source: lib/format_duck.c @ 15e9390

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

Support using timespec's for dealing with traces

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