/*
 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#define NETDISSECT_REWORKED
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifndef HAVE_NET_PFVAR_H
#error "No pf headers available"
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/pfvar.h>
#include <net/if_pflog.h>

#include <tcpdump-stdinc.h>

#include "interface.h"
#include "extract.h"

static const char tstr[] = "[|pflog]";

static const struct tok pf_reasons[] = {
	{ 0,	"0(match)" },
	{ 1,	"1(bad-offset)" },
	{ 2,	"2(fragment)" },
	{ 3,	"3(short)" },
	{ 4,	"4(normalize)" },
	{ 5,	"5(memory)" },
	{ 6,	"6(bad-timestamp)" },
	{ 7,	"7(congestion)" },
	{ 8,	"8(ip-option)" },
	{ 9,	"9(proto-cksum)" },
	{ 10,	"10(state-mismatch)" },
	{ 11,	"11(state-insert)" },
	{ 12,	"12(state-limit)" },
	{ 13,	"13(src-limit)" },
	{ 14,	"14(synproxy)" },
	{ 0,	NULL }
};

static const struct tok pf_actions[] = {
	{ PF_PASS,		"pass" },
	{ PF_DROP,		"block" },
	{ PF_SCRUB,		"scrub" },
	{ PF_NAT,		"nat" },
	{ PF_NONAT,		"nat" },
	{ PF_BINAT,		"binat" },
	{ PF_NOBINAT,		"binat" },
	{ PF_RDR,		"rdr" },
	{ PF_NORDR,		"rdr" },
	{ PF_SYNPROXY_DROP,	"synproxy-drop" },
	{ 0,			NULL }
};

static const struct tok pf_directions[] = {
	{ PF_INOUT,	"in/out" },
	{ PF_IN,	"in" },
	{ PF_OUT,	"out" },
	{ 0,		NULL }
};

/* For reading capture files on other systems */
#define	OPENBSD_AF_INET		2
#define	OPENBSD_AF_INET6	24

static void
pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr)
{
	uint32_t rulenr, subrulenr;

	rulenr = EXTRACT_32BITS(&hdr->rulenr);
	subrulenr = EXTRACT_32BITS(&hdr->subrulenr);
	if (subrulenr == (uint32_t)-1)
		ND_PRINT((ndo, "rule %u/", rulenr));
	else
		ND_PRINT((ndo, "rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr));

	ND_PRINT((ndo, "%s: %s %s on %s: ",
	    tok2str(pf_reasons, "unkn(%u)", hdr->reason),
	    tok2str(pf_actions, "unkn(%u)", hdr->action),
	    tok2str(pf_directions, "unkn(%u)", hdr->dir),
	    hdr->ifname));
}

u_int
pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
               register const u_char *p)
{
	u_int length = h->len;
	u_int hdrlen;
	u_int caplen = h->caplen;
	const struct pfloghdr *hdr;
	uint8_t af;

	/* check length */
	if (caplen < sizeof(uint8_t)) {
		ND_PRINT((ndo, "%s", tstr));
		return (caplen);
	}

#define MIN_PFLOG_HDRLEN	45
	hdr = (struct pfloghdr *)p;
	if (hdr->length < MIN_PFLOG_HDRLEN) {
		ND_PRINT((ndo, "[pflog: invalid header length!]"));
		return (hdr->length);	/* XXX: not really */
	}
	hdrlen = BPF_WORDALIGN(hdr->length);

	if (caplen < hdrlen) {
		ND_PRINT((ndo, "%s", tstr));
		return (hdrlen);	/* XXX: true? */
	}

	/* print what we know */
	hdr = (struct pfloghdr *)p;
	ND_TCHECK(*hdr);
	if (ndo->ndo_eflag)
		pflog_print(ndo, hdr);

	/* skip to the real packet */
	af = hdr->af;
	length -= hdrlen;
	caplen -= hdrlen;
	p += hdrlen;
	switch (af) {

		case AF_INET:
#if OPENBSD_AF_INET != AF_INET
		case OPENBSD_AF_INET:		/* XXX: read pcap files */
#endif
		        ip_print(ndo, p, length);
			break;

#if defined(AF_INET6) || defined(OPENBSD_AF_INET6)
#ifdef AF_INET6
		case AF_INET6:
#endif /* AF_INET6 */
#if !defined(AF_INET6) || OPENBSD_AF_INET6 != AF_INET6
		case OPENBSD_AF_INET6:		/* XXX: read pcap files */
#endif /* !defined(AF_INET6) || OPENBSD_AF_INET6 != AF_INET6 */
			ip6_print(ndo, p, length);
			break;
#endif /* defined(AF_INET6) || defined(OPENBSD_AF_INET6) */

	default:
		/* address family not handled, print raw packet */
		if (!ndo->ndo_eflag)
			pflog_print(ndo, hdr);
		if (!ndo->ndo_suppress_default_print)
			ND_DEFAULTPRINT(p, caplen);
	}

	return (hdrlen);
trunc:
	ND_PRINT((ndo, "%s", tstr));
	return (hdrlen);
}

/*
 * Local Variables:
 * c-style: whitesmith
 * c-basic-offset: 8
 * End:
 */
