source: branches/libtrace2/lib/format_erf.c @ 580

Last change on this file since 580 was 580, checked in by spa1, 7 years ago

Changed the TYPE_80211 number - seems dag 2.5 uses a lot more types

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