print-ip.c revision 1.1 1 1.1 christos /*
2 1.1 christos * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 1.1 christos * The Regents of the University of California. All rights reserved.
4 1.1 christos *
5 1.1 christos * Redistribution and use in source and binary forms, with or without
6 1.1 christos * modification, are permitted provided that: (1) source code distributions
7 1.1 christos * retain the above copyright notice and this paragraph in its entirety, (2)
8 1.1 christos * distributions including binary code include the above copyright notice and
9 1.1 christos * this paragraph in its entirety in the documentation or other materials
10 1.1 christos * provided with the distribution, and (3) all advertising materials mentioning
11 1.1 christos * features or use of this software display the following acknowledgement:
12 1.1 christos * ``This product includes software developed by the University of California,
13 1.1 christos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 1.1 christos * the University nor the names of its contributors may be used to endorse
15 1.1 christos * or promote products derived from this software without specific prior
16 1.1 christos * written permission.
17 1.1 christos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 1.1 christos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 1.1 christos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 1.1 christos */
21 1.1 christos
22 1.1 christos #ifndef lint
23 1.1 christos static const char rcsid[] _U_ =
24 1.1 christos "@(#) Header: /tcpdump/master/tcpdump/print-ip.c,v 1.159 2007-09-14 01:29:28 guy Exp (LBL)";
25 1.1 christos #endif
26 1.1 christos
27 1.1 christos #ifdef HAVE_CONFIG_H
28 1.1 christos #include "config.h"
29 1.1 christos #endif
30 1.1 christos
31 1.1 christos #include <tcpdump-stdinc.h>
32 1.1 christos
33 1.1 christos #include <stdio.h>
34 1.1 christos #include <stdlib.h>
35 1.1 christos #include <string.h>
36 1.1 christos
37 1.1 christos #include "addrtoname.h"
38 1.1 christos #include "interface.h"
39 1.1 christos #include "extract.h" /* must come after interface.h */
40 1.1 christos
41 1.1 christos #include "ip.h"
42 1.1 christos #include "ipproto.h"
43 1.1 christos
44 1.1 christos struct tok ip_option_values[] = {
45 1.1 christos { IPOPT_EOL, "EOL" },
46 1.1 christos { IPOPT_NOP, "NOP" },
47 1.1 christos { IPOPT_TS, "timestamp" },
48 1.1 christos { IPOPT_SECURITY, "security" },
49 1.1 christos { IPOPT_RR, "RR" },
50 1.1 christos { IPOPT_SSRR, "SSRR" },
51 1.1 christos { IPOPT_LSRR, "LSRR" },
52 1.1 christos { IPOPT_RA, "RA" },
53 1.1 christos { IPOPT_RFC1393, "traceroute" },
54 1.1 christos { 0, NULL }
55 1.1 christos };
56 1.1 christos
57 1.1 christos /*
58 1.1 christos * print the recorded route in an IP RR, LSRR or SSRR option.
59 1.1 christos */
60 1.1 christos static void
61 1.1 christos ip_printroute(register const u_char *cp, u_int length)
62 1.1 christos {
63 1.1 christos register u_int ptr;
64 1.1 christos register u_int len;
65 1.1 christos
66 1.1 christos if (length < 3) {
67 1.1 christos printf(" [bad length %u]", length);
68 1.1 christos return;
69 1.1 christos }
70 1.1 christos if ((length + 1) & 3)
71 1.1 christos printf(" [bad length %u]", length);
72 1.1 christos ptr = cp[2] - 1;
73 1.1 christos if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
74 1.1 christos printf(" [bad ptr %u]", cp[2]);
75 1.1 christos
76 1.1 christos for (len = 3; len < length; len += 4) {
77 1.1 christos printf(" %s", ipaddr_string(&cp[len]));
78 1.1 christos if (ptr > len)
79 1.1 christos printf(",");
80 1.1 christos }
81 1.1 christos }
82 1.1 christos
83 1.1 christos /*
84 1.1 christos * If source-routing is present and valid, return the final destination.
85 1.1 christos * Otherwise, return IP destination.
86 1.1 christos *
87 1.1 christos * This is used for UDP and TCP pseudo-header in the checksum
88 1.1 christos * calculation.
89 1.1 christos */
90 1.1 christos u_int32_t
91 1.1 christos ip_finddst(const struct ip *ip)
92 1.1 christos {
93 1.1 christos int length;
94 1.1 christos int len;
95 1.1 christos const u_char *cp;
96 1.1 christos u_int32_t retval;
97 1.1 christos
98 1.1 christos cp = (const u_char *)(ip + 1);
99 1.1 christos length = (IP_HL(ip) << 2) - sizeof(struct ip);
100 1.1 christos
101 1.1 christos for (; length > 0; cp += len, length -= len) {
102 1.1 christos int tt;
103 1.1 christos
104 1.1 christos TCHECK(*cp);
105 1.1 christos tt = *cp;
106 1.1 christos if (tt == IPOPT_EOL)
107 1.1 christos break;
108 1.1 christos else if (tt == IPOPT_NOP)
109 1.1 christos len = 1;
110 1.1 christos else {
111 1.1 christos TCHECK(cp[1]);
112 1.1 christos len = cp[1];
113 1.1 christos if (len < 2)
114 1.1 christos break;
115 1.1 christos }
116 1.1 christos TCHECK2(*cp, len);
117 1.1 christos switch (tt) {
118 1.1 christos
119 1.1 christos case IPOPT_SSRR:
120 1.1 christos case IPOPT_LSRR:
121 1.1 christos if (len < 7)
122 1.1 christos break;
123 1.1 christos memcpy(&retval, cp + len - 4, 4);
124 1.1 christos return retval;
125 1.1 christos }
126 1.1 christos }
127 1.1 christos trunc:
128 1.1 christos memcpy(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t));
129 1.1 christos return retval;
130 1.1 christos }
131 1.1 christos
132 1.1 christos static void
133 1.1 christos ip_printts(register const u_char *cp, u_int length)
134 1.1 christos {
135 1.1 christos register u_int ptr;
136 1.1 christos register u_int len;
137 1.1 christos int hoplen;
138 1.1 christos const char *type;
139 1.1 christos
140 1.1 christos if (length < 4) {
141 1.1 christos printf("[bad length %u]", length);
142 1.1 christos return;
143 1.1 christos }
144 1.1 christos printf(" TS{");
145 1.1 christos hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
146 1.1 christos if ((length - 4) & (hoplen-1))
147 1.1 christos printf("[bad length %u]", length);
148 1.1 christos ptr = cp[2] - 1;
149 1.1 christos len = 0;
150 1.1 christos if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
151 1.1 christos printf("[bad ptr %u]", cp[2]);
152 1.1 christos switch (cp[3]&0xF) {
153 1.1 christos case IPOPT_TS_TSONLY:
154 1.1 christos printf("TSONLY");
155 1.1 christos break;
156 1.1 christos case IPOPT_TS_TSANDADDR:
157 1.1 christos printf("TS+ADDR");
158 1.1 christos break;
159 1.1 christos /*
160 1.1 christos * prespecified should really be 3, but some ones might send 2
161 1.1 christos * instead, and the IPOPT_TS_PRESPEC constant can apparently
162 1.1 christos * have both values, so we have to hard-code it here.
163 1.1 christos */
164 1.1 christos
165 1.1 christos case 2:
166 1.1 christos printf("PRESPEC2.0");
167 1.1 christos break;
168 1.1 christos case 3: /* IPOPT_TS_PRESPEC */
169 1.1 christos printf("PRESPEC");
170 1.1 christos break;
171 1.1 christos default:
172 1.1 christos printf("[bad ts type %d]", cp[3]&0xF);
173 1.1 christos goto done;
174 1.1 christos }
175 1.1 christos
176 1.1 christos type = " ";
177 1.1 christos for (len = 4; len < length; len += hoplen) {
178 1.1 christos if (ptr == len)
179 1.1 christos type = " ^ ";
180 1.1 christos printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
181 1.1 christos hoplen!=8 ? "" : ipaddr_string(&cp[len]));
182 1.1 christos type = " ";
183 1.1 christos }
184 1.1 christos
185 1.1 christos done:
186 1.1 christos printf("%s", ptr == len ? " ^ " : "");
187 1.1 christos
188 1.1 christos if (cp[3]>>4)
189 1.1 christos printf(" [%d hops not recorded]} ", cp[3]>>4);
190 1.1 christos else
191 1.1 christos printf("}");
192 1.1 christos }
193 1.1 christos
194 1.1 christos /*
195 1.1 christos * print IP options.
196 1.1 christos */
197 1.1 christos static void
198 1.1 christos ip_optprint(register const u_char *cp, u_int length)
199 1.1 christos {
200 1.1 christos register u_int option_len;
201 1.1 christos const char *sep = "";
202 1.1 christos
203 1.1 christos for (; length > 0; cp += option_len, length -= option_len) {
204 1.1 christos u_int option_code;
205 1.1 christos
206 1.1 christos printf("%s", sep);
207 1.1 christos sep = ",";
208 1.1 christos
209 1.1 christos TCHECK(*cp);
210 1.1 christos option_code = *cp;
211 1.1 christos
212 1.1 christos printf("%s",
213 1.1 christos tok2str(ip_option_values,"unknown %u",option_code));
214 1.1 christos
215 1.1 christos if (option_code == IPOPT_NOP ||
216 1.1 christos option_code == IPOPT_EOL)
217 1.1 christos option_len = 1;
218 1.1 christos
219 1.1 christos else {
220 1.1 christos TCHECK(cp[1]);
221 1.1 christos option_len = cp[1];
222 1.1 christos if (option_len < 2) {
223 1.1 christos printf(" [bad length %u]", option_len);
224 1.1 christos return;
225 1.1 christos }
226 1.1 christos }
227 1.1 christos
228 1.1 christos if (option_len > length) {
229 1.1 christos printf(" [bad length %u]", option_len);
230 1.1 christos return;
231 1.1 christos }
232 1.1 christos
233 1.1 christos TCHECK2(*cp, option_len);
234 1.1 christos
235 1.1 christos switch (option_code) {
236 1.1 christos case IPOPT_EOL:
237 1.1 christos return;
238 1.1 christos
239 1.1 christos case IPOPT_TS:
240 1.1 christos ip_printts(cp, option_len);
241 1.1 christos break;
242 1.1 christos
243 1.1 christos case IPOPT_RR: /* fall through */
244 1.1 christos case IPOPT_SSRR:
245 1.1 christos case IPOPT_LSRR:
246 1.1 christos ip_printroute(cp, option_len);
247 1.1 christos break;
248 1.1 christos
249 1.1 christos case IPOPT_RA:
250 1.1 christos if (option_len < 4) {
251 1.1 christos printf(" [bad length %u]", option_len);
252 1.1 christos break;
253 1.1 christos }
254 1.1 christos TCHECK(cp[3]);
255 1.1 christos if (EXTRACT_16BITS(&cp[2]) != 0)
256 1.1 christos printf(" value %u", EXTRACT_16BITS(&cp[2]));
257 1.1 christos break;
258 1.1 christos
259 1.1 christos case IPOPT_NOP: /* nothing to print - fall through */
260 1.1 christos case IPOPT_SECURITY:
261 1.1 christos default:
262 1.1 christos break;
263 1.1 christos }
264 1.1 christos }
265 1.1 christos return;
266 1.1 christos
267 1.1 christos trunc:
268 1.1 christos printf("[|ip]");
269 1.1 christos }
270 1.1 christos
271 1.1 christos /*
272 1.1 christos * compute an IP header checksum.
273 1.1 christos * don't modifiy the packet.
274 1.1 christos */
275 1.1 christos u_short
276 1.1 christos in_cksum(const u_short *addr, register u_int len, int csum)
277 1.1 christos {
278 1.1 christos int nleft = len;
279 1.1 christos const u_short *w = addr;
280 1.1 christos u_short answer;
281 1.1 christos int sum = csum;
282 1.1 christos
283 1.1 christos /*
284 1.1 christos * Our algorithm is simple, using a 32 bit accumulator (sum),
285 1.1 christos * we add sequential 16 bit words to it, and at the end, fold
286 1.1 christos * back all the carry bits from the top 16 bits into the lower
287 1.1 christos * 16 bits.
288 1.1 christos */
289 1.1 christos while (nleft > 1) {
290 1.1 christos sum += *w++;
291 1.1 christos nleft -= 2;
292 1.1 christos }
293 1.1 christos if (nleft == 1)
294 1.1 christos sum += htons(*(u_char *)w<<8);
295 1.1 christos
296 1.1 christos /*
297 1.1 christos * add back carry outs from top 16 bits to low 16 bits
298 1.1 christos */
299 1.1 christos sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
300 1.1 christos sum += (sum >> 16); /* add carry */
301 1.1 christos answer = ~sum; /* truncate to 16 bits */
302 1.1 christos return (answer);
303 1.1 christos }
304 1.1 christos
305 1.1 christos /*
306 1.1 christos * Given the host-byte-order value of the checksum field in a packet
307 1.1 christos * header, and the network-byte-order computed checksum of the data
308 1.1 christos * that the checksum covers (including the checksum itself), compute
309 1.1 christos * what the checksum field *should* have been.
310 1.1 christos */
311 1.1 christos u_int16_t
312 1.1 christos in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum)
313 1.1 christos {
314 1.1 christos u_int32_t shouldbe;
315 1.1 christos
316 1.1 christos /*
317 1.1 christos * The value that should have gone into the checksum field
318 1.1 christos * is the negative of the value gotten by summing up everything
319 1.1 christos * *but* the checksum field.
320 1.1 christos *
321 1.1 christos * We can compute that by subtracting the value of the checksum
322 1.1 christos * field from the sum of all the data in the packet, and then
323 1.1 christos * computing the negative of that value.
324 1.1 christos *
325 1.1 christos * "sum" is the value of the checksum field, and "computed_sum"
326 1.1 christos * is the negative of the sum of all the data in the packets,
327 1.1 christos * so that's -(-computed_sum - sum), or (sum + computed_sum).
328 1.1 christos *
329 1.1 christos * All the arithmetic in question is one's complement, so the
330 1.1 christos * addition must include an end-around carry; we do this by
331 1.1 christos * doing the arithmetic in 32 bits (with no sign-extension),
332 1.1 christos * and then adding the upper 16 bits of the sum, which contain
333 1.1 christos * the carry, to the lower 16 bits of the sum, and then do it
334 1.1 christos * again in case *that* sum produced a carry.
335 1.1 christos *
336 1.1 christos * As RFC 1071 notes, the checksum can be computed without
337 1.1 christos * byte-swapping the 16-bit words; summing 16-bit words
338 1.1 christos * on a big-endian machine gives a big-endian checksum, which
339 1.1 christos * can be directly stuffed into the big-endian checksum fields
340 1.1 christos * in protocol headers, and summing words on a little-endian
341 1.1 christos * machine gives a little-endian checksum, which must be
342 1.1 christos * byte-swapped before being stuffed into a big-endian checksum
343 1.1 christos * field.
344 1.1 christos *
345 1.1 christos * "computed_sum" is a network-byte-order value, so we must put
346 1.1 christos * it in host byte order before subtracting it from the
347 1.1 christos * host-byte-order value from the header; the adjusted checksum
348 1.1 christos * will be in host byte order, which is what we'll return.
349 1.1 christos */
350 1.1 christos shouldbe = sum;
351 1.1 christos shouldbe += ntohs(computed_sum);
352 1.1 christos shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
353 1.1 christos shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
354 1.1 christos return shouldbe;
355 1.1 christos }
356 1.1 christos
357 1.1 christos #define IP_RES 0x8000
358 1.1 christos
359 1.1 christos static struct tok ip_frag_values[] = {
360 1.1 christos { IP_MF, "+" },
361 1.1 christos { IP_DF, "DF" },
362 1.1 christos { IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */
363 1.1 christos { 0, NULL }
364 1.1 christos };
365 1.1 christos
366 1.1 christos struct ip_print_demux_state {
367 1.1 christos const struct ip *ip;
368 1.1 christos const u_char *cp;
369 1.1 christos u_int len, off;
370 1.1 christos u_char nh;
371 1.1 christos int advance;
372 1.1 christos };
373 1.1 christos
374 1.1 christos static void
375 1.1 christos ip_print_demux(netdissect_options *ndo,
376 1.1 christos struct ip_print_demux_state *ipds)
377 1.1 christos {
378 1.1 christos struct protoent *proto;
379 1.1 christos
380 1.1 christos again:
381 1.1 christos switch (ipds->nh) {
382 1.1 christos
383 1.1 christos case IPPROTO_AH:
384 1.1 christos ipds->nh = *ipds->cp;
385 1.1 christos ipds->advance = ah_print(ipds->cp);
386 1.1 christos if (ipds->advance <= 0)
387 1.1 christos break;
388 1.1 christos ipds->cp += ipds->advance;
389 1.1 christos ipds->len -= ipds->advance;
390 1.1 christos goto again;
391 1.1 christos
392 1.1 christos case IPPROTO_ESP:
393 1.1 christos {
394 1.1 christos int enh, padlen;
395 1.1 christos ipds->advance = esp_print(ndo, ipds->cp, ipds->len,
396 1.1 christos (const u_char *)ipds->ip,
397 1.1 christos &enh, &padlen);
398 1.1 christos if (ipds->advance <= 0)
399 1.1 christos break;
400 1.1 christos ipds->cp += ipds->advance;
401 1.1 christos ipds->len -= ipds->advance + padlen;
402 1.1 christos ipds->nh = enh & 0xff;
403 1.1 christos goto again;
404 1.1 christos }
405 1.1 christos
406 1.1 christos case IPPROTO_IPCOMP:
407 1.1 christos {
408 1.1 christos int enh;
409 1.1 christos ipds->advance = ipcomp_print(ipds->cp, &enh);
410 1.1 christos if (ipds->advance <= 0)
411 1.1 christos break;
412 1.1 christos ipds->cp += ipds->advance;
413 1.1 christos ipds->len -= ipds->advance;
414 1.1 christos ipds->nh = enh & 0xff;
415 1.1 christos goto again;
416 1.1 christos }
417 1.1 christos
418 1.1 christos case IPPROTO_SCTP:
419 1.1 christos sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
420 1.1 christos break;
421 1.1 christos
422 1.1 christos case IPPROTO_DCCP:
423 1.1 christos dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
424 1.1 christos break;
425 1.1 christos
426 1.1 christos case IPPROTO_TCP:
427 1.1 christos /* pass on the MF bit plus the offset to detect fragments */
428 1.1 christos tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
429 1.1 christos ipds->off & (IP_MF|IP_OFFMASK));
430 1.1 christos break;
431 1.1 christos
432 1.1 christos case IPPROTO_UDP:
433 1.1 christos /* pass on the MF bit plus the offset to detect fragments */
434 1.1 christos udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
435 1.1 christos ipds->off & (IP_MF|IP_OFFMASK));
436 1.1 christos break;
437 1.1 christos
438 1.1 christos case IPPROTO_ICMP:
439 1.1 christos /* pass on the MF bit plus the offset to detect fragments */
440 1.1 christos icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
441 1.1 christos ipds->off & (IP_MF|IP_OFFMASK));
442 1.1 christos break;
443 1.1 christos
444 1.1 christos case IPPROTO_PIGP:
445 1.1 christos /*
446 1.1 christos * XXX - the current IANA protocol number assignments
447 1.1 christos * page lists 9 as "any private interior gateway
448 1.1 christos * (used by Cisco for their IGRP)" and 88 as
449 1.1 christos * "EIGRP" from Cisco.
450 1.1 christos *
451 1.1 christos * Recent BSD <netinet/in.h> headers define
452 1.1 christos * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88.
453 1.1 christos * We define IP_PROTO_PIGP as 9 and
454 1.1 christos * IP_PROTO_EIGRP as 88; those names better
455 1.1 christos * match was the current protocol number
456 1.1 christos * assignments say.
457 1.1 christos */
458 1.1 christos igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
459 1.1 christos break;
460 1.1 christos
461 1.1 christos case IPPROTO_EIGRP:
462 1.1 christos eigrp_print(ipds->cp, ipds->len);
463 1.1 christos break;
464 1.1 christos
465 1.1 christos case IPPROTO_ND:
466 1.1 christos ND_PRINT((ndo, " nd %d", ipds->len));
467 1.1 christos break;
468 1.1 christos
469 1.1 christos case IPPROTO_EGP:
470 1.1 christos egp_print(ipds->cp, ipds->len);
471 1.1 christos break;
472 1.1 christos
473 1.1 christos case IPPROTO_OSPF:
474 1.1 christos ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
475 1.1 christos break;
476 1.1 christos
477 1.1 christos case IPPROTO_IGMP:
478 1.1 christos igmp_print(ipds->cp, ipds->len);
479 1.1 christos break;
480 1.1 christos
481 1.1 christos case IPPROTO_IPV4:
482 1.1 christos /* DVMRP multicast tunnel (ip-in-ip encapsulation) */
483 1.1 christos ip_print(gndo, ipds->cp, ipds->len);
484 1.1 christos if (! vflag) {
485 1.1 christos ND_PRINT((ndo, " (ipip-proto-4)"));
486 1.1 christos return;
487 1.1 christos }
488 1.1 christos break;
489 1.1 christos
490 1.1 christos #ifdef INET6
491 1.1 christos case IPPROTO_IPV6:
492 1.1 christos /* ip6-in-ip encapsulation */
493 1.1 christos ip6_print(ipds->cp, ipds->len);
494 1.1 christos break;
495 1.1 christos #endif /*INET6*/
496 1.1 christos
497 1.1 christos case IPPROTO_RSVP:
498 1.1 christos rsvp_print(ipds->cp, ipds->len);
499 1.1 christos break;
500 1.1 christos
501 1.1 christos case IPPROTO_GRE:
502 1.1 christos /* do it */
503 1.1 christos gre_print(ipds->cp, ipds->len);
504 1.1 christos break;
505 1.1 christos
506 1.1 christos case IPPROTO_MOBILE:
507 1.1 christos mobile_print(ipds->cp, ipds->len);
508 1.1 christos break;
509 1.1 christos
510 1.1 christos case IPPROTO_PIM:
511 1.1 christos pim_print(ipds->cp, ipds->len,
512 1.1 christos in_cksum((const u_short*)ipds->cp, ipds->len, 0));
513 1.1 christos break;
514 1.1 christos
515 1.1 christos case IPPROTO_VRRP:
516 1.1 christos vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
517 1.1 christos break;
518 1.1 christos
519 1.1 christos case IPPROTO_PGM:
520 1.1 christos pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
521 1.1 christos break;
522 1.1 christos
523 1.1 christos default:
524 1.1 christos if ((proto = getprotobynumber(ipds->nh)) != NULL)
525 1.1 christos ND_PRINT((ndo, " %s", proto->p_name));
526 1.1 christos else
527 1.1 christos ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
528 1.1 christos ND_PRINT((ndo, " %d", ipds->len));
529 1.1 christos break;
530 1.1 christos }
531 1.1 christos }
532 1.1 christos
533 1.1 christos void
534 1.1 christos ip_print_inner(netdissect_options *ndo,
535 1.1 christos const u_char *bp,
536 1.1 christos u_int length, u_int nh,
537 1.1 christos const u_char *bp2)
538 1.1 christos {
539 1.1 christos struct ip_print_demux_state ipd;
540 1.1 christos
541 1.1 christos ipd.ip = (const struct ip *)bp2;
542 1.1 christos ipd.cp = bp;
543 1.1 christos ipd.len = length;
544 1.1 christos ipd.off = 0;
545 1.1 christos ipd.nh = nh;
546 1.1 christos ipd.advance = 0;
547 1.1 christos
548 1.1 christos ip_print_demux(ndo, &ipd);
549 1.1 christos }
550 1.1 christos
551 1.1 christos
552 1.1 christos /*
553 1.1 christos * print an IP datagram.
554 1.1 christos */
555 1.1 christos void
556 1.1 christos ip_print(netdissect_options *ndo,
557 1.1 christos const u_char *bp,
558 1.1 christos u_int length)
559 1.1 christos {
560 1.1 christos struct ip_print_demux_state ipd;
561 1.1 christos struct ip_print_demux_state *ipds=&ipd;
562 1.1 christos const u_char *ipend;
563 1.1 christos u_int hlen;
564 1.1 christos u_int16_t sum, ip_sum;
565 1.1 christos struct protoent *proto;
566 1.1 christos
567 1.1 christos ipds->ip = (const struct ip *)bp;
568 1.1 christos if (IP_V(ipds->ip) != 4) { /* print version if != 4 */
569 1.1 christos printf("IP%u ", IP_V(ipds->ip));
570 1.1 christos if (IP_V(ipds->ip) == 6)
571 1.1 christos printf(", wrong link-layer encapsulation");
572 1.1 christos }
573 1.1 christos else if (!eflag)
574 1.1 christos printf("IP ");
575 1.1 christos
576 1.1 christos if ((u_char *)(ipds->ip + 1) > snapend) {
577 1.1 christos printf("[|ip]");
578 1.1 christos return;
579 1.1 christos }
580 1.1 christos if (length < sizeof (struct ip)) {
581 1.1 christos (void)printf("truncated-ip %u", length);
582 1.1 christos return;
583 1.1 christos }
584 1.1 christos hlen = IP_HL(ipds->ip) * 4;
585 1.1 christos if (hlen < sizeof (struct ip)) {
586 1.1 christos (void)printf("bad-hlen %u", hlen);
587 1.1 christos return;
588 1.1 christos }
589 1.1 christos
590 1.1 christos ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len);
591 1.1 christos if (length < ipds->len)
592 1.1 christos (void)printf("truncated-ip - %u bytes missing! ",
593 1.1 christos ipds->len - length);
594 1.1 christos if (ipds->len < hlen) {
595 1.1 christos #ifdef GUESS_TSO
596 1.1 christos if (ipds->len) {
597 1.1 christos (void)printf("bad-len %u", ipds->len);
598 1.1 christos return;
599 1.1 christos }
600 1.1 christos else {
601 1.1 christos /* we guess that it is a TSO send */
602 1.1 christos ipds->len = length;
603 1.1 christos }
604 1.1 christos #else
605 1.1 christos (void)printf("bad-len %u", ipds->len);
606 1.1 christos return;
607 1.1 christos #endif /* GUESS_TSO */
608 1.1 christos }
609 1.1 christos
610 1.1 christos /*
611 1.1 christos * Cut off the snapshot length to the end of the IP payload.
612 1.1 christos */
613 1.1 christos ipend = bp + ipds->len;
614 1.1 christos if (ipend < snapend)
615 1.1 christos snapend = ipend;
616 1.1 christos
617 1.1 christos ipds->len -= hlen;
618 1.1 christos
619 1.1 christos ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off);
620 1.1 christos
621 1.1 christos if (vflag) {
622 1.1 christos (void)printf("(tos 0x%x", (int)ipds->ip->ip_tos);
623 1.1 christos /* ECN bits */
624 1.1 christos if (ipds->ip->ip_tos & 0x03) {
625 1.1 christos switch (ipds->ip->ip_tos & 0x03) {
626 1.1 christos case 1:
627 1.1 christos (void)printf(",ECT(1)");
628 1.1 christos break;
629 1.1 christos case 2:
630 1.1 christos (void)printf(",ECT(0)");
631 1.1 christos break;
632 1.1 christos case 3:
633 1.1 christos (void)printf(",CE");
634 1.1 christos }
635 1.1 christos }
636 1.1 christos
637 1.1 christos if (ipds->ip->ip_ttl >= 1)
638 1.1 christos (void)printf(", ttl %u", ipds->ip->ip_ttl);
639 1.1 christos
640 1.1 christos /*
641 1.1 christos * for the firewall guys, print id, offset.
642 1.1 christos * On all but the last stick a "+" in the flags portion.
643 1.1 christos * For unfragmented datagrams, note the don't fragment flag.
644 1.1 christos */
645 1.1 christos
646 1.1 christos (void)printf(", id %u, offset %u, flags [%s], proto %s (%u)",
647 1.1 christos EXTRACT_16BITS(&ipds->ip->ip_id),
648 1.1 christos (ipds->off & 0x1fff) * 8,
649 1.1 christos bittok2str(ip_frag_values, "none", ipds->off&0xe000),
650 1.1 christos tok2str(ipproto_values,"unknown",ipds->ip->ip_p),
651 1.1 christos ipds->ip->ip_p);
652 1.1 christos
653 1.1 christos (void)printf(", length %u", EXTRACT_16BITS(&ipds->ip->ip_len));
654 1.1 christos
655 1.1 christos if ((hlen - sizeof(struct ip)) > 0) {
656 1.1 christos printf(", options (");
657 1.1 christos ip_optprint((u_char *)(ipds->ip + 1), hlen - sizeof(struct ip));
658 1.1 christos printf(")");
659 1.1 christos }
660 1.1 christos
661 1.1 christos if (!Kflag && (u_char *)ipds->ip + hlen <= snapend) {
662 1.1 christos sum = in_cksum((const u_short *)ipds->ip, hlen, 0);
663 1.1 christos if (sum != 0) {
664 1.1 christos ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum);
665 1.1 christos (void)printf(", bad cksum %x (->%x)!", ip_sum,
666 1.1 christos in_cksum_shouldbe(ip_sum, sum));
667 1.1 christos }
668 1.1 christos }
669 1.1 christos
670 1.1 christos printf(")\n ");
671 1.1 christos }
672 1.1 christos
673 1.1 christos /*
674 1.1 christos * If this is fragment zero, hand it to the next higher
675 1.1 christos * level protocol.
676 1.1 christos */
677 1.1 christos if ((ipds->off & 0x1fff) == 0) {
678 1.1 christos ipds->cp = (const u_char *)ipds->ip + hlen;
679 1.1 christos ipds->nh = ipds->ip->ip_p;
680 1.1 christos
681 1.1 christos if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP &&
682 1.1 christos ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) {
683 1.1 christos (void)printf("%s > %s: ",
684 1.1 christos ipaddr_string(&ipds->ip->ip_src),
685 1.1 christos ipaddr_string(&ipds->ip->ip_dst));
686 1.1 christos }
687 1.1 christos ip_print_demux(ndo, ipds);
688 1.1 christos } else {
689 1.1 christos /* Ultra quiet now means that all this stuff should be suppressed */
690 1.1 christos if (qflag > 1) return;
691 1.1 christos
692 1.1 christos /*
693 1.1 christos * if this isn't the first frag, we're missing the
694 1.1 christos * next level protocol header. print the ip addr
695 1.1 christos * and the protocol.
696 1.1 christos */
697 1.1 christos if (ipds->off & 0x1fff) {
698 1.1 christos (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src),
699 1.1 christos ipaddr_string(&ipds->ip->ip_dst));
700 1.1 christos if ((proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
701 1.1 christos (void)printf(" %s", proto->p_name);
702 1.1 christos else
703 1.1 christos (void)printf(" ip-proto-%d", ipds->ip->ip_p);
704 1.1 christos }
705 1.1 christos }
706 1.1 christos }
707 1.1 christos
708 1.1 christos void
709 1.1 christos ipN_print(register const u_char *bp, register u_int length)
710 1.1 christos {
711 1.1 christos struct ip *ip, hdr;
712 1.1 christos
713 1.1 christos ip = (struct ip *)bp;
714 1.1 christos if (length < 4) {
715 1.1 christos (void)printf("truncated-ip %d", length);
716 1.1 christos return;
717 1.1 christos }
718 1.1 christos memcpy (&hdr, (char *)ip, 4);
719 1.1 christos switch (IP_V(&hdr)) {
720 1.1 christos case 4:
721 1.1 christos ip_print (gndo, bp, length);
722 1.1 christos return;
723 1.1 christos #ifdef INET6
724 1.1 christos case 6:
725 1.1 christos ip6_print (bp, length);
726 1.1 christos return;
727 1.1 christos #endif
728 1.1 christos default:
729 1.1 christos (void)printf("unknown ip %d", IP_V(&hdr));
730 1.1 christos return;
731 1.1 christos }
732 1.1 christos }
733 1.1 christos
734 1.1 christos /*
735 1.1 christos * Local Variables:
736 1.1 christos * c-style: whitesmith
737 1.1 christos * c-basic-offset: 8
738 1.1 christos * End:
739 1.1 christos */
740 1.1 christos
741 1.1 christos
742