10f74e101Schristos /* 20f74e101Schristos * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996 30f74e101Schristos * The Regents of the University of California. All rights reserved. 40f74e101Schristos * 50f74e101Schristos * Redistribution and use in source and binary forms, with or without 60f74e101Schristos * modification, are permitted provided that: (1) source code distributions 70f74e101Schristos * retain the above copyright notice and this paragraph in its entirety, (2) 80f74e101Schristos * distributions including binary code include the above copyright notice and 90f74e101Schristos * this paragraph in its entirety in the documentation or other materials 100f74e101Schristos * provided with the distribution, and (3) all advertising materials mentioning 110f74e101Schristos * features or use of this software display the following acknowledgement: 120f74e101Schristos * ``This product includes software developed by the University of California, 130f74e101Schristos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 140f74e101Schristos * the University nor the names of its contributors may be used to endorse 150f74e101Schristos * or promote products derived from this software without specific prior 160f74e101Schristos * written permission. 170f74e101Schristos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 180f74e101Schristos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 190f74e101Schristos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 200f74e101Schristos */ 210f74e101Schristos 2211b3aaa1Schristos #include <sys/cdefs.h> 230f74e101Schristos #ifndef lint 24*26ba0b50Schristos __RCSID("$NetBSD: print-pflog.c,v 1.10 2024/09/02 16:15:32 christos Exp $"); 250f74e101Schristos #endif 260f74e101Schristos 27c74ad251Schristos /* \summary: *BSD/Darwin packet filter log file printer */ 28dc860a36Sspz 29c74ad251Schristos #include <config.h> 300f74e101Schristos 31c74ad251Schristos #include "netdissect-stdinc.h" 320f74e101Schristos 33fdccd7e4Schristos #include "netdissect.h" 34b3a00663Schristos #include "extract.h" 35c74ad251Schristos #include "af.h" 36b3a00663Schristos 37c74ad251Schristos #include "pflog.h" 380f74e101Schristos 39870189d2Schristos static const struct tok pf_reasons[] = { 40c74ad251Schristos { PFRES_MATCH, "0(match)" }, 41c74ad251Schristos { PFRES_BADOFF, "1(bad-offset)" }, 42c74ad251Schristos { PFRES_FRAG, "2(fragment)" }, 43*26ba0b50Schristos { PFRES_SHORT, "3(short)" }, 44c74ad251Schristos { PFRES_NORM, "4(normalize)" }, 45c74ad251Schristos { PFRES_MEMORY, "5(memory)" }, 46c74ad251Schristos { PFRES_TS, "6(bad-timestamp)" }, 47c74ad251Schristos { PFRES_CONGEST, "7(congestion)" }, 48c74ad251Schristos { PFRES_IPOPTIONS, "8(ip-option)" }, 49c74ad251Schristos { PFRES_PROTCKSUM, "9(proto-cksum)" }, 50c74ad251Schristos { PFRES_BADSTATE, "10(state-mismatch)" }, 51c74ad251Schristos { PFRES_STATEINS, "11(state-insert)" }, 52c74ad251Schristos { PFRES_MAXSTATES, "12(state-limit)" }, 53c74ad251Schristos { PFRES_SRCLIMIT, "13(src-limit)" }, 54c74ad251Schristos { PFRES_SYNPROXY, "14(synproxy)" }, 55c74ad251Schristos #if defined(__FreeBSD__) 56c74ad251Schristos { PFRES_MAPFAILED, "15(map-failed)" }, 57c74ad251Schristos #elif defined(__NetBSD__) 58c74ad251Schristos { PFRES_STATELOCKED, "15(state-locked)" }, 59c74ad251Schristos #elif defined(__OpenBSD__) 60c74ad251Schristos { PFRES_TRANSLATE, "15(translate)" }, 61c74ad251Schristos { PFRES_NOROUTE, "16(no-route)" }, 62c74ad251Schristos #elif defined(__APPLE__) 63c74ad251Schristos { PFRES_DUMMYNET, "15(dummynet)" }, 64c74ad251Schristos #endif 650f74e101Schristos { 0, NULL } 660f74e101Schristos }; 670f74e101Schristos 68870189d2Schristos static const struct tok pf_actions[] = { 690f74e101Schristos { PF_PASS, "pass" }, 700f74e101Schristos { PF_DROP, "block" }, 710f74e101Schristos { PF_SCRUB, "scrub" }, 720f74e101Schristos { PF_NAT, "nat" }, 73c74ad251Schristos { PF_NONAT, "nonat" }, 740f74e101Schristos { PF_BINAT, "binat" }, 75c74ad251Schristos { PF_NOBINAT, "nobinat" }, 760f74e101Schristos { PF_RDR, "rdr" }, 77c74ad251Schristos { PF_NORDR, "nordr" }, 780f74e101Schristos { PF_SYNPROXY_DROP, "synproxy-drop" }, 79c74ad251Schristos #if defined(__FreeBSD__) 80c74ad251Schristos { PF_DEFER, "defer" }, 81c74ad251Schristos #elif defined(__OpenBSD__) 82c74ad251Schristos { PF_DEFER, "defer" }, 83c74ad251Schristos { PF_MATCH, "match" }, 84c74ad251Schristos { PF_DIVERT, "divert" }, 85c74ad251Schristos { PF_RT, "rt" }, 86c74ad251Schristos { PF_AFRT, "afrt" }, 87c74ad251Schristos #elif defined(__APPLE__) 88c74ad251Schristos { PF_DUMMYNET, "dummynet" }, 89c74ad251Schristos { PF_NODUMMYNET, "nodummynet" }, 90c74ad251Schristos { PF_NAT64, "nat64" }, 91c74ad251Schristos { PF_NONAT64, "nonat64" }, 92c74ad251Schristos #endif 930f74e101Schristos { 0, NULL } 940f74e101Schristos }; 950f74e101Schristos 96870189d2Schristos static const struct tok pf_directions[] = { 970f74e101Schristos { PF_INOUT, "in/out" }, 980f74e101Schristos { PF_IN, "in" }, 990f74e101Schristos { PF_OUT, "out" }, 100c74ad251Schristos #if defined(__OpenBSD__) 101c74ad251Schristos { PF_FWD, "fwd" }, 102c74ad251Schristos #endif 1030f74e101Schristos { 0, NULL } 1040f74e101Schristos }; 1050f74e101Schristos 1060f74e101Schristos static void 107b3a00663Schristos pflog_print(netdissect_options *ndo, const struct pfloghdr *hdr) 1080f74e101Schristos { 109b3a00663Schristos uint32_t rulenr, subrulenr; 1100f74e101Schristos 111c74ad251Schristos ndo->ndo_protocol = "pflog"; 112*26ba0b50Schristos rulenr = GET_BE_U_4(hdr->rulenr); 113*26ba0b50Schristos subrulenr = GET_BE_U_4(hdr->subrulenr); 114b3a00663Schristos if (subrulenr == (uint32_t)-1) 115c74ad251Schristos ND_PRINT("rule %u/", rulenr); 116c74ad251Schristos else { 117c74ad251Schristos ND_PRINT("rule %u.", rulenr); 118c74ad251Schristos nd_printjnp(ndo, (const u_char*)hdr->ruleset, PFLOG_RULESET_NAME_SIZE); 119c74ad251Schristos ND_PRINT(".%u/", subrulenr); 1200f74e101Schristos } 1210f74e101Schristos 122c74ad251Schristos ND_PRINT("%s: %s %s on ", 123*26ba0b50Schristos tok2str(pf_reasons, "unkn(%u)", GET_U_1(hdr->reason)), 124*26ba0b50Schristos tok2str(pf_actions, "unkn(%u)", GET_U_1(hdr->action)), 125*26ba0b50Schristos tok2str(pf_directions, "unkn(%u)", GET_U_1(hdr->dir))); 126c74ad251Schristos nd_printjnp(ndo, (const u_char*)hdr->ifname, PFLOG_IFNAMSIZ); 127c74ad251Schristos ND_PRINT(": "); 128c74ad251Schristos } 129c74ad251Schristos 130c74ad251Schristos void 131b3a00663Schristos pflog_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, 132c74ad251Schristos const u_char *p) 1330f74e101Schristos { 1340f74e101Schristos u_int length = h->len; 1350f74e101Schristos u_int hdrlen; 1360f74e101Schristos u_int caplen = h->caplen; 1370f74e101Schristos const struct pfloghdr *hdr; 138b3a00663Schristos uint8_t af; 1390f74e101Schristos 140c74ad251Schristos ndo->ndo_protocol = "pflog"; 1410f74e101Schristos /* check length */ 142b3a00663Schristos if (caplen < sizeof(uint8_t)) { 143c74ad251Schristos nd_print_trunc(ndo); 144c74ad251Schristos ndo->ndo_ll_hdr_len += h->caplen; 145c74ad251Schristos return; 1460f74e101Schristos } 1470f74e101Schristos 148dc860a36Sspz hdr = (const struct pfloghdr *)p; 149*26ba0b50Schristos hdrlen = GET_U_1(hdr->length); 150*26ba0b50Schristos if (hdrlen < MIN_PFLOG_HDRLEN) { 151c74ad251Schristos ND_PRINT("[pflog: invalid header length!]"); 152*26ba0b50Schristos ndo->ndo_ll_hdr_len += hdrlen; /* XXX: not really */ 153c74ad251Schristos return; 1540f74e101Schristos } 155*26ba0b50Schristos hdrlen = roundup2(hdrlen, 4); 1560f74e101Schristos 1570f74e101Schristos if (caplen < hdrlen) { 158c74ad251Schristos nd_print_trunc(ndo); 159c74ad251Schristos ndo->ndo_ll_hdr_len += hdrlen; /* XXX: true? */ 160c74ad251Schristos return; 1610f74e101Schristos } 1620f74e101Schristos 1630f74e101Schristos /* print what we know */ 164c74ad251Schristos ND_TCHECK_SIZE(hdr); 165b3a00663Schristos if (ndo->ndo_eflag) 166b3a00663Schristos pflog_print(ndo, hdr); 1670f74e101Schristos 1680f74e101Schristos /* skip to the real packet */ 169*26ba0b50Schristos af = GET_U_1(hdr->af); 1700f74e101Schristos length -= hdrlen; 1710f74e101Schristos caplen -= hdrlen; 1720f74e101Schristos p += hdrlen; 1730f74e101Schristos switch (af) { 1740f74e101Schristos 175c74ad251Schristos /* 176c74ad251Schristos * If there's a system that doesn't use the AF_INET 177c74ad251Schristos * from 4.2BSD, feel free to add its value to af.h 178c74ad251Schristos * and use it here. 179c74ad251Schristos * 180c74ad251Schristos * Hopefully, there isn't. 181c74ad251Schristos */ 182c74ad251Schristos case BSD_AFNUM_INET: 183b3a00663Schristos ip_print(ndo, p, length); 1840f74e101Schristos break; 1850f74e101Schristos 186c74ad251Schristos /* 187c74ad251Schristos * Try all AF_INET6 values for all systems with pflog, 188c74ad251Schristos * including Darwin. 189c74ad251Schristos */ 190c74ad251Schristos case BSD_AFNUM_INET6_BSD: 191c74ad251Schristos case BSD_AFNUM_INET6_FREEBSD: 192c74ad251Schristos case BSD_AFNUM_INET6_DARWIN: 193b3a00663Schristos ip6_print(ndo, p, length); 1940f74e101Schristos break; 1950f74e101Schristos 1960f74e101Schristos default: 1970f74e101Schristos /* address family not handled, print raw packet */ 198b3a00663Schristos if (!ndo->ndo_eflag) 199b3a00663Schristos pflog_print(ndo, hdr); 200b3a00663Schristos if (!ndo->ndo_suppress_default_print) 201b3a00663Schristos ND_DEFAULTPRINT(p, caplen); 2020f74e101Schristos } 2030f74e101Schristos 204c74ad251Schristos ndo->ndo_ll_hdr_len += hdrlen; 205c74ad251Schristos return; 2060f74e101Schristos trunc: 207c74ad251Schristos nd_print_trunc(ndo); 208c74ad251Schristos ndo->ndo_ll_hdr_len += hdrlen; 2090f74e101Schristos } 210