Hi,

tcpdump pflog with addresses rewritten by rdr-to, nat-to, or af-to
is broken.

1. Fix address family of the packet in af-to rules:

before:
19:26:37.620926 169.254.0.14 > 169.254.0.14: icmp: echo request
19:26:37.620946 bad-ip6-version 4
19:26:37.620963 fc00::23 > fc00::24: icmp6: echo request
19:26:37.620977 bad-ip-version 6

after:
19:26:29.606966 169.254.0.14 > 169.254.0.14: icmp: echo request
19:26:29.606990 169.254.0.14 > 169.254.0.14: icmp: echo request
19:26:29.607006 fc00::23 > fc00::24: icmp6: echo request
19:26:29.607019 fc00::24 > fc00::23: icmp6: type-#0

The type-#0 is still buggy, but it is a step in the right direction.

2. Print the addresses that were rewritten if called with -ev:

This is rdr-to.  Note that "orig src" is the modified address.

before:
19:32:34.843807 rule 2.regress.19/(match) [uid 0, pid 37810] pass out on lo11: 
[orig src 169.254.0.22:59443, dst 169.254.0.12:9] 169.254.0.12.42793 > 
169.254.0.12.9: [bad udp cksum 0900! -> 152f] udp 4 (ttl 64, id 11544, len 32, 
bad ip cksum c! -> f9a0)

after:
19:32:06.794193 rule 2.regress.19/(match) [uid 0, pid 37810] pass out on lo11: 
[rewritten: src 169.254.0.22:52093, dst 169.254.0.12:9] 169.254.0.12.1885 > 
169.254.0.12.9: [bad udp cksum 27aa! -> e1ce] udp 4 (ttl 64, id 5110, len 32, 
bad ip cksum c! -> 12c3)

With af-to the old code confuses the address family:

before:
19:33:45.731267 rule 2.regress.22/(match) [uid 0, pid 37810] pass in on lo11: 
[orig src 252.0.0.0:64597, dst 252.0.0.0:9] [|ip6]

after:
19:34:05.388153 rule 2.regress.22/(match) [uid 0, pid 37810] pass in on lo11: 
[rewritten: src fc00::23:65141, dst fc00::24:9] 169.254.0.14.10027 > 
169.254.0.14.9: [udp sum ok] udp 4 (ttl 64, id 27481, len 32)

Basically the kernel uses the information from the packet description
and fills it into the fields in the pflog header.  While doing this,
it is trival to figure out whether the packet has been rewritten.

ok?

bluhm

Index: sys/net/if_pflog.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if_pflog.c,v
retrieving revision 1.94
diff -u -p -r1.94 if_pflog.c
--- sys/net/if_pflog.c  13 Jan 2021 09:13:30 -0000      1.94
+++ sys/net/if_pflog.c  18 Jan 2021 18:16:04 -0000
@@ -231,11 +231,18 @@ pflog_packet(struct pf_pdesc *pd, u_int8
        hdr.rule_uid = rm->cuid;
        hdr.rule_pid = rm->cpid;
        hdr.dir = pd->dir;
+       hdr.af = pd->af;
 
+       if (pd->af != pd->naf ||
+           pf_addr_compare(pd->src, &pd->nsaddr, pd->naf) != 0 ||
+           pf_addr_compare(pd->dst, &pd->ndaddr, pd->naf) != 0 ||
+           pd->osport != pd->nsport ||
+           pd->odport != pd->ndport) {
+               hdr.rewritten = 1;
+       }
+       hdr.naf = pd->naf;
        pf_addrcpy(&hdr.saddr, &pd->nsaddr, pd->naf);
        pf_addrcpy(&hdr.daddr, &pd->ndaddr, pd->naf);
-       hdr.af = pd->af;
-       hdr.naf = pd->naf;
        hdr.sport = pd->nsport;
        hdr.dport = pd->ndport;
 
Index: usr.sbin/tcpdump/print-pflog.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/tcpdump/print-pflog.c,v
retrieving revision 1.32
diff -u -p -r1.32 print-pflog.c
--- usr.sbin/tcpdump/print-pflog.c      22 Oct 2018 16:12:45 -0000      1.32
+++ usr.sbin/tcpdump/print-pflog.c      18 Jan 2021 17:41:05 -0000
@@ -64,7 +64,6 @@ pflog_if_print(u_char *user, const struc
        const struct ip *ip;
        const struct ip6_hdr *ip6;
        const struct pfloghdr *hdr;
-       u_int8_t af;
 
        ts_print(&h->ts);
 
@@ -153,34 +152,40 @@ pflog_if_print(u_char *user, const struc
                if (vflag && hdr->rewritten) {
                        char buf[48];
 
-                       if (inet_ntop(hdr->af, &hdr->saddr.v4, buf,
+                       printf("[rewritten: ");
+                       if (inet_ntop(hdr->naf, &hdr->saddr, buf,
                            sizeof(buf)) == NULL)
-                               printf("[orig src ?, ");
+                               printf("src ?");
                        else
-                               printf("[orig src %s:%u, ", buf,
-                                   ntohs(hdr->sport));
-                       if (inet_ntop(hdr->af, &hdr->daddr.v4, buf,
+                               printf("src %s:%u", buf, ntohs(hdr->sport));
+                       printf(", ");
+                       if (inet_ntop(hdr->naf, &hdr->daddr, buf,
                            sizeof(buf)) == NULL)
-                               printf("dst ?] ");
+                               printf("dst ?");
                        else
-                               printf("dst %s:%u] ", buf,
-                                   ntohs(hdr->dport));
+                               printf("dst %s:%u", buf, ntohs(hdr->dport));
+                       printf("] ");
                }
        }
-       af = hdr->naf;
        length -= hdrlen;
-       if (af == AF_INET) {
+       switch(hdr->af) {
+       case AF_INET:
                ip = (struct ip *)(p + hdrlen);
                ip_print((const u_char *)ip, length);
                if (xflag)
                        default_print((const u_char *)ip,
                            caplen - hdrlen);
-       } else {
+               break;
+       case AF_INET6:
                ip6 = (struct ip6_hdr *)(p + hdrlen);
                ip6_print((const u_char *)ip6, length);
                if (xflag)
                        default_print((const u_char *)ip6,
                            caplen - hdrlen);
+               break;
+       default:
+               printf("unknown-af %d", hdr->af);
+               break;
        }
 
 out:

Reply via email to