This fixes a -Waddress-of-packed-member error raised by GCC 9.
The build fails with GCC on all architectures.
FreeBSD doesn't work on architectures where char is not a byte. See all the uses of 'caddr_t'. This is the code in udp_input to calculate the pointer:
ip = mtod(m, struct ip *); uh = (struct udphdr *)((caddr_t)ip + iphlen);
In fact, it'd probably be cleaner to write this instead as
struct udphdr *u = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
to more closely match udp_input. A hlen helper variable for ip->ip_hl << 2 wouldn't be bad either.
If char is really 32-bits long, then the uint8_t type must necessarily also be at least 32-bits long. char is the smallest unit you can have in C, absent non-standard extensions (and ignoring the special case of bit fields which aren't a first-class type).
*sigh* Now this causes a -Wcast-align error with clang even though it's the same exact code as used in udp_input() in the kernel. I guess the kernel doesn't build with -Wcast-align perhaps?