source: lib/format_erf.c @ 3b8a5ef

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

I hate shane

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