source: lib/format_rt.c @ 2fbcb26

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 2fbcb26 was 2fbcb26, checked in by Shane Alcock <salcock@…>, 15 years ago

tracedump now ignores packets that are not actual data packets, particularly RT meta-data packets.
Corrected the calculation of get_capture_length for RT meta-data packets.

  • Property mode set to 100644
File size: 18.9 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *          Shane Alcock
8 *
9 * All rights reserved.
10 *
11 * This code has been developed by the University of Waikato WAND
12 * research group. For further information please see http://www.wand.net.nz/
13 *
14 * libtrace is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * libtrace is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with libtrace; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 *
28 * $Id$
29 *
30 */
31
32#define _GNU_SOURCE
33
34#include "config.h"
35#include "common.h"
36#include "libtrace.h"
37#include "libtrace_int.h"
38#include "format_helper.h"
39#include "rt_protocol.h"
40
41#include <sys/stat.h>
42#include <assert.h>
43#include <errno.h>
44#include <fcntl.h>
45#include <stdio.h>
46#include <string.h>
47#include <stdlib.h>
48
49#ifndef WIN32
50# include <netdb.h>
51#endif
52
53#define RT_INFO ((struct rt_format_data_t*)libtrace->format_data)
54
55static const char *rt_deny_reason(enum rt_conn_denied_t reason) 
56{
57        const char *string = 0;
58
59        switch(reason) {
60                case RT_DENY_WRAPPER:
61                        string = "Rejected by TCP Wrappers";
62                        break;
63                case RT_DENY_FULL:
64                        string = "Max connections reached on server";
65                        break;
66                case RT_DENY_AUTH:
67                        string = "Authentication failed";
68                        break;
69                default:
70                        string = "Unknown reason";
71        }
72
73        return string;
74}
75
76
77struct rt_format_data_t {
78        char *hostname;
79        int port;
80        int input_fd;
81        int reliable;
82        char *pkt_buffer;
83        char *buf_current;
84        size_t buf_filled;
85        rt_header_t rt_hdr;
86       
87        libtrace_t *dummy_duck;
88        libtrace_t *dummy_erf;
89        libtrace_t *dummy_pcap;
90        libtrace_t *dummy_wag;
91        libtrace_t *dummy_linux;
92};
93
94static int rt_connect(libtrace_t *libtrace) {
95        struct hostent *he;
96        struct sockaddr_in remote;
97        rt_header_t connect_msg;
98        rt_deny_conn_t deny_hdr;       
99        rt_hello_t hello_opts;
100        uint8_t reason;
101       
102        if ((he=gethostbyname(RT_INFO->hostname)) == NULL) {
103                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
104                                "Failed to convert hostname %s to address",
105                                RT_INFO->hostname);
106                return -1;
107        }
108        if ((RT_INFO->input_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
109                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
110                                "Could not create socket");
111                return -1;
112        }
113
114        memset(&remote,0, sizeof(remote));
115        remote.sin_family = AF_INET;
116        remote.sin_port = htons(RT_INFO->port);
117        remote.sin_addr = *((struct in_addr *)he->h_addr);
118
119        if (connect(RT_INFO->input_fd, (struct sockaddr *)&remote,
120                                (socklen_t)sizeof(struct sockaddr)) == -1) {
121                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
122                                "Could not connect to host %s on port %d",
123                                RT_INFO->hostname, RT_INFO->port);
124                return -1;
125        }
126
127       
128#if 0
129        oldflags = fcntl(RT_INFO->input_fd, F_GETFL, 0);
130        if (oldflags == -1) {
131                trace_set_err(libtrace, errno,
132                                "Could not get fd flags from fd %d\n",
133                                RT_INFO->input_fd);
134                return -1;
135        }
136        oldflags |= O_NONBLOCK;
137        if (fcntl(RT_INFO->input_fd, F_SETFL, oldflags) == -1) {
138                trace_set_err(libtrace, errno,
139                                "Could not set fd flags for fd %d\n",
140                                RT_INFO->input_fd);
141                return -1;
142        }
143#endif
144       
145       
146        /* We are connected, now receive message from server */
147       
148        if (recv(RT_INFO->input_fd, (void*)&connect_msg, sizeof(rt_header_t), 0) != sizeof(rt_header_t) ) {
149                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
150                                "Could not receive connection message from %s",
151                                RT_INFO->hostname);
152                return -1;
153        }
154       
155        switch (connect_msg.type) {
156                case TRACE_RT_DENY_CONN:
157                       
158                        if (recv(RT_INFO->input_fd, (void*)&deny_hdr, 
159                                                sizeof(rt_deny_conn_t),
160                                                0) != sizeof(rt_deny_conn_t)) {
161                                reason = 0;
162                        }       
163                        reason = deny_hdr.reason;
164                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
165                                "Connection attempt is denied: %s",
166                                rt_deny_reason(reason));       
167                        return -1;
168                case TRACE_RT_HELLO:
169                        /* do something with options */
170                        if (recv(RT_INFO->input_fd, (void*)&hello_opts, 
171                                                sizeof(rt_hello_t), 0)
172                                        != sizeof(rt_hello_t)) {
173                                trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
174                                        "Failed to receive TRACE_RT_HELLO options");
175                                return -1;
176                        }
177                        RT_INFO->reliable = hello_opts.reliable;
178                       
179                        return 0;
180                default:
181                        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
182                                        "Unknown message type received: %d",
183                                        connect_msg.type);
184                        return -1;
185        }
186        trace_set_err(libtrace, TRACE_ERR_INIT_FAILED,
187                        "Somehow you managed to reach this unreachable code");
188        return -1;
189}
190
191
192static int rt_init_input(libtrace_t *libtrace) {
193        char *scan;
194        char *uridata = libtrace->uridata;
195        libtrace->format_data = malloc(sizeof(struct rt_format_data_t));
196
197        RT_INFO->dummy_duck = NULL;
198        RT_INFO->dummy_erf = NULL;
199        RT_INFO->dummy_pcap = NULL;
200        RT_INFO->dummy_wag = NULL;
201        RT_INFO->dummy_linux = NULL;
202        RT_INFO->pkt_buffer = NULL;
203        RT_INFO->buf_current = NULL;
204        RT_INFO->buf_filled = 0;
205       
206        if (strlen(uridata) == 0) {
207                RT_INFO->hostname =
208                        strdup("localhost");
209                RT_INFO->port =
210                        COLLECTOR_PORT;
211        } else {
212                if ((scan = strchr(uridata,':')) == NULL) {
213                        RT_INFO->hostname =
214                                strdup(uridata);
215                        RT_INFO->port =
216                                COLLECTOR_PORT;
217                } else {
218                        RT_INFO->hostname =
219                                (char *)strndup(uridata,
220                                                (size_t)(scan - uridata));
221                        RT_INFO->port =
222                                atoi(++scan);
223                }
224        }
225
226        return 0;
227}
228       
229static int rt_start_input(libtrace_t *libtrace) {
230        rt_header_t start_msg;
231
232        start_msg.type = TRACE_RT_START;
233        start_msg.length = 0; 
234
235        if (rt_connect(libtrace) == -1)
236                return -1;
237       
238        /* Need to send start message to server */
239        if (send(RT_INFO->input_fd, (void*)&start_msg, sizeof(rt_header_t) +
240                                start_msg.length, 0) != sizeof(rt_header_t)) {
241                printf("Failed to send start message to server\n");
242                return -1;
243        }
244        RT_INFO->rt_hdr.type = TRACE_RT_LAST;
245
246        return 0;
247}
248
249static int rt_pause_input(libtrace_t *libtrace) {
250        rt_header_t close_msg;
251
252        close_msg.type = TRACE_RT_CLOSE;
253        close_msg.length = 0; 
254       
255        /* Send a close message to the server */
256        if (send(RT_INFO->input_fd, (void*)&close_msg, sizeof(rt_header_t) + 
257                                close_msg.length, 0) != (int)sizeof(rt_header_t)
258                                + close_msg.length) {
259                printf("Failed to send close message to server\n");
260       
261        }
262
263        close(RT_INFO->input_fd);
264        return 0;
265}
266
267static int rt_fin_input(libtrace_t *libtrace) {
268        if (RT_INFO->dummy_duck)
269                trace_destroy_dead(RT_INFO->dummy_duck);
270
271        if (RT_INFO->dummy_erf) 
272                trace_destroy_dead(RT_INFO->dummy_erf);
273               
274        if (RT_INFO->dummy_pcap)
275                trace_destroy_dead(RT_INFO->dummy_pcap);
276
277        if (RT_INFO->dummy_wag)
278                trace_destroy_dead(RT_INFO->dummy_wag);
279
280        if (RT_INFO->dummy_linux)
281                trace_destroy_dead(RT_INFO->dummy_linux);
282        free(libtrace->format_data);
283        return 0;
284}
285
286#define RT_BUF_SIZE 4000U
287
288static int rt_read(libtrace_t *libtrace, void **buffer, size_t len, int block) 
289{
290        int numbytes;
291       
292        assert(len <= RT_BUF_SIZE);
293       
294        if (!RT_INFO->pkt_buffer) {
295                RT_INFO->pkt_buffer = (char*)malloc((size_t)RT_BUF_SIZE);
296                RT_INFO->buf_current = RT_INFO->pkt_buffer;
297                RT_INFO->buf_filled = 0;
298        }
299
300#ifndef MSG_DONTWAIT
301#define MSG_DONTWAIT 0
302#endif
303
304        if (block)
305                block=0;
306        else
307                block=MSG_DONTWAIT;
308
309       
310        if (len > RT_INFO->buf_filled) {
311                memcpy(RT_INFO->pkt_buffer, RT_INFO->buf_current, 
312                                RT_INFO->buf_filled);
313                RT_INFO->buf_current = RT_INFO->pkt_buffer;
314               
315#ifndef MSG_NOSIGNAL
316#  define MSG_NOSIGNAL 0
317#endif
318                while (len > RT_INFO->buf_filled) {
319                        if ((numbytes = recv(RT_INFO->input_fd,
320                                                RT_INFO->buf_current + 
321                                                RT_INFO->buf_filled,
322                                                RT_BUF_SIZE-RT_INFO->buf_filled,
323                                                MSG_NOSIGNAL|block)) <= 0) {
324                                if (numbytes == 0) {
325                                        trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 
326                                                        "No data received");
327                                        return -1;
328                                }
329                               
330                                if (errno == EINTR) {
331                                        /* ignore EINTR in case
332                                         * a caller is using signals
333                                         */
334                                        continue;
335                                }
336                                if (errno == EAGAIN) {
337                                        trace_set_err(libtrace,
338                                                        EAGAIN,
339                                                        "EAGAIN");
340                                        return -1;
341                                }
342                               
343                                perror("recv");
344                                trace_set_err(libtrace, errno,
345                                                "Failed to read data into rt recv buffer");
346                                return -1;
347                        }
348                        /*
349                        buf_ptr = RT_INFO->pkt_buffer;
350                        for (i = 0; i < RT_BUF_SIZE ; i++) {
351                                       
352                                printf("%02x", (unsigned char)*buf_ptr);
353                                buf_ptr ++;
354                        }
355                        printf("\n");
356                        */
357                        RT_INFO->buf_filled+=numbytes;
358                }
359
360        }
361        *buffer = RT_INFO->buf_current;
362        RT_INFO->buf_current += len;
363        RT_INFO->buf_filled -= len;
364        return len;
365}
366
367
368static int rt_set_format(libtrace_t *libtrace, libtrace_packet_t *packet) 
369{
370       
371        if (packet->type >= TRACE_RT_DATA_DLT) {
372                if (!RT_INFO->dummy_pcap) {
373                        RT_INFO->dummy_pcap = trace_create_dead("pcap:-");
374                }
375                packet->trace = RT_INFO->dummy_pcap;
376                return 0;       
377        }
378
379        switch (packet->type) {
380                case TRACE_RT_DUCK_2_4:
381                case TRACE_RT_DUCK_2_5:
382                        if (!RT_INFO->dummy_duck) {
383                                RT_INFO->dummy_duck = trace_create_dead("duck:dummy");
384                        }
385                        packet->trace = RT_INFO->dummy_duck;
386                        break;
387                case TRACE_RT_DATA_ERF:
388                        if (!RT_INFO->dummy_erf) {
389                                RT_INFO->dummy_erf = trace_create_dead("erf:-");
390                        }
391                        packet->trace = RT_INFO->dummy_erf;
392                        break;
393                case TRACE_RT_DATA_WAG:
394                        if (!RT_INFO->dummy_wag) {
395                                RT_INFO->dummy_wag = trace_create_dead("wtf:-");
396                        }
397                        packet->trace = RT_INFO->dummy_wag;
398                        break;
399                case TRACE_RT_DATA_LINUX_NATIVE:
400                        if (!RT_INFO->dummy_linux) {
401                                RT_INFO->dummy_linux = trace_create_dead("int:");
402                        }
403                        packet->trace = RT_INFO->dummy_linux;
404                        break;
405                case TRACE_RT_DATA_LEGACY_ETH:
406                case TRACE_RT_DATA_LEGACY_ATM:
407                case TRACE_RT_DATA_LEGACY_POS:
408                        printf("Sending legacy over RT is currently not supported\n");
409                        trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Legacy packet cannot be sent over rt");
410                        return -1;
411                default:
412                        printf("Unrecognised format: %d\n", packet->type);
413                        trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Unrecognised packet format");
414                        return -1;
415        }
416        return 0; /* success */
417}               
418
419static void rt_set_payload(libtrace_packet_t *packet) {
420        dag_record_t *erfptr;
421       
422        switch (packet->type) {
423                case TRACE_RT_DATA_ERF:
424                        erfptr = (dag_record_t *)packet->header;
425                       
426                        if (erfptr->flags.rxerror == 1) {
427                                packet->payload = NULL;
428                                break;
429                        }
430                        /* else drop into the default case */
431                default:
432                        packet->payload = (char *)packet->buffer +
433                                trace_get_framing_length(packet);
434                        break;
435        }
436}
437
438static int rt_send_ack(libtrace_t *libtrace, 
439                uint32_t seqno)  {
440       
441        static char *ack_buffer = 0;
442        char *buf_ptr;
443        int numbytes = 0;
444        size_t to_write = 0;
445        rt_header_t *hdr;
446        rt_ack_t *ack_hdr;
447       
448        if (!ack_buffer) {
449                ack_buffer = (char*)malloc(sizeof(rt_header_t) 
450                                                        + sizeof(rt_ack_t));
451        }
452       
453        hdr = (rt_header_t *) ack_buffer;
454        ack_hdr = (rt_ack_t *) (ack_buffer + sizeof(rt_header_t));
455       
456        hdr->type = TRACE_RT_ACK;
457        hdr->length = sizeof(rt_ack_t);
458
459        ack_hdr->sequence = seqno;
460       
461        to_write = hdr->length + sizeof(rt_header_t);
462        buf_ptr = ack_buffer;
463
464        while (to_write > 0) {
465                numbytes = send(RT_INFO->input_fd, buf_ptr, to_write, 0); 
466                if (numbytes == -1) {
467                        if (errno == EINTR || errno == EAGAIN) {
468                                continue;
469                        }
470                        else {
471                                printf("Error sending ack\n");
472                                perror("send");
473                                trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 
474                                                "Error sending ack");
475                                return -1;
476                        }
477                }
478                to_write = to_write - numbytes;
479                buf_ptr = buf_ptr + to_write;
480               
481        }
482
483        return 1;
484}
485
486       
487static int rt_read_packet_versatile(libtrace_t *libtrace,
488                libtrace_packet_t *packet,int blocking) {
489        rt_header_t *pkt_hdr = NULL;
490        void *void_hdr;
491       
492        if (packet->buf_control == TRACE_CTRL_PACKET) {
493                packet->buf_control = TRACE_CTRL_EXTERNAL;
494                free(packet->buffer);
495                packet->buffer = NULL;
496        }
497
498        /* RT_LAST means that the next bytes received should be a
499         * rt header - I know it's hax and maybe I'll fix it later on */
500        if (RT_INFO->rt_hdr.type == TRACE_RT_LAST) {
501                void_hdr = (void *)pkt_hdr;
502               
503                /* FIXME: Better error handling required */
504                if (rt_read(libtrace, &void_hdr, 
505                                sizeof(rt_header_t),blocking) !=
506                                sizeof(rt_header_t)) {
507                        return -1;
508                }
509                pkt_hdr = (rt_header_t *)void_hdr;
510               
511                /* Need to salvage these in case the next rt_read overwrites
512                 * the buffer they came from! */
513                RT_INFO->rt_hdr.type = pkt_hdr->type;
514                RT_INFO->rt_hdr.length = pkt_hdr->length;
515                RT_INFO->rt_hdr.sequence = pkt_hdr->sequence;
516        }
517        packet->type = RT_INFO->rt_hdr.type;
518
519        if (packet->type >= TRACE_RT_DATA_SIMPLE) {
520                if (rt_read(libtrace, 
521                                        &packet->buffer,
522                                        (size_t)RT_INFO->rt_hdr.length,
523                                        blocking) != RT_INFO->rt_hdr.length) {
524                        return -1;
525                }
526                packet->header = packet->buffer;
527               
528                if (RT_INFO->reliable > 0) {
529                        if (rt_send_ack(libtrace, RT_INFO->rt_hdr.sequence) 
530                                        == -1)
531                        {
532                                return -1;
533                        }
534                }
535               
536                       
537                if (rt_set_format(libtrace, packet) < 0) {
538                        return -1;
539                }
540                rt_set_payload(packet);
541        } else {
542                switch(packet->type) {
543                        case TRACE_RT_STATUS:
544                        case TRACE_RT_METADATA:
545                                if (rt_read(libtrace, &packet->buffer, 
546                                        (size_t)RT_INFO->rt_hdr.length,
547                                        blocking) != 
548                                                RT_INFO->rt_hdr.length) {
549                                        return -1;
550                                }
551                                packet->header = 0;
552                                packet->payload = packet->buffer;
553                                break;
554                        case TRACE_RT_DUCK_2_4:
555                        case TRACE_RT_DUCK_2_5:
556                                if (rt_read(libtrace, &packet->buffer,
557                                        (size_t)RT_INFO->rt_hdr.length,
558                                        blocking) != 
559                                                RT_INFO->rt_hdr.length) {
560                                        return -1;
561                                }
562                                if (rt_set_format(libtrace, packet) < 0) {
563                                        return -1;
564                                }
565                                packet->header = 0;
566                                packet->payload = packet->buffer;
567                                break;
568                        case TRACE_RT_END_DATA:
569                                break;
570                        case TRACE_RT_PAUSE_ACK:
571                                /* FIXME: Do something useful */
572                                break;
573                        case TRACE_RT_OPTION:
574                                /* FIXME: Do something useful here as well */
575                                break;
576                        case TRACE_RT_KEYCHANGE:
577                                break;
578                        case TRACE_RT_LOSTCONN:
579                                break;
580                        case TRACE_RT_SERVERSTART:
581                                break;
582                        case TRACE_RT_CLIENTDROP:
583                                break;
584                        default:
585                                printf("Bad rt type for client receipt: %d\n",
586                                        packet->type);
587                                return -1;
588                }
589        }
590        /* Return the number of bytes read from the stream */
591        RT_INFO->rt_hdr.type = TRACE_RT_LAST;
592        return RT_INFO->rt_hdr.length;
593}
594
595static int rt_read_packet(libtrace_t *libtrace,
596                libtrace_packet_t *packet) {
597        return rt_read_packet_versatile(libtrace,packet,1);
598}
599
600
601static int rt_get_capture_length(const libtrace_packet_t *packet) {
602        rt_metadata_t *rt_md_hdr;
603        switch (packet->type) {
604                case TRACE_RT_STATUS:
605                        return sizeof(rt_status_t);
606                case TRACE_RT_HELLO:
607                        return sizeof(rt_hello_t);
608                case TRACE_RT_START:
609                        return 0;
610                case TRACE_RT_ACK:
611                        return sizeof(rt_ack_t);
612                case TRACE_RT_END_DATA:
613                        return 0;
614                case TRACE_RT_CLOSE:
615                        return 0;
616                case TRACE_RT_DENY_CONN:
617                        return sizeof(rt_deny_conn_t);
618                case TRACE_RT_PAUSE:
619                        return 0; 
620                case TRACE_RT_PAUSE_ACK:
621                        return 0;
622                case TRACE_RT_OPTION:
623                        return 0; /* FIXME */
624                case TRACE_RT_KEYCHANGE:
625                        return 0;
626                case TRACE_RT_LOSTCONN:
627                        return 0;
628                case TRACE_RT_SERVERSTART:
629                        return 0;
630                case TRACE_RT_CLIENTDROP:
631                        return 0;
632                case TRACE_RT_METADATA:
633                        /* This is a little trickier to work out */
634                        rt_md_hdr = (rt_metadata_t *)packet->buffer;
635                        return rt_md_hdr->label_len + rt_md_hdr->value_len + 
636                                sizeof(rt_metadata_t);
637                default:
638                        printf("Unknown type: %d\n", packet->type);
639                       
640        }
641        return 0;
642}
643
644static int rt_get_wire_length(UNUSED const libtrace_packet_t *packet) {
645        return 0;
646}
647                       
648static int rt_get_framing_length(UNUSED const libtrace_packet_t *packet) {
649        return 0;
650}
651
652static int rt_get_fd(const libtrace_t *trace) {
653        return ((struct rt_format_data_t *)trace->format_data)->input_fd;
654}
655
656static libtrace_eventobj_t trace_event_rt(libtrace_t *trace,
657                                        libtrace_packet_t *packet) 
658{
659        libtrace_eventobj_t event = {0,0,0.0,0};
660        libtrace_err_t read_err;
661
662        assert(trace);
663        assert(packet);
664       
665        if (trace->format->get_fd) {
666                event.fd = trace->format->get_fd(trace);
667        } else {
668                event.fd = 0;
669        }
670
671        event.size = rt_read_packet_versatile(trace, packet, 0);
672        if (event.size == -1) {
673                read_err = trace_get_err(trace);
674                if (read_err.err_num == EAGAIN) {
675                        event.type = TRACE_EVENT_IOWAIT;
676                }
677                else {
678                        event.type = TRACE_EVENT_PACKET;
679                }
680        } else if (event.size == 0) {
681                if (packet->type == TRACE_RT_END_DATA)
682                        event.type = TRACE_EVENT_TERMINATE;
683                else
684                        event.type = TRACE_EVENT_PACKET;
685               
686        }       
687        else {
688                event.type = TRACE_EVENT_PACKET;
689        }
690       
691        return event;
692}
693
694static void rt_help(void) {
695        printf("rt format module\n");
696        printf("Supported input URIs:\n");
697        printf("\trt:hostname:port\n");
698        printf("\trt:hostname (connects on default port)\n");
699        printf("\n");
700        printf("\te.g.: rt:localhost\n");
701        printf("\te.g.: rt:localhost:32500\n");
702        printf("\n");
703
704}
705
706
707static struct libtrace_format_t rt = {
708        "rt",
709        "$Id$",
710        TRACE_FORMAT_RT,
711        rt_init_input,                  /* init_input */
712        NULL,                           /* config_input */
713        rt_start_input,                 /* start_input */
714        rt_pause_input,                 /* pause */
715        NULL,                           /* init_output */
716        NULL,                           /* config_output */
717        NULL,                           /* start_output */
718        rt_fin_input,                   /* fin_input */
719        NULL,                           /* fin_output */
720        rt_read_packet,                 /* read_packet */
721        NULL,                           /* fin_packet */
722        NULL,                           /* write_packet */
723        NULL,                           /* get_link_type */
724        NULL,                           /* get_direction */
725        NULL,                           /* set_direction */
726        NULL,                           /* get_erf_timestamp */
727        NULL,                           /* get_timeval */
728        NULL,                           /* get_seconds */
729        NULL,                           /* seek_erf */
730        NULL,                           /* seek_timeval */
731        NULL,                           /* seek_seconds */
732        rt_get_capture_length,          /* get_capture_length */
733        rt_get_wire_length,                     /* get_wire_length */
734        rt_get_framing_length,          /* get_framing_length */
735        NULL,                           /* set_capture_length */
736        rt_get_fd,                      /* get_fd */
737        trace_event_rt,             /* trace_event */
738        rt_help,                        /* help */
739        NULL                            /* next pointer */
740};
741
742void rt_constructor(void) {
743        register_format(&rt);
744}
Note: See TracBrowser for help on using the repository browser.