summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordhartmei <dhartmei@openbsd.org>2006-03-25 20:55:24 +0000
committerdhartmei <dhartmei@openbsd.org>2006-03-25 20:55:24 +0000
commitadcef2ddaa1af4aeee7a834bafb3e64a9c6e8603 (patch)
tree20db204fac9dc43317be343f4097bc03d36a18c4 /sys
parenthook telldir (diff)
downloadwireguard-openbsd-adcef2ddaa1af4aeee7a834bafb3e64a9c6e8603.tar.xz
wireguard-openbsd-adcef2ddaa1af4aeee7a834bafb3e64a9c6e8603.zip
fixup IP checksum when modifying IP header fields, based on a patch in
fbsd PR 93849 from Max Laier, ok claudio@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/pf_norm.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index ad10d05de14..85e2d63b84e 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.105 2006/03/14 11:09:42 djm Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.106 2006/03/25 20:55:24 dhartmei Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -866,8 +866,12 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
goto drop;
/* Clear IP_DF if the rule uses the no-df option */
- if (r->rule_flag & PFRULE_NODF)
+ if (r->rule_flag & PFRULE_NODF && h->ip_off & htons(IP_DF)) {
+ u_int16_t ip_off = h->ip_off;
+
h->ip_off &= htons(~IP_DF);
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
+ }
/* We will need other tests here */
if (!fragoff && !mff)
@@ -970,11 +974,20 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
no_fragment:
/* At this point, only IP_DF is allowed in ip_off */
- h->ip_off &= htons(IP_DF);
+ if (h->ip_off & ~htons(IP_DF)) {
+ u_int16_t ip_off = h->ip_off;
+
+ h->ip_off &= htons(IP_DF);
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
+ }
/* Enforce a minimum ttl, may cause endless packet loops */
- if (r->min_ttl && h->ip_ttl < r->min_ttl)
+ if (r->min_ttl && h->ip_ttl < r->min_ttl) {
+ u_int16_t ip_ttl = h->ip_ttl;
+
h->ip_ttl = r->min_ttl;
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
+ }
if (r->rule_flag & PFRULE_RANDOMID) {
u_int16_t ip_id = h->ip_id;
@@ -989,8 +1002,12 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
fragment_pass:
/* Enforce a minimum ttl, may cause endless packet loops */
- if (r->min_ttl && h->ip_ttl < r->min_ttl)
+ if (r->min_ttl && h->ip_ttl < r->min_ttl) {
+ u_int16_t ip_ttl = h->ip_ttl;
+
h->ip_ttl = r->min_ttl;
+ h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
+ }
if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
pd->flags |= PFDESC_IP_REAS;
return (PF_PASS);