source: lib/format_duck.c @ dd06159

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

Add svn:keyword properties

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