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 <[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 = 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 |