X-Git-Url: http://git.samba.org/?p=metze%2Fwireshark%2Fwip.git;a=blobdiff_plain;f=reordercap.c;h=7f3463d89bd66f04ab2ebffb85e2c56f09a6d4e8;hp=df46d7c166f6ba0519566ce4409fad5591a168cc;hb=6648e34c061a14d4f76e22ed891aae8ceede520a;hpb=c0c480d08c175eed4524ea9e73ec86298f468cf4 diff --git a/reordercap.c b/reordercap.c index df46d7c166..7f3463d89b 100644 --- a/reordercap.c +++ b/reordercap.c @@ -5,58 +5,50 @@ * By Gerald Combs * Copyright 1998 Gerald Combs * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * + * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "config.h" +#include #include #include #include #include -#ifdef HAVE_UNISTD_H -#include +#ifdef HAVE_GETOPT_H +#include #endif -#include "wtap.h" +#include -#ifndef HAVE_GETOPT +#ifndef HAVE_GETOPT_LONG #include "wsutil/wsgetopt.h" #endif -/* Show command-line usage */ -static void usage(gboolean is_error) -{ - FILE *output; - - if (!is_error) { - output = stdout; - } - else { - output = stderr; - } +#include +#include +#include +#include +#include +#include +#include - fprintf(output, "Reordercap %s" -#ifdef GITVERSION - " (" GITVERSION " from " GITBRANCH ")" +#ifdef HAVE_PLUGINS +#include #endif - "\n", VERSION); - fprintf(output, "Reorder timestamps of input file frames into output file.\n"); - fprintf(output, "See http://www.wireshark.org for more information.\n"); + +#include + +#include "ui/failure_message.h" + +#define INVALID_OPTION 1 +#define OPEN_ERROR 2 +#define OUTPUT_FILE_ERROR 1 + +/* Show command-line usage */ +static void +print_usage(FILE *output) +{ fprintf(output, "\n"); fprintf(output, "Usage: reordercap [options] \n"); fprintf(output, "\n"); @@ -70,7 +62,7 @@ typedef struct FrameRecord_t { gint64 offset; guint num; - nstime_t time; + nstime_t frame_time; } FrameRecord_t; @@ -89,55 +81,47 @@ typedef struct FrameRecord_t { static void -frame_write(FrameRecord_t *frame, wtap *wth, wtap_dumper *pdh, Buffer *buf, - const char *infile) +frame_write(FrameRecord_t *frame, wtap *wth, wtap_dumper *pdh, + wtap_rec *rec, Buffer *buf, const char *infile, + const char *outfile) { int err; gchar *err_info; - struct wtap_pkthdr phdr; - - memset(&phdr, 0, sizeof(struct wtap_pkthdr)); DEBUG_PRINT("\nDumping frame (offset=%" G_GINT64_MODIFIER "u)\n", frame->offset); - /* Re-read the first frame from the stored location */ - if (wtap_seek_read(wth, frame->offset, &phdr, buf, &err, &err_info) == -1) { + /* Re-read the frame from the stored location */ + if (!wtap_seek_read(wth, frame->offset, rec, buf, &err, &err_info)) { if (err != 0) { /* Print a message noting that the read failed somewhere along the line. */ fprintf(stderr, - "reordercap: An error occurred while re-reading \"%s\": %s.\n", - infile, wtap_strerror(err)); - switch (err) { - - case WTAP_ERR_UNSUPPORTED: - case WTAP_ERR_UNSUPPORTED_ENCAP: - case WTAP_ERR_BAD_FILE: - fprintf(stderr, "(%s)\n", err_info); - g_free(err_info); - break; - } + "reordercap: An error occurred while re-reading \"%s\".\n", + infile); + cfile_read_failure_message("reordercap", infile, err, err_info); exit(1); } } /* Copy, and set length and timestamp from item. */ - /* TODO: remove when wtap_seek_read() will read phdr */ - phdr.ts = frame->time; + /* TODO: remove when wtap_seek_read() fills in rec, + including time stamps, for all file types */ + rec->ts = frame->frame_time; /* Dump frame to outfile */ - if (!wtap_dump(pdh, &phdr, buffer_start_ptr(buf), &err)) { - fprintf(stderr, "reordercap: Error (%s) writing frame to outfile\n", - wtap_strerror(err)); + if (!wtap_dump(pdh, rec, ws_buffer_start_ptr(buf), &err, &err_info)) { + cfile_write_failure_message("reordercap", infile, outfile, err, + err_info, frame->num, + wtap_file_type_subtype(wth)); exit(1); } } /* Comparing timestamps between 2 frames. - -1 if (t1 < t2) - 0 if (t1 == t2) - 1 if (t1 > t2) + negative if (t1 < t2) + zero if (t1 == t2) + positive if (t1 > t2) */ static int frames_compare(gconstpointer a, gconstpointer b) @@ -145,69 +129,112 @@ frames_compare(gconstpointer a, gconstpointer b) const FrameRecord_t *frame1 = *(const FrameRecord_t *const *) a; const FrameRecord_t *frame2 = *(const FrameRecord_t *const *) b; - const nstime_t *time1 = &frame1->time; - const nstime_t *time2 = &frame2->time; + const nstime_t *time1 = &frame1->frame_time; + const nstime_t *time2 = &frame2->frame_time; - if (time1->secs > time2->secs) - return 1; - if (time1->secs < time2->secs) - return -1; - - /* time1->secs == time2->secs */ - if (time1->nsecs > time2->nsecs) - return 1; - if (time1->nsecs < time2->nsecs) - return -1; - - /* time1->nsecs == time2->nsecs */ + return nstime_cmp(time1, time2); +} - if (frame1->num > frame2->num) - return 1; - if (frame1->num < frame2->num) - return -1; - return 0; +/* + * General errors and warnings are reported with an console message + * in reordercap. + */ +static void +failure_warning_message(const char *msg_format, va_list ap) +{ + fprintf(stderr, "reordercap: "); + vfprintf(stderr, msg_format, ap); + fprintf(stderr, "\n"); } +/* + * Report additional information for an error in command-line arguments. + */ +static void +failure_message_cont(const char *msg_format, va_list ap) +{ + vfprintf(stderr, msg_format, ap); + fprintf(stderr, "\n"); +} /********************************************************************/ /* Main function. */ /********************************************************************/ -int main(int argc, char *argv[]) +int +main(int argc, char *argv[]) { + char *init_progfile_dir_error; wtap *wth = NULL; wtap_dumper *pdh = NULL; - int rec_type; + wtap_rec dump_rec; Buffer buf; int err; gchar *err_info; gint64 data_offset; - const struct wtap_pkthdr *phdr; + const wtap_rec *rec; guint wrong_order_count = 0; gboolean write_output_regardless = TRUE; guint i; - wtapng_section_t *shb_hdr; - wtapng_iface_descriptions_t *idb_inf; + wtap_dump_params params; + 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; - char *outfile; + const char *outfile; + + cmdarg_err_init(failure_warning_message, failure_message_cont); + + /* Initialize the version information. */ + ws_init_version_info("Reordercap (Wireshark)", NULL, NULL, NULL); + + /* + * 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(argc, argv, "hn")) != -1) { + while ((opt = getopt_long(argc, argv, "hnv", long_options, NULL)) != -1) { switch (opt) { case 'n': write_output_regardless = FALSE; break; case 'h': - usage(FALSE); - exit(0); + show_help_header("Reorder timestamps of input file frames into output file."); + print_usage(stdout); + goto clean_exit; + case 'v': + show_version(); + goto clean_exit; case '?': - usage(TRUE); - exit(1); + print_usage(stderr); + ret = INVALID_OPTION; + goto clean_exit; } } @@ -218,83 +245,69 @@ int main(int argc, char *argv[]) outfile = argv[optind+1]; } else { - usage(TRUE); - exit(1); + print_usage(stderr); + ret = INVALID_OPTION; + goto clean_exit; } - init_open_routines(); - /* 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) { - fprintf(stderr, "reordercap: Can't open %s: %s\n", infile, - wtap_strerror(err)); - switch (err) { - - case WTAP_ERR_UNSUPPORTED: - case WTAP_ERR_UNSUPPORTED_ENCAP: - case WTAP_ERR_BAD_FILE: - fprintf(stderr, "(%s)\n", err_info); - g_free(err_info); - break; - } - exit(1); + cfile_open_failure_message("reordercap", infile, err, err_info); + ret = OPEN_ERROR; + goto clean_exit; } - DEBUG_PRINT("file_type_subtype is %u\n", wtap_file_type_subtype(wth)); + DEBUG_PRINT("file_type_subtype is %d\n", wtap_file_type_subtype(wth)); - shb_hdr = wtap_file_get_shb_info(wth); - idb_inf = wtap_file_get_idb_info(wth); + wtap_dump_params_init(¶ms, wth); /* Open outfile (same filetype/encap as input file) */ - pdh = wtap_dump_open_ng(outfile, wtap_file_type_subtype(wth), wtap_file_encap(wth), - 65535, FALSE, shb_hdr, idb_inf, &err); - g_free(idb_inf); + if (strcmp(outfile, "-") == 0) { + pdh = wtap_dump_open_stdout(wtap_file_type_subtype(wth), WTAP_UNCOMPRESSED, ¶ms, &err); + } else { + pdh = wtap_dump_open(outfile, wtap_file_type_subtype(wth), WTAP_UNCOMPRESSED, ¶ms, &err); + } + g_free(params.idb_inf); + params.idb_inf = NULL; + if (pdh == NULL) { - fprintf(stderr, "reordercap: Failed to open output file: (%s) - error %s\n", - outfile, wtap_strerror(err)); - g_free(shb_hdr); - exit(1); + cfile_dump_open_failure_message("reordercap", outfile, err, + wtap_file_type_subtype(wth)); + wtap_dump_params_cleanup(¶ms); + ret = OUTPUT_FILE_ERROR; + goto clean_exit; } /* Allocate the array of frame pointers. */ frames = g_ptr_array_new(); /* Read each frame from infile */ - while ((rec_type = wtap_read(wth, &err, &err_info, &data_offset)) != -1) { - if (rec_type == REC_TYPE_PACKET) { - FrameRecord_t *newFrameRecord; - - phdr = wtap_phdr(wth); - - newFrameRecord = g_slice_new(FrameRecord_t); - newFrameRecord->num = frames->len + 1; - newFrameRecord->offset = data_offset; - newFrameRecord->time = phdr->ts; - - if (prevFrame && frames_compare(&newFrameRecord, &prevFrame) < 0) { - wrong_order_count++; - } + 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); + } - g_ptr_array_add(frames, newFrameRecord); - prevFrame = newFrameRecord; + 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. */ - fprintf(stderr, - "reordercap: An error occurred while reading \"%s\": %s.\n", - infile, wtap_strerror(err)); - switch (err) { - - case WTAP_ERR_UNSUPPORTED: - case WTAP_ERR_UNSUPPORTED_ENCAP: - case WTAP_ERR_BAD_FILE: - fprintf(stderr, "(%s)\n", err_info); - g_free(err_info); - break; - } + cfile_read_failure_message("reordercap", infile, err, err_info); } printf("%u frames, %u out of order\n", frames->len, wrong_order_count); @@ -305,20 +318,22 @@ int main(int argc, char *argv[]) } /* Write out each sorted frame in turn */ - buffer_init(&buf, 1500); + 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, &buf, infile); + frame_write(frame, wth, pdh, &dump_rec, &buf, infile, outfile); } g_slice_free(FrameRecord_t, frame); } - buffer_free(&buf); + 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"); + printf("Not writing output file because input file is already in order.\n"); } /* Free the whole array */ @@ -326,17 +341,20 @@ int main(int argc, char *argv[]) /* Close outfile */ if (!wtap_dump_close(pdh, &err)) { - fprintf(stderr, "reordercap: Error closing %s: %s\n", outfile, - wtap_strerror(err)); - g_free(shb_hdr); - exit(1); + cfile_close_failure_message(outfile, err); + wtap_dump_params_cleanup(¶ms); + ret = OUTPUT_FILE_ERROR; + goto clean_exit; } - g_free(shb_hdr); + wtap_dump_params_cleanup(¶ms); - /* Finally, close infile */ - wtap_fdclose(wth); + /* Finally, close infile and release resources. */ + wtap_close(wth); - return 0; +clean_exit: + wtap_cleanup(); + free_progdirs(); + return ret; } /*