blob: a0df95918898ff3228e760d0c07942790d3e3074 [file] [log] [blame]
The Android Open Source Project2949f582009-03-03 19:30:46 -08001/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 */
21
Elliott Hughese2e3bd12017-05-15 10:59:29 -070022/* \summary: IP printer */
23
The Android Open Source Project2949f582009-03-03 19:30:46 -080024#ifdef HAVE_CONFIG_H
Elliott Hughes820eced2021-08-20 18:00:50 -070025#include <config.h>
The Android Open Source Project2949f582009-03-03 19:30:46 -080026#endif
27
Elliott Hughes820eced2021-08-20 18:00:50 -070028#include "netdissect-stdinc.h"
The Android Open Source Project2949f582009-03-03 19:30:46 -080029
Elliott Hughese2e3bd12017-05-15 10:59:29 -070030#include "netdissect.h"
Elliott Hughes892a68b2015-10-19 14:43:53 -070031#include "addrtoname.h"
Elliott Hughese2e3bd12017-05-15 10:59:29 -070032#include "extract.h"
The Android Open Source Project2949f582009-03-03 19:30:46 -080033
34#include "ip.h"
35#include "ipproto.h"
36
Elliott Hughes892a68b2015-10-19 14:43:53 -070037
JP Abgrall53f17a92014-02-12 14:02:41 -080038static const struct tok ip_option_values[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -080039 { IPOPT_EOL, "EOL" },
40 { IPOPT_NOP, "NOP" },
41 { IPOPT_TS, "timestamp" },
42 { IPOPT_SECURITY, "security" },
43 { IPOPT_RR, "RR" },
44 { IPOPT_SSRR, "SSRR" },
45 { IPOPT_LSRR, "LSRR" },
46 { IPOPT_RA, "RA" },
47 { IPOPT_RFC1393, "traceroute" },
48 { 0, NULL }
49};
50
51/*
52 * print the recorded route in an IP RR, LSRR or SSRR option.
53 */
Elliott Hughescec480a2017-12-19 16:54:57 -080054static int
Elliott Hughes892a68b2015-10-19 14:43:53 -070055ip_printroute(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -070056 const u_char *cp, u_int length)
The Android Open Source Project2949f582009-03-03 19:30:46 -080057{
Elliott Hughes820eced2021-08-20 18:00:50 -070058 u_int ptr;
59 u_int len;
The Android Open Source Project2949f582009-03-03 19:30:46 -080060
61 if (length < 3) {
Elliott Hughes820eced2021-08-20 18:00:50 -070062 ND_PRINT(" [bad length %u]", length);
Elliott Hughescec480a2017-12-19 16:54:57 -080063 return (0);
The Android Open Source Project2949f582009-03-03 19:30:46 -080064 }
65 if ((length + 1) & 3)
Elliott Hughes820eced2021-08-20 18:00:50 -070066 ND_PRINT(" [bad length %u]", length);
67 ptr = GET_U_1(cp + 2) - 1;
The Android Open Source Project2949f582009-03-03 19:30:46 -080068 if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
Elliott Hughes820eced2021-08-20 18:00:50 -070069 ND_PRINT(" [bad ptr %u]", GET_U_1(cp + 2));
The Android Open Source Project2949f582009-03-03 19:30:46 -080070
71 for (len = 3; len < length; len += 4) {
Elliott Hughes820eced2021-08-20 18:00:50 -070072 ND_TCHECK_4(cp + len); /* Needed to print the IP addresses */
73 ND_PRINT(" %s", GET_IPADDR_STRING(cp + len));
Elliott Hughes892a68b2015-10-19 14:43:53 -070074 if (ptr > len)
Elliott Hughes820eced2021-08-20 18:00:50 -070075 ND_PRINT(",");
The Android Open Source Project2949f582009-03-03 19:30:46 -080076 }
Elliott Hughescec480a2017-12-19 16:54:57 -080077 return (0);
78
79trunc:
80 return (-1);
The Android Open Source Project2949f582009-03-03 19:30:46 -080081}
82
83/*
84 * If source-routing is present and valid, return the final destination.
85 * Otherwise, return IP destination.
86 *
87 * This is used for UDP and TCP pseudo-header in the checksum
88 * calculation.
89 */
Elliott Hughes892a68b2015-10-19 14:43:53 -070090static uint32_t
91ip_finddst(netdissect_options *ndo,
92 const struct ip *ip)
The Android Open Source Project2949f582009-03-03 19:30:46 -080093{
Elliott Hughes820eced2021-08-20 18:00:50 -070094 u_int length;
95 u_int len;
The Android Open Source Project2949f582009-03-03 19:30:46 -080096 const u_char *cp;
The Android Open Source Project2949f582009-03-03 19:30:46 -080097
98 cp = (const u_char *)(ip + 1);
Elliott Hughes820eced2021-08-20 18:00:50 -070099 length = IP_HL(ip) * 4;
100 if (length < sizeof(struct ip))
101 goto trunc;
102 length -= sizeof(struct ip);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800103
Elliott Hughes820eced2021-08-20 18:00:50 -0700104 for (; length != 0; cp += len, length -= len) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800105 int tt;
106
Elliott Hughes820eced2021-08-20 18:00:50 -0700107 tt = GET_U_1(cp);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800108 if (tt == IPOPT_EOL)
109 break;
110 else if (tt == IPOPT_NOP)
111 len = 1;
112 else {
Elliott Hughes820eced2021-08-20 18:00:50 -0700113 len = GET_U_1(cp + 1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800114 if (len < 2)
115 break;
116 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700117 if (length < len)
118 goto trunc;
119 ND_TCHECK_LEN(cp, len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800120 switch (tt) {
121
122 case IPOPT_SSRR:
123 case IPOPT_LSRR:
124 if (len < 7)
125 break;
Elliott Hughes820eced2021-08-20 18:00:50 -0700126 return (GET_IPV4_TO_NETWORK_ORDER(cp + len - 4));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800127 }
128 }
129trunc:
Elliott Hughes820eced2021-08-20 18:00:50 -0700130 return (GET_IPV4_TO_NETWORK_ORDER(ip->ip_dst));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800131}
132
JP Abgrall53f17a92014-02-12 14:02:41 -0800133/*
134 * Compute a V4-style checksum by building a pseudoheader.
135 */
Elliott Hughes820eced2021-08-20 18:00:50 -0700136uint16_t
Elliott Hughes892a68b2015-10-19 14:43:53 -0700137nextproto4_cksum(netdissect_options *ndo,
138 const struct ip *ip, const uint8_t *data,
Elliott Hughes820eced2021-08-20 18:00:50 -0700139 u_int len, u_int covlen, uint8_t next_proto)
JP Abgrall53f17a92014-02-12 14:02:41 -0800140{
141 struct phdr {
Elliott Hughes892a68b2015-10-19 14:43:53 -0700142 uint32_t src;
143 uint32_t dst;
Elliott Hughes820eced2021-08-20 18:00:50 -0700144 uint8_t mbz;
145 uint8_t proto;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700146 uint16_t len;
JP Abgrall53f17a92014-02-12 14:02:41 -0800147 } ph;
148 struct cksum_vec vec[2];
149
150 /* pseudo-header.. */
Elliott Hughes892a68b2015-10-19 14:43:53 -0700151 ph.len = htons((uint16_t)len);
JP Abgrall53f17a92014-02-12 14:02:41 -0800152 ph.mbz = 0;
153 ph.proto = next_proto;
Elliott Hughes820eced2021-08-20 18:00:50 -0700154 ph.src = GET_IPV4_TO_NETWORK_ORDER(ip->ip_src);
JP Abgrall53f17a92014-02-12 14:02:41 -0800155 if (IP_HL(ip) == 5)
Elliott Hughes820eced2021-08-20 18:00:50 -0700156 ph.dst = GET_IPV4_TO_NETWORK_ORDER(ip->ip_dst);
JP Abgrall53f17a92014-02-12 14:02:41 -0800157 else
Elliott Hughes892a68b2015-10-19 14:43:53 -0700158 ph.dst = ip_finddst(ndo, ip);
JP Abgrall53f17a92014-02-12 14:02:41 -0800159
Elliott Hughes892a68b2015-10-19 14:43:53 -0700160 vec[0].ptr = (const uint8_t *)(void *)&ph;
JP Abgrall53f17a92014-02-12 14:02:41 -0800161 vec[0].len = sizeof(ph);
162 vec[1].ptr = data;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700163 vec[1].len = covlen;
JP Abgrall53f17a92014-02-12 14:02:41 -0800164 return (in_cksum(vec, 2));
165}
166
Elliott Hughescec480a2017-12-19 16:54:57 -0800167static int
Elliott Hughes892a68b2015-10-19 14:43:53 -0700168ip_printts(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -0700169 const u_char *cp, u_int length)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800170{
Elliott Hughes820eced2021-08-20 18:00:50 -0700171 u_int ptr;
172 u_int len;
173 u_int hoplen;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800174 const char *type;
175
176 if (length < 4) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700177 ND_PRINT("[bad length %u]", length);
Elliott Hughescec480a2017-12-19 16:54:57 -0800178 return (0);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800179 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700180 ND_PRINT(" TS{");
181 hoplen = ((GET_U_1(cp + 3) & 0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800182 if ((length - 4) & (hoplen-1))
Elliott Hughes820eced2021-08-20 18:00:50 -0700183 ND_PRINT("[bad length %u]", length);
184 ptr = GET_U_1(cp + 2) - 1;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800185 len = 0;
186 if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
Elliott Hughes820eced2021-08-20 18:00:50 -0700187 ND_PRINT("[bad ptr %u]", GET_U_1(cp + 2));
188 switch (GET_U_1(cp + 3)&0xF) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800189 case IPOPT_TS_TSONLY:
Elliott Hughes820eced2021-08-20 18:00:50 -0700190 ND_PRINT("TSONLY");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800191 break;
192 case IPOPT_TS_TSANDADDR:
Elliott Hughes820eced2021-08-20 18:00:50 -0700193 ND_PRINT("TS+ADDR");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800194 break;
Elliott Hughes820eced2021-08-20 18:00:50 -0700195 case IPOPT_TS_PRESPEC:
196 ND_PRINT("PRESPEC");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800197 break;
198 default:
Elliott Hughes820eced2021-08-20 18:00:50 -0700199 ND_PRINT("[bad ts type %u]", GET_U_1(cp + 3)&0xF);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800200 goto done;
201 }
202
203 type = " ";
204 for (len = 4; len < length; len += hoplen) {
205 if (ptr == len)
206 type = " ^ ";
Elliott Hughes820eced2021-08-20 18:00:50 -0700207 ND_TCHECK_LEN(cp + len, hoplen);
208 ND_PRINT("%s%u@%s", type, GET_BE_U_4(cp + len + hoplen - 4),
209 hoplen!=8 ? "" : GET_IPADDR_STRING(cp + len));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800210 type = " ";
211 }
212
213done:
Elliott Hughes820eced2021-08-20 18:00:50 -0700214 ND_PRINT("%s", ptr == len ? " ^ " : "");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800215
Elliott Hughes820eced2021-08-20 18:00:50 -0700216 if (GET_U_1(cp + 3) >> 4)
217 ND_PRINT(" [%u hops not recorded]} ", GET_U_1(cp + 3)>>4);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800218 else
Elliott Hughes820eced2021-08-20 18:00:50 -0700219 ND_PRINT("}");
Elliott Hughescec480a2017-12-19 16:54:57 -0800220 return (0);
221
222trunc:
223 return (-1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800224}
225
226/*
227 * print IP options.
Elliott Hughes820eced2021-08-20 18:00:50 -0700228 If truncated return -1, else 0.
The Android Open Source Project2949f582009-03-03 19:30:46 -0800229 */
Elliott Hughes820eced2021-08-20 18:00:50 -0700230static int
Elliott Hughes892a68b2015-10-19 14:43:53 -0700231ip_optprint(netdissect_options *ndo,
Elliott Hughes820eced2021-08-20 18:00:50 -0700232 const u_char *cp, u_int length)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800233{
Elliott Hughes820eced2021-08-20 18:00:50 -0700234 u_int option_len;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800235 const char *sep = "";
236
237 for (; length > 0; cp += option_len, length -= option_len) {
238 u_int option_code;
239
Elliott Hughes820eced2021-08-20 18:00:50 -0700240 ND_PRINT("%s", sep);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800241 sep = ",";
242
Elliott Hughes820eced2021-08-20 18:00:50 -0700243 option_code = GET_U_1(cp);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800244
Elliott Hughes820eced2021-08-20 18:00:50 -0700245 ND_PRINT("%s",
246 tok2str(ip_option_values,"unknown %u",option_code));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800247
248 if (option_code == IPOPT_NOP ||
249 option_code == IPOPT_EOL)
250 option_len = 1;
251
252 else {
Elliott Hughes820eced2021-08-20 18:00:50 -0700253 option_len = GET_U_1(cp + 1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800254 if (option_len < 2) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700255 ND_PRINT(" [bad length %u]", option_len);
256 return 0;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800257 }
258 }
259
260 if (option_len > length) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700261 ND_PRINT(" [bad length %u]", option_len);
262 return 0;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800263 }
264
Elliott Hughes820eced2021-08-20 18:00:50 -0700265 ND_TCHECK_LEN(cp, option_len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800266
267 switch (option_code) {
268 case IPOPT_EOL:
Elliott Hughes820eced2021-08-20 18:00:50 -0700269 return 0;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800270
271 case IPOPT_TS:
Elliott Hughescec480a2017-12-19 16:54:57 -0800272 if (ip_printts(ndo, cp, option_len) == -1)
273 goto trunc;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800274 break;
275
276 case IPOPT_RR: /* fall through */
277 case IPOPT_SSRR:
278 case IPOPT_LSRR:
Elliott Hughescec480a2017-12-19 16:54:57 -0800279 if (ip_printroute(ndo, cp, option_len) == -1)
280 goto trunc;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800281 break;
282
283 case IPOPT_RA:
284 if (option_len < 4) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700285 ND_PRINT(" [bad length %u]", option_len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800286 break;
287 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700288 ND_TCHECK_1(cp + 3);
289 if (GET_BE_U_2(cp + 2) != 0)
290 ND_PRINT(" value %u", GET_BE_U_2(cp + 2));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800291 break;
292
293 case IPOPT_NOP: /* nothing to print - fall through */
294 case IPOPT_SECURITY:
295 default:
296 break;
297 }
298 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700299 return 0;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800300
301trunc:
Elliott Hughes820eced2021-08-20 18:00:50 -0700302 return -1;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800303}
304
The Android Open Source Project2949f582009-03-03 19:30:46 -0800305#define IP_RES 0x8000
306
JP Abgrall53f17a92014-02-12 14:02:41 -0800307static const struct tok ip_frag_values[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800308 { IP_MF, "+" },
309 { IP_DF, "DF" },
310 { IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */
311 { 0, NULL }
312};
313
The Android Open Source Project2949f582009-03-03 19:30:46 -0800314
315/*
316 * print an IP datagram.
317 */
318void
319ip_print(netdissect_options *ndo,
320 const u_char *bp,
321 u_int length)
322{
Elliott Hughes820eced2021-08-20 18:00:50 -0700323 const struct ip *ip;
324 u_int off;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800325 u_int hlen;
Elliott Hughes820eced2021-08-20 18:00:50 -0700326 u_int len;
JP Abgrall53f17a92014-02-12 14:02:41 -0800327 struct cksum_vec vec[1];
Elliott Hughes820eced2021-08-20 18:00:50 -0700328 uint8_t ip_tos, ip_ttl, ip_proto;
Elliott Hughes892a68b2015-10-19 14:43:53 -0700329 uint16_t sum, ip_sum;
Elliott Hughescec480a2017-12-19 16:54:57 -0800330 const char *p_name;
Elliott Hughes820eced2021-08-20 18:00:50 -0700331 int truncated = 0;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800332
Elliott Hughes820eced2021-08-20 18:00:50 -0700333 ndo->ndo_protocol = "ip";
334 ip = (const struct ip *)bp;
335 if (IP_V(ip) != 4) { /* print version and fail if != 4 */
336 if (IP_V(ip) == 6)
337 ND_PRINT("IP6, wrong link-layer encapsulation");
Elliott Hughes892a68b2015-10-19 14:43:53 -0700338 else
Elliott Hughes820eced2021-08-20 18:00:50 -0700339 ND_PRINT("IP%u", IP_V(ip));
340 nd_print_invalid(ndo);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700341 return;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800342 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700343 if (!ndo->ndo_eflag)
Elliott Hughes820eced2021-08-20 18:00:50 -0700344 ND_PRINT("IP ");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800345
Elliott Hughes820eced2021-08-20 18:00:50 -0700346 ND_TCHECK_SIZE(ip);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800347 if (length < sizeof (struct ip)) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700348 ND_PRINT("truncated-ip %u", length);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800349 return;
350 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700351 hlen = IP_HL(ip) * 4;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800352 if (hlen < sizeof (struct ip)) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700353 ND_PRINT("bad-hlen %u", hlen);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800354 return;
355 }
356
Elliott Hughes820eced2021-08-20 18:00:50 -0700357 len = GET_BE_U_2(ip->ip_len);
358 if (length < len)
359 ND_PRINT("truncated-ip - %u bytes missing! ",
360 len - length);
361 if (len < hlen) {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800362#ifdef GUESS_TSO
Elliott Hughes820eced2021-08-20 18:00:50 -0700363 if (len) {
364 ND_PRINT("bad-len %u", len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800365 return;
366 }
367 else {
368 /* we guess that it is a TSO send */
Elliott Hughes820eced2021-08-20 18:00:50 -0700369 len = length;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800370 }
371#else
Elliott Hughes820eced2021-08-20 18:00:50 -0700372 ND_PRINT("bad-len %u", len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800373 return;
374#endif /* GUESS_TSO */
375 }
376
377 /*
378 * Cut off the snapshot length to the end of the IP payload.
379 */
Elliott Hughes820eced2021-08-20 18:00:50 -0700380 nd_push_snapend(ndo, bp + len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800381
Elliott Hughes820eced2021-08-20 18:00:50 -0700382 len -= hlen;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800383
Elliott Hughes820eced2021-08-20 18:00:50 -0700384 off = GET_BE_U_2(ip->ip_off);
385
386 ip_proto = GET_U_1(ip->ip_p);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800387
Elliott Hughes892a68b2015-10-19 14:43:53 -0700388 if (ndo->ndo_vflag) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700389 ip_tos = GET_U_1(ip->ip_tos);
390 ND_PRINT("(tos 0x%x", ip_tos);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800391 /* ECN bits */
Elliott Hughes820eced2021-08-20 18:00:50 -0700392 switch (ip_tos & 0x03) {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700393
394 case 0:
395 break;
396
397 case 1:
Elliott Hughes820eced2021-08-20 18:00:50 -0700398 ND_PRINT(",ECT(1)");
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700399 break;
400
401 case 2:
Elliott Hughes820eced2021-08-20 18:00:50 -0700402 ND_PRINT(",ECT(0)");
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700403 break;
404
405 case 3:
Elliott Hughes820eced2021-08-20 18:00:50 -0700406 ND_PRINT(",CE");
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700407 break;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800408 }
409
Elliott Hughes820eced2021-08-20 18:00:50 -0700410 ip_ttl = GET_U_1(ip->ip_ttl);
411 if (ip_ttl >= 1)
412 ND_PRINT(", ttl %u", ip_ttl);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800413
414 /*
415 * for the firewall guys, print id, offset.
416 * On all but the last stick a "+" in the flags portion.
417 * For unfragmented datagrams, note the don't fragment flag.
418 */
Elliott Hughes820eced2021-08-20 18:00:50 -0700419 ND_PRINT(", id %u, offset %u, flags [%s], proto %s (%u)",
420 GET_BE_U_2(ip->ip_id),
421 (off & IP_OFFMASK) * 8,
422 bittok2str(ip_frag_values, "none", off & (IP_RES|IP_DF|IP_MF)),
423 tok2str(ipproto_values, "unknown", ip_proto),
424 ip_proto);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800425
Elliott Hughes820eced2021-08-20 18:00:50 -0700426 ND_PRINT(", length %u", GET_BE_U_2(ip->ip_len));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800427
428 if ((hlen - sizeof(struct ip)) > 0) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700429 ND_PRINT(", options (");
430 if (ip_optprint(ndo, (const u_char *)(ip + 1),
431 hlen - sizeof(struct ip)) == -1) {
432 ND_PRINT(" [truncated-option]");
433 truncated = 1;
434 }
435 ND_PRINT(")");
The Android Open Source Project2949f582009-03-03 19:30:46 -0800436 }
437
Elliott Hughes820eced2021-08-20 18:00:50 -0700438 if (!ndo->ndo_Kflag && (const u_char *)ip + hlen <= ndo->ndo_snapend) {
439 vec[0].ptr = (const uint8_t *)(const void *)ip;
JP Abgrall53f17a92014-02-12 14:02:41 -0800440 vec[0].len = hlen;
441 sum = in_cksum(vec, 1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800442 if (sum != 0) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700443 ip_sum = GET_BE_U_2(ip->ip_sum);
444 ND_PRINT(", bad cksum %x (->%x)!", ip_sum,
445 in_cksum_shouldbe(ip_sum, sum));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800446 }
447 }
448
Elliott Hughes820eced2021-08-20 18:00:50 -0700449 ND_PRINT(")\n ");
450 if (truncated) {
451 ND_PRINT("%s > %s: ",
452 GET_IPADDR_STRING(ip->ip_src),
453 GET_IPADDR_STRING(ip->ip_dst));
454 nd_print_trunc(ndo);
455 nd_pop_packet_info(ndo);
456 return;
457 }
The Android Open Source Project2949f582009-03-03 19:30:46 -0800458 }
459
460 /*
461 * If this is fragment zero, hand it to the next higher
Elliott Hughes820eced2021-08-20 18:00:50 -0700462 * level protocol. Let them know whether there are more
463 * fragments.
The Android Open Source Project2949f582009-03-03 19:30:46 -0800464 */
Elliott Hughes820eced2021-08-20 18:00:50 -0700465 if ((off & IP_OFFMASK) == 0) {
466 uint8_t nh = GET_U_1(ip->ip_p);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800467
Elliott Hughes820eced2021-08-20 18:00:50 -0700468 if (nh != IPPROTO_TCP && nh != IPPROTO_UDP &&
469 nh != IPPROTO_SCTP && nh != IPPROTO_DCCP) {
470 ND_PRINT("%s > %s: ",
471 GET_IPADDR_STRING(ip->ip_src),
472 GET_IPADDR_STRING(ip->ip_dst));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800473 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700474 /*
475 * Do a bounds check before calling ip_demux_print().
476 * At least the header data is required.
477 */
478 if (!ND_TTEST_LEN((const u_char *)ip, hlen)) {
479 ND_PRINT(" [remaining caplen(%u) < header length(%u)]",
480 ND_BYTES_AVAILABLE_AFTER((const u_char *)ip),
481 hlen);
482 nd_trunc_longjmp(ndo);
483 }
484 ip_demux_print(ndo, (const u_char *)ip + hlen, len, 4,
485 off & IP_MF, GET_U_1(ip->ip_ttl), nh, bp);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800486 } else {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700487 /*
488 * Ultra quiet now means that all this stuff should be
489 * suppressed.
490 */
Elliott Hughes820eced2021-08-20 18:00:50 -0700491 if (ndo->ndo_qflag > 1) {
492 nd_pop_packet_info(ndo);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700493 return;
Elliott Hughes820eced2021-08-20 18:00:50 -0700494 }
The Android Open Source Project2949f582009-03-03 19:30:46 -0800495
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700496 /*
497 * This isn't the first frag, so we're missing the
498 * next level protocol header. print the ip addr
499 * and the protocol.
500 */
Elliott Hughes820eced2021-08-20 18:00:50 -0700501 ND_PRINT("%s > %s:", GET_IPADDR_STRING(ip->ip_src),
502 GET_IPADDR_STRING(ip->ip_dst));
503 if (!ndo->ndo_nflag && (p_name = netdb_protoname(ip_proto)) != NULL)
504 ND_PRINT(" %s", p_name);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700505 else
Elliott Hughes820eced2021-08-20 18:00:50 -0700506 ND_PRINT(" ip-proto-%u", ip_proto);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800507 }
Elliott Hughes820eced2021-08-20 18:00:50 -0700508 nd_pop_packet_info(ndo);
Elliott Hughes892a68b2015-10-19 14:43:53 -0700509 return;
510
511trunc:
Elliott Hughes820eced2021-08-20 18:00:50 -0700512 nd_print_trunc(ndo);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800513}
514
515void
Elliott Hughes820eced2021-08-20 18:00:50 -0700516ipN_print(netdissect_options *ndo, const u_char *bp, u_int length)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800517{
Elliott Hughes820eced2021-08-20 18:00:50 -0700518 ndo->ndo_protocol = "ipn";
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700519 if (length < 1) {
Elliott Hughes820eced2021-08-20 18:00:50 -0700520 ND_PRINT("truncated-ip %u", length);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800521 return;
522 }
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700523
Elliott Hughes820eced2021-08-20 18:00:50 -0700524 switch (GET_U_1(bp) & 0xF0) {
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700525 case 0x40:
Elliott Hughes820eced2021-08-20 18:00:50 -0700526 ip_print(ndo, bp, length);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700527 break;
528 case 0x60:
Elliott Hughes820eced2021-08-20 18:00:50 -0700529 ip6_print(ndo, bp, length);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700530 break;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800531 default:
Elliott Hughes820eced2021-08-20 18:00:50 -0700532 ND_PRINT("unknown ip %u", (GET_U_1(bp) & 0xF0) >> 4);
Elliott Hughese2e3bd12017-05-15 10:59:29 -0700533 break;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800534 }
The Android Open Source Project2949f582009-03-03 19:30:46 -0800535}