From: Michael Richardson Date: Wed, 13 Feb 2013 00:26:02 +0000 (-0800) Subject: Merge pull request #48 from alagoutte/master X-Git-Tag: tcpdump-4.4.0~2 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/4ddd16b959cbf4f08ffd69384a0cb23a404a8b36?hp=75d749029ca9dc67eac7d8ca1c5f2e6377b8c5e9 Merge pull request #48 from alagoutte/master Update to final draft : RFC6810 --- diff --git a/Makefile.in b/Makefile.in index 3b589dc7..16b45ecb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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) diff --git a/interface.h b/interface.h index 8602d470..57d4636d 100644 --- a/interface.h +++ b/interface.h @@ -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); diff --git a/netdissect.h b/netdissect.h index 26df79cb..f187fd5d 100644 --- a/netdissect.h +++ b/netdissect.h @@ -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)) diff --git a/print-isoclns.c b/print-isoclns.c index b8b18138..4f8a5bb7 100644 --- a/print-isoclns.c +++ b/print-isoclns.c @@ -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: diff --git a/print-stp.c b/print-stp.c index 8822c304..7880268a 100644 --- a/print-stp.c +++ b/print-stp.c @@ -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; diff --git a/print-tcp.c b/print-tcp.c index 88b46157..3b0a1354 100644 --- a/print-tcp.c +++ b/print-tcp.c @@ -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 index 00000000..d5ac4bd3 --- /dev/null +++ b/print-zeromq.c @@ -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 + +#include + +#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); +} + diff --git a/tcpdump.1.in b/tcpdump.1.in index b9e2b8e7..d2223261 100644 --- a/tcpdump.1.in +++ b/tcpdump.1.in @@ -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. diff --git a/tcpdump.c b/tcpdump.c index 49029b89..ad07df6f 100644 --- 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; diff --git a/tests/TESTLIST b/tests/TESTLIST index 40803431..aed8e064 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -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 index 00000000..748d4d25 --- /dev/null +++ b/tests/spb_bpduv4.out @@ -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 index 00000000..b12d4c15 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 index 00000000..5b528774 --- /dev/null +++ b/tests/zmtp1.out @@ -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 index 00000000..55aebea2 Binary files /dev/null and b/tests/zmtp1.pcap differ