1*d85e4ad6Sdhartmei /* $OpenBSD: pfctl_parser.c,v 1.90 2002/06/19 17:44:02 dhartmei 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 * 192d14c53d7Swilfried geticmptypebynumber(u_int8_t type, u_int8_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 * 212d14c53d7Swilfried geticmptypebyname(char *w, u_int8_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 * 232d14c53d7Swilfried geticmpcodebynumber(u_int8_t type, u_int8_t code, u_int8_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 * 254d14c53d7Swilfried geticmpcodebyname(u_long type, char *w, u_int8_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, 35315e76891Sdhartmei u_int8_t af, u_int8_t proto) 35415e76891Sdhartmei { 35515e76891Sdhartmei if (PF_AZERO(&src->addr.addr, AF_INET6) && 35615e76891Sdhartmei PF_AZERO(&src->mask, AF_INET6) && 35715e76891Sdhartmei !src->noroute && !dst->noroute && 35815e76891Sdhartmei !src->port_op && PF_AZERO(&dst->addr.addr, AF_INET6) && 35915e76891Sdhartmei PF_AZERO(&dst->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) && 36615e76891Sdhartmei PF_AZERO(&src->mask, AF_INET6)) 36715e76891Sdhartmei printf("any "); 36815e76891Sdhartmei else { 36915e76891Sdhartmei if (src->not) 37015e76891Sdhartmei printf("! "); 37115e76891Sdhartmei print_addr(&src->addr, &src->mask, 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) && 38315e76891Sdhartmei PF_AZERO(&dst->mask, AF_INET6)) 38415e76891Sdhartmei printf("any "); 38515e76891Sdhartmei else { 38615e76891Sdhartmei if (dst->not) 38715e76891Sdhartmei printf("! "); 38815e76891Sdhartmei print_addr(&dst->addr, &dst->mask, 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 39981a15e5dSderaadt print_nat(struct pf_nat *n) 40014a9b182Skjell { 401f27db9bcSdhartmei if (n->no) 402f27db9bcSdhartmei printf("no "); 403f27db9bcSdhartmei printf("nat "); 40428964e80Sdhartmei if (n->ifname[0]) { 40528964e80Sdhartmei printf("on "); 406870b51d7Schris if (n->ifnot) 407870b51d7Schris printf("! "); 408870b51d7Schris printf("%s ", n->ifname); 40928964e80Sdhartmei } 410032e40b7Sdhartmei if (n->af) { 411032e40b7Sdhartmei if (n->af == AF_INET) 412032e40b7Sdhartmei printf("inet "); 413032e40b7Sdhartmei else 414032e40b7Sdhartmei printf("inet6 "); 415032e40b7Sdhartmei } 41680edb1f0Sdhartmei if (n->proto) { 41780edb1f0Sdhartmei struct protoent *p = getprotobynumber(n->proto); 418ed99c291Sderaadt 419ab745e3bSmpech if (p != NULL) 42080edb1f0Sdhartmei printf("proto %s ", p->p_name); 42180edb1f0Sdhartmei else 42280edb1f0Sdhartmei printf("proto %u ", n->proto); 42380edb1f0Sdhartmei } 42415e76891Sdhartmei print_fromto(&n->src, &n->dst, n->af, n->proto); 425f27db9bcSdhartmei if (!n->no) { 42628964e80Sdhartmei printf("-> "); 42730620b12Sfrantzen print_addr(&n->raddr, NULL, n->af); 428e4b04189Sdhartmei if (n->proxy_port[0] != PF_NAT_PROXY_PORT_LOW || 429e4b04189Sdhartmei n->proxy_port[1] != PF_NAT_PROXY_PORT_HIGH) { 430e4b04189Sdhartmei if (n->proxy_port[0] == n->proxy_port[1]) 431e4b04189Sdhartmei printf(" port %u", n->proxy_port[0]); 432e4b04189Sdhartmei else 433e4b04189Sdhartmei printf(" port %u:%u", n->proxy_port[0], 434e4b04189Sdhartmei n->proxy_port[1]); 435e4b04189Sdhartmei } 436f27db9bcSdhartmei } 43714a9b182Skjell printf("\n"); 43814a9b182Skjell } 43914a9b182Skjell 44014a9b182Skjell void 441a3e657d0Sjasoni print_binat(struct pf_binat *b) 442a3e657d0Sjasoni { 443f27db9bcSdhartmei if (b->no) 444f27db9bcSdhartmei printf("no "); 445f27db9bcSdhartmei printf("binat "); 446a3e657d0Sjasoni if (b->ifname[0]) { 447a3e657d0Sjasoni printf("on "); 448a3e657d0Sjasoni printf("%s ", b->ifname); 449a3e657d0Sjasoni } 450032e40b7Sdhartmei if (b->af) { 451032e40b7Sdhartmei if (b->af == AF_INET) 452032e40b7Sdhartmei printf("inet "); 453032e40b7Sdhartmei else 454032e40b7Sdhartmei printf("inet6 "); 455032e40b7Sdhartmei } 45680edb1f0Sdhartmei if (b->proto) { 45780edb1f0Sdhartmei struct protoent *p = getprotobynumber(b->proto); 458ed99c291Sderaadt 45980edb1f0Sdhartmei if (p != NULL) 46080edb1f0Sdhartmei printf("proto %s ", p->p_name); 46180edb1f0Sdhartmei else 46280edb1f0Sdhartmei printf("proto %u ", b->proto); 463a3e657d0Sjasoni } 464a3e657d0Sjasoni printf("from "); 46530620b12Sfrantzen print_addr(&b->saddr, NULL, b->af); 466a3e657d0Sjasoni printf(" "); 467a3e657d0Sjasoni printf("to "); 468032e40b7Sdhartmei if (!PF_AZERO(&b->daddr.addr, b->af) || !PF_AZERO(&b->dmask, b->af)) { 469a3e657d0Sjasoni if (b->dnot) 470a3e657d0Sjasoni printf("! "); 47130620b12Sfrantzen print_addr(&b->daddr, &b->dmask, b->af); 472a3e657d0Sjasoni printf(" "); 473a3e657d0Sjasoni } else 474a3e657d0Sjasoni printf("any "); 475f27db9bcSdhartmei if (!b->no) { 476a3e657d0Sjasoni printf("-> "); 47730620b12Sfrantzen print_addr(&b->raddr, NULL, b->af); 478f27db9bcSdhartmei } 479a3e657d0Sjasoni printf("\n"); 480a3e657d0Sjasoni } 481a3e657d0Sjasoni 482a3e657d0Sjasoni void 48381a15e5dSderaadt print_rdr(struct pf_rdr *r) 48414a9b182Skjell { 485f27db9bcSdhartmei if (r->no) 486f27db9bcSdhartmei printf("no "); 487f27db9bcSdhartmei printf("rdr "); 48828964e80Sdhartmei if (r->ifname[0]) { 48928964e80Sdhartmei printf("on "); 490870b51d7Schris if (r->ifnot) 491870b51d7Schris printf("! "); 492870b51d7Schris printf("%s ", r->ifname); 49328964e80Sdhartmei } 494032e40b7Sdhartmei if (r->af) { 495032e40b7Sdhartmei if (r->af == AF_INET) 496032e40b7Sdhartmei printf("inet "); 497032e40b7Sdhartmei else 498032e40b7Sdhartmei printf("inet6 "); 499032e40b7Sdhartmei } 50080edb1f0Sdhartmei if (r->proto) { 50180edb1f0Sdhartmei struct protoent *p = getprotobynumber(r->proto); 502ed99c291Sderaadt 50380edb1f0Sdhartmei if (p != NULL) 50480edb1f0Sdhartmei printf("proto %s ", p->p_name); 50580edb1f0Sdhartmei else 50680edb1f0Sdhartmei printf("proto %u ", r->proto); 507e3d52469Smillert } 50828964e80Sdhartmei printf("from "); 509032e40b7Sdhartmei if (!PF_AZERO(&r->saddr.addr, r->af) || !PF_AZERO(&r->smask, r->af)) { 51028964e80Sdhartmei if (r->snot) 51128964e80Sdhartmei printf("! "); 51230620b12Sfrantzen print_addr(&r->saddr, &r->smask, r->af); 51328964e80Sdhartmei printf(" "); 51428964e80Sdhartmei } else 51528964e80Sdhartmei printf("any "); 51628964e80Sdhartmei printf("to "); 517032e40b7Sdhartmei if (!PF_AZERO(&r->daddr.addr, r->af) || !PF_AZERO(&r->dmask, r->af)) { 518e7bd5eebSdhartmei if (r->dnot) 51914a9b182Skjell printf("! "); 52030620b12Sfrantzen print_addr(&r->daddr, &r->dmask, r->af); 52128964e80Sdhartmei printf(" "); 52228964e80Sdhartmei } else 52328964e80Sdhartmei printf("any "); 52480edb1f0Sdhartmei if (r->dport) { 525cb07131dSkjell printf("port %u", ntohs(r->dport)); 526cb07131dSkjell if (r->opts & PF_DPORT_RANGE) 527cb07131dSkjell printf(":%u", ntohs(r->dport2)); 52880edb1f0Sdhartmei } 529f27db9bcSdhartmei if (!r->no) { 530cb07131dSkjell printf(" -> "); 53130620b12Sfrantzen print_addr(&r->raddr, NULL, r->af); 53228964e80Sdhartmei printf(" "); 53380edb1f0Sdhartmei if (r->rport) { 53414a9b182Skjell printf("port %u", ntohs(r->rport)); 535cb07131dSkjell if (r->opts & PF_RPORT_RANGE) 536cb07131dSkjell printf(":*"); 53780edb1f0Sdhartmei } 538f27db9bcSdhartmei } 53914a9b182Skjell printf("\n"); 54014a9b182Skjell } 54114a9b182Skjell 542bca2bf17Sdhartmei char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; 543bca2bf17Sdhartmei char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES; 54499a73934Sderaadt 54514a9b182Skjell void 54681a15e5dSderaadt print_status(struct pf_status *s) 54714a9b182Skjell { 548c474e331Shenning time_t runtime; 54999a73934Sderaadt int i; 550c474e331Shenning char statline[80]; 55199a73934Sderaadt 552c474e331Shenning runtime = time(NULL) - s->since; 553c474e331Shenning 554*d85e4ad6Sdhartmei if (s->running) { 555*d85e4ad6Sdhartmei unsigned sec, min, hrs, day = runtime; 556*d85e4ad6Sdhartmei 557*d85e4ad6Sdhartmei sec = day % 60; 558*d85e4ad6Sdhartmei day /= 60; 559*d85e4ad6Sdhartmei min = day % 60; 560*d85e4ad6Sdhartmei day /= 60; 561*d85e4ad6Sdhartmei hrs = day % 24; 562*d85e4ad6Sdhartmei day /= 24; 563c474e331Shenning snprintf(statline, sizeof(statline), 564*d85e4ad6Sdhartmei "Status: Enabled for %u days %.2u:%.2u:%.2u", 565*d85e4ad6Sdhartmei day, hrs, min, sec); 566*d85e4ad6Sdhartmei } else 567c474e331Shenning snprintf(statline, sizeof(statline), "Status: Disabled"); 568c474e331Shenning printf("%-34s", statline); 569ae58c8acSdhartmei switch (s->debug) { 570ae58c8acSdhartmei case 0: 571c474e331Shenning printf("%25s\n\n", "Debug: None"); 572ae58c8acSdhartmei break; 573ae58c8acSdhartmei case 1: 574c474e331Shenning printf("%25s\n\n", "Debug: Urgent"); 575ae58c8acSdhartmei break; 576ae58c8acSdhartmei case 2: 577c474e331Shenning printf("%25s\n\n", "Debug: Misc"); 578ae58c8acSdhartmei break; 579ae58c8acSdhartmei } 580c474e331Shenning if (s->ifname[0] != 0) { 581c474e331Shenning printf("Interface Stats for %-16s %5s %16s\n", 582c474e331Shenning s->ifname, "IPv4", "IPv6"); 583c474e331Shenning printf(" %-25s %14llu %16llu\n", "Bytes In", 584c474e331Shenning s->bcounters[0][PF_IN], s->bcounters[1][PF_IN]); 585c474e331Shenning printf(" %-25s %14llu %16llu\n", "Bytes Out", 586c474e331Shenning s->bcounters[0][PF_OUT], s->bcounters[1][PF_OUT]); 587c474e331Shenning printf(" Packets In\n"); 588c474e331Shenning printf(" %-23s %14llu %16llu\n", "Passed", 58930620b12Sfrantzen s->pcounters[0][PF_IN][PF_PASS], 590c474e331Shenning s->pcounters[1][PF_IN][PF_PASS]); 591c474e331Shenning printf(" %-23s %14llu %16llu\n", "Blocked", 592c474e331Shenning s->pcounters[0][PF_IN][PF_DROP], 59330620b12Sfrantzen s->pcounters[1][PF_IN][PF_DROP]); 594c474e331Shenning printf(" Packets Out\n"); 595c474e331Shenning printf(" %-23s %14llu %16llu\n", "Passed", 59630620b12Sfrantzen s->pcounters[0][PF_OUT][PF_PASS], 597c474e331Shenning s->pcounters[1][PF_OUT][PF_PASS]); 598c474e331Shenning printf(" %-23s %14llu %16llu\n\n", "Blocked", 599c474e331Shenning s->pcounters[0][PF_OUT][PF_DROP], 60030620b12Sfrantzen s->pcounters[1][PF_OUT][PF_DROP]); 601c474e331Shenning } 602c474e331Shenning printf("%-27s %14s %16s\n", "State Table", "Total", "Rate"); 603c474e331Shenning printf(" %-25s %14u %14s\n", "current entries", s->states, ""); 604c474e331Shenning for (i = 0; i < FCNT_MAX; i++) { 605c474e331Shenning printf(" %-25s %14lld ", pf_fcounters[i], 60684976600Sderaadt s->fcounters[i]); 607c474e331Shenning if (runtime > 0) 608c474e331Shenning printf("%14.1f/s\n", 609c474e331Shenning (double)s->fcounters[i] / (double)runtime); 610c474e331Shenning else 611c474e331Shenning printf("%14s\n", ""); 612c474e331Shenning } 61399a73934Sderaadt printf("Counters\n"); 614c474e331Shenning for (i = 0; i < PFRES_MAX; i++) { 615c474e331Shenning printf(" %-25s %14lld ", pf_reasons[i], 61699a73934Sderaadt s->counters[i]); 617c474e331Shenning if (runtime > 0) 618c474e331Shenning printf("%14.1f/s\n", 619c474e331Shenning (double)s->counters[i] / (double)runtime); 620c474e331Shenning else 621c474e331Shenning printf("%14s\n", ""); 622c474e331Shenning } 62314a9b182Skjell } 62414a9b182Skjell 62514a9b182Skjell void 62681a15e5dSderaadt print_rule(struct pf_rule *r) 62714a9b182Skjell { 628cc5f0329Sdhartmei int i, opts; 629cc5f0329Sdhartmei 63078baf774Sdhartmei printf("@%d ", r->nr); 6318418a02fSprovos if (r->action == PF_PASS) 63214a9b182Skjell printf("pass "); 633b996d042Sdhartmei else if (r->action == PF_DROP) { 63414a9b182Skjell printf("block "); 6351f77cc8aSpb if (r->rule_flag & PFRULE_RETURNRST) { 6361f77cc8aSpb if (!r->return_ttl) 63714a9b182Skjell printf("return-rst "); 6381f77cc8aSpb else 6391f77cc8aSpb printf("return-rst(ttl %d) ", r->return_ttl); 6401f77cc8aSpb } else if (r->return_icmp) { 6417d27d81aSdhartmei const struct icmpcodeent *ic; 642b996d042Sdhartmei 643d14c53d7Swilfried if (r->af != AF_INET6) 644b996d042Sdhartmei printf("return-icmp"); 645d14c53d7Swilfried else 646d14c53d7Swilfried printf("return-icmp6"); 647b996d042Sdhartmei ic = geticmpcodebynumber(r->return_icmp >> 8, 648d14c53d7Swilfried r->return_icmp & 255, r->af); 649d14c53d7Swilfried 650d14c53d7Swilfried if (ic == NULL) 651d14c53d7Swilfried printf("(%u) ", r->return_icmp & 255); 6520eed2997Sdhartmei else if ((r->af != AF_INET6 && ic->code != 6530eed2997Sdhartmei ICMP_UNREACH_PORT) || 6540eed2997Sdhartmei (r->af == AF_INET6 && ic->code != 6550eed2997Sdhartmei ICMP6_DST_UNREACH_NOPORT)) 656b996d042Sdhartmei printf("(%s) ", ic->name); 657b996d042Sdhartmei else 658b996d042Sdhartmei printf(" "); 659b996d042Sdhartmei } 660cc42ff11Sfrantzen } else { 661b996d042Sdhartmei printf("scrub "); 662cc42ff11Sfrantzen } 66314a9b182Skjell if (r->direction == 0) 66414a9b182Skjell printf("in "); 66514a9b182Skjell else 66614a9b182Skjell printf("out "); 6677242ce7aSdhartmei if (r->log == 1) 66814a9b182Skjell printf("log "); 6697242ce7aSdhartmei else if (r->log == 2) 6707242ce7aSdhartmei printf("log-all "); 67114a9b182Skjell if (r->quick) 67214a9b182Skjell printf("quick "); 67314a9b182Skjell if (r->ifname[0]) 67414a9b182Skjell printf("on %s ", r->ifname); 675cb3a4e31Sjasoni if (r->rt) { 676cb3a4e31Sjasoni if (r->rt == PF_ROUTETO) 677cb3a4e31Sjasoni printf("route-to "); 678cb3a4e31Sjasoni else if (r->rt == PF_DUPTO) 679cb3a4e31Sjasoni printf("dup-to "); 680cb3a4e31Sjasoni else if (r->rt == PF_FASTROUTE) 681cb3a4e31Sjasoni printf("fastroute"); 682cb3a4e31Sjasoni if (r->rt_ifname[0]) 683cb3a4e31Sjasoni printf("%s", r->rt_ifname); 684cb3a4e31Sjasoni if (r->af && !PF_AZERO(&r->rt_addr, r->af)) { 685032e40b7Sdhartmei struct pf_addr_wrap aw; 686032e40b7Sdhartmei 687032e40b7Sdhartmei aw.addr = r->rt_addr; 688032e40b7Sdhartmei aw.addr_dyn = NULL; 689cb3a4e31Sjasoni printf(":"); 690032e40b7Sdhartmei print_addr(&aw, NULL, r->af); 691cb3a4e31Sjasoni } 692cb3a4e31Sjasoni printf(" "); 693cb3a4e31Sjasoni } 69430620b12Sfrantzen if (r->af) { 69530620b12Sfrantzen if (r->af == AF_INET) 69630620b12Sfrantzen printf("inet "); 69730620b12Sfrantzen else 69830620b12Sfrantzen printf("inet6 "); 69930620b12Sfrantzen } 70014a9b182Skjell if (r->proto) { 70114a9b182Skjell struct protoent *p = getprotobynumber(r->proto); 702ed99c291Sderaadt 70314a9b182Skjell if (p != NULL) 70414a9b182Skjell printf("proto %s ", p->p_name); 70514a9b182Skjell else 70614a9b182Skjell printf("proto %u ", r->proto); 70714a9b182Skjell } 70815e76891Sdhartmei print_fromto(&r->src, &r->dst, r->af, r->proto); 709c16ab608Sdhartmei if (r->uid.op) 710c16ab608Sdhartmei print_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], "user"); 711c16ab608Sdhartmei if (r->gid.op) 712c16ab608Sdhartmei print_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], "group"); 71314a9b182Skjell if (r->flags || r->flagset) { 71414a9b182Skjell printf("flags "); 71514a9b182Skjell print_flags(r->flags); 71614a9b182Skjell printf("/"); 71714a9b182Skjell print_flags(r->flagset); 71814a9b182Skjell printf(" "); 71914a9b182Skjell } 720082ebc44Swilfried if (r->type) { 7217d27d81aSdhartmei const struct icmptypeent *p; 722082ebc44Swilfried 723d14c53d7Swilfried p = geticmptypebynumber(r->type-1, r->af); 724d14c53d7Swilfried if (r->af != AF_INET6) 725d14c53d7Swilfried printf("icmp-type"); 726082ebc44Swilfried else 727d14c53d7Swilfried printf("ipv6-icmp-type"); 728d14c53d7Swilfried if (p != NULL) 729d14c53d7Swilfried printf(" %s ", p->name); 730d14c53d7Swilfried else 731d14c53d7Swilfried printf(" %u ", r->type-1); 732082ebc44Swilfried if (r->code) { 7337d27d81aSdhartmei const struct icmpcodeent *p; 734082ebc44Swilfried 735d14c53d7Swilfried p = geticmpcodebynumber(r->type-1, r->code-1, r->af); 736082ebc44Swilfried if (p != NULL) 737082ebc44Swilfried printf("code %s ", p->name); 738082ebc44Swilfried else 73914a9b182Skjell printf("code %u ", r->code-1); 740082ebc44Swilfried } 741082ebc44Swilfried } 742b96c47abSfrantzen if (r->keep_state == PF_STATE_NORMAL) 74314a9b182Skjell printf("keep state "); 744b96c47abSfrantzen else if (r->keep_state == PF_STATE_MODULATE) 745b96c47abSfrantzen printf("modulate state "); 746cc5f0329Sdhartmei opts = 0; 747b3c86969Sdhartmei if (r->max_states) 748cc5f0329Sdhartmei opts = 1; 749cc5f0329Sdhartmei for (i = 0; !opts && i < PFTM_MAX; ++i) 750cc5f0329Sdhartmei if (r->timeout[i]) 751cc5f0329Sdhartmei opts = 1; 752cc5f0329Sdhartmei if (opts) { 753cc5f0329Sdhartmei printf("("); 754cc5f0329Sdhartmei if (r->max_states) { 755cc5f0329Sdhartmei printf("max %u", r->max_states); 756cc5f0329Sdhartmei opts = 0; 757cc5f0329Sdhartmei } 758cc5f0329Sdhartmei for (i = 0; i < PFTM_MAX; ++i) 759cc5f0329Sdhartmei if (r->timeout[i]) { 760cc5f0329Sdhartmei if (!opts) 761cc5f0329Sdhartmei printf(", "); 762cc5f0329Sdhartmei opts = 0; 763cc5f0329Sdhartmei printf("%s %u", pf_timeouts[i].name, 764cc5f0329Sdhartmei r->timeout[i]); 765cc5f0329Sdhartmei } 766cc5f0329Sdhartmei printf(") "); 767cc5f0329Sdhartmei } 7686673dee2Sdhartmei if (r->rule_flag & PFRULE_FRAGMENT) 7696673dee2Sdhartmei printf("fragment "); 77067d2a440Sprovos if (r->rule_flag & PFRULE_NODF) 77167d2a440Sprovos printf("no-df "); 772e258bfd4Sprovos if (r->min_ttl) 77334c76dcbSprovos printf("min-ttl %d ", r->min_ttl); 774cfa91859Sjasoni if (r->max_mss) 775cfa91859Sjasoni printf("max-mss %d ", r->max_mss); 776f48d62b3Sdhartmei if (r->allow_opts) 777f48d62b3Sdhartmei printf("allow-opts "); 778b02af636Sfrantzen if (r->action == PF_SCRUB) { 779b02af636Sfrantzen if (r->rule_flag & PFRULE_FRAGDROP) 780b02af636Sfrantzen printf("fragment drop-ovl "); 781b02af636Sfrantzen else if (r->rule_flag & PFRULE_FRAGCROP) 782b02af636Sfrantzen printf("fragment crop "); 783b02af636Sfrantzen else 784b02af636Sfrantzen printf("fragment reassemble "); 785b02af636Sfrantzen } 786455ef0c1Sdhartmei if (r->label[0]) 787455ef0c1Sdhartmei printf("label %s", r->label); 78867d2a440Sprovos 78914a9b182Skjell printf("\n"); 79014a9b182Skjell } 79114a9b182Skjell 7921f8f21bdSmillert int 793ff352a37Smarkus parse_flags(char *s) 79414a9b182Skjell { 795ff352a37Smarkus char *p, *q; 79614a9b182Skjell u_int8_t f = 0; 79781a15e5dSderaadt 798ff352a37Smarkus for (p = s; *p; p++) { 799ff352a37Smarkus if ((q = strchr(tcpflags, *p)) == NULL) 800ff352a37Smarkus return -1; 801ff352a37Smarkus else 802ff352a37Smarkus f |= 1 << (q - tcpflags); 80314a9b182Skjell } 804bc795af0Shugh return (f ? f : PF_TH_ALL); 80514a9b182Skjell } 806