source: lib/format_erf.c @ 03cbfec

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

dag_record_size + 2 <- works better than sizeof(dag_record_t)

  • Property mode set to 100644
File size: 24.0 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
31#include "config.h"
32#include "libtrace.h"
33#include "libtrace_int.h"
34#include "format_helper.h"
35#include "rtserver.h"
36#include "parse_cmd.h"
37
38#ifdef HAVE_INTTYPES_H
39#  include <inttypes.h>
40#else
41#  error "Can't find inttypes.h - this needs to be fixed"
42#endif
43
44#ifdef HAVE_STDDEF_H
45#  include <stddef.h>
46#else
47# error "Can't find stddef.h - do you define ptrdiff_t elsewhere?"
48#endif
49#include <sys/types.h>
50#include <sys/socket.h>
51#include <sys/un.h>
52#include <sys/mman.h>
53#include <sys/stat.h>
54#include <unistd.h>
55#include <assert.h>
56#include <errno.h>
57#include <netdb.h>
58#include <fcntl.h>
59#include <getopt.h>
60
61/* Catch undefined O_LARGEFILE on *BSD etc */
62#ifndef O_LARGEFILE
63#  define O_LARGEFILE 0
64#endif
65
66static struct libtrace_format_t *erf_ptr = 0;
67static struct libtrace_format_t *rtclient_ptr = 0;
68#if HAVE_DAG
69static struct libtrace_format_t *dag_ptr = 0;
70#endif
71
72#define CONNINFO libtrace->format_data->conn_info
73#define INPUT libtrace->format_data->input
74#define OUTPUT libtrace->format_data->output
75#if HAVE_DAG
76#define DAG libtrace->format_data->dag
77#endif
78#define OPTIONS libtrace->format_data->options
79struct libtrace_format_data_t {
80        union {
81                struct {
82                        char *hostname;
83                        short port;
84                } rt;
85                char *path;             
86        } conn_info;
87       
88        union {
89                int fd;
90#if HAVE_ZLIB
91                gzFile *file;
92#else   
93                FILE *file;
94#endif
95        } input;
96
97#if HAVE_DAG
98        struct {
99                void *buf; 
100                unsigned bottom;
101                unsigned top;
102                unsigned diff;
103                unsigned curr;
104                unsigned offset;
105        } dag;
106#endif
107};
108
109struct libtrace_format_data_out_t {
110        union {
111                struct {
112                        char *hostname;
113                        short port;
114                } rt;
115                char *path;
116        } conn_info;
117
118        union {
119                struct {
120                        int level;
121                } erf;
122               
123        } options;
124       
125        union {
126                int fd;
127                struct rtserver_t * rtserver;
128#if HAVE_ZLIB
129                gzFile *file;
130#else
131                FILE *file;
132#endif
133        } output;
134};
135
136#ifdef HAVE_DAG
137static int dag_init_input(struct libtrace_t *libtrace) {
138        struct stat buf;
139        libtrace->format_data = (struct libtrace_format_data_t *)
140                malloc(sizeof(struct libtrace_format_data_t));
141
142        CONNINFO.path = libtrace->uridata;
143        if (stat(CONNINFO.path,&buf) == -1) {
144                perror("stat");
145                return 0;
146        } 
147        if (S_ISCHR(buf.st_mode)) {
148                // DEVICE
149                libtrace->sourcetype = DEVICE;
150                if((INPUT.fd = dag_open(CONNINFO.path)) < 0) {
151                        fprintf(stderr,"Cannot open DAG %s: %m\n", 
152                                        CONNINFO.path,errno);
153                        exit(0);
154                }
155                if((DAG.buf = (void *)dag_mmap(INPUT.fd)) == MAP_FAILED) {
156                        fprintf(stderr,"Cannot mmap DAG %s: %m\n", 
157                                        CONNINFO.path,errno);
158                        exit(0);
159                }
160                if(dag_start(INPUT.fd) < 0) {
161                        fprintf(stderr,"Cannot start DAG %s: %m\n", 
162                                        CONNINFO.path,errno);
163                        exit(0);
164                }
165        } else {
166                fprintf(stderr,"%s isn't a valid char device, exiting\n",
167                                CONNINFO.path);
168                return 0;
169        }
170        return 1;
171}
172#endif
173
174static int erf_init_input(struct libtrace_t *libtrace) {
175        struct stat buf;
176        struct hostent *he;
177        struct sockaddr_in remote;
178        struct sockaddr_un unix_sock;
179        libtrace->format_data = (struct libtrace_format_data_t *)
180                malloc(sizeof(struct libtrace_format_data_t));
181
182        CONNINFO.path = libtrace->uridata;
183        if (!strncmp(CONNINFO.path,"-",1)) {
184                // STDIN
185                libtrace->sourcetype = STDIN;
186#if HAVE_ZLIB
187                INPUT.file = gzdopen(STDIN, "r");
188#else   
189                INPUT.file = stdin;
190#endif
191
192        } else {
193                if (stat(CONNINFO.path,&buf) == -1 ) {
194                        perror("stat");
195                        return 0;
196                }
197                if (S_ISSOCK(buf.st_mode)) {
198                        libtrace->sourcetype = SOCKET;
199                        if ((INPUT.fd = socket(
200                                        AF_UNIX, SOCK_STREAM, 0)) == -1) {
201                                perror("socket");
202                                return 0;
203                        }
204                        unix_sock.sun_family = AF_UNIX;
205                        bzero(unix_sock.sun_path,108);
206                        snprintf(unix_sock.sun_path,
207                                        108,"%s"
208                                        ,CONNINFO.path);
209
210                        if (connect(INPUT.fd, 
211                                        (struct sockaddr *)&unix_sock,
212                                        sizeof(struct sockaddr)) == -1) {
213                                perror("connect (unix)");
214                                return 0;
215                        }
216                } else { 
217                        libtrace->sourcetype = TRACE;
218#if HAVE_ZLIB
219                        // using gzdopen means we can set O_LARGEFILE
220                        // ourselves. However, this way is messy and
221                        // we lose any error checking on "open"
222                        INPUT.file = 
223                                gzdopen(open(
224                                        CONNINFO.path,
225                                        O_LARGEFILE), "r");
226#else
227                        INPUT.file = 
228                                fdopen(open(
229                                        CONNINFO.path,
230                                        O_LARGEFILE), "r");
231#endif
232
233                }
234        }
235        return 1;
236}
237
238static int rtclient_init_input(struct libtrace_t *libtrace) {
239        char *scan;
240        char *uridata = libtrace->uridata;
241        struct hostent *he;
242        struct sockaddr_in remote;
243        libtrace->format_data = (struct libtrace_format_data_t *)
244                malloc(sizeof(struct libtrace_format_data_t));
245
246        libtrace->sourcetype = RT;
247
248        if (strlen(uridata) == 0) {
249                CONNINFO.rt.hostname = 
250                        strdup("localhost");
251                CONNINFO.rt.port = 
252                        COLLECTOR_PORT;
253        } else {
254                if ((scan = strchr(uridata,':')) == NULL) {
255                        CONNINFO.rt.hostname = 
256                                strdup(uridata);
257                        CONNINFO.rt.port =
258                                COLLECTOR_PORT;
259                } else {
260                        CONNINFO.rt.hostname = 
261                                (char *)strndup(uridata,
262                                                (scan - uridata));
263                        CONNINFO.rt.port = 
264                                atoi(++scan);
265                }
266        }
267       
268        if ((he=gethostbyname(CONNINFO.rt.hostname)) == NULL) { 
269                perror("gethostbyname");
270                return 0;
271        } 
272        if ((INPUT.fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
273                perror("socket");
274                return 0;
275        }
276
277        remote.sin_family = AF_INET;   
278        remote.sin_port = htons(CONNINFO.rt.port);
279        remote.sin_addr = *((struct in_addr *)he->h_addr);
280        bzero(&(remote.sin_zero), 8);
281
282        if (connect(INPUT.fd, (struct sockaddr *)&remote,
283                                sizeof(struct sockaddr)) == -1) {
284                perror("connect (inet)");
285                return 0;
286        }
287        return 1;
288}
289
290static int erf_init_output(struct libtrace_out_t *libtrace) {
291        char *filemode = 0;
292        libtrace->format_data = (struct libtrace_format_data_out_t *)
293                calloc(1,sizeof(struct libtrace_format_data_out_t));
294
295        OPTIONS.erf.level = 0;
296        asprintf(&filemode,"wb%d",OPTIONS.erf.level);
297
298        if (!strncmp(libtrace->uridata,"-",1)) {
299                // STDOUT
300#if HAVE_ZLIB
301                OUTPUT.file = gzdopen(dup(1), filemode);
302#else
303                OUTPUT.file = stdout;
304#endif
305        }
306        else {
307                // TRACE
308#if HAVE_ZLIB
309                // using gzdopen means we can set O_LARGEFILE
310                // ourselves. However, this way is messy and
311                // we lose any error checking on "open"
312                OUTPUT.file =  gzdopen(open(
313                                libtrace->uridata,
314                                O_CREAT | O_LARGEFILE | O_WRONLY, 
315                                S_IRUSR | S_IWUSR), filemode);
316#else
317                OUTPUT.file =  fdopen(open(
318                                libtrace->uridata,
319                                O_CREAT | O_LARGEFILE | O_WRONLY, 
320                                S_IRUSR | S_IWUSR), "w");
321#endif
322        }
323       
324        return 1;
325}
326
327static int rtclient_init_output(struct libtrace_out_t *libtrace) {
328        char * uridata = libtrace->uridata;
329        char * scan;
330        libtrace->format_data = (struct libtrace_format_data_out_t *)
331                calloc(1,sizeof(struct libtrace_format_data_out_t));
332        // extract conn_info from uridata
333        if (strlen(uridata) == 0) {
334                CONNINFO.rt.hostname = NULL;
335                CONNINFO.rt.port = COLLECTOR_PORT;
336        }
337        else {
338                if ((scan = strchr(uridata,':')) == NULL) {
339                        CONNINFO.rt.hostname =
340                                NULL;
341                        CONNINFO.rt.port =
342                                atoi(uridata);
343                } else {
344                        CONNINFO.rt.hostname =
345                                (char *)strndup(uridata,
346                                                (scan - uridata));
347                        CONNINFO.rt.port =
348                                atoi(++scan);
349                }
350        }
351       
352       
353        OUTPUT.rtserver = 
354                rtserver_create(CONNINFO.rt.hostname,
355                                CONNINFO.rt.port);
356        if (!OUTPUT.rtserver)
357                return 0;
358
359        return 1;
360}
361
362static int erf_config_output(struct libtrace_out_t *libtrace, int argc, char *argv[]) {
363#if HAVE_ZLIB
364        int opt;
365        int level = OPTIONS.erf.level;
366        optind = 1;
367
368        while ((opt = getopt(argc, argv, "z:")) != EOF) {
369                switch (opt) {
370                        case 'z':
371                                level = atoi(optarg);
372                                break;
373                        default:
374                                printf("Bad argument to erf: %s\n", opt);
375                                // maybe spit out some help here
376                                return -1;
377                }
378        }
379        if (level != OPTIONS.erf.level) {
380                if (level > 9 || level < 0) {
381                        // retarded level choice
382                        printf("Compression level must be between 0 and 9 inclusive - you selected %i \n", level);
383                       
384                } else {
385                        OPTIONS.erf.level = level;
386                        return gzsetparams(OUTPUT.file, level, Z_DEFAULT_STRATEGY);
387                }
388        }
389#endif
390        return 0;
391
392}
393
394static int rtclient_config_output(struct libtrace_out_t *libtrace, int argc, char *argv[]) {
395        return 0;
396}
397
398#ifdef HAVE_DAG
399static int dag_fin_input(struct libtrace_t *libtrace) {
400        dag_stop(INPUT.fd);
401}
402#endif
403
404static int erf_fin_input(struct libtrace_t *libtrace) {
405#if HAVE_ZLIB
406        gzclose(INPUT.file);
407#else   
408        fclose(INPUT.file);     
409#endif
410}
411
412static int rtclient_fin_input(struct libtrace_t *libtrace) {
413        close(INPUT.fd);
414}
415
416static int erf_fin_output(struct libtrace_out_t *libtrace) {
417#if HAVE_ZLIB
418        gzclose(OUTPUT.file);
419#else
420        fclose(OUTPUT.file);
421#endif
422}
423 
424
425static int rtclient_fin_output(struct libtrace_out_t *libtrace) {
426        rtserver_destroy(OUTPUT.rtserver);
427}
428
429#if HAVE_DAG
430static int dag_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
431        int numbytes;
432        static short lctr = 0;
433        struct dag_record_t *erfptr = 0;
434        int rlen;
435
436        if (buffer == 0)
437                buffer = malloc(len);
438       
439        DAG.bottom = DAG.top;
440        DAG.top = dag_offset(
441                        INPUT.fd,
442                        &(DAG.bottom),
443                        0);
444        DAG.diff = DAG.top -
445                DAG.bottom;
446
447        numbytes=DAG.diff;
448        DAG.offset = 0;
449        return numbytes;
450}
451#endif
452
453#if HAVE_DAG
454static int dag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
455        int numbytes;
456        int size;
457        char buf[RP_BUFSIZE];
458        dag_record_t *erfptr;
459        void *buffer = packet->buffer;
460        void *buffer2 = buffer;
461        int rlen;
462       
463        if (DAG.diff == 0) {
464                if ((numbytes = dag_read(libtrace,buf,RP_BUFSIZE)) <= 0) 
465                        return numbytes;
466        }
467
468        //DAG always gives us whole packets
469        erfptr = (dag_record_t *) ((void *)DAG.buf + 
470                        (DAG.bottom + DAG.offset));
471        size = ntohs(erfptr->rlen);
472
473        if ( size  > LIBTRACE_PACKET_BUFSIZE) {
474                printf("%d\n",size);
475                assert( size < LIBTRACE_PACKET_BUFSIZE);
476        }
477
478        // have to copy it out of the memory hole at this stage:
479        memcpy(packet->buffer, erfptr, size);
480
481        packet->size = size;
482        DAG.offset += size;
483        DAG.diff -= size;
484
485        assert(DAG.diff >= 0);
486
487        return (size);
488}
489#endif
490
491static int erf_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
492        int numbytes;
493        int size;
494        char buf[RP_BUFSIZE];
495        dag_record_t *erfptr;
496        void *buffer = packet->buffer;
497        void *buffer2 = buffer;
498        int rlen;
499#if HAVE_ZLIB
500        if ((numbytes=gzread(INPUT.file,
501                                        buffer,
502                                        dag_record_size)) == -1) {
503                perror("gzread");
504                return -1;
505        }
506#else
507        if ((numbytes = read(INPUT.file, buffer, dag_record_size)) == -1) {
508                perror("read");
509                return -1;
510        }
511#endif
512        if (numbytes == 0) {
513                return 0;
514        }
515        rlen = ntohs(((dag_record_t *)buffer)->rlen);
516        size = rlen - dag_record_size;
517        assert(size < LIBTRACE_PACKET_BUFSIZE);
518        buffer2 = buffer + dag_record_size;
519       
520        // read in the rest of the packet
521        if ((numbytes=gzread(INPUT.file,
522                                        buffer2,
523                                        size)) == -1) {
524                perror("gzread");
525                return -1;
526        }
527        packet->size = rlen;
528        return rlen;
529}
530
531static int rtclient_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
532        int numbytes;
533        static short lctr = 0;
534        struct dag_record_t *erfptr = 0;
535        int rlen;
536
537        if (buffer == 0)
538                buffer = malloc(len);
539        while(1) {
540#ifndef MSG_NOSIGNAL
541#  define MSG_NOSIGNAL 0
542#endif
543                if ((numbytes = recv(INPUT.fd,
544                                                buffer,
545                                                len,
546                                                MSG_NOSIGNAL)) == -1) {
547                        if (errno == EINTR) {
548                                //ignore EINTR in case
549                                // a caller is using signals
550                                continue;
551                        }
552                        perror("recv");
553                        return -1;
554                }
555                break;
556
557        }
558        return numbytes;
559}
560
561static int rtclient_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
562        int numbytes = 0;
563        int size = 0;
564        char buf[RP_BUFSIZE];
565        dag_record_t *erfptr = 0;
566        int read_required = 0;
567       
568        void *buffer = 0;
569
570        packet->trace = libtrace;
571        buffer = packet->buffer;
572
573        do {
574                if (tracefifo_out_available(libtrace->fifo) == 0 || read_required) {
575                        if ((numbytes = rtclient_read(
576                                        libtrace,buf,RP_BUFSIZE))<=0) {
577                                return numbytes;
578                        }
579                        tracefifo_write(libtrace->fifo,buf,numbytes);
580                        read_required = 0;
581                }
582                // Read status byte
583                if (tracefifo_out_read(libtrace->fifo,
584                                &packet->status, sizeof(int)) == 0) {
585                        read_required = 1;
586                        continue;
587                }
588                tracefifo_out_update(libtrace->fifo,sizeof(int));
589
590                // read in the ERF header
591                if ((numbytes = tracefifo_out_read(libtrace->fifo, buffer,
592                                                sizeof(dag_record_t))) == 0) {
593                        tracefifo_out_reset(libtrace->fifo);
594                        read_required = 1;
595                        continue;
596                }
597                size = ntohs(((dag_record_t *)buffer)->rlen);
598               
599                // read in the full packet
600                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
601                                                buffer, size)) == 0) {
602                        tracefifo_out_reset(libtrace->fifo);
603                        read_required = 1;
604                        continue;
605                }
606
607                // got in our whole packet, so...
608                tracefifo_out_update(libtrace->fifo,size);
609
610                tracefifo_ack_update(libtrace->fifo,size + sizeof(int));
611
612                packet->size = numbytes;
613                return numbytes;
614        } while(1);
615}
616
617static int erf_dump_packet(struct libtrace_out_t *libtrace, dag_record_t *erfptr, void *buffer, size_t size) {
618        int numbytes = 0;
619#if HAVE_ZLIB
620        if ((numbytes = gzwrite(OUTPUT.file, erfptr, dag_record_size + 2)) == 0) {
621                perror("gzwrite");
622                return -1;
623        }
624        if ((numbytes = gzwrite(OUTPUT.file, buffer, size)) == 0) {
625                perror("gzwrite");
626                return -1;
627        }
628#else
629        if ((numbytes = write(OUTPUT.file, erfptr, dag_record_size + 2)) == 0) {
630                perror("write");
631                return -1;
632        }
633        if ((numbytes = write(OUTPUT.file, buffer, size)) == 0) {
634                perror("write");
635                return -1;
636        }
637#endif
638        return numbytes + sizeof(dag_record_t);
639
640}
641               
642static int erf_write_packet(struct libtrace_out_t *libtrace, struct libtrace_packet_t *packet) {
643        int numbytes = 0;
644        dag_record_t erfhdr;
645        void *payload = (void *)trace_get_link(packet);
646
647        if (packet->trace->format == erf_ptr || 
648#if HAVE_DAG
649                        packet->trace->format == dag_ptr ||
650#endif
651                        packet->trace->format == rtclient_ptr ) {
652                numbytes = erf_dump_packet(libtrace,
653                                (dag_record_t *)packet->buffer,
654                                payload,
655                                packet->size - 
656                                        sizeof(dag_record_t)); 
657        } else {
658                // convert format - build up a new erf header
659                // Timestamp
660                erfhdr.ts = trace_get_erf_timestamp(packet);
661                // Link type
662                switch(trace_get_link_type(packet)) {
663                case TRACE_TYPE_ETH:
664                        erfhdr.type=TYPE_ETH; break;
665                case TRACE_TYPE_ATM:
666                        erfhdr.type=TYPE_ATM; break;
667                default:
668                        erfhdr.type=0; 
669                }
670                // Flags. Can't do this
671                memset(&erfhdr.flags,1,1);
672                // Packet length
673                erfhdr.rlen = trace_get_capture_length(packet);
674                // loss counter. Can't do this
675                erfhdr.lctr = 0;
676                // Wire length
677                erfhdr.wlen = trace_get_wire_length(packet);
678               
679                // Write it out
680                numbytes = erf_dump_packet(libtrace,
681                                &erfhdr,
682                                payload,
683                                erfhdr.rlen);
684        }
685        return numbytes;
686}
687
688static int rtclient_write_packet(struct libtrace_out_t *libtrace, struct libtrace_packet_t *packet) {
689        int numbytes = 0;
690        int size;
691        int intsize = sizeof(int);
692        char buf[RP_BUFSIZE];
693        void *buffer = &buf[intsize];
694        int write_required = 0;
695       
696        do {
697                if (rtserver_checklisten(libtrace->format_data->output.rtserver) < 0)
698                        return -1;
699
700                assert(libtrace->fifo);
701                if (tracefifo_out_available(libtrace->fifo) == 0 || write_required) {
702                        // Packet added to fifo
703                        if ((numbytes = tracefifo_write(libtrace->fifo, packet->buffer, packet->size)) == 0) {
704                                // some error with the fifo
705                                perror("tracefifo_write");
706                                return -1;
707                        }
708                        write_required = 0;
709                }
710
711                // Read from fifo and add protocol header
712                if ((numbytes = tracefifo_out_read(libtrace->fifo, buffer, sizeof(dag_record_t))) == 0) {
713                        // failure reading in from fifo
714                        tracefifo_out_reset(libtrace->fifo);
715                        write_required = 1;
716                        continue;
717                }
718                size = ntohs(((dag_record_t *)buffer)->rlen);
719                assert(size < LIBTRACE_PACKET_BUFSIZE);
720                if ((numbytes = tracefifo_out_read(libtrace->fifo, buffer, size)) == 0) {
721                       // failure reading in from fifo
722                       tracefifo_out_reset(libtrace->fifo);
723                       write_required = 1;
724                       continue;
725                }
726                // Sort out the protocol header
727                memcpy(buf, &packet->status, intsize);
728
729                if ((numbytes = rtserver_sendclients(libtrace->format_data->output.rtserver, buf, size + sizeof(int))) < 0) {
730                        write_required = 0;
731                        continue;
732                }
733
734
735                tracefifo_out_update(libtrace->fifo, size);
736                tracefifo_ack_update(libtrace->fifo, size);
737                return numbytes;
738        } while(1);
739}
740
741static void *erf_get_link(const struct libtrace_packet_t *packet) {
742        const void *ethptr = 0;
743        dag_record_t *erfptr = 0;
744        erfptr = (dag_record_t *)packet->buffer;
745       
746        if (erfptr->flags.rxerror == 1) {
747                return NULL;
748        }
749        ethptr = ((uint8_t *)packet->buffer +
750                        dag_record_size + 2);
751        return (void *)ethptr;
752}
753
754static libtrace_linktype_t erf_get_link_type(const struct libtrace_packet_t *packet) {
755        dag_record_t *erfptr = 0;
756        erfptr = (dag_record_t *)packet->buffer;
757        switch (erfptr->type) {
758                case TYPE_ETH: return TRACE_TYPE_ETH;
759                case TYPE_ATM: return TRACE_TYPE_ATM;
760                default: assert(0);
761        }
762        return erfptr->type;
763}
764
765static int8_t erf_get_direction(const struct libtrace_packet_t *packet) {
766        dag_record_t *erfptr = 0;
767        erfptr = (dag_record_t *)packet->buffer;
768        return erfptr->flags.iface;
769}
770
771static int8_t erf_set_direction(const struct libtrace_packet_t *packet, int8_t direction) {
772        dag_record_t *erfptr = 0;
773        erfptr = (dag_record_t *)packet->buffer;
774        erfptr->flags.iface = direction;
775        return erfptr->flags.iface;
776}
777
778static uint64_t erf_get_erf_timestamp(const struct libtrace_packet_t *packet) {
779        dag_record_t *erfptr = 0;
780        erfptr = (dag_record_t *)packet->buffer;
781        return erfptr->ts;
782}
783
784static int erf_get_capture_length(const struct libtrace_packet_t *packet) {
785        dag_record_t *erfptr = 0;
786        erfptr = (dag_record_t *)packet->buffer;
787        return ntohs(erfptr->rlen);
788}
789
790static int erf_get_wire_length(const struct libtrace_packet_t *packet) {
791        dag_record_t *erfptr = 0;
792        erfptr = (dag_record_t *)packet->buffer;
793        return ntohs(erfptr->wlen);
794}
795
796static size_t erf_set_capture_length(struct libtrace_packet_t *packet, size_t size) {
797        dag_record_t *erfptr = 0;
798        assert(packet);
799        if(size > packet->size) {
800                // can't make a packet larger
801                return packet->size;
802        }
803        erfptr = (dag_record_t *)packet->buffer;
804        erfptr->rlen = ntohs(size + sizeof(dag_record_t));
805        packet->size = size + sizeof(dag_record_t);
806        return packet->size;
807}
808
809static int rtclient_get_fd(struct libtrace_packet_t *packet) {
810        return packet->trace->format_data->input.fd;
811}
812
813static int erf_get_fd(struct libtrace_packet_t *packet) {
814        return packet->trace->format_data->input.fd;
815}
816
817#if HAVE_DAG
818static void dag_help() {
819        printf("dag format module: $Revision$\n");
820        printf("Supported input URIs:\n");
821        printf("\tdag:/dev/dagn\n");
822        printf("\n");
823        printf("\te.g.: dag:/dev/dag0\n");
824        printf("\n");
825        printf("Supported output URIs:\n");
826        printf("\tnone\n");
827        printf("\n");
828}
829#endif
830
831
832static void erf_help() {
833        printf("erf format module: $Revision$\n");
834        printf("Supported input URIs:\n");
835        printf("\terf:/path/to/file\t(uncompressed)\n");
836        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
837        printf("\terf:-\t(stdin, either compressed or not)\n");
838        printf("\terf:/path/to/socket\n");
839        printf("\n");
840        printf("\te.g.: erf:/tmp/trace\n");
841        printf("\n");
842        printf("Supported output URIs:\n");
843        printf("\terf:path/to/file\t(uncompressed)\n");
844        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
845        printf("\terf:-\t(stdout, either compressed or not)\n");
846        printf("\n");
847        printf("\te.g.: erf:/tmp/trace\n");
848        printf("\n");
849        printf("Supported output options:\n");
850        printf("\t-z\tSpecify the gzip compression, ranging from 0 (uncompressed) to 9 - defaults to 1\n");
851        printf("\n");
852
853       
854}
855
856static void rtclient_help() {
857        printf("rtclient format module\n");
858        printf("Supported input URIs:\n");
859        printf("\trtclient:hostname:port\n");
860        printf("\trtclient:hostname (connects on default port)\n");
861        printf("\n");
862        printf("\te.g.: rtclient:localhost\n");
863        printf("\te.g.: rtclient:localhost:32500\n");
864        printf("\n");
865        printf("Supported output URIs:\n");
866        printf("\trtclient: \t(will output on default port on all available IP addresses) \n");
867        printf("\trtclient:hostname:port\n");
868        printf("\trtclient:port\n");
869        printf("\n");
870        printf("\te.g.: rtclient:32500\n");
871        printf("\te.g.: rtclient:\n");
872        printf("\n");
873
874}
875
876       
877static struct libtrace_format_t erf = {
878        "erf",
879        "$Id$",
880        "erf",
881        erf_init_input,                 /* init_input */       
882        erf_init_output,                /* init_output */
883        erf_config_output,              /* config_output */
884        erf_fin_input,                  /* fin_input */
885        erf_fin_output,                 /* fin_output */
886        erf_read_packet,                /* read_packet */
887        erf_write_packet,               /* write_packet */
888        erf_get_link,                   /* get_link */
889        erf_get_link_type,              /* get_link_type */
890        erf_get_direction,              /* get_direction */
891        erf_set_direction,              /* set_direction */
892        erf_get_erf_timestamp,          /* get_erf_timestamp */
893        NULL,                           /* get_timeval */
894        NULL,                           /* get_seconds */
895        erf_get_capture_length,         /* get_capture_length */
896        erf_get_wire_length,            /* get_wire_length */
897        erf_set_capture_length,         /* set_capture_length */
898        erf_get_fd,                     /* get_fd */
899        trace_event_trace,              /* trace_event */
900        erf_help                        /* help */
901};
902
903#ifdef HAVE_DAG
904static struct libtrace_format_t dag = {
905        "dag",
906        "$Id$",
907        "erf",
908        dag_init_input,                 /* init_input */       
909        NULL,                           /* init_output */
910        NULL,                           /* config_output */
911        dag_fin_input,                  /* fin_input */
912        NULL,                           /* fin_output */
913        dag_read_packet,                /* read_packet */
914        NULL,                           /* write_packet */
915        erf_get_link,                   /* get_link */
916        erf_get_link_type,              /* get_link_type */
917        erf_get_direction,              /* get_direction */
918        erf_set_direction,              /* set_direction */
919        erf_get_erf_timestamp,          /* get_erf_timestamp */
920        NULL,                           /* get_timeval */
921        NULL,                           /* get_seconds */
922        erf_get_capture_length,         /* get_capture_length */
923        erf_get_wire_length,            /* get_wire_length */
924        erf_set_capture_length,         /* set_capture_length */
925        NULL,                           /* get_fd */
926        trace_event_trace,              /* trace_event */
927        dag_help                        /* help */
928};
929#endif
930
931static struct libtrace_format_t rtclient = {
932        "rtclient",
933        "$Id$",
934        "erf",
935        rtclient_init_input,            /* init_input */       
936        rtclient_init_output,           /* init_output */
937        rtclient_config_output,         /* config_output */
938        rtclient_fin_input,             /* fin_input */
939        rtclient_fin_output,            /* fin_output */
940        rtclient_read_packet,           /* read_packet */
941        rtclient_write_packet,          /* write_packet */
942        erf_get_link,                   /* get_link */
943        erf_get_link_type,              /* get_link_type */
944        erf_get_direction,              /* get_direction */
945        erf_set_direction,              /* set_direction */
946        erf_get_erf_timestamp,          /* get_erf_timestamp */
947        NULL,                           /* get_timeval */
948        NULL,                           /* get_seconds */
949        erf_get_capture_length,         /* get_capture_length */
950        erf_get_wire_length,            /* get_wire_length */
951        erf_set_capture_length,         /* set_capture_length */
952        rtclient_get_fd,                /* get_fd */
953        trace_event_device,             /* trace_event */
954        rtclient_help                   /* help */
955};
956
957void __attribute__((constructor)) erf_constructor() {
958        erf_ptr = &erf;
959        register_format(erf_ptr);
960#ifdef HAVE_DAG
961        dag_ptr = &dag;
962        register_format(dag_ptr);
963#endif
964        rtclient_ptr = &rtclient;
965        register_format(rtclient_ptr);
966}
Note: See TracBrowser for help on using the repository browser.