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