source: lib/format_tsh.c @ ef5ba20

develop
Last change on this file since ef5ba20 was ef5ba20, checked in by Jacob Van Walraven <jcv9@…>, 22 months ago

add abilty to get custom option from meta packets, add abilty to get entire section from meta packet, meta api now returns libtrace_meta_t structure

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