GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/pf_print_state.c Lines: 0 179 0.0 %
Date: 2017-11-07 Branches: 0 182 0.0 %

Line Branch Exec Source
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
}