Python网络IDS获取ARP表时遇IndexError:索引越界问题求助
问题解决:ARP表获取代码触发IndexError
报错原因
你的代码里re.findall没有匹配到任何ARP表条目,导致line是空列表,访问line[0]自然触发IndexError: list index out of range。核心问题是正则表达式和Kali Linux下arp -a的输出格式不匹配——原正则是针对Windows系统的ARP输出,而Linux的arp -a输出结构完全不同。
比如Kali下arp -a的典型输出是:
_gateway (192.168.1.1) at aa:bb:cc:dd:ee:ff [ether] on eth0
原正则([-.0-9]+)\s+([-0-9a-f]{17})\s+(\w+)根本匹配不上这种格式,所以返回空列表。
修复方案
1. 适配Linux的正则表达式
替换原正则为适配Linux ARP输出的规则,同时增加错误处理逻辑:
import os import re def get_default_gateway(self): with os.popen('arp -a') as f: data = f.read() # 适配Linux下arp -a的输出格式,匹配网关IP和MAC line = re.findall(r'_gateway \((\d+\.\d+\.\d+\.\d+)\) at ([0-9a-fA-F:]{17})', data) if not line: # 未匹配到网关时抛出异常或返回默认值,根据需求调整 raise ValueError("Failed to retrieve default gateway from ARP table") ip_gateway = line[0][0] mac_gateway = line[0][1] return ip_gateway, mac_gateway def check_mac_change(self, ip, mac)->int: ret = 0 try: ip_gw, mac_gw = self.get_default_gateway() if mac_gw != mac: ret = 1 except ValueError as e: print(e) # 处理获取网关失败的情况,比如返回错误码 ret = -1 return ret
2. 关键调整说明
- 正则表达式
r'_gateway \((\d+\.\d+\.\d+\.\d+)\) at ([0-9a-fA-F:]{17})'专门匹配Linux下网关的ARP条目,提取IP和MAC地址。 - 增加
if not line:判断,提前处理匹配失败的情况,避免索引越界。 - 在
check_mac_change中加入try-except捕获异常,增强代码健壮性。
3. 额外建议
如果需要跨平台兼容(同时支持Windows和Linux),可以先判断操作系统,再选择对应的正则和ARP命令:
import platform def get_default_gateway(self): if platform.system() == 'Windows': cmd = 'arp -a' pattern = r'([-.0-9]+)\s+([-0-9a-f]{17})\s+(\w+)' else: cmd = 'arp -a' pattern = r'_gateway \((\d+\.\d+\.\d+\.\d+)\) at ([0-9a-fA-F:]{17})' with os.popen(cmd) as f: data = f.read() line = re.findall(pattern, data) if not line: raise ValueError("Failed to retrieve default gateway from ARP table") ip_gateway = line[0][0] mac_gateway = line[0][1] return ip_gateway, mac_gateway
内容的提问来源于stack exchange,提问作者Unknown Coder
相关产品推荐
相关产品推荐

