source: lib/format_dag24.c @ 708f9ae

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 708f9ae was 708f9ae, checked in by Shane Alcock <salcock@…>, 14 years ago
  • Updated a number of formats to not set the libtrace error for config options they didn't understand. trace_config will attempt to set the option upon their return and should be trusted to set the error appropriately if it also fails.
  • Updated the synopt report to report percentages of option combos in SYNs and SYNACKs separately
  • Property mode set to 100644
File size: 12.2 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *          Shane Alcock
8 *
9 * All rights reserved.
10 *
11 * This code has been developed by the University of Waikato WAND
12 * research group. For further information please see http://www.wand.net.nz/
13 *
14 * libtrace is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * libtrace is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with libtrace; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 *
28 * $Id$
29 *
30 */
31#define _GNU_SOURCE
32
33#include "config.h"
34#include "common.h"
35#include "libtrace.h"
36#include "libtrace_int.h"
37#include "format_helper.h"
38#include "format_erf.h"
39
40#include <assert.h>
41#include <errno.h>
42#include <fcntl.h>
43#include <stdio.h>
44#include <string.h>
45#include <stdlib.h>
46
47#include <sys/mman.h>
48#ifdef WIN32
49#  include <io.h>
50#  include <share.h>
51#  define PATH_MAX _MAX_PATH
52#  define snprintf sprintf_s
53#else
54#  include <netdb.h>
55#  ifndef PATH_MAX
56#       define PATH_MAX 4096
57#  endif
58#  include <sys/ioctl.h>
59#endif
60
61
62static struct libtrace_format_t dag;
63
64#define DATA(x) ((struct dag_format_data_t *)x->format_data)
65#define DUCK DATA(libtrace)->duck
66#define FORMAT_DATA DATA(libtrace)
67
68struct dag_format_data_t {
69        struct {
70                uint32_t last_duck;
71                uint32_t duck_freq;
72                uint32_t last_pkt;
73                libtrace_t *dummy_duck;
74        } duck; 
75       
76        int fd;
77        void *buf;
78        uint32_t diff;
79        uint32_t offset;
80        uint32_t bottom;
81        uint32_t top;
82};
83
84static int dag_available(libtrace_t *libtrace) {
85
86        if (FORMAT_DATA->diff > 0)
87                return FORMAT_DATA->diff;
88
89        FORMAT_DATA->bottom = FORMAT_DATA->top;
90        FORMAT_DATA->top = dag_offset(
91                        FORMAT_DATA->fd,
92                        &(FORMAT_DATA->bottom),
93                        DAGF_NONBLOCK);
94        FORMAT_DATA->diff = FORMAT_DATA->top - FORMAT_DATA->bottom;
95        FORMAT_DATA->offset = 0;
96        return FORMAT_DATA->diff;
97}
98
99static int dag_init_input(libtrace_t *libtrace) {
100        struct stat buf;
101        libtrace->format_data = (struct dag_format_data_t *)
102                malloc(sizeof(struct dag_format_data_t));
103        if (stat(libtrace->uridata, &buf) == -1) {
104                trace_set_err(libtrace,errno,"stat(%s)",libtrace->uridata);
105                return -1;
106        }
107
108        FORMAT_DATA->top = 0;
109        FORMAT_DATA->bottom = 0;
110        if (S_ISCHR(buf.st_mode)) {
111                /* DEVICE */
112                if((FORMAT_DATA->fd = dag_open(libtrace->uridata)) < 0) {
113                        trace_set_err(libtrace,errno,"Cannot open DAG %s",
114                                        libtrace->uridata);
115                        return -1;
116                }
117                if((FORMAT_DATA->buf = (void *)dag_mmap(FORMAT_DATA->fd)) == MAP_FAILED) {
118                        trace_set_err(libtrace,errno,"Cannot mmap DAG %s",
119                                        libtrace->uridata);
120                        return -1;
121                }
122        } else {
123                trace_set_err(libtrace,errno,"Not a valid dag device: %s",
124                                libtrace->uridata);
125                return -1;
126        }
127
128        DUCK.last_duck = 0;
129        DUCK.duck_freq = 0;
130        DUCK.last_pkt = 0;
131        DUCK.dummy_duck = NULL;
132
133        return 0;
134}
135
136static int dag_config_input(libtrace_t *libtrace, trace_option_t option,
137                                void *data) {
138        switch(option) {
139                case TRACE_OPTION_META_FREQ:
140                        DUCK.duck_freq = *(int *)data;
141                        return 0;
142                case TRACE_OPTION_SNAPLEN:
143                        /* Surely we can set this?? Fall through for now*/
144                        return -1;
145                case TRACE_OPTION_PROMISC:
146                        /* DAG already operates in a promisc fashion */
147                        return -1;
148                case TRACE_OPTION_FILTER:
149                        return -1;
150                case TRACE_OPTION_EVENT_REALTIME:
151                        return -1;
152        }
153        return -1;
154}
155
156static int dag_start_input(libtrace_t *libtrace) {     
157        if(dag_start(FORMAT_DATA->fd) < 0) {
158                trace_set_err(libtrace,errno,"Cannot start DAG %s",
159                                libtrace->uridata);
160                return -1;
161        }
162
163        /* Flush the memory hole */
164        while(dag_available(libtrace) != 0)
165                FORMAT_DATA->diff = 0;
166        return 0;
167}
168
169static int dag_pause_input(libtrace_t *libtrace) {
170        dag_stop(FORMAT_DATA->fd);
171        return 0;
172}
173
174static int dag_fin_input(libtrace_t *libtrace) {
175        dag_close(FORMAT_DATA->fd);
176        if (DUCK.dummy_duck)
177                trace_destroy_dead(DUCK.dummy_duck);
178        free(libtrace->format_data);
179        return 0; /* success */
180}
181
182static int dag_get_duckinfo(libtrace_t *libtrace,
183                                libtrace_packet_t *packet) {
184        dag_inf lt_dag_inf;
185
186        if (packet->buf_control == TRACE_CTRL_EXTERNAL ||
187                        !packet->buffer) {
188                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
189                packet->buf_control = TRACE_CTRL_PACKET;
190                if (!packet->buffer) {
191                        trace_set_err(libtrace, errno,
192                                        "Cannot allocate packet buffer");
193                        return -1;
194                }
195        }
196
197        packet->header = 0;
198        packet->payload = packet->buffer;
199
200        if ((ioctl(FORMAT_DATA->fd, DAG_IOINF, &lt_dag_inf) < 0)) {
201                trace_set_err(libtrace, errno,
202                                "Error using DAG_IOINF");
203                return -1;
204        }
205        if (!IsDUCK(&lt_dag_inf)) {
206                printf("WARNING: %s does not have modern clock support - No DUCK information will be gathered\n", libtrace->uridata);
207                return 0;
208        }
209
210        if ((ioctl(FORMAT_DATA->fd, DAG_IOGETDUCK, (duck_inf *)packet->payload)
211                                < 0)) {
212                trace_set_err(libtrace, errno, "Error using DAG_IOGETDUCK");
213                return -1;
214        }
215
216        packet->type = TRACE_RT_DUCK_2_4;
217        if (!DUCK.dummy_duck)
218                DUCK.dummy_duck = trace_create_dead("duck:dummy");
219        packet->trace = DUCK.dummy_duck;
220        return sizeof(duck_inf);
221}
222
223
224dag_record_t *dag_get_record(libtrace_t *libtrace) {
225        dag_record_t *erfptr = NULL;
226        uint16_t size;
227        erfptr = (dag_record_t *) ((char *)FORMAT_DATA->buf + 
228                        (FORMAT_DATA->bottom + FORMAT_DATA->offset));
229
230        if (!erfptr)
231                return NULL;
232        size = ntohs(erfptr->rlen);
233        assert( size >= dag_record_size );
234        FORMAT_DATA->offset += size;
235        FORMAT_DATA->diff -= size;
236        return erfptr;
237}
238
239void dag_form_packet(dag_record_t *erfptr, libtrace_packet_t *packet) {
240        packet->buffer = erfptr;
241        packet->header = erfptr;
242        packet->type = TRACE_RT_DATA_ERF;
243        if (erfptr->flags.rxerror == 1) {
244                /* rxerror means the payload is corrupt - drop it
245                 * by tweaking rlen */
246                packet->payload = NULL;
247                erfptr->rlen = htons(erf_get_framing_length(packet));
248        } else {
249                packet->payload = (char*)packet->buffer
250                        + erf_get_framing_length(packet);
251        }
252
253}
254
255static int dag_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
256        int numbytes;
257        int size = 0;
258        struct timeval tv;
259        dag_record_t *erfptr = NULL;
260
261        if (DUCK.last_pkt - DUCK.last_duck > DUCK.duck_freq &&
262                        DUCK.duck_freq != 0) {
263                size = dag_get_duckinfo(libtrace, packet);
264                DUCK.last_duck = DUCK.last_pkt;
265                if (size != 0) {
266                        return size;
267                }
268                /* No DUCK support, so don't waste our time anymore */
269                DUCK.duck_freq = 0;
270        }
271
272        if (packet->buf_control == TRACE_CTRL_PACKET) {
273                packet->buf_control = TRACE_CTRL_EXTERNAL;
274                free(packet->buffer);
275                packet->buffer = 0;
276        }
277
278
279        do {
280                numbytes = dag_available(libtrace);
281                if (numbytes < 0)
282                        return numbytes;
283                if (numbytes == 0)
284                        continue;
285                erfptr = dag_get_record(libtrace);
286        } while (erfptr == NULL);
287        dag_form_packet(erfptr, packet);
288        tv = trace_get_timeval(packet);
289        DUCK.last_pkt = tv.tv_sec;
290        return packet->payload ? htons(erfptr->rlen) : erf_get_framing_length(packet);
291}
292
293static libtrace_eventobj_t trace_event_dag(libtrace_t *trace,
294                                        libtrace_packet_t *packet) {
295        libtrace_eventobj_t event = {0,0,0.0,0};
296        int data;
297
298        data = dag_available(trace);
299        if (data > 0) {
300                event.size = dag_read_packet(trace,packet);
301                //DATA(trace)->dag.diff -= event.size;
302                if (trace->filter) {
303                        if (trace_apply_filter(trace->filter, packet)) {
304                                event.type = TRACE_EVENT_PACKET;
305                        } else {
306                                event.type = TRACE_EVENT_SLEEP;
307                                event.seconds = 0.000001;
308                                return event;
309                        }
310                } else {
311                        event.type = TRACE_EVENT_PACKET;
312                }
313                if (trace->snaplen > 0) {
314                        trace_set_capture_length(packet, trace->snaplen);
315                }
316
317                return event;
318        }
319        assert(data == 0);
320        event.type = TRACE_EVENT_SLEEP;
321        event.seconds = 0.0001;
322        return event;
323}
324
325static void dag_help(void) {
326        printf("dag format module: $Revision$\n");
327        printf("Supported input URIs:\n");
328        printf("\tdag:/dev/dagn\n");
329        printf("\n");
330        printf("\te.g.: dag:/dev/dag0\n");
331        printf("\n");
332        printf("Supported output URIs:\n");
333        printf("\tnone\n");
334        printf("\n");
335}
336
337static struct libtrace_format_t dag = {
338        "dag",
339        "$Id$",
340        TRACE_FORMAT_ERF,
341        dag_init_input,                 /* init_input */
342        dag_config_input,               /* config_input */
343        dag_start_input,                /* start_input */
344        dag_pause_input,                /* pause_input */
345        NULL,                           /* init_output */
346        NULL,                           /* config_output */
347        NULL,                           /* start_output */
348        dag_fin_input,                  /* fin_input */
349        NULL,                           /* fin_output */
350        dag_read_packet,                /* read_packet */
351        NULL,                           /* fin_packet */
352        NULL,                           /* write_packet */
353        erf_get_link_type,              /* get_link_type */
354        erf_get_direction,              /* get_direction */
355        erf_set_direction,              /* set_direction */
356        erf_get_erf_timestamp,          /* get_erf_timestamp */
357        NULL,                           /* get_timeval */
358        NULL,                           /* get_seconds */
359        NULL,                           /* seek_erf */
360        NULL,                           /* seek_timeval */
361        NULL,                           /* seek_seconds */
362        erf_get_capture_length,         /* get_capture_length */
363        erf_get_wire_length,            /* get_wire_length */
364        erf_get_framing_length,         /* get_framing_length */
365        erf_set_capture_length,         /* set_capture_length */
366        NULL,                           /* get_fd */
367        trace_event_dag,                /* trace_event */
368        dag_help,                       /* help */
369        NULL                            /* next pointer */
370};
371
372void dag_constructor(void) {
373        register_format(&dag);
374}
Note: See TracBrowser for help on using the repository browser.