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