Получить флаги 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 значение?

3 ответов


обычно обычный способ обработки флагов - это растровые и побитовые операторы. Если 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 заявление, чтобы сделать это более элегантным, но это не имеет большого значения.

надеюсь, что это помогает!


Вы можете использовать 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']

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

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

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