示例#1
0
/*-----------------------------------------------------------------------------
  UA DISSECTOR
  ---------------------------------------------------------------------------*/
static void _dissect_ua_msg(tvbuff_t       *tvb,
                            packet_info    *pinfo,
                            proto_tree     *tree,
                            e_ua_direction  direction)
{
    gint        offset = 0;
    proto_item *ua_msg_item;
    proto_tree *ua_msg_tree;

    ua_msg_item = proto_tree_add_protocol_format(tree, proto_ua_msg, tvb, 0, -1,
                  "Universal Alcatel Protocol, %s",
                  ((direction == SYS_TO_TERM) ?
                   "System -> Terminal" : "Terminal -> System"));

    ua_msg_tree = proto_item_add_subtree(ua_msg_item, ett_ua_msg);

    while (tvb_offset_exists(tvb, offset))
    {
        gint length;
        gint opcode;

        length = tvb_get_letohs(tvb, offset) + 2;
        opcode = tvb_get_guint8(tvb, offset+2);

        /* RTP/RTCP conversation setup */
        if (setup_conversations_enabled && (opcode==0x13) && (tvb_get_guint8(tvb, offset+3)==0x01))
        {
            address remote_rtp_addr;
            guint32 remote_rtp_port;
            gint    suboffset;

            remote_rtp_addr.data = NULL;
            remote_rtp_port = 0;

            /* StartRTP */
            suboffset = offset + 5;

            while (suboffset < offset+length)
            {
                switch (tvb_get_guint8(tvb, suboffset))
                {
                case 0x00: /* local port */
                {
                    /*local_rtp_port = tvb_get_ntohs(tvb, suboffset+2);*/
                    break;
                }
                case 0x01: /* remote IP */
                {
                    remote_rtp_addr.type = AT_IPv4;
                    remote_rtp_addr.len  = 4;
                    remote_rtp_addr.data = tvb_get_ptr(tvb, suboffset+2, 4);
                    break;
                }
                case 0x02: /* remote port */
                {
                    remote_rtp_port = tvb_get_ntohs(tvb, suboffset+2);
                    break;
                }
                }

                suboffset += tvb_get_guint8(tvb, suboffset+1) + 2;
            }

            if ((remote_rtp_addr.data != NULL) && (remote_rtp_port != 0))
            {
                rtp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port, 0,
                                "UA", pinfo->fd->num, 0, NULL);
                rtcp_add_address(pinfo, &remote_rtp_addr, remote_rtp_port+1, 0,
                                 "UA", pinfo->fd->num);
            }
        }

        uadecode(direction, ua_msg_tree, pinfo, tvb, offset, opcode, length);

        offset += length;
    }
}
示例#2
0
static void
rtsp_create_conversation(packet_info *pinfo, const guchar *line_begin,
                         size_t line_len, gint rdt_feature_level)
{
	conversation_t	*conv;
	guchar		buf[256];
	guchar		*tmp;
	gboolean	rtp_transport = FALSE;
	gboolean	rdt_transport = FALSE;
	guint		c_data_port, c_mon_port;
	guint		s_data_port, s_mon_port;
	gboolean	is_video = FALSE; /* FIX ME - need to indicate video or not */

	/* Copy line into buf */
	if (line_len > sizeof(buf) - 1)
	{
		/* Don't overflow the buffer. */
		line_len = sizeof(buf) - 1;
	}
	memcpy(buf, line_begin, line_len);
	buf[line_len] = '\0';

	/* Get past "Transport:" and spaces */ 
	tmp = buf + STRLEN_CONST(rtsp_transport);
	while (*tmp && isspace(*tmp))
		tmp++;

	/* Work out which transport type is here */
	if (g_ascii_strncasecmp(tmp, rtsp_rtp, strlen(rtsp_rtp)) == 0)
		rtp_transport = TRUE;
	else
	if (g_ascii_strncasecmp(tmp, rtsp_real_rdt, strlen(rtsp_real_rdt)) == 0 ||
	    g_ascii_strncasecmp(tmp, rtsp_real_tng, strlen(rtsp_real_tng)) == 0)
		rdt_transport = TRUE;
	else
	{
		/* Give up on unknown transport types */
		return;
	}
	
	c_data_port = c_mon_port = 0;
	s_data_port = s_mon_port = 0;
	
	/* Look for server port */
	if ((tmp = strstr(buf, rtsp_sps))) {
		tmp += strlen(rtsp_sps);
		if (sscanf(tmp, "%u-%u", &s_data_port, &s_mon_port) < 1) {
			g_warning("Frame %u: rtsp: bad server_port",
				pinfo->fd->num);
			return;
		}
	}
	/* Look for client port */
	if ((tmp = strstr(buf, rtsp_cps))) {
		tmp += strlen(rtsp_cps);
		if (sscanf(tmp, "%u-%u", &c_data_port, &c_mon_port) < 1) {
			g_warning("Frame %u: rtsp: bad client_port",
				pinfo->fd->num);
			return;
		}
	}
	
	
	/* Deal with RTSP TCP-interleaved conversations. */
	if (!c_data_port) {
		rtsp_conversation_data_t	*data;
		guint				s_data_chan, s_mon_chan;
		int				i;

		/* Search tranport line for interleaved string */
		if ((tmp = strstr(buf, rtsp_inter)) == NULL) {
			/*
			 * No interleaved or server_port - probably a
			 * SETUP request, rather than reply.
			 */
			return;
		}
		
		/* Move tmp to beyone interleaved string */
		tmp += strlen(rtsp_inter);
		/* Look for channel number(s) */
		i = sscanf(tmp, "%u-%u", &s_data_chan, &s_mon_chan);
		if (i < 1)
		{
			g_warning("Frame %u: rtsp: bad interleaved", pinfo->fd->num);
			return;
		}
		
		/* At least data channel present, look for conversation (presumably TCP) */
		conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
		                         pinfo->srcport, pinfo->destport, 0);

		/* Create new conversation if necessary */
		if (!conv)
		{
			conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
			                        pinfo->ptype, pinfo->srcport, pinfo->destport,
			                        0);
		}
		
		/* Look for previous data */
		data = conversation_get_proto_data(conv, proto_rtsp);

		/* Create new data if necessary */
		if (!data)
		{
			data = se_alloc(sizeof(rtsp_conversation_data_t));
			conversation_add_proto_data(conv, proto_rtsp, data);
		}

		/* Now set the dissector handle of the interleaved channel
		   according to the transport protocol used */
		if (rtp_transport)
		{
			if (s_data_chan < RTSP_MAX_INTERLEAVED) {
				data->interleaved[s_data_chan].dissector =
					rtp_handle;
			}
			if (i > 1 && s_mon_chan < RTSP_MAX_INTERLEAVED) {
				data->interleaved[s_mon_chan].dissector =
					rtcp_handle;
			}
		}
		else if (rdt_transport)
		{
			if (s_data_chan < RTSP_MAX_INTERLEAVED) {
				data->interleaved[s_data_chan].dissector =
					rdt_handle;
			}
		}
		return;
	}

	/*
	 * We only want to match on the destination address, not the
	 * source address, because the server might send back a packet
	 * from an address other than the address to which its client
	 * sent the packet, so we construct a conversation with no
	 * second address.
	 */
	if (rtp_transport)
	{
		/* There is always data for RTP */
		rtp_add_address(pinfo, &pinfo->dst, c_data_port, s_data_port,
		                "RTSP", pinfo->fd->num, is_video, NULL);
	
		/* RTCP only if indicated */
		if (c_mon_port)
		{
			rtcp_add_address(pinfo, &pinfo->dst, c_mon_port, s_mon_port,
			                 "RTSP", pinfo->fd->num);
		}
	}
	else
	if (rdt_transport)
	{
		/* Real Data Transport */
		rdt_add_address(pinfo, &pinfo->dst, c_data_port, s_data_port,
		                "RTSP", rdt_feature_level);
	}
}