Example #1
0
static gint
add_message(tvbuff_t * tvb, gint offset, proto_tree * tree, wmem_strbuf_t * info)
{
	guint16      descriptor_id, message_id;
	gint         data_len;
	proto_item  *msg;
	proto_tree  *msg_tree;
	const gchar *descriptor;

	descriptor_id = tvb_get_ntohs(tvb, offset);
	message_id = tvb_get_ntohs(tvb, offset + 2);
	data_len = tvb_get_ntohs(tvb, offset + 4) * 2;

	/* Message subtree */
	descriptor = val_to_str(descriptor_id, descriptors, "Unknown (%u)");
	if (descriptor_id == ACK)
		msg = proto_tree_add_none_format(tree,
						 hf_armagetronad_msg_subtree,
						 tvb, offset, data_len + 6,
						 "ACK %d messages",
						 data_len / 2);
	else
		msg = proto_tree_add_none_format(tree,
						 hf_armagetronad_msg_subtree,
						 tvb, offset, data_len + 6,
						 "Message 0x%04x [%s]",
						 message_id, descriptor);

	msg_tree = proto_item_add_subtree(msg, ett_message);

	/* DescriptorID field */
	proto_tree_add_item(msg_tree, hf_armagetronad_descriptor_id, tvb,
			    offset, 2, ENC_BIG_ENDIAN);
	if (info)
		wmem_strbuf_append_printf(info, "%s, ", descriptor);

	/* MessageID field */
	proto_tree_add_item(msg_tree, hf_armagetronad_message_id, tvb,
			    offset + 2, 2, ENC_BIG_ENDIAN);

	/* DataLen field */
	proto_tree_add_item(msg_tree, hf_armagetronad_data_len, tvb,
			    offset + 4, 2, ENC_BIG_ENDIAN);

	/* Data field */
	add_message_data(tvb, offset + 6, data_len, msg_tree);

	return data_len + 6;
}
static void
dissect_dmx_chan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DMX Channels");
	col_clear(pinfo->cinfo, COL_INFO);

	if (tree != NULL) {
		static const char *chan_format[]   = {
			"%2u%% ",
			"0x%02x ",
			"%3u "
		};
		static const char *string_format[] = {
			"0x%03x: %s",
			"%3u: %s"
		};
		wmem_strbuf_t *chan_str = wmem_strbuf_new_label(wmem_packet_scope());
		proto_item    *item;
		guint16        length,r,c,row_count;
		guint8         v;
		guint          offset   = 0;

		proto_tree    *ti = proto_tree_add_item(tree, proto_dmx_chan, tvb, offset, -1, ENC_NA);
		proto_tree    *dmx_chan_tree = proto_item_add_subtree(ti, ett_dmx_chan);

		length = tvb_reported_length_remaining(tvb, offset);

		row_count = (length / global_disp_col_count) + ((length % global_disp_col_count) == 0 ? 0 : 1);
		for (r = 0; r < row_count;r++) {
			wmem_strbuf_truncate(chan_str, 0);
			for (c = 0;(c < global_disp_col_count) && (((r * global_disp_col_count) + c) < length);c++) {
				if ((global_disp_col_count >= 2) && ((c % (global_disp_col_count / 2)) == 0)) {
					wmem_strbuf_append(chan_str, " ");
				}

				v = tvb_get_guint8(tvb, (offset + (r * global_disp_col_count) + c));
				if (global_disp_chan_val_type == 0) {
					v = (v * 100) / 255;
					if (v == 100) {
						wmem_strbuf_append(chan_str, "FL ");
					} else {
						wmem_strbuf_append_printf(chan_str, chan_format[global_disp_chan_val_type], v);
					}
				} else {
					wmem_strbuf_append_printf(chan_str, chan_format[global_disp_chan_val_type], v);
				}
			}

			proto_tree_add_none_format(dmx_chan_tree, hf_dmx_chan_output_dmx_data, tvb,
							offset+(r * global_disp_col_count), c,
							string_format[global_disp_chan_nr_type],
							(r * global_disp_col_count) + 1, wmem_strbuf_get_str(chan_str));
		}

		/* Add the real type hidden */
		item = proto_tree_add_item(dmx_chan_tree, hf_dmx_chan_output_data_filter, tvb,
						offset, length, ENC_NA );
		PROTO_ITEM_SET_HIDDEN(item);
	}
}
Example #3
0
/* dict = d...e */
static int
dissect_bencoded_dict(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, const char *label )
{
  proto_item *ti;
  proto_tree *sub_tree;
  guint       orig_offset = offset;

  if(offset == 0)
  {
    ti = proto_tree_add_item(tree, proto_bt_dht, tvb, 0, -1, ENC_NA);
    sub_tree = proto_item_add_subtree(ti, ett_bt_dht);
  }
  else
  {
    ti = proto_tree_add_none_format( tree, hf_bencoded_dict, tvb, offset, -1, "%s: Dictionary...", label );
    sub_tree = proto_item_add_subtree( ti, ett_bencoded_dict);
  }

  /* skip the first char('d') */
  offset += 1;

  while( tvb_get_guint8(tvb,offset)!='e' )
    offset = dissect_bencoded_dict_entry( tvb, pinfo, sub_tree, offset );

  offset += 1;
  proto_item_set_len( ti, offset-orig_offset );

  return offset;
}
Example #4
0
/* Has storm request rate been exceeded with this request? */
static void check_for_storm_count(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  gboolean report_storm = FALSE;

  if (p_get_proto_data(pinfo->fd, proto_arp) != 0)
  {
    /* Read any previous stored packet setting */
    report_storm = (p_get_proto_data(pinfo->fd, proto_arp) == (void*)STORM);
  }
  else
  {
    /* Seeing packet for first time - check against preference settings */
    gint seconds_delta  = (gint) (pinfo->fd->abs_ts.secs - time_at_start_of_count.secs);
    gint nseconds_delta = pinfo->fd->abs_ts.nsecs - time_at_start_of_count.nsecs;
    gint gap = (seconds_delta*1000) + (nseconds_delta / 1000000);

    /* Reset if gap exceeds period or -ve gap (indicates we're rescanning from start) */
    if ((gap > (gint)global_arp_detect_request_storm_period) ||
        (gap < 0))
    {
      /* Time period elapsed without threshold being exceeded */
      arp_request_count = 1;
      time_at_start_of_count = pinfo->fd->abs_ts;
      p_add_proto_data(pinfo->fd, proto_arp, (void*)NO_STORM);
      return;
    }
    else
      if (arp_request_count > global_arp_detect_request_storm_packets)
      {
        /* Storm detected, record and reset start time. */
        report_storm = TRUE;
        p_add_proto_data(pinfo->fd, proto_arp, (void*)STORM);
        time_at_start_of_count = pinfo->fd->abs_ts;
      }
      else
      {
        /* Threshold not exceeded yet - no storm */
        p_add_proto_data(pinfo->fd, proto_arp, (void*)NO_STORM);
      }
  }

  if (report_storm)
  {
    /* Report storm and reset counter */
    proto_item *ti = proto_tree_add_none_format(tree, hf_arp_packet_storm, tvb, 0, 0,
                                                "Packet storm detected (%u packets in < %u ms)",
                                                global_arp_detect_request_storm_packets,
                                                global_arp_detect_request_storm_period);
    PROTO_ITEM_SET_GENERATED(ti);

    expert_add_info_format(pinfo, ti,
                           PI_SEQUENCE, PI_NOTE,
                           "ARP packet storm detected (%u packets in < %u ms)",
                           global_arp_detect_request_storm_packets,
                           global_arp_detect_request_storm_period);
    arp_request_count = 0;
  }
}
/* dissect a bt dht values list from tvb, start at offset. it's like "l6:....6:....e" */
static int
dissect_bt_dht_values(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label )
{
  proto_item *ti;
  proto_tree *sub_tree;
  proto_item *value_ti;
  proto_tree *value_tree;
  address     addr;

  guint       peer_index;
  guint       string_len_start;
  guint       string_len;
  guint16     port;

  ti = proto_tree_add_item( tree, hf_bt_dht_peers, tvb, offset, 0, ENC_NA );
  sub_tree = proto_item_add_subtree( ti, ett_bt_dht_peers);

  peer_index = 0;
  /* we has confirmed that the first byte is 'l' */
  offset += 1;

  /* dissect bt-dht values */
  while( tvb_get_guint8(tvb,offset)!='e' )
  {
    string_len_start = offset;
    while( tvb_get_guint8(tvb,offset) != ':' )
      offset += 1;

    string_len = atoi( tvb_get_ephemeral_string(tvb,string_len_start,offset-string_len_start) );
    /* skip the ':' */
    offset += 1;
    /* 4 bytes ip, 2 bytes port */
    for( ; string_len>=6; string_len-=6, offset+=6 )
    {
      peer_index += 1;
      SET_ADDRESS( &addr, AT_IPv4, 4, tvb_get_ptr( tvb, offset, 4) );
      port = tvb_get_letohl( tvb, offset+4 );

      value_ti = proto_tree_add_none_format( sub_tree, hf_bt_dht_peer, tvb, offset, 6,
          "%d\t%s:%u", peer_index, ep_address_to_str( &addr ), port );
      value_tree = proto_item_add_subtree( value_ti, ett_bt_dht_peers);

      proto_tree_add_item( value_tree, hf_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
      proto_tree_add_item( value_tree, hf_port, tvb, offset+4, 2, ENC_BIG_ENDIAN);
    }
    /* truncated data */
    if( string_len>0 )
    {
      proto_tree_add_item( tree, hf_truncated_data, tvb, offset, string_len, ENC_NA );
      offset += string_len;
    }
  }
  proto_item_set_text( ti, "%s: %d peers", label, peer_index );
  col_append_fstr( pinfo->cinfo, COL_INFO, "reply=%d peers  ", peer_index );
  *result = ep_strdup_printf("%d peers", peer_index);

  return offset;
}
static void add_double_coordinates( proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint32 offset, guint32 xoffset, guint32 yoffset, guint32 zoffset)
{
    proto_item *ti;
    proto_tree * coord_tree;
    ti = proto_tree_add_none_format(tree, hf_mc_double_coords, tvb, offset, -1, "Coordinates: %f, %f, %f", tvb_get_ntohieee_double(tvb, offset+xoffset), tvb_get_ntohieee_double(tvb, offset+yoffset), tvb_get_ntohieee_double(tvb, offset+zoffset));
    coord_tree = proto_item_add_subtree(ti, ett_mc_double_coords);
    proto_tree_add_item(coord_tree, hf_mc_x, tvb, offset + xoffset, 8, FALSE);
    proto_tree_add_item(coord_tree, hf_mc_y, tvb, offset + yoffset, 8, FALSE);
    proto_tree_add_item(coord_tree, hf_mc_z, tvb, offset + zoffset, 8, FALSE);
}
Example #7
0
void dissect_mqpcf_parm_int(tvbuff_t *tvb, proto_tree *tree, guint offset,guint uPrm,guint uVal,int hfindex)
{
	header_field_info *hfinfo;
	guint8 *pVal;

	pVal=dissect_mqpcf_parm_getintval(uPrm,uVal);
	hfinfo=proto_registrar_get_nth(hfindex);

	if (pVal)
	{
		proto_tree_add_none_format(tree, hfindex, tvb, offset , 4, "%s:%d-%s",
			hfinfo->name, uVal, pVal);
	}
	else
	{
		proto_tree_add_none_format(tree, hfindex, tvb, offset , 4, "%s:%8x-%d",
			hfinfo->name, uVal, uVal);
	}
}
Example #8
0
    int
    DDS_Dissector::dissect ()
    {

      gint offset = 0;

      col_set_str(pinfo_->cinfo, COL_PROTOCOL, "OpenDDS");

      col_clear(pinfo_->cinfo, COL_INFO);

      TransportHeader trans =
        demarshal_data<TransportHeader>(tvb_, offset);
      std::string trans_str(format(trans));

      col_add_fstr(pinfo_->cinfo, COL_INFO, "DCPS %s", trans_str.c_str());

      if (tree_ != NULL) {
        proto_item* item =
          proto_tree_add_protocol_format(tree_,
                                         proto_opendds, tvb_, 0, -1,
                                         "OpenDDS DCPS Protocol, %s",
                                         trans_str.c_str());

        proto_tree* trans_tree =
          proto_item_add_subtree(item, ett_trans_header);

        this->dissect_transport_header (trans_tree, trans, offset);

        while (offset < gint(tvb_length(tvb_)))
          {
            DataSampleHeader sample =
              demarshal_data<DataSampleHeader>(tvb_, offset);

            std::string sample_str(format(sample));

            proto_item* item =
              proto_tree_add_none_format
              (trans_tree, hf_sample, tvb_, offset,
               static_cast<gint>(sample.marshaled_size()) +
               sample.message_length_,
               "%s",
               sample_str.c_str()
               );

            proto_tree* sample_tree =
              proto_item_add_subtree(item, ett_sample_header);
            this->dissect_sample_header (sample_tree, sample, offset);

            sample_tree = proto_item_add_subtree (item, ett_sample_header);
            this->dissect_sample_payload (sample_tree, sample, offset);

          }
      }
      return offset;
    }
static int
dissect_bt_dht_nodes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char **result, char *label )
{
  proto_item *ti;
  proto_tree *sub_tree;
  proto_item *node_ti;
  proto_tree *node_tree;

  guint       node_index;
  guint       string_len_start;
  guint       string_len;
  address     addr;
  guint16     port;
  guint8     *id;

  ti = proto_tree_add_item( tree, hf_bt_dht_nodes, tvb, offset, 0, ENC_NA );
  sub_tree = proto_item_add_subtree( ti, ett_bt_dht_nodes);
  node_index = 0;

  string_len_start = offset;
  while( tvb_get_guint8(tvb,offset) != ':' )
    offset += 1;

  string_len = atoi( tvb_get_ephemeral_string(tvb,string_len_start,offset-string_len_start) );
  /* skip the ':' */
  offset += 1;

  /* 20 bytes id, 4 bytes ip, 2 bytes port */
  for( ; string_len>=26; string_len-=26, offset+=26 )
  {
    node_index += 1;

    id = tvb_bytes_to_str(tvb, offset, 20 );
    SET_ADDRESS( &addr, AT_IPv4, 4, tvb_get_ptr( tvb, offset, 4) );
    port = tvb_get_letohl( tvb, offset+24 );

    node_ti = proto_tree_add_none_format( sub_tree, hf_bt_dht_node, tvb, offset, 26,
        "%d\t%s %s:%u", node_index, id, ep_address_to_str( &addr ), port );
    node_tree = proto_item_add_subtree( node_ti, ett_bt_dht_peers);

    proto_tree_add_item( node_tree, hf_bt_dht_id, tvb, offset, 20, ENC_NA);
    proto_tree_add_item( node_tree, hf_ip, tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item( node_tree, hf_port, tvb, offset+24, 2, ENC_BIG_ENDIAN);
  }
  if( string_len>0 )
  {
    proto_tree_add_item( tree, hf_truncated_data, tvb, offset, string_len, ENC_NA );
    offset += string_len;
  }
  proto_item_set_text( ti, "%s: %d nodes", label, node_index );
  col_append_fstr( pinfo->cinfo, COL_INFO, "reply=%d nodes  ", node_index );
  *result = ep_strdup_printf("%d", node_index);

  return offset;
}
Example #10
0
/* Neighbor list is of the form:
 *      HID_1 NUM_1 HA_11 HA_12 ... HA_1NUM_1
 *      HID_2 NUM_2 HA_21 HA_22 ... HA_2NUM_2
 *      ...
 *      HID_count NUM_count HA_count1 HA_count2 ... HA_countNUM_count
 *
 *      count == hid_count.
 */
static void
dissect_nwp_nl(tvbuff_t *tvb, proto_tree *nwp_tree, guint8 hid_count,
	guint8 ha_len)
{
	proto_tree *neigh_list_tree = NULL;
	proto_tree *neigh_tree = NULL;
	proto_item *pi = NULL;

	guint i;
	guint8 offset = NWPH_NLST;

	wmem_strbuf_t *hid_buf = wmem_strbuf_sized_new(wmem_packet_scope(),
		NWP_HID_STR_LEN, NWP_HID_STR_LEN);

	/* Set up tree for neighbor list. */
	pi = proto_tree_add_item(nwp_tree, hf_nwp_neigh_list,
		tvb, NWPH_NLST, -1, ENC_NA);
	neigh_list_tree = proto_item_add_subtree(pi, ett_nwp_neigh_list_tree);

	for (i = 0; i < hid_count; i++) {
		const gchar *hid_str;
		guint j;
		guint8 ha_count = tvb_get_guint8(tvb, offset + NWP_XID_LEN);

		/* Set up tree for this individual neighbor. */
		pi = proto_tree_add_none_format(neigh_list_tree, hf_nwp_neigh,
			tvb, offset, NWP_XID_LEN + 1 + ha_len * ha_count,
			"Neighbor %d", i + 1);
		neigh_tree = proto_item_add_subtree(pi, ett_nwp_neigh_tree);

		/* Add HID for this neighbor. */
		wmem_strbuf_append(hid_buf, "hid-");
		add_hid_to_strbuf(tvb, hid_buf, offset);
		hid_str = wmem_strbuf_get_str(hid_buf);
		proto_tree_add_string(neigh_tree, hf_nwp_neigh_hid, tvb,
			offset, NWP_XID_LEN, hid_str);
		wmem_strbuf_truncate(hid_buf, 0);
		offset += NWP_XID_LEN;

		/* Add number of devices this neighbor has. */
		proto_tree_add_item(neigh_tree, hf_nwp_neigh_num, tvb,
			offset, 1, ENC_BIG_ENDIAN);
		offset++;

		/* Add hardware addresses for the neighbor's devices. */
		for (j = 0; j < ha_count; j++)
			proto_tree_add_item(neigh_tree, hf_nwp_neigh_haddr,
				tvb, offset + (j * ha_len), ha_len, ENC_NA);

		offset += ha_len * ha_count;
	}
}
Example #11
0
/* dissect one DCP block */
static int
dissect_PNDCP_Block(tvbuff_t *tvb, int offset, packet_info *pinfo,
                    proto_tree *tree, proto_item *dcp_item,
                    guint8 service_id, gboolean is_response)
{
    guint8      option;
    proto_item *block_item;
    proto_tree *block_tree;
    int         ori_offset = offset;

    /* subtree for block */
    block_item = proto_tree_add_none_format(tree, hf_pn_dcp_block,
        tvb, offset, 0, "Block: ");
    block_tree = proto_item_add_subtree(block_item, ett_pn_dcp_block);


    offset = dissect_pn_uint8(tvb, offset, pinfo, block_tree, hf_pn_dcp_option, &option);

    switch (option) {
    case PNDCP_OPTION_IP:
        offset = dissect_PNDCP_Suboption_IP(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
        break;
    case PNDCP_OPTION_DEVICE:
        offset = dissect_PNDCP_Suboption_Device(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
        break;
    case PNDCP_OPTION_DHCP:
        offset = dissect_PNDCP_Suboption_DHCP(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
        break;
    case PNDCP_OPTION_CONTROL:
        offset = dissect_PNDCP_Suboption_Control(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
        break;
    case PNDCP_OPTION_DEVICEINITIATIVE:
        offset = dissect_PNDCP_Suboption_DeviceInitiative(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
        break;
    case PNDCP_OPTION_ALLSELECTOR:
        offset = dissect_PNDCP_Suboption_All(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
        break;
    case PNDCP_OPTION_MANUF_X80:
    case PNDCP_OPTION_MANUF_X81:
    default:
        offset = dissect_PNDCP_Suboption_Manuf(tvb, offset, pinfo, block_tree, block_item, dcp_item, service_id, is_response);
    }

    proto_item_set_len(block_item, offset-ori_offset);

    if ((offset-ori_offset) & 1) {
        /* we have an odd number of bytes in this block, add a padding byte */
        offset = dissect_pn_padding(tvb, offset, pinfo, tree, 1);
    }

    return offset;
}
Example #12
0
static void
dissect_asf_payload_integrity(tvbuff_t *tvb, proto_tree *tree,
	gint offset, gint len)
{
	guint8      alg;
	proto_item *ti;
	proto_tree *atree;

	alg = tvb_get_guint8(tvb, offset);
	ti = proto_tree_add_none_format(tree, hf_asf_payload_data, tvb, offset,
		len, "Integrity Algorithm: %s",
		val_to_str(alg, asf_integrity_type_vals, "Unknown (%u)"));
	atree = proto_item_add_subtree(ti, ett_asf_alg_payload);
	proto_tree_add_item(atree, hf_asf_integrity_alg, tvb, offset, 1,ENC_BIG_ENDIAN);
	proto_tree_add_item(atree, hf_asf_reserved, tvb, offset + 1, len - 1,ENC_NA);
}
static void add_int_coordinates( proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, guint32 offset, guint32 xoffset, guint x_size, guint32 yoffset, guint y_size, guint32 zoffset, guint z_size)
{
    proto_item *ti;
    proto_tree * coord_tree;
    gint32 x,y,z;

    x = tvb_get_ntohint(tvb, offset+xoffset, x_size);
    y = tvb_get_ntohint(tvb, offset+yoffset, y_size);
    z = tvb_get_ntohint(tvb, offset+zoffset, z_size);

    ti = proto_tree_add_none_format(tree, hf_mc_int_coords, tvb, offset + xoffset, x_size + y_size + z_size, 
				    "Coordinates: %d, %d, %d", (gint32)tvb_get_ntohl(tvb, offset+xoffset), y, (gint32)tvb_get_ntohl(tvb, offset+zoffset));
    coord_tree = proto_item_add_subtree(ti, ett_mc_int_coords);

    proto_tree_add_item_varint(coord_tree, hf_mc_xbyte, hf_mc_xint, tvb, offset+xoffset, 4);
    proto_tree_add_item_varint(coord_tree, hf_mc_ybyte, hf_mc_yint, tvb, offset+yoffset, 4);
    proto_tree_add_item_varint(coord_tree, hf_mc_zbyte, hf_mc_zint, tvb, offset+zoffset, 4);
}
Example #14
0
static void
dissect_asf_payloads(tvbuff_t *tvb, proto_tree *tree,
	gint offset, gint len)
{
	guint8      ptype;
	guint16     plen;
	proto_item *ti;
	proto_tree *ptree;

	while ( len >= 4 )
	{
		ptype = tvb_get_guint8(tvb, offset);
		plen = tvb_get_ntohs(tvb, offset + 2);

		ti = proto_tree_add_none_format(tree, hf_asf_payload, tvb, offset,
			plen, "%s: %u bytes",
			val_to_str(ptype, asf_payload_type_vals, "Unknown (%u)"), plen);
		ptree = proto_item_add_subtree(ti, ett_asf_payload);
		proto_tree_add_item(ptree, hf_asf_payload_type, tvb, offset, 1,ENC_BIG_ENDIAN);
		proto_tree_add_item(ptree, hf_asf_payload_len, tvb, offset + 2, 2,ENC_BIG_ENDIAN);
		if ( ptype && (plen > 4) )
		{
			switch ( ptype )
			{
				case ASF_PAYLOAD_TYPE_AUTHENTICATION:
					dissect_asf_payload_authentication(tvb, ptree,
						offset + 4, plen - 4);
					break;
				case ASF_PAYLOAD_TYPE_INTEGRITY:
					dissect_asf_payload_integrity(tvb, ptree,
						offset + 4, plen - 4);
					break;
				default:
					proto_tree_add_item(ptree, hf_asf_payload_data, tvb,
						offset + 4, plen - 4,ENC_NA);
					break;
			}
		}
		offset += plen;
		len    -= plen;
	}
}
/* dissect a bencoded list from tvb, start at offset. it's like "lXXXe", "X" is any bencoded thing */
static int
dissect_bencoded_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset, char *label  )
{
  proto_item *ti;
  proto_tree *sub_tree;
  guint       one_byte;
  char       *result;

  ti = proto_tree_add_none_format( tree, hf_bencoded_list, tvb, offset, 0, "%s: list...", label );
  sub_tree = proto_item_add_subtree( ti, ett_bencoded_list);

  /* skip the 'l' */
  offset += 1;

  while( (one_byte=tvb_get_guint8(tvb,offset)) != 'e' )
  {
    switch( one_byte )
    {
    /* a integer */
    case 'i':
      offset = dissect_bencoded_int( tvb, pinfo, sub_tree, offset, &result, "Integer" );
      break;
    /* a sub-list */
    case 'l':
      offset = dissect_bencoded_list( tvb, pinfo, sub_tree, offset, "Sub-list" );
      break;
    /* a dictionary */
    case 'd':
      offset = dissect_bencoded_dict( tvb, pinfo, sub_tree, offset, "Sub-dict" );
      break;
    /* a string */
    default:
      offset = dissect_bencoded_string( tvb, pinfo, sub_tree, offset, &result, FALSE, "String" );
      break;
    }
  }
  offset += 1;
  return offset;
}
Example #16
0
/* Set System Boot Options
 */
static void
rq08(tvbuff_t *tvb, proto_tree *tree)
{
	proto_item *ti;
	proto_tree *s_tree;
	tvbuff_t *sub;
	guint8 pno;
	const char *desc;

	pno = tvb_get_guint8(tvb, 0) & 0x7f;
	if (pno < array_length(boot_options)) {
		desc = boot_options[pno].name;
	} else if (pno >= 96 && pno <= 127) {
		desc = "OEM";
	} else {
		desc = "Reserved";
	}

	ti = proto_tree_add_text(tree, tvb, 0, 1,
			"Boot option parameter selector: %s (0x%02x)",
			desc, pno);
	s_tree = proto_item_add_subtree(ti, ett_ipmi_chs_08_byte1);
	proto_tree_add_item(s_tree, hf_ipmi_chs_08_valid, tvb, 0, 1, TRUE);
	proto_tree_add_uint_format(s_tree, hf_ipmi_chs_08_selector, tvb, 0, 1,
			pno, "%sBoot option parameter selector: %s (0x%02x)",
			ipmi_dcd8(pno, 0x7f), desc, pno);

	/* Data is optional; no data means 'just set validity' */
	if (tvb_length(tvb) > 1) {
		if (pno < array_length(boot_options)) {
			sub = tvb_new_subset(tvb, 1, tvb_length(tvb) - 1, tvb_length(tvb) - 1);
			boot_options[pno].intrp(sub, tree);
		} else {
			proto_tree_add_none_format(tree, hf_ipmi_chs_08_data, tvb, 1,
					tvb_length(tvb) - 1, "Parameter data: %s", desc);
		}
	}
}
Example #17
0
/* Dissect OSC message */
static int
dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len)
{
    proto_tree *message_tree = NULL;
    proto_tree *header_tree = NULL;
    gint slen;
    gint rem;
    gint end = offset + len;
    const gchar *path = NULL;
    gint path_len;
    gint path_offset;
    const gchar *format = NULL;
    gint format_offset;
    gint format_len;
    const gchar *ptr = NULL;

    /* peek/read path */
    path_offset = offset;
    path = tvb_get_const_stringz(tvb, path_offset, &path_len);
    if( (rem = path_len%4) ) path_len += 4-rem;

    if(!is_valid_path(path))
        return -1;

    /* peek/read fmt */
    format_offset = path_offset + path_len;
    format = tvb_get_const_stringz(tvb, format_offset, &format_len);
    if( (rem = format_len%4) ) format_len += 4-rem;

    if(!is_valid_format(format))
        return -1;

    /* create message */
    ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format);
    message_tree = proto_item_add_subtree(ti, ett_osc_message);

    /* append header */
    ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA);
    header_tree = proto_item_add_subtree(ti, ett_osc_message_header);

    /* append path */
    proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA);

    /* append format */
    proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA);

    offset += path_len + format_len;

    /* ::parse argument:: */
    ptr = format + 1; /* skip ',' */
    while( (*ptr != '\0') && (offset < end) )
    {
        switch(*ptr)
        {
            case OSC_INT32:
                proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_FLOAT:
                proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_STRING:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_BLOB:
            {
                proto_item *bi = NULL;
                proto_tree *blob_tree = NULL;

                gint32 blen = tvb_get_ntohl(tvb, offset);
                slen = blen;
                if( (rem = slen%4) ) slen += 4-rem;

                bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen);
                blob_tree = proto_item_add_subtree(bi, ett_osc_blob);

                proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen);
                offset += 4;

                /* check for zero length blob */
                if(blen == 0)
                    break;

                proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA);
                offset += slen;
                break;
            }

            case OSC_TRUE:
                proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_FALSE:
                proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_NIL:
                proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_BANG:
                proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA);
                break;

            case OSC_INT64:
                proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_DOUBLE:
                proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_TIMETAG:
            {
                guint32 sec = tvb_get_ntohl(tvb, offset);
                guint32 frac = tvb_get_ntohl(tvb, offset+4);
                nstime_t ns;
                if( (sec == 0UL) && (frac == 1UL) )
                    proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str);
                else
                    proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN);
                offset += 8;
            }
                break;

            case OSC_SYMBOL:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_CHAR:
                offset += 3;
                proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA);
                offset += 1;
                break;
            case OSC_RGBA:
            {
                proto_item *ri = NULL;
                proto_tree *rgba_tree = NULL;

                ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba);

                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                break;
            }
            case OSC_MIDI:
            {
                const gchar *status_str = NULL;
                const gchar *control_str = NULL;
                proto_item *mi = NULL;
                proto_tree *midi_tree = NULL;
                guint8 channel;
                guint8 status;
                guint8 data1;
                guint8 data2;

                channel = tvb_get_guint8(tvb, offset);
                status = tvb_get_guint8(tvb, offset+1);
                data1 = tvb_get_guint8(tvb, offset+2);
                data2 = tvb_get_guint8(tvb, offset+3);

                status_str = val_to_str_const(status, MIDI_status, "Unknown");

                if(status == MIDI_STATUS_CONTROLLER) /* MIDI Controller */
                {
                    control_str = val_to_str_const(data1, MIDI_control, "Unknown");

                    mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                            "MIDI: Channel %2i, %s (0x%02x), %s (0x%02x), 0x%02x",
                            channel,
                            status_str, status,
                            control_str, data1,
                            data2);
                }
                else
                    mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                            "MIDI: Channel %2i, %s (0x%02x), 0x%02x, 0x%02x",
                            channel,
                            status_str, status,
                            data1, data2);
                midi_tree = proto_item_add_subtree(mi, ett_osc_midi);

                proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                if(status == MIDI_STATUS_CONTROLLER)
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_value_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                }
                else
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                }

                break;
            }

            default:
                /* if we get here, there must be a bug in the dissector  */
                DISSECTOR_ASSERT_NOT_REACHED();
                break;
        }
        ptr++;
    }

    if(offset != end)
        return -1;
    else
        return 0;
}
Example #18
0
static void
dissect_llrp_parameters(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        guint offset)
{
    guint8 has_length;
    guint16 len, type;
    guint real_len;
    proto_item *ti;
    proto_tree *param_tree;

    while (tvb_reported_length_remaining(tvb, offset) > 0)
    {
        has_length = !(tvb_get_guint8(tvb, offset) & 0x80);

        if (has_length)
        {
            len = tvb_get_ntohs(tvb, offset + 2);

            if (len < LLRP_TLV_LEN_MIN)
                real_len = LLRP_TLV_LEN_MIN;
            else if (len > tvb_reported_length_remaining(tvb, offset))
                real_len = tvb_reported_length_remaining(tvb, offset);
            else
                real_len = len;

            ti = proto_tree_add_none_format(tree, hf_llrp_param, tvb,
                    offset, real_len, "TLV Parameter");
            param_tree = proto_item_add_subtree(ti, ett_llrp_param);

            proto_tree_add_item(param_tree, hf_llrp_tlv_type, tvb,
                    offset, 2, ENC_BIG_ENDIAN);
            offset += 2;

            ti = proto_tree_add_item(param_tree, hf_llrp_tlv_len, tvb,
                    offset, 2, ENC_BIG_ENDIAN);
            if (len != real_len)
                expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
                        "Invalid length field: claimed %u, should be %u.",
                        len, real_len);
            offset += 2;

            /* TODO: Decode actual TLV parameter fields */

            /* The len field includes the 4-byte parameter header that we've
             * already accounted for in offset */
            offset += real_len - 4;
        }
        else
        {
            type = tvb_get_guint8(tvb, offset) & 0x7F;

            /* TODO: Decode actual TV fields rather than just jumping
             * ahead the correct length */
            switch (type)
            {
                case LLRP_TV_ANTENNA_ID:
                    real_len = LLRP_TV_LEN_ANTENNA_ID; break;
                case LLRP_TV_FIRST_SEEN_TIME_UTC:
                    real_len = LLRP_TV_LEN_FIRST_SEEN_TIME_UTC; break;
                case LLRP_TV_FIRST_SEEN_TIME_UPTIME:
                    real_len = LLRP_TV_LEN_FIRST_SEEN_TIME_UPTIME; break;
                case LLRP_TV_LAST_SEEN_TIME_UTC:
                    real_len = LLRP_TV_LEN_LAST_SEEN_TIME_UTC; break;
                case LLRP_TV_LAST_SEEN_TIME_UPTIME:
                    real_len = LLRP_TV_LEN_LAST_SEEN_TIME_UPTIME; break;
                case LLRP_TV_PEAK_RSSI:
                    real_len = LLRP_TV_LEN_PEAK_RSSI; break;
                case LLRP_TV_CHANNEL_INDEX:
                    real_len = LLRP_TV_LEN_CHANNEL_INDEX; break;
                case LLRP_TV_TAG_SEEN_COUNT:
                    real_len = LLRP_TV_LEN_TAG_SEEN_COUNT; break;
                case LLRP_TV_RO_SPEC_ID:
                    real_len = LLRP_TV_LEN_RO_SPEC_ID; break;
                case LLRP_TV_INVENTORY_PARAM_SPEC_ID:
                    real_len = LLRP_TV_LEN_INVENTORY_PARAM_SPEC_ID; break;
                case LLRP_TV_C1G2_CRC:
                    real_len = LLRP_TV_LEN_C1G2_CRC; break;
                case LLRP_TV_C1G2_PC:
                    real_len = LLRP_TV_LEN_C1G2_PC; break;
                case LLRP_TV_EPC96:
                    real_len = LLRP_TV_LEN_EPC96; break;
                case LLRP_TV_SPEC_INDEX:
                    real_len = LLRP_TV_LEN_SPEC_INDEX; break;
                case LLRP_TV_CLIENT_REQ_OP_SPEC_RES:
                    real_len = LLRP_TV_LEN_CLIENT_REQ_OP_SPEC_RES; break;
                case LLRP_TV_ACCESS_SPEC_ID:
                    real_len = LLRP_TV_LEN_ACCESS_SPEC_ID; break;
                case LLRP_TV_OP_SPEC_ID:
                    real_len = LLRP_TV_LEN_OP_SPEC_ID; break;
                case LLRP_TV_C1G2_SINGULATION_DET:
                    real_len = LLRP_TV_LEN_C1G2_SINGULATION_DET; break;
                case LLRP_TV_C1G2_XPC_W1:
                    real_len = LLRP_TV_LEN_C1G2_XPC_W1; break;
                case LLRP_TV_C1G2_XPC_W2:
                    real_len = LLRP_TV_LEN_C1G2_XPC_W2; break;
                default:
                    /* ???
                     * No need to mark it, since the hf_llrp_tv_type field
                     * will already show up as 'unknown'. */
                    real_len = 0;
                    break;
            };

            ti = proto_tree_add_none_format(tree, hf_llrp_param, tvb,
                    offset, real_len + 1, "TV Parameter");
            param_tree = proto_item_add_subtree(ti, ett_llrp_param);

            proto_tree_add_item(param_tree, hf_llrp_tv_type, tvb,
                    offset, 1, ENC_NA);
            offset++;

            /* Unlike for TLV's, real_len for TV's doesn't include the standard
             * header length, so just add it straight to the offset. */
            offset += real_len;
        }
    }
}
Example #19
0
/* Process an APP0 block.
 *
 * XXX - This code only works on US-ASCII systems!!!
 */
static int
process_app0_segment(proto_tree *tree, tvbuff_t *tvb, guint32 len,
        guint16 marker, const char *marker_name)
{
    proto_item *ti;
    proto_tree *subtree;
    proto_tree *subtree_details = NULL;
    guint32 offset;
    char *str;
    gint str_size;
    guint16 x, y;

    if (!tree)
        return 0;

    ti = proto_tree_add_item(tree, hf_marker_segment,
            tvb, 0, -1, ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_marker_segment);

    proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker);
    proto_tree_add_item(subtree, hf_marker, tvb, 0, 2, ENC_BIG_ENDIAN);

    proto_tree_add_item(subtree, hf_len, tvb, 2, 2, ENC_BIG_ENDIAN);

    str = tvb_get_stringz_enc(wmem_packet_scope(), tvb, 4, &str_size, ENC_ASCII);
    ti = proto_tree_add_item(subtree, hf_identifier, tvb, 4, str_size, ENC_ASCII|ENC_NA);
    if (strcmp(str, "JFIF") == 0) {
        /* Version */
        ti = proto_tree_add_none_format(subtree, hf_version,
                tvb, 9, 2, "Version: %u.%u",
                tvb_get_guint8(tvb, 9),
                tvb_get_guint8(tvb, 10));
        subtree_details = proto_item_add_subtree(ti, ett_details);
        proto_tree_add_item(subtree_details, hf_version_major,
                tvb, 9, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree_details, hf_version_minor,
                tvb, 10, 1, ENC_BIG_ENDIAN);

        proto_tree_add_item(subtree, hf_units,
                tvb, 11, 1, ENC_BIG_ENDIAN);

        /* Aspect ratio */
        proto_tree_add_item(subtree, hf_xdensity,
                tvb, 12, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree, hf_ydensity,
                tvb, 14, 2, ENC_BIG_ENDIAN);

        /* Thumbnail */
        proto_tree_add_item(subtree, hf_xthumbnail,
                tvb, 16, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree, hf_ythumbnail,
                tvb, 17, 1, ENC_BIG_ENDIAN);
        x = tvb_get_guint8(tvb, 16);
        y = tvb_get_guint8(tvb, 17);
        if (x || y) {
            proto_tree_add_item(subtree, hf_rgb,
                    tvb, 18, 3 * (x * y), ENC_NA);
            offset = 18 + (3 * (x * y));
        } else {
            offset = 18;
        }
    }
    else if (strcmp(str, "JFXX") == 0) {
        proto_tree_add_item(subtree, hf_extension_code,
                tvb, 9, 1, ENC_BIG_ENDIAN);
        /* XXX - dissect the extension based on its extension code */
        offset = 10;
    }
    else { /* Unknown */
        proto_item_append_text(ti, " (unknown identifier)");
        offset = 4 + str_size;

        proto_tree_add_bytes_format_value(subtree, hf_remain_seg_data, tvb, offset, -1, NULL, "%u bytes", len - 2 - str_size);
    }
    return offset;
}
Example #20
0
/* Check to see if this mac & ip pair represent 2 devices trying to share
   the same IP address - report if found (+ return TRUE and set out param) */
static gboolean check_for_duplicate_addresses(packet_info *pinfo, proto_tree *tree,
                                              tvbuff_t *tvb,
                                              const guint8 *mac, guint32 ip,
                                              guint32 *duplicate_ip)
{
  struct   address_hash_value *value;
  gboolean return_value = FALSE;

  /* Look up any existing entries */
  value = g_hash_table_lookup(address_hash_table, GUINT_TO_POINTER(ip));

  /* If MAC matches table, just update details */
  if (value != NULL)
  {
    if (pinfo->fd->num > value->frame_num)
    {
      if ((memcmp(value->mac, mac, 6) == 0))
      {
        /* Same MAC as before - update existing entry */
        value->frame_num = pinfo->fd->num;
        value->time_of_entry = pinfo->fd->abs_ts.secs;
      }
      else
      {
        /* Doesn't match earlier MAC - report! */
        proto_tree *duplicate_tree;

        /* Create subtree */
        proto_item *ti = proto_tree_add_none_format(tree, hf_arp_duplicate_ip_address,
                                                    tvb, 0, 0,
                                                    "Duplicate IP address detected for %s (%s) - also in use by %s (frame %u)",
                                                    arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP),
                                                    ether_to_str(mac),
                                                    ether_to_str(value->mac),
                                                    value->frame_num);
        PROTO_ITEM_SET_GENERATED(ti);
        duplicate_tree = proto_item_add_subtree(ti, ett_arp_duplicate_address);

        /* Add item for navigating to earlier frame */
        ti = proto_tree_add_uint(duplicate_tree, hf_arp_duplicate_ip_address_earlier_frame,
                                 tvb, 0, 0, value->frame_num);
        PROTO_ITEM_SET_GENERATED(ti);
        expert_add_info_format(pinfo, ti,
                               PI_SEQUENCE, PI_WARN,
                               "Duplicate IP address configured (%s)",
                               arpproaddr_to_str((guint8*)&ip, 4, ETHERTYPE_IP));

        /* Time since that frame was seen */
        ti = proto_tree_add_uint(duplicate_tree,
                                 hf_arp_duplicate_ip_address_seconds_since_earlier_frame,
                                 tvb, 0, 0,
                                 (guint32)(pinfo->fd->abs_ts.secs - value->time_of_entry));
        PROTO_ITEM_SET_GENERATED(ti);

        *duplicate_ip = ip;
        return_value = TRUE;
      }
    }
  }
  else
  {
    /* No existing entry. Prepare one */
    value = se_alloc(sizeof(struct address_hash_value));
    memcpy(value->mac, mac, 6);
    value->frame_num = pinfo->fd->num;
    value->time_of_entry = pinfo->fd->abs_ts.secs;

    /* Add it */
    g_hash_table_insert(address_hash_table, GUINT_TO_POINTER(ip), value);
  }

  return return_value;
}
/* Process an APP0 block.
 *
 * XXX - This code only works on US-ASCII systems!!!
 */
static int
process_app0_segment(proto_tree *tree, tvbuff_t *tvb, guint32 len,
        guint16 marker, const char *marker_name)
{
    proto_item *ti = NULL;
    proto_tree *subtree = NULL;
    proto_tree *subtree_details = NULL;
    guint32 offset;
    char *str;
    gint str_size;

    if (!tree)
        return 0 ;

    ti = proto_tree_add_item(tree, hf_marker_segment,
            tvb, 0, -1, ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_marker_segment);

    proto_item_append_text(ti, ": %s (0x%04X)", marker_name, marker);
    proto_tree_add_item(subtree, hf_marker, tvb, 0, 2, ENC_BIG_ENDIAN);

    proto_tree_add_item(subtree, hf_len, tvb, 2, 2, ENC_BIG_ENDIAN);

    str = tvb_get_ephemeral_stringz(tvb, 4, &str_size);
    ti = proto_tree_add_item(subtree, hf_identifier, tvb, 4, str_size, ENC_ASCII|ENC_NA);
    if (strcmp(str, "JFIF") == 0) {
        /* Version */
        ti = proto_tree_add_none_format(subtree, hf_version,
                tvb, 9, 2, "Version: %u.%u",
                tvb_get_guint8(tvb, 9),
                tvb_get_guint8(tvb, 10));
        subtree_details = proto_item_add_subtree(ti, ett_details);
        proto_tree_add_item(subtree_details, hf_version_major,
                tvb, 9, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree_details, hf_version_minor,
                tvb, 10, 1, ENC_BIG_ENDIAN);

        proto_tree_add_item(subtree, hf_units,
                tvb, 11, 1, ENC_BIG_ENDIAN);

        /* Aspect ratio */
        proto_tree_add_item(subtree, hf_xdensity,
                tvb, 12, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree, hf_ydensity,
                tvb, 14, 2, ENC_BIG_ENDIAN);

        /* Thumbnail */
        proto_tree_add_item(subtree, hf_xthumbnail,
                tvb, 16, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(subtree, hf_ythumbnail,
                tvb, 17, 1, ENC_BIG_ENDIAN);
        {
            guint16 x = tvb_get_guint8(tvb, 16);
            guint16 y = tvb_get_guint8(tvb, 17);
            if (x || y) {
                proto_tree_add_item(subtree, hf_rgb,
                        tvb, 18, 3 * (x * y), ENC_NA);
                offset = 18 + (3 * (x * y));
            } else {
                offset = 18;
            }
        }
    } else if (strcmp(str, "JFXX") == 0) {
        proto_tree_add_item(subtree, hf_extension_code,
                tvb, 9, 1, ENC_BIG_ENDIAN);
        {
            guint8 code = tvb_get_guint8(tvb, 9);
            switch (code) {
                case 0x10: /* Thumbnail coded using JPEG */
                    break;
                case 0x11: /* thumbnail stored using 1 byte per pixel */
                    break;
                case 0x13: /* thumbnail stored using 3 bytes per pixel */
                    break;
                default: /* Error */
                    break;
            }
        }
        offset = 10;
    } else { /* Unknown */
        proto_item_append_text(ti, " (unknown identifier)");
        offset = 4 + str_size;

        proto_tree_add_text(subtree, tvb, offset, -1,
                "Remaining segment data (%u bytes)", len - 2 - str_size);
    }
    return offset;
}
Example #22
0
static void
expert_set_info_vformat(packet_info *pinfo, proto_item *pi, int group, int severity, int hf_index, gboolean use_vaformat,
			const char *format, va_list ap)
{
	char           formatted[ITEM_LABEL_LENGTH];
	int            tap;
	expert_info_t *ei;
	proto_tree    *tree;
	proto_item    *ti;

	if (pinfo == NULL && pi && pi->tree_data) {
		pinfo = PTREE_DATA(pi)->pinfo;
	}

	/* if this packet isn't loaded because of a read filter, don't output anything */
	if (pinfo == NULL || pinfo->num == 0) {
		return;
	}

	if (severity > highest_severity) {
		highest_severity = severity;
	}

	/* XXX: can we get rid of these checks and make them programming errors instead now? */
	if (pi != NULL && PITEM_FINFO(pi) != NULL) {
		expert_set_item_flags(pi, group, severity);
	}

	if ((pi == NULL) || (PITEM_FINFO(pi) == NULL) ||
		((guint)severity >= FI_GET_FLAG(PITEM_FINFO(pi), PI_SEVERITY_MASK))) {
		col_add_str(pinfo->cinfo, COL_EXPERT, val_to_str(severity, expert_severity_vals, "Unknown (%u)"));
	}

	if (use_vaformat) {
		g_vsnprintf(formatted, ITEM_LABEL_LENGTH, format, ap);
	} else {
		g_strlcpy(formatted, format, ITEM_LABEL_LENGTH);
	}

	tree = expert_create_tree(pi, group, severity, formatted);

	if (hf_index == -1) {
		/* If no filterable expert info, just add the message */
		ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted);
		PROTO_ITEM_SET_GENERATED(ti);
	} else {
		/* If filterable expert info, hide the "generic" form of the message,
		   and generate the formatted filterable expert info */
		ti = proto_tree_add_none_format(tree, hf_index, NULL, 0, 0, "%s", formatted);
		PROTO_ITEM_SET_GENERATED(ti);
		ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted);
		PROTO_ITEM_SET_HIDDEN(ti);
	}

	ti = proto_tree_add_uint_format_value(tree, hf_expert_severity, NULL, 0, 0, severity,
					      "%s", val_to_str_const(severity, expert_severity_vals, "Unknown"));
	PROTO_ITEM_SET_GENERATED(ti);
	ti = proto_tree_add_uint_format_value(tree, hf_expert_group, NULL, 0, 0, group,
					      "%s", val_to_str_const(group, expert_group_vals, "Unknown"));
	PROTO_ITEM_SET_GENERATED(ti);

	tap = have_tap_listener(expert_tap);

	if (!tap)
		return;

	ei = wmem_new(wmem_packet_scope(), expert_info_t);

	ei->packet_num  = pinfo->num;
	ei->group       = group;
	ei->severity    = severity;
	ei->hf_index    = hf_index;
	ei->protocol    = pinfo->current_proto;
	ei->summary     = wmem_strdup(wmem_packet_scope(), formatted);

	/* if we have a proto_item (not a faked item), set expert attributes to it */
	if (pi != NULL && PITEM_FINFO(pi) != NULL) {
		ei->pitem = pi;
	}
	/* XXX: remove this because we don't have an internal-only function now? */
	else {
		ei->pitem = NULL;
	}

	tap_queue_packet(expert_tap, pinfo, ei);
}
Example #23
0
/* Dissect OSC message */
static int
dissect_osc_message(tvbuff_t *tvb, proto_item *ti, proto_tree *osc_tree, gint offset, gint len)
{
    proto_tree  *message_tree;
    proto_tree  *header_tree;
    gint         slen;
    gint         rem;
    gint         end = offset + len;
    const gchar *path;
    gint         path_len;
    gint         path_offset;
    const gchar *format;
    gint         format_offset;
    gint         format_len;
    const gchar *ptr;

    /* peek/read path */
    path_offset = offset;
    path = tvb_get_const_stringz(tvb, path_offset, &path_len);
    if( (rem = path_len%4) ) path_len += 4-rem;

    if(!is_valid_path(path))
        return -1;

    /* peek/read fmt */
    format_offset = path_offset + path_len;
    format = tvb_get_const_stringz(tvb, format_offset, &format_len);
    if( (rem = format_len%4) ) format_len += 4-rem;

    if(!is_valid_format(format))
        return -1;

    /* create message */
    ti = proto_tree_add_none_format(osc_tree, hf_osc_message_type, tvb, offset, len, "Message: %s %s", path, format);
    message_tree = proto_item_add_subtree(ti, ett_osc_message);

    /* append header */
    ti = proto_tree_add_item(message_tree, hf_osc_message_header_type, tvb, offset, path_len+format_len, ENC_NA);
    header_tree = proto_item_add_subtree(ti, ett_osc_message_header);

    /* append path */
    proto_tree_add_item(header_tree, hf_osc_message_path_type, tvb, path_offset, path_len, ENC_ASCII | ENC_NA);

    /* append format */
    proto_tree_add_item(header_tree, hf_osc_message_format_type, tvb, format_offset, format_len, ENC_ASCII | ENC_NA);

    offset += path_len + format_len;

    /* ::parse argument:: */
    ptr = format + 1; /* skip ',' */
    while( (*ptr != '\0') && (offset < end) )
    {
        switch(*ptr)
        {
            case OSC_INT32:
                proto_tree_add_item(message_tree, hf_osc_message_int32_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_FLOAT:
                proto_tree_add_item(message_tree, hf_osc_message_float_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
            case OSC_STRING:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_string_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_BLOB:
            {
                proto_item *bi;
                proto_tree *blob_tree;

                gint32 blen = tvb_get_ntohl(tvb, offset);
                slen = blen;
                if( (rem = slen%4) ) slen += 4-rem;

                bi = proto_tree_add_none_format(message_tree, hf_osc_message_blob_type, tvb, offset, 4+slen, "Blob: %i bytes", blen);
                blob_tree = proto_item_add_subtree(bi, ett_osc_blob);

                proto_tree_add_int_format_value(blob_tree, hf_osc_message_blob_size_type, tvb, offset, 4, blen, "%i bytes", blen);
                offset += 4;

                /* check for zero length blob */
                if(blen == 0)
                    break;

                proto_tree_add_item(blob_tree, hf_osc_message_blob_data_type, tvb, offset, slen, ENC_NA);
                offset += slen;
                break;
            }

            case OSC_TRUE:
                proto_tree_add_item(message_tree, hf_osc_message_true_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_FALSE:
                proto_tree_add_item(message_tree, hf_osc_message_false_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_NIL:
                proto_tree_add_item(message_tree, hf_osc_message_nil_type, tvb, offset, 0, ENC_NA);
                break;
            case OSC_BANG:
                proto_tree_add_item(message_tree, hf_osc_message_bang_type, tvb, offset, 0, ENC_NA);
                break;

            case OSC_INT64:
                proto_tree_add_item(message_tree, hf_osc_message_int64_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_DOUBLE:
                proto_tree_add_item(message_tree, hf_osc_message_double_type, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
                break;
            case OSC_TIMETAG:
            {
                guint32  sec  = tvb_get_ntohl(tvb, offset);
                guint32  frac = tvb_get_ntohl(tvb, offset+4);
                nstime_t ns;
                if( (sec == 0) && (frac == 1) )
                    proto_tree_add_time_format_value(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, &ns, immediate_fmt, immediate_str);
                else
                    proto_tree_add_item(message_tree, hf_osc_message_timetag_type, tvb, offset, 8, ENC_TIME_NTP | ENC_BIG_ENDIAN);
                offset += 8;
            }
                break;

            case OSC_SYMBOL:
                slen = tvb_strsize(tvb, offset);
                if( (rem = slen%4) ) slen += 4-rem;
                proto_tree_add_item(message_tree, hf_osc_message_symbol_type, tvb, offset, slen, ENC_ASCII | ENC_NA);
                offset += slen;
                break;
            case OSC_CHAR:
                offset += 3;
                proto_tree_add_item(message_tree, hf_osc_message_char_type, tvb, offset, 1, ENC_ASCII | ENC_NA);
                offset += 1;
                break;
            case OSC_RGBA:
            {
                proto_item *ri;
                proto_tree *rgba_tree;

                ri = proto_tree_add_item(message_tree, hf_osc_message_rgba_type, tvb, offset, 4, ENC_BIG_ENDIAN);
                rgba_tree = proto_item_add_subtree(ri, ett_osc_rgba);

                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_red_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_green_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_blue_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                proto_tree_add_item(rgba_tree, hf_osc_message_rgba_alpha_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
                break;
            }
            case OSC_MIDI:
            {
                const gchar *status_str;
                proto_item  *mi = NULL;
                proto_tree  *midi_tree;
                guint8       port;
                guint8       command;
                guint8       data1;
                guint8       data2;
                guint8       status;
                guint8       channel;
                gboolean     system_msg;
                guint8       status_shifted;

                port = tvb_get_guint8(tvb, offset);
                command  = tvb_get_guint8(tvb, offset+1);
                data1   = tvb_get_guint8(tvb, offset+2);
                data2   = tvb_get_guint8(tvb, offset+3);

                status  = command & 0xF0;
                channel = command & 0x0F;

                system_msg = status == 0xF0; /* is system message */
                status_shifted = status >> 4;

                if(system_msg)
                    status_str = val_to_str_ext_const(command, &MIDI_system_ext, "Unknown");
                else
                    status_str = val_to_str_ext_const(status_shifted, &MIDI_status_ext, "Unknown");

                if(system_msg)
                {
                    mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                            "MIDI: Port %i, %s, %i, %i",
                            port, status_str, data1, data2);
                }
                else
                {
                    switch(status_shifted)
                    {
                        case MIDI_STATUS_NOTE_ON:
                        case MIDI_STATUS_NOTE_OFF:
                        case MIDI_STATUS_NOTE_PRESSURE:
                        {
                            const gchar *note_str;
                            note_str = val_to_str_ext_const(data1, &MIDI_note_ext, "Unknown");

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %s, %i",
                                    port, channel, status_str, note_str, data2);
                            break;
                        }
                        case MIDI_STATUS_CONTROLLER:
                        {
                            const gchar *control_str;
                            control_str = val_to_str_ext_const(data1, &MIDI_control_ext, "Unknown");

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %s, %i",
                                    port, channel, status_str, control_str, data2);
                            break;
                        }
                        case MIDI_STATUS_PITCH_BENDER:
                        {
                            const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000;

                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %i",
                                    port, channel, status_str, bender);
                            break;
                        }
                        default:
                        {
                            mi = proto_tree_add_none_format(message_tree, hf_osc_message_midi_type, tvb, offset, 4,
                                    "MIDI: Port %i, Channel %i, %s, %i, %i",
                                    port, channel, status_str, data1, data2);
                            break;
                        }
                    }
                }
                midi_tree = proto_item_add_subtree(mi, ett_osc_midi);

                proto_tree_add_item(midi_tree, hf_osc_message_midi_port_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;

                if(system_msg)
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_system_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;
                }
                else
                {
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_status_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    proto_tree_add_item(midi_tree, hf_osc_message_midi_channel_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                    offset += 1;

                    switch(status_shifted)
                    {
                        case MIDI_STATUS_NOTE_ON:
                        case MIDI_STATUS_NOTE_OFF:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_velocity_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_NOTE_PRESSURE:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_note_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_CONTROLLER:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_controller_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_CHANNEL_PRESSURE:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_pressure_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                        case MIDI_STATUS_PITCH_BENDER:
                        {
                            const gint bender = (((gint)data2 << 7) | (gint)data1) - 0x2000;

                            proto_tree_add_int(midi_tree, hf_osc_message_midi_bender_type, tvb, offset, 2, bender);
                            offset += 2;

                            break;
                        }
                        default:
                        {
                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data1_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            proto_tree_add_item(midi_tree, hf_osc_message_midi_data2_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                            offset += 1;

                            break;
                        }
                    }
                }

                break;
            }

            default:
                /* if we get here, there must be a bug in the dissector  */
                DISSECTOR_ASSERT_NOT_REACHED();
                break;
        }
        ptr++;
    }

    if(offset != end)
        return -1;
    else
        return 0;
}
bool dissect_protobuf_message(const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *tree, string& displayText, bool bRoot)
{
	map<string, Handles*>::iterator it = g_mapHandles.find( message->GetDescriptor()->full_name() );
    if( it == g_mapHandles.end() )
    {
        return false; // bug
    }
    
    int iMsgLen = message->ByteSize();
    // if not root field then submessage needs to be computed
    if( !bRoot )
    {
      *offset += WireFormat::TagSize( message->GetDescriptor()->index(), FieldDescriptor::TYPE_MESSAGE );
      *offset += io::CodedOutputStream::VarintSize32( iMsgLen );
    }
    
    Handles* handles = it->second;
    proto_item* item = proto_tree_add_none_format( tree, handles->p_id, tvb, *offset, iMsgLen, "%s",displayText.c_str() );
    proto_tree* subTree = proto_item_add_subtree( item, *(handles->indices) );
      
    const Reflection *reflection = message->GetReflection();
    // dissect field
    vector<const FieldDescriptor*> fieldList;
    reflection->ListFields(*message, &fieldList);
    for( vector<const FieldDescriptor*>::iterator itField = fieldList.begin(); itField!=fieldList.end(); itField++ )
    {
        const FieldDescriptor* field = *itField;
        bool bMessage = ( FieldDescriptor::CPPTYPE_MESSAGE == field->cpp_type() );
            
        if (field->is_repeated())
        {
            int iRepeatedSize = reflection->FieldSize( *message, field );
            for( int iRepeatedIndex = 0; iRepeatedIndex < iRepeatedSize; iRepeatedIndex++ )
            {
                if (bMessage)
                {
                    const Message& subMessage = reflection->GetRepeatedMessage( *message, field, iRepeatedIndex );
                    dissect_protobuf_message(&subMessage, tvb, offset, subTree, string(field->name()), false);
                }
                else
                {
                    dissect_protobuf_repeated_field(field, message, tvb, offset, subTree, iRepeatedIndex);
                }
            }
        }
        else
        {
            if (bMessage)
            {
                const Message& subMessage = reflection->GetMessage( *message, field );
                
                dissect_protobuf_message(&subMessage, tvb, offset, subTree, string(field->name()), false);
            }
            else
            {
                dissect_protobuf_field(field, message, tvb, offset, subTree);
            }
        }
        
    } // end for (int iFieldIndex = 0; iFieldIndex < message->field_count(); iFieldIndex++) 
        
    return true;
}
Example #25
0
static void dissect_alc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	/* Logical packet representation */
	struct _alc alc;

	/* Offset for subpacket dissection */
	guint offset;

	/* Set up structures needed to add the protocol subtree and manage it */
	proto_item *ti;
	proto_tree *alc_tree;

	/* Flute or not */
	tvbuff_t *new_tvb;
	gboolean is_flute = FALSE;

	/* Structures and variables initialization */
	offset = 0;
	memset(&alc, 0, sizeof(struct _alc));

	/* Update packet info */
	pinfo->current_proto = "ALC";

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

	/* ALC header dissection */
	/* --------------------- */

	alc.version = hi_nibble(tvb_get_guint8(tvb, offset));

	if (tree)
	{
		/* Create subtree for the ALC protocol */
		ti = proto_tree_add_item(tree, proto, tvb, offset, -1, ENC_NA);
		alc_tree = proto_item_add_subtree(ti, ett.main);

		/* Fill the ALC subtree */
		proto_tree_add_uint(alc_tree, hf.version, tvb, offset, 1, alc.version);

	} else
		alc_tree = NULL;

	/* This dissector supports only ALCv1 packets.
	 * If alc.version > 1 print only version field and quit.
	 */
	if (alc.version == 1) {

		struct _lct_ptr l;
		struct _fec_ptr f;

		l.lct = &alc.lct;
		l.hf = &hf.lct;
		l.ett = &ett.lct;
		l.prefs = &preferences.lct;

		f.fec = &alc.fec;
		f.hf = &hf.fec;
		f.ett = &ett.fec;
		f.prefs = &preferences.fec;

		/* LCT header dissection */
		/* --------------------- */

		is_flute = lct_dissector(l, f, tvb, alc_tree, &offset);

		/* FEC header dissection */
		/* --------------------- */

		/* Only if it's present and if LCT dissector has determined FEC Encoding ID
		 * FEC dissector should be called with fec->encoding_id* and fec->instance_id* filled
		 */
		if (alc.fec.encoding_id_present && tvb_length(tvb) > offset)
			fec_dissector(f, tvb, alc_tree, &offset);

		/* Add the Payload item */
		if (tvb_length(tvb) > offset){
			if(is_flute){
				new_tvb = tvb_new_subset_remaining(tvb,offset);
				call_dissector(xml_handle, new_tvb, pinfo, alc_tree);
			}else{
				proto_tree_add_none_format(alc_tree, hf.payload, tvb, offset, -1, "Payload (%u bytes)", tvb_length(tvb) - offset);
			}
		}

		/* Complete entry in Info column on summary display */
		/* ------------------------------------------------ */

		if (check_col(pinfo->cinfo, COL_INFO))
		{
			lct_info_column(&alc.lct, pinfo);
			fec_info_column(&alc.fec, pinfo);
		}

		/* Free g_allocated memory */
		lct_dissector_free(&alc.lct);
		fec_dissector_free(&alc.fec);

	} else {

		if (tree)
			proto_tree_add_text(alc_tree, tvb, 0, -1, "Sorry, this dissector supports ALC version 1 only");

		/* Complete entry in Info column on summary display */
		if (check_col(pinfo->cinfo, COL_INFO))
			col_add_fstr(pinfo->cinfo, COL_INFO, "Version: %u (not supported)", alc.version);
	}
}
Example #26
0
static void
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_item  *volatile ti = NULL, *comment_item;
	guint	     cap_len = 0, frame_len = 0;
	proto_tree  *volatile tree;
	proto_tree  *comments_tree;
	proto_item  *item;
	const gchar *cap_plurality, *frame_plurality;

	tree=parent_tree;

	pinfo->current_proto = "Frame";

	if (pinfo->pseudo_header != NULL) {
		switch (pinfo->fd->lnk_t) {

		case WTAP_ENCAP_WFLEET_HDLC:
		case WTAP_ENCAP_CHDLC_WITH_PHDR:
		case WTAP_ENCAP_PPP_WITH_PHDR:
		case WTAP_ENCAP_SDLC:
		case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_BLUETOOTH_HCI:
			pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent;
			break;

		case WTAP_ENCAP_LAPB:
		case WTAP_ENCAP_FRELAY_WITH_PHDR:
			pinfo->p2p_dir =
			    (pinfo->pseudo_header->x25.flags & FROM_DCE) ?
			    P2P_DIR_RECV : P2P_DIR_SENT;
			break;

		case WTAP_ENCAP_ISDN:
		case WTAP_ENCAP_V5_EF:
		case WTAP_ENCAP_DPNSS:
		case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_LINUX_LAPD:
			pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
				pinfo->pseudo_header->lapd.pkttype == 4) ?
				P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_MTP2_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
			pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used;
			break;

		case WTAP_ENCAP_GSM_UM:
			pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		}
	}

	if(pinfo->fd->opt_comment){
		item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, -1, ENC_NA);
		comments_tree = proto_item_add_subtree(item, ett_comments);
		comment_item = proto_tree_add_string_format(comments_tree, hf_comments_text, tvb, 0, -1,
							                   pinfo->fd->opt_comment, "%s",
							                   pinfo->fd->opt_comment);
		expert_add_info_format(pinfo, comment_item, PI_COMMENTS_GROUP, PI_COMMENT,
					                       "%s",  pinfo->fd->opt_comment);


	}

	/* if FRAME is not referenced from any filters we dont need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_frame)) {
		tree=NULL;
		if(pinfo->fd->flags.has_ts) {
			if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000)
				expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN,
						       "Arrival Time: Fractional second out of range (0-1000000000)");
		}
	} else {
		proto_tree *fh_tree;
		gboolean old_visible;

		/* Put in frame header information. */
		cap_len = tvb_length(tvb);
		frame_len = tvb_reported_length(tvb);

		cap_plurality = plurality(cap_len, "", "s");
		frame_plurality = plurality(frame_len, "", "s");

		ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1,
		    "Frame %u: %u byte%s on wire",
		    pinfo->fd->num, frame_len, frame_plurality);
		if (generate_bits_field)
			proto_item_append_text(ti, " (%u bits)", frame_len * 8);
		proto_item_append_text(ti, ", %u byte%s captured",
		    cap_len, cap_plurality);
		if (generate_bits_field) {
			proto_item_append_text(ti, " (%u bits)",
			    cap_len * 8);
		}
		if (pinfo->fd->flags.has_if_id) {
			proto_item_append_text(ti, " on interface %u",
			    pinfo->fd->interface_id);
		}
		if (pinfo->fd->flags.has_pack_flags) {
			if (pinfo->fd->pack_flags & 0x00000001) {
				proto_item_append_text(ti, " (inbound)");
				pinfo->p2p_dir = P2P_DIR_RECV;
			}
			if (pinfo->fd->pack_flags & 0x00000002) {
				proto_item_append_text(ti, " (outbound)");
				pinfo->p2p_dir = P2P_DIR_SENT;
			}
		}

		fh_tree = proto_item_add_subtree(ti, ett_frame);

		if (pinfo->fd->flags.has_if_id)
			proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->fd->interface_id);

		if (pinfo->fd->flags.has_pack_flags) {
			proto_tree *flags_tree;
			proto_item *flags_item;

			flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pinfo->fd->pack_flags);
			flags_tree = proto_item_add_subtree(flags_item, ett_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_direction, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->fd->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->fd->pack_flags);
		}

		proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->fd->lnk_t);

		if (pinfo->fd->flags.has_ts) {
			proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
					    0, 0, &(pinfo->fd->abs_ts));
			if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) {
				item = proto_tree_add_none_format(fh_tree, hf_frame_time_invalid, tvb, 0, 0,
								  "Arrival Time: Fractional second %09ld is invalid,"
								  " the valid range is 0-1000000000",
								  (long) pinfo->fd->abs_ts.nsecs);
				PROTO_ITEM_SET_GENERATED(item);
				expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN,
						       "Arrival Time: Fractional second out of range (0-1000000000)");
			}
			item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb,
					    0, 0, &(pinfo->fd->shift_offset));
			PROTO_ITEM_SET_GENERATED(item);

			if(generate_epoch_time) {
				proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb,
						    0, 0, &(pinfo->fd->abs_ts));
			}

			if (proto_field_is_referenced(tree, hf_frame_time_delta)) {
				nstime_t     del_cap_ts;

				frame_delta_abs_time(pinfo->fd, pinfo->fd->prev_cap, &del_cap_ts);

				item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
							   0, 0, &(del_cap_ts));
				PROTO_ITEM_SET_GENERATED(item);
			}

			if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) {
				nstime_t del_dis_ts;

				frame_delta_abs_time(pinfo->fd, pinfo->fd->prev_dis, &del_dis_ts);

				item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
							   0, 0, &(del_dis_ts));
				PROTO_ITEM_SET_GENERATED(item);
			}

			item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
						   0, 0, &(pinfo->fd->rel_ts));
			PROTO_ITEM_SET_GENERATED(item);

			if(pinfo->fd->flags.ref_time){
				ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA);
				PROTO_ITEM_SET_GENERATED(ti);
			}
		}

		proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
				    0, 0, pinfo->fd->num);

		proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb,
					   0, 0, frame_len, "Frame Length: %u byte%s (%u bits)",
					   frame_len, frame_plurality, frame_len * 8);

		proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
					   0, 0, cap_len, "Capture Length: %u byte%s (%u bits)",
					   cap_len, cap_plurality, cap_len * 8);

		if (generate_md5_hash) {
			const guint8 *cp;
			md5_state_t   md_ctx;
			md5_byte_t    digest[16];
			const gchar  *digest_string;

			cp = tvb_get_ptr(tvb, 0, cap_len);

			md5_init(&md_ctx);
			md5_append(&md_ctx, cp, cap_len);
			md5_finish(&md_ctx, digest);

			digest_string = bytestring_to_str(digest, 16, '\0');
			ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
			PROTO_ITEM_SET_GENERATED(ti);
		}

		ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked);
		PROTO_ITEM_SET_GENERATED(ti);

		ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0,pinfo->fd->flags.ignored);
		PROTO_ITEM_SET_GENERATED(ti);

		if(proto_field_is_referenced(tree, hf_frame_protocols)) {
			/* we are going to be using proto_item_append_string() on
			 * hf_frame_protocols, and we must therefore disable the
			 * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
			 * setting it as visible.
			 *
			 * See proto.h for details.
			 */
			old_visible = proto_tree_set_visible(fh_tree, TRUE);
			ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, "");
			PROTO_ITEM_SET_GENERATED(ti);
			proto_tree_set_visible(fh_tree, old_visible);

			pinfo->layer_names = g_string_new("");
		}
		else
			pinfo->layer_names = NULL;

		/* Check for existences of P2P pseudo header */
		if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
			proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
					   0, 0, pinfo->p2p_dir);
		}

		/* Check for existences of MTP2 link number */
		if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) {
			proto_tree_add_uint(fh_tree, hf_link_number, tvb,
					    0, 0, pinfo->link_number);
		}

		if (show_file_off) {
			proto_tree_add_int64_format(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "File Offset: %" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
						    pinfo->fd->file_off, pinfo->fd->file_off);
		}

		if(pinfo->fd->color_filter != NULL) {
			const color_filter_t *color_filter = pinfo->fd->color_filter;
			item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
						     0, 0, color_filter->filter_name);
			PROTO_ITEM_SET_GENERATED(item);
			item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
						     0, 0, color_filter->filter_text);
			PROTO_ITEM_SET_GENERATED(item);
		}
	}

	if (pinfo->fd->flags.ignored) {
		/* Ignored package, stop handling here */
		col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
		proto_tree_add_text (tree, tvb, 0, -1, "This frame is marked as ignored");
		return;
	}

	/* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
		/* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
		   like memory access violations.
		   (a running debugger will be called before the except part below) */
                /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
                   stack in an inconsistent state thus causing a crash at some point in the
                   handling of the exception.
                   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
                */
		__try {
#endif
			if ((force_docsis_encap) && (docsis_handle)) {
				call_dissector(docsis_handle, tvb, pinfo, parent_tree);
			} else {
				if (!dissector_try_uint(wtap_encap_dissector_table, pinfo->fd->lnk_t,
							tvb, pinfo, parent_tree)) {

					col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
					col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
						     pinfo->fd->lnk_t);
					call_dissector(data_handle,tvb, pinfo, parent_tree);
				}
			}
#ifdef _MSC_VER
		} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
			switch(GetExceptionCode()) {
			case(STATUS_ACCESS_VIOLATION):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
				break;
			case(STATUS_INTEGER_DIVIDE_BY_ZERO):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
				break;
			case(STATUS_STACK_OVERFLOW):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
				/* XXX - this will have probably corrupted the stack,
				   which makes problems later in the exception code */
				break;
				/* XXX - add other hardware exception codes as required */
			default:
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
			}
		}
#endif
	}
	CATCH(OutOfMemoryError) {
		RETHROW;
	}
	CATCH_ALL {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

	if (tree && pinfo->layer_names) {
		proto_item_append_string(ti, pinfo->layer_names->str);
		g_string_free(pinfo->layer_names, TRUE);
		pinfo->layer_names = NULL;
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
		TRY {
#ifdef _MSC_VER
			/* Win32: Visual-C Structured Exception Handling (SEH)
			   to trap hardware exceptions like memory access violations */
			/* (a running debugger will be called before the except part below) */
                        /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
                           stack in an inconsistent state thus causing a crash at some point in the
                           handling of the exception.
                           See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
                        */
			__try {
#endif
				call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
			} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
				switch(GetExceptionCode()) {
				case(STATUS_ACCESS_VIOLATION):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
					break;
				case(STATUS_INTEGER_DIVIDE_BY_ZERO):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
					break;
				case(STATUS_STACK_OVERFLOW):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
					/* XXX - this will have probably corrupted the stack,
					   which makes problems later in the exception code */
					break;
					/* XXX - add other hardware exception codes as required */
				default:
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
				}
			}
#endif
		}
		CATCH(OutOfMemoryError) {
			RETHROW;
		}
		CATCH_ALL {
			show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
		}
		ENDTRY;
	}

	tap_queue_packet(frame_tap, pinfo, NULL);


	if (pinfo->frame_end_routines) {
		g_slist_foreach(pinfo->frame_end_routines, &call_frame_end_routine, NULL);
		g_slist_free(pinfo->frame_end_routines);
		pinfo->frame_end_routines = NULL;
	}
}
Example #27
0
static gint
dissect_userdata(proto_item *ti_arg, gint ett_arg, tvbuff_t *tvb, gint arg_offset)
{
        gint        offset = arg_offset;
        guint8      flen, lenbytes;
        guint8      year, month, day, hour, min, sec;
        guint16     msec;
        proto_tree *tree;
        proto_item *ti;

        tree = proto_item_add_subtree(ti_arg, ett_arg);

        /* length of User Data, should be 1 byte field ... */
        flen     = tvb_get_guint8(tvb, offset);
        lenbytes = 1;

        /* ... but sometimes it seems to be 2 bytes; try to be clever */
        if (flen == 0) {
                flen = tvb_get_guint8(tvb, offset+1);
                lenbytes = 2;
        }
        if (flen == 0 || flen > 79) /* invalid */
                return offset;

        ti = proto_tree_add_item(tree, hf_elcom_userdata_length, tvb, offset, lenbytes, ENC_BIG_ENDIAN);
        offset += lenbytes;
        if (lenbytes == 2) {
                proto_item_append_text(ti, " (2 bytes, should be 1 byte)");
        }

        if (tvb_reported_length_remaining(tvb, offset) <= 0)
                return offset;

        proto_tree_add_item(tree, hf_elcom_userdata_pduid, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;

        if (tvb_reported_length_remaining(tvb, offset) <= 0)
                return offset;

        proto_tree_add_item(tree, hf_elcom_userdata_version, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;


        if (tvb_reported_length_remaining(tvb, offset) <= 0)
                return offset;

        proto_tree_add_item(tree, hf_elcom_userdata_result, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;

        /* show the rest */
        /*        tree2 = proto_tree_add_subtree(tree, tvb, offset, -1, "User Data"); */

        if (tvb_reported_length_remaining(tvb, offset) <= 0)
                return offset;
        ti = proto_tree_add_item(tree, hf_elcom_userdata_restmark, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_item_append_text(ti, " <-- '0' = no restart etc.");
        offset +=1;

        if (tvb_reported_length_remaining(tvb, offset+8) <= 0)
                return offset;
        year  = tvb_get_guint8(tvb, offset);
        month = tvb_get_guint8(tvb, offset+1);
        day   = tvb_get_guint8(tvb, offset+2);
        hour  = tvb_get_guint8(tvb, offset+3);
        min   = tvb_get_guint8(tvb, offset+4);
        sec   = tvb_get_guint8(tvb, offset+5);
        msec  = tvb_get_ntohs(tvb, offset+6);

        proto_tree_add_none_format(tree, hf_elcom_userdata_cf, tvb, offset, 8,
                                   "Control Field: %4d-%02d-%02d %02d:%02d:%02d.%d",
                                   year+1900, month, day, hour, min, sec, msec);

        offset += 12;
        if (tvb_reported_length_remaining(tvb, offset+12) > 0) {
                proto_item_append_text(ti, " Security info: ");
        }
        /* security info field, if present */
        while (tvb_reported_length_remaining(tvb, offset) > 0) {
                proto_item_append_text(ti, elcom_show_hex ? " %02x" : " %03o",
                                       tvb_get_guint8(tvb, offset));
                offset++;
        }

        return offset;
}
Example #28
0
static void
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_item	*volatile ti = NULL;
	nstime_t	ts;
	int		cap_len = 0, frame_len = 0;
	proto_tree	*volatile tree;
        proto_item  *item;
	guint32 frame_number;

	frame_number=pinfo->fd->num; /* dummy so that the buildbot crashdumps
					will show the packetnumber where the
					crash occurred.
				     */
	tree=parent_tree;

	pinfo->current_proto = "Frame";

	if (pinfo->pseudo_header != NULL) {
		switch (pinfo->fd->lnk_t) {

		case WTAP_ENCAP_WFLEET_HDLC:
		case WTAP_ENCAP_CHDLC_WITH_PHDR:
		case WTAP_ENCAP_PPP_WITH_PHDR:
		case WTAP_ENCAP_SDLC:
		case WTAP_ENCAP_BLUETOOTH_H4:
		case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_BLUETOOTH_HCI:
			pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent;
			break;

		case WTAP_ENCAP_LAPB:
		case WTAP_ENCAP_FRELAY_WITH_PHDR:
			pinfo->p2p_dir =
			    (pinfo->pseudo_header->x25.flags & FROM_DCE) ?
			    P2P_DIR_RECV : P2P_DIR_SENT;
			break;

		case WTAP_ENCAP_ISDN:
			pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_LINUX_LAPD:
			pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
				pinfo->pseudo_header->lapd.pkttype == 4) ?
				P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_MTP2_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
			pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used;
			break;

		case WTAP_ENCAP_GSM_UM:
			pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		}
	}

	/* if FRAME is not referenced from any filters we dont need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_frame)) {
        tree=NULL;
        if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000)
            expert_add_info_format(pinfo, NULL, PI_MALFORMED, PI_WARN,
                "Arrival Time: Fractional second out of range (0-1000000000)");
    } else {
	    proto_tree	*fh_tree;

	  /* Put in frame header information. */
	  cap_len = tvb_length(tvb);
	  frame_len = tvb_reported_length(tvb);

	  ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1,
	    "Frame %u (%u bytes on wire, %u bytes captured)", pinfo->fd->num, frame_len, cap_len);

	  fh_tree = proto_item_add_subtree(ti, ett_frame);

	  ts = pinfo->fd->abs_ts;

	  proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
		0, 0, &ts);
	  if(ts.nsecs < 0 || ts.nsecs >= 1000000000) {
	    item = proto_tree_add_none_format(fh_tree, hf_frame_time_invalid, tvb,
	  	  0, 0, "Arrival Time: Fractional second %09ld is invalid, the valid range is 0-1000000000", (long) ts.nsecs);
	    PROTO_ITEM_SET_GENERATED(item);
	    expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Arrival Time: Fractional second out of range (0-1000000000)");
	  }

	  ts = pinfo->fd->del_cap_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  ts = pinfo->fd->del_dis_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  ts = pinfo->fd->rel_ts;

	  item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
		0, 0, &ts);
	  PROTO_ITEM_SET_GENERATED(item);

	  if(pinfo->fd->flags.ref_time){
		ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, FALSE);
		PROTO_ITEM_SET_GENERATED(ti);
	  }

	  proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
		0, 0, pinfo->fd->num);

	  proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb,
		0, 0, frame_len, "Frame Length: %d byte%s", frame_len,
		plurality(frame_len, "", "s"));

	  proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
		0, 0, cap_len, "Capture Length: %d byte%s", cap_len,
		plurality(cap_len, "", "s"));

	  if (generate_md5_hash) {
		  const guint8 *cp;
		  md5_state_t md_ctx;
		  md5_byte_t digest[16];
		  gchar *digest_string;

		  cp = tvb_get_ptr(tvb, 0, cap_len);

		  md5_init(&md_ctx);
		  md5_append(&md_ctx, cp, cap_len);
		  md5_finish(&md_ctx, digest);

		  digest_string = bytestring_to_str(digest, 16, '\0');
		  ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
		  PROTO_ITEM_SET_GENERATED(ti);
	  }

	  ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked);
	  PROTO_ITEM_SET_GENERATED(ti);

	  /* we are going to be using proto_item_append_string() on
	   * hf_frame_protocols, and we must therefore disable the
	   * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
	   * setting it as visible.
	   *
	   * See proto.h for details.
	   */
	  proto_tree_set_visible(fh_tree, TRUE);

	  ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb,
	  	0, 0, "");
	  PROTO_ITEM_SET_GENERATED(ti);
	  pinfo->layer_names = g_string_new("");

	  /* Check for existences of P2P pseudo header */
	  if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
		  proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
				  0, 0, pinfo->p2p_dir);
	  }

	  /* Check for existences of MTP2 link number */
	  if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) {
		  proto_tree_add_uint(fh_tree, hf_link_number, tvb,
				  0, 0, pinfo->link_number);
	  }

	  if (show_file_off) {
		  proto_tree_add_int64_format(fh_tree, hf_frame_file_off, tvb,
				  0, 0, pinfo->fd->file_off,
				  "File Offset: %" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
				  pinfo->fd->file_off, pinfo->fd->file_off);
	  }

	  if(pinfo->fd->color_filter != NULL) {
	      color_filter_t *color_filter = pinfo->fd->color_filter;
	      item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
		    0, 0, color_filter->filter_name);
	      PROTO_ITEM_SET_GENERATED(item);
	      item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
		    0, 0, color_filter->filter_text);
	      PROTO_ITEM_SET_GENERATED(item);
	  }
    }

    /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
    /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */
    /* (a running debugger will be called before the except part below) */
    __try {
#endif
	if ((force_docsis_encap) && (docsis_handle)) {
	    call_dissector(docsis_handle, tvb, pinfo, parent_tree);
	} else {
            if (!dissector_try_port(wtap_encap_dissector_table, pinfo->fd->lnk_t,
                tvb, pinfo, parent_tree)) {

				col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
				col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %u",
				    pinfo->fd->lnk_t);
			call_dissector(data_handle,tvb, pinfo, parent_tree);
		}
	}
#ifdef _MSC_VER
    } __except(TRUE /* handle all exceptions */) {
        switch(GetExceptionCode()) {
        case(STATUS_ACCESS_VIOLATION):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
            break;
        case(STATUS_INTEGER_DIVIDE_BY_ZERO):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
            break;
        case(STATUS_STACK_OVERFLOW):
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
            /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */
            break;
        /* XXX - add other hardware exception codes as required */
        default:
		    show_exception(tvb, pinfo, parent_tree, DissectorError,
                g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
        }
    }
#endif
	}
	CATCH(OutOfMemoryError) {
		RETHROW;
	}
	CATCH_ALL {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

	if (tree && pinfo->layer_names) {
		proto_item_append_string(ti, pinfo->layer_names->str);
		g_string_free(pinfo->layer_names, TRUE);
		pinfo->layer_names = NULL;
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
	    TRY {
#ifdef _MSC_VER
	    /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions like memory access violations */
	    /* (a running debugger will be called before the except part below) */
	    __try {
#endif
		call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
	    } __except(TRUE /* handle all exceptions */) {
		switch(GetExceptionCode()) {
		case(STATUS_ACCESS_VIOLATION):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
		    break;
		case(STATUS_INTEGER_DIVIDE_BY_ZERO):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
		    break;
		case(STATUS_STACK_OVERFLOW):
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			"STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
		    /* XXX - this will have probably corrupted the stack, which makes problems later in the exception code */
		    break;
		/* XXX - add other hardware exception codes as required */
		default:
			    show_exception(tvb, pinfo, parent_tree, DissectorError,
			g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
		}
	    }
#endif
	    }
	    CATCH(OutOfMemoryError) {
		    RETHROW;
	    }
	    CATCH_ALL {
		    show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	    }
	    ENDTRY;
	}

	tap_queue_packet(frame_tap, pinfo, NULL);


	if (frame_end_routines) {
		g_slist_foreach(frame_end_routines, &call_frame_end_routine, NULL);
		g_slist_free(frame_end_routines);
		frame_end_routines = NULL;
	}
}
Example #29
0
/* Decode an EXT_FTI extension and fill FEC array */
void fec_decode_ext_fti(struct _ext *e, tvbuff_t *tvb, proto_tree *tree, gint ett, struct _fec_ptr f)
{
	proto_item* ti = NULL;
	proto_tree *ext_tree;

	if (tree)
		ti = proto_tree_add_none_format(tree, f.hf->fti_header, tvb, e->offset, e->length,
			"EXT_FTI, FEC Object Transmission Information (%u)", e->het);

	if (f.fec->encoding_id_present)
	{
		ext_tree = proto_item_add_subtree(ti, ett);
		rmt_ext_decode_default_header(e, tvb, ext_tree);

		/* Decode 48-bit length field */
		f.fec->transfer_length = tvb_get_ntoh64(tvb, e->offset) & G_GINT64_CONSTANT(0xFFFFFFFFFFFFU);

		if (f.fec->encoding_id >= 128)
		{
			/* Decode FEC Instance ID */
			f.fec->instance_id_present = TRUE;
			f.fec->instance_id = (guint8) tvb_get_ntohs(tvb, e->offset+8);
		}

		if (tree)
			proto_tree_add_uint64(ext_tree, f.hf->fti_transfer_length, tvb, e->offset+2, 6, f.fec->transfer_length);

		switch (f.fec->encoding_id)
		{
		case 0:
		case 2:
		case 128:
		case 130:
			f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
			f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12);

			if (tree)
			{
				proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length);
			}
			break;

		case 129:
			f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
			f.fec->max_source_block_length = tvb_get_ntohs(tvb, e->offset+12);
			f.fec->max_number_encoding_symbols = tvb_get_ntohs(tvb, e->offset+14);

			if (tree)
			{
				proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 2, f.fec->max_source_block_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+14, 2, f.fec->max_number_encoding_symbols);
			}
			break;

		case 132:
			f.fec->encoding_symbol_length = tvb_get_ntohs(tvb, e->offset+10);
			f.fec->max_source_block_length = tvb_get_ntohl(tvb, e->offset+12);
			f.fec->max_number_encoding_symbols = tvb_get_ntohl(tvb, e->offset+16);

			if (tree)
			{
				proto_tree_add_uint(ext_tree, f.hf->fti_encoding_symbol_length, tvb, e->offset+10, 2, f.fec->encoding_symbol_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_source_block_length, tvb, e->offset+12, 4, f.fec->max_source_block_length);
				proto_tree_add_uint(ext_tree, f.hf->fti_max_number_encoding_symbols, tvb, e->offset+16, 4, f.fec->max_number_encoding_symbols);
			}
			break;
		}

	} else
		if (tree)
			rmt_ext_decode_default_subtree(e, tvb, ti, ett);
}
Example #30
0
static gint
dissect_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *top_tree,
        proto_tree *tree, gint offset, guint8 *parameter, gint *parameter_offset)
{
    proto_item  *parameter_item;
    proto_item  *pitem;
    proto_tree  *ptree;
    tvbuff_t    *next_tvb;
    guint        parameter_id;
    guint        parameter_length;
    guint        parameter_padding_length;
    guint        padding_length;
    guint        length;
    guint16      max_msg_size;
    guint8       connection_status;
    guint8       result_code;
    guint8       disconnection_type;
    guint8       status_change;
    guint8       transport_protocol;

    parameter_id = tvb_get_guint8(tvb, offset);
    parameter_length = tvb_get_ntohs(tvb, offset + 2);
    parameter_padding_length = parameter_length % 4;
    if (parameter_padding_length > 0)
        parameter_padding_length = 4 - parameter_padding_length;

    parameter_item = proto_tree_add_none_format(tree, hf_btsap_parameter, tvb, offset,
            2 + 2 + parameter_length + parameter_padding_length, "Parameter: %s: ",
            val_to_str_const(parameter_id, parameter_id_vals, "Unknown ParameterID"));
    ptree = proto_item_add_subtree(parameter_item, ett_btsap_parameter);

    proto_tree_add_item(ptree, hf_btsap_parameter_id, tvb, offset, 1, ENC_BIG_ENDIAN);

    col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(parameter_id, parameter_id_vals, "Unknown ParameterID"));
    offset += 1;

    proto_tree_add_item(ptree, hf_btsap_parameter_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    pitem = proto_tree_add_item(ptree, hf_btsap_parameter_length, tvb, offset, 2, ENC_BIG_ENDIAN);

    proto_item_append_text(pitem, " (in 4 bytes sections, padding length: %u)", parameter_padding_length);
    offset += 2;

    switch(parameter_id) {
        case 0x00: /* MaxMsgSize */
            proto_tree_add_item(ptree, hf_btsap_parameter_max_msg_size, tvb, offset, 2, ENC_BIG_ENDIAN);
            max_msg_size = tvb_get_ntohs(tvb, offset);
            proto_item_append_text(parameter_item, "%u", max_msg_size);
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", max_msg_size);
            length = 2;
            padding_length = 2;
            break;
        case 0x01: /* ConnectionStatus */
            proto_tree_add_item(ptree, hf_btsap_parameter_connection_status, tvb, offset, 1, ENC_BIG_ENDIAN);
            connection_status = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%s", val_to_str_const(connection_status, connection_status_vals, "Unknown"));
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(connection_status, connection_status_vals, "Unknown"));
            length = 1;
            padding_length = 3;
            break;
        case 0x02: /* ResultCode */
            proto_tree_add_item(ptree, hf_btsap_parameter_result_code, tvb, offset, 1, ENC_BIG_ENDIAN);
            result_code = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%s", val_to_str_const(result_code, result_code_vals, "Unknown"));
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(result_code, result_code_vals, "Unknown"));
            length = 1;
            padding_length = 3;
            break;
        case 0x03: /* DisconnectionType */
            proto_tree_add_item(ptree, hf_btsap_parameter_disconnection_type, tvb, offset, 1, ENC_BIG_ENDIAN);
            disconnection_type = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%s", val_to_str_const(disconnection_type, disconnection_type_vals, "Unknown"));
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(disconnection_type, disconnection_type_vals, "Unknown"));
            length = 1;
            padding_length = 3;
            break;
        case 0x04: /* CommandAPDU */
            /* GSM 11.11 */
            if (gsm_sim_cmd_handle && top_dissect != TOP_DISSECT_OFF) {
                next_tvb = tvb_new_subset_length(tvb, offset, parameter_length);
                col_append_str(pinfo->cinfo, COL_INFO, ": ");

                if (top_dissect == TOP_DISSECT_INTERNAL) {
                    call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, ptree);
                } else {
                    col_clear(pinfo->cinfo, COL_INFO);
                    call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, top_tree);
                }
            } else {
                proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            }

            length = parameter_length;
            padding_length = parameter_padding_length;
            break;
        case 0x05: /* ResponseAPDU */
            /* GSM 11.11 or ISO/IEC 7816-4; depend of TRANSFER_APDU_REQ */
            if (gsm_sim_resp_handle && top_dissect != TOP_DISSECT_OFF) {
                next_tvb = tvb_new_subset_length(tvb, offset, parameter_length);
                col_append_str(pinfo->cinfo, COL_INFO, ": ");

                if (top_dissect == TOP_DISSECT_INTERNAL) {
                    call_dissector(gsm_sim_resp_handle, next_tvb, pinfo, ptree);
                } else {
                    col_clear(pinfo->cinfo, COL_INFO);
                    call_dissector(gsm_sim_resp_handle, next_tvb, pinfo, top_tree);
                }
            } else {
                proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            }

            length = parameter_length;
            padding_length = parameter_padding_length;
            break;
        case 0x06: /* ATR */
            /* ISO/IEC 7816-3 */
            if (iso7816_atr_handle && top_dissect != TOP_DISSECT_OFF) {
                next_tvb = tvb_new_subset_length(tvb, offset, parameter_length);
                col_append_str(pinfo->cinfo, COL_INFO, ": ");

                if (top_dissect == TOP_DISSECT_INTERNAL) {
                    call_dissector(iso7816_atr_handle, next_tvb, pinfo, ptree);
                } else {
                    col_clear(pinfo->cinfo, COL_INFO);
                    call_dissector(iso7816_atr_handle, next_tvb, pinfo, top_tree);
                }
            } else {
                proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            }

            length = parameter_length;
            padding_length = parameter_padding_length;
            break;
        case 0x07: /* CardReaderStatus */
            /* 3GPP TS 11.14 */
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_powered, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_present, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_present_lower, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_present, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_removable, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item(ptree, hf_btsap_parameter_card_reader_status_card_reader_identity, tvb, offset, 1, ENC_BIG_ENDIAN);
            length = 1;
            padding_length = 3;
            break;
        case 0x08: /* StatusChange */
            proto_tree_add_item(ptree, hf_btsap_parameter_status_change, tvb, offset, 1, ENC_BIG_ENDIAN);
            status_change = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%s", val_to_str_const(status_change, status_change_vals, "Unknown"));
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(status_change, status_change_vals, "Unknown"));
            length = 1;
            padding_length = 3;
            break;
        case 0x09: /* TransportProtocol */
            proto_tree_add_item(ptree, hf_btsap_parameter_transport_protocol, tvb, offset, 1, ENC_BIG_ENDIAN);
            transport_protocol = tvb_get_guint8(tvb, offset);
            proto_item_append_text(parameter_item, "%u", transport_protocol);
            col_append_fstr(pinfo->cinfo, COL_INFO, ": %u", transport_protocol);
            length = 1;
            padding_length = 3;
            break;
        case 0x10: /* CommandAPDU7816 */
            /* ISO/IEC 7816-4 */
            if (gsm_sim_cmd_handle && top_dissect != TOP_DISSECT_OFF) {
                next_tvb = tvb_new_subset_length(tvb, offset, parameter_length);
                col_append_str(pinfo->cinfo, COL_INFO, ": ");

                if (top_dissect == TOP_DISSECT_INTERNAL) {
                    call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, ptree);
                } else {
                    col_clear(pinfo->cinfo, COL_INFO);
                    call_dissector(gsm_sim_cmd_handle, next_tvb, pinfo, top_tree);
                }
            } else {
                proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            }

            length = parameter_length;
            padding_length = parameter_padding_length;
            break;
        default:
            proto_tree_add_item(ptree, hf_btsap_data, tvb, offset, parameter_length, ENC_NA);
            length = parameter_length;
            padding_length = parameter_padding_length;
    }

    *parameter = parameter_id;
    *parameter_offset = offset;

    if (length != parameter_length || padding_length != parameter_padding_length) {
        /* Malformed frame */
        expert_add_info_format(pinfo, pitem, &ei_btsap_parameter_error,
            "Parameter Length does not meet content length");
    }

    offset += parameter_length;

    if (parameter_padding_length > 0) {
        pitem = proto_tree_add_item(ptree, hf_btsap_parameter_padding, tvb, offset, parameter_padding_length, ENC_NA);
        proto_item_append_text(pitem, " (length %d)", parameter_padding_length);
        offset += parameter_padding_length;
    }

    return offset;
}