1*d0cb3502Smcbride /* $OpenBSD: pfctl_parser.c,v 1.124 2002/12/30 23:46:54 mcbride Exp $ */ 214a9b182Skjell 314a9b182Skjell /* 4fd3c3a0cSderaadt * Copyright (c) 2001 Daniel Hartmeier 514a9b182Skjell * All rights reserved. 614a9b182Skjell * 714a9b182Skjell * Redistribution and use in source and binary forms, with or without 814a9b182Skjell * modification, are permitted provided that the following conditions 914a9b182Skjell * are met: 1014a9b182Skjell * 1114a9b182Skjell * - Redistributions of source code must retain the above copyright 1214a9b182Skjell * notice, this list of conditions and the following disclaimer. 1314a9b182Skjell * - Redistributions in binary form must reproduce the above 1414a9b182Skjell * copyright notice, this list of conditions and the following 1514a9b182Skjell * disclaimer in the documentation and/or other materials provided 1614a9b182Skjell * with the distribution. 1714a9b182Skjell * 1814a9b182Skjell * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1914a9b182Skjell * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2014a9b182Skjell * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2114a9b182Skjell * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 225974bd37Sdhartmei * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2314a9b182Skjell * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2414a9b182Skjell * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2514a9b182Skjell * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 2614a9b182Skjell * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2714a9b182Skjell * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 2814a9b182Skjell * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2914a9b182Skjell * POSSIBILITY OF SUCH DAMAGE. 3014a9b182Skjell * 3114a9b182Skjell */ 3214a9b182Skjell 33252d784aSderaadt #include <sys/types.h> 34252d784aSderaadt #include <sys/socket.h> 35252d784aSderaadt #include <net/if.h> 36252d784aSderaadt #include <netinet/in.h> 376329fa59Sderaadt #include <netinet/in_systm.h> 386329fa59Sderaadt #include <netinet/ip.h> 396329fa59Sderaadt #include <netinet/ip_icmp.h> 4030620b12Sfrantzen #include <netinet/icmp6.h> 41252d784aSderaadt #include <net/pfvar.h> 429f13c6caSmillert #include <arpa/inet.h> 43252d784aSderaadt 4414a9b182Skjell #include <stdio.h> 4514a9b182Skjell #include <stdlib.h> 4614a9b182Skjell #include <string.h> 4714a9b182Skjell #include <ctype.h> 4814a9b182Skjell #include <netdb.h> 496329fa59Sderaadt #include <stdarg.h> 506329fa59Sderaadt #include <errno.h> 51ff352a37Smarkus #include <err.h> 5214a9b182Skjell 5314a9b182Skjell #include "pfctl_parser.h" 54828e0448Smickey #include "pf_print_state.h" 5514a9b182Skjell 565d9ac2dcSdhartmei void print_op (u_int8_t, const char *, const char *); 5781a15e5dSderaadt void print_port (u_int8_t, u_int16_t, u_int16_t, char *); 585d9ac2dcSdhartmei void print_uid (u_int8_t, uid_t, uid_t, const char *); 59c16ab608Sdhartmei void print_gid (u_int8_t, gid_t, gid_t, const char *); 6081a15e5dSderaadt void print_flags (u_int8_t); 6115e76891Sdhartmei void print_fromto(struct pf_rule_addr *, struct pf_rule_addr *, 6215e76891Sdhartmei u_int8_t, u_int8_t); 6314a9b182Skjell 64bc795af0Shugh char *tcpflags = "FSRPAUEW"; 6514a9b182Skjell 667d27d81aSdhartmei static const struct icmptypeent icmp_type[] = { 67082ebc44Swilfried { "echoreq", ICMP_ECHO }, 68082ebc44Swilfried { "echorep", ICMP_ECHOREPLY }, 69082ebc44Swilfried { "unreach", ICMP_UNREACH }, 70082ebc44Swilfried { "squench", ICMP_SOURCEQUENCH }, 71082ebc44Swilfried { "redir", ICMP_REDIRECT }, 72082ebc44Swilfried { "althost", ICMP_ALTHOSTADDR }, 73082ebc44Swilfried { "routeradv", ICMP_ROUTERADVERT }, 74082ebc44Swilfried { "routersol", ICMP_ROUTERSOLICIT }, 75082ebc44Swilfried { "timex", ICMP_TIMXCEED }, 76082ebc44Swilfried { "paramprob", ICMP_PARAMPROB }, 77082ebc44Swilfried { "timereq", ICMP_TSTAMP }, 78082ebc44Swilfried { "timerep", ICMP_TSTAMPREPLY }, 79082ebc44Swilfried { "inforeq", ICMP_IREQ }, 80082ebc44Swilfried { "inforep", ICMP_IREQREPLY }, 81082ebc44Swilfried { "maskreq", ICMP_MASKREQ }, 8202cbcc9eSwilfried { "maskrep", ICMP_MASKREPLY }, 8302cbcc9eSwilfried { "trace", ICMP_TRACEROUTE }, 8402cbcc9eSwilfried { "dataconv", ICMP_DATACONVERR }, 8502cbcc9eSwilfried { "mobredir", ICMP_MOBILE_REDIRECT }, 8602cbcc9eSwilfried { "ipv6-where", ICMP_IPV6_WHEREAREYOU }, 8702cbcc9eSwilfried { "ipv6-here", ICMP_IPV6_IAMHERE }, 8802cbcc9eSwilfried { "mobregreq", ICMP_MOBILE_REGREQUEST }, 8902cbcc9eSwilfried { "mobregrep", ICMP_MOBILE_REGREPLY }, 9002cbcc9eSwilfried { "skip", ICMP_SKIP }, 9102cbcc9eSwilfried { "photuris", ICMP_PHOTURIS } 92082ebc44Swilfried }; 93082ebc44Swilfried 947d27d81aSdhartmei static const struct icmptypeent icmp6_type[] = { 9530620b12Sfrantzen { "unreach", ICMP6_DST_UNREACH }, 9630620b12Sfrantzen { "toobig", ICMP6_PACKET_TOO_BIG }, 9730620b12Sfrantzen { "timex", ICMP6_TIME_EXCEEDED }, 9830620b12Sfrantzen { "paramprob", ICMP6_PARAM_PROB }, 9930620b12Sfrantzen { "echoreq", ICMP6_ECHO_REQUEST }, 10030620b12Sfrantzen { "echorep", ICMP6_ECHO_REPLY }, 10130620b12Sfrantzen { "groupqry", ICMP6_MEMBERSHIP_QUERY }, 10230620b12Sfrantzen { "listqry", MLD6_LISTENER_QUERY }, 10330620b12Sfrantzen { "grouprep", ICMP6_MEMBERSHIP_REPORT }, 10430620b12Sfrantzen { "listenrep", MLD6_LISTENER_REPORT }, 10530620b12Sfrantzen { "groupterm", ICMP6_MEMBERSHIP_REDUCTION }, 10630620b12Sfrantzen { "listendone", MLD6_LISTENER_DONE }, 10730620b12Sfrantzen { "routersol", ND_ROUTER_SOLICIT }, 10830620b12Sfrantzen { "routeradv", ND_ROUTER_ADVERT }, 10930620b12Sfrantzen { "neighbrsol", ND_NEIGHBOR_SOLICIT }, 11030620b12Sfrantzen { "neighbradv", ND_NEIGHBOR_ADVERT }, 11130620b12Sfrantzen { "redir", ND_REDIRECT }, 11230620b12Sfrantzen { "routrrenum", ICMP6_ROUTER_RENUMBERING }, 11330620b12Sfrantzen { "wrureq", ICMP6_WRUREQUEST }, 11430620b12Sfrantzen { "wrurep", ICMP6_WRUREPLY }, 11530620b12Sfrantzen { "fqdnreq", ICMP6_FQDN_QUERY }, 11630620b12Sfrantzen { "fqdnrep", ICMP6_FQDN_REPLY }, 11730620b12Sfrantzen { "niqry", ICMP6_NI_QUERY }, 11830620b12Sfrantzen { "nirep", ICMP6_NI_REPLY }, 11930620b12Sfrantzen { "mtraceresp", MLD6_MTRACE_RESP }, 12030620b12Sfrantzen { "mtrace", MLD6_MTRACE } 12130620b12Sfrantzen }; 12230620b12Sfrantzen 1237d27d81aSdhartmei static const struct icmpcodeent icmp_code[] = { 124082ebc44Swilfried { "net-unr", ICMP_UNREACH, ICMP_UNREACH_NET }, 125082ebc44Swilfried { "host-unr", ICMP_UNREACH, ICMP_UNREACH_HOST }, 126082ebc44Swilfried { "proto-unr", ICMP_UNREACH, ICMP_UNREACH_PROTOCOL }, 127082ebc44Swilfried { "port-unr", ICMP_UNREACH, ICMP_UNREACH_PORT }, 128082ebc44Swilfried { "needfrag", ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG }, 129082ebc44Swilfried { "srcfail", ICMP_UNREACH, ICMP_UNREACH_SRCFAIL }, 130082ebc44Swilfried { "net-unk", ICMP_UNREACH, ICMP_UNREACH_NET_UNKNOWN }, 131082ebc44Swilfried { "host-unk", ICMP_UNREACH, ICMP_UNREACH_HOST_UNKNOWN }, 132082ebc44Swilfried { "isolate", ICMP_UNREACH, ICMP_UNREACH_ISOLATED }, 133082ebc44Swilfried { "net-prohib", ICMP_UNREACH, ICMP_UNREACH_NET_PROHIB }, 134082ebc44Swilfried { "host-prohib", ICMP_UNREACH, ICMP_UNREACH_HOST_PROHIB }, 135082ebc44Swilfried { "net-tos", ICMP_UNREACH, ICMP_UNREACH_TOSNET }, 136082ebc44Swilfried { "host-tos", ICMP_UNREACH, ICMP_UNREACH_TOSHOST }, 137082ebc44Swilfried { "filter-prohib", ICMP_UNREACH, ICMP_UNREACH_FILTER_PROHIB }, 138082ebc44Swilfried { "host-preced", ICMP_UNREACH, ICMP_UNREACH_HOST_PRECEDENCE }, 139082ebc44Swilfried { "cutoff-preced", ICMP_UNREACH, ICMP_UNREACH_PRECEDENCE_CUTOFF }, 140082ebc44Swilfried { "redir-net", ICMP_REDIRECT, ICMP_REDIRECT_NET }, 141082ebc44Swilfried { "redir-host", ICMP_REDIRECT, ICMP_REDIRECT_HOST }, 142082ebc44Swilfried { "redir-tos-net", ICMP_REDIRECT, ICMP_REDIRECT_TOSNET }, 143082ebc44Swilfried { "redir-tos-host", ICMP_REDIRECT, ICMP_REDIRECT_TOSHOST }, 14402cbcc9eSwilfried { "normal-adv", ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NORMAL }, 14502cbcc9eSwilfried { "common-adv", ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NOROUTE_COMMON }, 146082ebc44Swilfried { "transit", ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS }, 147082ebc44Swilfried { "reassemb", ICMP_TIMXCEED, ICMP_TIMXCEED_REASS }, 148082ebc44Swilfried { "badhead", ICMP_PARAMPROB, ICMP_PARAMPROB_ERRATPTR }, 149082ebc44Swilfried { "optmiss", ICMP_PARAMPROB, ICMP_PARAMPROB_OPTABSENT }, 15002cbcc9eSwilfried { "badlen", ICMP_PARAMPROB, ICMP_PARAMPROB_LENGTH }, 15102cbcc9eSwilfried { "unknown-ind", ICMP_PHOTURIS, ICMP_PHOTURIS_UNKNOWN_INDEX }, 15202cbcc9eSwilfried { "auth-fail", ICMP_PHOTURIS, ICMP_PHOTURIS_AUTH_FAILED }, 15302cbcc9eSwilfried { "decrypt-fail", ICMP_PHOTURIS, ICMP_PHOTURIS_DECRYPT_FAILED } 154082ebc44Swilfried }; 155082ebc44Swilfried 1567d27d81aSdhartmei static const struct icmpcodeent icmp6_code[] = { 1571d32ee3bSdhartmei { "admin-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN }, 1581d32ee3bSdhartmei { "noroute-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE }, 15930620b12Sfrantzen { "notnbr-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOTNEIGHBOR }, 16030620b12Sfrantzen { "beyond-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_BEYONDSCOPE }, 16130620b12Sfrantzen { "addr-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADDR }, 16230620b12Sfrantzen { "port-unr", ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT }, 16330620b12Sfrantzen { "transit", ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT }, 16430620b12Sfrantzen { "reassemb", ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY }, 16530620b12Sfrantzen { "badhead", ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER }, 16630620b12Sfrantzen { "nxthdr", ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER }, 16730620b12Sfrantzen { "redironlink", ND_REDIRECT, ND_REDIRECT_ONLINK }, 16830620b12Sfrantzen { "redirrouter", ND_REDIRECT, ND_REDIRECT_ROUTER } 16930620b12Sfrantzen }; 17030620b12Sfrantzen 171d593fb91Sdrahn const struct pf_timeout pf_timeouts[] = { 172d593fb91Sdrahn { "tcp.first", PFTM_TCP_FIRST_PACKET }, 173d593fb91Sdrahn { "tcp.opening", PFTM_TCP_OPENING }, 174d593fb91Sdrahn { "tcp.established", PFTM_TCP_ESTABLISHED }, 175d593fb91Sdrahn { "tcp.closing", PFTM_TCP_CLOSING }, 176d593fb91Sdrahn { "tcp.finwait", PFTM_TCP_FIN_WAIT }, 177d593fb91Sdrahn { "tcp.closed", PFTM_TCP_CLOSED }, 178d593fb91Sdrahn { "udp.first", PFTM_UDP_FIRST_PACKET }, 179d593fb91Sdrahn { "udp.single", PFTM_UDP_SINGLE }, 180d593fb91Sdrahn { "udp.multiple", PFTM_UDP_MULTIPLE }, 181d593fb91Sdrahn { "icmp.first", PFTM_ICMP_FIRST_PACKET }, 182d593fb91Sdrahn { "icmp.error", PFTM_ICMP_ERROR_REPLY }, 183d593fb91Sdrahn { "other.first", PFTM_OTHER_FIRST_PACKET }, 184d593fb91Sdrahn { "other.single", PFTM_OTHER_SINGLE }, 185d593fb91Sdrahn { "other.multiple", PFTM_OTHER_MULTIPLE }, 186d593fb91Sdrahn { "frag", PFTM_FRAG }, 187d593fb91Sdrahn { "interval", PFTM_INTERVAL }, 188d593fb91Sdrahn { NULL, 0 } 189d593fb91Sdrahn }; 190d593fb91Sdrahn 1917d27d81aSdhartmei const struct icmptypeent * 192bb9f691eSmcbride geticmptypebynumber(u_int8_t type, sa_family_t af) 193082ebc44Swilfried { 194ed99c291Sderaadt unsigned int i; 195082ebc44Swilfried 196d14c53d7Swilfried if (af != AF_INET6) { 197082ebc44Swilfried for (i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); i++) { 198082ebc44Swilfried if (type == icmp_type[i].type) 199082ebc44Swilfried return (&icmp_type[i]); 200082ebc44Swilfried } 20130620b12Sfrantzen } else { 20230620b12Sfrantzen for (i=0; i < (sizeof (icmp6_type) / 20330620b12Sfrantzen sizeof(icmp6_type[0])); i++) { 20430620b12Sfrantzen if (type == icmp6_type[i].type) 20530620b12Sfrantzen return (&icmp6_type[i]); 20630620b12Sfrantzen } 20730620b12Sfrantzen } 20830620b12Sfrantzen return (NULL); 209082ebc44Swilfried } 210082ebc44Swilfried 2117d27d81aSdhartmei const struct icmptypeent * 212bb9f691eSmcbride geticmptypebyname(char *w, sa_family_t af) 213082ebc44Swilfried { 214ed99c291Sderaadt unsigned int i; 215082ebc44Swilfried 216d14c53d7Swilfried if (af != AF_INET6) { 217082ebc44Swilfried for (i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); i++) { 218082ebc44Swilfried if (!strcmp(w, icmp_type[i].name)) 219082ebc44Swilfried return (&icmp_type[i]); 220082ebc44Swilfried } 22130620b12Sfrantzen } else { 22230620b12Sfrantzen for (i=0; i < (sizeof (icmp6_type) / 22330620b12Sfrantzen sizeof(icmp6_type[0])); i++) { 22430620b12Sfrantzen if (!strcmp(w, icmp6_type[i].name)) 22530620b12Sfrantzen return (&icmp6_type[i]); 22630620b12Sfrantzen } 22730620b12Sfrantzen } 22830620b12Sfrantzen return (NULL); 229082ebc44Swilfried } 230082ebc44Swilfried 2317d27d81aSdhartmei const struct icmpcodeent * 232bb9f691eSmcbride geticmpcodebynumber(u_int8_t type, u_int8_t code, sa_family_t af) 233082ebc44Swilfried { 234ed99c291Sderaadt unsigned int i; 235082ebc44Swilfried 236d14c53d7Swilfried if (af != AF_INET6) { 237082ebc44Swilfried for (i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); i++) { 23830620b12Sfrantzen if (type == icmp_code[i].type && 23930620b12Sfrantzen code == icmp_code[i].code) 240082ebc44Swilfried return (&icmp_code[i]); 241082ebc44Swilfried } 24230620b12Sfrantzen } else { 24330620b12Sfrantzen for (i=0; i < (sizeof (icmp6_code) / 24430620b12Sfrantzen sizeof(icmp6_code[0])); i++) { 24530620b12Sfrantzen if (type == icmp6_code[i].type && 24630620b12Sfrantzen code == icmp6_code[i].code) 24730620b12Sfrantzen return (&icmp6_code[i]); 24830620b12Sfrantzen } 24930620b12Sfrantzen } 25030620b12Sfrantzen return (NULL); 251082ebc44Swilfried } 252082ebc44Swilfried 2537d27d81aSdhartmei const struct icmpcodeent * 254bb9f691eSmcbride geticmpcodebyname(u_long type, char *w, sa_family_t af) 255082ebc44Swilfried { 256ed99c291Sderaadt unsigned int i; 257082ebc44Swilfried 258d14c53d7Swilfried if (af != AF_INET6) { 259082ebc44Swilfried for (i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); i++) { 26030620b12Sfrantzen if (type == icmp_code[i].type && 26130620b12Sfrantzen !strcmp(w, icmp_code[i].name)) 262082ebc44Swilfried return (&icmp_code[i]); 263082ebc44Swilfried } 26430620b12Sfrantzen } else { 26530620b12Sfrantzen for (i=0; i < (sizeof (icmp6_code) / 26630620b12Sfrantzen sizeof(icmp6_code[0])); i++) { 26730620b12Sfrantzen if (type == icmp6_code[i].type && 26830620b12Sfrantzen !strcmp(w, icmp6_code[i].name)) 26930620b12Sfrantzen return (&icmp6_code[i]); 27030620b12Sfrantzen } 27130620b12Sfrantzen } 27230620b12Sfrantzen return (NULL); 27330620b12Sfrantzen } 27430620b12Sfrantzen 27581a15e5dSderaadt void 2765d9ac2dcSdhartmei print_op(u_int8_t op, const char *a1, const char *a2) 2775d9ac2dcSdhartmei { 2785d9ac2dcSdhartmei if (op == PF_OP_IRG) 2795d9ac2dcSdhartmei printf("%s >< %s ", a1, a2); 2805d9ac2dcSdhartmei else if (op == PF_OP_XRG) 2815d9ac2dcSdhartmei printf("%s <> %s ", a1, a2); 2821308506cShenning else if (op == PF_OP_EQ) 2835d9ac2dcSdhartmei printf("= %s ", a1); 2841308506cShenning else if (op == PF_OP_NE) 2855d9ac2dcSdhartmei printf("!= %s ", a1); 2861308506cShenning else if (op == PF_OP_LT) 2875d9ac2dcSdhartmei printf("< %s ", a1); 2885d9ac2dcSdhartmei else if (op == PF_OP_LE) 2895d9ac2dcSdhartmei printf("<= %s ", a1); 2905d9ac2dcSdhartmei else if (op == PF_OP_GT) 2915d9ac2dcSdhartmei printf("> %s ", a1); 2925d9ac2dcSdhartmei else if (op == PF_OP_GE) 2935d9ac2dcSdhartmei printf(">= %s ", a1); 2945d9ac2dcSdhartmei } 2955d9ac2dcSdhartmei 2965d9ac2dcSdhartmei void 29714a9b182Skjell print_port(u_int8_t op, u_int16_t p1, u_int16_t p2, char *proto) 29814a9b182Skjell { 299e31d21c9Sdhartmei char a1[6], a2[6]; 30014a9b182Skjell struct servent *s = getservbyport(p1, proto); 30181a15e5dSderaadt 30214a9b182Skjell p1 = ntohs(p1); 30314a9b182Skjell p2 = ntohs(p2); 3045d9ac2dcSdhartmei snprintf(a1, sizeof(a1), "%u", p1); 3055d9ac2dcSdhartmei snprintf(a2, sizeof(a2), "%u", p2); 30614a9b182Skjell printf("port "); 3075d9ac2dcSdhartmei if (s != NULL && (op == PF_OP_EQ || op == PF_OP_NE)) 3085d9ac2dcSdhartmei print_op(op, s->s_name, a2); 30914a9b182Skjell else 3105d9ac2dcSdhartmei print_op(op, a1, a2); 3115d9ac2dcSdhartmei } 3125d9ac2dcSdhartmei 3135d9ac2dcSdhartmei void 3145d9ac2dcSdhartmei print_uid(u_int8_t op, uid_t u1, uid_t u2, const char *t) 3155d9ac2dcSdhartmei { 316d8fcd2dfSdhartmei char a1[11], a2[11]; 3175d9ac2dcSdhartmei 3185d9ac2dcSdhartmei snprintf(a1, sizeof(a1), "%u", u1); 3195d9ac2dcSdhartmei snprintf(a2, sizeof(a2), "%u", u2); 3205d9ac2dcSdhartmei printf("%s ", t); 3215d9ac2dcSdhartmei if (u1 == UID_MAX && (op == PF_OP_EQ || op == PF_OP_NE)) 3225d9ac2dcSdhartmei print_op(op, "unknown", a2); 32314a9b182Skjell else 3245d9ac2dcSdhartmei print_op(op, a1, a2); 32514a9b182Skjell } 32614a9b182Skjell 32781a15e5dSderaadt void 328c16ab608Sdhartmei print_gid(u_int8_t op, gid_t g1, gid_t g2, const char *t) 329c16ab608Sdhartmei { 330d8fcd2dfSdhartmei char a1[11], a2[11]; 331c16ab608Sdhartmei 332c16ab608Sdhartmei snprintf(a1, sizeof(a1), "%u", g1); 333c16ab608Sdhartmei snprintf(a2, sizeof(a2), "%u", g2); 334c16ab608Sdhartmei printf("%s ", t); 335c16ab608Sdhartmei if (g1 == GID_MAX && (op == PF_OP_EQ || op == PF_OP_NE)) 336c16ab608Sdhartmei print_op(op, "unknown", a2); 337c16ab608Sdhartmei else 338c16ab608Sdhartmei print_op(op, a1, a2); 339c16ab608Sdhartmei } 340c16ab608Sdhartmei 341c16ab608Sdhartmei void 34214a9b182Skjell print_flags(u_int8_t f) 34314a9b182Skjell { 34414a9b182Skjell int i; 34581a15e5dSderaadt 346bc795af0Shugh for (i = 0; tcpflags[i]; ++i) 34714a9b182Skjell if (f & (1 << i)) 34814a9b182Skjell printf("%c", tcpflags[i]); 34914a9b182Skjell } 35014a9b182Skjell 35114a9b182Skjell void 35215e76891Sdhartmei print_fromto(struct pf_rule_addr *src, struct pf_rule_addr *dst, 353bb9f691eSmcbride sa_family_t af, u_int8_t proto) 35415e76891Sdhartmei { 35515e76891Sdhartmei if (PF_AZERO(&src->addr.addr, AF_INET6) && 3563a44df3cSmcbride PF_AZERO(&src->addr.mask, AF_INET6) && 35715e76891Sdhartmei !src->noroute && !dst->noroute && 35815e76891Sdhartmei !src->port_op && PF_AZERO(&dst->addr.addr, AF_INET6) && 3593a44df3cSmcbride PF_AZERO(&dst->addr.mask, AF_INET6) && !dst->port_op) 36015e76891Sdhartmei printf("all "); 36115e76891Sdhartmei else { 36215e76891Sdhartmei printf("from "); 36315e76891Sdhartmei if (src->noroute) 36415e76891Sdhartmei printf("no-route "); 36515e76891Sdhartmei else if (PF_AZERO(&src->addr.addr, AF_INET6) && 3663a44df3cSmcbride PF_AZERO(&src->addr.mask, AF_INET6)) 36715e76891Sdhartmei printf("any "); 36815e76891Sdhartmei else { 36915e76891Sdhartmei if (src->not) 37015e76891Sdhartmei printf("! "); 3713a44df3cSmcbride print_addr(&src->addr, af); 37215e76891Sdhartmei printf(" "); 37315e76891Sdhartmei } 37415e76891Sdhartmei if (src->port_op) 37515e76891Sdhartmei print_port(src->port_op, src->port[0], 37615e76891Sdhartmei src->port[1], 37715e76891Sdhartmei proto == IPPROTO_TCP ? "tcp" : "udp"); 37815e76891Sdhartmei 37915e76891Sdhartmei printf("to "); 38015e76891Sdhartmei if (dst->noroute) 38115e76891Sdhartmei printf("no-route "); 38215e76891Sdhartmei else if (PF_AZERO(&dst->addr.addr, AF_INET6) && 3833a44df3cSmcbride PF_AZERO(&dst->addr.mask, AF_INET6)) 38415e76891Sdhartmei printf("any "); 38515e76891Sdhartmei else { 38615e76891Sdhartmei if (dst->not) 38715e76891Sdhartmei printf("! "); 3883a44df3cSmcbride print_addr(&dst->addr, af); 38915e76891Sdhartmei printf(" "); 39015e76891Sdhartmei } 39115e76891Sdhartmei if (dst->port_op) 39215e76891Sdhartmei print_port(dst->port_op, dst->port[0], 39315e76891Sdhartmei dst->port[1], 39415e76891Sdhartmei proto == IPPROTO_TCP ? "tcp" : "udp"); 39515e76891Sdhartmei } 39615e76891Sdhartmei } 39715e76891Sdhartmei 39815e76891Sdhartmei void 399e8793aa9Smcbride print_rule(struct pf_rule *r, int verbose) 400e8793aa9Smcbride { 401e8793aa9Smcbride switch (r->action) { 402e8793aa9Smcbride case PF_NAT: 403e8793aa9Smcbride case PF_NONAT: 40460927d26Sdhartmei print_nat(r, verbose); 405e8793aa9Smcbride break; 406e8793aa9Smcbride case PF_BINAT: 407e8793aa9Smcbride case PF_NOBINAT: 40860927d26Sdhartmei print_binat(r, verbose); 409e8793aa9Smcbride break; 410e8793aa9Smcbride case PF_RDR: 411e8793aa9Smcbride case PF_NORDR: 41260927d26Sdhartmei print_rdr(r, verbose); 413e8793aa9Smcbride break; 414e8793aa9Smcbride default: 415e8793aa9Smcbride case PF_PASS: 416e8793aa9Smcbride case PF_DROP: 417e8793aa9Smcbride case PF_SCRUB: 418e8793aa9Smcbride print_filter(r, verbose); 419e8793aa9Smcbride break; 420e8793aa9Smcbride } 421e8793aa9Smcbride } 422e8793aa9Smcbride 423e8793aa9Smcbride void 424e0c302d0Smcbride print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2, 425e0c302d0Smcbride sa_family_t af, int id) 4263a44df3cSmcbride { 4273a44df3cSmcbride struct pf_pooladdr *pooladdr; 4283a44df3cSmcbride 4296c917913Smcbride if ((TAILQ_FIRST(&pool->list) != NULL) && 4306c917913Smcbride TAILQ_NEXT(TAILQ_FIRST(&pool->list), entries) != NULL) 4313a44df3cSmcbride printf("{ "); 4323a44df3cSmcbride TAILQ_FOREACH(pooladdr, &pool->list, entries){ 4333a44df3cSmcbride switch (id) { 434e8793aa9Smcbride case PF_NAT: 435e8793aa9Smcbride case PF_RDR: 436e8793aa9Smcbride case PF_BINAT: 437e8793aa9Smcbride print_addr(&pooladdr->addr.addr, af); 4383a44df3cSmcbride break; 439e8793aa9Smcbride case PF_PASS: 440e8793aa9Smcbride if (PF_AZERO(&pooladdr->addr.addr.addr, af)) 4413b9b234fSmcbride printf("%s", pooladdr->ifname); 442790504a6Sdhartmei else { 4433a44df3cSmcbride printf("(%s ", pooladdr->ifname); 444e8793aa9Smcbride print_addr(&pooladdr->addr.addr, af); 4453a44df3cSmcbride printf(")"); 4463b9b234fSmcbride } 4473a44df3cSmcbride break; 448e8793aa9Smcbride default: 449e8793aa9Smcbride break; 4503a44df3cSmcbride } 4513a44df3cSmcbride if (TAILQ_NEXT(pooladdr, entries) != NULL) 4523a44df3cSmcbride printf(", "); 4533a44df3cSmcbride else if (TAILQ_NEXT(TAILQ_FIRST(&pool->list), entries) != NULL) 4543a44df3cSmcbride printf(" }"); 4553a44df3cSmcbride } 456e0c302d0Smcbride switch (id) { 457e8793aa9Smcbride case PF_NAT: 458e0c302d0Smcbride if (p1 != PF_NAT_PROXY_PORT_LOW || 459e0c302d0Smcbride p2 != PF_NAT_PROXY_PORT_HIGH) { 460e0c302d0Smcbride if (p1 == p2) 461e0c302d0Smcbride printf(" port %u", p1); 462e0c302d0Smcbride else 463e0c302d0Smcbride printf(" port %u:%u", p1, p2); 464e0c302d0Smcbride } 465e0c302d0Smcbride break; 466e8793aa9Smcbride case PF_RDR: 467e0c302d0Smcbride if (p1) { 468e0c302d0Smcbride printf(" port %u", ntohs(p1)); 469e8793aa9Smcbride if (p2 & PF_OP_RRG) 470e0c302d0Smcbride printf(":*"); 471e0c302d0Smcbride } 472e0c302d0Smcbride break; 473e0c302d0Smcbride default: 474e0c302d0Smcbride break; 475e0c302d0Smcbride } 476e0c302d0Smcbride switch (pool->opts & PF_POOL_TYPEMASK) { 477e0c302d0Smcbride case PF_POOL_NONE: 478e0c302d0Smcbride break; 479e0c302d0Smcbride case PF_POOL_BITMASK: 480e0c302d0Smcbride printf(" bitmask"); 481e0c302d0Smcbride break; 482e0c302d0Smcbride case PF_POOL_RANDOM: 483e0c302d0Smcbride printf(" random"); 484e0c302d0Smcbride break; 485e0c302d0Smcbride case PF_POOL_SRCHASH: 4860436fa02Smcbride printf(" source-hash 0x%08x%08x%08x%08x", 487e0c302d0Smcbride pool->key.key32[0], pool->key.key32[1], 488e0c302d0Smcbride pool->key.key32[2], pool->key.key32[3]); 489e0c302d0Smcbride break; 490e0c302d0Smcbride case PF_POOL_ROUNDROBIN: 491e0c302d0Smcbride printf(" round-robin"); 492e0c302d0Smcbride break; 493e0c302d0Smcbride } 494e0c302d0Smcbride if (pool->opts & PF_POOL_STATICPORT) 495e0c302d0Smcbride printf(" static-port"); 4963a44df3cSmcbride } 4973a44df3cSmcbride 4983a44df3cSmcbride void 49960927d26Sdhartmei print_nat(struct pf_rule *n, int verbose) 50014a9b182Skjell { 50160927d26Sdhartmei if (verbose) 50260927d26Sdhartmei printf("@%d ", n->nr); 5036ac94451Sdhartmei if (n->anchorname[0]) 5046ac94451Sdhartmei printf("nat-anchor %s ", n->anchorname); 5056ac94451Sdhartmei else { 506e8793aa9Smcbride if (n->action == PF_NONAT) 507f27db9bcSdhartmei printf("no "); 508f27db9bcSdhartmei printf("nat "); 5096ac94451Sdhartmei } 51028964e80Sdhartmei if (n->ifname[0]) { 51128964e80Sdhartmei printf("on "); 512870b51d7Schris if (n->ifnot) 513870b51d7Schris printf("! "); 514870b51d7Schris printf("%s ", n->ifname); 51528964e80Sdhartmei } 516032e40b7Sdhartmei if (n->af) { 517032e40b7Sdhartmei if (n->af == AF_INET) 518032e40b7Sdhartmei printf("inet "); 519032e40b7Sdhartmei else 520032e40b7Sdhartmei printf("inet6 "); 521032e40b7Sdhartmei } 52280edb1f0Sdhartmei if (n->proto) { 52380edb1f0Sdhartmei struct protoent *p = getprotobynumber(n->proto); 524ed99c291Sderaadt 525ab745e3bSmpech if (p != NULL) 52680edb1f0Sdhartmei printf("proto %s ", p->p_name); 52780edb1f0Sdhartmei else 52880edb1f0Sdhartmei printf("proto %u ", n->proto); 52980edb1f0Sdhartmei } 53015e76891Sdhartmei print_fromto(&n->src, &n->dst, n->af, n->proto); 531e8793aa9Smcbride if (!n->anchorname[0] && (n->action == PF_NAT)) { 53228964e80Sdhartmei printf("-> "); 533e8793aa9Smcbride print_pool(&n->rpool, n->rpool.proxy_port[0], 534e8793aa9Smcbride n->rpool.proxy_port[1], n->af, PF_NAT); 535f27db9bcSdhartmei } 53614a9b182Skjell printf("\n"); 53714a9b182Skjell } 53814a9b182Skjell 53914a9b182Skjell void 54060927d26Sdhartmei print_binat(struct pf_rule *b, int verbose) 541a3e657d0Sjasoni { 54260927d26Sdhartmei if (verbose) 54360927d26Sdhartmei printf("@%d ", b->nr); 5446ac94451Sdhartmei if (b->anchorname[0]) 5456ac94451Sdhartmei printf("binat-anchor %s ", b->anchorname); 5466ac94451Sdhartmei else { 547e8793aa9Smcbride if (b->action == PF_NOBINAT) 548f27db9bcSdhartmei printf("no "); 549f27db9bcSdhartmei printf("binat "); 5506ac94451Sdhartmei } 551a3e657d0Sjasoni if (b->ifname[0]) { 552a3e657d0Sjasoni printf("on "); 553a3e657d0Sjasoni printf("%s ", b->ifname); 554a3e657d0Sjasoni } 555032e40b7Sdhartmei if (b->af) { 556032e40b7Sdhartmei if (b->af == AF_INET) 557032e40b7Sdhartmei printf("inet "); 558032e40b7Sdhartmei else 559032e40b7Sdhartmei printf("inet6 "); 560032e40b7Sdhartmei } 56180edb1f0Sdhartmei if (b->proto) { 56280edb1f0Sdhartmei struct protoent *p = getprotobynumber(b->proto); 563ed99c291Sderaadt 56480edb1f0Sdhartmei if (p != NULL) 56580edb1f0Sdhartmei printf("proto %s ", p->p_name); 56680edb1f0Sdhartmei else 56780edb1f0Sdhartmei printf("proto %u ", b->proto); 568a3e657d0Sjasoni } 569a3e657d0Sjasoni printf("from "); 570e8793aa9Smcbride if (!PF_AZERO(&b->src.addr.addr, b->af) || 571e8793aa9Smcbride !PF_AZERO(&b->src.addr.mask, b->af)) { 572e8793aa9Smcbride print_addr(&b->src.addr, b->af); 573a3e657d0Sjasoni printf(" "); 5746ac94451Sdhartmei } else 5756ac94451Sdhartmei printf("any "); 576a3e657d0Sjasoni printf("to "); 577e8793aa9Smcbride if (!PF_AZERO(&b->dst.addr.addr, b->af) || 578e8793aa9Smcbride !PF_AZERO(&b->dst.addr.mask, b->af)) { 579e8793aa9Smcbride if (b->dst.not) 580a3e657d0Sjasoni printf("! "); 581e8793aa9Smcbride print_addr(&b->dst.addr, b->af); 582a3e657d0Sjasoni printf(" "); 583a3e657d0Sjasoni } else 584a3e657d0Sjasoni printf("any "); 585e8793aa9Smcbride if (!b->anchorname[0] && (b->action == PF_BINAT)) { 586a3e657d0Sjasoni printf("-> "); 587e8793aa9Smcbride print_pool(&b->rpool, 0, 0, b->af, PF_BINAT); 588f27db9bcSdhartmei } 589a3e657d0Sjasoni printf("\n"); 590a3e657d0Sjasoni } 591a3e657d0Sjasoni 592a3e657d0Sjasoni void 59360927d26Sdhartmei print_rdr(struct pf_rule *r, int verbose) 59414a9b182Skjell { 59560927d26Sdhartmei if (verbose) 59660927d26Sdhartmei printf("@%d ", r->nr); 5976ac94451Sdhartmei if (r->anchorname[0]) 5986ac94451Sdhartmei printf("rdr-anchor %s ", r->anchorname); 5996ac94451Sdhartmei else { 600e8793aa9Smcbride if (r->action == PF_NORDR) 601f27db9bcSdhartmei printf("no "); 602f27db9bcSdhartmei printf("rdr "); 6036ac94451Sdhartmei } 60428964e80Sdhartmei if (r->ifname[0]) { 60528964e80Sdhartmei printf("on "); 606870b51d7Schris if (r->ifnot) 607870b51d7Schris printf("! "); 608870b51d7Schris printf("%s ", r->ifname); 60928964e80Sdhartmei } 610032e40b7Sdhartmei if (r->af) { 611032e40b7Sdhartmei if (r->af == AF_INET) 612032e40b7Sdhartmei printf("inet "); 613032e40b7Sdhartmei else 614032e40b7Sdhartmei printf("inet6 "); 615032e40b7Sdhartmei } 61680edb1f0Sdhartmei if (r->proto) { 61780edb1f0Sdhartmei struct protoent *p = getprotobynumber(r->proto); 618ed99c291Sderaadt 61980edb1f0Sdhartmei if (p != NULL) 62080edb1f0Sdhartmei printf("proto %s ", p->p_name); 62180edb1f0Sdhartmei else 62280edb1f0Sdhartmei printf("proto %u ", r->proto); 623e3d52469Smillert } 62428964e80Sdhartmei printf("from "); 625e8793aa9Smcbride if (!PF_AZERO(&r->src.addr.addr, r->af) || 626e8793aa9Smcbride !PF_AZERO(&r->src.addr.mask, r->af)) { 627e8793aa9Smcbride if (r->src.not) 62828964e80Sdhartmei printf("! "); 629e8793aa9Smcbride print_addr(&r->src.addr, r->af); 63028964e80Sdhartmei printf(" "); 63128964e80Sdhartmei } else 63228964e80Sdhartmei printf("any "); 63328964e80Sdhartmei printf("to "); 634e8793aa9Smcbride if (!PF_AZERO(&r->dst.addr.addr, r->af) || 635e8793aa9Smcbride !PF_AZERO(&r->dst.addr.mask, r->af)) { 636e8793aa9Smcbride if (r->dst.not) 63714a9b182Skjell printf("! "); 638e8793aa9Smcbride print_addr(&r->dst.addr, r->af); 63928964e80Sdhartmei printf(" "); 64028964e80Sdhartmei } else 64128964e80Sdhartmei printf("any "); 642e8793aa9Smcbride if (r->dst.port[0]) { 643e8793aa9Smcbride printf("port %u", ntohs(r->dst.port[0])); 644e8793aa9Smcbride if (r->rpool.port_op & PF_OP_RRG) 645e8793aa9Smcbride printf(":%u", ntohs(r->dst.port[1])); 6460436fa02Smcbride printf(" "); 64780edb1f0Sdhartmei } 648e8793aa9Smcbride if (!r->anchorname[0] && (r->action == PF_RDR)) { 649cb07131dSkjell printf("-> "); 650e8793aa9Smcbride print_pool(&r->rpool, r->rpool.proxy_port[0], 651e8793aa9Smcbride r->rpool.port_op, r->af, PF_RDR); 652f27db9bcSdhartmei } 65314a9b182Skjell printf("\n"); 65414a9b182Skjell } 65514a9b182Skjell 656bca2bf17Sdhartmei char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; 657bca2bf17Sdhartmei char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES; 65899a73934Sderaadt 65914a9b182Skjell void 66081a15e5dSderaadt print_status(struct pf_status *s) 66114a9b182Skjell { 662c474e331Shenning time_t runtime; 66399a73934Sderaadt int i; 664c474e331Shenning char statline[80]; 66599a73934Sderaadt 666c474e331Shenning runtime = time(NULL) - s->since; 667c474e331Shenning 668d85e4ad6Sdhartmei if (s->running) { 669d85e4ad6Sdhartmei unsigned sec, min, hrs, day = runtime; 670d85e4ad6Sdhartmei 671d85e4ad6Sdhartmei sec = day % 60; 672d85e4ad6Sdhartmei day /= 60; 673d85e4ad6Sdhartmei min = day % 60; 674d85e4ad6Sdhartmei day /= 60; 675d85e4ad6Sdhartmei hrs = day % 24; 676d85e4ad6Sdhartmei day /= 24; 677c474e331Shenning snprintf(statline, sizeof(statline), 678d85e4ad6Sdhartmei "Status: Enabled for %u days %.2u:%.2u:%.2u", 679d85e4ad6Sdhartmei day, hrs, min, sec); 680d85e4ad6Sdhartmei } else 681c474e331Shenning snprintf(statline, sizeof(statline), "Status: Disabled"); 682c97b4ee1Shenning printf("%-44s", statline); 683ae58c8acSdhartmei switch (s->debug) { 684ae58c8acSdhartmei case 0: 685c97b4ee1Shenning printf("%15s\n\n", "Debug: None"); 686ae58c8acSdhartmei break; 687ae58c8acSdhartmei case 1: 688c97b4ee1Shenning printf("%15s\n\n", "Debug: Urgent"); 689ae58c8acSdhartmei break; 690ae58c8acSdhartmei case 2: 691c97b4ee1Shenning printf("%15s\n\n", "Debug: Misc"); 692ae58c8acSdhartmei break; 693ae58c8acSdhartmei } 694c474e331Shenning if (s->ifname[0] != 0) { 695c474e331Shenning printf("Interface Stats for %-16s %5s %16s\n", 696c474e331Shenning s->ifname, "IPv4", "IPv6"); 697c474e331Shenning printf(" %-25s %14llu %16llu\n", "Bytes In", 6987189e280Sdhartmei s->bcounters[0][0], s->bcounters[1][0]); 699c474e331Shenning printf(" %-25s %14llu %16llu\n", "Bytes Out", 7007189e280Sdhartmei s->bcounters[0][1], s->bcounters[1][1]); 701c474e331Shenning printf(" Packets In\n"); 702c474e331Shenning printf(" %-23s %14llu %16llu\n", "Passed", 7037189e280Sdhartmei s->pcounters[0][0][PF_PASS], 7047189e280Sdhartmei s->pcounters[1][0][PF_PASS]); 705c474e331Shenning printf(" %-23s %14llu %16llu\n", "Blocked", 7067189e280Sdhartmei s->pcounters[0][0][PF_DROP], 7077189e280Sdhartmei s->pcounters[1][0][PF_DROP]); 708c474e331Shenning printf(" Packets Out\n"); 709c474e331Shenning printf(" %-23s %14llu %16llu\n", "Passed", 7107189e280Sdhartmei s->pcounters[0][1][PF_PASS], 7117189e280Sdhartmei s->pcounters[1][1][PF_PASS]); 712c474e331Shenning printf(" %-23s %14llu %16llu\n\n", "Blocked", 7137189e280Sdhartmei s->pcounters[0][1][PF_DROP], 7147189e280Sdhartmei s->pcounters[1][1][PF_DROP]); 715c474e331Shenning } 716c474e331Shenning printf("%-27s %14s %16s\n", "State Table", "Total", "Rate"); 717c474e331Shenning printf(" %-25s %14u %14s\n", "current entries", s->states, ""); 718c474e331Shenning for (i = 0; i < FCNT_MAX; i++) { 719c474e331Shenning printf(" %-25s %14lld ", pf_fcounters[i], 72084976600Sderaadt s->fcounters[i]); 721c474e331Shenning if (runtime > 0) 722c474e331Shenning printf("%14.1f/s\n", 723c474e331Shenning (double)s->fcounters[i] / (double)runtime); 724c474e331Shenning else 725c474e331Shenning printf("%14s\n", ""); 726c474e331Shenning } 72799a73934Sderaadt printf("Counters\n"); 728c474e331Shenning for (i = 0; i < PFRES_MAX; i++) { 729c474e331Shenning printf(" %-25s %14lld ", pf_reasons[i], 73099a73934Sderaadt s->counters[i]); 731c474e331Shenning if (runtime > 0) 732c474e331Shenning printf("%14.1f/s\n", 733c474e331Shenning (double)s->counters[i] / (double)runtime); 734c474e331Shenning else 735c474e331Shenning printf("%14s\n", ""); 736c474e331Shenning } 73714a9b182Skjell } 73814a9b182Skjell 73914a9b182Skjell void 740e8793aa9Smcbride print_filter(struct pf_rule *r, int verbose) 74114a9b182Skjell { 742cc5f0329Sdhartmei int i, opts; 743cc5f0329Sdhartmei 74474dc4fddShenning if (verbose) 74578baf774Sdhartmei printf("@%d ", r->nr); 7466ac94451Sdhartmei if (r->anchorname[0]) 7476ac94451Sdhartmei printf("anchor %s ", r->anchorname); 7486ac94451Sdhartmei else if (r->action == PF_PASS) 74914a9b182Skjell printf("pass "); 750b996d042Sdhartmei else if (r->action == PF_DROP) { 75114a9b182Skjell printf("block "); 7528a87542aShenning if (r->rule_flag & PFRULE_RETURN) 7538a87542aShenning printf("return "); 7548a87542aShenning else if (r->rule_flag & PFRULE_RETURNRST) { 7551f77cc8aSpb if (!r->return_ttl) 75614a9b182Skjell printf("return-rst "); 7571f77cc8aSpb else 7581f77cc8aSpb printf("return-rst(ttl %d) ", r->return_ttl); 759328b2decShenning } else if (r->rule_flag & PFRULE_RETURNICMP) { 760328b2decShenning const struct icmpcodeent *ic, *ic6; 761b996d042Sdhartmei 762b996d042Sdhartmei ic = geticmpcodebynumber(r->return_icmp >> 8, 763328b2decShenning r->return_icmp & 255, AF_INET); 764328b2decShenning ic6 = geticmpcodebynumber(r->return_icmp6 >> 8, 765328b2decShenning r->return_icmp6 & 255, AF_INET6); 766d14c53d7Swilfried 767328b2decShenning switch(r->af) { 768328b2decShenning case AF_INET: 769328b2decShenning printf("return-icmp"); 770d14c53d7Swilfried if (ic == NULL) 771d14c53d7Swilfried printf("(%u) ", r->return_icmp & 255); 772b996d042Sdhartmei else 773328b2decShenning printf("(%s) ", ic->name); 774328b2decShenning break; 775328b2decShenning case AF_INET6: 776328b2decShenning printf("return-icmp6"); 777328b2decShenning if (ic6 == NULL) 778328b2decShenning printf("(%u) ", r->return_icmp6 & 255); 779328b2decShenning else 780328b2decShenning printf("(%s) ", ic6->name); 781328b2decShenning break; 782328b2decShenning default: 783328b2decShenning printf("return-icmp"); 784328b2decShenning if (ic == NULL) 785328b2decShenning printf("(%u, ", r->return_icmp & 255); 786328b2decShenning else 787328b2decShenning printf("(%s, ", ic->name); 788328b2decShenning if (ic6 == NULL) 789328b2decShenning printf("%u) ", r->return_icmp6 & 255); 790328b2decShenning else 791328b2decShenning printf("%s) ", ic6->name); 792328b2decShenning break; 793328b2decShenning } 794acf2444cShenning } else 795acf2444cShenning printf("drop "); 7966ac94451Sdhartmei } else 797b996d042Sdhartmei printf("scrub "); 7987189e280Sdhartmei if (r->direction == PF_IN) 79914a9b182Skjell printf("in "); 8007189e280Sdhartmei else if (r->direction == PF_OUT) 80114a9b182Skjell printf("out "); 8027242ce7aSdhartmei if (r->log == 1) 80314a9b182Skjell printf("log "); 8047242ce7aSdhartmei else if (r->log == 2) 8057242ce7aSdhartmei printf("log-all "); 80614a9b182Skjell if (r->quick) 80714a9b182Skjell printf("quick "); 8087d0c9138Shenning if (r->ifname[0]) { 8097d0c9138Shenning if (r->ifnot) 8107d0c9138Shenning printf("on ! %s ", r->ifname); 8117d0c9138Shenning else 81214a9b182Skjell printf("on %s ", r->ifname); 8137d0c9138Shenning } 814cb3a4e31Sjasoni if (r->rt) { 815cb3a4e31Sjasoni if (r->rt == PF_ROUTETO) 816cb3a4e31Sjasoni printf("route-to "); 817fa1cdd09Sdhartmei else if (r->rt == PF_REPLYTO) 818fa1cdd09Sdhartmei printf("reply-to "); 819cb3a4e31Sjasoni else if (r->rt == PF_DUPTO) 820cb3a4e31Sjasoni printf("dup-to "); 821cb3a4e31Sjasoni else if (r->rt == PF_FASTROUTE) 822cb3a4e31Sjasoni printf("fastroute "); 823790504a6Sdhartmei if (r->rt != PF_FASTROUTE) { 824e8793aa9Smcbride print_pool(&r->rpool, 0, 0, r->af, PF_PASS); 825790504a6Sdhartmei printf(" "); 826790504a6Sdhartmei } 827cb3a4e31Sjasoni } 82830620b12Sfrantzen if (r->af) { 82930620b12Sfrantzen if (r->af == AF_INET) 83030620b12Sfrantzen printf("inet "); 83130620b12Sfrantzen else 83230620b12Sfrantzen printf("inet6 "); 83330620b12Sfrantzen } 83414a9b182Skjell if (r->proto) { 83514a9b182Skjell struct protoent *p = getprotobynumber(r->proto); 836ed99c291Sderaadt 83714a9b182Skjell if (p != NULL) 83814a9b182Skjell printf("proto %s ", p->p_name); 83914a9b182Skjell else 84014a9b182Skjell printf("proto %u ", r->proto); 84114a9b182Skjell } 84215e76891Sdhartmei print_fromto(&r->src, &r->dst, r->af, r->proto); 843c16ab608Sdhartmei if (r->uid.op) 844c16ab608Sdhartmei print_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], "user"); 845c16ab608Sdhartmei if (r->gid.op) 846c16ab608Sdhartmei print_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], "group"); 84714a9b182Skjell if (r->flags || r->flagset) { 84814a9b182Skjell printf("flags "); 84914a9b182Skjell print_flags(r->flags); 85014a9b182Skjell printf("/"); 85114a9b182Skjell print_flags(r->flagset); 85214a9b182Skjell printf(" "); 85314a9b182Skjell } 854082ebc44Swilfried if (r->type) { 855b49ca6bbShenning const struct icmptypeent *it; 856082ebc44Swilfried 857b49ca6bbShenning it = geticmptypebynumber(r->type-1, r->af); 858d14c53d7Swilfried if (r->af != AF_INET6) 859d14c53d7Swilfried printf("icmp-type"); 860082ebc44Swilfried else 861*d0cb3502Smcbride printf("icmp6-type"); 862b49ca6bbShenning if (it != NULL) 863b49ca6bbShenning printf(" %s ", it->name); 864d14c53d7Swilfried else 865d14c53d7Swilfried printf(" %u ", r->type-1); 866082ebc44Swilfried if (r->code) { 867b49ca6bbShenning const struct icmpcodeent *ic; 868082ebc44Swilfried 869b49ca6bbShenning ic = geticmpcodebynumber(r->type-1, r->code-1, r->af); 870b49ca6bbShenning if (ic != NULL) 871b49ca6bbShenning printf("code %s ", ic->name); 872082ebc44Swilfried else 87314a9b182Skjell printf("code %u ", r->code-1); 874082ebc44Swilfried } 875082ebc44Swilfried } 876e4cbe364Sdhartmei if (r->tos) 877e4cbe364Sdhartmei printf("tos 0x%2.2x ", r->tos); 878b96c47abSfrantzen if (r->keep_state == PF_STATE_NORMAL) 87914a9b182Skjell printf("keep state "); 880b96c47abSfrantzen else if (r->keep_state == PF_STATE_MODULATE) 881b96c47abSfrantzen printf("modulate state "); 882cc5f0329Sdhartmei opts = 0; 883b3c86969Sdhartmei if (r->max_states) 884cc5f0329Sdhartmei opts = 1; 885cc5f0329Sdhartmei for (i = 0; !opts && i < PFTM_MAX; ++i) 886cc5f0329Sdhartmei if (r->timeout[i]) 887cc5f0329Sdhartmei opts = 1; 888cc5f0329Sdhartmei if (opts) { 889cc5f0329Sdhartmei printf("("); 890cc5f0329Sdhartmei if (r->max_states) { 891cc5f0329Sdhartmei printf("max %u", r->max_states); 892cc5f0329Sdhartmei opts = 0; 893cc5f0329Sdhartmei } 894cc5f0329Sdhartmei for (i = 0; i < PFTM_MAX; ++i) 895cc5f0329Sdhartmei if (r->timeout[i]) { 896cc5f0329Sdhartmei if (!opts) 897cc5f0329Sdhartmei printf(", "); 898cc5f0329Sdhartmei opts = 0; 899cc5f0329Sdhartmei printf("%s %u", pf_timeouts[i].name, 900cc5f0329Sdhartmei r->timeout[i]); 901cc5f0329Sdhartmei } 902cc5f0329Sdhartmei printf(") "); 903cc5f0329Sdhartmei } 9046673dee2Sdhartmei if (r->rule_flag & PFRULE_FRAGMENT) 9056673dee2Sdhartmei printf("fragment "); 90667d2a440Sprovos if (r->rule_flag & PFRULE_NODF) 90767d2a440Sprovos printf("no-df "); 908e258bfd4Sprovos if (r->min_ttl) 90934c76dcbSprovos printf("min-ttl %d ", r->min_ttl); 910cfa91859Sjasoni if (r->max_mss) 911cfa91859Sjasoni printf("max-mss %d ", r->max_mss); 912f48d62b3Sdhartmei if (r->allow_opts) 913f48d62b3Sdhartmei printf("allow-opts "); 914b02af636Sfrantzen if (r->action == PF_SCRUB) { 915b02af636Sfrantzen if (r->rule_flag & PFRULE_FRAGDROP) 916b02af636Sfrantzen printf("fragment drop-ovl "); 917b02af636Sfrantzen else if (r->rule_flag & PFRULE_FRAGCROP) 918b02af636Sfrantzen printf("fragment crop "); 919b02af636Sfrantzen else 920b02af636Sfrantzen printf("fragment reassemble "); 921b02af636Sfrantzen } 922455ef0c1Sdhartmei if (r->label[0]) 923455ef0c1Sdhartmei printf("label %s ", r->label); 924f98324c6Shenning if (r->qname[0] && r->pqname[0]) 925f98324c6Shenning printf("queue(%s, %s) ", r->qname, r->pqname); 926f98324c6Shenning else if (r->qname[0]) 92778e1d2a6Shenning printf("queue %s ", r->qname); 92867d2a440Sprovos 92914a9b182Skjell printf("\n"); 93014a9b182Skjell } 93114a9b182Skjell 9321f8f21bdSmillert int 933ff352a37Smarkus parse_flags(char *s) 93414a9b182Skjell { 935ff352a37Smarkus char *p, *q; 93614a9b182Skjell u_int8_t f = 0; 93781a15e5dSderaadt 938ff352a37Smarkus for (p = s; *p; p++) { 939ff352a37Smarkus if ((q = strchr(tcpflags, *p)) == NULL) 940ff352a37Smarkus return -1; 941ff352a37Smarkus else 942ff352a37Smarkus f |= 1 << (q - tcpflags); 94314a9b182Skjell } 944bc795af0Shugh return (f ? f : PF_TH_ALL); 94514a9b182Skjell } 946