Skip to content

Instantly share code, notes, and snippets.

@raitech
Last active December 31, 2018 15:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raitech/4150c8767d8f1f8642ccd9d44c4c57c6 to your computer and use it in GitHub Desktop.
Save raitech/4150c8767d8f1f8642ccd9d44c4c57c6 to your computer and use it in GitHub Desktop.
This patch alters pf (some headers and pflog interface), tcpdump, and pflogd to log more information about NAT translations (based on FreeBSD 10.2 RELEASE source), to be in accordance with Brazilian Internet's Civil Mark (Marco Civil da Internet).
diff -ru freebsd-10.2r-src-orig/contrib/pf/pflogd/pflogd.h freebsd-10.2r-src/contrib/pf/pflogd/pflogd.h
--- freebsd-10.2r-src-orig/contrib/pf/pflogd/pflogd.h 2015-08-12 11:20:57.000000000 -0300
+++ freebsd-10.2r-src/contrib/pf/pflogd/pflogd.h 2016-04-24 11:43:59.737952483 -0300
@@ -19,7 +19,7 @@
#include <sys/limits.h>
#include <pcap.h>
-#define DEF_SNAPLEN 116 /* default plus allow for larger header of pflog */
+#define DEF_SNAPLEN 160 /* default plus allow for larger header of pflog */
#define PCAP_TO_MS 500 /* pcap read timeout (ms) */
#define PCAP_NUM_PKTS 1000 /* max number of packets to process at each loop */
#define PCAP_OPT_FIL 1 /* filter optimization */
diff -ru freebsd-10.2r-src-orig/contrib/tcpdump/print-pflog.c freebsd-10.2r-src/contrib/tcpdump/print-pflog.c
--- freebsd-10.2r-src-orig/contrib/tcpdump/print-pflog.c 2015-08-12 11:20:41.000000000 -0300
+++ freebsd-10.2r-src/contrib/tcpdump/print-pflog.c 2016-05-07 21:27:23.593280260 -0300
@@ -40,6 +40,7 @@
#include <tcpdump-stdinc.h>
#include <stdio.h>
+#include <string.h>
#include <pcap.h>
#include "extract.h"
@@ -94,6 +95,7 @@
pflog_print(const struct pfloghdr *hdr)
{
u_int32_t rulenr, subrulenr;
+ char buf[48], buf1[48];
rulenr = EXTRACT_32BITS(&hdr->rulenr);
subrulenr = EXTRACT_32BITS(&hdr->subrulenr);
@@ -102,11 +104,28 @@
else
printf("rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr);
- printf("%s: %s %s on %s: ",
- tok2str(pf_reasons, "unkn(%u)", hdr->reason),
- tok2str(pf_actions, "unkn(%u)", hdr->action),
- tok2str(pf_directions, "unkn(%u)", hdr->dir),
- hdr->ifname);
+ if (hdr->action == PF_NAT) {
+ if(inet_ntop(hdr->af, &hdr->osaddr.v4, buf, sizeof(buf)) == NULL)
+ strncpy(buf, "???", 3);
+
+ if(inet_ntop(hdr->af, &hdr->nsaddr.v4, buf1, sizeof(buf1)) == NULL)
+ strncpy(buf1, "???", 3);
+
+ printf("%s: %s %s on %s [pre-NAT addr %s port %u -> post-NAT addr %s port %u]: ",
+ tok2str(pf_reasons, "unkn(%u)", hdr->reason),
+ tok2str(pf_actions, "unkn(%u)", hdr->action),
+ tok2str(pf_directions, "unkn(%u)", hdr->dir),
+ hdr->ifname,
+ buf,
+ ntohs(hdr->osport),
+ buf1,
+ ntohs(hdr->nsport));
+ } else
+ printf("%s: %s %s on %s: ",
+ tok2str(pf_reasons, "unkn(%u)", hdr->reason),
+ tok2str(pf_actions, "unkn(%u)", hdr->action),
+ tok2str(pf_directions, "unkn(%u)", hdr->dir),
+ hdr->ifname);
}
u_int
@@ -142,6 +161,10 @@
TCHECK(*hdr);
if (eflag)
pflog_print(hdr);
+
+ /* if there is nothing more than a complete pfloghdr, just skip */
+ if(caplen >= hdr->length && caplen <= hdr->length + 2)
+ return (hdrlen);
/* skip to the real packet */
af = hdr->af;
diff -ru freebsd-10.2r-src-orig/sys/net/if_pflog.h freebsd-10.2r-src/sys/net/if_pflog.h
--- freebsd-10.2r-src-orig/sys/net/if_pflog.h 2015-08-12 11:22:04.000000000 -0300
+++ freebsd-10.2r-src/sys/net/if_pflog.h 2016-05-07 12:01:11.235733260 -0300
@@ -27,6 +27,8 @@
#ifndef _NET_IF_PFLOG_H_
#define _NET_IF_PFLOG_H_
+#include <net/pfvar.h>
+
#define PFLOGIFS_MAX 16
#define PFLOG_RULESET_NAME_SIZE 16
@@ -45,7 +47,19 @@
uid_t rule_uid;
pid_t rule_pid;
u_int8_t dir;
- u_int8_t pad[3];
+ u_int8_t rewritten;
+ u_int8_t pad[6];
+ /*
+ * Brazilian Civil Mark (Marco Civil da Internet)
+ * doesn't permit an ISP to store dst addr and port.
+ *
+ * (in 2016-05-07)
+ *
+ */
+ struct pf_addr osaddr; /* orignal pre nat src addr */
+ struct pf_addr nsaddr; /* nated new src addr */
+ u_int16_t osport; /* original pre nat src port */
+ u_int16_t nsport; /* nated new src port */
};
#define PFLOG_HDRLEN sizeof(struct pfloghdr)
diff -ru freebsd-10.2r-src-orig/sys/net/pfvar.h freebsd-10.2r-src/sys/net/pfvar.h
--- freebsd-10.2r-src-orig/sys/net/pfvar.h 2015-08-12 11:22:04.000000000 -0300
+++ freebsd-10.2r-src/sys/net/pfvar.h 2016-05-07 11:58:14.341173218 -0300
@@ -1098,8 +1098,12 @@
struct pf_rule *nat_rule; /* nat/rdr rule applied to packet */
struct pf_addr *src; /* src address */
struct pf_addr *dst; /* dst address */
+ struct pf_addr osaddr; /* pre nat (original) src address */
+ struct pf_addr odaddr; /* pre nat (original) dst address */
u_int16_t *sport;
u_int16_t *dport;
+ u_int16_t osport;
+ u_int16_t odport;
struct pf_mtag *pf_mtag;
u_int32_t p_len; /* total length of payload */
diff -ru freebsd-10.2r-src-orig/sys/netpfil/pf/if_pflog.c freebsd-10.2r-src/sys/netpfil/pf/if_pflog.c
--- freebsd-10.2r-src-orig/sys/netpfil/pf/if_pflog.c 2015-08-12 11:22:08.000000000 -0300
+++ freebsd-10.2r-src/sys/netpfil/pf/if_pflog.c 2016-05-07 18:13:48.354865549 -0300
@@ -209,7 +209,7 @@
return (0);
bzero(&hdr, sizeof(hdr));
- hdr.length = PFLOG_REAL_HDRLEN;
+ hdr.length = PFLOG_HDRLEN;
hdr.af = af;
hdr.action = rm->action;
hdr.reason = reason;
@@ -241,6 +241,15 @@
hdr.rule_pid = rm->cpid;
hdr.dir = dir;
+ PF_ACPY(&hdr.osaddr, &pd->osaddr, pd->af);
+ PF_ACPY(&hdr.nsaddr, pd->src, pd->af);
+ hdr.af = pd->af;
+ hdr.osport = pd->osport;
+ if (pd->sport)
+ hdr.nsport = *pd->sport;
+ else
+ hdr.nsport = 0;
+
#ifdef INET
if (af == AF_INET && dir == PF_OUT) {
struct ip *ip;
diff -ru freebsd-10.2r-src-orig/sys/netpfil/pf/pf.c freebsd-10.2r-src/sys/netpfil/pf/pf.c
--- freebsd-10.2r-src-orig/sys/netpfil/pf/pf.c 2015-08-12 11:22:08.000000000 -0300
+++ freebsd-10.2r-src/sys/netpfil/pf/pf.c 2016-05-07 19:49:20.131598137 -0300
@@ -5772,6 +5772,9 @@
pd.sidx = (dir == PF_IN) ? 0 : 1;
pd.didx = (dir == PF_IN) ? 1 : 0;
pd.af = AF_INET;
+ PF_ACPY(&pd.osaddr, pd.src, pd.af);
+ PF_ACPY(&pd.odaddr, pd.dst, pd.af);
+ pd.osport = pd.odport = 0;
pd.tos = h->ip_tos;
pd.tot_len = ntohs(h->ip_len);
@@ -5799,6 +5802,9 @@
action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
if (action == PF_DROP)
goto done;
+
+ pd.osport = th.th_sport;
+
action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
&reason);
if (action == PF_PASS) {
@@ -5829,6 +5835,9 @@
REASON_SET(&reason, PFRES_SHORT);
goto done;
}
+
+ pd.osport = uh.uh_sport;
+
action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
if (action == PF_PASS) {
if (pfsync_update_state_ptr != NULL)
@@ -5851,6 +5860,9 @@
log = action != PF_PASS;
goto done;
}
+
+ pd.osport = ih.icmp_id;
+
action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
&reason);
if (action == PF_PASS) {
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment