wsutil/wsgcrypt.c decrypt_des_ecb
[wireshark-sm.git] / reordercap.c
blob0d8a7a60d6a40efe9d2e013e0b8e5760ef0acc50
1 /* Reorder the frames from an input dump file, and write to output dump file.
2 * Martin Mathieson and Jakub Jawadzki
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include <config.h>
12 #define WS_LOG_DOMAIN LOG_DOMAIN_MAIN
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <glib.h>
19 #include <ws_exit_codes.h>
20 #include <wsutil/ws_getopt.h>
22 #include <wiretap/wtap.h>
24 #include <wsutil/cmdarg_err.h>
25 #include <wsutil/filesystem.h>
26 #include <wsutil/file_util.h>
27 #include <wsutil/privileges.h>
28 #include <cli_main.h>
29 #include <wsutil/version_info.h>
30 #include <wiretap/wtap_opttypes.h>
32 #ifdef HAVE_PLUGINS
33 #include <wsutil/plugins.h>
34 #endif
36 #include <wsutil/wslog.h>
38 #include "ui/failure_message.h"
40 /* Additional exit codes */
41 #define OUTPUT_FILE_ERROR 1
43 /* Show command-line usage */
44 static void
45 print_usage(FILE *output)
47 fprintf(output, "\n");
48 fprintf(output, "Usage: reordercap [options] <infile> <outfile>\n");
49 fprintf(output, "\n");
50 fprintf(output, "Options:\n");
51 fprintf(output, " -n don't write to output file if the input file is ordered.\n");
52 fprintf(output, " -h, --help display this help and exit.\n");
53 fprintf(output, " -v, --version print version information and exit.\n");
56 /* Remember where this frame was in the file */
57 typedef struct FrameRecord_t {
58 int64_t offset;
59 unsigned num;
61 nstime_t frame_time;
62 } FrameRecord_t;
65 /**************************************************/
66 /* Debugging only */
68 /* Enable this symbol to see debug output */
69 /* #define REORDER_DEBUG */
71 #ifdef REORDER_DEBUG
72 #define DEBUG_PRINT printf
73 #else
74 #define DEBUG_PRINT(...)
75 #endif
76 /**************************************************/
79 static void
80 frame_write(FrameRecord_t *frame, wtap *wth, wtap_dumper *pdh,
81 wtap_rec *rec, const char *infile, const char *outfile)
83 int err;
84 char *err_info;
86 DEBUG_PRINT("\nDumping frame (offset=%" PRIu64 ")\n",
87 frame->offset);
90 /* Re-read the frame from the stored location */
91 if (!wtap_seek_read(wth, frame->offset, rec, &err, &err_info)) {
92 if (err != 0) {
93 /* Print a message noting that the read failed somewhere along the line. */
94 fprintf(stderr,
95 "reordercap: An error occurred while re-reading \"%s\".\n",
96 infile);
97 cfile_read_failure_message(infile, err, err_info);
98 exit(1);
102 /* Copy, and set length and timestamp from item. */
103 /* TODO: remove when wtap_seek_read() fills in rec,
104 including time stamps, for all file types */
105 rec->ts = frame->frame_time;
107 /* Dump frame to outfile */
108 if (!wtap_dump(pdh, rec, ws_buffer_start_ptr(&rec->data), &err, &err_info)) {
109 cfile_write_failure_message(infile, outfile, err, err_info, frame->num,
110 wtap_file_type_subtype(wth));
111 exit(1);
113 wtap_rec_reset(rec);
116 /* Comparing timestamps between 2 frames.
117 negative if (t1 < t2)
118 zero if (t1 == t2)
119 positive if (t1 > t2)
121 static int
122 frames_compare(const void *a, const void *b)
124 const FrameRecord_t *frame1 = *(const FrameRecord_t *const *) a;
125 const FrameRecord_t *frame2 = *(const FrameRecord_t *const *) b;
127 const nstime_t *time1 = &frame1->frame_time;
128 const nstime_t *time2 = &frame2->frame_time;
130 return nstime_cmp(time1, time2);
133 /********************************************************************/
134 /* Main function. */
135 /********************************************************************/
137 main(int argc, char *argv[])
139 char *configuration_init_error;
140 wtap *wth = NULL;
141 wtap_dumper *pdh = NULL;
142 wtap_rec rec;
143 int err;
144 char *err_info;
145 int64_t data_offset;
146 unsigned wrong_order_count = 0;
147 bool write_output_regardless = true;
148 unsigned i;
149 wtap_dump_params params;
150 int ret = EXIT_SUCCESS;
152 GPtrArray *frames;
153 FrameRecord_t *prevFrame = NULL;
155 int opt;
156 static const struct ws_option long_options[] = {
157 {"help", ws_no_argument, NULL, 'h'},
158 {"version", ws_no_argument, NULL, 'v'},
159 {0, 0, 0, 0 }
161 int file_count;
162 char *infile;
163 const char *outfile;
165 /* Set the program name. */
166 g_set_prgname("reordercap");
168 cmdarg_err_init(stderr_cmdarg_err, stderr_cmdarg_err_cont);
170 /* Initialize log handler early so we can have proper logging during startup. */
171 ws_log_init(vcmdarg_err);
173 /* Early logging command-line initialization. */
174 ws_log_parse_args(&argc, argv, vcmdarg_err, WS_EXIT_INVALID_OPTION);
176 ws_noisy("Finished log init and parsing command line log arguments");
179 * Get credential information for later use.
181 init_process_policies();
184 * Attempt to get the pathname of the directory containing the
185 * executable file.
187 configuration_init_error = configuration_init(argv[0]);
188 if (configuration_init_error != NULL) {
189 fprintf(stderr,
190 "reordercap: Can't get pathname of directory containing the reordercap program: %s.\n",
191 configuration_init_error);
192 g_free(configuration_init_error);
195 /* Initialize the version information. */
196 ws_init_version_info("Reordercap", NULL, NULL);
198 init_report_failure_message("reordercap");
200 wtap_init(true);
202 /* Process the options first */
203 while ((opt = ws_getopt_long(argc, argv, "hnv", long_options, NULL)) != -1) {
204 switch (opt) {
205 case 'n':
206 write_output_regardless = false;
207 break;
208 case 'h':
209 show_help_header("Reorder timestamps of input file frames into output file.");
210 print_usage(stdout);
211 goto clean_exit;
212 case 'v':
213 show_version();
214 goto clean_exit;
215 case '?':
216 print_usage(stderr);
217 ret = WS_EXIT_INVALID_OPTION;
218 goto clean_exit;
222 /* Remaining args are file names */
223 file_count = argc - ws_optind;
224 if (file_count == 2) {
225 infile = argv[ws_optind];
226 outfile = argv[ws_optind+1];
228 else {
229 print_usage(stderr);
230 ret = WS_EXIT_INVALID_OPTION;
231 goto clean_exit;
234 /* Open infile */
235 /* TODO: if reordercap is ever changed to give the user a choice of which
236 open_routine reader to use, then the following needs to change. */
237 wth = wtap_open_offline(infile, WTAP_TYPE_AUTO, &err, &err_info, true);
238 if (wth == NULL) {
239 cfile_open_failure_message(infile, err, err_info);
240 ret = WS_EXIT_OPEN_ERROR;
241 goto clean_exit;
243 DEBUG_PRINT("file_type_subtype is %d\n", wtap_file_type_subtype(wth));
245 /* Allocate the array of frame pointers. */
246 frames = g_ptr_array_new();
248 /* Read each frame from infile */
249 wtap_rec_init(&rec, 1514);
250 while (wtap_read(wth, &rec, &err, &err_info, &data_offset)) {
251 FrameRecord_t *newFrameRecord;
253 newFrameRecord = g_slice_new(FrameRecord_t);
254 newFrameRecord->num = frames->len + 1;
255 newFrameRecord->offset = data_offset;
256 if (rec.presence_flags & WTAP_HAS_TS) {
257 newFrameRecord->frame_time = rec.ts;
258 } else {
259 nstime_set_unset(&newFrameRecord->frame_time);
262 if (prevFrame && frames_compare(&newFrameRecord, &prevFrame) < 0) {
263 wrong_order_count++;
266 g_ptr_array_add(frames, newFrameRecord);
267 prevFrame = newFrameRecord;
268 wtap_rec_reset(&rec);
270 wtap_rec_cleanup(&rec);
271 if (err != 0) {
272 /* Print a message noting that the read failed somewhere along the line. */
273 cfile_read_failure_message(infile, err, err_info);
276 printf("%u frames, %u out of order\n", frames->len, wrong_order_count);
278 wtap_dump_params_init(&params, wth);
280 /* Sort the frames */
281 /* XXX - Does this handle multiple SHBs correctly? */
282 if (wrong_order_count > 0) {
283 g_ptr_array_sort(frames, frames_compare);
287 /* Avoid writing if already sorted and configured to */
288 if (write_output_regardless || (wrong_order_count > 0)) {
289 /* Open outfile (same filetype/encap as input file) */
290 if (strcmp(outfile, "-") == 0) {
291 pdh = wtap_dump_open_stdout(wtap_file_type_subtype(wth),
292 WTAP_UNCOMPRESSED, &params, &err, &err_info);
293 } else {
294 pdh = wtap_dump_open(outfile, wtap_file_type_subtype(wth),
295 WTAP_UNCOMPRESSED, &params, &err, &err_info);
297 g_free(params.idb_inf);
298 params.idb_inf = NULL;
300 if (pdh == NULL) {
301 cfile_dump_open_failure_message(outfile, err, err_info,
302 wtap_file_type_subtype(wth));
303 wtap_dump_params_cleanup(&params);
304 ret = OUTPUT_FILE_ERROR;
305 goto clean_exit;
309 /* Write out each sorted frame in turn */
310 wtap_rec_init(&rec, 1514);
311 for (i = 0; i < frames->len; i++) {
312 FrameRecord_t *frame = (FrameRecord_t *)frames->pdata[i];
314 frame_write(frame, wth, pdh, &rec, infile, outfile);
316 g_slice_free(FrameRecord_t, frame);
319 wtap_rec_cleanup(&rec);
323 /* Close outfile */
324 if (!wtap_dump_close(pdh, NULL, &err, &err_info)) {
325 cfile_close_failure_message(outfile, err, err_info);
326 wtap_dump_params_cleanup(&params);
327 ret = OUTPUT_FILE_ERROR;
328 goto clean_exit;
330 } else {
331 printf("Not writing output file because input file is already in order.\n");
333 /* Free frame memory */
334 for (i = 0; i < frames->len; i++) {
335 FrameRecord_t *frame = (FrameRecord_t *)frames->pdata[i];
337 g_slice_free(FrameRecord_t, frame);
342 /* Free the whole array */
343 g_ptr_array_free(frames, TRUE);
345 wtap_dump_params_cleanup(&params);
347 /* Finally, close infile and release resources. */
348 wtap_close(wth);
350 clean_exit:
351 wtap_cleanup();
352 free_progdirs();
353 return ret;
357 * Editor modelines - https://www.wireshark.org/tools/modelines.html
359 * Local variables:
360 * c-basic-offset: 4
361 * tab-width: 8
362 * indent-tabs-mode: nil
363 * End:
365 * vi: set shiftwidth=4 tabstop=8 expandtab:
366 * :indentSize=4:tabSize=8:noTabs=true: