嗅探主机的网络包并解析成ip地址
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)