ftypes: move get_value_uinteger64 into the union
[metze/wireshark/wip.git] / sharkd.c
1 /* sharkd.c
2  *
3  * Daemon variant of Wireshark
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include <config.h>
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <limits.h>
30 #include <errno.h>
31 #include <signal.h>
32
33 #include <glib.h>
34
35 #include <epan/exceptions.h>
36 #include <epan/epan-int.h>
37 #include <epan/epan.h>
38
39 #include <wsutil/clopts_common.h>
40 #include <wsutil/cmdarg_err.h>
41 #include <wsutil/crash_info.h>
42 #include <wsutil/filesystem.h>
43 #include <wsutil/file_util.h>
44 #include <wsutil/privileges.h>
45 #include <wsutil/report_err.h>
46 #include <ws_version_info.h>
47 #include <wiretap/wtap_opttypes.h>
48 #include <wiretap/pcapng.h>
49
50 #include <epan/decode_as.h>
51 #include <epan/timestamp.h>
52 #include <epan/packet.h>
53 #include "frame_tvbuff.h"
54 #include <epan/disabled_protos.h>
55 #include <epan/prefs.h>
56 #include <epan/column.h>
57 #include <epan/print.h>
58 #include <epan/addr_resolv.h>
59 #include "ui/util.h"
60 #include "ui/ui_util.h"
61 #include "ui/decode_as_utils.h"
62 #include "ui/tap_export_pdu.h"
63 #include "register.h"
64 #include "filter_files.h"
65 #include <epan/epan_dissect.h>
66 #include <epan/tap.h>
67
68 #include "log.h"
69
70 #include <wsutil/str_util.h>
71 #include <wsutil/utf8_entities.h>
72
73 #ifdef HAVE_PLUGINS
74 #include <wsutil/plugins.h>
75 #endif
76
77 #include "sharkd.h"
78
79 #define INIT_FAILED 1
80 #define EPAN_INIT_FAIL 2
81
82 static guint32 cum_bytes;
83 static const frame_data *ref;
84 static frame_data ref_frame;
85 static frame_data *prev_dis;
86 static frame_data *prev_cap;
87
88 static const char *cf_open_error_message(int err, gchar *err_info,
89     gboolean for_writing, int file_type);
90
91 static void open_failure_message(const char *filename, int err,
92     gboolean for_writing);
93 static void failure_message(const char *msg_format, va_list ap);
94 static void read_failure_message(const char *filename, int err);
95 static void write_failure_message(const char *filename, int err);
96 static void failure_message_cont(const char *msg_format, va_list ap);
97
98 capture_file cfile;
99
100 static void
101 print_current_user(void) {
102   gchar *cur_user, *cur_group;
103
104   if (started_with_special_privs()) {
105     cur_user = get_cur_username();
106     cur_group = get_cur_groupname();
107     fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
108       cur_user, cur_group);
109     g_free(cur_user);
110     g_free(cur_group);
111     if (running_with_special_privs()) {
112       fprintf(stderr, " This could be dangerous.");
113     }
114     fprintf(stderr, "\n");
115   }
116 }
117
118 int
119 main(int argc, char *argv[])
120 {
121   GString             *comp_info_str;
122   GString             *runtime_info_str;
123   char                *init_progfile_dir_error;
124
125   char                *gpf_path, *pf_path;
126   char                *gdp_path, *dp_path;
127   char                *cf_path;
128   char                *err_msg = NULL;
129   int                  gpf_open_errno, gpf_read_errno;
130   int                  pf_open_errno, pf_read_errno;
131   int                  gdp_open_errno, gdp_read_errno;
132   int                  dp_open_errno, dp_read_errno;
133   int                  cf_open_errno;
134   e_prefs             *prefs_p;
135   int                  ret = EXIT_SUCCESS;
136
137   cmdarg_err_init(failure_message, failure_message_cont);
138
139   /*
140    * Get credential information for later use, and drop privileges
141    * before doing anything else.
142    * Let the user know if anything happened.
143    */
144   init_process_policies();
145   relinquish_special_privs_perm();
146   print_current_user();
147
148   /*
149    * Attempt to get the pathname of the executable file.
150    */
151   init_progfile_dir_error = init_progfile_dir(argv[0], main);
152   if (init_progfile_dir_error != NULL) {
153     fprintf(stderr, "sharkd: Can't get pathname of sharkd program: %s.\n",
154             init_progfile_dir_error);
155   }
156
157   /* Get the compile-time version information string */
158   comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
159
160   /* Get the run-time version information string */
161   runtime_info_str = get_runtime_version_info(epan_get_runtime_version_info);
162
163   /* Add it to the information to be reported on a crash. */
164   ws_add_crash_info("Sharkd (Wireshark) %s\n"
165          "\n"
166          "%s"
167          "\n"
168          "%s",
169       get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
170   g_string_free(comp_info_str, TRUE);
171   g_string_free(runtime_info_str, TRUE);
172
173   if (sharkd_init(argc, argv) < 0)
174   {
175     printf("cannot initialize sharkd\n");
176     ret = INIT_FAILED;
177     goto clean_exit;
178   }
179
180   init_report_err(failure_message, open_failure_message, read_failure_message,
181                   write_failure_message);
182
183   timestamp_set_type(TS_RELATIVE);
184   timestamp_set_precision(TS_PREC_AUTO);
185   timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
186
187   wtap_init();
188
189 #ifdef HAVE_PLUGINS
190   /* Register all the plugin types we have. */
191   epan_register_plugin_types(); /* Types known to libwireshark */
192
193   /* Scan for plugins.  This does *not* call their registration routines;
194      that's done later. */
195   scan_plugins(REPORT_LOAD_FAILURE);
196
197   /* Register all libwiretap plugin modules. */
198   register_all_wiretap_modules();
199 #endif
200
201   /* Register all dissectors; we must do this before checking for the
202      "-G" flag, as the "-G" flag dumps information registered by the
203      dissectors, and we must do it before we read the preferences, in
204      case any dissectors register preferences. */
205   if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
206                  NULL)) {
207     ret = EPAN_INIT_FAIL;
208     goto clean_exit;
209   }
210
211   /* load the decode as entries of this profile */
212   load_decode_as_entries();
213
214   prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
215                      &pf_open_errno, &pf_read_errno, &pf_path);
216   if (gpf_path != NULL) {
217     if (gpf_open_errno != 0) {
218       cmdarg_err("Can't open global preferences file \"%s\": %s.",
219               pf_path, g_strerror(gpf_open_errno));
220     }
221     if (gpf_read_errno != 0) {
222       cmdarg_err("I/O error reading global preferences file \"%s\": %s.",
223               pf_path, g_strerror(gpf_read_errno));
224     }
225   }
226   if (pf_path != NULL) {
227     if (pf_open_errno != 0) {
228       cmdarg_err("Can't open your preferences file \"%s\": %s.", pf_path,
229               g_strerror(pf_open_errno));
230     }
231     if (pf_read_errno != 0) {
232       cmdarg_err("I/O error reading your preferences file \"%s\": %s.",
233               pf_path, g_strerror(pf_read_errno));
234     }
235     g_free(pf_path);
236     pf_path = NULL;
237   }
238
239   read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
240   if (cf_path != NULL) {
241       cmdarg_err("Could not open your capture filter file\n\"%s\": %s.",
242           cf_path, g_strerror(cf_open_errno));
243       g_free(cf_path);
244   }
245
246   if (!color_filters_init(&err_msg, NULL)) {
247      fprintf(stderr, "color_filters_init() failed %s\n", err_msg);
248      g_free(err_msg);
249   }
250
251   /* Read the disabled protocols file. */
252   read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
253                             &dp_path, &dp_open_errno, &dp_read_errno);
254   read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
255                             &dp_path, &dp_open_errno, &dp_read_errno);
256   if (gdp_path != NULL) {
257     if (gdp_open_errno != 0) {
258       cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
259                  gdp_path, g_strerror(gdp_open_errno));
260     }
261     if (gdp_read_errno != 0) {
262       cmdarg_err("I/O error reading global disabled protocols file\n\"%s\": %s.",
263                  gdp_path, g_strerror(gdp_read_errno));
264     }
265     g_free(gdp_path);
266   }
267   if (dp_path != NULL) {
268     if (dp_open_errno != 0) {
269       cmdarg_err(
270         "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
271         g_strerror(dp_open_errno));
272     }
273     if (dp_read_errno != 0) {
274       cmdarg_err(
275         "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
276         g_strerror(dp_read_errno));
277     }
278     g_free(dp_path);
279   }
280
281   cap_file_init(&cfile);
282
283   /* Notify all registered modules that have had any of their preferences
284      changed either from one of the preferences file or from the command
285      line that their preferences have changed. */
286   prefs_apply_all();
287
288   /* disabled protocols as per configuration file */
289   if (gdp_path == NULL && dp_path == NULL) {
290     set_disabled_protos_list();
291     set_disabled_heur_dissector_list();
292   }
293
294   /* Build the column format array */
295   build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
296
297   ret = sharkd_loop();
298 clean_exit:
299   col_cleanup(&cfile.cinfo);
300   free_filter_lists();
301   wtap_cleanup();
302   free_progdirs();
303 #ifdef HAVE_PLUGINS
304   plugins_cleanup();
305 #endif
306   return ret;
307 }
308
309 static const nstime_t *
310 sharkd_get_frame_ts(void *data, guint32 frame_num)
311 {
312   capture_file *cf = (capture_file *) data;
313
314   if (ref && ref->num == frame_num)
315     return &ref->abs_ts;
316
317   if (prev_dis && prev_dis->num == frame_num)
318     return &prev_dis->abs_ts;
319
320   if (prev_cap && prev_cap->num == frame_num)
321     return &prev_cap->abs_ts;
322
323   if (cf->frames) {
324      frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
325
326      return (fd) ? &fd->abs_ts : NULL;
327   }
328
329   return NULL;
330 }
331
332 static epan_t *
333 sharkd_epan_new(capture_file *cf)
334 {
335   epan_t *epan = epan_new();
336
337   epan->data = cf;
338   epan->get_frame_ts = sharkd_get_frame_ts;
339   epan->get_interface_name = cap_file_get_interface_name;
340   epan->get_interface_description = cap_file_get_interface_description;
341   epan->get_user_comment = NULL;
342
343   return epan;
344 }
345
346 static gboolean
347 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
348                gint64 offset, struct wtap_pkthdr *whdr,
349                const guchar *pd)
350 {
351   frame_data     fdlocal;
352   guint32        framenum;
353   gboolean       passed;
354
355   /* The frame number of this packet is one more than the count of
356      frames in this packet. */
357   framenum = cf->count + 1;
358
359   /* If we're not running a display filter and we're not printing any
360      packet information, we don't need to do a dissection. This means
361      that all packets can be marked as 'passed'. */
362   passed = TRUE;
363
364   frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
365
366   /* If we're going to print packet information, or we're going to
367      run a read filter, or display filter, or we're going to process taps, set up to
368      do a dissection and do so. */
369   if (edt) {
370     if (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
371         gbl_resolv_flags.transport_name)
372       /* Grab any resolved addresses */
373       host_name_lookup_process();
374
375     /* If we're running a read filter, prime the epan_dissect_t with that
376        filter. */
377     if (cf->rfcode)
378       epan_dissect_prime_dfilter(edt, cf->rfcode);
379
380     if (cf->dfcode)
381       epan_dissect_prime_dfilter(edt, cf->dfcode);
382
383     frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
384                                   &ref, prev_dis);
385     if (ref == &fdlocal) {
386       ref_frame = fdlocal;
387       ref = &ref_frame;
388     }
389
390     epan_dissect_run(edt, cf->cd_t, whdr, frame_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
391
392     /* Run the read filter if we have one. */
393     if (cf->rfcode)
394       passed = dfilter_apply_edt(cf->rfcode, edt);
395   }
396
397   if (passed) {
398     frame_data_set_after_dissect(&fdlocal, &cum_bytes);
399     prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
400
401     /* If we're not doing dissection then there won't be any dependent frames.
402      * More importantly, edt.pi.dependent_frames won't be initialized because
403      * epan hasn't been initialized.
404      * if we *are* doing dissection, then mark the dependent frames, but only
405      * if a display filter was given and it matches this packet.
406      */
407     if (edt && cf->dfcode) {
408       if (dfilter_apply_edt(cf->dfcode, edt)) {
409         g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
410       }
411     }
412
413     cf->count++;
414   } else {
415     /* if we don't add it to the frame_data_sequence, clean it up right now
416      * to avoid leaks */
417     frame_data_destroy(&fdlocal);
418   }
419
420   if (edt)
421     epan_dissect_reset(edt);
422
423   return passed;
424 }
425
426
427 static int
428 load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
429 {
430   int          err;
431   gchar       *err_info = NULL;
432   gint64       data_offset;
433   epan_dissect_t *edt = NULL;
434
435   {
436     /* Allocate a frame_data_sequence for all the frames. */
437     cf->frames = new_frame_data_sequence();
438
439     {
440        gboolean create_proto_tree = FALSE;
441
442       /* If we're going to be applying a filter, we'll need to
443          create a protocol tree against which to apply the filter. */
444       if (cf->rfcode || cf->dfcode)
445         create_proto_tree = TRUE;
446
447       /* We're not going to display the protocol tree on this pass,
448          so it's not going to be "visible". */
449       edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
450     }
451
452     while (wtap_read(cf->wth, &err, &err_info, &data_offset)) {
453       if (process_packet_first_pass(cf, edt, data_offset, wtap_phdr(cf->wth),
454                          wtap_buf_ptr(cf->wth))) {
455         /* Stop reading if we have the maximum number of packets;
456          * When the -c option has not been used, max_packet_count
457          * starts at 0, which practically means, never stop reading.
458          * (unless we roll over max_packet_count ?)
459          */
460         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
461           err = 0; /* This is not an error */
462           break;
463         }
464       }
465     }
466
467     if (edt) {
468       epan_dissect_free(edt);
469       edt = NULL;
470     }
471
472     /* Close the sequential I/O side, to free up memory it requires. */
473     wtap_sequential_close(cf->wth);
474
475     /* Allow the protocol dissectors to free up memory that they
476      * don't need after the sequential run-through of the packets. */
477     postseq_cleanup_all_protocols();
478
479     prev_dis = NULL;
480     prev_cap = NULL;
481   }
482
483   if (err != 0) {
484     switch (err) {
485
486     case WTAP_ERR_UNSUPPORTED:
487       cmdarg_err("The file \"%s\" contains record data that TShark doesn't support.\n(%s)",
488                  cf->filename,
489                  err_info != NULL ? err_info : "no information supplied");
490       g_free(err_info);
491       break;
492
493     case WTAP_ERR_SHORT_READ:
494       cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
495                  cf->filename);
496       break;
497
498     case WTAP_ERR_BAD_FILE:
499       cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
500                  cf->filename,
501                  err_info != NULL ? err_info : "no information supplied");
502       g_free(err_info);
503       break;
504
505     case WTAP_ERR_DECOMPRESS:
506       cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
507                  "(%s)", cf->filename,
508                  err_info != NULL ? err_info : "no information supplied");
509       g_free(err_info);
510       break;
511
512     default:
513       cmdarg_err("An error occurred while reading the file \"%s\": %s.",
514                  cf->filename, wtap_strerror(err));
515       break;
516     }
517   }
518
519   return err;
520 }
521
522 cf_status_t
523 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
524 {
525   wtap  *wth;
526   gchar *err_info;
527   char   err_msg[2048+1];
528
529   wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
530   if (wth == NULL)
531     goto fail;
532
533   /* The open succeeded.  Fill in the information for this file. */
534
535   /* Create new epan session for dissection. */
536   epan_free(cf->epan);
537   cf->epan = sharkd_epan_new(cf);
538
539   cf->wth = wth;
540   cf->f_datalen = 0; /* not used, but set it anyway */
541
542   /* Set the file name because we need it to set the follow stream filter.
543      XXX - is that still true?  We need it for other reasons, though,
544      in any case. */
545   cf->filename = g_strdup(fname);
546
547   /* Indicate whether it's a permanent or temporary file. */
548   cf->is_tempfile = is_tempfile;
549
550   /* No user changes yet. */
551   cf->unsaved_changes = FALSE;
552
553   cf->cd_t      = wtap_file_type_subtype(cf->wth);
554   cf->open_type = type;
555   cf->count     = 0;
556   cf->drops_known = FALSE;
557   cf->drops     = 0;
558   cf->snap      = wtap_snapshot_length(cf->wth);
559   if (cf->snap == 0) {
560     /* Snapshot length not known. */
561     cf->has_snap = FALSE;
562     cf->snap = WTAP_MAX_PACKET_SIZE;
563   } else
564     cf->has_snap = TRUE;
565   nstime_set_zero(&cf->elapsed_time);
566   ref = NULL;
567   prev_dis = NULL;
568   prev_cap = NULL;
569
570   cf->state = FILE_READ_IN_PROGRESS;
571
572   wtap_set_cb_new_ipv4(cf->wth, add_ipv4_name);
573   wtap_set_cb_new_ipv6(cf->wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
574
575   return CF_OK;
576
577 fail:
578   g_snprintf(err_msg, sizeof err_msg,
579              cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
580   cmdarg_err("%s", err_msg);
581   return CF_ERROR;
582 }
583
584 static const char *
585 cf_open_error_message(int err, gchar *err_info, gboolean for_writing,
586                       int file_type)
587 {
588   const char *errmsg;
589   static char errmsg_errno[1024+1];
590
591   if (err < 0) {
592     /* Wiretap error. */
593     switch (err) {
594
595     case WTAP_ERR_NOT_REGULAR_FILE:
596       errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
597       break;
598
599     case WTAP_ERR_RANDOM_OPEN_PIPE:
600       /* Seen only when opening a capture file for reading. */
601       errmsg = "The file \"%s\" is a pipe or FIFO; TShark can't read pipe or FIFO files in two-pass mode.";
602       break;
603
604     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
605       /* Seen only when opening a capture file for reading. */
606       errmsg = "The file \"%s\" isn't a capture file in a format TShark understands.";
607       break;
608
609     case WTAP_ERR_UNSUPPORTED:
610       /* Seen only when opening a capture file for reading. */
611       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
612                  "The file \"%%s\" contains record data that TShark doesn't support.\n"
613                  "(%s)",
614                  err_info != NULL ? err_info : "no information supplied");
615       g_free(err_info);
616       errmsg = errmsg_errno;
617       break;
618
619     case WTAP_ERR_CANT_WRITE_TO_PIPE:
620       /* Seen only when opening a capture file for writing. */
621       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
622                  "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
623                  "written to a pipe.", wtap_file_type_subtype_short_string(file_type));
624       errmsg = errmsg_errno;
625       break;
626
627     case WTAP_ERR_UNWRITABLE_FILE_TYPE:
628       /* Seen only when opening a capture file for writing. */
629       errmsg = "TShark doesn't support writing capture files in that format.";
630       break;
631
632     case WTAP_ERR_UNWRITABLE_ENCAP:
633       /* Seen only when opening a capture file for writing. */
634       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
635                  "TShark can't save this capture as a \"%s\" file.",
636                  wtap_file_type_subtype_short_string(file_type));
637       errmsg = errmsg_errno;
638       break;
639
640     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
641       if (for_writing) {
642         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
643                    "TShark can't save this capture as a \"%s\" file.",
644                    wtap_file_type_subtype_short_string(file_type));
645         errmsg = errmsg_errno;
646       } else
647         errmsg = "The file \"%s\" is a capture for a network type that TShark doesn't support.";
648       break;
649
650     case WTAP_ERR_BAD_FILE:
651       /* Seen only when opening a capture file for reading. */
652       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
653                  "The file \"%%s\" appears to be damaged or corrupt.\n"
654                  "(%s)",
655                  err_info != NULL ? err_info : "no information supplied");
656       g_free(err_info);
657       errmsg = errmsg_errno;
658       break;
659
660     case WTAP_ERR_CANT_OPEN:
661       if (for_writing)
662         errmsg = "The file \"%s\" could not be created for some unknown reason.";
663       else
664         errmsg = "The file \"%s\" could not be opened for some unknown reason.";
665       break;
666
667     case WTAP_ERR_SHORT_READ:
668       errmsg = "The file \"%s\" appears to have been cut short"
669                " in the middle of a packet or other data.";
670       break;
671
672     case WTAP_ERR_SHORT_WRITE:
673       errmsg = "A full header couldn't be written to the file \"%s\".";
674       break;
675
676     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
677       errmsg = "This file type cannot be written as a compressed file.";
678       break;
679
680     case WTAP_ERR_DECOMPRESS:
681       /* Seen only when opening a capture file for reading. */
682       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
683                  "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
684                  "(%s)",
685                  err_info != NULL ? err_info : "no information supplied");
686       g_free(err_info);
687       errmsg = errmsg_errno;
688       break;
689
690     default:
691       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
692                  "The file \"%%s\" could not be %s: %s.",
693                  for_writing ? "created" : "opened",
694                  wtap_strerror(err));
695       errmsg = errmsg_errno;
696       break;
697     }
698   } else
699     errmsg = file_open_error_message(err, for_writing);
700   return errmsg;
701 }
702
703 /*
704  * Open/create errors are reported with an console message in TShark.
705  */
706 static void
707 open_failure_message(const char *filename, int err, gboolean for_writing)
708 {
709   fprintf(stderr, "sharkd: ");
710   fprintf(stderr, file_open_error_message(err, for_writing), filename);
711   fprintf(stderr, "\n");
712 }
713
714 /*
715  * General errors are reported with an console message in TShark.
716  */
717 static void
718 failure_message(const char *msg_format, va_list ap)
719 {
720   fprintf(stderr, "sharkd: ");
721   vfprintf(stderr, msg_format, ap);
722   fprintf(stderr, "\n");
723 }
724
725 /*
726  * Read errors are reported with an console message in TShark.
727  */
728 static void
729 read_failure_message(const char *filename, int err)
730 {
731   cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
732           filename, g_strerror(err));
733 }
734
735 /*
736  * Write errors are reported with an console message in TShark.
737  */
738 static void
739 write_failure_message(const char *filename, int err)
740 {
741   cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
742           filename, g_strerror(err));
743 }
744
745 /*
746  * Report additional information for an error in command-line arguments.
747  */
748 static void
749 failure_message_cont(const char *msg_format, va_list ap)
750 {
751   vfprintf(stderr, msg_format, ap);
752   fprintf(stderr, "\n");
753 }
754
755 cf_status_t
756 sharkd_cf_open(const char *fname, unsigned int type, gboolean is_tempfile, int *err)
757 {
758   return cf_open(&cfile, fname, type, is_tempfile, err);
759 }
760
761 int
762 sharkd_load_cap_file(void)
763 {
764   return load_cap_file(&cfile, 0, 0);
765 }
766
767 int
768 sharkd_dissect_request(unsigned int framenum, void (*cb)(packet_info *, proto_tree *, struct epan_column_info *, const GSList *, void *), int dissect_bytes, int dissect_columns, int dissect_tree, void *data)
769 {
770   frame_data *fdata;
771   column_info *cinfo = (dissect_columns) ? &cfile.cinfo : NULL;
772   epan_dissect_t edt;
773   gboolean create_proto_tree;
774   struct wtap_pkthdr phdr; /* Packet header */
775   Buffer buf; /* Packet data */
776
777   int err;
778   char *err_info = NULL;
779
780   fdata = frame_data_sequence_find(cfile.frames, framenum);
781   if (fdata == NULL)
782     return -1;
783
784   wtap_phdr_init(&phdr);
785   ws_buffer_init(&buf, 1500);
786
787   if (!wtap_seek_read(cfile.wth, fdata->file_off, &phdr, &buf, &err, &err_info)) {
788     ws_buffer_free(&buf);
789     return -1; /* error reading the record */
790   }
791
792   create_proto_tree = (dissect_tree) || (cinfo && have_custom_cols(cinfo));
793   epan_dissect_init(&edt, cfile.epan, create_proto_tree, dissect_tree);
794
795   if (cinfo)
796     col_custom_prime_edt(&edt, cinfo);
797
798   /*
799    * XXX - need to catch an OutOfMemoryError exception and
800    * attempt to recover from it.
801    */
802   epan_dissect_run(&edt, cfile.cd_t, &phdr, frame_tvbuff_new_buffer(fdata, &buf), fdata, cinfo);
803
804   if (cinfo) {
805     /* "Stringify" non frame_data vals */
806     epan_dissect_fill_in_columns(&edt, FALSE, TRUE/* fill_fd_columns */);
807   }
808
809   cb(&edt.pi, dissect_tree ? edt.tree : NULL, cinfo, dissect_bytes ? edt.pi.data_src : NULL, data);
810
811   epan_dissect_cleanup(&edt);
812   wtap_phdr_cleanup(&phdr);
813   ws_buffer_free(&buf);
814   return 0;
815 }
816
817 /* based on packet_list_dissect_and_cache_record */
818 int
819 sharkd_dissect_columns(int framenum, column_info *cinfo, gboolean dissect_color)
820 {
821   frame_data *fdata;
822   epan_dissect_t edt;
823   gboolean create_proto_tree;
824   struct wtap_pkthdr phdr; /* Packet header */
825   Buffer buf; /* Packet data */
826
827   int err;
828   char *err_info = NULL;
829
830   fdata = frame_data_sequence_find(cfile.frames, framenum);
831   if (fdata == NULL) {
832     col_fill_in_error(cinfo, fdata, FALSE, TRUE/* fill_fd_columns */);
833     return -1; /* error reading the record */
834   }
835
836   wtap_phdr_init(&phdr);
837   ws_buffer_init(&buf, 1500);
838
839   if (!wtap_seek_read(cfile.wth, fdata->file_off, &phdr, &buf, &err, &err_info)) {
840     col_fill_in_error(cinfo, fdata, FALSE, FALSE /* fill_fd_columns */);
841     ws_buffer_free(&buf);
842     return -1; /* error reading the record */
843   }
844
845   create_proto_tree = (dissect_color && color_filters_used()) || (cinfo && have_custom_cols(cinfo));
846
847   epan_dissect_init(&edt, cfile.epan, create_proto_tree, FALSE /* proto_tree_visible */);
848
849   if (dissect_color) {
850     color_filters_prime_edt(&edt);
851     fdata->flags.need_colorize = 1;
852   }
853
854   if (cinfo)
855     col_custom_prime_edt(&edt, cinfo);
856
857   /*
858    * XXX - need to catch an OutOfMemoryError exception and
859    * attempt to recover from it.
860    */
861   epan_dissect_run(&edt, cfile.cd_t, &phdr, frame_tvbuff_new_buffer(fdata, &buf), fdata, cinfo);
862
863   if (cinfo) {
864     /* "Stringify" non frame_data vals */
865     epan_dissect_fill_in_columns(&edt, FALSE, TRUE/* fill_fd_columns */);
866   }
867
868   epan_dissect_cleanup(&edt);
869   wtap_phdr_cleanup(&phdr);
870   ws_buffer_free(&buf);
871   return 0;
872 }
873
874 int
875 sharkd_retap(void)
876 {
877   guint32          framenum;
878   frame_data      *fdata;
879   Buffer           buf;
880   struct wtap_pkthdr phdr;
881   int err;
882   char *err_info = NULL;
883
884   gboolean      filtering_tap_listeners;
885   guint         tap_flags;
886   gboolean      construct_protocol_tree;
887   epan_dissect_t edt;
888   column_info   *cinfo;
889
890   filtering_tap_listeners = have_filtering_tap_listeners();
891   tap_flags = union_of_tap_listener_flags();
892
893   construct_protocol_tree = filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE);
894   cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cfile.cinfo : NULL;
895
896   wtap_phdr_init(&phdr);
897   ws_buffer_init(&buf, 1500);
898   epan_dissect_init(&edt, cfile.epan, construct_protocol_tree, FALSE);
899
900   reset_tap_listeners();
901
902   for (framenum = 1; framenum <= cfile.count; framenum++) {
903     fdata = frame_data_sequence_find(cfile.frames, framenum);
904
905     if (!wtap_seek_read(cfile.wth, fdata->file_off, &phdr, &buf, &err, &err_info))
906       break;
907
908     epan_dissect_run_with_taps(&edt, cfile.cd_t, &phdr, frame_tvbuff_new(fdata, ws_buffer_start_ptr(&buf)), fdata, cinfo);
909     epan_dissect_reset(&edt);
910   }
911
912   wtap_phdr_cleanup(&phdr);
913   ws_buffer_free(&buf);
914   epan_dissect_cleanup(&edt);
915
916   draw_tap_listeners(TRUE);
917
918   return 0;
919 }
920
921 int
922 sharkd_filter(const char *dftext, guint8 **result)
923 {
924   dfilter_t  *dfcode = NULL;
925
926   guint32 framenum;
927   guint32 frames_count;
928   Buffer buf;
929   struct wtap_pkthdr phdr;
930   int err;
931   char *err_info = NULL;
932
933   guint8 *result_bits;
934   guint8  passed_bits;
935
936   epan_dissect_t edt;
937
938   if (!dfilter_compile(dftext, &dfcode, &err_info)) {
939     g_free(err_info);
940     return -1;
941   }
942
943   frames_count = cfile.count;
944
945   wtap_phdr_init(&phdr);
946   ws_buffer_init(&buf, 1500);
947   epan_dissect_init(&edt, cfile.epan, TRUE, FALSE);
948
949   passed_bits = 0;
950   result_bits = (guint8 *) g_malloc(2 + (frames_count / 8));
951
952   for (framenum = 1; framenum <= frames_count; framenum++) {
953     frame_data *fdata = frame_data_sequence_find(cfile.frames, framenum);
954
955     if ((framenum & 7) == 0) {
956       result_bits[(framenum / 8) - 1] = passed_bits;
957       passed_bits = 0;
958     }
959
960     if (!wtap_seek_read(cfile.wth, fdata->file_off, &phdr, &buf, &err, &err_info))
961       break;
962
963     /* frame_data_set_before_dissect */
964     epan_dissect_prime_dfilter(&edt, dfcode);
965
966     epan_dissect_run(&edt, cfile.cd_t, &phdr, frame_tvbuff_new_buffer(fdata, &buf), fdata, NULL);
967
968     if (dfilter_apply_edt(dfcode, &edt))
969       passed_bits |= (1 << (framenum % 8));
970
971     /* if passed or ref -> frame_data_set_after_dissect */
972
973     epan_dissect_reset(&edt);
974   }
975
976   if ((framenum & 7) == 0)
977       framenum--;
978   result_bits[framenum / 8] = passed_bits;
979
980   wtap_phdr_cleanup(&phdr);
981   ws_buffer_free(&buf);
982   epan_dissect_cleanup(&edt);
983
984   dfilter_free(dfcode);
985
986   *result = result_bits;
987
988   return framenum;
989 }
990
991 #include "version.h"
992 const char *sharkd_version(void)
993 {
994   /* based on get_ws_vcs_version_info(), but shorter */
995 #ifdef VCSVERSION
996   return VCSVERSION;
997 #else
998   return VERSION;
999 #endif
1000 }
1001
1002 /*
1003  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1004  *
1005  * Local variables:
1006  * c-basic-offset: 2
1007  * tab-width: 8
1008  * indent-tabs-mode: nil
1009  * End:
1010  *
1011  * vi: set shiftwidth=2 tabstop=8 expandtab:
1012  * :indentSize=2:tabSize=8:noTabs=true:
1013  */