Пример #1
0
static void
dissect_v8_user_data_message(tvbuff_t *message_data_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree)
{
  proto_item *m2pa_li_item;
  proto_tree *m2pa_li_tree;
  tvbuff_t *payload_tvb;

  if (tvb_length(message_data_tvb) > 0) {
    if (m2pa_tree) {
      m2pa_li_item = proto_tree_add_text(m2pa_tree, message_data_tvb, LI_OFFSET, LI_LENGTH, "Length Indicator");
      m2pa_li_tree = proto_item_add_subtree(m2pa_li_item, ett_m2pa_li);
      proto_tree_add_item(m2pa_li_tree, hf_v8_li_prio,  message_data_tvb, LI_OFFSET, LI_LENGTH, ENC_BIG_ENDIAN);
      proto_tree_add_item(m2pa_li_tree, hf_v8_li_spare, message_data_tvb, LI_OFFSET, LI_LENGTH, ENC_BIG_ENDIAN);

        /* Re-adjust length of M2PA item since it will be dissected as MTP3 */
      proto_item_set_len(m2pa_item, V8_HEADER_LENGTH + LI_LENGTH);
    }

    payload_tvb = tvb_new_subset_remaining(message_data_tvb, MTP3_OFFSET);
    call_dissector(mtp3_handle, payload_tvb, pinfo, tree);
  }
}
Пример #2
0
static void
dissect_v12_user_data_message(tvbuff_t *message_data_tvb, packet_info *pinfo, proto_item *m2pa_item, proto_tree *m2pa_tree, proto_tree *tree)
{
  proto_item *m2pa_li_item;
  proto_tree *m2pa_li_tree;
  tvbuff_t *payload_tvb;

  if (tvb_length(message_data_tvb) > 0) {
    if (m2pa_tree) {
      m2pa_li_item = proto_tree_add_text(m2pa_tree, message_data_tvb, PRI_OFFSET, PRI_LENGTH, "Priority");
      m2pa_li_tree = proto_item_add_subtree(m2pa_li_item, ett_m2pa_li);
      proto_tree_add_item(m2pa_li_tree, hf_pri_prio,  message_data_tvb, PRI_OFFSET, PRI_LENGTH, NETWORK_BYTE_ORDER);
      proto_tree_add_item(m2pa_li_tree, hf_pri_spare, message_data_tvb, PRI_OFFSET, PRI_LENGTH, NETWORK_BYTE_ORDER);

        /* Re-adjust length of M2PA item since it will be dissected as MTP3 */
      proto_item_set_len(m2pa_item, V12_HEADER_LENGTH + PRI_LENGTH);
    }

    payload_tvb = tvb_new_subset_remaining(message_data_tvb, MTP3_OFFSET);
    call_dissector(mtp3_handle, payload_tvb, pinfo, tree);
  }
}
Пример #3
0
static int
dissect_rx_challenge(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, guint32 seq, guint32 callnumber)
{
	proto_tree *tree;
	proto_item *item;
	guint32 version;
	int old_offset=offset;

	col_add_fstr(pinfo->cinfo, COL_INFO,
			"CHALLENGE  "
			"Seq: %lu  "
			"Call: %lu  "
			"Source Port: %s  "
			"Destination Port: %s  ",
			(unsigned long)seq,
			(unsigned long)callnumber,
			udp_port_to_display(wmem_packet_scope(), pinfo->srcport),
			udp_port_to_display(wmem_packet_scope(), pinfo->destport)
		);

	item = proto_tree_add_item(parent_tree, hf_rx_challenge, tvb, offset, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_rx_challenge);

	version = tvb_get_ntohl(tvb, offset);
	proto_tree_add_uint(tree, hf_rx_version, tvb,
		offset, 4, version);
	offset += 4;

	if (version==2) {
		proto_tree_add_item(tree, hf_rx_nonce, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;

		proto_tree_add_item(tree, hf_rx_min_level, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
	}

	proto_item_set_len(item, offset-old_offset);
	return offset;
}
Пример #4
0
static void
dissect_dvb_tot(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

    guint       offset = 0;
    guint       descriptor_len;

    proto_item *ti;
    proto_tree *dvb_tot_tree;

    nstime_t    utc_time;

    col_set_str(pinfo->cinfo, COL_INFO, "Time Offset Table (TOT)");

    ti = proto_tree_add_item(tree, proto_dvb_tot, tvb, offset, -1, ENC_NA);
    dvb_tot_tree = proto_item_add_subtree(ti, ett_dvb_tot);

    offset += packet_mpeg_sect_header(tvb, offset, dvb_tot_tree, NULL, NULL);

    if (packet_mpeg_sect_mjd_to_utc_time(tvb, offset, &utc_time) < 0) {
        proto_tree_add_text(dvb_tot_tree, tvb, offset, 5, "UTC Time : Unparseable time");
    } else {
        proto_tree_add_time_format(dvb_tot_tree, hf_dvb_tot_utc_time, tvb, offset, 5, &utc_time,
            "UTC Time : %s UTC", abs_time_to_str(&utc_time, ABSOLUTE_TIME_UTC, FALSE));
    }

    offset += 5;

    descriptor_len = tvb_get_ntohs(tvb, offset) & DVB_TOT_DESCRIPTORS_LOOP_LENGTH_MASK;
    proto_tree_add_item(dvb_tot_tree, hf_dvb_tot_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
    proto_tree_add_item(dvb_tot_tree, hf_dvb_tot_descriptors_loop_length, tvb, offset, 2, ENC_BIG_ENDIAN);
    offset += 2;

    offset += proto_mpeg_descriptor_loop_dissect(tvb, offset, descriptor_len, dvb_tot_tree);

    offset += packet_mpeg_sect_crc(tvb, pinfo, dvb_tot_tree, 0, offset);
    proto_item_set_len(ti, offset);
}
Пример #5
0
static void
dissect_mpeg_ca(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

    guint offset = 0, length = 0;

    proto_item *ti;
    proto_tree *mpeg_ca_tree;

    /* The TVB should start right after the section_length in the Section packet */

    col_set_str(pinfo->cinfo, COL_INFO, "Conditional Access Table (CA)");

    ti = proto_tree_add_item(tree, proto_mpeg_ca, tvb, offset, -1, ENC_NA);
    mpeg_ca_tree = proto_item_add_subtree(ti, ett_mpeg_ca);

    offset += packet_mpeg_sect_header(tvb, offset, mpeg_ca_tree, &length, NULL);
    length -= 4;

    proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_reserved, tvb, offset, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_version_number, tvb, offset, 3, ENC_BIG_ENDIAN);
    proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_current_next_indicator, tvb, offset, 3, ENC_BIG_ENDIAN);
    offset += 3;

    proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_section_number, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    proto_tree_add_item(mpeg_ca_tree, hf_mpeg_ca_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    /* Parse all the programs */
    while (offset < length)
        offset += proto_mpeg_descriptor_dissect(tvb, offset, mpeg_ca_tree);

    offset += packet_mpeg_sect_crc(tvb, pinfo, mpeg_ca_tree, 0, offset);

    proto_item_set_len(ti, offset);
}
static int
dissect_rs_pgo_result_t (tvbuff_t * tvb, int offset,
                         packet_info * pinfo, proto_tree * parent_tree,
                         dcerpc_info *di, guint8 * drep)
{

/*
    typedef struct {
        sec_rgy_name_t      name;
        sec_rgy_pgo_item_t  item;
    } rs_pgo_result_t;


*/

  proto_item *item = NULL;
  proto_tree *tree = NULL;
  int old_offset = offset;

  if (di->conformant_run)
    {
      return offset;
    }

  if (parent_tree)
    {
      item =
        proto_tree_add_text (parent_tree, tvb, offset, -1,
                             "rs_pgo_result_t ");
      tree = proto_item_add_subtree (item, ett_rs_pgo_result_t);
    }

  offset = dissect_sec_rgy_name_t (tvb, offset, pinfo, tree, di, drep);
  offset = dissect_sec_rgy_pgo_item_t (tvb, offset, pinfo, tree, di, drep);

  proto_item_set_len (item, offset - old_offset);
  return offset;
}
Пример #7
0
/* EcDoRpc Function 0x2  */
static int
mapi_dissect_element_EcDoRpc_MAPI_REPL_UNION_OpenFolder(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, dcerpc_info* di, guint8 *drep)
{
	proto_item	*item = NULL;
	proto_tree	*tree = NULL;
	int		old_offset;
	int		origin_offset;

	origin_offset = offset;

	if (parent_tree) {
		item = proto_tree_add_item(parent_tree, hf_mapi_EcDoRpc_MAPI_REPL_UNION_mapi_OpenFolder, tvb, offset, -1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_mapi_OpenFolder_repl);
	}

	old_offset = offset;
	proto_tree_add_item(tree, hf_mapi_EcDoRpc_unknown1, tvb, old_offset, 2, ENC_LITTLE_ENDIAN);
	offset += 2;

	proto_item_set_len(item, offset - origin_offset);

	return offset;
}
int
dssetup_dissect_struct_DsRoleOpStatus(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, guint8 *drep, int hf_index, guint32 param _U_)
{
	proto_item *item = NULL;
	proto_tree *tree = NULL;
	int old_offset;

	ALIGN_TO_2_BYTES;

	old_offset = offset;

	if(parent_tree){
		item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, TRUE);
		tree = proto_item_add_subtree(item, ett_dssetup_dssetup_DsRoleOpStatus);
	}
	
	offset = dssetup_dissect_element_DsRoleOpStatus_status(tvb, offset, pinfo, tree, drep);


	proto_item_set_len(item, offset-old_offset);

	return offset;
}
Пример #9
0
int
misc_dissect_struct_GUID(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, dcerpc_info* di, guint8 *drep, int hf_index, guint32 param)
{
	proto_item *item = NULL;
	proto_tree *tree = NULL;
	int old_offset;

	ALIGN_TO_4_BYTES;

	old_offset = offset;

	if (parent_tree) {
		item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_misc_GUID);
	}

	offset = misc_dissect_element_GUID_time_low(tvb, offset, pinfo, tree, di, drep);

	offset = misc_dissect_element_GUID_time_mid(tvb, offset, pinfo, tree, di, drep);

	offset = misc_dissect_element_GUID_time_hi_and_version(tvb, offset, pinfo, tree, di, drep);

	offset = misc_dissect_element_GUID_clock_seq(tvb, offset, pinfo, tree, di, drep);

	offset = misc_dissect_element_GUID_node(tvb, offset, pinfo, tree, di, drep);


	proto_item_set_len(item, offset-old_offset);


	if (di->call_data->flags & DCERPC_IS_NDR64) {
		ALIGN_TO_4_BYTES;
	}

	return offset;
}
Пример #10
0
static gint xdmcp_add_authorization_names(proto_tree *tree,
                                    tvbuff_t *tvb, gint offset)
{
  proto_tree *anames_tree;
  proto_item *anames_ti;
  gint anames_len, anames_start_offset;

  anames_start_offset = offset;
  anames_len = tvb_get_guint8(tvb, offset);
  anames_tree = proto_tree_add_subtree_format(tree, tvb,
                                  anames_start_offset, -1,
                                  ett_xdmcp_authorization_names, &anames_ti, "Authorization names (%d)",
                                  anames_len);

  anames_len = tvb_get_guint8(tvb, offset);
  offset++;
  while (anames_len > 0) {
    offset += xdmcp_add_string(anames_tree, hf_xdmcp_authorization_name,
                               tvb, offset);
    anames_len--;
  }
  proto_item_set_len(anames_ti, offset - anames_start_offset);
  return offset - anames_start_offset;
}
static int
dissect_error_status_t (tvbuff_t * tvb, int offset,
			packet_info * pinfo, proto_tree * parent_tree,
			guint8 * drep)
{
  proto_item *item = NULL;
  proto_tree *tree = NULL;
  int old_offset = offset;
  guint32 st;
  dcerpc_info *di;
  const char *st_str;

  di = (dcerpc_info *)pinfo->private_data;
  if (di->conformant_run)
    {
      return offset;
    }

  if (parent_tree)
    {
      item = proto_tree_add_text (parent_tree, tvb, offset, -1,
				  "error_status_t");
      tree = proto_item_add_subtree (item, ett_error_status_t);
    }

  offset =
    dissect_ndr_uint32 (tvb, offset, pinfo, tree, drep, hf_error_status_t,
			&st);
  st_str = val_to_str_ext (st, &dce_error_vals_ext, "%u");

  if (check_col (pinfo->cinfo, COL_INFO))
    col_append_fstr (pinfo->cinfo, COL_INFO, " st:%s ", st_str);

  proto_item_set_len (item, offset - old_offset);
  return offset;
}
static int
dissect_rs_pgo_query_t (tvbuff_t * tvb, int offset,
                        packet_info * pinfo, proto_tree * parent_tree,
                        dcerpc_info *di, guint8 * drep)
{

  enum
  {
    rs_pgo_query_name,
    rs_pgo_query_id,
    rs_pgo_query_unix_num,
    rs_pgo_query_next,
    rs_pgo_query_none
  };


  proto_item *item = NULL;
  proto_tree *tree = NULL;
  int old_offset = offset;
  guint8 query_t;

  if (di->conformant_run)
    {
      return offset;
    }


  if (parent_tree)
    {
      item =
        proto_tree_add_text (parent_tree, tvb, offset, -1, "rs_pgo_query_t ");
      tree = proto_item_add_subtree (item, ett_rs_pgo_query_t);
    }
  offset =
    dissect_ndr_uint8 (tvb, offset, pinfo, tree, di, drep, hf_rs_pgo_query_t,
                       &query_t);
  col_append_str (pinfo->cinfo, COL_INFO, " rs_pgo_query_t:");

  switch (query_t)
    {
    case rs_pgo_query_name:
      col_append_str (pinfo->cinfo, COL_INFO, "NAME");
      break;
    case rs_pgo_query_id:
      col_append_str (pinfo->cinfo, COL_INFO, "ID");
      break;
    case rs_pgo_query_unix_num:
      col_append_str (pinfo->cinfo, COL_INFO, "UNIX_NUM");
      break;
    case rs_pgo_query_next:
      col_append_str (pinfo->cinfo, COL_INFO, "NEXT");
      break;
    case rs_pgo_query_none:
      col_append_str (pinfo->cinfo, COL_INFO, "NONE");
      break;
    default:
          col_append_fstr (pinfo->cinfo, COL_INFO, " unknown:%u", query_t);
      break;
      ;
    }


  proto_item_set_len (item, offset - old_offset);
  return offset;
}
static int
dissect_sec_rgy_pgo_flags_t (tvbuff_t * tvb, int offset,
                             packet_info * pinfo, proto_tree * parent_tree,
                             dcerpc_info *di, guint8 * drep)
{

/*

*/

  proto_item *item = NULL;
  proto_tree *tree = NULL;
  int old_offset = offset;
  guint32 flags;

/*
    typedef bitset  sec_rgy_pgo_flags_t;
*/

  if (di->conformant_run)
    {
      return offset;
    }


  if (parent_tree)
    {
      item =
        proto_tree_add_text (parent_tree, tvb, offset, -1,
                             "sec_rgy_pgo_flags_t ");
      tree = proto_item_add_subtree (item, ett_sec_rgy_pgo_flags_t);
    }

  offset =
    dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
                        hf_sec_rgy_pgo_flags_t, &flags);

/*
     *
     * s e c _ r g y _ p g o _ f l a g s _ t
     *

        * pgo item is an alias *
        const unsigned32 sec_rgy_pgo_is_an_alias  = 0x1;

        * pgo item is required - cannot be deleted *
        const unsigned32 sec_rgy_pgo_is_required  = 0x2;

        *
         * projlist_ok: on person items indicates person can have a concurrent
         * group set on group items indicates this group can appear on a
         * concurrent group set.  On org items this flag is undefined.
         *
        const unsigned32 sec_rgy_pgo_projlist_ok = 0x4;

        *
        * bits 4-32 unused
        *
        const unsigned32 sec_rgy_pgo_flags_none = 0;
*/
#define sec_rgy_pgo_is_an_alias   0x01
#define sec_rgy_pgo_is_required   0x02
#define sec_rgy_pgo_projlist_ok   0x04
#define sec_rgy_pgo_flags_none    0x00


  col_append_str (pinfo->cinfo, COL_INFO, " PgoFlags=");
  if ((flags & sec_rgy_pgo_is_an_alias) == sec_rgy_pgo_is_an_alias)
    {
      col_append_str (pinfo->cinfo, COL_INFO, ":IS_AN_ALIAS");
    }
  if ((flags & sec_rgy_pgo_is_required) == sec_rgy_pgo_is_required)
    {
      col_append_str (pinfo->cinfo, COL_INFO, ":IS_REQUIRED");
    }
  if ((flags & sec_rgy_pgo_projlist_ok) == sec_rgy_pgo_projlist_ok)
    {
      col_append_str (pinfo->cinfo, COL_INFO, ":PROJLIST_OK");
    }
  if ((flags & sec_rgy_acct_admin_client) == sec_rgy_acct_admin_client)
    {
      col_append_str (pinfo->cinfo, COL_INFO, ":NONE");
    }
  if ((flags & sec_rgy_pgo_flags_none) == sec_rgy_pgo_flags_none)
    {
      col_append_str (pinfo->cinfo, COL_INFO, ":NONE");
    }

  proto_item_set_len (item, offset - old_offset);
  return offset;
}
Пример #14
0
static int
dissect_bencoded_dict_entry(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset )
{
  proto_item *ti;
  proto_tree *sub_tree;
  gboolean    tohex;
  char       *key, *val;
  guint       orig_offset = offset;

  key = NULL;
  val = NULL;

  ti       = proto_tree_add_item( tree, hf_bencoded_dict_entry, tvb, offset, 0, ENC_NA );
  sub_tree = proto_item_add_subtree( ti, ett_bencoded_dict_entry);

  /* dissect the key, it must be a string */
  offset   = dissect_bencoded_string( tvb, pinfo, sub_tree, offset, &key, FALSE, "Key" );

  /* If it is a dict, then just do recursion */
  switch( tvb_get_guint8(tvb,offset) )
  {
  case 'd':
    offset = dissect_bencoded_dict( tvb, pinfo, sub_tree, offset, "Value" );
    val    = (char*)dict_str;
    break;
  case 'l':
    if( strcmp(key,"e")==0 )
      offset = dissect_bt_dht_error( tvb, pinfo, sub_tree, offset, &val, "Value" );
    else if( strcmp(key,"values")==0 )
      offset = dissect_bt_dht_values( tvb, pinfo, sub_tree, offset, &val, "Value" );
    /* other unfamiliar lists */
    else
    {
      offset = dissect_bencoded_list( tvb, pinfo, sub_tree, offset, "Value" );
      val = (char*)list_str;
    }
    break;
  case 'i':
    offset = dissect_bencoded_int( tvb, pinfo, sub_tree, offset, &val, "Value" );
    break;
  /* it's a string */
  default:
    /* special process */
  if( strcmp(key,"nodes")==0 )
      offset = dissect_bt_dht_nodes( tvb, pinfo, sub_tree, offset, &val, "Value" );
  /* some need to return hex string */
    else
    {
      tohex = strcmp(key,"id")==0 || strcmp(key,"target")==0
           || strcmp(key,"info_hash")==0 || strcmp(key,"t")==0
           || strcmp(key,"v")==0;
      offset = dissect_bencoded_string( tvb, pinfo, sub_tree, offset, &val, tohex, "Value" );
    }
  }

  if( strlen(key)==1 )
    key = (char*)val_to_str( key[0], short_key_name_value_string, key );
  if( strlen(val)==1 )
    val = (char*)val_to_str( val[0], short_val_name_value_string, val );

  proto_item_set_text( ti, "%s: %s", key, val );
  proto_item_set_len( ti, offset-orig_offset );

  if( strcmp(key,"message_type")==0 || strcmp(key,"request_type")==0 )
    col_append_fstr(pinfo->cinfo, COL_INFO, "%s=%s  ", key, val);

  return offset;
}
Пример #15
0
/* Code to actually dissect the packets */
static void
dissect_gvrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti;
    proto_tree *gvrp_tree;
    guint16     protocol_id;
    guint8      octet;
    int         msg_index;
    int         attr_index;
    int         offset = 0;
    int         length = tvb_reported_length(tvb);

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

    col_set_str(pinfo->cinfo, COL_INFO, "GVRP");

    if (tree)
    {
        ti = proto_tree_add_item(tree, proto_gvrp, tvb, 0, length, ENC_NA);

        gvrp_tree = proto_item_add_subtree(ti, ett_gvrp);

        /* Read in GARP protocol ID */
        protocol_id = tvb_get_ntohs(tvb, GARP_PROTOCOL_ID);

        proto_tree_add_uint_format(gvrp_tree, hf_gvrp_proto_id, tvb,
                                   GARP_PROTOCOL_ID, sizeof(guint16),
                                   protocol_id,
                                   "Protocol Identifier: 0x%04x (%s)",
                                   protocol_id,
                                   protocol_id == GARP_DEFAULT_PROTOCOL_ID ?
                                     "GARP VLAN Registration Protocol" :
                                     "Unknown Protocol");

        /* Currently only one protocol ID is supported */
        if (protocol_id != GARP_DEFAULT_PROTOCOL_ID)
        {
            proto_tree_add_text(gvrp_tree, tvb, GARP_PROTOCOL_ID, sizeof(guint16),
                "   (Warning: this version of Wireshark only knows about protocol id = 1)");
            call_dissector(data_handle,
                tvb_new_subset(tvb, GARP_PROTOCOL_ID + sizeof(guint16), -1, -1),
                pinfo, tree);
            return;
        }

        offset += sizeof(guint16);
        length -= sizeof(guint16);

        msg_index = 0;

        /* Begin to parse GARP messages */
        while (length)
        {
            proto_item *msg_item;
            int         msg_start = offset;

            /* Read in attribute type. */
            octet = tvb_get_guint8(tvb, offset);

            /* Check for end of mark */
            if (octet == GARP_END_OF_MARK)
            {
                /* End of GARP PDU */
                if (msg_index)
                {
                    proto_tree_add_text(gvrp_tree, tvb, offset, sizeof(guint8),
                                        "End of mark");
                    break;
                }
                else
                {
                    call_dissector(data_handle,
                        tvb_new_subset_remaining(tvb, offset), pinfo, tree);
                    return;
                }
            }

            offset += sizeof(guint8);
            length -= sizeof(guint8);

            msg_item = proto_tree_add_text(gvrp_tree, tvb, msg_start, -1,
                                           "Message %d", msg_index + 1);

            proto_tree_add_uint(gvrp_tree, hf_gvrp_attribute_type, tvb,
                                msg_start, sizeof(guint8), octet);

            /* GVRP only supports one attribute type. */
            if (octet != GVRP_ATTRIBUTE_TYPE)
            {
                call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset),
                    pinfo, tree);
                return;
            }

            attr_index = 0;

            while (length)
            {
                int         attr_start = offset;
                proto_item *attr_item;

                /* Read in attribute length. */
                octet = tvb_get_guint8(tvb, offset);

                /* Check for end of mark */
                if (octet == GARP_END_OF_MARK)
                {
                    /* If at least one message has been already read,
                     * check for another end of mark.
                     */
                    if (attr_index)
                    {
                        proto_tree_add_text(gvrp_tree, tvb, offset,
                                            sizeof(guint8), "  End of mark");

                        offset += sizeof(guint8);
                        length -= sizeof(guint8);

                        proto_item_set_len(msg_item, offset - msg_start);
                        break;
                    }
                    else
                    {
                        call_dissector(data_handle,
                            tvb_new_subset_remaining(tvb, offset), pinfo, tree);
                        return;
                    }
                }
                else
                {
                    guint8 event;

                    offset += sizeof(guint8);
                    length -= sizeof(guint8);

                    attr_item = proto_tree_add_text(gvrp_tree, tvb,
                         attr_start, -1, "  Attribute %d", attr_index + 1);

                    proto_tree_add_uint(gvrp_tree, hf_gvrp_attribute_length,
                         tvb, attr_start, sizeof(guint8), octet);

                    /* Read in attribute event */
                    event = tvb_get_guint8(tvb, offset);

                    proto_tree_add_uint(gvrp_tree, hf_gvrp_attribute_event,
                         tvb, offset, sizeof(guint8), event);

                    offset += sizeof(guint8);
                    length -= sizeof(guint8);

                    switch (event) {

                    case GVRP_EVENT_LEAVEALL:
                        if (octet != GVRP_LENGTH_LEAVEALL)
                        {
                            call_dissector(data_handle,
                                tvb_new_subset_remaining(tvb, offset), pinfo,
                                tree);
                            return;
                        }
                        break;

                     case GVRP_EVENT_JOINEMPTY:
                     case GVRP_EVENT_JOININ:
                     case GVRP_EVENT_LEAVEEMPTY:
                     case GVRP_EVENT_LEAVEIN:
                     case GVRP_EVENT_EMPTY:
                        if (octet != GVRP_LENGTH_NON_LEAVEALL)
                        {
                            call_dissector(data_handle,
                                tvb_new_subset_remaining(tvb, offset),pinfo,
                                tree);
                            return;
                        }

                        /* Show attribute value */
                        proto_tree_add_item(gvrp_tree, hf_gvrp_attribute_value,
                            tvb, offset, sizeof(guint16), ENC_BIG_ENDIAN);

                        offset += sizeof(guint16);
                        length -= sizeof(guint16);
                        break;

                     default:
                        call_dissector(data_handle,
                            tvb_new_subset_remaining(tvb, offset), pinfo, tree);
                        return;
                    }
                }

                proto_item_set_len(attr_item, offset - attr_start);

                attr_index++;
            }

            msg_index++;
        }
    }
}
Пример #16
0
static int
dissect_data_segment(proto_tree *ltp_tree, tvbuff_t *tvb,packet_info *pinfo,int frame_offset,int ltp_type, guint64 session_num)
{
	guint64 client_id;
	guint64 data_offset;
	guint64 data_length;
	guint64 chkp_sno = 0;
	guint64 rpt_sno = 0;
	guint64 sda_client_id = 0;

	unsigned segment_size = 0;

	int sdnv_length;
	int sdnv_status;

	proto_tree *ltp_data_tree;
	proto_item *ti;

	fragment_head *frag_msg = NULL;
	gboolean more_frags = TRUE;

	tvbuff_t *new_tvb = NULL;

	/* Create a subtree for data segment and add the other fields under it */
	ltp_data_tree = proto_tree_add_subtree(ltp_tree, tvb, frame_offset, tvb_captured_length_remaining(tvb, frame_offset), ett_data_segm, NULL, "Data Segment");


	/* Client ID - 0 = Bundle Protocol, 1 = CCSDS LTP Service Data Aggregation */
	sdnv_status = evaluate_sdnv64(tvb, frame_offset, &sdnv_length, &client_id);
	ti = proto_tree_add_uint64_format_value(ltp_data_tree, hf_ltp_data_clid, tvb, frame_offset, sdnv_length, client_id,
						"%" G_GINT64_MODIFIER "u (%s)", client_id,
						val_to_str_const((const guint32) client_id, client_service_id_info, "Invalid"));
	if (!sdnv_status) {
		expert_add_info(pinfo, ti, &ei_ltp_sdnv_length);
		return 0;
	}
	frame_offset += sdnv_length;
	segment_size += sdnv_length;


	/* data segment offset */
	if ((sdnv_length = add_sdnv64_to_tree(ltp_data_tree, tvb, pinfo, frame_offset, hf_ltp_data_offset, &data_offset, &ti)) > 0) {
		frame_offset += sdnv_length;
		segment_size += sdnv_length;
	} else {
		return 0;
	}

	/* data segment length */
	if ((sdnv_length = add_sdnv64_to_tree(ltp_data_tree, tvb, pinfo, frame_offset, hf_ltp_data_length, &data_length, &ti)) > 0) {
		frame_offset += sdnv_length;
		segment_size += sdnv_length;

		/* add in the data length also */
		segment_size += (unsigned int) data_length;
	} else {
		return 0;
	}

	more_frags = FALSE;
	if (ltp_type != 0 && ltp_type < 4)
	{
		/* checkpoint serial number - 32 bits per CCSDS */
		if ((sdnv_length = add_sdnv64_to_tree(ltp_data_tree, tvb, pinfo, frame_offset, hf_ltp_data_chkp, &chkp_sno, &ti)) > 0) {
			frame_offset += sdnv_length;
			segment_size += sdnv_length;

			if (chkp_sno > 4294967295U) {
				/* just a warning - continue processing */
				expert_add_info(pinfo, ti, &ei_ltp_sno_larger_than_ccsds);
			}
		} else {
			return 0;
		}

		/* report serial number - 32 bits per CCSDS */
		if ((sdnv_length = add_sdnv64_to_tree(ltp_data_tree, tvb, pinfo, frame_offset, hf_ltp_data_rpt, &rpt_sno, &ti)) > 0) {
			frame_offset += sdnv_length;
			segment_size += sdnv_length;

			if (rpt_sno > 4294967295U) {
				/* just a warning - continue processing */
				expert_add_info(pinfo, ti, &ei_ltp_sno_larger_than_ccsds);
			}
		} else {
			return 0;
		}

	} else if (ltp_type != 7) {
		more_frags = TRUE;

	}

	if (segment_size >= tvb_captured_length(tvb)) {
		/* did not capture the entire packet */
		proto_tree_add_string(ltp_data_tree, hf_ltp_partial_packet, tvb, 0, 0, "<increase capture size?>");
		return tvb_captured_length(tvb);
	}

	frag_msg = fragment_add_check(&ltp_reassembly_table,
					tvb, frame_offset, pinfo, (guint32)session_num, NULL,
					(guint32)data_offset, (guint32)data_length, more_frags);

	if(frag_msg)
	{
		/* Checking if the segment is completely reassembled */
		if(!(frag_msg->flags & FD_PARTIAL_REASSEMBLY))
		{
			/* if the segment has not been fragmented, then no reassembly is needed */
			if(!more_frags && data_offset == 0)
			{
				new_tvb = tvb_new_subset_remaining(tvb, frame_offset);
			}
			else
			{
				new_tvb = process_reassembled_data(tvb, frame_offset, pinfo, "Reassembled LTP Segment",
									frag_msg, &ltp_frag_items,NULL, ltp_data_tree);

			}
		}
	}

	if(new_tvb)
	{
		int data_count = 1;

		int parse_length;
		int parse_offset = 0;
		parse_length = tvb_captured_length(new_tvb);
		while(parse_offset < parse_length)
		{
			int bundle_size;
			int sda_header_size;
			proto_tree *ltp_data_data_tree;
			tvbuff_t *datatvb;
			ltp_data_data_tree = proto_tree_add_subtree_format(ltp_data_tree, tvb,frame_offset, 0,
										ett_data_data_segm, NULL, "Data[%d]",data_count);

			sda_header_size = 0;
			if (client_id == 2) {
				sdnv_status = evaluate_sdnv64(tvb, frame_offset+parse_offset, &sdnv_length, &sda_client_id);
				ti = proto_tree_add_uint64_format_value(ltp_data_data_tree, hf_ltp_data_sda_clid, tvb, frame_offset+parse_offset, sdnv_length, sda_client_id,
									"%" G_GINT64_MODIFIER "u (%s)", sda_client_id, val_to_str_const((const guint32) sda_client_id, client_service_id_info, "Invalid"));

				if (!sdnv_status) {
					expert_add_info(pinfo, ti, &ei_ltp_sdnv_length);
					return 0;
				}

				sda_header_size = sdnv_length;

				parse_offset += sdnv_length;
				if (parse_offset == parse_length) {
					col_set_str(pinfo->cinfo, COL_INFO, "CCSDS LTP SDA Protocol Error");
					return 0;	/* Give up*/
				}
			}

			datatvb = tvb_new_subset_length_caplen(new_tvb, parse_offset, (int)parse_length - parse_offset, tvb_captured_length(new_tvb));
			bundle_size = call_dissector(bundle_handle, datatvb, pinfo, ltp_data_data_tree);
			if(bundle_size == 0) {  /*Couldn't parse bundle*/
				col_set_str(pinfo->cinfo, COL_INFO, "Dissection Failed");
				return 0;           /*Give up*/
			}

			/* update the length of the data set */
			proto_item_set_len(ltp_data_data_tree, bundle_size+sda_header_size);

			parse_offset += bundle_size;
			data_count++;
		}
	}
	else
	{
		if(frag_msg && more_frags)
		{
			col_append_frame_number(pinfo, COL_INFO, "[Reassembled in %d] ",frag_msg->reassembled_in);
		}
		else
		{
			col_append_str(pinfo->cinfo, COL_INFO, "[Unfinished LTP Segment] ");
		}

	}

	return segment_size;
}
static int
dissect_form_urlencoded(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
	proto_tree	*url_tree;
	proto_tree	*sub;
	proto_item	*ti;
	gint		offset = 0, next_offset;
	const char	*data_name;
	http_message_info_t *message_info;

	data_name = pinfo->match_string;
	if (! (data_name && data_name[0])) {
		/*
		 * No information from "match_string"
		 */
		message_info = (http_message_info_t *)data;
		if (message_info == NULL) {
			/*
			 * No information from dissector data
			 */
			data_name = NULL;
		} else {
			data_name = message_info->media_str;
			if (! (data_name && data_name[0])) {
				/*
				 * No information from dissector data
				 */
				data_name = NULL;
			}
		}
	}

	if (data_name)
		col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(%s)", data_name);

	ti = proto_tree_add_item(tree, hfi_urlencoded, tvb, 0, -1, ENC_NA);
	if (data_name)
		proto_item_append_text(ti, ": %s", data_name);
	url_tree = proto_item_add_subtree(ti, ett_form_urlencoded);

	while (tvb_reported_length_remaining(tvb, offset) > 0) {
		const int start_offset = offset;
		char *key, *value;

		sub = proto_tree_add_subtree(url_tree, tvb, offset, 0, ett_form_keyvalue, &ti, "Form item");

		next_offset = get_form_key_value(tvb, &key, offset, '=');
		if (next_offset == -1)
			break;
		proto_tree_add_string(sub, &hfi_form_key, tvb, offset, next_offset - offset, key);
		proto_item_append_text(sub, ": \"%s\"", key);

		offset = next_offset+1;

		next_offset = get_form_key_value(tvb, &value, offset, '&');
		if (next_offset == -1)
			break;
		proto_tree_add_string(sub, &hfi_form_value, tvb, offset, next_offset - offset, value);
		proto_item_append_text(sub, " = \"%s\"", value);

		offset = next_offset+1;

		proto_item_set_len(ti, offset - start_offset);
	}

	return tvb_captured_length(tvb);
}
Пример #18
0
static void
dissect_json(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree *json_tree = NULL;
	proto_item *ti = NULL;

	json_parser_data_t parser_data;
	tvbparse_t *tt;

	const char *data_name;
	int offset;

	data_name = pinfo->match_string;
	if (!(data_name && data_name[0])) {
		/*
		 * No information from "match_string"
		 */
		data_name = (char *)(pinfo->private_data);
		if (!(data_name && data_name[0])) {
			/*
			 * No information from "private_data"
			 */
			data_name = NULL;
		}
	}

	if (tree) {
		ti = proto_tree_add_item(tree, proto_json, tvb, 0, -1, ENC_NA);
		json_tree = proto_item_add_subtree(ti, ett_json);

		if (data_name)
			proto_item_append_text(ti, ": %s", data_name);
	}

	offset = 0;
	
	parser_data.stack = ep_stack_new();
	ep_stack_push(parser_data.stack, json_tree);

	tt = tvbparse_init(tvb, offset, -1, &parser_data, want_ignore);

	/* XXX, only one json in packet? */
	while ((tvbparse_get(tt, want)))
		;

	offset = tvbparse_curr_offset(tt);

	proto_item_set_len(ti, offset);

	/* if we have some unparsed data, pass to data-text-lines dissector (?) */
	if (tvb_length_remaining(tvb, offset) > 0) {
		int datalen, reported_datalen;
		tvbuff_t *next_tvb;
		
		datalen = tvb_length_remaining(tvb, offset);
		reported_datalen = tvb_reported_length_remaining(tvb, offset);

		next_tvb = tvb_new_subset(tvb, offset, datalen, reported_datalen);

		call_dissector(text_lines_handle, next_tvb, pinfo, tree);
	} else if (data_name) {
		col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(%s)", data_name);
	}
}
Пример #19
0
static void dissect_packetlogger (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_tree *packetlogger_tree = NULL;
  tvbuff_t   *next_tvb;
  proto_item *ti = NULL;
  guint8      pl_type;
  gint        len;

  col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME);
  col_clear (pinfo->cinfo, COL_INFO);

  ti = proto_tree_add_item (tree, proto_packetlogger, tvb, 0, -1, ENC_NA);
  packetlogger_tree = proto_item_add_subtree (ti, ett_packetlogger);

  pl_type = tvb_get_guint8 (tvb, 0);
  proto_tree_add_item (packetlogger_tree, hf_type, tvb, 0, 1, ENC_BIG_ENDIAN);
  proto_item_append_text (ti, " %s", val_to_str (pl_type, type_vals, "Unknown 0x%02x"));

  len = tvb_length_remaining (tvb, 1);
  next_tvb = tvb_new_subset (tvb, 1, len, len);

  if (pl_type <= PKT_RECV_ACL_DATA) {
    /* HCI H1 packages */
    switch (pl_type) {
    case PKT_HCI_COMMAND:
      pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_COMMAND;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_SENT;
      pinfo->p2p_dir = P2P_DIR_SENT;
      break;
    case PKT_HCI_EVENT:
      pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_EVENT;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_RECV;
      pinfo->p2p_dir = P2P_DIR_RECV;
      break;
    case PKT_SENT_ACL_DATA:
      pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_SENT;
      pinfo->p2p_dir = P2P_DIR_SENT;
      break;
    case PKT_RECV_ACL_DATA:
      pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_RECV;
      pinfo->p2p_dir = P2P_DIR_RECV;
      break;
    default:
      pinfo->pseudo_header->bthci.channel = pl_type;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_UNKNOWN;
      pinfo->p2p_dir = P2P_DIR_UNKNOWN;
      break;
    }
    proto_item_set_len (ti, 1);

    col_add_fstr (pinfo->cinfo, COL_INFO, "%s", val_to_str(pl_type, type_vals, "Unknown 0x%02x"));
    if (!dissector_try_uint (hci_h1_table, pinfo->pseudo_header->bthci.channel, next_tvb, pinfo, tree)) {
      call_dissector (data_handle, next_tvb, pinfo, tree);
    }
  } else {
    /* PacketLogger data */
    switch (pl_type) {
    case PKT_POWER:
    case PKT_NOTE:
    case PKT_NEW_CONTROLLER:
      proto_tree_add_item (packetlogger_tree, hf_info, next_tvb, 0, len, ENC_ASCII|ENC_NA);
      col_add_fstr (pinfo->cinfo, COL_INFO, "%s", tvb_format_stringzpad_wsp (next_tvb, 0, len));
      break;
    default:
      call_dissector (data_handle, next_tvb, pinfo, tree);
      col_add_fstr (pinfo->cinfo, COL_INFO, "Unknown 0x%02x", pl_type);
      break;
    }
  }
}
Пример #20
0
static int
dissect_nbipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
	gboolean	has_routes;
	proto_tree	*nbipx_tree = NULL;
	proto_item	*ti = NULL;
	int		offset = 0;
	guint8		packet_type;
	proto_tree	*name_type_flag_tree;
	proto_item	*tf;
	char		name[(NETBIOS_NAME_LEN - 1)*4 + 1];
	int		name_type;
	gboolean	has_payload;
	tvbuff_t	*next_tvb;
	ipxhdr_t *ipxh;

	/* Reject the packet if data is NULL */
	if (data == NULL)
		return 0;
	ipxh = (ipxhdr_t*)data;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBIPX");
	col_clear(pinfo->cinfo, COL_INFO);

	if (ipxh->ipx_type == IPX_PACKET_TYPE_WANBCAST) {
		/*
		 * This is a WAN Broadcast packet; we assume it will have
		 * 8 IPX addresses at the beginning.
		 */
		has_routes = TRUE;
	} else {
		/*
		 * This isn't a WAN Broadcast packet, but it still might
		 * have the 8 addresses.
		 *
		 * If it's the right length for a name operation,
		 * and, if we assume it has routes, the packet type
		 * is a name operation, assume it has routes.
		 *
		 * NOTE: this will throw an exception if the byte that
		 * would be the packet type byte if this has the 8
		 * addresses isn't present; if that's the case, we don't
		 * know how to interpret this packet, so we can't dissect
		 * it anyway.
		 */
		has_routes = FALSE;	/* start out assuming it doesn't */
		if (tvb_reported_length(tvb) == 50) {
			packet_type = tvb_get_guint8(tvb, offset + 32 + 1);
			switch (packet_type) {

			case NBIPX_FIND_NAME:
			case NBIPX_NAME_RECOGNIZED:
			case NBIPX_CHECK_NAME:
			case NBIPX_NAME_IN_USE:
			case NBIPX_DEREGISTER_NAME:
				has_routes = TRUE;
				break;
			}
		}
	}

	if (tree) {
		ti = proto_tree_add_item(tree, proto_nbipx, tvb, 0,
		    -1, ENC_NA);
		nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
	}

	if (has_routes) {
		if (tree)
			add_routers(nbipx_tree, tvb, 0);
		offset += 32;
	}

	packet_type = tvb_get_guint8(tvb, offset + 1);

	switch (packet_type) {

	case NBIPX_FIND_NAME:
	case NBIPX_NAME_RECOGNIZED:
	case NBIPX_CHECK_NAME:
	case NBIPX_NAME_IN_USE:
	case NBIPX_DEREGISTER_NAME:
		name_type = get_netbios_name(tvb, offset+2, name, (NETBIOS_NAME_LEN - 1)*4 + 1);
		col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s<%02x>",
				val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"),
				name, name_type);

		if (nbipx_tree) {
			tf = proto_tree_add_item(nbipx_tree, hf_nbipx_name_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			name_type_flag_tree = proto_item_add_subtree(tf, ett_nbipx_name_type_flags);

			proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_group, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_in_use, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_registered, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_duplicated, tvb, offset, 1, ENC_LITTLE_ENDIAN);
			proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_deregistered, tvb, offset, 1, ENC_LITTLE_ENDIAN);
		}
		offset += 1;

		proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type);
		offset += 1;

		if (nbipx_tree)
			netbios_add_name("Name", tvb, offset, nbipx_tree);
		offset += NETBIOS_NAME_LEN;

		/*
		 * No payload to be interpreted by another protocol.
		 */
		has_payload = FALSE;
		break;

	case NBIPX_SESSION_DATA:
	case NBIPX_SESSION_END:
	case NBIPX_SESSION_END_ACK:
		col_set_str(pinfo->cinfo, COL_INFO,
				val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"));

		dissect_conn_control(tvb, offset, nbipx_tree);
		offset += 1;

		proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type);
		offset += 1;

		proto_tree_add_item(nbipx_tree, hf_nbipx_session_src_conn_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset += 2;

		proto_tree_add_item(nbipx_tree, hf_nbipx_session_dest_conn_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset += 2;

		proto_tree_add_item(nbipx_tree, hf_nbipx_session_send_seq_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset += 2;

		proto_tree_add_item(nbipx_tree, hf_nbipx_session_total_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset += 2;

		proto_tree_add_item(nbipx_tree, hf_nbipx_session_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset += 2;

		proto_tree_add_item(nbipx_tree, hf_nbipx_session_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset += 2;

		proto_tree_add_item(nbipx_tree, hf_nbipx_session_recv_seq_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset += 2;

		proto_tree_add_item(nbipx_tree, hf_nbipx_session_bytes_received, tvb, offset, 2, ENC_LITTLE_ENDIAN);
		offset += 2;

		/*
		 * We may have payload to dissect.
		 */
		has_payload = TRUE;
		break;

	case NBIPX_DIRECTED_DATAGRAM:
		col_set_str(pinfo->cinfo, COL_INFO,
				val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"));

		dissect_conn_control(tvb, offset, nbipx_tree);
		offset += 1;

		proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type);
		offset += 1;

		if (nbipx_tree)
			netbios_add_name("Receiver's Name", tvb, offset,
			    nbipx_tree);
		offset += NETBIOS_NAME_LEN;

		if (nbipx_tree)
			netbios_add_name("Sender's Name", tvb, offset,
			    nbipx_tree);
		offset += NETBIOS_NAME_LEN;

		/*
		 * We may have payload to dissect.
		 */
		has_payload = TRUE;
		break;

	default:
		col_set_str(pinfo->cinfo, COL_INFO,
				val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"));

		/*
		 * We don't know what the first byte is.
		 */
		offset += 1;

		/*
		 * The second byte is a data stream type byte.
		 */
		proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type);
		offset += 1;

		/*
		 * We don't know what the rest of the packet is.
		 */
		has_payload = FALSE;
	}

	/*
	 * Set the length of the NBIPX tree item.
	 */
	if (ti != NULL)
		proto_item_set_len(ti, offset);

	if (has_payload && tvb_offset_exists(tvb, offset)) {
		next_tvb = tvb_new_subset_remaining(tvb, offset);
		dissect_netbios_payload(next_tvb, pinfo, tree);
	}

	return tvb_captured_length(tvb);
}
Пример #21
0
static void
client_display_socks_v5(tvbuff_t *tvb, int offset, packet_info *pinfo,
    proto_tree *tree, socks_hash_entry_t *hash_info, sock_state_t* state_info) {

/* Display the protocol tree for the version. This routine uses the */
/* stored conversation information to decide what to do with the row.   */
/* Per packet information would have been better to do this, but we */
/* didn't have that when I wrote this. And I didn't expect this to get  */
/* so messy.                                */

    unsigned int  i;
    const char   *AuthMethodStr;
    sock_state_t  new_state_info;

    /* Either there is an error, or we're done with the state machine
      (so there's nothing to display) */
    if (state_info == NULL)
        return;

    proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
    offset += 1;

    if (state_info->client == clientStart)
    {
        proto_tree      *AuthTree;
        proto_item      *ti;
        guint8 num_auth_methods, auth;

        ti = proto_tree_add_text( tree, tvb, offset, -1, "Client Authentication Methods");
        AuthTree = proto_item_add_subtree(ti, ett_socks_auth);

        num_auth_methods = tvb_get_guint8(tvb, offset);
        proto_item_set_len(ti, num_auth_methods+1);

        proto_tree_add_item( AuthTree, hf_client_auth_method_count, tvb, offset, 1, ENC_NA);
        offset += 1;

        for( i = 0; i  < num_auth_methods; ++i) {
            auth = tvb_get_guint8( tvb, offset);
            AuthMethodStr = get_auth_method_name(auth);

            proto_tree_add_uint_format(AuthTree, hf_client_auth_method, tvb, offset, 1, auth,
                                        "Method[%u]: %u (%s)", i, auth, AuthMethodStr);
            offset += 1;
        }

        if ((num_auth_methods == 1) &&
            (tvb_bytes_exist(tvb, offset + 2, 1)) &&
            (tvb_get_guint8(tvb, offset + 2) == 0) &&
            (tvb_reported_length_remaining(tvb, offset + 2 + num_auth_methods) > 0)) {
                new_state_info.client = clientV5Command;
                client_display_socks_v5(tvb, offset, pinfo, tree, hash_info, &new_state_info);
        }
    }
    else if (state_info->client == clientV5Command) {

        proto_tree_add_item( tree, hf_socks_cmd, tvb, offset, 1, ENC_NA);
        offset += 1;

        proto_tree_add_item( tree, hf_socks_reserved, tvb, offset, 1, ENC_NA);
        offset += 1;

        offset = display_address(tvb, offset, tree);
        proto_tree_add_item( tree, hf_client_port, tvb, offset, 2, ENC_BIG_ENDIAN);
    }
    else if ((state_info->client == clientWaitForAuthReply) &&
             (state_info->server == serverInitReply)) {
        guint16 len;
        gchar* str;

        switch(hash_info->authentication_method)
        {
        case NO_AUTHENTICATION:
            break;
        case USER_NAME_AUTHENTICATION:
            /* process user name */
            len = tvb_get_guint8(tvb, offset);
            str = tvb_get_string(wmem_packet_scope(), tvb, offset+1, len);
            proto_tree_add_string(tree, hf_socks_username, tvb, offset, len+1, str);
            offset += (len+1);

            len = tvb_get_guint8(tvb, offset);
            str = tvb_get_string(wmem_packet_scope(), tvb, offset+1, len);
            proto_tree_add_string(tree, hf_socks_password, tvb, offset, len+1, str);
            /* offset += (len+1); */
            break;
        case GSS_API_AUTHENTICATION:
            proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, ENC_BIG_ENDIAN);
            proto_tree_add_item( tree, hf_gssapi_length, tvb, offset+1, 2, ENC_BIG_ENDIAN);
            len = tvb_get_ntohs(tvb, offset+1);
            if (len > 0)
                proto_tree_add_item( tree, hf_gssapi_payload, tvb, offset+3, len, ENC_NA);
            break;
        default:
            break;
        }
    }
}
Пример #22
0
static void
dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *ti;
	proto_item *ct;
	proto_tree *bacnet_tree;
	proto_tree *control_tree;

	gint offset;
	guint8 bacnet_version;
	guint8 bacnet_control;
	guint8 bacnet_dlen;
	guint8 bacnet_slen;
	guint8 bacnet_mesgtyp;
	guint8 bacnet_rejectreason;
	guint8 bacnet_rportnum;
	guint8 bacnet_pinfolen;
	guint8 i;
	tvbuff_t *next_tvb;
	guint32 vendor_id;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-NPDU");

	col_set_str(pinfo->cinfo, COL_INFO, "Building Automation and Control Network NPDU");

	offset = 0;
	bacnet_version = tvb_get_guint8(tvb, offset);
	bacnet_control = tvb_get_guint8(tvb, offset+1);

	/* I don't know the length of the NPDU yet; Setting the length after dissection */
	ti = proto_tree_add_item(tree, proto_bacnet, tvb, 0, -1, ENC_NA);

	bacnet_tree = proto_item_add_subtree(ti, ett_bacnet);

	proto_tree_add_uint_format_value(bacnet_tree, hf_bacnet_version, tvb,
					 offset, 1,
					 bacnet_version,"0x%02x (%s)",bacnet_version,
					 (bacnet_version == 0x01)?"ASHRAE 135-1995":"unknown");
	offset ++;
	ct = proto_tree_add_uint(bacnet_tree, hf_bacnet_control,
		tvb, offset, 1, bacnet_control);
	control_tree = proto_item_add_subtree(ct, ett_bacnet_control);
	proto_tree_add_boolean(control_tree, hf_bacnet_control_net,
		tvb, offset, 1, bacnet_control);
	proto_tree_add_boolean(control_tree, hf_bacnet_control_res1, tvb,
		offset, 1, bacnet_control);
	proto_tree_add_boolean(control_tree, hf_bacnet_control_dest, tvb,
		offset, 1, bacnet_control);
	proto_tree_add_boolean(control_tree, hf_bacnet_control_res2, tvb,
		offset, 1, bacnet_control);
	proto_tree_add_boolean(control_tree, hf_bacnet_control_src, tvb,
		offset, 1, bacnet_control);
	proto_tree_add_boolean(control_tree, hf_bacnet_control_expect, tvb,
		offset, 1, bacnet_control);
	proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_high,
		tvb, offset, 1, bacnet_control);
	proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_low,
		tvb, offset, 1, bacnet_control);
	offset ++;
	if (bacnet_control & BAC_CONTROL_DEST) { /* DNET, DLEN, DADR */
		proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
			tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;
		bacnet_dlen = tvb_get_guint8(tvb, offset);
		/* DLEN = 0 is broadcast on dest.network */
		if( bacnet_dlen == 0) {
			/* append to hf_bacnet_dlen: broadcast */
			proto_tree_add_uint_format_value(bacnet_tree,
			    hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen,
			    "%d indicates Broadcast on Destination Network",
			    bacnet_dlen);
			offset ++;
			/* going to SNET */
		} else if (bacnet_dlen==6) {
			proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
				tvb, offset, 1, bacnet_dlen);
			offset ++;
			/* Ethernet MAC */
			proto_tree_add_item(bacnet_tree,
				hf_bacnet_dadr_eth, tvb, offset,
				bacnet_dlen, ENC_NA);
			offset += bacnet_dlen;
		} else if (bacnet_dlen==1) {
			proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
				tvb, offset, 1, bacnet_dlen);
			offset ++;
			/* MS/TP or ARCNET MAC */
			proto_tree_add_item(bacnet_tree,
				hf_bacnet_dadr_mstp, tvb, offset,
				bacnet_dlen, ENC_BIG_ENDIAN);
			offset += bacnet_dlen;
		} else if (bacnet_dlen<7) {
			proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
				tvb, offset, 1, bacnet_dlen);
			offset ++;
			/* Other MAC formats should be included here */
			proto_tree_add_item(bacnet_tree,
				hf_bacnet_dadr_tmp, tvb, offset,
				bacnet_dlen, ENC_NA);
			offset += bacnet_dlen;
		} else {
			proto_tree_add_uint_format_value(bacnet_tree,
			    hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen,
			    "%d invalid!",
			    bacnet_dlen);
		}
	}
	if (bacnet_control & BAC_CONTROL_SRC) { /* SNET, SLEN, SADR */
		/* SNET */
		proto_tree_add_uint(bacnet_tree, hf_bacnet_snet,
			tvb, offset, 2, tvb_get_ntohs(tvb, offset));
		offset += 2;
		bacnet_slen = tvb_get_guint8(tvb, offset);
		if( bacnet_slen == 0) { /* SLEN = 0 invalid */
			proto_tree_add_uint_format_value(bacnet_tree,
			    hf_bacnet_slen, tvb, offset, 1, bacnet_slen,
			    "%d invalid!",
			    bacnet_slen);
			offset ++;
		} else if (bacnet_slen==6) {
			/* SLEN */
			 proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
				tvb, offset, 1, bacnet_slen);
			offset ++;
			/* Ethernet MAC */
			proto_tree_add_item(bacnet_tree,
				hf_bacnet_sadr_eth, tvb, offset,
				bacnet_slen, ENC_NA);
			offset += bacnet_slen;
		} else if (bacnet_slen==1) {
			/* SLEN */
			 proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
				tvb, offset, 1, bacnet_slen);
			offset ++;
			/* MS/TP or ARCNET MAC */
			proto_tree_add_item(bacnet_tree,
				hf_bacnet_sadr_mstp, tvb, offset,
				bacnet_slen, ENC_BIG_ENDIAN);
			offset += bacnet_slen;
		} else if (bacnet_slen<6) { /* LON MAC */
			/* SLEN */
			 proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
				tvb, offset, 1, bacnet_slen);
			offset ++;
			/* Other MAC formats should be included here */
			proto_tree_add_item(bacnet_tree,
				hf_bacnet_sadr_tmp, tvb, offset,
				bacnet_slen, ENC_NA);
			offset += bacnet_slen;
		} else {
			proto_tree_add_uint_format_value(bacnet_tree,
			hf_bacnet_slen, tvb, offset, 1, bacnet_slen,
			    "%d invalid!",
			    bacnet_slen);
			offset ++;
		}
	}
	if (bacnet_control & BAC_CONTROL_DEST) { /* Hopcount */
		proto_tree_add_item(bacnet_tree, hf_bacnet_hopc,
			tvb, offset, 1, ENC_BIG_ENDIAN);
		offset ++;
	}
	/* Network Layer Message Type */
	if (bacnet_control & BAC_CONTROL_NET) {
		bacnet_mesgtyp =  tvb_get_guint8(tvb, offset);
		proto_tree_add_uint_format_value(bacnet_tree,
		hf_bacnet_mesgtyp, tvb, offset, 1, bacnet_mesgtyp,
			"%02x (%s)", bacnet_mesgtyp,
			bacnet_mesgtyp_name(bacnet_mesgtyp));
		/* Put the NPDU Type in the info column */
		col_add_str(pinfo->cinfo, COL_INFO,
			    bacnet_mesgtyp_name(bacnet_mesgtyp));
		offset ++;
		/* Vendor ID
		* The standard says: "If Bit 7 of the control octet is 1 and
		* the Message Type field contains a value in the range
		* X'80' - X'FF', then a Vendor ID field shall be present (...)."
		* We should not go any further in dissecting the packet if it's
		* not present, but we don't know about that: No length field...
		*/
		if (bacnet_mesgtyp > 0x7f) {
			/* Note: our next_tvb includes message type and vendor id! */
			next_tvb = tvb_new_subset_remaining(tvb, offset-1);
			vendor_id = tvb_get_ntohs(tvb, offset);
			proto_tree_add_uint(bacnet_tree, hf_bacnet_vendor, tvb,
					offset, 2, vendor_id);
			offset += 2;	/* vendor_id */
			if (dissector_try_uint(bacnet_dissector_table,
					vendor_id, next_tvb, pinfo, bacnet_tree)) {
					/* we parsed it so skip over length and we are done */
					/* Note: offset has now been bumped for message type and vendor id so we take that out of our next_tvb size */
					offset += tvb_length(next_tvb) -3;
			}
		}
		/* Performance Index (in I-Could-Be-Router-To-Network) */
		if (bacnet_mesgtyp == BAC_NET_ICB_R) {
			proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			proto_tree_add_item(bacnet_tree, hf_bacnet_perf,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset ++;
		}
		/* Reason, DNET (in Reject-Message-To-Network) */
		if (bacnet_mesgtyp == BAC_NET_REJ) {
			bacnet_rejectreason = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint_format_value(bacnet_tree,
				hf_bacnet_rejectreason,
				tvb, offset, 1,
				bacnet_rejectreason, "%d (%s)",
				bacnet_rejectreason,
				bacnet_rejectreason_name(bacnet_rejectreason));
			offset ++;
			proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
		}
		/* N*DNET (in Router-Busy-To-Network,Router-Available-To-Network) */
		if ((bacnet_mesgtyp == BAC_NET_R_BUSY) ||
			(bacnet_mesgtyp == BAC_NET_WHO_R) ||
			(bacnet_mesgtyp == BAC_NET_R_AVA) ||
			(bacnet_mesgtyp == BAC_NET_IAM_R) ) {
			while(tvb_reported_length_remaining(tvb, offset) > 1 ) {
				proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
					tvb, offset, 2, ENC_BIG_ENDIAN);
				offset += 2;
			}
		}
		/* Initialize-Routing-Table */
		if ( (bacnet_mesgtyp == BAC_NET_INIT_RTAB) ||
			(bacnet_mesgtyp == BAC_NET_INIT_RTAB_ACK) ) {
			bacnet_rportnum = tvb_get_guint8(tvb, offset);
			/* number of ports */
			proto_tree_add_uint(bacnet_tree, hf_bacnet_rportnum,
				tvb, offset, 1, bacnet_rportnum);
			offset ++;
			for(i=0; i<bacnet_rportnum; i++) {
					/* Connected DNET */
					proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
					tvb, offset, 2, ENC_BIG_ENDIAN);
					offset += 2;
					/* Port ID */
					proto_tree_add_item(bacnet_tree, hf_bacnet_portid,
					tvb, offset, 1, ENC_BIG_ENDIAN);
					offset ++;
					/* Port Info Length */
					bacnet_pinfolen = tvb_get_guint8(tvb, offset);
					proto_tree_add_uint(bacnet_tree, hf_bacnet_pinfolen,
					tvb, offset, 1, bacnet_pinfolen);
					offset ++;
					proto_tree_add_text(bacnet_tree, tvb, offset,
					bacnet_pinfolen, "Port Info: %s",
					tvb_bytes_to_str(tvb, offset, bacnet_pinfolen));
					offset += bacnet_pinfolen;
			}
		}
		/* Establish-Connection-To-Network */
		if (bacnet_mesgtyp == BAC_NET_EST_CON) {
			proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
			proto_tree_add_item(bacnet_tree, hf_bacnet_term_time_value,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset ++;
		}
		/* Disconnect-Connection-To-Network */
		if (bacnet_mesgtyp == BAC_NET_DISC_CON) {
			proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
				tvb, offset, 2, ENC_BIG_ENDIAN);
			offset += 2;
		}
	}
	/* Now set NPDU length */
	proto_item_set_len(ti, offset);

	/* dissect BACnet APDU */
	next_tvb = tvb_new_subset_remaining(tvb,offset);
	if (bacnet_control & BAC_CONTROL_NET) {
		/* Unknown function - dissect the payload as data */
		call_dissector(data_handle, next_tvb, pinfo, tree);
	} else {
		/* APDU - call the APDU dissector */
		call_dissector(bacapp_handle, next_tvb, pinfo, tree);
	}
}
Пример #23
0
/*FUNCTION:------------------------------------------------------
 *  NAME
 *      zdp_parse_bind_table_entry
 *  DESCRIPTION
 *      Parses and displays a single binding table entry.
 *  PARAMETERS
 *      tvbuff_t *tvb       - pointer to buffer containing raw packet.
 *      packet_into *pinfo  - pointer to packet information fields
 *      proto_tree *tree    - pointer to data tree Wireshark uses to display packet.
 *  RETURNS
 *      void
 *---------------------------------------------------------------
 */
void
zdp_parse_bind_table_entry(proto_tree *tree, tvbuff_t *tvb, guint *offset, packet_info *pinfo)
{
    proto_item      *ti = NULL;
    guint           len = 0;

    guint64 src64;
    guint8  src_ep;
    guint16 cluster;
    guint8  mode;
    guint64 dst64;
    guint16 dst;
    guint8  dst_ep;

    /* Add the source address. */
    src64 = tvb_get_letoh64(tvb, *offset + len);
    if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "Bind {Src: %s", get_eui64_name(src64));
    len += sizeof(guint64);

    /* Add the source endpoint. */
    src_ep = tvb_get_guint8(tvb, *offset + len);
    if (tree) proto_item_append_text(ti, ", Src Endpoint: %d", src_ep);
    len += sizeof(guint8);

    /* Add the cluster ID. */
    if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
        cluster = tvb_get_letohs(tvb, *offset + len);
        len += sizeof(guint16);
    }
    else {
        cluster = tvb_get_guint8(tvb, *offset + len);
        len += sizeof(guint8);
    }
    if (tree) proto_item_append_text(ti, ", Cluster: %d", cluster);

    /* Get the destination address mode. */
    if (pinfo->zbee_stack_vers >= ZBEE_VERSION_2007) {
        mode = tvb_get_guint8(tvb, *offset + len);
        len += sizeof(guint8);
    }
    else {
        /* Mode field doesn't exist and always uses unicast in 2003 & earlier. */
        mode = ZBEE_ZDP_ADDR_MODE_UNICAST;
    }

    /* Add the destination address. */
    if (mode == ZBEE_ZDP_ADDR_MODE_GROUP) {
        dst = tvb_get_letohs(tvb, *offset + len);
        if (tree) proto_item_append_text(ti, ", Dst: 0x%04x}", dst);
        len += sizeof(guint16);
    }
    else if (mode == ZBEE_ZDP_ADDR_MODE_UNICAST) {
        dst64 = tvb_get_letoh64(tvb, *offset + len);
        if (tree) proto_item_append_text(ti, ", Dst: %s", get_eui64_name(dst64));
        len += sizeof(guint64);

        dst_ep = tvb_get_guint8(tvb, *offset + len);
        if (tree) proto_item_append_text(ti, ", Dst Endpoint: %d}", dst_ep);
        len += sizeof(guint8);
    }
    else {
        if (tree) proto_item_append_text(ti, "}");
    }

    if (tree) {
        proto_item_set_len(ti, len);
    }
    *offset += len;
} /* zdp_parse_bind_table_entry */
static int
dissect_rs_pgo_query_key_t (tvbuff_t * tvb, int offset,
                            packet_info * pinfo, proto_tree * parent_tree,
                            dcerpc_info *di, guint8 * drep)
{

  enum
  {
    rs_pgo_query_name,
    rs_pgo_query_id,
    rs_pgo_query_unix_num,
    rs_pgo_query_next,
    rs_pgo_query_none
  };
/*
    typedef union switch (rs_pgo_query_t query) tagged_union {
        case rs_pgo_query_name:
            sec_rgy_name_t              name;

        case rs_pgo_query_id:
            rs_pgo_id_key_t             id_key;

        case rs_pgo_query_unix_num:
            rs_pgo_unix_num_key_t       unix_num_key;

        case rs_pgo_query_next:
            sec_rgy_name_t              scope;

        default:
            ;                       * empty branch of union *

    } rs_pgo_query_key_t;
*/


  proto_item *item = NULL;
  proto_tree *tree = NULL;
  int old_offset = offset;
  guint16 query_t;

  if (di->conformant_run)
    {
      return offset;
    }


  if (parent_tree)
    {
      item =
        proto_tree_add_text (parent_tree, tvb, offset, -1,
                             "rs_pgo_query_key_t ");
      tree = proto_item_add_subtree (item, ett_rs_pgo_query_key_t);
    }
  offset =
    dissect_ndr_uint16 (tvb, offset, pinfo, tree, di, drep, hf_rs_pgo_query_key_t,
                        &query_t);
  col_append_str (pinfo->cinfo, COL_INFO, " rs_pgo_query_key_t:");
  offset += 4;
  switch (query_t)
    {
    case rs_pgo_query_name:
      col_append_str (pinfo->cinfo, COL_INFO, "NAME");
      offset = dissect_sec_rgy_name_t (tvb, offset, pinfo, tree, di, drep);
      break;
    case rs_pgo_query_id:
      col_append_str (pinfo->cinfo, COL_INFO, "ID");
      offset = dissect_rs_pgo_id_key_t (tvb, offset, pinfo, tree, di, drep);
      break;
    case rs_pgo_query_unix_num:
      col_append_str (pinfo->cinfo, COL_INFO, "UNIX_NUM");
      offset = dissect_rs_pgo_unix_num_key_t (tvb, offset, pinfo, tree, di, drep);
      break;
    case rs_pgo_query_next:
      col_append_str (pinfo->cinfo, COL_INFO, "NEXT");
      offset = dissect_sec_rgy_name_t (tvb, offset, pinfo, tree, di, drep);
      break;
    case rs_pgo_query_none:
      col_append_str (pinfo->cinfo, COL_INFO, "NONE");
      break;

    default:
      col_append_fstr (pinfo->cinfo, COL_INFO, " unknown:%u", query_t);
      break;
    }

  proto_item_set_len (item, offset - old_offset);
  return offset;
}
Пример #25
0
/*
 * Process a multipart body-part:
 *      MIME-part-headers [ line-end *OCTET ]
 *      line-end dashed-boundary transport-padding line-end
 *
 * If applicable, call a media subdissector.
 *
 * Return the offset to the start of the next body-part.
 */
static gint
process_body_part(proto_tree *tree, tvbuff_t *tvb, const guint8 *boundary,
        gint boundary_len, packet_info *pinfo, gint start,
        gboolean *last_boundary)
{
    proto_tree *subtree;
    proto_item *ti;
    gint offset = start, next_offset = 0;
    char *parameters = NULL;
    gint body_start, boundary_start, boundary_line_len;

    gchar *content_type_str = NULL;
    gchar *content_encoding_str = NULL;
    char *filename = NULL;
    char *mimetypename = NULL;
    int  len = 0;
    gboolean last_field = FALSE;

    ti = proto_tree_add_item(tree, hf_multipart_part, tvb, start, 0, ENC_ASCII|ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_multipart_body);

    /*
     * Process the MIME-part-headers
     */

    while (!last_field)
    {
        gint colon_offset;
        char *hdr_str;
        char *header_str;

        /* Look for the end of the header (denoted by cr)
         * 3:d argument to imf_find_field_end() maxlen; must be last offset in the tvb.
         */
        next_offset = imf_find_field_end(tvb, offset, tvb_length_remaining(tvb, offset)+offset, &last_field);
        /* If cr not found, won't have advanced - get out to avoid infinite loop! */
        if (next_offset == offset) {
            break;
        }

        hdr_str = tvb_get_string(wmem_packet_scope(), tvb, offset, next_offset - offset);

        header_str = unfold_and_compact_mime_header(hdr_str, &colon_offset);
        if (colon_offset <= 0) {
           proto_tree_add_text(subtree, tvb, offset, next_offset - offset,
                 "%s",
                 tvb_format_text(tvb, offset, next_offset - offset));
        } else {
            gint hf_index;

            /* Split header name from header value */
            header_str[colon_offset] = '\0';
            hf_index = is_known_multipart_header(header_str, colon_offset);

            if (hf_index == -1) {
               proto_tree_add_text(subtree, tvb, offset,
                     next_offset - offset,
                     "%s",
                     tvb_format_text(tvb, offset, next_offset - offset));
            } else {
                char *value_str = header_str + colon_offset + 1;

                proto_tree_add_string_format(subtree,
                      hf_header_array[hf_index], tvb,
                      offset, next_offset - offset,
                      (const char *)value_str, "%s",
                      tvb_format_text(tvb, offset, next_offset - offset));

                switch (hf_index) {
                    case POS_CONTENT_TYPE:
                        {
                            /* The Content-Type starts at colon_offset + 1 */
                            gint semicolon_offset = index_of_char(
                                    value_str, ';');

                            if (semicolon_offset > 0) {
                                value_str[semicolon_offset] = '\0';
                                parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1);
                            } else {
                                parameters = NULL;
                            }

                            content_type_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1);

                            /* Show content-type in root 'part' label */
                            proto_item_append_text(ti, " (%s)", content_type_str);

                            /* find the "name" parameter in case we don't find a content disposition "filename" */
                            if((mimetypename = find_parameter(parameters, "name=", &len)) != NULL) {
                              mimetypename = g_strndup(mimetypename, len);
                            }
                        }


                        break;
                        case POS_CONTENT_TRANSFER_ENCODING:
                        {
                            /* The Content-Transfeing starts at colon_offset + 1 */
                            gint cr_offset = index_of_char(value_str, '\r');

                            if (cr_offset > 0) {
                                value_str[cr_offset] = '\0';
                            }

                            content_encoding_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1);
                        }
                        break;
                        case POS_CONTENT_DISPOSITION:
                            {
                            /* find the "filename" parameter */
                            if((filename = find_parameter(value_str, "filename=", &len)) != NULL) {
                                filename = g_strndup(filename, len);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        offset = next_offset;
    }

    body_start = next_offset;

    /*
     * Process the body
     */

    boundary_start = find_next_boundary(tvb, body_start, boundary, boundary_len,
            &boundary_line_len, last_boundary);
    if (boundary_start > 0) {
        gint body_len = boundary_start - body_start;
        tvbuff_t *tmp_tvb = tvb_new_subset(tvb, body_start,
                body_len, body_len);

        if (content_type_str) {

            /*
             * subdissection
             */
            void *save_private_data = pinfo->private_data;
            gboolean dissected;

            /*
             * Try and remove any content transfer encoding so that each sub-dissector
             * doesn't have to do it itself
             *
             */

            if(content_encoding_str && remove_base64_encoding) {

                if(!g_ascii_strncasecmp(content_encoding_str, "base64", 6))
                    tmp_tvb = base64_decode(pinfo, tmp_tvb, filename ? filename : (mimetypename ? mimetypename : content_type_str));

            }

            pinfo->private_data = parameters;
            /*
             * First try the dedicated multipart dissector table
             */
            dissected = dissector_try_string(multipart_media_subdissector_table,
                        content_type_str, tmp_tvb, pinfo, subtree, NULL);
            if (! dissected) {
                /*
                 * Fall back to the default media dissector table
                 */
                dissected = dissector_try_string(media_type_dissector_table,
                        content_type_str, tmp_tvb, pinfo, subtree, NULL);
            }
            if (! dissected) {
                const char *save_match_string = pinfo->match_string;
                pinfo->match_string = content_type_str;
                call_dissector(media_handle, tmp_tvb, pinfo, subtree);
                pinfo->match_string = save_match_string;
            }
            pinfo->private_data = save_private_data;
            parameters = NULL; /* Shares same memory as content_type_str */
        } else {
            call_dissector(data_handle, tmp_tvb, pinfo, subtree);
        }
        proto_item_set_len(ti, boundary_start - start);
        if (*last_boundary == TRUE) {
           proto_tree_add_text(tree, tvb,
                 boundary_start, boundary_line_len,
                 "Last boundary: %s",
                 tvb_format_text(tvb, boundary_start,
                    boundary_line_len));
        } else {
           proto_tree_add_text(tree, tvb,
                 boundary_start, boundary_line_len,
                 "Boundary: %s",
                 tvb_format_text(tvb, boundary_start,
                    boundary_line_len));
        }

        g_free(filename);
        g_free(mimetypename);

        return boundary_start + boundary_line_len;
    }

    g_free(filename);
    g_free(mimetypename);

    return -1;
}
Пример #26
0
static void
dissect_redirecttlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    proto_tree *meta_data_tree, *meta_data_ilv_tree, *redirect_data_tree;
    gint        start_offset;
    gint        length_meta, length_ilv, length_redirect;
    proto_item *ti;
    address     src_addr, src_net_addr;
    address     dst_addr, dst_net_addr;

    copy_address_shallow(&src_addr, &pinfo->src);
    copy_address_shallow(&src_net_addr, &pinfo->net_src);
    copy_address_shallow(&dst_addr, &pinfo->dst);
    copy_address_shallow(&dst_net_addr, &pinfo->net_dst);

    meta_data_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH,
        ett_forces_redirect_tlv_meta_data_tlv, &ti, "Meta Data TLV");
    proto_tree_add_item(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);

    length_meta = tvb_get_ntohs(tvb, offset+2);
    proto_tree_add_uint(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_length, tvb, offset+2, 2, length_meta);
    proto_item_set_len(ti, length_meta);

    start_offset = offset;
    while ((tvb_reported_length_remaining(tvb, offset) >= 8) && (start_offset+length_meta > offset))
    {
        meta_data_ilv_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH,
            ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv, &ti, "Meta Data ILV");

        proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id,
                                   tvb, offset+8, 4, ENC_BIG_ENDIAN);
        length_ilv = tvb_get_ntohl(tvb, offset+12);
        proto_tree_add_uint(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length,
                                   tvb, offset+12, 4, length_ilv);
        offset += 8;
        if (length_ilv > 0) {
            proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv,
                                   tvb, offset, length_ilv, ENC_NA);

            if (offset + length_ilv > offset) {
                offset += length_ilv;
            }
        }

        proto_item_set_len(ti, length_ilv + 8);
    }

    if (tvb_reported_length_remaining(tvb, offset) > 0)
    {
        redirect_data_tree = proto_tree_add_subtree(tree, tvb, offset, TLV_TL_LENGTH,
            ett_forces_redirect_tlv_redirect_data_tlv, &ti, "Redirect Data TLV");

        proto_tree_add_item(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_type,
                            tvb, offset, 2,  ENC_BIG_ENDIAN);
        length_redirect = tvb_get_ntohs(tvb, offset+2);
        proto_tree_add_uint(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_length,
                            tvb, offset+2, 2, length_redirect);

        if (tvb_reported_length_remaining(tvb, offset) < length_redirect)
        {
            expert_add_info_format(pinfo, ti, &ei_forces_redirect_tlv_redirect_data_tlv_length, "Bogus: Redirect Data TLV length (%u bytes) is wrong", length_redirect);
        }
        else if (length_redirect < TLV_TL_LENGTH + MIN_IP_HEADER_LENGTH)
        {
            expert_add_info_format(pinfo, ti, &ei_forces_redirect_tlv_redirect_data_tlv_length, "Bogus: Redirect Data TLV length (%u bytes) not big enough for IP layer", length_redirect);
        }
        else
        {
            tvbuff_t  *next_tvb;

            next_tvb = tvb_new_subset_length(tvb, offset+4, length_redirect-TLV_TL_LENGTH);
            call_dissector(ip_handle, next_tvb, pinfo, redirect_data_tree);

            /* Restore IP info */
            copy_address_shallow(&pinfo->src, &src_addr);
            copy_address_shallow(&pinfo->net_src, &src_net_addr);
            copy_address_shallow(&pinfo->dst, &dst_addr);
            copy_address_shallow(&pinfo->net_dst, &dst_net_addr);
        }
    }
}
Пример #27
0
static void
dissect_v5dl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*v5dl_tree, *addr_tree;
	proto_item	*v5dl_ti, *addr_ti;
	int		direction;
	guint		v5dl_header_len;
	guint16		control;
#if 0
	proto_tree	*checksum_tree;
	proto_item	*checksum_ti;
	guint16		checksum, checksum_calculated;
	guint		checksum_offset;
#endif
	guint16		addr, cr, eah, eal, v5addr;
	gboolean	is_response = 0;
#if 0
	guint		length, reported_length;
#endif
	tvbuff_t	*next_tvb;
	const char	*srcname = "?";
	const char	*dstname = "?";

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "V5DL");
	col_clear(pinfo->cinfo, COL_INFO);

	addr = tvb_get_ntohs(tvb, 0);
	cr = addr & V5DL_CR;
	eal = (addr & V5DL_EAL) >> V5DL_EAL_SHIFT;
	eah = (addr & V5DL_EAH) >> V5DL_EAH_SHIFT;
	v5addr = (eah << 7) + eal;
	v5dl_header_len = 2;	/* addr */

	direction = pinfo->p2p_dir;
	if (pinfo->p2p_dir == P2P_DIR_RECV) {
	    is_response = cr ? FALSE : TRUE;
	    srcname = "Network";
	    dstname = "User";
	}
	else if (pinfo->p2p_dir == P2P_DIR_SENT) {
	    is_response = cr ? TRUE : FALSE;
	    srcname = "User";
	    dstname = "Network";
	}

	col_set_str(pinfo->cinfo, COL_RES_DL_SRC, srcname);
	col_set_str(pinfo->cinfo, COL_RES_DL_DST, dstname);

	if (tree) {
		proto_item *direction_ti;

		v5dl_ti = proto_tree_add_item(tree, proto_v5dl, tvb, 0, -1,
		    ENC_NA);
		v5dl_tree = proto_item_add_subtree(v5dl_ti, ett_v5dl);

		/*
		 * Don't show the direction if we don't know it.
		 */
		if (direction != P2P_DIR_UNKNOWN) {
			direction_ti = proto_tree_add_uint(v5dl_tree, hf_v5dl_direction,
			                                   tvb, 0, 0, pinfo->p2p_dir);
			PROTO_ITEM_SET_GENERATED(direction_ti);
		}

		addr_ti = proto_tree_add_uint(v5dl_tree, hf_v5dl_ef, tvb,
		    0, 2, v5addr);
		addr_tree = proto_item_add_subtree(addr_ti, ett_v5dl_address);
		proto_tree_add_uint(addr_tree, hf_v5dl_eah, tvb, 0, 1, addr);
		proto_tree_add_uint(addr_tree, hf_v5dl_cr,  tvb, 0, 1, addr);
		proto_tree_add_uint(addr_tree, hf_v5dl_ea1, tvb, 0, 1, addr);
		proto_tree_add_uint(addr_tree, hf_v5dl_eal, tvb, 1, 1, addr);
		proto_tree_add_uint(addr_tree, hf_v5dl_ea2, tvb, 1, 1, addr);
	}
	else {
		v5dl_ti = NULL;
		v5dl_tree = NULL;
	}

	control = dissect_xdlc_control(tvb, 2, pinfo, v5dl_tree, hf_v5dl_control,
	    ett_v5dl_control, &v5dl_cf_items, &v5dl_cf_items_ext, NULL, NULL,
	    is_response, TRUE, FALSE);
	v5dl_header_len += XDLC_CONTROL_LEN(control, TRUE);

	if (tree)
		proto_item_set_len(v5dl_ti, v5dl_header_len);

	/*
	 * XXX - the sample capture supplied with bug 7027 does not
	 * appear to include checksums in the packets.
	 */
#if 0
	/*
	 * Check the checksum, if available.
	 * The checksum is a CCITT CRC-16 at the end of the packet, so
	 * if we don't have the entire packet in the capture - i.e., if
	 * tvb_captured_length(tvb) != tvb_reported_length(tvb) we can't check it.
	 */
	length = tvb_captured_length(tvb);
	reported_length = tvb_reported_length(tvb);

	/*
	 * If the reported length isn't big enough for the V5DL header
	 * and 2 bytes of checksum, the packet is malformed, as the
	 * checksum overlaps the header.
	 */
	if (reported_length < v5dl_header_len + 2)
		THROW(ReportedBoundsError);

	if (length == reported_length) {
		/*
		 * There's no snapshot length cutting off any of the
		 * packet.
		 */
		checksum_offset = reported_length - 2;
		checksum = tvb_get_ntohs(tvb, checksum_offset);
		checksum_calculated = crc16_ccitt_tvb(tvb, checksum_offset);
		checksum_calculated = g_htons(checksum_calculated);  /* Note: g_htons() macro may eval arg multiple times */

		if (checksum == checksum_calculated) {
			checksum_ti = proto_tree_add_uint_format_value(v5dl_tree, hf_v5dl_checksum, tvb, checksum_offset,
								 2, 0,
								 "0x%04x [correct]",
								 checksum);
			checksum_tree = proto_item_add_subtree(checksum_ti, ett_v5dl_checksum);
			proto_tree_add_boolean(checksum_tree, hf_v5dl_checksum_good, tvb, checksum_offset, 2, TRUE);
			proto_tree_add_boolean(checksum_tree, hf_v5dl_checksum_bad, tvb, checksum_offset, 2, FALSE);
		} else {
			checksum_ti = proto_tree_add_uint_format_value(v5dl_tree, hf_v5dl_checksum, tvb, checksum_offset,
								 2, 0,
								 "0x%04x [incorrect, should be 0x%04x]",
								 checksum, checksum_calculated);
			checksum_tree = proto_item_add_subtree(checksum_ti, ett_v5dl_checksum);
			proto_tree_add_boolean(checksum_tree, hf_v5dl_checksum_good, tvb, checksum_offset, 2, FALSE);
			proto_tree_add_boolean(checksum_tree, hf_v5dl_checksum_bad, tvb, checksum_offset, 2, TRUE);
		}

		/*
		 * Remove the V5DL header *and* the checksum.
		 */
		next_tvb = tvb_new_subset(tvb, v5dl_header_len,
		    tvb_captured_length_remaining(tvb, v5dl_header_len) - 2,
		    tvb_reported_length_remaining(tvb, v5dl_header_len) - 2);
	} else {
		/*
		 * Some or all of the packet is cut off by a snapshot
		 * length.
		 */
		if (length == reported_length - 1) {
			/*
			 * One byte is cut off, so there's only one
			 * byte of checksum in the captured data.
			 * Remove that byte from the captured length
			 * and both bytes from the reported length.
			 */
			next_tvb = tvb_new_subset(tvb, v5dl_header_len,
			    tvb_captured_length_remaining(tvb, v5dl_header_len) - 1,
			    tvb_reported_length_remaining(tvb, v5dl_header_len) - 2);
		} else {
			/*
			 * Two or more bytes are cut off, so there are
			 * no bytes of checksum in the captured data.
			 * Just remove the checksum from the reported
			 * length.
			 */
			next_tvb = tvb_new_subset(tvb, v5dl_header_len,
			    tvb_captured_length_remaining(tvb, v5dl_header_len),
			    tvb_reported_length_remaining(tvb, v5dl_header_len) - 2);
		}
	}
#else
	next_tvb = tvb_new_subset_remaining(tvb, v5dl_header_len);
#endif

	if (XDLC_IS_INFORMATION(control)) {
		/* call V5.2 dissector */
	        call_dissector(v52_handle, next_tvb, pinfo, tree);
	}
}
Пример #28
0
static void
dissect_forces(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset)
{
    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item *ti, *tlv_item;
    proto_tree *forces_tree, *forces_flags_tree;
    proto_tree *forces_main_header_tree, *forces_tlv_tree, *tlv_tree;
    gint        length_count;

    guint8      message_type;
    guint16     tlv_type;

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

    ti = proto_tree_add_item(tree, proto_forces, tvb, 0, -1, ENC_NA);
    forces_tree = proto_item_add_subtree(ti, ett_forces);

    forces_main_header_tree = proto_tree_add_subtree(forces_tree, tvb, 0, ForCES_HEADER_LENGTH,
                ett_forces_main_header, NULL, "Common Header");

    proto_tree_add_item(forces_main_header_tree, hf_forces_version, tvb, 0, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_main_header_tree, hf_forces_rsvd,    tvb, 0, 1, ENC_BIG_ENDIAN);

    message_type = tvb_get_guint8(tvb, offset+1);
    proto_tree_add_item( forces_main_header_tree, hf_forces_messagetype, tvb, offset+1, 1, ENC_BIG_ENDIAN);

    length_count = tvb_get_ntohs(tvb, offset+2) * 4;  /*multiply 4 DWORD*/
    ti = proto_tree_add_uint_format( forces_main_header_tree, hf_forces_length,
                                     tvb, offset+2, 2, length_count, "Length: %u Bytes", length_count);
    if (length_count != tvb_reported_length_remaining(tvb, offset))
        expert_add_info_format(pinfo, ti, &ei_forces_length, "Bogus: ForCES Header length (%u bytes) is wrong),should be (%u bytes)",
            length_count, tvb_reported_length_remaining(tvb, offset));
    if (length_count < 24)
        expert_add_info_format(pinfo, ti, &ei_forces_length, "Bogus: ForCES Header length (%u bytes) is less than 24bytes)", length_count);

    col_add_fstr(pinfo->cinfo, COL_INFO, "Message Type: %s, Total Length:  %u Bytes",
            val_to_str(message_type, message_type_vals, "Unknown messagetype 0x%x"), length_count);

    proto_tree_add_item( forces_main_header_tree, hf_forces_sid,        tvb, offset+4,  4, ENC_BIG_ENDIAN);
    proto_tree_add_item( forces_main_header_tree, hf_forces_did,        tvb, offset+8,  4, ENC_BIG_ENDIAN);
    proto_tree_add_item( forces_main_header_tree, hf_forces_correlator, tvb, offset+12, 8, ENC_BIG_ENDIAN);

    /*Add flags tree*/
    ti = proto_tree_add_item(forces_main_header_tree, hf_forces_flags, tvb, offset+20, 4, ENC_BIG_ENDIAN);
    forces_flags_tree = proto_item_add_subtree(ti, ett_forces_flags);

    proto_tree_add_item(forces_flags_tree, hf_forces_flags_ack,      tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_at,       tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_em,       tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_pri,      tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_reserved, tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_rsrvd,    tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_tp,       tvb, offset+20, 4, ENC_BIG_ENDIAN);

    offset += 24;
    while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH)
    {
        forces_tlv_tree = proto_tree_add_subtree(forces_tree, tvb, offset, TLV_TL_LENGTH, ett_forces_tlv, &ti, "TLV");

        tlv_type = tvb_get_ntohs(tvb, offset);
        tlv_item = proto_tree_add_item(forces_tlv_tree, hf_forces_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
        length_count = tvb_get_ntohs(tvb, offset+2) * 4;
        proto_item_set_len(ti, length_count);
        ti = proto_tree_add_uint(forces_tlv_tree, hf_forces_tlv_length,
                                        tvb, offset+2, 2, length_count);
        if (tvb_reported_length_remaining(tvb, offset) < length_count)
            expert_add_info_format(pinfo, ti, &ei_forces_tlv_length, "Bogus: Main TLV length (%u bytes) is wrong", length_count);

        if (length_count < TLV_TL_LENGTH)
        {
            expert_add_info_format(pinfo, ti, &ei_forces_tlv_length, "Bogus TLV length: %u", length_count);
            break;
        }

        offset       += TLV_TL_LENGTH;
        length_count -= TLV_TL_LENGTH;

        switch(tlv_type)
        {
        case LFBselect_TLV:
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
                    ett_forces_lfbselect_tlv_type, NULL, "LFB select TLV");
            dissect_lfbselecttlv(tvb, pinfo, tlv_tree, offset, length_count);
            break;

        case REDIRECT_TLV:
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
                            ett_forces_redirect_tlv_type, NULL, "Redirect TLV");
            dissect_redirecttlv(tvb, pinfo, tlv_tree, offset);
            break;

        case ASResult_TLV:
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
                        ett_forces_asresult_tlv, NULL, "ASResult TLV");
            proto_tree_add_item(tlv_tree, hf_forces_asresult_association_setup_result, tvb, offset, 4, ENC_BIG_ENDIAN);
            break;

        case ASTreason_TLV:
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
                            ett_forces_astreason_tlv, NULL, "ASTreason TLV");
            proto_tree_add_item(tlv_tree, hf_forces_astreason_tlv_teardown_reason, tvb, offset, 4, ENC_BIG_ENDIAN);
            break;

        default:
            expert_add_info(pinfo, tlv_item, &ei_forces_tlv_type);
            tlv_tree = proto_tree_add_subtree(forces_tlv_tree, tvb, offset, length_count,
                ett_forces_unknown_tlv, NULL, "Unknown TLV");
            proto_tree_add_item(tlv_tree, hf_forces_unknown_tlv, tvb, offset, length_count, ENC_NA);
            break;
        }

        offset += length_count;
    }
}
Пример #29
0
/* Dissect a FEC header:
 * fec - ptr to the logical FEC packet representation to fill
 * hf - ptr to header fields array
 * ett - ptr to ett array
 * prefs - ptr to FEC prefs array
 * tvb - buffer
 * pinfo - packet info
 * tree - tree where to add FEC header subtree
 * offset - ptr to offset to use and update
 */
void fec_dissector(struct _fec_ptr f, tvbuff_t *tvb, proto_tree *tree, guint *offset)
{
	proto_item *ti;
	proto_tree *fec_tree;
	guint offset_save = *offset;

	/* Create the FEC subtree */
	if (tree)
	{
		ti = proto_tree_add_item(tree, f.hf->header, tvb, *offset, -1, FALSE);
		fec_tree = proto_item_add_subtree(ti, f.ett->main);
	} else
	{
		ti = NULL;
		fec_tree = NULL;
	}

	/* FEC Encoding ID and FEC Instance ID processing */
	if (f.fec->encoding_id_present)
	{
		if (tree)
		{
			proto_tree_add_uint(fec_tree, f.hf->encoding_id, tvb, *offset, 0, f.fec->encoding_id);

			if (f.fec->encoding_id >= 128 && f.fec->instance_id_present)
				proto_tree_add_uint(fec_tree, f.hf->instance_id, tvb, *offset, 0, f.fec->instance_id);
		}

		switch (f.fec->encoding_id)
		{
		case 0:
		case 130:
			f.fec->sbn = tvb_get_ntohs(tvb, *offset);
			f.fec->esi = tvb_get_ntohs(tvb, *offset+2);

			if (tree)
			{
				proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 2, f.fec->sbn);
				proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+2, 2, f.fec->esi);
			}

			f.fec->sbn_present = TRUE;
			f.fec->esi_present = TRUE;
			*offset += 4;
			break;

		case 2:
		case 128:
		case 132:
			f.fec->sbn = tvb_get_ntohl(tvb, *offset);
			f.fec->esi = tvb_get_ntohl(tvb, *offset+4);

			if (tree)
			{
				proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 4, f.fec->sbn);
				proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+4, 4, f.fec->esi);
			}

			f.fec->sbn_present = TRUE;
			f.fec->esi_present = TRUE;
			*offset += 8;
			break;

		case 129:
			f.fec->sbn = tvb_get_ntohl(tvb, *offset);
			f.fec->sbl = tvb_get_ntohs(tvb, *offset+4);
			f.fec->esi = tvb_get_ntohs(tvb, *offset+6);

			if (tree)
			{
				proto_tree_add_uint(fec_tree, f.hf->sbn, tvb, *offset, 4, f.fec->sbn);
				proto_tree_add_uint(fec_tree, f.hf->sbl, tvb, *offset+4, 2, f.fec->sbl);
				proto_tree_add_uint(fec_tree, f.hf->esi, tvb, *offset+6, 2, f.fec->esi);
			}

			f.fec->sbn_present = TRUE;
			f.fec->sbl_present = TRUE;
			f.fec->esi_present = TRUE;
			*offset += 8;
			break;
		}
	}
	if (tree)
		proto_item_set_len(ti, *offset - offset_save);
}
Пример #30
0
/*
 * Returns TRUE if there's a User Information field in this SPDU, FALSE
 * otherwise.
 */
static gboolean
dissect_parameters(tvbuff_t *tvb, int offset, guint16 len, proto_tree *tree,
	           proto_tree *ses_tree, packet_info *pinfo,
	           guint8 *enclosure_item_flags, struct SESSION_DATA_STRUCTURE *session)
{
	gboolean has_user_information = TRUE;
	proto_item *ti;
	proto_tree *param_tree;
	guint8 param_type;
	const char *param_str;
	int len_len;
	guint16 param_len;

	while (len != 0)
	{
		param_type = tvb_get_guint8(tvb, offset);
		param_tree = proto_tree_add_subtree(ses_tree, tvb, offset, -1, ett_ses_param, &ti,
		    val_to_str(param_type, param_vals,
		      "Unknown parameter type (0x%02x)"));
		param_str = val_to_str_const(param_type, param_vals, "Unknown");
		proto_tree_add_text(param_tree, tvb, offset, 1,
		    "Parameter type: %s", param_str);
		offset++;
		len--;
		param_len = get_item_len(tvb, offset, &len_len);
		if (len_len > len) {
			proto_item_set_len(ti, len + 1 );
			proto_tree_add_text(param_tree, tvb, offset, len,
			    "Parameter length doesn't fit in parameter");
			return has_user_information;
		}
		len -= len_len;
		if (param_len > len) {
			proto_item_set_len(ti, len + 1 + len_len);
			proto_tree_add_text(param_tree, tvb, offset, len,
			    "Parameter length: %u, should be <= %u",
			    param_len, len);
			return has_user_information;
		}
		proto_item_set_len(ti, 1 + len_len + param_len);
		proto_tree_add_text(param_tree, tvb, offset, len_len,
		    "Parameter length: %u", param_len);
		offset += len_len;

		if (param_str != NULL)
		{
			switch(param_type)
			{
			case Extended_User_Data:
				call_pres_dissector(tvb, offset, param_len,
				    pinfo, tree, param_tree, session);
				break;

			case User_Data:
				call_pres_dissector(tvb, offset, param_len,
				    pinfo, tree, param_tree, session);
				break;

			/* handle PGI's  */
			case Connect_Accept_Item:
			case Connection_Identifier:
			case Linking_Information:
				/* Yes. */
				if (!dissect_parameter_group(tvb, offset, tree,
				    param_tree, pinfo, param_len, enclosure_item_flags, session))
					has_user_information = FALSE;
				break;

			/* everything else is a PI */
			default:
				if (!dissect_parameter(tvb, offset, tree,
				    param_tree, pinfo, param_type, param_len,
				    enclosure_item_flags, session))
					has_user_information = FALSE;
				break;
			}
		}
		offset += param_len;
		len -= param_len;
	}
	return has_user_information;
}