xref: /openbsd-src/usr.sbin/tcpdump/print-pflog.c (revision 91f110e064cd7c194e59e019b83bb7496c1c84d4)
1 /*	$OpenBSD: print-pflog.c,v 1.24 2011/10/13 18:32:30 claudio 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/types.h>
25 #include <sys/param.h>
26 #include <sys/time.h>
27 #include <sys/socket.h>
28 #include <sys/file.h>
29 #include <sys/ioctl.h>
30 #include <sys/mbuf.h>
31 #include <sys/proc.h>
32 
33 #ifndef NO_PID
34 #define NO_PID	(32766+1)
35 #endif
36 
37 struct rtentry;
38 #include <net/if.h>
39 #include <net/if_pflog.h>
40 
41 #include <netinet/in.h>
42 #include <netinet/in_systm.h>
43 #include <netinet/ip.h>
44 
45 #include <net/pfvar.h>
46 
47 #include <arpa/inet.h>
48 
49 #include <ctype.h>
50 #include <netdb.h>
51 #include <pcap.h>
52 #include <signal.h>
53 #include <stdio.h>
54 
55 #include "interface.h"
56 #include "addrtoname.h"
57 
58 char *pf_reasons[PFRES_MAX+2] = PFRES_NAMES;
59 
60 void
61 pflog_if_print(u_char *user, const struct pcap_pkthdr *h,
62      register const u_char *p)
63 {
64 	u_int length = h->len;
65 	u_int hdrlen;
66 	u_int caplen = h->caplen;
67 	const struct ip *ip;
68 #ifdef INET6
69 	const struct ip6_hdr *ip6;
70 #endif
71 	const struct pfloghdr *hdr;
72 	u_int8_t af;
73 
74 	ts_print(&h->ts);
75 
76 	/* check length */
77 	if (caplen < sizeof(u_int8_t)) {
78 		printf("[|pflog]");
79 		goto out;
80 	}
81 
82 #define MIN_PFLOG_HDRLEN	45
83 	hdr = (struct pfloghdr *)p;
84 	if (hdr->length < MIN_PFLOG_HDRLEN) {
85 		printf("[pflog: invalid header length!]");
86 		goto out;
87 	}
88 	hdrlen = (hdr->length + 3) & 0xfc;
89 
90 	if (caplen < hdrlen) {
91 		printf("[|pflog]");
92 		goto out;
93 	}
94 
95 	/*
96 	 * Some printers want to get back at the link level addresses,
97 	 * and/or check that they're not walking off the end of the packet.
98 	 * Rather than pass them all the way down, we set these globals.
99 	 */
100 	packetp = p;
101 	snapend = p + caplen;
102 
103 	hdr = (struct pfloghdr *)p;
104 	if (eflag) {
105 		printf("rule ");
106 		if (ntohl(hdr->rulenr) == (u_int32_t) -1)
107 			printf("def");
108 		else {
109 			printf("%u", ntohl(hdr->rulenr));
110 			if (hdr->ruleset[0]) {
111 				printf(".%s", hdr->ruleset);
112 				if (ntohl(hdr->subrulenr) == (u_int32_t) -1)
113 					printf(".def");
114 				else
115 					printf(".%u", ntohl(hdr->subrulenr));
116 			}
117 		}
118 		if (hdr->reason < PFRES_MAX)
119 			printf("/(%s) ", pf_reasons[hdr->reason]);
120 		else
121 			printf("/(unkn %u) ", (unsigned)hdr->reason);
122 		if (vflag)
123 			printf("[uid %u, pid %u] ", (unsigned)hdr->rule_uid,
124 			    (unsigned)hdr->rule_pid);
125 
126 		switch (hdr->action) {
127 		case PF_MATCH:
128 			printf("match");
129 			break;
130 		case PF_SCRUB:
131 			printf("scrub");
132 			break;
133 		case PF_PASS:
134 			printf("pass");
135 			break;
136 		case PF_DROP:
137 			printf("block");
138 			break;
139 		case PF_NAT:
140 		case PF_NONAT:
141 			printf("nat");
142 			break;
143 		case PF_BINAT:
144 		case PF_NOBINAT:
145 			printf("binat");
146 			break;
147 		case PF_RDR:
148 		case PF_NORDR:
149 			printf("rdr");
150 			break;
151 		}
152 		printf(" %s on %s: ",
153 		    hdr->dir == PF_OUT ? "out" : "in",
154 		    hdr->ifname);
155 		if (vflag && hdr->pid != NO_PID)
156 			printf("[uid %u, pid %u] ", (unsigned)hdr->uid,
157 			    (unsigned)hdr->pid);
158 		if (vflag && hdr->rewritten) {
159 			char buf[48];
160 
161 			if (inet_ntop(hdr->af, &hdr->saddr.v4, buf,
162 			    sizeof(buf)) == NULL)
163 				printf("[orig src ?, ");
164 			else
165 				printf("[orig src %s:%u, ", buf,
166 				    ntohs(hdr->sport));
167 			if (inet_ntop(hdr->af, &hdr->daddr.v4, buf,
168 			    sizeof(buf)) == NULL)
169 				printf("dst ?] ");
170 			else
171 				printf("dst %s:%u] ", buf,
172 				    ntohs(hdr->dport));
173 		}
174 	}
175 	af = hdr->naf;
176 	length -= hdrlen;
177 	if (af == AF_INET) {
178 		ip = (struct ip *)(p + hdrlen);
179 		ip_print((const u_char *)ip, length);
180 		if (xflag)
181 			default_print((const u_char *)ip,
182 			    caplen - hdrlen);
183 	} else {
184 #ifdef INET6
185 		ip6 = (struct ip6_hdr *)(p + hdrlen);
186 		ip6_print((const u_char *)ip6, length);
187 		if (xflag)
188 			default_print((const u_char *)ip6,
189 			    caplen - hdrlen);
190 #endif
191 	}
192 
193 out:
194 	putchar('\n');
195 }
196