Remove editor modelines and .editorconfig exceptions from root files

This commit is contained in:
David Perry 2022-02-20 19:39:37 +00:00 committed by A Wireshark GitLab Utility
parent 695ce22b0d
commit 70d432c357
19 changed files with 15965 additions and 16219 deletions

View File

@ -71,51 +71,3 @@ indent_size = 8
[*.{c,cpp,h}] [*.{c,cpp,h}]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
[{capinfos,captype,mergecap,tfshark,tshark}.c]
indent_size = 2
[{dftest,randpkt,trigcap}.c]
indent_style = tab
indent_size = tab
[capture_stop_conditions.[ch]]
indent_size = 2
[cfile.[ch]]
indent_size = 2
[conditions.[ch]]
indent_size = 2
[file.[ch]]
indent_size = 2
[frame_tvbuff.[ch]]
indent_style = tab
indent_size = tab
[pcapio.[ch]]
indent_size = 8
[ringbuffer.[ch]]
indent_size = 2
[randpkt_core.[ch]]
indent_style = tab
indent_size = tab
[sharkd.c]
indent_size = 2
[sharkd_daemon.c]
indent_style = tab
indent_size = tab
[sharkd_session.c]
indent_style = tab
indent_size = tab
[version_info.[ch]]
indent_style = tab
indent_size = tab

2824
capinfos.c

File diff suppressed because it is too large Load Diff

229
captype.c
View File

@ -46,12 +46,12 @@
static void static void
print_usage(FILE *output) print_usage(FILE *output)
{ {
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Usage: captype [options] <infile> ...\n"); fprintf(output, "Usage: captype [options] <infile> ...\n");
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Miscellaneous:\n"); fprintf(output, "Miscellaneous:\n");
fprintf(output, " -h, --help display this help and exit\n"); fprintf(output, " -h, --help display this help and exit\n");
fprintf(output, " -v, --version display version info and exit\n"); fprintf(output, " -v, --version display version info and exit\n");
} }
/* /*
@ -60,9 +60,9 @@ print_usage(FILE *output)
static void static void
captype_cmdarg_err(const char *msg_format, va_list ap) captype_cmdarg_err(const char *msg_format, va_list ap)
{ {
fprintf(stderr, "captype: "); fprintf(stderr, "captype: ");
vfprintf(stderr, msg_format, ap); vfprintf(stderr, msg_format, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
/* /*
@ -71,145 +71,132 @@ captype_cmdarg_err(const char *msg_format, va_list ap)
static void static void
captype_cmdarg_err_cont(const char *msg_format, va_list ap) captype_cmdarg_err_cont(const char *msg_format, va_list ap)
{ {
vfprintf(stderr, msg_format, ap); vfprintf(stderr, msg_format, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *init_progfile_dir_error; char *init_progfile_dir_error;
static const struct report_message_routines captype_report_routines = { static const struct report_message_routines captype_report_routines = {
failure_message, failure_message,
failure_message, failure_message,
open_failure_message, open_failure_message,
read_failure_message, read_failure_message,
write_failure_message, write_failure_message,
cfile_open_failure_message, cfile_open_failure_message,
cfile_dump_open_failure_message, cfile_dump_open_failure_message,
cfile_read_failure_message, cfile_read_failure_message,
cfile_write_failure_message, cfile_write_failure_message,
cfile_close_failure_message cfile_close_failure_message
}; };
wtap *wth; wtap *wth;
int err; int err;
gchar *err_info; gchar *err_info;
int i; int i;
int opt; int opt;
int overall_error_status; int overall_error_status;
static const struct ws_option long_options[] = { static const struct ws_option long_options[] = {
{"help", ws_no_argument, NULL, 'h'}, {"help", ws_no_argument, NULL, 'h'},
{"version", ws_no_argument, NULL, 'v'}, {"version", ws_no_argument, NULL, 'v'},
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
/* /*
* Set the C-language locale to the native environment and set the * Set the C-language locale to the native environment and set the
* code page to UTF-8 on Windows. * code page to UTF-8 on Windows.
*/ */
#ifdef _WIN32 #ifdef _WIN32
setlocale(LC_ALL, ".UTF-8"); setlocale(LC_ALL, ".UTF-8");
#else #else
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
#endif #endif
cmdarg_err_init(captype_cmdarg_err, captype_cmdarg_err_cont); cmdarg_err_init(captype_cmdarg_err, captype_cmdarg_err_cont);
/* Initialize log handler early so we can have proper logging during startup. */ /* Initialize log handler early so we can have proper logging during startup. */
ws_log_init("captype", vcmdarg_err); ws_log_init("captype", vcmdarg_err);
/* Early logging command-line initialization. */ /* Early logging command-line initialization. */
ws_log_parse_args(&argc, argv, vcmdarg_err, 1); ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
/* Initialize the version information. */ /* Initialize the version information. */
ws_init_version_info("Captype (Wireshark)", NULL, NULL, NULL); ws_init_version_info("Captype (Wireshark)", NULL, NULL, NULL);
#ifdef _WIN32 #ifdef _WIN32
create_app_running_mutex(); create_app_running_mutex();
#endif /* _WIN32 */ #endif /* _WIN32 */
/* /*
* Get credential information for later use. * Get credential information for later use.
*/ */
init_process_policies(); init_process_policies();
/* /*
* Attempt to get the pathname of the directory containing the * Attempt to get the pathname of the directory containing the
* executable file. * executable file.
*/ */
init_progfile_dir_error = init_progfile_dir(argv[0]); init_progfile_dir_error = init_progfile_dir(argv[0]);
if (init_progfile_dir_error != NULL) { if (init_progfile_dir_error != NULL) {
fprintf(stderr, fprintf(stderr,
"captype: Can't get pathname of directory containing the captype program: %s.\n", "captype: Can't get pathname of directory containing the captype program: %s.\n",
init_progfile_dir_error); init_progfile_dir_error);
g_free(init_progfile_dir_error); g_free(init_progfile_dir_error);
} }
init_report_message("captype", &captype_report_routines); init_report_message("captype", &captype_report_routines);
wtap_init(TRUE); wtap_init(TRUE);
/* Process the options */ /* Process the options */
while ((opt = ws_getopt_long(argc, argv, "hv", long_options, NULL)) !=-1) { while ((opt = ws_getopt_long(argc, argv, "hv", long_options, NULL)) !=-1) {
switch (opt) { switch (opt) {
case 'h': case 'h':
show_help_header("Print the file types of capture files."); show_help_header("Print the file types of capture files.");
print_usage(stdout); print_usage(stdout);
exit(0); exit(0);
break; break;
case 'v': case 'v':
show_version(); show_version();
exit(0); exit(0);
break; break;
case '?': /* Bad flag - print usage message */ case '?': /* Bad flag - print usage message */
print_usage(stderr);
exit(1);
break;
}
}
if (argc < 2) {
print_usage(stderr); print_usage(stderr);
exit(1); return 1;
break;
}
}
if (argc < 2) {
print_usage(stderr);
return 1;
}
overall_error_status = 0;
for (i = 1; i < argc; i++) {
wth = wtap_open_offline(argv[i], WTAP_TYPE_AUTO, &err, &err_info, FALSE);
if(wth) {
printf("%s: %s\n", argv[i], wtap_file_type_subtype_name(wtap_file_type_subtype(wth)));
wtap_close(wth);
} else {
if (err == WTAP_ERR_FILE_UNKNOWN_FORMAT)
printf("%s: unknown\n", argv[i]);
else {
cfile_open_failure_message(argv[i], err, err_info);
overall_error_status = 2; /* remember that an error has occurred */
}
} }
} overall_error_status = 0;
wtap_cleanup(); for (i = 1; i < argc; i++) {
free_progdirs(); wth = wtap_open_offline(argv[i], WTAP_TYPE_AUTO, &err, &err_info, FALSE);
return overall_error_status;
if(wth) {
printf("%s: %s\n", argv[i], wtap_file_type_subtype_name(wtap_file_type_subtype(wth)));
wtap_close(wth);
} else {
if (err == WTAP_ERR_FILE_UNKNOWN_FORMAT)
printf("%s: unknown\n", argv[i]);
else {
cfile_open_failure_message(argv[i], err, err_info);
overall_error_status = 2; /* remember that an error has occurred */
}
}
}
wtap_cleanup();
free_progdirs();
return overall_error_status;
} }
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

17
cfile.c
View File

@ -20,19 +20,6 @@
void void
cap_file_init(capture_file *cf) cap_file_init(capture_file *cf)
{ {
/* Initialize the capture file struct */ /* Initialize the capture file struct */
memset(cf, 0, sizeof(capture_file)); memset(cf, 0, sizeof(capture_file));
} }
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

169
cfile.h
View File

@ -25,107 +25,107 @@ extern "C" {
/* Current state of file. */ /* Current state of file. */
typedef enum { typedef enum {
FILE_CLOSED, /* No file open */ FILE_CLOSED, /* No file open */
FILE_READ_IN_PROGRESS, /* Reading a file we've opened */ FILE_READ_IN_PROGRESS, /* Reading a file we've opened */
FILE_READ_ABORTED, /* Read aborted by user */ FILE_READ_ABORTED, /* Read aborted by user */
FILE_READ_DONE /* Read completed */ FILE_READ_DONE /* Read completed */
} file_state; } file_state;
/* Requested packets rescan action. */ /* Requested packets rescan action. */
typedef enum { typedef enum {
RESCAN_NONE = 0, /* No rescan requested */ RESCAN_NONE = 0, /* No rescan requested */
RESCAN_SCAN, /* Request rescan without full redissection. */ RESCAN_SCAN, /* Request rescan without full redissection. */
RESCAN_REDISSECT /* Request full redissection. */ RESCAN_REDISSECT /* Request full redissection. */
} rescan_type; } rescan_type;
/* Character set for text search. */ /* Character set for text search. */
typedef enum { typedef enum {
SCS_NARROW_AND_WIDE, SCS_NARROW_AND_WIDE,
SCS_NARROW, SCS_NARROW,
SCS_WIDE SCS_WIDE
/* add EBCDIC when it's implemented */ /* add EBCDIC when it's implemented */
} search_charset_t; } search_charset_t;
typedef enum { typedef enum {
SD_FORWARD, SD_FORWARD,
SD_BACKWARD SD_BACKWARD
} search_direction; } search_direction;
/* /*
* Packet provider for programs using a capture file. * Packet provider for programs using a capture file.
*/ */
struct packet_provider_data { struct packet_provider_data {
wtap *wth; /* Wiretap session */ wtap *wth; /* Wiretap session */
const frame_data *ref; const frame_data *ref;
frame_data *prev_dis; frame_data *prev_dis;
frame_data *prev_cap; frame_data *prev_cap;
frame_data_sequence *frames; /* Sequence of frames, if we're keeping that information */ frame_data_sequence *frames; /* Sequence of frames, if we're keeping that information */
GTree *frames_modified_blocks; /* BST with modified blocks for frames (key = frame_data) */ GTree *frames_modified_blocks; /* BST with modified blocks for frames (key = frame_data) */
}; };
typedef struct _capture_file { typedef struct _capture_file {
epan_t *epan; epan_t *epan;
file_state state; /* Current state of capture file */ file_state state; /* Current state of capture file */
gchar *filename; /* Name of capture file */ gchar *filename; /* Name of capture file */
gchar *source; /* Temp file source, e.g. "Pipe from elsewhere" */ gchar *source; /* Temp file source, e.g. "Pipe from elsewhere" */
gboolean is_tempfile; /* Is capture file a temporary file? */ gboolean is_tempfile; /* Is capture file a temporary file? */
gboolean unsaved_changes; /* Does the capture file have changes that have not been saved? */ gboolean unsaved_changes; /* Does the capture file have changes that have not been saved? */
gboolean stop_flag; /* Stop current processing (loading, searching, etc.) */ gboolean stop_flag; /* Stop current processing (loading, searching, etc.) */
gint64 f_datalen; /* Size of capture file data (uncompressed) */ gint64 f_datalen; /* Size of capture file data (uncompressed) */
guint16 cd_t; /* File type of capture file */ guint16 cd_t; /* File type of capture file */
unsigned int open_type; /* open_routine index+1 used, if selected, or WTAP_TYPE_AUTO */ unsigned int open_type; /* open_routine index+1 used, if selected, or WTAP_TYPE_AUTO */
wtap_compression_type compression_type; /* Compression type of the file, or uncompressed */ wtap_compression_type compression_type; /* Compression type of the file, or uncompressed */
int lnk_t; /* File link-layer type; could be WTAP_ENCAP_PER_PACKET */ int lnk_t; /* File link-layer type; could be WTAP_ENCAP_PER_PACKET */
GArray *linktypes; /* Array of packet link-layer types */ GArray *linktypes; /* Array of packet link-layer types */
guint32 count; /* Total number of frames */ guint32 count; /* Total number of frames */
guint64 packet_comment_count; /* Number of comments in frames (could be >1 per frame... */ guint64 packet_comment_count; /* Number of comments in frames (could be >1 per frame... */
guint32 displayed_count; /* Number of displayed frames */ guint32 displayed_count; /* Number of displayed frames */
guint32 marked_count; /* Number of marked frames */ guint32 marked_count; /* Number of marked frames */
guint32 ignored_count; /* Number of ignored frames */ guint32 ignored_count; /* Number of ignored frames */
guint32 ref_time_count; /* Number of time referenced frames */ guint32 ref_time_count; /* Number of time referenced frames */
gboolean drops_known; /* TRUE if we know how many packets were dropped */ gboolean drops_known; /* TRUE if we know how many packets were dropped */
guint32 drops; /* Dropped packets */ guint32 drops; /* Dropped packets */
nstime_t elapsed_time; /* Elapsed time */ nstime_t elapsed_time; /* Elapsed time */
int snap; /* Maximum captured packet length; 0 if unknown */ int snap; /* Maximum captured packet length; 0 if unknown */
dfilter_t *rfcode; /* Compiled read filter program */ dfilter_t *rfcode; /* Compiled read filter program */
dfilter_t *dfcode; /* Compiled display filter program */ dfilter_t *dfcode; /* Compiled display filter program */
gchar *dfilter; /* Display filter string */ gchar *dfilter; /* Display filter string */
gboolean redissecting; /* TRUE if currently redissecting (cf_redissect_packets) */ gboolean redissecting; /* TRUE if currently redissecting (cf_redissect_packets) */
gboolean read_lock; /* TRUE if currently processing a file (cf_read) */ gboolean read_lock; /* TRUE if currently processing a file (cf_read) */
rescan_type redissection_queued; /* Queued redissection type. */ rescan_type redissection_queued; /* Queued redissection type. */
/* search */ /* search */
gchar *sfilter; /* Filter, hex value, or string being searched */ gchar *sfilter; /* Filter, hex value, or string being searched */
gboolean hex; /* TRUE if "Hex value" search was last selected */ gboolean hex; /* TRUE if "Hex value" search was last selected */
gboolean string; /* TRUE if "String" search was last selected */ gboolean string; /* TRUE if "String" search was last selected */
gboolean summary_data; /* TRUE if "String" search in "Packet list" (Info column) was last selected */ gboolean summary_data; /* TRUE if "String" search in "Packet list" (Info column) was last selected */
gboolean decode_data; /* TRUE if "String" search in "Packet details" was last selected */ gboolean decode_data; /* TRUE if "String" search in "Packet details" was last selected */
gboolean packet_data; /* TRUE if "String" search in "Packet data" was last selected */ gboolean packet_data; /* TRUE if "String" search in "Packet data" was last selected */
guint32 search_pos; /* Byte position of last byte found in a hex search */ guint32 search_pos; /* Byte position of last byte found in a hex search */
guint32 search_len; /* Length of bytes matching the search */ guint32 search_len; /* Length of bytes matching the search */
gboolean case_type; /* TRUE if case-insensitive text search */ gboolean case_type; /* TRUE if case-insensitive text search */
GRegex *regex; /* Set if regular expression search */ GRegex *regex; /* Set if regular expression search */
search_charset_t scs_type; /* Character set for text search */ search_charset_t scs_type; /* Character set for text search */
search_direction dir; /* Direction in which to do searches */ search_direction dir; /* Direction in which to do searches */
gboolean search_in_progress; /* TRUE if user just clicked OK in the Find dialog or hit <control>N/B */ gboolean search_in_progress; /* TRUE if user just clicked OK in the Find dialog or hit <control>N/B */
/* packet provider */ /* packet provider */
struct packet_provider_data provider; struct packet_provider_data provider;
/* frames */ /* frames */
guint32 first_displayed; /* Frame number of first frame displayed */ guint32 first_displayed; /* Frame number of first frame displayed */
guint32 last_displayed; /* Frame number of last frame displayed */ guint32 last_displayed; /* Frame number of last frame displayed */
/* Data for currently selected frame */ /* Data for currently selected frame */
column_info cinfo; /* Column formatting information */ column_info cinfo; /* Column formatting information */
frame_data *current_frame; /* Frame data */ frame_data *current_frame; /* Frame data */
gint current_row; /* Row number */ gint current_row; /* Row number */
epan_dissect_t *edt; /* Protocol dissection */ epan_dissect_t *edt; /* Protocol dissection */
field_info *finfo_selected; /* Field info */ field_info *finfo_selected; /* Field info */
wtap_rec rec; /* Record header */ wtap_rec rec; /* Record header */
Buffer buf; /* Record data */ Buffer buf; /* Record data */
gpointer window; /* Top-level window associated with file */ gpointer window; /* Top-level window associated with file */
gulong computed_elapsed; /* Elapsed time to load the file (in msec). */ gulong computed_elapsed; /* Elapsed time to load the file (in msec). */
guint32 cum_bytes; guint32 cum_bytes;
} capture_file; } capture_file;
extern void cap_file_init(capture_file *cf); extern void cap_file_init(capture_file *cf);
@ -140,16 +140,3 @@ void cap_file_provider_set_modified_block(struct packet_provider_data *prov, fra
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* cfile.h */ #endif /* cfile.h */
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

197
dftest.c
View File

@ -43,115 +43,115 @@ static void dftest_cmdarg_err_cont(const char *fmt, va_list ap);
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
char *init_progfile_dir_error; char *init_progfile_dir_error;
static const struct report_message_routines dftest_report_routines = { static const struct report_message_routines dftest_report_routines = {
failure_message, failure_message,
failure_message, failure_message,
open_failure_message, open_failure_message,
read_failure_message, read_failure_message,
write_failure_message, write_failure_message,
cfile_open_failure_message, cfile_open_failure_message,
cfile_dump_open_failure_message, cfile_dump_open_failure_message,
cfile_read_failure_message, cfile_read_failure_message,
cfile_write_failure_message, cfile_write_failure_message,
cfile_close_failure_message cfile_close_failure_message
}; };
char *text; char *text;
dfilter_t *df; dfilter_t *df;
gchar *err_msg; gchar *err_msg;
cmdarg_err_init(dftest_cmdarg_err, dftest_cmdarg_err_cont); cmdarg_err_init(dftest_cmdarg_err, dftest_cmdarg_err_cont);
/* Initialize log handler early so we can have proper logging during startup. */ /* Initialize log handler early so we can have proper logging during startup. */
ws_log_init("dftest", vcmdarg_err); ws_log_init("dftest", vcmdarg_err);
/* Early logging command-line initialization. */ /* Early logging command-line initialization. */
ws_log_parse_args(&argc, argv, vcmdarg_err, 1); ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
/* /*
* Get credential information for later use. * Get credential information for later use.
*/ */
init_process_policies(); init_process_policies();
/* /*
* Attempt to get the pathname of the directory containing the * Attempt to get the pathname of the directory containing the
* executable file. * executable file.
*/ */
init_progfile_dir_error = init_progfile_dir(argv[0]); init_progfile_dir_error = init_progfile_dir(argv[0]);
if (init_progfile_dir_error != NULL) { if (init_progfile_dir_error != NULL) {
fprintf(stderr, "dftest: Can't get pathname of directory containing the dftest program: %s.\n", fprintf(stderr, "dftest: Can't get pathname of directory containing the dftest program: %s.\n",
init_progfile_dir_error); init_progfile_dir_error);
g_free(init_progfile_dir_error); g_free(init_progfile_dir_error);
} }
init_report_message("dftest", &dftest_report_routines); init_report_message("dftest", &dftest_report_routines);
timestamp_set_type(TS_RELATIVE); timestamp_set_type(TS_RELATIVE);
timestamp_set_seconds_type(TS_SECONDS_DEFAULT); timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
/* /*
* Libwiretap must be initialized before libwireshark is, so that * Libwiretap must be initialized before libwireshark is, so that
* dissection-time handlers for file-type-dependent blocks can * dissection-time handlers for file-type-dependent blocks can
* register using the file type/subtype value for the file type. * register using the file type/subtype value for the file type.
*/ */
wtap_init(TRUE); wtap_init(TRUE);
/* Register all dissectors; we must do this before checking for the /* Register all dissectors; we must do this before checking for the
"-g" flag, as the "-g" flag dumps a list of fields registered "-g" flag, as the "-g" flag dumps a list of fields registered
by the dissectors, and we must do it before we read the preferences, by the dissectors, and we must do it before we read the preferences,
in case any dissectors register preferences. */ in case any dissectors register preferences. */
if (!epan_init(NULL, NULL, FALSE)) if (!epan_init(NULL, NULL, FALSE))
return 2; return 2;
/* /*
* Set the C-language locale to the native environment and set the * Set the C-language locale to the native environment and set the
* code page to UTF-8 on Windows. * code page to UTF-8 on Windows.
*/ */
#ifdef _WIN32 #ifdef _WIN32
setlocale(LC_ALL, ".UTF-8"); setlocale(LC_ALL, ".UTF-8");
#else #else
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
#endif #endif
/* Load libwireshark settings from the current profile. */ /* Load libwireshark settings from the current profile. */
epan_load_settings(); epan_load_settings();
/* notify all registered modules that have had any of their preferences /* notify all registered modules that have had any of their preferences
changed either from one of the preferences file or from the command changed either from one of the preferences file or from the command
line that its preferences have changed. */ line that its preferences have changed. */
prefs_apply_all(); prefs_apply_all();
/* Check for filter on command line */ /* Check for filter on command line */
if (argc <= 1) { if (argc <= 1) {
fprintf(stderr, "Usage: dftest <filter>\n"); fprintf(stderr, "Usage: dftest <filter>\n");
exit(1); exit(1);
} }
/* Get filter text */ /* Get filter text */
text = get_args_as_string(argc, argv, 1); text = get_args_as_string(argc, argv, 1);
printf("Filter: %s\n", text); printf("Filter: %s\n", text);
/* Compile it */ /* Compile it */
if (!dfilter_compile(text, &df, &err_msg)) { if (!dfilter_compile(text, &df, &err_msg)) {
fprintf(stderr, "dftest: %s\n", err_msg); fprintf(stderr, "dftest: %s\n", err_msg);
g_free(err_msg); g_free(err_msg);
epan_cleanup(); epan_cleanup();
g_free(text); g_free(text);
exit(2); exit(2);
} }
printf("\n"); printf("\n");
if (df == NULL) if (df == NULL)
printf("Filter is empty\n"); printf("Filter is empty\n");
else else
dfilter_dump(df); dfilter_dump(df);
dfilter_free(df); dfilter_free(df);
epan_cleanup(); epan_cleanup();
g_free(text); g_free(text);
exit(0); exit(0);
} }
/* /*
@ -160,9 +160,9 @@ main(int argc, char **argv)
static void static void
dftest_cmdarg_err(const char *fmt, va_list ap) dftest_cmdarg_err(const char *fmt, va_list ap)
{ {
fprintf(stderr, "dftest: "); fprintf(stderr, "dftest: ");
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
/* /*
@ -171,19 +171,6 @@ dftest_cmdarg_err(const char *fmt, va_list ap)
static void static void
dftest_cmdarg_err_cont(const char *fmt, va_list ap) dftest_cmdarg_err_cont(const char *fmt, va_list ap)
{ {
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* 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:
*/

7995
file.c

File diff suppressed because it is too large Load Diff

13
file.h
View File

@ -735,16 +735,3 @@ gboolean cf_add_ip_name_from_string(capture_file *cf, const char *addr, const ch
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* file.h */ #endif /* file.h */
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/

View File

@ -21,36 +21,36 @@
#include "wiretap/wtap-int.h" /* for ->random_fh */ #include "wiretap/wtap-int.h" /* for ->random_fh */
struct tvb_frame { struct tvb_frame {
struct tvbuff tvb; struct tvbuff tvb;
Buffer *buf; /* Packet data */ Buffer *buf; /* Packet data */
const struct packet_provider_data *prov; /* provider of packet information */ const struct packet_provider_data *prov; /* provider of packet information */
gint64 file_off; /**< File offset */ gint64 file_off; /**< File offset */
guint offset; guint offset;
}; };
static gboolean static gboolean
frame_read(struct tvb_frame *frame_tvb, wtap_rec *rec, Buffer *buf) frame_read(struct tvb_frame *frame_tvb, wtap_rec *rec, Buffer *buf)
{ {
int err; int err;
gchar *err_info; gchar *err_info;
gboolean ok = TRUE; gboolean ok = TRUE;
/* XXX, what if phdr->caplen isn't equal to /* XXX, what if phdr->caplen isn't equal to
* frame_tvb->tvb.length + frame_tvb->offset? * frame_tvb->tvb.length + frame_tvb->offset?
*/ */
if (!wtap_seek_read(frame_tvb->prov->wth, frame_tvb->file_off, rec, buf, &err, &err_info)) { if (!wtap_seek_read(frame_tvb->prov->wth, frame_tvb->file_off, rec, buf, &err, &err_info)) {
/* XXX - report error! */ /* XXX - report error! */
switch (err) { switch (err) {
case WTAP_ERR_BAD_FILE: case WTAP_ERR_BAD_FILE:
g_free(err_info); g_free(err_info);
ok = FALSE; ok = FALSE;
break; break;
} }
} }
return ok; return ok;
} }
static GPtrArray *buffer_cache = NULL; static GPtrArray *buffer_cache = NULL;
@ -58,287 +58,274 @@ static GPtrArray *buffer_cache = NULL;
static void static void
frame_cache(struct tvb_frame *frame_tvb) frame_cache(struct tvb_frame *frame_tvb)
{ {
wtap_rec rec; /* Record metadata */ wtap_rec rec; /* Record metadata */
wtap_rec_init(&rec); wtap_rec_init(&rec);
if (frame_tvb->buf == NULL) { if (frame_tvb->buf == NULL) {
if (G_UNLIKELY(!buffer_cache)) buffer_cache = g_ptr_array_sized_new(1024); if (G_UNLIKELY(!buffer_cache)) buffer_cache = g_ptr_array_sized_new(1024);
if (buffer_cache->len > 0) { if (buffer_cache->len > 0) {
frame_tvb->buf = (struct Buffer *) g_ptr_array_remove_index(buffer_cache, buffer_cache->len - 1); frame_tvb->buf = (struct Buffer *) g_ptr_array_remove_index(buffer_cache, buffer_cache->len - 1);
} else { } else {
frame_tvb->buf = g_new(struct Buffer, 1); frame_tvb->buf = g_new(struct Buffer, 1);
} }
ws_buffer_init(frame_tvb->buf, frame_tvb->tvb.length + frame_tvb->offset); ws_buffer_init(frame_tvb->buf, frame_tvb->tvb.length + frame_tvb->offset);
if (!frame_read(frame_tvb, &rec, frame_tvb->buf)) if (!frame_read(frame_tvb, &rec, frame_tvb->buf))
{ /* TODO: THROW(???); */ } { /* TODO: THROW(???); */ }
} }
frame_tvb->tvb.real_data = ws_buffer_start_ptr(frame_tvb->buf) + frame_tvb->offset; frame_tvb->tvb.real_data = ws_buffer_start_ptr(frame_tvb->buf) + frame_tvb->offset;
wtap_rec_cleanup(&rec); wtap_rec_cleanup(&rec);
} }
static void static void
frame_free(tvbuff_t *tvb) frame_free(tvbuff_t *tvb)
{ {
struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb; struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
if (frame_tvb->buf) { if (frame_tvb->buf) {
ws_buffer_free(frame_tvb->buf); ws_buffer_free(frame_tvb->buf);
g_ptr_array_add(buffer_cache, frame_tvb->buf); g_ptr_array_add(buffer_cache, frame_tvb->buf);
} }
} }
static const guint8 * static const guint8 *
frame_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length _U_) frame_get_ptr(tvbuff_t *tvb, guint abs_offset, guint abs_length _U_)
{ {
struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb; struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
frame_cache(frame_tvb); frame_cache(frame_tvb);
return tvb->real_data + abs_offset; return tvb->real_data + abs_offset;
} }
static void * static void *
frame_memcpy(tvbuff_t *tvb, void *target, guint abs_offset, guint abs_length) frame_memcpy(tvbuff_t *tvb, void *target, guint abs_offset, guint abs_length)
{ {
struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb; struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
frame_cache(frame_tvb); frame_cache(frame_tvb);
return memcpy(target, tvb->real_data + abs_offset, abs_length); return memcpy(target, tvb->real_data + abs_offset, abs_length);
} }
static gint static gint
frame_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle) frame_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
{ {
struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb; struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
const guint8 *result; const guint8 *result;
frame_cache(frame_tvb); frame_cache(frame_tvb);
result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit); result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
if (result) if (result)
return (gint) (result - tvb->real_data); return (gint) (result - tvb->real_data);
else else
return -1; return -1;
} }
static gint static gint
frame_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle) frame_pbrk_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, const ws_mempbrk_pattern* pattern, guchar *found_needle)
{ {
struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb; struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
frame_cache(frame_tvb); frame_cache(frame_tvb);
return tvb_ws_mempbrk_pattern_guint8(tvb, abs_offset, limit, pattern, found_needle); return tvb_ws_mempbrk_pattern_guint8(tvb, abs_offset, limit, pattern, found_needle);
} }
static guint static guint
frame_offset(const tvbuff_t *tvb _U_, const guint counter) frame_offset(const tvbuff_t *tvb _U_, const guint counter)
{ {
/* XXX: frame_tvb->offset */ /* XXX: frame_tvb->offset */
return counter; return counter;
} }
static tvbuff_t *frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length); static tvbuff_t *frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length);
static const struct tvb_ops tvb_frame_ops = { static const struct tvb_ops tvb_frame_ops = {
sizeof(struct tvb_frame), /* size */ sizeof(struct tvb_frame), /* size */
frame_free, /* free */ frame_free, /* free */
frame_offset, /* offset */ frame_offset, /* offset */
frame_get_ptr, /* get_ptr */ frame_get_ptr, /* get_ptr */
frame_memcpy, /* memcpy */ frame_memcpy, /* memcpy */
frame_find_guint8, /* find_guint8 */ frame_find_guint8, /* find_guint8 */
frame_pbrk_guint8, /* pbrk_guint8 */ frame_pbrk_guint8, /* pbrk_guint8 */
frame_clone, /* clone */ frame_clone, /* clone */
}; };
/* based on tvb_new_real_data() */ /* based on tvb_new_real_data() */
tvbuff_t * tvbuff_t *
frame_tvbuff_new(const struct packet_provider_data *prov, const frame_data *fd, frame_tvbuff_new(const struct packet_provider_data *prov, const frame_data *fd,
const guint8 *buf) const guint8 *buf)
{ {
struct tvb_frame *frame_tvb; struct tvb_frame *frame_tvb;
tvbuff_t *tvb; tvbuff_t *tvb;
tvb = tvb_new(&tvb_frame_ops); tvb = tvb_new(&tvb_frame_ops);
/* /*
* XXX - currently, the length arguments in * XXX - currently, the length arguments in
* tvbuff structure are signed, but the captured * tvbuff structure are signed, but the captured
* and reported length values are unsigned; this means * and reported length values are unsigned; this means
* that length values > 2^31 - 1 will appear as * that length values > 2^31 - 1 will appear as
* negative lengths * negative lengths
* *
* Captured length values that large will already * Captured length values that large will already
* have been filtered out by the Wiretap modules * have been filtered out by the Wiretap modules
* (the file will be reported as corrupted), to * (the file will be reported as corrupted), to
* avoid trying to allocate large chunks of data. * avoid trying to allocate large chunks of data.
* *
* Reported length values will not have been * Reported length values will not have been
* filtered out, and should not be filtered out, * filtered out, and should not be filtered out,
* as those lengths are not necessarily invalid. * as those lengths are not necessarily invalid.
* *
* For now, we clip the reported length at G_MAXINT * For now, we clip the reported length at G_MAXINT
* *
* (XXX, is this still a problem?) There was an exception when we call * (XXX, is this still a problem?) There was an exception when we call
* tvb_new_real_data() now there's no one * tvb_new_real_data() now there's no one
*/ */
tvb->real_data = buf; tvb->real_data = buf;
tvb->length = fd->cap_len; tvb->length = fd->cap_len;
tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len; tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
tvb->contained_length = tvb->reported_length; tvb->contained_length = tvb->reported_length;
tvb->initialized = TRUE; tvb->initialized = TRUE;
/* /*
* This is the top-level real tvbuff for this data source, * This is the top-level real tvbuff for this data source,
* so its data source tvbuff is itself. * so its data source tvbuff is itself.
*/ */
tvb->ds_tvb = tvb; tvb->ds_tvb = tvb;
frame_tvb = (struct tvb_frame *) tvb; frame_tvb = (struct tvb_frame *) tvb;
/* XXX, wtap_can_seek() */ /* XXX, wtap_can_seek() */
if (prov->wth && prov->wth->random_fh) { if (prov->wth && prov->wth->random_fh) {
frame_tvb->prov = prov; frame_tvb->prov = prov;
frame_tvb->file_off = fd->file_off; frame_tvb->file_off = fd->file_off;
frame_tvb->offset = 0; frame_tvb->offset = 0;
} else } else
frame_tvb->prov = NULL; frame_tvb->prov = NULL;
frame_tvb->buf = NULL; frame_tvb->buf = NULL;
return tvb; return tvb;
} }
tvbuff_t * tvbuff_t *
frame_tvbuff_new_buffer(const struct packet_provider_data *prov, frame_tvbuff_new_buffer(const struct packet_provider_data *prov,
const frame_data *fd, Buffer *buf) const frame_data *fd, Buffer *buf)
{ {
return frame_tvbuff_new(prov, fd, ws_buffer_start_ptr(buf)); return frame_tvbuff_new(prov, fd, ws_buffer_start_ptr(buf));
} }
static tvbuff_t * static tvbuff_t *
frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length) frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length)
{ {
struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb; struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
tvbuff_t *cloned_tvb; tvbuff_t *cloned_tvb;
struct tvb_frame *cloned_frame_tvb; struct tvb_frame *cloned_frame_tvb;
/* file not seekable */ /* file not seekable */
if (!frame_tvb->prov) if (!frame_tvb->prov)
return NULL; return NULL;
abs_offset += frame_tvb->offset; abs_offset += frame_tvb->offset;
cloned_tvb = tvb_new(&tvb_frame_ops); cloned_tvb = tvb_new(&tvb_frame_ops);
/* data will be read when needed */ /* data will be read when needed */
cloned_tvb->real_data = NULL; cloned_tvb->real_data = NULL;
cloned_tvb->length = abs_length; cloned_tvb->length = abs_length;
cloned_tvb->reported_length = abs_length; /* XXX? */ cloned_tvb->reported_length = abs_length; /* XXX? */
cloned_tvb->contained_length = cloned_tvb->reported_length; cloned_tvb->contained_length = cloned_tvb->reported_length;
cloned_tvb->initialized = TRUE; cloned_tvb->initialized = TRUE;
/* /*
* This is the top-level real tvbuff for this data source, * This is the top-level real tvbuff for this data source,
* so its data source tvbuff is itself. * so its data source tvbuff is itself.
*/ */
cloned_tvb->ds_tvb = cloned_tvb; cloned_tvb->ds_tvb = cloned_tvb;
cloned_frame_tvb = (struct tvb_frame *) cloned_tvb; cloned_frame_tvb = (struct tvb_frame *) cloned_tvb;
cloned_frame_tvb->prov = frame_tvb->prov; cloned_frame_tvb->prov = frame_tvb->prov;
cloned_frame_tvb->file_off = frame_tvb->file_off; cloned_frame_tvb->file_off = frame_tvb->file_off;
cloned_frame_tvb->offset = abs_offset; cloned_frame_tvb->offset = abs_offset;
cloned_frame_tvb->buf = NULL; cloned_frame_tvb->buf = NULL;
return cloned_tvb; return cloned_tvb;
} }
/* based on tvb_new_real_data() */ /* based on tvb_new_real_data() */
tvbuff_t * tvbuff_t *
file_tvbuff_new(const struct packet_provider_data *prov, const frame_data *fd, file_tvbuff_new(const struct packet_provider_data *prov, const frame_data *fd,
const guint8 *buf) const guint8 *buf)
{ {
struct tvb_frame *frame_tvb; struct tvb_frame *frame_tvb;
tvbuff_t *tvb; tvbuff_t *tvb;
tvb = tvb_new(&tvb_frame_ops); tvb = tvb_new(&tvb_frame_ops);
/* /*
* XXX - currently, the length arguments in * XXX - currently, the length arguments in
* tvbuff structure are signed, but the captured * tvbuff structure are signed, but the captured
* and reported length values are unsigned; this means * and reported length values are unsigned; this means
* that length values > 2^31 - 1 will appear as * that length values > 2^31 - 1 will appear as
* negative lengths * negative lengths
* *
* Captured length values that large will already * Captured length values that large will already
* have been filtered out by the Wiretap modules * have been filtered out by the Wiretap modules
* (the file will be reported as corrupted), to * (the file will be reported as corrupted), to
* avoid trying to allocate large chunks of data. * avoid trying to allocate large chunks of data.
* *
* Reported length values will not have been * Reported length values will not have been
* filtered out, and should not be filtered out, * filtered out, and should not be filtered out,
* as those lengths are not necessarily invalid. * as those lengths are not necessarily invalid.
* *
* For now, we clip the reported length at G_MAXINT * For now, we clip the reported length at G_MAXINT
* *
* (XXX, is this still a problem?) There was an exception when we call * (XXX, is this still a problem?) There was an exception when we call
* tvb_new_real_data() now there's no one * tvb_new_real_data() now there's no one
*/ */
tvb->real_data = buf; tvb->real_data = buf;
tvb->length = fd->cap_len; tvb->length = fd->cap_len;
tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len; tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
tvb->contained_length = tvb->reported_length; tvb->contained_length = tvb->reported_length;
tvb->initialized = TRUE; tvb->initialized = TRUE;
/* /*
* This is the top-level real tvbuff for this data source, * This is the top-level real tvbuff for this data source,
* so its data source tvbuff is itself. * so its data source tvbuff is itself.
*/ */
tvb->ds_tvb = tvb; tvb->ds_tvb = tvb;
frame_tvb = (struct tvb_frame *) tvb; frame_tvb = (struct tvb_frame *) tvb;
/* XXX, wtap_can_seek() */ /* XXX, wtap_can_seek() */
if (prov->wth && prov->wth->random_fh) { if (prov->wth && prov->wth->random_fh) {
frame_tvb->prov = prov; frame_tvb->prov = prov;
frame_tvb->file_off = fd->file_off; frame_tvb->file_off = fd->file_off;
frame_tvb->offset = 0; frame_tvb->offset = 0;
} else } else
frame_tvb->prov = NULL; frame_tvb->prov = NULL;
frame_tvb->buf = NULL; frame_tvb->buf = NULL;
return tvb; return tvb;
} }
tvbuff_t * tvbuff_t *
file_tvbuff_new_buffer(const struct packet_provider_data *prov, file_tvbuff_new_buffer(const struct packet_provider_data *prov,
const frame_data *fd, Buffer *buf) const frame_data *fd, Buffer *buf)
{ {
return frame_tvbuff_new(prov, fd, ws_buffer_start_ptr(buf)); return frame_tvbuff_new(prov, fd, ws_buffer_start_ptr(buf));
} }
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* 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:
*/

View File

@ -37,16 +37,3 @@ extern tvbuff_t *file_tvbuff_new_buffer(const struct packet_provider_data *prov,
#endif /* __cplusplus */ #endif /* __cplusplus */
#endif /* __FRAME_TVBUFF_H__ */ #endif /* __FRAME_TVBUFF_H__ */
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* 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:
*/

View File

@ -52,23 +52,23 @@
static void static void
print_usage(FILE *output) print_usage(FILE *output)
{ {
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Usage: mergecap [options] -w <outfile>|- <infile> [<infile> ...]\n"); fprintf(output, "Usage: mergecap [options] -w <outfile>|- <infile> [<infile> ...]\n");
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Output:\n"); fprintf(output, "Output:\n");
fprintf(output, " -a concatenate rather than merge files.\n"); fprintf(output, " -a concatenate rather than merge files.\n");
fprintf(output, " default is to merge based on frame timestamps.\n"); fprintf(output, " default is to merge based on frame timestamps.\n");
fprintf(output, " -s <snaplen> truncate packets to <snaplen> bytes of data.\n"); fprintf(output, " -s <snaplen> truncate packets to <snaplen> bytes of data.\n");
fprintf(output, " -w <outfile>|- set the output filename to <outfile> or '-' for stdout.\n"); fprintf(output, " -w <outfile>|- set the output filename to <outfile> or '-' for stdout.\n");
fprintf(output, " -F <capture type> set the output file type; default is pcapng.\n"); fprintf(output, " -F <capture type> set the output file type; default is pcapng.\n");
fprintf(output, " an empty \"-F\" option will list the file types.\n"); fprintf(output, " an empty \"-F\" option will list the file types.\n");
fprintf(output, " -I <IDB merge mode> set the merge mode for Interface Description Blocks; default is 'all'.\n"); fprintf(output, " -I <IDB merge mode> set the merge mode for Interface Description Blocks; default is 'all'.\n");
fprintf(output, " an empty \"-I\" option will list the merge modes.\n"); fprintf(output, " an empty \"-I\" option will list the merge modes.\n");
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Miscellaneous:\n"); fprintf(output, "Miscellaneous:\n");
fprintf(output, " -h display this help and exit.\n"); fprintf(output, " -h display this help and exit.\n");
fprintf(output, " -v verbose output.\n"); fprintf(output, " -v verbose output.\n");
fprintf(output, " -V print version information and exit.\n"); fprintf(output, " -V print version information and exit.\n");
} }
/* /*
@ -77,9 +77,9 @@ print_usage(FILE *output)
static void static void
mergecap_cmdarg_err(const char *fmt, va_list ap) mergecap_cmdarg_err(const char *fmt, va_list ap)
{ {
fprintf(stderr, "mergecap: "); fprintf(stderr, "mergecap: ");
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
/* /*
@ -88,352 +88,339 @@ mergecap_cmdarg_err(const char *fmt, va_list ap)
static void static void
mergecap_cmdarg_err_cont(const char *fmt, va_list ap) mergecap_cmdarg_err_cont(const char *fmt, va_list ap)
{ {
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
static void static void
list_capture_types(void) { list_capture_types(void) {
GArray *writable_type_subtypes; GArray *writable_type_subtypes;
fprintf(stderr, "mergecap: The available capture file types for the \"-F\" flag are:\n"); fprintf(stderr, "mergecap: The available capture file types for the \"-F\" flag are:\n");
writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME); writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
for (guint i = 0; i < writable_type_subtypes->len; i++) { for (guint i = 0; i < writable_type_subtypes->len; i++) {
int ft = g_array_index(writable_type_subtypes, int, i); int ft = g_array_index(writable_type_subtypes, int, i);
fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft), fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
wtap_file_type_subtype_description(ft)); wtap_file_type_subtype_description(ft));
} }
g_array_free(writable_type_subtypes, TRUE); g_array_free(writable_type_subtypes, TRUE);
} }
static void static void
list_idb_merge_modes(void) { list_idb_merge_modes(void) {
int i; int i;
fprintf(stderr, "mergecap: The available IDB merge modes for the \"-I\" flag are:\n"); fprintf(stderr, "mergecap: The available IDB merge modes for the \"-I\" flag are:\n");
for (i = 0; i < IDB_MERGE_MODE_MAX; i++) { for (i = 0; i < IDB_MERGE_MODE_MAX; i++) {
fprintf(stderr, " %s\n", merge_idb_merge_mode_to_string(i)); fprintf(stderr, " %s\n", merge_idb_merge_mode_to_string(i));
} }
} }
static gboolean static gboolean
merge_callback(merge_event event, int num, merge_callback(merge_event event, int num,
const merge_in_file_t in_files[], const guint in_file_count, const merge_in_file_t in_files[], const guint in_file_count,
void *data _U_) void *data _U_)
{ {
guint i; guint i;
switch (event) { switch (event) {
case MERGE_EVENT_INPUT_FILES_OPENED: case MERGE_EVENT_INPUT_FILES_OPENED:
for (i = 0; i < in_file_count; i++) { for (i = 0; i < in_file_count; i++) {
fprintf(stderr, "mergecap: %s is type %s.\n", in_files[i].filename, fprintf(stderr, "mergecap: %s is type %s.\n", in_files[i].filename,
wtap_file_type_subtype_description(wtap_file_type_subtype(in_files[i].wth))); wtap_file_type_subtype_description(wtap_file_type_subtype(in_files[i].wth)));
} }
break;
case MERGE_EVENT_FRAME_TYPE_SELECTED:
/* for this event, num = frame_type */
if (num == WTAP_ENCAP_PER_PACKET) {
/*
* Find out why we had to choose WTAP_ENCAP_PER_PACKET.
*/
int first_frame_type, this_frame_type;
first_frame_type = wtap_file_encap(in_files[0].wth);
for (i = 1; i < in_file_count; i++) {
this_frame_type = wtap_file_encap(in_files[i].wth);
if (first_frame_type != this_frame_type) {
fprintf(stderr, "mergecap: multiple frame encapsulation types detected\n");
fprintf(stderr, " defaulting to WTAP_ENCAP_PER_PACKET\n");
fprintf(stderr, " %s had type %s (%s)\n",
in_files[0].filename,
wtap_encap_description(first_frame_type),
wtap_encap_name(first_frame_type));
fprintf(stderr, " %s had type %s (%s)\n",
in_files[i].filename,
wtap_encap_description(this_frame_type),
wtap_encap_name(this_frame_type));
break; break;
}
}
}
fprintf(stderr, "mergecap: selected frame_type %s (%s)\n",
wtap_encap_description(num),
wtap_encap_name(num));
break;
case MERGE_EVENT_READY_TO_MERGE: case MERGE_EVENT_FRAME_TYPE_SELECTED:
fprintf(stderr, "mergecap: ready to merge records\n"); /* for this event, num = frame_type */
break; if (num == WTAP_ENCAP_PER_PACKET) {
/*
* Find out why we had to choose WTAP_ENCAP_PER_PACKET.
*/
int first_frame_type, this_frame_type;
case MERGE_EVENT_RECORD_WAS_READ: first_frame_type = wtap_file_encap(in_files[0].wth);
/* for this event, num = count */ for (i = 1; i < in_file_count; i++) {
fprintf(stderr, "Record: %d\n", num); this_frame_type = wtap_file_encap(in_files[i].wth);
break; if (first_frame_type != this_frame_type) {
fprintf(stderr, "mergecap: multiple frame encapsulation types detected\n");
fprintf(stderr, " defaulting to WTAP_ENCAP_PER_PACKET\n");
fprintf(stderr, " %s had type %s (%s)\n",
in_files[0].filename,
wtap_encap_description(first_frame_type),
wtap_encap_name(first_frame_type));
fprintf(stderr, " %s had type %s (%s)\n",
in_files[i].filename,
wtap_encap_description(this_frame_type),
wtap_encap_name(this_frame_type));
break;
}
}
}
fprintf(stderr, "mergecap: selected frame_type %s (%s)\n",
wtap_encap_description(num),
wtap_encap_name(num));
break;
case MERGE_EVENT_DONE: case MERGE_EVENT_READY_TO_MERGE:
fprintf(stderr, "mergecap: merging complete\n"); fprintf(stderr, "mergecap: ready to merge records\n");
break; break;
}
/* false = do not stop merging */ case MERGE_EVENT_RECORD_WAS_READ:
return FALSE; /* for this event, num = count */
fprintf(stderr, "Record: %d\n", num);
break;
case MERGE_EVENT_DONE:
fprintf(stderr, "mergecap: merging complete\n");
break;
}
/* false = do not stop merging */
return FALSE;
} }
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *init_progfile_dir_error; char *init_progfile_dir_error;
static const struct report_message_routines mergecap_report_routines = { static const struct report_message_routines mergecap_report_routines = {
failure_message, failure_message,
failure_message, failure_message,
open_failure_message, open_failure_message,
read_failure_message, read_failure_message,
write_failure_message, write_failure_message,
cfile_open_failure_message, cfile_open_failure_message,
cfile_dump_open_failure_message, cfile_dump_open_failure_message,
cfile_read_failure_message, cfile_read_failure_message,
cfile_write_failure_message, cfile_write_failure_message,
cfile_close_failure_message cfile_close_failure_message
}; };
int opt; int opt;
static const struct ws_option long_options[] = { static const struct ws_option long_options[] = {
{"help", ws_no_argument, NULL, 'h'}, {"help", ws_no_argument, NULL, 'h'},
{"version", ws_no_argument, NULL, 'V'}, {"version", ws_no_argument, NULL, 'V'},
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
gboolean do_append = FALSE; gboolean do_append = FALSE;
gboolean verbose = FALSE; gboolean verbose = FALSE;
int in_file_count = 0; int in_file_count = 0;
guint32 snaplen = 0; guint32 snaplen = 0;
int file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN; int file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
int err = 0; int err = 0;
gchar *err_info = NULL; gchar *err_info = NULL;
int err_fileno; int err_fileno;
guint32 err_framenum; guint32 err_framenum;
char *out_filename = NULL; char *out_filename = NULL;
merge_result status = MERGE_OK; merge_result status = MERGE_OK;
idb_merge_mode mode = IDB_MERGE_MODE_MAX; idb_merge_mode mode = IDB_MERGE_MODE_MAX;
merge_progress_callback_t cb; merge_progress_callback_t cb;
cmdarg_err_init(mergecap_cmdarg_err, mergecap_cmdarg_err_cont); cmdarg_err_init(mergecap_cmdarg_err, mergecap_cmdarg_err_cont);
/* Initialize log handler early so we can have proper logging during startup. */ /* Initialize log handler early so we can have proper logging during startup. */
ws_log_init("mergecap", vcmdarg_err); ws_log_init("mergecap", vcmdarg_err);
/* Early logging command-line initialization. */ /* Early logging command-line initialization. */
ws_log_parse_args(&argc, argv, vcmdarg_err, 1); ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
#ifdef _WIN32 #ifdef _WIN32
create_app_running_mutex(); create_app_running_mutex();
#endif /* _WIN32 */ #endif /* _WIN32 */
/* Initialize the version information. */ /* Initialize the version information. */
ws_init_version_info("Mergecap (Wireshark)", NULL, NULL, NULL); ws_init_version_info("Mergecap (Wireshark)", NULL, NULL, NULL);
/* /*
* Get credential information for later use. * Get credential information for later use.
*/ */
init_process_policies(); init_process_policies();
/* /*
* Attempt to get the pathname of the directory containing the * Attempt to get the pathname of the directory containing the
* executable file. * executable file.
*/ */
init_progfile_dir_error = init_progfile_dir(argv[0]); init_progfile_dir_error = init_progfile_dir(argv[0]);
if (init_progfile_dir_error != NULL) { if (init_progfile_dir_error != NULL) {
fprintf(stderr, fprintf(stderr,
"mergecap: Can't get pathname of directory containing the mergecap program: %s.\n", "mergecap: Can't get pathname of directory containing the mergecap program: %s.\n",
init_progfile_dir_error); init_progfile_dir_error);
g_free(init_progfile_dir_error); g_free(init_progfile_dir_error);
}
init_report_message("mergecap", &mergecap_report_routines);
wtap_init(TRUE);
/* Process the options first */
while ((opt = ws_getopt_long(argc, argv, "aF:hI:s:vVw:", long_options, NULL)) != -1) {
switch (opt) {
case 'a':
do_append = !do_append;
break;
case 'F':
file_type = wtap_name_to_file_type_subtype(ws_optarg);
if (file_type < 0) {
fprintf(stderr, "mergecap: \"%s\" isn't a valid capture file type\n",
ws_optarg);
list_capture_types();
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
}
break;
case 'h':
show_help_header("Merge two or more capture files into one.");
print_usage(stdout);
goto clean_exit;
break;
case 'I':
mode = merge_string_to_idb_merge_mode(ws_optarg);
if (mode == IDB_MERGE_MODE_MAX) {
fprintf(stderr, "mergecap: \"%s\" isn't a valid IDB merge mode\n",
ws_optarg);
list_idb_merge_modes();
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
}
break;
case 's':
snaplen = get_nonzero_guint32(ws_optarg, "snapshot length");
break;
case 'v':
verbose = TRUE;
break;
case 'V':
show_version();
goto clean_exit;
break;
case 'w':
out_filename = ws_optarg;
break;
case '?': /* Bad options if GNU getopt */
switch(ws_optopt) {
case'F':
list_capture_types();
break;
case'I':
list_idb_merge_modes();
break;
default:
print_usage(stderr);
}
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
break;
} }
}
/* Default to pcapng when writing. */ init_report_message("mergecap", &mergecap_report_routines);
if (file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
file_type = wtap_pcapng_file_type_subtype();
cb.callback_func = merge_callback; wtap_init(TRUE);
cb.data = NULL;
/* check for proper args; at a minimum, must have an output /* Process the options first */
* filename and one input file while ((opt = ws_getopt_long(argc, argv, "aF:hI:s:vVw:", long_options, NULL)) != -1) {
*/
in_file_count = argc - ws_optind;
if (!out_filename) {
fprintf(stderr, "mergecap: an output filename must be set with -w\n");
fprintf(stderr, " run with -h for help\n");
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
}
if (in_file_count < 1) {
fprintf(stderr, "mergecap: No input files were specified\n");
return 1;
}
/* switch (opt) {
* Setting IDB merge mode must use a file format that supports case 'a':
* (and thus requires) interface ID and information blocks. do_append = !do_append;
*/ break;
if (mode != IDB_MERGE_MODE_MAX &&
wtap_file_type_subtype_supports_block(file_type, WTAP_BLOCK_IF_ID_AND_INFO) == BLOCK_NOT_SUPPORTED) {
fprintf(stderr, "The IDB merge mode can only be used with an output format that identifies interfaces\n");
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
}
/* if they didn't set IDB merge mode, set it to our default */ case 'F':
if (mode == IDB_MERGE_MODE_MAX) { file_type = wtap_name_to_file_type_subtype(ws_optarg);
mode = IDB_MERGE_MODE_ALL_SAME; if (file_type < 0) {
} fprintf(stderr, "mergecap: \"%s\" isn't a valid capture file type\n",
ws_optarg);
list_capture_types();
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
}
break;
/* open the outfile */ case 'h':
if (strcmp(out_filename, "-") == 0) { show_help_header("Merge two or more capture files into one.");
/* merge the files to the standard output */ print_usage(stdout);
status = merge_files_to_stdout(file_type, goto clean_exit;
(const char *const *) &argv[ws_optind], break;
in_file_count, do_append, mode, snaplen,
get_appname_and_version(),
verbose ? &cb : NULL,
&err, &err_info, &err_fileno, &err_framenum);
} else {
/* merge the files to the outfile */
status = merge_files(out_filename, file_type,
(const char *const *) &argv[ws_optind], in_file_count,
do_append, mode, snaplen, get_appname_and_version(),
verbose ? &cb : NULL,
&err, &err_info, &err_fileno, &err_framenum);
}
switch (status) { case 'I':
case MERGE_OK: mode = merge_string_to_idb_merge_mode(ws_optarg);
break; if (mode == IDB_MERGE_MODE_MAX) {
fprintf(stderr, "mergecap: \"%s\" isn't a valid IDB merge mode\n",
ws_optarg);
list_idb_merge_modes();
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
}
break;
case MERGE_USER_ABORTED: case 's':
/* we don't catch SIGINT/SIGTERM (yet?), so we couldn't have aborted */ snaplen = get_nonzero_guint32(ws_optarg, "snapshot length");
ws_assert_not_reached(); break;
break;
case MERGE_ERR_CANT_OPEN_INFILE: case 'v':
cfile_open_failure_message(argv[ws_optind + err_fileno], err, err_info); verbose = TRUE;
break; break;
case MERGE_ERR_CANT_OPEN_OUTFILE: case 'V':
cfile_dump_open_failure_message(out_filename, err, err_info, file_type); show_version();
break; goto clean_exit;
break;
case MERGE_ERR_CANT_READ_INFILE: case 'w':
cfile_read_failure_message(argv[ws_optind + err_fileno], err, err_info); out_filename = ws_optarg;
break; break;
case MERGE_ERR_BAD_PHDR_INTERFACE_ID: case '?': /* Bad options if GNU getopt */
cmdarg_err("Record %u of \"%s\" has an interface ID that does not match any IDB in its file.", switch(ws_optopt) {
err_framenum, argv[ws_optind + err_fileno]); case'F':
break; list_capture_types();
break;
case'I':
list_idb_merge_modes();
break;
default:
print_usage(stderr);
}
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
break;
}
}
case MERGE_ERR_CANT_WRITE_OUTFILE: /* Default to pcapng when writing. */
cfile_write_failure_message(argv[ws_optind + err_fileno], out_filename, if (file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
err, err_info, err_framenum, file_type); file_type = wtap_pcapng_file_type_subtype();
break;
case MERGE_ERR_CANT_CLOSE_OUTFILE: cb.callback_func = merge_callback;
cfile_close_failure_message(out_filename, err, err_info); cb.data = NULL;
break;
default: /* check for proper args; at a minimum, must have an output
cmdarg_err("Unknown merge_files error %d", status); * filename and one input file
break; */
} in_file_count = argc - ws_optind;
if (!out_filename) {
fprintf(stderr, "mergecap: an output filename must be set with -w\n");
fprintf(stderr, " run with -h for help\n");
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
}
if (in_file_count < 1) {
fprintf(stderr, "mergecap: No input files were specified\n");
return 1;
}
/*
* Setting IDB merge mode must use a file format that supports
* (and thus requires) interface ID and information blocks.
*/
if (mode != IDB_MERGE_MODE_MAX &&
wtap_file_type_subtype_supports_block(file_type, WTAP_BLOCK_IF_ID_AND_INFO) == BLOCK_NOT_SUPPORTED) {
fprintf(stderr, "The IDB merge mode can only be used with an output format that identifies interfaces\n");
status = MERGE_ERR_INVALID_OPTION;
goto clean_exit;
}
/* if they didn't set IDB merge mode, set it to our default */
if (mode == IDB_MERGE_MODE_MAX) {
mode = IDB_MERGE_MODE_ALL_SAME;
}
/* open the outfile */
if (strcmp(out_filename, "-") == 0) {
/* merge the files to the standard output */
status = merge_files_to_stdout(file_type,
(const char *const *) &argv[ws_optind],
in_file_count, do_append, mode, snaplen,
get_appname_and_version(),
verbose ? &cb : NULL,
&err, &err_info, &err_fileno, &err_framenum);
} else {
/* merge the files to the outfile */
status = merge_files(out_filename, file_type,
(const char *const *) &argv[ws_optind], in_file_count,
do_append, mode, snaplen, get_appname_and_version(),
verbose ? &cb : NULL,
&err, &err_info, &err_fileno, &err_framenum);
}
switch (status) {
case MERGE_OK:
break;
case MERGE_USER_ABORTED:
/* we don't catch SIGINT/SIGTERM (yet?), so we couldn't have aborted */
ws_assert_not_reached();
break;
case MERGE_ERR_CANT_OPEN_INFILE:
cfile_open_failure_message(argv[ws_optind + err_fileno], err, err_info);
break;
case MERGE_ERR_CANT_OPEN_OUTFILE:
cfile_dump_open_failure_message(out_filename, err, err_info, file_type);
break;
case MERGE_ERR_CANT_READ_INFILE:
cfile_read_failure_message(argv[ws_optind + err_fileno], err, err_info);
break;
case MERGE_ERR_BAD_PHDR_INTERFACE_ID:
cmdarg_err("Record %u of \"%s\" has an interface ID that does not match any IDB in its file.",
err_framenum, argv[ws_optind + err_fileno]);
break;
case MERGE_ERR_CANT_WRITE_OUTFILE:
cfile_write_failure_message(argv[ws_optind + err_fileno], out_filename,
err, err_info, err_framenum, file_type);
break;
case MERGE_ERR_CANT_CLOSE_OUTFILE:
cfile_close_failure_message(out_filename, err, err_info);
break;
default:
cmdarg_err("Unknown merge_files error %d", status);
break;
}
clean_exit: clean_exit:
wtap_cleanup(); wtap_cleanup();
free_progdirs(); free_progdirs();
return (status == MERGE_OK) ? 0 : 2; return (status == MERGE_OK) ? 0 : 2;
} }
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

339
randpkt.c
View File

@ -45,9 +45,9 @@
static void static void
randpkt_cmdarg_err(const char *msg_format, va_list ap) randpkt_cmdarg_err(const char *msg_format, va_list ap)
{ {
fprintf(stderr, "randpkt: "); fprintf(stderr, "randpkt: ");
vfprintf(stderr, msg_format, ap); vfprintf(stderr, msg_format, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
/* /*
@ -56,219 +56,206 @@ randpkt_cmdarg_err(const char *msg_format, va_list ap)
static void static void
randpkt_cmdarg_err_cont(const char *msg_format, va_list ap) randpkt_cmdarg_err_cont(const char *msg_format, va_list ap)
{ {
vfprintf(stderr, msg_format, ap); vfprintf(stderr, msg_format, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
/* Print usage statement and exit program */ /* Print usage statement and exit program */
static void static void
usage(gboolean is_error) usage(gboolean is_error)
{ {
FILE *output; FILE *output;
char** abbrev_list; char** abbrev_list;
char** longname_list; char** longname_list;
unsigned i = 0; unsigned i = 0;
if (!is_error) { if (!is_error) {
output = stdout; output = stdout;
} }
else { else {
output = stderr; output = stderr;
} }
fprintf(output, "Usage: randpkt [-b maxbytes] [-c count] [-t type] [-r] filename\n"); fprintf(output, "Usage: randpkt [-b maxbytes] [-c count] [-t type] [-r] filename\n");
fprintf(output, "Default max bytes (per packet) is 5000\n"); fprintf(output, "Default max bytes (per packet) is 5000\n");
fprintf(output, "Default count is 1000.\n"); fprintf(output, "Default count is 1000.\n");
fprintf(output, "-r: random packet type selection\n"); fprintf(output, "-r: random packet type selection\n");
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Types:\n"); fprintf(output, "Types:\n");
/* Get the examples list */ /* Get the examples list */
randpkt_example_list(&abbrev_list, &longname_list); randpkt_example_list(&abbrev_list, &longname_list);
while (abbrev_list[i] && longname_list[i]) { while (abbrev_list[i] && longname_list[i]) {
fprintf(output, "\t%-16s%s\n", abbrev_list[i], longname_list[i]); fprintf(output, "\t%-16s%s\n", abbrev_list[i], longname_list[i]);
i++; i++;
} }
g_strfreev(abbrev_list); g_strfreev(abbrev_list);
g_strfreev(longname_list); g_strfreev(longname_list);
fprintf(output, "\nIf type is not specified, a random packet will be chosen\n\n"); fprintf(output, "\nIf type is not specified, a random packet will be chosen\n\n");
} }
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *init_progfile_dir_error; char *init_progfile_dir_error;
static const struct report_message_routines randpkt_report_routines = { static const struct report_message_routines randpkt_report_routines = {
failure_message, failure_message,
failure_message, failure_message,
open_failure_message, open_failure_message,
read_failure_message, read_failure_message,
write_failure_message, write_failure_message,
cfile_open_failure_message, cfile_open_failure_message,
cfile_dump_open_failure_message, cfile_dump_open_failure_message,
cfile_read_failure_message, cfile_read_failure_message,
cfile_write_failure_message, cfile_write_failure_message,
cfile_close_failure_message cfile_close_failure_message
}; };
int opt; int opt;
int produce_type = -1; int produce_type = -1;
char *produce_filename = NULL; char *produce_filename = NULL;
int produce_max_bytes = 5000; int produce_max_bytes = 5000;
int produce_count = 1000; int produce_count = 1000;
randpkt_example *example; randpkt_example *example;
guint8* type = NULL; guint8* type = NULL;
int allrandom = FALSE; int allrandom = FALSE;
wtap_dumper *savedump; wtap_dumper *savedump;
int ret = EXIT_SUCCESS; int ret = EXIT_SUCCESS;
static const struct ws_option long_options[] = { static const struct ws_option long_options[] = {
{"help", ws_no_argument, NULL, 'h'}, {"help", ws_no_argument, NULL, 'h'},
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
cmdarg_err_init(randpkt_cmdarg_err, randpkt_cmdarg_err_cont); cmdarg_err_init(randpkt_cmdarg_err, randpkt_cmdarg_err_cont);
/* Initialize log handler early so we can have proper logging during startup. */ /* Initialize log handler early so we can have proper logging during startup. */
ws_log_init("randpkt", vcmdarg_err); ws_log_init("randpkt", vcmdarg_err);
/* Early logging command-line initialization. */ /* Early logging command-line initialization. */
ws_log_parse_args(&argc, argv, vcmdarg_err, INVALID_OPTION); ws_log_parse_args(&argc, argv, vcmdarg_err, INVALID_OPTION);
/* /*
* Get credential information for later use. * Get credential information for later use.
*/ */
init_process_policies(); init_process_policies();
/* /*
* Attempt to get the pathname of the directory containing the * Attempt to get the pathname of the directory containing the
* executable file. * executable file.
*/ */
init_progfile_dir_error = init_progfile_dir(argv[0]); init_progfile_dir_error = init_progfile_dir(argv[0]);
if (init_progfile_dir_error != NULL) { if (init_progfile_dir_error != NULL) {
fprintf(stderr, fprintf(stderr,
"capinfos: Can't get pathname of directory containing the capinfos program: %s.\n", "capinfos: Can't get pathname of directory containing the capinfos program: %s.\n",
init_progfile_dir_error); init_progfile_dir_error);
g_free(init_progfile_dir_error); g_free(init_progfile_dir_error);
} }
init_report_message("randpkt", &randpkt_report_routines); init_report_message("randpkt", &randpkt_report_routines);
wtap_init(TRUE); wtap_init(TRUE);
#ifdef _WIN32 #ifdef _WIN32
create_app_running_mutex(); create_app_running_mutex();
#endif /* _WIN32 */ #endif /* _WIN32 */
while ((opt = ws_getopt_long(argc, argv, "b:c:ht:r", long_options, NULL)) != -1) { while ((opt = ws_getopt_long(argc, argv, "b:c:ht:r", long_options, NULL)) != -1) {
switch (opt) { switch (opt) {
case 'b': /* max bytes */ case 'b': /* max bytes */
produce_max_bytes = get_positive_int(ws_optarg, "max bytes"); produce_max_bytes = get_positive_int(ws_optarg, "max bytes");
if (produce_max_bytes > 65536) { if (produce_max_bytes > 65536) {
cmdarg_err("max bytes is > 65536"); cmdarg_err("max bytes is > 65536");
ret = INVALID_OPTION; ret = INVALID_OPTION;
goto clean_exit; goto clean_exit;
} }
break; break;
case 'c': /* count */ case 'c': /* count */
produce_count = get_positive_int(ws_optarg, "count"); produce_count = get_positive_int(ws_optarg, "count");
break; break;
case 't': /* type of packet to produce */ case 't': /* type of packet to produce */
type = g_strdup(ws_optarg); type = g_strdup(ws_optarg);
break; break;
case 'h': case 'h':
usage(FALSE); usage(FALSE);
goto clean_exit; goto clean_exit;
break; break;
case 'r': case 'r':
allrandom = TRUE; allrandom = TRUE;
break; break;
default: default:
usage(TRUE); usage(TRUE);
ret = INVALID_OPTION; ret = INVALID_OPTION;
goto clean_exit; goto clean_exit;
break; break;
} }
} }
/* any more command line parameters? */ /* any more command line parameters? */
if (argc > ws_optind) { if (argc > ws_optind) {
produce_filename = argv[ws_optind]; produce_filename = argv[ws_optind];
} else { } else {
usage(TRUE); usage(TRUE);
ret = INVALID_OPTION; ret = INVALID_OPTION;
goto clean_exit; goto clean_exit;
} }
if (!allrandom) { if (!allrandom) {
produce_type = randpkt_parse_type(type); produce_type = randpkt_parse_type(type);
g_free(type); g_free(type);
example = randpkt_find_example(produce_type); example = randpkt_find_example(produce_type);
if (!example) { if (!example) {
ret = INVALID_OPTION; ret = INVALID_OPTION;
goto clean_exit; goto clean_exit;
} }
ret = randpkt_example_init(example, produce_filename, produce_max_bytes); ret = randpkt_example_init(example, produce_filename, produce_max_bytes);
if (ret != EXIT_SUCCESS) if (ret != EXIT_SUCCESS)
goto clean_exit; goto clean_exit;
randpkt_loop(example, produce_count, 0); randpkt_loop(example, produce_count, 0);
} else { } else {
if (type) { if (type) {
fprintf(stderr, "Can't set type in random mode\n"); fprintf(stderr, "Can't set type in random mode\n");
ret = INVALID_TYPE; ret = INVALID_TYPE;
goto clean_exit; goto clean_exit;
} }
produce_type = randpkt_parse_type(NULL); produce_type = randpkt_parse_type(NULL);
example = randpkt_find_example(produce_type); example = randpkt_find_example(produce_type);
if (!example) { if (!example) {
ret = INVALID_OPTION; ret = INVALID_OPTION;
goto clean_exit; goto clean_exit;
} }
ret = randpkt_example_init(example, produce_filename, produce_max_bytes); ret = randpkt_example_init(example, produce_filename, produce_max_bytes);
if (ret != EXIT_SUCCESS) if (ret != EXIT_SUCCESS)
goto clean_exit; goto clean_exit;
while (produce_count-- > 0) { while (produce_count-- > 0) {
randpkt_loop(example, 1, 0); randpkt_loop(example, 1, 0);
produce_type = randpkt_parse_type(NULL); produce_type = randpkt_parse_type(NULL);
savedump = example->dump; savedump = example->dump;
example = randpkt_find_example(produce_type); example = randpkt_find_example(produce_type);
if (!example) { if (!example) {
ret = INVALID_OPTION; ret = INVALID_OPTION;
goto clean_exit; goto clean_exit;
} }
example->dump = savedump; example->dump = savedump;
example->filename = produce_filename; example->filename = produce_filename;
} }
} }
if (!randpkt_example_close(example)) { if (!randpkt_example_close(example)) {
ret = CLOSE_ERROR; ret = CLOSE_ERROR;
} }
clean_exit: clean_exit:
wtap_cleanup(); wtap_cleanup();
return ret; return ret;
} }
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* 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:
*/

View File

@ -60,30 +60,30 @@
/* Ringbuffer file structure */ /* Ringbuffer file structure */
typedef struct _rb_file { typedef struct _rb_file {
gchar *name; gchar *name;
} rb_file; } rb_file;
#define MAX_FILENAME_QUEUE 100 #define MAX_FILENAME_QUEUE 100
/** Ringbuffer data structure */ /** Ringbuffer data structure */
typedef struct _ringbuf_data { typedef struct _ringbuf_data {
rb_file *files; rb_file *files;
guint num_files; /**< Number of ringbuffer files (1 to ...) */ guint num_files; /**< Number of ringbuffer files (1 to ...) */
guint curr_file_num; /**< Number of the current file (ever increasing) */ guint curr_file_num; /**< Number of the current file (ever increasing) */
gchar *fprefix; /**< Filename prefix */ gchar *fprefix; /**< Filename prefix */
gchar *fsuffix; /**< Filename suffix */ gchar *fsuffix; /**< Filename suffix */
gboolean nametimenum; /**< ...num_time... or ...time_num... */ gboolean nametimenum; /**< ...num_time... or ...time_num... */
gboolean unlimited; /**< TRUE if unlimited number of files */ gboolean unlimited; /**< TRUE if unlimited number of files */
int fd; /**< Current ringbuffer file descriptor */ int fd; /**< Current ringbuffer file descriptor */
FILE *pdh; FILE *pdh;
char *io_buffer; /**< The IO buffer used to write to the file */ char *io_buffer; /**< The IO buffer used to write to the file */
gboolean group_read_access; /**< TRUE if files need to be opened with group read access */ gboolean group_read_access; /**< TRUE if files need to be opened with group read access */
FILE *name_h; /**< write names of completed files to this handle */ FILE *name_h; /**< write names of completed files to this handle */
gchar *compress_type; /**< compress type */ gchar *compress_type; /**< compress type */
GMutex mutex; /**< mutex for oldnames */ GMutex mutex; /**< mutex for oldnames */
gchar *oldnames[MAX_FILENAME_QUEUE]; /**< filename list of pending to be deleted */ gchar *oldnames[MAX_FILENAME_QUEUE]; /**< filename list of pending to be deleted */
} ringbuf_data; } ringbuf_data;
static ringbuf_data rb_data; static ringbuf_data rb_data;
@ -91,172 +91,177 @@ static ringbuf_data rb_data;
/* /*
* delete pending uncompressed pcap files. * delete pending uncompressed pcap files.
*/ */
static void CleanupOldCap(gchar* name) static void
CleanupOldCap(gchar* name)
{ {
ws_statb64 statb; ws_statb64 statb;
size_t i; size_t i;
g_mutex_lock(&rb_data.mutex); g_mutex_lock(&rb_data.mutex);
/* Delete pending delete file */ /* Delete pending delete file */
for (i = 0; i < sizeof(rb_data.oldnames) / sizeof(rb_data.oldnames[0]); i++) { for (i = 0; i < sizeof(rb_data.oldnames) / sizeof(rb_data.oldnames[0]); i++) {
if (rb_data.oldnames[i] != NULL) { if (rb_data.oldnames[i] != NULL) {
ws_unlink(rb_data.oldnames[i]); ws_unlink(rb_data.oldnames[i]);
if (ws_stat64(rb_data.oldnames[i], &statb) != 0) { if (ws_stat64(rb_data.oldnames[i], &statb) != 0) {
g_free(rb_data.oldnames[i]); g_free(rb_data.oldnames[i]);
rb_data.oldnames[i] = NULL; rb_data.oldnames[i] = NULL;
} }
}
}
if (name) {
/* push the current file to pending list if it failed to delete */
if (ws_stat64(name, &statb) == 0) {
for (i = 0; i < sizeof(rb_data.oldnames) / sizeof(rb_data.oldnames[0]); i++) {
if (rb_data.oldnames[i] == NULL) {
rb_data.oldnames[i] = g_strdup(name);
break;
} }
}
} }
}
g_mutex_unlock(&rb_data.mutex); if (name) {
/* push the current file to pending list if it failed to delete */
if (ws_stat64(name, &statb) == 0) {
for (i = 0; i < sizeof(rb_data.oldnames) / sizeof(rb_data.oldnames[0]); i++) {
if (rb_data.oldnames[i] == NULL) {
rb_data.oldnames[i] = g_strdup(name);
break;
}
}
}
}
g_mutex_unlock(&rb_data.mutex);
} }
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
/* /*
* compress capture file * compress capture file
*/ */
static int ringbuf_exec_compress(gchar* name) static int
ringbuf_exec_compress(gchar* name)
{ {
guint8 *buffer = NULL; guint8 *buffer = NULL;
gchar* outgz = NULL; gchar* outgz = NULL;
int fd = -1; int fd = -1;
ssize_t nread; ssize_t nread;
gboolean delete_org_file = TRUE; gboolean delete_org_file = TRUE;
gzFile fi = NULL; gzFile fi = NULL;
fd = ws_open(name, O_RDONLY | O_BINARY, 0000); fd = ws_open(name, O_RDONLY | O_BINARY, 0000);
if (fd < 0) { if (fd < 0) {
return -1; return -1;
} }
outgz = ws_strdup_printf("%s.gz", name); outgz = ws_strdup_printf("%s.gz", name);
fi = gzopen(outgz, "wb"); fi = gzopen(outgz, "wb");
g_free(outgz); g_free(outgz);
if (fi == NULL) { if (fi == NULL) {
ws_close(fd); ws_close(fd);
return -1; return -1;
} }
#define FS_READ_SIZE 65536 #define FS_READ_SIZE 65536
buffer = (guint8*)g_malloc(FS_READ_SIZE); buffer = (guint8*)g_malloc(FS_READ_SIZE);
if (buffer == NULL) { if (buffer == NULL) {
ws_close(fd);
gzclose(fi);
return -1;
}
while ((nread = ws_read(fd, buffer, FS_READ_SIZE)) > 0) {
int n = gzwrite(fi, buffer, (unsigned int)nread);
if (n <= 0) {
/* mark compression as failed */
delete_org_file = FALSE;
break;
}
}
if (nread < 0) {
/* mark compression as failed */
delete_org_file = FALSE;
}
ws_close(fd); ws_close(fd);
gzclose(fi); gzclose(fi);
return -1; g_free(buffer);
}
while ((nread = ws_read(fd, buffer, FS_READ_SIZE)) > 0) { /* delete the original file only if compression succeeds */
int n = gzwrite(fi, buffer, (unsigned int)nread); if (delete_org_file) {
if (n <= 0) { ws_unlink(name);
/* mark compression as failed */ CleanupOldCap(name);
delete_org_file = FALSE;
break;
} }
} g_free(name);
if (nread < 0) { return 0;
/* mark compression as failed */
delete_org_file = FALSE;
}
ws_close(fd);
gzclose(fi);
g_free(buffer);
/* delete the original file only if compression succeeds */
if (delete_org_file) {
ws_unlink(name);
CleanupOldCap(name);
}
g_free(name);
return 0;
} }
/* /*
* thread to compress capture file * thread to compress capture file
*/ */
static void* exec_compress_thread(void* arg) static void*
exec_compress_thread(void* arg)
{ {
ringbuf_exec_compress((gchar*)arg); ringbuf_exec_compress((gchar*)arg);
return NULL; return NULL;
} }
/* /*
* start a thread to compress capture file * start a thread to compress capture file
*/ */
static int ringbuf_start_compress_file(rb_file* rfile) static int
ringbuf_start_compress_file(rb_file* rfile)
{ {
gchar* name = g_strdup(rfile->name); gchar* name = g_strdup(rfile->name);
g_thread_new("exec_compress", &exec_compress_thread, name); g_thread_new("exec_compress", &exec_compress_thread, name);
return 0; return 0;
} }
#endif #endif
/* /*
* create the next filename and open a new binary file with that name * create the next filename and open a new binary file with that name
*/ */
static int ringbuf_open_file(rb_file *rfile, int *err) static int
ringbuf_open_file(rb_file *rfile, int *err)
{ {
char filenum[5+1]; char filenum[5+1];
char timestr[14+1]; char timestr[14+1];
time_t current_time; time_t current_time;
struct tm *tm; struct tm *tm;
if (rfile->name != NULL) { if (rfile->name != NULL) {
if (rb_data.unlimited == FALSE) { if (rb_data.unlimited == FALSE) {
/* remove old file (if any, so ignore error) */ /* remove old file (if any, so ignore error) */
ws_unlink(rfile->name); ws_unlink(rfile->name);
} }
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
else if (rb_data.compress_type != NULL && strcmp(rb_data.compress_type, "gzip") == 0) { else if (rb_data.compress_type != NULL && strcmp(rb_data.compress_type, "gzip") == 0) {
ringbuf_start_compress_file(rfile); ringbuf_start_compress_file(rfile);
} }
#endif #endif
g_free(rfile->name); g_free(rfile->name);
} }
#ifdef _WIN32 #ifdef _WIN32
_tzset(); _tzset();
#endif #endif
current_time = time(NULL); current_time = time(NULL);
snprintf(filenum, sizeof(filenum), "%05u", (rb_data.curr_file_num + 1) % RINGBUFFER_MAX_NUM_FILES); snprintf(filenum, sizeof(filenum), "%05u", (rb_data.curr_file_num + 1) % RINGBUFFER_MAX_NUM_FILES);
tm = localtime(&current_time); tm = localtime(&current_time);
if (tm != NULL) if (tm != NULL)
strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", tm); strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", tm);
else else
(void) g_strlcpy(timestr, "196912312359", sizeof(timestr)); /* second before the Epoch */ (void) g_strlcpy(timestr, "196912312359", sizeof(timestr)); /* second before the Epoch */
if (rb_data.nametimenum) { if (rb_data.nametimenum) {
rfile->name = g_strconcat(rb_data.fprefix, "_", timestr, "_", filenum, rb_data.fsuffix, NULL); rfile->name = g_strconcat(rb_data.fprefix, "_", timestr, "_", filenum, rb_data.fsuffix, NULL);
} else { } else {
rfile->name = g_strconcat(rb_data.fprefix, "_", filenum, "_", timestr, rb_data.fsuffix, NULL); rfile->name = g_strconcat(rb_data.fprefix, "_", filenum, "_", timestr, rb_data.fsuffix, NULL);
} }
if (rfile->name == NULL) { if (rfile->name == NULL) {
if (err != NULL) if (err != NULL)
*err = ENOMEM; *err = ENOMEM;
return -1; return -1;
} }
rb_data.fd = ws_open(rfile->name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT, rb_data.fd = ws_open(rfile->name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT,
rb_data.group_read_access ? 0640 : 0600); rb_data.group_read_access ? 0640 : 0600);
if (rb_data.fd == -1 && err != NULL) { if (rb_data.fd == -1 && err != NULL) {
*err = errno; *err = errno;
} }
return rb_data.fd; return rb_data.fd;
} }
/* /*
@ -264,92 +269,92 @@ static int ringbuf_open_file(rb_file *rfile, int *err)
*/ */
int int
ringbuf_init(const char *capfile_name, guint num_files, gboolean group_read_access, ringbuf_init(const char *capfile_name, guint num_files, gboolean group_read_access,
gchar *compress_type, gboolean has_nametimenum) gchar *compress_type, gboolean has_nametimenum)
{ {
unsigned int i; unsigned int i;
char *pfx, *last_pathsep; char *pfx, *last_pathsep;
gchar *save_file; gchar *save_file;
rb_data.files = NULL; rb_data.files = NULL;
rb_data.curr_file_num = 0; rb_data.curr_file_num = 0;
rb_data.fprefix = NULL; rb_data.fprefix = NULL;
rb_data.fsuffix = NULL;
rb_data.nametimenum = has_nametimenum;
rb_data.unlimited = FALSE;
rb_data.fd = -1;
rb_data.pdh = NULL;
rb_data.io_buffer = NULL;
rb_data.group_read_access = group_read_access;
rb_data.name_h = NULL;
rb_data.compress_type = compress_type;
g_mutex_init(&rb_data.mutex);
/* just to be sure ... */
if (num_files <= RINGBUFFER_MAX_NUM_FILES) {
rb_data.num_files = num_files;
} else {
rb_data.num_files = RINGBUFFER_MAX_NUM_FILES;
}
/* Check file name */
if (capfile_name == NULL) {
/* ringbuffer does not work with temporary files! */
return -1;
}
/* set file name prefix/suffix */
save_file = g_strdup(capfile_name);
last_pathsep = strrchr(save_file, G_DIR_SEPARATOR);
pfx = strrchr(save_file,'.');
if (pfx != NULL && (last_pathsep == NULL || pfx > last_pathsep)) {
/* The pathname has a "." in it, and it's in the last component
of the pathname (because there is either only one component,
i.e. last_pathsep is null as there are no path separators,
or the "." is after the path separator before the last
component.
Treat it as a separator between the rest of the file name and
the file name suffix, and arrange that the names given to the
ring buffer files have the specified suffix, i.e. put the
changing part of the name *before* the suffix. */
pfx[0] = '\0';
rb_data.fprefix = g_strdup(save_file);
pfx[0] = '.'; /* restore capfile_name */
rb_data.fsuffix = g_strdup(pfx);
} else {
/* Either there's no "." in the pathname, or it's in a directory
component, so the last component has no suffix. */
rb_data.fprefix = g_strdup(save_file);
rb_data.fsuffix = NULL; rb_data.fsuffix = NULL;
} rb_data.nametimenum = has_nametimenum;
g_free(save_file); rb_data.unlimited = FALSE;
save_file = NULL; rb_data.fd = -1;
rb_data.pdh = NULL;
rb_data.io_buffer = NULL;
rb_data.group_read_access = group_read_access;
rb_data.name_h = NULL;
rb_data.compress_type = compress_type;
g_mutex_init(&rb_data.mutex);
/* allocate rb_file structures (only one if unlimited since there is no /* just to be sure ... */
need to save all file names in that case) */ if (num_files <= RINGBUFFER_MAX_NUM_FILES) {
rb_data.num_files = num_files;
} else {
rb_data.num_files = RINGBUFFER_MAX_NUM_FILES;
}
if (num_files == RINGBUFFER_UNLIMITED_FILES) { /* Check file name */
rb_data.unlimited = TRUE; if (capfile_name == NULL) {
rb_data.num_files = 1; /* ringbuffer does not work with temporary files! */
} return -1;
}
rb_data.files = g_new(rb_file, rb_data.num_files); /* set file name prefix/suffix */
if (rb_data.files == NULL) {
return -1;
}
for (i=0; i < rb_data.num_files; i++) { save_file = g_strdup(capfile_name);
rb_data.files[i].name = NULL; last_pathsep = strrchr(save_file, G_DIR_SEPARATOR);
} pfx = strrchr(save_file,'.');
if (pfx != NULL && (last_pathsep == NULL || pfx > last_pathsep)) {
/* The pathname has a "." in it, and it's in the last component
of the pathname (because there is either only one component,
i.e. last_pathsep is null as there are no path separators,
or the "." is after the path separator before the last
component.
/* create the first file */ Treat it as a separator between the rest of the file name and
if (ringbuf_open_file(&rb_data.files[0], NULL) == -1) { the file name suffix, and arrange that the names given to the
ringbuf_error_cleanup(); ring buffer files have the specified suffix, i.e. put the
return -1; changing part of the name *before* the suffix. */
} pfx[0] = '\0';
rb_data.fprefix = g_strdup(save_file);
pfx[0] = '.'; /* restore capfile_name */
rb_data.fsuffix = g_strdup(pfx);
} else {
/* Either there's no "." in the pathname, or it's in a directory
component, so the last component has no suffix. */
rb_data.fprefix = g_strdup(save_file);
rb_data.fsuffix = NULL;
}
g_free(save_file);
save_file = NULL;
return rb_data.fd; /* allocate rb_file structures (only one if unlimited since there is no
need to save all file names in that case) */
if (num_files == RINGBUFFER_UNLIMITED_FILES) {
rb_data.unlimited = TRUE;
rb_data.num_files = 1;
}
rb_data.files = g_new(rb_file, rb_data.num_files);
if (rb_data.files == NULL) {
return -1;
}
for (i=0; i < rb_data.num_files; i++) {
rb_data.files[i].name = NULL;
}
/* create the first file */
if (ringbuf_open_file(&rb_data.files[0], NULL) == -1) {
ringbuf_error_cleanup();
return -1;
}
return rb_data.fd;
} }
/* /*
@ -358,41 +363,43 @@ ringbuf_init(const char *capfile_name, guint num_files, gboolean group_read_acce
gboolean gboolean
ringbuf_set_print_name(gchar *name, int *err) ringbuf_set_print_name(gchar *name, int *err)
{ {
if (rb_data.name_h != NULL) { if (rb_data.name_h != NULL) {
if (EOF == fclose(rb_data.name_h)) { if (EOF == fclose(rb_data.name_h)) {
if (err != NULL) { if (err != NULL) {
*err = errno; *err = errno;
} }
return FALSE; return FALSE;
}
} }
} if (!strcmp(name, "-") || !strcmp(name, "stdout")) {
if (!strcmp(name, "-") || !strcmp(name, "stdout")) { rb_data.name_h = stdout;
rb_data.name_h = stdout; } else if (!strcmp(name, "stderr")) {
} else if (!strcmp(name, "stderr")) { rb_data.name_h = stderr;
rb_data.name_h = stderr; } else {
} else { if (NULL == (rb_data.name_h = ws_fopen(name, "wt"))) {
if (NULL == (rb_data.name_h = ws_fopen(name, "wt"))) { if (err != NULL) {
if (err != NULL) { *err = errno;
*err = errno; }
} return FALSE;
return FALSE; }
} }
} return TRUE;
return TRUE;
} }
/* /*
* Whether the ringbuf filenames are ready. * Whether the ringbuf filenames are ready.
* (Whether ringbuf_init is called and ringbuf_free is not called.) * (Whether ringbuf_init is called and ringbuf_free is not called.)
*/ */
gboolean ringbuf_is_initialized(void) gboolean
ringbuf_is_initialized(void)
{ {
return rb_data.files != NULL; return rb_data.files != NULL;
} }
const gchar *ringbuf_current_filename(void) const gchar *
ringbuf_current_filename(void)
{ {
return rb_data.files[rb_data.curr_file_num % rb_data.num_files].name; return rb_data.files[rb_data.curr_file_num % rb_data.num_files].name;
} }
/* /*
@ -401,28 +408,28 @@ const gchar *ringbuf_current_filename(void)
FILE * FILE *
ringbuf_init_libpcap_fdopen(int *err) ringbuf_init_libpcap_fdopen(int *err)
{ {
rb_data.pdh = ws_fdopen(rb_data.fd, "wb"); rb_data.pdh = ws_fdopen(rb_data.fd, "wb");
if (rb_data.pdh == NULL) { if (rb_data.pdh == NULL) {
if (err != NULL) { if (err != NULL) {
*err = errno; *err = errno;
} }
} else { } else {
size_t buffsize = IO_BUF_SIZE; size_t buffsize = IO_BUF_SIZE;
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
ws_statb64 statb; ws_statb64 statb;
if (ws_fstat64(rb_data.fd, &statb) == 0) { if (ws_fstat64(rb_data.fd, &statb) == 0) {
if (statb.st_blksize > IO_BUF_SIZE) { if (statb.st_blksize > IO_BUF_SIZE) {
buffsize = statb.st_blksize; buffsize = statb.st_blksize;
} }
} }
#endif #endif
/* Increase the size of the IO buffer */ /* Increase the size of the IO buffer */
rb_data.io_buffer = (char *)g_realloc(rb_data.io_buffer, buffsize); rb_data.io_buffer = (char *)g_realloc(rb_data.io_buffer, buffsize);
setvbuf(rb_data.pdh, rb_data.io_buffer, _IOFBF, buffsize); setvbuf(rb_data.pdh, rb_data.io_buffer, _IOFBF, buffsize);
} }
return rb_data.pdh; return rb_data.pdh;
} }
/* /*
@ -431,51 +438,51 @@ ringbuf_init_libpcap_fdopen(int *err)
gboolean gboolean
ringbuf_switch_file(FILE **pdh, gchar **save_file, int *save_file_fd, int *err) ringbuf_switch_file(FILE **pdh, gchar **save_file, int *save_file_fd, int *err)
{ {
int next_file_index; int next_file_index;
rb_file *next_rfile = NULL; rb_file *next_rfile = NULL;
/* close current file */ /* close current file */
if (fclose(rb_data.pdh) == EOF) { if (fclose(rb_data.pdh) == EOF) {
if (err != NULL) { if (err != NULL) {
*err = errno; *err = errno;
}
ws_close(rb_data.fd); /* XXX - the above should have closed this already */
rb_data.pdh = NULL; /* it's still closed, we just got an error while closing */
rb_data.fd = -1;
g_free(rb_data.io_buffer);
rb_data.io_buffer = NULL;
return FALSE;
} }
ws_close(rb_data.fd); /* XXX - the above should have closed this already */
rb_data.pdh = NULL; /* it's still closed, we just got an error while closing */
rb_data.fd = -1;
g_free(rb_data.io_buffer);
rb_data.io_buffer = NULL;
return FALSE;
}
rb_data.pdh = NULL; rb_data.pdh = NULL;
rb_data.fd = -1; rb_data.fd = -1;
if (rb_data.name_h != NULL) { if (rb_data.name_h != NULL) {
fprintf(rb_data.name_h, "%s\n", ringbuf_current_filename()); fprintf(rb_data.name_h, "%s\n", ringbuf_current_filename());
fflush(rb_data.name_h); fflush(rb_data.name_h);
} }
/* get the next file number and open it */ /* get the next file number and open it */
rb_data.curr_file_num++ /* = next_file_num*/; rb_data.curr_file_num++ /* = next_file_num*/;
next_file_index = (rb_data.curr_file_num) % rb_data.num_files; next_file_index = (rb_data.curr_file_num) % rb_data.num_files;
next_rfile = &rb_data.files[next_file_index]; next_rfile = &rb_data.files[next_file_index];
if (ringbuf_open_file(next_rfile, err) == -1) { if (ringbuf_open_file(next_rfile, err) == -1) {
return FALSE; return FALSE;
} }
if (ringbuf_init_libpcap_fdopen(err) == NULL) { if (ringbuf_init_libpcap_fdopen(err) == NULL) {
return FALSE; return FALSE;
} }
/* switch to the new file */ /* switch to the new file */
*save_file = next_rfile->name; *save_file = next_rfile->name;
*save_file_fd = rb_data.fd; *save_file_fd = rb_data.fd;
(*pdh) = rb_data.pdh; (*pdh) = rb_data.pdh;
return TRUE; return TRUE;
} }
/* /*
@ -484,36 +491,36 @@ ringbuf_switch_file(FILE **pdh, gchar **save_file, int *save_file_fd, int *err)
gboolean gboolean
ringbuf_libpcap_dump_close(gchar **save_file, int *err) ringbuf_libpcap_dump_close(gchar **save_file, int *err)
{ {
gboolean ret_val = TRUE; gboolean ret_val = TRUE;
/* close current file, if it's open */
if (rb_data.pdh != NULL) {
if (fclose(rb_data.pdh) == EOF) {
if (err != NULL) {
*err = errno;
}
ws_close(rb_data.fd);
ret_val = FALSE;
}
rb_data.pdh = NULL;
rb_data.fd = -1;
g_free(rb_data.io_buffer);
rb_data.io_buffer = NULL;
/* close current file, if it's open */
if (rb_data.pdh != NULL) {
if (fclose(rb_data.pdh) == EOF) {
if (err != NULL) {
*err = errno;
}
ws_close(rb_data.fd);
ret_val = FALSE;
} }
rb_data.pdh = NULL;
rb_data.fd = -1;
g_free(rb_data.io_buffer);
rb_data.io_buffer = NULL;
} if (rb_data.name_h != NULL) {
fprintf(rb_data.name_h, "%s\n", ringbuf_current_filename());
fflush(rb_data.name_h);
if (rb_data.name_h != NULL) { if (EOF == fclose(rb_data.name_h)) {
fprintf(rb_data.name_h, "%s\n", ringbuf_current_filename()); /* Can't really do much about this, can we? */
fflush(rb_data.name_h); }
if (EOF == fclose(rb_data.name_h)) {
/* Can't really do much about this, can we? */
} }
}
/* set the save file name to the current file */ /* set the save file name to the current file */
*save_file = rb_data.files[rb_data.curr_file_num % rb_data.num_files].name; *save_file = rb_data.files[rb_data.curr_file_num % rb_data.num_files].name;
return ret_val; return ret_val;
} }
/* /*
@ -522,28 +529,28 @@ ringbuf_libpcap_dump_close(gchar **save_file, int *err)
void void
ringbuf_free(void) ringbuf_free(void)
{ {
unsigned int i; unsigned int i;
if (rb_data.files != NULL) { if (rb_data.files != NULL) {
for (i=0; i < rb_data.num_files; i++) { for (i=0; i < rb_data.num_files; i++) {
if (rb_data.files[i].name != NULL) { if (rb_data.files[i].name != NULL) {
g_free(rb_data.files[i].name); g_free(rb_data.files[i].name);
rb_data.files[i].name = NULL; rb_data.files[i].name = NULL;
} }
}
g_free(rb_data.files);
rb_data.files = NULL;
}
if (rb_data.fprefix != NULL) {
g_free(rb_data.fprefix);
rb_data.fprefix = NULL;
}
if (rb_data.fsuffix != NULL) {
g_free(rb_data.fsuffix);
rb_data.fsuffix = NULL;
} }
g_free(rb_data.files);
rb_data.files = NULL;
}
if (rb_data.fprefix != NULL) {
g_free(rb_data.fprefix);
rb_data.fprefix = NULL;
}
if (rb_data.fsuffix != NULL) {
g_free(rb_data.fsuffix);
rb_data.fsuffix = NULL;
}
CleanupOldCap(NULL); CleanupOldCap(NULL);
} }
/* /*
@ -552,53 +559,40 @@ ringbuf_free(void)
void void
ringbuf_error_cleanup(void) ringbuf_error_cleanup(void)
{ {
unsigned int i; unsigned int i;
/* try to close via wtap */ /* try to close via wtap */
if (rb_data.pdh != NULL) { if (rb_data.pdh != NULL) {
if (fclose(rb_data.pdh) == 0) { if (fclose(rb_data.pdh) == 0) {
rb_data.fd = -1; rb_data.fd = -1;
}
rb_data.pdh = NULL;
} }
rb_data.pdh = NULL;
}
/* close directly if still open */ /* close directly if still open */
if (rb_data.fd != -1) { if (rb_data.fd != -1) {
ws_close(rb_data.fd); ws_close(rb_data.fd);
rb_data.fd = -1; rb_data.fd = -1;
}
if (rb_data.files != NULL) {
for (i=0; i < rb_data.num_files; i++) {
if (rb_data.files[i].name != NULL) {
ws_unlink(rb_data.files[i].name);
}
} }
}
g_free(rb_data.io_buffer);
rb_data.io_buffer = NULL;
if (rb_data.name_h != NULL) { if (rb_data.files != NULL) {
if (EOF == fclose(rb_data.name_h)) { for (i=0; i < rb_data.num_files; i++) {
/* Can't really do much about this, can we? */ if (rb_data.files[i].name != NULL) {
ws_unlink(rb_data.files[i].name);
}
}
} }
} g_free(rb_data.io_buffer);
rb_data.io_buffer = NULL;
/* free the memory */ if (rb_data.name_h != NULL) {
ringbuf_free(); if (EOF == fclose(rb_data.name_h)) {
/* Can't really do much about this, can we? */
}
}
/* free the memory */
ringbuf_free();
} }
#endif /* HAVE_LIBPCAP */ #endif /* HAVE_LIBPCAP */
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* ex: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

View File

@ -37,16 +37,3 @@ void ringbuf_error_cleanup(void);
gboolean ringbuf_set_print_name(gchar *name, int *err); gboolean ringbuf_set_print_name(gchar *name, int *err);
#endif /* ringbuffer.h */ #endif /* ringbuffer.h */
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local Variables:
* c-basic-offset: 2
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=2 tabstop=8 expandtab:
* :indentSize=2:tabSize=8:noTabs=true:
*/

956
sharkd.c

File diff suppressed because it is too large Load Diff

View File

@ -56,303 +56,303 @@ static socket_handle_t _server_fd = INVALID_SOCKET;
static socket_handle_t static socket_handle_t
socket_init(char *path) socket_init(char *path)
{ {
socket_handle_t fd = INVALID_SOCKET; socket_handle_t fd = INVALID_SOCKET;
char *err_msg; char *err_msg;
err_msg = ws_init_sockets(); err_msg = ws_init_sockets();
if (err_msg != NULL) { if (err_msg != NULL) {
ws_warning("ERROR: %s", err_msg); ws_warning("ERROR: %s", err_msg);
g_free(err_msg); g_free(err_msg);
ws_warning("%s", please_report_bug()); ws_warning("%s", please_report_bug());
return fd; return fd;
} }
#ifdef SHARKD_UNIX_SUPPORT #ifdef SHARKD_UNIX_SUPPORT
if (!strncmp(path, "unix:", 5)) if (!strncmp(path, "unix:", 5))
{ {
struct sockaddr_un s_un; struct sockaddr_un s_un;
socklen_t s_un_len; socklen_t s_un_len;
path += 5; path += 5;
if (strlen(path) + 1 > sizeof(s_un.sun_path)) if (strlen(path) + 1 > sizeof(s_un.sun_path))
return INVALID_SOCKET; return INVALID_SOCKET;
fd = socket(AF_UNIX, SOCK_STREAM, 0); fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == INVALID_SOCKET) if (fd == INVALID_SOCKET)
return INVALID_SOCKET; return INVALID_SOCKET;
memset(&s_un, 0, sizeof(s_un)); memset(&s_un, 0, sizeof(s_un));
s_un.sun_family = AF_UNIX; s_un.sun_family = AF_UNIX;
(void) g_strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path)); (void) g_strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path));
s_un_len = (socklen_t)(offsetof(struct sockaddr_un, sun_path) + strlen(s_un.sun_path)); s_un_len = (socklen_t)(offsetof(struct sockaddr_un, sun_path) + strlen(s_un.sun_path));
if (s_un.sun_path[0] == '@') if (s_un.sun_path[0] == '@')
s_un.sun_path[0] = '\0'; s_un.sun_path[0] = '\0';
if (bind(fd, (struct sockaddr *) &s_un, s_un_len)) if (bind(fd, (struct sockaddr *) &s_un, s_un_len))
{ {
closesocket(fd); closesocket(fd);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
} }
else else
#endif #endif
#ifdef SHARKD_TCP_SUPPORT #ifdef SHARKD_TCP_SUPPORT
if (!strncmp(path, "tcp:", 4)) if (!strncmp(path, "tcp:", 4))
{ {
struct sockaddr_in s_in; struct sockaddr_in s_in;
int one = 1; int one = 1;
char *port_sep; char *port_sep;
guint16 port; guint16 port;
path += 4; path += 4;
port_sep = strchr(path, ':'); port_sep = strchr(path, ':');
if (!port_sep) if (!port_sep)
return INVALID_SOCKET; return INVALID_SOCKET;
*port_sep = '\0'; *port_sep = '\0';
if (ws_strtou16(port_sep + 1, NULL, &port) == FALSE) if (ws_strtou16(port_sep + 1, NULL, &port) == FALSE)
return INVALID_SOCKET; return INVALID_SOCKET;
#ifdef _WIN32 #ifdef _WIN32
/* Need to use WSASocket() to disable overlapped I/O operations, /* Need to use WSASocket() to disable overlapped I/O operations,
this way on windows SOCKET can be used as HANDLE for stdin/stdout */ this way on windows SOCKET can be used as HANDLE for stdin/stdout */
fd = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0); fd = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
#else #else
fd = socket(AF_INET, SOCK_STREAM, 0); fd = socket(AF_INET, SOCK_STREAM, 0);
#endif #endif
if (fd == INVALID_SOCKET) if (fd == INVALID_SOCKET)
return INVALID_SOCKET; return INVALID_SOCKET;
s_in.sin_family = AF_INET; s_in.sin_family = AF_INET;
ws_inet_pton4(path, &(s_in.sin_addr.s_addr)); ws_inet_pton4(path, &(s_in.sin_addr.s_addr));
s_in.sin_port = g_htons(port); s_in.sin_port = g_htons(port);
*port_sep = ':'; *port_sep = ':';
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one)); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one));
if (bind(fd, (struct sockaddr *) &s_in, sizeof(struct sockaddr_in))) if (bind(fd, (struct sockaddr *) &s_in, sizeof(struct sockaddr_in)))
{ {
closesocket(fd); closesocket(fd);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
} }
else else
#endif #endif
{ {
return INVALID_SOCKET; return INVALID_SOCKET;
} }
if (listen(fd, SOMAXCONN)) if (listen(fd, SOMAXCONN))
{ {
closesocket(fd); closesocket(fd);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
return fd; return fd;
} }
static void static void
print_usage(FILE* output) print_usage(FILE* output)
{ {
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Usage: sharkd [<classic_options>|<gold_options>]\n"); fprintf(output, "Usage: sharkd [<classic_options>|<gold_options>]\n");
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Classic (classic_options):\n"); fprintf(output, "Classic (classic_options):\n");
fprintf(output, " [-|<socket>]\n"); fprintf(output, " [-|<socket>]\n");
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, " <socket> examples:\n"); fprintf(output, " <socket> examples:\n");
#ifdef SHARKD_UNIX_SUPPORT #ifdef SHARKD_UNIX_SUPPORT
fprintf(output, " - unix:/tmp/sharkd.sock - listen on unix file /tmp/sharkd.sock\n"); fprintf(output, " - unix:/tmp/sharkd.sock - listen on unix file /tmp/sharkd.sock\n");
#endif #endif
#ifdef SHARKD_TCP_SUPPORT #ifdef SHARKD_TCP_SUPPORT
fprintf(output, " - tcp:127.0.0.1:4446 - listen on TCP port 4446\n"); fprintf(output, " - tcp:127.0.0.1:4446 - listen on TCP port 4446\n");
#endif #endif
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "Gold (gold_options):\n"); fprintf(output, "Gold (gold_options):\n");
fprintf(output, " -a <socket>, --api <socket>\n"); fprintf(output, " -a <socket>, --api <socket>\n");
fprintf(output, " listen on this socket\n"); fprintf(output, " listen on this socket\n");
fprintf(output, " -h, --help show this help information\n"); fprintf(output, " -h, --help show this help information\n");
fprintf(output, " -v, --version show version information\n"); fprintf(output, " -v, --version show version information\n");
fprintf(output, " -C <config profile>, --config-profile <config profile>\n"); fprintf(output, " -C <config profile>, --config-profile <config profile>\n");
fprintf(output, " start with specified configuration profile\n"); fprintf(output, " start with specified configuration profile\n");
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, " Examples:\n"); fprintf(output, " Examples:\n");
fprintf(output, " sharkd -C myprofile\n"); fprintf(output, " sharkd -C myprofile\n");
fprintf(output, " sharkd -a tcp:127.0.0.1:4446 -C myprofile\n"); fprintf(output, " sharkd -a tcp:127.0.0.1:4446 -C myprofile\n");
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, "See the sharkd page of the Wireshark wiki for full details.\n"); fprintf(output, "See the sharkd page of the Wireshark wiki for full details.\n");
fprintf(output, "\n"); fprintf(output, "\n");
} }
int int
sharkd_init(int argc, char **argv) sharkd_init(int argc, char **argv)
{ {
/* /*
* The leading + ensures that getopt_long() does not permute the argv[] * The leading + ensures that getopt_long() does not permute the argv[]
* entries. * entries.
* *
* We have to make sure that the first getopt_long() preserves the content * We have to make sure that the first getopt_long() preserves the content
* of argv[] for the subsequent getopt_long() call. * of argv[] for the subsequent getopt_long() call.
* *
* We use getopt_long() in both cases to ensure that we're using a routine * We use getopt_long() in both cases to ensure that we're using a routine
* whose permutation behavior we can control in the same fashion on all * whose permutation behavior we can control in the same fashion on all
* platforms, and so that, if we ever need to process a long argument before * platforms, and so that, if we ever need to process a long argument before
* doing further initialization, we can do so. * doing further initialization, we can do so.
* *
* Glibc and Solaris libc document that a leading + disables permutation * Glibc and Solaris libc document that a leading + disables permutation
* of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
* and macOS don't document it, but do so anyway. * and macOS don't document it, but do so anyway.
* *
* We do *not* use a leading - because the behavior of a leading - is * We do *not* use a leading - because the behavior of a leading - is
* platform-dependent. * platform-dependent.
*/ */
#define OPTSTRING "+" "a:hmvC:" #define OPTSTRING "+" "a:hmvC:"
static const char optstring[] = OPTSTRING; static const char optstring[] = OPTSTRING;
// right now we don't have any long options // right now we don't have any long options
static const struct ws_option long_options[] = { static const struct ws_option long_options[] = {
{"api", ws_required_argument, NULL, 'a'}, {"api", ws_required_argument, NULL, 'a'},
{"help", ws_no_argument, NULL, 'h'}, {"help", ws_no_argument, NULL, 'h'},
{"version", ws_no_argument, NULL, 'v'}, {"version", ws_no_argument, NULL, 'v'},
{"config-profile", ws_required_argument, NULL, 'C'}, {"config-profile", ws_required_argument, NULL, 'C'},
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
int opt; int opt;
#ifndef _WIN32 #ifndef _WIN32
pid_t pid; pid_t pid;
#endif #endif
socket_handle_t fd; socket_handle_t fd;
if (argc < 2) if (argc < 2)
{ {
print_usage(stderr); print_usage(stderr);
return -1; return -1;
} }
// check for classic command line // check for classic command line
if (!strcmp(argv[1], "-") || argv[1][0] == 't' || argv[1][0] == 'u') if (!strcmp(argv[1], "-") || argv[1][0] == 't' || argv[1][0] == 'u')
{ {
mode = SHARKD_MODE_CLASSIC_CONSOLE; mode = SHARKD_MODE_CLASSIC_CONSOLE;
#ifndef _WIN32 #ifndef _WIN32
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, SIG_IGN);
#endif #endif
if (!strcmp(argv[1], "-")) if (!strcmp(argv[1], "-"))
{ {
mode = SHARKD_MODE_CLASSIC_CONSOLE; mode = SHARKD_MODE_CLASSIC_CONSOLE;
} }
else else
{ {
fd = socket_init(argv[1]); fd = socket_init(argv[1]);
if (fd == INVALID_SOCKET) if (fd == INVALID_SOCKET)
return -1; return -1;
_server_fd = fd; _server_fd = fd;
mode = SHARKD_MODE_CLASSIC_DAEMON; mode = SHARKD_MODE_CLASSIC_DAEMON;
} }
} }
else else
mode = SHARKD_MODE_GOLD_CONSOLE; // assume we are running as gold console mode = SHARKD_MODE_GOLD_CONSOLE; // assume we are running as gold console
if (mode >= SHARKD_MODE_GOLD_CONSOLE) if (mode >= SHARKD_MODE_GOLD_CONSOLE)
{ {
/* /*
In Daemon Mode, we will come through here twice; once when we start the Daemon and In Daemon Mode, we will come through here twice; once when we start the Daemon and
once again after we have forked the session process. The second time through, the once again after we have forked the session process. The second time through, the
session process has already had its stdin and stdout wired up to the TCP or UNIX session process has already had its stdin and stdout wired up to the TCP or UNIX
socket and so in the orignal version of sharkd the session process is invoked with socket and so in the orignal version of sharkd the session process is invoked with
the command line: sharkd - the command line: sharkd -
When not using the classic command line, we want to spawn the session process with When not using the classic command line, we want to spawn the session process with
the complete command line with all the new options but with the -a option and the complete command line with all the new options but with the -a option and
parameter removed. Invoking a second time with the -a option will cause a loop parameter removed. Invoking a second time with the -a option will cause a loop
where we repeatedly spawn a new session process. where we repeatedly spawn a new session process.
*/ */
do { do {
if (ws_optind > (argc - 1)) if (ws_optind > (argc - 1))
break; break;
opt = ws_getopt_long(argc, argv, optstring, long_options, NULL); opt = ws_getopt_long(argc, argv, optstring, long_options, NULL);
switch (opt) { switch (opt) {
case 'C': /* Configuration Profile */ case 'C': /* Configuration Profile */
if (profile_exists(ws_optarg, FALSE)) { if (profile_exists(ws_optarg, FALSE)) {
set_profile_name(ws_optarg); // In Daemon Mode, we may need to do this again in the child process set_profile_name(ws_optarg); // In Daemon Mode, we may need to do this again in the child process
} }
else { else {
fprintf(stderr, "Configuration Profile \"%s\" does not exist\n", ws_optarg); fprintf(stderr, "Configuration Profile \"%s\" does not exist\n", ws_optarg);
return -1; return -1;
} }
break; break;
case 'a': case 'a':
fd = socket_init(ws_optarg); fd = socket_init(ws_optarg);
if (fd == INVALID_SOCKET) if (fd == INVALID_SOCKET)
return -1; return -1;
_server_fd = fd; _server_fd = fd;
fprintf(stderr, "Sharkd listening on: %s\n", ws_optarg); fprintf(stderr, "Sharkd listening on: %s\n", ws_optarg);
mode = SHARKD_MODE_GOLD_DAEMON; mode = SHARKD_MODE_GOLD_DAEMON;
break; break;
case 'h': case 'h':
print_usage(stderr); print_usage(stderr);
exit(0); exit(0);
break; break;
case 'm': case 'm':
// m is an internal-only option used when the daemon session process is created // m is an internal-only option used when the daemon session process is created
mode = SHARKD_MODE_GOLD_CONSOLE; mode = SHARKD_MODE_GOLD_CONSOLE;
break; break;
case 'v': /* Show version and exit */ case 'v': /* Show version and exit */
show_version(); show_version();
exit(0); exit(0);
break; break;
default: default:
if (!ws_optopt) if (!ws_optopt)
fprintf(stderr, "This option isn't supported: %s\n", argv[ws_optind]); fprintf(stderr, "This option isn't supported: %s\n", argv[ws_optind]);
fprintf(stderr, "Use sharkd -h for details of supported options\n"); fprintf(stderr, "Use sharkd -h for details of supported options\n");
exit(0); exit(0);
break; break;
} }
} while (opt != -1); } while (opt != -1);
} }
if (mode == SHARKD_MODE_CLASSIC_DAEMON || mode == SHARKD_MODE_GOLD_DAEMON) if (mode == SHARKD_MODE_CLASSIC_DAEMON || mode == SHARKD_MODE_GOLD_DAEMON)
{ {
/* all good - try to daemonize */ /* all good - try to daemonize */
#ifndef _WIN32 #ifndef _WIN32
pid = fork(); pid = fork();
if (pid == -1) if (pid == -1)
fprintf(stderr, "cannot go to background fork() failed: %s\n", g_strerror(errno)); fprintf(stderr, "cannot go to background fork() failed: %s\n", g_strerror(errno));
if (pid != 0) if (pid != 0)
{ {
/* parent */ /* parent */
exit(0); exit(0);
} }
#endif #endif
} }
return 0; return 0;
} }
int int
@ -362,118 +362,105 @@ sharkd_loop(int argc _U_, char* argv[] _U_)
sharkd_loop(int argc _U_, char* argv[]) sharkd_loop(int argc _U_, char* argv[])
#endif #endif
{ {
if (mode == SHARKD_MODE_CLASSIC_CONSOLE || mode == SHARKD_MODE_GOLD_CONSOLE) if (mode == SHARKD_MODE_CLASSIC_CONSOLE || mode == SHARKD_MODE_GOLD_CONSOLE)
{ {
return sharkd_session_main(mode); return sharkd_session_main(mode);
} }
while (1) while (1)
{ {
#ifndef _WIN32 #ifndef _WIN32
pid_t pid; pid_t pid;
#else #else
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
STARTUPINFO si; STARTUPINFO si;
char *exename; char *exename;
char command_line[2048]; char command_line[2048];
#endif #endif
socket_handle_t fd; socket_handle_t fd;
fd = accept(_server_fd, NULL, NULL); fd = accept(_server_fd, NULL, NULL);
if (fd == INVALID_SOCKET) if (fd == INVALID_SOCKET)
{ {
fprintf(stderr, "cannot accept(): %s\n", g_strerror(errno)); fprintf(stderr, "cannot accept(): %s\n", g_strerror(errno));
continue; continue;
} }
/* wireshark is not ready for handling multiple capture files in single process, so fork(), and handle it in separate process */ /* wireshark is not ready for handling multiple capture files in single process, so fork(), and handle it in separate process */
#ifndef _WIN32 #ifndef _WIN32
pid = fork(); pid = fork();
if (pid == 0) if (pid == 0)
{ {
closesocket(_server_fd); closesocket(_server_fd);
/* redirect stdin, stdout to socket */ /* redirect stdin, stdout to socket */
dup2(fd, 0); dup2(fd, 0);
dup2(fd, 1); dup2(fd, 1);
close(fd); close(fd);
exit(sharkd_session_main(mode)); exit(sharkd_session_main(mode));
} }
if (pid == -1) if (pid == -1)
{ {
fprintf(stderr, "cannot fork(): %s\n", g_strerror(errno)); fprintf(stderr, "cannot fork(): %s\n", g_strerror(errno));
} }
#else #else
memset(&pi, 0, sizeof(pi)); memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
si.cb = sizeof(si); si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdInput = (HANDLE) fd; si.hStdInput = (HANDLE) fd;
si.hStdOutput = (HANDLE) fd; si.hStdOutput = (HANDLE) fd;
si.hStdError = GetStdHandle(STD_ERROR_HANDLE); si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
exename = ws_strdup_printf("%s\\%s", get_progfile_dir(), "sharkd.exe"); exename = ws_strdup_printf("%s\\%s", get_progfile_dir(), "sharkd.exe");
// we need to pass in all of the command line parameters except the -a parameter // we need to pass in all of the command line parameters except the -a parameter
// passing in -a at this point would could a loop, each iteration of which would generate a new session process // passing in -a at this point would could a loop, each iteration of which would generate a new session process
memset(&command_line, 0, sizeof(command_line)); memset(&command_line, 0, sizeof(command_line));
if (mode <= SHARKD_MODE_CLASSIC_DAEMON) if (mode <= SHARKD_MODE_CLASSIC_DAEMON)
{ {
(void) g_strlcat(command_line, "sharkd.exe -", sizeof(command_line)); (void) g_strlcat(command_line, "sharkd.exe -", sizeof(command_line));
} }
else else
{ {
// The -m option used here is an internal-only option that notifies the child process that it should // The -m option used here is an internal-only option that notifies the child process that it should
// run in Gold Console mode // run in Gold Console mode
(void) g_strlcat(command_line, "sharkd.exe -m", sizeof(command_line)); (void) g_strlcat(command_line, "sharkd.exe -m", sizeof(command_line));
for (int i = 1; i < argc; i++) for (int i = 1; i < argc; i++)
{ {
if ( if (
!g_ascii_strncasecmp(argv[i], "-a", (guint)strlen(argv[i])) !g_ascii_strncasecmp(argv[i], "-a", (guint)strlen(argv[i]))
|| !g_ascii_strncasecmp(argv[i], "--api", (guint)strlen(argv[i])) || !g_ascii_strncasecmp(argv[i], "--api", (guint)strlen(argv[i]))
) )
{ {
i++; // skip the socket details i++; // skip the socket details
} }
else else
{ {
(void) g_strlcat(command_line, " ", sizeof(command_line)); (void) g_strlcat(command_line, " ", sizeof(command_line));
(void) g_strlcat(command_line, argv[i], sizeof(command_line)); (void) g_strlcat(command_line, argv[i], sizeof(command_line));
} }
} }
} }
if (!win32_create_process(exename, command_line, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) if (!win32_create_process(exename, command_line, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{ {
fprintf(stderr, "win32_create_process(%s) failed\n", exename); fprintf(stderr, "win32_create_process(%s) failed\n", exename);
} }
else else
{ {
CloseHandle(pi.hThread); CloseHandle(pi.hThread);
} }
g_free(exename); g_free(exename);
#endif #endif
closesocket(fd); closesocket(fd);
} }
return 0; return 0;
} }
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* 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:
*/

File diff suppressed because it is too large Load Diff

3305
tfshark.c

File diff suppressed because it is too large Load Diff

7274
tshark.c

File diff suppressed because it is too large Load Diff