xref: /openbsd-src/usr.sbin/tcpdump/print-pflog.c (revision 4e1ee0786f11cc571bd0be17d38e46f635c719fc)
1 /*	$OpenBSD: print-pflog.c,v 1.33 2021/01/20 13:40:15 bluhm Exp $	*/
2 
3 /*
4  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  */
23 
24 #include <sys/param.h>	/* MAXCOMLEN */
25 #include <sys/time.h>
26 #include <sys/socket.h>
27 #include <sys/file.h>
28 #include <sys/ioctl.h>
29 #include <sys/queue.h>
30 #include <sys/mbuf.h>
31 
32 #ifndef NO_PID
33 #define NO_PID	(99999+1)
34 #endif
35 
36 struct rtentry;
37 
38 #include <netinet/in.h>
39 #include <netinet/ip.h>
40 #include <net/if.h>
41 #include <net/pfvar.h>
42 #include <net/if_pflog.h>
43 
44 #include <arpa/inet.h>
45 
46 #include <ctype.h>
47 #include <netdb.h>
48 #include <pcap.h>
49 #include <signal.h>
50 #include <stdio.h>
51 
52 #include "interface.h"
53 #include "addrtoname.h"
54 
55 char *pf_reasons[PFRES_MAX+2] = PFRES_NAMES;
56 
57 void
58 pflog_if_print(u_char *user, const struct pcap_pkthdr *h,
59      const u_char *p)
60 {
61 	u_int length = h->len;
62 	u_int hdrlen;
63 	u_int caplen = h->caplen;
64 	const struct ip *ip;
65 	const struct ip6_hdr *ip6;
66 	const struct pfloghdr *hdr;
67 
68 	ts_print(&h->ts);
69 
70 	/* check length */
71 	if (caplen < sizeof(u_int8_t)) {
72 		printf("[|pflog]");
73 		goto out;
74 	}
75 
76 #define MIN_PFLOG_HDRLEN	45
77 	hdr = (struct pfloghdr *)p;
78 	if (hdr->length < MIN_PFLOG_HDRLEN) {
79 		printf("[pflog: invalid header length!]");
80 		goto out;
81 	}
82 	hdrlen = (hdr->length + 3) & 0xfc;
83 
84 	if (caplen < hdrlen) {
85 		printf("[|pflog]");
86 		goto out;
87 	}
88 
89 	/*
90 	 * Some printers want to get back at the link level addresses,
91 	 * and/or check that they're not walking off the end of the packet.
92 	 * Rather than pass them all the way down, we set these globals.
93 	 */
94 	packetp = p;
95 	snapend = p + caplen;
96 
97 	hdr = (struct pfloghdr *)p;
98 	if (eflag) {
99 		printf("rule ");
100 		if (ntohl(hdr->rulenr) == (u_int32_t) -1)
101 			printf("def");
102 		else {
103 			printf("%u", ntohl(hdr->rulenr));
104 			if (hdr->ruleset[0]) {
105 				printf(".%s", hdr->ruleset);
106 				if (ntohl(hdr->subrulenr) == (u_int32_t) -1)
107 					printf(".def");
108 				else
109 					printf(".%u", ntohl(hdr->subrulenr));
110 			}
111 		}
112 		if (hdr->reason < PFRES_MAX)
113 			printf("/(%s) ", pf_reasons[hdr->reason]);
114 		else
115 			printf("/(unkn %u) ", (unsigned)hdr->reason);
116 		if (vflag)
117 			printf("[uid %u, pid %u] ", (unsigned)hdr->rule_uid,
118 			    (unsigned)hdr->rule_pid);
119 
120 		switch (hdr->action) {
121 		case PF_MATCH:
122 			printf("match");
123 			break;
124 		case PF_SCRUB:
125 			printf("scrub");
126 			break;
127 		case PF_PASS:
128 			printf("pass");
129 			break;
130 		case PF_DROP:
131 			printf("block");
132 			break;
133 		case PF_NAT:
134 		case PF_NONAT:
135 			printf("nat");
136 			break;
137 		case PF_BINAT:
138 		case PF_NOBINAT:
139 			printf("binat");
140 			break;
141 		case PF_RDR:
142 		case PF_NORDR:
143 			printf("rdr");
144 			break;
145 		}
146 		printf(" %s on %s: ",
147 		    hdr->dir == PF_OUT ? "out" : "in",
148 		    hdr->ifname);
149 		if (vflag && hdr->pid != NO_PID)
150 			printf("[uid %u, pid %u] ", (unsigned)hdr->uid,
151 			    (unsigned)hdr->pid);
152 		if (vflag && hdr->rewritten) {
153 			char buf[48];
154 
155 			printf("[rewritten: ");
156 			if (inet_ntop(hdr->naf, &hdr->saddr, buf,
157 			    sizeof(buf)) == NULL)
158 				printf("src ?");
159 			else
160 				printf("src %s:%u", buf, ntohs(hdr->sport));
161 			printf(", ");
162 			if (inet_ntop(hdr->naf, &hdr->daddr, buf,
163 			    sizeof(buf)) == NULL)
164 				printf("dst ?");
165 			else
166 				printf("dst %s:%u", buf, ntohs(hdr->dport));
167 			printf("] ");
168 		}
169 	}
170 	length -= hdrlen;
171 	switch(hdr->af) {
172 	case AF_INET:
173 		ip = (struct ip *)(p + hdrlen);
174 		ip_print((const u_char *)ip, length);
175 		if (xflag)
176 			default_print((const u_char *)ip,
177 			    caplen - hdrlen);
178 		break;
179 	case AF_INET6:
180 		ip6 = (struct ip6_hdr *)(p + hdrlen);
181 		ip6_print((const u_char *)ip6, length);
182 		if (xflag)
183 			default_print((const u_char *)ip6,
184 			    caplen - hdrlen);
185 		break;
186 	default:
187 		printf("unknown-af %d", hdr->af);
188 		break;
189 	}
190 
191 out:
192 	putchar('\n');
193 }
194