source: lib/format_erf.c @ 44c6c85

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

Replaced all instances of sizeof(rt_status_t) with sizeof(uint32_t)

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