source: lib/format_erf.c @ 144fc8d

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

fixed the legacyatm legacypos and legacyeth formats to correctly calculate the framing offset then use that to step into the link layer properly.
Added headers to deal with the link layers.

updated tracedump to be correct now.

  • Property mode set to 100644
File size: 28.1 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#include "daglegacy.h"
65
66#if HAVE_ZLIB
67#  include <zlib.h>
68#  define LIBTRACE_READ gzread
69#  define LIBTRACE_FDOPEN gzdopen
70#  define LIBTRACE_CLOSE gzclose
71#  define LIBTRACE_WRITE gzwrite
72#else
73#  define LIBTRACE_READ read
74#  define LIBTRACE_FDOPEN open
75#  define LIBTRACE_CLOSE close
76#  define LIBTRACE_WRITE write
77#endif
78
79/* Catch undefined O_LARGEFILE on *BSD etc */
80#ifndef O_LARGEFILE
81#  define O_LARGEFILE 0
82#endif
83
84extern struct libtrace_format_t erf;
85extern struct libtrace_format_t rtclient;
86#if HAVE_DAG
87extern struct libtrace_format_t dag;
88#endif
89extern struct libtrace_format_t legacypos;
90extern struct libtrace_format_t legacyeth;
91extern struct libtrace_format_t legacyatm;
92
93#define CONNINFO libtrace->format_data->conn_info
94#define INPUT libtrace->format_data->input
95#define OUTPUT libtrace->format_data->output
96#if HAVE_DAG
97#define DAG libtrace->format_data->dag
98#endif
99#define OPTIONS libtrace->format_data->options
100struct libtrace_format_data_t {
101        union {
102                struct {
103                        char *hostname;
104                        short port;
105                } rt;
106                char *path;             
107        } conn_info;
108       
109        union {
110                int fd;
111#if HAVE_ZLIB
112                gzFile *file;
113#else   
114                FILE *file;
115#endif
116        } input;
117
118#if HAVE_DAG
119        struct {
120                void *buf; 
121                unsigned bottom;
122                unsigned top;
123                unsigned diff;
124                unsigned curr;
125                unsigned offset;
126        } dag;
127#endif
128};
129
130struct libtrace_format_data_out_t {
131        union {
132                struct {
133                        char *hostname;
134                        short port;
135                } rt;
136                char *path;
137        } conn_info;
138
139        union {
140                struct {
141                        int level;
142                } erf;
143               
144        } options;
145       
146        union {
147                int fd;
148                struct rtserver_t * rtserver;
149#if HAVE_ZLIB
150                gzFile *file;
151#else
152                FILE *file;
153#endif
154        } output;
155};
156
157#ifdef HAVE_DAG
158static int dag_init_input(struct libtrace_t *libtrace) {
159        struct stat buf;
160        libtrace->format_data = (struct libtrace_format_data_t *)
161                malloc(sizeof(struct libtrace_format_data_t));
162
163        CONNINFO.path = libtrace->uridata;
164        if (stat(CONNINFO.path,&buf) == -1) {
165                perror("stat");
166                return 0;
167        } 
168        if (S_ISCHR(buf.st_mode)) {
169                // DEVICE
170                libtrace->sourcetype = DEVICE;
171                if((INPUT.fd = dag_open(CONNINFO.path)) < 0) {
172                        fprintf(stderr,"Cannot open DAG %s: %m\n", 
173                                        CONNINFO.path,errno);
174                        exit(0);
175                }
176                if((DAG.buf = (void *)dag_mmap(INPUT.fd)) == MAP_FAILED) {
177                        fprintf(stderr,"Cannot mmap DAG %s: %m\n", 
178                                        CONNINFO.path,errno);
179                        exit(0);
180                }
181                if(dag_start(INPUT.fd) < 0) {
182                        fprintf(stderr,"Cannot start DAG %s: %m\n", 
183                                        CONNINFO.path,errno);
184                        exit(0);
185                }
186        } else {
187                fprintf(stderr,"%s isn't a valid char device, exiting\n",
188                                CONNINFO.path);
189                return 0;
190        }
191        return 1;
192}
193#endif
194
195/* Dag erf ether packets have a 2 byte padding before the packet
196 * so that the ip header is aligned on a 32 bit boundary.
197 */
198static int erf_get_padding(const struct libtrace_packet_t *packet)
199{
200        switch(trace_get_link_type(packet)) {
201                case TRACE_TYPE_ETH:    return 2;
202                default:                return 0;
203        }
204}
205
206static int erf_get_framing_length(const struct libtrace_packet_t *packet)
207{
208        return dag_record_size + erf_get_padding(packet);
209}
210
211static int legacyeth_get_framing_length(const struct libtrace_packet_t *packet) 
212{
213        /* the legacy ethernet format consists of:
214         * uint64_t ts;
215         * uint16_t wlen;
216         * The legacy ethernet framing is therefore five (5) octets;
217         */
218        return sizeof(legacy_ether_t);
219}
220
221static int legacypos_get_framing_length(const struct libtrace_packet_t *packet) 
222{
223        /* the legacy POS format consists of:
224         * uint64_t ts;
225         * uint32_t slen;
226         * uint32_t wlen;
227         * The legacy pos framing is therefore eight (8) octets;
228         */
229        return sizeof(legacy_pos_t);
230}
231
232static int legacyatm_get_framing_length(const struct libtrace_packet_t *packet) 
233{
234        /* the legacy ATM format consists of:
235         * uint64_t ts;
236         * uint32_t crc;
237         * The legacy atm framing is therefore six (6) octets;
238         */
239        return sizeof(legacy_cell_t);
240}
241
242static int erf_init_input(struct libtrace_t *libtrace) {
243        struct stat buf;
244        struct sockaddr_un unix_sock;
245        libtrace->format_data = (struct libtrace_format_data_t *)
246                malloc(sizeof(struct libtrace_format_data_t));
247
248        CONNINFO.path = libtrace->uridata;
249        if (!strncmp(CONNINFO.path,"-",1)) {
250                // STDIN
251                libtrace->sourcetype = STDIN;
252                INPUT.file = LIBTRACE_FDOPEN(STDIN, "r");
253
254        } else {
255                if (stat(CONNINFO.path,&buf) == -1 ) {
256                        perror("stat");
257                        return 0;
258                }
259                if (S_ISSOCK(buf.st_mode)) {
260                        libtrace->sourcetype = SOCKET;
261                        if ((INPUT.fd = socket(
262                                        AF_UNIX, SOCK_STREAM, 0)) == -1) {
263                                perror("socket");
264                                return 0;
265                        }
266                        unix_sock.sun_family = AF_UNIX;
267                        bzero(unix_sock.sun_path,108);
268                        snprintf(unix_sock.sun_path,
269                                        108,"%s"
270                                        ,CONNINFO.path);
271
272                        if (connect(INPUT.fd, 
273                                        (struct sockaddr *)&unix_sock,
274                                        sizeof(struct sockaddr)) == -1) {
275                                perror("connect (unix)");
276                                return 0;
277                        }
278                } else { 
279
280                        libtrace->sourcetype = TRACE;
281
282                        // we use an FDOPEN call to reopen an FD
283                        // returned from open(), so that we can set
284                        // O_LARGEFILE. This gets around gzopen not
285                        // letting you do this...
286                        INPUT.file = LIBTRACE_FDOPEN(open(
287                                                CONNINFO.path,
288                                                O_LARGEFILE),"r");
289                }
290        }
291        return 1;
292}
293
294static int rtclient_init_input(struct libtrace_t *libtrace) {
295        char *scan;
296        char *uridata = libtrace->uridata;
297        struct hostent *he;
298        struct sockaddr_in remote;
299        libtrace->format_data = (struct libtrace_format_data_t *)
300                malloc(sizeof(struct libtrace_format_data_t));
301
302        libtrace->sourcetype = RT;
303
304        if (strlen(uridata) == 0) {
305                CONNINFO.rt.hostname = 
306                        strdup("localhost");
307                CONNINFO.rt.port = 
308                        COLLECTOR_PORT;
309        } else {
310                if ((scan = strchr(uridata,':')) == NULL) {
311                        CONNINFO.rt.hostname = 
312                                strdup(uridata);
313                        CONNINFO.rt.port =
314                                COLLECTOR_PORT;
315                } else {
316                        CONNINFO.rt.hostname = 
317                                (char *)strndup(uridata,
318                                                (scan - uridata));
319                        CONNINFO.rt.port = 
320                                atoi(++scan);
321                }
322        }
323       
324        if ((he=gethostbyname(CONNINFO.rt.hostname)) == NULL) { 
325                perror("gethostbyname");
326                return 0;
327        } 
328        if ((INPUT.fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
329                perror("socket");
330                return 0;
331        }
332
333        remote.sin_family = AF_INET;   
334        remote.sin_port = htons(CONNINFO.rt.port);
335        remote.sin_addr = *((struct in_addr *)he->h_addr);
336        bzero(&(remote.sin_zero), 8);
337
338        if (connect(INPUT.fd, (struct sockaddr *)&remote,
339                                sizeof(struct sockaddr)) == -1) {
340                perror("connect (inet)");
341                return 0;
342        }
343        return 1;
344}
345
346static int erf_init_output(struct libtrace_out_t *libtrace) {
347        char *filemode = 0;
348        int fd;
349        libtrace->format_data = (struct libtrace_format_data_out_t *)
350                calloc(1,sizeof(struct libtrace_format_data_out_t));
351
352        OPTIONS.erf.level = 0;
353#if HAVE_ZLIB
354        asprintf(&filemode,"wb%d",OPTIONS.erf.level);
355#else
356        asprintf(&filemode,"w");
357#endif
358
359        if (!strncmp(libtrace->uridata,"-",1)) {
360                // STDOUT
361                OUTPUT.file = LIBTRACE_FDOPEN(dup(1),filemode);
362        }
363        else {
364                // TRACE
365                fd = open(libtrace->uridata, O_CREAT | O_LARGEFILE | O_WRONLY, S_IRUSR | S_IWUSR);
366                if (fd <= 0) {
367                        return 0;
368                }
369                OUTPUT.file = LIBTRACE_FDOPEN(fd,filemode);
370                 
371        }
372        free(filemode); 
373        return 1;
374}
375
376static int erf_config_output(struct libtrace_out_t *libtrace, int argc, char *argv[]) {
377#if HAVE_ZLIB
378        int opt;
379        int level = OPTIONS.erf.level;
380        optind = 1;
381
382
383        while ((opt = getopt(argc, argv, "z:")) != EOF) {
384                switch (opt) {
385                        case 'z':
386                                level = atoi(optarg);
387                                break;
388                        default:
389                                printf("Bad argument to erf: %s\n", optarg);
390                                // maybe spit out some help here
391                                return -1;
392                }
393        }
394        if (level != OPTIONS.erf.level) {
395                if (level > 9 || level < 0) {
396                        // retarded level choice
397                        printf("Compression level must be between 0 and 9 inclusive - you selected %i \n", level);
398                       
399                } else {
400                        OPTIONS.erf.level = level;
401                        return gzsetparams(OUTPUT.file, level, Z_DEFAULT_STRATEGY);
402                }
403        }
404#endif
405        return 0;
406
407}
408
409
410#ifdef HAVE_DAG
411static int dag_fin_input(struct libtrace_t *libtrace) {
412        dag_stop(INPUT.fd);
413}
414#endif
415
416static int erf_fin_input(struct libtrace_t *libtrace) {
417        LIBTRACE_CLOSE(INPUT.file);
418        free(libtrace->format_data);
419        return 0;
420}
421
422static int rtclient_fin_input(struct libtrace_t *libtrace) {
423        close(INPUT.fd);
424        return 0;
425}
426
427static int erf_fin_output(struct libtrace_out_t *libtrace) {
428        LIBTRACE_CLOSE(OUTPUT.file);
429        free(libtrace->format_data);
430
431        return 0;
432}
433 
434
435
436#if HAVE_DAG
437static int dag_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
438        int numbytes;
439        static short lctr = 0;
440        struct dag_record_t *erfptr = 0;
441        int rlen;
442
443        if (buffer == 0)
444                buffer = malloc(len);
445       
446        DAG.bottom = DAG.top;
447        DAG.top = dag_offset(
448                        INPUT.fd,
449                        &(DAG.bottom),
450                        0);
451        DAG.diff = DAG.top -
452                DAG.bottom;
453
454        numbytes=DAG.diff;
455        DAG.offset = 0;
456        return numbytes;
457}
458#endif
459
460#if HAVE_DAG
461static int dag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
462        int numbytes;
463        int size;
464        char buf[RP_BUFSIZE];
465        dag_record_t *erfptr;
466        void *buffer = packet->buffer;
467        void *buffer2 = buffer;
468        int rlen;
469       
470        if (DAG.diff == 0) {
471                if ((numbytes = dag_read(libtrace,buf,RP_BUFSIZE)) <= 0) 
472                        return numbytes;
473        }
474
475        //DAG always gives us whole packets
476        erfptr = (dag_record_t *) ((void *)DAG.buf + 
477                        (DAG.bottom + DAG.offset));
478        size = ntohs(erfptr->rlen);
479
480        if ( size  > LIBTRACE_PACKET_BUFSIZE) {
481                assert( size < LIBTRACE_PACKET_BUFSIZE);
482        }
483
484        // have to copy it out of the memory hole at this stage:
485        memcpy(packet->buffer, erfptr, size);
486       
487        packet->status = 0;
488        packet->size = size;
489        DAG.offset += size;
490        DAG.diff -= size;
491
492        assert(DAG.diff >= 0);
493
494        return (size);
495}
496#endif
497
498static int legacy_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
499        int numbytes;
500        int size;
501        void *buffer = packet->buffer;
502        void *buffer2 = buffer;
503        int rlen;
504
505        if ((numbytes=LIBTRACE_READ(INPUT.file,
506                                        buffer,
507                                        dag_record_size)) == -1) {
508                perror("libtrace_read");
509                return -1;
510        }
511        if (numbytes == 0) {
512                return 0;
513        }
514
515        // legacy - 64byte captures
516        // type is TYPE_LEGACY
517        rlen = 64;
518        size = rlen - dag_record_size;
519        buffer2 = buffer + dag_record_size;
520       
521        if ((numbytes=LIBTRACE_READ(INPUT.file,
522                                        buffer2,
523                                        size)) == -1) {
524                perror("libtrace_read");
525                return -1;
526        }
527        packet->status = 0;
528        packet->size = rlen;
529        return rlen;
530}
531static int erf_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
532        int numbytes;
533        int size;
534        void *buffer = packet->buffer;
535        void *buffer2 = buffer;
536        int rlen;
537        if ((numbytes=LIBTRACE_READ(INPUT.file,
538                                        buffer,
539                                        dag_record_size)) == -1) {
540                perror("libtrace_read");
541                return -1;
542        }
543        if (numbytes == 0) {
544                return 0;
545        }
546        rlen = ntohs(((dag_record_t *)buffer)->rlen);
547        buffer2 = buffer + dag_record_size;
548        size = rlen - dag_record_size;
549        assert(size < LIBTRACE_PACKET_BUFSIZE);
550        /* If your trace is legacy, or corrupt, then this assert may fire. */
551        /* turns out some older traces have fixed snaplens, which are padded
552         * with 00's if the packet is smaller, so this doesn't work.  Sigh.
553        assert(ntohs(((dag_record_t *)buffer)->rlen) <=
554                        ntohs(((dag_record_t*)buffer)->wlen)+erf_get_framing_length(packet));
555        */
556        /* Unknown/corrupt */
557        assert(((dag_record_t *)buffer)->type < 10);
558       
559        // read in the rest of the packet
560        if ((numbytes=LIBTRACE_READ(INPUT.file,
561                                        buffer2,
562                                        size)) != size) {
563                perror("libtrace_read");
564                return -1;
565        }
566        packet->status = 0;
567        packet->size = rlen;
568        return rlen;
569}
570
571static int rtclient_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
572        int numbytes;
573
574        if (buffer == 0)
575                buffer = malloc(len);
576        while(1) {
577#ifndef MSG_NOSIGNAL
578#  define MSG_NOSIGNAL 0
579#endif
580                if ((numbytes = recv(INPUT.fd,
581                                                buffer,
582                                                len,
583                                                MSG_NOSIGNAL)) == -1) {
584                        if (errno == EINTR) {
585                                //ignore EINTR in case
586                                // a caller is using signals
587                                continue;
588                        }
589                        perror("recv");
590                        return -1;
591                }
592                break;
593
594        }
595        return numbytes;
596}
597
598static int rtclient_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
599        int numbytes = 0;
600        int size = 0;
601        char buf[RP_BUFSIZE];
602        int read_required = 0;
603       
604        void *buffer = 0;
605
606        packet->trace = libtrace;
607        buffer = packet->buffer;
608
609        do {
610                if (tracefifo_out_available(libtrace->fifo) == 0 || read_required) {
611                        if ((numbytes = rtclient_read(
612                                        libtrace,buf,RP_BUFSIZE))<=0) {
613                                return numbytes;
614                        }
615                        tracefifo_write(libtrace->fifo,buf,numbytes);
616                        read_required = 0;
617                }
618                // Read status byte
619                if (tracefifo_out_read(libtrace->fifo,
620                                &packet->status, sizeof(int)) == 0) {
621                        read_required = 1;
622                        continue;
623                }
624                tracefifo_out_update(libtrace->fifo,sizeof(int));
625
626                // read in the ERF header
627                if ((numbytes = tracefifo_out_read(libtrace->fifo, buffer,
628                                                dag_record_size)) == 0) {
629                        tracefifo_out_reset(libtrace->fifo);
630                        read_required = 1;
631                        continue;
632                }
633                size = ntohs(((dag_record_t *)buffer)->rlen);
634               
635                // read in the full packet
636                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
637                                                buffer, size)) == 0) {
638                        tracefifo_out_reset(libtrace->fifo);
639                        read_required = 1;
640                        continue;
641                }
642
643                // got in our whole packet, so...
644                tracefifo_out_update(libtrace->fifo,size);
645
646                tracefifo_ack_update(libtrace->fifo,size + sizeof(int));
647
648                packet->size = numbytes;
649                return numbytes;
650        } while(1);
651}
652
653static int erf_dump_packet(struct libtrace_out_t *libtrace, dag_record_t *erfptr, int pad, void *buffer, size_t size) {
654        int numbytes = 0;
655        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, erfptr, dag_record_size + pad)) == 0) {
656                perror("libtrace_write");
657                return -1;
658        }
659        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, buffer, size)) == 0) {
660                perror("libtrace_write");
661                return -1;
662        }
663        return numbytes + pad + dag_record_size;
664}
665               
666static int erf_write_packet(struct libtrace_out_t *libtrace, const struct libtrace_packet_t *packet) {
667        int numbytes = 0;
668        dag_record_t erfhdr;
669        int pad = 0;
670        void *payload = (void *)trace_get_link(packet);
671
672        pad = erf_get_padding(packet);
673        if (packet->trace->format == &erf || 
674#if HAVE_DAG
675                        packet->trace->format == &dag ||
676#endif
677                        packet->trace->format == &rtclient ) {
678                numbytes = erf_dump_packet(libtrace,
679                                (dag_record_t *)packet->buffer,
680                                pad,
681                                payload,
682                                packet->size - 
683                                        (dag_record_size + pad)); 
684        } else {
685                // convert format - build up a new erf header
686                // Timestamp
687                erfhdr.ts = trace_get_erf_timestamp(packet);
688                // Flags. Can't do this
689                memset(&erfhdr.flags,1,1);
690                // Packet length (rlen includes format overhead)
691                erfhdr.rlen = trace_get_capture_length(packet) + erf_get_framing_length(packet);
692                // loss counter. Can't do this
693                erfhdr.lctr = 0;
694                // Wire length
695                erfhdr.wlen = trace_get_wire_length(packet);
696               
697                // Write it out
698                numbytes = erf_dump_packet(libtrace,
699                                &erfhdr,
700                                pad,
701                                payload,
702                                trace_get_capture_length(packet));
703        }
704        return numbytes;
705}
706
707
708static void *legacypos_get_link(const struct libtrace_packet_t *packet) {
709        const void *posptr = 0;
710        posptr = ((uint8_t *)packet->buffer +
711                        legacypos_get_framing_length(packet));
712        return (void *)posptr;
713}
714
715static libtrace_linktype_t legacypos_get_link_type(const struct libtrace_packet_t *packet) {
716        return TRACE_TYPE_LEGACY_POS;
717}
718
719static void *legacyatm_get_link(const struct libtrace_packet_t *packet) {
720        const void *atmptr = 0;
721        atmptr = ((uint8_t *)packet->buffer +
722                        legacyatm_get_framing_length(packet));
723        return (void *)atmptr;
724}
725
726static libtrace_linktype_t legacyatm_get_link_type(const struct libtrace_packet_t *packet) {
727        return TRACE_TYPE_LEGACY_ATM;
728}
729
730static void *legacyeth_get_link(const struct libtrace_packet_t *packet) {
731        const void *ethptr = 0;
732        ethptr = ((uint8_t *)packet->buffer +
733                        legacyeth_get_framing_length(packet));
734        return (void *)ethptr;
735}
736
737static libtrace_linktype_t legacyeth_get_link_type(const struct libtrace_packet_t *packet) {
738        return TRACE_TYPE_LEGACY_ETH;
739}
740
741
742
743static void *erf_get_link(const struct libtrace_packet_t *packet) {
744        const void *ethptr = 0;
745        dag_record_t *erfptr = 0;
746        erfptr = (dag_record_t *)packet->buffer;
747       
748        if (erfptr->flags.rxerror == 1) {
749                return NULL;
750        }
751        ethptr = ((uint8_t *)packet->buffer +
752                        erf_get_framing_length(packet));
753        return (void *)ethptr;
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->buffer;
759        switch (erfptr->type) {
760                case TYPE_LEGACY:       return TRACE_TYPE_LEGACY;
761                case TYPE_ETH:          return TRACE_TYPE_ETH;
762                case TYPE_ATM:          return TRACE_TYPE_ATM;
763                default: 
764                               fprintf(stderr,"Unknown erf type %02x\n",erfptr->type);
765                               assert(0);
766        }
767        return erfptr->type;
768}
769
770static int8_t erf_get_direction(const struct libtrace_packet_t *packet) {
771        dag_record_t *erfptr = 0;
772        erfptr = (dag_record_t *)packet->buffer;
773        return erfptr->flags.iface;
774}
775
776static int8_t erf_set_direction(const struct libtrace_packet_t *packet, int8_t direction) {
777        dag_record_t *erfptr = 0;
778        erfptr = (dag_record_t *)packet->buffer;
779        erfptr->flags.iface = direction;
780        return erfptr->flags.iface;
781}
782
783static uint64_t erf_get_erf_timestamp(const struct libtrace_packet_t *packet) {
784        dag_record_t *erfptr = 0;
785        erfptr = (dag_record_t *)packet->buffer;
786        return erfptr->ts;
787}
788
789static int legacy_get_capture_length(const struct libtrace_packet_t *packet __attribute__((unused))) {
790        return 64;
791}
792
793static int legacypos_get_wire_length(const struct libtrace_packet_t *packet) {
794        legacy_pos_t *lpos = (legacy_pos_t *)packet->buffer;
795        return ntohs(lpos->wlen);
796}
797
798static int legacyatm_get_wire_length(const struct libtrace_packet_t *packet) {
799        return 53;
800}
801
802static int legacyeth_get_wire_length(const struct libtrace_packet_t *packet) {
803        legacy_ether_t *leth = (legacy_ether_t *)packet->buffer;
804        return ntohs(leth->wlen);
805}
806static int erf_get_capture_length(const struct libtrace_packet_t *packet) {
807        dag_record_t *erfptr = 0;
808        erfptr = (dag_record_t *)packet->buffer;
809        return (ntohs(erfptr->rlen) - erf_get_framing_length(packet));
810}
811
812static int erf_get_wire_length(const struct libtrace_packet_t *packet) {
813        dag_record_t *erfptr = 0;
814        erfptr = (dag_record_t *)packet->buffer;
815        return ntohs(erfptr->wlen);
816}
817
818static size_t erf_set_capture_length(struct libtrace_packet_t *packet, size_t size) {
819        dag_record_t *erfptr = 0;
820        assert(packet);
821        if((size + erf_get_framing_length(packet)) > packet->size) {
822                // can't make a packet larger
823                return (packet->size - erf_get_framing_length(packet));
824        }
825        erfptr = (dag_record_t *)packet->buffer;
826        erfptr->rlen = htons(size + erf_get_framing_length(packet));
827        packet->size = size + erf_get_framing_length(packet);
828        return size;
829}
830
831static int rtclient_get_fd(const struct libtrace_packet_t *packet) {
832        return packet->trace->format_data->input.fd;
833}
834
835static int erf_get_fd(const struct libtrace_packet_t *packet) {
836        return packet->trace->format_data->input.fd;
837}
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 legacypos_help() {
854        printf("legacypos format module: $Revision$\n");
855        printf("Supported input URIs:\n");
856        printf("\tlegacypos:/path/to/file\t(uncompressed)\n");
857        printf("\tlegacypos:/path/to/file.gz\t(gzip-compressed)\n");
858        printf("\tlegacypos:-\t(stdin, either compressed or not)\n");
859        printf("\n");
860        printf("\te.g.: legacypos:/tmp/trace.gz\n");
861        printf("\n");
862}
863
864static void legacyatm_help() {
865        printf("legacyatm format module: $Revision$\n");
866        printf("Supported input URIs:\n");
867        printf("\tlegacyatm:/path/to/file\t(uncompressed)\n");
868        printf("\tlegacyatm:/path/to/file.gz\t(gzip-compressed)\n");
869        printf("\tlegacyatm:-\t(stdin, either compressed or not)\n");
870        printf("\n");
871        printf("\te.g.: legacyatm:/tmp/trace.gz\n");
872        printf("\n");
873}
874
875static void legacyeth_help() {
876        printf("legacyeth format module: $Revision$\n");
877        printf("Supported input URIs:\n");
878        printf("\tlegacyeth:/path/to/file\t(uncompressed)\n");
879        printf("\tlegacyeth:/path/to/file.gz\t(gzip-compressed)\n");
880        printf("\tlegacyeth:-\t(stdin, either compressed or not)\n");
881        printf("\n");
882        printf("\te.g.: legacyeth:/tmp/trace.gz\n");
883        printf("\n");
884}
885
886static void erf_help() {
887        printf("erf format module: $Revision$\n");
888        printf("Supported input URIs:\n");
889        printf("\terf:/path/to/file\t(uncompressed)\n");
890        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
891        printf("\terf:-\t(stdin, either compressed or not)\n");
892        printf("\terf:/path/to/socket\n");
893        printf("\n");
894        printf("\te.g.: erf:/tmp/trace\n");
895        printf("\n");
896        printf("Supported output URIs:\n");
897        printf("\terf:path/to/file\t(uncompressed)\n");
898        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
899        printf("\terf:-\t(stdout, either compressed or not)\n");
900        printf("\n");
901        printf("\te.g.: erf:/tmp/trace\n");
902        printf("\n");
903        printf("Supported output options:\n");
904        printf("\t-z\tSpecify the gzip compression, ranging from 0 (uncompressed) to 9 - defaults to 1\n");
905        printf("\n");
906
907       
908}
909
910static void rtclient_help() {
911        printf("rtclient format module\n");
912        printf("Supported input URIs:\n");
913        printf("\trtclient:hostname:port\n");
914        printf("\trtclient:hostname (connects on default port)\n");
915        printf("\n");
916        printf("\te.g.: rtclient:localhost\n");
917        printf("\te.g.: rtclient:localhost:32500\n");
918        printf("\n");
919        printf("Supported output URIs:\n");
920        printf("\trtclient: \t(will output on default port on all available IP addresses) \n");
921        printf("\trtclient:hostname:port\n");
922        printf("\trtclient:port\n");
923        printf("\n");
924        printf("\te.g.: rtclient:32500\n");
925        printf("\te.g.: rtclient:\n");
926        printf("\n");
927
928}
929
930static struct libtrace_format_t legacyatm = {
931        "legacyatm",
932        "$Id$",
933        "legacyatm",
934        erf_init_input,                 /* init_input */       
935        NULL,                           /* init_output */
936        NULL,                           /* config_output */
937        erf_fin_input,                  /* fin_input */
938        NULL,                           /* fin_output */
939        legacy_read_packet,             /* read_packet */
940        NULL,                           /* write_packet */
941        legacyatm_get_link,             /* get_link */
942        legacyatm_get_link_type,        /* get_link_type */
943        NULL,                           /* get_direction */
944        NULL,                           /* set_direction */
945        erf_get_erf_timestamp,          /* get_erf_timestamp */
946        NULL,                           /* get_timeval */
947        NULL,                           /* get_seconds */
948        legacy_get_capture_length,      /* get_capture_length */
949        legacyatm_get_wire_length,      /* get_wire_length */
950        legacyatm_get_framing_length,   /* get_framing_length */
951        NULL,                           /* set_capture_length */
952        NULL,                           /* get_fd */
953        trace_event_trace,              /* trace_event */
954        legacyatm_help                  /* help */
955};
956
957static struct libtrace_format_t legacyeth = {
958        "legacyeth",
959        "$Id$",
960        "legacyeth",
961        erf_init_input,                 /* init_input */       
962        NULL,                           /* init_output */
963        NULL,                           /* config_output */
964        erf_fin_input,                  /* fin_input */
965        NULL,                           /* fin_output */
966        legacy_read_packet,             /* read_packet */
967        NULL,                           /* write_packet */
968        legacyeth_get_link,             /* get_link */
969        legacyeth_get_link_type,        /* get_link_type */
970        NULL,                           /* get_direction */
971        NULL,                           /* set_direction */
972        erf_get_erf_timestamp,          /* get_erf_timestamp */
973        NULL,                           /* get_timeval */
974        NULL,                           /* get_seconds */
975        legacy_get_capture_length,      /* get_capture_length */
976        legacyeth_get_wire_length,      /* get_wire_length */
977        legacyeth_get_framing_length,   /* get_framing_length */
978        NULL,                           /* set_capture_length */
979        NULL,                           /* get_fd */
980        trace_event_trace,              /* trace_event */
981        legacyeth_help                  /* help */
982};
983
984static struct libtrace_format_t legacypos = {
985        "legacypos",
986        "$Id$",
987        "legacypos",
988        erf_init_input,                 /* init_input */       
989        NULL,                           /* init_output */
990        NULL,                           /* config_output */
991        erf_fin_input,                  /* fin_input */
992        NULL,                           /* fin_output */
993        legacy_read_packet,             /* read_packet */
994        NULL,                           /* write_packet */
995        legacypos_get_link,             /* get_link */
996        legacypos_get_link_type,        /* get_link_type */
997        NULL,                           /* get_direction */
998        NULL,                           /* set_direction */
999        erf_get_erf_timestamp,          /* get_erf_timestamp */
1000        NULL,                           /* get_timeval */
1001        NULL,                           /* get_seconds */
1002        legacy_get_capture_length,      /* get_capture_length */
1003        legacypos_get_wire_length,      /* get_wire_length */
1004        legacypos_get_framing_length,   /* get_framing_length */
1005        NULL,                           /* set_capture_length */
1006        NULL,                           /* get_fd */
1007        trace_event_trace,              /* trace_event */
1008        legacypos_help                  /* help */
1009};
1010
1011       
1012static struct libtrace_format_t erf = {
1013        "erf",
1014        "$Id$",
1015        "erf",
1016        erf_init_input,                 /* init_input */       
1017        erf_init_output,                /* init_output */
1018        erf_config_output,              /* config_output */
1019        erf_fin_input,                  /* fin_input */
1020        erf_fin_output,                 /* fin_output */
1021        erf_read_packet,                /* read_packet */
1022        erf_write_packet,               /* write_packet */
1023        erf_get_link,                   /* get_link */
1024        erf_get_link_type,              /* get_link_type */
1025        erf_get_direction,              /* get_direction */
1026        erf_set_direction,              /* set_direction */
1027        erf_get_erf_timestamp,          /* get_erf_timestamp */
1028        NULL,                           /* get_timeval */
1029        NULL,                           /* get_seconds */
1030        erf_get_capture_length,         /* get_capture_length */
1031        erf_get_wire_length,            /* get_wire_length */
1032        erf_get_framing_length,         /* get_framing_length */
1033        erf_set_capture_length,         /* set_capture_length */
1034        erf_get_fd,                     /* get_fd */
1035        trace_event_trace,              /* trace_event */
1036        erf_help                        /* help */
1037};
1038
1039#ifdef HAVE_DAG
1040static struct libtrace_format_t dag = {
1041        "dag",
1042        "$Id$",
1043        "erf",
1044        dag_init_input,                 /* init_input */       
1045        NULL,                           /* init_output */
1046        NULL,                           /* config_output */
1047        dag_fin_input,                  /* fin_input */
1048        NULL,                           /* fin_output */
1049        dag_read_packet,                /* read_packet */
1050        NULL,                           /* write_packet */
1051        erf_get_link,                   /* get_link */
1052        erf_get_link_type,              /* get_link_type */
1053        erf_get_direction,              /* get_direction */
1054        erf_set_direction,              /* set_direction */
1055        erf_get_erf_timestamp,          /* get_erf_timestamp */
1056        NULL,                           /* get_timeval */
1057        NULL,                           /* get_seconds */
1058        erf_get_capture_length,         /* get_capture_length */
1059        erf_get_wire_length,            /* get_wire_length */
1060        erf_get_framing_length,         /* get_framing_length */
1061        erf_set_capture_length,         /* set_capture_length */
1062        NULL,                           /* get_fd */
1063        trace_event_trace,              /* trace_event */
1064        dag_help                        /* help */
1065};
1066#endif
1067
1068static struct libtrace_format_t rtclient = {
1069        "rtclient",
1070        "$Id$",
1071        "erf",
1072        rtclient_init_input,            /* init_input */       
1073        NULL,                           /* init_output */
1074        NULL,                           /* config_output */
1075        rtclient_fin_input,             /* fin_input */
1076        NULL,                           /* fin_output */
1077        rtclient_read_packet,           /* read_packet */
1078        NULL,                           /* write_packet */
1079        erf_get_link,                   /* get_link */
1080        erf_get_link_type,              /* get_link_type */
1081        erf_get_direction,              /* get_direction */
1082        erf_set_direction,              /* set_direction */
1083        erf_get_erf_timestamp,          /* get_erf_timestamp */
1084        NULL,                           /* get_timeval */
1085        NULL,                           /* get_seconds */
1086        erf_get_capture_length,         /* get_capture_length */
1087        erf_get_wire_length,            /* get_wire_length */
1088        erf_get_framing_length,         /* get_framing_length */
1089        erf_set_capture_length,         /* set_capture_length */
1090        rtclient_get_fd,                /* get_fd */
1091        trace_event_device,             /* trace_event */
1092        rtclient_help                   /* help */
1093};
1094
1095void __attribute__((constructor)) erf_constructor() {
1096        register_format(&erf);
1097#ifdef HAVE_DAG
1098        register_format(&dag);
1099#endif
1100        register_format(&rtclient);
1101        register_format(&legacypos);
1102        register_format(&legacyeth);
1103        register_format(&legacyatm);
1104}
Note: See TracBrowser for help on using the repository browser.