aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--debian/libwireshark0.symbols1
-rw-r--r--epan/epan.c8
-rw-r--r--epan/epan.h7
-rw-r--r--epan/proto.h2
-rw-r--r--ui/gtk/rtp_analysis.c102
-rw-r--r--ui/qt/rtp_analysis_dialog.cpp112
6 files changed, 61 insertions, 171 deletions
diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols
index fe9952d017..2dfd297131 100644
--- a/debian/libwireshark0.symbols
+++ b/debian/libwireshark0.symbols
@@ -476,6 +476,7 @@ libwireshark.so.0 libwireshark0 #MINVER#
epan_dissect_new@Base 1.9.1
epan_dissect_packet_contains_field@Base 1.12.0~rc1
epan_dissect_prime_dfilter@Base 1.9.1
+ epan_dissect_prime_hfid@Base 2.1.0
epan_dissect_reset@Base 1.12.0~rc1
epan_dissect_run@Base 1.9.1
epan_dissect_run_with_taps@Base 1.9.1
diff --git a/epan/epan.c b/epan/epan.c
index 98815b5d6f..d33544e681 100644
--- a/epan/epan.c
+++ b/epan/epan.c
@@ -446,7 +446,13 @@ epan_dissect_free(epan_dissect_t* edt)
void
epan_dissect_prime_dfilter(epan_dissect_t *edt, const dfilter_t* dfcode)
{
- dfilter_prime_proto_tree(dfcode, edt->tree);
+ dfilter_prime_proto_tree(dfcode, edt->tree);
+}
+
+void
+epan_dissect_prime_hfid(epan_dissect_t *edt, int hfid)
+{
+ proto_tree_prime_hfid(edt->tree, hfid);
}
/* ----------------------- */
diff --git a/epan/epan.h b/epan/epan.h
index 41bf18e437..1c743e80f3 100644
--- a/epan/epan.h
+++ b/epan/epan.h
@@ -206,11 +206,16 @@ void
epan_dissect_file_run_with_taps(epan_dissect_t *edt, struct wtap_pkthdr *phdr,
tvbuff_t *tvb, frame_data *fd, struct epan_column_info *cinfo);
-/** Prime a proto_tree using the fields/protocols used in a dfilter. */
+/** Prime an epan_dissect_t's proto_tree using the fields/protocols used in a dfilter. */
WS_DLL_PUBLIC
void
epan_dissect_prime_dfilter(epan_dissect_t *edt, const struct epan_dfilter *dfcode);
+/** Prime an epan_dissect_t's proto_tree with a field/protocol specified by its hfid */
+WS_DLL_PUBLIC
+void
+epan_dissect_prime_hfid(epan_dissect_t *edt, int hfid);
+
/** fill the dissect run output into the packet list columns */
WS_DLL_PUBLIC
void
diff --git a/epan/proto.h b/epan/proto.h
index 8277cde828..51e4dc0bac 100644
--- a/epan/proto.h
+++ b/epan/proto.h
@@ -2088,7 +2088,7 @@ WS_DLL_PUBLIC header_field_info* proto_registrar_get_byname(const char *field_na
/** Get the header_field id based upon a field name.
@param field_name the field name to search for
@return the field id for the registered item */
-extern int proto_registrar_get_id_byname(const char *field_name);
+WS_DLL_PUBLIC int proto_registrar_get_id_byname(const char *field_name);
/** Get enum ftenum FT_ of registered header_field number n.
@param n item # n (0-indexed)
diff --git a/ui/gtk/rtp_analysis.c b/ui/gtk/rtp_analysis.c
index 846635e206..2815e73d88 100644
--- a/ui/gtk/rtp_analysis.c
+++ b/ui/gtk/rtp_analysis.c
@@ -3719,75 +3719,6 @@ create_rtp_dialog(user_data_t* user_data)
/****************************************************************************/
-static gboolean
-process_node(proto_node *ptree_node, header_field_info *hfinformation,
- const gchar* proto_field, guint32* p_result)
-{
- field_info *finfo;
- proto_node *proto_sibling_node;
- header_field_info *hfssrc;
- ipv4_addr_and_mask *ipv4;
-
- finfo = PNODE_FINFO(ptree_node);
-
- /* Caller passed top of the protocol tree. Expected child node */
- g_assert(finfo);
-
- if (hfinformation == (finfo->hfinfo)) {
- hfssrc = proto_registrar_get_byname(proto_field);
- if (hfssrc == NULL)
- return FALSE;
- for (ptree_node = ptree_node->first_child;
- ptree_node != NULL;
- ptree_node = ptree_node->next) {
- finfo = PNODE_FINFO(ptree_node);
- if (hfssrc == finfo->hfinfo) {
- if (hfinformation->type == FT_IPv4) {
- ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
- *p_result = ipv4_get_net_order_addr(ipv4);
- }
- else {
- *p_result = fvalue_get_uinteger(&finfo->value);
- }
- return TRUE;
- }
- }
- if (!ptree_node)
- return FALSE;
- }
-
- proto_sibling_node = ptree_node->next;
-
- if (proto_sibling_node) {
- return process_node(proto_sibling_node, hfinformation, proto_field, p_result);
- }
- else
- return FALSE;
-}
-
-/****************************************************************************/
-static gboolean
-get_int_value_from_proto_tree(proto_tree *protocol_tree,
- const gchar *proto_name,
- const gchar *proto_field,
- guint32 *p_result)
-{
- proto_node *ptree_node;
- header_field_info *hfinformation;
-
- hfinformation = proto_registrar_get_byname(proto_name);
- if (hfinformation == NULL)
- return FALSE;
-
- ptree_node = ((proto_node *)protocol_tree)->first_child;
- if (!ptree_node)
- return FALSE;
-
- return process_node(ptree_node, hfinformation, proto_field, p_result);
-}
-
-
-/****************************************************************************/
void
rtp_analysis(address *src_fwd,
guint32 port_src_fwd,
@@ -3921,9 +3852,9 @@ rtp_analysis_cb(GtkAction *action _U_, gpointer user_data _U_)
address dst_rev;
guint32 port_dst_rev;
guint32 ssrc_rev = 0;
- unsigned int version_fwd;
+ GPtrArray *gp;
- const gchar *filter_text = "rtp && rtp.version && rtp.ssrc && (ip || ipv6)";
+ const gchar filter_text[] = "rtp && rtp.version == 2 && rtp.ssrc && (ip || ipv6)";
dfilter_t *sfcode;
gchar *err_msg;
capture_file *cf;
@@ -3932,8 +3863,16 @@ rtp_analysis_cb(GtkAction *action _U_, gpointer user_data _U_)
GList *filtered_list = NULL;
guint nfound;
epan_dissect_t edt;
+ int hfid_rtp_ssrc;
rtp_stream_info_t *strinfo;
+ /* Try to get the hfid for "rtp.ssrc". */
+ hfid_rtp_ssrc = proto_registrar_get_id_byname("rtp.ssrc");
+ if (hfid_rtp_ssrc == -1) {
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "There is no \"rtp.ssrc\" field in this version of Wireshark.");
+ return;
+ }
+
/* Try to compile the filter. */
if (!dfilter_compile(filter_text, &sfcode, &err_msg)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
@@ -3953,13 +3892,17 @@ rtp_analysis_cb(GtkAction *action _U_, gpointer user_data _U_)
return; /* error reading the record */
epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
epan_dissect_prime_dfilter(&edt, sfcode);
+ epan_dissect_prime_hfid(&edt, hfid_rtp_ssrc);
epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
- /* if it is not an rtp packet, show the rtpstream dialog */
+ /*
+ * Packet must be an RTPv2 packet with an SSRC; we use the filter to
+ * check.
+ */
if (!dfilter_apply_edt(sfcode, &edt)) {
epan_dissect_cleanup(&edt);
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Please select an RTP packet.");
+ "Please select an RTPv2 packet with an SSID.");
return;
}
@@ -3975,19 +3918,16 @@ rtp_analysis_cb(GtkAction *action _U_, gpointer user_data _U_)
port_src_rev = edt.pi.destport;
port_dst_rev = edt.pi.srcport;
- /* check if it is RTP Version 2 */
- if (!get_int_value_from_proto_tree(edt.tree, "rtp", "rtp.version", &version_fwd) || version_fwd != 2) {
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "Only RTP version 2 is supported.");
- return;
- }
-
/* now we need the SSRC value of the current frame */
- if (!get_int_value_from_proto_tree(edt.tree, "rtp", "rtp.ssrc", &ssrc_fwd)) {
+ gp = proto_get_finfo_ptr_array(edt.tree, hfid_rtp_ssrc);
+ if (gp == NULL || gp->len == 0) {
+ /* XXX - should not happen, as the filter inculdes rtp.ssrc */
+ epan_dissect_cleanup(&edt);
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"SSRC value not found.");
return;
}
+ ssrc_fwd = fvalue_get_uinteger(&((field_info *)gp->pdata[0])->value);
/* Scan for rtpstream */
rtpstream_scan(rtpstream_dlg_get_tapinfo(), &cfile, NULL);
diff --git a/ui/qt/rtp_analysis_dialog.cpp b/ui/qt/rtp_analysis_dialog.cpp
index ae819d48ad..66ac236e94 100644
--- a/ui/qt/rtp_analysis_dialog.cpp
+++ b/ui/qt/rtp_analysis_dialog.cpp
@@ -372,7 +372,7 @@ RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, struct _r
findStreams();
}
- if (num_streams_ < 1) {
+ if (err_str_.isEmpty() && num_streams_ < 1) {
err_str_ = tr("No streams found.");
}
@@ -1366,75 +1366,6 @@ void RtpAnalysisDialog::saveCsv(RtpAnalysisDialog::StreamDirection direction)
}
}
-// Adapted from rtp_analysis.c:process_node
-guint32 RtpAnalysisDialog::processNode(proto_node *ptree_node, header_field_info *hfinformation, const gchar *proto_field, bool *ok)
-{
- field_info *finfo;
- proto_node *proto_sibling_node;
- header_field_info *hfssrc;
- ipv4_addr_and_mask *ipv4;
-
- finfo = PNODE_FINFO(ptree_node);
-
- /* Caller passed top of the protocol tree. Expected child node */
- g_assert(finfo);
-
- if (hfinformation == (finfo->hfinfo)) {
- hfssrc = proto_registrar_get_byname(proto_field);
- if (hfssrc == NULL) {
- return 0;
- }
- for (ptree_node = ptree_node->first_child;
- ptree_node != NULL;
- ptree_node = ptree_node->next) {
- finfo = PNODE_FINFO(ptree_node);
- if (hfssrc == finfo->hfinfo) {
- guint32 result;
- if (hfinformation->type == FT_IPv4) {
- ipv4 = (ipv4_addr_and_mask *)fvalue_get(&finfo->value);
- result = ipv4_get_net_order_addr(ipv4);
- } else {
- result = fvalue_get_uinteger(&finfo->value);
- }
- if (ok) *ok = true;
- return result;
- }
- }
- if (!ptree_node) {
- return 0;
- }
- }
-
- proto_sibling_node = ptree_node->next;
-
- if (proto_sibling_node) {
- return processNode(proto_sibling_node, hfinformation, proto_field, ok);
- } else {
- return 0;
- }
-}
-
-// Adapted from rtp_analysis.c:get_int_value_from_proto_tree
-guint32 RtpAnalysisDialog::getIntFromProtoTree(proto_tree *protocol_tree, const gchar *proto_name, const gchar *proto_field, bool *ok)
-{
- proto_node *ptree_node;
- header_field_info *hfinformation;
-
- if (ok) *ok = false;
-
- hfinformation = proto_registrar_get_byname(proto_name);
- if (hfinformation == NULL) {
- return 0;
- }
-
- ptree_node = ((proto_node *)protocol_tree)->first_child;
- if (!ptree_node) {
- return 0;
- }
-
- return processNode(ptree_node, hfinformation, proto_field, ok);
-}
-
bool RtpAnalysisDialog::eventFilter(QObject *, QEvent *event)
{
if (event->type() != QEvent::KeyPress) return false;
@@ -1464,14 +1395,24 @@ void RtpAnalysisDialog::graphClicked(QMouseEvent *event)
void RtpAnalysisDialog::findStreams()
{
- const gchar *filter_text = "rtp && rtp.version && rtp.ssrc";
+ const gchar filter_text[] = "rtp && rtp.version == 2 && rtp.ssrc && (ip || ipv6)";
dfilter_t *sfcode;
gchar *err_msg;
+ /* Try to get the hfid for "rtp.ssrc". */
+ int hfid_rtp_ssrc = proto_registrar_get_id_byname("rtp.ssrc");
+ if (hfid_rtp_ssrc == -1) {
+ err_str_ = tr("There is no \"rtp.ssrc\" field in this version of Wireshark.");
+ updateWidgets();
+ return;
+ }
+
+ /* Try to compile the filter. */
if (!dfilter_compile(filter_text, &sfcode, &err_msg)) {
- QMessageBox::warning(this, tr("No RTP packets found"), QString("%1").arg(err_msg));
+ err_str_ = QString(err_msg);
g_free(err_msg);
- close();
+ updateWidgets();
+ return;
}
if (!cap_file_.capFile() || !cap_file_.capFile()->current_frame) close();
@@ -1484,14 +1425,18 @@ void RtpAnalysisDialog::findStreams()
epan_dissect_init(&edt, cap_file_.capFile()->epan, TRUE, FALSE);
epan_dissect_prime_dfilter(&edt, sfcode);
+ epan_dissect_prime_hfid(&edt, hfid_rtp_ssrc);
epan_dissect_run(&edt, cap_file_.capFile()->cd_t, &cap_file_.capFile()->phdr,
frame_tvbuff_new_buffer(fdata, &cap_file_.capFile()->buf), fdata, NULL);
- // This shouldn't happen (the menu item should be disabled) but check anyway
+ /*
+ * Packet must be an RTPv2 packet with an SSRC; we use the filter to
+ * check.
+ */
if (!dfilter_apply_edt(sfcode, &edt)) {
epan_dissect_cleanup(&edt);
dfilter_free(sfcode);
- err_str_ = tr("Please select an RTP packet");
+ err_str_ = tr("Please select an RTPv2 packet with an SSRC value");
updateWidgets();
return;
}
@@ -1510,23 +1455,16 @@ void RtpAnalysisDialog::findStreams()
port_src_rev_ = edt.pi.destport;
port_dst_rev_ = edt.pi.srcport;
- /* Check if it is RTP Version 2 */
- unsigned int version_fwd;
- bool ok;
- version_fwd = getIntFromProtoTree(edt.tree, "rtp", "rtp.version", &ok);
- if (!ok || version_fwd != 2) {
- err_str_ = tr("RTP version %1 found. Only version 2 is supported.").arg(version_fwd);
- updateWidgets();
- return;
- }
-
/* now we need the SSRC value of the current frame */
- ssrc_fwd_ = getIntFromProtoTree(edt.tree, "rtp", "rtp.ssrc", &ok);
- if (!ok) {
+ GPtrArray *gp = proto_get_finfo_ptr_array(edt.tree, hfid_rtp_ssrc);
+ if (gp == NULL || gp->len == 0) {
+ /* XXX - should not happen, as the filter includes rtp.ssrc */
+ epan_dissect_cleanup(&edt);
err_str_ = tr("SSRC value not found.");
updateWidgets();
return;
}
+ ssrc_fwd_ = fvalue_get_uinteger(&((field_info *)gp->pdata[0])->value);
/* Register the tap listener */
memset(&tapinfo_, 0, sizeof(rtpstream_tapinfo_t));