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>
# 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
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 " ) ;
}
}
int
main ( int argc , char * argv [ ] )
{
char * init_progfile_dir_error ;
char * err_msg = NULL ;
e_prefs * prefs_p ;
2017-02-03 22:06:35 +00:00
int ret = EXIT_SUCCESS ;
2021-03-15 18:29:43 +00:00
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
} ;
2016-10-15 18:48:17 +00:00
2021-03-15 18:29:43 +00:00
cmdarg_err_init ( sharkd_cmdarg_err , sharkd_cmdarg_err_cont ) ;
2016-10-15 18:48:17 +00:00
2021-06-24 20:20:25 +00:00
/* Initialize log handler early so we can have proper logging during startup. */
ws_log_init ( " sharkd " , vcmdarg_err ) ;
2021-06-19 18:44:58 +00:00
/* Early logging command-line initialization. */
ws_log_parse_args ( & argc , argv , vcmdarg_err , INIT_FAILED ) ;
2021-06-08 01:46:52 +00:00
2016-10-15 18:48:17 +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 .
*/
2018-05-05 07:19:09 +00:00
init_progfile_dir_error = init_progfile_dir ( argv [ 0 ] ) ;
2016-10-15 18:48:17 +00:00
if ( init_progfile_dir_error ! = NULL ) {
fprintf ( stderr , " sharkd: Can't get pathname of sharkd program: %s. \n " ,
init_progfile_dir_error ) ;
}
2018-12-13 02:16:15 +00:00
/* Initialize the version information. */
ws_init_version_info ( " Sharkd (Wireshark) " , NULL ,
epan_get_compiled_version_info ,
epan_get_runtime_version_info ) ;
2016-10-15 18:48:17 +00:00
if ( sharkd_init ( argc , argv ) < 0 )
{
printf ( " cannot initialize sharkd \n " ) ;
2017-02-03 22:06:35 +00:00
ret = INIT_FAILED ;
goto clean_exit ;
2016-10-15 18:48:17 +00:00
}
2021-03-15 18:29:43 +00:00
init_report_message ( " sharkd " , & sharkd_report_routines ) ;
2016-10-15 18:48:17 +00:00
timestamp_set_type ( TS_RELATIVE ) ;
timestamp_set_precision ( TS_PREC_AUTO ) ;
timestamp_set_seconds_type ( TS_SECONDS_DEFAULT ) ;
2021-02-19 22:46:42 +00:00
/*
* 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 .
*/
2018-01-09 08:55:37 +00:00
wtap_init ( TRUE ) ;
2016-10-15 18:48:17 +00:00
/* 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 . */
2018-09-08 15:02:06 +00:00
if ( ! epan_init ( NULL , NULL , TRUE ) ) {
2017-02-03 22:06:35 +00:00
ret = EPAN_INIT_FAIL ;
goto clean_exit ;
}
2016-10-15 18:48:17 +00:00
2017-09-30 23:56:03 +00:00
codecs_init ( ) ;
2017-04-09 19:27:57 +00:00
/* Load libwireshark settings from the current profile. */
prefs_p = epan_load_settings ( ) ;
2016-10-15 18:48:17 +00:00
2017-04-09 09:01:05 +00:00
read_filter_list ( CFILTER_LIST ) ;
2016-10-15 18:48:17 +00:00
if ( ! color_filters_init ( & err_msg , NULL ) ) {
2017-06-09 22:38:05 +00:00
fprintf ( stderr , " %s \n " , err_msg ) ;
2016-10-15 18:48:17 +00:00
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 ) ;
2018-05-04 18:38:19 +00:00
# ifdef HAVE_MAXMINDDB
/* 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 " ) ) ;
# endif
2021-02-08 10:27:18 +00:00
ret = sharkd_loop ( argc , argv ) ;
2017-02-03 22:06:35 +00:00
clean_exit :
2017-02-03 21:41:31 +00:00
col_cleanup ( & cfile . cinfo ) ;
2017-02-03 22:15:56 +00:00
free_filter_lists ( ) ;
2017-09-30 23:56:03 +00:00
codecs_cleanup ( ) ;
2017-02-04 15:26:34 +00:00
wtap_cleanup ( ) ;
2017-02-08 13:25:57 +00:00
free_progdirs ( ) ;
2017-02-03 22:06:35 +00:00
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
{
2017-12-08 03:31:43 +00:00
if ( prov - > ref & & prov - > ref - > num = = frame_num )
return & prov - > ref - > abs_ts ;
2016-10-15 18:48:17 +00:00
2017-12-08 03:31:43 +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
2017-12-08 03:31:43 +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
2017-12-08 03:31:43 +00:00
if ( prov - > frames ) {
frame_data * fd = frame_data_sequence_find ( prov - > frames , frame_num ) ;
2016-10-15 18:48:17 +00:00
return ( fd ) ? & fd - > abs_ts : NULL ;
}
return NULL ;
}
static epan_t *
sharkd_epan_new ( capture_file * cf )
{
2017-12-08 04:33:22 +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 ,
2021-07-08 05:43:29 +00:00
cap_file_provider_get_modified_block
2017-12-08 04:33:22 +00:00
} ;
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 ,
2019-04-05 03:30:53 +00:00
gint64 offset , wtap_rec * rec , Buffer * buf )
2016-10-15 18:48:17 +00:00
{
frame_data fdlocal ;
gboolean passed ;
/* 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 ;
2018-02-09 00:19:12 +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
/* 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 )
2017-04-12 04:56:14 +00:00
epan_dissect_prime_with_dfilter ( edt , cf - > rfcode ) ;
2016-10-15 18:48:17 +00:00
if ( cf - > dfcode )
2017-04-12 04:56:14 +00:00
epan_dissect_prime_with_dfilter ( edt , cf - > dfcode ) ;
2016-10-15 18:48:17 +00:00
2017-04-12 20:52:07 +00:00
/* This is the first and only pass, so prime the epan_dissect_t
2017-04-17 01:48:30 +00:00
with the hfids postdissectors want on the first pass . */
prime_epan_dissect_with_postdissector_wanted_hfids ( edt ) ;
2017-04-12 20:52:07 +00:00
2016-10-15 18:48:17 +00:00
frame_data_set_before_dissect ( & fdlocal , & cf - > elapsed_time ,
2017-12-08 03:31:43 +00:00
& cf - > provider . ref , cf - > provider . prev_dis ) ;
if ( cf - > provider . ref = = & fdlocal ) {
2016-10-15 18:48:17 +00:00
ref_frame = fdlocal ;
2017-12-08 03:31:43 +00:00
cf - > provider . ref = & ref_frame ;
2016-10-15 18:48:17 +00:00
}
2018-02-09 00:19:12 +00:00
epan_dissect_run ( edt , cf - > cd_t , rec ,
2019-04-05 03:30:53 +00:00
frame_tvbuff_new_buffer ( & cf - > provider , & fdlocal , buf ) ,
2017-12-08 08:30:55 +00:00
& fdlocal , NULL ) ;
2016-10-15 18:48:17 +00:00
/* Run the read filter if we have one. */
if ( cf - > rfcode )
passed = dfilter_apply_edt ( cf - > rfcode , edt ) ;
}
if ( passed ) {
frame_data_set_after_dissect ( & fdlocal , & cum_bytes ) ;
2017-12-08 03:31:43 +00:00
cf - > provider . prev_cap = cf - > provider . prev_dis = frame_data_sequence_add ( cf - > provider . frames , & fdlocal ) ;
2016-10-15 18:48:17 +00:00
/* If we're not doing dissection then there won't be any dependent frames.
* More importantly , edt . pi . dependent_frames won ' t be initialized because
* 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 ) ) {
2017-12-08 03:31:43 +00:00
g_slist_foreach ( edt - > pi . dependent_frames , find_and_mark_frame_depended_upon , cf - > provider . frames ) ;
2016-10-15 18:48:17 +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 ) ;
}
if ( edt )
epan_dissect_reset ( edt ) ;
return passed ;
}
static int
load_cap_file ( capture_file * cf , int max_packet_count , gint64 max_byte_count )
{
int err ;
gchar * err_info = NULL ;
gint64 data_offset ;
2019-04-05 01:56:27 +00:00
wtap_rec rec ;
Buffer buf ;
2016-10-15 18:48:17 +00:00
epan_dissect_t * edt = NULL ;
{
/* Allocate a frame_data_sequence for all the frames. */
2017-12-08 03:31:43 +00:00
cf - > provider . frames = new_frame_data_sequence ( ) ;
2016-10-15 18:48:17 +00:00
{
2017-04-12 02:53:48 +00:00
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 ;
*
2017-04-17 01:48:30 +00:00
* a postdissector wants field values or protocols
* on the first pass .
2017-04-12 02:53:48 +00:00
*/
create_proto_tree =
2017-04-17 01:48:30 +00:00
( cf - > rfcode ! = NULL | | cf - > dfcode ! = NULL | | postdissectors_want_hfids ( ) ) ;
2016-10-15 18:48:17 +00:00
/* 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
wtap_rec_init ( & rec ) ;
2019-04-06 21:02:49 +00:00
ws_buffer_init ( & buf , 1514 ) ;
2019-04-05 01:56:27 +00:00
while ( wtap_read ( cf - > provider . wth , & rec , & buf , & err , & err_info , & data_offset ) ) {
2019-04-05 03:30:53 +00:00
if ( process_packet ( cf , edt , data_offset , & rec , & buf ) ) {
2016-10-15 18:48:17 +00:00
/* 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 ;
}
}
}
if ( edt ) {
epan_dissect_free ( edt ) ;
edt = NULL ;
}
2019-04-05 01:56:27 +00:00
wtap_rec_cleanup ( & rec ) ;
ws_buffer_free ( & buf ) ;
2016-10-15 18:48:17 +00:00
/* Close the sequential I/O side, to free up memory it requires. */
2017-12-08 03:31:43 +00:00
wtap_sequential_close ( cf - > provider . wth ) ;
2016-10-15 18:48:17 +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 ( ) ;
2017-12-08 03:31:43 +00:00
cf - > provider . prev_dis = NULL ;
cf - > provider . prev_cap = NULL ;
2016-10-15 18:48:17 +00:00
}
if ( err ! = 0 ) {
2021-03-15 18:29:43 +00:00
cfile_read_failure_message ( cf - > filename , err , err_info ) ;
2016-10-15 18:48:17 +00:00
}
return err ;
}
cf_status_t
cf_open ( capture_file * cf , const char * fname , unsigned int type , gboolean is_tempfile , int * err )
{
wtap * wth ;
gchar * err_info ;
wth = wtap_open_offline ( fname , type , err , & err_info , TRUE ) ;
if ( wth = = NULL )
goto fail ;
/* The open succeeded. Fill in the information for this file. */
2017-12-08 03:31:43 +00:00
cf - > provider . wth = wth ;
2016-10-15 18:48:17 +00:00
cf - > f_datalen = 0 ; /* not used, but set it anyway */
/* 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 ) ;
/* Indicate whether it's a permanent or temporary file. */
cf - > is_tempfile = is_tempfile ;
/* No user changes yet. */
cf - > unsaved_changes = FALSE ;
2017-12-08 03:31:43 +00:00
cf - > cd_t = wtap_file_type_subtype ( cf - > provider . wth ) ;
2016-10-15 18:48:17 +00:00
cf - > open_type = type ;
cf - > count = 0 ;
cf - > drops_known = FALSE ;
cf - > drops = 0 ;
2017-12-08 03:31:43 +00:00
cf - > snap = wtap_snapshot_length ( cf - > provider . wth ) ;
2016-10-15 18:48:17 +00:00
nstime_set_zero ( & cf - > elapsed_time ) ;
2017-12-08 03:31:43 +00:00
cf - > provider . ref = NULL ;
cf - > provider . prev_dis = NULL ;
cf - > provider . prev_cap = NULL ;
2016-10-15 18:48:17 +00:00
2018-06-04 20:22:49 +00:00
/* Create new epan session for dissection. */
epan_free ( cf - > epan ) ;
cf - > epan = sharkd_epan_new ( cf ) ;
2016-10-15 18:48:17 +00:00
cf - > state = FILE_READ_IN_PROGRESS ;
2017-12-08 03:31:43 +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 ) ;
2018-11-18 17:11:42 +00:00
wtap_set_cb_new_secrets ( cf - > provider . wth , secrets_wtap_callback ) ;
2016-10-15 18:48:17 +00:00
return CF_OK ;
fail :
2021-03-15 18:29:43 +00:00
cfile_open_failure_message ( fname , * err , err_info ) ;
2016-10-15 18:48:17 +00:00
return CF_ERROR ;
}
/*
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
{
fprintf ( stderr , " sharkd: " ) ;
2017-04-08 19:45:19 +00:00
vfprintf ( stderr , msg_format , ap ) ;
2016-10-15 18:48:17 +00:00
fprintf ( stderr , " \n " ) ;
}
/*
* 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
{
vfprintf ( stderr , msg_format , ap ) ;
fprintf ( stderr , " \n " ) ;
}
cf_status_t
sharkd_cf_open ( const char * fname , unsigned int type , gboolean is_tempfile , int * err )
{
return cf_open ( & cfile , fname , type , is_tempfile , err ) ;
}
int
sharkd_load_cap_file ( void )
{
return load_cap_file ( & cfile , 0 , 0 ) ;
}
2017-12-07 20:56:11 +00:00
frame_data *
sharkd_get_frame ( guint32 framenum )
{
2017-12-08 03:31:43 +00:00
return frame_data_sequence_find ( cfile . provider . frames , framenum ) ;
2017-12-07 20:56:11 +00:00
}
2016-10-15 18:48:17 +00:00
int
2018-06-16 16:22:00 +00:00
sharkd_dissect_request ( guint32 framenum , guint32 frame_ref_num , guint32 prev_dis_num , sharkd_dissect_func_t cb , guint32 dissect_flags , void * data )
2016-10-15 18:48:17 +00:00
{
frame_data * fdata ;
2018-06-16 16:22:00 +00:00
column_info * cinfo = ( dissect_flags & SHARKD_DISSECT_FLAG_COLUMNS ) ? & cfile . cinfo : NULL ;
2016-10-15 18:48:17 +00:00
epan_dissect_t edt ;
gboolean create_proto_tree ;
2018-02-09 00:19:12 +00:00
wtap_rec rec ; /* Record metadata */
Buffer buf ; /* Record data */
2016-10-15 18:48:17 +00:00
int err ;
char * err_info = NULL ;
2017-12-07 20:56:11 +00:00
fdata = sharkd_get_frame ( framenum ) ;
2016-10-15 18:48:17 +00:00
if ( fdata = = NULL )
return - 1 ;
2018-02-09 00:19:12 +00:00
wtap_rec_init ( & rec ) ;
2019-04-06 21:02:49 +00:00
ws_buffer_init ( & buf , 1514 ) ;
2016-10-15 18:48:17 +00:00
2018-02-09 00:19:12 +00:00
if ( ! wtap_seek_read ( cfile . provider . wth , fdata - > file_off , & rec , & buf , & err , & err_info ) ) {
2018-10-08 20:50:41 +00:00
wtap_rec_cleanup ( & rec ) ;
2016-10-15 18:48:17 +00:00
ws_buffer_free ( & buf ) ;
return - 1 ; /* error reading the record */
}
2018-06-16 16:22:00 +00:00
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 ) ;
2018-12-27 02:26:24 +00:00
fdata - > need_colorize = 1 ;
2018-06-16 16:22:00 +00:00
}
2016-10-15 18:48:17 +00:00
if ( cinfo )
col_custom_prime_edt ( & edt , cinfo ) ;
/*
* XXX - need to catch an OutOfMemoryError exception and
* attempt to recover from it .
*/
2018-12-27 02:26:24 +00:00
fdata - > ref_time = ( framenum = = frame_ref_num ) ;
2017-12-28 12:07:54 +00:00
fdata - > frame_ref_num = frame_ref_num ;
fdata - > prev_dis_num = prev_dis_num ;
2018-02-09 00:19:12 +00:00
epan_dissect_run ( & edt , cfile . cd_t , & rec ,
2017-12-08 08:30:55 +00:00
frame_tvbuff_new_buffer ( & cfile . provider , fdata , & buf ) ,
fdata , cinfo ) ;
2016-10-15 18:48:17 +00:00
if ( cinfo ) {
/* "Stringify" non frame_data vals */
epan_dissect_fill_in_columns ( & edt , FALSE , TRUE /* fill_fd_columns */ ) ;
}
2018-06-16 16:22:00 +00:00
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 ) ;
2016-10-15 18:48:17 +00:00
epan_dissect_cleanup ( & edt ) ;
2018-02-09 00:19:12 +00:00
wtap_rec_cleanup ( & rec ) ;
2016-10-15 18:48:17 +00:00
ws_buffer_free ( & buf ) ;
return 0 ;
}
/* based on packet_list_dissect_and_cache_record */
int
2017-12-28 12:07:54 +00:00
sharkd_dissect_columns ( frame_data * fdata , guint32 frame_ref_num , guint32 prev_dis_num , column_info * cinfo , gboolean dissect_color )
2016-10-15 18:48:17 +00:00
{
epan_dissect_t edt ;
gboolean create_proto_tree ;
2018-02-09 00:19:12 +00:00
wtap_rec rec ; /* Record metadata */
Buffer buf ; /* Record data */
2016-10-15 18:48:17 +00:00
int err ;
char * err_info = NULL ;
2018-02-09 00:19:12 +00:00
wtap_rec_init ( & rec ) ;
2019-04-06 21:02:49 +00:00
ws_buffer_init ( & buf , 1514 ) ;
2016-10-15 18:48:17 +00:00
2018-02-09 00:19:12 +00:00
if ( ! wtap_seek_read ( cfile . provider . wth , fdata - > file_off , & rec , & buf , & err , & err_info ) ) {
2016-10-15 18:48:17 +00:00
col_fill_in_error ( cinfo , fdata , FALSE , FALSE /* fill_fd_columns */ ) ;
2018-10-08 20:50:41 +00:00
wtap_rec_cleanup ( & rec ) ;
2016-10-15 18:48:17 +00:00
ws_buffer_free ( & buf ) ;
return - 1 ; /* error reading the record */
}
create_proto_tree = ( dissect_color & & color_filters_used ( ) ) | | ( cinfo & & have_custom_cols ( cinfo ) ) ;
epan_dissect_init ( & edt , cfile . epan , create_proto_tree , FALSE /* proto_tree_visible */ ) ;
if ( dissect_color ) {
color_filters_prime_edt ( & edt ) ;
2018-12-27 02:26:24 +00:00
fdata - > need_colorize = 1 ;
2016-10-15 18:48:17 +00:00
}
if ( cinfo )
col_custom_prime_edt ( & edt , cinfo ) ;
/*
* XXX - need to catch an OutOfMemoryError exception and
* attempt to recover from it .
*/
2018-12-27 02:26:24 +00:00
fdata - > ref_time = ( fdata - > num = = frame_ref_num ) ;
2017-12-28 12:07:54 +00:00
fdata - > frame_ref_num = frame_ref_num ;
fdata - > prev_dis_num = prev_dis_num ;
2018-02-09 00:19:12 +00:00
epan_dissect_run ( & edt , cfile . cd_t , & rec ,
2017-12-08 08:30:55 +00:00
frame_tvbuff_new_buffer ( & cfile . provider , fdata , & buf ) ,
fdata , cinfo ) ;
2016-10-15 18:48:17 +00:00
if ( cinfo ) {
/* "Stringify" non frame_data vals */
epan_dissect_fill_in_columns ( & edt , FALSE , TRUE /* fill_fd_columns */ ) ;
}
epan_dissect_cleanup ( & edt ) ;
2018-02-09 00:19:12 +00:00
wtap_rec_cleanup ( & rec ) ;
2016-10-15 18:48:17 +00:00
ws_buffer_free ( & buf ) ;
return 0 ;
}
int
sharkd_retap ( void )
{
guint32 framenum ;
frame_data * fdata ;
Buffer buf ;
2018-02-09 00:19:12 +00:00
wtap_rec rec ;
2016-10-15 18:48:17 +00:00
int err ;
char * err_info = NULL ;
guint tap_flags ;
2017-04-12 02:53:48 +00:00
gboolean create_proto_tree ;
2016-10-15 18:48:17 +00:00
epan_dissect_t edt ;
column_info * cinfo ;
2017-04-12 02:53:48 +00:00
/* Get the union of the flags for all tap listeners. */
2016-10-15 18:48:17 +00:00
tap_flags = union_of_tap_listener_flags ( ) ;
2017-04-12 02:53:48 +00:00
/* If any tap listeners require the columns, construct them. */
2016-10-15 18:48:17 +00:00
cinfo = ( tap_flags & TL_REQUIRES_COLUMNS ) ? & cfile . cinfo : NULL ;
2017-04-12 02:53:48 +00:00
/*
* 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 ) ) ;
2018-02-09 00:19:12 +00:00
wtap_rec_init ( & rec ) ;
2019-04-06 21:02:49 +00:00
ws_buffer_init ( & buf , 1514 ) ;
2017-04-12 02:53:48 +00:00
epan_dissect_init ( & edt , cfile . epan , create_proto_tree , FALSE ) ;
2016-10-15 18:48:17 +00:00
reset_tap_listeners ( ) ;
for ( framenum = 1 ; framenum < = cfile . count ; framenum + + ) {
2017-12-07 20:56:11 +00:00
fdata = sharkd_get_frame ( framenum ) ;
2016-10-15 18:48:17 +00:00
2018-02-09 00:19:12 +00:00
if ( ! wtap_seek_read ( cfile . provider . wth , fdata - > file_off , & rec , & buf , & err , & err_info ) )
2016-10-15 18:48:17 +00:00
break ;