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