Bug Summary

File:builds/wireshark/wireshark/capinfos.c
Warning:line 1082, column 33
Read function called when stream is in EOF state. Function has no effect

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name capinfos.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-21/lib/clang/21 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2026-05-13-100359-3641-1 -x c /builds/wireshark/wireshark/capinfos.c
1/* capinfos.c
2 * Reports capture file information including # of packets, duration, others
3 *
4 * Copyright 2004 Ian Schorr
5 *
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <[email protected]>
8 * Copyright 1998 Gerald Combs
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13/*
14 * 2009-09-19: jyoung
15 *
16 * New capinfos features
17 *
18 * Continue processing additional files after
19 * a wiretap open failure. The new -C option
20 * reverts to capinfos' original behavior which
21 * is to cancel any further file processing at
22 * first file open failure.
23 *
24 * Change the behavior of how the default display
25 * of all infos is initiated. This gets rid of a
26 * special post getopt() argument count test.
27 *
28 * Add new table output format (with related options)
29 * This feature allows outputting the various infos
30 * into a tab delimited text file, or to a comma
31 * separated variables file (*.csv) instead of the
32 * original "long" format.
33 *
34 * 2011-04-05: wmeier
35 * behaviour changed: Upon exit capinfos will return
36 * an error status if an error occurred at any
37 * point during "continuous" file processing.
38 * (Previously a success status was always
39 * returned if the -C option was not used).
40 *
41 */
42
43
44#include <config.h>
45#define WS_LOG_DOMAIN"Main" LOG_DOMAIN_MAIN"Main"
46
47#include <stdio.h>
48#include <stdlib.h>
49#include <string.h>
50#include <stdarg.h>
51#include <locale.h>
52
53#include <ws_exit_codes.h>
54#include <wsutil/clopts_common.h>
55#include <wsutil/ws_getopt.h>
56
57#include <glib.h>
58
59#include <wiretap/wtap.h>
60
61#include <wsutil/cmdarg_err.h>
62#include <wsutil/filesystem.h>
63#include <app/application_flavor.h>
64#include <wsutil/file_compressed.h>
65#include <wsutil/privileges.h>
66#include <cli_main.h>
67#include <wsutil/version_info.h>
68#include <wsutil/report_message.h>
69#include <wiretap/wtap_opttypes.h>
70
71#ifdef HAVE_PLUGINS1
72#include <wsutil/plugins.h>
73#endif
74
75#include <wsutil/str_util.h>
76#include <wsutil/to_str.h>
77#include <wsutil/file_util.h>
78#include <wsutil/ws_assert.h>
79#include <wsutil/wslog.h>
80
81#include <gcrypt.h>
82
83#include "ui/failure_message.h"
84
85/*
86 * By default capinfos now continues processing
87 * the next filename if and when wiretap detects
88 * a problem opening or reading a file.
89 * Use the '-C' option to revert back to original
90 * capinfos behavior which is to abort any
91 * additional file processing at the first file
92 * open or read failure.
93 */
94
95static bool_Bool stop_after_failure;
96
97/*
98 * table report variables
99 */
100
101static bool_Bool long_report = true1; /* By default generate long report */
102static bool_Bool table_report_header = true1; /* Generate column header by default */
103static char field_separator = '\t'; /* Use TAB as field separator by default */
104static char quote_char = '\0'; /* Do NOT quote fields by default */
105static bool_Bool machine_readable; /* Display machine-readable numbers */
106
107/*
108 * capinfos has the ability to report on a number of
109 * various characteristics ("infos") for each input file.
110 *
111 * By default reporting of all info fields is enabled.
112 *
113 * Optionally the reporting of any specific info field
114 * or combination of info fields can be enabled with
115 * individual options.
116 */
117
118static bool_Bool report_all_infos = true1; /* Report all infos */
119
120static bool_Bool cap_file_type = true1; /* Report capture type */
121static bool_Bool cap_file_encap = true1; /* Report encapsulation */
122static bool_Bool cap_snaplen = true1; /* Packet size limit (snaplen)*/
123static bool_Bool cap_packet_count = true1; /* Report packet count */
124static bool_Bool cap_file_size = true1; /* Report file size */
125static bool_Bool cap_comment = true1; /* Display the capture comment */
126static bool_Bool cap_file_more_info = true1; /* Report more file info */
127static bool_Bool cap_file_idb = true1; /* Report Interface info */
128static bool_Bool cap_file_nrb = true1; /* Report Name Resolution Block info */
129static bool_Bool cap_file_dsb = true1; /* Report Decryption Secrets Block info */
130
131static bool_Bool cap_data_size = true1; /* Report packet byte size */
132static bool_Bool cap_duration = true1; /* Report capture duration */
133static bool_Bool cap_earliest_packet_time = true1; /* Report timestamp of earliest packet */
134static bool_Bool cap_latest_packet_time = true1; /* Report timestamp of latest packet */
135static bool_Bool time_as_secs; /* Report time values as raw seconds */
136
137static bool_Bool cap_data_rate_byte = true1; /* Report data rate bytes/sec */
138static bool_Bool cap_data_rate_bit = true1; /* Report data rate bites/sec */
139static bool_Bool cap_packet_size = true1; /* Report average packet size */
140static bool_Bool cap_packet_rate = true1; /* Report average packet rate */
141static bool_Bool cap_order = true1; /* Report if packets are in chronological order (True/False) */
142static bool_Bool pkt_comments = true1; /* Report individual packet comments */
143
144static bool_Bool cap_file_hashes = true1; /* Calculate file hashes */
145
146// Strongest to weakest
147#define HASH_SIZE_SHA25632 32
148#define HASH_SIZE_SHA120 20
149
150#define HASH_STR_SIZE(65) (65) /* Max hash size * 2 + '\0' */
151#define HASH_BUF_SIZE(1024 * 1024) (1024 * 1024)
152
153
154static char file_sha256[HASH_STR_SIZE(65)];
155static char file_sha1[HASH_STR_SIZE(65)];
156
157static char *hash_buf;
158static gcry_md_hd_t hd;
159
160static unsigned int num_ipv4_addresses;
161static unsigned int num_ipv6_addresses;
162static unsigned int num_decryption_secrets;
163
164/*
165 * If we have at least two packets with time stamps, and they're not in
166 * order - i.e., the later packet has a time stamp older than the earlier
167 * packet - the time stamps are known not to be in order.
168 *
169 * If every packet has a time stamp, and they're all in order, the time
170 * stamp is known to be in order.
171 *
172 * Otherwise, we have no idea.
173 */
174typedef enum {
175 IN_ORDER,
176 NOT_IN_ORDER,
177 ORDER_UNKNOWN
178} order_t;
179
180typedef struct _pkt_cmt {
181 uint32_t recno;
182 char *cmt;
183 struct _pkt_cmt *next;
184} pkt_cmt;
185
186typedef struct _capture_info {
187 const char *filename;
188 uint16_t file_type;
189 ws_compression_type compression_type;
190 int file_encap;
191 int file_tsprec;
192 wtap *wth;
193 int64_t filesize;
194 uint64_t packet_bytes;
195 bool_Bool times_known;
196 nstime_t earliest_packet_time;
197 int earliest_packet_time_tsprec;
198 nstime_t latest_packet_time;
199 int latest_packet_time_tsprec;
200 uint32_t packet_count;
201 bool_Bool snap_set; /* If set in capture file header */
202 uint32_t snaplen; /* value from the capture file header */
203 uint32_t snaplen_min_inferred; /* If caplen < len for 1 or more rcds */
204 uint32_t snaplen_max_inferred; /* ... */
205 bool_Bool drops_known;
206 uint32_t drop_count;
207
208 nstime_t duration;
209 int duration_tsprec;
210 double packet_rate;
211 double packet_size;
212 double data_rate; /* in bytes/s */
213 bool_Bool know_order;
214 order_t order;
215
216 int *encap_counts; /* array of per_packet encap counts; array has one entry per wtap_encap type */
217 pkt_cmt *pkt_cmts; /* list of packet comments */
218
219 unsigned int num_interfaces; /* number of IDBs, and thus size of interface_packet_counts array */
220 GArray *interface_packet_counts; /* array of per_packet interface_id counts; one entry per file IDB */
221 uint32_t pkt_interface_id_unknown; /* counts if packet interface_id didn't match a known one */
222 GArray *idb_info_strings; /* array of IDB info strings */
223} capture_info;
224
225static char *decimal_point;
226
227static void
228enable_all_infos(void)
229{
230 report_all_infos = true1;
231
232 cap_file_type = true1;
233 cap_file_encap = true1;
234 cap_snaplen = true1;
235 cap_packet_count = true1;
236 cap_file_size = true1;
237 cap_comment = true1;
238 pkt_comments = true1;
239 cap_file_more_info = true1;
240 cap_file_idb = true1;
241 cap_file_nrb = true1;
242 cap_file_dsb = true1;
243
244 cap_data_size = true1;
245 cap_duration = true1;
246 cap_earliest_packet_time = true1;
247 cap_latest_packet_time = true1;
248 cap_order = true1;
249
250 cap_data_rate_byte = true1;
251 cap_data_rate_bit = true1;
252 cap_packet_size = true1;
253 cap_packet_rate = true1;
254
255 cap_file_hashes = true1;
256}
257
258static void
259disable_all_infos(void)
260{
261 report_all_infos = false0;
262
263 cap_file_type = false0;
264 cap_file_encap = false0;
265 cap_snaplen = false0;
266 cap_packet_count = false0;
267 cap_file_size = false0;
268 cap_comment = false0;
269 pkt_comments = false0;
270 cap_file_more_info = false0;
271 cap_file_idb = false0;
272 cap_file_nrb = false0;
273 cap_file_dsb = false0;
274
275 cap_data_size = false0;
276 cap_duration = false0;
277 cap_earliest_packet_time = false0;
278 cap_latest_packet_time = false0;
279 cap_order = false0;
280
281 cap_data_rate_byte = false0;
282 cap_data_rate_bit = false0;
283 cap_packet_size = false0;
284 cap_packet_rate = false0;
285
286 cap_file_hashes = false0;
287}
288
289static const char *
290order_string(order_t order)
291{
292 switch (order) {
293
294 case IN_ORDER:
295 return "True";
296
297 case NOT_IN_ORDER:
298 return "False";
299
300 case ORDER_UNKNOWN:
301 return "Unknown";
302
303 default:
304 return "???"; /* "cannot happen" (the next step is "Profit!") */
305 }
306}
307
308static char *
309absolute_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info)
310{
311 /*
312 * https://web.archive.org/web/20120513133703/http://www.idrbt.ac.in/publications/workingpapers/Working%20Paper%20No.%209.pdf
313 *
314 * says:
315 *
316 * A 64-bit Unix time would be safe for the indefinite future, as
317 * this variable would not overflow until 2**63 or
318 * 9,223,372,036,854,775,808 (over nine quintillion) seconds
319 * after the beginning of the Unix epoch - corresponding to
320 * GMT 15:30:08, Sunday, 4th December, 292,277,026,596.
321 *
322 * So, if we're displaying the time as YYYY-MM-DD HH:MM:SS.SSSSSSSSS,
323 * we'll have the buffer be large enough for a date of the format
324 * 292277026596-MM-DD HH:MM:SS.SSSSSSSSS, which is the biggest value
325 * you'll get with a 64-bit time_t and a nanosecond-resolution
326 * fraction-of-a-second.
327 *
328 * That's 12+1+2+1+2+1+2+1+2+2+2+1+9+1, including the terminating
329 * \0, or 39.
330 *
331 * If we're displaying the time as epoch time, and the time is
332 * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
333 * to be big enough for 18446744073709551615.999999999. That's
334 * 20+1+9+1, including the terminating '\0', or 31. If it's
335 * signed, 2^63 is 9223372036854775808, so the buffer has to
336 * be big enough for -9223372036854775808.999999999, which is
337 * again 20+1+9+1, or 31.
338 *
339 * So we go with 39.
340 */
341 static char time_string_buf[39];
342
343 if (cf_info->times_known && cf_info->packet_count > 0) {
344 if (time_as_secs) {
345 display_epoch_time(time_string_buf, sizeof time_string_buf, timer, tsprecision);
346 } else {
347 format_nstime_as_iso8601(time_string_buf, sizeof time_string_buf, timer, decimal_point, true1, tsprecision);
348 }
349 } else {
350 snprintf(time_string_buf, sizeof time_string_buf, "n/a");
351 }
352 return time_string_buf;
353}
354
355static char *
356relative_time_string(nstime_t *timer, int tsprecision, capture_info *cf_info, bool_Bool want_seconds)
357{
358 const char *second = want_seconds ? " second" : "";
359 const char *plural = want_seconds ? "s" : "";
360 /*
361 * If we're displaying the time as epoch time, and the time is
362 * unsigned, 2^64-1 is 18446744073709551615, so the buffer has
363 * to be big enough for "18446744073709551615.999999999 seconds".
364 * That's 20+1+9+1+7+1, including the terminating '\0', or 39.
365 * If it's signed, 2^63 is 9223372036854775808, so the buffer has to
366 * be big enough for "-9223372036854775808.999999999 seconds",
367 * which is again 20+1+9+1+7+1, or 39.
368 */
369 static char time_string_buf[39];
370
371 if (cf_info->times_known && cf_info->packet_count > 0) {
372 char *ptr;
373 size_t remaining;
374 int num_bytes;
375
376 ptr = time_string_buf;
377 remaining = sizeof time_string_buf;
378 num_bytes = snprintf(ptr, remaining,
379 "%"PRId64"l" "d",
380 (int64_t)timer->secs);
381 if (num_bytes < 0) {
382 /*
383 * That got an error.
384 * Not much else we can do.
385 */
386 snprintf(ptr, remaining, "snprintf() failed");
387 return time_string_buf;
388 }
389 if ((unsigned int)num_bytes >= remaining) {
390 /*
391 * That filled up or would have overflowed the buffer.
392 * Nothing more we can do.
393 */
394 return time_string_buf;
395 }
396 ptr += num_bytes;
397 remaining -= num_bytes;
398
399 if (tsprecision != 0) {
400 /*
401 * Append the fractional part.
402 */
403 num_bytes = format_fractional_part_nsecs(ptr, remaining, timer->nsecs, decimal_point, tsprecision);
404 if ((unsigned int)num_bytes >= remaining) {
405 /*
406 * That filled up or would have overflowed the buffer.
407 * Nothing more we can do.
408 */
409 return time_string_buf;
410 }
411 ptr += num_bytes;
412 remaining -= num_bytes;
413 }
414
415 /*
416 * Append the units.
417 */
418 snprintf(ptr, remaining, "%s%s",
419 second,
420 timer->secs == 1 ? "" : plural);
421
422 return time_string_buf;
423 }
424
425 snprintf(time_string_buf, sizeof time_string_buf, "n/a");
426 return time_string_buf;
427}
428
429static void print_value(const char *text_p1, int width, const char *text_p2, double value)
430{
431 if (value > 0.0)
432 printf("%s%.*f%s\n", text_p1, width, value, text_p2);
433 else
434 printf("%sn/a\n", text_p1);
435}
436
437/* multi-line comments would conflict with the formatting that capinfos uses
438 we replace linefeeds with spaces */
439static void
440string_replace_newlines(char *str)
441{
442 char *p;
443
444 if (str) {
445 p = str;
446 while (*p != '\0') {
447 if (*p == '\n')
448 *p = ' ';
449 if (*p == '\r')
450 *p = ' ';
451 p++;
452 }
453 }
454}
455
456static void
457show_option_string(const char *prefix, const char *option_str)
458{
459 char *str;
460
461 if (option_str != NULL((void*)0) && option_str[0] != '\0') {
462 str = g_strdup(option_str)g_strdup_inline (option_str);
463 string_replace_newlines(str);
464 printf("%s%s\n", prefix, str);
465 g_free(str);
466 }
467}
468
469static void
470print_stats(const char *filename, capture_info *cf_info)
471{
472 const char *file_type_string, *file_encap_string;
473 char *size_string;
474 pkt_cmt *p, *prev;
475
476 /* Build printable strings for various stats */
477 if (machine_readable) {
478 file_type_string = wtap_file_type_subtype_name(cf_info->file_type);
479 file_encap_string = wtap_encap_name(cf_info->file_encap);
480 }
481 else {
482 file_type_string = wtap_file_type_subtype_description(cf_info->file_type);
483 file_encap_string = wtap_encap_description(cf_info->file_encap);
484 }
485
486 if (filename) printf ("File name: %s\n", filename);
487 if (cap_file_type) {
488 const char *compression_type_description;
489 compression_type_description = ws_compression_type_description(cf_info->compression_type);
490 if (compression_type_description == NULL((void*)0))
491 printf ("File type: %s\n",
492 file_type_string);
493 else
494 printf ("File type: %s (%s)\n",
495 file_type_string, compression_type_description);
496 }
497 if (cap_file_encap) {
498 printf ("File encapsulation: %s\n", file_encap_string);
499 if (cf_info->file_encap == WTAP_ENCAP_PER_PACKET-1) {
500 int i;
501 printf ("Encapsulation in use by packets (# of pkts):\n");
502 for (i=0; i<WTAP_NUM_ENCAP_TYPESwtap_get_num_encap_types(); i++) {
503 if (cf_info->encap_counts[i] > 0)
504 printf(" %s (%d)\n",
505 wtap_encap_description(i), cf_info->encap_counts[i]);
506 }
507 }
508 }
509 if (cap_file_more_info) {
510 printf ("File timestamp precision: %s (%d)\n",
511 wtap_tsprec_string(cf_info->file_tsprec), cf_info->file_tsprec);
512 }
513
514 if (cap_snaplen && cf_info->snap_set)
515 printf ("Packet size limit: file hdr: %u bytes\n", cf_info->snaplen);
516 else if (cap_snaplen && !cf_info->snap_set)
517 printf ("Packet size limit: file hdr: (not set)\n");
518 if (cf_info->snaplen_max_inferred > 0) {
519 if (cf_info->snaplen_min_inferred == cf_info->snaplen_max_inferred)
520 printf ("Packet size limit: inferred: %u bytes\n", cf_info->snaplen_min_inferred);
521 else
522 printf ("Packet size limit: inferred: %u bytes - %u bytes (range)\n",
523 cf_info->snaplen_min_inferred, cf_info->snaplen_max_inferred);
524 }
525 if (cap_packet_count) {
526 printf ("Number of packets: ");
527 if (machine_readable) {
528 printf ("%u\n", cf_info->packet_count);
529 } else {
530 size_string = format_size(cf_info->packet_count, FORMAT_SIZE_UNIT_NONE, 0)format_size_wmem(((void*)0), cf_info->packet_count, FORMAT_SIZE_UNIT_NONE
, 0)
;
531 printf ("%s\n", size_string);
532 g_free(size_string);
533 }
534 }
535 if (cap_file_size) {
536 printf ("File size: ");
537 if (machine_readable) {
538 printf ("%" PRId64"l" "d" " bytes\n", cf_info->filesize);
539 } else {
540 size_string = format_size(cf_info->filesize, FORMAT_SIZE_UNIT_BYTES, 0)format_size_wmem(((void*)0), cf_info->filesize, FORMAT_SIZE_UNIT_BYTES
, 0)
;
541 printf ("%s\n", size_string);
542 g_free(size_string);
543 }
544 }
545 if (cap_data_size) {
546 printf ("Data size: ");
547 if (machine_readable) {
548 printf ("%" PRIu64"l" "u" " bytes\n", cf_info->packet_bytes);
549 } else {
550 size_string = format_size(cf_info->packet_bytes, FORMAT_SIZE_UNIT_BYTES, 0)format_size_wmem(((void*)0), cf_info->packet_bytes, FORMAT_SIZE_UNIT_BYTES
, 0)
;
551 printf ("%s\n", size_string);
552 g_free(size_string);
553 }
554 }
555 if (cf_info->times_known) {
556 if (cap_duration) /* XXX - shorten to hh:mm:ss */
557 printf("Capture duration: %s\n", relative_time_string(&cf_info->duration, cf_info->duration_tsprec, cf_info, true1));
558 if (cap_earliest_packet_time)
559 printf("Earliest packet time: %s\n", absolute_time_string(&cf_info->earliest_packet_time, cf_info->earliest_packet_time_tsprec, cf_info));
560 if (cap_latest_packet_time)
561 printf("Latest packet time: %s\n", absolute_time_string(&cf_info->latest_packet_time, cf_info->latest_packet_time_tsprec, cf_info));
562 if (cap_data_rate_byte) {
563 printf("Data byte rate: ");
564 if (machine_readable) {
565 print_value("", 2, " bytes/sec", cf_info->data_rate);
566 } else {
567 size_string = format_size((int64_t)cf_info->data_rate, FORMAT_SIZE_UNIT_BYTES_S, 0)format_size_wmem(((void*)0), (int64_t)cf_info->data_rate, FORMAT_SIZE_UNIT_BYTES_S
, 0)
;
568 printf ("%s\n", size_string);
569 g_free(size_string);
570 }
571 }
572 if (cap_data_rate_bit) {
573 printf("Data bit rate: ");
574 if (machine_readable) {
575 print_value("", 2, " bits/sec", cf_info->data_rate*8);
576 } else {
577 size_string = format_size((int64_t)(cf_info->data_rate*8), FORMAT_SIZE_UNIT_BITS_S, 0)format_size_wmem(((void*)0), (int64_t)(cf_info->data_rate*
8), FORMAT_SIZE_UNIT_BITS_S, 0)
;
578 printf ("%s\n", size_string);
579 g_free(size_string);
580 }
581 }
582 }
583 if (cap_packet_size) printf("Average packet size: %.2f bytes\n", cf_info->packet_size);
584 if (cf_info->times_known) {
585 if (cap_packet_rate) {
586 printf("Average packet rate: ");
587 if (machine_readable) {
588 print_value("", 2, " packets/sec", cf_info->packet_rate);
589 } else {
590 size_string = format_size((int64_t)cf_info->packet_rate, FORMAT_SIZE_UNIT_PACKETS_S, 0)format_size_wmem(((void*)0), (int64_t)cf_info->packet_rate
, FORMAT_SIZE_UNIT_PACKETS_S, 0)
;
591 printf ("%s\n", size_string);
592 g_free(size_string);
593 }
594 }
595 }
596 if (cap_file_hashes) {
597 printf ("SHA256: %s\n", file_sha256);
598 printf ("SHA1: %s\n", file_sha1);
599 }
600 if (cap_order) printf ("Strict time order: %s\n", order_string(cf_info->order));
601
602 bool_Bool has_multiple_sections = (wtap_file_get_num_shbs(cf_info->wth) > 1);
603
604 for (unsigned int section_number = 0;
605 section_number < wtap_file_get_num_shbs(cf_info->wth);
606 section_number++) {
607 wtap_block_t shb;
608
609 // If we have more than one section, add headers for each section.
610 if (has_multiple_sections)
611 printf("Section %u:\n\n", section_number);
612
613 shb = wtap_file_get_shb(cf_info->wth, section_number);
614 if (shb != NULL((void*)0)) {
615 if (cap_file_more_info) {
616 char *str;
617
618 if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE2, &str) == WTAP_OPTTYPE_SUCCESS)
619 show_option_string("Capture hardware: ", str);
620 if (wtap_block_get_string_option_value(shb, OPT_SHB_OS3, &str) == WTAP_OPTTYPE_SUCCESS)
621 show_option_string("Capture oper-sys: ", str);
622 if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL4, &str) == WTAP_OPTTYPE_SUCCESS)
623 show_option_string("Capture application: ", str);
624 }
625 if (cap_comment) {
626 unsigned int i;
627 char *str;
628
629 for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT1, i, &str) == WTAP_OPTTYPE_SUCCESS; i++) {
630 show_option_string("Capture comment: ", str);
631 }
632 }
633 }
634 }
635
636 if (pkt_comments && cf_info->pkt_cmts != NULL((void*)0)) {
637 for (p = cf_info->pkt_cmts; p != NULL((void*)0); prev = p, p = p->next, g_free(prev)) {
638 if (machine_readable){
639 char *escaped_cmt = g_strescape(p->cmt, NULL((void*)0));
640 printf("Packet %u Comment: %s\n", p->recno, escaped_cmt);
641 g_free(escaped_cmt);
642 } else {
643 printf("Packet %u Comment: %s\n", p->recno, p->cmt);
644 }
645 g_free(p->cmt);
646 }
647 cf_info->pkt_cmts = NULL((void*)0);
648 }
649
650 if (cap_file_idb && cf_info->num_interfaces != 0) {
651 unsigned int i;
652 ws_assert(cf_info->num_interfaces == cf_info->idb_info_strings->len)do { if ((1) && !(cf_info->num_interfaces == cf_info
->idb_info_strings->len)) ws_log_fatal_full("Main", LOG_LEVEL_ERROR
, "capinfos.c", 652, __func__, "assertion failed: %s", "cf_info->num_interfaces == cf_info->idb_info_strings->len"
); } while (0)
;
653 printf ("Number of interfaces in file: %u\n", cf_info->num_interfaces);
654 for (i = 0; i < cf_info->idb_info_strings->len; i++) {
655 char *s = g_array_index(cf_info->idb_info_strings, char*, i)(((char**) (void *) (cf_info->idb_info_strings)->data) [
(i)])
;
656 uint32_t packet_count = 0;
657 if (i < cf_info->interface_packet_counts->len)
658 packet_count = g_array_index(cf_info->interface_packet_counts, uint32_t, i)(((uint32_t*) (void *) (cf_info->interface_packet_counts)->
data) [(i)])
;
659 printf ("Interface #%u info:\n", i);
660 printf ("%s", s);
661 printf (" Number of packets = %u\n", packet_count);
662 }
663 }
664
665 if (cap_file_nrb) {
666 if (num_ipv4_addresses != 0)
667 printf ("Number of resolved IPv4 addresses in file: %u\n", num_ipv4_addresses);
668 if (num_ipv6_addresses != 0)
669 printf ("Number of resolved IPv6 addresses in file: %u\n", num_ipv6_addresses);
670 }
671 if (cap_file_dsb) {
672 if (num_decryption_secrets != 0)
673 printf ("Number of decryption secrets in file: %u\n", num_decryption_secrets);
674 }
675}
676
677static void
678putsep(void)
679{
680 if (field_separator) putchar(field_separator);
681}
682
683static void
684putquote(void)
685{
686 if (quote_char) putchar(quote_char);
687}
688
689static void G_GNUC_PRINTF(1, 2)__attribute__((__format__ (__printf__, 1, 2)))
690print_stats_table_header_label(const char *fmt, ...)
691{
692 va_list ap;
693
694 putsep();
695 putquote();
696 va_start(ap, fmt)__builtin_va_start(ap, fmt);
697 vprintf(fmt, ap);
698 va_end(ap)__builtin_va_end(ap);
699 putquote();
700}
701
702static void
703print_stats_table_header(capture_info *cf_info)
704{
705 pkt_cmt *p;
706
707 putquote();
708 printf("File name");
709 putquote();
710
711 if (cap_file_type) print_stats_table_header_label("File type");
712 if (cap_file_encap) print_stats_table_header_label("File encapsulation");
713 if (cap_file_more_info) print_stats_table_header_label("File time precision");
714 if (cap_snaplen) {
715 print_stats_table_header_label("Packet size limit");
716 print_stats_table_header_label("Packet size limit min (inferred)");
717 print_stats_table_header_label("Packet size limit max (inferred)");
718 }
719 if (cap_packet_count) print_stats_table_header_label("Number of packets");
720 if (cap_file_size) print_stats_table_header_label("File size (bytes)");
721 if (cap_data_size) print_stats_table_header_label("Data size (bytes)");
722 if (cap_duration) print_stats_table_header_label("Capture duration (seconds)");
723 if (cap_earliest_packet_time) print_stats_table_header_label("Start time");
724 if (cap_latest_packet_time) print_stats_table_header_label("End time");
725 if (cap_data_rate_byte) print_stats_table_header_label("Data byte rate (bytes/sec)");
726 if (cap_data_rate_bit) print_stats_table_header_label("Data bit rate (bits/sec)");
727 if (cap_packet_size) print_stats_table_header_label("Average packet size (bytes)");
728 if (cap_packet_rate) print_stats_table_header_label("Average packet rate (packets/sec)");
729 if (cap_file_hashes) {
730 print_stats_table_header_label("SHA256");
731 print_stats_table_header_label("SHA1");
732 }
733 if (cap_order) print_stats_table_header_label("Strict time order");
734 if (cap_file_more_info) {
735 print_stats_table_header_label("Capture hardware");
736 print_stats_table_header_label("Capture oper-sys");
737 print_stats_table_header_label("Capture application");
738 }
739 if (cap_comment) print_stats_table_header_label("Capture comment");
740
741 if (pkt_comments && cf_info->pkt_cmts != NULL((void*)0)) {
742 for (p = cf_info->pkt_cmts; p != NULL((void*)0); p = p->next) {
743 print_stats_table_header_label("Packet %u Comment", p->recno);
744 }
745 }
746
747 printf("\n");
748}
749
750static void
751print_stats_table(const char *filename, capture_info *cf_info)
752{
753 const char *file_type_string, *file_encap_string;
754 pkt_cmt *p, *prev;
755
756 /* Build printable strings for various stats */
757 file_type_string = wtap_file_type_subtype_name(cf_info->file_type);
758 file_encap_string = wtap_encap_name(cf_info->file_encap);
759
760 if (filename) {
761 putquote();
762 printf("%s", filename);
763 putquote();
764 }
765
766 if (cap_file_type) {
767 putsep();
768 putquote();
769 printf("%s", file_type_string);
770 putquote();
771 }
772
773 /* ToDo: If WTAP_ENCAP_PER_PACKET, show the list of encapsulations encountered;
774 * Output a line for each different encap with all fields repeated except
775 * the encapsulation field which has "Per Packet: ..." for each
776 * encapsulation type seen ?
777 */
778 if (cap_file_encap) {
779 putsep();
780 putquote();
781 printf("%s", file_encap_string);
782 putquote();
783 }
784
785 if (cap_file_more_info) {
786 putsep();
787 putquote();
788 printf("%s", wtap_tsprec_string(cf_info->file_tsprec));
789 putquote();
790 }
791
792 if (cap_snaplen) {
793 putsep();
794 putquote();
795 if (cf_info->snap_set)
796 printf("%u", cf_info->snaplen);
797 else
798 printf("(not set)");
799 putquote();
800 if (cf_info->snaplen_max_inferred > 0) {
801 putsep();
802 putquote();
803 printf("%u", cf_info->snaplen_min_inferred);
804 putquote();
805 putsep();
806 putquote();
807 printf("%u", cf_info->snaplen_max_inferred);
808 putquote();
809 }
810 else {
811 putsep();
812 putquote();
813 printf("n/a");
814 putquote();
815 putsep();
816 putquote();
817 printf("n/a");
818 putquote();
819 }
820 }
821
822 if (cap_packet_count) {
823 putsep();
824 putquote();
825 printf("%u", cf_info->packet_count);
826 putquote();
827 }
828
829 if (cap_file_size) {
830 putsep();
831 putquote();
832 printf("%" PRId64"l" "d", cf_info->filesize);
833 putquote();
834 }
835
836 if (cap_data_size) {
837 putsep();
838 putquote();
839 printf("%" PRIu64"l" "u", cf_info->packet_bytes);
840 putquote();
841 }
842
843 if (cap_duration) {
844 putsep();
845 putquote();
846 printf("%s", relative_time_string(&cf_info->duration, cf_info->duration_tsprec, cf_info, false0));
847 putquote();
848 }
849
850 if (cap_earliest_packet_time) {
851 putsep();
852 putquote();
853 printf("%s", absolute_time_string(&cf_info->earliest_packet_time, cf_info->earliest_packet_time_tsprec, cf_info));
854 putquote();
855 }
856
857 if (cap_latest_packet_time) {
858 putsep();
859 putquote();
860 printf("%s", absolute_time_string(&cf_info->latest_packet_time, cf_info->latest_packet_time_tsprec, cf_info));
861 putquote();
862 }
863
864 if (cap_data_rate_byte) {
865 putsep();
866 putquote();
867 if (cf_info->times_known)
868 printf("%.2f", cf_info->data_rate);
869 else
870 printf("n/a");
871 putquote();
872 }
873
874 if (cap_data_rate_bit) {
875 putsep();
876 putquote();
877 if (cf_info->times_known)
878 printf("%.2f", cf_info->data_rate*8);
879 else
880 printf("n/a");
881 putquote();
882 }
883
884 if (cap_packet_size) {
885 putsep();
886 putquote();
887 printf("%.2f", cf_info->packet_size);
888 putquote();
889 }
890
891 if (cap_packet_rate) {
892 putsep();
893 putquote();
894 if (cf_info->times_known)
895 printf("%.2f", cf_info->packet_rate);
896 else
897 printf("n/a");
898 putquote();
899 }
900
901 if (cap_file_hashes) {
902 putsep();
903 putquote();
904 printf("%s", file_sha256);
905 putquote();
906
907 putsep();
908 putquote();
909 printf("%s", file_sha1);
910 putquote();
911 }
912
913 if (cap_order) {
914 putsep();
915 putquote();
916 printf("%s", order_string(cf_info->order));
917 putquote();
918 }
919
920 for (unsigned section_number = 0;
921 section_number < wtap_file_get_num_shbs(cf_info->wth);
922 section_number++) {
923 wtap_block_t shb;
924
925 shb = wtap_file_get_shb(cf_info->wth, section_number);
926 if (cap_file_more_info) {
927 char *str;
928
929 putsep();
930 putquote();
931 if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE2, &str) == WTAP_OPTTYPE_SUCCESS) {
932 printf("%s", str);
933 }
934 putquote();
935
936 putsep();
937 putquote();
938 if (wtap_block_get_string_option_value(shb, OPT_SHB_OS3, &str) == WTAP_OPTTYPE_SUCCESS) {
939 printf("%s", str);
940 }
941 putquote();
942
943 putsep();
944 putquote();
945 if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL4, &str) == WTAP_OPTTYPE_SUCCESS) {
946 printf("%s", str);
947 }
948 putquote();
949 }
950
951 /*
952 * One might argue that the following is silly to put into a table format,
953 * but oh well note that there may be *more than one* of each of these types
954 * of options. To mitigate some of the potential silliness the if(cap_comment)
955 * block is moved AFTER the if(cap_file_more_info) block. This will make any
956 * comments the last item(s) in each row. We now have a new -K option to
957 * disable cap_comment to more easily manage the potential silliness.
958 * Potential silliness includes multiple comments (therefore resulting in
959 * more than one additional column and/or comments with embedded newlines
960 * and/or possible delimiters).
961 *
962 * To mitigate embedded newlines and other special characters, use -M
963 */
964 if (cap_comment) {
965 unsigned int i;
966 char *opt_comment;
967 bool_Bool have_cap = false0;
968
969 for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT1, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) {
970 have_cap = true1;
971 putsep();
972 putquote();
973 if (machine_readable){
974 opt_comment = g_strescape(opt_comment, NULL((void*)0));
975 printf("%s", opt_comment);
976 g_free(opt_comment);
977 } else {
978 printf("%s", opt_comment);
979 }
980 putquote();
981 }
982 if(!have_cap) {
983 /* Maintain column alignment when we have no OPT_COMMENT */
984 putsep();
985 putquote();
986 putquote();
987 }
988 }
989
990 }
991
992 if (pkt_comments && cf_info->pkt_cmts != NULL((void*)0)) {
993 for(p = cf_info->pkt_cmts; p != NULL((void*)0); prev = p, p = p->next, g_free(prev)) {
994 putsep();
995 putquote();
996 if (machine_readable) {
997 char *escaped_cmt = g_strescape(p->cmt, NULL((void*)0));
998 printf("%s", escaped_cmt);
999 g_free(escaped_cmt);
1000 } else {
1001 printf("%s", p->cmt);
1002 }
1003 g_free(p->cmt);
1004 putquote();
1005 }
1006 cf_info->pkt_cmts = NULL((void*)0);
1007 }
1008
1009 printf("\n");
1010}
1011
1012static void
1013cleanup_capture_info(capture_info *cf_info)
1014{
1015 pkt_cmt *p, *prev;
1016 unsigned int i;
1017 ws_assert(cf_info != NULL)do { if ((1) && !(cf_info != ((void*)0))) ws_log_fatal_full
("Main", LOG_LEVEL_ERROR, "capinfos.c", 1017, __func__, "assertion failed: %s"
, "cf_info != ((void*)0)"); } while (0)
;
1018
1019 g_free(cf_info->encap_counts);
1020 cf_info->encap_counts = NULL((void*)0);
1021
1022 g_array_free(cf_info->interface_packet_counts, true1);
1023 cf_info->interface_packet_counts = NULL((void*)0);
1024
1025 if (cf_info->idb_info_strings) {
1026 for (i = 0; i < cf_info->idb_info_strings->len; i++) {
1027 char *s = g_array_index(cf_info->idb_info_strings, char*, i)(((char**) (void *) (cf_info->idb_info_strings)->data) [
(i)])
;
1028 g_free(s);
1029 }
1030 g_array_free(cf_info->idb_info_strings, true1);
1031 }
1032 cf_info->idb_info_strings = NULL((void*)0);
1033
1034 for(p = cf_info->pkt_cmts; p != NULL((void*)0); prev = p, p = p->next, g_free(prev)) {
1035 g_free(p->cmt);
1036 }
1037 cf_info->pkt_cmts = NULL((void*)0);
1038}
1039
1040static void
1041count_ipv4_address(const unsigned int addr _U___attribute__((unused)), const char *name _U___attribute__((unused)), const bool_Bool static_entry _U___attribute__((unused)))
1042{
1043 num_ipv4_addresses++;
1044}
1045
1046static void
1047count_ipv6_address(const ws_in6_addr *addrp _U___attribute__((unused)), const char *name _U___attribute__((unused)), const bool_Bool static_entry _U___attribute__((unused)))
1048{
1049 num_ipv6_addresses++;
1050}
1051
1052static void
1053count_decryption_secret(uint32_t secrets_type _U___attribute__((unused)), const void *secrets _U___attribute__((unused)), unsigned int size _U___attribute__((unused)))
1054{
1055 /* XXX - count them based on the secrets type (which is an opaque code,
1056 not a small integer)? */
1057 num_decryption_secrets++;
1058}
1059
1060static void
1061hash_to_str(const unsigned char *hash, size_t length, char *str)
1062{
1063 int i;
1064
1065 for (i = 0; i < (int) length; i++) {
1066 snprintf(str+(i*2), 3, "%02x", hash[i]);
1067 }
1068}
1069
1070static void
1071calculate_hashes(const char *filename)
1072{
1073 FILE *fh;
1074 size_t hash_bytes;
1075
1076 (void) g_strlcpy(file_sha256, "<unknown>", HASH_STR_SIZE(65));
1077 (void) g_strlcpy(file_sha1, "<unknown>", HASH_STR_SIZE(65));
1078
1079 if (cap_file_hashes) {
18
Assuming 'cap_file_hashes' is true
19
Taking true branch
1080 fh = ws_fopenfopen(filename, "rb");
1081 if (fh
19.1
'fh' is non-null
&& hd) {
20
Assuming 'hd' is non-null
21
Taking true branch
1082 while((hash_bytes = fread(hash_buf, 1, HASH_BUF_SIZE(1024 * 1024), fh)) > 0) {
22
Assuming stream reaches end-of-file here
23
Assuming the condition is true
24
Loop condition is true. Entering loop body
25
Read function called when stream is in EOF state. Function has no effect
1083 gcry_md_write(hd, hash_buf, hash_bytes);
1084 }
1085 gcry_md_final(hd)gcry_md_ctl ((hd), GCRYCTL_FINALIZE, ((void*)0), 0);
1086 hash_to_str(gcry_md_read(hd, GCRY_MD_SHA256), HASH_SIZE_SHA25632, file_sha256);
1087 hash_to_str(gcry_md_read(hd, GCRY_MD_SHA1), HASH_SIZE_SHA120, file_sha1);
1088 }
1089 if (fh) fclose(fh);
1090 if (hd) gcry_md_reset(hd);
1091 }
1092}
1093
1094static int
1095process_cap_file(const char *filename, bool_Bool need_separator)
1096{
1097 int status = 0;
1098 int err;
1099 char *err_info;
1100 int64_t size;
1101 int64_t data_offset;
1102
1103 uint32_t packet = 0;
1104 int64_t bytes = 0;
1105 uint32_t snaplen_min_inferred = 0xffffffff;
1106 uint32_t snaplen_max_inferred = 0;
1107 wtap_rec rec;
1108 capture_info cf_info;
1109 bool_Bool have_times = true1;
1110 nstime_t earliest_packet_time;
1111 int earliest_packet_time_tsprec;
1112 nstime_t latest_packet_time;
1113 int latest_packet_time_tsprec;
1114 nstime_t cur_time;
1115 nstime_t prev_time;
1116 bool_Bool know_order = false0;
1117 order_t order = IN_ORDER;
1118 unsigned int i;
1119 wtapng_iface_descriptions_t *idb_info;
1120
1121 pkt_cmt *pc = NULL((void*)0), *prev = NULL((void*)0);
1122
1123 cf_info.wth = wtap_open_offline(filename, WTAP_TYPE_AUTO0, &err, &err_info, false0, application_configuration_environment_prefix());
1124 if (!cf_info.wth) {
15
Assuming field 'wth' is non-null
16
Taking false branch
1125 report_cfile_open_failure(filename, err, err_info);
1126 return 2;
1127 }
1128
1129 /*
1130 * Calculate the checksums. Do this after wtap_open_offline, so we don't
1131 * bother calculating them for files that are not known capture types
1132 * where we wouldn't print them anyway.
1133 */
1134 calculate_hashes(filename);
17
Calling 'calculate_hashes'
1135
1136 if (need_separator && long_report) {
1137 printf("\n");
1138 }
1139
1140 nstime_set_zero(&earliest_packet_time);
1141 earliest_packet_time_tsprec = WTAP_TSPREC_UNKNOWN-2;
1142 nstime_set_zero(&latest_packet_time);
1143 latest_packet_time_tsprec = WTAP_TSPREC_UNKNOWN-2;
1144 nstime_set_zero(&cur_time);
1145 nstime_set_zero(&prev_time);
1146
1147 cf_info.encap_counts = g_new0(int,WTAP_NUM_ENCAP_TYPES)((int *) g_malloc0_n ((wtap_get_num_encap_types()), sizeof (int
)))
;
1148
1149 idb_info = wtap_file_get_idb_info(cf_info.wth);
1150
1151 ws_assert(idb_info->interface_data != NULL)do { if ((1) && !(idb_info->interface_data != ((void
*)0))) ws_log_fatal_full("Main", LOG_LEVEL_ERROR, "capinfos.c"
, 1151, __func__, "assertion failed: %s", "idb_info->interface_data != ((void*)0)"
); } while (0)
;
1152
1153 cf_info.pkt_cmts = NULL((void*)0);
1154 cf_info.num_interfaces = idb_info->interface_data->len;
1155 cf_info.interface_packet_counts = g_array_sized_new(false0, true1, sizeof(uint32_t), cf_info.num_interfaces);
1156 g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
1157 cf_info.pkt_interface_id_unknown = 0;
1158
1159 g_free(idb_info);
1160 idb_info = NULL((void*)0);
1161
1162 /* Zero out the counters for the callbacks. */
1163 num_ipv4_addresses = 0;
1164 num_ipv6_addresses = 0;
1165 num_decryption_secrets = 0;
1166
1167 /* Register callbacks for new name<->address maps from the file and
1168 decryption secrets from the file. */
1169 wtap_set_cb_new_ipv4(cf_info.wth, count_ipv4_address);
1170 wtap_set_cb_new_ipv6(cf_info.wth, count_ipv6_address);
1171 wtap_set_cb_new_secrets(cf_info.wth, count_decryption_secret);
1172
1173 /* Tally up data that we need to parse through the file to find */
1174 wtap_rec_init(&rec, DEFAULT_INIT_BUFFER_SIZE_2048(2 * 1024));
1175 while (wtap_read(cf_info.wth, &rec, &err, &err_info, &data_offset)) {
1176 if (rec.presence_flags & WTAP_HAS_TS0x00000001) {
1177 prev_time = cur_time;
1178 cur_time = rec.ts;
1179 if (packet == 0) {
1180 earliest_packet_time = rec.ts;
1181 earliest_packet_time_tsprec = rec.tsprec;
1182 latest_packet_time = rec.ts;
1183 latest_packet_time_tsprec = rec.tsprec;
1184 prev_time = rec.ts;
1185 }
1186 if (nstime_cmp(&cur_time, &prev_time) < 0) {
1187 order = NOT_IN_ORDER;
1188 }
1189 if (nstime_cmp(&cur_time, &earliest_packet_time) < 0) {
1190 earliest_packet_time = cur_time;
1191 earliest_packet_time_tsprec = rec.tsprec;
1192 }
1193 if (nstime_cmp(&cur_time, &latest_packet_time) > 0) {
1194 latest_packet_time = cur_time;
1195 latest_packet_time_tsprec = rec.tsprec;
1196 }
1197 } else {
1198 have_times = false0; /* at least one packet has no time stamp */
1199 if (order != NOT_IN_ORDER)
1200 order = ORDER_UNKNOWN;
1201 }
1202
1203 if (rec.rec_type == REC_TYPE_PACKET0) {
1204 bytes += rec.rec_header.packet_header.len;
1205 packet++;
1206 /* packet comments */
1207 if (pkt_comments && wtap_block_count_option(rec.block, OPT_COMMENT1) > 0) {
1208 char *cmt_buff;
1209 for (i = 0; wtap_block_get_nth_string_option_value(rec.block, OPT_COMMENT1, i, &cmt_buff) == WTAP_OPTTYPE_SUCCESS; i++) {
1210 pc = g_new0(pkt_cmt, 1)((pkt_cmt *) g_malloc0_n ((1), sizeof (pkt_cmt)));
1211
1212 pc->recno = packet;
1213 pc->cmt = g_strdup(cmt_buff)g_strdup_inline (cmt_buff);
1214 pc->next = NULL((void*)0);
1215
1216 if (prev == NULL((void*)0))
1217 cf_info.pkt_cmts = pc;
1218 else
1219 prev->next = pc;
1220
1221 prev = pc;
1222 }
1223 }
1224
1225 /* If caplen < len for a rcd, then presumably */
1226 /* 'Limit packet capture length' was done for this rcd. */
1227 /* Keep track as to the min/max actual snapshot lengths */
1228 /* seen for this file. */
1229 if (rec.rec_header.packet_header.caplen < rec.rec_header.packet_header.len) {
1230 if (rec.rec_header.packet_header.caplen < snaplen_min_inferred)
1231 snaplen_min_inferred = rec.rec_header.packet_header.caplen;
1232 if (rec.rec_header.packet_header.caplen > snaplen_max_inferred)
1233 snaplen_max_inferred = rec.rec_header.packet_header.caplen;
1234 }
1235
1236 if ((rec.rec_header.packet_header.pkt_encap > 0) &&
1237 (rec.rec_header.packet_header.pkt_encap < WTAP_NUM_ENCAP_TYPESwtap_get_num_encap_types())) {
1238 cf_info.encap_counts[rec.rec_header.packet_header.pkt_encap] += 1;
1239 } else {
1240 fprintf(stderrstderr, "capinfos: Unknown packet encapsulation %d in frame %u of file \"%s\"\n",
1241 rec.rec_header.packet_header.pkt_encap, packet, filename);
1242 }
1243
1244 /* Packet interface_id info */
1245 if (rec.presence_flags & WTAP_HAS_INTERFACE_ID0x00000004) {
1246 /* cf_info.num_interfaces is size, not index, so it's one more than max index */
1247 if (rec.rec_header.packet_header.interface_id >= cf_info.num_interfaces) {
1248 /*
1249 * OK, re-fetch the number of interfaces, as there might have
1250 * been an interface that was in the middle of packets, and
1251 * grow the array to be big enough for the new number of
1252 * interfaces.
1253 */
1254 idb_info = wtap_file_get_idb_info(cf_info.wth);
1255
1256 cf_info.num_interfaces = idb_info->interface_data->len;
1257 g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
1258
1259 g_free(idb_info);
1260 idb_info = NULL((void*)0);
1261 }
1262 if (rec.rec_header.packet_header.interface_id < cf_info.num_interfaces) {
1263 g_array_index(cf_info.interface_packet_counts, uint32_t,(((uint32_t*) (void *) (cf_info.interface_packet_counts)->
data) [(rec.rec_header.packet_header.interface_id)])
1264 rec.rec_header.packet_header.interface_id)(((uint32_t*) (void *) (cf_info.interface_packet_counts)->
data) [(rec.rec_header.packet_header.interface_id)])
+= 1;
1265 }
1266 else {
1267 cf_info.pkt_interface_id_unknown += 1;
1268 }
1269 }
1270 else {
1271 /* it's for interface_id 0 */
1272 if (cf_info.num_interfaces != 0) {
1273 g_array_index(cf_info.interface_packet_counts, uint32_t, 0)(((uint32_t*) (void *) (cf_info.interface_packet_counts)->
data) [(0)])
+= 1;
1274 }
1275 else {
1276 cf_info.pkt_interface_id_unknown += 1;
1277 }
1278 }
1279 }
1280
1281 wtap_rec_reset(&rec);
1282 } /* while */
1283 wtap_rec_cleanup(&rec);
1284
1285 /*
1286 * Get IDB info strings.
1287 * We do this at the end, so we can get information for all IDBs in
1288 * the file, even those that come after packet records, and so that
1289 * we get, for example, a count of the number of statistics entries
1290 * for each interface as of the *end* of the file.
1291 */
1292 idb_info = wtap_file_get_idb_info(cf_info.wth);
1293
1294 cf_info.idb_info_strings = g_array_sized_new(false0, false0, sizeof(char*), cf_info.num_interfaces);
1295 cf_info.num_interfaces = idb_info->interface_data->len;
1296 for (i = 0; i < cf_info.num_interfaces; i++) {
1297 const wtap_block_t if_descr = g_array_index(idb_info->interface_data, wtap_block_t, i)(((wtap_block_t*) (void *) (idb_info->interface_data)->
data) [(i)])
;
1298 char *s = wtap_get_debug_if_descr(if_descr, 21, "\n");
1299 g_array_append_val(cf_info.idb_info_strings, s)g_array_append_vals (cf_info.idb_info_strings, &(s), 1);
1300 }
1301
1302 g_free(idb_info);
1303 idb_info = NULL((void*)0);
1304
1305 if (err != 0) {
1306 fprintf(stderrstderr,
1307 "capinfos: An error occurred after reading %u packets from \"%s\".\n",
1308 packet, filename);
1309 report_cfile_read_failure(filename, err, err_info);
1310 if (err == WTAP_ERR_SHORT_READ-12) {
1311 /* Don't give up completely with this one. */
1312 status = 1;
1313 fprintf(stderrstderr,
1314 " (will continue anyway, checksums might be incorrect)\n");
1315 } else {
1316 cleanup_capture_info(&cf_info);
1317 wtap_close(cf_info.wth);
1318 return 2;
1319 }
1320 }
1321
1322 /* File size */
1323 size = wtap_file_size(cf_info.wth, &err);
1324 if (size == -1) {
1325 fprintf(stderrstderr,
1326 "capinfos: Can't get size of \"%s\": %s.\n",
1327 filename, g_strerror(err));
1328 cleanup_capture_info(&cf_info);
1329 wtap_close(cf_info.wth);
1330 return 2;
1331 }
1332
1333 cf_info.filesize = size;
1334
1335 /* File Type */
1336 cf_info.file_type = wtap_file_type_subtype(cf_info.wth);
1337 cf_info.compression_type = wtap_get_compression_type(cf_info.wth);
1338
1339 /* File Encapsulation */
1340 cf_info.file_encap = wtap_file_encap(cf_info.wth);
1341
1342 cf_info.file_tsprec = wtap_file_tsprec(cf_info.wth);
1343
1344 /* Packet size limit (snaplen) */
1345 cf_info.snaplen = wtap_snapshot_length(cf_info.wth);
1346 if (cf_info.snaplen > 0)
1347 cf_info.snap_set = true1;
1348 else
1349 cf_info.snap_set = false0;
1350
1351 cf_info.snaplen_min_inferred = snaplen_min_inferred;
1352 cf_info.snaplen_max_inferred = snaplen_max_inferred;
1353
1354 /* # of packets */
1355 cf_info.packet_count = packet;
1356
1357 /* File Times */
1358 cf_info.times_known = have_times;
1359 cf_info.earliest_packet_time = earliest_packet_time;
1360 cf_info.earliest_packet_time_tsprec = earliest_packet_time_tsprec;
1361 cf_info.latest_packet_time = latest_packet_time;
1362 cf_info.latest_packet_time_tsprec = latest_packet_time_tsprec;
1363 nstime_delta(&cf_info.duration, &latest_packet_time, &earliest_packet_time);
1364 /* Duration precision is the higher of the earliest and latest packet timestamp precisions. */
1365 if (cf_info.latest_packet_time_tsprec > cf_info.earliest_packet_time_tsprec)
1366 cf_info.duration_tsprec = cf_info.latest_packet_time_tsprec;
1367 else
1368 cf_info.duration_tsprec = cf_info.earliest_packet_time_tsprec;
1369 cf_info.know_order = know_order;
1370 cf_info.order = order;
1371
1372 /* Number of packet bytes */
1373 cf_info.packet_bytes = bytes;
1374
1375 cf_info.data_rate = 0.0;
1376 cf_info.packet_rate = 0.0;
1377 cf_info.packet_size = 0.0;
1378
1379 if (packet > 0) {
1380 double delta_time = nstime_to_sec(&latest_packet_time) - nstime_to_sec(&earliest_packet_time);
1381 if (delta_time > 0.0) {
1382 cf_info.data_rate = (double)bytes / delta_time; /* Data rate per second */
1383 cf_info.packet_rate = (double)packet / delta_time; /* packet rate per second */
1384 }
1385 cf_info.packet_size = (double)bytes / packet; /* Avg packet size */
1386 }
1387
1388 if (!long_report && table_report_header) {
1389 print_stats_table_header(&cf_info);
1390 }
1391
1392 if (long_report) {
1393 print_stats(filename, &cf_info);
1394 } else {
1395 print_stats_table(filename, &cf_info);
1396 }
1397
1398 cleanup_capture_info(&cf_info);
1399 wtap_close(cf_info.wth);
1400
1401 return status;
1402}
1403
1404static void
1405print_usage(FILE *output)
1406{
1407 fprintf(output, "\n");
1408 fprintf(output, "Usage: capinfos [options] <infile> ...\n");
1409 fprintf(output, "\n");
1410 fprintf(output, "General infos:\n");
1411 fprintf(output, " -t display the capture file type\n");
1412 fprintf(output, " -E display the capture file encapsulation\n");
1413 fprintf(output, " -I display the capture file interface information\n");
1414 fprintf(output, " -F display additional capture file information\n");
1415 fprintf(output, " -H display the SHA256 and SHA1 hashes of the file\n");
1416 fprintf(output, " -k display the capture comment\n");
1417 fprintf(output, " -p display individual packet comments\n");
1418 fprintf(output, "\n");
1419 fprintf(output, "Size infos:\n");
1420 fprintf(output, " -c display the number of packets\n");
1421 fprintf(output, " -s display the size of the file (in bytes)\n");
1422 fprintf(output, " -d display the total length of all packets (in bytes)\n");
1423 fprintf(output, " -l display the packet size limit (snapshot length)\n");
1424 fprintf(output, "\n");
1425 fprintf(output, "Time infos:\n");
1426 fprintf(output, " -u display the capture duration (in seconds)\n");
1427 fprintf(output, " -a display the timestamp of the earliest packet\n");
1428 fprintf(output, " -e display the timestamp of the latest packet\n");
1429 fprintf(output, " -o display the capture file chronological status (True/False)\n");
1430 fprintf(output, " -S display earliest and latest packet timestamps as seconds\n");
1431 fprintf(output, "\n");
1432 fprintf(output, "Statistic infos:\n");
1433 fprintf(output, " -y display average data rate (in bytes/sec)\n");
1434 fprintf(output, " -i display average data rate (in bits/sec)\n");
1435 fprintf(output, " -z display average packet size (in bytes)\n");
1436 fprintf(output, " -x display average packet rate (in packets/sec)\n");
1437 fprintf(output, "\n");
1438 fprintf(output, "Metadata infos:\n");
1439 fprintf(output, " -n display number of resolved IPv4 and IPv6 addresses\n");
1440 fprintf(output, " -D display number of decryption secrets\n");
1441 fprintf(output, "\n");
1442 fprintf(output, "Output format:\n");
1443 fprintf(output, " -L generate long report (default)\n");
1444 fprintf(output, " -T generate table report\n");
1445 fprintf(output, " -M display machine-readable values in long reports\n");
1446 fprintf(output, "\n");
1447 fprintf(output, "Table report options:\n");
1448 fprintf(output, " -R generate header record (default)\n");
1449 fprintf(output, " -r do not generate header record\n");
1450 fprintf(output, "\n");
1451 fprintf(output, " -B separate infos with TAB character (default)\n");
1452 fprintf(output, " -m separate infos with comma (,) character\n");
1453 fprintf(output, " -b separate infos with SPACE character\n");
1454 fprintf(output, "\n");
1455 fprintf(output, " -N do not quote infos (default)\n");
1456 fprintf(output, " -q quote infos with single quotes (')\n");
1457 fprintf(output, " -Q quote infos with double quotes (\")\n");
1458 fprintf(output, "\n");
1459 fprintf(output, "Miscellaneous:\n");
1460 fprintf(output, " -h, --help display this help and exit\n");
1461 fprintf(output, " -v, --version display version info and exit\n");
1462 fprintf(output, " -C cancel processing if file open fails (default is to continue)\n");
1463 fprintf(output, " -A generate all infos (default)\n");
1464 fprintf(output, " -K disable displaying the capture comment\n");
1465 fprintf(output, " -P disable displaying individual packet comments\n");
1466 fprintf(output, "\n");
1467 fprintf(output, "Options are processed from left to right order with later options superseding\n");
1468 fprintf(output, "or adding to earlier options.\n");
1469 fprintf(output, "\n");
1470 fprintf(output, "If no options are given the default is to display all infos in long report\n");
1471 fprintf(output, "output format.\n");
1472}
1473
1474int
1475main(int argc, char *argv[])
1476{
1477 char *configuration_init_error;
1478 bool_Bool need_separator = false0;
1479 int opt;
1480 int overall_error_status = EXIT_SUCCESS0;
1481 static const struct ws_option long_options[] = {
1482 {"help", ws_no_argument0, NULL((void*)0), 'h'},
1483 {"version", ws_no_argument0, NULL((void*)0), 'v'},
1484 LONGOPT_WSLOG{"log-level", 1, ((void*)0), 5000 +1}, {"log-domain", 1, ((void
*)0), 5000 +2}, {"log-domains", 1, ((void*)0), 5000 +2}, {"log-file"
, 1, ((void*)0), 5000 +3}, {"log-fatal", 1, ((void*)0), 5000 +
4}, {"log-fatal-domain", 1, ((void*)0), 5000 +5}, {"log-fatal-domains"
, 1, ((void*)0), 5000 +5}, {"log-debug", 1, ((void*)0), 5000 +
6}, {"log-noisy", 1, ((void*)0), 5000 +7},
1485 {0, 0, 0, 0 }
1486 };
1487 const struct file_extension_info* file_extensions;
1488 unsigned num_extensions;
1489
1490#define OPTSTRING"abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST" "abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST"
1491 static const char optstring[] = OPTSTRING"abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST";
1492
1493 int status = 0;
1494
1495 /* Set the program name. */
1496 g_set_prgname("capinfos");
1497
1498 /*
1499 * Set the C-language locale to the native environment and set the
1500 * code page to UTF-8 on Windows.
1501 */
1502#ifdef _WIN32
1503 setlocale(LC_ALL6, ".UTF-8");
1504#else
1505 setlocale(LC_ALL6, "");
1506#endif
1507
1508 cmdarg_err_init(stderr_cmdarg_err, stderr_cmdarg_err_cont);
1509
1510 /* Initialize log handler early so we can have proper logging during startup. */
1511 ws_log_init(vcmdarg_err, "Capinfos Debug Console");
1512
1513 /* Early logging command-line initialization. */
1514 ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION1);
1515
1516 ws_noisy("Finished log init and parsing command line log arguments")do { if (1) { ws_log_full("Main", LOG_LEVEL_NOISY, "capinfos.c"
, 1516, __func__, "Finished log init and parsing command line log arguments"
); } } while (0)
;
1
Taking true branch
2
Loop condition is false. Exiting loop
1517
1518 /* Get the decimal point. */
1519 decimal_point = g_strdup(localeconv()->decimal_point)g_strdup_inline (localeconv()->decimal_point);
1520
1521#ifdef _WIN32
1522 create_app_running_mutex();
1523#endif /* _WIN32 */
1524
1525 /*
1526 * Get credential information for later use.
1527 */
1528 init_process_policies();
1529
1530 /*
1531 * Attempt to get the pathname of the directory containing the
1532 * executable file.
1533 */
1534 configuration_init_error = configuration_init(argv[0], "wireshark");
1535 if (configuration_init_error != NULL((void*)0)) {
3
Assuming 'configuration_init_error' is equal to NULL
4
Taking false branch
1536 fprintf(stderrstderr,
1537 "capinfos: Can't get pathname of directory containing the capinfos program: %s.\n",
1538 configuration_init_error);
1539 g_free(configuration_init_error);
1540 }
1541
1542 /* Initialize the version information. */
1543 ws_init_version_info("Capinfos", NULL((void*)0), application_get_vcs_version_info, NULL((void*)0), NULL((void*)0));
1544
1545 init_report_failure_message("capinfos");
1546
1547 application_file_extensions(&file_extensions, &num_extensions);
1548 wtap_init(true1, application_configuration_environment_prefix(), file_extensions, num_extensions);
1549
1550 /* Process the options */
1551 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL((void*)0))) !=-1) {
5
Assuming the condition is false
6
Loop condition is false. Execution continues on line 1743
1552
1553 switch (opt) {
1554
1555 case 't':
1556 if (report_all_infos) disable_all_infos();
1557 cap_file_type = true1;
1558 break;
1559
1560 case 'E':
1561 if (report_all_infos) disable_all_infos();
1562 cap_file_encap = true1;
1563 break;
1564
1565 case 'l':
1566 if (report_all_infos) disable_all_infos();
1567 cap_snaplen = true1;
1568 break;
1569
1570 case 'c':
1571 if (report_all_infos) disable_all_infos();
1572 cap_packet_count = true1;
1573 break;
1574
1575 case 's':
1576 if (report_all_infos) disable_all_infos();
1577 cap_file_size = true1;
1578 break;
1579
1580 case 'd':
1581 if (report_all_infos) disable_all_infos();
1582 cap_data_size = true1;
1583 break;
1584
1585 case 'u':
1586 if (report_all_infos) disable_all_infos();
1587 cap_duration = true1;
1588 break;
1589
1590 case 'a':
1591 if (report_all_infos) disable_all_infos();
1592 cap_earliest_packet_time = true1;
1593 break;
1594
1595 case 'e':
1596 if (report_all_infos) disable_all_infos();
1597 cap_latest_packet_time = true1;
1598 break;
1599
1600 case 'S':
1601 time_as_secs = true1;
1602 break;
1603
1604 case 'y':
1605 if (report_all_infos) disable_all_infos();
1606 cap_data_rate_byte = true1;
1607 break;
1608
1609 case 'i':
1610 if (report_all_infos) disable_all_infos();
1611 cap_data_rate_bit = true1;
1612 break;
1613
1614 case 'z':
1615 if (report_all_infos) disable_all_infos();
1616 cap_packet_size = true1;
1617 break;
1618
1619 case 'x':
1620 if (report_all_infos) disable_all_infos();
1621 cap_packet_rate = true1;
1622 break;
1623
1624 case 'H':
1625 if (report_all_infos) disable_all_infos();
1626 cap_file_hashes = true1;
1627 break;
1628
1629 case 'o':
1630 if (report_all_infos) disable_all_infos();
1631 cap_order = true1;
1632 break;
1633
1634 case 'k':
1635 if (report_all_infos) disable_all_infos();
1636 cap_comment = true1;
1637 break;
1638
1639 case 'p':
1640 if (report_all_infos) disable_all_infos();
1641 pkt_comments = true1;
1642 break;
1643
1644 case 'K':
1645 cap_comment = false0;
1646 break;
1647
1648 case 'P':
1649 pkt_comments = false0;
1650 break;
1651
1652 case 'F':
1653 if (report_all_infos) disable_all_infos();
1654 cap_file_more_info = true1;
1655 break;
1656
1657 case 'I':
1658 if (report_all_infos) disable_all_infos();
1659 cap_file_idb = true1;
1660 break;
1661
1662 case 'n':
1663 if (report_all_infos) disable_all_infos();
1664 cap_file_nrb = true1;
1665 break;
1666
1667 case 'D':
1668 if (report_all_infos) disable_all_infos();
1669 cap_file_dsb = true1;
1670 break;
1671
1672 case 'C':
1673 stop_after_failure = true1;
1674 break;
1675
1676 case 'A':
1677 enable_all_infos();
1678 break;
1679
1680 case 'L':
1681 long_report = true1;
1682 break;
1683
1684 case 'T':
1685 long_report = false0;
1686 break;
1687
1688 case 'M':
1689 machine_readable = true1;
1690 break;
1691
1692 case 'R':
1693 table_report_header = true1;
1694 break;
1695
1696 case 'r':
1697 table_report_header = false0;
1698 break;
1699
1700 case 'N':
1701 quote_char = '\0';
1702 break;
1703
1704 case 'q':
1705 quote_char = '\'';
1706 break;
1707
1708 case 'Q':
1709 quote_char = '"';
1710 break;
1711
1712 case 'B':
1713 field_separator = '\t';
1714 break;
1715
1716 case 'm':
1717 field_separator = ',';
1718 break;
1719
1720 case 'b':
1721 field_separator = ' ';
1722 break;
1723
1724 case 'h':
1725 show_help_header("Print various information (infos) about capture files.");
1726 print_usage(stdoutstdout);
1727 goto exit;
1728 break;
1729
1730 case 'v':
1731 show_version();
1732 goto exit;
1733 break;
1734
1735 case '?': /* Bad flag - print usage message */
1736 print_usage(stderrstderr);
1737 overall_error_status = WS_EXIT_INVALID_OPTION1;
1738 goto exit;
1739 break;
1740 }
1741 }
1742
1743 if ((argc - ws_optind) < 1) {
7
Assuming the condition is false
8
Taking false branch
1744 print_usage(stderrstderr);
1745 overall_error_status = WS_EXIT_INVALID_OPTION1;
1746 goto exit;
1747 }
1748
1749 if (cap_file_hashes
8.1
'cap_file_hashes' is true
) {
9
Taking true branch
1750 gcry_check_version(NULL((void*)0));
1751 gcry_md_open(&hd, GCRY_MD_SHA256, 0);
1752 if (hd)
10
Assuming 'hd' is null
11
Taking false branch
1753 gcry_md_enable(hd, GCRY_MD_SHA1);
1754
1755 hash_buf = (char *)g_malloc(HASH_BUF_SIZE(1024 * 1024));
1756 }
1757
1758 overall_error_status = 0;
1759
1760 for (opt = ws_optind; opt < argc; opt++) {
12
Assuming 'opt' is < 'argc'
13
Loop condition is true. Entering loop body
1761
1762 status = process_cap_file(argv[opt], need_separator);
14
Calling 'process_cap_file'
1763 if (status) {
1764 /* Something failed. It's been reported; remember that processing
1765 one file failed and, if -C was specified, stop. */
1766 overall_error_status = status;
1767 if (stop_after_failure)
1768 goto exit;
1769 }
1770 if (status != 2) {
1771 /* Either it succeeded or it got a "short read" but printed
1772 information anyway. Note that we need a blank line before
1773 the next file's information, to separate it from the
1774 previous file. */
1775 need_separator = true1;
1776 }
1777 }
1778
1779exit:
1780 g_free(hash_buf);
1781 gcry_md_close(hd);
1782 wtap_cleanup();
1783 free_progdirs();
1784 return overall_error_status;
1785}