- payload_len = EXTRACT_BE_U_2(ip6->ip6_plen);
- len = payload_len + sizeof(struct ip6_hdr);
- if (length < len)
- ND_PRINT((ndo, "truncated-ip6 - %u bytes missing!",
- len - length));
-
- nh = EXTRACT_U_1(ip6->ip6_nxt);
- if (ndo->ndo_vflag) {
- flow = EXTRACT_BE_U_4(ip6->ip6_flow);
- ND_PRINT((ndo, "("));
-#if 0
- /* rfc1883 */
- if (flow & 0x0f000000)
- ND_PRINT((ndo, "pri 0x%02x, ", (flow & 0x0f000000) >> 24));
- if (flow & 0x00ffffff)
- ND_PRINT((ndo, "flowlabel 0x%06x, ", flow & 0x00ffffff));
-#else
- /* RFC 2460 */
- if (flow & 0x0ff00000)
- ND_PRINT((ndo, "class 0x%02x, ", (flow & 0x0ff00000) >> 20));
- if (flow & 0x000fffff)
- ND_PRINT((ndo, "flowlabel 0x%05x, ", flow & 0x000fffff));
-#endif
-
- ND_PRINT((ndo, "hlim %u, next-header %s (%u) payload length: %u) ",
- EXTRACT_U_1(ip6->ip6_hlim),
- tok2str(ipproto_values,"unknown",nh),
- nh,
- payload_len));
- }
+ payload_len = GET_BE_U_2(ip6->ip6_plen);
+ /*
+ * RFC 1883 says:
+ *
+ * The Payload Length field in the IPv6 header must be set to zero
+ * in every packet that carries the Jumbo Payload option. If a
+ * packet is received with a valid Jumbo Payload option present and
+ * a non-zero IPv6 Payload Length field, an ICMP Parameter Problem
+ * message, Code 0, should be sent to the packet's source, pointing
+ * to the Option Type field of the Jumbo Payload option.
+ *
+ * Later versions of the IPv6 spec don't discuss the Jumbo Payload
+ * option.
+ *
+ * If the payload length is 0, we temporarily just set the total
+ * length to the remaining data in the packet (which, for Ethernet,
+ * could include frame padding, but if it's a Jumbo Payload frame,
+ * it shouldn't even be sendable over Ethernet, so we don't worry
+ * about that), so we can process the extension headers in order
+ * to *find* a Jumbo Payload hop-by-hop option and, when we've
+ * processed all the extension headers, check whether we found
+ * a Jumbo Payload option, and fail if we haven't.
+ */
+ if (payload_len != 0) {
+ len = payload_len + sizeof(struct ip6_hdr);
+ if (length < len)
+ ND_PRINT("truncated-ip6 - %u bytes missing!",
+ len - length);
+ } else
+ len = length + sizeof(struct ip6_hdr);
+
+ ph = 255;
+ nh = GET_U_1(ip6->ip6_nxt);
+ if (ndo->ndo_vflag) {
+ flow = GET_BE_U_4(ip6->ip6_flow);
+ ND_PRINT("(");
+ /* RFC 2460 */
+ if (flow & 0x0ff00000)
+ ND_PRINT("class 0x%02x, ", (flow & 0x0ff00000) >> 20);
+ if (flow & 0x000fffff)
+ ND_PRINT("flowlabel 0x%05x, ", flow & 0x000fffff);
+
+ ND_PRINT("hlim %u, next-header %s (%u) payload length: %u) ",
+ GET_U_1(ip6->ip6_hlim),
+ tok2str(ipproto_values,"unknown",nh),
+ nh,
+ payload_len);
+ }