source: lib/format_duck.c @ 91b72d3

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 91b72d3 was 91b72d3, checked in by Perry Lorier <perry@…>, 12 years ago

Try to autoguess the tracetype if the format uri specify is not present

  • Property mode set to 100644
File size: 9.3 KB
RevLine 
[cd7eec7]1/*
2 * This file is part of libtrace
3 *
[f3f3558]4 * Copyright (c) 2007,2008 The University of Waikato, Hamilton, New Zealand.
[cd7eec7]5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
[293999b]27 * $Id$
[cd7eec7]28 *
29 */
30
31#include "libtrace.h"
32#include "libtrace_int.h"
33#include "format_helper.h"
34#include "config.h"
[c66068d]35#include "wandio.h"
[cd7eec7]36#include <stdlib.h>
37#include "rt_protocol.h"
38
39#include <errno.h>
40#include <assert.h>
41#include <stdio.h>
42#include <fcntl.h>
43
44#define DATA(x) ((struct duck_format_data_t *)x->format_data)
45#define DATAOUT(x) ((struct duck_format_data_out_t *)x->format_data)
46
47#define OUTPUT DATAOUT(libtrace)
48
49struct duck_format_data_t {
50        char *path;
51        int dag_version;
52};
53
54struct duck_format_data_out_t {
55        char *path;
56        int level;
57        int fileflag;
[c66068d]58        iow_t *file;
[cd7eec7]59        int dag_version;       
60};
61
62static int duck_init_input(libtrace_t *libtrace) {
63        libtrace->format_data = malloc(sizeof(struct duck_format_data_t));
64
[91b72d3]65        DATA(libtrace)->dag_version = 0;
[cd7eec7]66        return 0;
67}
68
69static int duck_init_output(libtrace_out_t *libtrace) {
70        libtrace->format_data = malloc(sizeof(struct duck_format_data_out_t));
71       
72        OUTPUT->level = 0;
73        OUTPUT->fileflag = O_CREAT | O_WRONLY;
74        OUTPUT->file = 0;
75        OUTPUT->dag_version = 0;
76        return 0;
77}
78
79static int duck_config_output(libtrace_out_t *libtrace, 
80                                trace_option_output_t option,
81                                void *data) {
82        switch (option) {
83                case TRACE_OPTION_OUTPUT_COMPRESS:
84                        OUTPUT->level = *(int *)data;
85                        return 0;
86                case TRACE_OPTION_OUTPUT_FILEFLAGS:
87                        OUTPUT->fileflag = *(int *)data;
88                        return 0;
89                default:
90                        trace_set_err_out(libtrace, TRACE_ERR_UNKNOWN_OPTION,
91                                        "Unknown option");
92                        return -1;
93        }
94        assert(0);
95}
96
97static int duck_start_input(libtrace_t *libtrace) {
98       
[91b72d3]99        if (libtrace->io)
[cd7eec7]100                /* File already open */
101                return 0;
102       
[91b72d3]103        libtrace->io = trace_open_file(libtrace);
104        if (!libtrace->io)
[cd7eec7]105                return -1;
106
107        return 0;
108}
109
110static int duck_start_output(libtrace_out_t *libtrace) {
111        OUTPUT->file = trace_open_file_out(libtrace, OUTPUT->level,
112                                                OUTPUT->fileflag);
113        if (!OUTPUT->file) {
114                return -1;
115        }
116        return 0;
117}
118
119static int duck_fin_input(libtrace_t *libtrace) {
[91b72d3]120        wandio_destroy(libtrace->io);
[cd7eec7]121        free(libtrace->format_data);
122
123        return 0;
124}
125
126static int duck_fin_output(libtrace_out_t *libtrace) {
[c66068d]127        wandio_wdestroy(OUTPUT->file);
[cd7eec7]128        free(libtrace->format_data);
129        return 0;
130}
131
[f0fb38f]132static int duck_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
133                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
134
135        if (packet->buffer != buffer &&
136                        packet->buf_control == TRACE_CTRL_PACKET) {
137                free(packet->buffer);
138        }
139
140        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
141                packet->buf_control = TRACE_CTRL_PACKET;
142        } else
143                packet->buf_control = TRACE_CTRL_EXTERNAL;
144
145
146        packet->buffer = buffer;
147        packet->header = NULL;
148        packet->payload = buffer;
149        packet->type = rt_type;
150
151        if (libtrace->format_data == NULL) {
152                if (duck_init_input(libtrace))
153                        return -1;
154        }
155
156        return 0;
157}
158
[cd7eec7]159static int duck_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
160
161        int numbytes = 0;
162        uint32_t version = 0;
[33d83d4]163        unsigned int duck_size;
[f0fb38f]164        uint32_t flags = 0;
[cd7eec7]165       
166        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
[4bd8a5b]167                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
[cd7eec7]168                if (!packet->buffer) {
169                        trace_set_err(libtrace, errno,
170                                        "Cannot allocate memory");
171                        return -1;
172                }
173        }
174
[f0fb38f]175        flags |= TRACE_PREP_OWN_BUFFER;
176       
[91b72d3]177        if (DATA(libtrace)->dag_version == 0) {
[cd7eec7]178                /* Read in the duck version from the start of the trace */
[91b72d3]179                if ((numbytes = wandio_read(libtrace->io, &version, 
[c28b5c7]180                                        sizeof(version))) != sizeof(uint32_t)) {
[cd7eec7]181                        trace_set_err(libtrace, errno, 
182                                        "Reading DUCK version failed");
183                        return -1;
184                }
185                if (numbytes == 0) {
186                        return 0;
187                }
[91b72d3]188                DATA(libtrace)->dag_version = bswap_le_to_host32(version);
[cd7eec7]189        }
190       
191
[91b72d3]192        if (DATA(libtrace)->dag_version == TRACE_RT_DUCK_2_4) {
[cd7eec7]193                duck_size = sizeof(duck2_4_t);
[cab58c5]194                packet->type = TRACE_RT_DUCK_2_4;
[91b72d3]195        } else if (DATA(libtrace)->dag_version == TRACE_RT_DUCK_2_5) {
[cd7eec7]196                duck_size = sizeof(duck2_5_t);
[cab58c5]197                packet->type = TRACE_RT_DUCK_2_5;
[cd7eec7]198        } else {
199                trace_set_err(libtrace, TRACE_ERR_BAD_PACKET,
200                                "Unrecognised DUCK version %i", 
[91b72d3]201                                DATA(libtrace)->dag_version);
[cd7eec7]202                return -1;
203        }
204
[91b72d3]205        if ((numbytes = wandio_read(libtrace->io, packet->buffer,
[4bd8a5b]206                                        (size_t)duck_size)) != (int)duck_size) {
[575c531]207                if (numbytes == -1) {
[cd7eec7]208                        trace_set_err(libtrace, errno, "Reading DUCK failed");
209                        return -1;
210                }
[575c531]211                else if (numbytes == 0) {
212                        return 0;
213                }
214                else {
215                        trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Truncated DUCK packet");
216                }
[cd7eec7]217        }
218
[f0fb38f]219        if (duck_prepare_packet(libtrace, packet, packet->buffer, packet->type,
220                                flags)) 
221                return -1;
222       
[cd7eec7]223        return numbytes;
224}
225
226static int duck_write_packet(libtrace_out_t *libtrace, 
[85a79b0]227                libtrace_packet_t *packet) 
228{
[cd7eec7]229
230        int numbytes = 0;
[cab58c5]231        if (packet->type != TRACE_RT_DUCK_2_4
232                        && packet->type != TRACE_RT_DUCK_2_5) {
[cd7eec7]233                trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET,
234                                "Only DUCK packets may be written to a DUCK file");
235                return -1;
236        }
237       
238        assert(OUTPUT->file);
239
240        if (OUTPUT->dag_version == 0) {
241        /* Writing the DUCK version will help with reading it back in later! */
[c66068d]242                if ((numbytes = wandio_wwrite(OUTPUT->file, &packet->type,
[c0cd256]243                                sizeof(packet->type))) != sizeof(uint32_t)){
[cd7eec7]244                        trace_set_err_out(libtrace, errno, 
245                                        "Writing DUCK version failed");
246                        return -1;
247                }
248                OUTPUT->dag_version = packet->type;
249        }
250       
[c66068d]251        if ((numbytes = wandio_wwrite(OUTPUT->file, packet->payload, 
[cd7eec7]252                                        trace_get_capture_length(packet))) !=
[85a79b0]253                                (int)trace_get_capture_length(packet)) {
[cd7eec7]254                trace_set_err_out(libtrace, errno, "Writing DUCK failed");
255                return -1;
256        }
257        return numbytes;
258}
259
260static int duck_get_capture_length(const libtrace_packet_t *packet) {
261        switch(packet->type) {
[cab58c5]262                case TRACE_RT_DUCK_2_4:
[cd7eec7]263                        return sizeof(duck2_4_t);
[cab58c5]264                case TRACE_RT_DUCK_2_5:
[cd7eec7]265                        return sizeof(duck2_5_t);
[2595c4d]266                default:
267                        trace_set_err(packet->trace,TRACE_ERR_BAD_PACKET,
268                                        "Not a duck packet");
269                        return -1;
[cd7eec7]270        }
271        return 0;
272}
273
[ac0fdbf]274static int duck_get_framing_length(const libtrace_packet_t *packet UNUSED) 
275{
[cd7eec7]276        return 0;
277}
278
[ac0fdbf]279static int duck_get_wire_length(const libtrace_packet_t *packet UNUSED) 
280{
[cd7eec7]281        return 0;
282}
283
[ac0fdbf]284static libtrace_linktype_t duck_get_link_type(
285                                const libtrace_packet_t *packet UNUSED) 
286{
[02b7297]287        return TRACE_TYPE_DUCK;
288}
289
[33d83d4]290static void duck_help(void) {
[cd7eec7]291        printf("Endace DUCK format module\n");
292        printf("Supported input uris:\n");
293        printf("\tduck:/path/to/input/file\n");
294        printf("Supported output uris:\n");
295        printf("\tduck:/path/to/output/file\n");
296        printf("\n");
297        return;
298}
299static struct libtrace_format_t duck = {
300        "duck",
[293999b]301        "$Id$",
[cd7eec7]302        TRACE_FORMAT_DUCK,
[91b72d3]303        NULL,                           /* probe filename */
304        NULL,                           /* probe magic */
[cd7eec7]305        duck_init_input,                /* init_input */
306        NULL,                           /* config_input */
307        duck_start_input,               /* start_input */
308        NULL,                           /* pause_input */
309        duck_init_output,               /* init_output */
310        duck_config_output,             /* config_output */
311        duck_start_output,              /* start_output */
312        duck_fin_input,                 /* fin_input */
313        duck_fin_output,                /* fin_output */
314        duck_read_packet,               /* read_packet */
[f0fb38f]315        duck_prepare_packet,            /* prepare_packet */
316        NULL,                           /* fin_packet */
[cd7eec7]317        duck_write_packet,              /* write_packet */
[02b7297]318        duck_get_link_type,             /* get_link_type */
[cd7eec7]319        NULL,                           /* get_direction */
320        NULL,                           /* set_direction */
321        NULL,                           /* get_erf_timestamp */
322        NULL,                           /* get_timeval */
323        NULL,                           /* get_seconds */
324        NULL,                           /* seek_erf */
325        NULL,                           /* seek_timeval */
326        NULL,                           /* seek_seconds */
327        duck_get_capture_length,        /* get_capture_length */
328        duck_get_wire_length,           /* get_wire_length */
329        duck_get_framing_length,        /* get_framing_length */
330        NULL,                           /* set_capture_length */
[f2fae49]331        NULL,                           /* get_received_packets */
332        NULL,                           /* get_filtered_packets */
333        NULL,                           /* get_dropped_packets */
334        NULL,                           /* get_captured_packets */
[cd7eec7]335        NULL,                           /* get_fd */
336        NULL,                           /* trace_event */
337        duck_help,                      /* help */
338        NULL                            /* next pointer */
339};
340
[33d83d4]341void duck_constructor(void) {
[cd7eec7]342        register_format(&duck);
343}       
Note: See TracBrowser for help on using the repository browser.