3

I'm actually trying to sniff packets with python (using pypcap and dpkt).

I tried the following :

import dpkt, pcap
pc = pcap.pcap()     # construct pcap object
pc.setfilter('src host X.X.X.X or dst host X.X.X.X')
for timestamp, packet in pc:
    print dpkt.ethernet.Ethernet(packet)

But nothing happens when I launch the script... Did I miss something ?

Using Python 2.7 On OS X Yosemite (10.10)

Quentin
  • 435
  • 2
  • 6
  • 15

4 Answers4

9

The question is old but for new people who might hit this. The github 'chains' project uses both pypcap and dpkt for exactly this kind of thing (Disclaimer: I'm involved with all three projects :) https://github.com/SuperCowPowers/chains

  • chains/sources/packet_streamer.py (code showing use of pypcap for 'sniffing')
  • chains/links/packet_meta.py (code showing use of dpkt for packet parsing)

For those that just want to use pypcap/dpkt here's a working code snippet:

import pcap
import dpkt

sniffer = pcap.pcap(name=None, promisc=True, immediate=True)
for timestamp, raw_buf in sniffer:
    output = {}

    # Unpack the Ethernet frame (mac src/dst, ethertype)
    eth = dpkt.ethernet.Ethernet(raw_buf)
    output['eth'] = {'src': eth.src, 'dst': eth.dst, 'type':eth.type}

    # It this an IP packet?
    if not isinstance(eth.data, dpkt.ip.IP):
        print 'Non IP Packet type not supported %s\n' % eth.data.__class__.__name__
        continue 

    # Grab ip packet
    packet = eth.data

    # Pull out fragment information
    df = bool(packet.off & dpkt.ip.IP_DF)
    mf = bool(packet.off & dpkt.ip.IP_MF)
    offset = packet.off & dpkt.ip.IP_OFFMASK

    # Pulling out src, dst, length, fragment info, TTL, checksum and Protocol
    output['ip'] = {'src':packet.src, 'dst':packet.dst, 'p': packet.p,
                    'len':packet.len, 'ttl':packet.ttl,
                    'df':df, 'mf': mf, 'offset': offset,
                    'checksum': packet.sum}
    print output
Brian Wylie
  • 2,347
  • 28
  • 29
2

You should check out Scapy. Its a powerful networking tool, that can be used interactivly as well. Its written in python, hence you can use it in your scripts as well.

In scapy its as easy as (but you can easily add filters as well):

sniff(iface='eth0')
sebs
  • 4,566
  • 3
  • 19
  • 28
  • I'll check it out, but still searching a solution for my previous problem (want to understand what's going wrong). – Quentin Nov 27 '14 at 02:38
1

If you didn't place the path to a file in pcap.pcap(), there's no pcap for it to parse.

I ran your script with a glob of from a pcap directory I have and replaced the IP with one in my network, seemed like it worked. You sure you installed pypcap and dpkt?

Here's exactly what I did with your script.

import dpkt, pcap, glob
for i in glob.glob("/pcap/*.pcap"):
    pc = pcap.pcap(i)
    pc.setfilter('src host 192.168.1.140 or dst host 192.168.1.140')
    for timestamp, packet in pc:
        print dpkt.ethernet.Ethernet(packet)

It printed a lot of stuff.

mdandr
  • 1,384
  • 3
  • 9
  • 19
  • I replace line 2 by `pc = pcap.pcap('pcap/capture.pcap')` (the path to my pcap capture) and the terminal displayed some results, so I was wrong because I didn't define any path to pcap file. But what I wanted to do is to print the stream of the packets. How am I supposed to do that using pypcap lib ? Is it possible ? – Quentin Nov 27 '14 at 04:11
  • If I'm not mistaken, because of the way packets are packed, printing out the entire packet will give you a bunch of unreadable data. Any values you want will have to be extracted and converted before you can read them and print them. – mdandr Nov 27 '14 at 05:09
  • Yes, you were true : packets are unreadable. What I need to do is extract TCP payload from a defined src ip to deserialize them. Actually, I gave up pypcap and dpkt but your answer solved my problem but I started using scapy. – Quentin Nov 27 '14 at 09:17
  • But, here is my new problem (http://stackoverflow.com/questions/27167069/do-not-receive-echo-reply-from-ping-request-with-scapy) if you want to have a look. – Quentin Nov 27 '14 at 09:27
1

Nothing jumps out at the code, so I'm wondering if it is just the network.

Can you double check the IP addresses and also maybe run tcpdump as a sanity check to make sure you can see traffic?

For tcpdump something like this

$ sudo tcpdump -i en1 "src host 10.0.0.2 or dst host 10.0.0.2" 
Casey
  • 12,070
  • 18
  • 71
  • 107
  • I run `sudo tcpdump -i en0` with the same filter as my python script and my terminal displayed a lot of packet when I request the IP in the filter. So tcpdump runs. – Quentin Nov 27 '14 at 03:56