source: lib/format_duck.c @ 5511c14

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 5511c14 was 5511c14, checked in by Shane Alcock <salcock@…>, 12 years ago
  • Tidied up the format data structures in format_erf. In particular, removed unnecessary unions.
  • Updated licensing and documentation for format_duck and format_erf
  • Property mode set to 100644
File size: 9.7 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 fileflag;
71        iow_t *file;
72        int dag_version;       
73};
74
75static int duck_init_input(libtrace_t *libtrace) {
76        libtrace->format_data = malloc(sizeof(struct duck_format_data_t));
77
78        DATA(libtrace)->dag_version = 0;
79        return 0;
80}
81
82static int duck_init_output(libtrace_out_t *libtrace) {
83        libtrace->format_data = malloc(sizeof(struct duck_format_data_out_t));
84       
85        OUTPUT->level = 0;
86        OUTPUT->fileflag = O_CREAT | O_WRONLY;
87        OUTPUT->file = 0;
88        OUTPUT->dag_version = 0;
89        return 0;
90}
91
92static int duck_config_output(libtrace_out_t *libtrace, 
93                                trace_option_output_t option,
94                                void *data) {
95        switch (option) {
96                case TRACE_OPTION_OUTPUT_COMPRESS:
97                        OUTPUT->level = *(int *)data;
98                        return 0;
99                case TRACE_OPTION_OUTPUT_FILEFLAGS:
100                        OUTPUT->fileflag = *(int *)data;
101                        return 0;
102                default:
103                        trace_set_err_out(libtrace, TRACE_ERR_UNKNOWN_OPTION,
104                                        "Unknown option");
105                        return -1;
106        }
107        assert(0);
108}
109
110static int duck_start_input(libtrace_t *libtrace) {
111       
112        if (libtrace->io)
113                /* File already open */
114                return 0;
115       
116        libtrace->io = trace_open_file(libtrace);
117        if (!libtrace->io)
118                return -1;
119
120        return 0;
121}
122
123static int duck_start_output(libtrace_out_t *libtrace) {
124        OUTPUT->file = trace_open_file_out(libtrace, OUTPUT->level,
125                                                OUTPUT->fileflag);
126        if (!OUTPUT->file) {
127                return -1;
128        }
129        return 0;
130}
131
132static int duck_fin_input(libtrace_t *libtrace) {
133        wandio_destroy(libtrace->io);
134        free(libtrace->format_data);
135
136        return 0;
137}
138
139static int duck_fin_output(libtrace_out_t *libtrace) {
140        wandio_wdestroy(OUTPUT->file);
141        free(libtrace->format_data);
142        return 0;
143}
144
145static int duck_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
146                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
147
148        if (packet->buffer != buffer &&
149                        packet->buf_control == TRACE_CTRL_PACKET) {
150                free(packet->buffer);
151        }
152
153        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
154                packet->buf_control = TRACE_CTRL_PACKET;
155        } else
156                packet->buf_control = TRACE_CTRL_EXTERNAL;
157
158
159        packet->buffer = buffer;
160        packet->header = NULL;
161        packet->payload = buffer;
162        packet->type = rt_type;
163
164        if (libtrace->format_data == NULL) {
165                if (duck_init_input(libtrace))
166                        return -1;
167        }
168
169        return 0;
170}
171
172static int duck_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
173
174        int numbytes = 0;
175        uint32_t version = 0;
176        unsigned int duck_size;
177        uint32_t flags = 0;
178       
179        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
180                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
181                if (!packet->buffer) {
182                        trace_set_err(libtrace, errno,
183                                        "Cannot allocate memory");
184                        return -1;
185                }
186        }
187
188        flags |= TRACE_PREP_OWN_BUFFER;
189       
190        if (DATA(libtrace)->dag_version == 0) {
191                /* Read in the duck version from the start of the trace */
192                if ((numbytes = wandio_read(libtrace->io, &version, 
193                                        sizeof(version))) != sizeof(uint32_t)) {
194                        trace_set_err(libtrace, errno, 
195                                        "Reading DUCK version failed");
196                        return -1;
197                }
198                if (numbytes == 0) {
199                        return 0;
200                }
201                DATA(libtrace)->dag_version = bswap_le_to_host32(version);
202        }
203       
204
205        if (DATA(libtrace)->dag_version == TRACE_RT_DUCK_2_4) {
206                duck_size = sizeof(duck2_4_t);
207                packet->type = TRACE_RT_DUCK_2_4;
208        } else if (DATA(libtrace)->dag_version == TRACE_RT_DUCK_2_5) {
209                duck_size = sizeof(duck2_5_t);
210                packet->type = TRACE_RT_DUCK_2_5;
211        } else {
212                trace_set_err(libtrace, TRACE_ERR_BAD_PACKET,
213                                "Unrecognised DUCK version %i", 
214                                DATA(libtrace)->dag_version);
215                return -1;
216        }
217
218        if ((numbytes = wandio_read(libtrace->io, packet->buffer,
219                                        (size_t)duck_size)) != (int)duck_size) {
220                if (numbytes == -1) {
221                        trace_set_err(libtrace, errno, "Reading DUCK failed");
222                        return -1;
223                }
224                else if (numbytes == 0) {
225                        return 0;
226                }
227                else {
228                        trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Truncated DUCK packet");
229                }
230        }
231
232        if (duck_prepare_packet(libtrace, packet, packet->buffer, packet->type,
233                                flags)) 
234                return -1;
235       
236        return numbytes;
237}
238
239static int duck_write_packet(libtrace_out_t *libtrace, 
240                libtrace_packet_t *packet) 
241{
242
243        int numbytes = 0;
244        if (packet->type != TRACE_RT_DUCK_2_4
245                        && packet->type != TRACE_RT_DUCK_2_5) {
246                trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET,
247                                "Only DUCK packets may be written to a DUCK file");
248                return -1;
249        }
250       
251        assert(OUTPUT->file);
252
253        if (OUTPUT->dag_version == 0) {
254        /* Writing the DUCK version will help with reading it back in later! */
255                if ((numbytes = wandio_wwrite(OUTPUT->file, &packet->type,
256                                sizeof(packet->type))) != sizeof(uint32_t)){
257                        trace_set_err_out(libtrace, errno, 
258                                        "Writing DUCK version failed");
259                        return -1;
260                }
261                OUTPUT->dag_version = packet->type;
262        }
263       
264        if ((numbytes = wandio_wwrite(OUTPUT->file, packet->payload, 
265                                        trace_get_capture_length(packet))) !=
266                                (int)trace_get_capture_length(packet)) {
267                trace_set_err_out(libtrace, errno, "Writing DUCK failed");
268                return -1;
269        }
270        return numbytes;
271}
272
273static int duck_get_capture_length(const libtrace_packet_t *packet) {
274        switch(packet->type) {
275                case TRACE_RT_DUCK_2_4:
276                        return sizeof(duck2_4_t);
277                case TRACE_RT_DUCK_2_5:
278                        return sizeof(duck2_5_t);
279                default:
280                        trace_set_err(packet->trace,TRACE_ERR_BAD_PACKET,
281                                        "Not a duck packet");
282                        return -1;
283        }
284        return 0;
285}
286
287static int duck_get_framing_length(const libtrace_packet_t *packet UNUSED) 
288{
289        return 0;
290}
291
292static int duck_get_wire_length(const libtrace_packet_t *packet UNUSED) 
293{
294        return 0;
295}
296
297static libtrace_linktype_t duck_get_link_type(
298                                const libtrace_packet_t *packet UNUSED) 
299{
300        return TRACE_TYPE_DUCK;
301}
302
303static void duck_help(void) {
304        printf("Endace DUCK format module\n");
305        printf("Supported input uris:\n");
306        printf("\tduck:/path/to/input/file\n");
307        printf("Supported output uris:\n");
308        printf("\tduck:/path/to/output/file\n");
309        printf("\n");
310        return;
311}
312static struct libtrace_format_t duck = {
313        "duck",
314        "$Id$",
315        TRACE_FORMAT_DUCK,
316        NULL,                           /* probe filename */
317        NULL,                           /* probe magic */
318        duck_init_input,                /* init_input */
319        NULL,                           /* config_input */
320        duck_start_input,               /* start_input */
321        NULL,                           /* pause_input */
322        duck_init_output,               /* init_output */
323        duck_config_output,             /* config_output */
324        duck_start_output,              /* start_output */
325        duck_fin_input,                 /* fin_input */
326        duck_fin_output,                /* fin_output */
327        duck_read_packet,               /* read_packet */
328        duck_prepare_packet,            /* prepare_packet */
329        NULL,                           /* fin_packet */
330        duck_write_packet,              /* write_packet */
331        duck_get_link_type,             /* get_link_type */
332        NULL,                           /* get_direction */
333        NULL,                           /* set_direction */
334        NULL,                           /* get_erf_timestamp */
335        NULL,                           /* get_timeval */
336        NULL,                           /* get_timespec */
337        NULL,                           /* get_seconds */
338        NULL,                           /* seek_erf */
339        NULL,                           /* seek_timeval */
340        NULL,                           /* seek_seconds */
341        duck_get_capture_length,        /* get_capture_length */
342        duck_get_wire_length,           /* get_wire_length */
343        duck_get_framing_length,        /* get_framing_length */
344        NULL,                           /* set_capture_length */
345        NULL,                           /* get_received_packets */
346        NULL,                           /* get_filtered_packets */
347        NULL,                           /* get_dropped_packets */
348        NULL,                           /* get_captured_packets */
349        NULL,                           /* get_fd */
350        NULL,                           /* trace_event */
351        duck_help,                      /* help */
352        NULL                            /* next pointer */
353};
354
355void duck_constructor(void) {
356        register_format(&duck);
357}       
Note: See TracBrowser for help on using the repository browser.