Exemplo n.º 1
0
static void
dissect_rssi(tvbuff_t *tvb, proto_tree *tree)
{
	gint32 rssi;
	rssi 			= (-1)*((gint32)tvb_get_guint8(tvb, get_rssi_index()));
	proto_tree_add_int(tree, hf_nordic_ble_rssi, tvb, get_rssi_index(), 1, rssi);
}
Exemplo n.º 2
0
bool dissect_protobuf_field(const FieldDescriptor* field, const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *leaf)
{
    int len = WireFormat::FieldByteSize( field, *message );

    map<string, Handles*>::iterator it = g_mapHandles.find( field->full_name() );
    if( it == g_mapHandles.end() )
    {
        return false; // bug
    }
    
    Handles* handles = it->second;
    const Reflection *reflection = message->GetReflection();
    const EnumValueDescriptor* enumDesc = NULL;

    switch( field->cpp_type() )
    {
    case FieldDescriptor::CPPTYPE_UINT32:
      proto_tree_add_uint( leaf, handles->p_id, tvb, *offset, len,
               reflection->GetUInt32( *message, field ) );
      break;
    case FieldDescriptor::CPPTYPE_INT32:
      proto_tree_add_int( leaf, handles->p_id, tvb, *offset, len, 
              reflection->GetInt32( *message, field ) );
      break;
    case FieldDescriptor::CPPTYPE_FLOAT:
      proto_tree_add_float( leaf, handles->p_id, tvb, *offset, len, 
                reflection->GetFloat( *message, field ) );
      break;
    case FieldDescriptor::CPPTYPE_UINT64:
      proto_tree_add_uint64( leaf, handles->p_id, tvb, *offset, len, 
                 reflection->GetUInt64( *message, field ) );
      break;
    case FieldDescriptor::CPPTYPE_INT64:
      proto_tree_add_int64( leaf, handles->p_id, tvb, *offset, len, 
                reflection->GetInt64( *message, field ) );
      break;
    case FieldDescriptor::CPPTYPE_DOUBLE:
      proto_tree_add_double( leaf, handles->p_id, tvb, *offset, len, 
                 reflection->GetDouble( *message, field ) );
      break;
    case FieldDescriptor::CPPTYPE_BOOL:
      proto_tree_add_boolean( leaf, handles->p_id, tvb, *offset, len, 
                  reflection->GetBool( *message, field ) );
      break;
    case FieldDescriptor::CPPTYPE_ENUM:
      enumDesc = reflection->GetEnum( *message, field );
      proto_tree_add_int_format_value( leaf, handles->p_id, tvb, *offset, len, 
                       enumDesc->number(), "%d ( %s )", enumDesc->number(), enumDesc->name().c_str() );
      break;
    case FieldDescriptor::CPPTYPE_STRING:
      proto_tree_add_string( leaf, handles->p_id, tvb, *offset, len, 
                 reflection->GetString( *message, field ).c_str() );
      break;
    default:
      proto_tree_add_item( leaf, handles->p_id, tvb, *offset, len, true );
    };

    *offset += len;
    return true;
}
Exemplo n.º 3
0
/* Dissect an individual actrace ISDN message */
static void dissect_actrace_isdn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
				 proto_tree *actrace_tree)
{
	/* Declare variables */
	gint len;
	gint32 value, trunk;
	tvbuff_t *next_tvb;
	int offset = 0;

	len = tvb_get_ntohs(tvb, 44);

	value = tvb_get_ntohl(tvb, offset+4);
	proto_tree_add_int(actrace_tree, hf_actrace_isdn_direction, tvb, offset+4, 4, value);

	offset += 8;
	trunk = tvb_get_ntohs(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_isdn_trunk, tvb, offset, 2, trunk);

	offset = 44;
	proto_tree_add_int(actrace_tree, hf_actrace_isdn_length, tvb, offset, 2, len);


	/* if it is a q931 packet (we don't want LAPD packets for Voip Graph) add tap info */
	if (len > 4) {
		/* Initialise packet info for passing to tap */
		actrace_pi = ep_new(actrace_info_t);

		actrace_pi->type = ACTRACE_ISDN;
		actrace_pi->direction = (value==PSTN_TO_BLADE?1:0);
		actrace_pi->trunk = trunk;

		/* Report this packet to the tap */
		tap_queue_packet(actrace_tap, pinfo, actrace_pi);
	}

	/* Dissect lapd payload */
	offset += 2 ;
	next_tvb = tvb_new_subset(tvb, offset, len, len);
	call_dissector(lapd_handle, next_tvb, pinfo, tree);

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "AC_ISDN");
	col_prepend_fstr(pinfo->cinfo, COL_INFO, "Trunk:%d  Blade %s PSTN "
			 , trunk, value==PSTN_TO_BLADE?"<--":"-->");
}
Exemplo n.º 4
0
static
void dissect_pw_padding(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
	/* do not touch columns */
	if (tree)
	{
		gint size;
		proto_item* item;
		size = tvb_reported_length_remaining(tvb, 0);
		item = proto_tree_add_item(tree, proto_pw_padding, tvb, 0, -1, FALSE);
		pwc_item_append_text_n_items(item,size,"byte");
		{
			proto_tree* tree_p;
			tree_p = proto_item_add_subtree(item, ett);
			call_dissector(dh_data, tvb, pinfo, tree_p);
			item = proto_tree_add_int(tree_p, hf_padding_len, tvb, 0, 0, size);
			PROTO_ITEM_SET_HIDDEN(item); /*allow filtering*/
		}
	}
	return;
}
Exemplo n.º 5
0
static void
dissect_wlancap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *wlan_tree = NULL;
    proto_item *ti;
    tvbuff_t *next_tvb;
    int offset;
    guint32 version;
    guint32 length;
    guint32 channel;
    guint32 datarate;
    guint32 ssi_type;
    guint32 antnoise;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
    col_clear(pinfo->cinfo, COL_INFO);
    offset = 0;

    version = tvb_get_ntohl(tvb, offset) - WLANCAP_MAGIC_COOKIE_BASE;

    length = tvb_get_ntohl(tvb, offset+4);

    col_add_fstr(pinfo->cinfo, COL_INFO, "AVS WLAN Capture v%x, Length %d",version, length);

    if (version > 2) {
      goto skip;
    }

    /* Dissect the AVS header */
    if (tree) {
      ti = proto_tree_add_item(tree, proto_wlancap, tvb, 0, length, ENC_NA);
      wlan_tree = proto_item_add_subtree(ti, ett_radio);
      proto_tree_add_item(wlan_tree, hf_wlan_magic, tvb, offset, 4, ENC_BIG_ENDIAN);
      proto_tree_add_item(wlan_tree, hf_wlan_version, tvb, offset, 4, ENC_BIG_ENDIAN);
    }
    offset+=4;
    if (tree)
      proto_tree_add_item(wlan_tree, hf_wlan_length, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset+=4;
    if (tree)
      proto_tree_add_item(wlan_tree, hf_mactime, tvb, offset, 8, ENC_BIG_ENDIAN);
    offset+=8;
    if (tree)
      proto_tree_add_item(wlan_tree, hf_hosttime, tvb, offset, 8, ENC_BIG_ENDIAN);
    offset+=8;
    if (tree)
      proto_tree_add_item(wlan_tree, hf_wlan_phytype, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset+=4;

    /* XXX cook channel (fh uses different numbers) */
    channel = tvb_get_ntohl(tvb, offset);
    if (channel < 256) {
      col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u", channel);
      if (tree)
        proto_tree_add_uint(wlan_tree, hf_channel, tvb, offset, 4, channel);
    } else if (channel < 10000) {
      col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u MHz", channel);
      if (tree)
        proto_tree_add_uint_format(wlan_tree, hf_channel_frequency, tvb, offset,
                                   4, channel, "Frequency: %u MHz", channel);
    } else {
      col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u KHz", channel);
      if (tree)
        proto_tree_add_uint_format(wlan_tree, hf_channel_frequency, tvb, offset,
                                   4, channel, "Frequency: %u KHz", channel);
    }
    offset+=4;
    datarate = tvb_get_ntohl(tvb, offset);
    if (datarate < 100000) {
      /* In units of 100 Kb/s; convert to b/s */
      datarate *= 100000;
    }

    col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u",
                   datarate / 1000000,
                   ((datarate % 1000000) > 500000) ? 5 : 0);
    if (tree) {
      proto_tree_add_uint64_format(wlan_tree, hf_data_rate, tvb, offset, 4,
                                   datarate,
                                   "Data Rate: %u.%u Mb/s",
                                   datarate/1000000,
                                   ((datarate % 1000000) > 500000) ? 5 : 0);
    }
    offset+=4;
    if (tree)
      proto_tree_add_item(wlan_tree, hf_wlan_antenna, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset+=4;
    if (tree)
      proto_tree_add_item(wlan_tree, hf_wlan_priority, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset+=4;
    ssi_type = tvb_get_ntohl(tvb, offset);
    if (tree)
      proto_tree_add_uint(wlan_tree, hf_wlan_ssi_type, tvb, offset, 4, ssi_type);
    offset+=4;
    switch (ssi_type) {

    case SSI_NONE:
    default:
      /* either there is no SSI information, or we don't know what type it is */
      break;

    case SSI_NORM_RSSI:
      /* Normalized RSSI */
      col_add_fstr(pinfo->cinfo, COL_RSSI, "%u (norm)", tvb_get_ntohl(tvb, offset));
      if (tree)
        proto_tree_add_item(wlan_tree, hf_normrssi_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
      break;

    case SSI_DBM:
      /* dBm */
      col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", tvb_get_ntohl(tvb, offset));
      if (tree)
        proto_tree_add_item(wlan_tree, hf_dbm_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
      break;

    case SSI_RAW_RSSI:
      /* Raw RSSI */
      col_add_fstr(pinfo->cinfo, COL_RSSI, "%u (raw)", tvb_get_ntohl(tvb, offset));
      if (tree)
        proto_tree_add_item(wlan_tree, hf_rawrssi_antsignal, tvb, offset, 4, ENC_BIG_ENDIAN);
      break;
    }
    offset+=4;
    antnoise = tvb_get_ntohl(tvb, offset);
    /* 0xffffffff means "hardware does not provide noise data" */
    if (antnoise != 0xffffffff) {
      switch (ssi_type) {

      case SSI_NONE:
      default:
        /* either there is no SSI information, or we don't know what type it is */
        break;

      case SSI_NORM_RSSI:
        /* Normalized RSSI */
        if (tree)
          proto_tree_add_uint(wlan_tree, hf_normrssi_antnoise, tvb, offset, 4, antnoise);
        break;

      case SSI_DBM:
        /* dBm */
        if (tree)
          proto_tree_add_int(wlan_tree, hf_dbm_antnoise, tvb, offset, 4, antnoise);
        break;

      case SSI_RAW_RSSI:
        /* Raw RSSI */
        if (tree)
          proto_tree_add_uint(wlan_tree, hf_rawrssi_antnoise, tvb, offset, 4, antnoise);
        break;
      }
    }
    offset+=4;
    if (tree)
      proto_tree_add_item(wlan_tree, hf_wlan_preamble, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset+=4;
    if (tree)
      proto_tree_add_item(wlan_tree, hf_wlan_encoding, tvb, offset, 4, ENC_BIG_ENDIAN);
    offset+=4;
    if (version > 1) {
      if (tree)
        proto_tree_add_item(wlan_tree, hf_wlan_sequence, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset+=4;
      if (tree)
        proto_tree_add_item(wlan_tree, hf_wlan_drops, tvb, offset, 4, ENC_BIG_ENDIAN);
      offset+=4;
      if (tree)
        proto_tree_add_item(wlan_tree, hf_wlan_receiver_addr, tvb, offset, 6, ENC_NA);
      offset+=6;
      if (tree)
        proto_tree_add_item(wlan_tree, hf_wlan_padding, tvb, offset, 2, ENC_NA);
      offset+=2;
    }


 skip:
    offset = length;

    /* dissect the 802.11 header next */
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
}
Exemplo n.º 6
0
static
void dissect_pw_satop(tvbuff_t * tvb_original
					,packet_info * pinfo
					,proto_tree * tree
					,pwc_demux_type_t demux)
{
	const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/
	gint      packet_size;
	gint      payload_size;
	gint      padding_size;
	int properties;

	enum {
		PAY_NO_IDEA = 0
		,PAY_LIKE_E1
		,PAY_LIKE_T1
		,PAY_LIKE_E3_T3
		,PAY_LIKE_OCTET_ALIGNED_T1
	} payload_properties;

	packet_size = tvb_reported_length_remaining(tvb_original, 0);
	/*
	 * FIXME
	 * "4" below should be replaced by something like "min_packet_size_this_dissector"
	 * Also call to dissect_try_cw_first_nibble() should be moved before this block
	 */
	if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */
	{
		proto_item  *item;
		item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
		expert_add_info_format(pinfo, item, &ei_cw_packet_size_too_small,
				       "PW packet size (%d) is too small to carry sensible information"
				       ,(int)packet_size);
		col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
		col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small");
		return;
	}

	switch (demux)
	{
	case PWC_DEMUX_MPLS:
		if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree))
		{
			return;
		}
		break;
	case PWC_DEMUX_UDP:
		break;
	default:
		DISSECTOR_ASSERT_NOT_REACHED();
		return;
	}

	/* check how "good" is this packet */
	/* also decide payload length from packet size and CW */
	properties = 0;
	if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/))
	{
		properties |= PWC_CW_BAD_BITS03;
	}
	if (0 != (tvb_get_guint8(tvb_original, 0) & 0x03 /*rsv*/))
	{
		properties |= PWC_CW_BAD_RSV;
	}
	if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/))
	{
		properties |= PWC_CW_BAD_FRAG;
	}
	{
		/* RFC4553:
		 * [...MAY be used to carry the length of the SAToP
		 * packet (defined as the size of the SAToP header + the payload
		 * size) if it is less than 64 bytes, and MUST be set to zero
		 * otherwise... ]
		 *
		 * Note that this differs from RFC4385's definition of length:
		 * [ If the MPLS payload is less than 64 bytes, the length field
		 * MUST be set to the length of the PW payload...]
		 *
		 * We will use RFC4553's definition here.
		 */
		int  cw_len;
		gint payload_size_from_packet;

		cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f;
		payload_size_from_packet = packet_size - encaps_size;
		if (cw_len != 0)
		{
			gint payload_size_from_cw;
			payload_size_from_cw = cw_len - encaps_size;
			/*
			 * Assumptions for error case,
			 * will be overwritten if no errors found:
			 */
			payload_size = payload_size_from_packet;
			padding_size = 0;

			if (payload_size_from_cw < 0)
			{
				properties |= PWC_CW_BAD_PAYLEN_LT_0;
			}
			else if (payload_size_from_cw > payload_size_from_packet)
			{
				properties |= PWC_CW_BAD_PAYLEN_GT_PACKET;
			}
			else if (payload_size_from_packet >= 64)
			{
				properties |= PWC_CW_BAD_LEN_MUST_BE_0;
			}
			else /* ok */
			{
				payload_size = payload_size_from_cw;
				padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */
			}
		}
		else
		{
			payload_size = payload_size_from_packet;
			padding_size = 0;
		}
	}
	if (payload_size == 0)
	{
		/*
		 * As CW.L it indicates that PW payload is invalid, dissector should
		 * not blame packets with bad payload (including "bad" or "strange" SIZE of
		 * payload) when L bit is set.
		 */
		if (0 == (tvb_get_guint8(tvb_original, 0) & 0x08 /*L bit*/))
		{
			properties |= PWC_PAY_SIZE_BAD;
		}
	}

	/* guess about payload type */
	if (payload_size == 256)
	{
		payload_properties = PAY_LIKE_E1;
	}
	else if (payload_size == 192)
	{
		payload_properties = PAY_LIKE_T1;
	}
	else if (payload_size == 1024)
	{
		payload_properties = PAY_LIKE_E3_T3;
	}
	else if ((payload_size != 0) && (payload_size % 25 == 0))
	{
		payload_properties = PAY_LIKE_OCTET_ALIGNED_T1;
	}
	else
	{
		payload_properties = PAY_NO_IDEA; /*we do not have any ideas about payload type*/
	}

	/* fill up columns*/
	col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
	col_clear(pinfo->cinfo, COL_INFO);
	if (properties & PWC_ANYOF_CW_BAD)
	{
		col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, ");
	}

	if (properties & PWC_PAY_SIZE_BAD)
	{
		col_append_str(pinfo->cinfo, COL_INFO, "Payload size:0 (Bad)");
	}
	else
	{
		col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size);
	}

	if (padding_size != 0)
	{
		col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size);
	}


	{
		proto_item* item;
		item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
		pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE);
		pwc_item_append_text_n_items(item,(int)payload_size,"octet");
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				proto_item* item2;
				tvb = tvb_new_subset_length(tvb_original, 0, PWC_SIZEOF_CW);
				item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA);
				pwc_item_append_cw(item2, tvb_get_ntohl(tvb, 0),FALSE);
				{
					proto_tree* tree3;
					tree3 = proto_item_add_subtree(item2, ett);
					{
						proto_item* item3;
						if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/
						{
							item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN);
							expert_add_info(pinfo, item3, &ei_cw_bits03);
						}

						proto_tree_add_item(tree3, hf_cw_l  , tvb, 0, 1, ENC_BIG_ENDIAN);
						proto_tree_add_item(tree3, hf_cw_r  , tvb, 0, 1, ENC_BIG_ENDIAN);

						item3 = proto_tree_add_item(tree3, hf_cw_rsv, tvb, 0, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_RSV)
						{
							expert_add_info(pinfo, item3, &ei_cw_rsv);
						}

						item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_FRAG)
						{
							expert_add_info(pinfo, item3, &ei_cw_frg);
						}

						item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_PAYLEN_LT_0)
						{
							expert_add_info_format(pinfo, item3, &ei_payload_size_invalid,
								"Bad Length: too small, must be > %d",
								(int)encaps_size);
						}
						if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET)
						{
							expert_add_info_format(pinfo, item3, &ei_payload_size_invalid,
								"Bad Length: must be <= than PSN packet size (%d)",
								(int)packet_size);
						}
						if (properties & PWC_CW_BAD_LEN_MUST_BE_0)
						{
							expert_add_info_format(pinfo, item3, &ei_payload_size_invalid,
								"Bad Length: must be 0 if SAToP packet size (%d) is > 64",
								(int)packet_size);
						}

						proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN);
					}
				}
			}
		}

		/* payload */
		if (properties & PWC_PAY_SIZE_BAD)
		{
			expert_add_info_format(pinfo, item, &ei_payload_size_invalid,
				"SAToP payload: none found. Size of payload must be <> 0");
		}
		else if (payload_size == 0)
		{
			expert_add_info(pinfo, item, &ei_payload_size_invalid_undecoded);
		}
		else
		{

			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				proto_item* item2;
				tvbuff_t* tvb;
				tvb = tvb_new_subset_length(tvb_original, PWC_SIZEOF_CW, payload_size);
				item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA);
				pwc_item_append_text_n_items(item2,(int)payload_size,"octet");
				{
					proto_tree* tree3;
					const char* s;
					switch(payload_properties)
					{
					case PAY_LIKE_E1:
						s = " (looks like E1)";
						break;
					case PAY_LIKE_T1:
						s = " (looks like T1)";
						break;
					case PAY_LIKE_E3_T3:
						s = " (looks like E3/T3)";
						break;
					case PAY_LIKE_OCTET_ALIGNED_T1:
						s = " (looks like octet-aligned T1)";
						break;
					case PAY_NO_IDEA:
					default:
						s = "";
						break;
					}
					proto_item_append_text(item2, "%s", s);
					tree3 = proto_item_add_subtree(item2, ett);
					call_data_dissector(tvb, pinfo, tree3);
					item2 = proto_tree_add_int(tree3, hf_payload_l, tvb, 0, 0
						,(int)payload_size); /* allow filtering */
					PROTO_ITEM_SET_HIDDEN(item2);
				}
			}
		}

		/* padding */
		if (padding_size > 0)
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1);
				call_dissector(pw_padding_handle, tvb, pinfo, tree2);
			}
		}
	}
	return;
}
Exemplo n.º 7
0
static void
dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
	proto_tree *tree, int direction)
{
	proto_tree	*cl_tree   = NULL;
	proto_tree	*text_tree = NULL;
	guint8		text[MAX_TEXT_SIZE+1];
	int		len;
	int		offset;
	guint32		marker;
	int		command_len;
	const char	*command = "";
	gboolean	command_finished = FALSE;

	marker = tvb_get_ntohl(tvb, 0);
	if (tree) {
		proto_item *cl_item;
		cl_item = proto_tree_add_text(tree, tvb, 0, -1, "Connectionless");
		cl_tree = proto_item_add_subtree(cl_item, ett_quakeworld_connectionless);

		proto_tree_add_uint(cl_tree, hf_quakeworld_connectionless_marker,
				tvb, 0, 4, marker);
	}

	/* all the rest of the packet is just text */
        offset = 4;

        len = tvb_get_nstringz0(tvb, offset, sizeof(text), text);
	/* actually, we should look for a eol char and stop already there */

        if (cl_tree) {
		proto_item *text_item;
                text_item = proto_tree_add_string(cl_tree, hf_quakeworld_connectionless_text,
						  tvb, offset, len + 1, text);
		text_tree = proto_item_add_subtree(text_item, ett_quakeworld_connectionless_text);
        }

	if (direction == DIR_C2S) {
		/* client to server commands */
		const char *c;

		Cmd_TokenizeString(text);
		c = Cmd_Argv(0);

		/* client to sever commands */
		if (strcmp(c,"ping") == 0) {
			command = "Ping";
			command_len = 4;
		} else if (strcmp(c,"status") == 0) {
			command = "Status";
			command_len = 6;
		} else if (strcmp(c,"log") == 0) {
			command = "Log";
			command_len = 3;
		} else if (strcmp(c,"connect") == 0) {
			int version;
			int qport;
			int challenge;
			const char *infostring;
			proto_tree *argument_tree = NULL;
			command = "Connect";
			command_len = Cmd_Argv_length(0);
			if (text_tree) {
				proto_item *argument_item;
				proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
					tvb, offset, command_len, command);
				argument_item = proto_tree_add_string(text_tree,
					hf_quakeworld_connectionless_arguments,
					tvb, offset + Cmd_Argv_start(1), len + 1 - Cmd_Argv_start(1),
					text + Cmd_Argv_start(1));
				argument_tree = proto_item_add_subtree(argument_item,
								       ett_quakeworld_connectionless_arguments);
				command_finished=TRUE;
			}
			version    = atoi(Cmd_Argv(1));
			qport      = atoi(Cmd_Argv(2));
			challenge  = atoi(Cmd_Argv(3));
			infostring = Cmd_Argv(4);
			if (argument_tree) {
				proto_item *info_item;
				proto_tree *info_tree;
				proto_tree_add_uint(argument_tree,
					hf_quakeworld_connectionless_connect_version,
					tvb,
					offset + Cmd_Argv_start(1),
					Cmd_Argv_length(1), version);
				proto_tree_add_uint(argument_tree,
					hf_quakeworld_connectionless_connect_qport,
					tvb,
					offset + Cmd_Argv_start(2),
					Cmd_Argv_length(2), qport);
				proto_tree_add_int(argument_tree,
					hf_quakeworld_connectionless_connect_challenge,
					tvb,
					offset + Cmd_Argv_start(3),
					Cmd_Argv_length(3), challenge);
				info_item = proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_connect_infostring,
					tvb,
					offset + Cmd_Argv_start(4),
					Cmd_Argv_length(4), infostring);
				info_tree = proto_item_add_subtree(
					info_item, ett_quakeworld_connectionless_connect_infostring);
				dissect_id_infostring(tvb, info_tree, offset + Cmd_Argv_start(4),
					ep_strdup(infostring),
					ett_quakeworld_connectionless_connect_infostring_key_value,
					hf_quakeworld_connectionless_connect_infostring_key_value,
					hf_quakeworld_connectionless_connect_infostring_key,
					hf_quakeworld_connectionless_connect_infostring_value);
			}
		} else if (strcmp(c,"getchallenge") == 0) {
			command = "Get Challenge";
			command_len = Cmd_Argv_length(0);
		} else if (strcmp(c,"rcon") == 0) {
			const char* password;
			int i;
			char remaining[MAX_TEXT_SIZE+1];
			proto_tree *argument_tree = NULL;
			command = "Remote Command";
			command_len = Cmd_Argv_length(0);
			if (text_tree) {
				proto_item *argument_item;
				proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
					tvb, offset, command_len, command);
				argument_item = proto_tree_add_string(text_tree,
					hf_quakeworld_connectionless_arguments,
					tvb, offset + Cmd_Argv_start(1), len + 1 - Cmd_Argv_start(1),
					text + Cmd_Argv_start(1));
				argument_tree =	proto_item_add_subtree(argument_item,
								       ett_quakeworld_connectionless_arguments);
				command_finished=TRUE;
			}
			password = Cmd_Argv(1);
			if (argument_tree) {
				proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_rcon_password,
					tvb,
					offset + Cmd_Argv_start(1),
					Cmd_Argv_length(1), password);
			}
			remaining[0] = '\0';
			for (i=2; i<Cmd_Argc() ; i++) {
				g_strlcat (remaining, Cmd_Argv(i), MAX_TEXT_SIZE+1);
				g_strlcat (remaining, " ", MAX_TEXT_SIZE+1);
			}
			if (text_tree) {
				proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_rcon_command,
					tvb, offset + Cmd_Argv_start(2),
					Cmd_Argv_start(Cmd_Argc()-1) + Cmd_Argv_length(Cmd_Argc()-1) -
					Cmd_Argv_start(2),
					remaining);
			}
		} else if (c[0]==A2A_PING && ( c[1]=='\0' || c[1]=='\n')) {
			command = "Ping";
			command_len = 1;
		} else if (c[0]==A2A_ACK && ( c[1]=='\0' || c[1]=='\n')) {
			command = "Ack";
			command_len = 1;
		} else {
			command = "Unknown";
			command_len = len;
		}
	}
	else {
		/* server to client commands */
		if (text[0] == S2C_CONNECTION) {
			command = "Connected";
			command_len = 1;
		} else if (text[0] == A2C_CLIENT_COMMAND) {
			command = "Client Command";
			command_len = 1;
			/* stringz (command), stringz (localid) */
		} else if (text[0] == A2C_PRINT) {
			command = "Print";
			command_len = 1;
			/* string */
		} else if (text[0] == A2A_PING) {
			command = "Ping";
			command_len = 1;
		} else if (text[0] == S2C_CHALLENGE) {
			command = "Challenge";
			command_len = 1;
			/* string, atoi */
		} else {
			command = "Unknown";
			command_len = len;
		}
	}

	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", command);
	}

	if (text_tree && !command_finished) {
		proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
			tvb, offset, command_len, command);
	}
        offset += len + 1;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
static int
dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *signature_tree;
    proto_tree *name_tree;
    proto_tree *signedinfo_tree;
    proto_tree *content_tree;
    proto_item *titem;
    struct ccn_parsed_ContentObject co;
    struct ccn_parsed_ContentObject *pco = &co;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    size_t blob_size;
    const unsigned char *blob;
    int l;
    unsigned int i;
    double dt;
    nstime_t timestamp;
    int res;

    comps = ccn_indexbuf_create();
    res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps);
    if (res < 0) return (-1);

    /* Signature */
    l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature];
    titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE);
    signature_tree = proto_item_add_subtree(titem, ett_signature);

    /* DigestAlgorithm */
    l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb,
                                  pco->offset[CCN_PCO_B_DigestAlgorithm],
                                  pco->offset[CCN_PCO_E_DigestAlgorithm],
                                  &blob, &blob_size);
        titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    /* Witness */
    l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness];
    if (l > 0) {
        /* add the witness item to the signature tree */
    }

    /* Signature bits */
    l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb,
                                  pco->offset[CCN_PCO_B_SignatureBits],
                                  pco->offset[CCN_PCO_E_SignatureBits],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb,
                                     blob - ccnb, blob_size, blob);
    }

    /* /Signature */

    /* Name */
    l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                      pco->offset[CCN_PCO_B_Name], l,
                                      ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);

    /* Name Components */
    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }

    /* /Name */

    /* SignedInfo */
    l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo];
    titem = proto_tree_add_text(tree, tvb,
                                         pco->offset[CCN_PCO_B_SignedInfo], l,
                                         "SignedInfo");
    signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo);

    /* PublisherPublicKeyDigest */
    l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb,
                                  pco->offset[CCN_PCO_B_PublisherPublicKeyDigest],
                                  pco->offset[CCN_PCO_E_PublisherPublicKeyDigest],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob);
    }

    /* Timestamp */
    l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb,
                                  pco->offset[CCN_PCO_B_Timestamp],
                                  pco->offset[CCN_PCO_E_Timestamp],
                                  &blob, &blob_size);
        dt = 0.0;
        for (i = 0; i < blob_size; i++)
            dt = dt * 256.0 + (double)blob[i];
        dt /= 4096.0;
        timestamp.secs = dt; /* truncates */
        timestamp.nsecs = (dt - (double) timestamp.secs) *  1000000000.0;
        titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, &timestamp);
    }

    /* Type */
    l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb,
                                  pco->offset[CCN_PCO_B_Type],
                                  pco->offset[CCN_PCO_E_Type],
                                  &blob, &blob_size);
        titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type);
    } else {
        titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type);
    }

    /* FreshnessSeconds */
    l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb,
                                  pco->offset[CCN_PCO_B_FreshnessSeconds],
                                  pco->offset[CCN_PCO_E_FreshnessSeconds],
                                  &blob, &blob_size);
        i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb,
                                                  pco->offset[CCN_PCO_B_FreshnessSeconds],
                                                  pco->offset[CCN_PCO_E_FreshnessSeconds]);

        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i);
    }

    /* FinalBlockID */
    l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb,
                                  pco->offset[CCN_PCO_B_FinalBlockID],
                                  pco->offset[CCN_PCO_E_FinalBlockID],
                                  &blob, &blob_size);

        titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE);
    }
    /* TODO: KeyLocator */
    /* /SignedInfo */

    /* Content */
    l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content];
    res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb,
                                  pco->offset[CCN_PCO_B_Content],
                                  pco->offset[CCN_PCO_E_Content],
                                  &blob, &blob_size);
    titem = proto_tree_add_text(tree, tvb,
                                         pco->offset[CCN_PCO_B_Content], l,
                                         "Content: %d bytes", blob_size);
    if (blob_size > 0) {
        content_tree = proto_item_add_subtree(titem, ett_content);
        titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE);
    }

    return (ccnb_size);
}
Exemplo n.º 10
0
static int 
add_option_info(tvbuff_t *tvb, int pos, proto_tree *tree, proto_item *ti)
{
	guint8 tag, length, fcs_err = 0, encr = 0, seen_fcs_err = 0;
	
	/*
	 * Read all option tags in an endless loop. If the packet is malformed this
	 * loop might be a problem.
	 */
	while (TRUE) {
		tag = tvb_get_guint8(tvb, pos++);

		switch (tag) {
		case TZSP_HDR_PAD:
			length = 0;
			break;

		case TZSP_HDR_END:
			/* Fill in header with information from other tags. */
			if (seen_fcs_err) {
				if (tree)
					proto_item_append_text(ti,"%s", fcs_err?"FCS Error":(encr?"Encrypted":"Good"));
			}
			return pos;

		case TZSP_HDR_ORIGINAL_LENGTH:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_int (tree, hf_original_length, tvb, pos-2, 4,
						tvb_get_ntohs(tvb, pos));
			pos += length;
			break;

		case WLAN_RADIO_HDR_SIGNAL:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_int (tree, hf_signal, tvb, pos-2, 3,
						(char)tvb_get_guint8(tvb, pos));
			pos += length;
			break;

		case WLAN_RADIO_HDR_NOISE:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_int (tree, hf_silence, tvb, pos-2, 3,
						(char)tvb_get_guint8(tvb, pos));
			pos += length;
			break;

		case WLAN_RADIO_HDR_RATE:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_uint (tree, hf_rate, tvb, pos-2, 3,
							tvb_get_guint8(tvb, pos));
			pos += length;
			break;

		case WLAN_RADIO_HDR_TIMESTAMP:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_uint (tree, hf_time, tvb, pos-2, 6,
							tvb_get_ntohl(tvb, pos));
			pos += length;
			break;

		case WLAN_RADIO_HDR_MSG_TYPE:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_uint (tree, hf_status_msg_type, tvb, pos-2, 3,
						tvb_get_guint8(tvb, pos));
			pos += length;
			break;

		case WLAN_RADIO_HDR_CF:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_boolean (tree, hf_status_pcf, tvb, pos-2, 3,
						tvb_get_guint8(tvb, pos));
			pos += length;
			break;

		case WLAN_RADIO_HDR_UN_DECR:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_boolean (tree, hf_status_undecrypted, tvb, pos-2, 3,
						tvb_get_guint8(tvb, pos));
			encr = tvb_get_guint8(tvb, pos);
			pos += length;
			break;

		case WLAN_RADIO_HDR_FCS_ERR:
			seen_fcs_err = 1;
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_boolean (tree, hf_status_fcs_error, tvb, pos-2, 3,
						tvb_get_guint8(tvb, pos));
			fcs_err = tvb_get_guint8(tvb, pos);
			pos += length;
			break;

		case WLAN_RADIO_HDR_CHANNEL:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_uint (tree, hf_channel, tvb, pos-2, 3,
							tvb_get_guint8(tvb, pos));
			pos += length;
			break;

		case TZSP_HDR_SENSOR:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_ether(tree, hf_sensormac, tvb, pos-2, 6,
							tvb_get_ptr (tvb, pos, 6));
			pos += length;
			break;

		default:
			length = tvb_get_guint8(tvb, pos++);
			if (tree)
				proto_tree_add_bytes(tree, hf_unknown, tvb, pos-2, length+2,
							tvb_get_ptr(tvb, pos, length));
			pos += length;
			break;
		}
	}
}
Exemplo n.º 11
0
/* Dissect an individual actrace CAS message */
static void dissect_actrace_cas(tvbuff_t *tvb, packet_info *pinfo, proto_tree *actrace_tree)
{
	/* Declare variables */
	gint32 value, function, trunk, bchannel, source, event, curr_state, next_state;
	gint32 par0, par1, par2;
	gchar *frame_label = NULL;
	int direction = 0;
	int offset = 0;

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

	value = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_time, tvb, offset, 4, value);
	offset += 4;

	source = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_source, tvb, offset, 4, source);
	offset += 4;

	curr_state = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_current_state, tvb, offset, 4, curr_state);
	offset += 4;

	event = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_event, tvb, offset, 4, event);
	offset += 4;

	next_state = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_next_state, tvb, offset, 4, next_state);
	offset += 4;

	function = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_function, tvb, offset, 4, function);
	offset += 4;

	col_append_fstr(pinfo->cinfo, COL_INFO, "%s|%d|%s|%d|%s|",
			val_to_str_const(source, actrace_cas_source_vals_short, "ukn"),
			curr_state,
			val_to_str_ext(event, &actrace_cas_event_vals_ext, "%d"),
			next_state,
			val_to_str_ext(function, &actrace_cas_function_vals_ext, "%d"));

	par0 = tvb_get_ntohl(tvb, offset);
	switch (function)
	{
		case SEND_EVENT:
			proto_tree_add_text(actrace_tree, tvb, offset, 4,
				"Parameter 0: %s",  val_to_str_ext(par0,
				&actrace_cas_pstn_event_vals_ext, "Unknown (%d)"));
			col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
					val_to_str_ext(par0, &actrace_cas_pstn_event_vals_ext, "%d"));
			break;
		case CHANGE_COLLECT_TYPE:
			proto_tree_add_text(actrace_tree, tvb, offset, 4,
				"Parameter 0: %s", val_to_str(par0,
				actrace_cas_collect_type_vals, "Unknown (%d)"));
			col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
					val_to_str(par0, actrace_cas_collect_type_vals, "%d"));
			break;
		case SEND_MF:
		case SEND_DEST_NUM:
			proto_tree_add_text(actrace_tree, tvb, offset, 4,
				"Parameter 0: %s", val_to_str(par0,
				actrace_cas_send_type_vals, "Unknown (%d)"));
			col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
					val_to_str(par0, actrace_cas_send_type_vals, "%d"));
			break;
		default:
			proto_tree_add_int(actrace_tree, hf_actrace_cas_par0, tvb, offset, 4, par0);
			col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par0);
	}
	offset += 4;

	par1 = tvb_get_ntohl(tvb, offset);
	if (function == SEND_EVENT) {
		proto_tree_add_text(actrace_tree, tvb, offset, 4,
			"Parameter 1: %s", val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "Unknown (%d)"));
		col_append_fstr(pinfo->cinfo, COL_INFO, "%s|",
				val_to_str_ext(par1, &actrace_cas_cause_vals_ext, "%d"));
	} else {
		proto_tree_add_int(actrace_tree, hf_actrace_cas_par1, tvb, offset, 4, par1);
		col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par1);
	}
	offset += 4;

	par2 = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_par2, tvb, offset, 4, par2);
	col_append_fstr(pinfo->cinfo, COL_INFO, "%d|", par2);
	offset += 4;

	trunk = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_trunk, tvb, offset, 4, trunk);
	offset += 4;

	bchannel = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_bchannel, tvb, offset, 4, bchannel);
	offset += 4;

	col_prepend_fstr(pinfo->cinfo, COL_INFO, "t%db%d|", trunk, bchannel);

	value = tvb_get_ntohl(tvb, offset);
	proto_tree_add_int(actrace_tree, hf_actrace_cas_connection_id, tvb, offset, 4, value);

	/* Add tap info for the Voip Graph */
	if (source == ACTRACE_CAS_SOURCE_DSP) {
		direction = 1;
		if ( (event >= ACTRACE_CAS_EV_11) && (event <= ACTRACE_CAS_EV_00 ) ) {
			frame_label = ep_strdup_printf("AB: %s", val_to_str_const(event, actrace_cas_event_ab_vals, "ERROR") );
		} else if ( (event >= 32) && (event <= 46 ) ) { /* is an MF tone */
			frame_label = ep_strdup_printf("MF: %s", val_to_str_ext_const(event, &actrace_cas_mf_vals_ext, "ERROR") );
		} else if ( (event == ACTRACE_CAS_EV_DTMF ) || (event == ACTRACE_CAS_EV_FIRST_DIGIT ) ) { /* DTMF digit */
			frame_label = ep_strdup_printf("DTMF: %u", par0 );
		}
	} else if (source == ACTRACE_CAS_SOURCE_TABLE) {
		direction = 0;
		if (function == SEND_MF) {
			if (par0 == SEND_TYPE_SPECIFIC ) {
				frame_label = ep_strdup_printf("MF: %u", par1);
			} else if (par0 == SEND_TYPE_ADDRESS ) {
				frame_label = ep_strdup("MF: DNIS digit");
			} else if (par0 == SEND_TYPE_ANI  ) {
				frame_label = ep_strdup("MF: ANI digit");
			} else if (par0 == SEND_TYPE_SOURCE_CATEGORY ) {
				frame_label = ep_strdup("MF: src_category");
			} else if (par0 == SEND_TYPE_TRANSFER_CAPABILITY ) {
				frame_label = ep_strdup("MF: trf_capability");
			} else if (par0 == SEND_TYPE_INTER_EXCHANGE_SWITCH ) {
				frame_label = ep_strdup("MF: inter_exch_sw");
			}
		} else if (function == SEND_CAS) {
			frame_label = ep_strdup_printf("AB: %s", val_to_str_const(ACTRACE_CAS_EV_00-par0, actrace_cas_event_ab_vals, "ERROR"));
		} else if (function == SEND_DEST_NUM) {
			if (par0 == SEND_TYPE_ADDRESS ) {
				frame_label = ep_strdup("DTMF/MF: sending DNIS");
			} else if (par0 == SEND_TYPE_ANI ) {
				frame_label = ep_strdup("DTMF/MF: sending ANI");
			}
		}
	}

	if (frame_label != NULL) {
		/* Initialise packet info for passing to tap */
		actrace_pi = ep_new(actrace_info_t);

		actrace_pi->type = ACTRACE_CAS;
		actrace_pi->direction = direction;
		actrace_pi->trunk = trunk;
		actrace_pi->cas_bchannel = bchannel;
		actrace_pi->cas_frame_label = frame_label;
		/* Report this packet to the tap */
		tap_queue_packet(actrace_tap, pinfo, actrace_pi);
	}
}
Exemplo n.º 12
0
bool dissect_protobuf_repeated_field(const FieldDescriptor* field, const Message* message, tvbuff_t *tvb, guint* offset, proto_tree *leaf, int iRepeatedIndex)
{
    int len = 0;
    string scratch;

    if( !field->options().packed() )
    {
      len += WireFormat::TagSize( field->number(), field->type() );
    }

    map<string, Handles*>::iterator it = g_mapHandles.find( field->full_name() );
    if( it == g_mapHandles.end() )
    {
        return false; // bug
    }
    
    Handles* handles = it->second;
    const Reflection *reflection = message->GetReflection();
    const EnumValueDescriptor* enumDesc = NULL;

    switch( field->cpp_type() )
    {
    case FieldDescriptor::CPPTYPE_UINT32:
        if( field->type() == FieldDescriptor::TYPE_FIXED32 )
        {
            len += WireFormatLite::kFixed32Size;
        }
        else
        {
            len += WireFormatLite::UInt32Size( reflection->GetRepeatedUInt32( *message, field, iRepeatedIndex )  );      
        }
        proto_tree_add_uint( leaf, handles->p_id, tvb, *offset, len,  
			   reflection->GetRepeatedUInt32( *message, field, iRepeatedIndex ) );
      break;
    case FieldDescriptor::CPPTYPE_INT32:
        if( field->type() == FieldDescriptor::TYPE_SFIXED32 )
        {
            len += WireFormatLite::kSFixed32Size;
        }
        else if( field->type() == FieldDescriptor::TYPE_SINT32 )
        {
            len += WireFormatLite::SInt32Size( reflection->GetRepeatedInt32( *message, field, iRepeatedIndex )  );	
        }
        else
        {
            len += WireFormatLite::Int32Size( reflection->GetRepeatedInt32( *message, field, iRepeatedIndex )  );	
        }
        proto_tree_add_int( leaf, handles->p_id, tvb, *offset, len,  
			      reflection->GetRepeatedInt32( *message, field, iRepeatedIndex ) );
      break;
    case FieldDescriptor::CPPTYPE_FLOAT:
        len += WireFormatLite::kFloatSize;
        proto_tree_add_float( leaf, handles->p_id, tvb, *offset, len,  
			    reflection->GetRepeatedFloat( *message, field, iRepeatedIndex ) );
      break;
    case FieldDescriptor::CPPTYPE_UINT64:
        if( field->type() == FieldDescriptor::TYPE_FIXED64 )
        {
            len += WireFormatLite::kFixed64Size;
        }
        else
        {
            len += WireFormatLite::UInt64Size( reflection->GetRepeatedUInt64( *message, field, iRepeatedIndex )  );	
        }
        proto_tree_add_uint64( leaf, handles->p_id, tvb, *offset, len,  
			     reflection->GetRepeatedUInt64( *message, field, iRepeatedIndex ) );
      break;
    case FieldDescriptor::CPPTYPE_INT64:
        if( field->type() == FieldDescriptor::TYPE_SFIXED64 )
        {
            len += WireFormatLite::kSFixed64Size;
        }
        else if( field->type() == FieldDescriptor::TYPE_SINT64 )
        {
            len += WireFormatLite::SInt64Size( reflection->GetRepeatedInt64( *message, field, iRepeatedIndex )  );	
        }
        else
        {
            len += WireFormatLite::Int64Size( reflection->GetRepeatedInt64( *message, field, iRepeatedIndex )  );	
        }
        proto_tree_add_int64( leaf, handles->p_id, tvb, *offset, len,  
			    reflection->GetRepeatedInt64( *message, field, iRepeatedIndex ) );
      break;
    case FieldDescriptor::CPPTYPE_DOUBLE:
        len += WireFormatLite::kDoubleSize;
        proto_tree_add_double( leaf, handles->p_id, tvb, *offset, len,  
			     reflection->GetRepeatedDouble( *message, field, iRepeatedIndex ) );
      break;
    case FieldDescriptor::CPPTYPE_BOOL:
        len += WireFormatLite::kBoolSize;
        proto_tree_add_boolean( leaf, handles->p_id, tvb, *offset, len,
			      reflection->GetRepeatedBool( *message, field, iRepeatedIndex ) );
      break;
    case FieldDescriptor::CPPTYPE_ENUM:
        enumDesc = reflection->GetRepeatedEnum( *message, field, iRepeatedIndex );
        len += WireFormatLite::EnumSize( enumDesc->number() );
        proto_tree_add_int_format_value( leaf, handles->p_id, tvb, *offset, len, 
				       enumDesc->number(), "%d ( %s )", enumDesc->number(),
				       enumDesc->name().c_str() );
      break;
    case FieldDescriptor::CPPTYPE_STRING:
        len += WireFormatLite::StringSize( reflection->GetRepeatedStringReference( *message, field, iRepeatedIndex, &scratch ) );
        proto_tree_add_string( leaf, handles->p_id, tvb, *offset, len,  
			     reflection->GetRepeatedString( *message, field, iRepeatedIndex ).c_str() );
      break;
    default:
        proto_tree_add_item( leaf, handles->p_id, tvb, *offset, len, true );
    };

    *offset += len;
    
    return true;
}
Exemplo n.º 13
0
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
                                 gint n, proto_tree *tree,
                                 pgsql_conn_data_t *conv_data)
{
    guchar c;
    gint i, siz;
    char *s, *t;
    gint32 num_nonsupported_options;
    proto_item *ti;
    proto_tree *shrub;
    guint32 auth_type;

    switch (type) {
    /* Authentication request */
    case 'R':
        proto_tree_add_item_ret_uint(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN, &auth_type);
        switch (auth_type) {
        case PGSQL_AUTH_TYPE_CRYPT:
        case PGSQL_AUTH_TYPE_MD5:
            n += 4;
            siz = (auth_type == PGSQL_AUTH_TYPE_CRYPT ? 2 : 4);
            proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA);
            break;
        case PGSQL_AUTH_TYPE_GSSAPI_SSPI_CONTINUE:
            conv_data->auth_state = PGSQL_AUTH_GSSAPI_SSPI_DATA;
            proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-8, ENC_NA);
            break;
        case PGSQL_AUTH_TYPE_SASL:
            conv_data->auth_state = PGSQL_AUTH_SASL_REQUESTED;
            n += 4;
            while ((guint)n < length) {
                siz = tvb_strsize(tvb, n);
                proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA);
                n += siz;
            }
            break;
        case PGSQL_AUTH_TYPE_SASL_CONTINUE:
        case PGSQL_AUTH_TYPE_SASL_COMPLETE:
            conv_data->auth_state = PGSQL_AUTH_SASL_CONTINUE;
            n += 4;
            if ((guint)n < length) {
                proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-8, ENC_NA);
            }
            break;
        }
        break;

    /* Key data */
    case 'K':
        proto_tree_add_item(tree, hf_pid, tvb, n,   4, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN);
        break;

    /* Parameter status */
    case 'S':
        s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII);
        proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s);
        n += siz;
        t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII);
        proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t);
        break;

    /* Parameter description */
    case 't':
        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
        }
        break;

    /* Row description */
    case 'T':
        i = tvb_get_ntohs(tvb, n);
        ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN);
        shrub = proto_item_add_subtree(ti, ett_values);
        n += 2;
        while (i-- > 0) {
            proto_tree *twig;
            siz = tvb_strsize(tvb, n);
            ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA);
            twig = proto_item_add_subtree(ti, ett_values);
            n += siz;
            proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
            proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
            proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Data row */
    case 'D':
        i = tvb_get_ntohs(tvb, n);
        ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN);
        shrub = proto_item_add_subtree(ti, ett_values);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }
        break;

    /* Command completion */
    case 'C':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Ready */
    case 'Z':
        proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_BIG_ENDIAN);
        break;

    /* Error, Notice */
    case 'E':
    case 'N':
        length -= 4;
        while ((signed)length > 0) {
            c = tvb_get_guint8(tvb, n);
            if (c == '\0')
                break;
            s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII);
            i = hf_text;
            switch (c) {
            case 'S': i = hf_severity;          break;
            case 'C': i = hf_code;              break;
            case 'M': i = hf_message;           break;
            case 'D': i = hf_detail;            break;
            case 'H': i = hf_hint;              break;
            case 'P': i = hf_position;          break;
            case 'p': i = hf_internal_position; break;
            case 'q': i = hf_internal_query;    break;
            case 'W': i = hf_where;             break;
            case 's': i = hf_schema_name;       break;
            case 't': i = hf_table_name;        break;
            case 'c': i = hf_column_name;       break;
            case 'd': i = hf_type_name;         break;
            case 'n': i = hf_constraint_name;   break;
            case 'F': i = hf_file;              break;
            case 'L': i = hf_line;              break;
            case 'R': i = hf_routine;           break;
            }
            proto_tree_add_string(tree, i, tvb, n, siz+1, s);
            length -= siz+1;
            n += siz+1;
        }
        break;

    /* NOTICE response */
    case 'A':
        proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;
        siz = tvb_strsize(tvb, n);
        if (siz > 1)
            proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Copy in/out */
    case 'G':
    case 'H':
        proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN);
        n += 1;
        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i);
        n += 2;
        while (i-- > 2) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Copy data */
    case 'd':
        proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA);
        break;

    /* Function call response */
    case 'V':
        siz = tvb_get_ntohl(tvb, n);
        proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz);
        if (siz > 0)
            proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA);
        break;

    /* Negotiate Protocol Version */
    case 'v':
        proto_tree_add_item(tree, hf_supported_minor_version, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;
        proto_tree_add_item_ret_int(tree, hf_number_nonsupported_options, tvb, n, 4, ENC_BIG_ENDIAN, &num_nonsupported_options);
        n += 4;
        while (num_nonsupported_options > 0) {
            siz = tvb_strsize(tvb, n);
            proto_tree_add_item(tree, hf_nonsupported_option, tvb, n, siz, ENC_ASCII|ENC_NA);
            n += siz;
            num_nonsupported_options--;
        }
        break;
    }
}
Exemplo n.º 14
0
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb,
                                 gint n, proto_tree *tree,
                                 pgsql_conn_data_t *conv_data)
{
    guchar c;
    gint i, siz;
    char *s;
    proto_tree *shrub;
    gint32 data_length;

    switch (type) {
    /* Password, SASL or GSSAPI Response, depending on context */
    case 'p':
        switch(conv_data->auth_state) {

            case PGSQL_AUTH_SASL_REQUESTED:
                /* SASLInitResponse */
                siz = tvb_strsize(tvb, n);
                proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA);
                n += siz;
                proto_tree_add_item_ret_int(tree, hf_sasl_auth_data_length, tvb, n, 4, ENC_BIG_ENDIAN, &data_length);
                n += 4;
                if (data_length) {
                    proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, data_length, ENC_NA);
                    n += data_length;
                }
                break;

            case PGSQL_AUTH_SASL_CONTINUE:
                proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-4, ENC_NA);
                break;

            case PGSQL_AUTH_GSSAPI_SSPI_DATA:
                proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-4, ENC_NA);
                break;

            default:
                siz = tvb_strsize(tvb, n);
                proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA);
                break;
        }
        break;

    /* Simple query */
    case 'Q':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Parse */
    case 'P':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
        }
        break;

    /* Bind */
    case 'B':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Execute */
    case 'E':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohl(tvb, n);
        if (i == 0)
            proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows");
        else
            proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i);
        break;

    /* Describe, Close */
    case 'D':
    case 'C':
        c = tvb_get_guint8(tvb, n);
        if (c == 'P')
            i = hf_portal;
        else
            i = hf_statement;

        n += 1;
        s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII);
        proto_tree_add_string(tree, i, tvb, n, siz, s);
        break;

    /* Messages without a type identifier */
    case '\0':
        i = tvb_get_ntohl(tvb, n);
        n += 4;
        length -= n;
        switch (i) {
        /* Startup message */
        case 196608:
            proto_tree_add_item(tree, hf_version_major, tvb, n-4, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(tree, hf_version_minor, tvb, n-2, 2, ENC_BIG_ENDIAN);
            while ((signed)length > 0) {
                siz = tvb_strsize(tvb, n);
                length -= siz;
                if ((signed)length <= 0) {
                    break;
                }
                proto_tree_add_item(tree, hf_parameter_name,  tvb, n,       siz, ENC_ASCII|ENC_NA);
                i = tvb_strsize(tvb, n+siz);
                proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i,   ENC_ASCII|ENC_NA);
                length -= i;

                n += siz+i;
                if (length == 1 && tvb_get_guint8(tvb, n) == 0)
                    break;
            }
            break;

        /* SSL request */
        case 80877103:
            /* Next reply will be a single byte. */
            conv_data->ssl_requested = TRUE;
            break;

        /* Cancellation request */
        case 80877102:
            proto_tree_add_item(tree, hf_pid, tvb, n,   4, ENC_BIG_ENDIAN);
            proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN);
            break;
        }
        break;

    /* Copy data */
    case 'd':
        proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA);
        break;

    /* Copy failure */
    case 'f':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Function call */
    case 'F':
        proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }

        proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
        break;
    }
}
Exemplo n.º 15
0
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb,
                                 gint n, proto_tree *tree)
{
    guchar c;
    gint i, siz;
    char *s;
    proto_tree *shrub;

    switch (type) {
    /* Password */
    case 'p':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Simple query */
    case 'Q':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Parse */
    case 'P':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
        }
        break;

    /* Bind */
    case 'B':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Execute */
    case 'E':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;

        i = tvb_get_ntohl(tvb, n);
        if (i == 0)
            proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows");
        else
            proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i);
        break;

    /* Describe, Close */
    case 'D':
    case 'C':
        c = tvb_get_guint8(tvb, n);
        if (c == 'P')
            i = hf_portal;
        else
            i = hf_statement;

        n += 1;
        s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII);
        proto_tree_add_string(tree, i, tvb, n, siz, s);
        break;

    /* Messages without a type identifier */
    case '\0':
        i = tvb_get_ntohl(tvb, n);
        n += 4;
        length -= n;
        switch (i) {
        /* Startup message */
        case 196608:
            while ((signed)length > 0) {
                siz = tvb_strsize(tvb, n);
                length -= siz;
                if ((signed)length <= 0) {
                    break;
                }
                proto_tree_add_item(tree, hf_parameter_name,  tvb, n,       siz, ENC_ASCII|ENC_NA);
                i = tvb_strsize(tvb, n+siz);
                proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i,   ENC_ASCII|ENC_NA);
                length -= i;

                n += siz+i;
                if (length == 1 && tvb_get_guint8(tvb, n) == 0)
                    break;
            }
            break;

        /* SSL request */
        case 80877103:
            /* There's nothing to parse here, but what do we do if the
               SSL negotiation succeeds? */
            break;

        /* Cancellation request */
        case 80877102:
            proto_tree_add_item(tree, hf_pid, tvb, n,   4, ENC_BIG_ENDIAN);
            proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN);
            break;
        }
        break;

    /* Copy data */
    case 'd':
        proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA);
        break;

    /* Copy failure */
    case 'f':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Function call */
    case 'F':
        proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }

        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }

        proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
        break;
    }
}
Exemplo n.º 16
0
static void
dissect_hci_h1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	guint8      type;
	tvbuff_t   *next_tvb;
	proto_item *ti=NULL;
	proto_tree *hci_h1_tree = NULL;
	void       *pd_save;
	hci_data_t *hci_data;

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

	col_clear(pinfo->cinfo, COL_INFO);

	type = pinfo->pseudo_header->bthci.channel;

	if(tree){
		ti = proto_tree_add_item(tree, proto_hci_h1, tvb, 0, 0, ENC_NA);
		hci_h1_tree = proto_item_add_subtree(ti, ett_hci_h1);

		if(pinfo->p2p_dir == P2P_DIR_SENT ||
		   pinfo->p2p_dir == P2P_DIR_RECV)
			proto_item_append_text(hci_h1_tree, " %s %s",
					       val_to_str(pinfo->p2p_dir,
							  hci_h1_direction_vals, "Unknown: %d"),
					       val_to_str(type,
							  hci_h1_type_vals,
							  "Unknown 0x%02x"));
		else
			proto_item_append_text(hci_h1_tree, " %s",
					       val_to_str(type,
							  hci_h1_type_vals,
							  "Unknown 0x%02x"));
	}

	if(check_col(pinfo->cinfo, COL_INFO)){
		if(pinfo->p2p_dir == P2P_DIR_SENT ||
		   pinfo->p2p_dir == P2P_DIR_RECV)
			col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
				     val_to_str(pinfo->p2p_dir,
						hci_h1_direction_vals, "Unknown: %d"),
				     val_to_str(type, hci_h1_type_vals,
						"Unknown 0x%02x"));
		else
			col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
				     val_to_str(type, hci_h1_type_vals,
						"Unknown 0x%02x"));
	}

	pd_save = pinfo->private_data;
	hci_data = ep_alloc(sizeof(hci_data_t));
	hci_data->interface_id = HCI_INTERFACE_H4;
	hci_data->adapter_id = HCI_ADAPTER_DEFAULT;
	hci_data->chandle_to_bdaddr_table = chandle_to_bdaddr_table;
	hci_data->bdaddr_to_name_table = bdaddr_to_name_table;
	hci_data->localhost_bdaddr = localhost_bdaddr;
	hci_data->localhost_name = localhost_name;
	pinfo->private_data = hci_data;

	ti=proto_tree_add_int(hci_h1_tree, hf_hci_h1_direction, tvb, 0, 0, pinfo->p2p_dir);
	PROTO_ITEM_SET_GENERATED(ti);

	next_tvb = tvb_new_subset_remaining(tvb, 0);
	if(!dissector_try_uint(hci_h1_table, type, next_tvb, pinfo, tree)) {
		call_dissector(data_handle, next_tvb, pinfo, tree);
	}

	pinfo->private_data = pd_save;
}
Exemplo n.º 17
0
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb,
                                 gint n, proto_tree *tree)
{
    guchar c;
    gint i, siz;
    char *s, *t;
    proto_item *ti;
    proto_tree *shrub;

    switch (type) {
    /* Authentication request */
    case 'R':
        proto_tree_add_item(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN);
        i = tvb_get_ntohl(tvb, n);
        if (i == 4 || i == 5) {
            /* i -= (6-i); :-) */
            n += 4;
            siz = (i == 4 ? 2 : 4);
            proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA);
        }
        break;

    /* Key data */
    case 'K':
        proto_tree_add_item(tree, hf_pid, tvb, n,   4, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN);
        break;

    /* Parameter status */
    case 'S':
        s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII);
        proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s);
        n += siz;
        t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII);
        proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t);
        break;

    /* Parameter description */
    case 't':
        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i);
        n += 2;
        while (i-- > 0) {
            proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
        }
        break;

    /* Row description */
    case 'T':
        i = tvb_get_ntohs(tvb, n);
        ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN);
        shrub = proto_item_add_subtree(ti, ett_values);
        n += 2;
        while (i-- > 0) {
            proto_tree *twig;
            siz = tvb_strsize(tvb, n);
            ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA);
            twig = proto_item_add_subtree(ti, ett_values);
            n += siz;
            proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
            proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
            proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN);
            n += 4;
            proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Data row */
    case 'D':
        i = tvb_get_ntohs(tvb, n);
        ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN);
        shrub = proto_item_add_subtree(ti, ett_values);
        n += 2;
        while (i-- > 0) {
            siz = tvb_get_ntohl(tvb, n);
            proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz);
            n += 4;
            if (siz > 0) {
                proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA);
                n += siz;
            }
        }
        break;

    /* Command completion */
    case 'C':
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Ready */
    case 'Z':
        proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_NA);
        break;

    /* Error, Notice */
    case 'E':
    case 'N':
        length -= 4;
        while ((signed)length > 0) {
            c = tvb_get_guint8(tvb, n);
            if (c == '\0')
                break;
            s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII);
            i = hf_text;
            switch (c) {
            case 'S': i = hf_severity;          break;
            case 'C': i = hf_code;              break;
            case 'M': i = hf_message;           break;
            case 'D': i = hf_detail;            break;
            case 'H': i = hf_hint;              break;
            case 'P': i = hf_position;          break;
            case 'p': i = hf_internal_position; break;
            case 'q': i = hf_internal_query;    break;
            case 'W': i = hf_where;             break;
            case 's': i = hf_schema_name;       break;
            case 't': i = hf_table_name;        break;
            case 'c': i = hf_column_name;       break;
            case 'd': i = hf_type_name;         break;
            case 'n': i = hf_constraint_name;   break;
            case 'F': i = hf_file;              break;
            case 'L': i = hf_line;              break;
            case 'R': i = hf_routine;           break;
            }
            proto_tree_add_string(tree, i, tvb, n, siz+1, s);
            length -= siz+1;
            n += siz+1;
        }
        break;

    /* NOTICE response */
    case 'A':
        proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN);
        n += 4;
        siz = tvb_strsize(tvb, n);
        proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA);
        n += siz;
        siz = tvb_strsize(tvb, n);
        if (siz > 1)
            proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA);
        break;

    /* Copy in/out */
    case 'G':
    case 'H':
        proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN);
        n += 1;
        i = tvb_get_ntohs(tvb, n);
        shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i);
        n += 2;
        while (i-- > 2) {
            proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN);
            n += 2;
        }
        break;

    /* Copy data */
    case 'd':
        proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA);
        break;

    /* Function call response */
    case 'V':
        siz = tvb_get_ntohl(tvb, n);
        proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz);
        if (siz > 0)
            proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA);
        break;
    }
}
Exemplo n.º 18
0
static void
dissect_nettl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
      proto_tree *nettl_tree;
      proto_item *nettl_item;

      pinfo->current_proto = "nettl";

      if (tree) {
	    nettl_item = proto_tree_add_protocol_format(tree, proto_nettl, tvb,
		0, -1, "HP-UX Network Tracing and Logging (nettl) header");
	    nettl_tree = proto_item_add_subtree(nettl_item, ett_nettl);
            proto_tree_add_uint_format(nettl_tree, hf_nettl_subsys, tvb,
		0, 0, pinfo->pseudo_header->nettl.subsys,
		"Subsystem: %d (%s)", pinfo->pseudo_header->nettl.subsys,
		val_to_str_const(pinfo->pseudo_header->nettl.subsys, subsystem, "Unknown"));
            proto_tree_add_int(nettl_tree, hf_nettl_devid, tvb,
		0, 0, pinfo->pseudo_header->nettl.devid);
            proto_tree_add_uint_format(nettl_tree, hf_nettl_kind, tvb,
		0, 0, pinfo->pseudo_header->nettl.kind,
		"Trace Kind: 0x%08x (%s)", pinfo->pseudo_header->nettl.kind,
		val_to_str_const(pinfo->pseudo_header->nettl.kind & ~NETTL_HDR_SUBSYSTEM_BITS_MASK, trace_kind, "Unknown"));
            proto_tree_add_int(nettl_tree, hf_nettl_pid, tvb,
		0, 0, pinfo->pseudo_header->nettl.pid);
            proto_tree_add_uint(nettl_tree, hf_nettl_uid, tvb,
		0, 0, pinfo->pseudo_header->nettl.uid);

      }

      switch (pinfo->fd->lnk_t) {
         case WTAP_ENCAP_NETTL_ETHERNET:
            call_dissector(eth_withoutfcs_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_TOKEN_RING:
            call_dissector(tr_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_FDDI:
            if (!dissector_try_uint(wtap_dissector_table,
			WTAP_ENCAP_FDDI_BITSWAPPED, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_RAW_IP:
            if ( (pinfo->pseudo_header->nettl.kind & NETTL_HDR_PDU_MASK) == 0 )
                    /* not actually a data packet (PDU) trace record */
	            call_dissector(data_handle, tvb, pinfo, tree);
            else if (pinfo->pseudo_header->nettl.subsys == NETTL_SUBSYS_NS_LS_SCTP )
                    call_dissector(sctp_handle, tvb, pinfo, tree);
            else if (!dissector_try_uint(wtap_dissector_table,
			WTAP_ENCAP_RAW_IP, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_RAW_ICMP:
            if (!dissector_try_uint(ip_proto_dissector_table,
			IP_PROTO_ICMP, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_RAW_ICMPV6:
            if (!dissector_try_uint(ip_proto_dissector_table,
	                IP_PROTO_ICMPV6, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_X25:
	    if (pinfo->pseudo_header->nettl.kind == NETTL_HDR_PDUIN)
            	pinfo->p2p_dir = P2P_DIR_RECV;
	    else if (pinfo->pseudo_header->nettl.kind == NETTL_HDR_PDUOUT)
            	pinfo->p2p_dir = P2P_DIR_SENT;
	    if (pinfo->pseudo_header->nettl.subsys == NETTL_SUBSYS_SX25L2)
            	call_dissector(lapb_handle, tvb, pinfo, tree);
	    else
            	call_dissector(x25_handle, tvb, pinfo, tree);
            break;
         case WTAP_ENCAP_NETTL_RAW_TELNET:
            if (!dissector_try_uint(tcp_subdissector_table,
	                TCP_PORT_TELNET, tvb, pinfo, tree))
	            call_dissector(data_handle, tvb, pinfo, tree);
            break;
         default:
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
            if (check_col(pinfo->cinfo, COL_INFO))
                col_add_fstr(pinfo->cinfo, COL_INFO,
		"Unsupported nettl subsytem: %d (%s)",
                pinfo->pseudo_header->nettl.subsys,
		val_to_str_const(pinfo->pseudo_header->nettl.subsys, subsystem, "Unknown"));
            call_dissector(data_handle, tvb, pinfo, tree);
      }
}
static void
dissect_radiotap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *radiotap_tree = NULL;
    proto_tree *pt, *present_tree = NULL;
    proto_tree *ft;
    proto_item *ti = NULL, *hidden_item;
    int align_offset, offset;
    tvbuff_t *next_tvb;
    guint32 version;
    guint length, length_remaining;
    guint32 rate, freq, flags;
    gint8 dbm;
    guint8 db, rflags;
    guint32 present, next_present;
    int bit;
    /* backward compat with bit 14 == fcs in header */
    proto_item *hdr_fcs_ti = NULL;
    int hdr_fcs_offset = 0;
    guint32 sent_fcs = 0;
    guint32 calc_fcs;

    struct _radiotap_info *radiotap_info;
    static struct _radiotap_info rtp_info_arr[1];
    
    radiotap_info = &rtp_info_arr[0];

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN");
    col_clear(pinfo->cinfo, COL_INFO);
    offset = 0;

    version = tvb_get_guint8(tvb, offset);
    length = tvb_get_letohs(tvb, offset+2);
    present = tvb_get_letohl(tvb, offset+4);
    
    radiotap_info->radiotap_length = length;

    col_add_fstr(pinfo->cinfo, COL_INFO, "Radiotap Capture v%u, Length %u",
		version, length);

    /* Dissect the packet */
    if (tree) {
	ti = proto_tree_add_protocol_format(tree, proto_radiotap,
		tvb, 0, length, "Radiotap Header v%u, Length %u", version, length);
	radiotap_tree = proto_item_add_subtree(ti, ett_radiotap);
	proto_tree_add_uint(radiotap_tree, hf_radiotap_version,
		tvb, offset, 1, version);
	proto_tree_add_item(radiotap_tree, hf_radiotap_pad,
		tvb, offset + 1, 1, FALSE);
	ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_length,
		tvb, offset + 2, 2, length);
    }
    length_remaining = length;

    /*
     * FIXME: This only works if there is exactly 1 it_present
     *        field in the header
     */
    if (length_remaining < RADIOTAP_MIN_HEADER_LEN) {
	/*
	 * Radiotap header is shorter than the fixed-length portion
	 * plus one "present" bitset.
	 */
	if (tree)
	    proto_item_append_text(ti, " (bogus - minimum length is 8)");
	return;
    }
    /* Subtree for the "present flags" bitfield. */
    if (tree) {
	pt = proto_tree_add_uint(radiotap_tree, hf_radiotap_present,
	    tvb, offset + 4, 4, present);
	present_tree = proto_item_add_subtree(pt, ett_radiotap_present);

	proto_tree_add_item(present_tree, hf_radiotap_present_tsft,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_flags,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_rate,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_channel,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_fhss,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antsignal,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_dbm_antnoise,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_lock_quality,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_tx_attenuation,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_db_tx_attenuation,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_dbm_tx_attenuation,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_antenna,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_db_antsignal,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_db_antnoise,
	    tvb, offset + 4, 4, TRUE);
	if (radiotap_bit14_fcs) {
		proto_tree_add_item(present_tree, hf_radiotap_present_hdrfcs,
			tvb, offset + 4, 4, TRUE);
	} else {
		proto_tree_add_item(present_tree, hf_radiotap_present_rxflags,
			tvb, offset + 4, 4, TRUE);
	}
	proto_tree_add_item(present_tree, hf_radiotap_present_xchannel,
	    tvb, offset + 4, 4, TRUE);
	proto_tree_add_item(present_tree, hf_radiotap_present_ext,
	    tvb, offset + 4, 4, TRUE);
    }
    offset += RADIOTAP_MIN_HEADER_LEN;
    length_remaining -= RADIOTAP_MIN_HEADER_LEN;

    rflags = 0;
    for (; present; present = next_present) {
	/* clear the least significant bit that is set */
	next_present = present & (present - 1);

	/* extract the least significant bit that is set */
	bit = BITNO_32(present ^ next_present);

	switch (bit) {

	case IEEE80211_RADIOTAP_TSFT:
	    align_offset = ALIGN_OFFSET(offset, 8);
	    offset += align_offset;
	    length_remaining -= align_offset;
	    if (length_remaining < 8)
		break;
            radiotap_info->tsft=tvb_get_letoh64(tvb, offset);
	    if (tree) {
		proto_tree_add_uint64(radiotap_tree, hf_radiotap_mactime,
				tvb, offset, 8,radiotap_info->tsft );
	    }
	    offset+=8;
	    length_remaining-=8;
	    break;

	case IEEE80211_RADIOTAP_FLAGS:
	{
	    proto_tree *flags_tree;
	    if (length_remaining < 1)
		break;
	    rflags = tvb_get_guint8(tvb, offset);
	    if (tree) {
		ft = proto_tree_add_item(radiotap_tree, hf_radiotap_flags,
					 tvb, offset, 1, FALSE);
		flags_tree = proto_item_add_subtree(ft, ett_radiotap_flags);

		proto_tree_add_item(flags_tree, hf_radiotap_flags_cfp,
			tvb, offset, 1, FALSE);
		proto_tree_add_item(flags_tree, hf_radiotap_flags_preamble,
			tvb, offset, 1, FALSE);
		proto_tree_add_item(flags_tree, hf_radiotap_flags_wep,
			tvb, offset, 1, FALSE);
		proto_tree_add_item(flags_tree, hf_radiotap_flags_frag,
			tvb, offset, 1, FALSE);
		proto_tree_add_item(flags_tree, hf_radiotap_flags_fcs,
			tvb, offset, 1, FALSE);
		proto_tree_add_item(flags_tree, hf_radiotap_flags_datapad,
			tvb, offset, 1, FALSE);
		proto_tree_add_item(flags_tree, hf_radiotap_flags_badfcs,
			tvb, offset, 1, FALSE);
		proto_tree_add_item(flags_tree, hf_radiotap_flags_shortgi,
			tvb, offset, 1, FALSE);
	    }
	    offset++;
	    length_remaining--;
	    break;
	}

	case IEEE80211_RADIOTAP_RATE:
	    if (length_remaining < 1)
		break;
	    rate = tvb_get_guint8(tvb, offset);
	    if (rate & 0x80) {
		/* XXX adjust by CW and short GI like other sniffers? */
		rate = ieee80211_htrates[rate & 0xf];
	    }
	    col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%d.%d",
		rate / 2, rate & 1 ? 5 : 0);
	    if (tree) {
		proto_tree_add_float_format(radiotap_tree, hf_radiotap_datarate,
			tvb, offset, 1, (float)rate / 2,
			"Data Rate: %.1f Mb/s", (float)rate / 2);
	    }
	    offset++;
	    length_remaining--;
            radiotap_info->rate = rate;
	    break;

	case IEEE80211_RADIOTAP_CHANNEL:
	{
	    proto_item *it;
	    proto_tree *flags_tree;
	    gchar *chan_str;

	    align_offset = ALIGN_OFFSET(offset, 2);
	    offset += align_offset;
	    length_remaining -= align_offset;
	    if (length_remaining < 2)
		break;
	    if (tree) {
		freq = tvb_get_letohs(tvb, offset);
		flags = tvb_get_letohs(tvb, offset+2);
		chan_str = ieee80211_mhz_to_str(freq);
		col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%s", chan_str);
		proto_tree_add_uint_format(radiotap_tree, hf_radiotap_channel_frequency,
				tvb, offset, 2, freq,
				"Channel frequency: %s", chan_str);
		g_free(chan_str);
		/* We're already 2-byte aligned. */
		it = proto_tree_add_uint(radiotap_tree, hf_radiotap_channel_flags,
			tvb, offset+2, 2, flags);
		flags_tree = proto_item_add_subtree(it, ett_radiotap_channel_flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_turbo,
			tvb, offset+2, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_cck,
			tvb, offset+2, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_ofdm,
			tvb, offset+2, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_2ghz,
			tvb, offset+2, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_5ghz,
			tvb, offset+3, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_passive,
			tvb, offset+3, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_dynamic,
			tvb, offset+3, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gfsk,
			tvb, offset+3, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_gsm,
			tvb, offset+3, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_sturbo,
			tvb, offset+3, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_half,
			tvb, offset+3, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_channel_flags_quarter,
			tvb, offset+3, 1, flags);
		radiotap_info->freq=freq;
		radiotap_info->flags=flags;
	    }
	    offset+=4 /* Channel + flags */;
	    length_remaining-=4;
	    break;
	}

	case IEEE80211_RADIOTAP_FHSS:
	    align_offset = ALIGN_OFFSET(offset, 2);
	    offset += align_offset;
	    length_remaining -= align_offset;
	    if (length_remaining < 2)
		break;
	    proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_hopset,
		tvb, offset, 1, FALSE);
	    proto_tree_add_item(radiotap_tree, hf_radiotap_fhss_pattern,
		tvb, offset, 1, FALSE);
	    offset+=2;
	    length_remaining-=2;
	    break;

	case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
	    if (length_remaining < 1)
		break;
	    dbm = (gint8) tvb_get_guint8(tvb, offset);
	    col_add_fstr(pinfo->cinfo, COL_RSSI, "%d dBm", dbm);
	    if (tree) {
		proto_tree_add_int_format(radiotap_tree,
					  hf_radiotap_dbm_antsignal,
					  tvb, offset, 1, dbm,
					  "SSI Signal: %d dBm", dbm);
	    }
	    offset++;
	    length_remaining--;
            radiotap_info->dbm_antsignal=dbm;
	    break;

	case IEEE80211_RADIOTAP_DBM_ANTNOISE:
	    if (length_remaining < 1)
		break;
	    dbm = (gint8) tvb_get_guint8(tvb, offset);
	    if (tree) {
		proto_tree_add_int_format(radiotap_tree,
					  hf_radiotap_dbm_antnoise,
					  tvb, offset, 1, dbm,
					  "SSI Noise: %d dBm", dbm);
	    }
	    offset++;
	    length_remaining--;
            radiotap_info->dbm_antnoise=dbm;
	    break;

	case IEEE80211_RADIOTAP_LOCK_QUALITY:
	    align_offset = ALIGN_OFFSET(offset, 2);
	    offset += align_offset;
	    length_remaining -= align_offset;
	    if (length_remaining < 2)
		break;
	    if (tree) {
		proto_tree_add_uint(radiotap_tree, hf_radiotap_quality,
				tvb, offset, 2, tvb_get_letohs(tvb, offset));
	    }
	    offset+=2;
	    length_remaining-=2;
	    break;

	case IEEE80211_RADIOTAP_TX_ATTENUATION:
	    align_offset = ALIGN_OFFSET(offset, 2);
	    offset += align_offset;
	    length_remaining -= align_offset;
	    if (length_remaining < 2)
		break;
	    proto_tree_add_item(radiotap_tree, hf_radiotap_tx_attenuation,
		tvb, offset, 2, FALSE);
	    offset+=2;
	    length_remaining-=2;
	    break;

	case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
	    align_offset = ALIGN_OFFSET(offset, 2);
	    offset += align_offset;
	    length_remaining -= align_offset;
	    if (length_remaining < 2)
		break;
	    proto_tree_add_item(radiotap_tree, hf_radiotap_db_tx_attenuation,
		tvb, offset, 2, FALSE);
	    offset+=2;
	    length_remaining-=2;
	    break;

	case IEEE80211_RADIOTAP_DBM_TX_POWER:
	    if (length_remaining < 1)
		break;
	    if (tree) {
		proto_tree_add_int(radiotap_tree, hf_radiotap_txpower,
				   tvb, offset, 1, tvb_get_guint8(tvb, offset));
	    }
	    offset++;
	    length_remaining--;
	    break;

	case IEEE80211_RADIOTAP_ANTENNA:
	    if (length_remaining < 1)
		break;
	    if (tree) {
		proto_tree_add_uint(radiotap_tree, hf_radiotap_antenna,
				   tvb, offset, 1, tvb_get_guint8(tvb, offset));
	    }
	    offset++;
	    length_remaining--;
	    break;

	case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
	    if (length_remaining < 1)
		break;
	    db = tvb_get_guint8(tvb, offset);
	    col_add_fstr(pinfo->cinfo, COL_RSSI, "%u dB", db);
	    if (tree) {
		proto_tree_add_uint_format(radiotap_tree,
					   hf_radiotap_db_antsignal,
					   tvb, offset, 1, db,
					   "SSI Signal: %u dB", db);
	    }
	    offset++;
	    length_remaining--;
	    break;

	case IEEE80211_RADIOTAP_DB_ANTNOISE:
	    if (length_remaining < 1)
		break;
	    db = tvb_get_guint8(tvb, offset);
	    if (tree) {
		proto_tree_add_uint_format(radiotap_tree,
					   hf_radiotap_db_antnoise,
					   tvb, offset, 1, db,
					   "SSI Noise: %u dB", db);
	    }
	    offset++;
	    length_remaining--;
	    break;

	case IEEE80211_RADIOTAP_RX_FLAGS:
	{
	    proto_tree *flags_tree;
	    if (radiotap_bit14_fcs) {
	        align_offset = ALIGN_OFFSET(offset, 4);
	        offset += align_offset;
	        length_remaining -= align_offset;
	        if (length_remaining < 4)
	            break;
                if (tree) {
                    sent_fcs = tvb_get_ntohl(tvb, offset);
                    hdr_fcs_ti = proto_tree_add_uint(radiotap_tree, hf_radiotap_fcs,
                                                     tvb, offset, 4, sent_fcs);
                    hdr_fcs_offset = offset;
                }
                offset+=4;
                length_remaining-=4;
	    } else {
	        proto_item *it;

                align_offset = ALIGN_OFFSET(offset, 2);
                offset += align_offset;
                length_remaining -= align_offset;
                if (length_remaining < 2)
                    break;
                if (tree) {
                    flags = tvb_get_letohs(tvb, offset);
                    it = proto_tree_add_uint(radiotap_tree, hf_radiotap_rxflags,
                            tvb, offset, 2, flags);
                    flags_tree = proto_item_add_subtree(it, ett_radiotap_rxflags);
                    proto_tree_add_boolean(flags_tree, hf_radiotap_rxflags_badplcp,
                            tvb, offset, 1, flags);
                }
                offset+=2;
                length_remaining-=2;
            }
	    break;
	}

	case IEEE80211_RADIOTAP_XCHANNEL:
	{
	    proto_item *it;
	    proto_tree *flags_tree;

	    align_offset = ALIGN_OFFSET(offset, 4);
	    offset += align_offset;
	    length_remaining -= align_offset;
	    if (length_remaining < 8)
		break;
	    if (tree) {
	        int channel;
	        guint8 maxpower;

		flags = tvb_get_letohl(tvb, offset);
		freq = tvb_get_letohs(tvb, offset+4);
		channel = tvb_get_guint8(tvb, offset+6);
		maxpower = tvb_get_guint8(tvb, offset+7);
		proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel,
			tvb, offset+6, 1, (guint32) channel);
		proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_frequency,
			tvb, offset+4, 2, freq);
		it = proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_flags,
			tvb, offset+0, 4, flags);
		flags_tree = proto_item_add_subtree(it, ett_radiotap_xchannel_flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_turbo,
			tvb, offset+0, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_cck,
			tvb, offset+0, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ofdm,
			tvb, offset+0, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_2ghz,
			tvb, offset+0, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_5ghz,
			tvb, offset+1, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_passive,
			tvb, offset+1, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_dynamic,
			tvb, offset+1, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gfsk,
			tvb, offset+1, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_gsm,
			tvb, offset+1, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_sturbo,
			tvb, offset+1, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_half,
			tvb, offset+1, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_quarter,
			tvb, offset+1, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht20,
			tvb, offset+2, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40u,
			tvb, offset+2, 1, flags);
		proto_tree_add_boolean(flags_tree, hf_radiotap_xchannel_flags_ht40d,
			tvb, offset+2, 1, flags);
#if 0
		proto_tree_add_uint(radiotap_tree, hf_radiotap_xchannel_maxpower,
			tvb, offset+7, 1, maxpower);
#endif
	    }
	    offset+=8 /* flags + freq + ieee + maxregpower */;
	    length_remaining-=8;
	    break;
	}

	default:
	    /*
	     * This indicates a field whose size we do not
	     * know, so we cannot proceed.
	     */
	    next_present = 0;
	    continue;
	}
    }

    /* This handles the case of an FCS exiting at the end of the frame. */
    if (rflags & IEEE80211_RADIOTAP_F_FCS)
	pinfo->pseudo_header->ieee_802_11.fcs_len = 4;
    else
	pinfo->pseudo_header->ieee_802_11.fcs_len = 0;

    /* Grab the rest of the frame. */
    next_tvb = tvb_new_subset_remaining(tvb, length);

    /* If we had an in-header FCS, check it.
     * This can only happen if the backward-compat configuration option
     * is chosen by the user. */
    if (hdr_fcs_ti) {
        /* It would be very strange for the header to have an FCS for the
         * frame *and* the frame to have the FCS at the end, but it's possible, so
         * take that into account by using the FCS length recorded in pinfo. */

        /* Watch out for [erroneously] short frames */
        if (tvb_length(next_tvb) > (unsigned int) pinfo->pseudo_header->ieee_802_11.fcs_len) {
            calc_fcs = crc32_802_tvb(next_tvb,
                    tvb_length(next_tvb) - pinfo->pseudo_header->ieee_802_11.fcs_len);

            /* By virtue of hdr_fcs_ti being set, we know that 'tree' is set,
             * so there's no need to check it here. */
            if (calc_fcs == sent_fcs) {
                proto_item_append_text(hdr_fcs_ti, " [correct]");
            }
            else {
                proto_item_append_text(hdr_fcs_ti,
                        " [incorrect, should be 0x%08x]", calc_fcs);
                hidden_item = proto_tree_add_boolean(radiotap_tree, hf_radiotap_fcs_bad,
                        tvb, hdr_fcs_offset, 4, TRUE);
                PROTO_ITEM_SET_HIDDEN(hidden_item);
            }
        }
        else {
                proto_item_append_text(hdr_fcs_ti,
                        " [cannot verify - not enough data]");
        }
    }

    /* dissect the 802.11 header next */
    call_dissector((rflags & IEEE80211_RADIOTAP_F_DATAPAD) ?
        ieee80211_datapad_handle : ieee80211_handle,
        next_tvb, pinfo, tree);
    
    tap_queue_packet(radiotap_tap, pinfo, radiotap_info);
}
Exemplo n.º 20
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;

	switch (pinfo->phdr->rec_type) {

	case REC_TYPE_PACKET:
		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;
			}
		}
		break;

	case REC_TYPE_FT_SPECIFIC_EVENT:
		pinfo->current_proto = "Event";
		break;

	case REC_TYPE_FT_SPECIFIC_REPORT:
		pinfo->current_proto = "Report";
		break;

	default:
		g_assert_not_reached();
		break;
	}

	if(pinfo->pkt_comment){
		item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, 0, 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, 0,
							                   pinfo->pkt_comment, "%s",
							                   pinfo->pkt_comment);
		expert_add_info_format(pinfo, comment_item, &ei_comments_text,
					                       "%s",  pinfo->pkt_comment);


	}

	/* if FRAME is not referenced from any filters we don't 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(pinfo, NULL, &ei_arrive_time_out_of_range);
		}
	} 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, tvb_captured_length(tvb),
		    "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->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) {
			proto_item_append_text(ti, " on interface %u",
			    pinfo->phdr->interface_id);
		}
		if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
			if (pinfo->phdr->pack_flags & 0x00000001) {
				proto_item_append_text(ti, " (inbound)");
				pinfo->p2p_dir = P2P_DIR_RECV;
			}
			if (pinfo->phdr->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->phdr->presence_flags & WTAP_HAS_INTERFACE_ID && proto_field_is_referenced(tree, hf_frame_interface_id)) {
			const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->phdr->interface_id);

			if (interface_name)
				proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id, "%u (%s)", pinfo->phdr->interface_id, interface_name);
			else
				proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id);
		}

		if (pinfo->phdr->presence_flags & WTAP_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->phdr->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->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->phdr->pack_flags);
		}

		if (pinfo->phdr->rec_type == REC_TYPE_PACKET)
			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) {
				expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range,
								  "Arrival Time: Fractional second %09ld is invalid,"
								  " the valid range is 0-1000000000",
								  (long) pinfo->fd->abs_ts.nsecs);
			}
			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->epan, pinfo->fd, pinfo->fd->num - 1, &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->epan, pinfo->fd, pinfo->fd->prev_dis_num, &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->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(wmem_packet_scope(), 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);
		}

		/* 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_value(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "%" 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 = (const color_filter_t *)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, 0, "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
			switch (pinfo->phdr->rec_type) {

			case REC_TYPE_PACKET:
				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);
					}
				}
				break;

			case REC_TYPE_FT_SPECIFIC_EVENT:
			case REC_TYPE_FT_SPECIFIC_REPORT:
				if (!dissector_try_uint(wtap_fts_rec_dissector_table, pinfo->file_type_subtype,
							tvb, pinfo, parent_tree)) {

					col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
					col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
						     pinfo->file_type_subtype);
					call_dissector(data_handle,tvb, pinfo, parent_tree);
				}
				break;
			}
#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_BOUNDS_AND_DISSECTOR_ERRORS {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

        if(proto_field_is_referenced(tree, hf_frame_protocols)) {
		wmem_strbuf_t *val = wmem_strbuf_sized_new(wmem_packet_scope(), 128, 0);
		wmem_list_frame_t *frame;
		/* skip the first entry, it's always the "frame" protocol */
		frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
		if (frame) {
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		while (frame) {
			wmem_strbuf_append_c(val, ':');
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		proto_item_append_string(ti, wmem_strbuf_get_str(val));
	}

	/*  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_BOUNDS_AND_DISSECTOR_ERRORS {
			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;
	}
}
Exemplo n.º 21
0
static int
dissect_banana_element(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) {
    proto_item *ti;
    proto_tree *list_tree;
    guint8 byte = 0;
    gint64 val = 0;
    gint val_len = 0;
    int start_offset = offset;
    int old_offset;
    int i;

    /* Accumulate our value/length 'til we hit a valid type */
    while (tvb_length_remaining(tvb, offset) > 0) {
        byte = tvb_get_guint8(tvb, offset);
        offset++;

        if (byte & 0x80) {
            if (is_element(byte)) {
                break;
            } else {
                expert_add_info_format(pinfo, NULL, &ei_banana_unknown_type, "Unknown type %u", byte);
            }
        } else {
            val_len++;
            if (val_len > MAX_ELEMENT_VAL_LEN) {
                expert_add_info(pinfo, NULL, &ei_banana_too_many_value_bytes);
            }
            val += byte + (val << 7);
        }
    }

    /* Type */
    switch (byte) {
        case BE_LIST:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_length_too_long, "List length %" G_GINT64_MODIFIER "d longer than we can handle", val);
            }
            ti = proto_tree_add_uint_format_value(tree, hf_banana_list, tvb, start_offset, offset - start_offset - 1, (guint32) val, "(%d items)", (gint) val);
            list_tree = proto_item_add_subtree(ti, ett_list);
            for (i = 0; i < val; i++) {
                old_offset = offset;
                offset += dissect_banana_element(tvb, pinfo, list_tree, offset);
                if (offset <= old_offset) {
                    return offset - start_offset;
                }
            }
            break;
        case BE_INT:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_value_too_large, "Integer value %" G_GINT64_MODIFIER "d too large", val);
            }
            proto_tree_add_uint(tree, hf_banana_int, tvb, start_offset, offset - start_offset, (guint32) val);
            break;
        case BE_STRING:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_length_too_long, "String length %" G_GINT64_MODIFIER "d longer than we can handle", val);
            }
            proto_tree_add_item(tree, hf_banana_string, tvb, offset, (guint32) val, ENC_ASCII|ENC_NA);
            offset += (gint) val;
            break;
        case BE_NEG_INT:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_value_too_large, "Integer value -%" G_GINT64_MODIFIER "d too large", val);
            }
            proto_tree_add_int(tree, hf_banana_neg_int, tvb, start_offset, offset - start_offset, (gint32) val * -1);
            break;
        case BE_FLOAT:
            proto_tree_add_item(tree, hf_banana_float, tvb, offset, 8, ENC_BIG_ENDIAN);
            offset += 8;
            break;
        case BE_LG_INT:
            proto_tree_add_item(tree, hf_banana_lg_int, tvb, start_offset, offset - start_offset, ENC_NA);
            break;
        case BE_LG_NEG_INT:
            proto_tree_add_item(tree, hf_banana_lg_neg_int, tvb, start_offset, offset - start_offset, ENC_NA);
            break;
        case BE_PB:
            if (val_len > 1) {
                expert_add_info(pinfo, NULL, &ei_banana_pb_error);
            }
            /*
             * The spec says the pb dictionary value comes after the tag.
             * In real-world captures it comes before.
             */
            proto_tree_add_item(tree, hf_banana_pb, tvb, offset - 2, 1, ENC_BIG_ENDIAN);
            break;
        default:
            return 0;
            break;
    }
    return offset - start_offset;
}
Exemplo n.º 22
0
static void
dissect_dsi_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree      *dsi_tree;
    proto_item	*ti;
    guint8		dsi_flags,dsi_command;
    guint16		dsi_requestid;
    gint32		dsi_code;
    guint32		dsi_length;
    guint32		dsi_reserved;
    struct		aspinfo aspinfo;


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

    dsi_flags = tvb_get_guint8(tvb, 0);
    dsi_command = tvb_get_guint8(tvb, 1);
    dsi_requestid = tvb_get_ntohs(tvb, 2);
    dsi_code = tvb_get_ntohl(tvb, 4);
    dsi_length = tvb_get_ntohl(tvb, 8);
    dsi_reserved = tvb_get_ntohl(tvb, 12);

    col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s (%u)",
                 val_to_str(dsi_flags, flag_vals,
                            "Unknown flag (0x%02x)"),
                 val_to_str_ext(dsi_command, &func_vals_ext,
                                "Unknown function (0x%02x)"),
                 dsi_requestid);

    if (tree) {
        ti = proto_tree_add_item(tree, proto_dsi, tvb, 0, -1, ENC_NA);
        dsi_tree = proto_item_add_subtree(ti, ett_dsi);

        proto_tree_add_uint(dsi_tree, hf_dsi_flags, tvb,
                            0, 1, dsi_flags);
        proto_tree_add_uint(dsi_tree, hf_dsi_command, tvb,
                            1, 1, dsi_command);
        proto_tree_add_uint(dsi_tree, hf_dsi_requestid, tvb,
                            2, 2, dsi_requestid);
        switch (dsi_flags) {

        case DSIFL_REQUEST:
            proto_tree_add_int(dsi_tree, hf_dsi_offset, tvb,
                               4, 4, dsi_code);
            break;

        case DSIFL_REPLY:
            proto_tree_add_int(dsi_tree, hf_dsi_error, tvb,
                               4, 4, dsi_code);
            break;
        }
        proto_tree_add_uint_format_value(dsi_tree, hf_dsi_length, tvb,
                                         8, 4, dsi_length,
                                         "%u bytes", dsi_length);
        proto_tree_add_uint(dsi_tree, hf_dsi_reserved, tvb,
                            12, 4, dsi_reserved);
    }
    else
        dsi_tree = tree;
    switch (dsi_command) {
    case DSIFUNC_OPEN:
        if (tree) {
            dissect_dsi_open_session(tvb, dsi_tree, DSI_BLOCKSIZ, dsi_length);
        }
        break;
    case DSIFUNC_ATTN:
        if (tree) {
            dissect_dsi_attention(tvb, dsi_tree, DSI_BLOCKSIZ);
        }
        break;
    case DSIFUNC_STAT:
        if (tree && (dsi_flags == DSIFL_REPLY)) {
            dissect_dsi_reply_get_status(tvb, dsi_tree, DSI_BLOCKSIZ);
        }
        break;
    case DSIFUNC_CMD:
    case DSIFUNC_WRITE:
    {
        tvbuff_t   *new_tvb;
        void* pd_save;
        int len = tvb_reported_length_remaining(tvb,DSI_BLOCKSIZ);

        aspinfo.reply = (dsi_flags == DSIFL_REPLY);
        aspinfo.command = dsi_command;
        aspinfo.seq = dsi_requestid;
        aspinfo.code = dsi_code;
        pd_save = pinfo->private_data;
        pinfo->private_data = &aspinfo;
        proto_item_set_len(dsi_tree, DSI_BLOCKSIZ);

        new_tvb = tvb_new_subset(tvb, DSI_BLOCKSIZ,-1,len);
        call_dissector(afp_handle, new_tvb, pinfo, tree);
        pinfo->private_data = pd_save;
    }
    break;
    default:
        if (tree) {
            call_dissector(data_handle,
                           tvb_new_subset_remaining(tvb, DSI_BLOCKSIZ),
                           pinfo, dsi_tree);
        }
        break;
    }
}
Exemplo n.º 23
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;
	}
}
Exemplo n.º 24
0
/* Code to actually dissect the packets */
static void
dissect_rngrsp (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
  proto_item *it;
  proto_tree *rngrsp_tree;
  guint8 tlvtype, tlvlen;
  int pos;
  gint length;
  guint8 upchid;
  guint16 sid;
  gint8 pwr;
  gint32 tim;

  sid = tvb_get_ntohs (tvb, 0);
  upchid = tvb_get_guint8 (tvb, 2);

  if (upchid > 0)
    col_add_fstr (pinfo->cinfo, COL_INFO,
                  "Ranging Response: SID = %u, Upstream Channel = %u (U%u)",
                  sid, upchid, upchid - 1);
  else
    col_add_fstr (pinfo->cinfo, COL_INFO,
                  "Ranging Response: SID = %u, Telephony Return", sid);


  if (tree)
    {
      it =
        proto_tree_add_protocol_format (tree, proto_docsis_rngrsp, tvb, 0, -1,
                                        "Ranging Response");
      rngrsp_tree = proto_item_add_subtree (it, ett_docsis_rngrsp);
      proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_sid, tvb, 0, 2,
                           ENC_BIG_ENDIAN);
      proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_upstream_chid, tvb,
                           2, 1, ENC_BIG_ENDIAN);

      length = tvb_reported_length_remaining (tvb, 0);
      pos = 3;
      while (pos < length)
        {
          tlvtype = tvb_get_guint8 (tvb, pos++);
          tlvlen = tvb_get_guint8 (tvb, pos++);
          switch (tlvtype)
            {
              case RNGRSP_TIMING:
                if (tlvlen == 4)
                  {
                    tim = tvb_get_ntohl (tvb, pos);
                    proto_tree_add_int (rngrsp_tree,
                                        hf_docsis_rngrsp_timing_adj, tvb, pos,
                                        tlvlen, tim);
                  }
                else
                  {
                    THROW (ReportedBoundsError);
                  }
                break;
              case RNGRSP_PWR_LEVEL_ADJ:
                if (tlvlen == 1)
                  {
                    pwr = tvb_get_guint8 (tvb, pos);
                    proto_tree_add_int (rngrsp_tree, hf_docsis_rngrsp_power_adj,
                                        tvb, pos, tlvlen, pwr);
                  }
                else
                  {
                    THROW (ReportedBoundsError);
                  }
                break;
              case RNGRSP_OFFSET_FREQ_ADJ:
                if (tlvlen == 2)
                  {
                    proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_freq_adj,
                                         tvb, pos, tlvlen, ENC_BIG_ENDIAN);
                  }
                else
                  {
                    THROW (ReportedBoundsError);
                  }
                break;
              case RNGRSP_TRANSMIT_EQ_ADJ:
                proto_tree_add_item (rngrsp_tree, hf_docsis_rngrsp_xmit_eq_adj,
                                     tvb, pos, tlvlen, ENC_NA);
                break;
              case RNGRSP_RANGING_STATUS:
                if (tlvlen == 1)
                  proto_tree_add_item (rngrsp_tree,
                                       hf_docsis_rngrsp_ranging_status, tvb,
                                       pos, tlvlen, ENC_BIG_ENDIAN);
                else
                  {
                    THROW (ReportedBoundsError);
                  }
                break;
              case RNGRSP_DOWN_FREQ_OVER:
                if (tlvlen == 4)
                  proto_tree_add_item (rngrsp_tree,
                                       hf_docsis_rngrsp_down_freq_over, tvb,
                                       pos, tlvlen, ENC_BIG_ENDIAN);
                else
                  {
                    THROW (ReportedBoundsError);
                  }
                break;
              case RNGRSP_UP_CHID_OVER:
                if (tlvlen == 1)
                  proto_tree_add_item (rngrsp_tree,
                                       hf_docsis_rngrsp_upstream_ch_over, tvb,
                                       pos, tlvlen, ENC_BIG_ENDIAN);
                else
                  {
                    THROW (ReportedBoundsError);
                  }
                break;

            }                   /* switch(tlvtype) */
          pos = pos + tlvlen;
        }                       /* while (pos < length) */
    }                           /* if (tree) */
}
Exemplo n.º 25
0
static
void dissect_pw_cesopsn( tvbuff_t * tvb_original
						,packet_info * pinfo
						,proto_tree * tree
						,pwc_demux_type_t demux)
{
	const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/
	gint      packet_size;
	gint      payload_size;
	gint      padding_size;
	int properties;

	packet_size = tvb_reported_length_remaining(tvb_original, 0);

	/*
	 * FIXME
	 * "4" below should be replaced by something like "min_packet_size_this_dissector"
	 * Also call to dissect_try_cw_first_nibble() should be moved before this block
	 */
	if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */
	{
		proto_item  *item;
		item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
		expert_add_info_format(pinfo, item, &ei_packet_size_too_small,
				       "PW packet size (%d) is too small to carry sensible information"
				       ,(int)packet_size);
		col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
		col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small");
		return;
	}

	switch (demux)
	{
	case PWC_DEMUX_MPLS:
		if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree))
		{
			return;
		}
		break;
	case PWC_DEMUX_UDP:
		break;
	default:
		DISSECTOR_ASSERT_NOT_REACHED();
		return;
	}

	/* check how "good" is this packet */
	/* also decide payload length from packet size and CW */
	properties = PWC_PACKET_PROPERTIES_T_INITIALIZER;
	if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/))
	{
		properties |= PWC_CW_BAD_BITS03;
	}
	if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/))
	{
		properties |= PWC_CW_BAD_FRAG;
	}
	{
		/* RFC5086:
		 * [LEN (bits (10 to 15) MAY be used to carry the length of the CESoPSN
		 * packet (defined as the size of the CESoPSN header + the payload size)
		 * if it is less than 64 bytes, and MUST be set to zero otherwise.
		 * Note:  If fixed RTP header is used in the encapsulation, it is
		 * considered part of the CESoPSN header.]
		 *
		 * Note that this differs from RFC4385's definition of length:
		 * [ If the MPLS payload is less than 64 bytes, the length field
		 * MUST be set to the length of the PW payload...]
		 *
		 * We will use RFC5086's definition here.
		 */
		int  cw_len;
		gint payload_size_from_packet;

		cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f;
		payload_size_from_packet = packet_size - encaps_size;
		if (cw_len != 0)
		{
			gint payload_size_from_cw;
			payload_size_from_cw = cw_len - encaps_size;
			/*
			 * Assumptions for error case,
			 * will be overwritten if no errors found:
			 */
			payload_size = payload_size_from_packet;
			padding_size = 0;

			if (payload_size_from_cw < 0)
			{
				properties |= PWC_CW_BAD_PAYLEN_LT_0;
			}
			else if (payload_size_from_cw > payload_size_from_packet)
			{
				properties |= PWC_CW_BAD_PAYLEN_GT_PACKET;
			}
			else if (payload_size_from_packet >= 64)
			{
				properties |= PWC_CW_BAD_LEN_MUST_BE_0;
			}
			else /* ok */
			{
				payload_size = payload_size_from_cw;
				padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */
			}
		}
		else
		{
			payload_size = payload_size_from_packet;
			padding_size = 0;
		}
	}

	{
		guint8 cw_lm;
		cw_lm = tvb_get_guint8(tvb_original, 0) & 0x0b /*l+mod*/;
		if (NULL == try_val_to_str(cw_lm, vals_cw_lm))
		{
			properties |= PWC_CW_SUSPECT_LM;
		}

		{
			guint8 l_bit, m_bits;
			l_bit  = (cw_lm & 0x08) >> 3;
			m_bits = (cw_lm & 0x03) >> 0;
			if ((l_bit == 0 && m_bits == 0x0) /*CESoPSN data packet - normal situation*/
			    ||(l_bit == 0 && m_bits == 0x2) /*CESoPSN data packet - RDI on the AC*/ )
			{
				if ((payload_size == 0) || ((payload_size % 8) != 0))
				{
					properties |= PWC_PAY_SIZE_BAD;
				}
			}
			else if (l_bit == 1 && m_bits == 0x0) /*TDM data is invalid; payload MAY be omitted*/
			{
				/*allow any size of payload*/
			}
			else /*reserved combinations*/
			{
				/*allow any size of payload*/
			}
		}
	}

	/* fill up columns*/
	col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
	col_clear(pinfo->cinfo, COL_INFO);
	if (properties & PWC_ANYOF_CW_BAD)
	{
		col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, ");
	}
	else if (properties & PWC_ANYOF_CW_SUSPECT)
	{
		col_append_str(pinfo->cinfo, COL_INFO, "CW:Suspect, ");
	}

	if (properties & PWC_PAY_SIZE_BAD)
	{
		col_append_str(pinfo->cinfo, COL_INFO, "Payload size:Bad, ");
	}

	col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size);

	if (padding_size != 0)
	{
		col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size);
	}

	{
		proto_item* item;
		item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
		pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE);
		pwc_item_append_text_n_items(item,(int)payload_size,"octet");
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				proto_item* item2;
				tvb = tvb_new_subset(tvb_original, 0, PWC_SIZEOF_CW, PWC_SIZEOF_CW);
				item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA);
				pwc_item_append_cw(item2,tvb_get_ntohl(tvb, 0),FALSE);
				{
					proto_tree* tree3;
					tree3 = proto_item_add_subtree(item, ett);
					{
						proto_item* item3;
						if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/
						{
							item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN);
							expert_add_info(pinfo, item3, &ei_cw_bits03);
						}

						item3 = proto_tree_add_item(tree3, hf_cw_lm,  tvb, 0, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_SUSPECT_LM)
						{
							expert_add_info(pinfo, item3, &ei_cw_lm);
						}

						proto_tree_add_item(tree3, hf_cw_r, tvb, 0, 1, ENC_BIG_ENDIAN);

						item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_FRAG)
						{
							expert_add_info(pinfo, item3, &ei_cw_frg);
						}

						item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN);
						if (properties & PWC_CW_BAD_PAYLEN_LT_0)
						{
							expert_add_info_format(pinfo, item3, &ei_pref_cw_len,
								"Bad Length: too small, must be > %d",
								(int)encaps_size);
						}
						if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET)
						{
							expert_add_info_format(pinfo, item3, &ei_pref_cw_len,
								"Bad Length: must be <= than PSN packet size (%d)",
								(int)packet_size);
						}
						if (properties & PWC_CW_BAD_LEN_MUST_BE_0)
						{
							expert_add_info_format(pinfo, item3, &ei_pref_cw_len,
								"Bad Length: must be 0 if CESoPSN packet size (%d) is > 64",
								(int)packet_size);
						}

						proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN);

					}
				}
			}
		}

		/* payload */
		if (payload_size == 0)
		{
			if (properties & PWC_PAY_SIZE_BAD)
			{
				expert_add_info_format(pinfo, item, &ei_payload_size_invalid_error,
					"CESoPSN payload: none found. Size of payload must be <> 0");
			}
			else
			{
				expert_add_info_format(pinfo, item, &ei_payload_size_invalid_undecoded,
					"CESoPSN payload: omitted to conserve bandwidth");
			}
		}
		else
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				proto_item* item2;
				tvbuff_t* tvb;
				tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW, payload_size, payload_size);
				item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA);
				pwc_item_append_text_n_items(item2,(int)payload_size,"octet");
				if (properties & PWC_PAY_SIZE_BAD)
				{
					expert_add_info_format(pinfo, item2, &ei_payload_size_invalid_error,
						"CESoPSN packet payload size must be multiple of 8");
				}
				tree2 = proto_item_add_subtree(item2, ett);
				call_dissector(data_handle, tvb, pinfo, tree2);
				item2 = proto_tree_add_int(tree2, hf_payload_l, tvb, 0, 0
					,(int)payload_size); /* allow filtering */
				PROTO_ITEM_SET_HIDDEN(item2);
			}
		}

		/* padding */
		if (padding_size > 0)
		{
			proto_tree* tree2;
			tree2 = proto_item_add_subtree(item, ett);
			{
				tvbuff_t* tvb;
				tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1);
				call_dissector(pw_padding_handle, tvb, pinfo, tree2);
			}
		}
	}
	return;
}
Exemplo n.º 26
0
/* Code to actually dissect the packets */
static void
dissect_lsc_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_item *ti;
  proto_tree *lsc_tree;
  guint8 op_code;
  guint32 stream;
  guint expected_len;

  /* Protocol is LSC, packet summary is not yet known */
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "LSC");
  col_clear(pinfo->cinfo, COL_INFO);

  /* Too little data? */
  if (tvb->length < LSC_MIN_LEN)
  {
    col_set_str(pinfo->cinfo, COL_INFO, "[Too short]");
    return;
  }

  /* Get the op code */
  op_code = tvb_get_guint8(tvb, 2);
  /* And the stream handle */
  stream = tvb_get_ntohl(tvb, 4);

  /* Check the data length against what we actually received */
  switch (op_code)
    {
      case LSC_PAUSE:
        expected_len = LSC_PAUSE_LEN;
        break;
      case LSC_RESUME:
        expected_len = LSC_RESUME_LEN;
        break;
      case LSC_STATUS:
        expected_len = LSC_STATUS_LEN;
        break;
      case LSC_RESET:
        expected_len = LSC_RESET_LEN;
        break;
      case LSC_JUMP:
        expected_len = LSC_JUMP_LEN;
        break;
      case LSC_PLAY:
        expected_len = LSC_PLAY_LEN;
        break;
      case LSC_DONE:
      case LSC_PAUSE_REPLY:
      case LSC_RESUME_REPLY:
      case LSC_STATUS_REPLY:
      case LSC_RESET_REPLY:
      case LSC_JUMP_REPLY:
      case LSC_PLAY_REPLY:
        expected_len = LSC_REPLY_LEN;
        break;
      default:
        /* Unrecognized op code */
        expected_len = LSC_MIN_LEN;
        break;
    }

  /* Display the op code in the summary */
  if (check_col(pinfo->cinfo, COL_INFO)) {
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s, session %.8u",
                 val_to_str(op_code, op_code_vals, "Unknown op code (0x%x)"),
                 stream);

    if (tvb->length < expected_len)
      col_append_str(pinfo->cinfo, COL_INFO, " [Too short]");
    else if (tvb->length > expected_len)
      col_append_str(pinfo->cinfo, COL_INFO, " [Too long]");
  }

  if (tree) {
    /* Create display subtree for the protocol */
    ti = proto_tree_add_item(tree, proto_lsc, tvb, 0, -1, FALSE);
    lsc_tree = proto_item_add_subtree(ti, ett_lsc);

    /* Add already fetched items to the tree */
    proto_tree_add_uint(lsc_tree, hf_lsc_op_code, tvb, 2, 1, op_code);
    proto_tree_add_uint_format_value(lsc_tree, hf_lsc_stream_handle, tvb, 4, 4,
                                     stream, "%.8u", stream);

    /* Add rest of LSC header */
    proto_tree_add_uint(lsc_tree, hf_lsc_version, tvb, 0, 1,
                        tvb_get_guint8(tvb, 0));
    proto_tree_add_uint(lsc_tree, hf_lsc_trans_id, tvb, 1, 1,
                        tvb_get_guint8(tvb, 1));

    /* Only replies contain a status code */
    if (isReply(op_code))
      proto_tree_add_uint(lsc_tree, hf_lsc_status_code, tvb, 3, 1,
                          tvb_get_guint8(tvb, 3));

    /* Add op code specific parts */
    switch (op_code)
      {
        case LSC_PAUSE:
          proto_tree_add_int(lsc_tree, hf_lsc_stop_npt, tvb, 8, 4,
                             tvb_get_ntohl(tvb, 8));
          break;
        case LSC_RESUME:
          proto_tree_add_int(lsc_tree, hf_lsc_start_npt, tvb, 8, 4,
                             tvb_get_ntohl(tvb, 8));
          proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 12, 2,
                             tvb_get_ntohs(tvb, 12));
          proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 14, 2,
                              tvb_get_ntohs(tvb, 14));
          break;
        case LSC_JUMP:
        case LSC_PLAY:
          proto_tree_add_int(lsc_tree, hf_lsc_start_npt, tvb, 8, 4,
                             tvb_get_ntohl(tvb, 8));
          proto_tree_add_int(lsc_tree, hf_lsc_stop_npt, tvb, 12, 4,
                             tvb_get_ntohl(tvb, 12));
          proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 16, 2,
                             tvb_get_ntohs(tvb, 16));
          proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 18, 2,
                              tvb_get_ntohs(tvb, 18));
          break;
        case LSC_DONE:
        case LSC_PAUSE_REPLY:
        case LSC_RESUME_REPLY:
        case LSC_STATUS_REPLY:
        case LSC_RESET_REPLY:
        case LSC_JUMP_REPLY:
        case LSC_PLAY_REPLY:
          proto_tree_add_int(lsc_tree, hf_lsc_current_npt, tvb, 8, 4,
                             tvb_get_ntohl(tvb, 8));
          proto_tree_add_int(lsc_tree, hf_lsc_scale_num, tvb, 12, 2,
                             tvb_get_ntohs(tvb, 12));
          proto_tree_add_uint(lsc_tree, hf_lsc_scale_denom, tvb, 14, 2,
                              tvb_get_ntohs(tvb, 14));
          proto_tree_add_uint(lsc_tree, hf_lsc_mode, tvb, 16, 1,
                              tvb_get_guint8(tvb, 16));
          break;
        default:
          break;
      }
  }
}
Exemplo n.º 27
0
/* XXX - "packet comment" is passed into dissector as data, but currently doesn't have a use */
static int
dissect_file_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
{
	proto_item  *volatile ti = NULL;
	guint	     cap_len = 0, frame_len = 0;
	proto_tree  *volatile fh_tree = NULL;
	proto_tree  *volatile tree;
	proto_item  *item;
	const gchar *cap_plurality, *frame_plurality;
	const color_filter_t *color_filter;
	file_data_t *file_data = (file_data_t*)data;

	tree=parent_tree;

	pinfo->current_proto = "File";

	/* if FILE is not referenced from any filters we don't need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_file)) {
		tree=NULL;
	} else {
		/* Put in frame header information. */
		cap_len = tvb_captured_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_file, tvb, 0, -1,
		    "File record %u: %u byte%s",
		    pinfo->num, frame_len, frame_plurality);
		proto_item_append_text(ti, ", %u byte%s",
		    cap_len, cap_plurality);

		fh_tree = proto_item_add_subtree(ti, ett_file);

		proto_tree_add_int(fh_tree, hf_file_ftap_encap, tvb, 0, 0, pinfo->pkt_encap);

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

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

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

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

		if(pinfo->fd->pfd != 0){
			proto_item *ppd_item;
			guint num_entries = g_slist_length(pinfo->fd->pfd);
			guint i;
			ppd_item = proto_tree_add_uint(fh_tree, hf_file_num_p_prot_data, tvb, 0, 0, num_entries);
			PROTO_ITEM_SET_GENERATED(ppd_item);
			for(i=0; i<num_entries; i++){
				gchar* str = p_get_proto_name_and_key(wmem_file_scope(), pinfo, i);
				proto_tree_add_string_format(fh_tree, hf_file_proto_name_and_key, tvb, 0, 0, str, "%s", str);
			}
		}

#if 0
		if (show_file_off) {
			proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
						    pinfo->fd->file_off, pinfo->fd->file_off);
		}
#endif
	}

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

	/* 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 (!dissector_try_uint(file_encap_dissector_table, pinfo->pkt_encap,
						tvb, pinfo, parent_tree)) {

				col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
				col_add_fstr(pinfo->cinfo, COL_INFO, "FTAP_ENCAP = %d",
					     pinfo->pkt_encap);
				call_data_dissector(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_BOUNDS_AND_DISSECTOR_ERRORS {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

	if(proto_field_is_referenced(tree, hf_file_protocols)) {
		wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), "");
		wmem_list_frame_t *frame;
		/* skip the first entry, it's always the "frame" protocol */
		frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
		if (frame) {
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		while (frame) {
			wmem_strbuf_append_c(val, ':');
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		ti = proto_tree_add_string(fh_tree, hf_file_protocols, tvb, 0, 0, wmem_strbuf_get_str(val));
		PROTO_ITEM_SET_GENERATED(ti);
	}

	/*  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_BOUNDS_AND_DISSECTOR_ERRORS {
			show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
		}
		ENDTRY;
	}

	/* Attempt to (re-)calculate color filters (if any). */
	if (pinfo->fd->flags.need_colorize) {
		color_filter = color_filters_colorize_packet(file_data->color_edt);
		pinfo->fd->color_filter = color_filter;
		pinfo->fd->flags.need_colorize = 0;
	} else {
		color_filter = pinfo->fd->color_filter;
	}
	if (color_filter) {
		pinfo->fd->color_filter = color_filter;
		item = proto_tree_add_string(fh_tree, hf_file_color_filter_name, tvb,
					     0, 0, color_filter->filter_name);
		PROTO_ITEM_SET_GENERATED(item);
		item = proto_tree_add_string(fh_tree, hf_file_color_filter_text, tvb,
					     0, 0, color_filter->filter_text);
		PROTO_ITEM_SET_GENERATED(item);
	}

	tap_queue_packet(file_tap, pinfo, NULL);


	if (pinfo->frame_end_routines) {
		g_slist_foreach(pinfo->frame_end_routines, &call_file_record_end_routine, NULL);
		g_slist_free(pinfo->frame_end_routines);
		pinfo->frame_end_routines = NULL;
	}

	return tvb_captured_length(tvb);
}
Exemplo n.º 28
0
static gint ett = -1;
static int hf_padding_len = -1;

static
int dissect_pw_padding(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree, void* data _U_)
{
	gint size;
	proto_item* item;
	proto_tree* tree_p;
	size = tvb_reported_length_remaining(tvb, 0);
	item = proto_tree_add_item(tree, proto_pw_padding, tvb, 0, -1, ENC_NA);
	pwc_item_append_text_n_items(item,size,"byte");
	tree_p = proto_item_add_subtree(item, ett);

	call_data_dissector(tvb, pinfo, tree_p);
	item = proto_tree_add_int(tree_p, hf_padding_len, tvb, 0, 0, size);
	PROTO_ITEM_SET_HIDDEN(item); /*allow filtering*/

	return tvb_captured_length(tvb);
}

void proto_register_pw_padding(void)
{
	static hf_register_info hfpadding[] = {
		{&hf_padding_len	,{"Length"			,"pw.padding.len"
					,FT_INT32	,BASE_DEC	,NULL		,0
					,NULL						,HFILL }}
	};
	static gint *ett_array[] = {
		&ett
	};
Exemplo n.º 29
0
static gboolean dissect_h1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  tvbuff_t *next_tvb;

  proto_tree *h1_tree = NULL;

  proto_item *ti;
  proto_tree *opcode_tree = NULL;
  proto_tree *org_tree = NULL;
  proto_tree *response_tree = NULL;
  proto_tree *empty_tree = NULL;

  unsigned int position = 3;
  unsigned int offset=0;

  if (tvb_length(tvb) < 2)
    {
      /* Not enough data captured to hold the "S5" header; don't try
         to interpret it as H1. */
      return FALSE;
    }

  if (!(tvb_get_guint8(tvb,offset) == 'S' && tvb_get_guint8(tvb,offset+1) == '5'))
    {
      return FALSE;
    }

  col_set_str (pinfo->cinfo, COL_PROTOCOL, "H1");
  col_set_str(pinfo->cinfo, COL_INFO, "S5: ");
  if (tree)
    {
      ti = proto_tree_add_item (tree, proto_h1, tvb, offset, 16, ENC_NA);
      h1_tree = proto_item_add_subtree (ti, ett_h1);
      proto_tree_add_uint (h1_tree, hf_h1_header, tvb, offset, 2,
			   tvb_get_ntohs(tvb,offset));
      proto_tree_add_uint (h1_tree, hf_h1_len, tvb, offset + 2, 1,
			   tvb_get_guint8(tvb,offset+2));
    }

  while (position < tvb_get_guint8(tvb,offset+2))
    {
      switch (tvb_get_guint8(tvb,offset + position))
	{
	  case OPCODE_BLOCK:
	    if (h1_tree)
	      {
		ti = proto_tree_add_uint (h1_tree, hf_h1_opfield, tvb,
					  offset + position,
					  tvb_get_guint8(tvb,offset+position+1),
					  tvb_get_guint8(tvb,offset+position));
		opcode_tree = proto_item_add_subtree (ti, ett_opcode);
		proto_tree_add_uint (opcode_tree, hf_h1_oplen, tvb,
				     offset + position + 1, 1,
				     tvb_get_guint8(tvb,offset + position + 1));
		proto_tree_add_uint (opcode_tree, hf_h1_opcode, tvb,
				     offset + position + 2, 1,
				     tvb_get_guint8(tvb,offset + position + 2));
	      }
	    if (check_col (pinfo->cinfo, COL_INFO))
	      {
		col_append_str (pinfo->cinfo, COL_INFO,
				val_to_str (tvb_get_guint8(tvb,offset + position + 2),
					    opcode_vals,"Unknown Opcode (0x%2.2x)"));
	      }
	    break;
	  case REQUEST_BLOCK:
	    if (h1_tree)
	      {
		ti = proto_tree_add_uint (h1_tree, hf_h1_requestblock, tvb,
					  offset + position,
					  tvb_get_guint8(tvb,offset + position + 1),
					  tvb_get_guint8(tvb,offset + position));
		org_tree = proto_item_add_subtree (ti, ett_org);
		proto_tree_add_uint (org_tree, hf_h1_requestlen, tvb,
				     offset + position + 1, 1,
				     tvb_get_guint8(tvb,offset + position+1));
		proto_tree_add_uint (org_tree, hf_h1_org, tvb,
				     offset + position + 2, 1,
				     tvb_get_guint8(tvb,offset + position+2));
		proto_tree_add_uint (org_tree, hf_h1_dbnr, tvb,
				     offset + position + 3, 1,
				     tvb_get_guint8(tvb,offset + position+3));
		proto_tree_add_uint (org_tree, hf_h1_dwnr, tvb,
				     offset + position + 4, 2,
				     tvb_get_ntohs(tvb,offset+position+4));
		proto_tree_add_int (org_tree, hf_h1_dlen, tvb,
				    offset + position + 6, 2,
				    tvb_get_ntohs(tvb,offset+position+6));
	      }
	    if (check_col (pinfo->cinfo, COL_INFO))
	      {
		col_append_fstr (pinfo->cinfo, COL_INFO, " %s %d",
				 val_to_str (tvb_get_guint8(tvb,offset + position + 2),
					     org_vals,"Unknown Type (0x%2.2x)"),
				 tvb_get_guint8(tvb,offset + position + 3));
		col_append_fstr (pinfo->cinfo, COL_INFO, " DW %d",
				 tvb_get_ntohs(tvb,offset+position+4));
		col_append_fstr (pinfo->cinfo, COL_INFO, " Count %d",
				 tvb_get_ntohs(tvb,offset+position+6));
	      }
	    break;
	  case RESPONSE_BLOCK:
	    if (h1_tree)
	      {
		ti = proto_tree_add_uint (h1_tree, hf_h1_response, tvb,
					  offset + position,
					  tvb_get_guint8(tvb,offset + position + 1),
					  tvb_get_guint8(tvb,offset + position));
		response_tree = proto_item_add_subtree (ti, ett_response);
		proto_tree_add_uint (response_tree, hf_h1_response_len, tvb,
				     offset + position + 1, 1,
				     tvb_get_guint8(tvb,offset + position+1));
		proto_tree_add_uint (response_tree, hf_h1_response_value, tvb,
				     offset + position + 2, 1,
				     tvb_get_guint8(tvb,offset + position+2));
	      }
	    if (check_col (pinfo->cinfo, COL_INFO))
	      {
		col_append_fstr (pinfo->cinfo, COL_INFO, " %s",
				 val_to_str (tvb_get_guint8(tvb,offset + position + 2),
					     returncode_vals,"Unknown Returncode (0x%2.2x"));
	      }
	    break;
	  case EMPTY_BLOCK:
	    if (h1_tree)
	      {
		ti = proto_tree_add_uint (h1_tree, hf_h1_empty, tvb,
					  offset + position,
					  tvb_get_guint8(tvb,offset + position + 1),
					  tvb_get_guint8(tvb,offset + position));
		empty_tree = proto_item_add_subtree (ti, ett_empty);

		proto_tree_add_uint (empty_tree, hf_h1_empty_len, tvb,
				     offset + position + 1, 1,
				     tvb_get_guint8(tvb,offset + position+1));
	      }
	    break;
	  default:
	    /* This is not a valid telegram. So cancel dissection
               and try the next dissector */
            return FALSE;
	}
	if (tvb_get_guint8(tvb,offset + position + 1) < 1)
	    THROW(ReportedBoundsError);
	position += tvb_get_guint8(tvb,offset + position + 1);	/* Goto next section */
    }			/* ..while */
  next_tvb = tvb_new_subset(tvb, offset+tvb_get_guint8(tvb,offset+2), -1, -1);
  call_dissector(data_handle,next_tvb, pinfo, tree);

  return TRUE;
}
Exemplo n.º 30
0
static void dissect_asterix_pdu(tvbuff_t *tvb, packet_info *pinfo,
    proto_tree *tree)
{
  proto_tree* asterix_tree[5];
  int tree_depth = 0;
  proto_item* t_head_item;
  proto_item* t_item = NULL;
  static fulliautomatix_data* pDataList = NULL;
  fulliautomatix_data* pData = NULL;
  guint32 offset = 0;
  guint8 category;
  guint32 payload_len;
  char tmpstr[256];
  char tmp2[64];
  int error=0;

  tmpstr[0] = 0;
  while(offset < tvb_length(tvb) && strlen(tmpstr)<200)
  {
    category = tvb_get_guint8(tvb,offset); offset+=1;
    payload_len = tvb_get_ntohs(tvb,offset); offset+=2;
    offset += payload_len-3;
    sprintf(tmp2,"CAT%03d (%-3d bytes),", category, payload_len);
    strcat(tmpstr, tmp2);
  }

  if (offset != tvb_length(tvb))
  {
    sprintf(tmp2, "Total= %d bytes - Wrong length !!!! ", offset);
  }
  else
  {
    sprintf(tmp2, "Total = %d bytes", offset);
  }
  strcat(tmpstr, tmp2);

  if (check_col(pinfo->cinfo, COL_PROTOCOL))
          col_set_str(pinfo->cinfo, COL_PROTOCOL, "Asterix");

  if (check_col(pinfo->cinfo, COL_INFO))
          col_add_fstr(pinfo->cinfo, COL_INFO, tmpstr);
  if(!tree)
          return;

   t_head_item = proto_tree_add_protocol_format(tree, proto_asterix, tvb, 0, -1,
          "All Purpose Structured Eurocontrol Surveillance Information Exhange (Asterix) Protocol");

  asterix_tree[tree_depth] = proto_item_add_subtree(t_head_item, ett_asterix[tree_depth]);

  pDataList = fulliautomatix_parse(tvb_get_ptr(tvb,0,tvb_length(tvb)), tvb_length(tvb));

  pData = pDataList;
  while(pData)
  {
    if (pData->tree == 1)
    {
      t_item = proto_tree_add_text(asterix_tree[tree_depth], tvb, pData->bytenr, pData->length, pData->description);
      if (tree_depth < MAX_TREE_DEPTH-1)
      {
        tree_depth++;
      }
      asterix_tree[tree_depth] = proto_item_add_subtree(t_item, ett_asterix[tree_depth]);
    }
    else if (pData->tree == -1)
    {
      if (tree_depth > 0)
      {
        tree_depth--;
      }
    }
    else
    {
      if (pData->pid < 0 || pData->pid > maxpid)
      {
        logTraceFunc("Wrong PID.\n");
      }
      else if (pData->type == FT_STRINGZ)
      {
        t_item = proto_tree_add_string(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.str);
      }
      else if (pData->type == FT_UINT32)
      {
        t_item = proto_tree_add_uint(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.ul);
      }
      else if (pData->type == FT_INT32)
      {
        t_item = proto_tree_add_int(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.sl);
      }
      else if (pData->type == FT_BYTES)
      {
        t_item = proto_tree_add_bytes(asterix_tree[tree_depth], def_pid[pData->pid], tvb, pData->bytenr, pData->length, pData->val.str);
      }
      else if (pData->type == FT_NONE)
      {
        t_item = proto_tree_add_text(asterix_tree[tree_depth], tvb, pData->bytenr, pData->length, pData->val.str);
      }
      //TODO add other types
    }
    if (pData->value_description)
    {
      proto_item_append_text(t_item, pData->value_description);
    }
    if (pData->err == 1)
    {
      proto_item_set_expert_flags(t_item, PI_GROUP_MASK, PI_WARN);
      expert_add_info_format(pinfo, t_item, PI_UNDECODED, PI_WARN, "Warning in Asterix message");
      if (error==0)
        error=1;
    }
    else if (pData->err == 2)
    {
      proto_item_set_expert_flags(t_item, PI_REASSEMBLE, PI_ERROR);
      expert_add_info_format(pinfo, t_item, PI_MALFORMED, PI_ERROR, "Error in Asterix message");
      if (error<2)
        error=2;
    }
    pData = pData->next;
  }

  if (error == 1)
  {
    proto_item_set_expert_flags(t_head_item, PI_GROUP_MASK, PI_WARN);
  }
  else if (error == 2)
  {
    proto_item_set_expert_flags(t_head_item, PI_REASSEMBLE, PI_ERROR);
  }

  fulliautomatix_data_destroy(pDataList);
}