source: lib/format_tsh.c @ f0fb38f

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since f0fb38f was f0fb38f, checked in by Shane Alcock <salcock@…>, 13 years ago
  • Added prepare_packet functions to all formats, primarily to support translating RT packets into the appropriate format. These functions are all used internally as well, as most formats still need to "prepare" packets that have been read by setting pointers, updating loss counters etc.
  • Also added a trace_prepare_packet function, but this is not made available externally at this stage
  • Added init_format_data functions to some formats to initialise format data structures in cases where the init_trace function does more than just that
  • Refactored rt packet reading code to use the new trace_prepare_packet functionality - also did a lot of tidying of the code
  • Added missing RT type for BPF format
  • 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        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_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
92                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
93        if (packet->buffer != buffer &&
94                        packet->buf_control == TRACE_CTRL_PACKET) {
95                free(packet->buffer);
96        }
97
98        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
99                packet->buf_control = TRACE_CTRL_PACKET;
100        } else
101                packet->buf_control = TRACE_CTRL_EXTERNAL;
102
103
104        packet->buffer = buffer;
105        packet->header = buffer;
106        packet->type = rt_type;
107        packet->payload = (char *)packet->buffer + sizeof(tsh_pkt_header_t);
108
109        if (libtrace->format_data == NULL) {
110                if (tsh_init_input(libtrace))
111                        return -1;
112        }
113
114        return 0;
115}
116
117static int tsh_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
118        int numbytes;
119        void *buffer2 = packet->buffer;
120        uint32_t flags = 0;
121
122        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
123                packet->buffer = malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
124                if (!packet->buffer) {
125                        trace_set_err(libtrace, errno, 
126                                        "Cannot allocate memory");
127                        return -1;
128                }
129        }
130
131        flags |= TRACE_PREP_OWN_BUFFER;
132        packet->type = TRACE_RT_DATA_TSH;
133
134        buffer2 = packet->buffer;
135
136        /* Read the TSH header */
137        if ((numbytes=libtrace_io_read(DATA(libtrace)->file,
138                                        buffer2,
139                                        (size_t)sizeof(tsh_pkt_header_t))) == -1) {
140                trace_set_err(libtrace,errno,"read(%s)",
141                                libtrace->uridata);
142                return -1;
143        }
144        /* EOF */
145        if (numbytes == 0) {
146                return 0;
147        }
148
149        buffer2 = (char*)buffer2 + numbytes;
150
151        /* Read the IP header */
152        if ((numbytes=libtrace_io_read(DATA(libtrace)->file,
153                                buffer2,
154                                (size_t)sizeof(libtrace_ip_t))) 
155                        != sizeof(libtrace_ip_t)) {
156                trace_set_err(libtrace,errno,"read(%s)",
157                                libtrace->uridata);
158                return -1;
159        }
160
161        /* IP Options aren't captured in the trace, so leave room
162         * for them, and put the transport header where it "should" be
163         */
164        buffer2 = (char*)buffer2 + ((libtrace_ip_t*)buffer2)->ip_hl*4;
165
166        /* Read the transport header */
167        if ((numbytes=libtrace_io_read(DATA(libtrace)->file,
168                                buffer2,
169                                16)) != 16) {
170                trace_set_err(libtrace,errno,"read(%s)",
171                                libtrace->uridata);
172                return -1;
173        }
174       
175        if (tsh_prepare_packet(libtrace, packet, packet->buffer, packet->type, 
176                                flags)) {
177                return -1;
178        }
179
180
181        return 80;
182}
183
184static libtrace_linktype_t tsh_get_link_type(const libtrace_packet_t *packet) {
185        return TRACE_TYPE_NONE;
186}
187
188static libtrace_direction_t tsh_get_direction(const libtrace_packet_t *packet) {
189        return ((tsh_pkt_header_t*)(packet->header))->iface;
190}
191
192static struct timeval tsh_get_timeval(const libtrace_packet_t *packet)
193{
194        struct timeval tv;
195        tv.tv_sec=ntohl(((tsh_pkt_header_t*)(packet->header))->seconds);
196        tv.tv_usec=ntohl(((tsh_pkt_header_t*)(packet->header))->usecs);
197
198        return tv;
199}
200
201static int tsh_get_capture_length(const libtrace_packet_t *packet) {
202        /* 16 bytes transport + 24 bytes IP, and we're missing the
203         * IP options, but we'll pretend we have them
204         */
205        return 16+((libtrace_ip_t*)packet->payload)->ip_hl*4;
206}
207
208static int tsh_get_wire_length(const libtrace_packet_t *packet) {
209        return ((libtrace_ip_t*)packet->payload)->ip_len;
210}
211
212static void tsh_help(void) {
213        printf("tsh format module: $Revision$\n");
214        printf("Supported input URIs:\n");
215        printf("\ttsh:/path/to/file\t(uncompressed)\n");
216        printf("\ttsh:/path/to/file.gz\t(gzip-compressed)\n");
217        printf("\ttsh:-\t(stdin, either compressed or not)\n");
218        printf("\ttsh:/path/to/socket\n");
219        printf("\n");
220        printf("\te.g.: erf:/tmp/trace\n");
221        printf("\n");
222}
223
224static struct libtrace_format_t tshformat = {
225        "tsh",
226        "$Id$",
227        TRACE_FORMAT_TSH,
228        tsh_init_input,                 /* init_input */       
229        NULL,                           /* config_input */
230        tsh_start_input,                /* start_input */
231        NULL,                           /* pause_input */
232        NULL,                           /* init_output */
233        NULL,                           /* config_output */
234        NULL,                           /* start_output */
235        tsh_fin_input,                  /* fin_input */
236        NULL,                           /* fin_output */
237        tsh_read_packet,                /* read_packet */
238        tsh_prepare_packet,             /* prepare_packet */
239        NULL,                           /* fin_packet */
240        NULL,                           /* write_packet */
241        tsh_get_link_type,              /* get_link_type */
242        tsh_get_direction,              /* get_direction */
243        NULL,                           /* set_direction */
244        NULL,                           /* get_erf_timestamp */
245        tsh_get_timeval,                /* get_timeval */
246        NULL,                           /* get_seconds */
247        NULL,                           /* seek_erf */
248        NULL,                           /* seek_timeval */
249        NULL,                           /* seek_seconds */
250        tsh_get_capture_length,         /* get_capture_length */
251        tsh_get_wire_length,            /* get_wire_length */
252        tsh_get_framing_length,         /* get_framing_length */
253        NULL,                           /* set_capture_length */
254        NULL,                           /* get_received_packets */
255        NULL,                           /* get_filtered_packets */
256        NULL,                           /* get_dropped_packets */
257        NULL,                           /* get_captured_packets */
258        NULL,                           /* get_fd */
259        trace_event_trace,              /* trace_event */
260        tsh_help,                       /* help */
261        NULL                            /* next pointer */
262};
263
264/* the tsh header format is the same as tsh, except that the bits that will
265 * always be "0" in the fr+ format are used for an "interface" identifier,
266 * thus on tr+ traces, this will always be 0.  So, we use the exact same
267 * decoder for both traces.
268 */
269static struct libtrace_format_t frplusformat = {
270        "fr+",
271        "$Id$",
272        TRACE_FORMAT_TSH,
273        tsh_init_input,                 /* init_input */       
274        NULL,                           /* config_input */
275        tsh_start_input,                /* start_input */
276        NULL,                           /* pause_input */
277        NULL,                           /* init_output */
278        NULL,                           /* config_output */
279        NULL,                           /* start_output */
280        tsh_fin_input,                  /* fin_input */
281        NULL,                           /* fin_output */
282        tsh_read_packet,                /* read_packet */
283        tsh_prepare_packet,             /* prepare_packet */
284        NULL,                           /* fin_packet */
285        NULL,                           /* write_packet */
286        tsh_get_link_type,              /* get_link_type */
287        tsh_get_direction,              /* get_direction */
288        NULL,                           /* set_direction */
289        NULL,                           /* get_erf_timestamp */
290        tsh_get_timeval,                /* get_timeval */
291        NULL,                           /* get_seconds */
292        NULL,                           /* seek_erf */
293        NULL,                           /* seek_timeval */
294        NULL,                           /* seek_seconds */
295        tsh_get_capture_length,         /* get_capture_length */
296        tsh_get_wire_length,            /* get_wire_length */
297        tsh_get_framing_length,         /* get_framing_length */
298        NULL,                           /* set_capture_length */
299        NULL,                           /* get_received_packets */
300        NULL,                           /* get_filtered_packets */
301        NULL,                           /* get_dropped_packets */
302        NULL,                           /* get_captured_packets */
303        NULL,                           /* get_fd */
304        trace_event_trace,              /* trace_event */
305        tsh_help,                       /* help */
306        NULL                            /* next pointer */
307};
308
309void tsh_constructor(void) {
310        register_format(&tshformat);
311        register_format(&frplusformat);
312}
Note: See TracBrowser for help on using the repository browser.