| File: | ui/summary.c |
| Warning: | line 225, column 29 File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* summary.c | ||||
| 2 | * Routines for capture file summary info | ||||
| 3 | * | ||||
| 4 | * Wireshark - Network traffic analyzer | ||||
| 5 | * By Gerald Combs <gerald@wireshark.org> | ||||
| 6 | * Copyright 1998 Gerald Combs | ||||
| 7 | * | ||||
| 8 | * SPDX-License-Identifier: GPL-2.0-or-later | ||||
| 9 | */ | ||||
| 10 | |||||
| 11 | #include <config.h> | ||||
| 12 | |||||
| 13 | #include <wiretap/pcap-encap.h> | ||||
| 14 | #include <wiretap/wtap_opttypes.h> | ||||
| 15 | |||||
| 16 | #include <epan/packet.h> | ||||
| 17 | #include <wsutil/file_util.h> | ||||
| 18 | #include <gcrypt.h> | ||||
| 19 | #include "cfile.h" | ||||
| 20 | #include "ui/summary.h" | ||||
| 21 | |||||
| 22 | // Strongest to weakest | ||||
| 23 | #define HASH_SIZE_SHA25632 32 | ||||
| 24 | #define HASH_SIZE_SHA120 20 | ||||
| 25 | |||||
| 26 | #define HASH_BUF_SIZE(1024 * 1024) (1024 * 1024) | ||||
| 27 | |||||
| 28 | static void | ||||
| 29 | tally_frame_data(frame_data *cur_frame, summary_tally *sum_tally) | ||||
| 30 | { | ||||
| 31 | double cur_time; | ||||
| 32 | |||||
| 33 | sum_tally->bytes += cur_frame->pkt_len; | ||||
| 34 | if (cur_frame->passed_dfilter){ | ||||
| 35 | sum_tally->filtered_count++; | ||||
| 36 | sum_tally->filtered_bytes += cur_frame->pkt_len; | ||||
| 37 | } | ||||
| 38 | if (cur_frame->marked){ | ||||
| 39 | sum_tally->marked_count++; | ||||
| 40 | sum_tally->marked_bytes += cur_frame->pkt_len; | ||||
| 41 | } | ||||
| 42 | if (cur_frame->ignored){ | ||||
| 43 | sum_tally->ignored_count++; | ||||
| 44 | } | ||||
| 45 | |||||
| 46 | if (cur_frame->has_ts) { | ||||
| 47 | /* This packet has a time stamp. */ | ||||
| 48 | cur_time = nstime_to_sec(&cur_frame->abs_ts); | ||||
| 49 | |||||
| 50 | sum_tally->packet_count_ts++; | ||||
| 51 | if (cur_time < sum_tally->start_time) { | ||||
| 52 | sum_tally->start_time = cur_time; | ||||
| 53 | } | ||||
| 54 | if (cur_time > sum_tally->stop_time){ | ||||
| 55 | sum_tally->stop_time = cur_time; | ||||
| 56 | } | ||||
| 57 | if (cur_frame->passed_dfilter){ | ||||
| 58 | sum_tally->filtered_count_ts++; | ||||
| 59 | /* | ||||
| 60 | * If we've seen one filtered packet, this is the first | ||||
| 61 | * one. | ||||
| 62 | */ | ||||
| 63 | if (sum_tally->filtered_count == 1){ | ||||
| 64 | sum_tally->filtered_start= cur_time; | ||||
| 65 | sum_tally->filtered_stop = cur_time; | ||||
| 66 | } else { | ||||
| 67 | if (cur_time < sum_tally->filtered_start) { | ||||
| 68 | sum_tally->filtered_start = cur_time; | ||||
| 69 | } | ||||
| 70 | if (cur_time > sum_tally->filtered_stop) { | ||||
| 71 | sum_tally->filtered_stop = cur_time; | ||||
| 72 | } | ||||
| 73 | } | ||||
| 74 | } | ||||
| 75 | if (cur_frame->marked){ | ||||
| 76 | sum_tally->marked_count_ts++; | ||||
| 77 | /* | ||||
| 78 | * If we've seen one marked packet, this is the first | ||||
| 79 | * one. | ||||
| 80 | */ | ||||
| 81 | if (sum_tally->marked_count == 1){ | ||||
| 82 | sum_tally->marked_start= cur_time; | ||||
| 83 | sum_tally->marked_stop = cur_time; | ||||
| 84 | } else { | ||||
| 85 | if (cur_time < sum_tally->marked_start) { | ||||
| 86 | sum_tally->marked_start = cur_time; | ||||
| 87 | } | ||||
| 88 | if (cur_time > sum_tally->marked_stop) { | ||||
| 89 | sum_tally->marked_stop = cur_time; | ||||
| 90 | } | ||||
| 91 | } | ||||
| 92 | } | ||||
| 93 | } | ||||
| 94 | } | ||||
| 95 | |||||
| 96 | static void | ||||
| 97 | hash_to_str(const unsigned char *hash, size_t length, char *str) { | ||||
| 98 | int i; | ||||
| 99 | |||||
| 100 | for (i = 0; i < (int) length; i++) { | ||||
| 101 | snprintf(str+(i*2), 3, "%02x", hash[i]); | ||||
| 102 | } | ||||
| 103 | } | ||||
| 104 | |||||
| 105 | void | ||||
| 106 | summary_fill_in(capture_file *cf, summary_tally *st) | ||||
| 107 | { | ||||
| 108 | frame_data *first_frame, *cur_frame; | ||||
| 109 | uint32_t framenum; | ||||
| 110 | iface_summary_info iface; | ||||
| 111 | unsigned i; | ||||
| 112 | wtapng_iface_descriptions_t* idb_info; | ||||
| 113 | wtap_block_t wtapng_if_descr; | ||||
| 114 | wtapng_if_descr_mandatory_t *wtapng_if_descr_mand; | ||||
| 115 | wtap_block_t if_stats; | ||||
| 116 | uint64_t isb_ifdrop; | ||||
| 117 | char* if_string; | ||||
| 118 | if_filter_opt_t if_filter; | ||||
| 119 | |||||
| 120 | FILE *fh; | ||||
| 121 | char *hash_buf; | ||||
| 122 | gcry_md_hd_t hd; | ||||
| 123 | size_t hash_bytes; | ||||
| 124 | |||||
| 125 | st->packet_count_ts = 0; | ||||
| 126 | st->start_time = 0; | ||||
| 127 | st->stop_time = 0; | ||||
| 128 | st->bytes = 0; | ||||
| 129 | st->filtered_count = 0; | ||||
| 130 | st->filtered_count_ts = 0; | ||||
| 131 | st->filtered_start = 0; | ||||
| 132 | st->filtered_stop = 0; | ||||
| 133 | st->filtered_bytes = 0; | ||||
| 134 | st->marked_count = 0; | ||||
| 135 | st->marked_count_ts = 0; | ||||
| 136 | st->marked_start = 0; | ||||
| 137 | st->marked_stop = 0; | ||||
| 138 | st->marked_bytes = 0; | ||||
| 139 | st->ignored_count = 0; | ||||
| 140 | |||||
| 141 | /* initialize the tally */ | ||||
| 142 | if (cf->count != 0) { | ||||
| |||||
| 143 | first_frame = frame_data_sequence_find(cf->provider.frames, 1); | ||||
| 144 | st->start_time = nstime_to_sec(&first_frame->abs_ts); | ||||
| 145 | st->stop_time = nstime_to_sec(&first_frame->abs_ts); | ||||
| 146 | |||||
| 147 | for (framenum = 1; framenum <= cf->count; framenum++) { | ||||
| 148 | cur_frame = frame_data_sequence_find(cf->provider.frames, framenum); | ||||
| 149 | tally_frame_data(cur_frame, st); | ||||
| 150 | } | ||||
| 151 | } | ||||
| 152 | |||||
| 153 | st->filename = cf->filename; | ||||
| 154 | st->file_length = cf->f_datalen; | ||||
| 155 | st->file_type = cf->cd_t; | ||||
| 156 | st->compression_type = cf->compression_type; | ||||
| 157 | st->is_tempfile = cf->is_tempfile; | ||||
| 158 | st->file_encap_type = cf->lnk_t; | ||||
| 159 | st->packet_encap_types = cf->linktypes; | ||||
| 160 | st->snap = cf->snap; | ||||
| 161 | st->elapsed_time = nstime_to_sec(&cf->elapsed_time); | ||||
| 162 | st->packet_count = cf->count; | ||||
| 163 | st->drops_known = cf->drops_known; | ||||
| 164 | st->drops = cf->drops; | ||||
| 165 | st->dfilter = cf->dfilter; | ||||
| 166 | |||||
| 167 | st->ifaces = g_array_new(false0, false0, sizeof(iface_summary_info)); | ||||
| 168 | idb_info = wtap_file_get_idb_info(cf->provider.wth); | ||||
| 169 | for (i = 0; i < idb_info->interface_data->len; i++) { | ||||
| 170 | wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (idb_info->interface_data)-> data) [(i)]); | ||||
| 171 | wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr); | ||||
| 172 | if (wtap_block_get_if_filter_option_value(wtapng_if_descr, OPT_IDB_FILTER11, &if_filter) == WTAP_OPTTYPE_SUCCESS) { | ||||
| 173 | if (if_filter.type == if_filter_pcap) { | ||||
| 174 | iface.cfilter = g_strdup(if_filter.data.filter_str)g_strdup_inline (if_filter.data.filter_str); | ||||
| 175 | } else { | ||||
| 176 | /* Not a pcap filter string; punt for now */ | ||||
| 177 | iface.cfilter = NULL((void*)0); | ||||
| 178 | } | ||||
| 179 | } else { | ||||
| 180 | iface.cfilter = NULL((void*)0); | ||||
| 181 | } | ||||
| 182 | if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_NAME2, &if_string) == WTAP_OPTTYPE_SUCCESS) { | ||||
| 183 | iface.name = g_strdup(if_string)g_strdup_inline (if_string); | ||||
| 184 | } else { | ||||
| 185 | iface.name = NULL((void*)0); | ||||
| 186 | } | ||||
| 187 | if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_DESCRIPTION3, &if_string) == WTAP_OPTTYPE_SUCCESS) { | ||||
| 188 | iface.descr = g_strdup(if_string)g_strdup_inline (if_string); | ||||
| 189 | } else { | ||||
| 190 | iface.descr = NULL((void*)0); | ||||
| 191 | } | ||||
| 192 | iface.drops_known = false0; | ||||
| 193 | iface.drops = 0; | ||||
| 194 | iface.snap = wtapng_if_descr_mand->snap_len; | ||||
| 195 | iface.encap_type = wtapng_if_descr_mand->wtap_encap; | ||||
| 196 | iface.isb_comment = NULL((void*)0); | ||||
| 197 | if(wtapng_if_descr_mand->num_stat_entries == 1){ | ||||
| 198 | /* dumpcap only writes one ISB, only handle that for now */ | ||||
| 199 | if_stats = g_array_index(wtapng_if_descr_mand->interface_statistics, wtap_block_t, 0)(((wtap_block_t*) (void *) (wtapng_if_descr_mand->interface_statistics )->data) [(0)]); | ||||
| 200 | if (wtap_block_get_uint64_option_value(if_stats, OPT_ISB_IFDROP5, &isb_ifdrop) == WTAP_OPTTYPE_SUCCESS) { | ||||
| 201 | iface.drops_known = true1; | ||||
| 202 | iface.drops = isb_ifdrop; | ||||
| 203 | } | ||||
| 204 | /* XXX: this doesn't get used, and might need to be g_strdup'ed when it does */ | ||||
| 205 | /* XXX - support multiple comments */ | ||||
| 206 | if (wtap_block_get_nth_string_option_value(if_stats, OPT_COMMENT1, 0, &iface.isb_comment) != WTAP_OPTTYPE_SUCCESS) { | ||||
| 207 | iface.isb_comment = NULL((void*)0); | ||||
| 208 | } | ||||
| 209 | } | ||||
| 210 | g_array_append_val(st->ifaces, iface)g_array_append_vals (st->ifaces, &(iface), 1); | ||||
| 211 | } | ||||
| 212 | g_free(idb_info); | ||||
| 213 | |||||
| 214 | (void) g_strlcpy(st->file_sha256, "<unknown>", HASH_STR_SIZE(65)); | ||||
| 215 | (void) g_strlcpy(st->file_sha1, "<unknown>", HASH_STR_SIZE(65)); | ||||
| 216 | |||||
| 217 | gcry_md_open(&hd, GCRY_MD_SHA256, 0); | ||||
| 218 | if (hd) { | ||||
| 219 | gcry_md_enable(hd, GCRY_MD_SHA1); | ||||
| 220 | } | ||||
| 221 | hash_buf = (char *)g_malloc(HASH_BUF_SIZE(1024 * 1024)); | ||||
| 222 | |||||
| 223 | fh = ws_fopenfopen(cf->filename, "rb"); | ||||
| 224 | if (fh
| ||||
| 225 | while((hash_bytes = fread(hash_buf, 1, HASH_BUF_SIZE(1024 * 1024), fh)) > 0) { | ||||
| |||||
| 226 | gcry_md_write(hd, hash_buf, hash_bytes); | ||||
| 227 | } | ||||
| 228 | gcry_md_final(hd)gcry_md_ctl ((hd), GCRYCTL_FINALIZE, ((void*)0), 0); | ||||
| 229 | hash_to_str(gcry_md_read(hd, GCRY_MD_SHA256), HASH_SIZE_SHA25632, st->file_sha256); | ||||
| 230 | hash_to_str(gcry_md_read(hd, GCRY_MD_SHA1), HASH_SIZE_SHA120, st->file_sha1); | ||||
| 231 | } | ||||
| 232 | if (fh) fclose(fh); | ||||
| 233 | g_free(hash_buf); | ||||
| 234 | gcry_md_close(hd); | ||||
| 235 | } | ||||
| 236 | |||||
| 237 | #ifdef HAVE_LIBPCAP1 | ||||
| 238 | void | ||||
| 239 | summary_fill_in_capture(capture_file *cf,capture_options *capture_opts, summary_tally *st) | ||||
| 240 | { | ||||
| 241 | iface_summary_info iface; | ||||
| 242 | interface_t *device; | ||||
| 243 | unsigned i; | ||||
| 244 | |||||
| 245 | if (st->ifaces->len == 0) { | ||||
| 246 | /* | ||||
| 247 | * XXX - do this only if we have a live capture. | ||||
| 248 | */ | ||||
| 249 | for (i = 0; i < capture_opts->all_ifaces->len; i++) { | ||||
| 250 | device = &g_array_index(capture_opts->all_ifaces, interface_t, i)(((interface_t*) (void *) (capture_opts->all_ifaces)->data ) [(i)]); | ||||
| 251 | if (!device->selected) { | ||||
| 252 | continue; | ||||
| 253 | } | ||||
| 254 | iface.cfilter = g_strdup(device->cfilter)g_strdup_inline (device->cfilter); | ||||
| 255 | iface.name = g_strdup(device->name)g_strdup_inline (device->name); | ||||
| 256 | iface.descr = g_strdup(device->display_name)g_strdup_inline (device->display_name); | ||||
| 257 | iface.drops_known = cf->drops_known; | ||||
| 258 | iface.drops = cf->drops; | ||||
| 259 | iface.snap = device->snaplen; | ||||
| 260 | iface.encap_type = wtap_pcap_encap_to_wtap_encap(device->active_dlt); | ||||
| 261 | g_array_append_val(st->ifaces, iface)g_array_append_vals (st->ifaces, &(iface), 1); | ||||
| 262 | } | ||||
| 263 | } | ||||
| 264 | } | ||||
| 265 | #endif |