1127668Sbms/*
2127668Sbms * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
3127668Sbms *	The Regents of the University of California.  All rights reserved.
4127668Sbms *
5127668Sbms * Redistribution and use in source and binary forms, with or without
6127668Sbms * modification, are permitted provided that: (1) source code distributions
7127668Sbms * retain the above copyright notice and this paragraph in its entirety, (2)
8127668Sbms * distributions including binary code include the above copyright notice and
9127668Sbms * this paragraph in its entirety in the documentation or other materials
10127668Sbms * provided with the distribution, and (3) all advertising materials mentioning
11127668Sbms * features or use of this software display the following acknowledgement:
12127668Sbms * ``This product includes software developed by the University of California,
13127668Sbms * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14127668Sbms * the University nor the names of its contributors may be used to endorse
15127668Sbms * or promote products derived from this software without specific prior
16127668Sbms * written permission.
17127668Sbms * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18127668Sbms * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19127668Sbms * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20127668Sbms */
21127668Sbms
22127668Sbms#ifndef lint
23127668Sbmsstatic const char rcsid[] _U_ =
24190207Srpaulo    "@(#) $Header: /tcpdump/master/tcpdump/print-pflog.c,v 1.16 2007-09-12 19:36:18 guy Exp $ (LBL)";
25127668Sbms#endif
26127668Sbms
27127668Sbms#ifdef HAVE_CONFIG_H
28127668Sbms#include "config.h"
29127668Sbms#endif
30127668Sbms
31172683Smlaier#ifndef HAVE_NET_PFVAR_H
32172683Smlaier#error "No pf headers available"
33172683Smlaier#endif
34172683Smlaier#include <sys/types.h>
35172683Smlaier#include <sys/socket.h>
36172683Smlaier#include <net/if.h>
37172683Smlaier#include <net/pfvar.h>
38172683Smlaier#include <net/if_pflog.h>
39172683Smlaier
40127668Sbms#include <tcpdump-stdinc.h>
41127668Sbms
42127668Sbms#include <stdio.h>
43127668Sbms#include <pcap.h>
44127668Sbms
45214478Srpaulo#include "extract.h"
46127668Sbms#include "interface.h"
47127668Sbms#include "addrtoname.h"
48127668Sbms
49127668Sbmsstatic struct tok pf_reasons[] = {
50127668Sbms	{ 0,	"0(match)" },
51127668Sbms	{ 1,	"1(bad-offset)" },
52127668Sbms	{ 2,	"2(fragment)" },
53127668Sbms	{ 3,	"3(short)" },
54127668Sbms	{ 4,	"4(normalize)" },
55127668Sbms	{ 5,	"5(memory)" },
56172683Smlaier	{ 6,	"6(bad-timestamp)" },
57172683Smlaier	{ 7,	"7(congestion)" },
58172683Smlaier	{ 8,	"8(ip-option)" },
59172683Smlaier	{ 9,	"9(proto-cksum)" },
60172683Smlaier	{ 10,	"10(state-mismatch)" },
61172683Smlaier	{ 11,	"11(state-insert)" },
62172683Smlaier	{ 12,	"12(state-limit)" },
63172683Smlaier	{ 13,	"13(src-limit)" },
64172683Smlaier	{ 14,	"14(synproxy)" },
65127668Sbms	{ 0,	NULL }
66127668Sbms};
67127668Sbms
68127668Sbmsstatic struct tok pf_actions[] = {
69127668Sbms	{ PF_PASS,		"pass" },
70127668Sbms	{ PF_DROP,		"block" },
71127668Sbms	{ PF_SCRUB,		"scrub" },
72127668Sbms	{ PF_NAT,		"nat" },
73127668Sbms	{ PF_NONAT,		"nat" },
74127668Sbms	{ PF_BINAT,		"binat" },
75127668Sbms	{ PF_NOBINAT,		"binat" },
76127668Sbms	{ PF_RDR,		"rdr" },
77127668Sbms	{ PF_NORDR,		"rdr" },
78127668Sbms	{ PF_SYNPROXY_DROP,	"synproxy-drop" },
79127668Sbms	{ 0,			NULL }
80127668Sbms};
81127668Sbms
82127668Sbmsstatic struct tok pf_directions[] = {
83127668Sbms	{ PF_INOUT,	"in/out" },
84127668Sbms	{ PF_IN,	"in" },
85127668Sbms	{ PF_OUT,	"out" },
86127668Sbms	{ 0,		NULL }
87127668Sbms};
88127668Sbms
89127668Sbms/* For reading capture files on other systems */
90127668Sbms#define	OPENBSD_AF_INET		2
91127668Sbms#define	OPENBSD_AF_INET6	24
92127668Sbms
93127668Sbmsstatic void
94127668Sbmspflog_print(const struct pfloghdr *hdr)
95127668Sbms{
96146773Ssam	u_int32_t rulenr, subrulenr;
97146773Ssam
98214478Srpaulo	rulenr = EXTRACT_32BITS(&hdr->rulenr);
99214478Srpaulo	subrulenr = EXTRACT_32BITS(&hdr->subrulenr);
100146773Ssam	if (subrulenr == (u_int32_t)-1)
101146773Ssam		printf("rule %u/", rulenr);
102127668Sbms	else
103146773Ssam		printf("rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr);
104127668Sbms
105127668Sbms	printf("%s: %s %s on %s: ",
106127668Sbms	    tok2str(pf_reasons, "unkn(%u)", hdr->reason),
107127668Sbms	    tok2str(pf_actions, "unkn(%u)", hdr->action),
108127668Sbms	    tok2str(pf_directions, "unkn(%u)", hdr->dir),
109127668Sbms	    hdr->ifname);
110127668Sbms}
111127668Sbms
112127668Sbmsu_int
113127668Sbmspflog_if_print(const struct pcap_pkthdr *h, register const u_char *p)
114127668Sbms{
115127668Sbms	u_int length = h->len;
116127668Sbms	u_int hdrlen;
117127668Sbms	u_int caplen = h->caplen;
118127668Sbms	const struct pfloghdr *hdr;
119127668Sbms	u_int8_t af;
120127668Sbms
121127668Sbms	/* check length */
122127668Sbms	if (caplen < sizeof(u_int8_t)) {
123127668Sbms		printf("[|pflog]");
124127668Sbms		return (caplen);
125127668Sbms	}
126127668Sbms
127127668Sbms#define MIN_PFLOG_HDRLEN	45
128127668Sbms	hdr = (struct pfloghdr *)p;
129127668Sbms	if (hdr->length < MIN_PFLOG_HDRLEN) {
130127668Sbms		printf("[pflog: invalid header length!]");
131127668Sbms		return (hdr->length);	/* XXX: not really */
132127668Sbms	}
133127668Sbms	hdrlen = BPF_WORDALIGN(hdr->length);
134127668Sbms
135127668Sbms	if (caplen < hdrlen) {
136127668Sbms		printf("[|pflog]");
137127668Sbms		return (hdrlen);	/* XXX: true? */
138127668Sbms	}
139127668Sbms
140127668Sbms	/* print what we know */
141127668Sbms	hdr = (struct pfloghdr *)p;
142127668Sbms	TCHECK(*hdr);
143127668Sbms	if (eflag)
144127668Sbms		pflog_print(hdr);
145127668Sbms
146127668Sbms	/* skip to the real packet */
147127668Sbms	af = hdr->af;
148127668Sbms	length -= hdrlen;
149127668Sbms	caplen -= hdrlen;
150127668Sbms	p += hdrlen;
151127668Sbms	switch (af) {
152127668Sbms
153127668Sbms		case AF_INET:
154127668Sbms#if OPENBSD_AF_INET != AF_INET
155127668Sbms		case OPENBSD_AF_INET:		/* XXX: read pcap files */
156127668Sbms#endif
157146773Ssam		        ip_print(gndo, p, length);
158127668Sbms			break;
159127668Sbms
160127668Sbms#ifdef INET6
161127668Sbms		case AF_INET6:
162127668Sbms#if OPENBSD_AF_INET6 != AF_INET6
163127668Sbms		case OPENBSD_AF_INET6:		/* XXX: read pcap files */
164127668Sbms#endif
165235530Sdelphij			ip6_print(gndo, p, length);
166127668Sbms			break;
167127668Sbms#endif
168127668Sbms
169127668Sbms	default:
170127668Sbms		/* address family not handled, print raw packet */
171127668Sbms		if (!eflag)
172127668Sbms			pflog_print(hdr);
173162017Ssam		if (!suppress_default_print)
174127668Sbms			default_print(p, caplen);
175127668Sbms	}
176127668Sbms
177127668Sbms	return (hdrlen);
178127668Sbmstrunc:
179127668Sbms	printf("[|pflog]");
180127668Sbms	return (hdrlen);
181127668Sbms}
182146773Ssam
183146773Ssam/*
184146773Ssam * Local Variables:
185146773Ssam * c-style: whitesmith
186146773Ssam * c-basic-offset: 8
187146773Ssam * End:
188146773Ssam */
189