コード例 #1
0
bool protobuf_get_message(const string msgName, tvbuff_t *tvb, guint* offset, bool bVarintLen, guint16 lenByte, Message **messagePacket)
{
    // get message handles
    map<string, Handles*>::iterator it = g_mapHandles.find( msgName );
    if( it == g_mapHandles.end() ) 
    {
        return false; // bug
    }
    
    Handles* handles = it->second;
    
    // get message len
    guint len = 0;
    if (bVarintLen)
    {
        if (!read_varint32(tvb, offset, &len)) 
        {
            return false;
        }
    } else {
        if (lenByte == 4)
        {
            len = tvb_get_ntohl(tvb, *offset);
	        *offset += 4;
	    } else {
	        len = tvb_get_ntohs(tvb, *offset);
	        *offset += 2;
	    }
    }
    
    if (len > tvb_reported_length(tvb))
    {
        return false;
    }
    // get message buffer
    const guint8* buf = tvb_get_ptr(tvb, *offset, len);
    
    DynamicMessageFactory *factory = new DynamicMessageFactory();
    const Message *message = NULL;
    message = factory->GetPrototype(handles->descriptor);
    *messagePacket = message->New();
    
    return (*messagePacket)->ParseFromArray(buf, len);  
}
コード例 #2
0
ファイル: packet-dcp-etsi.c プロジェクト: flaub/HotFuzz
/** Dissect the Tag Packet Layer.
 *  Split the AF packet into its tag items. Each tag item has a 4 character
 *  tag, a length in bits and a value. The *ptr tag is dissected in the routine.
 *  All other tags are listed and may be handled by other dissectors.
 *  Child dissectors are tied to the parent tree, not to this tree, so that
 *  they appear at the same level as DCP.
 *  \param[in,out] tvb The buffer containing the packet
 *  \param[in,out] pinfo The packet info structure
 *  \param[in,out] tree The structure containing the details which will be displayed, filtered, etc.
 */
static void
dissect_tpl(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
  proto_tree *tpl_tree = NULL;
  guint offset=0;
  char *prot=NULL;
  guint16 maj, min;

  pinfo->current_proto = "DCP-TPL";
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "DCP-TPL");

  if(tree) {
    proto_item *ti = NULL;
    ti = proto_tree_add_item (tree, proto_tpl, tvb, 0, -1, FALSE);
    tpl_tree = proto_item_add_subtree (ti, ett_tpl);
  }
  while(offset<tvb_length(tvb)) {
    guint32 bits;
    guint32 bytes;
    char *tag = (char*)tvb_get_ephemeral_string (tvb, offset, 4); offset += 4;
    bits = tvb_get_ntohl(tvb, offset); offset += 4;
    bytes = bits / 8;
    if(bits % 8)
      bytes++;
    if(tree) {
      proto_item *i = NULL;
      const guint8 *p = tvb_get_ptr(tvb, offset, bytes);
      if(strcmp(tag, "*ptr")==0) {
        prot = (char*)tvb_get_ephemeral_string (tvb, offset, 4);
        maj = tvb_get_ntohs(tvb, offset+4);
        min = tvb_get_ntohs(tvb, offset+6);
        i = proto_tree_add_bytes_format(tpl_tree, hf_tpl_tlv, tvb,
              offset-8, bytes+8, p, "%s %s rev %d.%d", tag, prot, maj, min);
      } else {
        i = proto_tree_add_bytes_format(tpl_tree, hf_tpl_tlv, tvb,
              offset-8, bytes+8, p, "%s (%u bits)", tag, bits);
      }
    }
    offset += bytes;
  }
  if(prot) {  /* prot is non-NULL only if we have our tree. */
    dissector_try_string(tpl_dissector_table, prot, tvb, pinfo, tree->parent);
  }
}
コード例 #3
0
static void
dissect_fcfcs_gieil (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
{
    int offset = 16; /* past the fcct header */
    int len, tot_len, prevlen;

    if (tree) {
        if (isreq) {
            proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
                                   fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
        }
        else {
            tot_len = tvb_get_guint8 (tvb, offset+3);
            proto_tree_add_text (tree, tvb, offset+3, 1, "List Length: %d",
                                 tot_len);

            prevlen = 0;
            len = tvb_strsize(tvb, offset+4);
            proto_tree_add_item (tree, hf_fcs_vendorname, tvb, offset+4,
                                 len, FALSE);
            prevlen += len;

            len = tvb_strsize(tvb, offset+4+prevlen);
            proto_tree_add_item (tree, hf_fcs_modelname, tvb, offset+4+prevlen,
                                 len, FALSE);
            prevlen += len;

            len = tvb_strsize(tvb, offset+4+prevlen);
            proto_tree_add_item (tree, hf_fcs_releasecode, tvb,
                                 offset+4+prevlen, len, FALSE);
            prevlen += len;
            offset += (4+prevlen);
            while (tot_len > prevlen) {
                len = tvb_strsize(tvb, offset);
                proto_tree_add_text (tree, tvb, offset, len,
                                     "Vendor-specific Information: %s",
                                     tvb_format_text(tvb, offset, len-1));
                prevlen += len;
                offset += len;
            }
        }
    }
}
コード例 #4
0
ファイル: packet-osi.c プロジェクト: HeartFlying/wireshark
gboolean
osi_calc_checksum( tvbuff_t *tvb, int offset, guint len, guint32* c0, guint32* c1) {
  guint         available_len;
  const guint8 *p;
  guint         seglen;
  guint         i;

  available_len = tvb_captured_length_remaining( tvb, offset );
  if ( available_len < len )
    return FALSE;

  p = tvb_get_ptr( tvb, offset, len );

  /*
   * The maximum values of c0 and c1 will occur if all bytes have the
   * value 255; if so, then c0 will be len*255 and c1 will be
   * (len*255 + (len-1)*255 + ... + 255), which is
   * (len + (len - 1) + ... + 1)*255, or 255*(len*(len + 1))/2.
   * This means it can overflow if "len" is 5804 or greater.
   *
   * (A+B) mod 255 = ((A mod 255) + (B mod 255) mod 255, so
   * we can solve this by taking c0 and c1 mod 255 every
   * 5803 bytes.
   */
  *c0 = 0;
  *c1 = 0;
  while (len != 0) {
    seglen = len;
    if (seglen > 5803)
      seglen = 5803;
    for (i = 0; i < seglen; i++) {
      (*c0) += *(p++);
      (*c1) += (*c0);
    }

    (*c0) = (*c0) % 255;
    (*c1) = (*c1) % 255;

    len -= seglen;
  }

  return TRUE;
}
コード例 #5
0
static void
dissect_fcfcs_rpl (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
{
    int offset = 16;            /* past the fc_ct header */
    int numelem, i, len;

    if (tree) {
        if (isreq) {
            len = tvb_get_guint8 (tvb, offset);
            proto_tree_add_text (tree, tvb, offset, 1,
                                 "Platform Name Length: %d", len);
            proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
                                 len, 0);
            proto_tree_add_item (tree, hf_fcs_platformtype, tvb, offset+256, 4,
                                 0);
            numelem = tvb_get_ntohl (tvb, offset+260);
            proto_tree_add_text (tree, tvb, offset+260, 4,
                                 "Number of Mgmt. Addr Entries: %d", numelem);
            offset += 264;
            for (i = 0; i < numelem; i++) {
                len = tvb_get_guint8 (tvb, offset);
                proto_tree_add_text (tree, tvb, offset, 1,
                                     "Mgmt. Addr Length: %d", len);
                proto_tree_add_item (tree, hf_fcs_mgmtaddr, tvb, offset+1,
                                     len, 0);
                offset += 256;
            }

            numelem = tvb_get_ntohl (tvb, offset);
            proto_tree_add_text (tree, tvb, offset, 4,
                                 "Number of Platform Node Name Entries: %d",
                                 numelem);
            offset += 4;
            for (i = 0; i < numelem; i++) {
                proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset,
                                       8,
                                       fcwwn_to_str (tvb_get_ptr (tvb, offset,
                                                     8)));
                offset += 8;
            }
        }
    }
}
コード例 #6
0
static const guint8*
get_unquoted_string(tvbuff_t *tvb, gint offset, gint *next_offset, guint *len)
{
    const guint8* s = NULL;
    guint l = 0;
    gint o;

    o = tvb_pbrk_guint8(tvb, offset, -1, " \t\r\n", NULL);
    if (o != -1) {
        l = o - offset;
        s = tvb_get_ptr(tvb, offset, l);
        offset = o;
    }

    *next_offset = offset;
    *len = l;

    return s;
}
コード例 #7
0
static void
dissect_fcfcs_rpln (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
{
    int offset = 16;            /* past the fc_ct header */
    int len;

    if (tree) {
        if (isreq) {
            len = tvb_get_guint8 (tvb, offset);
            proto_tree_add_text (tree, tvb, offset, 1,
                                 "Platform Name Length: %d", len);
            proto_tree_add_item (tree, hf_fcs_platformname, tvb, offset+1,
                                 len, 0);
            proto_tree_add_string (tree, hf_fcs_platformnname, tvb, offset+256,
                                   8,
                                   fcwwn_to_str (tvb_get_ptr (tvb, offset+256,
                                                 8)));
        }
    }
}
コード例 #8
0
/* Code to actually dissect the packets */
static void
dissect_fcfcs_giel (tvbuff_t *tvb, proto_tree *tree, gboolean isreq)
{
    int offset = 16;            /* past the ct header */
    int numelem, i;

    if (!isreq && tree) {
        numelem = tvb_get_ntohl (tvb, offset);

        proto_tree_add_text (tree, tvb, offset, 4, "Number of IE entries: 0x%d",
                             numelem);
        offset += 4;
        for (i = 0; i < numelem; i++) {
            proto_tree_add_string (tree, hf_fcs_iename, tvb, offset, 8,
                                   fcwwn_to_str (tvb_get_ptr (tvb, offset, 8)));
            proto_tree_add_item (tree, hf_fcs_ietype, tvb, offset+11, 1, 0);
            offset += 12;
        }
    }
}
コード例 #9
0
ファイル: packet-dccp.c プロジェクト: flaub/HotFuzz
/* decode a variable-length number of nbytes starting at offset. Based on a concept by Arnaldo de Melo */
static guint64 tvb_get_ntoh_var(tvbuff_t *tvb, gint offset, guint nbytes)
{
	const guint8* ptr;
	guint64 value = 0;

        ptr = tvb_get_ptr(tvb, offset, nbytes);
	if (nbytes > 5)
                value += ((guint64)*ptr++) << 40;
	if (nbytes > 4)
                value += ((guint64)*ptr++) << 32;
	if (nbytes > 3)
                value += ((guint64)*ptr++) << 24;
	if (nbytes > 2)
                value += ((guint64)*ptr++) << 16;
	if (nbytes > 1)
                value += ((guint64)*ptr++) << 8;
	if (nbytes > 0)
                value += *ptr;

        return value;
}
コード例 #10
0
tvbuff_t *
tvb_unmasked(tvbuff_t *tvb, const int offset, int payload_length, const guint8 *masking_key)
{

  gchar *data_unmask;
  tvbuff_t  *tvb_unmask    = NULL;
  int i;
  const guint8 *data_mask;
  int unmasked_length = payload_length > MAX_UNMASKED_LEN ? MAX_UNMASKED_LEN : payload_length;

  data_unmask = g_malloc(unmasked_length);
  data_mask = tvb_get_ptr(tvb, offset, unmasked_length);
  /* Unmasked(XOR) Data... */
  for(i=0; i < unmasked_length; i++){
    data_unmask[i] = data_mask[i] ^ masking_key[i%4];
  }

  tvb_unmask = tvb_new_real_data(data_unmask, unmasked_length, unmasked_length);
  tvb_set_free_cb(tvb_unmask, g_free);
  return tvb_unmask;
}
コード例 #11
0
/*
 * Name: isis_dissect_is_neighbors_clv()
 *
 * Description:
 *	Take apart a IS neighbor packet.  A neighbor is n 6 byte packets.
 *	(they tend to be an 802.3 MAC address, but its not required).
 *
 * Input:
 *	tvbuff_t * : tvbuffer for packet data
 *	proto_tree * : protocol display tree to fill out.  May be NULL
 *	int : offset into packet data where we are.
 *	int : length of IDs in packet.
 *	int : length of clv we are decoding
 *
 * Output:
 *	void, but we will add to proto tree if !NULL.
 */
static void
dissect_hello_is_neighbors_clv(tvbuff_t *tvb, proto_tree *tree, int offset,
                               int id_length _U_, int length)
{
    while ( length > 0 ) {
        if (length<6) {
            isis_dissect_unknown(tvb, tree, offset,
                                 "short is neighbor (%d vs 6)", length );
            return;
        }
        /*
         * Lets turn the area address into "standard" 0000.0000.etc
         * format string.
         */
        if ( tree ) {
            proto_tree_add_text ( tree, tvb, offset, 6,
                                  "IS Neighbor: %s", get_ether_name( tvb_get_ptr(tvb, offset, 6)) );
        }
        offset += 6;
        length -= 6;
    }
}
コード例 #12
0
ファイル: packet-esis.c プロジェクト: AnkitKejriwal/wireshark
static void
esis_dissect_ish_pdu( guint8 len, tvbuff_t *tvb, proto_tree *tree) {

  int   offset  = 0;
  int   netl    = 0;

  if (tree) {
    offset += ESIS_HDR_FIXED_LENGTH;

    netl = (int) tvb_get_guint8(tvb, offset);
    proto_tree_add_text( tree, tvb, offset, netl + 1,
                         "### Network Entity Title Section ###");
    proto_tree_add_text( tree, tvb, offset++, 1, "NETL: %2u Octets", netl);
    proto_tree_add_text( tree, tvb, offset, netl,
                         " NET: %s",
                         print_nsap_net( tvb_get_ptr(tvb, offset, netl), netl ) );
    offset += netl;
    len    -= ( netl + 1 );

    dissect_osi_options( len, tvb, offset, tree );
  }
}
コード例 #13
0
static const guint8 *get_field_data(GSList *src_list, field_info *fi)
{
  GSList *src_le;
  data_source *src;
  tvbuff_t *src_tvb;
  gint length, tvbuff_length;
  
  for (src_le = src_list; src_le != NULL; src_le = src_le->next)
    {
      src = src_le->data;
      src_tvb = src->tvb;
      if (fi->ds_tvb == src_tvb)
	{
	  /*
	   * Found it.
	   *
	   * XXX - a field can have a length that runs past
	   * the end of the tvbuff.  Ideally, that should
	   * be fixed when adding an item to the protocol
	   * tree, but checking the length when doing
	   * that could be expensive.  Until we fix that,
	   * we'll do the check here.
	   */
	  tvbuff_length = tvb_length_remaining(src_tvb,
					       fi->start);
	  if (tvbuff_length < 0)
	    {
	      return NULL;
	    }
	  length = fi->length;
	  if (length > tvbuff_length)
	    length = tvbuff_length;
	  return tvb_get_ptr(src_tvb, fi->start, length);
	}
    }
  g_assert_not_reached();
  return NULL;	/* not found */
}
コード例 #14
0
ファイル: packet-tr.c プロジェクト: dogphilly/wireshark
/*
 * DODGY LINUX HACK DODGY LINUX HACK
 * Linux 2.0.x always passes frames to the Token Ring driver for transmission with
 * 18 bytes padding for source routing information.  Some drivers copy the first
 * (18 - srlen) bytes up the frame (18 - srlen) bytes thus removing the padding.
 * Other drivers just make a copy of the entire frame and then hack about with it
 * so the frame the sniffer gets is fine (just has extra sr routing).
 * In the first instance (driver hacking frame in situ) the sniffer gets a garbled
 * frame.
 * This function trys to detect this and returns the offset of where
 * the frame really starts.
 * This only detects frames that we have sent ourselves so if we are packet sniffing
 * on the machine we are watching this is useful.
 * Compare offset 0 with offset x+1 for a length of x bytes for all value of x = 1 to 18
 * if match then Linux driver has done in situ source route compression of the crappy
 * Linux 2.0.x frame so the beginning of the real frame is x bytes in.
 * (And this real frame x bytes in looks like a proper TR frame that goes on the wire
 * with none of the Linux idiosyncrasies).
 *
 * XXX - there should perhaps be a preference setting to turn this off,
 * as sometimes it can, and does, get a false hit.
 */
static
int check_for_old_linux_tvb(tvbuff_t *tvb)
{
	const guint8	*data;
	int		 x, bytes;

	/* Restrict our looping to the boundaries of the frame */
	bytes = tvb_length(tvb);
	if (bytes > 19) {
		bytes = 19;
	}

	data = tvb_get_ptr(tvb, 0, bytes);

	for(x = 1; x <= bytes-1 ;x++)
	{
		if (memcmp(&data[0], &data[x], x) == 0)
		{
			return x;
		}
	}
	return 0;
}
コード例 #15
0
ファイル: wslua_tvb.c プロジェクト: DHODoS/wireshark
WSLUA_METHOD Tvb_raw(lua_State* L) {
    /* Obtain a Lua string of the binary bytes in a `Tvb`.

       @since 1.11.3
     */
#define WSLUA_OPTARG_Tvb_raw_OFFSET 2 /* The position of the first byte (default=0/first). */
#define WSLUA_OPTARG_Tvb_raw_LENGTH 3 /* The length of the segment to get (default=all). */
    Tvb tvb = checkTvb(L,1);
    int offset = (int) luaL_optinteger(L,WSLUA_OPTARG_Tvb_raw_OFFSET,0);
    int len = (int) luaL_optinteger(L,WSLUA_OPTARG_Tvb_raw_LENGTH,-1);

    if (!tvb) return 0;
    if (tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    if ((guint)offset > tvb_captured_length(tvb->ws_tvb)) {
        WSLUA_OPTARG_ERROR(Tvb_raw,OFFSET,"offset beyond end of Tvb");
        return 0;
    }

    if (len == -1) {
        len = tvb_captured_length_remaining(tvb->ws_tvb,offset);
        if (len < 0) {
            luaL_error(L,"out of bounds");
            return FALSE;
        }
    } else if ( (guint)(len + offset) > tvb_captured_length(tvb->ws_tvb)) {
        luaL_error(L,"Range is out of bounds");
        return FALSE;
    }

    lua_pushlstring(L, tvb_get_ptr(tvb->ws_tvb, offset, len), len);

    WSLUA_RETURN(1); /* A Lua string of the binary bytes in the `Tvb`. */
}
コード例 #16
0
static void dissect_echo(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  
  proto_tree   *echo_tree = NULL;
  proto_item   *ti, *hidden_item;
  int           offset = 0;
  gboolean      request = FALSE;
  const guint8 *data = tvb_get_ptr(tvb, offset, -1);

  if (pinfo->destport == ECHO_PORT) {
    request = TRUE;
  }

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ECHO");

  if (check_col(pinfo->cinfo, COL_INFO)) {
    col_set_str(pinfo->cinfo, COL_INFO, 
		 (request) ? "Request" : "Response");
  }
  
  if (tree) {

    ti = proto_tree_add_item(tree, proto_echo, tvb, offset, -1, FALSE);
    echo_tree = proto_item_add_subtree(ti, ett_echo);

    if (request) {
      hidden_item = proto_tree_add_boolean(echo_tree, hf_echo_request, tvb, 0, 0, 1);
    } else {
      hidden_item = proto_tree_add_boolean(echo_tree, hf_echo_response, tvb, 0, 0, 1);
    }
    PROTO_ITEM_SET_HIDDEN(hidden_item);

    proto_tree_add_bytes(echo_tree, hf_echo_data, tvb, offset, -1, data);

  }

} /* dissect_echo */
コード例 #17
0
/**
*   Decode a "Source Route" object.
*   @return the new offset or -1 on error.
**/
static gint
decode_sourceroute(tvbuff_t *tvb, proto_tree *parent_tree, gint offset, gchar *attribute_name)
{
  proto_item *ti = NULL;
  proto_tree *sourceroute_tree = NULL; 
  guint32 i;
  guint32 sourceroute_size = tvb_get_ntohl(tvb, offset);
  ti = proto_tree_add_text(parent_tree, tvb, offset, 1, attribute_name);
  sourceroute_tree = proto_item_add_subtree(ti, ett_freepastry_core_v0_sr);
  proto_tree_add_uint(sourceroute_tree, hf_freepastry_direct_sourceroute_numhops, tvb, offset, 4, sourceroute_size);
  offset += 4;
  /*for each hop (do not parse the last hop)*/
  for (i=0; i < (sourceroute_size - 1); ++i){
    offset = decode_epoch_inet_socket_address(tvb, sourceroute_tree, offset, "Hop");
    if (offset == -1){
      return -1;
    }
  }
  /*Parse the last node in the sourceroute*/
  if (sourceroute_size > 0) {
    gchar *ip_str;
    guint16 port_number;
    gint former_offset = offset;
    offset = decode_epoch_inet_socket_address(tvb, sourceroute_tree, offset, "Hop");
    if (offset == -1){
      return -1;
    }
    /*Print final destination on the subtree root*/
    ip_str = ip_to_str(tvb_get_ptr(tvb, former_offset + 1, 4));
    former_offset += 5;
    port_number = tvb_get_ntohs(tvb, former_offset);
    proto_item_append_text(ti, " -> %s:%d", ip_str, port_number);
  }
  proto_item_set_end(ti, tvb, offset);
  return offset;
}
コード例 #18
0
static const guint8*
get_quoted_string(tvbuff_t *tvb, gint offset, gint *next_offset, guint *len)
{
    int c;
    const guint8* s = NULL;
    guint l = 0;
    gint o;

    c = tvb_get_guint8(tvb, offset);
    if (c == '"') {
        o = tvb_find_guint8(tvb, offset+1, -1, '"');
        if (o != -1) {
            offset++;
            l = o - offset;
            s = tvb_get_ptr(tvb, offset, l);
            offset = o + 1;
        }
    }

    *next_offset = offset;
    *len = l;

    return s;
}
コード例 #19
0
ファイル: packet-iwarp-mpa.c プロジェクト: flaub/HotFuzz
/*
 * Removes any Markers from this FPDU by using memcpy or throws an out of memory
 * exception.
 */
static tvbuff_t *
remove_markers(tvbuff_t *tvb, packet_info *pinfo, guint32 marker_offset,
		guint32 num_markers, guint32 orig_length)
{
	guint8 *mfree_buff = NULL;
	const guint8 *raw_data_ptr = NULL;
	guint32 mfree_buff_length, tot_copy, cur_copy;
	tvbuff_t *mfree_tvb = NULL;

	DISSECTOR_ASSERT(num_markers > 0);
	DISSECTOR_ASSERT(orig_length > MPA_MARKER_LEN * num_markers);
	DISSECTOR_ASSERT(tvb_length(tvb) == orig_length);

	/* allocate memory for the marker-free buffer */
	mfree_buff_length = orig_length - (MPA_MARKER_LEN * num_markers);
	mfree_buff = g_malloc(mfree_buff_length);

	if (!mfree_buff)
		THROW(OutOfMemoryError);

	raw_data_ptr = tvb_get_ptr(tvb, 0, -1);
	tot_copy = 0;
	cur_copy = marker_offset;
	while (tot_copy < mfree_buff_length) {
		memcpy(mfree_buff+tot_copy, raw_data_ptr, cur_copy);
		tot_copy += cur_copy;
		raw_data_ptr += cur_copy + MPA_MARKER_LEN;
		cur_copy = MIN(MPA_MARKER_INTERVAL, (mfree_buff_length - tot_copy));
	}
	mfree_tvb = tvb_new_child_real_data(tvb, mfree_buff, mfree_buff_length,
					    mfree_buff_length);
	tvb_set_free_cb(mfree_tvb, g_free);
	add_new_data_source(pinfo, mfree_tvb, "FPDU without Markers");

	return mfree_tvb;
}
コード例 #20
0
ファイル: packet-pgm.c プロジェクト: hubolo/wireshark-1.8.0
/*
 * dissect_pgm - The dissector for Pragmatic General Multicast
 */
static void
dissect_pgm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint16 pgmhdr_sport;
	guint16 pgmhdr_dport;
	guint8 pgmhdr_type;
	guint8 pgmhdr_opts;
	guint16 pgmhdr_cksum;
	guint16 pgmhdr_tsdulen;
	guint32 sqn;
	guint16 afi;

	guint plen = 0;
	proto_item *ti;
	const char *pktname;
	const char *pollstname;
	char *gsi;
	gboolean isdata = FALSE;
	guint pgmlen, reportedlen;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "PGM");

	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_clear(pinfo->cinfo, COL_INFO);
		if (tvb_reported_length_remaining(tvb, 0) < 18) {
			col_set_str(pinfo->cinfo, COL_INFO,
				"Packet too small");
			return;
		}
	}

	pinfo->srcport = pgmhdr_sport = tvb_get_ntohs(tvb, 0);
	pinfo->destport = pgmhdr_dport = tvb_get_ntohs(tvb, 2);

	pgmhdr_type = tvb_get_guint8(tvb, 4);
	pktname = val_to_str(pgmhdr_type, type_vals, "Unknown (0x%02x)");

	pgmhdr_opts = tvb_get_guint8(tvb, 5);
	pgmhdr_cksum = tvb_get_ntohs(tvb, 6);
	gsi = tvb_bytes_to_str(tvb, 8, 6);
	pgmhdr_tsdulen = tvb_get_ntohs(tvb, 14);
	sqn = tvb_get_ntohl(tvb, 16);

	switch(pgmhdr_type) {
	case PGM_SPM_PCKT:
	case PGM_NAK_PCKT:
	case PGM_NNAK_PCKT:
	case PGM_NCF_PCKT:
	case PGM_POLR_PCKT:
	case PGM_ACK_PCKT:
		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_add_fstr(pinfo->cinfo, COL_INFO,
				"%-5s sqn 0x%x gsi %s", pktname, sqn, gsi);
		}
		break;
	case PGM_RDATA_PCKT:
	case PGM_ODATA_PCKT:
		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_add_fstr(pinfo->cinfo, COL_INFO,
			    "%-5s sqn 0x%x gsi %s tsdulen %d", pktname, sqn, gsi,
			    pgmhdr_tsdulen);
		}
		isdata = TRUE;
		break;
	case PGM_POLL_PCKT: {
		guint16 poll_stype = tvb_get_ntohs(tvb, 22);
		pollstname = val_to_str(poll_stype, poll_subtype_vals, "Unknown (0x%02x)");

		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_add_fstr(pinfo->cinfo, COL_INFO,
				"%-5s sqn 0x%x gsi %s subtype %s",
					pktname, sqn, gsi, pollstname);
		}
		}
		break;
	default:
		return;
	}

	{
		proto_tree *pgm_tree = NULL;
		proto_tree *opt_tree = NULL;
		proto_tree *type_tree = NULL;
		proto_item *tf, *hidden_item;
		ptvcursor_t* cursor;

		ti = proto_tree_add_protocol_format(tree, proto_pgm,
			tvb, 0, -1,
			"Pragmatic General Multicast: Type %s"
			    " Src Port %u, Dst Port %u, GSI %s", pktname,
			pgmhdr_sport, pgmhdr_dport, gsi);

		pgm_tree = proto_item_add_subtree(ti, ett_pgm);

		cursor = ptvcursor_new(pgm_tree, tvb, 0);

		hidden_item = proto_tree_add_item(pgm_tree, hf_pgm_port, tvb, 0, 2, ENC_BIG_ENDIAN);
		PROTO_ITEM_SET_HIDDEN(hidden_item);
		hidden_item = proto_tree_add_item(pgm_tree, hf_pgm_port, tvb, 2, 2, ENC_BIG_ENDIAN);
		PROTO_ITEM_SET_HIDDEN(hidden_item);
		ptvcursor_add(cursor, hf_pgm_main_sport, 2, ENC_BIG_ENDIAN);
		ptvcursor_add(cursor, hf_pgm_main_dport, 2, ENC_BIG_ENDIAN);
		ptvcursor_add(cursor, hf_pgm_main_type, 1, ENC_BIG_ENDIAN);

		tf = proto_tree_add_uint_format(pgm_tree, hf_pgm_main_opts, tvb,
			ptvcursor_current_offset(cursor), 1, pgmhdr_opts, "Options: %s (0x%x)",
			optsstr(pgmhdr_opts), pgmhdr_opts);
		opt_tree = proto_item_add_subtree(tf, ett_pgm_optbits);
		ptvcursor_set_tree(cursor, opt_tree);

		ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_opt, 1, ENC_BIG_ENDIAN);
		ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_netsig, 1, ENC_BIG_ENDIAN);
		ptvcursor_add_no_advance(cursor, hf_pgm_main_opts_varlen, 1, ENC_BIG_ENDIAN);
		ptvcursor_add(cursor, hf_pgm_main_opts_parity, 1, ENC_BIG_ENDIAN);
		ptvcursor_set_tree(cursor, pgm_tree);

		/* Checksum may be 0 (not available), but not for DATA packets */
		if ((pgmhdr_type != PGM_RDATA_PCKT) && (pgmhdr_type != PGM_ODATA_PCKT) &&
		    (pgmhdr_cksum == 0))
		{
			proto_tree_add_uint_format(pgm_tree, hf_pgm_main_cksum, tvb,
				ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "Checksum: not available");
		} else {
			reportedlen = tvb_reported_length(tvb);
			pgmlen = tvb_length(tvb);
			if (pgm_check_checksum && pgmlen >= reportedlen) {
				vec_t cksum_vec[1];
				guint16 computed_cksum;

				cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, pgmlen);
				cksum_vec[0].len = pgmlen;
				computed_cksum = in_cksum(&cksum_vec[0], 1);
				if (computed_cksum == 0) {
					proto_tree_add_uint_format(pgm_tree, hf_pgm_main_cksum, tvb,
						ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "Checksum: 0x%04x [correct]", pgmhdr_cksum);
				} else {
					hidden_item = proto_tree_add_boolean(pgm_tree, hf_pgm_main_cksum_bad, tvb,
					    ptvcursor_current_offset(cursor), 2, TRUE);
					PROTO_ITEM_SET_HIDDEN(hidden_item);
					proto_tree_add_uint_format(pgm_tree, hf_pgm_main_cksum, tvb,
					    ptvcursor_current_offset(cursor), 2, pgmhdr_cksum, "Checksum: 0x%04x [incorrect, should be 0x%04x]",
						pgmhdr_cksum, in_cksum_shouldbe(pgmhdr_cksum, computed_cksum));
				}
			} else {
				ptvcursor_add_no_advance(cursor, hf_pgm_main_cksum, 2, ENC_BIG_ENDIAN);
			}
		}
		ptvcursor_advance(cursor, 2);

		ptvcursor_add(cursor, hf_pgm_main_gsi, 6, ENC_NA);
		ptvcursor_add(cursor, hf_pgm_main_tsdulen, 2, ENC_BIG_ENDIAN);

		tf = proto_tree_add_text(pgm_tree, tvb, ptvcursor_current_offset(cursor), plen, "%s Packet", pktname);
		switch(pgmhdr_type) {
		case PGM_SPM_PCKT:
			type_tree = proto_item_add_subtree(tf, ett_pgm_spm);
			ptvcursor_set_tree(cursor, type_tree);

			ptvcursor_add(cursor, hf_pgm_spm_sqn, 4, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_spm_trail, 4, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_spm_lead, 4, ENC_BIG_ENDIAN);
			afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
			ptvcursor_add(cursor, hf_pgm_spm_pathafi, 2, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_spm_res, 2, ENC_BIG_ENDIAN);

			switch (afi) {
			case AFNUM_INET:
				ptvcursor_add(cursor, hf_pgm_spm_path, 4, ENC_BIG_ENDIAN);
				break;

			case AFNUM_INET6:
				ptvcursor_add(cursor, hf_pgm_spm_path6, 16, ENC_NA);
				break;

			default:
				proto_tree_add_text(type_tree, tvb, ptvcursor_current_offset(cursor), -1,
				    "Can't handle this address format");
				return;
			}
			break;
		case PGM_RDATA_PCKT:
		case PGM_ODATA_PCKT:
			type_tree = proto_item_add_subtree(tf, ett_pgm_data);
			ptvcursor_set_tree(cursor, type_tree);

			ptvcursor_add(cursor, hf_pgm_spm_sqn, 4, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_spm_trail, 4, ENC_BIG_ENDIAN);
			break;
		case PGM_NAK_PCKT:
		case PGM_NNAK_PCKT:
		case PGM_NCF_PCKT:
			type_tree = proto_item_add_subtree(tf, ett_pgm_nak);
			ptvcursor_set_tree(cursor, type_tree);

			ptvcursor_add(cursor, hf_pgm_nak_sqn, 4, ENC_BIG_ENDIAN);
			afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
			ptvcursor_add(cursor, hf_pgm_nak_srcafi, 2, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_nak_srcres, 2, ENC_BIG_ENDIAN);

			switch (afi) {
			case AFNUM_INET:
				ptvcursor_add(cursor, hf_pgm_nak_src, 4, ENC_BIG_ENDIAN);
				break;

			case AFNUM_INET6:
				ptvcursor_add(cursor, hf_pgm_nak_src6, 16, ENC_NA);
				break;

			default:
				proto_tree_add_text(type_tree, tvb, ptvcursor_current_offset(cursor), -1,
				    "Can't handle this address format");
				break;
			}

			afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
			ptvcursor_add(cursor, hf_pgm_nak_grpafi, 2, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_nak_grpres, 2, ENC_BIG_ENDIAN);

			switch (afi) {
			case AFNUM_INET:
				ptvcursor_add(cursor, hf_pgm_nak_grp, 4, ENC_BIG_ENDIAN);
				break;

			case AFNUM_INET6:
				ptvcursor_add(cursor, hf_pgm_nak_grp6, 16, ENC_NA);
				break;

			default:
				proto_tree_add_text(type_tree, tvb, ptvcursor_current_offset(cursor), -1,
				    "Can't handle this address format");
				return;
			}
			break;
		case PGM_POLL_PCKT:
			type_tree = proto_item_add_subtree(tf, ett_pgm_poll);
			ptvcursor_set_tree(cursor, type_tree);

			ptvcursor_add(cursor, hf_pgm_poll_sqn, 4, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_poll_round, 2, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_poll_subtype, 2, ENC_BIG_ENDIAN);
			afi = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor));
			ptvcursor_add(cursor, hf_pgm_poll_pathafi, 2, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_poll_res, 2, ENC_BIG_ENDIAN);

			switch (afi) {
			case AFNUM_INET:
				ptvcursor_add(cursor, hf_pgm_poll_path, 4, ENC_BIG_ENDIAN);
				break;

			case AFNUM_INET6:
				ptvcursor_add(cursor, hf_pgm_poll_path6, 16, ENC_NA);
				break;

			default:
				proto_tree_add_text(type_tree, tvb, ptvcursor_current_offset(cursor), -1,
				    "Can't handle this address format");
				break;
			}

			ptvcursor_add(cursor, hf_pgm_poll_backoff_ivl, 4, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_poll_rand_str, 4, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_poll_matching_bmask, 4, ENC_BIG_ENDIAN);
			break;
		case PGM_POLR_PCKT:
			type_tree = proto_item_add_subtree(tf, ett_pgm_polr);
			ptvcursor_set_tree(cursor, type_tree);

			ptvcursor_add(cursor, hf_pgm_polr_sqn, 4, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_polr_round, 2, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_polr_res, 2, ENC_BIG_ENDIAN);
			break;
		case PGM_ACK_PCKT:
			type_tree = proto_item_add_subtree(tf, ett_pgm_ack);
			ptvcursor_set_tree(cursor, type_tree);

			ptvcursor_add(cursor, hf_pgm_ack_sqn, 4, ENC_BIG_ENDIAN);
			ptvcursor_add(cursor, hf_pgm_ack_bitmap, 4, ENC_BIG_ENDIAN);
			break;
		}

		if (pgmhdr_opts & PGM_OPT)
			dissect_pgmopts(cursor, pktname);

		if (isdata)
			decode_pgm_ports(tvb, ptvcursor_current_offset(cursor), pinfo, tree, pgmhdr_sport, pgmhdr_dport);
	}
}
コード例 #21
0
ファイル: packet-zrtp.c プロジェクト: pvons/wireshark
static void
dissect_zrtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_tree    *zrtp_tree;
  proto_tree    *zrtp_msg_tree;
  proto_tree    *zrtp_msg_data_tree;
  proto_tree    *checksum_tree;
  proto_item    *ti;
  int            linelen;
  int            checksum_offset;
  unsigned char  message_type[9];
  unsigned int   prime_offset = 0;
  unsigned int   msg_offset   = 12;
  guint32        sent_crc, calc_crc;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZRTP");

  col_set_str(pinfo->cinfo, COL_INFO, "Unknown ZRTP Packet");

  ti = proto_tree_add_protocol_format(tree, proto_zrtp, tvb, 0, -1, "ZRTP protocol");
  zrtp_tree = proto_item_add_subtree(ti, ett_zrtp);

  proto_tree_add_item(zrtp_tree, hf_zrtp_rtpversion, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN);
  proto_tree_add_item(zrtp_tree, hf_zrtp_rtppadding, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN);
  proto_tree_add_item(zrtp_tree, hf_zrtp_rtpextension, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN);

  proto_tree_add_item(zrtp_tree, hf_zrtp_sequence, tvb, prime_offset+2, 2, ENC_BIG_ENDIAN);

  proto_tree_add_item(zrtp_tree, hf_zrtp_cookie, tvb, prime_offset+4, 4, ENC_ASCII|ENC_NA);

  proto_tree_add_item(zrtp_tree, hf_zrtp_source_id, tvb, prime_offset+8, 4, ENC_BIG_ENDIAN);

  linelen = tvb_reported_length_remaining(tvb, msg_offset);
  checksum_offset = linelen-4;

  ti = proto_tree_add_protocol_format(zrtp_tree, proto_zrtp, tvb, msg_offset, linelen-4, "Message");
  zrtp_msg_tree = proto_item_add_subtree(ti, ett_zrtp_msg);

  proto_tree_add_item(zrtp_msg_tree, hf_zrtp_signature, tvb, msg_offset+0, 2, ENC_BIG_ENDIAN);

  proto_tree_add_item(zrtp_msg_tree, hf_zrtp_msg_length, tvb, msg_offset+2, 2, ENC_BIG_ENDIAN);

  tvb_memcpy(tvb, (void *)message_type, msg_offset+4, 8);
  message_type[8] = '\0';
  proto_tree_add_item(zrtp_msg_tree, hf_zrtp_msg_type, tvb, msg_offset+4, 8, ENC_ASCII|ENC_NA);

  linelen = tvb_reported_length_remaining(tvb, msg_offset+12);

  if (!strncmp(message_type, "Hello   ", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_Hello(tvb, pinfo, zrtp_msg_data_tree);
  } else if (!strncmp(message_type, "HelloACK", 8)) {
    dissect_HelloACK(pinfo);
  } else if (!strncmp(message_type, "Commit  ", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_Commit(tvb, pinfo, zrtp_msg_data_tree);
  } else if (!strncmp(message_type, "DHPart1 ", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_DHPart(tvb, pinfo, zrtp_msg_data_tree, 1);
  } else if (!strncmp(message_type, "DHPart2 ", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_DHPart(tvb, pinfo, zrtp_msg_data_tree, 2);
  } else if (!strncmp(message_type, "Confirm1", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_Confirm(tvb, pinfo, zrtp_msg_data_tree, 1);
  } else if (!strncmp(message_type, "Confirm2", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_Confirm(tvb, pinfo, zrtp_msg_data_tree, 2);
  } else if (!strncmp(message_type, "Conf2ACK", 8)) {
    dissect_Conf2ACK(pinfo);
  } else if (!strncmp(message_type, "Error   ", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_Error(tvb, pinfo, zrtp_msg_data_tree);
  } else if (!strncmp(message_type, "ErrorACK", 8)) {
    dissect_ErrorACK(pinfo);
  } else if (!strncmp(message_type, "GoClear ", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_GoClear(tvb, pinfo, zrtp_msg_data_tree);
  } else if (!strncmp(message_type, "ClearACK", 8)) {
    dissect_ClearACK(pinfo);
  } else if (!strncmp(message_type, "SASrelay", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_SASrelay(tvb, pinfo, zrtp_msg_data_tree);
  } else if (!strncmp(message_type, "RelayACK", 8)) {
    dissect_RelayACK(pinfo);
  } else if (!strncmp(message_type, "Ping    ", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_Ping(tvb, pinfo, zrtp_msg_data_tree);
  } else if (!strncmp(message_type, "PingACK ", 8)) {
    ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data");
    zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data);
    dissect_PingACK(tvb, pinfo, zrtp_msg_data_tree);
  }

  sent_crc = tvb_get_ntohl(tvb, msg_offset+checksum_offset);
  calc_crc = ~crc32c_calculate(tvb_get_ptr(tvb, 0, msg_offset+checksum_offset), msg_offset+checksum_offset, CRC32C_PRELOAD);

  if (sent_crc == calc_crc) {
    ti = proto_tree_add_uint_format_value(zrtp_tree, hf_zrtp_checksum, tvb, msg_offset+checksum_offset, 4, sent_crc,
                                          "0x%04x [correct]", sent_crc);
    checksum_tree = proto_item_add_subtree(ti, ett_zrtp_checksum);
    ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_good,  tvb, msg_offset+checksum_offset, 4, TRUE);
    PROTO_ITEM_SET_GENERATED(ti);
    ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_bad,   tvb, msg_offset+checksum_offset, 4, FALSE);
    PROTO_ITEM_SET_GENERATED(ti);
  } else {
    ti = proto_tree_add_uint_format_value(zrtp_tree, hf_zrtp_checksum, tvb, msg_offset+checksum_offset, 4, sent_crc,
                                          "0x%04x [incorrect, should be 0x%04x]", sent_crc, calc_crc);
    checksum_tree = proto_item_add_subtree(ti, ett_zrtp_checksum);
    ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_good,  tvb, msg_offset+checksum_offset, 4, FALSE);
    PROTO_ITEM_SET_GENERATED(ti);
    ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_bad,   tvb, msg_offset+checksum_offset, 4, TRUE);
    PROTO_ITEM_SET_GENERATED(ti);
  }

}
コード例 #22
0
ファイル: packet-trmac.c プロジェクト: flaub/HotFuzz
/* Sub-vectors */
static int
sv_text(tvbuff_t *tvb, int svoff, proto_tree *tree)
{
	int	sv_length = tvb_get_guint8(tvb, svoff+0);
	guint16	beacon_type, ring;

	const char *beacon[] = {
		"Recovery mode set", "Signal loss error",
		"Streaming signal not Claim Token MAC frame",
		"Streaming signal, Claim Token MAC frame"
	};

	proto_tree	*sv_tree;
	proto_item	*ti, *hidden_item;

	guchar		errors[6];	/* isolating or non-isolating */

	/* Check the SV length.
	   XXX - Should we do this in each case statement below, e.g. to force
	   an SV length of 6 for the NAUN address? */
	if (sv_length < 1) {
		proto_tree_add_protocol_format(tree, proto_malformed, tvb, svoff+0, 1,
			"Invalid subvector length: %d bytes", sv_length);
		return sv_length;
	}

	/* this just adds to the clutter on the screen...
	proto_tree_add_text(tree, tvb, svoff, 1,
		"Subvector Length: %d bytes", sv_length);*/

	hidden_item = proto_tree_add_uint(tree, hf_trmac_sv, tvb, svoff+1, 1, tvb_get_guint8(tvb, svoff+1));
	PROTO_ITEM_SET_HIDDEN(hidden_item);

	switch(tvb_get_guint8(tvb, svoff+1)) {
		case 0x01: /* Beacon Type */
			beacon_type = tvb_get_ntohs(tvb, svoff+2);
			if (beacon_type < array_length(beacon)) {
				proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
					"Beacon Type: %s", beacon[beacon_type] );
			} else {
				proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
					"Beacon Type: Illegal value: %d", beacon_type );
			}
			break;

		case 0x02: /* NAUN */
			proto_tree_add_ether(tree, hf_trmac_naun, tvb, svoff+1, sv_length-1,
					tvb_get_ptr(tvb, svoff+2, 6));
			break;

		case 0x03: /* Local Ring Number */
			ring = tvb_get_ntohs(tvb, svoff+2);
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Local Ring Number: 0x%04X (%d)", ring, ring);
			break;

		case 0x04: /* Assign Physical Location */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Assign Physical Location: 0x%08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x05: /* Soft Error Report Value */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Soft Error Report Value: %d ms", 10 * tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x06: /* Enabled Function Classes */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Enabled Function Classes: %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x07: /* Allowed Access Priority */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Allowed Access Priority: %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x09: /* Correlator */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Correlator: %04X",  tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x0A: /* Address of last neighbor notification */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Address of Last Neighbor Notification: %s",
				ether_to_str(tvb_get_ptr(tvb, svoff+2, 6)));
			break;

		case 0x0B: /* Physical Location */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Physical Location: 0x%08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x20: /* Response Code */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Response Code: 0x%04X 0x%04X", tvb_get_ntohl(tvb, svoff+2),
				tvb_get_ntohl(tvb, svoff+4) );
			break;

		case 0x21: /* Reserved */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Reserved: 0x%04X", tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x22: /* Product Instance ID */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Product Instance ID: ...");
			break;

		case 0x23: /* Ring Station Microcode Level */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Ring Station Microcode Level: ...");
			break;

		case 0x26: /* Wrap data */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Wrap Data: ... (%d bytes)", sv_length - 2);
			break;

		case 0x27: /* Frame Forward */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Frame Forward: ... (%d bytes)", sv_length - 2);
			break;

		case 0x29: /* Ring Station Status Subvector */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Ring Station Status Subvector: ...");
			break;

		case 0x2A: /* Transmit Status Code */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Transmit Status Code: %04X", tvb_get_ntohs(tvb, svoff+2) );
			break;

		case 0x2B: /* Group Address */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Group Address: %08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x2C: /* Functional Address */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Functional Address: %08X", tvb_get_ntohl(tvb, svoff+2) );
			break;

		case 0x2D: /* Isolating Error Counts */
			memcpy(errors, tvb_get_ptr(tvb, svoff+2, 6), 6);
			ti = proto_tree_add_uint(tree, hf_trmac_errors_iso, tvb, svoff+1, sv_length-1,
				errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
			sv_tree = proto_item_add_subtree(ti, ett_tr_ierr_cnt);

			proto_tree_add_uint(sv_tree, hf_trmac_errors_line, tvb, svoff+2, 1, errors[0]);
			proto_tree_add_uint(sv_tree, hf_trmac_errors_internal, tvb, svoff+3, 1, errors[1]);
			proto_tree_add_uint(sv_tree, hf_trmac_errors_burst, tvb, svoff+4, 1, errors[2]);
			proto_tree_add_uint(sv_tree, hf_trmac_errors_ac, tvb, svoff+5, 1, errors[3]);
			proto_tree_add_uint(sv_tree, hf_trmac_errors_abort, tvb, svoff+6, 1, errors[4]);

			break;

		case 0x2E: /* Non-Isolating Error Counts */
			memcpy(errors, tvb_get_ptr(tvb, svoff+2, 6), 6);
			ti = proto_tree_add_uint(tree, hf_trmac_errors_noniso, tvb, svoff+1, sv_length-1,
				errors[0] + errors[1] + errors[2] + errors[3] + errors[4]);
			sv_tree = proto_item_add_subtree(ti, ett_tr_nerr_cnt);

			proto_tree_add_uint(sv_tree, hf_trmac_errors_lost, tvb, svoff+2, 1, errors[0]);
			proto_tree_add_uint(sv_tree, hf_trmac_errors_congestion, tvb, svoff+3, 1, errors[1]);
			proto_tree_add_uint(sv_tree, hf_trmac_errors_fc, tvb, svoff+4, 1, errors[2]);
			proto_tree_add_uint(sv_tree, hf_trmac_errors_freq, tvb, svoff+5, 1, errors[3]);
			proto_tree_add_uint(sv_tree, hf_trmac_errors_token, tvb, svoff+6, 1, errors[4]);
			break;

		case 0x30: /* Error Code */
			proto_tree_add_text(tree, tvb, svoff+1, sv_length-1,
				"Error Code: %04X", tvb_get_ntohs(tvb, svoff+2) );
			break;

		default: /* Unknown */
			proto_tree_add_text(tree, tvb, svoff+1, 1,
				"Unknown Sub-Vector: 0x%02X", tvb_get_guint8(tvb, svoff+1));
	}
	return sv_length;
}
コード例 #23
0
ファイル: packet-dtp.c プロジェクト: flaub/HotFuzz
static void
dissect_dtp_tlv(tvbuff_t *tvb, int offset, int length,
    proto_tree *tree, proto_item *ti, guint8 type)
{
	switch (type) {

	case TYPE_DOMAIN:
		if (length > 0) {
			proto_item_set_text(ti, "Domain: %s", tvb_format_text(tvb, offset, length - 1));
			proto_tree_add_text(tree, tvb, offset, length, "Domain: %s", tvb_format_text(tvb, offset, length - 1));
		} else {
			proto_item_set_text(ti, "Domain: Bad length %u", length);
			proto_tree_add_text(tree, tvb, offset, length, "Domain: Bad length %u", length);
		}
		break;

	case TYPE_STATUS:
		if (length > 0) {
			proto_item_set_text(ti,
			    "Status: 0x%02x",
			    tvb_get_guint8(tvb, offset));
			proto_tree_add_text(tree, tvb, offset, 1,
			    "Status: 0x%02x",
			    tvb_get_guint8(tvb, offset));
		} else {
			proto_item_set_text(ti,
			    "Status: Bad length %u",
			    length);
			proto_tree_add_text(tree, tvb, offset, length,
			    "Status: Bad length %u",
			    length);
		}
		break;

	case TYPE_DTPTYPE:
		if (length > 0) {
			proto_item_set_text(ti,
			    "Dtptype: 0x%02x",
			    tvb_get_guint8(tvb, offset));
			proto_tree_add_text(tree, tvb, offset, 1,
			    "Dtptype: 0x%02x",
			    tvb_get_guint8(tvb, offset));
		} else {
			proto_item_set_text(ti,
			    "Dtptype: Bad length %u",
			    length);
			proto_tree_add_text(tree, tvb, offset, length,
			    "Dtptype: Bad length %u",
			    length);
		}
		break;


	case TYPE_NEIGHBOR:
		if (length == 6) {
	                const guint8 *macptr=tvb_get_ptr(tvb,offset,length);

			proto_item_set_text(ti, "Neighbor: %s",
				ether_to_str(macptr));	/* XXX - resolve? */
            		proto_tree_add_ether(tree, hf_dtp_some_mac, tvb, offset,length,macptr);
		} else {
			proto_item_set_text(ti,
			    "Neighbor: Bad length %u",
			    length);
			proto_tree_add_text(tree, tvb, offset, length,
			    "Neighbor: Bad length %u",
			    length);
		}
		break;

	default:
		proto_tree_add_text(tree, tvb, offset, length, "Data");
		break;
	}
}
コード例 #24
0
static void
dissect_arp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  guint16     ar_hrd;
  guint16     ar_pro;
  guint8      ar_hln;
  guint8      ar_pln;
  guint16     ar_op;
  int         tot_len;
  proto_tree  *arp_tree = NULL;
  proto_item  *ti, *item;
  const gchar *op_str;
  int         sha_offset, spa_offset, tha_offset, tpa_offset;
  const guint8      *spa_val, *tpa_val;
  gboolean    is_gratuitous;
  gboolean    duplicate_detected = FALSE;
  guint32     duplicate_ip = 0;

  /* Call it ARP, for now, so that if we throw an exception before
     we decide whether it's ARP or RARP or IARP or ATMARP, it shows
     up in the packet list as ARP.

     Clear the Info column so that, if we throw an exception, it
     shows up as a short or malformed ARP frame. */
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
  col_clear(pinfo->cinfo, COL_INFO);

  /* Hardware Address Type */
  ar_hrd = tvb_get_ntohs(tvb, AR_HRD);
  if (ar_hrd == ARPHRD_ATM2225) {
    call_dissector(atmarp_handle, tvb, pinfo, tree);
    return;
  }
  /* Protocol Address Type */
  ar_pro = tvb_get_ntohs(tvb, AR_PRO);
  /* Hardware Address Size */
  ar_hln = tvb_get_guint8(tvb, AR_HLN);
  /* Protocol Address Size */
  ar_pln = tvb_get_guint8(tvb, AR_PLN);
  /* Operation */
  ar_op  = tvb_get_ntohs(tvb, AR_OP);

  tot_len = MIN_ARP_HEADER_SIZE + ar_hln*2 + ar_pln*2;

  /* Adjust the length of this tvbuff to include only the ARP datagram.
     Our caller may use that to determine how much of its packet
     was padding. */
  tvb_set_reported_length(tvb, tot_len);

  if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
    switch (ar_op) {

      case ARPOP_REQUEST:
        if (global_arp_detect_request_storm)
        {
          request_seen(pinfo);
        }
	/* FALLTHRU */
      case ARPOP_REPLY:
      default:
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "ARP");
        break;

      case ARPOP_RREQUEST:
      case ARPOP_RREPLY:
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "RARP");
        break;

      case ARPOP_IREQUEST:
      case ARPOP_IREPLY:
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ARP");
        break;
    }
  }

  /* Get the offsets of the addresses. */
  /* Source Hardware Address */
  sha_offset = MIN_ARP_HEADER_SIZE;
  /* Source Protocol Address */
  spa_offset = sha_offset + ar_hln;
  /* Target Hardware Address */
  tha_offset = spa_offset + ar_pln;
  /* Target Protocol Address */
  tpa_offset = tha_offset + ar_hln;

  if ((ar_op == ARPOP_REPLY || ar_op == ARPOP_REQUEST) &&
      ARP_HW_IS_ETHER(ar_hrd, ar_hln) &&
      ARP_PRO_IS_IPv4(ar_pro, ar_pln)) {

    /* inform resolv.c module of the new discovered addresses */

    guint32 ip;
    const guint8 *mac;

    /* Add sender address if sender MAC address is neither a broadcast/
       multicast address nor an all-zero address and if sender IP address
       isn't all zeroes. */
    ip = tvb_get_ipv4(tvb, spa_offset);
    mac = tvb_get_ptr(tvb, sha_offset, 6);
    if ((mac[0] & 0x01) == 0 && memcmp(mac, mac_allzero, 6) != 0 && ip != 0)
    {
      add_ether_byip(ip, mac);
      if (global_arp_detect_duplicate_ip_addresses)
      {
        duplicate_detected =
          check_for_duplicate_addresses(pinfo, tree, tvb, mac, ip,
                                        &duplicate_ip);
      }
    }

    /* Add target address if target MAC address is neither a broadcast/
       multicast address nor an all-zero address and if target IP address
       isn't all zeroes. */

    /* Do not add target address if the packet is a Request. According to the RFC,
       target addresses in requests have no meaning */

    ip = tvb_get_ipv4(tvb, tpa_offset);
    mac = tvb_get_ptr(tvb, tha_offset, 6);
    if ((mac[0] & 0x01) == 0 && memcmp(mac, mac_allzero, 6) != 0 && ip != 0
        && ar_op != ARPOP_REQUEST)
    {
      add_ether_byip(ip, mac);
      if (global_arp_detect_duplicate_ip_addresses)
      {
        duplicate_detected =
          check_for_duplicate_addresses(pinfo, tree, tvb, mac, ip,
                                        &duplicate_ip);
      }
    }
  }

  if (!tree && !check_col(pinfo->cinfo, COL_INFO)) {
    /* We're not building a protocol tree and we're not setting the Info
       column, so we don't have any more work to do. */
    return;
  }

  spa_val = tvb_get_ptr(tvb, spa_offset, ar_pln);
  tpa_val = tvb_get_ptr(tvb, tpa_offset, ar_pln);

  /* ARP requests/replies with the same sender and target protocol
     address are flagged as "gratuitous ARPs", i.e. ARPs sent out as,
     in effect, an announcement that the machine has MAC address
     XX:XX:XX:XX:XX:XX and IPv4 address YY.YY.YY.YY. Requests are to
     provoke complaints if some other machine has the same IPv4 address,
     replies are used to announce relocation of network address, like
     in failover solutions. */
  if (((ar_op == ARPOP_REQUEST) || (ar_op == ARPOP_REPLY)) && (memcmp(spa_val, tpa_val, ar_pln) == 0))
    is_gratuitous = TRUE;
  else
    is_gratuitous = FALSE;

  if (check_col(pinfo->cinfo, COL_INFO)) {
    switch (ar_op) {
      case ARPOP_REQUEST:
	if (is_gratuitous)
          col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Request)",
                       arpproaddr_to_str(tpa_val, ar_pln, ar_pro));
	else
          col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s?  Tell %s",
                       arpproaddr_to_str(tpa_val, ar_pln, ar_pro),
                       arpproaddr_to_str(spa_val, ar_pln, ar_pro));
        break;
      case ARPOP_REPLY:
        if (is_gratuitous)
          col_add_fstr(pinfo->cinfo, COL_INFO, "Gratuitous ARP for %s (Reply)",
                       arpproaddr_to_str(spa_val, ar_pln, ar_pro));
        else
          col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
                       arpproaddr_to_str(spa_val, ar_pln, ar_pro),
                       tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd));
        break;
      case ARPOP_RREQUEST:
      case ARPOP_IREQUEST:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s?  Tell %s",
                     tvb_arphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd),
                     tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd));
        break;
      case ARPOP_RREPLY:
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
                     tvb_arphrdaddr_to_str(tvb, tha_offset, ar_hln, ar_hrd),
                     arpproaddr_to_str(tpa_val, ar_pln, ar_pro));
        break;
      case ARPOP_IREPLY:
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s",
                     tvb_arphrdaddr_to_str(tvb, sha_offset, ar_hln, ar_hrd),
                     arpproaddr_to_str(spa_val, ar_pln, ar_pro));
        break;
      default:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ARP opcode 0x%04x", ar_op);
        break;
    }
  }

  if (tree) {
    if ((op_str = match_strval(ar_op, op_vals)))  {
      if (is_gratuitous && (ar_op == ARPOP_REQUEST))
        op_str = "request/gratuitous ARP";
      if (is_gratuitous && (ar_op == ARPOP_REPLY))
        op_str = "reply/gratuitous ARP";
      ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
                                          "Address Resolution Protocol (%s)", op_str);
    } else
      ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
                                          "Address Resolution Protocol (opcode 0x%04x)", ar_op);
    arp_tree = proto_item_add_subtree(ti, ett_arp);
    proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, AR_HRD, 2, ar_hrd);
    proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, AR_PRO, 2, ar_pro);
    proto_tree_add_uint(arp_tree, hf_arp_hard_size, tvb, AR_HLN, 1, ar_hln);
    proto_tree_add_uint(arp_tree, hf_arp_proto_size, tvb, AR_PLN, 1, ar_pln);
    proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP,  2, ar_op);
    item = proto_tree_add_boolean(arp_tree, hf_arp_isgratuitous, tvb, 0, 0, is_gratuitous);
    PROTO_ITEM_SET_GENERATED(item);
    if (ar_hln != 0) {
      proto_tree_add_item(arp_tree,
                          ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
                          hf_arp_src_hw_mac :
                          hf_arp_src_hw,
                          tvb, sha_offset, ar_hln, FALSE);
    }
    if (ar_pln != 0) {
      proto_tree_add_item(arp_tree,
                          ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
                          hf_arp_src_proto_ipv4 :
                          hf_arp_src_proto,
                          tvb, spa_offset, ar_pln, FALSE);
    }
    if (ar_hln != 0) {
      proto_tree_add_item(arp_tree,
                          ARP_HW_IS_ETHER(ar_hrd, ar_hln) ?
                          hf_arp_dst_hw_mac :
                          hf_arp_dst_hw,
                          tvb, tha_offset, ar_hln, FALSE);
    }
    if (ar_pln != 0) {
      proto_tree_add_item(arp_tree,
                          ARP_PRO_IS_IPv4(ar_pro, ar_pln) ?
                          hf_arp_dst_proto_ipv4 :
                          hf_arp_dst_proto,
                          tvb, tpa_offset, ar_pln, FALSE);
    }
  }

  if (global_arp_detect_request_storm)
  {
    check_for_storm_count(tvb, pinfo, arp_tree);
  }

  if (duplicate_detected)
  {
    /* Also indicate in info column */
    if (check_col(pinfo->cinfo, COL_INFO))
    {
      col_append_fstr(pinfo->cinfo, COL_INFO, " (duplicate use of %s detected!)",
                      arpproaddr_to_str((guint8*)&duplicate_ip, 4, ETHERTYPE_IP));
    }
  }
}
コード例 #25
0
/*
 * RFC 2225 ATMARP - it's just like ARP, except where it isn't.
 */
static void
dissect_atmarp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  guint16     ar_hrd;
  guint16     ar_pro;
  guint8      ar_shtl;
  guint8      ar_shl;
  guint8      ar_sstl;
  guint8      ar_ssl;
  guint16     ar_op;
  guint8      ar_spln;
  guint8      ar_thtl;
  guint8      ar_thl;
  guint8      ar_tstl;
  guint8      ar_tsl;
  guint8      ar_tpln;
  int         tot_len;
  proto_tree  *arp_tree;
  proto_item  *ti;
  const gchar *op_str;
  int         sha_offset, ssa_offset, spa_offset;
  int         tha_offset, tsa_offset, tpa_offset;
  const guint8      *sha_val, *ssa_val, *spa_val;
  const guint8      *tha_val, *tsa_val, *tpa_val;
  const gchar       *sha_str, *ssa_str, *spa_str;
  const gchar       *tha_str, *tsa_str, *tpa_str;
  proto_tree  *tl_tree;
  proto_item  *tl;

  /* Override the setting to "ARP/RARP". */
  pinfo->current_proto = "ATMARP";

  ar_hrd = tvb_get_ntohs(tvb, ATM_AR_HRD);
  ar_pro = tvb_get_ntohs(tvb, ATM_AR_PRO);
  ar_shtl = tvb_get_guint8(tvb, ATM_AR_SHTL);
  ar_shl = ar_shtl & ATMARP_LEN_MASK;
  ar_sstl = tvb_get_guint8(tvb, ATM_AR_SSTL);
  ar_ssl = ar_sstl & ATMARP_LEN_MASK;
  ar_op  = tvb_get_ntohs(tvb, AR_OP);
  ar_spln = tvb_get_guint8(tvb, ATM_AR_SPLN);
  ar_thtl = tvb_get_guint8(tvb, ATM_AR_THTL);
  ar_thl = ar_thtl & ATMARP_LEN_MASK;
  ar_tstl = tvb_get_guint8(tvb, ATM_AR_TSTL);
  ar_tsl = ar_tstl & ATMARP_LEN_MASK;
  ar_tpln = tvb_get_guint8(tvb, ATM_AR_TPLN);

  tot_len = MIN_ATMARP_HEADER_SIZE + ar_shl + ar_ssl + ar_spln +
    ar_thl + ar_tsl + ar_tpln;

  /* Adjust the length of this tvbuff to include only the ARP datagram.
     Our caller may use that to determine how much of its packet
     was padding. */
  tvb_set_reported_length(tvb, tot_len);

  /* Extract the addresses.  */
  sha_offset = MIN_ATMARP_HEADER_SIZE;
  if (ar_shl != 0) {
    sha_val = tvb_get_ptr(tvb, sha_offset, ar_shl);
    sha_str = atmarpnum_to_str(sha_val, ar_shtl);
  } else {
    sha_val = NULL;
    sha_str = "<No address>";
  }

  ssa_offset = sha_offset + ar_shl;
  if (ar_ssl != 0) {
    ssa_val = tvb_get_ptr(tvb, ssa_offset, ar_ssl);
    ssa_str = atmarpsubaddr_to_str(ssa_val, ar_sstl);
  } else {
    ssa_val = NULL;
    ssa_str = NULL;
  }

  spa_offset = ssa_offset + ar_ssl;
  spa_val = tvb_get_ptr(tvb, spa_offset, ar_spln);
  spa_str = arpproaddr_to_str(spa_val, ar_spln, ar_pro);

  tha_offset = spa_offset + ar_spln;
  if (ar_thl != 0) {
    tha_val = tvb_get_ptr(tvb, tha_offset, ar_thl);
    tha_str = atmarpnum_to_str(tha_val, ar_thtl);
  } else {
    tha_val = NULL;
    tha_str = "<No address>";
  }

  tsa_offset = tha_offset + ar_thl;
  if (ar_tsl != 0) {
    tsa_val = tvb_get_ptr(tvb, tsa_offset, ar_tsl);
    tsa_str = atmarpsubaddr_to_str(tsa_val, ar_tstl);
  } else {
    tsa_val = NULL;
    tsa_str = NULL;
  }

  tpa_offset = tsa_offset + ar_tsl;
  tpa_val = tvb_get_ptr(tvb, tpa_offset, ar_tpln);
  tpa_str = arpproaddr_to_str(tpa_val, ar_tpln, ar_pro);

  if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
    switch (ar_op) {

      case ARPOP_REQUEST:
      case ARPOP_REPLY:
      case ATMARPOP_NAK:
      default:
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMARP");
        break;

      case ARPOP_RREQUEST:
      case ARPOP_RREPLY:
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATMRARP");
        break;

      case ARPOP_IREQUEST:
      case ARPOP_IREPLY:
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "Inverse ATMARP");
        break;
    }
  }

  if (check_col(pinfo->cinfo, COL_INFO)) {
    switch (ar_op) {
      case ARPOP_REQUEST:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Who has %s?  Tell %s",
                     tpa_str, spa_str);
        break;
      case ARPOP_REPLY:
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s is at %s%s%s", spa_str, sha_str,
                     ((ssa_str != NULL) ? "," : ""),
                     ((ssa_str != NULL) ? ssa_str : ""));
        break;
      case ARPOP_IREQUEST:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Who is %s%s%s?  Tell %s%s%s",
                     tha_str,
                     ((tsa_str != NULL) ? "," : ""),
                     ((tsa_str != NULL) ? tsa_str : ""),
                     sha_str,
                     ((ssa_str != NULL) ? "," : ""),
                     ((ssa_str != NULL) ? ssa_str : ""));
        break;
      case ARPOP_IREPLY:
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s%s%s is at %s",
                     sha_str,
                     ((ssa_str != NULL) ? "," : ""),
                     ((ssa_str != NULL) ? ssa_str : ""),
                     spa_str);
        break;
      case ATMARPOP_NAK:
        col_add_fstr(pinfo->cinfo, COL_INFO, "I don't know where %s is", spa_str);
        break;
      default:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown ATMARP opcode 0x%04x", ar_op);
        break;
    }
  }

  if (tree) {
    if ((op_str = match_strval(ar_op, atmop_vals)))
      ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
                                          "ATM Address Resolution Protocol (%s)",
                                          op_str);
    else
      ti = proto_tree_add_protocol_format(tree, proto_arp, tvb, 0, tot_len,
                                          "ATM Address Resolution Protocol (opcode 0x%04x)", ar_op);
    arp_tree = proto_item_add_subtree(ti, ett_arp);

    proto_tree_add_uint(arp_tree, hf_arp_hard_type, tvb, ATM_AR_HRD, 2, ar_hrd);

    proto_tree_add_uint(arp_tree, hf_arp_proto_type, tvb, ATM_AR_PRO, 2,ar_pro);

    tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_SHTL, 1,
                             "Sender ATM number type/length: %s/%u",
                             (ar_shtl & ATMARP_IS_E164 ?
                              "E.164" :
                              "ATM Forum NSAPA"),
                             ar_shl);
    tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
    proto_tree_add_boolean(tl_tree, hf_atmarp_sht, tvb, ATM_AR_SHTL, 1, ar_shtl);
    proto_tree_add_uint(tl_tree, hf_atmarp_shl, tvb, ATM_AR_SHTL, 1, ar_shtl);

    tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_SSTL, 1,
                             "Sender ATM subaddress type/length: %s/%u",
                             (ar_sstl & ATMARP_IS_E164 ?
                              "E.164" :
                              "ATM Forum NSAPA"),
                             ar_ssl);
    tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
    proto_tree_add_boolean(tl_tree, hf_atmarp_sst, tvb, ATM_AR_SSTL, 1, ar_sstl);
    proto_tree_add_uint(tl_tree, hf_atmarp_ssl, tvb, ATM_AR_SSTL, 1, ar_sstl);

    proto_tree_add_uint(arp_tree, hf_arp_opcode, tvb, AR_OP,  2, ar_op);


    proto_tree_add_uint(arp_tree, hf_atmarp_spln, tvb, ATM_AR_SPLN, 1, ar_spln);

    tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_THTL, 1,
                             "Target ATM number type/length: %s/%u",
                             (ar_thtl & ATMARP_IS_E164 ?
                              "E.164" :
                              "ATM Forum NSAPA"),
                             ar_thl);
    tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
    proto_tree_add_boolean(tl_tree, hf_atmarp_tht, tvb, ATM_AR_THTL, 1, ar_thtl);
    proto_tree_add_uint(tl_tree, hf_atmarp_thl, tvb, ATM_AR_THTL, 1, ar_thtl);

    tl = proto_tree_add_text(arp_tree, tvb, ATM_AR_TSTL, 1,
                             "Target ATM subaddress type/length: %s/%u",
                             (ar_tstl & ATMARP_IS_E164 ?
                              "E.164" :
                              "ATM Forum NSAPA"),
                             ar_tsl);
    tl_tree = proto_item_add_subtree(tl, ett_atmarp_tl);
    proto_tree_add_boolean(tl_tree, hf_atmarp_tst, tvb, ATM_AR_TSTL, 1, ar_tstl);
    proto_tree_add_uint(tl_tree, hf_atmarp_tsl, tvb, ATM_AR_TSTL, 1, ar_tstl);

    proto_tree_add_uint(arp_tree, hf_atmarp_tpln, tvb, ATM_AR_TPLN, 1, ar_tpln);

    if (ar_shl != 0)
      dissect_atm_number(tvb, sha_offset, ar_shtl, hf_atmarp_src_atm_num_e164,
                         hf_atmarp_src_atm_num_nsap, arp_tree);

    if (ar_ssl != 0)
      proto_tree_add_bytes_format(arp_tree, hf_atmarp_src_atm_subaddr, tvb, ssa_offset,
                                  ar_ssl,
                                  ssa_val,
                                  "Sender ATM subaddress: %s", ssa_str);

    if (ar_spln != 0) {
      proto_tree_add_item(arp_tree,
                          ARP_PRO_IS_IPv4(ar_pro, ar_spln) ? hf_arp_src_proto_ipv4
                          : hf_arp_src_proto,
                          tvb, spa_offset, ar_spln, FALSE);
    }

    if (ar_thl != 0)
      dissect_atm_number(tvb, tha_offset, ar_thtl, hf_atmarp_dst_atm_num_e164,
                         hf_atmarp_dst_atm_num_nsap, arp_tree);

    if (ar_tsl != 0)
      proto_tree_add_bytes_format(arp_tree, hf_atmarp_dst_atm_subaddr, tvb, tsa_offset,
                                  ar_tsl,
                                  tsa_val,
                                  "Target ATM subaddress: %s", tsa_str);

    if (ar_tpln != 0) {
      proto_tree_add_item(arp_tree,
                          ARP_PRO_IS_IPv4(ar_pro, ar_tpln) ? hf_arp_dst_proto_ipv4
                          : hf_arp_dst_proto,
                          tvb, tpa_offset, ar_tpln, FALSE);
    }
  }
}
コード例 #26
0
ファイル: packet-packetbb.c プロジェクト: flaub/HotFuzz
static int dissect_pbb_message(tvbuff_t *tvb, proto_tree *tree, guint offset) {
  proto_tree *message_tree = NULL;
  proto_tree *header_tree = NULL;
  proto_tree *headerFlags_tree = NULL;

  proto_item *message_item = NULL;
  proto_item *header_item = NULL;
  proto_item *headerFlags_item = NULL;

  guint8 messageType;
  guint8 messageFlags;
  guint16 messageLength, headerLength, messageEnd;
  guint8 addressSize, addressType;

  if (tvb_reported_length(tvb) - offset < 6) {
    proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, -1,
        tvb_get_ptr(tvb, offset, -1), "Not enough octets for minimal message header");
    return tvb_reported_length(tvb);
  }

  messageType = tvb_get_guint8(tvb, offset);
  messageFlags = tvb_get_guint8(tvb, offset+1);
  messageLength = tvb_get_ntohs(tvb, offset+2);
  addressSize = (messageFlags & 0x0f) + 1;

  switch (addressSize) {
    case 4:
      addressType = 0;
      break;
    case 16:
      addressType = 1;
      break;
    case 6:
      addressType = 2;
      break;
    default:
      addressType = 3;
      break;
  }

  messageEnd = offset + messageLength;

  headerLength = 4;

  /* calculate header size */
  if ((messageFlags & MSG_HEADER_HASORIG) != 0) {
    headerLength += addressSize;
  }
  if ((messageFlags & MSG_HEADER_HASHOPLIMIT) != 0) {
    headerLength ++;
  }
  if ((messageFlags & MSG_HEADER_HASHOPCOUNT) != 0) {
    headerLength ++;
  }
  if ((messageFlags & MSG_HEADER_HASSEQNR) != 0) {
    headerLength += 2;
  }

  /* test length for message size */
  if (tvb_reported_length(tvb) - offset < messageLength) {
    proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, -1,
        tvb_get_ptr(tvb, offset, -1), "Not enough octets for message");
    return tvb_reported_length(tvb);
  }

  message_item = proto_tree_add_item(tree, hf_packetbb_msg, tvb, offset, messageLength, FALSE);
  message_tree = proto_item_add_subtree(message_item, ett_packetbb_msg[messageType]);
  proto_item_append_text(message_item, " (type %d)", messageType);

  header_item = proto_tree_add_item(message_tree, hf_packetbb_msgheader, tvb, offset, headerLength, FALSE);
  header_tree = proto_item_add_subtree(header_item, ett_packetbb_msgheader);

  /* type */
  proto_tree_add_item(header_tree, hf_packetbb_msgheader_type, tvb, offset, 1, FALSE);

  /* flags */
  headerFlags_item = proto_tree_add_uint(header_tree, hf_packetbb_msgheader_flags,
      tvb, offset+1, 1, messageFlags & 0xf8);

  headerFlags_tree = proto_item_add_subtree(headerFlags_item, ett_packetbb_msgheader_flags);
  proto_tree_add_boolean(headerFlags_tree, hf_packetbb_msgheader_flags_mhasorig,
      tvb, offset+1, 1, messageFlags);
  proto_tree_add_boolean(headerFlags_tree, hf_packetbb_msgheader_flags_mhashoplimit,
      tvb, offset+1, 1, messageFlags);
  proto_tree_add_boolean(headerFlags_tree, hf_packetbb_msgheader_flags_mhashopcount,
      tvb, offset+1, 1, messageFlags);
  proto_tree_add_boolean(headerFlags_tree, hf_packetbb_msgheader_flags_mhasseqnr,
      tvb, offset+1, 1, messageFlags);

  proto_tree_add_uint(header_tree, hf_packetbb_msgheader_addresssize,
      tvb, offset + 1, 1, (messageFlags & 0x0f) + 1);

  /* size */
  proto_tree_add_item(header_tree, hf_packetbb_msgheader_size, tvb, offset+2, 2, FALSE);

  offset += 4;

  /* originator address */
  if ((messageFlags & MSG_HEADER_HASORIG) != 0) {
    proto_tree_add_item(header_tree, hf_packetbb_msgheader_origaddr[addressType],
        tvb, offset, addressSize, FALSE);
    offset += addressSize;
  }

  /* hop limit */
  if ((messageFlags & MSG_HEADER_HASHOPLIMIT) != 0) {
    proto_tree_add_item(header_tree, hf_packetbb_msgheader_hoplimit, tvb, offset++, 1, FALSE);
  }

  /* hop count */
  if ((messageFlags & MSG_HEADER_HASHOPCOUNT) != 0) {
    proto_tree_add_item(header_tree, hf_packetbb_msgheader_hopcount, tvb, offset++, 1, FALSE);
  }

  /* sequence number */
  if ((messageFlags & MSG_HEADER_HASSEQNR) != 0) {
    proto_tree_add_item(header_tree, hf_packetbb_msgheader_seqnr, tvb, offset, 2, FALSE);
    offset += 2;
  }

  offset = dissect_pbb_tlvblock(tvb, message_tree, offset, messageEnd, 0);
  while (offset < messageEnd) {
    offset = dissect_pbb_addressblock(tvb, message_tree, offset, messageEnd, addressType, addressSize);
  }
  return offset;
}
コード例 #27
0
ファイル: packet-packetbb.c プロジェクト: flaub/HotFuzz
static int dissect_pbb_addressblock(tvbuff_t *tvb, proto_tree *tree, guint offset, guint maxoffset,
    guint8 addressType, guint8 addressSize) {
  guint8 addr[MAX_ADDR_SIZE];

  guint8 numAddr;
  guint8 address_flags;
  guint8 head_length = 0, tail_length = 0;
  guint block_length = 0, midSize = 0;
  guint block_index = 0, head_index = 0, tail_index = 0, mid_index = 0, prefix_index = 0;

  proto_tree *addr_tree = NULL;
  proto_tree *addrFlags_tree = NULL;
  proto_tree *addrValue_tree = NULL;

  proto_item *addr_item = NULL;
  proto_item *addrFlags_item = NULL;
  proto_item *addrValue_item = NULL;

  int i = 0;

  if (maxoffset - offset < 2) {
    proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
        tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for minimal addressblock header");
    return tvb_reported_length(tvb);
  }

  DISSECTOR_ASSERT(addressSize <= MAX_ADDR_SIZE);

  memset(addr, 0, addressSize);

  block_length = 2;
  block_index = offset;
  midSize = addressSize;

  numAddr = tvb_get_guint8(tvb, offset++);
  address_flags = tvb_get_guint8(tvb, offset++);

  if ((address_flags & ADDR_HASHEAD) != 0) {
    head_index = offset;

    if (maxoffset - offset <= 0) {
      proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
          tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for addressblock head");
      return tvb_reported_length(tvb);
    }
    head_length = tvb_get_guint8(tvb, offset++);

    if (head_length > addressSize-1) {
      proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
          tvb_get_ptr(tvb, offset, maxoffset - offset), "address head length is too long");
      return tvb_reported_length(tvb);
    }
    if (maxoffset - offset < head_length) {
      proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
          tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for addressblock head");
      return tvb_reported_length(tvb);
    }
    tvb_memcpy(tvb, addr, offset, head_length);

    midSize -= head_length;
    block_length += (head_length+1);
    offset += head_length;
  }
  if ((address_flags & ADDR_HASZEROTAIL) != 0) {
    tail_index = offset;

    if (maxoffset - offset <= 0) {
      proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
          tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for addressblock tail");
      return tvb_reported_length(tvb);
    }
    tail_length = tvb_get_guint8(tvb, offset++);
    if (tail_length > addressSize-1-head_length) {
      proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
          tvb_get_ptr(tvb, offset, maxoffset - offset), "address tail length is too long");
      return tvb_reported_length(tvb);
    }
    midSize -= tail_length;
    block_length++;
  }
  else if ((address_flags & ADDR_HASFULLTAIL) != 0) {
    tail_index = offset;

    if (maxoffset - offset <= 0) {
      proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
          tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for addressblock tail");
      return tvb_reported_length(tvb);
    }
    tail_length = tvb_get_guint8(tvb, offset++);
    if (tail_length > addressSize-1-head_length) {
      proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
          tvb_get_ptr(tvb, offset, maxoffset - offset), "address tail length is too long");
      return tvb_reported_length(tvb);
    }

    if (maxoffset - offset < tail_length) {
      proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
          tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for addressblock tail");
      return tvb_reported_length(tvb);
    }
    tvb_memcpy(tvb, &addr[addressSize - tail_length], offset, tail_length);

    midSize -= tail_length;
    block_length += (tail_length+1);
    offset += tail_length;
  }

  mid_index = offset;
  block_length += numAddr * midSize;
  offset += numAddr * midSize;

  if ((address_flags & ADDR_HASSINGLEPRELEN) != 0) {
    prefix_index = offset;
    block_length++;
  }
  else if ((address_flags & ADDR_HASMULTIPRELEN) != 0) {
    prefix_index = offset;
    block_length += numAddr;
  }

  if (maxoffset < block_index + block_length) {
    proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
        tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for address block");
    return maxoffset;
  }

  /* add address tree */
  addr_item = proto_tree_add_item(tree, hf_packetbb_addr, tvb, block_index, block_length, FALSE);
  addr_tree = proto_item_add_subtree(addr_item, ett_packetbb_addr);
  proto_item_append_text(addr_item, " (%d addresses)", numAddr);

  /* add num-addr */
  proto_tree_add_item(addr_tree, hf_packetbb_addr_num, tvb, block_index, 1, FALSE);

  /* add flags */
  addrFlags_item = proto_tree_add_item(addr_tree, hf_packetbb_addr_flags, tvb, block_index+1, 1, FALSE);
  addrFlags_tree = proto_item_add_subtree(addrFlags_item, ett_packetbb_addr_flags);

  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hashead, tvb, block_index+1, 1, FALSE);
  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hasfulltail, tvb, block_index+1, 1, FALSE);
  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_haszerotail, tvb, block_index+1, 1, FALSE);
  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hassingleprelen, tvb, block_index+1, 1, FALSE);
  proto_tree_add_item(addrFlags_tree, hf_packetbb_addr_flags_hasmultiprelen, tvb, block_index+1, 1, FALSE);

  if ((address_flags & ADDR_HASHEAD) != 0) {
    /* add head */
    proto_tree_add_item(addr_tree, hf_packetbb_addr_head, tvb, head_index, head_length+1, FALSE);
  }

  if ((address_flags & ADDR_HASFULLTAIL) != 0) {
    /* add full tail */
    proto_tree_add_item(addr_tree, hf_packetbb_addr_tail, tvb, tail_index, tail_length+1, FALSE);
  }
  else if ((address_flags & ADDR_HASZEROTAIL) != 0) {
    /* add zero tail */
    proto_tree_add_item(addr_tree, hf_packetbb_addr_head, tvb, tail_index, 1, FALSE);
  }
  for (i=0; i<numAddr; i++) {
    guint32 ipv4 = (addr[0] << 24) + (addr[1] << 16) + (addr[2] << 8) + addr[3];
    guint8 prefix = addressSize * 8;

    tvb_memcpy(tvb, &addr[head_length], mid_index + midSize*i, midSize);

    switch (addressType) {
      case 0:
        addrValue_item = proto_tree_add_ipv4(addr_tree, hf_packetbb_addr_value[addressType],
            tvb, mid_index, block_index + block_length - mid_index, ipv4);
        break;
      case 1:
        addrValue_item = proto_tree_add_ipv6(addr_tree, hf_packetbb_addr_value[addressType],
            tvb, mid_index, block_index + block_length - mid_index, addr);
        break;
      case 2:
        addrValue_item = proto_tree_add_ether(addr_tree, hf_packetbb_addr_value[addressType],
            tvb, mid_index, block_index + block_length - mid_index, addr);
        break;
      default:
        addrValue_item = proto_tree_add_bytes(addr_tree, hf_packetbb_addr_value[addressType],
            tvb, mid_index, block_index + block_length - mid_index, addr);
        break;
    }
    addrValue_tree = proto_item_add_subtree(addrValue_item, ett_packetbb_addr_value);

    proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_mid, tvb,
        mid_index + midSize*i, midSize, FALSE);

    if ((address_flags & ADDR_HASSINGLEPRELEN) != 0) {
      prefix = tvb_get_guint8(tvb, prefix_index);
      proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_prefix, tvb, prefix_index, 1, FALSE);
    }
    else if ((address_flags & ADDR_HASMULTIPRELEN) != 0) {
      prefix = tvb_get_guint8(tvb, prefix_index + i);
      proto_tree_add_item(addrValue_tree, hf_packetbb_addr_value_prefix, tvb, prefix_index + i, 1, FALSE);
    }
    proto_item_append_text(addrValue_item, "/%d", prefix);
  }

  offset = dissect_pbb_tlvblock(tvb, addr_tree, block_index + block_length, maxoffset, numAddr);
  return offset;
}
コード例 #28
0
static fragment_head *
force_reassemble_seq(reassembly_table *table, packet_info *pinfo, guint32 id)
{
	fragment_head *fd_head;
	fragment_item *fd_i;
	fragment_item *last_fd;
	guint32 dfpos, size, packet_lost, burst_lost, seq_num;
	guint8 *data;

	fd_head = fragment_get(table, pinfo, id, NULL);

	/* have we already seen this frame ?*/
	if (pinfo->fd->flags.visited) {
		if (fd_head != NULL && fd_head->flags & FD_DEFRAGMENTED) {
			return fd_head;
		} else {
			return NULL;
		}
	}

	if (fd_head==NULL){
		/* we must have it to continue */
		return NULL;
	}

	/* check for packet lost and count the burst of packet lost */
	packet_lost = 0;
	burst_lost = 0;
	seq_num = 0;
	for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
		if (seq_num != fd_i->offset) {
			packet_lost += fd_i->offset - seq_num;
			if ( (fd_i->offset - seq_num) > burst_lost ) {
				burst_lost = fd_i->offset - seq_num;
			}
		}
		seq_num = fd_i->offset + 1;
	}

	/* we have received an entire packet, defragment it and
	 * free all fragments
	 */
	size=0;
	last_fd=NULL;
	for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
	  if(!last_fd || last_fd->offset!=fd_i->offset){
	    size+=fd_i->len;
	  }
	  last_fd=fd_i;
	}

	data = (guint8 *) g_malloc(size);
	fd_head->tvb_data = tvb_new_real_data(data, size, size);
	fd_head->len = size;		/* record size for caller	*/

	/* add all data fragments */
	dfpos = 0;
	last_fd=NULL;
	for (fd_i=fd_head->next;fd_i && fd_i->len + dfpos <= size;fd_i=fd_i->next) {
	  if (fd_i->len) {
	    if(!last_fd || last_fd->offset!=fd_i->offset){
	      memcpy(data+dfpos,tvb_get_ptr(fd_i->tvb_data,0,fd_i->len),fd_i->len);
	      dfpos += fd_i->len;
	    } else {
	      /* duplicate/retransmission/overlap */
	      fd_i->flags    |= FD_OVERLAP;
	      fd_head->flags |= FD_OVERLAP;
	      if( (last_fd->len!=fd_i->datalen)
		  || tvb_memeql(last_fd->tvb_data, 0, tvb_get_ptr(fd_i->tvb_data, 0, last_fd->len), last_fd->len) ){
			fd_i->flags    |= FD_OVERLAPCONFLICT;
			fd_head->flags |= FD_OVERLAPCONFLICT;
	      }
	    }
	  }
	  last_fd=fd_i;
	}

	/* we have defragmented the pdu, now free all fragments*/
	for (fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
	  if(fd_i->tvb_data){
	    tvb_free(fd_i->tvb_data);
	    fd_i->tvb_data=NULL;
	  }
	}

	/* mark this packet as defragmented */
	fd_head->flags |= FD_DEFRAGMENTED;
	fd_head->reassembled_in=pinfo->fd->num;

	col_append_fstr(pinfo->cinfo, COL_INFO, " (t4-data Reassembled: %d pack lost, %d pack burst lost)", packet_lost, burst_lost);

	p_t38_packet_conv_info->packet_lost = packet_lost;
	p_t38_packet_conv_info->burst_lost = burst_lost;

	return fd_head;
}
コード例 #29
0
/* ---------------------------------------------- */
static void
dissect_fix_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item    *ti;
    proto_tree    *fix_tree;
    int            pdu_len;
    int            offset = 0;
    int            field_offset, ctrla_offset;
    int            tag_value;
    char          *value;
    char          *tag_str;
    fix_parameter *tag;

    /* Make entries in Protocol column and Info column on summary display */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "FIX");
    col_clear(pinfo->cinfo, COL_INFO);

    /* get at least the fix version: 8=FIX.x.x */
    if (fix_marker(tvb, 0) != 0) {
        /* not a fix packet start but it's a fix packet */
        col_set_str(pinfo->cinfo, COL_INFO, "[FIX continuation]");
        ti = proto_tree_add_item(tree, proto_fix, tvb, 0, -1, ENC_NA);
        fix_tree = proto_item_add_subtree(ti, ett_fix);
        proto_tree_add_item(fix_tree, hf_fix_data, tvb, 0, -1, ENC_NA);
        return;
    }

    pdu_len = tvb_reported_length(tvb);
    ti = proto_tree_add_item(tree, proto_fix, tvb, 0, -1, ENC_NA);
    fix_tree = proto_item_add_subtree(ti, ett_fix);

    /* begin string */
    ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01);
    if (ctrla_offset == -1) {
        return;
    }
    offset = ctrla_offset + 1;

    /* msg length */
    ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01);
    if (ctrla_offset == -1) {
        return;
    }
    offset = ctrla_offset + 1;

    /* msg type */
    if (!(tag = fix_param(tvb, offset)) || tag->value_len < 1) {
        return;
    }

    if (check_col(pinfo->cinfo, COL_INFO)) {
        const char *msg_type;

        value = tvb_get_ephemeral_string(tvb, tag->value_offset, tag->value_len);
        msg_type = str_to_str(value, messages_val, "FIX Message (%s)");
        col_add_str(pinfo->cinfo, COL_INFO, msg_type);
    }

    /* In the interest of speed, if "tree" is NULL, don't do any work not
     * necessary to generate protocol tree items.
     */
    field_offset = 0;

    while(field_offset < pdu_len && (tag = fix_param(tvb, field_offset)) ) {
        int i, found;

        if (tag->tag_len < 1) {
            field_offset =  tag->ctrla_offset + 1;
            continue;
        }

        tag_str = tvb_get_ephemeral_string(tvb, field_offset, tag->tag_len);
        tag_value = atoi(tag_str);
        if (tag->value_len < 1) {
            proto_tree *field_tree;
            /* XXX - put an error indication here.  It's too late
               to return FALSE; we've already started dissecting,
               and if a heuristic dissector starts dissecting
               (either updating the columns or creating a protocol
               tree) and then gives up, it leaves crud behind that
               messes up other dissectors that might process the
               packet. */
            ti = proto_tree_add_text(fix_tree, tvb, field_offset, tag->field_len, "%i: <missing value>", tag_value);
            field_tree = proto_item_add_subtree(ti, ett_badfield);
            proto_tree_add_uint(field_tree, hf_fix_field_tag, tvb, field_offset, tag->tag_len, tag_value);
            field_offset =  tag->ctrla_offset + 1;
            continue;
        }

        /* fix_fields array is sorted by tag_value */
        found = 0;
        if ((i = tag_search(tag_value)) >= 0) {
            found = 1;
        }

        value = tvb_get_ephemeral_string(tvb, tag->value_offset, tag->value_len);
        if (found) {
            if (fix_fields[i].table) {
                if (tree) {
                    switch (fix_fields[i].type) {
                    case 1: /* strings */
                        proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value,
                            "%s (%s)", value, str_to_str(value, fix_fields[i].table, "unknown %s"));
                        break;
                    case 2: /* char */
                        proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value,
                            "%s (%s)", value, val_to_str(*value, fix_fields[i].table, "unknown %d"));
                        break;
                    default:
                        proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value,
                            "%s (%s)", value, val_to_str(atoi(value), fix_fields[i].table, "unknown %d"));
                        break;
                    }
                }
            }
            else {
              proto_item *item;

              /* checksum */
              switch(tag_value) {
              case 10:
                {
                    proto_tree *checksum_tree;
                    guint8 sum = 0;
                    const guint8 *data = tvb_get_ptr(tvb, 0, field_offset);
                    gboolean sum_ok;
                    int j;

                    for (j = 0; j < field_offset; j++, data++) {
                         sum += *data;
                    }
                    sum_ok = (atoi(value) == sum);
                    if (sum_ok) {
                        item = proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len,
                                value, "%s [correct]", value);
                    }
                    else {
                        item = proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len,
                                value, "%s [incorrect should be %d]", value, sum);
                    }
                    checksum_tree = proto_item_add_subtree(item, ett_checksum);
                    item = proto_tree_add_boolean(checksum_tree, hf_fix_checksum_good, tvb, field_offset, tag->field_len, sum_ok);
                    PROTO_ITEM_SET_GENERATED(item);
                    item = proto_tree_add_boolean(checksum_tree, hf_fix_checksum_bad, tvb, field_offset, tag->field_len, !sum_ok);
                    PROTO_ITEM_SET_GENERATED(item);
                    if (!sum_ok)
                        expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
                }
                break;
              default:
                proto_tree_add_string(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value);
                break;
              }
            }
        }
        else if (tree) {
          proto_tree *field_tree;

          /* XXX - it could be -1 if the tag isn't a number */
          ti = proto_tree_add_text(fix_tree, tvb, field_offset, tag->field_len, "%i: %s", tag_value, value);
          field_tree = proto_item_add_subtree(ti, ett_unknow);
          proto_tree_add_uint(field_tree, hf_fix_field_tag, tvb, field_offset, tag->tag_len, tag_value);
          proto_tree_add_item(field_tree, hf_fix_field_value, tvb, tag->value_offset, tag->value_len, ENC_ASCII|ENC_NA);
        }

        field_offset =  tag->ctrla_offset + 1;

        tag_str = NULL;
    }
    return;
}
コード例 #30
0
ファイル: packet-packetbb.c プロジェクト: flaub/HotFuzz
static int dissect_pbb_tlvblock(tvbuff_t *tvb, proto_tree *tree, guint offset,
    guint maxoffset, gint8 addrCount) {
  guint16 tlvblockLength;
  guint tlvblockEnd;

  proto_tree *tlvblock_tree = NULL;
  proto_tree *tlv_tree = NULL;
  proto_tree *tlv_flags_tree = NULL;
  proto_tree *tlvValue_tree = NULL;

  proto_item *tlvBlock_item = NULL;
  proto_item *tlv_item = NULL;
  proto_item *tlvFlags_item = NULL;
  proto_item *tlvValue_item = NULL;
  proto_item *ti = NULL;

  int tlvCount = 0;

  if (maxoffset < offset + 2) {
    proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
        tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for minimal tlvblock");
    return maxoffset;
  }

  tlvblockLength = tvb_get_ntohs(tvb, offset);

  tlvblockEnd = offset + 2 + tlvblockLength;
  if (maxoffset < tlvblockEnd) {
    proto_tree_add_bytes_format(tree, hf_packetbb_error, tvb, offset, maxoffset - offset,
        tvb_get_ptr(tvb, offset, maxoffset - offset), "Not enough octets for tlvblock");
    return maxoffset;
  }

  tlvBlock_item = proto_tree_add_item(tree, hf_packetbb_tlvblock, tvb, offset, tlvblockEnd - offset, FALSE);
  tlvblock_tree = proto_item_add_subtree(tlvBlock_item, ett_packetbb_tlvblock);

  proto_tree_add_item(tlvblock_tree, hf_packetbb_tlvblock_length, tvb, offset, 2, FALSE);

  offset += 2;
  while (offset < tlvblockEnd) {
    guint tlvStart, tlvLength;
    guint8 tlvType, tlvFlags, tlvExtType, indexStart, indexEnd;
    guint16 length = 0;

    tlvStart = offset;
    tlvType = tvb_get_guint8(tvb, offset++);
    tlvFlags = tvb_get_guint8(tvb, offset++);

    indexStart = 0;
    indexEnd = addrCount;
    tlvExtType = 0;

    if ((tlvFlags & TLV_HAS_TYPEEXT) != 0) {
      tlvExtType = tvb_get_guint8(tvb, offset++);
    }

    if ((tlvFlags & TLV_HAS_SINGLEINDEX) != 0) {
      indexStart = indexEnd = tvb_get_guint8(tvb, offset++);
    }
    else if ((tlvFlags & TLV_HAS_MULTIINDEX) != 0) {
      indexStart = tvb_get_guint8(tvb, offset++);
      indexEnd = tvb_get_guint8(tvb, offset++);
    }

    if ((tlvFlags & TLV_HAS_VALUE) != 0) {
      if ((tlvFlags & TLV_HAS_EXTLEN) != 0) {
        length = tvb_get_ntohs(tvb, offset++);
      }
      else {
        length = tvb_get_guint8(tvb, offset++);
      }
    }

    tlvLength = offset - tlvStart + length;
    offset = tlvStart;

    tlv_item = proto_tree_add_item(tlvBlock_item, hf_packetbb_tlv, tvb, tlvStart, tlvLength, FALSE);
    tlv_tree = proto_item_add_subtree(tlv_item, ett_packetbb_tlv[tlvType]);

    if ((tlvFlags & TLV_HAS_TYPEEXT) == 0) {
      proto_item_append_text(tlv_item, " (%d)", tlvType);
    }
    else {
      proto_item_append_text(tlv_item, " (%d/%d)", tlvType, tlvExtType);
    }

    /* add type */
    proto_tree_add_item(tlv_tree, hf_packetbb_tlv_type, tvb, offset++, 1, FALSE);

    /* add flags */
    tlvFlags_item = proto_tree_add_item(tlv_tree, hf_packetbb_tlv_flags, tvb, offset, 1, FALSE);
    tlv_flags_tree = proto_item_add_subtree(tlvFlags_item, ett_packetbb_tlv_flags);

    proto_tree_add_item(tlv_flags_tree, hf_packetbb_tlv_flags_hastypext, tvb, offset, 1, FALSE);
    proto_tree_add_item(tlv_flags_tree, hf_packetbb_tlv_flags_hassingleindex, tvb, offset, 1, FALSE);
    proto_tree_add_item(tlv_flags_tree, hf_packetbb_tlv_flags_hasmultiindex, tvb, offset, 1, FALSE);
    proto_tree_add_item(tlv_flags_tree, hf_packetbb_tlv_flags_hasvalue, tvb, offset, 1, FALSE);
    proto_tree_add_item(tlv_flags_tree, hf_packetbb_tlv_flags_hasextlen, tvb, offset, 1, FALSE);
    proto_tree_add_item(tlv_flags_tree, hf_packetbb_tlv_flags_hasmultivalue, tvb, offset, 1, FALSE);
    offset++;

    if ((tlvFlags & TLV_HAS_TYPEEXT) != 0) {
      /* add ext-type */
      proto_tree_add_item(tlv_tree, hf_packetbb_tlv_typeext, tvb, offset++, 1, FALSE);
    }

    if (addrCount > 0) {
      /* add index values */
      if ((tlvFlags & TLV_HAS_SINGLEINDEX) != 0) {
        proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_indexstart, tvb, offset++, 1, indexStart);

        ti = proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_indexend, tvb, offset, 0, indexEnd);
        proto_item_append_text(ti, " (implicit)");
      }
      else if ((tlvFlags & TLV_HAS_MULTIINDEX) != 0) {
        proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_indexstart, tvb, offset++, 1, indexStart);
        proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_indexend, tvb, offset++, 1, indexEnd);
      }
      else {
        ti = proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_indexstart, tvb, offset, 0, indexStart);
        proto_item_append_text(ti, " (implicit)");

        ti = proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_indexend, tvb, offset, 0, indexEnd);
        proto_item_append_text(ti, " (implicit)");
      }
    }

    /* add length */
    if ((tlvFlags & TLV_HAS_VALUE) != 0) {
      if ((tlvFlags & TLV_HAS_EXTLEN) != 0) {
        proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_length, tvb, offset, 2, length);
        offset += 2;
      }
      else {
        proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_length, tvb, offset++, 1, length);
      }
    }
    else {
      ti = proto_tree_add_uint(tlv_tree, hf_packetbb_tlv_length, tvb, offset, 0, 0);
      proto_item_append_text(ti, " (implicit)");
    }

    if (length > 0) {
      /* add value */
      tlvValue_item = proto_tree_add_item(tlv_tree, hf_packetbb_tlv_value, tvb, offset, length, FALSE);

      if ((tlvFlags & TLV_HAS_MULTIVALUE) == 0) {
        offset += length;
      }
      else {
        int i;
        guint8 c = indexEnd - indexStart + 1;
        tlvValue_tree = proto_item_add_subtree(tlvValue_item, ett_packetbb_tlv_value);

        for (i=indexStart; i<=indexEnd; i++) {
          proto_tree_add_item(tlvValue_tree, hf_packetbb_tlv_multivalue, tvb, offset, length/c, FALSE);
          offset += (length/c);
        }
      }
    }
    tlvCount++;
  }

  proto_item_append_text(tlvBlock_item, " (%d TLVs)", tlvCount);

  return offset;
}