etc/services - sync with NetBSD-8
[minix.git] / external / bsd / tcpdump / dist / pf_print_state.c
blobd27d933c4262bd2e0902ac17dc7c2c5700cfa5d9
1 /* $NetBSD: pf_print_state.c,v 1.1 2010/12/05 05:11:30 christos Exp $ */
2 /* $OpenBSD: pf_print_state.c,v 1.45 2007/05/31 04:13:37 mcbride Exp $ */
4 /*
5 * Copyright (c) 2001 Daniel Hartmeier
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
12 * - Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
35 #ifndef lint
36 __RCSID("$NetBSD: pf_print_state.c,v 1.1 2010/12/05 05:11:30 christos Exp $");
37 #endif
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #endif
43 #include <sys/types.h>
44 #include <sys/socket.h>
45 #include <net/if.h>
46 #define TCPSTATES
47 #include <netinet/tcp_fsm.h>
48 #include <net/pfvar.h>
49 #include <arpa/inet.h>
50 #include <netdb.h>
52 #include <stdio.h>
53 #include <string.h>
55 #include "pfctl_parser.h"
56 #include "pfctl.h"
58 void print_name(struct pf_addr *, sa_family_t);
60 void
61 print_addr(struct pf_addr_wrap *addr, sa_family_t af, int verbose)
63 switch (addr->type) {
64 case PF_ADDR_DYNIFTL:
65 printf("(%s", addr->v.ifname);
66 if (addr->iflags & PFI_AFLAG_NETWORK)
67 printf(":network");
68 if (addr->iflags & PFI_AFLAG_BROADCAST)
69 printf(":broadcast");
70 if (addr->iflags & PFI_AFLAG_PEER)
71 printf(":peer");
72 if (addr->iflags & PFI_AFLAG_NOALIAS)
73 printf(":0");
74 if (verbose) {
75 if (addr->p.dyncnt <= 0)
76 printf(":*");
77 else
78 printf(":%d", addr->p.dyncnt);
80 printf(")");
81 break;
82 case PF_ADDR_TABLE:
83 if (verbose)
84 if (addr->p.tblcnt == -1)
85 printf("<%s:*>", addr->v.tblname);
86 else
87 printf("<%s:%d>", addr->v.tblname,
88 addr->p.tblcnt);
89 else
90 printf("<%s>", addr->v.tblname);
91 return;
92 case PF_ADDR_ADDRMASK:
93 if (PF_AZERO(&addr->v.a.addr, AF_INET6) &&
94 PF_AZERO(&addr->v.a.mask, AF_INET6))
95 printf("any");
96 else {
97 char buf[48];
99 if (inet_ntop(af, &addr->v.a.addr, buf,
100 sizeof(buf)) == NULL)
101 printf("?");
102 else
103 printf("%s", buf);
105 break;
106 case PF_ADDR_NOROUTE:
107 printf("no-route");
108 return;
109 case PF_ADDR_URPFFAILED:
110 printf("urpf-failed");
111 return;
112 case PF_ADDR_RTLABEL:
113 printf("route \"%s\"", addr->v.rtlabelname);
114 return;
115 default:
116 printf("?");
117 return;
120 /* mask if not _both_ address and mask are zero */
121 if (!(PF_AZERO(&addr->v.a.addr, AF_INET6) &&
122 PF_AZERO(&addr->v.a.mask, AF_INET6))) {
123 int bits = unmask(&addr->v.a.mask, af);
125 if (bits != (af == AF_INET ? 32 : 128))
126 printf("/%d", bits);
130 void
131 print_name(struct pf_addr *addr, sa_family_t af)
133 char host[NI_MAXHOST];
135 strlcpy(host, "?", sizeof(host));
136 switch (af) {
137 case AF_INET: {
138 struct sockaddr_in sin;
140 memset(&sin, 0, sizeof(sin));
141 sin.sin_len = sizeof(sin);
142 sin.sin_family = AF_INET;
143 sin.sin_addr = addr->v4;
144 getnameinfo((struct sockaddr *)&sin, sin.sin_len,
145 host, sizeof(host), NULL, 0, NI_NOFQDN);
146 break;
148 case AF_INET6: {
149 struct sockaddr_in6 sin6;
151 memset(&sin6, 0, sizeof(sin6));
152 sin6.sin6_len = sizeof(sin6);
153 sin6.sin6_family = AF_INET6;
154 sin6.sin6_addr = addr->v6;
155 getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len,
156 host, sizeof(host), NULL, 0, NI_NOFQDN);
157 break;
160 printf("%s", host);
163 void
164 print_host(struct pfsync_state_host *h, sa_family_t af, int opts)
166 u_int16_t p = ntohs(h->port);
168 if (opts & PF_OPT_USEDNS)
169 print_name(&h->addr, af);
170 else {
171 struct pf_addr_wrap aw;
173 memset(&aw, 0, sizeof(aw));
174 aw.v.a.addr = h->addr;
175 if (af == AF_INET)
176 aw.v.a.mask.addr32[0] = 0xffffffff;
177 else {
178 memset(&aw.v.a.mask, 0xff, sizeof(aw.v.a.mask));
179 af = AF_INET6;
181 print_addr(&aw, af, opts & PF_OPT_VERBOSE2);
184 if (p) {
185 if (af == AF_INET)
186 printf(":%u", p);
187 else
188 printf("[%u]", p);
192 void
193 print_seq(struct pfsync_state_peer *p)
195 if (p->seqdiff)
196 printf("[%u + %u](+%u)", p->seqlo, p->seqhi - p->seqlo,
197 p->seqdiff);
198 else
199 printf("[%u + %u]", p->seqlo, p->seqhi - p->seqlo);
202 void
203 print_state(struct pfsync_state *s, int opts)
205 struct pfsync_state_peer *src, *dst;
206 struct protoent *p;
207 int min, sec;
209 if (s->direction == PF_OUT) {
210 src = &s->src;
211 dst = &s->dst;
212 } else {
213 src = &s->dst;
214 dst = &s->src;
216 printf("%s ", s->ifname);
217 if ((p = getprotobynumber(s->proto)) != NULL)
218 printf("%s ", p->p_name);
219 else
220 printf("%u ", s->proto);
221 if (PF_ANEQ(&s->lan.addr, &s->gwy.addr, s->af) ||
222 (s->lan.port != s->gwy.port)) {
223 print_host(&s->lan, s->af, opts);
224 if (s->direction == PF_OUT)
225 printf(" -> ");
226 else
227 printf(" <- ");
229 print_host(&s->gwy, s->af, opts);
230 if (s->direction == PF_OUT)
231 printf(" -> ");
232 else
233 printf(" <- ");
234 print_host(&s->ext, s->af, opts);
236 printf(" ");
237 if (s->proto == IPPROTO_TCP) {
238 if (src->state <= TCPS_TIME_WAIT &&
239 dst->state <= TCPS_TIME_WAIT)
240 printf(" %s:%s\n", tcpstates[src->state],
241 tcpstates[dst->state]);
242 else if (src->state == PF_TCPS_PROXY_SRC ||
243 dst->state == PF_TCPS_PROXY_SRC)
244 printf(" PROXY:SRC\n");
245 else if (src->state == PF_TCPS_PROXY_DST ||
246 dst->state == PF_TCPS_PROXY_DST)
247 printf(" PROXY:DST\n");
248 else
249 printf(" <BAD STATE LEVELS %u:%u>\n",
250 src->state, dst->state);
251 if (opts & PF_OPT_VERBOSE) {
252 printf(" ");
253 print_seq(src);
254 if (src->wscale && dst->wscale)
255 printf(" wscale %u",
256 src->wscale & PF_WSCALE_MASK);
257 printf(" ");
258 print_seq(dst);
259 if (src->wscale && dst->wscale)
260 printf(" wscale %u",
261 dst->wscale & PF_WSCALE_MASK);
262 printf("\n");
264 } else if (s->proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
265 dst->state < PFUDPS_NSTATES) {
266 const char *states[] = PFUDPS_NAMES;
268 printf(" %s:%s\n", states[src->state], states[dst->state]);
269 } else if (s->proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
270 dst->state < PFOTHERS_NSTATES) {
271 /* XXX ICMP doesn't really have state levels */
272 const char *states[] = PFOTHERS_NAMES;
274 printf(" %s:%s\n", states[src->state], states[dst->state]);
275 } else {
276 printf(" %u:%u\n", src->state, dst->state);
279 if (opts & PF_OPT_VERBOSE) {
280 sec = s->creation % 60;
281 s->creation /= 60;
282 min = s->creation % 60;
283 s->creation /= 60;
284 printf(" age %.2u:%.2u:%.2u", s->creation, min, sec);
285 sec = s->expire % 60;
286 s->expire /= 60;
287 min = s->expire % 60;
288 s->expire /= 60;
289 printf(", expires in %.2u:%.2u:%.2u", s->expire, min, sec);
290 printf(", %llu:%llu pkts, %llu:%llu bytes",
291 (unsigned long long)pf_state_counter_from_pfsync(s->packets[0]),
292 (unsigned long long)pf_state_counter_from_pfsync(s->packets[1]),
293 (unsigned long long)pf_state_counter_from_pfsync(s->bytes[0]),
294 (unsigned long long)pf_state_counter_from_pfsync(s->bytes[1]));
295 if (s->anchor != -1)
296 printf(", anchor %u", s->anchor);
297 if (s->rule != -1)
298 printf(", rule %u", s->rule);
299 if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
300 printf(", source-track");
301 if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)
302 printf(", sticky-address");
303 printf("\n");
305 if (opts & PF_OPT_VERBOSE2) {
306 printf(" id: %016llx creatorid: %08x%s\n",
307 (unsigned long long int)pf_state_counter_from_pfsync(s->id),
308 ntohl(s->creatorid),
309 ((s->sync_flags & PFSTATE_NOSYNC) ? " (no-sync)" : ""));
314 unmask(struct pf_addr *m, sa_family_t af)
316 int i = 31, j = 0, b = 0;
317 u_int32_t tmp;
319 while (j < 4 && m->addr32[j] == 0xffffffff) {
320 b += 32;
321 j++;
323 if (j < 4) {
324 tmp = ntohl(m->addr32[j]);
325 for (i = 31; tmp & (1 << i); --i)
326 b++;
328 return (b);