I'm parsing a PCAP file and I need to extract TCP flags (SYN, ACK, PSH, URG, ...).
I'm using the packet['TCP'].flags
value to obtain all the flags at once.
pkts = PcapReader(infile)
for p in pkts:
F = bin(p['TCP'].flags)
print F, bin(F), p.summary()
# manual flags extraction from F
Is there a way to obtain a single TCP flag without manually extract it from packet['TCP'].flags
value?
Step I - Send the client's SYN to a listening server (SYN)Craft an IP header with the source and destination IP addresses. Craft a TCP header where we generate the TCP source port, assign the destination port that the server listens on, set the TCP flags to turn the SYN bit on, and generate the client's ISN.
Creating a packet In scapy, packets are constructed by defining packet headers for each protocol at different layers of TCP/IP and then stacking these layers in order. To create a DNS query, you need to build Ether(sometimes optional), IP,UDP headers and stack them using / operator.
Sniffing packets using scapy: To sniff the packets use the sniff() function. The sniff() function returns information about all the packets that has been sniffed. To see the summary of packet responses, use summary(). The sniff() function listens for an infinite period of time until the user interrupts.
Scapy runs natively on Linux, Windows, OSX and on most Unixes with libpcap (see scapy's installation page).
Normally, the usual way to handle FLAGS is with a bitmap and bitwise operators. If your Packet
class doesn't have specific method to test for flags, the best thing you can do IMHO is to:
FIN = 0x01
SYN = 0x02
RST = 0x04
PSH = 0x08
ACK = 0x10
URG = 0x20
ECE = 0x40
CWR = 0x80
And test them like this:
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
Sadly, python doesn't have a switch
statement to make this more elegant but it doesn't really matter much.
Hope this helps!
You can use the Packet.sprintf()
method:
>>> p = IP()/TCP(flags=18)
>>> p.sprintf('%TCP.flags%')
'SA'
If you want the "long" names, use a dict
instead of a long if
...elif
... expression (dict
are often used in Python when you would use a switch
in other languages):
>>> 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']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With