diff options
33 files changed, 1304 insertions, 224 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4639b94a17..bc0234b9fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -529,7 +529,12 @@ if(BUILD_wireshark) set( QT5_DLL_PATH "${QT5_BASE_PATH}/bin" ) set( WS_ALL_LIBS ${WS_ALL_LIBS} ${QT5_DLL_PATH} ) endif() - set(PACKAGELIST ${PACKAGELIST} Qt5Widgets Qt5PrintSupport Qt5LinguistTools) + set(PACKAGELIST ${PACKAGELIST} + Qt5LinguistTools + Qt5MultimediaWidgets + Qt5PrintSupport + Qt5Widgets + ) if (APPLE) set(PACKAGELIST ${PACKAGELIST} Qt5MacExtras) endif() @@ -732,6 +737,11 @@ if (Qt5Widgets_FOUND) endif() set (QT_FOUND ON) set (QT_LIBRARIES ${Qt5Widgets_LIBRARIES} ${Qt5PrintSupport_LIBRARIES}) + if(Qt5MultimediaWidgets_FOUND) + set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5MultimediaWidgets_LIBRARIES}) + # That's the name autofoo uses + set(QT_MULTIMEDIAWIDGETS_LIB 1) + endif() if(Qt5MacExtras_FOUND) set (QT_LIBRARIES ${QT_LIBRARIES} ${Qt5MacExtras_LIBRARIES}) # That's the name autofoo uses diff --git a/acinclude.m4 b/acinclude.m4 index 4b89b35dd3..47457f634b 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -2122,6 +2122,13 @@ AC_DEFUN([AC_WIRESHARK_QT_CHECK], AC_WIRESHARK_QT_MODULE_CHECK(PrintSupport, $1) # + # Qt 5.0 added multimedia widgets in the Qt + # MultimediaWidgets module. + # + AC_WIRESHARK_QT_MODULE_CHECK(MultimediaWidgets, $1, + AC_DEFINE(QT_MULTIMEDIAWIDGETS_LIB, 1, [Define if we have QtMultimediaWidgets])) + + # # While we're at it, look for QtMacExtras. (Presumably # if we're not building for OS X, it won't be present.) # diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in index 7f1c91a5c9..1303adbc7f 100644 --- a/cmakeconfig.h.in +++ b/cmakeconfig.h.in @@ -368,6 +368,9 @@ /* Define if we are using version of of the Portaudio library API */ #cmakedefine PORTAUDIO_API_1 1 +/* Define if we have QtMultimediaWidgets */ +#cmakedefine QT_MULTIMEDIAWIDGETS_LIB 1 + /* Define if we have QtMacExtras */ #cmakedefine QT_MACEXTRAS_LIB 1 diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc index 0afa8f5e24..dd3adf0d95 100644 --- a/docbook/release-notes.asciidoc +++ b/docbook/release-notes.asciidoc @@ -34,6 +34,7 @@ reassembled packets. description to be shown in the status bar. ** An Italian translation has been added. ** The Summary dialog has been updated and renamed to Capture File Properties. +** The VoIP Calls and SIP Flows dialogs have been added. The following features are new (or have been significantly updated) since version 1.12.0: diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 0040a2205b..5045c6a1ae 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1720,7 +1720,7 @@ endif() ABICHECK(libwireshark) -file(GLOB COLUMN_INFO_HEADER column-info.h) +file(GLOB EPAN_HEADERS *.h) file(GLOB CRYPT_HEADERS crypt/*.h) file(GLOB COMPRESS_HEADERS compress/*.h) file(GLOB DFILTER_HEADERS dfilter/*.h ../tools/lemon/cppmagic.h) diff --git a/image/toolbar.qrc b/image/toolbar.qrc index 2fc46fcb53..dc72c68dc4 100644 --- a/image/toolbar.qrc +++ b/image/toolbar.qrc @@ -9,6 +9,8 @@ <file>copy-8.png</file> </qresource> <qresource prefix="/icons"> + <file>toolbar/12x12/media-playback-start.png</file> + <file>toolbar/12x12/media-playback-start@2x.png</file> <file>toolbar/16x16/edit-find.png</file> <file>toolbar/16x16/edit-find@2x.png</file> <file>toolbar/16x16/go-first.png</file> diff --git a/image/toolbar/12x12/media-playback-start.png b/image/toolbar/12x12/media-playback-start.png Binary files differnew file mode 100644 index 0000000000..065d7550e2 --- /dev/null +++ b/image/toolbar/12x12/media-playback-start.png diff --git a/image/toolbar/12x12/media-playback-start.svg b/image/toolbar/12x12/media-playback-start.svg new file mode 100644 index 0000000000..25156d9dd2 --- /dev/null +++ b/image/toolbar/12x12/media-playback-start.svg @@ -0,0 +1,185 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="12" + height="12" + id="svg2" + version="1.1" + inkscape:version="0.48.2 r9819" + sodipodi:docname="media-playback-start.svg"> + <defs + id="defs4"> + <linearGradient + id="linearGradient4324"> + <stop + style="stop-color:#ffffff;stop-opacity:0.15686275;" + offset="0" + id="stop4326" /> + <stop + style="stop-color:#fffffd;stop-opacity:0;" + offset="1" + id="stop4328" /> + </linearGradient> + <linearGradient + id="linearGradient4316"> + <stop + style="stop-color:#000000;stop-opacity:0.15686275;" + offset="0" + id="stop4318" /> + <stop + style="stop-color:#000000;stop-opacity:0;" + offset="1" + id="stop4320" /> + </linearGradient> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4316" + id="linearGradient4322" + x1="3" + y1="3.9245384" + x2="0" + y2="1.0377871" + gradientUnits="userSpaceOnUse" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4324" + id="linearGradient4330" + x1="-1" + y1="-0.8867138" + x2="2" + y2="2.0000374" + gradientUnits="userSpaceOnUse" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="44.416667" + inkscape:cx="6" + inkscape:cy="6" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:window-width="1261" + inkscape:window-height="702" + inkscape:window-x="1701" + inkscape:window-y="76" + inkscape:window-maximized="0"> + <inkscape:grid + type="xygrid" + id="grid2983" + empspacing="2" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1040.3622)"> + <path + inkscape:transform-center-y="-3.9e-05" + inkscape:transform-center-x="-1.25" + transform="matrix(1,0,0,1.0392305,3,1044.2837)" + d="m 7,2 -7.5,4.330127 0,-8.660254 z" + inkscape:randomized="0" + inkscape:rounded="0" + inkscape:flatsided="true" + sodipodi:arg2="1.0471976" + sodipodi:arg1="0" + sodipodi:r2="2.5" + sodipodi:r1="5" + sodipodi:cy="2" + sodipodi:cx="2" + sodipodi:sides="3" + id="path3802" + style="fill:#888a85;fill-opacity:1;stroke:#555753;stroke-width:0.98094367999999998;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + sodipodi:type="star" /> + <path + sodipodi:type="star" + style="fill:#888a85;fill-opacity:1;stroke:#555753;stroke-width:0.98094367999999998;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + id="path4312" + sodipodi:sides="3" + sodipodi:cx="2" + sodipodi:cy="2" + sodipodi:r1="5" + sodipodi:r2="2.5" + sodipodi:arg1="0" + sodipodi:arg2="1.0471976" + inkscape:flatsided="true" + inkscape:rounded="0" + inkscape:randomized="0" + d="m 7,2 -7.5,4.330127 0,-8.660254 z" + transform="matrix(1,0,0,1.0392305,3,1044.2837)" + inkscape:transform-center-x="-1.25" + inkscape:transform-center-y="-3.9e-05" /> + <path + sodipodi:type="star" + style="fill:url(#linearGradient4330);fill-opacity:1;stroke:#555753;stroke-width:0.98094367999999998;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + id="path3760" + sodipodi:sides="3" + sodipodi:cx="2" + sodipodi:cy="2" + sodipodi:r1="5" + sodipodi:r2="2.5" + sodipodi:arg1="0" + sodipodi:arg2="1.0471976" + inkscape:flatsided="true" + inkscape:rounded="0" + inkscape:randomized="0" + d="m 7,2 -7.5,4.330127 0,-8.660254 z" + transform="matrix(1,0,0,1.0392305,3,1044.2837)" + inkscape:transform-center-x="-1.25" + inkscape:transform-center-y="-3.9e-05" /> + <path + inkscape:transform-center-y="-3.9e-05" + inkscape:transform-center-x="-1.25" + transform="matrix(1,0,0,1.0392305,3,1044.2837)" + d="m 7,2 -7.5,4.330127 0,-8.660254 z" + inkscape:randomized="0" + inkscape:rounded="0" + inkscape:flatsided="true" + sodipodi:arg2="1.0471976" + sodipodi:arg1="0" + sodipodi:r2="2.5" + sodipodi:r1="5" + sodipodi:cy="2" + sodipodi:cx="2" + sodipodi:sides="3" + id="path4314" + style="fill:url(#linearGradient4322);fill-opacity:1;stroke:#555753;stroke-width:0.98094367999999998;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + sodipodi:type="star" /> + </g> +</svg> diff --git a/image/toolbar/12x12/media-playback-start@2x.png b/image/toolbar/12x12/media-playback-start@2x.png Binary files differnew file mode 100644 index 0000000000..7bdf1bdeca --- /dev/null +++ b/image/toolbar/12x12/media-playback-start@2x.png diff --git a/image/toolbar/svg-to-png.sh b/image/toolbar/svg-to-png.sh index 739eea2e42..6796aad8d7 100755 --- a/image/toolbar/svg-to-png.sh +++ b/image/toolbar/svg-to-png.sh @@ -43,10 +43,6 @@ set_source_svgs() { if [ ! -f ${TWO_X_SVG} ] ; then TWO_X_SVG=$ONE_X_SVG fi - if [ ! -f ${ONE_X_SVG} ] ; then - >&2 echo "Can't find ${ONE_X_SVG}" - exit 1 - fi } ICONS=" @@ -56,6 +52,7 @@ ICONS=" go-last go-next go-previous + media-playback-start x-capture-file-close x-capture-file-save x-capture-file-reload @@ -75,7 +72,7 @@ ICONS=" QRC_FILES="" # XXX Add support for 16 pixel icons. -for SIZE in 16 24 ; do +for SIZE in 12 16 24 ; do SIZE_DIR=${SIZE}x${SIZE} TWO_X_SIZE=`expr $SIZE \* 2` @@ -87,6 +84,11 @@ for SIZE in 16 24 ; do for ICON in $ICONS ; do set_source_svgs $ICON + if [ ! -f ${ONE_X_SVG} ] ; then + >&2 echo "Skipping ${ONE_X_SVG}" + continue + fi + ONE_X_PNG=${ICON}.png TWO_X_PNG=${ICON}@2x.png @@ -100,15 +102,15 @@ for SIZE in 16 24 ; do --file=$TWO_X_SVG --export-png=$TWO_X_PNG || exit 1 fi - QRC_FILES="${QRC_FILES} ${ONE_X_PNG} ${TWO_X_PNG}" + QRC_FILES="${QRC_FILES} ${SIZE_DIR}/${ONE_X_PNG} ${SIZE_DIR}/${TWO_X_PNG}" done cd .. - + done for QRC_FILE in $QRC_FILES ; do - echo " <file>toolbar/${SIZE_DIR}/${QRC_FILE}</file>" + echo " <file>toolbar/${QRC_FILE}</file>" done # diff --git a/ui/gtk/voip_calls_dlg.c b/ui/gtk/voip_calls_dlg.c index 7042f25fa3..79b2fb3a41 100644 --- a/ui/gtk/voip_calls_dlg.c +++ b/ui/gtk/voip_calls_dlg.c @@ -41,7 +41,6 @@ #include <epan/epan.h> #include <epan/packet.h> #include "wsutil/filesystem.h" -#include <epan/tap.h> #include <epan/stat_tap_ui.h> #include <epan/to_str.h> #include <epan/address.h> @@ -125,7 +124,8 @@ voip_calls_get_info(void) { /* the one and only global voip_calls_tapinfo_t structure */ static voip_calls_tapinfo_t the_tapinfo_struct = - {voip_calls_dlg_reset, voip_calls_dlg_packet, voip_calls_dlg_draw, + { + voip_calls_dlg_reset, voip_calls_dlg_packet, voip_calls_dlg_draw, NULL, 0, NULL, {0}, 0, NULL, 0, 0, 0, NULL, NULL, 0, NULL, /* rtp */ 0, 0, FALSE, /* rtp evt */ @@ -332,22 +332,6 @@ voip_calls_on_select_all(GtkButton *button _U_, gpointer user_data _U_) gtk_tree_selection_select_all(selection); } -/* compare two list entries by packet no */ -static gint -graph_analysis_sort_compare(gconstpointer a, gconstpointer b, gpointer user_data _U_) -{ - const seq_analysis_item_t *entry_a = (const seq_analysis_item_t *)a; - const seq_analysis_item_t *entry_b = (const seq_analysis_item_t *)b; - - if(entry_a->fd->num < entry_b->fd->num) - return -1; - - if(entry_a->fd->num > entry_b->fd->num) - return 1; - - return 0; -} - /****************************************************************************/ static void on_graph_bt_clicked(GtkButton *button _U_, gpointer user_data _U_) @@ -361,7 +345,7 @@ on_graph_bt_clicked(GtkButton *button _U_, gpointer user_data _U_) if(!tapinfo->graph_analysis){ return; } - g_queue_sort(tapinfo->graph_analysis->items, graph_analysis_sort_compare, NULL); + sequence_analysis_list_sort(tapinfo->graph_analysis); /* reset the "display" parameter in graph analysis */ listb = g_queue_peek_nth_link(tapinfo->graph_analysis->items, 0); diff --git a/ui/help_url.c b/ui/help_url.c index 1638036c18..a1fa295b20 100644 --- a/ui/help_url.c +++ b/ui/help_url.c @@ -333,6 +333,9 @@ topic_action_url(topic_action_e action) case(HELP_FILTER_SAVE_DIALOG): url = user_guide_url("ChWorkFilterSaveSection.html"); break; + case(HELP_TELEPHONY_VOIP_CALLS_DIALOG): + url = user_guide_url("ChTelVoipCalls.html"); + break; case(TOPIC_ACTION_NONE): default: diff --git a/ui/help_url.h b/ui/help_url.h index ecaa0b4ee3..7662910a4d 100644 --- a/ui/help_url.h +++ b/ui/help_url.h @@ -109,7 +109,8 @@ typedef enum { HELP_MERGE_WIN32_DIALOG, HELP_SAVE_WIN32_DIALOG, HELP_TIME_SHIFT_DIALOG, - HELP_FILTER_SAVE_DIALOG + HELP_FILTER_SAVE_DIALOG, + HELP_TELEPHONY_VOIP_CALLS_DIALOG } topic_action_e; /** Given a filename return a filesystem URL. Relative paths are prefixed with diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index dcd553c261..32ad0cf112 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -97,6 +97,7 @@ set(WIRESHARK_QT_HEADERS time_shift_dialog.h traffic_table_dialog.h uat_dialog.h + voip_calls_dialog.h wireshark_application.h ) @@ -194,6 +195,7 @@ set(WIRESHARK_QT_SRC time_shift_dialog.cpp traffic_table_dialog.cpp uat_dialog.cpp + voip_calls_dialog.cpp wireshark_application.cpp ) @@ -267,6 +269,7 @@ set(WIRESHARK_QT_UI time_shift_dialog.ui traffic_table_dialog.ui uat_dialog.ui + voip_calls_dialog.ui ) if(HAVE_PCAP_REMOTE) diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index c8d7b447bb..a99b9287bc 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -214,6 +214,8 @@ traffic_table_dialog.cpp traffic_table_dialog.h: ui_traffic_table_dialog.h uat_dialog.cpp uat_dialog.h: ui_uat_dialog.h +voip_calls_dialog.cpp voip_calls_dialog.h: ui_voip_calls_dialog.h + doxygen: if HAVE_DOXYGEN $(DOXYGEN) doxygen.cfg diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common index 251a8f62cf..e7b0d247cb 100644 --- a/ui/qt/Makefile.common +++ b/ui/qt/Makefile.common @@ -75,7 +75,8 @@ NODIST_GENERATED_HEADER_FILES = \ ui_tcp_stream_dialog.h \ ui_time_shift_dialog.h \ ui_traffic_table_dialog.h \ - ui_uat_dialog.h + ui_uat_dialog.h \ + ui_voip_calls_dialog.h # Generated C source files that we want in the distribution. GENERATED_C_FILES = \ @@ -190,6 +191,7 @@ MOC_HDRS = \ time_shift_dialog.h \ traffic_table_dialog.h \ uat_dialog.h \ + voip_calls_dialog.h \ wireshark_application.h @@ -243,7 +245,8 @@ UI_FILES = \ tcp_stream_dialog.ui \ time_shift_dialog.ui \ traffic_table_dialog.ui \ - uat_dialog.ui + uat_dialog.ui \ + voip_calls_dialog.ui # # The .moc.cpp files generated from them. @@ -386,6 +389,7 @@ WIRESHARK_QT_SRC = \ time_shift_dialog.cpp \ traffic_table_dialog.cpp \ uat_dialog.cpp \ + voip_calls_dialog.cpp \ wireshark_application.cpp WIRESHARK_QT_TAP_SRC = \ diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro index 5d42d5b358..34e2db4a42 100644 --- a/ui/qt/Wireshark.pro +++ b/ui/qt/Wireshark.pro @@ -26,7 +26,7 @@ isEqual(QT_MAJOR_VERSION, 4) { QT += core gui } else { - QT += core widgets printsupport + QT += core widgets printsupport multimediawidgets } isEqual(QT_MAJOR_VERSION, 5): greaterThan(QT_MINOR_VERSION, 1): win32 { @@ -252,7 +252,8 @@ FORMS += \ tcp_stream_dialog.ui \ time_shift_dialog.ui \ traffic_table_dialog.ui \ - uat_dialog.ui + uat_dialog.ui \ + voip_calls_dialog.ui HEADERS += $$HEADERS_WS_C \ @@ -302,7 +303,8 @@ HEADERS += $$HEADERS_WS_C \ tango_colors.h \ tcp_stream_dialog.h \ traffic_table_dialog.h \ - uat_dialog.h + uat_dialog.h \ + voip_calls_dialog.h win32 { OBJECTS_WS_C = $$SOURCES_WS_C @@ -423,7 +425,7 @@ win32 { EXTRA_DLLS = QtCored4 QtGuid4 } else: lessThan(QT_MINOR_VERSION, 3) { # The QT lib parts are copied by windeployqt post 5.3 - EXTRA_DLLS = Qt5Cored Qt5Guid Qt5Widgetsd Qt5PrintSupportd + EXTRA_DLLS = Qt5Cored Qt5Guid Qt5Widgetsd Qt5PrintSupportd Qt5MultimediaWidgetsd EXTRA_PLATFORM_DLLS = qwindowsd QMAKE_POST_LINK +=$$quote($(CHK_DIR_EXISTS) $${PLATFORM_DLL_DIR} $(MKDIR) $${PLATFORM_DLL_DIR}$$escape_expand(\\n\\t)) } @@ -433,7 +435,7 @@ win32 { EXTRA_DLLS = QtCore4 QtGui4 } else: lessThan(QT_MINOR_VERSION, 3) { # The QT lib parts are copied by windeployqt post 5.3 - EXTRA_DLLS = Qt5Core Qt5Gui Qt5Widgets Qt5PrintSupport + EXTRA_DLLS = Qt5Core Qt5Gui Qt5Widgets Qt5PrintSupport Qt5MultimediaWidgets EXTRA_PLATFORM_DLLS = qwindows QMAKE_POST_LINK +=$$quote($(CHK_DIR_EXISTS) $${PLATFORM_DLL_DIR} $(MKDIR) $${PLATFORM_DLL_DIR}$$escape_expand(\\n\\t)) } @@ -667,4 +669,5 @@ SOURCES += \ time_shift_dialog.cpp \ traffic_table_dialog.cpp \ uat_dialog.cpp \ + voip_calls_dialog.cpp \ wireshark_application.cpp diff --git a/ui/qt/follow_stream_dialog.cpp b/ui/qt/follow_stream_dialog.cpp index ea80c8980c..3d5d2bd24e 100644 --- a/ui/qt/follow_stream_dialog.cpp +++ b/ui/qt/follow_stream_dialog.cpp @@ -607,7 +607,6 @@ void FollowStreamDialog::setCaptureFile(capture_file *cf) // / (slash), Ctrl-F - Focus and highlight the search box // Ctrl-G, Ctrl-N, F3 - Find next // Should we make it so that typing any text starts searching? -#include <QDebug> bool FollowStreamDialog::eventFilter(QObject *obj, QEvent *event) { Q_UNUSED(obj); diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index 6bf613d97b..6472e357c4 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -409,10 +409,13 @@ private slots: void on_actionStatisticsIOGraph_triggered(); void on_actionStatisticsSametime_triggered(); + void openVoipCallsDialog(bool all_flows = false); + void on_actionTelephonyVoipCalls_triggered(); void on_actionTelephonyISUPMessages_triggered(); void on_actionTelephonyRTSPPacketCounter_triggered(); void on_actionTelephonySMPPOperations_triggered(); void on_actionTelephonyUCPMessages_triggered(); + void on_actionTelephonySipFlows_triggered(); void changeEvent(QEvent* event); }; diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index fd13b206d5..cbf8922405 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -435,10 +435,12 @@ </property> <addaction name="actionTelephonyRTSPPacketCounter"/> </widget> + <addaction name="actionTelephonyVoipCalls"/> <addaction name="actionTelephonyISUPMessages"/> <addaction name="menuRTSP"/> <addaction name="actionTelephonySMPPOperations"/> <addaction name="actionTelephonyUCPMessages"/> + <addaction name="actionTelephonySipFlows"/> </widget> <widget class="QMenu" name="menuEdit"> <property name="title"> @@ -2136,6 +2138,22 @@ <string>Bytes</string> </property> </action> + <action name="actionTelephonyVoipCalls"> + <property name="text"> + <string>&VoIP Calls</string> + </property> + <property name="toolTip"> + <string>All VoIP Calls</string> + </property> + </action> + <action name="actionTelephonySipFlows"> + <property name="text"> + <string>SIP &Flows</string> + </property> + <property name="toolTip"> + <string>SIP Flows</string> + </property> + </action> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp index 82fadbe799..056fc0cbf5 100644 --- a/ui/qt/main_window_slots.cpp +++ b/ui/qt/main_window_slots.cpp @@ -96,6 +96,7 @@ #include "stats_tree_dialog.h" #include "tcp_stream_dialog.h" #include "time_shift_dialog.h" +#include "voip_calls_dialog.h" #include "wireshark_application.h" #include <QClipboard> @@ -2342,6 +2343,23 @@ void MainWindow::on_actionStatisticsSametime_triggered() // Telephony Menu +void MainWindow::openVoipCallsDialog(bool all_flows) +{ + VoipCallsDialog *voip_calls_dialog = new VoipCallsDialog(this, cap_file_, all_flows); + connect(voip_calls_dialog, SIGNAL(goToPacket(int)), + packet_list_, SLOT(goToPacket(int))); + connect(voip_calls_dialog, SIGNAL(updateFilter(QString&, bool)), + this, SLOT(filterPackets(QString&, bool))); + connect(this, SIGNAL(setCaptureFile(capture_file*)), + voip_calls_dialog, SLOT(setCaptureFile(capture_file*))); + voip_calls_dialog->show(); +} + +void MainWindow::on_actionTelephonyVoipCalls_triggered() +{ + openVoipCallsDialog(); +} + void MainWindow::on_actionTelephonyISUPMessages_triggered() { openStatisticsTreeDialog("isup_msg"); @@ -2362,6 +2380,11 @@ void MainWindow::on_actionTelephonyUCPMessages_triggered() openStatisticsTreeDialog("ucp_messages"); } +void MainWindow::on_actionTelephonySipFlows_triggered() +{ + openVoipCallsDialog(true); +} + // Help Menu void MainWindow::on_actionHelpContents_triggered() { diff --git a/ui/qt/sequence_diagram.cpp b/ui/qt/sequence_diagram.cpp index 8660c4295c..3bd4c2d724 100644 --- a/ui/qt/sequence_diagram.cpp +++ b/ui/qt/sequence_diagram.cpp @@ -31,8 +31,6 @@ #include <QPen> #include <QPointF> -#include <QDebug> - const int max_comment_em_width_ = 20; // UML-like network node sequence diagrams. @@ -98,8 +96,9 @@ SequenceDiagram::SequenceDiagram(QCPAxis *keyAxis, QCPAxis *valueAxis, QCPAxis * void SequenceDiagram::setData(seq_analysis_info_t *sainfo) { data_->clear(); + sainfo_ = sainfo; + if (!sainfo) return; - WSCPSeqData new_data; double cur_key = 0.0; QVector<double> key_ticks, val_ticks; QVector<QString> key_labels, val_labels, com_labels; @@ -108,6 +107,7 @@ void SequenceDiagram::setData(seq_analysis_info_t *sainfo) for (GList *cur = g_queue_peek_nth_link(sainfo->items, 0); cur; cur = g_list_next(cur)) { seq_analysis_item_t *sai = (seq_analysis_item_t *) cur->data; + WSCPSeqData new_data; new_data.key = cur_key; new_data.value = sai; @@ -120,7 +120,6 @@ void SequenceDiagram::setData(seq_analysis_info_t *sainfo) cur_key++; } - sainfo_ = sainfo; for (unsigned int i = 0; i < sainfo_->num_nodes; i++) { val_ticks.append(i); @@ -193,7 +192,7 @@ void SequenceDiagram::draw(QCPPainter *painter) WSCPSeqDataMap::const_iterator it; for (it = data_->constBegin(); it != data_->constEnd(); ++it) { double cur_key = it.key(); - seq_analysis_item_t *sai = (seq_analysis_item_t *) it.value().value; + seq_analysis_item_t *sai = it.value().value; QPen fg_pen(mainPen()); if (sai->fd->num == selected_packet_) { diff --git a/ui/qt/sequence_diagram.h b/ui/qt/sequence_diagram.h index 952570e27e..facc33bf42 100644 --- a/ui/qt/sequence_diagram.h +++ b/ui/qt/sequence_diagram.h @@ -64,7 +64,7 @@ public: seq_analysis_item_t *itemForPosY(int ypos); // reimplemented virtual methods: - virtual void clearData() {} + virtual void clearData() { data_->clear(); } virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; public slots: diff --git a/ui/qt/sequence_dialog.cpp b/ui/qt/sequence_dialog.cpp index 68eb6013f0..1d8f75fca6 100644 --- a/ui/qt/sequence_dialog.cpp +++ b/ui/qt/sequence_dialog.cpp @@ -26,6 +26,7 @@ #include "wsutil/nstime.h" +#include "sequence_diagram.h" #include "wireshark_application.h" #include <QDir> @@ -33,8 +34,6 @@ #include <QFontMetrics> #include <QPoint> -#include <QDebug> - // To do: // - Add UTF8 to text dump // - Save to XMI? http://www.umlgraph.org/ @@ -46,10 +45,11 @@ // - Create WSGraph subclasses with common behavior. // - Help button and text -SequenceDialog::SequenceDialog(QWidget *parent, capture_file *cf, SequenceType type) : +SequenceDialog::SequenceDialog(QWidget *parent, capture_file *cf, seq_analysis_info_t *sainfo) : QDialog(parent), ui(new Ui::SequenceDialog), cap_file_(cf), + sainfo_(sainfo), num_items_(0), packet_num_(0), node_label_w_(20) @@ -57,6 +57,14 @@ SequenceDialog::SequenceDialog(QWidget *parent, capture_file *cf, SequenceType t ui->setupUi(this); QCustomPlot *sp = ui->sequencePlot; + if (!sainfo_) { + sainfo_ = sequence_analysis_info_new(); + sainfo_->type = SEQ_ANALYSIS_ANY; + sainfo_->all_packets = TRUE; + } else { + num_items_ = sequence_analysis_get_nodes(sainfo_); + } + seq_diagram_ = new SequenceDiagram(sp->yAxis, sp->xAxis2, sp->yAxis2); sp->addPlottable(seq_diagram_); sp->axisRect()->setRangeDragAxes(sp->xAxis2, sp->yAxis); @@ -90,8 +98,6 @@ SequenceDialog::SequenceDialog(QWidget *parent, capture_file *cf, SequenceType t ctx_menu_.addSeparator(); ctx_menu_.addAction(ui->actionGoToPacket); - memset (&seq_analysis_, 0, sizeof(seq_analysis_)); - ui->showComboBox->blockSignals(true); ui->showComboBox->setCurrentIndex(0); ui->showComboBox->blockSignals(false); @@ -104,23 +110,13 @@ SequenceDialog::SequenceDialog(QWidget *parent, capture_file *cf, SequenceType t fcb->addItem(ui->actionFlowTcp->text(), SEQ_ANALYSIS_TCP); ui->flowComboBox->blockSignals(true); - switch (type) { - case any: - seq_analysis_.type = SEQ_ANALYSIS_ANY; - ui->flowComboBox->setCurrentIndex(SEQ_ANALYSIS_ANY); - break; - case tcp: - seq_analysis_.type = SEQ_ANALYSIS_TCP; - ui->flowComboBox->setCurrentIndex(SEQ_ANALYSIS_TCP); - break; - case voip: - seq_analysis_.type = SEQ_ANALYSIS_VOIP; - ui->flowComboBox->hide(); - ui->flowLabel->hide(); - break; + ui->flowComboBox->setCurrentIndex(sainfo_->type); + + if (sainfo_->type == SEQ_ANALYSIS_VOIP) { + ui->controlFrame->hide(); + } else { + ui->flowComboBox->blockSignals(false); } - ui->flowComboBox->blockSignals(false); - seq_analysis_.all_packets = TRUE; QPushButton *save_bt = ui->buttonBox->button(QDialogButtonBox::Save); save_bt->setText(tr("Save As...")); @@ -146,6 +142,9 @@ SequenceDialog::SequenceDialog(QWidget *parent, capture_file *cf, SequenceType t SequenceDialog::~SequenceDialog() { + if (sainfo_->type != SEQ_ANALYSIS_VOIP) { + sequence_analysis_info_free(sainfo_); + } delete ui; } @@ -279,8 +278,12 @@ void SequenceDialog::mouseMoved(QMouseEvent *event) } if (hint.isEmpty()) { - hint += tr("%Ln node(s)", "", seq_analysis_.num_nodes) + QString(", ") - + tr("%Ln item(s)", "", num_items_); + if (!sainfo_) { + hint += tr("No data"); + } else { + hint += tr("%Ln node(s)", "", sainfo_->num_nodes) + QString(", ") + + tr("%Ln item(s)", "", num_items_); + } } hint.prepend("<small><i>"); @@ -329,8 +332,8 @@ void SequenceDialog::on_buttonBox_accepted() save_ok = ui->sequencePlot->saveBmp(file_name); } else if (extension.compare(jpeg_filter) == 0) { save_ok = ui->sequencePlot->saveJpg(file_name); - } else if (extension.compare(ascii_filter) == 0 && cap_file_) { - save_ok = sequence_analysis_dump_to_file(file_name.toUtf8().constData(), &seq_analysis_, cap_file_, 0); + } else if (extension.compare(ascii_filter) == 0 && cap_file_ && sainfo_) { + save_ok = sequence_analysis_dump_to_file(file_name.toUtf8().constData(), sainfo_, cap_file_, 0); } // else error dialog? if (save_ok) { @@ -342,23 +345,24 @@ void SequenceDialog::on_buttonBox_accepted() void SequenceDialog::fillDiagram() { + if (!sainfo_) return; + QCustomPlot *sp = ui->sequencePlot; - seq_analysis_info_t new_sa; - - new_sa = seq_analysis_; - new_sa.items = g_queue_new(); - new_sa.ht = NULL; - new_sa.num_nodes = 0; - sequence_analysis_list_get(cap_file_, &new_sa); - num_items_ = sequence_analysis_get_nodes(&new_sa); - seq_diagram_->setData(&new_sa); - sequence_analysis_list_free(&seq_analysis_); - seq_analysis_ = new_sa; + + if (sainfo_->type == SEQ_ANALYSIS_VOIP) { + seq_diagram_->setData(sainfo_); + } else { + seq_diagram_->clearData(); + sequence_analysis_list_free(sainfo_); + sequence_analysis_list_get(cap_file_, sainfo_); + num_items_ = sequence_analysis_get_nodes(sainfo_); + seq_diagram_->setData(sainfo_); + } QFontMetrics vfm = QFontMetrics(sp->xAxis2->labelFont()); node_label_w_ = 0; - for (guint i = 0; i < seq_analysis_.num_nodes; i++) { - int label_w = vfm.width(ep_address_to_display(&(seq_analysis_.nodes[i]))); + for (guint i = 0; i < sainfo_->num_nodes; i++) { + int label_w = vfm.width(ep_address_to_display(&(sainfo_->nodes[i]))); if (node_label_w_ < label_w) { node_label_w_ = label_w; } @@ -393,6 +397,8 @@ void SequenceDialog::panAxes(int x_pixels, int y_pixels) void SequenceDialog::resetAxes(bool keep_lower) { + if (!sainfo_) return; + QCustomPlot *sp = ui->sequencePlot; // Allow space for labels on the top and port numbers on the left. double top_pos = -1.0, left_pos = -0.5; @@ -408,7 +414,7 @@ void SequenceDialog::resetAxes(bool keep_lower) sp->yAxis->setRange(top_pos, range_ratio + top_pos); double rmin = sp->xAxis2->range().size() / 2; - ui->horizontalScrollBar->setRange((rmin - 0.5) * 100, (seq_analysis_.num_nodes - 0.5 - rmin) * 100); + ui->horizontalScrollBar->setRange((rmin - 0.5) * 100, (sainfo_->num_nodes - 0.5 - rmin) * 100); xAxisChanged(sp->xAxis2->range()); rmin = (sp->yAxis->range().size() / 2); @@ -432,27 +438,32 @@ void SequenceDialog::on_actionGoToPacket_triggered() void SequenceDialog::on_showComboBox_currentIndexChanged(int index) { + if (!sainfo_) return; + if (index == 0) { - seq_analysis_.all_packets = TRUE; + sainfo_->all_packets = TRUE; } else { - seq_analysis_.all_packets = FALSE; + sainfo_->all_packets = FALSE; } fillDiagram(); } void SequenceDialog::on_flowComboBox_currentIndexChanged(int index) { - if (index < 0) return; - seq_analysis_.type = static_cast<seq_analysis_type>(ui->flowComboBox->itemData(index).toInt()); + if (!sainfo_ || sainfo_->type == SEQ_ANALYSIS_VOIP || index < 0) return; + + sainfo_->type = static_cast<seq_analysis_type>(ui->flowComboBox->itemData(index).toInt()); fillDiagram(); } void SequenceDialog::on_addressComboBox_currentIndexChanged(int index) { + if (!sainfo_) return; + if (index == 0) { - seq_analysis_.any_addr = TRUE; + sainfo_->any_addr = TRUE; } else { - seq_analysis_.any_addr = FALSE; + sainfo_->any_addr = FALSE; } fillDiagram(); } diff --git a/ui/qt/sequence_dialog.h b/ui/qt/sequence_dialog.h index 5ede431b06..77728ffd10 100644 --- a/ui/qt/sequence_dialog.h +++ b/ui/qt/sequence_dialog.h @@ -30,7 +30,9 @@ #include "epan/packet.h" -#include "sequence_diagram.h" +#include "ui/tap-sequence-analysis.h" + +#include "qcustomplot.h" #include <QDialog> #include <QMenu> @@ -39,14 +41,14 @@ namespace Ui { class SequenceDialog; } +class SequenceDiagram; + class SequenceDialog : public QDialog { Q_OBJECT public: - enum SequenceType { any, tcp, voip }; - - explicit SequenceDialog(QWidget *parent = 0, capture_file *cf = NULL, SequenceType type = any); + explicit SequenceDialog(QWidget *parent = 0, capture_file *cf = NULL, seq_analysis_info_t *sainfo = NULL); ~SequenceDialog(); signals: @@ -90,7 +92,7 @@ private: Ui::SequenceDialog *ui; SequenceDiagram *seq_diagram_; capture_file *cap_file_; - seq_analysis_info_t seq_analysis_; + seq_analysis_info_t *sainfo_; int num_items_; guint32 packet_num_; double one_em_; diff --git a/ui/qt/sequence_dialog.ui b/ui/qt/sequence_dialog.ui index 26067d9960..93a44eb140 100644 --- a/ui/qt/sequence_dialog.ui +++ b/ui/qt/sequence_dialog.ui @@ -13,7 +13,7 @@ <property name="windowTitle"> <string>Flow</string> </property> - <layout class="QVBoxLayout" name="verticalLayout"> + <layout class="QVBoxLayout" name="verticalLayout_2" stretch="1,0,0,0"> <item> <layout class="QGridLayout" name="gridLayout"> <item row="0" column="0"> @@ -75,123 +75,137 @@ </widget> </item> <item> - <layout class="QHBoxLayout" name="controlHorizontalLayout" stretch="0,0,0,0,0,0,0,0,1"> - <item> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Show:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="showComboBox"> - <item> - <property name="text"> - <string>All packets</string> - </property> - </item> - <item> - <property name="text"> - <string>Displayed packets</string> - </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>13</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="flowLabel"> - <property name="text"> - <string>Flow type:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="flowComboBox"/> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>13</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Addresses:</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="addressComboBox"> - <item> - <property name="text"> - <string>Any</string> - </property> - </item> - <item> - <property name="text"> - <string>Network</string> - </property> - </item> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_4"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <spacer name="horizontalSpacer_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="resetButton"> - <property name="text"> - <string>Reset</string> - </property> - </widget> - </item> - </layout> + <widget class="QFrame" name="controlFrame"> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <property name="lineWidth"> + <number>0</number> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Show:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="showComboBox"> + <item> + <property name="text"> + <string>All packets</string> + </property> + </item> + <item> + <property name="text"> + <string>Displayed packets</string> + </property> + </item> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>13</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="flowLabel"> + <property name="text"> + <string>Flow type:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="flowComboBox"/> + </item> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>13</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Addresses:</string> + </property> + </widget> + </item> + <item> + <widget class="QComboBox" name="addressComboBox"> + <item> + <property name="text"> + <string>Any</string> + </property> + </item> + <item> + <property name="text"> + <string>Network</string> + </property> + </item> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="resetButton"> + <property name="text"> + <string>Reset</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> </item> <item> <widget class="QDialogButtonBox" name="buttonBox"> @@ -345,6 +359,7 @@ <container>1</container> </customwidget> </customwidgets> + <resources/> <connections> <connection> <sender>buttonBox</sender> diff --git a/ui/qt/stock_icon.cpp b/ui/qt/stock_icon.cpp index 03c50e0325..86e953e3dd 100644 --- a/ui/qt/stock_icon.cpp +++ b/ui/qt/stock_icon.cpp @@ -75,15 +75,16 @@ StockIcon::StockIcon(const char *icon_name) : #endif return; } else { - QStringList types = QStringList() << "16x16" << "24x24"; + QStringList types = QStringList() << "12x12" << "16x16" << "24x24"; foreach (QString type, types) { - // Along with each name check for "<name>.on" to use for the on (checked) state. - // XXX Add checks for each combination of QIcon::Mode + QIcon::State QString icon_path = path_pfx_ + QString("%1/%2.png").arg(type).arg(icon_name); - QString icon_path_on = path_pfx_ + QString("%1/%2.on.png").arg(type).arg(icon_name); if (QFile::exists(icon_path)) { addFile(icon_path); } + + // Along with each name check for "<name>.on" to use for the on (checked) state. + // XXX Add checks for each combination of QIcon::Mode + QIcon::State + QString icon_path_on = path_pfx_ + QString("%1/%2.on.png").arg(type).arg(icon_name); if (QFile::exists(icon_path_on)) { addFile(icon_path_on, QSize(), QIcon::Normal, QIcon::On); } diff --git a/ui/qt/voip_calls_dialog.cpp b/ui/qt/voip_calls_dialog.cpp new file mode 100644 index 0000000000..aee0e08121 --- /dev/null +++ b/ui/qt/voip_calls_dialog.cpp @@ -0,0 +1,508 @@ +/* voip_calls_dialog.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "voip_calls_dialog.h" +#include "ui_voip_calls_dialog.h" + +#include "file.h" + +#include "epan/addr_resolv.h" +#include "epan/dissectors/packet-h225.h" + +#include "ui/utf8_entities.h" + +#include "sequence_dialog.h" +#include "stock_icon.h" +#include "wireshark_application.h" + +#include <QContextMenuEvent> +#include <QPushButton> + +// To do: +// - More context menu items +// - Don't select on right click +// - Player +// - Add a screenshot to the user's guide + +// Bugs: +// - Preparing a filter overwrites the existing filter. The GTK+ UI appends. +// We'll probably have to add an "append" parameter to MainWindow::filterPackets. + +// VoipCallsTreeWidgetItem +// QTreeWidgetItem subclass that allows sorting + +const int start_time_col_ = 0; +const int stop_time_col_ = 1; +const int initial_speaker_col_ = 2; +const int from_col_ = 3; +const int to_col_ = 4; +const int protocol_col_ = 5; +const int packets_col_ = 6; +const int state_col_ = 7; +const int comments_col_ = 8; + +Q_DECLARE_METATYPE(voip_calls_info_t*) + +class VoipCallsTreeWidgetItem : public QTreeWidgetItem +{ +public: + VoipCallsTreeWidgetItem(QTreeWidget *tree, voip_calls_info_t *call_info) : QTreeWidgetItem(tree) { + setData(0, Qt::UserRole, qVariantFromValue(call_info)); + drawData(); + } + + void drawData() { + voip_calls_info_t *call_info = data(0, Qt::UserRole).value<voip_calls_info_t*>(); + if (!call_info) { + return; + } + + // XXX Pull digit count from capture file precision + setText(start_time_col_, QString::number(nstime_to_sec(&(call_info->start_rel_ts)), 'f', 6)); + setText(stop_time_col_, QString::number(nstime_to_sec(&(call_info->stop_rel_ts)), 'f', 6)); + setText(initial_speaker_col_, ep_address_to_display(&(call_info->initial_speaker))); + setText(from_col_, call_info->from_identity); + setText(to_col_, call_info->to_identity); + setText(protocol_col_, ((call_info->protocol == VOIP_COMMON) && call_info->protocol_name) ? + call_info->protocol_name : voip_protocol_name[call_info->protocol]); + setText(packets_col_, QString::number(call_info->npackets)); + setText(state_col_, voip_call_state_name[call_info->call_state]); + + /* Add comments based on the protocol */ + QString call_comments; + switch (call_info->protocol) { + case VOIP_ISUP: + { + isup_calls_info_t *isup_info = (isup_calls_info_t *)call_info->prot_info; + call_comments = QString("%1-%2 %3 %4-%5") + .arg(isup_info->ni) + .arg(isup_info->opc) + .arg(UTF8_RIGHTWARDS_ARROW) + .arg(isup_info->ni) + .arg(isup_info->dpc); + } + break; + case VOIP_H323: + { + h323_calls_info_t *h323_info = (h323_calls_info_t *)call_info->prot_info; + gboolean flag = FALSE; + static const QString on_str = QObject::tr("On"); + static const QString off_str = QObject::tr("Off"); + if (call_info->call_state == VOIP_CALL_SETUP) { + flag = h323_info->is_faststart_Setup; + } else { + if ((h323_info->is_faststart_Setup) && (h323_info->is_faststart_Proc)) { + flag = TRUE; + } + } + call_comments = QObject::tr("Tunneling: %1 Fast Start: %2") + .arg(h323_info->is_h245Tunneling ? on_str : off_str) + .arg(flag ? on_str : off_str); + } + break; + case VOIP_COMMON: + default: + call_comments = call_info->call_comment; + break; + } + setText(comments_col_, call_comments); + } + + bool operator< (const QTreeWidgetItem &other) const + { + voip_calls_info_t *this_call_info = data(0, Qt::UserRole).value<voip_calls_info_t*>(); + voip_calls_info_t *other_call_info = other.data(0, Qt::UserRole).value<voip_calls_info_t*>(); + if (!this_call_info || !other_call_info) { + return false; + } + + switch (treeWidget()->sortColumn()) { + case start_time_col_: + return nstime_cmp(&(this_call_info->start_rel_ts), &(other_call_info->start_rel_ts)) < 0; + break; + case stop_time_col_: + return nstime_cmp(&(this_call_info->stop_rel_ts), &(other_call_info->stop_rel_ts)) < 0; + break; + case initial_speaker_col_: + return cmp_address(&(this_call_info->initial_speaker), &(other_call_info->initial_speaker)) < 0; + break; + case packets_col_: + return this_call_info->npackets < other_call_info->npackets; + break; + default: + break; + } + + // Fall back to string comparison + return QTreeWidgetItem::operator <(other); + } + +}; + +VoipCallsDialog::VoipCallsDialog(QWidget *parent, capture_file *cf, bool all_flows) : + QDialog(parent), + ui(new Ui::VoipCallsDialog), + cap_file_(cf) +{ + ui->setupUi(this); + ui->callTreeWidget->sortByColumn(start_time_col_, Qt::AscendingOrder); + + ctx_menu_.addActions(QList<QAction *>() << ui->actionSelect_All); + + prepare_button_ = ui->buttonBox->addButton(tr("Prepare Filter"), QDialogButtonBox::ApplyRole); + sequence_button_ = ui->buttonBox->addButton(tr("Flow Sequence"), QDialogButtonBox::ApplyRole); + player_button_ = ui->buttonBox->addButton(tr("Play Call"), QDialogButtonBox::ApplyRole); + player_button_->setIcon(StockIcon("media-playback-start")); + + // XXX Use recent settings instead + if (parent) { + resize(parent->width() * 4 / 5, parent->height() * 2 / 3); + } + + memset (&tapinfo_, 0, sizeof(tapinfo_)); + tapinfo_.tap_packet = tapPacket; + tapinfo_.tap_draw = tapDraw; + tapinfo_.tap_data = this; + tapinfo_.callsinfos = g_queue_new(); + tapinfo_.h225_cstype = H225_OTHER; + tapinfo_.fs_option = all_flows ? FLOW_ALL : FLOW_ONLY_INVITES; /* flow show option */ + tapinfo_.graph_analysis = sequence_analysis_info_new(); + tapinfo_.graph_analysis->type = SEQ_ANALYSIS_VOIP; + + voip_calls_init_all_taps(&tapinfo_); + + updateWidgets(); + + if (cap_file_) { + tapinfo_.session = cap_file_->epan; + cf_retap_packets(cap_file_); + } +} + +VoipCallsDialog::~VoipCallsDialog() +{ + delete ui; + + voip_calls_remove_all_tap_listeners(&tapinfo_); + sequence_analysis_info_free(tapinfo_.graph_analysis); +} + +void VoipCallsDialog::setCaptureFile(capture_file *cf) +{ + if (!cf) { // We only want to know when the file closes. + voip_calls_remove_all_tap_listeners(&tapinfo_); + cap_file_ = NULL; + tapinfo_.session = NULL; + } + emit captureFileChanged(cap_file_); + updateWidgets(); +} + +void VoipCallsDialog::contextMenuEvent(QContextMenuEvent *event) +{ + ctx_menu_.exec(event->globalPos()); +} + +void VoipCallsDialog::changeEvent(QEvent *event) +{ + if (0 != event) + { + switch (event->type()) + { + case QEvent::LanguageChange: + ui->retranslateUi(this); + break; + default: + break; + } + } + QDialog::changeEvent(event); +} + +//void VoipCallsDialog::tapReset(void *tapinfo_ptr) +//{ +// Q_UNUSED(tapinfo_ptr) +// voip_calls_tapinfo_t *tapinfo = (voip_calls_tapinfo_t *) tapinfo_ptr; +//} + +gboolean VoipCallsDialog::tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data) +{ + Q_UNUSED(tapinfo_ptr) + Q_UNUSED(pinfo) + Q_UNUSED(data) +#ifdef QT_MULTIMEDIAWIDGETS_LIB +// voip_calls_tapinfo_t *tapinfo = (voip_calls_tapinfo_t *) tapinfo_ptr; + // add_rtp_packet for voip player. +// return TRUE; +#endif + return FALSE; +} + +void VoipCallsDialog::tapDraw(void *tapinfo_ptr) +{ + voip_calls_tapinfo_t *tapinfo = (voip_calls_tapinfo_t *) tapinfo_ptr; + + if (!tapinfo || !tapinfo->redraw) { + return; + } + + VoipCallsDialog *voip_calls_dialog = static_cast<VoipCallsDialog *>(tapinfo->tap_data); + if (voip_calls_dialog) { + voip_calls_dialog->updateCalls(); + } +} + +void VoipCallsDialog::updateCalls() +{ + GList *cur_call = g_queue_peek_nth_link(tapinfo_.callsinfos, ui->callTreeWidget->topLevelItemCount()); + ui->callTreeWidget->setSortingEnabled(false); + + // Add any missing items + while (cur_call && cur_call->data) { + voip_calls_info_t *call_info = (voip_calls_info_t*) cur_call->data; + new VoipCallsTreeWidgetItem(ui->callTreeWidget, call_info); + cur_call = g_list_next(cur_call); + } + + // Fill in the tree + QTreeWidgetItemIterator iter(ui->callTreeWidget); + while (*iter) { + VoipCallsTreeWidgetItem *vcti = static_cast<VoipCallsTreeWidgetItem*>(*iter); + vcti->drawData(); + ++iter; + } + + // Resize columns + for (int i = 0; i < ui->callTreeWidget->columnCount(); i++) { + ui->callTreeWidget->resizeColumnToContents(i); + } + + ui->callTreeWidget->setSortingEnabled(true); + + updateWidgets(); +} + +void VoipCallsDialog::updateWidgets() +{ + bool selected = ui->callTreeWidget->selectedItems().count() > 0 ? true : false; + bool have_ga_items = false; + + if (tapinfo_.graph_analysis && tapinfo_.graph_analysis->items) { + have_ga_items = true; + } + + foreach (QMenu *submenu, ctx_menu_.findChildren<QMenu*>()) { + submenu->setEnabled(selected); + } + prepare_button_->setEnabled(selected && have_ga_items); + sequence_button_->setEnabled(selected && have_ga_items); +#if defined(QT_MULTIMEDIAWIDGETS_LIB) && 0 // We don't have a playback dialog yet. + player_button_->setEnabled(selected && have_ga_items); +#else + player_button_->setEnabled(false); + player_button_->setText(tr("No Audio")); +#endif +} + +void VoipCallsDialog::prepareFilter() +{ + if (ui->callTreeWidget->selectedItems().count() < 1 || !tapinfo_.graph_analysis) { + return; + } + + QString filter_str; + QSet<guint16> selected_calls; + + /* Build a new filter based on frame numbers */ + const char *or_prepend = ""; + foreach (QTreeWidgetItem *ti, ui->callTreeWidget->selectedItems()) { + voip_calls_info_t *call_info = ti->data(0, Qt::UserRole).value<voip_calls_info_t*>(); + selected_calls << call_info->call_num; + } + + GList *cur_ga_item = g_queue_peek_nth_link(tapinfo_.graph_analysis->items, 0); + while (cur_ga_item && cur_ga_item->data) { + seq_analysis_item_t *ga_item = (seq_analysis_item_t*) cur_ga_item->data; + if (selected_calls.contains(ga_item->conv_num)) { + filter_str += QString("%1frame.number == %2").arg(or_prepend).arg(ga_item->fd->num); + or_prepend = " or "; + } + cur_ga_item = g_list_next(cur_ga_item); + } + +#if 0 + // XXX The GTK+ UI falls back to building a filter based on protocols if the filter + // length is too long. Leaving this here for the time being in case we need to do + // the same in the Qt UI. + const sip_calls_info_t *sipinfo; + const isup_calls_info_t *isupinfo; + const h323_calls_info_t *h323info; + const h245_address_t *h245_add = NULL; + const gcp_ctx_t* ctx; + + if (filter_length < max_filter_length) { + gtk_editable_insert_text(GTK_EDITABLE(main_display_filter_widget), filter_string_fwd->str, -1, &pos); + } else { + g_string_free(filter_string_fwd, TRUE); + filter_string_fwd = g_string_new(filter_prepend); + + g_string_append_printf(filter_string_fwd, "("); + is_first = TRUE; + /* Build a new filter based on protocol fields */ + lista = g_queue_peek_nth_link(voip_calls_get_info()->callsinfos, 0); + while (lista) { + listinfo = (voip_calls_info_t *)lista->data; + if (listinfo->selected) { + if (!is_first) + g_string_append_printf(filter_string_fwd, " or "); + switch (listinfo->protocol) { + case VOIP_SIP: + sipinfo = (sip_calls_info_t *)listinfo->prot_info; + g_string_append_printf(filter_string_fwd, + "(sip.Call-ID == \"%s\")", + sipinfo->call_identifier + ); + break; + case VOIP_ISUP: + isupinfo = (isup_calls_info_t *)listinfo->prot_info; + g_string_append_printf(filter_string_fwd, + "(isup.cic == %i and frame.number >= %i and frame.number <= %i and mtp3.network_indicator == %i and ((mtp3.dpc == %i) and (mtp3.opc == %i)) or ((mtp3.dpc == %i) and (mtp3.opc == %i)))", + isupinfo->cic, listinfo->start_fd->num, + listinfo->stop_fd->num, + isupinfo->ni, isupinfo->dpc, isupinfo->opc, + isupinfo->opc, isupinfo->dpc + ); + break; + case VOIP_H323: + h323info = (h323_calls_info_t *)listinfo->prot_info; + g_string_append_printf(filter_string_fwd, + "((h225.guid == %s || q931.call_ref == %x:%x || q931.call_ref == %x:%x)", + guid_to_ep_str(&h323info->guid[0]), + (guint8) (h323info->q931_crv & 0x00ff), + (guint8)((h323info->q931_crv & 0xff00)>>8), + (guint8) (h323info->q931_crv2 & 0x00ff), + (guint8)((h323info->q931_crv2 & 0xff00)>>8)); + listb = g_list_first(h323info->h245_list); + while (listb) { + h245_add = (h245_address_t *)listb->data; + g_string_append_printf(filter_string_fwd, + " || (ip.addr == %s && tcp.port == %d && h245)", + ip_to_str((guint8 *)(h245_add->h245_address.data)), h245_add->h245_port); + listb = g_list_next(listb); + } + g_string_append_printf(filter_string_fwd, ")"); + break; + case TEL_H248: + ctx = (gcp_ctx_t *)listinfo->prot_info; + g_string_append_printf(filter_string_fwd, + "(h248.ctx == 0x%x)", ctx->id); + break; + default: + /* placeholder to assure valid display filter expression */ + g_string_append_printf(filter_string_fwd, + "(frame)"); + break; + } + is_first = FALSE; + } + lista = g_list_next(lista); + } + + g_string_append_printf(filter_string_fwd, ")"); + gtk_editable_insert_text(GTK_EDITABLE(main_display_filter_widget), filter_string_fwd->str, -1, &pos); + } +#endif + + emit updateFilter(filter_str); +} + +void VoipCallsDialog::showSequence() +{ + if (!cap_file_) return; + + QSet<guint16> selected_calls; + foreach (QTreeWidgetItem *ti, ui->callTreeWidget->selectedItems()) { + voip_calls_info_t *call_info = ti->data(0, Qt::UserRole).value<voip_calls_info_t*>(); + selected_calls << call_info->call_num; + } + + sequence_analysis_list_sort(tapinfo_.graph_analysis); + GList *cur_ga_item = g_queue_peek_nth_link(tapinfo_.graph_analysis->items, 0); + while (cur_ga_item && cur_ga_item->data) { + seq_analysis_item_t *ga_item = (seq_analysis_item_t*) cur_ga_item->data; + ga_item->display = selected_calls.contains(ga_item->conv_num); + cur_ga_item = g_list_next(cur_ga_item); + } + + SequenceDialog *sequence_dialog = new SequenceDialog(this, cap_file_, tapinfo_.graph_analysis); + // XXX This goes away when we close the VoIP Calls dialog. + connect(sequence_dialog, SIGNAL(goToPacket(int)), + this, SIGNAL(goToPacket(int))); + connect(this, SIGNAL(captureFileChanged(capture_file*)), + sequence_dialog, SLOT(setCaptureFile(capture_file*))); + sequence_dialog->show(); +} + +void VoipCallsDialog::on_callTreeWidget_itemActivated(QTreeWidgetItem *item, int) +{ + voip_calls_info_t *call_info = item->data(0, Qt::UserRole).value<voip_calls_info_t*>(); + if (!call_info) { + return; + } + emit goToPacket(call_info->start_fd->num); +} + +void VoipCallsDialog::on_callTreeWidget_itemSelectionChanged() +{ + updateWidgets(); +} + +void VoipCallsDialog::on_actionSelect_All_triggered() +{ + ui->callTreeWidget->selectAll(); +} + +void VoipCallsDialog::on_buttonBox_clicked(QAbstractButton *button) +{ + if (button == prepare_button_) { + prepareFilter(); + } else if (button == sequence_button_) { + showSequence(); + } +} + +void VoipCallsDialog::on_buttonBox_helpRequested() +{ + wsApp->helpTopicAction(HELP_TELEPHONY_VOIP_CALLS_DIALOG); +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/voip_calls_dialog.h b/ui/qt/voip_calls_dialog.h new file mode 100644 index 0000000000..16391b683d --- /dev/null +++ b/ui/qt/voip_calls_dialog.h @@ -0,0 +1,107 @@ +/* voip_calls_dialog.h + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef VOIP_CALLS_DIALOG_H +#define VOIP_CALLS_DIALOG_H + +#include "config.h" + +#include <glib.h> + +#include "cfile.h" + +#include "ui/voip_calls.h" + +#include <QDialog> +#include <QMenu> + +class QAbstractButton; +class QTreeWidgetItem; + +namespace Ui { +class VoipCallsDialog; +} + +class QTreeWidgetItem; +class VoipCallsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit VoipCallsDialog(QWidget *parent = 0, capture_file *cf = NULL, bool all_flows = false); + ~VoipCallsDialog(); + +public slots: + void setCaptureFile(capture_file *cf); + +signals: + void updateFilter(QString &filter, bool force = false); + void captureFileChanged(capture_file *cf); + void goToPacket(int packet_num); + +protected: + void contextMenuEvent(QContextMenuEvent *event); + +protected slots: + void changeEvent(QEvent* event); + +private: + Ui::VoipCallsDialog *ui; + + capture_file *cap_file_; + voip_calls_tapinfo_t tapinfo_; + QPushButton *prepare_button_; + QPushButton *sequence_button_; + QPushButton *player_button_; + QMenu ctx_menu_; + + // Tap callbacks +// static void tapReset(void *tapinfo_ptr); + static gboolean tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data); + static void tapDraw(void *tapinfo_ptr); + + void updateCalls(); + void updateWidgets(); + void prepareFilter(); + void showSequence(); + +private slots: + void on_callTreeWidget_itemActivated(QTreeWidgetItem *item, int); + void on_callTreeWidget_itemSelectionChanged(); + void on_actionSelect_All_triggered(); + void on_buttonBox_clicked(QAbstractButton *button); + void on_buttonBox_helpRequested(); +}; + +#endif // VOIP_CALLS_DIALOG_H + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/voip_calls_dialog.ui b/ui/qt/voip_calls_dialog.ui new file mode 100644 index 0000000000..27ec107427 --- /dev/null +++ b/ui/qt/voip_calls_dialog.ui @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>VoipCallsDialog</class> + <widget class="QDialog" name="VoipCallsDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>750</width> + <height>430</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTreeWidget" name="callTreeWidget"> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="textElideMode"> + <enum>Qt::ElideMiddle</enum> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <column> + <property name="text"> + <string>Start Time</string> + </property> + </column> + <column> + <property name="text"> + <string>Stop Time</string> + </property> + </column> + <column> + <property name="text"> + <string>Initial Speaker</string> + </property> + </column> + <column> + <property name="text"> + <string>From</string> + </property> + </column> + <column> + <property name="text"> + <string>To</string> + </property> + </column> + <column> + <property name="text"> + <string>Protocol</string> + </property> + </column> + <column> + <property name="text"> + <string>Packets</string> + </property> + </column> + <column> + <property name="text"> + <string>State</string> + </property> + </column> + <column> + <property name="text"> + <string>Comments</string> + </property> + </column> + </widget> + </item> + <item> + <widget class="QLabel" name="hintLabel"> + <property name="text"> + <string><small></small></string> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + <action name="actionSelect_All"> + <property name="text"> + <string>Select &All</string> + </property> + <property name="toolTip"> + <string>Select all calls</string> + </property> + <property name="shortcut"> + <string>Ctrl+A</string> + </property> + </action> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>VoipCallsDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>VoipCallsDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/ui/tap-sequence-analysis.c b/ui/tap-sequence-analysis.c index abaf6f19b1..a30ee53eda 100644 --- a/ui/tap-sequence-analysis.c +++ b/ui/tap-sequence-analysis.c @@ -256,8 +256,6 @@ sequence_analysis_list_get(capture_file *cf, seq_analysis_info_t *sainfo) case SEQ_ANALYSIS_VOIP: default: return; - break; - } cf_retap_packets(cf); @@ -278,6 +276,31 @@ static void sequence_analysis_item_free(gpointer data) g_free(data); } + +/* compare two list entries by packet no */ +static gint +sequence_analysis_sort_compare(gconstpointer a, gconstpointer b, gpointer user_data _U_) +{ + const seq_analysis_item_t *entry_a = (const seq_analysis_item_t *)a; + const seq_analysis_item_t *entry_b = (const seq_analysis_item_t *)b; + + if(entry_a->fd->num < entry_b->fd->num) + return -1; + + if(entry_a->fd->num > entry_b->fd->num) + return 1; + + return 0; +} + + +void +sequence_analysis_list_sort(seq_analysis_info_t *sainfo) +{ + if (!sainfo) return; + g_queue_sort(sainfo->items, sequence_analysis_sort_compare, NULL); +} + void sequence_analysis_list_free(seq_analysis_info_t *sainfo) { @@ -380,7 +403,7 @@ static void overwrite (GString *gstr, char *text_to_insert, guint32 p1, guint32 * and Return -2 if the array is full */ /****************************************************************************/ -static gint add_or_get_node(seq_analysis_info_t *sainfo, address *node) { +static guint add_or_get_node(seq_analysis_info_t *sainfo, address *node) { guint i; if (node->type == AT_NONE) return NODE_OVERFLOW; @@ -409,8 +432,8 @@ static void sequence_analysis_get_nodes_item_proc(gpointer data, gpointer user_d struct sainfo_counter *sc = (struct sainfo_counter *)user_data; if (gai->display) { (sc->num_items)++; - gai->src_node = (guint16)add_or_get_node(sc->sainfo, &(gai->src_addr)); - gai->dst_node = (guint16)add_or_get_node(sc->sainfo, &(gai->dst_addr)); + gai->src_node = add_or_get_node(sc->sainfo, &(gai->src_addr)); + gai->dst_node = add_or_get_node(sc->sainfo, &(gai->dst_addr)); } } diff --git a/ui/tap-sequence-analysis.h b/ui/tap-sequence-analysis.h index b8262f7d5b..342f91984e 100644 --- a/ui/tap-sequence-analysis.h +++ b/ui/tap-sequence-analysis.h @@ -60,8 +60,8 @@ typedef struct _seq_analysis_item { gchar *comment; /**< a comment that appears at the right of the graph */ guint16 conv_num; /**< the conversation number, each conversation will be colored */ gboolean display; /**< indicate if the packet is displayed or not in the graph */ - guint16 src_node; /**< this is used by graph_analysis.c to identify the node */ - guint16 dst_node; /**< a node is an IP address that will be displayed in columns */ + guint src_node; /**< this is used by graph_analysis.c to identify the node */ + guint dst_node; /**< a node is an IP address that will be displayed in columns */ guint16 line_style; /**< the arrow line width in pixels*/ } seq_analysis_item_t; @@ -94,6 +94,8 @@ void sequence_analysis_info_free(seq_analysis_info_t * sainfo); */ void sequence_analysis_list_get(capture_file *cf, seq_analysis_info_t *sainfo); +void sequence_analysis_list_sort(seq_analysis_info_t *sainfo); + /** Free the segment list * * @param sainfo Sequence analysis information. diff --git a/ui/voip_calls.h b/ui/voip_calls.h index ccaf2e984f..fc6cdb5904 100644 --- a/ui/voip_calls.h +++ b/ui/voip_calls.h @@ -34,11 +34,22 @@ #ifndef __VOIP_CALLS_H__ #define __VOIP_CALLS_H__ +/** @file + * "VoIP Calls" dialog box common routines. + * @ingroup main_ui_group + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + #include <glib.h> #include <stdio.h> #include "epan/address.h" +#include "epan/packet.h" #include "epan/guid-utils.h" +#include "epan/tap.h" #include "epan/tap-voip.h" #include "ui/tap-sequence-analysis.h" @@ -160,7 +171,7 @@ typedef struct _voip_calls_info { nstime_t start_rel_ts; frame_data *stop_fd; nstime_t stop_rel_ts; - gboolean selected; + gboolean selected; /* GTK+ only */ } voip_calls_info_t; @@ -176,6 +187,7 @@ typedef struct _voip_calls_tapinfo { tap_reset_cb tap_reset; /**< tap reset callback */ tap_packet_cb tap_packet; /**< tap per-packet callback */ tap_draw_cb tap_draw; /**< tap draw callback */ + void *tap_data; /**< data for tap callbacks */ int ncalls; /**< number of call */ GQueue* callsinfos; /**< queue with all calls */ GHashTable* callsinfo_hashtable[1]; /**< array of hashes per voip protocol; currently only the one for SIP is used */ @@ -237,6 +249,10 @@ void voip_calls_remove_all_tap_listeners(voip_calls_tapinfo_t *tap_id_base); */ void voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + #endif /* __VOIP_CALLS_H__ */ /* |