EOF in zlib 1.2.5 seems to be sticky. When we're tailing a file and we
[obnox/wireshark/wip.git] / rawshark.c
1 /* rawshark.c
2  *
3  * $Id$
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * Rawshark - Raw field extractor by Gerald Combs <gerald@wireshark.org>
10  * and Loris Degioanni <loris.degioanni@cacetech.com>
11  * Based on TShark, by Gilbert Ramirez <gram@alumni.rice.edu> and Guy Harris
12  * <guy@alum.mit.edu>.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 /*
30  * Rawshark does the following:
31  * - Opens a specified file or named pipe
32  * - Applies a specfied DLT or "decode as" encapsulation
33  * - Reads frames prepended with a libpcap packet header.
34  * - Prints a status line, followed by fields from a specified list.
35  */
36
37 #ifdef HAVE_CONFIG_H
38 # include "config.h"
39 #endif
40
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <ctype.h>
45 #include <locale.h>
46 #include <limits.h>
47
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51
52 #include <errno.h>
53
54 #ifdef HAVE_FCNTL_H
55 #include <fcntl.h>
56 #endif
57
58 #include <signal.h>
59
60 #ifdef HAVE_SYS_STAT_H
61 # include <sys/stat.h>
62 #endif
63
64 #ifdef NEED_STRERROR_H
65 #include "strerror.h"
66 #endif
67
68 #ifdef HAVE_GETOPT_H
69 #include <getopt.h>
70 #else
71 #include "wsgetopt.h"
72 #endif
73
74 #include <glib.h>
75 #include <epan/epan.h>
76 #include <epan/filesystem.h>
77 #include <wsutil/privileges.h>
78 #include <wsutil/file_util.h>
79
80 #include "globals.h"
81 #include <epan/packet.h>
82 #include "file.h"
83 #include "disabled_protos.h"
84 #include <epan/prefs.h>
85 #include <epan/column.h>
86 #include "print.h"
87 #include <epan/addr_resolv.h>
88 #include "util.h"
89 #include "clopts_common.h"
90 #include "cmdarg_err.h"
91 #include "version_info.h"
92 #include <epan/plugins.h>
93 #include "register.h"
94 #include "conditions.h"
95 #include "capture_stop_conditions.h"
96 #include "capture_ui_utils.h"
97 #include <epan/epan_dissect.h>
98 #include <epan/stat_cmd_args.h>
99 #include <epan/timestamp.h>
100 #include <wsutil/unicode-utils.h>
101 #include "epan/column-utils.h"
102 #include "epan/proto.h"
103 #include <epan/tap.h>
104
105 #include <wiretap/wtap.h>
106 #include <wiretap/libpcap.h>
107 #include <wiretap/pcap-encap.h>
108
109 #ifdef HAVE_LIBPCAP
110 #include <setjmp.h>
111 #include "capture-pcap-util.h"
112 #include "pcapio.h"
113 #ifdef _WIN32
114 #include "capture-wpcap.h"
115 #include "capture_errs.h"
116 #endif /* _WIN32 */
117 #endif /* HAVE_LIBPCAP */
118 #include "log.h"
119
120 /*
121  * This is the template for the decode as option; it is shared between the
122  * various functions that output the usage for this parameter.
123  */
124 static const gchar decode_as_arg_template[] = "<layer_type>==<selector>,<decode_as_protocol>";
125
126 static guint32 cum_bytes;
127 static nstime_t first_ts;
128 static nstime_t prev_dis_ts;
129 static nstime_t prev_cap_ts;
130
131 /*
132  * The way the packet decode is to be written.
133  */
134 typedef enum {
135     WRITE_TEXT, /* summary or detail text */
136     WRITE_XML   /* PDML or PSML */
137     /* Add CSV and the like here */
138 } output_action_e;
139
140 static gboolean line_buffered;
141 static print_format_e print_format = PR_FMT_TEXT;
142
143 /*
144  * Standard secondary message for unexpected errors.
145  */
146 static const char please_report[] =
147     "Please report this to the Wireshark developers";
148
149 cf_status_t raw_cf_open(capture_file *cf, const char *fname);
150 static int load_cap_file(capture_file *cf);
151 static gboolean process_packet(capture_file *cf, gint64 offset,
152                                const struct wtap_pkthdr *whdr, const guchar *pd);
153 static void show_print_file_io_error(int err);
154
155 static void open_failure_message(const char *filename, int err,
156                                  gboolean for_writing);
157 static void failure_message(const char *msg_format, va_list ap);
158 static void read_failure_message(const char *filename, int err);
159 static void write_failure_message(const char *filename, int err);
160 static void protocolinfo_init(char *field);
161 static gboolean parse_field_string_format(char *format);
162
163 typedef enum {
164     SF_NONE,    /* No format (placeholder) */
165     SF_NAME,    /* %D Field name / description */
166     SF_NUMVAL,  /* %N Numeric value */
167     SF_STRVAL   /* %S String value */
168 } string_fmt_e;
169
170 typedef struct string_fmt_s {
171     gchar *plain;
172     string_fmt_e format;    /* Valid if plain is NULL */
173 } string_fmt_t;
174
175 capture_file cfile;
176 int n_rfilters;
177 int n_rfcodes;
178 dfilter_t *rfcodes[64];
179 int n_rfieldfilters;
180 dfilter_t *rfieldfcodes[64];
181 int fd;
182 int encap;
183 GPtrArray *string_fmts;
184
185 static void
186 print_usage(gboolean print_ver)
187 {
188     FILE *output;
189
190     if (print_ver) {
191         output = stdout;
192         fprintf(output,
193                 "Rawshark " VERSION "%s\n"
194                 "Dump and analyze network traffic.\n"
195                 "See http://www.wireshark.org for more information.\n"
196                 "\n"
197                 "%s",
198                 wireshark_svnversion, get_copyright_info());
199     } else {
200         output = stderr;
201     }
202     fprintf(output, "\n");
203     fprintf(output, "Usage: rawshark [options] ...\n");
204     fprintf(output, "\n");
205
206     fprintf(output, "Input file:\n");
207     fprintf(output, "  -r <infile>              set the pipe or file name to read from\n");
208
209     fprintf(output, "\n");
210     fprintf(output, "Processing:\n");
211     fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
212     fprintf(output, "  -F <field>               field to display\n");
213     fprintf(output, "  -s                       skip PCAP header on input\n");
214     fprintf(output, "  -n                       disable all name resolution (def: all enabled)\n");
215     fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
216     fprintf(output, "  -d <encap:dlt>|<proto:protoname>\n");
217     fprintf(output, "                           packet encapsulation or protocol\n");
218
219     /*fprintf(output, "\n");*/
220     fprintf(output, "Output:\n");
221     fprintf(output, "  -S                       format string for fields (%%D - name, %%S - stringval, %%N numval)\n");
222     fprintf(output, "  -t ad|a|r|d|dd|e         output format of time stamps (def: r: rel. to first)\n");
223     fprintf(output, "  -l                       flush output after each packet\n");
224
225     fprintf(output, "\n");
226     fprintf(output, "Miscellaneous:\n");
227     fprintf(output, "  -h                       display this help and exit\n");
228     fprintf(output, "  -v                       display version info and exit\n");
229     fprintf(output, "  -o <name>:<value> ...    override preference setting\n");
230 }
231
232 static void
233 log_func_ignore (const gchar *log_domain _U_, GLogLevelFlags log_level _U_,
234                  const gchar *message _U_, gpointer user_data _U_)
235 {
236 }
237
238 /**
239  * Open a pipe for raw input.  This is a stripped-down version of
240  * pcap_loop.c:cap_pipe_open_live().
241  * We check if "pipe_name" is "-" (stdin) or a FIFO, and open it.
242  * @param pipe_name The name of the pipe or FIFO.
243  * @return A POSIX file descriptor on success, or -1 on failure.
244  */
245 static int
246 raw_pipe_open(const char *pipe_name)
247 {
248 #ifndef _WIN32
249     struct stat pipe_stat;
250 #else
251     char *pncopy, *pos;
252     DWORD err;
253     wchar_t *err_str;
254     HANDLE hPipe = NULL;
255 #endif
256     int          rfd;
257
258     g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "open_raw_pipe: %s", pipe_name);
259
260     /*
261      * XXX Rawshark blocks until we return
262      */
263     if (strcmp(pipe_name, "-") == 0) {
264         rfd = 0; /* read from stdin */
265 #ifdef _WIN32
266         /*
267          * This is needed to set the stdin pipe into binary mode, otherwise
268          * CR/LF are mangled...
269          */
270         _setmode(0, _O_BINARY);
271 #endif  /* _WIN32 */
272     } else {
273 #ifndef _WIN32
274         if (ws_stat(pipe_name, &pipe_stat) < 0) {
275             fprintf(stderr, "rawshark: The pipe %s could not be checked: %s\n",
276                     pipe_name, strerror(errno));
277             return -1;
278         }
279         if (! S_ISFIFO(pipe_stat.st_mode)) {
280             if (S_ISCHR(pipe_stat.st_mode)) {
281                 /*
282                  * Assume the user specified an interface on a system where
283                  * interfaces are in /dev.  Pretend we haven't seen it.
284                  */
285             } else
286             {
287                 fprintf(stderr, "rawshark: \"%s\" is neither an interface nor a pipe\n",
288                         pipe_name);
289             }
290             return -1;
291         }
292         rfd = ws_open(pipe_name, O_RDONLY | O_NONBLOCK, 0000 /* no creation so don't matter */);
293         if (rfd == -1) {
294             fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
295                     pipe_name, strerror(errno));
296             return -1;
297         }
298 #else /* _WIN32 */
299 #define PIPE_STR "\\pipe\\"
300         /* Under Windows, named pipes _must_ have the form
301          * "\\<server>\pipe\<pipe_name>".  <server> may be "." for localhost.
302          */
303         pncopy = g_strdup(pipe_name);
304         if (strstr(pncopy, "\\\\") == pncopy) {
305             pos = strchr(pncopy + 3, '\\');
306             if (pos && g_ascii_strncasecmp(pos, PIPE_STR, strlen(PIPE_STR)) != 0)
307                 pos = NULL;
308         }
309
310         g_free(pncopy);
311
312         if (!pos) {
313             fprintf(stderr, "rawshark: \"%s\" is neither an interface nor a pipe\n",
314                     pipe_name);
315             return -1;
316         }
317
318         /* Wait for the pipe to appear */
319         while (1) {
320             hPipe = CreateFile(utf_8to16(pipe_name), GENERIC_READ, 0, NULL,
321                                OPEN_EXISTING, 0, NULL);
322
323             if (hPipe != INVALID_HANDLE_VALUE)
324                 break;
325
326             err = GetLastError();
327             if (err != ERROR_PIPE_BUSY) {
328                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
329                               NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
330                 fprintf(stderr, "rawshark: \"%s\" could not be opened: %s (error %d)\n",
331                         pipe_name, utf_16to8(err_str), err);
332                 LocalFree(err_str);
333                 return -1;
334             }
335
336             if (!WaitNamedPipe(utf_8to16(pipe_name), 30 * 1000)) {
337                 err = GetLastError();
338                 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
339                               NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
340                 fprintf(stderr, "rawshark: \"%s\" could not be waited for: %s (error %d)\n",
341                         pipe_name, utf_16to8(err_str), err);
342                 LocalFree(err_str);
343                 return -1;
344             }
345         }
346
347         rfd = _open_osfhandle((long) hPipe, _O_RDONLY);
348         if (rfd == -1) {
349             fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
350                     pipe_name, strerror(errno));
351             return -1;
352         }
353 #endif /* _WIN32 */
354     }
355
356     return rfd;
357 }
358
359 /**
360  * Parse a link-type argument of the form "encap:<pcap dlt>" or
361  * "proto:<proto name>".  "Pcap dlt" must be a name conforming to
362  * pcap_datalink_name_to_val() or an integer.  "Proto name" must be
363  * a protocol name, e.g. "http".
364  */
365 static gboolean
366 set_link_type(const char *lt_arg) {
367     char *spec_ptr = strchr(lt_arg, ':');
368     char *p;
369     int dlt_val;
370     long val;
371     dissector_handle_t dhandle;
372     GString *pref_str;
373
374     if (!spec_ptr)
375         return FALSE;
376
377     spec_ptr++;
378
379     if (strncmp(lt_arg, "encap:", strlen("encap:")) == 0) {
380         dlt_val = linktype_name_to_val(spec_ptr);
381         if (dlt_val == -1) {
382             errno = 0;
383             val = strtol(spec_ptr, &p, 10);
384             if (p == spec_ptr || *p != '\0' || errno != 0 || val > INT_MAX) {
385                 return FALSE;
386             }
387             dlt_val = (int)val;
388         }
389         encap = wtap_pcap_encap_to_wtap_encap(dlt_val);
390         if (encap == WTAP_ENCAP_UNKNOWN) {
391             return FALSE;
392         }
393         return TRUE;
394     } else if (strncmp(lt_arg, "proto:", strlen("proto:")) == 0) {
395         dhandle = find_dissector(spec_ptr);
396         if (dhandle) {
397             encap = WTAP_ENCAP_USER0;
398             pref_str = g_string_new("uat:user_dlts:");
399             /* This must match the format used in the user_dlts file */
400             g_string_append_printf(pref_str,
401                                    "\"User 0 (DLT=147)\",\"%s\",\"0\",\"\",\"0\",\"\"",
402                                    spec_ptr);
403             if (prefs_set_pref(pref_str->str) != PREFS_SET_OK) {
404                 g_string_free(pref_str, TRUE);
405                 return FALSE;
406             }
407             g_string_free(pref_str, TRUE);
408             return TRUE;
409         }
410     }
411     return FALSE;
412 }
413
414 static void
415 show_version(GString *comp_info_str, GString *runtime_info_str)
416 {
417     printf("Rawshark " VERSION "%s\n"
418            "\n"
419            "%s"
420            "\n"
421            "%s"
422            "\n"
423            "%s",
424            wireshark_svnversion, get_copyright_info(), comp_info_str->str,
425            runtime_info_str->str);
426 }
427
428 int
429 main(int argc, char *argv[])
430 {
431     char                *init_progfile_dir_error;
432     int                  opt, i;
433     gboolean             arg_error = FALSE;
434
435 #ifdef _WIN32
436     WSADATA       wsaData;
437 #endif  /* _WIN32 */
438
439     char                *gpf_path, *pf_path;
440     char                *gdp_path, *dp_path;
441     int                  gpf_open_errno, gpf_read_errno;
442     int                  pf_open_errno, pf_read_errno;
443     int                  gdp_open_errno, gdp_read_errno;
444     int                  dp_open_errno, dp_read_errno;
445     int                  err;
446     gchar               *pipe_name = NULL;
447     gchar               *rfilters[64];
448     e_prefs             *prefs_p;
449     char                 badopt;
450     GLogLevelFlags       log_flags;
451     GPtrArray           *disp_fields = g_ptr_array_new();
452     guint                fc;
453     gboolean             skip_pcap_header = FALSE;
454
455 #define OPTSTRING_INIT "d:F:hlnN:o:r:R:sS:t:v"
456
457     static const char    optstring[] = OPTSTRING_INIT;
458
459     /*
460      * Get credential information for later use.
461      */
462     get_credential_info();
463
464     /*
465      * Clear the filters arrays
466      */
467     memset(rfilters, 0, sizeof(rfilters));
468     memset(rfcodes, 0, sizeof(rfcodes));
469     n_rfilters = 0;
470     n_rfcodes = 0;
471
472     /*
473      * Initialize our string format
474      */
475     string_fmts = g_ptr_array_new();
476
477     /*
478      * Attempt to get the pathname of the executable file.
479      */
480     init_progfile_dir_error = init_progfile_dir(argv[0], main);
481     if (init_progfile_dir_error != NULL) {
482         fprintf(stderr, "rawshark: Can't get pathname of rawshark program: %s.\n",
483                 init_progfile_dir_error);
484     }
485
486     /*
487      * Get credential information for later use.
488      */
489     get_credential_info();
490
491     /* nothing more than the standard GLib handler, but without a warning */
492     log_flags =
493         G_LOG_LEVEL_WARNING |
494         G_LOG_LEVEL_MESSAGE |
495         G_LOG_LEVEL_INFO |
496         G_LOG_LEVEL_DEBUG;
497
498     g_log_set_handler(NULL,
499                       log_flags,
500                       log_func_ignore, NULL /* user_data */);
501     g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
502                       log_flags,
503                       log_func_ignore, NULL /* user_data */);
504
505     timestamp_set_type(TS_RELATIVE);
506     timestamp_set_precision(TS_PREC_AUTO);
507     timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
508
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     epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL,
514               failure_message, open_failure_message, read_failure_message,
515               write_failure_message);
516
517     /* Now register the preferences for any non-dissector modules.
518        We must do that before we read the preferences as well. */
519     prefs_register_modules();
520
521     /* Set the C-language locale to the native environment. */
522     setlocale(LC_ALL, "");
523
524     prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
525                          &pf_open_errno, &pf_read_errno, &pf_path);
526     if (gpf_path != NULL) {
527         if (gpf_open_errno != 0) {
528             cmdarg_err("Can't open global preferences file \"%s\": %s.",
529                        pf_path, strerror(gpf_open_errno));
530         }
531         if (gpf_read_errno != 0) {
532             cmdarg_err("I/O error reading global preferences file \"%s\": %s.",
533                        pf_path, strerror(gpf_read_errno));
534         }
535     }
536     if (pf_path != NULL) {
537         if (pf_open_errno != 0) {
538             cmdarg_err("Can't open your preferences file \"%s\": %s.", pf_path,
539                        strerror(pf_open_errno));
540         }
541         if (pf_read_errno != 0) {
542             cmdarg_err("I/O error reading your preferences file \"%s\": %s.",
543                        pf_path, strerror(pf_read_errno));
544         }
545         g_free(pf_path);
546         pf_path = NULL;
547     }
548
549     /* Set the name resolution code's flags from the preferences. */
550     g_resolv_flags = prefs_p->name_resolve;
551
552     /* Read the disabled protocols file. */
553     read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
554                               &dp_path, &dp_open_errno, &dp_read_errno);
555     if (gdp_path != NULL) {
556         if (gdp_open_errno != 0) {
557             cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
558                        gdp_path, strerror(gdp_open_errno));
559         }
560         if (gdp_read_errno != 0) {
561             cmdarg_err("I/O error reading global disabled protocols file\n\"%s\": %s.",
562                        gdp_path, strerror(gdp_read_errno));
563         }
564         g_free(gdp_path);
565     }
566     if (dp_path != NULL) {
567         if (dp_open_errno != 0) {
568             cmdarg_err(
569                 "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
570                 strerror(dp_open_errno));
571         }
572         if (dp_read_errno != 0) {
573             cmdarg_err(
574                 "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
575                 strerror(dp_read_errno));
576         }
577         g_free(dp_path);
578     }
579
580 #ifdef _WIN32
581     /* Load Wpcap, if possible */
582     load_wpcap();
583 #endif
584
585     cap_file_init(&cfile);
586
587     /* Print format defaults to this. */
588     print_format = PR_FMT_TEXT;
589
590     /* Initialize our encapsulation type */
591     encap = WTAP_ENCAP_UNKNOWN;
592
593     /* Now get our args */
594     /* XXX - We should probably have an option to dump libpcap link types */
595     while ((opt = getopt(argc, argv, optstring)) != -1) {
596         switch (opt) {
597             case 'd':        /* Payload type */
598                 if (!set_link_type(optarg)) {
599                     cmdarg_err("Invalid link type or protocol \"%s\"", optarg);
600                     exit(1);
601                 }
602                 break;
603             case 'F':        /* Read field to display */
604                 g_ptr_array_add(disp_fields, g_strdup(optarg));
605                 break;
606             case 'h':        /* Print help and exit */
607                 print_usage(TRUE);
608                 exit(0);
609                 break;
610             case 'l':        /* "Line-buffer" standard output */
611                 /* This isn't line-buffering, strictly speaking, it's just
612                    flushing the standard output after the information for
613                    each packet is printed; however, that should be good
614                    enough for all the purposes to which "-l" is put (and
615                    is probably actually better for "-V", as it does fewer
616                    writes).
617
618                    See the comment in "process_packet()" for an explanation of
619                    why we do that, and why we don't just use "setvbuf()" to
620                    make the standard output line-buffered (short version: in
621                    Windows, "line-buffered" is the same as "fully-buffered",
622                    and the output buffer is only flushed when it fills up). */
623                 line_buffered = TRUE;
624                 break;
625             case 'n':        /* No name resolution */
626                 g_resolv_flags = RESOLV_NONE;
627                 break;
628             case 'N':        /* Select what types of addresses/port #s to resolve */
629                 if (g_resolv_flags == RESOLV_ALL)
630                     g_resolv_flags = RESOLV_NONE;
631                 badopt = string_to_name_resolve(optarg, &g_resolv_flags);
632                 if (badopt != '\0') {
633                     cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
634                                badopt);
635                     exit(1);
636                 }
637                 break;
638             case 'o':        /* Override preference from command line */
639                 switch (prefs_set_pref(optarg)) {
640
641                     case PREFS_SET_OK:
642                         break;
643
644                     case PREFS_SET_SYNTAX_ERR:
645                         cmdarg_err("Invalid -o flag \"%s\"", optarg);
646                         exit(1);
647                         break;
648
649                     case PREFS_SET_NO_SUCH_PREF:
650                     case PREFS_SET_OBSOLETE:
651                         cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
652                         exit(1);
653                         break;
654                 }
655                 break;
656             case 'r':        /* Read capture file xxx */
657                 pipe_name = g_strdup(optarg);
658                 break;
659             case 'R':        /* Read file filter */
660                 if(n_rfilters < (int) sizeof(rfilters) / (int) sizeof(rfilters[0])) {
661                     rfilters[n_rfilters++] = optarg;
662                 }
663                 else {
664                     cmdarg_err("Too many display filters");
665                     exit(1);
666                 }
667                 break;
668             case 's':        /* Skip PCAP header */
669                 skip_pcap_header = TRUE;
670                 break;
671             case 'S':        /* Print string representations */
672                 if (!parse_field_string_format(optarg)) {
673                     cmdarg_err("Invalid field string format");
674                     exit(1);
675                 }
676                 break;
677             case 't':        /* Time stamp type */
678                 if (strcmp(optarg, "r") == 0)
679                     timestamp_set_type(TS_RELATIVE);
680                 else if (strcmp(optarg, "a") == 0)
681                     timestamp_set_type(TS_ABSOLUTE);
682                 else if (strcmp(optarg, "ad") == 0)
683                     timestamp_set_type(TS_ABSOLUTE_WITH_DATE);
684                 else if (strcmp(optarg, "d") == 0)
685                     timestamp_set_type(TS_DELTA);
686                 else if (strcmp(optarg, "dd") == 0)
687                     timestamp_set_type(TS_DELTA_DIS);
688                 else if (strcmp(optarg, "e") == 0)
689                     timestamp_set_type(TS_EPOCH);
690                 else {
691                     cmdarg_err("Invalid time stamp type \"%s\"",
692                                optarg);
693                     cmdarg_err_cont("It must be \"r\" for relative, \"a\" for absolute,");
694                     cmdarg_err_cont("\"ad\" for absolute with date, or \"d\" for delta.");
695                     exit(1);
696                 }
697                 break;
698             case 'v':        /* Show version and exit */
699             {
700                 GString             *comp_info_str;
701                 GString             *runtime_info_str;
702                 /* Assemble the compile-time version information string */
703                 comp_info_str = g_string_new("Compiled ");
704                 get_compiled_version_info(comp_info_str, get_epan_compiled_version_info);
705
706                 /* Assemble the run-time version information string */
707                 runtime_info_str = g_string_new("Running ");
708                 get_runtime_version_info(runtime_info_str, NULL);
709                 show_version(comp_info_str, runtime_info_str);
710                 g_string_free(comp_info_str, TRUE);
711                 g_string_free(runtime_info_str, TRUE);
712                 exit(0);
713                 break;
714             }
715             default:
716             case '?':        /* Bad flag - print usage message */
717                 print_usage(TRUE);
718             exit(1);
719             break;
720         }
721     }
722
723     /* Notify all registered modules that have had any of their preferences
724        changed either from one of the preferences file or from the command
725        line that their preferences have changed.
726        Initialize preferences before display filters, otherwise modules
727        like MATE won't work. */
728     prefs_apply_all();
729
730     /* Initialize our display fields */
731     for (fc = 0; fc < disp_fields->len; fc++) {
732         protocolinfo_init((char *)g_ptr_array_index(disp_fields, fc));
733     }
734     g_ptr_array_free(disp_fields, TRUE);
735     printf("\n");
736     fflush(stdout);
737
738     /* If no capture filter or read filter has been specified, and there are
739        still command-line arguments, treat them as the tokens of a capture
740        filter (if no "-r" flag was specified) or a read filter (if a "-r"
741        flag was specified. */
742     if (optind < argc) {
743         if (pipe_name != NULL) {
744             if (n_rfilters != 0) {
745                 cmdarg_err("Read filters were specified both with \"-R\" "
746                            "and with additional command-line arguments");
747                 exit(1);
748             }
749             rfilters[n_rfilters] = get_args_as_string(argc, argv, optind);
750         }
751     }
752
753     /* Make sure we got a dissector handle for our payload. */
754     if (encap == WTAP_ENCAP_UNKNOWN) {
755         cmdarg_err("No valid payload dissector specified.");
756         exit(1);
757     }
758
759     if (arg_error) {
760         print_usage(FALSE);
761         exit(1);
762     }
763
764
765 #ifdef _WIN32
766     /* Start windows sockets */
767     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
768 #endif /* _WIN32 */
769
770     /* At this point MATE will have registered its field array so we can
771        have a tap filter with one of MATE's late-registered fields as part
772        of the filter.  We can now process all the "-z" arguments. */
773     start_requested_stats();
774
775     /* disabled protocols as per configuration file */
776     if (gdp_path == NULL && dp_path == NULL) {
777         set_disabled_protos_list();
778     }
779
780     /* Build the column format array */
781     build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
782
783     if (n_rfilters != 0) {
784         for (i = 0; i < n_rfilters; i++) {
785             if (!dfilter_compile(rfilters[i], &rfcodes[n_rfcodes])) {
786                 cmdarg_err("%s", dfilter_error_msg);
787                 epan_cleanup();
788                 exit(2);
789             }
790             n_rfcodes++;
791         }
792     }
793
794     if (pipe_name) {
795         /*
796          * We're reading a pipe (or capture file).
797          */
798
799         /*
800          * Immediately relinquish any special privileges we have; we must not
801          * be allowed to read any capture files the user running Rawshark
802          * can't open.
803          */
804         relinquish_special_privs_perm();
805
806         if (raw_cf_open(&cfile, pipe_name) != CF_OK) {
807             epan_cleanup();
808             exit(2);
809         }
810
811         /* Do we need to PCAP header and magic? */
812         if (skip_pcap_header) {
813             guint bytes_left = sizeof(struct pcap_hdr) + sizeof(guint32);
814             gchar buf[sizeof(struct pcap_hdr) + sizeof(guint32)];
815             while (bytes_left > 0) {
816                 guint bytes = read(fd, buf, bytes_left);
817                 if (bytes <= 0) {
818                     cmdarg_err("Not enough bytes for pcap header.");
819                     exit(2);
820                 }
821                 bytes_left -= bytes;
822             }
823         }
824
825         /* Set timestamp precision; there should arguably be a command-line
826            option to let the user set this. */
827 #if 0
828         switch(wtap_file_tsprecision(cfile.wth)) {
829             case(WTAP_FILE_TSPREC_SEC):
830                 timestamp_set_precision(TS_PREC_AUTO_SEC);
831                 break;
832             case(WTAP_FILE_TSPREC_DSEC):
833                 timestamp_set_precision(TS_PREC_AUTO_DSEC);
834                 break;
835             case(WTAP_FILE_TSPREC_CSEC):
836                 timestamp_set_precision(TS_PREC_AUTO_CSEC);
837                 break;
838             case(WTAP_FILE_TSPREC_MSEC):
839                 timestamp_set_precision(TS_PREC_AUTO_MSEC);
840                 break;
841             case(WTAP_FILE_TSPREC_USEC):
842                 timestamp_set_precision(TS_PREC_AUTO_USEC);
843                 break;
844             case(WTAP_FILE_TSPREC_NSEC):
845                 timestamp_set_precision(TS_PREC_AUTO_NSEC);
846                 break;
847             default:
848                 g_assert_not_reached();
849         }
850 #else
851         timestamp_set_precision(TS_PREC_AUTO_USEC);
852 #endif
853
854         /* Process the packets in the file */
855         err = load_cap_file(&cfile);
856
857         if (err != 0) {
858             epan_cleanup();
859             exit(2);
860         }
861     } else {
862         /* If you want to capture live packets, use TShark. */
863         cmdarg_err("Input file or pipe name not specified.");
864         exit(2);
865     }
866
867     epan_cleanup();
868
869     return 0;
870 }
871
872 /**
873  * Read data from a raw pipe.  The "raw" data consists of a libpcap
874  * packet header followed by the payload.
875  * @param fd [IN] A POSIX file descriptor.  Because that's _exactly_ the sort
876  *           of thing you want to use in Windows.
877  * @param phdr [OUT] Packet header information.
878  * @param err [OUT] Error indicator.  Uses wiretap values.
879  * @param err_info [OUT] Error message.
880  * @param data_offset [OUT] data offset in the pipe.
881  * @return TRUE on success, FALSE on failure.
882  */
883 static gboolean
884 raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, const gchar **err_info, gint64 *data_offset) {
885     struct pcaprec_hdr hdr;
886     int bytes_read = 0;
887     int bytes_needed = sizeof(struct pcaprec_hdr);
888     guchar *ptr = (guchar*)&hdr;
889     static gchar err_str[100];
890
891     /* Copied from capture_loop.c */
892     while (bytes_needed > 0) {
893         bytes_read = read(fd, ptr, bytes_needed);
894         if (bytes_read == 0) {
895             *err = 0;
896             return FALSE;
897         } else if (bytes_read < 0) {
898             *err = WTAP_ERR_CANT_READ;
899             *err_info = "Error reading header from pipe";
900             return FALSE;
901         }
902         bytes_needed -= bytes_read;
903         *data_offset += bytes_read;
904         ptr += bytes_read;
905     }
906
907     phdr->ts.secs = hdr.ts_sec;
908     phdr->ts.nsecs = hdr.ts_usec * 1000;
909     phdr->caplen = bytes_needed = hdr.incl_len;
910     phdr->len = hdr.orig_len;
911     phdr->pkt_encap = encap;
912
913 #if 0
914     printf("tv_sec: %d (%04x)\n", hdr.ts.tv_sec, hdr.ts.tv_sec);
915     printf("tv_usec: %d (%04x)\n", hdr.ts.tv_usec, hdr.ts.tv_usec);
916     printf("caplen: %d (%04x)\n", hdr.caplen, hdr.caplen);
917     printf("len: %d (%04x)\n", hdr.len, hdr.len);
918 #endif
919     if (bytes_needed > WTAP_MAX_PACKET_SIZE) {
920         *err = WTAP_ERR_BAD_RECORD;
921         g_snprintf(err_str, 100, "Bad packet length: %d (%04x)", bytes_needed, bytes_needed);
922         *err_info = err_str;
923         return FALSE;
924     }
925
926     ptr = pd;
927     while (bytes_needed > 0) {
928         bytes_read = read(fd, ptr, bytes_needed);
929         if (bytes_read == 0) {
930             *err = WTAP_ERR_SHORT_READ;
931             *err_info = "Got zero bytes reading data from pipe";
932             return FALSE;
933         } else if (bytes_read < 0) {
934             *err = WTAP_ERR_CANT_READ;
935             *err_info = "Error reading data from pipe";
936             return FALSE;
937         }
938         bytes_needed -= bytes_read;
939         *data_offset += bytes_read;
940         ptr += bytes_read;
941     }
942     return TRUE;
943 }
944
945 static int
946 load_cap_file(capture_file *cf)
947 {
948     int          err;
949     const gchar  *err_info;
950     gint64       data_offset = 0;
951     struct wtap_pkthdr  phdr;
952     guchar       pd[WTAP_MAX_PACKET_SIZE];
953
954     while (raw_pipe_read(&phdr, pd, &err, &err_info, &data_offset)) {
955         process_packet(cf, data_offset, &phdr, pd);
956     }
957
958     if (err != 0) {
959         /* Print a message noting that the read failed somewhere along the line. */
960         switch (err) {
961
962             case WTAP_ERR_UNSUPPORTED_ENCAP:
963                 cmdarg_err("\"%s\" has a packet with a network type that Rawshark doesn't support.\n(%s)",
964                            cf->filename, err_info);
965                 break;
966
967             case WTAP_ERR_CANT_READ:
968                 cmdarg_err("An attempt to read from \"%s\" failed for some unknown reason.",
969                            cf->filename);
970                 break;
971
972             case WTAP_ERR_SHORT_READ:
973                 cmdarg_err("\"%s\" appears to have been cut short in the middle of a packet.",
974                            cf->filename);
975                 break;
976
977             case WTAP_ERR_BAD_RECORD:
978                 cmdarg_err("\"%s\" appears to be damaged or corrupt.\n(%s)",
979                            cf->filename, err_info);
980                 break;
981
982             default:
983                 cmdarg_err("An error occurred while reading \"%s\": %s.",
984                            cf->filename, wtap_strerror(err));
985                 break;
986         }
987     }
988
989     return err;
990 }
991
992 static gboolean
993 process_packet(capture_file *cf, gint64 offset, const struct wtap_pkthdr *whdr,
994                const guchar *pd)
995 {
996     frame_data fdata;
997     gboolean create_proto_tree;
998     epan_dissect_t edt;
999     gboolean passed;
1000     union wtap_pseudo_header pseudo_header;
1001     int i;
1002
1003     if(whdr->len == 0)
1004     {
1005         /* The user sends an empty packet when he wants to get output from us even if we don't currently have
1006            packets to process. We spit out a line with the timestamp and the text "void"
1007         */
1008         printf("%lu %lu %lu void -\n", (unsigned long int)cf->count,
1009                (unsigned long int)whdr->ts.secs,
1010                (unsigned long int)whdr->ts.nsecs);
1011
1012         fflush(stdout);
1013
1014         return FALSE;
1015     }
1016
1017     memset(&pseudo_header, 0, sizeof(pseudo_header));
1018
1019     /* Count this packet. */
1020     cf->count++;
1021
1022     /* If we're going to print packet information, or we're going to
1023        run a read filter, or we're going to process taps, set up to
1024        do a dissection and do so. */
1025     frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1026
1027     passed = TRUE;
1028     create_proto_tree = TRUE;
1029
1030     /* The protocol tree will be "visible", i.e., printed, only if we're
1031        printing packet details, which is true if we're in verbose mode ("verbose"
1032        is true). */
1033     epan_dissect_init(&edt, create_proto_tree, FALSE);
1034
1035     /* If we're running a read filter, prime the epan_dissect_t with that
1036        filter. */
1037     if (n_rfilters > 0) {
1038         for(i = 0; i < n_rfcodes; i++) {
1039             epan_dissect_prime_dfilter(&edt, rfcodes[i]);
1040         }
1041     }
1042
1043     tap_queue_init(&edt);
1044
1045     printf("%lu", (unsigned long int) cf->count);
1046
1047     frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1048                                   &first_ts, &prev_dis_ts, &prev_cap_ts);
1049
1050     /* We only need the columns if we're printing packet info but we're
1051      *not* verbose; in verbose mode, we print the protocol tree, not
1052      the protocol summary. */
1053     epan_dissect_run(&edt, &pseudo_header, pd, &fdata, &cf->cinfo);
1054
1055     tap_push_tapped_queue(&edt);
1056
1057     frame_data_set_after_dissect(&fdata, &cum_bytes, &prev_dis_ts);
1058
1059     for(i = 0; i < n_rfilters; i++) {
1060         /* Run the read filter if we have one. */
1061         if (rfcodes[i])
1062             passed = dfilter_apply_edt(rfcodes[i], &edt);
1063         else
1064             passed = TRUE;
1065
1066         /* Print a one-line summary */
1067         printf(" %u", passed ? 1 : 0);
1068     }
1069
1070     printf(" -\n");
1071
1072     /* The ANSI C standard does not appear to *require* that a line-buffered
1073        stream be flushed to the host environment whenever a newline is
1074        written, it just says that, on such a stream, characters "are
1075        intended to be transmitted to or from the host environment as a
1076        block when a new-line character is encountered".
1077
1078        The Visual C++ 6.0 C implementation doesn't do what is intended;
1079        even if you set a stream to be line-buffered, it still doesn't
1080        flush the buffer at the end of every line.
1081
1082        So, if the "-l" flag was specified, we flush the standard output
1083        at the end of a packet.  This will do the right thing if we're
1084        printing packet summary lines, and, as we print the entire protocol
1085        tree for a single packet without waiting for anything to happen,
1086        it should be as good as line-buffered mode if we're printing
1087        protocol trees.  (The whole reason for the "-l" flag in either
1088        tcpdump or Rawshark is to allow the output of a live capture to
1089        be piped to a program or script and to have that script see the
1090        information for the packet as soon as it's printed, rather than
1091        having to wait until a standard I/O buffer fills up. */
1092     if (line_buffered)
1093         fflush(stdout);
1094
1095     if (ferror(stdout)) {
1096         show_print_file_io_error(errno);
1097         exit(2);
1098     }
1099
1100     epan_dissect_cleanup(&edt);
1101     frame_data_cleanup(&fdata);
1102
1103     return passed;
1104 }
1105
1106 /****************************************************************************************
1107  * FIELD EXTRACTION ROUTINES
1108  ****************************************************************************************/
1109 typedef struct _pci_t {
1110     char *filter;
1111     int hf_index;
1112     int cmd_line_index;
1113 } pci_t;
1114
1115 static const char* ftenum_to_string(header_field_info *hfi)
1116 {
1117     if (!hfi) {
1118         return "n.a.";
1119     }
1120
1121     if (string_fmts->len > 0 && hfi->strings) {
1122         return "FT_STRING";
1123     }
1124
1125     switch(hfi->type) {
1126         case FT_NONE:
1127             return "FT_NONE";
1128         case FT_PROTOCOL:
1129             return "FT_PROTOCOL";
1130         case FT_BOOLEAN:
1131             return "FT_BOOLEAN";
1132         case FT_UINT8:
1133             return "FT_UINT8";
1134         case FT_UINT16:
1135             return "FT_UINT16";
1136         case FT_UINT24:
1137             return "FT_UINT24";
1138         case FT_UINT32:
1139             return "FT_UINT32";
1140         case FT_UINT64:
1141             return "FT_UINT64";
1142         case FT_INT8:
1143             return "FT_INT8";
1144         case FT_INT16:
1145             return "FT_INT16";
1146         case FT_INT24:
1147             return "FT_INT24";
1148         case FT_INT32:
1149             return "FT_INT32";
1150         case FT_INT64:
1151             return "FT_INT64";
1152         case FT_FLOAT:
1153             return "FT_FLOAT";
1154         case FT_DOUBLE:
1155             return "FT_DOUBLE";
1156         case FT_ABSOLUTE_TIME:
1157             return "FT_ABSOLUTE_TIME";
1158         case FT_RELATIVE_TIME:
1159             return "FT_RELATIVE_TIME";
1160         case FT_STRING:
1161             return "FT_STRING";
1162         case FT_STRINGZ:
1163             return "FT_STRINGZ";
1164         case FT_UINT_STRING:
1165             return "FT_UINT_STRING";
1166         case FT_ETHER:
1167             return "FT_ETHER";
1168         case FT_BYTES:
1169             return "FT_BYTES";
1170         case FT_UINT_BYTES:
1171             return "FT_UINT_BYTES";
1172         case FT_IPv4:
1173             return "FT_IPv4";
1174         case FT_IPv6:
1175             return "FT_IPv6";
1176         case FT_IPXNET:
1177             return "FT_IPXNET";
1178         case FT_FRAMENUM:
1179             return "FT_FRAMENUM";
1180         case FT_PCRE:
1181             return "FT_PCRE";
1182         case FT_GUID:
1183             return "FT_GUID";
1184         case FT_OID:
1185             return "FT_OID";
1186         case FT_NUM_TYPES:
1187             return "FT_NUM_TYPES";
1188         default:
1189             return "n.a.";
1190     };
1191 }
1192
1193 static const char* absolute_time_display_e_to_string(absolute_time_display_e atd)
1194 {
1195     switch(atd) {
1196         case ABSOLUTE_TIME_LOCAL:
1197             return "ABSOLUTE_TIME_LOCAL";
1198         case ABSOLUTE_TIME_UTC:
1199             return "ABSOLUTE_TIME_UTC";
1200         default:
1201             return "n.a.";
1202     }
1203 }
1204
1205 static const char* base_display_e_to_string(base_display_e bd)
1206 {
1207     switch(bd) {
1208         case BASE_NONE:
1209             return "BASE_NONE";
1210         case BASE_DEC:
1211             return "BASE_DEC";
1212         case BASE_HEX:
1213             return "BASE_HEX";
1214         case BASE_OCT:
1215             return "BASE_OCT";
1216         case BASE_DEC_HEX:
1217             return "BASE_DEC_HEX";
1218         case BASE_HEX_DEC:
1219             return "BASE_HEX_DEC";
1220         default:
1221             return "n.a.";
1222     }
1223 }
1224
1225 /*
1226  * Copied from various parts of proto.c
1227  */
1228 #define FIELD_STR_INIT_LEN 256
1229 #define cVALS(x) (const value_string*)(x)
1230 static gboolean print_field_value(field_info *finfo, int cmd_line_index)
1231 {
1232     header_field_info   *hfinfo;
1233     static char         *fs_buf = NULL;
1234     char                *fs_ptr = fs_buf;
1235     static GString     *label_s = NULL;
1236     int                 fs_buf_len = FIELD_STR_INIT_LEN, fs_len;
1237     guint              i;
1238     string_fmt_t       *sf;
1239     guint32            uvalue;
1240     gint32             svalue;
1241     const true_false_string *tfstring = &tfs_true_false;
1242
1243     hfinfo = finfo->hfinfo;
1244
1245     if (!fs_buf) {
1246         fs_buf = (char *)g_malloc(fs_buf_len + 1);
1247         fs_ptr = fs_buf;
1248     }
1249
1250     if (!label_s) {
1251         label_s = g_string_new("");
1252     }
1253
1254     if(finfo->value.ftype->val_to_string_repr)
1255     {
1256         /*
1257          * this field has an associated value,
1258          * e.g: ip.hdr_len
1259          */
1260         fs_len = fvalue_string_repr_len(&finfo->value, FTREPR_DFILTER);
1261         while (fs_buf_len < fs_len) {
1262             fs_buf_len *= 2;
1263             fs_buf = (char *)g_realloc(fs_buf, fs_buf_len + 1);
1264             fs_ptr = fs_buf;
1265         }
1266         fvalue_to_string_repr(&finfo->value,
1267                               FTREPR_DFILTER,
1268                               fs_buf);
1269
1270         /* String types are quoted. Remove them. */
1271         if ((finfo->value.ftype->ftype == FT_STRING || finfo->value.ftype->ftype == FT_STRINGZ) && fs_len > 2) {
1272             fs_buf[fs_len - 1] = '\0';
1273             fs_ptr++;
1274         }
1275     }
1276
1277     if (string_fmts->len > 0 && finfo->hfinfo->strings) {
1278         g_string_truncate(label_s, 0);
1279         for (i = 0; i < string_fmts->len; i++) {
1280             sf = (string_fmt_t *)g_ptr_array_index(string_fmts, i);
1281             if (sf->plain) {
1282                 g_string_append(label_s, sf->plain);
1283             } else {
1284                 switch (sf->format) {
1285                     case SF_NAME:
1286                         g_string_append(label_s, hfinfo->name);
1287                         break;
1288                     case SF_NUMVAL:
1289                         g_string_append(label_s, fs_ptr);
1290                         break;
1291                     case SF_STRVAL:
1292                         switch(hfinfo->type) {
1293                             case FT_BOOLEAN:
1294                                 uvalue = fvalue_get_uinteger(&finfo->value);
1295                                 tfstring = (const struct true_false_string*) hfinfo->strings;
1296                                 g_string_append(label_s, uvalue ? tfstring->true_string : tfstring->false_string);
1297                                 break;
1298                             case FT_INT8:
1299                             case FT_INT16:
1300                             case FT_INT24:
1301                             case FT_INT32:
1302                                 DISSECTOR_ASSERT(!hfinfo->bitmask);
1303                                 svalue = fvalue_get_sinteger(&finfo->value);
1304                                 if (hfinfo->display & BASE_RANGE_STRING) {
1305                                     g_string_append(label_s, rval_to_str(svalue, RVALS(hfinfo->strings), "Unknown"));
1306                                 } else {
1307                                     g_string_append(label_s, val_to_str(svalue, cVALS(hfinfo->strings), "Unknown"));
1308                                 }
1309                                 break;
1310                             case FT_UINT8:
1311                             case FT_UINT16:
1312                             case FT_UINT24:
1313                             case FT_UINT32:
1314                                 uvalue = fvalue_get_uinteger(&finfo->value);
1315                                 if (!hfinfo->bitmask && hfinfo->display & BASE_RANGE_STRING) {
1316                                     g_string_append(label_s, rval_to_str(uvalue, RVALS(hfinfo->strings), "Unknown"));
1317                                 } else {
1318                                     g_string_append(label_s, val_to_str(uvalue, cVALS(hfinfo->strings), "Unknown"));
1319                                 }
1320                                 break;
1321                             default:
1322                                 break;
1323                         }
1324                         break;
1325                     default:
1326                         break;
1327                 }
1328             }
1329         }
1330         printf(" %u=\"%s\"", cmd_line_index, label_s->str);
1331         return TRUE;
1332     }
1333
1334     if(finfo->value.ftype->val_to_string_repr)
1335     {
1336         printf(" %u=\"%s\"", cmd_line_index, fs_ptr);
1337         return TRUE;
1338     }
1339
1340     /*
1341      * This field doesn't have an associated value,
1342      * e.g. http
1343      * We return n.a.
1344      */
1345     printf(" %u=\"n.a.\"", cmd_line_index);
1346     return TRUE;
1347 }
1348
1349 static int
1350 protocolinfo_packet(void *prs, packet_info *pinfo _U_, epan_dissect_t *edt, const void *dummy _U_)
1351 {
1352     pci_t *rs=(pci_t *)prs;
1353     GPtrArray *gp;
1354     guint i;
1355
1356     gp=proto_get_finfo_ptr_array(edt->tree, rs->hf_index);
1357     if(!gp){
1358         printf(" n.a.");
1359         return 0;
1360     }
1361
1362     /*
1363      * Print each occurrence of the field
1364      */
1365     for (i = 0; i < gp->len; i++) {
1366         print_field_value((field_info *)gp->pdata[i], rs->cmd_line_index);
1367     }
1368
1369     return 0;
1370 }
1371
1372 int g_cmd_line_index = 0;
1373
1374 /*
1375  * field must be persistent - we don't g_strdup() it below
1376  */
1377 static void
1378 protocolinfo_init(char *field)
1379 {
1380     pci_t *rs;
1381     header_field_info *hfi;
1382     GString *error_string;
1383
1384     hfi=proto_registrar_get_byname(field);
1385     if(!hfi){
1386         fprintf(stderr, "rawshark: Field \"%s\" doesn't exist.\n", field);
1387         exit(1);
1388     }
1389
1390     switch (hfi->type) {
1391
1392         case FT_ABSOLUTE_TIME:
1393             printf("%u %s %s - ",
1394                    g_cmd_line_index,
1395                    ftenum_to_string(hfi),
1396                    absolute_time_display_e_to_string(hfi->display));
1397             break;
1398             break;
1399
1400         default:
1401             printf("%u %s %s - ",
1402                    g_cmd_line_index,
1403                    ftenum_to_string(hfi),
1404                    base_display_e_to_string(hfi->display));
1405             break;
1406     }
1407
1408     rs=(pci_t *)g_malloc(sizeof(pci_t));
1409     rs->hf_index=hfi->id;
1410     rs->filter=field;
1411     rs->cmd_line_index = g_cmd_line_index++;
1412
1413     error_string=register_tap_listener("frame", rs, rs->filter, TL_REQUIRES_PROTO_TREE, NULL, protocolinfo_packet, NULL);
1414     if(error_string){
1415         /* error, we failed to attach to the tap. complain and clean up */
1416         fprintf(stderr, "rawshark: Couldn't register field extraction tap: %s\n",
1417                 error_string->str);
1418         g_string_free(error_string, TRUE);
1419         if(rs->filter){
1420             g_free(rs->filter);
1421         }
1422         g_free(rs);
1423
1424         exit(1);
1425     }
1426 }
1427
1428 /*
1429  * Given a format string, split it into a GPtrArray of string_fmt_t structs
1430  * and fill in string_fmt_parts.
1431  */
1432
1433 static void
1434 add_string_fmt(string_fmt_e format, gchar *plain) {
1435     string_fmt_t *sf = (string_fmt_t *)g_malloc(sizeof(string_fmt_t));
1436
1437     sf->format = format;
1438     sf->plain = g_strdup(plain);
1439
1440     g_ptr_array_add(string_fmts, sf);
1441 }
1442
1443 static gboolean
1444 parse_field_string_format(gchar *format) {
1445     GString *plain_s = g_string_new("");
1446     size_t len;
1447     size_t pos = 0;
1448
1449     if (!format) {
1450         return FALSE;
1451     }
1452
1453     len = strlen(format);
1454     g_ptr_array_set_size(string_fmts, 0);
1455
1456     while (pos < len) {
1457         if (format[pos] == '%') {
1458             if (pos >= len) { /* There should always be a following character */
1459                 return FALSE;
1460             }
1461             pos++;
1462             if (plain_s->len > 0) {
1463                 add_string_fmt(SF_NONE, plain_s->str);
1464                 g_string_truncate(plain_s, 0);
1465             }
1466             switch (format[pos]) {
1467                 case 'D':
1468                     add_string_fmt(SF_NAME, NULL);
1469                     break;
1470                 case 'N':
1471                     add_string_fmt(SF_NUMVAL, NULL);
1472                     break;
1473                 case 'S':
1474                     add_string_fmt(SF_STRVAL, NULL);
1475                     break;
1476                 case '%':
1477                     g_string_append_c(plain_s, '%');
1478                     break;
1479                 default: /* Invalid format */
1480                     return FALSE;
1481             }
1482         } else {
1483             g_string_append_c(plain_s, format[pos]);
1484         }
1485         pos++;
1486     }
1487
1488     if (plain_s->len > 0) {
1489         add_string_fmt(SF_NONE, plain_s->str);
1490     }
1491     g_string_free(plain_s, TRUE);
1492
1493     return TRUE;
1494 }
1495 /****************************************************************************************
1496  * END OF FIELD EXTRACTION ROUTINES
1497  ****************************************************************************************/
1498
1499 static void
1500 show_print_file_io_error(int err)
1501 {
1502     switch (err) {
1503
1504         case ENOSPC:
1505             cmdarg_err("Not all the packets could be printed because there is "
1506                        "no space left on the file system.");
1507             break;
1508
1509 #ifdef EDQUOT
1510         case EDQUOT:
1511             cmdarg_err("Not all the packets could be printed because you are "
1512                        "too close to, or over your disk quota.");
1513             break;
1514 #endif
1515
1516         default:
1517             cmdarg_err("An error occurred while printing packets: %s.",
1518                        strerror(err));
1519             break;
1520     }
1521 }
1522
1523 /*
1524  * Open/create errors are reported with an console message in Rawshark.
1525  */
1526 static void
1527 open_failure_message(const char *filename, int err, gboolean for_writing)
1528 {
1529     fprintf(stderr, "rawshark: ");
1530     fprintf(stderr, file_open_error_message(err, for_writing), filename);
1531     fprintf(stderr, "\n");
1532 }
1533
1534 cf_status_t
1535 raw_cf_open(capture_file *cf, const char *fname)
1536 {
1537     if ((fd = raw_pipe_open(fname)) < 0)
1538         return CF_ERROR;
1539
1540     /* The open succeeded.  Fill in the information for this file. */
1541
1542     /* Cleanup all data structures used for dissection. */
1543     cleanup_dissection();
1544     /* Initialize all data structures used for dissection. */
1545     init_dissection();
1546
1547     cf->wth = NULL;
1548     cf->f_datalen = 0; /* not used, but set it anyway */
1549
1550     /* Set the file name because we need it to set the follow stream filter.
1551        XXX - is that still true?  We need it for other reasons, though,
1552        in any case. */
1553     cf->filename = g_strdup(fname);
1554
1555     /* Indicate whether it's a permanent or temporary file. */
1556     cf->is_tempfile = FALSE;
1557
1558     /* If it's a temporary capture buffer file, mark it as not saved. */
1559     cf->user_saved = FALSE;
1560
1561     cf->cd_t      = WTAP_FILE_UNKNOWN;
1562     cf->count     = 0;
1563     cf->drops_known = FALSE;
1564     cf->drops     = 0;
1565     cf->has_snap = FALSE;
1566     cf->snap = WTAP_MAX_PACKET_SIZE;
1567     nstime_set_zero(&cf->elapsed_time);
1568     nstime_set_unset(&first_ts);
1569     nstime_set_unset(&prev_dis_ts);
1570     nstime_set_unset(&prev_cap_ts);
1571
1572     return CF_OK;
1573 }
1574
1575
1576 /*
1577  * General errors are reported with an console message in Rawshark.
1578  */
1579 static void
1580 failure_message(const char *msg_format, va_list ap)
1581 {
1582     fprintf(stderr, "rawshark: ");
1583     vfprintf(stderr, msg_format, ap);
1584     fprintf(stderr, "\n");
1585 }
1586
1587 /*
1588  * Read errors are reported with an console message in Rawshark.
1589  */
1590 static void
1591 read_failure_message(const char *filename, int err)
1592 {
1593     cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
1594                filename, strerror(err));
1595 }
1596
1597 /*
1598  * Write errors are reported with an console message in Rawshark.
1599  */
1600 static void
1601 write_failure_message(const char *filename, int err)
1602 {
1603     cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
1604                filename, strerror(err));
1605 }
1606
1607 /*
1608  * Report an error in command-line arguments.
1609  */
1610 void
1611 cmdarg_err(const char *fmt, ...)
1612 {
1613     va_list ap;
1614
1615     va_start(ap, fmt);
1616     fprintf(stderr, "rawshark: ");
1617     vfprintf(stderr, fmt, ap);
1618     fprintf(stderr, "\n");
1619     va_end(ap);
1620 }
1621
1622 /*
1623  * Report additional information for an error in command-line arguments.
1624  */
1625 void
1626 cmdarg_err_cont(const char *fmt, ...)
1627 {
1628     va_list ap;
1629
1630     va_start(ap, fmt);
1631     vfprintf(stderr, fmt, ap);
1632     fprintf(stderr, "\n");
1633     va_end(ap);
1634 }
1635
1636
1637 /****************************************************************************************************************/
1638 /* other "dummies" */
1639 void
1640 cf_mark_frame(capture_file *cf _U_, frame_data *frame _U_)
1641 {
1642     /* shouldn't happen */
1643     g_assert_not_reached();
1644 }
1645
1646 /*
1647  * Editor modelines
1648  *
1649  * Local Variables:
1650  * c-basic-offset: 4
1651  * tab-width: 8
1652  * indent-tabs-mode: nil
1653  * End:
1654  *
1655  * ex: set shiftwidth=4 tabstop=8 expandtab
1656  * :indentSize=4:tabSize=8:noTabs=true:
1657  */