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