source: lib/format_duck.c @ ee6e802

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivendag_formatrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since ee6e802 was ee6e802, checked in by Shane Alcock <salcock@…>, 4 years ago

Updated copyright blurb on all source files

In some cases, this meant adding copyright blurbs to files that
had never had them before.

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