1 /* $OpenBSD: pf_print_state.c,v 1.52 2008/08/12 16:40:18 david Exp $ */
2
3 /*-
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2001 Daniel Hartmeier
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 */
34
35 #include <sys/cdefs.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <sys/endian.h>
39 #include <net/if.h>
40 #define TCPSTATES
41 #include <netinet/tcp_fsm.h>
42 #include <netinet/sctp.h>
43 #include <net/pfvar.h>
44 #include <arpa/inet.h>
45 #include <netdb.h>
46
47 #include <stdint.h>
48 #include <stdio.h>
49 #include <string.h>
50
51 #include "pfctl_parser.h"
52 #include "pfctl.h"
53
54 void print_name(struct pf_addr *, sa_family_t);
55
56 void
print_addr(struct pf_addr_wrap * addr,sa_family_t af,int verbose)57 print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
58 {
59 switch (addr->type) {
60 case PF_ADDR_DYNIFTL:
61 printf("(%s", addr->v.ifname);
62 if (addr->iflags & PFI_AFLAG_NETWORK)
63 printf(":network");
64 if (addr->iflags & PFI_AFLAG_BROADCAST)
65 printf(":broadcast");
66 if (addr->iflags & PFI_AFLAG_PEER)
67 printf(":peer");
68 if (addr->iflags & PFI_AFLAG_NOALIAS)
69 printf(":0");
70 if (verbose) {
71 if (addr->p.dyncnt <= 0)
72 printf(":*");
73 else
74 printf(":%d", addr->p.dyncnt);
75 }
76 printf(")");
77 break;
78 case PF_ADDR_TABLE:
79 if (verbose)
80 if (addr->p.tblcnt == -1)
81 printf("<%s:*>", addr->v.tblname);
82 else
83 printf("<%s:%d>", addr->v.tblname,
84 addr->p.tblcnt);
85 else
86 printf("<%s>", addr->v.tblname);
87 return;
88 case PF_ADDR_RANGE: {
89 char buf[48];
90
91 if (inet_ntop(af, &addr->v.a.addr, buf, sizeof(buf)) == NULL)
92 printf("?");
93 else
94 printf("%s", buf);
95 if (inet_ntop(af, &addr->v.a.mask, buf, sizeof(buf)) == NULL)
96 printf(" - ?");
97 else
98 printf(" - %s", buf);
99 break;
100 }
101 case PF_ADDR_ADDRMASK:
102 if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
103 PF_AZERO(&addr->v.a.mask, AF_INET6))
104 printf("any");
105 else {
106 char buf[48];
107
108 if (inet_ntop(af, &addr->v.a.addr, buf,
109 sizeof(buf)) == NULL)
110 printf("?");
111 else
112 printf("%s", buf);
113 }
114 break;
115 case PF_ADDR_NOROUTE:
116 printf("no-route");
117 return;
118 case PF_ADDR_URPFFAILED:
119 printf("urpf-failed");
120 return;
121 default:
122 printf("?");
123 return;
124 }
125
126 /* mask if not _both_ address and mask are zero */
127 if (addr->type != PF_ADDR_RANGE &&
128 !(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
129 PF_AZERO(&addr->v.a.mask, AF_INET6))) {
130 int bits = unmask(&addr->v.a.mask, af);
131
132 if (bits != (af == AF_INET ? 32 : 128))
133 printf("/%d", bits);
134 }
135 }
136
137 void
print_name(struct pf_addr * addr,sa_family_t af)138 print_name(struct pf_addr *addr, sa_family_t af)
139 {
140 char host[NI_MAXHOST];
141
142 strlcpy(host, "?", sizeof(host));
143 switch (af) {
144 case AF_INET: {
145 struct sockaddr_in sin;
146
147 memset(&sin, 0, sizeof(sin));
148 sin.sin_len = sizeof(sin);
149 sin.sin_family = AF_INET;
150 sin.sin_addr = addr->v4;
151 getnameinfo((struct sockaddr *)&sin, sin.sin_len,
152 host, sizeof(host), NULL, 0, NI_NOFQDN);
153 break;
154 }
155 case AF_INET6: {
156 struct sockaddr_in6 sin6;
157
158 memset(&sin6, 0, sizeof(sin6));
159 sin6.sin6_len = sizeof(sin6);
160 sin6.sin6_family = AF_INET6;
161 sin6.sin6_addr = addr->v6;
162 getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
163 host, sizeof(host), NULL, 0, NI_NOFQDN);
164 break;
165 }
166 }
167 printf("%s", host);
168 }
169
170 void
print_host(struct pf_addr * addr,u_int16_t port,sa_family_t af,int opts)171 print_host(struct pf_addr *addr, u_int16_t port, sa_family_t af, int opts)
172 {
173 if (opts & PF_OPT_USEDNS)
174 print_name(addr, af);
175 else {
176 struct pf_addr_wrap aw;
177
178 memset(&aw, 0, sizeof(aw));
179 aw.v.a.addr = *addr;
180 if (af == AF_INET)
181 aw.v.a.mask.addr32[0] = 0xffffffff;
182 else {
183 memset(&aw.v.a.mask, 0xff, sizeof(aw.v.a.mask));
184 af = AF_INET6;
185 }
186 print_addr(&aw, af, opts & PF_OPT_VERBOSE2);
187 }
188
189 if (port) {
190 if (af == AF_INET)
191 printf(":%u", ntohs(port));
192 else
193 printf("[%u]", ntohs(port));
194 }
195 }
196
197 void
print_seq(struct pfctl_state_peer * p)198 print_seq(struct pfctl_state_peer *p)
199 {
200 if (p->seqdiff)
201 printf("[%u + %u](+%u)", p->seqlo,
202 p->seqhi - p->seqlo, p->seqdiff);
203 else
204 printf("[%u + %u]", p->seqlo,
205 p->seqhi - p->seqlo);
206 }
207
208
209 static const char *
sctp_state_name(int state)210 sctp_state_name(int state)
211 {
212 switch (state) {
213 case SCTP_CLOSED:
214 return ("CLOSED");
215 case SCTP_BOUND:
216 return ("BOUND");
217 case SCTP_LISTEN:
218 return ("LISTEN");
219 case SCTP_COOKIE_WAIT:
220 return ("COOKIE_WAIT");
221 case SCTP_COOKIE_ECHOED:
222 return ("COOKIE_ECHOED");
223 case SCTP_ESTABLISHED:
224 return ("ESTABLISHED");
225 case SCTP_SHUTDOWN_SENT:
226 return ("SHUTDOWN_SENT");
227 case SCTP_SHUTDOWN_RECEIVED:
228 return ("SHUTDOWN_RECEIVED");
229 case SCTP_SHUTDOWN_ACK_SENT:
230 return ("SHUTDOWN_ACK_SENT");
231 case SCTP_SHUTDOWN_PENDING:
232 return ("SHUTDOWN_PENDING");
233 default:
234 return ("?");
235 }
236 }
237
238 void
print_state(struct pfctl_state * s,int opts)239 print_state(struct pfctl_state *s, int opts)
240 {
241 struct pfctl_state_peer *src, *dst;
242 struct pfctl_state_key *key, *sk, *nk;
243 const char *protoname;
244 int min, sec;
245 sa_family_t af;
246 uint8_t proto;
247 #ifndef __NO_STRICT_ALIGNMENT
248 struct pfctl_state_key aligned_key[2];
249
250 bcopy(&s->key, aligned_key, sizeof(aligned_key));
251 key = aligned_key;
252 #else
253 key = s->key;
254 #endif
255
256 af = s->key[PF_SK_WIRE].af;
257 proto = s->key[PF_SK_WIRE].proto;
258
259 if (s->direction == PF_OUT) {
260 src = &s->src;
261 dst = &s->dst;
262 sk = &key[PF_SK_STACK];
263 nk = &key[PF_SK_WIRE];
264 if (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6)
265 sk->port[0] = nk->port[0];
266 } else {
267 src = &s->dst;
268 dst = &s->src;
269 sk = &key[PF_SK_WIRE];
270 nk = &key[PF_SK_STACK];
271 if (proto == IPPROTO_ICMP || proto == IPPROTO_ICMPV6)
272 sk->port[1] = nk->port[1];
273 }
274 printf("%s ", s->ifname);
275 if ((protoname = pfctl_proto2name(proto)) != NULL)
276 printf("%s ", protoname);
277 else
278 printf("%u ", proto);
279
280 print_host(&nk->addr[1], nk->port[1], af, opts);
281 if (PF_ANEQ(&nk->addr[1], &sk->addr[1], af) ||
282 nk->port[1] != sk->port[1]) {
283 printf(" (");
284 print_host(&sk->addr[1], sk->port[1], af, opts);
285 printf(")");
286 }
287 if (s->direction == PF_OUT)
288 printf(" -> ");
289 else
290 printf(" <- ");
291 print_host(&nk->addr[0], nk->port[0], af, opts);
292 if (PF_ANEQ(&nk->addr[0], &sk->addr[0], af) ||
293 nk->port[0] != sk->port[0]) {
294 printf(" (");
295 print_host(&sk->addr[0], sk->port[0], af, opts);
296 printf(")");
297 }
298
299 printf(" ");
300 if (proto == IPPROTO_TCP) {
301 if (src->state <= TCPS_TIME_WAIT &&
302 dst->state <= TCPS_TIME_WAIT)
303 printf(" %s:%s\n", tcpstates[src->state],
304 tcpstates[dst->state]);
305 else if (src->state == PF_TCPS_PROXY_SRC ||
306 dst->state == PF_TCPS_PROXY_SRC)
307 printf(" PROXY:SRC\n");
308 else if (src->state == PF_TCPS_PROXY_DST ||
309 dst->state == PF_TCPS_PROXY_DST)
310 printf(" PROXY:DST\n");
311 else
312 printf(" <BAD STATE LEVELS %u:%u>\n",
313 src->state, dst->state);
314 if (opts & PF_OPT_VERBOSE) {
315 printf(" ");
316 print_seq(src);
317 if (src->wscale && dst->wscale)
318 printf(" wscale %u",
319 src->wscale & PF_WSCALE_MASK);
320 printf(" ");
321 print_seq(dst);
322 if (src->wscale && dst->wscale)
323 printf(" wscale %u",
324 dst->wscale & PF_WSCALE_MASK);
325 printf("\n");
326 }
327 } else if (proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
328 dst->state < PFUDPS_NSTATES) {
329 const char *states[] = PFUDPS_NAMES;
330
331 printf(" %s:%s\n", states[src->state], states[dst->state]);
332 } else if (proto == IPPROTO_SCTP) {
333 printf(" %s:%s\n", sctp_state_name(src->state),
334 sctp_state_name(dst->state));
335 #ifndef INET6
336 } else if (proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
337 dst->state < PFOTHERS_NSTATES) {
338 #else
339 } else if (proto != IPPROTO_ICMP && proto != IPPROTO_ICMPV6 &&
340 src->state < PFOTHERS_NSTATES && dst->state < PFOTHERS_NSTATES) {
341 #endif
342 /* XXX ICMP doesn't really have state levels */
343 const char *states[] = PFOTHERS_NAMES;
344
345 printf(" %s:%s\n", states[src->state], states[dst->state]);
346 } else {
347 printf(" %u:%u\n", src->state, dst->state);
348 }
349
350 if (opts & PF_OPT_VERBOSE) {
351 u_int32_t creation = s->creation;
352 u_int32_t expire = s->expire;
353
354 sec = creation % 60;
355 creation /= 60;
356 min = creation % 60;
357 creation /= 60;
358 printf(" age %.2u:%.2u:%.2u", creation, min, sec);
359 sec = expire % 60;
360 expire /= 60;
361 min = expire % 60;
362 expire /= 60;
363 printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
364
365 printf(", %ju:%ju pkts, %ju:%ju bytes",
366 s->packets[0],
367 s->packets[1],
368 s->bytes[0],
369 s->bytes[1]);
370 if (s->anchor != -1)
371 printf(", anchor %u", s->anchor);
372 if (s->rule != -1)
373 printf(", rule %u", s->rule);
374 if (s->state_flags & PFSTATE_ALLOWOPTS)
375 printf(", allow-opts");
376 if (s->state_flags & PFSTATE_SLOPPY)
377 printf(", sloppy");
378 if (s->state_flags & PFSTATE_NOSYNC)
379 printf(", no-sync");
380 if (s->state_flags & PFSTATE_ACK)
381 printf(", psync-ack");
382 if (s->state_flags & PFSTATE_NODF)
383 printf(", no-df");
384 if (s->state_flags & PFSTATE_SETTOS)
385 printf(", set-tos 0x%2.2x", s->set_tos);
386 if (s->state_flags & PFSTATE_RANDOMID)
387 printf(", random-id");
388 if (s->state_flags & PFSTATE_SCRUB_TCP)
389 printf(", reassemble-tcp");
390 if (s->state_flags & PFSTATE_SETPRIO)
391 printf(", set-prio (0x%02x 0x%02x)",
392 s->set_prio[0], s->set_prio[1]);
393 if (s->dnpipe || s->dnrpipe) {
394 if (s->state_flags & PFSTATE_DN_IS_PIPE)
395 printf(", dummynet pipe (%d %d)",
396 s->dnpipe, s->dnrpipe);
397 if (s->state_flags & PFSTATE_DN_IS_QUEUE)
398 printf(", dummynet queue (%d %d)",
399 s->dnpipe, s->dnrpipe);
400 }
401 if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
402 printf(", source-track");
403 if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)
404 printf(", sticky-address");
405 if (s->log)
406 printf(", log");
407 if (s->log & PF_LOG_ALL)
408 printf(" (all)");
409 if (s->min_ttl)
410 printf(", min-ttl %d", s->min_ttl);
411 if (s->max_mss)
412 printf(", max-mss %d", s->max_mss);
413 printf("\n");
414 }
415 if (opts & PF_OPT_VERBOSE2) {
416 u_int64_t id;
417
418 bcopy(&s->id, &id, sizeof(u_int64_t));
419 printf(" id: %016jx creatorid: %08x", id, s->creatorid);
420 if (s->rt) {
421 switch (s->rt) {
422 case PF_ROUTETO:
423 printf(" route-to: ");
424 break;
425 case PF_DUPTO:
426 printf(" dup-to: ");
427 break;
428 case PF_REPLYTO:
429 printf(" reply-to: ");
430 break;
431 default:
432 printf(" gateway: ");
433 }
434 print_host(&s->rt_addr, 0, af, opts);
435 if (s->rt_ifname[0])
436 printf("@%s", s->rt_ifname);
437 }
438 if (s->rtableid != -1)
439 printf(" rtable: %d", s->rtableid);
440 printf("\n");
441
442 if (strcmp(s->ifname, s->orig_ifname) != 0)
443 printf(" origif: %s\n", s->orig_ifname);
444 }
445 }
446
447 int
unmask(struct pf_addr * m,sa_family_t af)448 unmask(struct pf_addr *m, sa_family_t af)
449 {
450 int i = 31, j = 0, b = 0;
451 u_int32_t tmp;
452
453 while (j < 4 && m->addr32[j] == 0xffffffff) {
454 b += 32;
455 j++;
456 }
457 if (j < 4) {
458 tmp = ntohl(m->addr32[j]);
459 for (i = 31; tmp & (1 << i); --i)
460 b++;
461 }
462 return (b);
463 }
464