source: lib/format_erf.c @ 4aa4615

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

Don't be so verbose about little warnings by default
Fix some bugs in format_erf
Be more verbose about errors

  • Property mode set to 100644
File size: 24.8 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30#define _GNU_SOURCE
31
32#include "config.h"
33#include "common.h"
34#include "libtrace.h"
35#include "libtrace_int.h"
36#include "format_helper.h"
37#include "parse_cmd.h"
38
39#ifdef HAVE_INTTYPES_H
40#  include <inttypes.h>
41#else
42#  error "Can't find inttypes.h - this needs to be fixed"
43#endif
44
45#ifdef HAVE_STDDEF_H
46#  include <stddef.h>
47#else
48# error "Can't find stddef.h - do you define ptrdiff_t elsewhere?"
49#endif
50#include <sys/types.h>
51#include <sys/socket.h>
52#include <sys/un.h>
53#include <sys/mman.h>
54#include <sys/stat.h>
55#include <unistd.h>
56#include <assert.h>
57#include <errno.h>
58#include <netdb.h>
59#include <fcntl.h>
60#include <getopt.h>
61#include <stdio.h>
62#include <string.h>
63#include <stdlib.h>
64
65
66#define COLLECTOR_PORT 3435
67
68static struct libtrace_format_t erf;
69static struct libtrace_format_t rtclient;
70#if HAVE_DAG
71static struct libtrace_format_t dag;
72#endif
73
74#define DATA(x) ((struct erf_format_data_t *)x->format_data)
75#define DATAOUT(x) ((struct erf_format_data_out_t *)x->format_data)
76
77#define CONNINFO DATA(libtrace)->conn_info
78#define INPUT DATA(libtrace)->input
79#define OUTPUT DATAOUT(libtrace)->output
80#if HAVE_DAG
81#define DAG DATA(libtrace)->dag
82#endif
83#define OPTIONS DATAOUT(libtrace)->options
84struct erf_format_data_t {
85        union {
86                struct {
87                        char *hostname;
88                        short port;
89                } rt;
90        } conn_info;
91       
92        union {
93                int fd;
94                LIBTRACE_FILE file;
95        } input;
96
97        struct {
98                enum { INDEX_UNKNOWN=0, INDEX_NONE, INDEX_EXISTS } exists;
99                LIBTRACE_FILE index;
100                off_t index_len;
101        } seek;
102
103#if HAVE_DAG
104        struct {
105                void *buf; 
106                unsigned bottom;
107                unsigned top;
108                unsigned diff;
109                unsigned curr;
110                unsigned offset;
111        } dag;
112#endif
113};
114
115struct erf_format_data_out_t {
116        union {
117                struct {
118                        char *hostname;
119                        short port;
120                } rt;
121                char *path;
122        } conn_info;
123
124        union {
125                struct {
126                        int level;
127                        int fileflag;
128                } erf;
129               
130        } options;
131       
132        union {
133                int fd;
134                struct rtserver_t * rtserver;
135#if HAVE_ZLIB
136                gzFile *file;
137#else
138                int file;
139#endif
140        } output;
141};
142
143/** Structure holding status information for a packet */
144typedef struct libtrace_packet_status {
145        uint8_t type;
146        uint8_t reserved;
147        uint16_t message;
148} libtrace_packet_status_t;
149
150typedef struct erf_index_t {
151        uint64_t timestamp;
152        uint64_t offset; 
153} erf_index_t;
154
155#ifdef HAVE_DAG
156static int dag_init_input(struct libtrace_t *libtrace) {
157        libtrace->format_data = (struct erf_format_data_t *)
158                malloc(sizeof(struct erf_format_data_t));
159        return 0;
160}
161
162static int dag_start_input(struct libtrace_t *libtrace) {
163        struct stat buf;
164        if (stat(libtrace->uridata, &buf) == -1) {
165                trace_set_err(libtrace,errno,"stat(%s)",libtrace->uridata);
166                return -1;
167        } 
168        if (S_ISCHR(buf.st_mode)) {
169                /* DEVICE */
170                if((INPUT.fd = dag_open(libtrace->uridata)) < 0) {
171                        trace_set_err(libtrace,errno,"Cannot open DAG %s",
172                                        libtrace->uridata);
173                        return -1;
174                }
175                if((DAG.buf = (void *)dag_mmap(INPUT.fd)) == MAP_FAILED) {
176                        trace_set_err(libtrace,errno,"Cannot mmap DAG %s",
177                                        libtrace->uridata);
178                        return -1;
179                }
180                if(dag_start(INPUT.fd) < 0) {
181                        trace_set_err(libtrace,errno,"Cannot start DAG %s",
182                                        libtrace->uridata);
183                        return -1;
184                }
185        } else {
186                trace_set_err(libtrace,errno,"Not a valid dag device: %s",
187                                libtrace->uridata);
188                return -1;
189        }
190        return 0;
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{
213        libtrace->format_data = malloc(sizeof(struct erf_format_data_t));
214
215        return 0; /* success */
216}
217
218static int erf_start_input(libtrace_t *libtrace)
219{
220        INPUT.file = trace_open_file(libtrace);
221
222        if (!INPUT.file)
223                return -1;
224
225        return 0; /* success */
226}
227
228/* Binary search through the index to find the closest point before
229 * the packet.  Consider in future having a btree index perhaps?
230 */
231static int erf_fast_seek_start(libtrace_t *libtrace,uint64_t erfts)
232{
233        size_t max_off = DATA(libtrace)->seek.index_len/sizeof(erf_index_t);
234        size_t min_off = 0;
235        off_t current;
236        erf_index_t record;
237        do {
238                current=(max_off+min_off)>>2;
239
240                LIBTRACE_SEEK(DATA(libtrace)->seek.index,
241                                current*sizeof(record),
242                                SEEK_SET);
243                LIBTRACE_READ(DATA(libtrace)->seek.index,
244                                &record,sizeof(record));
245                if (record.timestamp < erfts) {
246                        min_off=current;
247                }
248                if (record.timestamp > erfts) {
249                        max_off=current;
250                }
251                if (record.timestamp == erfts)
252                        break;
253        } while(min_off<max_off);
254
255        /* If we've passed it, seek backwards.  This loop shouldn't
256         * execute more than twice.
257         */
258        do {
259                LIBTRACE_SEEK(DATA(libtrace)->seek.index,
260                                current*sizeof(record),SEEK_SET);
261                LIBTRACE_READ(DATA(libtrace)->seek.index,
262                                &record,sizeof(record));
263                current--;
264        } while(record.timestamp>erfts);
265
266        /* We've found our location in the trace, now use it. */
267        LIBTRACE_SEEK(INPUT.file,record.offset,SEEK_SET);
268
269        return 0; /* success */
270}
271
272/* There is no index.  Seek through the entire trace from the start, nice
273 * and slowly.
274 */
275static int erf_slow_seek_start(libtrace_t *libtrace,uint64_t erfts)
276{
277        if (INPUT.file) {
278                LIBTRACE_CLOSE(INPUT.file);
279        }
280        INPUT.file = trace_open_file(libtrace);
281        if (!INPUT.file)
282                return -1;
283        return 0;
284}
285
286static int erf_seek_erf(libtrace_t *libtrace,uint64_t erfts)
287{
288        libtrace_packet_t *packet;
289        off_t off = 0;
290
291        if (DATA(libtrace)->seek.exists==INDEX_UNKNOWN) {
292                char buffer[PATH_MAX];
293                snprintf(buffer,sizeof(buffer),"%s.idx",libtrace->uridata);
294                DATA(libtrace)->seek.index=LIBTRACE_OPEN(buffer,"r");
295                if (DATA(libtrace)->seek.index) {
296                        DATA(libtrace)->seek.exists=INDEX_EXISTS;
297                }
298                else {
299                        DATA(libtrace)->seek.exists=INDEX_NONE;
300                }
301        }
302
303        /* If theres an index, use it to find the nearest packet that isn't
304         * after the time we're looking for.  If there is no index we need
305         * to seek slowly through the trace from the beginning.  Sigh.
306         */
307        switch(DATA(libtrace)->seek.exists) {
308                case INDEX_EXISTS:
309                        erf_fast_seek_start(libtrace,erfts);
310                        break;
311                case INDEX_NONE:
312                        erf_slow_seek_start(libtrace,erfts);
313                        break;
314                case INDEX_UNKNOWN:
315                        assert(0);
316                        break;
317        }
318
319        /* Now seek forward looking for the correct timestamp */
320        packet=trace_create_packet();
321        do {
322                trace_read_packet(libtrace,packet);
323                if (trace_get_erf_timestamp(packet)==erfts)
324                        break;
325                off=LIBTRACE_TELL(INPUT.file);
326        } while(trace_get_erf_timestamp(packet)<erfts);
327
328        LIBTRACE_SEEK(INPUT.file,off,SEEK_SET);
329
330        return 0;
331}
332
333static int rtclient_init_input(struct libtrace_t *libtrace) {
334        char *scan;
335        libtrace->format_data = malloc(sizeof(struct erf_format_data_t));
336
337
338        if (strlen(libtrace->uridata) == 0) {
339                CONNINFO.rt.hostname = 
340                        strdup("localhost");
341                CONNINFO.rt.port = 
342                        COLLECTOR_PORT;
343        } else {
344                if ((scan = strchr(libtrace->uridata,':')) == NULL) {
345                        CONNINFO.rt.hostname = 
346                                strdup(libtrace->uridata);
347                        CONNINFO.rt.port =
348                                COLLECTOR_PORT;
349                } else {
350                        CONNINFO.rt.hostname = 
351                                (char *)strndup(libtrace->uridata,
352                                                (scan - libtrace->uridata));
353                        CONNINFO.rt.port = 
354                                atoi(++scan);
355                }
356        }
357
358        return 0; /* success */
359}
360
361static int rtclient_start_input(libtrace_t *libtrace)
362{
363        struct hostent *he;
364        struct sockaddr_in remote;
365        if ((he=gethostbyname(CONNINFO.rt.hostname)) == NULL) { 
366                trace_set_err(libtrace,errno,"failed to resolve %s",
367                                CONNINFO.rt.hostname);
368                return -1;
369        } 
370        if ((INPUT.fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
371                trace_set_err(libtrace,errno,"socket(AF_INET,SOCK_STREAM)");
372                return -1;
373        }
374
375        remote.sin_family = AF_INET;   
376        remote.sin_port = htons(CONNINFO.rt.port);
377        remote.sin_addr = *((struct in_addr *)he->h_addr);
378        bzero(&(remote.sin_zero), 8);
379
380        if (connect(INPUT.fd, (struct sockaddr *)&remote,
381                                sizeof(struct sockaddr)) == -1) {
382                trace_set_err(libtrace,errno,"connect(%s)",
383                                CONNINFO.rt.hostname);
384                return -1;
385        }
386        return 0;
387}
388
389static int erf_init_output(struct libtrace_out_t *libtrace) {
390        libtrace->format_data = calloc(1,sizeof(struct erf_format_data_out_t));
391
392        OPTIONS.erf.level = 0;
393        OPTIONS.erf.fileflag = O_CREAT | O_LARGEFILE | O_WRONLY;
394        OUTPUT.file = 0;
395
396        return 0;
397}
398
399static int erf_config_output(struct libtrace_out_t *libtrace, trace_option_t option, void *value) {
400
401        switch (option) {
402                case TRACE_OPTION_OUTPUT_COMPRESS:
403                        OPTIONS.erf.level = *(int*)value;
404                        return 0;
405                case TRACE_OPTION_OUTPUT_FILEFLAGS:
406                        OPTIONS.erf.fileflag = *(int*)value;
407                        return 0;
408                default:
409                        /* Unknown option */
410                        trace_set_err_out(libtrace,TRACE_ERR_UNKNOWN_OPTION,
411                                        "Unknown option");
412                        return -1;
413        }
414}
415
416
417#ifdef HAVE_DAG
418static int dag_fin_input(struct libtrace_t *libtrace) {
419        dag_stop(INPUT.fd);
420        free(libtrace->format_data);
421}
422#endif
423
424static int rtclient_fin_input(struct libtrace_t *libtrace) {
425        free(CONNINFO.rt.hostname);
426        close(INPUT.fd);
427        free(libtrace->format_data);
428        return 0;
429}
430
431static int erf_fin_input(struct libtrace_t *libtrace) {
432        LIBTRACE_CLOSE(INPUT.file);
433        free(libtrace->format_data);
434        return 0;
435}
436
437static int erf_fin_output(struct libtrace_out_t *libtrace) {
438        LIBTRACE_CLOSE(OUTPUT.file);
439        free(libtrace->format_data);
440        return 0;
441}
442 
443#if HAVE_DAG
444static int dag_read(struct libtrace_t *libtrace, int block_flag) {
445        int numbytes;
446        static short lctr = 0;
447        struct dag_record_t *erfptr = 0;
448        int rlen;
449
450        if (DAG.diff != 0) 
451                return DAG.diff;
452
453        DAG.bottom = DAG.top;
454        DAG.top = dag_offset(
455                        INPUT.fd,
456                        &(DAG.bottom),
457                        block_flag);
458        DAG.diff = DAG.top -
459                DAG.bottom;
460
461        numbytes=DAG.diff;
462        DAG.offset = 0;
463        return numbytes;
464}
465#endif
466
467#if HAVE_DAG
468/* FIXME: dag_read_packet shouldn't update the pointers, dag_fin_packet
469 * should do that.
470 */
471static int dag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
472        int numbytes;
473        int size;
474        dag_record_t *erfptr;
475        void *buffer = packet->buffer;
476        void *buffer2 = buffer;
477        int rlen;
478
479        if (packet->buf_control == TRACE_CTRL_PACKET) {
480                packet->buf_control = TRACE_CTRL_EXTERNAL;
481                free(packet->buffer);
482                packet->buffer = 0;
483        }
484       
485        packet->type = RT_DATA_ERF;
486       
487        if ((numbytes = dag_read(libtrace,0)) <= 0) 
488                return numbytes;
489
490        /*DAG always gives us whole packets */
491        erfptr = (dag_record_t *) ((void *)DAG.buf + 
492                        (DAG.bottom + DAG.offset));
493        size = ntohs(erfptr->rlen);
494
495        if ( size  > LIBTRACE_PACKET_BUFSIZE) {
496                assert( size < LIBTRACE_PACKET_BUFSIZE);
497        }
498       
499        packet->buffer = erfptr;
500        packet->header = erfptr;
501        if (((dag_record_t *)packet->buffer)->flags.rxerror == 1) {
502                packet->payload = NULL;
503        } else {
504                packet->payload = packet->buffer + erf_get_framing_length(packet);
505        }
506
507        DAG.offset += size;
508        DAG.diff -= size;
509
510        assert(DAG.diff >= 0);
511
512        return (size);
513}
514#endif
515
516static int erf_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
517        int numbytes;
518        int size;
519        void *buffer2 = packet->buffer;
520        int rlen;
521
522        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
523                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
524                packet->buf_control = TRACE_CTRL_PACKET;
525        }
526
527        packet->header = packet->buffer;
528        packet->type = RT_DATA_ERF;
529
530        if ((numbytes=LIBTRACE_READ(INPUT.file,
531                                        packet->buffer,
532                                        dag_record_size)) == -1) {
533                trace_set_err(libtrace,errno,"read(%s)",
534                                libtrace->uridata);
535                return -1;
536        }
537        if (numbytes == 0) {
538                return 0;
539        }
540
541        rlen = ntohs(((dag_record_t *)packet->buffer)->rlen);
542        buffer2 = (char*)packet->buffer + dag_record_size;
543        size = rlen - dag_record_size;
544        assert(size < LIBTRACE_PACKET_BUFSIZE);
545
546       
547        /* Unknown/corrupt */
548        assert(((dag_record_t *)packet->buffer)->type < 10);
549       
550        /* read in the rest of the packet */
551        if ((numbytes=LIBTRACE_READ(INPUT.file,
552                                        buffer2,
553                                        size)) != size) {
554                trace_set_err(libtrace,errno, "read(%s)", libtrace->uridata);
555                return -1;
556        }
557        if (((dag_record_t *)packet->buffer)->flags.rxerror == 1) {
558                packet->payload = NULL;
559        } else {
560                packet->payload = (char*)packet->buffer + erf_get_framing_length(packet);
561        }
562        return rlen;
563}
564
565static int rtclient_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
566        int numbytes;
567
568        while(1) {
569#ifndef MSG_NOSIGNAL
570#  define MSG_NOSIGNAL 0
571#endif
572                if ((numbytes = recv(INPUT.fd,
573                                                buffer,
574                                                len,
575                                                MSG_NOSIGNAL)) == -1) {
576                        if (errno == EINTR) {
577                                /*ignore EINTR in case
578                                 *a caller is using signals
579                                 */
580                                continue;
581                        }
582                        trace_set_err(libtrace,errno,"recv(%s)",
583                                        libtrace->uridata);
584                        return -1;
585                }
586                break;
587
588        }
589        return numbytes;
590}
591
592static int rtclient_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
593        int numbytes = 0;
594        char buf[RP_BUFSIZE];
595        int read_required = 0;
596       
597        void *buffer = 0;
598
599        if (packet->buf_control == TRACE_CTRL_EXTERNAL || !packet->buffer) {
600                packet->buf_control = TRACE_CTRL_PACKET;
601                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
602        }
603
604        buffer = packet->buffer;
605        packet->header = packet->buffer;
606       
607        packet->type = RT_DATA_ERF;
608
609       
610        do {
611                struct libtrace_packet_status status;
612                int size;
613                if (tracefifo_out_available(libtrace->fifo) == 0 
614                                || read_required) {
615                        if ((numbytes = rtclient_read(
616                                        libtrace,buf,RP_BUFSIZE))<=0) {
617                                return numbytes;
618                        }
619                        tracefifo_write(libtrace->fifo,buf,numbytes);
620                        read_required = 0;
621                }
622                /* Read status byte */
623                if (tracefifo_out_read(libtrace->fifo,
624                                &status, sizeof(uint32_t)) == 0) {
625                        read_required = 1;
626                        continue;
627                }
628                tracefifo_out_update(libtrace->fifo,sizeof(uint32_t));
629                /* Read in packet size */
630                if (tracefifo_out_read(libtrace->fifo,
631                                &size, sizeof(uint32_t)) == 0) {
632                        tracefifo_out_reset(libtrace->fifo);
633                        read_required = 1;
634                        continue;
635                }
636                tracefifo_out_update(libtrace->fifo, sizeof(uint32_t));
637               
638                if (status.type == 2 /* RT_MSG */) {
639                        /* Need to skip this packet as it is a message packet */
640                        tracefifo_out_update(libtrace->fifo, size);
641                        tracefifo_ack_update(libtrace->fifo, size + 
642                                        sizeof(uint32_t) + 
643                                        sizeof(libtrace_packet_status_t));
644                        continue;
645                }
646               
647                /* read in the full packet */
648                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
649                                                buffer, size)) == 0) {
650                        tracefifo_out_reset(libtrace->fifo);
651                        read_required = 1;
652                        continue;
653                }
654
655                /* got in our whole packet, so... */
656                tracefifo_out_update(libtrace->fifo,size);
657
658                tracefifo_ack_update(libtrace->fifo,size + 
659                                sizeof(uint32_t) + 
660                                sizeof(libtrace_packet_status_t));
661
662                if (((dag_record_t *)buffer)->flags.rxerror == 1) {
663                        packet->payload = NULL;
664                } else {
665                        packet->payload = (char*)packet->buffer + erf_get_framing_length(packet);
666                }
667                return numbytes;
668        } while(1);
669}
670
671static int erf_dump_packet(libtrace_out_t *libtrace,
672                dag_record_t *erfptr, int pad, void *buffer, size_t size) {
673        int numbytes = 0;
674        assert(size<=65536);
675        /* FIXME: Shouldn't this return != dag_record_size+pad on error? */
676        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, erfptr, dag_record_size + pad)) == 0) {
677                trace_set_err_out(libtrace,errno,
678                                "write(%s)",libtrace->uridata);
679                return -1;
680        }
681
682        if ((numbytes=LIBTRACE_WRITE(OUTPUT.file, buffer, size)) == 0) {
683                trace_set_err_out(libtrace,errno,
684                                "write(%s)",libtrace->uridata);
685                return -1;
686        }
687
688        return numbytes + pad + dag_record_size;
689}
690
691static int erf_start_output(libtrace_out_t *libtrace)
692{
693        OUTPUT.file = trace_open_file_out(libtrace,
694                        OPTIONS.erf.level,
695                        OPTIONS.erf.fileflag);
696        if (!OUTPUT.file) {
697                return -1;
698        }
699        return 0;
700}
701               
702static int erf_write_packet(libtrace_out_t *libtrace, 
703                const libtrace_packet_t *packet) 
704{
705        int numbytes = 0;
706        int pad = 0;
707        dag_record_t *dag_hdr = (dag_record_t *)packet->header;
708        void *payload = packet->payload;
709
710        assert(OUTPUT.file);
711
712        pad = erf_get_padding(packet);
713
714        /* If we've had an rxerror, we have no payload to write - fix rlen to
715         * be the correct length */
716        if (payload == NULL) {
717                dag_hdr->rlen = htons(dag_record_size + pad);
718        } 
719       
720        if (libtrace->format == &erf 
721#if HAVE_DAG
722                        || libtrace->format == &dag
723#endif
724                        ) {
725                numbytes = erf_dump_packet(libtrace,
726                                (dag_record_t *)packet->buffer,
727                                pad,
728                                payload,
729                                trace_get_capture_length(packet)
730                                );
731        } else {
732                dag_record_t erfhdr;
733                /* convert format - build up a new erf header */
734                /* Timestamp */
735                erfhdr.ts = trace_get_erf_timestamp(packet);
736                erfhdr.type = libtrace_to_erf_type(trace_get_link_type(packet));
737                /* Flags. Can't do this */
738                memset(&erfhdr.flags,1,sizeof(erfhdr.flags));
739                /* Packet length (rlen includes format overhead) */
740                erfhdr.rlen = trace_get_capture_length(packet) 
741                        + erf_get_framing_length(packet);
742                /* loss counter. Can't do this */
743                erfhdr.lctr = 0;
744                /* Wire length */
745                erfhdr.wlen = trace_get_wire_length(packet);
746
747                /* Write it out */
748                numbytes = erf_dump_packet(libtrace,
749                                &erfhdr,
750                                pad,
751                                payload,
752                                trace_get_capture_length(packet));
753        }
754        return numbytes;
755}
756
757static libtrace_linktype_t erf_get_link_type(const struct libtrace_packet_t *packet) {
758        dag_record_t *erfptr = 0;
759        erfptr = (dag_record_t *)packet->header;
760        return erf_type_to_libtrace(erfptr->type);
761}
762
763static int8_t erf_get_direction(const struct libtrace_packet_t *packet) {
764        dag_record_t *erfptr = 0;
765        erfptr = (dag_record_t *)packet->header;
766        return erfptr->flags.iface;
767}
768
769static int8_t erf_set_direction(const struct libtrace_packet_t *packet, int8_t direction) {
770        dag_record_t *erfptr = 0;
771        erfptr = (dag_record_t *)packet->header;
772        erfptr->flags.iface = direction;
773        return erfptr->flags.iface;
774}
775
776static uint64_t erf_get_erf_timestamp(const struct libtrace_packet_t *packet) {
777        dag_record_t *erfptr = 0;
778        erfptr = (dag_record_t *)packet->header;
779        return erfptr->ts;
780}
781
782static int erf_get_capture_length(const struct libtrace_packet_t *packet) {
783        dag_record_t *erfptr = 0;
784        erfptr = (dag_record_t *)packet->header;
785        return (ntohs(erfptr->rlen) - erf_get_framing_length(packet));
786}
787
788static int erf_get_wire_length(const struct libtrace_packet_t *packet) {
789        dag_record_t *erfptr = 0;
790        erfptr = (dag_record_t *)packet->header;
791        return ntohs(erfptr->wlen);
792}
793
794static size_t erf_set_capture_length(struct libtrace_packet_t *packet, size_t size) {
795        dag_record_t *erfptr = 0;
796        assert(packet);
797        if(size  > trace_get_capture_length(packet)) {
798                /* can't make a packet larger */
799                return trace_get_capture_length(packet);
800        }
801        erfptr = (dag_record_t *)packet->header;
802        erfptr->rlen = htons(size + erf_get_framing_length(packet));
803        printf("Set length: %i\n", trace_get_capture_length(packet));
804        return trace_get_capture_length(packet);
805}
806
807static int rtclient_get_fd(const libtrace_t *libtrace) {
808        return INPUT.fd;
809}
810
811static int erf_get_fd(const libtrace_t *libtrace) {
812        return INPUT.fd;
813}
814
815#ifdef HAVE_DAG
816struct libtrace_eventobj_t trace_event_dag(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
817        struct libtrace_eventobj_t event = {0,0,0.0,0};
818        int dag_fd;
819        int data;
820
821        if (trace->format->get_fd) {
822                dag_fd = trace->format->get_fd(trace);
823        } else {
824                dag_fd = 0;
825        }
826       
827        data = dag_read(trace, DAGF_NONBLOCK);
828
829        if (data > 0) {
830                event.size = trace_read_packet(trace,packet);
831                event.type = TRACE_EVENT_PACKET;
832                return event;
833        }
834        event.type = TRACE_EVENT_SLEEP;
835        event.seconds = 0.0001;
836        return event;
837}
838#endif
839
840#if HAVE_DAG
841static void dag_help() {
842        printf("dag format module: $Revision$\n");
843        printf("Supported input URIs:\n");
844        printf("\tdag:/dev/dagn\n");
845        printf("\n");
846        printf("\te.g.: dag:/dev/dag0\n");
847        printf("\n");
848        printf("Supported output URIs:\n");
849        printf("\tnone\n");
850        printf("\n");
851}
852#endif
853
854static void erf_help() {
855        printf("erf format module: $Revision$\n");
856        printf("Supported input URIs:\n");
857        printf("\terf:/path/to/file\t(uncompressed)\n");
858        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
859        printf("\terf:-\t(stdin, either compressed or not)\n");
860        printf("\terf:/path/to/socket\n");
861        printf("\n");
862        printf("\te.g.: erf:/tmp/trace\n");
863        printf("\n");
864        printf("Supported output URIs:\n");
865        printf("\terf:path/to/file\t(uncompressed)\n");
866        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
867        printf("\terf:-\t(stdout, either compressed or not)\n");
868        printf("\n");
869        printf("\te.g.: erf:/tmp/trace\n");
870        printf("\n");
871        printf("Supported output options:\n");
872        printf("\t-z\tSpecify the gzip compression, ranging from 0 (uncompressed) to 9 - defaults to 1\n");
873        printf("\n");
874
875       
876}
877
878static void rtclient_help() {
879        printf("rtclient format module: $Revision$\n");
880        printf("DEPRECATED - use rt module instead\n");
881        printf("Supported input URIs:\n");
882        printf("\trtclient:host:port\n");
883        printf("\n");
884        printf("\te.g.:rtclient:localhost:3435\n");
885        printf("\n");
886        printf("Supported output URIs:\n");
887        printf("\tnone\n");
888        printf("\n");
889}       
890
891static struct libtrace_format_t erf = {
892        "erf",
893        "$Id$",
894        TRACE_FORMAT_ERF,
895        erf_init_input,                 /* init_input */       
896        NULL,                           /* config_input */
897        erf_start_input,                /* start_input */
898        NULL,                           /* pause_input */
899        erf_init_output,                /* init_output */
900        erf_config_output,              /* config_output */
901        erf_start_output,               /* start_output */
902        erf_fin_input,                  /* fin_input */
903        erf_fin_output,                 /* fin_output */
904        erf_read_packet,                /* read_packet */
905        erf_write_packet,               /* write_packet */
906        erf_get_link_type,              /* get_link_type */
907        erf_get_direction,              /* get_direction */
908        erf_set_direction,              /* set_direction */
909        erf_get_erf_timestamp,          /* get_erf_timestamp */
910        NULL,                           /* get_timeval */
911        NULL,                           /* get_seconds */
912        erf_seek_erf,                   /* seek_erf */
913        NULL,                           /* seek_timeval */
914        NULL,                           /* seek_seconds */
915        erf_get_capture_length,         /* get_capture_length */
916        erf_get_wire_length,            /* get_wire_length */
917        erf_get_framing_length,         /* get_framing_length */
918        erf_set_capture_length,         /* set_capture_length */
919        NULL,                           /* get_fd */
920        trace_event_trace,              /* trace_event */
921        erf_help                        /* help */
922};
923
924#ifdef HAVE_DAG
925static struct libtrace_format_t dag = {
926        "dag",
927        "$Id$",
928        TRACE_FORMAT_ERF,
929        dag_init_input,                 /* init_input */       
930        NULL,                           /* config_input */
931        dag_start_input,                /* start_input */
932        NULL,                           /* pause_input */
933        NULL,                           /* init_output */
934        NULL,                           /* config_output */
935        NULL,                           /* start_output */
936        dag_fin_input,                  /* fin_input */
937        NULL,                           /* fin_output */
938        dag_read_packet,                /* read_packet */
939        NULL,                           /* write_packet */
940        erf_get_link_type,              /* get_link_type */
941        erf_get_direction,              /* get_direction */
942        erf_set_direction,              /* set_direction */
943        erf_get_erf_timestamp,          /* get_erf_timestamp */
944        NULL,                           /* get_timeval */
945        NULL,                           /* get_seconds */
946        NULL,                           /* seek_erf */
947        NULL,                           /* seek_timeval */
948        NULL,                           /* seek_seconds */
949        erf_get_capture_length,         /* get_capture_length */
950        erf_get_wire_length,            /* get_wire_length */
951        erf_get_framing_length,         /* get_framing_length */
952        erf_set_capture_length,         /* set_capture_length */
953        NULL,                           /* get_fd */
954        trace_event_dag,                /* trace_event */
955        dag_help                        /* help */
956};
957#endif
958
959static struct libtrace_format_t rtclient = {
960        "rtclient",
961        "$Id$",
962        TRACE_FORMAT_ERF,
963        rtclient_init_input,            /* init_input */       
964        NULL,                           /* config_input */
965        rtclient_start_input,           /* start_input */
966        NULL,                           /* pause_input */
967        NULL,                           /* init_output */
968        NULL,                           /* config_output */
969        NULL,                           /* start_output */
970        rtclient_fin_input,             /* fin_input */
971        NULL,                           /* fin_output */
972        rtclient_read_packet,           /* read_packet */
973        NULL,                           /* write_packet */
974        erf_get_link_type,              /* get_link_type */
975        erf_get_direction,              /* get_direction */
976        erf_set_direction,              /* set_direction */
977        erf_get_erf_timestamp,          /* get_erf_timestamp */
978        NULL,                           /* get_timeval */
979        NULL,                           /* get_seconds */
980        NULL,                           /* seek_erf */
981        NULL,                           /* seek_timeval */
982        NULL,                           /* seek_seconds */
983        erf_get_capture_length,         /* get_capture_length */
984        erf_get_wire_length,            /* get_wire_length */
985        erf_get_framing_length,         /* get_framing_length */
986        erf_set_capture_length,         /* set_capture_length */
987        rtclient_get_fd,                /* get_fd */
988        trace_event_device,             /* trace_event */
989        rtclient_help                   /* help */
990};
991
992void __attribute__((constructor)) erf_constructor() {
993        register_format(&rtclient);
994        register_format(&erf);
995#ifdef HAVE_DAG
996        register_format(&dag);
997#endif
998}
Note: See TracBrowser for help on using the repository browser.