I am a beginner at python, currently trying to build a packet capture analysis tool using dpkt in python 3. I have not done much yet, I'm attempting to build it slowly, step by step so I can really understand my problems and learn from them. As it stands my first task is simply to be able to read, parse and close the packet capture, storing the relevant information as suitable data types. The first problem I have encountered is that I am able to parse all the packet information inside my initial function as demonstrated in the commented out line (line 17), however when I attempt to call any packet info inside main() I only get the first packet in the stream (line 36). I think the solution is either to create a list/dict to store the data from the parsepcap function or to move the opening, parsing and closing of the pcap file to main(). I'm not sure how to proceed from here so any help would be appreciated. The second task is to summarise the packet info into number of packet types (UDP,TCP,IGMP), print first and last timestamps for each type and mean packet length for each type, but I'm not quite there yet. Again, any help is appreciated.
import dpkt
import socket
import sys
#Open, Parse and Close a PCAP file
#Input = File
#Output = File Contents
def parsepcap(pcap):
with open(pcap,'rb') as pcap_in:
contents = dpkt.pcap.Reader(pcap_in)
for ts, buf in contents:
eth = dpkt.ethernet.Ethernet(buf)
ip = eth.data
tcp = ip.data
dst_ip = socket.inet_ntoa(ip.dst)
src_ip = socket.inet_ntoa(ip.src)
#print(f'Source: {src_ip} -> Destination: {dst_ip}')
return eth, ip, tcp, dst_ip, src_ip
def main():
#Test Arguments
sys.argv.append('packets1.pcap')
#sys.argv.append('packets2.pcap')
#sys.argv.append('evidence-packet-analysis.pcap')
#Checks if there are two arguments being passed to sys.argv. If not, then explains usage.
if len(sys.argv) != 2:
print('[Error] Usage: py pcap_cw.py [pcapfile.pcap]')
return
in_location = sys.argv[1] #string we are getting data from - URL or path
try:
print('[+] Analysing %s' % sys.argv[1])
text = ""
text = parsepcap(in_location)
print(text)
except FileNotFoundError as err1:
print(f' File "{in_location}" does not exist. Please choose another file.')
except Exception as err2:
print(f'Oh No! - {err2}')
if __name__ == '__main__':
main()
You're setting the return variables inside a loop. That means they're being overridden each loop iteration, wich leads to you receiving only the last value.
An easy solution would be to turn your method into a
generator
(https://docs.python.org/3/glossary.html#term-generator), that will return each value when iterated, then iterate it on the outside function.And when setting the text:
A complete example (with some changes) would be:
With result (I took the liberty of printing only the most "printable" parts, the source and destination IP):