Python 2.7 RAW 套接字:ARP 中缺失和错误的字段 header
Python 2.7 RAW sockets: missing and wrong fields in ARP header
一开始我想说我之前没有任何套接字经验。我正在尝试在 python 2.7 中创建响应 ARP 数据包。
我几乎完成了,但是有一个问题:当我在 wireshark 中查看数据包时,我发现 ARP header 缺少发件人和目标 mac 以及发件人和目标 ip 字段。硬件大小和协议大小字段也是错误的。我究竟做错了什么?我是否错误地打包了数据?这是程序的源代码:
import socket
import struct
import binascii
def formatMAC(mac):
return mac.lower().replace(':', '')
def sendPacket(packet):
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
s.bind(("wlan0", 0))
return s.send(packet)
eth_src = formatMAC('A0:88:B4:0A:A5:A8')
eth_dst = formatMAC("18:A6:F7:CF:51:B6")
eth_prt = '0806'
arp_hw_type = '0001'
arp_prt_type = '0800'
arp_hw_size = '0006'
arp_prt_size = "0004"
arp_opcode = '0002'
arp_mac_src = formatMAC('A0:88:B4:0A:A5:A8')
arp_ip_src = '192.168.0.134'
arp_mac_dst = formatMAC('18:A6:F7:CF:51:B6')
arp_ip_dst = '192.168.0.1'
eth_pack = struct.pack("!6s6s2s", binascii.unhexlify(eth_dst), binascii.unhexlify(eth_src), binascii.unhexlify(eth_prt))
arp_pack = struct.pack("2s2s1s1s2s6s4s6s4s",
binascii.unhexlify(arp_hw_type),
binascii.unhexlify(arp_prt_type),
binascii.unhexlify(arp_hw_size),
binascii.unhexlify(arp_prt_size),
binascii.unhexlify(arp_opcode),
binascii.unhexlify(arp_mac_src),
socket.inet_aton(arp_ip_src),
binascii.unhexlify(arp_mac_dst),
socket.inet_aton(arp_ip_dst)
)
packet = eth_pack + arp_pack
print(sendPacket(packet))
Wireshark screenshot
谢谢。
如果您将 Wireshark hexdump 与您尝试发送的内容进行匹配,您会看到实际发送的数据包的 "hardware address size" 和 "protocol address size" 字段均为 00。
这是因为您将两个字节传递给 struct.pack
(0006 和 0004),但您告诉它(使用 1s
)只格式化 1 个字节,所以它只输出第一个字节。
如果您查看 hexdump,您会发现地址确实已发送,Wireshark 只是忽略了它们,因为大小应该为 0。
只需将 0006 和 0004 更改为 06 和 04,因为它们是 1 字节字段。
一开始我想说我之前没有任何套接字经验。我正在尝试在 python 2.7 中创建响应 ARP 数据包。 我几乎完成了,但是有一个问题:当我在 wireshark 中查看数据包时,我发现 ARP header 缺少发件人和目标 mac 以及发件人和目标 ip 字段。硬件大小和协议大小字段也是错误的。我究竟做错了什么?我是否错误地打包了数据?这是程序的源代码:
import socket
import struct
import binascii
def formatMAC(mac):
return mac.lower().replace(':', '')
def sendPacket(packet):
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW)
s.bind(("wlan0", 0))
return s.send(packet)
eth_src = formatMAC('A0:88:B4:0A:A5:A8')
eth_dst = formatMAC("18:A6:F7:CF:51:B6")
eth_prt = '0806'
arp_hw_type = '0001'
arp_prt_type = '0800'
arp_hw_size = '0006'
arp_prt_size = "0004"
arp_opcode = '0002'
arp_mac_src = formatMAC('A0:88:B4:0A:A5:A8')
arp_ip_src = '192.168.0.134'
arp_mac_dst = formatMAC('18:A6:F7:CF:51:B6')
arp_ip_dst = '192.168.0.1'
eth_pack = struct.pack("!6s6s2s", binascii.unhexlify(eth_dst), binascii.unhexlify(eth_src), binascii.unhexlify(eth_prt))
arp_pack = struct.pack("2s2s1s1s2s6s4s6s4s",
binascii.unhexlify(arp_hw_type),
binascii.unhexlify(arp_prt_type),
binascii.unhexlify(arp_hw_size),
binascii.unhexlify(arp_prt_size),
binascii.unhexlify(arp_opcode),
binascii.unhexlify(arp_mac_src),
socket.inet_aton(arp_ip_src),
binascii.unhexlify(arp_mac_dst),
socket.inet_aton(arp_ip_dst)
)
packet = eth_pack + arp_pack
print(sendPacket(packet))
Wireshark screenshot
谢谢。
如果您将 Wireshark hexdump 与您尝试发送的内容进行匹配,您会看到实际发送的数据包的 "hardware address size" 和 "protocol address size" 字段均为 00。
这是因为您将两个字节传递给 struct.pack
(0006 和 0004),但您告诉它(使用 1s
)只格式化 1 个字节,所以它只输出第一个字节。
如果您查看 hexdump,您会发现地址确实已发送,Wireshark 只是忽略了它们,因为大小应该为 0。
只需将 0006 和 0004 更改为 06 和 04,因为它们是 1 字节字段。