Remove editor modelines and .editorconfig exceptions from root files
This commit is contained in:
parent
695ce22b0d
commit
70d432c357
|
@ -71,51 +71,3 @@ indent_size = 8
|
|||
[*.{c,cpp,h}]
|
||||
indent_style = space
|
||||
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
2824
capinfos.c
File diff suppressed because it is too large
Load Diff
229
captype.c
229
captype.c
|
@ -46,12 +46,12 @@
|
|||
static void
|
||||
print_usage(FILE *output)
|
||||
{
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Usage: captype [options] <infile> ...\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Miscellaneous:\n");
|
||||
fprintf(output, " -h, --help display this help and exit\n");
|
||||
fprintf(output, " -v, --version display version info and exit\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Usage: captype [options] <infile> ...\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Miscellaneous:\n");
|
||||
fprintf(output, " -h, --help display this help and exit\n");
|
||||
fprintf(output, " -v, --version display version info and exit\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -60,9 +60,9 @@ print_usage(FILE *output)
|
|||
static void
|
||||
captype_cmdarg_err(const char *msg_format, va_list ap)
|
||||
{
|
||||
fprintf(stderr, "captype: ");
|
||||
vfprintf(stderr, msg_format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "captype: ");
|
||||
vfprintf(stderr, msg_format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -71,145 +71,132 @@ captype_cmdarg_err(const char *msg_format, va_list ap)
|
|||
static void
|
||||
captype_cmdarg_err_cont(const char *msg_format, va_list ap)
|
||||
{
|
||||
vfprintf(stderr, msg_format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
vfprintf(stderr, msg_format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *init_progfile_dir_error;
|
||||
static const struct report_message_routines captype_report_routines = {
|
||||
failure_message,
|
||||
failure_message,
|
||||
open_failure_message,
|
||||
read_failure_message,
|
||||
write_failure_message,
|
||||
cfile_open_failure_message,
|
||||
cfile_dump_open_failure_message,
|
||||
cfile_read_failure_message,
|
||||
cfile_write_failure_message,
|
||||
cfile_close_failure_message
|
||||
};
|
||||
wtap *wth;
|
||||
int err;
|
||||
gchar *err_info;
|
||||
int i;
|
||||
int opt;
|
||||
int overall_error_status;
|
||||
static const struct ws_option long_options[] = {
|
||||
{"help", ws_no_argument, NULL, 'h'},
|
||||
{"version", ws_no_argument, NULL, 'v'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
char *init_progfile_dir_error;
|
||||
static const struct report_message_routines captype_report_routines = {
|
||||
failure_message,
|
||||
failure_message,
|
||||
open_failure_message,
|
||||
read_failure_message,
|
||||
write_failure_message,
|
||||
cfile_open_failure_message,
|
||||
cfile_dump_open_failure_message,
|
||||
cfile_read_failure_message,
|
||||
cfile_write_failure_message,
|
||||
cfile_close_failure_message
|
||||
};
|
||||
wtap *wth;
|
||||
int err;
|
||||
gchar *err_info;
|
||||
int i;
|
||||
int opt;
|
||||
int overall_error_status;
|
||||
static const struct ws_option long_options[] = {
|
||||
{"help", ws_no_argument, NULL, 'h'},
|
||||
{"version", ws_no_argument, NULL, 'v'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Set the C-language locale to the native environment and set the
|
||||
* code page to UTF-8 on Windows.
|
||||
*/
|
||||
/*
|
||||
* Set the C-language locale to the native environment and set the
|
||||
* code page to UTF-8 on Windows.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
setlocale(LC_ALL, ".UTF-8");
|
||||
setlocale(LC_ALL, ".UTF-8");
|
||||
#else
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_ALL, "");
|
||||
#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. */
|
||||
ws_log_init("captype", vcmdarg_err);
|
||||
/* Initialize log handler early so we can have proper logging during startup. */
|
||||
ws_log_init("captype", vcmdarg_err);
|
||||
|
||||
/* Early logging command-line initialization. */
|
||||
ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
|
||||
/* Early logging command-line initialization. */
|
||||
ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
|
||||
|
||||
/* Initialize the version information. */
|
||||
ws_init_version_info("Captype (Wireshark)", NULL, NULL, NULL);
|
||||
/* Initialize the version information. */
|
||||
ws_init_version_info("Captype (Wireshark)", NULL, NULL, NULL);
|
||||
|
||||
#ifdef _WIN32
|
||||
create_app_running_mutex();
|
||||
create_app_running_mutex();
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
* Get credential information for later use.
|
||||
*/
|
||||
init_process_policies();
|
||||
/*
|
||||
* Get credential information for later use.
|
||||
*/
|
||||
init_process_policies();
|
||||
|
||||
/*
|
||||
* Attempt to get the pathname of the directory containing the
|
||||
* executable file.
|
||||
*/
|
||||
init_progfile_dir_error = init_progfile_dir(argv[0]);
|
||||
if (init_progfile_dir_error != NULL) {
|
||||
fprintf(stderr,
|
||||
"captype: Can't get pathname of directory containing the captype program: %s.\n",
|
||||
init_progfile_dir_error);
|
||||
g_free(init_progfile_dir_error);
|
||||
}
|
||||
/*
|
||||
* Attempt to get the pathname of the directory containing the
|
||||
* executable file.
|
||||
*/
|
||||
init_progfile_dir_error = init_progfile_dir(argv[0]);
|
||||
if (init_progfile_dir_error != NULL) {
|
||||
fprintf(stderr,
|
||||
"captype: Can't get pathname of directory containing the captype program: %s.\n",
|
||||
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 */
|
||||
while ((opt = ws_getopt_long(argc, argv, "hv", long_options, NULL)) !=-1) {
|
||||
/* Process the options */
|
||||
while ((opt = ws_getopt_long(argc, argv, "hv", long_options, NULL)) !=-1) {
|
||||
|
||||
switch (opt) {
|
||||
switch (opt) {
|
||||
|
||||
case 'h':
|
||||
show_help_header("Print the file types of capture files.");
|
||||
print_usage(stdout);
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
show_help_header("Print the file types of capture files.");
|
||||
print_usage(stdout);
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
show_version();
|
||||
exit(0);
|
||||
break;
|
||||
case 'v':
|
||||
show_version();
|
||||
exit(0);
|
||||
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);
|
||||
exit(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 */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
overall_error_status = 0;
|
||||
|
||||
wtap_cleanup();
|
||||
free_progdirs();
|
||||
return overall_error_status;
|
||||
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 */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
17
cfile.c
|
@ -20,19 +20,6 @@
|
|||
void
|
||||
cap_file_init(capture_file *cf)
|
||||
{
|
||||
/* Initialize the capture file struct */
|
||||
memset(cf, 0, sizeof(capture_file));
|
||||
/* Initialize the capture file struct */
|
||||
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
169
cfile.h
|
@ -25,107 +25,107 @@ extern "C" {
|
|||
|
||||
/* Current state of file. */
|
||||
typedef enum {
|
||||
FILE_CLOSED, /* No file open */
|
||||
FILE_READ_IN_PROGRESS, /* Reading a file we've opened */
|
||||
FILE_READ_ABORTED, /* Read aborted by user */
|
||||
FILE_READ_DONE /* Read completed */
|
||||
FILE_CLOSED, /* No file open */
|
||||
FILE_READ_IN_PROGRESS, /* Reading a file we've opened */
|
||||
FILE_READ_ABORTED, /* Read aborted by user */
|
||||
FILE_READ_DONE /* Read completed */
|
||||
} file_state;
|
||||
|
||||
/* Requested packets rescan action. */
|
||||
typedef enum {
|
||||
RESCAN_NONE = 0, /* No rescan requested */
|
||||
RESCAN_SCAN, /* Request rescan without full redissection. */
|
||||
RESCAN_REDISSECT /* Request full redissection. */
|
||||
RESCAN_NONE = 0, /* No rescan requested */
|
||||
RESCAN_SCAN, /* Request rescan without full redissection. */
|
||||
RESCAN_REDISSECT /* Request full redissection. */
|
||||
} rescan_type;
|
||||
|
||||
/* Character set for text search. */
|
||||
typedef enum {
|
||||
SCS_NARROW_AND_WIDE,
|
||||
SCS_NARROW,
|
||||
SCS_WIDE
|
||||
/* add EBCDIC when it's implemented */
|
||||
SCS_NARROW_AND_WIDE,
|
||||
SCS_NARROW,
|
||||
SCS_WIDE
|
||||
/* add EBCDIC when it's implemented */
|
||||
} search_charset_t;
|
||||
|
||||
typedef enum {
|
||||
SD_FORWARD,
|
||||
SD_BACKWARD
|
||||
SD_FORWARD,
|
||||
SD_BACKWARD
|
||||
} search_direction;
|
||||
|
||||
/*
|
||||
* Packet provider for programs using a capture file.
|
||||
*/
|
||||
struct packet_provider_data {
|
||||
wtap *wth; /* Wiretap session */
|
||||
const frame_data *ref;
|
||||
frame_data *prev_dis;
|
||||
frame_data *prev_cap;
|
||||
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) */
|
||||
wtap *wth; /* Wiretap session */
|
||||
const frame_data *ref;
|
||||
frame_data *prev_dis;
|
||||
frame_data *prev_cap;
|
||||
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) */
|
||||
};
|
||||
|
||||
typedef struct _capture_file {
|
||||
epan_t *epan;
|
||||
file_state state; /* Current state of capture file */
|
||||
gchar *filename; /* Name of capture file */
|
||||
gchar *source; /* Temp file source, e.g. "Pipe from elsewhere" */
|
||||
gboolean is_tempfile; /* Is capture file a temporary file? */
|
||||
gboolean unsaved_changes; /* Does the capture file have changes that have not been saved? */
|
||||
gboolean stop_flag; /* Stop current processing (loading, searching, etc.) */
|
||||
epan_t *epan;
|
||||
file_state state; /* Current state of capture file */
|
||||
gchar *filename; /* Name of capture file */
|
||||
gchar *source; /* Temp file source, e.g. "Pipe from elsewhere" */
|
||||
gboolean is_tempfile; /* Is capture file a temporary file? */
|
||||
gboolean unsaved_changes; /* Does the capture file have changes that have not been saved? */
|
||||
gboolean stop_flag; /* Stop current processing (loading, searching, etc.) */
|
||||
|
||||
gint64 f_datalen; /* Size of capture file data (uncompressed) */
|
||||
guint16 cd_t; /* File type of capture file */
|
||||
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 */
|
||||
int lnk_t; /* File link-layer type; could be WTAP_ENCAP_PER_PACKET */
|
||||
GArray *linktypes; /* Array of packet link-layer types */
|
||||
guint32 count; /* Total number of frames */
|
||||
guint64 packet_comment_count; /* Number of comments in frames (could be >1 per frame... */
|
||||
guint32 displayed_count; /* Number of displayed frames */
|
||||
guint32 marked_count; /* Number of marked frames */
|
||||
guint32 ignored_count; /* Number of ignored frames */
|
||||
guint32 ref_time_count; /* Number of time referenced frames */
|
||||
gboolean drops_known; /* TRUE if we know how many packets were dropped */
|
||||
guint32 drops; /* Dropped packets */
|
||||
nstime_t elapsed_time; /* Elapsed time */
|
||||
int snap; /* Maximum captured packet length; 0 if unknown */
|
||||
dfilter_t *rfcode; /* Compiled read filter program */
|
||||
dfilter_t *dfcode; /* Compiled display filter program */
|
||||
gchar *dfilter; /* Display filter string */
|
||||
gboolean redissecting; /* TRUE if currently redissecting (cf_redissect_packets) */
|
||||
gboolean read_lock; /* TRUE if currently processing a file (cf_read) */
|
||||
rescan_type redissection_queued; /* Queued redissection type. */
|
||||
/* search */
|
||||
gchar *sfilter; /* Filter, hex value, or string being searched */
|
||||
gboolean hex; /* TRUE if "Hex value" 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 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 */
|
||||
guint32 search_pos; /* Byte position of last byte found in a hex search */
|
||||
guint32 search_len; /* Length of bytes matching the search */
|
||||
gboolean case_type; /* TRUE if case-insensitive text search */
|
||||
GRegex *regex; /* Set if regular expression search */
|
||||
search_charset_t scs_type; /* Character set for text search */
|
||||
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 */
|
||||
/* packet provider */
|
||||
struct packet_provider_data provider;
|
||||
/* frames */
|
||||
guint32 first_displayed; /* Frame number of first frame displayed */
|
||||
guint32 last_displayed; /* Frame number of last frame displayed */
|
||||
/* Data for currently selected frame */
|
||||
column_info cinfo; /* Column formatting information */
|
||||
frame_data *current_frame; /* Frame data */
|
||||
gint current_row; /* Row number */
|
||||
epan_dissect_t *edt; /* Protocol dissection */
|
||||
field_info *finfo_selected; /* Field info */
|
||||
wtap_rec rec; /* Record header */
|
||||
Buffer buf; /* Record data */
|
||||
gint64 f_datalen; /* Size of capture file data (uncompressed) */
|
||||
guint16 cd_t; /* File type of capture file */
|
||||
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 */
|
||||
int lnk_t; /* File link-layer type; could be WTAP_ENCAP_PER_PACKET */
|
||||
GArray *linktypes; /* Array of packet link-layer types */
|
||||
guint32 count; /* Total number of frames */
|
||||
guint64 packet_comment_count; /* Number of comments in frames (could be >1 per frame... */
|
||||
guint32 displayed_count; /* Number of displayed frames */
|
||||
guint32 marked_count; /* Number of marked frames */
|
||||
guint32 ignored_count; /* Number of ignored frames */
|
||||
guint32 ref_time_count; /* Number of time referenced frames */
|
||||
gboolean drops_known; /* TRUE if we know how many packets were dropped */
|
||||
guint32 drops; /* Dropped packets */
|
||||
nstime_t elapsed_time; /* Elapsed time */
|
||||
int snap; /* Maximum captured packet length; 0 if unknown */
|
||||
dfilter_t *rfcode; /* Compiled read filter program */
|
||||
dfilter_t *dfcode; /* Compiled display filter program */
|
||||
gchar *dfilter; /* Display filter string */
|
||||
gboolean redissecting; /* TRUE if currently redissecting (cf_redissect_packets) */
|
||||
gboolean read_lock; /* TRUE if currently processing a file (cf_read) */
|
||||
rescan_type redissection_queued; /* Queued redissection type. */
|
||||
/* search */
|
||||
gchar *sfilter; /* Filter, hex value, or string being searched */
|
||||
gboolean hex; /* TRUE if "Hex value" 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 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 */
|
||||
guint32 search_pos; /* Byte position of last byte found in a hex search */
|
||||
guint32 search_len; /* Length of bytes matching the search */
|
||||
gboolean case_type; /* TRUE if case-insensitive text search */
|
||||
GRegex *regex; /* Set if regular expression search */
|
||||
search_charset_t scs_type; /* Character set for text search */
|
||||
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 */
|
||||
/* packet provider */
|
||||
struct packet_provider_data provider;
|
||||
/* frames */
|
||||
guint32 first_displayed; /* Frame number of first frame displayed */
|
||||
guint32 last_displayed; /* Frame number of last frame displayed */
|
||||
/* Data for currently selected frame */
|
||||
column_info cinfo; /* Column formatting information */
|
||||
frame_data *current_frame; /* Frame data */
|
||||
gint current_row; /* Row number */
|
||||
epan_dissect_t *edt; /* Protocol dissection */
|
||||
field_info *finfo_selected; /* Field info */
|
||||
wtap_rec rec; /* Record header */
|
||||
Buffer buf; /* Record data */
|
||||
|
||||
gpointer window; /* Top-level window associated with file */
|
||||
gulong computed_elapsed; /* Elapsed time to load the file (in msec). */
|
||||
gpointer window; /* Top-level window associated with file */
|
||||
gulong computed_elapsed; /* Elapsed time to load the file (in msec). */
|
||||
|
||||
guint32 cum_bytes;
|
||||
guint32 cum_bytes;
|
||||
} capture_file;
|
||||
|
||||
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 /* 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
197
dftest.c
|
@ -43,115 +43,115 @@ static void dftest_cmdarg_err_cont(const char *fmt, va_list ap);
|
|||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *init_progfile_dir_error;
|
||||
static const struct report_message_routines dftest_report_routines = {
|
||||
failure_message,
|
||||
failure_message,
|
||||
open_failure_message,
|
||||
read_failure_message,
|
||||
write_failure_message,
|
||||
cfile_open_failure_message,
|
||||
cfile_dump_open_failure_message,
|
||||
cfile_read_failure_message,
|
||||
cfile_write_failure_message,
|
||||
cfile_close_failure_message
|
||||
};
|
||||
char *text;
|
||||
dfilter_t *df;
|
||||
gchar *err_msg;
|
||||
char *init_progfile_dir_error;
|
||||
static const struct report_message_routines dftest_report_routines = {
|
||||
failure_message,
|
||||
failure_message,
|
||||
open_failure_message,
|
||||
read_failure_message,
|
||||
write_failure_message,
|
||||
cfile_open_failure_message,
|
||||
cfile_dump_open_failure_message,
|
||||
cfile_read_failure_message,
|
||||
cfile_write_failure_message,
|
||||
cfile_close_failure_message
|
||||
};
|
||||
char *text;
|
||||
dfilter_t *df;
|
||||
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. */
|
||||
ws_log_init("dftest", vcmdarg_err);
|
||||
/* Initialize log handler early so we can have proper logging during startup. */
|
||||
ws_log_init("dftest", vcmdarg_err);
|
||||
|
||||
/* Early logging command-line initialization. */
|
||||
ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
|
||||
/* Early logging command-line initialization. */
|
||||
ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
|
||||
|
||||
/*
|
||||
* Get credential information for later use.
|
||||
*/
|
||||
init_process_policies();
|
||||
/*
|
||||
* Get credential information for later use.
|
||||
*/
|
||||
init_process_policies();
|
||||
|
||||
/*
|
||||
* Attempt to get the pathname of the directory containing the
|
||||
* executable file.
|
||||
*/
|
||||
init_progfile_dir_error = init_progfile_dir(argv[0]);
|
||||
if (init_progfile_dir_error != NULL) {
|
||||
fprintf(stderr, "dftest: Can't get pathname of directory containing the dftest program: %s.\n",
|
||||
init_progfile_dir_error);
|
||||
g_free(init_progfile_dir_error);
|
||||
}
|
||||
/*
|
||||
* Attempt to get the pathname of the directory containing the
|
||||
* executable file.
|
||||
*/
|
||||
init_progfile_dir_error = init_progfile_dir(argv[0]);
|
||||
if (init_progfile_dir_error != NULL) {
|
||||
fprintf(stderr, "dftest: Can't get pathname of directory containing the dftest program: %s.\n",
|
||||
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_seconds_type(TS_SECONDS_DEFAULT);
|
||||
timestamp_set_type(TS_RELATIVE);
|
||||
timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
|
||||
|
||||
/*
|
||||
* Libwiretap must be initialized before libwireshark is, so that
|
||||
* dissection-time handlers for file-type-dependent blocks can
|
||||
* register using the file type/subtype value for the file type.
|
||||
*/
|
||||
wtap_init(TRUE);
|
||||
/*
|
||||
* Libwiretap must be initialized before libwireshark is, so that
|
||||
* dissection-time handlers for file-type-dependent blocks can
|
||||
* register using the file type/subtype value for the file type.
|
||||
*/
|
||||
wtap_init(TRUE);
|
||||
|
||||
/* Register all dissectors; we must do this before checking for the
|
||||
"-g" flag, as the "-g" flag dumps a list of fields registered
|
||||
by the dissectors, and we must do it before we read the preferences,
|
||||
in case any dissectors register preferences. */
|
||||
if (!epan_init(NULL, NULL, FALSE))
|
||||
return 2;
|
||||
/* Register all dissectors; we must do this before checking for the
|
||||
"-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,
|
||||
in case any dissectors register preferences. */
|
||||
if (!epan_init(NULL, NULL, FALSE))
|
||||
return 2;
|
||||
|
||||
/*
|
||||
* Set the C-language locale to the native environment and set the
|
||||
* code page to UTF-8 on Windows.
|
||||
*/
|
||||
/*
|
||||
* Set the C-language locale to the native environment and set the
|
||||
* code page to UTF-8 on Windows.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
setlocale(LC_ALL, ".UTF-8");
|
||||
setlocale(LC_ALL, ".UTF-8");
|
||||
#else
|
||||
setlocale(LC_ALL, "");
|
||||
setlocale(LC_ALL, "");
|
||||
#endif
|
||||
|
||||
/* Load libwireshark settings from the current profile. */
|
||||
epan_load_settings();
|
||||
/* Load libwireshark settings from the current profile. */
|
||||
epan_load_settings();
|
||||
|
||||
/* notify all registered modules that have had any of their preferences
|
||||
changed either from one of the preferences file or from the command
|
||||
line that its preferences have changed. */
|
||||
prefs_apply_all();
|
||||
/* notify all registered modules that have had any of their preferences
|
||||
changed either from one of the preferences file or from the command
|
||||
line that its preferences have changed. */
|
||||
prefs_apply_all();
|
||||
|
||||
/* Check for filter on command line */
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "Usage: dftest <filter>\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Check for filter on command line */
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "Usage: dftest <filter>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Get filter text */
|
||||
text = get_args_as_string(argc, argv, 1);
|
||||
/* Get filter text */
|
||||
text = get_args_as_string(argc, argv, 1);
|
||||
|
||||
printf("Filter: %s\n", text);
|
||||
printf("Filter: %s\n", text);
|
||||
|
||||
/* Compile it */
|
||||
if (!dfilter_compile(text, &df, &err_msg)) {
|
||||
fprintf(stderr, "dftest: %s\n", err_msg);
|
||||
g_free(err_msg);
|
||||
epan_cleanup();
|
||||
g_free(text);
|
||||
exit(2);
|
||||
}
|
||||
/* Compile it */
|
||||
if (!dfilter_compile(text, &df, &err_msg)) {
|
||||
fprintf(stderr, "dftest: %s\n", err_msg);
|
||||
g_free(err_msg);
|
||||
epan_cleanup();
|
||||
g_free(text);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
printf("\n");
|
||||
|
||||
if (df == NULL)
|
||||
printf("Filter is empty\n");
|
||||
else
|
||||
dfilter_dump(df);
|
||||
if (df == NULL)
|
||||
printf("Filter is empty\n");
|
||||
else
|
||||
dfilter_dump(df);
|
||||
|
||||
dfilter_free(df);
|
||||
epan_cleanup();
|
||||
g_free(text);
|
||||
exit(0);
|
||||
dfilter_free(df);
|
||||
epan_cleanup();
|
||||
g_free(text);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -160,9 +160,9 @@ main(int argc, char **argv)
|
|||
static void
|
||||
dftest_cmdarg_err(const char *fmt, va_list ap)
|
||||
{
|
||||
fprintf(stderr, "dftest: ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "dftest: ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -171,19 +171,6 @@ dftest_cmdarg_err(const char *fmt, va_list ap)
|
|||
static void
|
||||
dftest_cmdarg_err_cont(const char *fmt, va_list ap)
|
||||
{
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
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:
|
||||
*/
|
||||
|
|
13
file.h
13
file.h
|
@ -735,16 +735,3 @@ gboolean cf_add_ip_name_from_string(capture_file *cf, const char *addr, const ch
|
|||
#endif /* __cplusplus */
|
||||
|
||||
#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:
|
||||
*/
|
||||
|
|
387
frame_tvbuff.c
387
frame_tvbuff.c
|
@ -21,36 +21,36 @@
|
|||
#include "wiretap/wtap-int.h" /* for ->random_fh */
|
||||
|
||||
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 */
|
||||
gint64 file_off; /**< File offset */
|
||||
const struct packet_provider_data *prov; /* provider of packet information */
|
||||
gint64 file_off; /**< File offset */
|
||||
|
||||
guint offset;
|
||||
guint offset;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
frame_read(struct tvb_frame *frame_tvb, wtap_rec *rec, Buffer *buf)
|
||||
{
|
||||
int err;
|
||||
gchar *err_info;
|
||||
gboolean ok = TRUE;
|
||||
int err;
|
||||
gchar *err_info;
|
||||
gboolean ok = TRUE;
|
||||
|
||||
/* XXX, what if phdr->caplen isn't equal to
|
||||
* frame_tvb->tvb.length + frame_tvb->offset?
|
||||
*/
|
||||
if (!wtap_seek_read(frame_tvb->prov->wth, frame_tvb->file_off, rec, buf, &err, &err_info)) {
|
||||
/* XXX - report error! */
|
||||
switch (err) {
|
||||
case WTAP_ERR_BAD_FILE:
|
||||
g_free(err_info);
|
||||
ok = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
/* XXX, what if phdr->caplen isn't equal to
|
||||
* frame_tvb->tvb.length + frame_tvb->offset?
|
||||
*/
|
||||
if (!wtap_seek_read(frame_tvb->prov->wth, frame_tvb->file_off, rec, buf, &err, &err_info)) {
|
||||
/* XXX - report error! */
|
||||
switch (err) {
|
||||
case WTAP_ERR_BAD_FILE:
|
||||
g_free(err_info);
|
||||
ok = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
static GPtrArray *buffer_cache = NULL;
|
||||
|
@ -58,287 +58,274 @@ static GPtrArray *buffer_cache = NULL;
|
|||
static void
|
||||
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 (G_UNLIKELY(!buffer_cache)) buffer_cache = g_ptr_array_sized_new(1024);
|
||||
if (frame_tvb->buf == NULL) {
|
||||
if (G_UNLIKELY(!buffer_cache)) buffer_cache = g_ptr_array_sized_new(1024);
|
||||
|
||||
if (buffer_cache->len > 0) {
|
||||
frame_tvb->buf = (struct Buffer *) g_ptr_array_remove_index(buffer_cache, buffer_cache->len - 1);
|
||||
} else {
|
||||
frame_tvb->buf = g_new(struct Buffer, 1);
|
||||
}
|
||||
if (buffer_cache->len > 0) {
|
||||
frame_tvb->buf = (struct Buffer *) g_ptr_array_remove_index(buffer_cache, buffer_cache->len - 1);
|
||||
} else {
|
||||
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))
|
||||
{ /* TODO: THROW(???); */ }
|
||||
}
|
||||
if (!frame_read(frame_tvb, &rec, frame_tvb->buf))
|
||||
{ /* 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
|
||||
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) {
|
||||
ws_buffer_free(frame_tvb->buf);
|
||||
g_ptr_array_add(buffer_cache, frame_tvb->buf);
|
||||
}
|
||||
if (frame_tvb->buf) {
|
||||
ws_buffer_free(frame_tvb->buf);
|
||||
g_ptr_array_add(buffer_cache, frame_tvb->buf);
|
||||
}
|
||||
}
|
||||
|
||||
static const guint8 *
|
||||
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 *
|
||||
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
|
||||
frame_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
|
||||
{
|
||||
struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
|
||||
const guint8 *result;
|
||||
struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb;
|
||||
const guint8 *result;
|
||||
|
||||
frame_cache(frame_tvb);
|
||||
frame_cache(frame_tvb);
|
||||
|
||||
result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
|
||||
if (result)
|
||||
return (gint) (result - tvb->real_data);
|
||||
else
|
||||
return -1;
|
||||
result = (const guint8 *)memchr(tvb->real_data + abs_offset, needle, limit);
|
||||
if (result)
|
||||
return (gint) (result - tvb->real_data);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static gint
|
||||
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
|
||||
frame_offset(const tvbuff_t *tvb _U_, const guint counter)
|
||||
{
|
||||
/* XXX: frame_tvb->offset */
|
||||
return counter;
|
||||
/* XXX: frame_tvb->offset */
|
||||
return counter;
|
||||
}
|
||||
|
||||
static tvbuff_t *frame_clone(tvbuff_t *tvb, guint abs_offset, guint abs_length);
|
||||
|
||||
static const struct tvb_ops tvb_frame_ops = {
|
||||
sizeof(struct tvb_frame), /* size */
|
||||
sizeof(struct tvb_frame), /* size */
|
||||
|
||||
frame_free, /* free */
|
||||
frame_offset, /* offset */
|
||||
frame_get_ptr, /* get_ptr */
|
||||
frame_memcpy, /* memcpy */
|
||||
frame_find_guint8, /* find_guint8 */
|
||||
frame_pbrk_guint8, /* pbrk_guint8 */
|
||||
frame_clone, /* clone */
|
||||
frame_free, /* free */
|
||||
frame_offset, /* offset */
|
||||
frame_get_ptr, /* get_ptr */
|
||||
frame_memcpy, /* memcpy */
|
||||
frame_find_guint8, /* find_guint8 */
|
||||
frame_pbrk_guint8, /* pbrk_guint8 */
|
||||
frame_clone, /* clone */
|
||||
};
|
||||
|
||||
/* based on tvb_new_real_data() */
|
||||
tvbuff_t *
|
||||
frame_tvbuff_new(const struct packet_provider_data *prov, const frame_data *fd,
|
||||
const guint8 *buf)
|
||||
const guint8 *buf)
|
||||
{
|
||||
struct tvb_frame *frame_tvb;
|
||||
tvbuff_t *tvb;
|
||||
struct tvb_frame *frame_tvb;
|
||||
tvbuff_t *tvb;
|
||||
|
||||
tvb = tvb_new(&tvb_frame_ops);
|
||||
tvb = tvb_new(&tvb_frame_ops);
|
||||
|
||||
/*
|
||||
* XXX - currently, the length arguments in
|
||||
* tvbuff structure are signed, but the captured
|
||||
* and reported length values are unsigned; this means
|
||||
* that length values > 2^31 - 1 will appear as
|
||||
* negative lengths
|
||||
*
|
||||
* Captured length values that large will already
|
||||
* have been filtered out by the Wiretap modules
|
||||
* (the file will be reported as corrupted), to
|
||||
* avoid trying to allocate large chunks of data.
|
||||
*
|
||||
* Reported length values will not have been
|
||||
* filtered out, and should not be filtered out,
|
||||
* as those lengths are not necessarily invalid.
|
||||
*
|
||||
* For now, we clip the reported length at G_MAXINT
|
||||
*
|
||||
* (XXX, is this still a problem?) There was an exception when we call
|
||||
* tvb_new_real_data() now there's no one
|
||||
*/
|
||||
/*
|
||||
* XXX - currently, the length arguments in
|
||||
* tvbuff structure are signed, but the captured
|
||||
* and reported length values are unsigned; this means
|
||||
* that length values > 2^31 - 1 will appear as
|
||||
* negative lengths
|
||||
*
|
||||
* Captured length values that large will already
|
||||
* have been filtered out by the Wiretap modules
|
||||
* (the file will be reported as corrupted), to
|
||||
* avoid trying to allocate large chunks of data.
|
||||
*
|
||||
* Reported length values will not have been
|
||||
* filtered out, and should not be filtered out,
|
||||
* as those lengths are not necessarily invalid.
|
||||
*
|
||||
* For now, we clip the reported length at G_MAXINT
|
||||
*
|
||||
* (XXX, is this still a problem?) There was an exception when we call
|
||||
* tvb_new_real_data() now there's no one
|
||||
*/
|
||||
|
||||
tvb->real_data = buf;
|
||||
tvb->length = fd->cap_len;
|
||||
tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
|
||||
tvb->contained_length = tvb->reported_length;
|
||||
tvb->initialized = TRUE;
|
||||
tvb->real_data = buf;
|
||||
tvb->length = fd->cap_len;
|
||||
tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
|
||||
tvb->contained_length = tvb->reported_length;
|
||||
tvb->initialized = TRUE;
|
||||
|
||||
/*
|
||||
* This is the top-level real tvbuff for this data source,
|
||||
* so its data source tvbuff is itself.
|
||||
*/
|
||||
tvb->ds_tvb = tvb;
|
||||
/*
|
||||
* This is the top-level real tvbuff for this data source,
|
||||
* so its data source tvbuff is itself.
|
||||
*/
|
||||
tvb->ds_tvb = tvb;
|
||||
|
||||
frame_tvb = (struct tvb_frame *) tvb;
|
||||
frame_tvb = (struct tvb_frame *) tvb;
|
||||
|
||||
/* XXX, wtap_can_seek() */
|
||||
if (prov->wth && prov->wth->random_fh) {
|
||||
frame_tvb->prov = prov;
|
||||
frame_tvb->file_off = fd->file_off;
|
||||
frame_tvb->offset = 0;
|
||||
} else
|
||||
frame_tvb->prov = NULL;
|
||||
/* XXX, wtap_can_seek() */
|
||||
if (prov->wth && prov->wth->random_fh) {
|
||||
frame_tvb->prov = prov;
|
||||
frame_tvb->file_off = fd->file_off;
|
||||
frame_tvb->offset = 0;
|
||||
} else
|
||||
frame_tvb->prov = NULL;
|
||||
|
||||
frame_tvb->buf = NULL;
|
||||
frame_tvb->buf = NULL;
|
||||
|
||||
return tvb;
|
||||
return tvb;
|
||||
}
|
||||
|
||||
tvbuff_t *
|
||||
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 *
|
||||
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;
|
||||
struct tvb_frame *cloned_frame_tvb;
|
||||
tvbuff_t *cloned_tvb;
|
||||
struct tvb_frame *cloned_frame_tvb;
|
||||
|
||||
/* file not seekable */
|
||||
if (!frame_tvb->prov)
|
||||
return NULL;
|
||||
/* file not seekable */
|
||||
if (!frame_tvb->prov)
|
||||
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 */
|
||||
cloned_tvb->real_data = NULL;
|
||||
cloned_tvb->length = abs_length;
|
||||
cloned_tvb->reported_length = abs_length; /* XXX? */
|
||||
cloned_tvb->contained_length = cloned_tvb->reported_length;
|
||||
cloned_tvb->initialized = TRUE;
|
||||
/* data will be read when needed */
|
||||
cloned_tvb->real_data = NULL;
|
||||
cloned_tvb->length = abs_length;
|
||||
cloned_tvb->reported_length = abs_length; /* XXX? */
|
||||
cloned_tvb->contained_length = cloned_tvb->reported_length;
|
||||
cloned_tvb->initialized = TRUE;
|
||||
|
||||
/*
|
||||
* This is the top-level real tvbuff for this data source,
|
||||
* so its data source tvbuff is itself.
|
||||
*/
|
||||
cloned_tvb->ds_tvb = cloned_tvb;
|
||||
/*
|
||||
* This is the top-level real tvbuff for this data source,
|
||||
* so its data source tvbuff is itself.
|
||||
*/
|
||||
cloned_tvb->ds_tvb = cloned_tvb;
|
||||
|
||||
cloned_frame_tvb = (struct tvb_frame *) cloned_tvb;
|
||||
cloned_frame_tvb->prov = frame_tvb->prov;
|
||||
cloned_frame_tvb->file_off = frame_tvb->file_off;
|
||||
cloned_frame_tvb->offset = abs_offset;
|
||||
cloned_frame_tvb->buf = NULL;
|
||||
cloned_frame_tvb = (struct tvb_frame *) cloned_tvb;
|
||||
cloned_frame_tvb->prov = frame_tvb->prov;
|
||||
cloned_frame_tvb->file_off = frame_tvb->file_off;
|
||||
cloned_frame_tvb->offset = abs_offset;
|
||||
cloned_frame_tvb->buf = NULL;
|
||||
|
||||
return cloned_tvb;
|
||||
return cloned_tvb;
|
||||
}
|
||||
|
||||
|
||||
/* based on tvb_new_real_data() */
|
||||
tvbuff_t *
|
||||
file_tvbuff_new(const struct packet_provider_data *prov, const frame_data *fd,
|
||||
const guint8 *buf)
|
||||
const guint8 *buf)
|
||||
{
|
||||
struct tvb_frame *frame_tvb;
|
||||
tvbuff_t *tvb;
|
||||
struct tvb_frame *frame_tvb;
|
||||
tvbuff_t *tvb;
|
||||
|
||||
tvb = tvb_new(&tvb_frame_ops);
|
||||
tvb = tvb_new(&tvb_frame_ops);
|
||||
|
||||
/*
|
||||
* XXX - currently, the length arguments in
|
||||
* tvbuff structure are signed, but the captured
|
||||
* and reported length values are unsigned; this means
|
||||
* that length values > 2^31 - 1 will appear as
|
||||
* negative lengths
|
||||
*
|
||||
* Captured length values that large will already
|
||||
* have been filtered out by the Wiretap modules
|
||||
* (the file will be reported as corrupted), to
|
||||
* avoid trying to allocate large chunks of data.
|
||||
*
|
||||
* Reported length values will not have been
|
||||
* filtered out, and should not be filtered out,
|
||||
* as those lengths are not necessarily invalid.
|
||||
*
|
||||
* For now, we clip the reported length at G_MAXINT
|
||||
*
|
||||
* (XXX, is this still a problem?) There was an exception when we call
|
||||
* tvb_new_real_data() now there's no one
|
||||
*/
|
||||
/*
|
||||
* XXX - currently, the length arguments in
|
||||
* tvbuff structure are signed, but the captured
|
||||
* and reported length values are unsigned; this means
|
||||
* that length values > 2^31 - 1 will appear as
|
||||
* negative lengths
|
||||
*
|
||||
* Captured length values that large will already
|
||||
* have been filtered out by the Wiretap modules
|
||||
* (the file will be reported as corrupted), to
|
||||
* avoid trying to allocate large chunks of data.
|
||||
*
|
||||
* Reported length values will not have been
|
||||
* filtered out, and should not be filtered out,
|
||||
* as those lengths are not necessarily invalid.
|
||||
*
|
||||
* For now, we clip the reported length at G_MAXINT
|
||||
*
|
||||
* (XXX, is this still a problem?) There was an exception when we call
|
||||
* tvb_new_real_data() now there's no one
|
||||
*/
|
||||
|
||||
tvb->real_data = buf;
|
||||
tvb->length = fd->cap_len;
|
||||
tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
|
||||
tvb->contained_length = tvb->reported_length;
|
||||
tvb->initialized = TRUE;
|
||||
tvb->real_data = buf;
|
||||
tvb->length = fd->cap_len;
|
||||
tvb->reported_length = fd->pkt_len > G_MAXINT ? G_MAXINT : fd->pkt_len;
|
||||
tvb->contained_length = tvb->reported_length;
|
||||
tvb->initialized = TRUE;
|
||||
|
||||
/*
|
||||
* This is the top-level real tvbuff for this data source,
|
||||
* so its data source tvbuff is itself.
|
||||
*/
|
||||
tvb->ds_tvb = tvb;
|
||||
/*
|
||||
* This is the top-level real tvbuff for this data source,
|
||||
* so its data source tvbuff is itself.
|
||||
*/
|
||||
tvb->ds_tvb = tvb;
|
||||
|
||||
frame_tvb = (struct tvb_frame *) tvb;
|
||||
frame_tvb = (struct tvb_frame *) tvb;
|
||||
|
||||
/* XXX, wtap_can_seek() */
|
||||
if (prov->wth && prov->wth->random_fh) {
|
||||
frame_tvb->prov = prov;
|
||||
frame_tvb->file_off = fd->file_off;
|
||||
frame_tvb->offset = 0;
|
||||
} else
|
||||
frame_tvb->prov = NULL;
|
||||
/* XXX, wtap_can_seek() */
|
||||
if (prov->wth && prov->wth->random_fh) {
|
||||
frame_tvb->prov = prov;
|
||||
frame_tvb->file_off = fd->file_off;
|
||||
frame_tvb->offset = 0;
|
||||
} else
|
||||
frame_tvb->prov = NULL;
|
||||
|
||||
frame_tvb->buf = NULL;
|
||||
frame_tvb->buf = NULL;
|
||||
|
||||
return tvb;
|
||||
return tvb;
|
||||
}
|
||||
|
||||
tvbuff_t *
|
||||
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:
|
||||
*/
|
||||
|
|
|
@ -37,16 +37,3 @@ extern tvbuff_t *file_tvbuff_new_buffer(const struct packet_provider_data *prov,
|
|||
#endif /* __cplusplus */
|
||||
|
||||
#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:
|
||||
*/
|
||||
|
|
615
mergecap.c
615
mergecap.c
|
@ -52,23 +52,23 @@
|
|||
static void
|
||||
print_usage(FILE *output)
|
||||
{
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Usage: mergecap [options] -w <outfile>|- <infile> [<infile> ...]\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Output:\n");
|
||||
fprintf(output, " -a concatenate rather than merge files.\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, " -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, " 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, " an empty \"-I\" option will list the merge modes.\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Miscellaneous:\n");
|
||||
fprintf(output, " -h display this help and exit.\n");
|
||||
fprintf(output, " -v verbose output.\n");
|
||||
fprintf(output, " -V print version information and exit.\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Usage: mergecap [options] -w <outfile>|- <infile> [<infile> ...]\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Output:\n");
|
||||
fprintf(output, " -a concatenate rather than merge files.\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, " -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, " 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, " an empty \"-I\" option will list the merge modes.\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Miscellaneous:\n");
|
||||
fprintf(output, " -h display this help and exit.\n");
|
||||
fprintf(output, " -v verbose output.\n");
|
||||
fprintf(output, " -V print version information and exit.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -77,9 +77,9 @@ print_usage(FILE *output)
|
|||
static void
|
||||
mergecap_cmdarg_err(const char *fmt, va_list ap)
|
||||
{
|
||||
fprintf(stderr, "mergecap: ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "mergecap: ");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -88,352 +88,339 @@ mergecap_cmdarg_err(const char *fmt, va_list ap)
|
|||
static void
|
||||
mergecap_cmdarg_err_cont(const char *fmt, va_list ap)
|
||||
{
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
static 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");
|
||||
writable_type_subtypes = wtap_get_writable_file_types_subtypes(FT_SORT_BY_NAME);
|
||||
for (guint i = 0; i < writable_type_subtypes->len; i++) {
|
||||
int ft = g_array_index(writable_type_subtypes, int, i);
|
||||
fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
|
||||
wtap_file_type_subtype_description(ft));
|
||||
}
|
||||
g_array_free(writable_type_subtypes, TRUE);
|
||||
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);
|
||||
for (guint i = 0; i < writable_type_subtypes->len; i++) {
|
||||
int ft = g_array_index(writable_type_subtypes, int, i);
|
||||
fprintf(stderr, " %s - %s\n", wtap_file_type_subtype_name(ft),
|
||||
wtap_file_type_subtype_description(ft));
|
||||
}
|
||||
g_array_free(writable_type_subtypes, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
list_idb_merge_modes(void) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "mergecap: The available IDB merge modes for the \"-I\" flag are:\n");
|
||||
for (i = 0; i < IDB_MERGE_MODE_MAX; i++) {
|
||||
fprintf(stderr, " %s\n", merge_idb_merge_mode_to_string(i));
|
||||
}
|
||||
fprintf(stderr, "mergecap: The available IDB merge modes for the \"-I\" flag are:\n");
|
||||
for (i = 0; i < IDB_MERGE_MODE_MAX; i++) {
|
||||
fprintf(stderr, " %s\n", merge_idb_merge_mode_to_string(i));
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
merge_callback(merge_event event, int num,
|
||||
const merge_in_file_t in_files[], const guint in_file_count,
|
||||
void *data _U_)
|
||||
const merge_in_file_t in_files[], const guint in_file_count,
|
||||
void *data _U_)
|
||||
{
|
||||
guint i;
|
||||
guint i;
|
||||
|
||||
switch (event) {
|
||||
switch (event) {
|
||||
|
||||
case MERGE_EVENT_INPUT_FILES_OPENED:
|
||||
for (i = 0; i < in_file_count; i++) {
|
||||
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)));
|
||||
}
|
||||
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));
|
||||
case MERGE_EVENT_INPUT_FILES_OPENED:
|
||||
for (i = 0; i < in_file_count; i++) {
|
||||
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)));
|
||||
}
|
||||
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:
|
||||
fprintf(stderr, "mergecap: ready to merge records\n");
|
||||
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;
|
||||
|
||||
case MERGE_EVENT_RECORD_WAS_READ:
|
||||
/* for this event, num = count */
|
||||
fprintf(stderr, "Record: %d\n", num);
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "mergecap: selected frame_type %s (%s)\n",
|
||||
wtap_encap_description(num),
|
||||
wtap_encap_name(num));
|
||||
break;
|
||||
|
||||
case MERGE_EVENT_DONE:
|
||||
fprintf(stderr, "mergecap: merging complete\n");
|
||||
break;
|
||||
}
|
||||
case MERGE_EVENT_READY_TO_MERGE:
|
||||
fprintf(stderr, "mergecap: ready to merge records\n");
|
||||
break;
|
||||
|
||||
/* false = do not stop merging */
|
||||
return FALSE;
|
||||
case MERGE_EVENT_RECORD_WAS_READ:
|
||||
/* 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
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *init_progfile_dir_error;
|
||||
static const struct report_message_routines mergecap_report_routines = {
|
||||
failure_message,
|
||||
failure_message,
|
||||
open_failure_message,
|
||||
read_failure_message,
|
||||
write_failure_message,
|
||||
cfile_open_failure_message,
|
||||
cfile_dump_open_failure_message,
|
||||
cfile_read_failure_message,
|
||||
cfile_write_failure_message,
|
||||
cfile_close_failure_message
|
||||
};
|
||||
int opt;
|
||||
static const struct ws_option long_options[] = {
|
||||
{"help", ws_no_argument, NULL, 'h'},
|
||||
{"version", ws_no_argument, NULL, 'V'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
gboolean do_append = FALSE;
|
||||
gboolean verbose = FALSE;
|
||||
int in_file_count = 0;
|
||||
guint32 snaplen = 0;
|
||||
int file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
|
||||
int err = 0;
|
||||
gchar *err_info = NULL;
|
||||
int err_fileno;
|
||||
guint32 err_framenum;
|
||||
char *out_filename = NULL;
|
||||
merge_result status = MERGE_OK;
|
||||
idb_merge_mode mode = IDB_MERGE_MODE_MAX;
|
||||
merge_progress_callback_t cb;
|
||||
char *init_progfile_dir_error;
|
||||
static const struct report_message_routines mergecap_report_routines = {
|
||||
failure_message,
|
||||
failure_message,
|
||||
open_failure_message,
|
||||
read_failure_message,
|
||||
write_failure_message,
|
||||
cfile_open_failure_message,
|
||||
cfile_dump_open_failure_message,
|
||||
cfile_read_failure_message,
|
||||
cfile_write_failure_message,
|
||||
cfile_close_failure_message
|
||||
};
|
||||
int opt;
|
||||
static const struct ws_option long_options[] = {
|
||||
{"help", ws_no_argument, NULL, 'h'},
|
||||
{"version", ws_no_argument, NULL, 'V'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
gboolean do_append = FALSE;
|
||||
gboolean verbose = FALSE;
|
||||
int in_file_count = 0;
|
||||
guint32 snaplen = 0;
|
||||
int file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
|
||||
int err = 0;
|
||||
gchar *err_info = NULL;
|
||||
int err_fileno;
|
||||
guint32 err_framenum;
|
||||
char *out_filename = NULL;
|
||||
merge_result status = MERGE_OK;
|
||||
idb_merge_mode mode = IDB_MERGE_MODE_MAX;
|
||||
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. */
|
||||
ws_log_init("mergecap", vcmdarg_err);
|
||||
/* Initialize log handler early so we can have proper logging during startup. */
|
||||
ws_log_init("mergecap", vcmdarg_err);
|
||||
|
||||
/* Early logging command-line initialization. */
|
||||
ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
|
||||
/* Early logging command-line initialization. */
|
||||
ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
|
||||
|
||||
#ifdef _WIN32
|
||||
create_app_running_mutex();
|
||||
create_app_running_mutex();
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/* Initialize the version information. */
|
||||
ws_init_version_info("Mergecap (Wireshark)", NULL, NULL, NULL);
|
||||
/* Initialize the version information. */
|
||||
ws_init_version_info("Mergecap (Wireshark)", NULL, NULL, NULL);
|
||||
|
||||
/*
|
||||
* Get credential information for later use.
|
||||
*/
|
||||
init_process_policies();
|
||||
/*
|
||||
* Get credential information for later use.
|
||||
*/
|
||||
init_process_policies();
|
||||
|
||||
/*
|
||||
* Attempt to get the pathname of the directory containing the
|
||||
* executable file.
|
||||
*/
|
||||
init_progfile_dir_error = init_progfile_dir(argv[0]);
|
||||
if (init_progfile_dir_error != NULL) {
|
||||
fprintf(stderr,
|
||||
"mergecap: Can't get pathname of directory containing the mergecap program: %s.\n",
|
||||
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;
|
||||
/*
|
||||
* Attempt to get the pathname of the directory containing the
|
||||
* executable file.
|
||||
*/
|
||||
init_progfile_dir_error = init_progfile_dir(argv[0]);
|
||||
if (init_progfile_dir_error != NULL) {
|
||||
fprintf(stderr,
|
||||
"mergecap: Can't get pathname of directory containing the mergecap program: %s.\n",
|
||||
init_progfile_dir_error);
|
||||
g_free(init_progfile_dir_error);
|
||||
}
|
||||
}
|
||||
|
||||
/* Default to pcapng when writing. */
|
||||
if (file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
|
||||
file_type = wtap_pcapng_file_type_subtype();
|
||||
init_report_message("mergecap", &mergecap_report_routines);
|
||||
|
||||
cb.callback_func = merge_callback;
|
||||
cb.data = NULL;
|
||||
wtap_init(TRUE);
|
||||
|
||||
/* check for proper args; at a minimum, must have an output
|
||||
* filename and one input file
|
||||
*/
|
||||
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;
|
||||
}
|
||||
/* Process the options first */
|
||||
while ((opt = ws_getopt_long(argc, argv, "aF:hI:s:vVw:", long_options, NULL)) != -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;
|
||||
}
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
do_append = !do_append;
|
||||
break;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
case 'h':
|
||||
show_help_header("Merge two or more capture files into one.");
|
||||
print_usage(stdout);
|
||||
goto clean_exit;
|
||||
break;
|
||||
|
||||
switch (status) {
|
||||
case MERGE_OK:
|
||||
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 MERGE_USER_ABORTED:
|
||||
/* we don't catch SIGINT/SIGTERM (yet?), so we couldn't have aborted */
|
||||
ws_assert_not_reached();
|
||||
break;
|
||||
case 's':
|
||||
snaplen = get_nonzero_guint32(ws_optarg, "snapshot length");
|
||||
break;
|
||||
|
||||
case MERGE_ERR_CANT_OPEN_INFILE:
|
||||
cfile_open_failure_message(argv[ws_optind + err_fileno], err, err_info);
|
||||
break;
|
||||
case 'v':
|
||||
verbose = TRUE;
|
||||
break;
|
||||
|
||||
case MERGE_ERR_CANT_OPEN_OUTFILE:
|
||||
cfile_dump_open_failure_message(out_filename, err, err_info, file_type);
|
||||
break;
|
||||
case 'V':
|
||||
show_version();
|
||||
goto clean_exit;
|
||||
break;
|
||||
|
||||
case MERGE_ERR_CANT_READ_INFILE:
|
||||
cfile_read_failure_message(argv[ws_optind + err_fileno], err, err_info);
|
||||
break;
|
||||
case 'w':
|
||||
out_filename = ws_optarg;
|
||||
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 '?': /* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
/* Default to pcapng when writing. */
|
||||
if (file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
|
||||
file_type = wtap_pcapng_file_type_subtype();
|
||||
|
||||
case MERGE_ERR_CANT_CLOSE_OUTFILE:
|
||||
cfile_close_failure_message(out_filename, err, err_info);
|
||||
break;
|
||||
cb.callback_func = merge_callback;
|
||||
cb.data = NULL;
|
||||
|
||||
default:
|
||||
cmdarg_err("Unknown merge_files error %d", status);
|
||||
break;
|
||||
}
|
||||
/* check for proper args; at a minimum, must have an output
|
||||
* filename and one input file
|
||||
*/
|
||||
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:
|
||||
wtap_cleanup();
|
||||
free_progdirs();
|
||||
return (status == MERGE_OK) ? 0 : 2;
|
||||
wtap_cleanup();
|
||||
free_progdirs();
|
||||
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
339
randpkt.c
|
@ -45,9 +45,9 @@
|
|||
static void
|
||||
randpkt_cmdarg_err(const char *msg_format, va_list ap)
|
||||
{
|
||||
fprintf(stderr, "randpkt: ");
|
||||
vfprintf(stderr, msg_format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "randpkt: ");
|
||||
vfprintf(stderr, msg_format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -56,219 +56,206 @@ randpkt_cmdarg_err(const char *msg_format, va_list ap)
|
|||
static void
|
||||
randpkt_cmdarg_err_cont(const char *msg_format, va_list ap)
|
||||
{
|
||||
vfprintf(stderr, msg_format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
vfprintf(stderr, msg_format, ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/* Print usage statement and exit program */
|
||||
static void
|
||||
usage(gboolean is_error)
|
||||
{
|
||||
FILE *output;
|
||||
char** abbrev_list;
|
||||
char** longname_list;
|
||||
unsigned i = 0;
|
||||
FILE *output;
|
||||
char** abbrev_list;
|
||||
char** longname_list;
|
||||
unsigned i = 0;
|
||||
|
||||
if (!is_error) {
|
||||
output = stdout;
|
||||
}
|
||||
else {
|
||||
output = stderr;
|
||||
}
|
||||
if (!is_error) {
|
||||
output = stdout;
|
||||
}
|
||||
else {
|
||||
output = stderr;
|
||||
}
|
||||
|
||||
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 count is 1000.\n");
|
||||
fprintf(output, "-r: random packet type selection\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Types:\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 count is 1000.\n");
|
||||
fprintf(output, "-r: random packet type selection\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Types:\n");
|
||||
|
||||
/* Get the examples list */
|
||||
randpkt_example_list(&abbrev_list, &longname_list);
|
||||
while (abbrev_list[i] && longname_list[i]) {
|
||||
fprintf(output, "\t%-16s%s\n", abbrev_list[i], longname_list[i]);
|
||||
i++;
|
||||
}
|
||||
/* Get the examples list */
|
||||
randpkt_example_list(&abbrev_list, &longname_list);
|
||||
while (abbrev_list[i] && longname_list[i]) {
|
||||
fprintf(output, "\t%-16s%s\n", abbrev_list[i], longname_list[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
g_strfreev(abbrev_list);
|
||||
g_strfreev(longname_list);
|
||||
g_strfreev(abbrev_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
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *init_progfile_dir_error;
|
||||
static const struct report_message_routines randpkt_report_routines = {
|
||||
failure_message,
|
||||
failure_message,
|
||||
open_failure_message,
|
||||
read_failure_message,
|
||||
write_failure_message,
|
||||
cfile_open_failure_message,
|
||||
cfile_dump_open_failure_message,
|
||||
cfile_read_failure_message,
|
||||
cfile_write_failure_message,
|
||||
cfile_close_failure_message
|
||||
};
|
||||
int opt;
|
||||
int produce_type = -1;
|
||||
char *produce_filename = NULL;
|
||||
int produce_max_bytes = 5000;
|
||||
int produce_count = 1000;
|
||||
randpkt_example *example;
|
||||
guint8* type = NULL;
|
||||
int allrandom = FALSE;
|
||||
wtap_dumper *savedump;
|
||||
int ret = EXIT_SUCCESS;
|
||||
static const struct ws_option long_options[] = {
|
||||
{"help", ws_no_argument, NULL, 'h'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
char *init_progfile_dir_error;
|
||||
static const struct report_message_routines randpkt_report_routines = {
|
||||
failure_message,
|
||||
failure_message,
|
||||
open_failure_message,
|
||||
read_failure_message,
|
||||
write_failure_message,
|
||||
cfile_open_failure_message,
|
||||
cfile_dump_open_failure_message,
|
||||
cfile_read_failure_message,
|
||||
cfile_write_failure_message,
|
||||
cfile_close_failure_message
|
||||
};
|
||||
int opt;
|
||||
int produce_type = -1;
|
||||
char *produce_filename = NULL;
|
||||
int produce_max_bytes = 5000;
|
||||
int produce_count = 1000;
|
||||
randpkt_example *example;
|
||||
guint8* type = NULL;
|
||||
int allrandom = FALSE;
|
||||
wtap_dumper *savedump;
|
||||
int ret = EXIT_SUCCESS;
|
||||
static const struct ws_option long_options[] = {
|
||||
{"help", ws_no_argument, NULL, 'h'},
|
||||
{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. */
|
||||
ws_log_init("randpkt", vcmdarg_err);
|
||||
/* Initialize log handler early so we can have proper logging during startup. */
|
||||
ws_log_init("randpkt", vcmdarg_err);
|
||||
|
||||
/* Early logging command-line initialization. */
|
||||
ws_log_parse_args(&argc, argv, vcmdarg_err, INVALID_OPTION);
|
||||
/* Early logging command-line initialization. */
|
||||
ws_log_parse_args(&argc, argv, vcmdarg_err, INVALID_OPTION);
|
||||
|
||||
/*
|
||||
* Get credential information for later use.
|
||||
*/
|
||||
init_process_policies();
|
||||
/*
|
||||
* Get credential information for later use.
|
||||
*/
|
||||
init_process_policies();
|
||||
|
||||
/*
|
||||
* Attempt to get the pathname of the directory containing the
|
||||
* executable file.
|
||||
*/
|
||||
init_progfile_dir_error = init_progfile_dir(argv[0]);
|
||||
if (init_progfile_dir_error != NULL) {
|
||||
fprintf(stderr,
|
||||
"capinfos: Can't get pathname of directory containing the capinfos program: %s.\n",
|
||||
init_progfile_dir_error);
|
||||
g_free(init_progfile_dir_error);
|
||||
}
|
||||
/*
|
||||
* Attempt to get the pathname of the directory containing the
|
||||
* executable file.
|
||||
*/
|
||||
init_progfile_dir_error = init_progfile_dir(argv[0]);
|
||||
if (init_progfile_dir_error != NULL) {
|
||||
fprintf(stderr,
|
||||
"capinfos: Can't get pathname of directory containing the capinfos program: %s.\n",
|
||||
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
|
||||
create_app_running_mutex();
|
||||
create_app_running_mutex();
|
||||
#endif /* _WIN32 */
|
||||
|
||||
while ((opt = ws_getopt_long(argc, argv, "b:c:ht:r", long_options, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'b': /* max bytes */
|
||||
produce_max_bytes = get_positive_int(ws_optarg, "max bytes");
|
||||
if (produce_max_bytes > 65536) {
|
||||
cmdarg_err("max bytes is > 65536");
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
break;
|
||||
while ((opt = ws_getopt_long(argc, argv, "b:c:ht:r", long_options, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'b': /* max bytes */
|
||||
produce_max_bytes = get_positive_int(ws_optarg, "max bytes");
|
||||
if (produce_max_bytes > 65536) {
|
||||
cmdarg_err("max bytes is > 65536");
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c': /* count */
|
||||
produce_count = get_positive_int(ws_optarg, "count");
|
||||
break;
|
||||
case 'c': /* count */
|
||||
produce_count = get_positive_int(ws_optarg, "count");
|
||||
break;
|
||||
|
||||
case 't': /* type of packet to produce */
|
||||
type = g_strdup(ws_optarg);
|
||||
break;
|
||||
case 't': /* type of packet to produce */
|
||||
type = g_strdup(ws_optarg);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage(FALSE);
|
||||
goto clean_exit;
|
||||
break;
|
||||
case 'h':
|
||||
usage(FALSE);
|
||||
goto clean_exit;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
allrandom = TRUE;
|
||||
break;
|
||||
case 'r':
|
||||
allrandom = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(TRUE);
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
usage(TRUE);
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* any more command line parameters? */
|
||||
if (argc > ws_optind) {
|
||||
produce_filename = argv[ws_optind];
|
||||
} else {
|
||||
usage(TRUE);
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
/* any more command line parameters? */
|
||||
if (argc > ws_optind) {
|
||||
produce_filename = argv[ws_optind];
|
||||
} else {
|
||||
usage(TRUE);
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
if (!allrandom) {
|
||||
produce_type = randpkt_parse_type(type);
|
||||
g_free(type);
|
||||
if (!allrandom) {
|
||||
produce_type = randpkt_parse_type(type);
|
||||
g_free(type);
|
||||
|
||||
example = randpkt_find_example(produce_type);
|
||||
if (!example) {
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
example = randpkt_find_example(produce_type);
|
||||
if (!example) {
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
ret = randpkt_example_init(example, produce_filename, produce_max_bytes);
|
||||
if (ret != EXIT_SUCCESS)
|
||||
goto clean_exit;
|
||||
randpkt_loop(example, produce_count, 0);
|
||||
} else {
|
||||
if (type) {
|
||||
fprintf(stderr, "Can't set type in random mode\n");
|
||||
ret = INVALID_TYPE;
|
||||
goto clean_exit;
|
||||
}
|
||||
ret = randpkt_example_init(example, produce_filename, produce_max_bytes);
|
||||
if (ret != EXIT_SUCCESS)
|
||||
goto clean_exit;
|
||||
randpkt_loop(example, produce_count, 0);
|
||||
} else {
|
||||
if (type) {
|
||||
fprintf(stderr, "Can't set type in random mode\n");
|
||||
ret = INVALID_TYPE;
|
||||
goto clean_exit;
|
||||
}
|
||||
|
||||
produce_type = randpkt_parse_type(NULL);
|
||||
example = randpkt_find_example(produce_type);
|
||||
if (!example) {
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
ret = randpkt_example_init(example, produce_filename, produce_max_bytes);
|
||||
if (ret != EXIT_SUCCESS)
|
||||
goto clean_exit;
|
||||
produce_type = randpkt_parse_type(NULL);
|
||||
example = randpkt_find_example(produce_type);
|
||||
if (!example) {
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
ret = randpkt_example_init(example, produce_filename, produce_max_bytes);
|
||||
if (ret != EXIT_SUCCESS)
|
||||
goto clean_exit;
|
||||
|
||||
while (produce_count-- > 0) {
|
||||
randpkt_loop(example, 1, 0);
|
||||
produce_type = randpkt_parse_type(NULL);
|
||||
while (produce_count-- > 0) {
|
||||
randpkt_loop(example, 1, 0);
|
||||
produce_type = randpkt_parse_type(NULL);
|
||||
|
||||
savedump = example->dump;
|
||||
savedump = example->dump;
|
||||
|
||||
example = randpkt_find_example(produce_type);
|
||||
if (!example) {
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
example->dump = savedump;
|
||||
example->filename = produce_filename;
|
||||
}
|
||||
}
|
||||
if (!randpkt_example_close(example)) {
|
||||
ret = CLOSE_ERROR;
|
||||
}
|
||||
example = randpkt_find_example(produce_type);
|
||||
if (!example) {
|
||||
ret = INVALID_OPTION;
|
||||
goto clean_exit;
|
||||
}
|
||||
example->dump = savedump;
|
||||
example->filename = produce_filename;
|
||||
}
|
||||
}
|
||||
if (!randpkt_example_close(example)) {
|
||||
ret = CLOSE_ERROR;
|
||||
}
|
||||
|
||||
clean_exit:
|
||||
wtap_cleanup();
|
||||
return ret;
|
||||
wtap_cleanup();
|
||||
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:
|
||||
*/
|
||||
|
|
726
ringbuffer.c
726
ringbuffer.c
|
@ -60,30 +60,30 @@
|
|||
|
||||
/* Ringbuffer file structure */
|
||||
typedef struct _rb_file {
|
||||
gchar *name;
|
||||
gchar *name;
|
||||
} rb_file;
|
||||
|
||||
#define MAX_FILENAME_QUEUE 100
|
||||
|
||||
/** Ringbuffer data structure */
|
||||
typedef struct _ringbuf_data {
|
||||
rb_file *files;
|
||||
guint num_files; /**< Number of ringbuffer files (1 to ...) */
|
||||
guint curr_file_num; /**< Number of the current file (ever increasing) */
|
||||
gchar *fprefix; /**< Filename prefix */
|
||||
gchar *fsuffix; /**< Filename suffix */
|
||||
gboolean nametimenum; /**< ...num_time... or ...time_num... */
|
||||
gboolean unlimited; /**< TRUE if unlimited number of files */
|
||||
rb_file *files;
|
||||
guint num_files; /**< Number of ringbuffer files (1 to ...) */
|
||||
guint curr_file_num; /**< Number of the current file (ever increasing) */
|
||||
gchar *fprefix; /**< Filename prefix */
|
||||
gchar *fsuffix; /**< Filename suffix */
|
||||
gboolean nametimenum; /**< ...num_time... or ...time_num... */
|
||||
gboolean unlimited; /**< TRUE if unlimited number of files */
|
||||
|
||||
int fd; /**< Current ringbuffer file descriptor */
|
||||
FILE *pdh;
|
||||
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 */
|
||||
FILE *name_h; /**< write names of completed files to this handle */
|
||||
gchar *compress_type; /**< compress type */
|
||||
int fd; /**< Current ringbuffer file descriptor */
|
||||
FILE *pdh;
|
||||
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 */
|
||||
FILE *name_h; /**< write names of completed files to this handle */
|
||||
gchar *compress_type; /**< compress type */
|
||||
|
||||
GMutex mutex; /**< mutex for oldnames */
|
||||
gchar *oldnames[MAX_FILENAME_QUEUE]; /**< filename list of pending to be deleted */
|
||||
GMutex mutex; /**< mutex for oldnames */
|
||||
gchar *oldnames[MAX_FILENAME_QUEUE]; /**< filename list of pending to be deleted */
|
||||
} ringbuf_data;
|
||||
|
||||
static ringbuf_data rb_data;
|
||||
|
@ -91,172 +91,177 @@ static ringbuf_data rb_data;
|
|||
/*
|
||||
* delete pending uncompressed pcap files.
|
||||
*/
|
||||
static void CleanupOldCap(gchar* name)
|
||||
static void
|
||||
CleanupOldCap(gchar* name)
|
||||
{
|
||||
ws_statb64 statb;
|
||||
size_t i;
|
||||
ws_statb64 statb;
|
||||
size_t i;
|
||||
|
||||
g_mutex_lock(&rb_data.mutex);
|
||||
g_mutex_lock(&rb_data.mutex);
|
||||
|
||||
/* Delete pending delete file */
|
||||
for (i = 0; i < sizeof(rb_data.oldnames) / sizeof(rb_data.oldnames[0]); i++) {
|
||||
if (rb_data.oldnames[i] != NULL) {
|
||||
ws_unlink(rb_data.oldnames[i]);
|
||||
if (ws_stat64(rb_data.oldnames[i], &statb) != 0) {
|
||||
g_free(rb_data.oldnames[i]);
|
||||
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;
|
||||
/* Delete pending delete file */
|
||||
for (i = 0; i < sizeof(rb_data.oldnames) / sizeof(rb_data.oldnames[0]); i++) {
|
||||
if (rb_data.oldnames[i] != NULL) {
|
||||
ws_unlink(rb_data.oldnames[i]);
|
||||
if (ws_stat64(rb_data.oldnames[i], &statb) != 0) {
|
||||
g_free(rb_data.oldnames[i]);
|
||||
rb_data.oldnames[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
/*
|
||||
* compress capture file
|
||||
*/
|
||||
static int ringbuf_exec_compress(gchar* name)
|
||||
static int
|
||||
ringbuf_exec_compress(gchar* name)
|
||||
{
|
||||
guint8 *buffer = NULL;
|
||||
gchar* outgz = NULL;
|
||||
int fd = -1;
|
||||
ssize_t nread;
|
||||
gboolean delete_org_file = TRUE;
|
||||
gzFile fi = NULL;
|
||||
guint8 *buffer = NULL;
|
||||
gchar* outgz = NULL;
|
||||
int fd = -1;
|
||||
ssize_t nread;
|
||||
gboolean delete_org_file = TRUE;
|
||||
gzFile fi = NULL;
|
||||
|
||||
fd = ws_open(name, O_RDONLY | O_BINARY, 0000);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
fd = ws_open(name, O_RDONLY | O_BINARY, 0000);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
outgz = ws_strdup_printf("%s.gz", name);
|
||||
fi = gzopen(outgz, "wb");
|
||||
g_free(outgz);
|
||||
if (fi == NULL) {
|
||||
ws_close(fd);
|
||||
return -1;
|
||||
}
|
||||
outgz = ws_strdup_printf("%s.gz", name);
|
||||
fi = gzopen(outgz, "wb");
|
||||
g_free(outgz);
|
||||
if (fi == NULL) {
|
||||
ws_close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define FS_READ_SIZE 65536
|
||||
buffer = (guint8*)g_malloc(FS_READ_SIZE);
|
||||
if (buffer == NULL) {
|
||||
buffer = (guint8*)g_malloc(FS_READ_SIZE);
|
||||
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);
|
||||
gzclose(fi);
|
||||
return -1;
|
||||
}
|
||||
g_free(buffer);
|
||||
|
||||
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;
|
||||
/* delete the original file only if compression succeeds */
|
||||
if (delete_org_file) {
|
||||
ws_unlink(name);
|
||||
CleanupOldCap(name);
|
||||
}
|
||||
}
|
||||
if (nread < 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;
|
||||
g_free(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* thread to compress capture file
|
||||
*/
|
||||
static void* exec_compress_thread(void* arg)
|
||||
static void*
|
||||
exec_compress_thread(void* arg)
|
||||
{
|
||||
ringbuf_exec_compress((gchar*)arg);
|
||||
return NULL;
|
||||
ringbuf_exec_compress((gchar*)arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
g_thread_new("exec_compress", &exec_compress_thread, name);
|
||||
return 0;
|
||||
gchar* name = g_strdup(rfile->name);
|
||||
g_thread_new("exec_compress", &exec_compress_thread, name);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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 timestr[14+1];
|
||||
time_t current_time;
|
||||
struct tm *tm;
|
||||
char filenum[5+1];
|
||||
char timestr[14+1];
|
||||
time_t current_time;
|
||||
struct tm *tm;
|
||||
|
||||
if (rfile->name != NULL) {
|
||||
if (rb_data.unlimited == FALSE) {
|
||||
/* remove old file (if any, so ignore error) */
|
||||
ws_unlink(rfile->name);
|
||||
}
|
||||
if (rfile->name != NULL) {
|
||||
if (rb_data.unlimited == FALSE) {
|
||||
/* remove old file (if any, so ignore error) */
|
||||
ws_unlink(rfile->name);
|
||||
}
|
||||
#ifdef HAVE_ZLIB
|
||||
else if (rb_data.compress_type != NULL && strcmp(rb_data.compress_type, "gzip") == 0) {
|
||||
ringbuf_start_compress_file(rfile);
|
||||
}
|
||||
else if (rb_data.compress_type != NULL && strcmp(rb_data.compress_type, "gzip") == 0) {
|
||||
ringbuf_start_compress_file(rfile);
|
||||
}
|
||||
#endif
|
||||
g_free(rfile->name);
|
||||
}
|
||||
g_free(rfile->name);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_tzset();
|
||||
_tzset();
|
||||
#endif
|
||||
current_time = time(NULL);
|
||||
current_time = time(NULL);
|
||||
|
||||
snprintf(filenum, sizeof(filenum), "%05u", (rb_data.curr_file_num + 1) % RINGBUFFER_MAX_NUM_FILES);
|
||||
tm = localtime(¤t_time);
|
||||
if (tm != NULL)
|
||||
strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", tm);
|
||||
else
|
||||
(void) g_strlcpy(timestr, "196912312359", sizeof(timestr)); /* second before the Epoch */
|
||||
if (rb_data.nametimenum) {
|
||||
rfile->name = g_strconcat(rb_data.fprefix, "_", timestr, "_", filenum, rb_data.fsuffix, NULL);
|
||||
} else {
|
||||
rfile->name = g_strconcat(rb_data.fprefix, "_", filenum, "_", timestr, rb_data.fsuffix, NULL);
|
||||
}
|
||||
snprintf(filenum, sizeof(filenum), "%05u", (rb_data.curr_file_num + 1) % RINGBUFFER_MAX_NUM_FILES);
|
||||
tm = localtime(¤t_time);
|
||||
if (tm != NULL)
|
||||
strftime(timestr, sizeof(timestr), "%Y%m%d%H%M%S", tm);
|
||||
else
|
||||
(void) g_strlcpy(timestr, "196912312359", sizeof(timestr)); /* second before the Epoch */
|
||||
if (rb_data.nametimenum) {
|
||||
rfile->name = g_strconcat(rb_data.fprefix, "_", timestr, "_", filenum, rb_data.fsuffix, NULL);
|
||||
} else {
|
||||
rfile->name = g_strconcat(rb_data.fprefix, "_", filenum, "_", timestr, rb_data.fsuffix, NULL);
|
||||
}
|
||||
|
||||
if (rfile->name == NULL) {
|
||||
if (err != NULL)
|
||||
*err = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
if (rfile->name == NULL) {
|
||||
if (err != NULL)
|
||||
*err = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
rb_data.fd = ws_open(rfile->name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT,
|
||||
rb_data.group_read_access ? 0640 : 0600);
|
||||
rb_data.fd = ws_open(rfile->name, O_RDWR|O_BINARY|O_TRUNC|O_CREAT,
|
||||
rb_data.group_read_access ? 0640 : 0600);
|
||||
|
||||
if (rb_data.fd == -1 && err != NULL) {
|
||||
*err = errno;
|
||||
}
|
||||
if (rb_data.fd == -1 && err != NULL) {
|
||||
*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
|
||||
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;
|
||||
char *pfx, *last_pathsep;
|
||||
gchar *save_file;
|
||||
unsigned int i;
|
||||
char *pfx, *last_pathsep;
|
||||
gchar *save_file;
|
||||
|
||||
rb_data.files = NULL;
|
||||
rb_data.curr_file_num = 0;
|
||||
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.files = NULL;
|
||||
rb_data.curr_file_num = 0;
|
||||
rb_data.fprefix = NULL;
|
||||
rb_data.fsuffix = NULL;
|
||||
}
|
||||
g_free(save_file);
|
||||
save_file = 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);
|
||||
|
||||
/* allocate rb_file structures (only one if unlimited since there is no
|
||||
need to save all file names in that case) */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
if (num_files == RINGBUFFER_UNLIMITED_FILES) {
|
||||
rb_data.unlimited = TRUE;
|
||||
rb_data.num_files = 1;
|
||||
}
|
||||
/* Check file name */
|
||||
if (capfile_name == NULL) {
|
||||
/* ringbuffer does not work with temporary files! */
|
||||
return -1;
|
||||
}
|
||||
|
||||
rb_data.files = g_new(rb_file, rb_data.num_files);
|
||||
if (rb_data.files == NULL) {
|
||||
return -1;
|
||||
}
|
||||
/* set file name prefix/suffix */
|
||||
|
||||
for (i=0; i < rb_data.num_files; i++) {
|
||||
rb_data.files[i].name = NULL;
|
||||
}
|
||||
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.
|
||||
|
||||
/* create the first file */
|
||||
if (ringbuf_open_file(&rb_data.files[0], NULL) == -1) {
|
||||
ringbuf_error_cleanup();
|
||||
return -1;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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
|
||||
ringbuf_set_print_name(gchar *name, int *err)
|
||||
{
|
||||
if (rb_data.name_h != NULL) {
|
||||
if (EOF == fclose(rb_data.name_h)) {
|
||||
if (err != NULL) {
|
||||
*err = errno;
|
||||
}
|
||||
return FALSE;
|
||||
if (rb_data.name_h != NULL) {
|
||||
if (EOF == fclose(rb_data.name_h)) {
|
||||
if (err != NULL) {
|
||||
*err = errno;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!strcmp(name, "-") || !strcmp(name, "stdout")) {
|
||||
rb_data.name_h = stdout;
|
||||
} else if (!strcmp(name, "stderr")) {
|
||||
rb_data.name_h = stderr;
|
||||
} else {
|
||||
if (NULL == (rb_data.name_h = ws_fopen(name, "wt"))) {
|
||||
if (err != NULL) {
|
||||
*err = errno;
|
||||
}
|
||||
return FALSE;
|
||||
if (!strcmp(name, "-") || !strcmp(name, "stdout")) {
|
||||
rb_data.name_h = stdout;
|
||||
} else if (!strcmp(name, "stderr")) {
|
||||
rb_data.name_h = stderr;
|
||||
} else {
|
||||
if (NULL == (rb_data.name_h = ws_fopen(name, "wt"))) {
|
||||
if (err != NULL) {
|
||||
*err = errno;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Whether the ringbuf filenames are ready.
|
||||
* (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 *
|
||||
ringbuf_init_libpcap_fdopen(int *err)
|
||||
{
|
||||
rb_data.pdh = ws_fdopen(rb_data.fd, "wb");
|
||||
if (rb_data.pdh == NULL) {
|
||||
if (err != NULL) {
|
||||
*err = errno;
|
||||
}
|
||||
} else {
|
||||
size_t buffsize = IO_BUF_SIZE;
|
||||
rb_data.pdh = ws_fdopen(rb_data.fd, "wb");
|
||||
if (rb_data.pdh == NULL) {
|
||||
if (err != NULL) {
|
||||
*err = errno;
|
||||
}
|
||||
} else {
|
||||
size_t buffsize = IO_BUF_SIZE;
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
ws_statb64 statb;
|
||||
ws_statb64 statb;
|
||||
|
||||
if (ws_fstat64(rb_data.fd, &statb) == 0) {
|
||||
if (statb.st_blksize > IO_BUF_SIZE) {
|
||||
buffsize = statb.st_blksize;
|
||||
}
|
||||
}
|
||||
if (ws_fstat64(rb_data.fd, &statb) == 0) {
|
||||
if (statb.st_blksize > IO_BUF_SIZE) {
|
||||
buffsize = statb.st_blksize;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Increase the size of the IO buffer */
|
||||
rb_data.io_buffer = (char *)g_realloc(rb_data.io_buffer, buffsize);
|
||||
setvbuf(rb_data.pdh, rb_data.io_buffer, _IOFBF, buffsize);
|
||||
}
|
||||
/* Increase the size of the IO buffer */
|
||||
rb_data.io_buffer = (char *)g_realloc(rb_data.io_buffer, 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
|
||||
ringbuf_switch_file(FILE **pdh, gchar **save_file, int *save_file_fd, int *err)
|
||||
{
|
||||
int next_file_index;
|
||||
rb_file *next_rfile = NULL;
|
||||
int next_file_index;
|
||||
rb_file *next_rfile = NULL;
|
||||
|
||||
/* close current file */
|
||||
/* close current file */
|
||||
|
||||
if (fclose(rb_data.pdh) == EOF) {
|
||||
if (err != NULL) {
|
||||
*err = errno;
|
||||
if (fclose(rb_data.pdh) == EOF) {
|
||||
if (err != NULL) {
|
||||
*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.fd = -1;
|
||||
rb_data.pdh = NULL;
|
||||
rb_data.fd = -1;
|
||||
|
||||
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) {
|
||||
fprintf(rb_data.name_h, "%s\n", ringbuf_current_filename());
|
||||
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*/;
|
||||
next_file_index = (rb_data.curr_file_num) % rb_data.num_files;
|
||||
next_rfile = &rb_data.files[next_file_index];
|
||||
rb_data.curr_file_num++ /* = next_file_num*/;
|
||||
next_file_index = (rb_data.curr_file_num) % rb_data.num_files;
|
||||
next_rfile = &rb_data.files[next_file_index];
|
||||
|
||||
if (ringbuf_open_file(next_rfile, err) == -1) {
|
||||
return FALSE;
|
||||
}
|
||||
if (ringbuf_open_file(next_rfile, err) == -1) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ringbuf_init_libpcap_fdopen(err) == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
if (ringbuf_init_libpcap_fdopen(err) == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* switch to the new file */
|
||||
*save_file = next_rfile->name;
|
||||
*save_file_fd = rb_data.fd;
|
||||
(*pdh) = rb_data.pdh;
|
||||
/* switch to the new file */
|
||||
*save_file = next_rfile->name;
|
||||
*save_file_fd = rb_data.fd;
|
||||
(*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
|
||||
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) {
|
||||
fprintf(rb_data.name_h, "%s\n", ringbuf_current_filename());
|
||||
fflush(rb_data.name_h);
|
||||
|
||||
if (EOF == fclose(rb_data.name_h)) {
|
||||
/* Can't really do much about this, can we? */
|
||||
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 */
|
||||
*save_file = rb_data.files[rb_data.curr_file_num % rb_data.num_files].name;
|
||||
return ret_val;
|
||||
/* set the save file name to the current file */
|
||||
*save_file = rb_data.files[rb_data.curr_file_num % rb_data.num_files].name;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -522,28 +529,28 @@ ringbuf_libpcap_dump_close(gchar **save_file, int *err)
|
|||
void
|
||||
ringbuf_free(void)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
|
||||
if (rb_data.files != NULL) {
|
||||
for (i=0; i < rb_data.num_files; i++) {
|
||||
if (rb_data.files[i].name != NULL) {
|
||||
g_free(rb_data.files[i].name);
|
||||
rb_data.files[i].name = NULL;
|
||||
}
|
||||
if (rb_data.files != NULL) {
|
||||
for (i=0; i < rb_data.num_files; i++) {
|
||||
if (rb_data.files[i].name != NULL) {
|
||||
g_free(rb_data.files[i].name);
|
||||
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
|
||||
ringbuf_error_cleanup(void)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
|
||||
/* try to close via wtap */
|
||||
if (rb_data.pdh != NULL) {
|
||||
if (fclose(rb_data.pdh) == 0) {
|
||||
rb_data.fd = -1;
|
||||
/* try to close via wtap */
|
||||
if (rb_data.pdh != NULL) {
|
||||
if (fclose(rb_data.pdh) == 0) {
|
||||
rb_data.fd = -1;
|
||||
}
|
||||
rb_data.pdh = NULL;
|
||||
}
|
||||
rb_data.pdh = NULL;
|
||||
}
|
||||
|
||||
/* close directly if still open */
|
||||
if (rb_data.fd != -1) {
|
||||
ws_close(rb_data.fd);
|
||||
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);
|
||||
}
|
||||
/* close directly if still open */
|
||||
if (rb_data.fd != -1) {
|
||||
ws_close(rb_data.fd);
|
||||
rb_data.fd = -1;
|
||||
}
|
||||
}
|
||||
g_free(rb_data.io_buffer);
|
||||
rb_data.io_buffer = NULL;
|
||||
|
||||
if (rb_data.name_h != NULL) {
|
||||
if (EOF == fclose(rb_data.name_h)) {
|
||||
/* Can't really do much about this, can we? */
|
||||
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;
|
||||
|
||||
/* free the memory */
|
||||
ringbuf_free();
|
||||
if (rb_data.name_h != NULL) {
|
||||
if (EOF == fclose(rb_data.name_h)) {
|
||||
/* Can't really do much about this, can we? */
|
||||
}
|
||||
}
|
||||
|
||||
/* free the memory */
|
||||
ringbuf_free();
|
||||
}
|
||||
|
||||
#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:
|
||||
*/
|
||||
|
|
13
ringbuffer.h
13
ringbuffer.h
|
@ -37,16 +37,3 @@ void ringbuf_error_cleanup(void);
|
|||
gboolean ringbuf_set_print_name(gchar *name, int *err);
|
||||
|
||||
#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:
|
||||
*/
|
||||
|
|
617
sharkd_daemon.c
617
sharkd_daemon.c
|
@ -56,303 +56,303 @@ static socket_handle_t _server_fd = INVALID_SOCKET;
|
|||
static socket_handle_t
|
||||
socket_init(char *path)
|
||||
{
|
||||
socket_handle_t fd = INVALID_SOCKET;
|
||||
char *err_msg;
|
||||
socket_handle_t fd = INVALID_SOCKET;
|
||||
char *err_msg;
|
||||
|
||||
err_msg = ws_init_sockets();
|
||||
if (err_msg != NULL) {
|
||||
ws_warning("ERROR: %s", err_msg);
|
||||
g_free(err_msg);
|
||||
ws_warning("%s", please_report_bug());
|
||||
return fd;
|
||||
}
|
||||
err_msg = ws_init_sockets();
|
||||
if (err_msg != NULL) {
|
||||
ws_warning("ERROR: %s", err_msg);
|
||||
g_free(err_msg);
|
||||
ws_warning("%s", please_report_bug());
|
||||
return fd;
|
||||
}
|
||||
|
||||
#ifdef SHARKD_UNIX_SUPPORT
|
||||
if (!strncmp(path, "unix:", 5))
|
||||
{
|
||||
struct sockaddr_un s_un;
|
||||
socklen_t s_un_len;
|
||||
if (!strncmp(path, "unix:", 5))
|
||||
{
|
||||
struct sockaddr_un s_un;
|
||||
socklen_t s_un_len;
|
||||
|
||||
path += 5;
|
||||
path += 5;
|
||||
|
||||
if (strlen(path) + 1 > sizeof(s_un.sun_path))
|
||||
return INVALID_SOCKET;
|
||||
if (strlen(path) + 1 > sizeof(s_un.sun_path))
|
||||
return INVALID_SOCKET;
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
memset(&s_un, 0, sizeof(s_un));
|
||||
s_un.sun_family = AF_UNIX;
|
||||
(void) g_strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path));
|
||||
memset(&s_un, 0, sizeof(s_un));
|
||||
s_un.sun_family = AF_UNIX;
|
||||
(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] == '@')
|
||||
s_un.sun_path[0] = '\0';
|
||||
if (s_un.sun_path[0] == '@')
|
||||
s_un.sun_path[0] = '\0';
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &s_un, s_un_len))
|
||||
{
|
||||
closesocket(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (bind(fd, (struct sockaddr *) &s_un, s_un_len))
|
||||
{
|
||||
closesocket(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
#ifdef SHARKD_TCP_SUPPORT
|
||||
if (!strncmp(path, "tcp:", 4))
|
||||
{
|
||||
struct sockaddr_in s_in;
|
||||
int one = 1;
|
||||
char *port_sep;
|
||||
guint16 port;
|
||||
if (!strncmp(path, "tcp:", 4))
|
||||
{
|
||||
struct sockaddr_in s_in;
|
||||
int one = 1;
|
||||
char *port_sep;
|
||||
guint16 port;
|
||||
|
||||
path += 4;
|
||||
path += 4;
|
||||
|
||||
port_sep = strchr(path, ':');
|
||||
if (!port_sep)
|
||||
return INVALID_SOCKET;
|
||||
port_sep = strchr(path, ':');
|
||||
if (!port_sep)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
*port_sep = '\0';
|
||||
*port_sep = '\0';
|
||||
|
||||
if (ws_strtou16(port_sep + 1, NULL, &port) == FALSE)
|
||||
return INVALID_SOCKET;
|
||||
if (ws_strtou16(port_sep + 1, NULL, &port) == FALSE)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Need to use WSASocket() to disable overlapped I/O operations,
|
||||
this way on windows SOCKET can be used as HANDLE for stdin/stdout */
|
||||
fd = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
|
||||
/* Need to use WSASocket() to disable overlapped I/O operations,
|
||||
this way on windows SOCKET can be used as HANDLE for stdin/stdout */
|
||||
fd = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
|
||||
#else
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
#endif
|
||||
if (fd == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
if (fd == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
s_in.sin_family = AF_INET;
|
||||
ws_inet_pton4(path, &(s_in.sin_addr.s_addr));
|
||||
s_in.sin_port = g_htons(port);
|
||||
*port_sep = ':';
|
||||
s_in.sin_family = AF_INET;
|
||||
ws_inet_pton4(path, &(s_in.sin_addr.s_addr));
|
||||
s_in.sin_port = g_htons(port);
|
||||
*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)))
|
||||
{
|
||||
closesocket(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (bind(fd, (struct sockaddr *) &s_in, sizeof(struct sockaddr_in)))
|
||||
{
|
||||
closesocket(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
{
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (listen(fd, SOMAXCONN))
|
||||
{
|
||||
closesocket(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
if (listen(fd, SOMAXCONN))
|
||||
{
|
||||
closesocket(fd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static void
|
||||
print_usage(FILE* output)
|
||||
{
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Usage: sharkd [<classic_options>|<gold_options>]\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Usage: sharkd [<classic_options>|<gold_options>]\n");
|
||||
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Classic (classic_options):\n");
|
||||
fprintf(output, " [-|<socket>]\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, " <socket> examples:\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Classic (classic_options):\n");
|
||||
fprintf(output, " [-|<socket>]\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, " <socket> examples:\n");
|
||||
#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
|
||||
#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
|
||||
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Gold (gold_options):\n");
|
||||
fprintf(output, " -a <socket>, --api <socket>\n");
|
||||
fprintf(output, " listen on this socket\n");
|
||||
fprintf(output, " -h, --help show this help information\n");
|
||||
fprintf(output, " -v, --version show version information\n");
|
||||
fprintf(output, " -C <config profile>, --config-profile <config profile>\n");
|
||||
fprintf(output, " start with specified configuration profile\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "Gold (gold_options):\n");
|
||||
fprintf(output, " -a <socket>, --api <socket>\n");
|
||||
fprintf(output, " listen on this socket\n");
|
||||
fprintf(output, " -h, --help show this help information\n");
|
||||
fprintf(output, " -v, --version show version information\n");
|
||||
fprintf(output, " -C <config profile>, --config-profile <config profile>\n");
|
||||
fprintf(output, " start with specified configuration profile\n");
|
||||
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, " Examples:\n");
|
||||
fprintf(output, " sharkd -C myprofile\n");
|
||||
fprintf(output, " sharkd -a tcp:127.0.0.1:4446 -C myprofile\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, " Examples:\n");
|
||||
fprintf(output, " sharkd -C myprofile\n");
|
||||
fprintf(output, " sharkd -a tcp:127.0.0.1:4446 -C myprofile\n");
|
||||
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "See the sharkd page of the Wireshark wiki for full details.\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "See the sharkd page of the Wireshark wiki for full details.\n");
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
sharkd_init(int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
* The leading + ensures that getopt_long() does not permute the argv[]
|
||||
* entries.
|
||||
*
|
||||
* We have to make sure that the first getopt_long() preserves the content
|
||||
* of argv[] for the subsequent getopt_long() call.
|
||||
*
|
||||
* 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
|
||||
* platforms, and so that, if we ever need to process a long argument before
|
||||
* doing further initialization, we can do so.
|
||||
*
|
||||
* Glibc and Solaris libc document that a leading + disables permutation
|
||||
* of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
|
||||
* and macOS don't document it, but do so anyway.
|
||||
*
|
||||
* We do *not* use a leading - because the behavior of a leading - is
|
||||
* platform-dependent.
|
||||
*/
|
||||
/*
|
||||
* The leading + ensures that getopt_long() does not permute the argv[]
|
||||
* entries.
|
||||
*
|
||||
* We have to make sure that the first getopt_long() preserves the content
|
||||
* of argv[] for the subsequent getopt_long() call.
|
||||
*
|
||||
* 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
|
||||
* platforms, and so that, if we ever need to process a long argument before
|
||||
* doing further initialization, we can do so.
|
||||
*
|
||||
* Glibc and Solaris libc document that a leading + disables permutation
|
||||
* of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
|
||||
* and macOS don't document it, but do so anyway.
|
||||
*
|
||||
* We do *not* use a leading - because the behavior of a leading - is
|
||||
* platform-dependent.
|
||||
*/
|
||||
|
||||
#define OPTSTRING "+" "a:hmvC:"
|
||||
|
||||
static const char optstring[] = OPTSTRING;
|
||||
static const char optstring[] = OPTSTRING;
|
||||
|
||||
// right now we don't have any long options
|
||||
static const struct ws_option long_options[] = {
|
||||
{"api", ws_required_argument, NULL, 'a'},
|
||||
{"help", ws_no_argument, NULL, 'h'},
|
||||
{"version", ws_no_argument, NULL, 'v'},
|
||||
{"config-profile", ws_required_argument, NULL, 'C'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
// right now we don't have any long options
|
||||
static const struct ws_option long_options[] = {
|
||||
{"api", ws_required_argument, NULL, 'a'},
|
||||
{"help", ws_no_argument, NULL, 'h'},
|
||||
{"version", ws_no_argument, NULL, 'v'},
|
||||
{"config-profile", ws_required_argument, NULL, 'C'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
int opt;
|
||||
int opt;
|
||||
|
||||
#ifndef _WIN32
|
||||
pid_t pid;
|
||||
pid_t pid;
|
||||
#endif
|
||||
socket_handle_t fd;
|
||||
socket_handle_t fd;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
print_usage(stderr);
|
||||
return -1;
|
||||
}
|
||||
if (argc < 2)
|
||||
{
|
||||
print_usage(stderr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check for classic command line
|
||||
if (!strcmp(argv[1], "-") || argv[1][0] == 't' || argv[1][0] == 'u')
|
||||
{
|
||||
mode = SHARKD_MODE_CLASSIC_CONSOLE;
|
||||
// check for classic command line
|
||||
if (!strcmp(argv[1], "-") || argv[1][0] == 't' || argv[1][0] == 'u')
|
||||
{
|
||||
mode = SHARKD_MODE_CLASSIC_CONSOLE;
|
||||
|
||||
#ifndef _WIN32
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
#endif
|
||||
|
||||
if (!strcmp(argv[1], "-"))
|
||||
{
|
||||
mode = SHARKD_MODE_CLASSIC_CONSOLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = socket_init(argv[1]);
|
||||
if (fd == INVALID_SOCKET)
|
||||
return -1;
|
||||
_server_fd = fd;
|
||||
mode = SHARKD_MODE_CLASSIC_DAEMON;
|
||||
}
|
||||
}
|
||||
else
|
||||
mode = SHARKD_MODE_GOLD_CONSOLE; // assume we are running as gold console
|
||||
if (!strcmp(argv[1], "-"))
|
||||
{
|
||||
mode = SHARKD_MODE_CLASSIC_CONSOLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = socket_init(argv[1]);
|
||||
if (fd == INVALID_SOCKET)
|
||||
return -1;
|
||||
_server_fd = fd;
|
||||
mode = SHARKD_MODE_CLASSIC_DAEMON;
|
||||
}
|
||||
}
|
||||
else
|
||||
mode = SHARKD_MODE_GOLD_CONSOLE; // assume we are running as gold console
|
||||
|
||||
if (mode >= SHARKD_MODE_GOLD_CONSOLE)
|
||||
{
|
||||
/*
|
||||
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
|
||||
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
|
||||
the command line: sharkd -
|
||||
if (mode >= SHARKD_MODE_GOLD_CONSOLE)
|
||||
{
|
||||
/*
|
||||
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
|
||||
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
|
||||
the command line: sharkd -
|
||||
|
||||
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
|
||||
parameter removed. Invoking a second time with the -a option will cause a loop
|
||||
where we repeatedly spawn a new session process.
|
||||
*/
|
||||
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
|
||||
parameter removed. Invoking a second time with the -a option will cause a loop
|
||||
where we repeatedly spawn a new session process.
|
||||
*/
|
||||
|
||||
do {
|
||||
if (ws_optind > (argc - 1))
|
||||
break;
|
||||
do {
|
||||
if (ws_optind > (argc - 1))
|
||||
break;
|
||||
|
||||
opt = ws_getopt_long(argc, argv, optstring, long_options, NULL);
|
||||
opt = ws_getopt_long(argc, argv, optstring, long_options, NULL);
|
||||
|
||||
switch (opt) {
|
||||
case 'C': /* Configuration Profile */
|
||||
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
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Configuration Profile \"%s\" does not exist\n", ws_optarg);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
switch (opt) {
|
||||
case 'C': /* Configuration Profile */
|
||||
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
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Configuration Profile \"%s\" does not exist\n", ws_optarg);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
fd = socket_init(ws_optarg);
|
||||
if (fd == INVALID_SOCKET)
|
||||
return -1;
|
||||
_server_fd = fd;
|
||||
case 'a':
|
||||
fd = socket_init(ws_optarg);
|
||||
if (fd == INVALID_SOCKET)
|
||||
return -1;
|
||||
_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;
|
||||
break;
|
||||
mode = SHARKD_MODE_GOLD_DAEMON;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_usage(stderr);
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
print_usage(stderr);
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
// m is an internal-only option used when the daemon session process is created
|
||||
mode = SHARKD_MODE_GOLD_CONSOLE;
|
||||
break;
|
||||
case 'm':
|
||||
// m is an internal-only option used when the daemon session process is created
|
||||
mode = SHARKD_MODE_GOLD_CONSOLE;
|
||||
break;
|
||||
|
||||
case 'v': /* Show version and exit */
|
||||
show_version();
|
||||
exit(0);
|
||||
break;
|
||||
case 'v': /* Show version and exit */
|
||||
show_version();
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!ws_optopt)
|
||||
fprintf(stderr, "This option isn't supported: %s\n", argv[ws_optind]);
|
||||
fprintf(stderr, "Use sharkd -h for details of supported options\n");
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
} while (opt != -1);
|
||||
}
|
||||
default:
|
||||
if (!ws_optopt)
|
||||
fprintf(stderr, "This option isn't supported: %s\n", argv[ws_optind]);
|
||||
fprintf(stderr, "Use sharkd -h for details of supported options\n");
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
} while (opt != -1);
|
||||
}
|
||||
|
||||
if (mode == SHARKD_MODE_CLASSIC_DAEMON || mode == SHARKD_MODE_GOLD_DAEMON)
|
||||
{
|
||||
/* all good - try to daemonize */
|
||||
if (mode == SHARKD_MODE_CLASSIC_DAEMON || mode == SHARKD_MODE_GOLD_DAEMON)
|
||||
{
|
||||
/* all good - try to daemonize */
|
||||
#ifndef _WIN32
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
fprintf(stderr, "cannot go to background fork() failed: %s\n", g_strerror(errno));
|
||||
pid = fork();
|
||||
if (pid == -1)
|
||||
fprintf(stderr, "cannot go to background fork() failed: %s\n", g_strerror(errno));
|
||||
|
||||
if (pid != 0)
|
||||
{
|
||||
/* parent */
|
||||
exit(0);
|
||||
}
|
||||
if (pid != 0)
|
||||
{
|
||||
/* parent */
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -362,118 +362,105 @@ sharkd_loop(int argc _U_, char* argv[] _U_)
|
|||
sharkd_loop(int argc _U_, char* argv[])
|
||||
#endif
|
||||
{
|
||||
if (mode == SHARKD_MODE_CLASSIC_CONSOLE || mode == SHARKD_MODE_GOLD_CONSOLE)
|
||||
{
|
||||
return sharkd_session_main(mode);
|
||||
}
|
||||
if (mode == SHARKD_MODE_CLASSIC_CONSOLE || mode == SHARKD_MODE_GOLD_CONSOLE)
|
||||
{
|
||||
return sharkd_session_main(mode);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
pid_t pid;
|
||||
pid_t pid;
|
||||
#else
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
char *exename;
|
||||
char command_line[2048];
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFO si;
|
||||
char *exename;
|
||||
char command_line[2048];
|
||||
#endif
|
||||
socket_handle_t fd;
|
||||
socket_handle_t fd;
|
||||
|
||||
fd = accept(_server_fd, NULL, NULL);
|
||||
if (fd == INVALID_SOCKET)
|
||||
{
|
||||
fprintf(stderr, "cannot accept(): %s\n", g_strerror(errno));
|
||||
continue;
|
||||
}
|
||||
fd = accept(_server_fd, NULL, NULL);
|
||||
if (fd == INVALID_SOCKET)
|
||||
{
|
||||
fprintf(stderr, "cannot accept(): %s\n", g_strerror(errno));
|
||||
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
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
closesocket(_server_fd);
|
||||
/* redirect stdin, stdout to socket */
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
close(fd);
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
closesocket(_server_fd);
|
||||
/* redirect stdin, stdout to socket */
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
close(fd);
|
||||
|
||||
exit(sharkd_session_main(mode));
|
||||
}
|
||||
exit(sharkd_session_main(mode));
|
||||
}
|
||||
|
||||
if (pid == -1)
|
||||
{
|
||||
fprintf(stderr, "cannot fork(): %s\n", g_strerror(errno));
|
||||
}
|
||||
if (pid == -1)
|
||||
{
|
||||
fprintf(stderr, "cannot fork(): %s\n", g_strerror(errno));
|
||||
}
|
||||
|
||||
#else
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
memset(&si, 0, sizeof(si));
|
||||
memset(&pi, 0, sizeof(pi));
|
||||
memset(&si, 0, sizeof(si));
|
||||
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
||||
si.hStdInput = (HANDLE) fd;
|
||||
si.hStdOutput = (HANDLE) fd;
|
||||
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
|
||||
si.hStdInput = (HANDLE) fd;
|
||||
si.hStdOutput = (HANDLE) fd;
|
||||
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
|
||||
// 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));
|
||||
// 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
|
||||
memset(&command_line, 0, sizeof(command_line));
|
||||
|
||||
if (mode <= SHARKD_MODE_CLASSIC_DAEMON)
|
||||
{
|
||||
(void) g_strlcat(command_line, "sharkd.exe -", sizeof(command_line));
|
||||
}
|
||||
else
|
||||
{
|
||||
// The -m option used here is an internal-only option that notifies the child process that it should
|
||||
// run in Gold Console mode
|
||||
(void) g_strlcat(command_line, "sharkd.exe -m", sizeof(command_line));
|
||||
if (mode <= SHARKD_MODE_CLASSIC_DAEMON)
|
||||
{
|
||||
(void) g_strlcat(command_line, "sharkd.exe -", sizeof(command_line));
|
||||
}
|
||||
else
|
||||
{
|
||||
// The -m option used here is an internal-only option that notifies the child process that it should
|
||||
// run in Gold Console mode
|
||||
(void) g_strlcat(command_line, "sharkd.exe -m", sizeof(command_line));
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (
|
||||
!g_ascii_strncasecmp(argv[i], "-a", (guint)strlen(argv[i]))
|
||||
|| !g_ascii_strncasecmp(argv[i], "--api", (guint)strlen(argv[i]))
|
||||
)
|
||||
{
|
||||
i++; // skip the socket details
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) g_strlcat(command_line, " ", sizeof(command_line));
|
||||
(void) g_strlcat(command_line, argv[i], sizeof(command_line));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (
|
||||
!g_ascii_strncasecmp(argv[i], "-a", (guint)strlen(argv[i]))
|
||||
|| !g_ascii_strncasecmp(argv[i], "--api", (guint)strlen(argv[i]))
|
||||
)
|
||||
{
|
||||
i++; // skip the socket details
|
||||
}
|
||||
else
|
||||
{
|
||||
(void) g_strlcat(command_line, " ", 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))
|
||||
{
|
||||
fprintf(stderr, "win32_create_process(%s) failed\n", exename);
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
if (!win32_create_process(exename, command_line, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
|
||||
{
|
||||
fprintf(stderr, "win32_create_process(%s) failed\n", exename);
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(pi.hThread);
|
||||
}
|
||||
|
||||
g_free(exename);
|
||||
g_free(exename);
|
||||
#endif
|
||||
|
||||
closesocket(fd);
|
||||
}
|
||||
return 0;
|
||||
closesocket(fd);
|
||||
}
|
||||
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:
|
||||
*/
|
||||
|
|
6447
sharkd_session.c
6447
sharkd_session.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue