win10 python 捕获并解析本机网卡IP数据包

原理就是调用socket模块里提供的各种API捕获数据包,然后根据RFC791协议对捕获的数据包按格式进行解析,把数据分类然后存储在一个字典里。

捕获部分代码:

def catchIPData():
    # 获取本机IP作为公共网络接口
    HOST = socket.gethostbyname(socket.gethostname())
    # 创建一个原始套接字
    s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
    # 将该套接字与公共网络接口绑定
    s.bind((HOST, 0))
    # 设定该套接字包含IP数据报首部
    s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
    # 设定该套接字接收所有数据包
    s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
    # 接收一个数据包并返回
    packet = s.recvfrom(4096)
    return packet

解析部分代码:

def decodeIpHeader(packet):
    # 创建一个空字典
    IPDatagram = {}
    # 根据RFC791协议对数据包进行解析
    IPDatagram['version'] = packet[0] >> 4
    IPDatagram['headLength'] = packet[0] & 0x0f
    IPDatagram['serviceType'] = packet[1]
    IPDatagram['totalLength'] = (packet[2] << 8) + packet[3]
    IPDatagram['identification'] = (packet[4] << 8) + packet[5]
    IPDatagram['flag'] = packet[6] >> 5
    IPDatagram['moreFragment'] = IPDatagram['flag'] & 1
    IPDatagram['dontFragment'] = (IPDatagram['flag'] >> 1) & 1
    IPDatagram['fragmentOffset'] = ((packet[6] & 0x1f) << 8) + packet[7]
    IPDatagram['TTL'] = packet[8]
    IPDatagram['protocol'] = packet[9]
    IPDatagram['headerCheckSum'] = (packet[10] << 8) + packet[11]
    # 源IP地址和目的IP地址都按照IP地址的格式用字符串存储
    IPDatagram['sourceAddress'] = "%d.%d.%d.%d" % (packet[12], packet[13], packet[14], packet[15])
    IPDatagram['destinationAddress'] = "%d.%d.%d.%d" % (packet[16], packet[17], packet[18], packet[19])
    # 根据数据包中头部长度确定是否有选项,如果有则添加至option列表中
    IPDatagram['options'] = []
    if IPDatagram['headLength'] > 5:
        step = 5
        while step < IPDatagram['headLength']:
            IPDatagram['options'].append(packet[step * 4])
            IPDatagram['options'].append(packet[step * 4 + 1])
            IPDatagram['options'].append(packet[step * 4 + 2])
            IPDatagram['options'].append(packet[step * 4 + 3])
            step += 1
    # 根据数据包中的总长度将数据部分添加至data列表中
    IPDatagram['data'] = []
    step = IPDatagram['headLength'] * 4
    while step < IPDatagram['totalLength']:
        IPDatagram['data'].append(packet[step])
        step += 1
    # 返回储存有数据包数据的字典
    return IPDatagram

 

你可能感兴趣的:(python)