source: lib/format_duck.c @ d5a42c2

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

Split compression type out from fileflags

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