diff options
author | iedowse <iedowse@FreeBSD.org> | 2002-12-27 17:43:25 +0000 |
---|---|---|
committer | iedowse <iedowse@FreeBSD.org> | 2002-12-27 17:43:25 +0000 |
commit | f5462007056ca440dfe2c11ce75452bcdab12f57 (patch) | |
tree | 72e2f9fa523fd23d9944eaa63a3d75799d4d3c99 /sys/netinet/ip_fw2.c | |
parent | f6258ba488075f7a4561dbca1e316dd438a7af5c (diff) | |
download | FreeBSD-src-f5462007056ca440dfe2c11ce75452bcdab12f57.zip FreeBSD-src-f5462007056ca440dfe2c11ce75452bcdab12f57.tar.gz |
Bridged packets are supplied to the firewall with their IP header
in network byte order, but icmp_error() expects the IP header to
be in host order and the code here did not perform the necessary
swapping for the bridged case. This bug causes an "icmp_error: bad
length" panic when certain length IP packets (e.g. ip_len == 0x100)
are rejected by the firewall with an ICMP response.
MFC after: 3 days
Diffstat (limited to 'sys/netinet/ip_fw2.c')
-rw-r--r-- | sys/netinet/ip_fw2.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index 1e2b84e..5715587 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -1136,9 +1136,15 @@ static void send_reject(struct ip_fw_args *args, int code, int offset, int ip_len) { - if (code != ICMP_REJECT_RST) /* Send an ICMP unreach */ + if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */ + /* We need the IP header in host order for icmp_error(). */ + if (args->eh != NULL) { + struct ip *ip = mtod(args->m, struct ip *); + ip->ip_len = ntohs(ip->ip_len); + ip->ip_off = ntohs(ip->ip_off); + } icmp_error(args->m, ICMP_UNREACH, code, 0L, 0); - else if (offset == 0 && args->f_id.proto == IPPROTO_TCP) { + } else if (offset == 0 && args->f_id.proto == IPPROTO_TCP) { struct tcphdr *const tcp = L3HDR(struct tcphdr, mtod(args->m, struct ip *)); if ( (tcp->th_flags & TH_RST) == 0) |