3 * Daemon variant of Wireshark
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
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.
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.
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.
35 #include <epan/exceptions.h>
36 #include <epan/epan-int.h>
37 #include <epan/epan.h>
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>
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>
60 #include "ui/ui_util.h"
61 #include "ui/decode_as_utils.h"
62 #include "ui/tap_export_pdu.h"
64 #include "filter_files.h"
65 #include <epan/epan_dissect.h>
70 #include <wsutil/str_util.h>
71 #include <wsutil/utf8_entities.h>
74 #include <wsutil/plugins.h>
80 #define EPAN_INIT_FAIL 2
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;
88 static const char *cf_open_error_message(int err, gchar *err_info,
89 gboolean for_writing, int file_type);
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);
101 print_current_user(void) {
102 gchar *cur_user, *cur_group;
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);
111 if (running_with_special_privs()) {
112 fprintf(stderr, " This could be dangerous.");
114 fprintf(stderr, "\n");
119 main(int argc, char *argv[])
121 GString *comp_info_str;
122 GString *runtime_info_str;
123 char *init_progfile_dir_error;
125 char *gpf_path, *pf_path;
126 char *gdp_path, *dp_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;
135 int ret = EXIT_SUCCESS;
137 cmdarg_err_init(failure_message, failure_message_cont);
140 * Get credential information for later use, and drop privileges
141 * before doing anything else.
142 * Let the user know if anything happened.
144 init_process_policies();
145 relinquish_special_privs_perm();
146 print_current_user();
149 * Attempt to get the pathname of the executable file.
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);
157 /* Get the compile-time version information string */
158 comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
160 /* Get the run-time version information string */
161 runtime_info_str = get_runtime_version_info(epan_get_runtime_version_info);
163 /* Add it to the information to be reported on a crash. */
164 ws_add_crash_info("Sharkd (Wireshark) %s\n"
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);
173 if (sharkd_init(argc, argv) < 0)
175 printf("cannot initialize sharkd\n");
180 init_report_err(failure_message, open_failure_message, read_failure_message,
181 write_failure_message);
183 timestamp_set_type(TS_RELATIVE);
184 timestamp_set_precision(TS_PREC_AUTO);
185 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
190 /* Register all the plugin types we have. */
191 epan_register_plugin_types(); /* Types known to libwireshark */
193 /* Scan for plugins. This does *not* call their registration routines;
194 that's done later. */
195 scan_plugins(REPORT_LOAD_FAILURE);
197 /* Register all libwiretap plugin modules. */
198 register_all_wiretap_modules();
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,
207 ret = EPAN_INIT_FAIL;
211 /* load the decode as entries of this profile */
212 load_decode_as_entries();
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));
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));
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));
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));
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));
246 if (!color_filters_init(&err_msg, NULL)) {
247 fprintf(stderr, "color_filters_init() failed %s\n", err_msg);
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));
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));
267 if (dp_path != NULL) {
268 if (dp_open_errno != 0) {
270 "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
271 g_strerror(dp_open_errno));
273 if (dp_read_errno != 0) {
275 "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
276 g_strerror(dp_read_errno));
281 cap_file_init(&cfile);
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. */
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();
294 /* Build the column format array */
295 build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
299 col_cleanup(&cfile.cinfo);
309 static const nstime_t *
310 sharkd_get_frame_ts(void *data, guint32 frame_num)
312 capture_file *cf = (capture_file *) data;
314 if (ref && ref->num == frame_num)
317 if (prev_dis && prev_dis->num == frame_num)
318 return &prev_dis->abs_ts;
320 if (prev_cap && prev_cap->num == frame_num)
321 return &prev_cap->abs_ts;
324 frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
326 return (fd) ? &fd->abs_ts : NULL;
333 sharkd_epan_new(capture_file *cf)
335 epan_t *epan = epan_new();
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;
347 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
348 gint64 offset, struct wtap_pkthdr *whdr,
355 /* The frame number of this packet is one more than the count of
356 frames in this packet. */
357 framenum = cf->count + 1;
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'. */
364 frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
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. */
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();
375 /* If we're running a read filter, prime the epan_dissect_t with that
378 epan_dissect_prime_dfilter(edt, cf->rfcode);
381 epan_dissect_prime_dfilter(edt, cf->dfcode);
383 frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
385 if (ref == &fdlocal) {
390 epan_dissect_run(edt, cf->cd_t, whdr, frame_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
392 /* Run the read filter if we have one. */
394 passed = dfilter_apply_edt(cf->rfcode, edt);
398 frame_data_set_after_dissect(&fdlocal, &cum_bytes);
399 prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
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.
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);
415 /* if we don't add it to the frame_data_sequence, clean it up right now
417 frame_data_destroy(&fdlocal);
421 epan_dissect_reset(edt);
428 load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
431 gchar *err_info = NULL;
433 epan_dissect_t *edt = NULL;
436 /* Allocate a frame_data_sequence for all the frames. */
437 cf->frames = new_frame_data_sequence();
440 gboolean create_proto_tree = FALSE;
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;
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);
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 ?)
460 if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
461 err = 0; /* This is not an error */
468 epan_dissect_free(edt);
472 /* Close the sequential I/O side, to free up memory it requires. */
473 wtap_sequential_close(cf->wth);
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();
486 case WTAP_ERR_UNSUPPORTED:
487 cmdarg_err("The file \"%s\" contains record data that TShark doesn't support.\n(%s)",
489 err_info != NULL ? err_info : "no information supplied");
493 case WTAP_ERR_SHORT_READ:
494 cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
498 case WTAP_ERR_BAD_FILE:
499 cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
501 err_info != NULL ? err_info : "no information supplied");
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");
513 cmdarg_err("An error occurred while reading the file \"%s\": %s.",
514 cf->filename, wtap_strerror(err));
523 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
527 char err_msg[2048+1];
529 wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
533 /* The open succeeded. Fill in the information for this file. */
535 /* Create new epan session for dissection. */
537 cf->epan = sharkd_epan_new(cf);
540 cf->f_datalen = 0; /* not used, but set it anyway */
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,
545 cf->filename = g_strdup(fname);
547 /* Indicate whether it's a permanent or temporary file. */
548 cf->is_tempfile = is_tempfile;
550 /* No user changes yet. */
551 cf->unsaved_changes = FALSE;
553 cf->cd_t = wtap_file_type_subtype(cf->wth);
554 cf->open_type = type;
556 cf->drops_known = FALSE;
558 cf->snap = wtap_snapshot_length(cf->wth);
560 /* Snapshot length not known. */
561 cf->has_snap = FALSE;
562 cf->snap = WTAP_MAX_PACKET_SIZE;
565 nstime_set_zero(&cf->elapsed_time);
570 cf->state = FILE_READ_IN_PROGRESS;
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);
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);
585 cf_open_error_message(int err, gchar *err_info, gboolean for_writing,
589 static char errmsg_errno[1024+1];
595 case WTAP_ERR_NOT_REGULAR_FILE:
596 errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
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.";
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.";
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"
614 err_info != NULL ? err_info : "no information supplied");
616 errmsg = errmsg_errno;
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;
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.";
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;
640 case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
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;
647 errmsg = "The file \"%s\" is a capture for a network type that TShark doesn't support.";
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"
655 err_info != NULL ? err_info : "no information supplied");
657 errmsg = errmsg_errno;
660 case WTAP_ERR_CANT_OPEN:
662 errmsg = "The file \"%s\" could not be created for some unknown reason.";
664 errmsg = "The file \"%s\" could not be opened for some unknown reason.";
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.";
672 case WTAP_ERR_SHORT_WRITE:
673 errmsg = "A full header couldn't be written to the file \"%s\".";
676 case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
677 errmsg = "This file type cannot be written as a compressed file.";
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"
685 err_info != NULL ? err_info : "no information supplied");
687 errmsg = errmsg_errno;
691 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
692 "The file \"%%s\" could not be %s: %s.",
693 for_writing ? "created" : "opened",
695 errmsg = errmsg_errno;
699 errmsg = file_open_error_message(err, for_writing);
704 * Open/create errors are reported with an console message in TShark.
707 open_failure_message(const char *filename, int err, gboolean for_writing)
709 fprintf(stderr, "sharkd: ");
710 fprintf(stderr, file_open_error_message(err, for_writing), filename);
711 fprintf(stderr, "\n");
715 * General errors are reported with an console message in TShark.
718 failure_message(const char *msg_format, va_list ap)
720 fprintf(stderr, "sharkd: ");
721 vfprintf(stderr, msg_format, ap);
722 fprintf(stderr, "\n");
726 * Read errors are reported with an console message in TShark.
729 read_failure_message(const char *filename, int err)
731 cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
732 filename, g_strerror(err));
736 * Write errors are reported with an console message in TShark.
739 write_failure_message(const char *filename, int err)
741 cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
742 filename, g_strerror(err));
746 * Report additional information for an error in command-line arguments.
749 failure_message_cont(const char *msg_format, va_list ap)
751 vfprintf(stderr, msg_format, ap);
752 fprintf(stderr, "\n");
756 sharkd_cf_open(const char *fname, unsigned int type, gboolean is_tempfile, int *err)
758 return cf_open(&cfile, fname, type, is_tempfile, err);
762 sharkd_load_cap_file(void)
764 return load_cap_file(&cfile, 0, 0);
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)
771 column_info *cinfo = (dissect_columns) ? &cfile.cinfo : NULL;
773 gboolean create_proto_tree;
774 struct wtap_pkthdr phdr; /* Packet header */
775 Buffer buf; /* Packet data */
778 char *err_info = NULL;
780 fdata = frame_data_sequence_find(cfile.frames, framenum);
784 wtap_phdr_init(&phdr);
785 ws_buffer_init(&buf, 1500);
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 */
792 create_proto_tree = (dissect_tree) || (cinfo && have_custom_cols(cinfo));
793 epan_dissect_init(&edt, cfile.epan, create_proto_tree, dissect_tree);
796 col_custom_prime_edt(&edt, cinfo);
799 * XXX - need to catch an OutOfMemoryError exception and
800 * attempt to recover from it.
802 epan_dissect_run(&edt, cfile.cd_t, &phdr, frame_tvbuff_new_buffer(fdata, &buf), fdata, cinfo);
805 /* "Stringify" non frame_data vals */
806 epan_dissect_fill_in_columns(&edt, FALSE, TRUE/* fill_fd_columns */);
809 cb(&edt.pi, dissect_tree ? edt.tree : NULL, cinfo, dissect_bytes ? edt.pi.data_src : NULL, data);
811 epan_dissect_cleanup(&edt);
812 wtap_phdr_cleanup(&phdr);
813 ws_buffer_free(&buf);
817 /* based on packet_list_dissect_and_cache_record */
819 sharkd_dissect_columns(int framenum, column_info *cinfo, gboolean dissect_color)
823 gboolean create_proto_tree;
824 struct wtap_pkthdr phdr; /* Packet header */
825 Buffer buf; /* Packet data */
828 char *err_info = NULL;
830 fdata = frame_data_sequence_find(cfile.frames, framenum);
832 col_fill_in_error(cinfo, fdata, FALSE, TRUE/* fill_fd_columns */);
833 return -1; /* error reading the record */
836 wtap_phdr_init(&phdr);
837 ws_buffer_init(&buf, 1500);
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 */
845 create_proto_tree = (dissect_color && color_filters_used()) || (cinfo && have_custom_cols(cinfo));
847 epan_dissect_init(&edt, cfile.epan, create_proto_tree, FALSE /* proto_tree_visible */);
850 color_filters_prime_edt(&edt);
851 fdata->flags.need_colorize = 1;
855 col_custom_prime_edt(&edt, cinfo);
858 * XXX - need to catch an OutOfMemoryError exception and
859 * attempt to recover from it.
861 epan_dissect_run(&edt, cfile.cd_t, &phdr, frame_tvbuff_new_buffer(fdata, &buf), fdata, cinfo);
864 /* "Stringify" non frame_data vals */
865 epan_dissect_fill_in_columns(&edt, FALSE, TRUE/* fill_fd_columns */);
868 epan_dissect_cleanup(&edt);
869 wtap_phdr_cleanup(&phdr);
870 ws_buffer_free(&buf);
880 struct wtap_pkthdr phdr;
882 char *err_info = NULL;
884 gboolean filtering_tap_listeners;
886 gboolean construct_protocol_tree;
890 filtering_tap_listeners = have_filtering_tap_listeners();
891 tap_flags = union_of_tap_listener_flags();
893 construct_protocol_tree = filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE);
894 cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cfile.cinfo : NULL;
896 wtap_phdr_init(&phdr);
897 ws_buffer_init(&buf, 1500);
898 epan_dissect_init(&edt, cfile.epan, construct_protocol_tree, FALSE);
900 reset_tap_listeners();
902 for (framenum = 1; framenum <= cfile.count; framenum++) {
903 fdata = frame_data_sequence_find(cfile.frames, framenum);
905 if (!wtap_seek_read(cfile.wth, fdata->file_off, &phdr, &buf, &err, &err_info))
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);
912 wtap_phdr_cleanup(&phdr);
913 ws_buffer_free(&buf);
914 epan_dissect_cleanup(&edt);
916 draw_tap_listeners(TRUE);
922 sharkd_filter(const char *dftext, guint8 **result)
924 dfilter_t *dfcode = NULL;
927 guint32 frames_count;
929 struct wtap_pkthdr phdr;
931 char *err_info = NULL;
938 if (!dfilter_compile(dftext, &dfcode, &err_info)) {
943 frames_count = cfile.count;
945 wtap_phdr_init(&phdr);
946 ws_buffer_init(&buf, 1500);
947 epan_dissect_init(&edt, cfile.epan, TRUE, FALSE);
950 result_bits = (guint8 *) g_malloc(2 + (frames_count / 8));
952 for (framenum = 1; framenum <= frames_count; framenum++) {
953 frame_data *fdata = frame_data_sequence_find(cfile.frames, framenum);
955 if ((framenum & 7) == 0) {
956 result_bits[(framenum / 8) - 1] = passed_bits;
960 if (!wtap_seek_read(cfile.wth, fdata->file_off, &phdr, &buf, &err, &err_info))
963 /* frame_data_set_before_dissect */
964 epan_dissect_prime_dfilter(&edt, dfcode);
966 epan_dissect_run(&edt, cfile.cd_t, &phdr, frame_tvbuff_new_buffer(fdata, &buf), fdata, NULL);
968 if (dfilter_apply_edt(dfcode, &edt))
969 passed_bits |= (1 << (framenum % 8));
971 /* if passed or ref -> frame_data_set_after_dissect */
973 epan_dissect_reset(&edt);
976 if ((framenum & 7) == 0)
978 result_bits[framenum / 8] = passed_bits;
980 wtap_phdr_cleanup(&phdr);
981 ws_buffer_free(&buf);
982 epan_dissect_cleanup(&edt);
984 dfilter_free(dfcode);
986 *result = result_bits;
992 const char *sharkd_version(void)
994 /* based on get_ws_vcs_version_info(), but shorter */
1003 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1008 * indent-tabs-mode: nil
1011 * vi: set shiftwidth=2 tabstop=8 expandtab:
1012 * :indentSize=2:tabSize=8:noTabs=true: