如何使用Python在Win10上正确解压缩原始套接字?

如何使用Python在Win10上正确解压缩原始套接字?,python,sockets,packet-sniffers,raw-sockets,Python,Sockets,Packet Sniffers,Raw Sockets,我有Linux的工作代码,但在Windows上我得到了意想不到的结果。 代码: 导入套接字 导入系统 从结构导入解包 导入平台 def main(): local_ip=socket.gethostbyname(socket.gethostname()) 打印本地\u ip 尝试: 如果platform.system()=“Linux”: s=socket.socket(socket.AF_数据包,socket.SOCK_原始, socket.ntohs(0x0003)) elif platfo

我有Linux的工作代码,但在Windows上我得到了意想不到的结果。 代码:

导入套接字
导入系统
从结构导入解包
导入平台
def main():
local_ip=socket.gethostbyname(socket.gethostname())
打印本地\u ip
尝试:
如果platform.system()=“Linux”:
s=socket.socket(socket.AF_数据包,socket.SOCK_原始,
socket.ntohs(0x0003))
elif platform.system()=“Windows”:
s=socket.socket(socket.AF_INET,socket.SOCK_RAW,
插座(IPPROTO_IP)
s、 绑定((本地ip,0))
s、 setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
s、 ioctl(socket.SIO_RCVALL,socket.RCVALL_ON)
其他:
sys.exit()
除了socket.error作为消息:
print('无法创建套接字。错误代码:'+str(
消息[0]+“消息”+消息[1])
sys.exit()
#收到一个包
i=0
当我<10时:
i+=1
数据包=s.recvfrom(65565)
#元组中的数据包字符串
数据包=数据包[0]
#解析以太网报头
eth_长度=14
eth_头=数据包[:eth_长度]
eth=拆包(“!6s6sH”,eth_标题)
eth_协议=socket.ntohs(eth[2])
ip_头=数据包[eth_长度:20+eth_长度]
#拆包头
iph=拆包('!BBHHBBH4S',ip_头)
版本\ ihl=iph[0]
版本=版本\u国际人道主义法>>4
ihl=版本\u ihl&0xF
ttl=iph[5]
协议=iph[6]
s_addr=socket.inet_ntoa(iph[8])
d_addr=socket.inet_ntoa(iph[9])
打印“头协议:”,eth[2],“未打包协议:”,eth_协议
打印“版本:”+str(
版本)+“IP头长度:”+str(
ihl)+“TTL:”+str(
ttl)+'协议:'+str(
协议)+'源地址:'+str(
地址+'目的地址:'+str(地址)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
我拿了

所以,在Linux上,我得到了预期的数据

127.0.1.1头协议:2048解包协议:8版本:4 IP头长度:5 TTL:64协议:17源地址:127.0.0.1 目标地址:127.0.0.53标头协议:2048未打包 协议:8版本:4 IP头长度:5 TTL:64协议:17 源地址:127.0.0.1目标地址:127.0.0.53标头 协议:2048解包协议:8版本:4 IP头长度:5 TTL:64协议:17源地址:127.0.0.53目标地址 :127.0.0.1标头协议:2048未打包协议:8版本:4 IP 标头长度:5 TTL:64协议:17源地址:127.0.0.53 目标地址:127.0.0.1头协议:2048未打包 协议:8版本:4IP头长度:5TTL:64协议:6 源地址:10.0.2.15目标地址:5.196.61.211

但在Windows上,所有字段都不正确

10.0.2.15

标头协议:2560解包协议:10版本:0 IP标头 长度:2 TTL:8协议:70源地址:183.96.34.40 目标地址:36.2.80.16标头协议:2560未打包 协议:10版本:0 IP头长度:2 TTL:8协议:70 源地址:183.96.34.40目标地址:36.2.80.16标头 协议:2560解包协议:10版本:0 IP头长度:2 TTL:8协议:70源地址:183.96.34.40目标 地址:36.3.80.16标头协议:2560未打包协议:10 版本:0 IP头长度:2 TTL:8协议:70源地址 :183.96.34.40目标地址:36.3.80.16头协议:2560 解包协议:10版本:0IP头长度:2TTL:8 协议:70源地址:183.96.34.40目标地址: 36.3.80.17

如何获得正确的数据

另外,我知道pypcap、scapy和其他,但我需要没有任何第三方LIB的原始数据解析器。当然,如果可能的话

PPS。我在这里查看了所有类似的主题,但仍然没有找到解决方案


在Linux上,许多thnx都使用
SOCK\u RAW
AF\u数据包来嗅探第2层,这意味着您首先获取第2层信息(以太网),然后获取第3层信息(IP)。在Windows上,您正在使用
AF\u INET
嗅探第3层,这意味着您无法获得任何第2层信息。不过,您的代码在这两种情况下都采用第2层信息(以太网)。

因此,解决此问题的一种方法是跳过在Windows上处理任何以太网信息,因为没有以太网信息,并立即从IP头开始。

谢谢,我没有想到这一点。也许你知道-我如何在Windows上获取第2层信息?因为我在Windows上没有AF_数据包。@stahh:你的问题已经回答了,你现在问的是另一个问题。请不要在评论中提出新问题,而是创建一个真正的新问题,这样您就可以从新问题的可见性中获益,其他人也可以从找到新问题的答案中获益。您不能期望其他人在其他问题的评论中搜索新的问题和答案。谢谢。最后我找到了答案:不幸的是,有些平台不提供对底层网络层的访问,这对windows是正确的,对OS X也是正确的。。。感谢winpcap/npcap,建议使用低层网络层
import socket
import sys
from struct import unpack
import platform


def main():
    local_ip = socket.gethostbyname(socket.gethostname())
    print local_ip
    try:
        if platform.system() == 'Linux':
            s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
                              socket.ntohs(0x0003))
        elif platform.system() == 'Windows':
            s = socket.socket(socket.AF_INET, socket.SOCK_RAW,
                              socket.IPPROTO_IP)
            s.bind((local_ip, 0))
            s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
            s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
        else:
            sys.exit()
    except socket.error as msg:
        print('Socket could not be created. Error Code : ' + str(
            msg[0]) + ' Message ' + msg[1])
        sys.exit()

    # receive a packet
    i = 0
    while i < 10:
        i += 1
        packet = s.recvfrom(65565)
        # packet string from tuple
        packet = packet[0]
        # parse ethernet header
        eth_length = 14
        eth_header = packet[:eth_length]
        eth = unpack('!6s6sH', eth_header)
        eth_protocol = socket.ntohs(eth[2])
        ip_header = packet[eth_length:20 + eth_length]
        # unpack header
        iph = unpack('!BBHHHBBH4s4s', ip_header)
        version_ihl = iph[0]
        version = version_ihl >> 4
        ihl = version_ihl & 0xF
        ttl = iph[5]
        protocol = iph[6]
        s_addr = socket.inet_ntoa(iph[8])
        d_addr = socket.inet_ntoa(iph[9])
        print 'Header protocol:', eth[2], 'Unpacked protocol:', eth_protocol
        print 'Version : ' + str(
            version) + ' IP Header Length : ' + str(
            ihl) + ' TTL : ' + str(
            ttl) + ' Protocol : ' + str(
            protocol) + ' Source Address : ' + str(
            s_addr) + ' Destination Address : ' + str(d_addr)


if __name__ == '__main__':
    main()