summaryrefslogtreecommitdiff
path: root/sys/netinet/if_ether.h
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2024-02-13 13:58:20 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2024-02-13 13:58:20 +0000
commit3bf939b5dc77522812f021796d66a014be458f59 (patch)
tree5e98564ecc20b96ac4acd5523b1e56a519165e5d /sys/netinet/if_ether.h
parent7d3d1aab4b11f9c8e07a3078344f27e6176b86aa (diff)
Analyse header layout in ether_extract_headers().
Several drivers need IPv4 header length and TCP offset for checksum offload, TSO and LRO. Accessing these fields directly caused crashes on sparc64 due to misaligned access. It cannot be guaranteed that IP and TCP header is 4 byte aligned in driver level. Also gcc 4.2.1 assumes that bit fields can be accessed with 32 bit load instructions. Use memcpy() in ether_extract_headers() to get the bits from IPv4 and TCP header and store the header length in struct ether_extracted. From there network drivers can esily use it without caring about alignment and bit shift. Do some sanity checks with the length values to prevent that invalid values from evil packets get stored into hardware registers. If check fails, clear the pointer to the header to hide it from the driver. Add debug prints that help to figure out the reason for bad packets and provide information when debugging drivers. OK mglocker@
Diffstat (limited to 'sys/netinet/if_ether.h')
-rw-r--r--sys/netinet/if_ether.h5
1 files changed, 4 insertions, 1 deletions
diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h
index ed28944e721..4f5edd31b14 100644
--- a/sys/netinet/if_ether.h
+++ b/sys/netinet/if_ether.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ether.h,v 1.90 2023/07/27 20:21:25 jan Exp $ */
+/* $OpenBSD: if_ether.h,v 1.91 2024/02/13 13:58:19 bluhm Exp $ */
/* $NetBSD: if_ether.h,v 1.22 1996/05/11 13:00:00 mycroft Exp $ */
/*
@@ -307,6 +307,9 @@ struct ether_extracted {
struct ip6_hdr *ip6;
struct tcphdr *tcp;
struct udphdr *udp;
+ u_int ip4hlen;
+ u_int tcphlen;
+ u_int paylen;
};
void ether_extract_headers(struct mbuf *, struct ether_extracted *);