2 # SPDX-License-Identifier: GPL-2.0
5 This script helps generate fragmented UDP packets.
7 While it is technically possible to dynamically generate
8 fragmented packets in C, it is much harder to read and write
9 said code. `scapy` is relatively industry standard and really
12 So we choose to write this script that generates a valid C
13 header. Rerun script and commit generated file after any
20 from scapy
.all
import *
23 # These constants must stay in sync with `ip_check_defrag.c`
24 VETH1_ADDR
= "172.16.1.200"
25 VETH0_ADDR6
= "fc00::100"
26 VETH1_ADDR6
= "fc00::200"
29 MAGIC_MESSAGE
= "THIS IS THE ORIGINAL MESSAGE, PLEASE REASSEMBLE ME"
33 f
.write("// SPDX-License-Identifier: GPL-2.0\n")
34 f
.write("/* DO NOT EDIT -- this file is generated */\n")
36 f
.write("#ifndef _IP_CHECK_DEFRAG_FRAGS_H\n")
37 f
.write("#define _IP_CHECK_DEFRAG_FRAGS_H\n")
39 f
.write("#include <stdint.h>\n")
43 def print_frags(f
, frags
, v6
):
44 for idx
, frag
in enumerate(frags
):
45 # 10 bytes per line to keep width in check
46 chunks
= [frag
[i
: i
+ 10] for i
in range(0, len(frag
), 10)]
47 chunks_fmted
= [", ".join([str(hex(b
)) for b
in chunk
]) for chunk
in chunks
]
48 suffix
= "6" if v6
else ""
50 f
.write(f
"static uint8_t frag{suffix}_{idx}[] = {{\n")
51 for chunk
in chunks_fmted
:
52 f
.write(f
"\t{chunk},\n")
58 f
.write("#endif /* _IP_CHECK_DEFRAG_FRAGS_H */\n")
62 # srcip of 0 is filled in by IP_HDRINCL
69 payload
= MAGIC_MESSAGE
.encode()
71 # Disable UDPv4 checksums to keep code simpler
72 pkt
= IP(src
=sip
,dst
=dip
) / UDP(sport
=sport
,dport
=dport
,chksum
=0) / Raw(load
=payload
)
73 # UDPv6 requires a checksum
74 # Also pin the ipv6 fragment header ID, otherwise it's a random value
75 pkt6
= IPv6(src
=sip6
,dst
=dip6
) / IPv6ExtHdrFragment(id=0xBEEF) / UDP(sport
=sport
,dport
=dport
) / Raw(load
=payload
)
77 frags
= [f
.build() for f
in pkt
.fragment(24)]
78 frags6
= [f
.build() for f
in fragment6(pkt6
, 72)]
81 print_frags(f
, frags
, False)
82 print_frags(f
, frags6
, True)
86 if __name__
== "__main__":
87 dir = os
.path
.dirname(os
.path
.realpath(__file__
))
88 header
= f
"{dir}/ip_check_defrag_frags.h"
89 with
open(header
, "w") as f
: