SIP/SDP, RTP: Dissectors shows information about ED-137 related states of radio in info column/VoIP call flow

Based on EUROCAE ED-137B specification:
ED-137B, Part 1: RADIO, INTEROPERABILITY STANDARDS FOR VOIP ATM COMPONENTS
https://boutique.eurocae.net/eshop/catalog/index.php

Bug: 13252
Change-Id: Ifab1aaf47e3405fcd46309167237f11ce2d7e2ff
Reviewed-on: https://code.wireshark.org/review/19302
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Jiri Novak 2016-12-16 11:49:56 +01:00 committed by Michael Mann
parent b4ea3c50f5
commit 92c725cafb
5 changed files with 142 additions and 8 deletions

View File

@ -2106,6 +2106,8 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
rtp_info->info_setup_frame_num = 0;
rtp_info->info_payload_type_str = NULL;
rtp_info->info_payload_rate = 0;
rtp_info->info_is_ed137 = FALSE;
rtp_info->info_ed137_info = NULL;
/*
* Do we have all the data?
@ -2308,7 +2310,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
pinfo, rtp_hext_tree);
}
else {
if ( !(dissector_try_uint(rtp_hdr_ext_dissector_table, hdr_extension_id, newtvb, pinfo, rtp_hext_tree)) ) {
if ( !(dissector_try_uint_new(rtp_hdr_ext_dissector_table, hdr_extension_id, newtvb, pinfo, rtp_hext_tree, FALSE, rtp_info)) ) {
unsigned int hdrext_offset;
hdrext_offset = offset;
@ -2468,10 +2470,16 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
return offset;
}
/* We do not need to allocate/free strings */
static char *ed137_ptt_only = "PTT";
static char *ed137_squ_only = "SQU";
static char *ed137_ptt_and_squ = "PTT+SQU";
static int
dissect_rtp_hdr_ext_ed137(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ )
{
unsigned int hdr_extension_len;
struct _rtp_info *rtp_info=(struct _rtp_info *)data;
hdr_extension_len = tvb_reported_length(tvb)/4;
@ -2480,7 +2488,10 @@ dissect_rtp_hdr_ext_ed137(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v
unsigned int offset = 0;
unsigned int hdrext_offset = 0;
unsigned int i;
gboolean ed137_ptt = FALSE;
gboolean ed137_squ = FALSE;
rtp_info->info_is_ed137 = TRUE;
if ( tree ) {
proto_item *ti;
ti = proto_tree_add_item(tree, hf_rtp_hdr_ed137s, tvb, offset, hdr_extension_len * 4, ENC_NA);
@ -2493,9 +2504,28 @@ dissect_rtp_hdr_ext_ed137(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, v
if (RTP_ED137_ptt_mask(ext_value)) {
col_append_str(pinfo->cinfo, COL_INFO, ", PTT");
ed137_ptt = TRUE;
}
if (RTP_ED137_squ_mask(ext_value)) {
col_append_str(pinfo->cinfo, COL_INFO, ", SQU");
ed137_squ = TRUE;
}
/* Map PTT/SQU bits to string */
if (rtp_info != NULL) {
if (ed137_ptt) {
if (ed137_squ) {
rtp_info->info_ed137_info = ed137_ptt_and_squ;
} else {
rtp_info->info_ed137_info = ed137_ptt_only;
}
} else {
if (ed137_squ) {
rtp_info->info_ed137_info = ed137_squ_only;
} else {
rtp_info->info_ed137_info = NULL;
}
}
}
ti2 = proto_tree_add_item(rtp_hext_tree, hf_rtp_hdr_ed137, tvb, hdrext_offset, 4, ENC_NA);
@ -2561,6 +2591,7 @@ static int
dissect_rtp_hdr_ext_ed137a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ )
{
unsigned int hdr_extension_len;
struct _rtp_info *rtp_info=(struct _rtp_info *)data;
hdr_extension_len = tvb_reported_length(tvb)/4;
@ -2569,7 +2600,10 @@ dissect_rtp_hdr_ext_ed137a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
unsigned int offset = 0;
unsigned int hdrext_offset = 0;
unsigned int i;
gboolean ed137_ptt = FALSE;
gboolean ed137_squ = FALSE;
rtp_info->info_is_ed137 = TRUE;
if ( tree ) {
proto_item *ti;
ti = proto_tree_add_item(tree, hf_rtp_hdr_ed137s, tvb, offset, hdr_extension_len * 4, ENC_NA);
@ -2582,9 +2616,28 @@ dissect_rtp_hdr_ext_ed137a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (RTP_ED137A_ptt_mask(ext_value)) {
col_append_str(pinfo->cinfo, COL_INFO, ", PTT");
ed137_ptt = TRUE;
}
if (RTP_ED137A_squ_mask(ext_value)) {
col_append_str(pinfo->cinfo, COL_INFO, ", SQU");
ed137_squ = TRUE;
}
/* Map PTT/SQU bits to string */
if (rtp_info != NULL) {
if (ed137_ptt) {
if (ed137_squ) {
rtp_info->info_ed137_info = ed137_ptt_and_squ;
} else {
rtp_info->info_ed137_info = ed137_ptt_only;
}
} else {
if (ed137_squ) {
rtp_info->info_ed137_info = ed137_squ_only;
} else {
rtp_info->info_ed137_info = NULL;
}
}
}
ti2 = proto_tree_add_item(rtp_hext_tree, hf_rtp_hdr_ed137a, tvb, hdrext_offset, 4, ENC_NA);

View File

@ -49,6 +49,8 @@ struct _rtp_info {
const guint8* info_data; /* pointer to raw rtp data */
const gchar *info_payload_type_str;
gint info_payload_rate;
gboolean info_is_ed137;
const gchar *info_ed137_info;
/*
* info_data: pointer to raw rtp data = header + payload incl. padding.
* That should be safe because the "epan_dissect_t" constructed for the packet

View File

@ -35,6 +35,7 @@
#include <epan/rtp_pt.h>
#include <epan/show_exception.h>
#include <epan/addr_resolv.h>
#include <epan/proto_data.h>
#include <wsutil/strtoi.h>
@ -302,6 +303,13 @@ typedef struct {
Note: wmem_file_scope, needs manual dealloc. */
} session_info_t;
/* Structure for private data to hold ED137 related values */
typedef struct sdp_data_t {
char *ed137_type; /* Radio session type */
char *ed137_txrxmode; /* Tx/Rx mode */
char *ed137_fid; /* Frequency ID */
} sdp_data_t;
/* here lie the debugging dumper functions */
#ifdef DEBUG_CONVERSATION
@ -1529,6 +1537,9 @@ typedef struct {
#define SDP_CRYPTO 5
#define SDP_SPRTMAP 6
#define SDP_CANDIDATE 7
#define SDP_ED137_TYPE 8
#define SDP_ED137_TXRXMODE 9
#define SDP_ED137_FID 10
static const sdp_names_t sdp_media_attribute_names[] = {
{ "Unknown-name"}, /* 0 Pad so that the real headers start at index 1 */
@ -1539,6 +1550,9 @@ static const sdp_names_t sdp_media_attribute_names[] = {
{ "crypto"}, /* 5 */
{ "sprt"}, /* 6 */
{ "candidate" }, /* 7 */
{ "type" }, /* 8 */
{ "txrxmode" }, /* 9 */
{ "fid" }, /* 10 */
};
static gint find_sdp_media_attribute_names(tvbuff_t *tvb, int offset, guint len)
@ -1557,7 +1571,8 @@ static gint find_sdp_media_attribute_names(tvbuff_t *tvb, int offset, guint len)
static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto_item * ti, int length,
transport_info_t *transport_info,
session_info_t *session_info,
media_description_t *media_desc)
media_description_t *media_desc,
sdp_data_t *sdp_data)
{
proto_tree *sdp_media_attribute_tree, *parameter_item;
proto_item *fmtp_item, *media_format_item, *parameter_tree;
@ -1998,6 +2013,24 @@ static void dissect_sdp_media_attribute(tvbuff_t *tvb, packet_info *pinfo, proto
case SDP_CANDIDATE:
dissect_sdp_media_attribute_candidate(sdp_media_attribute_tree, tvb, offset);
break;
case SDP_ED137_TYPE:
/* Remember the value and add it to tree */
sdp_data->ed137_type = attribute_value;
proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
tvb, offset, -1, ENC_UTF_8|ENC_NA);
break;
case SDP_ED137_TXRXMODE:
/* Remember the value and add it to tree */
sdp_data->ed137_txrxmode = attribute_value;
proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
tvb, offset, -1, ENC_UTF_8|ENC_NA);
break;
case SDP_ED137_FID:
/* Remember the value and add it to tree */
sdp_data->ed137_fid = attribute_value;
proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
tvb, offset, -1, ENC_UTF_8|ENC_NA);
break;
default:
/* No special treatment for values of this attribute type, just add as one item. */
proto_tree_add_item(sdp_media_attribute_tree, hf_media_attribute_value,
@ -2010,7 +2043,8 @@ static void
call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, int hf, proto_tree* ti, int length,
transport_info_t *transport_info,
session_info_t *session_info,
media_description_t *media_desc)
media_description_t *media_desc,
sdp_data_t *sdp_data)
{
if (hf == hf_owner) {
dissect_sdp_owner(tvb, ti);
@ -2031,7 +2065,7 @@ call_sdp_subdissector(tvbuff_t *tvb, packet_info *pinfo, int hf, proto_tree* ti,
} else if (hf == hf_media) {
dissect_sdp_media(tvb, pinfo, ti, media_desc);
} else if (hf == hf_media_attribute) {
dissect_sdp_media_attribute(tvb, pinfo, ti, length, transport_info, session_info, media_desc);
dissect_sdp_media_attribute(tvb, pinfo, ti, length, transport_info, session_info, media_desc, sdp_data);
}
}
@ -2221,6 +2255,7 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
transport_info_t* transport_info = NULL;
media_description_t *media_desc = NULL;
session_info_t session_info;
sdp_data_t sdp_data;
DPRINT2(("-------------------- setup_sdp_transport -------------------"));
@ -2230,6 +2265,8 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
return;
}
memset(&sdp_data, 0, sizeof(sdp_data));
if (request_frame != 0)
transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_reqs, request_frame );
if (transport_info == NULL) {
@ -2332,7 +2369,8 @@ setup_sdp_transport(tvbuff_t *tvb, packet_info *pinfo, enum sdp_exchange_type ex
hf, NULL, linelen-tokenoffset,
transport_info,
in_media_description ? NULL : &session_info,
media_desc);
media_desc,
&sdp_data);
DENDENT();
}
@ -2394,6 +2432,7 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
guchar type, delim;
int datalen, tokenoffset, hf = -1;
char *string;
sdp_data_t sdp_data;
transport_info_t local_transport_info;
transport_info_t* transport_info = NULL;
@ -2407,6 +2446,8 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
sdp_pi = wmem_new(wmem_packet_scope(), sdp_packet_info);
sdp_pi->summary_str[0] = '\0';
memset(&sdp_data, 0, sizeof(sdp_data));
if (!pinfo->fd->flags.visited) {
transport_info = (transport_info_t*)wmem_tree_lookup32( sdp_transport_reqs, pinfo->num );
@ -2567,11 +2608,31 @@ dissect_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
hf, sub_ti, linelen-tokenoffset,
&local_transport_info,
in_media_description ? NULL : &session_info,
in_media_description ? media_desc : NULL);
in_media_description ? media_desc : NULL,
&sdp_data);
offset = next_offset;
}
if (NULL != sdp_data.ed137_fid) {
col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", sdp_data.ed137_fid);
if (strlen(sdp_pi->summary_str))
g_strlcat(sdp_pi->summary_str, " ", 50);
g_strlcat(sdp_pi->summary_str, sdp_data.ed137_fid, 50);
}
if (NULL != sdp_data.ed137_txrxmode) {
col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", sdp_data.ed137_txrxmode);
if (strlen(sdp_pi->summary_str))
g_strlcat(sdp_pi->summary_str, " ", 50);
g_strlcat(sdp_pi->summary_str, sdp_data.ed137_txrxmode, 50);
}
if (NULL != sdp_data.ed137_type) {
col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", sdp_data.ed137_type);
if (strlen(sdp_pi->summary_str))
g_strlcat(sdp_pi->summary_str, " ", 50);
g_strlcat(sdp_pi->summary_str, sdp_data.ed137_type, 50);
}
/* Done parsing media description, no more need for the session-level details. */
rtp_dyn_payload_free(session_info.rtp_dyn_payload);
session_info.rtp_dyn_payload = NULL;

View File

@ -76,6 +76,7 @@ typedef struct _rtp_stream_info {
tap_rtp_stat_t rtp_stats; /**< here goes the RTP statistics info */
gboolean problem; /**< if the streams had wrong sequence numbers or wrong timestamps */
gchar *ed137_info;
} rtp_stream_info_t;
/** tapping modes */

View File

@ -305,6 +305,7 @@ voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
{
strinfo = (rtp_stream_info_t *)list->data;
wmem_free(NULL, strinfo->payload_type_name);
wmem_free(NULL, strinfo->ed137_info);
list = g_list_next(list);
}
g_list_free(tapinfo->rtp_stream_list);
@ -620,6 +621,14 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
this is to show multiple payload changes in the Graph for example for DTMF RFC2833 */
if ( tmp_listinfo->payload_type != rtp_info->info_payload_type ) {
tmp_listinfo->end_stream = TRUE;
} else if ( ( ( tmp_listinfo->ed137_info == NULL ) && (rtp_info->info_ed137_info != NULL) ) ||
( ( tmp_listinfo->ed137_info != NULL ) && (rtp_info->info_ed137_info == NULL) ) ||
( ( tmp_listinfo->ed137_info != NULL ) && (rtp_info->info_ed137_info != NULL) &&
( 0!=strcmp(tmp_listinfo->ed137_info, rtp_info->info_ed137_info) )
)
) {
/* if ed137_info has changed, create new stream */
tmp_listinfo->end_stream = TRUE;
} else {
strinfo = (rtp_stream_info_t*)(list->data);
break;
@ -660,6 +669,11 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
strinfo->setup_frame_number = rtp_info->info_setup_frame_num;
strinfo->call_num = -1;
strinfo->rtp_event = -1;
if (rtp_info->info_ed137_info != NULL) {
strinfo->ed137_info = wmem_strdup(NULL, rtp_info->info_ed137_info);
} else {
strinfo->ed137_info = NULL;
}
tapinfo->rtp_stream_list = g_list_prepend(tapinfo->rtp_stream_list, strinfo);
}
@ -726,11 +740,14 @@ rtp_draw(void *tap_offset_ptr)
new_gai->port_src = rtp_listinfo->src_port;
new_gai->port_dst = rtp_listinfo->dest_port;
duration = (guint32)(nstime_to_msec(&rtp_listinfo->stop_rel_time) - nstime_to_msec(&rtp_listinfo->start_rel_time));
new_gai->frame_label = g_strdup_printf("%s (%s) %s",
new_gai->frame_label = g_strdup_printf("%s (%s) %s%s%s",
(rtp_listinfo->is_srtp)?"SRTP":"RTP",
rtp_listinfo->payload_type_name,
(rtp_listinfo->rtp_event == -1)?
"":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"));
"":val_to_str_ext_const(rtp_listinfo->rtp_event, &rtp_event_type_values_ext, "Unknown RTP Event"),
(rtp_listinfo->ed137_info!=NULL?" ":""),
(rtp_listinfo->ed137_info!=NULL?rtp_listinfo->ed137_info:"")
);
new_gai->comment = g_strdup_printf(comment_fmt,
(rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
duration/1000,(duration%1000), rtp_listinfo->ssrc);