aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Perry <boolean263@protonmail.com>2022-02-20 19:39:37 +0000
committerA Wireshark GitLab Utility <6629907-ws-gitlab-utility@users.noreply.gitlab.com>2022-02-20 19:39:37 +0000
commit70d432c35724b23cfb1f6d80773b520523a65f75 (patch)
tree400adbe2036a9a1ca066ad7d5b2dd0a13816d436
parent695ce22b0d8fc18a3c492d99b0d774e6d77dd744 (diff)
Remove editor modelines and .editorconfig exceptions from root files
-rw-r--r--.editorconfig48
-rw-r--r--capinfos.c2958
-rw-r--r--captype.c231
-rw-r--r--cfile.c17
-rw-r--r--cfile.h175
-rw-r--r--dftest.c233
-rw-r--r--file.c8197
-rw-r--r--file.h13
-rw-r--r--frame_tvbuff.c423
-rw-r--r--frame_tvbuff.h13
-rw-r--r--mergecap.c661
-rw-r--r--randpkt.c389
-rw-r--r--ringbuffer.c770
-rw-r--r--ringbuffer.h13
-rw-r--r--sharkd.c1026
-rw-r--r--sharkd_daemon.c675
-rw-r--r--sharkd_session.c7407
-rw-r--r--tfshark.c3451
-rw-r--r--tshark.c7352
19 files changed, 16899 insertions, 17153 deletions
diff --git a/.editorconfig b/.editorconfig
index fc0aed1765..b06b9e1ee2 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -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
diff --git a/capinfos.c b/capinfos.c
index 06572c626b..684dc79132 100644
--- a/capinfos.c
+++ b/capinfos.c
@@ -38,7 +38,6 @@
* (Previously a success status was always
* returned if the -C option was not used).
*
-
*/
@@ -170,47 +169,47 @@ static guint num_decryption_secrets;
* Otherwise, we have no idea.
*/
typedef enum {
- IN_ORDER,
- NOT_IN_ORDER,
- ORDER_UNKNOWN
+ IN_ORDER,
+ NOT_IN_ORDER,
+ ORDER_UNKNOWN
} order_t;
typedef struct _capture_info {
- const char *filename;
- guint16 file_type;
- wtap_compression_type compression_type;
- int file_encap;
- int file_tsprec;
- wtap *wth;
- gint64 filesize;
- guint64 packet_bytes;
- gboolean times_known;
- nstime_t start_time;
- int start_time_tsprec;
- nstime_t stop_time;
- int stop_time_tsprec;
- guint32 packet_count;
- gboolean snap_set; /* If set in capture file header */
- guint32 snaplen; /* value from the capture file header */
- guint32 snaplen_min_inferred; /* If caplen < len for 1 or more rcds */
- guint32 snaplen_max_inferred; /* ... */
- gboolean drops_known;
- guint32 drop_count;
-
- nstime_t duration;
- int duration_tsprec;
- double packet_rate;
- double packet_size;
- double data_rate; /* in bytes/s */
- gboolean know_order;
- order_t order;
-
- int *encap_counts; /* array of per_packet encap counts; array has one entry per wtap_encap type */
-
- guint num_interfaces; /* number of IDBs, and thus size of interface_packet_counts array */
- GArray *interface_packet_counts; /* array of per_packet interface_id counts; one entry per file IDB */
- guint32 pkt_interface_id_unknown; /* counts if packet interface_id didn't match a known one */
- GArray *idb_info_strings; /* array of IDB info strings */
+ const char *filename;
+ guint16 file_type;
+ wtap_compression_type compression_type;
+ int file_encap;
+ int file_tsprec;
+ wtap *wth;
+ gint64 filesize;
+ guint64 packet_bytes;
+ gboolean times_known;
+ nstime_t start_time;
+ int start_time_tsprec;
+ nstime_t stop_time;
+ int stop_time_tsprec;
+ guint32 packet_count;
+ gboolean snap_set; /* If set in capture file header */
+ guint32 snaplen; /* value from the capture file header */
+ guint32 snaplen_min_inferred; /* If caplen < len for 1 or more rcds */
+ guint32 snaplen_max_inferred; /* ... */
+ gboolean drops_known;
+ guint32 drop_count;
+
+ nstime_t duration;
+ int duration_tsprec;
+ double packet_rate;
+ double packet_size;
+ double data_rate; /* in bytes/s */
+ gboolean know_order;
+ order_t order;
+
+ int *encap_counts; /* array of per_packet encap counts; array has one entry per wtap_encap type */
+
+ guint num_interfaces; /* number of IDBs, and thus size of interface_packet_counts array */
+ GArray *interface_packet_counts; /* array of per_packet interface_id counts; one entry per file IDB */
+ guint32 pkt_interface_id_unknown; /* counts if packet interface_id didn't match a known one */
+ GArray *idb_info_strings; /* array of IDB info strings */
} capture_info;
static char *decimal_point;
@@ -218,368 +217,369 @@ static char *decimal_point;
static void
enable_all_infos(void)
{
- report_all_infos = TRUE;
-
- cap_file_type = TRUE;
- cap_file_encap = TRUE;
- cap_snaplen = TRUE;
- cap_packet_count = TRUE;
- cap_file_size = TRUE;
- cap_comment = TRUE;
- cap_file_more_info = TRUE;
- cap_file_idb = TRUE;
- cap_file_nrb = TRUE;
- cap_file_dsb = TRUE;
-
- cap_data_size = TRUE;
- cap_duration = TRUE;
- cap_start_time = TRUE;
- cap_end_time = TRUE;
- cap_order = TRUE;
-
- cap_data_rate_byte = TRUE;
- cap_data_rate_bit = TRUE;
- cap_packet_size = TRUE;
- cap_packet_rate = TRUE;
-
- cap_file_hashes = TRUE;
+ report_all_infos = TRUE;
+
+ cap_file_type = TRUE;
+ cap_file_encap = TRUE;
+ cap_snaplen = TRUE;
+ cap_packet_count = TRUE;
+ cap_file_size = TRUE;
+ cap_comment = TRUE;
+ cap_file_more_info = TRUE;
+ cap_file_idb = TRUE;
+ cap_file_nrb = TRUE;
+ cap_file_dsb = TRUE;
+
+ cap_data_size = TRUE;
+ cap_duration = TRUE;
+ cap_start_time = TRUE;
+ cap_end_time = TRUE;
+ cap_order = TRUE;
+
+ cap_data_rate_byte = TRUE;
+ cap_data_rate_bit = TRUE;
+ cap_packet_size = TRUE;
+ cap_packet_rate = TRUE;
+
+ cap_file_hashes = TRUE;
}
static void
disable_all_infos(void)
{
- report_all_infos = FALSE;
-
- cap_file_type = FALSE;
- cap_file_encap = FALSE;
- cap_snaplen = FALSE;
- cap_packet_count = FALSE;
- cap_file_size = FALSE;
- cap_comment = FALSE;
- cap_file_more_info = FALSE;
- cap_file_idb = FALSE;
- cap_file_nrb = FALSE;
- cap_file_dsb = FALSE;
-
- cap_data_size = FALSE;
- cap_duration = FALSE;
- cap_start_time = FALSE;
- cap_end_time = FALSE;
- cap_order = FALSE;
-
- cap_data_rate_byte = FALSE;
- cap_data_rate_bit = FALSE;
- cap_packet_size = FALSE;
- cap_packet_rate = FALSE;
-
- cap_file_hashes = FALSE;
+ report_all_infos = FALSE;
+
+ cap_file_type = FALSE;
+ cap_file_encap = FALSE;
+ cap_snaplen = FALSE;
+ cap_packet_count = FALSE;
+ cap_file_size = FALSE;
+ cap_comment = FALSE;
+ cap_file_more_info = FALSE;
+ cap_file_idb = FALSE;
+ cap_file_nrb = FALSE;
+ cap_file_dsb = FALSE;
+
+ cap_data_size = FALSE;
+ cap_duration = FALSE;
+ cap_start_time = FALSE;
+ cap_end_time = FALSE;
+ cap_order = FALSE;
+
+ cap_data_rate_byte = FALSE;
+ cap_data_rate_bit = FALSE;
+ cap_packet_size = FALSE;
+ cap_packet_rate = FALSE;
+
+ cap_file_hashes = FALSE;
}
static const gchar *
order_string(order_t order)
{
- switch (order) {
+ switch (order) {
- case IN_ORDER:
- return "True";
+ case IN_ORDER:
+ return "True";
- case NOT_IN_ORDER:
- return "False";
+ case NOT_IN_ORDER:
+ return "False";
- case ORDER_UNKNOWN:
- return "Unknown";
+ case ORDER_UNKNOWN:
+ return "Unknown";
- default:
- return "???"; /* "cannot happen" (the next step is "Profit!") */
- }
+ default:
+ return "???"; /* "cannot happen" (the next step is "Profit!") */
+ }
}
static gchar *
absolute_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info)
{
- /*
- * https://web.archive.org/web/20120513133703/http://www.idrbt.ac.in/publications/workingpapers/Working%20Paper%20No.%209.pdf
- *
- * says:
- *
- * A 64-bit Unix time would be safe for the indefinite future, as
- * this variable would not overflow until 2**63 or
- * 9,223,372,036,854,775,808 (over nine quintillion) seconds
- * after the beginning of the Unix epoch - corresponding to
- * GMT 15:30:08, Sunday, 4th December, 292,277,026,596.
- *
- * So, if we're displaying the time as YYYY-MM-DD HH:MM:SS.SSSSSSSSS,
- * we'll have the buffer be large enouth for a date of the format
- * 292277026596-MM-DD HH:MM:SS.SSSSSSSSS, which is the biggest value
- * you'll get with a 64-bit time_t and a nanosecond-resolution
- * fraction-of-a-second.
- *
- * That's 12+1+2+1+2+1+2+1+2+2+2+1+9+1, including the terminating
- * \0, or 39.
- *
- * If we're displaying the time as epoch time, and the time is
- * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
- * to be big enough for 18446744073709551615.999999999. That's
- * 20+1+9+1, including the terminating '\0', or 31. If it's
- * signed, 2^63 is 9223372036854775808, so the buffer has to
- * be big enough for -9223372036854775808.999999999, which is
- * again 20+1+9+1, or 31.
- *
- * So we go with 39.
- */
- static gchar time_string_buf[39];
- struct tm *ti_tm;
-
- if (cf_info->times_known && cf_info->packet_count > 0) {
- if (time_as_secs) {
- switch (tsprecision) {
-
- case WTAP_TSPREC_SEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64,
- (gint64)timer->secs);
- break;
-
- case WTAP_TSPREC_DSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%01d",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs / 100000000);
- break;
-
- case WTAP_TSPREC_CSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%02d",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs / 10000000);
- break;
-
- case WTAP_TSPREC_MSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%03d",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs / 1000000);
- break;
-
- case WTAP_TSPREC_USEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%06d",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs / 1000);
- break;
-
- case WTAP_TSPREC_NSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%09d",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs);
- break;
-
- default:
- snprintf(time_string_buf, sizeof time_string_buf,
- "Unknown precision %d",
- tsprecision);
- break;
- }
- return time_string_buf;
- } else {
- ti_tm = localtime(&timer->secs);
- if (ti_tm == NULL) {
- snprintf(time_string_buf, sizeof time_string_buf, "Not representable");
- return time_string_buf;
- }
- switch (tsprecision) {
-
- case WTAP_TSPREC_SEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%04d-%02d-%02d %02d:%02d:%02d",
- ti_tm->tm_year + 1900,
- ti_tm->tm_mon + 1,
- ti_tm->tm_mday,
- ti_tm->tm_hour,
- ti_tm->tm_min,
- ti_tm->tm_sec);
- break;
-
- case WTAP_TSPREC_DSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%04d-%02d-%02d %02d:%02d:%02d%s%01d",
- ti_tm->tm_year + 1900,
- ti_tm->tm_mon + 1,
- ti_tm->tm_mday,
- ti_tm->tm_hour,
- ti_tm->tm_min,
- ti_tm->tm_sec,
- decimal_point,
- timer->nsecs / 100000000);
- break;
-
- case WTAP_TSPREC_CSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%04d-%02d-%02d %02d:%02d:%02d%s%02d",
- ti_tm->tm_year + 1900,
- ti_tm->tm_mon + 1,
- ti_tm->tm_mday,
- ti_tm->tm_hour,
- ti_tm->tm_min,
- ti_tm->tm_sec,
- decimal_point,
- timer->nsecs / 10000000);
- break;
-
- case WTAP_TSPREC_MSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%04d-%02d-%02d %02d:%02d:%02d%s%03d",
- ti_tm->tm_year + 1900,
- ti_tm->tm_mon + 1,
- ti_tm->tm_mday,
- ti_tm->tm_hour,
- ti_tm->tm_min,
- ti_tm->tm_sec,
- decimal_point,
- timer->nsecs / 1000000);
- break;
-
- case WTAP_TSPREC_USEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%04d-%02d-%02d %02d:%02d:%02d%s%06d",
- ti_tm->tm_year + 1900,
- ti_tm->tm_mon + 1,
- ti_tm->tm_mday,
- ti_tm->tm_hour,
- ti_tm->tm_min,
- ti_tm->tm_sec,
- decimal_point,
- timer->nsecs / 1000);
- break;
-
- case WTAP_TSPREC_NSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%04d-%02d-%02d %02d:%02d:%02d%s%09d",
- ti_tm->tm_year + 1900,
- ti_tm->tm_mon + 1,
- ti_tm->tm_mday,
- ti_tm->tm_hour,
- ti_tm->tm_min,
- ti_tm->tm_sec,
- decimal_point,
- timer->nsecs);
- break;
-
- default:
- snprintf(time_string_buf, sizeof time_string_buf,
- "Unknown precision %d",
- tsprecision);
- break;
- }
- return time_string_buf;
+ /*
+ * https://web.archive.org/web/20120513133703/http://www.idrbt.ac.in/publications/workingpapers/Working%20Paper%20No.%209.pdf
+ *
+ * says:
+ *
+ * A 64-bit Unix time would be safe for the indefinite future, as
+ * this variable would not overflow until 2**63 or
+ * 9,223,372,036,854,775,808 (over nine quintillion) seconds
+ * after the beginning of the Unix epoch - corresponding to
+ * GMT 15:30:08, Sunday, 4th December, 292,277,026,596.
+ *
+ * So, if we're displaying the time as YYYY-MM-DD HH:MM:SS.SSSSSSSSS,
+ * we'll have the buffer be large enouth for a date of the format
+ * 292277026596-MM-DD HH:MM:SS.SSSSSSSSS, which is the biggest value
+ * you'll get with a 64-bit time_t and a nanosecond-resolution
+ * fraction-of-a-second.
+ *
+ * That's 12+1+2+1+2+1+2+1+2+2+2+1+9+1, including the terminating
+ * \0, or 39.
+ *
+ * If we're displaying the time as epoch time, and the time is
+ * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
+ * to be big enough for 18446744073709551615.999999999. That's
+ * 20+1+9+1, including the terminating '\0', or 31. If it's
+ * signed, 2^63 is 9223372036854775808, so the buffer has to
+ * be big enough for -9223372036854775808.999999999, which is
+ * again 20+1+9+1, or 31.
+ *
+ * So we go with 39.
+ */
+ static gchar time_string_buf[39];
+ struct tm *ti_tm;
+
+ if (cf_info->times_known && cf_info->packet_count > 0) {
+ if (time_as_secs) {
+ switch (tsprecision) {
+
+ case WTAP_TSPREC_SEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64,
+ (gint64)timer->secs);
+ break;
+
+ case WTAP_TSPREC_DSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%01d",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs / 100000000);
+ break;
+
+ case WTAP_TSPREC_CSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%02d",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs / 10000000);
+ break;
+
+ case WTAP_TSPREC_MSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%03d",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs / 1000000);
+ break;
+
+ case WTAP_TSPREC_USEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%06d",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs / 1000);
+ break;
+
+ case WTAP_TSPREC_NSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%09d",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs);
+ break;
+
+ default:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "Unknown precision %d",
+ tsprecision);
+ break;
+ }
+ return time_string_buf;
+ } else {
+ ti_tm = localtime(&timer->secs);
+ if (ti_tm == NULL) {
+ snprintf(time_string_buf, sizeof time_string_buf, "Not representable");
+ return time_string_buf;
+ }
+ switch (tsprecision) {
+
+ case WTAP_TSPREC_SEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%04d-%02d-%02d %02d:%02d:%02d",
+ ti_tm->tm_year + 1900,
+ ti_tm->tm_mon + 1,
+ ti_tm->tm_mday,
+ ti_tm->tm_hour,
+ ti_tm->tm_min,
+ ti_tm->tm_sec);
+ break;
+
+ case WTAP_TSPREC_DSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%04d-%02d-%02d %02d:%02d:%02d%s%01d",
+ ti_tm->tm_year + 1900,
+ ti_tm->tm_mon + 1,
+ ti_tm->tm_mday,
+ ti_tm->tm_hour,
+ ti_tm->tm_min,
+ ti_tm->tm_sec,
+ decimal_point,
+ timer->nsecs / 100000000);
+ break;
+
+ case WTAP_TSPREC_CSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%04d-%02d-%02d %02d:%02d:%02d%s%02d",
+ ti_tm->tm_year + 1900,
+ ti_tm->tm_mon + 1,
+ ti_tm->tm_mday,
+ ti_tm->tm_hour,
+ ti_tm->tm_min,
+ ti_tm->tm_sec,
+ decimal_point,
+ timer->nsecs / 10000000);
+ break;
+
+ case WTAP_TSPREC_MSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%04d-%02d-%02d %02d:%02d:%02d%s%03d",
+ ti_tm->tm_year + 1900,
+ ti_tm->tm_mon + 1,
+ ti_tm->tm_mday,
+ ti_tm->tm_hour,
+ ti_tm->tm_min,
+ ti_tm->tm_sec,
+ decimal_point,
+ timer->nsecs / 1000000);
+ break;
+
+ case WTAP_TSPREC_USEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%04d-%02d-%02d %02d:%02d:%02d%s%06d",
+ ti_tm->tm_year + 1900,
+ ti_tm->tm_mon + 1,
+ ti_tm->tm_mday,
+ ti_tm->tm_hour,
+ ti_tm->tm_min,
+ ti_tm->tm_sec,
+ decimal_point,
+ timer->nsecs / 1000);
+ break;
+
+ case WTAP_TSPREC_NSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%04d-%02d-%02d %02d:%02d:%02d%s%09d",
+ ti_tm->tm_year + 1900,
+ ti_tm->tm_mon + 1,
+ ti_tm->tm_mday,
+ ti_tm->tm_hour,
+ ti_tm->tm_min,
+ ti_tm->tm_sec,
+ decimal_point,
+ timer->nsecs);
+ break;
+
+ default:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "Unknown precision %d",
+ tsprecision);
+ break;
+ }
+ return time_string_buf;
+ }
}
- }
- snprintf(time_string_buf, sizeof time_string_buf, "n/a");
- return time_string_buf;
+ snprintf(time_string_buf, sizeof time_string_buf, "n/a");
+ return time_string_buf;
}
static gchar *
relative_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info, gboolean want_seconds)
{
- const gchar *second = want_seconds ? " second" : "";
- const gchar *plural = want_seconds ? "s" : "";
- /*
- * If we're displaying the time as epoch time, and the time is
- * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
- * to be big enough for "18446744073709551615.999999999 seconds".
- * That's 20+1+9+1+7+1, including the terminating '\0', or 39.
- * If it'ssigned, 2^63 is 9223372036854775808, so the buffer has to
- * be big enough for "-9223372036854775808.999999999 seconds",
- * which is again 20+1+9+1+7+1, or 39.
- */
- static gchar time_string_buf[39];
-
- if (cf_info->times_known && cf_info->packet_count > 0) {
- switch (tsprecision) {
-
- case WTAP_TSPREC_SEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%s",
- (gint64)timer->secs,
- second,
- timer->secs == 1 ? "" : plural);
- break;
-
- case WTAP_TSPREC_DSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%01d%s%s",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs / 100000000,
- second,
- (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
- break;
-
- case WTAP_TSPREC_CSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%02d%s%s",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs / 10000000,
- second,
- (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
- break;
-
- case WTAP_TSPREC_MSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%03d%s%s",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs / 1000000,
- second,
- (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
- break;
-
- case WTAP_TSPREC_USEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%06d%s%s",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs / 1000,
- second,
- (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
- break;
-
- case WTAP_TSPREC_NSEC:
- snprintf(time_string_buf, sizeof time_string_buf,
- "%"PRId64"%s%09d%s%s",
- (gint64)timer->secs,
- decimal_point,
- timer->nsecs,
- second,
- (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
- break;
-
- default:
- snprintf(time_string_buf, sizeof time_string_buf,
- "Unknown precision %d",
- tsprecision);
- break;
+ const gchar *second = want_seconds ? " second" : "";
+ const gchar *plural = want_seconds ? "s" : "";
+ /*
+ * If we're displaying the time as epoch time, and the time is
+ * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
+ * to be big enough for "18446744073709551615.999999999 seconds".
+ * That's 20+1+9+1+7+1, including the terminating '\0', or 39.
+ * If it'ssigned, 2^63 is 9223372036854775808, so the buffer has to
+ * be big enough for "-9223372036854775808.999999999 seconds",
+ * which is again 20+1+9+1+7+1, or 39.
+ */
+ static gchar time_string_buf[39];
+
+ if (cf_info->times_known && cf_info->packet_count > 0) {
+ switch (tsprecision) {
+
+ case WTAP_TSPREC_SEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%s",
+ (gint64)timer->secs,
+ second,
+ timer->secs == 1 ? "" : plural);
+ break;
+
+ case WTAP_TSPREC_DSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%01d%s%s",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs / 100000000,
+ second,
+ (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
+ break;
+
+ case WTAP_TSPREC_CSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%02d%s%s",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs / 10000000,
+ second,
+ (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
+ break;
+
+ case WTAP_TSPREC_MSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%03d%s%s",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs / 1000000,
+ second,
+ (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
+ break;
+
+ case WTAP_TSPREC_USEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%06d%s%s",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs / 1000,
+ second,
+ (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
+ break;
+
+ case WTAP_TSPREC_NSEC:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "%"PRId64"%s%09d%s%s",
+ (gint64)timer->secs,
+ decimal_point,
+ timer->nsecs,
+ second,
+ (timer->secs == 1 && timer->nsecs == 0) ? "" : plural);
+ break;
+
+ default:
+ snprintf(time_string_buf, sizeof time_string_buf,
+ "Unknown precision %d",
+ tsprecision);
+ break;
+ }
+ return time_string_buf;
}
- return time_string_buf;
- }
- snprintf(time_string_buf, sizeof time_string_buf, "n/a");
- return time_string_buf;
+ snprintf(time_string_buf, sizeof time_string_buf, "n/a");
+ return time_string_buf;
}
-static void print_value(const gchar *text_p1, gint width, const gchar *text_p2, double value) {
- if (value > 0.0)
- printf("%s%.*f%s\n", text_p1, width, value, text_p2);
- else
- printf("%sn/a\n", text_p1);
+static void print_value(const gchar *text_p1, gint width, const gchar *text_p2, double value)
+{
+ if (value > 0.0)
+ printf("%s%.*f%s\n", text_p1, width, value, text_p2);
+ else
+ printf("%sn/a\n", text_p1);
}
/* multi-line comments would conflict with the formatting that capinfos uses
@@ -587,961 +587,962 @@ static void print_value(const gchar *text_p1, gint width, const gchar *text_p2,
static void
string_replace_newlines(gchar *str)
{
- gchar *p;
-
- if (str) {
- p = str;
- while (*p != '\0') {
- if (*p == '\n')
- *p = ' ';
- if (*p == '\r')
- *p = ' ';
- p++;
+ gchar *p;
+
+ if (str) {
+ p = str;
+ while (*p != '\0') {
+ if (*p == '\n')
+ *p = ' ';
+ if (*p == '\r')
+ *p = ' ';
+ p++;
+ }
}
- }
}
static void
show_option_string(const char *prefix, const char *option_str)
{
- char *str;
-
- if (option_str != NULL && option_str[0] != '\0') {
- str = g_strdup(option_str);
- string_replace_newlines(str);
- printf("%s%s\n", prefix, str);
- g_free(str);
- }
+ char *str;
+
+ if (option_str != NULL && option_str[0] != '\0') {
+ str = g_strdup(option_str);
+ string_replace_newlines(str);
+ printf("%s%s\n", prefix, str);
+ g_free(str);
+ }
}
static void
print_stats(const gchar *filename, capture_info *cf_info)
{
- const gchar *file_type_string, *file_encap_string;
- gchar *size_string;
+ const gchar *file_type_string, *file_encap_string;
+ gchar *size_string;
- /* Build printable strings for various stats */
- if (machine_readable) {
- file_type_string = wtap_file_type_subtype_name(cf_info->file_type);
- file_encap_string = wtap_encap_name(cf_info->file_encap);
- }
- else {
- file_type_string = wtap_file_type_subtype_description(cf_info->file_type);
- file_encap_string = wtap_encap_description(cf_info->file_encap);
- }
-
- if (filename) printf ("File name: %s\n", filename);
- if (cap_file_type) {
- const char *compression_type_description;
- compression_type_description = wtap_compression_type_description(cf_info->compression_type);
- if (compression_type_description == NULL)
- printf ("File type: %s\n",
- file_type_string);
- else
- printf ("File type: %s (%s)\n",
- file_type_string, compression_type_description);
- }
- if (cap_file_encap) {
- printf ("File encapsulation: %s\n", file_encap_string);
- if (cf_info->file_encap == WTAP_ENCAP_PER_PACKET) {
- int i;
- printf ("Encapsulation in use by packets (# of pkts):\n");
- for (i=0; i<WTAP_NUM_ENCAP_TYPES; i++) {
- if (cf_info->encap_counts[i] > 0)
- printf(" %s (%d)\n",
- wtap_encap_description(i), cf_info->encap_counts[i]);
- }
- }
- }
- if (cap_file_more_info) {
- printf ("File timestamp precision: %s (%d)\n",
- wtap_tsprec_string(cf_info->file_tsprec), cf_info->file_tsprec);
- }
-
- if (cap_snaplen && cf_info->snap_set)
- printf ("Packet size limit: file hdr: %u bytes\n", cf_info->snaplen);
- else if (cap_snaplen && !cf_info->snap_set)
- printf ("Packet size limit: file hdr: (not set)\n");
- if (cf_info->snaplen_max_inferred > 0) {
- if (cf_info->snaplen_min_inferred == cf_info->snaplen_max_inferred)
- printf ("Packet size limit: inferred: %u bytes\n", cf_info->snaplen_min_inferred);
- else
- printf ("Packet size limit: inferred: %u bytes - %u bytes (range)\n",
- cf_info->snaplen_min_inferred, cf_info->snaplen_max_inferred);
- }
- if (cap_packet_count) {
- printf ("Number of packets: ");
+ /* Build printable strings for various stats */
if (machine_readable) {
- printf ("%u\n", cf_info->packet_count);
- } else {
- size_string = format_size(cf_info->packet_count, FORMAT_SIZE_UNIT_NONE, 0);
- printf ("%s\n", size_string);
- g_free(size_string);
+ file_type_string = wtap_file_type_subtype_name(cf_info->file_type);
+ file_encap_string = wtap_encap_name(cf_info->file_encap);
}
- }
- if (cap_file_size) {
- printf ("File size: ");
- if (machine_readable) {
- printf ("%" PRId64 " bytes\n", cf_info->filesize);
- } else {
- size_string = format_size(cf_info->filesize, FORMAT_SIZE_UNIT_BYTES, 0);
- printf ("%s\n", size_string);
- g_free(size_string);
+ else {
+ file_type_string = wtap_file_type_subtype_description(cf_info->file_type);
+ file_encap_string = wtap_encap_description(cf_info->file_encap);
}
- }
- if (cap_data_size) {
- printf ("Data size: ");
- if (machine_readable) {
- printf ("%" PRIu64 " bytes\n", cf_info->packet_bytes);
- } else {
- size_string = format_size(cf_info->packet_bytes, FORMAT_SIZE_UNIT_BYTES, 0);
- printf ("%s\n", size_string);
- g_free(size_string);
+
+ if (filename) printf ("File name: %s\n", filename);
+ if (cap_file_type) {
+ const char *compression_type_description;
+ compression_type_description = wtap_compression_type_description(cf_info->compression_type);
+ if (compression_type_description == NULL)
+ printf ("File type: %s\n",
+ file_type_string);
+ else
+ printf ("File type: %s (%s)\n",
+ file_type_string, compression_type_description);
}
- }
- if (cf_info->times_known) {
- if (cap_duration) /* XXX - shorten to hh:mm:ss */
- printf("Capture duration: %s\n", relative_time_string(&cf_info->duration, cf_info->duration_tsprec, cf_info, TRUE));
- if (cap_start_time)
- printf("First packet time: %s\n", absolute_time_string(&cf_info->start_time, cf_info->start_time_tsprec, cf_info));
- if (cap_end_time)
- printf("Last packet time: %s\n", absolute_time_string(&cf_info->stop_time, cf_info->stop_time_tsprec, cf_info));
- if (cap_data_rate_byte) {
- printf("Data byte rate: ");
- if (machine_readable) {
- print_value("", 2, " bytes/sec", cf_info->data_rate);
- } else {
- size_string = format_size((int64_t)cf_info->data_rate, FORMAT_SIZE_UNIT_BYTES_S, 0);
- printf ("%s\n", size_string);
- g_free(size_string);
- }
+ if (cap_file_encap) {
+ printf ("File encapsulation: %s\n", file_encap_string);
+ if (cf_info->file_encap == WTAP_ENCAP_PER_PACKET) {
+ int i;
+ printf ("Encapsulation in use by packets (# of pkts):\n");
+ for (i=0; i<WTAP_NUM_ENCAP_TYPES; i++) {
+ if (cf_info->encap_counts[i] > 0)
+ printf(" %s (%d)\n",
+ wtap_encap_description(i), cf_info->encap_counts[i]);
+ }
+ }
}
- if (cap_data_rate_bit) {
- printf("Data bit rate: ");
- if (machine_readable) {
- print_value("", 2, " bits/sec", cf_info->data_rate*8);
- } else {
- size_string = format_size((int64_t)(cf_info->data_rate*8), FORMAT_SIZE_UNIT_BITS_S, 0);
- printf ("%s\n", size_string);
- g_free(size_string);
- }
+ if (cap_file_more_info) {
+ printf ("File timestamp precision: %s (%d)\n",
+ wtap_tsprec_string(cf_info->file_tsprec), cf_info->file_tsprec);
}
- }
- if (cap_packet_size) printf("Average packet size: %.2f bytes\n", cf_info->packet_size);
- if (cf_info->times_known) {
- if (cap_packet_rate) {
- printf("Average packet rate: ");
- if (machine_readable) {
- print_value("", 2, " packets/sec", cf_info->packet_rate);
- } else {
- size_string = format_size((int64_t)cf_info->packet_rate, FORMAT_SIZE_UNIT_PACKETS_S, 0);
- printf ("%s\n", size_string);
- g_free(size_string);
- }
+
+ if (cap_snaplen && cf_info->snap_set)
+ printf ("Packet size limit: file hdr: %u bytes\n", cf_info->snaplen);
+ else if (cap_snaplen && !cf_info->snap_set)
+ printf ("Packet size limit: file hdr: (not set)\n");
+ if (cf_info->snaplen_max_inferred > 0) {
+ if (cf_info->snaplen_min_inferred == cf_info->snaplen_max_inferred)
+ printf ("Packet size limit: inferred: %u bytes\n", cf_info->snaplen_min_inferred);
+ else
+ printf ("Packet size limit: inferred: %u bytes - %u bytes (range)\n",
+ cf_info->snaplen_min_inferred, cf_info->snaplen_max_inferred);
}
- }
- if (cap_file_hashes) {
- printf ("SHA256: %s\n", file_sha256);
- printf ("RIPEMD160: %s\n", file_rmd160);
- printf ("SHA1: %s\n", file_sha1);
- }
- if (cap_order) printf ("Strict time order: %s\n", order_string(cf_info->order));
-
- gboolean has_multiple_sections = (wtap_file_get_num_shbs(cf_info->wth) > 1);
-
- for (guint section_number = 0;
- section_number < wtap_file_get_num_shbs(cf_info->wth);
- section_number++) {
- wtap_block_t shb;
-
- // If we have more than one section, add headers for each section.
- if (has_multiple_sections)
- printf("Section %u:\n\n", section_number);
-
- shb = wtap_file_get_shb(cf_info->wth, section_number);
- if (shb != NULL) {
- if (cap_file_more_info) {
- char *str;
-
- if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS)
- show_option_string("Capture hardware: ", str);
- if (wtap_block_get_string_option_value(shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS)
- show_option_string("Capture oper-sys: ", str);
- if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS)
- show_option_string("Capture application: ", str);
- }
- if (cap_comment) {
- unsigned int i;
- char *str;
-
- for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, i, &str) == WTAP_OPTTYPE_SUCCESS; i++) {
- show_option_string("Capture comment: ", str);
+ if (cap_packet_count) {
+ printf ("Number of packets: ");
+ if (machine_readable) {
+ printf ("%u\n", cf_info->packet_count);
+ } else {
+ size_string = format_size(cf_info->packet_count, FORMAT_SIZE_UNIT_NONE, 0);
+ printf ("%s\n", size_string);
+ g_free(size_string);
}
- }
-
- if (cap_file_idb && cf_info->num_interfaces != 0) {
- guint i;
- ws_assert(cf_info->num_interfaces == cf_info->idb_info_strings->len);
- printf ("Number of interfaces in file: %u\n", cf_info->num_interfaces);
- for (i = 0; i < cf_info->idb_info_strings->len; i++) {
- gchar *s = g_array_index(cf_info->idb_info_strings, gchar*, i);
- guint32 packet_count = 0;
- if (i < cf_info->interface_packet_counts->len)
- packet_count = g_array_index(cf_info->interface_packet_counts, guint32, i);
- printf ("Interface #%u info:\n", i);
- printf ("%s", s);
- printf (" Number of packets = %u\n", packet_count);
+ }
+ if (cap_file_size) {
+ printf ("File size: ");
+ if (machine_readable) {
+ printf ("%" PRId64 " bytes\n", cf_info->filesize);
+ } else {
+ size_string = format_size(cf_info->filesize, FORMAT_SIZE_UNIT_BYTES, 0);
+ printf ("%s\n", size_string);
+ g_free(size_string);
}
- }
}
-
- if (cap_file_nrb) {
- if (num_ipv4_addresses != 0)
- printf ("Number of resolved IPv4 addresses in file: %u\n", num_ipv4_addresses);
- if (num_ipv6_addresses != 0)
- printf ("Number of resolved IPv6 addresses in file: %u\n", num_ipv6_addresses);
+ if (cap_data_size) {
+ printf ("Data size: ");
+ if (machine_readable) {
+ printf ("%" PRIu64 " bytes\n", cf_info->packet_bytes);
+ } else {
+ size_string = format_size(cf_info->packet_bytes, FORMAT_SIZE_UNIT_BYTES, 0);
+ printf ("%s\n", size_string);
+ g_free(size_string);
+ }
+ }
+ if (cf_info->times_known) {
+ if (cap_duration) /* XXX - shorten to hh:mm:ss */
+ printf("Capture duration: %s\n", relative_time_string(&cf_info->duration, cf_info->duration_tsprec, cf_info, TRUE));
+ if (cap_start_time)
+ printf("First packet time: %s\n", absolute_time_string(&cf_info->start_time, cf_info->start_time_tsprec, cf_info));
+ if (cap_end_time)
+ printf("Last packet time: %s\n", absolute_time_string(&cf_info->stop_time, cf_info->stop_time_tsprec, cf_info));
+ if (cap_data_rate_byte) {
+ printf("Data byte rate: ");
+ if (machine_readable) {
+ print_value("", 2, " bytes/sec", cf_info->data_rate);
+ } else {
+ size_string = format_size((int64_t)cf_info->data_rate, FORMAT_SIZE_UNIT_BYTES_S, 0);
+ printf ("%s\n", size_string);
+ g_free(size_string);
+ }
+ }
+ if (cap_data_rate_bit) {
+ printf("Data bit rate: ");
+ if (machine_readable) {
+ print_value("", 2, " bits/sec", cf_info->data_rate*8);
+ } else {
+ size_string = format_size((int64_t)(cf_info->data_rate*8), FORMAT_SIZE_UNIT_BITS_S, 0);
+ printf ("%s\n", size_string);
+ g_free(size_string);
+ }
+ }
+ }
+ if (cap_packet_size) printf("Average packet size: %.2f bytes\n", cf_info->packet_size);
+ if (cf_info->times_known) {
+ if (cap_packet_rate) {
+ printf("Average packet rate: ");
+ if (machine_readable) {
+ print_value("", 2, " packets/sec", cf_info->packet_rate);
+ } else {
+ size_string = format_size((int64_t)cf_info->packet_rate, FORMAT_SIZE_UNIT_PACKETS_S, 0);
+ printf ("%s\n", size_string);
+ g_free(size_string);
+ }
+ }
}
- if (cap_file_dsb) {
- if (num_decryption_secrets != 0)
- printf ("Number of decryption secrets in file: %u\n", num_decryption_secrets);
+ if (cap_file_hashes) {
+ printf ("SHA256: %s\n", file_sha256);
+ printf ("RIPEMD160: %s\n", file_rmd160);
+ printf ("SHA1: %s\n", file_sha1);
+ }
+ if (cap_order) printf ("Strict time order: %s\n", order_string(cf_info->order));
+
+ gboolean has_multiple_sections = (wtap_file_get_num_shbs(cf_info->wth) > 1);
+
+ for (guint section_number = 0;
+ section_number < wtap_file_get_num_shbs(cf_info->wth);
+ section_number++) {
+ wtap_block_t shb;
+
+ // If we have more than one section, add headers for each section.
+ if (has_multiple_sections)
+ printf("Section %u:\n\n", section_number);
+
+ shb = wtap_file_get_shb(cf_info->wth, section_number);
+ if (shb != NULL) {
+ if (cap_file_more_info) {
+ char *str;
+
+ if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS)
+ show_option_string("Capture hardware: ", str);
+ if (wtap_block_get_string_option_value(shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS)
+ show_option_string("Capture oper-sys: ", str);
+ if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS)
+ show_option_string("Capture application: ", str);
+ }
+ if (cap_comment) {
+ unsigned int i;
+ char *str;
+
+ for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, i, &str) == WTAP_OPTTYPE_SUCCESS; i++) {
+ show_option_string("Capture comment: ", str);
+ }
+ }
+
+ if (cap_file_idb && cf_info->num_interfaces != 0) {
+ guint i;
+ ws_assert(cf_info->num_interfaces == cf_info->idb_info_strings->len);
+ printf ("Number of interfaces in file: %u\n", cf_info->num_interfaces);
+ for (i = 0; i < cf_info->idb_info_strings->len; i++) {
+ gchar *s = g_array_index(cf_info->idb_info_strings, gchar*, i);
+ guint32 packet_count = 0;
+ if (i < cf_info->interface_packet_counts->len)
+ packet_count = g_array_index(cf_info->interface_packet_counts, guint32, i);
+ printf ("Interface #%u info:\n", i);
+ printf ("%s", s);
+ printf (" Number of packets = %u\n", packet_count);
+ }
+ }
+ }
+
+ if (cap_file_nrb) {
+ if (num_ipv4_addresses != 0)
+ printf ("Number of resolved IPv4 addresses in file: %u\n", num_ipv4_addresses);
+ if (num_ipv6_addresses != 0)
+ printf ("Number of resolved IPv6 addresses in file: %u\n", num_ipv6_addresses);
+ }
+ if (cap_file_dsb) {
+ if (num_decryption_secrets != 0)
+ printf ("Number of decryption secrets in file: %u\n", num_decryption_secrets);
+ }
}
- }
}
static void
putsep(void)
{
- if (field_separator) putchar(field_separator);
+ if (field_separator) putchar(field_separator);
}
static void
putquote(void)
{
- if (quote_char) putchar(quote_char);
+ if (quote_char) putchar(quote_char);
}
static void
print_stats_table_header_label(const gchar *label)
{
- putsep();
- putquote();
- printf("%s", label);
- putquote();
+ putsep();
+ putquote();
+ printf("%s", label);
+ putquote();
}
static void
print_stats_table_header(void)
{
- putquote();
- printf("File name");
- putquote();
-
- if (cap_file_type) print_stats_table_header_label("File type");
- if (cap_file_encap) print_stats_table_header_label("File encapsulation");
- if (cap_file_more_info) print_stats_table_header_label("File time precision");
- if (cap_snaplen) {
- print_stats_table_header_label("Packet size limit");
- print_stats_table_header_label("Packet size limit min (inferred)");
- print_stats_table_header_label("Packet size limit max (inferred)");
- }
- if (cap_packet_count) print_stats_table_header_label("Number of packets");
- if (cap_file_size) print_stats_table_header_label("File size (bytes)");
- if (cap_data_size) print_stats_table_header_label("Data size (bytes)");
- if (cap_duration) print_stats_table_header_label("Capture duration (seconds)");
- if (cap_start_time) print_stats_table_header_label("Start time");
- if (cap_end_time) print_stats_table_header_label("End time");
- if (cap_data_rate_byte) print_stats_table_header_label("Data byte rate (bytes/sec)");
- if (cap_data_rate_bit) print_stats_table_header_label("Data bit rate (bits/sec)");
- if (cap_packet_size) print_stats_table_header_label("Average packet size (bytes)");
- if (cap_packet_rate) print_stats_table_header_label("Average packet rate (packets/sec)");
- if (cap_file_hashes) {
- print_stats_table_header_label("SHA256");
- print_stats_table_header_label("RIPEMD160");
- print_stats_table_header_label("SHA1");
- }
- if (cap_order) print_stats_table_header_label("Strict time order");
- if (cap_file_more_info) {
- print_stats_table_header_label("Capture hardware");
- print_stats_table_header_label("Capture oper-sys");
- print_stats_table_header_label("Capture application");
- }
- if (cap_comment) print_stats_table_header_label("Capture comment");
-
- printf("\n");
+ putquote();
+ printf("File name");
+ putquote();
+
+ if (cap_file_type) print_stats_table_header_label("File type");
+ if (cap_file_encap) print_stats_table_header_label("File encapsulation");
+ if (cap_file_more_info) print_stats_table_header_label("File time precision");
+ if (cap_snaplen) {
+ print_stats_table_header_label("Packet size limit");
+ print_stats_table_header_label("Packet size limit min (inferred)");
+ print_stats_table_header_label("Packet size limit max (inferred)");
+ }
+ if (cap_packet_count) print_stats_table_header_label("Number of packets");
+ if (cap_file_size) print_stats_table_header_label("File size (bytes)");
+ if (cap_data_size) print_stats_table_header_label("Data size (bytes)");
+ if (cap_duration) print_stats_table_header_label("Capture duration (seconds)");
+ if (cap_start_time) print_stats_table_header_label("Start time");
+ if (cap_end_time) print_stats_table_header_label("End time");
+ if (cap_data_rate_byte) print_stats_table_header_label("Data byte rate (bytes/sec)");
+ if (cap_data_rate_bit) print_stats_table_header_label("Data bit rate (bits/sec)");
+ if (cap_packet_size) print_stats_table_header_label("Average packet size (bytes)");
+ if (cap_packet_rate) print_stats_table_header_label("Average packet rate (packets/sec)");
+ if (cap_file_hashes) {
+ print_stats_table_header_label("SHA256");
+ print_stats_table_header_label("RIPEMD160");
+ print_stats_table_header_label("SHA1");
+ }
+ if (cap_order) print_stats_table_header_label("Strict time order");
+ if (cap_file_more_info) {
+ print_stats_table_header_label("Capture hardware");
+ print_stats_table_header_label("Capture oper-sys");
+ print_stats_table_header_label("Capture application");
+ }
+ if (cap_comment) print_stats_table_header_label("Capture comment");
+
+ printf("\n");
}
static void
print_stats_table(const gchar *filename, capture_info *cf_info)
{
- const gchar *file_type_string, *file_encap_string;
-
- /* Build printable strings for various stats */
- file_type_string = wtap_file_type_subtype_name(cf_info->file_type);
- file_encap_string = wtap_encap_name(cf_info->file_encap);
+ const gchar *file_type_string, *file_encap_string;
- if (filename) {
- putquote();
- printf("%s", filename);
- putquote();
- }
-
- if (cap_file_type) {
- putsep();
- putquote();
- printf("%s", file_type_string);
- putquote();
- }
-
- /* ToDo: If WTAP_ENCAP_PER_PACKET, show the list of encapsulations encountered;
- * Output a line for each different encap with all fields repeated except
- * the encapsulation field which has "Per Packet: ..." for each
- * encapsulation type seen ?
- */
- if (cap_file_encap) {
- putsep();
- putquote();
- printf("%s", file_encap_string);
- putquote();
- }
-
- if (cap_file_more_info) {
- putsep();
- putquote();
- printf("%s", wtap_tsprec_string(cf_info->file_tsprec));
- putquote();
- }
+ /* Build printable strings for various stats */
+ file_type_string = wtap_file_type_subtype_name(cf_info->file_type);
+ file_encap_string = wtap_encap_name(cf_info->file_encap);
- if (cap_snaplen) {
- putsep();
- putquote();
- if (cf_info->snap_set)
- printf("%u", cf_info->snaplen);
- else
- printf("(not set)");
- putquote();
- if (cf_info->snaplen_max_inferred > 0) {
- putsep();
- putquote();
- printf("%u", cf_info->snaplen_min_inferred);
- putquote();
- putsep();
- putquote();
- printf("%u", cf_info->snaplen_max_inferred);
- putquote();
- }
- else {
- putsep();
- putquote();
- printf("n/a");
- putquote();
- putsep();
- putquote();
- printf("n/a");
- putquote();
+ if (filename) {
+ putquote();
+ printf("%s", filename);
+ putquote();
}
- }
- if (cap_packet_count) {
- putsep();
- putquote();
- printf("%u", cf_info->packet_count);
- putquote();
- }
-
- if (cap_file_size) {
- putsep();
- putquote();
- printf("%" PRId64, cf_info->filesize);
- putquote();
- }
-
- if (cap_data_size) {
- putsep();
- putquote();
- printf("%" PRIu64, cf_info->packet_bytes);
- putquote();
- }
+ if (cap_file_type) {
+ putsep();
+ putquote();
+ printf("%s", file_type_string);
+ putquote();
+ }
- if (cap_duration) {
- putsep();
- putquote();
- printf("%s", relative_time_string(&cf_info->duration, cf_info->duration_tsprec, cf_info, FALSE));
- putquote();
- }
+ /* ToDo: If WTAP_ENCAP_PER_PACKET, show the list of encapsulations encountered;
+ * Output a line for each different encap with all fields repeated except
+ * the encapsulation field which has "Per Packet: ..." for each
+ * encapsulation type seen ?
+ */
+ if (cap_file_encap) {
+ putsep();
+ putquote();
+ printf("%s", file_encap_string);
+ putquote();
+ }
- if (cap_start_time) {
- putsep();
- putquote();
- printf("%s", absolute_time_string(&cf_info->start_time, cf_info->start_time_tsprec, cf_info));
- putquote();
- }
+ if (cap_file_more_info) {
+ putsep();
+ putquote();
+ printf("%s", wtap_tsprec_string(cf_info->file_tsprec));
+ putquote();
+ }
- if (cap_end_time) {
- putsep();
- putquote();
- printf("%s", absolute_time_string(&cf_info->stop_time, cf_info->stop_time_tsprec, cf_info));
- putquote();
- }
+ if (cap_snaplen) {
+ putsep();
+ putquote();
+ if (cf_info->snap_set)
+ printf("%u", cf_info->snaplen);
+ else
+ printf("(not set)");
+ putquote();
+ if (cf_info->snaplen_max_inferred > 0) {
+ putsep();
+ putquote();
+ printf("%u", cf_info->snaplen_min_inferred);
+ putquote();
+ putsep();
+ putquote();
+ printf("%u", cf_info->snaplen_max_inferred);
+ putquote();
+ }
+ else {
+ putsep();
+ putquote();
+ printf("n/a");
+ putquote();
+ putsep();
+ putquote();
+ printf("n/a");
+ putquote();
+ }
+ }
- if (cap_data_rate_byte) {
- putsep();
- putquote();
- if (cf_info->times_known)
- printf("%.2f", cf_info->data_rate);
- else
- printf("n/a");
- putquote();
- }
+ if (cap_packet_count) {
+ putsep();
+ putquote();
+ printf("%u", cf_info->packet_count);
+ putquote();
+ }
- if (cap_data_rate_bit) {
- putsep();
- putquote();
- if (cf_info->times_known)
- printf("%.2f", cf_info->data_rate*8);
- else
- printf("n/a");
- putquote();
- }
+ if (cap_file_size) {
+ putsep();
+ putquote();
+ printf("%" PRId64, cf_info->filesize);
+ putquote();
+ }
- if (cap_packet_size) {
- putsep();
- putquote();
- printf("%.2f", cf_info->packet_size);
- putquote();
- }
+ if (cap_data_size) {
+ putsep();
+ putquote();
+ printf("%" PRIu64, cf_info->packet_bytes);
+ putquote();
+ }
- if (cap_packet_rate) {
- putsep();
- putquote();
- if (cf_info->times_known)
- printf("%.2f", cf_info->packet_rate);
- else
- printf("n/a");
- putquote();
- }
+ if (cap_duration) {
+ putsep();
+ putquote();
+ printf("%s", relative_time_string(&cf_info->duration, cf_info->duration_tsprec, cf_info, FALSE));
+ putquote();
+ }
- if (cap_file_hashes) {
- putsep();
- putquote();
- printf("%s", file_sha256);
- putquote();
+ if (cap_start_time) {
+ putsep();
+ putquote();
+ printf("%s", absolute_time_string(&cf_info->start_time, cf_info->start_time_tsprec, cf_info));
+ putquote();
+ }
- putsep();
- putquote();
- printf("%s", file_rmd160);
- putquote();
+ if (cap_end_time) {
+ putsep();
+ putquote();
+ printf("%s", absolute_time_string(&cf_info->stop_time, cf_info->stop_time_tsprec, cf_info));
+ putquote();
+ }
- putsep();
- putquote();
- printf("%s", file_sha1);
- putquote();
- }
+ if (cap_data_rate_byte) {
+ putsep();
+ putquote();
+ if (cf_info->times_known)
+ printf("%.2f", cf_info->data_rate);
+ else
+ printf("n/a");
+ putquote();
+ }
- if (cap_order) {
- putsep();
- putquote();
- printf("%s", order_string(cf_info->order));
- putquote();
- }
+ if (cap_data_rate_bit) {
+ putsep();
+ putquote();
+ if (cf_info->times_known)
+ printf("%.2f", cf_info->data_rate*8);
+ else
+ printf("n/a");
+ putquote();
+ }
- for (guint section_number = 0;
- section_number < wtap_file_get_num_shbs(cf_info->wth);
- section_number++) {
- wtap_block_t shb;
+ if (cap_packet_size) {
+ putsep();
+ putquote();
+ printf("%.2f", cf_info->packet_size);
+ putquote();
+ }
- shb = wtap_file_get_shb(cf_info->wth, section_number);
- if (cap_file_more_info) {
- char *str;
-
- putsep();
- putquote();
- if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS) {
- printf("%s", str);
- }
- putquote();
-
- putsep();
- putquote();
- if (wtap_block_get_string_option_value(shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS) {
- printf("%s", str);
- }
- putquote();
-
- putsep();
- putquote();
- if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS) {
- printf("%s", str);
- }
- putquote();
+ if (cap_packet_rate) {
+ putsep();
+ putquote();
+ if (cf_info->times_known)
+ printf("%.2f", cf_info->packet_rate);
+ else
+ printf("n/a");
+ putquote();
}
- /*
- * One might argue that the following is silly to put into a table format,
- * but oh well note that there may be *more than one* of each of these types
- * of options. To mitigate some of the potential silliness the if(cap_comment)
- * block is moved AFTER the if(cap_file_more_info) block. This will make any
- * comments the last item(s) in each row. We now have a new -K option to
- * disable cap_comment to more easily manage the potential silliness.
- * Potential silliness includes multiple comments (therefore resulting in
- * more than one additional column and/or comments with embeded newlines
- * and/or possible delimiters).
- */
- if (cap_comment) {
- unsigned int i;
- char *opt_comment;
- gboolean have_cap = FALSE;
+ if (cap_file_hashes) {
+ putsep();
+ putquote();
+ printf("%s", file_sha256);
+ putquote();
- for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) {
- have_cap = TRUE;
putsep();
putquote();
- printf("%s", opt_comment);
+ printf("%s", file_rmd160);
putquote();
- }
- if(!have_cap) {
- /* Maintain column alignment when we have no OPT_COMMENT */
+
putsep();
putquote();
+ printf("%s", file_sha1);
putquote();
- }
}
- }
+ if (cap_order) {
+ putsep();
+ putquote();
+ printf("%s", order_string(cf_info->order));
+ putquote();
+ }
+
+ for (guint section_number = 0;
+ section_number < wtap_file_get_num_shbs(cf_info->wth);
+ section_number++) {
+ wtap_block_t shb;
+
+ shb = wtap_file_get_shb(cf_info->wth, section_number);
+ if (cap_file_more_info) {
+ char *str;
+
+ putsep();
+ putquote();
+ if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS) {
+ printf("%s", str);
+ }
+ putquote();
+
+ putsep();
+ putquote();
+ if (wtap_block_get_string_option_value(shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS) {
+ printf("%s", str);
+ }
+ putquote();
+
+ putsep();
+ putquote();
+ if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS) {
+ printf("%s", str);
+ }
+ putquote();
+ }
+
+ /*
+ * One might argue that the following is silly to put into a table format,
+ * but oh well note that there may be *more than one* of each of these types
+ * of options. To mitigate some of the potential silliness the if(cap_comment)
+ * block is moved AFTER the if(cap_file_more_info) block. This will make any
+ * comments the last item(s) in each row. We now have a new -K option to
+ * disable cap_comment to more easily manage the potential silliness.
+ * Potential silliness includes multiple comments (therefore resulting in
+ * more than one additional column and/or comments with embeded newlines
+ * and/or possible delimiters).
+ */
+ if (cap_comment) {
+ unsigned int i;
+ char *opt_comment;
+ gboolean have_cap = FALSE;
+
+ for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) {
+ have_cap = TRUE;
+ putsep();
+ putquote();
+ printf("%s", opt_comment);
+ putquote();
+ }
+ if(!have_cap) {
+ /* Maintain column alignment when we have no OPT_COMMENT */
+ putsep();
+ putquote();
+ putquote();
+ }
+ }
- printf("\n");
+ }
+
+ printf("\n");
}
static void
cleanup_capture_info(capture_info *cf_info)
{
- guint i;
- ws_assert(cf_info != NULL);
+ guint i;
+ ws_assert(cf_info != NULL);
- g_free(cf_info->encap_counts);
- cf_info->encap_counts = NULL;
+ g_free(cf_info->encap_counts);
+ cf_info->encap_counts = NULL;
- g_array_free(cf_info->interface_packet_counts, TRUE);
- cf_info->interface_packet_counts = NULL;
+ g_array_free(cf_info->interface_packet_counts, TRUE);
+ cf_info->interface_packet_counts = NULL;
- if (cf_info->idb_info_strings) {
- for (i = 0; i < cf_info->idb_info_strings->len; i++) {
- gchar *s = g_array_index(cf_info->idb_info_strings, gchar*, i);
- g_free(s);
+ if (cf_info->idb_info_strings) {
+ for (i = 0; i < cf_info->idb_info_strings->len; i++) {
+ gchar *s = g_array_index(cf_info->idb_info_strings, gchar*, i);
+ g_free(s);
+ }
+ g_array_free(cf_info->idb_info_strings, TRUE);
}
- g_array_free(cf_info->idb_info_strings, TRUE);
- }
- cf_info->idb_info_strings = NULL;
+ cf_info->idb_info_strings = NULL;
}
static void
count_ipv4_address(const guint addr _U_, const gchar *name _U_)
{
- num_ipv4_addresses++;
+ num_ipv4_addresses++;
}
static void
count_ipv6_address(const void *addrp _U_, const gchar *name _U_)
{
- num_ipv6_addresses++;
+ num_ipv6_addresses++;
}
static void
count_decryption_secret(guint32 secrets_type _U_, const void *secrets _U_, guint size _U_)
{
- /* XXX - count them based on the secrets type (which is an opaque code,
- not a small integer)? */
- num_decryption_secrets++;
+ /* XXX - count them based on the secrets type (which is an opaque code,
+ not a small integer)? */
+ num_decryption_secrets++;
}
static void
-hash_to_str(const unsigned char *hash, size_t length, char *str) {
- int i;
+hash_to_str(const unsigned char *hash, size_t length, char *str)
+{
+ int i;
- for (i = 0; i < (int) length; i++) {
- snprintf(str+(i*2), 3, "%02x", hash[i]);
- }
+ for (i = 0; i < (int) length; i++) {
+ snprintf(str+(i*2), 3, "%02x", hash[i]);
+ }
}
static void
calculate_hashes(const char *filename)
{
- FILE *fh;
- size_t hash_bytes;
-
- (void) g_strlcpy(file_sha256, "<unknown>", HASH_STR_SIZE);
- (void) g_strlcpy(file_rmd160, "<unknown>", HASH_STR_SIZE);
- (void) g_strlcpy(file_sha1, "<unknown>", HASH_STR_SIZE);
-
- if (cap_file_hashes) {
- fh = ws_fopen(filename, "rb");
- if (fh && hd) {
- while((hash_bytes = fread(hash_buf, 1, HASH_BUF_SIZE, fh)) > 0) {
- gcry_md_write(hd, hash_buf, hash_bytes);
- }
- gcry_md_final(hd);
- hash_to_str(gcry_md_read(hd, GCRY_MD_SHA256), HASH_SIZE_SHA256, file_sha256);
- hash_to_str(gcry_md_read(hd, GCRY_MD_RMD160), HASH_SIZE_RMD160, file_rmd160);
- hash_to_str(gcry_md_read(hd, GCRY_MD_SHA1), HASH_SIZE_SHA1, file_sha1);
+ FILE *fh;
+ size_t hash_bytes;
+
+ (void) g_strlcpy(file_sha256, "<unknown>", HASH_STR_SIZE);
+ (void) g_strlcpy(file_rmd160, "<unknown>", HASH_STR_SIZE);
+ (void) g_strlcpy(file_sha1, "<unknown>", HASH_STR_SIZE);
+
+ if (cap_file_hashes) {
+ fh = ws_fopen(filename, "rb");
+ if (fh && hd) {
+ while((hash_bytes = fread(hash_buf, 1, HASH_BUF_SIZE, fh)) > 0) {
+ gcry_md_write(hd, hash_buf, hash_bytes);
+ }
+ gcry_md_final(hd);
+ hash_to_str(gcry_md_read(hd, GCRY_MD_SHA256), HASH_SIZE_SHA256, file_sha256);
+ hash_to_str(gcry_md_read(hd, GCRY_MD_RMD160), HASH_SIZE_RMD160, file_rmd160);
+ hash_to_str(gcry_md_read(hd, GCRY_MD_SHA1), HASH_SIZE_SHA1, file_sha1);
+ }
+ if (fh) fclose(fh);
+ if (hd) gcry_md_reset(hd);
}
- if (fh) fclose(fh);
- if (hd) gcry_md_reset(hd);
- }
}
static int
process_cap_file(const char *filename, gboolean need_separator)
{
- int status = 0;
- int err;
- gchar *err_info;
- gint64 size;
- gint64 data_offset;
-
- guint32 packet = 0;
- gint64 bytes = 0;
- guint32 snaplen_min_inferred = 0xffffffff;
- guint32 snaplen_max_inferred = 0;
- wtap_rec rec;
- Buffer buf;
- capture_info cf_info;
- gboolean have_times = TRUE;
- nstime_t start_time;
- int start_time_tsprec;
- nstime_t stop_time;
- int stop_time_tsprec;
- nstime_t cur_time;
- nstime_t prev_time;
- gboolean know_order = FALSE;
- order_t order = IN_ORDER;
- guint i;
- wtapng_iface_descriptions_t *idb_info;
-
- cf_info.wth = wtap_open_offline(filename, WTAP_TYPE_AUTO, &err, &err_info, FALSE);
- if (!cf_info.wth) {
- cfile_open_failure_message(filename, err, err_info);
- return 2;
- }
-
- /*
- * Calculate the checksums. Do this after wtap_open_offline, so we don't
- * bother calculating them for files that are not known capture types
- * where we wouldn't print them anyway.
- */
- calculate_hashes(filename);
-
- if (need_separator && long_report) {
- printf("\n");
- }
-
- nstime_set_zero(&start_time);
- start_time_tsprec = WTAP_TSPREC_UNKNOWN;
- nstime_set_zero(&stop_time);
- stop_time_tsprec = WTAP_TSPREC_UNKNOWN;
- nstime_set_zero(&cur_time);
- nstime_set_zero(&prev_time);
-
- cf_info.encap_counts = g_new0(int,WTAP_NUM_ENCAP_TYPES);
-
- idb_info = wtap_file_get_idb_info(cf_info.wth);
-
- ws_assert(idb_info->interface_data != NULL);
-
- cf_info.num_interfaces = idb_info->interface_data->len;
- cf_info.interface_packet_counts = g_array_sized_new(FALSE, TRUE, sizeof(guint32), cf_info.num_interfaces);
- g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
- cf_info.pkt_interface_id_unknown = 0;
-
- g_free(idb_info);
- idb_info = NULL;
-
- /* Register callbacks for new name<->address maps from the file and
- decryption secrets from the file. */
- wtap_set_cb_new_ipv4(cf_info.wth, count_ipv4_address);
- wtap_set_cb_new_ipv6(cf_info.wth, count_ipv6_address);
- wtap_set_cb_new_secrets(cf_info.wth, count_decryption_secret);
-
- /* Zero out the counters for the callbacks. */
- num_ipv4_addresses = 0;
- num_ipv6_addresses = 0;
- num_decryption_secrets = 0;
-
- /* Tally up data that we need to parse through the file to find */
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
- while (wtap_read(cf_info.wth, &rec, &buf, &err, &err_info, &data_offset)) {
- if (rec.presence_flags & WTAP_HAS_TS) {
- prev_time = cur_time;
- cur_time = rec.ts;
- if (packet == 0) {
- start_time = rec.ts;
- start_time_tsprec = rec.tsprec;
- stop_time = rec.ts;
- stop_time_tsprec = rec.tsprec;
- prev_time = rec.ts;
- }
- if (nstime_cmp(&cur_time, &prev_time) < 0) {
- order = NOT_IN_ORDER;
- }
- if (nstime_cmp(&cur_time, &start_time) < 0) {
- start_time = cur_time;
- start_time_tsprec = rec.tsprec;
- }
- if (nstime_cmp(&cur_time, &stop_time) > 0) {
- stop_time = cur_time;
- stop_time_tsprec = rec.tsprec;
- }
- } else {
- have_times = FALSE; /* at least one packet has no time stamp */
- if (order != NOT_IN_ORDER)
- order = ORDER_UNKNOWN;
+ int status = 0;
+ int err;
+ gchar *err_info;
+ gint64 size;
+ gint64 data_offset;
+
+ guint32 packet = 0;
+ gint64 bytes = 0;
+ guint32 snaplen_min_inferred = 0xffffffff;
+ guint32 snaplen_max_inferred = 0;
+ wtap_rec rec;
+ Buffer buf;
+ capture_info cf_info;
+ gboolean have_times = TRUE;
+ nstime_t start_time;
+ int start_time_tsprec;
+ nstime_t stop_time;
+ int stop_time_tsprec;
+ nstime_t cur_time;
+ nstime_t prev_time;
+ gboolean know_order = FALSE;
+ order_t order = IN_ORDER;
+ guint i;
+ wtapng_iface_descriptions_t *idb_info;
+
+ cf_info.wth = wtap_open_offline(filename, WTAP_TYPE_AUTO, &err, &err_info, FALSE);
+ if (!cf_info.wth) {
+ cfile_open_failure_message(filename, err, err_info);
+ return 2;
}
- if (rec.rec_type == REC_TYPE_PACKET) {
- bytes += rec.rec_header.packet_header.len;
- packet++;
-
- /* If caplen < len for a rcd, then presumably */
- /* 'Limit packet capture length' was done for this rcd. */
- /* Keep track as to the min/max actual snapshot lengths */
- /* seen for this file. */
- if (rec.rec_header.packet_header.caplen < rec.rec_header.packet_header.len) {
- if (rec.rec_header.packet_header.caplen < snaplen_min_inferred)
- snaplen_min_inferred = rec.rec_header.packet_header.caplen;
- if (rec.rec_header.packet_header.caplen > snaplen_max_inferred)
- snaplen_max_inferred = rec.rec_header.packet_header.caplen;
- }
-
- if ((rec.rec_header.packet_header.pkt_encap > 0) &&
- (rec.rec_header.packet_header.pkt_encap < WTAP_NUM_ENCAP_TYPES)) {
- cf_info.encap_counts[rec.rec_header.packet_header.pkt_encap] += 1;
- } else {
- fprintf(stderr, "capinfos: Unknown packet encapsulation %d in frame %u of file \"%s\"\n",
- rec.rec_header.packet_header.pkt_encap, packet, filename);
- }
-
- /* Packet interface_id info */
- if (rec.presence_flags & WTAP_HAS_INTERFACE_ID) {
- /* cf_info.num_interfaces is size, not index, so it's one more than max index */
- if (rec.rec_header.packet_header.interface_id >= cf_info.num_interfaces) {
- /*
- * OK, re-fetch the number of interfaces, as there might have
- * been an interface that was in the middle of packets, and
- * grow the array to be big enough for the new number of
- * interfaces.
- */
- idb_info = wtap_file_get_idb_info(cf_info.wth);
-
- cf_info.num_interfaces = idb_info->interface_data->len;
- g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
-
- g_free(idb_info);
- idb_info = NULL;
- }
- if (rec.rec_header.packet_header.interface_id < cf_info.num_interfaces) {
- g_array_index(cf_info.interface_packet_counts, guint32,
- rec.rec_header.packet_header.interface_id) += 1;
- }
- else {
- cf_info.pkt_interface_id_unknown += 1;
+ /*
+ * Calculate the checksums. Do this after wtap_open_offline, so we don't
+ * bother calculating them for files that are not known capture types
+ * where we wouldn't print them anyway.
+ */
+ calculate_hashes(filename);
+
+ if (need_separator && long_report) {
+ printf("\n");
+ }
+
+ nstime_set_zero(&start_time);
+ start_time_tsprec = WTAP_TSPREC_UNKNOWN;
+ nstime_set_zero(&stop_time);
+ stop_time_tsprec = WTAP_TSPREC_UNKNOWN;
+ nstime_set_zero(&cur_time);
+ nstime_set_zero(&prev_time);
+
+ cf_info.encap_counts = g_new0(int,WTAP_NUM_ENCAP_TYPES);
+
+ idb_info = wtap_file_get_idb_info(cf_info.wth);
+
+ ws_assert(idb_info->interface_data != NULL);
+
+ cf_info.num_interfaces = idb_info->interface_data->len;
+ cf_info.interface_packet_counts = g_array_sized_new(FALSE, TRUE, sizeof(guint32), cf_info.num_interfaces);
+ g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
+ cf_info.pkt_interface_id_unknown = 0;
+
+ g_free(idb_info);
+ idb_info = NULL;
+
+ /* Register callbacks for new name<->address maps from the file and
+ decryption secrets from the file. */
+ wtap_set_cb_new_ipv4(cf_info.wth, count_ipv4_address);
+ wtap_set_cb_new_ipv6(cf_info.wth, count_ipv6_address);
+ wtap_set_cb_new_secrets(cf_info.wth, count_decryption_secret);
+
+ /* Zero out the counters for the callbacks. */
+ num_ipv4_addresses = 0;
+ num_ipv6_addresses = 0;
+ num_decryption_secrets = 0;
+
+ /* Tally up data that we need to parse through the file to find */
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+ while (wtap_read(cf_info.wth, &rec, &buf, &err, &err_info, &data_offset)) {
+ if (rec.presence_flags & WTAP_HAS_TS) {
+ prev_time = cur_time;
+ cur_time = rec.ts;
+ if (packet == 0) {
+ start_time = rec.ts;
+ start_time_tsprec = rec.tsprec;
+ stop_time = rec.ts;
+ stop_time_tsprec = rec.tsprec;
+ prev_time = rec.ts;
+ }
+ if (nstime_cmp(&cur_time, &prev_time) < 0) {
+ order = NOT_IN_ORDER;
+ }
+ if (nstime_cmp(&cur_time, &start_time) < 0) {
+ start_time = cur_time;
+ start_time_tsprec = rec.tsprec;
+ }
+ if (nstime_cmp(&cur_time, &stop_time) > 0) {
+ stop_time = cur_time;
+ stop_time_tsprec = rec.tsprec;
+ }
+ } else {
+ have_times = FALSE; /* at least one packet has no time stamp */
+ if (order != NOT_IN_ORDER)
+ order = ORDER_UNKNOWN;
}
- }
- else {
- /* it's for interface_id 0 */
- if (cf_info.num_interfaces != 0) {
- g_array_index(cf_info.interface_packet_counts, guint32, 0) += 1;
+
+ if (rec.rec_type == REC_TYPE_PACKET) {
+ bytes += rec.rec_header.packet_header.len;
+ packet++;
+
+ /* If caplen < len for a rcd, then presumably */
+ /* 'Limit packet capture length' was done for this rcd. */
+ /* Keep track as to the min/max actual snapshot lengths */
+ /* seen for this file. */
+ if (rec.rec_header.packet_header.caplen < rec.rec_header.packet_header.len) {
+ if (rec.rec_header.packet_header.caplen < snaplen_min_inferred)
+ snaplen_min_inferred = rec.rec_header.packet_header.caplen;
+ if (rec.rec_header.packet_header.caplen > snaplen_max_inferred)
+ snaplen_max_inferred = rec.rec_header.packet_header.caplen;
+ }
+
+ if ((rec.rec_header.packet_header.pkt_encap > 0) &&
+ (rec.rec_header.packet_header.pkt_encap < WTAP_NUM_ENCAP_TYPES)) {
+ cf_info.encap_counts[rec.rec_header.packet_header.pkt_encap] += 1;
+ } else {
+ fprintf(stderr, "capinfos: Unknown packet encapsulation %d in frame %u of file \"%s\"\n",
+ rec.rec_header.packet_header.pkt_encap, packet, filename);
+ }
+
+ /* Packet interface_id info */
+ if (rec.presence_flags & WTAP_HAS_INTERFACE_ID) {
+ /* cf_info.num_interfaces is size, not index, so it's one more than max index */
+ if (rec.rec_header.packet_header.interface_id >= cf_info.num_interfaces) {
+ /*
+ * OK, re-fetch the number of interfaces, as there might have
+ * been an interface that was in the middle of packets, and
+ * grow the array to be big enough for the new number of
+ * interfaces.
+ */
+ idb_info = wtap_file_get_idb_info(cf_info.wth);
+
+ cf_info.num_interfaces = idb_info->interface_data->len;
+ g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
+
+ g_free(idb_info);
+ idb_info = NULL;
+ }
+ if (rec.rec_header.packet_header.interface_id < cf_info.num_interfaces) {
+ g_array_index(cf_info.interface_packet_counts, guint32,
+ rec.rec_header.packet_header.interface_id) += 1;
+ }
+ else {
+ cf_info.pkt_interface_id_unknown += 1;
+ }
+ }
+ else {
+ /* it's for interface_id 0 */
+ if (cf_info.num_interfaces != 0) {
+ g_array_index(cf_info.interface_packet_counts, guint32, 0) += 1;
+ }
+ else {
+ cf_info.pkt_interface_id_unknown += 1;
+ }
+ }
}
- else {
- cf_info.pkt_interface_id_unknown += 1;
+
+ wtap_rec_reset(&rec);
+ } /* while */
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+
+ /*
+ * Get IDB info strings.
+ * We do this at the end, so we can get information for all IDBs in
+ * the file, even those that come after packet records, and so that
+ * we get, for example, a count of the number of statistics entries
+ * for each interface as of the *end* of the file.
+ */
+ idb_info = wtap_file_get_idb_info(cf_info.wth);
+
+ cf_info.idb_info_strings = g_array_sized_new(FALSE, FALSE, sizeof(gchar*), cf_info.num_interfaces);
+ cf_info.num_interfaces = idb_info->interface_data->len;
+ for (i = 0; i < cf_info.num_interfaces; i++) {
+ const wtap_block_t if_descr = g_array_index(idb_info->interface_data, wtap_block_t, i);
+ gchar *s = wtap_get_debug_if_descr(if_descr, 21, "\n");
+ g_array_append_val(cf_info.idb_info_strings, s);
+ }
+
+ g_free(idb_info);
+ idb_info = NULL;
+
+ if (err != 0) {
+ fprintf(stderr,
+ "capinfos: An error occurred after reading %u packets from \"%s\".\n",
+ packet, filename);
+ cfile_read_failure_message(filename, err, err_info);
+ if (err == WTAP_ERR_SHORT_READ) {
+ /* Don't give up completely with this one. */
+ status = 1;
+ fprintf(stderr,
+ " (will continue anyway, checksums might be incorrect)\n");
+ } else {
+ cleanup_capture_info(&cf_info);
+ wtap_close(cf_info.wth);
+ return 2;
}
- }
}
- wtap_rec_reset(&rec);
- } /* while */
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
-
- /*
- * Get IDB info strings.
- * We do this at the end, so we can get information for all IDBs in
- * the file, even those that come after packet records, and so that
- * we get, for example, a count of the number of statistics entries
- * for each interface as of the *end* of the file.
- */
- idb_info = wtap_file_get_idb_info(cf_info.wth);
-
- cf_info.idb_info_strings = g_array_sized_new(FALSE, FALSE, sizeof(gchar*), cf_info.num_interfaces);
- cf_info.num_interfaces = idb_info->interface_data->len;
- for (i = 0; i < cf_info.num_interfaces; i++) {
- const wtap_block_t if_descr = g_array_index(idb_info->interface_data, wtap_block_t, i);
- gchar *s = wtap_get_debug_if_descr(if_descr, 21, "\n");
- g_array_append_val(cf_info.idb_info_strings, s);
- }
-
- g_free(idb_info);
- idb_info = NULL;
-
- if (err != 0) {
- fprintf(stderr,
- "capinfos: An error occurred after reading %u packets from \"%s\".\n",
- packet, filename);
- cfile_read_failure_message(filename, err, err_info);
- if (err == WTAP_ERR_SHORT_READ) {
- /* Don't give up completely with this one. */
- status = 1;
+ /* File size */
+ size = wtap_file_size(cf_info.wth, &err);
+ if (size == -1) {
fprintf(stderr,
- " (will continue anyway, checksums might be incorrect)\n");
- } else {
+ "capinfos: Can't get size of \"%s\": %s.\n",
+ filename, g_strerror(err));
cleanup_capture_info(&cf_info);
wtap_close(cf_info.wth);
return 2;
}
- }
-
- /* File size */
- size = wtap_file_size(cf_info.wth, &err);
- if (size == -1) {
- fprintf(stderr,
- "capinfos: Can't get size of \"%s\": %s.\n",
- filename, g_strerror(err));
- cleanup_capture_info(&cf_info);
- wtap_close(cf_info.wth);
- return 2;
- }
-
- cf_info.filesize = size;
-
- /* File Type */
- cf_info.file_type = wtap_file_type_subtype(cf_info.wth);
- cf_info.compression_type = wtap_get_compression_type(cf_info.wth);
-
- /* File Encapsulation */
- cf_info.file_encap = wtap_file_encap(cf_info.wth);
-
- cf_info.file_tsprec = wtap_file_tsprec(cf_info.wth);
-
- /* Packet size limit (snaplen) */
- cf_info.snaplen = wtap_snapshot_length(cf_info.wth);
- if (cf_info.snaplen > 0)
- cf_info.snap_set = TRUE;
- else
- cf_info.snap_set = FALSE;
-
- cf_info.snaplen_min_inferred = snaplen_min_inferred;
- cf_info.snaplen_max_inferred = snaplen_max_inferred;
-
- /* # of packets */
- cf_info.packet_count = packet;
-
- /* File Times */
- cf_info.times_known = have_times;
- cf_info.start_time = start_time;
- cf_info.start_time_tsprec = start_time_tsprec;
- cf_info.stop_time = stop_time;
- cf_info.stop_time_tsprec = stop_time_tsprec;
- nstime_delta(&cf_info.duration, &stop_time, &start_time);
- /* Duration precision is the higher of the start and stop time precisions. */
- if (cf_info.stop_time_tsprec > cf_info.start_time_tsprec)
- cf_info.duration_tsprec = cf_info.stop_time_tsprec;
- else
- cf_info.duration_tsprec = cf_info.start_time_tsprec;
- cf_info.know_order = know_order;
- cf_info.order = order;
-
- /* Number of packet bytes */
- cf_info.packet_bytes = bytes;
-
- cf_info.data_rate = 0.0;
- cf_info.packet_rate = 0.0;
- cf_info.packet_size = 0.0;
-
- if (packet > 0) {
- double delta_time = nstime_to_sec(&stop_time) - nstime_to_sec(&start_time);
- if (delta_time > 0.0) {
- cf_info.data_rate = (double)bytes / delta_time; /* Data rate per second */
- cf_info.packet_rate = (double)packet / delta_time; /* packet rate per second */
+
+ cf_info.filesize = size;
+
+ /* File Type */
+ cf_info.file_type = wtap_file_type_subtype(cf_info.wth);
+ cf_info.compression_type = wtap_get_compression_type(cf_info.wth);
+
+ /* File Encapsulation */
+ cf_info.file_encap = wtap_file_encap(cf_info.wth);
+
+ cf_info.file_tsprec = wtap_file_tsprec(cf_info.wth);
+
+ /* Packet size limit (snaplen) */
+ cf_info.snaplen = wtap_snapshot_length(cf_info.wth);
+ if (cf_info.snaplen > 0)
+ cf_info.snap_set = TRUE;
+ else
+ cf_info.snap_set = FALSE;
+
+ cf_info.snaplen_min_inferred = snaplen_min_inferred;
+ cf_info.snaplen_max_inferred = snaplen_max_inferred;
+
+ /* # of packets */
+ cf_info.packet_count = packet;
+
+ /* File Times */
+ cf_info.times_known = have_times;
+ cf_info.start_time = start_time;
+ cf_info.start_time_tsprec = start_time_tsprec;
+ cf_info.stop_time = stop_time;
+ cf_info.stop_time_tsprec = stop_time_tsprec;
+ nstime_delta(&cf_info.duration, &stop_time, &start_time);
+ /* Duration precision is the higher of the start and stop time precisions. */
+ if (cf_info.stop_time_tsprec > cf_info.start_time_tsprec)
+ cf_info.duration_tsprec = cf_info.stop_time_tsprec;
+ else
+ cf_info.duration_tsprec = cf_info.start_time_tsprec;
+ cf_info.know_order = know_order;
+ cf_info.order = order;
+
+ /* Number of packet bytes */
+ cf_info.packet_bytes = bytes;
+
+ cf_info.data_rate = 0.0;
+ cf_info.packet_rate = 0.0;
+ cf_info.packet_size = 0.0;
+
+ if (packet > 0) {
+ double delta_time = nstime_to_sec(&stop_time) - nstime_to_sec(&start_time);
+ if (delta_time > 0.0) {
+ cf_info.data_rate = (double)bytes / delta_time; /* Data rate per second */
+ cf_info.packet_rate = (double)packet / delta_time; /* packet rate per second */
+ }
+ cf_info.packet_size = (double)bytes / packet; /* Avg packet size */
}
- cf_info.packet_size = (double)bytes / packet; /* Avg packet size */
- }
- if (long_report) {
- print_stats(filename, &cf_info);
- } else {
- print_stats_table(filename, &cf_info);
- }
+ if (long_report) {
+ print_stats(filename, &cf_info);
+ } else {
+ print_stats_table(filename, &cf_info);
+ }
- cleanup_capture_info(&cf_info);
- wtap_close(cf_info.wth);
+ cleanup_capture_info(&cf_info);
+ wtap_close(cf_info.wth);
- return status;
+ return status;
}
static void
print_usage(FILE *output)
{
- fprintf(output, "\n");
- fprintf(output, "Usage: capinfos [options] <infile> ...\n");
- fprintf(output, "\n");
- fprintf(output, "General infos:\n");
- fprintf(output, " -t display the capture file type\n");
- fprintf(output, " -E display the capture file encapsulation\n");
- fprintf(output, " -I display the capture file interface information\n");
- fprintf(output, " -F display additional capture file information\n");
- fprintf(output, " -H display the SHA256, RIPEMD160, and SHA1 hashes of the file\n");
- fprintf(output, " -k display the capture comment\n");
- fprintf(output, "\n");
- fprintf(output, "Size infos:\n");
- fprintf(output, " -c display the number of packets\n");
- fprintf(output, " -s display the size of the file (in bytes)\n");
- fprintf(output, " -d display the total length of all packets (in bytes)\n");
- fprintf(output, " -l display the packet size limit (snapshot length)\n");
- fprintf(output, "\n");
- fprintf(output, "Time infos:\n");
- fprintf(output, " -u display the capture duration (in seconds)\n");
- fprintf(output, " -a display the capture start time\n");
- fprintf(output, " -e display the capture end time\n");
- fprintf(output, " -o display the capture file chronological status (True/False)\n");
- fprintf(output, " -S display start and end times as seconds\n");
- fprintf(output, "\n");
- fprintf(output, "Statistic infos:\n");
- fprintf(output, " -y display average data rate (in bytes/sec)\n");
- fprintf(output, " -i display average data rate (in bits/sec)\n");
- fprintf(output, " -z display average packet size (in bytes)\n");
- fprintf(output, " -x display average packet rate (in packets/sec)\n");
- fprintf(output, "\n");
- fprintf(output, "Metadata infos:\n");
- fprintf(output, " -n display number of resolved IPv4 and IPv6 addresses\n");
- fprintf(output, " -D display number of decryption secrets\n");
- fprintf(output, "\n");
- fprintf(output, "Output format:\n");
- fprintf(output, " -L generate long report (default)\n");
- fprintf(output, " -T generate table report\n");
- fprintf(output, " -M display machine-readable values in long reports\n");
- fprintf(output, "\n");
- fprintf(output, "Table report options:\n");
- fprintf(output, " -R generate header record (default)\n");
- fprintf(output, " -r do not generate header record\n");
- fprintf(output, "\n");
- fprintf(output, " -B separate infos with TAB character (default)\n");
- fprintf(output, " -m separate infos with comma (,) character\n");
- fprintf(output, " -b separate infos with SPACE character\n");
- fprintf(output, "\n");
- fprintf(output, " -N do not quote infos (default)\n");
- fprintf(output, " -q quote infos with single quotes (')\n");
- fprintf(output, " -Q quote infos with double quotes (\")\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, " -C cancel processing if file open fails (default is to continue)\n");
- fprintf(output, " -A generate all infos (default)\n");
- fprintf(output, " -K disable displaying the capture comment\n");
- fprintf(output, "\n");
- fprintf(output, "Options are processed from left to right order with later options superseding\n");
- fprintf(output, "or adding to earlier options.\n");
- fprintf(output, "\n");
- fprintf(output, "If no options are given the default is to display all infos in long report\n");
- fprintf(output, "output format.\n");
+ fprintf(output, "\n");
+ fprintf(output, "Usage: capinfos [options] <infile> ...\n");
+ fprintf(output, "\n");
+ fprintf(output, "General infos:\n");
+ fprintf(output, " -t display the capture file type\n");
+ fprintf(output, " -E display the capture file encapsulation\n");
+ fprintf(output, " -I display the capture file interface information\n");
+ fprintf(output, " -F display additional capture file information\n");
+ fprintf(output, " -H display the SHA256, RIPEMD160, and SHA1 hashes of the file\n");
+ fprintf(output, " -k display the capture comment\n");
+ fprintf(output, "\n");
+ fprintf(output, "Size infos:\n");
+ fprintf(output, " -c display the number of packets\n");
+ fprintf(output, " -s display the size of the file (in bytes)\n");
+ fprintf(output, " -d display the total length of all packets (in bytes)\n");
+ fprintf(output, " -l display the packet size limit (snapshot length)\n");
+ fprintf(output, "\n");
+ fprintf(output, "Time infos:\n");
+ fprintf(output, " -u display the capture duration (in seconds)\n");
+ fprintf(output, " -a display the capture start time\n");
+ fprintf(output, " -e display the capture end time\n");
+ fprintf(output, " -o display the capture file chronological status (True/False)\n");
+ fprintf(output, " -S display start and end times as seconds\n");
+ fprintf(output, "\n");
+ fprintf(output, "Statistic infos:\n");
+ fprintf(output, " -y display average data rate (in bytes/sec)\n");
+ fprintf(output, " -i display average data rate (in bits/sec)\n");
+ fprintf(output, " -z display average packet size (in bytes)\n");
+ fprintf(output, " -x display average packet rate (in packets/sec)\n");
+ fprintf(output, "\n");
+ fprintf(output, "Metadata infos:\n");
+ fprintf(output, " -n display number of resolved IPv4 and IPv6 addresses\n");
+ fprintf(output, " -D display number of decryption secrets\n");
+ fprintf(output, "\n");
+ fprintf(output, "Output format:\n");
+ fprintf(output, " -L generate long report (default)\n");
+ fprintf(output, " -T generate table report\n");
+ fprintf(output, " -M display machine-readable values in long reports\n");
+ fprintf(output, "\n");
+ fprintf(output, "Table report options:\n");
+ fprintf(output, " -R generate header record (default)\n");
+ fprintf(output, " -r do not generate header record\n");
+ fprintf(output, "\n");
+ fprintf(output, " -B separate infos with TAB character (default)\n");
+ fprintf(output, " -m separate infos with comma (,) character\n");
+ fprintf(output, " -b separate infos with SPACE character\n");
+ fprintf(output, "\n");
+ fprintf(output, " -N do not quote infos (default)\n");
+ fprintf(output, " -q quote infos with single quotes (')\n");
+ fprintf(output, " -Q quote infos with double quotes (\")\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, " -C cancel processing if file open fails (default is to continue)\n");
+ fprintf(output, " -A generate all infos (default)\n");
+ fprintf(output, " -K disable displaying the capture comment\n");
+ fprintf(output, "\n");
+ fprintf(output, "Options are processed from left to right order with later options superseding\n");
+ fprintf(output, "or adding to earlier options.\n");
+ fprintf(output, "\n");
+ fprintf(output, "If no options are given the default is to display all infos in long report\n");
+ fprintf(output, "output format.\n");
}
/*
@@ -1550,9 +1551,9 @@ print_usage(FILE *output)
static void
capinfos_cmdarg_err(const char *msg_format, va_list ap)
{
- fprintf(stderr, "capinfos: ");
- vfprintf(stderr, msg_format, ap);
- fprintf(stderr, "\n");
+ fprintf(stderr, "capinfos: ");
+ vfprintf(stderr, msg_format, ap);
+ fprintf(stderr, "\n");
}
/*
@@ -1561,328 +1562,315 @@ capinfos_cmdarg_err(const char *msg_format, va_list ap)
static void
capinfos_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 capinfos_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
- };
- gboolean need_separator = FALSE;
- int opt;
- int overall_error_status = EXIT_SUCCESS;
- static const struct ws_option long_options[] = {
- {"help", ws_no_argument, NULL, 'h'},
- {"version", ws_no_argument, NULL, 'v'},
- {0, 0, 0, 0 }
- };
-
- int status = 0;
-
- /*
- * Set the C-language locale to the native environment and set the
- * code page to UTF-8 on Windows.
- */
+ char *init_progfile_dir_error;
+ static const struct report_message_routines capinfos_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
+ };
+ gboolean need_separator = FALSE;
+ int opt;
+ int overall_error_status = EXIT_SUCCESS;
+ static const struct ws_option long_options[] = {
+ {"help", ws_no_argument, NULL, 'h'},
+ {"version", ws_no_argument, NULL, 'v'},
+ {0, 0, 0, 0 }
+ };
+
+ int status = 0;
+
+ /*
+ * 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(capinfos_cmdarg_err, capinfos_cmdarg_err_cont);
+ cmdarg_err_init(capinfos_cmdarg_err, capinfos_cmdarg_err_cont);
- /* Initialize log handler early so we can have proper logging during startup. */
- ws_log_init("capinfos", vcmdarg_err);
+ /* Initialize log handler early so we can have proper logging during startup. */
+ ws_log_init("capinfos", 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 the decimal point. */
- decimal_point = g_strdup(localeconv()->decimal_point);
+ /* Get the decimal point. */
+ decimal_point = g_strdup(localeconv()->decimal_point);
- /* Initialize the version information. */
- ws_init_version_info("Capinfos (Wireshark)", NULL, NULL, NULL);
+ /* Initialize the version information. */
+ ws_init_version_info("Capinfos (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();
-
- /*
- * 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("capinfos", &capinfos_report_routines);
-
- wtap_init(TRUE);
-
- /* Process the options */
- while ((opt = ws_getopt_long(argc, argv, "abcdehiklmnoqrstuvxyzABCDEFHIKLMNQRST", long_options, NULL)) !=-1) {
-
- switch (opt) {
-
- case 't':
- if (report_all_infos) disable_all_infos();
- cap_file_type = TRUE;
- break;
-
- case 'E':
- if (report_all_infos) disable_all_infos();
- cap_file_encap = TRUE;
- break;
-
- case 'l':
- if (report_all_infos) disable_all_infos();
- cap_snaplen = TRUE;
- break;
-
- case 'c':
- if (report_all_infos) disable_all_infos();
- cap_packet_count = TRUE;
- break;
-
- case 's':
- if (report_all_infos) disable_all_infos();
- cap_file_size = TRUE;
- break;
-
- case 'd':
- if (report_all_infos) disable_all_infos();
- cap_data_size = TRUE;
- break;
-
- case 'u':
- if (report_all_infos) disable_all_infos();
- cap_duration = TRUE;
- break;
-
- case 'a':
- if (report_all_infos) disable_all_infos();
- cap_start_time = TRUE;
- break;
-
- case 'e':
- if (report_all_infos) disable_all_infos();
- cap_end_time = TRUE;
- break;
-
- case 'S':
- time_as_secs = TRUE;
- break;
-
- case 'y':
- if (report_all_infos) disable_all_infos();
- cap_data_rate_byte = TRUE;
- break;
-
- case 'i':
- if (report_all_infos) disable_all_infos();
- cap_data_rate_bit = TRUE;
- break;
-
- case 'z':
- if (report_all_infos) disable_all_infos();
- cap_packet_size = TRUE;
- break;
-
- case 'x':
- if (report_all_infos) disable_all_infos();
- cap_packet_rate = TRUE;
- break;
-
- case 'H':
- if (report_all_infos) disable_all_infos();
- cap_file_hashes = TRUE;
- break;
-
- case 'o':
- if (report_all_infos) disable_all_infos();
- cap_order = TRUE;
- break;
-
- case 'k':
- if (report_all_infos) disable_all_infos();
- cap_comment = TRUE;
- break;
-
- case 'K':
- cap_comment = FALSE;
- break;
-
- case 'F':
- if (report_all_infos) disable_all_infos();
- cap_file_more_info = TRUE;
- break;
-
- case 'I':
- if (report_all_infos) disable_all_infos();
- cap_file_idb = TRUE;
- break;
-
- case 'n':
- if (report_all_infos) disable_all_infos();
- cap_file_nrb = TRUE;
- break;
-
- case 'D':
- if (report_all_infos) disable_all_infos();
- cap_file_dsb = TRUE;
- break;
-
- case 'C':
- stop_after_failure = TRUE;
- break;
-
- case 'A':
- enable_all_infos();
- break;
-
- case 'L':
- long_report = TRUE;
- break;
-
- case 'T':
- long_report = FALSE;
- break;
-
- case 'M':
- machine_readable = TRUE;
- break;
-
- case 'R':
- table_report_header = TRUE;
- break;
-
- case 'r':
- table_report_header = FALSE;
- break;
-
- case 'N':
- quote_char = '\0';
- break;
-
- case 'q':
- quote_char = '\'';
- break;
-
- case 'Q':
- quote_char = '"';
- break;
-
- case 'B':
- field_separator = '\t';
- break;
-
- case 'm':
- field_separator = ',';
- break;
-
- case 'b':
- field_separator = ' ';
- break;
-
- case 'h':
- show_help_header("Print various information (infos) about capture files.");
- print_usage(stdout);
- goto exit;
- break;
+ /*
+ * Get credential information for later use.
+ */
+ init_process_policies();
- case 'v':
- show_version();
- goto 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,
+ "capinfos: Can't get pathname of directory containing the capinfos program: %s.\n",
+ init_progfile_dir_error);
+ g_free(init_progfile_dir_error);
+ }
- case '?': /* Bad flag - print usage message */
+ init_report_message("capinfos", &capinfos_report_routines);
+
+ wtap_init(TRUE);
+
+ /* Process the options */
+ while ((opt = ws_getopt_long(argc, argv, "abcdehiklmnoqrstuvxyzABCDEFHIKLMNQRST", long_options, NULL)) !=-1) {
+
+ switch (opt) {
+
+ case 't':
+ if (report_all_infos) disable_all_infos();
+ cap_file_type = TRUE;
+ break;
+
+ case 'E':
+ if (report_all_infos) disable_all_infos();
+ cap_file_encap = TRUE;
+ break;
+
+ case 'l':
+ if (report_all_infos) disable_all_infos();
+ cap_snaplen = TRUE;
+ break;
+
+ case 'c':
+ if (report_all_infos) disable_all_infos();
+ cap_packet_count = TRUE;
+ break;
+
+ case 's':
+ if (report_all_infos) disable_all_infos();
+ cap_file_size = TRUE;
+ break;
+
+ case 'd':
+ if (report_all_infos) disable_all_infos();
+ cap_data_size = TRUE;
+ break;
+
+ case 'u':
+ if (report_all_infos) disable_all_infos();
+ cap_duration = TRUE;
+ break;
+
+ case 'a':
+ if (report_all_infos) disable_all_infos();
+ cap_start_time = TRUE;
+ break;
+
+ case 'e':
+ if (report_all_infos) disable_all_infos();
+ cap_end_time = TRUE;
+ break;
+
+ case 'S':
+ time_as_secs = TRUE;
+ break;
+
+ case 'y':
+ if (report_all_infos) disable_all_infos();
+ cap_data_rate_byte = TRUE;
+ break;
+
+ case 'i':
+ if (report_all_infos) disable_all_infos();
+ cap_data_rate_bit = TRUE;
+ break;
+
+ case 'z':
+ if (report_all_infos) disable_all_infos();
+ cap_packet_size = TRUE;
+ break;
+
+ case 'x':
+ if (report_all_infos) disable_all_infos();
+ cap_packet_rate = TRUE;
+ break;
+
+ case 'H':
+ if (report_all_infos) disable_all_infos();
+ cap_file_hashes = TRUE;
+ break;
+
+ case 'o':
+ if (report_all_infos) disable_all_infos();
+ cap_order = TRUE;
+ break;
+
+ case 'k':
+ if (report_all_infos) disable_all_infos();
+ cap_comment = TRUE;
+ break;
+
+ case 'K':
+ cap_comment = FALSE;
+ break;
+
+ case 'F':
+ if (report_all_infos) disable_all_infos();
+ cap_file_more_info = TRUE;
+ break;
+
+ case 'I':
+ if (report_all_infos) disable_all_infos();
+ cap_file_idb = TRUE;
+ break;
+
+ case 'n':
+ if (report_all_infos) disable_all_infos();
+ cap_file_nrb = TRUE;
+ break;
+
+ case 'D':
+ if (report_all_infos) disable_all_infos();
+ cap_file_dsb = TRUE;
+ break;
+
+ case 'C':
+ stop_after_failure = TRUE;
+ break;
+
+ case 'A':
+ enable_all_infos();
+ break;
+
+ case 'L':
+ long_report = TRUE;
+ break;
+
+ case 'T':
+ long_report = FALSE;
+ break;
+
+ case 'M':
+ machine_readable = TRUE;
+ break;
+
+ case 'R':
+ table_report_header = TRUE;
+ break;
+
+ case 'r':
+ table_report_header = FALSE;
+ break;
+
+ case 'N':
+ quote_char = '\0';
+ break;
+
+ case 'q':
+ quote_char = '\'';
+ break;
+
+ case 'Q':
+ quote_char = '"';
+ break;
+
+ case 'B':
+ field_separator = '\t';
+ break;
+
+ case 'm':
+ field_separator = ',';
+ break;
+
+ case 'b':
+ field_separator = ' ';
+ break;
+
+ case 'h':
+ show_help_header("Print various information (infos) about capture files.");
+ print_usage(stdout);
+ goto exit;
+ break;
+
+ case 'v':
+ show_version();
+ goto exit;
+ break;
+
+ case '?': /* Bad flag - print usage message */
+ print_usage(stderr);
+ overall_error_status = INVALID_OPTION;
+ goto exit;
+ break;
+ }
+ }
+
+ if ((argc - ws_optind) < 1) {
print_usage(stderr);
overall_error_status = INVALID_OPTION;
goto exit;
- break;
}
- }
-
- if ((argc - ws_optind) < 1) {
- print_usage(stderr);
- overall_error_status = INVALID_OPTION;
- goto exit;
- }
-
- if (!long_report && table_report_header) {
- print_stats_table_header();
- }
-
- if (cap_file_hashes) {
- gcry_check_version(NULL);
- gcry_md_open(&hd, GCRY_MD_SHA256, 0);
- if (hd) {
- gcry_md_enable(hd, GCRY_MD_RMD160);
- gcry_md_enable(hd, GCRY_MD_SHA1);
+
+ if (!long_report && table_report_header) {
+ print_stats_table_header();
}
- hash_buf = (char *)g_malloc(HASH_BUF_SIZE);
- }
- overall_error_status = 0;
+ if (cap_file_hashes) {
+ gcry_check_version(NULL);
+ gcry_md_open(&hd, GCRY_MD_SHA256, 0);
+ if (hd) {
+ gcry_md_enable(hd, GCRY_MD_RMD160);
+ gcry_md_enable(hd, GCRY_MD_SHA1);
+ }
+ hash_buf = (char *)g_malloc(HASH_BUF_SIZE);
+ }
- for (opt = ws_optind; opt < argc; opt++) {
+ overall_error_status = 0;
- status = process_cap_file(argv[opt], need_separator);
- if (status) {
- /* Something failed. It's been reported; remember that processing
- one file failed and, if -C was specified, stop. */
- overall_error_status = status;
- if (stop_after_failure)
- goto exit;
- }
- if (status != 2) {
- /* Either it succeeded or it got a "short read" but printed
- information anyway. Note that we need a blank line before
- the next file's information, to separate it from the
- previous file. */
- need_separator = TRUE;
+ for (opt = ws_optind; opt < argc; opt++) {
+
+ status = process_cap_file(argv[opt], need_separator);
+ if (status) {
+ /* Something failed. It's been reported; remember that processing
+ one file failed and, if -C was specified, stop. */
+ overall_error_status = status;
+ if (stop_after_failure)
+ goto exit;
+ }
+ if (status != 2) {
+ /* Either it succeeded or it got a "short read" but printed
+ information anyway. Note that we need a blank line before
+ the next file's information, to separate it from the
+ previous file. */
+ need_separator = TRUE;
+ }
}
- }
exit:
- g_free(hash_buf);
- gcry_md_close(hd);
- wtap_cleanup();
- free_progdirs();
- return overall_error_status;
+ g_free(hash_buf);
+ gcry_md_close(hd);
+ 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:
- */
diff --git a/captype.c b/captype.c
index 5820210184..fe541f5387 100644
--- a/captype.c
+++ b/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 }
- };
-
- /*
- * Set the C-language locale to the native environment and set the
- * code page to UTF-8 on Windows.
- */
+ 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.
+ */
#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 */
+ print_usage(stderr);
+ exit(1);
+ break;
+ }
+ }
- case '?': /* Bad flag - print usage message */
+ 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);
-/*
- * 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:
- */
+ 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;
+}
diff --git a/cfile.c b/cfile.c
index ef4b28c58d..fbc2b98df6 100644
--- a/cfile.c
+++ b/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:
- */
diff --git a/cfile.h b/cfile.h
index e532ecc286..70b0ef915c 100644
--- a/cfile.h
+++ b/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.) */
-
- 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). */
-
- guint32 cum_bytes;
+ 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 */
+
+ gpointer window; /* Top-level window associated with file */
+ gulong computed_elapsed; /* Elapsed time to load the file (in msec). */
+
+ 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:
- */
diff --git a/dftest.c b/dftest.c
index 1c7ba933b5..b5cc14496a 100644
--- a/dftest.c
+++ b/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;
-
- 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);
-
- /* Early logging command-line initialization. */
- ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
-
- /*
- * 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);
- }
-
- init_report_message("dftest", &dftest_report_routines);
-
- 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);
-
- /* 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.
- */
+ 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);
+
+ /* 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);
+
+ /*
+ * 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);
+ }
+
+ init_report_message("dftest", &dftest_report_routines);
+
+ 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);
+
+ /* 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.
+ */
#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();
-
- /* 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);
- }
-
- /* Get filter text */
- text = get_args_as_string(argc, argv, 1);
-
- 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);
- }
-
- printf("\n");
-
- if (df == NULL)
- printf("Filter is empty\n");
- else
- dfilter_dump(df);
-
- dfilter_free(df);
- epan_cleanup();
- g_free(text);
- exit(0);
+ /* 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();
+
+ /* 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);
+
+ 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);
+ }
+
+ printf("\n");
+
+ if (df == NULL)
+ printf("Filter is empty\n");
+ else
+ dfilter_dump(df);
+
+ 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:
- */
diff --git a/file.c b/file.c
index ea916c7743..23c5fef297 100644
--- a/file.c
+++ b/file.c
@@ -79,41 +79,41 @@ static gboolean read_record(capture_file *cf, wtap_rec *rec, Buffer *buf,
static void rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect);
typedef enum {
- MR_NOTMATCHED,
- MR_MATCHED,
- MR_ERROR
+ MR_NOTMATCHED,
+ MR_MATCHED,
+ MR_ERROR
} match_result;
typedef match_result (*ws_match_function)(capture_file *, frame_data *,
- wtap_rec *, Buffer *, void *);
+ wtap_rec *, Buffer *, void *);
static match_result match_protocol_tree(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static void match_subtree_text(proto_node *node, gpointer data);
static match_result match_summary_line(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_narrow_and_wide(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_narrow_and_wide_case(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_narrow(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_narrow_case(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_wide(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_wide_case(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_binary(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_regex(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_dfilter(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_marked(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static match_result match_time_reference(capture_file *cf, frame_data *fdata,
- wtap_rec *, Buffer *, void *criterion);
+ wtap_rec *, Buffer *, void *criterion);
static gboolean find_packet(capture_file *cf, ws_match_function match_function,
- void *criterion, search_direction dir);
+ void *criterion, search_direction dir);
static void cf_rename_failure_alert_box(const char *filename, int err);
@@ -137,7 +137,7 @@ static guint32 max_records = G_MAXUINT32;
void
cf_set_max_records(guint max_records_arg)
{
- max_records = max_records_arg;
+ max_records = max_records_arg;
}
/*
@@ -146,8 +146,8 @@ cf_set_max_records(guint max_records_arg)
* instance for the signals.
*/
typedef struct {
- cf_callback_t cb_fct;
- gpointer user_data;
+ cf_callback_t cb_fct;
+ gpointer user_data;
} cf_callback_data_t;
static GList *cf_callbacks = NULL;
@@ -155,193 +155,193 @@ static GList *cf_callbacks = NULL;
static void
cf_callback_invoke(int event, gpointer data)
{
- cf_callback_data_t *cb;
- GList *cb_item = cf_callbacks;
+ cf_callback_data_t *cb;
+ GList *cb_item = cf_callbacks;
- /* there should be at least one interested */
- ws_assert(cb_item != NULL);
+ /* there should be at least one interested */
+ ws_assert(cb_item != NULL);
- while (cb_item != NULL) {
- cb = (cf_callback_data_t *)cb_item->data;
- cb->cb_fct(event, data, cb->user_data);
- cb_item = g_list_next(cb_item);
- }
+ while (cb_item != NULL) {
+ cb = (cf_callback_data_t *)cb_item->data;
+ cb->cb_fct(event, data, cb->user_data);
+ cb_item = g_list_next(cb_item);
+ }
}
-
void
cf_callback_add(cf_callback_t func, gpointer user_data)
{
- cf_callback_data_t *cb;
+ cf_callback_data_t *cb;
- cb = g_new(cf_callback_data_t,1);
- cb->cb_fct = func;
- cb->user_data = user_data;
+ cb = g_new(cf_callback_data_t,1);
+ cb->cb_fct = func;
+ cb->user_data = user_data;
- cf_callbacks = g_list_prepend(cf_callbacks, cb);
+ cf_callbacks = g_list_prepend(cf_callbacks, cb);
}
void
cf_callback_remove(cf_callback_t func, gpointer user_data)
{
- cf_callback_data_t *cb;
- GList *cb_item = cf_callbacks;
-
- while (cb_item != NULL) {
- cb = (cf_callback_data_t *)cb_item->data;
- if (cb->cb_fct == func && cb->user_data == user_data) {
- cf_callbacks = g_list_remove(cf_callbacks, cb);
- g_free(cb);
- return;
+ cf_callback_data_t *cb;
+ GList *cb_item = cf_callbacks;
+
+ while (cb_item != NULL) {
+ cb = (cf_callback_data_t *)cb_item->data;
+ if (cb->cb_fct == func && cb->user_data == user_data) {
+ cf_callbacks = g_list_remove(cf_callbacks, cb);
+ g_free(cb);
+ return;
+ }
+ cb_item = g_list_next(cb_item);
}
- cb_item = g_list_next(cb_item);
- }
- ws_assert_not_reached();
+ ws_assert_not_reached();
}
void
cf_timestamp_auto_precision(capture_file *cf)
{
- int i;
+ int i;
- /* don't try to get the file's precision if none is opened */
- if (cf->state == FILE_CLOSED) {
- return;
- }
+ /* don't try to get the file's precision if none is opened */
+ if (cf->state == FILE_CLOSED) {
+ return;
+ }
- /* Set the column widths of those columns that show the time in
- "command-line-specified" format. */
- for (i = 0; i < cf->cinfo.num_cols; i++) {
- if (col_has_time_fmt(&cf->cinfo, i)) {
- packet_list_resize_column(i);
+ /* Set the column widths of those columns that show the time in
+ "command-line-specified" format. */
+ for (i = 0; i < cf->cinfo.num_cols; i++) {
+ if (col_has_time_fmt(&cf->cinfo, i)) {
+ packet_list_resize_column(i);
+ }
}
- }
}
gulong
cf_get_computed_elapsed(capture_file *cf)
{
- return cf->computed_elapsed;
+ return cf->computed_elapsed;
}
-static void compute_elapsed(capture_file *cf, gint64 start_time)
+static void
+compute_elapsed(capture_file *cf, gint64 start_time)
{
- gint64 delta_time = g_get_monotonic_time() - start_time;
+ gint64 delta_time = g_get_monotonic_time() - start_time;
- cf->computed_elapsed = (gulong) (delta_time / 1000); /* ms */
+ cf->computed_elapsed = (gulong) (delta_time / 1000); /* ms */
}
static const nstime_t *
ws_get_frame_ts(struct packet_provider_data *prov, guint32 frame_num)
{
- if (prov->prev_dis && prov->prev_dis->num == frame_num)
- return &prov->prev_dis->abs_ts;
+ if (prov->prev_dis && prov->prev_dis->num == frame_num)
+ return &prov->prev_dis->abs_ts;
- if (prov->prev_cap && prov->prev_cap->num == frame_num)
- return &prov->prev_cap->abs_ts;
+ if (prov->prev_cap && prov->prev_cap->num == frame_num)
+ return &prov->prev_cap->abs_ts;
- if (prov->frames) {
- frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
+ if (prov->frames) {
+ frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
- return (fd) ? &fd->abs_ts : NULL;
- }
+ return (fd) ? &fd->abs_ts : NULL;
+ }
- return NULL;
+ return NULL;
}
static epan_t *
ws_epan_new(capture_file *cf)
{
- static const struct packet_provider_funcs funcs = {
- ws_get_frame_ts,
- cap_file_provider_get_interface_name,
- cap_file_provider_get_interface_description,
- cap_file_provider_get_modified_block
- };
-
- return epan_new(&cf->provider, &funcs);
+ static const struct packet_provider_funcs funcs = {
+ ws_get_frame_ts,
+ cap_file_provider_get_interface_name,
+ cap_file_provider_get_interface_description,
+ cap_file_provider_get_modified_block
+ };
+
+ return epan_new(&cf->provider, &funcs);
}
cf_status_t
cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
- wtap *wth;
- gchar *err_info;
+ wtap *wth;
+ gchar *err_info;
- wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
- if (wth == NULL)
- goto fail;
-
- /* The open succeeded. Close whatever capture file we had open,
- and fill in the information for this file. */
- cf_close(cf);
-
- /* Initialize the record metadata. */
- wtap_rec_init(&cf->rec);
-
- /* XXX - we really want to initialize this after we've read all
- the packets, so we know how much we'll ultimately need. */
- ws_buffer_init(&cf->buf, 1514);
-
- /* We're about to start reading the file. */
- cf->state = FILE_READ_IN_PROGRESS;
-
- cf->provider.wth = wth;
- cf->f_datalen = 0;
+ wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
+ if (wth == NULL)
+ goto fail;
- /* Set the file name because we need it to set the follow stream filter.
- XXX - is that still true? We need it for other reasons, though,
- in any case. */
- cf->filename = g_strdup(fname);
+ /* The open succeeded. Close whatever capture file we had open,
+ and fill in the information for this file. */
+ cf_close(cf);
- /* Indicate whether it's a permanent or temporary file. */
- cf->is_tempfile = is_tempfile;
+ /* Initialize the record metadata. */
+ wtap_rec_init(&cf->rec);
- /* No user changes yet. */
- cf->unsaved_changes = FALSE;
+ /* XXX - we really want to initialize this after we've read all
+ the packets, so we know how much we'll ultimately need. */
+ ws_buffer_init(&cf->buf, 1514);
- cf->computed_elapsed = 0;
+ /* We're about to start reading the file. */
+ cf->state = FILE_READ_IN_PROGRESS;
- cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
- cf->open_type = type;
- cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
- cf->count = 0;
- cf->packet_comment_count = 0;
- cf->displayed_count = 0;
- cf->marked_count = 0;
- cf->ignored_count = 0;
- cf->ref_time_count = 0;
- cf->drops_known = FALSE;
- cf->drops = 0;
- cf->snap = wtap_snapshot_length(cf->provider.wth);
+ cf->provider.wth = wth;
+ cf->f_datalen = 0;
- /* Allocate a frame_data_sequence for the frames in this file */
- cf->provider.frames = new_frame_data_sequence();
+ /* Set the file name because we need it to set the follow stream filter.
+ XXX - is that still true? We need it for other reasons, though,
+ in any case. */
+ cf->filename = g_strdup(fname);
- nstime_set_zero(&cf->elapsed_time);
- cf->provider.ref = NULL;
- cf->provider.prev_dis = NULL;
- cf->provider.prev_cap = NULL;
- cf->cum_bytes = 0;
+ /* Indicate whether it's a permanent or temporary file. */
+ cf->is_tempfile = is_tempfile;
- /* Create new epan session for dissection.
- * (The old one was freed in cf_close().)
- */
- cf->epan = ws_epan_new(cf);
+ /* No user changes yet. */
+ cf->unsaved_changes = FALSE;
+
+ cf->computed_elapsed = 0;
+
+ cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
+ cf->open_type = type;
+ cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
+ cf->count = 0;
+ cf->packet_comment_count = 0;
+ cf->displayed_count = 0;
+ cf->marked_count = 0;
+ cf->ignored_count = 0;
+ cf->ref_time_count = 0;
+ cf->drops_known = FALSE;
+ cf->drops = 0;
+ cf->snap = wtap_snapshot_length(cf->provider.wth);
+
+ /* Allocate a frame_data_sequence for the frames in this file */
+ cf->provider.frames = new_frame_data_sequence();
+
+ nstime_set_zero(&cf->elapsed_time);
+ cf->provider.ref = NULL;
+ cf->provider.prev_dis = NULL;
+ cf->provider.prev_cap = NULL;
+ cf->cum_bytes = 0;
+
+ /* Create new epan session for dissection.
+ * (The old one was freed in cf_close().)
+ */
+ cf->epan = ws_epan_new(cf);
- packet_list_queue_draw();
- cf_callback_invoke(cf_cb_file_opened, cf);
+ packet_list_queue_draw();
+ cf_callback_invoke(cf_cb_file_opened, cf);
- wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
- wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
- wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
+ wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
+ wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
+ wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
- return CF_OK;
+ return CF_OK;
fail:
- cfile_open_failure_alert_box(fname, *err, err_info);
- return CF_ERROR;
+ cfile_open_failure_alert_box(fname, *err, err_info);
+ return CF_ERROR;
}
/*
@@ -350,100 +350,100 @@ fail:
static void
cf_add_encapsulation_type(capture_file *cf, int encap)
{
- guint i;
-
- for (i = 0; i < cf->linktypes->len; i++) {
- if (g_array_index(cf->linktypes, gint, i) == encap)
- return; /* it's already there */
- }
- /* It's not already there - add it. */
- g_array_append_val(cf->linktypes, encap);
+ guint i;
+
+ for (i = 0; i < cf->linktypes->len; i++) {
+ if (g_array_index(cf->linktypes, gint, i) == encap)
+ return; /* it's already there */
+ }
+ /* It's not already there - add it. */
+ g_array_append_val(cf->linktypes, encap);
}
/* Reset everything to a pristine state */
void
cf_close(capture_file *cf)
{
- cf->stop_flag = FALSE;
- if (cf->state == FILE_CLOSED)
- return; /* Nothing to do */
+ cf->stop_flag = FALSE;
+ if (cf->state == FILE_CLOSED)
+ return; /* Nothing to do */
- /* Die if we're in the middle of reading a file. */
- ws_assert(cf->state != FILE_READ_IN_PROGRESS);
- ws_assert(!cf->read_lock);
+ /* Die if we're in the middle of reading a file. */
+ ws_assert(cf->state != FILE_READ_IN_PROGRESS);
+ ws_assert(!cf->read_lock);
- cf_callback_invoke(cf_cb_file_closing, cf);
+ cf_callback_invoke(cf_cb_file_closing, cf);
- /* close things, if not already closed before */
- color_filters_cleanup();
+ /* close things, if not already closed before */
+ color_filters_cleanup();
- if (cf->provider.wth) {
- wtap_close(cf->provider.wth);
- cf->provider.wth = NULL;
- }
- /* We have no file open... */
- if (cf->filename != NULL) {
- /* If it's a temporary file, remove it. */
- if (cf->is_tempfile)
- ws_unlink(cf->filename);
- g_free(cf->filename);
- cf->filename = NULL;
- }
- /* ...which means we have no changes to that file to save. */
- cf->unsaved_changes = FALSE;
-
- /* no open_routine type */
- cf->open_type = WTAP_TYPE_AUTO;
-
- /* Clean up the record metadata. */
- wtap_rec_cleanup(&cf->rec);
-
- /* Clear the packet list. */
- packet_list_freeze();
- packet_list_clear();
- packet_list_thaw();
-
- /* Free up the packet buffer. */
- ws_buffer_free(&cf->buf);
-
- dfilter_free(cf->rfcode);
- cf->rfcode = NULL;
- if (cf->provider.frames != NULL) {
- free_frame_data_sequence(cf->provider.frames);
- cf->provider.frames = NULL;
- }
- if (cf->provider.frames_modified_blocks) {
- g_tree_destroy(cf->provider.frames_modified_blocks);
- cf->provider.frames_modified_blocks = NULL;
- }
- cf_unselect_packet(cf); /* nothing to select */
- cf->first_displayed = 0;
- cf->last_displayed = 0;
-
- /* No frames, no frame selected, no field in that frame selected. */
- cf->count = 0;
- cf->current_frame = NULL;
- cf->current_row = 0;
- cf->finfo_selected = NULL;
-
- /* No frame link-layer types, either. */
- if (cf->linktypes != NULL) {
- g_array_free(cf->linktypes, TRUE);
- cf->linktypes = NULL;
- }
-
- cf->f_datalen = 0;
- nstime_set_zero(&cf->elapsed_time);
-
- reset_tap_listeners();
-
- epan_free(cf->epan);
- cf->epan = NULL;
-
- /* We have no file open. */
- cf->state = FILE_CLOSED;
-
- cf_callback_invoke(cf_cb_file_closed, cf);
+ if (cf->provider.wth) {
+ wtap_close(cf->provider.wth);
+ cf->provider.wth = NULL;
+ }
+ /* We have no file open... */
+ if (cf->filename != NULL) {
+ /* If it's a temporary file, remove it. */
+ if (cf->is_tempfile)
+ ws_unlink(cf->filename);
+ g_free(cf->filename);
+ cf->filename = NULL;
+ }
+ /* ...which means we have no changes to that file to save. */
+ cf->unsaved_changes = FALSE;
+
+ /* no open_routine type */
+ cf->open_type = WTAP_TYPE_AUTO;
+
+ /* Clean up the record metadata. */
+ wtap_rec_cleanup(&cf->rec);
+
+ /* Clear the packet list. */
+ packet_list_freeze();
+ packet_list_clear();
+ packet_list_thaw();
+
+ /* Free up the packet buffer. */
+ ws_buffer_free(&cf->buf);
+
+ dfilter_free(cf->rfcode);
+ cf->rfcode = NULL;
+ if (cf->provider.frames != NULL) {
+ free_frame_data_sequence(cf->provider.frames);
+ cf->provider.frames = NULL;
+ }
+ if (cf->provider.frames_modified_blocks) {
+ g_tree_destroy(cf->provider.frames_modified_blocks);
+ cf->provider.frames_modified_blocks = NULL;
+ }
+ cf_unselect_packet(cf); /* nothing to select */
+ cf->first_displayed = 0;
+ cf->last_displayed = 0;
+
+ /* No frames, no frame selected, no field in that frame selected. */
+ cf->count = 0;
+ cf->current_frame = NULL;
+ cf->current_row = 0;
+ cf->finfo_selected = NULL;
+
+ /* No frame link-layer types, either. */
+ if (cf->linktypes != NULL) {
+ g_array_free(cf->linktypes, TRUE);
+ cf->linktypes = NULL;
+ }
+
+ cf->f_datalen = 0;
+ nstime_set_zero(&cf->elapsed_time);
+
+ reset_tap_listeners();
+
+ epan_free(cf->epan);
+ cf->epan = NULL;
+
+ /* We have no file open. */
+ cf->state = FILE_CLOSED;
+
+ cf_callback_invoke(cf_cb_file_closed, cf);
}
/*
@@ -453,797 +453,808 @@ cf_close(capture_file *cf)
static inline gboolean
progress_is_slow(progdlg_t *progdlg, GTimer *prog_timer, gint64 size, gint64 pos)
{
- double elapsed;
+ double elapsed;
- if (progdlg) return FALSE;
- elapsed = g_timer_elapsed(prog_timer, NULL);
- if ((elapsed / 2 > PROGBAR_SHOW_DELAY && (size / pos) > 2) /* It looks like we're going to be slow. */
- || elapsed > PROGBAR_SHOW_DELAY) { /* We are indeed slow. */
- return TRUE;
- }
- return FALSE;
+ if (progdlg) return FALSE;
+ elapsed = g_timer_elapsed(prog_timer, NULL);
+ if ((elapsed / 2 > PROGBAR_SHOW_DELAY && (size / pos) > 2) /* It looks like we're going to be slow. */
+ || elapsed > PROGBAR_SHOW_DELAY) { /* We are indeed slow. */
+ return TRUE;
+ }
+ return FALSE;
}
static float
calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos, gchar *status_str, gulong status_size)
{
- float progbar_val;
+ float progbar_val;
- progbar_val = (gfloat) file_pos / (gfloat) size;
- if (progbar_val > 1.0) {
+ progbar_val = (gfloat) file_pos / (gfloat) size;
+ if (progbar_val > 1.0) {
- /* The file probably grew while we were reading it.
- * Update file size, and try again.
- */
- size = wtap_file_size(cf->provider.wth, NULL);
+ /* The file probably grew while we were reading it.
+ * Update file size, and try again.
+ */
+ size = wtap_file_size(cf->provider.wth, NULL);
- if (size >= 0)
- progbar_val = (gfloat) file_pos / (gfloat) size;
+ if (size >= 0)
+ progbar_val = (gfloat) file_pos / (gfloat) size;
- /* If it's still > 1, either "wtap_file_size()" failed (in which
- * case there's not much we can do about it), or the file
- * *shrank* (in which case there's not much we can do about
- * it); just clip the progress value at 1.0.
- */
- if (progbar_val > 1.0f)
- progbar_val = 1.0f;
- }
+ /* If it's still > 1, either "wtap_file_size()" failed (in which
+ * case there's not much we can do about it), or the file
+ * *shrank* (in which case there's not much we can do about
+ * it); just clip the progress value at 1.0.
+ */
+ if (progbar_val > 1.0f)
+ progbar_val = 1.0f;
+ }
- snprintf(status_str, status_size,
- "%" PRId64 "KB of %" PRId64 "KB",
- file_pos / 1024, size / 1024);
+ snprintf(status_str, status_size,
+ "%" PRId64 "KB of %" PRId64 "KB",
+ file_pos / 1024, size / 1024);
- return progbar_val;
+ return progbar_val;
}
cf_read_status_t
cf_read(capture_file *cf, gboolean reloading)
{
- int err = 0;
- gchar *err_info = NULL;
- volatile gboolean too_many_records = FALSE;
- gchar *name_ptr;
- progdlg_t *volatile progbar = NULL;
- GTimer *prog_timer = g_timer_new();
- gint64 size;
- gint64 start_time;
- epan_dissect_t edt;
- wtap_rec rec;
- Buffer buf;
- dfilter_t *dfcode;
- column_info *cinfo;
- volatile gboolean create_proto_tree;
- guint tap_flags;
- gboolean compiled _U_;
- volatile gboolean is_read_aborted = FALSE;
-
- /* The update_progress_dlg call below might end up accepting a user request to
- * trigger redissection/rescans which can modify/destroy the dissection
- * context ("cf->epan"). That condition should be prevented by callers, but in
- * case it occurs let's fail gracefully.
- */
- if (cf->read_lock) {
- ws_warning("Failing due to recursive cf_read(\"%s\", %d) call!",
- cf->filename, reloading);
- return CF_READ_ERROR;
- }
- cf->read_lock = TRUE;
-
- /* Compile the current display filter.
- * We assume this will not fail since cf->dfilter is only set in
- * cf_filter IFF the filter was valid.
- */
- compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
- ws_assert(!cf->dfilter || (compiled && dfcode));
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a display filter;
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * a postdissector wants field values or protocols on
- * the first pass.
- */
- create_proto_tree =
- (dfcode != NULL || have_filtering_tap_listeners() ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids());
-
- reset_tap_listeners();
-
- name_ptr = g_filename_display_basename(cf->filename);
-
- if (reloading)
- cf_callback_invoke(cf_cb_file_reload_started, cf);
- else
- cf_callback_invoke(cf_cb_file_read_started, cf);
-
- /* Record the file's compression type.
- XXX - do we know this at open time? */
- cf->compression_type = wtap_get_compression_type(cf->provider.wth);
-
- /* The packet list window will be empty until the file is completly loaded */
- packet_list_freeze();
-
- cf->stop_flag = FALSE;
- start_time = g_get_monotonic_time();
-
- epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
-
- /* If any tap listeners require the columns, construct them. */
- cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
-
- /* Find the size of the file. */
- size = wtap_file_size(cf->provider.wth, NULL);
-
- g_timer_start(prog_timer);
-
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
-
- TRY {
- guint32 count = 0;
-
- gint64 file_pos;
- gint64 data_offset;
-
- float progbar_val;
- gchar status_str[100];
+ int err = 0;
+ gchar *err_info = NULL;
+ volatile gboolean too_many_records = FALSE;
+ gchar *name_ptr;
+ progdlg_t *volatile progbar = NULL;
+ GTimer *prog_timer = g_timer_new();
+ gint64 size;
+ gint64 start_time;
+ epan_dissect_t edt;
+ wtap_rec rec;
+ Buffer buf;
+ dfilter_t *dfcode;
+ column_info *cinfo;
+ volatile gboolean create_proto_tree;
+ guint tap_flags;
+ gboolean compiled _U_;
+ volatile gboolean is_read_aborted = FALSE;
+
+ /* The update_progress_dlg call below might end up accepting a user request to
+ * trigger redissection/rescans which can modify/destroy the dissection
+ * context ("cf->epan"). That condition should be prevented by callers, but in
+ * case it occurs let's fail gracefully.
+ */
+ if (cf->read_lock) {
+ ws_warning("Failing due to recursive cf_read(\"%s\", %d) call!",
+ cf->filename, reloading);
+ return CF_READ_ERROR;
+ }
+ cf->read_lock = TRUE;
- while ((wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info,
- &data_offset))) {
- if (size >= 0) {
- if (cf->count == max_records) {
- /*
- * Quit if we've already read the maximum number of
- * records allowed.
- */
- too_many_records = TRUE;
- break;
- }
- count++;
- file_pos = wtap_read_so_far(cf->provider.wth);
+ /* Compile the current display filter.
+ * We assume this will not fail since cf->dfilter is only set in
+ * cf_filter IFF the filter was valid.
+ */
+ compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
+ ws_assert(!cf->dfilter || (compiled && dfcode));
- /* Create the progress bar if necessary. */
- if (progress_is_slow(progbar, prog_timer, size, file_pos)) {
- progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
- progbar = delayed_create_progress_dlg(cf->window, NULL, NULL, TRUE,
- &cf->stop_flag, progbar_val);
- }
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
- /*
- * Update the progress bar, but do it only after
- * PROGBAR_UPDATE_INTERVAL has elapsed. Calling update_progress_dlg
- * and packets_bar_update will likely trigger UI paint events, which
- * might take a while depending on the platform and display. Reset
- * our timer *after* painting.
- */
- if (progbar && g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
- progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
- /* update the packet bar content on the first run or frequently on very large files */
- update_progress_dlg(progbar, progbar_val, status_str);
- compute_elapsed(cf, start_time);
- packets_bar_update();
- g_timer_start(prog_timer);
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a display filter;
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * a postdissector wants field values or protocols on
+ * the first pass.
+ */
+ create_proto_tree =
+ (dfcode != NULL || have_filtering_tap_listeners() ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids());
+
+ reset_tap_listeners();
+
+ name_ptr = g_filename_display_basename(cf->filename);
+
+ if (reloading)
+ cf_callback_invoke(cf_cb_file_reload_started, cf);
+ else
+ cf_callback_invoke(cf_cb_file_read_started, cf);
+
+ /* Record the file's compression type.
+ XXX - do we know this at open time? */
+ cf->compression_type = wtap_get_compression_type(cf->provider.wth);
+
+ /* The packet list window will be empty until the file is completly loaded */
+ packet_list_freeze();
+
+ cf->stop_flag = FALSE;
+ start_time = g_get_monotonic_time();
+
+ epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
+
+ /* If any tap listeners require the columns, construct them. */
+ cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+
+ /* Find the size of the file. */
+ size = wtap_file_size(cf->provider.wth, NULL);
+
+ g_timer_start(prog_timer);
+
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+
+ TRY {
+ guint32 count = 0;
+
+ gint64 file_pos;
+ gint64 data_offset;
+
+ float progbar_val;
+ gchar status_str[100];
+
+ while ((wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info,
+ &data_offset))) {
+ if (size >= 0) {
+ if (cf->count == max_records) {
+ /*
+ * Quit if we've already read the maximum number of
+ * records allowed.
+ */
+ too_many_records = TRUE;
+ break;
+ }
+ count++;
+ file_pos = wtap_read_so_far(cf->provider.wth);
+
+ /* Create the progress bar if necessary. */
+ if (progress_is_slow(progbar, prog_timer, size, file_pos)) {
+ progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
+ progbar = delayed_create_progress_dlg(cf->window, NULL, NULL, TRUE,
+ &cf->stop_flag, progbar_val);
+ }
+
+ /*
+ * Update the progress bar, but do it only after
+ * PROGBAR_UPDATE_INTERVAL has elapsed. Calling update_progress_dlg
+ * and packets_bar_update will likely trigger UI paint events, which
+ * might take a while depending on the platform and display. Reset
+ * our timer *after* painting.
+ */
+ if (progbar && g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
+ progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
+ /* update the packet bar content on the first run or frequently on very large files */
+ update_progress_dlg(progbar, progbar_val, status_str);
+ compute_elapsed(cf, start_time);
+ packets_bar_update();
+ g_timer_start(prog_timer);
+ }
+ /*
+ * The previous GUI triggers should not have destroyed the running
+ * session. If that did happen, it could blow up when read_record tries
+ * to use the destroyed edt.session, so detect it right here.
+ */
+ ws_assert(edt.session == cf->epan);
+ }
+
+ if (cf->state == FILE_READ_ABORTED) {
+ /* Well, the user decided to exit Wireshark. Break out of the
+ loop, and let the code below (which is called even if there
+ aren't any packets left to read) exit. */
+ is_read_aborted = TRUE;
+ break;
+ }
+ if (cf->stop_flag) {
+ /* Well, the user decided to abort the read. He/She will be warned and
+ it might be enough for him/her to work with the already loaded
+ packets.
+ This is especially true for very large capture files, where you don't
+ want to wait loading the whole file (which may last minutes or even
+ hours even on fast machines) just to see that it was the wrong file. */
+ break;
+ }
+ read_record(cf, &rec, &buf, dfcode, &edt, cinfo, data_offset);
+ wtap_rec_reset(&rec);
}
- /*
- * The previous GUI triggers should not have destroyed the running
- * session. If that did happen, it could blow up when read_record tries
- * to use the destroyed edt.session, so detect it right here.
- */
- ws_assert(edt.session == cf->epan);
- }
-
- if (cf->state == FILE_READ_ABORTED) {
- /* Well, the user decided to exit Wireshark. Break out of the
- loop, and let the code below (which is called even if there
- aren't any packets left to read) exit. */
- is_read_aborted = TRUE;
- break;
- }
- if (cf->stop_flag) {
- /* Well, the user decided to abort the read. He/She will be warned and
- it might be enough for him/her to work with the already loaded
- packets.
- This is especially true for very large capture files, where you don't
- want to wait loading the whole file (which may last minutes or even
- hours even on fast machines) just to see that it was the wrong file. */
- break;
- }
- read_record(cf, &rec, &buf, dfcode, &edt, cinfo, data_offset);
- wtap_rec_reset(&rec);
- }
- }
- CATCH(OutOfMemoryError) {
- simple_message_box(ESD_TYPE_ERROR, NULL,
- "More information and workarounds can be found at\n"
- WS_WIKI_URL("KnownBugs/OutOfMemory"),
- "Sorry, but Wireshark has run out of memory and has to terminate now.");
+ }
+ CATCH(OutOfMemoryError) {
+ simple_message_box(ESD_TYPE_ERROR, NULL,
+ "More information and workarounds can be found at\n"
+ WS_WIKI_URL("KnownBugs/OutOfMemory"),
+ "Sorry, but Wireshark has run out of memory and has to terminate now.");
#if 0
- /* Could we close the current capture and free up memory from that? */
+ /* Could we close the current capture and free up memory from that? */
#else
- /* we have to terminate, as we cannot recover from the memory error */
- exit(1);
+ /* we have to terminate, as we cannot recover from the memory error */
+ exit(1);
#endif
- }
- ENDTRY;
+ }
+ ENDTRY;
- /* We're done reading sequentially through the file. */
- cf->state = FILE_READ_DONE;
+ /* We're done reading sequentially through the file. */
+ cf->state = FILE_READ_DONE;
- /* Destroy the progress bar if it was created. */
- if (progbar != NULL)
- destroy_progress_dlg(progbar);
- g_timer_destroy(prog_timer);
+ /* Destroy the progress bar if it was created. */
+ if (progbar != NULL)
+ destroy_progress_dlg(progbar);
+ g_timer_destroy(prog_timer);
- /* Free the display name */
- g_free(name_ptr);
+ /* Free the display name */
+ g_free(name_ptr);
- /* Cleanup and release all dfilter resources */
- dfilter_free(dfcode);
+ /* Cleanup and release all dfilter resources */
+ dfilter_free(dfcode);
- epan_dissect_cleanup(&edt);
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
+ epan_dissect_cleanup(&edt);
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
- /* Close the sequential I/O side, to free up memory it requires. */
- wtap_sequential_close(cf->provider.wth);
+ /* Close the sequential I/O side, to free up memory it requires. */
+ wtap_sequential_close(cf->provider.wth);
- /* Allow the protocol dissectors to free up memory that they
- * don't need after the sequential run-through of the packets. */
- postseq_cleanup_all_protocols();
+ /* Allow the protocol dissectors to free up memory that they
+ * don't need after the sequential run-through of the packets. */
+ postseq_cleanup_all_protocols();
- /* compute the time it took to load the file */
- compute_elapsed(cf, start_time);
+ /* compute the time it took to load the file */
+ compute_elapsed(cf, start_time);
- /* Set the file encapsulation type now; we don't know what it is until
- we've looked at all the packets, as we don't know until then whether
- there's more than one type (and thus whether it's
- WTAP_ENCAP_PER_PACKET). */
- cf->lnk_t = wtap_file_encap(cf->provider.wth);
+ /* Set the file encapsulation type now; we don't know what it is until
+ we've looked at all the packets, as we don't know until then whether
+ there's more than one type (and thus whether it's
+ WTAP_ENCAP_PER_PACKET). */
+ cf->lnk_t = wtap_file_encap(cf->provider.wth);
- cf->current_frame = frame_data_sequence_find(cf->provider.frames, cf->first_displayed);
- cf->current_row = 0;
+ cf->current_frame = frame_data_sequence_find(cf->provider.frames, cf->first_displayed);
+ cf->current_row = 0;
- packet_list_thaw();
- if (reloading)
- cf_callback_invoke(cf_cb_file_reload_finished, cf);
- else
- cf_callback_invoke(cf_cb_file_read_finished, cf);
+ packet_list_thaw();
+ if (reloading)
+ cf_callback_invoke(cf_cb_file_reload_finished, cf);
+ else
+ cf_callback_invoke(cf_cb_file_read_finished, cf);
- /* If we have any displayed packets to select, select the first of those
- packets by making the first row the selected row. */
- if (cf->first_displayed != 0) {
- packet_list_select_first_row();
- }
+ /* If we have any displayed packets to select, select the first of those
+ packets by making the first row the selected row. */
+ if (cf->first_displayed != 0) {
+ packet_list_select_first_row();
+ }
- /* It is safe again to execute redissections. */
- ws_assert(cf->read_lock);
- cf->read_lock = FALSE;
+ /* It is safe again to execute redissections. */
+ ws_assert(cf->read_lock);
+ cf->read_lock = FALSE;
- if (is_read_aborted) {
- /*
- * Well, the user decided to exit Wireshark while reading this *offline*
- * capture file (Live captures are handled by something like
- * cf_continue_tail). Clean up accordingly.
- */
- cf_close(cf);
- cf->redissection_queued = RESCAN_NONE;
- return CF_READ_ABORTED;
- }
-
- if (cf->redissection_queued != RESCAN_NONE) {
- /* Redissection was queued up. Clear the request and perform it now. */
- gboolean redissect = cf->redissection_queued == RESCAN_REDISSECT;
- rescan_packets(cf, NULL, NULL, redissect);
- }
-
- if (cf->stop_flag) {
- simple_message_box(ESD_TYPE_WARN, NULL,
- "The remaining packets in the file were discarded.\n"
- "\n"
- "As a lot of packets from the original file will be missing,\n"
- "remember to be careful when saving the current content to a file.\n",
- "File loading was cancelled.");
- return CF_READ_ERROR;
- }
-
- if (err != 0) {
- /* Put up a message box noting that the read failed somewhere along
- the line. Don't throw out the stuff we managed to read, though,
- if any. */
- cfile_read_failure_alert_box(NULL, err, err_info);
- return CF_READ_ERROR;
- } else if (too_many_records) {
- simple_message_box(ESD_TYPE_WARN, NULL,
- "The remaining packets in the file were discarded.\n"
- "\n"
- "As a lot of packets from the original file will be missing,\n"
- "remember to be careful when saving the current content to a file.\n"
- "\n"
- "The command-line utility editcap can be used to split "
- "the file into multiple smaller files",
- "The file contains more records than the maximum "
- "supported number of records, %u.", max_records);
- return CF_READ_ERROR;
- } else
- return CF_READ_OK;
+ if (is_read_aborted) {
+ /*
+ * Well, the user decided to exit Wireshark while reading this *offline*
+ * capture file (Live captures are handled by something like
+ * cf_continue_tail). Clean up accordingly.
+ */
+ cf_close(cf);
+ cf->redissection_queued = RESCAN_NONE;
+ return CF_READ_ABORTED;
+ }
+
+ if (cf->redissection_queued != RESCAN_NONE) {
+ /* Redissection was queued up. Clear the request and perform it now. */
+ gboolean redissect = cf->redissection_queued == RESCAN_REDISSECT;
+ rescan_packets(cf, NULL, NULL, redissect);
+ }
+
+ if (cf->stop_flag) {
+ simple_message_box(ESD_TYPE_WARN, NULL,
+ "The remaining packets in the file were discarded.\n"
+ "\n"
+ "As a lot of packets from the original file will be missing,\n"
+ "remember to be careful when saving the current content to a file.\n",
+ "File loading was cancelled.");
+ return CF_READ_ERROR;
+ }
+
+ if (err != 0) {
+ /* Put up a message box noting that the read failed somewhere along
+ the line. Don't throw out the stuff we managed to read, though,
+ if any. */
+ cfile_read_failure_alert_box(NULL, err, err_info);
+ return CF_READ_ERROR;
+ } else if (too_many_records) {
+ simple_message_box(ESD_TYPE_WARN, NULL,
+ "The remaining packets in the file were discarded.\n"
+ "\n"
+ "As a lot of packets from the original file will be missing,\n"
+ "remember to be careful when saving the current content to a file.\n"
+ "\n"
+ "The command-line utility editcap can be used to split "
+ "the file into multiple smaller files",
+ "The file contains more records than the maximum "
+ "supported number of records, %u.", max_records);
+ return CF_READ_ERROR;
+ } else
+ return CF_READ_OK;
}
#ifdef HAVE_LIBPCAP
cf_read_status_t
cf_continue_tail(capture_file *cf, volatile int to_read, wtap_rec *rec,
- Buffer *buf, int *err)
+ Buffer *buf, int *err)
{
- gchar *err_info;
- volatile int newly_displayed_packets = 0;
- dfilter_t *dfcode;
- epan_dissect_t edt;
- gboolean create_proto_tree;
- guint tap_flags;
- gboolean compiled _U_;
-
- /* Compile the current display filter.
- * We assume this will not fail since cf->dfilter is only set in
- * cf_filter IFF the filter was valid.
- */
- compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
- ws_assert(!cf->dfilter || (compiled && dfcode));
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a display filter;
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * a postdissector wants field values or protocols on
- * the first pass.
- */
- create_proto_tree =
- (dfcode != NULL || have_filtering_tap_listeners() ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids());
-
- *err = 0;
-
- /* Don't freeze/thaw the list when doing live capture */
- /*packet_list_freeze();*/
-
- epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
-
- TRY {
- gint64 data_offset = 0;
- column_info *cinfo;
+ gchar *err_info;
+ volatile int newly_displayed_packets = 0;
+ dfilter_t *dfcode;
+ epan_dissect_t edt;
+ gboolean create_proto_tree;
+ guint tap_flags;
+ gboolean compiled _U_;
+
+ /* Compile the current display filter.
+ * We assume this will not fail since cf->dfilter is only set in
+ * cf_filter IFF the filter was valid.
+ */
+ compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
+ ws_assert(!cf->dfilter || (compiled && dfcode));
- /* If any tap listeners require the columns, construct them. */
- cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a display filter;
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * a postdissector wants field values or protocols on
+ * the first pass.
+ */
+ create_proto_tree =
+ (dfcode != NULL || have_filtering_tap_listeners() ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids());
+
+ *err = 0;
+
+ /* Don't freeze/thaw the list when doing live capture */
+ /*packet_list_freeze();*/
- while (to_read != 0) {
- wtap_cleareof(cf->provider.wth);
- if (!wtap_read(cf->provider.wth, rec, buf, err, &err_info,
- &data_offset)) {
- break;
- }
- if (cf->state == FILE_READ_ABORTED) {
- /* Well, the user decided to exit Wireshark. Break out of the
- loop, and let the code below (which is called even if there
- aren't any packets left to read) exit. */
- break;
- }
- if (read_record(cf, rec, buf, dfcode, &edt, cinfo, data_offset)) {
- newly_displayed_packets++;
- }
- to_read--;
- }
- wtap_rec_reset(rec);
- }
- CATCH(OutOfMemoryError) {
- simple_message_box(ESD_TYPE_ERROR, NULL,
- "More information and workarounds can be found at\n"
- WS_WIKI_URL("KnownBugs/OutOfMemory"),
- "Sorry, but Wireshark has run out of memory and has to terminate now.");
+ epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
+
+ TRY {
+ gint64 data_offset = 0;
+ column_info *cinfo;
+
+ /* If any tap listeners require the columns, construct them. */
+ cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+
+ while (to_read != 0) {
+ wtap_cleareof(cf->provider.wth);
+ if (!wtap_read(cf->provider.wth, rec, buf, err, &err_info,
+ &data_offset)) {
+ break;
+ }
+ if (cf->state == FILE_READ_ABORTED) {
+ /* Well, the user decided to exit Wireshark. Break out of the
+ loop, and let the code below (which is called even if there
+ aren't any packets left to read) exit. */
+ break;
+ }
+ if (read_record(cf, rec, buf, dfcode, &edt, cinfo, data_offset)) {
+ newly_displayed_packets++;
+ }
+ to_read--;
+ }
+ wtap_rec_reset(rec);
+ }
+ CATCH(OutOfMemoryError) {
+ simple_message_box(ESD_TYPE_ERROR, NULL,
+ "More information and workarounds can be found at\n"
+ WS_WIKI_URL("KnownBugs/OutOfMemory"),
+ "Sorry, but Wireshark has run out of memory and has to terminate now.");
#if 0
- /* Could we close the current capture and free up memory from that? */
- return CF_READ_ABORTED;
+ /* Could we close the current capture and free up memory from that? */
+ return CF_READ_ABORTED;
#else
- /* we have to terminate, as we cannot recover from the memory error */
- exit(1);
+ /* we have to terminate, as we cannot recover from the memory error */
+ exit(1);
#endif
- }
- ENDTRY;
-
- /* Update the file encapsulation; it might have changed based on the
- packets we've read. */
- cf->lnk_t = wtap_file_encap(cf->provider.wth);
-
- /* Cleanup and release all dfilter resources */
- dfilter_free(dfcode);
-
- epan_dissect_cleanup(&edt);
-
- /* Don't freeze/thaw the list when doing live capture */
- /*packet_list_thaw();*/
- /* With the new packet list the first packet
- * isn't automatically selected.
- */
- if (!cf->current_frame && !packet_list_multi_select_active())
- packet_list_select_first_row();
-
- /* moving to the end of the packet list - if the user requested so and
- we have some new packets. */
- if (newly_displayed_packets && cf->count != 0)
- packet_list_moveto_end();
-
- if (cf->state == FILE_READ_ABORTED) {
- /* Well, the user decided to exit Wireshark. Return CF_READ_ABORTED
- so that our caller can kill off the capture child process;
- this will cause an EOF on the pipe from the child, so
- "cf_finish_tail()" will be called, and it will clean up
- and exit. */
- return CF_READ_ABORTED;
- } else if (*err != 0) {
- /* We got an error reading the capture file.
- XXX - pop up a dialog box instead? */
- if (err_info != NULL) {
- ws_warning("Error \"%s\" while reading \"%s\" (\"%s\")",
- wtap_strerror(*err), cf->filename, err_info);
- g_free(err_info);
- } else {
- ws_warning("Error \"%s\" while reading \"%s\"",
- wtap_strerror(*err), cf->filename);
}
- return CF_READ_ERROR;
- } else
- return CF_READ_OK;
+ ENDTRY;
+
+ /* Update the file encapsulation; it might have changed based on the
+ packets we've read. */
+ cf->lnk_t = wtap_file_encap(cf->provider.wth);
+
+ /* Cleanup and release all dfilter resources */
+ dfilter_free(dfcode);
+
+ epan_dissect_cleanup(&edt);
+
+ /* Don't freeze/thaw the list when doing live capture */
+ /*packet_list_thaw();*/
+ /* With the new packet list the first packet
+ * isn't automatically selected.
+ */
+ if (!cf->current_frame && !packet_list_multi_select_active())
+ packet_list_select_first_row();
+
+ /* moving to the end of the packet list - if the user requested so and
+ we have some new packets. */
+ if (newly_displayed_packets && cf->count != 0)
+ packet_list_moveto_end();
+
+ if (cf->state == FILE_READ_ABORTED) {
+ /* Well, the user decided to exit Wireshark. Return CF_READ_ABORTED
+ so that our caller can kill off the capture child process;
+ this will cause an EOF on the pipe from the child, so
+ "cf_finish_tail()" will be called, and it will clean up
+ and exit. */
+ return CF_READ_ABORTED;
+ } else if (*err != 0) {
+ /* We got an error reading the capture file.
+ XXX - pop up a dialog box instead? */
+ if (err_info != NULL) {
+ ws_warning("Error \"%s\" while reading \"%s\" (\"%s\")",
+ wtap_strerror(*err), cf->filename, err_info);
+ g_free(err_info);
+ } else {
+ ws_warning("Error \"%s\" while reading \"%s\"",
+ wtap_strerror(*err), cf->filename);
+ }
+ return CF_READ_ERROR;
+ } else
+ return CF_READ_OK;
}
void
-cf_fake_continue_tail(capture_file *cf) {
- cf->state = FILE_READ_DONE;
+cf_fake_continue_tail(capture_file *cf)
+{
+ cf->state = FILE_READ_DONE;
}
cf_read_status_t
cf_finish_tail(capture_file *cf, wtap_rec *rec, Buffer *buf, int *err)
{
- gchar *err_info;
- gint64 data_offset;
- dfilter_t *dfcode;
- column_info *cinfo;
- epan_dissect_t edt;
- gboolean create_proto_tree;
- guint tap_flags;
- gboolean compiled _U_;
-
- /* Compile the current display filter.
- * We assume this will not fail since cf->dfilter is only set in
- * cf_filter IFF the filter was valid.
- */
- compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
- ws_assert(!cf->dfilter || (compiled && dfcode));
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- /* If any tap listeners require the columns, construct them. */
- cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a display filter;
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * a postdissector wants field values or protocols on
- * the first pass.
- */
- create_proto_tree =
- (dfcode != NULL || have_filtering_tap_listeners() ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids());
-
- if (cf->provider.wth == NULL) {
- cf_close(cf);
- return CF_READ_ERROR;
- }
+ gchar *err_info;
+ gint64 data_offset;
+ dfilter_t *dfcode;
+ column_info *cinfo;
+ epan_dissect_t edt;
+ gboolean create_proto_tree;
+ guint tap_flags;
+ gboolean compiled _U_;
+
+ /* Compile the current display filter.
+ * We assume this will not fail since cf->dfilter is only set in
+ * cf_filter IFF the filter was valid.
+ */
+ compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
+ ws_assert(!cf->dfilter || (compiled && dfcode));
+
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
+
+ /* If any tap listeners require the columns, construct them. */
+ cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a display filter;
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * a postdissector wants field values or protocols on
+ * the first pass.
+ */
+ create_proto_tree =
+ (dfcode != NULL || have_filtering_tap_listeners() ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids());
+
+ if (cf->provider.wth == NULL) {
+ cf_close(cf);
+ return CF_READ_ERROR;
+ }
+
+ /* Don't freeze/thaw the list when doing live capture */
+ /*packet_list_freeze();*/
+
+ epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
+
+ while ((wtap_read(cf->provider.wth, rec, buf, err, &err_info, &data_offset))) {
+ if (cf->state == FILE_READ_ABORTED) {
+ /* Well, the user decided to abort the read. Break out of the
+ loop, and let the code below (which is called even if there
+ aren't any packets left to read) exit. */
+ break;
+ }
+ read_record(cf, rec, buf, dfcode, &edt, cinfo, data_offset);
+ wtap_rec_reset(rec);
+ }
- /* Don't freeze/thaw the list when doing live capture */
- /*packet_list_freeze();*/
+ /* Cleanup and release all dfilter resources */
+ dfilter_free(dfcode);
- epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
+ epan_dissect_cleanup(&edt);
+
+ /* Don't freeze/thaw the list when doing live capture */
+ /*packet_list_thaw();*/
- while ((wtap_read(cf->provider.wth, rec, buf, err, &err_info, &data_offset))) {
if (cf->state == FILE_READ_ABORTED) {
- /* Well, the user decided to abort the read. Break out of the
- loop, and let the code below (which is called even if there
- aren't any packets left to read) exit. */
- break;
+ /* Well, the user decided to abort the read. We're only called
+ when the child capture process closes the pipe to us (meaning
+ it's probably exited), so we can just close the capture
+ file; we return CF_READ_ABORTED so our caller can do whatever
+ is appropriate when that happens. */
+ cf_close(cf);
+ return CF_READ_ABORTED;
}
- read_record(cf, rec, buf, dfcode, &edt, cinfo, data_offset);
- wtap_rec_reset(rec);
- }
- /* Cleanup and release all dfilter resources */
- dfilter_free(dfcode);
+ /* We're done reading sequentially through the file. */
+ cf->state = FILE_READ_DONE;
- epan_dissect_cleanup(&edt);
+ /* We're done reading sequentially through the file; close the
+ sequential I/O side, to free up memory it requires. */
+ wtap_sequential_close(cf->provider.wth);
- /* Don't freeze/thaw the list when doing live capture */
- /*packet_list_thaw();*/
+ /* Allow the protocol dissectors to free up memory that they
+ * don't need after the sequential run-through of the packets. */
+ postseq_cleanup_all_protocols();
- if (cf->state == FILE_READ_ABORTED) {
- /* Well, the user decided to abort the read. We're only called
- when the child capture process closes the pipe to us (meaning
- it's probably exited), so we can just close the capture
- file; we return CF_READ_ABORTED so our caller can do whatever
- is appropriate when that happens. */
- cf_close(cf);
- return CF_READ_ABORTED;
- }
-
- /* We're done reading sequentially through the file. */
- cf->state = FILE_READ_DONE;
-
- /* We're done reading sequentially through the file; close the
- sequential I/O side, to free up memory it requires. */
- wtap_sequential_close(cf->provider.wth);
-
- /* Allow the protocol dissectors to free up memory that they
- * don't need after the sequential run-through of the packets. */
- postseq_cleanup_all_protocols();
-
- /* Update the file encapsulation; it might have changed based on the
- packets we've read. */
- cf->lnk_t = wtap_file_encap(cf->provider.wth);
-
- /* Update the details in the file-set dialog, as the capture file
- * has likely grown since we first stat-ed it */
- fileset_update_file(cf->filename);
-
- if (*err != 0) {
- /* We got an error reading the capture file.
- XXX - pop up a dialog box? */
- if (err_info != NULL) {
- ws_warning("Error \"%s\" while reading \"%s\" (\"%s\")",
- wtap_strerror(*err), cf->filename, err_info);
- g_free(err_info);
+ /* Update the file encapsulation; it might have changed based on the
+ packets we've read. */
+ cf->lnk_t = wtap_file_encap(cf->provider.wth);
+
+ /* Update the details in the file-set dialog, as the capture file
+ * has likely grown since we first stat-ed it */
+ fileset_update_file(cf->filename);
+
+ if (*err != 0) {
+ /* We got an error reading the capture file.
+ XXX - pop up a dialog box? */
+ if (err_info != NULL) {
+ ws_warning("Error \"%s\" while reading \"%s\" (\"%s\")",
+ wtap_strerror(*err), cf->filename, err_info);
+ g_free(err_info);
+ } else {
+ ws_warning("Error \"%s\" while reading \"%s\"",
+ wtap_strerror(*err), cf->filename);
+ }
+ return CF_READ_ERROR;
} else {
- ws_warning("Error \"%s\" while reading \"%s\"",
- wtap_strerror(*err), cf->filename);
+ return CF_READ_OK;
}
- return CF_READ_ERROR;
- } else {
- return CF_READ_OK;
- }
}
#endif /* HAVE_LIBPCAP */
gchar *
cf_get_display_name(capture_file *cf)
{
- gchar *displayname;
+ gchar *displayname;
- /* Return a name to use in displays */
- if (!cf->is_tempfile) {
- /* Get the last component of the file name, and use that. */
- if (cf->filename) {
- displayname = g_filename_display_basename(cf->filename);
- } else {
- displayname=g_strdup("(No file)");
- }
- } else {
- /* The file we read is a temporary file from a live capture or
- a merge operation; we don't mention its name, but, if it's
- from a capture, give the source of the capture. */
- if (cf->source) {
- displayname = g_strdup(cf->source);
+ /* Return a name to use in displays */
+ if (!cf->is_tempfile) {
+ /* Get the last component of the file name, and use that. */
+ if (cf->filename) {
+ displayname = g_filename_display_basename(cf->filename);
+ } else {
+ displayname=g_strdup("(No file)");
+ }
} else {
- displayname = g_strdup("(Untitled)");
+ /* The file we read is a temporary file from a live capture or
+ a merge operation; we don't mention its name, but, if it's
+ from a capture, give the source of the capture. */
+ if (cf->source) {
+ displayname = g_strdup(cf->source);
+ } else {
+ displayname = g_strdup("(Untitled)");
+ }
}
- }
- return displayname;
+ return displayname;
}
gchar *
cf_get_basename(capture_file *cf)
{
- gchar *displayname;
-
- /* Return a name to use in the GUI for the basename for files to
- which we save statistics */
- if (!cf->is_tempfile) {
- /* Get the last component of the file name, and use that. */
- if (cf->filename) {
- displayname = g_filename_display_basename(cf->filename);
-
- /* If the file name ends with any extension that corresponds
- to a file type we support - including compressed versions
- of those files - strip it off. */
- size_t displayname_len = strlen(displayname);
- GSList *extensions = wtap_get_all_file_extensions_list();
- GSList *suffix;
- for (suffix = extensions; suffix != NULL; suffix = g_slist_next(suffix)) {
- /* Does the file name end with that extension? */
- const char *extension = (char *)suffix->data;
- size_t extension_len = strlen(extension);
- if (displayname_len > extension_len &&
- displayname[displayname_len - extension_len - 1] == '.' &&
- strcmp(&displayname[displayname_len - extension_len], extension) == 0) {
- /* Yes. Strip the extension off, and return the result. */
- displayname[displayname_len - extension_len - 1] = '\0';
- break;
+ gchar *displayname;
+
+ /* Return a name to use in the GUI for the basename for files to
+ which we save statistics */
+ if (!cf->is_tempfile) {
+ /* Get the last component of the file name, and use that. */
+ if (cf->filename) {
+ displayname = g_filename_display_basename(cf->filename);
+
+ /* If the file name ends with any extension that corresponds
+ to a file type we support - including compressed versions
+ of those files - strip it off. */
+ size_t displayname_len = strlen(displayname);
+ GSList *extensions = wtap_get_all_file_extensions_list();
+ GSList *suffix;
+ for (suffix = extensions; suffix != NULL; suffix = g_slist_next(suffix)) {
+ /* Does the file name end with that extension? */
+ const char *extension = (char *)suffix->data;
+ size_t extension_len = strlen(extension);
+ if (displayname_len > extension_len &&
+ displayname[displayname_len - extension_len - 1] == '.' &&
+ strcmp(&displayname[displayname_len - extension_len], extension) == 0) {
+ /* Yes. Strip the extension off, and return the result. */
+ displayname[displayname_len - extension_len - 1] = '\0';
+ break;
+ }
+ }
+ wtap_free_extensions_list(extensions);
+ } else {
+ displayname=g_strdup("");
}
- }
- wtap_free_extensions_list(extensions);
- } else {
- displayname=g_strdup("");
- }
- } else {
- /* The file we read is a temporary file from a live capture or
- a merge operation; we don't mention its name, but, if it's
- from a capture, give the source of the capture. */
- if (cf->source) {
- displayname = g_strdup(cf->source);
} else {
- displayname = g_strdup("");
+ /* The file we read is a temporary file from a live capture or
+ a merge operation; we don't mention its name, but, if it's
+ from a capture, give the source of the capture. */
+ if (cf->source) {
+ displayname = g_strdup(cf->source);
+ } else {
+ displayname = g_strdup("");
+ }
}
- }
- return displayname;
+ return displayname;
}
-void cf_set_tempfile_source(capture_file *cf, gchar *source) {
- if (cf->source) {
- g_free(cf->source);
- }
+void
+cf_set_tempfile_source(capture_file *cf, gchar *source)
+{
+ if (cf->source) {
+ g_free(cf->source);
+ }
- if (source) {
- cf->source = g_strdup(source);
- } else {
- cf->source = g_strdup("");
- }
+ if (source) {
+ cf->source = g_strdup(source);
+ } else {
+ cf->source = g_strdup("");
+ }
}
-const gchar *cf_get_tempfile_source(capture_file *cf) {
- if (!cf->source) {
- return "";
- }
+const gchar *
+cf_get_tempfile_source(capture_file *cf)
+{
+ if (!cf->source) {
+ return "";
+ }
- return cf->source;
+ return cf->source;
}
/* XXX - use a macro instead? */
int
cf_get_packet_count(capture_file *cf)
{
- return cf->count;
+ return cf->count;
}
/* XXX - use a macro instead? */
gboolean
cf_is_tempfile(capture_file *cf)
{
- return cf->is_tempfile;
+ return cf->is_tempfile;
}
-void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
+void
+cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
{
- cf->is_tempfile = is_tempfile;
+ cf->is_tempfile = is_tempfile;
}
/* XXX - use a macro instead? */
-void cf_set_drops_known(capture_file *cf, gboolean drops_known)
+void
+cf_set_drops_known(capture_file *cf, gboolean drops_known)
{
- cf->drops_known = drops_known;
+ cf->drops_known = drops_known;
}
/* XXX - use a macro instead? */
-void cf_set_drops(capture_file *cf, guint32 drops)
+void
+cf_set_drops(capture_file *cf, guint32 drops)
{
- cf->drops = drops;
+ cf->drops = drops;
}
/* XXX - use a macro instead? */
-gboolean cf_get_drops_known(capture_file *cf)
+gboolean
+cf_get_drops_known(capture_file *cf)
{
- return cf->drops_known;
+ return cf->drops_known;
}
/* XXX - use a macro instead? */
-guint32 cf_get_drops(capture_file *cf)
+guint32
+cf_get_drops(capture_file *cf)
{
- return cf->drops;
+ return cf->drops;
}
-void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
+void
+cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
{
- cf->rfcode = rfcode;
+ cf->rfcode = rfcode;
}
static void
add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
- epan_dissect_t *edt, dfilter_t *dfcode, column_info *cinfo,
- wtap_rec *rec, Buffer *buf, gboolean add_to_packet_list)
+ epan_dissect_t *edt, dfilter_t *dfcode, column_info *cinfo,
+ wtap_rec *rec, Buffer *buf, gboolean add_to_packet_list)
{
- frame_data_set_before_dissect(fdata, &cf->elapsed_time,
- &cf->provider.ref, cf->provider.prev_dis);
- cf->provider.prev_cap = fdata;
+ frame_data_set_before_dissect(fdata, &cf->elapsed_time,
+ &cf->provider.ref, cf->provider.prev_dis);
+ cf->provider.prev_cap = fdata;
- if (dfcode != NULL) {
- epan_dissect_prime_with_dfilter(edt, dfcode);
- }
+ if (dfcode != NULL) {
+ epan_dissect_prime_with_dfilter(edt, dfcode);
+ }
#if 0
- /* Prepare coloring rules, this ensures that display filter rules containing
- * frame.color_rule references are still processed.
- * TODO: actually detect that situation or maybe apply other optimizations? */
- if (edt->tree && color_filters_used()) {
- color_filters_prime_edt(edt);
- fdata->need_colorize = 1;
- }
+ /* Prepare coloring rules, this ensures that display filter rules containing
+ * frame.color_rule references are still processed.
+ * TODO: actually detect that situation or maybe apply other optimizations? */
+ if (edt->tree && color_filters_used()) {
+ color_filters_prime_edt(edt);
+ fdata->need_colorize = 1;
+ }
#endif
- if (!fdata->visited) {
- /* This is the first pass, so prime the epan_dissect_t with the
- hfids postdissectors want on the first pass. */
- prime_epan_dissect_with_postdissector_wanted_hfids(edt);
- }
-
- /* Dissect the frame. */
- epan_dissect_run_with_taps(edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, cinfo);
-
- /* If we don't have a display filter, set "passed_dfilter" to 1. */
- if (dfcode != NULL) {
- fdata->passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
-
- if (fdata->passed_dfilter) {
- /* This frame passed the display filter but it may depend on other
- * (potentially not displayed) frames. Find those frames and mark them
- * as depended upon.
- */
- g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
- }
- } else
- fdata->passed_dfilter = 1;
-
- if (fdata->passed_dfilter || fdata->ref_time)
- cf->displayed_count++;
-
- if (add_to_packet_list) {
- /* We fill the needed columns from new_packet_list */
- packet_list_append(cinfo, fdata);
- }
-
- if (fdata->passed_dfilter || fdata->ref_time)
- {
- frame_data_set_after_dissect(fdata, &cf->cum_bytes);
- cf->provider.prev_dis = fdata;
-
- /* If we haven't yet seen the first frame, this is it. */
- if (cf->first_displayed == 0)
- cf->first_displayed = fdata->num;
-
- /* This is the last frame we've seen so far. */
- cf->last_displayed = fdata->num;
- }
-
- epan_dissect_reset(edt);
+ if (!fdata->visited) {
+ /* This is the first pass, so prime the epan_dissect_t with the
+ hfids postdissectors want on the first pass. */
+ prime_epan_dissect_with_postdissector_wanted_hfids(edt);
+ }
+
+ /* Dissect the frame. */
+ epan_dissect_run_with_taps(edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, cinfo);
+
+ /* If we don't have a display filter, set "passed_dfilter" to 1. */
+ if (dfcode != NULL) {
+ fdata->passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
+
+ if (fdata->passed_dfilter) {
+ /* This frame passed the display filter but it may depend on other
+ * (potentially not displayed) frames. Find those frames and mark them
+ * as depended upon.
+ */
+ g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
+ }
+ } else
+ fdata->passed_dfilter = 1;
+
+ if (fdata->passed_dfilter || fdata->ref_time)
+ cf->displayed_count++;
+
+ if (add_to_packet_list) {
+ /* We fill the needed columns from new_packet_list */
+ packet_list_append(cinfo, fdata);
+ }
+
+ if (fdata->passed_dfilter || fdata->ref_time)
+ {
+ frame_data_set_after_dissect(fdata, &cf->cum_bytes);
+ cf->provider.prev_dis = fdata;
+
+ /* If we haven't yet seen the first frame, this is it. */
+ if (cf->first_displayed == 0)
+ cf->first_displayed = fdata->num;
+
+ /* This is the last frame we've seen so far. */
+ cf->last_displayed = fdata->num;
+ }
+
+ epan_dissect_reset(edt);
}
/*
@@ -1253,365 +1264,365 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
*/
static gboolean
read_record(capture_file *cf, wtap_rec *rec, Buffer *buf, dfilter_t *dfcode,
- epan_dissect_t *edt, column_info *cinfo, gint64 offset)
+ epan_dissect_t *edt, column_info *cinfo, gint64 offset)
{
- frame_data fdlocal;
- frame_data *fdata;
- gboolean passed = TRUE;
- gboolean added = FALSE;
-
- /* Add this packet's link-layer encapsulation type to cf->linktypes, if
- it's not already there.
- XXX - yes, this is O(N), so if every packet had a different
- link-layer encapsulation type, it'd be O(N^2) to read the file, but
- there are probably going to be a small number of encapsulation types
- in a file. */
- if (rec->rec_type == REC_TYPE_PACKET) {
- cf_add_encapsulation_type(cf, rec->rec_header.packet_header.pkt_encap);
- }
-
- /* The frame number of this packet, if we add it to the set of frames,
- would be one more than the count of frames in the file so far. */
- frame_data_init(&fdlocal, cf->count + 1, rec, offset, cf->cum_bytes);
-
- if (cf->rfcode) {
- epan_dissect_t rf_edt;
-
- epan_dissect_init(&rf_edt, cf->epan, TRUE, FALSE);
- epan_dissect_prime_with_dfilter(&rf_edt, cf->rfcode);
- epan_dissect_run(&rf_edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, &fdlocal, buf),
- &fdlocal, NULL);
- passed = dfilter_apply_edt(cf->rfcode, &rf_edt);
- epan_dissect_cleanup(&rf_edt);
- }
-
- if (passed) {
- added = TRUE;
-
- /* This does a shallow copy of fdlocal, which is good enough. */
- fdata = frame_data_sequence_add(cf->provider.frames, &fdlocal);
-
- cf->count++;
- if (rec->block != NULL)
- cf->packet_comment_count += wtap_block_count_option(rec->block, OPT_COMMENT);
- cf->f_datalen = offset + fdlocal.cap_len;
-
- /* When a redissection is in progress (or queued), do not process packets.
- * This will be done once all (new) packets have been scanned. */
- if (!cf->redissecting && cf->redissection_queued == RESCAN_NONE) {
- add_packet_to_packet_list(fdata, cf, edt, dfcode, cinfo, rec, buf, TRUE);
- }
- }
-
- return added;
+ frame_data fdlocal;
+ frame_data *fdata;
+ gboolean passed = TRUE;
+ gboolean added = FALSE;
+
+ /* Add this packet's link-layer encapsulation type to cf->linktypes, if
+ it's not already there.
+ XXX - yes, this is O(N), so if every packet had a different
+ link-layer encapsulation type, it'd be O(N^2) to read the file, but
+ there are probably going to be a small number of encapsulation types
+ in a file. */
+ if (rec->rec_type == REC_TYPE_PACKET) {
+ cf_add_encapsulation_type(cf, rec->rec_header.packet_header.pkt_encap);
+ }
+
+ /* The frame number of this packet, if we add it to the set of frames,
+ would be one more than the count of frames in the file so far. */
+ frame_data_init(&fdlocal, cf->count + 1, rec, offset, cf->cum_bytes);
+
+ if (cf->rfcode) {
+ epan_dissect_t rf_edt;
+
+ epan_dissect_init(&rf_edt, cf->epan, TRUE, FALSE);
+ epan_dissect_prime_with_dfilter(&rf_edt, cf->rfcode);
+ epan_dissect_run(&rf_edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, &fdlocal, buf),
+ &fdlocal, NULL);
+ passed = dfilter_apply_edt(cf->rfcode, &rf_edt);
+ epan_dissect_cleanup(&rf_edt);
+ }
+
+ if (passed) {
+ added = TRUE;
+
+ /* This does a shallow copy of fdlocal, which is good enough. */
+ fdata = frame_data_sequence_add(cf->provider.frames, &fdlocal);
+
+ cf->count++;
+ if (rec->block != NULL)
+ cf->packet_comment_count += wtap_block_count_option(rec->block, OPT_COMMENT);
+ cf->f_datalen = offset + fdlocal.cap_len;
+
+ /* When a redissection is in progress (or queued), do not process packets.
+ * This will be done once all (new) packets have been scanned. */
+ if (!cf->redissecting && cf->redissection_queued == RESCAN_NONE) {
+ add_packet_to_packet_list(fdata, cf, edt, dfcode, cinfo, rec, buf, TRUE);
+ }
+ }
+
+ return added;
}
typedef struct _callback_data_t {
- gpointer pd_window;
- gint64 f_len;
- progdlg_t *progbar;
- GTimer *prog_timer;
- gboolean stop_flag;
+ gpointer pd_window;
+ gint64 f_len;
+ progdlg_t *progbar;
+ GTimer *prog_timer;
+ gboolean stop_flag;
} callback_data_t;
static gboolean
merge_callback(merge_event event, int num _U_,
- const merge_in_file_t in_files[], const guint in_file_count,
- void *data)
+ const merge_in_file_t in_files[], const guint in_file_count,
+ void *data)
{
- guint i;
- callback_data_t *cb_data = (callback_data_t*) data;
-
- ws_assert(cb_data != NULL);
+ guint i;
+ callback_data_t *cb_data = (callback_data_t*) data;
- switch (event) {
+ ws_assert(cb_data != NULL);
- case MERGE_EVENT_INPUT_FILES_OPENED:
- /* do nothing */
- break;
+ switch (event) {
- case MERGE_EVENT_FRAME_TYPE_SELECTED:
- /* do nothing */
- break;
+ case MERGE_EVENT_INPUT_FILES_OPENED:
+ /* do nothing */
+ break;
- case MERGE_EVENT_READY_TO_MERGE:
- /* Get the sum of the sizes of all the files. */
- for (i = 0; i < in_file_count; i++)
- cb_data->f_len += in_files[i].size;
+ case MERGE_EVENT_FRAME_TYPE_SELECTED:
+ /* do nothing */
+ break;
- cb_data->prog_timer = g_timer_new();
- g_timer_start(cb_data->prog_timer);
- break;
+ case MERGE_EVENT_READY_TO_MERGE:
+ /* Get the sum of the sizes of all the files. */
+ for (i = 0; i < in_file_count; i++)
+ cb_data->f_len += in_files[i].size;
- case MERGE_EVENT_RECORD_WAS_READ:
- {
- /* Create the progress bar if necessary.
- We check on every iteration of the loop, so that it takes no
- longer than the standard time to create it (otherwise, for a
- large file, we might take considerably longer than that standard
- time in order to get to the next progress bar step). */
- if (cb_data->progbar == NULL) {
- cb_data->progbar = delayed_create_progress_dlg(cb_data->pd_window, NULL, NULL,
- FALSE, &cb_data->stop_flag, 0.0f);
- }
+ cb_data->prog_timer = g_timer_new();
+ g_timer_start(cb_data->prog_timer);
+ break;
- /*
- * Update the progress bar, but do it only after
- * PROGBAR_UPDATE_INTERVAL has elapsed. Calling update_progress_dlg
- * and packets_bar_update will likely trigger UI paint events, which
- * might take a while depending on the platform and display. Reset
- * our timer *after* painting.
- */
- if (g_timer_elapsed(cb_data->prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
- float progbar_val;
- gint64 file_pos = 0;
- /* Get the sum of the seek positions in all of the files. */
- for (i = 0; i < in_file_count; i++)
- file_pos += wtap_read_so_far(in_files[i].wth);
-
- progbar_val = (gfloat) file_pos / (gfloat) cb_data->f_len;
- if (progbar_val > 1.0f) {
- /* Some file probably grew while we were reading it.
- That "shouldn't happen", so we'll just clip the progress
- value at 1.0. */
- progbar_val = 1.0f;
+ case MERGE_EVENT_RECORD_WAS_READ:
+ {
+ /* Create the progress bar if necessary.
+ We check on every iteration of the loop, so that it takes no
+ longer than the standard time to create it (otherwise, for a
+ large file, we might take considerably longer than that standard
+ time in order to get to the next progress bar step). */
+ if (cb_data->progbar == NULL) {
+ cb_data->progbar = delayed_create_progress_dlg(cb_data->pd_window, NULL, NULL,
+ FALSE, &cb_data->stop_flag, 0.0f);
+ }
+
+ /*
+ * Update the progress bar, but do it only after
+ * PROGBAR_UPDATE_INTERVAL has elapsed. Calling update_progress_dlg
+ * and packets_bar_update will likely trigger UI paint events, which
+ * might take a while depending on the platform and display. Reset
+ * our timer *after* painting.
+ */
+ if (g_timer_elapsed(cb_data->prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
+ float progbar_val;
+ gint64 file_pos = 0;
+ /* Get the sum of the seek positions in all of the files. */
+ for (i = 0; i < in_file_count; i++)
+ file_pos += wtap_read_so_far(in_files[i].wth);
+
+ progbar_val = (gfloat) file_pos / (gfloat) cb_data->f_len;
+ if (progbar_val > 1.0f) {
+ /* Some file probably grew while we were reading it.
+ That "shouldn't happen", so we'll just clip the progress
+ value at 1.0. */
+ progbar_val = 1.0f;
+ }
+
+ if (cb_data->progbar != NULL) {
+ gchar status_str[100];
+ snprintf(status_str, sizeof(status_str),
+ "%" PRId64 "KB of %" PRId64 "KB",
+ file_pos / 1024, cb_data->f_len / 1024);
+ update_progress_dlg(cb_data->progbar, progbar_val, status_str);
+ }
+ g_timer_start(cb_data->prog_timer);
+ }
}
+ break;
- if (cb_data->progbar != NULL) {
- gchar status_str[100];
- snprintf(status_str, sizeof(status_str),
- "%" PRId64 "KB of %" PRId64 "KB",
- file_pos / 1024, cb_data->f_len / 1024);
- update_progress_dlg(cb_data->progbar, progbar_val, status_str);
- }
- g_timer_start(cb_data->prog_timer);
- }
- }
- break;
-
- case MERGE_EVENT_DONE:
- /* We're done merging the files; destroy the progress bar if it was created. */
- if (cb_data->progbar != NULL)
- destroy_progress_dlg(cb_data->progbar);
- g_timer_destroy(cb_data->prog_timer);
- break;
- }
-
- return cb_data->stop_flag;
+ case MERGE_EVENT_DONE:
+ /* We're done merging the files; destroy the progress bar if it was created. */
+ if (cb_data->progbar != NULL)
+ destroy_progress_dlg(cb_data->progbar);
+ g_timer_destroy(cb_data->prog_timer);
+ break;
+ }
+
+ return cb_data->stop_flag;
}
cf_status_t
cf_merge_files_to_tempfile(gpointer pd_window, const char *temp_dir, char **out_filenamep,
- int in_file_count, const char *const *in_filenames,
- int file_type, gboolean do_append)
+ int in_file_count, const char *const *in_filenames,
+ int file_type, gboolean do_append)
{
- int err = 0;
- gchar *err_info = NULL;
- guint err_fileno;
- guint32 err_framenum;
- merge_result status;
- merge_progress_callback_t cb;
- callback_data_t *cb_data = g_new0(callback_data_t, 1);
-
- /* prepare our callback routine */
- cb_data->pd_window = pd_window;
- cb.callback_func = merge_callback;
- cb.data = cb_data;
-
- cf_callback_invoke(cf_cb_file_merge_started, NULL);
-
- /* merge the files */
- status = merge_files_to_tempfile(temp_dir, out_filenamep, "wireshark", file_type,
- in_filenames,
- in_file_count, do_append,
- IDB_MERGE_MODE_ALL_SAME, 0 /* snaplen */,
- "Wireshark", &cb, &err, &err_info,
- &err_fileno, &err_framenum);
-
- g_free(cb.data);
-
- switch (status) {
- case MERGE_OK:
- break;
-
- case MERGE_USER_ABORTED:
- /* this isn't really an error, though we will return CF_ERROR later */
- break;
-
- case MERGE_ERR_CANT_OPEN_INFILE:
- cfile_open_failure_alert_box(in_filenames[err_fileno], err, err_info);
- break;
-
- case MERGE_ERR_CANT_OPEN_OUTFILE:
- cfile_dump_open_failure_alert_box(*out_filenamep, err, err_info,
- file_type);
- break;
-
- case MERGE_ERR_CANT_READ_INFILE:
- cfile_read_failure_alert_box(in_filenames[err_fileno], err, err_info);
- break;
-
- case MERGE_ERR_BAD_PHDR_INTERFACE_ID:
- simple_error_message_box("Record %u of \"%s\" has an interface ID that does not match any IDB in its file.",
- err_framenum, in_filenames[err_fileno]);
- break;
-
- case MERGE_ERR_CANT_WRITE_OUTFILE:
- cfile_write_failure_alert_box(in_filenames[err_fileno],
- *out_filenamep, err, err_info,
- err_framenum, file_type);
- break;
-
- case MERGE_ERR_CANT_CLOSE_OUTFILE:
- cfile_close_failure_alert_box(*out_filenamep, err, err_info);
- break;
-
- default:
- simple_error_message_box("Unknown merge_files error %d", status);
- break;
- }
-
- cf_callback_invoke(cf_cb_file_merge_finished, NULL);
-
- if (status != MERGE_OK) {
- /* Callers aren't expected to treat an error or an explicit abort
- differently - we put up error dialogs ourselves, so they don't
- have to. */
- return CF_ERROR;
- } else
- return CF_OK;
+ int err = 0;
+ gchar *err_info = NULL;
+ guint err_fileno;
+ guint32 err_framenum;
+ merge_result status;
+ merge_progress_callback_t cb;
+ callback_data_t *cb_data = g_new0(callback_data_t, 1);
+
+ /* prepare our callback routine */
+ cb_data->pd_window = pd_window;
+ cb.callback_func = merge_callback;
+ cb.data = cb_data;
+
+ cf_callback_invoke(cf_cb_file_merge_started, NULL);
+
+ /* merge the files */
+ status = merge_files_to_tempfile(temp_dir, out_filenamep, "wireshark", file_type,
+ in_filenames,
+ in_file_count, do_append,
+ IDB_MERGE_MODE_ALL_SAME, 0 /* snaplen */,
+ "Wireshark", &cb, &err, &err_info,
+ &err_fileno, &err_framenum);
+
+ g_free(cb.data);
+
+ switch (status) {
+ case MERGE_OK:
+ break;
+
+ case MERGE_USER_ABORTED:
+ /* this isn't really an error, though we will return CF_ERROR later */
+ break;
+
+ case MERGE_ERR_CANT_OPEN_INFILE:
+ cfile_open_failure_alert_box(in_filenames[err_fileno], err, err_info);
+ break;
+
+ case MERGE_ERR_CANT_OPEN_OUTFILE:
+ cfile_dump_open_failure_alert_box(*out_filenamep, err, err_info,
+ file_type);
+ break;
+
+ case MERGE_ERR_CANT_READ_INFILE:
+ cfile_read_failure_alert_box(in_filenames[err_fileno], err, err_info);
+ break;
+
+ case MERGE_ERR_BAD_PHDR_INTERFACE_ID:
+ simple_error_message_box("Record %u of \"%s\" has an interface ID that does not match any IDB in its file.",
+ err_framenum, in_filenames[err_fileno]);
+ break;
+
+ case MERGE_ERR_CANT_WRITE_OUTFILE:
+ cfile_write_failure_alert_box(in_filenames[err_fileno],
+ *out_filenamep, err, err_info,
+ err_framenum, file_type);
+ break;
+
+ case MERGE_ERR_CANT_CLOSE_OUTFILE:
+ cfile_close_failure_alert_box(*out_filenamep, err, err_info);
+ break;
+
+ default:
+ simple_error_message_box("Unknown merge_files error %d", status);
+ break;
+ }
+
+ cf_callback_invoke(cf_cb_file_merge_finished, NULL);
+
+ if (status != MERGE_OK) {
+ /* Callers aren't expected to treat an error or an explicit abort
+ differently - we put up error dialogs ourselves, so they don't
+ have to. */
+ return CF_ERROR;
+ } else
+ return CF_OK;
}
cf_status_t
cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
{
- const char *filter_new = dftext ? dftext : "";
- const char *filter_old = cf->dfilter ? cf->dfilter : "";
- dfilter_t *dfcode;
- gchar *err_msg;
+ const char *filter_new = dftext ? dftext : "";
+ const char *filter_old = cf->dfilter ? cf->dfilter : "";
+ dfilter_t *dfcode;
+ gchar *err_msg;
+
+ /* if new filter equals old one, do nothing unless told to do so */
+ if (!force && strcmp(filter_new, filter_old) == 0) {
+ return CF_OK;
+ }
- /* if new filter equals old one, do nothing unless told to do so */
- if (!force && strcmp(filter_new, filter_old) == 0) {
- return CF_OK;
- }
+ dfcode=NULL;
- dfcode=NULL;
+ if (dftext == NULL) {
+ /* The new filter is an empty filter (i.e., display all packets).
+ * so leave dfcode==NULL
+ */
+ } else {
+ /*
+ * We have a filter; make a copy of it (as we'll be saving it),
+ * and try to compile it.
+ */
+ dftext = g_strdup(dftext);
+ if (!dfilter_compile(dftext, &dfcode, &err_msg)) {
+ /* The attempt failed; report an error. */
+ simple_message_box(ESD_TYPE_ERROR, NULL,
+ "See the help for a description of the display filter syntax.",
+ "\"%s\" isn't a valid display filter: %s",
+ dftext, err_msg);
+ g_free(err_msg);
+ g_free(dftext);
+ return CF_ERROR;
+ }
- if (dftext == NULL) {
- /* The new filter is an empty filter (i.e., display all packets).
- * so leave dfcode==NULL
- */
- } else {
- /*
- * We have a filter; make a copy of it (as we'll be saving it),
- * and try to compile it.
+ /* Was it empty? */
+ if (dfcode == NULL) {
+ /* Yes - free the filter text, and set it to null. */
+ g_free(dftext);
+ dftext = NULL;
+ }
+ }
+
+ /* We have a valid filter. Replace the current filter. */
+ g_free(cf->dfilter);
+ cf->dfilter = dftext;
+
+
+ /* Now rescan the packet list, applying the new filter, but not
+ * throwing away information constructed on a previous pass.
+ * If a dissection is already in progress, queue it.
*/
- dftext = g_strdup(dftext);
- if (!dfilter_compile(dftext, &dfcode, &err_msg)) {
- /* The attempt failed; report an error. */
- simple_message_box(ESD_TYPE_ERROR, NULL,
- "See the help for a description of the display filter syntax.",
- "\"%s\" isn't a valid display filter: %s",
- dftext, err_msg);
- g_free(err_msg);
- g_free(dftext);
- return CF_ERROR;
- }
-
- /* Was it empty? */
- if (dfcode == NULL) {
- /* Yes - free the filter text, and set it to null. */
- g_free(dftext);
- dftext = NULL;
- }
- }
-
- /* We have a valid filter. Replace the current filter. */
- g_free(cf->dfilter);
- cf->dfilter = dftext;
-
-
- /* Now rescan the packet list, applying the new filter, but not
- * throwing away information constructed on a previous pass.
- * If a dissection is already in progress, queue it.
- */
- if (cf->redissection_queued == RESCAN_NONE) {
- if (cf->read_lock) {
- cf->redissection_queued = RESCAN_SCAN;
- } else if (cf->state != FILE_CLOSED) {
- if (dftext == NULL) {
- rescan_packets(cf, "Resetting", "filter", FALSE);
- } else {
- rescan_packets(cf, "Filtering", dftext, FALSE);
- }
+ if (cf->redissection_queued == RESCAN_NONE) {
+ if (cf->read_lock) {
+ cf->redissection_queued = RESCAN_SCAN;
+ } else if (cf->state != FILE_CLOSED) {
+ if (dftext == NULL) {
+ rescan_packets(cf, "Resetting", "filter", FALSE);
+ } else {
+ rescan_packets(cf, "Filtering", dftext, FALSE);
+ }
+ }
}
- }
- /* Cleanup and release all dfilter resources */
- dfilter_free(dfcode);
+ /* Cleanup and release all dfilter resources */
+ dfilter_free(dfcode);
- return CF_OK;
+ return CF_OK;
}
void
cf_redissect_packets(capture_file *cf)
{
- if (cf->read_lock || cf->redissection_queued == RESCAN_SCAN) {
- /* Dissection in progress, signal redissection rather than rescanning. That
- * would destroy the current (in-progress) dissection in "cf_read" which
- * will cause issues when "cf_read" tries to add packets to the list.
- * If a previous rescan was requested, "upgrade" it to a full redissection.
- */
- cf->redissection_queued = RESCAN_REDISSECT;
- }
- if (cf->redissection_queued != RESCAN_NONE) {
- /* Redissection is (already) queued, wait for "cf_read" to finish. */
- return;
- }
-
- if (cf->state != FILE_CLOSED) {
- /* Restart dissection in case no cf_read is pending. */
- rescan_packets(cf, "Reprocessing", "all packets", TRUE);
- }
+ if (cf->read_lock || cf->redissection_queued == RESCAN_SCAN) {
+ /* Dissection in progress, signal redissection rather than rescanning. That
+ * would destroy the current (in-progress) dissection in "cf_read" which
+ * will cause issues when "cf_read" tries to add packets to the list.
+ * If a previous rescan was requested, "upgrade" it to a full redissection.
+ */
+ cf->redissection_queued = RESCAN_REDISSECT;
+ }
+ if (cf->redissection_queued != RESCAN_NONE) {
+ /* Redissection is (already) queued, wait for "cf_read" to finish. */
+ return;
+ }
+
+ if (cf->state != FILE_CLOSED) {
+ /* Restart dissection in case no cf_read is pending. */
+ rescan_packets(cf, "Reprocessing", "all packets", TRUE);
+ }
}
gboolean
cf_read_record(capture_file *cf, const frame_data *fdata,
- wtap_rec *rec, Buffer *buf)
+ wtap_rec *rec, Buffer *buf)
{
- int err;
- gchar *err_info;
+ int err;
+ gchar *err_info;
- if (!wtap_seek_read(cf->provider.wth, fdata->file_off, rec, buf, &err, &err_info)) {
- cfile_read_failure_alert_box(cf->filename, err, err_info);
- return FALSE;
- }
- return TRUE;
+ if (!wtap_seek_read(cf->provider.wth, fdata->file_off, rec, buf, &err, &err_info)) {
+ cfile_read_failure_alert_box(cf->filename, err, err_info);
+ return FALSE;
+ }
+ return TRUE;
}
gboolean
cf_read_record_no_alert(capture_file *cf, const frame_data *fdata,
- wtap_rec *rec, Buffer *buf)
+ wtap_rec *rec, Buffer *buf)
{
- int err;
- gchar *err_info;
+ int err;
+ gchar *err_info;
- if (!wtap_seek_read(cf->provider.wth, fdata->file_off, rec, buf, &err, &err_info)) {
- g_free(err_info);
- return FALSE;
- }
- return TRUE;
+ if (!wtap_seek_read(cf->provider.wth, fdata->file_off, rec, buf, &err, &err_info)) {
+ g_free(err_info);
+ return FALSE;
+ }
+ return TRUE;
}
gboolean
cf_read_current_record(capture_file *cf)
{
- return cf_read_record(cf, cf->current_frame, &cf->rec, &cf->buf);
+ return cf_read_record(cf, cf->current_frame, &cf->rec, &cf->buf);
}
/* Rescan the list of packets, reconstructing the CList.
@@ -1629,390 +1640,390 @@ cf_read_current_record(capture_file *cf)
static void
rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect)
{
- /* Rescan packets new packet list */
- guint32 framenum;
- frame_data *fdata;
- wtap_rec rec;
- Buffer buf;
- progdlg_t *progbar = NULL;
- GTimer *prog_timer = g_timer_new();
- int count;
- frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
- int selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
- gboolean selected_frame_seen;
- float progbar_val;
- gint64 start_time;
- gchar status_str[100];
- epan_dissect_t edt;
- dfilter_t *dfcode;
- column_info *cinfo;
- gboolean create_proto_tree;
- guint tap_flags;
- gboolean add_to_packet_list = FALSE;
- gboolean compiled _U_;
- guint32 frames_count;
- gboolean queued_rescan_type = RESCAN_NONE;
-
- /* Rescan in progress, clear pending actions. */
- cf->redissection_queued = RESCAN_NONE;
- ws_assert(!cf->read_lock);
- cf->read_lock = TRUE;
-
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
-
- /* Compile the current display filter.
- * We assume this will not fail since cf->dfilter is only set in
- * cf_filter IFF the filter was valid.
- */
- compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
- ws_assert(!cf->dfilter || (compiled && dfcode));
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- /* If any tap listeners require the columns, construct them. */
- cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a display filter;
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * we're redissecting and a postdissector wants field
- * values or protocols on the first pass.
- */
- create_proto_tree =
- (dfcode != NULL || have_filtering_tap_listeners() ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) ||
- (redissect && postdissectors_want_hfids()));
-
- reset_tap_listeners();
- /* Which frame, if any, is the currently selected frame?
- XXX - should the selected frame or the focus frame be the "current"
- frame, that frame being the one from which "Find Frame" searches
- start? */
- selected_frame = cf->current_frame;
-
- /* Mark frame num as not found */
- selected_frame_num = -1;
-
- /* Freeze the packet list while we redo it, so we don't get any
- screen updates while it happens. */
- packet_list_freeze();
-
- if (redissect) {
- /* We need to re-initialize all the state information that protocols
- keep, because some preference that controls a dissector has changed,
- which might cause the state information to be constructed differently
- by that dissector. */
-
- /* We might receive new packets while redissecting, and we don't
- want to dissect those before their time. */
- cf->redissecting = TRUE;
-
- /* 'reset' dissection session */
- epan_free(cf->epan);
- if (cf->edt && cf->edt->pi.fd) {
- /* All pointers in "per frame proto data" for the currently selected
- packet are allocated in wmem_file_scope() and deallocated in epan_free().
- Free them here to avoid unintended usage in packet_list_clear(). */
- frame_data_destroy(cf->edt->pi.fd);
- }
- cf->epan = ws_epan_new(cf);
- cf->cinfo.epan = cf->epan;
+ /* Rescan packets new packet list */
+ guint32 framenum;
+ frame_data *fdata;
+ wtap_rec rec;
+ Buffer buf;
+ progdlg_t *progbar = NULL;
+ GTimer *prog_timer = g_timer_new();
+ int count;
+ frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
+ int selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
+ gboolean selected_frame_seen;
+ float progbar_val;
+ gint64 start_time;
+ gchar status_str[100];
+ epan_dissect_t edt;
+ dfilter_t *dfcode;
+ column_info *cinfo;
+ gboolean create_proto_tree;
+ guint tap_flags;
+ gboolean add_to_packet_list = FALSE;
+ gboolean compiled _U_;
+ guint32 frames_count;
+ gboolean queued_rescan_type = RESCAN_NONE;
+
+ /* Rescan in progress, clear pending actions. */
+ cf->redissection_queued = RESCAN_NONE;
+ ws_assert(!cf->read_lock);
+ cf->read_lock = TRUE;
- /* A new Lua tap listener may be registered in lua_prime_all_fields()
- called via epan_new() / init_dissection() when reloading Lua plugins. */
- if (!create_proto_tree && have_filtering_tap_listeners()) {
- create_proto_tree = TRUE;
- }
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
- /* We need to redissect the packets so we have to discard our old
- * packet list store. */
- packet_list_clear();
- add_to_packet_list = TRUE;
- }
+ /* Compile the current display filter.
+ * We assume this will not fail since cf->dfilter is only set in
+ * cf_filter IFF the filter was valid.
+ */
+ compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
+ ws_assert(!cf->dfilter || (compiled && dfcode));
- /* We don't yet know which will be the first and last frames displayed. */
- cf->first_displayed = 0;
- cf->last_displayed = 0;
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
- /* We currently don't display any packets */
- cf->displayed_count = 0;
+ /* If any tap listeners require the columns, construct them. */
+ cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
- /* Iterate through the list of frames. Call a routine for each frame
- to check whether it should be displayed and, if so, add it to
- the display list. */
- cf->provider.ref = NULL;
- cf->provider.prev_dis = NULL;
- cf->provider.prev_cap = NULL;
- cf->cum_bytes = 0;
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a display filter;
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * we're redissecting and a postdissector wants field
+ * values or protocols on the first pass.
+ */
+ create_proto_tree =
+ (dfcode != NULL || have_filtering_tap_listeners() ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) ||
+ (redissect && postdissectors_want_hfids()));
- cf_callback_invoke(cf_cb_file_rescan_started, cf);
+ reset_tap_listeners();
+ /* Which frame, if any, is the currently selected frame?
+ XXX - should the selected frame or the focus frame be the "current"
+ frame, that frame being the one from which "Find Frame" searches
+ start? */
+ selected_frame = cf->current_frame;
- g_timer_start(prog_timer);
- /* Count of packets at which we've looked. */
- count = 0;
- /* Progress so far. */
- progbar_val = 0.0f;
+ /* Mark frame num as not found */
+ selected_frame_num = -1;
- cf->stop_flag = FALSE;
- start_time = g_get_monotonic_time();
+ /* Freeze the packet list while we redo it, so we don't get any
+ screen updates while it happens. */
+ packet_list_freeze();
- /* no previous row yet */
- prev_frame_num = -1;
- prev_frame = NULL;
+ if (redissect) {
+ /* We need to re-initialize all the state information that protocols
+ keep, because some preference that controls a dissector has changed,
+ which might cause the state information to be constructed differently
+ by that dissector. */
+
+ /* We might receive new packets while redissecting, and we don't
+ want to dissect those before their time. */
+ cf->redissecting = TRUE;
+
+ /* 'reset' dissection session */
+ epan_free(cf->epan);
+ if (cf->edt && cf->edt->pi.fd) {
+ /* All pointers in "per frame proto data" for the currently selected
+ packet are allocated in wmem_file_scope() and deallocated in epan_free().
+ Free them here to avoid unintended usage in packet_list_clear(). */
+ frame_data_destroy(cf->edt->pi.fd);
+ }
+ cf->epan = ws_epan_new(cf);
+ cf->cinfo.epan = cf->epan;
- preceding_frame_num = -1;
- preceding_frame = NULL;
- following_frame_num = -1;
- following_frame = NULL;
+ /* A new Lua tap listener may be registered in lua_prime_all_fields()
+ called via epan_new() / init_dissection() when reloading Lua plugins. */
+ if (!create_proto_tree && have_filtering_tap_listeners()) {
+ create_proto_tree = TRUE;
+ }
- selected_frame_seen = FALSE;
+ /* We need to redissect the packets so we have to discard our old
+ * packet list store. */
+ packet_list_clear();
+ add_to_packet_list = TRUE;
+ }
- frames_count = cf->count;
+ /* We don't yet know which will be the first and last frames displayed. */
+ cf->first_displayed = 0;
+ cf->last_displayed = 0;
- epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
+ /* We currently don't display any packets */
+ cf->displayed_count = 0;
- if (redissect) {
- /*
- * Decryption secrets are read while sequentially processing records and
- * then passed to the dissector. During redissection, the previous secrets
- * are lost (see epan_free above), but they are not read again from the
- * file as only packet records are re-read. Therefore reset the wtap secrets
- * callback such that wtap resupplies the secrets callback with previously
- * read secrets.
- */
- wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
- }
+ /* Iterate through the list of frames. Call a routine for each frame
+ to check whether it should be displayed and, if so, add it to
+ the display list. */
+ cf->provider.ref = NULL;
+ cf->provider.prev_dis = NULL;
+ cf->provider.prev_cap = NULL;
+ cf->cum_bytes = 0;
- for (framenum = 1; framenum <= frames_count; framenum++) {
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+ cf_callback_invoke(cf_cb_file_rescan_started, cf);
- /* Create the progress bar if necessary.
- We check on every iteration of the loop, so that it takes no
- longer than the standard time to create it (otherwise, for a
- large file, we might take considerably longer than that standard
- time in order to get to the next progress bar step). */
- if (progbar == NULL)
- progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
- &cf->stop_flag,
- progbar_val);
+ g_timer_start(prog_timer);
+ /* Count of packets at which we've looked. */
+ count = 0;
+ /* Progress so far. */
+ progbar_val = 0.0f;
- /*
- * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
- * has elapsed. Calling update_progress_dlg and packets_bar_update will
- * likely trigger UI paint events, which might take a while depending on
- * the platform and display. Reset our timer *after* painting.
- */
- if (g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
- /* let's not divide by zero. I should never be started
- * with count == 0, so let's assert that
- */
- ws_assert(cf->count > 0);
- progbar_val = (gfloat) count / frames_count;
+ cf->stop_flag = FALSE;
+ start_time = g_get_monotonic_time();
- if (progbar != NULL) {
- snprintf(status_str, sizeof(status_str),
- "%4u of %u frames", count, frames_count);
- update_progress_dlg(progbar, progbar_val, status_str);
- }
+ /* no previous row yet */
+ prev_frame_num = -1;
+ prev_frame = NULL;
- g_timer_start(prog_timer);
- }
+ preceding_frame_num = -1;
+ preceding_frame = NULL;
+ following_frame_num = -1;
+ following_frame = NULL;
- queued_rescan_type = cf->redissection_queued;
- if (queued_rescan_type != RESCAN_NONE) {
- /* A redissection was requested while an existing redissection was
- * pending. */
- break;
+ selected_frame_seen = FALSE;
+
+ frames_count = cf->count;
+
+ epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
+
+ if (redissect) {
+ /*
+ * Decryption secrets are read while sequentially processing records and
+ * then passed to the dissector. During redissection, the previous secrets
+ * are lost (see epan_free above), but they are not read again from the
+ * file as only packet records are re-read. Therefore reset the wtap secrets
+ * callback such that wtap resupplies the secrets callback with previously
+ * read secrets.
+ */
+ wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
}
- if (cf->stop_flag) {
- /* Well, the user decided to abort the filtering. Just stop.
+ for (framenum = 1; framenum <= frames_count; framenum++) {
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+
+ /* Create the progress bar if necessary.
+ We check on every iteration of the loop, so that it takes no
+ longer than the standard time to create it (otherwise, for a
+ large file, we might take considerably longer than that standard
+ time in order to get to the next progress bar step). */
+ if (progbar == NULL)
+ progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
+ &cf->stop_flag,
+ progbar_val);
- XXX - go back to the previous filter? Users probably just
- want not to wait for a filtering operation to finish;
- unless we cancel by having no filter, reverting to the
- previous filter will probably be even more expensive than
- continuing the filtering, as it involves going back to the
- beginning and filtering, and even with no filter we currently
- have to re-generate the entire clist, which is also expensive.
+ /*
+ * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
+ * has elapsed. Calling update_progress_dlg and packets_bar_update will
+ * likely trigger UI paint events, which might take a while depending on
+ * the platform and display. Reset our timer *after* painting.
+ */
+ if (g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
+ /* let's not divide by zero. I should never be started
+ * with count == 0, so let's assert that
+ */
+ ws_assert(cf->count > 0);
+ progbar_val = (gfloat) count / frames_count;
- I'm not sure what Network Monitor does, but it doesn't appear
- to give you an unfiltered display if you cancel. */
- break;
+ if (progbar != NULL) {
+ snprintf(status_str, sizeof(status_str),
+ "%4u of %u frames", count, frames_count);
+ update_progress_dlg(progbar, progbar_val, status_str);
+ }
+
+ g_timer_start(prog_timer);
+ }
+
+ queued_rescan_type = cf->redissection_queued;
+ if (queued_rescan_type != RESCAN_NONE) {
+ /* A redissection was requested while an existing redissection was
+ * pending. */
+ break;
+ }
+
+ if (cf->stop_flag) {
+ /* Well, the user decided to abort the filtering. Just stop.
+
+ XXX - go back to the previous filter? Users probably just
+ want not to wait for a filtering operation to finish;
+ unless we cancel by having no filter, reverting to the
+ previous filter will probably be even more expensive than
+ continuing the filtering, as it involves going back to the
+ beginning and filtering, and even with no filter we currently
+ have to re-generate the entire clist, which is also expensive.
+
+ I'm not sure what Network Monitor does, but it doesn't appear
+ to give you an unfiltered display if you cancel. */
+ break;
+ }
+
+ count++;
+
+ if (redissect) {
+ /* Since all state for the frame was destroyed, mark the frame
+ * as not visited, free the GSList referring to the state
+ * data (the per-frame data itself was freed by
+ * "init_dissection()"), and null out the GSList pointer. */
+ frame_data_reset(fdata);
+ frames_count = cf->count;
+ }
+
+ /* Frame dependencies from the previous dissection/filtering are no longer valid. */
+ fdata->dependent_of_displayed = 0;
+
+ if (!cf_read_record(cf, fdata, &rec, &buf))
+ break; /* error reading the frame */
+
+ /* If the previous frame is displayed, and we haven't yet seen the
+ selected frame, remember that frame - it's the closest one we've
+ yet seen before the selected frame. */
+ if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->passed_dfilter) {
+ preceding_frame_num = prev_frame_num;
+ preceding_frame = prev_frame;
+ }
+
+ add_packet_to_packet_list(fdata, cf, &edt, dfcode,
+ cinfo, &rec, &buf,
+ add_to_packet_list);
+
+ /* If this frame is displayed, and this is the first frame we've
+ seen displayed after the selected frame, remember this frame -
+ it's the closest one we've yet seen at or after the selected
+ frame. */
+ if (fdata->passed_dfilter && selected_frame_seen && following_frame_num == -1) {
+ following_frame_num = fdata->num;
+ following_frame = fdata;
+ }
+ if (fdata == selected_frame) {
+ selected_frame_seen = TRUE;
+ if (fdata->passed_dfilter)
+ selected_frame_num = fdata->num;
+ }
+
+ /* Remember this frame - it'll be the previous frame
+ on the next pass through the loop. */
+ prev_frame_num = fdata->num;
+ prev_frame = fdata;
+ wtap_rec_reset(&rec);
}
- count++;
+ epan_dissect_cleanup(&edt);
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+
+ /* We are done redissecting the packet list. */
+ cf->redissecting = FALSE;
if (redissect) {
- /* Since all state for the frame was destroyed, mark the frame
- * as not visited, free the GSList referring to the state
- * data (the per-frame data itself was freed by
- * "init_dissection()"), and null out the GSList pointer. */
- frame_data_reset(fdata);
- frames_count = cf->count;
- }
-
- /* Frame dependencies from the previous dissection/filtering are no longer valid. */
- fdata->dependent_of_displayed = 0;
-
- if (!cf_read_record(cf, fdata, &rec, &buf))
- break; /* error reading the frame */
-
- /* If the previous frame is displayed, and we haven't yet seen the
- selected frame, remember that frame - it's the closest one we've
- yet seen before the selected frame. */
- if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->passed_dfilter) {
- preceding_frame_num = prev_frame_num;
- preceding_frame = prev_frame;
- }
-
- add_packet_to_packet_list(fdata, cf, &edt, dfcode,
- cinfo, &rec, &buf,
- add_to_packet_list);
-
- /* If this frame is displayed, and this is the first frame we've
- seen displayed after the selected frame, remember this frame -
- it's the closest one we've yet seen at or after the selected
- frame. */
- if (fdata->passed_dfilter && selected_frame_seen && following_frame_num == -1) {
- following_frame_num = fdata->num;
- following_frame = fdata;
- }
- if (fdata == selected_frame) {
- selected_frame_seen = TRUE;
- if (fdata->passed_dfilter)
- selected_frame_num = fdata->num;
- }
-
- /* Remember this frame - it'll be the previous frame
- on the next pass through the loop. */
- prev_frame_num = fdata->num;
- prev_frame = fdata;
- wtap_rec_reset(&rec);
- }
-
- epan_dissect_cleanup(&edt);
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
-
- /* We are done redissecting the packet list. */
- cf->redissecting = FALSE;
-
- if (redissect) {
- frames_count = cf->count;
- /* Clear out what remains of the visited flags and per-frame data
- pointers.
-
- XXX - that may cause various forms of bogosity when dissecting
- these frames, as they won't have been seen by this sequential
- pass, but the only alternative I see is to keep scanning them
- even though the user requested that the scan stop, and that
- would leave the user stuck with an Wireshark grinding on
- until it finishes. Should we just stick them with that? */
- for (; framenum <= frames_count; framenum++) {
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
- frame_data_reset(fdata);
- }
- }
-
- /* We're done filtering the packets; destroy the progress bar if it
- was created. */
- if (progbar != NULL)
- destroy_progress_dlg(progbar);
- g_timer_destroy(prog_timer);
-
- /* Unfreeze the packet list. */
- if (!add_to_packet_list)
- packet_list_recreate_visible_rows();
-
- /* Compute the time it took to filter the file */
- compute_elapsed(cf, start_time);
-
- packet_list_thaw();
-
- cf_callback_invoke(cf_cb_file_rescan_finished, cf);
-
- if (selected_frame_num == -1) {
- /* The selected frame didn't pass the filter. */
- if (selected_frame == NULL) {
- /* That's because there *was* no selected frame. Make the first
- displayed frame the current frame. */
- selected_frame_num = 0;
+ frames_count = cf->count;
+ /* Clear out what remains of the visited flags and per-frame data
+ pointers.
+
+ XXX - that may cause various forms of bogosity when dissecting
+ these frames, as they won't have been seen by this sequential
+ pass, but the only alternative I see is to keep scanning them
+ even though the user requested that the scan stop, and that
+ would leave the user stuck with an Wireshark grinding on
+ until it finishes. Should we just stick them with that? */
+ for (; framenum <= frames_count; framenum++) {
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+ frame_data_reset(fdata);
+ }
+ }
+
+ /* We're done filtering the packets; destroy the progress bar if it
+ was created. */
+ if (progbar != NULL)
+ destroy_progress_dlg(progbar);
+ g_timer_destroy(prog_timer);
+
+ /* Unfreeze the packet list. */
+ if (!add_to_packet_list)
+ packet_list_recreate_visible_rows();
+
+ /* Compute the time it took to filter the file */
+ compute_elapsed(cf, start_time);
+
+ packet_list_thaw();
+
+ cf_callback_invoke(cf_cb_file_rescan_finished, cf);
+
+ if (selected_frame_num == -1) {
+ /* The selected frame didn't pass the filter. */
+ if (selected_frame == NULL) {
+ /* That's because there *was* no selected frame. Make the first
+ displayed frame the current frame. */
+ selected_frame_num = 0;
+ } else {
+ /* Find the nearest displayed frame to the selected frame (whether
+ it's before or after that frame) and make that the current frame.
+ If the next and previous displayed frames are equidistant from the
+ selected frame, choose the next one. */
+ ws_assert(following_frame == NULL ||
+ following_frame->num >= selected_frame->num);
+ ws_assert(preceding_frame == NULL ||
+ preceding_frame->num <= selected_frame->num);
+ if (following_frame == NULL) {
+ /* No frame after the selected frame passed the filter, so we
+ have to select the last displayed frame before the selected
+ frame. */
+ selected_frame_num = preceding_frame_num;
+ selected_frame = preceding_frame;
+ } else if (preceding_frame == NULL) {
+ /* No frame before the selected frame passed the filter, so we
+ have to select the first displayed frame after the selected
+ frame. */
+ selected_frame_num = following_frame_num;
+ selected_frame = following_frame;
+ } else {
+ /* Frames before and after the selected frame passed the filter, so
+ we'll select the previous frame */
+ selected_frame_num = preceding_frame_num;
+ selected_frame = preceding_frame;
+ }
+ }
+ }
+
+ if (selected_frame_num == -1) {
+ /* There are no frames displayed at all. */
+ cf_unselect_packet(cf);
} else {
- /* Find the nearest displayed frame to the selected frame (whether
- it's before or after that frame) and make that the current frame.
- If the next and previous displayed frames are equidistant from the
- selected frame, choose the next one. */
- ws_assert(following_frame == NULL ||
- following_frame->num >= selected_frame->num);
- ws_assert(preceding_frame == NULL ||
- preceding_frame->num <= selected_frame->num);
- if (following_frame == NULL) {
- /* No frame after the selected frame passed the filter, so we
- have to select the last displayed frame before the selected
- frame. */
- selected_frame_num = preceding_frame_num;
- selected_frame = preceding_frame;
- } else if (preceding_frame == NULL) {
- /* No frame before the selected frame passed the filter, so we
- have to select the first displayed frame after the selected
- frame. */
- selected_frame_num = following_frame_num;
- selected_frame = following_frame;
- } else {
- /* Frames before and after the selected frame passed the filter, so
- we'll select the previous frame */
- selected_frame_num = preceding_frame_num;
- selected_frame = preceding_frame;
- }
- }
- }
-
- if (selected_frame_num == -1) {
- /* There are no frames displayed at all. */
- cf_unselect_packet(cf);
- } else {
- /* Either the frame that was selected passed the filter, or we've
- found the nearest displayed frame to that frame. Select it, make
- it the focus row, and make it visible. */
- /* Set to invalid to force update of packet list and packet details */
- cf->current_row = -1;
- if (selected_frame_num == 0) {
- packet_list_select_first_row();
- }else{
- if (!packet_list_select_row_from_data(selected_frame)) {
- /* We didn't find a row corresponding to this frame.
- This means that the frame isn't being displayed currently,
- so we can't select it. */
- simple_message_box(ESD_TYPE_INFO, NULL,
- "The capture file is probably not fully dissected.",
- "End of capture exceeded.");
- }
+ /* Either the frame that was selected passed the filter, or we've
+ found the nearest displayed frame to that frame. Select it, make
+ it the focus row, and make it visible. */
+ /* Set to invalid to force update of packet list and packet details */
+ cf->current_row = -1;
+ if (selected_frame_num == 0) {
+ packet_list_select_first_row();
+ }else{
+ if (!packet_list_select_row_from_data(selected_frame)) {
+ /* We didn't find a row corresponding to this frame.
+ This means that the frame isn't being displayed currently,
+ so we can't select it. */
+ simple_message_box(ESD_TYPE_INFO, NULL,
+ "The capture file is probably not fully dissected.",
+ "End of capture exceeded.");
+ }
+ }
}
- }
- /* Cleanup and release all dfilter resources */
- dfilter_free(dfcode);
+ /* Cleanup and release all dfilter resources */
+ dfilter_free(dfcode);
- /* It is safe again to execute redissections. */
- ws_assert(cf->read_lock);
- cf->read_lock = FALSE;
+ /* It is safe again to execute redissections. */
+ ws_assert(cf->read_lock);
+ cf->read_lock = FALSE;
- /* If another rescan (due to dfilter change) or redissection (due to profile
- * change) was requested, the rescan above is aborted and restarted here. */
- if (queued_rescan_type != RESCAN_NONE) {
- redissect = redissect || queued_rescan_type == RESCAN_REDISSECT;
- rescan_packets(cf, "Reprocessing", "all packets", redissect);
- }
+ /* If another rescan (due to dfilter change) or redissection (due to profile
+ * change) was requested, the rescan above is aborted and restarted here. */
+ if (queued_rescan_type != RESCAN_NONE) {
+ redissect = redissect || queued_rescan_type == RESCAN_REDISSECT;
+ rescan_packets(cf, "Reprocessing", "all packets", redissect);
+ }
}
@@ -2024,1233 +2035,1233 @@ rescan_packets(capture_file *cf, const char *action, const char *action_item, gb
void
cf_reftime_packets(capture_file* cf)
{
- guint32 framenum;
- frame_data *fdata;
- nstime_t rel_ts;
+ guint32 framenum;
+ frame_data *fdata;
+ nstime_t rel_ts;
- cf->provider.ref = NULL;
- cf->provider.prev_dis = NULL;
- cf->cum_bytes = 0;
+ cf->provider.ref = NULL;
+ cf->provider.prev_dis = NULL;
+ cf->cum_bytes = 0;
- for (framenum = 1; framenum <= cf->count; framenum++) {
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+ for (framenum = 1; framenum <= cf->count; framenum++) {
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
- /* just add some value here until we know if it is being displayed or not */
- fdata->cum_bytes = cf->cum_bytes + fdata->pkt_len;
+ /* just add some value here until we know if it is being displayed or not */
+ fdata->cum_bytes = cf->cum_bytes + fdata->pkt_len;
- /*
- *Timestamps
- */
+ /*
+ *Timestamps
+ */
- /* If we don't have the time stamp of the first packet in the
- capture, it's because this is the first packet. Save the time
- stamp of this packet as the time stamp of the first packet. */
- if (cf->provider.ref == NULL)
- cf->provider.ref = fdata;
- /* if this frames is marked as a reference time frame, reset
- firstsec and firstusec to this frame */
- if (fdata->ref_time)
- cf->provider.ref = fdata;
-
- /* If we don't have the time stamp of the previous displayed packet,
- it's because this is the first displayed packet. Save the time
- stamp of this packet as the time stamp of the previous displayed
- packet. */
- if (cf->provider.prev_dis == NULL) {
- cf->provider.prev_dis = fdata;
- }
+ /* If we don't have the time stamp of the first packet in the
+ capture, it's because this is the first packet. Save the time
+ stamp of this packet as the time stamp of the first packet. */
+ if (cf->provider.ref == NULL)
+ cf->provider.ref = fdata;
+ /* if this frames is marked as a reference time frame, reset
+ firstsec and firstusec to this frame */
+ if (fdata->ref_time)
+ cf->provider.ref = fdata;
+
+ /* If we don't have the time stamp of the previous displayed packet,
+ it's because this is the first displayed packet. Save the time
+ stamp of this packet as the time stamp of the previous displayed
+ packet. */
+ if (cf->provider.prev_dis == NULL) {
+ cf->provider.prev_dis = fdata;
+ }
- /* Get the time elapsed between the first packet and this packet. */
- fdata->frame_ref_num = (fdata != cf->provider.ref) ? cf->provider.ref->num : 0;
- nstime_delta(&rel_ts, &fdata->abs_ts, &cf->provider.ref->abs_ts);
+ /* Get the time elapsed between the first packet and this packet. */
+ fdata->frame_ref_num = (fdata != cf->provider.ref) ? cf->provider.ref->num : 0;
+ nstime_delta(&rel_ts, &fdata->abs_ts, &cf->provider.ref->abs_ts);
- /* If it's greater than the current elapsed time, set the elapsed time
- to it (we check for "greater than" so as not to be confused by
- time moving backwards). */
- if ((gint32)cf->elapsed_time.secs < rel_ts.secs
- || ((gint32)cf->elapsed_time.secs == rel_ts.secs && (gint32)cf->elapsed_time.nsecs < rel_ts.nsecs)) {
- cf->elapsed_time = rel_ts;
- }
+ /* If it's greater than the current elapsed time, set the elapsed time
+ to it (we check for "greater than" so as not to be confused by
+ time moving backwards). */
+ if ((gint32)cf->elapsed_time.secs < rel_ts.secs
+ || ((gint32)cf->elapsed_time.secs == rel_ts.secs && (gint32)cf->elapsed_time.nsecs < rel_ts.nsecs)) {
+ cf->elapsed_time = rel_ts;
+ }
- /* If this frame is displayed, get the time elapsed between the
- previous displayed packet and this packet. */
- if ( fdata->passed_dfilter ) {
- fdata->prev_dis_num = cf->provider.prev_dis->num;
- cf->provider.prev_dis = fdata;
- }
+ /* If this frame is displayed, get the time elapsed between the
+ previous displayed packet and this packet. */
+ if ( fdata->passed_dfilter ) {
+ fdata->prev_dis_num = cf->provider.prev_dis->num;
+ cf->provider.prev_dis = fdata;
+ }
- /*
- * Byte counts
- */
- if ( (fdata->passed_dfilter) || (fdata->ref_time) ) {
- /* This frame either passed the display filter list or is marked as
- a time reference frame. All time reference frames are displayed
- even if they don't pass the display filter */
- if (fdata->ref_time) {
- /* if this was a TIME REF frame we should reset the cum_bytes field */
- cf->cum_bytes = fdata->pkt_len;
- fdata->cum_bytes = cf->cum_bytes;
- } else {
- /* increase cum_bytes with this packets length */
- cf->cum_bytes += fdata->pkt_len;
+ /*
+ * Byte counts
+ */
+ if ( (fdata->passed_dfilter) || (fdata->ref_time) ) {
+ /* This frame either passed the display filter list or is marked as
+ a time reference frame. All time reference frames are displayed
+ even if they don't pass the display filter */
+ if (fdata->ref_time) {
+ /* if this was a TIME REF frame we should reset the cum_bytes field */
+ cf->cum_bytes = fdata->pkt_len;
+ fdata->cum_bytes = cf->cum_bytes;
+ } else {
+ /* increase cum_bytes with this packets length */
+ cf->cum_bytes += fdata->pkt_len;
+ }
}
}
- }
}
typedef enum {
- PSP_FINISHED,
- PSP_STOPPED,
- PSP_FAILED
+ PSP_FINISHED,
+ PSP_STOPPED,
+ PSP_FAILED
} psp_return_t;
static psp_return_t
process_specified_records(capture_file *cf, packet_range_t *range,
- const char *string1, const char *string2, gboolean terminate_is_stop,
- gboolean (*callback)(capture_file *, frame_data *,
- wtap_rec *, Buffer *, void *),
- void *callback_args,
- gboolean show_progress_bar)
+ const char *string1, const char *string2, gboolean terminate_is_stop,
+ gboolean (*callback)(capture_file *, frame_data *,
+ wtap_rec *, Buffer *, void *),
+ void *callback_args,
+ gboolean show_progress_bar)
{
- guint32 framenum;
- frame_data *fdata;
- wtap_rec rec;
- Buffer buf;
- psp_return_t ret = PSP_FINISHED;
-
- progdlg_t *progbar = NULL;
- GTimer *prog_timer = g_timer_new();
- int progbar_count;
- float progbar_val;
- gchar progbar_status_str[100];
- range_process_e process_this;
-
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
-
- g_timer_start(prog_timer);
- /* Count of packets at which we've looked. */
- progbar_count = 0;
- /* Progress so far. */
- progbar_val = 0.0f;
-
- if (cf->read_lock) {
- ws_warning("Failing due to nested process_specified_records(\"%s\") call!", cf->filename);
- return PSP_FAILED;
- }
- cf->read_lock = TRUE;
-
- cf->stop_flag = FALSE;
-
- if (range != NULL)
- packet_range_process_init(range);
+ guint32 framenum;
+ frame_data *fdata;
+ wtap_rec rec;
+ Buffer buf;
+ psp_return_t ret = PSP_FINISHED;
+
+ progdlg_t *progbar = NULL;
+ GTimer *prog_timer = g_timer_new();
+ int progbar_count;
+ float progbar_val;
+ gchar progbar_status_str[100];
+ range_process_e process_this;
+
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
- /* Iterate through all the packets, printing the packets that
- were selected by the current display filter. */
- for (framenum = 1; framenum <= cf->count; framenum++) {
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
-
- /* Create the progress bar if necessary.
- We check on every iteration of the loop, so that it takes no
- longer than the standard time to create it (otherwise, for a
- large file, we might take considerably longer than that standard
- time in order to get to the next progress bar step). */
- if (show_progress_bar && progbar == NULL)
- progbar = delayed_create_progress_dlg(cf->window, string1, string2,
- terminate_is_stop,
- &cf->stop_flag,
- progbar_val);
+ g_timer_start(prog_timer);
+ /* Count of packets at which we've looked. */
+ progbar_count = 0;
+ /* Progress so far. */
+ progbar_val = 0.0f;
- /*
- * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
- * has elapsed. Calling update_progress_dlg and packets_bar_update will
- * likely trigger UI paint events, which might take a while depending on
- * the platform and display. Reset our timer *after* painting.
- */
- if (progbar && g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
- /* let's not divide by zero. I should never be started
- * with count == 0, so let's assert that
- */
- ws_assert(cf->count > 0);
- progbar_val = (gfloat) progbar_count / cf->count;
+ if (cf->read_lock) {
+ ws_warning("Failing due to nested process_specified_records(\"%s\") call!", cf->filename);
+ return PSP_FAILED;
+ }
+ cf->read_lock = TRUE;
+
+ cf->stop_flag = FALSE;
+
+ if (range != NULL)
+ packet_range_process_init(range);
+
+ /* Iterate through all the packets, printing the packets that
+ were selected by the current display filter. */
+ for (framenum = 1; framenum <= cf->count; framenum++) {
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+
+ /* Create the progress bar if necessary.
+ We check on every iteration of the loop, so that it takes no
+ longer than the standard time to create it (otherwise, for a
+ large file, we might take considerably longer than that standard
+ time in order to get to the next progress bar step). */
+ if (show_progress_bar && progbar == NULL)
+ progbar = delayed_create_progress_dlg(cf->window, string1, string2,
+ terminate_is_stop,
+ &cf->stop_flag,
+ progbar_val);
+
+ /*
+ * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
+ * has elapsed. Calling update_progress_dlg and packets_bar_update will
+ * likely trigger UI paint events, which might take a while depending on
+ * the platform and display. Reset our timer *after* painting.
+ */
+ if (progbar && g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
+ /* let's not divide by zero. I should never be started
+ * with count == 0, so let's assert that
+ */
+ ws_assert(cf->count > 0);
+ progbar_val = (gfloat) progbar_count / cf->count;
+
+ snprintf(progbar_status_str, sizeof(progbar_status_str),
+ "%4u of %u packets", progbar_count, cf->count);
+ update_progress_dlg(progbar, progbar_val, progbar_status_str);
+
+ g_timer_start(prog_timer);
+ }
+
+ if (cf->stop_flag) {
+ /* Well, the user decided to abort the operation. Just stop,
+ and arrange to return PSP_STOPPED to our caller, so they know
+ it was stopped explicitly. */
+ ret = PSP_STOPPED;
+ break;
+ }
- snprintf(progbar_status_str, sizeof(progbar_status_str),
- "%4u of %u packets", progbar_count, cf->count);
- update_progress_dlg(progbar, progbar_val, progbar_status_str);
+ progbar_count++;
+
+ if (range != NULL) {
+ /* do we have to process this packet? */
+ process_this = packet_range_process_packet(range, fdata);
+ if (process_this == range_process_next) {
+ /* this packet uninteresting, continue with next one */
+ continue;
+ } else if (process_this == range_processing_finished) {
+ /* all interesting packets processed, stop the loop */
+ break;
+ }
+ }
- g_timer_start(prog_timer);
+ /* Get the packet */
+ if (!cf_read_record(cf, fdata, &rec, &buf)) {
+ /* Attempt to get the packet failed. */
+ ret = PSP_FAILED;
+ break;
+ }
+ /* Process the packet */
+ if (!callback(cf, fdata, &rec, &buf, callback_args)) {
+ /* Callback failed. We assume it reported the error appropriately. */
+ ret = PSP_FAILED;
+ break;
+ }
+ wtap_rec_reset(&rec);
}
- if (cf->stop_flag) {
- /* Well, the user decided to abort the operation. Just stop,
- and arrange to return PSP_STOPPED to our caller, so they know
- it was stopped explicitly. */
- ret = PSP_STOPPED;
- break;
- }
-
- progbar_count++;
-
- if (range != NULL) {
- /* do we have to process this packet? */
- process_this = packet_range_process_packet(range, fdata);
- if (process_this == range_process_next) {
- /* this packet uninteresting, continue with next one */
- continue;
- } else if (process_this == range_processing_finished) {
- /* all interesting packets processed, stop the loop */
- break;
- }
- }
-
- /* Get the packet */
- if (!cf_read_record(cf, fdata, &rec, &buf)) {
- /* Attempt to get the packet failed. */
- ret = PSP_FAILED;
- break;
- }
- /* Process the packet */
- if (!callback(cf, fdata, &rec, &buf, callback_args)) {
- /* Callback failed. We assume it reported the error appropriately. */
- ret = PSP_FAILED;
- break;
- }
- wtap_rec_reset(&rec);
- }
-
- /* We're done printing the packets; destroy the progress bar if
- it was created. */
- if (progbar != NULL)
- destroy_progress_dlg(progbar);
- g_timer_destroy(prog_timer);
-
- ws_assert(cf->read_lock);
- cf->read_lock = FALSE;
-
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
-
- return ret;
+ /* We're done printing the packets; destroy the progress bar if
+ it was created. */
+ if (progbar != NULL)
+ destroy_progress_dlg(progbar);
+ g_timer_destroy(prog_timer);
+
+ ws_assert(cf->read_lock);
+ cf->read_lock = FALSE;
+
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+
+ return ret;
}
typedef struct {
- epan_dissect_t edt;
- column_info *cinfo;
+ epan_dissect_t edt;
+ column_info *cinfo;
} retap_callback_args_t;
static gboolean
retap_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec, Buffer *buf,
- void *argsp)
+ void *argsp)
{
- retap_callback_args_t *args = (retap_callback_args_t *)argsp;
+ retap_callback_args_t *args = (retap_callback_args_t *)argsp;
- epan_dissect_run_with_taps(&args->edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, args->cinfo);
- epan_dissect_reset(&args->edt);
+ epan_dissect_run_with_taps(&args->edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, args->cinfo);
+ epan_dissect_reset(&args->edt);
- return TRUE;
+ return TRUE;
}
cf_read_status_t
cf_retap_packets(capture_file *cf)
{
- packet_range_t range;
- retap_callback_args_t callback_args;
- gboolean create_proto_tree;
- guint tap_flags;
- psp_return_t ret;
-
- /* Presumably the user closed the capture file. */
- if (cf == NULL) {
- return CF_READ_ABORTED;
- }
-
- cf_callback_invoke(cf_cb_file_retap_started, cf);
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- /* If any tap listeners require the columns, construct them. */
- callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree.
- */
- create_proto_tree =
- (have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
-
- /* Reset the tap listeners. */
- reset_tap_listeners();
-
- epan_dissect_init(&callback_args.edt, cf->epan, create_proto_tree, FALSE);
-
- /* Iterate through the list of packets, dissecting all packets and
- re-running the taps. */
- packet_range_init(&range, cf);
- packet_range_process_init(&range);
-
- ret = process_specified_records(cf, &range, "Recalculating statistics on",
- "all packets", TRUE, retap_packet,
- &callback_args, TRUE);
-
- packet_range_cleanup(&range);
- epan_dissect_cleanup(&callback_args.edt);
-
- cf_callback_invoke(cf_cb_file_retap_finished, cf);
-
- switch (ret) {
- case PSP_FINISHED:
- /* Completed successfully. */
- return CF_READ_OK;
+ packet_range_t range;
+ retap_callback_args_t callback_args;
+ gboolean create_proto_tree;
+ guint tap_flags;
+ psp_return_t ret;
+
+ /* Presumably the user closed the capture file. */
+ if (cf == NULL) {
+ return CF_READ_ABORTED;
+ }
+
+ cf_callback_invoke(cf_cb_file_retap_started, cf);
+
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
+
+ /* If any tap listeners require the columns, construct them. */
+ callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree.
+ */
+ create_proto_tree =
+ (have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
- case PSP_STOPPED:
- /* Well, the user decided to abort the refiltering.
- Return CF_READ_ABORTED so our caller knows they did that. */
- return CF_READ_ABORTED;
+ /* Reset the tap listeners. */
+ reset_tap_listeners();
- case PSP_FAILED:
- /* Error while retapping. */
- return CF_READ_ERROR;
- }
+ epan_dissect_init(&callback_args.edt, cf->epan, create_proto_tree, FALSE);
+
+ /* Iterate through the list of packets, dissecting all packets and
+ re-running the taps. */
+ packet_range_init(&range, cf);
+ packet_range_process_init(&range);
+
+ ret = process_specified_records(cf, &range, "Recalculating statistics on",
+ "all packets", TRUE, retap_packet,
+ &callback_args, TRUE);
+
+ packet_range_cleanup(&range);
+ epan_dissect_cleanup(&callback_args.edt);
+
+ cf_callback_invoke(cf_cb_file_retap_finished, cf);
+
+ switch (ret) {
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ return CF_READ_OK;
+
+ case PSP_STOPPED:
+ /* Well, the user decided to abort the refiltering.
+ Return CF_READ_ABORTED so our caller knows they did that. */
+ return CF_READ_ABORTED;
+
+ case PSP_FAILED:
+ /* Error while retapping. */
+ return CF_READ_ERROR;
+ }
- ws_assert_not_reached();
- return CF_READ_OK;
+ ws_assert_not_reached();
+ return CF_READ_OK;
}
typedef struct {
- print_args_t *print_args;
- gboolean print_header_line;
- char *header_line_buf;
- int header_line_buf_len;
- gboolean print_formfeed;
- gboolean print_separator;
- char *line_buf;
- int line_buf_len;
- gint *col_widths;
- int num_visible_cols;
- gint *visible_cols;
- epan_dissect_t edt;
+ print_args_t *print_args;
+ gboolean print_header_line;
+ char *header_line_buf;
+ int header_line_buf_len;
+ gboolean print_formfeed;
+ gboolean print_separator;
+ char *line_buf;
+ int line_buf_len;
+ gint *col_widths;
+ int num_visible_cols;
+ gint *visible_cols;
+ epan_dissect_t edt;
} print_callback_args_t;
static gboolean
print_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec, Buffer *buf,
- void *argsp)
+ void *argsp)
{
- print_callback_args_t *args = (print_callback_args_t *)argsp;
- int i;
- char *cp;
- int line_len;
- int column_len;
- int cp_off;
- char bookmark_name[9+10+1]; /* "__frameNNNNNNNNNN__\0" */
- char bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0" */
- col_item_t* col_item;
-
- /* Fill in the column information if we're printing the summary
- information. */
- if (args->print_args->print_summary) {
- col_custom_prime_edt(&args->edt, &cf->cinfo);
- epan_dissect_run(&args->edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, &cf->cinfo);
- epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
- } else
- epan_dissect_run(&args->edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, NULL);
-
- if (args->print_formfeed) {
- if (!new_page(args->print_args->stream))
- goto fail;
+ print_callback_args_t *args = (print_callback_args_t *)argsp;
+ int i;
+ char *cp;
+ int line_len;
+ int column_len;
+ int cp_off;
+ char bookmark_name[9+10+1]; /* "__frameNNNNNNNNNN__\0" */
+ char bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0" */
+ col_item_t* col_item;
+
+ /* Fill in the column information if we're printing the summary
+ information. */
+ if (args->print_args->print_summary) {
+ col_custom_prime_edt(&args->edt, &cf->cinfo);
+ epan_dissect_run(&args->edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, &cf->cinfo);
+ epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
+ } else
+ epan_dissect_run(&args->edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, NULL);
- /*
- * Print another header line if we print a packet summary on the
- * new page.
- */
- if (args->print_args->print_col_headings)
- args->print_header_line = TRUE;
- } else {
- if (args->print_separator) {
- if (!print_line(args->print_args->stream, 0, ""))
- goto fail;
- }
- }
-
- /*
- * We generate bookmarks, if the output format supports them.
- * The name is "__frameN__".
- */
- snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
-
- if (args->print_args->print_summary) {
- if (!args->print_args->print_col_headings)
- args->print_header_line = FALSE;
- if (args->print_header_line) {
- if (!print_line(args->print_args->stream, 0, args->header_line_buf))
- goto fail;
- args->print_header_line = FALSE; /* we might not need to print any more */
- }
- cp = &args->line_buf[0];
- line_len = 0;
- for (i = 0; i < args->num_visible_cols; i++) {
- col_item = &cf->cinfo.columns[args->visible_cols[i]];
- /* Find the length of the string for this column. */
- column_len = (int) strlen(col_item->col_data);
- if (args->col_widths[i] > column_len)
- column_len = args->col_widths[i];
-
- /* Make sure there's room in the line buffer for the column; if not,
- double its length. */
- line_len += column_len + 1; /* "+1" for space */
- if (line_len > args->line_buf_len) {
- cp_off = (int) (cp - args->line_buf);
- args->line_buf_len = 2 * line_len;
- args->line_buf = (char *)g_realloc(args->line_buf, args->line_buf_len + 1);
- cp = args->line_buf + cp_off;
- }
-
- /* Right-justify the packet number column. */
- if (col_item->col_fmt == COL_NUMBER)
- snprintf(cp, column_len+1, "%*s", args->col_widths[i], col_item->col_data);
- else
- snprintf(cp, column_len+1, "%-*s", args->col_widths[i], col_item->col_data);
- cp += column_len;
- if (i != args->num_visible_cols - 1)
- *cp++ = ' ';
- }
- *cp = '\0';
+ if (args->print_formfeed) {
+ if (!new_page(args->print_args->stream))
+ goto fail;
- /*
- * Generate a bookmark, using the summary line as the title.
- */
- if (!print_bookmark(args->print_args->stream, bookmark_name,
- args->line_buf))
- goto fail;
+ /*
+ * Print another header line if we print a packet summary on the
+ * new page.
+ */
+ if (args->print_args->print_col_headings)
+ args->print_header_line = TRUE;
+ } else {
+ if (args->print_separator) {
+ if (!print_line(args->print_args->stream, 0, ""))
+ goto fail;
+ }
+ }
- if (!print_line(args->print_args->stream, 0, args->line_buf))
- goto fail;
- } else {
/*
- * Generate a bookmark, using "Frame N" as the title, as we're not
- * printing the summary line.
+ * We generate bookmarks, if the output format supports them.
+ * The name is "__frameN__".
*/
- snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
- if (!print_bookmark(args->print_args->stream, bookmark_name,
- bookmark_title))
- goto fail;
- } /* if (print_summary) */
+ snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
- if (args->print_args->print_dissections != print_dissections_none) {
if (args->print_args->print_summary) {
- /* Separate the summary line from the tree with a blank line. */
- if (!print_line(args->print_args->stream, 0, ""))
- goto fail;
- }
+ if (!args->print_args->print_col_headings)
+ args->print_header_line = FALSE;
+ if (args->print_header_line) {
+ if (!print_line(args->print_args->stream, 0, args->header_line_buf))
+ goto fail;
+ args->print_header_line = FALSE; /* we might not need to print any more */
+ }
+ cp = &args->line_buf[0];
+ line_len = 0;
+ for (i = 0; i < args->num_visible_cols; i++) {
+ col_item = &cf->cinfo.columns[args->visible_cols[i]];
+ /* Find the length of the string for this column. */
+ column_len = (int) strlen(col_item->col_data);
+ if (args->col_widths[i] > column_len)
+ column_len = args->col_widths[i];
+
+ /* Make sure there's room in the line buffer for the column; if not,
+ double its length. */
+ line_len += column_len + 1; /* "+1" for space */
+ if (line_len > args->line_buf_len) {
+ cp_off = (int) (cp - args->line_buf);
+ args->line_buf_len = 2 * line_len;
+ args->line_buf = (char *)g_realloc(args->line_buf, args->line_buf_len + 1);
+ cp = args->line_buf + cp_off;
+ }
+
+ /* Right-justify the packet number column. */
+ if (col_item->col_fmt == COL_NUMBER)
+ snprintf(cp, column_len+1, "%*s", args->col_widths[i], col_item->col_data);
+ else
+ snprintf(cp, column_len+1, "%-*s", args->col_widths[i], col_item->col_data);
+ cp += column_len;
+ if (i != args->num_visible_cols - 1)
+ *cp++ = ' ';
+ }
+ *cp = '\0';
- /* Print the information in that tree. */
- if (!proto_tree_print(args->print_args->print_dissections,
- args->print_args->print_hex, &args->edt, NULL,
- args->print_args->stream))
- goto fail;
+ /*
+ * Generate a bookmark, using the summary line as the title.
+ */
+ if (!print_bookmark(args->print_args->stream, bookmark_name,
+ args->line_buf))
+ goto fail;
+
+ if (!print_line(args->print_args->stream, 0, args->line_buf))
+ goto fail;
+ } else {
+ /*
+ * Generate a bookmark, using "Frame N" as the title, as we're not
+ * printing the summary line.
+ */
+ snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
+ if (!print_bookmark(args->print_args->stream, bookmark_name,
+ bookmark_title))
+ goto fail;
+ } /* if (print_summary) */
+
+ if (args->print_args->print_dissections != print_dissections_none) {
+ if (args->print_args->print_summary) {
+ /* Separate the summary line from the tree with a blank line. */
+ if (!print_line(args->print_args->stream, 0, ""))
+ goto fail;
+ }
- /* Print a blank line if we print anything after this (aka more than one packet). */
- args->print_separator = TRUE;
+ /* Print the information in that tree. */
+ if (!proto_tree_print(args->print_args->print_dissections,
+ args->print_args->print_hex, &args->edt, NULL,
+ args->print_args->stream))
+ goto fail;
- /* Print a header line if we print any more packet summaries */
- if (args->print_args->print_col_headings)
- args->print_header_line = TRUE;
- }
+ /* Print a blank line if we print anything after this (aka more than one packet). */
+ args->print_separator = TRUE;
- if (args->print_args->print_hex) {
- if (args->print_args->print_summary || (args->print_args->print_dissections != print_dissections_none)) {
- if (!print_line(args->print_args->stream, 0, ""))
- goto fail;
+ /* Print a header line if we print any more packet summaries */
+ if (args->print_args->print_col_headings)
+ args->print_header_line = TRUE;
}
- /* Print the full packet data as hex. */
- if (!print_hex_data(args->print_args->stream, &args->edt, args->print_args->hexdump_options))
- goto fail;
- /* Print a blank line if we print anything after this (aka more than one packet). */
- args->print_separator = TRUE;
+ if (args->print_args->print_hex) {
+ if (args->print_args->print_summary || (args->print_args->print_dissections != print_dissections_none)) {
+ if (!print_line(args->print_args->stream, 0, ""))
+ goto fail;
+ }
+ /* Print the full packet data as hex. */
+ if (!print_hex_data(args->print_args->stream, &args->edt, args->print_args->hexdump_options))
+ goto fail;
- /* Print a header line if we print any more packet summaries */
- if (args->print_args->print_col_headings)
- args->print_header_line = TRUE;
- } /* if (args->print_args->print_dissections != print_dissections_none) */
+ /* Print a blank line if we print anything after this (aka more than one packet). */
+ args->print_separator = TRUE;
- epan_dissect_reset(&args->edt);
+ /* Print a header line if we print any more packet summaries */
+ if (args->print_args->print_col_headings)
+ args->print_header_line = TRUE;
+ } /* if (args->print_args->print_dissections != print_dissections_none) */
- /* do we want to have a formfeed between each packet from now on? */
- if (args->print_args->print_formfeed) {
- args->print_formfeed = TRUE;
- }
+ epan_dissect_reset(&args->edt);
- return TRUE;
+ /* do we want to have a formfeed between each packet from now on? */
+ if (args->print_args->print_formfeed) {
+ args->print_formfeed = TRUE;
+ }
+
+ return TRUE;
fail:
- epan_dissect_reset(&args->edt);
- return FALSE;
+ epan_dissect_reset(&args->edt);
+ return FALSE;
}
cf_print_status_t
cf_print_packets(capture_file *cf, print_args_t *print_args,
- gboolean show_progress_bar)
+ gboolean show_progress_bar)
{
- print_callback_args_t callback_args;
- gint data_width;
- char *cp;
- int i, cp_off, column_len, line_len;
- int num_visible_col = 0, last_visible_col = 0, visible_col_count;
- psp_return_t ret;
- GList *clp;
- fmt_data *cfmt;
- gboolean proto_tree_needed;
-
- callback_args.print_args = print_args;
- callback_args.print_header_line = print_args->print_col_headings;
- callback_args.header_line_buf = NULL;
- callback_args.header_line_buf_len = 256;
- callback_args.print_formfeed = FALSE;
- callback_args.print_separator = FALSE;
- callback_args.line_buf = NULL;
- callback_args.line_buf_len = 256;
- callback_args.col_widths = NULL;
- callback_args.num_visible_cols = 0;
- callback_args.visible_cols = NULL;
-
- if (!print_preamble(print_args->stream, cf->filename, get_ws_vcs_version_info())) {
- destroy_print_stream(print_args->stream);
- return CF_PRINT_WRITE_ERROR;
- }
-
- if (print_args->print_summary) {
- /* We're printing packet summaries. Allocate the header line buffer
- and get the column widths. */
- callback_args.header_line_buf = (char *)g_malloc(callback_args.header_line_buf_len + 1);
-
- /* Find the number of visible columns and the last visible column */
- for (i = 0; i < prefs.num_cols; i++) {
-
- clp = g_list_nth(prefs.col_list, i);
- if (clp == NULL) /* Sanity check, Invalid column requested */
- continue;
-
- cfmt = (fmt_data *) clp->data;
- if (cfmt->visible) {
- num_visible_col++;
- last_visible_col = i;
+ print_callback_args_t callback_args;
+ gint data_width;
+ char *cp;
+ int i, cp_off, column_len, line_len;
+ int num_visible_col = 0, last_visible_col = 0, visible_col_count;
+ psp_return_t ret;
+ GList *clp;
+ fmt_data *cfmt;
+ gboolean proto_tree_needed;
+
+ callback_args.print_args = print_args;
+ callback_args.print_header_line = print_args->print_col_headings;
+ callback_args.header_line_buf = NULL;
+ callback_args.header_line_buf_len = 256;
+ callback_args.print_formfeed = FALSE;
+ callback_args.print_separator = FALSE;
+ callback_args.line_buf = NULL;
+ callback_args.line_buf_len = 256;
+ callback_args.col_widths = NULL;
+ callback_args.num_visible_cols = 0;
+ callback_args.visible_cols = NULL;
+
+ if (!print_preamble(print_args->stream, cf->filename, get_ws_vcs_version_info())) {
+ destroy_print_stream(print_args->stream);
+ return CF_PRINT_WRITE_ERROR;
+ }
+
+ if (print_args->print_summary) {
+ /* We're printing packet summaries. Allocate the header line buffer
+ and get the column widths. */
+ callback_args.header_line_buf = (char *)g_malloc(callback_args.header_line_buf_len + 1);
+
+ /* Find the number of visible columns and the last visible column */
+ for (i = 0; i < prefs.num_cols; i++) {
+
+ clp = g_list_nth(prefs.col_list, i);
+ if (clp == NULL) /* Sanity check, Invalid column requested */
+ continue;
+
+ cfmt = (fmt_data *) clp->data;
+ if (cfmt->visible) {
+ num_visible_col++;
+ last_visible_col = i;
+ }
+ }
+
+ /* if num_visible_col is 0, we are done */
+ if (num_visible_col == 0) {
+ g_free(callback_args.header_line_buf);
+ return CF_PRINT_OK;
}
+
+ /* Find the widths for each of the columns - maximum of the
+ width of the title and the width of the data - and construct
+ a buffer with a line containing the column titles. */
+ callback_args.num_visible_cols = num_visible_col;
+ callback_args.col_widths = g_new(gint, num_visible_col);
+ callback_args.visible_cols = g_new(gint, num_visible_col);
+ cp = &callback_args.header_line_buf[0];
+ line_len = 0;
+ visible_col_count = 0;
+ for (i = 0; i < cf->cinfo.num_cols; i++) {
+
+ clp = g_list_nth(prefs.col_list, i);
+ if (clp == NULL) /* Sanity check, Invalid column requested */
+ continue;
+
+ cfmt = (fmt_data *) clp->data;
+ if (cfmt->visible == FALSE)
+ continue;
+
+ /* Save the order of visible columns */
+ callback_args.visible_cols[visible_col_count] = i;
+
+ /* Don't pad the last column. */
+ if (i == last_visible_col)
+ callback_args.col_widths[visible_col_count] = 0;
+ else {
+ callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.columns[i].col_title);
+ data_width = get_column_char_width(get_column_format(i));
+ if (data_width > callback_args.col_widths[visible_col_count])
+ callback_args.col_widths[visible_col_count] = data_width;
+ }
+
+ /* Find the length of the string for this column. */
+ column_len = (int) strlen(cf->cinfo.columns[i].col_title);
+ if (callback_args.col_widths[visible_col_count] > column_len)
+ column_len = callback_args.col_widths[visible_col_count];
+
+ /* Make sure there's room in the line buffer for the column; if not,
+ double its length. */
+ line_len += column_len + 1; /* "+1" for space */
+ if (line_len > callback_args.header_line_buf_len) {
+ cp_off = (int) (cp - callback_args.header_line_buf);
+ callback_args.header_line_buf_len = 2 * line_len;
+ callback_args.header_line_buf = (char *)g_realloc(callback_args.header_line_buf,
+ callback_args.header_line_buf_len + 1);
+ cp = callback_args.header_line_buf + cp_off;
+ }
+
+ /* Right-justify the packet number column. */
+/* if (cf->cinfo.col_fmt[i] == COL_NUMBER)
+ snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.columns[i].col_title);
+ else*/
+ snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.columns[i].col_title);
+ cp += column_len;
+ if (i != cf->cinfo.num_cols - 1)
+ *cp++ = ' ';
+
+ visible_col_count++;
+ }
+ *cp = '\0';
+
+ /* Now start out the main line buffer with the same length as the
+ header line buffer. */
+ callback_args.line_buf_len = callback_args.header_line_buf_len;
+ callback_args.line_buf = (char *)g_malloc(callback_args.line_buf_len + 1);
+ } /* if (print_summary) */
+
+ /* Create the protocol tree, and make it visible, if we're printing
+ the dissection or the hex data.
+ XXX - do we need it if we're just printing the hex data? */
+ proto_tree_needed =
+ callback_args.print_args->print_dissections != print_dissections_none ||
+ callback_args.print_args->print_hex ||
+ have_custom_cols(&cf->cinfo) || have_field_extractors();
+ epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
+
+ /* Iterate through the list of packets, printing the packets we were
+ told to print. */
+ ret = process_specified_records(cf, &print_args->range, "Printing",
+ "selected packets", TRUE, print_packet,
+ &callback_args, show_progress_bar);
+ epan_dissect_cleanup(&callback_args.edt);
+ g_free(callback_args.header_line_buf);
+ g_free(callback_args.line_buf);
+ g_free(callback_args.col_widths);
+ g_free(callback_args.visible_cols);
+
+ switch (ret) {
+
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ break;
+
+ case PSP_STOPPED:
+ /* Well, the user decided to abort the printing.
+
+ XXX - note that what got generated before they did that
+ will get printed if we're piping to a print program; we'd
+ have to write to a file and then hand that to the print
+ program to make it actually not print anything. */
+ break;
+
+ case PSP_FAILED:
+ /* Error while printing.
+
+ XXX - note that what got generated before they did that
+ will get printed if we're piping to a print program; we'd
+ have to write to a file and then hand that to the print
+ program to make it actually not print anything. */
+ destroy_print_stream(print_args->stream);
+ return CF_PRINT_WRITE_ERROR;
}
- /* if num_visible_col is 0, we are done */
- if (num_visible_col == 0) {
- g_free(callback_args.header_line_buf);
- return CF_PRINT_OK;
+ if (!print_finale(print_args->stream)) {
+ destroy_print_stream(print_args->stream);
+ return CF_PRINT_WRITE_ERROR;
}
- /* Find the widths for each of the columns - maximum of the
- width of the title and the width of the data - and construct
- a buffer with a line containing the column titles. */
- callback_args.num_visible_cols = num_visible_col;
- callback_args.col_widths = g_new(gint, num_visible_col);
- callback_args.visible_cols = g_new(gint, num_visible_col);
- cp = &callback_args.header_line_buf[0];
- line_len = 0;
- visible_col_count = 0;
- for (i = 0; i < cf->cinfo.num_cols; i++) {
+ if (!destroy_print_stream(print_args->stream))
+ return CF_PRINT_WRITE_ERROR;
- clp = g_list_nth(prefs.col_list, i);
- if (clp == NULL) /* Sanity check, Invalid column requested */
- continue;
-
- cfmt = (fmt_data *) clp->data;
- if (cfmt->visible == FALSE)
- continue;
-
- /* Save the order of visible columns */
- callback_args.visible_cols[visible_col_count] = i;
-
- /* Don't pad the last column. */
- if (i == last_visible_col)
- callback_args.col_widths[visible_col_count] = 0;
- else {
- callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.columns[i].col_title);
- data_width = get_column_char_width(get_column_format(i));
- if (data_width > callback_args.col_widths[visible_col_count])
- callback_args.col_widths[visible_col_count] = data_width;
- }
-
- /* Find the length of the string for this column. */
- column_len = (int) strlen(cf->cinfo.columns[i].col_title);
- if (callback_args.col_widths[visible_col_count] > column_len)
- column_len = callback_args.col_widths[visible_col_count];
-
- /* Make sure there's room in the line buffer for the column; if not,
- double its length. */
- line_len += column_len + 1; /* "+1" for space */
- if (line_len > callback_args.header_line_buf_len) {
- cp_off = (int) (cp - callback_args.header_line_buf);
- callback_args.header_line_buf_len = 2 * line_len;
- callback_args.header_line_buf = (char *)g_realloc(callback_args.header_line_buf,
- callback_args.header_line_buf_len + 1);
- cp = callback_args.header_line_buf + cp_off;
- }
-
- /* Right-justify the packet number column. */
-/* if (cf->cinfo.col_fmt[i] == COL_NUMBER)
- snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.columns[i].col_title);
- else*/
- snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.columns[i].col_title);
- cp += column_len;
- if (i != cf->cinfo.num_cols - 1)
- *cp++ = ' ';
-
- visible_col_count++;
- }
- *cp = '\0';
-
- /* Now start out the main line buffer with the same length as the
- header line buffer. */
- callback_args.line_buf_len = callback_args.header_line_buf_len;
- callback_args.line_buf = (char *)g_malloc(callback_args.line_buf_len + 1);
- } /* if (print_summary) */
-
- /* Create the protocol tree, and make it visible, if we're printing
- the dissection or the hex data.
- XXX - do we need it if we're just printing the hex data? */
- proto_tree_needed =
- callback_args.print_args->print_dissections != print_dissections_none ||
- callback_args.print_args->print_hex ||
- have_custom_cols(&cf->cinfo) || have_field_extractors();
- epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
-
- /* Iterate through the list of packets, printing the packets we were
- told to print. */
- ret = process_specified_records(cf, &print_args->range, "Printing",
- "selected packets", TRUE, print_packet,
- &callback_args, show_progress_bar);
- epan_dissect_cleanup(&callback_args.edt);
- g_free(callback_args.header_line_buf);
- g_free(callback_args.line_buf);
- g_free(callback_args.col_widths);
- g_free(callback_args.visible_cols);
-
- switch (ret) {
-
- case PSP_FINISHED:
- /* Completed successfully. */
- break;
-
- case PSP_STOPPED:
- /* Well, the user decided to abort the printing.
-
- XXX - note that what got generated before they did that
- will get printed if we're piping to a print program; we'd
- have to write to a file and then hand that to the print
- program to make it actually not print anything. */
- break;
-
- case PSP_FAILED:
- /* Error while printing.
-
- XXX - note that what got generated before they did that
- will get printed if we're piping to a print program; we'd
- have to write to a file and then hand that to the print
- program to make it actually not print anything. */
- destroy_print_stream(print_args->stream);
- return CF_PRINT_WRITE_ERROR;
- }
-
- if (!print_finale(print_args->stream)) {
- destroy_print_stream(print_args->stream);
- return CF_PRINT_WRITE_ERROR;
- }
-
- if (!destroy_print_stream(print_args->stream))
- return CF_PRINT_WRITE_ERROR;
-
- return CF_PRINT_OK;
+ return CF_PRINT_OK;
}
typedef struct {
- FILE *fh;
- epan_dissect_t edt;
- print_args_t *print_args;
- json_dumper jdumper;
+ FILE *fh;
+ epan_dissect_t edt;
+ print_args_t *print_args;
+ json_dumper jdumper;
} write_packet_callback_args_t;
static gboolean
write_pdml_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec,
- Buffer *buf, void *argsp)
+ Buffer *buf, void *argsp)
{
- write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
+ write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
- /* Create the protocol tree, but don't fill in the column information. */
- epan_dissect_run(&args->edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, NULL);
+ /* Create the protocol tree, but don't fill in the column information. */
+ epan_dissect_run(&args->edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, NULL);
- /* Write out the information in that tree. */
- write_pdml_proto_tree(NULL, NULL, PF_NONE, &args->edt, &cf->cinfo, args->fh, FALSE);
+ /* Write out the information in that tree. */
+ write_pdml_proto_tree(NULL, NULL, PF_NONE, &args->edt, &cf->cinfo, args->fh, FALSE);
- epan_dissect_reset(&args->edt);
+ epan_dissect_reset(&args->edt);
- return !ferror(args->fh);
+ return !ferror(args->fh);
}
cf_print_status_t
cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
{
- write_packet_callback_args_t callback_args;
- FILE *fh;
- psp_return_t ret;
-
- fh = ws_fopen(print_args->file, "w");
- if (fh == NULL)
- return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
+ write_packet_callback_args_t callback_args;
+ FILE *fh;
+ psp_return_t ret;
+
+ fh = ws_fopen(print_args->file, "w");
+ if (fh == NULL)
+ return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
+
+ write_pdml_preamble(fh, cf->filename);
+ if (ferror(fh)) {
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- write_pdml_preamble(fh, cf->filename);
- if (ferror(fh)) {
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ callback_args.fh = fh;
+ callback_args.print_args = print_args;
+ epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
- callback_args.fh = fh;
- callback_args.print_args = print_args;
- epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
+ /* Iterate through the list of packets, printing the packets we were
+ told to print. */
+ ret = process_specified_records(cf, &print_args->range, "Writing PDML",
+ "selected packets", TRUE,
+ write_pdml_packet, &callback_args, TRUE);
- /* Iterate through the list of packets, printing the packets we were
- told to print. */
- ret = process_specified_records(cf, &print_args->range, "Writing PDML",
- "selected packets", TRUE,
- write_pdml_packet, &callback_args, TRUE);
+ epan_dissect_cleanup(&callback_args.edt);
- epan_dissect_cleanup(&callback_args.edt);
+ switch (ret) {
- switch (ret) {
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ break;
- case PSP_FINISHED:
- /* Completed successfully. */
- break;
+ case PSP_STOPPED:
+ /* Well, the user decided to abort the printing. */
+ break;
- case PSP_STOPPED:
- /* Well, the user decided to abort the printing. */
- break;
+ case PSP_FAILED:
+ /* Error while printing. */
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- case PSP_FAILED:
- /* Error while printing. */
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ write_pdml_finale(fh);
+ if (ferror(fh)) {
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- write_pdml_finale(fh);
- if (ferror(fh)) {
+ /* XXX - check for an error */
fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
-
- /* XXX - check for an error */
- fclose(fh);
- return CF_PRINT_OK;
+ return CF_PRINT_OK;
}
static gboolean
write_psml_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec,
- Buffer *buf, void *argsp)
+ Buffer *buf, void *argsp)
{
- write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
+ write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
- /* Fill in the column information */
- col_custom_prime_edt(&args->edt, &cf->cinfo);
- epan_dissect_run(&args->edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, &cf->cinfo);
- epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
+ /* Fill in the column information */
+ col_custom_prime_edt(&args->edt, &cf->cinfo);
+ epan_dissect_run(&args->edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, &cf->cinfo);
+ epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
- /* Write out the column information. */
- write_psml_columns(&args->edt, args->fh, FALSE);
+ /* Write out the column information. */
+ write_psml_columns(&args->edt, args->fh, FALSE);
- epan_dissect_reset(&args->edt);
+ epan_dissect_reset(&args->edt);
- return !ferror(args->fh);
+ return !ferror(args->fh);
}
cf_print_status_t
cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
{
- write_packet_callback_args_t callback_args;
- FILE *fh;
- psp_return_t ret;
+ write_packet_callback_args_t callback_args;
+ FILE *fh;
+ psp_return_t ret;
- gboolean proto_tree_needed;
+ gboolean proto_tree_needed;
- fh = ws_fopen(print_args->file, "w");
- if (fh == NULL)
- return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
+ fh = ws_fopen(print_args->file, "w");
+ if (fh == NULL)
+ return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
- write_psml_preamble(&cf->cinfo, fh);
- if (ferror(fh)) {
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ write_psml_preamble(&cf->cinfo, fh);
+ if (ferror(fh)) {
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- callback_args.fh = fh;
- callback_args.print_args = print_args;
+ callback_args.fh = fh;
+ callback_args.print_args = print_args;
- /* Fill in the column information, only create the protocol tree
- if having custom columns or field extractors. */
- proto_tree_needed = have_custom_cols(&cf->cinfo) || have_field_extractors();
- epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
+ /* Fill in the column information, only create the protocol tree
+ if having custom columns or field extractors. */
+ proto_tree_needed = have_custom_cols(&cf->cinfo) || have_field_extractors();
+ epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
- /* Iterate through the list of packets, printing the packets we were
- told to print. */
- ret = process_specified_records(cf, &print_args->range, "Writing PSML",
- "selected packets", TRUE,
- write_psml_packet, &callback_args, TRUE);
+ /* Iterate through the list of packets, printing the packets we were
+ told to print. */
+ ret = process_specified_records(cf, &print_args->range, "Writing PSML",
+ "selected packets", TRUE,
+ write_psml_packet, &callback_args, TRUE);
- epan_dissect_cleanup(&callback_args.edt);
+ epan_dissect_cleanup(&callback_args.edt);
- switch (ret) {
+ switch (ret) {
- case PSP_FINISHED:
- /* Completed successfully. */
- break;
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ break;
- case PSP_STOPPED:
- /* Well, the user decided to abort the printing. */
- break;
+ case PSP_STOPPED:
+ /* Well, the user decided to abort the printing. */
+ break;
- case PSP_FAILED:
- /* Error while printing. */
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ case PSP_FAILED:
+ /* Error while printing. */
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- write_psml_finale(fh);
- if (ferror(fh)) {
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ write_psml_finale(fh);
+ if (ferror(fh)) {
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- /* XXX - check for an error */
- fclose(fh);
+ /* XXX - check for an error */
+ fclose(fh);
- return CF_PRINT_OK;
+ return CF_PRINT_OK;
}
static gboolean
write_csv_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec,
- Buffer *buf, void *argsp)
+ Buffer *buf, void *argsp)
{
- write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
+ write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
- /* Fill in the column information */
- col_custom_prime_edt(&args->edt, &cf->cinfo);
- epan_dissect_run(&args->edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, &cf->cinfo);
- epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
+ /* Fill in the column information */
+ col_custom_prime_edt(&args->edt, &cf->cinfo);
+ epan_dissect_run(&args->edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, &cf->cinfo);
+ epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
- /* Write out the column information. */
- write_csv_columns(&args->edt, args->fh);
+ /* Write out the column information. */
+ write_csv_columns(&args->edt, args->fh);
- epan_dissect_reset(&args->edt);
+ epan_dissect_reset(&args->edt);
- return !ferror(args->fh);
+ return !ferror(args->fh);
}
cf_print_status_t
cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
{
- write_packet_callback_args_t callback_args;
- gboolean proto_tree_needed;
- FILE *fh;
- psp_return_t ret;
-
- fh = ws_fopen(print_args->file, "w");
- if (fh == NULL)
- return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
+ write_packet_callback_args_t callback_args;
+ gboolean proto_tree_needed;
+ FILE *fh;
+ psp_return_t ret;
+
+ fh = ws_fopen(print_args->file, "w");
+ if (fh == NULL)
+ return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
+
+ write_csv_column_titles(&cf->cinfo, fh);
+ if (ferror(fh)) {
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- write_csv_column_titles(&cf->cinfo, fh);
- if (ferror(fh)) {
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ callback_args.fh = fh;
+ callback_args.print_args = print_args;
- callback_args.fh = fh;
- callback_args.print_args = print_args;
+ /* only create the protocol tree if having custom columns or field extractors. */
+ proto_tree_needed = have_custom_cols(&cf->cinfo) || have_field_extractors();
+ epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
- /* only create the protocol tree if having custom columns or field extractors. */
- proto_tree_needed = have_custom_cols(&cf->cinfo) || have_field_extractors();
- epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
+ /* Iterate through the list of packets, printing the packets we were
+ told to print. */
+ ret = process_specified_records(cf, &print_args->range, "Writing CSV",
+ "selected packets", TRUE,
+ write_csv_packet, &callback_args, TRUE);
- /* Iterate through the list of packets, printing the packets we were
- told to print. */
- ret = process_specified_records(cf, &print_args->range, "Writing CSV",
- "selected packets", TRUE,
- write_csv_packet, &callback_args, TRUE);
+ epan_dissect_cleanup(&callback_args.edt);
- epan_dissect_cleanup(&callback_args.edt);
+ switch (ret) {
- switch (ret) {
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ break;
- case PSP_FINISHED:
- /* Completed successfully. */
- break;
+ case PSP_STOPPED:
+ /* Well, the user decided to abort the printing. */
+ break;
- case PSP_STOPPED:
- /* Well, the user decided to abort the printing. */
- break;
+ case PSP_FAILED:
+ /* Error while printing. */
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- case PSP_FAILED:
- /* Error while printing. */
+ /* XXX - check for an error */
fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
-
- /* XXX - check for an error */
- fclose(fh);
- return CF_PRINT_OK;
+ return CF_PRINT_OK;
}
static gboolean
carrays_write_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec,
- Buffer *buf, void *argsp)
+ Buffer *buf, void *argsp)
{
- write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
+ write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
- epan_dissect_run(&args->edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, NULL);
- write_carrays_hex_data(fdata->num, args->fh, &args->edt);
- epan_dissect_reset(&args->edt);
+ epan_dissect_run(&args->edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, NULL);
+ write_carrays_hex_data(fdata->num, args->fh, &args->edt);
+ epan_dissect_reset(&args->edt);
- return !ferror(args->fh);
+ return !ferror(args->fh);
}
cf_print_status_t
cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
{
- write_packet_callback_args_t callback_args;
- FILE *fh;
- psp_return_t ret;
+ write_packet_callback_args_t callback_args;
+ FILE *fh;
+ psp_return_t ret;
- fh = ws_fopen(print_args->file, "w");
+ fh = ws_fopen(print_args->file, "w");
- if (fh == NULL)
- return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
+ if (fh == NULL)
+ return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
- if (ferror(fh)) {
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
-
- callback_args.fh = fh;
- callback_args.print_args = print_args;
- epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
-
- /* Iterate through the list of packets, printing the packets we were
- told to print. */
- ret = process_specified_records(cf, &print_args->range,
- "Writing C Arrays",
- "selected packets", TRUE,
- carrays_write_packet, &callback_args, TRUE);
-
- epan_dissect_cleanup(&callback_args.edt);
-
- switch (ret) {
- case PSP_FINISHED:
- /* Completed successfully. */
- break;
- case PSP_STOPPED:
- /* Well, the user decided to abort the printing. */
- break;
- case PSP_FAILED:
- /* Error while printing. */
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ if (ferror(fh)) {
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
+
+ callback_args.fh = fh;
+ callback_args.print_args = print_args;
+ epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
+
+ /* Iterate through the list of packets, printing the packets we were
+ told to print. */
+ ret = process_specified_records(cf, &print_args->range,
+ "Writing C Arrays",
+ "selected packets", TRUE,
+ carrays_write_packet, &callback_args, TRUE);
- fclose(fh);
- return CF_PRINT_OK;
+ epan_dissect_cleanup(&callback_args.edt);
+
+ switch (ret) {
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ break;
+ case PSP_STOPPED:
+ /* Well, the user decided to abort the printing. */
+ break;
+ case PSP_FAILED:
+ /* Error while printing. */
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
+
+ fclose(fh);
+ return CF_PRINT_OK;
}
static gboolean
write_json_packet(capture_file *cf, frame_data *fdata, wtap_rec *rec,
- Buffer *buf, void *argsp)
+ Buffer *buf, void *argsp)
{
- write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
+ write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
- /* Create the protocol tree, but don't fill in the column information. */
- epan_dissect_run(&args->edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, NULL);
+ /* Create the protocol tree, but don't fill in the column information. */
+ epan_dissect_run(&args->edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, NULL);
- /* Write out the information in that tree. */
- write_json_proto_tree(NULL, args->print_args->print_dissections,
- args->print_args->print_hex, NULL, PF_NONE,
- &args->edt, &cf->cinfo, proto_node_group_children_by_unique,
- &args->jdumper);
+ /* Write out the information in that tree. */
+ write_json_proto_tree(NULL, args->print_args->print_dissections,
+ args->print_args->print_hex, NULL, PF_NONE,
+ &args->edt, &cf->cinfo, proto_node_group_children_by_unique,
+ &args->jdumper);
- epan_dissect_reset(&args->edt);
+ epan_dissect_reset(&args->edt);
- return !ferror(args->fh);
+ return !ferror(args->fh);
}
cf_print_status_t
cf_write_json_packets(capture_file *cf, print_args_t *print_args)
{
- write_packet_callback_args_t callback_args;
- FILE *fh;
- psp_return_t ret;
+ write_packet_callback_args_t callback_args;
+ FILE *fh;
+ psp_return_t ret;
+
+ fh = ws_fopen(print_args->file, "w");
+ if (fh == NULL)
+ return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
+
+ callback_args.jdumper = write_json_preamble(fh);
+ if (ferror(fh)) {
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- fh = ws_fopen(print_args->file, "w");
- if (fh == NULL)
- return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
+ callback_args.fh = fh;
+ callback_args.print_args = print_args;
+ epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
- callback_args.jdumper = write_json_preamble(fh);
- if (ferror(fh)) {
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ /* Iterate through the list of packets, printing the packets we were
+ told to print. */
+ ret = process_specified_records(cf, &print_args->range, "Writing JSON",
+ "selected packets", TRUE,
+ write_json_packet, &callback_args, TRUE);
- callback_args.fh = fh;
- callback_args.print_args = print_args;
- epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
+ epan_dissect_cleanup(&callback_args.edt);
- /* Iterate through the list of packets, printing the packets we were
- told to print. */
- ret = process_specified_records(cf, &print_args->range, "Writing JSON",
- "selected packets", TRUE,
- write_json_packet, &callback_args, TRUE);
+ switch (ret) {
- epan_dissect_cleanup(&callback_args.edt);
-
- switch (ret) {
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ break;
- case PSP_FINISHED:
- /* Completed successfully. */
- break;
+ case PSP_STOPPED:
+ /* Well, the user decided to abort the printing. */
+ break;
- case PSP_STOPPED:
- /* Well, the user decided to abort the printing. */
- break;
+ case PSP_FAILED:
+ /* Error while printing. */
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- case PSP_FAILED:
- /* Error while printing. */
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
+ write_json_finale(&callback_args.jdumper);
+ if (ferror(fh)) {
+ fclose(fh);
+ return CF_PRINT_WRITE_ERROR;
+ }
- write_json_finale(&callback_args.jdumper);
- if (ferror(fh)) {
+ /* XXX - check for an error */
fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
- /* XXX - check for an error */
- fclose(fh);
-
- return CF_PRINT_OK;
+ return CF_PRINT_OK;
}
gboolean
cf_find_packet_protocol_tree(capture_file *cf, const char *string,
- search_direction dir)
+ search_direction dir)
{
- match_data mdata;
+ match_data mdata;
- mdata.string = string;
- mdata.string_len = strlen(string);
- return find_packet(cf, match_protocol_tree, &mdata, dir);
+ mdata.string = string;
+ mdata.string_len = strlen(string);
+ return find_packet(cf, match_protocol_tree, &mdata, dir);
}
gboolean
cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree, match_data *mdata)
{
- mdata->frame_matched = FALSE;
- mdata->string = convert_string_case(cf->sfilter, cf->case_type);
- mdata->string_len = strlen(mdata->string);
- mdata->cf = cf;
- /* Iterate through all the nodes looking for matching text */
- proto_tree_children_foreach(tree, match_subtree_text, mdata);
- return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
+ mdata->frame_matched = FALSE;
+ mdata->string = convert_string_case(cf->sfilter, cf->case_type);
+ mdata->string_len = strlen(mdata->string);
+ mdata->cf = cf;
+ /* Iterate through all the nodes looking for matching text */
+ proto_tree_children_foreach(tree, match_subtree_text, mdata);
+ return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
}
static match_result
match_protocol_tree(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- match_data *mdata = (match_data *)criterion;
- epan_dissect_t edt;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- /* Construct the protocol tree, including the displayed text */
- epan_dissect_init(&edt, cf->epan, TRUE, TRUE);
- /* We don't need the column information */
- epan_dissect_run(&edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, NULL);
-
- /* Iterate through all the nodes, seeing if they have text that matches. */
- mdata->cf = cf;
- mdata->frame_matched = FALSE;
- proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
- epan_dissect_cleanup(&edt);
- return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
+ match_data *mdata = (match_data *)criterion;
+ epan_dissect_t edt;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ /* Construct the protocol tree, including the displayed text */
+ epan_dissect_init(&edt, cf->epan, TRUE, TRUE);
+ /* We don't need the column information */
+ epan_dissect_run(&edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, NULL);
+
+ /* Iterate through all the nodes, seeing if they have text that matches. */
+ mdata->cf = cf;
+ mdata->frame_matched = FALSE;
+ proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
+ epan_dissect_cleanup(&edt);
+ return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
}
static void
match_subtree_text(proto_node *node, gpointer data)
{
- match_data *mdata = (match_data *) data;
- const gchar *string = mdata->string;
- size_t string_len = mdata->string_len;
- capture_file *cf = mdata->cf;
- field_info *fi = PNODE_FINFO(node);
- gchar label_str[ITEM_LABEL_LENGTH];
- gchar *label_ptr;
- size_t label_len;
- guint32 i;
- guint8 c_char;
- size_t c_match = 0;
-
- /* dissection with an invisible proto tree? */
- ws_assert(fi);
-
- if (mdata->frame_matched) {
- /* We already had a match; don't bother doing any more work. */
- return;
- }
-
- /* Don't match invisible entries. */
- if (proto_item_is_hidden(node))
- return;
-
- /* was a free format label produced? */
- if (fi->rep) {
- label_ptr = fi->rep->representation;
- } else {
- /* no, make a generic label */
- label_ptr = label_str;
- proto_item_fill_label(fi, label_str);
- }
-
- if (cf->regex) {
- if (g_regex_match(cf->regex, label_ptr, (GRegexMatchFlags) 0, NULL)) {
- mdata->frame_matched = TRUE;
- mdata->finfo = fi;
- return;
- }
- } else {
- /* Does that label match? */
- label_len = strlen(label_ptr);
- for (i = 0; i < label_len; i++) {
- c_char = label_ptr[i];
- if (cf->case_type)
- c_char = g_ascii_toupper(c_char);
- if (c_char == string[c_match]) {
- c_match++;
- if (c_match == string_len) {
- /* No need to look further; we have a match */
- mdata->frame_matched = TRUE;
- mdata->finfo = fi;
- return;
+ match_data *mdata = (match_data *) data;
+ const gchar *string = mdata->string;
+ size_t string_len = mdata->string_len;
+ capture_file *cf = mdata->cf;
+ field_info *fi = PNODE_FINFO(node);
+ gchar label_str[ITEM_LABEL_LENGTH];
+ gchar *label_ptr;
+ size_t label_len;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ /* dissection with an invisible proto tree? */
+ ws_assert(fi);
+
+ if (mdata->frame_matched) {
+ /* We already had a match; don't bother doing any more work. */
+ return;
+ }
+
+ /* Don't match invisible entries. */
+ if (proto_item_is_hidden(node))
+ return;
+
+ /* was a free format label produced? */
+ if (fi->rep) {
+ label_ptr = fi->rep->representation;
+ } else {
+ /* no, make a generic label */
+ label_ptr = label_str;
+ proto_item_fill_label(fi, label_str);
+ }
+
+ if (cf->regex) {
+ if (g_regex_match(cf->regex, label_ptr, (GRegexMatchFlags) 0, NULL)) {
+ mdata->frame_matched = TRUE;
+ mdata->finfo = fi;
+ return;
+ }
+ } else {
+ /* Does that label match? */
+ label_len = strlen(label_ptr);
+ for (i = 0; i < label_len; i++) {
+ c_char = label_ptr[i];
+ if (cf->case_type)
+ c_char = g_ascii_toupper(c_char);
+ if (c_char == string[c_match]) {
+ c_match++;
+ if (c_match == string_len) {
+ /* No need to look further; we have a match */
+ mdata->frame_matched = TRUE;
+ mdata->finfo = fi;
+ return;
+ }
+ } else
+ c_match = 0;
}
- } else
- c_match = 0;
}
- }
- /* Recurse into the subtree, if it exists */
- if (node->first_child != NULL)
- proto_tree_children_foreach(node, match_subtree_text, mdata);
+ /* Recurse into the subtree, if it exists */
+ if (node->first_child != NULL)
+ proto_tree_children_foreach(node, match_subtree_text, mdata);
}
gboolean
cf_find_packet_summary_line(capture_file *cf, const char *string,
- search_direction dir)
+ search_direction dir)
{
- match_data mdata;
+ match_data mdata;
- mdata.string = string;
- mdata.string_len = strlen(string);
- return find_packet(cf, match_summary_line, &mdata, dir);
+ mdata.string = string;
+ mdata.string_len = strlen(string);
+ return find_packet(cf, match_summary_line, &mdata, dir);
}
static match_result
match_summary_line(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- match_data *mdata = (match_data *)criterion;
- const gchar *string = mdata->string;
- size_t string_len = mdata->string_len;
- epan_dissect_t edt;
- const char *info_column;
- size_t info_column_len;
- match_result result = MR_NOTMATCHED;
- gint colx;
- guint32 i;
- guint8 c_char;
- size_t c_match = 0;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- /* Don't bother constructing the protocol tree */
- epan_dissect_init(&edt, cf->epan, FALSE, FALSE);
- /* Get the column information */
- epan_dissect_run(&edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, &cf->cinfo);
-
- /* Find the Info column */
- for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
- if (cf->cinfo.columns[colx].fmt_matx[COL_INFO]) {
- /* Found it. See if we match. */
- info_column = edt.pi.cinfo->columns[colx].col_data;
- info_column_len = strlen(info_column);
- if (cf->regex) {
- if (g_regex_match(cf->regex, info_column, (GRegexMatchFlags) 0, NULL)) {
- result = MR_MATCHED;
- break;
- }
- } else {
- for (i = 0; i < info_column_len; i++) {
- c_char = info_column[i];
- if (cf->case_type)
- c_char = g_ascii_toupper(c_char);
- if (c_char == string[c_match]) {
- c_match++;
- if (c_match == string_len) {
- result = MR_MATCHED;
- break;
+ match_data *mdata = (match_data *)criterion;
+ const gchar *string = mdata->string;
+ size_t string_len = mdata->string_len;
+ epan_dissect_t edt;
+ const char *info_column;
+ size_t info_column_len;
+ match_result result = MR_NOTMATCHED;
+ gint colx;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ /* Don't bother constructing the protocol tree */
+ epan_dissect_init(&edt, cf->epan, FALSE, FALSE);
+ /* Get the column information */
+ epan_dissect_run(&edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, &cf->cinfo);
+
+ /* Find the Info column */
+ for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
+ if (cf->cinfo.columns[colx].fmt_matx[COL_INFO]) {
+ /* Found it. See if we match. */
+ info_column = edt.pi.cinfo->columns[colx].col_data;
+ info_column_len = strlen(info_column);
+ if (cf->regex) {
+ if (g_regex_match(cf->regex, info_column, (GRegexMatchFlags) 0, NULL)) {
+ result = MR_MATCHED;
+ break;
+ }
+ } else {
+ for (i = 0; i < info_column_len; i++) {
+ c_char = info_column[i];
+ if (cf->case_type)
+ c_char = g_ascii_toupper(c_char);
+ if (c_char == string[c_match]) {
+ c_match++;
+ if (c_match == string_len) {
+ result = MR_MATCHED;
+ break;
+ }
+ } else
+ c_match = 0;
+ }
}
- } else
- c_match = 0;
+ break;
}
- }
- break;
}
- }
- epan_dissect_cleanup(&edt);
- return result;
+ epan_dissect_cleanup(&edt);
+ return result;
}
typedef struct {
@@ -3277,478 +3288,478 @@ typedef struct {
gboolean
cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
- search_direction dir)
+ search_direction dir)
{
- cbs_t info;
- guint8 needles[3];
- ws_mempbrk_pattern pattern;
-
- info.data = string;
- info.data_len = string_size;
-
- /* Regex, String or hex search? */
- if (cf->regex) {
- /* Regular Expression search */
- return find_packet(cf, match_regex, NULL, dir);
- } else if (cf->string) {
- /* String search - what type of string? */
- if (cf->case_type) {
- needles[0] = string[0];
- needles[1] = g_ascii_tolower(needles[0]);
- needles[2] = '\0';
- ws_mempbrk_compile(&pattern, needles);
- info.pattern = &pattern;
- switch (cf->scs_type) {
-
- case SCS_NARROW_AND_WIDE:
- return find_packet(cf, match_narrow_and_wide_case, &info, dir);
-
- case SCS_NARROW:
- return find_packet(cf, match_narrow_case, &info, dir);
-
- case SCS_WIDE:
- return find_packet(cf, match_wide_case, &info, dir);
-
- default:
- ws_assert_not_reached();
- return FALSE;
- }
+ cbs_t info;
+ guint8 needles[3];
+ ws_mempbrk_pattern pattern;
+
+ info.data = string;
+ info.data_len = string_size;
+
+ /* Regex, String or hex search? */
+ if (cf->regex) {
+ /* Regular Expression search */
+ return find_packet(cf, match_regex, NULL, dir);
+ } else if (cf->string) {
+ /* String search - what type of string? */
+ if (cf->case_type) {
+ needles[0] = string[0];
+ needles[1] = g_ascii_tolower(needles[0]);
+ needles[2] = '\0';
+ ws_mempbrk_compile(&pattern, needles);
+ info.pattern = &pattern;
+ switch (cf->scs_type) {
+
+ case SCS_NARROW_AND_WIDE:
+ return find_packet(cf, match_narrow_and_wide_case, &info, dir);
+
+ case SCS_NARROW:
+ return find_packet(cf, match_narrow_case, &info, dir);
+
+ case SCS_WIDE:
+ return find_packet(cf, match_wide_case, &info, dir);
+
+ default:
+ ws_assert_not_reached();
+ return FALSE;
+ }
- } else {
- switch (cf->scs_type) {
+ } else {
+ switch (cf->scs_type) {
- case SCS_NARROW_AND_WIDE:
- return find_packet(cf, match_narrow_and_wide, &info, dir);
+ case SCS_NARROW_AND_WIDE:
+ return find_packet(cf, match_narrow_and_wide, &info, dir);
- case SCS_NARROW:
- return find_packet(cf, match_narrow, &info, dir);
+ case SCS_NARROW:
+ return find_packet(cf, match_narrow, &info, dir);
- case SCS_WIDE:
- return find_packet(cf, match_wide, &info, dir);
+ case SCS_WIDE:
+ return find_packet(cf, match_wide, &info, dir);
- default:
- ws_assert_not_reached();
- return FALSE;
- }
- }
- } else
- return find_packet(cf, match_binary, &info, dir);
+ default:
+ ws_assert_not_reached();
+ return FALSE;
+ }
+ }
+ } else
+ return find_packet(cf, match_binary, &info, dir);
}
static match_result
match_narrow_and_wide(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- cbs_t *info = (cbs_t *)criterion;
- const guint8 *ascii_text = info->data;
- size_t textlen = info->data_len;
- match_result result;
- guint32 buf_len;
- guint8 *pd, *buf_start, *buf_end;
- guint32 i;
- guint8 c_char;
- size_t c_match = 0;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- result = MR_NOTMATCHED;
- buf_len = fdata->cap_len;
- buf_start = ws_buffer_start_ptr(buf);
- buf_end = buf_start + buf_len;
- for (pd = buf_start; pd < buf_end; pd++) {
- pd = (guint8 *)memchr(pd, ascii_text[0], buf_end - pd);
- if (pd == NULL) break;
- /* Try narrow match at this start location */
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- c_char = pd[i];
- if (c_char == ascii_text[c_match]) {
- c_match++;
- if (c_match == textlen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+ cbs_t *info = (cbs_t *)criterion;
+ const guint8 *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ match_result result;
+ guint32 buf_len;
+ guint8 *pd, *buf_start, *buf_end;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ result = MR_NOTMATCHED;
+ buf_len = fdata->cap_len;
+ buf_start = ws_buffer_start_ptr(buf);
+ buf_end = buf_start + buf_len;
+ for (pd = buf_start; pd < buf_end; pd++) {
+ pd = (guint8 *)memchr(pd, ascii_text[0], buf_end - pd);
+ if (pd == NULL) break;
+ /* Try narrow match at this start location */
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ c_char = pd[i];
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ } else {
+ break;
+ }
}
- } else {
- break;
- }
- }
-
- /* Now try wide match at the same start location. */
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- c_char = pd[i];
- if (c_char == ascii_text[c_match]) {
- c_match++;
- if (c_match == textlen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+
+ /* Now try wide match at the same start location. */
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ c_char = pd[i];
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ i++;
+ if (pd + i >= buf_end || pd[i] != '\0') break;
+ } else {
+ break;
+ }
}
- i++;
- if (pd + i >= buf_end || pd[i] != '\0') break;
- } else {
- break;
- }
}
- }
done:
- return result;
+ return result;
}
/* Case insensitive match */
static match_result
match_narrow_and_wide_case(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- cbs_t *info = (cbs_t *)criterion;
- const guint8 *ascii_text = info->data;
- size_t textlen = info->data_len;
- ws_mempbrk_pattern *pattern = info->pattern;
- match_result result;
- guint32 buf_len;
- guint8 *pd, *buf_start, *buf_end;
- guint32 i;
- guint8 c_char;
- size_t c_match = 0;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- ws_assert(pattern != NULL);
-
- result = MR_NOTMATCHED;
- buf_len = fdata->cap_len;
- buf_start = ws_buffer_start_ptr(buf);
- buf_end = buf_start + buf_len;
- for (pd = buf_start; pd < buf_end; pd++) {
- pd = (guint8 *)ws_mempbrk_exec(pd, buf_end - pd, pattern, &c_char);
- if (pd == NULL) break;
- /* Try narrow match at this start location */
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- c_char = g_ascii_toupper(pd[i]);
- if (c_char == ascii_text[c_match]) {
- c_match++;
- if (c_match == textlen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+ cbs_t *info = (cbs_t *)criterion;
+ const guint8 *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ ws_mempbrk_pattern *pattern = info->pattern;
+ match_result result;
+ guint32 buf_len;
+ guint8 *pd, *buf_start, *buf_end;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ ws_assert(pattern != NULL);
+
+ result = MR_NOTMATCHED;
+ buf_len = fdata->cap_len;
+ buf_start = ws_buffer_start_ptr(buf);
+ buf_end = buf_start + buf_len;
+ for (pd = buf_start; pd < buf_end; pd++) {
+ pd = (guint8 *)ws_mempbrk_exec(pd, buf_end - pd, pattern, &c_char);
+ if (pd == NULL) break;
+ /* Try narrow match at this start location */
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ c_char = g_ascii_toupper(pd[i]);
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ } else {
+ break;
+ }
}
- } else {
- break;
- }
- }
-
- /* Now try wide match at the same start location. */
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- c_char = g_ascii_toupper(pd[i]);
- if (c_char == ascii_text[c_match]) {
- c_match++;
- if (c_match == textlen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+
+ /* Now try wide match at the same start location. */
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ c_char = g_ascii_toupper(pd[i]);
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ i++;
+ if (pd + i >= buf_end || pd[i] != '\0') break;
+ } else {
+ break;
+ }
}
- i++;
- if (pd + i >= buf_end || pd[i] != '\0') break;
- } else {
- break;
- }
}
- }
done:
- return result;
+ return result;
}
static match_result
match_narrow(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- cbs_t *info = (cbs_t *)criterion;
- const guint8 *ascii_text = info->data;
- size_t textlen = info->data_len;
- match_result result;
- guint32 buf_len;
- guint8 *pd, *buf_start, *buf_end;
- guint32 i;
- guint8 c_char;
- size_t c_match = 0;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- result = MR_NOTMATCHED;
- buf_len = fdata->cap_len;
- buf_start = ws_buffer_start_ptr(buf);
- buf_end = buf_start + buf_len;
- for (pd = buf_start; pd < buf_end; pd++) {
- pd = (guint8 *)memchr(pd, ascii_text[0], buf_end - pd);
- if (pd == NULL) break;
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- c_char = pd[i];
- if (c_char == ascii_text[c_match]) {
- c_match++;
- if (c_match == textlen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+ cbs_t *info = (cbs_t *)criterion;
+ const guint8 *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ match_result result;
+ guint32 buf_len;
+ guint8 *pd, *buf_start, *buf_end;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ result = MR_NOTMATCHED;
+ buf_len = fdata->cap_len;
+ buf_start = ws_buffer_start_ptr(buf);
+ buf_end = buf_start + buf_len;
+ for (pd = buf_start; pd < buf_end; pd++) {
+ pd = (guint8 *)memchr(pd, ascii_text[0], buf_end - pd);
+ if (pd == NULL) break;
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ c_char = pd[i];
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ } else {
+ break;
+ }
}
- } else {
- break;
- }
}
- }
done:
- return result;
+ return result;
}
/* Case insensitive match */
static match_result
match_narrow_case(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- cbs_t *info = (cbs_t *)criterion;
- const guint8 *ascii_text = info->data;
- size_t textlen = info->data_len;
- ws_mempbrk_pattern *pattern = info->pattern;
- match_result result;
- guint32 buf_len;
- guint8 *pd, *buf_start, *buf_end;
- guint32 i;
- guint8 c_char;
- size_t c_match = 0;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- ws_assert(pattern != NULL);
-
- result = MR_NOTMATCHED;
- buf_len = fdata->cap_len;
- buf_start = ws_buffer_start_ptr(buf);
- buf_end = buf_start + buf_len;
- for (pd = buf_start; pd < buf_end; pd++) {
- pd = (guint8 *)ws_mempbrk_exec(pd, buf_end - pd, pattern, &c_char);
- if (pd == NULL) break;
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- c_char = g_ascii_toupper(pd[i]);
- if (c_char == ascii_text[c_match]) {
- c_match++;
- if (c_match == textlen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+ cbs_t *info = (cbs_t *)criterion;
+ const guint8 *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ ws_mempbrk_pattern *pattern = info->pattern;
+ match_result result;
+ guint32 buf_len;
+ guint8 *pd, *buf_start, *buf_end;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ ws_assert(pattern != NULL);
+
+ result = MR_NOTMATCHED;
+ buf_len = fdata->cap_len;
+ buf_start = ws_buffer_start_ptr(buf);
+ buf_end = buf_start + buf_len;
+ for (pd = buf_start; pd < buf_end; pd++) {
+ pd = (guint8 *)ws_mempbrk_exec(pd, buf_end - pd, pattern, &c_char);
+ if (pd == NULL) break;
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ c_char = g_ascii_toupper(pd[i]);
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ } else {
+ break;
+ }
}
- } else {
- break;
- }
}
- }
done:
- return result;
+ return result;
}
static match_result
match_wide(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- cbs_t *info = (cbs_t *)criterion;
- const guint8 *ascii_text = info->data;
- size_t textlen = info->data_len;
- match_result result;
- guint32 buf_len;
- guint8 *pd, *buf_start, *buf_end;
- guint32 i;
- guint8 c_char;
- size_t c_match = 0;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- result = MR_NOTMATCHED;
- buf_len = fdata->cap_len;
- buf_start = ws_buffer_start_ptr(buf);
- buf_end = buf_start + buf_len;
- for (pd = buf_start; pd < buf_end; pd++) {
- pd = (guint8 *)memchr(pd, ascii_text[0], buf_end - pd);
- if (pd == NULL) break;
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- c_char = pd[i];
- if (c_char == ascii_text[c_match]) {
- c_match++;
- if (c_match == textlen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+ cbs_t *info = (cbs_t *)criterion;
+ const guint8 *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ match_result result;
+ guint32 buf_len;
+ guint8 *pd, *buf_start, *buf_end;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ result = MR_NOTMATCHED;
+ buf_len = fdata->cap_len;
+ buf_start = ws_buffer_start_ptr(buf);
+ buf_end = buf_start + buf_len;
+ for (pd = buf_start; pd < buf_end; pd++) {
+ pd = (guint8 *)memchr(pd, ascii_text[0], buf_end - pd);
+ if (pd == NULL) break;
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ c_char = pd[i];
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ i++;
+ if (pd + i >= buf_end || pd[i] != '\0') break;
+ } else {
+ break;
+ }
}
- i++;
- if (pd + i >= buf_end || pd[i] != '\0') break;
- } else {
- break;
- }
}
- }
done:
- return result;
+ return result;
}
/* Case insensitive match */
static match_result
match_wide_case(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- cbs_t *info = (cbs_t *)criterion;
- const guint8 *ascii_text = info->data;
- size_t textlen = info->data_len;
- ws_mempbrk_pattern *pattern = info->pattern;
- match_result result;
- guint32 buf_len;
- guint8 *pd, *buf_start, *buf_end;
- guint32 i;
- guint8 c_char;
- size_t c_match = 0;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- ws_assert(pattern != NULL);
-
- result = MR_NOTMATCHED;
- buf_len = fdata->cap_len;
- buf_start = ws_buffer_start_ptr(buf);
- buf_end = buf_start + buf_len;
- for (pd = buf_start; pd < buf_end; pd++) {
- pd = (guint8 *)ws_mempbrk_exec(pd, buf_end - pd, pattern, &c_char);
- if (pd == NULL) break;
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- c_char = g_ascii_toupper(pd[i]);
- if (c_char == ascii_text[c_match]) {
- c_match++;
- if (c_match == textlen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+ cbs_t *info = (cbs_t *)criterion;
+ const guint8 *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ ws_mempbrk_pattern *pattern = info->pattern;
+ match_result result;
+ guint32 buf_len;
+ guint8 *pd, *buf_start, *buf_end;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ ws_assert(pattern != NULL);
+
+ result = MR_NOTMATCHED;
+ buf_len = fdata->cap_len;
+ buf_start = ws_buffer_start_ptr(buf);
+ buf_end = buf_start + buf_len;
+ for (pd = buf_start; pd < buf_end; pd++) {
+ pd = (guint8 *)ws_mempbrk_exec(pd, buf_end - pd, pattern, &c_char);
+ if (pd == NULL) break;
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ c_char = g_ascii_toupper(pd[i]);
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ i++;
+ if (pd + i >= buf_end || pd[i] != '\0') break;
+ } else {
+ break;
+ }
}
- i++;
- if (pd + i >= buf_end || pd[i] != '\0') break;
- } else {
- break;
- }
}
- }
done:
- return result;
+ return result;
}
static match_result
match_binary(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- cbs_t *info = (cbs_t *)criterion;
- const guint8 *binary_data = info->data;
- size_t datalen = info->data_len;
- match_result result;
- guint32 buf_len;
- guint8 *pd, *buf_start, *buf_end;
- guint32 i;
- size_t c_match = 0;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- result = MR_NOTMATCHED;
- buf_len = fdata->cap_len;
- buf_start = ws_buffer_start_ptr(buf);
- buf_end = buf_start + buf_len;
- /* Not clear if using memcmp() is faster. memmem() on systems that
- * have it should be faster, though.
- */
- for (pd = buf_start; pd < buf_end; pd++) {
- pd = (guint8 *)memchr(pd, binary_data[0], buf_end - pd);
- if (pd == NULL) break;
- c_match = 0;
- for (i = 0; pd + i < buf_end; i++) {
- if (pd[i] == binary_data[c_match]) {
- c_match++;
- if (c_match == datalen) {
- result = MR_MATCHED;
- cf->search_pos = i + (guint32)(pd - buf_start);
- /* Save the position of the last character
- for highlighting the field. */
- cf->search_len = i + 1;
- goto done;
+ cbs_t *info = (cbs_t *)criterion;
+ const guint8 *binary_data = info->data;
+ size_t datalen = info->data_len;
+ match_result result;
+ guint32 buf_len;
+ guint8 *pd, *buf_start, *buf_end;
+ guint32 i;
+ size_t c_match = 0;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ result = MR_NOTMATCHED;
+ buf_len = fdata->cap_len;
+ buf_start = ws_buffer_start_ptr(buf);
+ buf_end = buf_start + buf_len;
+ /* Not clear if using memcmp() is faster. memmem() on systems that
+ * have it should be faster, though.
+ */
+ for (pd = buf_start; pd < buf_end; pd++) {
+ pd = (guint8 *)memchr(pd, binary_data[0], buf_end - pd);
+ if (pd == NULL) break;
+ c_match = 0;
+ for (i = 0; pd + i < buf_end; i++) {
+ if (pd[i] == binary_data[c_match]) {
+ c_match++;
+ if (c_match == datalen) {
+ result = MR_MATCHED;
+ cf->search_pos = i + (guint32)(pd - buf_start);
+ /* Save the position of the last character
+ for highlighting the field. */
+ cf->search_len = i + 1;
+ goto done;
+ }
+ } else {
+ break;
+ }
}
- } else {
- break;
- }
}
- }
done:
- return result;
+ return result;
}
static match_result
match_regex(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion _U_)
+ wtap_rec *rec, Buffer *buf, void *criterion _U_)
{
match_result result = MR_NOTMATCHED;
GMatchInfo *match_info = NULL;
@@ -3760,7 +3771,7 @@ match_regex(capture_file *cf, frame_data *fdata,
}
if (g_regex_match_full(cf->regex, (const gchar *)ws_buffer_start_ptr(buf), fdata->cap_len,
- 0, (GRegexMatchFlags) 0, &match_info, NULL))
+ 0, (GRegexMatchFlags) 0, &match_info, NULL))
{
gint start_pos = 0, end_pos = 0;
g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos);
@@ -3773,296 +3784,296 @@ match_regex(capture_file *cf, frame_data *fdata,
gboolean
cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
- search_direction dir)
+ search_direction dir)
{
- return find_packet(cf, match_dfilter, sfcode, dir);
+ return find_packet(cf, match_dfilter, sfcode, dir);
}
gboolean
cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
- search_direction dir)
+ search_direction dir)
{
- dfilter_t *sfcode;
- gboolean result;
-
- if (!dfilter_compile(filter, &sfcode, NULL)) {
- /*
- * XXX - this shouldn't happen, as the filter string is machine
- * generated
- */
- return FALSE;
- }
- if (sfcode == NULL) {
- /*
- * XXX - this shouldn't happen, as the filter string is machine
- * generated.
- */
- return FALSE;
- }
- result = find_packet(cf, match_dfilter, sfcode, dir);
- dfilter_free(sfcode);
- return result;
+ dfilter_t *sfcode;
+ gboolean result;
+
+ if (!dfilter_compile(filter, &sfcode, NULL)) {
+ /*
+ * XXX - this shouldn't happen, as the filter string is machine
+ * generated
+ */
+ return FALSE;
+ }
+ if (sfcode == NULL) {
+ /*
+ * XXX - this shouldn't happen, as the filter string is machine
+ * generated.
+ */
+ return FALSE;
+ }
+ result = find_packet(cf, match_dfilter, sfcode, dir);
+ dfilter_free(sfcode);
+ return result;
}
static match_result
match_dfilter(capture_file *cf, frame_data *fdata,
- wtap_rec *rec, Buffer *buf, void *criterion)
+ wtap_rec *rec, Buffer *buf, void *criterion)
{
- dfilter_t *sfcode = (dfilter_t *)criterion;
- epan_dissect_t edt;
- match_result result;
-
- /* Load the frame's data. */
- if (!cf_read_record(cf, fdata, rec, buf)) {
- /* Attempt to get the packet failed. */
- return MR_ERROR;
- }
-
- epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
- epan_dissect_prime_with_dfilter(&edt, sfcode);
- epan_dissect_run(&edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, NULL);
- result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
- epan_dissect_cleanup(&edt);
- return result;
+ dfilter_t *sfcode = (dfilter_t *)criterion;
+ epan_dissect_t edt;
+ match_result result;
+
+ /* Load the frame's data. */
+ if (!cf_read_record(cf, fdata, rec, buf)) {
+ /* Attempt to get the packet failed. */
+ return MR_ERROR;
+ }
+
+ epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
+ epan_dissect_prime_with_dfilter(&edt, sfcode);
+ epan_dissect_run(&edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, NULL);
+ result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
+ epan_dissect_cleanup(&edt);
+ return result;
}
gboolean
cf_find_packet_marked(capture_file *cf, search_direction dir)
{
- return find_packet(cf, match_marked, NULL, dir);
+ return find_packet(cf, match_marked, NULL, dir);
}
static match_result
match_marked(capture_file *cf _U_, frame_data *fdata, wtap_rec *rec _U_,
- Buffer *buf _U_, void *criterion _U_)
+ Buffer *buf _U_, void *criterion _U_)
{
- return fdata->marked ? MR_MATCHED : MR_NOTMATCHED;
+ return fdata->marked ? MR_MATCHED : MR_NOTMATCHED;
}
gboolean
cf_find_packet_time_reference(capture_file *cf, search_direction dir)
{
- return find_packet(cf, match_time_reference, NULL, dir);
+ return find_packet(cf, match_time_reference, NULL, dir);
}
static match_result
match_time_reference(capture_file *cf _U_, frame_data *fdata, wtap_rec *rec _U_,
- Buffer *buf _U_, void *criterion _U_)
+ Buffer *buf _U_, void *criterion _U_)
{
- return fdata->ref_time ? MR_MATCHED : MR_NOTMATCHED;
+ return fdata->ref_time ? MR_MATCHED : MR_NOTMATCHED;
}
static gboolean
find_packet(capture_file *cf, ws_match_function match_function,
- void *criterion, search_direction dir)
+ void *criterion, search_direction dir)
{
- frame_data *start_fd;
- guint32 framenum;
- guint32 prev_framenum;
- frame_data *fdata;
- wtap_rec rec;
- Buffer buf;
- frame_data *new_fd = NULL;
- progdlg_t *progbar = NULL;
- GTimer *prog_timer = g_timer_new();
- int count;
- gboolean succeeded;
- float progbar_val;
- gchar status_str[100];
- match_result result;
-
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
-
- start_fd = cf->current_frame;
- if (start_fd != NULL) {
- prev_framenum = start_fd->num;
- } else {
- prev_framenum = 0; /* No start packet selected. */
- }
-
- /* Iterate through the list of packets, starting at the packet we've
- picked, calling a routine to run the filter on the packet, see if
- it matches, and stop if so. */
- count = 0;
- framenum = prev_framenum;
-
- g_timer_start(prog_timer);
- /* Progress so far. */
- progbar_val = 0.0f;
-
- cf->stop_flag = FALSE;
-
- for (;;) {
- /* Create the progress bar if necessary.
- We check on every iteration of the loop, so that it takes no
- longer than the standard time to create it (otherwise, for a
- large file, we might take considerably longer than that standard
- time in order to get to the next progress bar step). */
- if (progbar == NULL)
- progbar = delayed_create_progress_dlg(cf->window, NULL, NULL,
- FALSE, &cf->stop_flag, progbar_val);
+ frame_data *start_fd;
+ guint32 framenum;
+ guint32 prev_framenum;
+ frame_data *fdata;
+ wtap_rec rec;
+ Buffer buf;
+ frame_data *new_fd = NULL;
+ progdlg_t *progbar = NULL;
+ GTimer *prog_timer = g_timer_new();
+ int count;
+ gboolean succeeded;
+ float progbar_val;
+ gchar status_str[100];
+ match_result result;
- /*
- * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
- * has elapsed. Calling update_progress_dlg and packets_bar_update will
- * likely trigger UI paint events, which might take a while depending on
- * the platform and display. Reset our timer *after* painting.
- */
- if (g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
- /* let's not divide by zero. I should never be started
- * with count == 0, so let's assert that
- */
- ws_assert(cf->count > 0);
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
- progbar_val = (gfloat) count / cf->count;
+ start_fd = cf->current_frame;
+ if (start_fd != NULL) {
+ prev_framenum = start_fd->num;
+ } else {
+ prev_framenum = 0; /* No start packet selected. */
+ }
- snprintf(status_str, sizeof(status_str),
- "%4u of %u packets", count, cf->count);
- update_progress_dlg(progbar, progbar_val, status_str);
+ /* Iterate through the list of packets, starting at the packet we've
+ picked, calling a routine to run the filter on the packet, see if
+ it matches, and stop if so. */
+ count = 0;
+ framenum = prev_framenum;
- g_timer_start(prog_timer);
- }
+ g_timer_start(prog_timer);
+ /* Progress so far. */
+ progbar_val = 0.0f;
- if (cf->stop_flag) {
- /* Well, the user decided to abort the search. Go back to the
- frame where we started. */
- new_fd = start_fd;
- break;
- }
+ cf->stop_flag = FALSE;
+
+ for (;;) {
+ /* Create the progress bar if necessary.
+ We check on every iteration of the loop, so that it takes no
+ longer than the standard time to create it (otherwise, for a
+ large file, we might take considerably longer than that standard
+ time in order to get to the next progress bar step). */
+ if (progbar == NULL)
+ progbar = delayed_create_progress_dlg(cf->window, NULL, NULL,
+ FALSE, &cf->stop_flag, progbar_val);
- /* Go past the current frame. */
- if (dir == SD_BACKWARD) {
- /* Go on to the previous frame. */
- if (framenum <= 1) {
/*
- * XXX - other apps have a bit more of a detailed message
- * for this, and instead of offering "OK" and "Cancel",
- * they offer things such as "Continue" and "Cancel";
- * we need an API for popping up alert boxes with
- * {Verb} and "Cancel".
+ * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
+ * has elapsed. Calling update_progress_dlg and packets_bar_update will
+ * likely trigger UI paint events, which might take a while depending on
+ * the platform and display. Reset our timer *after* painting.
*/
+ if (g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
+ /* let's not divide by zero. I should never be started
+ * with count == 0, so let's assert that
+ */
+ ws_assert(cf->count > 0);
- if (prefs.gui_find_wrap) {
- statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
- framenum = cf->count; /* wrap around */
- } else {
- statusbar_push_temporary_msg("Search reached the beginning.");
- framenum = prev_framenum; /* stay on previous packet */
+ progbar_val = (gfloat) count / cf->count;
+
+ snprintf(status_str, sizeof(status_str),
+ "%4u of %u packets", count, cf->count);
+ update_progress_dlg(progbar, progbar_val, status_str);
+
+ g_timer_start(prog_timer);
}
- } else
- framenum--;
- } else {
- /* Go on to the next frame. */
- if (framenum == cf->count) {
- if (prefs.gui_find_wrap) {
- statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
- framenum = 1; /* wrap around */
+
+ if (cf->stop_flag) {
+ /* Well, the user decided to abort the search. Go back to the
+ frame where we started. */
+ new_fd = start_fd;
+ break;
+ }
+
+ /* Go past the current frame. */
+ if (dir == SD_BACKWARD) {
+ /* Go on to the previous frame. */
+ if (framenum <= 1) {
+ /*
+ * XXX - other apps have a bit more of a detailed message
+ * for this, and instead of offering "OK" and "Cancel",
+ * they offer things such as "Continue" and "Cancel";
+ * we need an API for popping up alert boxes with
+ * {Verb} and "Cancel".
+ */
+
+ if (prefs.gui_find_wrap) {
+ statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
+ framenum = cf->count; /* wrap around */
+ } else {
+ statusbar_push_temporary_msg("Search reached the beginning.");
+ framenum = prev_framenum; /* stay on previous packet */
+ }
+ } else
+ framenum--;
} else {
- statusbar_push_temporary_msg("Search reached the end.");
- framenum = prev_framenum; /* stay on previous packet */
+ /* Go on to the next frame. */
+ if (framenum == cf->count) {
+ if (prefs.gui_find_wrap) {
+ statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
+ framenum = 1; /* wrap around */
+ } else {
+ statusbar_push_temporary_msg("Search reached the end.");
+ framenum = prev_framenum; /* stay on previous packet */
+ }
+ } else
+ framenum++;
+ }
+
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+ count++;
+
+ /* Is this packet in the display? */
+ if (fdata && fdata->passed_dfilter) {
+ /* Yes. Does it match the search criterion? */
+ result = (*match_function)(cf, fdata, &rec, &buf, criterion);
+ if (result == MR_ERROR) {
+ /* Error; our caller has reported the error. Go back to the frame
+ where we started. */
+ new_fd = start_fd;
+ break;
+ } else if (result == MR_MATCHED) {
+ /* Yes. Go to the new frame. */
+ new_fd = fdata;
+ break;
+ }
+ wtap_rec_reset(&rec);
+ }
+
+ if (fdata == start_fd) {
+ /* We're back to the frame we were on originally, and that frame
+ doesn't match the search filter. The search failed. */
+ break;
}
- } else
- framenum++;
}
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
- count++;
-
- /* Is this packet in the display? */
- if (fdata && fdata->passed_dfilter) {
- /* Yes. Does it match the search criterion? */
- result = (*match_function)(cf, fdata, &rec, &buf, criterion);
- if (result == MR_ERROR) {
- /* Error; our caller has reported the error. Go back to the frame
- where we started. */
- new_fd = start_fd;
- break;
- } else if (result == MR_MATCHED) {
- /* Yes. Go to the new frame. */
- new_fd = fdata;
- break;
- }
- wtap_rec_reset(&rec);
- }
-
- if (fdata == start_fd) {
- /* We're back to the frame we were on originally, and that frame
- doesn't match the search filter. The search failed. */
- break;
- }
- }
-
- /* We're done scanning the packets; destroy the progress bar if it
- was created. */
- if (progbar != NULL)
- destroy_progress_dlg(progbar);
- g_timer_destroy(prog_timer);
-
- if (new_fd != NULL) {
- /* We found a frame that's displayed and that matches.
- Try to find and select the packet summary list row for that frame. */
- gboolean found_row;
-
- cf->search_in_progress = TRUE;
- found_row = packet_list_select_row_from_data(new_fd);
- cf->search_in_progress = FALSE;
- cf->search_pos = 0; /* Reset the position */
- cf->search_len = 0; /* Reset length */
- if (!found_row) {
- /* We didn't find a row corresponding to this frame.
- This means that the frame isn't being displayed currently,
- so we can't select it. */
- simple_message_box(ESD_TYPE_INFO, NULL,
- "The capture file is probably not fully dissected.",
- "End of capture exceeded.");
- succeeded = FALSE; /* The search succeeded but we didn't find the row */
+ /* We're done scanning the packets; destroy the progress bar if it
+ was created. */
+ if (progbar != NULL)
+ destroy_progress_dlg(progbar);
+ g_timer_destroy(prog_timer);
+
+ if (new_fd != NULL) {
+ /* We found a frame that's displayed and that matches.
+ Try to find and select the packet summary list row for that frame. */
+ gboolean found_row;
+
+ cf->search_in_progress = TRUE;
+ found_row = packet_list_select_row_from_data(new_fd);
+ cf->search_in_progress = FALSE;
+ cf->search_pos = 0; /* Reset the position */
+ cf->search_len = 0; /* Reset length */
+ if (!found_row) {
+ /* We didn't find a row corresponding to this frame.
+ This means that the frame isn't being displayed currently,
+ so we can't select it. */
+ simple_message_box(ESD_TYPE_INFO, NULL,
+ "The capture file is probably not fully dissected.",
+ "End of capture exceeded.");
+ succeeded = FALSE; /* The search succeeded but we didn't find the row */
+ } else
+ succeeded = TRUE; /* The search succeeded and we found the row */
} else
- succeeded = TRUE; /* The search succeeded and we found the row */
- } else
- succeeded = FALSE; /* The search failed */
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
- return succeeded;
+ succeeded = FALSE; /* The search failed */
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+ return succeeded;
}
gboolean
cf_goto_frame(capture_file *cf, guint fnumber)
{
- frame_data *fdata;
-
- if (cf == NULL || cf->provider.frames == NULL) {
- /* we don't have a loaded capture file - fix for bugs 11810 & 11989 */
- statusbar_push_temporary_msg("There is no file loaded");
- return FALSE; /* we failed to go to that packet */
- }
-
- fdata = frame_data_sequence_find(cf->provider.frames, fnumber);
-
- if (fdata == NULL) {
- /* we didn't find a packet with that packet number */
- statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
- return FALSE; /* we failed to go to that packet */
- }
- if (!fdata->passed_dfilter) {
- /* that packet currently isn't displayed */
- /* XXX - add it to the set of displayed packets? */
- statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
- return FALSE; /* we failed to go to that packet */
- }
-
- if (!packet_list_select_row_from_data(fdata)) {
- /* We didn't find a row corresponding to this frame.
- This means that the frame isn't being displayed currently,
- so we can't select it. */
- simple_message_box(ESD_TYPE_INFO, NULL,
- "The capture file is probably not fully dissected.",
- "End of capture exceeded.");
- return FALSE;
- }
- return TRUE; /* we got to that packet */
+ frame_data *fdata;
+
+ if (cf == NULL || cf->provider.frames == NULL) {
+ /* we don't have a loaded capture file - fix for bugs 11810 & 11989 */
+ statusbar_push_temporary_msg("There is no file loaded");
+ return FALSE; /* we failed to go to that packet */
+ }
+
+ fdata = frame_data_sequence_find(cf->provider.frames, fnumber);
+
+ if (fdata == NULL) {
+ /* we didn't find a packet with that packet number */
+ statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
+ return FALSE; /* we failed to go to that packet */
+ }
+ if (!fdata->passed_dfilter) {
+ /* that packet currently isn't displayed */
+ /* XXX - add it to the set of displayed packets? */
+ statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
+ return FALSE; /* we failed to go to that packet */
+ }
+
+ if (!packet_list_select_row_from_data(fdata)) {
+ /* We didn't find a row corresponding to this frame.
+ This means that the frame isn't being displayed currently,
+ so we can't select it. */
+ simple_message_box(ESD_TYPE_INFO, NULL,
+ "The capture file is probably not fully dissected.",
+ "End of capture exceeded.");
+ return FALSE;
+ }
+ return TRUE; /* we got to that packet */
}
/*
@@ -4071,99 +4082,99 @@ cf_goto_frame(capture_file *cf, guint fnumber)
gboolean
cf_goto_framenum(capture_file *cf)
{
- header_field_info *hfinfo;
- guint32 framenum;
-
- if (cf->finfo_selected) {
- hfinfo = cf->finfo_selected->hfinfo;
- ws_assert(hfinfo);
- if (hfinfo->type == FT_FRAMENUM) {
- framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
- if (framenum != 0)
- return cf_goto_frame(cf, framenum);
- }
- }
-
- return FALSE;
+ header_field_info *hfinfo;
+ guint32 framenum;
+
+ if (cf->finfo_selected) {
+ hfinfo = cf->finfo_selected->hfinfo;
+ ws_assert(hfinfo);
+ if (hfinfo->type == FT_FRAMENUM) {
+ framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
+ if (framenum != 0)
+ return cf_goto_frame(cf, framenum);
+ }
+ }
+
+ return FALSE;
}
/* Select the packet on a given row. */
void
cf_select_packet(capture_file *cf, int row)
{
- epan_dissect_t *old_edt;
- frame_data *fdata;
-
- /* Get the frame data struct pointer for this frame */
- fdata = packet_list_get_row_data(row);
-
- if (fdata == NULL) {
- return;
- }
-
- /* Get the data in that frame. */
- if (!cf_read_record(cf, fdata, &cf->rec, &cf->buf)) {
- return;
- }
-
- /* Record that this frame is the current frame. */
- cf->current_frame = fdata;
- cf->current_row = row;
-
- /*
- * The change to defer freeing the current epan_dissect_t was in
- * commit a2bb94c3b33d53f42534aceb7cc67aab1d1fb1f9; to quote
- * that commit's comment:
- *
- * Clear GtkTreeStore before freeing edt
- *
- * When building current data for packet details treeview we store two
- * things.
- * - Generated string with item label
- * - Pointer to node field_info structure
- *
- * After epan_dissect_{free, cleanup} pointer to field_info node is no
- * longer valid so we should clear GtkTreeStore before freeing.
- *
- * XXX - we're no longer using GTK+; is there a way to ensure that
- * *nothing* refers to any of the current frame information before
- * we replace it?
- */
- old_edt = cf->edt;
- /* Create the logical protocol tree. */
- /* We don't need the columns here. */
- cf->edt = epan_dissect_new(cf->epan, TRUE, TRUE);
-
- tap_build_interesting(cf->edt);
- epan_dissect_run(cf->edt, cf->cd_t, &cf->rec,
- frame_tvbuff_new_buffer(&cf->provider, cf->current_frame, &cf->buf),
- cf->current_frame, NULL);
-
- dfilter_macro_build_ftv_cache(cf->edt->tree);
-
- if (old_edt != NULL)
- epan_dissect_free(old_edt);
+ epan_dissect_t *old_edt;
+ frame_data *fdata;
+
+ /* Get the frame data struct pointer for this frame */
+ fdata = packet_list_get_row_data(row);
+
+ if (fdata == NULL) {
+ return;
+ }
+
+ /* Get the data in that frame. */
+ if (!cf_read_record(cf, fdata, &cf->rec, &cf->buf)) {
+ return;
+ }
+
+ /* Record that this frame is the current frame. */
+ cf->current_frame = fdata;
+ cf->current_row = row;
+
+ /*
+ * The change to defer freeing the current epan_dissect_t was in
+ * commit a2bb94c3b33d53f42534aceb7cc67aab1d1fb1f9; to quote
+ * that commit's comment:
+ *
+ * Clear GtkTreeStore before freeing edt
+ *
+ * When building current data for packet details treeview we store two
+ * things.
+ * - Generated string with item label
+ * - Pointer to node field_info structure
+ *
+ * After epan_dissect_{free, cleanup} pointer to field_info node is no
+ * longer valid so we should clear GtkTreeStore before freeing.
+ *
+ * XXX - we're no longer using GTK+; is there a way to ensure that
+ * *nothing* refers to any of the current frame information before
+ * we replace it?
+ */
+ old_edt = cf->edt;
+ /* Create the logical protocol tree. */
+ /* We don't need the columns here. */
+ cf->edt = epan_dissect_new(cf->epan, TRUE, TRUE);
+
+ tap_build_interesting(cf->edt);
+ epan_dissect_run(cf->edt, cf->cd_t, &cf->rec,
+ frame_tvbuff_new_buffer(&cf->provider, cf->current_frame, &cf->buf),
+ cf->current_frame, NULL);
+
+ dfilter_macro_build_ftv_cache(cf->edt->tree);
+
+ if (old_edt != NULL)
+ epan_dissect_free(old_edt);
}
/* Unselect the selected packet, if any. */
void
cf_unselect_packet(capture_file *cf)
{
- epan_dissect_t *old_edt = cf->edt;
+ epan_dissect_t *old_edt = cf->edt;
- /*
- * See the comment in cf_select_packet() about deferring the freeing
- * of the old cf->edt.
- */
- cf->edt = NULL;
+ /*
+ * See the comment in cf_select_packet() about deferring the freeing
+ * of the old cf->edt.
+ */
+ cf->edt = NULL;
- /* No packet is selected. */
- cf->current_frame = NULL;
- cf->current_row = 0;
+ /* No packet is selected. */
+ cf->current_frame = NULL;
+ cf->current_row = 0;
- /* Destroy the epan_dissect_t for the unselected packet. */
- if (old_edt != NULL)
- epan_dissect_free(old_edt);
+ /* Destroy the epan_dissect_t for the unselected packet. */
+ if (old_edt != NULL)
+ epan_dissect_free(old_edt);
}
/*
@@ -4172,11 +4183,11 @@ cf_unselect_packet(capture_file *cf)
void
cf_mark_frame(capture_file *cf, frame_data *frame)
{
- if (! frame->marked) {
- frame->marked = TRUE;
- if (cf->count > cf->marked_count)
- cf->marked_count++;
- }
+ if (! frame->marked) {
+ frame->marked = TRUE;
+ if (cf->count > cf->marked_count)
+ cf->marked_count++;
+ }
}
/*
@@ -4185,11 +4196,11 @@ cf_mark_frame(capture_file *cf, frame_data *frame)
void
cf_unmark_frame(capture_file *cf, frame_data *frame)
{
- if (frame->marked) {
- frame->marked = FALSE;
- if (cf->marked_count > 0)
- cf->marked_count--;
- }
+ if (frame->marked) {
+ frame->marked = FALSE;
+ if (cf->marked_count > 0)
+ cf->marked_count--;
+ }
}
/*
@@ -4198,11 +4209,11 @@ cf_unmark_frame(capture_file *cf, frame_data *frame)
void
cf_ignore_frame(capture_file *cf, frame_data *frame)
{
- if (! frame->ignored) {
- frame->ignored = TRUE;
- if (cf->count > cf->ignored_count)
- cf->ignored_count++;
- }
+ if (! frame->ignored) {
+ frame->ignored = TRUE;
+ if (cf->count > cf->ignored_count)
+ cf->ignored_count++;
+ }
}
/*
@@ -4211,11 +4222,11 @@ cf_ignore_frame(capture_file *cf, frame_data *frame)
void
cf_unignore_frame(capture_file *cf, frame_data *frame)
{
- if (frame->ignored) {
- frame->ignored = FALSE;
- if (cf->ignored_count > 0)
- cf->ignored_count--;
- }
+ if (frame->ignored) {
+ frame->ignored = FALSE;
+ if (cf->ignored_count > 0)
+ cf->ignored_count--;
+ }
}
/*
@@ -4224,30 +4235,30 @@ cf_unignore_frame(capture_file *cf, frame_data *frame)
void
cf_update_section_comment(capture_file *cf, gchar *comment)
{
- wtap_block_t shb_inf;
- gchar *shb_comment;
-
- /* Get the first SHB. */
- /* XXX - support multiple SHBs */
- shb_inf = wtap_file_get_shb(cf->provider.wth, 0);
-
- /* Get the first comment from the SHB. */
- /* XXX - support multiple comments */
- if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0, &shb_comment) != WTAP_OPTTYPE_SUCCESS) {
- /* There's no comment - add one. */
- wtap_block_add_string_option(shb_inf, OPT_COMMENT, comment, strlen(comment));
- } else {
- /* See if the comment has changed or not */
- if (strcmp(shb_comment, comment) == 0) {
- g_free(comment);
- return;
- }
-
- /* The comment has changed, let's update it */
- wtap_block_set_nth_string_option_value(shb_inf, OPT_COMMENT, 0, comment, strlen(comment));
- }
- /* Mark the file as having unsaved changes */
- cf->unsaved_changes = TRUE;
+ wtap_block_t shb_inf;
+ gchar *shb_comment;
+
+ /* Get the first SHB. */
+ /* XXX - support multiple SHBs */
+ shb_inf = wtap_file_get_shb(cf->provider.wth, 0);
+
+ /* Get the first comment from the SHB. */
+ /* XXX - support multiple comments */
+ if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0, &shb_comment) != WTAP_OPTTYPE_SUCCESS) {
+ /* There's no comment - add one. */
+ wtap_block_add_string_option(shb_inf, OPT_COMMENT, comment, strlen(comment));
+ } else {
+ /* See if the comment has changed or not */
+ if (strcmp(shb_comment, comment) == 0) {
+ g_free(comment);
+ return;
+ }
+
+ /* The comment has changed, let's update it */
+ wtap_block_set_nth_string_option_value(shb_inf, OPT_COMMENT, 0, comment, strlen(comment));
+ }
+ /* Mark the file as having unsaved changes */
+ cf->unsaved_changes = TRUE;
}
/*
@@ -4259,28 +4270,28 @@ cf_update_section_comment(capture_file *cf, gchar *comment)
wtap_block_t
cf_get_packet_block(capture_file *cf, const frame_data *fd)
{
- /* If this block has been modified, fetch the modified version */
- if (fd->has_modified_block)
- return wtap_block_ref(cap_file_provider_get_modified_block(&cf->provider, fd));
- else {
- wtap_rec rec; /* Record metadata */
- Buffer buf; /* Record data */
- wtap_block_t block;
-
- /* fetch record block */
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
-
- if (!cf_read_record(cf, fd, &rec, &buf))
- { /* XXX, what we can do here? */ }
-
- /* rec.block is owned by the record, steal it before it is gone. */
- block = wtap_block_ref(rec.block);
-
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
- return block;
- }
+ /* If this block has been modified, fetch the modified version */
+ if (fd->has_modified_block)
+ return wtap_block_ref(cap_file_provider_get_modified_block(&cf->provider, fd));
+ else {
+ wtap_rec rec; /* Record metadata */
+ Buffer buf; /* Record data */
+ wtap_block_t block;
+
+ /* fetch record block */
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+
+ if (!cf_read_record(cf, fd, &rec, &buf))
+ { /* XXX, what we can do here? */ }
+
+ /* rec.block is owned by the record, steal it before it is gone. */
+ block = wtap_block_ref(rec.block);
+
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+ return block;
+ }
}
/*
@@ -4289,36 +4300,36 @@ cf_get_packet_block(capture_file *cf, const frame_data *fd)
gboolean
cf_set_modified_block(capture_file *cf, frame_data *fd, const wtap_block_t new_block)
{
- wtap_block_t pkt_block = cf_get_packet_block(cf, fd);
-
- /* It's possible to further modify the modified block "in place" by doing
- * a call to cf_get_packet_block() that returns an already created modified
- * block, modifying that, and calling this function.
- * If the caller did that, then the block pointers will be equal.
- */
- if (pkt_block == new_block) {
- /* No need to save anything here, the caller changes went right
- * onto the block.
- * Unfortunately we don't have a way to know how many comments were in the block
- * before the caller modified it.
+ wtap_block_t pkt_block = cf_get_packet_block(cf, fd);
+
+ /* It's possible to further modify the modified block "in place" by doing
+ * a call to cf_get_packet_block() that returns an already created modified
+ * block, modifying that, and calling this function.
+ * If the caller did that, then the block pointers will be equal.
*/
- }
- else {
- if (pkt_block)
- cf->packet_comment_count -= wtap_block_count_option(pkt_block, OPT_COMMENT);
+ if (pkt_block == new_block) {
+ /* No need to save anything here, the caller changes went right
+ * onto the block.
+ * Unfortunately we don't have a way to know how many comments were in the block
+ * before the caller modified it.
+ */
+ }
+ else {
+ if (pkt_block)
+ cf->packet_comment_count -= wtap_block_count_option(pkt_block, OPT_COMMENT);
- if (new_block)
- cf->packet_comment_count += wtap_block_count_option(new_block, OPT_COMMENT);
+ if (new_block)
+ cf->packet_comment_count += wtap_block_count_option(new_block, OPT_COMMENT);
- cap_file_provider_set_modified_block(&cf->provider, fd, new_block);
+ cap_file_provider_set_modified_block(&cf->provider, fd, new_block);
- expert_update_comment_count(cf->packet_comment_count);
- }
+ expert_update_comment_count(cf->packet_comment_count);
+ }
- /* Either way, we have unsaved changes. */
- wtap_block_unref(pkt_block);
- cf->unsaved_changes = TRUE;
- return TRUE;
+ /* Either way, we have unsaved changes. */
+ wtap_block_unref(pkt_block);
+ cf->unsaved_changes = TRUE;
+ return TRUE;
}
/*
@@ -4327,32 +4338,32 @@ cf_set_modified_block(capture_file *cf, frame_data *fd, const wtap_block_t new_b
guint32
cf_comment_types(capture_file *cf)
{
- guint32 comment_types = 0;
-
- /*
- * Does this file have any sections with at least one comment?
- */
- for (guint section_number = 0;
- section_number < wtap_file_get_num_shbs(cf->provider.wth);
- section_number++) {
- wtap_block_t shb_inf;
- char *shb_comment;
-
- shb_inf = wtap_file_get_shb(cf->provider.wth, section_number);
-
- /* Try to get the first comment from that SHB. */
- if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0,
- &shb_comment) == WTAP_OPTTYPE_SUCCESS) {
- /* We succeeded, so this file has at least one section comment. */
- comment_types |= WTAP_COMMENT_PER_SECTION;
-
- /* We don't need to search any more. */
- break;
- }
- }
- if (cf->packet_comment_count != 0)
- comment_types |= WTAP_COMMENT_PER_PACKET;
- return comment_types;
+ guint32 comment_types = 0;
+
+ /*
+ * Does this file have any sections with at least one comment?
+ */
+ for (guint section_number = 0;
+ section_number < wtap_file_get_num_shbs(cf->provider.wth);
+ section_number++) {
+ wtap_block_t shb_inf;
+ char *shb_comment;
+
+ shb_inf = wtap_file_get_shb(cf->provider.wth, section_number);
+
+ /* Try to get the first comment from that SHB. */
+ if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0,
+ &shb_comment) == WTAP_OPTTYPE_SUCCESS) {
+ /* We succeeded, so this file has at least one section comment. */
+ comment_types |= WTAP_COMMENT_PER_SECTION;
+
+ /* We don't need to search any more. */
+ break;
+ }
+ }
+ if (cf->packet_comment_count != 0)
+ comment_types |= WTAP_COMMENT_PER_PACKET;
+ return comment_types;
}
/*
@@ -4361,22 +4372,22 @@ cf_comment_types(capture_file *cf)
gboolean
cf_add_ip_name_from_string(capture_file *cf, const char *addr, const char *name)
{
- /*
- * XXX - support multiple resolved address lists, and add to the one
- * attached to this file?
- */
- if (!add_ip_name_from_string(addr, name))
- return FALSE;
+ /*
+ * XXX - support multiple resolved address lists, and add to the one
+ * attached to this file?
+ */
+ if (!add_ip_name_from_string(addr, name))
+ return FALSE;
- /* OK, we have unsaved changes. */
- cf->unsaved_changes = TRUE;
- return TRUE;
+ /* OK, we have unsaved changes. */
+ cf->unsaved_changes = TRUE;
+ return TRUE;
}
typedef struct {
- wtap_dumper *pdh;
- const char *fname;
- int file_type;
+ wtap_dumper *pdh;
+ const char *fname;
+ int file_type;
} save_callback_args_t;
/*
@@ -4388,35 +4399,35 @@ typedef struct {
*/
static gboolean
save_record(capture_file *cf, frame_data *fdata, wtap_rec *rec,
- Buffer *buf, void *argsp)
+ Buffer *buf, void *argsp)
{
- save_callback_args_t *args = (save_callback_args_t *)argsp;
- wtap_rec new_rec;
- int err;
- gchar *err_info;
- wtap_block_t pkt_block;
-
- /* Copy the record information from what was read in from the file. */
- new_rec = *rec;
-
- /* Make changes based on anything that the user has done but that
- hasn't been saved yet. */
- if (fdata->has_modified_block)
- pkt_block = cap_file_provider_get_modified_block(&cf->provider, fdata);
- else
- pkt_block = rec->block;
- new_rec.block = pkt_block;
- new_rec.block_was_modified = fdata->has_modified_block ? TRUE : FALSE;
- /* XXX - what if times have been shifted? */
-
- /* and save the packet */
- if (!wtap_dump(args->pdh, &new_rec, ws_buffer_start_ptr(buf), &err, &err_info)) {
- cfile_write_failure_alert_box(NULL, args->fname, err, err_info, fdata->num,
- args->file_type);
- return FALSE;
- }
+ save_callback_args_t *args = (save_callback_args_t *)argsp;
+ wtap_rec new_rec;
+ int err;
+ gchar *err_info;
+ wtap_block_t pkt_block;
+
+ /* Copy the record information from what was read in from the file. */
+ new_rec = *rec;
+
+ /* Make changes based on anything that the user has done but that
+ hasn't been saved yet. */
+ if (fdata->has_modified_block)
+ pkt_block = cap_file_provider_get_modified_block(&cf->provider, fdata);
+ else
+ pkt_block = rec->block;
+ new_rec.block = pkt_block;
+ new_rec.block_was_modified = fdata->has_modified_block ? TRUE : FALSE;
+ /* XXX - what if times have been shifted? */
+
+ /* and save the packet */
+ if (!wtap_dump(args->pdh, &new_rec, ws_buffer_start_ptr(buf), &err, &err_info)) {
+ cfile_write_failure_alert_box(NULL, args->fname, err, err_info, fdata->num,
+ args->file_type);
+ return FALSE;
+ }
- return TRUE;
+ return TRUE;
}
/*
@@ -4426,10 +4437,10 @@ save_record(capture_file *cf, frame_data *fdata, wtap_rec *rec,
gboolean
cf_can_write_with_wiretap(capture_file *cf)
{
- /* We don't care whether we support the comments in this file or not;
- if we can't, we'll offer the user the option of discarding the
- comments. */
- return wtap_dump_can_write(cf->linktypes, 0);
+ /* We don't care whether we support the comments in this file or not;
+ if we can't, we'll offer the user the option of discarding the
+ comments. */
+ return wtap_dump_can_write(cf->linktypes, 0);
}
/*
@@ -4455,21 +4466,21 @@ cf_can_write_with_wiretap(capture_file *cf)
gboolean
cf_can_save(capture_file *cf)
{
- if (cf->unsaved_changes && wtap_dump_can_write(cf->linktypes, 0)) {
- /* Saved changes, and we can write it out with Wiretap. */
- return TRUE;
- }
+ if (cf->unsaved_changes && wtap_dump_can_write(cf->linktypes, 0)) {
+ /* Saved changes, and we can write it out with Wiretap. */
+ return TRUE;
+ }
- if (cf->is_tempfile && !cf->unsaved_changes) {
- /*
- * Temporary file with no unsaved changes, so we can just do a
- * raw binary copy.
- */
- return TRUE;
- }
+ if (cf->is_tempfile && !cf->unsaved_changes) {
+ /*
+ * Temporary file with no unsaved changes, so we can just do a
+ * raw binary copy.
+ */
+ return TRUE;
+ }
- /* Nothing to save. */
- return FALSE;
+ /* Nothing to save. */
+ return FALSE;
}
/*
@@ -4494,21 +4505,21 @@ cf_can_save(capture_file *cf)
gboolean
cf_can_save_as(capture_file *cf)
{
- if (wtap_dump_can_write(cf->linktypes, 0)) {
- /* We can write it out with Wiretap. */
- return TRUE;
- }
+ if (wtap_dump_can_write(cf->linktypes, 0)) {
+ /* We can write it out with Wiretap. */
+ return TRUE;
+ }
- if (cf->is_tempfile && !cf->unsaved_changes) {
- /*
- * Temporary file with no unsaved changes, so we can just do a
- * raw binary copy.
- */
- return TRUE;
- }
+ if (cf->is_tempfile && !cf->unsaved_changes) {
+ /*
+ * Temporary file with no unsaved changes, so we can just do a
+ * raw binary copy.
+ */
+ return TRUE;
+ }
- /* Nothing to save. */
- return FALSE;
+ /* Nothing to save. */
+ return FALSE;
}
/*
@@ -4517,11 +4528,11 @@ cf_can_save_as(capture_file *cf)
gboolean
cf_has_unsaved_data(capture_file *cf)
{
- /*
- * If this is a temporary file, or a file with unsaved changes, it
- * has unsaved data.
- */
- return (cf->is_tempfile && cf->count>0) || cf->unsaved_changes;
+ /*
+ * If this is a temporary file, or a file with unsaved changes, it
+ * has unsaved data.
+ */
+ return (cf->is_tempfile && cf->count>0) || cf->unsaved_changes;
}
/*
@@ -4530,287 +4541,546 @@ cf_has_unsaved_data(capture_file *cf)
static cf_read_status_t
rescan_file(capture_file *cf, const char *fname, gboolean is_tempfile)
{
- wtap_rec rec;
- Buffer buf;
- int err;
- gchar *err_info;
- gchar *name_ptr;
- gint64 data_offset;
- progdlg_t *progbar = NULL;
- GTimer *prog_timer = g_timer_new();
- gint64 size;
- float progbar_val;
- gint64 start_time;
- gchar status_str[100];
- guint32 framenum;
- frame_data *fdata;
- int count = 0;
-
- /* Close the old handle. */
- wtap_close(cf->provider.wth);
-
- /* Open the new file. */
- /* XXX: this will go through all open_routines for a matching one. But right
- now rescan_file() is only used when a file is being saved to a different
- format than the original, and the user is not given a choice of which
- reader to use (only which format to save it in), so doing this makes
- sense for now. */
- cf->provider.wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
- if (cf->provider.wth == NULL) {
- cfile_open_failure_alert_box(fname, err, err_info);
- return CF_READ_ERROR;
- }
-
- /* We're scanning a file whose contents should be the same as what
- we had before, so we don't discard dissection state etc.. */
- cf->f_datalen = 0;
-
- /* Set the file name because we need it to set the follow stream filter.
- XXX - is that still true? We need it for other reasons, though,
- in any case. */
- cf->filename = g_strdup(fname);
-
- /* Indicate whether it's a permanent or temporary file. */
- cf->is_tempfile = is_tempfile;
-
- /* No user changes yet. */
- cf->unsaved_changes = FALSE;
-
- cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
- cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
-
- cf->snap = wtap_snapshot_length(cf->provider.wth);
-
- name_ptr = g_filename_display_basename(cf->filename);
-
- cf_callback_invoke(cf_cb_file_rescan_started, cf);
-
- /* Record the file's compression type.
- XXX - do we know this at open time? */
- cf->compression_type = wtap_get_compression_type(cf->provider.wth);
-
- /* Find the size of the file. */
- size = wtap_file_size(cf->provider.wth, NULL);
-
- g_timer_start(prog_timer);
-
- cf->stop_flag = FALSE;
- start_time = g_get_monotonic_time();
-
- framenum = 0;
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
- while ((wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info,
- &data_offset))) {
- framenum++;
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
- fdata->file_off = data_offset;
- if (size >= 0) {
- count++;
- cf->f_datalen = wtap_read_so_far(cf->provider.wth);
-
- /* Create the progress bar if necessary. */
- if (progress_is_slow(progbar, prog_timer, size, cf->f_datalen)) {
- progbar_val = calc_progbar_val(cf, size, cf->f_datalen, status_str, sizeof(status_str));
- progbar = delayed_create_progress_dlg(cf->window, NULL, NULL,
- TRUE, &cf->stop_flag, progbar_val);
- }
-
- /*
- * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
- * has elapsed. Calling update_progress_dlg and packets_bar_update will
- * likely trigger UI paint events, which might take a while depending on
- * the platform and display. Reset our timer *after* painting.
- */
- if (progbar && g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
- progbar_val = calc_progbar_val(cf, size, cf->f_datalen, status_str, sizeof(status_str));
- /* update the packet bar content on the first run or frequently on very large files */
- update_progress_dlg(progbar, progbar_val, status_str);
- compute_elapsed(cf, start_time);
- packets_bar_update();
- g_timer_start(prog_timer);
- }
+ wtap_rec rec;
+ Buffer buf;
+ int err;
+ gchar *err_info;
+ gchar *name_ptr;
+ gint64 data_offset;
+ progdlg_t *progbar = NULL;
+ GTimer *prog_timer = g_timer_new();
+ gint64 size;
+ float progbar_val;
+ gint64 start_time;
+ gchar status_str[100];
+ guint32 framenum;
+ frame_data *fdata;
+ int count = 0;
+
+ /* Close the old handle. */
+ wtap_close(cf->provider.wth);
+
+ /* Open the new file. */
+ /* XXX: this will go through all open_routines for a matching one. But right
+ now rescan_file() is only used when a file is being saved to a different
+ format than the original, and the user is not given a choice of which
+ reader to use (only which format to save it in), so doing this makes
+ sense for now. */
+ cf->provider.wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
+ if (cf->provider.wth == NULL) {
+ cfile_open_failure_alert_box(fname, err, err_info);
+ return CF_READ_ERROR;
}
+ /* We're scanning a file whose contents should be the same as what
+ we had before, so we don't discard dissection state etc.. */
+ cf->f_datalen = 0;
+
+ /* Set the file name because we need it to set the follow stream filter.
+ XXX - is that still true? We need it for other reasons, though,
+ in any case. */
+ cf->filename = g_strdup(fname);
+
+ /* Indicate whether it's a permanent or temporary file. */
+ cf->is_tempfile = is_tempfile;
+
+ /* No user changes yet. */
+ cf->unsaved_changes = FALSE;
+
+ cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
+ cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
+
+ cf->snap = wtap_snapshot_length(cf->provider.wth);
+
+ name_ptr = g_filename_display_basename(cf->filename);
+
+ cf_callback_invoke(cf_cb_file_rescan_started, cf);
+
+ /* Record the file's compression type.
+ XXX - do we know this at open time? */
+ cf->compression_type = wtap_get_compression_type(cf->provider.wth);
+
+ /* Find the size of the file. */
+ size = wtap_file_size(cf->provider.wth, NULL);
+
+ g_timer_start(prog_timer);
+
+ cf->stop_flag = FALSE;
+ start_time = g_get_monotonic_time();
+
+ framenum = 0;
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+ while ((wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info,
+ &data_offset))) {
+ framenum++;
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+ fdata->file_off = data_offset;
+ if (size >= 0) {
+ count++;
+ cf->f_datalen = wtap_read_so_far(cf->provider.wth);
+
+ /* Create the progress bar if necessary. */
+ if (progress_is_slow(progbar, prog_timer, size, cf->f_datalen)) {
+ progbar_val = calc_progbar_val(cf, size, cf->f_datalen, status_str, sizeof(status_str));
+ progbar = delayed_create_progress_dlg(cf->window, NULL, NULL,
+ TRUE, &cf->stop_flag, progbar_val);
+ }
+
+ /*
+ * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
+ * has elapsed. Calling update_progress_dlg and packets_bar_update will
+ * likely trigger UI paint events, which might take a while depending on
+ * the platform and display. Reset our timer *after* painting.
+ */
+ if (progbar && g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
+ progbar_val = calc_progbar_val(cf, size, cf->f_datalen, status_str, sizeof(status_str));
+ /* update the packet bar content on the first run or frequently on very large files */
+ update_progress_dlg(progbar, progbar_val, status_str);
+ compute_elapsed(cf, start_time);
+ packets_bar_update();
+ g_timer_start(prog_timer);
+ }
+ }
+
+ if (cf->stop_flag) {
+ /* Well, the user decided to abort the rescan. Sadly, as this
+ isn't a reread, recovering is difficult, so we'll just
+ close the current capture. */
+ break;
+ }
+
+ /* Add this packet's link-layer encapsulation type to cf->linktypes, if
+ it's not already there.
+ XXX - yes, this is O(N), so if every packet had a different
+ link-layer encapsulation type, it'd be O(N^2) to read the file, but
+ there are probably going to be a small number of encapsulation types
+ in a file. */
+ if (rec.rec_type == REC_TYPE_PACKET) {
+ cf_add_encapsulation_type(cf, rec.rec_header.packet_header.pkt_encap);
+ }
+ }
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+
+ /* Free the display name */
+ g_free(name_ptr);
+
+ /* We're done reading the file; destroy the progress bar if it was created. */
+ if (progbar != NULL)
+ destroy_progress_dlg(progbar);
+ g_timer_destroy(prog_timer);
+
+ /* We're done reading sequentially through the file. */
+ cf->state = FILE_READ_DONE;
+
+ /* Close the sequential I/O side, to free up memory it requires. */
+ wtap_sequential_close(cf->provider.wth);
+
+ /* compute the time it took to load the file */
+ compute_elapsed(cf, start_time);
+
+ /* Set the file encapsulation type now; we don't know what it is until
+ we've looked at all the packets, as we don't know until then whether
+ there's more than one type (and thus whether it's
+ WTAP_ENCAP_PER_PACKET). */
+ cf->lnk_t = wtap_file_encap(cf->provider.wth);
+
+ cf_callback_invoke(cf_cb_file_rescan_finished, cf);
+
if (cf->stop_flag) {
- /* Well, the user decided to abort the rescan. Sadly, as this
- isn't a reread, recovering is difficult, so we'll just
- close the current capture. */
- break;
+ /* Our caller will give up at this point. */
+ return CF_READ_ABORTED;
}
- /* Add this packet's link-layer encapsulation type to cf->linktypes, if
- it's not already there.
- XXX - yes, this is O(N), so if every packet had a different
- link-layer encapsulation type, it'd be O(N^2) to read the file, but
- there are probably going to be a small number of encapsulation types
- in a file. */
- if (rec.rec_type == REC_TYPE_PACKET) {
- cf_add_encapsulation_type(cf, rec.rec_header.packet_header.pkt_encap);
- }
- }
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
-
- /* Free the display name */
- g_free(name_ptr);
-
- /* We're done reading the file; destroy the progress bar if it was created. */
- if (progbar != NULL)
- destroy_progress_dlg(progbar);
- g_timer_destroy(prog_timer);
-
- /* We're done reading sequentially through the file. */
- cf->state = FILE_READ_DONE;
-
- /* Close the sequential I/O side, to free up memory it requires. */
- wtap_sequential_close(cf->provider.wth);
-
- /* compute the time it took to load the file */
- compute_elapsed(cf, start_time);
-
- /* Set the file encapsulation type now; we don't know what it is until
- we've looked at all the packets, as we don't know until then whether
- there's more than one type (and thus whether it's
- WTAP_ENCAP_PER_PACKET). */
- cf->lnk_t = wtap_file_encap(cf->provider.wth);
-
- cf_callback_invoke(cf_cb_file_rescan_finished, cf);
-
- if (cf->stop_flag) {
- /* Our caller will give up at this point. */
- return CF_READ_ABORTED;
- }
-
- if (err != 0) {
- /* Put up a message box noting that the read failed somewhere along
- the line. Don't throw out the stuff we managed to read, though,
- if any. */
- cfile_read_failure_alert_box(NULL, err, err_info);
- return CF_READ_ERROR;
- } else
- return CF_READ_OK;
+ if (err != 0) {
+ /* Put up a message box noting that the read failed somewhere along
+ the line. Don't throw out the stuff we managed to read, though,
+ if any. */
+ cfile_read_failure_alert_box(NULL, err, err_info);
+ return CF_READ_ERROR;
+ } else
+ return CF_READ_OK;
}
cf_write_status_t
cf_save_records(capture_file *cf, const char *fname, guint save_format,
- wtap_compression_type compression_type,
- gboolean discard_comments, gboolean dont_reopen)
+ wtap_compression_type compression_type,
+ gboolean discard_comments, gboolean dont_reopen)
{
- gchar *err_info;
- gchar *fname_new = NULL;
- wtap_dumper *pdh;
- frame_data *fdata;
- addrinfo_lists_t *addr_lists;
- guint framenum;
- int err;
+ gchar *err_info;
+ gchar *fname_new = NULL;
+ wtap_dumper *pdh;
+ frame_data *fdata;
+ addrinfo_lists_t *addr_lists;
+ guint framenum;
+ int err;
#ifdef _WIN32
- gchar *display_basename;
+ gchar *display_basename;
#endif
- enum {
- SAVE_WITH_MOVE,
- SAVE_WITH_COPY,
- SAVE_WITH_WTAP
- } how_to_save;
- save_callback_args_t callback_args;
- gboolean needs_reload = FALSE;
-
- /* XXX caller should avoid saving the file while a read is pending
- * (e.g. by delaying the save action) */
- if (cf->read_lock) {
- ws_warning("cf_save_records(\"%s\") while the file is being read, potential crash ahead", fname);
- }
-
- cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
-
- addr_lists = get_addrinfo_list();
-
- if (save_format == cf->cd_t && compression_type == cf->compression_type
- && !discard_comments && !cf->unsaved_changes
- && (wtap_addrinfo_list_empty(addr_lists) || wtap_file_type_subtype_supports_block(save_format, WTAP_BLOCK_NAME_RESOLUTION) == BLOCK_NOT_SUPPORTED)) {
- /* We're saving in the format it's already in, and we're not discarding
- comments, and there are no changes we have in memory that aren't saved
- to the file, and we have no name resolution information to write or
- the file format we're saving in doesn't support writing name
- resolution information, so we can just move or copy the raw data. */
-
- if (cf->is_tempfile) {
- /* The file being saved is a temporary file from a live
- capture, so it doesn't need to stay around under that name;
- first, try renaming the capture buffer file to the new name.
- This acts as a "safe save", in that, if the file already
- exists, the existing file will be removed only if the rename
- succeeds.
-
- Sadly, on Windows, as we have the current capture file
- open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
- (to cause the rename to remove an existing target), as
- done by ws_stdio_rename() (ws_rename() is #defined to
- be ws_stdio_rename() on Windows) will fail.
-
- According to the MSDN documentation for CreateFile(), if,
- when we open a capture file, we were to directly do a CreateFile(),
- opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
- convert it to a file descriptor with _open_osfhandle(),
- that would allow the file to be renamed out from under us.
-
- However, that doesn't work in practice. Perhaps the problem
- is that the process doing the rename is the process that
- has the file open. */
+ enum {
+ SAVE_WITH_MOVE,
+ SAVE_WITH_COPY,
+ SAVE_WITH_WTAP
+ } how_to_save;
+ save_callback_args_t callback_args;
+ gboolean needs_reload = FALSE;
+
+ /* XXX caller should avoid saving the file while a read is pending
+ * (e.g. by delaying the save action) */
+ if (cf->read_lock) {
+ ws_warning("cf_save_records(\"%s\") while the file is being read, potential crash ahead", fname);
+ }
+
+ cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
+
+ addr_lists = get_addrinfo_list();
+
+ if (save_format == cf->cd_t && compression_type == cf->compression_type
+ && !discard_comments && !cf->unsaved_changes
+ && (wtap_addrinfo_list_empty(addr_lists) || wtap_file_type_subtype_supports_block(save_format, WTAP_BLOCK_NAME_RESOLUTION) == BLOCK_NOT_SUPPORTED)) {
+ /* We're saving in the format it's already in, and we're not discarding
+ comments, and there are no changes we have in memory that aren't saved
+ to the file, and we have no name resolution information to write or
+ the file format we're saving in doesn't support writing name
+ resolution information, so we can just move or copy the raw data. */
+
+ if (cf->is_tempfile) {
+ /* The file being saved is a temporary file from a live
+ capture, so it doesn't need to stay around under that name;
+ first, try renaming the capture buffer file to the new name.
+ This acts as a "safe save", in that, if the file already
+ exists, the existing file will be removed only if the rename
+ succeeds.
+
+ Sadly, on Windows, as we have the current capture file
+ open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
+ (to cause the rename to remove an existing target), as
+ done by ws_stdio_rename() (ws_rename() is #defined to
+ be ws_stdio_rename() on Windows) will fail.
+
+ According to the MSDN documentation for CreateFile(), if,
+ when we open a capture file, we were to directly do a CreateFile(),
+ opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
+ convert it to a file descriptor with _open_osfhandle(),
+ that would allow the file to be renamed out from under us.
+
+ However, that doesn't work in practice. Perhaps the problem
+ is that the process doing the rename is the process that
+ has the file open. */
#ifndef _WIN32
- if (ws_rename(cf->filename, fname) == 0) {
- /* That succeeded - there's no need to copy the source file. */
- how_to_save = SAVE_WITH_MOVE;
- } else {
- if (errno == EXDEV) {
- /* They're on different file systems, so we have to copy the
- file. */
- how_to_save = SAVE_WITH_COPY;
- } else {
- /* The rename failed, but not because they're on different
- file systems - put up an error message. (Or should we
- just punt and try to copy? The only reason why I'd
- expect the rename to fail and the copy to succeed would
- be if we didn't have permission to remove the file from
- the temporary directory, and that might be fixable - but
- is it worth requiring the user to go off and fix it?) */
- cf_rename_failure_alert_box(fname, errno);
- goto fail;
- }
- }
+ if (ws_rename(cf->filename, fname) == 0) {
+ /* That succeeded - there's no need to copy the source file. */
+ how_to_save = SAVE_WITH_MOVE;
+ } else {
+ if (errno == EXDEV) {
+ /* They're on different file systems, so we have to copy the
+ file. */
+ how_to_save = SAVE_WITH_COPY;
+ } else {
+ /* The rename failed, but not because they're on different
+ file systems - put up an error message. (Or should we
+ just punt and try to copy? The only reason why I'd
+ expect the rename to fail and the copy to succeed would
+ be if we didn't have permission to remove the file from
+ the temporary directory, and that might be fixable - but
+ is it worth requiring the user to go off and fix it?) */
+ cf_rename_failure_alert_box(fname, errno);
+ goto fail;
+ }
+ }
#else
- /* Windows - copy the file to its new location. */
- how_to_save = SAVE_WITH_COPY;
+ /* Windows - copy the file to its new location. */
+ how_to_save = SAVE_WITH_COPY;
#endif
+ } else {
+ /* It's a permanent file, so we should copy it, and not remove the
+ original. */
+ how_to_save = SAVE_WITH_COPY;
+ }
+
+ if (how_to_save == SAVE_WITH_COPY) {
+ /* Copy the file, if we haven't moved it. If we're overwriting
+ an existing file, we do it with a "safe save", by writing
+ to a new file and, if the write succeeds, renaming the
+ new file on top of the old file. */
+ if (file_exists(fname)) {
+ fname_new = ws_strdup_printf("%s~", fname);
+ if (!copy_file_binary_mode(cf->filename, fname_new))
+ goto fail;
+ } else {
+ if (!copy_file_binary_mode(cf->filename, fname))
+ goto fail;
+ }
+ }
} else {
- /* It's a permanent file, so we should copy it, and not remove the
- original. */
- how_to_save = SAVE_WITH_COPY;
+ /* Either we're saving in a different format or we're saving changes,
+ such as added, modified, or removed comments, that haven't yet
+ been written to the underlying file; we can't do that by copying
+ or moving the capture file, we have to do it by writing the packets
+ out in Wiretap. */
+
+ wtap_dump_params params;
+ int encap;
+
+ /* XXX: what free's params.shb_hdr? */
+ wtap_dump_params_init(&params, cf->provider.wth);
+
+ /* Determine what file encapsulation type we should use. */
+ encap = wtap_dump_file_encap_type(cf->linktypes);
+ params.encap = encap;
+
+ /* Use the snaplen from cf (XXX - does wtap_dump_params_init handle that?) */
+ params.snaplen = cf->snap;
+
+ if (file_exists(fname)) {
+ /* We're overwriting an existing file; write out to a new file,
+ and, if that succeeds, rename the new file on top of the
+ old file. That makes this a "safe save", so that we don't
+ lose the old file if we have a problem writing out the new
+ file. (If the existing file is the current capture file,
+ we *HAVE* to do that, otherwise we're overwriting the file
+ from which we're reading the packets that we're writing!) */
+ fname_new = ws_strdup_printf("%s~", fname);
+ pdh = wtap_dump_open(fname_new, save_format, compression_type, &params,
+ &err, &err_info);
+ } else {
+ pdh = wtap_dump_open(fname, save_format, compression_type, &params,
+ &err, &err_info);
+ }
+ /* XXX idb_inf is documented to be used until wtap_dump_close. */
+ g_free(params.idb_inf);
+ params.idb_inf = NULL;
+
+ if (pdh == NULL) {
+ cfile_dump_open_failure_alert_box(fname, err, err_info, save_format);
+ goto fail;
+ }
+
+ /* Add address resolution */
+ wtap_dump_set_addrinfo_list(pdh, addr_lists);
+
+ /* Iterate through the list of packets, processing all the packets. */
+ callback_args.pdh = pdh;
+ callback_args.fname = fname;
+ callback_args.file_type = save_format;
+ switch (process_specified_records(cf, NULL, "Saving", "packets",
+ TRUE, save_record, &callback_args, TRUE)) {
+
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ break;
+
+ case PSP_STOPPED:
+ /* The user decided to abort the saving.
+ If we're writing to a temporary file, remove it.
+ XXX - should we do so even if we're not writing to a
+ temporary file? */
+ wtap_dump_close(pdh, &err, &err_info);
+ if (fname_new != NULL)
+ ws_unlink(fname_new);
+ cf_callback_invoke(cf_cb_file_save_stopped, NULL);
+ return CF_WRITE_ABORTED;
+
+ case PSP_FAILED:
+ /* Error while saving.
+ If we're writing to a temporary file, remove it. */
+ if (fname_new != NULL)
+ ws_unlink(fname_new);
+ wtap_dump_close(pdh, &err, &err_info);
+ goto fail;
+ }
+
+ needs_reload = wtap_dump_get_needs_reload(pdh);
+
+ if (!wtap_dump_close(pdh, &err, &err_info)) {
+ cfile_close_failure_alert_box(fname, err, err_info);
+ goto fail;
+ }
+
+ how_to_save = SAVE_WITH_WTAP;
}
- if (how_to_save == SAVE_WITH_COPY) {
- /* Copy the file, if we haven't moved it. If we're overwriting
- an existing file, we do it with a "safe save", by writing
- to a new file and, if the write succeeds, renaming the
- new file on top of the old file. */
- if (file_exists(fname)) {
- fname_new = ws_strdup_printf("%s~", fname);
- if (!copy_file_binary_mode(cf->filename, fname_new))
- goto fail;
- } else {
- if (!copy_file_binary_mode(cf->filename, fname))
- goto fail;
- }
- }
- } else {
- /* Either we're saving in a different format or we're saving changes,
- such as added, modified, or removed comments, that haven't yet
- been written to the underlying file; we can't do that by copying
- or moving the capture file, we have to do it by writing the packets
- out in Wiretap. */
-
- wtap_dump_params params;
- int encap;
+ if (fname_new != NULL) {
+ /* We wrote out to fname_new, and should rename it on top of
+ fname. fname_new is now closed, so that should be possible even
+ on Windows. However, on Windows, we first need to close whatever
+ file descriptors we have open for fname. */
+#ifdef _WIN32
+ wtap_fdclose(cf->provider.wth);
+#endif
+ /* Now do the rename. */
+ if (ws_rename(fname_new, fname) == -1) {
+ /* Well, the rename failed. */
+ cf_rename_failure_alert_box(fname, errno);
+#ifdef _WIN32
+ /* Attempt to reopen the random file descriptor using the
+ current file's filename. (At this point, the sequential
+ file descriptor is closed.) */
+ if (!wtap_fdreopen(cf->provider.wth, cf->filename, &err)) {
+ /* Oh, well, we're screwed. */
+ display_basename = g_filename_display_basename(cf->filename);
+ simple_error_message_box(
+ file_open_error_message(err, FALSE), display_basename);
+ g_free(display_basename);
+ }
+#endif
+ goto fail;
+ }
+ }
+
+ /* If this was a temporary file, and we didn't do the save by doing
+ a move, so the tempoary file is still around under its old name,
+ remove it. */
+ if (cf->is_tempfile && how_to_save != SAVE_WITH_MOVE) {
+ /* If this fails, there's not much we can do, so just ignore errors. */
+ ws_unlink(cf->filename);
+ }
+
+ cf_callback_invoke(cf_cb_file_save_finished, NULL);
+ cf->unsaved_changes = FALSE;
+
+ if (!dont_reopen) {
+ switch (how_to_save) {
+
+ case SAVE_WITH_MOVE:
+ /* We just moved the file, so the wtap structure refers to the
+ new file, and all the information other than the filename
+ and the "is temporary" status applies to the new file; just
+ update that. */
+ g_free(cf->filename);
+ cf->filename = g_strdup(fname);
+ cf->is_tempfile = FALSE;
+ cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
+ break;
+
+ case SAVE_WITH_COPY:
+ /* We just copied the file, so all the information other than
+ the wtap structure, the filename, and the "is temporary"
+ status applies to the new file; just update that. */
+ wtap_close(cf->provider.wth);
+ /* Although we're just "copying" and then opening the copy, it will
+ try all open_routine readers to open the copy, so we need to
+ reset the cfile's open_type. */
+ cf->open_type = WTAP_TYPE_AUTO;
+ cf->provider.wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
+ if (cf->provider.wth == NULL) {
+ cfile_open_failure_alert_box(fname, err, err_info);
+ cf_close(cf);
+ } else {
+ g_free(cf->filename);
+ cf->filename = g_strdup(fname);
+ cf->is_tempfile = FALSE;
+ }
+ cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
+ break;
+
+ case SAVE_WITH_WTAP:
+ /* Open and read the file we saved to.
+
+ XXX - this is somewhat of a waste; we already have the
+ packets, all this gets us is updated file type information
+ (which we could just stuff into "cf"), and having the new
+ file be the one we have opened and from which we're reading
+ the data, and it means we have to spend time opening and
+ reading the file, which could be a significant amount of
+ time if the file is large.
+
+ If the capture-file-writing code were to return the
+ seek offset of each packet it writes, we could save that
+ in the frame_data structure for the frame, and just open
+ the file without reading it again...
+
+ ...as long as, for gzipped files, the process of writing
+ out the file *also* generates the information needed to
+ support fast random access to the compressed file. */
+ /* rescan_file will cause us to try all open_routines, so
+ reset cfile's open_type */
+ cf->open_type = WTAP_TYPE_AUTO;
+ /* There are cases when SAVE_WITH_WTAP can result in new packets
+ being written to the file, e.g ERF records
+ In that case, we need to reload the whole file */
+ if(needs_reload) {
+ if (cf_open(cf, fname, WTAP_TYPE_AUTO, FALSE, &err) == CF_OK) {
+ if (cf_read(cf, TRUE) != CF_READ_OK) {
+ /* The rescan failed; just close the file. Either
+ a dialog was popped up for the failure, so the
+ user knows what happened, or they stopped the
+ rescan, in which case they know what happened. */
+ /* XXX: This is inconsistent with normal open/reload behaviour. */
+ cf_close(cf);
+ }
+ }
+ }
+ else {
+ if (rescan_file(cf, fname, FALSE) != CF_READ_OK) {
+ /* The rescan failed; just close the file. Either
+ a dialog was popped up for the failure, so the
+ user knows what happened, or they stopped the
+ rescan, in which case they know what happened. */
+ cf_close(cf);
+ }
+ }
+ break;
+ }
+
+ /* If we were told to discard the comments, do so. */
+ if (discard_comments) {
+ /* Remove SHB comment, if any. */
+ wtap_write_shb_comment(cf->provider.wth, NULL);
+
+ /* remove all user comments */
+ for (framenum = 1; framenum <= cf->count; framenum++) {
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+
+ // XXX: This also ignores non-comment options like verdict
+ fdata->has_modified_block = FALSE;
+ }
+
+ if (cf->provider.frames_modified_blocks) {
+ g_tree_destroy(cf->provider.frames_modified_blocks);
+ cf->provider.frames_modified_blocks = NULL;
+ }
+
+ cf->packet_comment_count = 0;
+ }
+ }
+ return CF_WRITE_OK;
+
+fail:
+ if (fname_new != NULL) {
+ /* We were trying to write to a temporary file; get rid of it if it
+ exists. (We don't care whether this fails, as, if it fails,
+ there's not much we can do about it. I guess if it failed for
+ a reason other than "it doesn't exist", we could report an
+ error, so the user knows there's a junk file that they might
+ want to clean up.) */
+ ws_unlink(fname_new);
+ g_free(fname_new);
+ }
+ cf_callback_invoke(cf_cb_file_save_failed, NULL);
+ return CF_WRITE_ERROR;
+}
+
+cf_write_status_t
+cf_export_specified_packets(capture_file *cf, const char *fname,
+ packet_range_t *range, guint save_format,
+ wtap_compression_type compression_type)
+{
+ gchar *fname_new = NULL;
+ int err;
+ gchar *err_info;
+ wtap_dumper *pdh;
+ save_callback_args_t callback_args;
+ wtap_dump_params params;
+ int encap;
+
+ packet_range_process_init(range);
+
+ /* We're writing out specified packets from the specified capture
+ file to another file. Even if all captured packets are to be
+ written, don't special-case the operation - read each packet
+ and then write it out if it's one of the specified ones. */
/* XXX: what free's params.shb_hdr? */
wtap_dump_params_init(&params, cf->provider.wth);
@@ -4823,362 +5093,103 @@ cf_save_records(capture_file *cf, const char *fname, guint save_format,
params.snaplen = cf->snap;
if (file_exists(fname)) {
- /* We're overwriting an existing file; write out to a new file,
- and, if that succeeds, rename the new file on top of the
- old file. That makes this a "safe save", so that we don't
- lose the old file if we have a problem writing out the new
- file. (If the existing file is the current capture file,
- we *HAVE* to do that, otherwise we're overwriting the file
- from which we're reading the packets that we're writing!) */
- fname_new = ws_strdup_printf("%s~", fname);
- pdh = wtap_dump_open(fname_new, save_format, compression_type, &params,
- &err, &err_info);
+ /* We're overwriting an existing file; write out to a new file,
+ and, if that succeeds, rename the new file on top of the
+ old file. That makes this a "safe save", so that we don't
+ lose the old file if we have a problem writing out the new
+ file. (If the existing file is the current capture file,
+ we *HAVE* to do that, otherwise we're overwriting the file
+ from which we're reading the packets that we're writing!) */
+ fname_new = ws_strdup_printf("%s~", fname);
+ pdh = wtap_dump_open(fname_new, save_format, compression_type, &params,
+ &err, &err_info);
} else {
- pdh = wtap_dump_open(fname, save_format, compression_type, &params,
- &err, &err_info);
+ pdh = wtap_dump_open(fname, save_format, compression_type, &params,
+ &err, &err_info);
}
/* XXX idb_inf is documented to be used until wtap_dump_close. */
g_free(params.idb_inf);
params.idb_inf = NULL;
if (pdh == NULL) {
- cfile_dump_open_failure_alert_box(fname, err, err_info, save_format);
- goto fail;
+ cfile_dump_open_failure_alert_box(fname, err, err_info, save_format);
+ goto fail;
}
/* Add address resolution */
- wtap_dump_set_addrinfo_list(pdh, addr_lists);
+ wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
+
+ /* Iterate through the list of packets, processing the packets we were
+ told to process.
- /* Iterate through the list of packets, processing all the packets. */
+ XXX - we've already called "packet_range_process_init(range)", but
+ "process_specified_records()" will do it again. Fortunately,
+ that's harmless in this case, as we haven't done anything to
+ "range" since we initialized it. */
callback_args.pdh = pdh;
callback_args.fname = fname;
callback_args.file_type = save_format;
- switch (process_specified_records(cf, NULL, "Saving", "packets",
- TRUE, save_record, &callback_args, TRUE)) {
-
- case PSP_FINISHED:
- /* Completed successfully. */
- break;
-
- case PSP_STOPPED:
- /* The user decided to abort the saving.
- If we're writing to a temporary file, remove it.
- XXX - should we do so even if we're not writing to a
- temporary file? */
- wtap_dump_close(pdh, &err, &err_info);
- if (fname_new != NULL)
- ws_unlink(fname_new);
- cf_callback_invoke(cf_cb_file_save_stopped, NULL);
- return CF_WRITE_ABORTED;
+ switch (process_specified_records(cf, range, "Writing", "specified records",
+ TRUE, save_record, &callback_args, TRUE)) {
- case PSP_FAILED:
- /* Error while saving.
- If we're writing to a temporary file, remove it. */
- if (fname_new != NULL)
- ws_unlink(fname_new);
- wtap_dump_close(pdh, &err, &err_info);
- goto fail;
- }
+ case PSP_FINISHED:
+ /* Completed successfully. */
+ break;
- needs_reload = wtap_dump_get_needs_reload(pdh);
+ case PSP_STOPPED:
+ /* The user decided to abort the saving.
+ If we're writing to a temporary file, remove it.
+ XXX - should we do so even if we're not writing to a
+ temporary file? */
+ wtap_dump_close(pdh, &err, &err_info);
+ if (fname_new != NULL) {
+ ws_unlink(fname_new);
+ g_free(fname_new);
+ }
+ return CF_WRITE_ABORTED;
+ break;
- if (!wtap_dump_close(pdh, &err, &err_info)) {
- cfile_close_failure_alert_box(fname, err, err_info);
- goto fail;
+ case PSP_FAILED:
+ /* Error while saving. */
+ wtap_dump_close(pdh, &err, &err_info);
+ /*
+ * We don't report any error from closing; the error that caused
+ * process_specified_records() to fail has already been reported.
+ */
+ goto fail;
}
- how_to_save = SAVE_WITH_WTAP;
- }
+ if (!wtap_dump_close(pdh, &err, &err_info)) {
+ cfile_close_failure_alert_box(fname, err, err_info);
+ goto fail;
+ }
- if (fname_new != NULL) {
- /* We wrote out to fname_new, and should rename it on top of
- fname. fname_new is now closed, so that should be possible even
- on Windows. However, on Windows, we first need to close whatever
- file descriptors we have open for fname. */
-#ifdef _WIN32
- wtap_fdclose(cf->provider.wth);
-#endif
- /* Now do the rename. */
- if (ws_rename(fname_new, fname) == -1) {
- /* Well, the rename failed. */
- cf_rename_failure_alert_box(fname, errno);
-#ifdef _WIN32
- /* Attempt to reopen the random file descriptor using the
- current file's filename. (At this point, the sequential
- file descriptor is closed.) */
- if (!wtap_fdreopen(cf->provider.wth, cf->filename, &err)) {
- /* Oh, well, we're screwed. */
- display_basename = g_filename_display_basename(cf->filename);
- simple_error_message_box(
- file_open_error_message(err, FALSE), display_basename);
- g_free(display_basename);
- }
-#endif
- goto fail;
- }
- }
-
- /* If this was a temporary file, and we didn't do the save by doing
- a move, so the tempoary file is still around under its old name,
- remove it. */
- if (cf->is_tempfile && how_to_save != SAVE_WITH_MOVE) {
- /* If this fails, there's not much we can do, so just ignore errors. */
- ws_unlink(cf->filename);
- }
-
- cf_callback_invoke(cf_cb_file_save_finished, NULL);
- cf->unsaved_changes = FALSE;
-
- if (!dont_reopen) {
- switch (how_to_save) {
-
- case SAVE_WITH_MOVE:
- /* We just moved the file, so the wtap structure refers to the
- new file, and all the information other than the filename
- and the "is temporary" status applies to the new file; just
- update that. */
- g_free(cf->filename);
- cf->filename = g_strdup(fname);
- cf->is_tempfile = FALSE;
- cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
- break;
-
- case SAVE_WITH_COPY:
- /* We just copied the file, so all the information other than
- the wtap structure, the filename, and the "is temporary"
- status applies to the new file; just update that. */
- wtap_close(cf->provider.wth);
- /* Although we're just "copying" and then opening the copy, it will
- try all open_routine readers to open the copy, so we need to
- reset the cfile's open_type. */
- cf->open_type = WTAP_TYPE_AUTO;
- cf->provider.wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
- if (cf->provider.wth == NULL) {
- cfile_open_failure_alert_box(fname, err, err_info);
- cf_close(cf);
- } else {
- g_free(cf->filename);
- cf->filename = g_strdup(fname);
- cf->is_tempfile = FALSE;
- }
- cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
- break;
-
- case SAVE_WITH_WTAP:
- /* Open and read the file we saved to.
-
- XXX - this is somewhat of a waste; we already have the
- packets, all this gets us is updated file type information
- (which we could just stuff into "cf"), and having the new
- file be the one we have opened and from which we're reading
- the data, and it means we have to spend time opening and
- reading the file, which could be a significant amount of
- time if the file is large.
-
- If the capture-file-writing code were to return the
- seek offset of each packet it writes, we could save that
- in the frame_data structure for the frame, and just open
- the file without reading it again...
-
- ...as long as, for gzipped files, the process of writing
- out the file *also* generates the information needed to
- support fast random access to the compressed file. */
- /* rescan_file will cause us to try all open_routines, so
- reset cfile's open_type */
- cf->open_type = WTAP_TYPE_AUTO;
- /* There are cases when SAVE_WITH_WTAP can result in new packets
- being written to the file, e.g ERF records
- In that case, we need to reload the whole file */
- if(needs_reload) {
- if (cf_open(cf, fname, WTAP_TYPE_AUTO, FALSE, &err) == CF_OK) {
- if (cf_read(cf, TRUE) != CF_READ_OK) {
- /* The rescan failed; just close the file. Either
- a dialog was popped up for the failure, so the
- user knows what happened, or they stopped the
- rescan, in which case they know what happened. */
- /* XXX: This is inconsistent with normal open/reload behaviour. */
- cf_close(cf);
- }
+ if (fname_new != NULL) {
+ /* We wrote out to fname_new, and should rename it on top of
+ fname; fname is now closed, so that should be possible even
+ on Windows. Do the rename. */
+ if (ws_rename(fname_new, fname) == -1) {
+ /* Well, the rename failed. */
+ cf_rename_failure_alert_box(fname, errno);
+ goto fail;
}
- }
- else {
- if (rescan_file(cf, fname, FALSE) != CF_READ_OK) {
- /* The rescan failed; just close the file. Either
- a dialog was popped up for the failure, so the
- user knows what happened, or they stopped the
- rescan, in which case they know what happened. */
- cf_close(cf);
- }
- }
- break;
+ g_free(fname_new);
}
- /* If we were told to discard the comments, do so. */
- if (discard_comments) {
- /* Remove SHB comment, if any. */
- wtap_write_shb_comment(cf->provider.wth, NULL);
-
- /* remove all user comments */
- for (framenum = 1; framenum <= cf->count; framenum++) {
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
-
- // XXX: This also ignores non-comment options like verdict
- fdata->has_modified_block = FALSE;
- }
-
- if (cf->provider.frames_modified_blocks) {
- g_tree_destroy(cf->provider.frames_modified_blocks);
- cf->provider.frames_modified_blocks = NULL;
- }
-
- cf->packet_comment_count = 0;
- }
- }
- return CF_WRITE_OK;
+ return CF_WRITE_OK;
fail:
- if (fname_new != NULL) {
- /* We were trying to write to a temporary file; get rid of it if it
- exists. (We don't care whether this fails, as, if it fails,
- there's not much we can do about it. I guess if it failed for
- a reason other than "it doesn't exist", we could report an
- error, so the user knows there's a junk file that they might
- want to clean up.) */
- ws_unlink(fname_new);
- g_free(fname_new);
- }
- cf_callback_invoke(cf_cb_file_save_failed, NULL);
- return CF_WRITE_ERROR;
-}
-
-cf_write_status_t
-cf_export_specified_packets(capture_file *cf, const char *fname,
- packet_range_t *range, guint save_format,
- wtap_compression_type compression_type)
-{
- gchar *fname_new = NULL;
- int err;
- gchar *err_info;
- wtap_dumper *pdh;
- save_callback_args_t callback_args;
- wtap_dump_params params;
- int encap;
-
- packet_range_process_init(range);
-
- /* We're writing out specified packets from the specified capture
- file to another file. Even if all captured packets are to be
- written, don't special-case the operation - read each packet
- and then write it out if it's one of the specified ones. */
-
- /* XXX: what free's params.shb_hdr? */
- wtap_dump_params_init(&params, cf->provider.wth);
-
- /* Determine what file encapsulation type we should use. */
- encap = wtap_dump_file_encap_type(cf->linktypes);
- params.encap = encap;
-
- /* Use the snaplen from cf (XXX - does wtap_dump_params_init handle that?) */
- params.snaplen = cf->snap;
-
- if (file_exists(fname)) {
- /* We're overwriting an existing file; write out to a new file,
- and, if that succeeds, rename the new file on top of the
- old file. That makes this a "safe save", so that we don't
- lose the old file if we have a problem writing out the new
- file. (If the existing file is the current capture file,
- we *HAVE* to do that, otherwise we're overwriting the file
- from which we're reading the packets that we're writing!) */
- fname_new = ws_strdup_printf("%s~", fname);
- pdh = wtap_dump_open(fname_new, save_format, compression_type, &params,
- &err, &err_info);
- } else {
- pdh = wtap_dump_open(fname, save_format, compression_type, &params,
- &err, &err_info);
- }
- /* XXX idb_inf is documented to be used until wtap_dump_close. */
- g_free(params.idb_inf);
- params.idb_inf = NULL;
-
- if (pdh == NULL) {
- cfile_dump_open_failure_alert_box(fname, err, err_info, save_format);
- goto fail;
- }
-
- /* Add address resolution */
- wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
-
- /* Iterate through the list of packets, processing the packets we were
- told to process.
-
- XXX - we've already called "packet_range_process_init(range)", but
- "process_specified_records()" will do it again. Fortunately,
- that's harmless in this case, as we haven't done anything to
- "range" since we initialized it. */
- callback_args.pdh = pdh;
- callback_args.fname = fname;
- callback_args.file_type = save_format;
- switch (process_specified_records(cf, range, "Writing", "specified records",
- TRUE, save_record, &callback_args, TRUE)) {
-
- case PSP_FINISHED:
- /* Completed successfully. */
- break;
-
- case PSP_STOPPED:
- /* The user decided to abort the saving.
- If we're writing to a temporary file, remove it.
- XXX - should we do so even if we're not writing to a
- temporary file? */
- wtap_dump_close(pdh, &err, &err_info);
- if (fname_new != NULL) {
+ if (fname_new != NULL) {
+ /* We were trying to write to a temporary file; get rid of it if it
+ exists. (We don't care whether this fails, as, if it fails,
+ there's not much we can do about it. I guess if it failed for
+ a reason other than "it doesn't exist", we could report an
+ error, so the user knows there's a junk file that they might
+ want to clean up.) */
ws_unlink(fname_new);
g_free(fname_new);
- }
- return CF_WRITE_ABORTED;
- break;
-
- case PSP_FAILED:
- /* Error while saving. */
- wtap_dump_close(pdh, &err, &err_info);
- /*
- * We don't report any error from closing; the error that caused
- * process_specified_records() to fail has already been reported.
- */
- goto fail;
- }
-
- if (!wtap_dump_close(pdh, &err, &err_info)) {
- cfile_close_failure_alert_box(fname, err, err_info);
- goto fail;
- }
-
- if (fname_new != NULL) {
- /* We wrote out to fname_new, and should rename it on top of
- fname; fname is now closed, so that should be possible even
- on Windows. Do the rename. */
- if (ws_rename(fname_new, fname) == -1) {
- /* Well, the rename failed. */
- cf_rename_failure_alert_box(fname, errno);
- goto fail;
}
- g_free(fname_new);
- }
-
- return CF_WRITE_OK;
-
-fail:
- if (fname_new != NULL) {
- /* We were trying to write to a temporary file; get rid of it if it
- exists. (We don't care whether this fails, as, if it fails,
- there's not much we can do about it. I guess if it failed for
- a reason other than "it doesn't exist", we could report an
- error, so the user knows there's a junk file that they might
- want to clean up.) */
- ws_unlink(fname_new);
- g_free(fname_new);
- }
- return CF_WRITE_ERROR;
+ return CF_WRITE_ERROR;
}
/*
@@ -5189,102 +5200,90 @@ fail:
static void
cf_rename_failure_alert_box(const char *filename, int err)
{
- gchar *display_basename;
-
- display_basename = g_filename_display_basename(filename);
- switch (err) {
-
- case ENOENT:
- /* XXX - should check whether the source exists and, if not,
- report it as the problem and, if so, report the destination
- as the problem. */
- simple_error_message_box("The path to the file \"%s\" doesn't exist.",
- display_basename);
- break;
-
- case EACCES:
- /* XXX - if we're doing a rename after a safe save, we should
- probably say something else. */
- simple_error_message_box("You don't have permission to move the capture file to \"%s\".",
- display_basename);
- break;
-
- default:
- /* XXX - this should probably mention both the source and destination
- pathnames. */
- simple_error_message_box("The file \"%s\" could not be moved: %s.",
- display_basename, wtap_strerror(err));
- break;
- }
- g_free(display_basename);
+ gchar *display_basename;
+
+ display_basename = g_filename_display_basename(filename);
+ switch (err) {
+
+ case ENOENT:
+ /* XXX - should check whether the source exists and, if not,
+ report it as the problem and, if so, report the destination
+ as the problem. */
+ simple_error_message_box("The path to the file \"%s\" doesn't exist.",
+ display_basename);
+ break;
+
+ case EACCES:
+ /* XXX - if we're doing a rename after a safe save, we should
+ probably say something else. */
+ simple_error_message_box("You don't have permission to move the capture file to \"%s\".",
+ display_basename);
+ break;
+
+ default:
+ /* XXX - this should probably mention both the source and destination
+ pathnames. */
+ simple_error_message_box("The file \"%s\" could not be moved: %s.",
+ display_basename, wtap_strerror(err));
+ break;
+ }
+ g_free(display_basename);
}
/* Reload the current capture file. */
cf_status_t
-cf_reload(capture_file *cf) {
- gchar *filename;
- gboolean is_tempfile;
- cf_status_t cf_status = CF_OK;
- int err;
-
- if (cf->read_lock) {
- ws_warning("Failing cf_reload(\"%s\") since a read is in progress", cf->filename);
- return CF_ERROR;
- }
-
- /* If the file could be opened, "cf_open()" calls "cf_close()"
- to get rid of state for the old capture file before filling in state
- for the new capture file. "cf_close()" will remove the file if
- it's a temporary file; we don't want that to happen (for one thing,
- it'd prevent subsequent reopens from working). Remember whether it's
- a temporary file, mark it as not being a temporary file, and then
- reopen it as the type of file it was.
-
- Also, "cf_close()" will free "cf->filename", so we must make
- a copy of it first. */
- filename = g_strdup(cf->filename);
- is_tempfile = cf->is_tempfile;
- cf->is_tempfile = FALSE;
- if (cf_open(cf, filename, cf->open_type, is_tempfile, &err) == CF_OK) {
- switch (cf_read(cf, TRUE)) {
-
- case CF_READ_OK:
- case CF_READ_ERROR:
- /* Just because we got an error, that doesn't mean we were unable
- to read any of the file; we handle what we could get from the
- file. */
- break;
-
- case CF_READ_ABORTED:
- /* The user bailed out of re-reading the capture file; the
- capture file has been closed. */
- break;
- }
- } else {
- /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
- Instead, the file was left open, so we should restore "cf->is_tempfile"
- ourselves.
-
- XXX - change the menu? Presumably "cf_open()" will do that;
- make sure it does! */
- cf->is_tempfile = is_tempfile;
- cf_status = CF_ERROR;
- }
- /* "cf_open()" made a copy of the file name we handed it, so
- we should free up our copy. */
- g_free(filename);
- return cf_status;
-}
+cf_reload(capture_file *cf)
+{
+ gchar *filename;
+ gboolean is_tempfile;
+ cf_status_t cf_status = CF_OK;
+ int err;
-/*
- * Editor modelines
- *
- * 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:
- */
+ if (cf->read_lock) {
+ ws_warning("Failing cf_reload(\"%s\") since a read is in progress", cf->filename);
+ return CF_ERROR;
+ }
+
+ /* If the file could be opened, "cf_open()" calls "cf_close()"
+ to get rid of state for the old capture file before filling in state
+ for the new capture file. "cf_close()" will remove the file if
+ it's a temporary file; we don't want that to happen (for one thing,
+ it'd prevent subsequent reopens from working). Remember whether it's
+ a temporary file, mark it as not being a temporary file, and then
+ reopen it as the type of file it was.
+
+ Also, "cf_close()" will free "cf->filename", so we must make
+ a copy of it first. */
+ filename = g_strdup(cf->filename);
+ is_tempfile = cf->is_tempfile;
+ cf->is_tempfile = FALSE;
+ if (cf_open(cf, filename, cf->open_type, is_tempfile, &err) == CF_OK) {
+ switch (cf_read(cf, TRUE)) {
+
+ case CF_READ_OK:
+ case CF_READ_ERROR:
+ /* Just because we got an error, that doesn't mean we were unable
+ to read any of the file; we handle what we could get from the
+ file. */
+ break;
+
+ case CF_READ_ABORTED:
+ /* The user bailed out of re-reading the capture file; the
+ capture file has been closed. */
+ break;
+ }
+ } else {
+ /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
+ Instead, the file was left open, so we should restore "cf->is_tempfile"
+ ourselves.
+
+ XXX - change the menu? Presumably "cf_open()" will do that;
+ make sure it does! */
+ cf->is_tempfile = is_tempfile;
+ cf_status = CF_ERROR;
+ }
+ /* "cf_open()" made a copy of the file name we handed it, so
+ we should free up our copy. */
+ g_free(filename);
+ return cf_status;
+}
diff --git a/file.h b/file.h
index 6117d66574..8dc935c8c4 100644
--- a/file.h
+++ b/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:
- */
diff --git a/frame_tvbuff.c b/frame_tvbuff.c
index cb8426fbf1..1aec22c22d 100644
--- a/frame_tvbuff.c
+++ b/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;
-
- /* 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;
+ 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;
}
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 */
-
- 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 */
+ 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 */
};
/* 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;
-
- 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
- */
-
- 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;
-
- 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;
-
- frame_tvb->buf = NULL;
-
- return tvb;
+ struct tvb_frame *frame_tvb;
+ tvbuff_t *tvb;
+
+ 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
+ */
+
+ 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;
+
+ 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;
+
+ frame_tvb->buf = NULL;
+
+ 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;
-
- 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
- */
-
- 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;
-
- 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;
-
- frame_tvb->buf = NULL;
-
- return tvb;
+ struct tvb_frame *frame_tvb;
+ tvbuff_t *tvb;
+
+ 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
+ */
+
+ 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;
+
+ 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;
+
+ frame_tvb->buf = NULL;
+
+ 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:
- */
diff --git a/frame_tvbuff.h b/frame_tvbuff.h
index 612c100e4f..3f377c13d4 100644
--- a/frame_tvbuff.h
+++ b/frame_tvbuff.h
@@ -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:
- */
diff --git a/mergecap.c b/mergecap.c
index 69147bd9c3..0a05469678 100644
--- a/mergecap.c
+++ b/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;
-
- 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);
+ 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);
}
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;
-
- 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));
+ guint i;
+
+ 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;
- }
- }
- }
- 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_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;
+
+ case MERGE_EVENT_FRAME_TYPE_SELECTED:
+ /* for this event, num = frame_type */
+ if (num == WTAP_ENCAP_PER_PACKET) {
+ /*
+ * Find out why we had to choose WTAP_ENCAP_PER_PACKET.
+ */
+ int first_frame_type, this_frame_type;
+
+ first_frame_type = wtap_file_encap(in_files[0].wth);
+ for (i = 1; i < in_file_count; i++) {
+ this_frame_type = wtap_file_encap(in_files[i].wth);
+ if (first_frame_type != this_frame_type) {
+ fprintf(stderr, "mergecap: multiple frame encapsulation types detected\n");
+ fprintf(stderr, " defaulting to WTAP_ENCAP_PER_PACKET\n");
+ fprintf(stderr, " %s had type %s (%s)\n",
+ in_files[0].filename,
+ wtap_encap_description(first_frame_type),
+ wtap_encap_name(first_frame_type));
+ fprintf(stderr, " %s had type %s (%s)\n",
+ in_files[i].filename,
+ wtap_encap_description(this_frame_type),
+ wtap_encap_name(this_frame_type));
+ break;
+ }
+ }
+ }
+ 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_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;
-
- 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);
-
- /* Early logging command-line initialization. */
- ws_log_parse_args(&argc, argv, vcmdarg_err, 1);
+ 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);
+
+ /* 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);
#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);
-
- /*
- * 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();
+ /* Initialize the version information. */
+ ws_init_version_info("Mergecap (Wireshark)", NULL, NULL, NULL);
+
+ /*
+ * 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;
+ }
+ }
+
+ /* Default to pcapng when writing. */
+ if (file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
+ file_type = wtap_pcapng_file_type_subtype();
+
+ cb.callback_func = merge_callback;
+ cb.data = NULL;
+
+ /* 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;
- }
- 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();
+ }
+ 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;
- }
- break;
-
- case 's':
- snaplen = get_nonzero_guint32(ws_optarg, "snapshot length");
- break;
-
- case 'v':
- verbose = TRUE;
- break;
-
- case 'V':
- show_version();
- goto clean_exit;
- break;
-
- case 'w':
- out_filename = ws_optarg;
- break;
-
- case '?': /* Bad options if GNU getopt */
- switch(ws_optopt) {
- case'F':
- list_capture_types();
- break;
- case'I':
- list_idb_merge_modes();
- break;
- default:
- print_usage(stderr);
- }
- status = MERGE_ERR_INVALID_OPTION;
- goto clean_exit;
- break;
}
- }
-
- /* Default to pcapng when writing. */
- if (file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
- file_type = wtap_pcapng_file_type_subtype();
-
- cb.callback_func = merge_callback;
- cb.data = NULL;
-
- /* 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;
- }
+
+ /* 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:
- */
diff --git a/randpkt.c b/randpkt.c
index ec02aa800c..6ca5e10316 100644
--- a/randpkt.c
+++ b/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;
-
- 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");
-
- /* 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);
-
- fprintf(output, "\nIf type is not specified, a random packet will be chosen\n\n");
+ FILE *output;
+ char** abbrev_list;
+ char** longname_list;
+ unsigned i = 0;
+
+ 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");
+
+ /* 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);
+
+ 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 }
- };
-
- 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);
-
- /* Early logging command-line initialization. */
- ws_log_parse_args(&argc, argv, vcmdarg_err, INVALID_OPTION);
-
- /*
- * 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);
- }
-
- init_report_message("randpkt", &randpkt_report_routines);
-
- wtap_init(TRUE);
+ 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);
+
+ /* 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);
+
+ /*
+ * 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);
+ }
+
+ init_report_message("randpkt", &randpkt_report_routines);
+
+ 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;
-
- 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 'h':
- usage(FALSE);
- goto clean_exit;
- break;
-
- case 'r':
- allrandom = TRUE;
- 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;
- }
-
- 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;
- }
-
- 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;
-
- while (produce_count-- > 0) {
- randpkt_loop(example, 1, 0);
- produce_type = randpkt_parse_type(NULL);
-
- 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;
- }
+ 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 't': /* type of packet to produce */
+ type = g_strdup(ws_optarg);
+ break;
+
+ case 'h':
+ usage(FALSE);
+ goto clean_exit;
+ break;
+
+ case 'r':
+ allrandom = TRUE;
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+
+ while (produce_count-- > 0) {
+ randpkt_loop(example, 1, 0);
+ produce_type = randpkt_parse_type(NULL);
+
+ 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;
+ }
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:
- */
diff --git a/ringbuffer.c b/ringbuffer.c
index ec99c6871b..ff2b42e2c0 100644
--- a/ringbuffer.c
+++ b/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 */
-
- 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 */
+ 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 */
+
+ 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;
-
- 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;
+ ws_statb64 statb;
+ size_t i;
+
+ 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;
+ }
+ }
}
- }
}
- }
- g_mutex_unlock(&rb_data.mutex);
+ 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;
-
- 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;
- }
+ 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;
+ }
+
+ 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;
- }
-
- 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);
- 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(buffer);
+
+ /* delete the original file only if compression succeeds */
+ if (delete_org_file) {
+ ws_unlink(name);
+ CleanupOldCap(name);
+ }
+ g_free(name);
+ return 0;
}
/*
* thread to compress capture file
*/
-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;
-
- if (rfile->name != NULL) {
- if (rb_data.unlimited == FALSE) {
- /* remove old file (if any, so ignore error) */
- ws_unlink(rfile->name);
- }
+ 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);
+ }
#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);
-
- snprintf(filenum, sizeof(filenum), "%05u", (rb_data.curr_file_num + 1) % RINGBUFFER_MAX_NUM_FILES);
- tm = localtime(&current_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;
- }
-
- 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;
- }
-
- return rb_data.fd;
+ current_time = time(NULL);
+
+ snprintf(filenum, sizeof(filenum), "%05u", (rb_data.curr_file_num + 1) % RINGBUFFER_MAX_NUM_FILES);
+ tm = localtime(&current_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;
+ }
+
+ 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;
+ }
+
+ 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;
-
- 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);
+ 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;
- }
- g_free(save_file);
- save_file = NULL;
-
- /* 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;
+ rb_data.nametimenum = has_nametimenum;
+ rb_data.unlimited = FALSE;
+ rb_data.fd = -1;
+ rb_data.pdh = NULL;
+ rb_data.io_buffer = NULL;
+ rb_data.group_read_access = group_read_access;
+ rb_data.name_h = NULL;
+ rb_data.compress_type = compress_type;
+ g_mutex_init(&rb_data.mutex);
+
+ /* just to be sure ... */
+ if (num_files <= RINGBUFFER_MAX_NUM_FILES) {
+ rb_data.num_files = num_files;
+ } else {
+ rb_data.num_files = RINGBUFFER_MAX_NUM_FILES;
+ }
+
+ /* Check file name */
+ if (capfile_name == NULL) {
+ /* ringbuffer does not work with temporary files! */
+ return -1;
+ }
+
+ /* set file name prefix/suffix */
+
+ save_file = g_strdup(capfile_name);
+ last_pathsep = strrchr(save_file, G_DIR_SEPARATOR);
+ pfx = strrchr(save_file,'.');
+ if (pfx != NULL && (last_pathsep == NULL || pfx > last_pathsep)) {
+ /* The pathname has a "." in it, and it's in the last component
+ of the pathname (because there is either only one component,
+ i.e. last_pathsep is null as there are no path separators,
+ or the "." is after the path separator before the last
+ component.
+
+ Treat it as a separator between the rest of the file name and
+ the file name suffix, and arrange that the names given to the
+ ring buffer files have the specified suffix, i.e. put the
+ changing part of the name *before* the suffix. */
+ pfx[0] = '\0';
+ rb_data.fprefix = g_strdup(save_file);
+ pfx[0] = '.'; /* restore capfile_name */
+ rb_data.fsuffix = g_strdup(pfx);
+ } else {
+ /* Either there's no "." in the pathname, or it's in a directory
+ component, so the last component has no suffix. */
+ rb_data.fprefix = g_strdup(save_file);
+ rb_data.fsuffix = NULL;
+ }
+ g_free(save_file);
+ save_file = NULL;
+
+ /* 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 (!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 (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;
+ }
}
- }
- 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;
-
- 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;
- }
+ 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;
+ }
+ }
+ 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;
- }
+ /* 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);
- }
+ 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;
+ 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.name_h != NULL) {
+ if (EOF == fclose(rb_data.name_h)) {
+ /* Can't really do much about this, can we? */
+ }
}
- }
- /* free the memory */
- ringbuf_free();
+ /* 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:
- */
diff --git a/ringbuffer.h b/ringbuffer.h
index 07df4c2587..b9d0187093 100644
--- a/ringbuffer.h
+++ b/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:
- */
diff --git a/sharkd.c b/sharkd.c
index 3a9cf40363..a0298d2120 100644
--- a/sharkd.c
+++ b/sharkd.c
@@ -77,391 +77,392 @@ static void sharkd_cmdarg_err(const char *msg_format, va_list ap);
static void sharkd_cmdarg_err_cont(const char *msg_format, va_list ap);
static void
-print_current_user(void) {
- gchar *cur_user, *cur_group;
-
- if (started_with_special_privs()) {
- cur_user = get_cur_username();
- cur_group = get_cur_groupname();
- fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
- cur_user, cur_group);
- g_free(cur_user);
- g_free(cur_group);
- if (running_with_special_privs()) {
- fprintf(stderr, " This could be dangerous.");
+print_current_user(void)
+{
+ gchar *cur_user, *cur_group;
+
+ if (started_with_special_privs()) {
+ cur_user = get_cur_username();
+ cur_group = get_cur_groupname();
+ fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
+ cur_user, cur_group);
+ g_free(cur_user);
+ g_free(cur_group);
+ if (running_with_special_privs()) {
+ fprintf(stderr, " This could be dangerous.");
+ }
+ fprintf(stderr, "\n");
}
- fprintf(stderr, "\n");
- }
}
int
main(int argc, char *argv[])
{
- char *init_progfile_dir_error;
-
- char *err_msg = NULL;
- e_prefs *prefs_p;
- int ret = EXIT_SUCCESS;
- static const struct report_message_routines sharkd_report_routines = {
- failure_message,
- failure_message,
- open_failure_message,
- read_failure_message,
- write_failure_message,
- cfile_open_failure_message,
- cfile_dump_open_failure_message,
- cfile_read_failure_message,
- cfile_write_failure_message,
- cfile_close_failure_message
- };
-
- cmdarg_err_init(sharkd_cmdarg_err, sharkd_cmdarg_err_cont);
-
- /* Initialize log handler early so we can have proper logging during startup. */
- ws_log_init("sharkd", vcmdarg_err);
-
- /* Early logging command-line initialization. */
- ws_log_parse_args(&argc, argv, vcmdarg_err, INIT_FAILED);
-
- /*
- * Get credential information for later use, and drop privileges
- * before doing anything else.
- * Let the user know if anything happened.
- */
- init_process_policies();
- relinquish_special_privs_perm();
- print_current_user();
-
- /*
- * Attempt to get the pathname of the executable file.
- */
- init_progfile_dir_error = init_progfile_dir(argv[0]);
- if (init_progfile_dir_error != NULL) {
- fprintf(stderr, "sharkd: Can't get pathname of sharkd program: %s.\n",
- init_progfile_dir_error);
- }
-
- /* Initialize the version information. */
- ws_init_version_info("Sharkd (Wireshark)", NULL,
- epan_get_compiled_version_info,
- epan_get_runtime_version_info);
-
- if (sharkd_init(argc, argv) < 0)
- {
- printf("cannot initialize sharkd\n");
- ret = INIT_FAILED;
- goto clean_exit;
- }
-
- init_report_message("sharkd", &sharkd_report_routines);
-
- timestamp_set_type(TS_RELATIVE);
- timestamp_set_precision(TS_PREC_AUTO);
- timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
-
- /*
- * Libwiretap must be initialized before libwireshark is, so that
- * dissection-time handlers for file-type-dependent blocks can
- * register using the file type/subtype value for the file type.
- */
- wtap_init(TRUE);
-
- /* Register all dissectors; we must do this before checking for the
- "-G" flag, as the "-G" flag dumps information registered by the
- dissectors, and we must do it before we read the preferences, in
- case any dissectors register preferences. */
- if (!epan_init(NULL, NULL, TRUE)) {
- ret = EPAN_INIT_FAIL;
- goto clean_exit;
- }
-
- codecs_init();
-
- /* Load libwireshark settings from the current profile. */
- prefs_p = epan_load_settings();
-
- read_filter_list(CFILTER_LIST);
-
- if (!color_filters_init(&err_msg, NULL)) {
- fprintf(stderr, "%s\n", err_msg);
- g_free(err_msg);
- }
-
- cap_file_init(&cfile);
-
- /* Notify all registered modules that have had any of their preferences
- changed either from one of the preferences file or from the command
- line that their preferences have changed. */
- prefs_apply_all();
-
- /* Build the column format array */
- build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
+ char *init_progfile_dir_error;
+
+ char *err_msg = NULL;
+ e_prefs *prefs_p;
+ int ret = EXIT_SUCCESS;
+ static const struct report_message_routines sharkd_report_routines = {
+ failure_message,
+ failure_message,
+ open_failure_message,
+ read_failure_message,
+ write_failure_message,
+ cfile_open_failure_message,
+ cfile_dump_open_failure_message,
+ cfile_read_failure_message,
+ cfile_write_failure_message,
+ cfile_close_failure_message
+ };
+
+ cmdarg_err_init(sharkd_cmdarg_err, sharkd_cmdarg_err_cont);
+
+ /* Initialize log handler early so we can have proper logging during startup. */
+ ws_log_init("sharkd", vcmdarg_err);
+
+ /* Early logging command-line initialization. */
+ ws_log_parse_args(&argc, argv, vcmdarg_err, INIT_FAILED);
+
+ /*
+ * Get credential information for later use, and drop privileges
+ * before doing anything else.
+ * Let the user know if anything happened.
+ */
+ init_process_policies();
+ relinquish_special_privs_perm();
+ print_current_user();
+
+ /*
+ * Attempt to get the pathname of the executable file.
+ */
+ init_progfile_dir_error = init_progfile_dir(argv[0]);
+ if (init_progfile_dir_error != NULL) {
+ fprintf(stderr, "sharkd: Can't get pathname of sharkd program: %s.\n",
+ init_progfile_dir_error);
+ }
+
+ /* Initialize the version information. */
+ ws_init_version_info("Sharkd (Wireshark)", NULL,
+ epan_get_compiled_version_info,
+ epan_get_runtime_version_info);
+
+ if (sharkd_init(argc, argv) < 0)
+ {
+ printf("cannot initialize sharkd\n");
+ ret = INIT_FAILED;
+ goto clean_exit;
+ }
+
+ init_report_message("sharkd", &sharkd_report_routines);
+
+ timestamp_set_type(TS_RELATIVE);
+ timestamp_set_precision(TS_PREC_AUTO);
+ timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
+
+ /*
+ * Libwiretap must be initialized before libwireshark is, so that
+ * dissection-time handlers for file-type-dependent blocks can
+ * register using the file type/subtype value for the file type.
+ */
+ wtap_init(TRUE);
+
+ /* Register all dissectors; we must do this before checking for the
+ "-G" flag, as the "-G" flag dumps information registered by the
+ dissectors, and we must do it before we read the preferences, in
+ case any dissectors register preferences. */
+ if (!epan_init(NULL, NULL, TRUE)) {
+ ret = EPAN_INIT_FAIL;
+ goto clean_exit;
+ }
+
+ codecs_init();
+
+ /* Load libwireshark settings from the current profile. */
+ prefs_p = epan_load_settings();
+
+ read_filter_list(CFILTER_LIST);
+
+ if (!color_filters_init(&err_msg, NULL)) {
+ fprintf(stderr, "%s\n", err_msg);
+ g_free(err_msg);
+ }
+
+ cap_file_init(&cfile);
+
+ /* Notify all registered modules that have had any of their preferences
+ changed either from one of the preferences file or from the command
+ line that their preferences have changed. */
+ prefs_apply_all();
+
+ /* Build the column format array */
+ build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
#ifdef HAVE_MAXMINDDB
- /* mmdbresolve is started from mmdb_resolve_start(), which is called from epan_load_settings via: read_prefs -> (...) uat_load_all -> maxmind_db_post_update_cb.
- * Need to stop it, otherwise all sharkd will have same mmdbresolve process, including pipe descriptors to read and write. */
- uat_clear(uat_get_table_by_name("MaxMind Database Paths"));
+ /* mmdbresolve is started from mmdb_resolve_start(), which is called from epan_load_settings via: read_prefs -> (...) uat_load_all -> maxmind_db_post_update_cb.
+ * Need to stop it, otherwise all sharkd will have same mmdbresolve process, including pipe descriptors to read and write. */
+ uat_clear(uat_get_table_by_name("MaxMind Database Paths"));
#endif
- ret = sharkd_loop(argc, argv);
+ ret = sharkd_loop(argc, argv);
clean_exit:
- col_cleanup(&cfile.cinfo);
- free_filter_lists();
- codecs_cleanup();
- wtap_cleanup();
- free_progdirs();
- return ret;
+ col_cleanup(&cfile.cinfo);
+ free_filter_lists();
+ codecs_cleanup();
+ wtap_cleanup();
+ free_progdirs();
+ return ret;
}
static const nstime_t *
sharkd_get_frame_ts(struct packet_provider_data *prov, guint32 frame_num)
{
- if (prov->ref && prov->ref->num == frame_num)
- return &prov->ref->abs_ts;
+ if (prov->ref && prov->ref->num == frame_num)
+ return &prov->ref->abs_ts;
- if (prov->prev_dis && prov->prev_dis->num == frame_num)
- return &prov->prev_dis->abs_ts;
+ if (prov->prev_dis && prov->prev_dis->num == frame_num)
+ return &prov->prev_dis->abs_ts;
- if (prov->prev_cap && prov->prev_cap->num == frame_num)
- return &prov->prev_cap->abs_ts;
+ if (prov->prev_cap && prov->prev_cap->num == frame_num)
+ return &prov->prev_cap->abs_ts;
- if (prov->frames) {
- frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
+ if (prov->frames) {
+ frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
- return (fd) ? &fd->abs_ts : NULL;
- }
+ return (fd) ? &fd->abs_ts : NULL;
+ }
- return NULL;
+ return NULL;
}
static epan_t *
sharkd_epan_new(capture_file *cf)
{
- static const struct packet_provider_funcs funcs = {
- sharkd_get_frame_ts,
- cap_file_provider_get_interface_name,
- cap_file_provider_get_interface_description,
- cap_file_provider_get_modified_block
- };
-
- return epan_new(&cf->provider, &funcs);
+ static const struct packet_provider_funcs funcs = {
+ sharkd_get_frame_ts,
+ cap_file_provider_get_interface_name,
+ cap_file_provider_get_interface_description,
+ cap_file_provider_get_modified_block
+ };
+
+ return epan_new(&cf->provider, &funcs);
}
static gboolean
process_packet(capture_file *cf, epan_dissect_t *edt,
- gint64 offset, wtap_rec *rec, Buffer *buf)
+ gint64 offset, wtap_rec *rec, Buffer *buf)
{
- frame_data fdlocal;
- gboolean passed;
-
- /* If we're not running a display filter and we're not printing any
- packet information, we don't need to do a dissection. This means
- that all packets can be marked as 'passed'. */
- passed = TRUE;
-
- /* The frame number of this packet, if we add it to the set of frames,
- would be one more than the count of frames in the file so far. */
- frame_data_init(&fdlocal, cf->count + 1, rec, offset, cum_bytes);
-
- /* If we're going to print packet information, or we're going to
- run a read filter, or display filter, or we're going to process taps, set up to
- do a dissection and do so. */
- if (edt) {
- if (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
- gbl_resolv_flags.transport_name)
- /* Grab any resolved addresses */
- host_name_lookup_process();
-
- /* If we're running a read filter, prime the epan_dissect_t with that
- filter. */
- if (cf->rfcode)
- epan_dissect_prime_with_dfilter(edt, cf->rfcode);
-
- if (cf->dfcode)
- epan_dissect_prime_with_dfilter(edt, cf->dfcode);
-
- /* This is the first and only pass, so prime the epan_dissect_t
- with the hfids postdissectors want on the first pass. */
- prime_epan_dissect_with_postdissector_wanted_hfids(edt);
-
- frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
- &cf->provider.ref, cf->provider.prev_dis);
- if (cf->provider.ref == &fdlocal) {
- ref_frame = fdlocal;
- cf->provider.ref = &ref_frame;
- }
+ frame_data fdlocal;
+ gboolean passed;
- epan_dissect_run(edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, &fdlocal, buf),
- &fdlocal, NULL);
+ /* If we're not running a display filter and we're not printing any
+ packet information, we don't need to do a dissection. This means
+ that all packets can be marked as 'passed'. */
+ passed = TRUE;
- /* Run the read filter if we have one. */
- if (cf->rfcode)
- passed = dfilter_apply_edt(cf->rfcode, edt);
- }
+ /* The frame number of this packet, if we add it to the set of frames,
+ would be one more than the count of frames in the file so far. */
+ frame_data_init(&fdlocal, cf->count + 1, rec, offset, cum_bytes);
- if (passed) {
- frame_data_set_after_dissect(&fdlocal, &cum_bytes);
- cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
+ /* If we're going to print packet information, or we're going to
+ run a read filter, or display filter, or we're going to process taps, set up to
+ do a dissection and do so. */
+ if (edt) {
+ if (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
+ gbl_resolv_flags.transport_name)
+ /* Grab any resolved addresses */
+ host_name_lookup_process();
+
+ /* If we're running a read filter, prime the epan_dissect_t with that
+ filter. */
+ if (cf->rfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->rfcode);
+
+ if (cf->dfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->dfcode);
+
+ /* This is the first and only pass, so prime the epan_dissect_t
+ with the hfids postdissectors want on the first pass. */
+ prime_epan_dissect_with_postdissector_wanted_hfids(edt);
+
+ frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
+ &cf->provider.ref, cf->provider.prev_dis);
+ if (cf->provider.ref == &fdlocal) {
+ ref_frame = fdlocal;
+ cf->provider.ref = &ref_frame;
+ }
- /* If we're not doing dissection then there won't be any dependent frames.
- * More importantly, edt.pi.dependent_frames won't be initialized because
- * epan hasn't been initialized.
- * if we *are* doing dissection, then mark the dependent frames, but only
- * if a display filter was given and it matches this packet.
- */
- if (edt && cf->dfcode) {
- if (dfilter_apply_edt(cf->dfcode, edt)) {
- g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
- }
+ epan_dissect_run(edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, &fdlocal, buf),
+ &fdlocal, NULL);
+
+ /* Run the read filter if we have one. */
+ if (cf->rfcode)
+ passed = dfilter_apply_edt(cf->rfcode, edt);
}
- cf->count++;
- } else {
- /* if we don't add it to the frame_data_sequence, clean it up right now
- * to avoid leaks */
- frame_data_destroy(&fdlocal);
- }
+ if (passed) {
+ frame_data_set_after_dissect(&fdlocal, &cum_bytes);
+ cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
+
+ /* If we're not doing dissection then there won't be any dependent frames.
+ * More importantly, edt.pi.dependent_frames won't be initialized because
+ * epan hasn't been initialized.
+ * if we *are* doing dissection, then mark the dependent frames, but only
+ * if a display filter was given and it matches this packet.
+ */
+ if (edt && cf->dfcode) {
+ if (dfilter_apply_edt(cf->dfcode, edt)) {
+ g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
+ }
+ }
+
+ cf->count++;
+ } else {
+ /* if we don't add it to the frame_data_sequence, clean it up right now
+ * to avoid leaks */
+ frame_data_destroy(&fdlocal);
+ }
- if (edt)
- epan_dissect_reset(edt);
+ if (edt)
+ epan_dissect_reset(edt);
- return passed;
+ return passed;
}
static int
load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
{
- int err;
- gchar *err_info = NULL;
- gint64 data_offset;
- wtap_rec rec;
- Buffer buf;
- epan_dissect_t *edt = NULL;
-
- {
- /* Allocate a frame_data_sequence for all the frames. */
- cf->provider.frames = new_frame_data_sequence();
+ int err;
+ gchar *err_info = NULL;
+ gint64 data_offset;
+ wtap_rec rec;
+ Buffer buf;
+ epan_dissect_t *edt = NULL;
{
- gboolean create_proto_tree;
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a read filter;
- *
- * we're going to apply a display filter;
- *
- * a postdissector wants field values or protocols
- * on the first pass.
- */
- create_proto_tree =
- (cf->rfcode != NULL || cf->dfcode != NULL || postdissectors_want_hfids());
-
- /* We're not going to display the protocol tree on this pass,
- so it's not going to be "visible". */
- edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
- }
-
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
+ /* Allocate a frame_data_sequence for all the frames. */
+ cf->provider.frames = new_frame_data_sequence();
+
+ {
+ gboolean create_proto_tree;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a read filter;
+ *
+ * we're going to apply a display filter;
+ *
+ * a postdissector wants field values or protocols
+ * on the first pass.
+ */
+ create_proto_tree =
+ (cf->rfcode != NULL || cf->dfcode != NULL || postdissectors_want_hfids());
+
+ /* We're not going to display the protocol tree on this pass,
+ so it's not going to be "visible". */
+ edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
+ }
- while (wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info, &data_offset)) {
- if (process_packet(cf, edt, data_offset, &rec, &buf)) {
- wtap_rec_reset(&rec);
- /* Stop reading if we have the maximum number of packets;
- * When the -c option has not been used, max_packet_count
- * starts at 0, which practically means, never stop reading.
- * (unless we roll over max_packet_count ?)
- */
- if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
- err = 0; /* This is not an error */
- break;
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+
+ while (wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info, &data_offset)) {
+ if (process_packet(cf, edt, data_offset, &rec, &buf)) {
+ wtap_rec_reset(&rec);
+ /* Stop reading if we have the maximum number of packets;
+ * When the -c option has not been used, max_packet_count
+ * starts at 0, which practically means, never stop reading.
+ * (unless we roll over max_packet_count ?)
+ */
+ if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
+ err = 0; /* This is not an error */
+ break;
+ }
+ }
}
- }
- }
- if (edt) {
- epan_dissect_free(edt);
- edt = NULL;
- }
+ if (edt) {
+ epan_dissect_free(edt);
+ edt = NULL;
+ }
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
- /* Close the sequential I/O side, to free up memory it requires. */
- wtap_sequential_close(cf->provider.wth);
+ /* Close the sequential I/O side, to free up memory it requires. */
+ wtap_sequential_close(cf->provider.wth);
- /* Allow the protocol dissectors to free up memory that they
- * don't need after the sequential run-through of the packets. */
- postseq_cleanup_all_protocols();
+ /* Allow the protocol dissectors to free up memory that they
+ * don't need after the sequential run-through of the packets. */
+ postseq_cleanup_all_protocols();
- cf->provider.prev_dis = NULL;
- cf->provider.prev_cap = NULL;
- }
+ cf->provider.prev_dis = NULL;
+ cf->provider.prev_cap = NULL;
+ }
- if (err != 0) {
- cfile_read_failure_message(cf->filename, err, err_info);
- }
+ if (err != 0) {
+ cfile_read_failure_message(cf->filename, err, err_info);
+ }
- return err;
+ return err;
}
cf_status_t
cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
- wtap *wth;
- gchar *err_info;
+ wtap *wth;
+ gchar *err_info;
- wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
- if (wth == NULL)
- goto fail;
+ wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
+ if (wth == NULL)
+ goto fail;
- /* The open succeeded. Fill in the information for this file. */
+ /* The open succeeded. Fill in the information for this file. */
- cf->provider.wth = wth;
- cf->f_datalen = 0; /* not used, but set it anyway */
+ cf->provider.wth = wth;
+ cf->f_datalen = 0; /* not used, but set it anyway */
- /* Set the file name because we need it to set the follow stream filter.
- XXX - is that still true? We need it for other reasons, though,
- in any case. */
- cf->filename = g_strdup(fname);
+ /* Set the file name because we need it to set the follow stream filter.
+ XXX - is that still true? We need it for other reasons, though,
+ in any case. */
+ cf->filename = g_strdup(fname);
- /* Indicate whether it's a permanent or temporary file. */
- cf->is_tempfile = is_tempfile;
+ /* Indicate whether it's a permanent or temporary file. */
+ cf->is_tempfile = is_tempfile;
- /* No user changes yet. */
- cf->unsaved_changes = FALSE;
+ /* No user changes yet. */
+ cf->unsaved_changes = FALSE;
- cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
- cf->open_type = type;
- cf->count = 0;
- cf->drops_known = FALSE;
- cf->drops = 0;
- cf->snap = wtap_snapshot_length(cf->provider.wth);
- nstime_set_zero(&cf->elapsed_time);
- cf->provider.ref = NULL;
- cf->provider.prev_dis = NULL;
- cf->provider.prev_cap = NULL;
+ cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
+ cf->open_type = type;
+ cf->count = 0;
+ cf->drops_known = FALSE;
+ cf->drops = 0;
+ cf->snap = wtap_snapshot_length(cf->provider.wth);
+ nstime_set_zero(&cf->elapsed_time);
+ cf->provider.ref = NULL;
+ cf->provider.prev_dis = NULL;
+ cf->provider.prev_cap = NULL;
- /* Create new epan session for dissection. */
- epan_free(cf->epan);
- cf->epan = sharkd_epan_new(cf);
+ /* Create new epan session for dissection. */
+ epan_free(cf->epan);
+ cf->epan = sharkd_epan_new(cf);
- cf->state = FILE_READ_IN_PROGRESS;
+ cf->state = FILE_READ_IN_PROGRESS;
- wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
- wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
- wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
+ wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
+ wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
+ wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
- return CF_OK;
+ return CF_OK;
fail:
- cfile_open_failure_message(fname, *err, err_info);
- return CF_ERROR;
+ cfile_open_failure_message(fname, *err, err_info);
+ return CF_ERROR;
}
/*
@@ -470,9 +471,9 @@ fail:
static void
sharkd_cmdarg_err(const char *msg_format, va_list ap)
{
- fprintf(stderr, "sharkd: ");
- vfprintf(stderr, msg_format, ap);
- fprintf(stderr, "\n");
+ fprintf(stderr, "sharkd: ");
+ vfprintf(stderr, msg_format, ap);
+ fprintf(stderr, "\n");
}
/*
@@ -481,232 +482,232 @@ sharkd_cmdarg_err(const char *msg_format, va_list ap)
static void
sharkd_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");
}
cf_status_t
sharkd_cf_open(const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
- return cf_open(&cfile, fname, type, is_tempfile, err);
+ return cf_open(&cfile, fname, type, is_tempfile, err);
}
int
sharkd_load_cap_file(void)
{
- return load_cap_file(&cfile, 0, 0);
+ return load_cap_file(&cfile, 0, 0);
}
frame_data *
sharkd_get_frame(guint32 framenum)
{
- return frame_data_sequence_find(cfile.provider.frames, framenum);
+ return frame_data_sequence_find(cfile.provider.frames, framenum);
}
enum dissect_request_status
sharkd_dissect_request(guint32 framenum, guint32 frame_ref_num,
- guint32 prev_dis_num, wtap_rec *rec, Buffer *buf,
- column_info *cinfo, guint32 dissect_flags,
- sharkd_dissect_func_t cb, void *data,
- int *err, gchar **err_info)
+ guint32 prev_dis_num, wtap_rec *rec, Buffer *buf,
+ column_info *cinfo, guint32 dissect_flags,
+ sharkd_dissect_func_t cb, void *data,
+ int *err, gchar **err_info)
{
- frame_data *fdata;
- epan_dissect_t edt;
- gboolean create_proto_tree;
-
- fdata = sharkd_get_frame(framenum);
- if (fdata == NULL)
- return DISSECT_REQUEST_NO_SUCH_FRAME;
-
- if (!wtap_seek_read(cfile.provider.wth, fdata->file_off, rec, buf, err, err_info)) {
- if (cinfo != NULL)
- col_fill_in_error(cinfo, fdata, FALSE, FALSE /* fill_fd_columns */);
- return DISSECT_REQUEST_READ_ERROR; /* error reading the record */
- }
-
- create_proto_tree = ((dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE) ||
- ((dissect_flags & SHARKD_DISSECT_FLAG_COLOR) && color_filters_used()) ||
- (cinfo && have_custom_cols(cinfo)));
- epan_dissect_init(&edt, cfile.epan, create_proto_tree, (dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE));
-
- if (dissect_flags & SHARKD_DISSECT_FLAG_COLOR) {
- color_filters_prime_edt(&edt);
- fdata->need_colorize = 1;
- }
-
- if (cinfo)
- col_custom_prime_edt(&edt, cinfo);
-
- /*
- * XXX - need to catch an OutOfMemoryError exception and
- * attempt to recover from it.
- */
- fdata->ref_time = (framenum == frame_ref_num);
- fdata->frame_ref_num = frame_ref_num;
- fdata->prev_dis_num = prev_dis_num;
- epan_dissect_run(&edt, cfile.cd_t, rec,
- frame_tvbuff_new_buffer(&cfile.provider, fdata, buf),
- fdata, cinfo);
-
- if (cinfo) {
- /* "Stringify" non frame_data vals */
- epan_dissect_fill_in_columns(&edt, FALSE, TRUE/* fill_fd_columns */);
- }
-
- cb(&edt, (dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE) ? edt.tree : NULL,
- cinfo, (dissect_flags & SHARKD_DISSECT_FLAG_BYTES) ? edt.pi.data_src : NULL,
- data);
-
- wtap_rec_reset(rec);
- epan_dissect_cleanup(&edt);
- return DISSECT_REQUEST_SUCCESS;
+ frame_data *fdata;
+ epan_dissect_t edt;
+ gboolean create_proto_tree;
+
+ fdata = sharkd_get_frame(framenum);
+ if (fdata == NULL)
+ return DISSECT_REQUEST_NO_SUCH_FRAME;
+
+ if (!wtap_seek_read(cfile.provider.wth, fdata->file_off, rec, buf, err, err_info)) {
+ if (cinfo != NULL)
+ col_fill_in_error(cinfo, fdata, FALSE, FALSE /* fill_fd_columns */);
+ return DISSECT_REQUEST_READ_ERROR; /* error reading the record */
+ }
+
+ create_proto_tree = ((dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE) ||
+ ((dissect_flags & SHARKD_DISSECT_FLAG_COLOR) && color_filters_used()) ||
+ (cinfo && have_custom_cols(cinfo)));
+ epan_dissect_init(&edt, cfile.epan, create_proto_tree, (dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE));
+
+ if (dissect_flags & SHARKD_DISSECT_FLAG_COLOR) {
+ color_filters_prime_edt(&edt);
+ fdata->need_colorize = 1;
+ }
+
+ if (cinfo)
+ col_custom_prime_edt(&edt, cinfo);
+
+ /*
+ * XXX - need to catch an OutOfMemoryError exception and
+ * attempt to recover from it.
+ */
+ fdata->ref_time = (framenum == frame_ref_num);
+ fdata->frame_ref_num = frame_ref_num;
+ fdata->prev_dis_num = prev_dis_num;
+ epan_dissect_run(&edt, cfile.cd_t, rec,
+ frame_tvbuff_new_buffer(&cfile.provider, fdata, buf),
+ fdata, cinfo);
+
+ if (cinfo) {
+ /* "Stringify" non frame_data vals */
+ epan_dissect_fill_in_columns(&edt, FALSE, TRUE/* fill_fd_columns */);
+ }
+
+ cb(&edt, (dissect_flags & SHARKD_DISSECT_FLAG_PROTO_TREE) ? edt.tree : NULL,
+ cinfo, (dissect_flags & SHARKD_DISSECT_FLAG_BYTES) ? edt.pi.data_src : NULL,
+ data);
+
+ wtap_rec_reset(rec);
+ epan_dissect_cleanup(&edt);
+ return DISSECT_REQUEST_SUCCESS;
}
int
sharkd_retap(void)
{
- guint32 framenum;
- frame_data *fdata;
- Buffer buf;
- wtap_rec rec;
- int err;
- char *err_info = NULL;
-
- guint tap_flags;
- gboolean create_proto_tree;
- epan_dissect_t edt;
- column_info *cinfo;
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- /* If any tap listeners require the columns, construct them. */
- cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cfile.cinfo : NULL;
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree.
- */
- create_proto_tree =
- (have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
-
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
- epan_dissect_init(&edt, cfile.epan, create_proto_tree, FALSE);
-
- reset_tap_listeners();
-
- for (framenum = 1; framenum <= cfile.count; framenum++) {
- fdata = sharkd_get_frame(framenum);
+ guint32 framenum;
+ frame_data *fdata;
+ Buffer buf;
+ wtap_rec rec;
+ int err;
+ char *err_info = NULL;
+
+ guint tap_flags;
+ gboolean create_proto_tree;
+ epan_dissect_t edt;
+ column_info *cinfo;
+
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
+
+ /* If any tap listeners require the columns, construct them. */
+ cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cfile.cinfo : NULL;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree.
+ */
+ create_proto_tree =
+ (have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
+
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+ epan_dissect_init(&edt, cfile.epan, create_proto_tree, FALSE);
+
+ reset_tap_listeners();
- if (!wtap_seek_read(cfile.provider.wth, fdata->file_off, &rec, &buf, &err, &err_info))
- break;
+ for (framenum = 1; framenum <= cfile.count; framenum++) {
+ fdata = sharkd_get_frame(framenum);
- fdata->ref_time = FALSE;
- fdata->frame_ref_num = (framenum != 1) ? 1 : 0;
- fdata->prev_dis_num = framenum - 1;
- epan_dissect_run_with_taps(&edt, cfile.cd_t, &rec,
- frame_tvbuff_new_buffer(&cfile.provider, fdata, &buf),
- fdata, cinfo);
- wtap_rec_reset(&rec);
- epan_dissect_reset(&edt);
- }
+ if (!wtap_seek_read(cfile.provider.wth, fdata->file_off, &rec, &buf, &err, &err_info))
+ break;
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
- epan_dissect_cleanup(&edt);
+ fdata->ref_time = FALSE;
+ fdata->frame_ref_num = (framenum != 1) ? 1 : 0;
+ fdata->prev_dis_num = framenum - 1;
+ epan_dissect_run_with_taps(&edt, cfile.cd_t, &rec,
+ frame_tvbuff_new_buffer(&cfile.provider, fdata, &buf),
+ fdata, cinfo);
+ wtap_rec_reset(&rec);
+ epan_dissect_reset(&edt);
+ }
- draw_tap_listeners(TRUE);
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+ epan_dissect_cleanup(&edt);
- return 0;
+ draw_tap_listeners(TRUE);
+
+ return 0;
}
int
sharkd_filter(const char *dftext, guint8 **result)
{
- dfilter_t *dfcode = NULL;
+ dfilter_t *dfcode = NULL;
- guint32 framenum, prev_dis_num = 0;
- guint32 frames_count;
- Buffer buf;
- wtap_rec rec;
- int err;
- char *err_info = NULL;
+ guint32 framenum, prev_dis_num = 0;
+ guint32 frames_count;
+ Buffer buf;
+ wtap_rec rec;
+ int err;
+ char *err_info = NULL;
- guint8 *result_bits;
- guint8 passed_bits;
+ guint8 *result_bits;
+ guint8 passed_bits;
- epan_dissect_t edt;
+ epan_dissect_t edt;
- if (!dfilter_compile(dftext, &dfcode, &err_info)) {
- g_free(err_info);
- return -1;
- }
+ if (!dfilter_compile(dftext, &dfcode, &err_info)) {
+ g_free(err_info);
+ return -1;
+ }
- /* if dfilter_compile() success, but (dfcode == NULL) all frames are matching */
- if (dfcode == NULL) {
- *result = NULL;
- return 0;
- }
+ /* if dfilter_compile() success, but (dfcode == NULL) all frames are matching */
+ if (dfcode == NULL) {
+ *result = NULL;
+ return 0;
+ }
- frames_count = cfile.count;
+ frames_count = cfile.count;
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
- epan_dissect_init(&edt, cfile.epan, TRUE, FALSE);
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+ epan_dissect_init(&edt, cfile.epan, TRUE, FALSE);
- passed_bits = 0;
- result_bits = (guint8 *) g_malloc(2 + (frames_count / 8));
+ passed_bits = 0;
+ result_bits = (guint8 *) g_malloc(2 + (frames_count / 8));
- for (framenum = 1; framenum <= frames_count; framenum++) {
- frame_data *fdata = sharkd_get_frame(framenum);
+ for (framenum = 1; framenum <= frames_count; framenum++) {
+ frame_data *fdata = sharkd_get_frame(framenum);
- if ((framenum & 7) == 0) {
- result_bits[(framenum / 8) - 1] = passed_bits;
- passed_bits = 0;
- }
+ if ((framenum & 7) == 0) {
+ result_bits[(framenum / 8) - 1] = passed_bits;
+ passed_bits = 0;
+ }
- if (!wtap_seek_read(cfile.provider.wth, fdata->file_off, &rec, &buf, &err, &err_info))
- break;
+ if (!wtap_seek_read(cfile.provider.wth, fdata->file_off, &rec, &buf, &err, &err_info))
+ break;
- /* frame_data_set_before_dissect */
- epan_dissect_prime_with_dfilter(&edt, dfcode);
+ /* frame_data_set_before_dissect */
+ epan_dissect_prime_with_dfilter(&edt, dfcode);
- fdata->ref_time = FALSE;
- fdata->frame_ref_num = (framenum != 1) ? 1 : 0;
- fdata->prev_dis_num = prev_dis_num;
- epan_dissect_run(&edt, cfile.cd_t, &rec,
- frame_tvbuff_new_buffer(&cfile.provider, fdata, &buf),
- fdata, NULL);
+ fdata->ref_time = FALSE;
+ fdata->frame_ref_num = (framenum != 1) ? 1 : 0;
+ fdata->prev_dis_num = prev_dis_num;
+ epan_dissect_run(&edt, cfile.cd_t, &rec,
+ frame_tvbuff_new_buffer(&cfile.provider, fdata, &buf),
+ fdata, NULL);
- if (dfilter_apply_edt(dfcode, &edt)) {
- passed_bits |= (1 << (framenum % 8));
- prev_dis_num = framenum;
- }
+ if (dfilter_apply_edt(dfcode, &edt)) {
+ passed_bits |= (1 << (framenum % 8));
+ prev_dis_num = framenum;
+ }
- /* if passed or ref -> frame_data_set_after_dissect */
+ /* if passed or ref -> frame_data_set_after_dissect */
- wtap_rec_reset(&rec);
- epan_dissect_reset(&edt);
- }
+ wtap_rec_reset(&rec);
+ epan_dissect_reset(&edt);
+ }
- if ((framenum & 7) == 0)
- framenum--;
- result_bits[framenum / 8] = passed_bits;
+ if ((framenum & 7) == 0)
+ framenum--;
+ result_bits[framenum / 8] = passed_bits;
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
- epan_dissect_cleanup(&edt);
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+ epan_dissect_cleanup(&edt);
- dfilter_free(dfcode);
+ dfilter_free(dfcode);
- *result = result_bits;
+ *result = result_bits;
- return framenum;
+ return framenum;
}
/*
@@ -716,7 +717,7 @@ sharkd_filter(const char *dftext, guint8 **result)
wtap_block_t
sharkd_get_modified_block(const frame_data *fd)
{
- return cap_file_provider_get_modified_block(&cfile.provider, fd);
+ return cap_file_provider_get_modified_block(&cfile.provider, fd);
}
/*
@@ -727,47 +728,34 @@ sharkd_get_modified_block(const frame_data *fd)
wtap_block_t
sharkd_get_packet_block(const frame_data *fd)
{
- if (fd->has_modified_block)
- return wtap_block_ref(cap_file_provider_get_modified_block(&cfile.provider, fd));
- else
- {
- wtap_rec rec; /* Record metadata */
- Buffer buf; /* Record data */
- wtap_block_t block;
- int err;
- gchar *err_info;
+ if (fd->has_modified_block)
+ return wtap_block_ref(cap_file_provider_get_modified_block(&cfile.provider, fd));
+ else
+ {
+ wtap_rec rec; /* Record metadata */
+ Buffer buf; /* Record data */
+ wtap_block_t block;
+ int err;
+ gchar *err_info;
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
- if (!wtap_seek_read(cfile.provider.wth, fd->file_off, &rec, &buf, &err, &err_info))
- { /* XXX, what we can do here? */ }
+ if (!wtap_seek_read(cfile.provider.wth, fd->file_off, &rec, &buf, &err, &err_info))
+ { /* XXX, what we can do here? */ }
- /* rec.block is owned by the record, steal it before it is gone. */
- block = wtap_block_ref(rec.block);
+ /* rec.block is owned by the record, steal it before it is gone. */
+ block = wtap_block_ref(rec.block);
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
- return block;
- }
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+ return block;
+ }
}
int
sharkd_set_modified_block(frame_data *fd, wtap_block_t new_block)
{
- cap_file_provider_set_modified_block(&cfile.provider, fd, new_block);
- return 0;
+ cap_file_provider_set_modified_block(&cfile.provider, fd, new_block);
+ return 0;
}
-
-/*
- * 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:
- */
diff --git a/sharkd_daemon.c b/sharkd_daemon.c
index bd80f68069..e990b931ad 100644
--- a/sharkd_daemon.c
+++ b/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;
-
- 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));
-
- if (bind(fd, (struct sockaddr *) &s_in, sizeof(struct sockaddr_in)))
- {
- closesocket(fd);
- return INVALID_SOCKET;
- }
- }
- else
+ 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 = ':';
+
+ 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
#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, "Classic (classic_options):\n");
- fprintf(output, " [-|<socket>]\n");
- fprintf(output, "\n");
- fprintf(output, " <socket> examples:\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");
#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, " 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, "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, "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 (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.
- */
-
- do {
- if (ws_optind > (argc - 1))
- break;
-
- 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;
-
- 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);
-
- mode = SHARKD_MODE_GOLD_DAEMON;
- 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 '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);
- }
-
- if (mode == SHARKD_MODE_CLASSIC_DAEMON || mode == SHARKD_MODE_GOLD_DAEMON)
- {
- /* all good - try to daemonize */
+ 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 -
+
+ 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;
+
+ 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;
+
+ 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);
+
+ mode = SHARKD_MODE_GOLD_DAEMON;
+ 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 '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);
+ }
+
+ 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));
-
- if (pid != 0)
- {
- /* parent */
- exit(0);
- }
+ pid = fork();
+ if (pid == -1)
+ fprintf(stderr, "cannot go to background fork() failed: %s\n", g_strerror(errno));
+
+ 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);
-
- exit(sharkd_session_main(mode));
- }
-
- if (pid == -1)
- {
- fprintf(stderr, "cannot fork(): %s\n", g_strerror(errno));
- }
+ 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));
+ }
+
+ if (pid == -1)
+ {
+ fprintf(stderr, "cannot fork(): %s\n", g_strerror(errno));
+ }
#else
- 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);
-
- 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));
-
- 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));
- }
- }
- }
-
- 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);
+ 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);
+
+ 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));
+
+ 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));
+ }
+ }
+ }
+
+ 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);
#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:
- */
diff --git a/sharkd_session.c b/sharkd_session.c
index 5938824e44..1a5fdaa57a 100644
--- a/sharkd_session.c
+++ b/sharkd_session.c
@@ -77,7 +77,7 @@
struct sharkd_filter_item
{
- guint8 *filtered; /* can be NULL if all frames are matching for given filter. */
+ guint8 *filtered; /* can be NULL if all frames are matching for given filter. */
};
static GHashTable *filter_table = NULL;
@@ -91,234 +91,234 @@ static json_dumper dumper = {0};
static const char *
json_find_attr(const char *buf, const jsmntok_t *tokens, int count, const char *attr)
{
- int i;
+ int i;
- for (i = 0; i < count; i += 2)
- {
- const char *tok_attr = &buf[tokens[i + 0].start];
- const char *tok_value = &buf[tokens[i + 1].start];
+ for (i = 0; i < count; i += 2)
+ {
+ const char *tok_attr = &buf[tokens[i + 0].start];
+ const char *tok_value = &buf[tokens[i + 1].start];
- if (!strcmp(tok_attr, attr))
- return tok_value;
- }
+ if (!strcmp(tok_attr, attr))
+ return tok_value;
+ }
- return NULL;
+ return NULL;
}
static void
json_print_base64(const guint8 *data, size_t len)
{
- json_dumper_begin_base64(&dumper);
- json_dumper_write_base64(&dumper, data, len);
- json_dumper_end_base64(&dumper);
+ json_dumper_begin_base64(&dumper);
+ json_dumper_write_base64(&dumper, data, len);
+ json_dumper_end_base64(&dumper);
}
static void G_GNUC_PRINTF(2, 3)
sharkd_json_value_anyf(const char *key, const char *format, ...)
{
- if (key)
- json_dumper_set_member_name(&dumper, key);
-
- if (format) {
- va_list ap;
- va_start(ap, format);
- json_dumper_value_va_list(&dumper, format, ap);
- va_end(ap);
- }
+ if (key)
+ json_dumper_set_member_name(&dumper, key);
+
+ if (format) {
+ va_list ap;
+ va_start(ap, format);
+ json_dumper_value_va_list(&dumper, format, ap);
+ va_end(ap);
+ }
}
static void
sharkd_json_value_string(const char *key, const char *str)
{
- if (key)
- json_dumper_set_member_name(&dumper, key);
- if (str)
- json_dumper_value_string(&dumper, str);
+ if (key)
+ json_dumper_set_member_name(&dumper, key);
+ if (str)
+ json_dumper_value_string(&dumper, str);
}
static void
sharkd_json_value_base64(const char *key, const guint8 *data, size_t len)
{
- if (key)
- json_dumper_set_member_name(&dumper, key);
- json_print_base64(data, len);
+ if (key)
+ json_dumper_set_member_name(&dumper, key);
+ json_print_base64(data, len);
}
static void G_GNUC_PRINTF(2, 3)
sharkd_json_value_stringf(const char *key, const char *format, ...)
{
- if (key)
- json_dumper_set_member_name(&dumper, key);
-
- if (format) {
- va_list ap;
- va_start(ap, format);
- char* sformat = ws_strdup_printf("\"%s\"", format);
- json_dumper_value_va_list(&dumper, sformat, ap);
- g_free(sformat);
- va_end(ap);
- }
+ if (key)
+ json_dumper_set_member_name(&dumper, key);
+
+ if (format) {
+ va_list ap;
+ va_start(ap, format);
+ char* sformat = ws_strdup_printf("\"%s\"", format);
+ json_dumper_value_va_list(&dumper, sformat, ap);
+ g_free(sformat);
+ va_end(ap);
+ }
}
static void
sharkd_json_array_open(const char *key)
{
- if (key)
- json_dumper_set_member_name(&dumper, key);
- json_dumper_begin_array(&dumper);
+ if (key)
+ json_dumper_set_member_name(&dumper, key);
+ json_dumper_begin_array(&dumper);
}
static void
sharkd_json_array_close(void)
{
- json_dumper_end_array(&dumper);
+ json_dumper_end_array(&dumper);
}
static void
sharkd_json_response_open(guint32 id)
{
- json_dumper_begin_object(&dumper); // start the message
- sharkd_json_value_string("jsonrpc", "2.0");
- sharkd_json_value_anyf("id", "%d", id);
+ json_dumper_begin_object(&dumper); // start the message
+ sharkd_json_value_string("jsonrpc", "2.0");
+ sharkd_json_value_anyf("id", "%d", id);
}
static void
sharkd_json_response_close(void)
{
- json_dumper_finish(&dumper);
-
- /*
- * We do an explicit fflush after every line, because
- * we want output to be written to the socket as soon
- * as the line is complete.
- *
- * The stream is fully-buffered by default, so it's
- * only flushed when the buffer fills or the FILE *
- * is closed. On UN*X, we could set it to be line
- * buffered, but the MSVC standard I/O routines don't
- * support line buffering - they only support *byte*
- * buffering, doing a write for every byte written,
- * which is too inefficient, and full buffering,
- * which is what you get if you request line buffering.
- */
- fflush(stdout);
+ json_dumper_finish(&dumper);
+
+ /*
+ * We do an explicit fflush after every line, because
+ * we want output to be written to the socket as soon
+ * as the line is complete.
+ *
+ * The stream is fully-buffered by default, so it's
+ * only flushed when the buffer fills or the FILE *
+ * is closed. On UN*X, we could set it to be line
+ * buffered, but the MSVC standard I/O routines don't
+ * support line buffering - they only support *byte*
+ * buffering, doing a write for every byte written,
+ * which is too inefficient, and full buffering,
+ * which is what you get if you request line buffering.
+ */
+ fflush(stdout);
}
static void
sharkd_json_result_prologue(guint32 id)
{
- sharkd_json_response_open(id);
- sharkd_json_value_anyf("result", NULL);
- json_dumper_begin_object(&dumper); // start the result object
+ sharkd_json_response_open(id);
+ sharkd_json_value_anyf("result", NULL);
+ json_dumper_begin_object(&dumper); // start the result object
}
static void
sharkd_json_result_epilogue(void)
{
- json_dumper_end_object(&dumper); // end the result object
- json_dumper_end_object(&dumper); // end the message
- sharkd_json_response_close();
+ json_dumper_end_object(&dumper); // end the result object
+ json_dumper_end_object(&dumper); // end the message
+ sharkd_json_response_close();
}
static void
sharkd_json_result_array_prologue(guint32 id)
{
- sharkd_json_response_open(id);
- sharkd_json_array_open("result"); // start the result array
+ sharkd_json_response_open(id);
+ sharkd_json_array_open("result"); // start the result array
}
static void
sharkd_json_result_array_epilogue(void)
{
- sharkd_json_array_close(); // end of result array
- json_dumper_end_object(&dumper); // end the message
- sharkd_json_response_close();
+ sharkd_json_array_close(); // end of result array
+ json_dumper_end_object(&dumper); // end the message
+ sharkd_json_response_close();
}
static void
sharkd_json_simple_ok(guint32 id)
{
- sharkd_json_result_prologue(id);
- sharkd_json_value_string("status", "OK");
- sharkd_json_result_epilogue();
+ sharkd_json_result_prologue(id);
+ sharkd_json_value_string("status", "OK");
+ sharkd_json_result_epilogue();
}
static void
sharkd_json_warning(guint32 id, char *warning)
{
- sharkd_json_result_prologue(id);
- sharkd_json_value_string("status", "Warning");
- sharkd_json_value_string("warning", warning);
- sharkd_json_result_epilogue();
+ sharkd_json_result_prologue(id);
+ sharkd_json_value_string("status", "Warning");
+ sharkd_json_value_string("warning", warning);
+ sharkd_json_result_epilogue();
}
static void G_GNUC_PRINTF(4, 5)
sharkd_json_error(guint32 id, int code, char* data, char* format, ...)
{
- sharkd_json_response_open(id);
- sharkd_json_value_anyf("error", NULL);
- json_dumper_begin_object(&dumper);
- sharkd_json_value_anyf("code", "%d", code);
+ sharkd_json_response_open(id);
+ sharkd_json_value_anyf("error", NULL);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_anyf("code", "%d", code);
- if (format)
- {
- // format the text message
- va_list args;
+ if (format)
+ {
+ // format the text message
+ va_list args;
- va_start(args, format);
- char *error_msg = ws_strdup_vprintf(format, args);
- va_end(args);
+ va_start(args, format);
+ char *error_msg = ws_strdup_vprintf(format, args);
+ va_end(args);
- sharkd_json_value_string("message", error_msg);
+ sharkd_json_value_string("message", error_msg);
- g_free(error_msg);
- }
+ g_free(error_msg);
+ }
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
- if (data)
- sharkd_json_value_string("data", data);
+ if (data)
+ sharkd_json_value_string("data", data);
- json_dumper_end_object(&dumper);
- sharkd_json_response_close();
+ json_dumper_end_object(&dumper);
+ sharkd_json_response_close();
}
static gboolean
is_param_match(const char *param_in, const char *valid_param)
{
- char* ptr;
-
- if ((ptr = g_strrstr(valid_param, "*")))
- {
- size_t prefix_len = ptr - valid_param;
- return !strncmp(param_in, valid_param, prefix_len);
- }
- else
- return !strcmp(param_in, valid_param);
+ char* ptr;
+
+ if ((ptr = g_strrstr(valid_param, "*")))
+ {
+ size_t prefix_len = ptr - valid_param;
+ return !strncmp(param_in, valid_param, prefix_len);
+ }
+ else
+ return !strcmp(param_in, valid_param);
}
/*
-* json_prep does four things:
-*
-* 1. check the syntax of the root and parameter members
-* 2. tokenize the names and values by zero terminating them
-* 3. unescape the names and values
-* 4. extracts and saves the rpcid
-* - we have to do it here as it's needed for the error messages
-*
-* The objective is to minimise the validation work in the functions
-* that process each called method.
-*
-* This gets a little messy as the JSON parser creates a flat list
-* of all members rather than create a tree.
-*/
+ * json_prep does four things:
+ *
+ * 1. check the syntax of the root and parameter members
+ * 2. tokenize the names and values by zero terminating them
+ * 3. unescape the names and values
+ * 4. extracts and saves the rpcid
+ * - we have to do it here as it's needed for the error messages
+ *
+ * The objective is to minimise the validation work in the functions
+ * that process each called method.
+ *
+ * This gets a little messy as the JSON parser creates a flat list
+ * of all members rather than create a tree.
+ */
static gboolean
json_prep(char* buf, const jsmntok_t* tokens, int count)
{
- int i;
- char* method = NULL;
- char* attr_name = NULL;
- char* attr_value = NULL;
+ int i;
+ char* method = NULL;
+ char* attr_name = NULL;
+ char* attr_value = NULL;
#define SHARKD_JSON_ANY 0
#define SHARKD_JSON_STRING 1
@@ -330,568 +330,568 @@ json_prep(char* buf, const jsmntok_t* tokens, int count)
#define SHARKD_JSON_BOOLEAN 7
#define SHARKD_ARRAY_END 99
- struct member_attribute {
- const char* parent_ctx;
- const char* name;
- int level;
- jsmntype_t type;
- int value_type;
- gboolean is_mandatory;
- };
+ struct member_attribute {
+ const char* parent_ctx;
+ const char* name;
+ int level;
+ jsmntype_t type;
+ int value_type;
+ gboolean is_mandatory;
+ };
#define MANDATORY TRUE
#define OPTIONAL FALSE
- /*
- * The member attribute structure is key to the syntax checking. The
- * array contains all of the root level (1) member names, the data
- * types permissable for the value and a boolean that indicates whether
- * or not the member is mandatory.
- *
- * Once we get into the next layer (2) of the json tree, we need to check
- * params member names and data types dependent in the context of the method
- * (parent_ctx).
- */
-
- struct member_attribute name_array[] = {
- // Root members
- {NULL, "jsonrpc", 1, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
- {NULL, "userid", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {NULL, "id", 1, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, MANDATORY},
- {NULL, "method", 1, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
- {NULL, "params", 1, JSMN_OBJECT, SHARKD_JSON_OBJECT, OPTIONAL},
-
- // Valid methods
- {"method", "analyse", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "bye", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "check", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "complete", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "download", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "dumpconf", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "follow", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "frame", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "frames", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "info", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "intervals", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "iograph", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "load", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "setcomment", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "setconf", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "status", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"method", "tap", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
-
- // Parameters and their method context
- {"check", "field", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"check", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"complete", "field", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"complete", "pref", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"download", "token", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"dumpconf", "pref", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"follow", "follow", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
- {"follow", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
- {"frame", "frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, MANDATORY},
- {"frame", "proto", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
- {"frame", "ref_frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
- {"frame", "prev_frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
- {"frame", "columns", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
- {"frame", "color", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
- {"frame", "bytes", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
- {"frame", "hidden", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
- {"frames", "column*", 2, JSMN_UNDEFINED, SHARKD_JSON_ANY, OPTIONAL},
- {"frames", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"frames", "skip", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, OPTIONAL},
- {"frames", "limit", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, OPTIONAL},
- {"frames", "refs", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"intervals", "interval", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, OPTIONAL},
- {"intervals", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "interval", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, OPTIONAL},
- {"iograph", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph0", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
- {"iograph", "graph1", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph2", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph3", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph4", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph5", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph6", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph7", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph8", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "graph9", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter0", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter1", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter2", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter3", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter4", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter5", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter6", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter7", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter8", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"iograph", "filter9", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"load", "file", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
- {"setcomment", "frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, MANDATORY},
- {"setcomment", "comment", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"setconf", "name", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
- {"setconf", "value", 2, JSMN_UNDEFINED, SHARKD_JSON_ANY, MANDATORY},
- {"tap", "tap0", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
- {"tap", "tap1", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap2", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap3", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap4", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap5", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap6", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap7", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap8", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap9", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap10", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap11", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap12", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap13", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap14", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
- {"tap", "tap15", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
-
- // End of the name_array
- {NULL, NULL, 0, JSMN_STRING, SHARKD_ARRAY_END, OPTIONAL},
- };
-
- rpcid = 0;
-
- /* sanity check, and split strings */
- if (count < 1 || tokens[0].type != JSMN_OBJECT)
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "The request must an object"
- );
- return FALSE;
- }
-
- /* don't need [0] token */
- tokens++;
- count--;
-
- if (count & 1)
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "The request must contain name/value pairs"
- );
- return FALSE;
- }
-
- for (i = 0; i < count; i += 2)
- {
- if (tokens[i].type != JSMN_STRING)
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "Member names must be a string - member %d is not string", (i / 2) + 1
- );
- return FALSE;
- }
-
- buf[tokens[i + 0].end] = '\0';
- buf[tokens[i + 1].end] = '\0';
-
- attr_name = &buf[tokens[i + 0].start];
- attr_value = &buf[tokens[i + 1].start];
-
- // we must get the id as soon as possible so that it's available in all future error messages
- if (!strcmp(attr_name, "id"))
- {
- if (!ws_strtou32(attr_value, NULL, &rpcid))
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "The id value must be a positive integer"
- );
- return FALSE;
- }
- }
-
- if (!strcmp(attr_name, "jsonrpc"))
- {
- if (strcmp(&buf[tokens[i + 1].start], "2.0"))
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "Only JSON %s is supported", "2.0"
- );
- return FALSE;
- }
- }
-
- /* unescape only value, as keys are simple strings */
- if (tokens[i + 1].type == JSMN_STRING && !json_decode_string_inplace(attr_value))
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "Cannot unescape the value string of member %d", (i / 2) + 1
- );
- return FALSE;
- }
-
- /* Confirm that the member is valid */
- gboolean match = FALSE;
-
- // We need to check root members (level 1) and parameters (level 2), hence the for loop.
-
- for (int level = 1; level < 3; level++)
- {
- size_t j = 0;
-
- while (name_array[j].value_type != SHARKD_ARRAY_END) // iterate through the array until we hit the end
- {
- if (is_param_match(attr_name, name_array[j].name) && name_array[j].level == level)
- {
- // We need to be sure the match is in the correct context
- // i.e. is this a match for a root member (level 1) or for a parameter (level 2).
-
- if (level == 1)
- {
- // need to guard against a parameter name matching a method name
- if (method)
- {
- if (name_array[j].parent_ctx)
- {
- j++;
- continue;
- }
-
- if (!strcmp(method, &buf[tokens[i + 0].start]))
- {
- j++;
- continue;
- }
- }
-
- match = TRUE;
- }
- else if (method)
- {
- if (level == 2 && !strcmp(name_array[j].parent_ctx, method))
- match = TRUE;
- else
- {
- j++;
- continue;
- }
- }
- else
- {
- j++;
- continue;
- }
-
- // The match looks good, let's now check the data types
-
- if (tokens[i + 1].type != name_array[j].type && name_array[j].type != SHARKD_JSON_ANY)
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "The data type for member %s is not a valid", attr_name
- );
- return FALSE;
- }
- else if (name_array[j].type == JSMN_PRIMITIVE && name_array[j].value_type == SHARKD_JSON_UINTEGER)
- {
- guint32 temp;
- if (!ws_strtou32(attr_value, NULL, &temp) || temp <= 0)
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "The value for %s must be a positive integer", name_array[j].name
- );
- return FALSE;
- }
- }
- else if (name_array[j].type == JSMN_PRIMITIVE && name_array[j].value_type == SHARKD_JSON_BOOLEAN)
- {
- if (strcmp(attr_value, "true") && strcmp(attr_value, "false"))
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "The value for %s must be a boolean (true or false)", name_array[j].name
- );
- return FALSE;
- }
-
- }
- break; // looks like a valid match
- }
- j++;
- }
-
- if (!strcmp(attr_name, "method"))
- {
- int k = 0; // name array index
- // check that the request method is good
- while (name_array[k].value_type != SHARKD_ARRAY_END)
- {
- if (name_array[k].parent_ctx)
- {
- if (!strcmp(attr_value, name_array[k].name) && !strcmp(name_array[k].parent_ctx, "method"))
- method = attr_value; // the method is valid
- }
-
- k++;
- }
-
- if (!method)
- {
- sharkd_json_error(
- rpcid, -32601, NULL,
- "The method %s is not supported", attr_value
- );
- return FALSE;
- }
- }
- }
-
- if (!match)
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "%s is not a valid member name", attr_name
- );
- return FALSE;
- }
- }
-
- /* check for mandatory members */
- size_t j = 0;
-
- while (name_array[j].value_type != SHARKD_ARRAY_END)
- {
- if (name_array[j].is_mandatory && name_array[j].level == 1)
- {
- if (!json_find_attr(buf, tokens, count, name_array[j].name))
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "Mandatory member %s is missing", name_array[j].name
- );
- return FALSE;
- }
- }
- j++;
- }
-
- // check that the current request contains the mandatory parameters
- j = 0;
-
- while (name_array[j].value_type != SHARKD_ARRAY_END)
- {
- if (name_array[j].is_mandatory && name_array[j].level == 2 && !strcmp(method, name_array[j].parent_ctx))
- {
- if (!json_find_attr(buf, tokens, count, name_array[j].name))
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "Mandatory parameter %s is missing", name_array[j].name
- );
- return FALSE;
- }
- }
- j++;
- }
-
-
- // check that the parameters for the current request are valid for the method and that the data type for the value is valid
-
- return TRUE;
+ /*
+ * The member attribute structure is key to the syntax checking. The
+ * array contains all of the root level (1) member names, the data
+ * types permissable for the value and a boolean that indicates whether
+ * or not the member is mandatory.
+ *
+ * Once we get into the next layer (2) of the json tree, we need to check
+ * params member names and data types dependent in the context of the method
+ * (parent_ctx).
+ */
+
+ struct member_attribute name_array[] = {
+ // Root members
+ {NULL, "jsonrpc", 1, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
+ {NULL, "userid", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {NULL, "id", 1, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, MANDATORY},
+ {NULL, "method", 1, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
+ {NULL, "params", 1, JSMN_OBJECT, SHARKD_JSON_OBJECT, OPTIONAL},
+
+ // Valid methods
+ {"method", "analyse", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "bye", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "check", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "complete", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "download", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "dumpconf", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "follow", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "frame", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "frames", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "info", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "intervals", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "iograph", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "load", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "setcomment", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "setconf", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "status", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"method", "tap", 1, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+
+ // Parameters and their method context
+ {"check", "field", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"check", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"complete", "field", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"complete", "pref", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"download", "token", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"dumpconf", "pref", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"follow", "follow", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
+ {"follow", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
+ {"frame", "frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, MANDATORY},
+ {"frame", "proto", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
+ {"frame", "ref_frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
+ {"frame", "prev_frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
+ {"frame", "columns", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
+ {"frame", "color", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
+ {"frame", "bytes", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
+ {"frame", "hidden", 2, JSMN_PRIMITIVE, SHARKD_JSON_BOOLEAN, OPTIONAL},
+ {"frames", "column*", 2, JSMN_UNDEFINED, SHARKD_JSON_ANY, OPTIONAL},
+ {"frames", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"frames", "skip", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, OPTIONAL},
+ {"frames", "limit", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, OPTIONAL},
+ {"frames", "refs", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"intervals", "interval", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, OPTIONAL},
+ {"intervals", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "interval", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, OPTIONAL},
+ {"iograph", "filter", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph0", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
+ {"iograph", "graph1", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph2", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph3", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph4", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph5", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph6", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph7", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph8", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "graph9", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter0", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter1", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter2", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter3", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter4", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter5", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter6", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter7", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter8", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"iograph", "filter9", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"load", "file", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
+ {"setcomment", "frame", 2, JSMN_PRIMITIVE, SHARKD_JSON_UINTEGER, MANDATORY},
+ {"setcomment", "comment", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"setconf", "name", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
+ {"setconf", "value", 2, JSMN_UNDEFINED, SHARKD_JSON_ANY, MANDATORY},
+ {"tap", "tap0", 2, JSMN_STRING, SHARKD_JSON_STRING, MANDATORY},
+ {"tap", "tap1", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap2", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap3", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap4", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap5", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap6", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap7", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap8", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap9", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap10", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap11", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap12", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap13", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap14", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+ {"tap", "tap15", 2, JSMN_STRING, SHARKD_JSON_STRING, OPTIONAL},
+
+ // End of the name_array
+ {NULL, NULL, 0, JSMN_STRING, SHARKD_ARRAY_END, OPTIONAL},
+ };
+
+ rpcid = 0;
+
+ /* sanity check, and split strings */
+ if (count < 1 || tokens[0].type != JSMN_OBJECT)
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "The request must an object"
+ );
+ return FALSE;
+ }
+
+ /* don't need [0] token */
+ tokens++;
+ count--;
+
+ if (count & 1)
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "The request must contain name/value pairs"
+ );
+ return FALSE;
+ }
+
+ for (i = 0; i < count; i += 2)
+ {
+ if (tokens[i].type != JSMN_STRING)
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "Member names must be a string - member %d is not string", (i / 2) + 1
+ );
+ return FALSE;
+ }
+
+ buf[tokens[i + 0].end] = '\0';
+ buf[tokens[i + 1].end] = '\0';
+
+ attr_name = &buf[tokens[i + 0].start];
+ attr_value = &buf[tokens[i + 1].start];
+
+ // we must get the id as soon as possible so that it's available in all future error messages
+ if (!strcmp(attr_name, "id"))
+ {
+ if (!ws_strtou32(attr_value, NULL, &rpcid))
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "The id value must be a positive integer"
+ );
+ return FALSE;
+ }
+ }
+
+ if (!strcmp(attr_name, "jsonrpc"))
+ {
+ if (strcmp(&buf[tokens[i + 1].start], "2.0"))
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "Only JSON %s is supported", "2.0"
+ );
+ return FALSE;
+ }
+ }
+
+ /* unescape only value, as keys are simple strings */
+ if (tokens[i + 1].type == JSMN_STRING && !json_decode_string_inplace(attr_value))
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "Cannot unescape the value string of member %d", (i / 2) + 1
+ );
+ return FALSE;
+ }
+
+ /* Confirm that the member is valid */
+ gboolean match = FALSE;
+
+ // We need to check root members (level 1) and parameters (level 2), hence the for loop.
+
+ for (int level = 1; level < 3; level++)
+ {
+ size_t j = 0;
+
+ while (name_array[j].value_type != SHARKD_ARRAY_END) // iterate through the array until we hit the end
+ {
+ if (is_param_match(attr_name, name_array[j].name) && name_array[j].level == level)
+ {
+ // We need to be sure the match is in the correct context
+ // i.e. is this a match for a root member (level 1) or for a parameter (level 2).
+
+ if (level == 1)
+ {
+ // need to guard against a parameter name matching a method name
+ if (method)
+ {
+ if (name_array[j].parent_ctx)
+ {
+ j++;
+ continue;
+ }
+
+ if (!strcmp(method, &buf[tokens[i + 0].start]))
+ {
+ j++;
+ continue;
+ }
+ }
+
+ match = TRUE;
+ }
+ else if (method)
+ {
+ if (level == 2 && !strcmp(name_array[j].parent_ctx, method))
+ match = TRUE;
+ else
+ {
+ j++;
+ continue;
+ }
+ }
+ else
+ {
+ j++;
+ continue;
+ }
+
+ // The match looks good, let's now check the data types
+
+ if (tokens[i + 1].type != name_array[j].type && name_array[j].type != SHARKD_JSON_ANY)
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "The data type for member %s is not a valid", attr_name
+ );
+ return FALSE;
+ }
+ else if (name_array[j].type == JSMN_PRIMITIVE && name_array[j].value_type == SHARKD_JSON_UINTEGER)
+ {
+ guint32 temp;
+ if (!ws_strtou32(attr_value, NULL, &temp) || temp <= 0)
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "The value for %s must be a positive integer", name_array[j].name
+ );
+ return FALSE;
+ }
+ }
+ else if (name_array[j].type == JSMN_PRIMITIVE && name_array[j].value_type == SHARKD_JSON_BOOLEAN)
+ {
+ if (strcmp(attr_value, "true") && strcmp(attr_value, "false"))
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "The value for %s must be a boolean (true or false)", name_array[j].name
+ );
+ return FALSE;
+ }
+
+ }
+ break; // looks like a valid match
+ }
+ j++;
+ }
+
+ if (!strcmp(attr_name, "method"))
+ {
+ int k = 0; // name array index
+ // check that the request method is good
+ while (name_array[k].value_type != SHARKD_ARRAY_END)
+ {
+ if (name_array[k].parent_ctx)
+ {
+ if (!strcmp(attr_value, name_array[k].name) && !strcmp(name_array[k].parent_ctx, "method"))
+ method = attr_value; // the method is valid
+ }
+
+ k++;
+ }
+
+ if (!method)
+ {
+ sharkd_json_error(
+ rpcid, -32601, NULL,
+ "The method %s is not supported", attr_value
+ );
+ return FALSE;
+ }
+ }
+ }
+
+ if (!match)
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "%s is not a valid member name", attr_name
+ );
+ return FALSE;
+ }
+ }
+
+ /* check for mandatory members */
+ size_t j = 0;
+
+ while (name_array[j].value_type != SHARKD_ARRAY_END)
+ {
+ if (name_array[j].is_mandatory && name_array[j].level == 1)
+ {
+ if (!json_find_attr(buf, tokens, count, name_array[j].name))
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "Mandatory member %s is missing", name_array[j].name
+ );
+ return FALSE;
+ }
+ }
+ j++;
+ }
+
+ // check that the current request contains the mandatory parameters
+ j = 0;
+
+ while (name_array[j].value_type != SHARKD_ARRAY_END)
+ {
+ if (name_array[j].is_mandatory && name_array[j].level == 2 && !strcmp(method, name_array[j].parent_ctx))
+ {
+ if (!json_find_attr(buf, tokens, count, name_array[j].name))
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "Mandatory parameter %s is missing", name_array[j].name
+ );
+ return FALSE;
+ }
+ }
+ j++;
+ }
+
+
+ // check that the parameters for the current request are valid for the method and that the data type for the value is valid
+
+ return TRUE;
}
static void
sharkd_session_filter_free(gpointer data)
{
- struct sharkd_filter_item *l = (struct sharkd_filter_item *) data;
+ struct sharkd_filter_item *l = (struct sharkd_filter_item *) data;
- g_free(l->filtered);
- g_free(l);
+ g_free(l->filtered);
+ g_free(l);
}
static const struct sharkd_filter_item *
sharkd_session_filter_data(const char *filter)
{
- struct sharkd_filter_item *l;
+ struct sharkd_filter_item *l;
- l = (struct sharkd_filter_item *) g_hash_table_lookup(filter_table, filter);
- if (!l)
- {
- guint8 *filtered = NULL;
+ l = (struct sharkd_filter_item *) g_hash_table_lookup(filter_table, filter);
+ if (!l)
+ {
+ guint8 *filtered = NULL;
- int ret = sharkd_filter(filter, &filtered);
+ int ret = sharkd_filter(filter, &filtered);
- if (ret == -1)
- return NULL;
+ if (ret == -1)
+ return NULL;
- l = g_new(struct sharkd_filter_item, 1);
- l->filtered = filtered;
+ l = g_new(struct sharkd_filter_item, 1);
+ l->filtered = filtered;
- g_hash_table_insert(filter_table, g_strdup(filter), l);
- }
+ g_hash_table_insert(filter_table, g_strdup(filter), l);
+ }
- return l;
+ return l;
}
static gboolean
sharkd_rtp_match_init(rtpstream_id_t *id, const char *init_str)
{
- gboolean ret = FALSE;
- char **arr;
- guint32 tmp_addr_src, tmp_addr_dst;
- address tmp_src_addr, tmp_dst_addr;
+ gboolean ret = FALSE;
+ char **arr;
+ guint32 tmp_addr_src, tmp_addr_dst;
+ address tmp_src_addr, tmp_dst_addr;
- memset(id, 0, sizeof(*id));
+ memset(id, 0, sizeof(*id));
- arr = g_strsplit(init_str, "_", 7); /* pass larger value, so we'll catch incorrect input :) */
- if (g_strv_length(arr) != 5)
- goto fail;
+ arr = g_strsplit(init_str, "_", 7); /* pass larger value, so we'll catch incorrect input :) */
+ if (g_strv_length(arr) != 5)
+ goto fail;
- /* TODO, for now only IPv4 */
- if (!get_host_ipaddr(arr[0], &tmp_addr_src))
- goto fail;
+ /* TODO, for now only IPv4 */
+ if (!get_host_ipaddr(arr[0], &tmp_addr_src))
+ goto fail;
- if (!ws_strtou16(arr[1], NULL, &id->src_port))
- goto fail;
+ if (!ws_strtou16(arr[1], NULL, &id->src_port))
+ goto fail;
- if (!get_host_ipaddr(arr[2], &tmp_addr_dst))
- goto fail;
+ if (!get_host_ipaddr(arr[2], &tmp_addr_dst))
+ goto fail;
- if (!ws_strtou16(arr[3], NULL, &id->dst_port))
- goto fail;
+ if (!ws_strtou16(arr[3], NULL, &id->dst_port))
+ goto fail;
- if (!ws_hexstrtou32(arr[4], NULL, &id->ssrc))
- goto fail;
+ if (!ws_hexstrtou32(arr[4], NULL, &id->ssrc))
+ goto fail;
- set_address(&tmp_src_addr, AT_IPv4, 4, &tmp_addr_src);
- copy_address(&id->src_addr, &tmp_src_addr);
- set_address(&tmp_dst_addr, AT_IPv4, 4, &tmp_addr_dst);
- copy_address(&id->dst_addr, &tmp_dst_addr);
+ set_address(&tmp_src_addr, AT_IPv4, 4, &tmp_addr_src);
+ copy_address(&id->src_addr, &tmp_src_addr);
+ set_address(&tmp_dst_addr, AT_IPv4, 4, &tmp_addr_dst);
+ copy_address(&id->dst_addr, &tmp_dst_addr);
- ret = TRUE;
+ ret = TRUE;
fail:
- g_strfreev(arr);
- return ret;
+ g_strfreev(arr);
+ return ret;
}
static gboolean
sharkd_session_process_info_nstat_cb(const void *key, void *value, void *userdata _U_)
{
- stat_tap_table_ui *stat_tap = (stat_tap_table_ui *) value;
+ stat_tap_table_ui *stat_tap = (stat_tap_table_ui *) value;
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("name", stat_tap->title);
- sharkd_json_value_stringf("tap", "nstat:%s", (const char *) key);
- json_dumper_end_object(&dumper);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("name", stat_tap->title);
+ sharkd_json_value_stringf("tap", "nstat:%s", (const char *) key);
+ json_dumper_end_object(&dumper);
- return FALSE;
+ return FALSE;
}
static gboolean
sharkd_session_process_info_conv_cb(const void* key, void* value, void* userdata _U_)
{
- struct register_ct *table = (struct register_ct *) value;
-
- const char *label = (const char *) key;
-
- if (get_conversation_packet_func(table))
- {
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("name", "Conversation List/%s", label);
- sharkd_json_value_stringf("tap", "conv:%s", label);
- json_dumper_end_object(&dumper);
- }
-
- if (get_hostlist_packet_func(table))
- {
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("name", "Endpoint/%s", label);
- sharkd_json_value_stringf("tap", "endpt:%s", label);
- json_dumper_end_object(&dumper);
- }
- return FALSE;
+ struct register_ct *table = (struct register_ct *) value;
+
+ const char *label = (const char *) key;
+
+ if (get_conversation_packet_func(table))
+ {
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("name", "Conversation List/%s", label);
+ sharkd_json_value_stringf("tap", "conv:%s", label);
+ json_dumper_end_object(&dumper);
+ }
+
+ if (get_hostlist_packet_func(table))
+ {
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("name", "Endpoint/%s", label);
+ sharkd_json_value_stringf("tap", "endpt:%s", label);
+ json_dumper_end_object(&dumper);
+ }
+ return FALSE;
}
static gboolean
sharkd_session_seq_analysis_cb(const void *key, void *value, void *userdata _U_)
{
- register_analysis_t *analysis = (register_analysis_t *) value;
+ register_analysis_t *analysis = (register_analysis_t *) value;
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("name", sequence_analysis_get_ui_name(analysis));
- sharkd_json_value_stringf("tap", "seqa:%s", (const char *) key);
- json_dumper_end_object(&dumper);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("name", sequence_analysis_get_ui_name(analysis));
+ sharkd_json_value_stringf("tap", "seqa:%s", (const char *) key);
+ json_dumper_end_object(&dumper);
- return FALSE;
+ return FALSE;
}
static gboolean
sharkd_export_object_visit_cb(const void *key _U_, void *value, void *user_data _U_)
{
- register_eo_t *eo = (register_eo_t *) value;
+ register_eo_t *eo = (register_eo_t *) value;
- const int proto_id = get_eo_proto_id(eo);
- const char *filter = proto_get_protocol_filter_name(proto_id);
- const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
+ const int proto_id = get_eo_proto_id(eo);
+ const char *filter = proto_get_protocol_filter_name(proto_id);
+ const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("name", "Export Object/%s", label);
- sharkd_json_value_stringf("tap", "eo:%s", filter);
- json_dumper_end_object(&dumper);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("name", "Export Object/%s", label);
+ sharkd_json_value_stringf("tap", "eo:%s", filter);
+ json_dumper_end_object(&dumper);
- return FALSE;
+ return FALSE;
}
static gboolean
sharkd_srt_visit_cb(const void *key _U_, void *value, void *user_data _U_)
{
- register_srt_t *srt = (register_srt_t *) value;
+ register_srt_t *srt = (register_srt_t *) value;
- const int proto_id = get_srt_proto_id(srt);
- const char *filter = proto_get_protocol_filter_name(proto_id);
- const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
+ const int proto_id = get_srt_proto_id(srt);
+ const char *filter = proto_get_protocol_filter_name(proto_id);
+ const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("name", "Service Response Time/%s", label);
- sharkd_json_value_stringf("tap", "srt:%s", filter);
- json_dumper_end_object(&dumper);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("name", "Service Response Time/%s", label);
+ sharkd_json_value_stringf("tap", "srt:%s", filter);
+ json_dumper_end_object(&dumper);
- return FALSE;
+ return FALSE;
}
static gboolean
sharkd_rtd_visit_cb(const void *key _U_, void *value, void *user_data _U_)
{
- register_rtd_t *rtd = (register_rtd_t *) value;
+ register_rtd_t *rtd = (register_rtd_t *) value;
- const int proto_id = get_rtd_proto_id(rtd);
- const char *filter = proto_get_protocol_filter_name(proto_id);
- const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
+ const int proto_id = get_rtd_proto_id(rtd);
+ const char *filter = proto_get_protocol_filter_name(proto_id);
+ const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("name", "Response Time Delay/%s", label);
- sharkd_json_value_stringf("tap", "rtd:%s", filter);
- json_dumper_end_object(&dumper);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("name", "Response Time Delay/%s", label);
+ sharkd_json_value_stringf("tap", "rtd:%s", filter);
+ json_dumper_end_object(&dumper);
- return FALSE;
+ return FALSE;
}
static gboolean
sharkd_follower_visit_cb(const void *key _U_, void *value, void *user_data _U_)
{
- register_follow_t *follower = (register_follow_t *) value;
+ register_follow_t *follower = (register_follow_t *) value;
- const int proto_id = get_follow_proto_id(follower);
- const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
- const char *filter = label; /* correct: get_follow_by_name() is registered by short name */
+ const int proto_id = get_follow_proto_id(follower);
+ const char *label = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
+ const char *filter = label; /* correct: get_follow_by_name() is registered by short name */
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("name", "Follow/%s", label);
- sharkd_json_value_stringf("tap", "follow:%s", filter);
- json_dumper_end_object(&dumper);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("name", "Follow/%s", label);
+ sharkd_json_value_stringf("tap", "follow:%s", filter);
+ json_dumper_end_object(&dumper);
- return FALSE;
+ return FALSE;
}
/**
@@ -948,99 +948,99 @@ sharkd_follower_visit_cb(const void *key _U_, void *value, void *user_data _U_)
static void
sharkd_session_process_info(void)
{
- int i;
-
- sharkd_json_result_prologue(rpcid);
-
- sharkd_json_array_open("columns");
- for (i = 0; i < NUM_COL_FMTS; i++)
- {
- const char *col_format = col_format_to_string(i);
- const char *col_descr = col_format_desc(i);
-
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("name", col_descr);
- sharkd_json_value_string("format", col_format);
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
-
- sharkd_json_array_open("stats");
- {
- GList *cfg_list = stats_tree_get_cfg_list();
- GList *l;
-
- for (l = cfg_list; l; l = l->next)
- {
- stats_tree_cfg *cfg = (stats_tree_cfg *) l->data;
-
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("name", cfg->name);
- sharkd_json_value_stringf("tap", "stat:%s", cfg->abbr);
- json_dumper_end_object(&dumper);
- }
-
- g_list_free(cfg_list);
- }
- sharkd_json_array_close();
-
- sharkd_json_array_open("ftypes");
- for (i = 0; i < FT_NUM_TYPES; i++)
- sharkd_json_value_string(NULL, ftype_name((ftenum_t) i));
- sharkd_json_array_close();
-
- sharkd_json_value_string("version", get_ws_vcs_version_info_short());
-
- sharkd_json_array_open("nstat");
- i = 0;
- stat_tap_iterate_tables(sharkd_session_process_info_nstat_cb, &i);
- sharkd_json_array_close();
-
- sharkd_json_array_open("convs");
- i = 0;
- conversation_table_iterate_tables(sharkd_session_process_info_conv_cb, &i);
- sharkd_json_array_close();
-
- sharkd_json_array_open("seqa");
- i = 0;
- sequence_analysis_table_iterate_tables(sharkd_session_seq_analysis_cb, &i);
- sharkd_json_array_close();
-
- sharkd_json_array_open("taps");
- {
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("name", "RTP streams");
- sharkd_json_value_string("tap", "rtp-streams");
- json_dumper_end_object(&dumper);
-
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("name", "Expert Information");
- sharkd_json_value_string("tap", "expert");
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
-
- sharkd_json_array_open("eo");
- i = 0;
- eo_iterate_tables(sharkd_export_object_visit_cb, &i);
- sharkd_json_array_close();
-
- sharkd_json_array_open("srt");
- i = 0;
- srt_table_iterate_tables(sharkd_srt_visit_cb, &i);
- sharkd_json_array_close();
-
- sharkd_json_array_open("rtd");
- i = 0;
- rtd_table_iterate_tables(sharkd_rtd_visit_cb, &i);
- sharkd_json_array_close();
-
- sharkd_json_array_open("follow");
- i = 0;
- follow_iterate_followers(sharkd_follower_visit_cb, &i);
- sharkd_json_array_close();
-
- sharkd_json_result_epilogue();
+ int i;
+
+ sharkd_json_result_prologue(rpcid);
+
+ sharkd_json_array_open("columns");
+ for (i = 0; i < NUM_COL_FMTS; i++)
+ {
+ const char *col_format = col_format_to_string(i);
+ const char *col_descr = col_format_desc(i);
+
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("name", col_descr);
+ sharkd_json_value_string("format", col_format);
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("stats");
+ {
+ GList *cfg_list = stats_tree_get_cfg_list();
+ GList *l;
+
+ for (l = cfg_list; l; l = l->next)
+ {
+ stats_tree_cfg *cfg = (stats_tree_cfg *) l->data;
+
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("name", cfg->name);
+ sharkd_json_value_stringf("tap", "stat:%s", cfg->abbr);
+ json_dumper_end_object(&dumper);
+ }
+
+ g_list_free(cfg_list);
+ }
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("ftypes");
+ for (i = 0; i < FT_NUM_TYPES; i++)
+ sharkd_json_value_string(NULL, ftype_name((ftenum_t) i));
+ sharkd_json_array_close();
+
+ sharkd_json_value_string("version", get_ws_vcs_version_info_short());
+
+ sharkd_json_array_open("nstat");
+ i = 0;
+ stat_tap_iterate_tables(sharkd_session_process_info_nstat_cb, &i);
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("convs");
+ i = 0;
+ conversation_table_iterate_tables(sharkd_session_process_info_conv_cb, &i);
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("seqa");
+ i = 0;
+ sequence_analysis_table_iterate_tables(sharkd_session_seq_analysis_cb, &i);
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("taps");
+ {
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("name", "RTP streams");
+ sharkd_json_value_string("tap", "rtp-streams");
+ json_dumper_end_object(&dumper);
+
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("name", "Expert Information");
+ sharkd_json_value_string("tap", "expert");
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("eo");
+ i = 0;
+ eo_iterate_tables(sharkd_export_object_visit_cb, &i);
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("srt");
+ i = 0;
+ srt_table_iterate_tables(sharkd_srt_visit_cb, &i);
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("rtd");
+ i = 0;
+ rtd_table_iterate_tables(sharkd_rtd_visit_cb, &i);
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("follow");
+ i = 0;
+ follow_iterate_followers(sharkd_follower_visit_cb, &i);
+ sharkd_json_array_close();
+
+ sharkd_json_result_epilogue();
}
/**
@@ -1057,40 +1057,40 @@ sharkd_session_process_info(void)
static void
sharkd_session_process_load(const char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_file = json_find_attr(buf, tokens, count, "file");
- int err = 0;
-
- if (!tok_file)
- return;
-
- fprintf(stderr, "load: filename=%s\n", tok_file);
-
- if (sharkd_cf_open(tok_file, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK)
- {
- sharkd_json_error(
- rpcid, -2001, NULL,
- "Unable to open the file"
- );
- return;
- }
-
- TRY
- {
- err = sharkd_load_cap_file();
- }
- CATCH(OutOfMemoryError)
- {
- sharkd_json_error(
- rpcid, -32603, NULL,
- "Load failed, out of memory"
- );
- fprintf(stderr, "load: OutOfMemoryError\n");
- err = ENOMEM;
- }
- ENDTRY;
-
- if (err == 0)
- sharkd_json_simple_ok(rpcid);
+ const char *tok_file = json_find_attr(buf, tokens, count, "file");
+ int err = 0;
+
+ if (!tok_file)
+ return;
+
+ fprintf(stderr, "load: filename=%s\n", tok_file);
+
+ if (sharkd_cf_open(tok_file, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK)
+ {
+ sharkd_json_error(
+ rpcid, -2001, NULL,
+ "Unable to open the file"
+ );
+ return;
+ }
+
+ TRY
+ {
+ err = sharkd_load_cap_file();
+ }
+ CATCH(OutOfMemoryError)
+ {
+ sharkd_json_error(
+ rpcid, -32603, NULL,
+ "Load failed, out of memory"
+ );
+ fprintf(stderr, "load: OutOfMemoryError\n");
+ err = ENOMEM;
+ }
+ ENDTRY;
+
+ if (err == 0)
+ sharkd_json_simple_ok(rpcid);
}
/**
@@ -1107,66 +1107,66 @@ sharkd_session_process_load(const char *buf, const jsmntok_t *tokens, int count)
static void
sharkd_session_process_status(void)
{
- sharkd_json_result_prologue(rpcid);
+ sharkd_json_result_prologue(rpcid);
- sharkd_json_value_anyf("frames", "%u", cfile.count);
- sharkd_json_value_anyf("duration", "%.9f", nstime_to_sec(&cfile.elapsed_time));
+ sharkd_json_value_anyf("frames", "%u", cfile.count);
+ sharkd_json_value_anyf("duration", "%.9f", nstime_to_sec(&cfile.elapsed_time));
- if (cfile.filename)
- {
- char *name = g_path_get_basename(cfile.filename);
+ if (cfile.filename)
+ {
+ char *name = g_path_get_basename(cfile.filename);
- sharkd_json_value_string("filename", name);
- g_free(name);
- }
+ sharkd_json_value_string("filename", name);
+ g_free(name);
+ }
- if (cfile.provider.wth)
- {
- gint64 file_size = wtap_file_size(cfile.provider.wth, NULL);
+ if (cfile.provider.wth)
+ {
+ gint64 file_size = wtap_file_size(cfile.provider.wth, NULL);
- if (file_size > 0)
- sharkd_json_value_anyf("filesize", "%" PRId64, file_size);
- }
+ if (file_size > 0)
+ sharkd_json_value_anyf("filesize", "%" PRId64, file_size);
+ }
- sharkd_json_result_epilogue();
+ sharkd_json_result_epilogue();
}
struct sharkd_analyse_data
{
- GHashTable *protocols_set;
- nstime_t *first_time;
- nstime_t *last_time;
+ GHashTable *protocols_set;
+ nstime_t *first_time;
+ nstime_t *last_time;
};
static void
sharkd_session_process_analyse_cb(epan_dissect_t *edt, proto_tree *tree _U_,
- struct epan_column_info *cinfo _U_, const GSList *data_src _U_, void *data)
+ struct epan_column_info *cinfo _U_, const GSList *data_src _U_, void *data)
{
- struct sharkd_analyse_data *analyser = (struct sharkd_analyse_data *) data;
- packet_info *pi = &edt->pi;
- frame_data *fdata = pi->fd;
+ struct sharkd_analyse_data *analyser = (struct sharkd_analyse_data *) data;
+ packet_info *pi = &edt->pi;
+ frame_data *fdata = pi->fd;
- if (analyser->first_time == NULL || nstime_cmp(&fdata->abs_ts, analyser->first_time) < 0)
- analyser->first_time = &fdata->abs_ts;
+ if (analyser->first_time == NULL || nstime_cmp(&fdata->abs_ts, analyser->first_time) < 0)
+ analyser->first_time = &fdata->abs_ts;
- if (analyser->last_time == NULL || nstime_cmp(&fdata->abs_ts, analyser->last_time) > 0)
- analyser->last_time = &fdata->abs_ts;
+ if (analyser->last_time == NULL || nstime_cmp(&fdata->abs_ts, analyser->last_time) > 0)
+ analyser->last_time = &fdata->abs_ts;
- if (pi->layers)
- {
- wmem_list_frame_t *frame;
+ if (pi->layers)
+ {
+ wmem_list_frame_t *frame;
- for (frame = wmem_list_head(pi->layers); frame; frame = wmem_list_frame_next(frame))
- {
- int proto_id = GPOINTER_TO_UINT(wmem_list_frame_data(frame));
+ for (frame = wmem_list_head(pi->layers); frame; frame = wmem_list_frame_next(frame))
+ {
+ int proto_id = GPOINTER_TO_UINT(wmem_list_frame_data(frame));
- if (!g_hash_table_lookup_extended(analyser->protocols_set, GUINT_TO_POINTER(proto_id), NULL, NULL))
- {
- g_hash_table_insert(analyser->protocols_set, GUINT_TO_POINTER(proto_id), GUINT_TO_POINTER(proto_id));
- sharkd_json_value_string(NULL, proto_get_protocol_filter_name(proto_id));
- }
- }
- }
+ if (!g_hash_table_lookup_extended(analyser->protocols_set, GUINT_TO_POINTER(proto_id), NULL, NULL))
+ {
+ g_hash_table_insert(analyser->protocols_set, GUINT_TO_POINTER(proto_id), GUINT_TO_POINTER(proto_id));
+ sharkd_json_value_string(NULL, proto_get_protocol_filter_name(proto_id));
+ }
+ }
+ }
}
@@ -1184,191 +1184,191 @@ sharkd_session_process_analyse_cb(epan_dissect_t *edt, proto_tree *tree _U_,
static void
sharkd_session_process_analyse(void)
{
- struct sharkd_analyse_data analyser;
- wtap_rec rec; /* Record metadata */
- Buffer rec_buf; /* Record data */
+ struct sharkd_analyse_data analyser;
+ wtap_rec rec; /* Record metadata */
+ Buffer rec_buf; /* Record data */
- analyser.first_time = NULL;
- analyser.last_time = NULL;
- analyser.protocols_set = g_hash_table_new(NULL /* g_direct_hash() */, NULL /* g_direct_equal */);
+ analyser.first_time = NULL;
+ analyser.last_time = NULL;
+ analyser.protocols_set = g_hash_table_new(NULL /* g_direct_hash() */, NULL /* g_direct_equal */);
- sharkd_json_result_prologue(rpcid);
+ sharkd_json_result_prologue(rpcid);
- sharkd_json_value_anyf("frames", "%u", cfile.count);
+ sharkd_json_value_anyf("frames", "%u", cfile.count);
- sharkd_json_array_open("protocols");
+ sharkd_json_array_open("protocols");
- wtap_rec_init(&rec);
- ws_buffer_init(&rec_buf, 1514);
+ wtap_rec_init(&rec);
+ ws_buffer_init(&rec_buf, 1514);
- for (guint32 framenum = 1; framenum <= cfile.count; framenum++)
- {
- enum dissect_request_status status;
- int err;
- gchar *err_info;
+ for (guint32 framenum = 1; framenum <= cfile.count; framenum++)
+ {
+ enum dissect_request_status status;
+ int err;
+ gchar *err_info;
- status = sharkd_dissect_request(framenum,
- (framenum != 1) ? 1 : 0, framenum - 1,
- &rec, &rec_buf, NULL, SHARKD_DISSECT_FLAG_NULL,
- &sharkd_session_process_analyse_cb, &analyser,
- &err, &err_info);
- switch (status) {
+ status = sharkd_dissect_request(framenum,
+ (framenum != 1) ? 1 : 0, framenum - 1,
+ &rec, &rec_buf, NULL, SHARKD_DISSECT_FLAG_NULL,
+ &sharkd_session_process_analyse_cb, &analyser,
+ &err, &err_info);
+ switch (status) {
- case DISSECT_REQUEST_SUCCESS:
- break;
+ case DISSECT_REQUEST_SUCCESS:
+ break;
- case DISSECT_REQUEST_NO_SUCH_FRAME:
- /* XXX - report the error. */
- break;
+ case DISSECT_REQUEST_NO_SUCH_FRAME:
+ /* XXX - report the error. */
+ break;
- case DISSECT_REQUEST_READ_ERROR:
- /*
- * Free up the error string.
- * XXX - report the error.
- */
- g_free(err_info);
- break;
- }
- }
+ case DISSECT_REQUEST_READ_ERROR:
+ /*
+ * Free up the error string.
+ * XXX - report the error.
+ */
+ g_free(err_info);
+ break;
+ }
+ }
- sharkd_json_array_close();
+ sharkd_json_array_close();
- if (analyser.first_time)
- sharkd_json_value_anyf("first", "%.9f", nstime_to_sec(analyser.first_time));
+ if (analyser.first_time)
+ sharkd_json_value_anyf("first", "%.9f", nstime_to_sec(analyser.first_time));
- if (analyser.last_time)
- sharkd_json_value_anyf("last", "%.9f", nstime_to_sec(analyser.last_time));
+ if (analyser.last_time)
+ sharkd_json_value_anyf("last", "%.9f", nstime_to_sec(analyser.last_time));
- sharkd_json_result_epilogue();
+ sharkd_json_result_epilogue();
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&rec_buf);
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&rec_buf);
- g_hash_table_destroy(analyser.protocols_set);
+ g_hash_table_destroy(analyser.protocols_set);
}
static column_info *
sharkd_session_create_columns(column_info *cinfo, const char *buf, const jsmntok_t *tokens, int count)
{
- const char *columns_custom[32];
- guint16 columns_fmt[32];
- gint16 columns_occur[32];
+ const char *columns_custom[32];
+ guint16 columns_fmt[32];
+ gint16 columns_occur[32];
- int i, cols;
+ int i, cols;
- for (i = 0; i < 32; i++)
- {
- const char *tok_column;
- char tok_column_name[64];
- char *custom_sepa;
+ for (i = 0; i < 32; i++)
+ {
+ const char *tok_column;
+ char tok_column_name[64];
+ char *custom_sepa;
- snprintf(tok_column_name, sizeof(tok_column_name), "column%d", i);
- tok_column = json_find_attr(buf, tokens, count, tok_column_name);
- if (tok_column == NULL)
- break;
+ snprintf(tok_column_name, sizeof(tok_column_name), "column%d", i);
+ tok_column = json_find_attr(buf, tokens, count, tok_column_name);
+ if (tok_column == NULL)
+ break;
- columns_custom[i] = NULL;
- columns_occur[i] = 0;
+ columns_custom[i] = NULL;
+ columns_occur[i] = 0;
- if ((custom_sepa = strchr(tok_column, ':')))
- {
- *custom_sepa = '\0'; /* XXX, C abuse: discarding-const */
+ if ((custom_sepa = strchr(tok_column, ':')))
+ {
+ *custom_sepa = '\0'; /* XXX, C abuse: discarding-const */
- columns_fmt[i] = COL_CUSTOM;
- columns_custom[i] = tok_column;
+ columns_fmt[i] = COL_CUSTOM;
+ columns_custom[i] = tok_column;
- if (!ws_strtoi16(custom_sepa + 1, NULL, &columns_occur[i]))
- return NULL;
- }
- else
- {
- if (!ws_strtou16(tok_column, NULL, &columns_fmt[i]))
- return NULL;
+ if (!ws_strtoi16(custom_sepa + 1, NULL, &columns_occur[i]))
+ return NULL;
+ }
+ else
+ {
+ if (!ws_strtou16(tok_column, NULL, &columns_fmt[i]))
+ return NULL;
- if (columns_fmt[i] >= NUM_COL_FMTS)
- return NULL;
+ if (columns_fmt[i] >= NUM_COL_FMTS)
+ return NULL;
- /* if custom, that it shouldn't be just custom number -> error */
- if (columns_fmt[i] == COL_CUSTOM)
- return NULL;
- }
- }
+ /* if custom, that it shouldn't be just custom number -> error */
+ if (columns_fmt[i] == COL_CUSTOM)
+ return NULL;
+ }
+ }
- cols = i;
+ cols = i;
- col_setup(cinfo, cols);
+ col_setup(cinfo, cols);
- for (i = 0; i < cols; i++)
- {
- col_item_t *col_item = &cinfo->columns[i];
+ for (i = 0; i < cols; i++)
+ {
+ col_item_t *col_item = &cinfo->columns[i];
- col_item->col_fmt = columns_fmt[i];
- col_item->col_title = NULL; /* no need for title */
+ col_item->col_fmt = columns_fmt[i];
+ col_item->col_title = NULL; /* no need for title */
- if (col_item->col_fmt == COL_CUSTOM)
- {
- col_item->col_custom_fields = g_strdup(columns_custom[i]);
- col_item->col_custom_occurrence = columns_occur[i];
- }
+ if (col_item->col_fmt == COL_CUSTOM)
+ {
+ col_item->col_custom_fields = g_strdup(columns_custom[i]);
+ col_item->col_custom_occurrence = columns_occur[i];
+ }
- col_item->col_fence = 0;
- }
+ col_item->col_fence = 0;
+ }
- col_finalize(cinfo);
+ col_finalize(cinfo);
- return cinfo;
+ return cinfo;
}
static void
sharkd_session_process_frames_cb(epan_dissect_t *edt, proto_tree *tree _U_,
- struct epan_column_info *cinfo, const GSList *data_src _U_, void *data _U_)
+ struct epan_column_info *cinfo, const GSList *data_src _U_, void *data _U_)
{
- packet_info *pi = &edt->pi;
- frame_data *fdata = pi->fd;
- wtap_block_t pkt_block = NULL;
- char *comment;
-
- json_dumper_begin_object(&dumper);
-
- sharkd_json_array_open("c");
- for (int col = 0; col < cinfo->num_cols; ++col)
- {
- const col_item_t *col_item = &cinfo->columns[col];
-
- sharkd_json_value_string(NULL, col_item->col_data);
- }
- sharkd_json_array_close();
-
- sharkd_json_value_anyf("num", "%u", pi->num);
-
- /*
- * Get the block for this record, if it has one.
- */
- if (fdata->has_modified_block)
- pkt_block = sharkd_get_modified_block(fdata);
- else
- pkt_block = pi->rec->block;
-
- /*
- * Does this record have any comments?
- */
- if (pkt_block != NULL &&
- WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT, 0, &comment))
- sharkd_json_value_anyf("ct", "true");
-
- if (fdata->ignored)
- sharkd_json_value_anyf("i", "true");
-
- if (fdata->marked)
- sharkd_json_value_anyf("m", "true");
-
- if (fdata->color_filter)
- {
- sharkd_json_value_stringf("bg", "%x", color_t_to_rgb(&fdata->color_filter->bg_color));
- sharkd_json_value_stringf("fg", "%x", color_t_to_rgb(&fdata->color_filter->fg_color));
- }
-
- json_dumper_end_object(&dumper);
+ packet_info *pi = &edt->pi;
+ frame_data *fdata = pi->fd;
+ wtap_block_t pkt_block = NULL;
+ char *comment;
+
+ json_dumper_begin_object(&dumper);
+
+ sharkd_json_array_open("c");
+ for (int col = 0; col < cinfo->num_cols; ++col)
+ {
+ const col_item_t *col_item = &cinfo->columns[col];
+
+ sharkd_json_value_string(NULL, col_item->col_data);
+ }
+ sharkd_json_array_close();
+
+ sharkd_json_value_anyf("num", "%u", pi->num);
+
+ /*
+ * Get the block for this record, if it has one.
+ */
+ if (fdata->has_modified_block)
+ pkt_block = sharkd_get_modified_block(fdata);
+ else
+ pkt_block = pi->rec->block;
+
+ /*
+ * Does this record have any comments?
+ */
+ if (pkt_block != NULL &&
+ WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT, 0, &comment))
+ sharkd_json_value_anyf("ct", "true");
+
+ if (fdata->ignored)
+ sharkd_json_value_anyf("i", "true");
+
+ if (fdata->marked)
+ sharkd_json_value_anyf("m", "true");
+
+ if (fdata->color_filter)
+ {
+ sharkd_json_value_stringf("bg", "%x", color_t_to_rgb(&fdata->color_filter->bg_color));
+ sharkd_json_value_stringf("fg", "%x", color_t_to_rgb(&fdata->color_filter->fg_color));
+ }
+
+ json_dumper_end_object(&dumper);
}
/**
@@ -1396,211 +1396,211 @@ sharkd_session_process_frames_cb(epan_dissect_t *edt, proto_tree *tree _U_,
static void
sharkd_session_process_frames(const char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
- const char *tok_column = json_find_attr(buf, tokens, count, "column0");
- const char *tok_skip = json_find_attr(buf, tokens, count, "skip");
- const char *tok_limit = json_find_attr(buf, tokens, count, "limit");
- const char *tok_refs = json_find_attr(buf, tokens, count, "refs");
-
- const guint8 *filter_data = NULL;
-
- guint32 next_ref_frame = G_MAXUINT32;
- guint32 skip;
- guint32 limit;
-
- wtap_rec rec; /* Record metadata */
- Buffer rec_buf; /* Record data */
- column_info *cinfo = &cfile.cinfo;
- column_info user_cinfo;
-
- if (tok_column)
- {
- memset(&user_cinfo, 0, sizeof(user_cinfo));
- cinfo = sharkd_session_create_columns(&user_cinfo, buf, tokens, count);
- if (!cinfo)
- {
- sharkd_json_error(
- rpcid, -13001, NULL,
- "Column definition invalid - note column 6 requires a custom definition"
- );
- return;
- }
- }
-
- if (tok_filter)
- {
- const struct sharkd_filter_item *filter_item;
-
- filter_item = sharkd_session_filter_data(tok_filter);
- if (!filter_item)
- {
- sharkd_json_error(
- rpcid, -13002, NULL,
- "Filter expression invalid"
- );
- return;
- }
-
- filter_data = filter_item->filtered;
- }
-
- skip = 0;
- if (tok_skip)
- {
- if (!ws_strtou32(tok_skip, NULL, &skip))
- return;
- }
-
- limit = 0;
- if (tok_limit)
- {
- if (!ws_strtou32(tok_limit, NULL, &limit))
- return;
- }
-
- if (tok_refs)
- {
- if (!ws_strtou32(tok_refs, &tok_refs, &next_ref_frame))
- return;
- }
-
- sharkd_json_result_array_prologue(rpcid);
-
- wtap_rec_init(&rec);
- ws_buffer_init(&rec_buf, 1514);
-
- for (guint32 framenum = 1; framenum <= cfile.count; framenum++)
- {
- frame_data *fdata;
- enum dissect_request_status status;
- int err;
- gchar *err_info;
-
- if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))
- continue;
-
- if (skip)
- {
- skip--;
- continue;
- }
-
- if (tok_refs)
- {
- if (framenum >= next_ref_frame)
- {
- if (*tok_refs != ',')
- next_ref_frame = G_MAXUINT32;
-
- while (*tok_refs == ',' && framenum >= next_ref_frame)
- {
- if (!ws_strtou32(tok_refs + 1, &tok_refs, &next_ref_frame))
- {
- fprintf(stderr, "sharkd_session_process_frames() wrong format for refs: %s\n", tok_refs);
- break;
- }
- }
-
- if (*tok_refs == '\0' && framenum >= next_ref_frame)
- {
- next_ref_frame = G_MAXUINT32;
- }
- }
- }
-
- fdata = sharkd_get_frame(framenum);
- status = sharkd_dissect_request(framenum,
- (framenum != 1) ? 1 : 0, framenum - 1,
- &rec, &rec_buf, cinfo,
- (fdata->color_filter == NULL) ? SHARKD_DISSECT_FLAG_COLOR : SHARKD_DISSECT_FLAG_NULL,
- &sharkd_session_process_frames_cb, NULL,
- &err, &err_info);
- switch (status) {
-
- case DISSECT_REQUEST_SUCCESS:
- break;
-
- case DISSECT_REQUEST_NO_SUCH_FRAME:
- /* XXX - report the error. */
- break;
-
- case DISSECT_REQUEST_READ_ERROR:
- /*
- * Free up the error string.
- * XXX - report the error.
- */
- g_free(err_info);
- break;
- }
-
- if (limit && --limit == 0)
- break;
- }
- sharkd_json_result_array_epilogue();
-
- if (cinfo != &cfile.cinfo)
- col_cleanup(cinfo);
-
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&rec_buf);
+ const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
+ const char *tok_column = json_find_attr(buf, tokens, count, "column0");
+ const char *tok_skip = json_find_attr(buf, tokens, count, "skip");
+ const char *tok_limit = json_find_attr(buf, tokens, count, "limit");
+ const char *tok_refs = json_find_attr(buf, tokens, count, "refs");
+
+ const guint8 *filter_data = NULL;
+
+ guint32 next_ref_frame = G_MAXUINT32;
+ guint32 skip;
+ guint32 limit;
+
+ wtap_rec rec; /* Record metadata */
+ Buffer rec_buf; /* Record data */
+ column_info *cinfo = &cfile.cinfo;
+ column_info user_cinfo;
+
+ if (tok_column)
+ {
+ memset(&user_cinfo, 0, sizeof(user_cinfo));
+ cinfo = sharkd_session_create_columns(&user_cinfo, buf, tokens, count);
+ if (!cinfo)
+ {
+ sharkd_json_error(
+ rpcid, -13001, NULL,
+ "Column definition invalid - note column 6 requires a custom definition"
+ );
+ return;
+ }
+ }
+
+ if (tok_filter)
+ {
+ const struct sharkd_filter_item *filter_item;
+
+ filter_item = sharkd_session_filter_data(tok_filter);
+ if (!filter_item)
+ {
+ sharkd_json_error(
+ rpcid, -13002, NULL,
+ "Filter expression invalid"
+ );
+ return;
+ }
+
+ filter_data = filter_item->filtered;
+ }
+
+ skip = 0;
+ if (tok_skip)
+ {
+ if (!ws_strtou32(tok_skip, NULL, &skip))
+ return;
+ }
+
+ limit = 0;
+ if (tok_limit)
+ {
+ if (!ws_strtou32(tok_limit, NULL, &limit))
+ return;
+ }
+
+ if (tok_refs)
+ {
+ if (!ws_strtou32(tok_refs, &tok_refs, &next_ref_frame))
+ return;
+ }
+
+ sharkd_json_result_array_prologue(rpcid);
+
+ wtap_rec_init(&rec);
+ ws_buffer_init(&rec_buf, 1514);
+
+ for (guint32 framenum = 1; framenum <= cfile.count; framenum++)
+ {
+ frame_data *fdata;
+ enum dissect_request_status status;
+ int err;
+ gchar *err_info;
+
+ if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))
+ continue;
+
+ if (skip)
+ {
+ skip--;
+ continue;
+ }
+
+ if (tok_refs)
+ {
+ if (framenum >= next_ref_frame)
+ {
+ if (*tok_refs != ',')
+ next_ref_frame = G_MAXUINT32;
+
+ while (*tok_refs == ',' && framenum >= next_ref_frame)
+ {
+ if (!ws_strtou32(tok_refs + 1, &tok_refs, &next_ref_frame))
+ {
+ fprintf(stderr, "sharkd_session_process_frames() wrong format for refs: %s\n", tok_refs);
+ break;
+ }
+ }
+
+ if (*tok_refs == '\0' && framenum >= next_ref_frame)
+ {
+ next_ref_frame = G_MAXUINT32;
+ }
+ }
+ }
+
+ fdata = sharkd_get_frame(framenum);
+ status = sharkd_dissect_request(framenum,
+ (framenum != 1) ? 1 : 0, framenum - 1,
+ &rec, &rec_buf, cinfo,
+ (fdata->color_filter == NULL) ? SHARKD_DISSECT_FLAG_COLOR : SHARKD_DISSECT_FLAG_NULL,
+ &sharkd_session_process_frames_cb, NULL,
+ &err, &err_info);
+ switch (status) {
+
+ case DISSECT_REQUEST_SUCCESS:
+ break;
+
+ case DISSECT_REQUEST_NO_SUCH_FRAME:
+ /* XXX - report the error. */
+ break;
+
+ case DISSECT_REQUEST_READ_ERROR:
+ /*
+ * Free up the error string.
+ * XXX - report the error.
+ */
+ g_free(err_info);
+ break;
+ }
+
+ if (limit && --limit == 0)
+ break;
+ }
+ sharkd_json_result_array_epilogue();
+
+ if (cinfo != &cfile.cinfo)
+ col_cleanup(cinfo);
+
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&rec_buf);
}
static void
sharkd_session_process_tap_stats_node_cb(const stat_node *n)
{
- stat_node *node;
-
- sharkd_json_array_open(NULL);
- for (node = n->children; node; node = node->next)
- {
- json_dumper_begin_object(&dumper);
-
- /* code based on stats_tree_get_values_from_node() */
- sharkd_json_value_string("name", node->name);
- sharkd_json_value_anyf("count", "%d", node->counter);
- if (node->counter && ((node->st_flags & ST_FLG_AVERAGE) || node->rng))
- {
- switch(node->datatype)
- {
- case STAT_DT_INT:
- sharkd_json_value_anyf("avg", "%.2f", ((float)node->total.int_total) / node->counter);
- sharkd_json_value_anyf("min", "%d", node->minvalue.int_min);
- sharkd_json_value_anyf("max", "%d", node->maxvalue.int_max);
- break;
- case STAT_DT_FLOAT:
- sharkd_json_value_anyf("avg", "%.2f", node->total.float_total / node->counter);
- sharkd_json_value_anyf("min", "%f", node->minvalue.float_min);
- sharkd_json_value_anyf("max", "%f", node->maxvalue.float_max);
- break;
- }
- }
-
- if (node->st->elapsed)
- sharkd_json_value_anyf("rate", "%.4f", ((float)node->counter) / node->st->elapsed);
-
- if (node->parent && node->parent->counter)
- sharkd_json_value_anyf("perc", "%.2f", (node->counter * 100.0) / node->parent->counter);
- else if (node->parent == &(node->st->root))
- sharkd_json_value_anyf("perc", "100");
-
- if (prefs.st_enable_burstinfo && node->max_burst)
- {
- if (prefs.st_burst_showcount)
- sharkd_json_value_anyf("burstcount", "%d", node->max_burst);
- else
- sharkd_json_value_anyf("burstrate", "%.4f", ((double)node->max_burst) / prefs.st_burst_windowlen);
-
- sharkd_json_value_anyf("bursttime", "%.3f", (node->burst_time / 1000.0));
- }
-
- if (node->children)
- {
- sharkd_json_value_anyf("sub", NULL);
- sharkd_session_process_tap_stats_node_cb(node);
- }
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
+ stat_node *node;
+
+ sharkd_json_array_open(NULL);
+ for (node = n->children; node; node = node->next)
+ {
+ json_dumper_begin_object(&dumper);
+
+ /* code based on stats_tree_get_values_from_node() */
+ sharkd_json_value_string("name", node->name);
+ sharkd_json_value_anyf("count", "%d", node->counter);
+ if (node->counter && ((node->st_flags & ST_FLG_AVERAGE) || node->rng))
+ {
+ switch(node->datatype)
+ {
+ case STAT_DT_INT:
+ sharkd_json_value_anyf("avg", "%.2f", ((float)node->total.int_total) / node->counter);
+ sharkd_json_value_anyf("min", "%d", node->minvalue.int_min);
+ sharkd_json_value_anyf("max", "%d", node->maxvalue.int_max);
+ break;
+ case STAT_DT_FLOAT:
+ sharkd_json_value_anyf("avg", "%.2f", node->total.float_total / node->counter);
+ sharkd_json_value_anyf("min", "%f", node->minvalue.float_min);
+ sharkd_json_value_anyf("max", "%f", node->maxvalue.float_max);
+ break;
+ }
+ }
+
+ if (node->st->elapsed)
+ sharkd_json_value_anyf("rate", "%.4f", ((float)node->counter) / node->st->elapsed);
+
+ if (node->parent && node->parent->counter)
+ sharkd_json_value_anyf("perc", "%.2f", (node->counter * 100.0) / node->parent->counter);
+ else if (node->parent == &(node->st->root))
+ sharkd_json_value_anyf("perc", "100");
+
+ if (prefs.st_enable_burstinfo && node->max_burst)
+ {
+ if (prefs.st_burst_showcount)
+ sharkd_json_value_anyf("burstcount", "%d", node->max_burst);
+ else
+ sharkd_json_value_anyf("burstrate", "%.4f", ((double)node->max_burst) / prefs.st_burst_windowlen);
+
+ sharkd_json_value_anyf("bursttime", "%.3f", (node->burst_time / 1000.0));
+ }
+
+ if (node->children)
+ {
+ sharkd_json_value_anyf("sub", NULL);
+ sharkd_session_process_tap_stats_node_cb(node);
+ }
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
}
/**
@@ -1627,32 +1627,32 @@ sharkd_session_process_tap_stats_node_cb(const stat_node *n)
static void
sharkd_session_process_tap_stats_cb(void *psp)
{
- stats_tree *st = (stats_tree *) psp;
+ stats_tree *st = (stats_tree *) psp;
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("tap", "stats:%s", st->cfg->abbr);
- sharkd_json_value_string("type", "stats");
- sharkd_json_value_string("name", st->cfg->name);
+ sharkd_json_value_stringf("tap", "stats:%s", st->cfg->abbr);
+ sharkd_json_value_string("type", "stats");
+ sharkd_json_value_string("name", st->cfg->name);
- sharkd_json_value_anyf("stats", NULL);
- sharkd_session_process_tap_stats_node_cb(&st->root);
+ sharkd_json_value_anyf("stats", NULL);
+ sharkd_session_process_tap_stats_node_cb(&st->root);
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
}
static void
sharkd_session_free_tap_stats_cb(void *psp)
{
- stats_tree *st = (stats_tree *) psp;
+ stats_tree *st = (stats_tree *) psp;
- stats_tree_free(st);
+ stats_tree_free(st);
}
struct sharkd_expert_tap
{
- GSList *details;
- GStringChunk *text;
+ GSList *details;
+ GStringChunk *text;
};
/**
@@ -1672,75 +1672,75 @@ struct sharkd_expert_tap
static void
sharkd_session_process_tap_expert_cb(void *tapdata)
{
- struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
- GSList *list;
+ struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
+ GSList *list;
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- sharkd_json_value_string("tap", "expert");
- sharkd_json_value_string("type", "expert");
+ sharkd_json_value_string("tap", "expert");
+ sharkd_json_value_string("type", "expert");
- sharkd_json_array_open("details");
- for (list = etd->details; list; list = list->next)
- {
- expert_info_t *ei = (expert_info_t *) list->data;
- const char *tmp;
+ sharkd_json_array_open("details");
+ for (list = etd->details; list; list = list->next)
+ {
+ expert_info_t *ei = (expert_info_t *) list->data;
+ const char *tmp;
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- sharkd_json_value_anyf("f", "%u", ei->packet_num);
+ sharkd_json_value_anyf("f", "%u", ei->packet_num);
- tmp = try_val_to_str(ei->severity, expert_severity_vals);
- if (tmp)
- sharkd_json_value_string("s", tmp);
+ tmp = try_val_to_str(ei->severity, expert_severity_vals);
+ if (tmp)
+ sharkd_json_value_string("s", tmp);
- tmp = try_val_to_str(ei->group, expert_group_vals);
- if (tmp)
- sharkd_json_value_string("g", tmp);
+ tmp = try_val_to_str(ei->group, expert_group_vals);
+ if (tmp)
+ sharkd_json_value_string("g", tmp);
- sharkd_json_value_string("m", ei->summary);
+ sharkd_json_value_string("m", ei->summary);
- if (ei->protocol)
- sharkd_json_value_string("p", ei->protocol);
+ if (ei->protocol)
+ sharkd_json_value_string("p", ei->protocol);
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
}
static tap_packet_status
sharkd_session_packet_tap_expert_cb(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pointer)
{
- struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
- const expert_info_t *ei = (const expert_info_t *) pointer;
- expert_info_t *ei_copy;
+ struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
+ const expert_info_t *ei = (const expert_info_t *) pointer;
+ expert_info_t *ei_copy;
- if (ei == NULL)
- return TAP_PACKET_DONT_REDRAW;
+ if (ei == NULL)
+ return TAP_PACKET_DONT_REDRAW;
- ei_copy = g_new(expert_info_t, 1);
- /* Note: this is a shallow copy */
- *ei_copy = *ei;
+ ei_copy = g_new(expert_info_t, 1);
+ /* Note: this is a shallow copy */
+ *ei_copy = *ei;
- /* ei->protocol, ei->summary might be allocated in packet scope, make a copy. */
- ei_copy->protocol = g_string_chunk_insert_const(etd->text, ei_copy->protocol);
- ei_copy->summary = g_string_chunk_insert_const(etd->text, ei_copy->summary);
+ /* ei->protocol, ei->summary might be allocated in packet scope, make a copy. */
+ ei_copy->protocol = g_string_chunk_insert_const(etd->text, ei_copy->protocol);
+ ei_copy->summary = g_string_chunk_insert_const(etd->text, ei_copy->summary);
- etd->details = g_slist_prepend(etd->details, ei_copy);
+ etd->details = g_slist_prepend(etd->details, ei_copy);
- return TAP_PACKET_REDRAW;
+ return TAP_PACKET_REDRAW;
}
static void
sharkd_session_free_tap_expert_cb(void *tapdata)
{
- struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
+ struct sharkd_expert_tap *etd = (struct sharkd_expert_tap *) tapdata;
- g_slist_free_full(etd->details, g_free);
- g_string_chunk_free(etd->text);
- g_free(etd);
+ g_slist_free_full(etd->details, g_free);
+ g_string_chunk_free(etd->text);
+ g_free(etd);
}
/**
@@ -1759,217 +1759,217 @@ sharkd_session_free_tap_expert_cb(void *tapdata)
static void
sharkd_session_process_tap_flow_cb(void *tapdata)
{
- seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;
- GList *flow_list;
- guint i;
+ seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;
+ GList *flow_list;
+ guint i;
- sequence_analysis_get_nodes(graph_analysis);
+ sequence_analysis_get_nodes(graph_analysis);
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("tap", "seqa:%s", graph_analysis->name);
- sharkd_json_value_string("type", "flow");
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("tap", "seqa:%s", graph_analysis->name);
+ sharkd_json_value_string("type", "flow");
- sharkd_json_array_open("nodes");
- for (i = 0; i < graph_analysis->num_nodes; i++)
- {
- char *addr_str;
+ sharkd_json_array_open("nodes");
+ for (i = 0; i < graph_analysis->num_nodes; i++)
+ {
+ char *addr_str;
- addr_str = address_to_display(NULL, &(graph_analysis->nodes[i]));
- sharkd_json_value_string(NULL, addr_str);
- wmem_free(NULL, addr_str);
- }
- sharkd_json_array_close();
+ addr_str = address_to_display(NULL, &(graph_analysis->nodes[i]));
+ sharkd_json_value_string(NULL, addr_str);
+ wmem_free(NULL, addr_str);
+ }
+ sharkd_json_array_close();
- sharkd_json_array_open("flows");
- flow_list = g_queue_peek_nth_link(graph_analysis->items, 0);
- while (flow_list)
- {
- seq_analysis_item_t *sai = (seq_analysis_item_t *) flow_list->data;
+ sharkd_json_array_open("flows");
+ flow_list = g_queue_peek_nth_link(graph_analysis->items, 0);
+ while (flow_list)
+ {
+ seq_analysis_item_t *sai = (seq_analysis_item_t *) flow_list->data;
- flow_list = g_list_next(flow_list);
+ flow_list = g_list_next(flow_list);
- if (!sai->display)
- continue;
+ if (!sai->display)
+ continue;
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- sharkd_json_value_string("t", sai->time_str);
- sharkd_json_value_anyf("n", "[%u,%u]", sai->src_node, sai->dst_node);
- sharkd_json_value_anyf("pn", "[%u,%u]", sai->port_src, sai->port_dst);
+ sharkd_json_value_string("t", sai->time_str);
+ sharkd_json_value_anyf("n", "[%u,%u]", sai->src_node, sai->dst_node);
+ sharkd_json_value_anyf("pn", "[%u,%u]", sai->port_src, sai->port_dst);
- if (sai->comment)
- sharkd_json_value_string("c", sai->comment);
+ if (sai->comment)
+ sharkd_json_value_string("c", sai->comment);
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
}
static void
sharkd_session_free_tap_flow_cb(void *tapdata)
{
- seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;
+ seq_analysis_info_t *graph_analysis = (seq_analysis_info_t *) tapdata;
- sequence_analysis_info_free(graph_analysis);
+ sequence_analysis_info_free(graph_analysis);
}
struct sharkd_conv_tap_data
{
- const char *type;
- conv_hash_t hash;
- gboolean resolve_name;
- gboolean resolve_port;
+ const char *type;
+ conv_hash_t hash;
+ gboolean resolve_name;
+ gboolean resolve_port;
};
static gboolean
sharkd_session_geoip_addr(address *addr, const char *suffix)
{
- const mmdb_lookup_t *lookup = NULL;
- gboolean with_geoip = FALSE;
- char json_key[64];
-
- if (addr->type == AT_IPv4)
- {
- const ws_in4_addr *ip4 = (const ws_in4_addr *) addr->data;
-
- lookup = maxmind_db_lookup_ipv4(ip4);
- }
- else if (addr->type == AT_IPv6)
- {
- const ws_in6_addr *ip6 = (const ws_in6_addr *) addr->data;
-
- lookup = maxmind_db_lookup_ipv6(ip6);
- }
-
- if (!lookup || !lookup->found)
- return FALSE;
-
- if (lookup->country)
- {
- snprintf(json_key, sizeof(json_key), "geoip_country%s", suffix);
- sharkd_json_value_string(json_key, lookup->country);
- with_geoip = TRUE;
- }
-
- if (lookup->country_iso)
- {
- snprintf(json_key, sizeof(json_key), "geoip_country_iso%s", suffix);
- sharkd_json_value_string(json_key, lookup->country_iso);
- with_geoip = TRUE;
- }
-
- if (lookup->city)
- {
- snprintf(json_key, sizeof(json_key), "geoip_city%s", suffix);
- sharkd_json_value_string(json_key, lookup->city);
- with_geoip = TRUE;
- }
-
- if (lookup->as_org)
- {
- snprintf(json_key, sizeof(json_key), "geoip_as_org%s", suffix);
- sharkd_json_value_string(json_key, lookup->as_org);
- with_geoip = TRUE;
- }
-
- if (lookup->as_number > 0)
- {
- snprintf(json_key, sizeof(json_key), "geoip_as%s", suffix);
- sharkd_json_value_anyf(json_key, "%u", lookup->as_number);
- with_geoip = TRUE;
- }
-
- if (lookup->latitude >= -90.0 && lookup->latitude <= 90.0)
- {
- snprintf(json_key, sizeof(json_key), "geoip_lat%s", suffix);
- sharkd_json_value_anyf(json_key, "%f", lookup->latitude);
- with_geoip = TRUE;
- }
-
- if (lookup->longitude >= -180.0 && lookup->longitude <= 180.0)
- {
- snprintf(json_key, sizeof(json_key), "geoip_lon%s", suffix);
- sharkd_json_value_anyf(json_key, "%f", lookup->longitude);
- with_geoip = TRUE;
- }
-
- return with_geoip;
+ const mmdb_lookup_t *lookup = NULL;
+ gboolean with_geoip = FALSE;
+ char json_key[64];
+
+ if (addr->type == AT_IPv4)
+ {
+ const ws_in4_addr *ip4 = (const ws_in4_addr *) addr->data;
+
+ lookup = maxmind_db_lookup_ipv4(ip4);
+ }
+ else if (addr->type == AT_IPv6)
+ {
+ const ws_in6_addr *ip6 = (const ws_in6_addr *) addr->data;
+
+ lookup = maxmind_db_lookup_ipv6(ip6);
+ }
+
+ if (!lookup || !lookup->found)
+ return FALSE;
+
+ if (lookup->country)
+ {
+ snprintf(json_key, sizeof(json_key), "geoip_country%s", suffix);
+ sharkd_json_value_string(json_key, lookup->country);
+ with_geoip = TRUE;
+ }
+
+ if (lookup->country_iso)
+ {
+ snprintf(json_key, sizeof(json_key), "geoip_country_iso%s", suffix);
+ sharkd_json_value_string(json_key, lookup->country_iso);
+ with_geoip = TRUE;
+ }
+
+ if (lookup->city)
+ {
+ snprintf(json_key, sizeof(json_key), "geoip_city%s", suffix);
+ sharkd_json_value_string(json_key, lookup->city);
+ with_geoip = TRUE;
+ }
+
+ if (lookup->as_org)
+ {
+ snprintf(json_key, sizeof(json_key), "geoip_as_org%s", suffix);
+ sharkd_json_value_string(json_key, lookup->as_org);
+ with_geoip = TRUE;
+ }
+
+ if (lookup->as_number > 0)
+ {
+ snprintf(json_key, sizeof(json_key), "geoip_as%s", suffix);
+ sharkd_json_value_anyf(json_key, "%u", lookup->as_number);
+ with_geoip = TRUE;
+ }
+
+ if (lookup->latitude >= -90.0 && lookup->latitude <= 90.0)
+ {
+ snprintf(json_key, sizeof(json_key), "geoip_lat%s", suffix);
+ sharkd_json_value_anyf(json_key, "%f", lookup->latitude);
+ with_geoip = TRUE;
+ }
+
+ if (lookup->longitude >= -180.0 && lookup->longitude <= 180.0)
+ {
+ snprintf(json_key, sizeof(json_key), "geoip_lon%s", suffix);
+ sharkd_json_value_anyf(json_key, "%f", lookup->longitude);
+ with_geoip = TRUE;
+ }
+
+ return with_geoip;
}
struct sharkd_analyse_rtp_items
{
- guint32 frame_num;
- guint32 sequence_num;
+ guint32 frame_num;
+ guint32 sequence_num;
- double delta;
- double jitter;
- double skew;
- double bandwidth;
- gboolean marker;
+ double delta;
+ double jitter;
+ double skew;
+ double bandwidth;
+ gboolean marker;
- double arrive_offset;
+ double arrive_offset;
- /* from tap_rtp_stat_t */
- guint32 flags;
- guint16 pt;
+ /* from tap_rtp_stat_t */
+ guint32 flags;
+ guint16 pt;
};
struct sharkd_analyse_rtp
{
- const char *tap_name;
- rtpstream_id_t id;
+ const char *tap_name;
+ rtpstream_id_t id;
- GSList *packets;
- double start_time;
- tap_rtp_stat_t statinfo;
+ GSList *packets;
+ double start_time;
+ tap_rtp_stat_t statinfo;
};
static void
sharkd_session_process_tap_rtp_free_cb(void *tapdata)
{
- struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
+ struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
- g_slist_free_full(rtp_req->packets, g_free);
- g_free(rtp_req);
+ g_slist_free_full(rtp_req->packets, g_free);
+ g_free(rtp_req);
}
static tap_packet_status
sharkd_session_packet_tap_rtp_analyse_cb(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pointer)
{
- struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
- const struct _rtp_info *rtp_info = (const struct _rtp_info *) pointer;
+ struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
+ const struct _rtp_info *rtp_info = (const struct _rtp_info *) pointer;
- if (rtpstream_id_equal_pinfo_rtp_info(&rtp_req->id, pinfo, rtp_info))
- {
- tap_rtp_stat_t *statinfo = &(rtp_req->statinfo);
- struct sharkd_analyse_rtp_items *item;
+ if (rtpstream_id_equal_pinfo_rtp_info(&rtp_req->id, pinfo, rtp_info))
+ {
+ tap_rtp_stat_t *statinfo = &(rtp_req->statinfo);
+ struct sharkd_analyse_rtp_items *item;
- rtppacket_analyse(statinfo, pinfo, rtp_info);
+ rtppacket_analyse(statinfo, pinfo, rtp_info);
- item = g_new(struct sharkd_analyse_rtp_items, 1);
+ item = g_new(struct sharkd_analyse_rtp_items, 1);
- if (!rtp_req->packets)
- rtp_req->start_time = nstime_to_sec(&pinfo->abs_ts);
+ if (!rtp_req->packets)
+ rtp_req->start_time = nstime_to_sec(&pinfo->abs_ts);
- item->frame_num = pinfo->num;
- item->sequence_num = rtp_info->info_seq_num;
- item->delta = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->delta;
- item->jitter = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->jitter;
- item->skew = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->skew;
- item->bandwidth = statinfo->bandwidth;
- item->marker = rtp_info->info_marker_set ? TRUE : FALSE;
- item->arrive_offset= nstime_to_sec(&pinfo->abs_ts) - rtp_req->start_time;
+ item->frame_num = pinfo->num;
+ item->sequence_num = rtp_info->info_seq_num;
+ item->delta = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->delta;
+ item->jitter = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->jitter;
+ item->skew = (statinfo->flags & STAT_FLAG_FIRST) ? 0.0 : statinfo->skew;
+ item->bandwidth = statinfo->bandwidth;
+ item->marker = rtp_info->info_marker_set ? TRUE : FALSE;
+ item->arrive_offset= nstime_to_sec(&pinfo->abs_ts) - rtp_req->start_time;
- item->flags = statinfo->flags;
- item->pt = statinfo->pt;
+ item->flags = statinfo->flags;
+ item->pt = statinfo->pt;
- /* XXX, O(n) optimize */
- rtp_req->packets = g_slist_append(rtp_req->packets, item);
- }
+ /* XXX, O(n) optimize */
+ rtp_req->packets = g_slist_append(rtp_req->packets, item);
+ }
- return TAP_PACKET_REDRAW;
+ return TAP_PACKET_REDRAW;
}
/**
@@ -2002,105 +2002,105 @@ sharkd_session_packet_tap_rtp_analyse_cb(void *tapdata, packet_info *pinfo, epan
static void
sharkd_session_process_tap_rtp_analyse_cb(void *tapdata)
{
- const int RTP_TYPE_CN = 1;
- const int RTP_TYPE_ERROR = 2;
- const int RTP_TYPE_WARN = 3;
- const int RTP_TYPE_PT_EVENT = 4;
-
- const struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
- const tap_rtp_stat_t *statinfo = &rtp_req->statinfo;
-
- GSList *l;
-
- json_dumper_begin_object(&dumper);
-
- sharkd_json_value_string("tap", rtp_req->tap_name);
- sharkd_json_value_string("type", "rtp-analyse");
- sharkd_json_value_anyf("ssrc", "%u", rtp_req->id.ssrc);
-
- sharkd_json_value_anyf("max_delta", "%f", statinfo->max_delta);
- sharkd_json_value_anyf("max_delta_nr", "%u", statinfo->max_nr);
- sharkd_json_value_anyf("max_jitter", "%f", statinfo->max_jitter);
- sharkd_json_value_anyf("mean_jitter", "%f", statinfo->mean_jitter);
- sharkd_json_value_anyf("max_skew", "%f", statinfo->max_skew);
- sharkd_json_value_anyf("total_nr", "%u", statinfo->total_nr);
- sharkd_json_value_anyf("seq_err", "%u", statinfo->sequence);
- sharkd_json_value_anyf("duration", "%f", statinfo->time - statinfo->start_time);
-
- sharkd_json_array_open("items");
- for (l = rtp_req->packets; l; l = l->next)
- {
- struct sharkd_analyse_rtp_items *item = (struct sharkd_analyse_rtp_items *) l->data;
-
- json_dumper_begin_object(&dumper);
-
- sharkd_json_value_anyf("f", "%u", item->frame_num);
- sharkd_json_value_anyf("o", "%.9f", item->arrive_offset);
- sharkd_json_value_anyf("sn", "%u", item->sequence_num);
- sharkd_json_value_anyf("d", "%.2f", item->delta);
- sharkd_json_value_anyf("j", "%.2f", item->jitter);
- sharkd_json_value_anyf("sk", "%.2f", item->skew);
- sharkd_json_value_anyf("bw", "%.2f", item->bandwidth);
-
- if (item->pt == PT_CN)
- {
- sharkd_json_value_string("s", "Comfort noise (PT=13, RFC 3389)");
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_CN);
- }
- else if (item->pt == PT_CN_OLD)
- {
- sharkd_json_value_string("s", "Comfort noise (PT=19, reserved)");
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_CN);
- }
- else if (item->flags & STAT_FLAG_WRONG_SEQ)
- {
- sharkd_json_value_string("s", "Wrong sequence number");
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_ERROR);
- }
- else if (item->flags & STAT_FLAG_DUP_PKT)
- {
- sharkd_json_value_string("s", "Suspected duplicate (MAC address) only delta time calculated");
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
- }
- else if (item->flags & STAT_FLAG_REG_PT_CHANGE)
- {
- sharkd_json_value_stringf("s", "Payload changed to PT=%u%s",
- item->pt,
- (item->flags & STAT_FLAG_PT_T_EVENT) ? " telephone/event" : "");
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
- }
- else if (item->flags & STAT_FLAG_WRONG_TIMESTAMP)
- {
- sharkd_json_value_string("s", "Incorrect timestamp");
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
- }
- else if ((item->flags & STAT_FLAG_PT_CHANGE)
- && !(item->flags & STAT_FLAG_FIRST)
- && !(item->flags & STAT_FLAG_PT_CN)
- && (item->flags & STAT_FLAG_FOLLOW_PT_CN)
- && !(item->flags & STAT_FLAG_MARKER))
- {
- sharkd_json_value_string("s", "Marker missing?");
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
- }
- else if (item->flags & STAT_FLAG_PT_T_EVENT)
- {
- sharkd_json_value_stringf("s", "PT=%u telephone/event", item->pt);
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_PT_EVENT);
- }
- else if (item->flags & STAT_FLAG_MARKER)
- {
- sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
- }
-
- if (item->marker)
- sharkd_json_value_anyf("mark", "1");
-
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
-
- json_dumper_end_object(&dumper);
+ const int RTP_TYPE_CN = 1;
+ const int RTP_TYPE_ERROR = 2;
+ const int RTP_TYPE_WARN = 3;
+ const int RTP_TYPE_PT_EVENT = 4;
+
+ const struct sharkd_analyse_rtp *rtp_req = (struct sharkd_analyse_rtp *) tapdata;
+ const tap_rtp_stat_t *statinfo = &rtp_req->statinfo;
+
+ GSList *l;
+
+ json_dumper_begin_object(&dumper);
+
+ sharkd_json_value_string("tap", rtp_req->tap_name);
+ sharkd_json_value_string("type", "rtp-analyse");
+ sharkd_json_value_anyf("ssrc", "%u", rtp_req->id.ssrc);
+
+ sharkd_json_value_anyf("max_delta", "%f", statinfo->max_delta);
+ sharkd_json_value_anyf("max_delta_nr", "%u", statinfo->max_nr);
+ sharkd_json_value_anyf("max_jitter", "%f", statinfo->max_jitter);
+ sharkd_json_value_anyf("mean_jitter", "%f", statinfo->mean_jitter);
+ sharkd_json_value_anyf("max_skew", "%f", statinfo->max_skew);
+ sharkd_json_value_anyf("total_nr", "%u", statinfo->total_nr);
+ sharkd_json_value_anyf("seq_err", "%u", statinfo->sequence);
+ sharkd_json_value_anyf("duration", "%f", statinfo->time - statinfo->start_time);
+
+ sharkd_json_array_open("items");
+ for (l = rtp_req->packets; l; l = l->next)
+ {
+ struct sharkd_analyse_rtp_items *item = (struct sharkd_analyse_rtp_items *) l->data;
+
+ json_dumper_begin_object(&dumper);
+
+ sharkd_json_value_anyf("f", "%u", item->frame_num);
+ sharkd_json_value_anyf("o", "%.9f", item->arrive_offset);
+ sharkd_json_value_anyf("sn", "%u", item->sequence_num);
+ sharkd_json_value_anyf("d", "%.2f", item->delta);
+ sharkd_json_value_anyf("j", "%.2f", item->jitter);
+ sharkd_json_value_anyf("sk", "%.2f", item->skew);
+ sharkd_json_value_anyf("bw", "%.2f", item->bandwidth);
+
+ if (item->pt == PT_CN)
+ {
+ sharkd_json_value_string("s", "Comfort noise (PT=13, RFC 3389)");
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_CN);
+ }
+ else if (item->pt == PT_CN_OLD)
+ {
+ sharkd_json_value_string("s", "Comfort noise (PT=19, reserved)");
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_CN);
+ }
+ else if (item->flags & STAT_FLAG_WRONG_SEQ)
+ {
+ sharkd_json_value_string("s", "Wrong sequence number");
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_ERROR);
+ }
+ else if (item->flags & STAT_FLAG_DUP_PKT)
+ {
+ sharkd_json_value_string("s", "Suspected duplicate (MAC address) only delta time calculated");
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
+ }
+ else if (item->flags & STAT_FLAG_REG_PT_CHANGE)
+ {
+ sharkd_json_value_stringf("s", "Payload changed to PT=%u%s",
+ item->pt,
+ (item->flags & STAT_FLAG_PT_T_EVENT) ? " telephone/event" : "");
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
+ }
+ else if (item->flags & STAT_FLAG_WRONG_TIMESTAMP)
+ {
+ sharkd_json_value_string("s", "Incorrect timestamp");
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
+ }
+ else if ((item->flags & STAT_FLAG_PT_CHANGE)
+ && !(item->flags & STAT_FLAG_FIRST)
+ && !(item->flags & STAT_FLAG_PT_CN)
+ && (item->flags & STAT_FLAG_FOLLOW_PT_CN)
+ && !(item->flags & STAT_FLAG_MARKER))
+ {
+ sharkd_json_value_string("s", "Marker missing?");
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
+ }
+ else if (item->flags & STAT_FLAG_PT_T_EVENT)
+ {
+ sharkd_json_value_stringf("s", "PT=%u telephone/event", item->pt);
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_PT_EVENT);
+ }
+ else if (item->flags & STAT_FLAG_MARKER)
+ {
+ sharkd_json_value_anyf("t", "%d", RTP_TYPE_WARN);
+ }
+
+ if (item->marker)
+ sharkd_json_value_anyf("mark", "1");
+
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
+
+ json_dumper_end_object(&dumper);
}
/**
@@ -2137,150 +2137,150 @@ sharkd_session_process_tap_rtp_analyse_cb(void *tapdata)
static void
sharkd_session_process_tap_conv_cb(void *arg)
{
- conv_hash_t *hash = (conv_hash_t *) arg;
- const struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;
- const char *proto;
- int proto_with_port;
- guint i;
-
- int with_geoip = 0;
-
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("tap", iu->type);
-
- if (!strncmp(iu->type, "conv:", 5))
- {
- sharkd_json_value_string("type", "conv");
- sharkd_json_array_open("convs");
- proto = iu->type + 5;
- }
- else if (!strncmp(iu->type, "endpt:", 6))
- {
- sharkd_json_value_string("type", "host");
- sharkd_json_array_open("hosts");
- proto = iu->type + 6;
- }
- else
- {
- sharkd_json_value_string("type", "err");
- proto = "";
- }
-
- proto_with_port = (!strcmp(proto, "TCP") || !strcmp(proto, "UDP") || !strcmp(proto, "SCTP"));
-
- if (iu->hash.conv_array != NULL && !strncmp(iu->type, "conv:", 5))
- {
- for (i = 0; i < iu->hash.conv_array->len; i++)
- {
- conv_item_t *iui = &g_array_index(iu->hash.conv_array, conv_item_t, i);
- char *src_addr, *dst_addr;
- char *src_port, *dst_port;
- char *filter_str;
-
- json_dumper_begin_object(&dumper);
-
- sharkd_json_value_string("saddr", (src_addr = get_conversation_address(NULL, &iui->src_address, iu->resolve_name)));
- sharkd_json_value_string("daddr", (dst_addr = get_conversation_address(NULL, &iui->dst_address, iu->resolve_name)));
-
- if (proto_with_port)
- {
- sharkd_json_value_string("sport", (src_port = get_conversation_port(NULL, iui->src_port, iui->etype, iu->resolve_port)));
- sharkd_json_value_string("dport", (dst_port = get_conversation_port(NULL, iui->dst_port, iui->etype, iu->resolve_port)));
-
- wmem_free(NULL, src_port);
- wmem_free(NULL, dst_port);
- }
-
- sharkd_json_value_anyf("rxf", "%" PRIu64, iui->rx_frames);
- sharkd_json_value_anyf("rxb", "%" PRIu64, iui->rx_bytes);
-
- sharkd_json_value_anyf("txf", "%" PRIu64, iui->tx_frames);
- sharkd_json_value_anyf("txb", "%" PRIu64, iui->tx_bytes);
-
- sharkd_json_value_anyf("start", "%.9f", nstime_to_sec(&iui->start_time));
- sharkd_json_value_anyf("stop", "%.9f", nstime_to_sec(&iui->stop_time));
-
- filter_str = get_conversation_filter(iui, CONV_DIR_A_TO_FROM_B);
- if (filter_str)
- {
- sharkd_json_value_string("filter", filter_str);
- g_free(filter_str);
- }
-
- wmem_free(NULL, src_addr);
- wmem_free(NULL, dst_addr);
-
- if (sharkd_session_geoip_addr(&(iui->src_address), "1"))
- with_geoip = 1;
- if (sharkd_session_geoip_addr(&(iui->dst_address), "2"))
- with_geoip = 1;
-
- json_dumper_end_object(&dumper);
- }
- }
- else if (iu->hash.conv_array != NULL && !strncmp(iu->type, "endpt:", 6))
- {
- for (i = 0; i < iu->hash.conv_array->len; i++)
- {
- hostlist_talker_t *host = &g_array_index(iu->hash.conv_array, hostlist_talker_t, i);
- char *host_str, *port_str;
- char *filter_str;
-
- json_dumper_begin_object(&dumper);
-
- sharkd_json_value_string("host", (host_str = get_conversation_address(NULL, &host->myaddress, iu->resolve_name)));
-
- if (proto_with_port)
- {
- sharkd_json_value_string("port", (port_str = get_conversation_port(NULL, host->port, host->etype, iu->resolve_port)));
-
- wmem_free(NULL, port_str);
- }
-
- sharkd_json_value_anyf("rxf", "%" PRIu64, host->rx_frames);
- sharkd_json_value_anyf("rxb", "%" PRIu64, host->rx_bytes);
-
- sharkd_json_value_anyf("txf", "%" PRIu64, host->tx_frames);
- sharkd_json_value_anyf("txb", "%" PRIu64, host->tx_bytes);
-
- filter_str = get_hostlist_filter(host);
- if (filter_str)
- {
- sharkd_json_value_string("filter", filter_str);
- g_free(filter_str);
- }
-
- wmem_free(NULL, host_str);
-
- if (sharkd_session_geoip_addr(&(host->myaddress), ""))
- with_geoip = 1;
- json_dumper_end_object(&dumper);
- }
- }
- sharkd_json_array_close();
-
- sharkd_json_value_string("proto", proto);
- sharkd_json_value_anyf("geoip", with_geoip ? "true" : "false");
-
- json_dumper_end_object(&dumper);
+ conv_hash_t *hash = (conv_hash_t *) arg;
+ const struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;
+ const char *proto;
+ int proto_with_port;
+ guint i;
+
+ int with_geoip = 0;
+
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("tap", iu->type);
+
+ if (!strncmp(iu->type, "conv:", 5))
+ {
+ sharkd_json_value_string("type", "conv");
+ sharkd_json_array_open("convs");
+ proto = iu->type + 5;
+ }
+ else if (!strncmp(iu->type, "endpt:", 6))
+ {
+ sharkd_json_value_string("type", "host");
+ sharkd_json_array_open("hosts");
+ proto = iu->type + 6;
+ }
+ else
+ {
+ sharkd_json_value_string("type", "err");
+ proto = "";
+ }
+
+ proto_with_port = (!strcmp(proto, "TCP") || !strcmp(proto, "UDP") || !strcmp(proto, "SCTP"));
+
+ if (iu->hash.conv_array != NULL && !strncmp(iu->type, "conv:", 5))
+ {
+ for (i = 0; i < iu->hash.conv_array->len; i++)
+ {
+ conv_item_t *iui = &g_array_index(iu->hash.conv_array, conv_item_t, i);
+ char *src_addr, *dst_addr;
+ char *src_port, *dst_port;
+ char *filter_str;
+
+ json_dumper_begin_object(&dumper);
+
+ sharkd_json_value_string("saddr", (src_addr = get_conversation_address(NULL, &iui->src_address, iu->resolve_name)));
+ sharkd_json_value_string("daddr", (dst_addr = get_conversation_address(NULL, &iui->dst_address, iu->resolve_name)));
+
+ if (proto_with_port)
+ {
+ sharkd_json_value_string("sport", (src_port = get_conversation_port(NULL, iui->src_port, iui->etype, iu->resolve_port)));
+ sharkd_json_value_string("dport", (dst_port = get_conversation_port(NULL, iui->dst_port, iui->etype, iu->resolve_port)));
+
+ wmem_free(NULL, src_port);
+ wmem_free(NULL, dst_port);
+ }
+
+ sharkd_json_value_anyf("rxf", "%" PRIu64, iui->rx_frames);
+ sharkd_json_value_anyf("rxb", "%" PRIu64, iui->rx_bytes);
+
+ sharkd_json_value_anyf("txf", "%" PRIu64, iui->tx_frames);
+ sharkd_json_value_anyf("txb", "%" PRIu64, iui->tx_bytes);
+
+ sharkd_json_value_anyf("start", "%.9f", nstime_to_sec(&iui->start_time));
+ sharkd_json_value_anyf("stop", "%.9f", nstime_to_sec(&iui->stop_time));
+
+ filter_str = get_conversation_filter(iui, CONV_DIR_A_TO_FROM_B);
+ if (filter_str)
+ {
+ sharkd_json_value_string("filter", filter_str);
+ g_free(filter_str);
+ }
+
+ wmem_free(NULL, src_addr);
+ wmem_free(NULL, dst_addr);
+
+ if (sharkd_session_geoip_addr(&(iui->src_address), "1"))
+ with_geoip = 1;
+ if (sharkd_session_geoip_addr(&(iui->dst_address), "2"))
+ with_geoip = 1;
+
+ json_dumper_end_object(&dumper);
+ }
+ }
+ else if (iu->hash.conv_array != NULL && !strncmp(iu->type, "endpt:", 6))
+ {
+ for (i = 0; i < iu->hash.conv_array->len; i++)
+ {
+ hostlist_talker_t *host = &g_array_index(iu->hash.conv_array, hostlist_talker_t, i);
+ char *host_str, *port_str;
+ char *filter_str;
+
+ json_dumper_begin_object(&dumper);
+
+ sharkd_json_value_string("host", (host_str = get_conversation_address(NULL, &host->myaddress, iu->resolve_name)));
+
+ if (proto_with_port)
+ {
+ sharkd_json_value_string("port", (port_str = get_conversation_port(NULL, host->port, host->etype, iu->resolve_port)));
+
+ wmem_free(NULL, port_str);
+ }
+
+ sharkd_json_value_anyf("rxf", "%" PRIu64, host->rx_frames);
+ sharkd_json_value_anyf("rxb", "%" PRIu64, host->rx_bytes);
+
+ sharkd_json_value_anyf("txf", "%" PRIu64, host->tx_frames);
+ sharkd_json_value_anyf("txb", "%" PRIu64, host->tx_bytes);
+
+ filter_str = get_hostlist_filter(host);
+ if (filter_str)
+ {
+ sharkd_json_value_string("filter", filter_str);
+ g_free(filter_str);
+ }
+
+ wmem_free(NULL, host_str);
+
+ if (sharkd_session_geoip_addr(&(host->myaddress), ""))
+ with_geoip = 1;
+ json_dumper_end_object(&dumper);
+ }
+ }
+ sharkd_json_array_close();
+
+ sharkd_json_value_string("proto", proto);
+ sharkd_json_value_anyf("geoip", with_geoip ? "true" : "false");
+
+ json_dumper_end_object(&dumper);
}
static void
sharkd_session_free_tap_conv_cb(void *arg)
{
- conv_hash_t *hash = (conv_hash_t *) arg;
- struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;
-
- if (!strncmp(iu->type, "conv:", 5))
- {
- reset_conversation_table_data(hash);
- }
- else if (!strncmp(iu->type, "endpt:", 6))
- {
- reset_hostlist_table_data(hash);
- }
-
- g_free(iu);
+ conv_hash_t *hash = (conv_hash_t *) arg;
+ struct sharkd_conv_tap_data *iu = (struct sharkd_conv_tap_data *) hash->user_data;
+
+ if (!strncmp(iu->type, "conv:", 5))
+ {
+ reset_conversation_table_data(hash);
+ }
+ else if (!strncmp(iu->type, "endpt:", 6))
+ {
+ reset_hostlist_table_data(hash);
+ }
+
+ g_free(iu);
}
/**
@@ -2299,91 +2299,91 @@ sharkd_session_free_tap_conv_cb(void *arg)
static void
sharkd_session_process_tap_nstat_cb(void *arg)
{
- stat_data_t *stat_data = (stat_data_t *) arg;
- guint i, j, k;
-
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("tap", "nstat:%s", stat_data->stat_tap_data->cli_string);
- sharkd_json_value_string("type", "nstat");
-
- sharkd_json_array_open("fields");
- for (i = 0; i < stat_data->stat_tap_data->nfields; i++)
- {
- stat_tap_table_item *field = &(stat_data->stat_tap_data->fields[i]);
-
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("c", field->column_name);
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
-
- sharkd_json_array_open("tables");
- for (i = 0; i < stat_data->stat_tap_data->tables->len; i++)
- {
- stat_tap_table *table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table *, i);
-
- json_dumper_begin_object(&dumper);
-
- sharkd_json_value_string("t", table->title);
-
- sharkd_json_array_open("i");
- for (j = 0; j < table->num_elements; j++)
- {
- stat_tap_table_item_type *field_data;
-
- field_data = stat_tap_get_field_data(table, j, 0);
- if (field_data == NULL || field_data->type == TABLE_ITEM_NONE) /* Nothing for us here */
- continue;
-
- sharkd_json_array_open(NULL);
- for (k = 0; k < table->num_fields; k++)
- {
- field_data = stat_tap_get_field_data(table, j, k);
-
- switch (field_data->type)
- {
- case TABLE_ITEM_UINT:
- sharkd_json_value_anyf(NULL, "%u", field_data->value.uint_value);
- break;
-
- case TABLE_ITEM_INT:
- sharkd_json_value_anyf(NULL, "%d", field_data->value.int_value);
- break;
-
- case TABLE_ITEM_STRING:
- sharkd_json_value_string(NULL, field_data->value.string_value);
- break;
-
- case TABLE_ITEM_FLOAT:
- sharkd_json_value_anyf(NULL, "%f", field_data->value.float_value);
- break;
-
- case TABLE_ITEM_ENUM:
- sharkd_json_value_anyf(NULL, "%d", field_data->value.enum_value);
- break;
-
- case TABLE_ITEM_NONE:
- sharkd_json_value_anyf(NULL, "null");
- break;
- }
- }
-
- sharkd_json_array_close();
- }
- sharkd_json_array_close();
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
-
- json_dumper_end_object(&dumper);
+ stat_data_t *stat_data = (stat_data_t *) arg;
+ guint i, j, k;
+
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("tap", "nstat:%s", stat_data->stat_tap_data->cli_string);
+ sharkd_json_value_string("type", "nstat");
+
+ sharkd_json_array_open("fields");
+ for (i = 0; i < stat_data->stat_tap_data->nfields; i++)
+ {
+ stat_tap_table_item *field = &(stat_data->stat_tap_data->fields[i]);
+
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("c", field->column_name);
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
+
+ sharkd_json_array_open("tables");
+ for (i = 0; i < stat_data->stat_tap_data->tables->len; i++)
+ {
+ stat_tap_table *table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table *, i);
+
+ json_dumper_begin_object(&dumper);
+
+ sharkd_json_value_string("t", table->title);
+
+ sharkd_json_array_open("i");
+ for (j = 0; j < table->num_elements; j++)
+ {
+ stat_tap_table_item_type *field_data;
+
+ field_data = stat_tap_get_field_data(table, j, 0);
+ if (field_data == NULL || field_data->type == TABLE_ITEM_NONE) /* Nothing for us here */
+ continue;
+
+ sharkd_json_array_open(NULL);
+ for (k = 0; k < table->num_fields; k++)
+ {
+ field_data = stat_tap_get_field_data(table, j, k);
+
+ switch (field_data->type)
+ {
+ case TABLE_ITEM_UINT:
+ sharkd_json_value_anyf(NULL, "%u", field_data->value.uint_value);
+ break;
+
+ case TABLE_ITEM_INT:
+ sharkd_json_value_anyf(NULL, "%d", field_data->value.int_value);
+ break;
+
+ case TABLE_ITEM_STRING:
+ sharkd_json_value_string(NULL, field_data->value.string_value);
+ break;
+
+ case TABLE_ITEM_FLOAT:
+ sharkd_json_value_anyf(NULL, "%f", field_data->value.float_value);
+ break;
+
+ case TABLE_ITEM_ENUM:
+ sharkd_json_value_anyf(NULL, "%d", field_data->value.enum_value);
+ break;
+
+ case TABLE_ITEM_NONE:
+ sharkd_json_value_anyf(NULL, "null");
+ break;
+ }
+ }
+
+ sharkd_json_array_close();
+ }
+ sharkd_json_array_close();
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
+
+ json_dumper_end_object(&dumper);
}
static void
sharkd_session_free_tap_nstat_cb(void *arg)
{
- stat_data_t *stat_data = (stat_data_t *) arg;
+ stat_data_t *stat_data = (stat_data_t *) arg;
- free_stat_tables(stat_data->stat_tap_data);
+ free_stat_tables(stat_data->stat_tap_data);
}
/**
@@ -2412,86 +2412,86 @@ sharkd_session_free_tap_nstat_cb(void *arg)
static void
sharkd_session_process_tap_rtd_cb(void *arg)
{
- rtd_data_t *rtd_data = (rtd_data_t *) arg;
- register_rtd_t *rtd = (register_rtd_t *) rtd_data->user_data;
-
- guint i, j;
-
- const char *filter = proto_get_protocol_filter_name(get_rtd_proto_id(rtd));
-
- /* XXX, some dissectors are having single table and multiple timestats (mgcp, megaco),
- * some multiple table and single timestat (radius, h225)
- * and it seems that value_string is used one for timestamp-ID, other one for table-ID
- * I wonder how it will gonna work with multiple timestats and multiple tables...
- * (for usage grep for: register_rtd_table)
- */
- const value_string *vs = get_rtd_value_string(rtd);
-
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("tap", "rtd:%s", filter);
- sharkd_json_value_string("type", "rtd");
-
- if (rtd_data->stat_table.num_rtds == 1)
- {
- const rtd_timestat *ms = &rtd_data->stat_table.time_stats[0];
-
- sharkd_json_value_anyf("open_req", "%u", ms->open_req_num);
- sharkd_json_value_anyf("disc_rsp", "%u", ms->disc_rsp_num);
- sharkd_json_value_anyf("req_dup", "%u", ms->req_dup_num);
- sharkd_json_value_anyf("rsp_dup", "%u", ms->rsp_dup_num);
- }
-
- sharkd_json_array_open("stats");
- for (i = 0; i < rtd_data->stat_table.num_rtds; i++)
- {
- const rtd_timestat *ms = &rtd_data->stat_table.time_stats[i];
-
- for (j = 0; j < ms->num_timestat; j++)
- {
- const char *type_str;
-
- if (ms->rtd[j].num == 0)
- continue;
-
- json_dumper_begin_object(&dumper);
-
- if (rtd_data->stat_table.num_rtds == 1)
- type_str = val_to_str_const(j, vs, "Other"); /* 1 table - description per row */
- else
- type_str = val_to_str_const(i, vs, "Other"); /* multiple table - description per table */
- sharkd_json_value_string("type", type_str);
-
- sharkd_json_value_anyf("num", "%u", ms->rtd[j].num);
- sharkd_json_value_anyf("min", "%.9f", nstime_to_sec(&(ms->rtd[j].min)));
- sharkd_json_value_anyf("max", "%.9f", nstime_to_sec(&(ms->rtd[j].max)));
- sharkd_json_value_anyf("tot", "%.9f", nstime_to_sec(&(ms->rtd[j].tot)));
- sharkd_json_value_anyf("min_frame", "%u", ms->rtd[j].min_num);
- sharkd_json_value_anyf("max_frame", "%u", ms->rtd[j].max_num);
-
- if (rtd_data->stat_table.num_rtds != 1)
- {
- /* like in tshark, display it on every row */
- sharkd_json_value_anyf("open_req", "%u", ms->open_req_num);
- sharkd_json_value_anyf("disc_rsp", "%u", ms->disc_rsp_num);
- sharkd_json_value_anyf("req_dup", "%u", ms->req_dup_num);
- sharkd_json_value_anyf("rsp_dup", "%u", ms->rsp_dup_num);
- }
-
- json_dumper_end_object(&dumper);
- }
- }
- sharkd_json_array_close();
-
- json_dumper_end_object(&dumper);
+ rtd_data_t *rtd_data = (rtd_data_t *) arg;
+ register_rtd_t *rtd = (register_rtd_t *) rtd_data->user_data;
+
+ guint i, j;
+
+ const char *filter = proto_get_protocol_filter_name(get_rtd_proto_id(rtd));
+
+ /* XXX, some dissectors are having single table and multiple timestats (mgcp, megaco),
+ * some multiple table and single timestat (radius, h225)
+ * and it seems that value_string is used one for timestamp-ID, other one for table-ID
+ * I wonder how it will gonna work with multiple timestats and multiple tables...
+ * (for usage grep for: register_rtd_table)
+ */
+ const value_string *vs = get_rtd_value_string(rtd);
+
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("tap", "rtd:%s", filter);
+ sharkd_json_value_string("type", "rtd");
+
+ if (rtd_data->stat_table.num_rtds == 1)
+ {
+ const rtd_timestat *ms = &rtd_data->stat_table.time_stats[0];
+
+ sharkd_json_value_anyf("open_req", "%u", ms->open_req_num);
+ sharkd_json_value_anyf("disc_rsp", "%u", ms->disc_rsp_num);
+ sharkd_json_value_anyf("req_dup", "%u", ms->req_dup_num);
+ sharkd_json_value_anyf("rsp_dup", "%u", ms->rsp_dup_num);
+ }
+
+ sharkd_json_array_open("stats");
+ for (i = 0; i < rtd_data->stat_table.num_rtds; i++)
+ {
+ const rtd_timestat *ms = &rtd_data->stat_table.time_stats[i];
+
+ for (j = 0; j < ms->num_timestat; j++)
+ {
+ const char *type_str;
+
+ if (ms->rtd[j].num == 0)
+ continue;
+
+ json_dumper_begin_object(&dumper);
+
+ if (rtd_data->stat_table.num_rtds == 1)
+ type_str = val_to_str_const(j, vs, "Other"); /* 1 table - description per row */
+ else
+ type_str = val_to_str_const(i, vs, "Other"); /* multiple table - description per table */
+ sharkd_json_value_string("type", type_str);
+
+ sharkd_json_value_anyf("num", "%u", ms->rtd[j].num);
+ sharkd_json_value_anyf("min", "%.9f", nstime_to_sec(&(ms->rtd[j].min)));
+ sharkd_json_value_anyf("max", "%.9f", nstime_to_sec(&(ms->rtd[j].max)));
+ sharkd_json_value_anyf("tot", "%.9f", nstime_to_sec(&(ms->rtd[j].tot)));
+ sharkd_json_value_anyf("min_frame", "%u", ms->rtd[j].min_num);
+ sharkd_json_value_anyf("max_frame", "%u", ms->rtd[j].max_num);
+
+ if (rtd_data->stat_table.num_rtds != 1)
+ {
+ /* like in tshark, display it on every row */
+ sharkd_json_value_anyf("open_req", "%u", ms->open_req_num);
+ sharkd_json_value_anyf("disc_rsp", "%u", ms->disc_rsp_num);
+ sharkd_json_value_anyf("req_dup", "%u", ms->req_dup_num);
+ sharkd_json_value_anyf("rsp_dup", "%u", ms->rsp_dup_num);
+ }
+
+ json_dumper_end_object(&dumper);
+ }
+ }
+ sharkd_json_array_close();
+
+ json_dumper_end_object(&dumper);
}
static void
sharkd_session_free_tap_rtd_cb(void *arg)
{
- rtd_data_t *rtd_data = (rtd_data_t *) arg;
+ rtd_data_t *rtd_data = (rtd_data_t *) arg;
- free_rtd_table(&rtd_data->stat_table);
- g_free(rtd_data);
+ free_rtd_table(&rtd_data->stat_table);
+ g_free(rtd_data);
}
/**
@@ -2516,91 +2516,91 @@ sharkd_session_free_tap_rtd_cb(void *arg)
static void
sharkd_session_process_tap_srt_cb(void *arg)
{
- srt_data_t *srt_data = (srt_data_t *) arg;
- register_srt_t *srt = (register_srt_t *) srt_data->user_data;
+ srt_data_t *srt_data = (srt_data_t *) arg;
+ register_srt_t *srt = (register_srt_t *) srt_data->user_data;
- const char *filter = proto_get_protocol_filter_name(get_srt_proto_id(srt));
+ const char *filter = proto_get_protocol_filter_name(get_srt_proto_id(srt));
- guint i;
+ guint i;
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("tap", "srt:%s", filter);
- sharkd_json_value_string("type", "srt");
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("tap", "srt:%s", filter);
+ sharkd_json_value_string("type", "srt");
- sharkd_json_array_open("tables");
- for (i = 0; i < srt_data->srt_array->len; i++)
- {
- /* SRT table */
- srt_stat_table *rst = g_array_index(srt_data->srt_array, srt_stat_table *, i);
+ sharkd_json_array_open("tables");
+ for (i = 0; i < srt_data->srt_array->len; i++)
+ {
+ /* SRT table */
+ srt_stat_table *rst = g_array_index(srt_data->srt_array, srt_stat_table *, i);
- int j;
+ int j;
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- if (rst->name)
- sharkd_json_value_string("n", rst->name);
- else if (rst->short_name)
- sharkd_json_value_string("n", rst->short_name);
- else
- sharkd_json_value_stringf("n", "table%u", i);
+ if (rst->name)
+ sharkd_json_value_string("n", rst->name);
+ else if (rst->short_name)
+ sharkd_json_value_string("n", rst->short_name);
+ else
+ sharkd_json_value_stringf("n", "table%u", i);
- if (rst->filter_string)
- sharkd_json_value_string("f", rst->filter_string);
+ if (rst->filter_string)
+ sharkd_json_value_string("f", rst->filter_string);
- if (rst->proc_column_name)
- sharkd_json_value_string("c", rst->proc_column_name);
+ if (rst->proc_column_name)
+ sharkd_json_value_string("c", rst->proc_column_name);
- sharkd_json_array_open("r");
- for (j = 0; j < rst->num_procs; j++)
- {
- /* SRT row */
- srt_procedure_t *proc = &rst->procedures[j];
+ sharkd_json_array_open("r");
+ for (j = 0; j < rst->num_procs; j++)
+ {
+ /* SRT row */
+ srt_procedure_t *proc = &rst->procedures[j];
- if (proc->stats.num == 0)
- continue;
+ if (proc->stats.num == 0)
+ continue;
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- sharkd_json_value_string("n", proc->procedure);
+ sharkd_json_value_string("n", proc->procedure);
- if (rst->filter_string)
- sharkd_json_value_anyf("idx", "%d", proc->proc_index);
+ if (rst->filter_string)
+ sharkd_json_value_anyf("idx", "%d", proc->proc_index);
- sharkd_json_value_anyf("num", "%u", proc->stats.num);
+ sharkd_json_value_anyf("num", "%u", proc->stats.num);
- sharkd_json_value_anyf("min", "%.9f", nstime_to_sec(&proc->stats.min));
- sharkd_json_value_anyf("max", "%.9f", nstime_to_sec(&proc->stats.max));
- sharkd_json_value_anyf("tot", "%.9f", nstime_to_sec(&proc->stats.tot));
+ sharkd_json_value_anyf("min", "%.9f", nstime_to_sec(&proc->stats.min));
+ sharkd_json_value_anyf("max", "%.9f", nstime_to_sec(&proc->stats.max));
+ sharkd_json_value_anyf("tot", "%.9f", nstime_to_sec(&proc->stats.tot));
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
}
static void
sharkd_session_free_tap_srt_cb(void *arg)
{
- srt_data_t *srt_data = (srt_data_t *) arg;
- register_srt_t *srt = (register_srt_t *) srt_data->user_data;
+ srt_data_t *srt_data = (srt_data_t *) arg;
+ register_srt_t *srt = (register_srt_t *) srt_data->user_data;
- free_srt_table(srt, srt_data->srt_array);
- g_array_free(srt_data->srt_array, TRUE);
- g_free(srt_data);
+ free_srt_table(srt, srt_data->srt_array);
+ g_array_free(srt_data->srt_array, TRUE);
+ g_free(srt_data);
}
struct sharkd_export_object_list
{
- struct sharkd_export_object_list *next;
+ struct sharkd_export_object_list *next;
- char *type;
- const char *proto;
- GSList *entries;
+ char *type;
+ const char *proto;
+ GSList *entries;
};
static struct sharkd_export_object_list *sharkd_eo_list;
@@ -2622,62 +2622,62 @@ static struct sharkd_export_object_list *sharkd_eo_list;
static void
sharkd_session_process_tap_eo_cb(void *tapdata)
{
- export_object_list_t *tap_object = (export_object_list_t *) tapdata;
- struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) tap_object->gui_data;
- GSList *slist;
- int i = 0;
+ export_object_list_t *tap_object = (export_object_list_t *) tapdata;
+ struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) tap_object->gui_data;
+ GSList *slist;
+ int i = 0;
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("tap", object_list->type);
- sharkd_json_value_string("type", "eo");
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("tap", object_list->type);
+ sharkd_json_value_string("type", "eo");
- sharkd_json_value_string("proto", object_list->proto);
+ sharkd_json_value_string("proto", object_list->proto);
- sharkd_json_array_open("objects");
- for (slist = object_list->entries; slist; slist = slist->next)
- {
- const export_object_entry_t *eo_entry = (export_object_entry_t *) slist->data;
+ sharkd_json_array_open("objects");
+ for (slist = object_list->entries; slist; slist = slist->next)
+ {
+ const export_object_entry_t *eo_entry = (export_object_entry_t *) slist->data;
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- sharkd_json_value_anyf("pkt", "%u", eo_entry->pkt_num);
+ sharkd_json_value_anyf("pkt", "%u", eo_entry->pkt_num);
- if (eo_entry->hostname)
- sharkd_json_value_string("hostname", eo_entry->hostname);
+ if (eo_entry->hostname)
+ sharkd_json_value_string("hostname", eo_entry->hostname);
- if (eo_entry->content_type)
- sharkd_json_value_string("type", eo_entry->content_type);
+ if (eo_entry->content_type)
+ sharkd_json_value_string("type", eo_entry->content_type);
- if (eo_entry->filename)
- sharkd_json_value_string("filename", eo_entry->filename);
+ if (eo_entry->filename)
+ sharkd_json_value_string("filename", eo_entry->filename);
- sharkd_json_value_stringf("_download", "%s_%d", object_list->type, i);
+ sharkd_json_value_stringf("_download", "%s_%d", object_list->type, i);
- sharkd_json_value_anyf("len", "%zu", eo_entry->payload_len);
+ sharkd_json_value_anyf("len", "%zu", eo_entry->payload_len);
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
- i++;
- }
- sharkd_json_array_close();
+ i++;
+ }
+ sharkd_json_array_close();
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
}
static void
sharkd_eo_object_list_add_entry(void *gui_data, export_object_entry_t *entry)
{
- struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;
+ struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;
- object_list->entries = g_slist_append(object_list->entries, entry);
+ object_list->entries = g_slist_append(object_list->entries, entry);
}
static export_object_entry_t *
sharkd_eo_object_list_get_entry(void *gui_data, int row)
{
- struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;
+ struct sharkd_export_object_list *object_list = (struct sharkd_export_object_list *) gui_data;
- return (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);
+ return (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);
}
/**
@@ -2705,53 +2705,53 @@ sharkd_eo_object_list_get_entry(void *gui_data, int row)
static void
sharkd_session_process_tap_rtp_cb(void *arg)
{
- rtpstream_tapinfo_t *rtp_tapinfo = (rtpstream_tapinfo_t *) arg;
+ rtpstream_tapinfo_t *rtp_tapinfo = (rtpstream_tapinfo_t *) arg;
- GList *listx;
+ GList *listx;
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("tap", "rtp-streams");
- sharkd_json_value_string("type", "rtp-streams");
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("tap", "rtp-streams");
+ sharkd_json_value_string("type", "rtp-streams");
- sharkd_json_array_open("streams");
- for (listx = g_list_first(rtp_tapinfo->strinfo_list); listx; listx = listx->next)
- {
- rtpstream_info_t *streaminfo = (rtpstream_info_t *) listx->data;
- rtpstream_info_calc_t calc;
+ sharkd_json_array_open("streams");
+ for (listx = g_list_first(rtp_tapinfo->strinfo_list); listx; listx = listx->next)
+ {
+ rtpstream_info_t *streaminfo = (rtpstream_info_t *) listx->data;
+ rtpstream_info_calc_t calc;
- rtpstream_info_calculate(streaminfo, &calc);
+ rtpstream_info_calculate(streaminfo, &calc);
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- sharkd_json_value_anyf("ssrc", "%u", calc.ssrc);
- sharkd_json_value_string("payload", calc.all_payload_type_names);
+ sharkd_json_value_anyf("ssrc", "%u", calc.ssrc);
+ sharkd_json_value_string("payload", calc.all_payload_type_names);
- sharkd_json_value_string("saddr", calc.src_addr_str);
- sharkd_json_value_anyf("sport", "%u", calc.src_port);
- sharkd_json_value_string("daddr", calc.dst_addr_str);
- sharkd_json_value_anyf("dport", "%u", calc.dst_port);
+ sharkd_json_value_string("saddr", calc.src_addr_str);
+ sharkd_json_value_anyf("sport", "%u", calc.src_port);
+ sharkd_json_value_string("daddr", calc.dst_addr_str);
+ sharkd_json_value_anyf("dport", "%u", calc.dst_port);
- sharkd_json_value_anyf("pkts", "%u", calc.packet_count);
+ sharkd_json_value_anyf("pkts", "%u", calc.packet_count);
- sharkd_json_value_anyf("max_delta", "%f",calc.max_delta);
- sharkd_json_value_anyf("max_jitter", "%f", calc.max_jitter);
- sharkd_json_value_anyf("mean_jitter", "%f", calc.mean_jitter);
+ sharkd_json_value_anyf("max_delta", "%f",calc.max_delta);
+ sharkd_json_value_anyf("max_jitter", "%f", calc.max_jitter);
+ sharkd_json_value_anyf("mean_jitter", "%f", calc.mean_jitter);
- sharkd_json_value_anyf("expectednr", "%u", calc.packet_expected);
- sharkd_json_value_anyf("totalnr", "%u", calc.total_nr);
+ sharkd_json_value_anyf("expectednr", "%u", calc.packet_expected);
+ sharkd_json_value_anyf("totalnr", "%u", calc.total_nr);
- sharkd_json_value_anyf("problem", calc.problem ? "true" : "false");
+ sharkd_json_value_anyf("problem", calc.problem ? "true" : "false");
- /* for filter */
- sharkd_json_value_anyf("ipver", "%d", (streaminfo->id.src_addr.type == AT_IPv6) ? 6 : 4);
+ /* for filter */
+ sharkd_json_value_anyf("ipver", "%d", (streaminfo->id.src_addr.type == AT_IPv6) ? 6 : 4);
- rtpstream_info_calc_free(&calc);
+ rtpstream_info_calc_free(&calc);
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
}
/**
@@ -2785,373 +2785,373 @@ sharkd_session_process_tap_rtp_cb(void *arg)
static void
sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count)
{
- void *taps_data[16];
- GFreeFunc taps_free[16];
- int taps_count = 0;
- int i;
-
- rtpstream_tapinfo_t rtp_tapinfo =
- { NULL, NULL, NULL, NULL, 0, NULL, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE, FALSE};
-
- for (i = 0; i < 16; i++)
- {
- char tapbuf[32];
- const char *tok_tap;
-
- void *tap_data = NULL;
- GFreeFunc tap_free = NULL;
- const char *tap_filter = "";
- GString *tap_error = NULL;
-
- snprintf(tapbuf, sizeof(tapbuf), "tap%d", i);
- tok_tap = json_find_attr(buf, tokens, count, tapbuf);
- if (!tok_tap)
- break;
-
- if (!strncmp(tok_tap, "stat:", 5))
- {
- stats_tree_cfg *cfg = stats_tree_get_cfg_by_abbr(tok_tap + 5);
- stats_tree *st;
-
- if (!cfg)
- {
- sharkd_json_error(
- rpcid, -11001, NULL,
- "sharkd_session_process_tap() stat %s not found", tok_tap + 5
- );
- return;
- }
-
- st = stats_tree_new(cfg, NULL, tap_filter);
-
- tap_error = register_tap_listener(st->cfg->tapname, st, st->filter, st->cfg->flags, stats_tree_reset, stats_tree_packet, sharkd_session_process_tap_stats_cb, NULL);
-
- if (!tap_error && cfg->init)
- cfg->init(st);
-
- tap_data = st;
- tap_free = sharkd_session_free_tap_stats_cb;
- }
- else if (!strcmp(tok_tap, "expert"))
- {
- struct sharkd_expert_tap *expert_tap;
-
- expert_tap = g_new0(struct sharkd_expert_tap, 1);
- expert_tap->text = g_string_chunk_new(100);
-
- tap_error = register_tap_listener("expert", expert_tap, NULL, 0, NULL, sharkd_session_packet_tap_expert_cb, sharkd_session_process_tap_expert_cb, NULL);
-
- tap_data = expert_tap;
- tap_free = sharkd_session_free_tap_expert_cb;
- }
- else if (!strncmp(tok_tap, "seqa:", 5))
- {
- seq_analysis_info_t *graph_analysis;
- register_analysis_t *analysis;
- const char *tap_name;
- tap_packet_cb tap_func;
- guint tap_flags;
-
- analysis = sequence_analysis_find_by_name(tok_tap + 5);
- if (!analysis)
- {
- sharkd_json_error(
- rpcid, -11002, NULL,
- "sharkd_session_process_tap() seq analysis %s not found", tok_tap + 5
- );
- return;
- }
-
- graph_analysis = sequence_analysis_info_new();
- graph_analysis->name = tok_tap + 5;
- /* TODO, make configurable */
- graph_analysis->any_addr = FALSE;
-
- tap_name = sequence_analysis_get_tap_listener_name(analysis);
- tap_flags = sequence_analysis_get_tap_flags(analysis);
- tap_func = sequence_analysis_get_packet_func(analysis);
-
- tap_error = register_tap_listener(tap_name, graph_analysis, NULL, tap_flags, NULL, tap_func, sharkd_session_process_tap_flow_cb, NULL);
-
- tap_data = graph_analysis;
- tap_free = sharkd_session_free_tap_flow_cb;
- }
- else if (!strncmp(tok_tap, "conv:", 5) || !strncmp(tok_tap, "endpt:", 6))
- {
- struct register_ct *ct = NULL;
- const char *ct_tapname;
- struct sharkd_conv_tap_data *ct_data;
- tap_packet_cb tap_func = NULL;
-
- if (!strncmp(tok_tap, "conv:", 5))
- {
- ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 5));
-
- if (!ct || !(tap_func = get_conversation_packet_func(ct)))
- {
- sharkd_json_error(
- rpcid, -11003, NULL,
- "sharkd_session_process_tap() conv %s not found", tok_tap + 5
- );
- return;
- }
- }
- else if (!strncmp(tok_tap, "endpt:", 6))
- {
- ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 6));
-
- if (!ct || !(tap_func = get_hostlist_packet_func(ct)))
- {
- sharkd_json_error(
- rpcid, -11004, NULL,
- "sharkd_session_process_tap() endpt %s not found", tok_tap + 6
- );
- return;
- }
- }
- else
- {
- sharkd_json_error(
- rpcid, -11005, NULL,
- "sharkd_session_process_tap() conv/endpt(?): %s not found", tok_tap
- );
- return;
- }
-
- ct_tapname = proto_get_protocol_filter_name(get_conversation_proto_id(ct));
-
- ct_data = g_new0(struct sharkd_conv_tap_data, 1);
- ct_data->type = tok_tap;
- ct_data->hash.user_data = ct_data;
-
- /* XXX: make configurable */
- ct_data->resolve_name = TRUE;
- ct_data->resolve_port = TRUE;
-
- tap_error = register_tap_listener(ct_tapname, &ct_data->hash, tap_filter, 0, NULL, tap_func, sharkd_session_process_tap_conv_cb, NULL);
-
- tap_data = &ct_data->hash;
- tap_free = sharkd_session_free_tap_conv_cb;
- }
- else if (!strncmp(tok_tap, "nstat:", 6))
- {
- stat_tap_table_ui *stat_tap = stat_tap_by_name(tok_tap + 6);
- stat_data_t *stat_data;
-
- if (!stat_tap)
- {
- sharkd_json_error(
- rpcid, -11006, NULL,
- "sharkd_session_process_tap() nstat=%s not found", tok_tap + 6
- );
- return;
- }
-
- stat_tap->stat_tap_init_cb(stat_tap);
-
- stat_data = g_new0(stat_data_t, 1);
- stat_data->stat_tap_data = stat_tap;
- stat_data->user_data = NULL;
-
- tap_error = register_tap_listener(stat_tap->tap_name, stat_data, tap_filter, 0, NULL, stat_tap->packet_func, sharkd_session_process_tap_nstat_cb, NULL);
-
- tap_data = stat_data;
- tap_free = sharkd_session_free_tap_nstat_cb;
- }
- else if (!strncmp(tok_tap, "rtd:", 4))
- {
- register_rtd_t *rtd = get_rtd_table_by_name(tok_tap + 4);
- rtd_data_t *rtd_data;
- char *err;
-
- if (!rtd)
- {
- sharkd_json_error(
- rpcid, -11007, NULL,
- "sharkd_session_process_tap() rtd=%s not found", tok_tap + 4
- );
- return;
- }
-
- rtd_table_get_filter(rtd, "", &tap_filter, &err);
- if (err != NULL)
- {
- sharkd_json_error(
- rpcid, -11008, NULL,
- "sharkd_session_process_tap() rtd=%s err=%s", tok_tap + 4, err
- );
- g_free(err);
- return;
- }
-
- rtd_data = g_new0(rtd_data_t, 1);
- rtd_data->user_data = rtd;
- rtd_table_dissector_init(rtd, &rtd_data->stat_table, NULL, NULL);
-
- tap_error = register_tap_listener(get_rtd_tap_listener_name(rtd), rtd_data, tap_filter, 0, NULL, get_rtd_packet_func(rtd), sharkd_session_process_tap_rtd_cb, NULL);
-
- tap_data = rtd_data;
- tap_free = sharkd_session_free_tap_rtd_cb;
- }
- else if (!strncmp(tok_tap, "srt:", 4))
- {
- register_srt_t *srt = get_srt_table_by_name(tok_tap + 4);
- srt_data_t *srt_data;
- char *err;
-
- if (!srt)
- {
- sharkd_json_error(
- rpcid, -11009, NULL,
- "sharkd_session_process_tap() srt=%s not found", tok_tap + 4
- );
- return;
- }
-
- srt_table_get_filter(srt, "", &tap_filter, &err);
- if (err != NULL)
- {
- sharkd_json_error(
- rpcid, -11010, NULL,
- "sharkd_session_process_tap() srt=%s err=%s", tok_tap + 4, err
- );
- g_free(err);
- return;
- }
-
- srt_data = g_new0(srt_data_t, 1);
- srt_data->srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table *));
- srt_data->user_data = srt;
- srt_table_dissector_init(srt, srt_data->srt_array);
-
- tap_error = register_tap_listener(get_srt_tap_listener_name(srt), srt_data, tap_filter, 0, NULL, get_srt_packet_func(srt), sharkd_session_process_tap_srt_cb, NULL);
-
- tap_data = srt_data;
- tap_free = sharkd_session_free_tap_srt_cb;
- }
- else if (!strncmp(tok_tap, "eo:", 3))
- {
- register_eo_t *eo = get_eo_by_name(tok_tap + 3);
- export_object_list_t *eo_object;
- struct sharkd_export_object_list *object_list;
-
- if (!eo)
- {
- sharkd_json_error(
- rpcid, -11011, NULL,
- "sharkd_session_process_tap() eo=%s not found", tok_tap + 3
- );
- return;
- }
-
- for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)
- {
- if (!strcmp(object_list->type, tok_tap))
- {
- g_slist_free_full(object_list->entries, (GDestroyNotify) eo_free_entry);
- object_list->entries = NULL;
- break;
- }
- }
-
- if (!object_list)
- {
- object_list = g_new(struct sharkd_export_object_list, 1);
- object_list->type = g_strdup(tok_tap);
- object_list->proto = proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo)));
- object_list->entries = NULL;
- object_list->next = sharkd_eo_list;
- sharkd_eo_list = object_list;
- }
-
- eo_object = g_new0(export_object_list_t, 1);
- eo_object->add_entry = sharkd_eo_object_list_add_entry;
- eo_object->get_entry = sharkd_eo_object_list_get_entry;
- eo_object->gui_data = (void *) object_list;
-
- tap_error = register_tap_listener(get_eo_tap_listener_name(eo), eo_object, NULL, 0, NULL, get_eo_packet_func(eo), sharkd_session_process_tap_eo_cb, NULL);
-
- tap_data = eo_object;
- tap_free = g_free; /* need to free only eo_object, object_list need to be kept for potential download */
- }
- else if (!strcmp(tok_tap, "rtp-streams"))
- {
- tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet_cb, sharkd_session_process_tap_rtp_cb, NULL);
-
- tap_data = &rtp_tapinfo;
- tap_free = rtpstream_reset_cb;
- }
- else if (!strncmp(tok_tap, "rtp-analyse:", 12))
- {
- struct sharkd_analyse_rtp *rtp_req;
-
- rtp_req = (struct sharkd_analyse_rtp *) g_malloc0(sizeof(*rtp_req));
- if (!sharkd_rtp_match_init(&rtp_req->id, tok_tap + 12))
- {
- rtpstream_id_free(&rtp_req->id);
- g_free(rtp_req);
- continue;
- }
-
- rtp_req->tap_name = tok_tap;
- rtp_req->statinfo.first_packet = TRUE;
- rtp_req->statinfo.reg_pt = PT_UNDEFINED;
-
- tap_error = register_tap_listener("rtp", rtp_req, tap_filter, 0, NULL, sharkd_session_packet_tap_rtp_analyse_cb, sharkd_session_process_tap_rtp_analyse_cb, NULL);
-
- tap_data = rtp_req;
- tap_free = sharkd_session_process_tap_rtp_free_cb;
- }
- else
- {
- sharkd_json_error(
- rpcid, -11012, NULL,
- "sharkd_session_process_tap() %s not recognized", tok_tap
- );
- return;
- }
-
- if (tap_error)
- {
- sharkd_json_error(
- rpcid, -11013, NULL,
- "sharkd_session_process_tap() name=%s error=%s", tok_tap, tap_error->str
- );
- g_string_free(tap_error, TRUE);
- if (tap_free)
- tap_free(tap_data);
- return;
- }
-
- taps_data[taps_count] = tap_data;
- taps_free[taps_count] = tap_free;
- taps_count++;
- }
-
- fprintf(stderr, "sharkd_session_process_tap() count=%d\n", taps_count);
- if (taps_count == 0)
- {
- sharkd_json_result_prologue(rpcid);
- sharkd_json_array_open("taps");
- sharkd_json_array_close();
- sharkd_json_result_epilogue();
- return;
- }
-
- sharkd_json_result_prologue(rpcid);
- sharkd_json_array_open("taps");
- sharkd_retap();
- sharkd_json_array_close();
- sharkd_json_result_epilogue();
-
- for (i = 0; i < taps_count; i++)
- {
- if (taps_data[i])
- remove_tap_listener(taps_data[i]);
-
- if (taps_free[i])
- taps_free[i](taps_data[i]);
- }
+ void *taps_data[16];
+ GFreeFunc taps_free[16];
+ int taps_count = 0;
+ int i;
+
+ rtpstream_tapinfo_t rtp_tapinfo =
+ { NULL, NULL, NULL, NULL, 0, NULL, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE, FALSE};
+
+ for (i = 0; i < 16; i++)
+ {
+ char tapbuf[32];
+ const char *tok_tap;
+
+ void *tap_data = NULL;
+ GFreeFunc tap_free = NULL;
+ const char *tap_filter = "";
+ GString *tap_error = NULL;
+
+ snprintf(tapbuf, sizeof(tapbuf), "tap%d", i);
+ tok_tap = json_find_attr(buf, tokens, count, tapbuf);
+ if (!tok_tap)
+ break;
+
+ if (!strncmp(tok_tap, "stat:", 5))
+ {
+ stats_tree_cfg *cfg = stats_tree_get_cfg_by_abbr(tok_tap + 5);
+ stats_tree *st;
+
+ if (!cfg)
+ {
+ sharkd_json_error(
+ rpcid, -11001, NULL,
+ "sharkd_session_process_tap() stat %s not found", tok_tap + 5
+ );
+ return;
+ }
+
+ st = stats_tree_new(cfg, NULL, tap_filter);
+
+ tap_error = register_tap_listener(st->cfg->tapname, st, st->filter, st->cfg->flags, stats_tree_reset, stats_tree_packet, sharkd_session_process_tap_stats_cb, NULL);
+
+ if (!tap_error && cfg->init)
+ cfg->init(st);
+
+ tap_data = st;
+ tap_free = sharkd_session_free_tap_stats_cb;
+ }
+ else if (!strcmp(tok_tap, "expert"))
+ {
+ struct sharkd_expert_tap *expert_tap;
+
+ expert_tap = g_new0(struct sharkd_expert_tap, 1);
+ expert_tap->text = g_string_chunk_new(100);
+
+ tap_error = register_tap_listener("expert", expert_tap, NULL, 0, NULL, sharkd_session_packet_tap_expert_cb, sharkd_session_process_tap_expert_cb, NULL);
+
+ tap_data = expert_tap;
+ tap_free = sharkd_session_free_tap_expert_cb;
+ }
+ else if (!strncmp(tok_tap, "seqa:", 5))
+ {
+ seq_analysis_info_t *graph_analysis;
+ register_analysis_t *analysis;
+ const char *tap_name;
+ tap_packet_cb tap_func;
+ guint tap_flags;
+
+ analysis = sequence_analysis_find_by_name(tok_tap + 5);
+ if (!analysis)
+ {
+ sharkd_json_error(
+ rpcid, -11002, NULL,
+ "sharkd_session_process_tap() seq analysis %s not found", tok_tap + 5
+ );
+ return;
+ }
+
+ graph_analysis = sequence_analysis_info_new();
+ graph_analysis->name = tok_tap + 5;
+ /* TODO, make configurable */
+ graph_analysis->any_addr = FALSE;
+
+ tap_name = sequence_analysis_get_tap_listener_name(analysis);
+ tap_flags = sequence_analysis_get_tap_flags(analysis);
+ tap_func = sequence_analysis_get_packet_func(analysis);
+
+ tap_error = register_tap_listener(tap_name, graph_analysis, NULL, tap_flags, NULL, tap_func, sharkd_session_process_tap_flow_cb, NULL);
+
+ tap_data = graph_analysis;
+ tap_free = sharkd_session_free_tap_flow_cb;
+ }
+ else if (!strncmp(tok_tap, "conv:", 5) || !strncmp(tok_tap, "endpt:", 6))
+ {
+ struct register_ct *ct = NULL;
+ const char *ct_tapname;
+ struct sharkd_conv_tap_data *ct_data;
+ tap_packet_cb tap_func = NULL;
+
+ if (!strncmp(tok_tap, "conv:", 5))
+ {
+ ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 5));
+
+ if (!ct || !(tap_func = get_conversation_packet_func(ct)))
+ {
+ sharkd_json_error(
+ rpcid, -11003, NULL,
+ "sharkd_session_process_tap() conv %s not found", tok_tap + 5
+ );
+ return;
+ }
+ }
+ else if (!strncmp(tok_tap, "endpt:", 6))
+ {
+ ct = get_conversation_by_proto_id(proto_get_id_by_short_name(tok_tap + 6));
+
+ if (!ct || !(tap_func = get_hostlist_packet_func(ct)))
+ {
+ sharkd_json_error(
+ rpcid, -11004, NULL,
+ "sharkd_session_process_tap() endpt %s not found", tok_tap + 6
+ );
+ return;
+ }
+ }
+ else
+ {
+ sharkd_json_error(
+ rpcid, -11005, NULL,
+ "sharkd_session_process_tap() conv/endpt(?): %s not found", tok_tap
+ );
+ return;
+ }
+
+ ct_tapname = proto_get_protocol_filter_name(get_conversation_proto_id(ct));
+
+ ct_data = g_new0(struct sharkd_conv_tap_data, 1);
+ ct_data->type = tok_tap;
+ ct_data->hash.user_data = ct_data;
+
+ /* XXX: make configurable */
+ ct_data->resolve_name = TRUE;
+ ct_data->resolve_port = TRUE;
+
+ tap_error = register_tap_listener(ct_tapname, &ct_data->hash, tap_filter, 0, NULL, tap_func, sharkd_session_process_tap_conv_cb, NULL);
+
+ tap_data = &ct_data->hash;
+ tap_free = sharkd_session_free_tap_conv_cb;
+ }
+ else if (!strncmp(tok_tap, "nstat:", 6))
+ {
+ stat_tap_table_ui *stat_tap = stat_tap_by_name(tok_tap + 6);
+ stat_data_t *stat_data;
+
+ if (!stat_tap)
+ {
+ sharkd_json_error(
+ rpcid, -11006, NULL,
+ "sharkd_session_process_tap() nstat=%s not found", tok_tap + 6
+ );
+ return;
+ }
+
+ stat_tap->stat_tap_init_cb(stat_tap);
+
+ stat_data = g_new0(stat_data_t, 1);
+ stat_data->stat_tap_data = stat_tap;
+ stat_data->user_data = NULL;
+
+ tap_error = register_tap_listener(stat_tap->tap_name, stat_data, tap_filter, 0, NULL, stat_tap->packet_func, sharkd_session_process_tap_nstat_cb, NULL);
+
+ tap_data = stat_data;
+ tap_free = sharkd_session_free_tap_nstat_cb;
+ }
+ else if (!strncmp(tok_tap, "rtd:", 4))
+ {
+ register_rtd_t *rtd = get_rtd_table_by_name(tok_tap + 4);
+ rtd_data_t *rtd_data;
+ char *err;
+
+ if (!rtd)
+ {
+ sharkd_json_error(
+ rpcid, -11007, NULL,
+ "sharkd_session_process_tap() rtd=%s not found", tok_tap + 4
+ );
+ return;
+ }
+
+ rtd_table_get_filter(rtd, "", &tap_filter, &err);
+ if (err != NULL)
+ {
+ sharkd_json_error(
+ rpcid, -11008, NULL,
+ "sharkd_session_process_tap() rtd=%s err=%s", tok_tap + 4, err
+ );
+ g_free(err);
+ return;
+ }
+
+ rtd_data = g_new0(rtd_data_t, 1);
+ rtd_data->user_data = rtd;
+ rtd_table_dissector_init(rtd, &rtd_data->stat_table, NULL, NULL);
+
+ tap_error = register_tap_listener(get_rtd_tap_listener_name(rtd), rtd_data, tap_filter, 0, NULL, get_rtd_packet_func(rtd), sharkd_session_process_tap_rtd_cb, NULL);
+
+ tap_data = rtd_data;
+ tap_free = sharkd_session_free_tap_rtd_cb;
+ }
+ else if (!strncmp(tok_tap, "srt:", 4))
+ {
+ register_srt_t *srt = get_srt_table_by_name(tok_tap + 4);
+ srt_data_t *srt_data;
+ char *err;
+
+ if (!srt)
+ {
+ sharkd_json_error(
+ rpcid, -11009, NULL,
+ "sharkd_session_process_tap() srt=%s not found", tok_tap + 4
+ );
+ return;
+ }
+
+ srt_table_get_filter(srt, "", &tap_filter, &err);
+ if (err != NULL)
+ {
+ sharkd_json_error(
+ rpcid, -11010, NULL,
+ "sharkd_session_process_tap() srt=%s err=%s", tok_tap + 4, err
+ );
+ g_free(err);
+ return;
+ }
+
+ srt_data = g_new0(srt_data_t, 1);
+ srt_data->srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table *));
+ srt_data->user_data = srt;
+ srt_table_dissector_init(srt, srt_data->srt_array);
+
+ tap_error = register_tap_listener(get_srt_tap_listener_name(srt), srt_data, tap_filter, 0, NULL, get_srt_packet_func(srt), sharkd_session_process_tap_srt_cb, NULL);
+
+ tap_data = srt_data;
+ tap_free = sharkd_session_free_tap_srt_cb;
+ }
+ else if (!strncmp(tok_tap, "eo:", 3))
+ {
+ register_eo_t *eo = get_eo_by_name(tok_tap + 3);
+ export_object_list_t *eo_object;
+ struct sharkd_export_object_list *object_list;
+
+ if (!eo)
+ {
+ sharkd_json_error(
+ rpcid, -11011, NULL,
+ "sharkd_session_process_tap() eo=%s not found", tok_tap + 3
+ );
+ return;
+ }
+
+ for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)
+ {
+ if (!strcmp(object_list->type, tok_tap))
+ {
+ g_slist_free_full(object_list->entries, (GDestroyNotify) eo_free_entry);
+ object_list->entries = NULL;
+ break;
+ }
+ }
+
+ if (!object_list)
+ {
+ object_list = g_new(struct sharkd_export_object_list, 1);
+ object_list->type = g_strdup(tok_tap);
+ object_list->proto = proto_get_protocol_short_name(find_protocol_by_id(get_eo_proto_id(eo)));
+ object_list->entries = NULL;
+ object_list->next = sharkd_eo_list;
+ sharkd_eo_list = object_list;
+ }
+
+ eo_object = g_new0(export_object_list_t, 1);
+ eo_object->add_entry = sharkd_eo_object_list_add_entry;
+ eo_object->get_entry = sharkd_eo_object_list_get_entry;
+ eo_object->gui_data = (void *) object_list;
+
+ tap_error = register_tap_listener(get_eo_tap_listener_name(eo), eo_object, NULL, 0, NULL, get_eo_packet_func(eo), sharkd_session_process_tap_eo_cb, NULL);
+
+ tap_data = eo_object;
+ tap_free = g_free; /* need to free only eo_object, object_list need to be kept for potential download */
+ }
+ else if (!strcmp(tok_tap, "rtp-streams"))
+ {
+ tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet_cb, sharkd_session_process_tap_rtp_cb, NULL);
+
+ tap_data = &rtp_tapinfo;
+ tap_free = rtpstream_reset_cb;
+ }
+ else if (!strncmp(tok_tap, "rtp-analyse:", 12))
+ {
+ struct sharkd_analyse_rtp *rtp_req;
+
+ rtp_req = (struct sharkd_analyse_rtp *) g_malloc0(sizeof(*rtp_req));
+ if (!sharkd_rtp_match_init(&rtp_req->id, tok_tap + 12))
+ {
+ rtpstream_id_free(&rtp_req->id);
+ g_free(rtp_req);
+ continue;
+ }
+
+ rtp_req->tap_name = tok_tap;
+ rtp_req->statinfo.first_packet = TRUE;
+ rtp_req->statinfo.reg_pt = PT_UNDEFINED;
+
+ tap_error = register_tap_listener("rtp", rtp_req, tap_filter, 0, NULL, sharkd_session_packet_tap_rtp_analyse_cb, sharkd_session_process_tap_rtp_analyse_cb, NULL);
+
+ tap_data = rtp_req;
+ tap_free = sharkd_session_process_tap_rtp_free_cb;
+ }
+ else
+ {
+ sharkd_json_error(
+ rpcid, -11012, NULL,
+ "sharkd_session_process_tap() %s not recognized", tok_tap
+ );
+ return;
+ }
+
+ if (tap_error)
+ {
+ sharkd_json_error(
+ rpcid, -11013, NULL,
+ "sharkd_session_process_tap() name=%s error=%s", tok_tap, tap_error->str
+ );
+ g_string_free(tap_error, TRUE);
+ if (tap_free)
+ tap_free(tap_data);
+ return;
+ }
+
+ taps_data[taps_count] = tap_data;
+ taps_free[taps_count] = tap_free;
+ taps_count++;
+ }
+
+ fprintf(stderr, "sharkd_session_process_tap() count=%d\n", taps_count);
+ if (taps_count == 0)
+ {
+ sharkd_json_result_prologue(rpcid);
+ sharkd_json_array_open("taps");
+ sharkd_json_array_close();
+ sharkd_json_result_epilogue();
+ return;
+ }
+
+ sharkd_json_result_prologue(rpcid);
+ sharkd_json_array_open("taps");
+ sharkd_retap();
+ sharkd_json_array_close();
+ sharkd_json_result_epilogue();
+
+ for (i = 0; i < taps_count; i++)
+ {
+ if (taps_data[i])
+ remove_tap_listener(taps_data[i]);
+
+ if (taps_free[i])
+ taps_free[i](taps_data[i]);
+ }
}
/**
@@ -3180,453 +3180,453 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count)
static void
sharkd_session_process_follow(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_follow = json_find_attr(buf, tokens, count, "follow");
- const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
+ const char *tok_follow = json_find_attr(buf, tokens, count, "follow");
+ const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
- register_follow_t *follower;
- GString *tap_error;
+ register_follow_t *follower;
+ GString *tap_error;
- follow_info_t *follow_info;
- const char *host;
- char *port;
+ follow_info_t *follow_info;
+ const char *host;
+ char *port;
- follower = get_follow_by_name(tok_follow);
- if (!follower)
- {
- sharkd_json_error(
- rpcid, -12001, NULL,
- "sharkd_session_process_follow() follower=%s not found", tok_follow
- );
- return;
- }
+ follower = get_follow_by_name(tok_follow);
+ if (!follower)
+ {
+ sharkd_json_error(
+ rpcid, -12001, NULL,
+ "sharkd_session_process_follow() follower=%s not found", tok_follow
+ );
+ return;
+ }
- /* follow_reset_stream ? */
- follow_info = g_new0(follow_info_t, 1);
- /* gui_data, filter_out_filter not set, but not used by dissector */
+ /* follow_reset_stream ? */
+ follow_info = g_new0(follow_info_t, 1);
+ /* gui_data, filter_out_filter not set, but not used by dissector */
- tap_error = register_tap_listener(get_follow_tap_string(follower), follow_info, tok_filter, 0, NULL, get_follow_tap_handler(follower), NULL, NULL);
- if (tap_error)
- {
- sharkd_json_error(
- rpcid, -12002, NULL,
- "sharkd_session_process_follow() name=%s error=%s", tok_follow, tap_error->str
- );
- g_string_free(tap_error, TRUE);
- g_free(follow_info);
- return;
- }
+ tap_error = register_tap_listener(get_follow_tap_string(follower), follow_info, tok_filter, 0, NULL, get_follow_tap_handler(follower), NULL, NULL);
+ if (tap_error)
+ {
+ sharkd_json_error(
+ rpcid, -12002, NULL,
+ "sharkd_session_process_follow() name=%s error=%s", tok_follow, tap_error->str
+ );
+ g_string_free(tap_error, TRUE);
+ g_free(follow_info);
+ return;
+ }
- sharkd_retap();
+ sharkd_retap();
- sharkd_json_result_prologue(rpcid);
+ sharkd_json_result_prologue(rpcid);
- /* Server information: hostname, port, bytes sent */
- host = address_to_name(&follow_info->server_ip);
- sharkd_json_value_string("shost", host);
+ /* Server information: hostname, port, bytes sent */
+ host = address_to_name(&follow_info->server_ip);
+ sharkd_json_value_string("shost", host);
- port = get_follow_port_to_display(follower)(NULL, follow_info->server_port);
- sharkd_json_value_string("sport", port);
- wmem_free(NULL, port);
+ port = get_follow_port_to_display(follower)(NULL, follow_info->server_port);
+ sharkd_json_value_string("sport", port);
+ wmem_free(NULL, port);
- sharkd_json_value_anyf("sbytes", "%u", follow_info->bytes_written[0]);
+ sharkd_json_value_anyf("sbytes", "%u", follow_info->bytes_written[0]);
- /* Client information: hostname, port, bytes sent */
- host = address_to_name(&follow_info->client_ip);
- sharkd_json_value_string("chost", host);
+ /* Client information: hostname, port, bytes sent */
+ host = address_to_name(&follow_info->client_ip);
+ sharkd_json_value_string("chost", host);
- port = get_follow_port_to_display(follower)(NULL, follow_info->client_port);
- sharkd_json_value_string("cport", port);
- wmem_free(NULL, port);
+ port = get_follow_port_to_display(follower)(NULL, follow_info->client_port);
+ sharkd_json_value_string("cport", port);
+ wmem_free(NULL, port);
- sharkd_json_value_anyf("cbytes", "%u", follow_info->bytes_written[1]);
+ sharkd_json_value_anyf("cbytes", "%u", follow_info->bytes_written[1]);
- if (follow_info->payload)
- {
- follow_record_t *follow_record;
- GList *cur;
+ if (follow_info->payload)
+ {
+ follow_record_t *follow_record;
+ GList *cur;
- sharkd_json_array_open("payloads");
- for (cur = g_list_last(follow_info->payload); cur; cur = g_list_previous(cur))
- {
- follow_record = (follow_record_t *) cur->data;
+ sharkd_json_array_open("payloads");
+ for (cur = g_list_last(follow_info->payload); cur; cur = g_list_previous(cur))
+ {
+ follow_record = (follow_record_t *) cur->data;
- json_dumper_begin_object(&dumper);
+ json_dumper_begin_object(&dumper);
- sharkd_json_value_anyf("n", "%u", follow_record->packet_num);
- sharkd_json_value_base64("d", follow_record->data->data, follow_record->data->len);
+ sharkd_json_value_anyf("n", "%u", follow_record->packet_num);
+ sharkd_json_value_base64("d", follow_record->data->data, follow_record->data->len);
- if (follow_record->is_server)
- sharkd_json_value_anyf("s", "%d", 1);
+ if (follow_record->is_server)
+ sharkd_json_value_anyf("s", "%d", 1);
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
- }
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
+ }
- sharkd_json_result_epilogue();
+ sharkd_json_result_epilogue();
- remove_tap_listener(follow_info);
- follow_info_free(follow_info);
+ remove_tap_listener(follow_info);
+ follow_info_free(follow_info);
}
static void
sharkd_session_process_frame_cb_tree(epan_dissect_t *edt, proto_tree *tree, tvbuff_t **tvbs, gboolean display_hidden)
{
- proto_node *node;
-
- sharkd_json_array_open(NULL);
- for (node = tree->first_child; node; node = node->next)
- {
- field_info *finfo = PNODE_FINFO(node);
-
- if (!finfo)
- continue;
-
- if (!display_hidden && FI_GET_FLAG(finfo, FI_HIDDEN))
- continue;
-
- json_dumper_begin_object(&dumper);
-
- if (!finfo->rep)
- {
- char label_str[ITEM_LABEL_LENGTH];
-
- label_str[0] = '\0';
- proto_item_fill_label(finfo, label_str);
- sharkd_json_value_string("l", label_str);
- }
- else
- {
- sharkd_json_value_string("l", finfo->rep->representation);
- }
-
- if (finfo->ds_tvb && tvbs && tvbs[0] != finfo->ds_tvb)
- {
- int idx;
-
- for (idx = 1; tvbs[idx]; idx++)
- {
- if (tvbs[idx] == finfo->ds_tvb)
- {
- sharkd_json_value_anyf("ds", "%d", idx);
- break;
- }
- }
- }
-
- if (finfo->start >= 0 && finfo->length > 0)
- sharkd_json_value_anyf("h", "[%d,%d]", finfo->start, finfo->length);
-
- if (finfo->appendix_start >= 0 && finfo->appendix_length > 0)
- sharkd_json_value_anyf("i", "[%d,%d]", finfo->appendix_start, finfo->appendix_length);
-
-
- if (finfo->hfinfo)
- {
- char *filter;
-
- if (finfo->hfinfo->type == FT_PROTOCOL)
- {
- sharkd_json_value_string("t", "proto");
- }
- else if (finfo->hfinfo->type == FT_FRAMENUM)
- {
- sharkd_json_value_string("t", "framenum");
- sharkd_json_value_anyf("fnum", "%u", finfo->value.value.uinteger);
- }
- else if (FI_GET_FLAG(finfo, FI_URL) && IS_FT_STRING(finfo->hfinfo->type))
- {
- char *url = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, finfo->hfinfo->display);
-
- sharkd_json_value_string("t", "url");
- sharkd_json_value_string("url", url);
- wmem_free(NULL, url);
- }
-
- filter = proto_construct_match_selected_string(finfo, edt);
- if (filter)
- {
- sharkd_json_value_string("f", filter);
- wmem_free(NULL, filter);
- }
- }
-
- if (FI_GET_FLAG(finfo, FI_GENERATED))
- sharkd_json_value_anyf("g", "true");
-
- if (FI_GET_FLAG(finfo, FI_HIDDEN))
- sharkd_json_value_anyf("v", "true");
-
- if (FI_GET_FLAG(finfo, PI_SEVERITY_MASK))
- {
- const char *severity = try_val_to_str(FI_GET_FLAG(finfo, PI_SEVERITY_MASK), expert_severity_vals);
-
- ws_assert(severity != NULL);
-
- sharkd_json_value_string("s", severity);
- }
-
- if (((proto_tree *) node)->first_child)
- {
- if (finfo->tree_type != -1)
- sharkd_json_value_anyf("e", "%d", finfo->tree_type);
-
- sharkd_json_value_anyf("n", NULL);
- sharkd_session_process_frame_cb_tree(edt, (proto_tree *) node, tvbs, display_hidden);
- }
-
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
+ proto_node *node;
+
+ sharkd_json_array_open(NULL);
+ for (node = tree->first_child; node; node = node->next)
+ {
+ field_info *finfo = PNODE_FINFO(node);
+
+ if (!finfo)
+ continue;
+
+ if (!display_hidden && FI_GET_FLAG(finfo, FI_HIDDEN))
+ continue;
+
+ json_dumper_begin_object(&dumper);
+
+ if (!finfo->rep)
+ {
+ char label_str[ITEM_LABEL_LENGTH];
+
+ label_str[0] = '\0';
+ proto_item_fill_label(finfo, label_str);
+ sharkd_json_value_string("l", label_str);
+ }
+ else
+ {
+ sharkd_json_value_string("l", finfo->rep->representation);
+ }
+
+ if (finfo->ds_tvb && tvbs && tvbs[0] != finfo->ds_tvb)
+ {
+ int idx;
+
+ for (idx = 1; tvbs[idx]; idx++)
+ {
+ if (tvbs[idx] == finfo->ds_tvb)
+ {
+ sharkd_json_value_anyf("ds", "%d", idx);
+ break;
+ }
+ }
+ }
+
+ if (finfo->start >= 0 && finfo->length > 0)
+ sharkd_json_value_anyf("h", "[%d,%d]", finfo->start, finfo->length);
+
+ if (finfo->appendix_start >= 0 && finfo->appendix_length > 0)
+ sharkd_json_value_anyf("i", "[%d,%d]", finfo->appendix_start, finfo->appendix_length);
+
+
+ if (finfo->hfinfo)
+ {
+ char *filter;
+
+ if (finfo->hfinfo->type == FT_PROTOCOL)
+ {
+ sharkd_json_value_string("t", "proto");
+ }
+ else if (finfo->hfinfo->type == FT_FRAMENUM)
+ {
+ sharkd_json_value_string("t", "framenum");
+ sharkd_json_value_anyf("fnum", "%u", finfo->value.value.uinteger);
+ }
+ else if (FI_GET_FLAG(finfo, FI_URL) && IS_FT_STRING(finfo->hfinfo->type))
+ {
+ char *url = fvalue_to_string_repr(NULL, &finfo->value, FTREPR_DISPLAY, finfo->hfinfo->display);
+
+ sharkd_json_value_string("t", "url");
+ sharkd_json_value_string("url", url);
+ wmem_free(NULL, url);
+ }
+
+ filter = proto_construct_match_selected_string(finfo, edt);
+ if (filter)
+ {
+ sharkd_json_value_string("f", filter);
+ wmem_free(NULL, filter);
+ }
+ }
+
+ if (FI_GET_FLAG(finfo, FI_GENERATED))
+ sharkd_json_value_anyf("g", "true");
+
+ if (FI_GET_FLAG(finfo, FI_HIDDEN))
+ sharkd_json_value_anyf("v", "true");
+
+ if (FI_GET_FLAG(finfo, PI_SEVERITY_MASK))
+ {
+ const char *severity = try_val_to_str(FI_GET_FLAG(finfo, PI_SEVERITY_MASK), expert_severity_vals);
+
+ ws_assert(severity != NULL);
+
+ sharkd_json_value_string("s", severity);
+ }
+
+ if (((proto_tree *) node)->first_child)
+ {
+ if (finfo->tree_type != -1)
+ sharkd_json_value_anyf("e", "%d", finfo->tree_type);
+
+ sharkd_json_value_anyf("n", NULL);
+ sharkd_session_process_frame_cb_tree(edt, (proto_tree *) node, tvbs, display_hidden);
+ }
+
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
}
static gboolean
sharkd_follower_visit_layers_cb(const void *key _U_, void *value, void *user_data)
{
- register_follow_t *follower = (register_follow_t *) value;
- packet_info *pi = (packet_info *) user_data;
+ register_follow_t *follower = (register_follow_t *) value;
+ packet_info *pi = (packet_info *) user_data;
- const int proto_id = get_follow_proto_id(follower);
+ const int proto_id = get_follow_proto_id(follower);
- guint32 ignore_stream;
- guint32 ignore_sub_stream;
+ guint32 ignore_stream;
+ guint32 ignore_sub_stream;
- if (proto_is_frame_protocol(pi->layers, proto_get_protocol_filter_name(proto_id)))
- {
- const char *layer_proto = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
- char *follow_filter;
+ if (proto_is_frame_protocol(pi->layers, proto_get_protocol_filter_name(proto_id)))
+ {
+ const char *layer_proto = proto_get_protocol_short_name(find_protocol_by_id(proto_id));
+ char *follow_filter;
- follow_filter = get_follow_conv_func(follower)(NULL, pi, &ignore_stream, &ignore_sub_stream);
+ follow_filter = get_follow_conv_func(follower)(NULL, pi, &ignore_stream, &ignore_sub_stream);
- json_dumper_begin_array(&dumper);
- json_dumper_value_string(&dumper, layer_proto);
- json_dumper_value_string(&dumper, follow_filter);
- json_dumper_end_array(&dumper);
+ json_dumper_begin_array(&dumper);
+ json_dumper_value_string(&dumper, layer_proto);
+ json_dumper_value_string(&dumper, follow_filter);
+ json_dumper_end_array(&dumper);
- g_free(follow_filter);
- }
+ g_free(follow_filter);
+ }
- return FALSE;
+ return FALSE;
}
struct sharkd_frame_request_data
{
- gboolean display_hidden;
+ gboolean display_hidden;
};
static void
sharkd_session_process_frame_cb(epan_dissect_t *edt, proto_tree *tree, struct epan_column_info *cinfo, const GSList *data_src, void *data)
{
- packet_info *pi = &edt->pi;
- frame_data *fdata = pi->fd;
- wtap_block_t pkt_block = NULL;
-
- const struct sharkd_frame_request_data * const req_data = (const struct sharkd_frame_request_data * const) data;
- const gboolean display_hidden = (req_data) ? req_data->display_hidden : FALSE;
-
- sharkd_json_result_prologue(rpcid);
-
- if (fdata->has_modified_block)
- pkt_block = sharkd_get_modified_block(fdata);
- else
- pkt_block = pi->rec->block;
-
- if (pkt_block)
- {
- guint i;
- guint n;
- gchar *comment;
-
- n = wtap_block_count_option(pkt_block, OPT_COMMENT);
-
- sharkd_json_array_open("comment");
- for (i = 0; i < n; i++) {
- if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT, i, &comment)) {
- sharkd_json_value_string(NULL, comment);
- }
- }
- sharkd_json_array_close();
- }
+ packet_info *pi = &edt->pi;
+ frame_data *fdata = pi->fd;
+ wtap_block_t pkt_block = NULL;
+
+ const struct sharkd_frame_request_data * const req_data = (const struct sharkd_frame_request_data * const) data;
+ const gboolean display_hidden = (req_data) ? req_data->display_hidden : FALSE;
+
+ sharkd_json_result_prologue(rpcid);
+
+ if (fdata->has_modified_block)
+ pkt_block = sharkd_get_modified_block(fdata);
+ else
+ pkt_block = pi->rec->block;
+
+ if (pkt_block)
+ {
+ guint i;
+ guint n;
+ gchar *comment;
+
+ n = wtap_block_count_option(pkt_block, OPT_COMMENT);
+
+ sharkd_json_array_open("comment");
+ for (i = 0; i < n; i++) {
+ if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT, i, &comment)) {
+ sharkd_json_value_string(NULL, comment);
+ }
+ }
+ sharkd_json_array_close();
+ }
- if (tree)
- {
- tvbuff_t **tvbs = NULL;
+ if (tree)
+ {
+ tvbuff_t **tvbs = NULL;
- /* arrayize data src, to speedup searching for ds_tvb index */
- if (data_src && data_src->next /* only needed if there are more than one data source */)
- {
- guint count = g_slist_length((GSList *) data_src);
- guint i;
-
- tvbs = (tvbuff_t **) g_malloc0((count + 1) * sizeof(*tvbs));
-
- for (i = 0; i < count; i++)
- {
- const struct data_source *src = (const struct data_source *) g_slist_nth_data((GSList *) data_src, i);
-
- tvbs[i] = get_data_source_tvb(src);
- }
-
- tvbs[count] = NULL;
- }
-
- sharkd_json_value_anyf("tree", NULL);
- sharkd_session_process_frame_cb_tree(edt, tree, tvbs, display_hidden);
-
- g_free(tvbs);
- }
-
- if (cinfo)
- {
- int col;
-
- sharkd_json_array_open("col");
- for (col = 0; col < cinfo->num_cols; ++col)
- {
- const col_item_t *col_item = &cinfo->columns[col];
-
- sharkd_json_value_string(NULL, col_item->col_data);
- }
- sharkd_json_array_close();
- }
-
- if (fdata->ignored)
- sharkd_json_value_anyf("i", "true");
-
- if (fdata->marked)
- sharkd_json_value_anyf("m", "true");
-
- if (fdata->color_filter)
- {
- sharkd_json_value_stringf("bg", "%x", color_t_to_rgb(&fdata->color_filter->bg_color));
- sharkd_json_value_stringf("fg", "%x", color_t_to_rgb(&fdata->color_filter->fg_color));
- }
-
- if (data_src)
- {
- struct data_source *src = (struct data_source *) data_src->data;
- gboolean ds_open = FALSE;
-
- tvbuff_t *tvb;
- guint length;
-
- tvb = get_data_source_tvb(src);
- length = tvb_captured_length(tvb);
-
- if (length != 0)
- {
- const guchar *cp = tvb_get_ptr(tvb, 0, length);
-
- /* XXX pi.fd->encoding */
- sharkd_json_value_base64("bytes", cp, length);
- }
- else
- {
- sharkd_json_value_base64("bytes", "", 0);
- }
-
- data_src = data_src->next;
- if (data_src)
- {
- sharkd_json_array_open("ds");
- ds_open = TRUE;
- }
-
- while (data_src)
- {
- src = (struct data_source *) data_src->data;
-
- json_dumper_begin_object(&dumper);
-
- {
- char *src_name = get_data_source_name(src);
-
- sharkd_json_value_string("name", src_name);
- wmem_free(NULL, src_name);
- }
+ /* arrayize data src, to speedup searching for ds_tvb index */
+ if (data_src && data_src->next /* only needed if there are more than one data source */)
+ {
+ guint count = g_slist_length((GSList *) data_src);
+ guint i;
+
+ tvbs = (tvbuff_t **) g_malloc0((count + 1) * sizeof(*tvbs));
+
+ for (i = 0; i < count; i++)
+ {
+ const struct data_source *src = (const struct data_source *) g_slist_nth_data((GSList *) data_src, i);
+
+ tvbs[i] = get_data_source_tvb(src);
+ }
+
+ tvbs[count] = NULL;
+ }
+
+ sharkd_json_value_anyf("tree", NULL);
+ sharkd_session_process_frame_cb_tree(edt, tree, tvbs, display_hidden);
+
+ g_free(tvbs);
+ }
+
+ if (cinfo)
+ {
+ int col;
+
+ sharkd_json_array_open("col");
+ for (col = 0; col < cinfo->num_cols; ++col)
+ {
+ const col_item_t *col_item = &cinfo->columns[col];
+
+ sharkd_json_value_string(NULL, col_item->col_data);
+ }
+ sharkd_json_array_close();
+ }
+
+ if (fdata->ignored)
+ sharkd_json_value_anyf("i", "true");
+
+ if (fdata->marked)
+ sharkd_json_value_anyf("m", "true");
+
+ if (fdata->color_filter)
+ {
+ sharkd_json_value_stringf("bg", "%x", color_t_to_rgb(&fdata->color_filter->bg_color));
+ sharkd_json_value_stringf("fg", "%x", color_t_to_rgb(&fdata->color_filter->fg_color));
+ }
+
+ if (data_src)
+ {
+ struct data_source *src = (struct data_source *) data_src->data;
+ gboolean ds_open = FALSE;
+
+ tvbuff_t *tvb;
+ guint length;
+
+ tvb = get_data_source_tvb(src);
+ length = tvb_captured_length(tvb);
+
+ if (length != 0)
+ {
+ const guchar *cp = tvb_get_ptr(tvb, 0, length);
+
+ /* XXX pi.fd->encoding */
+ sharkd_json_value_base64("bytes", cp, length);
+ }
+ else
+ {
+ sharkd_json_value_base64("bytes", "", 0);
+ }
+
+ data_src = data_src->next;
+ if (data_src)
+ {
+ sharkd_json_array_open("ds");
+ ds_open = TRUE;
+ }
+
+ while (data_src)
+ {
+ src = (struct data_source *) data_src->data;
+
+ json_dumper_begin_object(&dumper);
+
+ {
+ char *src_name = get_data_source_name(src);
+
+ sharkd_json_value_string("name", src_name);
+ wmem_free(NULL, src_name);
+ }
- tvb = get_data_source_tvb(src);
- length = tvb_captured_length(tvb);
+ tvb = get_data_source_tvb(src);
+ length = tvb_captured_length(tvb);
- if (length != 0)
- {
- const guchar *cp = tvb_get_ptr(tvb, 0, length);
+ if (length != 0)
+ {
+ const guchar *cp = tvb_get_ptr(tvb, 0, length);
- /* XXX pi.fd->encoding */
- sharkd_json_value_base64("bytes", cp, length);
- }
- else
- {
- sharkd_json_value_base64("bytes", "", 0);
- }
+ /* XXX pi.fd->encoding */
+ sharkd_json_value_base64("bytes", cp, length);
+ }
+ else
+ {
+ sharkd_json_value_base64("bytes", "", 0);
+ }
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
- data_src = data_src->next;
- }
+ data_src = data_src->next;
+ }
- /* close ds, only if was opened */
- if (ds_open)
- sharkd_json_array_close();
- }
+ /* close ds, only if was opened */
+ if (ds_open)
+ sharkd_json_array_close();
+ }
- sharkd_json_array_open("fol");
- follow_iterate_followers(sharkd_follower_visit_layers_cb, pi);
- sharkd_json_array_close();
-
- sharkd_json_result_epilogue();
+ sharkd_json_array_open("fol");
+ follow_iterate_followers(sharkd_follower_visit_layers_cb, pi);
+ sharkd_json_array_close();
+
+ sharkd_json_result_epilogue();
}
#define SHARKD_IOGRAPH_MAX_ITEMS 250000 /* 250k limit of items is taken from wireshark-qt, on x86_64 sizeof(io_graph_item_t) is 152, so single graph can take max 36 MB */
struct sharkd_iograph
{
- /* config */
- int hf_index;
- io_graph_item_unit_t calc_type;
- guint32 interval;
-
- /* result */
- int space_items;
- int num_items;
- io_graph_item_t *items;
- GString *error;
+ /* config */
+ int hf_index;
+ io_graph_item_unit_t calc_type;
+ guint32 interval;
+
+ /* result */
+ int space_items;
+ int num_items;
+ io_graph_item_t *items;
+ GString *error;
};
static tap_packet_status
sharkd_iograph_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const void *dummy _U_)
{
- struct sharkd_iograph *graph = (struct sharkd_iograph *) g;
- int idx;
- gboolean update_succeeded;
-
- idx = get_io_graph_index(pinfo, graph->interval);
- if (idx < 0 || idx >= SHARKD_IOGRAPH_MAX_ITEMS)
- return TAP_PACKET_DONT_REDRAW;
-
- if (idx + 1 > graph->num_items)
- {
- if (idx + 1 > graph->space_items)
- {
- int new_size = idx + 1024;
-
- graph->items = (io_graph_item_t *) g_realloc(graph->items, sizeof(io_graph_item_t) * new_size);
- reset_io_graph_items(&graph->items[graph->space_items], new_size - graph->space_items);
-
- graph->space_items = new_size;
- }
- else if (graph->items == NULL)
- {
- graph->items = g_new(io_graph_item_t, graph->space_items);
- reset_io_graph_items(graph->items, graph->space_items);
- }
-
- graph->num_items = idx + 1;
- }
-
- update_succeeded = update_io_graph_item(graph->items, idx, pinfo, edt, graph->hf_index, graph->calc_type, graph->interval);
- /* XXX - TAP_PACKET_FAILED if the item couldn't be updated, with an error message? */
- return update_succeeded ? TAP_PACKET_REDRAW : TAP_PACKET_DONT_REDRAW;
+ struct sharkd_iograph *graph = (struct sharkd_iograph *) g;
+ int idx;
+ gboolean update_succeeded;
+
+ idx = get_io_graph_index(pinfo, graph->interval);
+ if (idx < 0 || idx >= SHARKD_IOGRAPH_MAX_ITEMS)
+ return TAP_PACKET_DONT_REDRAW;
+
+ if (idx + 1 > graph->num_items)
+ {
+ if (idx + 1 > graph->space_items)
+ {
+ int new_size = idx + 1024;
+
+ graph->items = (io_graph_item_t *) g_realloc(graph->items, sizeof(io_graph_item_t) * new_size);
+ reset_io_graph_items(&graph->items[graph->space_items], new_size - graph->space_items);
+
+ graph->space_items = new_size;
+ }
+ else if (graph->items == NULL)
+ {
+ graph->items = g_new(io_graph_item_t, graph->space_items);
+ reset_io_graph_items(graph->items, graph->space_items);
+ }
+
+ graph->num_items = idx + 1;
+ }
+
+ update_succeeded = update_io_graph_item(graph->items, idx, pinfo, edt, graph->hf_index, graph->calc_type, graph->interval);
+ /* XXX - TAP_PACKET_FAILED if the item couldn't be updated, with an error message? */
+ return update_succeeded ? TAP_PACKET_REDRAW : TAP_PACKET_DONT_REDRAW;
}
/**
@@ -3652,141 +3652,141 @@ sharkd_iograph_packet(void *g, packet_info *pinfo, epan_dissect_t *edt, const vo
static void
sharkd_session_process_iograph(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_interval = json_find_attr(buf, tokens, count, "interval");
- struct sharkd_iograph graphs[10];
- gboolean is_any_ok = FALSE;
- int graph_count;
-
- guint32 interval_ms = 1000; /* default: one per second */
- int i;
-
- if (tok_interval)
- ws_strtou32(tok_interval, NULL, &interval_ms);
-
- for (i = graph_count = 0; i < (int) G_N_ELEMENTS(graphs); i++)
- {
- struct sharkd_iograph *graph = &graphs[graph_count];
-
- const char *tok_graph;
- const char *tok_filter;
- char tok_format_buf[32];
- const char *field_name;
-
- snprintf(tok_format_buf, sizeof(tok_format_buf), "graph%d", i);
- tok_graph = json_find_attr(buf, tokens, count, tok_format_buf);
- if (!tok_graph)
- break;
-
- snprintf(tok_format_buf, sizeof(tok_format_buf), "filter%d", i);
- tok_filter = json_find_attr(buf, tokens, count, tok_format_buf);
-
- if (!strcmp(tok_graph, "packets"))
- graph->calc_type = IOG_ITEM_UNIT_PACKETS;
- else if (!strcmp(tok_graph, "bytes"))
- graph->calc_type = IOG_ITEM_UNIT_BYTES;
- else if (!strcmp(tok_graph, "bits"))
- graph->calc_type = IOG_ITEM_UNIT_BITS;
- else if (g_str_has_prefix(tok_graph, "sum:"))
- graph->calc_type = IOG_ITEM_UNIT_CALC_SUM;
- else if (g_str_has_prefix(tok_graph, "frames:"))
- graph->calc_type = IOG_ITEM_UNIT_CALC_FRAMES;
- else if (g_str_has_prefix(tok_graph, "fields:"))
- graph->calc_type = IOG_ITEM_UNIT_CALC_FIELDS;
- else if (g_str_has_prefix(tok_graph, "max:"))
- graph->calc_type = IOG_ITEM_UNIT_CALC_MAX;
- else if (g_str_has_prefix(tok_graph, "min:"))
- graph->calc_type = IOG_ITEM_UNIT_CALC_MIN;
- else if (g_str_has_prefix(tok_graph, "avg:"))
- graph->calc_type = IOG_ITEM_UNIT_CALC_AVERAGE;
- else if (g_str_has_prefix(tok_graph, "load:"))
- graph->calc_type = IOG_ITEM_UNIT_CALC_LOAD;
- else
- break;
-
- field_name = strchr(tok_graph, ':');
- if (field_name)
- field_name = field_name + 1;
-
- graph->interval = interval_ms;
-
- graph->hf_index = -1;
- graph->error = check_field_unit(field_name, &graph->hf_index, graph->calc_type);
-
- graph->space_items = 0; /* TODO, can avoid realloc()s in sharkd_iograph_packet() by calculating: capture_time / interval */
- graph->num_items = 0;
- graph->items = NULL;
-
- if (!graph->error)
- graph->error = register_tap_listener("frame", graph, tok_filter, TL_REQUIRES_PROTO_TREE, NULL, sharkd_iograph_packet, NULL, NULL);
-
- graph_count++;
-
- if (graph->error)
- {
- sharkd_json_error(
- rpcid, -6001, NULL,
- "%s", graph->error->str
- );
- g_string_free(graph->error, TRUE);
- return;
- }
-
- if (graph->error == NULL)
- is_any_ok = TRUE;
- }
-
- /* retap only if we have at least one ok */
- if (is_any_ok)
- sharkd_retap();
-
- sharkd_json_result_prologue(rpcid);
-
- sharkd_json_array_open("iograph");
- for (i = 0; i < graph_count; i++)
- {
- struct sharkd_iograph *graph = &graphs[i];
-
- json_dumper_begin_object(&dumper);
-
- if (graph->error)
- {
- fprintf(stderr, "SNAP 6002 - we should never get to here.\n");
- g_string_free(graph->error, TRUE);
- exit(-1);
- }
- else
- {
- int idx;
- int next_idx = 0;
-
- sharkd_json_array_open("items");
- for (idx = 0; idx < graph->num_items; idx++)
- {
- double val;
-
- val = get_io_graph_item(graph->items, graph->calc_type, idx, graph->hf_index, &cfile, graph->interval, graph->num_items);
-
- /* if it's zero, don't display */
- if (val == 0.0)
- continue;
-
- /* cause zeros are not printed, need to output index */
- if (next_idx != idx)
- sharkd_json_value_stringf(NULL, "%x", idx);
-
- sharkd_json_value_anyf(NULL, "%f", val);
- next_idx = idx + 1;
- }
- sharkd_json_array_close();
- }
- json_dumper_end_object(&dumper);
-
- remove_tap_listener(graph);
- g_free(graph->items);
- }
- sharkd_json_array_close();
-
- sharkd_json_result_epilogue();
+ const char *tok_interval = json_find_attr(buf, tokens, count, "interval");
+ struct sharkd_iograph graphs[10];
+ gboolean is_any_ok = FALSE;
+ int graph_count;
+
+ guint32 interval_ms = 1000; /* default: one per second */
+ int i;
+
+ if (tok_interval)
+ ws_strtou32(tok_interval, NULL, &interval_ms);
+
+ for (i = graph_count = 0; i < (int) G_N_ELEMENTS(graphs); i++)
+ {
+ struct sharkd_iograph *graph = &graphs[graph_count];
+
+ const char *tok_graph;
+ const char *tok_filter;
+ char tok_format_buf[32];
+ const char *field_name;
+
+ snprintf(tok_format_buf, sizeof(tok_format_buf), "graph%d", i);
+ tok_graph = json_find_attr(buf, tokens, count, tok_format_buf);
+ if (!tok_graph)
+ break;
+
+ snprintf(tok_format_buf, sizeof(tok_format_buf), "filter%d", i);
+ tok_filter = json_find_attr(buf, tokens, count, tok_format_buf);
+
+ if (!strcmp(tok_graph, "packets"))
+ graph->calc_type = IOG_ITEM_UNIT_PACKETS;
+ else if (!strcmp(tok_graph, "bytes"))
+ graph->calc_type = IOG_ITEM_UNIT_BYTES;
+ else if (!strcmp(tok_graph, "bits"))
+ graph->calc_type = IOG_ITEM_UNIT_BITS;
+ else if (g_str_has_prefix(tok_graph, "sum:"))
+ graph->calc_type = IOG_ITEM_UNIT_CALC_SUM;
+ else if (g_str_has_prefix(tok_graph, "frames:"))
+ graph->calc_type = IOG_ITEM_UNIT_CALC_FRAMES;
+ else if (g_str_has_prefix(tok_graph, "fields:"))
+ graph->calc_type = IOG_ITEM_UNIT_CALC_FIELDS;
+ else if (g_str_has_prefix(tok_graph, "max:"))
+ graph->calc_type = IOG_ITEM_UNIT_CALC_MAX;
+ else if (g_str_has_prefix(tok_graph, "min:"))
+ graph->calc_type = IOG_ITEM_UNIT_CALC_MIN;
+ else if (g_str_has_prefix(tok_graph, "avg:"))
+ graph->calc_type = IOG_ITEM_UNIT_CALC_AVERAGE;
+ else if (g_str_has_prefix(tok_graph, "load:"))
+ graph->calc_type = IOG_ITEM_UNIT_CALC_LOAD;
+ else
+ break;
+
+ field_name = strchr(tok_graph, ':');
+ if (field_name)
+ field_name = field_name + 1;
+
+ graph->interval = interval_ms;
+
+ graph->hf_index = -1;
+ graph->error = check_field_unit(field_name, &graph->hf_index, graph->calc_type);
+
+ graph->space_items = 0; /* TODO, can avoid realloc()s in sharkd_iograph_packet() by calculating: capture_time / interval */
+ graph->num_items = 0;
+ graph->items = NULL;
+
+ if (!graph->error)
+ graph->error = register_tap_listener("frame", graph, tok_filter, TL_REQUIRES_PROTO_TREE, NULL, sharkd_iograph_packet, NULL, NULL);
+
+ graph_count++;
+
+ if (graph->error)
+ {
+ sharkd_json_error(
+ rpcid, -6001, NULL,
+ "%s", graph->error->str
+ );
+ g_string_free(graph->error, TRUE);
+ return;
+ }
+
+ if (graph->error == NULL)
+ is_any_ok = TRUE;
+ }
+
+ /* retap only if we have at least one ok */
+ if (is_any_ok)
+ sharkd_retap();
+
+ sharkd_json_result_prologue(rpcid);
+
+ sharkd_json_array_open("iograph");
+ for (i = 0; i < graph_count; i++)
+ {
+ struct sharkd_iograph *graph = &graphs[i];
+
+ json_dumper_begin_object(&dumper);
+
+ if (graph->error)
+ {
+ fprintf(stderr, "SNAP 6002 - we should never get to here.\n");
+ g_string_free(graph->error, TRUE);
+ exit(-1);
+ }
+ else
+ {
+ int idx;
+ int next_idx = 0;
+
+ sharkd_json_array_open("items");
+ for (idx = 0; idx < graph->num_items; idx++)
+ {
+ double val;
+
+ val = get_io_graph_item(graph->items, graph->calc_type, idx, graph->hf_index, &cfile, graph->interval, graph->num_items);
+
+ /* if it's zero, don't display */
+ if (val == 0.0)
+ continue;
+
+ /* cause zeros are not printed, need to output index */
+ if (next_idx != idx)
+ sharkd_json_value_stringf(NULL, "%x", idx);
+
+ sharkd_json_value_anyf(NULL, "%f", val);
+ next_idx = idx + 1;
+ }
+ sharkd_json_array_close();
+ }
+ json_dumper_end_object(&dumper);
+
+ remove_tap_listener(graph);
+ g_free(graph->items);
+ }
+ sharkd_json_array_close();
+
+ sharkd_json_result_epilogue();
}
/**
@@ -3813,103 +3813,103 @@ sharkd_session_process_iograph(char *buf, const jsmntok_t *tokens, int count)
static void
sharkd_session_process_intervals(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_interval = json_find_attr(buf, tokens, count, "interval");
- const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
+ const char *tok_interval = json_find_attr(buf, tokens, count, "interval");
+ const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
- const guint8 *filter_data = NULL;
+ const guint8 *filter_data = NULL;
- struct
- {
- unsigned int frames;
- guint64 bytes;
- } st, st_total;
+ struct
+ {
+ unsigned int frames;
+ guint64 bytes;
+ } st, st_total;
- nstime_t *start_ts;
+ nstime_t *start_ts;
- guint32 interval_ms = 1000; /* default: one per second */
+ guint32 interval_ms = 1000; /* default: one per second */
- gint64 idx;
- gint64 max_idx = 0;
+ gint64 idx;
+ gint64 max_idx = 0;
- if (tok_interval)
- ws_strtou32(tok_interval, NULL, &interval_ms); // already validated
+ if (tok_interval)
+ ws_strtou32(tok_interval, NULL, &interval_ms); // already validated
- if (tok_filter)
- {
- const struct sharkd_filter_item *filter_item;
+ if (tok_filter)
+ {
+ const struct sharkd_filter_item *filter_item;
- filter_item = sharkd_session_filter_data(tok_filter);
- if (!filter_item)
- {
- sharkd_json_error(
- rpcid, -7001, NULL,
- "Invalid filter parameter: %s", tok_filter
- );
- return;
- }
- filter_data = filter_item->filtered;
- }
+ filter_item = sharkd_session_filter_data(tok_filter);
+ if (!filter_item)
+ {
+ sharkd_json_error(
+ rpcid, -7001, NULL,
+ "Invalid filter parameter: %s", tok_filter
+ );
+ return;
+ }
+ filter_data = filter_item->filtered;
+ }
- st_total.frames = 0;
- st_total.bytes = 0;
+ st_total.frames = 0;
+ st_total.bytes = 0;
- st.frames = 0;
- st.bytes = 0;
+ st.frames = 0;
+ st.bytes = 0;
- idx = 0;
+ idx = 0;
- sharkd_json_result_prologue(rpcid);
- sharkd_json_array_open("intervals");
+ sharkd_json_result_prologue(rpcid);
+ sharkd_json_array_open("intervals");
- start_ts = (cfile.count >= 1) ? &(sharkd_get_frame(1)->abs_ts) : NULL;
+ start_ts = (cfile.count >= 1) ? &(sharkd_get_frame(1)->abs_ts) : NULL;
- for (guint32 framenum = 1; framenum <= cfile.count; framenum++)
- {
- frame_data *fdata;
- gint64 msec_rel;
- gint64 new_idx;
+ for (guint32 framenum = 1; framenum <= cfile.count; framenum++)
+ {
+ frame_data *fdata;
+ gint64 msec_rel;
+ gint64 new_idx;
- if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))
- continue;
+ if (filter_data && !(filter_data[framenum / 8] & (1 << (framenum % 8))))
+ continue;
- fdata = sharkd_get_frame(framenum);
+ fdata = sharkd_get_frame(framenum);
- msec_rel = (fdata->abs_ts.secs - start_ts->secs) * (gint64) 1000 + (fdata->abs_ts.nsecs - start_ts->nsecs) / 1000000;
- new_idx = msec_rel / interval_ms;
+ msec_rel = (fdata->abs_ts.secs - start_ts->secs) * (gint64) 1000 + (fdata->abs_ts.nsecs - start_ts->nsecs) / 1000000;
+ new_idx = msec_rel / interval_ms;
- if (idx != new_idx)
- {
- if (st.frames != 0)
- {
- sharkd_json_value_anyf(NULL, "[%" PRId64 ",%u,%" PRIu64 "]", idx, st.frames, st.bytes);
- }
+ if (idx != new_idx)
+ {
+ if (st.frames != 0)
+ {
+ sharkd_json_value_anyf(NULL, "[%" PRId64 ",%u,%" PRIu64 "]", idx, st.frames, st.bytes);
+ }
- idx = new_idx;
- if (idx > max_idx)
- max_idx = idx;
+ idx = new_idx;
+ if (idx > max_idx)
+ max_idx = idx;
- st.frames = 0;
- st.bytes = 0;
- }
+ st.frames = 0;
+ st.bytes = 0;
+ }
- st.frames += 1;
- st.bytes += fdata->pkt_len;
+ st.frames += 1;
+ st.bytes += fdata->pkt_len;
- st_total.frames += 1;
- st_total.bytes += fdata->pkt_len;
- }
+ st_total.frames += 1;
+ st_total.bytes += fdata->pkt_len;
+ }
- if (st.frames != 0)
- {
- sharkd_json_value_anyf(NULL, "[%" PRId64 ",%u,%" PRIu64 "]", idx, st.frames, st.bytes);
- }
- sharkd_json_array_close();
+ if (st.frames != 0)
+ {
+ sharkd_json_value_anyf(NULL, "[%" PRId64 ",%u,%" PRIu64 "]", idx, st.frames, st.bytes);
+ }
+ sharkd_json_array_close();
- sharkd_json_value_anyf("last", "%" PRId64, max_idx);
- sharkd_json_value_anyf("frames", "%u", st_total.frames);
- sharkd_json_value_anyf("bytes", "%" PRIu64, st_total.bytes);
+ sharkd_json_value_anyf("last", "%" PRId64, max_idx);
+ sharkd_json_value_anyf("frames", "%u", st_total.frames);
+ sharkd_json_value_anyf("bytes", "%" PRIu64, st_total.bytes);
- sharkd_json_result_epilogue();
+ sharkd_json_result_epilogue();
}
/**
@@ -3960,94 +3960,94 @@ sharkd_session_process_intervals(char *buf, const jsmntok_t *tokens, int count)
static void
sharkd_session_process_frame(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_frame = json_find_attr(buf, tokens, count, "frame");
- const char *tok_ref_frame = json_find_attr(buf, tokens, count, "ref_frame");
- const char *tok_prev_frame = json_find_attr(buf, tokens, count, "prev_frame");
- column_info *cinfo = NULL;
-
- guint32 framenum, ref_frame_num, prev_dis_num;
- guint32 dissect_flags = SHARKD_DISSECT_FLAG_NULL;
- struct sharkd_frame_request_data req_data;
- wtap_rec rec; /* Record metadata */
- Buffer rec_buf; /* Record data */
- enum dissect_request_status status;
- int err;
- gchar *err_info;
-
- ws_strtou32(tok_frame, NULL, &framenum); // we have already validated this
-
- ref_frame_num = (framenum != 1) ? 1 : 0;
- if (tok_ref_frame)
- {
- ws_strtou32(tok_ref_frame, NULL, &ref_frame_num);
- if (ref_frame_num > framenum)
- {
- sharkd_json_error(
- rpcid, -8001, NULL,
- "Invalid ref_frame - The ref_frame occurs after the frame specified"
- );
- return;
- }
- }
-
- prev_dis_num = framenum - 1;
- if (tok_prev_frame)
- {
- ws_strtou32(tok_prev_frame, NULL, &prev_dis_num);
- if (prev_dis_num >= framenum)
- {
- sharkd_json_error(
- rpcid, -8002, NULL,
- "Invalid prev_frame - The prev_frame occurs on or after the frame specified"
- );
- return;
- }
- }
-
- if (json_find_attr(buf, tokens, count, "proto") != NULL)
- dissect_flags |= SHARKD_DISSECT_FLAG_PROTO_TREE;
- if (json_find_attr(buf, tokens, count, "bytes") != NULL)
- dissect_flags |= SHARKD_DISSECT_FLAG_BYTES;
- if (json_find_attr(buf, tokens, count, "columns") != NULL) {
- dissect_flags |= SHARKD_DISSECT_FLAG_COLUMNS;
- cinfo = &cfile.cinfo;
- }
- if (json_find_attr(buf, tokens, count, "color") != NULL)
- dissect_flags |= SHARKD_DISSECT_FLAG_COLOR;
-
- req_data.display_hidden = (json_find_attr(buf, tokens, count, "v") != NULL);
-
- wtap_rec_init(&rec);
- ws_buffer_init(&rec_buf, 1514);
-
- status = sharkd_dissect_request(framenum, ref_frame_num, prev_dis_num,
- &rec, &rec_buf, cinfo, dissect_flags,
- &sharkd_session_process_frame_cb, &req_data, &err, &err_info);
- switch (status) {
-
- case DISSECT_REQUEST_SUCCESS:
- /* success */
- break;
-
- case DISSECT_REQUEST_NO_SUCH_FRAME:
- sharkd_json_error(
- rpcid, -8003, NULL,
- "Invalid frame - The frame number requested is out of range"
- );
- break;
-
- case DISSECT_REQUEST_READ_ERROR:
- sharkd_json_error(
- rpcid, -8003, NULL,
- /* XXX - show the error details */
- "Read error - The frame could not be read from the file"
- );
- g_free(err_info);
- break;
- }
-
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&rec_buf);
+ const char *tok_frame = json_find_attr(buf, tokens, count, "frame");
+ const char *tok_ref_frame = json_find_attr(buf, tokens, count, "ref_frame");
+ const char *tok_prev_frame = json_find_attr(buf, tokens, count, "prev_frame");
+ column_info *cinfo = NULL;
+
+ guint32 framenum, ref_frame_num, prev_dis_num;
+ guint32 dissect_flags = SHARKD_DISSECT_FLAG_NULL;
+ struct sharkd_frame_request_data req_data;
+ wtap_rec rec; /* Record metadata */
+ Buffer rec_buf; /* Record data */
+ enum dissect_request_status status;
+ int err;
+ gchar *err_info;
+
+ ws_strtou32(tok_frame, NULL, &framenum); // we have already validated this
+
+ ref_frame_num = (framenum != 1) ? 1 : 0;
+ if (tok_ref_frame)
+ {
+ ws_strtou32(tok_ref_frame, NULL, &ref_frame_num);
+ if (ref_frame_num > framenum)
+ {
+ sharkd_json_error(
+ rpcid, -8001, NULL,
+ "Invalid ref_frame - The ref_frame occurs after the frame specified"
+ );
+ return;
+ }
+ }
+
+ prev_dis_num = framenum - 1;
+ if (tok_prev_frame)
+ {
+ ws_strtou32(tok_prev_frame, NULL, &prev_dis_num);
+ if (prev_dis_num >= framenum)
+ {
+ sharkd_json_error(
+ rpcid, -8002, NULL,
+ "Invalid prev_frame - The prev_frame occurs on or after the frame specified"
+ );
+ return;
+ }
+ }
+
+ if (json_find_attr(buf, tokens, count, "proto") != NULL)
+ dissect_flags |= SHARKD_DISSECT_FLAG_PROTO_TREE;
+ if (json_find_attr(buf, tokens, count, "bytes") != NULL)
+ dissect_flags |= SHARKD_DISSECT_FLAG_BYTES;
+ if (json_find_attr(buf, tokens, count, "columns") != NULL) {
+ dissect_flags |= SHARKD_DISSECT_FLAG_COLUMNS;
+ cinfo = &cfile.cinfo;
+ }
+ if (json_find_attr(buf, tokens, count, "color") != NULL)
+ dissect_flags |= SHARKD_DISSECT_FLAG_COLOR;
+
+ req_data.display_hidden = (json_find_attr(buf, tokens, count, "v") != NULL);
+
+ wtap_rec_init(&rec);
+ ws_buffer_init(&rec_buf, 1514);
+
+ status = sharkd_dissect_request(framenum, ref_frame_num, prev_dis_num,
+ &rec, &rec_buf, cinfo, dissect_flags,
+ &sharkd_session_process_frame_cb, &req_data, &err, &err_info);
+ switch (status) {
+
+ case DISSECT_REQUEST_SUCCESS:
+ /* success */
+ break;
+
+ case DISSECT_REQUEST_NO_SUCH_FRAME:
+ sharkd_json_error(
+ rpcid, -8003, NULL,
+ "Invalid frame - The frame number requested is out of range"
+ );
+ break;
+
+ case DISSECT_REQUEST_READ_ERROR:
+ sharkd_json_error(
+ rpcid, -8003, NULL,
+ /* XXX - show the error details */
+ "Read error - The frame could not be read from the file"
+ );
+ g_free(err_info);
+ break;
+ }
+
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&rec_buf);
}
/**
@@ -4067,96 +4067,96 @@ sharkd_session_process_frame(char *buf, const jsmntok_t *tokens, int count)
static int
sharkd_session_process_check(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
- const char *tok_field = json_find_attr(buf, tokens, count, "field");
-
- if (tok_filter != NULL)
- {
- char *err_msg = NULL;
- dfilter_t *dfp;
-
- if (dfilter_compile(tok_filter, &dfp, &err_msg))
- {
- if (dfp && dfilter_deprecated_tokens(dfp))
- sharkd_json_warning(rpcid, err_msg);
- else
- sharkd_json_simple_ok(rpcid);
-
- dfilter_free(dfp);
- g_free(err_msg);
- return 0;
- }
- else
- {
- sharkd_json_error(
- rpcid, -5001, NULL,
- "Filter invalid - %s", err_msg
- );
- return -5001;
- }
- }
-
- if (tok_field != NULL)
- {
- header_field_info *hfi = proto_registrar_get_byname(tok_field);
-
- if (!hfi)
- {
- sharkd_json_error(
- rpcid, -5002, NULL,
- "Field %s not found", tok_field
- );
- return -5002;
- }
- else
- {
- sharkd_json_simple_ok(rpcid);
- return 0;
- }
- }
-
- sharkd_json_simple_ok(rpcid);
- return 0;
+ const char *tok_filter = json_find_attr(buf, tokens, count, "filter");
+ const char *tok_field = json_find_attr(buf, tokens, count, "field");
+
+ if (tok_filter != NULL)
+ {
+ char *err_msg = NULL;
+ dfilter_t *dfp;
+
+ if (dfilter_compile(tok_filter, &dfp, &err_msg))
+ {
+ if (dfp && dfilter_deprecated_tokens(dfp))
+ sharkd_json_warning(rpcid, err_msg);
+ else
+ sharkd_json_simple_ok(rpcid);
+
+ dfilter_free(dfp);
+ g_free(err_msg);
+ return 0;
+ }
+ else
+ {
+ sharkd_json_error(
+ rpcid, -5001, NULL,
+ "Filter invalid - %s", err_msg
+ );
+ return -5001;
+ }
+ }
+
+ if (tok_field != NULL)
+ {
+ header_field_info *hfi = proto_registrar_get_byname(tok_field);
+
+ if (!hfi)
+ {
+ sharkd_json_error(
+ rpcid, -5002, NULL,
+ "Field %s not found", tok_field
+ );
+ return -5002;
+ }
+ else
+ {
+ sharkd_json_simple_ok(rpcid);
+ return 0;
+ }
+ }
+
+ sharkd_json_simple_ok(rpcid);
+ return 0;
}
struct sharkd_session_process_complete_pref_data
{
- const char *module;
- const char *pref;
+ const char *module;
+ const char *pref;
};
static guint
sharkd_session_process_complete_pref_cb(module_t *module, gpointer d)
{
- struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;
+ struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;
- if (strncmp(data->pref, module->name, strlen(data->pref)) != 0)
- return 0;
+ if (strncmp(data->pref, module->name, strlen(data->pref)) != 0)
+ return 0;
- json_dumper_begin_object(&dumper);
- sharkd_json_value_string("f", module->name);
- sharkd_json_value_string("d", module->title);
- json_dumper_end_object(&dumper);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_string("f", module->name);
+ sharkd_json_value_string("d", module->title);
+ json_dumper_end_object(&dumper);
- return 0;
+ return 0;
}
static guint
sharkd_session_process_complete_pref_option_cb(pref_t *pref, gpointer d)
{
- struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;
- const char *pref_name = prefs_get_name(pref);
- const char *pref_title = prefs_get_title(pref);
+ struct sharkd_session_process_complete_pref_data *data = (struct sharkd_session_process_complete_pref_data *) d;
+ const char *pref_name = prefs_get_name(pref);
+ const char *pref_title = prefs_get_title(pref);
- if (strncmp(data->pref, pref_name, strlen(data->pref)) != 0)
- return 0;
+ if (strncmp(data->pref, pref_name, strlen(data->pref)) != 0)
+ return 0;
- json_dumper_begin_object(&dumper);
- sharkd_json_value_stringf("f", "%s.%s", data->module, pref_name);
- sharkd_json_value_string("d", pref_title);
- json_dumper_end_object(&dumper);
+ json_dumper_begin_object(&dumper);
+ sharkd_json_value_stringf("f", "%s.%s", data->module, pref_name);
+ sharkd_json_value_string("d", pref_title);
+ json_dumper_end_object(&dumper);
- return 0; /* continue */
+ return 0; /* continue */
}
/**
@@ -4181,107 +4181,107 @@ sharkd_session_process_complete_pref_option_cb(pref_t *pref, gpointer d)
static int
sharkd_session_process_complete(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_field = json_find_attr(buf, tokens, count, "field");
- const char *tok_pref = json_find_attr(buf, tokens, count, "pref");
-
- sharkd_json_result_prologue(rpcid);
-
- if (tok_field != NULL && tok_field[0])
- {
- const size_t filter_length = strlen(tok_field);
- const int filter_with_dot = !!strchr(tok_field, '.');
-
- void *proto_cookie;
- void *field_cookie;
- int proto_id;
-
- sharkd_json_array_open("field");
-
- for (proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; proto_id = proto_get_next_protocol(&proto_cookie))
- {
- protocol_t *protocol = find_protocol_by_id(proto_id);
- const char *protocol_filter;
- const char *protocol_name;
- header_field_info *hfinfo;
-
- if (!proto_is_protocol_enabled(protocol))
- continue;
-
- protocol_name = proto_get_protocol_long_name(protocol);
- protocol_filter = proto_get_protocol_filter_name(proto_id);
-
- if (strlen(protocol_filter) >= filter_length && !g_ascii_strncasecmp(tok_field, protocol_filter, filter_length))
- {
- json_dumper_begin_object(&dumper);
- {
- sharkd_json_value_string("f", protocol_filter);
- sharkd_json_value_anyf("t", "%d", FT_PROTOCOL);
- sharkd_json_value_string("n", protocol_name);
- }
- json_dumper_end_object(&dumper);
- }
-
- if (!filter_with_dot)
- continue;
-
- for (hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL; hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie))
- {
- if (hfinfo->same_name_prev_id != -1) /* ignore duplicate names */
- continue;
-
- if (strlen(hfinfo->abbrev) >= filter_length && !g_ascii_strncasecmp(tok_field, hfinfo->abbrev, filter_length))
- {
- json_dumper_begin_object(&dumper);
- {
- sharkd_json_value_string("f", hfinfo->abbrev);
-
- /* XXX, skip displaying name, if there are multiple (to not confuse user) */
- if (hfinfo->same_name_next == NULL)
- {
- sharkd_json_value_anyf("t", "%d", hfinfo->type);
- sharkd_json_value_string("n", hfinfo->name);
- }
- }
- json_dumper_end_object(&dumper);
- }
- }
- }
-
- sharkd_json_array_close();
- }
-
- if (tok_pref != NULL && tok_pref[0])
- {
- struct sharkd_session_process_complete_pref_data data;
- char *dot_sepa;
-
- data.module = tok_pref;
- data.pref = tok_pref;
-
- sharkd_json_array_open("pref");
- if ((dot_sepa = strchr(tok_pref, '.')))
- {
- module_t *pref_mod;
-
- *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */
- data.pref = dot_sepa + 1;
-
- pref_mod = prefs_find_module(data.module);
- if (pref_mod)
- prefs_pref_foreach(pref_mod, sharkd_session_process_complete_pref_option_cb, &data);
-
- *dot_sepa = '.';
- }
- else
- {
- prefs_modules_foreach(sharkd_session_process_complete_pref_cb, &data);
- }
- sharkd_json_array_close();
- }
-
- sharkd_json_result_epilogue();
-
- return 0;
+ const char *tok_field = json_find_attr(buf, tokens, count, "field");
+ const char *tok_pref = json_find_attr(buf, tokens, count, "pref");
+
+ sharkd_json_result_prologue(rpcid);
+
+ if (tok_field != NULL && tok_field[0])
+ {
+ const size_t filter_length = strlen(tok_field);
+ const int filter_with_dot = !!strchr(tok_field, '.');
+
+ void *proto_cookie;
+ void *field_cookie;
+ int proto_id;
+
+ sharkd_json_array_open("field");
+
+ for (proto_id = proto_get_first_protocol(&proto_cookie); proto_id != -1; proto_id = proto_get_next_protocol(&proto_cookie))
+ {
+ protocol_t *protocol = find_protocol_by_id(proto_id);
+ const char *protocol_filter;
+ const char *protocol_name;
+ header_field_info *hfinfo;
+
+ if (!proto_is_protocol_enabled(protocol))
+ continue;
+
+ protocol_name = proto_get_protocol_long_name(protocol);
+ protocol_filter = proto_get_protocol_filter_name(proto_id);
+
+ if (strlen(protocol_filter) >= filter_length && !g_ascii_strncasecmp(tok_field, protocol_filter, filter_length))
+ {
+ json_dumper_begin_object(&dumper);
+ {
+ sharkd_json_value_string("f", protocol_filter);
+ sharkd_json_value_anyf("t", "%d", FT_PROTOCOL);
+ sharkd_json_value_string("n", protocol_name);
+ }
+ json_dumper_end_object(&dumper);
+ }
+
+ if (!filter_with_dot)
+ continue;
+
+ for (hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo != NULL; hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie))
+ {
+ if (hfinfo->same_name_prev_id != -1) /* ignore duplicate names */
+ continue;
+
+ if (strlen(hfinfo->abbrev) >= filter_length && !g_ascii_strncasecmp(tok_field, hfinfo->abbrev, filter_length))
+ {
+ json_dumper_begin_object(&dumper);
+ {
+ sharkd_json_value_string("f", hfinfo->abbrev);
+
+ /* XXX, skip displaying name, if there are multiple (to not confuse user) */
+ if (hfinfo->same_name_next == NULL)
+ {
+ sharkd_json_value_anyf("t", "%d", hfinfo->type);
+ sharkd_json_value_string("n", hfinfo->name);
+ }
+ }
+ json_dumper_end_object(&dumper);
+ }
+ }
+ }
+
+ sharkd_json_array_close();
+ }
+
+ if (tok_pref != NULL && tok_pref[0])
+ {
+ struct sharkd_session_process_complete_pref_data data;
+ char *dot_sepa;
+
+ data.module = tok_pref;
+ data.pref = tok_pref;
+
+ sharkd_json_array_open("pref");
+ if ((dot_sepa = strchr(tok_pref, '.')))
+ {
+ module_t *pref_mod;
+
+ *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */
+ data.pref = dot_sepa + 1;
+
+ pref_mod = prefs_find_module(data.module);
+ if (pref_mod)
+ prefs_pref_foreach(pref_mod, sharkd_session_process_complete_pref_option_cb, &data);
+
+ *dot_sepa = '.';
+ }
+ else
+ {
+ prefs_modules_foreach(sharkd_session_process_complete_pref_cb, &data);
+ }
+ sharkd_json_array_close();
+ }
+
+ sharkd_json_result_epilogue();
+
+ return 0;
}
/**
@@ -4302,49 +4302,49 @@ sharkd_session_process_complete(char *buf, const jsmntok_t *tokens, int count)
static void
sharkd_session_process_setcomment(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_frame = json_find_attr(buf, tokens, count, "frame");
- const char *tok_comment = json_find_attr(buf, tokens, count, "comment");
-
- guint32 framenum;
- frame_data *fdata;
- wtap_opttype_return_val ret;
- wtap_block_t pkt_block = NULL;
-
- if (!tok_frame || !ws_strtou32(tok_frame, NULL, &framenum) || framenum == 0)
- {
- sharkd_json_error(
- rpcid, -3001, NULL,
- "Frame number must be a positive integer"
- );
- return;
- }
-
- fdata = sharkd_get_frame(framenum); // BUG HERE - If no file loaded you get a crash
- if (!fdata)
- {
- sharkd_json_error(
- rpcid, -3002, NULL,
- "Frame number is out of range"
- );
- return;
- }
-
- pkt_block = sharkd_get_packet_block(fdata);
-
- ret = wtap_block_add_string_option(pkt_block, OPT_COMMENT, tok_comment, strlen(tok_comment));
-
- if (ret != WTAP_OPTTYPE_SUCCESS)
- {
- sharkd_json_error(
- rpcid, -3003, NULL,
- "Unable to set the comment"
- );
- }
- else
- {
- sharkd_set_modified_block(fdata, pkt_block);
- sharkd_json_simple_ok(rpcid);
- }
+ const char *tok_frame = json_find_attr(buf, tokens, count, "frame");
+ const char *tok_comment = json_find_attr(buf, tokens, count, "comment");
+
+ guint32 framenum;
+ frame_data *fdata;
+ wtap_opttype_return_val ret;
+ wtap_block_t pkt_block = NULL;
+
+ if (!tok_frame || !ws_strtou32(tok_frame, NULL, &framenum) || framenum == 0)
+ {
+ sharkd_json_error(
+ rpcid, -3001, NULL,
+ "Frame number must be a positive integer"
+ );
+ return;
+ }
+
+ fdata = sharkd_get_frame(framenum); // BUG HERE - If no file loaded you get a crash
+ if (!fdata)
+ {
+ sharkd_json_error(
+ rpcid, -3002, NULL,
+ "Frame number is out of range"
+ );
+ return;
+ }
+
+ pkt_block = sharkd_get_packet_block(fdata);
+
+ ret = wtap_block_add_string_option(pkt_block, OPT_COMMENT, tok_comment, strlen(tok_comment));
+
+ if (ret != WTAP_OPTTYPE_SUCCESS)
+ {
+ sharkd_json_error(
+ rpcid, -3003, NULL,
+ "Unable to set the comment"
+ );
+ }
+ else
+ {
+ sharkd_set_modified_block(fdata, pkt_block);
+ sharkd_json_simple_ok(rpcid);
+ }
}
/**
@@ -4362,187 +4362,187 @@ sharkd_session_process_setcomment(char *buf, const jsmntok_t *tokens, int count)
static void
sharkd_session_process_setconf(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_name = json_find_attr(buf, tokens, count, "name");
- const char *tok_value = json_find_attr(buf, tokens, count, "value");
- char pref[4096];
- char *errmsg = NULL;
-
- prefs_set_pref_e ret;
-
- if (!tok_name || tok_name[0] == '\0')
- {
- sharkd_json_error(
- rpcid, -4001, NULL,
- "Preference name missing"
- );
- return;
- }
-
- if (!tok_value)
- {
- sharkd_json_error(
- rpcid, -4002, NULL,
- "Preference value missing"
- );
- return;
- }
-
- snprintf(pref, sizeof(pref), "%s:%s", tok_name, tok_value);
-
- ret = prefs_set_pref(pref, &errmsg);
-
- switch (ret)
- {
- case PREFS_SET_OK:
- sharkd_json_simple_ok(rpcid);
- break;
-
- case PREFS_SET_OBSOLETE:
- sharkd_json_error(
- rpcid, -4003, NULL,
- "The preference specified is obsolete"
- );
- break;
-
- case PREFS_SET_NO_SUCH_PREF:
- sharkd_json_error(
- rpcid, -4004, NULL,
- "No such preference exists"
- );
- break;
-
- default:
- sharkd_json_error(
- rpcid, -4005, NULL,
- "Unable to set the preference"
- );
- }
-
- g_free(errmsg);
+ const char *tok_name = json_find_attr(buf, tokens, count, "name");
+ const char *tok_value = json_find_attr(buf, tokens, count, "value");
+ char pref[4096];
+ char *errmsg = NULL;
+
+ prefs_set_pref_e ret;
+
+ if (!tok_name || tok_name[0] == '\0')
+ {
+ sharkd_json_error(
+ rpcid, -4001, NULL,
+ "Preference name missing"
+ );
+ return;
+ }
+
+ if (!tok_value)
+ {
+ sharkd_json_error(
+ rpcid, -4002, NULL,
+ "Preference value missing"
+ );
+ return;
+ }
+
+ snprintf(pref, sizeof(pref), "%s:%s", tok_name, tok_value);
+
+ ret = prefs_set_pref(pref, &errmsg);
+
+ switch (ret)
+ {
+ case PREFS_SET_OK:
+ sharkd_json_simple_ok(rpcid);
+ break;
+
+ case PREFS_SET_OBSOLETE:
+ sharkd_json_error(
+ rpcid, -4003, NULL,
+ "The preference specified is obsolete"
+ );
+ break;
+
+ case PREFS_SET_NO_SUCH_PREF:
+ sharkd_json_error(
+ rpcid, -4004, NULL,
+ "No such preference exists"
+ );
+ break;
+
+ default:
+ sharkd_json_error(
+ rpcid, -4005, NULL,
+ "Unable to set the preference"
+ );
+ }
+
+ g_free(errmsg);
}
struct sharkd_session_process_dumpconf_data
{
- module_t *module;
+ module_t *module;
};
static guint
sharkd_session_process_dumpconf_cb(pref_t *pref, gpointer d)
{
- struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;
- const char *pref_name = prefs_get_name(pref);
-
- char json_pref_key[512];
-
- snprintf(json_pref_key, sizeof(json_pref_key), "%s.%s", data->module->name, pref_name);
- json_dumper_set_member_name(&dumper, json_pref_key);
- json_dumper_begin_object(&dumper);
-
- switch (prefs_get_type(pref))
- {
- case PREF_UINT:
- case PREF_DECODE_AS_UINT:
- sharkd_json_value_anyf("u", "%u", prefs_get_uint_value_real(pref, pref_current));
- if (prefs_get_uint_base(pref) != 10)
- sharkd_json_value_anyf("ub", "%u", prefs_get_uint_base(pref));
- break;
-
- case PREF_BOOL:
- sharkd_json_value_anyf("b", prefs_get_bool_value(pref, pref_current) ? "1" : "0");
- break;
-
- case PREF_STRING:
- case PREF_SAVE_FILENAME:
- case PREF_OPEN_FILENAME:
- case PREF_DIRNAME:
- case PREF_PASSWORD:
- sharkd_json_value_string("s", prefs_get_string_value(pref, pref_current));
- break;
-
- case PREF_ENUM:
- {
- const enum_val_t *enums;
-
- sharkd_json_array_open("e");
- for (enums = prefs_get_enumvals(pref); enums->name; enums++)
- {
- json_dumper_begin_object(&dumper);
-
- sharkd_json_value_anyf("v", "%d", enums->value);
-
- if (enums->value == prefs_get_enum_value(pref, pref_current))
- sharkd_json_value_anyf("s", "1");
-
- sharkd_json_value_string("d", enums->description);
-
- json_dumper_end_object(&dumper);
- }
- sharkd_json_array_close();
- break;
- }
-
- case PREF_RANGE:
- case PREF_DECODE_AS_RANGE:
- {
- char *range_str = range_convert_range(NULL, prefs_get_range_value_real(pref, pref_current));
- sharkd_json_value_string("r", range_str);
- wmem_free(NULL, range_str);
- break;
- }
-
- case PREF_UAT:
- {
- uat_t *uat = prefs_get_uat_value(pref);
- guint idx;
-
- sharkd_json_array_open("t");
- for (idx = 0; idx < uat->raw_data->len; idx++)
- {
- void *rec = UAT_INDEX_PTR(uat, idx);
- guint colnum;
-
- sharkd_json_array_open(NULL);
- for (colnum = 0; colnum < uat->ncols; colnum++)
- {
- char *str = uat_fld_tostr(rec, &(uat->fields[colnum]));
-
- sharkd_json_value_string(NULL, str);
- g_free(str);
- }
-
- sharkd_json_array_close();
- }
-
- sharkd_json_array_close();
- break;
- }
-
- case PREF_COLOR:
- case PREF_CUSTOM:
- case PREF_STATIC_TEXT:
- case PREF_OBSOLETE:
- /* TODO */
- break;
- }
+ struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;
+ const char *pref_name = prefs_get_name(pref);
+
+ char json_pref_key[512];
+
+ snprintf(json_pref_key, sizeof(json_pref_key), "%s.%s", data->module->name, pref_name);
+ json_dumper_set_member_name(&dumper, json_pref_key);
+ json_dumper_begin_object(&dumper);
+
+ switch (prefs_get_type(pref))
+ {
+ case PREF_UINT:
+ case PREF_DECODE_AS_UINT:
+ sharkd_json_value_anyf("u", "%u", prefs_get_uint_value_real(pref, pref_current));
+ if (prefs_get_uint_base(pref) != 10)
+ sharkd_json_value_anyf("ub", "%u", prefs_get_uint_base(pref));
+ break;
+
+ case PREF_BOOL:
+ sharkd_json_value_anyf("b", prefs_get_bool_value(pref, pref_current) ? "1" : "0");
+ break;
+
+ case PREF_STRING:
+ case PREF_SAVE_FILENAME:
+ case PREF_OPEN_FILENAME:
+ case PREF_DIRNAME:
+ case PREF_PASSWORD:
+ sharkd_json_value_string("s", prefs_get_string_value(pref, pref_current));
+ break;
+
+ case PREF_ENUM:
+ {
+ const enum_val_t *enums;
+
+ sharkd_json_array_open("e");
+ for (enums = prefs_get_enumvals(pref); enums->name; enums++)
+ {
+ json_dumper_begin_object(&dumper);
+
+ sharkd_json_value_anyf("v", "%d", enums->value);
+
+ if (enums->value == prefs_get_enum_value(pref, pref_current))
+ sharkd_json_value_anyf("s", "1");
+
+ sharkd_json_value_string("d", enums->description);
+
+ json_dumper_end_object(&dumper);
+ }
+ sharkd_json_array_close();
+ break;
+ }
+
+ case PREF_RANGE:
+ case PREF_DECODE_AS_RANGE:
+ {
+ char *range_str = range_convert_range(NULL, prefs_get_range_value_real(pref, pref_current));
+ sharkd_json_value_string("r", range_str);
+ wmem_free(NULL, range_str);
+ break;
+ }
+
+ case PREF_UAT:
+ {
+ uat_t *uat = prefs_get_uat_value(pref);
+ guint idx;
+
+ sharkd_json_array_open("t");
+ for (idx = 0; idx < uat->raw_data->len; idx++)
+ {
+ void *rec = UAT_INDEX_PTR(uat, idx);
+ guint colnum;
+
+ sharkd_json_array_open(NULL);
+ for (colnum = 0; colnum < uat->ncols; colnum++)
+ {
+ char *str = uat_fld_tostr(rec, &(uat->fields[colnum]));
+
+ sharkd_json_value_string(NULL, str);
+ g_free(str);
+ }
+
+ sharkd_json_array_close();
+ }
+
+ sharkd_json_array_close();
+ break;
+ }
+
+ case PREF_COLOR:
+ case PREF_CUSTOM:
+ case PREF_STATIC_TEXT:
+ case PREF_OBSOLETE:
+ /* TODO */
+ break;
+ }
#if 0
- sharkd_json_value_string("t", prefs_get_title(pref));
+ sharkd_json_value_string("t", prefs_get_title(pref));
#endif
- json_dumper_end_object(&dumper);
+ json_dumper_end_object(&dumper);
- return 0; /* continue */
+ return 0; /* continue */
}
static guint
sharkd_session_process_dumpconf_mod_cb(module_t *module, gpointer d)
{
- struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;
+ struct sharkd_session_process_dumpconf_data *data = (struct sharkd_session_process_dumpconf_data *) d;
- data->module = module;
- prefs_pref_foreach(module, sharkd_session_process_dumpconf_cb, data);
+ data->module = module;
+ prefs_pref_foreach(module, sharkd_session_process_dumpconf_cb, data);
- return 0;
+ return 0;
}
/**
@@ -4567,266 +4567,266 @@ sharkd_session_process_dumpconf_mod_cb(module_t *module, gpointer d)
static void
sharkd_session_process_dumpconf(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_pref = json_find_attr(buf, tokens, count, "pref");
- module_t *pref_mod;
- char *dot_sepa;
-
- if (!tok_pref)
- {
- struct sharkd_session_process_dumpconf_data data;
-
- data.module = NULL;
-
- sharkd_json_result_prologue(rpcid);
-
- sharkd_json_value_anyf("prefs", NULL);
- json_dumper_begin_object(&dumper);
- prefs_modules_foreach(sharkd_session_process_dumpconf_mod_cb, &data);
- json_dumper_end_object(&dumper);
-
- sharkd_json_result_epilogue();
- return;
- }
-
- if ((dot_sepa = strchr(tok_pref, '.')))
- {
- pref_t *pref = NULL;
-
- *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */
- pref_mod = prefs_find_module(tok_pref);
- if (pref_mod)
- pref = prefs_find_preference(pref_mod, dot_sepa + 1);
- *dot_sepa = '.';
-
- if (pref)
- {
- struct sharkd_session_process_dumpconf_data data;
-
- data.module = pref_mod;
-
- sharkd_json_result_prologue(rpcid);
-
- sharkd_json_value_anyf("prefs", NULL);
- json_dumper_begin_object(&dumper);
- sharkd_session_process_dumpconf_cb(pref, &data);
- json_dumper_end_object(&dumper);
-
- sharkd_json_result_epilogue();
- return;
- }
- else
- {
- sharkd_json_error(
- rpcid, -9001, NULL,
- "Invalid pref %s.", tok_pref
- );
- return;
- }
-
- }
-
- pref_mod = prefs_find_module(tok_pref);
- if (pref_mod)
- {
- struct sharkd_session_process_dumpconf_data data;
-
- data.module = pref_mod;
-
- sharkd_json_result_prologue(rpcid);
-
- sharkd_json_value_anyf("prefs", NULL);
- json_dumper_begin_object(&dumper);
- prefs_pref_foreach(pref_mod, sharkd_session_process_dumpconf_cb, &data);
- json_dumper_end_object(&dumper);
-
- sharkd_json_result_epilogue();
- }
- else
- {
- sharkd_json_error(
- rpcid, -9002, NULL,
- "Invalid pref %s.", tok_pref
- );
- }
+ const char *tok_pref = json_find_attr(buf, tokens, count, "pref");
+ module_t *pref_mod;
+ char *dot_sepa;
+
+ if (!tok_pref)
+ {
+ struct sharkd_session_process_dumpconf_data data;
+
+ data.module = NULL;
+
+ sharkd_json_result_prologue(rpcid);
+
+ sharkd_json_value_anyf("prefs", NULL);
+ json_dumper_begin_object(&dumper);
+ prefs_modules_foreach(sharkd_session_process_dumpconf_mod_cb, &data);
+ json_dumper_end_object(&dumper);
+
+ sharkd_json_result_epilogue();
+ return;
+ }
+
+ if ((dot_sepa = strchr(tok_pref, '.')))
+ {
+ pref_t *pref = NULL;
+
+ *dot_sepa = '\0'; /* XXX, C abuse: discarding-const */
+ pref_mod = prefs_find_module(tok_pref);
+ if (pref_mod)
+ pref = prefs_find_preference(pref_mod, dot_sepa + 1);
+ *dot_sepa = '.';
+
+ if (pref)
+ {
+ struct sharkd_session_process_dumpconf_data data;
+
+ data.module = pref_mod;
+
+ sharkd_json_result_prologue(rpcid);
+
+ sharkd_json_value_anyf("prefs", NULL);
+ json_dumper_begin_object(&dumper);
+ sharkd_session_process_dumpconf_cb(pref, &data);
+ json_dumper_end_object(&dumper);
+
+ sharkd_json_result_epilogue();
+ return;
+ }
+ else
+ {
+ sharkd_json_error(
+ rpcid, -9001, NULL,
+ "Invalid pref %s.", tok_pref
+ );
+ return;
+ }
+
+ }
+
+ pref_mod = prefs_find_module(tok_pref);
+ if (pref_mod)
+ {
+ struct sharkd_session_process_dumpconf_data data;
+
+ data.module = pref_mod;
+
+ sharkd_json_result_prologue(rpcid);
+
+ sharkd_json_value_anyf("prefs", NULL);
+ json_dumper_begin_object(&dumper);
+ prefs_pref_foreach(pref_mod, sharkd_session_process_dumpconf_cb, &data);
+ json_dumper_end_object(&dumper);
+
+ sharkd_json_result_epilogue();
+ }
+ else
+ {
+ sharkd_json_error(
+ rpcid, -9002, NULL,
+ "Invalid pref %s.", tok_pref
+ );
+ }
}
struct sharkd_download_rtp
{
- rtpstream_id_t id;
- GSList *packets;
- double start_time;
+ rtpstream_id_t id;
+ GSList *packets;
+ double start_time;
};
static void
sharkd_rtp_download_free_items(void *ptr)
{
- rtp_packet_t *rtp_packet = (rtp_packet_t *) ptr;
+ rtp_packet_t *rtp_packet = (rtp_packet_t *) ptr;
- g_free(rtp_packet->info);
- g_free(rtp_packet->payload_data);
- g_free(rtp_packet);
+ g_free(rtp_packet->info);
+ g_free(rtp_packet->payload_data);
+ g_free(rtp_packet);
}
static void
sharkd_rtp_download_decode(struct sharkd_download_rtp *req)
{
- /* based on RtpAudioStream::decode() 6e29d874f8b5e6ebc59f661a0bb0dab8e56f122a */
- /* TODO, for now only without silence (timing_mode_ = Uninterrupted) */
-
- static const int sample_bytes_ = sizeof(SAMPLE) / sizeof(char);
-
- guint32 audio_out_rate_ = 0;
- struct _GHashTable *decoders_hash_ = rtp_decoder_hash_table_new();
- struct SpeexResamplerState_ *audio_resampler_ = NULL;
-
- gsize resample_buff_len = 0x1000;
- SAMPLE *resample_buff = (SAMPLE *) g_malloc(resample_buff_len);
- spx_uint32_t cur_in_rate = 0;
- char *write_buff = NULL;
- size_t write_bytes = 0;
- unsigned channels = 0;
- unsigned sample_rate = 0;
-
- GSList *l;
-
- for (l = req->packets; l; l = l->next)
- {
- rtp_packet_t *rtp_packet = (rtp_packet_t *) l->data;
-
- SAMPLE *decode_buff = NULL;
- size_t decoded_bytes;
-
- decoded_bytes = decode_rtp_packet(rtp_packet, &decode_buff, decoders_hash_, &channels, &sample_rate);
- if (decoded_bytes == 0 || sample_rate == 0)
- {
- /* We didn't decode anything. Clean up and prep for the next packet. */
- g_free(decode_buff);
- continue;
- }
-
- if (audio_out_rate_ == 0)
- {
- guint32 tmp32;
- guint16 tmp16;
- char wav_hdr[44];
-
- /* First non-zero wins */
- audio_out_rate_ = sample_rate;
-
- RTP_STREAM_DEBUG("Audio sample rate is %u", audio_out_rate_);
-
- /* write WAVE header */
- memset(&wav_hdr, 0, sizeof(wav_hdr));
- memcpy(&wav_hdr[0], "RIFF", 4);
- memcpy(&wav_hdr[4], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */
- memcpy(&wav_hdr[8], "WAVE", 4);
-
- memcpy(&wav_hdr[12], "fmt ", 4);
- memcpy(&wav_hdr[16], "\x10\x00\x00\x00", 4); /* PCM */
- memcpy(&wav_hdr[20], "\x01\x00", 2); /* PCM */
- /* # channels */
- tmp16 = channels;
- memcpy(&wav_hdr[22], &tmp16, 2);
- /* sample rate */
- tmp32 = sample_rate;
- memcpy(&wav_hdr[24], &tmp32, 4);
- /* byte rate */
- tmp32 = sample_rate * channels * sample_bytes_;
- memcpy(&wav_hdr[28], &tmp32, 4);
- /* block align */
- tmp16 = channels * sample_bytes_;
- memcpy(&wav_hdr[32], &tmp16, 2);
- /* bits per sample */
- tmp16 = 8 * sample_bytes_;
- memcpy(&wav_hdr[34], &tmp16, 2);
-
- memcpy(&wav_hdr[36], "data", 4);
- memcpy(&wav_hdr[40], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */
-
- json_dumper_write_base64(&dumper, wav_hdr, sizeof(wav_hdr));
- }
-
- // Write samples to our file.
- write_buff = (char *) decode_buff;
- write_bytes = decoded_bytes;
-
- if (audio_out_rate_ != sample_rate)
- {
- spx_uint32_t in_len, out_len;
-
- /* Resample the audio to match our previous output rate. */
- if (!audio_resampler_)
- {
- audio_resampler_ = speex_resampler_init(1, sample_rate, audio_out_rate_, 10, NULL);
- speex_resampler_skip_zeros(audio_resampler_);
- RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, audio_out_rate_);
- }
- else
- {
- spx_uint32_t audio_out_rate;
- speex_resampler_get_rate(audio_resampler_, &cur_in_rate, &audio_out_rate);
-
- if (sample_rate != cur_in_rate)
- {
- speex_resampler_set_rate(audio_resampler_, sample_rate, audio_out_rate);
- RTP_STREAM_DEBUG("Changed input rate from %u to %u Hz. Out is %u.", cur_in_rate, sample_rate, audio_out_rate_);
- }
- }
- in_len = (spx_uint32_t)rtp_packet->info->info_payload_len;
- out_len = (audio_out_rate_ * (spx_uint32_t)rtp_packet->info->info_payload_len / sample_rate) + (audio_out_rate_ % sample_rate != 0);
- if (out_len * sample_bytes_ > resample_buff_len)
- {
- while ((out_len * sample_bytes_ > resample_buff_len))
- resample_buff_len *= 2;
- resample_buff = (SAMPLE *) g_realloc(resample_buff, resample_buff_len);
- }
-
- speex_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len);
- write_buff = (char *) resample_buff;
- write_bytes = out_len * sample_bytes_;
- }
-
- /* Write the decoded, possibly-resampled audio */
- json_dumper_write_base64(&dumper, write_buff, write_bytes);
-
- g_free(decode_buff);
- }
-
- g_free(resample_buff);
- g_hash_table_destroy(decoders_hash_);
+ /* based on RtpAudioStream::decode() 6e29d874f8b5e6ebc59f661a0bb0dab8e56f122a */
+ /* TODO, for now only without silence (timing_mode_ = Uninterrupted) */
+
+ static const int sample_bytes_ = sizeof(SAMPLE) / sizeof(char);
+
+ guint32 audio_out_rate_ = 0;
+ struct _GHashTable *decoders_hash_ = rtp_decoder_hash_table_new();
+ struct SpeexResamplerState_ *audio_resampler_ = NULL;
+
+ gsize resample_buff_len = 0x1000;
+ SAMPLE *resample_buff = (SAMPLE *) g_malloc(resample_buff_len);
+ spx_uint32_t cur_in_rate = 0;
+ char *write_buff = NULL;
+ size_t write_bytes = 0;
+ unsigned channels = 0;
+ unsigned sample_rate = 0;
+
+ GSList *l;
+
+ for (l = req->packets; l; l = l->next)
+ {
+ rtp_packet_t *rtp_packet = (rtp_packet_t *) l->data;
+
+ SAMPLE *decode_buff = NULL;
+ size_t decoded_bytes;
+
+ decoded_bytes = decode_rtp_packet(rtp_packet, &decode_buff, decoders_hash_, &channels, &sample_rate);
+ if (decoded_bytes == 0 || sample_rate == 0)
+ {
+ /* We didn't decode anything. Clean up and prep for the next packet. */
+ g_free(decode_buff);
+ continue;
+ }
+
+ if (audio_out_rate_ == 0)
+ {
+ guint32 tmp32;
+ guint16 tmp16;
+ char wav_hdr[44];
+
+ /* First non-zero wins */
+ audio_out_rate_ = sample_rate;
+
+ RTP_STREAM_DEBUG("Audio sample rate is %u", audio_out_rate_);
+
+ /* write WAVE header */
+ memset(&wav_hdr, 0, sizeof(wav_hdr));
+ memcpy(&wav_hdr[0], "RIFF", 4);
+ memcpy(&wav_hdr[4], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */
+ memcpy(&wav_hdr[8], "WAVE", 4);
+
+ memcpy(&wav_hdr[12], "fmt ", 4);
+ memcpy(&wav_hdr[16], "\x10\x00\x00\x00", 4); /* PCM */
+ memcpy(&wav_hdr[20], "\x01\x00", 2); /* PCM */
+ /* # channels */
+ tmp16 = channels;
+ memcpy(&wav_hdr[22], &tmp16, 2);
+ /* sample rate */
+ tmp32 = sample_rate;
+ memcpy(&wav_hdr[24], &tmp32, 4);
+ /* byte rate */
+ tmp32 = sample_rate * channels * sample_bytes_;
+ memcpy(&wav_hdr[28], &tmp32, 4);
+ /* block align */
+ tmp16 = channels * sample_bytes_;
+ memcpy(&wav_hdr[32], &tmp16, 2);
+ /* bits per sample */
+ tmp16 = 8 * sample_bytes_;
+ memcpy(&wav_hdr[34], &tmp16, 2);
+
+ memcpy(&wav_hdr[36], "data", 4);
+ memcpy(&wav_hdr[40], "\xFF\xFF\xFF\xFF", 4); /* XXX, unknown */
+
+ json_dumper_write_base64(&dumper, wav_hdr, sizeof(wav_hdr));
+ }
+
+ // Write samples to our file.
+ write_buff = (char *) decode_buff;
+ write_bytes = decoded_bytes;
+
+ if (audio_out_rate_ != sample_rate)
+ {
+ spx_uint32_t in_len, out_len;
+
+ /* Resample the audio to match our previous output rate. */
+ if (!audio_resampler_)
+ {
+ audio_resampler_ = speex_resampler_init(1, sample_rate, audio_out_rate_, 10, NULL);
+ speex_resampler_skip_zeros(audio_resampler_);
+ RTP_STREAM_DEBUG("Started resampling from %u to (out) %u Hz.", sample_rate, audio_out_rate_);
+ }
+ else
+ {
+ spx_uint32_t audio_out_rate;
+ speex_resampler_get_rate(audio_resampler_, &cur_in_rate, &audio_out_rate);
+
+ if (sample_rate != cur_in_rate)
+ {
+ speex_resampler_set_rate(audio_resampler_, sample_rate, audio_out_rate);
+ RTP_STREAM_DEBUG("Changed input rate from %u to %u Hz. Out is %u.", cur_in_rate, sample_rate, audio_out_rate_);
+ }
+ }
+ in_len = (spx_uint32_t)rtp_packet->info->info_payload_len;
+ out_len = (audio_out_rate_ * (spx_uint32_t)rtp_packet->info->info_payload_len / sample_rate) + (audio_out_rate_ % sample_rate != 0);
+ if (out_len * sample_bytes_ > resample_buff_len)
+ {
+ while ((out_len * sample_bytes_ > resample_buff_len))
+ resample_buff_len *= 2;
+ resample_buff = (SAMPLE *) g_realloc(resample_buff, resample_buff_len);
+ }
+
+ speex_resampler_process_int(audio_resampler_, 0, decode_buff, &in_len, resample_buff, &out_len);
+ write_buff = (char *) resample_buff;
+ write_bytes = out_len * sample_bytes_;
+ }
+
+ /* Write the decoded, possibly-resampled audio */
+ json_dumper_write_base64(&dumper, write_buff, write_bytes);
+
+ g_free(decode_buff);
+ }
+
+ g_free(resample_buff);
+ g_hash_table_destroy(decoders_hash_);
}
static tap_packet_status
sharkd_session_packet_download_tap_rtp_cb(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
{
- const struct _rtp_info *rtp_info = (const struct _rtp_info *) data;
- struct sharkd_download_rtp *req_rtp = (struct sharkd_download_rtp *) tapdata;
+ const struct _rtp_info *rtp_info = (const struct _rtp_info *) data;
+ struct sharkd_download_rtp *req_rtp = (struct sharkd_download_rtp *) tapdata;
- /* do not consider RTP packets without a setup frame */
- if (rtp_info->info_setup_frame_num == 0)
- return TAP_PACKET_DONT_REDRAW;
+ /* do not consider RTP packets without a setup frame */
+ if (rtp_info->info_setup_frame_num == 0)
+ return TAP_PACKET_DONT_REDRAW;
- if (rtpstream_id_equal_pinfo_rtp_info(&req_rtp->id, pinfo, rtp_info))
- {
- rtp_packet_t *rtp_packet;
+ if (rtpstream_id_equal_pinfo_rtp_info(&req_rtp->id, pinfo, rtp_info))
+ {
+ rtp_packet_t *rtp_packet;
- rtp_packet = g_new0(rtp_packet_t, 1);
- rtp_packet->info = (struct _rtp_info *) g_memdup2(rtp_info, sizeof(struct _rtp_info));
+ rtp_packet = g_new0(rtp_packet_t, 1);
+ rtp_packet->info = (struct _rtp_info *) g_memdup2(rtp_info, sizeof(struct _rtp_info));
- if (rtp_info->info_all_data_present && rtp_info->info_payload_len != 0)
- rtp_packet->payload_data = (guint8 *) g_memdup2(&(rtp_info->info_data[rtp_info->info_payload_offset]), rtp_info->info_payload_len);
+ if (rtp_info->info_all_data_present && rtp_info->info_payload_len != 0)
+ rtp_packet->payload_data = (guint8 *) g_memdup2(&(rtp_info->info_data[rtp_info->info_payload_offset]), rtp_info->info_payload_len);
- if (!req_rtp->packets)
- req_rtp->start_time = nstime_to_sec(&pinfo->abs_ts);
+ if (!req_rtp->packets)
+ req_rtp->start_time = nstime_to_sec(&pinfo->abs_ts);
- rtp_packet->frame_num = pinfo->num;
- rtp_packet->arrive_offset = nstime_to_sec(&pinfo->abs_ts) - req_rtp->start_time;
+ rtp_packet->frame_num = pinfo->num;
+ rtp_packet->arrive_offset = nstime_to_sec(&pinfo->abs_ts) - req_rtp->start_time;
- /* XXX, O(n) optimize */
- req_rtp->packets = g_slist_append(req_rtp->packets, rtp_packet);
- }
+ /* XXX, O(n) optimize */
+ req_rtp->packets = g_slist_append(req_rtp->packets, rtp_packet);
+ }
- return TAP_PACKET_DONT_REDRAW;
+ return TAP_PACKET_DONT_REDRAW;
}
/**
@@ -4845,257 +4845,244 @@ sharkd_session_packet_download_tap_rtp_cb(void *tapdata, packet_info *pinfo, epa
static void
sharkd_session_process_download(char *buf, const jsmntok_t *tokens, int count)
{
- const char *tok_token = json_find_attr(buf, tokens, count, "token");
-
- if (!tok_token)
- return;
-
- if (!strncmp(tok_token, "eo:", 3))
- {
- struct sharkd_export_object_list *object_list;
- const export_object_entry_t *eo_entry = NULL;
-
- for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)
- {
- size_t eo_type_len = strlen(object_list->type);
-
- if (!strncmp(tok_token, object_list->type, eo_type_len) && tok_token[eo_type_len] == '_')
- {
- int row;
-
- if (sscanf(&tok_token[eo_type_len + 1], "%d", &row) != 1)
- break;
-
- eo_entry = (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);
- break;
- }
- }
-
- if (eo_entry)
- {
- const char *mime = (eo_entry->content_type) ? eo_entry->content_type : "application/octet-stream";
- const char *filename = (eo_entry->filename) ? eo_entry->filename : tok_token;
-
- sharkd_json_result_prologue(rpcid);
- sharkd_json_value_string("file", filename);
- sharkd_json_value_string("mime", mime);
- sharkd_json_value_base64("data", eo_entry->payload_data, eo_entry->payload_len);
- sharkd_json_result_epilogue();
- }
- else
- {
- sharkd_json_result_prologue(rpcid);
- sharkd_json_result_epilogue();
- }
- }
- else if (!strcmp(tok_token, "ssl-secrets"))
- {
- gsize str_len;
- char *str = ssl_export_sessions(&str_len);
-
- if (str)
- {
- const char *mime = "text/plain";
- const char *filename = "keylog.txt";
-
- sharkd_json_result_prologue(rpcid);
- sharkd_json_value_string("file", filename);
- sharkd_json_value_string("mime", mime);
- sharkd_json_value_base64("data", str, str_len);
- sharkd_json_result_epilogue();
- }
- g_free(str);
- }
- else if (!strncmp(tok_token, "rtp:", 4))
- {
- struct sharkd_download_rtp rtp_req;
- GString *tap_error;
-
- memset(&rtp_req, 0, sizeof(rtp_req));
- if (!sharkd_rtp_match_init(&rtp_req.id, tok_token + 4))
- {
- sharkd_json_error(
- rpcid, -10001, NULL,
- "sharkd_session_process_download() rtp tokenizing error %s", tok_token
- );
- return;
- }
-
- tap_error = register_tap_listener("rtp", &rtp_req, NULL, 0, NULL, sharkd_session_packet_download_tap_rtp_cb, NULL, NULL);
- if (tap_error)
- {
- sharkd_json_error(
- rpcid, -10002, NULL,
- "sharkd_session_process_download() rtp error %s", tap_error->str
- );
- g_string_free(tap_error, TRUE);
- return;
- }
-
- sharkd_retap();
- remove_tap_listener(&rtp_req);
-
- if (rtp_req.packets)
- {
- const char *mime = "audio/x-wav";
- const char *filename = tok_token;
-
- sharkd_json_result_prologue(rpcid);
- sharkd_json_value_string("file", filename);
- sharkd_json_value_string("mime", mime);
-
- sharkd_json_value_anyf("data", NULL);
- json_dumper_begin_base64(&dumper);
- sharkd_rtp_download_decode(&rtp_req);
- json_dumper_end_base64(&dumper);
-
- sharkd_json_result_epilogue();
-
- g_slist_free_full(rtp_req.packets, sharkd_rtp_download_free_items);
- }
- }
+ const char *tok_token = json_find_attr(buf, tokens, count, "token");
+
+ if (!tok_token)
+ return;
+
+ if (!strncmp(tok_token, "eo:", 3))
+ {
+ struct sharkd_export_object_list *object_list;
+ const export_object_entry_t *eo_entry = NULL;
+
+ for (object_list = sharkd_eo_list; object_list; object_list = object_list->next)
+ {
+ size_t eo_type_len = strlen(object_list->type);
+
+ if (!strncmp(tok_token, object_list->type, eo_type_len) && tok_token[eo_type_len] == '_')
+ {
+ int row;
+
+ if (sscanf(&tok_token[eo_type_len + 1], "%d", &row) != 1)
+ break;
+
+ eo_entry = (export_object_entry_t *) g_slist_nth_data(object_list->entries, row);
+ break;
+ }
+ }
+
+ if (eo_entry)
+ {
+ const char *mime = (eo_entry->content_type) ? eo_entry->content_type : "application/octet-stream";
+ const char *filename = (eo_entry->filename) ? eo_entry->filename : tok_token;
+
+ sharkd_json_result_prologue(rpcid);
+ sharkd_json_value_string("file", filename);
+ sharkd_json_value_string("mime", mime);
+ sharkd_json_value_base64("data", eo_entry->payload_data, eo_entry->payload_len);
+ sharkd_json_result_epilogue();
+ }
+ else
+ {
+ sharkd_json_result_prologue(rpcid);
+ sharkd_json_result_epilogue();
+ }
+ }
+ else if (!strcmp(tok_token, "ssl-secrets"))
+ {
+ gsize str_len;
+ char *str = ssl_export_sessions(&str_len);
+
+ if (str)
+ {
+ const char *mime = "text/plain";
+ const char *filename = "keylog.txt";
+
+ sharkd_json_result_prologue(rpcid);
+ sharkd_json_value_string("file", filename);
+ sharkd_json_value_string("mime", mime);
+ sharkd_json_value_base64("data", str, str_len);
+ sharkd_json_result_epilogue();
+ }
+ g_free(str);
+ }
+ else if (!strncmp(tok_token, "rtp:", 4))
+ {
+ struct sharkd_download_rtp rtp_req;
+ GString *tap_error;
+
+ memset(&rtp_req, 0, sizeof(rtp_req));
+ if (!sharkd_rtp_match_init(&rtp_req.id, tok_token + 4))
+ {
+ sharkd_json_error(
+ rpcid, -10001, NULL,
+ "sharkd_session_process_download() rtp tokenizing error %s", tok_token
+ );
+ return;
+ }
+
+ tap_error = register_tap_listener("rtp", &rtp_req, NULL, 0, NULL, sharkd_session_packet_download_tap_rtp_cb, NULL, NULL);
+ if (tap_error)
+ {
+ sharkd_json_error(
+ rpcid, -10002, NULL,
+ "sharkd_session_process_download() rtp error %s", tap_error->str
+ );
+ g_string_free(tap_error, TRUE);
+ return;
+ }
+
+ sharkd_retap();
+ remove_tap_listener(&rtp_req);
+
+ if (rtp_req.packets)
+ {
+ const char *mime = "audio/x-wav";
+ const char *filename = tok_token;
+
+ sharkd_json_result_prologue(rpcid);
+ sharkd_json_value_string("file", filename);
+ sharkd_json_value_string("mime", mime);
+
+ sharkd_json_value_anyf("data", NULL);
+ json_dumper_begin_base64(&dumper);
+ sharkd_rtp_download_decode(&rtp_req);
+ json_dumper_end_base64(&dumper);
+
+ sharkd_json_result_epilogue();
+
+ g_slist_free_full(rtp_req.packets, sharkd_rtp_download_free_items);
+ }
+ }
}
static void
sharkd_session_process(char *buf, const jsmntok_t *tokens, int count)
{
- if (json_prep(buf, tokens, count))
- {
- /* don't need [0] token */
- tokens++;
- count--;
-
- const char* tok_method = json_find_attr(buf, tokens, count, "method");
-
- if (!tok_method) {
- sharkd_json_error(
- rpcid, -32601, NULL,
- "No method found");
- return;
- }
- if (!strcmp(tok_method, "load"))
- sharkd_session_process_load(buf, tokens, count);
- else if (!strcmp(tok_method, "status"))
- sharkd_session_process_status();
- else if (!strcmp(tok_method, "analyse"))
- sharkd_session_process_analyse();
- else if (!strcmp(tok_method, "info"))
- sharkd_session_process_info();
- else if (!strcmp(tok_method, "check"))
- sharkd_session_process_check(buf, tokens, count);
- else if (!strcmp(tok_method, "complete"))
- sharkd_session_process_complete(buf, tokens, count);
- else if (!strcmp(tok_method, "frames"))
- sharkd_session_process_frames(buf, tokens, count);
- else if (!strcmp(tok_method, "tap"))
- sharkd_session_process_tap(buf, tokens, count);
- else if (!strcmp(tok_method, "follow"))
- sharkd_session_process_follow(buf, tokens, count);
- else if (!strcmp(tok_method, "iograph"))
- sharkd_session_process_iograph(buf, tokens, count);
- else if (!strcmp(tok_method, "intervals"))
- sharkd_session_process_intervals(buf, tokens, count);
- else if (!strcmp(tok_method, "frame"))
- sharkd_session_process_frame(buf, tokens, count);
- else if (!strcmp(tok_method, "setcomment"))
- sharkd_session_process_setcomment(buf, tokens, count);
- else if (!strcmp(tok_method, "setconf"))
- sharkd_session_process_setconf(buf, tokens, count);
- else if (!strcmp(tok_method, "dumpconf"))
- sharkd_session_process_dumpconf(buf, tokens, count);
- else if (!strcmp(tok_method, "download"))
- sharkd_session_process_download(buf, tokens, count);
- else if (!strcmp(tok_method, "bye"))
- {
- sharkd_json_simple_ok(rpcid);
- exit(0);
- }
- else
- {
- sharkd_json_error(
- rpcid, -32601, NULL,
- "The method \"%s\" is unknown", tok_method
- );
- }
- }
+ if (json_prep(buf, tokens, count))
+ {
+ /* don't need [0] token */
+ tokens++;
+ count--;
+
+ const char* tok_method = json_find_attr(buf, tokens, count, "method");
+
+ if (!tok_method) {
+ sharkd_json_error(
+ rpcid, -32601, NULL,
+ "No method found");
+ return;
+ }
+ if (!strcmp(tok_method, "load"))
+ sharkd_session_process_load(buf, tokens, count);
+ else if (!strcmp(tok_method, "status"))
+ sharkd_session_process_status();
+ else if (!strcmp(tok_method, "analyse"))
+ sharkd_session_process_analyse();
+ else if (!strcmp(tok_method, "info"))
+ sharkd_session_process_info();
+ else if (!strcmp(tok_method, "check"))
+ sharkd_session_process_check(buf, tokens, count);
+ else if (!strcmp(tok_method, "complete"))
+ sharkd_session_process_complete(buf, tokens, count);
+ else if (!strcmp(tok_method, "frames"))
+ sharkd_session_process_frames(buf, tokens, count);
+ else if (!strcmp(tok_method, "tap"))
+ sharkd_session_process_tap(buf, tokens, count);
+ else if (!strcmp(tok_method, "follow"))
+ sharkd_session_process_follow(buf, tokens, count);
+ else if (!strcmp(tok_method, "iograph"))
+ sharkd_session_process_iograph(buf, tokens, count);
+ else if (!strcmp(tok_method, "intervals"))
+ sharkd_session_process_intervals(buf, tokens, count);
+ else if (!strcmp(tok_method, "frame"))
+ sharkd_session_process_frame(buf, tokens, count);
+ else if (!strcmp(tok_method, "setcomment"))
+ sharkd_session_process_setcomment(buf, tokens, count);
+ else if (!strcmp(tok_method, "setconf"))
+ sharkd_session_process_setconf(buf, tokens, count);
+ else if (!strcmp(tok_method, "dumpconf"))
+ sharkd_session_process_dumpconf(buf, tokens, count);
+ else if (!strcmp(tok_method, "download"))
+ sharkd_session_process_download(buf, tokens, count);
+ else if (!strcmp(tok_method, "bye"))
+ {
+ sharkd_json_simple_ok(rpcid);
+ exit(0);
+ }
+ else
+ {
+ sharkd_json_error(
+ rpcid, -32601, NULL,
+ "The method \"%s\" is unknown", tok_method
+ );
+ }
+ }
}
int
sharkd_session_main(int mode_setting)
{
- char buf[2 * 1024];
- jsmntok_t *tokens = NULL;
- int tokens_max = -1;
+ char buf[2 * 1024];
+ jsmntok_t *tokens = NULL;
+ int tokens_max = -1;
- mode = mode_setting;
+ mode = mode_setting;
- fprintf(stderr, "Hello in child.\n");
+ fprintf(stderr, "Hello in child.\n");
- dumper.output_file = stdout;
+ dumper.output_file = stdout;
- filter_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, sharkd_session_filter_free);
+ filter_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, sharkd_session_filter_free);
#ifdef HAVE_MAXMINDDB
- /* mmdbresolve was stopped before fork(), force starting it */
- uat_get_table_by_name("MaxMind Database Paths")->post_update_cb();
+ /* mmdbresolve was stopped before fork(), force starting it */
+ uat_get_table_by_name("MaxMind Database Paths")->post_update_cb();
#endif
- while (fgets(buf, sizeof(buf), stdin))
- {
- /* every command is line seperated JSON */
- int ret;
-
- ret = json_parse(buf, NULL, 0);
- if (ret <= 0)
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "Invalid JSON(1)"
- );
- continue;
- }
-
- /* fprintf(stderr, "JSON: %d tokens\n", ret); */
- ret += 1;
-
- if (tokens == NULL || tokens_max < ret)
- {
- tokens_max = ret;
- tokens = (jsmntok_t *) g_realloc(tokens, sizeof(jsmntok_t) * tokens_max);
- }
-
- memset(tokens, 0, ret * sizeof(jsmntok_t));
-
- ret = json_parse(buf, tokens, ret);
- if (ret <= 0)
- {
- sharkd_json_error(
- rpcid, -32600, NULL,
- "Invalid JSON(2)"
- );
- continue;
- }
-
- host_name_lookup_process();
-
- sharkd_session_process(buf, tokens, ret);
- }
-
- g_hash_table_destroy(filter_table);
- g_free(tokens);
-
- return 0;
+ while (fgets(buf, sizeof(buf), stdin))
+ {
+ /* every command is line seperated JSON */
+ int ret;
+
+ ret = json_parse(buf, NULL, 0);
+ if (ret <= 0)
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "Invalid JSON(1)"
+ );
+ continue;
+ }
+
+ /* fprintf(stderr, "JSON: %d tokens\n", ret); */
+ ret += 1;
+
+ if (tokens == NULL || tokens_max < ret)
+ {
+ tokens_max = ret;
+ tokens = (jsmntok_t *) g_realloc(tokens, sizeof(jsmntok_t) * tokens_max);
+ }
+
+ memset(tokens, 0, ret * sizeof(jsmntok_t));
+
+ ret = json_parse(buf, tokens, ret);
+ if (ret <= 0)
+ {
+ sharkd_json_error(
+ rpcid, -32600, NULL,
+ "Invalid JSON(2)"
+ );
+ continue;
+ }
+
+ host_name_lookup_process();
+
+ sharkd_session_process(buf, tokens, ret);
+ }
+
+ g_hash_table_destroy(filter_table);
+ g_free(tokens);
+
+ 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:
- */
diff --git a/tfshark.c b/tfshark.c
index 701f702ce0..1d8a6c8a2f 100644
--- a/tfshark.c
+++ b/tfshark.c
@@ -91,10 +91,10 @@ static gboolean perform_two_pass_analysis;
* The way the packet decode is to be written.
*/
typedef enum {
- WRITE_TEXT, /* summary or detail text */
- WRITE_XML, /* PDML or PSML */
- WRITE_FIELDS /* User defined list of fields */
- /* Add CSV and the like here */
+ WRITE_TEXT, /* summary or detail text */
+ WRITE_XML, /* PDML or PSML */
+ WRITE_FIELDS /* User defined list of fields */
+ /* Add CSV and the like here */
} output_action_e;
static output_action_e output_action;
@@ -116,14 +116,14 @@ static const char *separator = "";
static gboolean process_file(capture_file *, int, gint64);
static gboolean process_packet_single_pass(capture_file *cf,
- epan_dissect_t *edt, gint64 offset, wtap_rec *rec,
- const guchar *pd, guint tap_flags);
+ epan_dissect_t *edt, gint64 offset, wtap_rec *rec,
+ const guchar *pd, guint tap_flags);
static void show_print_file_io_error(int err);
static gboolean write_preamble(capture_file *cf);
static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
static gboolean write_finale(void);
static const char *cf_open_error_message(int err, gchar *err_info,
- gboolean for_writing, int file_type);
+ gboolean for_writing, int file_type);
static void tfshark_cmdarg_err(const char *msg_format, va_list ap);
static void tfshark_cmdarg_err_cont(const char *msg_format, va_list ap);
@@ -132,852 +132,854 @@ static GHashTable *output_only_tables = NULL;
#if 0
struct string_elem {
- const char *sstr; /* The short string */
- const char *lstr; /* The long string */
+ const char *sstr; /* The short string */
+ const char *lstr; /* The long string */
};
static gint
string_compare(gconstpointer a, gconstpointer b)
{
- return strcmp(((const struct string_elem *)a)->sstr,
- ((const struct string_elem *)b)->sstr);
+ return strcmp(((const struct string_elem *)a)->sstr,
+ ((const struct string_elem *)b)->sstr);
}
static void
string_elem_print(gpointer data, gpointer not_used _U_)
{
- fprintf(stderr, " %s - %s\n",
- ((struct string_elem *)data)->sstr,
- ((struct string_elem *)data)->lstr);
+ fprintf(stderr, " %s - %s\n",
+ ((struct string_elem *)data)->sstr,
+ ((struct string_elem *)data)->lstr);
}
#endif
static void
print_usage(FILE *output)
{
- fprintf(output, "\n");
- fprintf(output, "Usage: tfshark [options] ...\n");
- fprintf(output, "\n");
-
- /*fprintf(output, "\n");*/
- fprintf(output, "Input file:\n");
- fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin)\n");
-
- fprintf(output, "\n");
- fprintf(output, "Processing:\n");
- fprintf(output, " -2 perform a two-pass analysis\n");
- fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
- fprintf(output, " (requires -2)\n");
- fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
- fprintf(output, " syntax\n");
- fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
- fprintf(output, " \"Decode As\", see the man page for details\n");
- fprintf(output, " Example: tcp.port==8888,http\n");
-
- /*fprintf(output, "\n");*/
- fprintf(output, "Output:\n");
- fprintf(output, " -C <config profile> start with specified configuration profile\n");
- fprintf(output, " -V add output of packet tree (Packet Details)\n");
- fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
- fprintf(output, " separated\n");
- fprintf(output, " -S <separator> the line separator to print between packets\n");
- fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
- fprintf(output, " -T pdml|ps|psml|text|fields\n");
- fprintf(output, " format of text output (def: text)\n");
- fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
- fprintf(output, " _ws.col.Info)\n");
- fprintf(output, " this option can be repeated to print multiple fields\n");
- fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
- fprintf(output, " header=y|n switch headers on and off\n");
- fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
- fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
- fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
- fprintf(output, " aggregator\n");
- fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
- fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
- fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
- fprintf(output, " -l flush standard output after each packet\n");
- fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
- fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
- fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
- fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
- fprintf(output, "\n");
-
- ws_log_print_usage(output);
- fprintf(output, "\n");
-
- fprintf(output, "Miscellaneous:\n");
- fprintf(output, " -h display this help and exit\n");
- fprintf(output, " -v display version info and exit\n");
- fprintf(output, " -o <name>:<value> ... override preference setting\n");
- fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
- fprintf(output, " -G [report] dump one of several available reports and exit\n");
- fprintf(output, " default report=\"fields\"\n");
- fprintf(output, " use \"-G ?\" for more help\n");
+ fprintf(output, "\n");
+ fprintf(output, "Usage: tfshark [options] ...\n");
+ fprintf(output, "\n");
+
+ /*fprintf(output, "\n");*/
+ fprintf(output, "Input file:\n");
+ fprintf(output, " -r <infile> set the filename to read from (no pipes or stdin)\n");
+
+ fprintf(output, "\n");
+ fprintf(output, "Processing:\n");
+ fprintf(output, " -2 perform a two-pass analysis\n");
+ fprintf(output, " -R <read filter> packet Read filter in Wireshark display filter syntax\n");
+ fprintf(output, " (requires -2)\n");
+ fprintf(output, " -Y <display filter> packet displaY filter in Wireshark display filter\n");
+ fprintf(output, " syntax\n");
+ fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
+ fprintf(output, " \"Decode As\", see the man page for details\n");
+ fprintf(output, " Example: tcp.port==8888,http\n");
+
+ /*fprintf(output, "\n");*/
+ fprintf(output, "Output:\n");
+ fprintf(output, " -C <config profile> start with specified configuration profile\n");
+ fprintf(output, " -V add output of packet tree (Packet Details)\n");
+ fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
+ fprintf(output, " separated\n");
+ fprintf(output, " -S <separator> the line separator to print between packets\n");
+ fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
+ fprintf(output, " -T pdml|ps|psml|text|fields\n");
+ fprintf(output, " format of text output (def: text)\n");
+ fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
+ fprintf(output, " _ws.col.Info)\n");
+ fprintf(output, " this option can be repeated to print multiple fields\n");
+ fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
+ fprintf(output, " header=y|n switch headers on and off\n");
+ fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
+ fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
+ fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
+ fprintf(output, " aggregator\n");
+ fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
+ fprintf(output, " -t a|ad|d|dd|e|r|u|ud output format of time stamps (def: r: rel. to first)\n");
+ fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
+ fprintf(output, " -l flush standard output after each packet\n");
+ fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
+ fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
+ fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
+ fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
+ fprintf(output, "\n");
+
+ ws_log_print_usage(output);
+ fprintf(output, "\n");
+
+ fprintf(output, "Miscellaneous:\n");
+ fprintf(output, " -h display this help and exit\n");
+ fprintf(output, " -v display version info and exit\n");
+ fprintf(output, " -o <name>:<value> ... override preference setting\n");
+ fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
+ fprintf(output, " -G [report] dump one of several available reports and exit\n");
+ fprintf(output, " default report=\"fields\"\n");
+ fprintf(output, " use \"-G ?\" for more help\n");
}
static void
glossary_option_help(void)
{
- FILE *output;
-
- output = stdout;
-
- fprintf(output, "%s\n", get_appname_and_version());
-
- fprintf(output, "\n");
- fprintf(output, "Usage: tfshark -G [report]\n");
- fprintf(output, "\n");
- fprintf(output, "Glossary table reports:\n");
- fprintf(output, " -G column-formats dump column format codes and exit\n");
- fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
- fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
- fprintf(output, " -G fields dump fields glossary and exit\n");
- fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
- fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
- fprintf(output, " -G plugins dump installed plugins and exit\n");
- fprintf(output, " -G protocols dump protocols in registration database and exit\n");
- fprintf(output, " -G values dump value, range, true/false strings and exit\n");
- fprintf(output, "\n");
- fprintf(output, "Preference reports:\n");
- fprintf(output, " -G currentprefs dump current preferences and exit\n");
- fprintf(output, " -G defaultprefs dump default preferences and exit\n");
- fprintf(output, "\n");
+ FILE *output;
+
+ output = stdout;
+
+ fprintf(output, "%s\n", get_appname_and_version());
+
+ fprintf(output, "\n");
+ fprintf(output, "Usage: tfshark -G [report]\n");
+ fprintf(output, "\n");
+ fprintf(output, "Glossary table reports:\n");
+ fprintf(output, " -G column-formats dump column format codes and exit\n");
+ fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
+ fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
+ fprintf(output, " -G fields dump fields glossary and exit\n");
+ fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
+ fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
+ fprintf(output, " -G plugins dump installed plugins and exit\n");
+ fprintf(output, " -G protocols dump protocols in registration database and exit\n");
+ fprintf(output, " -G values dump value, range, true/false strings and exit\n");
+ fprintf(output, "\n");
+ fprintf(output, "Preference reports:\n");
+ fprintf(output, " -G currentprefs dump current preferences and exit\n");
+ fprintf(output, " -G defaultprefs dump default preferences and exit\n");
+ fprintf(output, "\n");
}
static void
-print_current_user(void) {
- gchar *cur_user, *cur_group;
-
- if (started_with_special_privs()) {
- cur_user = get_cur_username();
- cur_group = get_cur_groupname();
- fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
- cur_user, cur_group);
- g_free(cur_user);
- g_free(cur_group);
- if (running_with_special_privs()) {
- fprintf(stderr, " This could be dangerous.");
+print_current_user(void)
+{
+ gchar *cur_user, *cur_group;
+
+ if (started_with_special_privs()) {
+ cur_user = get_cur_username();
+ cur_group = get_cur_groupname();
+ fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
+ cur_user, cur_group);
+ g_free(cur_user);
+ g_free(cur_group);
+ if (running_with_special_privs()) {
+ fprintf(stderr, " This could be dangerous.");
+ }
+ fprintf(stderr, "\n");
}
- fprintf(stderr, "\n");
- }
}
static void
get_tfshark_runtime_version_info(GString *str)
{
- /* stuff used by libwireshark */
- epan_get_runtime_version_info(str);
+ /* stuff used by libwireshark */
+ epan_get_runtime_version_info(str);
}
int
main(int argc, char *argv[])
{
- char *init_progfile_dir_error;
- 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 arg_error = FALSE;
-
- int err;
- volatile gboolean success;
- volatile int exit_status = 0;
- gboolean quiet = FALSE;
- gchar *volatile cf_name = NULL;
- gchar *rfilter = NULL;
- gchar *dfilter = NULL;
- dfilter_t *rfcode = NULL;
- dfilter_t *dfcode = NULL;
- gchar *err_msg;
- e_prefs *prefs_p;
- gchar *output_only = NULL;
+ char *init_progfile_dir_error;
+ 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 arg_error = FALSE;
+
+ int err;
+ volatile gboolean success;
+ volatile int exit_status = 0;
+ gboolean quiet = FALSE;
+ gchar *volatile cf_name = NULL;
+ gchar *rfilter = NULL;
+ gchar *dfilter = NULL;
+ dfilter_t *rfcode = NULL;
+ dfilter_t *dfcode = NULL;
+ gchar *err_msg;
+ e_prefs *prefs_p;
+ gchar *output_only = NULL;
-/*
- * 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 "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
- static const char optstring[] = OPTSTRING;
- static const struct report_message_routines tfshark_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
- };
-
- /*
- * Set the C-language locale to the native environment and set the
- * code page to UTF-8 on Windows.
- */
+ static const char optstring[] = OPTSTRING;
+ static const struct report_message_routines tfshark_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
+ };
+
+ /*
+ * 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(tfshark_cmdarg_err, tfshark_cmdarg_err_cont);
+ cmdarg_err_init(tfshark_cmdarg_err, tfshark_cmdarg_err_cont);
- /* Initialize log handler early so we can have proper logging during startup. */
- ws_log_init("tfshark", vcmdarg_err);
+ /* Initialize log handler early so we can have proper logging during startup. */
+ ws_log_init("tfshark", 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);
#ifdef _WIN32
- create_app_running_mutex();
+ create_app_running_mutex();
#endif /* _WIN32 */
- /*
- * Get credential information for later use, and drop privileges
- * before doing anything else.
- * Let the user know if anything happened.
- */
- init_process_policies();
- relinquish_special_privs_perm();
- print_current_user();
-
- /*
- * Attempt to get the pathname of the directory containing the
- * executable file.
- */
- init_progfile_dir_error = init_progfile_dir(argv[0]);
- if (init_progfile_dir_error != NULL) {
- fprintf(stderr,
- "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
- init_progfile_dir_error);
- g_free(init_progfile_dir_error);
- }
-
- initialize_funnel_ops();
-
- /* Initialize the version information. */
- ws_init_version_info("TFShark (Wireshark)", NULL,
- epan_get_compiled_version_info,
- get_tfshark_runtime_version_info);
-
- /*
- * In order to have the -X opts assigned before the wslua machine starts
- * we need to call getopts before epan_init() gets called.
- *
- * In order to handle, for example, -o options, we also need to call it
- * *after* epan_init() gets called, so that the dissectors have had a
- * chance to register their preferences.
- *
- * XXX - can we do this all with one getopt_long() call, saving the
- * arguments we can't handle until after initializing libwireshark,
- * and then process them after initializing libwireshark?
- */
- ws_opterr = 0;
-
- while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
- switch (opt) {
- case 'C': /* Configuration Profile */
- if (profile_exists (ws_optarg, FALSE)) {
- set_profile_name (ws_optarg);
- } else {
- cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
- return 1;
- }
- break;
- case 'O': /* Only output these protocols */
- output_only = g_strdup(ws_optarg);
- /* FALLTHROUGH */
- case 'V': /* Verbose */
- print_details = TRUE;
- print_packet_info = TRUE;
- break;
- case 'x': /* Print packet data in hex (and ASCII) */
- print_hex = TRUE;
- /* The user asked for hex output, so let's ensure they get it,
- * even if they're writing to a file.
- */
- print_packet_info = TRUE;
- break;
- case 'X':
- ex_opt_add(ws_optarg);
- break;
- default:
- break;
+ /*
+ * Get credential information for later use, and drop privileges
+ * before doing anything else.
+ * Let the user know if anything happened.
+ */
+ init_process_policies();
+ relinquish_special_privs_perm();
+ print_current_user();
+
+ /*
+ * Attempt to get the pathname of the directory containing the
+ * executable file.
+ */
+ init_progfile_dir_error = init_progfile_dir(argv[0]);
+ if (init_progfile_dir_error != NULL) {
+ fprintf(stderr,
+ "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
+ init_progfile_dir_error);
+ g_free(init_progfile_dir_error);
}
- }
-
- /*
- * Print packet summary information is the default, unless either -V or -x
- * were specified. Note that this is new behavior, which
- * allows for the possibility of printing only hex/ascii output without
- * necessarily requiring that either the summary or details be printed too.
- */
- if (print_summary == -1)
- print_summary = (print_details || print_hex) ? FALSE : TRUE;
-
- init_report_message("tfshark", &tfshark_report_routines);
-
- timestamp_set_type(TS_RELATIVE);
- timestamp_set_precision(TS_PREC_AUTO);
- timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
-
- /*
- * Libwiretap must be initialized before libwireshark is, so that
- * dissection-time handlers for file-type-dependent blocks can
- * register using the file type/subtype value for the file type.
- *
- * XXX - TFShark shouldn't use libwiretap, as it's a file dissector
- * and should read all files as raw bytes and then try to dissect them.
- * It needs to handle file types its own way, because we would want
- * to support dissecting file-type-specific blocks when dissecting
- * capture files, but that mechanism should support plugins for
- * other files, too, if *their* formats are extensible.
- */
- wtap_init(TRUE);
-
- /* Register all dissectors; we must do this before checking for the
- "-G" flag, as the "-G" flag dumps information registered by the
- dissectors, and we must do it before we read the preferences, in
- case any dissectors register preferences. */
- if (!epan_init(NULL, NULL, TRUE)) {
- exit_status = INIT_FAILED;
- goto clean_exit;
- }
-
- /* Register all tap listeners; we do this before we parse the arguments,
- as the "-z" argument can specify a registered tap. */
-
- /* we register the plugin taps before the other taps because
- stats_tree taps plugins will be registered as tap listeners
- by stats_tree_stat.c and need to registered before that */
-
- /* XXX Disable tap registration for now until we can get tfshark set up with
- * its own set of taps and the necessary registration function etc.
- register_all_tap_listeners();
- */
-
- /* If invoked with the "-G" flag, we dump out information based on
- the argument to the "-G" flag; if no argument is specified,
- for backwards compatibility we dump out a glossary of display
- filter symbols.
-
- XXX - we do this here, for now, to support "-G" with no arguments.
- If none of our build or other processes uses "-G" with no arguments,
- we can just process it with the other arguments. */
- if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
- proto_initialize_all_prefixes();
-
- if (argc == 2)
- proto_registrar_dump_fields();
- else {
- if (strcmp(argv[2], "column-formats") == 0)
- column_dump_column_formats();
- else if (strcmp(argv[2], "currentprefs") == 0) {
- epan_load_settings();
- write_prefs(NULL);
- }
- else if (strcmp(argv[2], "decodes") == 0)
- dissector_dump_decodes();
- else if (strcmp(argv[2], "defaultprefs") == 0)
- write_prefs(NULL);
- else if (strcmp(argv[2], "dissector-tables") == 0)
- dissector_dump_dissector_tables();
- else if (strcmp(argv[2], "fields") == 0)
- proto_registrar_dump_fields();
- else if (strcmp(argv[2], "ftypes") == 0)
- proto_registrar_dump_ftypes();
- else if (strcmp(argv[2], "heuristic-decodes") == 0)
- dissector_dump_heur_decodes();
- else if (strcmp(argv[2], "plugins") == 0) {
+
+ initialize_funnel_ops();
+
+ /* Initialize the version information. */
+ ws_init_version_info("TFShark (Wireshark)", NULL,
+ epan_get_compiled_version_info,
+ get_tfshark_runtime_version_info);
+
+ /*
+ * In order to have the -X opts assigned before the wslua machine starts
+ * we need to call getopts before epan_init() gets called.
+ *
+ * In order to handle, for example, -o options, we also need to call it
+ * *after* epan_init() gets called, so that the dissectors have had a
+ * chance to register their preferences.
+ *
+ * XXX - can we do this all with one getopt_long() call, saving the
+ * arguments we can't handle until after initializing libwireshark,
+ * and then process them after initializing libwireshark?
+ */
+ ws_opterr = 0;
+
+ while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
+ switch (opt) {
+ case 'C': /* Configuration Profile */
+ if (profile_exists (ws_optarg, FALSE)) {
+ set_profile_name (ws_optarg);
+ } else {
+ cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
+ return 1;
+ }
+ break;
+ case 'O': /* Only output these protocols */
+ output_only = g_strdup(ws_optarg);
+ /* FALLTHROUGH */
+ case 'V': /* Verbose */
+ print_details = TRUE;
+ print_packet_info = TRUE;
+ break;
+ case 'x': /* Print packet data in hex (and ASCII) */
+ print_hex = TRUE;
+ /* The user asked for hex output, so let's ensure they get it,
+ * even if they're writing to a file.
+ */
+ print_packet_info = TRUE;
+ break;
+ case 'X':
+ ex_opt_add(ws_optarg);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /*
+ * Print packet summary information is the default, unless either -V or -x
+ * were specified. Note that this is new behavior, which
+ * allows for the possibility of printing only hex/ascii output without
+ * necessarily requiring that either the summary or details be printed too.
+ */
+ if (print_summary == -1)
+ print_summary = (print_details || print_hex) ? FALSE : TRUE;
+
+ init_report_message("tfshark", &tfshark_report_routines);
+
+ timestamp_set_type(TS_RELATIVE);
+ timestamp_set_precision(TS_PREC_AUTO);
+ timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
+
+ /*
+ * Libwiretap must be initialized before libwireshark is, so that
+ * dissection-time handlers for file-type-dependent blocks can
+ * register using the file type/subtype value for the file type.
+ *
+ * XXX - TFShark shouldn't use libwiretap, as it's a file dissector
+ * and should read all files as raw bytes and then try to dissect them.
+ * It needs to handle file types its own way, because we would want
+ * to support dissecting file-type-specific blocks when dissecting
+ * capture files, but that mechanism should support plugins for
+ * other files, too, if *their* formats are extensible.
+ */
+ wtap_init(TRUE);
+
+ /* Register all dissectors; we must do this before checking for the
+ "-G" flag, as the "-G" flag dumps information registered by the
+ dissectors, and we must do it before we read the preferences, in
+ case any dissectors register preferences. */
+ if (!epan_init(NULL, NULL, TRUE)) {
+ exit_status = INIT_FAILED;
+ goto clean_exit;
+ }
+
+ /* Register all tap listeners; we do this before we parse the arguments,
+ as the "-z" argument can specify a registered tap. */
+
+ /* we register the plugin taps before the other taps because
+ stats_tree taps plugins will be registered as tap listeners
+ by stats_tree_stat.c and need to registered before that */
+
+ /* XXX Disable tap registration for now until we can get tfshark set up with
+ * its own set of taps and the necessary registration function etc.
+ register_all_tap_listeners();
+ */
+
+ /* If invoked with the "-G" flag, we dump out information based on
+ the argument to the "-G" flag; if no argument is specified,
+ for backwards compatibility we dump out a glossary of display
+ filter symbols.
+
+ XXX - we do this here, for now, to support "-G" with no arguments.
+ If none of our build or other processes uses "-G" with no arguments,
+ we can just process it with the other arguments. */
+ if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
+ proto_initialize_all_prefixes();
+
+ if (argc == 2)
+ proto_registrar_dump_fields();
+ else {
+ if (strcmp(argv[2], "column-formats") == 0)
+ column_dump_column_formats();
+ else if (strcmp(argv[2], "currentprefs") == 0) {
+ epan_load_settings();
+ write_prefs(NULL);
+ }
+ else if (strcmp(argv[2], "decodes") == 0)
+ dissector_dump_decodes();
+ else if (strcmp(argv[2], "defaultprefs") == 0)
+ write_prefs(NULL);
+ else if (strcmp(argv[2], "dissector-tables") == 0)
+ dissector_dump_dissector_tables();
+ else if (strcmp(argv[2], "fields") == 0)
+ proto_registrar_dump_fields();
+ else if (strcmp(argv[2], "ftypes") == 0)
+ proto_registrar_dump_ftypes();
+ else if (strcmp(argv[2], "heuristic-decodes") == 0)
+ dissector_dump_heur_decodes();
+ else if (strcmp(argv[2], "plugins") == 0) {
#ifdef HAVE_PLUGINS
- plugins_dump_all();
+ plugins_dump_all();
#endif
#ifdef HAVE_LUA
- wslua_plugins_dump_all();
+ wslua_plugins_dump_all();
#endif
- }
- else if (strcmp(argv[2], "protocols") == 0)
- proto_registrar_dump_protocols();
- else if (strcmp(argv[2], "values") == 0)
- proto_registrar_dump_values();
- else if (strcmp(argv[2], "?") == 0)
- glossary_option_help();
- else if (strcmp(argv[2], "-?") == 0)
- glossary_option_help();
- else {
- cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
- exit_status = INVALID_OPTION;
+ }
+ else if (strcmp(argv[2], "protocols") == 0)
+ proto_registrar_dump_protocols();
+ else if (strcmp(argv[2], "values") == 0)
+ proto_registrar_dump_values();
+ else if (strcmp(argv[2], "?") == 0)
+ glossary_option_help();
+ else if (strcmp(argv[2], "-?") == 0)
+ glossary_option_help();
+ else {
+ cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ }
goto clean_exit;
- }
}
- goto clean_exit;
- }
-
- /* Load libwireshark settings from the current profile. */
- prefs_p = epan_load_settings();
- prefs_loaded = TRUE;
-
- cap_file_init(&cfile);
-
- /* Print format defaults to this. */
- print_format = PR_FMT_TEXT;
-
- output_fields = output_fields_new();
-
- /*
- * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
- *
- * Also reset ws_opterr to 1, so that error messages are printed by
- * getopt_long().
- */
- ws_optreset = 1;
- ws_optind = 1;
- ws_opterr = 1;
-
- /* Now get our args */
- while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
- switch (opt) {
- case '2': /* Perform two pass analysis */
- perform_two_pass_analysis = TRUE;
- break;
- case 'C':
- /* already processed; just ignore it now */
- break;
- case 'e':
- /* Field entry */
- output_fields_add(output_fields, ws_optarg);
- break;
- case 'E':
- /* Field option */
- if (!output_fields_set_option(output_fields, ws_optarg)) {
- cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg);
- output_fields_list_options(stderr);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
-
- case 'h': /* Print help and exit */
- show_help_header("Analyze file structure.");
- print_usage(stdout);
- goto clean_exit;
- break;
- case 'l': /* "Line-buffer" standard output */
- /* The ANSI C standard does not appear to *require* that a line-buffered
- stream be flushed to the host environment whenever a newline is
- written, it just says that, on such a stream, characters "are
- intended to be transmitted to or from the host environment as a
- block when a new-line character is encountered".
-
- The Visual C++ 6.0 C implementation doesn't do what is intended;
- even if you set a stream to be line-buffered, it still doesn't
- flush the buffer at the end of every line.
-
- The whole reason for the "-l" flag in either tcpdump or TShark
- is to allow the output of a live capture to be piped to a program
- or script and to have that script see the information for the
- packet as soon as it's printed, rather than having to wait until
- a standard I/O buffer fills up.
-
- So, if the "-l" flag is specified, we flush the standard output
- at the end of a packet. This will do the right thing if we're
- printing packet summary lines, and, as we print the entire protocol
- tree for a single packet without waiting for anything to happen,
- it should be as good as line-buffered mode if we're printing
- protocol trees - arguably even better, as it may do fewer
- writes. */
- line_buffered = TRUE;
- break;
- case 'o': /* Override preference from command line */
- {
- char *errmsg = NULL;
-
- switch (prefs_set_pref(ws_optarg, &errmsg)) {
-
- case PREFS_SET_OK:
- break;
-
- case PREFS_SET_SYNTAX_ERR:
- cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
- errmsg ? ": " : "", errmsg ? errmsg : "");
- g_free(errmsg);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- break;
- case PREFS_SET_NO_SUCH_PREF:
- cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- break;
+ /* Load libwireshark settings from the current profile. */
+ prefs_p = epan_load_settings();
+ prefs_loaded = TRUE;
- case PREFS_SET_OBSOLETE:
- cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- break;
- }
- break;
+ cap_file_init(&cfile);
+
+ /* Print format defaults to this. */
+ print_format = PR_FMT_TEXT;
+
+ output_fields = output_fields_new();
+
+ /*
+ * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
+ *
+ * Also reset ws_opterr to 1, so that error messages are printed by
+ * getopt_long().
+ */
+ ws_optreset = 1;
+ ws_optind = 1;
+ ws_opterr = 1;
+
+ /* Now get our args */
+ while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
+ switch (opt) {
+ case '2': /* Perform two pass analysis */
+ perform_two_pass_analysis = TRUE;
+ break;
+ case 'C':
+ /* already processed; just ignore it now */
+ break;
+ case 'e':
+ /* Field entry */
+ output_fields_add(output_fields, ws_optarg);
+ break;
+ case 'E':
+ /* Field option */
+ if (!output_fields_set_option(output_fields, ws_optarg)) {
+ cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg);
+ output_fields_list_options(stderr);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+
+ case 'h': /* Print help and exit */
+ show_help_header("Analyze file structure.");
+ print_usage(stdout);
+ goto clean_exit;
+ break;
+ case 'l': /* "Line-buffer" standard output */
+ /* The ANSI C standard does not appear to *require* that a
+ line-buffered stream be flushed to the host environment
+ whenever a newline is written, it just says that, on such a
+ stream, characters "are intended to be transmitted to or
+ from the host environment as a block when a new-line
+ character is encountered".
+
+ The Visual C++ 6.0 C implementation doesn't do what is
+ intended; even if you set a stream to be line-buffered, it
+ still doesn't flush the buffer at the end of every line.
+
+ The whole reason for the "-l" flag in either tcpdump or
+ TShark is to allow the output of a live capture to be piped
+ to a program or script and to have that script see the
+ information for the packet as soon as it's printed, rather
+ than having to wait until a standard I/O buffer fills up.
+
+ So, if the "-l" flag is specified, we flush the standard
+ output at the end of a packet. This will do the right thing
+ if we're printing packet summary lines, and, as we print the
+ entire protocol tree for a single packet without waiting for
+ anything to happen, it should be as good as line-buffered
+ mode if we're printing protocol trees - arguably even
+ better, as it may do fewer writes. */
+ line_buffered = TRUE;
+ break;
+ case 'o': /* Override preference from command line */
+ {
+ char *errmsg = NULL;
+
+ switch (prefs_set_pref(ws_optarg, &errmsg)) {
+
+ case PREFS_SET_OK:
+ break;
+
+ case PREFS_SET_SYNTAX_ERR:
+ cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
+ errmsg ? ": " : "", errmsg ? errmsg : "");
+ g_free(errmsg);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ break;
+
+ case PREFS_SET_NO_SUCH_PREF:
+ cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ break;
+
+ case PREFS_SET_OBSOLETE:
+ cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ break;
+ }
+ break;
+ }
+ case 'q': /* Quiet */
+ quiet = TRUE;
+ break;
+ case 'Q': /* Really quiet */
+ quiet = TRUE;
+ really_quiet = TRUE;
+ break;
+ case 'r': /* Read capture file x */
+ cf_name = g_strdup(ws_optarg);
+ break;
+ case 'R': /* Read file filter */
+ rfilter = ws_optarg;
+ break;
+ case 'S': /* Set the line Separator to be printed between packets */
+ separator = g_strdup(ws_optarg);
+ break;
+ case 'T': /* printing Type */
+ if (strcmp(ws_optarg, "text") == 0) {
+ output_action = WRITE_TEXT;
+ print_format = PR_FMT_TEXT;
+ } else if (strcmp(ws_optarg, "ps") == 0) {
+ output_action = WRITE_TEXT;
+ print_format = PR_FMT_PS;
+ } else if (strcmp(ws_optarg, "pdml") == 0) {
+ output_action = WRITE_XML;
+ print_details = TRUE; /* Need details */
+ print_summary = FALSE; /* Don't allow summary */
+ } else if (strcmp(ws_optarg, "psml") == 0) {
+ output_action = WRITE_XML;
+ print_details = FALSE; /* Don't allow details */
+ print_summary = TRUE; /* Need summary */
+ } else if (strcmp(ws_optarg, "fields") == 0) {
+ output_action = WRITE_FIELDS;
+ print_details = TRUE; /* Need full tree info */
+ print_summary = FALSE; /* Don't allow summary */
+ } else {
+ cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */
+ cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
+ "\t specified by the -E option.\n"
+ "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
+ "\t details of a decoded packet. This information is equivalent to\n"
+ "\t the packet details printed with the -V flag.\n"
+ "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
+ "\t the packets, or a multi-line view of the details of each of\n"
+ "\t the packets, depending on whether the -V flag was specified.\n"
+ "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
+ "\t summary information of a decoded packet. This information is\n"
+ "\t equivalent to the information shown in the one-line summary\n"
+ "\t printed by default.\n"
+ "\t\"text\" Text of a human-readable one-line summary of each of the\n"
+ "\t packets, or a multi-line view of the details of each of the\n"
+ "\t packets, depending on whether the -V flag was specified.\n"
+ "\t This is the default.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case 'v': /* Show version and exit */
+ show_version();
+ goto clean_exit;
+ case 'O': /* Only output these protocols */
+ /* already processed; just ignore it now */
+ break;
+ case 'V': /* Verbose */
+ /* already processed; just ignore it now */
+ break;
+ case 'x': /* Print packet data in hex (and ASCII) */
+ /* already processed; just ignore it now */
+ break;
+ case 'X':
+ /* already processed; just ignore it now */
+ break;
+ case 'Y':
+ dfilter = ws_optarg;
+ break;
+ case 'z':
+ /* We won't call the init function for the stat this soon
+ as it would disallow MATE's fields (which are registered
+ by the preferences set callback) from being used as
+ part of a tap filter. Instead, we just add the argument
+ to a list of stat arguments. */
+ if (strcmp("help", ws_optarg) == 0) {
+ fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
+ list_stat_cmd_args();
+ goto clean_exit;
+ }
+ if (!process_stat_cmd_arg(ws_optarg)) {
+ cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg);
+ list_stat_cmd_args();
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case 'd': /* Decode as rule */
+ case 'K': /* Kerberos keytab file */
+ case 't': /* Time stamp type */
+ case 'u': /* Seconds type */
+ case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
+ case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
+ case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
+ case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
+ if (!dissect_opts_handle_opt(opt, ws_optarg)) {
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ default:
+ case '?': /* Bad flag - print usage message */
+ print_usage(stderr);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ break;
+ }
}
- case 'q': /* Quiet */
- quiet = TRUE;
- break;
- case 'Q': /* Really quiet */
- quiet = TRUE;
- really_quiet = TRUE;
- break;
- case 'r': /* Read capture file x */
- cf_name = g_strdup(ws_optarg);
- break;
- case 'R': /* Read file filter */
- rfilter = ws_optarg;
- break;
- case 'S': /* Set the line Separator to be printed between packets */
- separator = g_strdup(ws_optarg);
- break;
- case 'T': /* printing Type */
- if (strcmp(ws_optarg, "text") == 0) {
- output_action = WRITE_TEXT;
- print_format = PR_FMT_TEXT;
- } else if (strcmp(ws_optarg, "ps") == 0) {
- output_action = WRITE_TEXT;
- print_format = PR_FMT_PS;
- } else if (strcmp(ws_optarg, "pdml") == 0) {
- output_action = WRITE_XML;
- print_details = TRUE; /* Need details */
- print_summary = FALSE; /* Don't allow summary */
- } else if (strcmp(ws_optarg, "psml") == 0) {
- output_action = WRITE_XML;
- print_details = FALSE; /* Don't allow details */
- print_summary = TRUE; /* Need summary */
- } else if (strcmp(ws_optarg, "fields") == 0) {
- output_action = WRITE_FIELDS;
- print_details = TRUE; /* Need full tree info */
- print_summary = FALSE; /* Don't allow summary */
- } else {
- cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */
- cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
- "\t specified by the -E option.\n"
- "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
- "\t details of a decoded packet. This information is equivalent to\n"
- "\t the packet details printed with the -V flag.\n"
- "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
- "\t the packets, or a multi-line view of the details of each of\n"
- "\t the packets, depending on whether the -V flag was specified.\n"
- "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
- "\t summary information of a decoded packet. This information is\n"
- "\t equivalent to the information shown in the one-line summary\n"
- "\t printed by default.\n"
- "\t\"text\" Text of a human-readable one-line summary of each of the\n"
- "\t packets, or a multi-line view of the details of each of the\n"
- "\t packets, depending on whether the -V flag was specified.\n"
- "\t This is the default.");
+
+ /* If we specified output fields, but not the output field type... */
+ if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
+ cmdarg_err("Output fields were specified with \"-e\", "
+ "but \"-Tfields\" was not specified.");
+ return 1;
+ } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
+ cmdarg_err("\"-Tfields\" was specified, but no fields were "
+ "specified with \"-e\".");
+
exit_status = INVALID_OPTION;
goto clean_exit;
- }
- break;
- case 'v': /* Show version and exit */
- show_version();
- goto clean_exit;
- case 'O': /* Only output these protocols */
- /* already processed; just ignore it now */
- break;
- case 'V': /* Verbose */
- /* already processed; just ignore it now */
- break;
- case 'x': /* Print packet data in hex (and ASCII) */
- /* already processed; just ignore it now */
- break;
- case 'X':
- /* already processed; just ignore it now */
- break;
- case 'Y':
- dfilter = ws_optarg;
- break;
- case 'z':
- /* We won't call the init function for the stat this soon
- as it would disallow MATE's fields (which are registered
- by the preferences set callback) from being used as
- part of a tap filter. Instead, we just add the argument
- to a list of stat arguments. */
- if (strcmp("help", ws_optarg) == 0) {
- fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
- list_stat_cmd_args();
+ }
+
+ /* We require a -r flag specifying a file to read. */
+ if (cf_name == NULL) {
+ cmdarg_err("A file to read must be specified with \"-r\".");
+ exit_status = NO_FILE_SPECIFIED;
goto clean_exit;
- }
- if (!process_stat_cmd_arg(ws_optarg)) {
- cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg);
- list_stat_cmd_args();
+ }
+
+ /* If no display filter has been specified, and there are still command-
+ line arguments, treat them as the tokens of a display filter. */
+ if (ws_optind < argc) {
+ if (dfilter != NULL) {
+ cmdarg_err("Display filters were specified both with \"-Y\" "
+ "and with additional command-line arguments.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ dfilter = get_args_as_string(argc, argv, ws_optind);
+ }
+
+ /* if "-q" wasn't specified, we should print packet information */
+ if (!quiet)
+ print_packet_info = TRUE;
+
+ if (arg_error) {
+ print_usage(stderr);
exit_status = INVALID_OPTION;
goto clean_exit;
- }
- break;
- case 'd': /* Decode as rule */
- case 'K': /* Kerberos keytab file */
- case 't': /* Time stamp type */
- case 'u': /* Seconds type */
- case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
- case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
- case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
- case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
- if (!dissect_opts_handle_opt(opt, ws_optarg)) {
+ }
+
+ if (print_hex) {
+ if (output_action != WRITE_TEXT) {
+ cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ }
+
+ if (output_only != NULL) {
+ char *ps;
+
+ if (!print_details) {
+ cmdarg_err("-O requires -V");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+
+ output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
+ for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
+ g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
+ }
+ }
+
+ if (rfilter != NULL && !perform_two_pass_analysis) {
+ cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
exit_status = INVALID_OPTION;
goto clean_exit;
- }
- break;
- default:
- case '?': /* Bad flag - print usage message */
- print_usage(stderr);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- break;
}
- }
- /* If we specified output fields, but not the output field type... */
- if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
- cmdarg_err("Output fields were specified with \"-e\", "
- "but \"-Tfields\" was not specified.");
- return 1;
- } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
- cmdarg_err("\"-Tfields\" was specified, but no fields were "
- "specified with \"-e\".");
+ /* Notify all registered modules that have had any of their preferences
+ changed either from one of the preferences file or from the command
+ line that their preferences have changed. */
+ prefs_apply_all();
+ /*
+ * Enabled and disabled protocols and heuristic dissectors as per
+ * command-line options.
+ */
+ if (!setup_enabled_and_disabled_protocols()) {
exit_status = INVALID_OPTION;
goto clean_exit;
- }
-
- /* We require a -r flag specifying a file to read. */
- if (cf_name == NULL) {
- cmdarg_err("A file to read must be specified with \"-r\".");
- exit_status = NO_FILE_SPECIFIED;
- goto clean_exit;
- }
-
- /* If no display filter has been specified, and there are still command-
- line arguments, treat them as the tokens of a display filter. */
- if (ws_optind < argc) {
+ }
+
+ /* Build the column format array */
+ build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
+
+ if (rfilter != NULL) {
+ if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
+ cmdarg_err("%s", err_msg);
+ g_free(err_msg);
+ exit_status = INVALID_FILTER;
+ goto clean_exit;
+ }
+ }
+ cfile.rfcode = rfcode;
+
if (dfilter != NULL) {
- cmdarg_err("Display filters were specified both with \"-Y\" "
- "and with additional command-line arguments.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
+ cmdarg_err("%s", err_msg);
+ g_free(err_msg);
+ exit_status = INVALID_FILTER;
+ goto clean_exit;
+ }
}
- dfilter = get_args_as_string(argc, argv, ws_optind);
- }
-
- /* if "-q" wasn't specified, we should print packet information */
- if (!quiet)
- print_packet_info = TRUE;
-
- if (arg_error) {
- print_usage(stderr);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
-
- if (print_hex) {
- if (output_action != WRITE_TEXT) {
- cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ cfile.dfcode = dfcode;
+
+ if (print_packet_info) {
+ /* If we're printing as text or PostScript, we have
+ to create a print stream. */
+ if (output_action == WRITE_TEXT) {
+ switch (print_format) {
+
+ case PR_FMT_TEXT:
+ print_stream = print_stream_text_stdio_new(stdout);
+ break;
+
+ case PR_FMT_PS:
+ print_stream = print_stream_ps_stdio_new(stdout);
+ break;
+
+ default:
+ ws_assert_not_reached();
+ }
+ }
}
- }
- if (output_only != NULL) {
- char *ps;
+ /* We have to dissect each packet if:
+
+ we're printing information about each packet;
+
+ we're using a read filter on the packets;
+
+ we're using a display filter on the packets;
- if (!print_details) {
- cmdarg_err("-O requires -V");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ we're using any taps that need dissection. */
+ do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
+
+ /*
+ * Read the file.
+ */
+
+ /* TODO: if tfshark is ever changed to give the user a choice of which
+ open_routine reader to use, then the following needs to change. */
+ if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
+ exit_status = OPEN_ERROR;
+ goto clean_exit;
}
- output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
- for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
- g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
+ /* Start statistics taps; we do so after successfully opening the
+ capture file, so we know we have something to compute stats
+ on, and after registering all dissectors, so that MATE will
+ have registered its field array so we can have a tap filter
+ with one of MATE's late-registered fields as part of the
+ filter. */
+ start_requested_stats();
+
+ /* Process the packets in the file */
+ TRY {
+ /* XXX - for now there is only 1 packet */
+ success = process_file(&cfile, 1, 0);
}
- }
-
- if (rfilter != NULL && !perform_two_pass_analysis) {
- cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
-
- /* Notify all registered modules that have had any of their preferences
- changed either from one of the preferences file or from the command
- line that their preferences have changed. */
- prefs_apply_all();
-
- /*
- * Enabled and disabled protocols and heuristic dissectors as per
- * command-line options.
- */
- if (!setup_enabled_and_disabled_protocols()) {
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
-
- /* Build the column format array */
- build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
-
- if (rfilter != NULL) {
- if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
- cmdarg_err("%s", err_msg);
- g_free(err_msg);
- exit_status = INVALID_FILTER;
- goto clean_exit;
+ CATCH(OutOfMemoryError) {
+ fprintf(stderr,
+ "Out Of Memory.\n"
+ "\n"
+ "Sorry, but TFShark has to terminate now.\n"
+ "\n"
+ "Some infos / workarounds can be found at:\n"
+ WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
+ success = FALSE;
}
- }
- cfile.rfcode = rfcode;
-
- if (dfilter != NULL) {
- if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
- cmdarg_err("%s", err_msg);
- g_free(err_msg);
- exit_status = INVALID_FILTER;
- goto clean_exit;
+ ENDTRY;
+
+ if (!success) {
+ /* We still dump out the results of taps, etc., as we might have
+ read some packets; however, we exit with an error status. */
+ exit_status = 2;
}
- }
- cfile.dfcode = dfcode;
-
- if (print_packet_info) {
- /* If we're printing as text or PostScript, we have
- to create a print stream. */
- if (output_action == WRITE_TEXT) {
- switch (print_format) {
-
- case PR_FMT_TEXT:
- print_stream = print_stream_text_stdio_new(stdout);
- break;
-
- case PR_FMT_PS:
- print_stream = print_stream_ps_stdio_new(stdout);
- break;
-
- default:
- ws_assert_not_reached();
- }
+
+ g_free(cf_name);
+
+ if (cfile.provider.frames != NULL) {
+ free_frame_data_sequence(cfile.provider.frames);
+ cfile.provider.frames = NULL;
}
- }
-
- /* We have to dissect each packet if:
-
- we're printing information about each packet;
-
- we're using a read filter on the packets;
-
- we're using a display filter on the packets;
-
- we're using any taps that need dissection. */
- do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
-
- /*
- * Read the file.
- */
-
- /* TODO: if tfshark is ever changed to give the user a choice of which
- open_routine reader to use, then the following needs to change. */
- if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
- exit_status = OPEN_ERROR;
- goto clean_exit;
- }
-
- /* Start statistics taps; we do so after successfully opening the
- capture file, so we know we have something to compute stats
- on, and after registering all dissectors, so that MATE will
- have registered its field array so we can have a tap filter
- with one of MATE's late-registered fields as part of the
- filter. */
- start_requested_stats();
-
- /* Process the packets in the file */
- TRY {
- /* XXX - for now there is only 1 packet */
- success = process_file(&cfile, 1, 0);
- }
- CATCH(OutOfMemoryError) {
- fprintf(stderr,
- "Out Of Memory.\n"
- "\n"
- "Sorry, but TFShark has to terminate now.\n"
- "\n"
- "Some infos / workarounds can be found at:\n"
- WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
- success = FALSE;
- }
- ENDTRY;
-
- if (!success) {
- /* We still dump out the results of taps, etc., as we might have
- read some packets; however, we exit with an error status. */
- exit_status = 2;
- }
-
- g_free(cf_name);
-
- if (cfile.provider.frames != NULL) {
- free_frame_data_sequence(cfile.provider.frames);
- cfile.provider.frames = NULL;
- }
-
- draw_tap_listeners(TRUE);
- funnel_dump_all_text_windows();
+
+ draw_tap_listeners(TRUE);
+ funnel_dump_all_text_windows();
clean_exit:
- destroy_print_stream(print_stream);
- epan_free(cfile.epan);
- epan_cleanup();
- extcap_cleanup();
+ destroy_print_stream(print_stream);
+ epan_free(cfile.epan);
+ epan_cleanup();
+ extcap_cleanup();
- output_fields_free(output_fields);
- output_fields = NULL;
+ output_fields_free(output_fields);
+ output_fields = NULL;
- col_cleanup(&cfile.cinfo);
- wtap_cleanup();
- return exit_status;
+ col_cleanup(&cfile.cinfo);
+ wtap_cleanup();
+ return exit_status;
}
static const nstime_t *
tfshark_get_frame_ts(struct packet_provider_data *prov, guint32 frame_num)
{
- if (prov->ref && prov->ref->num == frame_num)
- return &prov->ref->abs_ts;
+ if (prov->ref && prov->ref->num == frame_num)
+ return &prov->ref->abs_ts;
- if (prov->prev_dis && prov->prev_dis->num == frame_num)
- return &prov->prev_dis->abs_ts;
+ if (prov->prev_dis && prov->prev_dis->num == frame_num)
+ return &prov->prev_dis->abs_ts;
- if (prov->prev_cap && prov->prev_cap->num == frame_num)
- return &prov->prev_cap->abs_ts;
+ if (prov->prev_cap && prov->prev_cap->num == frame_num)
+ return &prov->prev_cap->abs_ts;
- if (prov->frames) {
- frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
+ if (prov->frames) {
+ frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
- return (fd) ? &fd->abs_ts : NULL;
- }
+ return (fd) ? &fd->abs_ts : NULL;
+ }
- return NULL;
+ return NULL;
}
static const char *
@@ -989,172 +991,172 @@ no_interface_name(struct packet_provider_data *prov _U_, guint32 interface_id _U
static epan_t *
tfshark_epan_new(capture_file *cf)
{
- static const struct packet_provider_funcs funcs = {
- tfshark_get_frame_ts,
- no_interface_name,
- NULL,
- NULL,
- };
-
- return epan_new(&cf->provider, &funcs);
+ static const struct packet_provider_funcs funcs = {
+ tfshark_get_frame_ts,
+ no_interface_name,
+ NULL,
+ NULL,
+ };
+
+ return epan_new(&cf->provider, &funcs);
}
static gboolean
process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
- gint64 offset, wtap_rec *rec,
- const guchar *pd)
+ gint64 offset, wtap_rec *rec,
+ const guchar *pd)
{
- frame_data fdlocal;
- guint32 framenum;
- gboolean passed;
-
- /* The frame number of this packet is one more than the count of
- frames in this packet. */
- framenum = cf->count + 1;
-
- /* If we're not running a display filter and we're not printing any
- packet information, we don't need to do a dissection. This means
- that all packets can be marked as 'passed'. */
- passed = TRUE;
-
- frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
-
- /* If we're going to print packet information, or we're going to
- run a read filter, or display filter, or we're going to process taps, set up to
- do a dissection and do so. */
- if (edt) {
- /* If we're running a read filter, prime the epan_dissect_t with that
- filter. */
- if (cf->rfcode)
- epan_dissect_prime_with_dfilter(edt, cf->rfcode);
-
- /* This is the first pass, so prime the epan_dissect_t with the
- hfids postdissectors want on the first pass. */
- prime_epan_dissect_with_postdissector_wanted_hfids(edt);
-
- frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
- &cf->provider.ref, cf->provider.prev_dis);
- if (cf->provider.ref == &fdlocal) {
- ref_frame = fdlocal;
- cf->provider.ref = &ref_frame;
- }
+ frame_data fdlocal;
+ guint32 framenum;
+ gboolean passed;
- epan_dissect_file_run(edt, rec,
- file_tvbuff_new(&cf->provider, &fdlocal, pd),
- &fdlocal, NULL);
+ /* The frame number of this packet is one more than the count of
+ frames in this packet. */
+ framenum = cf->count + 1;
- /* Run the read filter if we have one. */
- if (cf->rfcode)
- passed = dfilter_apply_edt(cf->rfcode, edt);
- }
+ /* If we're not running a display filter and we're not printing any
+ packet information, we don't need to do a dissection. This means
+ that all packets can be marked as 'passed'. */
+ passed = TRUE;
- if (passed) {
- frame_data_set_after_dissect(&fdlocal, &cum_bytes);
- cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
+ frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
- /* If we're not doing dissection then there won't be any dependent frames.
- * More importantly, edt.pi.dependent_frames won't be initialized because
- * epan hasn't been initialized.
- */
+ /* If we're going to print packet information, or we're going to
+ run a read filter, or display filter, or we're going to process taps, set up to
+ do a dissection and do so. */
if (edt) {
- g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
+ /* If we're running a read filter, prime the epan_dissect_t with that
+ filter. */
+ if (cf->rfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->rfcode);
+
+ /* This is the first pass, so prime the epan_dissect_t with the
+ hfids postdissectors want on the first pass. */
+ prime_epan_dissect_with_postdissector_wanted_hfids(edt);
+
+ frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
+ &cf->provider.ref, cf->provider.prev_dis);
+ if (cf->provider.ref == &fdlocal) {
+ ref_frame = fdlocal;
+ cf->provider.ref = &ref_frame;
+ }
+
+ epan_dissect_file_run(edt, rec,
+ file_tvbuff_new(&cf->provider, &fdlocal, pd),
+ &fdlocal, NULL);
+
+ /* Run the read filter if we have one. */
+ if (cf->rfcode)
+ passed = dfilter_apply_edt(cf->rfcode, edt);
}
- cf->count++;
- } else {
- /* if we don't add it to the frame_data_sequence, clean it up right now
- * to avoid leaks */
- frame_data_destroy(&fdlocal);
- }
+ if (passed) {
+ frame_data_set_after_dissect(&fdlocal, &cum_bytes);
+ cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
+
+ /* If we're not doing dissection then there won't be any dependent frames.
+ * More importantly, edt.pi.dependent_frames won't be initialized because
+ * epan hasn't been initialized.
+ */
+ if (edt) {
+ g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
+ }
+
+ cf->count++;
+ } else {
+ /* if we don't add it to the frame_data_sequence, clean it up right now
+ * to avoid leaks */
+ frame_data_destroy(&fdlocal);
+ }
- if (edt)
- epan_dissect_reset(edt);
+ if (edt)
+ epan_dissect_reset(edt);
- return passed;
+ return passed;
}
static gboolean
process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
- frame_data *fdata, wtap_rec *rec,
- Buffer *buf, guint tap_flags)
+ frame_data *fdata, wtap_rec *rec,
+ Buffer *buf, guint tap_flags)
{
- column_info *cinfo;
- gboolean passed;
+ column_info *cinfo;
+ gboolean passed;
- /* If we're not running a display filter and we're not printing any
- packet information, we don't need to do a dissection. This means
- that all packets can be marked as 'passed'. */
- passed = TRUE;
+ /* If we're not running a display filter and we're not printing any
+ packet information, we don't need to do a dissection. This means
+ that all packets can be marked as 'passed'. */
+ passed = TRUE;
- /* If we're going to print packet information, or we're going to
- run a read filter, or we're going to process taps, set up to
- do a dissection and do so. */
- if (edt) {
-
- /* If we're running a display filter, prime the epan_dissect_t with that
- filter. */
- if (cf->dfcode)
- epan_dissect_prime_with_dfilter(edt, cf->dfcode);
+ /* If we're going to print packet information, or we're going to
+ run a read filter, or we're going to process taps, set up to
+ do a dissection and do so. */
+ if (edt) {
- /* This is the first and only pass, so prime the epan_dissect_t
- with the hfids postdissectors want on the first pass. */
- prime_epan_dissect_with_postdissector_wanted_hfids(edt);
+ /* If we're running a display filter, prime the epan_dissect_t with that
+ filter. */
+ if (cf->dfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->dfcode);
+
+ /* This is the first and only pass, so prime the epan_dissect_t
+ with the hfids postdissectors want on the first pass. */
+ prime_epan_dissect_with_postdissector_wanted_hfids(edt);
+
+ col_custom_prime_edt(edt, &cf->cinfo);
+
+ /* We only need the columns if either
+ 1) some tap needs the columns
+ or
+ 2) we're printing packet info but we're *not* verbose; in verbose
+ mode, we print the protocol tree, not the protocol summary.
+ */
+ if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
+ cinfo = &cf->cinfo;
+ else
+ cinfo = NULL;
+
+ frame_data_set_before_dissect(fdata, &cf->elapsed_time,
+ &cf->provider.ref, cf->provider.prev_dis);
+ if (cf->provider.ref == fdata) {
+ ref_frame = *fdata;
+ cf->provider.ref = &ref_frame;
+ }
- col_custom_prime_edt(edt, &cf->cinfo);
+ epan_dissect_file_run_with_taps(edt, rec,
+ file_tvbuff_new_buffer(&cf->provider, fdata, buf), fdata, cinfo);
- /* We only need the columns if either
- 1) some tap needs the columns
- or
- 2) we're printing packet info but we're *not* verbose; in verbose
- mode, we print the protocol tree, not the protocol summary.
- */
- if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
- cinfo = &cf->cinfo;
- else
- cinfo = NULL;
-
- frame_data_set_before_dissect(fdata, &cf->elapsed_time,
- &cf->provider.ref, cf->provider.prev_dis);
- if (cf->provider.ref == fdata) {
- ref_frame = *fdata;
- cf->provider.ref = &ref_frame;
+ /* Run the read/display filter if we have one. */
+ if (cf->dfcode)
+ passed = dfilter_apply_edt(cf->dfcode, edt);
}
- epan_dissect_file_run_with_taps(edt, rec,
- file_tvbuff_new_buffer(&cf->provider, fdata, buf), fdata, cinfo);
-
- /* Run the read/display filter if we have one. */
- if (cf->dfcode)
- passed = dfilter_apply_edt(cf->dfcode, edt);
- }
+ if (passed) {
+ frame_data_set_after_dissect(fdata, &cum_bytes);
+ /* Process this packet. */
+ if (print_packet_info) {
+ /* We're printing packet information; print the information for
+ this packet. */
+ print_packet(cf, edt);
+
+ /* If we're doing "line-buffering", flush the standard output
+ after every packet. See the comment above, for the "-l"
+ option, for an explanation of why we do that. */
+ if (line_buffered)
+ fflush(stdout);
+
+ if (ferror(stdout)) {
+ show_print_file_io_error(errno);
+ return FALSE;
+ }
+ }
+ cf->provider.prev_dis = fdata;
+ }
+ cf->provider.prev_cap = fdata;
- if (passed) {
- frame_data_set_after_dissect(fdata, &cum_bytes);
- /* Process this packet. */
- if (print_packet_info) {
- /* We're printing packet information; print the information for
- this packet. */
- print_packet(cf, edt);
-
- /* If we're doing "line-buffering", flush the standard output
- after every packet. See the comment above, for the "-l"
- option, for an explanation of why we do that. */
- if (line_buffered)
- fflush(stdout);
-
- if (ferror(stdout)) {
- show_print_file_io_error(errno);
- return FALSE;
- }
+ if (edt) {
+ epan_dissect_reset(edt);
}
- cf->provider.prev_dis = fdata;
- }
- cf->provider.prev_cap = fdata;
-
- if (edt) {
- epan_dissect_reset(edt);
- }
- return passed || fdata->dependent_of_displayed;
+ return passed || fdata->dependent_of_displayed;
}
static gboolean
@@ -1229,966 +1231,966 @@ local_wtap_read(capture_file *cf, wtap_rec *file_rec _U_, int *err, gchar **err_
static gboolean
process_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
{
- guint32 framenum;
- int err;
- gchar *err_info = NULL;
- gint64 data_offset = 0;
- gboolean filtering_tap_listeners;
- guint tap_flags;
- Buffer buf;
- epan_dissect_t *edt = NULL;
- wtap_rec file_rec;
- guint8* raw_data;
-
- if (print_packet_info) {
- if (!write_preamble(cf)) {
- err = errno;
- show_print_file_io_error(err);
- goto out;
- }
- }
+ guint32 framenum;
+ int err;
+ gchar *err_info = NULL;
+ gint64 data_offset = 0;
+ gboolean filtering_tap_listeners;
+ guint tap_flags;
+ Buffer buf;
+ epan_dissect_t *edt = NULL;
+ wtap_rec file_rec;
+ guint8* raw_data;
- /* Do we have any tap listeners with filters? */
- filtering_tap_listeners = have_filtering_tap_listeners();
+ if (print_packet_info) {
+ if (!write_preamble(cf)) {
+ err = errno;
+ show_print_file_io_error(err);
+ goto out;
+ }
+ }
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
+ /* Do we have any tap listeners with filters? */
+ filtering_tap_listeners = have_filtering_tap_listeners();
- wtap_rec_init(&file_rec);
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
- /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
- file_rec.rec_header.packet_header.pkt_encap = 1234;
+ wtap_rec_init(&file_rec);
- if (perform_two_pass_analysis) {
- frame_data *fdata;
+ /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
+ file_rec.rec_header.packet_header.pkt_encap = 1234;
- /* Allocate a frame_data_sequence for all the frames. */
- cf->provider.frames = new_frame_data_sequence();
+ if (perform_two_pass_analysis) {
+ frame_data *fdata;
- if (do_dissection) {
- gboolean create_proto_tree;
+ /* Allocate a frame_data_sequence for all the frames. */
+ cf->provider.frames = new_frame_data_sequence();
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a read filter;
- *
- * a postdissector wants field values or protocols
- * on the first pass.
- */
- create_proto_tree =
- (cf->rfcode != NULL || postdissectors_want_hfids());
+ if (do_dissection) {
+ gboolean create_proto_tree;
- /* We're not going to display the protocol tree on this pass,
- so it's not going to be "visible". */
- edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
- }
- while (local_wtap_read(cf, &file_rec, &err, &err_info, &data_offset, &raw_data)) {
- if (process_packet_first_pass(cf, edt, data_offset, &file_rec, raw_data)) {
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a read filter;
+ *
+ * a postdissector wants field values or protocols
+ * on the first pass.
+ */
+ create_proto_tree =
+ (cf->rfcode != NULL || postdissectors_want_hfids());
- /* Stop reading if we have the maximum number of packets;
- * When the -c option has not been used, max_packet_count
- * starts at 0, which practically means, never stop reading.
- * (unless we roll over max_packet_count ?)
- */
- if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
- err = 0; /* This is not an error */
- break;
+ /* We're not going to display the protocol tree on this pass,
+ so it's not going to be "visible". */
+ edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
+ }
+ while (local_wtap_read(cf, &file_rec, &err, &err_info, &data_offset, &raw_data)) {
+ if (process_packet_first_pass(cf, edt, data_offset, &file_rec, raw_data)) {
+
+ /* Stop reading if we have the maximum number of packets;
+ * When the -c option has not been used, max_packet_count
+ * starts at 0, which practically means, never stop reading.
+ * (unless we roll over max_packet_count ?)
+ */
+ if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
+ err = 0; /* This is not an error */
+ break;
+ }
+ }
}
- }
- }
- if (edt) {
- epan_dissect_free(edt);
- edt = NULL;
- }
+ if (edt) {
+ epan_dissect_free(edt);
+ edt = NULL;
+ }
#if 0
- /* Close the sequential I/O side, to free up memory it requires. */
- wtap_sequential_close(cf->provider.wth);
+ /* Close the sequential I/O side, to free up memory it requires. */
+ wtap_sequential_close(cf->provider.wth);
#endif
- /* Allow the protocol dissectors to free up memory that they
- * don't need after the sequential run-through of the packets. */
- postseq_cleanup_all_protocols();
-
- cf->provider.prev_dis = NULL;
- cf->provider.prev_cap = NULL;
- ws_buffer_init(&buf, 1514);
-
- if (do_dissection) {
- gboolean create_proto_tree;
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a display filter;
- *
- * we're going to print the protocol tree;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * we have custom columns (which require field values, which
- * currently requires that we build a protocol tree).
- */
- create_proto_tree =
- (cf->dfcode || print_details || filtering_tap_listeners ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
-
- /* The protocol tree will be "visible", i.e., printed, only if we're
- printing packet details, which is true if we're printing stuff
- ("print_packet_info" is true) and we're in verbose mode
- ("packet_details" is true). */
- edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
- }
+ /* Allow the protocol dissectors to free up memory that they
+ * don't need after the sequential run-through of the packets. */
+ postseq_cleanup_all_protocols();
+
+ cf->provider.prev_dis = NULL;
+ cf->provider.prev_cap = NULL;
+ ws_buffer_init(&buf, 1514);
+
+ if (do_dissection) {
+ gboolean create_proto_tree;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a display filter;
+ *
+ * we're going to print the protocol tree;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * we have custom columns (which require field values, which
+ * currently requires that we build a protocol tree).
+ */
+ create_proto_tree =
+ (cf->dfcode || print_details || filtering_tap_listeners ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo));
+
+ /* The protocol tree will be "visible", i.e., printed, only if we're
+ printing packet details, which is true if we're printing stuff
+ ("print_packet_info" is true) and we're in verbose mode
+ ("packet_details" is true). */
+ edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
+ }
- for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+ for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
#if 0
- if (wtap_seek_read(cf->provider.wth, fdata->file_off,
- &buf, fdata->cap_len, &err, &err_info)) {
- process_packet_second_pass(cf, edt, fdata, &cf->rec, &buf, tap_flags);
- }
+ if (wtap_seek_read(cf->provider.wth, fdata->file_off,
+ &buf, fdata->cap_len, &err, &err_info)) {
+ process_packet_second_pass(cf, edt, fdata, &cf->rec, &buf, tap_flags);
+ }
#else
- if (!process_packet_second_pass(cf, edt, fdata, &cf->rec, &buf,
- tap_flags))
- return FALSE;
+ if (!process_packet_second_pass(cf, edt, fdata, &cf->rec, &buf,
+ tap_flags))
+ return FALSE;
#endif
- }
+ }
- if (edt) {
- epan_dissect_free(edt);
- edt = NULL;
- }
+ if (edt) {
+ epan_dissect_free(edt);
+ edt = NULL;
+ }
- ws_buffer_free(&buf);
- }
- else {
- framenum = 0;
-
- if (do_dissection) {
- gboolean create_proto_tree;
-
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a read filter;
- *
- * we're going to apply a display filter;
- *
- * we're going to print the protocol tree;
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * a postdissector wants field values or protocols
- * on the first pass;
- *
- * we have custom columns (which require field values, which
- * currently requires that we build a protocol tree).
- */
- create_proto_tree =
- (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
- have_custom_cols(&cf->cinfo));
-
- /* The protocol tree will be "visible", i.e., printed, only if we're
- printing packet details, which is true if we're printing stuff
- ("print_packet_info" is true) and we're in verbose mode
- ("packet_details" is true). */
- edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
+ ws_buffer_free(&buf);
}
+ else {
+ framenum = 0;
+
+ if (do_dissection) {
+ gboolean create_proto_tree;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a read filter;
+ *
+ * we're going to apply a display filter;
+ *
+ * we're going to print the protocol tree;
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * a postdissector wants field values or protocols
+ * on the first pass;
+ *
+ * we have custom columns (which require field values, which
+ * currently requires that we build a protocol tree).
+ */
+ create_proto_tree =
+ (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
+ have_custom_cols(&cf->cinfo));
+
+ /* The protocol tree will be "visible", i.e., printed, only if we're
+ printing packet details, which is true if we're printing stuff
+ ("print_packet_info" is true) and we're in verbose mode
+ ("packet_details" is true). */
+ edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
+ }
- while (local_wtap_read(cf, &file_rec, &err, &err_info, &data_offset, &raw_data)) {
+ while (local_wtap_read(cf, &file_rec, &err, &err_info, &data_offset, &raw_data)) {
- framenum++;
+ framenum++;
- if (!process_packet_single_pass(cf, edt, data_offset,
- &file_rec/*wtap_get_rec(cf->provider.wth)*/,
- raw_data, tap_flags))
- return FALSE;
+ if (!process_packet_single_pass(cf, edt, data_offset,
+ &file_rec/*wtap_get_rec(cf->provider.wth)*/,
+ raw_data, tap_flags))
+ return FALSE;
- /* Stop reading if we have the maximum number of packets;
- * When the -c option has not been used, max_packet_count
- * starts at 0, which practically means, never stop reading.
- * (unless we roll over max_packet_count ?)
- */
- if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
- err = 0; /* This is not an error */
- break;
- }
- }
+ /* Stop reading if we have the maximum number of packets;
+ * When the -c option has not been used, max_packet_count
+ * starts at 0, which practically means, never stop reading.
+ * (unless we roll over max_packet_count ?)
+ */
+ if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
+ err = 0; /* This is not an error */
+ break;
+ }
+ }
- if (edt) {
- epan_dissect_free(edt);
- edt = NULL;
+ if (edt) {
+ epan_dissect_free(edt);
+ edt = NULL;
+ }
}
- }
- wtap_rec_cleanup(&file_rec);
+ wtap_rec_cleanup(&file_rec);
- if (err != 0) {
- /*
- * Print a message noting that the read failed somewhere along the line.
- *
- * If we're printing packet data, and the standard output and error are
- * going to the same place, flush the standard output, so everything
- * buffered up is written, and then print a newline to the standard error
- * before printing the error message, to separate it from the packet
- * data. (Alas, that only works on UN*X; st_dev is meaningless, and
- * the _fstat() documentation at Microsoft doesn't indicate whether
- * st_ino is even supported.)
- */
+ if (err != 0) {
+ /*
+ * Print a message noting that the read failed somewhere along the line.
+ *
+ * If we're printing packet data, and the standard output and error are
+ * going to the same place, flush the standard output, so everything
+ * buffered up is written, and then print a newline to the standard error
+ * before printing the error message, to separate it from the packet
+ * data. (Alas, that only works on UN*X; st_dev is meaningless, and
+ * the _fstat() documentation at Microsoft doesn't indicate whether
+ * st_ino is even supported.)
+ */
#ifndef _WIN32
- if (print_packet_info) {
- ws_statb64 stat_stdout, stat_stderr;
-
- if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
- if (stat_stdout.st_dev == stat_stderr.st_dev &&
- stat_stdout.st_ino == stat_stderr.st_ino) {
- fflush(stdout);
- fprintf(stderr, "\n");
+ if (print_packet_info) {
+ ws_statb64 stat_stdout, stat_stderr;
+
+ if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
+ if (stat_stdout.st_dev == stat_stderr.st_dev &&
+ stat_stdout.st_ino == stat_stderr.st_ino) {
+ fflush(stdout);
+ fprintf(stderr, "\n");
+ }
+ }
}
- }
- }
#endif
#if 0
- switch (err) {
-
- case FTAP_ERR_UNSUPPORTED:
- cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
- cf->filename, err_info);
- g_free(err_info);
- break;
-
- case FTAP_ERR_UNSUPPORTED_ENCAP:
- cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
- cf->filename, err_info);
- g_free(err_info);
- break;
-
- case FTAP_ERR_CANT_READ:
- cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
- cf->filename);
- break;
-
- case FTAP_ERR_SHORT_READ:
- cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
- cf->filename);
- break;
-
- case FTAP_ERR_BAD_FILE:
- cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
- cf->filename, err_info);
- g_free(err_info);
- break;
-
- case FTAP_ERR_DECOMPRESS:
- cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
- "(%s)", cf->filename, err_info);
- break;
-
- default:
- cmdarg_err("An error occurred while reading the file \"%s\": %s.",
- cf->filename, ftap_strerror(err));
- break;
- }
+ switch (err) {
+
+ case FTAP_ERR_UNSUPPORTED:
+ cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
+ cf->filename, err_info);
+ g_free(err_info);
+ break;
+
+ case FTAP_ERR_UNSUPPORTED_ENCAP:
+ cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
+ cf->filename, err_info);
+ g_free(err_info);
+ break;
+
+ case FTAP_ERR_CANT_READ:
+ cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
+ cf->filename);
+ break;
+
+ case FTAP_ERR_SHORT_READ:
+ cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
+ cf->filename);
+ break;
+
+ case FTAP_ERR_BAD_FILE:
+ cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
+ cf->filename, err_info);
+ g_free(err_info);
+ break;
+
+ case FTAP_ERR_DECOMPRESS:
+ cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
+ "(%s)", cf->filename, err_info);
+ break;
+
+ default:
+ cmdarg_err("An error occurred while reading the file \"%s\": %s.",
+ cf->filename, ftap_strerror(err));
+ break;
+ }
#endif
- } else {
- if (print_packet_info) {
- if (!write_finale()) {
- err = errno;
- show_print_file_io_error(err);
- }
+ } else {
+ if (print_packet_info) {
+ if (!write_finale()) {
+ err = errno;
+ show_print_file_io_error(err);
+ }
+ }
}
- }
out:
- wtap_close(cf->provider.wth);
- cf->provider.wth = NULL;
+ wtap_close(cf->provider.wth);
+ cf->provider.wth = NULL;
- return (err != 0);
+ return (err != 0);
}
static gboolean
process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
- wtap_rec *rec, const guchar *pd,
- guint tap_flags)
+ wtap_rec *rec, const guchar *pd,
+ guint tap_flags)
{
- frame_data fdata;
- column_info *cinfo;
- gboolean passed;
+ frame_data fdata;
+ column_info *cinfo;
+ gboolean passed;
- /* Count this packet. */
- cf->count++;
+ /* Count this packet. */
+ cf->count++;
- /* If we're not running a display filter and we're not printing any
- packet information, we don't need to do a dissection. This means
- that all packets can be marked as 'passed'. */
- passed = TRUE;
+ /* If we're not running a display filter and we're not printing any
+ packet information, we don't need to do a dissection. This means
+ that all packets can be marked as 'passed'. */
+ passed = TRUE;
- frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
+ frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
- /* If we're going to print packet information, or we're going to
- run a read filter, or we're going to process taps, set up to
- do a dissection and do so. */
- if (edt) {
- /* If we're running a filter, prime the epan_dissect_t with that
- filter. */
- if (cf->dfcode)
- epan_dissect_prime_with_dfilter(edt, cf->dfcode);
-
- col_custom_prime_edt(edt, &cf->cinfo);
-
- /* We only need the columns if either
- 1) some tap needs the columns
- or
- 2) we're printing packet info but we're *not* verbose; in verbose
- mode, we print the protocol tree, not the protocol summary.
- or
- 3) there is a column mapped as an individual field */
- if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
- cinfo = &cf->cinfo;
- else
- cinfo = NULL;
-
- frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
- &cf->provider.ref, cf->provider.prev_dis);
- if (cf->provider.ref == &fdata) {
- ref_frame = fdata;
- cf->provider.ref = &ref_frame;
- }
+ /* If we're going to print packet information, or we're going to
+ run a read filter, or we're going to process taps, set up to
+ do a dissection and do so. */
+ if (edt) {
+ /* If we're running a filter, prime the epan_dissect_t with that
+ filter. */
+ if (cf->dfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->dfcode);
+
+ col_custom_prime_edt(edt, &cf->cinfo);
+
+ /* We only need the columns if either
+ 1) some tap needs the columns
+ or
+ 2) we're printing packet info but we're *not* verbose; in verbose
+ mode, we print the protocol tree, not the protocol summary.
+ or
+ 3) there is a column mapped as an individual field */
+ if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
+ cinfo = &cf->cinfo;
+ else
+ cinfo = NULL;
+
+ frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
+ &cf->provider.ref, cf->provider.prev_dis);
+ if (cf->provider.ref == &fdata) {
+ ref_frame = fdata;
+ cf->provider.ref = &ref_frame;
+ }
- epan_dissect_file_run_with_taps(edt, rec,
- frame_tvbuff_new(&cf->provider, &fdata, pd),
- &fdata, cinfo);
+ epan_dissect_file_run_with_taps(edt, rec,
+ frame_tvbuff_new(&cf->provider, &fdata, pd),
+ &fdata, cinfo);
- /* Run the filter if we have it. */
- if (cf->dfcode)
- passed = dfilter_apply_edt(cf->dfcode, edt);
- }
+ /* Run the filter if we have it. */
+ if (cf->dfcode)
+ passed = dfilter_apply_edt(cf->dfcode, edt);
+ }
- if (passed) {
- frame_data_set_after_dissect(&fdata, &cum_bytes);
+ if (passed) {
+ frame_data_set_after_dissect(&fdata, &cum_bytes);
+
+ /* Process this packet. */
+ if (print_packet_info) {
+ /* We're printing packet information; print the information for
+ this packet. */
+ print_packet(cf, edt);
+
+ /* If we're doing "line-buffering", flush the standard output
+ after every packet. See the comment above, for the "-l"
+ option, for an explanation of why we do that. */
+ if (line_buffered)
+ fflush(stdout);
+
+ if (ferror(stdout)) {
+ show_print_file_io_error(errno);
+ return FALSE;
+ }
+ }
- /* Process this packet. */
- if (print_packet_info) {
- /* We're printing packet information; print the information for
- this packet. */
- print_packet(cf, edt);
-
- /* If we're doing "line-buffering", flush the standard output
- after every packet. See the comment above, for the "-l"
- option, for an explanation of why we do that. */
- if (line_buffered)
- fflush(stdout);
-
- if (ferror(stdout)) {
- show_print_file_io_error(errno);
- return FALSE;
- }
+ /* this must be set after print_packet() [bug #8160] */
+ prev_dis_frame = fdata;
+ cf->provider.prev_dis = &prev_dis_frame;
}
- /* this must be set after print_packet() [bug #8160] */
- prev_dis_frame = fdata;
- cf->provider.prev_dis = &prev_dis_frame;
- }
+ prev_cap_frame = fdata;
+ cf->provider.prev_cap = &prev_cap_frame;
- prev_cap_frame = fdata;
- cf->provider.prev_cap = &prev_cap_frame;
-
- if (edt) {
- epan_dissect_reset(edt);
- frame_data_destroy(&fdata);
- }
- return passed;
+ if (edt) {
+ epan_dissect_reset(edt);
+ frame_data_destroy(&fdata);
+ }
+ return passed;
}
static gboolean
write_preamble(capture_file *cf)
{
- switch (output_action) {
-
- case WRITE_TEXT:
- return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
-
- case WRITE_XML:
- if (print_details)
- write_pdml_preamble(stdout, cf->filename);
- else
- write_psml_preamble(&cf->cinfo, stdout);
- return !ferror(stdout);
-
- case WRITE_FIELDS:
- write_fields_preamble(output_fields, stdout);
- return !ferror(stdout);
-
- default:
- ws_assert_not_reached();
- return FALSE;
- }
+ switch (output_action) {
+
+ case WRITE_TEXT:
+ return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
+
+ case WRITE_XML:
+ if (print_details)
+ write_pdml_preamble(stdout, cf->filename);
+ else
+ write_psml_preamble(&cf->cinfo, stdout);
+ return !ferror(stdout);
+
+ case WRITE_FIELDS:
+ write_fields_preamble(output_fields, stdout);
+ return !ferror(stdout);
+
+ default:
+ ws_assert_not_reached();
+ return FALSE;
+ }
}
static char *
get_line_buf(size_t len)
{
- static char *line_bufp = NULL;
- static size_t line_buf_len = 256;
- size_t new_line_buf_len;
-
- for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
- new_line_buf_len *= 2)
- ;
- if (line_bufp == NULL) {
- line_buf_len = new_line_buf_len;
- line_bufp = (char *)g_malloc(line_buf_len + 1);
- } else {
- if (new_line_buf_len > line_buf_len) {
- line_buf_len = new_line_buf_len;
- line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
+ static char *line_bufp = NULL;
+ static size_t line_buf_len = 256;
+ size_t new_line_buf_len;
+
+ for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
+ new_line_buf_len *= 2)
+ ;
+ if (line_bufp == NULL) {
+ line_buf_len = new_line_buf_len;
+ line_bufp = (char *)g_malloc(line_buf_len + 1);
+ } else {
+ if (new_line_buf_len > line_buf_len) {
+ line_buf_len = new_line_buf_len;
+ line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
+ }
}
- }
- return line_bufp;
+ return line_bufp;
}
static inline void
put_string(char *dest, const char *str, size_t str_len)
{
- memcpy(dest, str, str_len);
- dest[str_len] = '\0';
+ memcpy(dest, str, str_len);
+ dest[str_len] = '\0';
}
static inline void
put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
{
- size_t i;
+ size_t i;
- for (i = str_len; i < str_with_spaces; i++)
- *dest++ = ' ';
+ for (i = str_len; i < str_with_spaces; i++)
+ *dest++ = ' ';
- put_string(dest, str, str_len);
+ put_string(dest, str, str_len);
}
static inline void
put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
{
- size_t i;
+ size_t i;
- memcpy(dest, str, str_len);
- for (i = str_len; i < str_with_spaces; i++)
- dest[i] = ' ';
+ memcpy(dest, str, str_len);
+ for (i = str_len; i < str_with_spaces; i++)
+ dest[i] = ' ';
- dest[str_with_spaces] = '\0';
+ dest[str_with_spaces] = '\0';
}
static gboolean
print_columns(capture_file *cf)
{
- char *line_bufp;
- int i;
- size_t buf_offset;
- size_t column_len;
- size_t col_len;
- col_item_t* col_item;
-
- line_bufp = get_line_buf(256);
- buf_offset = 0;
- *line_bufp = '\0';
- for (i = 0; i < cf->cinfo.num_cols; i++) {
- col_item = &cf->cinfo.columns[i];
- /* Skip columns not marked as visible. */
- if (!get_column_visible(i))
- continue;
- switch (col_item->col_fmt) {
- case COL_NUMBER:
- column_len = col_len = strlen(col_item->col_data);
- if (column_len < 3)
- column_len = 3;
- line_bufp = get_line_buf(buf_offset + column_len);
- put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
- break;
-
- case COL_CLS_TIME:
- case COL_REL_TIME:
- case COL_ABS_TIME:
- case COL_ABS_YMD_TIME: /* XXX - wider */
- case COL_ABS_YDOY_TIME: /* XXX - wider */
- case COL_UTC_TIME:
- case COL_UTC_YMD_TIME: /* XXX - wider */
- case COL_UTC_YDOY_TIME: /* XXX - wider */
- column_len = col_len = strlen(col_item->col_data);
- if (column_len < 10)
- column_len = 10;
- line_bufp = get_line_buf(buf_offset + column_len);
- put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
- break;
-
- case COL_DEF_SRC:
- case COL_RES_SRC:
- case COL_UNRES_SRC:
- case COL_DEF_DL_SRC:
- case COL_RES_DL_SRC:
- case COL_UNRES_DL_SRC:
- case COL_DEF_NET_SRC:
- case COL_RES_NET_SRC:
- case COL_UNRES_NET_SRC:
- column_len = col_len = strlen(col_item->col_data);
- if (column_len < 12)
- column_len = 12;
- line_bufp = get_line_buf(buf_offset + column_len);
- put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
- break;
-
- case COL_DEF_DST:
- case COL_RES_DST:
- case COL_UNRES_DST:
- case COL_DEF_DL_DST:
- case COL_RES_DL_DST:
- case COL_UNRES_DL_DST:
- case COL_DEF_NET_DST:
- case COL_RES_NET_DST:
- case COL_UNRES_NET_DST:
- column_len = col_len = strlen(col_item->col_data);
- if (column_len < 12)
- column_len = 12;
- line_bufp = get_line_buf(buf_offset + column_len);
- put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
- break;
-
- default:
- column_len = strlen(col_item->col_data);
- line_bufp = get_line_buf(buf_offset + column_len);
- put_string(line_bufp + buf_offset, col_item->col_data, column_len);
- break;
- }
- buf_offset += column_len;
- if (i != cf->cinfo.num_cols - 1) {
- /*
- * This isn't the last column, so we need to print a
- * separator between this column and the next.
- *
- * If we printed a network source and are printing a
- * network destination of the same type next, separate
- * them with " -> "; if we printed a network destination
- * and are printing a network source of the same type
- * next, separate them with " <- "; otherwise separate them
- * with a space.
- *
- * We add enough space to the buffer for " <- " or " -> ",
- * even if we're only adding " ".
- */
- line_bufp = get_line_buf(buf_offset + 4);
- switch (col_item->col_fmt) {
-
- case COL_DEF_SRC:
- case COL_RES_SRC:
- case COL_UNRES_SRC:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_DST:
- case COL_RES_DST:
- case COL_UNRES_DST:
- put_string(line_bufp + buf_offset, " -> ", 4);
- buf_offset += 4;
- break;
-
- default:
- put_string(line_bufp + buf_offset, " ", 1);
- buf_offset += 1;
- break;
- }
- break;
-
- case COL_DEF_DL_SRC:
- case COL_RES_DL_SRC:
- case COL_UNRES_DL_SRC:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_DL_DST:
- case COL_RES_DL_DST:
- case COL_UNRES_DL_DST:
- put_string(line_bufp + buf_offset, " -> ", 4);
- buf_offset += 4;
- break;
-
- default:
- put_string(line_bufp + buf_offset, " ", 1);
- buf_offset += 1;
- break;
+ char *line_bufp;
+ int i;
+ size_t buf_offset;
+ size_t column_len;
+ size_t col_len;
+ col_item_t* col_item;
+
+ line_bufp = get_line_buf(256);
+ buf_offset = 0;
+ *line_bufp = '\0';
+ for (i = 0; i < cf->cinfo.num_cols; i++) {
+ col_item = &cf->cinfo.columns[i];
+ /* Skip columns not marked as visible. */
+ if (!get_column_visible(i))
+ continue;
+ switch (col_item->col_fmt) {
+ case COL_NUMBER:
+ column_len = col_len = strlen(col_item->col_data);
+ if (column_len < 3)
+ column_len = 3;
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
+ break;
+
+ case COL_CLS_TIME:
+ case COL_REL_TIME:
+ case COL_ABS_TIME:
+ case COL_ABS_YMD_TIME: /* XXX - wider */
+ case COL_ABS_YDOY_TIME: /* XXX - wider */
+ case COL_UTC_TIME:
+ case COL_UTC_YMD_TIME: /* XXX - wider */
+ case COL_UTC_YDOY_TIME: /* XXX - wider */
+ column_len = col_len = strlen(col_item->col_data);
+ if (column_len < 10)
+ column_len = 10;
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
+ break;
+
+ case COL_DEF_SRC:
+ case COL_RES_SRC:
+ case COL_UNRES_SRC:
+ case COL_DEF_DL_SRC:
+ case COL_RES_DL_SRC:
+ case COL_UNRES_DL_SRC:
+ case COL_DEF_NET_SRC:
+ case COL_RES_NET_SRC:
+ case COL_UNRES_NET_SRC:
+ column_len = col_len = strlen(col_item->col_data);
+ if (column_len < 12)
+ column_len = 12;
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
+ break;
+
+ case COL_DEF_DST:
+ case COL_RES_DST:
+ case COL_UNRES_DST:
+ case COL_DEF_DL_DST:
+ case COL_RES_DL_DST:
+ case COL_UNRES_DL_DST:
+ case COL_DEF_NET_DST:
+ case COL_RES_NET_DST:
+ case COL_UNRES_NET_DST:
+ column_len = col_len = strlen(col_item->col_data);
+ if (column_len < 12)
+ column_len = 12;
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
+ break;
+
+ default:
+ column_len = strlen(col_item->col_data);
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_string(line_bufp + buf_offset, col_item->col_data, column_len);
+ break;
}
- break;
-
- case COL_DEF_NET_SRC:
- case COL_RES_NET_SRC:
- case COL_UNRES_NET_SRC:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_NET_DST:
- case COL_RES_NET_DST:
- case COL_UNRES_NET_DST:
- put_string(line_bufp + buf_offset, " -> ", 4);
- buf_offset += 4;
- break;
-
- default:
- put_string(line_bufp + buf_offset, " ", 1);
- buf_offset += 1;
- break;
- }
- break;
-
- case COL_DEF_DST:
- case COL_RES_DST:
- case COL_UNRES_DST:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_SRC:
- case COL_RES_SRC:
- case COL_UNRES_SRC:
- put_string(line_bufp + buf_offset, " <- ", 4);
- buf_offset += 4;
- break;
-
- default:
- put_string(line_bufp + buf_offset, " ", 1);
- buf_offset += 1;
- break;
- }
- break;
-
- case COL_DEF_DL_DST:
- case COL_RES_DL_DST:
- case COL_UNRES_DL_DST:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_DL_SRC:
- case COL_RES_DL_SRC:
- case COL_UNRES_DL_SRC:
- put_string(line_bufp + buf_offset, " <- ", 4);
- buf_offset += 4;
- break;
-
- default:
- put_string(line_bufp + buf_offset, " ", 1);
- buf_offset += 1;
- break;
- }
- break;
-
- case COL_DEF_NET_DST:
- case COL_RES_NET_DST:
- case COL_UNRES_NET_DST:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_NET_SRC:
- case COL_RES_NET_SRC:
- case COL_UNRES_NET_SRC:
- put_string(line_bufp + buf_offset, " <- ", 4);
- buf_offset += 4;
- break;
-
- default:
- put_string(line_bufp + buf_offset, " ", 1);
- buf_offset += 1;
- break;
+ buf_offset += column_len;
+ if (i != cf->cinfo.num_cols - 1) {
+ /*
+ * This isn't the last column, so we need to print a
+ * separator between this column and the next.
+ *
+ * If we printed a network source and are printing a
+ * network destination of the same type next, separate
+ * them with " -> "; if we printed a network destination
+ * and are printing a network source of the same type
+ * next, separate them with " <- "; otherwise separate them
+ * with a space.
+ *
+ * We add enough space to the buffer for " <- " or " -> ",
+ * even if we're only adding " ".
+ */
+ line_bufp = get_line_buf(buf_offset + 4);
+ switch (col_item->col_fmt) {
+
+ case COL_DEF_SRC:
+ case COL_RES_SRC:
+ case COL_UNRES_SRC:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_DST:
+ case COL_RES_DST:
+ case COL_UNRES_DST:
+ put_string(line_bufp + buf_offset, " -> ", 4);
+ buf_offset += 4;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, " ", 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_DL_SRC:
+ case COL_RES_DL_SRC:
+ case COL_UNRES_DL_SRC:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_DL_DST:
+ case COL_RES_DL_DST:
+ case COL_UNRES_DL_DST:
+ put_string(line_bufp + buf_offset, " -> ", 4);
+ buf_offset += 4;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, " ", 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_NET_SRC:
+ case COL_RES_NET_SRC:
+ case COL_UNRES_NET_SRC:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_NET_DST:
+ case COL_RES_NET_DST:
+ case COL_UNRES_NET_DST:
+ put_string(line_bufp + buf_offset, " -> ", 4);
+ buf_offset += 4;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, " ", 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_DST:
+ case COL_RES_DST:
+ case COL_UNRES_DST:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_SRC:
+ case COL_RES_SRC:
+ case COL_UNRES_SRC:
+ put_string(line_bufp + buf_offset, " <- ", 4);
+ buf_offset += 4;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, " ", 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_DL_DST:
+ case COL_RES_DL_DST:
+ case COL_UNRES_DL_DST:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_DL_SRC:
+ case COL_RES_DL_SRC:
+ case COL_UNRES_DL_SRC:
+ put_string(line_bufp + buf_offset, " <- ", 4);
+ buf_offset += 4;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, " ", 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_NET_DST:
+ case COL_RES_NET_DST:
+ case COL_UNRES_NET_DST:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_NET_SRC:
+ case COL_RES_NET_SRC:
+ case COL_UNRES_NET_SRC:
+ put_string(line_bufp + buf_offset, " <- ", 4);
+ buf_offset += 4;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, " ", 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, " ", 1);
+ buf_offset += 1;
+ break;
+ }
}
- break;
-
- default:
- put_string(line_bufp + buf_offset, " ", 1);
- buf_offset += 1;
- break;
- }
}
- }
- return print_line(print_stream, 0, line_bufp);
+ return print_line(print_stream, 0, line_bufp);
}
static gboolean
print_packet(capture_file *cf, epan_dissect_t *edt)
{
- if (print_summary || output_fields_has_cols(output_fields)) {
- /* Just fill in the columns. */
- epan_dissect_fill_in_columns(edt, FALSE, TRUE);
-
- if (print_summary) {
- /* Now print them. */
- switch (output_action) {
-
- case WRITE_TEXT:
- if (!print_columns(cf))
- return FALSE;
- break;
-
- case WRITE_XML:
- write_psml_columns(edt, stdout, FALSE);
- return !ferror(stdout);
- case WRITE_FIELDS: /*No non-verbose "fields" format */
- ws_assert_not_reached();
- break;
- }
+ if (print_summary || output_fields_has_cols(output_fields)) {
+ /* Just fill in the columns. */
+ epan_dissect_fill_in_columns(edt, FALSE, TRUE);
+
+ if (print_summary) {
+ /* Now print them. */
+ switch (output_action) {
+
+ case WRITE_TEXT:
+ if (!print_columns(cf))
+ return FALSE;
+ break;
+
+ case WRITE_XML:
+ write_psml_columns(edt, stdout, FALSE);
+ return !ferror(stdout);
+ case WRITE_FIELDS: /*No non-verbose "fields" format */
+ ws_assert_not_reached();
+ break;
+ }
+ }
}
- }
- if (print_details) {
- /* Print the information in the protocol tree. */
- switch (output_action) {
+ if (print_details) {
+ /* Print the information in the protocol tree. */
+ switch (output_action) {
- case WRITE_TEXT:
- if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
+ case WRITE_TEXT:
+ if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
print_hex, edt, output_only_tables, print_stream))
- return FALSE;
- if (!print_hex) {
- if (!print_line(print_stream, 0, separator))
- return FALSE;
- }
- break;
-
- case WRITE_XML:
- write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, &cf->cinfo, stdout, FALSE);
- printf("\n");
- return !ferror(stdout);
- case WRITE_FIELDS:
- write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
- printf("\n");
- return !ferror(stdout);
+ return FALSE;
+ if (!print_hex) {
+ if (!print_line(print_stream, 0, separator))
+ return FALSE;
+ }
+ break;
+
+ case WRITE_XML:
+ write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, &cf->cinfo, stdout, FALSE);
+ printf("\n");
+ return !ferror(stdout);
+ case WRITE_FIELDS:
+ write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
+ printf("\n");
+ return !ferror(stdout);
+ }
}
- }
- if (print_hex) {
- if (print_summary || print_details) {
- if (!print_line(print_stream, 0, ""))
- return FALSE;
+ if (print_hex) {
+ if (print_summary || print_details) {
+ if (!print_line(print_stream, 0, ""))
+ return FALSE;
+ }
+ if (!print_hex_data(print_stream, edt, HEXDUMP_SOURCE_MULTI | HEXDUMP_ASCII_INCLUDE))
+ return FALSE;
+ if (!print_line(print_stream, 0, separator))
+ return FALSE;
}
- if (!print_hex_data(print_stream, edt, HEXDUMP_SOURCE_MULTI | HEXDUMP_ASCII_INCLUDE))
- return FALSE;
- if (!print_line(print_stream, 0, separator))
- return FALSE;
- }
- return TRUE;
+ return TRUE;
}
static gboolean
write_finale(void)
{
- switch (output_action) {
-
- case WRITE_TEXT:
- return print_finale(print_stream);
-
- case WRITE_XML:
- if (print_details)
- write_pdml_finale(stdout);
- else
- write_psml_finale(stdout);
- return !ferror(stdout);
-
- case WRITE_FIELDS:
- write_fields_finale(output_fields, stdout);
- return !ferror(stdout);
-
- default:
- ws_assert_not_reached();
- return FALSE;
- }
+ switch (output_action) {
+
+ case WRITE_TEXT:
+ return print_finale(print_stream);
+
+ case WRITE_XML:
+ if (print_details)
+ write_pdml_finale(stdout);
+ else
+ write_psml_finale(stdout);
+ return !ferror(stdout);
+
+ case WRITE_FIELDS:
+ write_fields_finale(output_fields, stdout);
+ return !ferror(stdout);
+
+ default:
+ ws_assert_not_reached();
+ return FALSE;
+ }
}
cf_status_t
cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
- gchar *err_info;
- char err_msg[2048+1];
+ gchar *err_info;
+ char err_msg[2048+1];
- /* The open isn't implemented yet. Fill in the information for this file. */
+ /* The open isn't implemented yet. Fill in the information for this file. */
- /* Create new epan session for dissection. */
- epan_free(cf->epan);
- cf->epan = tfshark_epan_new(cf);
+ /* Create new epan session for dissection. */
+ epan_free(cf->epan);
+ cf->epan = tfshark_epan_new(cf);
- cf->provider.wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
- cf->f_datalen = 0; /* not used, but set it anyway */
+ cf->provider.wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
+ cf->f_datalen = 0; /* not used, but set it anyway */
- /* Set the file name because we need it to set the follow stream filter.
- XXX - is that still true? We need it for other reasons, though,
- in any case. */
- cf->filename = g_strdup(fname);
+ /* Set the file name because we need it to set the follow stream filter.
+ XXX - is that still true? We need it for other reasons, though,
+ in any case. */
+ cf->filename = g_strdup(fname);
- /* Indicate whether it's a permanent or temporary file. */
- cf->is_tempfile = is_tempfile;
+ /* Indicate whether it's a permanent or temporary file. */
+ cf->is_tempfile = is_tempfile;
- /* No user changes yet. */
- cf->unsaved_changes = FALSE;
+ /* No user changes yet. */
+ cf->unsaved_changes = FALSE;
- cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
- cf->open_type = type;
- cf->count = 0;
- cf->drops_known = FALSE;
- cf->drops = 0;
- cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
- nstime_set_zero(&cf->elapsed_time);
- cf->provider.ref = NULL;
- cf->provider.prev_dis = NULL;
- cf->provider.prev_cap = NULL;
+ cf->cd_t = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
+ cf->open_type = type;
+ cf->count = 0;
+ cf->drops_known = FALSE;
+ cf->drops = 0;
+ cf->snap = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
+ nstime_set_zero(&cf->elapsed_time);
+ cf->provider.ref = NULL;
+ cf->provider.prev_dis = NULL;
+ cf->provider.prev_cap = NULL;
- cf->state = FILE_READ_IN_PROGRESS;
+ cf->state = FILE_READ_IN_PROGRESS;
- return CF_OK;
+ return CF_OK;
/* fail: */
- snprintf(err_msg, sizeof err_msg,
- cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
- cmdarg_err("%s", err_msg);
- return CF_ERROR;
+ snprintf(err_msg, sizeof err_msg,
+ cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
+ cmdarg_err("%s", err_msg);
+ return CF_ERROR;
}
static void
show_print_file_io_error(int err)
{
- switch (err) {
+ switch (err) {
- case ENOSPC:
- cmdarg_err("Not all the packets could be printed because there is "
-"no space left on the file system.");
- break;
+ case ENOSPC:
+ cmdarg_err("Not all the packets could be printed because there is "
+ "no space left on the file system.");
+ break;
#ifdef EDQUOT
- case EDQUOT:
- cmdarg_err("Not all the packets could be printed because you are "
-"too close to, or over your disk quota.");
- break;
+ case EDQUOT:
+ cmdarg_err("Not all the packets could be printed because you are "
+ "too close to, or over your disk quota.");
+ break;
#endif
- default:
- cmdarg_err("An error occurred while printing packets: %s.",
- g_strerror(err));
- break;
- }
+ default:
+ cmdarg_err("An error occurred while printing packets: %s.",
+ g_strerror(err));
+ break;
+ }
}
static const char *
cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
- int file_type _U_)
+ int file_type _U_)
{
- const char *errmsg;
- /* static char errmsg_errno[1024+1]; */
+ const char *errmsg;
+ /* static char errmsg_errno[1024+1]; */
#if 0
- if (err < 0) {
- /* Wiretap error. */
- switch (err) {
-
- case FTAP_ERR_NOT_REGULAR_FILE:
- errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
- break;
-
- case FTAP_ERR_RANDOM_OPEN_PIPE:
- /* Seen only when opening a capture file for reading. */
- errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
- break;
-
- case FTAP_ERR_FILE_UNKNOWN_FORMAT:
- /* Seen only when opening a capture file for reading. */
- errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
- break;
-
- case FTAP_ERR_UNSUPPORTED:
- /* Seen only when opening a capture file for reading. */
- snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
- "(%s)", err_info);
- g_free(err_info);
- errmsg = errmsg_errno;
- break;
-
- case FTAP_ERR_CANT_WRITE_TO_PIPE:
- /* Seen only when opening a capture file for writing. */
- snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
- "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
- errmsg = errmsg_errno;
- break;
-
- case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
- /* Seen only when opening a capture file for writing. */
- errmsg = "TFShark doesn't support writing capture files in that format.";
- break;
-
- case FTAP_ERR_UNSUPPORTED_ENCAP:
- if (for_writing) {
- snprintf(errmsg_errno, sizeof(errmsg_errno),
- "TFShark can't save this capture as a \"%s\" file.",
- ftap_file_type_subtype_short_string(file_type));
- } else {
- snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
- "(%s)", err_info);
- g_free(err_info);
- }
- errmsg = errmsg_errno;
- break;
-
- case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
- if (for_writing) {
- snprintf(errmsg_errno, sizeof(errmsg_errno),
- "TFShark can't save this capture as a \"%s\" file.",
- ftap_file_type_subtype_short_string(file_type));
- errmsg = errmsg_errno;
- } else
- errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
- break;
-
- case FTAP_ERR_BAD_FILE:
- /* Seen only when opening a capture file for reading. */
- snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The file \"%%s\" appears to be damaged or corrupt.\n"
- "(%s)", err_info);
- g_free(err_info);
- errmsg = errmsg_errno;
- break;
-
- case FTAP_ERR_CANT_OPEN:
- if (for_writing)
- errmsg = "The file \"%s\" could not be created for some unknown reason.";
- else
- errmsg = "The file \"%s\" could not be opened for some unknown reason.";
- break;
-
- case FTAP_ERR_SHORT_READ:
- errmsg = "The file \"%s\" appears to have been cut short"
- " in the middle of a packet or other data.";
- break;
-
- case FTAP_ERR_SHORT_WRITE:
- errmsg = "A full header couldn't be written to the file \"%s\".";
- break;
-
- case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
- errmsg = "This file type cannot be written as a compressed file.";
- break;
-
- case FTAP_ERR_DECOMPRESS:
- /* Seen only when opening a capture file for reading. */
- snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
- "(%s)", err_info);
- g_free(err_info);
- errmsg = errmsg_errno;
- break;
-
- default:
- snprintf(errmsg_errno, sizeof(errmsg_errno),
- "The file \"%%s\" could not be %s: %s.",
- for_writing ? "created" : "opened",
- ftap_strerror(err));
- errmsg = errmsg_errno;
- break;
- }
- } else
+ if (err < 0) {
+ /* Wiretap error. */
+ switch (err) {
+
+ case FTAP_ERR_NOT_REGULAR_FILE:
+ errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
+ break;
+
+ case FTAP_ERR_RANDOM_OPEN_PIPE:
+ /* Seen only when opening a capture file for reading. */
+ errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
+ break;
+
+ case FTAP_ERR_FILE_UNKNOWN_FORMAT:
+ /* Seen only when opening a capture file for reading. */
+ errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
+ break;
+
+ case FTAP_ERR_UNSUPPORTED:
+ /* Seen only when opening a capture file for reading. */
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
+ "(%s)", err_info);
+ g_free(err_info);
+ errmsg = errmsg_errno;
+ break;
+
+ case FTAP_ERR_CANT_WRITE_TO_PIPE:
+ /* Seen only when opening a capture file for writing. */
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
+ "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
+ errmsg = errmsg_errno;
+ break;
+
+ case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
+ /* Seen only when opening a capture file for writing. */
+ errmsg = "TFShark doesn't support writing capture files in that format.";
+ break;
+
+ case FTAP_ERR_UNSUPPORTED_ENCAP:
+ if (for_writing) {
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "TFShark can't save this capture as a \"%s\" file.",
+ ftap_file_type_subtype_short_string(file_type));
+ } else {
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
+ "(%s)", err_info);
+ g_free(err_info);
+ }
+ errmsg = errmsg_errno;
+ break;
+
+ case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
+ if (for_writing) {
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "TFShark can't save this capture as a \"%s\" file.",
+ ftap_file_type_subtype_short_string(file_type));
+ errmsg = errmsg_errno;
+ } else
+ errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
+ break;
+
+ case FTAP_ERR_BAD_FILE:
+ /* Seen only when opening a capture file for reading. */
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "The file \"%%s\" appears to be damaged or corrupt.\n"
+ "(%s)", err_info);
+ g_free(err_info);
+ errmsg = errmsg_errno;
+ break;
+
+ case FTAP_ERR_CANT_OPEN:
+ if (for_writing)
+ errmsg = "The file \"%s\" could not be created for some unknown reason.";
+ else
+ errmsg = "The file \"%s\" could not be opened for some unknown reason.";
+ break;
+
+ case FTAP_ERR_SHORT_READ:
+ errmsg = "The file \"%s\" appears to have been cut short"
+ " in the middle of a packet or other data.";
+ break;
+
+ case FTAP_ERR_SHORT_WRITE:
+ errmsg = "A full header couldn't be written to the file \"%s\".";
+ break;
+
+ case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
+ errmsg = "This file type cannot be written as a compressed file.";
+ break;
+
+ case FTAP_ERR_DECOMPRESS:
+ /* Seen only when opening a capture file for reading. */
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
+ "(%s)", err_info);
+ g_free(err_info);
+ errmsg = errmsg_errno;
+ break;
+
+ default:
+ snprintf(errmsg_errno, sizeof(errmsg_errno),
+ "The file \"%%s\" could not be %s: %s.",
+ for_writing ? "created" : "opened",
+ ftap_strerror(err));
+ errmsg = errmsg_errno;
+ break;
+ }
+ } else
#endif
- errmsg = file_open_error_message(err, for_writing);
- return errmsg;
+ errmsg = file_open_error_message(err, for_writing);
+ return errmsg;
}
/*
@@ -2197,9 +2199,9 @@ cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
static void
tfshark_cmdarg_err(const char *msg_format, va_list ap)
{
- fprintf(stderr, "tfshark: ");
- vfprintf(stderr, msg_format, ap);
- fprintf(stderr, "\n");
+ fprintf(stderr, "tfshark: ");
+ vfprintf(stderr, msg_format, ap);
+ fprintf(stderr, "\n");
}
/*
@@ -2208,19 +2210,6 @@ tfshark_cmdarg_err(const char *msg_format, va_list ap)
static void
tfshark_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");
}
-
-/*
- * 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:
- */
diff --git a/tshark.c b/tshark.c
index 1e66941ae6..6ab5b449c8 100644
--- a/tshark.c
+++ b/tshark.c
@@ -151,14 +151,14 @@ static gboolean epan_auto_reset = FALSE;
* The way the packet decode is to be written.
*/
typedef enum {
- WRITE_NONE, /* dummy initial state */
- WRITE_TEXT, /* summary or detail text */
- WRITE_XML, /* PDML or PSML */
- WRITE_FIELDS, /* User defined list of fields */
- WRITE_JSON, /* JSON */
- WRITE_JSON_RAW, /* JSON only raw hex */
- WRITE_EK /* JSON bulk insert to Elasticsearch */
- /* Add CSV and the like here */
+ WRITE_NONE, /* dummy initial state */
+ WRITE_TEXT, /* summary or detail text */
+ WRITE_XML, /* PDML or PSML */
+ WRITE_FIELDS, /* User defined list of fields */
+ WRITE_JSON, /* JSON */
+ WRITE_JSON_RAW, /* JSON only raw hex */
+ WRITE_EK /* JSON bulk insert to Elasticsearch */
+ /* Add CSV and the like here */
} output_action_e;
static output_action_e output_action;
@@ -214,15 +214,15 @@ static gboolean infoprint; /* if TRUE, print capture info after clearing in
static gboolean capture(void);
static gboolean capture_input_new_file(capture_session *cap_session,
- gchar *new_file);
+ gchar *new_file);
static void capture_input_new_packets(capture_session *cap_session,
- int to_read);
+ int to_read);
static void capture_input_drops(capture_session *cap_session, guint32 dropped,
- const char* interface_name);
+ const char* interface_name);
static void capture_input_error(capture_session *cap_session,
- char *error_msg, char *secondary_error_msg);
+ char *error_msg, char *secondary_error_msg);
static void capture_input_cfilter_error(capture_session *cap_session,
- guint i, const char *error_message);
+ guint i, const char *error_message);
static void capture_input_closed(capture_session *cap_session, gchar *msg);
static void report_counts(void);
@@ -239,16 +239,16 @@ static void report_counts_siginfo(int);
static void reset_epan_mem(capture_file *cf, epan_dissect_t *edt, gboolean tree, gboolean visual);
typedef enum {
- PROCESS_FILE_SUCCEEDED,
- PROCESS_FILE_NO_FILE_PROCESSED,
- PROCESS_FILE_ERROR,
- PROCESS_FILE_INTERRUPTED
+ PROCESS_FILE_SUCCEEDED,
+ PROCESS_FILE_NO_FILE_PROCESSED,
+ PROCESS_FILE_ERROR,
+ PROCESS_FILE_INTERRUPTED
} process_file_status_t;
static process_file_status_t process_cap_file(capture_file *, char *, int, gboolean, int, gint64, int);
static gboolean process_packet_single_pass(capture_file *cf,
- epan_dissect_t *edt, gint64 offset, wtap_rec *rec, Buffer *buf,
- guint tap_flags);
+ epan_dissect_t *edt, gint64 offset, wtap_rec *rec, Buffer *buf,
+ guint tap_flags);
static void show_print_file_io_error(void);
static gboolean write_preamble(capture_file *cf);
static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
@@ -260,249 +260,252 @@ static void tshark_cmdarg_err_cont(const char *msg_format, va_list ap);
static GHashTable *output_only_tables = NULL;
static void
-list_capture_types(void) {
- GArray *writable_type_subtypes;
-
- fprintf(stderr, "tshark: 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);
+list_capture_types(void)
+{
+ GArray *writable_type_subtypes;
+
+ fprintf(stderr, "tshark: 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);
}
struct string_elem {
- const char *sstr; /* The short string */
- const char *lstr; /* The long string */
+ const char *sstr; /* The short string */
+ const char *lstr; /* The long string */
};
static gint
string_compare(gconstpointer a, gconstpointer b)
{
- return strcmp(((const struct string_elem *)a)->sstr,
- ((const struct string_elem *)b)->sstr);
+ return strcmp(((const struct string_elem *)a)->sstr,
+ ((const struct string_elem *)b)->sstr);
}
static void
string_elem_print(gpointer data)
{
- fprintf(stderr, " %s - %s\n",
- ((struct string_elem *)data)->sstr,
- ((struct string_elem *)data)->lstr);
+ fprintf(stderr, " %s - %s\n",
+ ((struct string_elem *)data)->sstr,
+ ((struct string_elem *)data)->lstr);
}
static void
-list_read_capture_types(void) {
- guint i;
- size_t num_file_types;
- struct string_elem *captypes;
- GSList *list = NULL;
- const char *magic = "Magic-value-based";
- const char *heuristic = "Heuristics-based";
-
- /* How many readable file types are there? */
- num_file_types = 0;
- for (i = 0; open_routines[i].name != NULL; i++)
- num_file_types++;
- captypes = g_new(struct string_elem, num_file_types);
-
- fprintf(stderr, "tshark: The available read file types for the \"-X read_format:\" option are:\n");
- for (i = 0; i < num_file_types && open_routines[i].name != NULL; i++) {
- captypes[i].sstr = open_routines[i].name;
- captypes[i].lstr = (open_routines[i].type == OPEN_INFO_MAGIC) ? magic : heuristic;
- list = g_slist_insert_sorted(list, &captypes[i], string_compare);
- }
- g_slist_free_full(list, string_elem_print);
- g_free(captypes);
+list_read_capture_types(void)
+{
+ guint i;
+ size_t num_file_types;
+ struct string_elem *captypes;
+ GSList *list = NULL;
+ const char *magic = "Magic-value-based";
+ const char *heuristic = "Heuristics-based";
+
+ /* How many readable file types are there? */
+ num_file_types = 0;
+ for (i = 0; open_routines[i].name != NULL; i++)
+ num_file_types++;
+ captypes = g_new(struct string_elem, num_file_types);
+
+ fprintf(stderr, "tshark: The available read file types for the \"-X read_format:\" option are:\n");
+ for (i = 0; i < num_file_types && open_routines[i].name != NULL; i++) {
+ captypes[i].sstr = open_routines[i].name;
+ captypes[i].lstr = (open_routines[i].type == OPEN_INFO_MAGIC) ? magic : heuristic;
+ list = g_slist_insert_sorted(list, &captypes[i], string_compare);
+ }
+ g_slist_free_full(list, string_elem_print);
+ g_free(captypes);
}
static void
-list_export_pdu_taps(void) {
- fprintf(stderr, "tshark: The available export tap names for the \"-U tap_name\" option are:\n");
- for (GSList *export_pdu_tap_name_list = get_export_pdu_tap_list();
- export_pdu_tap_name_list != NULL;
- export_pdu_tap_name_list = g_slist_next(export_pdu_tap_name_list)) {
- fprintf(stderr, " %s\n", (const char*)(export_pdu_tap_name_list->data));
- }
+list_export_pdu_taps(void)
+{
+ fprintf(stderr, "tshark: The available export tap names for the \"-U tap_name\" option are:\n");
+ for (GSList *export_pdu_tap_name_list = get_export_pdu_tap_list();
+ export_pdu_tap_name_list != NULL;
+ export_pdu_tap_name_list = g_slist_next(export_pdu_tap_name_list)) {
+ fprintf(stderr, " %s\n", (const char*)(export_pdu_tap_name_list->data));
+ }
}
static void
print_usage(FILE *output)
{
- fprintf(output, "\n");
- fprintf(output, "Usage: tshark [options] ...\n");
- fprintf(output, "\n");
+ fprintf(output, "\n");
+ fprintf(output, "Usage: tshark [options] ...\n");
+ fprintf(output, "\n");
#ifdef HAVE_LIBPCAP
- fprintf(output, "Capture interface:\n");
- fprintf(output, " -i <interface>, --interface <interface>\n");
- fprintf(output, " name or idx of interface (def: first non-loopback)\n");
- fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
- fprintf(output, " -s <snaplen>, --snapshot-length <snaplen>\n");
+ fprintf(output, "Capture interface:\n");
+ fprintf(output, " -i <interface>, --interface <interface>\n");
+ fprintf(output, " name or idx of interface (def: first non-loopback)\n");
+ fprintf(output, " -f <capture filter> packet filter in libpcap filter syntax\n");
+ fprintf(output, " -s <snaplen>, --snapshot-length <snaplen>\n");
#ifdef HAVE_PCAP_CREATE
- fprintf(output, " packet snapshot length (def: appropriate maximum)\n");
+ fprintf(output, " packet snapshot length (def: appropriate maximum)\n");
#else
- fprintf(output, " packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
+ fprintf(output, " packet snapshot length (def: %u)\n", WTAP_MAX_PACKET_SIZE_STANDARD);
#endif
- fprintf(output, " -p, --no-promiscuous-mode\n");
- fprintf(output, " don't capture in promiscuous mode\n");
+ fprintf(output, " -p, --no-promiscuous-mode\n");
+ fprintf(output, " don't capture in promiscuous mode\n");
#ifdef HAVE_PCAP_CREATE
- fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
+ fprintf(output, " -I, --monitor-mode capture in monitor mode, if available\n");
#endif
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
- fprintf(output, " -B <buffer size>, --buffer-size <buffer size>\n");
- fprintf(output, " size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
+ fprintf(output, " -B <buffer size>, --buffer-size <buffer size>\n");
+ fprintf(output, " size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
#endif
- fprintf(output, " -y <link type>, --linktype <link type>\n");
- fprintf(output, " link layer type (def: first appropriate)\n");
- fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
- fprintf(output, " -D, --list-interfaces print list of interfaces and exit\n");
- fprintf(output, " -L, --list-data-link-types\n");
- fprintf(output, " print list of link-layer types of iface and exit\n");
- fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
- fprintf(output, "\n");
- fprintf(output, "Capture stop conditions:\n");
- fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
- fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
- fprintf(output, " duration:NUM - stop after NUM seconds\n");
- fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
- fprintf(output, " files:NUM - stop after NUM files\n");
- fprintf(output, " packets:NUM - stop after NUM packets\n");
- /*fprintf(output, "\n");*/
- fprintf(output, "Capture output:\n");
- fprintf(output, " -b <ringbuffer opt.> ..., --ring-buffer <ringbuffer opt.>\n");
- fprintf(output, " duration:NUM - switch to next file after NUM secs\n");
- fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
- fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
- fprintf(output, " packets:NUM - switch to next file after NUM packets\n");
- fprintf(output, " interval:NUM - switch to next file when the time is\n");
- fprintf(output, " an exact multiple of NUM secs\n");
+ fprintf(output, " -y <link type>, --linktype <link type>\n");
+ fprintf(output, " link layer type (def: first appropriate)\n");
+ fprintf(output, " --time-stamp-type <type> timestamp method for interface\n");
+ fprintf(output, " -D, --list-interfaces print list of interfaces and exit\n");
+ fprintf(output, " -L, --list-data-link-types\n");
+ fprintf(output, " print list of link-layer types of iface and exit\n");
+ fprintf(output, " --list-time-stamp-types print list of timestamp types for iface and exit\n");
+ fprintf(output, "\n");
+ fprintf(output, "Capture stop conditions:\n");
+ fprintf(output, " -c <packet count> stop after n packets (def: infinite)\n");
+ fprintf(output, " -a <autostop cond.> ..., --autostop <autostop cond.> ...\n");
+ fprintf(output, " duration:NUM - stop after NUM seconds\n");
+ fprintf(output, " filesize:NUM - stop this file after NUM KB\n");
+ fprintf(output, " files:NUM - stop after NUM files\n");
+ fprintf(output, " packets:NUM - stop after NUM packets\n");
+ /*fprintf(output, "\n");*/
+ fprintf(output, "Capture output:\n");
+ fprintf(output, " -b <ringbuffer opt.> ..., --ring-buffer <ringbuffer opt.>\n");
+ fprintf(output, " duration:NUM - switch to next file after NUM secs\n");
+ fprintf(output, " filesize:NUM - switch to next file after NUM KB\n");
+ fprintf(output, " files:NUM - ringbuffer: replace after NUM files\n");
+ fprintf(output, " packets:NUM - switch to next file after NUM packets\n");
+ fprintf(output, " interval:NUM - switch to next file when the time is\n");
+ fprintf(output, " an exact multiple of NUM secs\n");
#endif /* HAVE_LIBPCAP */
#ifdef HAVE_PCAP_REMOTE
- fprintf(output, "RPCAP options:\n");
- fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
+ fprintf(output, "RPCAP options:\n");
+ fprintf(output, " -A <user>:<password> use RPCAP password authentication\n");
#endif
- /*fprintf(output, "\n");*/
- fprintf(output, "Input file:\n");
- fprintf(output, " -r <infile>, --read-file <infile>\n");
- fprintf(output, " set the filename to read from (or '-' for stdin)\n");
-
- fprintf(output, "\n");
- fprintf(output, "Processing:\n");
- fprintf(output, " -2 perform a two-pass analysis\n");
- fprintf(output, " -M <packet count> perform session auto reset\n");
- fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
- fprintf(output, " packet Read filter in Wireshark display filter syntax\n");
- fprintf(output, " (requires -2)\n");
- fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
- fprintf(output, " packet displaY filter in Wireshark display filter\n");
- fprintf(output, " syntax\n");
- fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
- fprintf(output, " as set in preferences)\n");
- fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtdv\"\n");
- fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
- fprintf(output, " \"Decode As\", see the man page for details\n");
- fprintf(output, " Example: tcp.port==8888,http\n");
- fprintf(output, " -H <hosts file> read a list of entries from a hosts file, which will\n");
- fprintf(output, " then be written to a capture file. (Implies -W n)\n");
- fprintf(output, " --enable-protocol <proto_name>\n");
- fprintf(output, " enable dissection of proto_name\n");
- fprintf(output, " --disable-protocol <proto_name>\n");
- fprintf(output, " disable dissection of proto_name\n");
- fprintf(output, " --enable-heuristic <short_name>\n");
- fprintf(output, " enable dissection of heuristic protocol\n");
- fprintf(output, " --disable-heuristic <short_name>\n");
- fprintf(output, " disable dissection of heuristic protocol\n");
-
- /*fprintf(output, "\n");*/
- fprintf(output, "Output:\n");
- fprintf(output, " -w <outfile|-> write packets to a pcapng-format file named \"outfile\"\n");
- fprintf(output, " (or '-' for stdout)\n");
- fprintf(output, " --capture-comment <comment>\n");
- fprintf(output, " add a capture file comment, if supported\n");
- fprintf(output, " -C <config profile> start with specified configuration profile\n");
- fprintf(output, " -F <output file type> set the output file type, default is pcapng\n");
- fprintf(output, " an empty \"-F\" option will list the file types\n");
- fprintf(output, " -V add output of packet tree (Packet Details)\n");
- fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
- fprintf(output, " separated\n");
- fprintf(output, " -P, --print print packet summary even when writing to a file\n");
- fprintf(output, " -S <separator> the line separator to print between packets\n");
- fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
- fprintf(output, " --hexdump <hexoption> add hexdump, set options for data source and ASCII dump\n");
- fprintf(output, " all dump all data sources (-x default)\n");
- fprintf(output, " frames dump only frame data source\n");
- fprintf(output, " ascii include ASCII dump text (-x default)\n");
- fprintf(output, " delimit delimit ASCII dump text with '|' characters\n");
- fprintf(output, " noascii exclude ASCII dump text\n");
- fprintf(output, " help display help for --hexdump and exit\n");
- fprintf(output, " -T pdml|ps|psml|json|jsonraw|ek|tabs|text|fields|?\n");
- fprintf(output, " format of text output (def: text)\n");
- fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
- fprintf(output, " (e.g. \"ip ip.flags text\", filter does not expand child\n");
- fprintf(output, " nodes, unless child is specified also in the filter)\n");
- fprintf(output, " -J <protocolfilter> top level protocol filter if -T ek|pdml|json selected\n");
- fprintf(output, " (e.g. \"http tcp\", filter which expands all child nodes)\n");
- fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
- fprintf(output, " _ws.col.Info)\n");
- fprintf(output, " this option can be repeated to print multiple fields\n");
- fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
- fprintf(output, " bom=y|n print a UTF-8 BOM\n");
- fprintf(output, " header=y|n switch headers on and off\n");
- fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
- fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
- fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
- fprintf(output, " aggregator\n");
- fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
- fprintf(output, " -t a|ad|adoy|d|dd|e|r|u|ud|udoy\n");
- fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
- fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
- fprintf(output, " -l flush standard output after each packet\n");
- fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
- fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
- fprintf(output, " -g enable group read access on the output file(s)\n");
- fprintf(output, " -W n Save extra information in the file, if supported.\n");
- fprintf(output, " n = write network address resolution information\n");
- fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
- fprintf(output, " -U tap_name PDUs export mode, see the man page for details\n");
- fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
- fprintf(output, " --export-objects <protocol>,<destdir>\n");
- fprintf(output, " save exported objects for a protocol to a directory\n");
- fprintf(output, " named \"destdir\"\n");
- fprintf(output, " --export-tls-session-keys <keyfile>\n");
- fprintf(output, " export TLS Session Keys to a file named \"keyfile\"\n");
- fprintf(output, " --color color output text similarly to the Wireshark GUI,\n");
- fprintf(output, " requires a terminal with 24-bit color support\n");
- fprintf(output, " Also supplies color attributes to pdml and psml formats\n");
- fprintf(output, " (Note that attributes are nonstandard)\n");
- fprintf(output, " --no-duplicate-keys If -T json is specified, merge duplicate keys in an object\n");
- fprintf(output, " into a single key with as value a json array containing all\n");
- fprintf(output, " values\n");
- fprintf(output, " --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
- fprintf(output, " specified protocols within the mapping file\n");
- fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
- fprintf(output, " (default: %s)\n", g_get_tmp_dir());
- fprintf(output, "\n");
-
- ws_log_print_usage(output);
- 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, " -o <name>:<value> ... override preference setting\n");
- fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
- fprintf(output, " -G [report] dump one of several available reports and exit\n");
- fprintf(output, " default report=\"fields\"\n");
- fprintf(output, " use \"-G help\" for more help\n");
+ /*fprintf(output, "\n");*/
+ fprintf(output, "Input file:\n");
+ fprintf(output, " -r <infile>, --read-file <infile>\n");
+ fprintf(output, " set the filename to read from (or '-' for stdin)\n");
+
+ fprintf(output, "\n");
+ fprintf(output, "Processing:\n");
+ fprintf(output, " -2 perform a two-pass analysis\n");
+ fprintf(output, " -M <packet count> perform session auto reset\n");
+ fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
+ fprintf(output, " packet Read filter in Wireshark display filter syntax\n");
+ fprintf(output, " (requires -2)\n");
+ fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
+ fprintf(output, " packet displaY filter in Wireshark display filter\n");
+ fprintf(output, " syntax\n");
+ fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
+ fprintf(output, " as set in preferences)\n");
+ fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtdv\"\n");
+ fprintf(output, " -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
+ fprintf(output, " \"Decode As\", see the man page for details\n");
+ fprintf(output, " Example: tcp.port==8888,http\n");
+ fprintf(output, " -H <hosts file> read a list of entries from a hosts file, which will\n");
+ fprintf(output, " then be written to a capture file. (Implies -W n)\n");
+ fprintf(output, " --enable-protocol <proto_name>\n");
+ fprintf(output, " enable dissection of proto_name\n");
+ fprintf(output, " --disable-protocol <proto_name>\n");
+ fprintf(output, " disable dissection of proto_name\n");
+ fprintf(output, " --enable-heuristic <short_name>\n");
+ fprintf(output, " enable dissection of heuristic protocol\n");
+ fprintf(output, " --disable-heuristic <short_name>\n");
+ fprintf(output, " disable dissection of heuristic protocol\n");
+
+ /*fprintf(output, "\n");*/
+ fprintf(output, "Output:\n");
+ fprintf(output, " -w <outfile|-> write packets to a pcapng-format file named \"outfile\"\n");
+ fprintf(output, " (or '-' for stdout)\n");
+ fprintf(output, " --capture-comment <comment>\n");
+ fprintf(output, " add a capture file comment, if supported\n");
+ fprintf(output, " -C <config profile> start with specified configuration profile\n");
+ fprintf(output, " -F <output file type> set the output file type, default is pcapng\n");
+ fprintf(output, " an empty \"-F\" option will list the file types\n");
+ fprintf(output, " -V add output of packet tree (Packet Details)\n");
+ fprintf(output, " -O <protocols> Only show packet details of these protocols, comma\n");
+ fprintf(output, " separated\n");
+ fprintf(output, " -P, --print print packet summary even when writing to a file\n");
+ fprintf(output, " -S <separator> the line separator to print between packets\n");
+ fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
+ fprintf(output, " --hexdump <hexoption> add hexdump, set options for data source and ASCII dump\n");
+ fprintf(output, " all dump all data sources (-x default)\n");
+ fprintf(output, " frames dump only frame data source\n");
+ fprintf(output, " ascii include ASCII dump text (-x default)\n");
+ fprintf(output, " delimit delimit ASCII dump text with '|' characters\n");
+ fprintf(output, " noascii exclude ASCII dump text\n");
+ fprintf(output, " help display help for --hexdump and exit\n");
+ fprintf(output, " -T pdml|ps|psml|json|jsonraw|ek|tabs|text|fields|?\n");
+ fprintf(output, " format of text output (def: text)\n");
+ fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
+ fprintf(output, " (e.g. \"ip ip.flags text\", filter does not expand child\n");
+ fprintf(output, " nodes, unless child is specified also in the filter)\n");
+ fprintf(output, " -J <protocolfilter> top level protocol filter if -T ek|pdml|json selected\n");
+ fprintf(output, " (e.g. \"http tcp\", filter which expands all child nodes)\n");
+ fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
+ fprintf(output, " _ws.col.Info)\n");
+ fprintf(output, " this option can be repeated to print multiple fields\n");
+ fprintf(output, " -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
+ fprintf(output, " bom=y|n print a UTF-8 BOM\n");
+ fprintf(output, " header=y|n switch headers on and off\n");
+ fprintf(output, " separator=/t|/s|<char> select tab, space, printable character as separator\n");
+ fprintf(output, " occurrence=f|l|a print first, last or all occurrences of each field\n");
+ fprintf(output, " aggregator=,|/s|<char> select comma, space, printable character as\n");
+ fprintf(output, " aggregator\n");
+ fprintf(output, " quote=d|s|n select double, single, no quotes for values\n");
+ fprintf(output, " -t a|ad|adoy|d|dd|e|r|u|ud|udoy\n");
+ fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
+ fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
+ fprintf(output, " -l flush standard output after each packet\n");
+ fprintf(output, " -q be more quiet on stdout (e.g. when using statistics)\n");
+ fprintf(output, " -Q only log true errors to stderr (quieter than -q)\n");
+ fprintf(output, " -g enable group read access on the output file(s)\n");
+ fprintf(output, " -W n Save extra information in the file, if supported.\n");
+ fprintf(output, " n = write network address resolution information\n");
+ fprintf(output, " -X <key>:<value> eXtension options, see the man page for details\n");
+ fprintf(output, " -U tap_name PDUs export mode, see the man page for details\n");
+ fprintf(output, " -z <statistics> various statistics, see the man page for details\n");
+ fprintf(output, " --export-objects <protocol>,<destdir>\n");
+ fprintf(output, " save exported objects for a protocol to a directory\n");
+ fprintf(output, " named \"destdir\"\n");
+ fprintf(output, " --export-tls-session-keys <keyfile>\n");
+ fprintf(output, " export TLS Session Keys to a file named \"keyfile\"\n");
+ fprintf(output, " --color color output text similarly to the Wireshark GUI,\n");
+ fprintf(output, " requires a terminal with 24-bit color support\n");
+ fprintf(output, " Also supplies color attributes to pdml and psml formats\n");
+ fprintf(output, " (Note that attributes are nonstandard)\n");
+ fprintf(output, " --no-duplicate-keys If -T json is specified, merge duplicate keys in an object\n");
+ fprintf(output, " into a single key with as value a json array containing all\n");
+ fprintf(output, " values\n");
+ fprintf(output, " --elastic-mapping-filter <protocols> If -G elastic-mapping is specified, put only the\n");
+ fprintf(output, " specified protocols within the mapping file\n");
+ fprintf(output, " --temp-dir <directory> write temporary files to this directory\n");
+ fprintf(output, " (default: %s)\n", g_get_tmp_dir());
+ fprintf(output, "\n");
+
+ ws_log_print_usage(output);
+ 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, " -o <name>:<value> ... override preference setting\n");
+ fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
+ fprintf(output, " -G [report] dump one of several available reports and exit\n");
+ fprintf(output, " default report=\"fields\"\n");
+ fprintf(output, " use \"-G help\" for more help\n");
#ifdef __linux__
- fprintf(output, "\n");
- fprintf(output, "Dumpcap can benefit from an enabled BPF JIT compiler if available.\n");
- fprintf(output, "You might want to enable it by executing:\n");
- fprintf(output, " \"echo 1 > /proc/sys/net/core/bpf_jit_enable\"\n");
- fprintf(output, "Note that this can make your system less secure!\n");
+ fprintf(output, "\n");
+ fprintf(output, "Dumpcap can benefit from an enabled BPF JIT compiler if available.\n");
+ fprintf(output, "You might want to enable it by executing:\n");
+ fprintf(output, " \"echo 1 > /proc/sys/net/core/bpf_jit_enable\"\n");
+ fprintf(output, "Note that this can make your system less secure!\n");
#endif
}
@@ -510,83 +513,84 @@ print_usage(FILE *output)
static void
glossary_option_help(void)
{
- FILE *output;
-
- output = stdout;
-
- fprintf(output, "%s\n", get_appname_and_version());
-
- fprintf(output, "\n");
- fprintf(output, "Usage: tshark -G [report]\n");
- fprintf(output, "\n");
- fprintf(output, "Glossary table reports:\n");
- fprintf(output, " -G column-formats dump column format codes and exit\n");
- fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
- fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
- fprintf(output, " -G elastic-mapping dump ElasticSearch mapping file\n");
- fprintf(output, " -G fieldcount dump count of header fields and exit\n");
- fprintf(output, " -G fields dump fields glossary and exit\n");
- fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
- fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
- fprintf(output, " -G plugins dump installed plugins and exit\n");
- fprintf(output, " -G protocols dump protocols in registration database and exit\n");
- fprintf(output, " -G values dump value, range, true/false strings and exit\n");
- fprintf(output, "\n");
- fprintf(output, "Preference reports:\n");
- fprintf(output, " -G currentprefs dump current preferences and exit\n");
- fprintf(output, " -G defaultprefs dump default preferences and exit\n");
- fprintf(output, " -G folders dump about:folders\n");
- fprintf(output, "\n");
+ FILE *output;
+
+ output = stdout;
+
+ fprintf(output, "%s\n", get_appname_and_version());
+
+ fprintf(output, "\n");
+ fprintf(output, "Usage: tshark -G [report]\n");
+ fprintf(output, "\n");
+ fprintf(output, "Glossary table reports:\n");
+ fprintf(output, " -G column-formats dump column format codes and exit\n");
+ fprintf(output, " -G decodes dump \"layer type\"/\"decode as\" associations and exit\n");
+ fprintf(output, " -G dissector-tables dump dissector table names, types, and properties\n");
+ fprintf(output, " -G elastic-mapping dump ElasticSearch mapping file\n");
+ fprintf(output, " -G fieldcount dump count of header fields and exit\n");
+ fprintf(output, " -G fields dump fields glossary and exit\n");
+ fprintf(output, " -G ftypes dump field type basic and descriptive names\n");
+ fprintf(output, " -G heuristic-decodes dump heuristic dissector tables\n");
+ fprintf(output, " -G plugins dump installed plugins and exit\n");
+ fprintf(output, " -G protocols dump protocols in registration database and exit\n");
+ fprintf(output, " -G values dump value, range, true/false strings and exit\n");
+ fprintf(output, "\n");
+ fprintf(output, "Preference reports:\n");
+ fprintf(output, " -G currentprefs dump current preferences and exit\n");
+ fprintf(output, " -G defaultprefs dump default preferences and exit\n");
+ fprintf(output, " -G folders dump about:folders\n");
+ fprintf(output, "\n");
}
static void
hexdump_option_help(FILE *output)
{
- fprintf(output, "%s\n", get_appname_and_version());
- fprintf(output, "\n");
- fprintf(output, "tshark: Valid --hexdump <hexoption> values include:\n");
- fprintf(output, "\n");
- fprintf(output, "Data source options:\n");
- fprintf(output, " all add hexdump, dump all data sources (-x default)\n");
- fprintf(output, " frames add hexdump, dump only frame data source\n");
- fprintf(output, "\n");
- fprintf(output, "ASCII options:\n");
- fprintf(output, " ascii add hexdump, include ASCII dump text (-x default)\n");
- fprintf(output, " delimit add hexdump, delimit ASCII dump text with '|' characters\n");
- fprintf(output, " noascii add hexdump, exclude ASCII dump text\n");
- fprintf(output, "\n");
- fprintf(output, "Miscellaneous:\n");
- fprintf(output, " help display this help and exit\n");
- fprintf(output, "\n");
- fprintf(output, "Example:\n");
- fprintf(output, "\n");
- fprintf(output, " $ tshark ... --hexdump frames --hexdump delimit ...\n");
- fprintf(output, "\n");
+ fprintf(output, "%s\n", get_appname_and_version());
+ fprintf(output, "\n");
+ fprintf(output, "tshark: Valid --hexdump <hexoption> values include:\n");
+ fprintf(output, "\n");
+ fprintf(output, "Data source options:\n");
+ fprintf(output, " all add hexdump, dump all data sources (-x default)\n");
+ fprintf(output, " frames add hexdump, dump only frame data source\n");
+ fprintf(output, "\n");
+ fprintf(output, "ASCII options:\n");
+ fprintf(output, " ascii add hexdump, include ASCII dump text (-x default)\n");
+ fprintf(output, " delimit add hexdump, delimit ASCII dump text with '|' characters\n");
+ fprintf(output, " noascii add hexdump, exclude ASCII dump text\n");
+ fprintf(output, "\n");
+ fprintf(output, "Miscellaneous:\n");
+ fprintf(output, " help display this help and exit\n");
+ fprintf(output, "\n");
+ fprintf(output, "Example:\n");
+ fprintf(output, "\n");
+ fprintf(output, " $ tshark ... --hexdump frames --hexdump delimit ...\n");
+ fprintf(output, "\n");
}
static void
-print_current_user(void) {
- gchar *cur_user, *cur_group;
-
- if (started_with_special_privs()) {
- cur_user = get_cur_username();
- cur_group = get_cur_groupname();
- fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
- cur_user, cur_group);
- g_free(cur_user);
- g_free(cur_group);
- if (running_with_special_privs()) {
- fprintf(stderr, " This could be dangerous.");
+print_current_user(void)
+{
+ gchar *cur_user, *cur_group;
+
+ if (started_with_special_privs()) {
+ cur_user = get_cur_username();
+ cur_group = get_cur_groupname();
+ fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
+ cur_user, cur_group);
+ g_free(cur_user);
+ g_free(cur_group);
+ if (running_with_special_privs()) {
+ fprintf(stderr, " This could be dangerous.");
+ }
+ fprintf(stderr, "\n");
}
- fprintf(stderr, "\n");
- }
}
static void
get_tshark_compiled_version_info(GString *str)
{
- /* Capture libraries */
- get_compiled_caplibs_version(str);
+ /* Capture libraries */
+ get_compiled_caplibs_version(str);
}
static void
@@ -605,1840 +609,1840 @@ get_tshark_runtime_version_info(GString *str)
static void
about_folders(void)
{
- const char *constpath;
- char *path;
- gint i;
- gchar **resultArray;
+ const char *constpath;
+ char *path;
+ gint i;
+ gchar **resultArray;
- /* "file open" */
+ /* "file open" */
- /*
- * Fetching the "File" dialogs folder not implemented.
- * This is arguably just a pwd for a ui/cli .
- */
+ /*
+ * Fetching the "File" dialogs folder not implemented.
+ * This is arguably just a pwd for a ui/cli .
+ */
- /* temp */
- constpath = g_get_tmp_dir();
+ /* temp */
+ constpath = g_get_tmp_dir();
#ifdef HAVE_LIBPCAP
- /* global_capture_opts only exists in this case */
- if (global_capture_opts.temp_dir)
- constpath = global_capture_opts.temp_dir;
+ /* global_capture_opts only exists in this case */
+ if (global_capture_opts.temp_dir)
+ constpath = global_capture_opts.temp_dir;
#endif
- printf("%-21s\t%s\n", "Temp:", constpath);
+ printf("%-21s\t%s\n", "Temp:", constpath);
- /* pers conf */
- path = get_persconffile_path("", FALSE);
- printf("%-21s\t%s\n", "Personal configuration:", path);
- g_free(path);
+ /* pers conf */
+ path = get_persconffile_path("", FALSE);
+ printf("%-21s\t%s\n", "Personal configuration:", path);
+ g_free(path);
- /* global conf */
- constpath = get_datafile_dir();
- if (constpath != NULL) {
- printf("%-21s\t%s\n", "Global configuration:", constpath);
- }
+ /* global conf */
+ constpath = get_datafile_dir();
+ if (constpath != NULL) {
+ printf("%-21s\t%s\n", "Global configuration:", constpath);
+ }
- /* system */
- constpath = get_systemfile_dir();
- printf("%-21s\t%s\n", "System:", constpath);
+ /* system */
+ constpath = get_systemfile_dir();
+ printf("%-21s\t%s\n", "System:", constpath);
- /* program */
- constpath = get_progfile_dir();
- printf("%-21s\t%s\n", "Program:", constpath);
+ /* program */
+ constpath = get_progfile_dir();
+ printf("%-21s\t%s\n", "Program:", constpath);
#ifdef HAVE_PLUGINS
- /* pers plugins */
- printf("%-21s\t%s\n", "Personal Plugins:", get_plugins_pers_dir_with_version());
+ /* pers plugins */
+ printf("%-21s\t%s\n", "Personal Plugins:", get_plugins_pers_dir_with_version());
- /* global plugins */
- printf("%-21s\t%s\n", "Global Plugins:", get_plugins_dir_with_version());
+ /* global plugins */
+ printf("%-21s\t%s\n", "Global Plugins:", get_plugins_dir_with_version());
#endif
#ifdef HAVE_LUA
- /* pers lua plugins */
- printf("%-21s\t%s\n", "Personal Lua Plugins:", get_plugins_pers_dir());
+ /* pers lua plugins */
+ printf("%-21s\t%s\n", "Personal Lua Plugins:", get_plugins_pers_dir());
- /* global lua plugins */
- printf("%-21s\t%s\n", "Global Lua Plugins:", get_plugins_dir());
+ /* global lua plugins */
+ printf("%-21s\t%s\n", "Global Lua Plugins:", get_plugins_dir());
#endif
- /* Extcap */
- constpath = get_extcap_dir();
+ /* Extcap */
+ constpath = get_extcap_dir();
- resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S, 10);
- for(i = 0; resultArray[i]; i++)
- printf("%-21s\t%s\n", "Extcap path:", g_strstrip(resultArray[i]));
+ resultArray = g_strsplit(constpath, G_SEARCHPATH_SEPARATOR_S, 10);
+ for(i = 0; resultArray[i]; i++)
+ printf("%-21s\t%s\n", "Extcap path:", g_strstrip(resultArray[i]));
- g_strfreev(resultArray);
+ g_strfreev(resultArray);
- /* MaxMindDB */
- path = maxmind_db_get_paths();
+ /* MaxMindDB */
+ path = maxmind_db_get_paths();
- resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 10);
+ resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 10);
- for(i = 0; resultArray[i]; i++)
- printf("%-21s\t%s\n", "MaxMind database path:", g_strstrip(resultArray[i]));
+ for(i = 0; resultArray[i]; i++)
+ printf("%-21s\t%s\n", "MaxMind database path:", g_strstrip(resultArray[i]));
- g_strfreev(resultArray);
- g_free(path);
+ g_strfreev(resultArray);
+ g_free(path);
#ifdef HAVE_LIBSMI
- /* SMI MIBs/PIBs */
- path = oid_get_default_mib_path();
+ /* SMI MIBs/PIBs */
+ path = oid_get_default_mib_path();
- resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 20);
+ resultArray = g_strsplit(path, G_SEARCHPATH_SEPARATOR_S, 20);
- for(i = 0; resultArray[i]; i++)
- printf("%-21s\t%s\n", "MIB/PIB path:", g_strstrip(resultArray[i]));
+ for(i = 0; resultArray[i]; i++)
+ printf("%-21s\t%s\n", "MIB/PIB path:", g_strstrip(resultArray[i]));
- g_strfreev(resultArray);
- g_free(path);
+ g_strfreev(resultArray);
+ g_free(path);
#endif
}
static gboolean
must_do_dissection(dfilter_t *rfcode, dfilter_t *dfcode,
- gchar *volatile pdu_export_arg)
+ gchar *volatile pdu_export_arg)
{
- /* We have to dissect each packet if:
+ /* We have to dissect each packet if:
- we're printing information about each packet;
+ we're printing information about each packet;
- we're using a read filter on the packets;
+ we're using a read filter on the packets;
- we're using a display filter on the packets;
+ we're using a display filter on the packets;
- we're exporting PDUs;
+ we're exporting PDUs;
- we're using any taps that need dissection. */
- return print_packet_info || rfcode || dfcode || pdu_export_arg ||
- tap_listeners_require_dissection() || dissect_color;
+ we're using any taps that need dissection. */
+ return print_packet_info || rfcode || dfcode || pdu_export_arg ||
+ tap_listeners_require_dissection() || dissect_color;
}
int
main(int argc, char *argv[])
{
- char *err_msg;
- static const struct report_message_routines tshark_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'},
- LONGOPT_CAPTURE_COMMON
- LONGOPT_DISSECT_COMMON
- {"print", ws_no_argument, NULL, 'P'},
- {"export-objects", ws_required_argument, NULL, LONGOPT_EXPORT_OBJECTS},
- {"export-tls-session-keys", ws_required_argument, NULL, LONGOPT_EXPORT_TLS_SESSION_KEYS},
- {"color", ws_no_argument, NULL, LONGOPT_COLOR},
- {"no-duplicate-keys", ws_no_argument, NULL, LONGOPT_NO_DUPLICATE_KEYS},
- {"elastic-mapping-filter", ws_required_argument, NULL, LONGOPT_ELASTIC_MAPPING_FILTER},
- {"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
- {"hexdump", ws_required_argument, NULL, LONGOPT_HEXDUMP},
- {0, 0, 0, 0 }
- };
- gboolean arg_error = FALSE;
- gboolean has_extcap_options = FALSE;
-
- int err;
- gchar *err_info;
- gboolean exp_pdu_status;
- volatile process_file_status_t status;
- volatile gboolean draw_taps = FALSE;
- volatile int exit_status = EXIT_SUCCESS;
+ char *err_msg;
+ static const struct report_message_routines tshark_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'},
+ LONGOPT_CAPTURE_COMMON
+ LONGOPT_DISSECT_COMMON
+ {"print", ws_no_argument, NULL, 'P'},
+ {"export-objects", ws_required_argument, NULL, LONGOPT_EXPORT_OBJECTS},
+ {"export-tls-session-keys", ws_required_argument, NULL, LONGOPT_EXPORT_TLS_SESSION_KEYS},
+ {"color", ws_no_argument, NULL, LONGOPT_COLOR},
+ {"no-duplicate-keys", ws_no_argument, NULL, LONGOPT_NO_DUPLICATE_KEYS},
+ {"elastic-mapping-filter", ws_required_argument, NULL, LONGOPT_ELASTIC_MAPPING_FILTER},
+ {"capture-comment", ws_required_argument, NULL, LONGOPT_CAPTURE_COMMENT},
+ {"hexdump", ws_required_argument, NULL, LONGOPT_HEXDUMP},
+ {0, 0, 0, 0}
+ };
+ gboolean arg_error = FALSE;
+ gboolean has_extcap_options = FALSE;
+
+ int err;
+ gchar *err_info;
+ gboolean exp_pdu_status;
+ volatile process_file_status_t status;
+ volatile gboolean draw_taps = FALSE;
+ volatile int exit_status = EXIT_SUCCESS;
#ifdef HAVE_LIBPCAP
- int caps_queries = 0;
- GList *if_list;
- gchar *err_str, *err_str_secondary;
- struct bpf_program fcode;
+ int caps_queries = 0;
+ GList *if_list;
+ gchar *err_str, *err_str_secondary;
+ struct bpf_program fcode;
#else
- gboolean capture_option_specified = FALSE;
- volatile int max_packet_count = 0;
+ gboolean capture_option_specified = FALSE;
+ volatile int max_packet_count = 0;
#endif
- volatile int out_file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
- volatile gboolean out_file_name_res = FALSE;
- volatile int in_file_type = WTAP_TYPE_AUTO;
- gchar *volatile cf_name = NULL;
- gchar *rfilter = NULL;
- gchar *volatile dfilter = NULL;
- dfilter_t *rfcode = NULL;
- dfilter_t *dfcode = NULL;
- e_prefs *prefs_p;
- gchar *output_only = NULL;
- gchar *volatile pdu_export_arg = NULL;
- char *volatile exp_pdu_filename = NULL;
- const gchar *volatile tls_session_keys_file = NULL;
- exp_pdu_t exp_pdu_tap_data;
- const gchar* elastic_mapping_filter = NULL;
+ volatile int out_file_type = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
+ volatile gboolean out_file_name_res = FALSE;
+ volatile int in_file_type = WTAP_TYPE_AUTO;
+ gchar *volatile cf_name = NULL;
+ gchar *rfilter = NULL;
+ gchar *volatile dfilter = NULL;
+ dfilter_t *rfcode = NULL;
+ dfilter_t *dfcode = NULL;
+ e_prefs *prefs_p;
+ gchar *output_only = NULL;
+ gchar *volatile pdu_export_arg = NULL;
+ char *volatile exp_pdu_filename = NULL;
+ const gchar *volatile tls_session_keys_file = NULL;
+ exp_pdu_t exp_pdu_tap_data;
+ const gchar* elastic_mapping_filter = NULL;
-/*
- * 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 "+2" OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON "M:C:e:E:F:gG:hH:j:J:lo:O:PqQr:R:S:T:U:vVw:W:xX:Y:z:"
- static const char optstring[] = OPTSTRING;
+ static const char optstring[] = OPTSTRING;
- /*
- * 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(tshark_cmdarg_err, tshark_cmdarg_err_cont);
+ cmdarg_err_init(tshark_cmdarg_err, tshark_cmdarg_err_cont);
- /* Initialize log handler early so we can have proper logging during startup. */
- ws_log_init("tshark", vcmdarg_err);
+ /* Initialize log handler early so we can have proper logging during startup. */
+ ws_log_init("tshark", 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);
- ws_debug("tshark started with %d args", argc);
+ ws_debug("tshark started with %d args", argc);
#ifdef _WIN32
- create_app_running_mutex();
+ create_app_running_mutex();
#endif /* _WIN32 */
- /*
- * Get credential information for later use, and drop privileges
- * before doing anything else.
- * Let the user know if anything happened.
- */
- init_process_policies();
- relinquish_special_privs_perm();
- print_current_user();
-
- /*
- * Attempt to get the pathname of the directory containing the
- * executable file.
- */
- err_msg = init_progfile_dir(argv[0]);
- if (err_msg != NULL) {
- fprintf(stderr,
- "tshark: Can't get pathname of directory containing the tshark program: %s.\n"
- "It won't be possible to capture traffic.\n"
- "Report this to the Wireshark developers.",
- err_msg);
- g_free(err_msg);
- }
-
- initialize_funnel_ops();
+ /*
+ * Get credential information for later use, and drop privileges
+ * before doing anything else.
+ * Let the user know if anything happened.
+ */
+ init_process_policies();
+ relinquish_special_privs_perm();
+ print_current_user();
+
+ /*
+ * Attempt to get the pathname of the directory containing the
+ * executable file.
+ */
+ err_msg = init_progfile_dir(argv[0]);
+ if (err_msg != NULL) {
+ fprintf(stderr,
+ "tshark: Can't get pathname of directory containing the tshark program: %s.\n"
+ "It won't be possible to capture traffic.\n"
+ "Report this to the Wireshark developers.",
+ err_msg);
+ g_free(err_msg);
+ }
+
+ initialize_funnel_ops();
#ifdef _WIN32
- ws_init_dll_search_path();
+ ws_init_dll_search_path();
#ifdef HAVE_LIBPCAP
- /* Load wpcap if possible. Do this before collecting the run-time version information */
- load_wpcap();
+ /* Load wpcap if possible. Do this before collecting the run-time version information */
+ load_wpcap();
#endif /* HAVE_LIBPCAP */
#endif /* _WIN32 */
- /* Initialize the version information. */
- ws_init_version_info("TShark (Wireshark)", get_tshark_compiled_version_info,
- epan_get_compiled_version_info,
- get_tshark_runtime_version_info);
-
- /* Fail sometimes. Useful for testing fuzz scripts. */
- /* if (g_random_int_range(0, 100) < 5) abort(); */
-
- /*
- * In order to have the -X opts assigned before the wslua machine starts
- * we need to call getopt_long before epan_init() gets called.
- *
- * In order to handle, for example, -o options, we also need to call it
- * *after* epan_init() gets called, so that the dissectors have had a
- * chance to register their preferences.
- *
- * Spawning a bunch of extcap processes can delay program startup,
- * particularly on Windows. Check to see if we have any options that
- * might require extcap and set has_extcap_options = TRUE if that's
- * the case.
- *
- * XXX - can we do this all with one getopt_long() call, saving the
- * arguments we can't handle until after initializing libwireshark,
- * and then process them after initializing libwireshark?
- */
- ws_opterr = 0;
-
- while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
- switch (opt) {
- case 'C': /* Configuration Profile */
- if (profile_exists (ws_optarg, FALSE)) {
- set_profile_name (ws_optarg);
- } else {
- cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- case 'G':
- if (g_str_has_suffix(ws_optarg, "prefs") || strcmp(ws_optarg, "folders") == 0) {
- has_extcap_options = TRUE;
- }
- break;
- case 'i':
- has_extcap_options = TRUE;
- break;
- case 'o':
- if (g_str_has_prefix(ws_optarg, "extcap.")) {
- has_extcap_options = TRUE;
- }
- break;
- case 'P': /* Print packet summary info even when writing to a file */
- print_packet_info = TRUE;
- print_summary = TRUE;
- break;
- case 'r': /* Read capture file x */
- cf_name = g_strdup(ws_optarg);
- break;
- case 'O': /* Only output these protocols */
- output_only = g_strdup(ws_optarg);
- /* FALLTHROUGH */
- case 'V': /* Verbose */
- print_details = TRUE;
- print_packet_info = TRUE;
- break;
- case 'x': /* Print packet data in hex (and ASCII) */
- print_hex = TRUE;
- /* The user asked for hex output, so let's ensure they get it,
- * even if they're writing to a file.
- */
- print_packet_info = TRUE;
- break;
- case 'X':
- ex_opt_add(ws_optarg);
- break;
- case LONGOPT_ELASTIC_MAPPING_FILTER:
- elastic_mapping_filter = ws_optarg;
- break;
- default:
- break;
+ /* Initialize the version information. */
+ ws_init_version_info("TShark (Wireshark)", get_tshark_compiled_version_info,
+ epan_get_compiled_version_info,
+ get_tshark_runtime_version_info);
+
+ /* Fail sometimes. Useful for testing fuzz scripts. */
+ /* if (g_random_int_range(0, 100) < 5) abort(); */
+
+ /*
+ * In order to have the -X opts assigned before the wslua machine starts
+ * we need to call getopt_long before epan_init() gets called.
+ *
+ * In order to handle, for example, -o options, we also need to call it
+ * *after* epan_init() gets called, so that the dissectors have had a
+ * chance to register their preferences.
+ *
+ * Spawning a bunch of extcap processes can delay program startup,
+ * particularly on Windows. Check to see if we have any options that
+ * might require extcap and set has_extcap_options = TRUE if that's
+ * the case.
+ *
+ * XXX - can we do this all with one getopt_long() call, saving the
+ * arguments we can't handle until after initializing libwireshark,
+ * and then process them after initializing libwireshark?
+ */
+ ws_opterr = 0;
+
+ while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
+ switch (opt) {
+ case 'C': /* Configuration Profile */
+ if (profile_exists (ws_optarg, FALSE)) {
+ set_profile_name (ws_optarg);
+ } else {
+ cmdarg_err("Configuration Profile \"%s\" does not exist", ws_optarg);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case 'G':
+ if (g_str_has_suffix(ws_optarg, "prefs") || strcmp(ws_optarg, "folders") == 0) {
+ has_extcap_options = TRUE;
+ }
+ break;
+ case 'i':
+ has_extcap_options = TRUE;
+ break;
+ case 'o':
+ if (g_str_has_prefix(ws_optarg, "extcap.")) {
+ has_extcap_options = TRUE;
+ }
+ break;
+ case 'P': /* Print packet summary info even when writing to a file */
+ print_packet_info = TRUE;
+ print_summary = TRUE;
+ break;
+ case 'r': /* Read capture file x */
+ cf_name = g_strdup(ws_optarg);
+ break;
+ case 'O': /* Only output these protocols */
+ output_only = g_strdup(ws_optarg);
+ /* FALLTHROUGH */
+ case 'V': /* Verbose */
+ print_details = TRUE;
+ print_packet_info = TRUE;
+ break;
+ case 'x': /* Print packet data in hex (and ASCII) */
+ print_hex = TRUE;
+ /* The user asked for hex output, so let's ensure they get it,
+ * even if they're writing to a file.
+ */
+ print_packet_info = TRUE;
+ break;
+ case 'X':
+ ex_opt_add(ws_optarg);
+ break;
+ case LONGOPT_ELASTIC_MAPPING_FILTER:
+ elastic_mapping_filter = ws_optarg;
+ break;
+ default:
+ break;
+ }
}
- }
#ifndef HAVE_LUA
- if (ex_opt_count("lua_script") > 0) {
- cmdarg_err("This version of TShark was not built with support for Lua scripting.");
- exit_status = INIT_FAILED;
- goto clean_exit;
- }
+ if (ex_opt_count("lua_script") > 0) {
+ cmdarg_err("This version of TShark was not built with support for Lua scripting.");
+ exit_status = INIT_FAILED;
+ goto clean_exit;
+ }
#endif /* HAVE_LUA */
- init_report_message("TShark", &tshark_report_routines);
+ init_report_message("TShark", &tshark_report_routines);
#ifdef HAVE_LIBPCAP
- capture_opts_init(&global_capture_opts);
- capture_session_init(&global_capture_session, &cfile,
- capture_input_new_file, capture_input_new_packets,
- capture_input_drops, capture_input_error,
- capture_input_cfilter_error, capture_input_closed);
+ capture_opts_init(&global_capture_opts);
+ capture_session_init(&global_capture_session, &cfile,
+ capture_input_new_file, capture_input_new_packets,
+ capture_input_drops, capture_input_error,
+ capture_input_cfilter_error, capture_input_closed);
#endif
- timestamp_set_type(TS_RELATIVE);
- timestamp_set_precision(TS_PREC_AUTO);
- timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
-
- /*
- * Libwiretap must be initialized before libwireshark is, so that
- * dissection-time handlers for file-type-dependent blocks can
- * register using the file type/subtype value for the file type.
- */
- wtap_init(TRUE);
-
- /* Register all dissectors; we must do this before checking for the
- "-G" flag, as the "-G" flag dumps information registered by the
- dissectors, and we must do it before we read the preferences, in
- case any dissectors register preferences. */
- if (!epan_init(NULL, NULL, TRUE)) {
- exit_status = INIT_FAILED;
- goto clean_exit;
- }
-
- /* Register all tap listeners; we do this before we parse the arguments,
- as the "-z" argument can specify a registered tap. */
-
- register_all_tap_listeners(tap_reg_listener);
-
- /*
- * An empty cf_name indicates that we're capturing, and we might
- * be doing so on an extcap interface.
- */
- if (has_extcap_options || !cf_name) {
- extcap_register_preferences();
- }
-
- conversation_table_set_gui_info(init_iousers);
- hostlist_table_set_gui_info(init_hostlists);
- srt_table_iterate_tables(register_srt_tables, NULL);
- rtd_table_iterate_tables(register_rtd_tables, NULL);
- stat_tap_iterate_tables(register_simple_stat_tables, NULL);
-
- /* If invoked with the "-G" flag, we dump out information based on
- the argument to the "-G" flag; if no argument is specified,
- for backwards compatibility we dump out a glossary of display
- filter symbols.
-
- XXX - we do this here, for now, to support "-G" with no arguments.
- If none of our build or other processes uses "-G" with no arguments,
- we can just process it with the other arguments. */
- if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
- proto_initialize_all_prefixes();
-
- if (argc == 2)
- proto_registrar_dump_fields();
- else {
- if (strcmp(argv[2], "column-formats") == 0)
- column_dump_column_formats();
- else if (strcmp(argv[2], "currentprefs") == 0) {
- epan_load_settings();
- write_prefs(NULL);
- }
- else if (strcmp(argv[2], "decodes") == 0)
- dissector_dump_decodes();
- else if (strcmp(argv[2], "defaultprefs") == 0)
- write_prefs(NULL);
- else if (strcmp(argv[2], "dissector-tables") == 0)
- dissector_dump_dissector_tables();
- else if (strcmp(argv[2], "elastic-mapping") == 0)
- proto_registrar_dump_elastic(elastic_mapping_filter);
- else if (strcmp(argv[2], "fieldcount") == 0) {
- /* return value for the test suite */
- exit_status = proto_registrar_dump_fieldcount();
+ timestamp_set_type(TS_RELATIVE);
+ timestamp_set_precision(TS_PREC_AUTO);
+ timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
+
+ /*
+ * Libwiretap must be initialized before libwireshark is, so that
+ * dissection-time handlers for file-type-dependent blocks can
+ * register using the file type/subtype value for the file type.
+ */
+ wtap_init(TRUE);
+
+ /* Register all dissectors; we must do this before checking for the
+ "-G" flag, as the "-G" flag dumps information registered by the
+ dissectors, and we must do it before we read the preferences, in
+ case any dissectors register preferences. */
+ if (!epan_init(NULL, NULL, TRUE)) {
+ exit_status = INIT_FAILED;
goto clean_exit;
- } else if (strcmp(argv[2], "fields") == 0)
- proto_registrar_dump_fields();
- else if (strcmp(argv[2], "folders") == 0) {
- epan_load_settings();
- about_folders();
- } else if (strcmp(argv[2], "ftypes") == 0)
- proto_registrar_dump_ftypes();
- else if (strcmp(argv[2], "heuristic-decodes") == 0)
- dissector_dump_heur_decodes();
- else if (strcmp(argv[2], "plugins") == 0) {
+ }
+
+ /* Register all tap listeners; we do this before we parse the arguments,
+ as the "-z" argument can specify a registered tap. */
+
+ register_all_tap_listeners(tap_reg_listener);
+
+ /*
+ * An empty cf_name indicates that we're capturing, and we might
+ * be doing so on an extcap interface.
+ */
+ if (has_extcap_options || !cf_name) {
+ extcap_register_preferences();
+ }
+
+ conversation_table_set_gui_info(init_iousers);
+ hostlist_table_set_gui_info(init_hostlists);
+ srt_table_iterate_tables(register_srt_tables, NULL);
+ rtd_table_iterate_tables(register_rtd_tables, NULL);
+ stat_tap_iterate_tables(register_simple_stat_tables, NULL);
+
+ /* If invoked with the "-G" flag, we dump out information based on
+ the argument to the "-G" flag; if no argument is specified,
+ for backwards compatibility we dump out a glossary of display
+ filter symbols.
+
+ XXX - we do this here, for now, to support "-G" with no arguments.
+ If none of our build or other processes uses "-G" with no arguments,
+ we can just process it with the other arguments. */
+ if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
+ proto_initialize_all_prefixes();
+
+ if (argc == 2)
+ proto_registrar_dump_fields();
+ else {
+ if (strcmp(argv[2], "column-formats") == 0)
+ column_dump_column_formats();
+ else if (strcmp(argv[2], "currentprefs") == 0) {
+ epan_load_settings();
+ write_prefs(NULL);
+ }
+ else if (strcmp(argv[2], "decodes") == 0)
+ dissector_dump_decodes();
+ else if (strcmp(argv[2], "defaultprefs") == 0)
+ write_prefs(NULL);
+ else if (strcmp(argv[2], "dissector-tables") == 0)
+ dissector_dump_dissector_tables();
+ else if (strcmp(argv[2], "elastic-mapping") == 0)
+ proto_registrar_dump_elastic(elastic_mapping_filter);
+ else if (strcmp(argv[2], "fieldcount") == 0) {
+ /* return value for the test suite */
+ exit_status = proto_registrar_dump_fieldcount();
+ goto clean_exit;
+ } else if (strcmp(argv[2], "fields") == 0)
+ proto_registrar_dump_fields();
+ else if (strcmp(argv[2], "folders") == 0) {
+ epan_load_settings();
+ about_folders();
+ } else if (strcmp(argv[2], "ftypes") == 0)
+ proto_registrar_dump_ftypes();
+ else if (strcmp(argv[2], "heuristic-decodes") == 0)
+ dissector_dump_heur_decodes();
+ else if (strcmp(argv[2], "plugins") == 0) {
#ifdef HAVE_PLUGINS
- plugins_dump_all();
+ plugins_dump_all();
#endif
#ifdef HAVE_LUA
- wslua_plugins_dump_all();
+ wslua_plugins_dump_all();
#endif
- extcap_dump_all();
- }
- else if (strcmp(argv[2], "protocols") == 0)
- proto_registrar_dump_protocols();
- else if (strcmp(argv[2], "values") == 0)
- proto_registrar_dump_values();
- else if (strcmp(argv[2], "help") == 0)
- glossary_option_help();
- /* These are supported only for backwards compatibility and may or may not work
- * for a given user in a given directory on a given operating system with a given
- * command-line interpreter.
- */
- else if (strcmp(argv[2], "?") == 0)
- glossary_option_help();
- else if (strcmp(argv[2], "-?") == 0)
- glossary_option_help();
- else {
- cmdarg_err("Invalid \"%s\" option for -G flag, enter -G help for more help.", argv[2]);
- exit_status = INVALID_OPTION;
+ extcap_dump_all();
+ }
+ else if (strcmp(argv[2], "protocols") == 0)
+ proto_registrar_dump_protocols();
+ else if (strcmp(argv[2], "values") == 0)
+ proto_registrar_dump_values();
+ else if (strcmp(argv[2], "help") == 0)
+ glossary_option_help();
+ /* These are supported only for backwards compatibility and may or may not work
+ * for a given user in a given directory on a given operating system with a given
+ * command-line interpreter.
+ */
+ else if (strcmp(argv[2], "?") == 0)
+ glossary_option_help();
+ else if (strcmp(argv[2], "-?") == 0)
+ glossary_option_help();
+ else {
+ cmdarg_err("Invalid \"%s\" option for -G flag, enter -G help for more help.", argv[2]);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ }
+ exit_status = EXIT_SUCCESS;
goto clean_exit;
- }
}
- exit_status = EXIT_SUCCESS;
- goto clean_exit;
- }
-
- ws_debug("tshark reading settings");
-
- /* Load libwireshark settings from the current profile. */
- prefs_p = epan_load_settings();
- prefs_loaded = TRUE;
-
- read_filter_list(CFILTER_LIST);
-
- cap_file_init(&cfile);
-
- /* Print format defaults to this. */
- print_format = PR_FMT_TEXT;
- delimiter_char = " ";
-
- output_fields = output_fields_new();
-
- /*
- * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
- *
- * Also reset ws_opterr to 1, so that error messages are printed by
- * getopt_long().
- */
- ws_optreset = 1;
- ws_optind = 1;
- ws_opterr = 1;
-
- /* Now get our args */
- while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
- switch (opt) {
- case '2': /* Perform two pass analysis */
- if(epan_auto_reset){
- cmdarg_err("-2 does not support auto session reset.");
- arg_error=TRUE;
- }
- perform_two_pass_analysis = TRUE;
- break;
- case 'M':
- if(perform_two_pass_analysis){
- cmdarg_err("-M does not support two pass analysis.");
- arg_error=TRUE;
- }
- epan_auto_reset_count = get_positive_int(ws_optarg, "epan reset count");
- epan_auto_reset = TRUE;
- break;
- case 'a': /* autostop criteria */
- case 'b': /* Ringbuffer option */
- case 'f': /* capture filter */
- case 'g': /* enable group read access on file(s) */
- case 'i': /* Use interface x */
- case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
- case 'p': /* Don't capture in promiscuous mode */
+
+ ws_debug("tshark reading settings");
+
+ /* Load libwireshark settings from the current profile. */
+ prefs_p = epan_load_settings();
+ prefs_loaded = TRUE;
+
+ read_filter_list(CFILTER_LIST);
+
+ cap_file_init(&cfile);
+
+ /* Print format defaults to this. */
+ print_format = PR_FMT_TEXT;
+ delimiter_char = " ";
+
+ output_fields = output_fields_new();
+
+ /*
+ * To reset the options parser, set ws_optreset to 1 and set ws_optind to 1.
+ *
+ * Also reset ws_opterr to 1, so that error messages are printed by
+ * getopt_long().
+ */
+ ws_optreset = 1;
+ ws_optind = 1;
+ ws_opterr = 1;
+
+ /* Now get our args */
+ while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
+ switch (opt) {
+ case '2': /* Perform two pass analysis */
+ if(epan_auto_reset){
+ cmdarg_err("-2 does not support auto session reset.");
+ arg_error=TRUE;
+ }
+ perform_two_pass_analysis = TRUE;
+ break;
+ case 'M':
+ if(perform_two_pass_analysis){
+ cmdarg_err("-M does not support two pass analysis.");
+ arg_error=TRUE;
+ }
+ epan_auto_reset_count = get_positive_int(ws_optarg, "epan reset count");
+ epan_auto_reset = TRUE;
+ break;
+ case 'a': /* autostop criteria */
+ case 'b': /* Ringbuffer option */
+ case 'f': /* capture filter */
+ case 'g': /* enable group read access on file(s) */
+ case 'i': /* Use interface x */
+ case LONGOPT_SET_TSTAMP_TYPE: /* Set capture timestamp type */
+ case 'p': /* Don't capture in promiscuous mode */
#ifdef HAVE_PCAP_REMOTE
- case 'A': /* Authentication */
+ case 'A': /* Authentication */
#endif
#ifdef HAVE_PCAP_CREATE
- case 'I': /* Capture in monitor mode, if available */
+ case 'I': /* Capture in monitor mode, if available */
#endif
- case 's': /* Set the snapshot (capture) length */
- case 'y': /* Set the pcap data link type */
+ case 's': /* Set the snapshot (capture) length */
+ case 'y': /* Set the pcap data link type */
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
- case 'B': /* Buffer size */
+ case 'B': /* Buffer size */
#endif
- case LONGOPT_COMPRESS_TYPE: /* compress type */
- case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
- /* These are options only for packet capture. */
+ case LONGOPT_COMPRESS_TYPE: /* compress type */
+ case LONGOPT_CAPTURE_TMPDIR: /* capture temp directory */
+ /* These are options only for packet capture. */
#ifdef HAVE_LIBPCAP
- exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
- if (exit_status != 0) {
- goto clean_exit;
- }
+ exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
+ if (exit_status != 0) {
+ goto clean_exit;
+ }
#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
#endif
- break;
- case 'c': /* Stop after x packets */
+ break;
+ case 'c': /* Stop after x packets */
#ifdef HAVE_LIBPCAP
- exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
- if (exit_status != 0) {
- goto clean_exit;
- }
+ exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
+ if (exit_status != 0) {
+ goto clean_exit;
+ }
#else
- max_packet_count = get_positive_int(ws_optarg, "packet count");
+ max_packet_count = get_positive_int(ws_optarg, "packet count");
#endif
- break;
- case 'w': /* Write to file x */
- output_file_name = g_strdup(ws_optarg);
+ break;
+ case 'w': /* Write to file x */
+ output_file_name = g_strdup(ws_optarg);
#ifdef HAVE_LIBPCAP
- exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
- if (exit_status != 0) {
- goto clean_exit;
- }
+ exit_status = capture_opts_add_opt(&global_capture_opts, opt, ws_optarg);
+ if (exit_status != 0) {
+ goto clean_exit;
+ }
#endif
- break;
- case 'C':
- /* already processed; just ignore it now */
- break;
- case 'D': /* Print a list of capture devices and exit */
+ break;
+ case 'C':
+ /* already processed; just ignore it now */
+ break;
+ case 'D': /* Print a list of capture devices and exit */
#ifdef HAVE_LIBPCAP
- if_list = capture_interface_list(&err, &err_str,NULL);
- if (if_list == NULL) {
- if (err == 0)
- cmdarg_err("There are no interfaces on which a capture can be done");
- else {
- cmdarg_err("%s", err_str);
- g_free(err_str);
- }
- exit_status = INVALID_INTERFACE;
- goto clean_exit;
- }
- capture_opts_print_interfaces(if_list);
- free_interface_list(if_list);
- exit_status = EXIT_SUCCESS;
- goto clean_exit;
+ if_list = capture_interface_list(&err, &err_str,NULL);
+ if (if_list == NULL) {
+ if (err == 0)
+ cmdarg_err("There are no interfaces on which a capture can be done");
+ else {
+ cmdarg_err("%s", err_str);
+ g_free(err_str);
+ }
+ exit_status = INVALID_INTERFACE;
+ goto clean_exit;
+ }
+ capture_opts_print_interfaces(if_list);
+ free_interface_list(if_list);
+ exit_status = EXIT_SUCCESS;
+ goto clean_exit;
#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
#endif
- break;
- case 'e':
- /* Field entry */
- output_fields_add(output_fields, ws_optarg);
- break;
- case 'E':
- /* Field option */
- if (!output_fields_set_option(output_fields, ws_optarg)) {
- cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg);
- output_fields_list_options(stderr);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- case 'F':
- out_file_type = wtap_name_to_file_type_subtype(ws_optarg);
- if (out_file_type < 0) {
- cmdarg_err("\"%s\" isn't a valid capture file type", ws_optarg);
- list_capture_types();
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- case 'j':
- if (protocolfilter) {
- cmdarg_err("-j or -J was already specified! Overwriting previous protocol filter");
- }
- protocolfilter = wmem_strsplit(wmem_epan_scope(), ws_optarg, " ", -1);
- break;
- case 'J':
- if (protocolfilter) {
- cmdarg_err("-j or -J was already specified! Overwriting previous protocol filter");
- }
- protocolfilter_flags = PF_INCLUDE_CHILDREN;
- protocolfilter = wmem_strsplit(wmem_epan_scope(), ws_optarg, " ", -1);
- break;
- case 'W': /* Select extra information to save in our capture file */
- /* This is patterned after the -N flag which may not be the best idea. */
- if (strchr(ws_optarg, 'n')) {
- out_file_name_res = TRUE;
- } else {
- cmdarg_err("Invalid -W argument \"%s\"; it must be one of:", ws_optarg);
- cmdarg_err_cont("\t'n' write network address resolution information (pcapng only)");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- case 'H': /* Read address to name mappings from a hosts file */
- if (! add_hosts_file(ws_optarg))
- {
- cmdarg_err("Can't read host entries from \"%s\"", ws_optarg);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- out_file_name_res = TRUE;
- break;
-
- case 'h': /* Print help and exit */
- show_help_header("Dump and analyze network traffic.");
- print_usage(stdout);
- exit_status = EXIT_SUCCESS;
- goto clean_exit;
- break;
- case 'l': /* "Line-buffer" standard output */
- /* The ANSI C standard does not appear to *require* that a line-buffered
- stream be flushed to the host environment whenever a newline is
- written, it just says that, on such a stream, characters "are
- intended to be transmitted to or from the host environment as a
- block when a new-line character is encountered".
-
- The Visual C++ 6.0 C implementation doesn't do what is intended;
- even if you set a stream to be line-buffered, it still doesn't
- flush the buffer at the end of every line.
-
- The whole reason for the "-l" flag in either tcpdump or TShark
- is to allow the output of a live capture to be piped to a program
- or script and to have that script see the information for the
- packet as soon as it's printed, rather than having to wait until
- a standard I/O buffer fills up.
-
- So, if the "-l" flag is specified, we flush the standard output
- at the end of a packet. This will do the right thing if we're
- printing packet summary lines, and, as we print the entire protocol
- tree for a single packet without waiting for anything to happen,
- it should be as good as line-buffered mode if we're printing
- protocol trees - arguably even better, as it may do fewer
- writes. */
- line_buffered = TRUE;
- break;
- case 'L': /* Print list of link-layer types and exit */
+ break;
+ case 'e':
+ /* Field entry */
+ output_fields_add(output_fields, ws_optarg);
+ break;
+ case 'E':
+ /* Field option */
+ if (!output_fields_set_option(output_fields, ws_optarg)) {
+ cmdarg_err("\"%s\" is not a valid field output option=value pair.", ws_optarg);
+ output_fields_list_options(stderr);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case 'F':
+ out_file_type = wtap_name_to_file_type_subtype(ws_optarg);
+ if (out_file_type < 0) {
+ cmdarg_err("\"%s\" isn't a valid capture file type", ws_optarg);
+ list_capture_types();
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case 'j':
+ if (protocolfilter) {
+ cmdarg_err("-j or -J was already specified! Overwriting previous protocol filter");
+ }
+ protocolfilter = wmem_strsplit(wmem_epan_scope(), ws_optarg, " ", -1);
+ break;
+ case 'J':
+ if (protocolfilter) {
+ cmdarg_err("-j or -J was already specified! Overwriting previous protocol filter");
+ }
+ protocolfilter_flags = PF_INCLUDE_CHILDREN;
+ protocolfilter = wmem_strsplit(wmem_epan_scope(), ws_optarg, " ", -1);
+ break;
+ case 'W': /* Select extra information to save in our capture file */
+ /* This is patterned after the -N flag which may not be the best idea. */
+ if (strchr(ws_optarg, 'n')) {
+ out_file_name_res = TRUE;
+ } else {
+ cmdarg_err("Invalid -W argument \"%s\"; it must be one of:", ws_optarg);
+ cmdarg_err_cont("\t'n' write network address resolution information (pcapng only)");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case 'H': /* Read address to name mappings from a hosts file */
+ if (! add_hosts_file(ws_optarg))
+ {
+ cmdarg_err("Can't read host entries from \"%s\"", ws_optarg);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ out_file_name_res = TRUE;
+ break;
+
+ case 'h': /* Print help and exit */
+ show_help_header("Dump and analyze network traffic.");
+ print_usage(stdout);
+ exit_status = EXIT_SUCCESS;
+ goto clean_exit;
+ break;
+ case 'l': /* "Line-buffer" standard output */
+ /* The ANSI C standard does not appear to *require* that a line-buffered
+ stream be flushed to the host environment whenever a newline is
+ written, it just says that, on such a stream, characters "are
+ intended to be transmitted to or from the host environment as a
+ block when a new-line character is encountered".
+
+ The Visual C++ 6.0 C implementation doesn't do what is intended;
+ even if you set a stream to be line-buffered, it still doesn't
+ flush the buffer at the end of every line.
+
+ The whole reason for the "-l" flag in either tcpdump or TShark
+ is to allow the output of a live capture to be piped to a program
+ or script and to have that script see the information for the
+ packet as soon as it's printed, rather than having to wait until
+ a standard I/O buffer fills up.
+
+ So, if the "-l" flag is specified, we flush the standard output
+ at the end of a packet. This will do the right thing if we're
+ printing packet summary lines, and, as we print the entire protocol
+ tree for a single packet without waiting for anything to happen,
+ it should be as good as line-buffered mode if we're printing
+ protocol trees - arguably even better, as it may do fewer
+ writes. */
+ line_buffered = TRUE;
+ break;
+ case 'L': /* Print list of link-layer types and exit */
#ifdef HAVE_LIBPCAP
- caps_queries |= CAPS_QUERY_LINK_TYPES;
+ caps_queries |= CAPS_QUERY_LINK_TYPES;
#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
#endif
- break;
- case LONGOPT_LIST_TSTAMP_TYPES: /* List possible timestamp types */
+ break;
+ case LONGOPT_LIST_TSTAMP_TYPES: /* List possible timestamp types */
#ifdef HAVE_LIBPCAP
- caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
+ caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
#else
- capture_option_specified = TRUE;
- arg_error = TRUE;
+ capture_option_specified = TRUE;
+ arg_error = TRUE;
#endif
- break;
- case 'o': /* Override preference from command line */
- {
- char *errmsg = NULL;
-
- switch (prefs_set_pref(ws_optarg, &errmsg)) {
+ break;
+ case 'o': /* Override preference from command line */
+ {
+ char *errmsg = NULL;
+
+ switch (prefs_set_pref(ws_optarg, &errmsg)) {
+
+ case PREFS_SET_OK:
+ break;
+
+ case PREFS_SET_SYNTAX_ERR:
+ cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
+ errmsg ? ": " : "", errmsg ? errmsg : "");
+ g_free(errmsg);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ break;
+
+ case PREFS_SET_NO_SUCH_PREF:
+ cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ break;
+
+ case PREFS_SET_OBSOLETE:
+ cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ break;
+ }
+ break;
+ }
+ case 'q': /* Quiet */
+ quiet = TRUE;
+ break;
+ case 'Q': /* Really quiet */
+ quiet = TRUE;
+ really_quiet = TRUE;
+ break;
+ case 'r':
+ /* already processed; just ignore it now */
+ break;
+ case 'R': /* Read file filter */
+ rfilter = ws_optarg;
+ break;
+ case 'P':
+ /* already processed; just ignore it now */
+ break;
+ case 'S': /* Set the line Separator to be printed between packets */
+ separator = ws_optarg;
+ break;
+ case 'T': /* printing Type */
+ /* output_action has been already set. It means multiple -T. */
+ if (output_action > WRITE_NONE) {
+ cmdarg_err("Multiple -T parameters are unsupported");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ print_packet_info = TRUE;
+ if (strcmp(ws_optarg, "text") == 0) {
+ output_action = WRITE_TEXT;
+ print_format = PR_FMT_TEXT;
+ } else if (strcmp(ws_optarg, "tabs") == 0) {
+ output_action = WRITE_TEXT;
+ print_format = PR_FMT_TEXT;
+ delimiter_char = "\t";
+ } else if (strcmp(ws_optarg, "ps") == 0) {
+ output_action = WRITE_TEXT;
+ print_format = PR_FMT_PS;
+ } else if (strcmp(ws_optarg, "pdml") == 0) {
+ output_action = WRITE_XML;
+ print_details = TRUE; /* Need details */
+ print_summary = FALSE; /* Don't allow summary */
+ } else if (strcmp(ws_optarg, "psml") == 0) {
+ output_action = WRITE_XML;
+ print_details = FALSE; /* Don't allow details */
+ print_summary = TRUE; /* Need summary */
+ } else if (strcmp(ws_optarg, "fields") == 0) {
+ output_action = WRITE_FIELDS;
+ print_details = TRUE; /* Need full tree info */
+ print_summary = FALSE; /* Don't allow summary */
+ } else if (strcmp(ws_optarg, "json") == 0) {
+ output_action = WRITE_JSON;
+ print_details = TRUE; /* Need details */
+ print_summary = FALSE; /* Don't allow summary */
+ } else if (strcmp(ws_optarg, "ek") == 0) {
+ output_action = WRITE_EK;
+ if (!print_summary)
+ print_details = TRUE;
+ } else if (strcmp(ws_optarg, "jsonraw") == 0) {
+ output_action = WRITE_JSON_RAW;
+ print_details = TRUE; /* Need details */
+ print_summary = FALSE; /* Don't allow summary */
+ }
+ else {
+ cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */
+ cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
+ "\t specified by the -E option.\n"
+ "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
+ "\t details of a decoded packet. This information is equivalent to\n"
+ "\t the packet details printed with the -V flag.\n"
+ "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
+ "\t the packets, or a multi-line view of the details of each of\n"
+ "\t the packets, depending on whether the -V flag was specified.\n"
+ "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
+ "\t summary information of a decoded packet. This information is\n"
+ "\t equivalent to the information shown in the one-line summary\n"
+ "\t printed by default.\n"
+ "\t\"json\" Packet Summary, an JSON-based format for the details\n"
+ "\t summary information of a decoded packet. This information is \n"
+ "\t equivalent to the packet details printed with the -V flag.\n"
+ "\t\"jsonraw\" Packet Details, a JSON-based format for machine parsing\n"
+ "\t including only raw hex decoded fields (same as -T json -x but\n"
+ "\t without text decoding, only raw fields included). \n"
+ "\t\"ek\" Packet Details, an EK JSON-based format for the bulk insert \n"
+ "\t into elastic search cluster. This information is \n"
+ "\t equivalent to the packet details printed with the -V flag.\n"
+ "\t\"text\" Text of a human-readable one-line summary of each of the\n"
+ "\t packets, or a multi-line view of the details of each of the\n"
+ "\t packets, depending on whether the -V flag was specified.\n"
+ "\t This is the default.\n"
+ "\t\"tabs\" Similar to the text report except that each column of the\n"
+ "\t human-readable one-line summary is delimited with an ASCII\n"
+ "\t horizontal tab character.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case 'U': /* Export PDUs to file */
+ if (strcmp(ws_optarg, "") == 0 || strcmp(ws_optarg, "?") == 0) {
+ list_export_pdu_taps();
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ pdu_export_arg = g_strdup(ws_optarg);
+ break;
+ case 'v': /* Show version and exit */
+ show_version();
+ /* We don't really have to cleanup here, but it's a convenient way to test
+ * start-up and shut-down of the epan library without any UI-specific
+ * cruft getting in the way. Makes the results of running
+ * $ ./tools/valgrind-wireshark -n
+ * much more useful. */
+ epan_cleanup();
+ extcap_cleanup();
+ exit_status = EXIT_SUCCESS;
+ goto clean_exit;
+ case 'O': /* Only output these protocols */
+ /* already processed; just ignore it now */
+ break;
+ case 'V': /* Verbose */
+ /* already processed; just ignore it now */
+ break;
+ case 'x': /* Print packet data in hex (and ASCII) */
+ /* already processed; just ignore it now */
+ break;
+ case 'X':
+ /* already processed; just ignore it now */
+ break;
+ case 'Y':
+ dfilter = g_strdup(ws_optarg);
+ break;
+ case 'z':
+ /* We won't call the init function for the stat this soon
+ as it would disallow MATE's fields (which are registered
+ by the preferences set callback) from being used as
+ part of a tap filter. Instead, we just add the argument
+ to a list of stat arguments. */
+ if (strcmp("help", ws_optarg) == 0) {
+ fprintf(stderr, "tshark: The available statistics for the \"-z\" option are:\n");
+ list_stat_cmd_args();
+ exit_status = EXIT_SUCCESS;
+ goto clean_exit;
+ }
+ if (!process_stat_cmd_arg(ws_optarg)) {
+ cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg);
+ list_stat_cmd_args();
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case 'd': /* Decode as rule */
+ case 'K': /* Kerberos keytab file */
+ case 'n': /* No name resolution */
+ case 'N': /* Select what types of addresses/port #s to resolve */
+ case 't': /* Time stamp type */
+ case 'u': /* Seconds type */
+ case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
+ case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
+ case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
+ case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
+ if (!dissect_opts_handle_opt(opt, ws_optarg)) {
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case LONGOPT_EXPORT_OBJECTS: /* --export-objects */
+ if (strcmp("help", ws_optarg) == 0) {
+ fprintf(stderr, "tshark: The available export object types for the \"--export-objects\" option are:\n");
+ eo_list_object_types();
+ exit_status = EXIT_SUCCESS;
+ goto clean_exit;
+ }
+ if (!eo_tap_opt_add(ws_optarg)) {
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ case LONGOPT_EXPORT_TLS_SESSION_KEYS: /* --export-tls-session-keys */
+ tls_session_keys_file = ws_optarg;
+ break;
+ case LONGOPT_COLOR: /* print in color where appropriate */
+ dissect_color = TRUE;
+ break;
+ case LONGOPT_NO_DUPLICATE_KEYS:
+ no_duplicate_keys = TRUE;
+ node_children_grouper = proto_node_group_children_by_json_key;
+ break;
+ case LONGOPT_CAPTURE_COMMENT: /* capture comment */
+ if (capture_comments == NULL) {
+ capture_comments = g_ptr_array_new_with_free_func(g_free);
+ }
+ g_ptr_array_add(capture_comments, g_strdup(ws_optarg));
+ break;
+ case LONGOPT_HEXDUMP:
+ print_hex = TRUE;
+ print_packet_info = TRUE;
+ if (strcmp(ws_optarg, "all") == 0)
+ hexdump_source_option = HEXDUMP_SOURCE_MULTI;
+ else if (strcmp(ws_optarg, "frames") == 0)
+ hexdump_source_option = HEXDUMP_SOURCE_PRIMARY;
+ else if (strcmp(ws_optarg, "ascii") == 0)
+ hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE;
+ else if (strcmp(ws_optarg, "delimit") == 0)
+ hexdump_ascii_option = HEXDUMP_ASCII_DELIMIT;
+ else if (strcmp(ws_optarg, "noascii") == 0)
+ hexdump_ascii_option = HEXDUMP_ASCII_EXCLUDE;
+ else if (strcmp("help", ws_optarg) == 0) {
+ hexdump_option_help(stdout);
+ exit_status = EXIT_SUCCESS;
+ goto clean_exit;
+ } else {
+ fprintf(stderr, "tshark: \"%s\" is an invalid value for --hexdump <hexoption>\n", ws_optarg);
+ fprintf(stderr, "For valid <hexoption> values enter: tshark --hexdump help\n");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ break;
+ default:
+ case '?': /* Bad flag - print usage message */
+ switch(ws_optopt) {
+ case 'F':
+ list_capture_types();
+ break;
+ default:
+ print_usage(stderr);
+ }
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ break;
+ }
+ }
- case PREFS_SET_OK:
- break;
+ /* set the default output action to TEXT */
+ if (output_action == WRITE_NONE)
+ output_action = WRITE_TEXT;
- case PREFS_SET_SYNTAX_ERR:
- cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
- errmsg ? ": " : "", errmsg ? errmsg : "");
- g_free(errmsg);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- break;
+ /* set the default file type to pcapng */
+ if (out_file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
+ out_file_type = wtap_pcapng_file_type_subtype();
- case PREFS_SET_NO_SUCH_PREF:
- cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- break;
+ /*
+ * Print packet summary information is the default if neither -V or -x
+ * were specified. Note that this is new behavior, which allows for the
+ * possibility of printing only hex/ascii output without necessarily
+ * requiring that either the summary or details be printed too.
+ */
+ if (!print_summary && !print_details && !print_hex)
+ print_summary = TRUE;
- case PREFS_SET_OBSOLETE:
- cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
+ if (no_duplicate_keys && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW) {
+ cmdarg_err("--no-duplicate-keys can only be used with \"-T json\" and \"-T jsonraw\"");
exit_status = INVALID_OPTION;
goto clean_exit;
- break;
- }
- break;
}
- case 'q': /* Quiet */
- quiet = TRUE;
- break;
- case 'Q': /* Really quiet */
- quiet = TRUE;
- really_quiet = TRUE;
- break;
- case 'r':
- /* already processed; just ignore it now */
- break;
- case 'R': /* Read file filter */
- rfilter = ws_optarg;
- break;
- case 'P':
- /* already processed; just ignore it now */
- break;
- case 'S': /* Set the line Separator to be printed between packets */
- separator = ws_optarg;
- break;
- case 'T': /* printing Type */
- /* output_action has been already set. It means multiple -T. */
- if (output_action > WRITE_NONE) {
- cmdarg_err("Multiple -T parameters are unsupported");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- print_packet_info = TRUE;
- if (strcmp(ws_optarg, "text") == 0) {
- output_action = WRITE_TEXT;
- print_format = PR_FMT_TEXT;
- } else if (strcmp(ws_optarg, "tabs") == 0) {
- output_action = WRITE_TEXT;
- print_format = PR_FMT_TEXT;
- delimiter_char = "\t";
- } else if (strcmp(ws_optarg, "ps") == 0) {
- output_action = WRITE_TEXT;
- print_format = PR_FMT_PS;
- } else if (strcmp(ws_optarg, "pdml") == 0) {
- output_action = WRITE_XML;
- print_details = TRUE; /* Need details */
- print_summary = FALSE; /* Don't allow summary */
- } else if (strcmp(ws_optarg, "psml") == 0) {
- output_action = WRITE_XML;
- print_details = FALSE; /* Don't allow details */
- print_summary = TRUE; /* Need summary */
- } else if (strcmp(ws_optarg, "fields") == 0) {
- output_action = WRITE_FIELDS;
- print_details = TRUE; /* Need full tree info */
- print_summary = FALSE; /* Don't allow summary */
- } else if (strcmp(ws_optarg, "json") == 0) {
- output_action = WRITE_JSON;
- print_details = TRUE; /* Need details */
- print_summary = FALSE; /* Don't allow summary */
- } else if (strcmp(ws_optarg, "ek") == 0) {
- output_action = WRITE_EK;
- if (!print_summary)
- print_details = TRUE;
- } else if (strcmp(ws_optarg, "jsonraw") == 0) {
- output_action = WRITE_JSON_RAW;
- print_details = TRUE; /* Need details */
- print_summary = FALSE; /* Don't allow summary */
- }
- else {
- cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", ws_optarg); /* x */
- cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
- "\t specified by the -E option.\n"
- "\t\"pdml\" Packet Details Markup Language, an XML-based format for the\n"
- "\t details of a decoded packet. This information is equivalent to\n"
- "\t the packet details printed with the -V flag.\n"
- "\t\"ps\" PostScript for a human-readable one-line summary of each of\n"
- "\t the packets, or a multi-line view of the details of each of\n"
- "\t the packets, depending on whether the -V flag was specified.\n"
- "\t\"psml\" Packet Summary Markup Language, an XML-based format for the\n"
- "\t summary information of a decoded packet. This information is\n"
- "\t equivalent to the information shown in the one-line summary\n"
- "\t printed by default.\n"
- "\t\"json\" Packet Summary, an JSON-based format for the details\n"
- "\t summary information of a decoded packet. This information is \n"
- "\t equivalent to the packet details printed with the -V flag.\n"
- "\t\"jsonraw\" Packet Details, a JSON-based format for machine parsing\n"
- "\t including only raw hex decoded fields (same as -T json -x but\n"
- "\t without text decoding, only raw fields included). \n"
- "\t\"ek\" Packet Details, an EK JSON-based format for the bulk insert \n"
- "\t into elastic search cluster. This information is \n"
- "\t equivalent to the packet details printed with the -V flag.\n"
- "\t\"text\" Text of a human-readable one-line summary of each of the\n"
- "\t packets, or a multi-line view of the details of each of the\n"
- "\t packets, depending on whether the -V flag was specified.\n"
- "\t This is the default.\n"
- "\t\"tabs\" Similar to the text report except that each column of the\n"
- "\t human-readable one-line summary is delimited with an ASCII\n"
- "\t horizontal tab character.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- case 'U': /* Export PDUs to file */
- if (strcmp(ws_optarg, "") == 0 || strcmp(ws_optarg, "?") == 0) {
- list_export_pdu_taps();
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- pdu_export_arg = g_strdup(ws_optarg);
- break;
- case 'v': /* Show version and exit */
- show_version();
- /* We don't really have to cleanup here, but it's a convenient way to test
- * start-up and shut-down of the epan library without any UI-specific
- * cruft getting in the way. Makes the results of running
- * $ ./tools/valgrind-wireshark -n
- * much more useful. */
- epan_cleanup();
- extcap_cleanup();
- exit_status = EXIT_SUCCESS;
- goto clean_exit;
- case 'O': /* Only output these protocols */
- /* already processed; just ignore it now */
- break;
- case 'V': /* Verbose */
- /* already processed; just ignore it now */
- break;
- case 'x': /* Print packet data in hex (and ASCII) */
- /* already processed; just ignore it now */
- break;
- case 'X':
- /* already processed; just ignore it now */
- break;
- case 'Y':
- dfilter = g_strdup(ws_optarg);
- break;
- case 'z':
- /* We won't call the init function for the stat this soon
- as it would disallow MATE's fields (which are registered
- by the preferences set callback) from being used as
- part of a tap filter. Instead, we just add the argument
- to a list of stat arguments. */
- if (strcmp("help", ws_optarg) == 0) {
- fprintf(stderr, "tshark: The available statistics for the \"-z\" option are:\n");
- list_stat_cmd_args();
- exit_status = EXIT_SUCCESS;
- goto clean_exit;
- }
- if (!process_stat_cmd_arg(ws_optarg)) {
- cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", ws_optarg);
- list_stat_cmd_args();
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- case 'd': /* Decode as rule */
- case 'K': /* Kerberos keytab file */
- case 'n': /* No name resolution */
- case 'N': /* Select what types of addresses/port #s to resolve */
- case 't': /* Time stamp type */
- case 'u': /* Seconds type */
- case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
- case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
- case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
- case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
- if (!dissect_opts_handle_opt(opt, ws_optarg)) {
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- case LONGOPT_EXPORT_OBJECTS: /* --export-objects */
- if (strcmp("help", ws_optarg) == 0) {
- fprintf(stderr, "tshark: The available export object types for the \"--export-objects\" option are:\n");
- eo_list_object_types();
- exit_status = EXIT_SUCCESS;
- goto clean_exit;
- }
- if (!eo_tap_opt_add(ws_optarg)) {
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- case LONGOPT_EXPORT_TLS_SESSION_KEYS: /* --export-tls-session-keys */
- tls_session_keys_file = ws_optarg;
- break;
- case LONGOPT_COLOR: /* print in color where appropriate */
- dissect_color = TRUE;
- break;
- case LONGOPT_NO_DUPLICATE_KEYS:
- no_duplicate_keys = TRUE;
- node_children_grouper = proto_node_group_children_by_json_key;
- break;
- case LONGOPT_CAPTURE_COMMENT: /* capture comment */
- if (capture_comments == NULL) {
- capture_comments = g_ptr_array_new_with_free_func(g_free);
- }
- g_ptr_array_add(capture_comments, g_strdup(ws_optarg));
- break;
- case LONGOPT_HEXDUMP:
- print_hex = TRUE;
- print_packet_info = TRUE;
- if (strcmp(ws_optarg, "all") == 0)
- hexdump_source_option = HEXDUMP_SOURCE_MULTI;
- else if (strcmp(ws_optarg, "frames") == 0)
- hexdump_source_option = HEXDUMP_SOURCE_PRIMARY;
- else if (strcmp(ws_optarg, "ascii") == 0)
- hexdump_ascii_option = HEXDUMP_ASCII_INCLUDE;
- else if (strcmp(ws_optarg, "delimit") == 0)
- hexdump_ascii_option = HEXDUMP_ASCII_DELIMIT;
- else if (strcmp(ws_optarg, "noascii") == 0)
- hexdump_ascii_option = HEXDUMP_ASCII_EXCLUDE;
- else if (strcmp("help", ws_optarg) == 0) {
- hexdump_option_help(stdout);
- exit_status = EXIT_SUCCESS;
- goto clean_exit;
- } else {
- fprintf(stderr, "tshark: \"%s\" is an invalid value for --hexdump <hexoption>\n", ws_optarg);
- fprintf(stderr, "For valid <hexoption> values enter: tshark --hexdump help\n");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- break;
- default:
- case '?': /* Bad flag - print usage message */
- switch(ws_optopt) {
- case 'F':
- list_capture_types();
- break;
- default:
- print_usage(stderr);
- }
- exit_status = INVALID_OPTION;
- goto clean_exit;
- break;
- }
- }
-
- /* set the default output action to TEXT */
- if (output_action == WRITE_NONE)
- output_action = WRITE_TEXT;
-
- /* set the default file type to pcapng */
- if (out_file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN)
- out_file_type = wtap_pcapng_file_type_subtype();
-
- /*
- * Print packet summary information is the default if neither -V or -x
- * were specified. Note that this is new behavior, which allows for the
- * possibility of printing only hex/ascii output without necessarily
- * requiring that either the summary or details be printed too.
- */
- if (!print_summary && !print_details && !print_hex)
- print_summary = TRUE;
-
- if (no_duplicate_keys && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW) {
- cmdarg_err("--no-duplicate-keys can only be used with \"-T json\" and \"-T jsonraw\"");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
-
- /* If we specified output fields, but not the output field type... */
- if ((WRITE_FIELDS != output_action && WRITE_XML != output_action && WRITE_JSON != output_action && WRITE_EK != output_action) && 0 != output_fields_num_fields(output_fields)) {
+
+ /* If we specified output fields, but not the output field type... */
+ if ((WRITE_FIELDS != output_action && WRITE_XML != output_action && WRITE_JSON != output_action && WRITE_EK != output_action) && 0 != output_fields_num_fields(output_fields)) {
cmdarg_err("Output fields were specified with \"-e\", "
- "but \"-Tek, -Tfields, -Tjson or -Tpdml\" was not specified.");
+ "but \"-Tek, -Tfields, -Tjson or -Tpdml\" was not specified.");
exit_status = INVALID_OPTION;
goto clean_exit;
- } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
+ } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
cmdarg_err("\"-Tfields\" was specified, but no fields were "
- "specified with \"-e\".");
+ "specified with \"-e\".");
exit_status = INVALID_OPTION;
goto clean_exit;
- }
+ }
- if (dissect_color) {
- if (!color_filters_init(&err_msg, NULL)) {
- fprintf(stderr, "%s\n", err_msg);
- g_free(err_msg);
+ if (dissect_color) {
+ if (!color_filters_init(&err_msg, NULL)) {
+ fprintf(stderr, "%s\n", err_msg);
+ g_free(err_msg);
+ }
}
- }
-
- /* If no capture filter or display filter has been specified, and there are
- still command-line arguments, treat them as the tokens of a capture
- filter (if no "-r" flag was specified) or a display filter (if a "-r"
- flag was specified. */
- if (ws_optind < argc) {
- if (cf_name != NULL) {
- if (dfilter != NULL) {
- cmdarg_err("Display filters were specified both with \"-Y\" "
- "and with additional command-line arguments.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- dfilter = get_args_as_string(argc, argv, ws_optind);
- } else {
-#ifdef HAVE_LIBPCAP
- guint i;
- if (global_capture_opts.default_options.cfilter) {
- cmdarg_err("A default capture filter was specified both with \"-f\""
- " and with additional command-line arguments.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- for (i = 0; i < global_capture_opts.ifaces->len; i++) {
- interface_options *interface_opts;
- interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
- if (interface_opts->cfilter == NULL) {
- interface_opts->cfilter = get_args_as_string(argc, argv, ws_optind);
+ /* If no capture filter or display filter has been specified, and there are
+ still command-line arguments, treat them as the tokens of a capture
+ filter (if no "-r" flag was specified) or a display filter (if a "-r"
+ flag was specified. */
+ if (ws_optind < argc) {
+ if (cf_name != NULL) {
+ if (dfilter != NULL) {
+ cmdarg_err("Display filters were specified both with \"-Y\" "
+ "and with additional command-line arguments.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ dfilter = get_args_as_string(argc, argv, ws_optind);
} else {
- cmdarg_err("A capture filter was specified both with \"-f\""
- " and with additional command-line arguments.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- }
- global_capture_opts.default_options.cfilter = get_args_as_string(argc, argv, ws_optind);
+#ifdef HAVE_LIBPCAP
+ guint i;
+
+ if (global_capture_opts.default_options.cfilter) {
+ cmdarg_err("A default capture filter was specified both with \"-f\""
+ " and with additional command-line arguments.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+ interface_options *interface_opts;
+ interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
+ if (interface_opts->cfilter == NULL) {
+ interface_opts->cfilter = get_args_as_string(argc, argv, ws_optind);
+ } else {
+ cmdarg_err("A capture filter was specified both with \"-f\""
+ " and with additional command-line arguments.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ }
+ global_capture_opts.default_options.cfilter = get_args_as_string(argc, argv, ws_optind);
#else
- capture_option_specified = TRUE;
+ capture_option_specified = TRUE;
#endif
+ }
}
- }
-
- if (!output_file_name) {
- /* We're not saving the capture to a file; if "-q" wasn't specified,
- we should print packet information */
- if (!quiet)
- print_packet_info = TRUE;
- } else {
- const char *save_file = output_file_name;
- /* We're saving to a file; if we're writing to the standard output.
- and we'll also be writing dissected packets to the standard
- output, reject the request. At best, we could redirect that
- to the standard error; we *can't* write both to the standard
- output and have either of them be useful. */
- if (strcmp(save_file, "-") == 0 && print_packet_info) {
- cmdarg_err("You can't write both raw packet data and dissected packets"
- " to the standard output.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+
+ if (!output_file_name) {
+ /* We're not saving the capture to a file; if "-q" wasn't specified,
+ we should print packet information */
+ if (!quiet)
+ print_packet_info = TRUE;
+ } else {
+ const char *save_file = output_file_name;
+ /* We're saving to a file; if we're writing to the standard output.
+ and we'll also be writing dissected packets to the standard
+ output, reject the request. At best, we could redirect that
+ to the standard error; we *can't* write both to the standard
+ output and have either of them be useful. */
+ if (strcmp(save_file, "-") == 0 && print_packet_info) {
+ cmdarg_err("You can't write both raw packet data and dissected packets"
+ " to the standard output.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
}
- }
#ifndef HAVE_LIBPCAP
- if (capture_option_specified)
- cmdarg_err("This version of TShark was not built with support for capturing packets.");
+ if (capture_option_specified)
+ cmdarg_err("This version of TShark was not built with support for capturing packets.");
#endif
- if (arg_error) {
- print_usage(stderr);
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
-
- if (print_hex) {
- if (output_action != WRITE_TEXT && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW && output_action != WRITE_EK) {
- cmdarg_err("Raw packet hex data can only be printed as text, PostScript, JSON, JSONRAW or EK JSON");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ if (arg_error) {
+ print_usage(stderr);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
}
- }
-
- if (output_only != NULL) {
- char *ps;
- if (!print_details) {
- cmdarg_err("-O requires -V");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ if (print_hex) {
+ if (output_action != WRITE_TEXT && output_action != WRITE_JSON && output_action != WRITE_JSON_RAW && output_action != WRITE_EK) {
+ cmdarg_err("Raw packet hex data can only be printed as text, PostScript, JSON, JSONRAW or EK JSON");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
}
- output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
- for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
- const char *name = ps;
- header_field_info *hfi = proto_registrar_get_byalias(name);
- if (hfi) {
- name = hfi->abbrev;
- }
- g_hash_table_insert(output_only_tables, (gpointer)name, (gpointer)name);
- }
- }
+ if (output_only != NULL) {
+ char *ps;
- if (rfilter != NULL && !perform_two_pass_analysis) {
- cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
+ if (!print_details) {
+ cmdarg_err("-O requires -V");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
-#ifdef HAVE_LIBPCAP
- if (caps_queries) {
- /* We're supposed to list the link-layer/timestamp types for an interface;
- did the user also specify a capture file to be read? */
- if (cf_name) {
- /* Yes - that's bogus. */
- cmdarg_err("You can't specify %s and a capture file to be read.",
- caps_queries & CAPS_QUERY_LINK_TYPES ? "-L" : "--list-time-stamp-types");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- /* No - did they specify a ring buffer option? */
- if (global_capture_opts.multi_files_on) {
- cmdarg_err("Ring buffer requested, but a capture isn't being done.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
+ for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
+ const char *name = ps;
+ header_field_info *hfi = proto_registrar_get_byalias(name);
+ if (hfi) {
+ name = hfi->abbrev;
+ }
+ g_hash_table_insert(output_only_tables, (gpointer)name, (gpointer)name);
+ }
}
- } else {
- if (cf_name) {
- /*
- * "-r" was specified, so we're reading a capture file.
- * Capture options don't apply here.
- */
- /* We don't support capture filters when reading from a capture file
- (the BPF compiler doesn't support all link-layer types that we
- support in capture files we read). */
- if (global_capture_opts.default_options.cfilter) {
- cmdarg_err("Only read filters, not capture filters, "
- "can be specified when reading a capture file.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (global_capture_opts.multi_files_on) {
- cmdarg_err("Multiple capture files requested, but "
- "a capture isn't being done.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (global_capture_opts.has_file_duration) {
- cmdarg_err("Switching capture files after a time period was specified, but "
- "a capture isn't being done.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (global_capture_opts.has_file_interval) {
- cmdarg_err("Switching capture files after a time interval was specified, but "
- "a capture isn't being done.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (global_capture_opts.has_ring_num_files) {
- cmdarg_err("A ring buffer of capture files was specified, but "
- "a capture isn't being done.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (global_capture_opts.has_autostop_files) {
- cmdarg_err("A maximum number of capture files was specified, but "
- "a capture isn't being done.");
+ if (rfilter != NULL && !perform_two_pass_analysis) {
+ cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
exit_status = INVALID_OPTION;
goto clean_exit;
- }
-
- /* Note: TShark now allows the restriction of a _read_ file by packet count
- * and byte count as well as a write file. Other autostop options remain valid
- * only for a write file.
- */
- if (global_capture_opts.has_autostop_duration) {
- cmdarg_err("A maximum capture time was specified, but "
- "a capture isn't being done.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- } else {
- /*
- * "-r" wasn't specified, so we're doing a live capture.
- */
- gboolean use_pcapng = TRUE;
-
- if (perform_two_pass_analysis) {
- /* Two-pass analysis doesn't work with live capture since it requires us
- * to buffer packets until we've read all of them, but a live capture
- * has no useful/meaningful definition of "all" */
- cmdarg_err("Live captures do not support two-pass analysis.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
-
- if (global_capture_opts.saving_to_file) {
- /* They specified a "-w" flag, so we'll be saving to a capture file. */
+ }
- /* When capturing, we only support writing pcap or pcapng format. */
- if (out_file_type == wtap_pcapng_file_type_subtype()) {
- use_pcapng = TRUE;
- } else if (out_file_type == wtap_pcap_file_type_subtype()) {
- use_pcapng = FALSE;
- } else {
- cmdarg_err("Live captures can only be saved in pcap or pcapng format.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (capture_comments != NULL && !use_pcapng) {
- cmdarg_err("Capture comments can only be written to a pcapng file.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (global_capture_opts.multi_files_on) {
- /* Multiple-file mode doesn't work under certain conditions:
- a) it doesn't work if you're writing to the standard output;
- b) it doesn't work if you're writing to a pipe;
- */
- if (strcmp(global_capture_opts.save_file, "-") == 0) {
- cmdarg_err("Multiple capture files requested, but "
- "the capture is being written to the standard output.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (global_capture_opts.output_to_pipe) {
- cmdarg_err("Multiple capture files requested, but "
- "the capture file is a pipe.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (!global_capture_opts.has_autostop_filesize &&
- !global_capture_opts.has_file_duration &&
- !global_capture_opts.has_file_interval &&
- !global_capture_opts.has_file_packets) {
- cmdarg_err("Multiple capture files requested, but "
- "no maximum capture file size, duration, interval or packets were specified.");
+#ifdef HAVE_LIBPCAP
+ if (caps_queries) {
+ /* We're supposed to list the link-layer/timestamp types for an interface;
+ did the user also specify a capture file to be read? */
+ if (cf_name) {
+ /* Yes - that's bogus. */
+ cmdarg_err("You can't specify %s and a capture file to be read.",
+ caps_queries & CAPS_QUERY_LINK_TYPES ? "-L" : "--list-time-stamp-types");
exit_status = INVALID_OPTION;
goto clean_exit;
- }
- }
- /* Currently, we don't support read or display filters when capturing
- and saving the packets. */
- if (rfilter != NULL) {
- cmdarg_err("Read filters aren't supported when capturing and saving the captured packets.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (dfilter != NULL) {
- cmdarg_err("Display filters aren't supported when capturing and saving the captured packets.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- global_capture_opts.use_pcapng = use_pcapng;
- } else {
- /* They didn't specify a "-w" flag, so we won't be saving to a
- capture file. Check for options that only make sense if
- we're saving to a file. */
- if (global_capture_opts.has_autostop_filesize) {
- cmdarg_err("Maximum capture file size specified, but "
- "capture isn't being saved to a file.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
}
+ /* No - did they specify a ring buffer option? */
if (global_capture_opts.multi_files_on) {
- cmdarg_err("Multiple capture files requested, but "
- "the capture isn't being saved to a file.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ cmdarg_err("Ring buffer requested, but a capture isn't being done.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
}
- if (capture_comments != NULL) {
- cmdarg_err("Capture comments were specified, but "
- "the capture isn't being saved to a file.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ } else {
+ if (cf_name) {
+ /*
+ * "-r" was specified, so we're reading a capture file.
+ * Capture options don't apply here.
+ */
+
+ /* We don't support capture filters when reading from a capture file
+ (the BPF compiler doesn't support all link-layer types that we
+ support in capture files we read). */
+ if (global_capture_opts.default_options.cfilter) {
+ cmdarg_err("Only read filters, not capture filters, "
+ "can be specified when reading a capture file.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (global_capture_opts.multi_files_on) {
+ cmdarg_err("Multiple capture files requested, but "
+ "a capture isn't being done.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (global_capture_opts.has_file_duration) {
+ cmdarg_err("Switching capture files after a time period was specified, but "
+ "a capture isn't being done.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (global_capture_opts.has_file_interval) {
+ cmdarg_err("Switching capture files after a time interval was specified, but "
+ "a capture isn't being done.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (global_capture_opts.has_ring_num_files) {
+ cmdarg_err("A ring buffer of capture files was specified, but "
+ "a capture isn't being done.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (global_capture_opts.has_autostop_files) {
+ cmdarg_err("A maximum number of capture files was specified, but "
+ "a capture isn't being done.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+
+ /* Note: TShark now allows the restriction of a _read_ file by packet count
+ * and byte count as well as a write file. Other autostop options remain valid
+ * only for a write file.
+ */
+ if (global_capture_opts.has_autostop_duration) {
+ cmdarg_err("A maximum capture time was specified, but "
+ "a capture isn't being done.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ } else {
+ /*
+ * "-r" wasn't specified, so we're doing a live capture.
+ */
+ gboolean use_pcapng = TRUE;
+
+ if (perform_two_pass_analysis) {
+ /* Two-pass analysis doesn't work with live capture since it requires us
+ * to buffer packets until we've read all of them, but a live capture
+ * has no useful/meaningful definition of "all" */
+ cmdarg_err("Live captures do not support two-pass analysis.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+
+ if (global_capture_opts.saving_to_file) {
+ /* They specified a "-w" flag, so we'll be saving to a capture file. */
+
+ /* When capturing, we only support writing pcap or pcapng format. */
+ if (out_file_type == wtap_pcapng_file_type_subtype()) {
+ use_pcapng = TRUE;
+ } else if (out_file_type == wtap_pcap_file_type_subtype()) {
+ use_pcapng = FALSE;
+ } else {
+ cmdarg_err("Live captures can only be saved in pcap or pcapng format.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (capture_comments != NULL && !use_pcapng) {
+ cmdarg_err("Capture comments can only be written to a pcapng file.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (global_capture_opts.multi_files_on) {
+ /* Multiple-file mode doesn't work under certain conditions:
+ a) it doesn't work if you're writing to the standard output;
+ b) it doesn't work if you're writing to a pipe;
+ */
+ if (strcmp(global_capture_opts.save_file, "-") == 0) {
+ cmdarg_err("Multiple capture files requested, but "
+ "the capture is being written to the standard output.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (global_capture_opts.output_to_pipe) {
+ cmdarg_err("Multiple capture files requested, but "
+ "the capture file is a pipe.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (!global_capture_opts.has_autostop_filesize &&
+ !global_capture_opts.has_file_duration &&
+ !global_capture_opts.has_file_interval &&
+ !global_capture_opts.has_file_packets) {
+ cmdarg_err("Multiple capture files requested, but "
+ "no maximum capture file size, duration, interval or packets were specified.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ }
+ /* Currently, we don't support read or display filters when capturing
+ and saving the packets. */
+ if (rfilter != NULL) {
+ cmdarg_err("Read filters aren't supported when capturing and saving the captured packets.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (dfilter != NULL) {
+ cmdarg_err("Display filters aren't supported when capturing and saving the captured packets.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ global_capture_opts.use_pcapng = use_pcapng;
+ } else {
+ /* They didn't specify a "-w" flag, so we won't be saving to a
+ capture file. Check for options that only make sense if
+ we're saving to a file. */
+ if (global_capture_opts.has_autostop_filesize) {
+ cmdarg_err("Maximum capture file size specified, but "
+ "capture isn't being saved to a file.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (global_capture_opts.multi_files_on) {
+ cmdarg_err("Multiple capture files requested, but "
+ "the capture isn't being saved to a file.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (capture_comments != NULL) {
+ cmdarg_err("Capture comments were specified, but "
+ "the capture isn't being saved to a file.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ }
}
- }
}
- }
#endif
- /*
- * If capture comments were specified, -w also has to have been specified.
- */
- if (capture_comments != NULL) {
- if (output_file_name) {
- /* They specified a "-w" flag, so we'll be saving to a capture file.
- * This is fine if they're writing in a format that supports
- * section block comments.
- */
- if (wtap_file_type_subtype_supports_option(out_file_type,
- WTAP_BLOCK_SECTION,
- OPT_COMMENT) == OPTION_NOT_SUPPORTED) {
- GArray *writable_type_subtypes;
-
- cmdarg_err("Capture comments can only be written to files of the following types:");
- 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);
-
- if (wtap_file_type_subtype_supports_option(ft, WTAP_BLOCK_SECTION,
- OPT_COMMENT) != OPTION_NOT_SUPPORTED)
- cmdarg_err_cont(" %s - %s", wtap_file_type_subtype_name(ft),
- wtap_file_type_subtype_description(ft));
+ /*
+ * If capture comments were specified, -w also has to have been specified.
+ */
+ if (capture_comments != NULL) {
+ if (output_file_name) {
+ /* They specified a "-w" flag, so we'll be saving to a capture file.
+ * This is fine if they're writing in a format that supports
+ * section block comments.
+ */
+ if (wtap_file_type_subtype_supports_option(out_file_type,
+ WTAP_BLOCK_SECTION,
+ OPT_COMMENT) == OPTION_NOT_SUPPORTED) {
+ GArray *writable_type_subtypes;
+
+ cmdarg_err("Capture comments can only be written to files of the following types:");
+ 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);
+
+ if (wtap_file_type_subtype_supports_option(ft, WTAP_BLOCK_SECTION,
+ OPT_COMMENT) != OPTION_NOT_SUPPORTED)
+ cmdarg_err_cont(" %s - %s", wtap_file_type_subtype_name(ft),
+ wtap_file_type_subtype_description(ft));
+ }
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ }
+ else {
+ cmdarg_err("Capture comments were specified, but you aren't writing a capture file.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
}
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
}
- else {
- cmdarg_err("Capture comments were specified, but you aren't writing a capture file.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+
+ err_msg = ws_init_sockets();
+ if (err_msg != NULL)
+ {
+ cmdarg_err("%s", err_msg);
+ g_free(err_msg);
+ cmdarg_err_cont("%s", please_report_bug());
+ exit_status = INIT_FAILED;
+ goto clean_exit;
}
- }
-
- err_msg = ws_init_sockets();
- if (err_msg != NULL)
- {
- cmdarg_err("%s", err_msg);
- g_free(err_msg);
- cmdarg_err_cont("%s", please_report_bug());
- exit_status = INIT_FAILED;
- goto clean_exit;
- }
-
- /* Notify all registered modules that have had any of their preferences
- changed either from one of the preferences file or from the command
- line that their preferences have changed. */
- prefs_apply_all();
-
- /* We can also enable specified taps for export object */
- start_exportobjects();
-
- /* At this point MATE will have registered its field array so we can
- check if the fields specified by the user are all good.
- */
- {
- GSList* it = NULL;
- GSList *invalid_fields = output_fields_valid(output_fields);
- if (invalid_fields != NULL) {
-
- cmdarg_err("Some fields aren't valid:");
- for (it=invalid_fields; it != NULL; it = g_slist_next(it)) {
- cmdarg_err_cont("\t%s", (gchar *)it->data);
- }
- g_slist_free(invalid_fields);
- exit_status = INVALID_OPTION;
- goto clean_exit;
+
+ /* Notify all registered modules that have had any of their preferences
+ changed either from one of the preferences file or from the command
+ line that their preferences have changed. */
+ prefs_apply_all();
+
+ /* We can also enable specified taps for export object */
+ start_exportobjects();
+
+ /* At this point MATE will have registered its field array so we can
+ check if the fields specified by the user are all good.
+ */
+ {
+ GSList* it = NULL;
+ GSList *invalid_fields = output_fields_valid(output_fields);
+ if (invalid_fields != NULL) {
+
+ cmdarg_err("Some fields aren't valid:");
+ for (it=invalid_fields; it != NULL; it = g_slist_next(it)) {
+ cmdarg_err_cont("\t%s", (gchar *)it->data);
+ }
+ g_slist_free(invalid_fields);
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
}
- }
#ifdef HAVE_LIBPCAP
- /* We currently don't support taps, or printing dissected packets,
- if we're writing to a pipe. */
- if (global_capture_opts.saving_to_file &&
- global_capture_opts.output_to_pipe) {
- if (tap_listeners_require_dissection()) {
- cmdarg_err("Taps aren't supported when saving to a pipe.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- if (print_packet_info) {
- cmdarg_err("Printing dissected packets isn't supported when saving to a pipe.");
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ /* We currently don't support taps, or printing dissected packets,
+ if we're writing to a pipe. */
+ if (global_capture_opts.saving_to_file &&
+ global_capture_opts.output_to_pipe) {
+ if (tap_listeners_require_dissection()) {
+ cmdarg_err("Taps aren't supported when saving to a pipe.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ if (print_packet_info) {
+ cmdarg_err("Printing dissected packets isn't supported when saving to a pipe.");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
}
- }
#endif
- if (ex_opt_count("read_format") > 0) {
- const gchar* name = ex_opt_get_next("read_format");
- in_file_type = open_info_name_to_type(name);
- if (in_file_type == WTAP_TYPE_AUTO) {
- cmdarg_err("\"%s\" isn't a valid read file format type", name? name : "");
- list_read_capture_types();
- exit_status = INVALID_OPTION;
- goto clean_exit;
+ if (ex_opt_count("read_format") > 0) {
+ const gchar* name = ex_opt_get_next("read_format");
+ in_file_type = open_info_name_to_type(name);
+ if (in_file_type == WTAP_TYPE_AUTO) {
+ cmdarg_err("\"%s\" isn't a valid read file format type", name? name : "");
+ list_read_capture_types();
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
}
- }
- timestamp_set_type(global_dissect_options.time_format);
+ timestamp_set_type(global_dissect_options.time_format);
- /*
- * Enabled and disabled protocols and heuristic dissectors as per
- * command-line options.
- */
- if (!setup_enabled_and_disabled_protocols()) {
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
+ /*
+ * Enabled and disabled protocols and heuristic dissectors as per
+ * command-line options.
+ */
+ if (!setup_enabled_and_disabled_protocols()) {
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
- /* Build the column format array */
- build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
+ /* Build the column format array */
+ build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
#ifdef HAVE_LIBPCAP
- capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
- capture_opts_trim_ring_num_files(&global_capture_opts);
+ capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
+ capture_opts_trim_ring_num_files(&global_capture_opts);
#endif
- if (rfilter != NULL) {
- ws_debug("Compiling read filter: '%s'", rfilter);
- if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
- cmdarg_err("%s", err_msg);
- g_free(err_msg);
- epan_cleanup();
- extcap_cleanup();
+ if (rfilter != NULL) {
+ ws_debug("Compiling read filter: '%s'", rfilter);
+ if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
+ cmdarg_err("%s", err_msg);
+ g_free(err_msg);
+ epan_cleanup();
+ extcap_cleanup();
#ifdef HAVE_LIBPCAP
- pcap_t *pc;
- pc = pcap_open_dead(DLT_EN10MB, MIN_PACKET_SIZE);
- if (pc != NULL) {
- if (pcap_compile(pc, &fcode, rfilter, 0, 0) != -1) {
- cmdarg_err_cont(
- " Note: That read filter code looks like a valid capture filter;\n"
- " maybe you mixed them up?");
- }
- pcap_close(pc);
- }
+ pcap_t *pc;
+ pc = pcap_open_dead(DLT_EN10MB, MIN_PACKET_SIZE);
+ if (pc != NULL) {
+ if (pcap_compile(pc, &fcode, rfilter, 0, 0) != -1) {
+ cmdarg_err_cont(
+ " Note: That read filter code looks like a valid capture filter;\n"
+ " maybe you mixed them up?");
+ }
+ pcap_close(pc);
+ }
#endif
- exit_status = INVALID_INTERFACE;
- goto clean_exit;
+ exit_status = INVALID_INTERFACE;
+ goto clean_exit;
+ }
}
- }
- cfile.rfcode = rfcode;
+ cfile.rfcode = rfcode;
- if (dfilter != NULL) {
- ws_debug("Compiling display filter: '%s'", dfilter);
- if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
- cmdarg_err("%s", err_msg);
- g_free(err_msg);
- epan_cleanup();
- extcap_cleanup();
+ if (dfilter != NULL) {
+ ws_debug("Compiling display filter: '%s'", dfilter);
+ if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
+ cmdarg_err("%s", err_msg);
+ g_free(err_msg);
+ epan_cleanup();
+ extcap_cleanup();
#ifdef HAVE_LIBPCAP
- pcap_t *pc;
- pc = pcap_open_dead(DLT_EN10MB, MIN_PACKET_SIZE);
- if (pc != NULL) {
- if (pcap_compile(pc, &fcode, dfilter, 0, 0) != -1) {
- cmdarg_err_cont(
- " Note: That display filter code looks like a valid capture filter;\n"
- " maybe you mixed them up?");
- }
- pcap_close(pc);
- }
+ pcap_t *pc;
+ pc = pcap_open_dead(DLT_EN10MB, MIN_PACKET_SIZE);
+ if (pc != NULL) {
+ if (pcap_compile(pc, &fcode, dfilter, 0, 0) != -1) {
+ cmdarg_err_cont(
+ " Note: That display filter code looks like a valid capture filter;\n"
+ " maybe you mixed them up?");
+ }
+ pcap_close(pc);
+ }
#endif
- exit_status = INVALID_FILTER;
- goto clean_exit;
+ exit_status = INVALID_FILTER;
+ goto clean_exit;
+ }
}
- }
- cfile.dfcode = dfcode;
-
- if (print_packet_info) {
- /* If we're printing as text or PostScript, we have
- to create a print stream. */
- if (output_action == WRITE_TEXT) {
- switch (print_format) {
-
- case PR_FMT_TEXT:
- print_stream = print_stream_text_stdio_new(stdout);
- break;
-
- case PR_FMT_PS:
- print_stream = print_stream_ps_stdio_new(stdout);
- break;
-
- default:
- ws_assert_not_reached();
- }
+ cfile.dfcode = dfcode;
+
+ if (print_packet_info) {
+ /* If we're printing as text or PostScript, we have
+ to create a print stream. */
+ if (output_action == WRITE_TEXT) {
+ switch (print_format) {
+
+ case PR_FMT_TEXT:
+ print_stream = print_stream_text_stdio_new(stdout);
+ break;
+
+ case PR_FMT_PS:
+ print_stream = print_stream_ps_stdio_new(stdout);
+ break;
+
+ default:
+ ws_assert_not_reached();
+ }
+ }
}
- }
-
- /* PDU export requested. Take the ownership of the '-w' file, apply tap
- * filters and start tapping. */
- if (pdu_export_arg) {
- const char *exp_pdu_tap_name = pdu_export_arg;
- const char *exp_pdu_filter = dfilter; /* may be NULL to disable filter */
- char *exp_pdu_error;
- int exp_fd;
- char *comment;
-
- if (!cf_name) {
- cmdarg_err("PDUs export requires a capture file (specify with -r).");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
- /* Take ownership of the '-w' output file. */
- exp_pdu_filename = output_file_name;
- output_file_name = NULL;
+
+ /* PDU export requested. Take the ownership of the '-w' file, apply tap
+ * filters and start tapping. */
+ if (pdu_export_arg) {
+ const char *exp_pdu_tap_name = pdu_export_arg;
+ const char *exp_pdu_filter = dfilter; /* may be NULL to disable filter */
+ char *exp_pdu_error;
+ int exp_fd;
+ char *comment;
+
+ if (!cf_name) {
+ cmdarg_err("PDUs export requires a capture file (specify with -r).");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+ /* Take ownership of the '-w' output file. */
+ exp_pdu_filename = output_file_name;
+ output_file_name = NULL;
#ifdef HAVE_LIBPCAP
- global_capture_opts.save_file = NULL;
+ global_capture_opts.save_file = NULL;
#endif
- if (exp_pdu_filename == NULL) {
- cmdarg_err("PDUs export requires an output file (-w).");
- exit_status = INVALID_OPTION;
- goto clean_exit;
- }
-
- exp_pdu_error = exp_pdu_pre_open(exp_pdu_tap_name, exp_pdu_filter,
- &exp_pdu_tap_data);
- if (exp_pdu_error) {
- cmdarg_err("Cannot register tap: %s", exp_pdu_error);
- g_free(exp_pdu_error);
- list_export_pdu_taps();
- exit_status = INVALID_TAP;
- goto clean_exit;
- }
-
- if (strcmp(exp_pdu_filename, "-") == 0) {
- /* Write to the standard output. */
- exp_fd = 1;
- } else {
- exp_fd = ws_open(exp_pdu_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
- if (exp_fd == -1) {
- cmdarg_err("%s: %s", exp_pdu_filename, file_open_error_message(errno, TRUE));
- exit_status = INVALID_FILE;
- goto clean_exit;
+ if (exp_pdu_filename == NULL) {
+ cmdarg_err("PDUs export requires an output file (-w).");
+ exit_status = INVALID_OPTION;
+ goto clean_exit;
+ }
+
+ exp_pdu_error = exp_pdu_pre_open(exp_pdu_tap_name, exp_pdu_filter,
+ &exp_pdu_tap_data);
+ if (exp_pdu_error) {
+ cmdarg_err("Cannot register tap: %s", exp_pdu_error);
+ g_free(exp_pdu_error);
+ list_export_pdu_taps();
+ exit_status = INVALID_TAP;
+ goto clean_exit;
+ }
+
+ if (strcmp(exp_pdu_filename, "-") == 0) {
+ /* Write to the standard output. */
+ exp_fd = 1;
+ } else {
+ exp_fd = ws_open(exp_pdu_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+ if (exp_fd == -1) {
+ cmdarg_err("%s: %s", exp_pdu_filename, file_open_error_message(errno, TRUE));
+ exit_status = INVALID_FILE;
+ goto clean_exit;
+ }
+ }
+
+ /* Activate the export PDU tap */
+ /* Write to our output file with this comment (if the type supports it,
+ * otherwise exp_pdu_open() will ignore the comment) */
+ comment = ws_strdup_printf("Dump of PDUs from %s", cf_name);
+ exp_pdu_status = exp_pdu_open(&exp_pdu_tap_data, exp_pdu_filename,
+ out_file_type, exp_fd, comment,
+ &err, &err_info);
+ g_free(comment);
+ if (!exp_pdu_status) {
+ cfile_dump_open_failure_message(exp_pdu_filename, err, err_info,
+ out_file_type);
+ exit_status = INVALID_EXPORT;
+ goto clean_exit;
}
- }
-
- /* Activate the export PDU tap */
- /* Write to our output file with this comment (if the type supports it,
- * otherwise exp_pdu_open() will ignore the comment) */
- comment = ws_strdup_printf("Dump of PDUs from %s", cf_name);
- exp_pdu_status = exp_pdu_open(&exp_pdu_tap_data, exp_pdu_filename,
- out_file_type, exp_fd, comment,
- &err, &err_info);
- g_free(comment);
- if (!exp_pdu_status) {
- cfile_dump_open_failure_message(exp_pdu_filename, err, err_info,
- out_file_type);
- exit_status = INVALID_EXPORT;
- goto clean_exit;
- }
- }
-
- ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE");
-
- if (cf_name) {
- ws_debug("tshark: Opening capture file: %s", cf_name);
- /*
- * We're reading a capture file.
- */
- if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) != CF_OK) {
- epan_cleanup();
- extcap_cleanup();
- exit_status = INVALID_FILE;
- goto clean_exit;
}
- /* Start statistics taps; we do so after successfully opening the
- capture file, so we know we have something to compute stats
- on, and after registering all dissectors, so that MATE will
- have registered its field array so we can have a tap filter
- with one of MATE's late-registered fields as part of the
- filter. */
- start_requested_stats();
-
- /* Do we need to do dissection of packets? That depends on, among
- other things, what taps are listening, so determine that after
- starting the statistics taps. */
- do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
-
- /* Process the packets in the file */
- ws_debug("tshark: invoking process_cap_file() to process the packets");
- TRY {
- status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res,
+ ws_debug("tshark: do_dissection = %s", do_dissection ? "TRUE" : "FALSE");
+
+ if (cf_name) {
+ ws_debug("tshark: Opening capture file: %s", cf_name);
+ /*
+ * We're reading a capture file.
+ */
+ if (cf_open(&cfile, cf_name, in_file_type, FALSE, &err) != CF_OK) {
+ epan_cleanup();
+ extcap_cleanup();
+ exit_status = INVALID_FILE;
+ goto clean_exit;
+ }
+
+ /* Start statistics taps; we do so after successfully opening the
+ capture file, so we know we have something to compute stats
+ on, and after registering all dissectors, so that MATE will
+ have registered its field array so we can have a tap filter
+ with one of MATE's late-registered fields as part of the
+ filter. */
+ start_requested_stats();
+
+ /* Do we need to do dissection of packets? That depends on, among
+ other things, what taps are listening, so determine that after
+ starting the statistics taps. */
+ do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
+
+ /* Process the packets in the file */
+ ws_debug("tshark: invoking process_cap_file() to process the packets");
+ TRY {
+ status = process_cap_file(&cfile, output_file_name, out_file_type, out_file_name_res,
#ifdef HAVE_LIBPCAP
- global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
- global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0,
- global_capture_opts.has_autostop_written_packets ? global_capture_opts.autostop_written_packets : 0);
+ global_capture_opts.has_autostop_packets ? global_capture_opts.autostop_packets : 0,
+ global_capture_opts.has_autostop_filesize ? global_capture_opts.autostop_filesize : 0,
+ global_capture_opts.has_autostop_written_packets ? global_capture_opts.autostop_written_packets : 0);
#else
- max_packet_count,
- 0,
- 0);
+ max_packet_count,
+ 0,
+ 0);
#endif
- }
- CATCH(OutOfMemoryError) {
- fprintf(stderr,
- "Out Of Memory.\n"
- "\n"
- "Sorry, but TShark has to terminate now.\n"
- "\n"
- "More information and workarounds can be found at\n"
- WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
- status = PROCESS_FILE_ERROR;
- }
- ENDTRY;
-
- switch (status) {
-
- case PROCESS_FILE_SUCCEEDED:
- /* Everything worked OK; draw the taps. */
- draw_taps = TRUE;
- break;
-
- case PROCESS_FILE_NO_FILE_PROCESSED:
- /* We never got to try to read the file, so there are no tap
- results to dump. Exit with an error status. */
- exit_status = 2;
- break;
-
- case PROCESS_FILE_ERROR:
- /* We still dump out the results of taps, etc., as we might have
- read some packets; however, we exit with an error status. */
- draw_taps = TRUE;
- exit_status = 2;
- break;
-
- case PROCESS_FILE_INTERRUPTED:
- /* The user interrupted the read process; Don't dump out the
- result of taps, etc., and exit with an error status. */
- exit_status = 2;
- break;
- }
+ }
+ CATCH(OutOfMemoryError) {
+ fprintf(stderr,
+ "Out Of Memory.\n"
+ "\n"
+ "Sorry, but TShark has to terminate now.\n"
+ "\n"
+ "More information and workarounds can be found at\n"
+ WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
+ status = PROCESS_FILE_ERROR;
+ }
+ ENDTRY;
+
+ switch (status) {
+
+ case PROCESS_FILE_SUCCEEDED:
+ /* Everything worked OK; draw the taps. */
+ draw_taps = TRUE;
+ break;
+
+ case PROCESS_FILE_NO_FILE_PROCESSED:
+ /* We never got to try to read the file, so there are no tap
+ results to dump. Exit with an error status. */
+ exit_status = 2;
+ break;
+
+ case PROCESS_FILE_ERROR:
+ /* We still dump out the results of taps, etc., as we might have
+ read some packets; however, we exit with an error status. */
+ draw_taps = TRUE;
+ exit_status = 2;
+ break;
+
+ case PROCESS_FILE_INTERRUPTED:
+ /* The user interrupted the read process; Don't dump out the
+ result of taps, etc., and exit with an error status. */
+ exit_status = 2;
+ break;
+ }
- if (pdu_export_arg) {
- if (!exp_pdu_close(&exp_pdu_tap_data, &err, &err_info)) {
- cfile_close_failure_message(exp_pdu_filename, err, err_info);
- exit_status = 2;
+ if (pdu_export_arg) {
+ if (!exp_pdu_close(&exp_pdu_tap_data, &err, &err_info)) {
+ cfile_close_failure_message(exp_pdu_filename, err, err_info);
+ exit_status = 2;
+ }
+ g_free(pdu_export_arg);
+ g_free(exp_pdu_filename);
}
- g_free(pdu_export_arg);
- g_free(exp_pdu_filename);
- }
- } else {
- ws_debug("tshark: no capture file specified");
- /* No capture file specified, so we're supposed to do a live capture
- or get a list of link-layer types for a live capture device;
- do we have support for live captures? */
+ } else {
+ ws_debug("tshark: no capture file specified");
+ /* No capture file specified, so we're supposed to do a live capture
+ or get a list of link-layer types for a live capture device;
+ do we have support for live captures? */
#ifdef HAVE_LIBPCAP
#ifdef _WIN32
- /* Warn the user if npf.sys isn't loaded. */
- if (!npf_sys_is_running()) {
- fprintf(stderr, "The NPF driver isn't running. You may have trouble "
- "capturing or\nlisting interfaces.\n");
- }
+ /* Warn the user if npf.sys isn't loaded. */
+ if (!npf_sys_is_running()) {
+ fprintf(stderr, "The NPF driver isn't running. You may have trouble "
+ "capturing or\nlisting interfaces.\n");
+ }
#endif /* _WIN32 */
- /* if no interface was specified, pick a default */
- exit_status = capture_opts_default_iface_if_necessary(&global_capture_opts,
- ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
- if (exit_status != 0) {
- goto clean_exit;
- }
-
- /*
- * If requested, list the link layer types and/or time stamp types
- * and exit.
- */
- if (caps_queries) {
- guint i;
-
- /* Get the list of link-layer types for the capture devices. */
- exit_status = EXIT_SUCCESS;
- for (i = 0; i < global_capture_opts.ifaces->len; i++) {
- interface_options *interface_opts;
- if_capabilities_t *caps;
- char *auth_str = NULL;
+ /* if no interface was specified, pick a default */
+ exit_status = capture_opts_default_iface_if_necessary(&global_capture_opts,
+ ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
+ if (exit_status != 0) {
+ goto clean_exit;
+ }
- interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
+ /*
+ * If requested, list the link layer types and/or time stamp types
+ * and exit.
+ */
+ if (caps_queries) {
+ guint i;
+
+ /* Get the list of link-layer types for the capture devices. */
+ exit_status = EXIT_SUCCESS;
+ for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+ interface_options *interface_opts;
+ if_capabilities_t *caps;
+ char *auth_str = NULL;
+
+ interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
#ifdef HAVE_PCAP_REMOTE
- if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
- auth_str = ws_strdup_printf("%s:%s", interface_opts->auth_username, interface_opts->auth_password);
- }
+ if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
+ auth_str = ws_strdup_printf("%s:%s", interface_opts->auth_username, interface_opts->auth_password);
+ }
#endif
- caps = capture_get_if_capabilities(interface_opts->name, interface_opts->monitor_mode,
- auth_str, &err_str, &err_str_secondary, NULL);
- g_free(auth_str);
- if (caps == NULL) {
- cmdarg_err("%s%s%s", err_str, err_str_secondary ? "\n" : "", err_str_secondary ? err_str_secondary : "");
- g_free(err_str);
- g_free(err_str_secondary);
- exit_status = INVALID_CAPABILITY;
- break;
+ caps = capture_get_if_capabilities(interface_opts->name, interface_opts->monitor_mode,
+ auth_str, &err_str, &err_str_secondary, NULL);
+ g_free(auth_str);
+ if (caps == NULL) {
+ cmdarg_err("%s%s%s", err_str, err_str_secondary ? "\n" : "", err_str_secondary ? err_str_secondary : "");
+ g_free(err_str);
+ g_free(err_str_secondary);
+ exit_status = INVALID_CAPABILITY;
+ break;
+ }
+ exit_status = capture_opts_print_if_capabilities(caps, interface_opts,
+ caps_queries);
+ free_if_capabilities(caps);
+ if (exit_status != EXIT_SUCCESS) {
+ break;
+ }
+ }
+ goto clean_exit;
}
- exit_status = capture_opts_print_if_capabilities(caps, interface_opts,
- caps_queries);
- free_if_capabilities(caps);
- if (exit_status != EXIT_SUCCESS) {
- break;
+
+ /*
+ * If the standard error isn't a terminal, don't print packet counts,
+ * as they won't show up on the user's terminal and they'll get in
+ * the way of error messages in the file (to which we assume the
+ * standard error was redirected; if it's redirected to the null
+ * device, there's no point in printing packet counts anyway).
+ *
+ * Otherwise, if we're printing packet information and the standard
+ * output is a terminal (which we assume means the standard output and
+ * error are going to the same terminal), don't print packet counts,
+ * as they'll get in the way of the packet information.
+ *
+ * Otherwise, if the user specified -q, don't print packet counts.
+ *
+ * Otherwise, print packet counts.
+ *
+ * XXX - what if the user wants to do a live capture, doesn't want
+ * to save it to a file, doesn't want information printed for each
+ * packet, does want some "-z" statistic, and wants packet counts
+ * so they know whether they're seeing any packets? -q will
+ * suppress the information printed for each packet, but it'll
+ * also suppress the packet counts.
+ */
+ if (!ws_isatty(ws_fileno(stderr)))
+ print_packet_counts = FALSE;
+ else if (print_packet_info && ws_isatty(ws_fileno(stdout)))
+ print_packet_counts = FALSE;
+ else if (quiet)
+ print_packet_counts = FALSE;
+ else
+ print_packet_counts = TRUE;
+
+ if (print_packet_info) {
+ if (!write_preamble(&cfile)) {
+ show_print_file_io_error();
+ exit_status = INVALID_FILE;
+ goto clean_exit;
+ }
}
- }
- goto clean_exit;
- }
- /*
- * If the standard error isn't a terminal, don't print packet counts,
- * as they won't show up on the user's terminal and they'll get in
- * the way of error messages in the file (to which we assume the
- * standard error was redirected; if it's redirected to the null
- * device, there's no point in printing packet counts anyway).
- *
- * Otherwise, if we're printing packet information and the standard
- * output is a terminal (which we assume means the standard output and
- * error are going to the same terminal), don't print packet counts,
- * as they'll get in the way of the packet information.
- *
- * Otherwise, if the user specified -q, don't print packet counts.
- *
- * Otherwise, print packet counts.
- *
- * XXX - what if the user wants to do a live capture, doesn't want
- * to save it to a file, doesn't want information printed for each
- * packet, does want some "-z" statistic, and wants packet counts
- * so they know whether they're seeing any packets? -q will
- * suppress the information printed for each packet, but it'll
- * also suppress the packet counts.
- */
- if (!ws_isatty(ws_fileno(stderr)))
- print_packet_counts = FALSE;
- else if (print_packet_info && ws_isatty(ws_fileno(stdout)))
- print_packet_counts = FALSE;
- else if (quiet)
- print_packet_counts = FALSE;
- else
- print_packet_counts = TRUE;
+ ws_debug("tshark: performing live capture");
+
+ /* Start statistics taps; we should only do so after the capture
+ started successfully, so we know we have something to compute
+ stats, but we currently don't check for that - see below.
+
+ We do so after registering all dissectors, so that MATE will
+ have registered its field array so we can have a tap filter
+ with one of MATE's late-registered fields as part of the
+ filter. */
+ start_requested_stats();
+
+ /* Do we need to do dissection of packets? That depends on, among
+ other things, what taps are listening, so determine that after
+ starting the statistics taps. */
+ do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
+
+ /*
+ * XXX - this returns FALSE if an error occurred, but it also
+ * returns FALSE if the capture stops because a time limit
+ * was reached (and possibly other limits), so we can't assume
+ * it means an error.
+ *
+ * The capture code is a bit twisty, so it doesn't appear to
+ * be an easy fix. We just ignore the return value for now.
+ * Instead, pass on the exit status from the capture child.
+ */
+ capture();
+ exit_status = global_capture_session.fork_child_status;
+
+ if (print_packet_info) {
+ if (!write_finale()) {
+ show_print_file_io_error();
+ }
+ }
- if (print_packet_info) {
- if (!write_preamble(&cfile)) {
- show_print_file_io_error();
- exit_status = INVALID_FILE;
+ /*
+ * If we never got a capture file, don't draw the taps; we not only
+ * didn't capture any packets, we never even did any capturing.
+ */
+ if (cfile.filename != NULL)
+ draw_taps = TRUE;
+#else
+ /* No - complain. */
+ cmdarg_err("This version of TShark was not built with support for capturing packets.");
+ exit_status = INVALID_CAPTURE;
goto clean_exit;
- }
+#endif
}
- ws_debug("tshark: performing live capture");
-
- /* Start statistics taps; we should only do so after the capture
- started successfully, so we know we have something to compute
- stats, but we currently don't check for that - see below.
-
- We do so after registering all dissectors, so that MATE will
- have registered its field array so we can have a tap filter
- with one of MATE's late-registered fields as part of the
- filter. */
- start_requested_stats();
-
- /* Do we need to do dissection of packets? That depends on, among
- other things, what taps are listening, so determine that after
- starting the statistics taps. */
- do_dissection = must_do_dissection(rfcode, dfcode, pdu_export_arg);
-
- /*
- * XXX - this returns FALSE if an error occurred, but it also
- * returns FALSE if the capture stops because a time limit
- * was reached (and possibly other limits), so we can't assume
- * it means an error.
- *
- * The capture code is a bit twisty, so it doesn't appear to
- * be an easy fix. We just ignore the return value for now.
- * Instead, pass on the exit status from the capture child.
- */
- capture();
- exit_status = global_capture_session.fork_child_status;
-
- if (print_packet_info) {
- if (!write_finale()) {
- show_print_file_io_error();
- }
+ if (cfile.provider.frames != NULL) {
+ free_frame_data_sequence(cfile.provider.frames);
+ cfile.provider.frames = NULL;
}
- /*
- * If we never got a capture file, don't draw the taps; we not only
- * didn't capture any packets, we never even did any capturing.
- */
- if (cfile.filename != NULL)
- draw_taps = TRUE;
-#else
- /* No - complain. */
- cmdarg_err("This version of TShark was not built with support for capturing packets.");
- exit_status = INVALID_CAPTURE;
- goto clean_exit;
-#endif
- }
-
- if (cfile.provider.frames != NULL) {
- free_frame_data_sequence(cfile.provider.frames);
- cfile.provider.frames = NULL;
- }
+ if (draw_taps)
+ draw_tap_listeners(TRUE);
- if (draw_taps)
- draw_tap_listeners(TRUE);
-
- if (tls_session_keys_file) {
- gsize keylist_length;
- gchar *keylist = ssl_export_sessions(&keylist_length);
- write_file_binary_mode(tls_session_keys_file, keylist, keylist_length);
- g_free(keylist);
- }
+ if (tls_session_keys_file) {
+ gsize keylist_length;
+ gchar *keylist = ssl_export_sessions(&keylist_length);
+ write_file_binary_mode(tls_session_keys_file, keylist, keylist_length);
+ g_free(keylist);
+ }
- /* Memory cleanup */
- reset_tap_listeners();
- funnel_dump_all_text_windows();
- epan_free(cfile.epan);
- epan_cleanup();
- extcap_cleanup();
+ /* Memory cleanup */
+ reset_tap_listeners();
+ funnel_dump_all_text_windows();
+ epan_free(cfile.epan);
+ epan_cleanup();
+ extcap_cleanup();
- output_fields_free(output_fields);
- output_fields = NULL;
+ output_fields_free(output_fields);
+ output_fields = NULL;
clean_exit:
- cf_close(&cfile);
- g_free(cf_name);
- destroy_print_stream(print_stream);
- g_free(output_file_name);
+ cf_close(&cfile);
+ g_free(cf_name);
+ destroy_print_stream(print_stream);
+ g_free(output_file_name);
#ifdef HAVE_LIBPCAP
- capture_opts_cleanup(&global_capture_opts);
+ capture_opts_cleanup(&global_capture_opts);
#endif
- col_cleanup(&cfile.cinfo);
- free_filter_lists();
- wtap_cleanup();
- free_progdirs();
- dfilter_free(dfcode);
- g_free(dfilter);
- return exit_status;
+ col_cleanup(&cfile.cinfo);
+ free_filter_lists();
+ wtap_cleanup();
+ free_progdirs();
+ dfilter_free(dfcode);
+ g_free(dfilter);
+ return exit_status;
}
/*#define USE_BROKEN_G_MAIN_LOOP*/
#ifdef USE_BROKEN_G_MAIN_LOOP
- GMainLoop *loop;
+ GMainLoop *loop;
#else
- gboolean loop_running = FALSE;
+ gboolean loop_running = FALSE;
#endif
- guint32 packet_count = 0;
+ guint32 packet_count = 0;
typedef struct pipe_input_tag {
- gint source;
- gpointer user_data;
- ws_process_id *child_process;
- pipe_input_cb_t input_cb;
- guint pipe_input_id;
+ gint source;
+ gpointer user_data;
+ ws_process_id *child_process;
+ pipe_input_cb_t input_cb;
+ guint pipe_input_id;
#ifdef _WIN32
- GMutex *callback_running;
+ GMutex *callback_running;
#endif
} pipe_input_t;
@@ -2450,51 +2454,51 @@ static pipe_input_t pipe_input;
static gint
pipe_timer_cb(gpointer data)
{
- HANDLE handle;
- DWORD avail = 0;
- gboolean result;
- DWORD childstatus;
- pipe_input_t *pipe_input_p = data;
- gint iterations = 0;
-
- g_mutex_lock (pipe_input_p->callback_running);
-
- /* try to read data from the pipe only 5 times, to avoid blocking */
- while(iterations < 5) {
- /* Oddly enough although Named pipes don't work on win9x,
- PeekNamedPipe does !!! */
- handle = (HANDLE) _get_osfhandle (pipe_input_p->source);
- result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
-
- /* Get the child process exit status */
- GetExitCodeProcess((HANDLE)*(pipe_input_p->child_process),
- &childstatus);
-
- /* If the Peek returned an error, or there are bytes to be read
- or the childwatcher thread has terminated then call the normal
- callback */
- if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
-
- /* And call the real handler */
- if (!pipe_input_p->input_cb(pipe_input_p->source, pipe_input_p->user_data)) {
- ws_debug("input pipe closed, iterations: %u", iterations);
- /* pipe closed, return false so that the timer is stopped */
- g_mutex_unlock (pipe_input_p->callback_running);
- return FALSE;
- }
- }
- else {
- /* No data, stop now */
- break;
- }
+ HANDLE handle;
+ DWORD avail = 0;
+ gboolean result;
+ DWORD childstatus;
+ pipe_input_t *pipe_input_p = data;
+ gint iterations = 0;
+
+ g_mutex_lock (pipe_input_p->callback_running);
+
+ /* try to read data from the pipe only 5 times, to avoid blocking */
+ while(iterations < 5) {
+ /* Oddly enough although Named pipes don't work on win9x,
+ PeekNamedPipe does !!! */
+ handle = (HANDLE) _get_osfhandle (pipe_input_p->source);
+ result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
+
+ /* Get the child process exit status */
+ GetExitCodeProcess((HANDLE)*(pipe_input_p->child_process),
+ &childstatus);
+
+ /* If the Peek returned an error, or there are bytes to be read
+ or the childwatcher thread has terminated then call the normal
+ callback */
+ if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
+
+ /* And call the real handler */
+ if (!pipe_input_p->input_cb(pipe_input_p->source, pipe_input_p->user_data)) {
+ ws_debug("input pipe closed, iterations: %u", iterations);
+ /* pipe closed, return false so that the timer is stopped */
+ g_mutex_unlock (pipe_input_p->callback_running);
+ return FALSE;
+ }
+ }
+ else {
+ /* No data, stop now */
+ break;
+ }
- iterations++;
- }
+ iterations++;
+ }
- g_mutex_unlock (pipe_input_p->callback_running);
+ g_mutex_unlock (pipe_input_p->callback_running);
- /* we didn't stopped the timer, so let it run */
- return TRUE;
+ /* we didn't stopped the timer, so let it run */
+ return TRUE;
}
#endif
@@ -2503,210 +2507,210 @@ void
pipe_input_set_handler(gint source, gpointer user_data, ws_process_id *child_process, pipe_input_cb_t input_cb)
{
- pipe_input.source = source;
- pipe_input.child_process = child_process;
- pipe_input.user_data = user_data;
- pipe_input.input_cb = input_cb;
+ pipe_input.source = source;
+ pipe_input.child_process = child_process;
+ pipe_input.user_data = user_data;
+ pipe_input.input_cb = input_cb;
#ifdef _WIN32
- pipe_input.callback_running = g_new(GMutex, 1);
- g_mutex_init(pipe_input.callback_running);
- /* Tricky to use pipes in win9x, as no concept of wait. NT can
- do this but that doesn't cover all win32 platforms. GTK can do
- this but doesn't seem to work over processes. Attempt to do
- something similar here, start a timer and check for data on every
- timeout. */
- pipe_input.pipe_input_id = g_timeout_add(200, pipe_timer_cb, &pipe_input);
+ pipe_input.callback_running = g_new(GMutex, 1);
+ g_mutex_init(pipe_input.callback_running);
+ /* Tricky to use pipes in win9x, as no concept of wait. NT can
+ do this but that doesn't cover all win32 platforms. GTK can do
+ this but doesn't seem to work over processes. Attempt to do
+ something similar here, start a timer and check for data on every
+ timeout. */
+ pipe_input.pipe_input_id = g_timeout_add(200, pipe_timer_cb, &pipe_input);
#endif
}
static const nstime_t *
tshark_get_frame_ts(struct packet_provider_data *prov, guint32 frame_num)
{
- if (prov->ref && prov->ref->num == frame_num)
- return &prov->ref->abs_ts;
+ if (prov->ref && prov->ref->num == frame_num)
+ return &prov->ref->abs_ts;
- if (prov->prev_dis && prov->prev_dis->num == frame_num)
- return &prov->prev_dis->abs_ts;
+ if (prov->prev_dis && prov->prev_dis->num == frame_num)
+ return &prov->prev_dis->abs_ts;
- if (prov->prev_cap && prov->prev_cap->num == frame_num)
- return &prov->prev_cap->abs_ts;
+ if (prov->prev_cap && prov->prev_cap->num == frame_num)
+ return &prov->prev_cap->abs_ts;
- if (prov->frames) {
- frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
+ if (prov->frames) {
+ frame_data *fd = frame_data_sequence_find(prov->frames, frame_num);
- return (fd) ? &fd->abs_ts : NULL;
- }
+ return (fd) ? &fd->abs_ts : NULL;
+ }
- return NULL;
+ return NULL;
}
static epan_t *
tshark_epan_new(capture_file *cf)
{
- static const struct packet_provider_funcs funcs = {
- tshark_get_frame_ts,
- cap_file_provider_get_interface_name,
- cap_file_provider_get_interface_description,
- NULL,
- };
-
- return epan_new(&cf->provider, &funcs);
+ static const struct packet_provider_funcs funcs = {
+ tshark_get_frame_ts,
+ cap_file_provider_get_interface_name,
+ cap_file_provider_get_interface_description,
+ NULL,
+ };
+
+ return epan_new(&cf->provider, &funcs);
}
#ifdef HAVE_LIBPCAP
static gboolean
capture(void)
{
- volatile gboolean ret = TRUE;
- guint i;
- GString *str;
+ volatile gboolean ret = TRUE;
+ guint i;
+ GString *str;
#ifdef USE_TSHARK_SELECT
- fd_set readfds;
+ fd_set readfds;
#endif
#ifndef _WIN32
- struct sigaction action, oldaction;
+ struct sigaction action, oldaction;
#endif
- /* Create new dissection section. */
- epan_free(cfile.epan);
- cfile.epan = tshark_epan_new(&cfile);
+ /* Create new dissection section. */
+ epan_free(cfile.epan);
+ cfile.epan = tshark_epan_new(&cfile);
#ifdef _WIN32
- /* Catch a CTRL+C event and, if we get it, clean up and exit. */
- SetConsoleCtrlHandler(capture_cleanup, TRUE);
+ /* Catch a CTRL+C event and, if we get it, clean up and exit. */
+ SetConsoleCtrlHandler(capture_cleanup, TRUE);
#else /* _WIN32 */
- /* Catch SIGINT and SIGTERM and, if we get either of them,
- clean up and exit. If SIGHUP isn't being ignored, catch
- it too and, if we get it, clean up and exit.
-
- We restart any read that was in progress, so that it doesn't
- disrupt reading from the sync pipe. The signal handler tells
- the capture child to finish; it will report that it finished,
- or will exit abnormally, so we'll stop reading from the sync
- pipe, pick up the exit status, and quit. */
- memset(&action, 0, sizeof(action));
- action.sa_handler = capture_cleanup;
- action.sa_flags = SA_RESTART;
- sigemptyset(&action.sa_mask);
- sigaction(SIGTERM, &action, NULL);
- sigaction(SIGINT, &action, NULL);
- sigaction(SIGHUP, NULL, &oldaction);
- if (oldaction.sa_handler == SIG_DFL)
- sigaction(SIGHUP, &action, NULL);
+ /* Catch SIGINT and SIGTERM and, if we get either of them,
+ clean up and exit. If SIGHUP isn't being ignored, catch
+ it too and, if we get it, clean up and exit.
+
+ We restart any read that was in progress, so that it doesn't
+ disrupt reading from the sync pipe. The signal handler tells
+ the capture child to finish; it will report that it finished,
+ or will exit abnormally, so we'll stop reading from the sync
+ pipe, pick up the exit status, and quit. */
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = capture_cleanup;
+ action.sa_flags = SA_RESTART;
+ sigemptyset(&action.sa_mask);
+ sigaction(SIGTERM, &action, NULL);
+ sigaction(SIGINT, &action, NULL);
+ sigaction(SIGHUP, NULL, &oldaction);
+ if (oldaction.sa_handler == SIG_DFL)
+ sigaction(SIGHUP, &action, NULL);
#ifdef SIGINFO
- /* Catch SIGINFO and, if we get it and we're capturing to a file in
- quiet mode, report the number of packets we've captured.
-
- Again, restart any read that was in progress, so that it doesn't
- disrupt reading from the sync pipe. */
- action.sa_handler = report_counts_siginfo;
- action.sa_flags = SA_RESTART;
- sigemptyset(&action.sa_mask);
- sigaction(SIGINFO, &action, NULL);
+ /* Catch SIGINFO and, if we get it and we're capturing to a file in
+ quiet mode, report the number of packets we've captured.
+
+ Again, restart any read that was in progress, so that it doesn't
+ disrupt reading from the sync pipe. */
+ action.sa_handler = report_counts_siginfo;
+ action.sa_flags = SA_RESTART;
+ sigemptyset(&action.sa_mask);
+ sigaction(SIGINFO, &action, NULL);
#endif /* SIGINFO */
#endif /* _WIN32 */
- global_capture_session.state = CAPTURE_PREPARING;
+ global_capture_session.state = CAPTURE_PREPARING;
- /* Let the user know which interfaces were chosen. */
- for (i = 0; i < global_capture_opts.ifaces->len; i++) {
- interface_options *interface_opts;
+ /* Let the user know which interfaces were chosen. */
+ for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+ interface_options *interface_opts;
- interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
- g_free(interface_opts->descr);
- interface_opts->descr = get_interface_descriptive_name(interface_opts->name);
- }
- str = get_iface_list_string(&global_capture_opts, IFLIST_QUOTE_IF_DESCRIPTION);
- if (really_quiet == FALSE)
- fprintf(stderr, "Capturing on %s\n", str->str);
- fflush(stderr);
- g_string_free(str, TRUE);
-
- ret = sync_pipe_start(&global_capture_opts, capture_comments,
- &global_capture_session, &global_info_data, NULL);
-
- if (!ret)
- return FALSE;
-
- /*
- * Force synchronous resolution of IP addresses; we're doing only
- * one pass, so we can't do it in the background and fix up past
- * dissections.
- */
- set_resolution_synchrony(TRUE);
-
- /* the actual capture loop
- *
- * XXX - glib doesn't seem to provide any event based loop handling.
- *
- * XXX - for whatever reason,
- * calling g_main_loop_new() ends up in 100% cpu load.
- *
- * But that doesn't matter: in UNIX we can use select() to find an input
- * source with something to do.
- *
- * But that doesn't matter because we're in a CLI (that doesn't need to
- * update a GUI or something at the same time) so it's OK if we block
- * trying to read from the pipe.
- *
- * So all the stuff in USE_TSHARK_SELECT could be removed unless I'm
- * wrong (but I leave it there in case I am...).
- */
+ interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
+ g_free(interface_opts->descr);
+ interface_opts->descr = get_interface_descriptive_name(interface_opts->name);
+ }
+ str = get_iface_list_string(&global_capture_opts, IFLIST_QUOTE_IF_DESCRIPTION);
+ if (really_quiet == FALSE)
+ fprintf(stderr, "Capturing on %s\n", str->str);
+ fflush(stderr);
+ g_string_free(str, TRUE);
+
+ ret = sync_pipe_start(&global_capture_opts, capture_comments,
+ &global_capture_session, &global_info_data, NULL);
+
+ if (!ret)
+ return FALSE;
+
+ /*
+ * Force synchronous resolution of IP addresses; we're doing only
+ * one pass, so we can't do it in the background and fix up past
+ * dissections.
+ */
+ set_resolution_synchrony(TRUE);
+
+ /* the actual capture loop
+ *
+ * XXX - glib doesn't seem to provide any event based loop handling.
+ *
+ * XXX - for whatever reason,
+ * calling g_main_loop_new() ends up in 100% cpu load.
+ *
+ * But that doesn't matter: in UNIX we can use select() to find an input
+ * source with something to do.
+ *
+ * But that doesn't matter because we're in a CLI (that doesn't need to
+ * update a GUI or something at the same time) so it's OK if we block
+ * trying to read from the pipe.
+ *
+ * So all the stuff in USE_TSHARK_SELECT could be removed unless I'm
+ * wrong (but I leave it there in case I am...).
+ */
#ifdef USE_TSHARK_SELECT
- FD_ZERO(&readfds);
- FD_SET(pipe_input.source, &readfds);
+ FD_ZERO(&readfds);
+ FD_SET(pipe_input.source, &readfds);
#endif
- loop_running = TRUE;
+ loop_running = TRUE;
- TRY
- {
- while (loop_running)
+ TRY
{
+ while (loop_running)
+ {
#ifdef USE_TSHARK_SELECT
- ret = select(pipe_input.source+1, &readfds, NULL, NULL, NULL);
-
- if (ret == -1)
- {
- fprintf(stderr, "%s: %s\n", "select()", g_strerror(errno));
- ret = TRUE;
- loop_running = FALSE;
- } else if (ret == 1) {
+ ret = select(pipe_input.source+1, &readfds, NULL, NULL, NULL);
+
+ if (ret == -1)
+ {
+ fprintf(stderr, "%s: %s\n", "select()", g_strerror(errno));
+ ret = TRUE;
+ loop_running = FALSE;
+ } else if (ret == 1) {
#endif
- /* Call the real handler */
- if (!pipe_input.input_cb(pipe_input.source, pipe_input.user_data)) {
- ws_debug("input pipe closed");
- ret = FALSE;
- loop_running = FALSE;
- }
+ /* Call the real handler */
+ if (!pipe_input.input_cb(pipe_input.source, pipe_input.user_data)) {
+ ws_debug("input pipe closed");
+ ret = FALSE;
+ loop_running = FALSE;
+ }
#ifdef USE_TSHARK_SELECT
- }
+ }
#endif
+ }
+ }
+ CATCH(OutOfMemoryError) {
+ fprintf(stderr,
+ "Out Of Memory.\n"
+ "\n"
+ "Sorry, but TShark has to terminate now.\n"
+ "\n"
+ "More information and workarounds can be found at\n"
+ WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
+ abort();
}
- }
- CATCH(OutOfMemoryError) {
- fprintf(stderr,
- "Out Of Memory.\n"
- "\n"
- "Sorry, but TShark has to terminate now.\n"
- "\n"
- "More information and workarounds can be found at\n"
- WS_WIKI_URL("KnownBugs/OutOfMemory") "\n");
- abort();
- }
- ENDTRY;
- return ret;
+ ENDTRY;
+ return ret;
}
/* capture child detected an error */
static void
capture_input_error(capture_session *cap_session _U_, char *error_msg, char *secondary_error_msg)
{
- cmdarg_err("%s", error_msg);
- cmdarg_err_cont("%s", secondary_error_msg);
+ cmdarg_err("%s", error_msg);
+ cmdarg_err_cont("%s", secondary_error_msg);
}
@@ -2714,34 +2718,34 @@ capture_input_error(capture_session *cap_session _U_, char *error_msg, char *sec
static void
capture_input_cfilter_error(capture_session *cap_session, guint i, const char *error_message)
{
- capture_options *capture_opts = cap_session->capture_opts;
- dfilter_t *rfcode = NULL;
- interface_options *interface_opts;
-
- ws_assert(i < capture_opts->ifaces->len);
- interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
-
- if (dfilter_compile(interface_opts->cfilter, &rfcode, NULL) && rfcode != NULL) {
- cmdarg_err(
- "Invalid capture filter \"%s\" for interface '%s'.\n"
- "\n"
- "That string looks like a valid display filter; however, it isn't a valid\n"
- "capture filter (%s).\n"
- "\n"
- "Note that display filters and capture filters don't have the same syntax,\n"
- "so you can't use most display filter expressions as capture filters.\n"
- "\n"
- "See the User's Guide for a description of the capture filter syntax.",
- interface_opts->cfilter, interface_opts->descr, error_message);
- dfilter_free(rfcode);
- } else {
- cmdarg_err(
- "Invalid capture filter \"%s\" for interface '%s'.\n"
- "\n"
- "That string isn't a valid capture filter (%s).\n"
- "See the User's Guide for a description of the capture filter syntax.",
- interface_opts->cfilter, interface_opts->descr, error_message);
- }
+ capture_options *capture_opts = cap_session->capture_opts;
+ dfilter_t *rfcode = NULL;
+ interface_options *interface_opts;
+
+ ws_assert(i < capture_opts->ifaces->len);
+ interface_opts = &g_array_index(capture_opts->ifaces, interface_options, i);
+
+ if (dfilter_compile(interface_opts->cfilter, &rfcode, NULL) && rfcode != NULL) {
+ cmdarg_err(
+ "Invalid capture filter \"%s\" for interface '%s'.\n"
+ "\n"
+ "That string looks like a valid display filter; however, it isn't a valid\n"
+ "capture filter (%s).\n"
+ "\n"
+ "Note that display filters and capture filters don't have the same syntax,\n"
+ "so you can't use most display filter expressions as capture filters.\n"
+ "\n"
+ "See the User's Guide for a description of the capture filter syntax.",
+ interface_opts->cfilter, interface_opts->descr, error_message);
+ dfilter_free(rfcode);
+ } else {
+ cmdarg_err(
+ "Invalid capture filter \"%s\" for interface '%s'.\n"
+ "\n"
+ "That string isn't a valid capture filter (%s).\n"
+ "See the User's Guide for a description of the capture filter syntax.",
+ interface_opts->cfilter, interface_opts->descr, error_message);
+ }
}
@@ -2749,63 +2753,63 @@ capture_input_cfilter_error(capture_session *cap_session, guint i, const char *e
static gboolean
capture_input_new_file(capture_session *cap_session, gchar *new_file)
{
- capture_options *capture_opts = cap_session->capture_opts;
- capture_file *cf = cap_session->cf;
- gboolean is_tempfile;
- int err;
+ capture_options *capture_opts = cap_session->capture_opts;
+ capture_file *cf = cap_session->cf;
+ gboolean is_tempfile;
+ int err;
- if (cap_session->state == CAPTURE_PREPARING) {
- ws_message("Capture started.");
- }
- ws_message("File: \"%s\"", new_file);
+ if (cap_session->state == CAPTURE_PREPARING) {
+ ws_message("Capture started.");
+ }
+ ws_message("File: \"%s\"", new_file);
- ws_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
+ ws_assert(cap_session->state == CAPTURE_PREPARING || cap_session->state == CAPTURE_RUNNING);
- /* free the old filename */
- if (capture_opts->save_file != NULL) {
+ /* free the old filename */
+ if (capture_opts->save_file != NULL) {
- /* we start a new capture file, close the old one (if we had one before) */
- if (cf->state != FILE_CLOSED) {
- cf_close(cf);
- }
+ /* we start a new capture file, close the old one (if we had one before) */
+ if (cf->state != FILE_CLOSED) {
+ cf_close(cf);
+ }
- g_free(capture_opts->save_file);
- is_tempfile = FALSE;
+ g_free(capture_opts->save_file);
+ is_tempfile = FALSE;
- epan_free(cf->epan);
- cf->epan = tshark_epan_new(cf);
- } else {
- /* we didn't had a save_file before, must be a tempfile */
- is_tempfile = TRUE;
- }
-
- /* save the new filename */
- capture_opts->save_file = g_strdup(new_file);
-
- /* if we are in real-time mode, open the new file now */
- if (do_dissection) {
- /* this is probably unecessary, but better safe than sorry */
- cap_session->cf->open_type = WTAP_TYPE_AUTO;
- /* Attempt to open the capture file and set up to read from it. */
- switch(cf_open(cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
- case CF_OK:
- break;
- case CF_ERROR:
- /* Don't unlink (delete) the save file - leave it around,
- for debugging purposes. */
- g_free(capture_opts->save_file);
- capture_opts->save_file = NULL;
- return FALSE;
+ epan_free(cf->epan);
+ cf->epan = tshark_epan_new(cf);
+ } else {
+ /* we didn't had a save_file before, must be a tempfile */
+ is_tempfile = TRUE;
}
- } else if (quiet && is_tempfile) {
- cf->state = FILE_READ_ABORTED;
- cf->filename = g_strdup(new_file);
- cf->is_tempfile = is_tempfile;
- }
- cap_session->state = CAPTURE_RUNNING;
+ /* save the new filename */
+ capture_opts->save_file = g_strdup(new_file);
+
+ /* if we are in real-time mode, open the new file now */
+ if (do_dissection) {
+ /* this is probably unecessary, but better safe than sorry */
+ cap_session->cf->open_type = WTAP_TYPE_AUTO;
+ /* Attempt to open the capture file and set up to read from it. */
+ switch(cf_open(cap_session->cf, capture_opts->save_file, WTAP_TYPE_AUTO, is_tempfile, &err)) {
+ case CF_OK:
+ break;
+ case CF_ERROR:
+ /* Don't unlink (delete) the save file - leave it around,
+ for debugging purposes. */
+ g_free(capture_opts->save_file);
+ capture_opts->save_file = NULL;
+ return FALSE;
+ }
+ } else if (quiet && is_tempfile) {
+ cf->state = FILE_READ_ABORTED;
+ cf->filename = g_strdup(new_file);
+ cf->is_tempfile = is_tempfile;
+ }
- return TRUE;
+ cap_session->state = CAPTURE_RUNNING;
+
+ return TRUE;
}
@@ -2813,136 +2817,136 @@ capture_input_new_file(capture_session *cap_session, gchar *new_file)
static void
capture_input_new_packets(capture_session *cap_session, int to_read)
{
- gboolean ret;
- int err;
- gchar *err_info;
- gint64 data_offset;
- capture_file *cf = cap_session->cf;
- gboolean filtering_tap_listeners;
- guint tap_flags;
+ gboolean ret;
+ int err;
+ gchar *err_info;
+ gint64 data_offset;
+ capture_file *cf = cap_session->cf;
+ gboolean filtering_tap_listeners;
+ guint tap_flags;
#ifdef SIGINFO
- /*
- * Prevent a SIGINFO handler from writing to the standard error while
- * we're doing so or writing to the standard output; instead, have it
- * just set a flag telling us to print that information when we're done.
- */
- infodelay = TRUE;
-#endif /* SIGINFO */
-
- /* Do we have any tap listeners with filters? */
- filtering_tap_listeners = have_filtering_tap_listeners();
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- if (do_dissection) {
- gboolean create_proto_tree;
- epan_dissect_t *edt;
- wtap_rec rec;
- Buffer buf;
-
/*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a read filter;
- *
- * we're going to apply a display filter;
- *
- * we're going to print the protocol tree;
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * a postdissector wants field values or protocols
- * on the first pass;
- *
- * we have custom columns (which require field values, which
- * currently requires that we build a protocol tree).
+ * Prevent a SIGINFO handler from writing to the standard error while
+ * we're doing so or writing to the standard output; instead, have it
+ * just set a flag telling us to print that information when we're done.
*/
- create_proto_tree =
- (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
- have_custom_cols(&cf->cinfo) || dissect_color);
+ infodelay = TRUE;
+#endif /* SIGINFO */
- /* The protocol tree will be "visible", i.e., printed, only if we're
- printing packet details, which is true if we're printing stuff
- ("print_packet_info" is true) and we're in verbose mode
- ("packet_details" is true). */
- edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
+ /* Do we have any tap listeners with filters? */
+ filtering_tap_listeners = have_filtering_tap_listeners();
+
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
+
+ if (do_dissection) {
+ gboolean create_proto_tree;
+ epan_dissect_t *edt;
+ wtap_rec rec;
+ Buffer buf;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a read filter;
+ *
+ * we're going to apply a display filter;
+ *
+ * we're going to print the protocol tree;
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * a postdissector wants field values or protocols
+ * on the first pass;
+ *
+ * we have custom columns (which require field values, which
+ * currently requires that we build a protocol tree).
+ */
+ create_proto_tree =
+ (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
+ have_custom_cols(&cf->cinfo) || dissect_color);
+
+ /* The protocol tree will be "visible", i.e., printed, only if we're
+ printing packet details, which is true if we're printing stuff
+ ("print_packet_info" is true) and we're in verbose mode
+ ("packet_details" is true). */
+ edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
+
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+
+ while (to_read-- && cf->provider.wth) {
+ wtap_cleareof(cf->provider.wth);
+ ret = wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info, &data_offset);
+ reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
+ if (ret == FALSE) {
+ /* read from file failed, tell the capture child to stop */
+ sync_pipe_stop(cap_session);
+ wtap_close(cf->provider.wth);
+ cf->provider.wth = NULL;
+ } else {
+ ret = process_packet_single_pass(cf, edt, data_offset, &rec, &buf,
+ tap_flags);
+ }
+ if (ret != FALSE) {
+ /* packet successfully read and gone through the "Read Filter" */
+ packet_count++;
+ }
+ wtap_rec_reset(&rec);
+ }
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
+ epan_dissect_free(edt);
- while (to_read-- && cf->provider.wth) {
- wtap_cleareof(cf->provider.wth);
- ret = wtap_read(cf->provider.wth, &rec, &buf, &err, &err_info, &data_offset);
- reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
- if (ret == FALSE) {
- /* read from file failed, tell the capture child to stop */
- sync_pipe_stop(cap_session);
- wtap_close(cf->provider.wth);
- cf->provider.wth = NULL;
- } else {
- ret = process_packet_single_pass(cf, edt, data_offset, &rec, &buf,
- tap_flags);
- }
- if (ret != FALSE) {
- /* packet successfully read and gone through the "Read Filter" */
- packet_count++;
- }
- wtap_rec_reset(&rec);
- }
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
- epan_dissect_free(edt);
+ } else {
+ /*
+ * Dumpcap's doing all the work; we're not doing any dissection.
+ * Count all the packets it wrote.
+ */
+ packet_count += to_read;
+ }
- wtap_rec_cleanup(&rec);
- ws_buffer_free(&buf);
+ if (print_packet_counts) {
+ /* We're printing packet counts. */
+ if (packet_count != 0) {
+ fprintf(stderr, "\r%u ", packet_count);
+ /* stderr could be line buffered */
+ fflush(stderr);
+ }
+ }
- } else {
+#ifdef SIGINFO
/*
- * Dumpcap's doing all the work; we're not doing any dissection.
- * Count all the packets it wrote.
+ * Allow SIGINFO handlers to write.
*/
- packet_count += to_read;
- }
-
- if (print_packet_counts) {
- /* We're printing packet counts. */
- if (packet_count != 0) {
- fprintf(stderr, "\r%u ", packet_count);
- /* stderr could be line buffered */
- fflush(stderr);
- }
- }
+ infodelay = FALSE;
-#ifdef SIGINFO
- /*
- * Allow SIGINFO handlers to write.
- */
- infodelay = FALSE;
-
- /*
- * If a SIGINFO handler asked us to write out capture counts, do so.
- */
- if (infoprint)
- report_counts();
+ /*
+ * If a SIGINFO handler asked us to write out capture counts, do so.
+ */
+ if (infoprint)
+ report_counts();
#endif /* SIGINFO */
}
static void
report_counts(void)
{
- if ((print_packet_counts == FALSE) && (really_quiet == FALSE)) {
- /* Report the count only if we aren't printing a packet count
- as packets arrive. */
- fprintf(stderr, "%u packet%s captured\n", packet_count,
- plurality(packet_count, "", "s"));
- }
+ if ((print_packet_counts == FALSE) && (really_quiet == FALSE)) {
+ /* Report the count only if we aren't printing a packet count
+ as packets arrive. */
+ fprintf(stderr, "%u packet%s captured\n", packet_count,
+ plurality(packet_count, "", "s"));
+ }
#ifdef SIGINFO
- infoprint = FALSE; /* we just reported it */
+ infoprint = FALSE; /* we just reported it */
#endif /* SIGINFO */
}
@@ -2950,15 +2954,15 @@ report_counts(void)
static void
report_counts_siginfo(int signum _U_)
{
- int sav_errno = errno;
- /* If we've been told to delay printing, just set a flag asking
- that we print counts (if we're supposed to), otherwise print
- the count of packets captured (if we're supposed to). */
- if (infodelay)
- infoprint = TRUE;
- else
- report_counts();
- errno = sav_errno;
+ int sav_errno = errno;
+ /* If we've been told to delay printing, just set a flag asking
+ that we print counts (if we're supposed to), otherwise print
+ the count of packets captured (if we're supposed to). */
+ if (infodelay)
+ infoprint = TRUE;
+ else
+ report_counts();
+ errno = sav_errno;
}
#endif /* SIGINFO */
@@ -2967,21 +2971,21 @@ report_counts_siginfo(int signum _U_)
static void
capture_input_drops(capture_session *cap_session _U_, guint32 dropped, const char* interface_name)
{
- if (print_packet_counts) {
- /* We're printing packet counts to stderr.
- Send a newline so that we move to the line after the packet count. */
- fprintf(stderr, "\n");
- }
+ if (print_packet_counts) {
+ /* We're printing packet counts to stderr.
+ Send a newline so that we move to the line after the packet count. */
+ fprintf(stderr, "\n");
+ }
- if (dropped != 0) {
- /* We're printing packet counts to stderr.
- Send a newline so that we move to the line after the packet count. */
- if (interface_name != NULL) {
- fprintf(stderr, "%u packet%s dropped from %s\n", dropped, plurality(dropped, "", "s"), interface_name);
- } else {
- fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
+ if (dropped != 0) {
+ /* We're printing packet counts to stderr.
+ Send a newline so that we move to the line after the packet count. */
+ if (interface_name != NULL) {
+ fprintf(stderr, "%u packet%s dropped from %s\n", dropped, plurality(dropped, "", "s"), interface_name);
+ } else {
+ fprintf(stderr, "%u packet%s dropped\n", dropped, plurality(dropped, "", "s"));
+ }
}
- }
}
@@ -2992,16 +2996,16 @@ capture_input_drops(capture_session *cap_session _U_, guint32 dropped, const cha
static void
capture_input_closed(capture_session *cap_session _U_, gchar *msg)
{
- if (msg != NULL)
- fprintf(stderr, "tshark: %s\n", msg);
+ if (msg != NULL)
+ fprintf(stderr, "tshark: %s\n", msg);
- report_counts();
+ report_counts();
#ifdef USE_BROKEN_G_MAIN_LOOP
- /*g_main_loop_quit(loop);*/
- g_main_loop_quit(loop);
+ /*g_main_loop_quit(loop);*/
+ g_main_loop_quit(loop);
#else
- loop_running = FALSE;
+ loop_running = FALSE;
#endif
}
@@ -3009,130 +3013,130 @@ capture_input_closed(capture_session *cap_session _U_, gchar *msg)
static BOOL WINAPI
capture_cleanup(DWORD ctrltype _U_)
{
- /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
- Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
- is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
- like SIGTERM at least when the machine's shutting down.
-
- For now, we handle them all as indications that we should clean up
- and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
- way on UNIX.
-
- We must return TRUE so that no other handler - such as one that would
- terminate the process - gets called.
-
- XXX - for some reason, typing ^C to TShark, if you run this in
- a Cygwin console window in at least some versions of Cygwin,
- causes TShark to terminate immediately; this routine gets
- called, but the main loop doesn't get a chance to run and
- exit cleanly, at least if this is compiled with Microsoft Visual
- C++ (i.e., it's a property of the Cygwin console window or Bash;
- it happens if TShark is not built with Cygwin - for all I know,
- building it with Cygwin may make the problem go away). */
-
- /* tell the capture child to stop */
- sync_pipe_stop(&global_capture_session);
-
- /* don't stop our own loop already here, otherwise status messages and
- * cleanup wouldn't be done properly. The child will indicate the stop of
- * everything by calling capture_input_closed() later */
-
- return TRUE;
+ /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
+ Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
+ is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
+ like SIGTERM at least when the machine's shutting down.
+
+ For now, we handle them all as indications that we should clean up
+ and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
+ way on UNIX.
+
+ We must return TRUE so that no other handler - such as one that would
+ terminate the process - gets called.
+
+ XXX - for some reason, typing ^C to TShark, if you run this in
+ a Cygwin console window in at least some versions of Cygwin,
+ causes TShark to terminate immediately; this routine gets
+ called, but the main loop doesn't get a chance to run and
+ exit cleanly, at least if this is compiled with Microsoft Visual
+ C++ (i.e., it's a property of the Cygwin console window or Bash;
+ it happens if TShark is not built with Cygwin - for all I know,
+ building it with Cygwin may make the problem go away). */
+
+ /* tell the capture child to stop */
+ sync_pipe_stop(&global_capture_session);
+
+ /* don't stop our own loop already here, otherwise status messages and
+ * cleanup wouldn't be done properly. The child will indicate the stop of
+ * everything by calling capture_input_closed() later */
+
+ return TRUE;
}
#else
static void
capture_cleanup(int signum _U_)
{
- /* tell the capture child to stop */
- sync_pipe_stop(&global_capture_session);
+ /* tell the capture child to stop */
+ sync_pipe_stop(&global_capture_session);
- /* don't stop our own loop already here, otherwise status messages and
- * cleanup wouldn't be done properly. The child will indicate the stop of
- * everything by calling capture_input_closed() later */
+ /* don't stop our own loop already here, otherwise status messages and
+ * cleanup wouldn't be done properly. The child will indicate the stop of
+ * everything by calling capture_input_closed() later */
}
#endif /* _WIN32 */
#endif /* HAVE_LIBPCAP */
static gboolean
process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
- gint64 offset, wtap_rec *rec, Buffer *buf)
+ gint64 offset, wtap_rec *rec, Buffer *buf)
{
- frame_data fdlocal;
- guint32 framenum;
- gboolean passed;
-
- /* The frame number of this packet is one more than the count of
- frames in this packet. */
- framenum = cf->count + 1;
-
- /* If we're not running a display filter and we're not printing any
- packet information, we don't need to do a dissection. This means
- that all packets can be marked as 'passed'. */
- passed = TRUE;
-
- frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
-
- /* If we're going to run a read filter or a display filter, set up to
- do a dissection and do so. (This is the first pass of two passes
- over the packets, so we will not be printing any information
- from the dissection or running taps on the packet; if we're doing
- any of that, we'll do it in the second pass.) */
- if (edt) {
- /* If we're running a read filter, prime the epan_dissect_t with that
- filter. */
- if (cf->rfcode)
- epan_dissect_prime_with_dfilter(edt, cf->rfcode);
-
- if (cf->dfcode)
- epan_dissect_prime_with_dfilter(edt, cf->dfcode);
-
- /* This is the first pass, so prime the epan_dissect_t with the
- hfids postdissectors want on the first pass. */
- prime_epan_dissect_with_postdissector_wanted_hfids(edt);
-
- frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
- &cf->provider.ref, cf->provider.prev_dis);
- if (cf->provider.ref == &fdlocal) {
- ref_frame = fdlocal;
- cf->provider.ref = &ref_frame;
- }
+ frame_data fdlocal;
+ guint32 framenum;
+ gboolean passed;
+
+ /* The frame number of this packet is one more than the count of
+ frames in this packet. */
+ framenum = cf->count + 1;
+
+ /* If we're not running a display filter and we're not printing any
+ packet information, we don't need to do a dissection. This means
+ that all packets can be marked as 'passed'. */
+ passed = TRUE;
+
+ frame_data_init(&fdlocal, framenum, rec, offset, cum_bytes);
+
+ /* If we're going to run a read filter or a display filter, set up to
+ do a dissection and do so. (This is the first pass of two passes
+ over the packets, so we will not be printing any information
+ from the dissection or running taps on the packet; if we're doing
+ any of that, we'll do it in the second pass.) */
+ if (edt) {
+ /* If we're running a read filter, prime the epan_dissect_t with that
+ filter. */
+ if (cf->rfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->rfcode);
+
+ if (cf->dfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->dfcode);
+
+ /* This is the first pass, so prime the epan_dissect_t with the
+ hfids postdissectors want on the first pass. */
+ prime_epan_dissect_with_postdissector_wanted_hfids(edt);
+
+ frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
+ &cf->provider.ref, cf->provider.prev_dis);
+ if (cf->provider.ref == &fdlocal) {
+ ref_frame = fdlocal;
+ cf->provider.ref = &ref_frame;
+ }
- epan_dissect_run(edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, &fdlocal, buf),
- &fdlocal, NULL);
+ epan_dissect_run(edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, &fdlocal, buf),
+ &fdlocal, NULL);
- /* Run the read filter if we have one. */
- if (cf->rfcode)
- passed = dfilter_apply_edt(cf->rfcode, edt);
- }
+ /* Run the read filter if we have one. */
+ if (cf->rfcode)
+ passed = dfilter_apply_edt(cf->rfcode, edt);
+ }
- if (passed) {
- frame_data_set_after_dissect(&fdlocal, &cum_bytes);
- cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
+ if (passed) {
+ frame_data_set_after_dissect(&fdlocal, &cum_bytes);
+ cf->provider.prev_cap = cf->provider.prev_dis = frame_data_sequence_add(cf->provider.frames, &fdlocal);
+
+ /* If we're not doing dissection then there won't be any dependent frames.
+ * More importantly, edt.pi.dependent_frames won't be initialized because
+ * epan hasn't been initialized.
+ * if we *are* doing dissection, then mark the dependent frames, but only
+ * if a display filter was given and it matches this packet.
+ */
+ if (edt && cf->dfcode) {
+ if (dfilter_apply_edt(cf->dfcode, edt)) {
+ g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
+ }
+ }
- /* If we're not doing dissection then there won't be any dependent frames.
- * More importantly, edt.pi.dependent_frames won't be initialized because
- * epan hasn't been initialized.
- * if we *are* doing dissection, then mark the dependent frames, but only
- * if a display filter was given and it matches this packet.
- */
- if (edt && cf->dfcode) {
- if (dfilter_apply_edt(cf->dfcode, edt)) {
- g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->provider.frames);
- }
+ cf->count++;
+ } else {
+ /* if we don't add it to the frame_data_sequence, clean it up right now
+ * to avoid leaks */
+ frame_data_destroy(&fdlocal);
}
- cf->count++;
- } else {
- /* if we don't add it to the frame_data_sequence, clean it up right now
- * to avoid leaks */
- frame_data_destroy(&fdlocal);
- }
-
- if (edt)
- epan_dissect_reset(edt);
+ if (edt)
+ epan_dissect_reset(edt);
- return passed;
+ return passed;
}
/*
@@ -3145,1479 +3149,1479 @@ static gboolean read_interrupted = FALSE;
static BOOL WINAPI
read_cleanup(DWORD ctrltype _U_)
{
- /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
- Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
- is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
- like SIGTERM at least when the machine's shutting down.
-
- For now, we handle them all as indications that we should clean up
- and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
- way on UNIX.
-
- We must return TRUE so that no other handler - such as one that would
- terminate the process - gets called.
-
- XXX - for some reason, typing ^C to TShark, if you run this in
- a Cygwin console window in at least some versions of Cygwin,
- causes TShark to terminate immediately; this routine gets
- called, but the main loop doesn't get a chance to run and
- exit cleanly, at least if this is compiled with Microsoft Visual
- C++ (i.e., it's a property of the Cygwin console window or Bash;
- it happens if TShark is not built with Cygwin - for all I know,
- building it with Cygwin may make the problem go away). */
-
- /* tell the read to stop */
- read_interrupted = TRUE;
-
- return TRUE;
+ /* CTRL_C_EVENT is sort of like SIGINT, CTRL_BREAK_EVENT is unique to
+ Windows, CTRL_CLOSE_EVENT is sort of like SIGHUP, CTRL_LOGOFF_EVENT
+ is also sort of like SIGHUP, and CTRL_SHUTDOWN_EVENT is sort of
+ like SIGTERM at least when the machine's shutting down.
+
+ For now, we handle them all as indications that we should clean up
+ and quit, just as we handle SIGINT, SIGHUP, and SIGTERM in that
+ way on UNIX.
+
+ We must return TRUE so that no other handler - such as one that would
+ terminate the process - gets called.
+
+ XXX - for some reason, typing ^C to TShark, if you run this in
+ a Cygwin console window in at least some versions of Cygwin,
+ causes TShark to terminate immediately; this routine gets
+ called, but the main loop doesn't get a chance to run and
+ exit cleanly, at least if this is compiled with Microsoft Visual
+ C++ (i.e., it's a property of the Cygwin console window or Bash;
+ it happens if TShark is not built with Cygwin - for all I know,
+ building it with Cygwin may make the problem go away). */
+
+ /* tell the read to stop */
+ read_interrupted = TRUE;
+
+ return TRUE;
}
#else
static void
read_cleanup(int signum _U_)
{
- /* tell the read to stop */
- read_interrupted = TRUE;
+ /* tell the read to stop */
+ read_interrupted = TRUE;
}
#endif /* _WIN32 */
typedef enum {
- PASS_SUCCEEDED,
- PASS_READ_ERROR,
- PASS_WRITE_ERROR,
- PASS_INTERRUPTED
+ PASS_SUCCEEDED,
+ PASS_READ_ERROR,
+ PASS_WRITE_ERROR,
+ PASS_INTERRUPTED
} pass_status_t;
static pass_status_t
process_cap_file_first_pass(capture_file *cf, int max_packet_count,
- gint64 max_byte_count, int *err, gchar **err_info)
+ gint64 max_byte_count, int *err, gchar **err_info)
{
- wtap_rec rec;
- Buffer buf;
- epan_dissect_t *edt = NULL;
- gint64 data_offset;
- pass_status_t status = PASS_SUCCEEDED;
- int framenum = 0;
+ wtap_rec rec;
+ Buffer buf;
+ epan_dissect_t *edt = NULL;
+ gint64 data_offset;
+ pass_status_t status = PASS_SUCCEEDED;
+ int framenum = 0;
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
-
- /* Allocate a frame_data_sequence for all the frames. */
- cf->provider.frames = new_frame_data_sequence();
-
- if (do_dissection) {
- gboolean create_proto_tree;
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a read filter;
- *
- * we're going to apply a display filter;
- *
- * a postdissector wants field values or protocols
- * on the first pass.
- */
- create_proto_tree =
- (cf->rfcode != NULL || cf->dfcode != NULL || postdissectors_want_hfids() || dissect_color);
-
- ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
-
- /* We're not going to display the protocol tree on this pass,
- so it's not going to be "visible". */
- edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
- }
-
- ws_debug("tshark: reading records for first pass");
- *err = 0;
- while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
- if (read_interrupted) {
- status = PASS_INTERRUPTED;
- break;
+ /* Allocate a frame_data_sequence for all the frames. */
+ cf->provider.frames = new_frame_data_sequence();
+
+ if (do_dissection) {
+ gboolean create_proto_tree;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a read filter;
+ *
+ * we're going to apply a display filter;
+ *
+ * a postdissector wants field values or protocols
+ * on the first pass.
+ */
+ create_proto_tree =
+ (cf->rfcode != NULL || cf->dfcode != NULL || postdissectors_want_hfids() || dissect_color);
+
+ ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
+
+ /* We're not going to display the protocol tree on this pass,
+ so it's not going to be "visible". */
+ edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
}
- framenum++;
-
- if (process_packet_first_pass(cf, edt, data_offset, &rec, &buf)) {
- /* Stop reading if we hit a stop condition */
- if (max_packet_count > 0 && framenum >= max_packet_count) {
- ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
- *err = 0; /* This is not an error */
- break;
- }
- if (max_byte_count != 0 && data_offset >= max_byte_count) {
- ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
- data_offset, max_byte_count);
- *err = 0; /* This is not an error */
- break;
- }
+
+ ws_debug("tshark: reading records for first pass");
+ *err = 0;
+ while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
+ if (read_interrupted) {
+ status = PASS_INTERRUPTED;
+ break;
+ }
+ framenum++;
+
+ if (process_packet_first_pass(cf, edt, data_offset, &rec, &buf)) {
+ /* Stop reading if we hit a stop condition */
+ if (max_packet_count > 0 && framenum >= max_packet_count) {
+ ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
+ *err = 0; /* This is not an error */
+ break;
+ }
+ if (max_byte_count != 0 && data_offset >= max_byte_count) {
+ ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
+ data_offset, max_byte_count);
+ *err = 0; /* This is not an error */
+ break;
+ }
+ }
+ wtap_rec_reset(&rec);
}
- wtap_rec_reset(&rec);
- }
- if (*err != 0)
- status = PASS_READ_ERROR;
+ if (*err != 0)
+ status = PASS_READ_ERROR;
- if (edt)
- epan_dissect_free(edt);
+ if (edt)
+ epan_dissect_free(edt);
- /* Close the sequential I/O side, to free up memory it requires. */
- wtap_sequential_close(cf->provider.wth);
+ /* Close the sequential I/O side, to free up memory it requires. */
+ wtap_sequential_close(cf->provider.wth);
- /* Allow the protocol dissectors to free up memory that they
- * don't need after the sequential run-through of the packets. */
- postseq_cleanup_all_protocols();
+ /* Allow the protocol dissectors to free up memory that they
+ * don't need after the sequential run-through of the packets. */
+ postseq_cleanup_all_protocols();
- cf->provider.prev_dis = NULL;
- cf->provider.prev_cap = NULL;
+ cf->provider.prev_dis = NULL;
+ cf->provider.prev_cap = NULL;
- ws_buffer_free(&buf);
- wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+ wtap_rec_cleanup(&rec);
- return status;
+ return status;
}
static gboolean
process_packet_second_pass(capture_file *cf, epan_dissect_t *edt,
- frame_data *fdata, wtap_rec *rec,
- Buffer *buf, guint tap_flags)
+ frame_data *fdata, wtap_rec *rec,
+ Buffer *buf, guint tap_flags)
{
- column_info *cinfo;
- gboolean passed;
-
- /* If we're not running a display filter and we're not printing any
- packet information, we don't need to do a dissection. This means
- that all packets can be marked as 'passed'. */
- passed = TRUE;
-
- /* If we're going to print packet information, or we're going to
- run a read filter, or we're going to process taps, set up to
- do a dissection and do so. (This is the second pass of two
- passes over the packets; that's the pass where we print
- packet information or run taps.) */
- if (edt) {
- /* If we're running a display filter, prime the epan_dissect_t with that
- filter. */
- if (cf->dfcode)
- epan_dissect_prime_with_dfilter(edt, cf->dfcode);
-
- col_custom_prime_edt(edt, &cf->cinfo);
-
- /* We only need the columns if either
- 1) some tap needs the columns
- or
- 2) we're printing packet info but we're *not* verbose; in verbose
- mode, we print the protocol tree, not the protocol summary.
- */
- if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
- cinfo = &cf->cinfo;
- else
- cinfo = NULL;
+ column_info *cinfo;
+ gboolean passed;
+
+ /* If we're not running a display filter and we're not printing any
+ packet information, we don't need to do a dissection. This means
+ that all packets can be marked as 'passed'. */
+ passed = TRUE;
+
+ /* If we're going to print packet information, or we're going to
+ run a read filter, or we're going to process taps, set up to
+ do a dissection and do so. (This is the second pass of two
+ passes over the packets; that's the pass where we print
+ packet information or run taps.) */
+ if (edt) {
+ /* If we're running a display filter, prime the epan_dissect_t with that
+ filter. */
+ if (cf->dfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->dfcode);
+
+ col_custom_prime_edt(edt, &cf->cinfo);
+
+ /* We only need the columns if either
+ 1) some tap needs the columns
+ or
+ 2) we're printing packet info but we're *not* verbose; in verbose
+ mode, we print the protocol tree, not the protocol summary.
+ */
+ if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
+ cinfo = &cf->cinfo;
+ else
+ cinfo = NULL;
+
+ frame_data_set_before_dissect(fdata, &cf->elapsed_time,
+ &cf->provider.ref, cf->provider.prev_dis);
+ if (cf->provider.ref == fdata) {
+ ref_frame = *fdata;
+ cf->provider.ref = &ref_frame;
+ }
- frame_data_set_before_dissect(fdata, &cf->elapsed_time,
- &cf->provider.ref, cf->provider.prev_dis);
- if (cf->provider.ref == fdata) {
- ref_frame = *fdata;
- cf->provider.ref = &ref_frame;
- }
+ if (dissect_color) {
+ color_filters_prime_edt(edt);
+ fdata->need_colorize = 1;
+ }
- if (dissect_color) {
- color_filters_prime_edt(edt);
- fdata->need_colorize = 1;
- }
+ epan_dissect_run_with_taps(edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
+ fdata, cinfo);
- epan_dissect_run_with_taps(edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, fdata, buf),
- fdata, cinfo);
+ /* Run the read/display filter if we have one. */
+ if (cf->dfcode)
+ passed = dfilter_apply_edt(cf->dfcode, edt);
+ }
- /* Run the read/display filter if we have one. */
- if (cf->dfcode)
- passed = dfilter_apply_edt(cf->dfcode, edt);
- }
+ if (passed) {
+ frame_data_set_after_dissect(fdata, &cum_bytes);
+ /* Process this packet. */
+ if (print_packet_info) {
+ /* We're printing packet information; print the information for
+ this packet. */
+ print_packet(cf, edt);
+
+ /* If we're doing "line-buffering", flush the standard output
+ after every packet. See the comment above, for the "-l"
+ option, for an explanation of why we do that. */
+ if (line_buffered)
+ fflush(stdout);
+
+ if (ferror(stdout)) {
+ show_print_file_io_error();
+ exit(2);
+ }
+ }
+ cf->provider.prev_dis = fdata;
+ }
+ cf->provider.prev_cap = fdata;
- if (passed) {
- frame_data_set_after_dissect(fdata, &cum_bytes);
- /* Process this packet. */
- if (print_packet_info) {
- /* We're printing packet information; print the information for
- this packet. */
- print_packet(cf, edt);
-
- /* If we're doing "line-buffering", flush the standard output
- after every packet. See the comment above, for the "-l"
- option, for an explanation of why we do that. */
- if (line_buffered)
- fflush(stdout);
-
- if (ferror(stdout)) {
- show_print_file_io_error();
- exit(2);
- }
+ if (edt) {
+ epan_dissect_reset(edt);
}
- cf->provider.prev_dis = fdata;
- }
- cf->provider.prev_cap = fdata;
-
- if (edt) {
- epan_dissect_reset(edt);
- }
- return passed || fdata->dependent_of_displayed;
+ return passed || fdata->dependent_of_displayed;
}
static gboolean
process_new_idbs(wtap *wth, wtap_dumper *pdh, int *err, gchar **err_info)
{
- wtap_block_t if_data;
-
- while ((if_data = wtap_get_next_interface_description(wth)) != NULL) {
- /*
- * Only add interface blocks if the output file supports (meaning
- * *requires*) them.
- *
- * That mean that the abstract interface provided by libwiretap
- * involves WTAP_BLOCK_IF_ID_AND_INFO blocks.
- */
- if (pdh != NULL) {
- if (wtap_file_type_subtype_supports_block(wtap_dump_file_type_subtype(pdh), WTAP_BLOCK_IF_ID_AND_INFO) != BLOCK_NOT_SUPPORTED) {
- if (!wtap_dump_add_idb(pdh, if_data, err, err_info))
- return FALSE;
- }
+ wtap_block_t if_data;
+
+ while ((if_data = wtap_get_next_interface_description(wth)) != NULL) {
+ /*
+ * Only add interface blocks if the output file supports (meaning
+ * *requires*) them.
+ *
+ * That mean that the abstract interface provided by libwiretap
+ * involves WTAP_BLOCK_IF_ID_AND_INFO blocks.
+ */
+ if (pdh != NULL) {
+ if (wtap_file_type_subtype_supports_block(wtap_dump_file_type_subtype(pdh), WTAP_BLOCK_IF_ID_AND_INFO) != BLOCK_NOT_SUPPORTED) {
+ if (!wtap_dump_add_idb(pdh, if_data, err, err_info))
+ return FALSE;
+ }
+ }
}
- }
- return TRUE;
+ return TRUE;
}
static pass_status_t
process_cap_file_second_pass(capture_file *cf, wtap_dumper *pdh,
- int *err, gchar **err_info,
- volatile guint32 *err_framenum,
- int max_write_packet_count)
+ int *err, gchar **err_info,
+ volatile guint32 *err_framenum,
+ int max_write_packet_count)
{
- wtap_rec rec;
- Buffer buf;
- int framenum = 0;
- int write_framenum = 0;
- frame_data *fdata;
- gboolean filtering_tap_listeners;
- guint tap_flags;
- epan_dissect_t *edt = NULL;
- pass_status_t status = PASS_SUCCEEDED;
-
- /*
- * Process whatever IDBs we haven't seen yet. This will be all
- * the IDBs in the file, as we've finished reading it; they'll
- * all be at the beginning of the output file.
- */
- if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
- *err_framenum = 0;
- return PASS_WRITE_ERROR;
- }
-
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
-
- /* Do we have any tap listeners with filters? */
- filtering_tap_listeners = have_filtering_tap_listeners();
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- if (do_dissection) {
- gboolean create_proto_tree;
+ wtap_rec rec;
+ Buffer buf;
+ int framenum = 0;
+ int write_framenum = 0;
+ frame_data *fdata;
+ gboolean filtering_tap_listeners;
+ guint tap_flags;
+ epan_dissect_t *edt = NULL;
+ pass_status_t status = PASS_SUCCEEDED;
/*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a display filter;
- *
- * we're going to print the protocol tree;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * we have custom columns (which require field values, which
- * currently requires that we build a protocol tree).
+ * Process whatever IDBs we haven't seen yet. This will be all
+ * the IDBs in the file, as we've finished reading it; they'll
+ * all be at the beginning of the output file.
*/
- create_proto_tree =
- (cf->dfcode || print_details || filtering_tap_listeners ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo) || dissect_color);
-
- ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
-
- /* The protocol tree will be "visible", i.e., printed, only if we're
- printing packet details, which is true if we're printing stuff
- ("print_packet_info" is true) and we're in verbose mode
- ("packet_details" is true). */
- edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
- }
-
- /*
- * Force synchronous resolution of IP addresses; in this pass, we
- * can't do it in the background and fix up past dissections.
- */
- set_resolution_synchrony(TRUE);
-
- for (framenum = 1; framenum <= (int)cf->count; framenum++) {
- if (read_interrupted) {
- status = PASS_INTERRUPTED;
- break;
+ if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
+ *err_framenum = 0;
+ return PASS_WRITE_ERROR;
}
- fdata = frame_data_sequence_find(cf->provider.frames, framenum);
- if (!wtap_seek_read(cf->provider.wth, fdata->file_off, &rec, &buf, err,
- err_info)) {
- /* Error reading from the input file. */
- status = PASS_READ_ERROR;
- break;
+
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+
+ /* Do we have any tap listeners with filters? */
+ filtering_tap_listeners = have_filtering_tap_listeners();
+
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
+
+ if (do_dissection) {
+ gboolean create_proto_tree;
+
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a display filter;
+ *
+ * we're going to print the protocol tree;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * we have custom columns (which require field values, which
+ * currently requires that we build a protocol tree).
+ */
+ create_proto_tree =
+ (cf->dfcode || print_details || filtering_tap_listeners ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo) || dissect_color);
+
+ ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
+
+ /* The protocol tree will be "visible", i.e., printed, only if we're
+ printing packet details, which is true if we're printing stuff
+ ("print_packet_info" is true) and we're in verbose mode
+ ("packet_details" is true). */
+ edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
}
- ws_debug("tshark: invoking process_packet_second_pass() for frame #%d", framenum);
- if (process_packet_second_pass(cf, edt, fdata, &rec, &buf, tap_flags)) {
- /* Either there's no read filtering or this packet passed the
- filter, so, if we're writing to a capture file, write
- this packet out. */
- write_framenum++;
- if (pdh != NULL) {
- ws_debug("tshark: writing packet #%d to outfile packet #%d", framenum, write_framenum);
- if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
- /* Error writing to the output file. */
- ws_debug("tshark: error writing to a capture file (%d)", *err);
- *err_framenum = framenum;
- status = PASS_WRITE_ERROR;
- break;
+
+ /*
+ * Force synchronous resolution of IP addresses; in this pass, we
+ * can't do it in the background and fix up past dissections.
+ */
+ set_resolution_synchrony(TRUE);
+
+ for (framenum = 1; framenum <= (int)cf->count; framenum++) {
+ if (read_interrupted) {
+ status = PASS_INTERRUPTED;
+ break;
}
- /* Stop reading if we hit a stop condition */
- if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
- ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
- *err = 0; /* This is not an error */
- break;
+ fdata = frame_data_sequence_find(cf->provider.frames, framenum);
+ if (!wtap_seek_read(cf->provider.wth, fdata->file_off, &rec, &buf, err,
+ err_info)) {
+ /* Error reading from the input file. */
+ status = PASS_READ_ERROR;
+ break;
+ }
+ ws_debug("tshark: invoking process_packet_second_pass() for frame #%d", framenum);
+ if (process_packet_second_pass(cf, edt, fdata, &rec, &buf, tap_flags)) {
+ /* Either there's no read filtering or this packet passed the
+ filter, so, if we're writing to a capture file, write
+ this packet out. */
+ write_framenum++;
+ if (pdh != NULL) {
+ ws_debug("tshark: writing packet #%d to outfile packet #%d", framenum, write_framenum);
+ if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
+ /* Error writing to the output file. */
+ ws_debug("tshark: error writing to a capture file (%d)", *err);
+ *err_framenum = framenum;
+ status = PASS_WRITE_ERROR;
+ break;
+ }
+ /* Stop reading if we hit a stop condition */
+ if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
+ ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
+ *err = 0; /* This is not an error */
+ break;
+ }
+ }
}
- }
+ wtap_rec_reset(&rec);
}
- wtap_rec_reset(&rec);
- }
- if (edt)
- epan_dissect_free(edt);
+ if (edt)
+ epan_dissect_free(edt);
- ws_buffer_free(&buf);
- wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+ wtap_rec_cleanup(&rec);
- return status;
+ return status;
}
static pass_status_t
process_cap_file_single_pass(capture_file *cf, wtap_dumper *pdh,
- int max_packet_count, gint64 max_byte_count,
- int max_write_packet_count,
- int *err, gchar **err_info,
- volatile guint32 *err_framenum)
+ int max_packet_count, gint64 max_byte_count,
+ int max_write_packet_count,
+ int *err, gchar **err_info,
+ volatile guint32 *err_framenum)
{
- wtap_rec rec;
- Buffer buf;
- gboolean create_proto_tree = FALSE;
- gboolean filtering_tap_listeners;
- guint tap_flags;
- int framenum = 0;
- int write_framenum = 0;
- epan_dissect_t *edt = NULL;
- gint64 data_offset;
- pass_status_t status = PASS_SUCCEEDED;
-
- wtap_rec_init(&rec);
- ws_buffer_init(&buf, 1514);
-
- /* Do we have any tap listeners with filters? */
- filtering_tap_listeners = have_filtering_tap_listeners();
-
- /* Get the union of the flags for all tap listeners. */
- tap_flags = union_of_tap_listener_flags();
-
- if (do_dissection) {
- /*
- * Determine whether we need to create a protocol tree.
- * We do if:
- *
- * we're going to apply a read filter;
- *
- * we're going to apply a display filter;
- *
- * we're going to print the protocol tree;
- *
- * one of the tap listeners is going to apply a filter;
- *
- * one of the tap listeners requires a protocol tree;
- *
- * a postdissector wants field values or protocols
- * on the first pass;
- *
- * we have custom columns (which require field values, which
- * currently requires that we build a protocol tree).
- */
- create_proto_tree =
- (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
- (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
- have_custom_cols(&cf->cinfo) || dissect_color);
-
- ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
-
- /* The protocol tree will be "visible", i.e., printed, only if we're
- printing packet details, which is true if we're printing stuff
- ("print_packet_info" is true) and we're in verbose mode
- ("packet_details" is true). */
- edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
- }
-
- /*
- * Force synchronous resolution of IP addresses; we're doing only
- * one pass, so we can't do it in the background and fix up past
- * dissections.
- */
- set_resolution_synchrony(TRUE);
-
- *err = 0;
- while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
- if (read_interrupted) {
- status = PASS_INTERRUPTED;
- break;
+ wtap_rec rec;
+ Buffer buf;
+ gboolean create_proto_tree = FALSE;
+ gboolean filtering_tap_listeners;
+ guint tap_flags;
+ int framenum = 0;
+ int write_framenum = 0;
+ epan_dissect_t *edt = NULL;
+ gint64 data_offset;
+ pass_status_t status = PASS_SUCCEEDED;
+
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+
+ /* Do we have any tap listeners with filters? */
+ filtering_tap_listeners = have_filtering_tap_listeners();
+
+ /* Get the union of the flags for all tap listeners. */
+ tap_flags = union_of_tap_listener_flags();
+
+ if (do_dissection) {
+ /*
+ * Determine whether we need to create a protocol tree.
+ * We do if:
+ *
+ * we're going to apply a read filter;
+ *
+ * we're going to apply a display filter;
+ *
+ * we're going to print the protocol tree;
+ *
+ * one of the tap listeners is going to apply a filter;
+ *
+ * one of the tap listeners requires a protocol tree;
+ *
+ * a postdissector wants field values or protocols
+ * on the first pass;
+ *
+ * we have custom columns (which require field values, which
+ * currently requires that we build a protocol tree).
+ */
+ create_proto_tree =
+ (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
+ (tap_flags & TL_REQUIRES_PROTO_TREE) || postdissectors_want_hfids() ||
+ have_custom_cols(&cf->cinfo) || dissect_color);
+
+ ws_debug("tshark: create_proto_tree = %s", create_proto_tree ? "TRUE" : "FALSE");
+
+ /* The protocol tree will be "visible", i.e., printed, only if we're
+ printing packet details, which is true if we're printing stuff
+ ("print_packet_info" is true) and we're in verbose mode
+ ("packet_details" is true). */
+ edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
}
- framenum++;
/*
- * Process whatever IDBs we haven't seen yet.
+ * Force synchronous resolution of IP addresses; we're doing only
+ * one pass, so we can't do it in the background and fix up past
+ * dissections.
*/
- if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
- *err_framenum = framenum;
- status = PASS_WRITE_ERROR;
- break;
- }
+ set_resolution_synchrony(TRUE);
- ws_debug("tshark: processing packet #%d", framenum);
-
- reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
-
- if (process_packet_single_pass(cf, edt, data_offset, &rec, &buf, tap_flags)) {
- /* Either there's no read filtering or this packet passed the
- filter, so, if we're writing to a capture file, write
- this packet out. */
- write_framenum++;
- if (pdh != NULL) {
- ws_debug("tshark: writing packet #%d to outfile as #%d",
- framenum, write_framenum);
- if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
- /* Error writing to the output file. */
- ws_debug("tshark: error writing to a capture file (%d)", *err);
- *err_framenum = framenum;
- status = PASS_WRITE_ERROR;
- break;
+ *err = 0;
+ while (wtap_read(cf->provider.wth, &rec, &buf, err, err_info, &data_offset)) {
+ if (read_interrupted) {
+ status = PASS_INTERRUPTED;
+ break;
}
- }
- }
- /* Stop reading if we hit a stop condition */
- if (max_packet_count > 0 && framenum >= max_packet_count) {
- ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
- *err = 0; /* This is not an error */
- break;
- }
- if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
- ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
- *err = 0; /* This is not an error */
- break;
- }
- if (max_byte_count != 0 && data_offset >= max_byte_count) {
- ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
+ framenum++;
+
+ /*
+ * Process whatever IDBs we haven't seen yet.
+ */
+ if (!process_new_idbs(cf->provider.wth, pdh, err, err_info)) {
+ *err_framenum = framenum;
+ status = PASS_WRITE_ERROR;
+ break;
+ }
+
+ ws_debug("tshark: processing packet #%d", framenum);
+
+ reset_epan_mem(cf, edt, create_proto_tree, print_packet_info && print_details);
+
+ if (process_packet_single_pass(cf, edt, data_offset, &rec, &buf, tap_flags)) {
+ /* Either there's no read filtering or this packet passed the
+ filter, so, if we're writing to a capture file, write
+ this packet out. */
+ write_framenum++;
+ if (pdh != NULL) {
+ ws_debug("tshark: writing packet #%d to outfile as #%d",
+ framenum, write_framenum);
+ if (!wtap_dump(pdh, &rec, ws_buffer_start_ptr(&buf), err, err_info)) {
+ /* Error writing to the output file. */
+ ws_debug("tshark: error writing to a capture file (%d)", *err);
+ *err_framenum = framenum;
+ status = PASS_WRITE_ERROR;
+ break;
+ }
+ }
+ }
+ /* Stop reading if we hit a stop condition */
+ if (max_packet_count > 0 && framenum >= max_packet_count) {
+ ws_debug("tshark: max_packet_count (%d) reached", max_packet_count);
+ *err = 0; /* This is not an error */
+ break;
+ }
+ if (max_write_packet_count > 0 && write_framenum >= max_write_packet_count) {
+ ws_debug("tshark: max_write_packet_count (%d) reached", max_write_packet_count);
+ *err = 0; /* This is not an error */
+ break;
+ }
+ if (max_byte_count != 0 && data_offset >= max_byte_count) {
+ ws_debug("tshark: max_byte_count (%" PRId64 "/%" PRId64 ") reached",
data_offset, max_byte_count);
- *err = 0; /* This is not an error */
- break;
+ *err = 0; /* This is not an error */
+ break;
+ }
+ wtap_rec_reset(&rec);
+ }
+ if (*err != 0 && status == PASS_SUCCEEDED) {
+ /* Error reading from the input file. */
+ status = PASS_READ_ERROR;
}
- wtap_rec_reset(&rec);
- }
- if (*err != 0 && status == PASS_SUCCEEDED) {
- /* Error reading from the input file. */
- status = PASS_READ_ERROR;
- }
- if (edt)
- epan_dissect_free(edt);
+ if (edt)
+ epan_dissect_free(edt);
- ws_buffer_free(&buf);
- wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+ wtap_rec_cleanup(&rec);
- return status;
+ return status;
}
static process_file_status_t
process_cap_file(capture_file *cf, char *save_file, int out_file_type,
- gboolean out_file_name_res, int max_packet_count, gint64 max_byte_count,
- int max_write_packet_count)
+ gboolean out_file_name_res, int max_packet_count, gint64 max_byte_count,
+ int max_write_packet_count)
{
- process_file_status_t status = PROCESS_FILE_SUCCEEDED;
- wtap_dumper *pdh;
+ process_file_status_t status = PROCESS_FILE_SUCCEEDED;
+ wtap_dumper *pdh;
#ifndef _WIN32
- struct sigaction action, oldaction;
+ struct sigaction action, oldaction;
#endif
- int err = 0, err_pass1 = 0;
- gchar *err_info = NULL, *err_info_pass1 = NULL;
- volatile guint32 err_framenum;
- wtap_dump_params params = WTAP_DUMP_PARAMS_INIT;
- char *shb_user_appl;
- pass_status_t first_pass_status, second_pass_status;
- gboolean pcapng_pcapng_workaround = false;
- wtapng_iface_descriptions_t if_tmp;
-
- if (save_file != NULL) {
- /* Set up to write to the capture file. */
- wtap_dump_params_init_no_idbs(&params, cf->provider.wth);
-
- /* workaround for pcapng -> pcapng (e.g., when pcapng starts with a custom block) */
- if (out_file_type == wtap_pcapng_file_type_subtype() && params.encap == WTAP_ENCAP_UNKNOWN) {
- pcapng_pcapng_workaround = true;
- params.encap = WTAP_ENCAP_PER_PACKET;
- params.dont_copy_idbs = true; /* make sure this stay true */
- if (params.idb_inf->interface_data != NULL) {
- /* lets fake an interface, which is not copied anyway */
- g_array_insert_val(params.idb_inf->interface_data, 0, if_tmp);
- }
- }
+ int err = 0, err_pass1 = 0;
+ gchar *err_info = NULL, *err_info_pass1 = NULL;
+ volatile guint32 err_framenum;
+ wtap_dump_params params = WTAP_DUMP_PARAMS_INIT;
+ char *shb_user_appl;
+ pass_status_t first_pass_status, second_pass_status;
+ gboolean pcapng_pcapng_workaround = false;
+ wtapng_iface_descriptions_t if_tmp;
+
+ if (save_file != NULL) {
+ /* Set up to write to the capture file. */
+ wtap_dump_params_init_no_idbs(&params, cf->provider.wth);
+
+ /* workaround for pcapng -> pcapng (e.g., when pcapng starts with a custom block) */
+ if (out_file_type == wtap_pcapng_file_type_subtype() && params.encap == WTAP_ENCAP_UNKNOWN) {
+ pcapng_pcapng_workaround = true;
+ params.encap = WTAP_ENCAP_PER_PACKET;
+ params.dont_copy_idbs = true; /* make sure this stay true */
+ if (params.idb_inf->interface_data != NULL) {
+ /* lets fake an interface, which is not copied anyway */
+ g_array_insert_val(params.idb_inf->interface_data, 0, if_tmp);
+ }
+ }
- /* If we don't have an application name add TShark */
- if (wtap_block_get_string_option_value(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) {
- /* this is free'd by wtap_block_unref() later */
- wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "%s", get_appname_and_version());
- }
- if (capture_comments != NULL) {
- for (guint i = 0; i < capture_comments->len; i++) {
- wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0),
- OPT_COMMENT, "%s",
- (char *)g_ptr_array_index(capture_comments, i));
- }
- }
+ /* If we don't have an application name add TShark */
+ if (wtap_block_get_string_option_value(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS) {
+ /* this is free'd by wtap_block_unref() later */
+ wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "%s", get_appname_and_version());
+ }
+ if (capture_comments != NULL) {
+ for (guint i = 0; i < capture_comments->len; i++) {
+ wtap_block_add_string_option_format(g_array_index(params.shb_hdrs, wtap_block_t, 0),
+ OPT_COMMENT, "%s",
+ (char *)g_ptr_array_index(capture_comments, i));
+ }
+ }
- ws_debug("tshark: writing format type %d, to %s", out_file_type, save_file);
- if (strcmp(save_file, "-") == 0) {
- /* Write to the standard output. */
- pdh = wtap_dump_open_stdout(out_file_type, WTAP_UNCOMPRESSED, &params,
- &err, &err_info);
- } else {
- pdh = wtap_dump_open(save_file, out_file_type, WTAP_UNCOMPRESSED, &params,
- &err, &err_info);
- }
+ ws_debug("tshark: writing format type %d, to %s", out_file_type, save_file);
+ if (strcmp(save_file, "-") == 0) {
+ /* Write to the standard output. */
+ pdh = wtap_dump_open_stdout(out_file_type, WTAP_UNCOMPRESSED, &params,
+ &err, &err_info);
+ } else {
+ pdh = wtap_dump_open(save_file, out_file_type, WTAP_UNCOMPRESSED, &params,
+ &err, &err_info);
+ }
- if (pcapng_pcapng_workaround) {
- /* remove the fake interface before it will be used */
- g_array_remove_index((params.idb_inf->interface_data), 0);
- }
+ if (pcapng_pcapng_workaround) {
+ /* remove the fake interface before it will be used */
+ g_array_remove_index((params.idb_inf->interface_data), 0);
+ }
- g_free(params.idb_inf);
- params.idb_inf = NULL;
+ g_free(params.idb_inf);
+ params.idb_inf = NULL;
- if (pdh == NULL) {
- /* We couldn't set up to write to the capture file. */
- cfile_dump_open_failure_message(save_file, err, err_info,
- out_file_type);
- status = PROCESS_FILE_NO_FILE_PROCESSED;
- goto out;
- }
- } else {
- /* Set up to print packet information. */
- if (print_packet_info) {
- if (!write_preamble(cf)) {
- show_print_file_io_error();
- status = PROCESS_FILE_NO_FILE_PROCESSED;
- goto out;
- }
+ if (pdh == NULL) {
+ /* We couldn't set up to write to the capture file. */
+ cfile_dump_open_failure_message(save_file, err, err_info,
+ out_file_type);
+ status = PROCESS_FILE_NO_FILE_PROCESSED;
+ goto out;
+ }
+ } else {
+ /* Set up to print packet information. */
+ if (print_packet_info) {
+ if (!write_preamble(cf)) {
+ show_print_file_io_error();
+ status = PROCESS_FILE_NO_FILE_PROCESSED;
+ goto out;
+ }
+ }
+ pdh = NULL;
}
- pdh = NULL;
- }
#ifdef _WIN32
- /* Catch a CTRL+C event and, if we get it, clean up and exit. */
- SetConsoleCtrlHandler(read_cleanup, TRUE);
+ /* Catch a CTRL+C event and, if we get it, clean up and exit. */
+ SetConsoleCtrlHandler(read_cleanup, TRUE);
#else /* _WIN32 */
- /* Catch SIGINT and SIGTERM and, if we get either of them,
- clean up and exit. If SIGHUP isn't being ignored, catch
- it too and, if we get it, clean up and exit.
-
- We restart any read that was in progress, so that it doesn't
- disrupt reading from the sync pipe. The signal handler tells
- the capture child to finish; it will report that it finished,
- or will exit abnormally, so we'll stop reading from the sync
- pipe, pick up the exit status, and quit. */
- memset(&action, 0, sizeof(action));
- action.sa_handler = read_cleanup;
- action.sa_flags = SA_RESTART;
- sigemptyset(&action.sa_mask);
- sigaction(SIGTERM, &action, NULL);
- sigaction(SIGINT, &action, NULL);
- sigaction(SIGHUP, NULL, &oldaction);
- if (oldaction.sa_handler == SIG_DFL)
- sigaction(SIGHUP, &action, NULL);
+ /* Catch SIGINT and SIGTERM and, if we get either of them,
+ clean up and exit. If SIGHUP isn't being ignored, catch
+ it too and, if we get it, clean up and exit.
+
+ We restart any read that was in progress, so that it doesn't
+ disrupt reading from the sync pipe. The signal handler tells
+ the capture child to finish; it will report that it finished,
+ or will exit abnormally, so we'll stop reading from the sync
+ pipe, pick up the exit status, and quit. */
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = read_cleanup;
+ action.sa_flags = SA_RESTART;
+ sigemptyset(&action.sa_mask);
+ sigaction(SIGTERM, &action, NULL);
+ sigaction(SIGINT, &action, NULL);
+ sigaction(SIGHUP, NULL, &oldaction);
+ if (oldaction.sa_handler == SIG_DFL)
+ sigaction(SIGHUP, &action, NULL);
#endif /* _WIN32 */
- if (perform_two_pass_analysis) {
- ws_debug("tshark: perform_two_pass_analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
+ if (perform_two_pass_analysis) {
+ ws_debug("tshark: perform_two_pass_analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
- first_pass_status = process_cap_file_first_pass(cf, max_packet_count,
- max_byte_count,
- &err_pass1,
- &err_info_pass1);
+ first_pass_status = process_cap_file_first_pass(cf, max_packet_count,
+ max_byte_count,
+ &err_pass1,
+ &err_info_pass1);
- ws_debug("tshark: done with first pass");
+ ws_debug("tshark: done with first pass");
- if (first_pass_status == PASS_INTERRUPTED) {
- /* The first pass was interrupted; skip the second pass.
- It won't be run, so it won't get an error. */
- second_pass_status = PASS_SUCCEEDED;
- } else {
- /*
- * If we got a read error on the first pass, we still do the second
- * pass, so we can at least process the packets we read, and then
- * report the first-pass error after the second pass (and before
- * we report any second-pass errors), so all the errors show up
- * at the end.
- */
- second_pass_status = process_cap_file_second_pass(cf, pdh, &err, &err_info,
- &err_framenum,
- max_write_packet_count);
-
- ws_debug("tshark: done with second pass");
- }
- }
- else {
- /* !perform_two_pass_analysis */
- ws_debug("tshark: perform one pass analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
-
- first_pass_status = PASS_SUCCEEDED; /* There is no first pass */
- second_pass_status = process_cap_file_single_pass(cf, pdh,
- max_packet_count,
- max_byte_count,
- max_write_packet_count,
- &err, &err_info,
- &err_framenum);
- }
-
- if (first_pass_status != PASS_SUCCEEDED ||
- second_pass_status != PASS_SUCCEEDED) {
- /*
- * At least one of the passes didn't succeed; either it got a failure
- * or it was interrupted.
- */
- if (first_pass_status != PASS_INTERRUPTED ||
- second_pass_status != PASS_INTERRUPTED) {
- /* At least one of the passes got an error. */
- ws_debug("tshark: something failed along the line (%d)", err);
- /*
- * If we're printing packet data, and the standard output and error
- * are going to the same place, flush the standard output, so everything
- * buffered up is written, and then print a newline to the standard
- * error before printing the error message, to separate it from the
- * packet data. (Alas, that only works on UN*X; st_dev is meaningless,
- * and the _fstat() documentation at Microsoft doesn't indicate whether
- * st_ino is even supported.)
- */
-#ifndef _WIN32
- if (print_packet_info) {
- ws_statb64 stat_stdout, stat_stderr;
-
- if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
- if (stat_stdout.st_dev == stat_stderr.st_dev &&
- stat_stdout.st_ino == stat_stderr.st_ino) {
- fflush(stdout);
- fprintf(stderr, "\n");
- }
+ if (first_pass_status == PASS_INTERRUPTED) {
+ /* The first pass was interrupted; skip the second pass.
+ It won't be run, so it won't get an error. */
+ second_pass_status = PASS_SUCCEEDED;
+ } else {
+ /*
+ * If we got a read error on the first pass, we still do the second
+ * pass, so we can at least process the packets we read, and then
+ * report the first-pass error after the second pass (and before
+ * we report any second-pass errors), so all the errors show up
+ * at the end.
+ */
+ second_pass_status = process_cap_file_second_pass(cf, pdh, &err, &err_info,
+ &err_framenum,
+ max_write_packet_count);
+
+ ws_debug("tshark: done with second pass");
}
- }
-#endif
}
- /* Report status of pass 1 of two-pass processing. */
- switch (first_pass_status) {
-
- case PASS_SUCCEEDED:
- /* No problem. */
- break;
-
- case PASS_READ_ERROR:
- /* Read error. */
- cfile_read_failure_message(cf->filename, err_pass1, err_info_pass1);
- status = PROCESS_FILE_ERROR;
- break;
-
- case PASS_WRITE_ERROR:
- /* Won't happen on the first pass. */
- break;
-
- case PASS_INTERRUPTED:
- /* Not an error, so nothing to report. */
- status = PROCESS_FILE_INTERRUPTED;
- break;
+ else {
+ /* !perform_two_pass_analysis */
+ ws_debug("tshark: perform one pass analysis, do_dissection=%s", do_dissection ? "TRUE" : "FALSE");
+
+ first_pass_status = PASS_SUCCEEDED; /* There is no first pass */
+ second_pass_status = process_cap_file_single_pass(cf, pdh,
+ max_packet_count,
+ max_byte_count,
+ max_write_packet_count,
+ &err, &err_info,
+ &err_framenum);
}
- /* Report status of pass 2 of two-pass processing or the only pass
- of one-pass processing. */
- switch (second_pass_status) {
-
- case PASS_SUCCEEDED:
- /* No problem. */
- break;
-
- case PASS_READ_ERROR:
- /* Read error. */
- cfile_read_failure_message(cf->filename, err, err_info);
- status = PROCESS_FILE_ERROR;
- break;
-
- case PASS_WRITE_ERROR:
- /* Write error.
- XXX - framenum is not necessarily the frame number in
- the input file if there was a read filter. */
- cfile_write_failure_message(cf->filename, save_file, err, err_info,
- err_framenum, out_file_type);
- status = PROCESS_FILE_ERROR;
- break;
-
- case PASS_INTERRUPTED:
- /* Not an error, so nothing to report. */
- status = PROCESS_FILE_INTERRUPTED;
- break;
+ if (first_pass_status != PASS_SUCCEEDED ||
+ second_pass_status != PASS_SUCCEEDED) {
+ /*
+ * At least one of the passes didn't succeed; either it got a failure
+ * or it was interrupted.
+ */
+ if (first_pass_status != PASS_INTERRUPTED ||
+ second_pass_status != PASS_INTERRUPTED) {
+ /* At least one of the passes got an error. */
+ ws_debug("tshark: something failed along the line (%d)", err);
+ /*
+ * If we're printing packet data, and the standard output and error
+ * are going to the same place, flush the standard output, so everything
+ * buffered up is written, and then print a newline to the standard
+ * error before printing the error message, to separate it from the
+ * packet data. (Alas, that only works on UN*X; st_dev is meaningless,
+ * and the _fstat() documentation at Microsoft doesn't indicate whether
+ * st_ino is even supported.)
+ */
+#ifndef _WIN32
+ if (print_packet_info) {
+ ws_statb64 stat_stdout, stat_stderr;
+
+ if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
+ if (stat_stdout.st_dev == stat_stderr.st_dev &&
+ stat_stdout.st_ino == stat_stderr.st_ino) {
+ fflush(stdout);
+ fprintf(stderr, "\n");
+ }
+ }
+ }
+#endif
+ }
+ /* Report status of pass 1 of two-pass processing. */
+ switch (first_pass_status) {
+
+ case PASS_SUCCEEDED:
+ /* No problem. */
+ break;
+
+ case PASS_READ_ERROR:
+ /* Read error. */
+ cfile_read_failure_message(cf->filename, err_pass1, err_info_pass1);
+ status = PROCESS_FILE_ERROR;
+ break;
+
+ case PASS_WRITE_ERROR:
+ /* Won't happen on the first pass. */
+ break;
+
+ case PASS_INTERRUPTED:
+ /* Not an error, so nothing to report. */
+ status = PROCESS_FILE_INTERRUPTED;
+ break;
+ }
+
+ /* Report status of pass 2 of two-pass processing or the only pass
+ of one-pass processing. */
+ switch (second_pass_status) {
+
+ case PASS_SUCCEEDED:
+ /* No problem. */
+ break;
+
+ case PASS_READ_ERROR:
+ /* Read error. */
+ cfile_read_failure_message(cf->filename, err, err_info);
+ status = PROCESS_FILE_ERROR;
+ break;
+
+ case PASS_WRITE_ERROR:
+ /* Write error.
+ XXX - framenum is not necessarily the frame number in
+ the input file if there was a read filter. */
+ cfile_write_failure_message(cf->filename, save_file, err, err_info,
+ err_framenum, out_file_type);
+ status = PROCESS_FILE_ERROR;
+ break;
+
+ case PASS_INTERRUPTED:
+ /* Not an error, so nothing to report. */
+ status = PROCESS_FILE_INTERRUPTED;
+ break;
+ }
}
- }
- if (save_file != NULL) {
- if (second_pass_status != PASS_WRITE_ERROR) {
- if (pdh && out_file_name_res) {
- if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
- cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
- wtap_file_type_subtype_name(out_file_type));
+ if (save_file != NULL) {
+ if (second_pass_status != PASS_WRITE_ERROR) {
+ if (pdh && out_file_name_res) {
+ if (!wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list())) {
+ cmdarg_err("The file format \"%s\" doesn't support name resolution information.",
+ wtap_file_type_subtype_name(out_file_type));
+ }
+ }
+ /* Now close the capture file. */
+ if (!wtap_dump_close(pdh, &err, &err_info)) {
+ cfile_close_failure_message(save_file, err, err_info);
+ status = PROCESS_FILE_ERROR;
+ }
+ } else {
+ /* We got a write error; it was reported, so just close the dump file
+ without bothering to check for further errors. */
+ wtap_dump_close(pdh, &err, &err_info);
+ g_free(err_info);
+ status = PROCESS_FILE_ERROR;
}
- }
- /* Now close the capture file. */
- if (!wtap_dump_close(pdh, &err, &err_info)) {
- cfile_close_failure_message(save_file, err, err_info);
- status = PROCESS_FILE_ERROR;
- }
} else {
- /* We got a write error; it was reported, so just close the dump file
- without bothering to check for further errors. */
- wtap_dump_close(pdh, &err, &err_info);
- g_free(err_info);
- status = PROCESS_FILE_ERROR;
- }
- } else {
- if (print_packet_info) {
- if (!write_finale()) {
- show_print_file_io_error();
- status = PROCESS_FILE_ERROR;
- }
+ if (print_packet_info) {
+ if (!write_finale()) {
+ show_print_file_io_error();
+ status = PROCESS_FILE_ERROR;
+ }
+ }
}
- }
out:
- wtap_close(cf->provider.wth);
- cf->provider.wth = NULL;
+ wtap_close(cf->provider.wth);
+ cf->provider.wth = NULL;
- wtap_dump_params_cleanup(&params);
+ wtap_dump_params_cleanup(&params);
- return status;
+ return status;
}
static gboolean
process_packet_single_pass(capture_file *cf, epan_dissect_t *edt, gint64 offset,
- wtap_rec *rec, Buffer *buf, guint tap_flags)
+ wtap_rec *rec, Buffer *buf, guint tap_flags)
{
- frame_data fdata;
- column_info *cinfo;
- gboolean passed;
-
- /* Count this packet. */
- cf->count++;
-
- /* If we're not running a display filter and we're not printing any
- packet information, we don't need to do a dissection. This means
- that all packets can be marked as 'passed'. */
- passed = TRUE;
-
- frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
-
- /* If we're going to print packet information, or we're going to
- run a read filter, or we're going to process taps, set up to
- do a dissection and do so. (This is the one and only pass
- over the packets, so, if we'll be printing packet information
- or running taps, we'll be doing it here.) */
- if (edt) {
- /* If we're running a filter, prime the epan_dissect_t with that
- filter. */
- if (cf->dfcode)
- epan_dissect_prime_with_dfilter(edt, cf->dfcode);
-
- /* This is the first and only pass, so prime the epan_dissect_t
- with the hfids postdissectors want on the first pass. */
- prime_epan_dissect_with_postdissector_wanted_hfids(edt);
-
- col_custom_prime_edt(edt, &cf->cinfo);
-
- /* We only need the columns if either
- 1) some tap needs the columns
- or
- 2) we're printing packet info but we're *not* verbose; in verbose
- mode, we print the protocol tree, not the protocol summary.
- or
- 3) there is a column mapped as an individual field */
- if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
- cinfo = &cf->cinfo;
- else
- cinfo = NULL;
+ frame_data fdata;
+ column_info *cinfo;
+ gboolean passed;
- frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
- &cf->provider.ref, cf->provider.prev_dis);
- if (cf->provider.ref == &fdata) {
- ref_frame = fdata;
- cf->provider.ref = &ref_frame;
- }
-
- if (dissect_color) {
- color_filters_prime_edt(edt);
- fdata.need_colorize = 1;
- }
+ /* Count this packet. */
+ cf->count++;
- epan_dissect_run_with_taps(edt, cf->cd_t, rec,
- frame_tvbuff_new_buffer(&cf->provider, &fdata, buf),
- &fdata, cinfo);
+ /* If we're not running a display filter and we're not printing any
+ packet information, we don't need to do a dissection. This means
+ that all packets can be marked as 'passed'. */
+ passed = TRUE;
+
+ frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
+
+ /* If we're going to print packet information, or we're going to
+ run a read filter, or we're going to process taps, set up to
+ do a dissection and do so. (This is the one and only pass
+ over the packets, so, if we'll be printing packet information
+ or running taps, we'll be doing it here.) */
+ if (edt) {
+ /* If we're running a filter, prime the epan_dissect_t with that
+ filter. */
+ if (cf->dfcode)
+ epan_dissect_prime_with_dfilter(edt, cf->dfcode);
+
+ /* This is the first and only pass, so prime the epan_dissect_t
+ with the hfids postdissectors want on the first pass. */
+ prime_epan_dissect_with_postdissector_wanted_hfids(edt);
+
+ col_custom_prime_edt(edt, &cf->cinfo);
+
+ /* We only need the columns if either
+ 1) some tap needs the columns
+ or
+ 2) we're printing packet info but we're *not* verbose; in verbose
+ mode, we print the protocol tree, not the protocol summary.
+ or
+ 3) there is a column mapped as an individual field */
+ if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
+ cinfo = &cf->cinfo;
+ else
+ cinfo = NULL;
+
+ frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
+ &cf->provider.ref, cf->provider.prev_dis);
+ if (cf->provider.ref == &fdata) {
+ ref_frame = fdata;
+ cf->provider.ref = &ref_frame;
+ }
- /* Run the filter if we have it. */
- if (cf->dfcode)
- passed = dfilter_apply_edt(cf->dfcode, edt);
- }
+ if (dissect_color) {
+ color_filters_prime_edt(edt);
+ fdata.need_colorize = 1;
+ }
- if (passed) {
- frame_data_set_after_dissect(&fdata, &cum_bytes);
+ epan_dissect_run_with_taps(edt, cf->cd_t, rec,
+ frame_tvbuff_new_buffer(&cf->provider, &fdata, buf),
+ &fdata, cinfo);
- /* Process this packet. */
- if (print_packet_info) {
- /* We're printing packet information; print the information for
- this packet. */
- ws_assert(edt);
- print_packet(cf, edt);
-
- /* If we're doing "line-buffering", flush the standard output
- after every packet. See the comment above, for the "-l"
- option, for an explanation of why we do that. */
- if (line_buffered)
- fflush(stdout);
-
- if (ferror(stdout)) {
- show_print_file_io_error();
- exit(2);
- }
+ /* Run the filter if we have it. */
+ if (cf->dfcode)
+ passed = dfilter_apply_edt(cf->dfcode, edt);
}
- /* this must be set after print_packet() [bug #8160] */
- prev_dis_frame = fdata;
- cf->provider.prev_dis = &prev_dis_frame;
- }
+ if (passed) {
+ frame_data_set_after_dissect(&fdata, &cum_bytes);
+
+ /* Process this packet. */
+ if (print_packet_info) {
+ /* We're printing packet information; print the information for
+ this packet. */
+ ws_assert(edt);
+ print_packet(cf, edt);
+
+ /* If we're doing "line-buffering", flush the standard output
+ after every packet. See the comment above, for the "-l"
+ option, for an explanation of why we do that. */
+ if (line_buffered)
+ fflush(stdout);
+
+ if (ferror(stdout)) {
+ show_print_file_io_error();
+ exit(2);
+ }
+ }
+
+ /* this must be set after print_packet() [bug #8160] */
+ prev_dis_frame = fdata;
+ cf->provider.prev_dis = &prev_dis_frame;
+ }
- prev_cap_frame = fdata;
- cf->provider.prev_cap = &prev_cap_frame;
+ prev_cap_frame = fdata;
+ cf->provider.prev_cap = &prev_cap_frame;
- if (edt) {
- epan_dissect_reset(edt);
- frame_data_destroy(&fdata);
- }
- return passed;
+ if (edt) {
+ epan_dissect_reset(edt);
+ frame_data_destroy(&fdata);
+ }
+ return passed;
}
static gboolean
write_preamble(capture_file *cf)
{
- switch (output_action) {
+ switch (output_action) {
- case WRITE_TEXT:
- return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
+ case WRITE_TEXT:
+ return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
- case WRITE_XML:
- if (print_details)
- write_pdml_preamble(stdout, cf->filename);
- else
- write_psml_preamble(&cf->cinfo, stdout);
- return !ferror(stdout);
+ case WRITE_XML:
+ if (print_details)
+ write_pdml_preamble(stdout, cf->filename);
+ else
+ write_psml_preamble(&cf->cinfo, stdout);
+ return !ferror(stdout);
- case WRITE_FIELDS:
- write_fields_preamble(output_fields, stdout);
- return !ferror(stdout);
+ case WRITE_FIELDS:
+ write_fields_preamble(output_fields, stdout);
+ return !ferror(stdout);
- case WRITE_JSON:
- case WRITE_JSON_RAW:
- jdumper = write_json_preamble(stdout);
- return !ferror(stdout);
+ case WRITE_JSON:
+ case WRITE_JSON_RAW:
+ jdumper = write_json_preamble(stdout);
+ return !ferror(stdout);
- case WRITE_EK:
- return TRUE;
+ case WRITE_EK:
+ return TRUE;
- default:
- ws_assert_not_reached();
- return FALSE;
- }
+ default:
+ ws_assert_not_reached();
+ return FALSE;
+ }
}
static char *
get_line_buf(size_t len)
{
- static char *line_bufp = NULL;
- static size_t line_buf_len = 256;
- size_t new_line_buf_len;
-
- for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
- new_line_buf_len *= 2)
- ;
- if (line_bufp == NULL) {
- line_buf_len = new_line_buf_len;
- line_bufp = (char *)g_malloc(line_buf_len + 1);
- } else {
- if (new_line_buf_len > line_buf_len) {
- line_buf_len = new_line_buf_len;
- line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
+ static char *line_bufp = NULL;
+ static size_t line_buf_len = 256;
+ size_t new_line_buf_len;
+
+ for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
+ new_line_buf_len *= 2)
+ ;
+ if (line_bufp == NULL) {
+ line_buf_len = new_line_buf_len;
+ line_bufp = (char *)g_malloc(line_buf_len + 1);
+ } else {
+ if (new_line_buf_len > line_buf_len) {
+ line_buf_len = new_line_buf_len;
+ line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
+ }
}
- }
- return line_bufp;
+ return line_bufp;
}
static inline void
put_string(char *dest, const char *str, size_t str_len)
{
- memcpy(dest, str, str_len);
- dest[str_len] = '\0';
+ memcpy(dest, str, str_len);
+ dest[str_len] = '\0';
}
static inline void
put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
{
- size_t i;
+ size_t i;
- for (i = str_len; i < str_with_spaces; i++)
- *dest++ = ' ';
+ for (i = str_len; i < str_with_spaces; i++)
+ *dest++ = ' ';
- put_string(dest, str, str_len);
+ put_string(dest, str, str_len);
}
static inline void
put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
{
- size_t i;
+ size_t i;
- memcpy(dest, str, str_len);
- for (i = str_len; i < str_with_spaces; i++)
- dest[i] = ' ';
+ memcpy(dest, str, str_len);
+ for (i = str_len; i < str_with_spaces; i++)
+ dest[i] = ' ';
- dest[str_with_spaces] = '\0';
+ dest[str_with_spaces] = '\0';
}
static gboolean
print_columns(capture_file *cf, const epan_dissect_t *edt)
{
- char *line_bufp;
- int i;
- size_t buf_offset;
- size_t column_len;
- size_t col_len;
- col_item_t* col_item;
- gchar str_format[11];
- const color_filter_t *color_filter = NULL;
-
- line_bufp = get_line_buf(256);
- buf_offset = 0;
- *line_bufp = '\0';
-
- if (dissect_color)
- color_filter = edt->pi.fd->color_filter;
-
- for (i = 0; i < cf->cinfo.num_cols; i++) {
- col_item = &cf->cinfo.columns[i];
- /* Skip columns not marked as visible. */
- if (!get_column_visible(i))
- continue;
- switch (col_item->col_fmt) {
- case COL_NUMBER:
- column_len = col_len = strlen(col_item->col_data);
- if (column_len < 5)
- column_len = 5;
- line_bufp = get_line_buf(buf_offset + column_len);
- put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
- break;
-
- case COL_CLS_TIME:
- case COL_REL_TIME:
- case COL_ABS_TIME:
- case COL_ABS_YMD_TIME: /* XXX - wider */
- case COL_ABS_YDOY_TIME: /* XXX - wider */
- case COL_UTC_TIME:
- case COL_UTC_YMD_TIME: /* XXX - wider */
- case COL_UTC_YDOY_TIME: /* XXX - wider */
- column_len = col_len = strlen(col_item->col_data);
- if (column_len < 10)
- column_len = 10;
- line_bufp = get_line_buf(buf_offset + column_len);
- put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
- break;
-
- case COL_DEF_SRC:
- case COL_RES_SRC:
- case COL_UNRES_SRC:
- case COL_DEF_DL_SRC:
- case COL_RES_DL_SRC:
- case COL_UNRES_DL_SRC:
- case COL_DEF_NET_SRC:
- case COL_RES_NET_SRC:
- case COL_UNRES_NET_SRC:
- column_len = col_len = strlen(col_item->col_data);
- if (column_len < 12)
- column_len = 12;
- line_bufp = get_line_buf(buf_offset + column_len);
- put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
- break;
-
- case COL_DEF_DST:
- case COL_RES_DST:
- case COL_UNRES_DST:
- case COL_DEF_DL_DST:
- case COL_RES_DL_DST:
- case COL_UNRES_DL_DST:
- case COL_DEF_NET_DST:
- case COL_RES_NET_DST:
- case COL_UNRES_NET_DST:
- column_len = col_len = strlen(col_item->col_data);
- if (column_len < 12)
- column_len = 12;
- line_bufp = get_line_buf(buf_offset + column_len);
- put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
- break;
-
- default:
- column_len = strlen(col_item->col_data);
- line_bufp = get_line_buf(buf_offset + column_len);
- put_string(line_bufp + buf_offset, col_item->col_data, column_len);
- break;
- }
- buf_offset += column_len;
- if (i != cf->cinfo.num_cols - 1) {
- /*
- * This isn't the last column, so we need to print a
- * separator between this column and the next.
- *
- * If we printed a network source and are printing a
- * network destination of the same type next, separate
- * them with a UTF-8 right arrow; if we printed a network
- * destination and are printing a network source of the same
- * type next, separate them with a UTF-8 left arrow;
- * otherwise separate them with a space.
- *
- * We add enough space to the buffer for " \xe2\x86\x90 "
- * or " \xe2\x86\x92 ", even if we're only adding " ".
- */
- line_bufp = get_line_buf(buf_offset + 5);
- switch (col_item->col_fmt) {
-
- case COL_DEF_SRC:
- case COL_RES_SRC:
- case COL_UNRES_SRC:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_DST:
- case COL_RES_DST:
- case COL_UNRES_DST:
- snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
- put_string(line_bufp + buf_offset, str_format, 5);
- buf_offset += 5;
- break;
-
- default:
- put_string(line_bufp + buf_offset, delimiter_char, 1);
- buf_offset += 1;
- break;
- }
- break;
-
- case COL_DEF_DL_SRC:
- case COL_RES_DL_SRC:
- case COL_UNRES_DL_SRC:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_DL_DST:
- case COL_RES_DL_DST:
- case COL_UNRES_DL_DST:
- snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
- put_string(line_bufp + buf_offset, str_format, 5);
- buf_offset += 5;
- break;
-
- default:
- put_string(line_bufp + buf_offset, delimiter_char, 1);
- buf_offset += 1;
- break;
- }
- break;
-
- case COL_DEF_NET_SRC:
- case COL_RES_NET_SRC:
- case COL_UNRES_NET_SRC:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_NET_DST:
- case COL_RES_NET_DST:
- case COL_UNRES_NET_DST:
- snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
- put_string(line_bufp + buf_offset, str_format, 5);
- buf_offset += 5;
- break;
-
- default:
- put_string(line_bufp + buf_offset, delimiter_char, 1);
- buf_offset += 1;
- break;
- }
- break;
-
- case COL_DEF_DST:
- case COL_RES_DST:
- case COL_UNRES_DST:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_SRC:
- case COL_RES_SRC:
- case COL_UNRES_SRC:
- snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
- put_string(line_bufp + buf_offset, str_format, 5);
- buf_offset += 5;
- break;
-
- default:
- put_string(line_bufp + buf_offset, delimiter_char, 1);
- buf_offset += 1;
- break;
- }
- break;
-
- case COL_DEF_DL_DST:
- case COL_RES_DL_DST:
- case COL_UNRES_DL_DST:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_DL_SRC:
- case COL_RES_DL_SRC:
- case COL_UNRES_DL_SRC:
- snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
- put_string(line_bufp + buf_offset, str_format, 5);
- buf_offset += 5;
- break;
-
- default:
- put_string(line_bufp + buf_offset, delimiter_char, 1);
- buf_offset += 1;
- break;
+ char *line_bufp;
+ int i;
+ size_t buf_offset;
+ size_t column_len;
+ size_t col_len;
+ col_item_t* col_item;
+ gchar str_format[11];
+ const color_filter_t *color_filter = NULL;
+
+ line_bufp = get_line_buf(256);
+ buf_offset = 0;
+ *line_bufp = '\0';
+
+ if (dissect_color)
+ color_filter = edt->pi.fd->color_filter;
+
+ for (i = 0; i < cf->cinfo.num_cols; i++) {
+ col_item = &cf->cinfo.columns[i];
+ /* Skip columns not marked as visible. */
+ if (!get_column_visible(i))
+ continue;
+ switch (col_item->col_fmt) {
+ case COL_NUMBER:
+ column_len = col_len = strlen(col_item->col_data);
+ if (column_len < 5)
+ column_len = 5;
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
+ break;
+
+ case COL_CLS_TIME:
+ case COL_REL_TIME:
+ case COL_ABS_TIME:
+ case COL_ABS_YMD_TIME: /* XXX - wider */
+ case COL_ABS_YDOY_TIME: /* XXX - wider */
+ case COL_UTC_TIME:
+ case COL_UTC_YMD_TIME: /* XXX - wider */
+ case COL_UTC_YDOY_TIME: /* XXX - wider */
+ column_len = col_len = strlen(col_item->col_data);
+ if (column_len < 10)
+ column_len = 10;
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
+ break;
+
+ case COL_DEF_SRC:
+ case COL_RES_SRC:
+ case COL_UNRES_SRC:
+ case COL_DEF_DL_SRC:
+ case COL_RES_DL_SRC:
+ case COL_UNRES_DL_SRC:
+ case COL_DEF_NET_SRC:
+ case COL_RES_NET_SRC:
+ case COL_UNRES_NET_SRC:
+ column_len = col_len = strlen(col_item->col_data);
+ if (column_len < 12)
+ column_len = 12;
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
+ break;
+
+ case COL_DEF_DST:
+ case COL_RES_DST:
+ case COL_UNRES_DST:
+ case COL_DEF_DL_DST:
+ case COL_RES_DL_DST:
+ case COL_UNRES_DL_DST:
+ case COL_DEF_NET_DST:
+ case COL_RES_NET_DST:
+ case COL_UNRES_NET_DST:
+ column_len = col_len = strlen(col_item->col_data);
+ if (column_len < 12)
+ column_len = 12;
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
+ break;
+
+ default:
+ column_len = strlen(col_item->col_data);
+ line_bufp = get_line_buf(buf_offset + column_len);
+ put_string(line_bufp + buf_offset, col_item->col_data, column_len);
+ break;
}
- break;
-
- case COL_DEF_NET_DST:
- case COL_RES_NET_DST:
- case COL_UNRES_NET_DST:
- switch (cf->cinfo.columns[i+1].col_fmt) {
-
- case COL_DEF_NET_SRC:
- case COL_RES_NET_SRC:
- case COL_UNRES_NET_SRC:
- snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
- put_string(line_bufp + buf_offset, str_format, 5);
- buf_offset += 5;
- break;
-
- default:
- put_string(line_bufp + buf_offset, delimiter_char, 1);
- buf_offset += 1;
- break;
+ buf_offset += column_len;
+ if (i != cf->cinfo.num_cols - 1) {
+ /*
+ * This isn't the last column, so we need to print a
+ * separator between this column and the next.
+ *
+ * If we printed a network source and are printing a
+ * network destination of the same type next, separate
+ * them with a UTF-8 right arrow; if we printed a network
+ * destination and are printing a network source of the same
+ * type next, separate them with a UTF-8 left arrow;
+ * otherwise separate them with a space.
+ *
+ * We add enough space to the buffer for " \xe2\x86\x90 "
+ * or " \xe2\x86\x92 ", even if we're only adding " ".
+ */
+ line_bufp = get_line_buf(buf_offset + 5);
+ switch (col_item->col_fmt) {
+
+ case COL_DEF_SRC:
+ case COL_RES_SRC:
+ case COL_UNRES_SRC:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_DST:
+ case COL_RES_DST:
+ case COL_UNRES_DST:
+ snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
+ put_string(line_bufp + buf_offset, str_format, 5);
+ buf_offset += 5;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, delimiter_char, 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_DL_SRC:
+ case COL_RES_DL_SRC:
+ case COL_UNRES_DL_SRC:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_DL_DST:
+ case COL_RES_DL_DST:
+ case COL_UNRES_DL_DST:
+ snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
+ put_string(line_bufp + buf_offset, str_format, 5);
+ buf_offset += 5;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, delimiter_char, 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_NET_SRC:
+ case COL_RES_NET_SRC:
+ case COL_UNRES_NET_SRC:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_NET_DST:
+ case COL_RES_NET_DST:
+ case COL_UNRES_NET_DST:
+ snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_RIGHTWARDS_ARROW, delimiter_char);
+ put_string(line_bufp + buf_offset, str_format, 5);
+ buf_offset += 5;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, delimiter_char, 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_DST:
+ case COL_RES_DST:
+ case COL_UNRES_DST:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_SRC:
+ case COL_RES_SRC:
+ case COL_UNRES_SRC:
+ snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
+ put_string(line_bufp + buf_offset, str_format, 5);
+ buf_offset += 5;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, delimiter_char, 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_DL_DST:
+ case COL_RES_DL_DST:
+ case COL_UNRES_DL_DST:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_DL_SRC:
+ case COL_RES_DL_SRC:
+ case COL_UNRES_DL_SRC:
+ snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
+ put_string(line_bufp + buf_offset, str_format, 5);
+ buf_offset += 5;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, delimiter_char, 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ case COL_DEF_NET_DST:
+ case COL_RES_NET_DST:
+ case COL_UNRES_NET_DST:
+ switch (cf->cinfo.columns[i+1].col_fmt) {
+
+ case COL_DEF_NET_SRC:
+ case COL_RES_NET_SRC:
+ case COL_UNRES_NET_SRC:
+ snprintf(str_format, sizeof(str_format), "%s%s%s", delimiter_char, UTF8_LEFTWARDS_ARROW, delimiter_char);
+ put_string(line_bufp + buf_offset, str_format, 5);
+ buf_offset += 5;
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, delimiter_char, 1);
+ buf_offset += 1;
+ break;
+ }
+ break;
+
+ default:
+ put_string(line_bufp + buf_offset, delimiter_char, 1);
+ buf_offset += 1;
+ break;
+ }
}
- break;
-
- default:
- put_string(line_bufp + buf_offset, delimiter_char, 1);
- buf_offset += 1;
- break;
- }
}
- }
- if (dissect_color && color_filter != NULL)
- return print_line_color(print_stream, 0, line_bufp, &color_filter->fg_color, &color_filter->bg_color);
- else
- return print_line(print_stream, 0, line_bufp);
+ if (dissect_color && color_filter != NULL)
+ return print_line_color(print_stream, 0, line_bufp, &color_filter->fg_color, &color_filter->bg_color);
+ else
+ return print_line(print_stream, 0, line_bufp);
}
static gboolean
print_packet(capture_file *cf, epan_dissect_t *edt)
{
- if (print_summary || output_fields_has_cols(output_fields))
- /* Just fill in the columns. */
- epan_dissect_fill_in_columns(edt, FALSE, TRUE);
-
- /* Print summary columns and/or protocol tree */
- switch (output_action) {
-
- case WRITE_TEXT:
- if (print_summary && !print_columns(cf, edt))
- return FALSE;
- if (print_details) {
- if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
+ if (print_summary || output_fields_has_cols(output_fields))
+ /* Just fill in the columns. */
+ epan_dissect_fill_in_columns(edt, FALSE, TRUE);
+
+ /* Print summary columns and/or protocol tree */
+ switch (output_action) {
+
+ case WRITE_TEXT:
+ if (print_summary && !print_columns(cf, edt))
+ return FALSE;
+ if (print_details) {
+ if (!proto_tree_print(print_details ? print_dissections_expanded : print_dissections_none,
print_hex, edt, output_only_tables, print_stream))
- return FALSE;
- if (!print_hex) {
- if (!print_line(print_stream, 0, separator))
- return FALSE;
- }
- }
- break;
-
- case WRITE_XML:
- if (print_summary) {
- write_psml_columns(edt, stdout, dissect_color);
- return !ferror(stdout);
- }
- if (print_details) {
- write_pdml_proto_tree(output_fields, protocolfilter, protocolfilter_flags, edt, &cf->cinfo, stdout, dissect_color);
- printf("\n");
- return !ferror(stdout);
- }
- break;
+ return FALSE;
+ if (!print_hex) {
+ if (!print_line(print_stream, 0, separator))
+ return FALSE;
+ }
+ }
+ break;
+
+ case WRITE_XML:
+ if (print_summary) {
+ write_psml_columns(edt, stdout, dissect_color);
+ return !ferror(stdout);
+ }
+ if (print_details) {
+ write_pdml_proto_tree(output_fields, protocolfilter, protocolfilter_flags, edt, &cf->cinfo, stdout, dissect_color);
+ printf("\n");
+ return !ferror(stdout);
+ }
+ break;
+
+ case WRITE_FIELDS:
+ if (print_summary) {
+ /*No non-verbose "fields" format */
+ ws_assert_not_reached();
+ }
+ if (print_details) {
+ write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
+ printf("\n");
+ return !ferror(stdout);
+ }
+ break;
+
+ case WRITE_JSON:
+ if (print_summary)
+ ws_assert_not_reached();
+ if (print_details) {
+ write_json_proto_tree(output_fields, print_dissections_expanded,
+ print_hex, protocolfilter, protocolfilter_flags,
+ edt, &cf->cinfo, node_children_grouper, &jdumper);
+ return !ferror(stdout);
+ }
+ break;
+
+ case WRITE_JSON_RAW:
+ if (print_summary)
+ ws_assert_not_reached();
+ if (print_details) {
+ write_json_proto_tree(output_fields, print_dissections_none, TRUE,
+ protocolfilter, protocolfilter_flags,
+ edt, &cf->cinfo, node_children_grouper, &jdumper);
+ return !ferror(stdout);
+ }
+ break;
+
+ case WRITE_EK:
+ write_ek_proto_tree(output_fields, print_summary, print_hex, protocolfilter,
+ protocolfilter_flags, edt, &cf->cinfo, stdout);
+ return !ferror(stdout);
- case WRITE_FIELDS:
- if (print_summary) {
- /*No non-verbose "fields" format */
- ws_assert_not_reached();
- }
- if (print_details) {
- write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
- printf("\n");
- return !ferror(stdout);
- }
- break;
-
- case WRITE_JSON:
- if (print_summary)
- ws_assert_not_reached();
- if (print_details) {
- write_json_proto_tree(output_fields, print_dissections_expanded,
- print_hex, protocolfilter, protocolfilter_flags,
- edt, &cf->cinfo, node_children_grouper, &jdumper);
- return !ferror(stdout);
- }
- break;
-
- case WRITE_JSON_RAW:
- if (print_summary)
- ws_assert_not_reached();
- if (print_details) {
- write_json_proto_tree(output_fields, print_dissections_none, TRUE,
- protocolfilter, protocolfilter_flags,
- edt, &cf->cinfo, node_children_grouper, &jdumper);
- return !ferror(stdout);
+ default:
+ ws_assert_not_reached();
}
- break;
-
- case WRITE_EK:
- write_ek_proto_tree(output_fields, print_summary, print_hex, protocolfilter,
- protocolfilter_flags, edt, &cf->cinfo, stdout);
- return !ferror(stdout);
-
- default:
- ws_assert_not_reached();
- }
- if (print_hex) {
- if (print_summary || print_details) {
- if (!print_line(print_stream, 0, ""))
- return FALSE;
+ if (print_hex) {
+ if (print_summary || print_details) {
+ if (!print_line(print_stream, 0, ""))
+ return FALSE;
+ }
+ if (!print_hex_data(print_stream, edt, hexdump_source_option | hexdump_ascii_option))
+ return FALSE;
+ if (!print_line(print_stream, 0, separator))
+ return FALSE;
}
- if (!print_hex_data(print_stream, edt, hexdump_source_option | hexdump_ascii_option))
- return FALSE;
- if (!print_line(print_stream, 0, separator))
- return FALSE;
- }
- return TRUE;
+ return TRUE;
}
static gboolean
write_finale(void)
{
- switch (output_action) {
+ switch (output_action) {
- case WRITE_TEXT:
- return print_finale(print_stream);
+ case WRITE_TEXT:
+ return print_finale(print_stream);
- case WRITE_XML:
- if (print_details)
- write_pdml_finale(stdout);
- else
- write_psml_finale(stdout);
- return !ferror(stdout);
+ case WRITE_XML:
+ if (print_details)
+ write_pdml_finale(stdout);
+ else
+ write_psml_finale(stdout);
+ return !ferror(stdout);
- case WRITE_FIELDS:
- write_fields_finale(output_fields, stdout);
- return !ferror(stdout);
+ case WRITE_FIELDS:
+ write_fields_finale(output_fields, stdout);
+ return !ferror(stdout);
- case WRITE_JSON:
- case WRITE_JSON_RAW:
- write_json_finale(&jdumper);
- return !ferror(stdout);
+ case WRITE_JSON:
+ case WRITE_JSON_RAW:
+ write_json_finale(&jdumper);
+ return !ferror(stdout);
- case WRITE_EK:
- return TRUE;
+ case WRITE_EK:
+ return TRUE;
- default:
- ws_assert_not_reached();
- return FALSE;
- }
+ default:
+ ws_assert_not_reached();
+ return FALSE;
+ }
}
void
cf_close(capture_file *cf)
{
- if (cf->state == FILE_CLOSED)
- return; /* Nothing to do */
+ if (cf->state == FILE_CLOSED)
+ return; /* Nothing to do */
- if (cf->provider.wth != NULL) {
- wtap_close(cf->provider.wth);
- cf->provider.wth = NULL;
- }
- /* We have no file open... */
- if (cf->filename != NULL) {
- /* If it's a temporary file, remove it. */
- if (cf->is_tempfile)
- ws_unlink(cf->filename);
- g_free(cf->filename);
- cf->filename = NULL;
- }
-
- /* We have no file open. */
- cf->state = FILE_CLOSED;
+ if (cf->provider.wth != NULL) {
+ wtap_close(cf->provider.wth);
+ cf->provider.wth = NULL;
+ }
+ /* We have no file open... */
+ if (cf->filename != NULL) {
+ /* If it's a temporary file, remove it. */
+ if (cf->is_tempfile)
+ ws_unlink(cf->filename);
+ g_free(cf->filename);
+ cf->filename = NULL;
+ }
+
+ /* We have no file open. */
+ cf->state = FILE_CLOSED;
}
cf_status_t
cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
- wtap *wth;
- gchar *err_info;
+ wtap *wth;
+ gchar *err_info;
- wth = wtap_open_offline(fname, type, err, &err_info, perform_two_pass_analysis);
- if (wth == NULL)
- goto fail;
+ wth = wtap_open_offline(fname, type, err, &err_info, perform_two_pass_analysis);
+ if (wth == NULL)
+ goto fail;
- /* The open succeeded. Fill in the information for this file. */
+ /* The open succeeded. Fill in the information for this file. */
- cf->provider.wth = wth;
- cf->f_datalen = 0; /* not used, but set it anyway */
+ cf->provider.wth = wth;
+ cf->f_datalen = 0; /* not used, but set it anyway */
- /* Set the file name because we need it to set the follow stream filter.
- XXX - is that still true? We need it for other reasons, though,
- in any case. */
- cf->filename = g_strdup(fname);
+ /* Set the file name because we need it to set the follow stream filter.
+ XXX - is that still true? We need it for other reasons, though,
+ in any case. */
+ cf->filename = g_strdup(fname);
- /* Indicate whether it's a permanent or temporary file. */
- cf->is_tempfile = is_tempfile;
+ /* Indicate whether it's a permanent or temporary file. */
+ cf->is_tempfile = is_tempfile;
- /* No user changes yet. */
- cf->unsaved_changes = FALSE;
+ /* No user changes yet. */
+ cf->unsaved_changes = FALSE;
- cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
- cf->open_type = type;
- cf->count = 0;
- cf->drops_known = FALSE;
- cf->drops = 0;
- cf->snap = wtap_snapshot_length(cf->provider.wth);
- nstime_set_zero(&cf->elapsed_time);
- cf->provider.ref = NULL;
- cf->provider.prev_dis = NULL;
- cf->provider.prev_cap = NULL;
+ cf->cd_t = wtap_file_type_subtype(cf->provider.wth);
+ cf->open_type = type;
+ cf->count = 0;
+ cf->drops_known = FALSE;
+ cf->drops = 0;
+ cf->snap = wtap_snapshot_length(cf->provider.wth);
+ nstime_set_zero(&cf->elapsed_time);
+ cf->provider.ref = NULL;
+ cf->provider.prev_dis = NULL;
+ cf->provider.prev_cap = NULL;
- cf->state = FILE_READ_IN_PROGRESS;
+ cf->state = FILE_READ_IN_PROGRESS;
- /* Create new epan session for dissection. */
- epan_free(cf->epan);
- cf->epan = tshark_epan_new(cf);
+ /* Create new epan session for dissection. */
+ epan_free(cf->epan);
+ cf->epan = tshark_epan_new(cf);
- wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
- wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
- wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
+ wtap_set_cb_new_ipv4(cf->provider.wth, add_ipv4_name);
+ wtap_set_cb_new_ipv6(cf->provider.wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
+ wtap_set_cb_new_secrets(cf->provider.wth, secrets_wtap_callback);
- return CF_OK;
+ return CF_OK;
fail:
- cfile_open_failure_message(fname, *err, err_info);
- return CF_ERROR;
+ cfile_open_failure_message(fname, *err, err_info);
+ return CF_ERROR;
}
static void
show_print_file_io_error(void)
{
- switch (errno) {
+ switch (errno) {
- case ENOSPC:
- cmdarg_err("Not all the packets could be printed because there is "
-"no space left on the file system.");
- break;
+ case ENOSPC:
+ cmdarg_err("Not all the packets could be printed because there is "
+ "no space left on the file system.");
+ break;
#ifdef EDQUOT
- case EDQUOT:
- cmdarg_err("Not all the packets could be printed because you are "
-"too close to, or over your disk quota.");
- break;
+ case EDQUOT:
+ cmdarg_err("Not all the packets could be printed because you are "
+ "too close to, or over your disk quota.");
+ break;
#endif
- case EPIPE:
- /*
- * This almost certainly means "the next program after us in
- * the pipeline exited before we were finished writing", so
- * this isn't a real error, it just means we're done. (We
- * don't get SIGPIPE because libwireshark ignores SIGPIPE
- * to avoid getting killed if writing to the MaxMind process
- * gets SIGPIPE because that process died.)
- *
- * Presumably either that program exited deliberately (for
- * example, "head -N" read N lines and printed them), in
- * which case there's no error to report, or it terminated
- * due to an error or a signal, in which case *that's* the
- * error and that error has been reported.
- */
- break;
+ case EPIPE:
+ /*
+ * This almost certainly means "the next program after us in
+ * the pipeline exited before we were finished writing", so
+ * this isn't a real error, it just means we're done. (We
+ * don't get SIGPIPE because libwireshark ignores SIGPIPE
+ * to avoid getting killed if writing to the MaxMind process
+ * gets SIGPIPE because that process died.)
+ *
+ * Presumably either that program exited deliberately (for
+ * example, "head -N" read N lines and printed them), in
+ * which case there's no error to report, or it terminated
+ * due to an error or a signal, in which case *that's* the
+ * error and that error has been reported.
+ */
+ break;
- default:
+ default:
#ifdef _WIN32
- if (errno == EINVAL && _doserrno == ERROR_NO_DATA) {
- /*
- * XXX - on Windows, a write to a pipe where the read side
- * has been closed apparently may return the Windows error
- * ERROR_BROKEN_PIPE, which the Visual Studio C library maps
- * to EPIPE, or may return the Windows error ERROR_NO_DATA,
- * which the Visual Studio C library maps to EINVAL.
- *
- * Either of those almost certainly means "the next program
- * after us in the pipeline exited before we were finished
- * writing", so, if _doserrno is ERROR_NO_DATA, this isn't
- * a real error, it just means we're done. (Windows doesn't
- * SIGPIPE.)
- *
- * Presumably either that program exited deliberately (for
- * example, "head -N" read N lines and printed them), in
- * which case there's no error to report, or it terminated
- * due to an error or a signal, in which case *that's* the
- * error and that error has been reported.
- */
- break;
- }
-
- /*
- * It's a different error; report it, but with the error
- * message for _doserrno, which will give more detail
- * than just "Invalid argument".
- */
- cmdarg_err("An error occurred while printing packets: %s.",
- win32strerror(_doserrno));
+ if (errno == EINVAL && _doserrno == ERROR_NO_DATA) {
+ /*
+ * XXX - on Windows, a write to a pipe where the read side
+ * has been closed apparently may return the Windows error
+ * ERROR_BROKEN_PIPE, which the Visual Studio C library maps
+ * to EPIPE, or may return the Windows error ERROR_NO_DATA,
+ * which the Visual Studio C library maps to EINVAL.
+ *
+ * Either of those almost certainly means "the next program
+ * after us in the pipeline exited before we were finished
+ * writing", so, if _doserrno is ERROR_NO_DATA, this isn't
+ * a real error, it just means we're done. (Windows doesn't
+ * SIGPIPE.)
+ *
+ * Presumably either that program exited deliberately (for
+ * example, "head -N" read N lines and printed them), in
+ * which case there's no error to report, or it terminated
+ * due to an error or a signal, in which case *that's* the
+ * error and that error has been reported.
+ */
+ break;
+ }
+
+ /*
+ * It's a different error; report it, but with the error
+ * message for _doserrno, which will give more detail
+ * than just "Invalid argument".
+ */
+ cmdarg_err("An error occurred while printing packets: %s.",
+ win32strerror(_doserrno));
#else
- cmdarg_err("An error occurred while printing packets: %s.",
- g_strerror(errno));
+ cmdarg_err("An error occurred while printing packets: %s.",
+ g_strerror(errno));
#endif
- break;
- }
+ break;
+ }
}
/*
@@ -4626,9 +4630,9 @@ show_print_file_io_error(void)
static void
tshark_cmdarg_err(const char *msg_format, va_list ap)
{
- fprintf(stderr, "tshark: ");
- vfprintf(stderr, msg_format, ap);
- fprintf(stderr, "\n");
+ fprintf(stderr, "tshark: ");
+ vfprintf(stderr, msg_format, ap);
+ fprintf(stderr, "\n");
}
/*
@@ -4637,34 +4641,22 @@ tshark_cmdarg_err(const char *msg_format, va_list ap)
static void
tshark_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");
}
-static void reset_epan_mem(capture_file *cf,epan_dissect_t *edt, gboolean tree, gboolean visual)
+static void
+reset_epan_mem(capture_file *cf,epan_dissect_t *edt, gboolean tree, gboolean visual)
{
- if (!epan_auto_reset || (cf->count < epan_auto_reset_count))
- return;
+ if (!epan_auto_reset || (cf->count < epan_auto_reset_count))
+ return;
- fprintf(stderr, "resetting session.\n");
+ fprintf(stderr, "resetting session.\n");
- epan_dissect_cleanup(edt);
- epan_free(cf->epan);
+ epan_dissect_cleanup(edt);
+ epan_free(cf->epan);
- cf->epan = tshark_epan_new(cf);
- epan_dissect_init(edt, cf->epan, tree, visual);
- cf->count = 0;
+ cf->epan = tshark_epan_new(cf);
+ epan_dissect_init(edt, cf->epan, tree, visual);
+ cf->count = 0;
}
-
-/*
- * 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:
- */