]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Merge pull request #48 from alagoutte/master
authorMichael Richardson <[email protected]>
Wed, 13 Feb 2013 00:26:02 +0000 (16:26 -0800)
committerMichael Richardson <[email protected]>
Wed, 13 Feb 2013 00:26:02 +0000 (16:26 -0800)
Update to final draft : RFC6810

14 files changed:
Makefile.in
interface.h
netdissect.h
print-isoclns.c
print-stp.c
print-tcp.c
print-zeromq.c [new file with mode: 0644]
tcpdump.1.in
tcpdump.c
tests/TESTLIST
tests/spb_bpduv4.out [new file with mode: 0644]
tests/spb_bpduv4.pcap [new file with mode: 0644]
tests/zmtp1.out [new file with mode: 0644]
tests/zmtp1.pcap [new file with mode: 0644]

index 3b589dc749aa9fa57c3fba686fd346b98a9d4894..16b45ecbb259bc7a48ea9910690e4ff2d22303b6 100644 (file)
@@ -93,7 +93,7 @@ CSRC =        addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c
        print-symantec.c print-syslog.c print-tcp.c print-telnet.c print-tftp.c \
        print-timed.c print-tipc.c print-token.c print-udld.c print-udp.c \
        print-usb.c print-vjc.c print-vqp.c print-vrrp.c print-vtp.c \
-       print-wb.c print-zephyr.c signature.c setsignal.c tcpdump.c util.c
+       print-wb.c print-zephyr.c print-zeromq.c signature.c setsignal.c tcpdump.c util.c
 
 LIBNETDISSECT_SRC=print-isakmp.c
 LIBNETDISSECT_OBJ=$(LIBNETDISSECT_SRC:.c=.o)
index 8602d470085c590e1392cd29b1d8ce699a018ab3..57d4636dd72884f50d31696c53036ea46392f1b0 100644 (file)
@@ -70,8 +70,9 @@ extern char *strsep(char **, const char *);
 #define PT_CNFP                7       /* Cisco NetFlow protocol */
 #define PT_TFTP                8       /* trivial file transfer protocol */
 #define PT_AODV                9       /* Ad-hoc On-demand Distance Vector Protocol */
-#define PT_CARP         10      /* Common Address Redundancy Protocol */
-#define PT_RADIUS       11      /* RADIUS authentication Protocol */
+#define PT_CARP                10      /* Common Address Redundancy Protocol */
+#define PT_RADIUS      11      /* RADIUS authentication Protocol */
+#define PT_ZMTP1       12      /* ZeroMQ Message Transport Protocol 1.0 */
 
 #ifndef min
 #define min(a,b) ((a)>(b)?(b):(a))
@@ -311,6 +312,7 @@ extern void forces_print(const u_char *, u_int);
 extern void mpls_print(const u_char *, u_int);
 extern void mpls_lsp_ping_print(const u_char *, u_int);
 extern void zephyr_print(const u_char *, int);
+extern void zmtp1_print(const u_char *, u_int);
 extern void hsrp_print(const u_char *, u_int);
 extern void bfd_print(const u_char *, u_int, u_int);
 extern void sip_print(const u_char *, u_int);
index 26df79cb6e10b6adc6b2919b98beccb74715b6f9..f187fd5d9db912693e615d27d578a6b41b5d3a82 100644 (file)
@@ -179,8 +179,9 @@ struct netdissect_options {
 #define PT_CNFP                7       /* Cisco NetFlow protocol */
 #define PT_TFTP                8       /* trivial file transfer protocol */
 #define PT_AODV                9       /* Ad-hoc On-demand Distance Vector Protocol */
-#define PT_CARP         10      /* Common Address Redundancy Protocol */
-#define PT_RADIUS       11      /* RADIUS authentication Protocol */
+#define PT_CARP                10      /* Common Address Redundancy Protocol */
+#define PT_RADIUS      11      /* RADIUS authentication Protocol */
+#define PT_ZMTP1       12      /* ZeroMQ Message Transport Protocol 1.0 */
 
 #ifndef min
 #define min(a,b) ((a)>(b)?(b):(a))
index b8b181384145316a8105ffacee835ad39777beb0..4f8a5bb7d13a7d747d6a8bcae5973d2eef566f04 100644 (file)
@@ -1328,8 +1328,7 @@ isis_print_mcid (const struct isis_spb_mcid *mcid)
 static int
 isis_print_mt_port_cap_subtlv (const u_int8_t *tptr, int len)
 {
-  int stlv_type;
-  int stlv_len;
+  int stlv_type, stlv_len;
   const struct isis_subtlv_spb_mcid *subtlv_spb_mcid;
   int i;
 
@@ -1344,79 +1343,87 @@ isis_print_mt_port_cap_subtlv (const u_int8_t *tptr, int len)
                stlv_type,
                stlv_len);
 
+    /*len -= TLV_TYPE_LEN_OFFSET;*/
     len = len -2;
 
     switch (stlv_type)
     {
       case ISIS_SUBTLV_SPB_MCID:
+      {
+        if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN))
+          goto trunctlv;
 
-          if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN))
-            goto trunctlv;
+        subtlv_spb_mcid = (struct isis_subtlv_spb_mcid *)tptr;
 
-          subtlv_spb_mcid = (struct isis_subtlv_spb_mcid *)tptr;
+        printf( "\n\t         MCID: ");
+        isis_print_mcid (&(subtlv_spb_mcid->mcid));
 
-          printf( "\n\t         MCID: ");
-          isis_print_mcid (&(subtlv_spb_mcid->mcid));
+          /*tptr += SPB_MCID_MIN_LEN;
+            len -= SPB_MCID_MIN_LEN; */
 
-          printf( "\n\t         AUX-MCID: ");
-          isis_print_mcid (&(subtlv_spb_mcid->aux_mcid));
+        printf( "\n\t         AUX-MCID: ");
+        isis_print_mcid (&(subtlv_spb_mcid->aux_mcid));
 
-          tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
-          len = len - sizeof(struct isis_subtlv_spb_mcid);
+          /*tptr += SPB_MCID_MIN_LEN;
+            len -= SPB_MCID_MIN_LEN; */
+        tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
+        len = len - sizeof(struct isis_subtlv_spb_mcid);
 
-          break;
+        break;
+      }
 
       case ISIS_SUBTLV_SPB_DIGEST:
+      {
+        if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN))
+          goto trunctlv;
 
-          if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN))
-            goto trunctlv;
-
-          printf ("\n\t         RES: %d V: %d A: %d D: %d",
+        printf ("\n\t        RES: %d V: %d A: %d D: %d",
                         (*(tptr) >> 5), (((*tptr)>> 4) & 0x01),
                         ((*(tptr) >> 2) & 0x03), ((*tptr) & 0x03));
 
-          tptr++;
+        tptr++;
 
-          printf( "\n\t         Digest: ");
+        printf( "\n\t         Digest: ");
           
-          for(i=1;i<=8; i++)
-          {
+        for(i=1;i<=8; i++)
+        {
             printf("%08x ", EXTRACT_32BITS(tptr));
             if (i%4 == 0 && i != 8)
               printf("\n\t                 ");
             tptr = tptr + 4;
-          }
+        }
 
-          len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
+        len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
 
-          break;
+        break;
+      }
 
       case ISIS_SUBTLV_SPB_BVID:
+      {
+        if (!TTEST2(*(tptr), stlv_len))
+          goto trunctlv;
 
-          if (!TTEST2(*(tptr), stlv_len))
+        while (len)
+        {
+          if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN))
             goto trunctlv;
 
-          while (len)
-          {
-            if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN))
-              goto trunctlv;
-
-            printf("\n\t           ECT: %08x", 
+          printf("\n\t           ECT: %08x", 
                       EXTRACT_32BITS(tptr));
 
-            tptr = tptr+4;
+          tptr = tptr+4;
 
-            printf(" B-Vlan: %d, U:%01x, M:%01x RES: %01x",
+          printf(" BVID: %d, U:%01x M:%01x ",
                      (EXTRACT_16BITS (tptr) >> 4) ,
                      (EXTRACT_16BITS (tptr) >> 3) & 0x01,
-                     (EXTRACT_16BITS (tptr) >> 2) & 0x01,
-                     (EXTRACT_16BITS (tptr) & 0x03));
+                     (EXTRACT_16BITS (tptr) >> 2) & 0x01);
 
-            tptr = tptr + 2;
-            len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
-          }
+          tptr = tptr + 2;
+          len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
+        }
 
-          break;
+        break;
+      }
       
       default:
           break;
@@ -1430,7 +1437,6 @@ isis_print_mt_port_cap_subtlv (const u_int8_t *tptr, int len)
     return(1); 
 }
 
-
 static int
 isis_print_mt_capability_subtlv (const u_int8_t *tptr, int len)
 {
@@ -2754,7 +2760,7 @@ static int isis_print (const u_int8_t *p, u_int length)
            break;
 
     case ISIS_TLV_MT_PORT_CAP:
-
+    {
       if (!TTEST2(*(tptr), 2))
         goto trunctlv;
 
@@ -2767,7 +2773,9 @@ static int isis_print (const u_int8_t *p, u_int length)
 
       if (tmp)
         isis_print_mt_port_cap_subtlv (tptr, tmp);
+
       break;
+    }
 
     case ISIS_TLV_MT_CAPABILITY:
 
index 8822c3046d0b026347c68054e3317e40733bc3d0..7880268acee5b77abcdaae63a5533fb21c8df532 100644 (file)
@@ -52,11 +52,13 @@ struct stp_bpdu_ {
 #define STP_PROTO_REGULAR 0x00
 #define STP_PROTO_RAPID   0x02
 #define STP_PROTO_MSTP    0x03
+#define STP_PROTO_SPB     0x04
 
 struct tok stp_proto_values[] = {
     { STP_PROTO_REGULAR, "802.1d" },
     { STP_PROTO_RAPID, "802.1w" },
     { STP_PROTO_MSTP, "802.1s" },
+    { STP_PROTO_SPB, "802.1aq" },
     { 0, NULL}
 };
 
@@ -164,6 +166,30 @@ stp_print_config_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
  * 1 -  byte  CIST Remaining Hops
  * 16 - bytes MSTI information [Max 64 MSTI, each 16 bytes]
  *
+ *
+ * SPB BPDU
+ * Ref. IEEE 802.1aq. Section 14
+ *
+ * 2 -  bytes Version 4 length
+ * 1 -  byte  Aux Config Identifier  
+ * 32 - bytes Aux Config Name
+ * 2 -  bytes Aux Revision level
+ * 16 - bytes Aux Config Digest [MD5]
+ * 1 -  byte  (1 - 2) Agreement Number 
+ *            (3 - 4) Discarded Agreement Number
+ *            (5) Agreement Valid Flag
+ *            (6) Restricted Role Flag
+ *            (7 - 8) Unused sent zero
+ * 1 -  byte Unused
+ * 1 -  byte (1 - 4) Agreement Digest Format Identifier
+ *           (5 - 8) Agreement Digest Format Capabilities
+ * 1 -  byte (1 - 4) Agreement Digest Convention Identifier
+ *           (5 - 8) Agreement Digest Convention Capabilities
+ * 2 -  bytes Agreement Digest Edge Count
+ * 8 -  byte Reserved Set
+ * 20 - bytes Computed Topology Digest
+ *
+ *
  * MSTI Payload
  *
  * 1 - byte  MSTI flag
@@ -172,6 +198,7 @@ stp_print_config_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
  * 1 - byte  MSTI Bridge Priority
  * 1 - byte  MSTI Port Priority
  * 1 - byte  MSTI Remaining Hops
+ *
  */
 
 #define MST_BPDU_MSTI_LENGTH               16
@@ -192,18 +219,32 @@ stp_print_config_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
 #define MST_BPDU_MSTI_PORT_PRIO_OFFSET     14
 #define MST_BPDU_MSTI_REMAIN_HOPS_OFFSET    15
 
+#define SPB_BPDU_MIN_LEN                  87
+#define SPB_BPDU_CONFIG_NAME_OFFSET       3
+#define SPB_BPDU_CONFIG_REV_OFFSET        SPB_BPDU_CONFIG_NAME_OFFSET + 32
+#define SPB_BPDU_CONFIG_DIGEST_OFFSET     SPB_BPDU_CONFIG_REV_OFFSET + 2
+#define SPB_BPDU_AGREEMENT_OFFSET         SPB_BPDU_CONFIG_DIGEST_OFFSET + 16
+#define SPB_BPDU_AGREEMENT_UNUSED_OFFSET  SPB_BPDU_AGREEMENT_OFFSET + 1
+#define SPB_BPDU_AGREEMENT_FORMAT_OFFSET  SPB_BPDU_AGREEMENT_UNUSED_OFFSET + 1
+#define SPB_BPDU_AGREEMENT_CON_OFFSET     SPB_BPDU_AGREEMENT_FORMAT_OFFSET + 1
+#define SPB_BPDU_AGREEMENT_EDGE_OFFSET    SPB_BPDU_AGREEMENT_CON_OFFSET + 1
+#define SPB_BPDU_AGREEMENT_RES1_OFFSET    SPB_BPDU_AGREEMENT_EDGE_OFFSET + 2
+#define SPB_BPDU_AGREEMENT_RES2_OFFSET    SPB_BPDU_AGREEMENT_RES1_OFFSET + 4
+#define SPB_BPDU_AGREEMENT_DIGEST_OFFSET  SPB_BPDU_AGREEMENT_RES2_OFFSET + 4
+
+
 static void
 stp_print_mstp_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
 {
-    const u_char    *ptr;
+    const u_char *ptr;
     u_int16_t      v3len;
     u_int16_t      len;
     u_int16_t      msti;
     u_int16_t      offset;
 
     ptr = (const u_char *)stp_bpdu;
-    printf(", CIST Flags [%s]",
-           bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags));
+    printf(", CIST Flags [%s], length %u",
+           bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags), length);
 
     /*
      * in non-verbose mode just print the flags. We dont read that much
@@ -213,10 +254,18 @@ stp_print_mstp_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
         return;
     }
 
-    printf(", CIST bridge-id %s.%04x, length %u",
-           stp_print_bridge_id(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET),
-           EXTRACT_16BITS(&stp_bpdu->port_id), length);
+    printf("\n\tport-role %s, ",
+           tok2str(rstp_obj_port_role_values, "Unknown",
+                   RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)));
+
+    printf("CIST root-id %s, CIST ext-pathcost %u ",
+           stp_print_bridge_id((const u_char *)&stp_bpdu->root_id),
+           EXTRACT_32BITS(&stp_bpdu->root_path_cost));
 
+    printf("\n\tCIST regional-root-id %s, ",
+           stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id));
+
+    printf("CIST port-id %04x, ", EXTRACT_16BITS(&stp_bpdu->port_id));
 
     printf("\n\tmessage-age %.2fs, max-age %.2fs"
            ", hello-time %.2fs, forwarding-delay %.2fs",
@@ -225,27 +274,23 @@ stp_print_mstp_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
            (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE,
            (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE);
 
-    printf("\n\tCIST root-id %s, ext-pathcost %u int-pathcost %u",
-           stp_print_bridge_id((const u_char *)&stp_bpdu->root_id),
-           EXTRACT_32BITS(&stp_bpdu->root_path_cost),
-           EXTRACT_32BITS(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET));
+    printf ("\n\tv3len %d, ", EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET));
+    printf("MCID Name %s, rev %u, "
+            "\n\t\tdigest %08x%08x%08x%08x, ",
+            ptr + MST_BPDU_CONFIG_NAME_OFFSET,
+                 EXTRACT_16BITS(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32),
+           EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET),
+                 EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4),
+                 EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8),
+                 EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12));
 
-    printf(", port-role %s",
-           tok2str(rstp_obj_port_role_values, "Unknown",
-                   RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)));
-
-    printf("\n\tCIST regional-root-id %s",
-           stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id));
+    printf ("CIST int-root-pathcost %u, ", 
+            EXTRACT_32BITS(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET));  
 
-    printf("\n\tMSTP Configuration Name %s, revision %u, digest %08x%08x%08x%08x",
-           ptr + MST_BPDU_CONFIG_NAME_OFFSET,
-          EXTRACT_16BITS(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32),
-          EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET),
-          EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4),
-          EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8),
-          EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12));
+    printf("\n\tCIST bridge-id %s, ",
+           stp_print_bridge_id(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET));
 
-    printf("\n\tCIST remaining-hops %d", ptr[MST_BPDU_CIST_REMAIN_HOPS_OFFSET]);
+    printf("CIST remaining-hops %d", ptr[MST_BPDU_CIST_REMAIN_HOPS_OFFSET]);
 
     /* Dump all MSTI's */
     v3len = EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET);
@@ -275,16 +320,48 @@ stp_print_mstp_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
             offset += MST_BPDU_MSTI_LENGTH;
         }
     }
+
+    if ((length-offset) >= SPB_BPDU_MIN_LEN)
+    {
+      printf("\n\tv4len %d AUXMCID Name %s, Rev %u, \n\t\tdigest %08x%08x%08x%08x",
+              EXTRACT_16BITS (ptr + offset),
+              ptr + offset + SPB_BPDU_CONFIG_NAME_OFFSET,
+              EXTRACT_16BITS(ptr + offset + SPB_BPDU_CONFIG_REV_OFFSET),
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET),
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 4),
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 8),
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 12));
+     
+      printf("\n\tAgreement num %d, Discarded Agreement num %d, Agreement valid-"
+              "flag %d, \n\tRestricted role-flag: %d, Format id %d cap %d, "
+              "Convention id %d cap %d, \n\tEdge count %d, "
+              "Agreement digest %08x%08x%08x%08x%08x\n",
+              ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>6, 
+              ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>4 & 0x3,
+              ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>3 & 0x1,
+              ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>2 & 0x1,
+              ptr[offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET]>>4,
+              ptr[offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET]&0x00ff,
+              ptr[offset + SPB_BPDU_AGREEMENT_CON_OFFSET]>>4,
+              ptr[offset + SPB_BPDU_AGREEMENT_CON_OFFSET]&0x00ff,
+              EXTRACT_16BITS(ptr + offset + SPB_BPDU_AGREEMENT_EDGE_OFFSET),
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET),
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+4,
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+8,
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+12,
+              EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+16);
+      }
 }
 
 /*
- * Print 802.1d / 802.1w / 802.1q (mstp) packets.
+ * Print 802.1d / 802.1w / 802.1q (mstp) / 802.1aq (spb) packets.
  */
 void
 stp_print(const u_char *p, u_int length)
 {
     const struct stp_bpdu_ *stp_bpdu;
     u_int16_t              mstp_len;
+    u_int16_t              spb_len;
     
     stp_bpdu = (struct stp_bpdu_*)p;
 
@@ -304,6 +381,7 @@ stp_print(const u_char *p, u_int length)
     case STP_PROTO_REGULAR:
     case STP_PROTO_RAPID:
     case STP_PROTO_MSTP:
+    case STP_PROTO_SPB:
         break;
     default:
         return;
@@ -326,20 +404,35 @@ stp_print(const u_char *p, u_int length)
                 goto trunc;
             }
             stp_print_config_bpdu(stp_bpdu, length);
-        } else if (stp_bpdu->protocol_version == STP_PROTO_MSTP) {
+        } else if (stp_bpdu->protocol_version == STP_PROTO_MSTP ||
+                   stp_bpdu->protocol_version == STP_PROTO_SPB) {
             if (length < STP_BPDU_MSTP_MIN_LEN) {
                 goto trunc;
             }
+
             if (stp_bpdu->v1_length != 0) {
                 /* FIX ME: Emit a message here ? */
                 goto trunc;
             }
+
             /* Validate v3 length */
             mstp_len = EXTRACT_16BITS(p + MST_BPDU_VER3_LEN_OFFSET);
             mstp_len += 2;  /* length encoding itself is 2 bytes */
             if (length < (sizeof(struct stp_bpdu_) + mstp_len)) {
                 goto trunc;
             }
+
+            if (stp_bpdu->protocol_version == STP_PROTO_SPB)
+            {
+              /* Validate v4 length */
+              spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
+              spb_len += 2;
+              if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) ||
+                  spb_len < SPB_BPDU_MIN_LEN) {
+                goto trunc;
+              }
+            }
+
             stp_print_mstp_bpdu(stp_bpdu, length);
         }
         break;
index 88b461576df9a2cfe8d12d74ca87f91faff141cd..3b0a13541afce82b1da3b26b144efd4678c8fc2f 100644 (file)
@@ -639,6 +639,15 @@ tcp_print(register const u_char *bp, register u_int length,
                 return;
         } 
 
+        if (packettype) {
+                switch (packettype) {
+                case PT_ZMTP1:
+                        zmtp1_print(bp, length);
+                        break;
+                }
+                return;
+        }
+
         if (sport == TELNET_PORT || dport == TELNET_PORT) {
                 if (!qflag && vflag)
                         telnet_print(bp, length);
diff --git a/print-zeromq.c b/print-zeromq.c
new file mode 100644 (file)
index 0000000..d5ac4bd
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * This file implements decoding of ZeroMQ network protocol(s).
+ *
+ *
+ * Copyright (c) 2013 The TCPDUMP project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "extract.h"
+
+/* Maximum number of ZMTP/1.0 frame body bytes (without the flags) to dump in
+ * hex and ASCII under a single "-v" flag.
+ */
+#define VBYTES 128
+
+/*
+ * Below is an excerpt from the "13/ZMTP" specification:
+ *
+ * A ZMTP message consists of 1 or more frames.
+ *
+ * A ZMTP frame consists of a length, followed by a flags field and a frame
+ * body of (length - 1) octets. Note: the length includes the flags field, so
+ * an empty frame has a length of 1.
+ *
+ * For frames with a length of 1 to 254 octets, the length SHOULD BE encoded
+ * as a single octet. The minimum valid length of a frame is 1 octet, thus a
+ * length of 0 is invalid and such frames SHOULD be discarded silently.
+ *
+ * For frames with lengths of 255 and greater, the length SHALL BE encoded as
+ * a single octet with the value 255, followed by the length encoded as a
+ * 64-bit unsigned integer in network byte order. For frames with lengths of
+ * 1 to 254 octets this encoding MAY be also used.
+ *
+ * The flags field consists of a single octet containing various control
+ * flags. Bit 0 is the least significant bit.
+ *
+ * - Bit 0 (MORE): More frames to follow. A value of 0 indicates that there
+ *   are no more frames to follow. A value of 1 indicates that more frames
+ *   will follow. On messages consisting of a single frame the MORE flag MUST
+ *   be 0.
+ *
+ * - Bits 1-7: Reserved. Bits 1-7 are reserved for future use and SHOULD be
+ *   zero.
+ */
+
+static const u_char *
+zmtp1_print_frame(const u_char *cp, const u_char *ep) {
+       u_int64_t body_len_declared, body_len_captured, header_len;
+       u_int8_t flags;
+
+       printf("\n\t");
+       TCHECK2(*cp, 1); /* length/0xFF */
+
+       if (cp[0] != 0xFF) {
+               header_len = 1; /* length */
+               body_len_declared = cp[0];
+               if (body_len_declared == 0)
+                       return cp + header_len; /* skip to next frame */
+               printf(" frame flags+body  (8-bit) length %"PRIu8"", cp[0]);
+               TCHECK2(*cp, header_len + 1); /* length, flags */
+               flags = cp[1];
+       } else {
+               header_len = 1 + 8; /* 0xFF, length */
+               printf(" frame flags+body (64-bit) length");
+               TCHECK2(*cp, header_len); /* 0xFF, length */
+               body_len_declared = EXTRACT_64BITS(cp + 1);
+               if (body_len_declared == 0)
+                       return cp + header_len; /* skip to next frame */
+               printf(" %"PRIu64"", body_len_declared);
+               TCHECK2(*cp, header_len + 1); /* 0xFF, length, flags */
+               flags = cp[9];
+       }
+
+       body_len_captured = ep - cp - header_len;
+       if (body_len_declared > body_len_captured)
+               printf(" (%"PRIu64" captured)", body_len_captured);
+       printf(", flags 0x%02"PRIx8"", flags);
+
+       if (vflag) {
+               u_int64_t body_len_printed = MIN(body_len_captured, body_len_declared);
+
+               printf(" (%s|%s|%s|%s|%s|%s|%s|%s)",
+                       flags & 0x80 ? "MBZ" : "-",
+                       flags & 0x40 ? "MBZ" : "-",
+                       flags & 0x20 ? "MBZ" : "-",
+                       flags & 0x10 ? "MBZ" : "-",
+                       flags & 0x08 ? "MBZ" : "-",
+                       flags & 0x04 ? "MBZ" : "-",
+                       flags & 0x02 ? "MBZ" : "-",
+                       flags & 0x01 ? "MORE" : "-");
+
+               if (vflag == 1)
+                       body_len_printed = MIN(VBYTES + 1, body_len_printed);
+               if (body_len_printed > 1) {
+                       printf(", first %"PRIu64" byte(s) of body:", body_len_printed - 1);
+                       hex_and_ascii_print("\n\t ", cp + header_len + 1, body_len_printed - 1);
+                       printf("\n");
+               }
+       }
+
+       TCHECK2(*cp, header_len + body_len_declared); /* Next frame within the buffer ? */
+       return cp + header_len + body_len_declared;
+
+trunc:
+       printf(" [|zmtp1]");
+       return ep;
+}
+
+void
+zmtp1_print(const u_char *cp, u_int len) {
+       const u_char *ep = MIN(snapend, cp + len);
+
+       printf(": ZMTP/1.0");
+       while (cp < ep)
+               cp = zmtp1_print_frame(cp, ep);
+}
+
index b9e2b8e7b4ce004556ca630d119e650899906db7..d22232614f6eb9324d286f30de8b95a0bdf67f28 100644 (file)
@@ -526,8 +526,9 @@ Currently known types are
 \fBsnmp\fR (Simple Network Management Protocol),
 \fBtftp\fR (Trivial File Transfer Protocol),
 \fBvat\fR (Visual Audio Tool),
+\fBwb\fR (distributed White Board),
 and
-\fBwb\fR (distributed White Board).
+\fBzmtp1\fR (ZeroMQ Message Transport Protocol 1.0).
 .TP
 .B \-t
 \fIDon't\fP print a timestamp on each dump line.
index 49029b8988ab6486fdf4627fc41fe356673dd0a5..ad07df6f4a97c45fd1877a72123f8438b6959576 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -1011,6 +1011,8 @@ main(int argc, char **argv)
                                packettype = PT_CARP;
                        else if (strcasecmp(optarg, "radius") == 0)
                                packettype = PT_RADIUS;
+                       else if (strcasecmp(optarg, "zmtp1") == 0)
+                               packettype = PT_ZMTP1;
                        else
                                error("unknown packet type `%s'", optarg);
                        break;
index 408034316cd2b10f1e6709a16f9e575ac8e51396..aed8e0643eb44ddeefca5ac18606ac0fe98f3359 100644 (file)
@@ -71,6 +71,9 @@ icmpv6          icmpv6.pcap             icmpv6.out      -t -vv
 # SPB tests
 spb                spb.pcap                spb.out -t
 
+# SPB BPDUv4 tests
+spb_bpduv4      spb_bpduv4.pcap       spb_bpduv4.out -t
+
 # RIP tests
 ripv1v2         ripv1v2.pcap            ripv1v2.out     -t -v
 ripv2_auth      ripv2_auth.pcap         ripv2_auth.out  -t -v
@@ -80,3 +83,6 @@ dhcpv6-aftr-name      dhcpv6-AFTR-Name-RFC6334.pcap   dhcpv6-AFTR-Name-RFC6334.out    -t -
 dhcpv6-ia-na   dhcpv6-ia-na.pcap       dhcpv6-ia-na.out        -t -v
 dhcpv6-ia-pd   dhcpv6-ia-pd.pcap       dhcpv6-ia-pd.out        -t -v
 dhcpv6-ia-ta   dhcpv6-ia-ta.pcap       dhcpv6-ia-ta.out        -t -v
+
+# ZeroMQ tests
+zmtp1v         zmtp1.pcap              zmtp1.out       -t -v -T zmtp1
diff --git a/tests/spb_bpduv4.out b/tests/spb_bpduv4.out
new file mode 100644 (file)
index 0000000..748d4d2
--- /dev/null
@@ -0,0 +1,25 @@
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
+STP 802.1aq, Rapid STP, CIST Flags [Learn, Forward], length 205
diff --git a/tests/spb_bpduv4.pcap b/tests/spb_bpduv4.pcap
new file mode 100644 (file)
index 0000000..b12d4c1
Binary files /dev/null and b/tests/spb_bpduv4.pcap differ
diff --git a/tests/zmtp1.out b/tests/zmtp1.out
new file mode 100644 (file)
index 0000000..5b52877
--- /dev/null
@@ -0,0 +1,73 @@
+IP (tos 0x0, ttl 64, id 17993, offset 0, flags [DF], proto TCP (6), length 60)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [S], cksum 0xfe30 (incorrect -> 0x1a9d), seq 2523978814, win 32792, options [mss 16396,sackOK,TS val 245537399 ecr 0,nop,wscale 7], length 0
+IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
+    127.0.0.1.33000 > 127.0.0.1.55358: Flags [S.], cksum 0xfe30 (incorrect -> 0x31b6), seq 3988083230, ack 2523978815, win 32768, options [mss 16396,sackOK,TS val 245537399 ecr 245537399,nop,wscale 7], length 0
+IP (tos 0x0, ttl 64, id 17994, offset 0, flags [DF], proto TCP (6), length 52)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [.], cksum 0xfe28 (incorrect -> 0x19da), ack 1, win 257, options [nop,nop,TS val 245537399 ecr 245537399], length 0
+IP (tos 0x0, ttl 64, id 17995, offset 0, flags [DF], proto TCP (6), length 54)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [P.], cksum 0xfe2a (incorrect -> 0x18d0), seq 1:3, ack 1, win 257, options [nop,nop,TS val 245537399 ecr 245537399], length 2: ZMTP/1.0
+        frame flags+body  (8-bit) length 1, flags 0x00 (-|-|-|-|-|-|-|-)
+IP (tos 0x0, ttl 64, id 51304, offset 0, flags [DF], proto TCP (6), length 52)
+    127.0.0.1.33000 > 127.0.0.1.55358: Flags [.], cksum 0xfe28 (incorrect -> 0x19d9), ack 3, win 256, options [nop,nop,TS val 245537399 ecr 245537399], length 0
+IP (tos 0x0, ttl 64, id 51305, offset 0, flags [DF], proto TCP (6), length 54)
+    127.0.0.1.33000 > 127.0.0.1.55358: Flags [P.], cksum 0xfe2a (incorrect -> 0x18cf), seq 1:3, ack 3, win 256, options [nop,nop,TS val 245537399 ecr 245537399], length 2: ZMTP/1.0
+        frame flags+body  (8-bit) length 1, flags 0x00 (-|-|-|-|-|-|-|-)
+IP (tos 0x0, ttl 64, id 17996, offset 0, flags [DF], proto TCP (6), length 52)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [.], cksum 0xfe28 (incorrect -> 0x19d6), ack 3, win 257, options [nop,nop,TS val 245537399 ecr 245537399], length 0
+IP (tos 0x0, ttl 64, id 17997, offset 0, flags [DF], proto TCP (6), length 148)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [P.], cksum 0xfe88 (incorrect -> 0x11da), seq 3:99, ack 3, win 257, options [nop,nop,TS val 245537399 ecr 245537399], length 96: ZMTP/1.0
+        frame flags+body  (8-bit) length 1, flags 0x01 (-|-|-|-|-|-|-|MORE)
+        frame flags+body  (8-bit) length 93, flags 0x00 (-|-|-|-|-|-|-|-), first 92 byte(s) of body:
+        0x0000:  5468 6973 2069 7320 6120 7368 6f72 7420  This.is.a.short.
+        0x0010:  4153 4349 4920 6d65 7373 6167 6520 666f  ASCII.message.fo
+        0x0020:  6c6c 6f77 6564 2062 7920 6120 7368 6f72  llowed.by.a.shor
+        0x0030:  7420 6269 6e61 7279 206d 6573 7361 6765  t.binary.message
+        0x0040:  2061 6e64 2061 206c 6f6e 6765 7220 4153  .and.a.longer.AS
+        0x0050:  4349 4920 6d65 7373 6167 652e            CII.message.
+
+IP (tos 0x0, ttl 64, id 51306, offset 0, flags [DF], proto TCP (6), length 84)
+    127.0.0.1.33000 > 127.0.0.1.55358: Flags [P.], cksum 0xfe48 (incorrect -> 0xc80f), seq 3:35, ack 99, win 256, options [nop,nop,TS val 245537399 ecr 245537399], length 32: ZMTP/1.0
+        frame flags+body  (8-bit) length 1, flags 0x01 (-|-|-|-|-|-|-|MORE)
+        frame flags+body  (8-bit) length 29, flags 0x00 (-|-|-|-|-|-|-|-), first 28 byte(s) of body:
+        0x0000:  5468 6973 2069 7320 6120 7368 6f72 7420  This.is.a.short.
+        0x0010:  4153 4349 4920 7265 706c 792e            ASCII.reply.
+
+IP (tos 0x0, ttl 64, id 17998, offset 0, flags [DF], proto TCP (6), length 72)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [P.], cksum 0xfe3c (incorrect -> 0xcef8), seq 99:119, ack 35, win 257, options [nop,nop,TS val 245537399 ecr 245537399], length 20: ZMTP/1.0
+        frame flags+body  (8-bit) length 1, flags 0x01 (-|-|-|-|-|-|-|MORE)
+        frame flags+body  (8-bit) length 17, flags 0x00 (-|-|-|-|-|-|-|-), first 16 byte(s) of body:
+        0x0000:  0001 0203 0405 0607 0809 0a0b 0c0d 0e0f  ................
+
+IP (tos 0x0, ttl 64, id 51307, offset 0, flags [DF], proto TCP (6), length 84)
+    127.0.0.1.33000 > 127.0.0.1.55358: Flags [P.], cksum 0xfe48 (incorrect -> 0xc7da), seq 35:67, ack 119, win 256, options [nop,nop,TS val 245537400 ecr 245537399], length 32: ZMTP/1.0
+        frame flags+body  (8-bit) length 1, flags 0x01 (-|-|-|-|-|-|-|MORE)
+        frame flags+body  (8-bit) length 29, flags 0x00 (-|-|-|-|-|-|-|-), first 28 byte(s) of body:
+        0x0000:  5468 6973 2069 7320 6120 7368 6f72 7420  This.is.a.short.
+        0x0010:  4153 4349 4920 7265 706c 792e            ASCII.reply.
+
+IP (tos 0x0, ttl 64, id 17999, offset 0, flags [DF], proto TCP (6), length 603)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [P.], cksum 0x0050 (incorrect -> 0xafc1), seq 119:670, ack 67, win 257, options [nop,nop,TS val 245537400 ecr 245537400], length 551: ZMTP/1.0
+        frame flags+body  (8-bit) length 1, flags 0x01 (-|-|-|-|-|-|-|MORE)
+        frame flags+body (64-bit) length 540, flags 0x00 (-|-|-|-|-|-|-|-), first 128 byte(s) of body:
+        0x0000:  5468 6520 7175 6963 6b20 6272 6f77 6e20  The.quick.brown.
+        0x0010:  666f 7820 6a75 6d70 7320 6f76 6572 2074  fox.jumps.over.t
+        0x0020:  6865 206c 617a 7920 646f 672e 2054 6865  he.lazy.dog..The
+        0x0030:  2071 7569 636b 2062 726f 776e 2066 6f78  .quick.brown.fox
+        0x0040:  206a 756d 7073 206f 7665 7220 7468 6520  .jumps.over.the.
+        0x0050:  6c61 7a79 2064 6f67 2e20 5468 6520 7175  lazy.dog..The.qu
+        0x0060:  6963 6b20 6272 6f77 6e20 666f 7820 6a75  ick.brown.fox.ju
+        0x0070:  6d70 7320 6f76 6572 2074 6865 206c 617a  mps.over.the.laz
+
+IP (tos 0x0, ttl 64, id 51308, offset 0, flags [DF], proto TCP (6), length 84)
+    127.0.0.1.33000 > 127.0.0.1.55358: Flags [P.], cksum 0xfe48 (incorrect -> 0xc592), seq 67:99, ack 670, win 256, options [nop,nop,TS val 245537400 ecr 245537400], length 32: ZMTP/1.0
+        frame flags+body  (8-bit) length 1, flags 0x01 (-|-|-|-|-|-|-|MORE)
+        frame flags+body  (8-bit) length 29, flags 0x00 (-|-|-|-|-|-|-|-), first 28 byte(s) of body:
+        0x0000:  5468 6973 2069 7320 6120 7368 6f72 7420  This.is.a.short.
+        0x0010:  4153 4349 4920 7265 706c 792e            ASCII.reply.
+
+IP (tos 0x0, ttl 64, id 18000, offset 0, flags [DF], proto TCP (6), length 52)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [F.], cksum 0xfe28 (incorrect -> 0x16d8), seq 670, ack 99, win 257, options [nop,nop,TS val 245537400 ecr 245537400], length 0
+IP (tos 0x0, ttl 64, id 51309, offset 0, flags [DF], proto TCP (6), length 52)
+    127.0.0.1.33000 > 127.0.0.1.55358: Flags [F.], cksum 0xfe28 (incorrect -> 0x16d8), seq 99, ack 671, win 256, options [nop,nop,TS val 245537400 ecr 245537400], length 0
+IP (tos 0x0, ttl 64, id 18001, offset 0, flags [DF], proto TCP (6), length 52)
+    127.0.0.1.55358 > 127.0.0.1.33000: Flags [.], cksum 0xfe28 (incorrect -> 0x16d7), ack 100, win 257, options [nop,nop,TS val 245537400 ecr 245537400], length 0
diff --git a/tests/zmtp1.pcap b/tests/zmtp1.pcap
new file mode 100644 (file)
index 0000000..55aebea
Binary files /dev/null and b/tests/zmtp1.pcap differ