]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip6opts.c
gre: add support for MikroTik Ethernet-over-IP hack.
[tcpdump] / print-ip6opts.c
index 4039f44e32ca94cdd0bcde3bc81476f973f64b9a..a78c76daa27def5e848179534e9ba0b4bb883bea 100644 (file)
@@ -88,10 +88,12 @@ trunc:
 
 static int
 ip6_opt_process(netdissect_options *ndo, const u_char *bp, int len,
-               int *found_jumbo, uint32_t *jumbolen)
+               int *found_jumbop, uint32_t *payload_len)
 {
     int i;
     int optlen = 0;
+    int found_jumbo = 0;
+    uint32_t jumbolen = 0;
 
     if (len == 0)
         return 0;
@@ -141,10 +143,39 @@ ip6_opt_process(netdissect_options *ndo, const u_char *bp, int len,
                ND_PRINT("(jumbo: invalid len %u)", GET_U_1(bp + i + 1));
                goto trunc;
            }
-           *found_jumbo = 1;
-           *jumbolen = GET_BE_U_4(bp + i + 2);
-           if (ndo->ndo_vflag)
-               ND_PRINT("(jumbo: %u) ", *jumbolen);
+           jumbolen = GET_BE_U_4(bp + i + 2);
+           if (found_jumbo) {
+               /* More than one Jumbo Payload option */
+               if (ndo->ndo_vflag)
+                   ND_PRINT("(jumbo: %u - already seen) ", jumbolen);
+           } else {
+               found_jumbo = 1;
+               if (payload_len == NULL) {
+                   /* Not a hop-by-hop option - not valid */
+                   if (ndo->ndo_vflag)
+                       ND_PRINT("(jumbo: %u - not a hop-by-hop option) ", jumbolen);
+               } else if (*payload_len != 0) {
+                   /* Payload length was non-zero - not valid */
+                   if (ndo->ndo_vflag)
+                       ND_PRINT("(jumbo: %u - payload len != 0) ", jumbolen);
+               } else {
+                   /*
+                    * This is a hop-by-hop option, and Payload length
+                    * was zero in the IPv6 header.
+                    */
+                   if (jumbolen < 65536) {
+                       /* Too short */
+                       if (ndo->ndo_vflag)
+                           ND_PRINT("(jumbo: %u - < 65536) ", jumbolen);
+                   } else {
+                       /* OK, this is valid */
+                       *found_jumbop = 1;
+                       *payload_len = jumbolen;
+                       if (ndo->ndo_vflag)
+                           ND_PRINT("(jumbo: %u) ", jumbolen);
+                   }
+               }
+           }
            break;
         case IP6OPT_HOME_ADDRESS:
            if (len - i < IP6OPT_HOMEADDR_MINLEN) {
@@ -156,7 +187,7 @@ ip6_opt_process(netdissect_options *ndo, const u_char *bp, int len,
                goto trunc;
            }
            if (ndo->ndo_vflag) {
-               ND_PRINT("(homeaddr: %s", ip6addr_string(ndo, bp + i + 2));
+               ND_PRINT("(homeaddr: %s", GET_IP6ADDR_STRING(bp + i + 2));
                if (GET_U_1(bp + i + 1) > IP6OPT_HOMEADDR_MINLEN - 2) {
                    if (ip6_sopt_print(ndo, bp + i + IP6OPT_HOMEADDR_MINLEN,
                                       (optlen - IP6OPT_HOMEADDR_MINLEN)) == -1)
@@ -192,7 +223,6 @@ hbhopt_process(netdissect_options *ndo, const u_char *bp, int *found_jumbo,
     u_int hbhlen = 0;
 
     ndo->ndo_protocol = "hbhopt";
-    ND_TCHECK_1(dp->ip6h_len);
     hbhlen = (GET_U_1(dp->ip6h_len) + 1) << 3;
     ND_TCHECK_LEN(dp, hbhlen);
     ND_PRINT("HBH ");
@@ -211,22 +241,19 @@ dstopt_process(netdissect_options *ndo, const u_char *bp)
 {
     const struct ip6_dest *dp = (const struct ip6_dest *)bp;
     u_int dstoptlen = 0;
-    int found_jumbo;
-    uint32_t jumbolen;
 
     ndo->ndo_protocol = "dstopt";
-    ND_TCHECK_1(dp->ip6d_len);
     dstoptlen = (GET_U_1(dp->ip6d_len) + 1) << 3;
     ND_TCHECK_LEN(dp, dstoptlen);
     ND_PRINT("DSTOPT ");
     if (ndo->ndo_vflag) {
        /*
-        * The Jumbo Payload option is a hop-by-hop option; we print,
-        * but don't honor, Jumbo Payload destination options.
+        * The Jumbo Payload option is a hop-by-hop option; we don't
+        * honor Jumbo Payload destination options, reporting them
+        * as invalid.
         */
        if (ip6_opt_process(ndo, (const u_char *)dp + sizeof(*dp),
-                           dstoptlen - sizeof(*dp), &found_jumbo,
-                           &jumbolen) == -1)
+                           dstoptlen - sizeof(*dp), NULL, NULL) == -1)
            goto trunc;
     }