/*
 * 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.
 */

/* \summary: *BSD/Darwin packet filter log file printer */

#include <config.h>

#include "netdissect-stdinc.h"

#include "netdissect.h"
#include "extract.h"
#include "af.h"

#include "pflog.h"

static const struct tok pf_reasons[] = {
	{ PFRES_MATCH,		"0(match)" },
	{ PFRES_BADOFF,		"1(bad-offset)" },
	{ PFRES_FRAG,		"2(fragment)" },
	{ PFRES_SHORT,		"3(short)" },
	{ PFRES_NORM,		"4(normalize)" },
	{ PFRES_MEMORY,		"5(memory)" },
	{ PFRES_TS,		"6(bad-timestamp)" },
	{ PFRES_CONGEST,	"7(congestion)" },
	{ PFRES_IPOPTIONS,	"8(ip-option)" },
	{ PFRES_PROTCKSUM,	"9(proto-cksum)" },
	{ PFRES_BADSTATE,	"10(state-mismatch)" },
	{ PFRES_STATEINS,	"11(state-insert)" },
	{ PFRES_MAXSTATES,	"12(state-limit)" },
	{ PFRES_SRCLIMIT,	"13(src-limit)" },
	{ PFRES_SYNPROXY,	"14(synproxy)" },
#if defined(__FreeBSD__)
	{ PFRES_MAPFAILED,	"15(map-failed)" },
#elif defined(__NetBSD__)
	{ PFRES_STATELOCKED,	"15(state-locked)" },
#elif defined(__OpenBSD__)
	{ PFRES_TRANSLATE,	"15(translate)" },
	{ PFRES_NOROUTE,	"16(no-route)" },
#elif defined(__APPLE__)
	{ PFRES_DUMMYNET,	"15(dummynet)" },
#endif
	{ 0,	NULL }
};

static const struct tok pf_actions[] = {
	{ PF_PASS,		"pass" },
	{ PF_DROP,		"block" },
	{ PF_SCRUB,		"scrub" },
	{ PF_NAT,		"nat" },
	{ PF_NONAT,		"nonat" },
	{ PF_BINAT,		"binat" },
	{ PF_NOBINAT,		"nobinat" },
	{ PF_RDR,		"rdr" },
	{ PF_NORDR,		"nordr" },
	{ PF_SYNPROXY_DROP,	"synproxy-drop" },
#if defined(__FreeBSD__)
	{ PF_DEFER,		"defer" },
#elif defined(__OpenBSD__)
	{ PF_DEFER,		"defer" },
	{ PF_MATCH,		"match" },
	{ PF_DIVERT,		"divert" },
	{ PF_RT,		"rt" },
	{ PF_AFRT,		"afrt" },
#elif defined(__APPLE__)
	{ PF_DUMMYNET,		"dummynet" },
	{ PF_NODUMMYNET,	"nodummynet" },
	{ PF_NAT64,		"nat64" },
	{ PF_NONAT64,		"nonat64" },
#endif
	{ 0,			NULL }
};

static const struct tok pf_directions[] = {
	{ PF_INOUT,	"in/out" },
	{ PF_IN,	"in" },
	{ PF_OUT,	"out" },
#if defined(__OpenBSD__)
	{ PF_FWD,	"fwd" },
#endif
	{ 0,		NULL }
};

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

	ndo->ndo_protocol = "pflog";
	rulenr = GET_BE_U_4(hdr->rulenr);
	subrulenr = GET_BE_U_4(hdr->subrulenr);
	if (subrulenr == (uint32_t)-1)
		ND_PRINT("rule %u/", rulenr);
	else {
		ND_PRINT("rule %u.", rulenr);
		nd_printjnp(ndo, (const u_char*)hdr->ruleset, PFLOG_RULESET_NAME_SIZE);
		ND_PRINT(".%u/", subrulenr);
	}

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

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

	ndo->ndo_protocol = "pflog";
	/* check length */
	if (caplen < sizeof(uint8_t)) {
		nd_print_trunc(ndo);
		ndo->ndo_ll_hdr_len += h->caplen;
		return;
	}

	hdr = (const struct pfloghdr *)p;
	hdrlen = GET_U_1(hdr->length);
	if (hdrlen < MIN_PFLOG_HDRLEN) {
		ND_PRINT("[pflog: invalid header length!]");
		ndo->ndo_ll_hdr_len += hdrlen;	/* XXX: not really */
		return;
	}
	hdrlen = roundup2(hdrlen, 4);

	if (caplen < hdrlen) {
		nd_print_trunc(ndo);
		ndo->ndo_ll_hdr_len += hdrlen;	/* XXX: true? */
		return;
	}

	/* print what we know */
	ND_TCHECK_SIZE(hdr);
	if (ndo->ndo_eflag)
		pflog_print(ndo, hdr);

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

		/*
		 * If there's a system that doesn't use the AF_INET
		 * from 4.2BSD, feel free to add its value to af.h
		 * and use it here.
		 *
		 * Hopefully, there isn't.
		 */
		case BSD_AFNUM_INET:
		        ip_print(ndo, p, length);
			break;

		/*
		 * Try all AF_INET6 values for all systems with pflog,
		 * including Darwin.
		 */
		case BSD_AFNUM_INET6_BSD:
		case BSD_AFNUM_INET6_FREEBSD:
		case BSD_AFNUM_INET6_DARWIN:
			ip6_print(ndo, p, length);
			break;

	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);
	}

	ndo->ndo_ll_hdr_len += hdrlen;
	return;
trunc:
	nd_print_trunc(ndo);
	ndo->ndo_ll_hdr_len += hdrlen;
}
