summaryrefslogtreecommitdiff
path: root/capinfos.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-06-09 20:32:35 -0700
committerGuy Harris <guy@alum.mit.edu>2016-06-10 03:33:07 +0000
commit4233e9a680095384fc37f02b5ea96998be80b9c8 (patch)
tree588fcee237162916ce56a0593d86dc745b651050 /capinfos.c
parentf928a5f5bf1b26092cb9e5b109a4cde1d6ba64cc (diff)
downloadwireshark-4233e9a680095384fc37f02b5ea96998be80b9c8.tar.gz
Don't assume all IDBs are available aftre we open the file.
IDBs can occur anywhere in the file, so if we see an interface ID bigger than the number of IDBs we've see, re-fetch the interface information, update the IDB count, and grow the packet count array as necessary. Get the information strings for interfaces after reading the entire file; we don't need them until then. Change-Id: Ib6096e481e321de485710d14eadf7b5232bf0be7 Reviewed-on: https://code.wireshark.org/review/15797 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'capinfos.c')
-rw-r--r--capinfos.c59
1 files changed, 41 insertions, 18 deletions
diff --git a/capinfos.c b/capinfos.c
index 7bf0a84a76..069608052a 100644
--- a/capinfos.c
+++ b/capinfos.c
@@ -219,8 +219,8 @@ typedef struct _capture_info {
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_ids array */
- guint32 *interface_ids; /* array of per_packet interface_id counts; one entry per file IDB */
+ 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;
@@ -740,7 +740,7 @@ print_stats(const gchar *filename, capture_info *cf_info)
gchar *s = g_array_index(cf_info->idb_info_strings, gchar*, i);
printf ("Interface #%u info:\n", i);
printf ("%s", s);
- printf (" Number of packets = %u\n", cf_info->interface_ids[i]);
+ printf (" Number of packets = %u\n", g_array_index(cf_info->interface_packet_counts, guint32, i));
}
}
}
@@ -1047,8 +1047,8 @@ cleanup_capture_info(capture_info *cf_info)
g_free(cf_info->encap_counts);
cf_info->encap_counts = NULL;
- g_free(cf_info->interface_ids);
- cf_info->interface_ids = 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++) {
@@ -1105,19 +1105,9 @@ process_cap_file(wtap *wth, const char *filename)
g_assert(idb_info->interface_data != NULL);
- cf_info.num_interfaces = idb_info->interface_data->len;
- cf_info.interface_ids = g_new0(guint32, cf_info.num_interfaces);
+ cf_info.interface_packet_counts = g_array_sized_new(FALSE, TRUE, sizeof(guint32), cf_info.num_interfaces);
cf_info.pkt_interface_id_unknown = 0;
- cf_info.idb_info_strings = g_array_sized_new(FALSE, FALSE, sizeof(gchar*), cf_info.num_interfaces);
-
- /* get IDB info strings */
- for (i = 0; i < cf_info.num_interfaces; i++) {
- const wtap_optionblock_t if_descr = g_array_index(idb_info->interface_data, wtap_optionblock_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;
@@ -1179,8 +1169,23 @@ process_cap_file(wtap *wth, const char *filename)
/* Packet interface_id info */
if (phdr->presence_flags & WTAP_HAS_INTERFACE_ID) {
/* cf_info.num_interfaces is size, not index, so it's one more than max index */
+ if (phdr->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(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 (phdr->interface_id < cf_info.num_interfaces) {
- cf_info.interface_ids[phdr->interface_id] += 1;
+ g_array_index(cf_info.interface_packet_counts, guint32, phdr->interface_id) += 1;
}
else {
cf_info.pkt_interface_id_unknown += 1;
@@ -1189,7 +1194,7 @@ process_cap_file(wtap *wth, const char *filename)
else {
/* it's for interface_id 0 */
if (cf_info.num_interfaces != 0) {
- cf_info.interface_ids[0] += 1;
+ g_array_index(cf_info.interface_packet_counts, guint32, 0) += 1;
}
else {
cf_info.pkt_interface_id_unknown += 1;
@@ -1199,6 +1204,24 @@ process_cap_file(wtap *wth, const char *filename)
} /* while */
+ /*
+ * 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.
+ */
+ idb_info = wtap_file_get_idb_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_optionblock_t if_descr = g_array_index(idb_info->interface_data, wtap_optionblock_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\": %s.\n",