source: lib/format_atmhdr.c @ 32ee9b2

cachetimestampsdeveloprc-4.0.4ringdecrementfixringperformance
Last change on this file since 32ee9b2 was 32ee9b2, checked in by Shane Alcock <salcock@…>, 3 years ago

Add new trace_flush_output() to public API

Can be used to force a libtrace output to dump any buffered output
to disk immediately.

Note that if the file is compressed or the output trace format
requires a trailer, the flushed file will still not be properly
readable afterwards as this will not result in any trailers
being written. You'll still have to close the file for that.

Mainly this is useful for ensuring that output file sizes grow
over time in situations where the amount of output is relatively
small, rather than staying stuck at 0 bytes until we either reach
1MB of output or the file is closed. For instance, you could have
a timer that calls trace_flush_output() every 30 seconds so that
the output file size will grow if any packets were written in the
last 30 seconds.

  • Property mode set to 100644
File size: 7.6 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#define _GNU_SOURCE
27
28#include "config.h"
29#include "common.h"
30#include "libtrace.h"
31#include "libtrace_int.h"
32#include "format_helper.h"
33#include "wandio.h"
34
35#include <sys/stat.h>
36#include <assert.h>
37#include <errno.h>
38#include <fcntl.h>
39#include <stdio.h>
40#include <string.h>
41#include <stdlib.h>
42
43/* This particular format covers the ATM cell header capture format used to
44 * take the Auckland VII trace set.
45 *
46 * Each capture record contains only a timestamp and the first four bytes of
47 * the ATM header - nothing else.
48 *
49 * As a result, there isn't a lot you can actually do with these traces!
50 *
51 * Libtrace does not support writing using this format, because it is so
52 * useless :)
53 */
54
55/* Returns the size of the ATM cell framing header */
56static int atmhdr_get_framing_length(const libtrace_packet_t *packet UNUSED)
57{
58        return sizeof(atmhdr_t);
59}
60
61/* Initialise an input trace to read an ATM cell header capture */
62static int atmhdr_init_input(libtrace_t *libtrace) {
63        libtrace->format_data = NULL; /* No format data needed */
64        return 0;
65}
66
67/* Start an ATM cell header input trace */
68static int atmhdr_start_input(libtrace_t *libtrace)
69{
70        if (libtrace->io) /* Already open? */
71                return 0;
72        libtrace->io = trace_open_file(libtrace);
73        if (libtrace->io)
74                return 0;
75        return -1;
76}
77
78/* Close an ATM cell header input trace */
79static int atmhdr_fin_input(libtrace_t *libtrace)
80{
81        wandio_destroy(libtrace->io);
82        return 0;
83}
84
85
86/* Converts a buffer containing a recently read ATM cell header record into
87 * a libtrace packet */
88static int atmhdr_prepare_packet(libtrace_t *libtrace, 
89                libtrace_packet_t *packet, void *buffer, 
90                libtrace_rt_types_t rt_type, uint32_t flags) {
91
92        /* If the packet previously owned a buffer that was not the buffer
93         * containing the new packet data, we need to free the old one to
94         * avoid leaking memory */
95        if (packet->buffer != buffer &&
96                        packet->buf_control == TRACE_CTRL_PACKET) {
97                free(packet->buffer);
98        }
99
100        /* Set the buffer owner appropriately */
101        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
102                packet->buf_control = TRACE_CTRL_PACKET;
103        } else
104                packet->buf_control = TRACE_CTRL_EXTERNAL;
105
106        /* Update the packet pointers appropriately */
107        packet->buffer = buffer;
108        packet->header = buffer;
109        packet->payload = (void*)((char*)packet->buffer + 
110                        libtrace->format->get_framing_length(packet));
111
112        /* Set the packet type */
113        packet->type = rt_type;
114
115        return 0;
116}
117
118/* Reads the next ATM cell header record from the given trace and writes it
119 * into a libtrace packet */
120static int atmhdr_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
121        int numbytes;
122        void *buffer;
123        uint32_t flags = 0;
124       
125        /* Make sure we have a buffer available to read the next record into */
126        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
127                packet->buffer=malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
128        }
129        buffer = packet->buffer;
130        flags |= TRACE_PREP_OWN_BUFFER;
131       
132        packet->type = TRACE_RT_DATA_ATMHDR;
133
134        /* The records are a fixed size so we can read the entire record in
135         * one go */
136        if ((numbytes=wandio_read(libtrace->io, buffer, (size_t)12)) != 12)
137        {
138                if (numbytes != 0) {
139                        trace_set_err(libtrace,TRACE_ERR_WANDIO_FAILED,"read(%s)",libtrace->uridata);
140                }
141                return numbytes;
142        }
143
144        /* Update all our packet pointers appropriately */
145        if (atmhdr_prepare_packet(libtrace, packet, buffer, 
146                                TRACE_RT_DATA_ATMHDR, flags)) {
147                return -1;
148        }
149                               
150       
151        return 12;
152}
153
154/* Get the link type for an ATM cell header record */
155static libtrace_linktype_t atmhdr_get_link_type(const libtrace_packet_t *packet UNUSED) {
156        /* Unsurprisingly, we're always going to be an ATM header */
157        return TRACE_TYPE_ATM;
158}
159
160/* Get the capture length for an ATM cell header record */
161static int atmhdr_get_capture_length(const libtrace_packet_t *packet UNUSED) {
162        /* There is always 4 bytes of ATM header retained by this format */
163        return 4;
164}
165
166/* Get the wire length for an ATM cell header record */
167static int atmhdr_get_wire_length(const libtrace_packet_t *packet UNUSED) {
168        /* ATM packets are 53 byte fixed length records */
169        return 53;
170}
171
172/* Returns the timestamp for an ATM cell header record in the ERF timestamp
173 * format */
174static uint64_t atmhdr_get_erf_timestamp(const libtrace_packet_t *packet) {
175        uint64_t ts;
176        atmhdr_t *atm = (atmhdr_t *)packet->header;
177       
178        /* Basically, the capture format header is an ERF timestamp except
179         * the two 32-bit segments are reversed */
180        ts = (uint64_t)atm->ts_fraction + ((uint64_t)atm->ts_sec << 32);
181
182        return ts;
183}
184
185static struct libtrace_format_t atmhdr = {
186        "atmhdr",
187        "$Id$",
188        TRACE_FORMAT_ATMHDR,
189        NULL,                           /* probe filename */
190        NULL,                           /* probe magic */
191        atmhdr_init_input,              /* init_input */
192        NULL,                           /* config_input */
193        atmhdr_start_input,             /* start_input */
194        NULL,                           /* pause_input */
195        NULL,                           /* init_output */
196        NULL,                           /* config_output */
197        NULL,                           /* start_output */
198        atmhdr_fin_input,               /* fin_input */
199        NULL,                           /* fin_output */
200        atmhdr_read_packet,             /* read_packet */
201        atmhdr_prepare_packet,          /* prepare_packet */
202        NULL,                           /* fin_packet */
203        NULL,                           /* write_packet */
204        NULL,                           /* flush_output */
205        atmhdr_get_link_type,           /* get_link_type */
206        NULL,                           /* get_direction */
207        NULL,                           /* set_direction */
208        atmhdr_get_erf_timestamp,       /* get_erf_timestamp */
209        NULL,                           /* get_timeval */
210        NULL,                           /* get_timespec */
211        NULL,                           /* get_seconds */
212        NULL,                           /* seek_erf */
213        NULL,                           /* seek_timeval */
214        NULL,                           /* seek_seconds */
215        atmhdr_get_capture_length,      /* get_capture_length */
216        atmhdr_get_wire_length,         /* get_wire_length */
217        atmhdr_get_framing_length,      /* get_framing_length */
218        NULL,                           /* set_capture_length */
219        NULL,                           /* get_received_packets */
220        NULL,                           /* get_filtered_packets */
221        NULL,                           /* get_dropped_packets */
222        NULL,                           /* get_statistics */
223        NULL,                           /* get_fd */
224        trace_event_trace,              /* trace_event */
225        NULL,                           /* help */
226        NULL,                            /* next pointer */
227        NON_PARALLEL(false)
228};
229       
230
231void atmhdr_constructor(void) {
232        register_format(&atmhdr);
233}
Note: See TracBrowser for help on using the repository browser.