CentOS 下 ARP 请求代码错误解析及修复
CentOS 下 ARP 请求代码错误解析及修复
本文将详细解析 CentOS 下 ARP 请求代码中常见的错误,并提供完整的修复方案。
原始代码:
def send_arp_request(ifname, src_ip, src_mac, dst_ip):
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
s.bind((ifname, ETH_P_ALL))
dst_mac = 'ff:ff:ff:ff:ff:ff' # 广播地址
arp_packet = struct.pack('!6s6s2s2s1s1s2s6s4s6s4s', bytes(dst_mac.replace(':', ''), 'utf-8'), bytes(src_mac.replace(':', ''), 'utf-8'), bytes.fromhex('08 06'), bytes.fromhex('00 01'), bytes.fromhex('08'), bytes.fromhex('00'), bytes.fromhex('06 04'), bytes.fromhex('00 01'), socket.inet_aton(src_ip), bytes.fromhex('00 00 00 00 00 00'), socket.inet_aton(dst_ip))
s.send(arp_packet)
print('Sent ARP request to', dst_ip)
response = s.recvfrom(65535)[0]
eth_header = struct.unpack('!6s6sH', response[:14])
if eth_header[2] == ETH_P_ARP:
arp_header = struct.unpack('2s2s1s1s2s6s4s6s4s', response[14:42])
if arp_header[4] == bytes.fromhex('00 02'):
return {'src_ip': socket.inet_ntoa(arp_header[6]), 'src_mac': ':'.join(['%02x' % b for b in arp_header[5]])}
return None
问题:
该代码存在以下几个错误:
- 引入缺失的模块:代码中使用了
socket和struct模块,但没有在代码开头引入。 - 更改
bytes.fromhex()的参数:代码中有多处使用了bytes.fromhex(),但参数格式不正确。应该将参数改为字符串,且字符串中的空格应该去掉。 - 更改
socket.inet_aton()的参数:代码中使用了socket.inet_aton(),但参数应该是一个 IP 地址的字符串,而不是一个 MAC 地址的字符串。应该将src_ip和dst_ip的值改为正确的 IP 地址字符串。 - 更改返回值的格式:代码中,如果成功接收到 ARP 响应,会返回一个字典,包含源 IP 地址和源 MAC 地址。但是,如果没有接收到 ARP 响应,会返回
None。这种返回值格式不太友好,建议将返回值改为一个元组,包含源 IP 地址和源 MAC 地址。
解决方案:
- 引入缺失的模块
在代码开头加入以下代码,引入缺失的模块:
import socket
import struct
- 更改
bytes.fromhex()的参数
例如:
bytes.fromhex('08 06') # 错误
bytes.fromhex('0806') # 正确
- 更改
socket.inet_aton()的参数
例如:
src_ip = '192.168.1.100' # 正确
src_mac = '00:11:22:33:44:55' # 正确
dst_ip = '192.168.1.1' # 正确
- 更改返回值的格式
例如:
return (socket.inet_ntoa(arp_header[6]), ':'.join(['%02x' % b for b in arp_header[5]])) # 返回一个元组
完整代码:
import socket
import struct
ETH_P_ALL = 0x0003
def send_arp_request(ifname, src_ip, src_mac, dst_ip):
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
s.bind((ifname, ETH_P_ALL))
dst_mac = 'ff:ff:ff:ff:ff:ff' # 广播地址
arp_packet = struct.pack('!6s6s2s2s1s1s2s6s4s6s4s', bytes.fromhex(dst_mac.replace(':', '')), bytes.fromhex(src_mac.replace(':', '')), bytes.fromhex('0806'), bytes.fromhex('0001'), bytes.fromhex('08'), bytes.fromhex('00'), bytes.fromhex('0604'), bytes.fromhex('0001'), socket.inet_aton(src_ip), bytes.fromhex('000000000000'), socket.inet_aton(dst_ip))
s.send(arp_packet)
print('Sent ARP request to', dst_ip)
response = s.recvfrom(65535)[0]
eth_header = struct.unpack('!6s6sH', response[:14])
if eth_header[2] == ETH_P_ALL:
arp_header = struct.unpack('2s2s1s1s2s6s4s6s4s', response[14:42])
if arp_header[4] == bytes.fromhex('0002'):
return (socket.inet_ntoa(arp_header[6]), ':'.join(['%02x' % b for b in arp_header[5]]))
return None
# 示例
if __name__ == '__main__':
src_ip = '192.168.1.100'
src_mac = '00:11:22:33:44:55'
dst_ip = '192.168.1.1'
result = send_arp_request('eth0', src_ip, src_mac, dst_ip)
if result:
print('Received ARP response from', result[0], 'with MAC address', result[1])
else:
print('No ARP response received')
注意:
- 代码中的
ifname是网卡名称,需要根据实际情况修改。 - 代码中的
src_ip、src_mac、dst_ip是源 IP 地址、源 MAC 地址和目标 IP 地址,需要根据实际情况修改。 - 代码中的
ETH_P_ALL是一个常量,表示接收所有协议的数据包,可以根据实际情况修改。
总结:
本文详细解析了 CentOS 下 ARP 请求代码中常见的错误,并提供完整的修复方案,包括引入缺失模块、修改参数格式、更改返回值等,并附带代码示例。希望本文能够帮助你解决 CentOS 下 ARP 请求代码的错误问题。
原文地址: https://www.cveoy.top/t/topic/jm9o 著作权归作者所有。请勿转载和采集!