source: lib/format_tsh.c @ c66068d

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

Rewrite the libtrace io subsystem to use the new wandio abstraction layer.

  • Property mode set to 100644
File size: 8.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: Perry Lorier
6 *         
7 * All rights reserved.
8 *
9 * This code has been developed by the University of Waikato WAND
10 * research group. For further information please see http://www.wand.net.nz/
11 *
12 * libtrace is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * libtrace is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with libtrace; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25 *
26 * $Id$
27 *
28 */
29#include "config.h"
30#include "common.h"
31#include "libtrace.h"
32#include "libtrace_int.h"
33#include "format_helper.h"
34
35#include <assert.h>
36#include <errno.h>
37#include <fcntl.h>
38#include <stdio.h>
39#include <string.h>
40#include <stdlib.h>
41
42static struct libtrace_format_t tshformat;
43
44#define DATA(x) ((struct tsh_format_data_t *)x->format_data)
45
46struct tsh_format_data_t {
47        io_t *file;
48};
49
50typedef struct tsh_pkt_header_t {
51        uint32_t seconds;
52        uint32_t usecs;
53} tsh_pkt_header_t;
54
55static int tsh_get_framing_length(const libtrace_packet_t *packet)
56{
57        return sizeof(tsh_pkt_header_t);
58}
59
60
61static int tsh_init_input(libtrace_t *libtrace) 
62{
63        libtrace->format_data = malloc(sizeof(struct tsh_format_data_t));
64       
65        DATA(libtrace)->file = 0;
66
67        return 0; /* success */
68}
69
70static int tsh_start_input(libtrace_t *libtrace)
71{
72        if (DATA(libtrace)->file)
73                return 0; /* success */
74
75        DATA(libtrace)->file = trace_open_file(libtrace);
76
77        if (!DATA(libtrace)->file)
78                return -1;
79
80        return 0; /* success */
81}
82
83static int tsh_fin_input(libtrace_t *libtrace) {
84        if (DATA(libtrace)->file)
85                wandio_destroy(DATA(libtrace)->file);
86        free(libtrace->format_data);
87        return 0;
88}
89
90static int tsh_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
91                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
92        if (packet->buffer != buffer &&
93                        packet->buf_control == TRACE_CTRL_PACKET) {
94                free(packet->buffer);
95        }
96
97        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
98                packet->buf_control = TRACE_CTRL_PACKET;
99        } else
100                packet->buf_control = TRACE_CTRL_EXTERNAL;
101
102
103        packet->buffer = buffer;
104        packet->header = buffer;
105        packet->type = rt_type;
106        packet->payload = (char *)packet->buffer + sizeof(tsh_pkt_header_t);
107
108        if (libtrace->format_data == NULL) {
109                if (tsh_init_input(libtrace))
110                        return -1;
111        }
112
113        return 0;
114}
115
116static int tsh_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
117        int numbytes;
118        void *buffer2 = packet->buffer;
119        uint32_t flags = 0;
120
121        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
122                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
123                if (!packet->buffer) {
124                        trace_set_err(libtrace, errno, 
125                                        "Cannot allocate memory");
126                        return -1;
127                }
128        }
129
130        flags |= TRACE_PREP_OWN_BUFFER;
131        packet->type = TRACE_RT_DATA_TSH;
132
133        buffer2 = packet->buffer;
134
135        /* Read the TSH header */
136        if ((numbytes=wandio_read(DATA(libtrace)->file,
137                                        buffer2,
138                                        (size_t)sizeof(tsh_pkt_header_t))) == -1) {
139                trace_set_err(libtrace,errno,"read(%s)",
140                                libtrace->uridata);
141                return -1;
142        }
143        /* EOF */
144        if (numbytes == 0) {
145                return 0;
146        }
147
148        buffer2 = (char*)buffer2 + numbytes;
149
150        /* Read the IP header */
151        if ((numbytes=wandio_read(DATA(libtrace)->file,
152                                buffer2,
153                                (size_t)sizeof(libtrace_ip_t))) 
154                        != sizeof(libtrace_ip_t)) {
155                trace_set_err(libtrace,errno,"read(%s)",
156                                libtrace->uridata);
157                return -1;
158        }
159
160        /* IP Options aren't captured in the trace, so leave room
161         * for them, and put the transport header where it "should" be
162         */
163        buffer2 = (char*)buffer2 + ((libtrace_ip_t*)buffer2)->ip_hl*4;
164
165        /* Read the transport header */
166        if ((numbytes=wandio_read(DATA(libtrace)->file,
167                                buffer2,
168                                16)) != 16) {
169                trace_set_err(libtrace,errno,"read(%s)",
170                                libtrace->uridata);
171                return -1;
172        }
173       
174        if (tsh_prepare_packet(libtrace, packet, packet->buffer, packet->type, 
175                                flags)) {
176                return -1;
177        }
178
179
180        return 80;
181}
182
183static libtrace_linktype_t tsh_get_link_type(const libtrace_packet_t *packet) {
184        return TRACE_TYPE_NONE;
185}
186
187static libtrace_direction_t tsh_get_direction(const libtrace_packet_t *packet) {
188        return ntohl(((tsh_pkt_header_t*)(packet->header))->usecs & htonl(0xFF000000)) >> 24;
189}
190
191static struct timeval tsh_get_timeval(const libtrace_packet_t *packet)
192{
193        struct timeval tv;
194        tv.tv_sec=ntohl(((tsh_pkt_header_t*)(packet->header))->seconds);
195        tv.tv_usec=ntohl(((tsh_pkt_header_t*)(packet->header))->usecs & htonl(0x00FFFFFF));
196
197        return tv;
198}
199
200static int tsh_get_capture_length(const libtrace_packet_t *packet) {
201        /* 16 bytes transport + 24 bytes IP, and we're missing the
202         * IP options, but we'll pretend we have them
203         */
204        return 16+((libtrace_ip_t*)packet->payload)->ip_hl*4;
205}
206
207static int tsh_get_wire_length(const libtrace_packet_t *packet) {
208        return ((libtrace_ip_t*)packet->payload)->ip_len;
209}
210
211static void tsh_help(void) {
212        printf("tsh format module: $Revision$\n");
213        printf("Supported input URIs:\n");
214        printf("\ttsh:/path/to/file\t(uncompressed)\n");
215        printf("\ttsh:/path/to/file.gz\t(gzip-compressed)\n");
216        printf("\ttsh:-\t(stdin, either compressed or not)\n");
217        printf("\ttsh:/path/to/socket\n");
218        printf("\n");
219        printf("\te.g.: erf:/tmp/trace\n");
220        printf("\n");
221}
222
223static struct libtrace_format_t tshformat = {
224        "tsh",
225        "$Id$",
226        TRACE_FORMAT_TSH,
227        tsh_init_input,                 /* init_input */       
228        NULL,                           /* config_input */
229        tsh_start_input,                /* start_input */
230        NULL,                           /* pause_input */
231        NULL,                           /* init_output */
232        NULL,                           /* config_output */
233        NULL,                           /* start_output */
234        tsh_fin_input,                  /* fin_input */
235        NULL,                           /* fin_output */
236        tsh_read_packet,                /* read_packet */
237        tsh_prepare_packet,             /* prepare_packet */
238        NULL,                           /* fin_packet */
239        NULL,                           /* write_packet */
240        tsh_get_link_type,              /* get_link_type */
241        tsh_get_direction,              /* get_direction */
242        NULL,                           /* set_direction */
243        NULL,                           /* get_erf_timestamp */
244        tsh_get_timeval,                /* get_timeval */
245        NULL,                           /* get_seconds */
246        NULL,                           /* seek_erf */
247        NULL,                           /* seek_timeval */
248        NULL,                           /* seek_seconds */
249        tsh_get_capture_length,         /* get_capture_length */
250        tsh_get_wire_length,            /* get_wire_length */
251        tsh_get_framing_length,         /* get_framing_length */
252        NULL,                           /* set_capture_length */
253        NULL,                           /* get_received_packets */
254        NULL,                           /* get_filtered_packets */
255        NULL,                           /* get_dropped_packets */
256        NULL,                           /* get_captured_packets */
257        NULL,                           /* get_fd */
258        trace_event_trace,              /* trace_event */
259        tsh_help,                       /* help */
260        NULL                            /* next pointer */
261};
262
263/* the tsh header format is the same as tsh, except that the bits that will
264 * always be "0" in the fr+ format are used for an "interface" identifier,
265 * thus on tr+ traces, this will always be 0.  So, we use the exact same
266 * decoder for both traces.
267 */
268static struct libtrace_format_t frplusformat = {
269        "fr+",
270        "$Id$",
271        TRACE_FORMAT_TSH,
272        tsh_init_input,                 /* init_input */       
273        NULL,                           /* config_input */
274        tsh_start_input,                /* start_input */
275        NULL,                           /* pause_input */
276        NULL,                           /* init_output */
277        NULL,                           /* config_output */
278        NULL,                           /* start_output */
279        tsh_fin_input,                  /* fin_input */
280        NULL,                           /* fin_output */
281        tsh_read_packet,                /* read_packet */
282        tsh_prepare_packet,             /* prepare_packet */
283        NULL,                           /* fin_packet */
284        NULL,                           /* write_packet */
285        tsh_get_link_type,              /* get_link_type */
286        tsh_get_direction,              /* get_direction */
287        NULL,                           /* set_direction */
288        NULL,                           /* get_erf_timestamp */
289        tsh_get_timeval,                /* get_timeval */
290        NULL,                           /* get_seconds */
291        NULL,                           /* seek_erf */
292        NULL,                           /* seek_timeval */
293        NULL,                           /* seek_seconds */
294        tsh_get_capture_length,         /* get_capture_length */
295        tsh_get_wire_length,            /* get_wire_length */
296        tsh_get_framing_length,         /* get_framing_length */
297        NULL,                           /* set_capture_length */
298        NULL,                           /* get_received_packets */
299        NULL,                           /* get_filtered_packets */
300        NULL,                           /* get_dropped_packets */
301        NULL,                           /* get_captured_packets */
302        NULL,                           /* get_fd */
303        trace_event_trace,              /* trace_event */
304        tsh_help,                       /* help */
305        NULL                            /* next pointer */
306};
307
308void tsh_constructor(void) {
309        register_format(&tshformat);
310        register_format(&frplusformat);
311}
Note: See TracBrowser for help on using the repository browser.