print-ip6.c 11 KB

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