Получить флаги TCP с помощью Scapy

Я разбираю файл 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

Есть ли способ получить один флаг TCP, не извлекая вручную его из значения packet['TCP'].flags?

Ответ 1

Обычно обычным способом обработки FLAGS является битмап и побитовые операторы. Если ваш класс Packet не имеет специального метода проверки флажков, лучше всего сделать IMHO:

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, когда вы будете использовать switch на других языках):

>>> 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

Другой вариант, для записи, который не существовал к моменту появления этого вопроса. Он работает с текущей версией разработки Scapy (первая версия, включая это изменение, будет 2.3.4).

Теперь вы можете использовать str() для значения флага:

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