]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip6.c
Add printing support for vsockmon devices.
[tcpdump] / print-ip6.c
index 50374e089bdca135a3cc3318d4d5821c3a7bc196..9f8b4dbf63734ed7cf5f7fc3dd53eaf43723f36e 100644 (file)
@@ -53,12 +53,13 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst,
        const void *dst_addr;
        const struct ip6_rthdr *dp;
        const struct ip6_rthdr0 *dp0;
+       const struct ip6_srh *srh;
        const u_char *p;
        int i, len;
 
        cp = (const u_char *)ip6;
        advance = sizeof(struct ip6_hdr);
-       nh = EXTRACT_U_1(ip6->ip6_nxt);
+       nh = GET_U_1(ip6->ip6_nxt);
        dst_addr = (const void *)ip6->ip6_dst;
 
        while (cp < ndo->ndo_snapend) {
@@ -77,8 +78,8 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst,
                         * the first 8 octets.
                         */
                        ND_TCHECK_2(cp);
-                       advance = (EXTRACT_U_1(cp + 1) + 1) << 3;
-                       nh = EXTRACT_U_1(cp);
+                       advance = (GET_U_1(cp + 1) + 1) << 3;
+                       nh = GET_U_1(cp);
                        break;
 
                case IPPROTO_FRAGMENT:
@@ -89,7 +90,7 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst,
                         */
                        ND_TCHECK_1(cp);
                        advance = sizeof(struct ip6_frag);
-                       nh = EXTRACT_U_1(cp);
+                       nh = GET_U_1(cp);
                        break;
 
                case IPPROTO_ROUTING:
@@ -98,8 +99,8 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst,
                         */
                        dp = (const struct ip6_rthdr *)cp;
                        ND_TCHECK_SIZE(dp);
-                       len = EXTRACT_U_1(dp->ip6r_len);
-                       switch (EXTRACT_U_1(dp->ip6r_type)) {
+                       len = GET_U_1(dp->ip6r_len);
+                       switch (GET_U_1(dp->ip6r_type)) {
 
                        case IPV6_RTHDR_TYPE_0:
                        case IPV6_RTHDR_TYPE_2:         /* Mobile IPv6 ID-20 */
@@ -114,6 +115,19 @@ ip6_finddst(netdissect_options *ndo, struct in6_addr *dst,
                                        p += 16;
                                }
                                break;
+                       case IPV6_RTHDR_TYPE_4:
+                               /* IPv6 Segment Routing Header (SRH) */
+                               srh = (const struct ip6_srh *)dp;
+                               if (len % 2 == 1)
+                                       goto trunc;
+                               p = (const u_char *) srh->srh_segments;
+                               /*
+                                * The list of segments are encoded in the reverse order.
+                                * Accordingly, the final DA is encoded in srh_segments[0]
+                                */
+                               ND_TCHECK_16(p);
+                               dst_addr = (const void *)p;
+                               break;
 
                        default:
                                break;
@@ -157,7 +171,7 @@ trunc:
 /*
  * Compute a V6-style checksum by building a pseudoheader.
  */
-int
+uint16_t
 nextproto6_cksum(netdissect_options *ndo,
                  const struct ip6_hdr *ip6, const uint8_t *data,
                 u_int len, u_int covlen, u_int next_proto)
@@ -175,7 +189,7 @@ nextproto6_cksum(netdissect_options *ndo,
         /* pseudo-header */
         memset(&ph, 0, sizeof(ph));
         UNALIGNED_MEMCPY(&ph.ph_src, ip6->ip6_src, sizeof (struct in6_addr));
-        nh = EXTRACT_U_1(ip6->ip6_nxt);
+        nh = GET_U_1(ip6->ip6_nxt);
         switch (nh) {
 
         case IPPROTO_HOPOPTS:
@@ -241,15 +255,15 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
           return;
        }
 
-       payload_len = EXTRACT_BE_U_2(ip6->ip6_plen);
+       payload_len = GET_BE_U_2(ip6->ip6_plen);
        len = payload_len + sizeof(struct ip6_hdr);
        if (length < len)
                ND_PRINT("truncated-ip6 - %u bytes missing!",
                        len - length);
 
-        nh = EXTRACT_U_1(ip6->ip6_nxt);
+        nh = GET_U_1(ip6->ip6_nxt);
         if (ndo->ndo_vflag) {
-            flow = EXTRACT_BE_U_4(ip6->ip6_flow);
+            flow = GET_BE_U_4(ip6->ip6_flow);
             ND_PRINT("(");
 #if 0
             /* rfc1883 */
@@ -266,7 +280,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
 #endif
 
             ND_PRINT("hlim %u, next-header %s (%u) payload length: %u) ",
-                         EXTRACT_U_1(ip6->ip6_hlim),
+                         GET_U_1(ip6->ip6_hlim),
                          tok2str(ipproto_values,"unknown",nh),
                          nh,
                          payload_len);
@@ -281,6 +295,7 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
 
        cp = (const u_char *)ip6;
        advance = sizeof(struct ip6_hdr);
+       /* Process extension headers */
        while (cp < ndo->ndo_snapend && advance > 0) {
                if (len < (u_int)advance)
                        goto trunc;
@@ -295,23 +310,26 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
                }
 
                switch (nh) {
+
                case IPPROTO_HOPOPTS:
                        advance = hbhopt_print(ndo, cp);
                        if (advance < 0)
                                return;
-                       nh = EXTRACT_U_1(cp);
+                       nh = GET_U_1(cp);
                        break;
+
                case IPPROTO_DSTOPTS:
                        advance = dstopt_print(ndo, cp);
                        if (advance < 0)
                                return;
-                       nh = EXTRACT_U_1(cp);
+                       nh = GET_U_1(cp);
                        break;
+
                case IPPROTO_FRAGMENT:
                        advance = frag6_print(ndo, cp, (const u_char *)ip6);
                        if (advance < 0 || ndo->ndo_snapend <= cp + advance)
                                return;
-                       nh = EXTRACT_U_1(cp);
+                       nh = GET_U_1(cp);
                        fragmented = 1;
                        break;
 
@@ -328,102 +346,32 @@ ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
                        advance = mobility_print(ndo, cp, (const u_char *)ip6);
                        if (advance < 0)
                                return;
-                       nh = EXTRACT_U_1(cp);
+                       nh = GET_U_1(cp);
                        return;
+
                case IPPROTO_ROUTING:
                        ND_TCHECK_1(cp);
                        advance = rt6_print(ndo, cp, (const u_char *)ip6);
                        if (advance < 0)
                                return;
-                       nh = EXTRACT_U_1(cp);
-                       break;
-               case IPPROTO_SCTP:
-                       sctp_print(ndo, cp, (const u_char *)ip6, len);
-                       return;
-               case IPPROTO_DCCP:
-                       dccp_print(ndo, cp, (const u_char *)ip6, len);
-                       return;
-               case IPPROTO_TCP:
-                       tcp_print(ndo, cp, len, (const u_char *)ip6, fragmented);
-                       return;
-               case IPPROTO_UDP:
-                       udp_print(ndo, cp, len, (const u_char *)ip6, fragmented);
-                       return;
-               case IPPROTO_ICMPV6:
-                       icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented);
-                       return;
-               case IPPROTO_AH:
-                       advance = ah_print(ndo, cp);
-                       if (advance < 0)
-                               return;
-                       nh = EXTRACT_U_1(cp);
-                       break;
-               case IPPROTO_ESP:
-                   {
-                       u_int enh, padlen;
-                       advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen);
-                       if (advance < 0)
-                               return;
-                       nh = enh & 0xff;
-                       len -= padlen;
-                       break;
-                   }
-               case IPPROTO_IPCOMP:
-                   {
-                       ipcomp_print(ndo, cp);
-                       /*
-                        * Either this has decompressed the payload and
-                        * printed it, in which case there's nothing more
-                        * to do, or it hasn't, in which case there's
-                        * nothing more to do.
-                        */
-                       advance = -1;
+                       nh = GET_U_1(cp);
                        break;
-                   }
-
-               case IPPROTO_PIM:
-                       pim_print(ndo, cp, len, (const u_char *)ip6);
-                       return;
-
-               case IPPROTO_OSPF:
-                       ospf6_print(ndo, cp, len);
-                       return;
-
-               case IPPROTO_IPV6:
-                       ip6_print(ndo, cp, len);
-                       return;
-
-               case IPPROTO_IPV4:
-                       ip_print(ndo, cp, len);
-                       return;
-
-                case IPPROTO_PGM:
-                        pgm_print(ndo, cp, len, (const u_char *)ip6);
-                        return;
-
-               case IPPROTO_GRE:
-                       gre_print(ndo, cp, len);
-                       return;
-
-               case IPPROTO_RSVP:
-                       rsvp_print(ndo, cp, len);
-                       return;
-
-               case IPPROTO_EIGRP:
-                       eigrp_print(ndo, cp, len);
-                       return;
-
-               case IPPROTO_NONE:
-                       ND_PRINT("no next header");
-                       return;
 
                default:
-                       ND_PRINT("ip-proto-%u %u", nh, len);
+                       /*
+                        * Not an extension header; hand off to the
+                        * IP protocol demuxer.
+                        */
+                       ip_print_demux(ndo, cp, len, 6, fragmented,
+                           GET_U_1(ip6->ip6_hlim), nh, bp);
                        return;
                }
+
+               /* ndo_protocol reassignment after xxx_print() calls */
+               ndo->ndo_protocol = "ip6";
        }
 
        return;
 trunc:
-       ND_PRINT("[|ip6]");
+       nd_print_trunc(ndo);
 }