Follow SIP Call: Added Follow SIP Call to Follow menu

Changes:
- epan/follow.c: follow_conv_filter_func has new parameter
  epan_dissect_t *edt, so filter can be generated based on decoded tree
of packet below the cursor
- menu Follow/SIP Call is enabled when sip packet is selected
- value of sip.Call-ID is used as filter for SIP call
- for sharkd it generates filter just 'sip.Call-ID' with no value
This commit is contained in:
Jirka Novak 2021-03-26 18:24:38 +01:00 committed by Wireshark GitLab Utility
parent cd5b568233
commit e75e1fb580
15 changed files with 89 additions and 10 deletions

View File

@ -538,7 +538,7 @@ dccp_build_filter(packet_info *pinfo)
return NULL;
}
static gchar *dccp_follow_conv_filter(packet_info *pinfo, guint *stream, guint *sub_stream _U_)
static gchar *dccp_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream _U_)
{
conversation_t *conv;
struct dccp_analysis *dccpd;

View File

@ -2058,7 +2058,7 @@ inflate_http2_header_block(tvbuff_t *tvb, packet_info *pinfo, guint offset, prot
#endif
static gchar*
http2_follow_conv_filter(packet_info *pinfo, guint *stream, guint *sub_stream)
http2_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream)
{
http2_session_t *h2session;
struct tcp_analysis *tcpd;

View File

@ -3747,7 +3747,7 @@ quic_cleanup(void)
/* Follow QUIC Stream functionality {{{ */
static gchar *
quic_follow_conv_filter(packet_info *pinfo, guint *stream, guint *sub_stream)
quic_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream)
{
if (((pinfo->net_src.type == AT_IPv4 && pinfo->net_dst.type == AT_IPv4) ||
(pinfo->net_src.type == AT_IPv6 && pinfo->net_dst.type == AT_IPv6))) {

View File

@ -35,6 +35,10 @@
#include <epan/uat.h>
#include <epan/strutil.h>
#include <epan/to_str.h>
#include <epan/follow.h>
#include <epan/conversation.h>
#include <epan/addr_resolv.h>
#include <epan/epan_dissect.h>
#include <wsutil/str_util.h>
#include <wsutil/strtoi.h>
@ -61,6 +65,7 @@
void proto_register_sip(void);
static gint sip_tap = -1;
static gint sip_follow_tap = -1;
static gint exported_pdu_tap = -1;
static dissector_handle_t sip_handle;
static dissector_handle_t sip_tcp_handle;
@ -3586,6 +3591,9 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info
proto_item_set_text(th, "Message Header");
hdr_tree = proto_item_add_subtree(th, ett_sip_hdr);
if (have_tap_listener(sip_follow_tap))
tap_queue_packet(sip_follow_tap, pinfo, tvb);
/*
* Process the headers - if we're not building a protocol tree,
* we just do this to find the blank line separating the
@ -6007,6 +6015,36 @@ sip_stat_free_table_item(stat_tap_table* table _U_, guint row _U_, guint column,
field_data->value.string_value = NULL;
}
static gchar *sip_follow_conv_filter(epan_dissect_t *edt, packet_info *pinfo _U_, guint *stream _U_, guint *sub_stream _U_)
{
gchar *filter = NULL;
/* Extract si.Call-ID from decoded tree in edt */
if (edt != NULL) {
int hfid = proto_registrar_get_id_byname("sip.Call-ID");
GPtrArray *gp = proto_find_first_finfo(edt->tree, hfid);
if (gp != NULL && gp->len != 0) {
filter = g_strdup_printf("sip.Call-ID == \"%s\"", (gchar *)fvalue_get(&((field_info *)gp->pdata[0])->value));
}
g_ptr_array_free(gp, TRUE);
} else {
filter = g_strdup_printf("sip.Call-ID");
}
return filter;
}
static gchar *sip_follow_index_filter(guint stream _U_, guint sub_stream _U_)
{
return NULL;
}
static gchar *sip_follow_address_filter(address *src_addr _U_, address *dst_addr _U_, int src_port _U_, int dst_port _U_)
{
return NULL;
}
/* Register the protocol with Wireshark */
void proto_register_sip(void)
{
@ -7617,6 +7655,7 @@ void proto_register_sip(void)
heur_subdissector_list = register_heur_dissector_list("sip", proto_sip);
/* Register for tapping */
sip_tap = register_tap("sip");
sip_follow_tap = register_tap("sip_follow");
ext_hdr_subdissector_table = register_dissector_table("sip.hdr", "SIP Extension header", proto_sip, FT_STRING, BASE_NONE);
@ -7632,6 +7671,8 @@ void proto_register_sip(void)
ws_mempbrk_compile(&pbrk_addr_end, "[] \t:;");
ws_mempbrk_compile(&pbrk_via_param_end, "\t;, ");
register_follow_stream(proto_sip, "sip_follow", sip_follow_conv_filter, sip_follow_index_filter, sip_follow_address_filter,
udp_port_to_display, follow_tvb_tap_listener);
}
void

View File

@ -947,7 +947,7 @@ tcp_seq_analysis_packet( void *ptr, packet_info *pinfo, epan_dissect_t *edt _U_,
}
gchar *tcp_follow_conv_filter(packet_info *pinfo, guint *stream, guint *sub_stream _U_)
gchar *tcp_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream _U_)
{
conversation_t *conv;
struct tcp_analysis *tcpd;

View File

@ -539,7 +539,7 @@ WS_DLL_PUBLIC guint32 get_tcp_stream_count(void);
WS_DLL_PUBLIC guint32 get_mptcp_stream_count(void);
/* Follow Stream functionality shared with HTTP (and SSL?) */
extern gchar *tcp_follow_conv_filter(packet_info *pinfo, guint *stream, guint *sub_stream);
extern gchar *tcp_follow_conv_filter(epan_dissect_t *edt, packet_info *pinfo, guint *stream, guint *sub_stream);
extern gchar *tcp_follow_index_filter(guint stream, guint sub_stream);
extern gchar *tcp_follow_address_filter(address *src_addr, address *dst_addr, int src_port, int dst_port);

View File

@ -434,7 +434,7 @@ udp_build_filter(packet_info *pinfo)
return NULL;
}
static gchar *udp_follow_conv_filter(packet_info *pinfo, guint *stream, guint *sub_stream _U_)
static gchar *udp_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, guint *stream, guint *sub_stream _U_)
{
conversation_t *conv;
struct udp_analysis *udpd;

View File

@ -46,6 +46,7 @@ typedef enum {
FOLLOW_HTTP,
FOLLOW_HTTP2,
FOLLOW_QUIC,
FOLLOW_SIP,
} follow_type_t;
/* Show Type */
@ -101,7 +102,7 @@ typedef struct _follow_info {
struct register_follow;
typedef struct register_follow register_follow_t;
typedef gchar* (*follow_conv_filter_func)(packet_info *pinfo, guint *stream, guint *sub_stream);
typedef gchar* (*follow_conv_filter_func)(epan_dissect_t *edt, packet_info *pinfo, guint *stream, guint *sub_stream);
typedef gchar* (*follow_index_filter_func)(guint stream, guint sub_stream);
typedef gchar* (*follow_address_filter_func)(address* src_addr, address* dst_addr, int src_port, int dst_port);
typedef gchar* (*follow_port_to_display_func)(wmem_allocator_t *allocator, guint port);

View File

@ -2749,7 +2749,7 @@ sharkd_follower_visit_layers_cb(const void *key _U_, void *value, void *user_dat
const char *layer_proto = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
char *follow_filter;
follow_filter = get_follow_conv_func(follower)(pi, &ignore_stream, &ignore_sub_stream);
follow_filter = get_follow_conv_func(follower)(NULL, pi, &ignore_stream, &ignore_sub_stream);
json_dumper_begin_array(&dumper);
json_dumper_value_string(&dumper, layer_proto);

View File

@ -13,6 +13,7 @@
#include "main_window.h"
#include "wireshark_application.h"
#include "frame_tvbuff.h"
#include "epan/follow.h"
#include "epan/dissectors/packet-tcp.h"
#include "epan/dissectors/packet-udp.h"
@ -106,6 +107,9 @@ FollowStreamDialog::FollowStreamDialog(QWidget &parent, CaptureFile &cf, follow_
case FOLLOW_QUIC:
follower_ = get_follow_by_name("QUIC");
break;
case FOLLOW_SIP:
follower_ = get_follow_by_name("SIP");
break;
default :
g_assert_not_reached();
}
@ -528,6 +532,7 @@ FollowStreamDialog::readStream()
case FOLLOW_HTTP2:
case FOLLOW_QUIC:
case FOLLOW_TLS :
case FOLLOW_SIP :
ret = readFollowStream();
break;
@ -884,7 +889,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
if (use_stream_index) {
follow_filter = gchar_free_to_qstring(get_follow_index_func(follower_)(stream_num, sub_stream_num));
} else {
follow_filter = gchar_free_to_qstring(get_follow_conv_func(follower_)(&cap_file_.capFile()->edt->pi, &stream_num, &sub_stream_num));
follow_filter = gchar_free_to_qstring(get_follow_conv_func(follower_)(cap_file_.capFile()->edt, &cap_file_.capFile()->edt->pi, &stream_num, &sub_stream_num));
}
if (follow_filter.isEmpty()) {
QMessageBox::warning(this,
@ -1011,6 +1016,19 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
case FOLLOW_HTTP:
/* No extra handling */
break;
case FOLLOW_SIP:
{
/* There are no more streams */
ui->streamNumberSpinBox->setEnabled(false);
ui->streamNumberSpinBox->blockSignals(true);
ui->streamNumberSpinBox->setMaximum(0);
ui->streamNumberSpinBox->setValue(0);
ui->streamNumberSpinBox->blockSignals(false);
ui->streamNumberSpinBox->setToolTip(tr("No streams"));
ui->streamNumberLabel->setToolTip(ui->streamNumberSpinBox->toolTip());
break;
}
}
beginRetapPackets();

View File

@ -579,6 +579,7 @@ private slots:
void on_actionAnalyzeFollowHTTPStream_triggered();
void on_actionAnalyzeFollowHTTP2Stream_triggered();
void on_actionAnalyzeFollowQUICStream_triggered();
void on_actionAnalyzeFollowSIPCall_triggered();
void statCommandExpertInfo(const char *, void *);
void on_actionAnalyzeExpertInfo_triggered();

View File

@ -418,6 +418,7 @@
<addaction name="actionAnalyzeFollowHTTPStream"/>
<addaction name="actionAnalyzeFollowHTTP2Stream"/>
<addaction name="actionAnalyzeFollowQUICStream"/>
<addaction name="actionAnalyzeFollowSIPCall"/>
</widget>
<widget class="QMenu" name="menuConversationFilter">
<property name="title">
@ -1759,6 +1760,14 @@
<string>QUIC Stream</string>
</property>
</action>
<action name="actionAnalyzeFollowSIPCall">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>SIP Call</string>
</property>
</action>
<action name="actionStatisticsTcpStreamTcptrace">
<property name="text">
<string>Time Sequence (tcptrace)</string>

View File

@ -1124,7 +1124,7 @@ void MainWindow::recentActionTriggered() {
void MainWindow::setMenusForSelectedPacket()
{
gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_dccp = FALSE, is_sctp = FALSE, is_tls = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE,
is_http = FALSE, is_http2 = FALSE, is_quic = FALSE;
is_http = FALSE, is_http2 = FALSE, is_quic = FALSE, is_sip = FALSE;
/* Making the menu context-sensitive allows for easier selection of the
desired item and has the added benefit, with large captures, of
@ -1197,6 +1197,7 @@ void MainWindow::setMenusForSelectedPacket()
is_http = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http");
is_http2 = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http2");
is_quic = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "quic");
is_sip = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "sip");
}
}
@ -1243,6 +1244,7 @@ void MainWindow::setMenusForSelectedPacket()
main_ui_->actionAnalyzeFollowHTTPStream->setEnabled(is_http);
main_ui_->actionAnalyzeFollowHTTP2Stream->setEnabled(is_http2);
main_ui_->actionAnalyzeFollowQUICStream->setEnabled(is_quic);
main_ui_->actionAnalyzeFollowSIPCall->setEnabled(is_sip);
foreach(QAction *cc_action, cc_actions) {
cc_action->setEnabled(frame_selected);
@ -2907,6 +2909,11 @@ void MainWindow::on_actionAnalyzeFollowQUICStream_triggered()
openFollowStreamDialogForType(FOLLOW_QUIC);
}
void MainWindow::on_actionAnalyzeFollowSIPCall_triggered()
{
openFollowStreamDialogForType(FOLLOW_SIP);
}
void MainWindow::openSCTPAllAssocsDialog()
{
SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile());

View File

@ -688,6 +688,7 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTPStream"));
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTP2Stream"));
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowQUICStream"));
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowSIPCall"));
ctx_menu->addSeparator();

View File

@ -309,6 +309,7 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTPStream"));
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowHTTP2Stream"));
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowQUICStream"));
submenu->addAction(window()->findChild<QAction *>("actionAnalyzeFollowSIPCall"));
ctx_menu.addSeparator();
}