source: lib/format_erf.c @ eaa5529

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

legacy pos, atm, eth support

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