]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-erspan.c
CHANGES: Add a change backported to 4.99
[tcpdump] / print-erspan.c
index 6d305edd36acff8c94adc2b17ffce98b1e1a471e..1f8c9f00aa012730b11c9b356b17a91a06bfd1c6 100644 (file)
@@ -66,7 +66,7 @@
 #define ERSPAN2_INDEX_MASK     (0xfffffU << ERSPAN2_INDEX_SHIFT)
 
 void
-erspan_print_i_ii(netdissect_options *ndo, uint16_t flags, const u_char *bp, u_int len)
+erspan_i_ii_print(netdissect_options *ndo, uint16_t flags, const u_char *bp, u_int len)
 {
        uint32_t hdr, ver, vlan, cos, en, sid, index;
 
@@ -169,15 +169,17 @@ invalid:
 #define ERSPAN3_SID_SHIFT              0
 #define ERSPAN3_SID_MASK               (0x3ffU << ERSPAN3_SID_SHIFT)
 #define ERSPAN3_P_SHIFT                        15
-#define ERSPAN3_P_MASK                 (0x1U << ERSPAN3_P_MASK)
+#define ERSPAN3_P_MASK                 (0x1U << ERSPAN3_P_SHIFT)
 #define ERSPAN3_FT_SHIFT               10
-#define ERSPAN3_FT_MASK                        (0x1fU << ERSPAN3_FT_MASK)
+#define ERSPAN3_FT_MASK                        (0x1fU << ERSPAN3_FT_SHIFT)
+#define ERSPAN3_FT_ETHERNET            0
+#define ERSPAN3_FT_IP                  2
 #define ERSPAN3_HW_ID_SHIFT            4
-#define ERSPAN3_HW_ID_MASK             (0x3fU << ERSPAN3_HW_ID_MASK)
+#define ERSPAN3_HW_ID_MASK             (0x3fU << ERSPAN3_HW_ID_SHIFT)
 #define ERSPAN3_D_SHIFT                        3
 #define ERSPAN3_D_MASK                 (0x1U << ERSPAN3_D_SHIFT)
 #define ERSPAN3_GRA_SHIFT              1
-#define ERSPAN3_GRA_MASK               (0x3U << ERSPAN3_GRA_MASK)
+#define ERSPAN3_GRA_MASK               (0x3U << ERSPAN3_GRA_SHIFT)
 #define ERSPAN3_O_SHIFT                        0
 #define ERSPAN3_O_MASK                 (0x1U << ERSPAN3_O_SHIFT)
 
@@ -189,10 +191,16 @@ static const struct tok erspan3_bso_values[] = {
        { 0, NULL }
 };
 
+static const struct tok erspan3_ft_values[] = {
+       { ERSPAN3_FT_ETHERNET, "Ethernet" },
+       { ERSPAN3_FT_IP, "IP" },
+       { 0, NULL }
+};
+
 void
-erspan_print_iii(netdissect_options *ndo, const u_char *bp, u_int len)
+erspan_iii_print(netdissect_options *ndo, const u_char *bp, u_int len)
 {
-       uint32_t hdr, hdr2, ver, cos, sid;
+       uint32_t hdr, hdr2, ver, cos, sid, ft;
 
        ndo->ndo_protocol = "erspan";
        nd_print_protocol(ndo);
@@ -236,11 +244,13 @@ erspan_print_iii(netdissect_options *ndo, const u_char *bp, u_int len)
 
        /* Skip timestamp */
        ND_ICHECK_U(len, <, 4);
+       ND_TCHECK_LEN(bp, 4);
        bp += 4;
        len -= 4;
 
        /* Skip SGT */
        ND_ICHECK_U(len, <, 2);
+       ND_TCHECK_LEN(bp, 2);
        bp += 2;
        len -= 2;
 
@@ -250,16 +260,32 @@ erspan_print_iii(netdissect_options *ndo, const u_char *bp, u_int len)
        bp += 2;
        len -= 2;
 
+       ft = (hdr2 & ERSPAN3_FT_MASK) >> ERSPAN3_FT_SHIFT;
+       ND_PRINT(" ft %s",
+                tok2str(erspan3_ft_values, "unknown %x", ft));
+
+
        /* Do we have the platform-specific header? */
        if (hdr2 & ERSPAN3_O_MASK) {
                /* Yes.  Skip it. */
                ND_ICHECK_U(len, <, 8);
+               ND_TCHECK_LEN(bp, 8);
                bp += 8;
                len -= 8;
        }
 
        ND_PRINT(": ");
-       ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
+
+       switch (ft) {
+
+       case ERSPAN3_FT_ETHERNET:
+               ether_print(ndo, bp, len, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
+               break;
+
+       default:
+               ND_PRINT("Frame type unknown");
+               break;
+       }
        return;
 
 invalid: