source: lib/format_erf.c @ f66a4933

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

moved LIBTRACE_READ etc defines into common.h

if we don't have zlib, use read,open etc. We were using fread,fopen, but these take different parameters, and i couldn't make them work nicely.

stdin doesn't seem to work for non-zlib paths however

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