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:
parent
cd5b568233
commit
e75e1fb580
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue