source: lib/format_erf.c @ 1fbd938

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

More -pedantic cleanups
Changed the format structure (again) for pause and seek support

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