source: lib/format_erf.c @ e6d963c

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

Style fixes, get rid of unnecessary "struct"'s

  • Property mode set to 100644
File size: 25.0 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30#define _GNU_SOURCE
31
32#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#if HAVE_DAG
47#include <sys/mman.h>
48#endif
49
50#ifdef WIN32
51#  include <io.h>
52#  include <share.h>
53#  define PATH_MAX _MAX_PATH
54#  define snprintf sprintf_s
55#else
56#  include <netdb.h>
57#endif
58
59
60#define COLLECTOR_PORT 3435
61
62static struct libtrace_format_t erf;
63static struct libtrace_format_t rtclient;
64#if HAVE_DAG
65static struct libtrace_format_t dag;
66#endif
67
68#define DATA(x) ((struct erf_format_data_t *)x->format_data)
69#define DATAOUT(x) ((struct erf_format_data_out_t *)x->format_data)
70
71#define CONNINFO DATA(libtrace)->conn_info
72#define INPUT DATA(libtrace)->input
73#define OUTPUT DATAOUT(libtrace)->output
74#if HAVE_DAG
75#define DAG DATA(libtrace)->dag
76#endif
77#define OPTIONS DATAOUT(libtrace)->options
78struct erf_format_data_t {
79        union {
80                struct {
81                        char *hostname;
82                        short port;
83                } rt;
84        } conn_info;
85       
86        union {
87                int fd;
88                libtrace_io_t *file;
89        } input;
90
91        struct {
92                enum { INDEX_UNKNOWN=0, INDEX_NONE, INDEX_EXISTS } exists;
93                libtrace_io_t *index;
94                off_t index_len;
95        } seek;
96
97#if HAVE_DAG
98        struct {
99                void *buf; 
100                unsigned bottom;
101                unsigned top;
102                unsigned diff;
103                unsigned curr;
104                unsigned offset;
105        } dag;
106#endif
107};
108
109struct erf_format_data_out_t {
110        union {
111                struct {
112                        char *hostname;
113                        short port;
114                } rt;
115                char *path;
116        } conn_info;
117
118        union {
119                struct {
120                        int level;
121                        int fileflag;
122                } erf;
123               
124        } options;
125       
126        union {
127                int fd;
128                struct rtserver_t * rtserver;
129                libtrace_io_t *file;
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(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_io_seek(DATA(libtrace)->seek.index,
230                                current*sizeof(record),
231                                SEEK_SET);
232                libtrace_io_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_io_seek(DATA(libtrace)->seek.index,
249                                current*sizeof(record),SEEK_SET);
250                libtrace_io_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_io_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_io_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_io_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_io_tell(INPUT.file);
315        } while(trace_get_erf_timestamp(packet)<erfts);
316
317        libtrace_io_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,TRACE_ERR_INIT_FAILED,"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 = malloc(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_io_close(INPUT.file);
435        free(libtrace->format_data);
436        return 0;
437}
438
439static int erf_fin_output(libtrace_out_t *libtrace) {
440        libtrace_io_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_io_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                return 0;
546        }
547
548        rlen = ntohs(((dag_record_t *)packet->buffer)->rlen);
549        buffer2 = (char*)packet->buffer + dag_record_size;
550        size = rlen - dag_record_size;
551
552        assert(size < LIBTRACE_PACKET_BUFSIZE && size >= dag_record_size);
553
554        /* Unknown/corrupt */
555        assert(((dag_record_t *)packet->buffer)->type < 10);
556       
557        /* read in the rest of the packet */
558        if ((numbytes=libtrace_io_read(INPUT.file,
559                                        buffer2,
560                                        size)) != size) {
561                trace_set_err(libtrace,errno, "read(%s)", libtrace->uridata);
562                return -1;
563        }
564        if (((dag_record_t *)packet->buffer)->flags.rxerror == 1) {
565                packet->payload = NULL;
566        } else {
567                packet->payload = (char*)packet->buffer + erf_get_framing_length(packet);
568        }
569        return rlen;
570}
571
572static int rtclient_read(libtrace_t *libtrace, void *buffer, size_t len) {
573        int numbytes;
574
575        while(1) {
576#ifndef MSG_NOSIGNAL
577#  define MSG_NOSIGNAL 0
578#endif
579                if ((numbytes = recv(INPUT.fd,
580                                                buffer,
581                                                len,
582                                                MSG_NOSIGNAL)) == -1) {
583                        if (errno == EINTR) {
584                                /*ignore EINTR in case
585                                 *a caller is using signals
586                                 */
587                                continue;
588                        }
589                        trace_set_err(libtrace,errno,"recv(%s)",
590                                        libtrace->uridata);
591                        return -1;
592                }
593                break;
594
595        }
596        return numbytes;
597}
598
599static int rtclient_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
600        int numbytes = 0;
601        char buf[RP_BUFSIZE];
602        int read_required = 0;
603       
604        void *buffer = 0;
605
606        if (packet->buf_control == TRACE_CTRL_EXTERNAL || !packet->buffer) {
607                packet->buf_control = TRACE_CTRL_PACKET;
608                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
609        }
610
611        buffer = packet->buffer;
612        packet->header = packet->buffer;
613       
614        packet->type = RT_DATA_ERF;
615
616       
617        do {
618                libtrace_packet_status_t status;
619                int size;
620                if (tracefifo_out_available(libtrace->fifo) == 0 
621                                || read_required) {
622                        if ((numbytes = rtclient_read(
623                                        libtrace,buf,RP_BUFSIZE))<=0) {
624                                return numbytes;
625                        }
626                        tracefifo_write(libtrace->fifo,buf,numbytes);
627                        read_required = 0;
628                }
629                /* Read status byte */
630                if (tracefifo_out_read(libtrace->fifo,
631                                &status, sizeof(uint32_t)) == 0) {
632                        read_required = 1;
633                        continue;
634                }
635                tracefifo_out_update(libtrace->fifo,sizeof(uint32_t));
636                /* Read in packet size */
637                if (tracefifo_out_read(libtrace->fifo,
638                                &size, sizeof(uint32_t)) == 0) {
639                        tracefifo_out_reset(libtrace->fifo);
640                        read_required = 1;
641                        continue;
642                }
643                tracefifo_out_update(libtrace->fifo, sizeof(uint32_t));
644               
645                if (status.type == 2 /* RT_MSG */) {
646                        /* Need to skip this packet as it is a message packet */
647                        tracefifo_out_update(libtrace->fifo, size);
648                        tracefifo_ack_update(libtrace->fifo, size + 
649                                        sizeof(uint32_t) + 
650                                        sizeof(libtrace_packet_status_t));
651                        continue;
652                }
653               
654                /* read in the full packet */
655                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
656                                                buffer, size)) == 0) {
657                        tracefifo_out_reset(libtrace->fifo);
658                        read_required = 1;
659                        continue;
660                }
661
662                /* got in our whole packet, so... */
663                tracefifo_out_update(libtrace->fifo,size);
664
665                tracefifo_ack_update(libtrace->fifo,size + 
666                                sizeof(uint32_t) + 
667                                sizeof(libtrace_packet_status_t));
668
669                if (((dag_record_t *)buffer)->flags.rxerror == 1) {
670                        packet->payload = NULL;
671                } else {
672                        packet->payload = (char*)packet->buffer + erf_get_framing_length(packet);
673                }
674                return numbytes;
675        } while(1);
676}
677
678static int erf_dump_packet(libtrace_out_t *libtrace,
679                dag_record_t *erfptr, int pad, void *buffer, size_t size) {
680        int numbytes = 0;
681        assert(size<=65536);
682
683        if ((numbytes = libtrace_io_write(OUTPUT.file, erfptr, dag_record_size + pad)) != dag_record_size+pad) {
684                trace_set_err_out(libtrace,errno,
685                                "write(%s)",libtrace->uridata);
686                return -1;
687        }
688
689        if ((numbytes=libtrace_io_write(OUTPUT.file, buffer, size)) != (int)size) {
690                trace_set_err_out(libtrace,errno,
691                                "write(%s)",libtrace->uridata);
692                return -1;
693        }
694
695        return numbytes + pad + dag_record_size;
696}
697
698static int erf_start_output(libtrace_out_t *libtrace)
699{
700        OUTPUT.file = trace_open_file_out(libtrace,
701                        OPTIONS.erf.level,
702                        OPTIONS.erf.fileflag);
703        if (!OUTPUT.file) {
704                return -1;
705        }
706        return 0;
707}
708               
709static int erf_write_packet(libtrace_out_t *libtrace, 
710                const libtrace_packet_t *packet) 
711{
712        int numbytes = 0;
713        int pad = 0;
714        dag_record_t *dag_hdr = (dag_record_t *)packet->header;
715        void *payload = packet->payload;
716
717        assert(OUTPUT.file);
718
719        pad = erf_get_padding(packet);
720
721        /* If we've had an rxerror, we have no payload to write - fix rlen to
722         * be the correct length */
723        if (payload == NULL) {
724                dag_hdr->rlen = htons(dag_record_size + pad);
725        } 
726       
727        if (packet->trace->format == &erf 
728#if HAVE_DAG
729                        || packet->trace->format == &dag
730#endif
731                        ) {
732                numbytes = erf_dump_packet(libtrace,
733                                (dag_record_t *)packet->header,
734                                pad,
735                                payload,
736                                trace_get_capture_length(packet)
737                                );
738        } else {
739                dag_record_t erfhdr;
740                int type;
741                /* convert format - build up a new erf header */
742                /* Timestamp */
743                erfhdr.ts = trace_get_erf_timestamp(packet);
744                type=libtrace_to_erf_type(trace_get_link_type(packet));
745                if (type==(char)-1) {
746                        trace_set_err_out(libtrace,TRACE_ERR_NO_CONVERSION,
747                                        "No erf type for packet");
748                        return -1;
749                }
750                erfhdr.type = type;
751                /* Flags. Can't do this */
752                memset(&erfhdr.flags,1,sizeof(erfhdr.flags));
753                /* Packet length (rlen includes format overhead) */
754                erfhdr.rlen = trace_get_capture_length(packet) 
755                        + erf_get_framing_length(packet);
756                /* loss counter. Can't do this */
757                erfhdr.lctr = 0;
758                /* Wire length */
759                erfhdr.wlen = trace_get_wire_length(packet);
760
761                /* Write it out */
762                numbytes = erf_dump_packet(libtrace,
763                                &erfhdr,
764                                pad,
765                                payload,
766                                trace_get_capture_length(packet));
767        }
768        return numbytes;
769}
770
771static libtrace_linktype_t erf_get_link_type(const libtrace_packet_t *packet) {
772        dag_record_t *erfptr = 0;
773        erfptr = (dag_record_t *)packet->header;
774        return erf_type_to_libtrace(erfptr->type);
775}
776
777static int8_t erf_get_direction(const libtrace_packet_t *packet) {
778        dag_record_t *erfptr = 0;
779        erfptr = (dag_record_t *)packet->header;
780        return erfptr->flags.iface;
781}
782
783static int8_t erf_set_direction(const libtrace_packet_t *packet, int8_t direction) {
784        dag_record_t *erfptr = 0;
785        erfptr = (dag_record_t *)packet->header;
786        erfptr->flags.iface = direction;
787        return erfptr->flags.iface;
788}
789
790static uint64_t erf_get_erf_timestamp(const libtrace_packet_t *packet) {
791        dag_record_t *erfptr = 0;
792        erfptr = (dag_record_t *)packet->header;
793        return erfptr->ts;
794}
795
796static int erf_get_capture_length(const libtrace_packet_t *packet) {
797        dag_record_t *erfptr = 0;
798        erfptr = (dag_record_t *)packet->header;
799        return (ntohs(erfptr->rlen) - erf_get_framing_length(packet));
800}
801
802static int erf_get_wire_length(const libtrace_packet_t *packet) {
803        dag_record_t *erfptr = 0;
804        erfptr = (dag_record_t *)packet->header;
805        return ntohs(erfptr->wlen);
806}
807
808static size_t erf_set_capture_length(libtrace_packet_t *packet, size_t size) {
809        dag_record_t *erfptr = 0;
810        assert(packet);
811        if(size  > trace_get_capture_length(packet)) {
812                /* can't make a packet larger */
813                return trace_get_capture_length(packet);
814        }
815        erfptr = (dag_record_t *)packet->header;
816        erfptr->rlen = htons(size + erf_get_framing_length(packet));
817        return trace_get_capture_length(packet);
818}
819
820static int rtclient_get_fd(const libtrace_t *libtrace) {
821        return INPUT.fd;
822}
823
824#ifdef HAVE_DAG
825libtrace_eventobj_t trace_event_dag(libtrace_t *trace, libtrace_packet_t *packet) {
826        libtrace_eventobj_t event = {0,0,0.0,0};
827        int dag_fd;
828        int data;
829
830        if (trace->format->get_fd) {
831                dag_fd = trace->format->get_fd(trace);
832        } else {
833                dag_fd = 0;
834        }
835       
836        data = dag_read(trace, DAGF_NONBLOCK);
837
838        if (data > 0) {
839                event.size = trace_read_packet(trace,packet);
840                event.type = TRACE_EVENT_PACKET;
841                return event;
842        }
843        event.type = TRACE_EVENT_SLEEP;
844        event.seconds = 0.0001;
845        return event;
846}
847#endif
848
849#if HAVE_DAG
850static void dag_help() {
851        printf("dag format module: $Revision$\n");
852        printf("Supported input URIs:\n");
853        printf("\tdag:/dev/dagn\n");
854        printf("\n");
855        printf("\te.g.: dag:/dev/dag0\n");
856        printf("\n");
857        printf("Supported output URIs:\n");
858        printf("\tnone\n");
859        printf("\n");
860}
861#endif
862
863static void erf_help() {
864        printf("erf format module: $Revision$\n");
865        printf("Supported input URIs:\n");
866        printf("\terf:/path/to/file\t(uncompressed)\n");
867        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
868        printf("\terf:-\t(stdin, either compressed or not)\n");
869        printf("\terf:/path/to/socket\n");
870        printf("\n");
871        printf("\te.g.: erf:/tmp/trace\n");
872        printf("\n");
873        printf("Supported output URIs:\n");
874        printf("\terf:path/to/file\t(uncompressed)\n");
875        printf("\terf:/path/to/file.gz\t(gzip-compressed)\n");
876        printf("\terf:-\t(stdout, either compressed or not)\n");
877        printf("\n");
878        printf("\te.g.: erf:/tmp/trace\n");
879        printf("\n");
880        printf("Supported output options:\n");
881        printf("\t-z\tSpecify the gzip compression, ranging from 0 (uncompressed) to 9 - defaults to 1\n");
882        printf("\n");
883
884       
885}
886
887static void rtclient_help() {
888        printf("rtclient format module: $Revision$\n");
889        printf("DEPRECATED - use rt module instead\n");
890        printf("Supported input URIs:\n");
891        printf("\trtclient:host:port\n");
892        printf("\n");
893        printf("\te.g.:rtclient:localhost:3435\n");
894        printf("\n");
895        printf("Supported output URIs:\n");
896        printf("\tnone\n");
897        printf("\n");
898}       
899
900static struct libtrace_format_t erf = {
901        "erf",
902        "$Id$",
903        TRACE_FORMAT_ERF,
904        erf_init_input,                 /* init_input */       
905        NULL,                           /* config_input */
906        erf_start_input,                /* start_input */
907        NULL,                           /* pause_input */
908        erf_init_output,                /* init_output */
909        erf_config_output,              /* config_output */
910        erf_start_output,               /* start_output */
911        erf_fin_input,                  /* fin_input */
912        erf_fin_output,                 /* fin_output */
913        erf_read_packet,                /* read_packet */
914        NULL,                           /* fin_packet */
915        erf_write_packet,               /* write_packet */
916        erf_get_link_type,              /* get_link_type */
917        erf_get_direction,              /* get_direction */
918        erf_set_direction,              /* set_direction */
919        erf_get_erf_timestamp,          /* get_erf_timestamp */
920        NULL,                           /* get_timeval */
921        NULL,                           /* get_seconds */
922        erf_seek_erf,                   /* seek_erf */
923        NULL,                           /* seek_timeval */
924        NULL,                           /* seek_seconds */
925        erf_get_capture_length,         /* get_capture_length */
926        erf_get_wire_length,            /* get_wire_length */
927        erf_get_framing_length,         /* get_framing_length */
928        erf_set_capture_length,         /* set_capture_length */
929        NULL,                           /* get_fd */
930        trace_event_trace,              /* trace_event */
931        erf_help,                       /* help */
932        NULL                            /* next pointer */
933};
934
935#ifdef HAVE_DAG
936static struct libtrace_format_t dag = {
937        "dag",
938        "$Id$",
939        TRACE_FORMAT_ERF,
940        dag_init_input,                 /* init_input */       
941        NULL,                           /* config_input */
942        dag_start_input,                /* start_input */
943        dag_pause_input,                /* pause_input */
944        NULL,                           /* init_output */
945        NULL,                           /* config_output */
946        NULL,                           /* start_output */
947        dag_fin_input,                  /* fin_input */
948        NULL,                           /* fin_output */
949        dag_read_packet,                /* read_packet */
950        NULL,                           /* fin_packet */
951        NULL,                           /* write_packet */
952        erf_get_link_type,              /* get_link_type */
953        erf_get_direction,              /* get_direction */
954        erf_set_direction,              /* set_direction */
955        erf_get_erf_timestamp,          /* get_erf_timestamp */
956        NULL,                           /* get_timeval */
957        NULL,                           /* get_seconds */
958        NULL,                           /* seek_erf */
959        NULL,                           /* seek_timeval */
960        NULL,                           /* seek_seconds */
961        erf_get_capture_length,         /* get_capture_length */
962        erf_get_wire_length,            /* get_wire_length */
963        erf_get_framing_length,         /* get_framing_length */
964        erf_set_capture_length,         /* set_capture_length */
965        NULL,                           /* get_fd */
966        trace_event_dag,                /* trace_event */
967        dag_help,                       /* help */
968        NULL                            /* next pointer */
969};
970#endif
971
972static struct libtrace_format_t rtclient = {
973        "rtclient",
974        "$Id$",
975        TRACE_FORMAT_ERF,
976        rtclient_init_input,            /* init_input */       
977        NULL,                           /* config_input */
978        rtclient_start_input,           /* start_input */
979        rtclient_pause_input,           /* pause_input */
980        NULL,                           /* init_output */
981        NULL,                           /* config_output */
982        NULL,                           /* start_output */
983        rtclient_fin_input,             /* fin_input */
984        NULL,                           /* fin_output */
985        rtclient_read_packet,           /* read_packet */
986        NULL,                           /* fin_packet */
987        NULL,                           /* write_packet */
988        erf_get_link_type,              /* get_link_type */
989        erf_get_direction,              /* get_direction */
990        erf_set_direction,              /* set_direction */
991        erf_get_erf_timestamp,          /* get_erf_timestamp */
992        NULL,                           /* get_timeval */
993        NULL,                           /* get_seconds */
994        NULL,                           /* seek_erf */
995        NULL,                           /* seek_timeval */
996        NULL,                           /* seek_seconds */
997        erf_get_capture_length,         /* get_capture_length */
998        erf_get_wire_length,            /* get_wire_length */
999        erf_get_framing_length,         /* get_framing_length */
1000        erf_set_capture_length,         /* set_capture_length */
1001        rtclient_get_fd,                /* get_fd */
1002        trace_event_device,             /* trace_event */
1003        rtclient_help,                  /* help */
1004        NULL                            /* next pointer */
1005};
1006
1007void CONSTRUCTOR erf_constructor() {
1008        register_format(&rtclient);
1009        register_format(&erf);
1010#ifdef HAVE_DAG
1011        register_format(&dag);
1012#endif
1013}
Note: See TracBrowser for help on using the repository browser.