========== Sniffing ========== Introduction ============ Since v0.2 UMPA provides a new feature to capture packets over the network. It uses well known libpcap[1] as a background and users who are familiar with it can easily understand and use UMPA's sniffing tool. .. note:: using libpcap requires root privileges! The First Step ============== ``umit.umpa.sniffing`` provides the following functions for sniffing: 1. sniff() 2. sniff_next() 3. sniff_any() 4. sniff_loop() 5. to_file() 6. from_file() 7. from_file_loop() The main function is obviously ``sniff()`` and the rest of them simple wrap this function to make our life easier. Also, most of arguments for all of these functions are the same and keep in the same order (for some functions like \*_loop() additional arguments were added at the end). Functions 2-3 are very similar to the first one and in this paragraph we gonna focus on these 3 functions. Basically, the simplest function is ``sniff_any()``, you can call it and you will get a first arrived packet from the network. That's all. You can't set anything (apart from store it on your harddrive). In contrary to ``sniff_any()``, ``sniff()`` gives you full control on sniffing packets. You can set how many packets you expect, filter packets, select network interface and many more. For details, please check pydocs of ``umit.umpa.sniffing`` package. In libpcap's manuals you can find interesting informations as well. Lets imagine the following situation. We need first 3 packets sent to us on our port 80. Just to see what's goin on. Our IP in this case is ``127.0.0.1``. And we are interested in loopback interface .. code-block:: python In [1]: from umit.umpa.sniffing import sniff In [2]: packets = umit.umpa.sniffing.sniff(10, filter="src host 127.0.0.1 and port 80", device="lo") In [3]: len(packets) Out[3]: 3 In [4]: for pkt in packets: ...: print pkt Packet contains 4 protocols +-< Ethernet > | \ | +-[ Destination ] dst : 00:00:00:00:00:00 | +-[ Source ] src : 00:00:00:00:00:00 | +-[ Type ] _type : 2048 \-< Ethernet > contains 3 fields <umit.umpa.protocols.Ethernet.Ethernet object at 0xa14c2cc> +-< IP > | \ | +-[ Version ] _version : 4 | +-[ IHL ] _hdr_len : 5 | +-[ TOS ] tos | | \ | | -{ precedence0 } 0 | | -{ precedence1 } 0 | | -{ precedence2 } 0 | | -{ delay } 0 | | -{ throughput } 0 | | -{ reliability } 0 | | -{ reserved0 } 0 | | -{ reserved1 } 0 | | / | \-[ TOS ] contains 8 bit flags | +-[ Total Length ] _len : 60 | +-[ Identification ] _id : 38286 | +-[ Flags ] flags | | \ | | -{ rb } 0 | | -{ df } 1 | | -{ mf } 0 | | / | \-[ Flags ] contains 3 bit flags | +-[ Fragment Offset ] _frag_offset : 0 | +-[ TTL ] ttl : 64 | +-[ Protocol ] _proto : 6 | +-[ Header Checksum ] _checksum : 42795 | +-[ Source Address ] src : 127.0.0.1 | +-[ Destination Address ] dst : 127.0.0.1 | +-[ Options ] options : 0 | +-[ Padding ] _padding : 0 (auto - 0) \-< IP > contains 14 fields <umit.umpa.protocols.IP.IP object at 0xa14c3cc> +-< TCP > | \ | +-[ Source Port ] srcport : 40551 | +-[ Destination Port ] dstport : 80 | +-[ Sequence Number ] _seq : 4002535750 | +-[ Acknowledgment Number ] _ack : 4004130011 | +-[ Data Offset ] _hdr_len : 8 | +-[ Reserved ] _reserved : 0 | +-[ Control Bits ] flags | | \ | | -{ urg } 0 | | -{ ack } 1 | | -{ psh } 1 | | -{ rst } 0 | | -{ syn } 0 | | -{ fin } 0 | | / | \-[ Control Bits ] contains 6 bit flags | +-[ Window ] _window_size : 513 | +-[ Checksum ] _checksum : 65072 | +-[ Urgent Pointer ] _urgent_pointer : 0 | +-[ Options ] options : 310731899079550965555890515 | +-[ Padding ] _padding : 0 (auto - 0) \-< TCP > contains 12 fields <umit.umpa.protocols.TCP.TCP object at 0xa14c08c> +-< Payload > | \ | +-[ Data ] data : this is \-< Payload > contains 1 fields <umit.umpa.protocols.Payload.Payload object at 0xa14c2ec> <umit.umpa._packets.Packet object at 0xa14c5cc> Packet contains 3 protocols +-< Ethernet > | \ | +-[ Destination ] dst : 00:00:00:00:00:00 | +-[ Source ] src : 00:00:00:00:00:00 | +-[ Type ] _type : 2048 \-< Ethernet > contains 3 fields <umit.umpa.protocols.Ethernet.Ethernet object at 0xa14caac> +-< IP > | \ | +-[ Version ] _version : 4 | +-[ IHL ] _hdr_len : 5 | +-[ TOS ] tos | | \ | | -{ precedence0 } 0 | | -{ precedence1 } 0 | | -{ precedence2 } 0 | | -{ delay } 0 | | -{ throughput } 0 | | -{ reliability } 0 | | -{ reserved0 } 0 | | -{ reserved1 } 0 | | / | \-[ TOS ] contains 8 bit flags | +-[ Total Length ] _len : 52 | +-[ Identification ] _id : 24866 | +-[ Flags ] flags | | \ | | -{ rb } 0 | | -{ df } 1 | | -{ mf } 0 | | / | \-[ Flags ] contains 3 bit flags | +-[ Fragment Offset ] _frag_offset : 0 | +-[ TTL ] ttl : 64 | +-[ Protocol ] _proto : 6 | +-[ Header Checksum ] _checksum : 56223 | +-[ Source Address ] src : 127.0.0.1 | +-[ Destination Address ] dst : 127.0.0.1 | +-[ Options ] options : 0 | +-[ Padding ] _padding : 0 (auto - 0) \-< IP > contains 14 fields <umit.umpa.protocols.IP.IP object at 0xa14c82c> +-< TCP > | \ | +-[ Source Port ] srcport : 80 | +-[ Destination Port ] dstport : 40551 | +-[ Sequence Number ] _seq : 4004130011 | +-[ Acknowledgment Number ] _ack : 4002535758 | +-[ Data Offset ] _hdr_len : 8 | +-[ Reserved ] _reserved : 0 | +-[ Control Bits ] flags | | \ | | -{ urg } 0 | | -{ ack } 1 | | -{ psh } 0 | | -{ rst } 0 | | -{ syn } 0 | | -{ fin } 0 | | / | \-[ Control Bits ] contains 6 bit flags | +-[ Window ] _window_size : 512 | +-[ Checksum ] _checksum : 52183 | +-[ Urgent Pointer ] _urgent_pointer : 0 | +-[ Options ] options : 310731899079550965555893207 | +-[ Padding ] _padding : 0 (auto - 0) \-< TCP > contains 12 fields <umit.umpa.protocols.TCP.TCP object at 0xa14c6cc> <umit.umpa._packets.Packet object at 0xa14c54c> Packet contains 4 protocols +-< Ethernet > | \ | +-[ Destination ] dst : 00:00:00:00:00:00 | +-[ Source ] src : 00:00:00:00:00:00 | +-[ Type ] _type : 2048 \-< Ethernet > contains 3 fields <umit.umpa.protocols.Ethernet.Ethernet object at 0xa14ce0c> +-< IP > | \ | +-[ Version ] _version : 4 | +-[ IHL ] _hdr_len : 5 | +-[ TOS ] tos | | \ | | -{ precedence0 } 0 | | -{ precedence1 } 0 | | -{ precedence2 } 0 | | -{ delay } 0 | | -{ throughput } 0 | | -{ reliability } 0 | | -{ reserved0 } 0 | | -{ reserved1 } 0 | | / | \-[ TOS ] contains 8 bit flags | +-[ Total Length ] _len : 62 | +-[ Identification ] _id : 38287 | +-[ Flags ] flags | | \ | | -{ rb } 0 | | -{ df } 1 | | -{ mf } 0 | | / | \-[ Flags ] contains 3 bit flags | +-[ Fragment Offset ] _frag_offset : 0 | +-[ TTL ] ttl : 64 | +-[ Protocol ] _proto : 6 | +-[ Header Checksum ] _checksum : 42792 | +-[ Source Address ] src : 127.0.0.1 | +-[ Destination Address ] dst : 127.0.0.1 | +-[ Options ] options : 0 | +-[ Padding ] _padding : 0 (auto - 0) \-< IP > contains 14 fields <umit.umpa.protocols.IP.IP object at 0xa14cf4c> +-< TCP > | \ | +-[ Source Port ] srcport : 40551 | +-[ Destination Port ] dstport : 80 | +-[ Sequence Number ] _seq : 4002535758 | +-[ Acknowledgment Number ] _ack : 4004130011 | +-[ Data Offset ] _hdr_len : 8 | +-[ Reserved ] _reserved : 0 | +-[ Control Bits ] flags | | \ | | -{ urg } 0 | | -{ ack } 1 | | -{ psh } 1 | | -{ rst } 0 | | -{ syn } 0 | | -{ fin } 0 | | / | \-[ Control Bits ] contains 6 bit flags | +-[ Window ] _window_size : 513 | +-[ Checksum ] _checksum : 65074 | +-[ Urgent Pointer ] _urgent_pointer : 0 | +-[ Options ] options : 310731899079553100154639319 | +-[ Padding ] _padding : 0 (auto - 0) \-< TCP > contains 12 fields <umit.umpa.protocols.TCP.TCP object at 0xa1512ec> +-< Payload > | \ | +-[ Data ] data : umpa umpa \-< Payload > contains 1 fields <umit.umpa.protocols.Payload.Payload object at 0xa14cdac> <umit.umpa._packets.Packet object at 0xa14c9cc> As you can see, we got 3 packets (``umit.umpa.Packet``'s objects). 2 sent to a port 80 and 1 packet from the port 80. If we are intrestested to get just 1 packet, we can also use ``sniff_next()`` which is equivalent to pass ``1`` as a first argument in ``sniff()``. Callbacks ========= By using callbacks we can simple register functions which will be called when suitable packet will be sniffed. These functions are ending with ''_loop'' word in the func name. Before we will register a callback function, we have define it. It has fixed arguments list: ``timestamp, pkt, *callback_args``. .. code-block:: python def callback_func(timestamp, pkt, *args): print "[%f] Captured a new packet.." % timestamp print pkt print The callback's function simple print a timestamp in brackets with a notification and after that, print sniffed packet. Let's register this function. .. code-block:: python In [5]: umit.umpa.sniffing.sniff_loop(3, callback=callback, filter="src host 127.0.0.1 and port 80", device="lo") [1249423424.454845] Captured a new packet.. Packet contains 4 protocols +-< Ethernet > | \ | +-[ Destination ] dst : 00:00:00:00:00:00 | +-[ Source ] src : 00:00:00:00:00:00 | +-[ Type ] _type : 2048 \-< Ethernet > contains 3 fields <umit.umpa.protocols.Ethernet.Ethernet object at 0xa1574ec> +-< IP > | \ | +-[ Version ] _version : 4 | +-[ IHL ] _hdr_len : 5 | +-[ TOS ] tos | | \ | | -{ precedence0 } 0 | | -{ precedence1 } 0 | | -{ precedence2 } 0 | | -{ delay } 0 | | -{ throughput } 0 | | -{ reliability } 0 | | -{ reserved0 } 0 | | -{ reserved1 } 0 | | / | \-[ TOS ] contains 8 bit flags | +-[ Total Length ] _len : 61 | +-[ Identification ] _id : 38289 | +-[ Flags ] flags | | \ | | -{ rb } 0 | | -{ df } 1 | | -{ mf } 0 | | / | \-[ Flags ] contains 3 bit flags | +-[ Fragment Offset ] _frag_offset : 0 | +-[ TTL ] ttl : 64 | +-[ Protocol ] _proto : 6 | +-[ Header Checksum ] _checksum : 42791 | +-[ Source Address ] src : 127.0.0.1 | +-[ Destination Address ] dst : 127.0.0.1 | +-[ Options ] options : 0 | +-[ Padding ] _padding : 0 (auto - 0) \-< IP > contains 14 fields <umit.umpa.protocols.IP.IP object at 0xa15716c> +-< TCP > | \ | +-[ Source Port ] srcport : 40551 | +-[ Destination Port ] dstport : 80 | +-[ Sequence Number ] _seq : 4002535777 | +-[ Acknowledgment Number ] _ack : 4004130011 | +-[ Data Offset ] _hdr_len : 8 | +-[ Reserved ] _reserved : 0 | +-[ Control Bits ] flags | | \ | | -{ urg } 0 | | -{ ack } 1 | | -{ psh } 1 | | -{ rst } 0 | | -{ syn } 0 | | -{ fin } 0 | | / | \-[ Control Bits ] contains 6 bit flags | +-[ Window ] _window_size : 513 | +-[ Checksum ] _checksum : 65073 | +-[ Urgent Pointer ] _urgent_pointer : 0 | +-[ Options ] options : 310731899081384963836337783 | +-[ Padding ] _padding : 0 (auto - 0) \-< TCP > contains 12 fields <umit.umpa.protocols.TCP.TCP object at 0xa1573ec> +-< Payload > | \ | +-[ Data ] data : callback \-< Payload > contains 1 fields <umit.umpa.protocols.Payload.Payload object at 0xa15778c> <umit.umpa._packets.Packet object at 0xa14ca2c> [1249423424.454873] Captured a new packet.. Packet contains 3 protocols +-< Ethernet > | \ | +-[ Destination ] dst : 00:00:00:00:00:00 | +-[ Source ] src : 00:00:00:00:00:00 | +-[ Type ] _type : 2048 \-< Ethernet > contains 3 fields <umit.umpa.protocols.Ethernet.Ethernet object at 0xa15794c> +-< IP > | \ | +-[ Version ] _version : 4 | +-[ IHL ] _hdr_len : 5 | +-[ TOS ] tos | | \ | | -{ precedence0 } 0 | | -{ precedence1 } 0 | | -{ precedence2 } 0 | | -{ delay } 0 | | -{ throughput } 0 | | -{ reliability } 0 | | -{ reserved0 } 0 | | -{ reserved1 } 0 | | / | \-[ TOS ] contains 8 bit flags | +-[ Total Length ] _len : 52 | +-[ Identification ] _id : 24869 | +-[ Flags ] flags | | \ | | -{ rb } 0 | | -{ df } 1 | | -{ mf } 0 | | / | \-[ Flags ] contains 3 bit flags | +-[ Fragment Offset ] _frag_offset : 0 | +-[ TTL ] ttl : 64 | +-[ Protocol ] _proto : 6 | +-[ Header Checksum ] _checksum : 56220 | +-[ Source Address ] src : 127.0.0.1 | +-[ Destination Address ] dst : 127.0.0.1 | +-[ Options ] options : 0 | +-[ Padding ] _padding : 0 (auto - 0) \-< IP > contains 14 fields <umit.umpa.protocols.IP.IP object at 0xa1579ec> +-< TCP > | \ | +-[ Source Port ] srcport : 80 | +-[ Destination Port ] dstport : 40551 | +-[ Sequence Number ] _seq : 4004130011 | +-[ Acknowledgment Number ] _ack : 4002535786 | +-[ Data Offset ] _hdr_len : 8 | +-[ Reserved ] _reserved : 0 | +-[ Control Bits ] flags | | \ | | -{ urg } 0 | | -{ ack } 1 | | -{ psh } 0 | | -{ rst } 0 | | -{ syn } 0 | | -{ fin } 0 | | / | \-[ Control Bits ] contains 6 bit flags | +-[ Window ] _window_size : 512 | +-[ Checksum ] _checksum : 50088 | +-[ Urgent Pointer ] _urgent_pointer : 0 | +-[ Options ] options : 310731899081384963836352474 | +-[ Padding ] _padding : 0 (auto - 0) \-< TCP > contains 12 fields <umit.umpa.protocols.TCP.TCP object at 0xa157cec> <umit.umpa._packets.Packet object at 0xa15132c> [1249423429.719059] Captured a new packet.. Packet contains 4 protocols +-< Ethernet > | \ | +-[ Destination ] dst : 00:00:00:00:00:00 | +-[ Source ] src : 00:00:00:00:00:00 | +-[ Type ] _type : 2048 \-< Ethernet > contains 3 fields <umit.umpa.protocols.Ethernet.Ethernet object at 0xa1574ec> +-< IP > | \ | +-[ Version ] _version : 4 | +-[ IHL ] _hdr_len : 5 | +-[ TOS ] tos | | \ | | -{ precedence0 } 0 | | -{ precedence1 } 0 | | -{ precedence2 } 0 | | -{ delay } 0 | | -{ throughput } 0 | | -{ reliability } 0 | | -{ reserved0 } 0 | | -{ reserved1 } 0 | | / | \-[ TOS ] contains 8 bit flags | +-[ Total Length ] _len : 62 | +-[ Identification ] _id : 38290 | +-[ Flags ] flags | | \ | | -{ rb } 0 | | -{ df } 1 | | -{ mf } 0 | | / | \-[ Flags ] contains 3 bit flags | +-[ Fragment Offset ] _frag_offset : 0 | +-[ TTL ] ttl : 64 | +-[ Protocol ] _proto : 6 | +-[ Header Checksum ] _checksum : 42789 | +-[ Source Address ] src : 127.0.0.1 | +-[ Destination Address ] dst : 127.0.0.1 | +-[ Options ] options : 0 | +-[ Padding ] _padding : 0 (auto - 0) \-< IP > contains 14 fields <umit.umpa.protocols.IP.IP object at 0xa15758c> +-< TCP > | \ | +-[ Source Port ] srcport : 40551 | +-[ Destination Port ] dstport : 80 | +-[ Sequence Number ] _seq : 4002535786 | +-[ Acknowledgment Number ] _ack : 4004130011 | +-[ Data Offset ] _hdr_len : 8 | +-[ Reserved ] _reserved : 0 | +-[ Control Bits ] flags | | \ | | -{ urg } 0 | | -{ ack } 1 | | -{ psh } 1 | | -{ rst } 0 | | -{ syn } 0 | | -{ fin } 0 | | / | \-[ Control Bits ] contains 6 bit flags | +-[ Window ] _window_size : 513 | +-[ Checksum ] _checksum : 65074 | +-[ Urgent Pointer ] _urgent_pointer : 0 | +-[ Options ] options : 310731899081390616013314010 | +-[ Padding ] _padding : 0 (auto - 0) \-< TCP > contains 12 fields <umit.umpa.protocols.TCP.TCP object at 0xa1576cc> +-< Payload > | \ | +-[ Data ] data : umpa umpa \-< Payload > contains 1 fields <umit.umpa.protocols.Payload.Payload object at 0xa1578ec> <umit.umpa._packets.Packet object at 0xa14ca2c> Dealing with files ================== We can also read packets from files or store results there. Let's store packet to file first and then load them. There are 2 options to store packets on our harddrive. We can use special function ``to_file()`` or use special argument for any sniff*() functions called ''dump''. The difference is only that using sniff* functions we can still do other things with already sniffed packets and storing packets is just an option. ``to_file()`` is focused only on storing packets. It's pretty simple and there is no need more explanation. Just show on the example below. .. code-block:: python In [6]: umit.umpa.sniffing.to_file('/tmp/our_packets.cap', 3, "src host 127.0.0.1 and port 80", "lo") As you can notice, we used .cap extensions. And yes, our packets can be read by any application which is able to read .cap format's files (e.g. wireshark). Now, let's read packets back. We have to use one of the functions: ``from_file()`` or ``from_file_loop()``. A distinction between them is about callback what is already explained above. .. code-block:: python In [7]: packets = umit.umpa.sniffing.from_file('/tmp/our_packets.cap') We can use filter, count or other arguments as well to limit loaded packets. But in this case we wanna load everything from a file.
