GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/print-sl.c Lines: 0 94 0.0 %
Date: 2017-11-13 Branches: 0 51 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: print-sl.c,v 1.20 2017/10/30 10:07:44 mpi Exp $	*/
2
3
/*
4
 * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that: (1) source code distributions
9
 * retain the above copyright notice and this paragraph in its entirety, (2)
10
 * distributions including binary code include the above copyright notice and
11
 * this paragraph in its entirety in the documentation or other materials
12
 * provided with the distribution, and (3) all advertising materials mentioning
13
 * features or use of this software display the following acknowledgement:
14
 * ``This product includes software developed by the University of California,
15
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16
 * the University nor the names of its contributors may be used to endorse
17
 * or promote products derived from this software without specific prior
18
 * written permission.
19
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
 */
23
24
#include <sys/time.h>
25
#include <sys/file.h>
26
#include <sys/ioctl.h>
27
#include <sys/socket.h>
28
29
struct rtentry;
30
#include <net/if.h>
31
32
#include <netinet/in.h>
33
#include <netinet/ip.h>
34
#include <netinet/if_ether.h>
35
#include <netinet/udp.h>
36
#include <netinet/tcp.h>
37
38
#include <net/slcompress.h>
39
40
#include <ctype.h>
41
#include <netdb.h>
42
#include <pcap.h>
43
#include <stdio.h>
44
#include <limits.h>
45
46
#include "interface.h"
47
#include "addrtoname.h"
48
#include "extract.h"			/* must come after interface.h */
49
50
static u_int lastlen[2][256];
51
static u_int lastconn = 255;
52
53
static void sliplink_print(const u_char *, const struct ip *, u_int);
54
static void compressed_sl_print(const u_char *, const struct ip *, u_int, int);
55
56
/*
57
 * Definitions of the pseudo-link-level header attached to slip
58
 * packets grabbed by the packet filter (bpf) traffic monitor.
59
 */
60
#define SLIP_HDRLEN	16		/* BPF SLIP header length */
61
62
/* Offsets into BPF SLIP header. */
63
#define SLX_DIR		0		/* direction; see below */
64
#define SLX_CHDR	1		/* compressed header data */
65
#define CHDR_LEN	15		/* length of compressed header data */
66
67
#define SLIPDIR_IN	0		/* incoming */
68
#define SLIPDIR_OUT	1		/* outgoing */
69
70
/* XXX needs more hacking to work right */
71
72
void
73
sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
74
{
75
	u_int caplen = h->caplen;
76
	u_int length = h->len;
77
	const struct ip *ip;
78
79
	ts_print(&h->ts);
80
81
	if (caplen < SLIP_HDRLEN || length < SLIP_HDRLEN) {
82
		printf("[|slip]");
83
		goto out;
84
	}
85
	/*
86
	 * Some printers want to get back at the link level addresses,
87
	 * and/or check that they're not walking off the end of the packet.
88
	 * Rather than pass them all the way down, we set these globals.
89
	 */
90
	packetp = p;
91
	snapend = p + caplen;
92
93
	length -= SLIP_HDRLEN;
94
95
	ip = (struct ip *)(p + SLIP_HDRLEN);
96
97
	if (eflag)
98
		sliplink_print(p, ip, length);
99
100
	switch (ip->ip_v) {
101
	case 4:
102
		ip_print((u_char *)ip, length);
103
		break;
104
#ifdef INET6
105
	case 6:
106
		ip6_print((u_char *)ip, length);
107
		break;
108
#endif
109
	default:
110
		printf ("ip v%d", ip->ip_v);
111
	}
112
113
	if (xflag)
114
		default_print((u_char *)ip, caplen - SLIP_HDRLEN);
115
 out:
116
	putchar('\n');
117
}
118
119
120
void
121
sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
122
{
123
	u_int caplen = h->caplen;
124
	u_int length = h->len;
125
	const struct ip *ip;
126
127
	ts_print(&h->ts);
128
129
	if (caplen < SLIP_HDRLEN) {
130
		printf("[|slip]");
131
		goto out;
132
	}
133
	/*
134
	 * Some printers want to get back at the link level addresses,
135
	 * and/or check that they're not walking off the end of the packet.
136
	 * Rather than pass them all the way down, we set these globals.
137
	 */
138
	packetp = p;
139
	snapend = p + caplen;
140
141
	length -= SLIP_HDRLEN;
142
143
	ip = (struct ip *)(p + SLIP_HDRLEN);
144
145
#ifdef notdef
146
	if (eflag)
147
		sliplink_print(p, ip, length);
148
#endif
149
150
	ip_print((u_char *)ip, length);
151
152
	if (xflag)
153
		default_print((u_char *)ip, caplen - SLIP_HDRLEN);
154
 out:
155
	putchar('\n');
156
}
157
158
static void
159
sliplink_print(const u_char *p, const struct ip *ip, u_int length)
160
{
161
	int dir;
162
	u_int hlen;
163
164
	dir = p[SLX_DIR];
165
	putchar(dir == SLIPDIR_IN ? 'I' : 'O');
166
	putchar(' ');
167
168
	if (nflag) {
169
		/* XXX just dump the header */
170
		int i;
171
172
		for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i)
173
			printf("%02x.", p[i]);
174
		printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]);
175
		return;
176
	}
177
	switch (p[SLX_CHDR] & 0xf0) {
178
179
	case TYPE_IP:
180
		printf("ip %d: ", length + SLIP_HDRLEN);
181
		break;
182
183
	case TYPE_UNCOMPRESSED_TCP:
184
		/*
185
		 * The connection id is stored in the IP protocol field.
186
		 * Get it from the link layer since sl_uncompress_tcp()
187
		 * has restored the IP header copy to IPPROTO_TCP.
188
		 */
189
		lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p;
190
		hlen = ip->ip_hl;
191
		hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
192
		lastlen[dir][lastconn] = length - (hlen << 2);
193
		printf("utcp %d: ", lastconn);
194
		break;
195
196
	default:
197
		if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
198
			compressed_sl_print(&p[SLX_CHDR], ip,
199
			    length, dir);
200
			printf(": ");
201
		} else
202
			printf("slip-%d!: ", p[SLX_CHDR]);
203
	}
204
}
205
206
static const u_char *
207
print_sl_change(const char *str, const u_char *cp)
208
{
209
	u_int i;
210
211
	if ((i = *cp++) == 0) {
212
		i = EXTRACT_16BITS(cp);
213
		cp += 2;
214
	}
215
	printf(" %s%d", str, i);
216
	return (cp);
217
}
218
219
static const u_char *
220
print_sl_winchange(const u_char *cp)
221
{
222
	short i;
223
224
	if ((i = *cp++) == 0) {
225
		i = EXTRACT_16BITS(cp);
226
		cp += 2;
227
	}
228
	if (i >= 0)
229
		printf(" W+%d", i);
230
	else
231
		printf(" W%d", i);
232
	return (cp);
233
}
234
235
static void
236
compressed_sl_print(const u_char *chdr, const struct ip *ip,
237
		    u_int length, int dir)
238
{
239
	const u_char *cp = chdr;
240
	u_int flags, hlen;
241
242
	flags = *cp++;
243
	if (flags & NEW_C) {
244
		lastconn = *cp++;
245
		printf("ctcp %d", lastconn);
246
	} else
247
		printf("ctcp *");
248
249
	/* skip tcp checksum */
250
	cp += 2;
251
252
	switch (flags & SPECIALS_MASK) {
253
	case SPECIAL_I:
254
		printf(" *SA+%d", lastlen[dir][lastconn]);
255
		break;
256
257
	case SPECIAL_D:
258
		printf(" *S+%d", lastlen[dir][lastconn]);
259
		break;
260
261
	default:
262
		if (flags & NEW_U)
263
			cp = print_sl_change("U=", cp);
264
		if (flags & NEW_W)
265
			cp = print_sl_winchange(cp);
266
		if (flags & NEW_A)
267
			cp = print_sl_change("A+", cp);
268
		if (flags & NEW_S)
269
			cp = print_sl_change("S+", cp);
270
		break;
271
	}
272
	if (flags & NEW_I)
273
		cp = print_sl_change("I+", cp);
274
275
	/*
276
	 * 'hlen' is the length of the uncompressed TCP/IP header (in words).
277
	 * 'cp - chdr' is the length of the compressed header.
278
	 * 'length - hlen' is the amount of data in the packet.
279
	 */
280
	hlen = ip->ip_hl;
281
	hlen += ((struct tcphdr *)&((int32_t *)ip)[hlen])->th_off;
282
	lastlen[dir][lastconn] = length - (hlen << 2);
283
	printf(" %d (%d)", lastlen[dir][lastconn], (int)(cp - chdr));
284
}