source: lib/format_erf.c @ 880aa58

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

Added libtrace_set_err() to everything (except format_rt, that's shane's job)

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