diff -rNu epan/dissectors/Makefile.common epan/dissectors/Makefile.common --- epan/dissectors/Makefile.common 2015-03-04 10:08:41.000000000 -0700 +++ epan/dissectors/Makefile.common 2015-03-31 21:57:56.458338755 -0600 @@ -593,6 +593,7 @@ packet-fr.c \ packet-fractalgeneratorprotocol.c \ packet-frame.c \ + packet-frisbee.c \ packet-ftp.c \ packet-fw1.c \ packet-g723.c \ @@ -1002,6 +1003,7 @@ packet-prp.c \ packet-ptp.c \ packet-ptpip.c \ + packet-pubsub.c \ packet-pulse.c \ packet-pvfs2.c \ packet-pw-atm.c \ diff -rNu epan/dissectors/Makefile.in epan/dissectors/Makefile.in --- epan/dissectors/Makefile.in 2015-03-04 10:09:10.000000000 -0700 +++ epan/dissectors/Makefile.in 2015-03-31 21:57:56.470338378 -0600 @@ -504,6 +504,7 @@ libdissectors_la-packet-fr.lo \ libdissectors_la-packet-fractalgeneratorprotocol.lo \ libdissectors_la-packet-frame.lo \ + libdissectors_la-packet-frisbee.lo \ libdissectors_la-packet-ftp.lo libdissectors_la-packet-fw1.lo \ libdissectors_la-packet-g723.lo \ libdissectors_la-packet-gadu-gadu.lo \ @@ -881,6 +882,7 @@ libdissectors_la-packet-pptp.lo libdissectors_la-packet-prp.lo \ libdissectors_la-packet-ptp.lo \ libdissectors_la-packet-ptpip.lo \ + libdissectors_la-packet-pubsub.lo \ libdissectors_la-packet-pulse.lo \ libdissectors_la-packet-pvfs2.lo \ libdissectors_la-packet-pw-atm.lo \ @@ -2231,6 +2233,7 @@ packet-fr.c \ packet-fractalgeneratorprotocol.c \ packet-frame.c \ + packet-frisbee.c \ packet-ftp.c \ packet-fw1.c \ packet-g723.c \ @@ -2640,6 +2643,7 @@ packet-prp.c \ packet-ptp.c \ packet-ptpip.c \ + packet-pubsub.c \ packet-pulse.c \ packet-pvfs2.c \ packet-pw-atm.c \ @@ -3075,6 +3079,7 @@ packet-fmp.h \ packet-fr.h \ packet-frame.h \ + packet-frisbee.h \ packet-ftam.h \ packet-giop.h \ packet-gluster.h \ @@ -3210,6 +3215,7 @@ packet-ppp.h \ packet-pres.h \ packet-ptpip.h \ + packet-pubsub.h \ packet-pw-atm.h \ packet-pw-common.h \ packet-q708.h \ @@ -3909,6 +3915,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-fr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-fractalgeneratorprotocol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-frame.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-frisbee.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-ftam.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-ftp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-fw1.Plo@am__quote@ @@ -4375,6 +4382,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-prp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-ptp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-ptpip.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-pubsub.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-pulse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-pvfs2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdissectors_la-packet-pw-atm.Plo@am__quote@ @@ -7323,6 +7331,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -c -o libdissectors_la-packet-frame.lo `test -f 'packet-frame.c' || echo '$(srcdir)/'`packet-frame.c +libdissectors_la-packet-frisbee.lo: packet-frisbee.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -MT libdissectors_la-packet-frisbee.lo -MD -MP -MF $(DEPDIR)/libdissectors_la-packet-frisbee.Tpo -c -o libdissectors_la-packet-frisbee.lo `test -f 'packet-frisbee.c' || echo '$(srcdir)/'`packet-frisbee.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdissectors_la-packet-frisbee.Tpo $(DEPDIR)/libdissectors_la-packet-frisbee.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='packet-frisbee.c' object='libdissectors_la-packet-frisbee.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -c -o libdissectors_la-packet-frisbee.lo `test -f 'packet-frisbee.c' || echo '$(srcdir)/'`packet-frisbee.c + libdissectors_la-packet-ftp.lo: packet-ftp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -MT libdissectors_la-packet-ftp.lo -MD -MP -MF $(DEPDIR)/libdissectors_la-packet-ftp.Tpo -c -o libdissectors_la-packet-ftp.lo `test -f 'packet-ftp.c' || echo '$(srcdir)/'`packet-ftp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdissectors_la-packet-ftp.Tpo $(DEPDIR)/libdissectors_la-packet-ftp.Plo @@ -10186,6 +10201,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -c -o libdissectors_la-packet-ptpip.lo `test -f 'packet-ptpip.c' || echo '$(srcdir)/'`packet-ptpip.c +libdissectors_la-packet-pubsub.lo: packet-pubsub.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -MT libdissectors_la-packet-pubsub.lo -MD -MP -MF $(DEPDIR)/libdissectors_la-packet-pubsub.Tpo -c -o libdissectors_la-packet-pubsub.lo `test -f 'packet-pubsub.c' || echo '$(srcdir)/'`packet-pubsub.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdissectors_la-packet-pubsub.Tpo $(DEPDIR)/libdissectors_la-packet-pubsub.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='packet-pubsub.c' object='libdissectors_la-packet-pubsub.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -c -o libdissectors_la-packet-pubsub.lo `test -f 'packet-pubsub.c' || echo '$(srcdir)/'`packet-pubsub.c + libdissectors_la-packet-pulse.lo: packet-pulse.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdissectors_la_CFLAGS) $(CFLAGS) -MT libdissectors_la-packet-pulse.lo -MD -MP -MF $(DEPDIR)/libdissectors_la-packet-pulse.Tpo -c -o libdissectors_la-packet-pulse.lo `test -f 'packet-pulse.c' || echo '$(srcdir)/'`packet-pulse.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libdissectors_la-packet-pulse.Tpo $(DEPDIR)/libdissectors_la-packet-pulse.Plo diff -rNu epan/dissectors/packet-frisbee.c epan/dissectors/packet-frisbee.c --- epan/dissectors/packet-frisbee.c 1969-12-31 17:00:00.000000000 -0700 +++ epan/dissectors/packet-frisbee.c 2015-03-31 21:58:37.672335770 -0600 @@ -0,0 +1,598 @@ +/* packet-frisbee.c + * Routines for Utah Emulab frisbee protocol. + * Mike Hibler + * + * TODO: + * - Add dissection of master server messages + * - Add conversations for tracking frisbee sessions + * (assuming they can track many-to-one relationships) + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "packet-frisbee.h" + +static int proto_frisbee = -1; +static int hf_frisbee_msg = -1; +static int hf_frisbee_type = -1; +static int hf_frisbee_subtype = -1; +static int hf_frisbee_datalen = -1; +static int hf_frisbee_srcip = -1; +static int hf_frisbee_join_id = -1; +static int hf_frisbee_join_bcount = -1; +static int hf_frisbee_leave_id = -1; +static int hf_frisbee_leave_elapsed = -1; +static int hf_frisbee_req_chunk = -1; +static int hf_frisbee_req_block = -1; +static int hf_frisbee_req_count = -1; +static int hf_frisbee_preq_chunk = -1; +static int hf_frisbee_preq_retries = -1; +static int hf_frisbee_blk_chunk = -1; +static int hf_frisbee_blk_block = -1; +static int hf_frisbee_blk_data = -1; +static int hf_frisbee_join2_id = -1; +static int hf_frisbee_join2_bcount = -1; +static int hf_frisbee_join2_csize = -1; +static int hf_frisbee_join2_bsize = -1; +static int hf_frisbee_join2_bycount = -1; +static int hf_frisbee_leave2_id = -1; +static int hf_frisbee_leave2_elapsed = -1; +static int hf_frisbee_leave2_stats = -1; + +static gint ett_frisbee = -1; +static gint ett_frisbee_msg = -1; + +static const value_string frisbee_type_vals[] = { + { PKTTYPE_REQUEST, "Request" }, + { PKTTYPE_REPLY, "Reply" }, + { 0, NULL } +}; + +static const value_string frisbee_subtype_vals[] = { + { PKTSUBTYPE_JOIN, "JOIN" }, + { PKTSUBTYPE_LEAVE, "LEAVE" }, + { PKTSUBTYPE_BLOCK, "BLOCK" }, + { PKTSUBTYPE_REQUEST, "REQUEST" }, + { PKTSUBTYPE_LEAVE2, "LEAVE2" }, + { PKTSUBTYPE_PREQUEST, "PREQUEST" }, + { PKTSUBTYPE_JOIN2, "JOIN2" }, + { 0, NULL } +}; + +/* + * Parse a frisbee blockmap and create a string of block numbers. + * Returns number of blocks in map. + */ +int +parse_blockmap(BlockMap_t *blockmap, wmem_strbuf_t *buf) +{ + int block, count, mask; + unsigned int i; + int bit, val; + int did = 0; + + block = count = 0; + for (i = 0; i < sizeof(blockmap->map); i++) { + val = blockmap->map[i]; + for (bit = 0; bit < CHAR_BIT; bit++) { + mask = 1 << bit; + if ((val & mask) != 0) { + val &= ~mask; + if (count == 0) + block = (i * CHAR_BIT) + bit; + count++; + } else { + if (count > 0) { + if (did > 0) + wmem_strbuf_append(buf, ","); + if (count > 1) + wmem_strbuf_append_printf(buf, "%d-%d", + block, block+count-1); + else + wmem_strbuf_append_printf(buf, "%d", block); + did += count; + count = 0; + } + if (val == 0) + break; + } + } + } + if (count > 0) { + if (did > 0) + wmem_strbuf_append(buf, ","); + if (count > 1) + wmem_strbuf_append_printf(buf, "%d-%d", + block, block+count-1); + else + wmem_strbuf_append_printf(buf, "%d", block); + did += count; + } + + return did; +} + +/* + * Grievous oversight: all values are in little-endian on the wire! + */ +static int +dissect_frisbee(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) +{ + proto_item *ti = NULL; + proto_tree *frisbee_tree = NULL; + proto_tree *msg_tree = NULL; + int offset = 0, count; + guint len; + Packet_t tmp; + wmem_strbuf_t *buf; + + /* Quick sanity check */ + if (tvb_length(tvb) < sizeof(tmp.hdr)) + return 0; + + /* Read the header and do some more sanity */ + tmp.hdr.type = tvb_get_letohl(tvb, 0); + tmp.hdr.subtype = tvb_get_letohl(tvb, 4); + tmp.hdr.datalen = tvb_get_letohl(tvb, 8); + tmp.hdr.srcip = tvb_get_letohl(tvb, 12); + if (!(tmp.hdr.type == PKTTYPE_REQUEST || tmp.hdr.type == PKTTYPE_REPLY) || + tmp.hdr.subtype > PKTSUBTYPE_MAX || + (guint32)(sizeof(tmp.hdr) + tmp.hdr.datalen) > sizeof(tmp)) + return 0; + + /* Summary information */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "Frisbee"); + col_clear(pinfo->cinfo, COL_INFO); + /* XXX only JOINs have request/reply, all others are just request */ + if (tmp.hdr.subtype == PKTSUBTYPE_JOIN) + col_add_fstr(pinfo->cinfo, COL_INFO, "%s (%s)", + val_to_str(tmp.hdr.subtype, frisbee_subtype_vals, "??"), + val_to_str(tmp.hdr.type, frisbee_type_vals, "??")); + else + col_add_str(pinfo->cinfo, COL_INFO, + val_to_str(tmp.hdr.subtype, frisbee_subtype_vals, "??")); + + /* Create the protocol tree and put in the common header info */ + if (tree) { + ti = proto_tree_add_item(tree, proto_frisbee, tvb, + 0, -1, ENC_ASCII|ENC_NA); + frisbee_tree = proto_item_add_subtree(ti, ett_frisbee); + + proto_tree_add_uint(frisbee_tree, hf_frisbee_type, tvb, + offset, 4, tmp.hdr.type); + offset += 4; + proto_tree_add_uint(frisbee_tree, hf_frisbee_subtype, tvb, + offset, 4, tmp.hdr.subtype); + offset += 4; + proto_tree_add_uint(frisbee_tree, hf_frisbee_datalen, tvb, + offset, 4, tmp.hdr.datalen); + offset += 4; + proto_tree_add_ipv4(frisbee_tree, hf_frisbee_srcip, tvb, + offset, 4, tmp.hdr.srcip); + offset += 4; + } + + /* Create a subtree for the particular message type */ + if (tree) { + proto_item *mti = NULL; + + mti = proto_tree_add_item(tree, hf_frisbee_msg, tvb, + offset, tmp.hdr.datalen, ENC_NA); + msg_tree = proto_item_add_subtree(mti, ett_frisbee_msg); + } + + switch (tmp.hdr.subtype) { + case PKTSUBTYPE_JOIN: + if (tmp.hdr.type == PKTTYPE_REQUEST) { + tmp.msg.join.clientid = tvb_get_letohl(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, " ID=%d ", + tmp.msg.join.clientid); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_join_id, tvb, + offset, 4, tmp.msg.join.clientid); + } + } else { + tmp.msg.join.blockcount = tvb_get_letohl(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, " blockcount=%d", + tmp.msg.join.blockcount); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_join_bcount, tvb, + offset, 4, tmp.msg.join.blockcount); + } + } + offset += 4; + break; + + case PKTSUBTYPE_LEAVE: + tmp.msg.leave.clientid = tvb_get_letohl(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, " ID=%d ", + tmp.msg.leave.clientid); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_leave_id, tvb, + offset, 4, tmp.msg.leave.clientid); + } + offset += 4; + tmp.msg.leave.elapsed = tvb_get_letohl(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, ", elapsed=%d", + tmp.msg.leave.elapsed); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_leave_elapsed, tvb, + offset, 4, tmp.msg.leave.elapsed); + } + offset += 4; + break; + + case PKTSUBTYPE_REQUEST: + tmp.msg.request.chunk = tvb_get_letohl(tvb, offset); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_req_chunk, tvb, + offset, 4, tmp.msg.request.chunk); + } + offset += 4; + + tmp.msg.request.block = tvb_get_letohl(tvb, offset); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_req_block, tvb, + offset, 4, tmp.msg.request.block); + } + offset += 4; + + tmp.msg.request.count = tvb_get_letohl(tvb, offset); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_req_count, tvb, + offset, 4, tmp.msg.request.count); + } + offset += 4; + + col_append_fstr(pinfo->cinfo, COL_INFO, " chunk %d[%d-%d]", + tmp.msg.request.chunk, tmp.msg.request.block, + tmp.msg.request.block+tmp.msg.request.count); + break; + + case PKTSUBTYPE_PREQUEST: + tmp.msg.prequest.chunk = tvb_get_letohl(tvb, offset); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_preq_chunk, tvb, + offset, 4, tmp.msg.prequest.chunk); + } + offset += 4; + + tmp.msg.prequest.retries = tvb_get_letohl(tvb, offset); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_preq_retries, tvb, + offset, 4, tmp.msg.prequest.retries); + } + offset += 4; + + col_append_fstr(pinfo->cinfo, COL_INFO, " chunk %d (%d retries)", + tmp.msg.prequest.chunk, tmp.msg.prequest.retries); + + memset(&tmp.msg.prequest.blockmap, 0, sizeof(BlockMap_t)); + len = tvb_length_remaining(tvb, offset); + if (len > sizeof(BlockMap_t)) + len = sizeof(BlockMap_t); + tvb_memcpy(tvb, &tmp.msg.prequest.blockmap, offset, len); + buf = wmem_strbuf_new_label(wmem_packet_scope()); + count = parse_blockmap(&tmp.msg.prequest.blockmap, buf); + if (count > 0) { + if (tree) { + if (len < sizeof(BlockMap_t)) + proto_tree_add_text(msg_tree, tvb, offset, len, + "blocks (Truncated after %d of %d blocks): %d [%s]", + len*CHAR_BIT, (int)sizeof(BlockMap_t)*CHAR_BIT, + count, wmem_strbuf_get_str(buf)); + + else + proto_tree_add_text(msg_tree, tvb, offset, len, + "blocks: %d [%s]", count, + wmem_strbuf_get_str(buf)); + } + offset += len; + col_append_fstr(pinfo->cinfo, COL_INFO, ", %d blocks", count); + if (len < sizeof(BlockMap_t)) + col_append_fstr(pinfo->cinfo, COL_INFO, " (Truncated)"); + } + break; + + case PKTSUBTYPE_BLOCK: + tmp.msg.request.chunk = tvb_get_letohl(tvb, offset); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_blk_chunk, tvb, + offset, 4, tmp.msg.block.chunk); + } + offset += 4; + + tmp.msg.request.block = tvb_get_letohl(tvb, offset); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_blk_block, tvb, + offset, 4, tmp.msg.block.block); + } + offset += 4; + + len = tvb_length_remaining(tvb, offset); + if (len > sizeof(tmp.msg.block.buf)) + len = sizeof(tmp.msg.block.buf); + if (tree) { + proto_tree_add_item(msg_tree, hf_frisbee_blk_data, tvb, + offset, len, ENC_LITTLE_ENDIAN|ENC_NA); + } + offset += len; + + col_append_fstr(pinfo->cinfo, COL_INFO, " chunk %d[%d]", + tmp.msg.block.chunk, tmp.msg.block.block); + if (len < sizeof(tmp.msg.block.buf)) + col_append_fstr(pinfo->cinfo, COL_INFO, " (Truncated)"); + break; + + case PKTSUBTYPE_JOIN2: + tmp.msg.join2.clientid = tvb_get_letohl(tvb, offset); + tmp.msg.join2.blockcount = tvb_get_letohl(tvb, offset+4); + tmp.msg.join2.chunksize = tvb_get_letohl(tvb, offset+8); + tmp.msg.join2.blocksize = tvb_get_letohl(tvb, offset+12); + tmp.msg.join2.bytecount = tvb_get_letoh64(tvb, offset+16); + if (tmp.hdr.type == PKTTYPE_REQUEST) { + col_append_fstr(pinfo->cinfo, COL_INFO, + " ID=%d chunksize=%d blocksize=%d", + tmp.msg.join2.clientid, + tmp.msg.join2.chunksize, tmp.msg.join2.blocksize); + } else { + col_append_fstr(pinfo->cinfo, COL_INFO, + " chunksize=%d blocksize=%d bytecount=%" G_GINT64_MODIFIER "u", + tmp.msg.join2.chunksize, tmp.msg.join2.blocksize, + tmp.msg.join2.bytecount); + } + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_join2_id, tvb, + offset, 4, tmp.msg.join2.clientid); + offset += 4; + proto_tree_add_uint(msg_tree, hf_frisbee_join2_bcount, tvb, + offset, 4, tmp.msg.join2.blockcount); + offset += 4; + proto_tree_add_uint(msg_tree, hf_frisbee_join2_csize, tvb, + offset, 4, tmp.msg.join2.chunksize); + offset += 4; + proto_tree_add_uint(msg_tree, hf_frisbee_join2_bsize, tvb, + offset, 4, tmp.msg.join2.blocksize); + offset += 4; + proto_tree_add_uint64(msg_tree, hf_frisbee_join2_bycount, tvb, + offset, 8, tmp.msg.join2.bytecount); + offset += 8; + } + break; + + case PKTSUBTYPE_LEAVE2: + tmp.msg.leave2.clientid = tvb_get_letohl(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, " ID=%d ", + tmp.msg.leave2.clientid); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_leave2_id, tvb, + offset, 4, tmp.msg.leave2.clientid); + } + offset += 4; + tmp.msg.leave2.elapsed = tvb_get_letohl(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, ", elapsed=%d", + tmp.msg.leave2.elapsed); + if (tree) { + proto_tree_add_uint(msg_tree, hf_frisbee_leave2_elapsed, tvb, + offset, 4, tmp.msg.leave2.elapsed); + } + offset += 4; + len = tvb_length_remaining(tvb, offset); + if (len > sizeof(tmp.msg.leave2.stats)) + len = sizeof(tmp.msg.leave2.stats); + if (tree) { + proto_tree_add_item(msg_tree, hf_frisbee_leave2_stats, tvb, + offset, len, ENC_LITTLE_ENDIAN|ENC_NA); + } + offset += len; + break; + + default: + break; + } + + return tvb_length(tvb); +} + +/* + * NOTE: the extra "_" in the name is just to get us registered before e100 + * since their heuristic dissector will accidentally pick up some frisbee + * packets. There has got to be a better way to do this! + */ +void +proto_register__frisbee(void) +{ + static hf_register_info hf[] = { + { &hf_frisbee_type, + { "Type", "frisbee.type", + FT_UINT32, BASE_DEC, VALS(frisbee_type_vals), 0x0, + "Frisbee message type", HFILL }}, + + { &hf_frisbee_subtype, + { "Subtype", "frisbee.subtype", + FT_UINT32, BASE_DEC, VALS(frisbee_subtype_vals), 0x0, + "Frisbee message subtype", HFILL }}, + + { &hf_frisbee_datalen, + { "Datalen", "frisbee.datalen", + FT_UINT32, BASE_DEC, NULL, 0x0, + "Frisbee message payload length", HFILL }}, + + { &hf_frisbee_srcip, + { "SrcIP", "frisbee.srcip", + FT_IPv4, BASE_NONE, NULL, 0x0, + "Frisbee source IP", HFILL }}, + + { &hf_frisbee_msg, + { "Frisbee message", "frisbee.msg", + FT_NONE, BASE_NONE, NULL, 0x0, + "Frisbee message", HFILL }}, + + { &hf_frisbee_join_id, + { "client ID", "frisbee.join.clientid", + FT_UINT32, BASE_DEC, NULL, 0x0, + "JOIN clientid", HFILL }}, + { &hf_frisbee_join_bcount, + { "block count", "frisbee.join.blockcount", + FT_UINT32, BASE_DEC, NULL, 0x0, + "JOIN blockcount", HFILL }}, + + { &hf_frisbee_leave_id, + { "client ID", "frisbee.leave.clientid", + FT_UINT32, BASE_DEC, NULL, 0x0, + "LEAVE clientid", HFILL }}, + { &hf_frisbee_leave_elapsed, + { "elapsed time", "frisbee.leave.elapsed", + FT_UINT32, BASE_DEC, NULL, 0x0, + "LEAVE elapsed", HFILL }}, + + { &hf_frisbee_req_chunk, + { "chunk", "frisbee.request.chunk", + FT_UINT32, BASE_DEC, NULL, 0x0, + "REQUEST chunk #", HFILL }}, + { &hf_frisbee_req_block, + { "block", "frisbee.request.block", + FT_UINT32, BASE_DEC, NULL, 0x0, + "REQUEST block #", HFILL }}, + { &hf_frisbee_req_count, + { "count", "frisbee.request.count", + FT_UINT32, BASE_DEC, NULL, 0x0, + "REQUEST block count", HFILL }}, + + { &hf_frisbee_preq_chunk, + { "chunk", "frisbee.prequest.chunk", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PREQUEST chunk #", HFILL }}, + { &hf_frisbee_preq_retries, + { "retries", "frisbee.prequest.retries", + FT_UINT32, BASE_DEC, NULL, 0x0, + "REQUEST retries", HFILL }}, + + { &hf_frisbee_blk_chunk, + { "chunk", "frisbee.block.chunk", + FT_UINT32, BASE_DEC, NULL, 0x0, + "BLOCK chunk #", HFILL }}, + { &hf_frisbee_blk_block, + { "block", "frisbee.block.block", + FT_UINT32, BASE_DEC, NULL, 0x0, + "BLOCK block #", HFILL }}, + { &hf_frisbee_blk_data, + { "data", "frisbee.block.data", + FT_BYTES, BASE_NONE, NULL, 0x0, + "BLOCK data", HFILL }}, + + { &hf_frisbee_join2_id, + { "client ID", "frisbee.join2.clientid", + FT_UINT32, BASE_DEC, NULL, 0x0, + "JOIN2 clientid", HFILL }}, + { &hf_frisbee_join2_bcount, + { "block count", "frisbee.join2.blockcount", + FT_UINT32, BASE_DEC, NULL, 0x0, + "JOIN2 blockcount", HFILL }}, + { &hf_frisbee_join2_csize, + { "chunk size", "frisbee.join2.chunksize", + FT_UINT32, BASE_DEC, NULL, 0x0, + "JOIN2 chunksize", HFILL }}, + { &hf_frisbee_join2_bsize, + { "block size", "frisbee.join2.blocksize", + FT_UINT32, BASE_DEC, NULL, 0x0, + "JOIN2 blocksize", HFILL }}, + { &hf_frisbee_join2_bycount, + { "byte count", "frisbee.join2.bytecount", + FT_UINT64, BASE_DEC, NULL, 0x0, + "JOIN2 bytecount", HFILL }}, + + { &hf_frisbee_leave2_id, + { "client ID", "frisbee.leave2.clientid", + FT_UINT32, BASE_DEC, NULL, 0x0, + "LEAVE2 clientid", HFILL }}, + { &hf_frisbee_leave2_elapsed, + { "elapsed time", "frisbee.leave2.elapsed", + FT_UINT32, BASE_DEC, NULL, 0x0, + "LEAVE2 elapsed", HFILL }}, + { &hf_frisbee_leave2_stats, + { "stats data", "frisbee.leave2.stats", + FT_BYTES, BASE_NONE, NULL, 0x0, + "LEAVE2 stats data", HFILL }}, + }; + + static gint *ett[] = { + &ett_frisbee, + &ett_frisbee_msg, + }; + + proto_frisbee = proto_register_protocol("Frisbee Image Distribution Protocol", "Frisbee", "frisbee"); + proto_register_field_array(proto_frisbee, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +static gboolean +dissect_frisbee_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) +{ + if (dissect_frisbee(tvb, pinfo, tree, data) == 0) + return FALSE; + + return TRUE; +} + +/* + * NOTE: the extra "_" in the name is just to get us registered before e100 + * since their heuristic dissector will accidentally pick up some frisbee + * packets. There has got to be a better way to do this! + */ +void +proto_reg_handoff__frisbee(void) +{ + static gboolean frisbee_prefs_initialized = FALSE; + static dissector_handle_t frisbee_handle; + + if (!frisbee_prefs_initialized) { + frisbee_handle = new_create_dissector_handle(dissect_frisbee, + proto_frisbee); + heur_dissector_add("udp", dissect_frisbee_heur, proto_frisbee); + dissector_add_handle("udp.port", frisbee_handle); + frisbee_prefs_initialized = TRUE; + } +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff -rNu epan/dissectors/packet-frisbee.h epan/dissectors/packet-frisbee.h --- epan/dissectors/packet-frisbee.h 1969-12-31 17:00:00.000000000 -0700 +++ epan/dissectors/packet-frisbee.h 2015-03-31 21:57:56.477338737 -0600 @@ -0,0 +1,423 @@ +/* + * From clientside/os/frisbee.redux/decls.h + */ + +/* + * EMULAB-COPYRIGHT + * Copyright (c) 2000-2011 University of Utah and the Flux Group. + * All rights reserved. + */ + +/* + * Shared for defintions for frisbee client/server code. + */ + +#include +#include /* CHAR_BIT */ + +/* + * Ethernet MTU (1514 or 9000) - eth header (14) - min UDP/IP (28) - BLOCK msg + * header (24). + */ +#ifdef JUMBO +#define MAXPACKETDATA 8934 +#else +#define MAXPACKETDATA 1448 +#endif + +/* + * Images are broken into chunks which are the standalone unit of decompression + * Chunks are broken into blocks which are the unit of transmission + */ +#ifdef JUMBO +#define MAXCHUNKSIZE 128 +#define MAXBLOCKSIZE 8192 +#else +#define MAXCHUNKSIZE 1024 +#define MAXBLOCKSIZE 1024 +#endif + +/* + * Make sure we can fit a block in a single ethernet MTU. + */ +#if MAXBLOCKSIZE > MAXPACKETDATA +#error "Invalid block size" +#endif + +/* + * Make sure we can represent a bitmap of blocks in a single packet. + * This limits the maximum number of blocks in a chunk to 1448*8 == 11584. + * With the maximum block size of 1448, this limits a chunk to no more + * than 16,773,632 bytes (just under 16MB). + */ +#if (MAXCHUNKSIZE%CHAR_BIT) != 0 || (MAXCHUNKSIZE/CHAR_BIT) > MAXPACKETDATA +#error "Invalid chunk size" +#endif + +/* + * Chunk buffers and output write buffers constitute most of the memory + * used in the system. These should be sized to fit in the physical memory + * of the client (forcing pieces of frisbee to be paged out to disk, even + * if there is a swap disk to use, is not a very efficient way to load disks!) + * + * MAXCHUNKBUFS is the number of MAXBLOCKSIZE*MAXCHUNKSIZE chunk buffers used + * to receive data from the network. With the default values, these are 1MB + * each. + * + * MAXWRITEBUFMEM is the amount, in MB, of write buffer memory in the client. + * This is the amount of queued write data that can be pending. A value of + * zero means unlimited. + * + * The ratio of the number of these two buffer types depends on the ratio + * of network to disk speed and the degree of compression in the image. + */ +#define MAXCHUNKBUFS 64 /* 64MB with default chunk size */ +#define MAXWRITEBUFMEM 64 /* in MB */ + +/* + * Socket buffer size, used for both send and receive in client and + * server right now. If DYN_SOCKBUFSIZE is set, we find the larger + * socketbuffer size possible that is less than or equal to SOCKBUFSIZE. + */ +#define SOCKBUFSIZE (512 * 1024) +#define DYN_SOCKBUFSIZE 1 + +/* + * The number of read-ahead chunks that the client will request + * at a time. No point in requesting too far ahead either, since they + * are uncompressed/written at a fraction of the network transfer speed. + * Also, with multiple clients at different stages, each requesting blocks, + * it is likely that there will be plenty more chunks ready or in progress. + */ +#define MAXREADAHEAD 2 +#define MAXINPROGRESS 8 + +/* + * Timeout (in usecs) for packet receive. The idletimer number is how + * many PKT timeouts we allow before requesting more data from the server. + * That is, if we go TIMEOUT usecs without getting a packet, then ask for + * more. + */ +#define PKTRCV_TIMEOUT 30000 +#define CLIENT_IDLETIMER_COUNT 3 +#define TIMEOUT_HZ (1000000 / PKTRCV_TIMEOUT) +#define TIMEOUT_HALFHZ (TIMEOUT_HZ / 2) + +/* + * Timeout (in seconds!) server will hang around with no active clients. + * Make it zero to never exit. + */ +#define SERVER_INACTIVE_SECONDS (60 * 30) + +/* + * The number of disk read blocks in a single read on the server. + * Must be an integer divisor of MAXCHUNKSIZE. + */ +#define SERVER_READ_SIZE 32 + +/* + * Parameters for server network usage: + * + * SERVER_BURST_SIZE Max MAXBLOCKSIZE packets sent in a burst. + * Should be a multiple of SERVER_READ_SIZE + * Should be less than SOCKBUFSIZE/MAXBLOCKSIZE, + * bursts of greater than the send socket + * buffer size are almost certain to cause + * lost packets. + * SERVER_BURST_GAP Delay in usec between output bursts. + * Given the typical scheduling granularity + * of 10ms for most unix systems, this + * will likely be set to either 0 or 10000. + * On FreeBSD we set the clock to 1ms + * granularity. + * + * Together with the MAXBLOCKSIZE, these two params form a theoretical upper + * bound on bandwidth consumption for the server. That upper bound (for + * ethernet) is: + * + * (1000000 / SERVER_BURST_GAP) # bursts per second + * * (MAXBLOCKSIZE+24+42) * SERVER_BURST_SIZE # * wire size of a burst + * + * which for the default 1k packets, gap of 1ms and burst of 16 packets + * is about 17.4MB/sec. That is beyond the capacity of a 100Mb ethernet + * but with a 1ms granularity clock, the average gap size is going to be + * 1.5ms yielding 11.6MB/sec. In practice, the server is ultimately + * throttled by clients' ability to generate requests which is limited by + * their ability to decompress and write to disk. + */ +#define SERVER_BURST_SIZE 16 +#define SERVER_BURST_GAP 2000 + +/* + * Max burst size when doing dynamic bandwidth adjustment. + * Needs to be large enough to induce loss. + */ +#define SERVER_DYNBURST_SIZE 128 + +/* + * How long (in usecs) to wait before re-reqesting a chunk. + * It will take the server more than: + * + * (MAXCHUNKSIZE/SERVER_BURST_SIZE) * SERVER_BURST_GAP + * + * usec (0.13 sec with defaults) for each each chunk it pumps out, + * and we conservatively assume that there are a fair number of other + * chunks that must be processed before it gets to our chunk. + * + * XXX don't like making the client rely on compiled in server constants, + * lets just set it to 1 second right now. + */ +#define CLIENT_REQUEST_REDO_DELAY 1000000 + +/* + * How long for the writer to sleep if there are no blocks currently + * ready to write. Allow a full server burst period, assuming that + * something in the next burst will complete a block. + */ +#define CLIENT_WRITER_IDLE_DELAY 1000 + +/* + * Client parameters and statistics. + */ +#define CLIENT_STATS_VERSION 1 +typedef struct { + int32_t version; + union { + struct { + int32_t runsec; + int32_t runmsec; + int32_t delayms; + uint64_t rbyteswritten; + uint64_t ebyteswritten; + int32_t chunkbufs; + int32_t maxreadahead; + int32_t maxinprogress; + int32_t pkttimeout; + int32_t startdelay; + int32_t idletimer; + int32_t idledelay; + int32_t redodelay; + int32_t randomize; + uint32_t nochunksready; + uint32_t nofreechunks; + uint32_t dupchunk; + uint32_t dupblock; + uint32_t prequests; + uint32_t recvidles; + uint32_t joinattempts; + uint32_t requests; + uint32_t decompblocks; + uint32_t writeridles; + int32_t writebufmem; + uint32_t lostblocks; + uint32_t rerequests; + } __attribute__((__packed__)) v1; + uint32_t limit[256]; + } u; +} __attribute__((__packed__)) ClientStats_t; + +typedef struct { + char map[MAXCHUNKSIZE/CHAR_BIT]; +} BlockMap_t; + +/* + * Packet defs. + */ +typedef struct { + struct { + int32_t type; + int32_t subtype; + int32_t datalen; /* Useful amount of data in packet */ + uint32_t srcip; /* Filled in by network level. */ + } hdr; + union { + /* + * Join/leave the Team. Send a randomized ID, and receive + * the number of blocks in the file. This is strictly + * informational; the info is reported in the log file. + * We must return the number of chunks in the file though. + */ + union { + uint32_t clientid; + int32_t blockcount; + } join; + + struct { + uint32_t clientid; + int32_t elapsed; /* Stats only */ + } leave; + + /* + * A data block, indexed by chunk,block. + */ + struct { + int32_t chunk; + int32_t block; + int8_t buf[MAXBLOCKSIZE]; + } block; + + /* + * A request for a data block, indexed by chunk,block. + */ + struct { + int32_t chunk; + int32_t block; + int32_t count; /* Number of blocks */ + } request; + + /* + * Partial chunk request, a bit map of the desired blocks + * for a chunk. An alternative to issuing multiple standard + * requests. Retries is a hint to the server for congestion + * control, non-zero if this is a retry of an earlier request + * we made. + */ + struct { + int32_t chunk; + int32_t retries; + BlockMap_t blockmap; + } prequest; + + /* + * Join V2 allows: + * - client to request a specific chunk/block size + * server will return what it will provide + * - server to return the size in bytes + * so that we can transfer files that are not a + * multiple of the block/chunk size + * Note the blockcount field remains for vague + * compatibility-ish reasons. + */ + struct { + uint32_t clientid; + int32_t blockcount; + int32_t chunksize; + int32_t blocksize; + uint64_t bytecount; + } join2; + + /* + * Leave reporting client params/stats + */ + struct { + uint32_t clientid; + int32_t elapsed; + ClientStats_t stats; + } leave2; + } msg; +} Packet_t; +#define PKTTYPE_REQUEST 1 +#define PKTTYPE_REPLY 2 + +#define PKTSUBTYPE_JOIN 1 +#define PKTSUBTYPE_LEAVE 2 +#define PKTSUBTYPE_BLOCK 3 +#define PKTSUBTYPE_REQUEST 4 +#define PKTSUBTYPE_LEAVE2 5 +#define PKTSUBTYPE_PREQUEST 6 +#define PKTSUBTYPE_JOIN2 7 + +#define PKTSUBTYPE_MAX 7 + +#ifdef MASTER_SERVER +#include + +/* default port number: 0xfbee */ +#define MS_PORTNUM 64494 + +/* imageid length: large enough to hold an ascii encoded SHA 1024 hash */ +#define MS_MAXIDLEN 256 +/* ditto for signature */ +#define MS_MAXSIGLEN 256 + +/* + * Master server messages. + * These are sent via unicast TCP. + */ +typedef struct { + uint32_t hostip; + uint8_t methods; + uint8_t status; + uint16_t idlen; + uint8_t imageid[MS_MAXIDLEN]; +} __attribute__((__packed__)) GetRequest; + +typedef struct { + uint8_t method; + uint8_t isrunning; + uint16_t error; + uint32_t servaddr; + uint32_t addr; + uint16_t port; + uint16_t sigtype; + uint8_t signature[MS_MAXSIGLEN]; + uint32_t hisize; + uint32_t losize; +} __attribute__((__packed__)) GetReply; + +typedef struct { + uint32_t hostip; + uint8_t status; + uint16_t idlen; + uint8_t imageid[MS_MAXIDLEN]; + uint32_t hisize; + uint32_t losize; + uint32_t mtime; + uint32_t timeout; +} __attribute__((__packed__)) PutRequest; + +typedef struct { + uint16_t error; + uint32_t addr; + uint16_t port; + uint8_t exists; + uint16_t sigtype; + uint8_t signature[MS_MAXSIGLEN]; + uint32_t hisize; + uint32_t losize; + uint32_t himaxsize; + uint32_t lomaxsize; +} __attribute__((__packed__)) PutReply; + +typedef struct { + struct { + int8_t version[4]; + int32_t type; + } hdr; + union { + GetRequest getrequest; + GetReply getreply; + PutRequest putrequest; + PutReply putreply; + } body; +} MasterMsg_t; + +#define MS_MSGVERS_1 "V01" + +#define MS_MSGTYPE_GETREQUEST 1 +#define MS_MSGTYPE_GETREPLY 2 +#define MS_MSGTYPE_PUTREQUEST 3 +#define MS_MSGTYPE_PUTREPLY 4 + +#define MS_METHOD_UNKNOWN 0 +#define MS_METHOD_UNICAST 1 +#define MS_METHOD_MULTICAST 2 +#define MS_METHOD_BROADCAST 4 +#define MS_METHOD_ANY 7 + +#define MS_SIGTYPE_NONE 0 +#define MS_SIGTYPE_MTIME 1 +#define MS_SIGTYPE_MD5 2 +#define MS_SIGTYPE_SHA1 3 + +#define MS_ERROR_FAILED 1 /* internal host auth error */ +#define MS_ERROR_NOHOST 2 /* no such host */ +#define MS_ERROR_NOIMAGE 3 /* no such image */ +#define MS_ERROR_NOACCESS 4 /* access not allowed for host */ +#define MS_ERROR_NOMETHOD 5 /* not avail to host via method */ +#define MS_ERROR_INVALID 6 /* invalid argument */ +#define MS_ERROR_TRYAGAIN 7 /* try again later */ +#define MS_ERROR_TOOBIG 8 /* attempted PUT is too large */ +#define MS_ERROR_BADMTIME 9 /* attempt to set bad mtime */ +#define MS_ERROR_NOTIMPL 10 /* operation not implemented */ +#endif diff -rNu epan/dissectors/packet-pubsub.c epan/dissectors/packet-pubsub.c --- epan/dissectors/packet-pubsub.c 1969-12-31 17:00:00.000000000 -0700 +++ epan/dissectors/packet-pubsub.c 2015-03-31 21:57:56.478338529 -0600 @@ -0,0 +1,415 @@ +/* packet-pubsub.c + * Routines for Utah Emulab pubsub protocol + * Mike Hibler + * + * Wireshark - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include "packet-pubsub.h" + +static int proto_pubsub = -1; +static int hf_pubsub_len = -1; +static int hf_pubsub_type = -1; +static int hf_pubsub_flags = -1; +static int hf_pubsub_seq = -1; +static int hf_pubsub_error = -1; +static int hf_pubsub_vers = -1; +static int hf_pubsub_token = -1; +static int hf_pubsub_expr = -1; +static int hf_pubsub_used = -1; +static int hf_pubsub_items = -1; +static int hf_pubsub_keytype = -1; +static int hf_pubsub_keylen = -1; +static int hf_pubsub_key = -1; +static int hf_pubsub_valtype = -1; +static int hf_pubsub_vallen = -1; + +static gint ett_pubsub = -1; +static gint ett_pubsub_items = -1; + +static void dissect_items(tvbuff_t *tvb, int offset, + proto_tree *tree, packet_info *pinfo); + +#define TCP_PORT_PUBSUB 16505 + +static const value_string pubsub_type_vals[] = { + { PUBSUB_PKT_CONNECT, "Connect" }, + { PUBSUB_PKT_DISCONNECT, "Disconnect" }, + { PUBSUB_PKT_SUBSCRIBE, "Subscribe" }, + { PUBSUB_PKT_UNSUBSCRIBE, "Unsubscribe" }, + { PUBSUB_PKT_NOTIFY, "Notify" }, + { PUBSUB_PKT_NOTIFICATION,"Notification" }, + { PUBSUB_PKT_PING, "Ping" }, + { 0, NULL } +}; + +static const value_string item_type_vals[] = { +/* { TERNARY_TYPE, "Ternary" },*/ +/* { BEGIN_NUMERIC_TYPE,"STARTNUM" },*/ + { INT32_TYPE, "INT32" }, + { INT64_TYPE, "INT64" }, + { REAL64_TYPE, "REAL64" }, +/* { END_NUMERIC_TYPE, "ENDNUM" },*/ + { STRING_TYPE, "STRING" }, + { OPAQUE_TYPE, "OPAQUE" }, + { 0, NULL } +}; + +static void +dissect_pubsub(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + int offset = 0; + proto_tree *pubsub_tree = NULL; + proto_item *pubsub_ti = NULL; + pheader_t tmp; + short val; + + /* Summary information */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "PUBSUB"); + val = tvb_get_ntohs(tvb, 4); + col_add_str(pinfo->cinfo, COL_INFO, + val_to_str(val, pubsub_type_vals, "Unknown (0x%04x)")); + if (tree) { + pubsub_ti = proto_tree_add_item(tree, proto_pubsub, tvb, + offset, -1, ENC_ASCII|ENC_NA); + pubsub_tree = proto_item_add_subtree(pubsub_ti, ett_pubsub); + } + + tmp.len = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_uint(pubsub_tree, hf_pubsub_len, tvb, + offset, 4, tmp.len); + } + offset += 4; + + tmp.type = tvb_get_ntohs(tvb, offset); + if (tree) + proto_tree_add_uint(pubsub_tree, hf_pubsub_type, tvb, + offset, 2, tmp.type); + offset += 2; + + tmp.flags = tvb_get_ntohs(tvb, offset); + if (tree) + proto_tree_add_uint(pubsub_tree, hf_pubsub_flags, tvb, + offset, 2, tmp.flags); + offset += 2; + + tmp.seq = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_uint(pubsub_tree, hf_pubsub_seq, tvb, + offset, 4, tmp.seq); + } + offset += 4; + + tmp.error = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_uint(pubsub_tree, hf_pubsub_error, tvb, + offset, 4, tmp.error); + } + offset += 4; + + tmp.vers = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_uint(pubsub_tree, hf_pubsub_vers, tvb, + offset, 4, tmp.vers); + } + offset += 4; + + /* + * XXX if packet is just a header, it is a reply to the indicated type + */ + if (tmp.len == sizeof(pheader_t)) { + col_append_fstr(pinfo->cinfo, COL_INFO, + " Reply: Seq=%d", tmp.seq); + //return tvb_length(tvb); + } + col_append_fstr(pinfo->cinfo, COL_INFO, ": Seq=%d ", tmp.seq); + + switch (tmp.type) { + case PUBSUB_PKT_SUBSCRIBE: + { + unsigned int token; + int exprlen; + + token = tvb_get_ntohl(tvb, offset); +#if 0 + col_append_fstr(pinfo->cinfo, COL_INFO, ": token=%d ", token); +#endif + if (tree) { + proto_tree_add_uint(pubsub_tree, hf_pubsub_token, tvb, + offset, 4, token); + } + offset += 4; + + exprlen = tvb_strsize(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "Expr: \"%s\" ", + tvb_format_stringzpad(tvb, offset, exprlen)); + if (tree) { + proto_tree_add_item(pubsub_tree, hf_pubsub_expr, tvb, + offset, exprlen, ENC_ASCII|ENC_NA); + } + offset += exprlen; + break; + } + case PUBSUB_PKT_NOTIFY: + case PUBSUB_PKT_NOTIFICATION: + { + unsigned int token; + unsigned int used; + + token = tvb_get_ntohl(tvb, offset); +#if 0 + col_append_fstr(pinfo->cinfo, COL_INFO, ": token=%d ", token); +#endif + if (tree) { + proto_tree_add_uint(pubsub_tree, hf_pubsub_token, tvb, + offset, 4, token); + } + offset += 4; + + used = tvb_get_ntohl(tvb, offset); + if (tree) { + proto_tree_add_uint(pubsub_tree, hf_pubsub_used, tvb, + offset, 4, used); + } + offset += 4; + dissect_items(tvb, offset, pubsub_tree, pinfo); + break; + } + default: + break; + } + + //return tvb_length(tvb); +} + +static void +dissect_items(tvbuff_t *tvb, int offset, proto_tree *tree, packet_info *pinfo) +{ + proto_tree *item_tree = NULL; + proto_item *item_ti = NULL; + int item_offset, val_offset; + int len, itype, ilen; + char *key, valbuf[1024]; + const char *val; + + while ((len = tvb_reported_length_remaining(tvb, offset)) > 0) { + item_ti = proto_tree_add_item(tree, hf_pubsub_items, tvb, + offset, len, ENC_ASCII|ENC_NA); + item_tree = proto_item_add_subtree(item_ti, ett_pubsub_items); + + /* Get key */ + item_offset = offset; + itype = tvb_get_ntohl(tvb, offset); + offset += 4; + + ilen = tvb_get_ntohl(tvb, offset); + offset += 4; + + key = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, ilen, ENC_ASCII|ENC_NA); + offset += ilen; + if (ilen % 4) + offset += (4 - (ilen % 4)); + + proto_tree_add_text(item_tree, tvb, + item_offset, offset - item_offset, + "Key: %s [type=%s(%d), len=%d]", + key, + val_to_str(itype, item_type_vals, "UNKNOWN"), + itype, + ilen); + + /* get value */ + val_offset = offset; + itype = tvb_get_ntohl(tvb, offset); + offset += 4; + + ilen = tvb_get_ntohl(tvb, offset); + offset += 4; + + switch (itype) { + case INT32_TYPE: + { + gint32 v = tvb_get_ntohl(tvb, offset); + g_snprintf(valbuf, sizeof(valbuf), "%d", v); + val = valbuf; + break; + } + case INT64_TYPE: + { + gint64 v = tvb_get_ntoh64(tvb, offset); + g_snprintf(valbuf, sizeof(valbuf), "%lld", (long long)v); + val = valbuf; + break; + } + case REAL64_TYPE: + { + gdouble v = tvb_get_ntohieee_double(tvb, offset); + g_snprintf(valbuf, sizeof(valbuf), "%f", v); + val = valbuf; + break; + } + case STRING_TYPE: + val = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, ilen, ENC_ASCII|ENC_NA); + break; + case OPAQUE_TYPE: + val = "[data]"; + break; + default: + val = "[unknown]"; + break; + } + offset += ilen; + if (ilen % 4) + offset += (4 - (ilen % 4)); + + proto_tree_add_text(item_tree, tvb, + item_offset, offset - val_offset, + "Val: %s [type=%s(%d), len=%d]", + val, + val_to_str(itype, item_type_vals, "UNKNOWN"), + itype, + ilen); + + /* update length */ + proto_item_set_len(item_ti, offset - item_offset); + + col_append_fstr(pinfo->cinfo, COL_INFO, "%s=%s ", key, val); + } +} + +void +proto_register_pubsub(void) +{ + static hf_register_info hf[] = { + { &hf_pubsub_len, + { "Packet Len", "pubsub.len", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PUBSUB packet length", HFILL }}, + + { &hf_pubsub_type, + { "Type", "pubsub.type", + FT_UINT16, BASE_DEC, VALS(pubsub_type_vals), 0x0, + "PUBSUB message type", HFILL }}, + + { &hf_pubsub_flags, + { "Flags", "pubsub.flags", + FT_UINT16, BASE_HEX, NULL, 0x0, + "PUBSUB flags", HFILL }}, + + { &hf_pubsub_seq, + { "Sequence", "pubsub.seq", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PUBSUB sequence number", HFILL }}, + + { &hf_pubsub_error, + { "Error", "pubsub.error", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PUBSUB error code", HFILL }}, + + { &hf_pubsub_vers, + { "Version", "pubsub.vers", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PUBSUB version", HFILL }}, + + { &hf_pubsub_token, + { "Token", "pubsub.token", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PUBSUB token", HFILL }}, + + { &hf_pubsub_expr, + { "Expression", "pubsub.expr", + FT_STRINGZ, BASE_NONE, NULL, 0x0, + "PUBSUB subscription expression", HFILL }}, + + { &hf_pubsub_used, + { "Used", "pubsub.used", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PUBSUB space used", HFILL }}, + + { &hf_pubsub_items, + { "Key/value pair", "pubsub.items", + FT_NONE, BASE_NONE, NULL, 0x0, + "PUBSUB key/value pair", HFILL }}, + + { &hf_pubsub_keytype, + { "Item keytype", "pubsub.keytype", + FT_UINT32, BASE_DEC, VALS(item_type_vals), 0x0, + "PUBSUB item key type", HFILL }}, + + { &hf_pubsub_keylen, + { "Item keylen", "pubsub.keylen", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PUBSUB item key length", HFILL }}, + + { &hf_pubsub_key, + { "Item key", "pubsub.key", + FT_STRINGZ, BASE_NONE, NULL, 0x0, + "PUBSUB item key", HFILL }}, + + { &hf_pubsub_valtype, + { "Item valtype", "pubsub.valtype", + FT_UINT32, BASE_DEC, VALS(item_type_vals), 0x0, + "PUBSUB value type", HFILL }}, + + { &hf_pubsub_vallen, + { "Item vallen", "pubsub.vallen", + FT_UINT32, BASE_DEC, NULL, 0x0, + "PUBSUB value length", HFILL }}, + }; + + static gint *ett[] = { + &ett_pubsub, + &ett_pubsub_items, + }; + + proto_pubsub = proto_register_protocol("Pubsub publish/subscribe protocol", "PUBSUB", "pubsub"); + proto_register_field_array(proto_pubsub, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_pubsub(void) +{ + dissector_handle_t pubsub_handle; + + pubsub_handle = create_dissector_handle(dissect_pubsub, proto_pubsub); + dissector_add_uint("tcp.port", TCP_PORT_PUBSUB, pubsub_handle); +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff -rNu epan/dissectors/packet-pubsub.h epan/dissectors/packet-pubsub.h --- epan/dissectors/packet-pubsub.h 1969-12-31 17:00:00.000000000 -0700 +++ epan/dissectors/packet-pubsub.h 2015-03-31 21:57:56.479338324 -0600 @@ -0,0 +1,73 @@ +/* + * From pubsub/network.h + */ + +/* + * The structure of a request (response) packet. The len is field used to + * calculate how much more data to read to get the entire packet. + */ +typedef struct { + int len; /* length of entire packet */ + short type; /* See below */ + short flags; /* See below */ + int seq; /* unique sequence number */ + int error; /* Error code (0 == no error) */ + int vers; /* protocol version */ +} pheader_t; + +/* The complete packet */ +typedef struct packet { + pheader_t header; + char data[0]; +} packet_t; + +#define PUBSUB_MAX_PACKET 4096 /* XXX arbitrary */ + +/* A maximum size packet. */ +typedef struct { + pheader_t header; + char data[PUBSUB_MAX_PACKET-sizeof(pheader_t)]; +} maxpacket_t; + +/* Protocol Versions */ +#define PUBSUB_WIRE_V1 1 +#define PUBSUB_MIN_VERSION PUBSUB_WIRE_V1 +#define PUBSUB_CUR_VERSION PUBSUB_WIRE_V1 +#define PUBSUB_MAX_VERSION PUBSUB_WIRE_V1 + +/* Packet Type */ +#define PUBSUB_PKT_CONNECT 1 +#define PUBSUB_PKT_DISCONNECT 2 +#define PUBSUB_PKT_SUBSCRIBE 3 +#define PUBSUB_PKT_UNSUBSCRIBE 4 +#define PUBSUB_PKT_NOTIFY 5 +#define PUBSUB_PKT_NOTIFICATION 6 +#define PUBSUB_PKT_PING 7 + +/* Subpacket definitions */ +typedef struct { + pheader_t header; + unsigned int token; /* Unique token to identify it */ + char expression[0]; /* subscription string. */ +} subscription_packet_t; + +/* + * XXX This needs to match the version in clientapi.h ... + */ +typedef struct { + pheader_t header; + unsigned int token; /* Token to match subscription */ + unsigned int used; + char data[0]; /* key=value pairs */ +} notification_packet_t; + +typedef enum { + TERNARY_TYPE = 0, + BEGIN_NUMERIC_TYPE = 1, + INT32_TYPE = 2, + INT64_TYPE = 3, + REAL64_TYPE = 4, + END_NUMERIC_TYPE = 5, + STRING_TYPE = 6, + OPAQUE_TYPE = 7, +} pubsub_type_t; diff -rNu epan/dissectors/register.c epan/dissectors/register.c --- epan/dissectors/register.c 2015-03-04 10:10:55.000000000 -0700 +++ epan/dissectors/register.c 2015-03-31 21:57:56.482338627 -0600 @@ -24,6 +24,7 @@ {extern void proto_register_AllJoyn (void); if(cb) (*cb)(RA_REGISTER, "proto_register_AllJoyn", client_data); proto_register_AllJoyn ();} {extern void proto_register_HI2Operations (void); if(cb) (*cb)(RA_REGISTER, "proto_register_HI2Operations", client_data); proto_register_HI2Operations ();} {extern void proto_register_ISystemActivator (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ISystemActivator", client_data); proto_register_ISystemActivator ();} + {extern void proto_register__frisbee (void); if(cb) (*cb)(RA_REGISTER, "proto_register__frisbee", client_data); proto_register__frisbee ();} {extern void proto_register_a11 (void); if(cb) (*cb)(RA_REGISTER, "proto_register_a11", client_data); proto_register_a11 ();} {extern void proto_register_a21 (void); if(cb) (*cb)(RA_REGISTER, "proto_register_a21", client_data); proto_register_a21 ();} {extern void proto_register_aarp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_aarp", client_data); proto_register_aarp ();} @@ -913,6 +914,7 @@ {extern void proto_register_prp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_prp", client_data); proto_register_prp ();} {extern void proto_register_ptp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ptp", client_data); proto_register_ptp ();} {extern void proto_register_ptpip (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ptpip", client_data); proto_register_ptpip ();} + {extern void proto_register_pubsub (void); if(cb) (*cb)(RA_REGISTER, "proto_register_pubsub", client_data); proto_register_pubsub ();} {extern void proto_register_pulse (void); if(cb) (*cb)(RA_REGISTER, "proto_register_pulse", client_data); proto_register_pulse ();} {extern void proto_register_pvfs (void); if(cb) (*cb)(RA_REGISTER, "proto_register_pvfs", client_data); proto_register_pvfs ();} {extern void proto_register_pw_atm_ata (void); if(cb) (*cb)(RA_REGISTER, "proto_register_pw_atm_ata", client_data); proto_register_pw_atm_ata ();} @@ -1306,6 +1308,7 @@ {extern void proto_reg_handoff_AllJoyn (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_AllJoyn", client_data); proto_reg_handoff_AllJoyn ();} {extern void proto_reg_handoff_HI2Operations (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_HI2Operations", client_data); proto_reg_handoff_HI2Operations ();} {extern void proto_reg_handoff_ISystemActivator (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ISystemActivator", client_data); proto_reg_handoff_ISystemActivator ();} + {extern void proto_reg_handoff__frisbee (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff__frisbee", client_data); proto_reg_handoff__frisbee ();} {extern void proto_reg_handoff_a11 (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_a11", client_data); proto_reg_handoff_a11 ();} {extern void proto_reg_handoff_a21 (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_a21", client_data); proto_reg_handoff_a21 ();} {extern void proto_reg_handoff_aarp (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_aarp", client_data); proto_reg_handoff_aarp ();} @@ -2117,6 +2120,7 @@ {extern void proto_reg_handoff_prp (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_prp", client_data); proto_reg_handoff_prp ();} {extern void proto_reg_handoff_ptp (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ptp", client_data); proto_reg_handoff_ptp ();} {extern void proto_reg_handoff_ptpIP (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_ptpIP", client_data); proto_reg_handoff_ptpIP ();} + {extern void proto_reg_handoff_pubsub (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_pubsub", client_data); proto_reg_handoff_pubsub ();} {extern void proto_reg_handoff_pulse (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_pulse", client_data); proto_reg_handoff_pulse ();} {extern void proto_reg_handoff_pvfs (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_pvfs", client_data); proto_reg_handoff_pvfs ();} {extern void proto_reg_handoff_pw_atm_ata (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_pw_atm_ata", client_data); proto_reg_handoff_pw_atm_ata ();} @@ -2476,12 +2480,12 @@ static gulong proto_reg_count(void) { - return 1277; + return 1279; } static gulong handoff_reg_count(void) { - return 1176; + return 1178; } gulong register_count(void)