-/* $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
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);
* 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)
{
-/* $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>
#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;
/* 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 */
/* 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);
+ }
}
-/* $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
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 *);