source: lib/format_rt.c @ 226c08b

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

Create a new "NonData?" link type for things that aren't data at all

  • Property mode set to 100644
File size: 20.2 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007,2008 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#include <unistd.h>
49
50#ifndef WIN32
51# include <netdb.h>
52#endif
53
54#define RT_INFO ((struct rt_format_data_t*)libtrace->format_data)
55
56static const char *rt_deny_reason(enum rt_conn_denied_t reason) 
57{
58        const char *string = 0;
59
60        switch(reason) {
61                case RT_DENY_WRAPPER:
62                        string = "Rejected by TCP Wrappers";
63                        break;
64                case RT_DENY_FULL:
65                        string = "Max connections reached on server";
66                        break;
67                case RT_DENY_AUTH:
68                        string = "Authentication failed";
69                        break;
70                default:
71                        string = "Unknown reason";
72        }
73
74        return string;
75}
76
77
78struct rt_format_data_t {
79        char *hostname;
80        char *pkt_buffer;
81        char *buf_current;
82        size_t buf_filled;
83        int port;
84        int input_fd;
85        int reliable;
86        rt_header_t rt_hdr;
87       
88        libtrace_t *dummy_duck;
89        libtrace_t *dummy_erf;
90        libtrace_t *dummy_pcap;
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
191static void rt_init_format_data(libtrace_t *libtrace) {
192        libtrace->format_data = malloc(sizeof(struct rt_format_data_t));
193
194        RT_INFO->dummy_duck = NULL;
195        RT_INFO->dummy_erf = NULL;
196        RT_INFO->dummy_pcap = NULL;
197        RT_INFO->dummy_linux = NULL;
198        RT_INFO->pkt_buffer = NULL;
199        RT_INFO->buf_current = NULL;
200        RT_INFO->buf_filled = 0;
201        RT_INFO->hostname = NULL;
202        RT_INFO->port = 0;
203}
204
205static int rt_init_input(libtrace_t *libtrace) {
206        char *scan;
207        char *uridata = libtrace->uridata;
208
209        rt_init_format_data(libtrace);
210       
211        if (strlen(uridata) == 0) {
212                RT_INFO->hostname =
213                        strdup("localhost");
214                RT_INFO->port =
215                        COLLECTOR_PORT;
216        } else {
217                if ((scan = strchr(uridata,':')) == NULL) {
218                        RT_INFO->hostname =
219                                strdup(uridata);
220                        RT_INFO->port =
221                                COLLECTOR_PORT;
222                } else {
223                        RT_INFO->hostname =
224                                (char *)strndup(uridata,
225                                                (size_t)(scan - uridata));
226                        RT_INFO->port =
227                                atoi(++scan);
228                }
229        }
230
231        return 0;
232}
233       
234static int rt_start_input(libtrace_t *libtrace) {
235        rt_header_t start_msg;
236
237        start_msg.type = TRACE_RT_START;
238        start_msg.length = 0; 
239
240        if (rt_connect(libtrace) == -1)
241                return -1;
242       
243        /* Need to send start message to server */
244        if (send(RT_INFO->input_fd, (void*)&start_msg, sizeof(rt_header_t) +
245                                start_msg.length, 0) != sizeof(rt_header_t)) {
246                printf("Failed to send start message to server\n");
247                return -1;
248        }
249        RT_INFO->rt_hdr.type = TRACE_RT_LAST;
250
251        return 0;
252}
253
254static int rt_pause_input(libtrace_t *libtrace) {
255        rt_header_t close_msg;
256
257        close_msg.type = TRACE_RT_CLOSE;
258        close_msg.length = 0; 
259       
260        /* Send a close message to the server */
261        if (send(RT_INFO->input_fd, (void*)&close_msg, sizeof(rt_header_t) + 
262                                close_msg.length, 0) != (int)sizeof(rt_header_t)
263                                + close_msg.length) {
264                printf("Failed to send close message to server\n");
265       
266        }
267
268        close(RT_INFO->input_fd);
269        return 0;
270}
271
272static int rt_fin_input(libtrace_t *libtrace) {
273        if (RT_INFO->dummy_duck)
274                trace_destroy_dead(RT_INFO->dummy_duck);
275
276        if (RT_INFO->dummy_erf) 
277                trace_destroy_dead(RT_INFO->dummy_erf);
278               
279        if (RT_INFO->dummy_pcap)
280                trace_destroy_dead(RT_INFO->dummy_pcap);
281
282        if (RT_INFO->dummy_linux)
283                trace_destroy_dead(RT_INFO->dummy_linux);
284        free(libtrace->format_data);
285        return 0;
286}
287
288
289/* I've upped this to 10K to deal with jumbo-grams that have not been snapped
290 * in any way. This means we have a much larger memory overhead per packet
291 * (which won't be used in the vast majority of cases), so we may want to think
292 * about doing something smarter, e.g. allocate a smaller block of memory and
293 * only increase it as required.
294 *
295 * XXX Capturing off int: can still lead to packets that are larger than 10K,
296 * in instances where the fragmentation is done magically by the NIC. This
297 * is pretty nasty, but also very rare.
298 */
299#define RT_BUF_SIZE 10000U
300
301static int rt_read(libtrace_t *libtrace, void **buffer, size_t len, int block) 
302{
303        int numbytes;
304       
305        assert(len <= RT_BUF_SIZE);
306       
307        if (!RT_INFO->pkt_buffer) {
308                RT_INFO->pkt_buffer = (char*)malloc((size_t)RT_BUF_SIZE);
309                RT_INFO->buf_current = RT_INFO->pkt_buffer;
310                RT_INFO->buf_filled = 0;
311        }
312
313#ifndef MSG_DONTWAIT
314#define MSG_DONTWAIT 0
315#endif
316
317        if (block)
318                block=0;
319        else
320                block=MSG_DONTWAIT;
321
322       
323        if (len > RT_INFO->buf_filled) {
324                memcpy(RT_INFO->pkt_buffer, RT_INFO->buf_current, 
325                                RT_INFO->buf_filled);
326                RT_INFO->buf_current = RT_INFO->pkt_buffer;
327#ifndef MSG_NOSIGNAL
328#  define MSG_NOSIGNAL 0
329#endif
330                while (len > RT_INFO->buf_filled) {
331                        if ((numbytes = recv(RT_INFO->input_fd,
332                                                RT_INFO->buf_current + 
333                                                RT_INFO->buf_filled,
334                                                RT_BUF_SIZE-RT_INFO->buf_filled,
335                                                MSG_NOSIGNAL|block)) <= 0) {
336                                if (numbytes == 0) {
337                                        trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 
338                                                        "No data received");
339                                        return -1;
340                                }
341                               
342                                if (errno == EINTR) {
343                                        /* ignore EINTR in case
344                                         * a caller is using signals
345                                         */
346                                        continue;
347                                }
348                                if (errno == EAGAIN) {
349                                        trace_set_err(libtrace,
350                                                        EAGAIN,
351                                                        "EAGAIN");
352                                        return -1;
353                                }
354                               
355                                perror("recv");
356                                trace_set_err(libtrace, errno,
357                                                "Failed to read data into rt recv buffer");
358                                return -1;
359                        }
360                        /*
361                        buf_ptr = RT_INFO->pkt_buffer;
362                        for (i = 0; i < RT_BUF_SIZE ; i++) {
363                                       
364                                printf("%02x", (unsigned char)*buf_ptr);
365                                buf_ptr ++;
366                        }
367                        printf("\n");
368                        */
369                        RT_INFO->buf_filled+=numbytes;
370                }
371
372        }
373        *buffer = RT_INFO->buf_current;
374        RT_INFO->buf_current += len;
375        RT_INFO->buf_filled -= len;
376        return len;
377}
378
379
380static int rt_set_format(libtrace_t *libtrace, libtrace_packet_t *packet) 
381{
382
383        /* Try to minimize the number of corrupt packets that slip through
384         * while making it easy to identify new pcap DLTs */
385        if (packet->type > TRACE_RT_DATA_DLT && 
386                        packet->type < TRACE_RT_DATA_DLT_END) {
387                if (!RT_INFO->dummy_pcap) {
388                        RT_INFO->dummy_pcap = trace_create_dead("pcap:-");
389                }
390                packet->trace = RT_INFO->dummy_pcap;
391                return 0;       
392        }
393
394        switch (packet->type) {
395                case TRACE_RT_DUCK_2_4:
396                case TRACE_RT_DUCK_2_5:
397                        if (!RT_INFO->dummy_duck) {
398                                RT_INFO->dummy_duck = trace_create_dead("duck:dummy");
399                        }
400                        packet->trace = RT_INFO->dummy_duck;
401                        break;
402                case TRACE_RT_DATA_ERF:
403                        if (!RT_INFO->dummy_erf) {
404                                RT_INFO->dummy_erf = trace_create_dead("erf:-");
405                        }
406                        packet->trace = RT_INFO->dummy_erf;
407                        break;
408                case TRACE_RT_DATA_LINUX_NATIVE:
409                        if (!RT_INFO->dummy_linux) {
410                                RT_INFO->dummy_linux = trace_create_dead("int:");
411                        }
412                        packet->trace = RT_INFO->dummy_linux;
413                        break;
414                case TRACE_RT_STATUS:
415                case TRACE_RT_METADATA:
416                        /* Just use the RT trace! */
417                        packet->trace = libtrace;
418                        break;
419                case TRACE_RT_DATA_LEGACY_ETH:
420                case TRACE_RT_DATA_LEGACY_ATM:
421                case TRACE_RT_DATA_LEGACY_POS:
422                        printf("Sending legacy over RT is currently not supported\n");
423                        trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Legacy packet cannot be sent over rt");
424                        return -1;
425                default:
426                        printf("Unrecognised format: %u\n", packet->type);
427                        trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, "Unrecognised packet format");
428                        return -1;
429        }
430        return 0; /* success */
431}               
432
433static int rt_send_ack(libtrace_t *libtrace, 
434                uint32_t seqno)  {
435       
436        static char *ack_buffer = 0;
437        char *buf_ptr;
438        int numbytes = 0;
439        size_t to_write = 0;
440        rt_header_t *hdr;
441        rt_ack_t *ack_hdr;
442       
443        if (!ack_buffer) {
444                ack_buffer = (char*)malloc(sizeof(rt_header_t) 
445                                                        + sizeof(rt_ack_t));
446        }
447       
448        hdr = (rt_header_t *) ack_buffer;
449        ack_hdr = (rt_ack_t *) (ack_buffer + sizeof(rt_header_t));
450       
451        hdr->type = TRACE_RT_ACK;
452        hdr->length = sizeof(rt_ack_t);
453
454        ack_hdr->sequence = seqno;
455       
456        to_write = hdr->length + sizeof(rt_header_t);
457        buf_ptr = ack_buffer;
458
459        while (to_write > 0) {
460                numbytes = send(RT_INFO->input_fd, buf_ptr, to_write, 0); 
461                if (numbytes == -1) {
462                        if (errno == EINTR || errno == EAGAIN) {
463                                continue;
464                        }
465                        else {
466                                printf("Error sending ack\n");
467                                perror("send");
468                                trace_set_err(libtrace, TRACE_ERR_BAD_PACKET, 
469                                                "Error sending ack");
470                                return -1;
471                        }
472                }
473                to_write = to_write - numbytes;
474                buf_ptr = buf_ptr + to_write;
475               
476        }
477
478        return 1;
479}
480
481static int rt_prepare_packet(libtrace_t *libtrace, libtrace_packet_t *packet,
482                void *buffer, libtrace_rt_types_t rt_type, uint32_t flags) {
483
484        if (packet->buffer != buffer &&
485                        packet->buf_control == TRACE_CTRL_PACKET) {
486                free(packet->buffer);
487        }
488
489        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
490                packet->buf_control = TRACE_CTRL_PACKET;
491        } else
492                packet->buf_control = TRACE_CTRL_EXTERNAL;
493
494
495        packet->buffer = buffer;
496        packet->header = NULL;
497        packet->type = rt_type;
498        packet->payload = buffer;
499
500        if (libtrace->format_data == NULL) {
501                rt_init_format_data(libtrace);
502        }
503
504        return 0;
505}       
506
507static int rt_read_data_packet(libtrace_t *libtrace,
508                libtrace_packet_t *packet, int blocking) {
509        uint32_t prep_flags = 0;
510
511        prep_flags |= TRACE_PREP_DO_NOT_OWN_BUFFER;
512
513        if (rt_read(libtrace, &packet->buffer, (size_t)RT_INFO->rt_hdr.length, 
514                                blocking) != RT_INFO->rt_hdr.length) {
515                return -1;
516        }
517
518        if (RT_INFO->reliable > 0 && packet->type >= TRACE_RT_DATA_SIMPLE) {
519                if (rt_send_ack(libtrace, RT_INFO->rt_hdr.sequence) == -1)
520                                return -1;
521        }
522       
523        if (rt_set_format(libtrace, packet) < 0) {
524                return -1;
525        }
526               
527        /* Update payload pointers and loss counters correctly */
528        if (trace_prepare_packet(packet->trace, packet, packet->buffer,
529                                packet->type, prep_flags)) {
530                return -1;
531        }
532
533        return 0;
534}
535
536static int rt_read_packet_versatile(libtrace_t *libtrace,
537                libtrace_packet_t *packet,int blocking) {
538        rt_header_t *pkt_hdr = NULL;
539        void *void_hdr;
540        libtrace_rt_types_t switch_type;
541       
542        if (packet->buf_control == TRACE_CTRL_PACKET) {
543                packet->buf_control = TRACE_CTRL_EXTERNAL;
544                free(packet->buffer);
545                packet->buffer = NULL;
546        }
547
548        /* RT_LAST means that the next bytes received should be a
549         * rt header - I know it's hax and maybe I'll fix it later on */
550        if (RT_INFO->rt_hdr.type == TRACE_RT_LAST) {
551                void_hdr = (void *)pkt_hdr;
552                /* FIXME: Better error handling required */
553                if (rt_read(libtrace, &void_hdr, 
554                                sizeof(rt_header_t),blocking) !=
555                                sizeof(rt_header_t)) {
556                        return -1;
557                }
558                pkt_hdr = (rt_header_t *)void_hdr;
559               
560                /* Need to salvage these in case the next rt_read overwrites
561                 * the buffer they came from! */
562                RT_INFO->rt_hdr.type = pkt_hdr->type;
563                RT_INFO->rt_hdr.length = pkt_hdr->length;
564                RT_INFO->rt_hdr.sequence = pkt_hdr->sequence;
565        }
566        packet->type = RT_INFO->rt_hdr.type;
567       
568        if (packet->type >= TRACE_RT_DATA_SIMPLE) {
569                switch_type = TRACE_RT_DATA_SIMPLE;
570        } else {
571                switch_type = packet->type;
572        }
573
574        switch(switch_type) {
575                case TRACE_RT_DATA_SIMPLE:
576                case TRACE_RT_DUCK_2_4:
577                case TRACE_RT_DUCK_2_5:
578                case TRACE_RT_STATUS:
579                case TRACE_RT_METADATA:
580                        if (rt_read_data_packet(libtrace, packet, blocking))
581                                return -1;
582                        break;
583                case TRACE_RT_END_DATA:
584                case TRACE_RT_KEYCHANGE:
585                case TRACE_RT_LOSTCONN:
586                case TRACE_RT_CLIENTDROP:
587                case TRACE_RT_SERVERSTART:
588                        /* All these have no payload */
589                        break;
590                case TRACE_RT_PAUSE_ACK:
591                        /* XXX: Add support for this */
592                        break;
593                case TRACE_RT_OPTION:
594                        /* XXX: Add support for this */
595                        break;
596                default:
597                        printf("Bad rt type for client receipt: %d\n",
598                                        switch_type);
599                        return -1;
600        }
601                               
602                       
603               
604        /* Return the number of bytes read from the stream */
605        RT_INFO->rt_hdr.type = TRACE_RT_LAST;
606        return RT_INFO->rt_hdr.length + sizeof(rt_header_t);
607}
608
609static int rt_read_packet(libtrace_t *libtrace,
610                libtrace_packet_t *packet) {
611        return rt_read_packet_versatile(libtrace,packet,1);
612}
613
614
615static int rt_get_capture_length(const libtrace_packet_t *packet) {
616        rt_metadata_t *rt_md_hdr;
617        switch (packet->type) {
618                case TRACE_RT_STATUS:
619                        return sizeof(rt_status_t);
620                case TRACE_RT_HELLO:
621                        return sizeof(rt_hello_t);
622                case TRACE_RT_START:
623                        return 0;
624                case TRACE_RT_ACK:
625                        return sizeof(rt_ack_t);
626                case TRACE_RT_END_DATA:
627                        return 0;
628                case TRACE_RT_CLOSE:
629                        return 0;
630                case TRACE_RT_DENY_CONN:
631                        return sizeof(rt_deny_conn_t);
632                case TRACE_RT_PAUSE:
633                        return 0; 
634                case TRACE_RT_PAUSE_ACK:
635                        return 0;
636                case TRACE_RT_OPTION:
637                        return 0; /* FIXME */
638                case TRACE_RT_KEYCHANGE:
639                        return 0;
640                case TRACE_RT_LOSTCONN:
641                        return 0;
642                case TRACE_RT_SERVERSTART:
643                        return 0;
644                case TRACE_RT_CLIENTDROP:
645                        return 0;
646                case TRACE_RT_METADATA:
647                        /* This is a little trickier to work out */
648                        rt_md_hdr = (rt_metadata_t *)packet->buffer;
649                        return rt_md_hdr->label_len + rt_md_hdr->value_len + 
650                                sizeof(rt_metadata_t);
651                default:
652                        printf("Unknown type: %d\n", packet->type);
653                       
654        }
655        return 0;
656}
657
658static int rt_get_wire_length(UNUSED const libtrace_packet_t *packet) {
659        return 0;
660}
661                       
662static int rt_get_framing_length(UNUSED const libtrace_packet_t *packet) {
663        return 0;
664}
665
666static libtrace_linktype_t rt_get_link_type(UNUSED const libtrace_packet_t *packet)
667{
668        return TRACE_TYPE_NONDATA;
669}
670
671static int rt_get_fd(const libtrace_t *trace) {
672        return ((struct rt_format_data_t *)trace->format_data)->input_fd;
673}
674
675static libtrace_eventobj_t trace_event_rt(libtrace_t *trace,
676                                        libtrace_packet_t *packet) 
677{
678        libtrace_eventobj_t event = {0,0,0.0,0};
679        libtrace_err_t read_err;
680
681        assert(trace);
682        assert(packet);
683       
684        if (trace->format->get_fd) {
685                event.fd = trace->format->get_fd(trace);
686        } else {
687                event.fd = 0;
688        }
689
690        event.size = rt_read_packet_versatile(trace, packet, 0);
691        if (event.size == -1) {
692                read_err = trace_get_err(trace);
693                if (read_err.err_num == EAGAIN) {
694                        event.type = TRACE_EVENT_IOWAIT;
695                }
696                else {
697                        event.type = TRACE_EVENT_PACKET;
698                }
699        } else if (event.size == 0) {
700                if (packet->type == TRACE_RT_END_DATA)
701                        event.type = TRACE_EVENT_TERMINATE;
702                else
703                        event.type = TRACE_EVENT_PACKET;
704               
705        }       
706        else {
707                event.type = TRACE_EVENT_PACKET;
708        }
709
710       
711        return event;
712}
713
714static void rt_help(void) {
715        printf("rt format module\n");
716        printf("Supported input URIs:\n");
717        printf("\trt:hostname:port\n");
718        printf("\trt:hostname (connects on default port)\n");
719        printf("\n");
720        printf("\te.g.: rt:localhost\n");
721        printf("\te.g.: rt:localhost:32500\n");
722        printf("\n");
723
724}
725
726
727static struct libtrace_format_t rt = {
728        "rt",
729        "$Id$",
730        TRACE_FORMAT_RT,
731        NULL,                           /* probe filename */
732        NULL,                           /* probe magic */
733        rt_init_input,                  /* init_input */
734        NULL,                           /* config_input */
735        rt_start_input,                 /* start_input */
736        rt_pause_input,                 /* pause */
737        NULL,                           /* init_output */
738        NULL,                           /* config_output */
739        NULL,                           /* start_output */
740        rt_fin_input,                   /* fin_input */
741        NULL,                           /* fin_output */
742        rt_read_packet,                 /* read_packet */
743        rt_prepare_packet,              /* prepare_packet */
744        NULL,                           /* fin_packet */
745        NULL,                           /* write_packet */
746        rt_get_link_type,               /* get_link_type */
747        NULL,                           /* get_direction */
748        NULL,                           /* set_direction */
749        NULL,                           /* get_erf_timestamp */
750        NULL,                           /* get_timeval */
751        NULL,                           /* get_timespec */
752        NULL,                           /* get_seconds */
753        NULL,                           /* seek_erf */
754        NULL,                           /* seek_timeval */
755        NULL,                           /* seek_seconds */
756        rt_get_capture_length,          /* get_capture_length */
757        rt_get_wire_length,                     /* get_wire_length */
758        rt_get_framing_length,          /* get_framing_length */
759        NULL,                           /* set_capture_length */
760        NULL,                           /* get_received_packets */
761        NULL,                           /* get_filtered_packets */
762        NULL,                           /* get_dropped_packets */
763        NULL,                           /* get_captured_packets */
764        rt_get_fd,                      /* get_fd */
765        trace_event_rt,             /* trace_event */
766        rt_help,                        /* help */
767        NULL                            /* next pointer */
768};
769
770void rt_constructor(void) {
771        register_format(&rt);
772}
Note: See TracBrowser for help on using the repository browser.