xref: /dragonfly/usr.sbin/pfctl/pf_print_state.c (revision 95cc27f0)
1*95cc27f0SJoerg Sonnenberger /*	$OpenBSD: pf_print_state.c,v 1.39 2004/02/10 17:48:08 henning Exp $	*/
2*95cc27f0SJoerg Sonnenberger /*	$DragonFly: src/usr.sbin/pfctl/pf_print_state.c,v 1.1 2004/09/21 21:25:28 joerg Exp $ */
3*95cc27f0SJoerg Sonnenberger 
4*95cc27f0SJoerg Sonnenberger /*
5*95cc27f0SJoerg Sonnenberger  * Copyright (c) 2001 Daniel Hartmeier
6*95cc27f0SJoerg Sonnenberger  * All rights reserved.
7*95cc27f0SJoerg Sonnenberger  *
8*95cc27f0SJoerg Sonnenberger  * Redistribution and use in source and binary forms, with or without
9*95cc27f0SJoerg Sonnenberger  * modification, are permitted provided that the following conditions
10*95cc27f0SJoerg Sonnenberger  * are met:
11*95cc27f0SJoerg Sonnenberger  *
12*95cc27f0SJoerg Sonnenberger  *    - Redistributions of source code must retain the above copyright
13*95cc27f0SJoerg Sonnenberger  *      notice, this list of conditions and the following disclaimer.
14*95cc27f0SJoerg Sonnenberger  *    - Redistributions in binary form must reproduce the above
15*95cc27f0SJoerg Sonnenberger  *      copyright notice, this list of conditions and the following
16*95cc27f0SJoerg Sonnenberger  *      disclaimer in the documentation and/or other materials provided
17*95cc27f0SJoerg Sonnenberger  *      with the distribution.
18*95cc27f0SJoerg Sonnenberger  *
19*95cc27f0SJoerg Sonnenberger  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*95cc27f0SJoerg Sonnenberger  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*95cc27f0SJoerg Sonnenberger  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22*95cc27f0SJoerg Sonnenberger  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23*95cc27f0SJoerg Sonnenberger  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24*95cc27f0SJoerg Sonnenberger  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25*95cc27f0SJoerg Sonnenberger  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26*95cc27f0SJoerg Sonnenberger  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27*95cc27f0SJoerg Sonnenberger  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28*95cc27f0SJoerg Sonnenberger  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29*95cc27f0SJoerg Sonnenberger  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30*95cc27f0SJoerg Sonnenberger  * POSSIBILITY OF SUCH DAMAGE.
31*95cc27f0SJoerg Sonnenberger  *
32*95cc27f0SJoerg Sonnenberger  */
33*95cc27f0SJoerg Sonnenberger 
34*95cc27f0SJoerg Sonnenberger #include <sys/param.h>
35*95cc27f0SJoerg Sonnenberger #include <sys/endian.h>
36*95cc27f0SJoerg Sonnenberger #include <sys/socket.h>
37*95cc27f0SJoerg Sonnenberger #include <net/if.h>
38*95cc27f0SJoerg Sonnenberger #define TCPSTATES
39*95cc27f0SJoerg Sonnenberger #include <netinet/tcp_fsm.h>
40*95cc27f0SJoerg Sonnenberger #include <net/pf/pfvar.h>
41*95cc27f0SJoerg Sonnenberger #include <arpa/inet.h>
42*95cc27f0SJoerg Sonnenberger #include <netdb.h>
43*95cc27f0SJoerg Sonnenberger 
44*95cc27f0SJoerg Sonnenberger #include <stdio.h>
45*95cc27f0SJoerg Sonnenberger #include <string.h>
46*95cc27f0SJoerg Sonnenberger 
47*95cc27f0SJoerg Sonnenberger #include "pfctl_parser.h"
48*95cc27f0SJoerg Sonnenberger #include "pfctl.h"
49*95cc27f0SJoerg Sonnenberger 
50*95cc27f0SJoerg Sonnenberger void	print_name(struct pf_addr *, sa_family_t);
51*95cc27f0SJoerg Sonnenberger 
52*95cc27f0SJoerg Sonnenberger void
53*95cc27f0SJoerg Sonnenberger print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
54*95cc27f0SJoerg Sonnenberger {
55*95cc27f0SJoerg Sonnenberger 	switch (addr->type) {
56*95cc27f0SJoerg Sonnenberger 	case PF_ADDR_DYNIFTL:
57*95cc27f0SJoerg Sonnenberger 		printf("(%s", addr->v.ifname);
58*95cc27f0SJoerg Sonnenberger 		if (addr->iflags & PFI_AFLAG_NETWORK)
59*95cc27f0SJoerg Sonnenberger 			printf(":network");
60*95cc27f0SJoerg Sonnenberger 		if (addr->iflags & PFI_AFLAG_BROADCAST)
61*95cc27f0SJoerg Sonnenberger 			printf(":broadcast");
62*95cc27f0SJoerg Sonnenberger 		if (addr->iflags & PFI_AFLAG_PEER)
63*95cc27f0SJoerg Sonnenberger 			printf(":peer");
64*95cc27f0SJoerg Sonnenberger 		if (addr->iflags & PFI_AFLAG_NOALIAS)
65*95cc27f0SJoerg Sonnenberger 			printf(":0");
66*95cc27f0SJoerg Sonnenberger 		if (verbose) {
67*95cc27f0SJoerg Sonnenberger 			if (addr->p.dyncnt <= 0)
68*95cc27f0SJoerg Sonnenberger 				printf(":*");
69*95cc27f0SJoerg Sonnenberger 			else
70*95cc27f0SJoerg Sonnenberger 				printf(":%d", addr->p.dyncnt);
71*95cc27f0SJoerg Sonnenberger 		}
72*95cc27f0SJoerg Sonnenberger 		printf(")");
73*95cc27f0SJoerg Sonnenberger 		break;
74*95cc27f0SJoerg Sonnenberger 	case PF_ADDR_TABLE:
75*95cc27f0SJoerg Sonnenberger 		if (verbose)
76*95cc27f0SJoerg Sonnenberger 			if (addr->p.tblcnt == -1)
77*95cc27f0SJoerg Sonnenberger 				printf("<%s:*>", addr->v.tblname);
78*95cc27f0SJoerg Sonnenberger 			else
79*95cc27f0SJoerg Sonnenberger 				printf("<%s:%d>", addr->v.tblname,
80*95cc27f0SJoerg Sonnenberger 				    addr->p.tblcnt);
81*95cc27f0SJoerg Sonnenberger 		else
82*95cc27f0SJoerg Sonnenberger 			printf("<%s>", addr->v.tblname);
83*95cc27f0SJoerg Sonnenberger 		return;
84*95cc27f0SJoerg Sonnenberger 	case PF_ADDR_ADDRMASK:
85*95cc27f0SJoerg Sonnenberger 		if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
86*95cc27f0SJoerg Sonnenberger 		    PF_AZERO(&addr->v.a.mask, AF_INET6))
87*95cc27f0SJoerg Sonnenberger 			printf("any");
88*95cc27f0SJoerg Sonnenberger 		else {
89*95cc27f0SJoerg Sonnenberger 			char buf[48];
90*95cc27f0SJoerg Sonnenberger 
91*95cc27f0SJoerg Sonnenberger 			if (inet_ntop(af, &addr->v.a.addr, buf,
92*95cc27f0SJoerg Sonnenberger 			    sizeof(buf)) == NULL)
93*95cc27f0SJoerg Sonnenberger 				printf("?");
94*95cc27f0SJoerg Sonnenberger 			else
95*95cc27f0SJoerg Sonnenberger 				printf("%s", buf);
96*95cc27f0SJoerg Sonnenberger 		}
97*95cc27f0SJoerg Sonnenberger 		break;
98*95cc27f0SJoerg Sonnenberger 	case PF_ADDR_NOROUTE:
99*95cc27f0SJoerg Sonnenberger 		printf("no-route");
100*95cc27f0SJoerg Sonnenberger 		return;
101*95cc27f0SJoerg Sonnenberger 	default:
102*95cc27f0SJoerg Sonnenberger 		printf("?");
103*95cc27f0SJoerg Sonnenberger 		return;
104*95cc27f0SJoerg Sonnenberger 	}
105*95cc27f0SJoerg Sonnenberger 
106*95cc27f0SJoerg Sonnenberger 	/* mask if not _both_ address and mask are zero */
107*95cc27f0SJoerg Sonnenberger 	if (!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
108*95cc27f0SJoerg Sonnenberger 	    PF_AZERO(&addr->v.a.mask, AF_INET6))) {
109*95cc27f0SJoerg Sonnenberger 		int bits = unmask(&addr->v.a.mask, af);
110*95cc27f0SJoerg Sonnenberger 
111*95cc27f0SJoerg Sonnenberger 		if (bits != (af == AF_INET ? 32 : 128))
112*95cc27f0SJoerg Sonnenberger 			printf("/%d", bits);
113*95cc27f0SJoerg Sonnenberger 	}
114*95cc27f0SJoerg Sonnenberger }
115*95cc27f0SJoerg Sonnenberger 
116*95cc27f0SJoerg Sonnenberger void
117*95cc27f0SJoerg Sonnenberger print_name(struct pf_addr *addr, sa_family_t af)
118*95cc27f0SJoerg Sonnenberger {
119*95cc27f0SJoerg Sonnenberger 	char hostname[NI_MAXHOST];
120*95cc27f0SJoerg Sonnenberger 
121*95cc27f0SJoerg Sonnenberger 	strlcpy(hostname, "?", sizeof(hostname));
122*95cc27f0SJoerg Sonnenberger 	switch (af) {
123*95cc27f0SJoerg Sonnenberger 	case AF_INET: {
124*95cc27f0SJoerg Sonnenberger 		struct sockaddr_in sin;
125*95cc27f0SJoerg Sonnenberger 
126*95cc27f0SJoerg Sonnenberger 		memset(&sin, 0, sizeof(sin));
127*95cc27f0SJoerg Sonnenberger 		sin.sin_len = sizeof(sin);
128*95cc27f0SJoerg Sonnenberger 		sin.sin_family = AF_INET;
129*95cc27f0SJoerg Sonnenberger 		sin.sin_addr = addr->v4;
130*95cc27f0SJoerg Sonnenberger 		getnameinfo((struct sockaddr *)&sin, sin.sin_len,
131*95cc27f0SJoerg Sonnenberger 		    hostname, sizeof(hostname), NULL, 0, NI_NOFQDN);
132*95cc27f0SJoerg Sonnenberger 		break;
133*95cc27f0SJoerg Sonnenberger 	}
134*95cc27f0SJoerg Sonnenberger 	case AF_INET6: {
135*95cc27f0SJoerg Sonnenberger 		struct sockaddr_in6 sin6;
136*95cc27f0SJoerg Sonnenberger 
137*95cc27f0SJoerg Sonnenberger 		memset(&sin6, 0, sizeof(sin6));
138*95cc27f0SJoerg Sonnenberger 		sin6.sin6_len = sizeof(sin6);
139*95cc27f0SJoerg Sonnenberger 		sin6.sin6_family = AF_INET6;
140*95cc27f0SJoerg Sonnenberger 		sin6.sin6_addr = addr->v6;
141*95cc27f0SJoerg Sonnenberger 		getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
142*95cc27f0SJoerg Sonnenberger 		    hostname, sizeof(hostname), NULL, 0, NI_NOFQDN);
143*95cc27f0SJoerg Sonnenberger 		break;
144*95cc27f0SJoerg Sonnenberger 	}
145*95cc27f0SJoerg Sonnenberger 	}
146*95cc27f0SJoerg Sonnenberger 	printf("%s", hostname);
147*95cc27f0SJoerg Sonnenberger }
148*95cc27f0SJoerg Sonnenberger 
149*95cc27f0SJoerg Sonnenberger void
150*95cc27f0SJoerg Sonnenberger print_host(struct pf_state_host *h, sa_family_t af, int opts)
151*95cc27f0SJoerg Sonnenberger {
152*95cc27f0SJoerg Sonnenberger 	u_int16_t p = ntohs(h->port);
153*95cc27f0SJoerg Sonnenberger 
154*95cc27f0SJoerg Sonnenberger 	if (opts & PF_OPT_USEDNS)
155*95cc27f0SJoerg Sonnenberger 		print_name(&h->addr, af);
156*95cc27f0SJoerg Sonnenberger 	else {
157*95cc27f0SJoerg Sonnenberger 		struct pf_addr_wrap aw;
158*95cc27f0SJoerg Sonnenberger 
159*95cc27f0SJoerg Sonnenberger 		memset(&aw, 0, sizeof(aw));
160*95cc27f0SJoerg Sonnenberger 		aw.v.a.addr = h->addr;
161*95cc27f0SJoerg Sonnenberger 		if (af == AF_INET)
162*95cc27f0SJoerg Sonnenberger 			aw.v.a.mask.addr32[0] = 0xffffffff;
163*95cc27f0SJoerg Sonnenberger 		else {
164*95cc27f0SJoerg Sonnenberger 			memset(&aw.v.a.mask, 0xff, sizeof(aw.v.a.mask));
165*95cc27f0SJoerg Sonnenberger 			af = AF_INET6;
166*95cc27f0SJoerg Sonnenberger 		}
167*95cc27f0SJoerg Sonnenberger 		print_addr(&aw, af, opts & PF_OPT_VERBOSE2);
168*95cc27f0SJoerg Sonnenberger 	}
169*95cc27f0SJoerg Sonnenberger 
170*95cc27f0SJoerg Sonnenberger 	if (p) {
171*95cc27f0SJoerg Sonnenberger 		if (af == AF_INET)
172*95cc27f0SJoerg Sonnenberger 			printf(":%u", p);
173*95cc27f0SJoerg Sonnenberger 		else
174*95cc27f0SJoerg Sonnenberger 			printf("[%u]", p);
175*95cc27f0SJoerg Sonnenberger 	}
176*95cc27f0SJoerg Sonnenberger }
177*95cc27f0SJoerg Sonnenberger 
178*95cc27f0SJoerg Sonnenberger void
179*95cc27f0SJoerg Sonnenberger print_seq(struct pf_state_peer *p)
180*95cc27f0SJoerg Sonnenberger {
181*95cc27f0SJoerg Sonnenberger 	if (p->seqdiff)
182*95cc27f0SJoerg Sonnenberger 		printf("[%u + %u](+%u)", p->seqlo, p->seqhi - p->seqlo,
183*95cc27f0SJoerg Sonnenberger 		    p->seqdiff);
184*95cc27f0SJoerg Sonnenberger 	else
185*95cc27f0SJoerg Sonnenberger 		printf("[%u + %u]", p->seqlo, p->seqhi - p->seqlo);
186*95cc27f0SJoerg Sonnenberger }
187*95cc27f0SJoerg Sonnenberger 
188*95cc27f0SJoerg Sonnenberger void
189*95cc27f0SJoerg Sonnenberger print_state(struct pf_state *s, int opts)
190*95cc27f0SJoerg Sonnenberger {
191*95cc27f0SJoerg Sonnenberger 	struct pf_state_peer *src, *dst;
192*95cc27f0SJoerg Sonnenberger 	struct protoent *p;
193*95cc27f0SJoerg Sonnenberger 	int min, sec;
194*95cc27f0SJoerg Sonnenberger 
195*95cc27f0SJoerg Sonnenberger 	if (s->direction == PF_OUT) {
196*95cc27f0SJoerg Sonnenberger 		src = &s->src;
197*95cc27f0SJoerg Sonnenberger 		dst = &s->dst;
198*95cc27f0SJoerg Sonnenberger 	} else {
199*95cc27f0SJoerg Sonnenberger 		src = &s->dst;
200*95cc27f0SJoerg Sonnenberger 		dst = &s->src;
201*95cc27f0SJoerg Sonnenberger 	}
202*95cc27f0SJoerg Sonnenberger 	printf("%s ", s->u.ifname);
203*95cc27f0SJoerg Sonnenberger 	if ((p = getprotobynumber(s->proto)) != NULL)
204*95cc27f0SJoerg Sonnenberger 		printf("%s ", p->p_name);
205*95cc27f0SJoerg Sonnenberger 	else
206*95cc27f0SJoerg Sonnenberger 		printf("%u ", s->proto);
207*95cc27f0SJoerg Sonnenberger 	if (PF_ANEQ(&s->lan.addr, &s->gwy.addr, s->af) ||
208*95cc27f0SJoerg Sonnenberger 	    (s->lan.port != s->gwy.port)) {
209*95cc27f0SJoerg Sonnenberger 		print_host(&s->lan, s->af, opts);
210*95cc27f0SJoerg Sonnenberger 		if (s->direction == PF_OUT)
211*95cc27f0SJoerg Sonnenberger 			printf(" -> ");
212*95cc27f0SJoerg Sonnenberger 		else
213*95cc27f0SJoerg Sonnenberger 			printf(" <- ");
214*95cc27f0SJoerg Sonnenberger 	}
215*95cc27f0SJoerg Sonnenberger 	print_host(&s->gwy, s->af, opts);
216*95cc27f0SJoerg Sonnenberger 	if (s->direction == PF_OUT)
217*95cc27f0SJoerg Sonnenberger 		printf(" -> ");
218*95cc27f0SJoerg Sonnenberger 	else
219*95cc27f0SJoerg Sonnenberger 		printf(" <- ");
220*95cc27f0SJoerg Sonnenberger 	print_host(&s->ext, s->af, opts);
221*95cc27f0SJoerg Sonnenberger 
222*95cc27f0SJoerg Sonnenberger 	printf("    ");
223*95cc27f0SJoerg Sonnenberger 	if (s->proto == IPPROTO_TCP) {
224*95cc27f0SJoerg Sonnenberger 		if (src->state <= TCPS_TIME_WAIT &&
225*95cc27f0SJoerg Sonnenberger 		    dst->state <= TCPS_TIME_WAIT)
226*95cc27f0SJoerg Sonnenberger 			printf("   %s:%s\n", tcpstates[src->state],
227*95cc27f0SJoerg Sonnenberger 			    tcpstates[dst->state]);
228*95cc27f0SJoerg Sonnenberger 		else if (src->state == PF_TCPS_PROXY_SRC ||
229*95cc27f0SJoerg Sonnenberger 		    dst->state == PF_TCPS_PROXY_SRC)
230*95cc27f0SJoerg Sonnenberger 			printf("   PROXY:SRC\n");
231*95cc27f0SJoerg Sonnenberger 		else if (src->state == PF_TCPS_PROXY_DST ||
232*95cc27f0SJoerg Sonnenberger 		    dst->state == PF_TCPS_PROXY_DST)
233*95cc27f0SJoerg Sonnenberger 			printf("   PROXY:DST\n");
234*95cc27f0SJoerg Sonnenberger 		else
235*95cc27f0SJoerg Sonnenberger 			printf("   <BAD STATE LEVELS %u:%u>\n",
236*95cc27f0SJoerg Sonnenberger 			    src->state, dst->state);
237*95cc27f0SJoerg Sonnenberger 		if (opts & PF_OPT_VERBOSE) {
238*95cc27f0SJoerg Sonnenberger 			printf("   ");
239*95cc27f0SJoerg Sonnenberger 			print_seq(src);
240*95cc27f0SJoerg Sonnenberger 			if (src->wscale && dst->wscale)
241*95cc27f0SJoerg Sonnenberger 				printf(" wscale %u",
242*95cc27f0SJoerg Sonnenberger 				    src->wscale & PF_WSCALE_MASK);
243*95cc27f0SJoerg Sonnenberger 			printf("  ");
244*95cc27f0SJoerg Sonnenberger 			print_seq(dst);
245*95cc27f0SJoerg Sonnenberger 			if (src->wscale && dst->wscale)
246*95cc27f0SJoerg Sonnenberger 				printf(" wscale %u",
247*95cc27f0SJoerg Sonnenberger 				    dst->wscale & PF_WSCALE_MASK);
248*95cc27f0SJoerg Sonnenberger 			printf("\n");
249*95cc27f0SJoerg Sonnenberger 		}
250*95cc27f0SJoerg Sonnenberger 	} else if (s->proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
251*95cc27f0SJoerg Sonnenberger 	    dst->state < PFUDPS_NSTATES) {
252*95cc27f0SJoerg Sonnenberger 		const char *states[] = PFUDPS_NAMES;
253*95cc27f0SJoerg Sonnenberger 
254*95cc27f0SJoerg Sonnenberger 		printf("   %s:%s\n", states[src->state], states[dst->state]);
255*95cc27f0SJoerg Sonnenberger 	} else if (s->proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
256*95cc27f0SJoerg Sonnenberger 	    dst->state < PFOTHERS_NSTATES) {
257*95cc27f0SJoerg Sonnenberger 		/* XXX ICMP doesn't really have state levels */
258*95cc27f0SJoerg Sonnenberger 		const char *states[] = PFOTHERS_NAMES;
259*95cc27f0SJoerg Sonnenberger 
260*95cc27f0SJoerg Sonnenberger 		printf("   %s:%s\n", states[src->state], states[dst->state]);
261*95cc27f0SJoerg Sonnenberger 	} else {
262*95cc27f0SJoerg Sonnenberger 		printf("   %u:%u\n", src->state, dst->state);
263*95cc27f0SJoerg Sonnenberger 	}
264*95cc27f0SJoerg Sonnenberger 
265*95cc27f0SJoerg Sonnenberger 	if (opts & PF_OPT_VERBOSE) {
266*95cc27f0SJoerg Sonnenberger 		sec = s->creation % 60;
267*95cc27f0SJoerg Sonnenberger 		s->creation /= 60;
268*95cc27f0SJoerg Sonnenberger 		min = s->creation % 60;
269*95cc27f0SJoerg Sonnenberger 		s->creation /= 60;
270*95cc27f0SJoerg Sonnenberger 		printf("   age %.2u:%.2u:%.2u", s->creation, min, sec);
271*95cc27f0SJoerg Sonnenberger 		sec = s->expire % 60;
272*95cc27f0SJoerg Sonnenberger 		s->expire /= 60;
273*95cc27f0SJoerg Sonnenberger 		min = s->expire % 60;
274*95cc27f0SJoerg Sonnenberger 		s->expire /= 60;
275*95cc27f0SJoerg Sonnenberger 		printf(", expires in %.2u:%.2u:%.2u", s->expire, min, sec);
276*95cc27f0SJoerg Sonnenberger 		printf(", %u:%u pkts, %u:%u bytes",
277*95cc27f0SJoerg Sonnenberger 		    s->packets[0], s->packets[1], s->bytes[0], s->bytes[1]);
278*95cc27f0SJoerg Sonnenberger 		if (s->anchor.nr != (uint32_t)(-1))
279*95cc27f0SJoerg Sonnenberger 			printf(", anchor %u", s->anchor.nr);
280*95cc27f0SJoerg Sonnenberger 		if (s->rule.nr != (uint32_t)(-1))
281*95cc27f0SJoerg Sonnenberger 			printf(", rule %u", s->rule.nr);
282*95cc27f0SJoerg Sonnenberger 		if (s->src_node != NULL)
283*95cc27f0SJoerg Sonnenberger 			printf(", source-track");
284*95cc27f0SJoerg Sonnenberger 		if (s->nat_src_node != NULL)
285*95cc27f0SJoerg Sonnenberger 			printf(", sticky-address");
286*95cc27f0SJoerg Sonnenberger 		printf("\n");
287*95cc27f0SJoerg Sonnenberger 	}
288*95cc27f0SJoerg Sonnenberger 	if (opts & PF_OPT_VERBOSE2) {
289*95cc27f0SJoerg Sonnenberger 		printf("   id: %016llx creatorid: %08x\n",
290*95cc27f0SJoerg Sonnenberger 		    be64toh(s->id), ntohl(s->creatorid));
291*95cc27f0SJoerg Sonnenberger 	}
292*95cc27f0SJoerg Sonnenberger }
293*95cc27f0SJoerg Sonnenberger 
294*95cc27f0SJoerg Sonnenberger int
295*95cc27f0SJoerg Sonnenberger unmask(struct pf_addr *m, sa_family_t af __unused)
296*95cc27f0SJoerg Sonnenberger {
297*95cc27f0SJoerg Sonnenberger 	int i = 31, j = 0, b = 0;
298*95cc27f0SJoerg Sonnenberger 	u_int32_t tmp;
299*95cc27f0SJoerg Sonnenberger 
300*95cc27f0SJoerg Sonnenberger 	while (j < 4 && m->addr32[j] == 0xffffffff) {
301*95cc27f0SJoerg Sonnenberger 		b += 32;
302*95cc27f0SJoerg Sonnenberger 		j++;
303*95cc27f0SJoerg Sonnenberger 	}
304*95cc27f0SJoerg Sonnenberger 	if (j < 4) {
305*95cc27f0SJoerg Sonnenberger 		tmp = ntohl(m->addr32[j]);
306*95cc27f0SJoerg Sonnenberger 		for (i = 31; tmp & (1 << i); --i)
307*95cc27f0SJoerg Sonnenberger 			b++;
308*95cc27f0SJoerg Sonnenberger 	}
309*95cc27f0SJoerg Sonnenberger 	return (b);
310*95cc27f0SJoerg Sonnenberger }
311