Hi,
When sending IP packets to userland with divert-packet rules, the
checksum may be wrong. Locally generated packets diverted by pf
out rules may have no checksum due to to hardware offloading.
IDS/IPS systems may complain about that.
Calculate the checksum in that case.
ok?
bluhm
Index: netinet/ip_divert.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_divert.c,v
retrieving revision 1.89
diff -u -p -r1.89 ip_divert.c
--- netinet/ip_divert.c 17 Oct 2022 14:49:02 -0000 1.89
+++ netinet/ip_divert.c 3 Apr 2023 19:18:59 -0000
@@ -190,6 +190,8 @@ divert_packet(struct mbuf *m, int dir, u
struct inpcb *inp = NULL;
struct socket *so;
struct sockaddr_in sin;
+ struct ip *ip;
+ int off;
divstat_inc(divs_ipackets);
@@ -232,6 +234,17 @@ divert_packet(struct mbuf *m, int dir, u
break;
}
if_put(ifp);
+ } else {
+ /*
+ * Calculate IP and protocol checksums for outbound packet
+ * diverted to userland. pf rule diverts before cksum offload.
+ */
+ ip = mtod(m, struct ip *);
+ off = ip->ip_hl << 2;
+
+ ip->ip_sum = 0;
+ ip->ip_sum = in_cksum(m, off);
+ in_proto_cksum_out(m, NULL);
}
mtx_enter(&inp->inp_mtx);
Index: netinet6/ip6_divert.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_divert.c,v
retrieving revision 1.88
diff -u -p -r1.88 ip6_divert.c
--- netinet6/ip6_divert.c 17 Oct 2022 14:49:02 -0000 1.88
+++ netinet6/ip6_divert.c 3 Apr 2023 19:19:06 -0000
@@ -238,6 +238,12 @@ divert6_packet(struct mbuf *m, int dir,
break;
}
if_put(ifp);
+ } else {
+ /*
+ * Calculate protocol checksum for outbound packet diverted
+ * to userland. pf out rule diverts before cksum offload.
+ */
+ in6_proto_cksum_out(m, NULL);
}
mtx_enter(&inp->inp_mtx);