Hi everyone this is my first time doing PCAP programming using Python for the programming language, this is for a task for University and I have mostly got everything I need to complete the task except for one small detail.
I just need to get an output of the source and destination port numbers (HTTP Port 80 for example) associated with the IP addresses.
I'm happy for the answer to be a pointer to the right direction to help me work it out for myself. Otherwise if it's easier for it to be just answered, I would like a basic explanation on what was used and how it resolves the problem so I can understand it better for when I do more future PCAP programming in my studies and research.
This is being utilized on a Unix system running FreeBSD 10.3
I have tried using dpkt.tcp, dpkt.udp, dpkt.ip libraries as well as tried some socket libraries to see if I can achieve the result I am looking for, but not having much luck. I'll be honest, I'm not sure what I need to use.
EDIT: I did try using tcp.sport and tcp.dport, still had no luck.
The main area of focus is where I have added the comments.
import datetime
import time
import sys
import dpkt
import socket
def printPcap(pcap):
for (ts,buf) in pcap:
try:
eth = dpkt.ethernet.Ethernet(buf)
if eth.type == dpkt.ethernet.ETH_TYPE_IP:
ip = eth.data
ipsrc = socket.inet_ntoa(ip.src)
ipdst = socket.inet_ntoa(ip.dst)
srcport = ??? ###Stuck here for source port
dstport = ??? ###Stuck here for destination port
if ip.p == dpkt.ip.IP_PROTO_TCP:
TCP = ip.data
iptype = 'tcp'
elif ip.p == dpkt.ip.IP_PROTO_UDP:
UDP = ip.data
iptype = 'udp'
len = str(ip.len)
ttl = str(ip.ttl)
###My current output
print '[' +str(datetime.datetime.utcfromtimestamp(ts))+ '] - ' \
+ipsrc+ ':' +srcport+ ' -> ' +ipdst+ ':' +dstport+ \
' ('+iptype+', len='+len+', ttl='+ttl+')'
except:
pass
SAMPLE EXPECTED OUTPUT:
[2018-08-16 02:48:10.238506] - 172.16.11.2:61016 -> 172.16.10.2:80 (tcp, len=52, ttl=63)
The problem is that your print statement is bogus, but you've hidden that with the "bare except". Using the bare except is considered very poor practice in python for exactly this reason. See also answers to this question: Should I always specify an exception type in `except` statements?
Specifically, your print statement is attempting to concatenate an integer to a string which isn't valid.
So, repaired, and with:
if ip.p == dpkt.ip.IP_PROTO_TCP:
TCP = ip.data
iptype = 'tcp'
srcport = TCP.sport
dstport = TCP.dport
elif ip.p == dpkt.ip.IP_PROTO_UDP:
UDP = ip.data
iptype = 'udp'
srcport = UDP.sport
dstport = UDP.dport
and this print statement, it works:
print("[{}] - {}:{} -> {}:{} ({}, len={}, ttl={})".format(
datetime.datetime.utcfromtimestamp(ts), ipsrc, srcport,
ipdst, dstport, iptype, len, ttl))
Finally, at the very least, I would change your except clause to something like this to detect such issues in the future:
except Exception as exc:
print("Exception: {}".format(exc))
(Note that I've used the python3-compatible print function syntax here, which also works fine with python2's print statement.)
EDIT:
One other thing just occurred to me. If the first IP packet encountered is neither TCP or UDP, srcport
and dstport
will not be defined and that will cause an AttributeError
exception. Leaving that for you to clean up.