source: lib/format_erf.c @ 37195b4

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 37195b4 was 37195b4, checked in by Perry Lorier <perry@…>, 16 years ago

Split out legacy from erf
Added config_input, start_input, and start_output hooks for formats

  • Property mode set to 100644
File size: 23.8 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
78
79#define CONNINFO libtrace->format_data->conn_info
80#define INPUT libtrace->format_data->input
81#define OUTPUT libtrace->format_data->output
82#if HAVE_DAG
83#define DAG libtrace->format_data->dag
84#endif
85#define OPTIONS libtrace->format_data->options
86struct libtrace_format_data_t {
87        union {
88                struct {
89                        char *hostname;
90                        short port;
91                } rt;
92                char *path;             
93        } conn_info;
94       
95        union {
96                int fd;
97#if HAVE_ZLIB
98                gzFile *file;
99#else   
100                //FILE  *file;
101                int file;
102#endif
103        } input;
104
105#if HAVE_DAG
106        struct {
107                void *buf; 
108                unsigned bottom;
109                unsigned top;
110                unsigned diff;
111                unsigned curr;
112                unsigned offset;
113        } dag;
114#endif
115};
116
117struct libtrace_format_data_out_t {
118        union {
119                struct {
120                        char *hostname;
121                        short port;
122                } rt;
123                char *path;
124        } conn_info;
125
126
127
128        union {
129                struct {
130                        int level;
131                        int append;
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
202
203static int erf_init_input(struct libtrace_t *libtrace) {
204        struct stat buf;
205        struct sockaddr_un unix_sock;
206        libtrace->format_data = (struct libtrace_format_data_t *)
207                malloc(sizeof(struct libtrace_format_data_t));
208
209        CONNINFO.path = libtrace->uridata;
210        if (!strncmp(CONNINFO.path,"-",1)) {
211                // STDIN
212                libtrace->sourcetype = STDIN;
213                INPUT.file = LIBTRACE_FDOPEN(fileno(stdin), "r");
214               
215
216        } else {
217                if (stat(CONNINFO.path,&buf) == -1 ) {
218                        perror("stat");
219                        return 0;
220                }
221                if (S_ISSOCK(buf.st_mode)) {
222                        libtrace->sourcetype = SOCKET;
223                        if ((INPUT.fd = socket(
224                                        AF_UNIX, SOCK_STREAM, 0)) == -1) {
225                                perror("socket");
226                                return 0;
227                        }
228                        unix_sock.sun_family = AF_UNIX;
229                        bzero(unix_sock.sun_path,108);
230                        snprintf(unix_sock.sun_path,
231                                        108,"%s"
232                                        ,CONNINFO.path);
233
234                        if (connect(INPUT.fd, 
235                                        (struct sockaddr *)&unix_sock,
236                                        sizeof(struct sockaddr)) == -1) {
237                                perror("connect (unix)");
238                                return 0;
239                        }
240                } else { 
241
242                        libtrace->sourcetype = TRACE;
243
244                        // we use an FDOPEN call to reopen an FD
245                        // returned from open(), so that we can set
246                        // O_LARGEFILE. This gets around gzopen not
247                        // letting you do this...
248                        INPUT.file = LIBTRACE_FDOPEN(open(
249                                                CONNINFO.path,
250                                                O_LARGEFILE),"r");
251                }
252        }
253        return 1;
254}
255
256static int rtclient_init_input(struct libtrace_t *libtrace) {
257        char *scan;
258        char *uridata = libtrace->uridata;
259        struct hostent *he;
260        struct sockaddr_in remote;
261        libtrace->format_data = (struct libtrace_format_data_t *)
262                malloc(sizeof(struct libtrace_format_data_t));
263
264        libtrace->sourcetype = RT;
265
266        if (strlen(uridata) == 0) {
267                CONNINFO.rt.hostname = 
268                        strdup("localhost");
269                CONNINFO.rt.port = 
270                        COLLECTOR_PORT;
271        } else {
272                if ((scan = strchr(uridata,':')) == NULL) {
273                        CONNINFO.rt.hostname = 
274                                strdup(uridata);
275                        CONNINFO.rt.port =
276                                COLLECTOR_PORT;
277                } else {
278                        CONNINFO.rt.hostname = 
279                                (char *)strndup(uridata,
280                                                (scan - uridata));
281                        CONNINFO.rt.port = 
282                                atoi(++scan);
283                }
284        }
285       
286        if ((he=gethostbyname(CONNINFO.rt.hostname)) == NULL) { 
287                perror("gethostbyname");
288                return 0;
289        } 
290        if ((INPUT.fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
291                perror("socket");
292                return 0;
293        }
294
295        remote.sin_family = AF_INET;   
296        remote.sin_port = htons(CONNINFO.rt.port);
297        remote.sin_addr = *((struct in_addr *)he->h_addr);
298        bzero(&(remote.sin_zero), 8);
299
300        if (connect(INPUT.fd, (struct sockaddr *)&remote,
301                                sizeof(struct sockaddr)) == -1) {
302                perror("connect (inet)");
303                return 0;
304        }
305        return 1;
306}
307
308static int erf_init_output(struct libtrace_out_t *libtrace) {
309        int fd;
310        libtrace->format_data = (struct libtrace_format_data_out_t *)
311                calloc(1,sizeof(struct libtrace_format_data_out_t));
312
313        OPTIONS.erf.level = 0;
314        OPTIONS.erf.append = 0;
315        OUTPUT.file = 0;
316
317        return 1;
318}
319
320static int erf_open_output(struct libtrace_out_t *libtrace) {
321        char *filemode;
322        int trunc_flag = O_TRUNC;
323        int fd;
324
325#if HAVE_ZLIB
326        asprintf(&filemode,"wb%d",OPTIONS.erf.level);
327#else
328        asprintf(&filemode,"w");
329#endif
330
331        if (OPTIONS.erf.append) {
332                trunc_flag = O_APPEND;
333        }               
334
335        if (!strncmp(libtrace->uridata,"-",1)) {
336                // STDOUT
337                OUTPUT.file = LIBTRACE_FDOPEN(fileno(stdout),filemode);
338        }
339        else {
340                // TRACE
341                fd = open(libtrace->uridata, O_CREAT | O_LARGEFILE | O_WRONLY | trunc_flag, 
342                                S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
343                if (fd <= 0) {
344                        return 0;
345                }
346                OUTPUT.file = LIBTRACE_FDOPEN(fd,filemode);
347
348        }
349        free(filemode);
350        return 1;
351}
352
353static int erf_config_output(struct libtrace_out_t *libtrace, int argc, char *argv[]) {
354        int opt;
355        int level = OPTIONS.erf.level;
356        optind = 1;
357
358
359        while ((opt = getopt(argc, argv, "z:a")) != EOF) {
360                switch (opt) {
361                        case 'z':
362                                level = atoi(optarg);
363                                break;
364                        case 'a':
365                                OPTIONS.erf.append = 1;
366                                break;
367                        default:
368                                printf("Bad argument to erf: %s\n", optarg);
369                                // maybe spit out some help here
370                                return -1;
371                }
372        }
373       
374        return 0;
375
376}
377
378
379#ifdef HAVE_DAG
380static int dag_fin_input(struct libtrace_t *libtrace) {
381        dag_stop(INPUT.fd);
382}
383#endif
384
385static int erf_fin_input(struct libtrace_t *libtrace) {
386        LIBTRACE_CLOSE(INPUT.file);
387        free(libtrace->format_data);
388        return 0;
389}
390
391static int rtclient_fin_input(struct libtrace_t *libtrace) {
392        close(INPUT.fd);
393        return 0;
394}
395
396static int erf_fin_output(struct libtrace_out_t *libtrace) {
397        LIBTRACE_CLOSE(OUTPUT.file);
398        free(libtrace->format_data);
399
400        return 0;
401}
402 
403#if HAVE_DAG
404static int dag_read(struct libtrace_t *libtrace, int block_flag) {
405        int numbytes;
406        static short lctr = 0;
407        struct dag_record_t *erfptr = 0;
408        int rlen;
409
410        if (DAG.diff != 0) 
411                return DAG.diff;
412
413        DAG.bottom = DAG.top;
414        DAG.top = dag_offset(
415                        INPUT.fd,
416                        &(DAG.bottom),
417                        block_flag);
418        DAG.diff = DAG.top -
419                DAG.bottom;
420
421        numbytes=DAG.diff;
422        DAG.offset = 0;
423        return numbytes;
424}
425#endif
426
427#if HAVE_DAG
428static int dag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
429        int numbytes;
430        int size;
431        dag_record_t *erfptr;
432        void *buffer = packet->buffer;
433        void *buffer2 = buffer;
434        int rlen;
435
436        if (packet->buf_control == PACKET) {
437                packet->buf_control = EXTERNAL;
438                free(packet->buffer);
439                packet->buffer = 0;
440        }
441   
442        if ((numbytes = dag_read(libtrace,0)) <= 0) 
443                return numbytes;
444
445        //DAG always gives us whole packets
446        erfptr = (dag_record_t *) ((void *)DAG.buf + 
447                        (DAG.bottom + DAG.offset));
448        size = ntohs(erfptr->rlen);
449
450        if ( size  > LIBTRACE_PACKET_BUFSIZE) {
451                assert( size < LIBTRACE_PACKET_BUFSIZE);
452        }
453       
454        packet->buffer = erfptr;
455        packet->header = erfptr;
456        if (((dag_record_t *)buffer)->flags.rxerror == 1) {
457                packet->payload = NULL;
458        } else {
459                packet->payload = packet->buffer + erf_get_framing_length(packet);
460        }
461
462       
463        packet->status.type = RT_DATA;
464        packet->status.message = 0;
465        packet->size = size;
466        DAG.offset += size;
467        DAG.diff -= size;
468
469        assert(DAG.diff >= 0);
470
471        return (size);
472}
473#endif
474
475static int erf_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
476        int numbytes;
477        int size;
478        void *buffer = packet->buffer;
479        void *buffer2 = buffer;
480        int rlen;
481        if (packet->buf_control == EXTERNAL) {
482                packet->buf_control = PACKET;
483                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
484        }
485        buffer = packet->buffer;
486        packet->header = packet->buffer;
487
488
489        if ((numbytes=LIBTRACE_READ(INPUT.file,
490                                        buffer,
491                                        dag_record_size)) == -1) {
492                perror("libtrace_read");
493                return -1;
494        }
495        if (numbytes == 0) {
496                return 0;
497        }
498
499        rlen = ntohs(((dag_record_t *)buffer)->rlen);
500        buffer2 = buffer + dag_record_size;
501        size = rlen - dag_record_size;
502        assert(size < LIBTRACE_PACKET_BUFSIZE);
503       
504        /* If your trace is legacy, or corrupt, then this assert may fire. */
505        /* turns out some older traces have fixed snaplens, which are padded
506         * with 00's if the packet is smaller, so this doesn't work.  Sigh.
507        assert(ntohs(((dag_record_t *)buffer)->rlen) <=
508                        ntohs(((dag_record_t*)buffer)->wlen)+erf_get_framing_length(packet));
509        */
510        /* Unknown/corrupt */
511        assert(((dag_record_t *)buffer)->type < 10);
512       
513        // read in the rest of the packet
514        if ((numbytes=LIBTRACE_READ(INPUT.file,
515                                        buffer2,
516                                        size)) != size) {
517                perror("libtrace_read");
518                return -1;
519        }
520        packet->status.type = RT_DATA;
521        packet->status.message = 0;
522        packet->size = rlen;
523        if (((dag_record_t *)buffer)->flags.rxerror == 1) {
524                packet->payload = NULL;
525        } else {
526                packet->payload = packet->buffer + erf_get_framing_length(packet);
527        }
528        return rlen;
529}
530
531static int rtclient_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
532        int numbytes;
533
534        if (buffer == 0)
535                buffer = malloc(len);
536        while(1) {
537#ifndef MSG_NOSIGNAL
538#  define MSG_NOSIGNAL 0
539#endif
540                if ((numbytes = recv(INPUT.fd,
541                                                buffer,
542                                                len,
543                                                MSG_NOSIGNAL)) == -1) {
544                        if (errno == EINTR) {
545                                //ignore EINTR in case
546                                // a caller is using signals
547                                continue;
548                        }
549                        perror("recv");
550                        return -1;
551                }
552                break;
553
554        }
555        return numbytes;
556}
557
558static int rtclient_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
559        int numbytes = 0;
560        char buf[RP_BUFSIZE];
561        int read_required = 0;
562       
563        void *buffer = 0;
564
565        packet->trace = libtrace;
566
567        if (packet->buf_control == EXTERNAL) {
568                packet->buf_control = PACKET;
569                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
570        }
571
572        buffer = packet->buffer;
573        packet->header = packet->buffer;
574
575       
576        do {
577                if (tracefifo_out_available(libtrace->fifo) == 0 || read_required) {
578                        if ((numbytes = rtclient_read(
579                                        libtrace,buf,RP_BUFSIZE))<=0) {
580                                return numbytes;
581                        }
582                        tracefifo_write(libtrace->fifo,buf,numbytes);
583                        read_required = 0;
584                }
585                // Read status byte
586                if (tracefifo_out_read(libtrace->fifo,
587                                &packet->status, sizeof(uint32_t)) == 0) {
588                        read_required = 1;
589                        continue;
590                }
591                tracefifo_out_update(libtrace->fifo,sizeof(uint32_t));
592                // Read in packet size
593                if (tracefifo_out_read(libtrace->fifo,
594                                &packet->size, sizeof(uint32_t)) == 0) {
595                        tracefifo_out_reset(libtrace->fifo);
596                        read_required = 1;
597                        continue;
598                }
599                tracefifo_out_update(libtrace->fifo, sizeof(uint32_t));
600               
601                /*
602                // read in the ERF header
603                if ((numbytes = tracefifo_out_read(libtrace->fifo, buffer,
604                                                dag_record_size)) == 0) {
605                        tracefifo_out_reset(libtrace->fifo);
606                        read_required = 1;
607                        continue;
608                }
609                */
610                if (packet->status.type == RT_MSG) {
611                        // Need to skip this packet as it is a message packet
612                        tracefifo_out_update(libtrace->fifo, packet->size);
613                        tracefifo_ack_update(libtrace->fifo, packet->size + 
614                                        sizeof(uint32_t) + 
615                                        sizeof(libtrace_packet_status_t));
616                        continue;
617                }
618               
619                //size = ntohs(((dag_record_t *)buffer)->rlen);
620               
621                // read in the full packet
622                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
623                                                buffer, packet->size)) == 0) {
624                        tracefifo_out_reset(libtrace->fifo);
625                        read_required = 1;
626                        continue;
627                }
628
629                // got in our whole packet, so...
630                tracefifo_out_update(libtrace->fifo,packet->size);
631
632                tracefifo_ack_update(libtrace->fifo,packet->size + 
633                                sizeof(uint32_t) + 
634                                sizeof(libtrace_packet_status_t));
635
636                //packet->size = numbytes;
637                if (((dag_record_t *)buffer)->flags.rxerror == 1) {
638                        packet->payload = NULL;
639                } else {
640                        packet->payload = packet->buffer + erf_get_framing_length(packet);
641                }
642                return numbytes;
643        } while(1);
644}
645
646static int erf_dump_packet(struct libtrace_out_t *libtrace, dag_record_t *erfptr, int pad, void *buffer, size_t size) {
647        int numbytes = 0;
648        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, erfptr, dag_record_size + pad)) == 0) {
649                perror("libtrace_write");
650                return -1;
651        }
652
653        if (buffer) {
654                if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, buffer, size)) == 0) {
655                        perror("libtrace_write");
656                        return -1;
657                }
658       
659                return numbytes + pad + dag_record_size;
660        }
661        return numbytes;
662}
663               
664static int erf_write_packet(struct libtrace_out_t *libtrace, const struct libtrace_packet_t *packet) {
665        int numbytes = 0;
666        dag_record_t erfhdr;
667        int pad = 0;
668        dag_record_t *dag_hdr = (dag_record_t *)packet->header;
669        void *payload = packet->payload;
670
671        /* Because of configuration, we don't actually open the output file
672           until we get the first packet. Not ideal, but it'll do for now */
673        if (!OUTPUT.file) {
674                if (erf_open_output(libtrace) <= 0) { 
675                        perror("erf_open_output");
676                        return -1;
677                }
678        }
679
680        pad = erf_get_padding(packet);
681
682        /* If we've had an rxerror, we have no payload to write - fix rlen to
683         * be the correct length */
684        if (payload == NULL) {
685                dag_hdr->rlen = htons(dag_record_size + pad);
686        } 
687       
688        if (packet->trace->format == &erf || 
689#if HAVE_DAG
690                        packet->trace->format == &dag ||
691#endif
692                        packet->trace->format == &rtclient ) {
693                numbytes = erf_dump_packet(libtrace,
694                                (dag_record_t *)packet->buffer,
695                                pad,
696                                payload,
697                                packet->size - 
698                                        (dag_record_size + pad)); 
699        } else {
700                // convert format - build up a new erf header
701                // Timestamp
702                erfhdr.ts = trace_get_erf_timestamp(packet);
703                // Flags. Can't do this
704                memset(&erfhdr.flags,1,1);
705                // Packet length (rlen includes format overhead)
706                erfhdr.rlen = trace_get_capture_length(packet) + erf_get_framing_length(packet);
707                // loss counter. Can't do this
708                erfhdr.lctr = 0;
709                // Wire length
710                erfhdr.wlen = trace_get_wire_length(packet);
711               
712                // Write it out
713                numbytes = erf_dump_packet(libtrace,
714                                &erfhdr,
715                                pad,
716                                payload,
717                                trace_get_capture_length(packet));
718        }
719        return numbytes;
720}
721
722static void *erf_get_link(const struct libtrace_packet_t *packet) {
723        return (void *)packet->payload;
724}
725
726static libtrace_linktype_t erf_get_link_type(const struct libtrace_packet_t *packet) {
727        dag_record_t *erfptr = 0;
728        erfptr = (dag_record_t *)packet->header;
729        switch (erfptr->type) {
730                case TYPE_LEGACY:       return TRACE_TYPE_LEGACY;
731                case TYPE_ETH:          return TRACE_TYPE_ETH;
732                case TYPE_ATM:          return TRACE_TYPE_ATM;
733                default: 
734                               fprintf(stderr,"Unknown erf type %02x\n",erfptr->type);
735                               assert(0);
736        }
737        return erfptr->type;
738}
739
740static int8_t erf_get_direction(const struct libtrace_packet_t *packet) {
741        dag_record_t *erfptr = 0;
742        erfptr = (dag_record_t *)packet->header;
743        return erfptr->flags.iface;
744}
745
746static int8_t erf_set_direction(const struct libtrace_packet_t *packet, int8_t direction) {
747        dag_record_t *erfptr = 0;
748        erfptr = (dag_record_t *)packet->header;
749        erfptr->flags.iface = direction;
750        return erfptr->flags.iface;
751}
752
753static uint64_t erf_get_erf_timestamp(const struct libtrace_packet_t *packet) {
754        dag_record_t *erfptr = 0;
755        erfptr = (dag_record_t *)packet->header;
756        return erfptr->ts;
757}
758
759static int erf_get_capture_length(const struct libtrace_packet_t *packet) {
760        dag_record_t *erfptr = 0;
761        erfptr = (dag_record_t *)packet->header;
762        return (ntohs(erfptr->rlen) - erf_get_framing_length(packet));
763}
764
765static int erf_get_wire_length(const struct libtrace_packet_t *packet) {
766        dag_record_t *erfptr = 0;
767        erfptr = (dag_record_t *)packet->header;
768        return ntohs(erfptr->wlen);
769}
770
771static size_t erf_set_capture_length(struct libtrace_packet_t *packet, size_t size) {
772        dag_record_t *erfptr = 0;
773        assert(packet);
774        if((size + erf_get_framing_length(packet)) > packet->size) {
775                // can't make a packet larger
776                return (packet->size - erf_get_framing_length(packet));
777        }
778        erfptr = (dag_record_t *)packet->header;
779        erfptr->rlen = htons(size + erf_get_framing_length(packet));
780        packet->size = size + erf_get_framing_length(packet);
781        return packet->size;
782}
783
784static int rtclient_get_fd(const struct libtrace_packet_t *packet) {
785        return packet->trace->format_data->input.fd;
786}
787
788static int erf_get_fd(const struct libtrace_packet_t *packet) {
789        return packet->trace->format_data->input.fd;
790}
791
792#ifdef HAVE_DAG
793struct libtrace_eventobj_t trace_event_dag(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
794        struct libtrace_eventobj_t event = {0,0,0.0,0};
795        int dag_fd;
796        int data;
797
798        if (packet->trace->format->get_fd) {
799                dag_fd = packet->trace->format->get_fd(packet);
800        } else {
801                dag_fd = 0;
802        }
803       
804        data = dag_read(trace, DAGF_NONBLOCK);
805
806        if (data > 0) {
807                event.size = trace_read_packet(trace,packet);
808                event.type = TRACE_EVENT_PACKET;
809                return event;
810        }
811        event.type = TRACE_EVENT_SLEEP;
812        event.seconds = 0.0001;
813        return event;
814}
815#endif
816
817#if HAVE_DAG
818static void dag_help() {
819        printf("dag format module: $Revision$\n");
820        printf("Supported input URIs:\n");
821        printf("\tdag:/dev/dagn\n");
822        printf("\n");
823        printf("\te.g.: dag:/dev/dag0\n");
824        printf("\n");
825        printf("Supported output URIs:\n");
826        printf("\tnone\n");
827        printf("\n");
828}
829#endif
830
831static void erf_help() {
832        printf("erf format module: $Revision$\n");
833        printf("Supported input URIs:\n");
834        printf("\terf:/path/to/file\t(uncompressed)\n");
835        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
836        printf("\terf:-\t(stdin, either compressed or not)\n");
837        printf("\terf:/path/to/socket\n");
838        printf("\n");
839        printf("\te.g.: erf:/tmp/trace\n");
840        printf("\n");
841        printf("Supported output URIs:\n");
842        printf("\terf:path/to/file\t(uncompressed)\n");
843        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
844        printf("\terf:-\t(stdout, either compressed or not)\n");
845        printf("\n");
846        printf("\te.g.: erf:/tmp/trace\n");
847        printf("\n");
848        printf("Supported output options:\n");
849        printf("\t-z\tSpecify the gzip compression, ranging from 0 (uncompressed) to 9 - defaults to 1\n");
850        printf("\n");
851
852       
853}
854
855static void rtclient_help() {
856        printf("rtclient format module\n");
857        printf("Supported input URIs:\n");
858        printf("\trtclient:hostname:port\n");
859        printf("\trtclient:hostname (connects on default port)\n");
860        printf("\n");
861        printf("\te.g.: rtclient:localhost\n");
862        printf("\te.g.: rtclient:localhost:32500\n");
863        printf("\n");
864        printf("Supported output URIs:\n");
865        printf("\trtclient: \t(will output on default port on all available IP addresses) \n");
866        printf("\trtclient:hostname:port\n");
867        printf("\trtclient:port\n");
868        printf("\n");
869        printf("\te.g.: rtclient:32500\n");
870        printf("\te.g.: rtclient:\n");
871        printf("\n");
872
873}
874
875static struct libtrace_format_t erf = {
876        "erf",
877        "$Id$",
878        "erf",
879        erf_init_input,                 /* init_input */       
880        NULL,                           /* config_input */
881        NULL,                           /* start_input */
882        erf_init_output,                /* init_output */
883        erf_config_output,              /* config_output */
884        NULL,                           /* start_output */
885        erf_fin_input,                  /* fin_input */
886        erf_fin_output,                 /* fin_output */
887        erf_read_packet,                /* read_packet */
888        erf_write_packet,               /* write_packet */
889        erf_get_link_type,              /* get_link_type */
890        erf_get_direction,              /* get_direction */
891        erf_set_direction,              /* set_direction */
892        erf_get_erf_timestamp,          /* get_erf_timestamp */
893        NULL,                           /* get_timeval */
894        NULL,                           /* get_seconds */
895        erf_get_capture_length,         /* get_capture_length */
896        erf_get_wire_length,            /* get_wire_length */
897        erf_get_framing_length,         /* get_framing_length */
898        erf_set_capture_length,         /* set_capture_length */
899        erf_get_fd,                     /* get_fd */
900        trace_event_trace,              /* trace_event */
901        erf_help                        /* help */
902};
903
904#ifdef HAVE_DAG
905static struct libtrace_format_t dag = {
906        "dag",
907        "$Id$",
908        "erf",
909        dag_init_input,                 /* init_input */       
910        NULL,                           /* config_input */
911        NULL,                           /* start_output */
912        NULL,                           /* init_output */
913        NULL,                           /* config_output */
914        NULL,                           /* start_output */
915        dag_fin_input,                  /* fin_input */
916        NULL,                           /* fin_output */
917        dag_read_packet,                /* read_packet */
918        NULL,                           /* write_packet */
919        erf_get_link_type,              /* get_link_type */
920        erf_get_direction,              /* get_direction */
921        erf_set_direction,              /* set_direction */
922        erf_get_erf_timestamp,          /* get_erf_timestamp */
923        NULL,                           /* get_timeval */
924        NULL,                           /* get_seconds */
925        erf_get_capture_length,         /* get_capture_length */
926        erf_get_wire_length,            /* get_wire_length */
927        erf_get_framing_length,         /* get_framing_length */
928        erf_set_capture_length,         /* set_capture_length */
929        NULL,                           /* get_fd */
930        trace_event_dag,                /* trace_event */
931        dag_help                        /* help */
932};
933#endif
934
935static struct libtrace_format_t rtclient = {
936        "rtclient",
937        "$Id$",
938        "erf",
939        rtclient_init_input,            /* init_input */       
940        NULL,                           /* config_input */
941        NULL,                           /* start_input */
942        NULL,                           /* init_output */
943        NULL,                           /* config_output */
944        NULL,                           /* start_output */
945        rtclient_fin_input,             /* fin_input */
946        NULL,                           /* fin_output */
947        rtclient_read_packet,           /* read_packet */
948        NULL,                           /* write_packet */
949        erf_get_link_type,              /* get_link_type */
950        erf_get_direction,              /* get_direction */
951        erf_set_direction,              /* set_direction */
952        erf_get_erf_timestamp,          /* get_erf_timestamp */
953        NULL,                           /* get_timeval */
954        NULL,                           /* get_seconds */
955        erf_get_capture_length,         /* get_capture_length */
956        erf_get_wire_length,            /* get_wire_length */
957        erf_get_framing_length,         /* get_framing_length */
958        erf_set_capture_length,         /* set_capture_length */
959        rtclient_get_fd,                /* get_fd */
960        trace_event_device,             /* trace_event */
961        rtclient_help                   /* help */
962};
963
964void __attribute__((constructor)) erf_constructor() {
965        register_format(&erf);
966#ifdef HAVE_DAG
967        register_format(&dag);
968#endif
969}
Note: See TracBrowser for help on using the repository browser.