source: lib/format_erf.c @ 14d8a63

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

update to version 3.0.0
zero-copy patch - trace.c updated with new trace_create_packet() etc
format_*.c updated with zero-copy codepath

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