Esempio n. 1
0
static void dissect_ss_info_ie(tvbuff_t *tvb, packet_info *pinfo, guint offset, guint len, proto_tree *tree)
{
	guint saved_offset;
	gint8 appclass;
	gboolean pc;
	gboolean ind = FALSE;
	guint32 component_len = 0;
	guint32 header_end_offset;
	guint32 header_len;
	asn1_ctx_t asn1_ctx;
	tvbuff_t *ss_tvb = NULL;
	static gint comp_type_tag;

	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
	saved_offset = offset;
	col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
	col_set_fence(pinfo->cinfo, COL_PROTOCOL);
	while (len > (offset - saved_offset)) {
		/* get the length of the component. there can be multiple components in one message */
		header_end_offset = get_ber_identifier(tvb, offset, &appclass, &pc, &comp_type_tag);
		header_end_offset = get_ber_length(tvb, header_end_offset, &component_len, &ind);
		header_len = header_end_offset -offset;
		component_len += header_len;

		ss_tvb = tvb_new_subset_length(tvb, offset, component_len);
		col_append_str(pinfo->cinfo, COL_INFO, "(GSM MAP) ");
		col_set_fence(pinfo->cinfo, COL_INFO);
		call_dissector(gsm_map_handle, ss_tvb, pinfo, tree);
		offset += component_len;
	}
}
Esempio n. 2
0
WSLUA_METHOD Column_fence(lua_State *L) {
        /* Sets Column text fence, to prevent overwriting */
    Column c = checkColumn(L,1);

    if (c && c->cinfo)
        col_set_fence(c->cinfo, c->col);

    return 0;
}  
/* ---------------------------- */
static void
dissect_nasdaq_soup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti;
    proto_tree *nasdaq_soup_tree = NULL;
    guint8 nasdaq_soup_type;
    int  linelen;
    gint next_offset;
    int  offset = 0;
    gint col_info;
    gint counter = 0;

    col_info = check_col(pinfo->cinfo, COL_INFO);
    while (tvb_offset_exists(tvb, offset)) {
        /* there's only a \n no \r */
        linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, nasdaq_soup_desegment && pinfo->can_desegment);
        if (linelen == -1) {
            /*
             * We didn't find a line ending, and we're doing desegmentation;
             * tell the TCP dissector where the data for this message starts
             * in the data it handed us, and tell it we need one more byte
             * (we may need more, but we'll try again if what we get next
             * isn't enough), and return.
             */
            pinfo->desegment_offset = offset;
            pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
            return;
        }

        nasdaq_soup_type = tvb_get_guint8(tvb, offset);
        if (counter == 0) {
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "Nasdaq-SOUP");
            if (col_info)
                col_clear(pinfo->cinfo, COL_INFO);
        }
        if (col_info ) {
            if (counter) {
                col_append_str(pinfo->cinfo, COL_INFO, "; ");
                col_set_fence(pinfo->cinfo, COL_INFO);
            }
            col_append_str(pinfo->cinfo, COL_INFO, val_to_str(nasdaq_soup_type, message_types_val, "Unknown packet type (0x%02x)"));
        }
        counter++;
        if (tree) {
            ti = proto_tree_add_item(tree, proto_nasdaq_soup, tvb, offset, linelen +1, ENC_NA);
            nasdaq_soup_tree = proto_item_add_subtree(ti, ett_nasdaq_soup);
        }
        dissect_nasdaq_soup_packet(tvb, pinfo, tree, nasdaq_soup_tree, offset, linelen);
        offset = next_offset;
    }
}
static int
dissect_h225_H323UserInformation(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item *it;
	proto_tree *tr;
	int offset = 0;

	pi_current++;
	if(pi_current==5){
		pi_current=0;
	}
	h225_pi=&pi_arr[pi_current];

	/* Init struct for collecting h225_packet_info */
	reset_h225_packet_info(h225_pi);
	h225_pi->msg_type = H225_CS;

	next_tvb_init(&h245_list);
	next_tvb_init(&tp_list);

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

	it=proto_tree_add_protocol_format(tree, proto_h225, tvb, 0, tvb_length(tvb), PSNAME" CS");
	tr=proto_item_add_subtree(it, ett_h225);

	offset = dissect_H323_UserInformation_PDU(tvb, pinfo, tr);

	if (h245_list.count){
		col_append_str(pinfo->cinfo, COL_PROTOCOL, "/");
		col_set_fence(pinfo->cinfo, COL_PROTOCOL);
	}

	next_tvb_call(&h245_list, pinfo, tree, h245dg_handle, data_handle);
	next_tvb_call(&tp_list, pinfo, tree, NULL, data_handle);

	tap_queue_packet(h225_tap, pinfo, h225_pi);

	return offset;
}
Esempio n. 5
0
/* Code to actually dissect the packets */
static int
dissect_tte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    tvbuff_t* tvb_next;
    int is_frame_pcf;

    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item *tte_root_item, *tte_macdest_item, *tte_macsrc_item;
    proto_tree *tte_tree, *tte_macdest_tree/*, *tte_macsrc_tree*/;

    /* Check that there's enough data */
    if (tvb_length(tvb) < TTE_HEADER_LENGTH)
        return 0;

    /* check if data of pcf frame */
    is_frame_pcf = 
       (tvb_get_ntohs(tvb, TTE_MAC_LENGTH * 2) == ETHERTYPE_TTE_PCF);

    /* return if no valid cosntant field is found */
    if (!is_frame_pcf)
    {
        if ( (tvb_get_ntohl(tvb, 0) & tte_pref_ct_mask) != tte_pref_ct_marker)
            return 0;
    }

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

    col_set_str(pinfo->cinfo, COL_INFO, "Bogus TTEthernet Frame");

    if (tree) {

        /* create display subtree for the protocol */
        tte_root_item = proto_tree_add_item(tree, proto_tte, tvb, 0,
            TTE_HEADER_LENGTH, FALSE);

        tte_tree = proto_item_add_subtree(tte_root_item, ett_tte);

        tte_macdest_item = proto_tree_add_item(tte_tree,
            hf_eth_dst, tvb, 0, TTE_MAC_LENGTH, FALSE);

        tte_macsrc_item = proto_tree_add_item(tte_tree,
            hf_eth_src, tvb, TTE_MAC_LENGTH, TTE_MAC_LENGTH, FALSE);

        proto_tree_add_item(tte_tree,
            hf_eth_type, tvb, TTE_MAC_LENGTH*2, TTE_ETHERTYPE_LENGTH,
            FALSE);

        tte_macdest_tree = proto_item_add_subtree(tte_macdest_item,
            ett_tte_macdest);

        proto_tree_add_item(tte_macdest_tree,
            hf_tte_dst_cf, tvb, 0, TTE_MACDEST_CF_LENGTH, FALSE);

        proto_tree_add_item(tte_macdest_tree,
            hf_tte_ctid, tvb, TTE_MACDEST_CF_LENGTH,
            TTE_MACDEST_CTID_LENGTH, FALSE);
    }

    tvb_next = tvb_new_subset_remaining(tvb, TTE_HEADER_LENGTH);

    /* prevent the Columns to be cleared...appending cannot be prevented */
    col_set_fence(pinfo->cinfo, COL_PROTOCOL);

    /* call std Ethernet dissector */
    ethertype (tvb_get_ntohs(tvb, TTE_MAC_LENGTH * 2), tvb
        , 14, pinfo, tree, NULL, hf_eth_type, 0, 0 );

    return tvb_length(tvb);
}
Esempio n. 6
0
static void
dissect_fcgi_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
   gint offset = 0;
   guint8 type;

   type = tvb_get_guint8(tvb, 1);

   /* When there are multiple FCGI records in a TCP frame the following code */
   /* will append the type for each record to COL_INFO.                      */
   /* XXX: Unfortunately, something in the tcp_dissect_pdus() code is broken */
   /*      such that only the type for the first FCGI record appears in the  */
   /*      INFO column. (All write attempts to COL_INFO after the first fail */
   /*      because pinfo->cinfo->writable is FALSE).                         */
   col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCGI");
   col_clear(pinfo->cinfo, COL_INFO);
   col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
                      val_to_str(type, record_types, "Unknown (%u)"));
   col_set_fence(pinfo->cinfo, COL_INFO);

   if (tree) { /* we are being asked for details */
      proto_item *ti;
      proto_tree *fcgi_tree;
      guint16 clen;
      guint8 plen;

      ti = proto_tree_add_item(tree, proto_fcgi, tvb, 0, -1, ENC_NA);
      proto_item_append_text(ti, " (%s)",
                             val_to_str(type, record_types, "Unknown (%u)"));
      fcgi_tree = proto_item_add_subtree(ti, ett_fcgi);

      proto_tree_add_item(fcgi_tree, hf_fcgi_version, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;

      proto_tree_add_item(fcgi_tree, hf_fcgi_type, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;

      proto_tree_add_item(fcgi_tree, hf_fcgi_id, tvb, offset, 2, ENC_BIG_ENDIAN);
      offset += 2;

      clen = tvb_get_ntohs(tvb, offset);
      proto_tree_add_item(fcgi_tree, hf_fcgi_content_length, tvb, offset, 2, ENC_BIG_ENDIAN);
      offset += 2;

      plen = tvb_get_guint8(tvb, offset);
      proto_tree_add_item(fcgi_tree, hf_fcgi_padding_length, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset += 1;

      offset += 1;

      switch (type)
      {
      case FCGI_BEGIN_REQUEST:
         dissect_begin_request(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_ABORT_REQUEST:
         dissect_abort_request(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_END_REQUEST:
         dissect_end_request(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_PARAMS:
         dissect_params(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_GET_VALUES:
         dissect_get_values(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      case FCGI_GET_VALUES_RESULT:
         dissect_get_values_result(tvb, fcgi_tree, offset, clen);
         offset += clen;
         break;
      default:
         if (clen > 0) {
            proto_tree_add_item(fcgi_tree, hf_fcgi_content_data, tvb, offset, clen, ENC_NA);
            offset += clen;
         }
         break;
      }

      if (plen > 0) {
         proto_tree_add_item(fcgi_tree, hf_fcgi_padding_data, tvb, offset, plen, ENC_NA);
         /*offset += plen;*/
      }
   }
}
static void
dissect_cwids(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	tvbuff_t *wlan_tvb;
	proto_tree *ti, *cwids_tree;
	volatile int offset = 0;
	guint16 capturelen;
	void *pd_save;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "CWIDS");
	col_set_str(pinfo->cinfo, COL_INFO, "Cwids: ");
	/* FIXME: col_set_fence(pinfo->cinfo, all-cols, only addr-cols?); */

	cwids_tree = NULL;

	while(tvb_length_remaining(tvb, offset) > 0) {
		ti = proto_tree_add_item(tree, proto_cwids, tvb, offset, 28, ENC_NA);
		cwids_tree = proto_item_add_subtree(ti, ett_cwids);

		proto_tree_add_item(cwids_tree, hf_cwids_version, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;
		proto_tree_add_item(cwids_tree, hf_cwids_unknown1, tvb, offset, 7, ENC_NA);
		offset += 7;
		proto_tree_add_item(cwids_tree, hf_cwids_channel, tvb, offset, 1, ENC_BIG_ENDIAN);
		offset += 1;
		proto_tree_add_item(cwids_tree, hf_cwids_unknown2, tvb, offset, 6, ENC_NA);
		offset += 6;
		proto_tree_add_item(cwids_tree, hf_cwids_reallength, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;
		capturelen = tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(cwids_tree, hf_cwids_capturelen, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;
		proto_tree_add_item(cwids_tree, hf_cwids_unknown3, tvb, offset, 8, ENC_NA);
		offset += 8;

		wlan_tvb = tvb_new_subset(tvb, offset, capturelen, capturelen);
		/* Continue after ieee80211 dissection errors */
		pd_save = pinfo->private_data;
		TRY {
			call_dissector(ieee80211_handle, wlan_tvb, pinfo, tree);
		} CATCH2(BoundsError, ReportedBoundsError) {

			expert_add_info_format(pinfo, NULL,
				PI_MALFORMED, PI_ERROR,
				"Malformed or short IEEE80211 subpacket");

			/*  Restore the private_data structure in case one of the
			 *  called dissectors modified it (and, due to the exception,
			 *  was unable to restore it).
			 */
			pinfo->private_data = pd_save;

			col_append_str(pinfo->cinfo, COL_INFO,
				" [Malformed or short IEEE80211 subpacket] " );
			col_set_fence(pinfo->cinfo, COL_INFO);
#if 0
	wlan_tvb = tvb_new_subset(tvb, offset, capturelen, capturelen);
			/* FIXME: Why does this throw an exception? */
			proto_tree_add_text(cwids_tree, wlan_tvb, offset, capturelen,
				"[Malformed or short IEEE80211 subpacket]");
#else
			tvb_new_subset(tvb, offset, capturelen, capturelen);
#endif
	;
		} ENDTRY;

		offset += capturelen;
	}
Esempio n. 8
0
static void
dissect_rtmpt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*rtmpt_tree = NULL;
	proto_tree	*rtmptroot_tree = NULL;
	proto_item	*ti = NULL;
	gint        offset = 0;

	struct tcpinfo* tcpinfo = pinfo->private_data;

	guint8  iCommand = -1;
	guint32 iLength = 1;
	guint16 iHeaderType = 4;
	guint16 iHeaderLength;
	guint8  iID;
	guint   rtmp_index;

	conversation_t * current_conversation;
	rtmpt_conversation_data_t * conversation_data;
	rtmpt_packet_data_t * packet_data;

	rtmpt_chunk_data_t *current_chunk_data = NULL;
	rtmpt_chunk_data_t *initial_chunk_data = NULL;

	tvbuff_t*   amf_tvb;

	current_conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);

	if (NULL != current_conversation)
	{
		conversation_data = (rtmpt_conversation_data_t*)conversation_get_proto_data(current_conversation, proto_rtmpt);
		if (NULL == conversation_data)
		{
			conversation_data = se_alloc(sizeof(rtmpt_conversation_data_t));
			memset((void*)conversation_data, 0, sizeof(rtmpt_conversation_data_t));
			conversation_add_proto_data(current_conversation, proto_rtmpt, conversation_data);
			conversation_data->current_chunks = g_hash_table_new(g_direct_hash, g_direct_equal);
			conversation_data->previous_frame_number = -1;
			conversation_data->current_chunk_size = RTMPT_DEFAULT_CHUNK_SIZE;
			conversation_data->is_rtmpe = 0;
		}

		packet_data = p_get_proto_data(pinfo->fd, proto_rtmpt);
		if (NULL == packet_data)
		{
			packet_data = se_alloc(sizeof(rtmpt_packet_data_t));
			memset((void*)packet_data, 0, sizeof(rtmpt_packet_data_t));
			p_add_proto_data(pinfo->fd, proto_rtmpt, packet_data);
			packet_data->initial_chunks = g_hash_table_new(g_direct_hash, g_direct_equal);
			packet_data->initial_chunk_size = conversation_data->current_chunk_size;
		}


		if (conversation_data->is_rtmpe == 1)
		{
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMPE");
			return;
		}
		else
		{
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
		}

		if (conversation_data->previous_frame_number != (guint) pinfo->fd->num)
		{
			conversation_data->current_chunk_size = packet_data->initial_chunk_size;
		}

		col_set_writable(pinfo->cinfo, TRUE);
		col_clear(pinfo->cinfo, COL_INFO);

		conversation_data->previous_frame_number = pinfo->fd->num;
		if (tvb_length_remaining(tvb, offset) >= 1)
		{
			if (tcpinfo->lastackseq == RTMPT_HANDSHAKE_OFFSET_1 && tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_1)
			{
				iCommand =  RTMPT_TYPE_HANDSHAKE_1;
			}
			else if (tcpinfo->lastackseq == RTMPT_HANDSHAKE_OFFSET_2 && tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_1) iCommand =  RTMPT_TYPE_HANDSHAKE_2;
			else if (tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_2
			         && tvb_length(tvb) == RTMPT_HANDSHAKE_LENGTH_3) iCommand = RTMPT_TYPE_HANDSHAKE_3;
			else
			{
				iID = tvb_get_guint8(tvb, offset + 0);
				iHeaderType = iID >> 6;
				rtmp_index = iID & 0x3F;

				current_chunk_data = g_hash_table_lookup(conversation_data->current_chunks, GUINT_TO_POINTER(rtmp_index));
				initial_chunk_data = g_hash_table_lookup(packet_data->initial_chunks, GUINT_TO_POINTER(rtmp_index));

				if (iHeaderType <= 2) iLength = tvb_get_ntoh24(tvb, offset + 4);
				if (iHeaderType <= 1)
				{
					iCommand = tvb_get_guint8(tvb, offset + 7);
					if (NULL == current_chunk_data)
					{
						current_chunk_data = se_alloc(sizeof(rtmpt_chunk_data_t));
						memset((void*)current_chunk_data, 0, sizeof(rtmpt_chunk_data_t));
						g_hash_table_insert(conversation_data->current_chunks, GUINT_TO_POINTER(rtmp_index), current_chunk_data);
					}

					current_chunk_data->data_type = iCommand;
					current_chunk_data->last_length = iLength;
					current_chunk_data->frame_modified = pinfo->fd->num;
				}
				else
				{
					/* must get the command type from the previous entries in the hash table */
					/* try to use the current_chunk_data unless it is from a different frame */
					if (NULL != current_chunk_data && NULL != initial_chunk_data)
					{
						/* we have precedent data (we should)*/
						if (current_chunk_data->frame_modified != pinfo->fd->num)
						{
							iCommand = initial_chunk_data->data_type;
							iLength = initial_chunk_data->length_remaining;
							current_chunk_data->frame_modified = pinfo->fd->num;
							current_chunk_data->data_type = iCommand;
							current_chunk_data->last_length = iLength;
							current_chunk_data->dechunk_buffer = initial_chunk_data->dechunk_buffer;
						}
						else
						{
							iCommand = current_chunk_data->data_type;
							iLength = current_chunk_data->length_remaining;
						}

						if (iLength > conversation_data->current_chunk_size)
						{
							iLength = conversation_data->current_chunk_size;
						}
					}
				}
			}

			iHeaderLength = rtmpt_header_length_from_type(iHeaderType);


			if (check_col(pinfo->cinfo, COL_INFO))
			{
				col_append_sep_fstr(pinfo->cinfo, COL_INFO, " | ", "%s", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)"));
				col_set_fence(pinfo->cinfo, COL_INFO);
			}

			if (tree)
			{
				ti = proto_tree_add_item(tree, proto_rtmpt, tvb, offset, -1, FALSE);
				proto_item_append_text(ti, " (%s)", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)"));
				rtmptroot_tree = proto_item_add_subtree(ti, ett_rtmpt);

				ti = proto_tree_add_text(rtmptroot_tree, tvb, offset, iHeaderLength, RTMPT_TEXT_RTMP_HEADER);
				proto_item_append_text(ti, " (%s)", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)"));
				rtmpt_tree = proto_item_add_subtree(ti, ett_rtmpt_header);

				if (iHeaderType <= 3) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_objid, tvb, offset + 0, 1, FALSE);
				if (iHeaderType <= 2) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_timestamp, tvb, offset + 1, 3, FALSE);
				if (iHeaderType <= 1) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_body_size, tvb, offset + 4, 3, FALSE);
				if (iHeaderType <= 1) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_function, tvb, offset + 7, 1, FALSE);
				if (iHeaderType <= 0) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_source, tvb, offset + 8, 4, TRUE);

				if (iCommand == RTMPT_TYPE_HANDSHAKE_1)
				{
					proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1, 1536, FALSE);
				}
				else if (iCommand == RTMPT_TYPE_HANDSHAKE_2)
				{
					proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1, 1536, FALSE);
					proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1537, 1536, FALSE);
				}
				else if (iCommand == RTMPT_TYPE_HANDSHAKE_3)
				{
					proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 0, -1, FALSE);
				}
				else if (iCommand == RTMPT_TYPE_CHUNK_SIZE)
				{
					conversation_data->current_chunk_size = tvb_get_ntohl (tvb, offset + iHeaderLength);
				}

				offset = iHeaderLength;
				if (tvb_length_remaining(tvb, offset))
				{
					ti = proto_tree_add_text(rtmptroot_tree, tvb, offset, -1, RTMPT_TEXT_RTMP_BODY);
				}


				if (iCommand == RTMPT_TYPE_INVOKE || iCommand == RTMPT_TYPE_NOTIFY)
				{
					guint iChunkSize = tvb_length_remaining(tvb, iHeaderLength);
					/* we have data which will be AMF */
					/* we should add it to a new tvb */
					if (NULL != current_chunk_data)
					{
						if (NULL == current_chunk_data->dechunk_buffer)
						{
							/* we have to create a new tvbuffer */
							current_chunk_data->dechunk_buffer = tvb_new_composite();
						}
						if (!(current_chunk_data->dechunk_buffer->initialized))
						{
							/* add the existing data to the new buffer */
							tvb_composite_append(current_chunk_data->dechunk_buffer,
							                     tvb_new_real_data(tvb_memdup(tvb, iHeaderLength, iChunkSize), iChunkSize, iChunkSize));

							if (current_chunk_data->length_remaining <= 0)
							{
								guint amf_length;
								guint8* amf_data;

								tvb_composite_finalize(current_chunk_data->dechunk_buffer);

								amf_length = tvb_length(current_chunk_data->dechunk_buffer);

								if (amf_length == 0)
								{
									return;
								}


								amf_data = tvb_memdup(current_chunk_data->dechunk_buffer, 0, amf_length);

								amf_tvb = tvb_new_real_data(amf_data, tvb_length_remaining(current_chunk_data->dechunk_buffer, 0), tvb_length_remaining(current_chunk_data->dechunk_buffer, 0));

								add_new_data_source(pinfo, amf_tvb, "Dechunked AMF data");
								ti = proto_tree_add_item(tree, proto_rtmpt, amf_tvb, 0, -1, FALSE);
								rtmpt_tree = proto_item_add_subtree(ti, ett_rtmpt_body);
								proto_tree_set_appendix(rtmpt_tree, amf_tvb, 0, tvb_length_remaining(amf_tvb, 0));
								proto_item_append_text(rtmpt_tree, " (%s)", "AMF Data");
								dissect_rtmpt_amf(amf_tvb, rtmpt_tree);
								current_chunk_data->dechunk_buffer = NULL;
							}
						}
					}
				}
			}
		}
	}
Esempio n. 9
0
/*
 * Call this method to actually dissect the multipart body.
 * NOTE - Only do so if a boundary string has been found!
 */
static int dissect_multipart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
    proto_tree *subtree;
    proto_item *ti;
    proto_item *type_ti;
    multipart_info_t *m_info = get_multipart_info(pinfo, (const char*)data);
    gint header_start = 0;
    gint body_index = 0;
    gboolean last_boundary = FALSE;

    if (m_info == NULL) {
        /*
         * We can't get the required multipart information
         */
        proto_tree_add_expert(tree, pinfo, &ei_multipart_no_required_parameter, tvb, 0, -1);
        call_dissector(data_handle, tvb, pinfo, tree);
        return tvb_reported_length(tvb);
    }
    /* Clean up the memory if an exception is thrown */
    /* CLEANUP_PUSH(cleanup_multipart_info, m_info); */

    /* Add stuff to the protocol tree */
    ti = proto_tree_add_item(tree, proto_multipart,
                             tvb, 0, -1, ENC_NA);
    subtree = proto_item_add_subtree(ti, ett_multipart);
    proto_item_append_text(ti, ", Type: %s, Boundary: \"%s\"",
                           m_info->type, m_info->boundary);

    /* Show multi-part type as a generated field */
    type_ti = proto_tree_add_string(subtree, hf_multipart_type,
                                    tvb, 0, 0, pinfo->match_string);
    PROTO_ITEM_SET_GENERATED(type_ti);

    /*
     * Make no entries in Protocol column and Info column on summary display,
     * but stop sub-dissectors from clearing entered text in summary display.
     */
    col_set_fence(pinfo->cinfo, COL_INFO);

    /*
     * Process the multipart preamble
     */
    header_start = process_preamble(subtree, tvb, m_info, &last_boundary);
    if (header_start == -1) {
        call_dissector(data_handle, tvb, pinfo, subtree);
        /* Clean up the dynamically allocated memory */
        cleanup_multipart_info(m_info);
        return tvb_reported_length(tvb);
    }
    /*
     * Process the encapsulated bodies
     */
    while (last_boundary == FALSE) {
        header_start = process_body_part(subtree, tvb, m_info,
                                         pinfo, header_start, body_index++, &last_boundary);
        if (header_start == -1) {
            /* Clean up the dynamically allocated memory */
            cleanup_multipart_info(m_info);
            return tvb_reported_length(tvb);
        }
    }
    /*
     * Process the multipart trailer
     */
    if (tvb_reported_length_remaining(tvb, header_start) > 0) {
        proto_tree_add_item(subtree, hf_multipart_trailer, tvb, header_start, -1, ENC_NA);
    }
    /* Clean up the dynamically allocated memory */
    cleanup_multipart_info(m_info);
    return tvb_reported_length(tvb);
}