Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / rawshark.c
blob54ef7f0911166bbcb4f207ecbea4d305fb174c19
1 /* rawshark.c
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * Rawshark - Raw field extractor by Gerald Combs <gerald@wireshark.org>
8 * and Loris Degioanni <loris.degioanni@cacetech.com>
9 * Based on TShark, by Gilbert Ramirez <gram@alumni.rice.edu> and Guy Harris
10 * <guy@alum.mit.edu>.
12 * SPDX-License-Identifier: GPL-2.0-or-later
16 * Rawshark does the following:
17 * - Opens a specified file or named pipe
18 * - Applies a specified DLT or "decode as" encapsulation
19 * - Reads frames prepended with a libpcap packet header.
20 * - Prints a status line, followed by fields from a specified list.
23 #include <config.h>
24 #define WS_LOG_DOMAIN LOG_DOMAIN_MAIN
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <locale.h>
30 #include <limits.h>
32 #ifndef _WIN32
33 #include <sys/time.h>
34 #include <sys/resource.h>
35 #endif
37 #include <errno.h>
39 #include <ws_exit_codes.h>
40 #include <wsutil/ws_getopt.h>
42 #include <glib.h>
43 #include <epan/epan.h>
45 #include <epan/tfs.h>
46 #include <wsutil/array.h>
47 #include <wsutil/cmdarg_err.h>
48 #include <wsutil/filesystem.h>
49 #include <wsutil/file_util.h>
50 #include <wsutil/socket.h>
51 #include <wsutil/privileges.h>
52 #include <wsutil/please_report_bug.h>
53 #include <wsutil/wslog.h>
54 #include <wsutil/clopts_common.h>
56 #ifdef _WIN32
57 #include <wsutil/unicode-utils.h>
58 #include <wsutil/win32-utils.h>
59 #endif
61 #include "globals.h"
62 #include <epan/packet.h>
63 #include <epan/ftypes/ftypes.h>
64 #include "file.h"
65 #include <epan/disabled_protos.h>
66 #include <epan/prefs.h>
67 #include <epan/column.h>
68 #include <epan/print.h>
69 #include <epan/addr_resolv.h>
70 #ifdef HAVE_LIBPCAP
71 #include "ui/capture_ui_utils.h"
72 #endif
73 #include "ui/util.h"
74 #include "ui/dissect_opts.h"
75 #include "ui/failure_message.h"
76 #include <epan/epan_dissect.h>
77 #include <epan/stat_tap_ui.h>
78 #include <epan/timestamp.h>
79 #include "epan/column-utils.h"
80 #include "epan/proto.h"
81 #include <epan/tap.h>
83 #include <wiretap/wtap.h>
84 #include <wiretap/libpcap.h>
85 #include <wiretap/pcap-encap.h>
87 #include <cli_main.h>
88 #include <wsutil/version_info.h>
90 #include "capture/capture-pcap-util.h"
92 #ifdef HAVE_LIBPCAP
93 #include <setjmp.h>
94 #ifdef _WIN32
95 #include "capture/capture-wpcap.h"
96 #endif /* _WIN32 */
97 #endif /* HAVE_LIBPCAP */
99 #if 0
101 * This is the template for the decode as option; it is shared between the
102 * various functions that output the usage for this parameter.
104 static const char decode_as_arg_template[] = "<layer_type>==<selector>,<decode_as_protocol>";
105 #endif
107 /* Additional exit codes */
108 #define INVALID_DFILTER 2
109 #define FORMAT_ERROR 2
111 capture_file cfile;
113 static uint32_t cum_bytes;
114 static frame_data ref_frame;
115 static frame_data prev_dis_frame;
116 static frame_data prev_cap_frame;
119 * The way the packet decode is to be written.
121 typedef enum {
122 WRITE_TEXT, /* summary or detail text */
123 WRITE_XML /* PDML or PSML */
124 /* Add CSV and the like here */
125 } output_action_e;
127 static bool line_buffered;
128 static print_format_e print_format = PR_FMT_TEXT;
130 static bool want_pcap_pkthdr;
132 cf_status_t raw_cf_open(capture_file *cf, const char *fname);
133 static bool load_cap_file(capture_file *cf);
134 static bool process_packet(capture_file *cf, epan_dissect_t *edt, int64_t offset,
135 wtap_rec *rec, Buffer *buf);
136 static void show_print_file_io_error(int err);
138 static void protocolinfo_init(char *field);
139 static bool parse_field_string_format(char *format);
141 typedef enum {
142 SF_NONE, /* No format (placeholder) */
143 SF_NAME, /* %D Field name / description */
144 SF_NUMVAL, /* %N Numeric value */
145 SF_STRVAL /* %S String value */
146 } string_fmt_e;
148 typedef struct string_fmt_s {
149 char *plain;
150 string_fmt_e format; /* Valid if plain is NULL */
151 } string_fmt_t;
153 int n_rfilters;
154 int n_rfcodes;
155 dfilter_t *rfcodes[64];
156 int n_rfieldfilters;
157 dfilter_t *rfieldfcodes[64];
158 int fd;
159 int encap;
160 GPtrArray *string_fmts;
162 static void
163 print_usage(FILE *output)
165 fprintf(output, "\n");
166 fprintf(output, "Usage: rawshark [options] ...\n");
167 fprintf(output, "\n");
169 fprintf(output, "Input file:\n");
170 fprintf(output, " -r <infile>, --read-file <infile>\n");
171 fprintf(output," set the pipe or file name to read from\n");
173 fprintf(output, "\n");
174 fprintf(output, "Processing:\n");
175 fprintf(output, " -d <encap:linktype>|<proto:protoname>\n");
176 fprintf(output, " packet encapsulation or protocol\n");
177 fprintf(output, " -F <field> field to display\n");
178 #if !defined(_WIN32) && defined(RLIMIT_AS)
179 fprintf(output, " -m virtual memory limit, in bytes\n");
180 #endif
181 fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
182 fprintf(output, " as set in preferences)\n");
183 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtdv\"\n");
184 fprintf(output, " -p use the system's packet header format\n");
185 fprintf(output, " (which may have 64-bit timestamps)\n");
186 fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
187 fprintf(output, " packet filter in Wireshark display filter syntax\n");
188 fprintf(output, " -s skip PCAP header on input\n");
189 fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
190 fprintf(output, " packet filter in Wireshark display filter syntax\n");
191 fprintf(output, " --enable-protocol <proto_name>\n");
192 fprintf(output, " enable dissection of proto_name\n");
193 fprintf(output, " --disable-protocol <proto_name>\n");
194 fprintf(output, " disable dissection of proto_name\n");
195 fprintf(output, " --only-protocols <protocols>\n");
196 fprintf(output, " Only enable dissection of these protocols, comma\n");
197 fprintf(output, " separated. Disable everything else\n");
198 fprintf(output, " --disable-all-protocols\n");
199 fprintf(output, " Disable dissection of all protocols\n");
200 fprintf(output, " --enable-heuristic <short_name>\n");
201 fprintf(output, " enable dissection of heuristic protocol\n");
202 fprintf(output, " --disable-heuristic <short_name>\n");
203 fprintf(output, " disable dissection of heuristic protocol\n");
205 fprintf(output, "\n");
206 fprintf(output, "Output:\n");
207 fprintf(output, " -l flush output after each packet\n");
208 fprintf(output, " -S format string for fields\n");
209 fprintf(output, " (%%D - name, %%S - stringval, %%N numval)\n");
210 fprintf(output, " -t (a|ad|adoy|d|dd|e|r|u|ud|udoy)[.[N]]|.[N]\n");
211 fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
212 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
213 fprintf(output, "\n");
215 ws_log_print_usage(output);
216 fprintf(output, "\n");
218 fprintf(output, "\n");
219 fprintf(output, "Miscellaneous:\n");
220 fprintf(output, " -h, --help display this help and exit\n");
221 fprintf(output, " -v, --version display version info and exit\n");
222 fprintf(output, " -o <name>:<value> ... override preference setting\n");
223 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
227 * Open a pipe for raw input. This is a stripped-down version of
228 * pcap_loop.c:cap_pipe_open_live().
229 * We check if "pipe_name" is "-" (stdin) or a FIFO, and open it.
230 * @param pipe_name The name of the pipe or FIFO.
231 * @return A POSIX file descriptor on success, or -1 on failure.
233 static int
234 raw_pipe_open(const char *pipe_name)
236 #ifndef _WIN32
237 ws_statb64 pipe_stat;
238 #else
239 DWORD err;
240 wchar_t *err_str;
241 HANDLE hPipe = NULL;
242 #endif
243 int rfd;
245 ws_log(LOG_DOMAIN_CAPCHILD, LOG_LEVEL_DEBUG, "open_raw_pipe: %s", pipe_name);
248 * XXX Rawshark blocks until we return
250 if (strcmp(pipe_name, "-") == 0) {
251 rfd = 0; /* read from stdin */
252 #ifdef _WIN32
254 * This is needed to set the stdin pipe into binary mode, otherwise
255 * CR/LF are mangled...
257 _setmode(0, _O_BINARY);
258 #endif /* _WIN32 */
259 } else {
260 #ifndef _WIN32
261 if (ws_stat64(pipe_name, &pipe_stat) < 0) {
262 fprintf(stderr, "rawshark: The pipe %s could not be checked: %s\n",
263 pipe_name, g_strerror(errno));
264 return -1;
266 if (! S_ISFIFO(pipe_stat.st_mode)) {
267 if (S_ISCHR(pipe_stat.st_mode)) {
269 * Assume the user specified an interface on a system where
270 * interfaces are in /dev. Pretend we haven't seen it.
272 } else
274 fprintf(stderr, "rawshark: \"%s\" is neither an interface nor a pipe\n",
275 pipe_name);
277 return -1;
279 rfd = ws_open(pipe_name, O_RDONLY | O_NONBLOCK, 0000 /* no creation so don't matter */);
280 if (rfd == -1) {
281 fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
282 pipe_name, g_strerror(errno));
283 return -1;
285 #else /* _WIN32 */
286 if (!win32_is_pipe_name(pipe_name)) {
287 fprintf(stderr, "rawshark: \"%s\" is neither an interface nor a pipe\n",
288 pipe_name);
289 return -1;
292 /* Wait for the pipe to appear */
293 while (1) {
294 hPipe = CreateFile(utf_8to16(pipe_name), GENERIC_READ, 0, NULL,
295 OPEN_EXISTING, 0, NULL);
297 if (hPipe != INVALID_HANDLE_VALUE)
298 break;
300 err = GetLastError();
301 if (err != ERROR_PIPE_BUSY) {
302 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
303 NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
304 fprintf(stderr, "rawshark: \"%s\" could not be opened: %s (error %lu)\n",
305 pipe_name, utf_16to8(err_str), err);
306 LocalFree(err_str);
307 return -1;
310 if (!WaitNamedPipe(utf_8to16(pipe_name), 30 * 1000)) {
311 err = GetLastError();
312 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
313 NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
314 fprintf(stderr, "rawshark: \"%s\" could not be waited for: %s (error %lu)\n",
315 pipe_name, utf_16to8(err_str), err);
316 LocalFree(err_str);
317 return -1;
321 rfd = _open_osfhandle((intptr_t) hPipe, _O_RDONLY);
322 if (rfd == -1) {
323 fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
324 pipe_name, g_strerror(errno));
325 return -1;
327 #endif /* _WIN32 */
330 return rfd;
334 * Parse a link-type argument of the form "encap:<pcap linktype>" or
335 * "proto:<proto name>". "Pcap linktype" must be a name conforming to
336 * pcap_datalink_name_to_val() or an integer; the integer should be
337 * a LINKTYPE_ value supported by Wiretap. "Proto name" must be
338 * a protocol name, e.g. "http".
340 static bool
341 set_link_type(const char *lt_arg) {
342 char *spec_ptr = strchr(lt_arg, ':');
343 char *p;
344 int dlt_val;
345 long val;
346 dissector_handle_t dhandle;
347 GString *pref_str;
348 char *errmsg = NULL;
350 if (!spec_ptr)
351 return false;
353 spec_ptr++;
355 if (strncmp(lt_arg, "encap:", strlen("encap:")) == 0) {
356 dlt_val = linktype_name_to_val(spec_ptr);
357 if (dlt_val == -1) {
358 errno = 0;
359 val = strtol(spec_ptr, &p, 10);
360 if (p == spec_ptr || *p != '\0' || errno != 0 || val > INT_MAX) {
361 return false;
363 dlt_val = (int)val;
366 * In those cases where a given link-layer header type
367 * has different LINKTYPE_ and DLT_ values, linktype_name_to_val()
368 * will return the OS's DLT_ value for that link-layer header
369 * type, not its OS-independent LINKTYPE_ value.
371 * On a given OS, wtap_pcap_encap_to_wtap_encap() should
372 * be able to map either LINKTYPE_ values or DLT_ values
373 * for the OS to the appropriate Wiretap encapsulation.
375 encap = wtap_pcap_encap_to_wtap_encap(dlt_val);
376 if (encap == WTAP_ENCAP_UNKNOWN) {
377 return false;
379 return true;
380 } else if (strncmp(lt_arg, "proto:", strlen("proto:")) == 0) {
381 dhandle = find_dissector(spec_ptr);
382 if (dhandle) {
383 encap = WTAP_ENCAP_USER0;
384 pref_str = g_string_new("uat:user_dlts:");
385 /* This must match the format used in the user_dlts file */
386 g_string_append_printf(pref_str,
387 "\"User 0 (DLT=147)\",\"%s\",\"0\",\"\",\"0\",\"\"",
388 spec_ptr);
389 if (prefs_set_pref(pref_str->str, &errmsg) != PREFS_SET_OK) {
390 g_string_free(pref_str, TRUE);
391 g_free(errmsg);
392 return false;
394 g_string_free(pref_str, TRUE);
395 return true;
398 return false;
402 main(int argc, char *argv[])
404 char *err_msg;
405 int opt, i;
406 df_error_t *df_err;
408 #if !defined(_WIN32) && defined(RLIMIT_AS)
409 struct rlimit limit;
410 #endif /* !_WIN32 */
412 char *pipe_name = NULL;
413 char *rfilters[64];
414 e_prefs *prefs_p;
415 GPtrArray *disp_fields = g_ptr_array_new();
416 unsigned fc;
417 bool skip_pcap_header = false;
418 int ret = EXIT_SUCCESS;
419 static const struct ws_option long_options[] = {
420 {"help", ws_no_argument, NULL, 'h'},
421 {"version", ws_no_argument, NULL, 'v'},
422 LONGOPT_DISSECT_COMMON
423 LONGOPT_READ_CAPTURE_COMMON
424 {0, 0, 0, 0 }
427 #define OPTSTRING_INIT OPTSTRING_DISSECT_COMMON OPTSTRING_READ_CAPTURE_COMMON "F:hlm:o:psS:v"
429 static const char optstring[] = OPTSTRING_INIT;
431 /* Set the program name. */
432 g_set_prgname("rawshark");
435 * Set the C-language locale to the native environment and set the
436 * code page to UTF-8 on Windows.
438 #ifdef _WIN32
439 setlocale(LC_ALL, ".UTF-8");
440 #else
441 setlocale(LC_ALL, "");
442 #endif
444 cmdarg_err_init(stderr_cmdarg_err, stderr_cmdarg_err_cont);
446 /* Initialize log handler early so we can have proper logging during startup. */
447 ws_log_init(vcmdarg_err);
449 /* Early logging command-line initialization. */
450 ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION);
452 ws_noisy("Finished log init and parsing command line log arguments");
454 #ifdef _WIN32
455 create_app_running_mutex();
456 #endif /* _WIN32 */
459 * Get credential information for later use.
461 init_process_policies();
464 * Clear the filters arrays
466 memset(rfilters, 0, sizeof(rfilters));
467 memset(rfcodes, 0, sizeof(rfcodes));
468 n_rfilters = 0;
469 n_rfcodes = 0;
472 * Initialize our string format
474 string_fmts = g_ptr_array_new();
477 * Attempt to get the pathname of the directory containing the
478 * executable file.
480 err_msg = configuration_init(argv[0]);
481 if (err_msg != NULL) {
482 fprintf(stderr, "rawshark: Can't get pathname of rawshark program: %s.\n",
483 err_msg);
486 /* Initialize the version information. */
487 ws_init_version_info("Rawshark",
488 epan_gather_compile_info,
489 NULL);
491 init_report_failure_message("rawshark");
493 timestamp_set_type(TS_RELATIVE);
494 timestamp_set_precision(TS_PREC_AUTO);
495 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
498 * XXX - is this necessary, given that we're not reading a
499 * regular capture file, we're reading rawshark's packet
500 * stream format?
502 * If it is, note that libwiretap must be initialized before
503 * libwireshark is, so that dissection-time handlers for
504 * file-type-dependent blocks can register using the file
505 * type/subtype value for the file type.
507 wtap_init(false);
509 /* Register all dissectors; we must do this before checking for the
510 "-G" flag, as the "-G" flag dumps information registered by the
511 dissectors, and we must do it before we read the preferences, in
512 case any dissectors register preferences. */
513 if (!epan_init(NULL, NULL, true)) {
514 ret = WS_EXIT_INIT_FAILED;
515 goto clean_exit;
518 /* Load libwireshark settings from the current profile. */
519 prefs_p = epan_load_settings();
521 #ifdef _WIN32
522 ws_init_dll_search_path();
523 /* Load Wpcap, if possible */
524 load_wpcap();
525 #endif
527 cap_file_init(&cfile);
529 /* Print format defaults to this. */
530 print_format = PR_FMT_TEXT;
532 /* Initialize our encapsulation type */
533 encap = WTAP_ENCAP_UNKNOWN;
535 /* Now get our args */
536 /* XXX - We should probably have an option to dump libpcap link types */
537 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
538 switch (opt) {
539 case 'd': /* Payload type */
540 /* XXX: This option should probably be changed so it doesn't
541 * conflict with the common dissection option for Decode As.
543 if (!set_link_type(ws_optarg)) {
544 cmdarg_err("Invalid link type or protocol \"%s\"", ws_optarg);
545 ret = WS_EXIT_INVALID_OPTION;
546 goto clean_exit;
548 break;
549 case 'F': /* Read field to display */
550 g_ptr_array_add(disp_fields, g_strdup(ws_optarg));
551 break;
552 case 'h': /* Print help and exit */
553 show_help_header("Dump and analyze network traffic.");
554 print_usage(stdout);
555 goto clean_exit;
556 break;
557 case 'l': /* "Line-buffer" standard output */
558 /* This isn't line-buffering, strictly speaking, it's just
559 flushing the standard output after the information for
560 each packet is printed; however, that should be good
561 enough for all the purposes to which "-l" is put (and
562 is probably actually better for "-V", as it does fewer
563 writes).
565 See the comment in "process_packet()" for an explanation of
566 why we do that, and why we don't just use "setvbuf()" to
567 make the standard output line-buffered (short version: in
568 Windows, "line-buffered" is the same as "fully-buffered",
569 and the output buffer is only flushed when it fills up). */
570 line_buffered = true;
571 break;
572 #if !defined(_WIN32) && defined(RLIMIT_AS)
573 case 'm':
574 limit.rlim_cur = get_positive_int(ws_optarg, "memory limit");
575 limit.rlim_max = get_positive_int(ws_optarg, "memory limit");
577 if(setrlimit(RLIMIT_AS, &limit) != 0) {
578 cmdarg_err("setrlimit(RLIMIT_AS) failed: %s",
579 g_strerror(errno));
580 ret = WS_EXIT_INVALID_OPTION;
581 goto clean_exit;
583 break;
584 #endif
585 case 'o': /* Override preference from command line */
587 char *errmsg = NULL;
589 switch (prefs_set_pref(ws_optarg, &errmsg)) {
591 case PREFS_SET_OK:
592 break;
594 case PREFS_SET_SYNTAX_ERR:
595 cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
596 errmsg ? ": " : "", errmsg ? errmsg : "");
597 g_free(errmsg);
598 ret = WS_EXIT_INVALID_OPTION;
599 goto clean_exit;
600 break;
602 case PREFS_SET_NO_SUCH_PREF:
603 cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
604 ret = WS_EXIT_INVALID_OPTION;
605 goto clean_exit;
606 break;
608 case PREFS_SET_OBSOLETE:
609 cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
610 ret = WS_EXIT_INVALID_OPTION;
611 goto clean_exit;
612 break;
614 break;
616 case 'p': /* Expect pcap_pkthdr packet headers, which may have 64-bit timestamps */
617 want_pcap_pkthdr = true;
618 break;
619 case 'r': /* Read capture file xxx */
620 pipe_name = g_strdup(ws_optarg);
621 break;
622 case 'R': /* Read file filter */
623 case 'Y': /* Read file filter */
624 /* Read and display filters are the same for rawshark */
625 if(n_rfilters < (int)array_length(rfilters)) {
626 rfilters[n_rfilters++] = ws_optarg;
628 else {
629 cmdarg_err("Too many display filters");
630 ret = WS_EXIT_INVALID_OPTION;
631 goto clean_exit;
633 break;
634 case 's': /* Skip PCAP header */
635 skip_pcap_header = true;
636 break;
637 case 'S': /* Print string representations */
638 if (!parse_field_string_format(ws_optarg)) {
639 cmdarg_err("Invalid field string format");
640 ret = WS_EXIT_INVALID_OPTION;
641 goto clean_exit;
643 break;
644 case 'v': /* Show version and exit */
646 show_version();
647 goto clean_exit;
649 /* Common dissection options - 'd' for Decode As also makes
650 * sense, but rawshark uses it for the payload link layer/
651 * dissector selection.
653 case 'K': /* Kerberos keytab file */
654 case 'n': /* No name resolution */
655 case 'N': /* Select what types of addresses/port #s to resolve */
656 case 't': /* Time stamp type */
657 case 'u': /* Seconds type */
658 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
659 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
660 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
661 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
662 case LONGOPT_ONLY_PROTOCOLS: /* enable dissection of only this comma separated list of protocols */
663 case LONGOPT_DISABLE_ALL_PROTOCOLS: /* enable dissection of protocol (that is disabled by default) */
664 if (!dissect_opts_handle_opt(opt, ws_optarg)) {
665 ret = WS_EXIT_INVALID_OPTION;
666 goto clean_exit;
668 break;
669 default:
670 case '?': /* Bad flag - print usage message */
671 print_usage(stderr);
672 ret = WS_EXIT_INVALID_OPTION;
673 goto clean_exit;
677 /* Notify all registered modules that have had any of their preferences
678 changed either from one of the preferences file or from the command
679 line that their preferences have changed.
680 Initialize preferences before display filters, otherwise modules
681 like MATE won't work. */
682 prefs_apply_all();
684 /* Initialize our display fields */
685 for (fc = 0; fc < disp_fields->len; fc++) {
686 protocolinfo_init((char *)g_ptr_array_index(disp_fields, fc));
688 g_ptr_array_free(disp_fields, TRUE);
689 printf("\n");
690 fflush(stdout);
692 /* If no capture filter or read filter has been specified, and there are
693 still command-line arguments, treat them as the tokens of a capture
694 filter (if no "-r" flag was specified) or a read filter (if a "-r"
695 flag was specified. */
696 if (ws_optind < argc) {
697 if (pipe_name != NULL) {
698 if (n_rfilters != 0) {
699 cmdarg_err("Read filters were specified both with \"-R\" "
700 "and with additional command-line arguments");
701 ret = WS_EXIT_INVALID_OPTION;
702 goto clean_exit;
704 rfilters[n_rfilters] = get_args_as_string(argc, argv, ws_optind);
708 /* Make sure we got a dissector handle for our payload. */
709 if (encap == WTAP_ENCAP_UNKNOWN) {
710 cmdarg_err("No valid payload dissector specified.");
711 ret = WS_EXIT_INVALID_OPTION;
712 goto clean_exit;
715 err_msg = ws_init_sockets();
716 if (err_msg != NULL)
718 cmdarg_err("%s", err_msg);
719 g_free(err_msg);
720 cmdarg_err_cont("%s", please_report_bug());
721 ret = WS_EXIT_INIT_FAILED;
722 goto clean_exit;
725 if (global_dissect_options.time_format != TS_NOT_SET)
726 timestamp_set_type(global_dissect_options.time_format);
727 if (global_dissect_options.time_precision != TS_PREC_NOT_SET)
728 timestamp_set_precision(global_dissect_options.time_precision);
731 * Enabled and disabled protocols and heuristic dissectors as per
732 * command-line options.
734 if (!setup_enabled_and_disabled_protocols()) {
735 ret = WS_EXIT_INVALID_OPTION;
736 goto clean_exit;
739 /* Build the column format array */
740 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, true);
742 if (n_rfilters != 0) {
743 for (i = 0; i < n_rfilters; i++) {
744 if (!dfilter_compile(rfilters[i], &rfcodes[n_rfcodes], &df_err)) {
745 cmdarg_err("%s", df_err->msg);
746 df_error_free(&df_err);
747 ret = INVALID_DFILTER;
748 goto clean_exit;
750 n_rfcodes++;
754 if (pipe_name) {
756 * We're reading a pipe (or capture file).
760 * Immediately relinquish any special privileges we have; we must not
761 * be allowed to read any capture files the user running Rawshark
762 * can't open.
764 relinquish_special_privs_perm();
766 if (raw_cf_open(&cfile, pipe_name) != CF_OK) {
767 ret = WS_EXIT_OPEN_ERROR;
768 goto clean_exit;
771 /* Do we need to PCAP header and magic? */
772 if (skip_pcap_header) {
773 unsigned int bytes_left = (unsigned int) sizeof(struct pcap_hdr) + sizeof(uint32_t);
774 char buf[sizeof(struct pcap_hdr) + sizeof(uint32_t)];
775 while (bytes_left != 0) {
776 ssize_t bytes = ws_read(fd, buf, bytes_left);
777 if (bytes <= 0) {
778 cmdarg_err("Not enough bytes for pcap header.");
779 ret = FORMAT_ERROR;
780 goto clean_exit;
782 bytes_left -= (unsigned int)bytes;
786 /* Process the packets in the file */
787 if (!load_cap_file(&cfile)) {
788 ret = WS_EXIT_OPEN_ERROR;
789 goto clean_exit;
791 } else {
792 /* If you want to capture live packets, use TShark. */
793 cmdarg_err("Input file or pipe name not specified.");
794 ret = WS_EXIT_OPEN_ERROR;
795 goto clean_exit;
798 clean_exit:
799 g_free(pipe_name);
800 epan_free(cfile.epan);
801 epan_cleanup();
802 wtap_cleanup();
803 return ret;
807 * Read data from a raw pipe. The "raw" data consists of a libpcap
808 * packet header followed by the payload.
809 * @param buf [IN] A POSIX file descriptor. Because that's _exactly_ the sort
810 * of thing you want to use in Windows.
811 * @param err [OUT] Error indicator. Uses wiretap values.
812 * @param err_info [OUT] Error message.
813 * @param data_offset [OUT] data offset in the pipe.
814 * @return true on success, false on failure.
816 static bool
817 raw_pipe_read(wtap_rec *rec, Buffer *buf, int *err, char **err_info, int64_t *data_offset) {
818 struct pcap_pkthdr mem_hdr;
819 struct pcaprec_hdr disk_hdr;
820 ssize_t bytes_read = 0;
821 unsigned int bytes_needed = (unsigned int) sizeof(disk_hdr);
822 unsigned char *ptr = (unsigned char*) &disk_hdr;
824 *err = 0;
826 if (want_pcap_pkthdr) {
827 bytes_needed = sizeof(mem_hdr);
828 ptr = (unsigned char*) &mem_hdr;
832 * Newer versions of the VC runtime do parameter validation. If stdin
833 * has been closed, calls to _read, _get_osfhandle, et al will trigger
834 * the invalid parameter handler and crash.
835 * We could alternatively use ReadFile or set an invalid parameter
836 * handler.
837 * We could also tell callers not to close stdin prematurely.
839 #ifdef _WIN32
840 DWORD ghi_flags;
841 if (fd == 0 && GetHandleInformation(GetStdHandle(STD_INPUT_HANDLE), &ghi_flags) == 0) {
842 *err = 0;
843 *err_info = NULL;
844 return false;
846 #endif
848 /* Copied from capture_loop.c */
849 while (bytes_needed > 0) {
850 bytes_read = ws_read(fd, ptr, bytes_needed);
851 if (bytes_read == 0) {
852 *err = 0;
853 *err_info = NULL;
854 return false;
855 } else if (bytes_read < 0) {
856 *err = errno;
857 *err_info = NULL;
858 return false;
860 bytes_needed -= (unsigned int)bytes_read;
861 *data_offset += bytes_read;
862 ptr += bytes_read;
865 rec->rec_type = REC_TYPE_PACKET;
866 rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
867 if (want_pcap_pkthdr) {
868 rec->ts.secs = mem_hdr.ts.tv_sec;
869 rec->ts.nsecs = (int32_t)mem_hdr.ts.tv_usec * 1000;
870 rec->rec_header.packet_header.caplen = mem_hdr.caplen;
871 rec->rec_header.packet_header.len = mem_hdr.len;
872 } else {
873 rec->ts.secs = disk_hdr.ts_sec;
874 rec->ts.nsecs = disk_hdr.ts_usec * 1000;
875 rec->rec_header.packet_header.caplen = disk_hdr.incl_len;
876 rec->rec_header.packet_header.len = disk_hdr.orig_len;
878 bytes_needed = rec->rec_header.packet_header.caplen;
880 rec->rec_header.packet_header.pkt_encap = encap;
882 #if 0
883 printf("mem_hdr: %lu disk_hdr: %lu\n", sizeof(mem_hdr), sizeof(disk_hdr));
884 printf("tv_sec: %d (%04x)\n", (unsigned int) rec->ts.secs, (unsigned int) rec->ts.secs);
885 printf("tv_nsec: %d (%04x)\n", rec->ts.nsecs, rec->ts.nsecs);
886 printf("caplen: %d (%04x)\n", rec->rec_header.packet_header.caplen, rec->rec_header.packet_header.caplen);
887 printf("len: %d (%04x)\n", rec->rec_header.packet_header.len, rec->rec_header.packet_header.len);
888 #endif
889 if (bytes_needed > WTAP_MAX_PACKET_SIZE_STANDARD) {
890 *err = WTAP_ERR_BAD_FILE;
891 *err_info = ws_strdup_printf("Bad packet length: %lu",
892 (unsigned long) bytes_needed);
893 return false;
896 ws_buffer_assure_space(buf, bytes_needed);
897 ptr = ws_buffer_start_ptr(buf);
898 while (bytes_needed > 0) {
899 bytes_read = ws_read(fd, ptr, bytes_needed);
900 if (bytes_read == 0) {
901 *err = WTAP_ERR_SHORT_READ;
902 *err_info = NULL;
903 return false;
904 } else if (bytes_read < 0) {
905 *err = errno;
906 *err_info = NULL;
907 return false;
909 bytes_needed -= (unsigned int)bytes_read;
910 *data_offset += bytes_read;
911 ptr += bytes_read;
913 return true;
916 static bool
917 load_cap_file(capture_file *cf)
919 int err;
920 char *err_info = NULL;
921 int64_t data_offset = 0;
923 wtap_rec rec;
924 Buffer buf;
925 epan_dissect_t edt;
927 wtap_rec_init(&rec);
928 ws_buffer_init(&buf, 1514);
930 epan_dissect_init(&edt, cf->epan, true, false);
932 while (raw_pipe_read(&rec, &buf, &err, &err_info, &data_offset)) {
933 process_packet(cf, &edt, data_offset, &rec, &buf);
936 epan_dissect_cleanup(&edt);
938 wtap_rec_cleanup(&rec);
939 ws_buffer_free(&buf);
940 if (err != 0) {
941 /* Print a message noting that the read failed somewhere along the line. */
942 cfile_read_failure_message(cf->filename, err, err_info);
943 return false;
946 return true;
949 static bool
950 process_packet(capture_file *cf, epan_dissect_t *edt, int64_t offset,
951 wtap_rec *rec, Buffer *buf)
953 frame_data fdata;
954 bool passed;
955 int i;
957 if(rec->rec_header.packet_header.len == 0)
959 /* The user sends an empty packet when he wants to get output from us even if we don't currently have
960 packets to process. We spit out a line with the timestamp and the text "void"
962 printf("%lu %" PRIu64 " %d void -\n", (unsigned long int)cf->count,
963 (uint64_t)rec->ts.secs, rec->ts.nsecs);
965 fflush(stdout);
967 return false;
970 /* Count this packet. */
971 cf->count++;
973 /* If we're going to print packet information, or we're going to
974 run a read filter, or we're going to process taps, set up to
975 do a dissection and do so. */
976 frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
978 passed = true;
980 /* If we're running a read filter, prime the epan_dissect_t with that
981 filter. */
982 if (n_rfilters > 0) {
983 for(i = 0; i < n_rfcodes; i++) {
984 epan_dissect_prime_with_dfilter(edt, rfcodes[i]);
988 printf("%lu", (unsigned long int) cf->count);
990 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
991 &cf->provider.ref, cf->provider.prev_dis);
993 if (cf->provider.ref == &fdata) {
994 ref_frame = fdata;
995 cf->provider.ref = &ref_frame;
998 /* We only need the columns if we're printing packet info but we're
999 *not* verbose; in verbose mode, we print the protocol tree, not
1000 the protocol summary. */
1001 epan_dissect_run_with_taps(edt, cf->cd_t, rec,
1002 ws_buffer_start_ptr(buf),
1003 &fdata, &cf->cinfo);
1005 frame_data_set_after_dissect(&fdata, &cum_bytes);
1006 prev_dis_frame = fdata;
1007 cf->provider.prev_dis = &prev_dis_frame;
1009 prev_cap_frame = fdata;
1010 cf->provider.prev_cap = &prev_cap_frame;
1012 for(i = 0; i < n_rfilters; i++) {
1013 /* Run the read filter if we have one. */
1014 if (rfcodes[i])
1015 passed = dfilter_apply_edt(rfcodes[i], edt);
1016 else
1017 passed = true;
1019 /* Print a one-line summary */
1020 printf(" %d", passed ? 1 : 0);
1023 printf(" -\n");
1025 /* The ANSI C standard does not appear to *require* that a line-buffered
1026 stream be flushed to the host environment whenever a newline is
1027 written, it just says that, on such a stream, characters "are
1028 intended to be transmitted to or from the host environment as a
1029 block when a new-line character is encountered".
1031 The Visual C++ 6.0 C implementation doesn't do what is intended;
1032 even if you set a stream to be line-buffered, it still doesn't
1033 flush the buffer at the end of every line.
1035 So, if the "-l" flag was specified, we flush the standard output
1036 at the end of a packet. This will do the right thing if we're
1037 printing packet summary lines, and, as we print the entire protocol
1038 tree for a single packet without waiting for anything to happen,
1039 it should be as good as line-buffered mode if we're printing
1040 protocol trees. (The whole reason for the "-l" flag in either
1041 tcpdump or Rawshark is to allow the output of a live capture to
1042 be piped to a program or script and to have that script see the
1043 information for the packet as soon as it's printed, rather than
1044 having to wait until a standard I/O buffer fills up. */
1045 if (line_buffered)
1046 fflush(stdout);
1048 if (ferror(stdout)) {
1049 show_print_file_io_error(errno);
1050 exit(2);
1053 epan_dissect_reset(edt);
1054 frame_data_destroy(&fdata);
1056 return passed;
1059 /****************************************************************************************
1060 * FIELD EXTRACTION ROUTINES
1061 ****************************************************************************************/
1062 typedef struct _pci_t {
1063 char *filter;
1064 int hf_index;
1065 int cmd_line_index;
1066 } pci_t;
1068 static const char* ftenum_to_string(header_field_info *hfi)
1070 const char* str;
1071 if (!hfi) {
1072 return "n.a.";
1075 if (string_fmts->len > 0 && hfi->strings) {
1076 return "FT_STRING";
1079 str = ftype_name(hfi->type);
1080 if (str == NULL) {
1081 str = "n.a.";
1084 return str;
1087 static void field_display_to_string(header_field_info *hfi, char* buf, int size)
1089 if (hfi->type != FT_BOOLEAN)
1091 (void) g_strlcpy(buf, proto_field_display_to_string(hfi->display), size);
1093 else
1095 snprintf(buf, size, "(Bit count: %d)", hfi->display);
1100 * Copied from various parts of proto.c
1102 #define FIELD_STR_INIT_LEN 256
1103 #define cVALS(x) (const value_string*)(x)
1104 static bool print_field_value(field_info *finfo, int cmd_line_index)
1106 const header_field_info *hfinfo;
1107 char *fs_buf;
1108 char *fs_ptr = NULL;
1109 static GString *label_s = NULL;
1110 size_t fs_len;
1111 unsigned i;
1112 string_fmt_t *sf;
1113 uint32_t uvalue;
1114 int32_t svalue;
1115 uint64_t uvalue64;
1116 int64_t svalue64;
1118 hfinfo = finfo->hfinfo;
1120 if (!label_s) {
1121 label_s = g_string_new("");
1124 fs_buf = fvalue_to_string_repr(NULL, finfo->value,
1125 FTREPR_DFILTER, finfo->hfinfo->display);
1126 if (fs_buf != NULL) {
1128 * this field has an associated value,
1129 * e.g: ip.hdr_len
1131 fs_len = strlen(fs_buf);
1132 fs_ptr = fs_buf;
1134 /* String types are quoted. Remove them. */
1135 if (FT_IS_STRING(fvalue_type_ftenum(finfo->value)) && fs_len > 2) {
1136 fs_buf[fs_len - 1] = '\0';
1137 fs_ptr++;
1141 if (string_fmts->len > 0 && finfo->hfinfo->strings) {
1142 g_string_truncate(label_s, 0);
1143 for (i = 0; i < string_fmts->len; i++) {
1144 sf = (string_fmt_t *)g_ptr_array_index(string_fmts, i);
1145 if (sf->plain) {
1146 g_string_append(label_s, sf->plain);
1147 } else {
1148 switch (sf->format) {
1149 case SF_NAME:
1150 g_string_append(label_s, hfinfo->name);
1151 break;
1152 case SF_NUMVAL:
1153 g_string_append(label_s, fs_ptr);
1154 break;
1155 case SF_STRVAL:
1156 switch(hfinfo->type) {
1157 case FT_BOOLEAN:
1158 uvalue64 = fvalue_get_uinteger64(finfo->value);
1159 g_string_append(label_s, tfs_get_string(!!uvalue64, hfinfo->strings));
1160 break;
1161 case FT_INT8:
1162 case FT_INT16:
1163 case FT_INT24:
1164 case FT_INT32:
1165 DISSECTOR_ASSERT(!hfinfo->bitmask);
1166 svalue = fvalue_get_sinteger(finfo->value);
1167 if (hfinfo->display & BASE_RANGE_STRING) {
1168 g_string_append(label_s, rval_to_str_const(svalue, (const range_string *) hfinfo->strings, "Unknown"));
1169 } else if (hfinfo->display & BASE_EXT_STRING) {
1170 g_string_append(label_s, val_to_str_ext_const(svalue, (value_string_ext *) hfinfo->strings, "Unknown"));
1171 } else {
1172 g_string_append(label_s, val_to_str_const(svalue, cVALS(hfinfo->strings), "Unknown"));
1174 break;
1175 case FT_INT40: /* XXX: Shouldn't these be as smart as FT_INT{8,16,24,32}? */
1176 case FT_INT48:
1177 case FT_INT56:
1178 case FT_INT64:
1179 DISSECTOR_ASSERT(!hfinfo->bitmask);
1180 svalue64 = fvalue_get_sinteger64(finfo->value);
1181 if (hfinfo->display & BASE_VAL64_STRING) {
1182 g_string_append(label_s, val64_to_str_const(svalue64, (const val64_string *)(hfinfo->strings), "Unknown"));
1184 break;
1185 case FT_UINT8:
1186 case FT_UINT16:
1187 case FT_UINT24:
1188 case FT_UINT32:
1189 DISSECTOR_ASSERT(!hfinfo->bitmask);
1190 uvalue = fvalue_get_uinteger(finfo->value);
1191 if (!hfinfo->bitmask && hfinfo->display & BASE_RANGE_STRING) {
1192 g_string_append(label_s, rval_to_str_const(uvalue, (const range_string *) hfinfo->strings, "Unknown"));
1193 } else if (hfinfo->display & BASE_EXT_STRING) {
1194 g_string_append(label_s, val_to_str_ext_const(uvalue, (value_string_ext *) hfinfo->strings, "Unknown"));
1195 } else {
1196 g_string_append(label_s, val_to_str_const(uvalue, cVALS(hfinfo->strings), "Unknown"));
1198 break;
1199 case FT_UINT40: /* XXX: Shouldn't these be as smart as FT_INT{8,16,24,32}? */
1200 case FT_UINT48:
1201 case FT_UINT56:
1202 case FT_UINT64:
1203 DISSECTOR_ASSERT(!hfinfo->bitmask);
1204 uvalue64 = fvalue_get_uinteger64(finfo->value);
1205 if (hfinfo->display & BASE_VAL64_STRING) {
1206 g_string_append(label_s, val64_to_str_const(uvalue64, (const val64_string *)(hfinfo->strings), "Unknown"));
1208 break;
1209 default:
1210 break;
1212 break;
1213 default:
1214 break;
1218 printf(" %d=\"%s\"", cmd_line_index, label_s->str);
1219 wmem_free(NULL, fs_buf);
1220 return true;
1223 if(fs_buf)
1225 printf(" %d=\"%s\"", cmd_line_index, fs_ptr);
1226 wmem_free(NULL, fs_buf);
1227 return true;
1231 * This field doesn't have an associated value,
1232 * e.g. http
1233 * We return n.a.
1235 printf(" %d=\"n.a.\"", cmd_line_index);
1236 return true;
1239 static tap_packet_status
1240 protocolinfo_packet(void *prs, packet_info *pinfo _U_, epan_dissect_t *edt, const void *dummy _U_, tap_flags_t flags _U_)
1242 pci_t *rs=(pci_t *)prs;
1243 GPtrArray *gp;
1244 unsigned i;
1246 gp=proto_get_finfo_ptr_array(edt->tree, rs->hf_index);
1247 if(!gp){
1248 printf(" n.a.");
1249 return TAP_PACKET_DONT_REDRAW;
1253 * Print each occurrence of the field
1255 for (i = 0; i < gp->len; i++) {
1256 print_field_value((field_info *)gp->pdata[i], rs->cmd_line_index);
1259 return TAP_PACKET_DONT_REDRAW;
1262 int g_cmd_line_index;
1265 * field must be persistent - we don't g_strdup() it below
1267 static void
1268 protocolinfo_init(char *field)
1270 pci_t *rs;
1271 header_field_info *hfi;
1272 GString *error_string;
1273 char hfibuf[100];
1275 hfi=proto_registrar_get_byname(field);
1276 if(!hfi){
1277 fprintf(stderr, "rawshark: Field \"%s\" doesn't exist.\n", field);
1278 exit(1);
1281 field_display_to_string(hfi, hfibuf, sizeof(hfibuf));
1282 printf("%d %s %s - ",
1283 g_cmd_line_index,
1284 ftenum_to_string(hfi),
1285 hfibuf);
1287 rs=g_new(pci_t, 1);
1288 rs->hf_index=hfi->id;
1289 rs->filter=field;
1290 rs->cmd_line_index = g_cmd_line_index++;
1292 error_string=register_tap_listener("frame", rs, rs->filter, TL_REQUIRES_PROTO_TREE, NULL, protocolinfo_packet, NULL, NULL);
1293 if(error_string){
1294 /* error, we failed to attach to the tap. complain and clean up */
1295 fprintf(stderr, "rawshark: Couldn't register field extraction tap: %s\n",
1296 error_string->str);
1297 g_string_free(error_string, TRUE);
1298 if(rs->filter){
1299 g_free(rs->filter);
1301 g_free(rs);
1303 exit(1);
1308 * Given a format string, split it into a GPtrArray of string_fmt_t structs
1309 * and fill in string_fmt_parts.
1312 static void
1313 add_string_fmt(string_fmt_e format, char *plain) {
1314 string_fmt_t *sf = g_new(string_fmt_t, 1);
1316 sf->format = format;
1317 sf->plain = g_strdup(plain);
1319 g_ptr_array_add(string_fmts, sf);
1322 static bool
1323 parse_field_string_format(char *format) {
1324 size_t len;
1325 size_t pos = 0;
1327 if (!format) {
1328 return false;
1331 GString *plain_s = g_string_new("");
1333 len = strlen(format);
1334 g_ptr_array_set_size(string_fmts, 0);
1336 while (pos < len) {
1337 if (format[pos] == '%') {
1338 if (pos >= (len-1)) { /* There should always be a following specifier character */
1339 return false;
1341 pos++;
1342 if (plain_s->len > 0) {
1343 add_string_fmt(SF_NONE, plain_s->str);
1344 g_string_truncate(plain_s, 0);
1346 switch (format[pos]) {
1347 case 'D':
1348 add_string_fmt(SF_NAME, NULL);
1349 break;
1350 case 'N':
1351 add_string_fmt(SF_NUMVAL, NULL);
1352 break;
1353 case 'S':
1354 add_string_fmt(SF_STRVAL, NULL);
1355 break;
1356 case '%':
1357 g_string_append_c(plain_s, '%');
1358 break;
1359 default: /* Invalid format */
1360 return false;
1362 } else {
1363 g_string_append_c(plain_s, format[pos]);
1365 pos++;
1368 if (plain_s->len > 0) {
1369 add_string_fmt(SF_NONE, plain_s->str);
1371 g_string_free(plain_s, TRUE);
1373 return true;
1375 /****************************************************************************************
1376 * END OF FIELD EXTRACTION ROUTINES
1377 ****************************************************************************************/
1379 static void
1380 show_print_file_io_error(int err)
1382 switch (err) {
1384 case ENOSPC:
1385 cmdarg_err("Not all the packets could be printed because there is "
1386 "no space left on the file system.");
1387 break;
1389 #ifdef EDQUOT
1390 case EDQUOT:
1391 cmdarg_err("Not all the packets could be printed because you are "
1392 "too close to, or over your disk quota.");
1393 break;
1394 #endif
1396 default:
1397 cmdarg_err("An error occurred while printing packets: %s.",
1398 g_strerror(err));
1399 break;
1403 static epan_t *
1404 raw_epan_new(capture_file *cf)
1406 static const struct packet_provider_funcs funcs = {
1407 cap_file_provider_get_frame_ts,
1408 cap_file_provider_get_interface_name,
1409 cap_file_provider_get_interface_description,
1410 NULL,
1413 return epan_new(&cf->provider, &funcs);
1416 cf_status_t
1417 raw_cf_open(capture_file *cf, const char *fname)
1419 if ((fd = raw_pipe_open(fname)) < 0)
1420 return CF_ERROR;
1422 /* The open succeeded. Fill in the information for this file. */
1424 /* Create new epan session for dissection. */
1425 epan_free(cf->epan);
1426 cf->epan = raw_epan_new(cf);
1428 cf->provider.wth = NULL;
1429 cf->f_datalen = 0; /* not used, but set it anyway */
1431 /* Set the file name because we need it to set the follow stream filter.
1432 XXX - is that still true? We need it for other reasons, though,
1433 in any case. */
1434 cf->filename = g_strdup(fname);
1436 /* Indicate whether it's a permanent or temporary file. */
1437 cf->is_tempfile = false;
1439 /* No user changes yet. */
1440 cf->unsaved_changes = false;
1442 cf->cd_t = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
1443 cf->open_type = WTAP_TYPE_AUTO;
1444 cf->count = 0;
1445 cf->drops_known = false;
1446 cf->drops = 0;
1447 cf->snap = 0;
1448 nstime_set_zero(&cf->elapsed_time);
1449 cf->provider.ref = NULL;
1450 cf->provider.prev_dis = NULL;
1451 cf->provider.prev_cap = NULL;
1453 return CF_OK;
1457 * Editor modelines
1459 * Local Variables:
1460 * c-basic-offset: 4
1461 * tab-width: 8
1462 * indent-tabs-mode: nil
1463 * End:
1465 * ex: set shiftwidth=4 tabstop=8 expandtab:
1466 * :indentSize=4:tabSize=8:noTabs=true: