source: lib/format_erf.c @ f3ed52a

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

working with trace_event on pcapint
changed some decls inside the format_*.c functions - s/extern/static/

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