File: | ui/summary.c |
Warning: | line 232, 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 <[email protected]> | ||||
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 = DBL_MAX1.7976931348623157e+308; | ||||
127 | st->stop_time = DBL_MIN2.2250738585072014e-308; | ||||
128 | st->bytes = 0; | ||||
129 | st->filtered_count = 0; | ||||
130 | st->filtered_count_ts = 0; | ||||
131 | st->filtered_start = DBL_MAX1.7976931348623157e+308; | ||||
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 = DBL_MAX1.7976931348623157e+308; | ||||
137 | st->marked_stop = 0; | ||||
138 | st->marked_bytes = 0; | ||||
139 | st->ignored_count = 0; | ||||
140 | |||||
141 | const nstime_t *cap_start = cap_file_provider_get_start_ts(&(cf->provider)); | ||||
142 | const nstime_t *cap_end = cap_file_provider_get_end_ts(&(cf->provider)); | ||||
143 | st->cap_start_time = (cap_start == NULL((void*)0) || nstime_is_unset(cap_start)) ? DBL_MAX1.7976931348623157e+308 : nstime_to_sec(cap_start); | ||||
| |||||
144 | st->cap_end_time = (cap_end == NULL((void*)0) || nstime_is_unset(cap_end)) ? DBL_MIN2.2250738585072014e-308 : nstime_to_sec(cap_end); | ||||
145 | |||||
146 | /* initialize the tally */ | ||||
147 | if (cf->count != 0) { | ||||
148 | first_frame = frame_data_sequence_find(cf->provider.frames, 1); | ||||
149 | if (first_frame->has_ts) { | ||||
150 | st->start_time = nstime_to_sec(&first_frame->abs_ts); | ||||
151 | st->stop_time = nstime_to_sec(&first_frame->abs_ts); | ||||
152 | } | ||||
153 | |||||
154 | for (framenum = 1; framenum <= cf->count; framenum++) { | ||||
155 | cur_frame = frame_data_sequence_find(cf->provider.frames, framenum); | ||||
156 | tally_frame_data(cur_frame, st); | ||||
157 | } | ||||
158 | } | ||||
159 | |||||
160 | st->filename = cf->filename; | ||||
161 | st->file_length = cf->f_datalen; | ||||
162 | st->file_type = cf->cd_t; | ||||
163 | st->compression_type = cf->compression_type; | ||||
164 | st->is_tempfile = cf->is_tempfile; | ||||
165 | st->file_encap_type = cf->lnk_t; | ||||
166 | st->packet_encap_types = cf->linktypes; | ||||
167 | st->snap = cf->snap; | ||||
168 | st->elapsed_time = nstime_to_sec(&cf->elapsed_time); | ||||
169 | st->packet_count = cf->count; | ||||
170 | st->drops_known = cf->drops_known; | ||||
171 | st->drops = cf->drops; | ||||
172 | st->dfilter = cf->dfilter; | ||||
173 | |||||
174 | st->ifaces = g_array_new(false0, false0, sizeof(iface_summary_info)); | ||||
175 | idb_info = wtap_file_get_idb_info(cf->provider.wth); | ||||
176 | for (i = 0; i < idb_info->interface_data->len; i++) { | ||||
177 | wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (idb_info->interface_data)-> data) [(i)]); | ||||
178 | wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr); | ||||
179 | if (wtap_block_get_if_filter_option_value(wtapng_if_descr, OPT_IDB_FILTER11, &if_filter) == WTAP_OPTTYPE_SUCCESS) { | ||||
180 | if (if_filter.type == if_filter_pcap) { | ||||
181 | iface.cfilter = g_strdup(if_filter.data.filter_str)g_strdup_inline (if_filter.data.filter_str); | ||||
182 | } else { | ||||
183 | /* Not a pcap filter string; punt for now */ | ||||
184 | iface.cfilter = NULL((void*)0); | ||||
185 | } | ||||
186 | } else { | ||||
187 | iface.cfilter = NULL((void*)0); | ||||
188 | } | ||||
189 | if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_NAME2, &if_string) == WTAP_OPTTYPE_SUCCESS) { | ||||
190 | iface.name = g_strdup(if_string)g_strdup_inline (if_string); | ||||
191 | } else { | ||||
192 | iface.name = NULL((void*)0); | ||||
193 | } | ||||
194 | if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_DESCRIPTION3, &if_string) == WTAP_OPTTYPE_SUCCESS) { | ||||
195 | iface.descr = g_strdup(if_string)g_strdup_inline (if_string); | ||||
196 | } else { | ||||
197 | iface.descr = NULL((void*)0); | ||||
198 | } | ||||
199 | iface.drops_known = false0; | ||||
200 | iface.drops = 0; | ||||
201 | iface.snap = wtapng_if_descr_mand->snap_len; | ||||
202 | iface.encap_type = wtapng_if_descr_mand->wtap_encap; | ||||
203 | iface.isb_comment = NULL((void*)0); | ||||
204 | if(wtapng_if_descr_mand->num_stat_entries == 1){ | ||||
205 | /* dumpcap only writes one ISB, only handle that for now */ | ||||
206 | 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)]); | ||||
207 | if (wtap_block_get_uint64_option_value(if_stats, OPT_ISB_IFDROP5, &isb_ifdrop) == WTAP_OPTTYPE_SUCCESS) { | ||||
208 | iface.drops_known = true1; | ||||
209 | iface.drops = isb_ifdrop; | ||||
210 | } | ||||
211 | /* XXX: this doesn't get used, and might need to be g_strdup'ed when it does */ | ||||
212 | /* XXX - support multiple comments */ | ||||
213 | if (wtap_block_get_nth_string_option_value(if_stats, OPT_COMMENT1, 0, &iface.isb_comment) != WTAP_OPTTYPE_SUCCESS) { | ||||
214 | iface.isb_comment = NULL((void*)0); | ||||
215 | } | ||||
216 | } | ||||
217 | g_array_append_val(st->ifaces, iface)g_array_append_vals (st->ifaces, &(iface), 1); | ||||
218 | } | ||||
219 | g_free(idb_info); | ||||
220 | |||||
221 | (void) g_strlcpy(st->file_sha256, "<unknown>", HASH_STR_SIZE(65)); | ||||
222 | (void) g_strlcpy(st->file_sha1, "<unknown>", HASH_STR_SIZE(65)); | ||||
223 | |||||
224 | gcry_md_open(&hd, GCRY_MD_SHA256, 0); | ||||
225 | if (hd) { | ||||
226 | gcry_md_enable(hd, GCRY_MD_SHA1); | ||||
227 | } | ||||
228 | hash_buf = (char *)g_malloc(HASH_BUF_SIZE(1024 * 1024)); | ||||
229 | |||||
230 | fh = ws_fopenfopen(cf->filename, "rb"); | ||||
231 | if (fh
| ||||
232 | while((hash_bytes = fread(hash_buf, 1, HASH_BUF_SIZE(1024 * 1024), fh)) > 0) { | ||||
| |||||
233 | gcry_md_write(hd, hash_buf, hash_bytes); | ||||
234 | } | ||||
235 | gcry_md_final(hd)gcry_md_ctl ((hd), GCRYCTL_FINALIZE, ((void*)0), 0); | ||||
236 | hash_to_str(gcry_md_read(hd, GCRY_MD_SHA256), HASH_SIZE_SHA25632, st->file_sha256); | ||||
237 | hash_to_str(gcry_md_read(hd, GCRY_MD_SHA1), HASH_SIZE_SHA120, st->file_sha1); | ||||
238 | } | ||||
239 | if (fh) fclose(fh); | ||||
240 | g_free(hash_buf); | ||||
241 | gcry_md_close(hd); | ||||
242 | } | ||||
243 | |||||
244 | #ifdef HAVE_LIBPCAP1 | ||||
245 | void | ||||
246 | summary_fill_in_capture(capture_file *cf,capture_options *capture_opts, summary_tally *st) | ||||
247 | { | ||||
248 | iface_summary_info iface; | ||||
249 | interface_t *device; | ||||
250 | unsigned i; | ||||
251 | |||||
252 | if (st->ifaces->len == 0) { | ||||
253 | /* | ||||
254 | * XXX - do this only if we have a live capture. | ||||
255 | */ | ||||
256 | for (i = 0; i < capture_opts->all_ifaces->len; i++) { | ||||
257 | device = &g_array_index(capture_opts->all_ifaces, interface_t, i)(((interface_t*) (void *) (capture_opts->all_ifaces)->data ) [(i)]); | ||||
258 | if (!device->selected) { | ||||
259 | continue; | ||||
260 | } | ||||
261 | iface.cfilter = g_strdup(device->cfilter)g_strdup_inline (device->cfilter); | ||||
262 | iface.name = g_strdup(device->name)g_strdup_inline (device->name); | ||||
263 | iface.descr = g_strdup(device->display_name)g_strdup_inline (device->display_name); | ||||
264 | iface.drops_known = cf->drops_known; | ||||
265 | iface.drops = cf->drops; | ||||
266 | iface.snap = device->snaplen; | ||||
267 | iface.encap_type = wtap_pcap_encap_to_wtap_encap(device->active_dlt); | ||||
268 | g_array_append_val(st->ifaces, iface)g_array_append_vals (st->ifaces, &(iface), 1); | ||||
269 | } | ||||
270 | } | ||||
271 | } | ||||
272 | #endif |