summaryrefslogtreecommitdiffstats
path: root/sys/net/if_bridge.c
diff options
context:
space:
mode:
authordhartmei <dhartmei@FreeBSD.org>2006-05-15 11:49:01 +0000
committerdhartmei <dhartmei@FreeBSD.org>2006-05-15 11:49:01 +0000
commitadb361fa57e7fb1f6c2cbba86f93c803e3f26b66 (patch)
treee5a2a5b6c650aa7a9dfdaee339b254758c797b74 /sys/net/if_bridge.c
parentc6e771a4186712ad0136a8ffb9cf7821cfe8e8f6 (diff)
downloadFreeBSD-src-adb361fa57e7fb1f6c2cbba86f93c803e3f26b66.zip
FreeBSD-src-adb361fa57e7fb1f6c2cbba86f93c803e3f26b66.tar.gz
Recalculate IP checksum after running pfil hooks.
Reviewed by: thompsa Tested by: Adam McDougall <mcdouga9@egr.msu.edu>
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r--sys/net/if_bridge.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 80eb0b4..78dfd98 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -2590,7 +2590,7 @@ bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
static int
bridge_pfil(struct mbuf **mp, struct ifnet *bifp, struct ifnet *ifp, int dir)
{
- int snap, error, i;
+ int snap, error, i, hlen;
struct ether_header *eh1, eh2;
struct ip_fw_args args;
struct ip *ip;
@@ -2785,10 +2785,25 @@ ipfwpass:
}
}
- /* Restore ip and the fields ntohs()'d. */
+ /* Recalculate the ip checksum and restore byte ordering */
ip = mtod(*mp, struct ip *);
+ hlen = ip->ip_hl << 2;
+ if (hlen < sizeof(struct ip))
+ goto bad;
+ if (hlen > (*mp)->m_len) {
+ if ((*mp = m_pullup(*mp, hlen)) == 0)
+ goto bad;
+ ip = mtod(*mp, struct ip *);
+ if (ip == NULL)
+ goto bad;
+ }
ip->ip_len = htons(ip->ip_len);
ip->ip_off = htons(ip->ip_off);
+ ip->ip_sum = 0;
+ if (hlen == sizeof(struct ip))
+ ip->ip_sum = in_cksum_hdr(ip);
+ else
+ ip->ip_sum = in_cksum(*mp, hlen);
break;
# ifdef INET6
OpenPOWER on IntegriCloud