MFC after: 1 week Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D37210
84 lines
2.0 KiB
Python
84 lines
2.0 KiB
Python
#! /usr/bin/env python3
|
|
# Used to inject various malformed packets
|
|
|
|
import errno
|
|
import logging
|
|
import subprocess
|
|
import sys
|
|
|
|
logging.getLogger("scapy").setLevel(logging.CRITICAL)
|
|
|
|
from scapy.all import IP, ICMP, IPOption
|
|
import scapy.layers.all
|
|
from scapy.layers.inet import ICMPEcho_am
|
|
from scapy.layers.tuntap import TunTapInterface
|
|
|
|
SRC_ADDR = "192.0.2.14"
|
|
DST_ADDR = "192.0.2.15"
|
|
|
|
mode = sys.argv[1]
|
|
ip = None
|
|
|
|
# fill opts with nop (0x01)
|
|
opts = b''
|
|
for x in range(40):
|
|
opts += b'\x01'
|
|
|
|
|
|
# Create and configure a tun interface with an RFC5737 nonrouteable address
|
|
create_proc = subprocess.run(
|
|
args=["ifconfig", "tun", "create"],
|
|
capture_output=True,
|
|
check=True,
|
|
text=True)
|
|
iface = create_proc.stdout.strip()
|
|
tun = TunTapInterface(iface)
|
|
with open("tun.txt", "w") as f:
|
|
f.write(iface)
|
|
subprocess.run(["ifconfig", tun.iface, "up"])
|
|
subprocess.run(["ifconfig", tun.iface, SRC_ADDR, DST_ADDR])
|
|
|
|
ping = subprocess.Popen(
|
|
args=["/sbin/ping", "-v", "-c1", "-t1", DST_ADDR],
|
|
text=True
|
|
)
|
|
# Wait for /sbin/ping to ping us
|
|
echo_req = tun.recv()
|
|
|
|
# Construct the response packet
|
|
if mode == "opts":
|
|
# Sending reply with IP options
|
|
echo_reply = IP(
|
|
dst=SRC_ADDR,
|
|
src=DST_ADDR,
|
|
options=IPOption(opts)
|
|
)/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload
|
|
elif mode == "pip":
|
|
# packet in packet (inner has options)
|
|
|
|
inner = IP(
|
|
dst=SRC_ADDR,
|
|
src=DST_ADDR,
|
|
options=IPOption(opts)
|
|
)/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload
|
|
outer = IP(
|
|
dst=SRC_ADDR,
|
|
src=DST_ADDR
|
|
)/ICMP(type=3, code=1) # host unreach
|
|
|
|
echo_reply = outer/inner
|
|
elif mode == "reply":
|
|
# Sending normal echo reply
|
|
echo_reply = IP(
|
|
dst=SRC_ADDR,
|
|
src=DST_ADDR,
|
|
)/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload
|
|
else:
|
|
print("unknown mode {}".format(mode))
|
|
exit(1)
|
|
|
|
tun.send(echo_reply)
|
|
outs, errs = ping.communicate()
|
|
|
|
sys.exit(ping.returncode)
|