2016-10-15 18:48:17 +00:00
/* sharkd.c
*
* Daemon variant of Wireshark
*
* 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>
2022-10-06 17:41:17 +00:00
# define WS_LOG_DOMAIN LOG_DOMAIN_MAIN
2016-10-15 18:48:17 +00:00
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <limits.h>
# include <errno.h>
# include <signal.h>
# include <glib.h>
# include <epan/exceptions.h>
# include <epan/epan.h>
2019-01-01 00:55:23 +00:00
# include <ui/clopts_common.h>
# include <ui/cmdarg_err.h>
2016-10-15 18:48:17 +00:00
# include <wsutil/filesystem.h>
# include <wsutil/file_util.h>
# include <wsutil/privileges.h>
2017-04-08 19:45:19 +00:00
# include <wsutil/report_message.h>
2021-06-08 01:46:52 +00:00
# include <wsutil/wslog.h>
2021-07-03 11:58:30 +00:00
# include <ui/version_info.h>
2016-10-15 18:48:17 +00:00
# include <wiretap/wtap_opttypes.h>
# include <epan/decode_as.h>
# include <epan/timestamp.h>
# include <epan/packet.h>
# include "frame_tvbuff.h"
# include <epan/disabled_protos.h>
# include <epan/prefs.h>
# include <epan/column.h>
# include <epan/print.h>
# include <epan/addr_resolv.h>
# include "ui/util.h"
2017-10-14 20:14:14 +00:00
# include "ui/ws_ui_util.h"
2016-10-15 18:48:17 +00:00
# include "ui/decode_as_utils.h"
2017-04-09 04:24:45 +00:00
# include "ui/filter_files.h"
2016-10-15 18:48:17 +00:00
# include "ui/tap_export_pdu.h"
2017-04-20 02:21:11 +00:00
# include "ui/failure_message.h"
2021-04-29 11:23:21 +00:00
# include "wtap.h"
2016-10-15 18:48:17 +00:00
# include <epan/epan_dissect.h>
# include <epan/tap.h>
2018-05-04 18:38:19 +00:00
# include <epan/uat-int.h>
2018-11-18 17:11:42 +00:00
# include <epan/secrets.h>
2016-10-15 18:48:17 +00:00
2019-02-03 02:15:13 +00:00
# include <wsutil/codecs.h>
2017-04-08 08:15:11 +00:00
2016-10-15 18:48:17 +00:00
# include <wsutil/str_util.h>
# include <wsutil/utf8_entities.h>
# ifdef HAVE_PLUGINS
# include <wsutil/plugins.h>
# endif
# include "sharkd.h"
2017-02-03 22:06:35 +00:00
# define INIT_FAILED 1
# define EPAN_INIT_FAIL 2
2017-12-04 03:18:38 +00:00
capture_file cfile ;
2016-10-15 18:48:17 +00:00
static guint32 cum_bytes ;
static frame_data ref_frame ;
2021-03-15 18:29:43 +00:00
static void sharkd_cmdarg_err ( const char * msg_format , va_list ap ) ;
static void sharkd_cmdarg_err_cont ( const char * msg_format , va_list ap ) ;
2016-10-15 18:48:17 +00:00
static void
2022-02-20 19:39:37 +00:00
print_current_user ( void )
{
gchar * cur_user , * cur_group ;
if ( started_with_special_privs ( ) ) {
cur_user = get_cur_username ( ) ;
cur_group = get_cur_groupname ( ) ;
fprintf ( stderr , " Running as user \" %s \" and group \" %s \" . " ,
cur_user , cur_group ) ;
g_free ( cur_user ) ;
g_free ( cur_group ) ;
if ( running_with_special_privs ( ) ) {
fprintf ( stderr , " This could be dangerous. " ) ;
}
fprintf ( stderr , " \n " ) ;
2016-10-15 18:48:17 +00:00
}
}
int
main ( int argc , char * argv [ ] )
{
2022-02-20 20:09:34 +00:00
char * configuration_init_error ;
2022-02-20 19:39:37 +00:00
char * err_msg = NULL ;
e_prefs * prefs_p ;
int ret = EXIT_SUCCESS ;
static const struct report_message_routines sharkd_report_routines = {
failure_message ,
failure_message ,
open_failure_message ,
read_failure_message ,
write_failure_message ,
cfile_open_failure_message ,
cfile_dump_open_failure_message ,
cfile_read_failure_message ,
cfile_write_failure_message ,
cfile_close_failure_message
} ;
cmdarg_err_init ( sharkd_cmdarg_err , sharkd_cmdarg_err_cont ) ;
/* Initialize log handler early so we can have proper logging during startup. */
ws_log_init ( " sharkd " , vcmdarg_err ) ;
/* Early logging command-line initialization. */
ws_log_parse_args ( & argc , argv , vcmdarg_err , INIT_FAILED ) ;
2022-10-06 17:41:17 +00:00
ws_noisy ( " Finished log init and parsing command line log arguments " ) ;
2022-02-20 19:39:37 +00:00
/*
* Get credential information for later use , and drop privileges
* before doing anything else .
* Let the user know if anything happened .
*/
init_process_policies ( ) ;
relinquish_special_privs_perm ( ) ;
print_current_user ( ) ;
/*
* Attempt to get the pathname of the executable file .
*/
2022-02-20 20:09:34 +00:00
configuration_init_error = configuration_init ( argv [ 0 ] , NULL ) ;
if ( configuration_init_error ! = NULL ) {
2022-02-20 19:39:37 +00:00
fprintf ( stderr , " sharkd: Can't get pathname of sharkd program: %s. \n " ,
2022-02-20 20:09:34 +00:00
configuration_init_error ) ;
2022-02-20 19:39:37 +00:00
}
/* Initialize the version information. */
2022-02-24 13:27:08 +00:00
ws_init_version_info ( " Sharkd " ,
epan_gather_compile_info ,
epan_gather_runtime_info ) ;
2022-02-20 19:39:37 +00:00
if ( sharkd_init ( argc , argv ) < 0 )
{
printf ( " cannot initialize sharkd \n " ) ;
ret = INIT_FAILED ;
goto clean_exit ;
}
init_report_message ( " sharkd " , & sharkd_report_routines ) ;
timestamp_set_type ( TS_RELATIVE ) ;
timestamp_set_precision ( TS_PREC_AUTO ) ;
timestamp_set_seconds_type ( TS_SECONDS_DEFAULT ) ;
/*
* Libwiretap must be initialized before libwireshark is , so that
* dissection - time handlers for file - type - dependent blocks can
* register using the file type / subtype value for the file type .
*/
wtap_init ( TRUE ) ;
/* Register all dissectors; we must do this before checking for the
" -G " flag , as the " -G " flag dumps information registered by the
dissectors , and we must do it before we read the preferences , in
case any dissectors register preferences . */
if ( ! epan_init ( NULL , NULL , TRUE ) ) {
ret = EPAN_INIT_FAIL ;
goto clean_exit ;
}
codecs_init ( ) ;
/* Load libwireshark settings from the current profile. */
prefs_p = epan_load_settings ( ) ;
read_filter_list ( CFILTER_LIST ) ;
if ( ! color_filters_init ( & err_msg , NULL ) ) {
fprintf ( stderr , " %s \n " , err_msg ) ;
g_free ( err_msg ) ;
}
cap_file_init ( & cfile ) ;
/* Notify all registered modules that have had any of their preferences
changed either from one of the preferences file or from the command
line that their preferences have changed . */
prefs_apply_all ( ) ;
/* Build the column format array */
build_column_format_array ( & cfile . cinfo , prefs_p - > num_cols , TRUE ) ;
2016-10-15 18:48:17 +00:00
2018-05-04 18:38:19 +00:00
# ifdef HAVE_MAXMINDDB
2022-02-20 19:39:37 +00:00
/* mmdbresolve is started from mmdb_resolve_start(), which is called from epan_load_settings via: read_prefs -> (...) uat_load_all -> maxmind_db_post_update_cb.
* Need to stop it , otherwise all sharkd will have same mmdbresolve process , including pipe descriptors to read and write . */
uat_clear ( uat_get_table_by_name ( " MaxMind Database Paths " ) ) ;
2018-05-04 18:38:19 +00:00
# endif
2022-02-20 19:39:37 +00:00
ret = sharkd_loop ( argc , argv ) ;
2017-02-03 22:06:35 +00:00
clean_exit :
2022-02-20 19:39:37 +00:00
col_cleanup ( & cfile . cinfo ) ;
free_filter_lists ( ) ;
codecs_cleanup ( ) ;
wtap_cleanup ( ) ;
free_progdirs ( ) ;
return ret ;
2016-10-15 18:48:17 +00:00
}
static const nstime_t *
2017-12-08 04:33:22 +00:00
sharkd_get_frame_ts ( struct packet_provider_data * prov , guint32 frame_num )
2016-10-15 18:48:17 +00:00
{
2022-02-20 19:39:37 +00:00
if ( prov - > ref & & prov - > ref - > num = = frame_num )
return & prov - > ref - > abs_ts ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( prov - > prev_dis & & prov - > prev_dis - > num = = frame_num )
return & prov - > prev_dis - > abs_ts ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( prov - > prev_cap & & prov - > prev_cap - > num = = frame_num )
return & prov - > prev_cap - > abs_ts ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( prov - > frames ) {
frame_data * fd = frame_data_sequence_find ( prov - > frames , frame_num ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
return ( fd ) ? & fd - > abs_ts : NULL ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
return NULL ;
2016-10-15 18:48:17 +00:00
}
static epan_t *
sharkd_epan_new ( capture_file * cf )
{
2022-02-20 19:39:37 +00:00
static const struct packet_provider_funcs funcs = {
sharkd_get_frame_ts ,
cap_file_provider_get_interface_name ,
cap_file_provider_get_interface_description ,
cap_file_provider_get_modified_block
} ;
return epan_new ( & cf - > provider , & funcs ) ;
2016-10-15 18:48:17 +00:00
}
static gboolean
2017-04-12 20:52:07 +00:00
process_packet ( capture_file * cf , epan_dissect_t * edt ,
2022-02-20 19:39:37 +00:00
gint64 offset , wtap_rec * rec , Buffer * buf )
2016-10-15 18:48:17 +00:00
{
2022-02-20 19:39:37 +00:00
frame_data fdlocal ;
gboolean passed ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* If we're not running a display filter and we're not printing any
packet information , we don ' t need to do a dissection . This means
that all packets can be marked as ' passed ' . */
passed = TRUE ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* The frame number of this packet, if we add it to the set of frames,
would be one more than the count of frames in the file so far . */
frame_data_init ( & fdlocal , cf - > count + 1 , rec , offset , cum_bytes ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* If we're going to print packet information, or we're going to
run a read filter , or display filter , or we ' re going to process taps , set up to
do a dissection and do so . */
if ( edt ) {
if ( gbl_resolv_flags . mac_name | | gbl_resolv_flags . network_name | |
gbl_resolv_flags . transport_name )
/* Grab any resolved addresses */
host_name_lookup_process ( ) ;
/* If we're running a read filter, prime the epan_dissect_t with that
filter . */
if ( cf - > rfcode )
epan_dissect_prime_with_dfilter ( edt , cf - > rfcode ) ;
if ( cf - > dfcode )
epan_dissect_prime_with_dfilter ( edt , cf - > dfcode ) ;
/* This is the first and only pass, so prime the epan_dissect_t
with the hfids postdissectors want on the first pass . */
prime_epan_dissect_with_postdissector_wanted_hfids ( edt ) ;
frame_data_set_before_dissect ( & fdlocal , & cf - > elapsed_time ,
& cf - > provider . ref , cf - > provider . prev_dis ) ;
if ( cf - > provider . ref = = & fdlocal ) {
ref_frame = fdlocal ;
cf - > provider . ref = & ref_frame ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
epan_dissect_run ( edt , cf - > cd_t , rec ,
frame_tvbuff_new_buffer ( & cf - > provider , & fdlocal , buf ) ,
& fdlocal , NULL ) ;
/* Run the read filter if we have one. */
if ( cf - > rfcode )
passed = dfilter_apply_edt ( cf - > rfcode , edt ) ;
2016-10-15 18:48:17 +00:00
}
2022-02-20 19:39:37 +00:00
if ( passed ) {
frame_data_set_after_dissect ( & fdlocal , & cum_bytes ) ;
cf - > provider . prev_cap = cf - > provider . prev_dis = frame_data_sequence_add ( cf - > provider . frames , & fdlocal ) ;
/* If we're not doing dissection then there won't be any dependent frames.
2022-03-27 15:53:29 +00:00
* More importantly , edt . pi . dependent_frames won ' t be initialized because
2022-02-20 19:39:37 +00:00
* epan hasn ' t been initialized .
* if we * are * doing dissection , then mark the dependent frames , but only
* if a display filter was given and it matches this packet .
*/
if ( edt & & cf - > dfcode ) {
if ( dfilter_apply_edt ( cf - > dfcode , edt ) ) {
2022-03-27 15:53:29 +00:00
g_slist_foreach ( edt - > pi . dependent_frames , find_and_mark_frame_depended_upon , cf - > provider . frames ) ;
2022-02-20 19:39:37 +00:00
}
}
cf - > count + + ;
} else {
/* if we don't add it to the frame_data_sequence, clean it up right now
* to avoid leaks */
frame_data_destroy ( & fdlocal ) ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( edt )
epan_dissect_reset ( edt ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
return passed ;
2016-10-15 18:48:17 +00:00
}
static int
load_cap_file ( capture_file * cf , int max_packet_count , gint64 max_byte_count )
{
2022-02-20 19:39:37 +00:00
int err ;
gchar * err_info = NULL ;
gint64 data_offset ;
wtap_rec rec ;
Buffer buf ;
epan_dissect_t * edt = NULL ;
2016-10-15 18:48:17 +00:00
{
2022-02-20 19:39:37 +00:00
/* Allocate a frame_data_sequence for all the frames. */
cf - > provider . frames = new_frame_data_sequence ( ) ;
{
gboolean create_proto_tree ;
/*
* Determine whether we need to create a protocol tree .
* We do if :
*
* we ' re going to apply a read filter ;
*
* we ' re going to apply a display filter ;
*
* a postdissector wants field values or protocols
* on the first pass .
*/
create_proto_tree =
( cf - > rfcode ! = NULL | | cf - > dfcode ! = NULL | | postdissectors_want_hfids ( ) ) ;
/* We're not going to display the protocol tree on this pass,
so it ' s not going to be " visible " . */
edt = epan_dissect_new ( cf - > epan , create_proto_tree , FALSE ) ;
}
2019-04-05 01:56:27 +00:00
2022-02-20 19:39:37 +00:00
wtap_rec_init ( & rec ) ;
ws_buffer_init ( & buf , 1514 ) ;
while ( wtap_read ( cf - > provider . wth , & rec , & buf , & err , & err_info , & data_offset ) ) {
if ( process_packet ( cf , edt , data_offset , & rec , & buf ) ) {
wtap_rec_reset ( & rec ) ;
/* Stop reading if we have the maximum number of packets;
* When the - c option has not been used , max_packet_count
* starts at 0 , which practically means , never stop reading .
* ( unless we roll over max_packet_count ? )
*/
if ( ( - - max_packet_count = = 0 ) | | ( max_byte_count ! = 0 & & data_offset > = max_byte_count ) ) {
err = 0 ; /* This is not an error */
break ;
}
}
2016-10-15 18:48:17 +00:00
}
2022-02-20 19:39:37 +00:00
if ( edt ) {
epan_dissect_free ( edt ) ;
edt = NULL ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
wtap_rec_cleanup ( & rec ) ;
ws_buffer_free ( & buf ) ;
2019-04-05 01:56:27 +00:00
2022-02-20 19:39:37 +00:00
/* Close the sequential I/O side, to free up memory it requires. */
wtap_sequential_close ( cf - > provider . wth ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* Allow the protocol dissectors to free up memory that they
* don ' t need after the sequential run - through of the packets . */
postseq_cleanup_all_protocols ( ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
cf - > provider . prev_dis = NULL ;
cf - > provider . prev_cap = NULL ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( err ! = 0 ) {
cfile_read_failure_message ( cf - > filename , err , err_info ) ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
return err ;
2016-10-15 18:48:17 +00:00
}
cf_status_t
cf_open ( capture_file * cf , const char * fname , unsigned int type , gboolean is_tempfile , int * err )
{
2022-02-20 19:39:37 +00:00
wtap * wth ;
gchar * err_info ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
wth = wtap_open_offline ( fname , type , err , & err_info , TRUE ) ;
if ( wth = = NULL )
goto fail ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* The open succeeded. Fill in the information for this file. */
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
cf - > provider . wth = wth ;
cf - > f_datalen = 0 ; /* not used, but set it anyway */
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* Set the file name because we need it to set the follow stream filter.
XXX - is that still true ? We need it for other reasons , though ,
in any case . */
cf - > filename = g_strdup ( fname ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* Indicate whether it's a permanent or temporary file. */
cf - > is_tempfile = is_tempfile ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* No user changes yet. */
cf - > unsaved_changes = FALSE ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
cf - > cd_t = wtap_file_type_subtype ( cf - > provider . wth ) ;
cf - > open_type = type ;
cf - > count = 0 ;
cf - > drops_known = FALSE ;
cf - > drops = 0 ;
cf - > snap = wtap_snapshot_length ( cf - > provider . wth ) ;
nstime_set_zero ( & cf - > elapsed_time ) ;
cf - > provider . ref = NULL ;
cf - > provider . prev_dis = NULL ;
cf - > provider . prev_cap = NULL ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* Create new epan session for dissection. */
epan_free ( cf - > epan ) ;
cf - > epan = sharkd_epan_new ( cf ) ;
2018-06-04 20:22:49 +00:00
2022-02-20 19:39:37 +00:00
cf - > state = FILE_READ_IN_PROGRESS ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
wtap_set_cb_new_ipv4 ( cf - > provider . wth , add_ipv4_name ) ;
wtap_set_cb_new_ipv6 ( cf - > provider . wth , ( wtap_new_ipv6_callback_t ) add_ipv6_name ) ;
wtap_set_cb_new_secrets ( cf - > provider . wth , secrets_wtap_callback ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
return CF_OK ;
2016-10-15 18:48:17 +00:00
fail :
2022-02-20 19:39:37 +00:00
cfile_open_failure_message ( fname , * err , err_info ) ;
return CF_ERROR ;
2016-10-15 18:48:17 +00:00
}
/*
2021-03-15 18:29:43 +00:00
* Report an error in command - line arguments .
2016-10-15 18:48:17 +00:00
*/
static void
2021-03-15 18:29:43 +00:00
sharkd_cmdarg_err ( const char * msg_format , va_list ap )
2016-10-15 18:48:17 +00:00
{
2022-02-20 19:39:37 +00:00
fprintf ( stderr , " sharkd: " ) ;
vfprintf ( stderr , msg_format , ap ) ;
fprintf ( stderr , " \n " ) ;
2016-10-15 18:48:17 +00:00
}
/*
* Report additional information for an error in command - line arguments .
*/
static void
2021-03-15 18:29:43 +00:00
sharkd_cmdarg_err_cont ( const char * msg_format , va_list ap )
2016-10-15 18:48:17 +00:00
{
2022-02-20 19:39:37 +00:00
vfprintf ( stderr , msg_format , ap ) ;
fprintf ( stderr , " \n " ) ;
2016-10-15 18:48:17 +00:00
}
cf_status_t
sharkd_cf_open ( const char * fname , unsigned int type , gboolean is_tempfile , int * err )
{
2022-02-20 19:39:37 +00:00
return cf_open ( & cfile , fname , type , is_tempfile , err ) ;
2016-10-15 18:48:17 +00:00
}
int
sharkd_load_cap_file ( void )
{
2022-02-20 19:39:37 +00:00
return load_cap_file ( & cfile , 0 , 0 ) ;
2016-10-15 18:48:17 +00:00
}
2017-12-07 20:56:11 +00:00
frame_data *
sharkd_get_frame ( guint32 framenum )
{
2022-02-20 19:39:37 +00:00
return frame_data_sequence_find ( cfile . provider . frames , framenum ) ;
2017-12-07 20:56:11 +00:00
}
sharkd: various cleanups.
Extend sharkd_dissect_request() so that it can replace
sharkd_dissect_columns().
Have it return a status indicating success, invalid frame number, or
read error, so that the caller knows what the problem is.
Pass it pointers to the wtap_rec and Buffer to use when reading packets
from the file, so that if it's called in a loop iterating over all
frames, those structures can be initialized once, before the loop, and
cleaned up once, after the loop, rather than doing both once per loop
iteration.
Pass pointers to the read error code and additional read error
information string pointer, so that, on a file read error, that
information is available to the caller.
Get rid of sharkd_dissect_columns(); instead, use
sharkd_dissect_request(), with code from the loop body pulled into a
callback routine. Fix that code to correctly determine whether the
current frame has any comments, rather than just treating all frames
that have blocks as having comments.
Use _U_ to mark arguments as unused, rather than throwing in a
(void) variablename;
statement.
Move some variables used only within a loop into the for() statement or
the loop body.
2021-07-11 10:06:10 +00:00
enum dissect_request_status
sharkd_dissect_request ( guint32 framenum , guint32 frame_ref_num ,
2022-02-20 19:39:37 +00:00
guint32 prev_dis_num , wtap_rec * rec , Buffer * buf ,
column_info * cinfo , guint32 dissect_flags ,
sharkd_dissect_func_t cb , void * data ,
int * err , gchar * * err_info )
2016-10-15 18:48:17 +00:00
{
2022-02-20 19:39:37 +00:00
frame_data * fdata ;
epan_dissect_t edt ;
gboolean create_proto_tree ;
fdata = sharkd_get_frame ( framenum ) ;
if ( fdata = = NULL )
return DISSECT_REQUEST_NO_SUCH_FRAME ;
if ( ! wtap_seek_read ( cfile . provider . wth , fdata - > file_off , rec , buf , err , err_info ) ) {
if ( cinfo ! = NULL )
col_fill_in_error ( cinfo , fdata , FALSE , FALSE /* fill_fd_columns */ ) ;
return DISSECT_REQUEST_READ_ERROR ; /* error reading the record */
}
create_proto_tree = ( ( dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE ) | |
( ( dissect_flags & SHARKD_DISSECT_FLAG_COLOR ) & & color_filters_used ( ) ) | |
( cinfo & & have_custom_cols ( cinfo ) ) ) ;
epan_dissect_init ( & edt , cfile . epan , create_proto_tree , ( dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE ) ) ;
if ( dissect_flags & SHARKD_DISSECT_FLAG_COLOR ) {
color_filters_prime_edt ( & edt ) ;
fdata - > need_colorize = 1 ;
}
if ( cinfo )
col_custom_prime_edt ( & edt , cinfo ) ;
/*
* XXX - need to catch an OutOfMemoryError exception and
* attempt to recover from it .
*/
fdata - > ref_time = ( framenum = = frame_ref_num ) ;
fdata - > frame_ref_num = frame_ref_num ;
fdata - > prev_dis_num = prev_dis_num ;
epan_dissect_run ( & edt , cfile . cd_t , rec ,
frame_tvbuff_new_buffer ( & cfile . provider , fdata , buf ) ,
fdata , cinfo ) ;
if ( cinfo ) {
/* "Stringify" non frame_data vals */
epan_dissect_fill_in_columns ( & edt , FALSE , TRUE /* fill_fd_columns */ ) ;
}
cb ( & edt , ( dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE ) ? edt . tree : NULL ,
cinfo , ( dissect_flags & SHARKD_DISSECT_FLAG_BYTES ) ? edt . pi . data_src : NULL ,
data ) ;
wtap_rec_reset ( rec ) ;
epan_dissect_cleanup ( & edt ) ;
return DISSECT_REQUEST_SUCCESS ;
2016-10-15 18:48:17 +00:00
}
int
sharkd_retap ( void )
{
2022-02-20 19:39:37 +00:00
guint32 framenum ;
frame_data * fdata ;
Buffer buf ;
wtap_rec rec ;
int err ;
char * err_info = NULL ;
guint tap_flags ;
gboolean create_proto_tree ;
epan_dissect_t edt ;
column_info * cinfo ;
/* Get the union of the flags for all tap listeners. */
tap_flags = union_of_tap_listener_flags ( ) ;
/* If any tap listeners require the columns, construct them. */
cinfo = ( tap_flags & TL_REQUIRES_COLUMNS ) ? & cfile . cinfo : NULL ;
/*
* Determine whether we need to create a protocol tree .
* We do if :
*
* one of the tap listeners is going to apply a filter ;
*
* one of the tap listeners requires a protocol tree .
*/
create_proto_tree =
( have_filtering_tap_listeners ( ) | | ( tap_flags & TL_REQUIRES_PROTO_TREE ) ) ;
wtap_rec_init ( & rec ) ;
ws_buffer_init ( & buf , 1514 ) ;
epan_dissect_init ( & edt , cfile . epan , create_proto_tree , FALSE ) ;
reset_tap_listeners ( ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
for ( framenum = 1 ; framenum < = cfile . count ; framenum + + ) {
fdata = sharkd_get_frame ( framenum ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( ! wtap_seek_read ( cfile . provider . wth , fdata - > file_off , & rec , & buf , & err , & err_info ) )
break ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
fdata - > ref_time = FALSE ;
fdata - > frame_ref_num = ( framenum ! = 1 ) ? 1 : 0 ;
fdata - > prev_dis_num = framenum - 1 ;
epan_dissect_run_with_taps ( & edt , cfile . cd_t , & rec ,
frame_tvbuff_new_buffer ( & cfile . provider , fdata , & buf ) ,
fdata , cinfo ) ;
wtap_rec_reset ( & rec ) ;
epan_dissect_reset ( & edt ) ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
wtap_rec_cleanup ( & rec ) ;
ws_buffer_free ( & buf ) ;
epan_dissect_cleanup ( & edt ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
draw_tap_listeners ( TRUE ) ;
return 0 ;
2016-10-15 18:48:17 +00:00
}
int
sharkd_filter ( const char * dftext , guint8 * * result )
{
2022-02-20 19:39:37 +00:00
dfilter_t * dfcode = NULL ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
guint32 framenum , prev_dis_num = 0 ;
guint32 frames_count ;
Buffer buf ;
wtap_rec rec ;
int err ;
char * err_info = NULL ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
guint8 * result_bits ;
guint8 passed_bits ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
epan_dissect_t edt ;
2016-10-15 18:48:17 +00:00
2022-11-19 19:21:19 +00:00
if ( ! dfilter_compile ( dftext , & dfcode , NULL ) ) {
2022-02-20 19:39:37 +00:00
return - 1 ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* if dfilter_compile() success, but (dfcode == NULL) all frames are matching */
if ( dfcode = = NULL ) {
* result = NULL ;
return 0 ;
}
2018-09-01 16:47:38 +00:00
2022-02-20 19:39:37 +00:00
frames_count = cfile . count ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
wtap_rec_init ( & rec ) ;
ws_buffer_init ( & buf , 1514 ) ;
epan_dissect_init ( & edt , cfile . epan , TRUE , FALSE ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
passed_bits = 0 ;
result_bits = ( guint8 * ) g_malloc ( 2 + ( frames_count / 8 ) ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
for ( framenum = 1 ; framenum < = frames_count ; framenum + + ) {
frame_data * fdata = sharkd_get_frame ( framenum ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( ( framenum & 7 ) = = 0 ) {
result_bits [ ( framenum / 8 ) - 1 ] = passed_bits ;
passed_bits = 0 ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( ! wtap_seek_read ( cfile . provider . wth , fdata - > file_off , & rec , & buf , & err , & err_info ) )
break ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* frame_data_set_before_dissect */
epan_dissect_prime_with_dfilter ( & edt , dfcode ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
fdata - > ref_time = FALSE ;
fdata - > frame_ref_num = ( framenum ! = 1 ) ? 1 : 0 ;
fdata - > prev_dis_num = prev_dis_num ;
epan_dissect_run ( & edt , cfile . cd_t , & rec ,
frame_tvbuff_new_buffer ( & cfile . provider , fdata , & buf ) ,
fdata , NULL ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( dfilter_apply_edt ( dfcode , & edt ) ) {
passed_bits | = ( 1 < < ( framenum % 8 ) ) ;
prev_dis_num = framenum ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
/* if passed or ref -> frame_data_set_after_dissect */
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
wtap_rec_reset ( & rec ) ;
epan_dissect_reset ( & edt ) ;
}
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
if ( ( framenum & 7 ) = = 0 )
framenum - - ;
result_bits [ framenum / 8 ] = passed_bits ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
wtap_rec_cleanup ( & rec ) ;
ws_buffer_free ( & buf ) ;
epan_dissect_cleanup ( & edt ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
dfilter_free ( dfcode ) ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
* result = result_bits ;
2016-10-15 18:48:17 +00:00
2022-02-20 19:39:37 +00:00
return framenum ;
2016-10-15 18:48:17 +00:00
}
2021-04-29 11:23:21 +00:00
/*
2021-07-08 05:43:29 +00:00
* Get the modified block if available , nothing otherwise .
2021-04-29 11:23:21 +00:00
* Must be cloned if changes desired .
*/
wtap_block_t
2021-07-08 05:43:29 +00:00
sharkd_get_modified_block ( const frame_data * fd )
2017-12-06 18:51:18 +00:00
{
2022-02-20 19:39:37 +00:00
return cap_file_provider_get_modified_block ( & cfile . provider , fd ) ;
2021-04-29 11:23:21 +00:00
}
/*
2021-07-08 05:43:29 +00:00
* Gets the modified block if available , otherwise the packet ' s default block ,
2021-04-29 11:23:21 +00:00
* or a new packet block .
* User must wtap_block_unref ( ) it when done .
*/
wtap_block_t
sharkd_get_packet_block ( const frame_data * fd )
{
2022-02-20 19:39:37 +00:00
if ( fd - > has_modified_block )
return wtap_block_ref ( cap_file_provider_get_modified_block ( & cfile . provider , fd ) ) ;
else
{
wtap_rec rec ; /* Record metadata */
Buffer buf ; /* Record data */
wtap_block_t block ;
int err ;
gchar * err_info ;
2021-04-29 11:23:21 +00:00
2022-02-20 19:39:37 +00:00
wtap_rec_init ( & rec ) ;
ws_buffer_init ( & buf , 1514 ) ;
2021-04-29 11:23:21 +00:00
2022-02-20 19:39:37 +00:00
if ( ! wtap_seek_read ( cfile . provider . wth , fd - > file_off , & rec , & buf , & err , & err_info ) )
{ /* XXX, what we can do here? */ }
2021-04-29 11:23:21 +00:00
2022-02-20 19:39:37 +00:00
/* rec.block is owned by the record, steal it before it is gone. */
block = wtap_block_ref ( rec . block ) ;
2021-04-29 11:23:21 +00:00
2022-02-20 19:39:37 +00:00
wtap_rec_cleanup ( & rec ) ;
ws_buffer_free ( & buf ) ;
return block ;
}
2017-12-06 18:51:18 +00:00
}
int