void wtap_rec_cleanup(wtap_rec *rec) { g_free(rec->opt_comment); rec->opt_comment = NULL; ws_buffer_free(&rec->options_buf); }
static void destroy_k12_file_data(k12_t* fd) { g_hash_table_destroy(fd->src_by_id); g_hash_table_foreach_remove(fd->src_by_name,destroy_srcdsc,NULL); g_hash_table_destroy(fd->src_by_name); ws_buffer_free(&(fd->extra_info)); g_free(fd->seq_read_buff); g_free(fd->rand_read_buff); g_free(fd); }
static void frame_free(tvbuff_t *tvb) { struct tvb_frame *frame_tvb = (struct tvb_frame *) tvb; if (frame_tvb->buf) { ws_buffer_free(frame_tvb->buf); g_free(frame_tvb->buf); } }
static void wshtp_conn_free(wshtp_conn_t *conn) { if (conn) { if (conn->free_cb && conn->userdata) { conn->free_cb(conn, conn->userdata); } if (conn->data.ws_frames) { ws_buffer_free(conn->data.ws_frames); conn->data.ws_frames = NULL; } free(conn); } }
/* Close only the sequential side, freeing up memory it uses. Note that we do *not* want to call the subtype's close function, as it would free any per-subtype data, and that data may be needed by the random-access side. Instead, if the subtype has a "sequential close" function, we call it, to free up stuff used only by the sequential side. */ void wtap_sequential_close(wtap *wth) { if (wth->subtype_sequential_close != NULL) (*wth->subtype_sequential_close)(wth); if (wth->fh != NULL) { file_close(wth->fh); wth->fh = NULL; } if (wth->frame_buffer) { ws_buffer_free(wth->frame_buffer); g_free(wth->frame_buffer); wth->frame_buffer = NULL; } }
static gboolean process_record(capture_file *cf, frame_data *frame, column_info *cinfo, ph_stats_t* ps) { epan_dissect_t edt; struct wtap_pkthdr phdr; Buffer buf; double cur_time; wtap_phdr_init(&phdr); /* Load the record from the capture file */ ws_buffer_init(&buf, 1500); if (!cf_read_record_r(cf, frame, &phdr, &buf)) return FALSE; /* failure */ /* Dissect the record tree not visible */ epan_dissect_init(&edt, cf->epan, TRUE, FALSE); /* Don't fake protocols. We need them for the protocol hierarchy */ epan_dissect_fake_protocols(&edt, FALSE); epan_dissect_run(&edt, cf->cd_t, &phdr, frame_tvbuff_new_buffer(frame, &buf), frame, cinfo); /* Get stats from this protocol tree */ process_tree(edt.tree, ps, frame->pkt_len); if (frame->flags.has_ts) { /* Update times */ cur_time = nstime_to_sec(&frame->abs_ts); if (cur_time < ps->first_time) ps->first_time = cur_time; if (cur_time > ps->last_time) ps->last_time = cur_time; } /* Free our memory. */ epan_dissect_cleanup(&edt); wtap_phdr_cleanup(&phdr); ws_buffer_free(&buf); return TRUE; /* success */ }
void PacketListRecord::dissect(capture_file *cap_file, bool dissect_color) { // packet_list_store.c:packet_list_dissect_and_cache_record epan_dissect_t edt; column_info *cinfo = NULL; gboolean create_proto_tree; struct wtap_pkthdr phdr; /* Packet header */ Buffer buf; /* Packet data */ gboolean dissect_columns = col_text_.isEmpty() || data_ver_ != col_data_ver_; if (!cap_file) { return; } memset(&phdr, 0, sizeof(struct wtap_pkthdr)); if (dissect_columns) { cinfo = &cap_file->cinfo; } ws_buffer_init(&buf, 1500); if (!cf_read_record_r(cap_file, fdata_, &phdr, &buf)) { /* * Error reading the record. * * Don't set the color filter for now (we might want * to colorize it in some fashion to warn that the * row couldn't be filled in or colorized), and * set the columns to placeholder values, except * for the Info column, where we'll put in an * error message. */ if (dissect_columns) { col_fill_in_error(cinfo, fdata_, FALSE, FALSE /* fill_fd_columns */); cacheColumnStrings(cinfo); } if (dissect_color) { fdata_->color_filter = NULL; colorized_ = true; } ws_buffer_free(&buf); return; /* error reading the record */ } create_proto_tree = (dissect_color && color_filters_used()) || (dissect_columns && have_custom_cols(cinfo)); epan_dissect_init(&edt, cap_file->epan, create_proto_tree, FALSE /* proto_tree_visible */); /* Re-color when the coloring rules are changed via the UI. */ if (dissect_color) { color_filters_prime_edt(&edt); fdata_->flags.need_colorize = 1; } if (dissect_columns) col_custom_prime_edt(&edt, cinfo); /* * XXX - need to catch an OutOfMemoryError exception and * attempt to recover from it. */ epan_dissect_run(&edt, cap_file->cd_t, &phdr, frame_tvbuff_new_buffer(fdata_, &buf), fdata_, cinfo); if (dissect_columns) { /* "Stringify" non frame_data vals */ epan_dissect_fill_in_columns(&edt, FALSE, FALSE /* fill_fd_columns */); cacheColumnStrings(cinfo); } if (dissect_color) { colorized_ = true; } data_ver_ = col_data_ver_; packet_info *pi = &edt.pi; conv_ = find_conversation(pi->num, &pi->src, &pi->dst, pi->ptype, pi->srcport, pi->destport, 0); epan_dissect_cleanup(&edt); ws_buffer_free(&buf); }
static void ws_read_cb(evbev_t * bev, void *arg) { size_t data_len = 0; wshtp_conn_t *conn = (wshtp_conn_t*)arg; evbuf_t *in = bufferevent_get_input(bev); bufferevent_lock(bev); while ( (data_len = evbuffer_get_length(in)) ){ void *data = evbuffer_pullup(in, data_len); ws_frame_t frame; size_t nread = ws_parse_frame(data, data_len, &frame); if (frame.status == STATUS_OK) { if (frame.opcode == OP_TEXT) { conn->data.type = WS_DATA_TEXT; conn->method = WSHTP_ON_MESSAGE; } else if (frame.opcode == OP_BIN) { conn->data.type = WS_DATA_BINARY; conn->method = WSHTP_ON_MESSAGE; } else if (frame.opcode == OP_CLOSE) { conn->method = WSHTP_ON_CLOSE; } if (frame.fin == 0 || frame.opcode == OP_CONT) { if (conn->data.ws_frames == NULL) { conn->data.ws_frames = ws_buffer_new(); } ws_buffer_append_data(conn->data.ws_frames, frame.data, frame.payload_len); } if (conn->method == WSHTP_ON_CLOSE) { evbuffer_drain(in, data_len); } else { evbuffer_drain(in, nread); } if (frame.fin) { if (conn->data.ws_frames) { conn->data.content = ws_buffer_get_data(conn->data.ws_frames, &conn->data.size); ws_buffer_free(conn->data.ws_frames); conn->data.ws_frames = NULL; } else { conn->data.content = frame.data; conn->data.size = frame.payload_len; } bufferevent_unlock(bev); wshtp_hooks_call(conn->server, conn->method, conn); bufferevent_lock(bev); free(conn->data.content); conn->data.content = NULL; conn->data.size = 0; } } else { break; } } // free fragments bufferevent_unlock(bev); }
void wtap_phdr_cleanup(struct wtap_pkthdr *phdr) { ws_buffer_free(&phdr->ft_specific_data); }
ph_stats_t* ph_stats_new(capture_file *cf) { ph_stats_t *ps; guint32 framenum; frame_data *frame; guint tot_packets, tot_bytes; progdlg_t *progbar = NULL; gboolean stop_flag; int count; wtap_rec rec; Buffer buf; float progbar_val; GTimeVal start_time; gchar status_str[100]; int progbar_nextstep; int progbar_quantum; if (!cf) return NULL; pc_proto_id = proto_registrar_get_id_byname("pkt_comment"); /* Initialize the data */ ps = g_new(ph_stats_t, 1); ps->tot_packets = 0; ps->tot_bytes = 0; ps->stats_tree = g_node_new(NULL); ps->first_time = 0.0; ps->last_time = 0.0; /* Update the progress bar when it gets to this value. */ progbar_nextstep = 0; /* When we reach the value that triggers a progress bar update, bump that value by this amount. */ progbar_quantum = cf->count/N_PROGBAR_UPDATES; /* Count of packets at which we've looked. */ count = 0; /* Progress so far. */ progbar_val = 0.0f; stop_flag = FALSE; g_get_current_time(&start_time); tot_packets = 0; tot_bytes = 0; wtap_rec_init(&rec); ws_buffer_init(&buf, 1514); for (framenum = 1; framenum <= cf->count; framenum++) { frame = frame_data_sequence_find(cf->provider.frames, framenum); /* Create the progress bar if necessary. We check on every iteration of the loop, so that it takes no longer than the standard time to create it (otherwise, for a large file, we might take considerably longer than that standard time in order to get to the next progress bar step). */ if (progbar == NULL) progbar = delayed_create_progress_dlg( cf->window, "Computing", "protocol hierarchy statistics", TRUE, &stop_flag, &start_time, progbar_val); /* Update the progress bar, but do it only N_PROGBAR_UPDATES times; when we update it, we have to run the GTK+ main loop to get it to repaint what's pending, and doing so may involve an "ioctl()" to see if there's any pending input from an X server, and doing that for every packet can be costly, especially on a big file. */ if (count >= progbar_nextstep) { /* let's not divide by zero. I should never be started * with count == 0, so let's assert that */ g_assert(cf->count > 0); progbar_val = (gfloat) count / cf->count; if (progbar != NULL) { g_snprintf(status_str, sizeof(status_str), "%4u of %u frames", count, cf->count); update_progress_dlg(progbar, progbar_val, status_str); } progbar_nextstep += progbar_quantum; } if (stop_flag) { /* Well, the user decided to abort the statistics. computation process Just stop. */ break; } /* Skip frames that are hidden due to the display filter. XXX - should the progress bar count only packets that passed the display filter? If so, it should probably do so for other loops (see "file.c") that look only at those packets. */ if (frame->passed_dfilter) { if (frame->has_ts) { if (tot_packets == 0) { double cur_time = nstime_to_sec(&frame->abs_ts); ps->first_time = cur_time; ps->last_time = cur_time; } } /* we don't care about colinfo */ if (!process_record(cf, frame, NULL, &rec, &buf, ps)) { /* * Give up, and set "stop_flag" so we * just abort rather than popping up * the statistics window. */ stop_flag = TRUE; break; } tot_packets++; tot_bytes += frame->pkt_len; } count++; } wtap_rec_cleanup(&rec); ws_buffer_free(&buf); /* We're done calculating the statistics; destroy the progress bar if it was created. */ if (progbar != NULL) destroy_progress_dlg(progbar); if (stop_flag) { /* * We quit in the middle; throw away the statistics * and return NULL, so our caller doesn't pop up a * window with the incomplete statistics. */ ph_stats_free(ps); return NULL; } ps->tot_packets = tot_packets; ps->tot_bytes = tot_bytes; return ps; }
void PacketListRecord::dissect(capture_file *cap_file, bool dissect_color) { // packet_list_store.c:packet_list_dissect_and_cache_record epan_dissect_t edt; column_info *cinfo = NULL; gboolean create_proto_tree; wtap_rec rec; /* Record metadata */ Buffer buf; /* Record data */ if (!col_text_) col_text_ = new ColumnTextList; gboolean dissect_columns = col_text_->isEmpty() || data_ver_ != col_data_ver_; if (!cap_file) { return; } memset(&rec, 0, sizeof rec); if (dissect_columns) { cinfo = &cap_file->cinfo; } ws_buffer_init(&buf, 1500); if (!cf_read_record_r(cap_file, fdata_, &rec, &buf)) { /* * Error reading the record. * * Don't set the color filter for now (we might want * to colorize it in some fashion to warn that the * row couldn't be filled in or colorized), and * set the columns to placeholder values, except * for the Info column, where we'll put in an * error message. */ if (dissect_columns) { col_fill_in_error(cinfo, fdata_, FALSE, FALSE /* fill_fd_columns */); cacheColumnStrings(cinfo); } if (dissect_color) { fdata_->color_filter = NULL; colorized_ = true; } ws_buffer_free(&buf); return; /* error reading the record */ } /* * Determine whether we need to create a protocol tree. * We do if: * * we're going to apply a color filter to this packet; * * we're need to fill in the columns and we have custom columns * (which require field values, which currently requires that * we build a protocol tree). * * XXX - field extractors? (Not done for GTK+....) */ create_proto_tree = ((dissect_color && color_filters_used()) || (dissect_columns && (have_custom_cols(cinfo) || have_field_extractors()))); epan_dissect_init(&edt, cap_file->epan, create_proto_tree, FALSE /* proto_tree_visible */); /* Re-color when the coloring rules are changed via the UI. */ if (dissect_color) { color_filters_prime_edt(&edt); fdata_->flags.need_colorize = 1; } if (dissect_columns) col_custom_prime_edt(&edt, cinfo); /* * XXX - need to catch an OutOfMemoryError exception and * attempt to recover from it. */ epan_dissect_run(&edt, cap_file->cd_t, &rec, frame_tvbuff_new_buffer(&cap_file->provider, fdata_, &buf), fdata_, cinfo); if (dissect_columns) { /* "Stringify" non frame_data vals */ epan_dissect_fill_in_columns(&edt, FALSE, FALSE /* fill_fd_columns */); cacheColumnStrings(cinfo); } if (dissect_color) { colorized_ = true; } data_ver_ = col_data_ver_; packet_info *pi = &edt.pi; conv_ = find_conversation_pinfo(pi, 0); epan_dissect_cleanup(&edt); ws_buffer_free(&buf); }
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; }