1 /* $OpenBSD: pf_print_state.c,v 1.12 2015/01/20 18:26:58 deraadt 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 46 #include "pfctl_parser.h" 47 #include "pfctl.h" 48 #include "addrtoname.h" 49 50 void print_name(struct pf_addr *, sa_family_t); 51 52 void 53 print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose) 54 { 55 switch (addr->type) { 56 case PF_ADDR_DYNIFTL: 57 printf("(%s", addr->v.ifname); 58 if (addr->iflags & PFI_AFLAG_NETWORK) 59 printf(":network"); 60 if (addr->iflags & PFI_AFLAG_BROADCAST) 61 printf(":broadcast"); 62 if (addr->iflags & PFI_AFLAG_PEER) 63 printf(":peer"); 64 if (addr->iflags & PFI_AFLAG_NOALIAS) 65 printf(":0"); 66 if (verbose) { 67 if (addr->p.dyncnt <= 0) 68 printf(":*"); 69 else 70 printf(":%d", addr->p.dyncnt); 71 } 72 printf(")"); 73 break; 74 case PF_ADDR_TABLE: 75 if (verbose) 76 if (addr->p.tblcnt == -1) 77 printf("<%s:*>", addr->v.tblname); 78 else 79 printf("<%s:%d>", addr->v.tblname, 80 addr->p.tblcnt); 81 else 82 printf("<%s>", addr->v.tblname); 83 return; 84 case PF_ADDR_ADDRMASK: 85 if (PF_AZERO(&addr->v.a.addr, AF_INET6) && 86 PF_AZERO(&addr->v.a.mask, AF_INET6)) 87 printf("any"); 88 else { 89 char buf[48]; 90 91 if (inet_ntop(af, &addr->v.a.addr, buf, 92 sizeof(buf)) == NULL) 93 printf("?"); 94 else 95 printf("%s", buf); 96 } 97 break; 98 case PF_ADDR_NOROUTE: 99 printf("no-route"); 100 return; 101 default: 102 printf("?"); 103 return; 104 } 105 if (! PF_AZERO(&addr->v.a.mask, af)) { 106 int bits = unmask(&addr->v.a.mask, af); 107 108 if (bits != (af == AF_INET ? 32 : 128)) 109 printf("/%d", bits); 110 } 111 } 112 113 void 114 print_name(struct pf_addr *addr, sa_family_t af) 115 { 116 char *host; 117 118 switch (af) { 119 case AF_INET: 120 host = getname((char *)&addr->v4); 121 break; 122 case AF_INET6: 123 host = getname6((char *)&addr->v6); 124 break; 125 default: 126 host = "?"; 127 break; 128 } 129 printf("%s", host); 130 } 131 132 void 133 print_host(struct pf_addr *addr, u_int16_t port, sa_family_t af, u_int16_t rdom, 134 const char *proto, int opts) 135 { 136 struct servent *s = NULL; 137 char ps[6]; 138 139 if (rdom) 140 printf("(%u) ", ntohs(rdom)); 141 142 if (opts & PF_OPT_USEDNS) 143 print_name(addr, af); 144 else { 145 struct pf_addr_wrap aw; 146 147 memset(&aw, 0, sizeof(aw)); 148 aw.v.a.addr = *addr; 149 if (af == AF_INET) 150 aw.v.a.mask.addr32[0] = 0xffffffff; 151 else { 152 memset(&aw.v.a.mask, 0xff, sizeof(aw.v.a.mask)); 153 af = AF_INET6; 154 } 155 print_addr(&aw, af, opts & PF_OPT_VERBOSE2); 156 } 157 158 if (port) { 159 snprintf(ps, sizeof(ps), "%u", ntohs(port)); 160 if (opts & PF_OPT_PORTNAMES) 161 s = getservbyport(port, proto); 162 if (af == AF_INET) 163 printf(":%s", s ? s->s_name : ps); 164 else 165 printf("[%s]", s ? s->s_name : ps); 166 } 167 } 168 169 void 170 print_seq(struct pfsync_state_peer *p) 171 { 172 if (p->seqdiff) 173 printf("[%u + %u](+%u)", ntohl(p->seqlo), 174 ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff)); 175 else 176 printf("[%u + %u]", ntohl(p->seqlo), 177 ntohl(p->seqhi) - ntohl(p->seqlo)); 178 } 179 180 void 181 print_state(struct pfsync_state *s, int opts) 182 { 183 struct pfsync_state_peer *src, *dst; 184 struct pfsync_state_key *sk, *nk; 185 int min, sec, sidx, didx; 186 187 if (s->direction == PF_OUT) { 188 src = &s->src; 189 dst = &s->dst; 190 sk = &s->key[PF_SK_STACK]; 191 nk = &s->key[PF_SK_WIRE]; 192 if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6) 193 sk->port[0] = nk->port[0]; 194 } else { 195 src = &s->dst; 196 dst = &s->src; 197 sk = &s->key[PF_SK_WIRE]; 198 nk = &s->key[PF_SK_STACK]; 199 if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6) 200 sk->port[1] = nk->port[1]; 201 } 202 printf("%s ", s->ifname); 203 printf("%s ", ipproto_string(s->proto)); 204 205 if (nk->af != sk->af) 206 sidx = 1, didx = 0; 207 else 208 sidx = 0, didx = 1; 209 210 print_host(&nk->addr[didx], nk->port[didx], nk->af, nk->rdomain, NULL, opts); 211 if (nk->af != sk->af || PF_ANEQ(&nk->addr[1], &sk->addr[1], nk->af) || 212 nk->port[1] != sk->port[1]) { 213 printf(" ("); 214 print_host(&sk->addr[1], sk->port[1], sk->af, sk->rdomain, 215 NULL, opts); 216 printf(")"); 217 } 218 if (s->direction == PF_OUT) 219 printf(" -> "); 220 else 221 printf(" <- "); 222 print_host(&nk->addr[sidx], nk->port[sidx], nk->af, nk->rdomain, NULL, 223 opts); 224 if (nk->af != sk->af || PF_ANEQ(&nk->addr[0], &sk->addr[0], nk->af) || 225 nk->port[0] != sk->port[0]) { 226 printf(" ("); 227 print_host(&sk->addr[0], sk->port[0], sk->af, sk->rdomain, NULL, 228 opts); 229 printf(")"); 230 } 231 232 printf(" "); 233 if (s->proto == IPPROTO_TCP) { 234 if (src->state <= TCPS_TIME_WAIT && 235 dst->state <= TCPS_TIME_WAIT) 236 printf("\n %s:%s", tcpstates[src->state], 237 tcpstates[dst->state]); 238 else if (src->state == PF_TCPS_PROXY_SRC || 239 dst->state == PF_TCPS_PROXY_SRC) 240 printf("\n PROXY:SRC"); 241 else if (src->state == PF_TCPS_PROXY_DST || 242 dst->state == PF_TCPS_PROXY_DST) 243 printf("\n PROXY:DST"); 244 else 245 printf("\n <BAD STATE LEVELS %u:%u>", 246 src->state, dst->state); 247 if (opts & PF_OPT_VERBOSE) { 248 printf("\n "); 249 print_seq(src); 250 if (src->wscale && dst->wscale) 251 printf(" wscale %u", 252 src->wscale & PF_WSCALE_MASK); 253 printf(" "); 254 print_seq(dst); 255 if (src->wscale && dst->wscale) 256 printf(" wscale %u", 257 dst->wscale & PF_WSCALE_MASK); 258 } 259 } else if (s->proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES && 260 dst->state < PFUDPS_NSTATES) { 261 const char *states[] = PFUDPS_NAMES; 262 263 printf(" %s:%s", states[src->state], states[dst->state]); 264 } else if (s->proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES && 265 dst->state < PFOTHERS_NSTATES) { 266 /* XXX ICMP doesn't really have state levels */ 267 const char *states[] = PFOTHERS_NAMES; 268 269 printf(" %s:%s", states[src->state], states[dst->state]); 270 } else { 271 printf(" %u:%u", src->state, dst->state); 272 } 273 274 if (opts & PF_OPT_VERBOSE) { 275 u_int64_t packets[2]; 276 u_int64_t bytes[2]; 277 u_int32_t creation = ntohl(s->creation); 278 u_int32_t expire = ntohl(s->expire); 279 280 sec = creation % 60; 281 creation /= 60; 282 min = creation % 60; 283 creation /= 60; 284 printf("\n age %.2u:%.2u:%.2u", creation, min, sec); 285 sec = expire % 60; 286 expire /= 60; 287 min = expire % 60; 288 expire /= 60; 289 printf(", expires in %.2u:%.2u:%.2u", expire, min, sec); 290 291 bcopy(s->packets[0], &packets[0], sizeof(u_int64_t)); 292 bcopy(s->packets[1], &packets[1], sizeof(u_int64_t)); 293 bcopy(s->bytes[0], &bytes[0], sizeof(u_int64_t)); 294 bcopy(s->bytes[1], &bytes[1], sizeof(u_int64_t)); 295 printf(", %llu:%llu pkts, %llu:%llu bytes", 296 betoh64(packets[0]), 297 betoh64(packets[1]), 298 betoh64(bytes[0]), 299 betoh64(bytes[1])); 300 if (s->anchor != -1) 301 printf(", anchor %u", ntohl(s->anchor)); 302 if (s->rule != -1) 303 printf(", rule %u", ntohl(s->rule)); 304 } 305 if (opts & PF_OPT_VERBOSE2) { 306 u_int64_t id; 307 308 bcopy(&s->id, &id, sizeof(u_int64_t)); 309 printf("\n id: %016llx creatorid: %08x", 310 betoh64(id), ntohl(s->creatorid)); 311 } 312 } 313 314 int 315 unmask(struct pf_addr *m, sa_family_t af) 316 { 317 int i = 31, j = 0, b = 0; 318 u_int32_t tmp; 319 320 while (j < 4 && m->addr32[j] == 0xffffffff) { 321 b += 32; 322 j++; 323 } 324 if (j < 4) { 325 tmp = ntohl(m->addr32[j]); 326 for (i = 31; tmp & (1 << i); --i) 327 b++; 328 } 329 return (b); 330 } 331