source: lib/format_erf.c @ d3e4697

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since d3e4697 was d3e4697, checked in by Shane Alcock <salcock@…>, 15 years ago

Made sure that most formats set packet->status to zero when reading in a packet.

  • 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->status = 0;
482        packet->size = size;
483        DAG.offset += size;
484        DAG.diff -= size;
485
486        assert(DAG.diff >= 0);
487
488        return (size);
489}
490#endif
491
492static int erf_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
493        int numbytes;
494        int size;
495        char buf[RP_BUFSIZE];
496        dag_record_t *erfptr;
497        void *buffer = packet->buffer;
498        void *buffer2 = buffer;
499        int rlen;
500#if HAVE_ZLIB
501        if ((numbytes=gzread(INPUT.file,
502                                        buffer,
503                                        dag_record_size)) == -1) {
504                perror("gzread");
505                return -1;
506        }
507#else
508        if ((numbytes = read(INPUT.file, buffer, dag_record_size)) == -1) {
509                perror("read");
510                return -1;
511        }
512#endif
513        if (numbytes == 0) {
514                return 0;
515        }
516        rlen = ntohs(((dag_record_t *)buffer)->rlen);
517        size = rlen - dag_record_size;
518        assert(size < LIBTRACE_PACKET_BUFSIZE);
519        buffer2 = buffer + dag_record_size;
520       
521        // read in the rest of the packet
522        if ((numbytes=gzread(INPUT.file,
523                                        buffer2,
524                                        size)) == -1) {
525                perror("gzread");
526                return -1;
527        }
528        packet->status = 0;
529        packet->size = rlen;
530        return rlen;
531}
532
533static int rtclient_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
534        int numbytes;
535        static short lctr = 0;
536        struct dag_record_t *erfptr = 0;
537        int rlen;
538
539        if (buffer == 0)
540                buffer = malloc(len);
541        while(1) {
542#ifndef MSG_NOSIGNAL
543#  define MSG_NOSIGNAL 0
544#endif
545                if ((numbytes = recv(INPUT.fd,
546                                                buffer,
547                                                len,
548                                                MSG_NOSIGNAL)) == -1) {
549                        if (errno == EINTR) {
550                                //ignore EINTR in case
551                                // a caller is using signals
552                                continue;
553                        }
554                        perror("recv");
555                        return -1;
556                }
557                break;
558
559        }
560        return numbytes;
561}
562
563static int rtclient_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
564        int numbytes = 0;
565        int size = 0;
566        char buf[RP_BUFSIZE];
567        dag_record_t *erfptr = 0;
568        int read_required = 0;
569       
570        void *buffer = 0;
571
572        packet->trace = libtrace;
573        buffer = packet->buffer;
574
575        do {
576                if (tracefifo_out_available(libtrace->fifo) == 0 || read_required) {
577                        if ((numbytes = rtclient_read(
578                                        libtrace,buf,RP_BUFSIZE))<=0) {
579                                return numbytes;
580                        }
581                        tracefifo_write(libtrace->fifo,buf,numbytes);
582                        read_required = 0;
583                }
584                // Read status byte
585                if (tracefifo_out_read(libtrace->fifo,
586                                &packet->status, sizeof(int)) == 0) {
587                        read_required = 1;
588                        continue;
589                }
590                tracefifo_out_update(libtrace->fifo,sizeof(int));
591
592                // read in the ERF header
593                if ((numbytes = tracefifo_out_read(libtrace->fifo, buffer,
594                                                sizeof(dag_record_t))) == 0) {
595                        tracefifo_out_reset(libtrace->fifo);
596                        read_required = 1;
597                        continue;
598                }
599                size = ntohs(((dag_record_t *)buffer)->rlen);
600               
601                // read in the full packet
602                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
603                                                buffer, size)) == 0) {
604                        tracefifo_out_reset(libtrace->fifo);
605                        read_required = 1;
606                        continue;
607                }
608
609                // got in our whole packet, so...
610                tracefifo_out_update(libtrace->fifo,size);
611
612                tracefifo_ack_update(libtrace->fifo,size + sizeof(int));
613
614                packet->size = numbytes;
615                return numbytes;
616        } while(1);
617}
618
619static int erf_dump_packet(struct libtrace_out_t *libtrace, dag_record_t *erfptr, void *buffer, size_t size) {
620        int numbytes = 0;
621#if HAVE_ZLIB
622        if ((numbytes = gzwrite(OUTPUT.file, erfptr, dag_record_size + 2)) == 0) {
623                perror("gzwrite");
624                return -1;
625        }
626        if ((numbytes = gzwrite(OUTPUT.file, buffer, size)) == 0) {
627                perror("gzwrite");
628                return -1;
629        }
630#else
631        if ((numbytes = write(OUTPUT.file, erfptr, dag_record_size + 2)) == 0) {
632                perror("write");
633                return -1;
634        }
635        if ((numbytes = write(OUTPUT.file, buffer, size)) == 0) {
636                perror("write");
637                return -1;
638        }
639#endif
640        return numbytes + sizeof(dag_record_t);
641
642}
643               
644static int erf_write_packet(struct libtrace_out_t *libtrace, struct libtrace_packet_t *packet) {
645        int numbytes = 0;
646        dag_record_t erfhdr;
647        void *payload = (void *)trace_get_link(packet);
648
649        if (packet->trace->format == erf_ptr || 
650#if HAVE_DAG
651                        packet->trace->format == dag_ptr ||
652#endif
653                        packet->trace->format == rtclient_ptr ) {
654                numbytes = erf_dump_packet(libtrace,
655                                (dag_record_t *)packet->buffer,
656                                payload,
657                                packet->size - 
658                                        (dag_record_size + 2)); 
659        } else {
660                // convert format - build up a new erf header
661                // Timestamp
662                erfhdr.ts = trace_get_erf_timestamp(packet);
663                // Link type
664                switch(trace_get_link_type(packet)) {
665                case TRACE_TYPE_ETH:
666                        erfhdr.type=TYPE_ETH; break;
667                case TRACE_TYPE_ATM:
668                        erfhdr.type=TYPE_ATM; break;
669                default:
670                        erfhdr.type=0; 
671                }
672                // Flags. Can't do this
673                memset(&erfhdr.flags,1,1);
674                // Packet length
675                erfhdr.rlen = trace_get_capture_length(packet);
676                // loss counter. Can't do this
677                erfhdr.lctr = 0;
678                // Wire length
679                erfhdr.wlen = trace_get_wire_length(packet);
680               
681                // Write it out
682                numbytes = erf_dump_packet(libtrace,
683                                &erfhdr,
684                                payload,
685                                erfhdr.rlen);
686        }
687        return numbytes;
688}
689
690static int rtclient_write_packet(struct libtrace_out_t *libtrace, struct libtrace_packet_t *packet) {
691        int numbytes = 0;
692        int size;
693        int intsize = sizeof(int);
694        char buf[RP_BUFSIZE];
695        void *buffer = &buf[intsize];
696        int write_required = 0;
697       
698        do {
699                if (rtserver_checklisten(libtrace->format_data->output.rtserver) < 0)
700                        return -1;
701
702                assert(libtrace->fifo);
703                if (tracefifo_out_available(libtrace->fifo) == 0 || write_required) {
704                        // Packet added to fifo
705                        if ((numbytes = tracefifo_write(libtrace->fifo, packet->buffer, packet->size)) == 0) {
706                                // some error with the fifo
707                                perror("tracefifo_write");
708                                return -1;
709                        }
710                        write_required = 0;
711                }
712
713                // Read from fifo and add protocol header
714                if ((numbytes = tracefifo_out_read(libtrace->fifo, buffer, sizeof(dag_record_t))) == 0) {
715                        // failure reading in from fifo
716                        tracefifo_out_reset(libtrace->fifo);
717                        write_required = 1;
718                        continue;
719                }
720                size = ntohs(((dag_record_t *)buffer)->rlen);
721                assert(size < LIBTRACE_PACKET_BUFSIZE);
722                if ((numbytes = tracefifo_out_read(libtrace->fifo, buffer, size)) == 0) {
723                       // failure reading in from fifo
724                       tracefifo_out_reset(libtrace->fifo);
725                       write_required = 1;
726                       continue;
727                }
728                // Sort out the protocol header
729                memcpy(buf, &packet->status, intsize);
730
731                if ((numbytes = rtserver_sendclients(libtrace->format_data->output.rtserver, buf, size + sizeof(int))) < 0) {
732                        write_required = 0;
733                        continue;
734                }
735
736
737                tracefifo_out_update(libtrace->fifo, size);
738                tracefifo_ack_update(libtrace->fifo, size);
739                return numbytes;
740        } while(1);
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                        dag_record_size + 2);
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_ETH: return TRACE_TYPE_ETH;
761                case TYPE_ATM: return TRACE_TYPE_ATM;
762                default: assert(0);
763        }
764        return erfptr->type;
765}
766
767static int8_t erf_get_direction(const struct libtrace_packet_t *packet) {
768        dag_record_t *erfptr = 0;
769        erfptr = (dag_record_t *)packet->buffer;
770        return erfptr->flags.iface;
771}
772
773static int8_t erf_set_direction(const struct libtrace_packet_t *packet, int8_t direction) {
774        dag_record_t *erfptr = 0;
775        erfptr = (dag_record_t *)packet->buffer;
776        erfptr->flags.iface = direction;
777        return erfptr->flags.iface;
778}
779
780static uint64_t erf_get_erf_timestamp(const struct libtrace_packet_t *packet) {
781        dag_record_t *erfptr = 0;
782        erfptr = (dag_record_t *)packet->buffer;
783        return erfptr->ts;
784}
785
786static int erf_get_capture_length(const struct libtrace_packet_t *packet) {
787        dag_record_t *erfptr = 0;
788        erfptr = (dag_record_t *)packet->buffer;
789        return ntohs(erfptr->rlen);
790}
791
792static int erf_get_wire_length(const struct libtrace_packet_t *packet) {
793        dag_record_t *erfptr = 0;
794        erfptr = (dag_record_t *)packet->buffer;
795        return ntohs(erfptr->wlen);
796}
797
798static size_t erf_set_capture_length(struct libtrace_packet_t *packet, size_t size) {
799        dag_record_t *erfptr = 0;
800        assert(packet);
801        if(size > packet->size) {
802                // can't make a packet larger
803                return packet->size;
804        }
805        erfptr = (dag_record_t *)packet->buffer;
806        erfptr->rlen = ntohs(size + sizeof(dag_record_t));
807        packet->size = size + sizeof(dag_record_t);
808        return packet->size;
809}
810
811static int rtclient_get_fd(struct libtrace_packet_t *packet) {
812        return packet->trace->format_data->input.fd;
813}
814
815static int erf_get_fd(struct libtrace_packet_t *packet) {
816        return packet->trace->format_data->input.fd;
817}
818
819#if HAVE_DAG
820static void dag_help() {
821        printf("dag format module: $Revision$\n");
822        printf("Supported input URIs:\n");
823        printf("\tdag:/dev/dagn\n");
824        printf("\n");
825        printf("\te.g.: dag:/dev/dag0\n");
826        printf("\n");
827        printf("Supported output URIs:\n");
828        printf("\tnone\n");
829        printf("\n");
830}
831#endif
832
833
834static void erf_help() {
835        printf("erf format module: $Revision$\n");
836        printf("Supported input URIs:\n");
837        printf("\terf:/path/to/file\t(uncompressed)\n");
838        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
839        printf("\terf:-\t(stdin, either compressed or not)\n");
840        printf("\terf:/path/to/socket\n");
841        printf("\n");
842        printf("\te.g.: erf:/tmp/trace\n");
843        printf("\n");
844        printf("Supported output URIs:\n");
845        printf("\terf:path/to/file\t(uncompressed)\n");
846        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
847        printf("\terf:-\t(stdout, either compressed or not)\n");
848        printf("\n");
849        printf("\te.g.: erf:/tmp/trace\n");
850        printf("\n");
851        printf("Supported output options:\n");
852        printf("\t-z\tSpecify the gzip compression, ranging from 0 (uncompressed) to 9 - defaults to 1\n");
853        printf("\n");
854
855       
856}
857
858static void rtclient_help() {
859        printf("rtclient format module\n");
860        printf("Supported input URIs:\n");
861        printf("\trtclient:hostname:port\n");
862        printf("\trtclient:hostname (connects on default port)\n");
863        printf("\n");
864        printf("\te.g.: rtclient:localhost\n");
865        printf("\te.g.: rtclient:localhost:32500\n");
866        printf("\n");
867        printf("Supported output URIs:\n");
868        printf("\trtclient: \t(will output on default port on all available IP addresses) \n");
869        printf("\trtclient:hostname:port\n");
870        printf("\trtclient:port\n");
871        printf("\n");
872        printf("\te.g.: rtclient:32500\n");
873        printf("\te.g.: rtclient:\n");
874        printf("\n");
875
876}
877
878       
879static struct libtrace_format_t erf = {
880        "erf",
881        "$Id$",
882        "erf",
883        erf_init_input,                 /* init_input */       
884        erf_init_output,                /* init_output */
885        erf_config_output,              /* config_output */
886        erf_fin_input,                  /* fin_input */
887        erf_fin_output,                 /* fin_output */
888        erf_read_packet,                /* read_packet */
889        erf_write_packet,               /* write_packet */
890        erf_get_link,                   /* get_link */
891        erf_get_link_type,              /* get_link_type */
892        erf_get_direction,              /* get_direction */
893        erf_set_direction,              /* set_direction */
894        erf_get_erf_timestamp,          /* get_erf_timestamp */
895        NULL,                           /* get_timeval */
896        NULL,                           /* get_seconds */
897        erf_get_capture_length,         /* get_capture_length */
898        erf_get_wire_length,            /* get_wire_length */
899        erf_set_capture_length,         /* set_capture_length */
900        erf_get_fd,                     /* get_fd */
901        trace_event_trace,              /* trace_event */
902        erf_help                        /* help */
903};
904
905#ifdef HAVE_DAG
906static struct libtrace_format_t dag = {
907        "dag",
908        "$Id$",
909        "erf",
910        dag_init_input,                 /* init_input */       
911        NULL,                           /* init_output */
912        NULL,                           /* config_output */
913        dag_fin_input,                  /* fin_input */
914        NULL,                           /* fin_output */
915        dag_read_packet,                /* read_packet */
916        NULL,                           /* write_packet */
917        erf_get_link,                   /* get_link */
918        erf_get_link_type,              /* get_link_type */
919        erf_get_direction,              /* get_direction */
920        erf_set_direction,              /* set_direction */
921        erf_get_erf_timestamp,          /* get_erf_timestamp */
922        NULL,                           /* get_timeval */
923        NULL,                           /* get_seconds */
924        erf_get_capture_length,         /* get_capture_length */
925        erf_get_wire_length,            /* get_wire_length */
926        erf_set_capture_length,         /* set_capture_length */
927        NULL,                           /* get_fd */
928        trace_event_trace,              /* trace_event */
929        dag_help                        /* help */
930};
931#endif
932
933static struct libtrace_format_t rtclient = {
934        "rtclient",
935        "$Id$",
936        "erf",
937        rtclient_init_input,            /* init_input */       
938        rtclient_init_output,           /* init_output */
939        rtclient_config_output,         /* config_output */
940        rtclient_fin_input,             /* fin_input */
941        rtclient_fin_output,            /* fin_output */
942        rtclient_read_packet,           /* read_packet */
943        rtclient_write_packet,          /* write_packet */
944        erf_get_link,                   /* get_link */
945        erf_get_link_type,              /* get_link_type */
946        erf_get_direction,              /* get_direction */
947        erf_set_direction,              /* set_direction */
948        erf_get_erf_timestamp,          /* get_erf_timestamp */
949        NULL,                           /* get_timeval */
950        NULL,                           /* get_seconds */
951        erf_get_capture_length,         /* get_capture_length */
952        erf_get_wire_length,            /* get_wire_length */
953        erf_set_capture_length,         /* set_capture_length */
954        rtclient_get_fd,                /* get_fd */
955        trace_event_device,             /* trace_event */
956        rtclient_help                   /* help */
957};
958
959void __attribute__((constructor)) erf_constructor() {
960        erf_ptr = &erf;
961        register_format(erf_ptr);
962#ifdef HAVE_DAG
963        dag_ptr = &dag;
964        register_format(dag_ptr);
965#endif
966        rtclient_ptr = &rtclient;
967        register_format(rtclient_ptr);
968}
Note: See TracBrowser for help on using the repository browser.