diff options
-rw-r--r-- | debian/libwireshark0.symbols | 1 | ||||
-rw-r--r-- | epan/epan.c | 8 | ||||
-rw-r--r-- | epan/epan.h | 7 | ||||
-rw-r--r-- | epan/proto.h | 2 | ||||
-rw-r--r-- | ui/gtk/rtp_analysis.c | 102 | ||||
-rw-r--r-- | ui/qt/rtp_analysis_dialog.cpp | 112 |
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)); |