2 * Routines for capture file summary info
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include <wiretap/pcap-encap.h>
14 #include <wiretap/wtap_opttypes.h>
16 #include <epan/packet.h>
17 #include <wsutil/file_util.h>
20 #include "ui/summary.h"
22 // Strongest to weakest
23 #define HASH_SIZE_SHA256 32
24 #define HASH_SIZE_SHA1 20
26 #define HASH_BUF_SIZE (1024 * 1024)
29 tally_frame_data(frame_data
*cur_frame
, summary_tally
*sum_tally
)
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
;
38 if (cur_frame
->marked
){
39 sum_tally
->marked_count
++;
40 sum_tally
->marked_bytes
+= cur_frame
->pkt_len
;
42 if (cur_frame
->ignored
){
43 sum_tally
->ignored_count
++;
46 if (cur_frame
->has_ts
) {
47 /* This packet has a time stamp. */
48 cur_time
= nstime_to_sec(&cur_frame
->abs_ts
);
50 sum_tally
->packet_count_ts
++;
51 if (cur_time
< sum_tally
->start_time
) {
52 sum_tally
->start_time
= cur_time
;
54 if (cur_time
> sum_tally
->stop_time
){
55 sum_tally
->stop_time
= cur_time
;
57 if (cur_frame
->passed_dfilter
){
58 sum_tally
->filtered_count_ts
++;
60 * If we've seen one filtered packet, this is the first
63 if (sum_tally
->filtered_count
== 1){
64 sum_tally
->filtered_start
= cur_time
;
65 sum_tally
->filtered_stop
= cur_time
;
67 if (cur_time
< sum_tally
->filtered_start
) {
68 sum_tally
->filtered_start
= cur_time
;
70 if (cur_time
> sum_tally
->filtered_stop
) {
71 sum_tally
->filtered_stop
= cur_time
;
75 if (cur_frame
->marked
){
76 sum_tally
->marked_count_ts
++;
78 * If we've seen one marked packet, this is the first
81 if (sum_tally
->marked_count
== 1){
82 sum_tally
->marked_start
= cur_time
;
83 sum_tally
->marked_stop
= cur_time
;
85 if (cur_time
< sum_tally
->marked_start
) {
86 sum_tally
->marked_start
= cur_time
;
88 if (cur_time
> sum_tally
->marked_stop
) {
89 sum_tally
->marked_stop
= cur_time
;
97 hash_to_str(const unsigned char *hash
, size_t length
, char *str
) {
100 for (i
= 0; i
< (int) length
; i
++) {
101 snprintf(str
+(i
*2), 3, "%02x", hash
[i
]);
106 summary_fill_in(capture_file
*cf
, summary_tally
*st
)
108 frame_data
*first_frame
, *cur_frame
;
110 iface_summary_info iface
;
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
;
118 if_filter_opt_t if_filter
;
125 st
->packet_count_ts
= 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;
138 st
->marked_bytes
= 0;
139 st
->ignored_count
= 0;
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
);
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
);
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
;
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
;
167 st
->ifaces
= g_array_new(false, false, 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
);
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_FILTER
, &if_filter
) == WTAP_OPTTYPE_SUCCESS
) {
173 if (if_filter
.type
== if_filter_pcap
) {
174 iface
.cfilter
= g_strdup(if_filter
.data
.filter_str
);
176 /* Not a pcap filter string; punt for now */
177 iface
.cfilter
= NULL
;
180 iface
.cfilter
= NULL
;
182 if (wtap_block_get_string_option_value(wtapng_if_descr
, OPT_IDB_NAME
, &if_string
) == WTAP_OPTTYPE_SUCCESS
) {
183 iface
.name
= g_strdup(if_string
);
187 if (wtap_block_get_string_option_value(wtapng_if_descr
, OPT_IDB_DESCRIPTION
, &if_string
) == WTAP_OPTTYPE_SUCCESS
) {
188 iface
.descr
= g_strdup(if_string
);
192 iface
.drops_known
= false;
194 iface
.snap
= wtapng_if_descr_mand
->snap_len
;
195 iface
.encap_type
= wtapng_if_descr_mand
->wtap_encap
;
196 iface
.isb_comment
= NULL
;
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);
200 if (wtap_block_get_uint64_option_value(if_stats
, OPT_ISB_IFDROP
, &isb_ifdrop
) == WTAP_OPTTYPE_SUCCESS
) {
201 iface
.drops_known
= true;
202 iface
.drops
= isb_ifdrop
;
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_COMMENT
, 0, &iface
.isb_comment
) != WTAP_OPTTYPE_SUCCESS
) {
207 iface
.isb_comment
= NULL
;
210 g_array_append_val(st
->ifaces
, iface
);
214 (void) g_strlcpy(st
->file_sha256
, "<unknown>", HASH_STR_SIZE
);
215 (void) g_strlcpy(st
->file_sha1
, "<unknown>", HASH_STR_SIZE
);
217 gcry_md_open(&hd
, GCRY_MD_SHA256
, 0);
219 gcry_md_enable(hd
, GCRY_MD_SHA1
);
221 hash_buf
= (char *)g_malloc(HASH_BUF_SIZE
);
223 fh
= ws_fopen(cf
->filename
, "rb");
224 if (fh
&& hash_buf
&& hd
) {
225 while((hash_bytes
= fread(hash_buf
, 1, HASH_BUF_SIZE
, fh
)) > 0) {
226 gcry_md_write(hd
, hash_buf
, hash_bytes
);
229 hash_to_str(gcry_md_read(hd
, GCRY_MD_SHA256
), HASH_SIZE_SHA256
, st
->file_sha256
);
230 hash_to_str(gcry_md_read(hd
, GCRY_MD_SHA1
), HASH_SIZE_SHA1
, st
->file_sha1
);
239 summary_fill_in_capture(capture_file
*cf
,capture_options
*capture_opts
, summary_tally
*st
)
241 iface_summary_info iface
;
245 if (st
->ifaces
->len
== 0) {
247 * XXX - do this only if we have a live capture.
249 for (i
= 0; i
< capture_opts
->all_ifaces
->len
; i
++) {
250 device
= &g_array_index(capture_opts
->all_ifaces
, interface_t
, i
);
251 if (!device
->selected
) {
254 iface
.cfilter
= g_strdup(device
->cfilter
);
255 iface
.name
= g_strdup(device
->name
);
256 iface
.descr
= g_strdup(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
);