xref: /openbsd/sbin/pfctl/pfctl_parser.c (revision d0cb3502)
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