The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994 |
| 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 Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 22 | /* \summary: IPv6 printer */ |
| 23 | |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 24 | #ifdef HAVE_CONFIG_H |
| 25 | #include "config.h" |
| 26 | #endif |
| 27 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 28 | #include <netdissect-stdinc.h> |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 29 | |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 30 | #include <string.h> |
| 31 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 32 | #include "netdissect.h" |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 33 | #include "addrtoname.h" |
| 34 | #include "extract.h" |
| 35 | |
| 36 | #include "ip6.h" |
| 37 | #include "ipproto.h" |
| 38 | |
| 39 | /* |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 40 | * If routing headers are presend and valid, set dst to the final destination. |
| 41 | * Otherwise, set it to the IPv6 destination. |
| 42 | * |
| 43 | * This is used for UDP and TCP pseudo-header in the checksum |
| 44 | * calculation. |
| 45 | */ |
| 46 | static void |
| 47 | ip6_finddst(netdissect_options *ndo, struct in6_addr *dst, |
| 48 | const struct ip6_hdr *ip6) |
| 49 | { |
| 50 | const u_char *cp; |
| 51 | int advance; |
| 52 | u_int nh; |
| 53 | const struct in6_addr *dst_addr; |
| 54 | const struct ip6_rthdr *dp; |
| 55 | const struct ip6_rthdr0 *dp0; |
| 56 | const struct in6_addr *addr; |
| 57 | int i, len; |
| 58 | |
| 59 | cp = (const u_char *)ip6; |
| 60 | advance = sizeof(struct ip6_hdr); |
| 61 | nh = ip6->ip6_nxt; |
| 62 | dst_addr = &ip6->ip6_dst; |
| 63 | |
| 64 | while (cp < ndo->ndo_snapend) { |
| 65 | cp += advance; |
| 66 | |
| 67 | switch (nh) { |
| 68 | |
| 69 | case IPPROTO_HOPOPTS: |
| 70 | case IPPROTO_DSTOPTS: |
| 71 | case IPPROTO_MOBILITY_OLD: |
| 72 | case IPPROTO_MOBILITY: |
| 73 | /* |
| 74 | * These have a header length byte, following |
| 75 | * the next header byte, giving the length of |
| 76 | * the header, in units of 8 octets, excluding |
| 77 | * the first 8 octets. |
| 78 | */ |
| 79 | ND_TCHECK2(*cp, 2); |
| 80 | advance = (int)((*(cp + 1) + 1) << 3); |
| 81 | nh = *cp; |
| 82 | break; |
| 83 | |
| 84 | case IPPROTO_FRAGMENT: |
| 85 | /* |
| 86 | * The byte following the next header byte is |
| 87 | * marked as reserved, and the header is always |
| 88 | * the same size. |
| 89 | */ |
| 90 | ND_TCHECK2(*cp, 1); |
| 91 | advance = sizeof(struct ip6_frag); |
| 92 | nh = *cp; |
| 93 | break; |
| 94 | |
| 95 | case IPPROTO_ROUTING: |
| 96 | /* |
| 97 | * OK, we found it. |
| 98 | */ |
| 99 | dp = (const struct ip6_rthdr *)cp; |
| 100 | ND_TCHECK(*dp); |
| 101 | len = dp->ip6r_len; |
| 102 | switch (dp->ip6r_type) { |
| 103 | |
| 104 | case IPV6_RTHDR_TYPE_0: |
| 105 | case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */ |
| 106 | dp0 = (const struct ip6_rthdr0 *)dp; |
| 107 | if (len % 2 == 1) |
| 108 | goto trunc; |
| 109 | len >>= 1; |
| 110 | addr = &dp0->ip6r0_addr[0]; |
| 111 | for (i = 0; i < len; i++) { |
| 112 | if ((const u_char *)(addr + 1) > ndo->ndo_snapend) |
| 113 | goto trunc; |
| 114 | |
| 115 | dst_addr = addr; |
| 116 | addr++; |
| 117 | } |
| 118 | break; |
| 119 | |
| 120 | default: |
| 121 | break; |
| 122 | } |
| 123 | |
| 124 | /* |
| 125 | * Only one routing header to a customer. |
| 126 | */ |
| 127 | goto done; |
| 128 | |
| 129 | case IPPROTO_AH: |
| 130 | case IPPROTO_ESP: |
| 131 | case IPPROTO_IPCOMP: |
| 132 | default: |
| 133 | /* |
| 134 | * AH and ESP are, in the RFCs that describe them, |
| 135 | * described as being "viewed as an end-to-end |
| 136 | * payload" "in the IPv6 context, so that they |
| 137 | * "should appear after hop-by-hop, routing, and |
| 138 | * fragmentation extension headers". We assume |
| 139 | * that's the case, and stop as soon as we see |
| 140 | * one. (We can't handle an ESP header in |
| 141 | * the general case anyway, as its length depends |
| 142 | * on the encryption algorithm.) |
| 143 | * |
| 144 | * IPComp is also "viewed as an end-to-end |
| 145 | * payload" "in the IPv6 context". |
| 146 | * |
| 147 | * All other protocols are assumed to be the final |
| 148 | * protocol. |
| 149 | */ |
| 150 | goto done; |
| 151 | } |
| 152 | } |
| 153 | |
| 154 | done: |
| 155 | trunc: |
| 156 | UNALIGNED_MEMCPY(dst, dst_addr, sizeof(struct in6_addr)); |
| 157 | } |
| 158 | |
| 159 | /* |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 160 | * Compute a V6-style checksum by building a pseudoheader. |
| 161 | */ |
| 162 | int |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 163 | nextproto6_cksum(netdissect_options *ndo, |
| 164 | const struct ip6_hdr *ip6, const uint8_t *data, |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 165 | u_int len, u_int covlen, u_int next_proto) |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 166 | { |
| 167 | struct { |
| 168 | struct in6_addr ph_src; |
| 169 | struct in6_addr ph_dst; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 170 | uint32_t ph_len; |
| 171 | uint8_t ph_zero[3]; |
| 172 | uint8_t ph_nxt; |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 173 | } ph; |
| 174 | struct cksum_vec vec[2]; |
| 175 | |
| 176 | /* pseudo-header */ |
| 177 | memset(&ph, 0, sizeof(ph)); |
| 178 | UNALIGNED_MEMCPY(&ph.ph_src, &ip6->ip6_src, sizeof (struct in6_addr)); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 179 | switch (ip6->ip6_nxt) { |
| 180 | |
| 181 | case IPPROTO_HOPOPTS: |
| 182 | case IPPROTO_DSTOPTS: |
| 183 | case IPPROTO_MOBILITY_OLD: |
| 184 | case IPPROTO_MOBILITY: |
| 185 | case IPPROTO_FRAGMENT: |
| 186 | case IPPROTO_ROUTING: |
| 187 | /* |
| 188 | * The next header is either a routing header or a header |
| 189 | * after which there might be a routing header, so scan |
| 190 | * for a routing header. |
| 191 | */ |
| 192 | ip6_finddst(ndo, &ph.ph_dst, ip6); |
| 193 | break; |
| 194 | |
| 195 | default: |
| 196 | UNALIGNED_MEMCPY(&ph.ph_dst, &ip6->ip6_dst, sizeof (struct in6_addr)); |
| 197 | break; |
| 198 | } |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 199 | ph.ph_len = htonl(len); |
| 200 | ph.ph_nxt = next_proto; |
| 201 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 202 | vec[0].ptr = (const uint8_t *)(void *)&ph; |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 203 | vec[0].len = sizeof(ph); |
| 204 | vec[1].ptr = data; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 205 | vec[1].len = covlen; |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 206 | |
| 207 | return in_cksum(vec, 2); |
| 208 | } |
| 209 | |
| 210 | /* |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 211 | * print an IP6 datagram. |
| 212 | */ |
| 213 | void |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 214 | ip6_print(netdissect_options *ndo, const u_char *bp, u_int length) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 215 | { |
| 216 | register const struct ip6_hdr *ip6; |
| 217 | register int advance; |
| 218 | u_int len; |
| 219 | const u_char *ipend; |
| 220 | register const u_char *cp; |
| 221 | register u_int payload_len; |
| 222 | int nh; |
| 223 | int fragmented = 0; |
| 224 | u_int flow; |
| 225 | |
| 226 | ip6 = (const struct ip6_hdr *)bp; |
| 227 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 228 | ND_TCHECK(*ip6); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 229 | if (length < sizeof (struct ip6_hdr)) { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 230 | ND_PRINT((ndo, "truncated-ip6 %u", length)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 231 | return; |
| 232 | } |
| 233 | |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 234 | if (!ndo->ndo_eflag) |
| 235 | ND_PRINT((ndo, "IP6 ")); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 236 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 237 | if (IP6_VERSION(ip6) != 6) { |
| 238 | ND_PRINT((ndo,"version error: %u != 6", IP6_VERSION(ip6))); |
| 239 | return; |
| 240 | } |
| 241 | |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 242 | payload_len = EXTRACT_16BITS(&ip6->ip6_plen); |
| 243 | len = payload_len + sizeof(struct ip6_hdr); |
| 244 | if (length < len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 245 | ND_PRINT((ndo, "truncated-ip6 - %u bytes missing!", |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 246 | len - length)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 247 | |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 248 | if (ndo->ndo_vflag) { |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 249 | flow = EXTRACT_32BITS(&ip6->ip6_flow); |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 250 | ND_PRINT((ndo, "(")); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 251 | #if 0 |
| 252 | /* rfc1883 */ |
| 253 | if (flow & 0x0f000000) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 254 | ND_PRINT((ndo, "pri 0x%02x, ", (flow & 0x0f000000) >> 24)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 255 | if (flow & 0x00ffffff) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 256 | ND_PRINT((ndo, "flowlabel 0x%06x, ", flow & 0x00ffffff)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 257 | #else |
| 258 | /* RFC 2460 */ |
| 259 | if (flow & 0x0ff00000) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 260 | ND_PRINT((ndo, "class 0x%02x, ", (flow & 0x0ff00000) >> 20)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 261 | if (flow & 0x000fffff) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 262 | ND_PRINT((ndo, "flowlabel 0x%05x, ", flow & 0x000fffff)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 263 | #endif |
| 264 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 265 | ND_PRINT((ndo, "hlim %u, next-header %s (%u) payload length: %u) ", |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 266 | ip6->ip6_hlim, |
| 267 | tok2str(ipproto_values,"unknown",ip6->ip6_nxt), |
| 268 | ip6->ip6_nxt, |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 269 | payload_len)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 270 | } |
| 271 | |
| 272 | /* |
| 273 | * Cut off the snapshot length to the end of the IP payload. |
| 274 | */ |
| 275 | ipend = bp + len; |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 276 | if (ipend < ndo->ndo_snapend) |
| 277 | ndo->ndo_snapend = ipend; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 278 | |
| 279 | cp = (const u_char *)ip6; |
| 280 | advance = sizeof(struct ip6_hdr); |
| 281 | nh = ip6->ip6_nxt; |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 282 | while (cp < ndo->ndo_snapend && advance > 0) { |
Elliott Hughes | cec480a | 2017-12-19 16:54:57 -0800 | [diff] [blame] | 283 | if (len < (u_int)advance) |
| 284 | goto trunc; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 285 | cp += advance; |
| 286 | len -= advance; |
| 287 | |
| 288 | if (cp == (const u_char *)(ip6 + 1) && |
| 289 | nh != IPPROTO_TCP && nh != IPPROTO_UDP && |
| 290 | nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 291 | ND_PRINT((ndo, "%s > %s: ", ip6addr_string(ndo, &ip6->ip6_src), |
| 292 | ip6addr_string(ndo, &ip6->ip6_dst))); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 293 | } |
| 294 | |
| 295 | switch (nh) { |
| 296 | case IPPROTO_HOPOPTS: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 297 | advance = hbhopt_print(ndo, cp); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 298 | if (advance < 0) |
| 299 | return; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 300 | nh = *cp; |
| 301 | break; |
| 302 | case IPPROTO_DSTOPTS: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 303 | advance = dstopt_print(ndo, cp); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 304 | if (advance < 0) |
| 305 | return; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 306 | nh = *cp; |
| 307 | break; |
| 308 | case IPPROTO_FRAGMENT: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 309 | advance = frag6_print(ndo, cp, (const u_char *)ip6); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 310 | if (advance < 0 || ndo->ndo_snapend <= cp + advance) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 311 | return; |
| 312 | nh = *cp; |
| 313 | fragmented = 1; |
| 314 | break; |
| 315 | |
| 316 | case IPPROTO_MOBILITY_OLD: |
| 317 | case IPPROTO_MOBILITY: |
| 318 | /* |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 319 | * XXX - we don't use "advance"; RFC 3775 says that |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 320 | * the next header field in a mobility header |
| 321 | * should be IPPROTO_NONE, but speaks of |
| 322 | * the possiblity of a future extension in |
| 323 | * which payload can be piggybacked atop a |
| 324 | * mobility header. |
| 325 | */ |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 326 | advance = mobility_print(ndo, cp, (const u_char *)ip6); |
Elliott Hughes | cec480a | 2017-12-19 16:54:57 -0800 | [diff] [blame] | 327 | if (advance < 0) |
| 328 | return; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 329 | nh = *cp; |
| 330 | return; |
| 331 | case IPPROTO_ROUTING: |
Elliott Hughes | cec480a | 2017-12-19 16:54:57 -0800 | [diff] [blame] | 332 | ND_TCHECK(*cp); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 333 | advance = rt6_print(ndo, cp, (const u_char *)ip6); |
Elliott Hughes | cec480a | 2017-12-19 16:54:57 -0800 | [diff] [blame] | 334 | if (advance < 0) |
| 335 | return; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 336 | nh = *cp; |
| 337 | break; |
| 338 | case IPPROTO_SCTP: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 339 | sctp_print(ndo, cp, (const u_char *)ip6, len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 340 | return; |
| 341 | case IPPROTO_DCCP: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 342 | dccp_print(ndo, cp, (const u_char *)ip6, len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 343 | return; |
| 344 | case IPPROTO_TCP: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 345 | tcp_print(ndo, cp, len, (const u_char *)ip6, fragmented); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 346 | return; |
| 347 | case IPPROTO_UDP: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 348 | udp_print(ndo, cp, len, (const u_char *)ip6, fragmented); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 349 | return; |
| 350 | case IPPROTO_ICMPV6: |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 351 | icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 352 | return; |
| 353 | case IPPROTO_AH: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 354 | advance = ah_print(ndo, cp); |
Elliott Hughes | cec480a | 2017-12-19 16:54:57 -0800 | [diff] [blame] | 355 | if (advance < 0) |
| 356 | return; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 357 | nh = *cp; |
| 358 | break; |
| 359 | case IPPROTO_ESP: |
| 360 | { |
| 361 | int enh, padlen; |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 362 | advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen); |
Elliott Hughes | cec480a | 2017-12-19 16:54:57 -0800 | [diff] [blame] | 363 | if (advance < 0) |
| 364 | return; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 365 | nh = enh & 0xff; |
| 366 | len -= padlen; |
| 367 | break; |
| 368 | } |
| 369 | case IPPROTO_IPCOMP: |
| 370 | { |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 371 | ipcomp_print(ndo, cp); |
| 372 | /* |
| 373 | * Either this has decompressed the payload and |
| 374 | * printed it, in which case there's nothing more |
| 375 | * to do, or it hasn't, in which case there's |
| 376 | * nothing more to do. |
| 377 | */ |
| 378 | advance = -1; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 379 | break; |
| 380 | } |
| 381 | |
| 382 | case IPPROTO_PIM: |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 383 | pim_print(ndo, cp, len, (const u_char *)ip6); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 384 | return; |
| 385 | |
| 386 | case IPPROTO_OSPF: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 387 | ospf6_print(ndo, cp, len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 388 | return; |
| 389 | |
| 390 | case IPPROTO_IPV6: |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 391 | ip6_print(ndo, cp, len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 392 | return; |
| 393 | |
| 394 | case IPPROTO_IPV4: |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 395 | ip_print(ndo, cp, len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 396 | return; |
| 397 | |
| 398 | case IPPROTO_PGM: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 399 | pgm_print(ndo, cp, len, (const u_char *)ip6); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 400 | return; |
| 401 | |
| 402 | case IPPROTO_GRE: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 403 | gre_print(ndo, cp, len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 404 | return; |
| 405 | |
| 406 | case IPPROTO_RSVP: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 407 | rsvp_print(ndo, cp, len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 408 | return; |
| 409 | |
| 410 | case IPPROTO_NONE: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 411 | ND_PRINT((ndo, "no next header")); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 412 | return; |
| 413 | |
| 414 | default: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 415 | ND_PRINT((ndo, "ip-proto-%d %d", nh, len)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 416 | return; |
| 417 | } |
| 418 | } |
| 419 | |
| 420 | return; |
| 421 | trunc: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 422 | ND_PRINT((ndo, "[|ip6]")); |
| 423 | } |