1 /* $OpenBSD: pf_print_state.c,v 1.9 2010/11/12 13:14:41 claudio 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 int opts) 134 { 135 if (rdom) 136 printf("(%u) ", ntohs(rdom)); 137 138 if (opts & PF_OPT_USEDNS) 139 print_name(addr, af); 140 else { 141 struct pf_addr_wrap aw; 142 143 memset(&aw, 0, sizeof(aw)); 144 aw.v.a.addr = *addr; 145 if (af == AF_INET) 146 aw.v.a.mask.addr32[0] = 0xffffffff; 147 else { 148 memset(&aw.v.a.mask, 0xff, sizeof(aw.v.a.mask)); 149 af = AF_INET6; 150 } 151 print_addr(&aw, af, opts & PF_OPT_VERBOSE2); 152 } 153 154 if (port) { 155 if (af == AF_INET) 156 printf(":%u", ntohs(port)); 157 else 158 printf("[%u]", ntohs(port)); 159 } 160 } 161 162 void 163 print_seq(struct pfsync_state_peer *p) 164 { 165 if (p->seqdiff) 166 printf("[%u + %u](+%u)", ntohl(p->seqlo), 167 ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff)); 168 else 169 printf("[%u + %u]", ntohl(p->seqlo), 170 ntohl(p->seqhi) - ntohl(p->seqlo)); 171 } 172 173 void 174 print_state(struct pfsync_state *s, int opts) 175 { 176 struct pfsync_state_peer *src, *dst; 177 struct pfsync_state_key *sk, *nk; 178 int min, sec; 179 180 if (s->direction == PF_OUT) { 181 src = &s->src; 182 dst = &s->dst; 183 sk = &s->key[PF_SK_STACK]; 184 nk = &s->key[PF_SK_WIRE]; 185 if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6) 186 sk->port[0] = nk->port[0]; 187 } else { 188 src = &s->dst; 189 dst = &s->src; 190 sk = &s->key[PF_SK_WIRE]; 191 nk = &s->key[PF_SK_STACK]; 192 if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6) 193 sk->port[1] = nk->port[1]; 194 } 195 printf("%s ", s->ifname); 196 printf("%s ", ipproto_string(s->proto)); 197 198 print_host(&nk->addr[1], nk->port[1], s->af, nk->rdomain, opts); 199 if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) || 200 nk->port[1] != sk->port[1]) { 201 printf(" ("); 202 print_host(&sk->addr[1], sk->port[1], s->af, sk->rdomain, opts); 203 printf(")"); 204 } 205 if (s->direction == PF_OUT) 206 printf(" -> "); 207 else 208 printf(" <- "); 209 print_host(&nk->addr[0], nk->port[0], s->af, nk->rdomain, opts); 210 if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) || 211 nk->port[0] != sk->port[0]) { 212 printf(" ("); 213 print_host(&sk->addr[0], sk->port[0], s->af, sk->rdomain, opts); 214 printf(")"); 215 } 216 217 printf(" "); 218 if (s->proto == IPPROTO_TCP) { 219 if (src->state <= TCPS_TIME_WAIT && 220 dst->state <= TCPS_TIME_WAIT) 221 printf("\n %s:%s", tcpstates[src->state], 222 tcpstates[dst->state]); 223 else if (src->state == PF_TCPS_PROXY_SRC || 224 dst->state == PF_TCPS_PROXY_SRC) 225 printf("\n PROXY:SRC"); 226 else if (src->state == PF_TCPS_PROXY_DST || 227 dst->state == PF_TCPS_PROXY_DST) 228 printf("\n PROXY:DST"); 229 else 230 printf("\n <BAD STATE LEVELS %u:%u>", 231 src->state, dst->state); 232 if (opts & PF_OPT_VERBOSE) { 233 printf("\n "); 234 print_seq(src); 235 if (src->wscale && dst->wscale) 236 printf(" wscale %u", 237 src->wscale & PF_WSCALE_MASK); 238 printf(" "); 239 print_seq(dst); 240 if (src->wscale && dst->wscale) 241 printf(" wscale %u", 242 dst->wscale & PF_WSCALE_MASK); 243 } 244 } else if (s->proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES && 245 dst->state < PFUDPS_NSTATES) { 246 const char *states[] = PFUDPS_NAMES; 247 248 printf(" %s:%s", states[src->state], states[dst->state]); 249 } else if (s->proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES && 250 dst->state < PFOTHERS_NSTATES) { 251 /* XXX ICMP doesn't really have state levels */ 252 const char *states[] = PFOTHERS_NAMES; 253 254 printf(" %s:%s", states[src->state], states[dst->state]); 255 } else { 256 printf(" %u:%u", src->state, dst->state); 257 } 258 259 if (opts & PF_OPT_VERBOSE) { 260 u_int64_t packets[2]; 261 u_int64_t bytes[2]; 262 u_int32_t creation = ntohl(s->creation); 263 u_int32_t expire = ntohl(s->expire); 264 265 sec = creation % 60; 266 creation /= 60; 267 min = creation % 60; 268 creation /= 60; 269 printf("\n age %.2u:%.2u:%.2u", creation, min, sec); 270 sec = expire % 60; 271 expire /= 60; 272 min = expire % 60; 273 expire /= 60; 274 printf(", expires in %.2u:%.2u:%.2u", expire, min, sec); 275 276 bcopy(s->packets[0], &packets[0], sizeof(u_int64_t)); 277 bcopy(s->packets[1], &packets[1], sizeof(u_int64_t)); 278 bcopy(s->bytes[0], &bytes[0], sizeof(u_int64_t)); 279 bcopy(s->bytes[1], &bytes[1], sizeof(u_int64_t)); 280 printf(", %llu:%llu pkts, %llu:%llu bytes", 281 betoh64(packets[0]), 282 betoh64(packets[1]), 283 betoh64(bytes[0]), 284 betoh64(bytes[1])); 285 if (s->anchor != -1) 286 printf(", anchor %u", ntohl(s->anchor)); 287 if (s->rule != -1) 288 printf(", rule %u", ntohl(s->rule)); 289 } 290 if (opts & PF_OPT_VERBOSE2) { 291 u_int64_t id; 292 293 bcopy(&s->id, &id, sizeof(u_int64_t)); 294 printf("\n id: %016llx creatorid: %08x", 295 betoh64(id), ntohl(s->creatorid)); 296 } 297 } 298 299 int 300 unmask(struct pf_addr *m, sa_family_t af) 301 { 302 int i = 31, j = 0, b = 0; 303 u_int32_t tmp; 304 305 while (j < 4 && m->addr32[j] == 0xffffffff) { 306 b += 32; 307 j++; 308 } 309 if (j < 4) { 310 tmp = ntohl(m->addr32[j]); 311 for (i = 31; tmp & (1 << i); --i) 312 b++; 313 } 314 return (b); 315 } 316