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

Line Branch Exec Source
1
/*	$OpenBSD: print-ip6.c,v 1.24 2016/12/13 06:40:21 dlg Exp $	*/
2
3
/*
4
 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
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
#ifdef INET6
25
26
#include <sys/time.h>
27
#include <sys/types.h>
28
#include <sys/socket.h>
29
30
#include <netinet/in.h>
31
#include <netinet/ip.h>
32
#include <netinet/ip_var.h>
33
#include <netinet/udp.h>
34
#include <netinet/udp_var.h>
35
#include <netinet/tcp.h>
36
37
#include <inttypes.h>
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include <unistd.h>
42
43
#include "interface.h"
44
#include "addrtoname.h"
45
46
#include <netinet/ip6.h>
47
48
/*
49
 * print an IP6 datagram.
50
 */
51
void
52
ip6_print(const u_char *bp, u_int length)
53
{
54
	const struct ip6_hdr *ip6;
55
	int hlen;
56
	int len;
57
	const u_char *cp;
58
	const u_char *pktp = packetp;
59
	const u_char *send = snapend;
60
	int nh;
61
	u_int flow;
62
63
	ip6 = (const struct ip6_hdr *)bp;
64
	if ((u_char *)(ip6 + 1) > snapend) {
65
		printf("[|ip6]");
66
		return;
67
	}
68
69
	/*
70
	 * The IP header is not word aligned, so copy into abuf.
71
	 * This will never happen with BPF.  It does happen with
72
	 * raw packet dumps from -r.
73
	 */
74
	if ((intptr_t)ip6 & (sizeof(u_int32_t)-1)) {
75
		static u_char *abuf = NULL;
76
		static int didwarn = 0;
77
		int clen = snapend - bp;
78
		if (clen > snaplen)
79
			clen = snaplen;
80
81
		if (abuf == NULL) {
82
			abuf = malloc(snaplen);
83
			if (abuf == NULL)
84
				error("ip6_print: malloc");
85
		}
86
		memmove((char *)abuf, (char *)ip6, min(length, clen));
87
		snapend = abuf + clen;
88
		packetp = bp = abuf;
89
		ip6 = (struct ip6_hdr *)abuf;
90
		/* We really want libpcap to give us aligned packets */
91
		if (!didwarn) {
92
			warning("compensating for unaligned libpcap packets");
93
			++didwarn;
94
		}
95
	}
96
97
	if (length < sizeof (struct ip6_hdr)) {
98
		(void)printf("truncated-ip6 %d", length);
99
		goto out;
100
	}
101
	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
102
		(void)printf("bad-ip6-version %u", ip6->ip6_vfc >> 4);
103
		goto out;
104
	}
105
	hlen = sizeof(struct ip6_hdr);
106
107
	len = ntohs(ip6->ip6_plen);
108
	if (length < len + hlen)
109
		(void)printf("truncated-ip6 - %d bytes missing!",
110
			len + hlen - length);
111
112
	cp = (const u_char *)ip6;
113
	nh = ip6->ip6_nxt;
114
	while (cp + hlen <= snapend) {
115
		cp += hlen;
116
117
#ifndef IPPROTO_IPV4
118
#define IPPROTO_IPV4	4
119
#endif
120
		if (cp == (u_char *)(ip6 + 1) &&
121
		    nh != IPPROTO_TCP && nh != IPPROTO_UDP &&
122
		    nh != IPPROTO_ESP && nh != IPPROTO_AH &&
123
		    (vflag || (nh != IPPROTO_IPV4 && nh != IPPROTO_IPV6))) {
124
			(void)printf("%s > %s: ", ip6addr_string(&ip6->ip6_src),
125
				     ip6addr_string(&ip6->ip6_dst));
126
		}
127
128
		switch (nh) {
129
		case IPPROTO_HOPOPTS:
130
			hlen = hbhopt_print(cp);
131
			nh = *cp;
132
			break;
133
		case IPPROTO_DSTOPTS:
134
			hlen = dstopt_print(cp);
135
			nh = *cp;
136
			break;
137
		case IPPROTO_FRAGMENT:
138
			hlen = frag6_print(cp, (const u_char *)ip6);
139
			if (snapend < cp + hlen)
140
				goto end;
141
			nh = *cp;
142
			break;
143
		case IPPROTO_ROUTING:
144
			hlen = rt6_print(cp, (const u_char *)ip6);
145
			nh = *cp;
146
			break;
147
		case IPPROTO_TCP:
148
			tcp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp),
149
				(const u_char *)ip6);
150
			goto end;
151
		case IPPROTO_UDP:
152
			udp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp),
153
				(const u_char *)ip6);
154
			goto end;
155
		case IPPROTO_ESP:
156
			esp_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp),
157
				(const u_char *)ip6);
158
			goto end;
159
		case IPPROTO_AH:
160
			ah_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp),
161
				(const u_char *)ip6);
162
			goto end;
163
		case IPPROTO_ICMPV6:
164
			icmp6_print(cp, len + sizeof(struct ip6_hdr) - (cp - bp),
165
				(const u_char *)ip6);
166
			goto end;
167
		case IPPROTO_PIM:
168
			(void)printf("PIM");
169
			pim_print(cp, len);
170
			goto end;
171
#ifndef IPPROTO_OSPF
172
#define IPPROTO_OSPF 89
173
#endif
174
		case IPPROTO_OSPF:
175
			ospf6_print(cp, len);
176
			goto end;
177
		case IPPROTO_IPV6:
178
			ip6_print(cp, len);
179
			if (! vflag)
180
				printf(" (encap)");
181
			goto end;
182
		case IPPROTO_IPV4:
183
			ip_print(cp, len);
184
			if (! vflag)
185
				printf(" (encap)");
186
			goto end;
187
188
#ifndef IPPROTO_GRE
189
#define IPPROTO_GRE 47
190
#endif
191
		case IPPROTO_GRE:
192
			gre_print(cp, len);
193
			if (! vflag) {
194
				printf(" (gre encap)");
195
				goto out;
196
			}
197
			goto end;
198
199
		case IPPROTO_NONE:
200
			(void)printf("no next header");
201
			goto end;
202
203
#ifndef IPPROTO_CARP
204
#define IPPROTO_CARP 112
205
#endif
206
		case IPPROTO_CARP:
207
			if (packettype == PT_VRRP)
208
				vrrp_print(cp, len, ip6->ip6_hlim);
209
			else
210
				carp_print(cp, len, ip6->ip6_hlim);
211
			break;
212
213
		default:
214
			(void)printf("ip-proto-%d %d", ip6->ip6_nxt, len);
215
			goto end;
216
		}
217
		if (hlen == 0)
218
			break;
219
	}
220
221
 end:
222
223
	flow = ntohl(ip6->ip6_flow);
224
#if 0
225
	/* rfc1883 */
226
	if (flow & 0x0f000000)
227
		(void)printf(" [pri 0x%x]", (flow & 0x0f000000) >> 24);
228
	if (flow & 0x00ffffff)
229
		(void)printf(" [flowlabel 0x%x]", flow & 0x00ffffff);
230
#else
231
	/* RFC 2460 */
232
	if (flow & 0x0ff00000)
233
		(void)printf(" [class 0x%x]", (flow & 0x0ff00000) >> 20);
234
	if (flow & 0x000fffff)
235
		(void)printf(" [flowlabel 0x%x]", flow & 0x000fffff);
236
#endif
237
238
	if (ip6->ip6_hlim <= 1)
239
		(void)printf(" [hlim %d]", (int)ip6->ip6_hlim);
240
241
	if (vflag) {
242
		printf(" (");
243
		(void)printf("len %d", len);
244
		if (ip6->ip6_hlim > 1)
245
			(void)printf(", hlim %d", (int)ip6->ip6_hlim);
246
		printf(")");
247
	}
248
249
 out:
250
	packetp = pktp;
251
	snapend = send;
252
}
253
254
#endif /* INET6 */