Scapy发送超1514字节数据包遇OSError: [Errno 90]问题求助
问题
使用Scapy发送长度超过1514字节的数据包时,触发错误:OSError: [Errno 90] Message too long,能否无需拆分数据包,直接发送超过该大小的数据包?
用户测试代码:
import os load = os.urandom(1481) pkt = Ether()/IP(dst="192.168.10.104")/load print("len=",len(pkt)) sendp(pkt)
报错信息:
len= 1515 --------------------------------------------------------------------------- OSError Traceback (most recent call last) /tmp/ipykernel_83506/53727884.py in <module> 3 pkt = Ether()/IP(dst="192.168.10.104")/load 4 print("len=",len(pkt)) ----> 5 sendp(pkt) /opt/anaconda3/lib/python3.9/site-packages/scapy/sendrecv.py in sendp(x, inter, loop, iface, iface_hint, count, verbose, realtime, return_packets, socket, *args, **kargs) 334 need_closing = socket is None 335 socket = socket or conf.L2socket(iface=iface, *args, **kargs) ---> 336 results = __gen_send(socket, x, inter=inter, loop=loop, 337 count=count, verbose=verbose, 338 realtime=realtime, return_packets=return_packets) /opt/anaconda3/lib/python3.9/site-packages/scapy/sendrecv.py in __gen_send(s, x, inter, loop, count, verbose, realtime, return_packets, *args, **kargs) 289 else: 290 dt0 = ct - p.time ---> 291 s.send(p) 292 if return_packets: 293 sent_packets.append(p) /opt/anaconda3/lib/python3.9/site-packages/scapy/arch/linux.py in send(self, x) 557 def send(self, x): 558 try: ---> 559 return SuperSocket.send(self, x) 560 except socket.error as msg: 561 if msg.errno == 22 and len(x) < conf.min_pkt_size: /opt/anaconda3/lib/python3.9/site-packages/scapy/supersocket.py in send(self, x) 47 def send(self, x): 48 sx = raw(x) ---> 49 sent = self.outs.send(sx) 50 try: 51 x.sent_time = time.time() OSError: [Errno 90] Message too long
解决方案
可以直接发送超过1514字节的数据包,但需要完成以下两步配置:
1. 启用网卡巨帧支持
1514字节是标准以太网帧的MTU(不含VLAN标签),要发送更大的帧,需将网卡MTU调高(常见巨帧MTU为9000):
Linux临时配置(重启失效)
sudo ip link set dev <你的网卡名> mtu 9000
Linux永久配置(Debian/Ubuntu为例)
编辑Netplan配置文件(如/etc/netplan/00-installer-config.yaml):
network: ethernets: <你的网卡名>: mtu: 9000 # 保留原有其他配置 version: 2
执行以下命令生效:
sudo netplan apply
2. 配置Scapy适配巨帧
修改Scapy的Socket配置,使其支持更大的MTU:
示例代码:
import os from scapy.all import Ether, IP, sendp, conf # 配置L2Socket支持9000字节MTU conf.L2socket = conf.L2socket(mtu=9000) # 生成对应大小的负载:9000 - 14(以太网头) - 20(IP头) = 8966 load = os.urandom(8966) pkt = Ether()/IP(dst="192.168.10.104")/load print("len=", len(pkt)) sendp(pkt)
也可以在发送时直接指定Socket:
import os from scapy.all import Ether, IP, sendp, conf load = os.urandom(8966) pkt = Ether()/IP(dst="192.168.10.104")/load print("len=", len(pkt)) # 创建支持9000 MTU的Socket并发送 sock = conf.L2socket(mtu=9000) sendp(pkt, socket=sock)
注意事项
- 接收端网卡必须设置相同MTU,否则数据包会被丢弃
- 链路中的所有网络设备(交换机、路由器)都需支持对应MTU的巨帧
- 如果仅需测试分片传输,可使用Scapy的
fragment函数,但这不符合“无需拆分”的需求
内容的提问来源于stack exchange,提问作者Aztec N
相关产品推荐
相关产品推荐

