xref: /openbsd-src/regress/sys/netinet6/rip6cksum/sendrecv.py (revision fa9278d941643d703932f7cf465a6add3f71fd1a)
1*fa9278d9Sbluhm#!/usr/local/bin/python3
2*fa9278d9Sbluhm# $OpenBSD: sendrecv.py,v 1.3 2020/12/25 13:47:43 bluhm Exp $
3d6191a09Sbluhm
4d6191a09Sbluhmimport os
5d6191a09Sbluhmfrom scapy.all import *
6d6191a09Sbluhmfrom struct import pack
7d6191a09Sbluhmimport getopt, sys
8d6191a09Sbluhm
9d6191a09Sbluhmdef usage():
10*fa9278d9Sbluhm	print("sendrecv [-hi] [-c ckoff] [-r recvsz] [-s sendsz]")
11*fa9278d9Sbluhm	print("    -c ckoff   set checksum offset within payload")
12*fa9278d9Sbluhm	print("    -h         help, show usage")
13*fa9278d9Sbluhm	print("    -i         expect icmp6 error message as response")
14*fa9278d9Sbluhm	print("    -r recvsz  expected payload size")
15*fa9278d9Sbluhm	print("    -s sendsz  set payload size")
16d6191a09Sbluhm	exit(1)
17d6191a09Sbluhm
18d6191a09Sbluhmopts, args = getopt.getopt(sys.argv[1:], "c:hir:s:")
19d6191a09Sbluhm
20d6191a09Sbluhmip = IPv6(src="::1", dst="::1", nh=255)
21d6191a09Sbluhm
22d6191a09Sbluhmckoff = None
23d6191a09Sbluhmicmp = False
24d6191a09Sbluhmrecvsz = None
25d6191a09Sbluhmsendsz = None
26d6191a09Sbluhmfor o, a in opts:
27d6191a09Sbluhm	if o == "-c":
28d6191a09Sbluhm		ckoff = int(a)
29d6191a09Sbluhm	elif o == "-i":
30d6191a09Sbluhm		icmp = True
31d6191a09Sbluhm	elif o == "-r":
32d6191a09Sbluhm		recvsz = int(a)
33d6191a09Sbluhm	elif o == "-s":
34d6191a09Sbluhm		sendsz = int(a)
35d6191a09Sbluhm	else:
36d6191a09Sbluhm		usage()
37d6191a09Sbluhm
38*fa9278d9Sbluhmpayload = b"";
39d6191a09Sbluhmif sendsz is not None:
40d6191a09Sbluhm	for i in range(sendsz):
41*fa9278d9Sbluhm		payload += pack('B', i)
42*fa9278d9Sbluhm	print("payload length is", len(payload))
43d6191a09Sbluhm
44d6191a09Sbluhmif ckoff is not None:
45d6191a09Sbluhm	payload = payload[:ckoff] + pack("xx") + payload[ckoff+2:]
46d6191a09Sbluhm	cksum = in6_chksum(255, ip, payload)
47*fa9278d9Sbluhm	print("calculated checksum is", cksum)
48d6191a09Sbluhm	payload = payload[:ckoff] + pack("!H", cksum) + payload[ckoff+2:]
49d6191a09Sbluhm
50d6191a09Sbluhmreq=ip/payload
51d6191a09Sbluhm# As we are sending from ::1 to ::1 we sniff our own packet as answer.
52d6191a09Sbluhm# Add a filter that matches on the expected answer using the payload size.
53d6191a09Sbluhmif icmp:
54d6191a09Sbluhm	filter="icmp6"
55d6191a09Sbluhm	if recvsz is not None:
56d6191a09Sbluhm		filter += (" and len = %d" % (4 + 40 + 8 + 40 + recvsz))
57d6191a09Sbluhmelse:
58d6191a09Sbluhm	filter="proto 255"
59d6191a09Sbluhm	if recvsz is not None:
60d6191a09Sbluhm		filter += (" and len = %d" % (4 + 40 + recvsz))
61*fa9278d9Sbluhmprint("filter", filter)
62d6191a09Sbluhmans=sr(req, iface="lo0", filter=filter, timeout=10)
63*fa9278d9Sbluhmprint(ans)
64d6191a09Sbluhmres=ans[0][0][1]
65d6191a09Sbluhmres.show()
66d6191a09Sbluhm
67*fa9278d9Sbluhmprint("response protocol next header is", res.nh)
68d6191a09Sbluhmif icmp:
69d6191a09Sbluhm	if res.nh != 58:
70*fa9278d9Sbluhm		print("response wrong protocol, expected icmp6")
71d6191a09Sbluhm		exit(1)
72*fa9278d9Sbluhm	print("response icmp6 type is", res.payload.type)
73d6191a09Sbluhm	if res.payload.type != 4:
74*fa9278d9Sbluhm		print("response wrong icmp6 type, expected parameter problem")
75d6191a09Sbluhm		exit(1)
76d6191a09Sbluhm	exit(0)
77d6191a09Sbluhm
78d6191a09Sbluhmif res.nh != 255:
79*fa9278d9Sbluhm	print("response with wrong protocol, expected 255, got")
80d6191a09Sbluhm	exit(1)
81d6191a09Sbluhm
82d6191a09Sbluhmcksum = in6_chksum(255, res, res.payload.load)
83*fa9278d9Sbluhmprint("received checksum is", cksum)
84d6191a09Sbluhmif ckoff is not None and cksum != 0:
85*fa9278d9Sbluhm	print("received invalid checksum", cksum)
86d6191a09Sbluhm	exit(1)
87d6191a09Sbluhm
88*fa9278d9Sbluhmprint("received payload length is", len(res.payload.load))
89d6191a09Sbluhmif recvsz is not None:
90d6191a09Sbluhm	if len(res.payload.load) != recvsz:
91*fa9278d9Sbluhm		print("wrong payload length, expected", recvsz)
92d6191a09Sbluhm		exit(1)
93d6191a09Sbluhm
94d6191a09Sbluhmexit(0)
95