mirror of
https://github.com/openbsd/src.git
synced 2025-01-04 23:35:36 -08:00
Recalculate checksum of normalised packet
In 2011, henning@ removed fiddling with the ip checksum of normalised packets in r1.131 of sys/net/pf_norm.c. Rationale was that the checksum is always recalculated in all output paths anyway. In 2016, procter@ reintroduced checksum modification to preserve end-to-end checksums in r1.189 of sys/net/pf_norm.c. Likely soomewhere in that timeslot checksum recalculation of normalised packets was broken. With input from bluhm@. OK sashan@, bluhm@
This commit is contained in:
parent
6e8568b906
commit
33c43c6d64
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf.c,v 1.1140 2022/09/03 19:22:19 bluhm Exp $ */
|
||||
/* $OpenBSD: pf.c,v 1.1141 2022/10/10 16:43:12 bket Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -164,7 +164,7 @@ void pf_add_threshold(struct pf_threshold *);
|
||||
int pf_check_threshold(struct pf_threshold *);
|
||||
int pf_check_tcp_cksum(struct mbuf *, int, int,
|
||||
sa_family_t);
|
||||
static __inline void pf_cksum_fixup(u_int16_t *, u_int16_t, u_int16_t,
|
||||
__inline void pf_cksum_fixup(u_int16_t *, u_int16_t, u_int16_t,
|
||||
u_int8_t);
|
||||
void pf_cksum_fixup_a(u_int16_t *, const struct pf_addr *,
|
||||
const struct pf_addr *, sa_family_t, u_int8_t);
|
||||
@ -1937,7 +1937,7 @@ pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
|
||||
* Note: this serves also as a reduction step for at most one add (as the
|
||||
* trailing mod 2^16 prevents further reductions by destroying carries).
|
||||
*/
|
||||
static __inline void
|
||||
__inline void
|
||||
pf_cksum_fixup(u_int16_t *cksum, u_int16_t was, u_int16_t now,
|
||||
u_int8_t proto)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf_norm.c,v 1.224 2022/08/22 20:35:39 bluhm Exp $ */
|
||||
/* $OpenBSD: pf_norm.c,v 1.225 2022/10/10 16:43:12 bket Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
@ -1646,14 +1646,21 @@ pf_scrub(struct mbuf *m, u_int16_t flags, sa_family_t af, u_int8_t min_ttl,
|
||||
#ifdef INET6
|
||||
struct ip6_hdr *h6 = mtod(m, struct ip6_hdr *);
|
||||
#endif /* INET6 */
|
||||
u_int16_t old;
|
||||
|
||||
/* Clear IP_DF if no-df was requested */
|
||||
if (flags & PFSTATE_NODF && af == AF_INET && h->ip_off & htons(IP_DF))
|
||||
if (flags & PFSTATE_NODF && af == AF_INET && h->ip_off & htons(IP_DF)) {
|
||||
old = h->ip_off;
|
||||
h->ip_off &= htons(~IP_DF);
|
||||
pf_cksum_fixup(&h->ip_sum, old, h->ip_off, 0);
|
||||
}
|
||||
|
||||
/* Enforce a minimum ttl, may cause endless packet loops */
|
||||
if (min_ttl && af == AF_INET && h->ip_ttl < min_ttl)
|
||||
if (min_ttl && af == AF_INET && h->ip_ttl < min_ttl) {
|
||||
old = h->ip_ttl;
|
||||
h->ip_ttl = min_ttl;
|
||||
pf_cksum_fixup(&h->ip_sum, old, h->ip_ttl, 0);
|
||||
}
|
||||
#ifdef INET6
|
||||
if (min_ttl && af == AF_INET6 && h6->ip6_hlim < min_ttl)
|
||||
h6->ip6_hlim = min_ttl;
|
||||
@ -1661,8 +1668,15 @@ pf_scrub(struct mbuf *m, u_int16_t flags, sa_family_t af, u_int8_t min_ttl,
|
||||
|
||||
/* Enforce tos */
|
||||
if (flags & PFSTATE_SETTOS) {
|
||||
if (af == AF_INET)
|
||||
if (af == AF_INET) {
|
||||
/*
|
||||
* ip_tos is 8 bit field at offset 1. Use 16 bit value
|
||||
* at offset 0.
|
||||
*/
|
||||
old = *(u_int16_t *)h;
|
||||
h->ip_tos = tos | (h->ip_tos & IPTOS_ECN_MASK);
|
||||
pf_cksum_fixup(&h->ip_sum, old, *(u_int16_t *)h, 0);
|
||||
}
|
||||
#ifdef INET6
|
||||
if (af == AF_INET6) {
|
||||
/* drugs are unable to explain such idiocy */
|
||||
@ -1674,6 +1688,9 @@ pf_scrub(struct mbuf *m, u_int16_t flags, sa_family_t af, u_int8_t min_ttl,
|
||||
|
||||
/* random-id, but not for fragments */
|
||||
if (flags & PFSTATE_RANDOMID && af == AF_INET &&
|
||||
!(h->ip_off & ~htons(IP_DF)))
|
||||
!(h->ip_off & ~htons(IP_DF))) {
|
||||
old = h->ip_id;
|
||||
h->ip_id = htons(ip_randomid());
|
||||
pf_cksum_fixup(&h->ip_sum, old, h->ip_id, 0);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfvar.h,v 1.510 2022/09/03 14:57:54 yasuoka Exp $ */
|
||||
/* $OpenBSD: pfvar.h,v 1.511 2022/10/10 16:43:12 bket Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -1745,6 +1745,8 @@ extern void pf_print_state(struct pf_state *);
|
||||
extern void pf_print_flags(u_int8_t);
|
||||
extern void pf_addrcpy(struct pf_addr *, struct pf_addr *,
|
||||
sa_family_t);
|
||||
extern void pf_cksum_fixup(u_int16_t *, u_int16_t,
|
||||
u_int16_t, u_int8_t);
|
||||
void pf_rm_rule(struct pf_rulequeue *,
|
||||
struct pf_rule *);
|
||||
void pf_purge_rule(struct pf_rule *);
|
||||
|
Loading…
Reference in New Issue
Block a user