1#!/usr/local/bin/python2.7 2# $OpenBSD: sendrecv.py,v 1.2 2019/05/10 14:45:00 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 = ""; 39if sendsz is not None: 40 for i in range(sendsz): 41 payload += chr(i & 0xff) 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