]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sbin/ping/tests/injection.py
unbound: Import upstream 0ee44ef3 when ENOBUFS is returned
[FreeBSD/FreeBSD.git] / sbin / ping / tests / injection.py
1 #! /usr/bin/env python3
2 # Used to inject various malformed packets
3
4 import errno
5 import logging
6 import subprocess
7 import sys
8
9 logging.getLogger("scapy").setLevel(logging.CRITICAL)
10
11 from scapy.all import IP, ICMP, IPOption
12 import scapy.layers.all
13 from scapy.layers.inet import ICMPEcho_am
14 from scapy.layers.tuntap import TunTapInterface
15
16 SRC_ADDR = "192.0.2.14"
17 DST_ADDR = "192.0.2.15"
18
19 mode = sys.argv[1]
20 ip = None
21
22 # fill opts with nop (0x01)
23 opts = b''
24 for x in range(40):
25     opts += b'\x01'
26
27
28 # Create and configure a tun interface with an RFC5737 nonrouteable address
29 create_proc = subprocess.run(
30     args=["ifconfig", "tun", "create"],
31     capture_output=True,
32     check=True,
33     text=True)
34 iface = create_proc.stdout.strip()
35 tun = TunTapInterface(iface)
36 with open("tun.txt", "w") as f:
37     f.write(iface)
38 subprocess.run(["ifconfig", tun.iface, "up"])
39 subprocess.run(["ifconfig", tun.iface, SRC_ADDR, DST_ADDR])
40
41 ping = subprocess.Popen(
42         args=["/sbin/ping", "-v", "-c1", "-t1", DST_ADDR],
43         text=True
44 )
45 # Wait for /sbin/ping to ping us
46 echo_req = tun.recv()
47
48 # Construct the response packet
49 if mode == "opts":
50     # Sending reply with IP options
51     echo_reply = IP(
52         dst=SRC_ADDR,
53         src=DST_ADDR,
54         options=IPOption(opts)
55     )/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload
56 elif mode == "pip":
57     # packet in packet (inner has options)
58
59     inner = IP(
60         dst=SRC_ADDR,
61         src=DST_ADDR,
62         options=IPOption(opts)
63     )/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload
64     outer = IP(
65         dst=SRC_ADDR,
66         src=DST_ADDR
67     )/ICMP(type=3, code=1)  # host unreach
68
69     echo_reply = outer/inner
70 elif mode == "reply":
71     # Sending normal echo reply
72     echo_reply = IP(
73         dst=SRC_ADDR,
74         src=DST_ADDR,
75     )/ICMP(type=0, code=0, id=echo_req.payload.id)/echo_req.payload.payload
76 else:
77     print("unknown mode {}".format(mode))
78     exit(1)
79
80 tun.send(echo_reply)
81 outs, errs = ping.communicate()
82
83 sys.exit(ping.returncode)