void wtap_dump_params_init(wtap_dump_params *params, wtap *wth) { memset(params, 0, sizeof(*params)); if (wth == NULL) return; params->encap = wtap_file_encap(wth); params->snaplen = wtap_snapshot_length(wth); params->shb_hdrs = wtap_file_get_shb_for_new_file(wth); params->idb_inf = wtap_file_get_idb_info(wth); params->nrb_hdrs = wtap_file_get_nrb_for_new_file(wth); /* Assume that the input handle remains open until the dumper is closed. * Refer to the DSBs from the input file, wtap_dump will then copy DSBs * as they become available. */ params->dsbs_growing = wth->dsbs; }
/* * Scan through input files and find maximum snapshot length */ int merge_max_snapshot_length(int count, merge_in_file_t in_files[]) { int i; int max_snapshot = 0; int snapshot_length; for (i = 0; i < count; i++) { snapshot_length = wtap_snapshot_length(in_files[i].wth); if (snapshot_length == 0) { /* Snapshot length of input file not known. */ snapshot_length = WTAP_MAX_PACKET_SIZE; } if (snapshot_length > max_snapshot) max_snapshot = snapshot_length; } return max_snapshot; }
static int process_cap_file(wtap *wth, const char *filename) { int err; gchar *err_info; gint64 size; gint64 data_offset; guint32 packet = 0; gint64 bytes = 0; guint32 snaplen_min_inferred = 0xffffffff; guint32 snaplen_max_inferred = 0; const struct wtap_pkthdr *phdr; capture_info cf_info; gboolean have_times = TRUE; double start_time = 0; double stop_time = 0; double cur_time = 0; double prev_time = 0; gboolean know_order = FALSE; order_t order = IN_ORDER; cf_info.encap_counts = g_malloc0(WTAP_NUM_ENCAP_TYPES * sizeof(int)); /* Tally up data that we need to parse through the file to find */ while (wtap_read(wth, &err, &err_info, &data_offset)) { phdr = wtap_phdr(wth); if (phdr->presence_flags & WTAP_HAS_TS) { prev_time = cur_time; cur_time = secs_nsecs(&phdr->ts); if(packet==0) { start_time = cur_time; stop_time = cur_time; prev_time = cur_time; } if (cur_time < prev_time) { order = NOT_IN_ORDER; } if (cur_time < start_time) { start_time = cur_time; } if (cur_time > stop_time) { stop_time = cur_time; } } else { have_times = FALSE; /* at least one packet has no time stamp */ if (order != NOT_IN_ORDER) order = ORDER_UNKNOWN; } bytes+=phdr->len; packet++; /* If caplen < len for a rcd, then presumably */ /* 'Limit packet capture length' was done for this rcd. */ /* Keep track as to the min/max actual snapshot lengths */ /* seen for this file. */ if (phdr->caplen < phdr->len) { if (phdr->caplen < snaplen_min_inferred) snaplen_min_inferred = phdr->caplen; if (phdr->caplen > snaplen_max_inferred) snaplen_max_inferred = phdr->caplen; } /* Per-packet encapsulation */ if (wtap_file_encap(wth) == WTAP_ENCAP_PER_PACKET) { if ((phdr->pkt_encap > 0) && (phdr->pkt_encap < WTAP_NUM_ENCAP_TYPES)) { cf_info.encap_counts[phdr->pkt_encap] += 1; } else { fprintf(stderr, "capinfos: Unknown per-packet encapsulation: %d [frame number: %d]\n", phdr->pkt_encap, packet); } } } /* while */ if (err != 0) { fprintf(stderr, "capinfos: An error occurred after reading %u packets from \"%s\": %s.\n", packet, filename, wtap_strerror(err)); switch (err) { case WTAP_ERR_UNSUPPORTED: case WTAP_ERR_UNSUPPORTED_ENCAP: case WTAP_ERR_BAD_FILE: case WTAP_ERR_DECOMPRESS: fprintf(stderr, "(%s)\n", err_info); g_free(err_info); break; } g_free(cf_info.encap_counts); return 1; } /* File size */ size = wtap_file_size(wth, &err); if (size == -1) { fprintf(stderr, "capinfos: Can't get size of \"%s\": %s.\n", filename, g_strerror(err)); g_free(cf_info.encap_counts); return 1; } cf_info.filesize = size; /* File Type */ cf_info.file_type = wtap_file_type(wth); cf_info.iscompressed = wtap_iscompressed(wth); /* File Encapsulation */ cf_info.file_encap = wtap_file_encap(wth); /* Packet size limit (snaplen) */ cf_info.snaplen = wtap_snapshot_length(wth); if(cf_info.snaplen > 0) cf_info.snap_set = TRUE; else cf_info.snap_set = FALSE; cf_info.snaplen_min_inferred = snaplen_min_inferred; cf_info.snaplen_max_inferred = snaplen_max_inferred; /* # of packets */ cf_info.packet_count = packet; /* File Times */ cf_info.times_known = have_times; cf_info.start_time = start_time; cf_info.stop_time = stop_time; cf_info.duration = stop_time-start_time; cf_info.know_order = know_order; cf_info.order = order; /* Number of packet bytes */ cf_info.packet_bytes = bytes; cf_info.data_rate = 0.0; cf_info.packet_rate = 0.0; cf_info.packet_size = 0.0; if (packet > 0) { if (cf_info.duration > 0.0) { cf_info.data_rate = (double)bytes / (stop_time-start_time); /* Data rate per second */ cf_info.packet_rate = (double)packet / (stop_time-start_time); /* packet rate per second */ } cf_info.packet_size = (double)bytes / packet; /* Avg packet size */ } if(long_report) { print_stats(filename, &cf_info); } else { print_stats_table(filename, &cf_info); } g_free(cf_info.encap_counts); return 0; }
bool CaptureFile::open() { //wtap *wth; gchar *err_info; int err; resetState(); wth = wtap_open_offline(filename.c_str(), &err, &err_info, TRUE); if (wth == NULL) { if (err != 0) { /* Print a message noting that the read failed somewhere along the line. */ switch (err) { case WTAP_ERR_UNSUPPORTED_ENCAP: { ostringstream s; s << "File " << filename << " has a packet with a network type that is not supported. (" << err_info << ")"; g_free(err_info); errorMessage = s.str(); break; } case WTAP_ERR_CANT_READ: { ostringstream s; s << "An attempt to read from file " << filename << " failed for some unknown reason."; errorMessage = s.str(); break; } case WTAP_ERR_SHORT_READ: { ostringstream s; s << "File " << filename << " appears to have been cut short in the middle of a packet."; errorMessage = s.str(); break; } case WTAP_ERR_BAD_RECORD: { ostringstream s; s << "File " << filename << " appears to be damaged or corrupt."; errorMessage = s.str(); g_free(err_info); break; } default: { ostringstream s; s << "An error occurred while reading" << " file " << filename << ": " << wtap_strerror(err); errorMessage = s.str(); break; } } } return false; } /* Initialize all data structures used for dissection. */ init_dissection(); /* We're about to start reading the file. */ state = FILE_READ_IN_PROGRESS; //wth = wth; f_datalen = 0; cd_t = wtap_file_type(wth); count = 0; displayed_count = 0; marked_count = 0; drops_known = FALSE; drops = 0; snap = wtap_snapshot_length(wth); if (snap == 0) { /* Snapshot length not known. */ has_snap = FALSE; snap = WTAP_MAX_PACKET_SIZE; } else has_snap = TRUE; nstime_set_zero(&elapsed_time); nstime_set_unset(&first_ts); nstime_set_unset(&prev_dis_ts); #if GLIB_CHECK_VERSION(2,10,0) #else /* memory chunks have been deprecated in favor of the slice allocator, * which has been added in 2.10 */ plist_chunk = g_mem_chunk_new("frame_data_chunk", sizeof (frame_data), FRAME_DATA_CHUNK_SIZE * sizeof (frame_data), G_ALLOC_AND_FREE); g_assert(plist_chunk); #endif /* change the time formats now, as we might have a new precision */ //cf_change_time_formats(cf);//FIXME ?? return true; }
cf_status_t cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err) { wtap *wth; gchar *err_info; //char err_msg[2048+1]; dprintf("%s: fname = %s\n", __FUNCTION__, fname); dprintf("%s: is_tempfile = %d err = %p\n", __FUNCTION__, is_tempfile, err); wth = wtap_open_offline(fname, err, &err_info, FALSE); dprintf("wth = %p\n", wth); if (wth == NULL) goto fail; /* The open succeeded. Fill in the information for this file. */ #if WIRESHARK_1_4_0 /* Cleanup all data structures used for dissection. */ cleanup_dissection(); #endif /* Initialize all data structures used for dissection. */ init_dissection(); cf->wth = wth; cf->f_datalen = 0; /* not used, but set it anyway */ /* Set the file name because we need it to set the follow stream filter. XXX - is that still true? We need it for other reasons, though, in any case. */ cf->filename = g_strdup(fname); /* Indicate whether it's a permanent or temporary file. */ cf->is_tempfile = is_tempfile; /* If it's a temporary capture buffer file, mark it as not saved. */ cf->user_saved = !is_tempfile; cf->cd_t = wtap_file_type(cf->wth); cf->count = 0; cf->drops_known = FALSE; cf->drops = 0; cf->snap = wtap_snapshot_length(cf->wth); if (cf->snap == 0) { /* Snapshot length not known. */ cf->has_snap = FALSE; cf->snap = WTAP_MAX_PACKET_SIZE; } else cf->has_snap = TRUE; nstime_set_zero(&cf->elapsed_time); nstime_set_unset(&first_ts); nstime_set_unset(&prev_dis_ts); nstime_set_unset(&prev_cap_ts); dprintf("%s: exiting\n", __FUNCTION__); return CF_OK; fail: g_snprintf(sharktools_errmsg, sizeof(sharktools_errmsg), cf_open_error_message(*err, err_info, cf->cd_t), fname); return CF_ERROR; }
static int process_cap_file(wtap *wth, const char *filename) { int status = 0; int err; gchar *err_info; gint64 size; gint64 data_offset; guint32 packet = 0; gint64 bytes = 0; guint32 snaplen_min_inferred = 0xffffffff; guint32 snaplen_max_inferred = 0; const struct wtap_pkthdr *phdr; capture_info cf_info; gboolean have_times = TRUE; double start_time = 0; double stop_time = 0; double cur_time = 0; double prev_time = 0; gboolean know_order = FALSE; order_t order = IN_ORDER; wtapng_section_t *shb_inf; gchar *p; cf_info.encap_counts = g_new0(int,WTAP_NUM_ENCAP_TYPES); /* Tally up data that we need to parse through the file to find */ while (wtap_read(wth, &err, &err_info, &data_offset)) { phdr = wtap_phdr(wth); if (phdr->presence_flags & WTAP_HAS_TS) { prev_time = cur_time; cur_time = nstime_to_sec(&phdr->ts); if (packet == 0) { start_time = cur_time; stop_time = cur_time; prev_time = cur_time; } if (cur_time < prev_time) { order = NOT_IN_ORDER; } if (cur_time < start_time) { start_time = cur_time; } if (cur_time > stop_time) { stop_time = cur_time; } } else { have_times = FALSE; /* at least one packet has no time stamp */ if (order != NOT_IN_ORDER) order = ORDER_UNKNOWN; } if (phdr->rec_type == REC_TYPE_PACKET) { bytes+=phdr->len; packet++; /* If caplen < len for a rcd, then presumably */ /* 'Limit packet capture length' was done for this rcd. */ /* Keep track as to the min/max actual snapshot lengths */ /* seen for this file. */ if (phdr->caplen < phdr->len) { if (phdr->caplen < snaplen_min_inferred) snaplen_min_inferred = phdr->caplen; if (phdr->caplen > snaplen_max_inferred) snaplen_max_inferred = phdr->caplen; } /* Per-packet encapsulation */ if (wtap_file_encap(wth) == WTAP_ENCAP_PER_PACKET) { if ((phdr->pkt_encap > 0) && (phdr->pkt_encap < WTAP_NUM_ENCAP_TYPES)) { cf_info.encap_counts[phdr->pkt_encap] += 1; } else { fprintf(stderr, "capinfos: Unknown per-packet encapsulation: %d [frame number: %d]\n", phdr->pkt_encap, packet); } } } } /* while */ if (err != 0) { fprintf(stderr, "capinfos: An error occurred after reading %u packets from \"%s\": %s.\n", packet, filename, wtap_strerror(err)); switch (err) { case WTAP_ERR_SHORT_READ: status = 1; fprintf(stderr, " (will continue anyway, checksums might be incorrect)\n"); break; case WTAP_ERR_UNSUPPORTED: case WTAP_ERR_UNSUPPORTED_ENCAP: case WTAP_ERR_BAD_FILE: case WTAP_ERR_DECOMPRESS: fprintf(stderr, "(%s)\n", err_info); g_free(err_info); /* fallthrough */ default: g_free(cf_info.encap_counts); return 1; } } /* File size */ size = wtap_file_size(wth, &err); if (size == -1) { fprintf(stderr, "capinfos: Can't get size of \"%s\": %s.\n", filename, g_strerror(err)); g_free(cf_info.encap_counts); return 1; } cf_info.filesize = size; /* File Type */ cf_info.file_type = wtap_file_type_subtype(wth); cf_info.iscompressed = wtap_iscompressed(wth); /* File Encapsulation */ cf_info.file_encap = wtap_file_encap(wth); /* Packet size limit (snaplen) */ cf_info.snaplen = wtap_snapshot_length(wth); if (cf_info.snaplen > 0) cf_info.snap_set = TRUE; else cf_info.snap_set = FALSE; cf_info.snaplen_min_inferred = snaplen_min_inferred; cf_info.snaplen_max_inferred = snaplen_max_inferred; /* # of packets */ cf_info.packet_count = packet; /* File Times */ cf_info.times_known = have_times; cf_info.start_time = start_time; cf_info.stop_time = stop_time; cf_info.duration = stop_time-start_time; cf_info.know_order = know_order; cf_info.order = order; /* Number of packet bytes */ cf_info.packet_bytes = bytes; cf_info.data_rate = 0.0; cf_info.packet_rate = 0.0; cf_info.packet_size = 0.0; if (packet > 0) { if (cf_info.duration > 0.0) { cf_info.data_rate = (double)bytes / (stop_time-start_time); /* Data rate per second */ cf_info.packet_rate = (double)packet / (stop_time-start_time); /* packet rate per second */ } cf_info.packet_size = (double)bytes / packet; /* Avg packet size */ } cf_info.comment = NULL; shb_inf = wtap_file_get_shb_info(wth); if (shb_inf) { /* opt_comment is always 0-terminated by pcapng_read_section_header_block */ cf_info.comment = g_strdup(shb_inf->opt_comment); } g_free(shb_inf); if (cf_info.comment) { /* multi-line comments would conflict with the formatting that capinfos uses we replace linefeeds with spaces */ p = cf_info.comment; while (*p != '\0') { if (*p == '\n') *p = ' '; p++; } } if (long_report) { print_stats(filename, &cf_info); } else { print_stats_table(filename, &cf_info); } g_free(cf_info.encap_counts); g_free(cf_info.comment); return status; }
int main(int argc, char *argv[]) { GString *comp_info_str; GString *runtime_info_str; char *init_progfile_dir_error; wtap *wth = NULL; wtap_dumper *pdh = NULL; wtap_rec dump_rec; Buffer buf; int err; gchar *err_info; gint64 data_offset; const wtap_rec *rec; guint wrong_order_count = 0; gboolean write_output_regardless = TRUE; guint i; GArray *shb_hdrs = NULL; wtapng_iface_descriptions_t *idb_inf = NULL; GArray *nrb_hdrs = NULL; int ret = EXIT_SUCCESS; GPtrArray *frames; FrameRecord_t *prevFrame = NULL; int opt; static const struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {0, 0, 0, 0 } }; int file_count; char *infile; const char *outfile; cmdarg_err_init(failure_warning_message, failure_message_cont); /* Get the compile-time version information string */ comp_info_str = get_compiled_version_info(NULL, NULL); /* Get the run-time version information string */ runtime_info_str = get_runtime_version_info(NULL); /* Add it to the information to be reported on a crash. */ ws_add_crash_info("Reordercap (Wireshark) %s\n" "\n" "%s" "\n" "%s", get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str); g_string_free(comp_info_str, TRUE); g_string_free(runtime_info_str, TRUE); /* * Get credential information for later use. */ init_process_policies(); /* * Attempt to get the pathname of the directory containing the * executable file. */ init_progfile_dir_error = init_progfile_dir(argv[0]); if (init_progfile_dir_error != NULL) { fprintf(stderr, "reordercap: Can't get pathname of directory containing the reordercap program: %s.\n", init_progfile_dir_error); g_free(init_progfile_dir_error); } init_report_message(failure_warning_message, failure_warning_message, NULL, NULL, NULL); wtap_init(TRUE); /* Process the options first */ while ((opt = getopt_long(argc, argv, "hnv", long_options, NULL)) != -1) { switch (opt) { case 'n': write_output_regardless = FALSE; break; case 'h': printf("Reordercap (Wireshark) %s\n" "Reorder timestamps of input file frames into output file.\n" "See https://www.wireshark.org for more information.\n", get_ws_vcs_version_info()); print_usage(stdout); goto clean_exit; case 'v': comp_info_str = get_compiled_version_info(NULL, NULL); runtime_info_str = get_runtime_version_info(NULL); show_version("Reordercap (Wireshark)", comp_info_str, runtime_info_str); g_string_free(comp_info_str, TRUE); g_string_free(runtime_info_str, TRUE); goto clean_exit; case '?': print_usage(stderr); ret = INVALID_OPTION; goto clean_exit; } } /* Remaining args are file names */ file_count = argc - optind; if (file_count == 2) { infile = argv[optind]; outfile = argv[optind+1]; } else { print_usage(stderr); ret = INVALID_OPTION; goto clean_exit; } /* Open infile */ /* TODO: if reordercap is ever changed to give the user a choice of which open_routine reader to use, then the following needs to change. */ wth = wtap_open_offline(infile, WTAP_TYPE_AUTO, &err, &err_info, TRUE); if (wth == NULL) { cfile_open_failure_message("reordercap", infile, err, err_info); ret = OPEN_ERROR; goto clean_exit; } DEBUG_PRINT("file_type_subtype is %d\n", wtap_file_type_subtype(wth)); shb_hdrs = wtap_file_get_shb_for_new_file(wth); idb_inf = wtap_file_get_idb_info(wth); nrb_hdrs = wtap_file_get_nrb_for_new_file(wth); /* Open outfile (same filetype/encap as input file) */ if (strcmp(outfile, "-") == 0) { pdh = wtap_dump_open_stdout_ng(wtap_file_type_subtype(wth), wtap_file_encap(wth), wtap_snapshot_length(wth), FALSE, shb_hdrs, idb_inf, nrb_hdrs, &err); } else { pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth), wtap_snapshot_length(wth), FALSE, shb_hdrs, idb_inf, nrb_hdrs, &err); } g_free(idb_inf); idb_inf = NULL; if (pdh == NULL) { cfile_dump_open_failure_message("reordercap", outfile, err, wtap_file_type_subtype(wth)); wtap_block_array_free(shb_hdrs); wtap_block_array_free(nrb_hdrs); ret = OUTPUT_FILE_ERROR; goto clean_exit; } /* Allocate the array of frame pointers. */ frames = g_ptr_array_new(); /* Read each frame from infile */ while (wtap_read(wth, &err, &err_info, &data_offset)) { FrameRecord_t *newFrameRecord; rec = wtap_get_rec(wth); newFrameRecord = g_slice_new(FrameRecord_t); newFrameRecord->num = frames->len + 1; newFrameRecord->offset = data_offset; if (rec->presence_flags & WTAP_HAS_TS) { newFrameRecord->frame_time = rec->ts; } else { nstime_set_unset(&newFrameRecord->frame_time); } if (prevFrame && frames_compare(&newFrameRecord, &prevFrame) < 0) { wrong_order_count++; } g_ptr_array_add(frames, newFrameRecord); prevFrame = newFrameRecord; } if (err != 0) { /* Print a message noting that the read failed somewhere along the line. */ cfile_read_failure_message("reordercap", infile, err, err_info); } printf("%u frames, %u out of order\n", frames->len, wrong_order_count); /* Sort the frames */ if (wrong_order_count > 0) { g_ptr_array_sort(frames, frames_compare); } /* Write out each sorted frame in turn */ wtap_rec_init(&dump_rec); ws_buffer_init(&buf, 1500); for (i = 0; i < frames->len; i++) { FrameRecord_t *frame = (FrameRecord_t *)frames->pdata[i]; /* Avoid writing if already sorted and configured to */ if (write_output_regardless || (wrong_order_count > 0)) { frame_write(frame, wth, pdh, &dump_rec, &buf, infile, outfile); } g_slice_free(FrameRecord_t, frame); } wtap_rec_cleanup(&dump_rec); ws_buffer_free(&buf); if (!write_output_regardless && (wrong_order_count == 0)) { printf("Not writing output file because input file is already in order.\n"); } /* Free the whole array */ g_ptr_array_free(frames, TRUE); /* Close outfile */ if (!wtap_dump_close(pdh, &err)) { cfile_close_failure_message(outfile, err); wtap_block_array_free(shb_hdrs); wtap_block_array_free(nrb_hdrs); ret = OUTPUT_FILE_ERROR; goto clean_exit; } wtap_block_array_free(shb_hdrs); wtap_block_array_free(nrb_hdrs); /* Finally, close infile and release resources. */ wtap_close(wth); clean_exit: wtap_cleanup(); free_progdirs(); return ret; }