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);

Reply via email to