source: lib/format_erf.c @ 08f7fca

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

Erf output files now have group read and write access upon creation

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