source: lib/format_erf.c @ 9e830d4

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

More portability/warnings fixed

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