From 1dd8f3a66680b1f640121a0ed55847af55285fc6 Mon Sep 17 00:00:00 2001 From: John Thacker Date: Wed, 29 Sep 2021 20:59:41 -0400 Subject: [PATCH] capinfos: Calculate hashes after determining if a capture file Calculate the hashes for a file after the wtap_open_offline, to avoid spending time calculating them for files that aren't known capture formats. We wouldn't print the checksums in those cases anyway, and the time savings can be considerable on large non-capture files. --- capinfos.c | 77 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/capinfos.c b/capinfos.c index 49be19de54..6982731c50 100644 --- a/capinfos.c +++ b/capinfos.c @@ -152,6 +152,9 @@ static gchar file_sha256[HASH_STR_SIZE]; static gchar file_rmd160[HASH_STR_SIZE]; static gchar file_sha1[HASH_STR_SIZE]; +static char *hash_buf = NULL; +static gcry_md_hd_t hd = NULL; + static guint num_ipv4_addresses; static guint num_ipv6_addresses; static guint num_decryption_secrets; @@ -1150,6 +1153,41 @@ count_decryption_secret(guint32 secrets_type _U_, const void *secrets _U_, guint num_decryption_secrets++; } +static void +hash_to_str(const unsigned char *hash, size_t length, char *str) { + int i; + + for (i = 0; i < (int) length; i++) { + g_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, "", HASH_STR_SIZE); + (void) g_strlcpy(file_rmd160, "", HASH_STR_SIZE); + (void) g_strlcpy(file_sha1, "", 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); + } +} + static int process_cap_file(const char *filename, gboolean need_separator) { @@ -1184,6 +1222,13 @@ process_cap_file(const char *filename, gboolean need_separator) 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"); } @@ -1519,15 +1564,6 @@ capinfos_cmdarg_err_cont(const char *msg_format, va_list ap) fprintf(stderr, "\n"); } -static void -hash_to_str(const unsigned char *hash, size_t length, char *str) { - int i; - - for (i = 0; i < (int) length; i++) { - g_snprintf(str+(i*2), 3, "%02x", hash[i]); - } -} - int main(int argc, char *argv[]) { @@ -1554,10 +1590,6 @@ main(int argc, char *argv[]) }; int status = 0; - FILE *fh; - char *hash_buf = NULL; - gcry_md_hd_t hd = NULL; - size_t hash_bytes; /* * Set the C-language locale to the native environment and set the @@ -1816,25 +1848,6 @@ main(int argc, char *argv[]) for (opt = ws_optind; opt < argc; opt++) { - (void) g_strlcpy(file_sha256, "", HASH_STR_SIZE); - (void) g_strlcpy(file_rmd160, "", HASH_STR_SIZE); - (void) g_strlcpy(file_sha1, "", HASH_STR_SIZE); - - if (cap_file_hashes) { - fh = ws_fopen(argv[opt], "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); - } - status = process_cap_file(argv[opt], need_separator); if (status) { /* Something failed. It's been reported; remember that processing