1 # coding:utf8
2 import socket
3 import os
4 import struct
5 from ctypes import *
6
7 # 嗅探主机上面流经的所有数据包 并转换成ip地址流向
8
9 # 监听的主机
10 host = "192.168.1.2"
11
12 # IP头定义 定义了一个 Structure 的结构体
13 class IP(Structure):
14 _fields_ = [
15 ("ih1", c_ubyte, 4),
16 ("version", c_ubyte, 4),
17 ("tos", c_ubyte),
18 ("len", c_ushort),
19 ("id", c_ushort),
20 ("offset", c_ushort),
21 ("ttl", c_ubyte),
22 ("protocol_num", c_ubyte),
23 ("sum", c_ushort),
24 ("src", c_ulong),
25 ("dst", c_ulong),
26 ]
27
28 def __new__(self, socket_buffer=None):
29 # 把我们获取到的 网络包ip头生成IP实例
30 return self.from_buffer_copy(socket_buffer)
31 pass
32
33 def __init__(self, socket_buffer=None):
34 # 协议字段与协议名称对应
35 self.protocol_map = {1:"ICMP", 6:"TCP", 17:"UDP"}
36
37 # 可读性更强的IP地址
38 # 使用了python struct库的pack方法 用指定的格式化参数将src 和dst的long型数值转换为字符串,
39 # 然后使用socket.inet_ntoa方法将字符串的一串数字转换为对应的ip格式。最后赋值给对应的src或者dst变量
40 self.src_address = socket.inet_ntoa(struct.pack("L", self.src))
41 self.dst_address = socket.inet_ntoa(struct.pack("L", self.dst))
42
43 # 协议类型
44 try:
45 self.protocol = self.protocol_map[self.protocol_num]
46 except :
47 self.protocol = str(self.protocol_num)
48
49 if os.name == 'nt':
50 socket_protocol = socket.IPPROTO_IP
51 else:
52 socket_protocol = socket.IPPROTO_ICMP
53
54
55 sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
56
57 sniffer.bind((host, 0))
58
59 sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
60
61 if os.name == 'nt':
62 sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
63
64 try:
65 while True:
66 #读取数据包
67 raw_buffer = sniffer.recvfrom(65565)[0]
68
69 # 将缓冲区的前20个字节按IP头进行解析
70 ip_header = IP(raw_buffer[0:20])
71 print "raw_buffer is %s " % raw_buffer[0:20]
72 # 输出协议和通信双方IP地址
73 print "Protocol: %s %s -> %s" % (ip_header.protocol, ip_header.src_address, ip_header.dst_address)
74
75 pass
76
77 # 处理 ctrl-c
78 except KeyboardInterrupt:
79 # 如果运行在Windows上, 关闭混杂模式
80 if os.name == 'nt':
81 sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)