source: lib/format_duck.c @ f051c1b

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since f051c1b was b13b939, checked in by Richard Sanger <rsangerarj@…>, 7 years ago

Adds a configuration option for the tick messages.
Adds the trace_information structure which contains information about traces.
Updates trace_rt_stats to use both of these.

Replaced libtrace_t->joined internally with a state

  • Property mode set to 100644
File size: 10.0 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 "config.h"
35#include "libtrace.h"
36#include "libtrace_int.h"
37#include "format_helper.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        uint32_t duck_version;
252
253        if (packet->type != TRACE_RT_DUCK_2_4
254                        && packet->type != TRACE_RT_DUCK_2_5) {
255                trace_set_err_out(libtrace, TRACE_ERR_BAD_PACKET,
256                                "Only DUCK packets may be written to a DUCK file");
257                return -1;
258        }
259       
260        assert(OUTPUT->file);
261
262        if (OUTPUT->dag_version == 0) {
263        /* Writing the DUCK version will help with reading it back in later! */
264                duck_version = bswap_host_to_le32(packet->type);
265                if ((numbytes = wandio_wwrite(OUTPUT->file, &duck_version,
266                                sizeof(duck_version))) != sizeof(uint32_t)){
267                        trace_set_err_out(libtrace, errno, 
268                                        "Writing DUCK version failed");
269                        return -1;
270                }
271                OUTPUT->dag_version = packet->type;
272        }
273       
274        if ((numbytes = wandio_wwrite(OUTPUT->file, packet->payload, 
275                                        trace_get_capture_length(packet))) !=
276                                (int)trace_get_capture_length(packet)) {
277                trace_set_err_out(libtrace, errno, "Writing DUCK failed");
278                return -1;
279        }
280        return numbytes;
281}
282
283static int duck_get_capture_length(const libtrace_packet_t *packet) {
284        switch(packet->type) {
285                case TRACE_RT_DUCK_2_4:
286                        return sizeof(duck2_4_t);
287                case TRACE_RT_DUCK_2_5:
288                        return sizeof(duck2_5_t);
289                default:
290                        trace_set_err(packet->trace,TRACE_ERR_BAD_PACKET,
291                                        "Not a duck packet");
292                        return -1;
293        }
294        return 0;
295}
296
297static int duck_get_framing_length(const libtrace_packet_t *packet UNUSED) 
298{
299        return 0;
300}
301
302static int duck_get_wire_length(const libtrace_packet_t *packet UNUSED) 
303{
304        return 0;
305}
306
307static libtrace_linktype_t duck_get_link_type(
308                                const libtrace_packet_t *packet UNUSED) 
309{
310        return TRACE_TYPE_DUCK;
311}
312
313static void duck_help(void) {
314        printf("Endace DUCK format module\n");
315        printf("Supported input uris:\n");
316        printf("\tduck:/path/to/input/file\n");
317        printf("Supported output uris:\n");
318        printf("\tduck:/path/to/output/file\n");
319        printf("\n");
320        return;
321}
322static struct libtrace_format_t duck = {
323        "duck",
324        "$Id$",
325        TRACE_FORMAT_DUCK,
326        NULL,                           /* probe filename */
327        NULL,                           /* probe magic */
328        duck_init_input,                /* init_input */
329        NULL,                           /* config_input */
330        duck_start_input,               /* start_input */
331        NULL,                           /* pause_input */
332        duck_init_output,               /* init_output */
333        duck_config_output,             /* config_output */
334        duck_start_output,              /* start_output */
335        duck_fin_input,                 /* fin_input */
336        duck_fin_output,                /* fin_output */
337        duck_read_packet,               /* read_packet */
338        duck_prepare_packet,            /* prepare_packet */
339        NULL,                           /* fin_packet */
340        duck_write_packet,              /* write_packet */
341        duck_get_link_type,             /* get_link_type */
342        NULL,                           /* get_direction */
343        NULL,                           /* set_direction */
344        NULL,                           /* get_erf_timestamp */
345        NULL,                           /* get_timeval */
346        NULL,                           /* get_timespec */
347        NULL,                           /* get_seconds */
348        NULL,                           /* seek_erf */
349        NULL,                           /* seek_timeval */
350        NULL,                           /* seek_seconds */
351        duck_get_capture_length,        /* get_capture_length */
352        duck_get_wire_length,           /* get_wire_length */
353        duck_get_framing_length,        /* get_framing_length */
354        NULL,                           /* set_capture_length */
355        NULL,                           /* get_received_packets */
356        NULL,                           /* get_filtered_packets */
357        NULL,                           /* get_dropped_packets */
358        NULL,                           /* get_captured_packets */
359        NULL,                           /* get_fd */
360        NULL,                           /* trace_event */
361        duck_help,                      /* help */
362        NULL,                            /* next pointer */
363        NON_PARALLEL(false)
364};
365
366void duck_constructor(void) {
367        register_format(&duck);
368}       
Note: See TracBrowser for help on using the repository browser.