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>
# include <wsutil/clopts_common.h>
# include <wsutil/cmdarg_err.h>
# include <wsutil/crash_info.h>
# 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>
2017-09-26 14:04:56 +00:00
# include <version_info.h>
2016-10-15 18:48:17 +00:00
# include <wiretap/wtap_opttypes.h>
# include <wiretap/pcapng.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"
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>
2016-10-15 18:48:17 +00:00
2017-04-08 08:15:11 +00:00
# include <codecs/codecs.h>
2016-10-15 18:48:17 +00:00
# include "log.h"
# 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 ;
2017-04-08 19:45:19 +00:00
static void failure_warning_message ( const char * msg_format , va_list ap ) ;
2016-10-15 18:48:17 +00:00
static void open_failure_message ( const char * filename , int err ,
gboolean for_writing ) ;
static void read_failure_message ( const char * filename , int err ) ;
static void write_failure_message ( const char * filename , int err ) ;
static void failure_message_cont ( const char * msg_format , va_list ap ) ;
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 [ ] )
{
GString * comp_info_str ;
GString * runtime_info_str ;
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 ;
2016-10-15 18:48:17 +00:00
2017-04-08 19:45:19 +00:00
cmdarg_err_init ( failure_warning_message , failure_message_cont ) ;
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 ) ;
}
/* Get the compile-time version information string */
comp_info_str = get_compiled_version_info ( NULL , epan_get_compiled_version_info ) ;
/* Get the run-time version information string */
runtime_info_str = get_runtime_version_info ( epan_get_runtime_version_info ) ;
/* Add it to the information to be reported on a crash. */
ws_add_crash_info ( " Sharkd (Wireshark) %s \n "
" \n "
" %s "
" \n "
" %s " ,
get_ws_vcs_version_info ( ) , comp_info_str - > str , runtime_info_str - > str ) ;
g_string_free ( comp_info_str , TRUE ) ;
g_string_free ( runtime_info_str , TRUE ) ;
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
}
2017-04-08 19:45:19 +00:00
init_report_message ( failure_warning_message , failure_warning_message ,
open_failure_message , read_failure_message ,
write_failure_message ) ;
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 ) ;
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-08-28 20:39:55 +00:00
if ( ! epan_init ( NULL , NULL ) ) {
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
2017-02-03 22:06:35 +00:00
ret = sharkd_loop ( ) ;
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 ,
cap_file_provider_get_user_comment
} ;
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 ,
2018-02-09 00:19:12 +00:00
gint64 offset , wtap_rec * rec , const guchar * pd )
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 ,
2017-12-08 08:30:55 +00:00
frame_tvbuff_new ( & cf - > provider , & fdlocal , pd ) ,
& 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 ;
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 ) ;
}
2017-12-08 03:31:43 +00:00
while ( wtap_read ( cf - > provider . wth , & err , & err_info , & data_offset ) ) {
2018-02-09 00:19:12 +00:00
if ( process_packet ( cf , edt , data_offset , wtap_get_rec ( cf - > provider . wth ) ,
wtap_get_buf_ptr ( cf - > provider . wth ) ) ) {
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 ;
}
/* 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 ) {
2017-04-20 02:21:11 +00:00
cfile_read_failure_message ( " sharkd " , 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 ) ;
2016-10-15 18:48:17 +00:00
return CF_OK ;
fail :
2017-04-20 18:23:51 +00:00
cfile_open_failure_message ( " sharkd " , fname , * err , err_info ) ;
2016-10-15 18:48:17 +00:00
return CF_ERROR ;
}
/*
2017-04-08 19:45:19 +00:00
* General errors and warnings are reported with an console message
* in sharkd .
2016-10-15 18:48:17 +00:00
*/
static void
2017-04-08 19:45:19 +00:00
failure_warning_message ( 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 " ) ;
}
/*
2017-04-08 19:45:19 +00:00
* Open / create errors are reported with an console message in sharkd .
2016-10-15 18:48:17 +00:00
*/
static void
2017-04-08 19:45:19 +00:00
open_failure_message ( const char * filename , int err , gboolean for_writing )
2016-10-15 18:48:17 +00:00
{
fprintf ( stderr , " sharkd: " ) ;
2017-04-08 19:45:19 +00:00
fprintf ( stderr , file_open_error_message ( err , for_writing ) , filename ) ;
2016-10-15 18:48:17 +00:00
fprintf ( stderr , " \n " ) ;
}
/*
2017-04-08 19:45:19 +00:00
* Read errors are reported with an console message in sharkd .
2016-10-15 18:48:17 +00:00
*/
static void
read_failure_message ( const char * filename , int err )
{
cmdarg_err ( " An error occurred while reading from the file \" %s \" : %s. " ,
filename , g_strerror ( err ) ) ;
}
/*
2017-04-08 19:45:19 +00:00
* Write errors are reported with an console message in sharkd .
2016-10-15 18:48:17 +00:00
*/
static void
write_failure_message ( const char * filename , int err )
{
cmdarg_err ( " An error occurred while writing to the file \" %s \" : %s. " ,
filename , g_strerror ( err ) ) ;
}
/*
* Report additional information for an error in command - line arguments .
*/
static void
failure_message_cont ( const char * msg_format , va_list ap )
{
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 ) ;
2016-10-15 18:48:17 +00:00
ws_buffer_init ( & buf , 1500 ) ;
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
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 ) ;
fdata - > flags . 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 .
*/
2017-12-28 12:07:54 +00:00
fdata - > flags . ref_time = ( framenum = = frame_ref_num ) ;
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 ) ;
2016-10-15 18:48:17 +00:00
ws_buffer_init ( & buf , 1500 ) ;
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 */ ) ;
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 ) ;
fdata - > flags . need_colorize = 1 ;
}
if ( cinfo )
col_custom_prime_edt ( & edt , cinfo ) ;
/*
* XXX - need to catch an OutOfMemoryError exception and
* attempt to recover from it .
*/
2017-12-28 12:07:54 +00:00
fdata - > flags . ref_time = ( fdata - > num = = frame_ref_num ) ;
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 ) ;
2016-10-15 18:48:17 +00:00
ws_buffer_init ( & buf , 1500 ) ;
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 ;
2017-12-28 12:07:54 +00:00
fdata - > flags . ref_time = FALSE ;
fdata - > frame_ref_num = ( framenum ! = 1 ) ? 1 : 0 ;
fdata - > prev_dis_num = framenum - 1 ;
2018-02-09 00:19:12 +00:00
epan_dissect_run_with_taps ( & edt , cfile . cd_t , & rec ,
2017-12-08 08:30:55 +00:00
frame_tvbuff_new ( & cfile . provider , fdata , ws_buffer_start_ptr ( & buf ) ) ,
fdata , cinfo ) ;
2016-10-15 18:48:17 +00:00
epan_dissect_reset ( & 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 ) ;
epan_dissect_cleanup ( & edt ) ;
draw_tap_listeners ( TRUE ) ;
return 0 ;
}
int
sharkd_filter ( const char * dftext , guint8 * * result )
{
dfilter_t * dfcode = NULL ;