使用 Scapy 获取 TCP 标志

Posted

技术标签:

【中文标题】使用 Scapy 获取 TCP 标志【英文标题】:Get TCP Flags with Scapy 【发布时间】:2013-12-24 03:29:05 【问题描述】:

我正在解析一个 PCAP 文件,我需要提取 TCP 标志(SYN、ACK、PSH、URG...)。 我正在使用packet['TCP'].flags 值一次获取所有标志。

pkts = PcapReader(infile)
for p in pkts:
        F = bin(p['TCP'].flags)
        print F, bin(F), p.summary()
        # manual flags extraction from F

有没有办法在不从packet['TCP'].flags 值中手动提取单个 TCP 标志的情况下获得它?

【问题讨论】:

定义更智能的方式?你是如何手动完成的? 所以您是说上述方法有效?代码有什么问题? 【参考方案1】:

通常,处理 FLAGS 的常用方法是使用位图和位运算符。如果您的 Packet 类没有测试标志的特定方法,恕我直言,您可以做的最好的事情是:

FIN = 0x01
SYN = 0x02
RST = 0x04
PSH = 0x08
ACK = 0x10
URG = 0x20
ECE = 0x40
CWR = 0x80

并像这样测试它们:

F = p['TCP'].flags    # this should give you an integer
if F & FIN:
    # FIN flag activated
if F & SYN:
    # SYN flag activated
# rest of the flags here

遗憾的是,python 没有 switch 语句来使它更优雅,但这并不重要。

希望这会有所帮助!

【讨论】:

【参考方案2】:

您可以使用Packet.sprintf() 方法:

>>> p = IP()/TCP(flags=18)
>>> p.sprintf('%TCP.flags%')
'SA'

如果您想要“长”名称,请使用 dict 而不是长 if...elif... 表达式(dict 通常在 Python 中使用,而您将使用 @987654327 @ 其他语言):

>>> flags = 
    'F': 'FIN',
    'S': 'SYN',
    'R': 'RST',
    'P': 'PSH',
    'A': 'ACK',
    'U': 'URG',
    'E': 'ECE',
    'C': 'CWR',

>>> [flags[x] for x in p.sprintf('%TCP.flags%')]
['SYN', 'ACK']

【讨论】:

【参考方案3】:

这也有效。

if packet[TCP].flags.F:
    print('FIN received')

【讨论】:

它可能使用__getattr__语义python-reference.readthedocs.io/en/latest/docs/dunderattr/…【参考方案4】:

另外一个选项,记录在案,在提出这个问题时还不存在。它适用于当前的 Scapy 开发版本(包含此更改的第一个版本将是 2.4.0;2.4.0rc* 也包含它)。

您现在可以在标志值上使用str()

>>> p = IP()/TCP(flags=18)
>>> p[TCP].flags
<Flag 18 (SA)>
>>> str(p[TCP].flags)
'SA'

【讨论】:

以上是关于使用 Scapy 获取 TCP 标志的主要内容,如果未能解决你的问题,请参考以下文章

TCP标志位简析

如何使用 libpcap 在原始数据包的 TCP 标头中打印标志

23-TCP 协议(紧急标志)

TCP中的URG标志与PSH标志有什么不同?

TCP协议的RST标志位

如何在 POSIX 函数 send() 中关闭 TCP PSH 标志?