source: lib/format_dag25.c @ 35c5a72

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 35c5a72 was 35c5a72, checked in by Daniel Lawson <dlawson@…>, 13 years ago

dag_write_packet() now works correctly for ERF - fixed issues with calculating size to send.
dag_write_packet() still needs to handle type conversions from other formats.

Replaced all references to FORMAT_DATA in the output path to FORMAT_DATA_OUT, to correctly use the format_out_t data structure. This struct only differs in that it lacks a DUCK structure, so perhaps it's worth collapsing these two structs back into a single one, and removing the FORMAT_DATA / FORMAT_DATA_OUT confusion.

  • Property mode set to 100644
File size: 22.3 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: 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/* XXX: Windows doesn't have pthreads, but this code doesn't compile under
49 * Windows anyway so we'll worry about this more later :] */
50#include <pthread.h>
51
52
53#ifdef WIN32
54#  include <io.h>
55#  include <share.h>
56#  define PATH_MAX _MAX_PATH
57#  define snprintf sprintf_s
58#else
59#  include <netdb.h>
60#  ifndef PATH_MAX
61#       define PATH_MAX 4096
62#  endif
63#  include <sys/ioctl.h>
64#endif
65
66
67#define DATA(x) ((struct dag_format_data_t *)x->format_data)
68#define DATA_OUT(x) ((struct dag_format_data_out_t *)x->format_data)
69
70#define FORMAT_DATA DATA(libtrace)
71#define FORMAT_DATA_OUT DATA_OUT(libtrace)
72
73#define DUCK FORMAT_DATA->duck
74static struct libtrace_format_t dag;
75
76struct dag_dev_t {
77        //pthread_mutex_t dag_mutex;
78        char * dev_name;
79        int fd;
80        uint16_t ref_count;
81        struct dag_dev_t *prev;
82        struct dag_dev_t *next;
83};
84
85struct dag_format_data_out_t {
86        struct dag_dev_t *device;
87        unsigned int dagstream;
88        int stream_attached;
89        uint8_t *bottom;
90        uint8_t *top;
91        uint32_t processed;
92        uint64_t drops;
93};
94
95struct dag_format_data_t {
96        struct {
97                uint32_t last_duck;
98                uint32_t duck_freq;
99                uint32_t last_pkt;
100                libtrace_t *dummy_duck;
101        } duck;
102
103        struct dag_dev_t *device;
104        unsigned int dagstream;
105        int stream_attached;
106        uint8_t *bottom;
107        uint8_t *top;
108        uint32_t processed;
109        uint64_t drops;
110};
111
112pthread_mutex_t open_dag_mutex;
113struct dag_dev_t *open_dags = NULL;
114
115static int dag_probe_filename(const char *filename)
116{
117        struct stat statbuf;
118        /* Can we stat the file? */
119        if (stat(filename, &statbuf) != 0) {
120                return 0;
121        }
122        /* Is it a character device? */
123        if (!S_ISCHR(statbuf.st_mode)) {
124                return 0;
125        }
126        /* Yeah, it's probably us. */
127        return 1;
128}
129
130static void dag_init_format_out_data(libtrace_out_t *libtrace) {
131        libtrace->format_data = (struct dag_format_data_out_t *) malloc(sizeof(struct dag_format_data_out_t));
132        // no DUCK on output
133        FORMAT_DATA_OUT->stream_attached = 0;
134        FORMAT_DATA_OUT->drops = 0;
135        FORMAT_DATA_OUT->device = NULL;
136        FORMAT_DATA_OUT->dagstream = 0;
137        FORMAT_DATA_OUT->processed = 0;
138        FORMAT_DATA_OUT->bottom = NULL;
139        FORMAT_DATA_OUT->top = NULL;
140
141}
142
143static void dag_init_format_data(libtrace_t *libtrace) {
144        libtrace->format_data = (struct dag_format_data_t *)
145                malloc(sizeof(struct dag_format_data_t));
146        DUCK.last_duck = 0;
147        DUCK.duck_freq = 0;
148        DUCK.last_pkt = 0;
149        DUCK.dummy_duck = NULL;
150        FORMAT_DATA->stream_attached = 0;
151        FORMAT_DATA->drops = 0;
152        FORMAT_DATA->device = NULL;
153        FORMAT_DATA->dagstream = 0;
154        FORMAT_DATA->processed = 0;
155        FORMAT_DATA->bottom = NULL;
156        FORMAT_DATA->top = NULL;
157}
158
159/* NOTE: This function assumes the open_dag_mutex is held by the caller */
160static struct dag_dev_t *dag_find_open_device(char *dev_name) {
161        struct dag_dev_t *dag_dev;
162
163        dag_dev = open_dags;
164
165        /* XXX: Not exactly zippy, but how often are we going to be dealing
166         * with multiple dag cards? */
167        while (dag_dev != NULL) {
168                if (strcmp(dag_dev->dev_name, dev_name) == 0) {
169                        dag_dev->ref_count ++;
170                        return dag_dev;
171
172                }
173                dag_dev = dag_dev->next;
174        }
175        return NULL;
176
177
178}
179
180/* NOTE: This function assumes the open_dag_mutex is held by the caller */
181static void dag_close_device(struct dag_dev_t *dev) {
182        /* Need to remove from the device list */
183
184        assert(dev->ref_count == 0);
185
186        if (dev->prev == NULL) {
187                open_dags = dev->next;
188                if (dev->next)
189                        dev->next->prev = NULL;
190        } else {
191                dev->prev->next = dev->next;
192                if (dev->next)
193                        dev->next->prev = dev->prev;
194        }
195
196        dag_close(dev->fd);
197        if (dev->dev_name)
198        free(dev->dev_name);
199        free(dev);
200}
201
202static struct dag_dev_t *dag_open_output_device(libtrace_out_t *libtrace, char *dev_name) {
203        struct stat buf;
204        int fd;
205        struct dag_dev_t *new_dev;
206
207        if (stat(dev_name, &buf) == -1) {
208                trace_set_err_out(libtrace,errno,"stat(%s)",dev_name);
209                return NULL;
210}
211
212        if (S_ISCHR(buf.st_mode)) {
213                if((fd = dag_open(dev_name)) < 0) {
214                        trace_set_err_out(libtrace,errno,"Cannot open DAG %s",
215                                        dev_name);
216                        return NULL;
217                }
218        } else {
219                trace_set_err_out(libtrace,errno,"Not a valid dag device: %s",
220                                dev_name);
221                return NULL;
222        }
223
224        new_dev = (struct dag_dev_t *)malloc(sizeof(struct dag_dev_t));
225        new_dev->fd = fd;
226        new_dev->dev_name = dev_name;
227        new_dev->ref_count = 1;
228
229        new_dev->prev = NULL;
230        new_dev->next = open_dags;
231        if (open_dags)
232                open_dags->prev = new_dev;
233
234        open_dags = new_dev;
235
236        return new_dev;
237}
238
239/* NOTE: This function assumes the open_dag_mutex is held by the caller */
240static struct dag_dev_t *dag_open_device(libtrace_t *libtrace, char *dev_name) {
241        struct stat buf;
242        int fd;
243        struct dag_dev_t *new_dev;
244
245        if (stat(dev_name, &buf) == -1) {
246                trace_set_err(libtrace,errno,"stat(%s)",dev_name);
247                return NULL;
248        }
249
250        if (S_ISCHR(buf.st_mode)) {
251                if((fd = dag_open(dev_name)) < 0) {
252                        trace_set_err(libtrace,errno,"Cannot open DAG %s",
253                                        dev_name);
254                        return NULL;
255                }
256        } else {
257                trace_set_err(libtrace,errno,"Not a valid dag device: %s",
258                                dev_name);
259                return NULL;
260        }
261
262        new_dev = (struct dag_dev_t *)malloc(sizeof(struct dag_dev_t));
263        new_dev->fd = fd;
264        new_dev->dev_name = dev_name;
265        new_dev->ref_count = 1;
266
267        new_dev->prev = NULL;
268        new_dev->next = open_dags;
269        if (open_dags)
270                open_dags->prev = new_dev;
271
272        open_dags = new_dev;
273
274        return new_dev;
275}
276
277static int dag_init_output(libtrace_out_t *libtrace) {
278        char *dag_dev_name = NULL;
279        char *scan = NULL;
280        struct dag_dev_t *dag_device = NULL;
281        int stream = 1;
282
283        dag_init_format_out_data(libtrace);
284        pthread_mutex_lock(&open_dag_mutex);
285        if ((scan = strchr(libtrace->uridata,',')) == NULL) {
286                dag_dev_name = strdup(libtrace->uridata);
287        } else {
288                dag_dev_name = (char *)strndup(libtrace->uridata,
289                                (size_t)(scan - libtrace->uridata));
290                stream = atoi(++scan);
291        }
292        FORMAT_DATA_OUT->dagstream = stream;
293
294        dag_device = dag_find_open_device(dag_dev_name);
295
296        if (dag_device == NULL) {
297                /* Device not yet opened - open it ourselves */
298                dag_device = dag_open_output_device(libtrace, dag_dev_name);
299        } else {
300                free(dag_dev_name);
301                dag_dev_name = NULL;
302        }
303
304        if (dag_device == NULL) {
305                if (dag_dev_name) {
306                        free(dag_dev_name);
307                }
308                return -1;
309        }
310
311        FORMAT_DATA_OUT->device = dag_device;
312        pthread_mutex_unlock(&open_dag_mutex);
313        return 0;
314}
315
316static int dag_init_input(libtrace_t *libtrace) {
317        char *dag_dev_name = NULL;
318        char *scan = NULL;
319        int stream = 0;
320        struct dag_dev_t *dag_device = NULL;
321
322        dag_init_format_data(libtrace);
323        pthread_mutex_lock(&open_dag_mutex);
324        if ((scan = strchr(libtrace->uridata,',')) == NULL) {
325                dag_dev_name = strdup(libtrace->uridata);
326        } else {
327                dag_dev_name = (char *)strndup(libtrace->uridata,
328                                (size_t)(scan - libtrace->uridata));
329                stream = atoi(++scan);
330        }
331
332        FORMAT_DATA->dagstream = stream;
333
334        dag_device = dag_find_open_device(dag_dev_name);
335
336        if (dag_device == NULL) {
337                /* Device not yet opened - open it ourselves */
338                dag_device = dag_open_device(libtrace, dag_dev_name);
339        } else {
340                free(dag_dev_name);
341                dag_dev_name = NULL;
342        }
343
344        if (dag_device == NULL) {
345                if (dag_dev_name)
346                        free(dag_dev_name);
347                dag_dev_name = NULL;
348                return -1;
349        }
350
351        FORMAT_DATA->device = dag_device;
352
353        pthread_mutex_unlock(&open_dag_mutex);
354        return 0;
355}
356
357static int dag_config_input(libtrace_t *libtrace, trace_option_t option,
358                                void *data) {
359        char conf_str[4096];
360        switch(option) {
361                case TRACE_OPTION_META_FREQ:
362                        DUCK.duck_freq = *(int *)data;
363                        return 0;
364                case TRACE_OPTION_SNAPLEN:
365                        snprintf(conf_str, 4096, "varlen slen=%i", *(int *)data);
366                        if (dag_configure(FORMAT_DATA->device->fd,
367                                                conf_str) != 0) {
368                                trace_set_err(libtrace, errno, "Failed to configure snaplen on DAG card: %s", libtrace->uridata);
369                                return -1;
370                        }
371                        return 0;
372                case TRACE_OPTION_PROMISC:
373                        /* DAG already operates in a promisc fashion */
374                        return -1;
375                case TRACE_OPTION_FILTER:
376                        return -1;
377                case TRACE_OPTION_EVENT_REALTIME:
378                        return -1;
379        }
380        return -1;
381}
382static int dag_start_output(libtrace_out_t *libtrace) {
383        struct timeval zero, nopoll;
384        uint8_t *top, *bottom;
385        top = bottom = NULL;
386
387        zero.tv_sec = 0;
388        zero.tv_usec = 0;
389        nopoll = zero;
390
391        if (dag_attach_stream(FORMAT_DATA_OUT->device->fd,
392                        FORMAT_DATA_OUT->dagstream, 0, 1048576) < 0) {
393                trace_set_err_out(libtrace, errno, "Cannot attach DAG stream");
394                return -1;
395        }
396
397        if (dag_start_stream(FORMAT_DATA_OUT->device->fd,
398                        FORMAT_DATA_OUT->dagstream) < 0) {
399                trace_set_err_out(libtrace, errno, "Cannot start DAG stream");
400                return -1;
401        }
402        FORMAT_DATA_OUT->stream_attached = 1;
403
404        /* We don't want the dag card to do any sleeping */
405        /*
406        dag_set_stream_poll(FORMAT_DATA->device->fd,
407                        FORMAT_DATA->dagstream, 0, &zero,
408                        &nopoll);
409*/
410        return 0;
411}
412
413static int dag_start_input(libtrace_t *libtrace) {
414        struct timeval zero, nopoll;
415        uint8_t *top, *bottom;
416        uint8_t diff = 0;
417        top = bottom = NULL;
418
419        zero.tv_sec = 0;
420        zero.tv_usec = 0;
421        nopoll = zero;
422
423
424
425        if (dag_attach_stream(FORMAT_DATA->device->fd,
426                                FORMAT_DATA->dagstream, 0, 0) < 0) {
427                trace_set_err(libtrace, errno, "Cannot attach DAG stream");
428                return -1;
429        }
430
431        if (dag_start_stream(FORMAT_DATA->device->fd,
432                                FORMAT_DATA->dagstream) < 0) {
433                trace_set_err(libtrace, errno, "Cannot start DAG stream");
434                return -1;
435        }
436        FORMAT_DATA->stream_attached = 1;
437        /* We don't want the dag card to do any sleeping */
438        dag_set_stream_poll(FORMAT_DATA->device->fd,
439                                FORMAT_DATA->dagstream, 0, &zero,
440                                &nopoll);
441
442        /* Should probably flush the memory hole now */
443
444        do {
445                top = dag_advance_stream(FORMAT_DATA->device->fd,
446                                        FORMAT_DATA->dagstream,
447                                        &bottom);
448                assert(top && bottom);
449                diff = top - bottom;
450                bottom -= diff;
451        } while (diff != 0);
452        FORMAT_DATA->top = NULL;
453        FORMAT_DATA->bottom = NULL;
454        FORMAT_DATA->processed = 0;
455        FORMAT_DATA->drops = 0;
456
457        return 0;
458}
459
460static int dag_pause_output(libtrace_out_t *libtrace) {
461        if (dag_stop_stream(FORMAT_DATA_OUT->device->fd,
462                        FORMAT_DATA_OUT->dagstream) < 0) {
463                trace_set_err_out(libtrace, errno, "Could not stop DAG stream");
464                return -1;
465        }
466        if (dag_detach_stream(FORMAT_DATA_OUT->device->fd,
467                        FORMAT_DATA_OUT->dagstream) < 0) {
468                trace_set_err_out(libtrace, errno, "Could not detach DAG stream");
469                return -1;
470        }
471        FORMAT_DATA_OUT->stream_attached = 0;
472        return 0;
473}
474
475static int dag_pause_input(libtrace_t *libtrace) {
476        if (dag_stop_stream(FORMAT_DATA->device->fd,
477                                FORMAT_DATA->dagstream) < 0) {
478                trace_set_err(libtrace, errno, "Could not stop DAG stream");
479                return -1;
480        }
481        if (dag_detach_stream(FORMAT_DATA->device->fd,
482                                FORMAT_DATA->dagstream) < 0) {
483                trace_set_err(libtrace, errno, "Could not detach DAG stream");
484                return -1;
485        }
486        FORMAT_DATA->stream_attached = 0;
487        return 0;
488}
489
490static int dag_fin_input(libtrace_t *libtrace) {
491        pthread_mutex_lock(&open_dag_mutex);
492        if (FORMAT_DATA->stream_attached)
493                dag_pause_input(libtrace);
494        FORMAT_DATA->device->ref_count --;
495
496        if (FORMAT_DATA->device->ref_count == 0)
497                dag_close_device(FORMAT_DATA->device);
498        if (DUCK.dummy_duck)
499                trace_destroy_dead(DUCK.dummy_duck);
500        free(libtrace->format_data);
501        pthread_mutex_unlock(&open_dag_mutex);
502        return 0; /* success */
503}
504
505static int dag_fin_output(libtrace_out_t *libtrace) {
506        pthread_mutex_lock(&open_dag_mutex);
507        if (FORMAT_DATA_OUT->stream_attached)
508                dag_pause_output(libtrace);
509        FORMAT_DATA_OUT->device->ref_count --;
510
511        if (FORMAT_DATA_OUT->device->ref_count == 0)
512                dag_close_device(FORMAT_DATA_OUT->device);
513        free(libtrace->format_data);
514        pthread_mutex_unlock(&open_dag_mutex);
515        return 0; /* success */
516}
517
518static int dag_get_duckinfo(libtrace_t *libtrace,
519                                libtrace_packet_t *packet) {
520        if (packet->buf_control == TRACE_CTRL_EXTERNAL ||
521                        !packet->buffer) {
522                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
523                packet->buf_control = TRACE_CTRL_PACKET;
524                if (!packet->buffer) {
525                        trace_set_err(libtrace, errno,
526                                        "Cannot allocate packet buffer");
527                        return -1;
528                }
529        }
530
531        packet->header = 0;
532        packet->payload = packet->buffer;
533
534        /* No need to check if we can get DUCK or not - we're modern
535         * enough */
536        if ((ioctl(FORMAT_DATA->device->fd, DAGIOCDUCK,
537                                        (duckinf_t *)packet->payload) < 0)) {
538                trace_set_err(libtrace, errno, "Error using DAGIOCDUCK");
539                return -1;
540        }
541
542        packet->type = TRACE_RT_DUCK_2_5;
543        if (!DUCK.dummy_duck)
544                DUCK.dummy_duck = trace_create_dead("rt:localhost:3434");
545        packet->trace = DUCK.dummy_duck;
546        return sizeof(duckinf_t);
547}
548
549static int dag_available(libtrace_t *libtrace) {
550        uint32_t diff = FORMAT_DATA->top - FORMAT_DATA->bottom;
551        /* If we've processed more than 4MB of data since we last called
552         * dag_advance_stream, then we should call it again to allow the
553         * space occupied by that 4MB to be released */
554        if (diff >= dag_record_size && FORMAT_DATA->processed < 4 * 1024 * 1024)
555                return diff;
556        FORMAT_DATA->top = dag_advance_stream(FORMAT_DATA->device->fd,
557                        FORMAT_DATA->dagstream,
558                        &(FORMAT_DATA->bottom));
559        if (FORMAT_DATA->top == NULL) {
560                trace_set_err(libtrace, errno, "dag_advance_stream failed!");
561                return -1;
562        }
563        FORMAT_DATA->processed = 0;
564        diff = FORMAT_DATA->top - FORMAT_DATA->bottom;
565        return diff;
566}
567
568static dag_record_t *dag_get_record(libtrace_t *libtrace) {
569        dag_record_t *erfptr = NULL;
570        uint16_t size;
571        erfptr = (dag_record_t *)FORMAT_DATA->bottom;
572        if (!erfptr)
573                return NULL;
574        size = ntohs(erfptr->rlen);
575        assert( size >= dag_record_size );
576        /* Make certain we have the full packet available */
577        if (size > (FORMAT_DATA->top - FORMAT_DATA->bottom))
578                return NULL;
579        FORMAT_DATA->bottom += size;
580        FORMAT_DATA->processed += size;
581        return erfptr;
582}
583
584static int dag_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
585                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
586
587        dag_record_t *erfptr;
588
589        if (packet->buffer != buffer &&
590                        packet->buf_control == TRACE_CTRL_PACKET) {
591                free(packet->buffer);
592        }
593
594        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
595                packet->buf_control = TRACE_CTRL_PACKET;
596        } else
597                packet->buf_control = TRACE_CTRL_EXTERNAL;
598
599        erfptr = (dag_record_t *)buffer;
600        packet->buffer = erfptr;
601        packet->header = erfptr;
602        packet->type = rt_type;
603
604        if (erfptr->flags.rxerror == 1) {
605                /* rxerror means the payload is corrupt - drop it
606                 * by tweaking rlen */
607                packet->payload = NULL;
608                erfptr->rlen = htons(erf_get_framing_length(packet));
609        } else {
610                packet->payload = (char*)packet->buffer
611                        + erf_get_framing_length(packet);
612        }
613
614        if (libtrace->format_data == NULL) {
615                dag_init_format_data(libtrace);
616        }
617
618        /* No loss counter for DSM coloured records - have to use
619         * some other API */
620        if (erfptr->type == TYPE_DSM_COLOR_ETH) {
621
622        } else {
623                DATA(libtrace)->drops += ntohs(erfptr->lctr);
624        }
625
626        return 0;
627}
628
629
630static int dag_write_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) {
631        int err;
632        void *record;
633        int size = trace_get_capture_length(packet) + dag_record_size;
634        size = size + (8 - (size % 8));
635
636
637        //dag_record_t *erf = packet->buffer;
638/*
639        record = dag_tx_get_stream_space(FORMAT_DATA_OUT->device->fd, FORMAT_DATA_OUT->dagstream, 65535);
640
641        memcpy(record,packet->buffer,size);
642
643        dag_tx_stream_commit_bytes(FORMAT_DATA_OUT->device->fd, FORMAT_DATA_OUT->dagstream,
644                        size );
645*/
646
647
648
649        if (dag_tx_stream_copy_bytes(FORMAT_DATA_OUT->device->fd, FORMAT_DATA_OUT->dagstream,
650                        packet->buffer, size) == -1 ) {
651                trace_set_err_out(libtrace, errno, "dag_tx_stream_copy_bytes failed!");
652                return 1;
653        }
654
655        return 0;
656}
657
658static int dag_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
659        int size = 0;
660        struct timeval tv;
661        dag_record_t *erfptr = NULL;
662        int numbytes = 0;
663        uint32_t flags = 0;
664
665        if (DUCK.last_pkt - DUCK.last_duck > DUCK.duck_freq &&
666                        DUCK.duck_freq != 0) {
667                size = dag_get_duckinfo(libtrace, packet);
668                DUCK.last_duck = DUCK.last_pkt;
669                if (size != 0) {
670                        return size;
671                }
672                /* No DUCK support, so don't waste our time anymore */
673                DUCK.duck_freq = 0;
674        }
675
676        flags |= TRACE_PREP_DO_NOT_OWN_BUFFER;
677
678        if (packet->buf_control == TRACE_CTRL_PACKET) {
679                free(packet->buffer);
680                packet->buffer = 0;
681        }
682
683        do {
684                numbytes = dag_available(libtrace);
685                if (numbytes < 0)
686                        return numbytes;
687                if (numbytes < dag_record_size)
688                        /* Block until we see a packet */
689                        continue;
690                erfptr = dag_get_record(libtrace);
691        } while (erfptr == NULL);
692
693        //dag_form_packet(erfptr, packet);
694        if (dag_prepare_packet(libtrace, packet, erfptr, TRACE_RT_DATA_ERF,
695                                flags))
696                return -1;
697        tv = trace_get_timeval(packet);
698        DUCK.last_pkt = tv.tv_sec;
699
700        return packet->payload ? htons(erfptr->rlen) :
701                                erf_get_framing_length(packet);
702}
703
704static libtrace_eventobj_t trace_event_dag(libtrace_t *trace,
705                                        libtrace_packet_t *packet) {
706        libtrace_eventobj_t event = {0,0,0.0,0};
707        dag_record_t *erfptr = NULL;
708        int numbytes;
709        uint32_t flags = 0;
710
711        /* Need to call dag_available so that the top pointer will get
712         * updated, otherwise we'll never see any data! */
713        numbytes = dag_available(trace);
714
715        /* May as well not bother calling dag_get_record if dag_available
716         * suggests that there's no data */
717        if (numbytes != 0)
718                erfptr = dag_get_record(trace);
719        if (erfptr == NULL) {
720                /* No packet available */
721                event.type = TRACE_EVENT_SLEEP;
722                event.seconds = 0.0001;
723                return event;
724        }
725        //dag_form_packet(erfptr, packet);
726        if (dag_prepare_packet(trace, packet, erfptr, TRACE_RT_DATA_ERF,
727                                flags)) {
728                event.type = TRACE_EVENT_TERMINATE;
729                return event;
730        }
731
732
733        event.size = trace_get_capture_length(packet) + trace_get_framing_length(packet);
734        if (trace->filter) {
735                if (trace_apply_filter(trace->filter, packet)) {
736                        event.type = TRACE_EVENT_PACKET;
737                } else {
738                        event.type = TRACE_EVENT_SLEEP;
739                        event.seconds = 0.000001;
740                        return event;
741                }
742        } else {
743                event.type = TRACE_EVENT_PACKET;
744        }
745
746        if (trace->snaplen > 0) {
747                trace_set_capture_length(packet, trace->snaplen);
748        }
749
750        return event;
751}
752
753static uint64_t dag_get_dropped_packets(libtrace_t *trace) {
754        if (trace->format_data == NULL)
755                return (uint64_t)-1;
756        return DATA(trace)->drops;
757}
758
759static void dag_help(void) {
760        printf("dag format module: $Revision$\n");
761        printf("Supported input URIs:\n");
762        printf("\tdag:/dev/dagn\n");
763        printf("\n");
764        printf("\te.g.: dag:/dev/dag0\n");
765        printf("\n");
766        printf("Supported output URIs:\n");
767        printf("\tnone\n");
768        printf("\n");
769}
770
771static struct libtrace_format_t dag = {
772        "dag",
773        "$Id$",
774        TRACE_FORMAT_ERF,
775        dag_probe_filename,             /* probe filename */
776        NULL,                           /* probe magic */
777        dag_init_input,                 /* init_input */
778        dag_config_input,               /* config_input */
779        dag_start_input,                /* start_input */
780        dag_pause_input,                /* pause_input */
781        dag_init_output,                /* init_output */
782        NULL,                           /* config_output */
783        dag_start_output,               /* start_output */
784        dag_fin_input,                  /* fin_input */
785        dag_fin_output,                 /* fin_output */
786        dag_read_packet,                /* read_packet */
787        dag_prepare_packet,             /* prepare_packet */
788        NULL,                           /* fin_packet */
789        dag_write_packet,               /* write_packet */
790        erf_get_link_type,              /* get_link_type */
791        erf_get_direction,              /* get_direction */
792        erf_set_direction,              /* set_direction */
793        erf_get_erf_timestamp,          /* get_erf_timestamp */
794        NULL,                           /* get_timeval */
795        NULL,                           /* get_seconds */
796        NULL,                           /* seek_erf */
797        NULL,                           /* seek_timeval */
798        NULL,                           /* seek_seconds */
799        erf_get_capture_length,         /* get_capture_length */
800        erf_get_wire_length,            /* get_wire_length */
801        erf_get_framing_length,         /* get_framing_length */
802        erf_set_capture_length,         /* set_capture_length */
803        NULL,                           /* get_received_packets */
804        NULL,                           /* get_filtered_packets */
805        dag_get_dropped_packets,        /* get_dropped_packets */
806        NULL,                           /* get_captured_packets */
807        NULL,                           /* get_fd */
808        trace_event_dag,                /* trace_event */
809        dag_help,                       /* help */
810        NULL                            /* next pointer */
811};
812
813void dag_constructor(void) {
814        register_format(&dag);
815}
Note: See TracBrowser for help on using the repository browser.