Jim's
Tutorials

Spring 2011
course
navigation

jims socket notes

(copy of April 29 email in response to sam)
I think the quick answer for your example is that the fcntl isn't needed at all. This worked on my machine (running as root). I haven't tested to see which packets its getting.
import socket HOST = socket.gethostbyname(socket.gethostname()) s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP) s.bind((HOST, 0)) s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) while True: packet = s.recvfrom(4096) print packet[1] # address; raw data bytes in packet[0]
But this isn't a great place to start for packet capture. (Note that the comments in the python example you're using says "packages" rather than "packets". Need I say more?)
All the python socket.* etc calls are a thin wrapper around the Berkely Socket API; see for example wikipedia's "Berkely Sockets" article for details.
Most of the socket examples you'll find are client/server sorts, where your program either listens (server) or connects (client), not the raw stuff needed for sniffing. In particularl, once you grab the raw packets, you'll usually want someone else's library to decode them, otherwise you'll need to parse the IP addresses etc. from the raw data bytes. (Python's socket() library doesn't do any of that.)
And since usually you're going to see *lots* of packets, you're immediately faced with filtering or storing them. This is a common enough issue that there is a standard library (and file format) that everyone uses, namely libpcap. (which is what wireshark uses, for example). It can be installed with (for example) macports, and you can find several python interfaces for it. (I just installed ppylibpcap-0.6.2, which gives you "import pcap".)
See for example http://pylibpcap.sourceforge.net/ and http://sourceforge.net/projects/pylibpcap/
Their example code runs with things like
thirty-two:Desktop$ ./sniff.py en1 "" 01:05.47.352791 69.250.234.154 > 192.168.1.33 version: 4 header_len: 5 tos: 32 total_len: 1076 id: 51003 flags: 0 fragment_offset: 0 ttl: 49 protocol: tcp header checksum: 52234 data: c8 d5 fc 9c 14 1e b9 86 a6 c4 4e fd 80 18 ff ff a5 20 00 00 01 01 08 0a 17 5c 3d 73 35 fb bc 94 55 49 eb 77 4e 65 83 c5 dc 27 e3 e0 55 f0 f7 df ...
The interior loop of their code can grab each packet with just
while True: (length, data, timestamp) = pcapsession.next()
Or you can use raw packets to do the same sort of thing.
Here's what looks like a reasonable example (including a library for decoding the raw data), from http://code.google.com/p/impacket/ .
It uses python's (thin wrapper to unix) select() to wait for socket that has data, I think.
Grab their code with
$ svn checkout http://impacket.googlecode.com/svn/trunk/impacket-read-only
Then in their examples/ folder, look at sniffer.py for a raw sockets python example, and sniff.py for a libpcap example. (They do "import pcapy", using another python api to libpcap, from http://oss.coresecurity.com/projects/pcapy.html.)
I note in passing that another of their examples is exploit.py : often folks who are doing this low-level packet hacking are building their own packets and network libraries to pursue security stuff; that one looks like it sends a custom packet to a target host/port.
Are we having fun yet?
Jim
On 4/28/11 5:25 PM, sam auciello wrote: >> I trying to get the example at the bottom of this >> >> http://docs.python.org/library/socket.html#example >> >> page to work for Mac. I replaced the ioctl method with the ioctl function >> imported from the fnctl module as suggested here: >> >> http://docs.python.org/library/socket.html#socket.socket.ioctl >> >> The real question at this point is what to use for my second argument on >> line 26 in the code I've attached here. >> >> I've tried to find an example of someone else doing something similar but >> I'm not having much luck. >> >> Thanks for taking a look, >> >> Peace >> ~Sam
http://cs.marlboro.edu/ courses/ spring2011/jims_tutorials/ sam/ jims_socket_notes
last modified Friday April 29 2011 1:45 am EDT