source: lib/format_tsh.c @ 2c124cf

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 2c124cf was 2c124cf, checked in by Brendon Jones <brendonj@…>, 14 years ago

"interface" is a reserved word in Windows, renamed it to "iface". This
will break the API for anyone doing interface stuff in tsh traces... anyone?

Windows also needs the size to be explicit when doing pointer arithmetic,
void pointers need to be cast to something other than void.

  • Property mode set to 100644
File size: 7.5 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        libtrace_io_t *file;
48};
49
50typedef struct tsh_pkt_header_t {
51        uint32_t seconds;
52        LT_BITFIELD32 iface:8;
53        LT_BITFIELD32 usecs:24;
54} tsh_pkt_header_t;
55
56static int tsh_get_framing_length(const libtrace_packet_t *packet)
57{
58        return sizeof(tsh_pkt_header_t);
59}
60
61
62static int tsh_init_input(libtrace_t *libtrace) 
63{
64        libtrace->format_data = malloc(sizeof(struct tsh_format_data_t));
65       
66        DATA(libtrace)->file = 0;
67
68        return 0; /* success */
69}
70
71static int tsh_start_input(libtrace_t *libtrace)
72{
73        if (DATA(libtrace)->file)
74                return 0; /* success */
75
76        DATA(libtrace)->file = trace_open_file(libtrace);
77
78        if (!DATA(libtrace)->file)
79                return -1;
80
81        return 0; /* success */
82}
83
84static int tsh_fin_input(libtrace_t *libtrace) {
85        if (DATA(libtrace)->file)
86                libtrace_io_close(DATA(libtrace)->file);
87        free(libtrace->format_data);
88        return 0;
89}
90
91static int tsh_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
92        int numbytes;
93        void *buffer2 = packet->buffer;
94
95        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
96                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
97                packet->buf_control = TRACE_CTRL_PACKET;
98                if (!packet->buffer) {
99                        trace_set_err(libtrace, errno, 
100                                        "Cannot allocate memory");
101                        return -1;
102                }
103        }
104
105        packet->header = packet->buffer;
106        packet->type = TRACE_RT_DATA_TSH;
107
108        buffer2 = packet->buffer;
109
110        /* Read the TSH header */
111        if ((numbytes=libtrace_io_read(DATA(libtrace)->file,
112                                        buffer2,
113                                        (size_t)sizeof(tsh_pkt_header_t))) == -1) {
114                trace_set_err(libtrace,errno,"read(%s)",
115                                libtrace->uridata);
116                return -1;
117        }
118        /* EOF */
119        if (numbytes == 0) {
120                return 0;
121        }
122
123        (char*)buffer2 += numbytes;
124        packet->payload = buffer2;
125
126        /* Read the IP header */
127        if ((numbytes=libtrace_io_read(DATA(libtrace)->file,
128                                buffer2,
129                                (size_t)sizeof(libtrace_ip_t))) 
130                        != sizeof(libtrace_ip_t)) {
131                trace_set_err(libtrace,errno,"read(%s)",
132                                libtrace->uridata);
133                return -1;
134        }
135
136        /* IP Options aren't captured in the trace, so leave room
137         * for them, and put the transport header where it "should" be
138         */
139        (char*)buffer2 += ((libtrace_ip_t*)buffer2)->ip_hl*4;
140
141        /* Read the transport header */
142        if ((numbytes=libtrace_io_read(DATA(libtrace)->file,
143                                buffer2,
144                                16)) != 16) {
145                trace_set_err(libtrace,errno,"read(%s)",
146                                libtrace->uridata);
147                return -1;
148        }
149
150        return 80;
151}
152
153static libtrace_linktype_t tsh_get_link_type(const libtrace_packet_t *packet) {
154        return TRACE_TYPE_NONE;
155}
156
157static libtrace_direction_t tsh_get_direction(const libtrace_packet_t *packet) {
158        return ((tsh_pkt_header_t*)(packet->header))->iface;
159}
160
161static struct timeval tsh_get_timeval(const libtrace_packet_t *packet)
162{
163        struct timeval tv;
164        tv.tv_sec=ntohl(((tsh_pkt_header_t*)(packet->header))->seconds);
165        tv.tv_usec=ntohl(((tsh_pkt_header_t*)(packet->header))->usecs);
166
167        return tv;
168}
169
170static int tsh_get_capture_length(const libtrace_packet_t *packet) {
171        /* 16 bytes transport + 24 bytes IP, and we're missing the
172         * IP options, but we'll pretend we have them
173         */
174        return 16+((libtrace_ip_t*)packet->payload)->ip_hl*4;
175}
176
177static int tsh_get_wire_length(const libtrace_packet_t *packet) {
178        return ((libtrace_ip_t*)packet->payload)->ip_len;
179}
180
181static void tsh_help(void) {
182        printf("tsh format module: $Revision$\n");
183        printf("Supported input URIs:\n");
184        printf("\ttsh:/path/to/file\t(uncompressed)\n");
185        printf("\ttsh:/path/to/file.gz\t(gzip-compressed)\n");
186        printf("\ttsh:-\t(stdin, either compressed or not)\n");
187        printf("\ttsh:/path/to/socket\n");
188        printf("\n");
189        printf("\te.g.: erf:/tmp/trace\n");
190        printf("\n");
191}
192
193static struct libtrace_format_t tshformat = {
194        "tsh",
195        "$Id$",
196        TRACE_FORMAT_TSH,
197        tsh_init_input,                 /* init_input */       
198        NULL,                           /* config_input */
199        tsh_start_input,                /* start_input */
200        NULL,                           /* pause_input */
201        NULL,                           /* init_output */
202        NULL,                           /* config_output */
203        NULL,                           /* start_output */
204        tsh_fin_input,                  /* fin_input */
205        NULL,                           /* fin_output */
206        tsh_read_packet,                /* read_packet */
207        NULL,                           /* fin_packet */
208        NULL,                           /* write_packet */
209        tsh_get_link_type,              /* get_link_type */
210        tsh_get_direction,              /* get_direction */
211        NULL,                           /* set_direction */
212        NULL,                           /* get_erf_timestamp */
213        tsh_get_timeval,                /* get_timeval */
214        NULL,                           /* get_seconds */
215        NULL,                           /* seek_erf */
216        NULL,                           /* seek_timeval */
217        NULL,                           /* seek_seconds */
218        tsh_get_capture_length,         /* get_capture_length */
219        tsh_get_wire_length,            /* get_wire_length */
220        tsh_get_framing_length,         /* get_framing_length */
221        NULL,                           /* set_capture_length */
222        NULL,                           /* get_received_packets */
223        NULL,                           /* get_filtered_packets */
224        NULL,                           /* get_dropped_packets */
225        NULL,                           /* get_captured_packets */
226        NULL,                           /* get_fd */
227        trace_event_trace,              /* trace_event */
228        tsh_help,                       /* help */
229        NULL                            /* next pointer */
230};
231
232/* the tsh header format is the same as tsh, except that the bits that will
233 * always be "0" in the fr+ format are used for an "interface" identifier,
234 * thus on tr+ traces, this will always be 0.  So, we use the exact same
235 * decoder for both traces.
236 */
237static struct libtrace_format_t frplusformat = {
238        "fr+",
239        "$Id$",
240        TRACE_FORMAT_TSH,
241        tsh_init_input,                 /* init_input */       
242        NULL,                           /* config_input */
243        tsh_start_input,                /* start_input */
244        NULL,                           /* pause_input */
245        NULL,                           /* init_output */
246        NULL,                           /* config_output */
247        NULL,                           /* start_output */
248        tsh_fin_input,                  /* fin_input */
249        NULL,                           /* fin_output */
250        tsh_read_packet,                /* read_packet */
251        NULL,                           /* fin_packet */
252        NULL,                           /* write_packet */
253        tsh_get_link_type,              /* get_link_type */
254        tsh_get_direction,              /* get_direction */
255        NULL,                           /* set_direction */
256        NULL,                           /* get_erf_timestamp */
257        tsh_get_timeval,                /* get_timeval */
258        NULL,                           /* get_seconds */
259        NULL,                           /* seek_erf */
260        NULL,                           /* seek_timeval */
261        NULL,                           /* seek_seconds */
262        tsh_get_capture_length,         /* get_capture_length */
263        tsh_get_wire_length,            /* get_wire_length */
264        tsh_get_framing_length,         /* get_framing_length */
265        NULL,                           /* set_capture_length */
266        NULL,                           /* get_received_packets */
267        NULL,                           /* get_filtered_packets */
268        NULL,                           /* get_dropped_packets */
269        NULL,                           /* get_captured_packets */
270        NULL,                           /* get_fd */
271        trace_event_trace,              /* trace_event */
272        tsh_help,                       /* help */
273        NULL                            /* next pointer */
274};
275
276void tsh_constructor(void) {
277        register_format(&tshformat);
278        register_format(&frplusformat);
279}
Note: See TracBrowser for help on using the repository browser.