SHOW:
|
|
- or go back to the newest paste.
| 1 | import socket, struct, os, array | |
| 2 | from scapy.all import ETH_P_ALL | |
| 3 | from scapy.all import select | |
| 4 | from scapy.all import MTU | |
| 5 | ||
| 6 | #author: askldjd | |
| 7 | #see: http://wp.me/pDfjR-rQ | |
| 8 | class IPSniff: | |
| 9 | ||
| 10 | def __init__(self, interface_name, on_ip_incoming, on_ip_outgoing): | |
| 11 | ||
| 12 | self.interface_name = interface_name | |
| 13 | self.on_ip_incoming = on_ip_incoming | |
| 14 | self.on_ip_outgoing = on_ip_outgoing | |
| 15 | ||
| 16 | # The raw in (listen) socket is a L2 raw socket that listens | |
| 17 | # for all packets going through a specific interface. | |
| 18 | self.ins = socket.socket( | |
| 19 | socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL)) | |
| 20 | self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30) | |
| 21 | self.ins.bind((self.interface_name, ETH_P_ALL)) | |
| 22 | ||
| 23 | def __process_ipframe(self, pkt_type, ip_header, payload): | |
| 24 | ||
| 25 | # Extract the 20 bytes IP header, ignoring the IP options | |
| 26 | fields = struct.unpack("!BBHHHBBHII", ip_header)
| |
| 27 | ||
| 28 | dummy_hdrlen = fields[0] & 0xf | |
| 29 | iplen = fields[2] | |
| 30 | ||
| 31 | ip_src = payload[12:16] | |
| 32 | ip_dst = payload[16:20] | |
| 33 | ip_frame = payload[0:iplen] | |
| 34 | ||
| 35 | if pkt_type == socket.PACKET_OUTGOING: | |
| 36 | if self.on_ip_outgoing is not None: | |
| 37 | self.on_ip_outgoing(ip_src, ip_dst, ip_frame) | |
| 38 | ||
| 39 | else: | |
| 40 | if self.on_ip_incoming is not None: | |
| 41 | self.on_ip_incoming(ip_src, ip_dst, ip_frame) | |
| 42 | ||
| 43 | def recv(self): | |
| 44 | while True: | |
| 45 | ||
| 46 | pkt, sa_ll = self.ins.recvfrom(MTU) | |
| 47 | ||
| 48 | if type == socket.PACKET_OUTGOING and self.on_ip_outgoing is None: | |
| 49 | continue | |
| 50 | elif self.on_ip_outgoing is None: | |
| 51 | continue | |
| 52 | ||
| 53 | if len(pkt) <= 0: | |
| 54 | break | |
| 55 | ||
| 56 | eth_header = struct.unpack("!6s6sH", pkt[0:14])
| |
| 57 | ||
| 58 | dummy_eth_protocol = socket.ntohs(eth_header[2]) | |
| 59 | ||
| 60 | if eth_header[2] != 0x800 : | |
| 61 | continue | |
| 62 | ||
| 63 | ip_header = pkt[14:34] | |
| 64 | payload = pkt[14:] | |
| 65 | ||
| 66 | self.__process_ipframe(sa_ll[2], ip_header, payload) | |
| 67 | ||
| 68 | #Example code to use IPSniff | |
| 69 | def test_incoming_callback(src, dst, frame): | |
| 70 | pass | |
| 71 | #print("incoming - src=%s, dst=%s, frame len = %d"
| |
| 72 | # %(socket.inet_ntoa(src), socket.inet_ntoa(dst), len(frame))) | |
| 73 | ||
| 74 | def test_outgoing_callback(src, dst, frame): | |
| 75 | pass | |
| 76 | #print("outgoing - src=%s, dst=%s, frame len = %d"
| |
| 77 | # %(socket.inet_ntoa(src), socket.inet_ntoa(dst), len(frame))) | |
| 78 | ||
| 79 | ip_sniff = IPSniff('eth0', test_incoming_callback, test_outgoing_callback)
| |
| 80 | ip_sniff.recv() |