2016-10-15 18:48:17 +00:00
/* sharkd_session.c
*
* Copyright ( C ) 2016 Jakub Zawadzki
*
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
* Copyright 1998 Gerald Combs
*
2018-02-07 11:26:45 +00:00
* SPDX - License - Identifier : GPL - 2.0 - or - later
2016-10-15 18:48:17 +00:00
*/
# include <config.h>
# include <stdio.h>
# include <stdlib.h>
2018-09-24 20:47:42 +00:00
# include <stdarg.h>
2016-10-15 18:48:17 +00:00
# include <string.h>
# include <errno.h>
# include <glib.h>
2018-04-20 14:55:00 +00:00
# include <wsutil/wsjson.h>
2017-01-26 01:27:13 +00:00
# include <wsutil/ws_printf.h>
2018-12-12 14:33:44 +00:00
# include <wsutil/json_dumper.h>
2016-10-15 18:48:17 +00:00
# include <file.h>
2017-10-04 20:41:19 +00:00
# include <epan/epan_dissect.h>
2016-10-15 18:48:17 +00:00
# include <epan/exceptions.h>
# include <epan/color_filters.h>
# include <epan/prefs.h>
# include <epan/prefs-int.h>
# include <epan/uat-int.h>
# include <wiretap/wtap.h>
# include <epan/column.h>
2017-03-25 12:05:50 +00:00
# include <ui/ssl_key_export.h>
2018-05-06 16:15:58 +00:00
# include <ui/io_graph_item.h>
2016-10-15 18:48:17 +00:00
# include <epan/stats_tree_priv.h>
# include <epan/stat_tap_ui.h>
# include <epan/conversation_table.h>
2017-09-16 15:46:15 +00:00
# include <epan/sequence_analysis.h>
2017-03-17 06:59:05 +00:00
# include <epan/expert.h>
2017-03-11 11:27:14 +00:00
# include <epan/export_object.h>
# include <epan/follow.h>
2017-03-19 10:33:47 +00:00
# include <epan/rtd_table.h>
# include <epan/srt_table.h>
2016-10-15 18:48:17 +00:00
# include <epan/dissectors/packet-h225.h>
# include <epan/rtp_pt.h>
# include <ui/voip_calls.h>
# include <ui/rtp_stream.h>
# include <ui/tap-rtp-common.h>
2018-06-14 21:19:01 +00:00
# include <ui/tap-rtp-analysis.h>
2016-10-15 18:48:17 +00:00
# include <epan/to_str.h>
2017-03-31 18:35:51 +00:00
# include <epan/addr_resolv.h>
# include <epan/dissectors/packet-rtp.h>
2017-04-08 08:15:11 +00:00
# include <ui/rtp_media.h>
2017-05-29 21:23:49 +00:00
# ifdef HAVE_SPEEXDSP
2017-08-19 20:24:56 +00:00
# include <speex / speex_resampler.h>
2017-05-29 21:23:49 +00:00
# else
2019-02-02 14:52:07 +00:00
# include "speexdsp / speex_resampler.h"
2017-05-29 21:23:49 +00:00
# endif /* HAVE_SPEEXDSP */
2017-03-31 18:35:51 +00:00
2018-03-12 15:38:35 +00:00
# include <epan/maxmind_db.h>
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
# include <wsutil/pint.h>
2016-10-15 18:48:17 +00:00
# include <wsutil/strtoi.h>
2017-12-08 08:30:55 +00:00
# include "globals.h"
2016-10-15 18:48:17 +00:00
# include "sharkd.h"
2018-01-14 15:38:55 +00:00
struct sharkd_filter_item
{
2018-09-01 16:47:38 +00:00
guint8 * filtered ; /* can be NULL if all frames are matching for given filter. */
2018-01-14 15:38:55 +00:00
} ;
static GHashTable * filter_table = NULL ;
2018-12-12 14:33:44 +00:00
static json_dumper dumper = { 0 } ;
2016-10-15 18:48:17 +00:00
static const char *
json_find_attr ( const char * buf , const jsmntok_t * tokens , int count , const char * attr )
{
int i ;
for ( i = 0 ; i < count ; i + = 2 )
{
const char * tok_attr = & buf [ tokens [ i + 0 ] . start ] ;
const char * tok_value = & buf [ tokens [ i + 1 ] . start ] ;
if ( ! strcmp ( tok_attr , attr ) )
return tok_value ;
}
return NULL ;
}
static void
2017-03-29 16:38:54 +00:00
json_print_base64 ( const guint8 * data , size_t len )
2016-10-15 18:48:17 +00:00
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_base64 ( & dumper ) ;
json_dumper_write_base64 ( & dumper , data , len ) ;
json_dumper_end_base64 ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
2018-12-12 14:33:44 +00:00
static void G_GNUC_PRINTF ( 2 , 3 )
sharkd_json_value_anyf ( const char * key , const char * format , . . . )
2018-09-24 18:34:30 +00:00
{
if ( key )
2018-12-12 14:33:44 +00:00
json_dumper_set_member_name ( & dumper , key ) ;
2018-09-24 20:47:42 +00:00
2018-12-12 14:33:44 +00:00
if ( format ) {
2018-09-24 20:47:42 +00:00
va_list ap ;
2018-12-12 14:33:44 +00:00
va_start ( ap , format ) ;
json_dumper_value_va_list ( & dumper , format , ap ) ;
2018-09-24 20:47:42 +00:00
va_end ( ap ) ;
}
}
2018-09-25 09:06:12 +00:00
static void
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( const char * key , const char * str )
2018-09-25 09:06:12 +00:00
{
2018-12-12 14:33:44 +00:00
if ( key )
json_dumper_set_member_name ( & dumper , key ) ;
if ( str )
json_dumper_value_string ( & dumper , str ) ;
2018-09-25 09:06:12 +00:00
}
static void
2018-12-12 14:33:44 +00:00
sharkd_json_value_base64 ( const char * key , const guint8 * data , size_t len )
2018-09-25 09:06:12 +00:00
{
2018-12-12 14:33:44 +00:00
if ( key )
json_dumper_set_member_name ( & dumper , key ) ;
2018-09-25 09:06:12 +00:00
json_print_base64 ( data , len ) ;
}
2018-12-12 14:33:44 +00:00
static void G_GNUC_PRINTF ( 2 , 3 )
sharkd_json_value_stringf ( const char * key , const char * format , . . . )
2018-09-24 20:47:42 +00:00
{
2018-12-12 14:33:44 +00:00
if ( key )
json_dumper_set_member_name ( & dumper , key ) ;
2018-09-24 20:47:42 +00:00
2018-12-12 14:33:44 +00:00
if ( format ) {
va_list ap ;
va_start ( ap , format ) ;
char * sformat = g_strdup_printf ( " \" %s \" " , format ) ;
json_dumper_value_va_list ( & dumper , sformat , ap ) ;
g_free ( sformat ) ;
va_end ( ap ) ;
}
2018-09-24 18:34:30 +00:00
}
2018-09-24 16:55:27 +00:00
static void
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( const char * key )
2018-09-24 16:55:27 +00:00
{
2018-12-12 14:33:44 +00:00
if ( key )
json_dumper_set_member_name ( & dumper , key ) ;
json_dumper_begin_array ( & dumper ) ;
2018-09-24 16:55:27 +00:00
}
static void
sharkd_json_array_close ( void )
{
2018-12-12 14:33:44 +00:00
json_dumper_end_array ( & dumper ) ;
2018-09-25 17:20:54 +00:00
}
static void
sharkd_json_simple_reply ( int err , const char * errmsg )
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_anyf ( " err " , " %d " , err ) ;
2018-09-25 17:20:54 +00:00
if ( errmsg )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " errmsg " , errmsg ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2018-09-24 16:55:27 +00:00
}
2018-01-14 15:38:55 +00:00
static void
sharkd_session_filter_free ( gpointer data )
2016-10-15 18:48:17 +00:00
{
2018-01-14 15:38:55 +00:00
struct sharkd_filter_item * l = ( struct sharkd_filter_item * ) data ;
2016-10-15 18:48:17 +00:00
2018-01-14 15:38:55 +00:00
g_free ( l - > filtered ) ;
g_free ( l ) ;
}
2016-10-15 18:48:17 +00:00
2018-09-01 16:47:38 +00:00
static const struct sharkd_filter_item *
2016-10-15 18:48:17 +00:00
sharkd_session_filter_data ( const char * filter )
{
2018-01-14 15:38:55 +00:00
struct sharkd_filter_item * l ;
2016-10-15 18:48:17 +00:00
2018-01-14 15:38:55 +00:00
l = ( struct sharkd_filter_item * ) g_hash_table_lookup ( filter_table , filter ) ;
if ( ! l )
2016-10-15 18:48:17 +00:00
{
guint8 * filtered = NULL ;
int ret = sharkd_filter ( filter , & filtered ) ;
if ( ret = = - 1 )
return NULL ;
2018-01-14 15:38:55 +00:00
l = ( struct sharkd_filter_item * ) g_malloc ( sizeof ( struct sharkd_filter_item ) ) ;
2016-10-15 18:48:17 +00:00
l - > filtered = filtered ;
2018-01-14 15:38:55 +00:00
g_hash_table_insert ( filter_table , g_strdup ( filter ) , l ) ;
2016-10-15 18:48:17 +00:00
}
2018-01-14 15:38:55 +00:00
2018-09-01 16:47:38 +00:00
return l ;
2016-10-15 18:48:17 +00:00
}
2017-03-31 18:35:51 +00:00
static gboolean
2018-06-15 20:47:47 +00:00
sharkd_rtp_match_init ( rtpstream_id_t * id , const char * init_str )
2017-03-31 18:35:51 +00:00
{
gboolean ret = FALSE ;
char * * arr ;
2018-06-15 20:47:47 +00:00
guint32 tmp_addr_src , tmp_addr_dst ;
address tmp_src_addr , tmp_dst_addr ;
memset ( id , 0 , sizeof ( * id ) ) ;
2017-03-31 18:35:51 +00:00
arr = g_strsplit ( init_str , " _ " , 7 ) ; /* pass larger value, so we'll catch incorrect input :) */
if ( g_strv_length ( arr ) ! = 5 )
goto fail ;
/* TODO, for now only IPv4 */
2018-06-15 20:47:47 +00:00
if ( ! get_host_ipaddr ( arr [ 0 ] , & tmp_addr_src ) )
2017-03-31 18:35:51 +00:00
goto fail ;
2018-06-15 20:47:47 +00:00
if ( ! ws_strtou16 ( arr [ 1 ] , NULL , & id - > src_port ) )
2017-03-31 18:35:51 +00:00
goto fail ;
2018-06-15 20:47:47 +00:00
if ( ! get_host_ipaddr ( arr [ 2 ] , & tmp_addr_dst ) )
2017-03-31 18:35:51 +00:00
goto fail ;
2018-06-15 20:47:47 +00:00
if ( ! ws_strtou16 ( arr [ 3 ] , NULL , & id - > dst_port ) )
2017-03-31 18:35:51 +00:00
goto fail ;
2018-06-15 20:47:47 +00:00
if ( ! ws_hexstrtou32 ( arr [ 4 ] , NULL , & id - > ssrc ) )
2017-03-31 18:35:51 +00:00
goto fail ;
2018-06-15 20:47:47 +00:00
set_address ( & tmp_src_addr , AT_IPv4 , 4 , & tmp_addr_src ) ;
copy_address ( & id - > src_addr , & tmp_src_addr ) ;
set_address ( & tmp_dst_addr , AT_IPv4 , 4 , & tmp_addr_dst ) ;
copy_address ( & id - > dst_addr , & tmp_dst_addr ) ;
2017-03-31 18:35:51 +00:00
ret = TRUE ;
fail :
g_strfreev ( arr ) ;
return ret ;
}
2017-05-13 21:52:50 +00:00
static gboolean
2018-12-12 14:33:44 +00:00
sharkd_session_process_info_nstat_cb ( const void * key , void * value , void * userdata _U_ )
2017-05-13 21:52:50 +00:00
{
2018-02-18 22:39:49 +00:00
stat_tap_table_ui * stat_tap = ( stat_tap_table_ui * ) value ;
2017-05-13 21:52:50 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " name " , stat_tap - > title ) ;
sharkd_json_value_stringf ( " tap " , " nstat:%s " , ( const char * ) key ) ;
json_dumper_end_object ( & dumper ) ;
2017-05-13 21:52:50 +00:00
return FALSE ;
}
2017-02-07 22:05:17 +00:00
static gboolean
2018-12-12 14:33:44 +00:00
sharkd_session_process_info_conv_cb ( const void * key , void * value , void * userdata _U_ )
2016-10-15 18:48:17 +00:00
{
2017-02-07 22:05:17 +00:00
struct register_ct * table = ( struct register_ct * ) value ;
2016-10-15 18:48:17 +00:00
2017-12-07 19:37:54 +00:00
const char * label = ( const char * ) key ;
2016-10-15 18:48:17 +00:00
if ( get_conversation_packet_func ( table ) )
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " name " , " Conversation List/%s " , label ) ;
sharkd_json_value_stringf ( " tap " , " conv:%s " , label ) ;
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
if ( get_hostlist_packet_func ( table ) )
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " name " , " Endpoint/%s " , label ) ;
sharkd_json_value_stringf ( " tap " , " endpt:%s " , label ) ;
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
2017-02-07 22:05:17 +00:00
return FALSE ;
2016-10-15 18:48:17 +00:00
}
2017-09-16 15:46:15 +00:00
static gboolean
2018-12-12 14:33:44 +00:00
sharkd_session_seq_analysis_cb ( const void * key , void * value , void * userdata _U_ )
2017-09-16 15:46:15 +00:00
{
2017-12-07 19:37:54 +00:00
register_analysis_t * analysis = ( register_analysis_t * ) value ;
2017-09-16 15:46:15 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " name " , sequence_analysis_get_ui_name ( analysis ) ) ;
sharkd_json_value_stringf ( " tap " , " seqa:%s " , ( const char * ) key ) ;
json_dumper_end_object ( & dumper ) ;
2017-09-16 15:46:15 +00:00
return FALSE ;
}
2017-03-11 11:27:14 +00:00
static gboolean
2018-12-12 14:33:44 +00:00
sharkd_export_object_visit_cb ( const void * key _U_ , void * value , void * user_data _U_ )
2017-03-11 11:27:14 +00:00
{
2017-12-07 19:37:54 +00:00
register_eo_t * eo = ( register_eo_t * ) value ;
2017-03-11 11:27:14 +00:00
const int proto_id = get_eo_proto_id ( eo ) ;
const char * filter = proto_get_protocol_filter_name ( proto_id ) ;
const char * label = proto_get_protocol_short_name ( find_protocol_by_id ( proto_id ) ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " name " , " Export Object/%s " , label ) ;
sharkd_json_value_stringf ( " tap " , " eo:%s " , filter ) ;
json_dumper_end_object ( & dumper ) ;
2017-03-11 11:27:14 +00:00
return FALSE ;
}
2017-03-19 10:33:47 +00:00
static gboolean
2018-12-12 14:33:44 +00:00
sharkd_srt_visit_cb ( const void * key _U_ , void * value , void * user_data _U_ )
2017-03-19 10:33:47 +00:00
{
register_srt_t * srt = ( register_srt_t * ) value ;
const int proto_id = get_srt_proto_id ( srt ) ;
const char * filter = proto_get_protocol_filter_name ( proto_id ) ;
const char * label = proto_get_protocol_short_name ( find_protocol_by_id ( proto_id ) ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " name " , " Service Response Time/%s " , label ) ;
sharkd_json_value_stringf ( " tap " , " srt:%s " , filter ) ;
json_dumper_end_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
return FALSE ;
}
static gboolean
2018-12-12 14:33:44 +00:00
sharkd_rtd_visit_cb ( const void * key _U_ , void * value , void * user_data _U_ )
2017-03-19 10:33:47 +00:00
{
register_rtd_t * rtd = ( register_rtd_t * ) value ;
const int proto_id = get_rtd_proto_id ( rtd ) ;
const char * filter = proto_get_protocol_filter_name ( proto_id ) ;
const char * label = proto_get_protocol_short_name ( find_protocol_by_id ( proto_id ) ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " name " , " Response Time Delay/%s " , label ) ;
sharkd_json_value_stringf ( " tap " , " rtd:%s " , filter ) ;
json_dumper_end_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
return FALSE ;
}
2017-03-11 11:27:14 +00:00
static gboolean
2018-12-12 14:33:44 +00:00
sharkd_follower_visit_cb ( const void * key _U_ , void * value , void * user_data _U_ )
2017-03-11 11:27:14 +00:00
{
2017-12-07 19:37:54 +00:00
register_follow_t * follower = ( register_follow_t * ) value ;
2017-03-11 11:27:14 +00:00
const int proto_id = get_follow_proto_id ( follower ) ;
const char * label = proto_get_protocol_short_name ( find_protocol_by_id ( proto_id ) ) ;
const char * filter = label ; /* correct: get_follow_by_name() is registered by short name */
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " name " , " Follow/%s " , label ) ;
sharkd_json_value_stringf ( " tap " , " follow:%s " , filter ) ;
json_dumper_end_object ( & dumper ) ;
2017-03-11 11:27:14 +00:00
return FALSE ;
}
2016-10-15 18:48:17 +00:00
/**
* sharkd_session_process_info ( )
*
* Process info request
*
* Output object with attributes :
2018-11-20 15:22:46 +00:00
* ( m ) version - version number
*
2016-10-15 18:48:17 +00:00
* ( m ) columns - available column formats , array of object with attributes :
* ' name ' - column name
* ' format ' - column format - name
*
* ( m ) stats - available statistics , array of object with attributes :
* ' name ' - statistic name
* ' tap ' - sharkd tap - name for statistic
*
* ( m ) convs - available conversation list , array of object with attributes :
* ' name ' - conversation name
* ' tap ' - sharkd tap - name for conversation
*
2017-03-11 11:27:14 +00:00
* ( m ) eo - available export object list , array of object with attributes :
* ' name ' - export object name
2017-03-19 10:33:47 +00:00
* ' tap ' - sharkd tap - name for eo
*
* ( m ) srt - available service response time list , array of object with attributes :
* ' name ' - service response time name
* ' tap ' - sharkd tap - name for srt
*
* ( m ) rtd - available response time delay list , array of object with attributes :
* ' name ' - response time delay name
* ' tap ' - sharkd tap - name for rtd
2017-03-11 11:27:14 +00:00
*
2017-09-16 15:46:15 +00:00
* ( m ) seqa - available sequence analysis ( flow ) list , array of object with attributes :
* ' name ' - sequence analysis name
* ' tap ' - sharkd tap - name
*
2018-11-20 15:22:46 +00:00
* ( m ) taps - available taps , array of object with attributes :
2016-10-15 18:48:17 +00:00
* ' name ' - tap name
* ' tap ' - sharkd tap - name
2017-03-19 10:33:47 +00:00
*
2018-11-20 15:22:46 +00:00
* ( m ) follow - available followers , array of object with attributes :
* ' name ' - tap name
* ' tap ' - sharkd tap - name
*
* ( m ) ftypes - conversation table for FT_ number to string , array of FT_xxx strings .
*
* ( m ) nstat - available table - based taps , array of object with attributes :
2017-03-11 11:27:14 +00:00
* ' name ' - tap name
* ' tap ' - sharkd tap - name
2016-10-15 18:48:17 +00:00
*
*/
static void
sharkd_session_process_info ( void )
{
int i ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-24 18:34:30 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " columns " ) ;
2016-10-15 18:48:17 +00:00
for ( i = 0 ; i < NUM_COL_FMTS ; i + + )
{
const char * col_format = col_format_to_string ( i ) ;
const char * col_descr = col_format_desc ( i ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " name " , col_descr ) ;
sharkd_json_value_string ( " format " , col_format ) ;
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " stats " ) ;
2016-10-15 18:48:17 +00:00
{
GList * cfg_list = stats_tree_get_cfg_list ( ) ;
GList * l ;
for ( l = cfg_list ; l ; l = l - > next )
{
stats_tree_cfg * cfg = ( stats_tree_cfg * ) l - > data ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " name " , cfg - > name ) ;
sharkd_json_value_stringf ( " tap " , " stat:%s " , cfg - > abbr ) ;
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
g_list_free ( cfg_list ) ;
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " ftypes " ) ;
2016-10-15 18:48:17 +00:00
for ( i = 0 ; i < FT_NUM_TYPES ; i + + )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( NULL , ftype_name ( ( ftenum_t ) i ) ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " version " , sharkd_version ( ) ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " nstat " ) ;
2017-05-13 21:52:50 +00:00
i = 0 ;
2018-02-18 22:39:49 +00:00
stat_tap_iterate_tables ( sharkd_session_process_info_nstat_cb , & i ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-05-13 21:52:50 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " convs " ) ;
2016-10-15 18:48:17 +00:00
i = 0 ;
conversation_table_iterate_tables ( sharkd_session_process_info_conv_cb , & i ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " seqa " ) ;
2017-09-16 15:46:15 +00:00
i = 0 ;
sequence_analysis_table_iterate_tables ( sharkd_session_seq_analysis_cb , & i ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-09-16 15:46:15 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " taps " ) ;
2017-02-25 11:45:33 +00:00
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " name " , " RTP streams " ) ;
sharkd_json_value_string ( " tap " , " rtp-streams " ) ;
json_dumper_end_object ( & dumper ) ;
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " name " , " Expert Information " ) ;
sharkd_json_value_string ( " tap " , " expert " ) ;
json_dumper_end_object ( & dumper ) ;
2017-02-25 11:45:33 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " eo " ) ;
2017-03-11 11:27:14 +00:00
i = 0 ;
eo_iterate_tables ( sharkd_export_object_visit_cb , & i ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " srt " ) ;
2017-03-19 10:33:47 +00:00
i = 0 ;
srt_table_iterate_tables ( sharkd_srt_visit_cb , & i ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " rtd " ) ;
2017-03-19 10:33:47 +00:00
i = 0 ;
rtd_table_iterate_tables ( sharkd_rtd_visit_cb , & i ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " follow " ) ;
2017-03-11 11:27:14 +00:00
i = 0 ;
follow_iterate_followers ( sharkd_follower_visit_cb , & i ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
/**
* sharkd_session_process_load ( )
*
* Process load request
*
* Input :
* ( m ) file - file to be loaded
*
* Output object with attributes :
* ( m ) err - error code
*/
static void
sharkd_session_process_load ( const char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_file = json_find_attr ( buf , tokens , count , " file " ) ;
int err = 0 ;
if ( ! tok_file )
return ;
2020-05-14 13:28:39 +00:00
fprintf ( stderr , " load: filename=%s \n " , tok_file ) ;
2016-10-15 18:48:17 +00:00
if ( sharkd_cf_open ( tok_file , WTAP_TYPE_AUTO , FALSE , & err ) ! = CF_OK )
{
2018-09-25 17:20:54 +00:00
sharkd_json_simple_reply ( err , NULL ) ;
2016-10-15 18:48:17 +00:00
return ;
}
TRY
{
err = sharkd_load_cap_file ( ) ;
}
CATCH ( OutOfMemoryError )
{
fprintf ( stderr , " load: OutOfMemoryError \n " ) ;
err = ENOMEM ;
}
ENDTRY ;
2018-09-25 17:20:54 +00:00
sharkd_json_simple_reply ( err , NULL ) ;
2016-10-15 18:48:17 +00:00
}
/**
* sharkd_session_process_status ( )
*
* Process status request
*
* Output object with attributes :
2017-05-16 05:52:13 +00:00
* ( m ) frames - count of currently loaded frames
* ( m ) duration - time difference between time of first frame , and last loaded frame
* ( o ) filename - capture filename
* ( o ) filesize - capture filesize
2016-10-15 18:48:17 +00:00
*/
static void
sharkd_session_process_status ( void )
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " frames " , " %u " , cfile . count ) ;
sharkd_json_value_anyf ( " duration " , " %.9f " , nstime_to_sec ( & cfile . elapsed_time ) ) ;
2017-05-16 05:52:13 +00:00
if ( cfile . filename )
{
char * name = g_path_get_basename ( cfile . filename ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " filename " , name ) ;
2017-05-16 05:52:13 +00:00
g_free ( name ) ;
}
2017-12-08 03:31:43 +00:00
if ( cfile . provider . wth )
2017-05-16 05:52:13 +00:00
{
2017-12-08 03:31:43 +00:00
gint64 file_size = wtap_file_size ( cfile . provider . wth , NULL ) ;
2017-05-16 05:52:13 +00:00
if ( file_size > 0 )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " filesize " , " % " G_GINT64_FORMAT , file_size ) ;
2017-05-16 05:52:13 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
struct sharkd_analyse_data
{
GHashTable * protocols_set ;
nstime_t * first_time ;
nstime_t * last_time ;
} ;
static void
2017-10-04 20:41:19 +00:00
sharkd_session_process_analyse_cb ( epan_dissect_t * edt , proto_tree * tree , struct epan_column_info * cinfo , const GSList * data_src , void * data )
2016-10-15 18:48:17 +00:00
{
struct sharkd_analyse_data * analyser = ( struct sharkd_analyse_data * ) data ;
2017-10-04 20:41:19 +00:00
packet_info * pi = & edt - > pi ;
2016-10-15 18:48:17 +00:00
frame_data * fdata = pi - > fd ;
( void ) tree ;
( void ) cinfo ;
( void ) data_src ;
if ( analyser - > first_time = = NULL | | nstime_cmp ( & fdata - > abs_ts , analyser - > first_time ) < 0 )
analyser - > first_time = & fdata - > abs_ts ;
if ( analyser - > last_time = = NULL | | nstime_cmp ( & fdata - > abs_ts , analyser - > last_time ) > 0 )
analyser - > last_time = & fdata - > abs_ts ;
if ( pi - > layers )
{
2017-01-27 07:10:56 +00:00
wmem_list_frame_t * frame ;
2016-10-15 18:48:17 +00:00
for ( frame = wmem_list_head ( pi - > layers ) ; frame ; frame = wmem_list_frame_next ( frame ) )
{
int proto_id = GPOINTER_TO_UINT ( wmem_list_frame_data ( frame ) ) ;
if ( ! g_hash_table_lookup_extended ( analyser - > protocols_set , GUINT_TO_POINTER ( proto_id ) , NULL , NULL ) )
{
g_hash_table_insert ( analyser - > protocols_set , GUINT_TO_POINTER ( proto_id ) , GUINT_TO_POINTER ( proto_id ) ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( NULL , proto_get_protocol_filter_name ( proto_id ) ) ;
2016-10-15 18:48:17 +00:00
}
}
}
}
/**
* sharkd_session_process_status ( )
*
* Process analyse request
*
* Output object with attributes :
* ( m ) frames - count of currently loaded frames
* ( m ) protocols - protocol list
* ( m ) first - earliest frame time
* ( m ) last - latest frame time
*/
static void
sharkd_session_process_analyse ( void )
{
unsigned int framenum ;
struct sharkd_analyse_data analyser ;
analyser . first_time = NULL ;
analyser . last_time = NULL ;
analyser . protocols_set = g_hash_table_new ( NULL /* g_direct_hash() */ , NULL /* g_direct_equal */ ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " frames " , " %u " , cfile . count ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " protocols " ) ;
2016-10-15 18:48:17 +00:00
for ( framenum = 1 ; framenum < = cfile . count ; framenum + + )
2018-06-16 16:22:00 +00:00
sharkd_dissect_request ( framenum , ( framenum ! = 1 ) ? 1 : 0 , framenum - 1 , & sharkd_session_process_analyse_cb , SHARKD_DISSECT_FLAG_NULL , & analyser ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
if ( analyser . first_time )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " first " , " %.9f " , nstime_to_sec ( analyser . first_time ) ) ;
2016-10-15 18:48:17 +00:00
if ( analyser . last_time )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " last " , " %.9f " , nstime_to_sec ( analyser . last_time ) ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
g_hash_table_destroy ( analyser . protocols_set ) ;
}
2017-09-27 20:24:54 +00:00
static column_info *
sharkd_session_create_columns ( column_info * cinfo , const char * buf , const jsmntok_t * tokens , int count )
{
const char * columns_custom [ 32 ] ;
guint16 columns_fmt [ 32 ] ;
gint16 columns_occur [ 32 ] ;
int i , cols ;
for ( i = 0 ; i < 32 ; i + + )
{
const char * tok_column ;
char tok_column_name [ 64 ] ;
char * custom_sepa ;
ws_snprintf ( tok_column_name , sizeof ( tok_column_name ) , " column%d " , i ) ;
tok_column = json_find_attr ( buf , tokens , count , tok_column_name ) ;
if ( tok_column = = NULL )
break ;
2018-01-17 15:49:21 +00:00
columns_custom [ i ] = NULL ;
columns_occur [ i ] = 0 ;
2017-09-27 20:24:54 +00:00
if ( ( custom_sepa = strchr ( tok_column , ' : ' ) ) )
{
* custom_sepa = ' \0 ' ; /* XXX, C abuse: discarding-const */
columns_fmt [ i ] = COL_CUSTOM ;
columns_custom [ i ] = tok_column ;
if ( ! ws_strtoi16 ( custom_sepa + 1 , NULL , & columns_occur [ i ] ) )
return NULL ;
}
else
{
if ( ! ws_strtou16 ( tok_column , NULL , & columns_fmt [ i ] ) )
return NULL ;
if ( columns_fmt [ i ] > = NUM_COL_FMTS )
return NULL ;
/* if custom, that it shouldn't be just custom number -> error */
if ( columns_fmt [ i ] = = COL_CUSTOM )
return NULL ;
}
}
cols = i ;
col_setup ( cinfo , cols ) ;
for ( i = 0 ; i < cols ; i + + )
{
col_item_t * col_item = & cinfo - > columns [ i ] ;
col_item - > col_fmt = columns_fmt [ i ] ;
col_item - > col_title = NULL ; /* no need for title */
if ( col_item - > col_fmt = = COL_CUSTOM )
{
col_item - > col_custom_fields = g_strdup ( columns_custom [ i ] ) ;
col_item - > col_custom_occurrence = columns_occur [ i ] ;
}
col_item - > col_fence = 0 ;
}
col_finalize ( cinfo ) ;
return cinfo ;
}
2016-10-15 18:48:17 +00:00
/**
* sharkd_session_process_frames ( )
*
* Process frames request
*
* Input :
2017-09-27 20:24:54 +00:00
* ( o ) column0 . . . columnXX - requested columns either number in range [ 0. . NUM_COL_FMTS ) , or custom ( syntax < dfilter > : < occurence > ) .
* If column0 is not specified default column set will be used .
2016-10-15 18:48:17 +00:00
* ( o ) filter - filter to be used
2017-03-26 15:06:04 +00:00
* ( o ) skip = N - skip N frames
* ( o ) limit = N - show only N frames
2017-12-28 12:07:54 +00:00
* ( o ) refs - list ( comma separated ) with sorted time reference frame numbers .
2016-10-15 18:48:17 +00:00
*
* Output array of frames with attributes :
* ( m ) c - array of column data
* ( m ) num - frame number
2017-09-26 21:42:20 +00:00
* ( o ) i - if frame is ignored
* ( o ) m - if frame is marked
* ( o ) ct - if frame is commented
* ( o ) bg - color filter - background color in hex
* ( o ) fg - color filter - foreground color in hex
2016-10-15 18:48:17 +00:00
*/
static void
sharkd_session_process_frames ( const char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_filter = json_find_attr ( buf , tokens , count , " filter " ) ;
2017-09-27 20:24:54 +00:00
const char * tok_column = json_find_attr ( buf , tokens , count , " column0 " ) ;
2017-03-26 15:06:04 +00:00
const char * tok_skip = json_find_attr ( buf , tokens , count , " skip " ) ;
const char * tok_limit = json_find_attr ( buf , tokens , count , " limit " ) ;
2017-12-28 12:07:54 +00:00
const char * tok_refs = json_find_attr ( buf , tokens , count , " refs " ) ;
2016-10-15 18:48:17 +00:00
const guint8 * filter_data = NULL ;
int col ;
2017-12-28 12:07:54 +00:00
guint32 framenum , prev_dis_num = 0 ;
guint32 current_ref_frame = 0 , next_ref_frame = G_MAXUINT32 ;
2017-03-26 15:06:04 +00:00
guint32 skip ;
guint32 limit ;
2016-10-15 18:48:17 +00:00
column_info * cinfo = & cfile . cinfo ;
2017-09-27 20:24:54 +00:00
column_info user_cinfo ;
if ( tok_column )
{
memset ( & user_cinfo , 0 , sizeof ( user_cinfo ) ) ;
cinfo = sharkd_session_create_columns ( & user_cinfo , buf , tokens , count ) ;
if ( ! cinfo )
return ;
}
2016-10-15 18:48:17 +00:00
if ( tok_filter )
{
2018-09-01 16:47:38 +00:00
const struct sharkd_filter_item * filter_item ;
filter_item = sharkd_session_filter_data ( tok_filter ) ;
if ( ! filter_item )
2016-10-15 18:48:17 +00:00
return ;
2018-09-01 16:47:38 +00:00
filter_data = filter_item - > filtered ;
2016-10-15 18:48:17 +00:00
}
2017-03-26 15:06:04 +00:00
skip = 0 ;
if ( tok_skip )
{
if ( ! ws_strtou32 ( tok_skip , NULL , & skip ) )
return ;
}
limit = 0 ;
if ( tok_limit )
{
if ( ! ws_strtou32 ( tok_limit , NULL , & limit ) )
return ;
}
2017-12-28 12:07:54 +00:00
if ( tok_refs )
{
if ( ! ws_strtou32 ( tok_refs , & tok_refs , & next_ref_frame ) )
return ;
}
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( NULL ) ;
2016-10-15 18:48:17 +00:00
for ( framenum = 1 ; framenum < = cfile . count ; framenum + + )
{
2017-12-07 20:56:11 +00:00
frame_data * fdata ;
2017-12-28 12:07:54 +00:00
guint32 ref_frame = ( framenum ! = 1 ) ? 1 : 0 ;
2016-10-15 18:48:17 +00:00
if ( filter_data & & ! ( filter_data [ framenum / 8 ] & ( 1 < < ( framenum % 8 ) ) ) )
continue ;
2017-03-26 15:06:04 +00:00
if ( skip )
{
skip - - ;
2017-12-28 12:07:54 +00:00
prev_dis_num = framenum ;
2017-03-26 15:06:04 +00:00
continue ;
}
2017-12-28 12:07:54 +00:00
if ( tok_refs )
{
if ( framenum > = next_ref_frame )
{
current_ref_frame = next_ref_frame ;
if ( * tok_refs ! = ' , ' )
next_ref_frame = G_MAXUINT32 ;
2017-12-07 20:56:11 +00:00
2017-12-28 12:07:54 +00:00
while ( * tok_refs = = ' , ' & & framenum > = next_ref_frame )
{
current_ref_frame = next_ref_frame ;
if ( ! ws_strtou32 ( tok_refs + 1 , & tok_refs , & next_ref_frame ) )
{
fprintf ( stderr , " sharkd_session_process_frames() wrong format for refs: %s \n " , tok_refs ) ;
break ;
}
}
2018-09-24 07:56:16 +00:00
if ( * tok_refs = = ' \0 ' & & framenum > = next_ref_frame )
{
current_ref_frame = next_ref_frame ;
next_ref_frame = G_MAXUINT32 ;
}
2017-12-28 12:07:54 +00:00
}
if ( current_ref_frame )
ref_frame = current_ref_frame ;
}
fdata = sharkd_get_frame ( framenum ) ;
sharkd_dissect_columns ( fdata , ref_frame , prev_dis_num , cinfo , ( fdata - > color_filter = = NULL ) ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " c " ) ;
2016-10-15 18:48:17 +00:00
for ( col = 0 ; col < cinfo - > num_cols ; + + col )
{
const col_item_t * col_item = & cinfo - > columns [ col ] ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( NULL , col_item - > col_data ) ;
2016-10-15 18:48:17 +00:00
}
2018-09-25 17:20:54 +00:00
sharkd_json_array_close ( ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " num " , " %u " , framenum ) ;
2016-10-15 18:48:17 +00:00
2018-12-27 02:26:24 +00:00
if ( fdata - > has_user_comment | | fdata - > has_phdr_comment )
2017-12-06 18:51:18 +00:00
{
2018-12-27 02:26:24 +00:00
if ( ! fdata - > has_user_comment | | sharkd_get_user_comment ( fdata ) ! = NULL )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " ct " , " true " ) ;
2017-12-06 18:51:18 +00:00
}
2017-09-26 21:42:20 +00:00
2018-12-27 02:26:24 +00:00
if ( fdata - > ignored )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " i " , " true " ) ;
2016-10-15 18:48:17 +00:00
2018-12-27 02:26:24 +00:00
if ( fdata - > marked )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " m " , " true " ) ;
2016-10-15 18:48:17 +00:00
if ( fdata - > color_filter )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_stringf ( " bg " , " %x " , color_t_to_rgb ( & fdata - > color_filter - > bg_color ) ) ;
sharkd_json_value_stringf ( " fg " , " %x " , color_t_to_rgb ( & fdata - > color_filter - > fg_color ) ) ;
2016-10-15 18:48:17 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-12-28 12:07:54 +00:00
prev_dis_num = framenum ;
2017-03-26 15:06:04 +00:00
if ( limit & & - - limit = = 0 )
break ;
2016-10-15 18:48:17 +00:00
}
2018-09-25 17:20:54 +00:00
sharkd_json_array_close ( ) ;
2018-12-12 14:33:44 +00:00
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
if ( cinfo ! = & cfile . cinfo )
col_cleanup ( cinfo ) ;
}
static void
sharkd_session_process_tap_stats_node_cb ( const stat_node * n )
{
stat_node * node ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( NULL ) ;
2016-10-15 18:48:17 +00:00
for ( node = n - > children ; node ; node = node - > next )
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2016-10-15 18:48:17 +00:00
/* code based on stats_tree_get_values_from_node() */
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " name " , node - > name ) ;
sharkd_json_value_anyf ( " count " , " %d " , node - > counter ) ;
2016-10-15 18:48:17 +00:00
if ( node - > counter & & ( ( node - > st_flags & ST_FLG_AVERAGE ) | | node - > rng ) )
{
2018-12-27 19:47:02 +00:00
switch ( node - > datatype )
{
case STAT_DT_INT :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " avg " , " %.2f " , ( ( float ) node - > total . int_total ) / node - > counter ) ;
sharkd_json_value_anyf ( " min " , " %d " , node - > minvalue . int_min ) ;
sharkd_json_value_anyf ( " max " , " %d " , node - > maxvalue . int_max ) ;
2018-12-27 19:47:02 +00:00
break ;
case STAT_DT_FLOAT :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " avg " , " %.2f " , node - > total . float_total / node - > counter ) ;
sharkd_json_value_anyf ( " min " , " %f " , node - > minvalue . float_min ) ;
sharkd_json_value_anyf ( " max " , " %f " , node - > maxvalue . float_max ) ;
2018-12-27 19:47:02 +00:00
break ;
}
2016-10-15 18:48:17 +00:00
}
if ( node - > st - > elapsed )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " rate " , " %.4f " , ( ( float ) node - > counter ) / node - > st - > elapsed ) ;
2016-10-15 18:48:17 +00:00
if ( node - > parent & & node - > parent - > counter )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " perc " , " %.2f " , ( node - > counter * 100.0 ) / node - > parent - > counter ) ;
2016-10-15 18:48:17 +00:00
else if ( node - > parent = = & ( node - > st - > root ) )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " perc " , " 100 " ) ;
2016-10-15 18:48:17 +00:00
if ( prefs . st_enable_burstinfo & & node - > max_burst )
{
if ( prefs . st_burst_showcount )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " burstcount " , " %d " , node - > max_burst ) ;
2016-10-15 18:48:17 +00:00
else
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " burstrate " , " %.4f " , ( ( double ) node - > max_burst ) / prefs . st_burst_windowlen ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " bursttime " , " %.3f " , ( node - > burst_time / 1000.0 ) ) ;
2016-10-15 18:48:17 +00:00
}
if ( node - > children )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " sub " , NULL ) ;
2016-10-15 18:48:17 +00:00
sharkd_session_process_tap_stats_node_cb ( node ) ;
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
}
/**
* sharkd_session_process_tap_stats_cb ( )
*
* Output stats tap :
*
* ( m ) tap - tap name
* ( m ) type : stats - tap output type
* ( m ) name - stat name
* ( m ) stats - array of object with attributes :
* ( m ) name - stat item name
* ( m ) count - stat item counter
* ( o ) avg - stat item averange value
* ( o ) min - stat item min value
* ( o ) max - stat item max value
* ( o ) rate - stat item rate value ( ms )
* ( o ) perc - stat item percentage
* ( o ) burstrate - stat item burst rate
* ( o ) burstcount - stat item burst count
* ( o ) burstttme - stat item burst start
* ( o ) sub - array of object with attributes like in stats node .
*/
static void
sharkd_session_process_tap_stats_cb ( void * psp )
{
2017-03-12 08:23:17 +00:00
stats_tree * st = ( stats_tree * ) psp ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_stringf ( " tap " , " stats:%s " , st - > cfg - > abbr ) ;
sharkd_json_value_string ( " type " , " stats " ) ;
sharkd_json_value_string ( " name " , st - > cfg - > name ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " stats " , NULL ) ;
2016-10-15 18:48:17 +00:00
sharkd_session_process_tap_stats_node_cb ( & st - > root ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
2017-03-12 08:23:17 +00:00
static void
sharkd_session_free_tap_stats_cb ( void * psp )
{
stats_tree * st = ( stats_tree * ) psp ;
stats_tree_free ( st ) ;
}
2017-03-17 06:59:05 +00:00
struct sharkd_expert_tap
{
GSList * details ;
GStringChunk * text ;
} ;
/**
* sharkd_session_process_tap_expert_cb ( )
*
* Output expert tap :
*
* ( m ) tap - tap name
* ( m ) type : expert - tap output type
* ( m ) details - array of object with attributes :
* ( m ) f - frame number , which generated expert information
* ( o ) s - severity
* ( o ) g - group
* ( m ) m - expert message
* ( o ) p - protocol
*/
static void
sharkd_session_process_tap_expert_cb ( void * tapdata )
{
struct sharkd_expert_tap * etd = ( struct sharkd_expert_tap * ) tapdata ;
GSList * list ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " tap " , " expert " ) ;
sharkd_json_value_string ( " type " , " expert " ) ;
2017-03-17 06:59:05 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " details " ) ;
2017-03-17 06:59:05 +00:00
for ( list = etd - > details ; list ; list = list - > next )
{
expert_info_t * ei = ( expert_info_t * ) list - > data ;
const char * tmp ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-17 06:59:05 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " f " , " %u " , ei - > packet_num ) ;
2017-03-17 06:59:05 +00:00
tmp = try_val_to_str ( ei - > severity , expert_severity_vals ) ;
if ( tmp )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , tmp ) ;
2017-03-17 06:59:05 +00:00
tmp = try_val_to_str ( ei - > group , expert_group_vals ) ;
if ( tmp )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " g " , tmp ) ;
2017-03-17 06:59:05 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " m " , ei - > summary ) ;
2017-03-17 06:59:05 +00:00
if ( ei - > protocol )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " p " , ei - > protocol ) ;
2017-03-17 06:59:05 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-17 06:59:05 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-03-17 06:59:05 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-17 06:59:05 +00:00
}
2019-01-01 03:36:12 +00:00
static tap_packet_status
2017-03-17 06:59:05 +00:00
sharkd_session_packet_tap_expert_cb ( void * tapdata , packet_info * pinfo _U_ , epan_dissect_t * edt _U_ , const void * pointer )
{
struct sharkd_expert_tap * etd = ( struct sharkd_expert_tap * ) tapdata ;
2018-01-18 19:29:36 +00:00
const expert_info_t * ei = ( const expert_info_t * ) pointer ;
expert_info_t * ei_copy ;
2017-03-17 06:59:05 +00:00
2018-01-19 18:06:10 +00:00
if ( ei = = NULL )
2019-01-01 03:36:12 +00:00
return TAP_PACKET_DONT_REDRAW ;
2018-01-16 11:43:34 +00:00
2018-01-19 18:06:10 +00:00
ei_copy = g_new ( expert_info_t , 1 ) ;
/* Note: this is a shallow copy */
* ei_copy = * ei ;
/* ei->protocol, ei->summary might be allocated in packet scope, make a copy. */
2018-01-18 19:29:36 +00:00
ei_copy - > protocol = g_string_chunk_insert_const ( etd - > text , ei_copy - > protocol ) ;
ei_copy - > summary = g_string_chunk_insert_const ( etd - > text , ei_copy - > summary ) ;
2017-03-17 06:59:05 +00:00
2018-01-18 19:29:36 +00:00
etd - > details = g_slist_prepend ( etd - > details , ei_copy ) ;
2017-03-17 06:59:05 +00:00
2019-01-01 03:36:12 +00:00
return TAP_PACKET_REDRAW ;
2017-03-17 06:59:05 +00:00
}
static void
sharkd_session_free_tap_expert_cb ( void * tapdata )
{
struct sharkd_expert_tap * etd = ( struct sharkd_expert_tap * ) tapdata ;
g_slist_free_full ( etd - > details , g_free ) ;
g_string_chunk_free ( etd - > text ) ;
g_free ( etd ) ;
}
2017-09-16 15:46:15 +00:00
/**
* sharkd_session_process_tap_flow_cb ( )
*
* Output flow tap :
* ( m ) tap - tap name
* ( m ) type : flow - tap output type
* ( m ) nodes - array of strings with node address
* ( m ) flows - array of object with attributes :
* ( m ) t - frame time string
* ( m ) n - array of two numbers with source node index and destination node index
* ( m ) pn - array of two numbers with source and destination port
* ( o ) c - comment
*/
static void
sharkd_session_process_tap_flow_cb ( void * tapdata )
{
seq_analysis_info_t * graph_analysis = ( seq_analysis_info_t * ) tapdata ;
GList * flow_list ;
guint i ;
sequence_analysis_get_nodes ( graph_analysis ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " tap " , " seqa:%s " , graph_analysis - > name ) ;
sharkd_json_value_string ( " type " , " flow " ) ;
2017-09-16 15:46:15 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " nodes " ) ;
2017-09-16 15:46:15 +00:00
for ( i = 0 ; i < graph_analysis - > num_nodes ; i + + )
{
char * addr_str ;
addr_str = address_to_display ( NULL , & ( graph_analysis - > nodes [ i ] ) ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( NULL , addr_str ) ;
2017-09-16 15:46:15 +00:00
wmem_free ( NULL , addr_str ) ;
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-09-16 15:46:15 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " flows " ) ;
2017-09-16 15:46:15 +00:00
flow_list = g_queue_peek_nth_link ( graph_analysis - > items , 0 ) ;
while ( flow_list )
{
seq_analysis_item_t * sai = ( seq_analysis_item_t * ) flow_list - > data ;
flow_list = g_list_next ( flow_list ) ;
if ( ! sai - > display )
continue ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-09-16 15:46:15 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " t " , sai - > time_str ) ;
sharkd_json_value_anyf ( " n " , " [%u,%u] " , sai - > src_node , sai - > dst_node ) ;
sharkd_json_value_anyf ( " pn " , " [%u,%u] " , sai - > port_src , sai - > port_dst ) ;
2017-09-16 15:46:15 +00:00
if ( sai - > comment )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " c " , sai - > comment ) ;
2017-09-16 15:46:15 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-09-16 15:46:15 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-09-16 15:46:15 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-09-16 15:46:15 +00:00
}
static void
sharkd_session_free_tap_flow_cb ( void * tapdata )
{
seq_analysis_info_t * graph_analysis = ( seq_analysis_info_t * ) tapdata ;
sequence_analysis_info_free ( graph_analysis ) ;
}
2016-10-15 18:48:17 +00:00
struct sharkd_conv_tap_data
{
const char * type ;
conv_hash_t hash ;
gboolean resolve_name ;
gboolean resolve_port ;
} ;
2018-03-12 15:38:35 +00:00
static gboolean
2016-10-15 18:48:17 +00:00
sharkd_session_geoip_addr ( address * addr , const char * suffix )
{
2018-03-12 15:38:35 +00:00
const mmdb_lookup_t * lookup = NULL ;
gboolean with_geoip = FALSE ;
2018-09-25 17:20:54 +00:00
char json_key [ 64 ] ;
2016-10-15 18:48:17 +00:00
if ( addr - > type = = AT_IPv4 )
{
2019-02-09 22:25:17 +00:00
const ws_in4_addr * ip4 = ( const ws_in4_addr * ) addr - > data ;
2016-10-15 18:48:17 +00:00
2019-02-09 22:25:17 +00:00
lookup = maxmind_db_lookup_ipv4 ( ip4 ) ;
2018-03-12 15:38:35 +00:00
}
else if ( addr - > type = = AT_IPv6 )
{
const ws_in6_addr * ip6 = ( const ws_in6_addr * ) addr - > data ;
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
lookup = maxmind_db_lookup_ipv6 ( ip6 ) ;
}
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
if ( ! lookup | | ! lookup - > found )
return FALSE ;
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
if ( lookup - > country )
{
2018-09-25 17:20:54 +00:00
snprintf ( json_key , sizeof ( json_key ) , " geoip_country%s " , suffix ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( json_key , lookup - > country ) ;
2018-03-12 15:38:35 +00:00
with_geoip = TRUE ;
2016-10-15 18:48:17 +00:00
}
2018-03-12 15:38:35 +00:00
if ( lookup - > country_iso )
2016-10-15 18:48:17 +00:00
{
2018-09-25 17:20:54 +00:00
snprintf ( json_key , sizeof ( json_key ) , " geoip_country_iso%s " , suffix ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( json_key , lookup - > country_iso ) ;
2018-03-12 15:38:35 +00:00
with_geoip = TRUE ;
}
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
if ( lookup - > city )
{
2018-09-25 17:20:54 +00:00
snprintf ( json_key , sizeof ( json_key ) , " geoip_city%s " , suffix ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( json_key , lookup - > city ) ;
2018-03-12 15:38:35 +00:00
with_geoip = TRUE ;
}
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
if ( lookup - > as_org )
{
2018-09-25 17:20:54 +00:00
snprintf ( json_key , sizeof ( json_key ) , " geoip_as_org%s " , suffix ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( json_key , lookup - > as_org ) ;
2018-03-12 15:38:35 +00:00
with_geoip = TRUE ;
}
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
if ( lookup - > as_number > 0 )
{
2018-09-25 17:20:54 +00:00
snprintf ( json_key , sizeof ( json_key ) , " geoip_as%s " , suffix ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( json_key , " %u " , lookup - > as_number ) ;
2018-03-12 15:38:35 +00:00
with_geoip = TRUE ;
}
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
if ( lookup - > latitude > = - 90.0 & & lookup - > latitude < = 90.0 )
{
2018-09-25 17:20:54 +00:00
snprintf ( json_key , sizeof ( json_key ) , " geoip_lat%s " , suffix ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( json_key , " %f " , lookup - > latitude ) ;
2018-03-12 15:38:35 +00:00
with_geoip = TRUE ;
}
2016-10-15 18:48:17 +00:00
2018-03-12 15:38:35 +00:00
if ( lookup - > longitude > = - 180.0 & & lookup - > longitude < = 180.0 )
{
2018-09-25 17:20:54 +00:00
snprintf ( json_key , sizeof ( json_key ) , " geoip_lon%s " , suffix ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( json_key , " %f " , lookup - > longitude ) ;
2018-03-12 15:38:35 +00:00
with_geoip = TRUE ;
2016-10-15 18:48:17 +00:00
}
2017-03-12 08:23:17 +00:00
2016-10-15 18:48:17 +00:00
return with_geoip ;
}
2017-03-31 18:35:51 +00:00
struct sharkd_analyse_rtp_items
{
guint32 frame_num ;
guint32 sequence_num ;
double delta ;
double jitter ;
double skew ;
double bandwidth ;
gboolean marker ;
double arrive_offset ;
/* from tap_rtp_stat_t */
guint32 flags ;
guint16 pt ;
} ;
struct sharkd_analyse_rtp
{
const char * tap_name ;
2018-06-15 20:47:47 +00:00
rtpstream_id_t id ;
2017-03-31 18:35:51 +00:00
GSList * packets ;
double start_time ;
tap_rtp_stat_t statinfo ;
} ;
static void
sharkd_session_process_tap_rtp_free_cb ( void * tapdata )
{
struct sharkd_analyse_rtp * rtp_req = ( struct sharkd_analyse_rtp * ) tapdata ;
g_slist_free_full ( rtp_req - > packets , g_free ) ;
g_free ( rtp_req ) ;
}
2019-01-01 03:36:12 +00:00
static tap_packet_status
2017-03-31 18:35:51 +00:00
sharkd_session_packet_tap_rtp_analyse_cb ( void * tapdata , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * pointer )
{
struct sharkd_analyse_rtp * rtp_req = ( struct sharkd_analyse_rtp * ) tapdata ;
2018-06-15 20:47:47 +00:00
const struct _rtp_info * rtp_info = ( const struct _rtp_info * ) pointer ;
2017-03-31 18:35:51 +00:00
2018-06-15 20:47:47 +00:00
if ( rtpstream_id_equal_pinfo_rtp_info ( & rtp_req - > id , pinfo , rtp_info ) )
2017-03-31 18:35:51 +00:00
{
tap_rtp_stat_t * statinfo = & ( rtp_req - > statinfo ) ;
struct sharkd_analyse_rtp_items * item ;
2018-06-15 20:47:47 +00:00
rtppacket_analyse ( statinfo , pinfo , rtp_info ) ;
2017-03-31 18:35:51 +00:00
item = ( struct sharkd_analyse_rtp_items * ) g_malloc ( sizeof ( struct sharkd_analyse_rtp_items ) ) ;
if ( ! rtp_req - > packets )
rtp_req - > start_time = nstime_to_sec ( & pinfo - > abs_ts ) ;
item - > frame_num = pinfo - > num ;
2018-06-15 20:47:47 +00:00
item - > sequence_num = rtp_info - > info_seq_num ;
2017-03-31 18:35:51 +00:00
item - > delta = ( statinfo - > flags & STAT_FLAG_FIRST ) ? 0.0 : statinfo - > delta ;
item - > jitter = ( statinfo - > flags & STAT_FLAG_FIRST ) ? 0.0 : statinfo - > jitter ;
item - > skew = ( statinfo - > flags & STAT_FLAG_FIRST ) ? 0.0 : statinfo - > skew ;
item - > bandwidth = statinfo - > bandwidth ;
2018-06-15 20:47:47 +00:00
item - > marker = rtp_info - > info_marker_set ? TRUE : FALSE ;
2017-03-31 18:35:51 +00:00
item - > arrive_offset = nstime_to_sec ( & pinfo - > abs_ts ) - rtp_req - > start_time ;
item - > flags = statinfo - > flags ;
item - > pt = statinfo - > pt ;
/* XXX, O(n) optimize */
rtp_req - > packets = g_slist_append ( rtp_req - > packets , item ) ;
}
2019-01-01 03:36:12 +00:00
return TAP_PACKET_REDRAW ;
2017-03-31 18:35:51 +00:00
}
/**
* sharkd_session_process_tap_rtp_analyse_cb ( )
*
* Output rtp analyse tap :
* ( m ) tap - tap name
* ( m ) type - tap output type
* ( m ) ssrc - RTP SSRC
* ( m ) max_delta - Max delta ( ms )
* ( m ) max_delta_nr - Max delta packet #
* ( m ) max_jitter - Max jitter ( ms )
* ( m ) mean_jitter - Mean jitter ( ms )
* ( m ) max_skew - Max skew ( ms )
* ( m ) total_nr - Total number of RTP packets
* ( m ) seq_err - Number of sequence errors
* ( m ) duration - Duration ( ms )
* ( m ) items - array of object with attributes :
* ( m ) f - frame number
* ( m ) o - arrive offset
* ( m ) sn - sequence number
* ( m ) d - delta
* ( m ) j - jitter
* ( m ) sk - skew
* ( m ) bw - bandwidth
* ( o ) s - status string
* ( o ) t - status type
* ( o ) mark - rtp mark
*/
static void
sharkd_session_process_tap_rtp_analyse_cb ( void * tapdata )
{
const int RTP_TYPE_CN = 1 ;
const int RTP_TYPE_ERROR = 2 ;
const int RTP_TYPE_WARN = 3 ;
const int RTP_TYPE_PT_EVENT = 4 ;
const struct sharkd_analyse_rtp * rtp_req = ( struct sharkd_analyse_rtp * ) tapdata ;
const tap_rtp_stat_t * statinfo = & rtp_req - > statinfo ;
GSList * l ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-31 18:35:51 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " tap " , rtp_req - > tap_name ) ;
sharkd_json_value_string ( " type " , " rtp-analyse " ) ;
sharkd_json_value_anyf ( " ssrc " , " %u " , rtp_req - > id . ssrc ) ;
2017-03-31 18:35:51 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " max_delta " , " %f " , statinfo - > max_delta ) ;
sharkd_json_value_anyf ( " max_delta_nr " , " %u " , statinfo - > max_nr ) ;
sharkd_json_value_anyf ( " max_jitter " , " %f " , statinfo - > max_jitter ) ;
sharkd_json_value_anyf ( " mean_jitter " , " %f " , statinfo - > mean_jitter ) ;
sharkd_json_value_anyf ( " max_skew " , " %f " , statinfo - > max_skew ) ;
sharkd_json_value_anyf ( " total_nr " , " %u " , statinfo - > total_nr ) ;
sharkd_json_value_anyf ( " seq_err " , " %u " , statinfo - > sequence ) ;
sharkd_json_value_anyf ( " duration " , " %f " , statinfo - > time - statinfo - > start_time ) ;
2017-03-31 18:35:51 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " items " ) ;
2017-03-31 18:35:51 +00:00
for ( l = rtp_req - > packets ; l ; l = l - > next )
{
struct sharkd_analyse_rtp_items * item = ( struct sharkd_analyse_rtp_items * ) l - > data ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-31 18:35:51 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " f " , " %u " , item - > frame_num ) ;
sharkd_json_value_anyf ( " o " , " %.9f " , item - > arrive_offset ) ;
sharkd_json_value_anyf ( " sn " , " %u " , item - > sequence_num ) ;
sharkd_json_value_anyf ( " d " , " %.2f " , item - > delta ) ;
sharkd_json_value_anyf ( " j " , " %.2f " , item - > jitter ) ;
sharkd_json_value_anyf ( " sk " , " %.2f " , item - > skew ) ;
sharkd_json_value_anyf ( " bw " , " %.2f " , item - > bandwidth ) ;
2017-03-31 18:35:51 +00:00
if ( item - > pt = = PT_CN )
2018-09-25 17:20:54 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , " Comfort noise (PT=13, RFC 3389) " ) ;
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_CN ) ;
2018-09-25 17:20:54 +00:00
}
2017-03-31 18:35:51 +00:00
else if ( item - > pt = = PT_CN_OLD )
2018-09-25 17:20:54 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , " Comfort noise (PT=19, reserved) " ) ;
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_CN ) ;
2018-09-25 17:20:54 +00:00
}
2017-03-31 18:35:51 +00:00
else if ( item - > flags & STAT_FLAG_WRONG_SEQ )
2018-09-25 17:20:54 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , " Wrong sequence number " ) ;
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_ERROR ) ;
2018-09-25 17:20:54 +00:00
}
2017-03-31 18:35:51 +00:00
else if ( item - > flags & STAT_FLAG_DUP_PKT )
2018-09-25 17:20:54 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , " Suspected duplicate (MAC address) only delta time calculated " ) ;
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_WARN ) ;
2018-09-25 17:20:54 +00:00
}
2017-03-31 18:35:51 +00:00
else if ( item - > flags & STAT_FLAG_REG_PT_CHANGE )
2018-09-25 17:20:54 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_stringf ( " s " , " Payload changed to PT=%u%s " ,
2017-03-31 18:35:51 +00:00
item - > pt ,
2018-09-25 17:20:54 +00:00
( item - > flags & STAT_FLAG_PT_T_EVENT ) ? " telephone/event " : " " ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_WARN ) ;
2018-09-25 17:20:54 +00:00
}
2017-03-31 18:35:51 +00:00
else if ( item - > flags & STAT_FLAG_WRONG_TIMESTAMP )
2018-09-25 17:20:54 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , " Incorrect timestamp " ) ;
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_WARN ) ;
2018-09-25 17:20:54 +00:00
}
2017-03-31 18:35:51 +00:00
else if ( ( item - > flags & STAT_FLAG_PT_CHANGE )
& & ! ( item - > flags & STAT_FLAG_FIRST )
& & ! ( item - > flags & STAT_FLAG_PT_CN )
& & ( item - > flags & STAT_FLAG_FOLLOW_PT_CN )
& & ! ( item - > flags & STAT_FLAG_MARKER ) )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , " Marker missing? " ) ;
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_WARN ) ;
2017-03-31 18:35:51 +00:00
}
else if ( item - > flags & STAT_FLAG_PT_T_EVENT )
2018-09-25 17:20:54 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_stringf ( " s " , " PT=%u telephone/event " , item - > pt ) ;
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_PT_EVENT ) ;
2018-09-25 17:20:54 +00:00
}
2017-03-31 18:35:51 +00:00
else if ( item - > flags & STAT_FLAG_MARKER )
2018-09-25 17:20:54 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " t " , " %d " , RTP_TYPE_WARN ) ;
2018-09-25 17:20:54 +00:00
}
2017-03-31 18:35:51 +00:00
if ( item - > marker )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " mark " , " 1 " ) ;
2017-03-31 18:35:51 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-31 18:35:51 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-03-31 18:35:51 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-31 18:35:51 +00:00
}
2016-10-15 18:48:17 +00:00
/**
* sharkd_session_process_tap_conv_cb ( )
*
* Output conv tap :
* ( m ) tap - tap name
* ( m ) type - tap output type
* ( m ) proto - protocol short name
* ( o ) filter - filter string
2018-11-20 15:22:46 +00:00
* ( o ) geoip - whether GeoIP information is available , boolean
2016-10-15 18:48:17 +00:00
*
* ( o ) convs - array of object with attributes :
* ( m ) saddr - source address
* ( m ) daddr - destination address
* ( o ) sport - source port
* ( o ) dport - destination port
* ( m ) txf - TX frame count
* ( m ) txb - TX bytes
* ( m ) rxf - RX frame count
* ( m ) rxb - RX bytes
* ( m ) start - ( relative ) first packet time
* ( m ) stop - ( relative ) last packet time
2018-11-20 15:22:46 +00:00
* ( o ) filter - conversation filter
2016-10-15 18:48:17 +00:00
*
* ( o ) hosts - array of object with attributes :
* ( m ) host - host address
* ( o ) port - host port
* ( m ) txf - TX frame count
* ( m ) txb - TX bytes
* ( m ) rxf - RX frame count
* ( m ) rxb - RX bytes
*/
static void
sharkd_session_process_tap_conv_cb ( void * arg )
{
conv_hash_t * hash = ( conv_hash_t * ) arg ;
const struct sharkd_conv_tap_data * iu = ( struct sharkd_conv_tap_data * ) hash - > user_data ;
const char * proto ;
int proto_with_port ;
guint i ;
int with_geoip = 0 ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " tap " , iu - > type ) ;
2018-09-25 17:20:54 +00:00
2016-10-15 18:48:17 +00:00
if ( ! strncmp ( iu - > type , " conv: " , 5 ) )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " type " , " conv " ) ;
sharkd_json_array_open ( " convs " ) ;
2016-10-15 18:48:17 +00:00
proto = iu - > type + 5 ;
}
else if ( ! strncmp ( iu - > type , " endpt: " , 6 ) )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " type " , " host " ) ;
sharkd_json_array_open ( " hosts " ) ;
2016-10-15 18:48:17 +00:00
proto = iu - > type + 6 ;
}
else
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " type " , " err " ) ;
2016-10-15 18:48:17 +00:00
proto = " " ;
}
proto_with_port = ( ! strcmp ( proto , " TCP " ) | | ! strcmp ( proto , " UDP " ) | | ! strcmp ( proto , " SCTP " ) ) ;
if ( iu - > hash . conv_array ! = NULL & & ! strncmp ( iu - > type , " conv: " , 5 ) )
{
for ( i = 0 ; i < iu - > hash . conv_array - > len ; i + + )
{
conv_item_t * iui = & g_array_index ( iu - > hash . conv_array , conv_item_t , i ) ;
char * src_addr , * dst_addr ;
char * src_port , * dst_port ;
char * filter_str ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " saddr " , ( src_addr = get_conversation_address ( NULL , & iui - > src_address , iu - > resolve_name ) ) ) ;
sharkd_json_value_string ( " daddr " , ( dst_addr = get_conversation_address ( NULL , & iui - > dst_address , iu - > resolve_name ) ) ) ;
2016-10-15 18:48:17 +00:00
if ( proto_with_port )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " sport " , ( src_port = get_conversation_port ( NULL , iui - > src_port , iui - > etype , iu - > resolve_port ) ) ) ;
sharkd_json_value_string ( " dport " , ( dst_port = get_conversation_port ( NULL , iui - > dst_port , iui - > etype , iu - > resolve_port ) ) ) ;
2016-10-15 18:48:17 +00:00
wmem_free ( NULL , src_port ) ;
wmem_free ( NULL , dst_port ) ;
}
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " rxf " , " % " G_GUINT64_FORMAT , iui - > rx_frames ) ;
sharkd_json_value_anyf ( " rxb " , " % " G_GUINT64_FORMAT , iui - > rx_bytes ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " txf " , " % " G_GUINT64_FORMAT , iui - > tx_frames ) ;
sharkd_json_value_anyf ( " txb " , " % " G_GUINT64_FORMAT , iui - > tx_bytes ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " start " , " %.9f " , nstime_to_sec ( & iui - > start_time ) ) ;
sharkd_json_value_anyf ( " stop " , " %.9f " , nstime_to_sec ( & iui - > stop_time ) ) ;
2016-10-15 18:48:17 +00:00
filter_str = get_conversation_filter ( iui , CONV_DIR_A_TO_FROM_B ) ;
if ( filter_str )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " filter " , filter_str ) ;
2016-10-15 18:48:17 +00:00
g_free ( filter_str ) ;
}
wmem_free ( NULL , src_addr ) ;
wmem_free ( NULL , dst_addr ) ;
if ( sharkd_session_geoip_addr ( & ( iui - > src_address ) , " 1 " ) )
with_geoip = 1 ;
if ( sharkd_session_geoip_addr ( & ( iui - > dst_address ) , " 2 " ) )
with_geoip = 1 ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
}
else if ( iu - > hash . conv_array ! = NULL & & ! strncmp ( iu - > type , " endpt: " , 6 ) )
{
for ( i = 0 ; i < iu - > hash . conv_array - > len ; i + + )
{
hostlist_talker_t * host = & g_array_index ( iu - > hash . conv_array , hostlist_talker_t , i ) ;
char * host_str , * port_str ;
char * filter_str ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " host " , ( host_str = get_conversation_address ( NULL , & host - > myaddress , iu - > resolve_name ) ) ) ;
2016-10-15 18:48:17 +00:00
if ( proto_with_port )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " port " , ( port_str = get_conversation_port ( NULL , host - > port , host - > etype , iu - > resolve_port ) ) ) ;
2016-10-15 18:48:17 +00:00
wmem_free ( NULL , port_str ) ;
}
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " rxf " , " % " G_GUINT64_FORMAT , host - > rx_frames ) ;
sharkd_json_value_anyf ( " rxb " , " % " G_GUINT64_FORMAT , host - > rx_bytes ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " txf " , " % " G_GUINT64_FORMAT , host - > tx_frames ) ;
sharkd_json_value_anyf ( " txb " , " % " G_GUINT64_FORMAT , host - > tx_bytes ) ;
2016-10-15 18:48:17 +00:00
filter_str = get_hostlist_filter ( host ) ;
if ( filter_str )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " filter " , filter_str ) ;
2016-10-15 18:48:17 +00:00
g_free ( filter_str ) ;
}
wmem_free ( NULL , host_str ) ;
if ( sharkd_session_geoip_addr ( & ( host - > myaddress ) , " " ) )
with_geoip = 1 ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
}
2018-09-25 17:20:54 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " proto " , proto ) ;
sharkd_json_value_anyf ( " geoip " , with_geoip ? " true " : " false " ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
2017-03-12 08:23:17 +00:00
static void
sharkd_session_free_tap_conv_cb ( void * arg )
{
conv_hash_t * hash = ( conv_hash_t * ) arg ;
struct sharkd_conv_tap_data * iu = ( struct sharkd_conv_tap_data * ) hash - > user_data ;
if ( ! strncmp ( iu - > type , " conv: " , 5 ) )
{
reset_conversation_table_data ( hash ) ;
}
else if ( ! strncmp ( iu - > type , " endpt: " , 6 ) )
{
reset_hostlist_table_data ( hash ) ;
}
g_free ( iu ) ;
}
2017-05-13 21:52:50 +00:00
/**
* sharkd_session_process_tap_nstat_cb ( )
*
* Output nstat tap :
* ( m ) tap - tap name
* ( m ) type - tap output type
* ( m ) fields : array of objects with attributes :
* ( m ) c - name
*
* ( m ) tables : array of object with attributes :
* ( m ) t - table title
* ( m ) i - array of items
*/
static void
sharkd_session_process_tap_nstat_cb ( void * arg )
{
2018-02-18 22:39:49 +00:00
stat_data_t * stat_data = ( stat_data_t * ) arg ;
2017-05-13 21:52:50 +00:00
guint i , j , k ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " tap " , " nstat:%s " , stat_data - > stat_tap_data - > cli_string ) ;
sharkd_json_value_string ( " type " , " nstat " ) ;
2017-05-13 21:52:50 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " fields " ) ;
2017-05-13 21:52:50 +00:00
for ( i = 0 ; i < stat_data - > stat_tap_data - > nfields ; i + + )
{
stat_tap_table_item * field = & ( stat_data - > stat_tap_data - > fields [ i ] ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " c " , field - > column_name ) ;
json_dumper_end_object ( & dumper ) ;
2017-05-13 21:52:50 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-05-13 21:52:50 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " tables " ) ;
2017-05-13 21:52:50 +00:00
for ( i = 0 ; i < stat_data - > stat_tap_data - > tables - > len ; i + + )
{
stat_tap_table * table = g_array_index ( stat_data - > stat_tap_data - > tables , stat_tap_table * , i ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-05-13 21:52:50 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " t " , table - > title ) ;
2017-05-13 21:52:50 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " i " ) ;
2017-05-13 21:52:50 +00:00
for ( j = 0 ; j < table - > num_elements ; j + + )
{
stat_tap_table_item_type * field_data ;
2018-02-18 22:39:49 +00:00
field_data = stat_tap_get_field_data ( table , j , 0 ) ;
2017-05-13 21:52:50 +00:00
if ( field_data = = NULL | | field_data - > type = = TABLE_ITEM_NONE ) /* Nothing for us here */
continue ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( NULL ) ;
2017-05-13 21:52:50 +00:00
for ( k = 0 ; k < table - > num_fields ; k + + )
{
2018-02-18 22:39:49 +00:00
field_data = stat_tap_get_field_data ( table , j , k ) ;
2017-05-13 21:52:50 +00:00
switch ( field_data - > type )
{
case TABLE_ITEM_UINT :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( NULL , " %u " , field_data - > value . uint_value ) ;
2017-05-13 21:52:50 +00:00
break ;
case TABLE_ITEM_INT :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( NULL , " %d " , field_data - > value . int_value ) ;
2017-05-13 21:52:50 +00:00
break ;
case TABLE_ITEM_STRING :
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( NULL , field_data - > value . string_value ) ;
2017-05-13 21:52:50 +00:00
break ;
case TABLE_ITEM_FLOAT :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( NULL , " %f " , field_data - > value . float_value ) ;
2017-05-13 21:52:50 +00:00
break ;
case TABLE_ITEM_ENUM :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( NULL , " %d " , field_data - > value . enum_value ) ;
2017-05-13 21:52:50 +00:00
break ;
case TABLE_ITEM_NONE :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( NULL , " null " ) ;
2017-05-13 21:52:50 +00:00
break ;
}
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-05-13 21:52:50 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-05-13 21:52:50 +00:00
}
2018-09-25 17:20:54 +00:00
sharkd_json_array_close ( ) ;
2017-05-13 21:52:50 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-05-13 21:52:50 +00:00
}
static void
sharkd_session_free_tap_nstat_cb ( void * arg )
{
2018-02-18 22:39:49 +00:00
stat_data_t * stat_data = ( stat_data_t * ) arg ;
2017-05-13 21:52:50 +00:00
2018-05-13 20:20:33 +00:00
free_stat_tables ( stat_data - > stat_tap_data ) ;
2017-05-13 21:52:50 +00:00
}
2017-03-19 10:33:47 +00:00
/**
* sharkd_session_process_tap_rtd_cb ( )
*
* Output rtd tap :
* ( m ) tap - tap name
* ( m ) type - tap output type
* ( m ) stats - statistics rows - array object with attributes :
* ( m ) type - statistic name
* ( m ) num - number of messages
* ( m ) min - minimum SRT time
* ( m ) max - maximum SRT time
* ( m ) tot - total SRT time
* ( m ) min_frame - minimal SRT
* ( m ) max_frame - maximum SRT
* ( o ) open_req - Open Requests
* ( o ) disc_rsp - Discarded Responses
* ( o ) req_dup - Duplicated Requests
* ( o ) rsp_dup - Duplicated Responses
* ( o ) open_req - Open Requests
* ( o ) disc_rsp - Discarded Responses
* ( o ) req_dup - Duplicated Requests
* ( o ) rsp_dup - Duplicated Responses
*/
static void
sharkd_session_process_tap_rtd_cb ( void * arg )
{
rtd_data_t * rtd_data = ( rtd_data_t * ) arg ;
register_rtd_t * rtd = ( register_rtd_t * ) rtd_data - > user_data ;
guint i , j ;
const char * filter = proto_get_protocol_filter_name ( get_rtd_proto_id ( rtd ) ) ;
/* XXX, some dissectors are having single table and multiple timestats (mgcp, megaco),
* some multiple table and single timestat ( radius , h225 )
* and it seems that value_string is used one for timestamp - ID , other one for table - ID
2017-08-19 20:24:56 +00:00
* I wonder how it will gonna work with multiple timestats and multiple tables . . .
2017-03-19 10:33:47 +00:00
* ( for usage grep for : register_rtd_table )
*/
const value_string * vs = get_rtd_value_string ( rtd ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " tap " , " rtd:%s " , filter ) ;
sharkd_json_value_string ( " type " , " rtd " ) ;
2017-03-19 10:33:47 +00:00
if ( rtd_data - > stat_table . num_rtds = = 1 )
{
const rtd_timestat * ms = & rtd_data - > stat_table . time_stats [ 0 ] ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " open_req " , " %u " , ms - > open_req_num ) ;
sharkd_json_value_anyf ( " disc_rsp " , " %u " , ms - > disc_rsp_num ) ;
sharkd_json_value_anyf ( " req_dup " , " %u " , ms - > req_dup_num ) ;
sharkd_json_value_anyf ( " rsp_dup " , " %u " , ms - > rsp_dup_num ) ;
2017-03-19 10:33:47 +00:00
}
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " stats " ) ;
2017-03-19 10:33:47 +00:00
for ( i = 0 ; i < rtd_data - > stat_table . num_rtds ; i + + )
{
const rtd_timestat * ms = & rtd_data - > stat_table . time_stats [ i ] ;
for ( j = 0 ; j < ms - > num_timestat ; j + + )
{
const char * type_str ;
if ( ms - > rtd [ j ] . num = = 0 )
continue ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
if ( rtd_data - > stat_table . num_rtds = = 1 )
type_str = val_to_str_const ( j , vs , " Other " ) ; /* 1 table - description per row */
else
type_str = val_to_str_const ( i , vs , " Other " ) ; /* multiple table - description per table */
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " type " , type_str ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " num " , " %u " , ms - > rtd [ j ] . num ) ;
sharkd_json_value_anyf ( " min " , " %.9f " , nstime_to_sec ( & ( ms - > rtd [ j ] . min ) ) ) ;
sharkd_json_value_anyf ( " max " , " %.9f " , nstime_to_sec ( & ( ms - > rtd [ j ] . max ) ) ) ;
sharkd_json_value_anyf ( " tot " , " %.9f " , nstime_to_sec ( & ( ms - > rtd [ j ] . tot ) ) ) ;
sharkd_json_value_anyf ( " min_frame " , " %u " , ms - > rtd [ j ] . min_num ) ;
sharkd_json_value_anyf ( " max_frame " , " %u " , ms - > rtd [ j ] . max_num ) ;
2017-03-19 10:33:47 +00:00
if ( rtd_data - > stat_table . num_rtds ! = 1 )
{
/* like in tshark, display it on every row */
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " open_req " , " %u " , ms - > open_req_num ) ;
sharkd_json_value_anyf ( " disc_rsp " , " %u " , ms - > disc_rsp_num ) ;
sharkd_json_value_anyf ( " req_dup " , " %u " , ms - > req_dup_num ) ;
sharkd_json_value_anyf ( " rsp_dup " , " %u " , ms - > rsp_dup_num ) ;
2017-03-19 10:33:47 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
}
}
2018-09-25 17:20:54 +00:00
sharkd_json_array_close ( ) ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
}
static void
sharkd_session_free_tap_rtd_cb ( void * arg )
{
rtd_data_t * rtd_data = ( rtd_data_t * ) arg ;
2018-05-12 23:00:36 +00:00
free_rtd_table ( & rtd_data - > stat_table ) ;
2017-03-19 10:33:47 +00:00
g_free ( rtd_data ) ;
}
/**
* sharkd_session_process_tap_srt_cb ( )
*
* Output srt tap :
* ( m ) tap - tap name
* ( m ) type - tap output type
*
* ( m ) tables - array of object with attributes :
* ( m ) n - table name
* ( m ) f - table filter
* ( o ) c - table column name
* ( m ) r - table rows - array object with attributes :
* ( m ) n - row name
* ( m ) idx - procedure index
* ( m ) num - number of events
* ( m ) min - minimum SRT time
* ( m ) max - maximum SRT time
* ( m ) tot - total SRT time
*/
static void
sharkd_session_process_tap_srt_cb ( void * arg )
{
srt_data_t * srt_data = ( srt_data_t * ) arg ;
register_srt_t * srt = ( register_srt_t * ) srt_data - > user_data ;
const char * filter = proto_get_protocol_filter_name ( get_srt_proto_id ( srt ) ) ;
guint i ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " tap " , " srt:%s " , filter ) ;
sharkd_json_value_string ( " type " , " srt " ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " tables " ) ;
2017-03-19 10:33:47 +00:00
for ( i = 0 ; i < srt_data - > srt_array - > len ; i + + )
{
/* SRT table */
srt_stat_table * rst = g_array_index ( srt_data - > srt_array , srt_stat_table * , i ) ;
int j ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
if ( rst - > name )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " n " , rst - > name ) ;
2017-03-19 10:33:47 +00:00
else if ( rst - > short_name )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " n " , rst - > short_name ) ;
2017-03-19 10:33:47 +00:00
else
2018-12-12 14:33:44 +00:00
sharkd_json_value_stringf ( " n " , " table%u " , i ) ;
2017-03-19 10:33:47 +00:00
if ( rst - > filter_string )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " f " , rst - > filter_string ) ;
2017-03-19 10:33:47 +00:00
if ( rst - > proc_column_name )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " c " , rst - > proc_column_name ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " r " ) ;
2017-03-19 10:33:47 +00:00
for ( j = 0 ; j < rst - > num_procs ; j + + )
{
/* SRT row */
srt_procedure_t * proc = & rst - > procedures [ j ] ;
if ( proc - > stats . num = = 0 )
continue ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " n " , proc - > procedure ) ;
2017-03-19 10:33:47 +00:00
if ( rst - > filter_string )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " idx " , " %d " , proc - > proc_index ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " num " , " %u " , proc - > stats . num ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " min " , " %.9f " , nstime_to_sec ( & proc - > stats . min ) ) ;
sharkd_json_value_anyf ( " max " , " %.9f " , nstime_to_sec ( & proc - > stats . max ) ) ;
sharkd_json_value_anyf ( " tot " , " %.9f " , nstime_to_sec ( & proc - > stats . tot ) ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
}
2018-09-24 18:34:30 +00:00
sharkd_json_array_close ( ) ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
}
2018-09-24 18:34:30 +00:00
sharkd_json_array_close ( ) ;
2017-03-19 10:33:47 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-19 10:33:47 +00:00
}
static void
sharkd_session_free_tap_srt_cb ( void * arg )
{
srt_data_t * srt_data = ( srt_data_t * ) arg ;
register_srt_t * srt = ( register_srt_t * ) srt_data - > user_data ;
2018-05-13 19:45:16 +00:00
free_srt_table ( srt , srt_data - > srt_array ) ;
2017-03-19 10:33:47 +00:00
g_array_free ( srt_data - > srt_array , TRUE ) ;
g_free ( srt_data ) ;
}
2017-03-11 11:27:14 +00:00
struct sharkd_export_object_list
{
struct sharkd_export_object_list * next ;
char * type ;
const char * proto ;
GSList * entries ;
} ;
static struct sharkd_export_object_list * sharkd_eo_list ;
/**
* sharkd_session_process_tap_eo_cb ( )
*
* Output eo tap :
* ( m ) tap - tap name
* ( m ) type - tap output type
* ( m ) proto - protocol short name
* ( m ) objects - array of object with attributes :
* ( m ) pkt - packet number
* ( o ) hostname - hostname
* ( o ) type - content type
* ( o ) filename - filename
* ( m ) len - object length
*/
static void
sharkd_session_process_tap_eo_cb ( void * tapdata )
{
export_object_list_t * tap_object = ( export_object_list_t * ) tapdata ;
2017-12-07 19:37:54 +00:00
struct sharkd_export_object_list * object_list = ( struct sharkd_export_object_list * ) tap_object - > gui_data ;
2017-03-11 11:27:14 +00:00
GSList * slist ;
int i = 0 ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " tap " , object_list - > type ) ;
sharkd_json_value_string ( " type " , " eo " ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " proto " , object_list - > proto ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " objects " ) ;
2017-03-11 11:27:14 +00:00
for ( slist = object_list - > entries ; slist ; slist = slist - > next )
{
const export_object_entry_t * eo_entry = ( export_object_entry_t * ) slist - > data ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " pkt " , " %u " , eo_entry - > pkt_num ) ;
2017-03-11 11:27:14 +00:00
if ( eo_entry - > hostname )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " hostname " , eo_entry - > hostname ) ;
2017-03-11 11:27:14 +00:00
if ( eo_entry - > content_type )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " type " , eo_entry - > content_type ) ;
2017-03-11 11:27:14 +00:00
if ( eo_entry - > filename )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " filename " , eo_entry - > filename ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_stringf ( " _download " , " %s_%d " , object_list - > type , i ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " len " , " % " G_GINT64_FORMAT , eo_entry - > payload_len ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-11 11:27:14 +00:00
i + + ;
}
2018-09-24 18:34:30 +00:00
sharkd_json_array_close ( ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-11 11:27:14 +00:00
}
static void
sharkd_eo_object_list_add_entry ( void * gui_data , export_object_entry_t * entry )
{
struct sharkd_export_object_list * object_list = ( struct sharkd_export_object_list * ) gui_data ;
object_list - > entries = g_slist_append ( object_list - > entries , entry ) ;
}
static export_object_entry_t *
sharkd_eo_object_list_get_entry ( void * gui_data , int row )
{
struct sharkd_export_object_list * object_list = ( struct sharkd_export_object_list * ) gui_data ;
return ( export_object_entry_t * ) g_slist_nth_data ( object_list - > entries , row ) ;
}
2017-02-25 11:45:33 +00:00
/**
* sharkd_session_process_tap_rtp_cb ( )
*
* Output RTP streams tap :
* ( m ) tap - tap name
* ( m ) type - tap output type
* ( m ) streams - array of object with attributes :
* ( m ) ssrc - RTP synchronization source identifier
* ( m ) payload - stream payload
* ( m ) saddr - source address
* ( m ) sport - source port
* ( m ) daddr - destination address
* ( m ) dport - destination port
* ( m ) pkts - packets count
* ( m ) max_delta - max delta ( ms )
* ( m ) max_jitter - max jitter ( ms )
* ( m ) mean_jitter - mean jitter ( ms )
* ( m ) expectednr -
* ( m ) totalnr -
* ( m ) problem - if analyser found the problem
* ( m ) ipver - address IP version ( 4 or 6 )
*/
static void
sharkd_session_process_tap_rtp_cb ( void * arg )
{
rtpstream_tapinfo_t * rtp_tapinfo = ( rtpstream_tapinfo_t * ) arg ;
GList * listx ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " tap " , " rtp-streams " ) ;
sharkd_json_value_string ( " type " , " rtp-streams " ) ;
2017-02-25 11:45:33 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " streams " ) ;
2017-02-25 11:45:33 +00:00
for ( listx = g_list_first ( rtp_tapinfo - > strinfo_list ) ; listx ; listx = listx - > next )
{
2018-06-14 21:19:01 +00:00
rtpstream_info_t * streaminfo = ( rtpstream_info_t * ) listx - > data ;
2018-09-23 22:03:58 +00:00
rtpstream_info_calc_t calc ;
2017-02-25 11:45:33 +00:00
2018-06-20 13:59:33 +00:00
rtpstream_info_calculate ( streaminfo , & calc ) ;
2017-02-25 11:45:33 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " ssrc " , " %u " , calc . ssrc ) ;
sharkd_json_value_string ( " payload " , calc . all_payload_type_names ) ;
2017-02-25 11:45:33 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " saddr " , calc . src_addr_str ) ;
sharkd_json_value_anyf ( " sport " , " %u " , calc . src_port ) ;
sharkd_json_value_string ( " daddr " , calc . dst_addr_str ) ;
sharkd_json_value_anyf ( " dport " , " %u " , calc . dst_port ) ;
2017-02-25 11:45:33 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " pkts " , " %u " , calc . packet_count ) ;
2017-02-25 11:45:33 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " max_delta " , " %f " , calc . max_delta ) ;
sharkd_json_value_anyf ( " max_jitter " , " %f " , calc . max_jitter ) ;
sharkd_json_value_anyf ( " mean_jitter " , " %f " , calc . mean_jitter ) ;
2017-02-25 11:45:33 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " expectednr " , " %u " , calc . packet_expected ) ;
sharkd_json_value_anyf ( " totalnr " , " %u " , calc . total_nr ) ;
2017-02-25 11:45:33 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " problem " , calc . problem ? " true " : " false " ) ;
2017-02-25 11:45:33 +00:00
/* for filter */
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " ipver " , " %d " , ( streaminfo - > id . src_addr . type = = AT_IPv6 ) ? 6 : 4 ) ;
2017-02-25 11:45:33 +00:00
2018-06-20 13:59:33 +00:00
rtpstream_info_calc_free ( & calc ) ;
2017-02-25 11:45:33 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-02-25 11:45:33 +00:00
}
2018-09-24 18:34:30 +00:00
sharkd_json_array_close ( ) ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-02-25 11:45:33 +00:00
}
2016-10-15 18:48:17 +00:00
/**
* sharkd_session_process_tap ( )
*
* Process tap request
*
* Input :
* ( m ) tap0 - First tap request
* ( o ) tap1 . . . tap15 - Other tap requests
*
* Output object with attributes :
* ( m ) taps - array of object with attributes :
* ( m ) tap - tap name
* ( m ) type - tap output type
* . . .
* for type : stats see sharkd_session_process_tap_stats_cb ( )
2017-05-13 21:52:50 +00:00
* for type : nstat see sharkd_session_process_tap_nstat_cb ( )
2016-10-15 18:48:17 +00:00
* for type : conv see sharkd_session_process_tap_conv_cb ( )
* for type : host see sharkd_session_process_tap_conv_cb ( )
2017-02-25 11:45:33 +00:00
* for type : rtp - streams see sharkd_session_process_tap_rtp_cb ( )
2017-03-31 18:35:51 +00:00
* for type : rtp - analyse see sharkd_session_process_tap_rtp_analyse_cb ( )
2017-03-11 11:27:14 +00:00
* for type : eo see sharkd_session_process_tap_eo_cb ( )
2017-03-17 06:59:05 +00:00
* for type : expert see sharkd_session_process_tap_expert_cb ( )
2017-03-19 10:33:47 +00:00
* for type : rtd see sharkd_session_process_tap_rtd_cb ( )
* for type : srt see sharkd_session_process_tap_srt_cb ( )
2017-09-16 15:46:15 +00:00
* for type : flow see sharkd_session_process_tap_flow_cb ( )
2016-10-15 18:48:17 +00:00
*
* ( m ) err - error code
*/
static void
sharkd_session_process_tap ( char * buf , const jsmntok_t * tokens , int count )
{
void * taps_data [ 16 ] ;
2017-03-12 08:23:17 +00:00
GFreeFunc taps_free [ 16 ] ;
2016-10-15 18:48:17 +00:00
int taps_count = 0 ;
int i ;
2017-02-25 11:45:33 +00:00
rtpstream_tapinfo_t rtp_tapinfo =
2017-12-07 19:37:54 +00:00
{ NULL , NULL , NULL , NULL , 0 , NULL , 0 , TAP_ANALYSE , NULL , NULL , NULL , FALSE } ;
2017-02-25 11:45:33 +00:00
2016-10-15 18:48:17 +00:00
for ( i = 0 ; i < 16 ; i + + )
{
char tapbuf [ 32 ] ;
const char * tok_tap ;
void * tap_data = NULL ;
2017-03-12 08:23:17 +00:00
GFreeFunc tap_free = NULL ;
2016-10-15 18:48:17 +00:00
const char * tap_filter = " " ;
GString * tap_error = NULL ;
2017-01-26 01:27:13 +00:00
ws_snprintf ( tapbuf , sizeof ( tapbuf ) , " tap%d " , i ) ;
2016-10-15 18:48:17 +00:00
tok_tap = json_find_attr ( buf , tokens , count , tapbuf ) ;
if ( ! tok_tap )
break ;
if ( ! strncmp ( tok_tap , " stat: " , 5 ) )
{
stats_tree_cfg * cfg = stats_tree_get_cfg_by_abbr ( tok_tap + 5 ) ;
stats_tree * st ;
if ( ! cfg )
{
fprintf ( stderr , " sharkd_session_process_tap() stat %s not found \n " , tok_tap + 5 ) ;
continue ;
}
st = stats_tree_new ( cfg , NULL , tap_filter ) ;
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( st - > cfg - > tapname , st , st - > filter , st - > cfg - > flags , stats_tree_reset , stats_tree_packet , sharkd_session_process_tap_stats_cb , NULL ) ;
2016-10-15 18:48:17 +00:00
if ( ! tap_error & & cfg - > init )
cfg - > init ( st ) ;
2017-03-12 08:23:17 +00:00
tap_data = st ;
tap_free = sharkd_session_free_tap_stats_cb ;
2016-10-15 18:48:17 +00:00
}
2017-03-17 06:59:05 +00:00
else if ( ! strcmp ( tok_tap , " expert " ) )
{
struct sharkd_expert_tap * expert_tap ;
expert_tap = g_new0 ( struct sharkd_expert_tap , 1 ) ;
expert_tap - > text = g_string_chunk_new ( 100 ) ;
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( " expert " , expert_tap , NULL , 0 , NULL , sharkd_session_packet_tap_expert_cb , sharkd_session_process_tap_expert_cb , NULL ) ;
2017-03-17 06:59:05 +00:00
tap_data = expert_tap ;
tap_free = sharkd_session_free_tap_expert_cb ;
}
2017-09-16 15:46:15 +00:00
else if ( ! strncmp ( tok_tap , " seqa: " , 5 ) )
{
seq_analysis_info_t * graph_analysis ;
register_analysis_t * analysis ;
const char * tap_name ;
tap_packet_cb tap_func ;
guint tap_flags ;
analysis = sequence_analysis_find_by_name ( tok_tap + 5 ) ;
if ( ! analysis )
{
fprintf ( stderr , " sharkd_session_process_tap() seq analysis %s not found \n " , tok_tap + 5 ) ;
continue ;
}
graph_analysis = sequence_analysis_info_new ( ) ;
graph_analysis - > name = tok_tap + 5 ;
/* TODO, make configurable */
graph_analysis - > any_addr = FALSE ;
tap_name = sequence_analysis_get_tap_listener_name ( analysis ) ;
tap_flags = sequence_analysis_get_tap_flags ( analysis ) ;
tap_func = sequence_analysis_get_packet_func ( analysis ) ;
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( tap_name , graph_analysis , NULL , tap_flags , NULL , tap_func , sharkd_session_process_tap_flow_cb , NULL ) ;
2017-09-16 15:46:15 +00:00
tap_data = graph_analysis ;
tap_free = sharkd_session_free_tap_flow_cb ;
}
2016-10-15 18:48:17 +00:00
else if ( ! strncmp ( tok_tap , " conv: " , 5 ) | | ! strncmp ( tok_tap , " endpt: " , 6 ) )
{
struct register_ct * ct = NULL ;
const char * ct_tapname ;
struct sharkd_conv_tap_data * ct_data ;
2017-03-12 08:23:17 +00:00
tap_packet_cb tap_func = NULL ;
2016-10-15 18:48:17 +00:00
if ( ! strncmp ( tok_tap , " conv: " , 5 ) )
{
2017-03-12 08:23:17 +00:00
ct = get_conversation_by_proto_id ( proto_get_id_by_short_name ( tok_tap + 5 ) ) ;
2016-10-15 18:48:17 +00:00
if ( ! ct | | ! ( tap_func = get_conversation_packet_func ( ct ) ) )
{
fprintf ( stderr , " sharkd_session_process_tap() conv %s not found \n " , tok_tap + 5 ) ;
continue ;
}
}
else if ( ! strncmp ( tok_tap , " endpt: " , 6 ) )
{
2017-03-12 08:23:17 +00:00
ct = get_conversation_by_proto_id ( proto_get_id_by_short_name ( tok_tap + 6 ) ) ;
2016-10-15 18:48:17 +00:00
if ( ! ct | | ! ( tap_func = get_hostlist_packet_func ( ct ) ) )
{
2017-03-12 08:23:17 +00:00
fprintf ( stderr , " sharkd_session_process_tap() endpt %s not found \n " , tok_tap + 6 ) ;
2016-10-15 18:48:17 +00:00
continue ;
}
}
else
{
fprintf ( stderr , " sharkd_session_process_tap() conv/endpt(?): %s not found \n " , tok_tap ) ;
continue ;
}
ct_tapname = proto_get_protocol_filter_name ( get_conversation_proto_id ( ct ) ) ;
ct_data = ( struct sharkd_conv_tap_data * ) g_malloc0 ( sizeof ( struct sharkd_conv_tap_data ) ) ;
ct_data - > type = tok_tap ;
ct_data - > hash . user_data = ct_data ;
/* XXX: make configurable */
ct_data - > resolve_name = TRUE ;
ct_data - > resolve_port = TRUE ;
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( ct_tapname , & ct_data - > hash , tap_filter , 0 , NULL , tap_func , sharkd_session_process_tap_conv_cb , NULL ) ;
2016-10-15 18:48:17 +00:00
tap_data = & ct_data - > hash ;
2017-03-12 08:23:17 +00:00
tap_free = sharkd_session_free_tap_conv_cb ;
2016-10-15 18:48:17 +00:00
}
2017-05-13 21:52:50 +00:00
else if ( ! strncmp ( tok_tap , " nstat: " , 6 ) )
{
2018-02-18 22:39:49 +00:00
stat_tap_table_ui * stat_tap = stat_tap_by_name ( tok_tap + 6 ) ;
stat_data_t * stat_data ;
2017-05-13 21:52:50 +00:00
2017-06-08 20:16:36 +00:00
if ( ! stat_tap )
2017-05-13 21:52:50 +00:00
{
fprintf ( stderr , " sharkd_session_process_tap() nstat=%s not found \n " , tok_tap + 6 ) ;
continue ;
}
2018-05-13 20:20:33 +00:00
stat_tap - > stat_tap_init_cb ( stat_tap ) ;
2017-05-13 21:52:50 +00:00
2018-02-18 22:39:49 +00:00
stat_data = g_new0 ( stat_data_t , 1 ) ;
2017-06-08 20:16:36 +00:00
stat_data - > stat_tap_data = stat_tap ;
2017-05-13 21:52:50 +00:00
stat_data - > user_data = NULL ;
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( stat_tap - > tap_name , stat_data , tap_filter , 0 , NULL , stat_tap - > packet_func , sharkd_session_process_tap_nstat_cb , NULL ) ;
2017-05-13 21:52:50 +00:00
tap_data = stat_data ;
tap_free = sharkd_session_free_tap_nstat_cb ;
}
2017-03-19 10:33:47 +00:00
else if ( ! strncmp ( tok_tap , " rtd: " , 4 ) )
{
register_rtd_t * rtd = get_rtd_table_by_name ( tok_tap + 4 ) ;
rtd_data_t * rtd_data ;
char * err ;
if ( ! rtd )
{
fprintf ( stderr , " sharkd_session_process_tap() rtd=%s not found \n " , tok_tap + 4 ) ;
continue ;
}
rtd_table_get_filter ( rtd , " " , & tap_filter , & err ) ;
if ( err ! = NULL )
{
fprintf ( stderr , " sharkd_session_process_tap() rtd=%s err=%s \n " , tok_tap + 4 , err ) ;
g_free ( err ) ;
continue ;
}
rtd_data = g_new0 ( rtd_data_t , 1 ) ;
rtd_data - > user_data = rtd ;
rtd_table_dissector_init ( rtd , & rtd_data - > stat_table , NULL , NULL ) ;
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( get_rtd_tap_listener_name ( rtd ) , rtd_data , tap_filter , 0 , NULL , get_rtd_packet_func ( rtd ) , sharkd_session_process_tap_rtd_cb , NULL ) ;
2017-03-19 10:33:47 +00:00
tap_data = rtd_data ;
tap_free = sharkd_session_free_tap_rtd_cb ;
}
else if ( ! strncmp ( tok_tap , " srt: " , 4 ) )
{
register_srt_t * srt = get_srt_table_by_name ( tok_tap + 4 ) ;
srt_data_t * srt_data ;
char * err ;
if ( ! srt )
{
fprintf ( stderr , " sharkd_session_process_tap() srt=%s not found \n " , tok_tap + 4 ) ;
continue ;
}
srt_table_get_filter ( srt , " " , & tap_filter , & err ) ;
if ( err ! = NULL )
{
fprintf ( stderr , " sharkd_session_process_tap() srt=%s err=%s \n " , tok_tap + 4 , err ) ;
g_free ( err ) ;
continue ;
}
srt_data = g_new0 ( srt_data_t , 1 ) ;
srt_data - > srt_array = g_array_new ( FALSE , TRUE , sizeof ( srt_stat_table * ) ) ;
srt_data - > user_data = srt ;
2018-05-13 19:45:16 +00:00
srt_table_dissector_init ( srt , srt_data - > srt_array ) ;
2017-03-19 10:33:47 +00:00
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( get_srt_tap_listener_name ( srt ) , srt_data , tap_filter , 0 , NULL , get_srt_packet_func ( srt ) , sharkd_session_process_tap_srt_cb , NULL ) ;
2017-03-19 10:33:47 +00:00
tap_data = srt_data ;
tap_free = sharkd_session_free_tap_srt_cb ;
}
2017-03-11 11:27:14 +00:00
else if ( ! strncmp ( tok_tap , " eo: " , 3 ) )
{
register_eo_t * eo = get_eo_by_name ( tok_tap + 3 ) ;
export_object_list_t * eo_object ;
struct sharkd_export_object_list * object_list ;
if ( ! eo )
{
fprintf ( stderr , " sharkd_session_process_tap() eo=%s not found \n " , tok_tap + 3 ) ;
continue ;
}
for ( object_list = sharkd_eo_list ; object_list ; object_list = object_list - > next )
{
if ( ! strcmp ( object_list - > type , tok_tap ) )
{
g_slist_free_full ( object_list - > entries , ( GDestroyNotify ) eo_free_entry ) ;
object_list - > entries = NULL ;
break ;
}
}
if ( ! object_list )
{
object_list = g_new ( struct sharkd_export_object_list , 1 ) ;
object_list - > type = g_strdup ( tok_tap ) ;
object_list - > proto = proto_get_protocol_short_name ( find_protocol_by_id ( get_eo_proto_id ( eo ) ) ) ;
object_list - > entries = NULL ;
object_list - > next = sharkd_eo_list ;
sharkd_eo_list = object_list ;
}
eo_object = g_new0 ( export_object_list_t , 1 ) ;
eo_object - > add_entry = sharkd_eo_object_list_add_entry ;
eo_object - > get_entry = sharkd_eo_object_list_get_entry ;
eo_object - > gui_data = ( void * ) object_list ;
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( get_eo_tap_listener_name ( eo ) , eo_object , NULL , 0 , NULL , get_eo_packet_func ( eo ) , sharkd_session_process_tap_eo_cb , NULL ) ;
2017-03-11 11:27:14 +00:00
tap_data = eo_object ;
2017-03-12 08:23:17 +00:00
tap_free = g_free ; /* need to free only eo_object, object_list need to be kept for potential download */
2017-03-11 11:27:14 +00:00
}
2017-02-25 11:45:33 +00:00
else if ( ! strcmp ( tok_tap , " rtp-streams " ) )
{
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( " rtp " , & rtp_tapinfo , tap_filter , 0 , rtpstream_reset_cb , rtpstream_packet_cb , sharkd_session_process_tap_rtp_cb , NULL ) ;
2017-02-25 11:45:33 +00:00
tap_data = & rtp_tapinfo ;
2017-03-12 08:23:17 +00:00
tap_free = rtpstream_reset_cb ;
2017-02-25 11:45:33 +00:00
}
2017-03-31 18:35:51 +00:00
else if ( ! strncmp ( tok_tap , " rtp-analyse: " , 12 ) )
{
struct sharkd_analyse_rtp * rtp_req ;
rtp_req = ( struct sharkd_analyse_rtp * ) g_malloc0 ( sizeof ( * rtp_req ) ) ;
2018-06-15 20:47:47 +00:00
if ( ! sharkd_rtp_match_init ( & rtp_req - > id , tok_tap + 12 ) )
2017-03-31 18:35:51 +00:00
{
2018-06-15 20:47:47 +00:00
rtpstream_id_free ( & rtp_req - > id ) ;
2017-03-31 18:35:51 +00:00
g_free ( rtp_req ) ;
continue ;
}
rtp_req - > tap_name = tok_tap ;
rtp_req - > statinfo . first_packet = TRUE ;
rtp_req - > statinfo . reg_pt = PT_UNDEFINED ;
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( " rtp " , rtp_req , tap_filter , 0 , NULL , sharkd_session_packet_tap_rtp_analyse_cb , sharkd_session_process_tap_rtp_analyse_cb , NULL ) ;
2017-03-31 18:35:51 +00:00
tap_data = rtp_req ;
tap_free = sharkd_session_process_tap_rtp_free_cb ;
}
2016-10-15 18:48:17 +00:00
else
{
fprintf ( stderr , " sharkd_session_process_tap() %s not recognized \n " , tok_tap ) ;
continue ;
}
if ( tap_error )
{
fprintf ( stderr , " sharkd_session_process_tap() name=%s error=%s " , tok_tap , tap_error - > str ) ;
g_string_free ( tap_error , TRUE ) ;
2017-03-12 08:23:17 +00:00
if ( tap_free )
tap_free ( tap_data ) ;
2016-10-15 18:48:17 +00:00
continue ;
}
2017-03-12 08:23:17 +00:00
taps_data [ taps_count ] = tap_data ;
taps_free [ taps_count ] = tap_free ;
2016-10-15 18:48:17 +00:00
taps_count + + ;
}
fprintf ( stderr , " sharkd_session_process_tap() count=%d \n " , taps_count ) ;
if ( taps_count = = 0 )
return ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " taps " ) ;
2016-10-15 18:48:17 +00:00
sharkd_retap ( ) ;
2018-09-25 17:20:54 +00:00
sharkd_json_array_close ( ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " err " , " 0 " ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
2017-03-12 08:23:17 +00:00
for ( i = 0 ; i < taps_count ; i + + )
2016-10-15 18:48:17 +00:00
{
if ( taps_data [ i ] )
remove_tap_listener ( taps_data [ i ] ) ;
2017-03-12 08:23:17 +00:00
if ( taps_free [ i ] )
taps_free [ i ] ( taps_data [ i ] ) ;
2016-10-15 18:48:17 +00:00
}
}
2017-03-11 11:27:14 +00:00
/**
* sharkd_session_process_follow ( )
*
* Process follow request
*
* Input :
* ( m ) follow - follow protocol request ( e . g . HTTP )
* ( m ) filter - filter request ( e . g . tcp . stream = = 1 )
*
* Output object with attributes :
*
* ( m ) err - error code
* ( m ) shost - server host
* ( m ) sport - server port
* ( m ) sbytes - server send bytes count
* ( m ) chost - client host
* ( m ) cport - client port
* ( m ) cbytes - client send bytes count
* ( o ) payloads - array of object with attributes :
* ( o ) s - set if server sent , else client
* ( m ) n - packet number
* ( m ) d - data base64 encoded
*/
static void
sharkd_session_process_follow ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_follow = json_find_attr ( buf , tokens , count , " follow " ) ;
const char * tok_filter = json_find_attr ( buf , tokens , count , " filter " ) ;
register_follow_t * follower ;
GString * tap_error ;
follow_info_t * follow_info ;
const char * host ;
char * port ;
if ( ! tok_follow | | ! tok_filter )
return ;
follower = get_follow_by_name ( tok_follow ) ;
if ( ! follower )
{
fprintf ( stderr , " sharkd_session_process_follow() follower=%s not found \n " , tok_follow ) ;
return ;
}
/* follow_reset_stream ? */
follow_info = g_new0 ( follow_info_t , 1 ) ;
/* gui_data, filter_out_filter not set, but not used by dissector */
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( get_follow_tap_string ( follower ) , follow_info , tok_filter , 0 , NULL , get_follow_tap_handler ( follower ) , NULL , NULL ) ;
2017-03-11 11:27:14 +00:00
if ( tap_error )
{
fprintf ( stderr , " sharkd_session_process_follow() name=%s error=%s " , tok_follow , tap_error - > str ) ;
g_string_free ( tap_error , TRUE ) ;
g_free ( follow_info ) ;
return ;
}
sharkd_retap ( ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " err " , " 0 " ) ;
2017-03-11 11:27:14 +00:00
/* Server information: hostname, port, bytes sent */
host = address_to_name ( & follow_info - > server_ip ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " shost " , host ) ;
2017-03-11 11:27:14 +00:00
port = get_follow_port_to_display ( follower ) ( NULL , follow_info - > server_port ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " sport " , port ) ;
2017-03-11 11:27:14 +00:00
wmem_free ( NULL , port ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " sbytes " , " %u " , follow_info - > bytes_written [ 0 ] ) ;
2017-03-11 11:27:14 +00:00
/* Client information: hostname, port, bytes sent */
host = address_to_name ( & follow_info - > client_ip ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " chost " , host ) ;
2017-03-11 11:27:14 +00:00
port = get_follow_port_to_display ( follower ) ( NULL , follow_info - > client_port ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " cport " , port ) ;
2017-03-11 11:27:14 +00:00
wmem_free ( NULL , port ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " cbytes " , " %u " , follow_info - > bytes_written [ 1 ] ) ;
2017-03-11 11:27:14 +00:00
if ( follow_info - > payload )
{
follow_record_t * follow_record ;
GList * cur ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " payloads " ) ;
2018-07-04 19:53:53 +00:00
for ( cur = g_list_last ( follow_info - > payload ) ; cur ; cur = g_list_previous ( cur ) )
2017-03-11 11:27:14 +00:00
{
follow_record = ( follow_record_t * ) cur - > data ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " n " , " %u " , follow_record - > packet_num ) ;
sharkd_json_value_base64 ( " d " , follow_record - > data - > data , follow_record - > data - > len ) ;
2017-03-11 11:27:14 +00:00
if ( follow_record - > is_server )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " s " , " %d " , 1 ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-03-11 11:27:14 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-03-11 11:27:14 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2017-03-11 11:27:14 +00:00
remove_tap_listener ( follow_info ) ;
follow_info_free ( follow_info ) ;
}
2016-10-15 18:48:17 +00:00
static void
2018-07-22 12:54:36 +00:00
sharkd_session_process_frame_cb_tree ( epan_dissect_t * edt , proto_tree * tree , tvbuff_t * * tvbs , gboolean display_hidden )
2016-10-15 18:48:17 +00:00
{
proto_node * node ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( NULL ) ;
2016-10-15 18:48:17 +00:00
for ( node = tree - > first_child ; node ; node = node - > next )
{
field_info * finfo = PNODE_FINFO ( node ) ;
if ( ! finfo )
continue ;
2018-07-22 12:54:36 +00:00
if ( ! display_hidden & & FI_GET_FLAG ( finfo , FI_HIDDEN ) )
2016-10-15 18:48:17 +00:00
continue ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
if ( ! finfo - > rep )
{
char label_str [ ITEM_LABEL_LENGTH ] ;
label_str [ 0 ] = ' \0 ' ;
proto_item_fill_label ( finfo , label_str ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " l " , label_str ) ;
2016-10-15 18:48:17 +00:00
}
else
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " l " , finfo - > rep - > representation ) ;
2016-10-15 18:48:17 +00:00
}
if ( finfo - > ds_tvb & & tvbs & & tvbs [ 0 ] ! = finfo - > ds_tvb )
{
int idx ;
for ( idx = 1 ; tvbs [ idx ] ; idx + + )
{
if ( tvbs [ idx ] = = finfo - > ds_tvb )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " ds " , " %d " , idx ) ;
2016-10-15 18:48:17 +00:00
break ;
}
}
}
if ( finfo - > start > = 0 & & finfo - > length > 0 )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " h " , " [%d,%d] " , finfo - > start , finfo - > length ) ;
2016-10-15 18:48:17 +00:00
if ( finfo - > appendix_start > = 0 & & finfo - > appendix_length > 0 )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " i " , " [%d,%d] " , finfo - > appendix_start , finfo - > appendix_length ) ;
2016-10-15 18:48:17 +00:00
2017-03-12 08:23:17 +00:00
if ( finfo - > hfinfo )
{
2017-10-04 20:41:19 +00:00
char * filter ;
2017-03-12 08:23:17 +00:00
if ( finfo - > hfinfo - > type = = FT_PROTOCOL )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " t " , " proto " ) ;
2017-03-12 08:23:17 +00:00
}
else if ( finfo - > hfinfo - > type = = FT_FRAMENUM )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " t " , " framenum " ) ;
sharkd_json_value_anyf ( " fnum " , " %u " , finfo - > value . value . uinteger ) ;
2017-03-12 08:23:17 +00:00
}
else if ( FI_GET_FLAG ( finfo , FI_URL ) & & IS_FT_STRING ( finfo - > hfinfo - > type ) )
{
char * url = fvalue_to_string_repr ( NULL , & finfo - > value , FTREPR_DISPLAY , finfo - > hfinfo - > display ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " t " , " url " ) ;
sharkd_json_value_string ( " url " , url ) ;
2017-03-12 08:23:17 +00:00
wmem_free ( NULL , url ) ;
}
2017-10-04 20:41:19 +00:00
filter = proto_construct_match_selected_string ( finfo , edt ) ;
if ( filter )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " f " , filter ) ;
2017-10-04 20:41:19 +00:00
wmem_free ( NULL , filter ) ;
}
2017-03-12 08:23:17 +00:00
}
2016-10-15 18:48:17 +00:00
2018-07-22 12:54:36 +00:00
if ( FI_GET_FLAG ( finfo , FI_GENERATED ) )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " g " , " true " ) ;
2018-07-22 12:54:36 +00:00
if ( FI_GET_FLAG ( finfo , FI_HIDDEN ) )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " v " , " true " ) ;
2018-07-22 12:54:36 +00:00
2016-10-15 18:48:17 +00:00
if ( FI_GET_FLAG ( finfo , PI_SEVERITY_MASK ) )
{
2017-03-17 06:59:05 +00:00
const char * severity = try_val_to_str ( FI_GET_FLAG ( finfo , PI_SEVERITY_MASK ) , expert_severity_vals ) ;
2016-10-15 18:48:17 +00:00
g_assert ( severity ! = NULL ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , severity ) ;
2016-10-15 18:48:17 +00:00
}
2017-12-07 19:37:54 +00:00
if ( ( ( proto_tree * ) node ) - > first_child )
{
2016-10-15 18:48:17 +00:00
if ( finfo - > tree_type ! = - 1 )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " e " , " %d " , finfo - > tree_type ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " n " , NULL ) ;
2018-07-22 12:54:36 +00:00
sharkd_session_process_frame_cb_tree ( edt , ( proto_tree * ) node , tvbs , display_hidden ) ;
2016-10-15 18:48:17 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
}
2017-03-11 11:27:14 +00:00
static gboolean
sharkd_follower_visit_layers_cb ( const void * key _U_ , void * value , void * user_data )
{
register_follow_t * follower = ( register_follow_t * ) value ;
packet_info * pi = ( packet_info * ) user_data ;
const int proto_id = get_follow_proto_id ( follower ) ;
guint32 ignore_stream ;
2019-02-27 04:55:52 +00:00
guint32 ignore_sub_stream ;
2017-03-11 11:27:14 +00:00
if ( proto_is_frame_protocol ( pi - > layers , proto_get_protocol_filter_name ( proto_id ) ) )
{
const char * layer_proto = proto_get_protocol_short_name ( find_protocol_by_id ( proto_id ) ) ;
char * follow_filter ;
2019-02-27 04:55:52 +00:00
follow_filter = get_follow_conv_func ( follower ) ( pi , & ignore_stream , & ignore_sub_stream ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_array ( & dumper ) ;
json_dumper_value_string ( & dumper , layer_proto ) ;
json_dumper_value_string ( & dumper , follow_filter ) ;
json_dumper_end_array ( & dumper ) ;
2017-03-11 11:27:14 +00:00
g_free ( follow_filter ) ;
}
return FALSE ;
}
2018-07-22 12:54:36 +00:00
struct sharkd_frame_request_data
{
gboolean display_hidden ;
} ;
2016-10-15 18:48:17 +00:00
static void
2017-10-04 20:41:19 +00:00
sharkd_session_process_frame_cb ( epan_dissect_t * edt , proto_tree * tree , struct epan_column_info * cinfo , const GSList * data_src , void * data )
2016-10-15 18:48:17 +00:00
{
2017-10-04 20:41:19 +00:00
packet_info * pi = & edt - > pi ;
2017-09-26 21:42:20 +00:00
frame_data * fdata = pi - > fd ;
const char * pkt_comment = NULL ;
2018-07-22 12:54:36 +00:00
const struct sharkd_frame_request_data * const req_data = ( const struct sharkd_frame_request_data * const ) data ;
const gboolean display_hidden = ( req_data ) ? req_data - > display_hidden : FALSE ;
2018-09-23 22:03:58 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " err " , " 0 " ) ;
2016-10-15 18:48:17 +00:00
2018-12-27 02:26:24 +00:00
if ( fdata - > has_user_comment )
2017-12-06 18:51:18 +00:00
pkt_comment = sharkd_get_user_comment ( fdata ) ;
2018-12-27 02:26:24 +00:00
else if ( fdata - > has_phdr_comment )
2018-02-09 00:19:12 +00:00
pkt_comment = pi - > rec - > opt_comment ;
2017-09-26 21:42:20 +00:00
if ( pkt_comment )
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " comment " , pkt_comment ) ;
2017-09-26 21:42:20 +00:00
2016-10-15 18:48:17 +00:00
if ( tree )
{
tvbuff_t * * tvbs = NULL ;
/* arrayize data src, to speedup searching for ds_tvb index */
if ( data_src & & data_src - > next /* only needed if there are more than one data source */ )
{
guint count = g_slist_length ( ( GSList * ) data_src ) ;
guint i ;
tvbs = ( tvbuff_t * * ) g_malloc ( ( count + 1 ) * sizeof ( * tvbs ) ) ;
for ( i = 0 ; i < count ; i + + )
{
2018-02-21 08:19:51 +00:00
const struct data_source * src = ( const struct data_source * ) g_slist_nth_data ( ( GSList * ) data_src , i ) ;
2016-10-15 18:48:17 +00:00
tvbs [ i ] = get_data_source_tvb ( src ) ;
}
tvbs [ count ] = NULL ;
}
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " tree " , NULL ) ;
2018-07-22 12:54:36 +00:00
sharkd_session_process_frame_cb_tree ( edt , tree , tvbs , display_hidden ) ;
2016-10-15 18:48:17 +00:00
g_free ( tvbs ) ;
}
if ( cinfo )
{
int col ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " col " ) ;
2016-10-15 18:48:17 +00:00
for ( col = 0 ; col < cinfo - > num_cols ; + + col )
{
const col_item_t * col_item = & cinfo - > columns [ col ] ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( NULL , col_item - > col_data ) ;
2016-10-15 18:48:17 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
}
2018-12-27 02:26:24 +00:00
if ( fdata - > ignored )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " i " , " true " ) ;
2018-06-16 16:22:00 +00:00
2018-12-27 02:26:24 +00:00
if ( fdata - > marked )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " m " , " true " ) ;
2018-06-16 16:22:00 +00:00
if ( fdata - > color_filter )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_stringf ( " bg " , " %x " , color_t_to_rgb ( & fdata - > color_filter - > bg_color ) ) ;
sharkd_json_value_stringf ( " fg " , " %x " , color_t_to_rgb ( & fdata - > color_filter - > fg_color ) ) ;
2018-06-16 16:22:00 +00:00
}
2016-10-15 18:48:17 +00:00
if ( data_src )
{
2017-12-07 19:37:54 +00:00
struct data_source * src = ( struct data_source * ) data_src - > data ;
2018-09-25 17:20:54 +00:00
gboolean ds_open = FALSE ;
2016-10-15 18:48:17 +00:00
tvbuff_t * tvb ;
guint length ;
tvb = get_data_source_tvb ( src ) ;
length = tvb_captured_length ( tvb ) ;
if ( length ! = 0 )
{
const guchar * cp = tvb_get_ptr ( tvb , 0 , length ) ;
2018-12-27 02:26:24 +00:00
/* XXX pi.fd->encoding */
2018-12-12 14:33:44 +00:00
sharkd_json_value_base64 ( " bytes " , cp , length ) ;
2016-10-15 18:48:17 +00:00
}
else
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_base64 ( " bytes " , " " , 0 ) ;
2016-10-15 18:48:17 +00:00
}
data_src = data_src - > next ;
if ( data_src )
{
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " ds " ) ;
2018-09-25 17:20:54 +00:00
ds_open = TRUE ;
2016-10-15 18:48:17 +00:00
}
while ( data_src )
{
2017-12-07 19:37:54 +00:00
src = ( struct data_source * ) data_src - > data ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2016-10-15 18:48:17 +00:00
{
char * src_name = get_data_source_name ( src ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " name " , src_name ) ;
2016-10-15 18:48:17 +00:00
wmem_free ( NULL , src_name ) ;
}
tvb = get_data_source_tvb ( src ) ;
length = tvb_captured_length ( tvb ) ;
if ( length ! = 0 )
{
const guchar * cp = tvb_get_ptr ( tvb , 0 , length ) ;
2018-12-27 02:26:24 +00:00
/* XXX pi.fd->encoding */
2018-12-12 14:33:44 +00:00
sharkd_json_value_base64 ( " bytes " , cp , length ) ;
2016-10-15 18:48:17 +00:00
}
else
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_base64 ( " bytes " , " " , 0 ) ;
2016-10-15 18:48:17 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
data_src = data_src - > next ;
}
/* close ds, only if was opened */
2018-09-25 17:20:54 +00:00
if ( ds_open )
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
}
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " fol " ) ;
2017-03-11 11:27:14 +00:00
follow_iterate_followers ( sharkd_follower_visit_layers_cb , pi ) ;
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-03-11 11:27:14 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
2018-05-06 16:15:58 +00:00
# define SHARKD_IOGRAPH_MAX_ITEMS 250000 /* 250k limit of items is taken from wireshark-qt, on x86_64 sizeof(io_graph_item_t) is 152, so single graph can take max 36 MB */
struct sharkd_iograph
{
/* config */
int hf_index ;
io_graph_item_unit_t calc_type ;
guint32 interval ;
/* result */
int space_items ;
int num_items ;
io_graph_item_t * items ;
GString * error ;
} ;
2019-01-01 03:36:12 +00:00
static tap_packet_status
2018-05-06 16:15:58 +00:00
sharkd_iograph_packet ( void * g , packet_info * pinfo , epan_dissect_t * edt , const void * dummy _U_ )
{
struct sharkd_iograph * graph = ( struct sharkd_iograph * ) g ;
int idx ;
2019-01-01 03:36:12 +00:00
gboolean update_succeeded ;
2018-05-06 16:15:58 +00:00
idx = get_io_graph_index ( pinfo , graph - > interval ) ;
if ( idx < 0 | | idx > = SHARKD_IOGRAPH_MAX_ITEMS )
2019-01-01 03:36:12 +00:00
return TAP_PACKET_DONT_REDRAW ;
2018-05-06 16:15:58 +00:00
if ( idx + 1 > graph - > num_items )
{
if ( idx + 1 > graph - > space_items )
{
2018-06-02 20:37:57 +00:00
int new_size = idx + 1024 ;
2018-05-06 16:15:58 +00:00
graph - > items = ( io_graph_item_t * ) g_realloc ( graph - > items , sizeof ( io_graph_item_t ) * new_size ) ;
reset_io_graph_items ( & graph - > items [ graph - > space_items ] , new_size - graph - > space_items ) ;
graph - > space_items = new_size ;
}
else if ( graph - > items = = NULL )
{
graph - > items = ( io_graph_item_t * ) g_malloc ( sizeof ( io_graph_item_t ) * graph - > space_items ) ;
reset_io_graph_items ( graph - > items , graph - > space_items ) ;
}
graph - > num_items = idx + 1 ;
}
2019-01-01 03:36:12 +00:00
update_succeeded = update_io_graph_item ( graph - > items , idx , pinfo , edt , graph - > hf_index , graph - > calc_type , graph - > interval ) ;
/* XXX - TAP_PACKET_FAILED if the item couldn't be updated, with an error message? */
return update_succeeded ? TAP_PACKET_REDRAW : TAP_PACKET_DONT_REDRAW ;
2018-05-06 16:15:58 +00:00
}
/**
* sharkd_session_process_iograph ( )
*
* Process iograph request
*
* Input :
* ( o ) interval - interval time in ms , if not specified : 1000 ms
* ( m ) graph0 - First graph request
* ( o ) graph1 . . . graph9 - Other graph requests
* ( o ) filter0 - First graph filter
* ( o ) filter1 . . . filter9 - Other graph filters
*
* Graph requests can be one of : " packets " , " bytes " , " bits " , " sum:<field> " , " frames:<field> " , " max:<field> " , " min:<field> " , " avg:<field> " , " load:<field> " ,
* if you use variant with < field > , you need to pass field name in filter request .
*
* Output object with attributes :
* ( m ) iograph - array of graph results with attributes :
* errmsg - graph cannot be constructed
* items - graph values , zeros are skipped , if value is not a number it ' s next index encoded as hex string
*/
static void
sharkd_session_process_iograph ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_interval = json_find_attr ( buf , tokens , count , " interval " ) ;
struct sharkd_iograph graphs [ 10 ] ;
gboolean is_any_ok = FALSE ;
int graph_count ;
guint32 interval_ms = 1000 ; /* default: one per second */
int i ;
if ( tok_interval )
{
if ( ! ws_strtou32 ( tok_interval , NULL , & interval_ms ) | | interval_ms = = 0 )
{
fprintf ( stderr , " Invalid interval parameter: %s. \n " , tok_interval ) ;
return ;
}
}
for ( i = graph_count = 0 ; i < ( int ) G_N_ELEMENTS ( graphs ) ; i + + )
{
struct sharkd_iograph * graph = & graphs [ graph_count ] ;
const char * tok_graph ;
const char * tok_filter ;
char tok_format_buf [ 32 ] ;
const char * field_name ;
snprintf ( tok_format_buf , sizeof ( tok_format_buf ) , " graph%d " , i ) ;
tok_graph = json_find_attr ( buf , tokens , count , tok_format_buf ) ;
if ( ! tok_graph )
break ;
snprintf ( tok_format_buf , sizeof ( tok_format_buf ) , " filter%d " , i ) ;
tok_filter = json_find_attr ( buf , tokens , count , tok_format_buf ) ;
if ( ! strcmp ( tok_graph , " packets " ) )
graph - > calc_type = IOG_ITEM_UNIT_PACKETS ;
else if ( ! strcmp ( tok_graph , " bytes " ) )
graph - > calc_type = IOG_ITEM_UNIT_BYTES ;
else if ( ! strcmp ( tok_graph , " bits " ) )
graph - > calc_type = IOG_ITEM_UNIT_BITS ;
else if ( g_str_has_prefix ( tok_graph , " sum: " ) )
graph - > calc_type = IOG_ITEM_UNIT_CALC_SUM ;
else if ( g_str_has_prefix ( tok_graph , " frames: " ) )
graph - > calc_type = IOG_ITEM_UNIT_CALC_FRAMES ;
else if ( g_str_has_prefix ( tok_graph , " fields: " ) )
graph - > calc_type = IOG_ITEM_UNIT_CALC_FIELDS ;
else if ( g_str_has_prefix ( tok_graph , " max: " ) )
graph - > calc_type = IOG_ITEM_UNIT_CALC_MAX ;
else if ( g_str_has_prefix ( tok_graph , " min: " ) )
graph - > calc_type = IOG_ITEM_UNIT_CALC_MIN ;
else if ( g_str_has_prefix ( tok_graph , " avg: " ) )
graph - > calc_type = IOG_ITEM_UNIT_CALC_AVERAGE ;
else if ( g_str_has_prefix ( tok_graph , " load: " ) )
graph - > calc_type = IOG_ITEM_UNIT_CALC_LOAD ;
else
break ;
field_name = strchr ( tok_graph , ' : ' ) ;
if ( field_name )
field_name = field_name + 1 ;
graph - > interval = interval_ms ;
graph - > hf_index = - 1 ;
graph - > error = check_field_unit ( field_name , & graph - > hf_index , graph - > calc_type ) ;
graph - > space_items = 0 ; /* TODO, can avoid realloc()s in sharkd_iograph_packet() by calculating: capture_time / interval */
graph - > num_items = 0 ;
graph - > items = NULL ;
if ( ! graph - > error )
2018-07-21 00:07:19 +00:00
graph - > error = register_tap_listener ( " frame " , graph , tok_filter , TL_REQUIRES_PROTO_TREE , NULL , sharkd_iograph_packet , NULL , NULL ) ;
2018-05-06 16:15:58 +00:00
graph_count + + ;
if ( graph - > error = = NULL )
is_any_ok = TRUE ;
}
/* retap only if we have at least one ok */
if ( is_any_ok )
sharkd_retap ( ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-05-06 16:15:58 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " iograph " ) ;
2018-05-06 16:15:58 +00:00
for ( i = 0 ; i < graph_count ; i + + )
{
struct sharkd_iograph * graph = & graphs [ i ] ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-05-06 16:15:58 +00:00
if ( graph - > error )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " errmsg " , graph - > error - > str ) ;
2018-05-06 16:15:58 +00:00
g_string_free ( graph - > error , TRUE ) ;
}
else
{
int idx ;
int next_idx = 0 ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " items " ) ;
2018-05-06 16:15:58 +00:00
for ( idx = 0 ; idx < graph - > num_items ; idx + + )
{
double val ;
val = get_io_graph_item ( graph - > items , graph - > calc_type , idx , graph - > hf_index , & cfile , graph - > interval , graph - > num_items ) ;
/* if it's zero, don't display */
if ( val = = 0.0 )
continue ;
/* cause zeros are not printed, need to output index */
if ( next_idx ! = idx )
2018-12-12 14:33:44 +00:00
sharkd_json_value_stringf ( NULL , " %x " , idx ) ;
2018-05-06 16:15:58 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( NULL , " %f " , val ) ;
2018-05-06 16:15:58 +00:00
next_idx = idx + 1 ;
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2018-05-06 16:15:58 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2018-05-06 16:15:58 +00:00
remove_tap_listener ( graph ) ;
g_free ( graph - > items ) ;
}
2018-09-24 18:34:30 +00:00
sharkd_json_array_close ( ) ;
2018-05-06 16:15:58 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2018-05-06 16:15:58 +00:00
}
2016-10-15 18:48:17 +00:00
/**
* sharkd_session_process_intervals ( )
*
* Process intervals request - generate basic capture file statistics per requested interval .
*
* Input :
* ( o ) interval - interval time in ms , if not specified : 1000 ms
* ( o ) filter - filter for generating interval request
*
* Output object with attributes :
* ( m ) intervals - array of intervals , with indexes :
* [ 0 ] - index of interval ,
* [ 1 ] - number of frames during interval ,
* [ 2 ] - number of bytes during interval .
*
* ( m ) last - last interval number .
* ( m ) frames - total number of frames
* ( m ) bytes - total number of bytes
*
* NOTE : If frames are not in order , there might be items with same interval index , or even negative one .
*/
static void
sharkd_session_process_intervals ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_interval = json_find_attr ( buf , tokens , count , " interval " ) ;
const char * tok_filter = json_find_attr ( buf , tokens , count , " filter " ) ;
const guint8 * filter_data = NULL ;
struct
{
unsigned int frames ;
guint64 bytes ;
2017-02-22 00:12:16 +00:00
} st , st_total ;
2016-10-15 18:48:17 +00:00
2017-12-07 20:56:11 +00:00
nstime_t * start_ts ;
2016-10-15 18:48:17 +00:00
guint32 interval_ms = 1000 ; /* default: one per second */
unsigned int framenum ;
2017-01-26 05:29:54 +00:00
gint64 idx ;
gint64 max_idx = 0 ;
2016-10-15 18:48:17 +00:00
2017-12-07 19:37:54 +00:00
if ( tok_interval )
{
if ( ! ws_strtou32 ( tok_interval , NULL , & interval_ms ) | | interval_ms = = 0 )
{
2017-01-25 14:35:09 +00:00
fprintf ( stderr , " Invalid interval parameter: %s. \n " , tok_interval ) ;
return ;
}
}
2016-10-15 18:48:17 +00:00
if ( tok_filter )
{
2018-09-01 16:47:38 +00:00
const struct sharkd_filter_item * filter_item ;
filter_item = sharkd_session_filter_data ( tok_filter ) ;
if ( ! filter_item )
2016-10-15 18:48:17 +00:00
return ;
2018-09-01 16:47:38 +00:00
filter_data = filter_item - > filtered ;
2016-10-15 18:48:17 +00:00
}
2017-02-22 00:12:16 +00:00
st_total . frames = 0 ;
st_total . bytes = 0 ;
2016-10-15 18:48:17 +00:00
2017-02-22 00:12:16 +00:00
st . frames = 0 ;
st . bytes = 0 ;
2016-10-15 18:48:17 +00:00
idx = 0 ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_array_open ( " intervals " ) ;
2016-10-15 18:48:17 +00:00
2017-12-07 20:56:11 +00:00
start_ts = ( cfile . count > = 1 ) ? & ( sharkd_get_frame ( 1 ) - > abs_ts ) : NULL ;
2016-10-15 18:48:17 +00:00
for ( framenum = 1 ; framenum < = cfile . count ; framenum + + )
{
2017-12-07 20:56:11 +00:00
frame_data * fdata ;
2017-01-26 05:29:54 +00:00
gint64 msec_rel ;
gint64 new_idx ;
2016-10-15 18:48:17 +00:00
if ( filter_data & & ! ( filter_data [ framenum / 8 ] & ( 1 < < ( framenum % 8 ) ) ) )
continue ;
2017-12-07 20:56:11 +00:00
fdata = sharkd_get_frame ( framenum ) ;
2017-03-12 08:23:17 +00:00
msec_rel = ( fdata - > abs_ts . secs - start_ts - > secs ) * ( gint64 ) 1000 + ( fdata - > abs_ts . nsecs - start_ts - > nsecs ) / 1000000 ;
2016-10-15 18:48:17 +00:00
new_idx = msec_rel / interval_ms ;
if ( idx ! = new_idx )
{
2017-02-22 00:12:16 +00:00
if ( st . frames ! = 0 )
2016-10-15 18:48:17 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( NULL , " [% " G_GINT64_FORMAT " ,%u,% " G_GUINT64_FORMAT " ] " , idx , st . frames , st . bytes ) ;
2016-10-15 18:48:17 +00:00
}
idx = new_idx ;
if ( idx > max_idx )
max_idx = idx ;
2017-02-22 00:12:16 +00:00
st . frames = 0 ;
st . bytes = 0 ;
2016-10-15 18:48:17 +00:00
}
2017-02-22 00:12:16 +00:00
st . frames + = 1 ;
st . bytes + = fdata - > pkt_len ;
2016-10-15 18:48:17 +00:00
2017-02-22 00:12:16 +00:00
st_total . frames + = 1 ;
st_total . bytes + = fdata - > pkt_len ;
2016-10-15 18:48:17 +00:00
}
2017-02-22 00:12:16 +00:00
if ( st . frames ! = 0 )
2016-10-15 18:48:17 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( NULL , " [% " G_GINT64_FORMAT " ,%u,% " G_GUINT64_FORMAT " ] " , idx , st . frames , st . bytes ) ;
2016-10-15 18:48:17 +00:00
}
2018-09-24 18:34:30 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " last " , " % " G_GINT64_FORMAT , max_idx ) ;
sharkd_json_value_anyf ( " frames " , " %u " , st_total . frames ) ;
sharkd_json_value_anyf ( " bytes " , " % " G_GUINT64_FORMAT , st_total . bytes ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
/**
* sharkd_session_process_frame ( )
*
* Process frame request
*
* Input :
* ( m ) frame - requested frame number
2017-12-28 12:07:54 +00:00
* ( o ) ref_frame - time reference frame number
* ( o ) prev_frame - previously displayed frame number
2016-10-15 18:48:17 +00:00
* ( o ) proto - set if output frame tree
* ( o ) columns - set if output frame columns
2018-06-16 16:22:00 +00:00
* ( o ) color - set if output color - filter bg / fg
2016-10-15 18:48:17 +00:00
* ( o ) bytes - set if output frame bytes
2018-07-22 12:54:36 +00:00
* ( o ) hidden - set if output hidden tree fields
2016-10-15 18:48:17 +00:00
*
* Output object with attributes :
* ( m ) err - 0 if succeed
* ( o ) tree - array of frame nodes with attributes :
* l - label
2017-03-12 08:23:17 +00:00
* t : ' proto ' , ' framenum ' , ' url ' - type of node
2017-10-04 20:41:19 +00:00
* f - filter string
2016-10-15 18:48:17 +00:00
* s - severity
* e - subtree ett index
* n - array of subtree nodes
* h - two item array : ( item start , item length )
* i - two item array : ( appendix start , appendix length )
* p - [ RESERVED ] two item array : ( protocol start , protocol length )
* ds - data src index
2017-03-12 08:23:17 +00:00
* url - only for t : ' url ' , url
* fnum - only for t : ' framenum ' , frame number
2018-07-22 12:54:36 +00:00
* g - if field is generated by Wireshark
* v - if field is hidden
2016-10-15 18:48:17 +00:00
*
* ( o ) col - array of column data
* ( o ) bytes - base64 of frame bytes
* ( o ) ds - array of other data srcs
2017-09-26 21:42:20 +00:00
* ( o ) comment - frame comment
2017-03-11 11:27:14 +00:00
* ( o ) fol - array of follow filters :
* [ 0 ] - protocol
* [ 1 ] - filter string
2018-06-16 16:22:00 +00:00
* ( o ) i - if frame is ignored
* ( o ) m - if frame is marked
* ( o ) bg - color filter - background color in hex
* ( o ) fg - color filter - foreground color in hex
2016-10-15 18:48:17 +00:00
*/
static void
sharkd_session_process_frame ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_frame = json_find_attr ( buf , tokens , count , " frame " ) ;
2017-12-28 12:07:54 +00:00
const char * tok_ref_frame = json_find_attr ( buf , tokens , count , " ref_frame " ) ;
const char * tok_prev_frame = json_find_attr ( buf , tokens , count , " prev_frame " ) ;
2018-09-23 22:03:58 +00:00
2017-12-28 12:07:54 +00:00
guint32 framenum , ref_frame_num , prev_dis_num ;
2018-06-16 16:22:00 +00:00
guint32 dissect_flags = SHARKD_DISSECT_FLAG_NULL ;
2018-09-23 22:03:58 +00:00
struct sharkd_frame_request_data req_data ;
2016-10-15 18:48:17 +00:00
if ( ! tok_frame | | ! ws_strtou32 ( tok_frame , NULL , & framenum ) | | framenum = = 0 )
return ;
2017-12-28 12:07:54 +00:00
ref_frame_num = ( framenum ! = 1 ) ? 1 : 0 ;
if ( tok_ref_frame & & ( ! ws_strtou32 ( tok_ref_frame , NULL , & ref_frame_num ) | | ref_frame_num > framenum ) )
return ;
prev_dis_num = framenum - 1 ;
if ( tok_prev_frame & & ( ! ws_strtou32 ( tok_prev_frame , NULL , & prev_dis_num ) | | prev_dis_num > = framenum ) )
return ;
2018-09-23 22:03:58 +00:00
if ( json_find_attr ( buf , tokens , count , " proto " ) ! = NULL )
dissect_flags | = SHARKD_DISSECT_FLAG_PROTO_TREE ;
if ( json_find_attr ( buf , tokens , count , " bytes " ) ! = NULL )
dissect_flags | = SHARKD_DISSECT_FLAG_BYTES ;
if ( json_find_attr ( buf , tokens , count , " columns " ) ! = NULL )
dissect_flags | = SHARKD_DISSECT_FLAG_COLUMNS ;
if ( json_find_attr ( buf , tokens , count , " color " ) ! = NULL )
dissect_flags | = SHARKD_DISSECT_FLAG_COLOR ;
2018-07-22 12:54:36 +00:00
req_data . display_hidden = ( json_find_attr ( buf , tokens , count , " v " ) ! = NULL ) ;
sharkd_dissect_request ( framenum , ref_frame_num , prev_dis_num , & sharkd_session_process_frame_cb , dissect_flags , & req_data ) ;
2016-10-15 18:48:17 +00:00
}
/**
* sharkd_session_process_check ( )
*
* Process check request .
*
* Input :
* ( o ) filter - filter to be checked
2018-09-24 07:24:55 +00:00
* ( o ) field - field to be checked
2016-10-15 18:48:17 +00:00
*
* Output object with attributes :
* ( m ) err - always 0
* ( o ) filter - ' ok ' , ' warn ' or error message
2018-09-24 07:24:55 +00:00
* ( o ) field - ' ok ' , or ' notfound '
2016-10-15 18:48:17 +00:00
*/
static int
sharkd_session_process_check ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_filter = json_find_attr ( buf , tokens , count , " filter " ) ;
2018-09-24 07:24:55 +00:00
const char * tok_field = json_find_attr ( buf , tokens , count , " field " ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_anyf ( " err " , " 0 " ) ;
2018-09-24 07:24:55 +00:00
2016-10-15 18:48:17 +00:00
if ( tok_filter ! = NULL )
{
char * err_msg = NULL ;
dfilter_t * dfp ;
if ( dfilter_compile ( tok_filter , & dfp , & err_msg ) )
{
const char * s = " ok " ;
2018-09-23 20:14:21 +00:00
if ( dfp & & dfilter_deprecated_tokens ( dfp ) )
2016-10-15 18:48:17 +00:00
s = " warn " ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " filter " , s ) ;
2016-10-15 18:48:17 +00:00
dfilter_free ( dfp ) ;
}
else
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " filter " , err_msg ) ;
2016-10-15 18:48:17 +00:00
g_free ( err_msg ) ;
}
}
2018-09-24 07:24:55 +00:00
if ( tok_field ! = NULL )
{
header_field_info * hfi = proto_registrar_get_byname ( tok_field ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " field " , ( hfi ) ? " ok " : " notfound " ) ;
2018-09-24 07:24:55 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2016-10-15 18:48:17 +00:00
return 0 ;
}
struct sharkd_session_process_complete_pref_data
{
const char * module ;
const char * pref ;
} ;
static guint
sharkd_session_process_complete_pref_cb ( module_t * module , gpointer d )
{
struct sharkd_session_process_complete_pref_data * data = ( struct sharkd_session_process_complete_pref_data * ) d ;
if ( strncmp ( data - > pref , module - > name , strlen ( data - > pref ) ) ! = 0 )
return 0 ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " f " , module - > name ) ;
sharkd_json_value_string ( " d " , module - > title ) ;
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
return 0 ;
}
static guint
sharkd_session_process_complete_pref_option_cb ( pref_t * pref , gpointer d )
{
struct sharkd_session_process_complete_pref_data * data = ( struct sharkd_session_process_complete_pref_data * ) d ;
const char * pref_name = prefs_get_name ( pref ) ;
const char * pref_title = prefs_get_title ( pref ) ;
if ( strncmp ( data - > pref , pref_name , strlen ( data - > pref ) ) ! = 0 )
return 0 ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_stringf ( " f " , " %s.%s " , data - > module , pref_name ) ;
sharkd_json_value_string ( " d " , pref_title ) ;
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
return 0 ; /* continue */
}
/**
* sharkd_session_process_complete ( )
*
* Process complete request
*
* Input :
* ( o ) field - field to be completed
* ( o ) pref - preference to be completed
*
* Output object with attributes :
* ( m ) err - always 0
* ( o ) field - array of object with attributes :
* ( m ) f - field text
* ( o ) t - field type ( FT_ number )
* ( o ) n - field name
* ( o ) pref - array of object with attributes :
* ( m ) f - pref name
* ( o ) d - pref description
*/
static int
sharkd_session_process_complete ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_field = json_find_attr ( buf , tokens , count , " field " ) ;
const char * tok_pref = json_find_attr ( buf , tokens , count , " pref " ) ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_anyf ( " err " , " 0 " ) ;
2018-09-25 17:20:54 +00:00
2016-10-15 18:48:17 +00:00
if ( tok_field ! = NULL & & tok_field [ 0 ] )
{
const size_t filter_length = strlen ( tok_field ) ;
const int filter_with_dot = ! ! strchr ( tok_field , ' . ' ) ;
void * proto_cookie ;
void * field_cookie ;
int proto_id ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " field " ) ;
2016-10-15 18:48:17 +00:00
for ( proto_id = proto_get_first_protocol ( & proto_cookie ) ; proto_id ! = - 1 ; proto_id = proto_get_next_protocol ( & proto_cookie ) )
{
protocol_t * protocol = find_protocol_by_id ( proto_id ) ;
const char * protocol_filter ;
const char * protocol_name ;
header_field_info * hfinfo ;
if ( ! proto_is_protocol_enabled ( protocol ) )
continue ;
protocol_name = proto_get_protocol_long_name ( protocol ) ;
protocol_filter = proto_get_protocol_filter_name ( proto_id ) ;
if ( strlen ( protocol_filter ) > = filter_length & & ! g_ascii_strncasecmp ( tok_field , protocol_filter , filter_length ) )
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " f " , protocol_filter ) ;
sharkd_json_value_anyf ( " t " , " %d " , FT_PROTOCOL ) ;
sharkd_json_value_string ( " n " , protocol_name ) ;
2016-10-15 18:48:17 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
if ( ! filter_with_dot )
continue ;
for ( hfinfo = proto_get_first_protocol_field ( proto_id , & field_cookie ) ; hfinfo ! = NULL ; hfinfo = proto_get_next_protocol_field ( proto_id , & field_cookie ) )
{
if ( hfinfo - > same_name_prev_id ! = - 1 ) /* ignore duplicate names */
continue ;
if ( strlen ( hfinfo - > abbrev ) > = filter_length & & ! g_ascii_strncasecmp ( tok_field , hfinfo - > abbrev , filter_length ) )
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " f " , hfinfo - > abbrev ) ;
2016-10-15 18:48:17 +00:00
/* XXX, skip displaying name, if there are multiple (to not confuse user) */
if ( hfinfo - > same_name_next = = NULL )
{
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " t " , " %d " , hfinfo - > type ) ;
sharkd_json_value_string ( " n " , hfinfo - > name ) ;
2016-10-15 18:48:17 +00:00
}
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
}
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
}
if ( tok_pref ! = NULL & & tok_pref [ 0 ] )
{
struct sharkd_session_process_complete_pref_data data ;
char * dot_sepa ;
data . module = tok_pref ;
data . pref = tok_pref ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " pref " ) ;
2016-10-15 18:48:17 +00:00
if ( ( dot_sepa = strchr ( tok_pref , ' . ' ) ) )
{
module_t * pref_mod ;
* dot_sepa = ' \0 ' ; /* XXX, C abuse: discarding-const */
data . pref = dot_sepa + 1 ;
pref_mod = prefs_find_module ( data . module ) ;
if ( pref_mod )
prefs_pref_foreach ( pref_mod , sharkd_session_process_complete_pref_option_cb , & data ) ;
* dot_sepa = ' . ' ;
}
else
{
prefs_modules_foreach ( sharkd_session_process_complete_pref_cb , & data ) ;
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2016-10-15 18:48:17 +00:00
}
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
return 0 ;
}
2017-12-06 18:51:18 +00:00
/**
* sharkd_session_process_setcomment ( )
*
* Process setcomment request
*
* Input :
* ( m ) frame - frame number
* ( o ) comment - user comment
*
* Output object with attributes :
* ( m ) err - error code : 0 succeed
*/
static void
sharkd_session_process_setcomment ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_frame = json_find_attr ( buf , tokens , count , " frame " ) ;
const char * tok_comment = json_find_attr ( buf , tokens , count , " comment " ) ;
guint32 framenum ;
frame_data * fdata ;
int ret ;
if ( ! tok_frame | | ! ws_strtou32 ( tok_frame , NULL , & framenum ) | | framenum = = 0 )
return ;
2017-12-07 20:56:11 +00:00
fdata = sharkd_get_frame ( framenum ) ;
2017-12-06 18:51:18 +00:00
if ( ! fdata )
return ;
ret = sharkd_set_user_comment ( fdata , tok_comment ) ;
2018-09-25 17:20:54 +00:00
sharkd_json_simple_reply ( ret , NULL ) ;
2017-12-06 18:51:18 +00:00
}
2016-10-15 18:48:17 +00:00
/**
* sharkd_session_process_setconf ( )
*
* Process setconf request
*
* Input :
* ( m ) name - preference name
* ( m ) value - preference value
*
* Output object with attributes :
* ( m ) err - error code : 0 succeed
*/
static void
sharkd_session_process_setconf ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_name = json_find_attr ( buf , tokens , count , " name " ) ;
const char * tok_value = json_find_attr ( buf , tokens , count , " value " ) ;
char pref [ 4096 ] ;
2017-05-24 22:28:45 +00:00
char * errmsg = NULL ;
2016-10-15 18:48:17 +00:00
prefs_set_pref_e ret ;
if ( ! tok_name | | tok_name [ 0 ] = = ' \0 ' | | ! tok_value )
return ;
2017-01-26 01:27:13 +00:00
ws_snprintf ( pref , sizeof ( pref ) , " %s:%s " , tok_name , tok_value ) ;
2016-10-15 18:48:17 +00:00
2017-05-24 22:28:45 +00:00
ret = prefs_set_pref ( pref , & errmsg ) ;
2018-09-25 17:20:54 +00:00
sharkd_json_simple_reply ( ret , errmsg ) ;
2017-05-24 22:28:45 +00:00
g_free ( errmsg ) ;
2016-10-15 18:48:17 +00:00
}
struct sharkd_session_process_dumpconf_data
{
module_t * module ;
} ;
static guint
sharkd_session_process_dumpconf_cb ( pref_t * pref , gpointer d )
{
struct sharkd_session_process_dumpconf_data * data = ( struct sharkd_session_process_dumpconf_data * ) d ;
const char * pref_name = prefs_get_name ( pref ) ;
2018-09-25 17:20:54 +00:00
char json_pref_key [ 512 ] ;
snprintf ( json_pref_key , sizeof ( json_pref_key ) , " %s.%s " , data - > module - > name , pref_name ) ;
2018-12-12 14:33:44 +00:00
json_dumper_set_member_name ( & dumper , json_pref_key ) ;
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
2017-02-12 23:09:16 +00:00
switch ( prefs_get_type ( pref ) )
{
case PREF_UINT :
case PREF_DECODE_AS_UINT :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " u " , " %u " , prefs_get_uint_value_real ( pref , pref_current ) ) ;
2017-02-12 23:09:16 +00:00
if ( prefs_get_uint_base ( pref ) ! = 10 )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " ub " , " %u " , prefs_get_uint_base ( pref ) ) ;
2017-02-12 23:09:16 +00:00
break ;
case PREF_BOOL :
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " b " , prefs_get_bool_value ( pref , pref_current ) ? " 1 " : " 0 " ) ;
2017-02-12 23:09:16 +00:00
break ;
case PREF_STRING :
2017-08-28 18:24:08 +00:00
case PREF_SAVE_FILENAME :
case PREF_OPEN_FILENAME :
case PREF_DIRNAME :
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " s " , prefs_get_string_value ( pref , pref_current ) ) ;
2017-02-12 23:09:16 +00:00
break ;
case PREF_ENUM :
{
const enum_val_t * enums ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " e " ) ;
2017-02-12 23:09:16 +00:00
for ( enums = prefs_get_enumvals ( pref ) ; enums - > name ; enums + + )
{
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " v " , " %d " , enums - > value ) ;
2017-02-12 23:09:16 +00:00
if ( enums - > value = = prefs_get_enum_value ( pref , pref_current ) )
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " s " , " 1 " ) ;
2017-02-12 23:09:16 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " d " , enums - > description ) ;
2017-02-12 23:09:16 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2017-02-12 23:09:16 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-02-12 23:09:16 +00:00
break ;
}
case PREF_RANGE :
case PREF_DECODE_AS_RANGE :
{
char * range_str = range_convert_range ( NULL , prefs_get_range_value_real ( pref , pref_current ) ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " r " , range_str ) ;
2017-02-12 23:09:16 +00:00
wmem_free ( NULL , range_str ) ;
break ;
}
case PREF_UAT :
2017-05-15 13:07:34 +00:00
{
uat_t * uat = prefs_get_uat_value ( pref ) ;
guint idx ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( " t " ) ;
2017-05-15 13:07:34 +00:00
for ( idx = 0 ; idx < uat - > raw_data - > len ; idx + + )
{
void * rec = UAT_INDEX_PTR ( uat , idx ) ;
guint colnum ;
2018-12-12 14:33:44 +00:00
sharkd_json_array_open ( NULL ) ;
2017-05-15 13:07:34 +00:00
for ( colnum = 0 ; colnum < uat - > ncols ; colnum + + )
{
char * str = uat_fld_tostr ( rec , & ( uat - > fields [ colnum ] ) ) ;
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( NULL , str ) ;
2017-05-15 13:07:34 +00:00
g_free ( str ) ;
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-05-15 13:07:34 +00:00
}
2018-09-24 16:55:27 +00:00
sharkd_json_array_close ( ) ;
2017-05-15 13:07:34 +00:00
break ;
}
2017-02-12 23:09:16 +00:00
case PREF_COLOR :
case PREF_CUSTOM :
case PREF_STATIC_TEXT :
case PREF_OBSOLETE :
/* TODO */
break ;
}
#if 0
2018-12-12 14:33:44 +00:00
sharkd_json_value_string ( " t " , prefs_get_title ( pref ) ) ;
2017-02-12 23:09:16 +00:00
# endif
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
return 0 ; /* continue */
}
static guint
sharkd_session_process_dumpconf_mod_cb ( module_t * module , gpointer d )
{
struct sharkd_session_process_dumpconf_data * data = ( struct sharkd_session_process_dumpconf_data * ) d ;
data - > module = module ;
prefs_pref_foreach ( module , sharkd_session_process_dumpconf_cb , data ) ;
return 0 ;
}
/**
* sharkd_session_process_dumpconf ( )
*
* Process dumpconf request
*
* Input :
* ( o ) pref - module , or preference , NULL for all
*
* Output object with attributes :
* ( o ) prefs - object with module preferences
* ( m ) [ KEY ] - preference name
2017-08-28 18:24:08 +00:00
* ( o ) u - preference value ( for PREF_UINT , PREF_DECODE_AS_UINT )
* ( o ) ub - preference value suggested base for display ( for PREF_UINT , PREF_DECODE_AS_UINT ) and if different than 10
2016-10-15 18:48:17 +00:00
* ( o ) b - preference value ( only for PREF_BOOL ) ( 1 true , 0 false )
2017-08-28 18:24:08 +00:00
* ( o ) s - preference value ( for PREF_STRING , PREF_SAVE_FILENAME , PREF_OPEN_FILENAME , PREF_DIRNAME )
2016-10-15 18:48:17 +00:00
* ( o ) e - preference possible values ( only for PREF_ENUM )
2017-08-28 18:24:08 +00:00
* ( o ) r - preference value ( for PREF_RANGE , PREF_DECODE_AS_RANGE )
2016-10-15 18:48:17 +00:00
* ( o ) t - preference value ( only for PREF_UAT )
*/
static void
sharkd_session_process_dumpconf ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_pref = json_find_attr ( buf , tokens , count , " pref " ) ;
module_t * pref_mod ;
char * dot_sepa ;
if ( ! tok_pref )
{
struct sharkd_session_process_dumpconf_data data ;
data . module = NULL ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " prefs " , NULL ) ;
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
prefs_modules_foreach ( sharkd_session_process_dumpconf_mod_cb , & data ) ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
return ;
}
if ( ( dot_sepa = strchr ( tok_pref , ' . ' ) ) )
{
pref_t * pref = NULL ;
* dot_sepa = ' \0 ' ; /* XXX, C abuse: discarding-const */
pref_mod = prefs_find_module ( tok_pref ) ;
if ( pref_mod )
pref = prefs_find_preference ( pref_mod , dot_sepa + 1 ) ;
* dot_sepa = ' . ' ;
if ( pref )
{
struct sharkd_session_process_dumpconf_data data ;
data . module = pref_mod ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " prefs " , NULL ) ;
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
sharkd_session_process_dumpconf_cb ( pref , & data ) ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2016-10-15 18:48:17 +00:00
}
return ;
}
pref_mod = prefs_find_module ( tok_pref ) ;
if ( pref_mod )
{
struct sharkd_session_process_dumpconf_data data ;
data . module = pref_mod ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " prefs " , NULL ) ;
json_dumper_begin_object ( & dumper ) ;
2016-10-15 18:48:17 +00:00
prefs_pref_foreach ( pref_mod , sharkd_session_process_dumpconf_cb , & data ) ;
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
2018-09-25 17:20:54 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2017-09-26 21:42:20 +00:00
}
2016-10-15 18:48:17 +00:00
}
2017-04-08 08:15:11 +00:00
struct sharkd_download_rtp
{
2018-06-15 20:47:47 +00:00
rtpstream_id_t id ;
2017-04-08 08:15:11 +00:00
GSList * packets ;
double start_time ;
} ;
static void
sharkd_rtp_download_free_items ( void * ptr )
{
rtp_packet_t * rtp_packet = ( rtp_packet_t * ) ptr ;
g_free ( rtp_packet - > info ) ;
g_free ( rtp_packet - > payload_data ) ;
g_free ( rtp_packet ) ;
}
static void
sharkd_rtp_download_decode ( struct sharkd_download_rtp * req )
{
/* based on RtpAudioStream::decode() 6e29d874f8b5e6ebc59f661a0bb0dab8e56f122a */
/* TODO, for now only without silence (timing_mode_ = Uninterrupted) */
static const int sample_bytes_ = sizeof ( SAMPLE ) / sizeof ( char ) ;
guint32 audio_out_rate_ = 0 ;
struct _GHashTable * decoders_hash_ = rtp_decoder_hash_table_new ( ) ;
struct SpeexResamplerState_ * audio_resampler_ = NULL ;
gsize resample_buff_len = 0x1000 ;
SAMPLE * resample_buff = ( SAMPLE * ) g_malloc ( resample_buff_len ) ;
spx_uint32_t cur_in_rate = 0 ;
char * write_buff = NULL ;
2019-02-05 20:32:17 +00:00
size_t write_bytes = 0 ;
2017-04-08 08:15:11 +00:00
unsigned channels = 0 ;
unsigned sample_rate = 0 ;
GSList * l ;
for ( l = req - > packets ; l ; l = l - > next )
{
rtp_packet_t * rtp_packet = ( rtp_packet_t * ) l - > data ;
SAMPLE * decode_buff = NULL ;
size_t decoded_bytes ;
decoded_bytes = decode_rtp_packet ( rtp_packet , & decode_buff , decoders_hash_ , & channels , & sample_rate ) ;
if ( decoded_bytes = = 0 | | sample_rate = = 0 )
{
/* We didn't decode anything. Clean up and prep for the next packet. */
g_free ( decode_buff ) ;
continue ;
}
if ( audio_out_rate_ = = 0 )
{
guint32 tmp32 ;
guint16 tmp16 ;
char wav_hdr [ 44 ] ;
/* First non-zero wins */
audio_out_rate_ = sample_rate ;
RTP_STREAM_DEBUG ( " Audio sample rate is %u " , audio_out_rate_ ) ;
/* write WAVE header */
memset ( & wav_hdr , 0 , sizeof ( wav_hdr ) ) ;
memcpy ( & wav_hdr [ 0 ] , " RIFF " , 4 ) ;
memcpy ( & wav_hdr [ 4 ] , " \xFF \xFF \xFF \xFF " , 4 ) ; /* XXX, unknown */
memcpy ( & wav_hdr [ 8 ] , " WAVE " , 4 ) ;
memcpy ( & wav_hdr [ 12 ] , " fmt " , 4 ) ;
memcpy ( & wav_hdr [ 16 ] , " \x10 \x00 \x00 \x00 " , 4 ) ; /* PCM */
memcpy ( & wav_hdr [ 20 ] , " \x01 \x00 " , 2 ) ; /* PCM */
/* # channels */
tmp16 = channels ;
memcpy ( & wav_hdr [ 22 ] , & tmp16 , 2 ) ;
/* sample rate */
tmp32 = sample_rate ;
memcpy ( & wav_hdr [ 24 ] , & tmp32 , 4 ) ;
/* byte rate */
tmp32 = sample_rate * channels * sample_bytes_ ;
memcpy ( & wav_hdr [ 28 ] , & tmp32 , 4 ) ;
/* block align */
tmp16 = channels * sample_bytes_ ;
memcpy ( & wav_hdr [ 32 ] , & tmp16 , 2 ) ;
/* bits per sample */
tmp16 = 8 * sample_bytes_ ;
memcpy ( & wav_hdr [ 34 ] , & tmp16 , 2 ) ;
memcpy ( & wav_hdr [ 36 ] , " data " , 4 ) ;
memcpy ( & wav_hdr [ 40 ] , " \xFF \xFF \xFF \xFF " , 4 ) ; /* XXX, unknown */
2018-12-12 14:33:44 +00:00
json_dumper_write_base64 ( & dumper , wav_hdr , sizeof ( wav_hdr ) ) ;
2017-04-08 08:15:11 +00:00
}
// Write samples to our file.
write_buff = ( char * ) decode_buff ;
write_bytes = decoded_bytes ;
if ( audio_out_rate_ ! = sample_rate )
{
spx_uint32_t in_len , out_len ;
/* Resample the audio to match our previous output rate. */
if ( ! audio_resampler_ )
{
audio_resampler_ = speex_resampler_init ( 1 , sample_rate , audio_out_rate_ , 10 , NULL ) ;
speex_resampler_skip_zeros ( audio_resampler_ ) ;
RTP_STREAM_DEBUG ( " Started resampling from %u to (out) %u Hz. " , sample_rate , audio_out_rate_ ) ;
}
else
{
spx_uint32_t audio_out_rate ;
speex_resampler_get_rate ( audio_resampler_ , & cur_in_rate , & audio_out_rate ) ;
if ( sample_rate ! = cur_in_rate )
{
speex_resampler_set_rate ( audio_resampler_ , sample_rate , audio_out_rate ) ;
RTP_STREAM_DEBUG ( " Changed input rate from %u to %u Hz. Out is %u. " , cur_in_rate , sample_rate , audio_out_rate_ ) ;
}
}
in_len = ( spx_uint32_t ) rtp_packet - > info - > info_payload_len ;
out_len = ( audio_out_rate_ * ( spx_uint32_t ) rtp_packet - > info - > info_payload_len / sample_rate ) + ( audio_out_rate_ % sample_rate ! = 0 ) ;
if ( out_len * sample_bytes_ > resample_buff_len )
{
while ( ( out_len * sample_bytes_ > resample_buff_len ) )
resample_buff_len * = 2 ;
resample_buff = ( SAMPLE * ) g_realloc ( resample_buff , resample_buff_len ) ;
}
speex_resampler_process_int ( audio_resampler_ , 0 , decode_buff , & in_len , resample_buff , & out_len ) ;
write_buff = ( char * ) resample_buff ;
write_bytes = out_len * sample_bytes_ ;
}
/* Write the decoded, possibly-resampled audio */
2018-12-12 14:33:44 +00:00
json_dumper_write_base64 ( & dumper , write_buff , write_bytes ) ;
2017-04-08 08:15:11 +00:00
g_free ( decode_buff ) ;
}
g_free ( resample_buff ) ;
g_hash_table_destroy ( decoders_hash_ ) ;
}
2019-01-01 03:36:12 +00:00
static tap_packet_status
2017-04-08 08:15:11 +00:00
sharkd_session_packet_download_tap_rtp_cb ( void * tapdata , packet_info * pinfo , epan_dissect_t * edt _U_ , const void * data )
{
const struct _rtp_info * rtp_info = ( const struct _rtp_info * ) data ;
struct sharkd_download_rtp * req_rtp = ( struct sharkd_download_rtp * ) tapdata ;
/* do not consider RTP packets without a setup frame */
if ( rtp_info - > info_setup_frame_num = = 0 )
2019-01-01 03:36:12 +00:00
return TAP_PACKET_DONT_REDRAW ;
2017-04-08 08:15:11 +00:00
2018-06-15 20:47:47 +00:00
if ( rtpstream_id_equal_pinfo_rtp_info ( & req_rtp - > id , pinfo , rtp_info ) )
2017-04-08 08:15:11 +00:00
{
rtp_packet_t * rtp_packet ;
rtp_packet = g_new0 ( rtp_packet_t , 1 ) ;
rtp_packet - > info = ( struct _rtp_info * ) g_memdup ( rtp_info , sizeof ( struct _rtp_info ) ) ;
if ( rtp_info - > info_all_data_present & & rtp_info - > info_payload_len ! = 0 )
rtp_packet - > payload_data = ( guint8 * ) g_memdup ( & ( rtp_info - > info_data [ rtp_info - > info_payload_offset ] ) , rtp_info - > info_payload_len ) ;
if ( ! req_rtp - > packets )
req_rtp - > start_time = nstime_to_sec ( & pinfo - > abs_ts ) ;
rtp_packet - > frame_num = pinfo - > num ;
rtp_packet - > arrive_offset = nstime_to_sec ( & pinfo - > abs_ts ) - req_rtp - > start_time ;
/* XXX, O(n) optimize */
req_rtp - > packets = g_slist_append ( req_rtp - > packets , rtp_packet ) ;
}
2019-01-01 03:36:12 +00:00
return TAP_PACKET_DONT_REDRAW ;
2017-04-08 08:15:11 +00:00
}
2017-03-11 11:27:14 +00:00
/**
* sharkd_session_process_download ( )
*
* Process download request
*
* Input :
* ( m ) token - token to download
*
* Output object with attributes :
* ( o ) file - suggested name of file
* ( o ) mime - suggested content type
* ( o ) data - payload base64 encoded
*/
static void
sharkd_session_process_download ( char * buf , const jsmntok_t * tokens , int count )
{
const char * tok_token = json_find_attr ( buf , tokens , count , " token " ) ;
if ( ! tok_token )
return ;
if ( ! strncmp ( tok_token , " eo: " , 3 ) )
{
struct sharkd_export_object_list * object_list ;
const export_object_entry_t * eo_entry = NULL ;
for ( object_list = sharkd_eo_list ; object_list ; object_list = object_list - > next )
{
size_t eo_type_len = strlen ( object_list - > type ) ;
if ( ! strncmp ( tok_token , object_list - > type , eo_type_len ) & & tok_token [ eo_type_len ] = = ' _ ' )
{
int row ;
2017-03-26 23:25:49 +00:00
if ( sscanf ( & tok_token [ eo_type_len + 1 ] , " %d " , & row ) ! = 1 )
break ;
2017-03-11 11:27:14 +00:00
eo_entry = ( export_object_entry_t * ) g_slist_nth_data ( object_list - > entries , row ) ;
break ;
}
}
if ( eo_entry )
{
const char * mime = ( eo_entry - > content_type ) ? eo_entry - > content_type : " application/octet-stream " ;
const char * filename = ( eo_entry - > filename ) ? eo_entry - > filename : tok_token ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " file " , filename ) ;
sharkd_json_value_string ( " mime " , mime ) ;
sharkd_json_value_base64 ( " data " , eo_entry - > payload_data , ( size_t ) eo_entry - > payload_len ) ;
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2017-03-11 11:27:14 +00:00
}
}
2017-03-25 12:05:50 +00:00
else if ( ! strcmp ( tok_token , " ssl-secrets " ) )
{
char * str = ssl_export_sessions ( ) ;
if ( str )
{
const char * mime = " text/plain " ;
const char * filename = " keylog.txt " ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " file " , filename ) ;
sharkd_json_value_string ( " mime " , mime ) ;
sharkd_json_value_base64 ( " data " , str , strlen ( str ) ) ;
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2017-03-25 12:05:50 +00:00
}
g_free ( str ) ;
}
2017-04-08 08:15:11 +00:00
else if ( ! strncmp ( tok_token , " rtp: " , 4 ) )
{
struct sharkd_download_rtp rtp_req ;
GString * tap_error ;
memset ( & rtp_req , 0 , sizeof ( rtp_req ) ) ;
2018-06-15 20:47:47 +00:00
if ( ! sharkd_rtp_match_init ( & rtp_req . id , tok_token + 4 ) )
2017-04-08 08:15:11 +00:00
{
fprintf ( stderr , " sharkd_session_process_download() rtp tokenizing error %s \n " , tok_token ) ;
return ;
}
2018-07-21 00:07:19 +00:00
tap_error = register_tap_listener ( " rtp " , & rtp_req , NULL , 0 , NULL , sharkd_session_packet_download_tap_rtp_cb , NULL , NULL ) ;
2017-04-08 08:15:11 +00:00
if ( tap_error )
{
fprintf ( stderr , " sharkd_session_process_download() rtp error=%s " , tap_error - > str ) ;
g_string_free ( tap_error , TRUE ) ;
return ;
}
sharkd_retap ( ) ;
remove_tap_listener ( & rtp_req ) ;
if ( rtp_req . packets )
{
const char * mime = " audio/x-wav " ;
const char * filename = tok_token ;
2018-12-12 14:33:44 +00:00
json_dumper_begin_object ( & dumper ) ;
sharkd_json_value_string ( " file " , filename ) ;
sharkd_json_value_string ( " mime " , mime ) ;
2017-04-08 08:15:11 +00:00
2018-12-12 14:33:44 +00:00
sharkd_json_value_anyf ( " data " , NULL ) ;
json_dumper_begin_base64 ( & dumper ) ;
2017-04-08 08:15:11 +00:00
sharkd_rtp_download_decode ( & rtp_req ) ;
2018-12-12 14:33:44 +00:00
json_dumper_end_base64 ( & dumper ) ;
2017-04-08 08:15:11 +00:00
2018-12-12 14:33:44 +00:00
json_dumper_end_object ( & dumper ) ;
json_dumper_finish ( & dumper ) ;
2017-04-08 08:15:11 +00:00
g_slist_free_full ( rtp_req . packets , sharkd_rtp_download_free_items ) ;
}
}
2017-03-11 11:27:14 +00:00
}
2016-10-15 18:48:17 +00:00
static void
sharkd_session_process ( char * buf , const jsmntok_t * tokens , int count )
{
int i ;
/* sanity check, and split strings */
if ( count < 1 | | tokens [ 0 ] . type ! = JSMN_OBJECT )
{
fprintf ( stderr , " sanity check(1): [0] not object \n " ) ;
return ;
}
/* don't need [0] token */
tokens + + ;
count - - ;
if ( count & 1 )
{
fprintf ( stderr , " sanity check(2): %d not even \n " , count ) ;
return ;
}
for ( i = 0 ; i < count ; i + = 2 )
{
if ( tokens [ i ] . type ! = JSMN_STRING )
{
fprintf ( stderr , " sanity check(3): [%d] not string \n " , i ) ;
return ;
}
2017-10-04 06:12:23 +00:00
if ( tokens [ i + 1 ] . type ! = JSMN_STRING & & tokens [ i + 1 ] . type ! = JSMN_PRIMITIVE )
{
fprintf ( stderr , " sanity check(3a): [%d] wrong type \n " , i + 1 ) ;
return ;
}
2016-10-15 18:48:17 +00:00
buf [ tokens [ i + 0 ] . end ] = ' \0 ' ;
buf [ tokens [ i + 1 ] . end ] = ' \0 ' ;
2017-09-02 19:47:14 +00:00
/* unescape only value, as keys are simple strings */
2018-11-19 14:52:30 +00:00
if ( tokens [ i + 1 ] . type = = JSMN_STRING & & ! json_decode_string_inplace ( & buf [ tokens [ i + 1 ] . start ] ) )
2017-09-02 19:47:14 +00:00
{
2017-10-04 06:12:23 +00:00
fprintf ( stderr , " sanity check(3b): [%d] cannot unescape string \n " , i + 1 ) ;
2017-09-02 19:47:14 +00:00
return ;
}
2016-10-15 18:48:17 +00:00
}
{
const char * tok_req = json_find_attr ( buf , tokens , count , " req " ) ;
if ( ! tok_req )
{
2017-02-19 18:58:47 +00:00
fprintf ( stderr , " sanity check(4): no \" req \" . \n " ) ;
2016-10-15 18:48:17 +00:00
return ;
}
if ( ! strcmp ( tok_req , " load " ) )
sharkd_session_process_load ( buf , tokens , count ) ;
else if ( ! strcmp ( tok_req , " status " ) )
sharkd_session_process_status ( ) ;
else if ( ! strcmp ( tok_req , " analyse " ) )
sharkd_session_process_analyse ( ) ;
else if ( ! strcmp ( tok_req , " info " ) )
sharkd_session_process_info ( ) ;
else if ( ! strcmp ( tok_req , " check " ) )
sharkd_session_process_check ( buf , tokens , count ) ;
else if ( ! strcmp ( tok_req , " complete " ) )
sharkd_session_process_complete ( buf , tokens , count ) ;
else if ( ! strcmp ( tok_req , " frames " ) )
sharkd_session_process_frames ( buf , tokens , count ) ;
else if ( ! strcmp ( tok_req , " tap " ) )
sharkd_session_process_tap ( buf , tokens , count ) ;
2017-03-11 11:27:14 +00:00
else if ( ! strcmp ( tok_req , " follow " ) )
sharkd_session_process_follow ( buf , tokens , count ) ;
2018-05-06 16:15:58 +00:00
else if ( ! strcmp ( tok_req , " iograph " ) )
sharkd_session_process_iograph ( buf , tokens , count ) ;
2016-10-15 18:48:17 +00:00
else if ( ! strcmp ( tok_req , " intervals " ) )
sharkd_session_process_intervals ( buf , tokens , count ) ;
else if ( ! strcmp ( tok_req , " frame " ) )
sharkd_session_process_frame ( buf , tokens , count ) ;
2017-12-06 18:51:18 +00:00
else if ( ! strcmp ( tok_req , " setcomment " ) )
sharkd_session_process_setcomment ( buf , tokens , count ) ;
2016-10-15 18:48:17 +00:00
else if ( ! strcmp ( tok_req , " setconf " ) )
sharkd_session_process_setconf ( buf , tokens , count ) ;
else if ( ! strcmp ( tok_req , " dumpconf " ) )
sharkd_session_process_dumpconf ( buf , tokens , count ) ;
2017-03-11 11:27:14 +00:00
else if ( ! strcmp ( tok_req , " download " ) )
sharkd_session_process_download ( buf , tokens , count ) ;
2016-10-15 18:48:17 +00:00
else if ( ! strcmp ( tok_req , " bye " ) )
2017-01-26 01:27:13 +00:00
exit ( 0 ) ;
2016-10-15 18:48:17 +00:00
else
fprintf ( stderr , " ::: req = %s \n " , tok_req ) ;
2017-01-28 21:40:17 +00:00
/* reply for every command are 0+ lines of JSON reply (outputed above), finished by empty new line */
2018-12-12 14:33:44 +00:00
json_dumper_finish ( & dumper ) ;
2017-01-28 21:40:17 +00:00
2017-02-01 04:41:38 +00:00
/*
* We do an explicit fflush after every line , because
* we want output to be written to the socket as soon
* as the line is complete .
*
* The stream is fully - buffered by default , so it ' s
* only flushed when the buffer fills or the FILE *
* is closed . On UN * X , we could set it to be line
* buffered , but the MSVC standard I / O routines don ' t
* support line buffering - they only support * byte *
* buffering , doing a write for every byte written ,
* which is too inefficient , and full buffering ,
* which is what you get if you request line buffering .
*/
2017-01-28 21:40:17 +00:00
fflush ( stdout ) ;
2016-10-15 18:48:17 +00:00
}
}
int
sharkd_session_main ( void )
{
2017-04-13 18:02:48 +00:00
char buf [ 2 * 1024 ] ;
2016-10-15 18:48:17 +00:00
jsmntok_t * tokens = NULL ;
int tokens_max = - 1 ;
2017-02-19 18:58:47 +00:00
fprintf ( stderr , " Hello in child. \n " ) ;
2016-10-15 18:48:17 +00:00
2018-12-12 14:33:44 +00:00
dumper . output_file = stdout ;
2018-01-14 15:38:55 +00:00
filter_table = g_hash_table_new_full ( g_str_hash , g_str_equal , g_free , sharkd_session_filter_free ) ;
2018-05-04 18:38:19 +00:00
# ifdef HAVE_MAXMINDDB
/* mmdbresolve was stopped before fork(), force starting it */
uat_get_table_by_name ( " MaxMind Database Paths " ) - > post_update_cb ( ) ;
# endif
2016-10-15 18:48:17 +00:00
while ( fgets ( buf , sizeof ( buf ) , stdin ) )
{
/* every command is line seperated JSON */
int ret ;
2018-11-19 14:52:30 +00:00
ret = json_parse ( buf , NULL , 0 ) ;
2020-08-14 12:49:48 +00:00
if ( ret < = 0 )
2016-10-15 18:48:17 +00:00
{
fprintf ( stderr , " invalid JSON -> closing \n " ) ;
return 1 ;
}
/* fprintf(stderr, "JSON: %d tokens\n", ret); */
ret + = 1 ;
if ( tokens = = NULL | | tokens_max < ret )
{
tokens_max = ret ;
tokens = ( jsmntok_t * ) g_realloc ( tokens , sizeof ( jsmntok_t ) * tokens_max ) ;
}
memset ( tokens , 0 , ret * sizeof ( jsmntok_t ) ) ;
2018-11-19 14:52:30 +00:00
ret = json_parse ( buf , tokens , ret ) ;
2020-08-14 12:49:48 +00:00
if ( ret < = 0 )
2016-10-15 18:48:17 +00:00
{
fprintf ( stderr , " invalid JSON(2) -> closing \n " ) ;
return 2 ;
}
2018-05-04 18:38:19 +00:00
host_name_lookup_process ( ) ;
2016-10-15 18:48:17 +00:00
sharkd_session_process ( buf , tokens , ret ) ;
}
2018-01-14 15:38:55 +00:00
g_hash_table_destroy ( filter_table ) ;
2016-10-15 18:48:17 +00:00
g_free ( tokens ) ;
return 0 ;
}
/*
2019-07-26 18:43:17 +00:00
* Editor modelines - https : //www.wireshark.org/tools/modelines.html
2016-10-15 18:48:17 +00:00
*
* Local variables :
* c - basic - offset : 8
* tab - width : 8
* indent - tabs - mode : t
* End :
*
* vi : set shiftwidth = 8 tabstop = 8 noexpandtab :
* : indentSize = 8 : tabSize = 8 : noTabs = false :
*/