source: lib/format_tsh.c @ 756b8f9

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 756b8f9 was d8b05b7, checked in by Shane Alcock <salcock@…>, 6 years ago

Make sure our copyright covers recent years

Consistency across all of our source files is also nice.

  • Property mode set to 100644
File size: 8.9 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007-2015 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
35#include "config.h"
36#include "common.h"
37#include "libtrace.h"
38#include "libtrace_int.h"
39#include "format_helper.h"
40
41#include <assert.h>
42#include <errno.h>
43#include <fcntl.h>
44#include <stdio.h>
45#include <string.h>
46#include <stdlib.h>
47
48/* This format module deals with reading traces that are in the TSH format.
49 *
50 * We do not support writing TSH traces, because it's a pretty rubbish format.
51 */
52
53static struct libtrace_format_t tshformat;
54
55typedef struct tsh_pkt_header_t {
56        uint32_t seconds;
57        uint32_t usecs;
58} tsh_pkt_header_t;
59
60static int tsh_get_framing_length(const libtrace_packet_t *packet UNUSED)
61{
62        return sizeof(tsh_pkt_header_t);
63}
64
65
66static int tsh_init_input(libtrace_t *libtrace) 
67{
68        libtrace->format_data = NULL; /* No format data */
69       
70        return 0; /* success */
71}
72
73static int tsh_start_input(libtrace_t *libtrace)
74{
75        if (libtrace->io)
76                return 0; /* success */
77
78        libtrace->io = trace_open_file(libtrace);
79
80        if (!libtrace->io)
81                return -1;
82
83        return 0; /* success */
84}
85
86static int tsh_fin_input(libtrace_t *libtrace) {
87        if (libtrace->io)
88                wandio_destroy(libtrace->io);
89        return 0;
90}
91
92static int tsh_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
93                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
94        if (packet->buffer != buffer &&
95                        packet->buf_control == TRACE_CTRL_PACKET) {
96                free(packet->buffer);
97        }
98
99        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
100                packet->buf_control = TRACE_CTRL_PACKET;
101        } else
102                packet->buf_control = TRACE_CTRL_EXTERNAL;
103
104
105        packet->buffer = buffer;
106        packet->header = buffer;
107        packet->type = rt_type;
108        packet->payload = (char *)packet->buffer + sizeof(tsh_pkt_header_t);
109
110        if (libtrace->format_data == NULL) {
111                if (tsh_init_input(libtrace))
112                        return -1;
113        }
114
115        return 0;
116}
117
118static int tsh_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
119        int numbytes;
120        void *buffer2 = packet->buffer;
121        uint32_t flags = 0;
122
123        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
124                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
125                if (!packet->buffer) {
126                        trace_set_err(libtrace, errno, 
127                                        "Cannot allocate memory");
128                        return -1;
129                }
130        }
131
132        flags |= TRACE_PREP_OWN_BUFFER;
133        packet->type = TRACE_RT_DATA_TSH;
134
135        buffer2 = packet->buffer;
136
137        /* Read the TSH header */
138        if ((numbytes=wandio_read(libtrace->io,
139                                        buffer2,
140                                        (size_t)sizeof(tsh_pkt_header_t))) == -1) {
141                trace_set_err(libtrace,errno,"read(%s)",
142                                libtrace->uridata);
143                return -1;
144        }
145        /* EOF */
146        if (numbytes == 0) {
147                return 0;
148        }
149
150        if (numbytes < (int)sizeof(tsh_pkt_header_t)) {
151                trace_set_err(libtrace, errno, "Incomplete TSH header");
152                return -1;
153        }
154
155        buffer2 = (char*)buffer2 + numbytes;
156
157        /* Read the IP header */
158        if ((numbytes=wandio_read(libtrace->io,
159                                buffer2,
160                                (size_t)sizeof(libtrace_ip_t)+16))  /* 16 bytes of transport header */
161                        != sizeof(libtrace_ip_t)+16) {
162                trace_set_err(libtrace,errno,"read(%s)",
163                                libtrace->uridata);
164                return -1;
165        }
166
167#if 0
168        /* IP Options aren't captured in the trace, so leave room
169         * for them, and put the transport header where it "should" be
170         */
171        buffer2 = (char*)buffer2 + ((libtrace_ip_t*)buffer2)->ip_hl*4;
172
173        /* Read the transport header */
174        if ((numbytes=wandio_read(libtrace->io,
175                                buffer2,
176                                16)) != 16) {
177                trace_set_err(libtrace,errno,"read(%s)",
178                                libtrace->uridata);
179                return -1;
180        }
181#endif
182       
183        if (tsh_prepare_packet(libtrace, packet, packet->buffer, packet->type, 
184                                flags)) {
185                return -1;
186        }
187
188
189        return 80;
190}
191
192static libtrace_linktype_t tsh_get_link_type(const libtrace_packet_t *packet UNUSED) {
193        return TRACE_TYPE_NONE;
194}
195
196static libtrace_direction_t tsh_get_direction(const libtrace_packet_t *packet) {
197        return ntohl(((tsh_pkt_header_t*)(packet->header))->usecs & htonl(0xFF000000)) >> 24;
198}
199
200static struct timeval tsh_get_timeval(const libtrace_packet_t *packet)
201{
202        struct timeval tv;
203        tv.tv_sec=ntohl(((tsh_pkt_header_t*)(packet->header))->seconds);
204        tv.tv_usec=ntohl(((tsh_pkt_header_t*)(packet->header))->usecs & htonl(0x00FFFFFF));
205
206        return tv;
207}
208
209static int tsh_get_capture_length(const libtrace_packet_t *packet UNUSED) {
210        /* 16 bytes transport + 24 bytes IP, and we're missing the
211         * IP options, but we'll pretend we have them
212         */
213#if 0
214        return 16+((libtrace_ip_t*)packet->payload)->ip_hl*4;
215#else
216        return 16+sizeof(libtrace_ip_t);
217#endif
218}
219
220static int tsh_get_wire_length(const libtrace_packet_t *packet) {
221        return ntohs(((libtrace_ip_t*)packet->payload)->ip_len);
222}
223
224static void tsh_help(void) {
225        printf("tsh format module: $Revision: 1611 $\n");
226        printf("Supported input URIs:\n");
227        printf("\ttsh:/path/to/file\t(uncompressed)\n");
228        printf("\ttsh:/path/to/file.gz\t(gzip-compressed)\n");
229        printf("\ttsh:-\t(stdin, either compressed or not)\n");
230        printf("\ttsh:/path/to/socket\n");
231        printf("\n");
232        printf("\te.g.: erf:/tmp/trace\n");
233        printf("\n");
234}
235
236static struct libtrace_format_t tshformat = {
237        "tsh",
238        "$Id$",
239        TRACE_FORMAT_TSH,
240        NULL,                           /* probe filename */
241        NULL,                           /* probe magic */
242        tsh_init_input,                 /* init_input */       
243        NULL,                           /* config_input */
244        tsh_start_input,                /* start_input */
245        NULL,                           /* pause_input */
246        NULL,                           /* init_output */
247        NULL,                           /* config_output */
248        NULL,                           /* start_output */
249        tsh_fin_input,                  /* fin_input */
250        NULL,                           /* fin_output */
251        tsh_read_packet,                /* read_packet */
252        tsh_prepare_packet,             /* prepare_packet */
253        NULL,                           /* fin_packet */
254        NULL,                           /* write_packet */
255        tsh_get_link_type,              /* get_link_type */
256        tsh_get_direction,              /* get_direction */
257        NULL,                           /* set_direction */
258        NULL,                           /* get_erf_timestamp */
259        tsh_get_timeval,                /* get_timeval */
260        NULL,                           /* get_timespec */
261        NULL,                           /* get_seconds */
262        NULL,                           /* seek_erf */
263        NULL,                           /* seek_timeval */
264        NULL,                           /* seek_seconds */
265        tsh_get_capture_length,         /* get_capture_length */
266        tsh_get_wire_length,            /* get_wire_length */
267        tsh_get_framing_length,         /* get_framing_length */
268        NULL,                           /* set_capture_length */
269        NULL,                           /* get_received_packets */
270        NULL,                           /* get_filtered_packets */
271        NULL,                           /* get_dropped_packets */
272        NULL,                           /* get_statistics */
273        NULL,                           /* get_fd */
274        trace_event_trace,              /* trace_event */
275        tsh_help,                       /* help */
276        NULL,                   /* next pointer */
277        NON_PARALLEL(false)
278};
279
280/* the tsh header format is the same as tsh, except that the bits that will
281 * always be "0" in the fr+ format are used for an "interface" identifier,
282 * thus on tr+ traces, this will always be 0.  So, we use the exact same
283 * decoder for both traces.
284 */
285static struct libtrace_format_t frplusformat = {
286        "fr+",
287        "$Id$",
288        TRACE_FORMAT_TSH,
289        NULL,                           /* probe filename */
290        NULL,                           /* probe magic */
291        tsh_init_input,                 /* init_input */       
292        NULL,                           /* config_input */
293        tsh_start_input,                /* start_input */
294        NULL,                           /* pause_input */
295        NULL,                           /* init_output */
296        NULL,                           /* config_output */
297        NULL,                           /* start_output */
298        tsh_fin_input,                  /* fin_input */
299        NULL,                           /* fin_output */
300        tsh_read_packet,                /* read_packet */
301        tsh_prepare_packet,             /* prepare_packet */
302        NULL,                           /* fin_packet */
303        NULL,                           /* write_packet */
304        tsh_get_link_type,              /* get_link_type */
305        tsh_get_direction,              /* get_direction */
306        NULL,                           /* set_direction */
307        NULL,                           /* get_erf_timestamp */
308        tsh_get_timeval,                /* get_timeval */
309        NULL,                           /* get_timespec */
310        NULL,                           /* get_seconds */
311        NULL,                           /* seek_erf */
312        NULL,                           /* seek_timeval */
313        NULL,                           /* seek_seconds */
314        tsh_get_capture_length,         /* get_capture_length */
315        tsh_get_wire_length,            /* get_wire_length */
316        tsh_get_framing_length,         /* get_framing_length */
317        NULL,                           /* set_capture_length */
318        NULL,                           /* get_received_packets */
319        NULL,                           /* get_filtered_packets */
320        NULL,                           /* get_dropped_packets */
321        NULL,                           /* get_statistics */
322        NULL,                           /* get_fd */
323        trace_event_trace,              /* trace_event */
324        tsh_help,                       /* help */
325        NULL,                   /* next pointer */
326        NON_PARALLEL(false)
327};
328
329void tsh_constructor(void) {
330        register_format(&tshformat);
331        register_format(&frplusformat);
332}
Note: See TracBrowser for help on using the repository browser.