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