如何使用Python在Win10上正确解压缩原始套接字?
我有Linux的工作代码,但在Windows上我得到了意想不到的结果。 代码:如何使用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
导入套接字
导入系统
从结构导入解包
导入平台
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()