source: lib/format_erf.c @ 0d57541

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 0d57541 was 0d57541, checked in by Perry Lorier <perry@…>, 16 years ago

Add preliminary seek support

  • Property mode set to 100644
File size: 24.8 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30#define _GNU_SOURCE
31
32#include "config.h"
33#include "common.h"
34#include "libtrace.h"
35#include "libtrace_int.h"
36#include "format_helper.h"
37#include "parse_cmd.h"
38
39#ifdef HAVE_INTTYPES_H
40#  include <inttypes.h>
41#else
42#  error "Can't find inttypes.h - this needs to be fixed"
43#endif
44
45#ifdef HAVE_STDDEF_H
46#  include <stddef.h>
47#else
48# error "Can't find stddef.h - do you define ptrdiff_t elsewhere?"
49#endif
50#include <sys/types.h>
51#include <sys/socket.h>
52#include <sys/un.h>
53#include <sys/mman.h>
54#include <sys/stat.h>
55#include <unistd.h>
56#include <assert.h>
57#include <errno.h>
58#include <netdb.h>
59#include <fcntl.h>
60#include <getopt.h>
61#include <stdio.h>
62#include <string.h>
63#include <stdlib.h>
64
65
66#define COLLECTOR_PORT 3435
67
68static struct libtrace_format_t erf;
69static struct libtrace_format_t rtclient;
70#if HAVE_DAG
71static struct libtrace_format_t dag;
72#endif
73
74#define DATA(x) ((struct erf_format_data_t *)x->format_data)
75#define DATAOUT(x) ((struct erf_format_data_out_t *)x->format_data)
76
77#define CONNINFO DATA(libtrace)->conn_info
78#define INPUT DATA(libtrace)->input
79#define OUTPUT DATAOUT(libtrace)->output
80#if HAVE_DAG
81#define DAG DATA(libtrace)->dag
82#endif
83#define OPTIONS DATAOUT(libtrace)->options
84struct erf_format_data_t {
85        union {
86                struct {
87                        char *hostname;
88                        short port;
89                } rt;
90        } conn_info;
91       
92        union {
93                int fd;
94                LIBTRACE_FILE file;
95        } input;
96
97        struct {
98                enum { INDEX_UNKNOWN=0, INDEX_NONE, INDEX_EXISTS } exists;
99                LIBTRACE_FILE index;
100                off_t index_len;
101        } seek;
102
103#if HAVE_DAG
104        struct {
105                void *buf; 
106                unsigned bottom;
107                unsigned top;
108                unsigned diff;
109                unsigned curr;
110                unsigned offset;
111        } dag;
112#endif
113};
114
115struct erf_format_data_out_t {
116        union {
117                struct {
118                        char *hostname;
119                        short port;
120                } rt;
121                char *path;
122        } conn_info;
123
124        union {
125                struct {
126                        int level;
127                        int fileflag;
128                } erf;
129               
130        } options;
131       
132        union {
133                int fd;
134                struct rtserver_t * rtserver;
135#if HAVE_ZLIB
136                gzFile *file;
137#else
138                int file;
139#endif
140        } output;
141};
142
143/** Structure holding status information for a packet */
144typedef struct libtrace_packet_status {
145        uint8_t type;
146        uint8_t reserved;
147        uint16_t message;
148} libtrace_packet_status_t;
149
150typedef struct erf_index_t {
151        uint64_t timestamp;
152        uint64_t offset; 
153} erf_index_t;
154
155#ifdef HAVE_DAG
156static int dag_init_input(struct libtrace_t *libtrace) {
157        libtrace->format_data = (struct libtrace_format_data_t *)
158                malloc(sizeof(struct libtrace_format_data_t));
159}
160
161static int dag_start_input(struct libtrace_t *libtrace) {
162        struct stat buf;
163        if (stat(libtrace->uridata, &buf) == -1) {
164                trace_set_err(libtrace,errno,"stat(%s)",libtrace->uridata);
165                return -1;
166        } 
167        if (S_ISCHR(buf.st_mode)) {
168                /* DEVICE */
169                if((INPUT.fd = dag_open(libtrace->uridata)) < 0) {
170                        trace_set_err(libtrace,errno,"Cannot open DAG %s",
171                                        libtrace->uridata);
172                        return -1;
173                }
174                if((DAG.buf = (void *)dag_mmap(INPUT.fd)) == MAP_FAILED) {
175                        trace_set_err(libtrace,errno,"Cannot mmap DAG %s",
176                                        libtrace->uridata);
177                        return -1;
178                }
179                if(dag_start(INPUT.fd) < 0) {
180                        trace_set_err(libtrace,errno,"Cannot start DAG %s",
181                                        libtrace->uridata);
182                        return -1;
183                }
184        } else {
185                trace_set_err(libtrace,errno,"Not a valid dag device: %s",
186                                libtrace->uridata);
187                return -1;
188        }
189        return 0;
190}
191#endif
192
193/* Dag erf ether packets have a 2 byte padding before the packet
194 * so that the ip header is aligned on a 32 bit boundary.
195 */
196static int erf_get_padding(const struct libtrace_packet_t *packet)
197{
198        switch(trace_get_link_type(packet)) {
199                case TRACE_TYPE_ETH:    return 2;
200                default:                return 0;
201        }
202}
203
204static int erf_get_framing_length(const struct libtrace_packet_t *packet)
205{
206        return dag_record_size + erf_get_padding(packet);
207}
208
209
210static int erf_init_input(struct libtrace_t *libtrace) 
211{
212        libtrace->format_data = malloc(sizeof(struct erf_format_data_t));
213
214        return 0; /* success */
215}
216
217static int erf_start_input(libtrace_t *libtrace)
218{
219        INPUT.file = trace_open_file(libtrace);
220
221        if (!INPUT.file)
222                return -1;
223
224        return 0; /* success */
225}
226
227/* Binary search through the index to find the closest point before
228 * the packet.  Consider in future having a btree index perhaps?
229 */
230static int erf_fast_seek_start(libtrace_t *libtrace,uint64_t erfts)
231{
232        size_t max_off = DATA(libtrace)->seek.index_len/sizeof(erf_index_t);
233        size_t min_off = 0;
234        off_t current;
235        erf_index_t record;
236        do {
237                current=(max_off+min_off)>>2;
238
239                LIBTRACE_SEEK(DATA(libtrace)->seek.index,
240                                current*sizeof(record),
241                                SEEK_SET);
242                LIBTRACE_READ(DATA(libtrace)->seek.index,
243                                &record,sizeof(record));
244                if (record.timestamp < erfts) {
245                        min_off=current;
246                }
247                if (record.timestamp > erfts) {
248                        max_off=current;
249                }
250                if (record.timestamp == erfts)
251                        break;
252        } while(min_off<max_off);
253
254        /* If we've passed it, seek backwards.  This loop shouldn't
255         * execute more than twice.
256         */
257        do {
258                LIBTRACE_SEEK(DATA(libtrace)->seek.index,
259                                current*sizeof(record),SEEK_SET);
260                LIBTRACE_READ(DATA(libtrace)->seek.index,
261                                &record,sizeof(record));
262                current--;
263        } while(record.timestamp>erfts);
264
265        /* We've found our location in the trace, now use it. */
266        LIBTRACE_SEEK(INPUT.file,record.offset,SEEK_SET);
267
268        return 0; /* success */
269}
270
271/* There is no index.  Seek through the entire trace from the start, nice
272 * and slowly.
273 */
274static int erf_slow_seek_start(libtrace_t *libtrace,uint64_t erfts)
275{
276        if (INPUT.file) {
277                LIBTRACE_CLOSE(INPUT.file);
278        }
279        INPUT.file = trace_open_file(libtrace);
280        if (!INPUT.file)
281                return -1;
282        return 0;
283}
284
285static int erf_seek_erf(libtrace_t *libtrace,uint64_t erfts)
286{
287        libtrace_packet_t *packet;
288        off_t off = 0;
289
290        if (DATA(libtrace)->seek.exists==INDEX_UNKNOWN) {
291                char buffer[PATH_MAX];
292                snprintf(buffer,sizeof(buffer),"%s.idx",libtrace->uridata);
293                DATA(libtrace)->seek.index=LIBTRACE_OPEN(buffer,"r");
294                if (DATA(libtrace)->seek.index) {
295                        DATA(libtrace)->seek.exists=INDEX_EXISTS;
296                }
297                else {
298                        DATA(libtrace)->seek.exists=INDEX_NONE;
299                }
300        }
301
302        /* If theres an index, use it to find the nearest packet that isn't
303         * after the time we're looking for.  If there is no index we need
304         * to seek slowly through the trace from the beginning.  Sigh.
305         */
306        switch(DATA(libtrace)->seek.exists) {
307                case INDEX_EXISTS:
308                        erf_fast_seek_start(libtrace,erfts);
309                        break;
310                case INDEX_NONE:
311                        erf_slow_seek_start(libtrace,erfts);
312                        break;
313                case INDEX_UNKNOWN:
314                        assert(0);
315                        break;
316        }
317
318        /* Now seek forward looking for the correct timestamp */
319        packet=trace_create_packet();
320        do {
321                trace_read_packet(libtrace,packet);
322                if (trace_get_erf_timestamp(packet)==erfts)
323                        break;
324                off=LIBTRACE_TELL(INPUT.file);
325        } while(trace_get_erf_timestamp(packet)<erfts);
326
327        LIBTRACE_SEEK(INPUT.file,off,SEEK_SET);
328
329        return 0;
330}
331
332static int rtclient_init_input(struct libtrace_t *libtrace) {
333        char *scan;
334        libtrace->format_data = malloc(sizeof(struct erf_format_data_t));
335
336
337        if (strlen(libtrace->uridata) == 0) {
338                CONNINFO.rt.hostname = 
339                        strdup("localhost");
340                CONNINFO.rt.port = 
341                        COLLECTOR_PORT;
342        } else {
343                if ((scan = strchr(libtrace->uridata,':')) == NULL) {
344                        CONNINFO.rt.hostname = 
345                                strdup(libtrace->uridata);
346                        CONNINFO.rt.port =
347                                COLLECTOR_PORT;
348                } else {
349                        CONNINFO.rt.hostname = 
350                                (char *)strndup(libtrace->uridata,
351                                                (scan - libtrace->uridata));
352                        CONNINFO.rt.port = 
353                                atoi(++scan);
354                }
355        }
356
357        return 0; /* success */
358}
359
360static int rtclient_start_input(libtrace_t *libtrace)
361{
362        struct hostent *he;
363        struct sockaddr_in remote;
364        if ((he=gethostbyname(CONNINFO.rt.hostname)) == NULL) { 
365                trace_set_err(libtrace,errno,"failed to resolve %s",
366                                CONNINFO.rt.hostname);
367                return -1;
368        } 
369        if ((INPUT.fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
370                trace_set_err(libtrace,errno,"socket(AF_INET,SOCK_STREAM)");
371                return -1;
372        }
373
374        remote.sin_family = AF_INET;   
375        remote.sin_port = htons(CONNINFO.rt.port);
376        remote.sin_addr = *((struct in_addr *)he->h_addr);
377        bzero(&(remote.sin_zero), 8);
378
379        if (connect(INPUT.fd, (struct sockaddr *)&remote,
380                                sizeof(struct sockaddr)) == -1) {
381                trace_set_err(libtrace,errno,"connect(%s)",
382                                CONNINFO.rt.hostname);
383                return -1;
384        }
385        return 0;
386}
387
388static int erf_init_output(struct libtrace_out_t *libtrace) {
389        libtrace->format_data = calloc(1,sizeof(struct erf_format_data_out_t));
390
391        OPTIONS.erf.level = 0;
392        OPTIONS.erf.fileflag = O_CREAT | O_LARGEFILE | O_WRONLY;
393        OUTPUT.file = 0;
394
395        return 0;
396}
397
398static int erf_config_output(struct libtrace_out_t *libtrace, trace_option_t option, void *value) {
399
400        switch (option) {
401                case TRACE_OPTION_OUTPUT_COMPRESS:
402                        OPTIONS.erf.level = *(int*)value;
403                        return 0;
404                case TRACE_OPTION_OUTPUT_FILEFLAGS:
405                        OPTIONS.erf.fileflag = *(int*)value;
406                        return 0;
407                default:
408                        /* Unknown option */
409                        trace_set_err_out(libtrace,TRACE_ERR_UNKNOWN_OPTION,
410                                        "Unknown option");
411                        return -1;
412        }
413}
414
415
416#ifdef HAVE_DAG
417static int dag_fin_input(struct libtrace_t *libtrace) {
418        dag_stop(INPUT.fd);
419        free(libtrace->format_data);
420}
421#endif
422
423static int rtclient_fin_input(struct libtrace_t *libtrace) {
424        free(CONNINFO.rt.hostname);
425        close(INPUT.fd);
426        free(libtrace->format_data);
427        return 0;
428}
429
430static int erf_fin_input(struct libtrace_t *libtrace) {
431        LIBTRACE_CLOSE(INPUT.file);
432        free(libtrace->format_data);
433        return 0;
434}
435
436static int erf_fin_output(struct libtrace_out_t *libtrace) {
437        LIBTRACE_CLOSE(OUTPUT.file);
438        free(libtrace->format_data);
439        return 0;
440}
441 
442#if HAVE_DAG
443static int dag_read(struct libtrace_t *libtrace, int block_flag) {
444        int numbytes;
445        static short lctr = 0;
446        struct dag_record_t *erfptr = 0;
447        int rlen;
448
449        if (DAG.diff != 0) 
450                return DAG.diff;
451
452        DAG.bottom = DAG.top;
453        DAG.top = dag_offset(
454                        INPUT.fd,
455                        &(DAG.bottom),
456                        block_flag);
457        DAG.diff = DAG.top -
458                DAG.bottom;
459
460        numbytes=DAG.diff;
461        DAG.offset = 0;
462        return numbytes;
463}
464#endif
465
466#if HAVE_DAG
467/* FIXME: dag_read_packet shouldn't update the pointers, dag_fin_packet
468 * should do that.
469 */
470static int dag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
471        int numbytes;
472        int size;
473        dag_record_t *erfptr;
474        void *buffer = packet->buffer;
475        void *buffer2 = buffer;
476        int rlen;
477
478        if (packet->buf_control == TRACE_CTRL_PACKET) {
479                packet->buf_control = TRACE_CTRL_EXTERNAL;
480                free(packet->buffer);
481                packet->buffer = 0;
482        }
483       
484        packet->type = RT_DATA_ERF;
485       
486        if ((numbytes = dag_read(libtrace,0)) <= 0) 
487                return numbytes;
488
489        /*DAG always gives us whole packets */
490        erfptr = (dag_record_t *) ((void *)DAG.buf + 
491                        (DAG.bottom + DAG.offset));
492        size = ntohs(erfptr->rlen);
493
494        if ( size  > LIBTRACE_PACKET_BUFSIZE) {
495                assert( size < LIBTRACE_PACKET_BUFSIZE);
496        }
497       
498        packet->buffer = erfptr;
499        packet->header = erfptr;
500        if (((dag_record_t *)packet->buffer)->flags.rxerror == 1) {
501                packet->payload = NULL;
502        } else {
503                packet->payload = packet->buffer + erf_get_framing_length(packet);
504        }
505
506        DAG.offset += size;
507        DAG.diff -= size;
508
509        assert(DAG.diff >= 0);
510
511        return (size);
512}
513#endif
514
515static int erf_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
516        int numbytes;
517        int size;
518        void *buffer2 = packet->buffer;
519        int rlen;
520
521        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
522                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
523                packet->buf_control = TRACE_CTRL_PACKET;
524        }
525
526        packet->header = packet->buffer;
527        packet->type = RT_DATA_ERF;
528
529        if ((numbytes=LIBTRACE_READ(INPUT.file,
530                                        packet->buffer,
531                                        dag_record_size)) == -1) {
532                trace_set_err(libtrace,errno,"read(%s)",
533                                libtrace->uridata);
534                return -1;
535        }
536        if (numbytes == 0) {
537                return 0;
538        }
539
540        rlen = ntohs(((dag_record_t *)packet->buffer)->rlen);
541        buffer2 = (char*)packet->buffer + dag_record_size;
542        size = rlen - dag_record_size;
543        assert(size < LIBTRACE_PACKET_BUFSIZE);
544
545       
546        /* Unknown/corrupt */
547        assert(((dag_record_t *)packet->buffer)->type < 10);
548       
549        /* read in the rest of the packet */
550        if ((numbytes=LIBTRACE_READ(INPUT.file,
551                                        buffer2,
552                                        size)) != size) {
553                trace_set_err(libtrace,errno, "read(%s)", libtrace->uridata);
554                return -1;
555        }
556        if (((dag_record_t *)packet->buffer)->flags.rxerror == 1) {
557                packet->payload = NULL;
558        } else {
559                packet->payload = (char*)packet->buffer + erf_get_framing_length(packet);
560        }
561        return rlen;
562}
563
564static int rtclient_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
565        int numbytes;
566
567        while(1) {
568#ifndef MSG_NOSIGNAL
569#  define MSG_NOSIGNAL 0
570#endif
571                if ((numbytes = recv(INPUT.fd,
572                                                buffer,
573                                                len,
574                                                MSG_NOSIGNAL)) == -1) {
575                        if (errno == EINTR) {
576                                /*ignore EINTR in case
577                                 *a caller is using signals
578                                 */
579                                continue;
580                        }
581                        trace_set_err(libtrace,errno,"recv(%s)",
582                                        libtrace->uridata);
583                        return -1;
584                }
585                break;
586
587        }
588        return numbytes;
589}
590
591static int rtclient_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
592        int numbytes = 0;
593        char buf[RP_BUFSIZE];
594        int read_required = 0;
595       
596        void *buffer = 0;
597
598        if (packet->buf_control == TRACE_CTRL_EXTERNAL || !packet->buffer) {
599                packet->buf_control = TRACE_CTRL_PACKET;
600                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
601        }
602
603        buffer = packet->buffer;
604        packet->header = packet->buffer;
605       
606        packet->type = RT_DATA_ERF;
607
608       
609        do {
610                struct libtrace_packet_status status;
611                int size;
612                if (tracefifo_out_available(libtrace->fifo) == 0 
613                                || read_required) {
614                        if ((numbytes = rtclient_read(
615                                        libtrace,buf,RP_BUFSIZE))<=0) {
616                                return numbytes;
617                        }
618                        tracefifo_write(libtrace->fifo,buf,numbytes);
619                        read_required = 0;
620                }
621                /* Read status byte */
622                if (tracefifo_out_read(libtrace->fifo,
623                                &status, sizeof(uint32_t)) == 0) {
624                        read_required = 1;
625                        continue;
626                }
627                tracefifo_out_update(libtrace->fifo,sizeof(uint32_t));
628                /* Read in packet size */
629                if (tracefifo_out_read(libtrace->fifo,
630                                &size, sizeof(uint32_t)) == 0) {
631                        tracefifo_out_reset(libtrace->fifo);
632                        read_required = 1;
633                        continue;
634                }
635                tracefifo_out_update(libtrace->fifo, sizeof(uint32_t));
636               
637                if (status.type == 2 /* RT_MSG */) {
638                        /* Need to skip this packet as it is a message packet */
639                        tracefifo_out_update(libtrace->fifo, size);
640                        tracefifo_ack_update(libtrace->fifo, size + 
641                                        sizeof(uint32_t) + 
642                                        sizeof(libtrace_packet_status_t));
643                        continue;
644                }
645               
646                /* read in the full packet */
647                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
648                                                buffer, size)) == 0) {
649                        tracefifo_out_reset(libtrace->fifo);
650                        read_required = 1;
651                        continue;
652                }
653
654                /* got in our whole packet, so... */
655                tracefifo_out_update(libtrace->fifo,size);
656
657                tracefifo_ack_update(libtrace->fifo,size + 
658                                sizeof(uint32_t) + 
659                                sizeof(libtrace_packet_status_t));
660
661                if (((dag_record_t *)buffer)->flags.rxerror == 1) {
662                        packet->payload = NULL;
663                } else {
664                        packet->payload = (char*)packet->buffer + erf_get_framing_length(packet);
665                }
666                return numbytes;
667        } while(1);
668}
669
670static int erf_dump_packet(libtrace_out_t *libtrace,
671                dag_record_t *erfptr, int pad, void *buffer, size_t size) {
672        int numbytes = 0;
673        assert(size<=65536);
674        /* FIXME: Shouldn't this return != dag_record_size+pad on error? */
675        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, erfptr, dag_record_size + pad)) == 0) {
676                trace_set_err_out(libtrace,errno,
677                                "write(%s)",libtrace->uridata);
678                return -1;
679        }
680
681        if ((numbytes=LIBTRACE_WRITE(OUTPUT.file, buffer, size)) == 0) {
682                trace_set_err_out(libtrace,errno,
683                                "write(%s)",libtrace->uridata);
684                return -1;
685        }
686
687        return numbytes + pad + dag_record_size;
688}
689
690static int erf_start_output(libtrace_out_t *libtrace)
691{
692        OUTPUT.file = trace_open_file_out(libtrace,
693                        OPTIONS.erf.level,
694                        OPTIONS.erf.fileflag);
695        if (!OUTPUT.file) {
696                return -1;
697        }
698        return 0;
699}
700               
701static int erf_write_packet(libtrace_out_t *libtrace, 
702                const libtrace_packet_t *packet) 
703{
704        int numbytes = 0;
705        int pad = 0;
706        dag_record_t *dag_hdr = (dag_record_t *)packet->header;
707        void *payload = packet->payload;
708
709        assert(OUTPUT.file);
710
711        pad = erf_get_padding(packet);
712
713        /* If we've had an rxerror, we have no payload to write - fix rlen to
714         * be the correct length */
715        if (payload == NULL) {
716                dag_hdr->rlen = htons(dag_record_size + pad);
717        } 
718       
719        if (libtrace->format == &erf 
720#if HAVE_DAG
721                        || libtrace->format == &dag
722#endif
723                        ) {
724                numbytes = erf_dump_packet(libtrace,
725                                (dag_record_t *)packet->buffer,
726                                pad,
727                                payload,
728                                trace_get_capture_length(packet)
729                                );
730        } else {
731                dag_record_t erfhdr;
732                /* convert format - build up a new erf header */
733                /* Timestamp */
734                erfhdr.ts = trace_get_erf_timestamp(packet);
735                erfhdr.type = libtrace_to_erf_type(trace_get_link_type(packet));
736                /* Flags. Can't do this */
737                memset(&erfhdr.flags,1,sizeof(erfhdr.flags));
738                /* Packet length (rlen includes format overhead) */
739                erfhdr.rlen = trace_get_capture_length(packet) 
740                        + erf_get_framing_length(packet);
741                /* loss counter. Can't do this */
742                erfhdr.lctr = 0;
743                /* Wire length */
744                erfhdr.wlen = trace_get_wire_length(packet);
745
746                /* Write it out */
747                numbytes = erf_dump_packet(libtrace,
748                                &erfhdr,
749                                pad,
750                                payload,
751                                trace_get_capture_length(packet));
752        }
753        return numbytes;
754}
755
756static libtrace_linktype_t erf_get_link_type(const struct libtrace_packet_t *packet) {
757        dag_record_t *erfptr = 0;
758        erfptr = (dag_record_t *)packet->header;
759        return erf_type_to_libtrace(erfptr->type);
760}
761
762static int8_t erf_get_direction(const struct libtrace_packet_t *packet) {
763        dag_record_t *erfptr = 0;
764        erfptr = (dag_record_t *)packet->header;
765        return erfptr->flags.iface;
766}
767
768static int8_t erf_set_direction(const struct libtrace_packet_t *packet, int8_t direction) {
769        dag_record_t *erfptr = 0;
770        erfptr = (dag_record_t *)packet->header;
771        erfptr->flags.iface = direction;
772        return erfptr->flags.iface;
773}
774
775static uint64_t erf_get_erf_timestamp(const struct libtrace_packet_t *packet) {
776        dag_record_t *erfptr = 0;
777        erfptr = (dag_record_t *)packet->header;
778        return erfptr->ts;
779}
780
781static int erf_get_capture_length(const struct libtrace_packet_t *packet) {
782        dag_record_t *erfptr = 0;
783        erfptr = (dag_record_t *)packet->header;
784        return (ntohs(erfptr->rlen) - erf_get_framing_length(packet));
785}
786
787static int erf_get_wire_length(const struct libtrace_packet_t *packet) {
788        dag_record_t *erfptr = 0;
789        erfptr = (dag_record_t *)packet->header;
790        return ntohs(erfptr->wlen);
791}
792
793static size_t erf_set_capture_length(struct libtrace_packet_t *packet, size_t size) {
794        dag_record_t *erfptr = 0;
795        assert(packet);
796        if(size  > trace_get_capture_length(packet)) {
797                /* can't make a packet larger */
798                return trace_get_capture_length(packet);
799        }
800        erfptr = (dag_record_t *)packet->header;
801        erfptr->rlen = htons(size + erf_get_framing_length(packet));
802        printf("Set length: %i\n", trace_get_capture_length(packet));
803        return trace_get_capture_length(packet);
804}
805
806static int rtclient_get_fd(const libtrace_t *libtrace) {
807        return INPUT.fd;
808}
809
810static int erf_get_fd(const libtrace_t *libtrace) {
811        return INPUT.fd;
812}
813
814#ifdef HAVE_DAG
815struct libtrace_eventobj_t trace_event_dag(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
816        struct libtrace_eventobj_t event = {0,0,0.0,0};
817        int dag_fd;
818        int data;
819
820        if (trace->format->get_fd) {
821                dag_fd = trace->format->get_fd(trace);
822        } else {
823                dag_fd = 0;
824        }
825       
826        data = dag_read(trace, DAGF_NONBLOCK);
827
828        if (data > 0) {
829                event.size = trace_read_packet(trace,packet);
830                event.type = TRACE_EVENT_PACKET;
831                return event;
832        }
833        event.type = TRACE_EVENT_SLEEP;
834        event.seconds = 0.0001;
835        return event;
836}
837#endif
838
839#if HAVE_DAG
840static void dag_help() {
841        printf("dag format module: $Revision$\n");
842        printf("Supported input URIs:\n");
843        printf("\tdag:/dev/dagn\n");
844        printf("\n");
845        printf("\te.g.: dag:/dev/dag0\n");
846        printf("\n");
847        printf("Supported output URIs:\n");
848        printf("\tnone\n");
849        printf("\n");
850}
851#endif
852
853static void erf_help() {
854        printf("erf format module: $Revision$\n");
855        printf("Supported input URIs:\n");
856        printf("\terf:/path/to/file\t(uncompressed)\n");
857        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
858        printf("\terf:-\t(stdin, either compressed or not)\n");
859        printf("\terf:/path/to/socket\n");
860        printf("\n");
861        printf("\te.g.: erf:/tmp/trace\n");
862        printf("\n");
863        printf("Supported output URIs:\n");
864        printf("\terf:path/to/file\t(uncompressed)\n");
865        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
866        printf("\terf:-\t(stdout, either compressed or not)\n");
867        printf("\n");
868        printf("\te.g.: erf:/tmp/trace\n");
869        printf("\n");
870        printf("Supported output options:\n");
871        printf("\t-z\tSpecify the gzip compression, ranging from 0 (uncompressed) to 9 - defaults to 1\n");
872        printf("\n");
873
874       
875}
876
877static void rtclient_help() {
878        printf("rtclient format module: $Revision$\n");
879        printf("DEPRECATED - use rt module instead\n");
880        printf("Supported input URIs:\n");
881        printf("\trtclient:host:port\n");
882        printf("\n");
883        printf("\te.g.:rtclient:localhost:3435\n");
884        printf("\n");
885        printf("Supported output URIs:\n");
886        printf("\tnone\n");
887        printf("\n");
888}       
889
890static struct libtrace_format_t erf = {
891        "erf",
892        "$Id$",
893        TRACE_FORMAT_ERF,
894        erf_init_input,                 /* init_input */       
895        NULL,                           /* config_input */
896        erf_start_input,                /* start_input */
897        NULL,                           /* pause_input */
898        erf_init_output,                /* init_output */
899        erf_config_output,              /* config_output */
900        erf_start_output,               /* start_output */
901        erf_fin_input,                  /* fin_input */
902        erf_fin_output,                 /* fin_output */
903        erf_read_packet,                /* read_packet */
904        erf_write_packet,               /* write_packet */
905        erf_get_link_type,              /* get_link_type */
906        erf_get_direction,              /* get_direction */
907        erf_set_direction,              /* set_direction */
908        erf_get_erf_timestamp,          /* get_erf_timestamp */
909        NULL,                           /* get_timeval */
910        NULL,                           /* get_seconds */
911        erf_seek_erf,                   /* seek_erf */
912        NULL,                           /* seek_timeval */
913        NULL,                           /* seek_seconds */
914        erf_get_capture_length,         /* get_capture_length */
915        erf_get_wire_length,            /* get_wire_length */
916        erf_get_framing_length,         /* get_framing_length */
917        erf_set_capture_length,         /* set_capture_length */
918        erf_get_fd,                     /* get_fd */
919        trace_event_trace,              /* trace_event */
920        erf_help                        /* help */
921};
922
923#ifdef HAVE_DAG
924static struct libtrace_format_t dag = {
925        "dag",
926        "$Id$",
927        TRACE_FORMAT_ERF,
928        dag_init_input,                 /* init_input */       
929        NULL,                           /* config_input */
930        dag_start_input,                /* start_input */
931        NULL,                           /* pause_input */
932        NULL,                           /* init_output */
933        NULL,                           /* config_output */
934        NULL,                           /* start_output */
935        dag_fin_input,                  /* fin_input */
936        NULL,                           /* fin_output */
937        dag_read_packet,                /* read_packet */
938        NULL,                           /* write_packet */
939        erf_get_link_type,              /* get_link_type */
940        erf_get_direction,              /* get_direction */
941        erf_set_direction,              /* set_direction */
942        erf_get_erf_timestamp,          /* get_erf_timestamp */
943        NULL,                           /* get_timeval */
944        NULL,                           /* get_seconds */
945        NULL,                           /* seek_erf */
946        NULL,                           /* seek_timeval */
947        NULL,                           /* seek_seconds */
948        erf_get_capture_length,         /* get_capture_length */
949        erf_get_wire_length,            /* get_wire_length */
950        erf_get_framing_length,         /* get_framing_length */
951        erf_set_capture_length,         /* set_capture_length */
952        NULL,                           /* get_fd */
953        trace_event_dag,                /* trace_event */
954        dag_help                        /* help */
955};
956#endif
957
958static struct libtrace_format_t rtclient = {
959        "rtclient",
960        "$Id$",
961        TRACE_FORMAT_ERF,
962        rtclient_init_input,            /* init_input */       
963        NULL,                           /* config_input */
964        rtclient_start_input,           /* start_input */
965        NULL,                           /* pause_input */
966        NULL,                           /* init_output */
967        NULL,                           /* config_output */
968        NULL,                           /* start_output */
969        rtclient_fin_input,             /* fin_input */
970        NULL,                           /* fin_output */
971        rtclient_read_packet,           /* read_packet */
972        NULL,                           /* write_packet */
973        erf_get_link_type,              /* get_link_type */
974        erf_get_direction,              /* get_direction */
975        erf_set_direction,              /* set_direction */
976        erf_get_erf_timestamp,          /* get_erf_timestamp */
977        NULL,                           /* get_timeval */
978        NULL,                           /* get_seconds */
979        NULL,                           /* seek_erf */
980        NULL,                           /* seek_timeval */
981        NULL,                           /* seek_seconds */
982        erf_get_capture_length,         /* get_capture_length */
983        erf_get_wire_length,            /* get_wire_length */
984        erf_get_framing_length,         /* get_framing_length */
985        erf_set_capture_length,         /* set_capture_length */
986        rtclient_get_fd,                /* get_fd */
987        trace_event_device,             /* trace_event */
988        rtclient_help                   /* help */
989};
990
991void __attribute__((constructor)) erf_constructor() {
992        register_format(&rtclient);
993        register_format(&erf);
994#ifdef HAVE_DAG
995        register_format(&dag);
996#endif
997}
Note: See TracBrowser for help on using the repository browser.