forked from osmocom/wireshark
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>daniel/osmux
parent
f928a5f5bf
commit
4233e9a680
59
capinfos.c
59
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",
|
||||
|
|
Loading…
Reference in New Issue