source: lib/format_erf.c @ 9cecdb2

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

updated Changelog
fixed anonymous definition of packet status struct, to improve use.
updated format_erf paths to use sizeof(libtrace_packet_status_t)

  • Property mode set to 100644
File size: 29.7 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 + 
677                                        sizeof(uint32_t) + 
678                                        sizeof(libtrace_packet_status_t));
679                        continue;
680                }
681               
682                //size = ntohs(((dag_record_t *)buffer)->rlen);
683               
684                // read in the full packet
685                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
686                                                buffer, packet->size)) == 0) {
687                        tracefifo_out_reset(libtrace->fifo);
688                        read_required = 1;
689                        continue;
690                }
691
692                // got in our whole packet, so...
693                tracefifo_out_update(libtrace->fifo,packet->size);
694
695                tracefifo_ack_update(libtrace->fifo,packet->size + 
696                                sizeof(uint32_t) + 
697                                sizeof(libtrace_packet_status_t));
698
699                //packet->size = numbytes;
700                return numbytes;
701        } while(1);
702}
703
704static int erf_dump_packet(struct libtrace_out_t *libtrace, dag_record_t *erfptr, int pad, void *buffer, size_t size) {
705        int numbytes = 0;
706        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, erfptr, dag_record_size + pad)) == 0) {
707                perror("libtrace_write");
708                return -1;
709        }
710
711        if (buffer) {
712                if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, buffer, size)) == 0) {
713                        perror("libtrace_write");
714                        return -1;
715                }
716       
717                return numbytes + pad + dag_record_size;
718        }
719        return numbytes;
720}
721               
722static int erf_write_packet(struct libtrace_out_t *libtrace, const struct libtrace_packet_t *packet) {
723        int numbytes = 0;
724        dag_record_t erfhdr;
725        int pad = 0;
726        dag_record_t *dag_hdr = (dag_record_t *)packet->buffer;
727        void *payload = (void *)trace_get_link(packet);
728
729        pad = erf_get_padding(packet);
730
731        /* If we've had an rxerror, we have no payload to write - fix rlen to
732         * be the correct length */
733        if (payload == NULL) {
734                dag_hdr->rlen = htons(dag_record_size + pad);
735        } 
736       
737        if (packet->trace->format == &erf || 
738#if HAVE_DAG
739                        packet->trace->format == &dag ||
740#endif
741                        packet->trace->format == &rtclient ) {
742                numbytes = erf_dump_packet(libtrace,
743                                (dag_record_t *)packet->buffer,
744                                pad,
745                                payload,
746                                packet->size - 
747                                        (dag_record_size + pad)); 
748        } else {
749                // convert format - build up a new erf header
750                // Timestamp
751                erfhdr.ts = trace_get_erf_timestamp(packet);
752                // Flags. Can't do this
753                memset(&erfhdr.flags,1,1);
754                // Packet length (rlen includes format overhead)
755                erfhdr.rlen = trace_get_capture_length(packet) + erf_get_framing_length(packet);
756                // loss counter. Can't do this
757                erfhdr.lctr = 0;
758                // Wire length
759                erfhdr.wlen = trace_get_wire_length(packet);
760               
761                // Write it out
762                numbytes = erf_dump_packet(libtrace,
763                                &erfhdr,
764                                pad,
765                                payload,
766                                trace_get_capture_length(packet));
767        }
768        return numbytes;
769}
770
771
772static void *legacypos_get_link(const struct libtrace_packet_t *packet) {
773        const void *posptr = 0;
774        posptr = ((uint8_t *)packet->buffer +
775                        legacypos_get_framing_length(packet));
776        return (void *)posptr;
777}
778
779static libtrace_linktype_t legacypos_get_link_type(const struct libtrace_packet_t *packet) {
780        return TRACE_TYPE_LEGACY_POS;
781}
782
783static void *legacyatm_get_link(const struct libtrace_packet_t *packet) {
784        const void *atmptr = 0;
785        atmptr = ((uint8_t *)packet->buffer +
786                        legacyatm_get_framing_length(packet));
787        return (void *)atmptr;
788}
789
790static libtrace_linktype_t legacyatm_get_link_type(const struct libtrace_packet_t *packet) {
791        return TRACE_TYPE_LEGACY_ATM;
792}
793
794static void *legacyeth_get_link(const struct libtrace_packet_t *packet) {
795        const void *ethptr = 0;
796        ethptr = ((uint8_t *)packet->buffer +
797                        legacyeth_get_framing_length(packet));
798        return (void *)ethptr;
799}
800
801static libtrace_linktype_t legacyeth_get_link_type(const struct libtrace_packet_t *packet) {
802        return TRACE_TYPE_LEGACY_ETH;
803}
804
805
806
807static void *erf_get_link(const struct libtrace_packet_t *packet) {
808        const void *ethptr = 0;
809        dag_record_t *erfptr = 0;
810        erfptr = (dag_record_t *)packet->buffer;
811       
812        if (erfptr->flags.rxerror == 1) {
813                return NULL;
814        }
815        ethptr = ((uint8_t *)packet->buffer +
816                        erf_get_framing_length(packet));
817        return (void *)ethptr;
818}
819
820static libtrace_linktype_t erf_get_link_type(const struct libtrace_packet_t *packet) {
821        dag_record_t *erfptr = 0;
822        erfptr = (dag_record_t *)packet->buffer;
823        switch (erfptr->type) {
824                case TYPE_LEGACY:       return TRACE_TYPE_LEGACY;
825                case TYPE_ETH:          return TRACE_TYPE_ETH;
826                case TYPE_ATM:          return TRACE_TYPE_ATM;
827                default: 
828                               fprintf(stderr,"Unknown erf type %02x\n",erfptr->type);
829                               assert(0);
830        }
831        return erfptr->type;
832}
833
834static int8_t erf_get_direction(const struct libtrace_packet_t *packet) {
835        dag_record_t *erfptr = 0;
836        erfptr = (dag_record_t *)packet->buffer;
837        return erfptr->flags.iface;
838}
839
840static int8_t erf_set_direction(const struct libtrace_packet_t *packet, int8_t direction) {
841        dag_record_t *erfptr = 0;
842        erfptr = (dag_record_t *)packet->buffer;
843        erfptr->flags.iface = direction;
844        return erfptr->flags.iface;
845}
846
847static uint64_t erf_get_erf_timestamp(const struct libtrace_packet_t *packet) {
848        dag_record_t *erfptr = 0;
849        erfptr = (dag_record_t *)packet->buffer;
850        return erfptr->ts;
851}
852
853static int legacy_get_capture_length(const struct libtrace_packet_t *packet __attribute__((unused))) {
854        return 64;
855}
856
857static int legacypos_get_wire_length(const struct libtrace_packet_t *packet) {
858        legacy_pos_t *lpos = (legacy_pos_t *)packet->buffer;
859        return ntohs(lpos->wlen);
860}
861
862static int legacyatm_get_wire_length(const struct libtrace_packet_t *packet) {
863        return 53;
864}
865
866static int legacyeth_get_wire_length(const struct libtrace_packet_t *packet) {
867        legacy_ether_t *leth = (legacy_ether_t *)packet->buffer;
868        return ntohs(leth->wlen);
869}
870static int erf_get_capture_length(const struct libtrace_packet_t *packet) {
871        dag_record_t *erfptr = 0;
872        erfptr = (dag_record_t *)packet->buffer;
873        return (ntohs(erfptr->rlen) - erf_get_framing_length(packet));
874}
875
876static int erf_get_wire_length(const struct libtrace_packet_t *packet) {
877        dag_record_t *erfptr = 0;
878        erfptr = (dag_record_t *)packet->buffer;
879        return ntohs(erfptr->wlen);
880}
881
882static size_t erf_set_capture_length(struct libtrace_packet_t *packet, size_t size) {
883        dag_record_t *erfptr = 0;
884        assert(packet);
885        if((size + erf_get_framing_length(packet)) > packet->size) {
886                // can't make a packet larger
887                return (packet->size - erf_get_framing_length(packet));
888        }
889        erfptr = (dag_record_t *)packet->buffer;
890        erfptr->rlen = htons(size + erf_get_framing_length(packet));
891        packet->size = size + erf_get_framing_length(packet);
892        return size;
893}
894
895static int rtclient_get_fd(const struct libtrace_packet_t *packet) {
896        return packet->trace->format_data->input.fd;
897}
898
899static int erf_get_fd(const struct libtrace_packet_t *packet) {
900        return packet->trace->format_data->input.fd;
901}
902
903#if HAVE_DAG
904static void dag_help() {
905        printf("dag format module: $Revision$\n");
906        printf("Supported input URIs:\n");
907        printf("\tdag:/dev/dagn\n");
908        printf("\n");
909        printf("\te.g.: dag:/dev/dag0\n");
910        printf("\n");
911        printf("Supported output URIs:\n");
912        printf("\tnone\n");
913        printf("\n");
914}
915#endif
916
917static void legacypos_help() {
918        printf("legacypos format module: $Revision$\n");
919        printf("Supported input URIs:\n");
920        printf("\tlegacypos:/path/to/file\t(uncompressed)\n");
921        printf("\tlegacypos:/path/to/file.gz\t(gzip-compressed)\n");
922        printf("\tlegacypos:-\t(stdin, either compressed or not)\n");
923        printf("\n");
924        printf("\te.g.: legacypos:/tmp/trace.gz\n");
925        printf("\n");
926}
927
928static void legacyatm_help() {
929        printf("legacyatm format module: $Revision$\n");
930        printf("Supported input URIs:\n");
931        printf("\tlegacyatm:/path/to/file\t(uncompressed)\n");
932        printf("\tlegacyatm:/path/to/file.gz\t(gzip-compressed)\n");
933        printf("\tlegacyatm:-\t(stdin, either compressed or not)\n");
934        printf("\n");
935        printf("\te.g.: legacyatm:/tmp/trace.gz\n");
936        printf("\n");
937}
938
939static void legacyeth_help() {
940        printf("legacyeth format module: $Revision$\n");
941        printf("Supported input URIs:\n");
942        printf("\tlegacyeth:/path/to/file\t(uncompressed)\n");
943        printf("\tlegacyeth:/path/to/file.gz\t(gzip-compressed)\n");
944        printf("\tlegacyeth:-\t(stdin, either compressed or not)\n");
945        printf("\n");
946        printf("\te.g.: legacyeth:/tmp/trace.gz\n");
947        printf("\n");
948}
949
950static void erf_help() {
951        printf("erf format module: $Revision$\n");
952        printf("Supported input URIs:\n");
953        printf("\terf:/path/to/file\t(uncompressed)\n");
954        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
955        printf("\terf:-\t(stdin, either compressed or not)\n");
956        printf("\terf:/path/to/socket\n");
957        printf("\n");
958        printf("\te.g.: erf:/tmp/trace\n");
959        printf("\n");
960        printf("Supported output URIs:\n");
961        printf("\terf:path/to/file\t(uncompressed)\n");
962        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
963        printf("\terf:-\t(stdout, either compressed or not)\n");
964        printf("\n");
965        printf("\te.g.: erf:/tmp/trace\n");
966        printf("\n");
967        printf("Supported output options:\n");
968        printf("\t-z\tSpecify the gzip compression, ranging from 0 (uncompressed) to 9 - defaults to 1\n");
969        printf("\n");
970
971       
972}
973
974static void rtclient_help() {
975        printf("rtclient format module\n");
976        printf("Supported input URIs:\n");
977        printf("\trtclient:hostname:port\n");
978        printf("\trtclient:hostname (connects on default port)\n");
979        printf("\n");
980        printf("\te.g.: rtclient:localhost\n");
981        printf("\te.g.: rtclient:localhost:32500\n");
982        printf("\n");
983        printf("Supported output URIs:\n");
984        printf("\trtclient: \t(will output on default port on all available IP addresses) \n");
985        printf("\trtclient:hostname:port\n");
986        printf("\trtclient:port\n");
987        printf("\n");
988        printf("\te.g.: rtclient:32500\n");
989        printf("\te.g.: rtclient:\n");
990        printf("\n");
991
992}
993
994static struct libtrace_format_t legacyatm = {
995        "legacyatm",
996        "$Id$",
997        "legacyatm",
998        erf_init_input,                 /* init_input */       
999        NULL,                           /* init_output */
1000        NULL,                           /* config_output */
1001        erf_fin_input,                  /* fin_input */
1002        NULL,                           /* fin_output */
1003        legacy_read_packet,             /* read_packet */
1004        NULL,                           /* write_packet */
1005        legacyatm_get_link,             /* get_link */
1006        legacyatm_get_link_type,        /* get_link_type */
1007        NULL,                           /* get_direction */
1008        NULL,                           /* set_direction */
1009        erf_get_erf_timestamp,          /* get_erf_timestamp */
1010        NULL,                           /* get_timeval */
1011        NULL,                           /* get_seconds */
1012        legacy_get_capture_length,      /* get_capture_length */
1013        legacyatm_get_wire_length,      /* get_wire_length */
1014        legacyatm_get_framing_length,   /* get_framing_length */
1015        NULL,                           /* set_capture_length */
1016        NULL,                           /* get_fd */
1017        trace_event_trace,              /* trace_event */
1018        legacyatm_help                  /* help */
1019};
1020
1021static struct libtrace_format_t legacyeth = {
1022        "legacyeth",
1023        "$Id$",
1024        "legacyeth",
1025        erf_init_input,                 /* init_input */       
1026        NULL,                           /* init_output */
1027        NULL,                           /* config_output */
1028        erf_fin_input,                  /* fin_input */
1029        NULL,                           /* fin_output */
1030        legacy_read_packet,             /* read_packet */
1031        NULL,                           /* write_packet */
1032        legacyeth_get_link,             /* get_link */
1033        legacyeth_get_link_type,        /* get_link_type */
1034        NULL,                           /* get_direction */
1035        NULL,                           /* set_direction */
1036        erf_get_erf_timestamp,          /* get_erf_timestamp */
1037        NULL,                           /* get_timeval */
1038        NULL,                           /* get_seconds */
1039        legacy_get_capture_length,      /* get_capture_length */
1040        legacyeth_get_wire_length,      /* get_wire_length */
1041        legacyeth_get_framing_length,   /* get_framing_length */
1042        NULL,                           /* set_capture_length */
1043        NULL,                           /* get_fd */
1044        trace_event_trace,              /* trace_event */
1045        legacyeth_help                  /* help */
1046};
1047
1048static struct libtrace_format_t legacypos = {
1049        "legacypos",
1050        "$Id$",
1051        "legacypos",
1052        erf_init_input,                 /* init_input */       
1053        NULL,                           /* init_output */
1054        NULL,                           /* config_output */
1055        erf_fin_input,                  /* fin_input */
1056        NULL,                           /* fin_output */
1057        legacy_read_packet,             /* read_packet */
1058        NULL,                           /* write_packet */
1059        legacypos_get_link,             /* get_link */
1060        legacypos_get_link_type,        /* get_link_type */
1061        NULL,                           /* get_direction */
1062        NULL,                           /* set_direction */
1063        erf_get_erf_timestamp,          /* get_erf_timestamp */
1064        NULL,                           /* get_timeval */
1065        NULL,                           /* get_seconds */
1066        legacy_get_capture_length,      /* get_capture_length */
1067        legacypos_get_wire_length,      /* get_wire_length */
1068        legacypos_get_framing_length,   /* get_framing_length */
1069        NULL,                           /* set_capture_length */
1070        NULL,                           /* get_fd */
1071        trace_event_trace,              /* trace_event */
1072        legacypos_help                  /* help */
1073};
1074
1075       
1076static struct libtrace_format_t erf = {
1077        "erf",
1078        "$Id$",
1079        "erf",
1080        erf_init_input,                 /* init_input */       
1081        erf_init_output,                /* init_output */
1082        erf_config_output,              /* config_output */
1083        erf_fin_input,                  /* fin_input */
1084        erf_fin_output,                 /* fin_output */
1085        erf_read_packet,                /* read_packet */
1086        erf_write_packet,               /* write_packet */
1087        erf_get_link,                   /* get_link */
1088        erf_get_link_type,              /* get_link_type */
1089        erf_get_direction,              /* get_direction */
1090        erf_set_direction,              /* set_direction */
1091        erf_get_erf_timestamp,          /* get_erf_timestamp */
1092        NULL,                           /* get_timeval */
1093        NULL,                           /* get_seconds */
1094        erf_get_capture_length,         /* get_capture_length */
1095        erf_get_wire_length,            /* get_wire_length */
1096        erf_get_framing_length,         /* get_framing_length */
1097        erf_set_capture_length,         /* set_capture_length */
1098        erf_get_fd,                     /* get_fd */
1099        trace_event_trace,              /* trace_event */
1100        erf_help                        /* help */
1101};
1102
1103#ifdef HAVE_DAG
1104static struct libtrace_format_t dag = {
1105        "dag",
1106        "$Id$",
1107        "erf",
1108        dag_init_input,                 /* init_input */       
1109        NULL,                           /* init_output */
1110        NULL,                           /* config_output */
1111        dag_fin_input,                  /* fin_input */
1112        NULL,                           /* fin_output */
1113        dag_read_packet,                /* read_packet */
1114        NULL,                           /* write_packet */
1115        erf_get_link,                   /* get_link */
1116        erf_get_link_type,              /* get_link_type */
1117        erf_get_direction,              /* get_direction */
1118        erf_set_direction,              /* set_direction */
1119        erf_get_erf_timestamp,          /* get_erf_timestamp */
1120        NULL,                           /* get_timeval */
1121        NULL,                           /* get_seconds */
1122        erf_get_capture_length,         /* get_capture_length */
1123        erf_get_wire_length,            /* get_wire_length */
1124        erf_get_framing_length,         /* get_framing_length */
1125        erf_set_capture_length,         /* set_capture_length */
1126        NULL,                           /* get_fd */
1127        trace_event_trace,              /* trace_event */
1128        dag_help                        /* help */
1129};
1130#endif
1131
1132static struct libtrace_format_t rtclient = {
1133        "rtclient",
1134        "$Id$",
1135        "erf",
1136        rtclient_init_input,            /* init_input */       
1137        NULL,                           /* init_output */
1138        NULL,                           /* config_output */
1139        rtclient_fin_input,             /* fin_input */
1140        NULL,                           /* fin_output */
1141        rtclient_read_packet,           /* read_packet */
1142        NULL,                           /* write_packet */
1143        erf_get_link,                   /* get_link */
1144        erf_get_link_type,              /* get_link_type */
1145        erf_get_direction,              /* get_direction */
1146        erf_set_direction,              /* set_direction */
1147        erf_get_erf_timestamp,          /* get_erf_timestamp */
1148        NULL,                           /* get_timeval */
1149        NULL,                           /* get_seconds */
1150        erf_get_capture_length,         /* get_capture_length */
1151        erf_get_wire_length,            /* get_wire_length */
1152        erf_get_framing_length,         /* get_framing_length */
1153        erf_set_capture_length,         /* set_capture_length */
1154        rtclient_get_fd,                /* get_fd */
1155        trace_event_device,             /* trace_event */
1156        rtclient_help                   /* help */
1157};
1158
1159void __attribute__((constructor)) erf_constructor() {
1160        register_format(&erf);
1161#ifdef HAVE_DAG
1162        register_format(&dag);
1163#endif
1164        register_format(&rtclient);
1165        register_format(&legacypos);
1166        register_format(&legacyeth);
1167        register_format(&legacyatm);
1168}
Note: See TracBrowser for help on using the repository browser.