source: lib/format_duck.c @ c66068d

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

Rewrite the libtrace io subsystem to use the new wandio abstraction layer.

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