/*----------------------------------------------------------------------------- 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; } }
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); } }