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