kbandla/dpkt

provide me the code to read pcap files using dpkt

Closed this issue · 13 comments

i am a beginner to python and i want to use dpkt for extracting the fields of packet header from a pcap file. can someone provide me the sample code so that it will help me to understand how to use dpkt for a pcap file by inputing the pcap file of my choice.
Thanks & Regards

@sheenawadhwa, first, have a look at the dpkt documentation
I think, that the most interesting info for you will be "Examples" section. You'l find examples of how to open, parse and work with pcap files.

Thanks @saylenty for looking into this matter.
i have tried the following code:
import dpkt
from dpkt.ip import IP
from dpkt.ethernet import Ethernet
from dpkt.arp import ARP
f = open('sample.pcap', 'rb')
pcap = dpkt.pcap.Reader(f)
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
ip = eth.data
do_not_fragment = bool(dpkt.ip.IP_DF)
more_fragments = bool(dpkt.ip.IP_MF)
fragment_offset = ip.off & dpkt.ip.IP_OFFMASK
print 'IP: %s -> %s (len=%d ttl=%d DF=%d MF=%d offset=%d)\n' %
(ip.src, ip.dst, ip.len, ip.ttl, do_not_fragment, more_fragments, fragment_offset)
but it gives the error as following:
IP:
��� ->
��ÿ (len=170 ttl=64 DF=1 MF=1 offset=0)

Traceback (most recent call last):
File "C:\Python27\3.py", line 12, in
fragment_offset = ip.off & dpkt.ip.IP_OFFMASK
AttributeError: 'ARP' object has no attribute 'off'

as per dpkt "Example" section expected output is
IP: 65.208.228.223 -> 145.254.160.237 (len=48 ttl=47 DF=1 MF=0 offset=0)

...
can you please help me to resolve this issue

@sheenawadhwa you should check if the Ethernet frame actually contains an IP packet. You can see how the example excerpt does this:

    # Make sure the Ethernet frame contains an IP packet
    # EtherType (IP, ARP, PPPoE, IP6... see http://en.wikipedia.org/wiki/EtherType)
    if eth.type != dpkt.ethernet.ETH_TYPE_IP:
        print 'Non IP Packet type not supported %s\n' % eth.data.__class__.__name__
        continue

This was apparent based on this line from the traceback you posted:

AttributeError: 'ARP' object has no attribute 'off'

So clearly ip object is an instance of ARP, and not IP.

Adding this check to your code above: (not tested)

import dpkt
from dpkt.ip import IP
from dpkt.ethernet import Ethernet
from dpkt.arp import ARP

f = open('sample.pcap', 'rb')
pcap = dpkt.pcap.Reader(f)

for ts, buf in pcap:
  eth = dpkt.ethernet.Ethernet(buf)
  if eth.type != dpkt.ethernet.ETH_TYPE_IP:
    print 'Non IP Packet type not supported'
    continue

  ip = eth.data
  do_not_fragment = bool(dpkt.ip.IP_DF)
  more_fragments = bool(dpkt.ip.IP_MF)
  fragment_offset = ip.off & dpkt.ip.IP_OFFMASK
  print 'IP: %s -> %s (len=%d ttl=%d DF=%d MF=%d offset=%d)\n' % \
  (ip.src, ip.dst, ip.len, ip.ttl, do_not_fragment, more_fragments, fragment_offset)

Hope this helps

Thanks alot
it worked well
but still one issue is i am not able to get src and dst as in dpkt "example"
my output of IP is as follows
IP:
�� ->
��� (len=576 ttl=64 DF=1 MF=1 offset=1)

where expected is
IP: 65.208.228.223 -> 145.254.160.237 (len=48 ttl=47 DF=1 MF=0 offset=0)

not able to get the actual source and destination
my code is:
import dpkt
from dpkt.ethernet import Ethernet
f = open('sample.pcap', 'rb')
pcap = dpkt.pcap.Reader(f)
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
print ('Ethernet Frame: ', eth.src, eth.dst , eth.type)
if eth.type != dpkt.ethernet.ETH_TYPE_IP:
print 'Non IP Packet type not supported %s\n' % eth.data.class.name
continue
ip = eth.data
do_not_fragment = bool(dpkt.ip.IP_DF)
more_fragments = bool(dpkt.ip.IP_MF)
fragment_offset = bool(dpkt.ip.IP_OFFMASK)
print 'IP: %s -> %s (len=%d ttl=%d DF=%d MF=%d offset=%d)\n' %
(ip.src, ip.dst, ip.len, ip.ttl, do_not_fragment, more_fragments, fragment_offset)

The code is doing what you have asked it to do. I am assuming that you want to print the IP address in a human readable form. Please see this

def ip2int(addr):                                                               
    return struct.unpack("!I", socket.inet_aton(addr))[0]   

You can then do

print ip2int(ip.src)

thanks alot for your precious suggestions
@kbandla sir i am not able to understand how to use your code actually because its running perfectly as you have given:
def ip2int(addr):
return structs.unpack("!I", socket.inet_aton(addr))[0]
print ip2int(ip.src)

but after this what to do i am not getting that as i am begginer to python

Thanks for your patience

here is your code put together.

import dpkt
from dpkt.ip import IP
from dpkt.ethernet import Ethernet
from dpkt.arp import ARP

import struct
import socket
def ip2int(addr):                                                               
    return struct.unpack("!I", socket.inet_aton(addr))[0]   

f = open('sample.pcap', 'rb')
pcap = dpkt.pcap.Reader(f)

for ts, buf in pcap:
  eth = dpkt.ethernet.Ethernet(buf)
  if eth.type != dpkt.ethernet.ETH_TYPE_IP:
    print 'Non IP Packet type not supported'
    continue

  ip = eth.data
  do_not_fragment = bool(dpkt.ip.IP_DF)
  more_fragments = bool(dpkt.ip.IP_MF)
  fragment_offset = ip.off & dpkt.ip.IP_OFFMASK
  print 'IP: %s -> %s (len=%d ttl=%d DF=%d MF=%d offset=%d)\n' % \
  (ip2int(ip.src), ip2int(ip.dst), ip.len, ip.ttl, do_not_fragment, more_fragments, fragment_offset)

Hope this helps. Please go ahead and close this issue when you are done.

thanks for the information but as you have said i already tried that but it encounters the following error:
Traceback (most recent call last):
File "C:\Python27\int.py", line 21, in
(ip2int(ip.src), ip2int(ip.dst), ip.len, ip.ttl, do_not_fragment, more_fragments, fragment_offset)
File "C:\Python27\int.py", line 8, in ip2int
return structs.unpack("!I", socket.inet_aton(addr))[0]
NameError: global name 'structs' is not defined

You have a typo in your code. Please check it. Its struct, not structs

@kbandla after correcting this gives the following error :

Traceback (most recent call last):
File "C:\Python27\int.py", line 20, in
(ip2int(ip.src), ip2int(ip.dst), ip.len, ip.ttl, do_not_fragment, more_fragments, fragment_offset)
File "C:\Python27\int.py", line 8, in ip2int
return struct.unpack("!I", socket.inet_aton(addr))[0]
error: illegal IP address string passed to inet_aton

issue solved with little modification
thanks

You can convert the destination/source IP address to an ASCII string in dotted quad format using the socket package:

For example,
import socket
dst_ip_addr_str = socket.inet_ntoa(ip.dst)

@mrajiullah The issue is resolved and closed (have a look at the issue status).