source: lib/format_erf.c @ f03fc17

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

Get rid of ->sourcetype, it was never used.
Cleanup some of the wag stuff

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