Revert "TODO: smb2: simplify preauth_hash calculation..."
[wireshark-sm.git] / rawshark.c
blob4eb94e550ccf01cdee42bc0fb45f7ebdbc1d1835
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 <wsutil/cmdarg_err.h>
46 #include <wsutil/filesystem.h>
47 #include <wsutil/file_util.h>
48 #include <wsutil/socket.h>
49 #include <wsutil/plugins.h>
50 #include <wsutil/privileges.h>
51 #include <wsutil/report_message.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 "frame_tvbuff.h"
66 #include <epan/disabled_protos.h>
67 #include <epan/prefs.h>
68 #include <epan/column.h>
69 #include <epan/print.h>
70 #include <epan/addr_resolv.h>
71 #ifdef HAVE_LIBPCAP
72 #include "ui/capture_ui_utils.h"
73 #endif
74 #include "ui/util.h"
75 #include "ui/dissect_opts.h"
76 #include "ui/failure_message.h"
77 #include <epan/epan_dissect.h>
78 #include <epan/stat_tap_ui.h>
79 #include <epan/timestamp.h>
80 #include "epan/column-utils.h"
81 #include "epan/proto.h"
82 #include <epan/tap.h>
84 #include <wiretap/wtap.h>
85 #include <wiretap/libpcap.h>
86 #include <wiretap/pcap-encap.h>
88 #include <cli_main.h>
89 #include <wsutil/version_info.h>
91 #include "capture/capture-pcap-util.h"
93 #ifdef HAVE_LIBPCAP
94 #include <setjmp.h>
95 #ifdef _WIN32
96 #include "capture/capture-wpcap.h"
97 #endif /* _WIN32 */
98 #endif /* HAVE_LIBPCAP */
100 #if 0
102 * This is the template for the decode as option; it is shared between the
103 * various functions that output the usage for this parameter.
105 static const gchar decode_as_arg_template[] = "<layer_type>==<selector>,<decode_as_protocol>";
106 #endif
108 /* Additional exit codes */
109 #define INVALID_DFILTER 2
110 #define FORMAT_ERROR 2
112 capture_file cfile;
114 static guint32 cum_bytes;
115 static frame_data ref_frame;
116 static frame_data prev_dis_frame;
117 static frame_data prev_cap_frame;
120 * The way the packet decode is to be written.
122 typedef enum {
123 WRITE_TEXT, /* summary or detail text */
124 WRITE_XML /* PDML or PSML */
125 /* Add CSV and the like here */
126 } output_action_e;
128 static gboolean line_buffered;
129 static print_format_e print_format = PR_FMT_TEXT;
131 static gboolean want_pcap_pkthdr;
133 cf_status_t raw_cf_open(capture_file *cf, const char *fname);
134 static gboolean load_cap_file(capture_file *cf);
135 static gboolean process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
136 wtap_rec *rec, Buffer *buf);
137 static void show_print_file_io_error(int err);
139 static void rawshark_cmdarg_err(const char *fmt, va_list ap);
140 static void rawshark_cmdarg_err_cont(const char *fmt, va_list ap);
141 static void protocolinfo_init(char *field);
142 static gboolean parse_field_string_format(char *format);
144 typedef enum {
145 SF_NONE, /* No format (placeholder) */
146 SF_NAME, /* %D Field name / description */
147 SF_NUMVAL, /* %N Numeric value */
148 SF_STRVAL /* %S String value */
149 } string_fmt_e;
151 typedef struct string_fmt_s {
152 gchar *plain;
153 string_fmt_e format; /* Valid if plain is NULL */
154 } string_fmt_t;
156 int n_rfilters;
157 int n_rfcodes;
158 dfilter_t *rfcodes[64];
159 int n_rfieldfilters;
160 dfilter_t *rfieldfcodes[64];
161 int fd;
162 int encap;
163 GPtrArray *string_fmts;
165 static void
166 print_usage(FILE *output)
168 fprintf(output, "\n");
169 fprintf(output, "Usage: rawshark [options] ...\n");
170 fprintf(output, "\n");
172 fprintf(output, "Input file:\n");
173 fprintf(output, " -r <infile>, --read-file <infile>\n");
174 fprintf(output," set the pipe or file name to read from\n");
176 fprintf(output, "\n");
177 fprintf(output, "Processing:\n");
178 fprintf(output, " -d <encap:linktype>|<proto:protoname>\n");
179 fprintf(output, " packet encapsulation or protocol\n");
180 fprintf(output, " -F <field> field to display\n");
181 #if !defined(_WIN32) && defined(RLIMIT_AS)
182 fprintf(output, " -m virtual memory limit, in bytes\n");
183 #endif
184 fprintf(output, " -n disable all name resolutions (def: \"mNd\" enabled, or\n");
185 fprintf(output, " as set in preferences)\n");
186 fprintf(output, " -N <name resolve flags> enable specific name resolution(s): \"mnNtdv\"\n");
187 fprintf(output, " -p use the system's packet header format\n");
188 fprintf(output, " (which may have 64-bit timestamps)\n");
189 fprintf(output, " -R <read filter>, --read-filter <read filter>\n");
190 fprintf(output, " packet filter in Wireshark display filter syntax\n");
191 fprintf(output, " -s skip PCAP header on input\n");
192 fprintf(output, " -Y <display filter>, --display-filter <display filter>\n");
193 fprintf(output, " packet filter in Wireshark display filter syntax\n");
194 fprintf(output, " --enable-protocol <proto_name>\n");
195 fprintf(output, " enable dissection of proto_name\n");
196 fprintf(output, " --disable-protocol <proto_name>\n");
197 fprintf(output, " disable dissection of proto_name\n");
198 fprintf(output, " --only-protocols <protocols>\n");
199 fprintf(output, " Only enable dissection of these protocols, comma\n");
200 fprintf(output, " separated. Disable everything else\n");
201 fprintf(output, " --disable-all-protocols\n");
202 fprintf(output, " Disable dissection of all protocols\n");
203 fprintf(output, " --enable-heuristic <short_name>\n");
204 fprintf(output, " enable dissection of heuristic protocol\n");
205 fprintf(output, " --disable-heuristic <short_name>\n");
206 fprintf(output, " disable dissection of heuristic protocol\n");
208 fprintf(output, "\n");
209 fprintf(output, "Output:\n");
210 fprintf(output, " -l flush output after each packet\n");
211 fprintf(output, " -S format string for fields\n");
212 fprintf(output, " (%%D - name, %%S - stringval, %%N numval)\n");
213 fprintf(output, " -t (a|ad|adoy|d|dd|e|r|u|ud|udoy)[.[N]]|.[N]\n");
214 fprintf(output, " output format of time stamps (def: r: rel. to first)\n");
215 fprintf(output, " -u s|hms output format of seconds (def: s: seconds)\n");
216 fprintf(output, "\n");
218 ws_log_print_usage(output);
219 fprintf(output, "\n");
221 fprintf(output, "\n");
222 fprintf(output, "Miscellaneous:\n");
223 fprintf(output, " -h, --help display this help and exit\n");
224 fprintf(output, " -v, --version display version info and exit\n");
225 fprintf(output, " -o <name>:<value> ... override preference setting\n");
226 fprintf(output, " -K <keytab> keytab file to use for kerberos decryption\n");
230 * Open a pipe for raw input. This is a stripped-down version of
231 * pcap_loop.c:cap_pipe_open_live().
232 * We check if "pipe_name" is "-" (stdin) or a FIFO, and open it.
233 * @param pipe_name The name of the pipe or FIFO.
234 * @return A POSIX file descriptor on success, or -1 on failure.
236 static int
237 raw_pipe_open(const char *pipe_name)
239 #ifndef _WIN32
240 ws_statb64 pipe_stat;
241 #else
242 DWORD err;
243 wchar_t *err_str;
244 HANDLE hPipe = NULL;
245 #endif
246 int rfd;
248 ws_log(LOG_DOMAIN_CAPCHILD, LOG_LEVEL_DEBUG, "open_raw_pipe: %s", pipe_name);
251 * XXX Rawshark blocks until we return
253 if (strcmp(pipe_name, "-") == 0) {
254 rfd = 0; /* read from stdin */
255 #ifdef _WIN32
257 * This is needed to set the stdin pipe into binary mode, otherwise
258 * CR/LF are mangled...
260 _setmode(0, _O_BINARY);
261 #endif /* _WIN32 */
262 } else {
263 #ifndef _WIN32
264 if (ws_stat64(pipe_name, &pipe_stat) < 0) {
265 fprintf(stderr, "rawshark: The pipe %s could not be checked: %s\n",
266 pipe_name, g_strerror(errno));
267 return -1;
269 if (! S_ISFIFO(pipe_stat.st_mode)) {
270 if (S_ISCHR(pipe_stat.st_mode)) {
272 * Assume the user specified an interface on a system where
273 * interfaces are in /dev. Pretend we haven't seen it.
275 } else
277 fprintf(stderr, "rawshark: \"%s\" is neither an interface nor a pipe\n",
278 pipe_name);
280 return -1;
282 rfd = ws_open(pipe_name, O_RDONLY | O_NONBLOCK, 0000 /* no creation so don't matter */);
283 if (rfd == -1) {
284 fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
285 pipe_name, g_strerror(errno));
286 return -1;
288 #else /* _WIN32 */
289 if (!win32_is_pipe_name(pipe_name)) {
290 fprintf(stderr, "rawshark: \"%s\" is neither an interface nor a pipe\n",
291 pipe_name);
292 return -1;
295 /* Wait for the pipe to appear */
296 while (1) {
297 hPipe = CreateFile(utf_8to16(pipe_name), GENERIC_READ, 0, NULL,
298 OPEN_EXISTING, 0, NULL);
300 if (hPipe != INVALID_HANDLE_VALUE)
301 break;
303 err = GetLastError();
304 if (err != ERROR_PIPE_BUSY) {
305 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
306 NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
307 fprintf(stderr, "rawshark: \"%s\" could not be opened: %s (error %lu)\n",
308 pipe_name, utf_16to8(err_str), err);
309 LocalFree(err_str);
310 return -1;
313 if (!WaitNamedPipe(utf_8to16(pipe_name), 30 * 1000)) {
314 err = GetLastError();
315 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
316 NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
317 fprintf(stderr, "rawshark: \"%s\" could not be waited for: %s (error %lu)\n",
318 pipe_name, utf_16to8(err_str), err);
319 LocalFree(err_str);
320 return -1;
324 rfd = _open_osfhandle((intptr_t) hPipe, _O_RDONLY);
325 if (rfd == -1) {
326 fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
327 pipe_name, g_strerror(errno));
328 return -1;
330 #endif /* _WIN32 */
333 return rfd;
337 * Parse a link-type argument of the form "encap:<pcap linktype>" or
338 * "proto:<proto name>". "Pcap linktype" must be a name conforming to
339 * pcap_datalink_name_to_val() or an integer; the integer should be
340 * a LINKTYPE_ value supported by Wiretap. "Proto name" must be
341 * a protocol name, e.g. "http".
343 static gboolean
344 set_link_type(const char *lt_arg) {
345 char *spec_ptr = strchr(lt_arg, ':');
346 char *p;
347 int dlt_val;
348 long val;
349 dissector_handle_t dhandle;
350 GString *pref_str;
351 char *errmsg = NULL;
353 if (!spec_ptr)
354 return FALSE;
356 spec_ptr++;
358 if (strncmp(lt_arg, "encap:", strlen("encap:")) == 0) {
359 dlt_val = linktype_name_to_val(spec_ptr);
360 if (dlt_val == -1) {
361 errno = 0;
362 val = strtol(spec_ptr, &p, 10);
363 if (p == spec_ptr || *p != '\0' || errno != 0 || val > INT_MAX) {
364 return FALSE;
366 dlt_val = (int)val;
369 * In those cases where a given link-layer header type
370 * has different LINKTYPE_ and DLT_ values, linktype_name_to_val()
371 * will return the OS's DLT_ value for that link-layer header
372 * type, not its OS-independent LINKTYPE_ value.
374 * On a given OS, wtap_pcap_encap_to_wtap_encap() should
375 * be able to map either LINKTYPE_ values or DLT_ values
376 * for the OS to the appropriate Wiretap encapsulation.
378 encap = wtap_pcap_encap_to_wtap_encap(dlt_val);
379 if (encap == WTAP_ENCAP_UNKNOWN) {
380 return FALSE;
382 return TRUE;
383 } else if (strncmp(lt_arg, "proto:", strlen("proto:")) == 0) {
384 dhandle = find_dissector(spec_ptr);
385 if (dhandle) {
386 encap = WTAP_ENCAP_USER0;
387 pref_str = g_string_new("uat:user_dlts:");
388 /* This must match the format used in the user_dlts file */
389 g_string_append_printf(pref_str,
390 "\"User 0 (DLT=147)\",\"%s\",\"0\",\"\",\"0\",\"\"",
391 spec_ptr);
392 if (prefs_set_pref(pref_str->str, &errmsg) != PREFS_SET_OK) {
393 g_string_free(pref_str, TRUE);
394 g_free(errmsg);
395 return FALSE;
397 g_string_free(pref_str, TRUE);
398 return TRUE;
401 return FALSE;
405 main(int argc, char *argv[])
407 char *err_msg;
408 int opt, i;
409 df_error_t *df_err;
411 #if !defined(_WIN32) && defined(RLIMIT_AS)
412 struct rlimit limit;
413 #endif /* !_WIN32 */
415 gchar *pipe_name = NULL;
416 gchar *rfilters[64];
417 e_prefs *prefs_p;
418 GPtrArray *disp_fields = g_ptr_array_new();
419 guint fc;
420 gboolean skip_pcap_header = FALSE;
421 int ret = EXIT_SUCCESS;
422 static const struct ws_option long_options[] = {
423 {"help", ws_no_argument, NULL, 'h'},
424 {"version", ws_no_argument, NULL, 'v'},
425 LONGOPT_DISSECT_COMMON
426 LONGOPT_READ_CAPTURE_COMMON
427 {0, 0, 0, 0 }
430 #define OPTSTRING_INIT OPTSTRING_DISSECT_COMMON OPTSTRING_READ_CAPTURE_COMMON "F:hlm:o:psS:v"
432 static const char optstring[] = OPTSTRING_INIT;
433 static const struct report_message_routines rawshark_report_routines = {
434 failure_message,
435 failure_message,
436 open_failure_message,
437 read_failure_message,
438 write_failure_message,
439 cfile_open_failure_message,
440 cfile_dump_open_failure_message,
441 cfile_read_failure_message,
442 cfile_write_failure_message,
443 cfile_close_failure_message
447 * Set the C-language locale to the native environment and set the
448 * code page to UTF-8 on Windows.
450 #ifdef _WIN32
451 setlocale(LC_ALL, ".UTF-8");
452 #else
453 setlocale(LC_ALL, "");
454 #endif
456 cmdarg_err_init(rawshark_cmdarg_err, rawshark_cmdarg_err_cont);
458 /* Initialize log handler early so we can have proper logging during startup. */
459 ws_log_init("rawshark", vcmdarg_err);
461 /* Early logging command-line initialization. */
462 ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION);
464 ws_noisy("Finished log init and parsing command line log arguments");
466 /* Initialize the version information. */
467 ws_init_version_info("Rawshark",
468 epan_gather_compile_info,
469 NULL);
471 #ifdef _WIN32
472 create_app_running_mutex();
473 #endif /* _WIN32 */
476 * Get credential information for later use.
478 init_process_policies();
481 * Clear the filters arrays
483 memset(rfilters, 0, sizeof(rfilters));
484 memset(rfcodes, 0, sizeof(rfcodes));
485 n_rfilters = 0;
486 n_rfcodes = 0;
489 * Initialize our string format
491 string_fmts = g_ptr_array_new();
494 * Attempt to get the pathname of the directory containing the
495 * executable file.
497 err_msg = configuration_init(argv[0], NULL);
498 if (err_msg != NULL) {
499 fprintf(stderr, "rawshark: Can't get pathname of rawshark program: %s.\n",
500 err_msg);
503 init_report_message("rawshark", &rawshark_report_routines);
505 timestamp_set_type(TS_RELATIVE);
506 timestamp_set_precision(TS_PREC_AUTO);
507 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
510 * XXX - is this necessary, given that we're not reading a
511 * regular capture file, we're reading rawshark's packet
512 * stream format?
514 * If it is, note that libwiretap must be initialized before
515 * libwireshark is, so that dissection-time handlers for
516 * file-type-dependent blocks can register using the file
517 * type/subtype value for the file type.
519 wtap_init(FALSE);
521 /* Register all dissectors; we must do this before checking for the
522 "-G" flag, as the "-G" flag dumps information registered by the
523 dissectors, and we must do it before we read the preferences, in
524 case any dissectors register preferences. */
525 if (!epan_init(NULL, NULL, TRUE)) {
526 ret = WS_EXIT_INIT_FAILED;
527 goto clean_exit;
530 /* Load libwireshark settings from the current profile. */
531 prefs_p = epan_load_settings();
533 #ifdef _WIN32
534 ws_init_dll_search_path();
535 /* Load Wpcap, if possible */
536 load_wpcap();
537 #endif
539 cap_file_init(&cfile);
541 /* Print format defaults to this. */
542 print_format = PR_FMT_TEXT;
544 /* Initialize our encapsulation type */
545 encap = WTAP_ENCAP_UNKNOWN;
547 /* Now get our args */
548 /* XXX - We should probably have an option to dump libpcap link types */
549 while ((opt = ws_getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
550 switch (opt) {
551 case 'd': /* Payload type */
552 /* XXX: This option should probably be changed so it doesn't
553 * conflict with the common dissection option for Decode As.
555 if (!set_link_type(ws_optarg)) {
556 cmdarg_err("Invalid link type or protocol \"%s\"", ws_optarg);
557 ret = WS_EXIT_INVALID_OPTION;
558 goto clean_exit;
560 break;
561 case 'F': /* Read field to display */
562 g_ptr_array_add(disp_fields, g_strdup(ws_optarg));
563 break;
564 case 'h': /* Print help and exit */
565 show_help_header("Dump and analyze network traffic.");
566 print_usage(stdout);
567 goto clean_exit;
568 break;
569 case 'l': /* "Line-buffer" standard output */
570 /* This isn't line-buffering, strictly speaking, it's just
571 flushing the standard output after the information for
572 each packet is printed; however, that should be good
573 enough for all the purposes to which "-l" is put (and
574 is probably actually better for "-V", as it does fewer
575 writes).
577 See the comment in "process_packet()" for an explanation of
578 why we do that, and why we don't just use "setvbuf()" to
579 make the standard output line-buffered (short version: in
580 Windows, "line-buffered" is the same as "fully-buffered",
581 and the output buffer is only flushed when it fills up). */
582 line_buffered = TRUE;
583 break;
584 #if !defined(_WIN32) && defined(RLIMIT_AS)
585 case 'm':
586 limit.rlim_cur = get_positive_int(ws_optarg, "memory limit");
587 limit.rlim_max = get_positive_int(ws_optarg, "memory limit");
589 if(setrlimit(RLIMIT_AS, &limit) != 0) {
590 cmdarg_err("setrlimit(RLIMIT_AS) failed: %s",
591 g_strerror(errno));
592 ret = WS_EXIT_INVALID_OPTION;
593 goto clean_exit;
595 break;
596 #endif
597 case 'o': /* Override preference from command line */
599 char *errmsg = NULL;
601 switch (prefs_set_pref(ws_optarg, &errmsg)) {
603 case PREFS_SET_OK:
604 break;
606 case PREFS_SET_SYNTAX_ERR:
607 cmdarg_err("Invalid -o flag \"%s\"%s%s", ws_optarg,
608 errmsg ? ": " : "", errmsg ? errmsg : "");
609 g_free(errmsg);
610 ret = WS_EXIT_INVALID_OPTION;
611 goto clean_exit;
612 break;
614 case PREFS_SET_NO_SUCH_PREF:
615 cmdarg_err("-o flag \"%s\" specifies unknown preference", ws_optarg);
616 ret = WS_EXIT_INVALID_OPTION;
617 goto clean_exit;
618 break;
620 case PREFS_SET_OBSOLETE:
621 cmdarg_err("-o flag \"%s\" specifies obsolete preference", ws_optarg);
622 ret = WS_EXIT_INVALID_OPTION;
623 goto clean_exit;
624 break;
626 break;
628 case 'p': /* Expect pcap_pkthdr packet headers, which may have 64-bit timestamps */
629 want_pcap_pkthdr = TRUE;
630 break;
631 case 'r': /* Read capture file xxx */
632 pipe_name = g_strdup(ws_optarg);
633 break;
634 case 'R': /* Read file filter */
635 case 'Y': /* Read file filter */
636 /* Read and display filters are the same for rawshark */
637 if(n_rfilters < (int) sizeof(rfilters) / (int) sizeof(rfilters[0])) {
638 rfilters[n_rfilters++] = ws_optarg;
640 else {
641 cmdarg_err("Too many display filters");
642 ret = WS_EXIT_INVALID_OPTION;
643 goto clean_exit;
645 break;
646 case 's': /* Skip PCAP header */
647 skip_pcap_header = TRUE;
648 break;
649 case 'S': /* Print string representations */
650 if (!parse_field_string_format(ws_optarg)) {
651 cmdarg_err("Invalid field string format");
652 ret = WS_EXIT_INVALID_OPTION;
653 goto clean_exit;
655 break;
656 case 'v': /* Show version and exit */
658 show_version();
659 goto clean_exit;
661 /* Common dissection options - 'd' for Decode As also makes
662 * sense, but rawshark uses it for the payload link layer/
663 * dissector selection.
665 case 'K': /* Kerberos keytab file */
666 case 'n': /* No name resolution */
667 case 'N': /* Select what types of addresses/port #s to resolve */
668 case 't': /* Time stamp type */
669 case 'u': /* Seconds type */
670 case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
671 case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
672 case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
673 case LONGOPT_ENABLE_PROTOCOL: /* enable dissection of protocol (that is disabled by default) */
674 case LONGOPT_ONLY_PROTOCOLS: /* enable dissection of only this comma separated list of protocols */
675 case LONGOPT_DISABLE_ALL_PROTOCOLS: /* enable dissection of protocol (that is disabled by default) */
676 if (!dissect_opts_handle_opt(opt, ws_optarg)) {
677 ret = WS_EXIT_INVALID_OPTION;
678 goto clean_exit;
680 break;
681 default:
682 case '?': /* Bad flag - print usage message */
683 print_usage(stderr);
684 ret = WS_EXIT_INVALID_OPTION;
685 goto clean_exit;
689 /* Notify all registered modules that have had any of their preferences
690 changed either from one of the preferences file or from the command
691 line that their preferences have changed.
692 Initialize preferences before display filters, otherwise modules
693 like MATE won't work. */
694 prefs_apply_all();
696 /* Initialize our display fields */
697 for (fc = 0; fc < disp_fields->len; fc++) {
698 protocolinfo_init((char *)g_ptr_array_index(disp_fields, fc));
700 g_ptr_array_free(disp_fields, TRUE);
701 printf("\n");
702 fflush(stdout);
704 /* If no capture filter or read filter has been specified, and there are
705 still command-line arguments, treat them as the tokens of a capture
706 filter (if no "-r" flag was specified) or a read filter (if a "-r"
707 flag was specified. */
708 if (ws_optind < argc) {
709 if (pipe_name != NULL) {
710 if (n_rfilters != 0) {
711 cmdarg_err("Read filters were specified both with \"-R\" "
712 "and with additional command-line arguments");
713 ret = WS_EXIT_INVALID_OPTION;
714 goto clean_exit;
716 rfilters[n_rfilters] = get_args_as_string(argc, argv, ws_optind);
720 /* Make sure we got a dissector handle for our payload. */
721 if (encap == WTAP_ENCAP_UNKNOWN) {
722 cmdarg_err("No valid payload dissector specified.");
723 ret = WS_EXIT_INVALID_OPTION;
724 goto clean_exit;
727 err_msg = ws_init_sockets();
728 if (err_msg != NULL)
730 cmdarg_err("%s", err_msg);
731 g_free(err_msg);
732 cmdarg_err_cont("%s", please_report_bug());
733 ret = WS_EXIT_INIT_FAILED;
734 goto clean_exit;
737 if (global_dissect_options.time_format != TS_NOT_SET)
738 timestamp_set_type(global_dissect_options.time_format);
739 if (global_dissect_options.time_precision != TS_PREC_NOT_SET)
740 timestamp_set_precision(global_dissect_options.time_precision);
743 * Enabled and disabled protocols and heuristic dissectors as per
744 * command-line options.
746 if (!setup_enabled_and_disabled_protocols()) {
747 ret = WS_EXIT_INVALID_OPTION;
748 goto clean_exit;
751 /* Build the column format array */
752 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
754 if (n_rfilters != 0) {
755 for (i = 0; i < n_rfilters; i++) {
756 if (!dfilter_compile(rfilters[i], &rfcodes[n_rfcodes], &df_err)) {
757 cmdarg_err("%s", df_err->msg);
758 df_error_free(&df_err);
759 ret = INVALID_DFILTER;
760 goto clean_exit;
762 n_rfcodes++;
766 if (pipe_name) {
768 * We're reading a pipe (or capture file).
772 * Immediately relinquish any special privileges we have; we must not
773 * be allowed to read any capture files the user running Rawshark
774 * can't open.
776 relinquish_special_privs_perm();
778 if (raw_cf_open(&cfile, pipe_name) != CF_OK) {
779 ret = WS_EXIT_OPEN_ERROR;
780 goto clean_exit;
783 /* Do we need to PCAP header and magic? */
784 if (skip_pcap_header) {
785 unsigned int bytes_left = (unsigned int) sizeof(struct pcap_hdr) + sizeof(guint32);
786 gchar buf[sizeof(struct pcap_hdr) + sizeof(guint32)];
787 while (bytes_left != 0) {
788 ssize_t bytes = ws_read(fd, buf, bytes_left);
789 if (bytes <= 0) {
790 cmdarg_err("Not enough bytes for pcap header.");
791 ret = FORMAT_ERROR;
792 goto clean_exit;
794 bytes_left -= (unsigned int)bytes;
798 /* Process the packets in the file */
799 if (!load_cap_file(&cfile)) {
800 ret = WS_EXIT_OPEN_ERROR;
801 goto clean_exit;
803 } else {
804 /* If you want to capture live packets, use TShark. */
805 cmdarg_err("Input file or pipe name not specified.");
806 ret = WS_EXIT_OPEN_ERROR;
807 goto clean_exit;
810 clean_exit:
811 g_free(pipe_name);
812 epan_free(cfile.epan);
813 epan_cleanup();
814 wtap_cleanup();
815 return ret;
819 * Read data from a raw pipe. The "raw" data consists of a libpcap
820 * packet header followed by the payload.
821 * @param buf [IN] A POSIX file descriptor. Because that's _exactly_ the sort
822 * of thing you want to use in Windows.
823 * @param err [OUT] Error indicator. Uses wiretap values.
824 * @param err_info [OUT] Error message.
825 * @param data_offset [OUT] data offset in the pipe.
826 * @return TRUE on success, FALSE on failure.
828 static gboolean
829 raw_pipe_read(wtap_rec *rec, Buffer *buf, int *err, gchar **err_info, gint64 *data_offset) {
830 struct pcap_pkthdr mem_hdr;
831 struct pcaprec_hdr disk_hdr;
832 ssize_t bytes_read = 0;
833 unsigned int bytes_needed = (unsigned int) sizeof(disk_hdr);
834 guchar *ptr = (guchar*) &disk_hdr;
836 *err = 0;
838 if (want_pcap_pkthdr) {
839 bytes_needed = sizeof(mem_hdr);
840 ptr = (guchar*) &mem_hdr;
844 * Newer versions of the VC runtime do parameter validation. If stdin
845 * has been closed, calls to _read, _get_osfhandle, et al will trigger
846 * the invalid parameter handler and crash.
847 * We could alternatively use ReadFile or set an invalid parameter
848 * handler.
849 * We could also tell callers not to close stdin prematurely.
851 #ifdef _WIN32
852 DWORD ghi_flags;
853 if (fd == 0 && GetHandleInformation(GetStdHandle(STD_INPUT_HANDLE), &ghi_flags) == 0) {
854 *err = 0;
855 *err_info = NULL;
856 return FALSE;
858 #endif
860 /* Copied from capture_loop.c */
861 while (bytes_needed > 0) {
862 bytes_read = ws_read(fd, ptr, bytes_needed);
863 if (bytes_read == 0) {
864 *err = 0;
865 *err_info = NULL;
866 return FALSE;
867 } else if (bytes_read < 0) {
868 *err = errno;
869 *err_info = NULL;
870 return FALSE;
872 bytes_needed -= (unsigned int)bytes_read;
873 *data_offset += bytes_read;
874 ptr += bytes_read;
877 rec->rec_type = REC_TYPE_PACKET;
878 rec->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
879 if (want_pcap_pkthdr) {
880 rec->ts.secs = mem_hdr.ts.tv_sec;
881 rec->ts.nsecs = (gint32)mem_hdr.ts.tv_usec * 1000;
882 rec->rec_header.packet_header.caplen = mem_hdr.caplen;
883 rec->rec_header.packet_header.len = mem_hdr.len;
884 } else {
885 rec->ts.secs = disk_hdr.ts_sec;
886 rec->ts.nsecs = disk_hdr.ts_usec * 1000;
887 rec->rec_header.packet_header.caplen = disk_hdr.incl_len;
888 rec->rec_header.packet_header.len = disk_hdr.orig_len;
890 bytes_needed = rec->rec_header.packet_header.caplen;
892 rec->rec_header.packet_header.pkt_encap = encap;
894 #if 0
895 printf("mem_hdr: %lu disk_hdr: %lu\n", sizeof(mem_hdr), sizeof(disk_hdr));
896 printf("tv_sec: %d (%04x)\n", (unsigned int) rec->ts.secs, (unsigned int) rec->ts.secs);
897 printf("tv_nsec: %d (%04x)\n", rec->ts.nsecs, rec->ts.nsecs);
898 printf("caplen: %d (%04x)\n", rec->rec_header.packet_header.caplen, rec->rec_header.packet_header.caplen);
899 printf("len: %d (%04x)\n", rec->rec_header.packet_header.len, rec->rec_header.packet_header.len);
900 #endif
901 if (bytes_needed > WTAP_MAX_PACKET_SIZE_STANDARD) {
902 *err = WTAP_ERR_BAD_FILE;
903 *err_info = ws_strdup_printf("Bad packet length: %lu",
904 (unsigned long) bytes_needed);
905 return FALSE;
908 ws_buffer_assure_space(buf, bytes_needed);
909 ptr = ws_buffer_start_ptr(buf);
910 while (bytes_needed > 0) {
911 bytes_read = ws_read(fd, ptr, bytes_needed);
912 if (bytes_read == 0) {
913 *err = WTAP_ERR_SHORT_READ;
914 *err_info = NULL;
915 return FALSE;
916 } else if (bytes_read < 0) {
917 *err = errno;
918 *err_info = NULL;
919 return FALSE;
921 bytes_needed -= (unsigned int)bytes_read;
922 *data_offset += bytes_read;
923 ptr += bytes_read;
925 return TRUE;
928 static gboolean
929 load_cap_file(capture_file *cf)
931 int err;
932 gchar *err_info = NULL;
933 gint64 data_offset = 0;
935 wtap_rec rec;
936 Buffer buf;
937 epan_dissect_t edt;
939 wtap_rec_init(&rec);
940 ws_buffer_init(&buf, 1514);
942 epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
944 while (raw_pipe_read(&rec, &buf, &err, &err_info, &data_offset)) {
945 process_packet(cf, &edt, data_offset, &rec, &buf);
948 epan_dissect_cleanup(&edt);
950 wtap_rec_cleanup(&rec);
951 ws_buffer_free(&buf);
952 if (err != 0) {
953 /* Print a message noting that the read failed somewhere along the line. */
954 cfile_read_failure_message(cf->filename, err, err_info);
955 return FALSE;
958 return TRUE;
961 static gboolean
962 process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
963 wtap_rec *rec, Buffer *buf)
965 frame_data fdata;
966 gboolean passed;
967 int i;
969 if(rec->rec_header.packet_header.len == 0)
971 /* The user sends an empty packet when he wants to get output from us even if we don't currently have
972 packets to process. We spit out a line with the timestamp and the text "void"
974 printf("%lu %" PRIu64 " %d void -\n", (unsigned long int)cf->count,
975 (guint64)rec->ts.secs, rec->ts.nsecs);
977 fflush(stdout);
979 return FALSE;
982 /* Count this packet. */
983 cf->count++;
985 /* If we're going to print packet information, or we're going to
986 run a read filter, or we're going to process taps, set up to
987 do a dissection and do so. */
988 frame_data_init(&fdata, cf->count, rec, offset, cum_bytes);
990 passed = TRUE;
992 /* If we're running a read filter, prime the epan_dissect_t with that
993 filter. */
994 if (n_rfilters > 0) {
995 for(i = 0; i < n_rfcodes; i++) {
996 epan_dissect_prime_with_dfilter(edt, rfcodes[i]);
1000 printf("%lu", (unsigned long int) cf->count);
1002 frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1003 &cf->provider.ref, cf->provider.prev_dis);
1005 if (cf->provider.ref == &fdata) {
1006 ref_frame = fdata;
1007 cf->provider.ref = &ref_frame;
1010 /* We only need the columns if we're printing packet info but we're
1011 *not* verbose; in verbose mode, we print the protocol tree, not
1012 the protocol summary. */
1013 epan_dissect_run_with_taps(edt, cf->cd_t, rec,
1014 frame_tvbuff_new_buffer(&cf->provider, &fdata, buf),
1015 &fdata, &cf->cinfo);
1017 frame_data_set_after_dissect(&fdata, &cum_bytes);
1018 prev_dis_frame = fdata;
1019 cf->provider.prev_dis = &prev_dis_frame;
1021 prev_cap_frame = fdata;
1022 cf->provider.prev_cap = &prev_cap_frame;
1024 for(i = 0; i < n_rfilters; i++) {
1025 /* Run the read filter if we have one. */
1026 if (rfcodes[i])
1027 passed = dfilter_apply_edt(rfcodes[i], edt);
1028 else
1029 passed = TRUE;
1031 /* Print a one-line summary */
1032 printf(" %d", passed ? 1 : 0);
1035 printf(" -\n");
1037 /* The ANSI C standard does not appear to *require* that a line-buffered
1038 stream be flushed to the host environment whenever a newline is
1039 written, it just says that, on such a stream, characters "are
1040 intended to be transmitted to or from the host environment as a
1041 block when a new-line character is encountered".
1043 The Visual C++ 6.0 C implementation doesn't do what is intended;
1044 even if you set a stream to be line-buffered, it still doesn't
1045 flush the buffer at the end of every line.
1047 So, if the "-l" flag was specified, we flush the standard output
1048 at the end of a packet. This will do the right thing if we're
1049 printing packet summary lines, and, as we print the entire protocol
1050 tree for a single packet without waiting for anything to happen,
1051 it should be as good as line-buffered mode if we're printing
1052 protocol trees. (The whole reason for the "-l" flag in either
1053 tcpdump or Rawshark is to allow the output of a live capture to
1054 be piped to a program or script and to have that script see the
1055 information for the packet as soon as it's printed, rather than
1056 having to wait until a standard I/O buffer fills up. */
1057 if (line_buffered)
1058 fflush(stdout);
1060 if (ferror(stdout)) {
1061 show_print_file_io_error(errno);
1062 exit(2);
1065 epan_dissect_reset(edt);
1066 frame_data_destroy(&fdata);
1068 return passed;
1071 /****************************************************************************************
1072 * FIELD EXTRACTION ROUTINES
1073 ****************************************************************************************/
1074 typedef struct _pci_t {
1075 char *filter;
1076 int hf_index;
1077 int cmd_line_index;
1078 } pci_t;
1080 static const char* ftenum_to_string(header_field_info *hfi)
1082 const char* str;
1083 if (!hfi) {
1084 return "n.a.";
1087 if (string_fmts->len > 0 && hfi->strings) {
1088 return "FT_STRING";
1091 str = ftype_name(hfi->type);
1092 if (str == NULL) {
1093 str = "n.a.";
1096 return str;
1099 static void field_display_to_string(header_field_info *hfi, char* buf, int size)
1101 if (hfi->type != FT_BOOLEAN)
1103 (void) g_strlcpy(buf, proto_field_display_to_string(hfi->display), size);
1105 else
1107 snprintf(buf, size, "(Bit count: %d)", hfi->display);
1112 * Copied from various parts of proto.c
1114 #define FIELD_STR_INIT_LEN 256
1115 #define cVALS(x) (const value_string*)(x)
1116 static gboolean print_field_value(field_info *finfo, int cmd_line_index)
1118 const header_field_info *hfinfo;
1119 char *fs_buf;
1120 char *fs_ptr = NULL;
1121 static GString *label_s = NULL;
1122 size_t fs_len;
1123 guint i;
1124 string_fmt_t *sf;
1125 guint32 uvalue;
1126 gint32 svalue;
1127 guint64 uvalue64;
1128 gint64 svalue64;
1130 hfinfo = finfo->hfinfo;
1132 if (!label_s) {
1133 label_s = g_string_new("");
1136 fs_buf = fvalue_to_string_repr(NULL, finfo->value,
1137 FTREPR_DFILTER, finfo->hfinfo->display);
1138 if (fs_buf != NULL) {
1140 * this field has an associated value,
1141 * e.g: ip.hdr_len
1143 fs_len = strlen(fs_buf);
1144 fs_ptr = fs_buf;
1146 /* String types are quoted. Remove them. */
1147 if (FT_IS_STRING(fvalue_type_ftenum(finfo->value)) && fs_len > 2) {
1148 fs_buf[fs_len - 1] = '\0';
1149 fs_ptr++;
1153 if (string_fmts->len > 0 && finfo->hfinfo->strings) {
1154 g_string_truncate(label_s, 0);
1155 for (i = 0; i < string_fmts->len; i++) {
1156 sf = (string_fmt_t *)g_ptr_array_index(string_fmts, i);
1157 if (sf->plain) {
1158 g_string_append(label_s, sf->plain);
1159 } else {
1160 switch (sf->format) {
1161 case SF_NAME:
1162 g_string_append(label_s, hfinfo->name);
1163 break;
1164 case SF_NUMVAL:
1165 g_string_append(label_s, fs_ptr);
1166 break;
1167 case SF_STRVAL:
1168 switch(hfinfo->type) {
1169 case FT_BOOLEAN:
1170 uvalue64 = fvalue_get_uinteger64(finfo->value);
1171 g_string_append(label_s, tfs_get_string(!!uvalue64, hfinfo->strings));
1172 break;
1173 case FT_INT8:
1174 case FT_INT16:
1175 case FT_INT24:
1176 case FT_INT32:
1177 DISSECTOR_ASSERT(!hfinfo->bitmask);
1178 svalue = fvalue_get_sinteger(finfo->value);
1179 if (hfinfo->display & BASE_RANGE_STRING) {
1180 g_string_append(label_s, rval_to_str_const(svalue, (const range_string *) hfinfo->strings, "Unknown"));
1181 } else if (hfinfo->display & BASE_EXT_STRING) {
1182 g_string_append(label_s, val_to_str_ext_const(svalue, (value_string_ext *) hfinfo->strings, "Unknown"));
1183 } else {
1184 g_string_append(label_s, val_to_str_const(svalue, cVALS(hfinfo->strings), "Unknown"));
1186 break;
1187 case FT_INT40: /* XXX: Shouldn't these be as smart as FT_INT{8,16,24,32}? */
1188 case FT_INT48:
1189 case FT_INT56:
1190 case FT_INT64:
1191 DISSECTOR_ASSERT(!hfinfo->bitmask);
1192 svalue64 = fvalue_get_sinteger64(finfo->value);
1193 if (hfinfo->display & BASE_VAL64_STRING) {
1194 g_string_append(label_s, val64_to_str_const(svalue64, (const val64_string *)(hfinfo->strings), "Unknown"));
1196 break;
1197 case FT_UINT8:
1198 case FT_UINT16:
1199 case FT_UINT24:
1200 case FT_UINT32:
1201 DISSECTOR_ASSERT(!hfinfo->bitmask);
1202 uvalue = fvalue_get_uinteger(finfo->value);
1203 if (!hfinfo->bitmask && hfinfo->display & BASE_RANGE_STRING) {
1204 g_string_append(label_s, rval_to_str_const(uvalue, (const range_string *) hfinfo->strings, "Unknown"));
1205 } else if (hfinfo->display & BASE_EXT_STRING) {
1206 g_string_append(label_s, val_to_str_ext_const(uvalue, (value_string_ext *) hfinfo->strings, "Unknown"));
1207 } else {
1208 g_string_append(label_s, val_to_str_const(uvalue, cVALS(hfinfo->strings), "Unknown"));
1210 break;
1211 case FT_UINT40: /* XXX: Shouldn't these be as smart as FT_INT{8,16,24,32}? */
1212 case FT_UINT48:
1213 case FT_UINT56:
1214 case FT_UINT64:
1215 DISSECTOR_ASSERT(!hfinfo->bitmask);
1216 uvalue64 = fvalue_get_uinteger64(finfo->value);
1217 if (hfinfo->display & BASE_VAL64_STRING) {
1218 g_string_append(label_s, val64_to_str_const(uvalue64, (const val64_string *)(hfinfo->strings), "Unknown"));
1220 break;
1221 default:
1222 break;
1224 break;
1225 default:
1226 break;
1230 printf(" %d=\"%s\"", cmd_line_index, label_s->str);
1231 wmem_free(NULL, fs_buf);
1232 return TRUE;
1235 if(fs_buf)
1237 printf(" %d=\"%s\"", cmd_line_index, fs_ptr);
1238 wmem_free(NULL, fs_buf);
1239 return TRUE;
1243 * This field doesn't have an associated value,
1244 * e.g. http
1245 * We return n.a.
1247 printf(" %d=\"n.a.\"", cmd_line_index);
1248 return TRUE;
1251 static tap_packet_status
1252 protocolinfo_packet(void *prs, packet_info *pinfo _U_, epan_dissect_t *edt, const void *dummy _U_, tap_flags_t flags _U_)
1254 pci_t *rs=(pci_t *)prs;
1255 GPtrArray *gp;
1256 guint i;
1258 gp=proto_get_finfo_ptr_array(edt->tree, rs->hf_index);
1259 if(!gp){
1260 printf(" n.a.");
1261 return TAP_PACKET_DONT_REDRAW;
1265 * Print each occurrence of the field
1267 for (i = 0; i < gp->len; i++) {
1268 print_field_value((field_info *)gp->pdata[i], rs->cmd_line_index);
1271 return TAP_PACKET_DONT_REDRAW;
1274 int g_cmd_line_index;
1277 * field must be persistent - we don't g_strdup() it below
1279 static void
1280 protocolinfo_init(char *field)
1282 pci_t *rs;
1283 header_field_info *hfi;
1284 GString *error_string;
1285 char hfibuf[100];
1287 hfi=proto_registrar_get_byname(field);
1288 if(!hfi){
1289 fprintf(stderr, "rawshark: Field \"%s\" doesn't exist.\n", field);
1290 exit(1);
1293 field_display_to_string(hfi, hfibuf, sizeof(hfibuf));
1294 printf("%d %s %s - ",
1295 g_cmd_line_index,
1296 ftenum_to_string(hfi),
1297 hfibuf);
1299 rs=g_new(pci_t, 1);
1300 rs->hf_index=hfi->id;
1301 rs->filter=field;
1302 rs->cmd_line_index = g_cmd_line_index++;
1304 error_string=register_tap_listener("frame", rs, rs->filter, TL_REQUIRES_PROTO_TREE, NULL, protocolinfo_packet, NULL, NULL);
1305 if(error_string){
1306 /* error, we failed to attach to the tap. complain and clean up */
1307 fprintf(stderr, "rawshark: Couldn't register field extraction tap: %s\n",
1308 error_string->str);
1309 g_string_free(error_string, TRUE);
1310 if(rs->filter){
1311 g_free(rs->filter);
1313 g_free(rs);
1315 exit(1);
1320 * Given a format string, split it into a GPtrArray of string_fmt_t structs
1321 * and fill in string_fmt_parts.
1324 static void
1325 add_string_fmt(string_fmt_e format, gchar *plain) {
1326 string_fmt_t *sf = g_new(string_fmt_t, 1);
1328 sf->format = format;
1329 sf->plain = g_strdup(plain);
1331 g_ptr_array_add(string_fmts, sf);
1334 static gboolean
1335 parse_field_string_format(gchar *format) {
1336 size_t len;
1337 size_t pos = 0;
1339 if (!format) {
1340 return FALSE;
1343 GString *plain_s = g_string_new("");
1345 len = strlen(format);
1346 g_ptr_array_set_size(string_fmts, 0);
1348 while (pos < len) {
1349 if (format[pos] == '%') {
1350 if (pos >= (len-1)) { /* There should always be a following specifier character */
1351 return FALSE;
1353 pos++;
1354 if (plain_s->len > 0) {
1355 add_string_fmt(SF_NONE, plain_s->str);
1356 g_string_truncate(plain_s, 0);
1358 switch (format[pos]) {
1359 case 'D':
1360 add_string_fmt(SF_NAME, NULL);
1361 break;
1362 case 'N':
1363 add_string_fmt(SF_NUMVAL, NULL);
1364 break;
1365 case 'S':
1366 add_string_fmt(SF_STRVAL, NULL);
1367 break;
1368 case '%':
1369 g_string_append_c(plain_s, '%');
1370 break;
1371 default: /* Invalid format */
1372 return FALSE;
1374 } else {
1375 g_string_append_c(plain_s, format[pos]);
1377 pos++;
1380 if (plain_s->len > 0) {
1381 add_string_fmt(SF_NONE, plain_s->str);
1383 g_string_free(plain_s, TRUE);
1385 return TRUE;
1387 /****************************************************************************************
1388 * END OF FIELD EXTRACTION ROUTINES
1389 ****************************************************************************************/
1391 static void
1392 show_print_file_io_error(int err)
1394 switch (err) {
1396 case ENOSPC:
1397 cmdarg_err("Not all the packets could be printed because there is "
1398 "no space left on the file system.");
1399 break;
1401 #ifdef EDQUOT
1402 case EDQUOT:
1403 cmdarg_err("Not all the packets could be printed because you are "
1404 "too close to, or over your disk quota.");
1405 break;
1406 #endif
1408 default:
1409 cmdarg_err("An error occurred while printing packets: %s.",
1410 g_strerror(err));
1411 break;
1415 static epan_t *
1416 raw_epan_new(capture_file *cf)
1418 static const struct packet_provider_funcs funcs = {
1419 cap_file_provider_get_frame_ts,
1420 cap_file_provider_get_interface_name,
1421 cap_file_provider_get_interface_description,
1422 NULL,
1425 return epan_new(&cf->provider, &funcs);
1428 cf_status_t
1429 raw_cf_open(capture_file *cf, const char *fname)
1431 if ((fd = raw_pipe_open(fname)) < 0)
1432 return CF_ERROR;
1434 /* The open succeeded. Fill in the information for this file. */
1436 /* Create new epan session for dissection. */
1437 epan_free(cf->epan);
1438 cf->epan = raw_epan_new(cf);
1440 cf->provider.wth = NULL;
1441 cf->f_datalen = 0; /* not used, but set it anyway */
1443 /* Set the file name because we need it to set the follow stream filter.
1444 XXX - is that still true? We need it for other reasons, though,
1445 in any case. */
1446 cf->filename = g_strdup(fname);
1448 /* Indicate whether it's a permanent or temporary file. */
1449 cf->is_tempfile = FALSE;
1451 /* No user changes yet. */
1452 cf->unsaved_changes = FALSE;
1454 cf->cd_t = WTAP_FILE_TYPE_SUBTYPE_UNKNOWN;
1455 cf->open_type = WTAP_TYPE_AUTO;
1456 cf->count = 0;
1457 cf->drops_known = FALSE;
1458 cf->drops = 0;
1459 cf->snap = 0;
1460 nstime_set_zero(&cf->elapsed_time);
1461 cf->provider.ref = NULL;
1462 cf->provider.prev_dis = NULL;
1463 cf->provider.prev_cap = NULL;
1465 return CF_OK;
1469 * Report an error in command-line arguments.
1471 static void
1472 rawshark_cmdarg_err(const char *fmt, va_list ap)
1474 fprintf(stderr, "rawshark: ");
1475 vfprintf(stderr, fmt, ap);
1476 fprintf(stderr, "\n");
1480 * Report additional information for an error in command-line arguments.
1482 static void
1483 rawshark_cmdarg_err_cont(const char *fmt, va_list ap)
1485 vfprintf(stderr, fmt, ap);
1486 fprintf(stderr, "\n");
1490 * Editor modelines
1492 * Local Variables:
1493 * c-basic-offset: 4
1494 * tab-width: 8
1495 * indent-tabs-mode: nil
1496 * End:
1498 * ex: set shiftwidth=4 tabstop=8 expandtab:
1499 * :indentSize=4:tabSize=8:noTabs=true: