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() |