### Bug Summary

File: | builds/wireshark/wireshark/capinfos.c
Warning: | line 1068, column 33 File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
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=gnu11 -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-02-100336-3641-1 -x c /builds/wireshark/wireshark/capinfos.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

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 <gerald@wireshark.org>
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 |
95 | static bool_Bool stop_after_failure;
96 |
97 | /*
98 | * table report variables
99 | */
100 |
101 | static bool_Bool long_report = true1; /* By default generate long report */
102 | static bool_Bool table_report_header = true1; /* Generate column header by default */
103 | static char field_separator = '\t'; /* Use TAB as field separator by default */
104 | static char quote_char = '\0'; /* Do NOT quote fields by default */
105 | static 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 |
118 | static bool_Bool report_all_infos = true1; /* Report all infos */
119 |
120 | static bool_Bool cap_file_type = true1; /* Report capture type */
121 | static bool_Bool cap_file_encap = true1; /* Report encapsulation */
122 | static bool_Bool cap_snaplen = true1; /* Packet size limit (snaplen)*/
123 | static bool_Bool cap_packet_count = true1; /* Report packet count */
124 | static bool_Bool cap_file_size = true1; /* Report file size */
125 | static bool_Bool cap_comment = true1; /* Display the capture comment */
126 | static bool_Bool cap_file_more_info = true1; /* Report more file info */
127 | static bool_Bool cap_file_idb = true1; /* Report Interface info */
128 | static bool_Bool cap_file_nrb = true1; /* Report Name Resolution Block info */
129 | static bool_Bool cap_file_dsb = true1; /* Report Decryption Secrets Block info */
130 |
131 | static bool_Bool cap_data_size = true1; /* Report packet byte size */
132 | static bool_Bool cap_duration = true1; /* Report capture duration */
133 | static bool_Bool cap_earliest_packet_time = true1; /* Report timestamp of earliest packet */
134 | static bool_Bool cap_latest_packet_time = true1; /* Report timestamp of latest packet */
135 | static bool_Bool time_as_secs; /* Report time values as raw seconds */
136 |
137 | static bool_Bool cap_data_rate_byte = true1; /* Report data rate bytes/sec */
138 | static bool_Bool cap_data_rate_bit = true1; /* Report data rate bites/sec */
139 | static bool_Bool cap_packet_size = true1; /* Report average packet size */
140 | static bool_Bool cap_packet_rate = true1; /* Report average packet rate */
141 | static bool_Bool cap_order = true1; /* Report if packets are in chronological order (True/False) */
142 | static bool_Bool pkt_comments = true1; /* Report individual packet comments */
143 |
144 | static 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 |
154 | static char file_sha256[HASH_STR_SIZE(65)];
155 | static char file_sha1[HASH_STR_SIZE(65)];
156 |
157 | static char *hash_buf;
158 | static gcry_md_hd_t hd;
159 |
160 | static unsigned int num_ipv4_addresses;
161 | static unsigned int num_ipv6_addresses;
162 | static 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 | */
174 | typedef enum {
175 | IN_ORDER,
176 | NOT_IN_ORDER,
177 | ORDER_UNKNOWN
178 | } order_t;
179 |
180 | typedef struct _pkt_cmt {
181 | uint32_t recno;
182 | char *cmt;
183 | struct _pkt_cmt *next;
184 | } pkt_cmt;
185 |
186 | typedef 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 |
225 | static char *decimal_point;
226 |
227 | static void
228 | enable_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 |
258 | static void
259 | disable_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 |
289 | static const char *
290 | order_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 |
308 | static char *
309 | absolute_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 |
355 | static char *
356 | relative_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 |
429 | static 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 */
439 | static void
440 | string_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 |
456 | static void
457 | show_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 |
469 | static void
470 | print_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 | printf("Packet %u Comment: %s\n", p->recno, g_strescape(p->cmt, NULL((void*)0)));
640 | } else {
641 | printf("Packet %u Comment: %s\n", p->recno, p->cmt);
642 | }
643 | g_free(p->cmt);
644 | }
645 | }
646 |
647 | if (cap_file_idb && cf_info->num_interfaces != 0) {
648 | unsigned int i;
649 | 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", 649, __func__, "assertion failed: %s", "cf_info->num_interfaces == cf_info->idb_info_strings->len" ); } while (0);
650 | printf ("Number of interfaces in file: %u\n", cf_info->num_interfaces);
651 | for (i = 0; i < cf_info->idb_info_strings->len; i++) {
652 | char *s = g_array_index(cf_info->idb_info_strings, char*, i)(((char**) (void *) (cf_info->idb_info_strings)->data) [ (i)]);
653 | uint32_t packet_count = 0;
654 | if (i < cf_info->interface_packet_counts->len)
655 | packet_count = g_array_index(cf_info->interface_packet_counts, uint32_t, i)(((uint32_t*) (void *) (cf_info->interface_packet_counts)-> data) [(i)]);
656 | printf ("Interface #%u info:\n", i);
657 | printf ("%s", s);
658 | printf (" Number of packets = %u\n", packet_count);
659 | }
660 | }
661 |
662 | if (cap_file_nrb) {
663 | if (num_ipv4_addresses != 0)
664 | printf ("Number of resolved IPv4 addresses in file: %u\n", num_ipv4_addresses);
665 | if (num_ipv6_addresses != 0)
666 | printf ("Number of resolved IPv6 addresses in file: %u\n", num_ipv6_addresses);
667 | }
668 | if (cap_file_dsb) {
669 | if (num_decryption_secrets != 0)
670 | printf ("Number of decryption secrets in file: %u\n", num_decryption_secrets);
671 | }
672 | }
673 |
674 | static void
675 | putsep(void)
676 | {
677 | if (field_separator) putchar(field_separator);
678 | }
679 |
680 | static void
681 | putquote(void)
682 | {
683 | if (quote_char) putchar(quote_char);
684 | }
685 |
686 | static void G_GNUC_PRINTF(1, 2)__attribute__((__format__ (__printf__, 1, 2)))
687 | print_stats_table_header_label(const char *fmt, ...)
688 | {
689 | va_list ap;
690 |
691 | putsep();
692 | putquote();
693 | va_start(ap, fmt)__builtin_va_start(ap, fmt);
694 | vprintf(fmt, ap);
695 | va_end(ap)__builtin_va_end(ap);
696 | putquote();
697 | }
698 |
699 | static void
700 | print_stats_table_header(capture_info *cf_info)
701 | {
702 | pkt_cmt *p;
703 |
704 | putquote();
705 | printf("File name");
706 | putquote();
707 |
708 | if (cap_file_type) print_stats_table_header_label("File type");
709 | if (cap_file_encap) print_stats_table_header_label("File encapsulation");
710 | if (cap_file_more_info) print_stats_table_header_label("File time precision");
711 | if (cap_snaplen) {
712 | print_stats_table_header_label("Packet size limit");
713 | print_stats_table_header_label("Packet size limit min (inferred)");
714 | print_stats_table_header_label("Packet size limit max (inferred)");
715 | }
716 | if (cap_packet_count) print_stats_table_header_label("Number of packets");
717 | if (cap_file_size) print_stats_table_header_label("File size (bytes)");
718 | if (cap_data_size) print_stats_table_header_label("Data size (bytes)");
719 | if (cap_duration) print_stats_table_header_label("Capture duration (seconds)");
720 | if (cap_earliest_packet_time) print_stats_table_header_label("Start time");
721 | if (cap_latest_packet_time) print_stats_table_header_label("End time");
722 | if (cap_data_rate_byte) print_stats_table_header_label("Data byte rate (bytes/sec)");
723 | if (cap_data_rate_bit) print_stats_table_header_label("Data bit rate (bits/sec)");
724 | if (cap_packet_size) print_stats_table_header_label("Average packet size (bytes)");
725 | if (cap_packet_rate) print_stats_table_header_label("Average packet rate (packets/sec)");
726 | if (cap_file_hashes) {
727 | print_stats_table_header_label("SHA256");
728 | print_stats_table_header_label("SHA1");
729 | }
730 | if (cap_order) print_stats_table_header_label("Strict time order");
731 | if (cap_file_more_info) {
732 | print_stats_table_header_label("Capture hardware");
733 | print_stats_table_header_label("Capture oper-sys");
734 | print_stats_table_header_label("Capture application");
735 | }
736 | if (cap_comment) print_stats_table_header_label("Capture comment");
737 |
738 | if (pkt_comments && cf_info->pkt_cmts != NULL((void*)0)) {
739 | for (p = cf_info->pkt_cmts; p != NULL((void*)0); p = p->next) {
740 | print_stats_table_header_label("Packet %u Comment", p->recno);
741 | }
742 | }
743 |
744 | printf("\n");
745 | }
746 |
747 | static void
748 | print_stats_table(const char *filename, capture_info *cf_info)
749 | {
750 | const char *file_type_string, *file_encap_string;
751 | pkt_cmt *p, *prev;
752 |
753 | /* Build printable strings for various stats */
754 | file_type_string = wtap_file_type_subtype_name(cf_info->file_type);
755 | file_encap_string = wtap_encap_name(cf_info->file_encap);
756 |
757 | if (filename) {
758 | putquote();
759 | printf("%s", filename);
760 | putquote();
761 | }
762 |
763 | if (cap_file_type) {
764 | putsep();
765 | putquote();
766 | printf("%s", file_type_string);
767 | putquote();
768 | }
769 |
770 | /* ToDo: If WTAP_ENCAP_PER_PACKET, show the list of encapsulations encountered;
771 | * Output a line for each different encap with all fields repeated except
772 | * the encapsulation field which has "Per Packet: ..." for each
773 | * encapsulation type seen ?
774 | */
775 | if (cap_file_encap) {
776 | putsep();
777 | putquote();
778 | printf("%s", file_encap_string);
779 | putquote();
780 | }
781 |
782 | if (cap_file_more_info) {
783 | putsep();
784 | putquote();
785 | printf("%s", wtap_tsprec_string(cf_info->file_tsprec));
786 | putquote();
787 | }
788 |
789 | if (cap_snaplen) {
790 | putsep();
791 | putquote();
792 | if (cf_info->snap_set)
793 | printf("%u", cf_info->snaplen);
794 | else
795 | printf("(not set)");
796 | putquote();
797 | if (cf_info->snaplen_max_inferred > 0) {
798 | putsep();
799 | putquote();
800 | printf("%u", cf_info->snaplen_min_inferred);
801 | putquote();
802 | putsep();
803 | putquote();
804 | printf("%u", cf_info->snaplen_max_inferred);
805 | putquote();
806 | }
807 | else {
808 | putsep();
809 | putquote();
810 | printf("n/a");
811 | putquote();
812 | putsep();
813 | putquote();
814 | printf("n/a");
815 | putquote();
816 | }
817 | }
818 |
819 | if (cap_packet_count) {
820 | putsep();
821 | putquote();
822 | printf("%u", cf_info->packet_count);
823 | putquote();
824 | }
825 |
826 | if (cap_file_size) {
827 | putsep();
828 | putquote();
829 | printf("%" PRId64"l" "d", cf_info->filesize);
830 | putquote();
831 | }
832 |
833 | if (cap_data_size) {
834 | putsep();
835 | putquote();
836 | printf("%" PRIu64"l" "u", cf_info->packet_bytes);
837 | putquote();
838 | }
839 |
840 | if (cap_duration) {
841 | putsep();
842 | putquote();
843 | printf("%s", relative_time_string(&cf_info->duration, cf_info->duration_tsprec, cf_info, false0));
844 | putquote();
845 | }
846 |
847 | if (cap_earliest_packet_time) {
848 | putsep();
849 | putquote();
850 | printf("%s", absolute_time_string(&cf_info->earliest_packet_time, cf_info->earliest_packet_time_tsprec, cf_info));
851 | putquote();
852 | }
853 |
854 | if (cap_latest_packet_time) {
855 | putsep();
856 | putquote();
857 | printf("%s", absolute_time_string(&cf_info->latest_packet_time, cf_info->latest_packet_time_tsprec, cf_info));
858 | putquote();
859 | }
860 |
861 | if (cap_data_rate_byte) {
862 | putsep();
863 | putquote();
864 | if (cf_info->times_known)
865 | printf("%.2f", cf_info->data_rate);
866 | else
867 | printf("n/a");
868 | putquote();
869 | }
870 |
871 | if (cap_data_rate_bit) {
872 | putsep();
873 | putquote();
874 | if (cf_info->times_known)
875 | printf("%.2f", cf_info->data_rate*8);
876 | else
877 | printf("n/a");
878 | putquote();
879 | }
880 |
881 | if (cap_packet_size) {
882 | putsep();
883 | putquote();
884 | printf("%.2f", cf_info->packet_size);
885 | putquote();
886 | }
887 |
888 | if (cap_packet_rate) {
889 | putsep();
890 | putquote();
891 | if (cf_info->times_known)
892 | printf("%.2f", cf_info->packet_rate);
893 | else
894 | printf("n/a");
895 | putquote();
896 | }
897 |
898 | if (cap_file_hashes) {
899 | putsep();
900 | putquote();
901 | printf("%s", file_sha256);
902 | putquote();
903 |
904 | putsep();
905 | putquote();
906 | printf("%s", file_sha1);
907 | putquote();
908 | }
909 |
910 | if (cap_order) {
911 | putsep();
912 | putquote();
913 | printf("%s", order_string(cf_info->order));
914 | putquote();
915 | }
916 |
917 | for (unsigned section_number = 0;
918 | section_number < wtap_file_get_num_shbs(cf_info->wth);
919 | section_number++) {
920 | wtap_block_t shb;
921 |
922 | shb = wtap_file_get_shb(cf_info->wth, section_number);
923 | if (cap_file_more_info) {
924 | char *str;
925 |
926 | putsep();
927 | putquote();
928 | if (wtap_block_get_string_option_value(shb, OPT_SHB_HARDWARE2, &str) == WTAP_OPTTYPE_SUCCESS) {
929 | printf("%s", str);
930 | }
931 | putquote();
932 |
933 | putsep();
934 | putquote();
935 | if (wtap_block_get_string_option_value(shb, OPT_SHB_OS3, &str) == WTAP_OPTTYPE_SUCCESS) {
936 | printf("%s", str);
937 | }
938 | putquote();
939 |
940 | putsep();
941 | putquote();
942 | if (wtap_block_get_string_option_value(shb, OPT_SHB_USERAPPL4, &str) == WTAP_OPTTYPE_SUCCESS) {
943 | printf("%s", str);
944 | }
945 | putquote();
946 | }
947 |
948 | /*
949 | * One might argue that the following is silly to put into a table format,
950 | * but oh well note that there may be *more than one* of each of these types
951 | * of options. To mitigate some of the potential silliness the if(cap_comment)
952 | * block is moved AFTER the if(cap_file_more_info) block. This will make any
953 | * comments the last item(s) in each row. We now have a new -K option to
954 | * disable cap_comment to more easily manage the potential silliness.
955 | * Potential silliness includes multiple comments (therefore resulting in
956 | * more than one additional column and/or comments with embedded newlines
957 | * and/or possible delimiters).
958 | *
959 | * To mitigate embedded newlines and other special characters, use -M
960 | */
961 | if (cap_comment) {
962 | unsigned int i;
963 | char *opt_comment;
964 | bool_Bool have_cap = false0;
965 |
966 | for (i = 0; wtap_block_get_nth_string_option_value(shb, OPT_COMMENT1, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) {
967 | have_cap = true1;
968 | putsep();
969 | putquote();
970 | if (machine_readable){
971 | printf("%s", g_strescape(opt_comment, NULL((void*)0)));
972 | } else {
973 | printf("%s", opt_comment);
974 | }
975 | putquote();
976 | }
977 | if(!have_cap) {
978 | /* Maintain column alignment when we have no OPT_COMMENT */
979 | putsep();
980 | putquote();
981 | putquote();
982 | }
983 | }
984 |
985 | }
986 |
987 | if (pkt_comments && cf_info->pkt_cmts != NULL((void*)0)) {
988 | for(p = cf_info->pkt_cmts; p != NULL((void*)0); prev = p, p = p->next, g_free(prev)) {
989 | putsep();
990 | putquote();
991 | if (machine_readable) {
992 | printf("%s", g_strescape(p->cmt, NULL((void*)0)));
993 | } else {
994 | printf("%s", p->cmt);
995 | }
996 | g_free(p->cmt);
997 | putquote();
998 | }
999 | }
1000 |
1001 | printf("\n");
1002 | }
1003 |
1004 | static void
1005 | cleanup_capture_info(capture_info *cf_info)
1006 | {
1007 | unsigned int i;
1008 | ws_assert(cf_info != NULL)do { if ((1) && !(cf_info != ((void*)0))) ws_log_fatal_full ("Main", LOG_LEVEL_ERROR, "capinfos.c", 1008, __func__, "assertion failed: %s" , "cf_info != ((void*)0)"); } while (0);
1009 |
1010 | g_free(cf_info->encap_counts);
1011 | cf_info->encap_counts = NULL((void*)0);
1012 |
1013 | g_array_free(cf_info->interface_packet_counts, true1);
1014 | cf_info->interface_packet_counts = NULL((void*)0);
1015 |
1016 | if (cf_info->idb_info_strings) {
1017 | for (i = 0; i < cf_info->idb_info_strings->len; i++) {
1018 | char *s = g_array_index(cf_info->idb_info_strings, char*, i)(((char**) (void *) (cf_info->idb_info_strings)->data) [ (i)]);
1019 | g_free(s);
1020 | }
1021 | g_array_free(cf_info->idb_info_strings, true1);
1022 | }
1023 | cf_info->idb_info_strings = NULL((void*)0);
1024 | }
1025 |
1026 | static void
1027 | count_ipv4_address(const unsigned int addr _U___attribute__((unused)), const char *name _U___attribute__((unused)), const bool_Bool static_entry _U___attribute__((unused)))
1028 | {
1029 | num_ipv4_addresses++;
1030 | }
1031 |
1032 | static void
1033 | count_ipv6_address(const ws_in6_addr *addrp _U___attribute__((unused)), const char *name _U___attribute__((unused)), const bool_Bool static_entry _U___attribute__((unused)))
1034 | {
1035 | num_ipv6_addresses++;
1036 | }
1037 |
1038 | static void
1039 | count_decryption_secret(uint32_t secrets_type _U___attribute__((unused)), const void *secrets _U___attribute__((unused)), unsigned int size _U___attribute__((unused)))
1040 | {
1041 | /* XXX - count them based on the secrets type (which is an opaque code,
1042 | not a small integer)? */
1043 | num_decryption_secrets++;
1044 | }
1045 |
1046 | static void
1047 | hash_to_str(const unsigned char *hash, size_t length, char *str)
1048 | {
1049 | int i;
1050 |
1051 | for (i = 0; i < (int) length; i++) {
1052 | snprintf(str+(i*2), 3, "%02x", hash[i]);
1053 | }
1054 | }
1055 |
1056 | static void
1057 | calculate_hashes(const char *filename)
1058 | {
1059 | FILE *fh;
1060 | size_t hash_bytes;
1061 |
1062 | (void) g_strlcpy(file_sha256, "<unknown>", HASH_STR_SIZE(65));
1063 | (void) g_strlcpy(file_sha1, "<unknown>", HASH_STR_SIZE(65));
1064 |
1065 | if (cap_file_hashes) {
18 | ← | Assuming 'cap_file_hashes' is true | →
19 | ← | Taking true branch | →
1066 | fh = ws_fopenfopen(filename, "rb");
1067 | if (fh
19.1 | 'fh' is non-null
&& hd) {
20 | ← | Assuming 'hd' is non-null | →
21 | ← | Taking true branch | →
1068 | while((hash_bytes = fread(hash_buf, 1, HASH_BUF_SIZE(1024 * 1024), fh)) > 0) {
22 | ← | Assuming this stream operation fails | →
23 | ← | Assuming the condition is true | →
24 | ← | Loop condition is true. Entering loop body | →
25 | ← | File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior
1069 | gcry_md_write(hd, hash_buf, hash_bytes);
1070 | }
1071 | gcry_md_final(hd)gcry_md_ctl ((hd), GCRYCTL_FINALIZE, ((void*)0), 0);
1072 | hash_to_str(gcry_md_read(hd, GCRY_MD_SHA256), HASH_SIZE_SHA25632, file_sha256);
1073 | hash_to_str(gcry_md_read(hd, GCRY_MD_SHA1), HASH_SIZE_SHA120, file_sha1);
1074 | }
1075 | if (fh) fclose(fh);
1076 | if (hd) gcry_md_reset(hd);
1077 | }
1078 | }
1079 |
1080 | static int
1081 | process_cap_file(const char *filename, bool_Bool need_separator)
1082 | {
1083 | int status = 0;
1084 | int err;
1085 | char *err_info;
1086 | int64_t size;
1087 | int64_t data_offset;
1088 |
1089 | uint32_t packet = 0;
1090 | int64_t bytes = 0;
1091 | uint32_t snaplen_min_inferred = 0xffffffff;
1092 | uint32_t snaplen_max_inferred = 0;
1093 | wtap_rec rec;
1094 | capture_info cf_info;
1095 | bool_Bool have_times = true1;
1096 | nstime_t earliest_packet_time;
1097 | int earliest_packet_time_tsprec;
1098 | nstime_t latest_packet_time;
1099 | int latest_packet_time_tsprec;
1100 | nstime_t cur_time;
1101 | nstime_t prev_time;
1102 | bool_Bool know_order = false0;
1103 | order_t order = IN_ORDER;
1104 | unsigned int i;
1105 | wtapng_iface_descriptions_t *idb_info;
1106 |
1107 | pkt_cmt *pc = NULL((void*)0), *prev = NULL((void*)0);
1108 |
1109 | cf_info.wth = wtap_open_offline(filename, WTAP_TYPE_AUTO0, &err, &err_info, false0, application_configuration_environment_prefix());
1110 | if (!cf_info.wth) {
15 | ← | Assuming field 'wth' is non-null | →
16 | ← | Taking false branch | →
1111 | report_cfile_open_failure(filename, err, err_info);
1112 | return 2;
1113 | }
1114 |
1115 | /*
1116 | * Calculate the checksums. Do this after wtap_open_offline, so we don't
1117 | * bother calculating them for files that are not known capture types
1118 | * where we wouldn't print them anyway.
1119 | */
1120 | calculate_hashes(filename);
17 | ← | Calling 'calculate_hashes' | →
1121 |
1122 | if (need_separator && long_report) {
1123 | printf("\n");
1124 | }
1125 |
1126 | nstime_set_zero(&earliest_packet_time);
1127 | earliest_packet_time_tsprec = WTAP_TSPREC_UNKNOWN-2;
1128 | nstime_set_zero(&latest_packet_time);
1129 | latest_packet_time_tsprec = WTAP_TSPREC_UNKNOWN-2;
1130 | nstime_set_zero(&cur_time);
1131 | nstime_set_zero(&prev_time);
1132 |
1133 | cf_info.encap_counts = g_new0(int,WTAP_NUM_ENCAP_TYPES)((int *) g_malloc0_n ((wtap_get_num_encap_types()), sizeof (int )));
1134 |
1135 | idb_info = wtap_file_get_idb_info(cf_info.wth);
1136 |
1137 | 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" , 1137, __func__, "assertion failed: %s", "idb_info->interface_data != ((void*)0)" ); } while (0);
1138 |
1139 | cf_info.pkt_cmts = NULL((void*)0);
1140 | cf_info.num_interfaces = idb_info->interface_data->len;
1141 | cf_info.interface_packet_counts = g_array_sized_new(false0, true1, sizeof(uint32_t), cf_info.num_interfaces);
1142 | g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
1143 | cf_info.pkt_interface_id_unknown = 0;
1144 |
1145 | g_free(idb_info);
1146 | idb_info = NULL((void*)0);
1147 |
1148 | /* Zero out the counters for the callbacks. */
1149 | num_ipv4_addresses = 0;
1150 | num_ipv6_addresses = 0;
1151 | num_decryption_secrets = 0;
1152 |
1153 | /* Register callbacks for new name<->address maps from the file and
1154 | decryption secrets from the file. */
1155 | wtap_set_cb_new_ipv4(cf_info.wth, count_ipv4_address);
1156 | wtap_set_cb_new_ipv6(cf_info.wth, count_ipv6_address);
1157 | wtap_set_cb_new_secrets(cf_info.wth, count_decryption_secret);
1158 |
1159 | /* Tally up data that we need to parse through the file to find */
1160 | wtap_rec_init(&rec, DEFAULT_INIT_BUFFER_SIZE_2048(2 * 1024));
1161 | while (wtap_read(cf_info.wth, &rec, &err, &err_info, &data_offset)) {
1162 | if (rec.presence_flags & WTAP_HAS_TS0x00000001) {
1163 | prev_time = cur_time;
1164 | cur_time = rec.ts;
1165 | if (packet == 0) {
1166 | earliest_packet_time = rec.ts;
1167 | earliest_packet_time_tsprec = rec.tsprec;
1168 | latest_packet_time = rec.ts;
1169 | latest_packet_time_tsprec = rec.tsprec;
1170 | prev_time = rec.ts;
1171 | }
1172 | if (nstime_cmp(&cur_time, &prev_time) < 0) {
1173 | order = NOT_IN_ORDER;
1174 | }
1175 | if (nstime_cmp(&cur_time, &earliest_packet_time) < 0) {
1176 | earliest_packet_time = cur_time;
1177 | earliest_packet_time_tsprec = rec.tsprec;
1178 | }
1179 | if (nstime_cmp(&cur_time, &latest_packet_time) > 0) {
1180 | latest_packet_time = cur_time;
1181 | latest_packet_time_tsprec = rec.tsprec;
1182 | }
1183 | } else {
1184 | have_times = false0; /* at least one packet has no time stamp */
1185 | if (order != NOT_IN_ORDER)
1186 | order = ORDER_UNKNOWN;
1187 | }
1188 |
1189 | if (rec.rec_type == REC_TYPE_PACKET0) {
1190 | bytes += rec.rec_header.packet_header.len;
1191 | packet++;
1192 | /* packet comments */
1193 | if (pkt_comments && wtap_block_count_option(rec.block, OPT_COMMENT1) > 0) {
1194 | char *cmt_buff;
1195 | for (i = 0; wtap_block_get_nth_string_option_value(rec.block, OPT_COMMENT1, i, &cmt_buff) == WTAP_OPTTYPE_SUCCESS; i++) {
1196 | pc = g_new0(pkt_cmt, 1)((pkt_cmt *) g_malloc0_n ((1), sizeof (pkt_cmt)));
1197 |
1198 | pc->recno = packet;
1199 | pc->cmt = g_strdup(cmt_buff)g_strdup_inline (cmt_buff);
1200 | pc->next = NULL((void*)0);
1201 |
1202 | if (prev == NULL((void*)0))
1203 | cf_info.pkt_cmts = pc;
1204 | else
1205 | prev->next = pc;
1206 |
1207 | prev = pc;
1208 | }
1209 | }
1210 |
1211 | /* If caplen < len for a rcd, then presumably */
1212 | /* 'Limit packet capture length' was done for this rcd. */
1213 | /* Keep track as to the min/max actual snapshot lengths */
1214 | /* seen for this file. */
1215 | if (rec.rec_header.packet_header.caplen < rec.rec_header.packet_header.len) {
1216 | if (rec.rec_header.packet_header.caplen < snaplen_min_inferred)
1217 | snaplen_min_inferred = rec.rec_header.packet_header.caplen;
1218 | if (rec.rec_header.packet_header.caplen > snaplen_max_inferred)
1219 | snaplen_max_inferred = rec.rec_header.packet_header.caplen;
1220 | }
1221 |
1222 | if ((rec.rec_header.packet_header.pkt_encap > 0) &&
1223 | (rec.rec_header.packet_header.pkt_encap < WTAP_NUM_ENCAP_TYPESwtap_get_num_encap_types())) {
1224 | cf_info.encap_counts[rec.rec_header.packet_header.pkt_encap] += 1;
1225 | } else {
1226 | fprintf(stderrstderr, "capinfos: Unknown packet encapsulation %d in frame %u of file \"%s\"\n",
1227 | rec.rec_header.packet_header.pkt_encap, packet, filename);
1228 | }
1229 |
1230 | /* Packet interface_id info */
1231 | if (rec.presence_flags & WTAP_HAS_INTERFACE_ID0x00000004) {
1232 | /* cf_info.num_interfaces is size, not index, so it's one more than max index */
1233 | if (rec.rec_header.packet_header.interface_id >= cf_info.num_interfaces) {
1234 | /*
1235 | * OK, re-fetch the number of interfaces, as there might have
1236 | * been an interface that was in the middle of packets, and
1237 | * grow the array to be big enough for the new number of
1238 | * interfaces.
1239 | */
1240 | idb_info = wtap_file_get_idb_info(cf_info.wth);
1241 |
1242 | cf_info.num_interfaces = idb_info->interface_data->len;
1243 | g_array_set_size(cf_info.interface_packet_counts, cf_info.num_interfaces);
1244 |
1245 | g_free(idb_info);
1246 | idb_info = NULL((void*)0);
1247 | }
1248 | if (rec.rec_header.packet_header.interface_id < cf_info.num_interfaces) {
1249 | 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)])
1250 | rec.rec_header.packet_header.interface_id)(((uint32_t*) (void *) (cf_info.interface_packet_counts)-> data) [(rec.rec_header.packet_header.interface_id)]) += 1;
1251 | }
1252 | else {
1253 | cf_info.pkt_interface_id_unknown += 1;
1254 | }
1255 | }
1256 | else {
1257 | /* it's for interface_id 0 */
1258 | if (cf_info.num_interfaces != 0) {
1259 | g_array_index(cf_info.interface_packet_counts, uint32_t, 0)(((uint32_t*) (void *) (cf_info.interface_packet_counts)-> data) [(0)]) += 1;
1260 | }
1261 | else {
1262 | cf_info.pkt_interface_id_unknown += 1;
1263 | }
1264 | }
1265 | }
1266 |
1267 | wtap_rec_reset(&rec);
1268 | } /* while */
1269 | wtap_rec_cleanup(&rec);
1270 |
1271 | /*
1272 | * Get IDB info strings.
1273 | * We do this at the end, so we can get information for all IDBs in
1274 | * the file, even those that come after packet records, and so that
1275 | * we get, for example, a count of the number of statistics entries
1276 | * for each interface as of the *end* of the file.
1277 | */
1278 | idb_info = wtap_file_get_idb_info(cf_info.wth);
1279 |
1280 | cf_info.idb_info_strings = g_array_sized_new(false0, false0, sizeof(char*), cf_info.num_interfaces);
1281 | cf_info.num_interfaces = idb_info->interface_data->len;
1282 | for (i = 0; i < cf_info.num_interfaces; i++) {
1283 | 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)]);
1284 | char *s = wtap_get_debug_if_descr(if_descr, 21, "\n");
1285 | g_array_append_val(cf_info.idb_info_strings, s)g_array_append_vals (cf_info.idb_info_strings, &(s), 1);
1286 | }
1287 |
1288 | g_free(idb_info);
1289 | idb_info = NULL((void*)0);
1290 |
1291 | if (err != 0) {
1292 | fprintf(stderrstderr,
1293 | "capinfos: An error occurred after reading %u packets from \"%s\".\n",
1294 | packet, filename);
1295 | report_cfile_read_failure(filename, err, err_info);
1296 | if (err == WTAP_ERR_SHORT_READ-12) {
1297 | /* Don't give up completely with this one. */
1298 | status = 1;
1299 | fprintf(stderrstderr,
1300 | " (will continue anyway, checksums might be incorrect)\n");
1301 | } else {
1302 | cleanup_capture_info(&cf_info);
1303 | wtap_close(cf_info.wth);
1304 | return 2;
1305 | }
1306 | }
1307 |
1308 | /* File size */
1309 | size = wtap_file_size(cf_info.wth, &err);
1310 | if (size == -1) {
1311 | fprintf(stderrstderr,
1312 | "capinfos: Can't get size of \"%s\": %s.\n",
1313 | filename, g_strerror(err));
1314 | cleanup_capture_info(&cf_info);
1315 | wtap_close(cf_info.wth);
1316 | return 2;
1317 | }
1318 |
1319 | cf_info.filesize = size;
1320 |
1321 | /* File Type */
1322 | cf_info.file_type = wtap_file_type_subtype(cf_info.wth);
1323 | cf_info.compression_type = wtap_get_compression_type(cf_info.wth);
1324 |
1325 | /* File Encapsulation */
1326 | cf_info.file_encap = wtap_file_encap(cf_info.wth);
1327 |
1328 | cf_info.file_tsprec = wtap_file_tsprec(cf_info.wth);
1329 |
1330 | /* Packet size limit (snaplen) */
1331 | cf_info.snaplen = wtap_snapshot_length(cf_info.wth);
1332 | if (cf_info.snaplen > 0)
1333 | cf_info.snap_set = true1;
1334 | else
1335 | cf_info.snap_set = false0;
1336 |
1337 | cf_info.snaplen_min_inferred = snaplen_min_inferred;
1338 | cf_info.snaplen_max_inferred = snaplen_max_inferred;
1339 |
1340 | /* # of packets */
1341 | cf_info.packet_count = packet;
1342 |
1343 | /* File Times */
1344 | cf_info.times_known = have_times;
1345 | cf_info.earliest_packet_time = earliest_packet_time;
1346 | cf_info.earliest_packet_time_tsprec = earliest_packet_time_tsprec;
1347 | cf_info.latest_packet_time = latest_packet_time;
1348 | cf_info.latest_packet_time_tsprec = latest_packet_time_tsprec;
1349 | nstime_delta(&cf_info.duration, &latest_packet_time, &earliest_packet_time);
1350 | /* Duration precision is the higher of the earliest and latest packet timestamp precisions. */
1351 | if (cf_info.latest_packet_time_tsprec > cf_info.earliest_packet_time_tsprec)
1352 | cf_info.duration_tsprec = cf_info.latest_packet_time_tsprec;
1353 | else
1354 | cf_info.duration_tsprec = cf_info.earliest_packet_time_tsprec;
1355 | cf_info.know_order = know_order;
1356 | cf_info.order = order;
1357 |
1358 | /* Number of packet bytes */
1359 | cf_info.packet_bytes = bytes;
1360 |
1361 | cf_info.data_rate = 0.0;
1362 | cf_info.packet_rate = 0.0;
1363 | cf_info.packet_size = 0.0;
1364 |
1365 | if (packet > 0) {
1366 | double delta_time = nstime_to_sec(&latest_packet_time) - nstime_to_sec(&earliest_packet_time);
1367 | if (delta_time > 0.0) {
1368 | cf_info.data_rate = (double)bytes / delta_time; /* Data rate per second */
1369 | cf_info.packet_rate = (double)packet / delta_time; /* packet rate per second */
1370 | }
1371 | cf_info.packet_size = (double)bytes / packet; /* Avg packet size */
1372 | }
1373 |
1374 | if (!long_report && table_report_header) {
1375 | print_stats_table_header(&cf_info);
1376 | }
1377 |
1378 | if (long_report) {
1379 | print_stats(filename, &cf_info);
1380 | } else {
1381 | print_stats_table(filename, &cf_info);
1382 | }
1383 |
1384 | cleanup_capture_info(&cf_info);
1385 | wtap_close(cf_info.wth);
1386 |
1387 | return status;
1388 | }
1389 |
1390 | static void
1391 | print_usage(FILE *output)
1392 | {
1393 | fprintf(output, "\n");
1394 | fprintf(output, "Usage: capinfos [options] <infile> ...\n");
1395 | fprintf(output, "\n");
1396 | fprintf(output, "General infos:\n");
1397 | fprintf(output, " -t display the capture file type\n");
1398 | fprintf(output, " -E display the capture file encapsulation\n");
1399 | fprintf(output, " -I display the capture file interface information\n");
1400 | fprintf(output, " -F display additional capture file information\n");
1401 | fprintf(output, " -H display the SHA256 and SHA1 hashes of the file\n");
1402 | fprintf(output, " -k display the capture comment\n");
1403 | fprintf(output, " -p display individual packet comments\n");
1404 | fprintf(output, "\n");
1405 | fprintf(output, "Size infos:\n");
1406 | fprintf(output, " -c display the number of packets\n");
1407 | fprintf(output, " -s display the size of the file (in bytes)\n");
1408 | fprintf(output, " -d display the total length of all packets (in bytes)\n");
1409 | fprintf(output, " -l display the packet size limit (snapshot length)\n");
1410 | fprintf(output, "\n");
1411 | fprintf(output, "Time infos:\n");
1412 | fprintf(output, " -u display the capture duration (in seconds)\n");
1413 | fprintf(output, " -a display the timestamp of the earliest packet\n");
1414 | fprintf(output, " -e display the timestamp of the latest packet\n");
1415 | fprintf(output, " -o display the capture file chronological status (True/False)\n");
1416 | fprintf(output, " -S display earliest and latest packet timestamps as seconds\n");
1417 | fprintf(output, "\n");
1418 | fprintf(output, "Statistic infos:\n");
1419 | fprintf(output, " -y display average data rate (in bytes/sec)\n");
1420 | fprintf(output, " -i display average data rate (in bits/sec)\n");
1421 | fprintf(output, " -z display average packet size (in bytes)\n");
1422 | fprintf(output, " -x display average packet rate (in packets/sec)\n");
1423 | fprintf(output, "\n");
1424 | fprintf(output, "Metadata infos:\n");
1425 | fprintf(output, " -n display number of resolved IPv4 and IPv6 addresses\n");
1426 | fprintf(output, " -D display number of decryption secrets\n");
1427 | fprintf(output, "\n");
1428 | fprintf(output, "Output format:\n");
1429 | fprintf(output, " -L generate long report (default)\n");
1430 | fprintf(output, " -T generate table report\n");
1431 | fprintf(output, " -M display machine-readable values in long reports\n");
1432 | fprintf(output, "\n");
1433 | fprintf(output, "Table report options:\n");
1434 | fprintf(output, " -R generate header record (default)\n");
1435 | fprintf(output, " -r do not generate header record\n");
1436 | fprintf(output, "\n");
1437 | fprintf(output, " -B separate infos with TAB character (default)\n");
1438 | fprintf(output, " -m separate infos with comma (,) character\n");
1439 | fprintf(output, " -b separate infos with SPACE character\n");
1440 | fprintf(output, "\n");
1441 | fprintf(output, " -N do not quote infos (default)\n");
1442 | fprintf(output, " -q quote infos with single quotes (')\n");
1443 | fprintf(output, " -Q quote infos with double quotes (\")\n");
1444 | fprintf(output, "\n");
1445 | fprintf(output, "Miscellaneous:\n");
1446 | fprintf(output, " -h, --help display this help and exit\n");
1447 | fprintf(output, " -v, --version display version info and exit\n");
1448 | fprintf(output, " -C cancel processing if file open fails (default is to continue)\n");
1449 | fprintf(output, " -A generate all infos (default)\n");
1450 | fprintf(output, " -K disable displaying the capture comment\n");
1451 | fprintf(output, " -P disable displaying individual packet comments\n");
1452 | fprintf(output, "\n");
1453 | fprintf(output, "Options are processed from left to right order with later options superseding\n");
1454 | fprintf(output, "or adding to earlier options.\n");
1455 | fprintf(output, "\n");
1456 | fprintf(output, "If no options are given the default is to display all infos in long report\n");
1457 | fprintf(output, "output format.\n");
1458 | }
1459 |
1460 | int
1461 | main(int argc, char *argv[])
1462 | {
1463 | char *configuration_init_error;
1464 | bool_Bool need_separator = false0;
1465 | int opt;
1466 | int overall_error_status = EXIT_SUCCESS0;
1467 | static const struct ws_option long_options[] = {
1468 | {"help", ws_no_argument0, NULL((void*)0), 'h'},
1469 | {"version", ws_no_argument0, NULL((void*)0), 'v'},
1470 | 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},
1471 | {0, 0, 0, 0 }
1472 | };
1473 | const struct file_extension_info* file_extensions;
1474 | unsigned num_extensions;
1475 |
1476 | #define OPTSTRING"abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST" "abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST"
1477 | static const char optstring[] = OPTSTRING"abcdehiklmnopqrstuvxyzABCDEFHIKLMNPQRST";
1478 |
1479 | int status = 0;
1480 |
1481 | /* Set the program name. */
1482 | g_set_prgname("capinfos");
1483 |
1484 | /*
1485 | * Set the C-language locale to the native environment and set the
1486 | * code page to UTF-8 on Windows.
1487 | */
1488 | #ifdef _WIN32
1489 | setlocale(LC_ALL6, ".UTF-8");
1490 | #else
1491 | setlocale(LC_ALL6, "");
1492 | #endif
1493 |
1494 | cmdarg_err_init(stderr_cmdarg_err, stderr_cmdarg_err_cont);
1495 |
1496 | /* Initialize log handler early so we can have proper logging during startup. */
1497 | ws_log_init(vcmdarg_err, "Capinfos Debug Console");
1498 |
1499 | /* Early logging command-line initialization. */
1500 | ws_log_parse_args(&argc, argv, optstring, long_options, vcmdarg_err, WS_EXIT_INVALID_OPTION1);
1501 |
1502 | ws_noisy("Finished log init and parsing command line log arguments")do { if (1) { ws_log_full("Main", LOG_LEVEL_NOISY, "capinfos.c" , 1502, __func__, "Finished log init and parsing command line log arguments" ); } } while (0);
1 | Taking true branch | →
2 | ← | Loop condition is false. Exiting loop | →
1503 |
1504 | /* Get the decimal point. */
1505 | decimal_point = g_strdup(localeconv()->decimal_point)g_strdup_inline (localeconv()->decimal_point);
1506 |
1507 | #ifdef _WIN32
1508 | create_app_running_mutex();
1509 | #endif /* _WIN32 */
1510 |
1511 | /*
1512 | * Get credential information for later use.
1513 | */
1514 | init_process_policies();
1515 |
1516 | /*
1517 | * Attempt to get the pathname of the directory containing the
1518 | * executable file.
1519 | */
1520 | configuration_init_error = configuration_init(argv[0], "wireshark");
1521 | if (configuration_init_error != NULL((void*)0)) {
3 | ← | Assuming 'configuration_init_error' is equal to NULL | →
4 | ← | Taking false branch | →
1522 | fprintf(stderrstderr,
1523 | "capinfos: Can't get pathname of directory containing the capinfos program: %s.\n",
1524 | configuration_init_error);
1525 | g_free(configuration_init_error);
1526 | }
1527 |
1528 | /* Initialize the version information. */
1529 | ws_init_version_info("Capinfos", NULL((void*)0), application_get_vcs_version_info, NULL((void*)0), NULL((void*)0));
1530 |
1531 | init_report_failure_message("capinfos");
1532 |
1533 | application_file_extensions(&file_extensions, &num_extensions);
1534 | wtap_init(true1, application_configuration_environment_prefix(), file_extensions, num_extensions);
1535 |
1536 | /* Process the options */
1537 | 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 1729 | →
1538 |
1539 | switch (opt) {
1540 |
1541 | case 't':
1542 | if (report_all_infos) disable_all_infos();
1543 | cap_file_type = true1;
1544 | break;
1545 |
1546 | case 'E':
1547 | if (report_all_infos) disable_all_infos();
1548 | cap_file_encap = true1;
1549 | break;
1550 |
1551 | case 'l':
1552 | if (report_all_infos) disable_all_infos();
1553 | cap_snaplen = true1;
1554 | break;
1555 |
1556 | case 'c':
1557 | if (report_all_infos) disable_all_infos();
1558 | cap_packet_count = true1;
1559 | break;
1560 |
1561 | case 's':
1562 | if (report_all_infos) disable_all_infos();
1563 | cap_file_size = true1;
1564 | break;
1565 |
1566 | case 'd':
1567 | if (report_all_infos) disable_all_infos();
1568 | cap_data_size = true1;
1569 | break;
1570 |
1571 | case 'u':
1572 | if (report_all_infos) disable_all_infos();
1573 | cap_duration = true1;
1574 | break;
1575 |
1576 | case 'a':
1577 | if (report_all_infos) disable_all_infos();
1578 | cap_earliest_packet_time = true1;
1579 | break;
1580 |
1581 | case 'e':
1582 | if (report_all_infos) disable_all_infos();
1583 | cap_latest_packet_time = true1;
1584 | break;
1585 |
1586 | case 'S':
1587 | time_as_secs = true1;
1588 | break;
1589 |
1590 | case 'y':
1591 | if (report_all_infos) disable_all_infos();
1592 | cap_data_rate_byte = true1;
1593 | break;
1594 |
1595 | case 'i':
1596 | if (report_all_infos) disable_all_infos();
1597 | cap_data_rate_bit = true1;
1598 | break;
1599 |
1600 | case 'z':
1601 | if (report_all_infos) disable_all_infos();
1602 | cap_packet_size = true1;
1603 | break;
1604 |
1605 | case 'x':
1606 | if (report_all_infos) disable_all_infos();
1607 | cap_packet_rate = true1;
1608 | break;
1609 |
1610 | case 'H':
1611 | if (report_all_infos) disable_all_infos();
1612 | cap_file_hashes = true1;
1613 | break;
1614 |
1615 | case 'o':
1616 | if (report_all_infos) disable_all_infos();
1617 | cap_order = true1;
1618 | break;
1619 |
1620 | case 'k':
1621 | if (report_all_infos) disable_all_infos();
1622 | cap_comment = true1;
1623 | break;
1624 |
1625 | case 'p':
1626 | if (report_all_infos) disable_all_infos();
1627 | pkt_comments = true1;
1628 | break;
1629 |
1630 | case 'K':
1631 | cap_comment = false0;
1632 | break;
1633 |
1634 | case 'P':
1635 | pkt_comments = false0;
1636 | break;
1637 |
1638 | case 'F':
1639 | if (report_all_infos) disable_all_infos();
1640 | cap_file_more_info = true1;
1641 | break;
1642 |
1643 | case 'I':
1644 | if (report_all_infos) disable_all_infos();
1645 | cap_file_idb = true1;
1646 | break;
1647 |
1648 | case 'n':
1649 | if (report_all_infos) disable_all_infos();
1650 | cap_file_nrb = true1;
1651 | break;
1652 |
1653 | case 'D':
1654 | if (report_all_infos) disable_all_infos();
1655 | cap_file_dsb = true1;
1656 | break;
1657 |
1658 | case 'C':
1659 | stop_after_failure = true1;
1660 | break;
1661 |
1662 | case 'A':
1663 | enable_all_infos();
1664 | break;
1665 |
1666 | case 'L':
1667 | long_report = true1;
1668 | break;
1669 |
1670 | case 'T':
1671 | long_report = false0;
1672 | break;
1673 |
1674 | case 'M':
1675 | machine_readable = true1;
1676 | break;
1677 |
1678 | case 'R':
1679 | table_report_header = true1;
1680 | break;
1681 |
1682 | case 'r':
1683 | table_report_header = false0;
1684 | break;
1685 |
1686 | case 'N':
1687 | quote_char = '\0';
1688 | break;
1689 |
1690 | case 'q':
1691 | quote_char = '\'';
1692 | break;
1693 |
1694 | case 'Q':
1695 | quote_char = '"';
1696 | break;
1697 |
1698 | case 'B':
1699 | field_separator = '\t';
1700 | break;
1701 |
1702 | case 'm':
1703 | field_separator = ',';
1704 | break;
1705 |
1706 | case 'b':
1707 | field_separator = ' ';
1708 | break;
1709 |
1710 | case 'h':
1711 | show_help_header("Print various information (infos) about capture files.");
1712 | print_usage(stdoutstdout);
1713 | goto exit;
1714 | break;
1715 |
1716 | case 'v':
1717 | show_version();
1718 | goto exit;
1719 | break;
1720 |
1721 | case '?': /* Bad flag - print usage message */
1722 | print_usage(stderrstderr);
1723 | overall_error_status = WS_EXIT_INVALID_OPTION1;
1724 | goto exit;
1725 | break;
1726 | }
1727 | }
1728 |
1729 | if ((argc - ws_optind) < 1) {
7 | ← | Assuming the condition is false | →
8 | ← | Taking false branch | →
1730 | print_usage(stderrstderr);
1731 | overall_error_status = WS_EXIT_INVALID_OPTION1;
1732 | goto exit;
1733 | }
1734 |
1735 | if (cap_file_hashes
8.1 | 'cap_file_hashes' is true
) {
9 | ← | Taking true branch | →
1736 | gcry_check_version(NULL((void*)0));
1737 | gcry_md_open(&hd, GCRY_MD_SHA256, 0);
1738 | if (hd)
10 | ← | Assuming 'hd' is null | →
11 | ← | Taking false branch | →
1739 | gcry_md_enable(hd, GCRY_MD_SHA1);
1740 |
1741 | hash_buf = (char *)g_malloc(HASH_BUF_SIZE(1024 * 1024));
1742 | }
1743 |
1744 | overall_error_status = 0;
1745 |
1746 | for (opt = ws_optind; opt < argc; opt++) {
12 | ← | Assuming 'opt' is < 'argc' | →
13 | ← | Loop condition is true. Entering loop body | →
1747 |
1748 | status = process_cap_file(argv[opt], need_separator);
14 | ← | Calling 'process_cap_file' | →
1749 | if (status) {
1750 | /* Something failed. It's been reported; remember that processing
1751 | one file failed and, if -C was specified, stop. */
1752 | overall_error_status = status;
1753 | if (stop_after_failure)
1754 | goto exit;
1755 | }
1756 | if (status != 2) {
1757 | /* Either it succeeded or it got a "short read" but printed
1758 | information anyway. Note that we need a blank line before
1759 | the next file's information, to separate it from the
1760 | previous file. */
1761 | need_separator = true1;
1762 | }
1763 | }
1764 |
1765 | exit:
1766 | g_free(hash_buf);
1767 | gcry_md_close(hd);
1768 | wtap_cleanup();
1769 | free_progdirs();
1770 | return overall_error_status;
1771 | }