xref: /netbsd-src/external/bsd/tcpdump/dist/print-pflog.c (revision 26ba0b503b498a5194a71ac319838b7f5497f3fe)
10f74e101Schristos /*
20f74e101Schristos  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
30f74e101Schristos  *	The Regents of the University of California.  All rights reserved.
40f74e101Schristos  *
50f74e101Schristos  * Redistribution and use in source and binary forms, with or without
60f74e101Schristos  * modification, are permitted provided that: (1) source code distributions
70f74e101Schristos  * retain the above copyright notice and this paragraph in its entirety, (2)
80f74e101Schristos  * distributions including binary code include the above copyright notice and
90f74e101Schristos  * this paragraph in its entirety in the documentation or other materials
100f74e101Schristos  * provided with the distribution, and (3) all advertising materials mentioning
110f74e101Schristos  * features or use of this software display the following acknowledgement:
120f74e101Schristos  * ``This product includes software developed by the University of California,
130f74e101Schristos  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
140f74e101Schristos  * the University nor the names of its contributors may be used to endorse
150f74e101Schristos  * or promote products derived from this software without specific prior
160f74e101Schristos  * written permission.
170f74e101Schristos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
180f74e101Schristos  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
190f74e101Schristos  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
200f74e101Schristos  */
210f74e101Schristos 
2211b3aaa1Schristos #include <sys/cdefs.h>
230f74e101Schristos #ifndef lint
24*26ba0b50Schristos __RCSID("$NetBSD: print-pflog.c,v 1.10 2024/09/02 16:15:32 christos Exp $");
250f74e101Schristos #endif
260f74e101Schristos 
27c74ad251Schristos /* \summary: *BSD/Darwin packet filter log file printer */
28dc860a36Sspz 
29c74ad251Schristos #include <config.h>
300f74e101Schristos 
31c74ad251Schristos #include "netdissect-stdinc.h"
320f74e101Schristos 
33fdccd7e4Schristos #include "netdissect.h"
34b3a00663Schristos #include "extract.h"
35c74ad251Schristos #include "af.h"
36b3a00663Schristos 
37c74ad251Schristos #include "pflog.h"
380f74e101Schristos 
39870189d2Schristos static const struct tok pf_reasons[] = {
40c74ad251Schristos 	{ PFRES_MATCH,		"0(match)" },
41c74ad251Schristos 	{ PFRES_BADOFF,		"1(bad-offset)" },
42c74ad251Schristos 	{ PFRES_FRAG,		"2(fragment)" },
43*26ba0b50Schristos 	{ PFRES_SHORT,		"3(short)" },
44c74ad251Schristos 	{ PFRES_NORM,		"4(normalize)" },
45c74ad251Schristos 	{ PFRES_MEMORY,		"5(memory)" },
46c74ad251Schristos 	{ PFRES_TS,		"6(bad-timestamp)" },
47c74ad251Schristos 	{ PFRES_CONGEST,	"7(congestion)" },
48c74ad251Schristos 	{ PFRES_IPOPTIONS,	"8(ip-option)" },
49c74ad251Schristos 	{ PFRES_PROTCKSUM,	"9(proto-cksum)" },
50c74ad251Schristos 	{ PFRES_BADSTATE,	"10(state-mismatch)" },
51c74ad251Schristos 	{ PFRES_STATEINS,	"11(state-insert)" },
52c74ad251Schristos 	{ PFRES_MAXSTATES,	"12(state-limit)" },
53c74ad251Schristos 	{ PFRES_SRCLIMIT,	"13(src-limit)" },
54c74ad251Schristos 	{ PFRES_SYNPROXY,	"14(synproxy)" },
55c74ad251Schristos #if defined(__FreeBSD__)
56c74ad251Schristos 	{ PFRES_MAPFAILED,	"15(map-failed)" },
57c74ad251Schristos #elif defined(__NetBSD__)
58c74ad251Schristos 	{ PFRES_STATELOCKED,	"15(state-locked)" },
59c74ad251Schristos #elif defined(__OpenBSD__)
60c74ad251Schristos 	{ PFRES_TRANSLATE,	"15(translate)" },
61c74ad251Schristos 	{ PFRES_NOROUTE,	"16(no-route)" },
62c74ad251Schristos #elif defined(__APPLE__)
63c74ad251Schristos 	{ PFRES_DUMMYNET,	"15(dummynet)" },
64c74ad251Schristos #endif
650f74e101Schristos 	{ 0,	NULL }
660f74e101Schristos };
670f74e101Schristos 
68870189d2Schristos static const struct tok pf_actions[] = {
690f74e101Schristos 	{ PF_PASS,		"pass" },
700f74e101Schristos 	{ PF_DROP,		"block" },
710f74e101Schristos 	{ PF_SCRUB,		"scrub" },
720f74e101Schristos 	{ PF_NAT,		"nat" },
73c74ad251Schristos 	{ PF_NONAT,		"nonat" },
740f74e101Schristos 	{ PF_BINAT,		"binat" },
75c74ad251Schristos 	{ PF_NOBINAT,		"nobinat" },
760f74e101Schristos 	{ PF_RDR,		"rdr" },
77c74ad251Schristos 	{ PF_NORDR,		"nordr" },
780f74e101Schristos 	{ PF_SYNPROXY_DROP,	"synproxy-drop" },
79c74ad251Schristos #if defined(__FreeBSD__)
80c74ad251Schristos 	{ PF_DEFER,		"defer" },
81c74ad251Schristos #elif defined(__OpenBSD__)
82c74ad251Schristos 	{ PF_DEFER,		"defer" },
83c74ad251Schristos 	{ PF_MATCH,		"match" },
84c74ad251Schristos 	{ PF_DIVERT,		"divert" },
85c74ad251Schristos 	{ PF_RT,		"rt" },
86c74ad251Schristos 	{ PF_AFRT,		"afrt" },
87c74ad251Schristos #elif defined(__APPLE__)
88c74ad251Schristos 	{ PF_DUMMYNET,		"dummynet" },
89c74ad251Schristos 	{ PF_NODUMMYNET,	"nodummynet" },
90c74ad251Schristos 	{ PF_NAT64,		"nat64" },
91c74ad251Schristos 	{ PF_NONAT64,		"nonat64" },
92c74ad251Schristos #endif
930f74e101Schristos 	{ 0,			NULL }
940f74e101Schristos };
950f74e101Schristos 
96870189d2Schristos static const struct tok pf_directions[] = {
970f74e101Schristos 	{ PF_INOUT,	"in/out" },
980f74e101Schristos 	{ PF_IN,	"in" },
990f74e101Schristos 	{ PF_OUT,	"out" },
100c74ad251Schristos #if defined(__OpenBSD__)
101c74ad251Schristos 	{ PF_FWD,	"fwd" },
102c74ad251Schristos #endif
1030f74e101Schristos 	{ 0,		NULL }
1040f74e101Schristos };
1050f74e101Schristos 
1060f74e101Schristos static void
107b3a00663Schristos pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
1080f74e101Schristos {
109b3a00663Schristos 	uint32_t rulenr, subrulenr;
1100f74e101Schristos 
111c74ad251Schristos 	ndo->ndo_protocol = "pflog";
112*26ba0b50Schristos 	rulenr = GET_BE_U_4(hdr->rulenr);
113*26ba0b50Schristos 	subrulenr = GET_BE_U_4(hdr->subrulenr);
114b3a00663Schristos 	if (subrulenr == (uint32_t)-1)
115c74ad251Schristos 		ND_PRINT("rule %u/", rulenr);
116c74ad251Schristos 	else {
117c74ad251Schristos 		ND_PRINT("rule %u.", rulenr);
118c74ad251Schristos 		nd_printjnp(ndo, (const u_char*)hdr->ruleset, PFLOG_RULESET_NAME_SIZE);
119c74ad251Schristos 		ND_PRINT(".%u/", subrulenr);
1200f74e101Schristos 	}
1210f74e101Schristos 
122c74ad251Schristos 	ND_PRINT("%s: %s %s on ",
123*26ba0b50Schristos 	    tok2str(pf_reasons, "unkn(%u)", GET_U_1(hdr->reason)),
124*26ba0b50Schristos 	    tok2str(pf_actions, "unkn(%u)", GET_U_1(hdr->action)),
125*26ba0b50Schristos 	    tok2str(pf_directions, "unkn(%u)", GET_U_1(hdr->dir)));
126c74ad251Schristos 	nd_printjnp(ndo, (const u_char*)hdr->ifname, PFLOG_IFNAMSIZ);
127c74ad251Schristos 	ND_PRINT(": ");
128c74ad251Schristos }
129c74ad251Schristos 
130c74ad251Schristos void
131b3a00663Schristos pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
132c74ad251Schristos                const u_char *p)
1330f74e101Schristos {
1340f74e101Schristos 	u_int length = h->len;
1350f74e101Schristos 	u_int hdrlen;
1360f74e101Schristos 	u_int caplen = h->caplen;
1370f74e101Schristos 	const struct pfloghdr *hdr;
138b3a00663Schristos 	uint8_t af;
1390f74e101Schristos 
140c74ad251Schristos 	ndo->ndo_protocol = "pflog";
1410f74e101Schristos 	/* check length */
142b3a00663Schristos 	if (caplen < sizeof(uint8_t)) {
143c74ad251Schristos 		nd_print_trunc(ndo);
144c74ad251Schristos 		ndo->ndo_ll_hdr_len += h->caplen;
145c74ad251Schristos 		return;
1460f74e101Schristos 	}
1470f74e101Schristos 
148dc860a36Sspz 	hdr = (const struct pfloghdr *)p;
149*26ba0b50Schristos 	hdrlen = GET_U_1(hdr->length);
150*26ba0b50Schristos 	if (hdrlen < MIN_PFLOG_HDRLEN) {
151c74ad251Schristos 		ND_PRINT("[pflog: invalid header length!]");
152*26ba0b50Schristos 		ndo->ndo_ll_hdr_len += hdrlen;	/* XXX: not really */
153c74ad251Schristos 		return;
1540f74e101Schristos 	}
155*26ba0b50Schristos 	hdrlen = roundup2(hdrlen, 4);
1560f74e101Schristos 
1570f74e101Schristos 	if (caplen < hdrlen) {
158c74ad251Schristos 		nd_print_trunc(ndo);
159c74ad251Schristos 		ndo->ndo_ll_hdr_len += hdrlen;	/* XXX: true? */
160c74ad251Schristos 		return;
1610f74e101Schristos 	}
1620f74e101Schristos 
1630f74e101Schristos 	/* print what we know */
164c74ad251Schristos 	ND_TCHECK_SIZE(hdr);
165b3a00663Schristos 	if (ndo->ndo_eflag)
166b3a00663Schristos 		pflog_print(ndo, hdr);
1670f74e101Schristos 
1680f74e101Schristos 	/* skip to the real packet */
169*26ba0b50Schristos 	af = GET_U_1(hdr->af);
1700f74e101Schristos 	length -= hdrlen;
1710f74e101Schristos 	caplen -= hdrlen;
1720f74e101Schristos 	p += hdrlen;
1730f74e101Schristos 	switch (af) {
1740f74e101Schristos 
175c74ad251Schristos 		/*
176c74ad251Schristos 		 * If there's a system that doesn't use the AF_INET
177c74ad251Schristos 		 * from 4.2BSD, feel free to add its value to af.h
178c74ad251Schristos 		 * and use it here.
179c74ad251Schristos 		 *
180c74ad251Schristos 		 * Hopefully, there isn't.
181c74ad251Schristos 		 */
182c74ad251Schristos 		case BSD_AFNUM_INET:
183b3a00663Schristos 		        ip_print(ndo, p, length);
1840f74e101Schristos 			break;
1850f74e101Schristos 
186c74ad251Schristos 		/*
187c74ad251Schristos 		 * Try all AF_INET6 values for all systems with pflog,
188c74ad251Schristos 		 * including Darwin.
189c74ad251Schristos 		 */
190c74ad251Schristos 		case BSD_AFNUM_INET6_BSD:
191c74ad251Schristos 		case BSD_AFNUM_INET6_FREEBSD:
192c74ad251Schristos 		case BSD_AFNUM_INET6_DARWIN:
193b3a00663Schristos 			ip6_print(ndo, p, length);
1940f74e101Schristos 			break;
1950f74e101Schristos 
1960f74e101Schristos 	default:
1970f74e101Schristos 		/* address family not handled, print raw packet */
198b3a00663Schristos 		if (!ndo->ndo_eflag)
199b3a00663Schristos 			pflog_print(ndo, hdr);
200b3a00663Schristos 		if (!ndo->ndo_suppress_default_print)
201b3a00663Schristos 			ND_DEFAULTPRINT(p, caplen);
2020f74e101Schristos 	}
2030f74e101Schristos 
204c74ad251Schristos 	ndo->ndo_ll_hdr_len += hdrlen;
205c74ad251Schristos 	return;
2060f74e101Schristos trunc:
207c74ad251Schristos 	nd_print_trunc(ndo);
208c74ad251Schristos 	ndo->ndo_ll_hdr_len += hdrlen;
2090f74e101Schristos }
210