1*ff352a37Smarkus /* $OpenBSD: pfctl_parser.c,v 1.35 2001/07/16 21:09:38 markus Exp $ */ 214a9b182Skjell 314a9b182Skjell /* 414a9b182Skjell * 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> 40252d784aSderaadt #include <net/pfvar.h> 419f13c6caSmillert #include <arpa/inet.h> 42252d784aSderaadt 4314a9b182Skjell #include <stdio.h> 4414a9b182Skjell #include <stdlib.h> 4514a9b182Skjell #include <string.h> 4614a9b182Skjell #include <ctype.h> 4714a9b182Skjell #include <netdb.h> 486329fa59Sderaadt #include <stdarg.h> 496329fa59Sderaadt #include <errno.h> 50*ff352a37Smarkus #include <err.h> 5114a9b182Skjell 5214a9b182Skjell #include "pfctl_parser.h" 5314a9b182Skjell 5481a15e5dSderaadt void print_addr (u_int32_t); 556d5ce0fbSderaadt void print_host (struct pf_state_host *); 566d5ce0fbSderaadt void print_seq (struct pf_state_peer *); 5781a15e5dSderaadt void print_port (u_int8_t, u_int16_t, u_int16_t, char *); 5881a15e5dSderaadt void print_flags (u_int8_t); 5914a9b182Skjell 6081a15e5dSderaadt char *tcpflags = "FSRPAU"; 6114a9b182Skjell 62082ebc44Swilfried struct icmptypeent icmp_type[] = { 63082ebc44Swilfried { "echoreq", ICMP_ECHO }, 64082ebc44Swilfried { "echorep", ICMP_ECHOREPLY }, 65082ebc44Swilfried { "unreach", ICMP_UNREACH }, 66082ebc44Swilfried { "squench", ICMP_SOURCEQUENCH }, 67082ebc44Swilfried { "redir", ICMP_REDIRECT }, 68082ebc44Swilfried { "althost", ICMP_ALTHOSTADDR }, 69082ebc44Swilfried { "routeradv", ICMP_ROUTERADVERT }, 70082ebc44Swilfried { "routersol", ICMP_ROUTERSOLICIT }, 71082ebc44Swilfried { "timex", ICMP_TIMXCEED }, 72082ebc44Swilfried { "paramprob", ICMP_PARAMPROB }, 73082ebc44Swilfried { "timereq", ICMP_TSTAMP }, 74082ebc44Swilfried { "timerep", ICMP_TSTAMPREPLY }, 75082ebc44Swilfried { "inforeq", ICMP_IREQ }, 76082ebc44Swilfried { "inforep", ICMP_IREQREPLY }, 77082ebc44Swilfried { "maskreq", ICMP_MASKREQ }, 7802cbcc9eSwilfried { "maskrep", ICMP_MASKREPLY }, 7902cbcc9eSwilfried { "trace", ICMP_TRACEROUTE }, 8002cbcc9eSwilfried { "dataconv", ICMP_DATACONVERR }, 8102cbcc9eSwilfried { "mobredir", ICMP_MOBILE_REDIRECT }, 8202cbcc9eSwilfried { "ipv6-where", ICMP_IPV6_WHEREAREYOU }, 8302cbcc9eSwilfried { "ipv6-here", ICMP_IPV6_IAMHERE }, 8402cbcc9eSwilfried { "mobregreq", ICMP_MOBILE_REGREQUEST }, 8502cbcc9eSwilfried { "mobregrep", ICMP_MOBILE_REGREPLY }, 8602cbcc9eSwilfried { "skip", ICMP_SKIP }, 8702cbcc9eSwilfried { "photuris", ICMP_PHOTURIS } 8802cbcc9eSwilfried 89082ebc44Swilfried }; 90082ebc44Swilfried 91082ebc44Swilfried struct icmpcodeent icmp_code[] = { 92082ebc44Swilfried { "net-unr", ICMP_UNREACH, ICMP_UNREACH_NET }, 93082ebc44Swilfried { "host-unr", ICMP_UNREACH, ICMP_UNREACH_HOST }, 94082ebc44Swilfried { "proto-unr", ICMP_UNREACH, ICMP_UNREACH_PROTOCOL }, 95082ebc44Swilfried { "port-unr", ICMP_UNREACH, ICMP_UNREACH_PORT }, 96082ebc44Swilfried { "needfrag", ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG }, 97082ebc44Swilfried { "srcfail", ICMP_UNREACH, ICMP_UNREACH_SRCFAIL }, 98082ebc44Swilfried { "net-unk", ICMP_UNREACH, ICMP_UNREACH_NET_UNKNOWN }, 99082ebc44Swilfried { "host-unk", ICMP_UNREACH, ICMP_UNREACH_HOST_UNKNOWN }, 100082ebc44Swilfried { "isolate", ICMP_UNREACH, ICMP_UNREACH_ISOLATED }, 101082ebc44Swilfried { "net-prohib", ICMP_UNREACH, ICMP_UNREACH_NET_PROHIB }, 102082ebc44Swilfried { "host-prohib", ICMP_UNREACH, ICMP_UNREACH_HOST_PROHIB }, 103082ebc44Swilfried { "net-tos", ICMP_UNREACH, ICMP_UNREACH_TOSNET }, 104082ebc44Swilfried { "host-tos", ICMP_UNREACH, ICMP_UNREACH_TOSHOST }, 105082ebc44Swilfried { "filter-prohib", ICMP_UNREACH, ICMP_UNREACH_FILTER_PROHIB }, 106082ebc44Swilfried { "host-preced", ICMP_UNREACH, ICMP_UNREACH_HOST_PRECEDENCE }, 107082ebc44Swilfried { "cutoff-preced", ICMP_UNREACH, ICMP_UNREACH_PRECEDENCE_CUTOFF }, 108082ebc44Swilfried { "redir-net", ICMP_REDIRECT, ICMP_REDIRECT_NET }, 109082ebc44Swilfried { "redir-host", ICMP_REDIRECT, ICMP_REDIRECT_HOST }, 110082ebc44Swilfried { "redir-tos-net", ICMP_REDIRECT, ICMP_REDIRECT_TOSNET }, 111082ebc44Swilfried { "redir-tos-host", ICMP_REDIRECT, ICMP_REDIRECT_TOSHOST }, 11202cbcc9eSwilfried { "normal-adv", ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NORMAL }, 11302cbcc9eSwilfried { "common-adv", ICMP_ROUTERADVERT, ICMP_ROUTERADVERT_NOROUTE_COMMON }, 114082ebc44Swilfried { "transit", ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS }, 115082ebc44Swilfried { "reassemb", ICMP_TIMXCEED, ICMP_TIMXCEED_REASS }, 116082ebc44Swilfried { "badhead", ICMP_PARAMPROB, ICMP_PARAMPROB_ERRATPTR }, 117082ebc44Swilfried { "optmiss", ICMP_PARAMPROB, ICMP_PARAMPROB_OPTABSENT }, 11802cbcc9eSwilfried { "badlen", ICMP_PARAMPROB, ICMP_PARAMPROB_LENGTH }, 11902cbcc9eSwilfried { "unknown-ind", ICMP_PHOTURIS, ICMP_PHOTURIS_UNKNOWN_INDEX }, 12002cbcc9eSwilfried { "auth-fail", ICMP_PHOTURIS, ICMP_PHOTURIS_AUTH_FAILED }, 12102cbcc9eSwilfried { "decrypt-fail", ICMP_PHOTURIS, ICMP_PHOTURIS_DECRYPT_FAILED } 122082ebc44Swilfried }; 123082ebc44Swilfried 124082ebc44Swilfried struct icmptypeent * 125082ebc44Swilfried geticmptypebynumber(u_int8_t type) 126082ebc44Swilfried { 127d77ee430Sdhartmei unsigned i; 128082ebc44Swilfried 129082ebc44Swilfried for(i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); i++) { 130082ebc44Swilfried if(type == icmp_type[i].type) 131082ebc44Swilfried return (&icmp_type[i]); 132082ebc44Swilfried } 133082ebc44Swilfried return (0); 134082ebc44Swilfried } 135082ebc44Swilfried 136082ebc44Swilfried struct icmptypeent * 137082ebc44Swilfried geticmptypebyname(char *w) 138082ebc44Swilfried { 139d77ee430Sdhartmei unsigned i; 140082ebc44Swilfried 141082ebc44Swilfried for(i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); i++) { 142082ebc44Swilfried if(!strcmp(w, icmp_type[i].name)) 143082ebc44Swilfried return (&icmp_type[i]); 144082ebc44Swilfried } 145082ebc44Swilfried return (0); 146082ebc44Swilfried } 147082ebc44Swilfried 148082ebc44Swilfried struct icmpcodeent * 149082ebc44Swilfried geticmpcodebynumber(u_int8_t type, u_int8_t code) 150082ebc44Swilfried { 151d77ee430Sdhartmei unsigned i; 152082ebc44Swilfried 153082ebc44Swilfried for(i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); i++) { 154082ebc44Swilfried if (type == icmp_code[i].type && code == icmp_code[i].code) 155082ebc44Swilfried return (&icmp_code[i]); 156082ebc44Swilfried } 157082ebc44Swilfried return (0); 158082ebc44Swilfried } 159082ebc44Swilfried 160082ebc44Swilfried struct icmpcodeent * 161082ebc44Swilfried geticmpcodebyname(u_long type, char *w) 162082ebc44Swilfried { 163d77ee430Sdhartmei unsigned i; 164082ebc44Swilfried 165082ebc44Swilfried for(i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); i++) { 166082ebc44Swilfried if (type == icmp_code[i].type && !strcmp(w, icmp_code[i].name)) 167082ebc44Swilfried return (&icmp_code[i]); 168082ebc44Swilfried } 169082ebc44Swilfried return (0); 170082ebc44Swilfried } 171082ebc44Swilfried 17281a15e5dSderaadt void 17314a9b182Skjell print_addr(u_int32_t a) 17414a9b182Skjell { 17514a9b182Skjell a = ntohl(a); 17614a9b182Skjell printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255, (a>>8)&255, a&255); 17714a9b182Skjell } 17814a9b182Skjell 17981a15e5dSderaadt void 1806d5ce0fbSderaadt print_host(struct pf_state_host *h) 18114a9b182Skjell { 18214a9b182Skjell u_int32_t a = ntohl(h->addr); 18314a9b182Skjell u_int16_t p = ntohs(h->port); 18481a15e5dSderaadt 18514a9b182Skjell printf("%u.%u.%u.%u:%u", (a>>24)&255, (a>>16)&255, (a>>8)&255, a&255, p); 18614a9b182Skjell } 18714a9b182Skjell 18881a15e5dSderaadt void 1896d5ce0fbSderaadt print_seq(struct pf_state_peer *p) 19014a9b182Skjell { 19114a9b182Skjell printf("[%u + %u]", p->seqlo, p->seqhi - p->seqlo); 19214a9b182Skjell } 19314a9b182Skjell 19481a15e5dSderaadt void 19514a9b182Skjell print_port(u_int8_t op, u_int16_t p1, u_int16_t p2, char *proto) 19614a9b182Skjell { 19714a9b182Skjell struct servent *s = getservbyport(p1, proto); 19881a15e5dSderaadt 19914a9b182Skjell p1 = ntohs(p1); 20014a9b182Skjell p2 = ntohs(p2); 20114a9b182Skjell printf("port "); 202e2baa6deSdugsong if (op == PF_OP_GL) 20314a9b182Skjell printf("%u >< %u ", p1, p2); 204e2baa6deSdugsong else if (op == PF_OP_EQ) { 20514a9b182Skjell if (s != NULL) 20614a9b182Skjell printf("= %s ", s->s_name); 20714a9b182Skjell else 20814a9b182Skjell printf("= %u ", p1); 209e2baa6deSdugsong } else if (op == PF_OP_NE) { 21014a9b182Skjell if (s != NULL) 21114a9b182Skjell printf("!= %s ", s->s_name); 21214a9b182Skjell else 21314a9b182Skjell printf("!= %u ", p1); 214e2baa6deSdugsong } else if (op == PF_OP_LT) 21514a9b182Skjell printf("< %u ", p1); 216e2baa6deSdugsong else if (op == PF_OP_LE) 21714a9b182Skjell printf("<= %u ", p1); 218e2baa6deSdugsong else if (op == PF_OP_GT) 21914a9b182Skjell printf("> %u ", p1); 220e2baa6deSdugsong else if (op == PF_OP_GE) 22114a9b182Skjell printf(">= %u ", p1); 22214a9b182Skjell } 22314a9b182Skjell 22481a15e5dSderaadt void 22514a9b182Skjell print_flags(u_int8_t f) 22614a9b182Skjell { 22714a9b182Skjell int i; 22881a15e5dSderaadt 22914a9b182Skjell for (i = 0; i < 6; ++i) 23014a9b182Skjell if (f & (1 << i)) 23114a9b182Skjell printf("%c", tcpflags[i]); 23214a9b182Skjell } 23314a9b182Skjell 23414a9b182Skjell void 23581a15e5dSderaadt print_nat(struct pf_nat *n) 23614a9b182Skjell { 237870b51d7Schris printf("nat "); 23828964e80Sdhartmei if (n->ifname[0]) { 23928964e80Sdhartmei printf("on "); 240870b51d7Schris if (n->ifnot) 241870b51d7Schris printf("! "); 242870b51d7Schris printf("%s ", n->ifname); 24328964e80Sdhartmei } 24428964e80Sdhartmei printf("from "); 24528964e80Sdhartmei if (n->saddr || n->smask) { 24628964e80Sdhartmei if (n->snot) 24714a9b182Skjell printf("! "); 24814a9b182Skjell print_addr(n->saddr); 24914a9b182Skjell if (n->smask != 0xFFFFFFFF) { 25014a9b182Skjell printf("/"); 25114a9b182Skjell print_addr(n->smask); 25214a9b182Skjell } 25328964e80Sdhartmei printf(" "); 25428964e80Sdhartmei } else 25528964e80Sdhartmei printf("any "); 25628964e80Sdhartmei printf("to "); 25728964e80Sdhartmei if (n->daddr || n->dmask) { 25828964e80Sdhartmei if (n->dnot) 25928964e80Sdhartmei printf("! "); 26014a9b182Skjell print_addr(n->daddr); 26128964e80Sdhartmei if (n->dmask != 0xFFFFFFFF) { 26228964e80Sdhartmei printf("/"); 26328964e80Sdhartmei print_addr(n->dmask); 26428964e80Sdhartmei } 26528964e80Sdhartmei printf(" "); 26628964e80Sdhartmei } else 26728964e80Sdhartmei printf("any "); 26828964e80Sdhartmei printf("-> "); 26928964e80Sdhartmei print_addr(n->raddr); 27028964e80Sdhartmei printf(" "); 27114a9b182Skjell switch (n->proto) { 27214a9b182Skjell case IPPROTO_TCP: 27314a9b182Skjell printf("proto tcp"); 27414a9b182Skjell break; 27514a9b182Skjell case IPPROTO_UDP: 27614a9b182Skjell printf("proto udp"); 27714a9b182Skjell break; 27814a9b182Skjell case IPPROTO_ICMP: 27914a9b182Skjell printf("proto icmp"); 28014a9b182Skjell break; 28114a9b182Skjell } 28214a9b182Skjell printf("\n"); 28314a9b182Skjell } 28414a9b182Skjell 28514a9b182Skjell void 28681a15e5dSderaadt print_rdr(struct pf_rdr *r) 28714a9b182Skjell { 288870b51d7Schris printf("rdr "); 28928964e80Sdhartmei if (r->ifname[0]) { 29028964e80Sdhartmei printf("on "); 291870b51d7Schris if (r->ifnot) 292870b51d7Schris printf("! "); 293870b51d7Schris printf("%s ", r->ifname); 29428964e80Sdhartmei } 295e3d52469Smillert switch (r->proto) { 296e3d52469Smillert case IPPROTO_TCP: 297e3d52469Smillert printf("proto tcp "); 298e3d52469Smillert break; 299e3d52469Smillert case IPPROTO_UDP: 300e3d52469Smillert printf("proto udp "); 301e3d52469Smillert break; 302e3d52469Smillert } 30328964e80Sdhartmei printf("from "); 30428964e80Sdhartmei if (r->saddr || r->smask) { 30528964e80Sdhartmei if (r->snot) 30628964e80Sdhartmei printf("! "); 30728964e80Sdhartmei print_addr(r->saddr); 30828964e80Sdhartmei if (r->smask != 0xFFFFFFFF) { 30928964e80Sdhartmei printf("/"); 31028964e80Sdhartmei print_addr(r->smask); 31128964e80Sdhartmei } 31228964e80Sdhartmei printf(" "); 31328964e80Sdhartmei } else 31428964e80Sdhartmei printf("any "); 31528964e80Sdhartmei printf("to "); 31628964e80Sdhartmei if (r->daddr || r->dmask) { 31728964e80Sdhartmei if (r->dnot) 31814a9b182Skjell printf("! "); 31914a9b182Skjell print_addr(r->daddr); 32014a9b182Skjell if (r->dmask != 0xFFFFFFFF) { 32114a9b182Skjell printf("/"); 32214a9b182Skjell print_addr(r->dmask); 32314a9b182Skjell } 32428964e80Sdhartmei printf(" "); 32528964e80Sdhartmei } else 32628964e80Sdhartmei printf("any "); 327cb07131dSkjell printf("port %u", ntohs(r->dport)); 328cb07131dSkjell if (r->opts & PF_DPORT_RANGE) 329cb07131dSkjell printf(":%u", ntohs(r->dport2)); 330cb07131dSkjell printf(" -> "); 33114a9b182Skjell print_addr(r->raddr); 33228964e80Sdhartmei printf(" "); 33314a9b182Skjell printf("port %u", ntohs(r->rport)); 334cb07131dSkjell if (r->opts & PF_RPORT_RANGE) 335cb07131dSkjell printf(":*"); 33614a9b182Skjell printf("\n"); 33714a9b182Skjell } 33814a9b182Skjell 339bca2bf17Sdhartmei char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES; 340bca2bf17Sdhartmei char *pf_fcounters[FCNT_MAX+1] = FCNT_NAMES; 34199a73934Sderaadt 34214a9b182Skjell void 34381a15e5dSderaadt print_status(struct pf_status *s) 34414a9b182Skjell { 34581a15e5dSderaadt 34699a73934Sderaadt time_t t = time(NULL); 34799a73934Sderaadt int i; 34899a73934Sderaadt 3497f08579dSkjell printf("Status: %s Time: %u Since: %u\n", 3507f08579dSkjell s->running ? "Enabled" : "Disabled", 3517f08579dSkjell t, s->since); 352184bf464Sderaadt printf("Bytes In: %-10llu Bytes Out: %-10llu\n", 35384976600Sderaadt s->bcounters[PF_IN], s->bcounters[PF_OUT]); 354184bf464Sderaadt printf("Inbound Packets: Passed: %-10llu Dropped: %-10llu\n", 3559de5da5eSdhartmei s->pcounters[PF_IN][PF_PASS], 35684976600Sderaadt s->pcounters[PF_IN][PF_DROP]); 357184bf464Sderaadt printf("Outbound Packets: Passed: %-10llu Dropped: %-10llu\n", 35884976600Sderaadt s->pcounters[PF_OUT][PF_PASS], 35984976600Sderaadt s->pcounters[PF_OUT][PF_DROP]); 36084976600Sderaadt printf("States: %u\n", s->states); 36184976600Sderaadt printf("pf Counters\n"); 362bca2bf17Sdhartmei for (i = 0; i < FCNT_MAX; i++) 363184bf464Sderaadt printf("%-25s %-8lld\n", pf_fcounters[i], 36484976600Sderaadt s->fcounters[i]); 36599a73934Sderaadt printf("Counters\n"); 36699a73934Sderaadt for (i = 0; i < PFRES_MAX; i++) 367184bf464Sderaadt printf("%-25s %-8lld\n", pf_reasons[i], 36899a73934Sderaadt s->counters[i]); 36914a9b182Skjell } 37014a9b182Skjell 37114a9b182Skjell void 37281a15e5dSderaadt print_state(struct pf_state *s) 37314a9b182Skjell { 3746d5ce0fbSderaadt struct pf_state_peer *src, *dst; 37514a9b182Skjell u_int8_t hrs, min, sec; 376252d784aSderaadt 37714a9b182Skjell if (s->direction == PF_OUT) { 37814a9b182Skjell src = &s->src; 37914a9b182Skjell dst = &s->dst; 38014a9b182Skjell } else { 38114a9b182Skjell src = &s->dst; 38214a9b182Skjell dst = &s->src; 38314a9b182Skjell } 38414a9b182Skjell switch (s->proto) { 38514a9b182Skjell case IPPROTO_TCP: 38614a9b182Skjell printf("TCP "); 38714a9b182Skjell break; 38814a9b182Skjell case IPPROTO_UDP: 38914a9b182Skjell printf("UDP "); 39014a9b182Skjell break; 39114a9b182Skjell case IPPROTO_ICMP: 39214a9b182Skjell printf("ICMP "); 39314a9b182Skjell break; 39414a9b182Skjell default: 39514a9b182Skjell printf("???? "); 39614a9b182Skjell break; 39714a9b182Skjell } 39814a9b182Skjell if ((s->lan.addr != s->gwy.addr) || (s->lan.port != s->gwy.port)) { 39914a9b182Skjell print_host(&s->lan); 40014a9b182Skjell if (s->direction == PF_OUT) 40114a9b182Skjell printf(" -> "); 40214a9b182Skjell else 40314a9b182Skjell printf(" <- "); 40414a9b182Skjell } 40514a9b182Skjell print_host(&s->gwy); 40614a9b182Skjell if (s->direction == PF_OUT) 40714a9b182Skjell printf(" -> "); 40814a9b182Skjell else 40914a9b182Skjell printf(" <- "); 41014a9b182Skjell print_host(&s->ext); 41114a9b182Skjell printf("\n"); 41214a9b182Skjell 41314a9b182Skjell printf("%u:%u ", src->state, dst->state); 41414a9b182Skjell if (s->proto == IPPROTO_TCP) { 41514a9b182Skjell print_seq(src); 41614a9b182Skjell printf(" "); 41714a9b182Skjell print_seq(dst); 41814a9b182Skjell printf("\n "); 41914a9b182Skjell } 42014a9b182Skjell 42114a9b182Skjell sec = s->creation % 60; 42214a9b182Skjell s->creation /= 60; 42314a9b182Skjell min = s->creation % 60; 42414a9b182Skjell s->creation /= 60; 42514a9b182Skjell hrs = s->creation; 42614a9b182Skjell printf("age %.2u:%.2u:%.2u", hrs, min, sec); 42714a9b182Skjell sec = s->expire % 60; 42814a9b182Skjell s->expire /= 60; 42914a9b182Skjell min = s->expire % 60; 43014a9b182Skjell s->expire /= 60; 43114a9b182Skjell hrs = s->expire; 43214a9b182Skjell printf(", expires in %.2u:%.2u:%.2u", hrs, min, sec); 43314a9b182Skjell printf(", %u pkts, %u bytes\n", s->packets, s->bytes); 43414a9b182Skjell printf("\n"); 43514a9b182Skjell } 43614a9b182Skjell 43714a9b182Skjell void 43881a15e5dSderaadt print_rule(struct pf_rule *r) 43914a9b182Skjell { 44076234b53Sdhartmei printf("@%d ", r->nr + 1); 4418418a02fSprovos if (r->action == PF_PASS) 44214a9b182Skjell printf("pass "); 443b996d042Sdhartmei else if (r->action == PF_DROP) { 44414a9b182Skjell printf("block "); 445b996d042Sdhartmei if (r->return_rst) 44614a9b182Skjell printf("return-rst "); 447b996d042Sdhartmei else if (r->return_icmp) { 448b996d042Sdhartmei struct icmpcodeent *ic; 449b996d042Sdhartmei 450b996d042Sdhartmei printf("return-icmp"); 451b996d042Sdhartmei ic = geticmpcodebynumber(r->return_icmp >> 8, 452b996d042Sdhartmei r->return_icmp & 255); 453b996d042Sdhartmei if ((ic == NULL) || (ic->type != ICMP_UNREACH)) 454b996d042Sdhartmei printf("(%u,%u) ", r->return_icmp >> 8, 455b996d042Sdhartmei r->return_icmp & 255); 456b996d042Sdhartmei else if (ic->code != ICMP_UNREACH_PORT) 457b996d042Sdhartmei printf("(%s) ", ic->name); 458b996d042Sdhartmei else 459b996d042Sdhartmei printf(" "); 460b996d042Sdhartmei } 461b996d042Sdhartmei } else 462b996d042Sdhartmei printf("scrub "); 46314a9b182Skjell if (r->direction == 0) 46414a9b182Skjell printf("in "); 46514a9b182Skjell else 46614a9b182Skjell printf("out "); 4677242ce7aSdhartmei if (r->log == 1) 46814a9b182Skjell printf("log "); 4697242ce7aSdhartmei else if (r->log == 2) 4707242ce7aSdhartmei printf("log-all "); 47114a9b182Skjell if (r->quick) 47214a9b182Skjell printf("quick "); 47314a9b182Skjell if (r->ifname[0]) 47414a9b182Skjell printf("on %s ", r->ifname); 47514a9b182Skjell if (r->proto) { 47614a9b182Skjell struct protoent *p = getprotobynumber(r->proto); 47714a9b182Skjell if (p != NULL) 47814a9b182Skjell printf("proto %s ", p->p_name); 47914a9b182Skjell else 48014a9b182Skjell printf("proto %u ", r->proto); 48114a9b182Skjell } 482ade2013bSwilfried if (!r->src.addr && !r->src.mask && !r->src.port_op && !r->dst.addr && ! r->dst.mask && !r->dst.port_op) 48314a9b182Skjell printf("all "); 48414a9b182Skjell else { 48514a9b182Skjell printf("from "); 486ade2013bSwilfried if (!r->src.addr && !r->src.mask) 48714a9b182Skjell printf("any "); 48814a9b182Skjell else { 48914a9b182Skjell if (r->src.not) 49014a9b182Skjell printf("! "); 49114a9b182Skjell print_addr(r->src.addr); 49214a9b182Skjell if (r->src.mask != 0xFFFFFFFF) { 49314a9b182Skjell printf("/"); 49414a9b182Skjell print_addr(r->src.mask); 49514a9b182Skjell } 49614a9b182Skjell printf(" "); 49714a9b182Skjell } 49814a9b182Skjell if (r->src.port_op) 49914a9b182Skjell print_port(r->src.port_op, r->src.port[0], 5005df8e51cSsmart r->src.port[1], 5015df8e51cSsmart r->proto == IPPROTO_TCP ? "tcp" : "udp"); 50214a9b182Skjell 50314a9b182Skjell printf("to "); 504ade2013bSwilfried if (!r->dst.addr && !r->dst.mask) 50514a9b182Skjell printf("any "); 50614a9b182Skjell else { 50714a9b182Skjell if (r->dst.not) 50814a9b182Skjell printf("! "); 50914a9b182Skjell print_addr(r->dst.addr); 51014a9b182Skjell if (r->dst.mask != 0xFFFFFFFF) { 51114a9b182Skjell printf("/"); 51214a9b182Skjell print_addr(r->dst.mask); 51314a9b182Skjell } 51414a9b182Skjell printf(" "); 51514a9b182Skjell } 51614a9b182Skjell if (r->dst.port_op) 51714a9b182Skjell print_port(r->dst.port_op, r->dst.port[0], 5185df8e51cSsmart r->dst.port[1], 5195df8e51cSsmart r->proto == IPPROTO_TCP ? "tcp" : "udp"); 52014a9b182Skjell } 52114a9b182Skjell if (r->flags || r->flagset) { 52214a9b182Skjell printf("flags "); 52314a9b182Skjell print_flags(r->flags); 52414a9b182Skjell printf("/"); 52514a9b182Skjell print_flags(r->flagset); 52614a9b182Skjell printf(" "); 52714a9b182Skjell } 528082ebc44Swilfried if (r->type) { 529082ebc44Swilfried struct icmptypeent *p; 530082ebc44Swilfried 531082ebc44Swilfried p = geticmptypebynumber(r->type-1); 532082ebc44Swilfried if (p != NULL) 533082ebc44Swilfried printf("icmp-type %s ", p->name); 534082ebc44Swilfried else 53514a9b182Skjell printf("icmp-type %u ", r->type-1); 536082ebc44Swilfried if (r->code) { 537082ebc44Swilfried struct icmpcodeent *p; 538082ebc44Swilfried 539082ebc44Swilfried p = geticmpcodebynumber(r->type-1, r->code-1); 540082ebc44Swilfried if (p != NULL) 541082ebc44Swilfried printf("code %s ", p->name); 542082ebc44Swilfried else 54314a9b182Skjell printf("code %u ", r->code-1); 544082ebc44Swilfried } 545082ebc44Swilfried } 54614a9b182Skjell if (r->keep_state) 54714a9b182Skjell printf("keep state "); 54814a9b182Skjell printf("\n"); 54914a9b182Skjell } 55014a9b182Skjell 5511f8f21bdSmillert int 552*ff352a37Smarkus parse_flags(char *s) 55314a9b182Skjell { 554*ff352a37Smarkus char *p, *q; 55514a9b182Skjell u_int8_t f = 0; 55681a15e5dSderaadt 557*ff352a37Smarkus for (p = s; *p; p++) { 558*ff352a37Smarkus if ((q = strchr(tcpflags, *p)) == NULL) 559*ff352a37Smarkus return -1; 560*ff352a37Smarkus else 561*ff352a37Smarkus f |= 1 << (q - tcpflags); 56214a9b182Skjell } 563dbfb98deSprovos return (f ? f : 63); 56414a9b182Skjell } 565