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