Fragment one large 64k IP ping packet into 155 fragments, each with
authorbluhm <bluhm@openbsd.org>
Fri, 7 Sep 2018 13:10:38 +0000 (13:10 +0000)
committerbluhm <bluhm@openbsd.org>
Fri, 7 Sep 2018 13:10:38 +0000 (13:10 +0000)
424 bytes payload.  Send them in random order.  Expect a fragment
with matching echo reply header.

regress/sys/netinet/frag/frag_maxlen.py [new file with mode: 0644]
regress/sys/netinet6/frag6/frag6_maxlen.py [new file with mode: 0644]

diff --git a/regress/sys/netinet/frag/frag_maxlen.py b/regress/sys/netinet/frag/frag_maxlen.py
new file mode 100644 (file)
index 0000000..1e727e2
--- /dev/null
@@ -0,0 +1,62 @@
+#!/usr/local/bin/python2.7
+
+print "fully fragmented maximum size ping packet, sent in random order"
+
+#          |----|
+#                                        |----|
+#                              |----|
+#                                                       |----|
+#     |----|
+
+import os
+import random
+from addr import *
+from scapy.all import *
+
+pid=os.getpid()
+eid=pid & 0xffff
+iplen=2**16
+size=424
+payload="ABCDEFGHIJKLMNOP" * (iplen / 16)
+packet=IP(src=LOCAL_ADDR, dst=REMOTE_ADDR)/ \
+    ICMP(type='echo-request', id=eid)/str(payload)[0:iplen-20-8-1]
+frag=[]
+fid=pid & 0xffff
+max=(iplen-20)/size
+for i in range(max):
+       frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
+           frag=i*(size/8), flags='MF')/str(packet)[20+i*size:20+(i+1)*size])
+frag.append(IP(src=LOCAL_ADDR, dst=REMOTE_ADDR, proto=1, id=fid,
+    frag=max*(size/8))/str(packet)[20+max*size:])
+eth=[]
+for f in frag:
+       eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/f)
+
+child = os.fork()
+if child == 0:
+       time.sleep(1)
+       randeth=eth
+       random.shuffle(randeth)
+       for e in randeth:
+               sendp(e, iface=LOCAL_IF)
+               time.sleep(0.001)
+       os._exit(0)
+
+ans=sniff(iface=LOCAL_IF, timeout=10, filter=
+    "ip and src "+REMOTE_ADDR+" and dst "+LOCAL_ADDR+" and icmp")
+os.kill(child, 15)
+os.wait()
+
+for a in ans:
+       if a and a.type == ETH_P_IP and \
+           a.payload.frag == 0 and \
+           a.payload.proto == 1 and \
+           icmptypes[a.payload.payload.type] == 'echo-reply':
+               id=a.payload.payload.id
+               print "id=%#x" % (id)
+               if id != eid:
+                       print "WRONG ECHO REPLY ID"
+                       exit(2)
+               exit(0)
+print "NO ECHO REPLY"
+exit(1)
diff --git a/regress/sys/netinet6/frag6/frag6_maxlen.py b/regress/sys/netinet6/frag6/frag6_maxlen.py
new file mode 100644 (file)
index 0000000..70040b3
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/local/bin/python2.7
+
+print "fully fragmented maximum size ping6 packet, sent in random order"
+
+#          |----|
+#                                        |----|
+#                              |----|
+#                                                       |----|
+#     |----|
+
+import os
+import random
+from addr import *
+from scapy.all import *
+
+pid=os.getpid()
+eid=pid & 0xffff
+iplen=2**16
+size=424
+payload="ABCDEFGHIJKLMNOP" * (iplen / 16)
+packet=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/ \
+    ICMPv6EchoRequest(id=eid, data=str(payload)[0:iplen-8-1])
+frag=[]
+fid=pid & 0xffffffff
+max=iplen/size
+for i in range(max):
+       frag.append(IPv6ExtHdrFragment(nh=58, id=fid, m=1,
+           offset=i*(size/8))/str(packet)[40+i*size:40+(i+1)*size])
+frag.append(IPv6ExtHdrFragment(nh=58, id=fid,
+    offset=max*(size/8))/str(packet)[40+max*size:])
+eth=[]
+for f in frag:
+       pkt=IPv6(src=LOCAL_ADDR6, dst=REMOTE_ADDR6)/f
+       eth.append(Ether(src=LOCAL_MAC, dst=REMOTE_MAC)/pkt)
+
+child = os.fork()
+if child == 0:
+       time.sleep(1)
+       randeth=eth
+       random.shuffle(randeth)
+       for e in randeth:
+               sendp(e, iface=LOCAL_IF)
+               time.sleep(0.001)
+       os._exit(0)
+
+ans=sniff(iface=LOCAL_IF, timeout=10, filter=
+    "ip6 and src "+REMOTE_ADDR6+" and dst "+LOCAL_ADDR6+" and proto ipv6-frag")
+os.kill(child, 15)
+os.wait()
+
+for a in ans:
+       if a and a.type == ETH_P_IPV6 and \
+           ipv6nh[a.payload.nh] == 'Fragment Header' and \
+           a.payload.payload.offset == 0 and \
+           ipv6nh[a.payload.payload.nh] == 'ICMPv6' and \
+           icmp6types[a.payload.payload.payload.type] == 'Echo Reply':
+               id=a.payload.payload.payload.id
+               print "id=%#x" % (id)
+               if id != eid:
+                       print "WRONG ECHO REPLY ID"
+                       exit(2)
+               exit(0)
+print "NO ECHO REPLY"
+exit(1)