source: lib/format_wag.c @ 79dbcef

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 79dbcef was 79dbcef, checked in by Daniel Lawson <dlawson@…>, 16 years ago

wrapped stdin and stdout in fileno() when passing to LIBTRACE_FDOPEN

  • Property mode set to 100644
File size: 10.9 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30
31#define _GNU_SOURCE
32#include "config.h"
33#include "common.h"
34#include "libtrace.h"
35#include "libtrace_int.h"
36#include "format_helper.h"
37#include "wag.h"
38
39#ifdef HAVE_INTTYPES_H
40#  include <inttypes.h>
41#else
42#  error "Can't find inttypes.h - this needs to be fixed"
43#endif
44
45#ifdef HAVE_STDDEF_H
46#  include <stddef.h>
47#else
48# error "Can't find stddef.h - do you define ptrdiff_t elsewhere?"
49#endif
50#include <sys/types.h>
51#include <sys/time.h>
52#include <time.h>
53#include <sys/socket.h>
54#include <sys/un.h>
55#include <sys/mman.h>
56#include <sys/stat.h>
57#include <fcntl.h>
58#include <unistd.h>
59#include <assert.h>
60#include <errno.h>
61#include <netdb.h>
62#include <stdio.h>
63#include <string.h>
64#include <stdlib.h>
65
66#ifdef HAVE_LIMITS_H
67#  include <limits.h>
68#endif
69
70#ifdef HAVE_SYS_LIMITS_H
71#  include <sys/limits.h>
72#endif
73
74#ifndef O_LARGEFILE
75#define O_LARGEFILE 0
76#endif
77
78static struct libtrace_format_t wag;
79
80#define CONNINFO libtrace->format_data->conn_info
81#define INPUT libtrace->format_data->input
82#define OUTPUT libtrace->format_data->output
83#define OPTIONS libtrace->format_data->options
84
85struct libtrace_format_data_t {
86        union {
87                /** Information about rtclients */
88                struct {
89                        char *hostname;
90                        short port;
91                } rt;
92                char *path;             /**< information for local sockets */
93        } conn_info;
94        /** Information about the current state of the input device */
95        union {
96                int fd;
97#if HAVE_ZLIB
98                gzFile *file;
99#else   
100                //FILE *file;
101                int file;
102#endif
103        } input;       
104};
105
106struct libtrace_format_data_out_t {
107        union {
108                char *path;
109        } conn_info;
110        union {
111                struct {
112                        int level;
113                } zlib;
114        } options;
115        union {
116                int fd;
117#if HAVE_ZLIB
118                gzFile *file;
119#else
120                //FILE *file;
121                int file;
122#endif
123        } output;
124};
125
126static int wag_init_input(struct libtrace_t *libtrace) {
127        struct stat buf;
128        struct sockaddr_un unix_sock;
129        libtrace->format_data = (struct libtrace_format_data_t *) 
130                calloc(1,sizeof(struct libtrace_format_data_t));
131        CONNINFO.path = libtrace->uridata;
132        if (!strncmp(CONNINFO.path,"-",1)) {
133                // STDIN
134                libtrace->sourcetype = STDIN;
135                INPUT.file = LIBTRACE_FDOPEN(fileno(stdin),"r");
136
137        } else {
138                if (stat(CONNINFO.path,&buf) == -1 ) {
139                        perror("stat");
140                        return 0;
141                }
142                if (S_ISSOCK(buf.st_mode)) {
143                        libtrace->sourcetype = SOCKET;
144                        // SOCKET
145                        if ((INPUT.fd = socket(
146                                        AF_UNIX, SOCK_STREAM, 0)) == -1) {
147                                perror("socket");
148                                return 0;
149                        }
150                        unix_sock.sun_family = AF_UNIX;
151                        bzero(unix_sock.sun_path,108);
152                        snprintf(unix_sock.sun_path,
153                                        108,"%s"
154                                        ,CONNINFO.path);
155
156                        if (connect(INPUT.fd, 
157                                        (struct sockaddr *)&unix_sock,
158                                        sizeof(struct sockaddr)) == -1) {
159                                perror("connect (unix)");
160                                return 0;
161                        }
162                } else { 
163                        // TRACE
164                        libtrace->sourcetype = TRACE;
165                       
166                        // we use an FDOPEN call to reopen an FD
167                        // returned from open(), so that we can set
168                        // O_LARGEFILE. This gets around gzopen not
169                        // letting you do this...
170                        INPUT.file = LIBTRACE_FDOPEN(open(
171                                        CONNINFO.path,
172                                        O_LARGEFILE), "r");
173
174                }
175        }
176        return 1;
177}
178
179static int wag_init_output(struct libtrace_out_t *libtrace) {
180        char *filemode = 0;
181        libtrace->format_data = (struct libtrace_format_data_out_t *)
182                calloc(1,sizeof(struct libtrace_format_data_out_t));
183
184        OPTIONS.zlib.level = 0;
185        asprintf(&filemode,"wb%d",OPTIONS.zlib.level);
186        if (!strncmp(libtrace->uridata,"-",1)) {
187                // STDOUT                               
188                OUTPUT.file = LIBTRACE_FDOPEN(dup(1), filemode);
189        } else {
190                // TRACE
191                OUTPUT.file = LIBTRACE_FDOPEN(open(
192                                        libtrace->uridata,
193                                        O_CREAT | O_LARGEFILE | O_WRONLY,
194                                        S_IRUSR | S_IWUSR), filemode);
195        }
196
197        return 1;
198}
199
200static int wag_config_output(struct libtrace_out_t *libtrace, int argc, char *argv[]) {
201#if HAVE_ZLIB
202        int opt;
203        int level = OPTIONS.zlib.level;
204        optind = 1;
205        while ((opt = getopt(argc, argv, "z:")) != EOF) {
206                switch (opt) {
207                        case 'z':
208                                level = atoi(optarg);
209                                break;
210                        default:
211                                printf("Bad argument to wag: %s\n", optarg);
212                                return -1;
213                }
214        }
215        if (level != OPTIONS.zlib.level) {
216                if (level > 9 || level < 0) {
217                        // retarded level choice
218                        printf("Compression level must be between 0 and 9 inclusive - you selected %i \n", level);
219                } else {
220                        OPTIONS.zlib.level = level;
221                        return gzsetparams(OUTPUT.file, level, Z_DEFAULT_STRATEGY);
222                }
223        }
224#endif
225        return 0;
226}
227
228static int wag_fin_input(struct libtrace_t *libtrace) {
229        LIBTRACE_CLOSE(INPUT.file);
230        return 0;
231}
232
233static int wag_fin_output(struct libtrace_out_t *libtrace) {
234        LIBTRACE_CLOSE(OUTPUT.file);
235        return 0;
236}
237
238static int wag_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
239        int numbytes;
240        assert(libtrace);
241
242        if (buffer == 0)
243                buffer = malloc(len);
244
245        while(1) {
246                switch(libtrace->sourcetype) {
247                        case DEVICE:
248                                if ((numbytes=read(INPUT.fd, 
249                                                                buffer, 
250                                                                len)) == -1) {
251                                        perror("read");
252                                        return -1;
253                                }
254                                break;
255                        default:
256                                if ((numbytes=LIBTRACE_READ(INPUT.file,
257                                                                buffer,
258                                                                len)) == -1) {
259                                        perror("libtrace_read");
260                                        return -1;
261                                }
262                }
263                break;
264        }
265        return numbytes;
266
267}
268
269
270static int wag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
271        int numbytes;
272        int size;
273        char buf[RP_BUFSIZE];
274        int read_required = 0;
275
276        void *buffer = 0;
277
278        packet->trace = libtrace;
279        buffer = packet->buffer;
280       
281
282        do {
283                if (tracefifo_out_available(libtrace->fifo) == 0 || read_required) {
284                        if ((numbytes = wag_read(libtrace,buf,RP_BUFSIZE)) <= 0) {
285                                return numbytes;
286                        }
287                        assert(libtrace->fifo);
288                        tracefifo_write(libtrace->fifo,buf,numbytes);
289                        read_required = 0;
290                }
291                // read in wag_frame_hdr
292                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
293                                                buffer,
294                                                sizeof(struct wag_frame_hdr)))
295                                == 0 ) {
296                        tracefifo_out_reset(libtrace->fifo);
297                        read_required = 1;
298                        continue;
299                }
300               
301                size = ntohs(((struct wag_frame_hdr *)buffer)->size);
302
303                // wag isn't in network byte order yet
304                //size = htons(size);
305                //printf("%d %d\n",size,htons(size));
306
307                // read in full packet
308                if((numbytes = tracefifo_out_read(libtrace->fifo,buffer,size)) == 0) {
309                        tracefifo_out_reset(libtrace->fifo);
310                        read_required = 1;
311                        continue;
312                }
313
314                // have the whole packet
315                tracefifo_out_update(libtrace->fifo,size);
316                tracefifo_ack_update(libtrace->fifo,size);
317
318                packet->status.type = RT_DATA;
319                packet->status.message = 0;
320                packet->size = numbytes;
321                return numbytes;
322        } while(1);
323}
324
325static int wag_write_packet(struct libtrace_out_t *libtrace, const struct libtrace_packet_t *packet) {
326        int numbytes =0 ;
327        if (packet->trace->format != &wag) {
328                fprintf(stderr,"Cannot convert from wag to %s format yet\n",
329                                packet->trace->format->name);
330                return -1;
331        }
332        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, packet->buffer, packet->size)) == 0) {
333                perror("libtrace_write");
334                return -1;
335        }
336        return numbytes;
337}
338
339static void *wag_get_link(const struct libtrace_packet_t *packet) {
340        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
341        void *payload = wagptr->data;
342        return (void*)payload;
343}
344
345static libtrace_linktype_t wag_get_link_type(const struct libtrace_packet_t *packet __attribute__((unused))) {
346        return TRACE_TYPE_80211;
347}
348
349static int8_t wag_get_direction(const struct libtrace_packet_t *packet) {
350        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
351        if (wagptr->hdr.type == 0) {
352                return wagptr->hdr.subtype;
353        }
354        return -1;
355}
356
357static uint64_t wag_get_erf_timestamp(const struct libtrace_packet_t *packet) {
358        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
359        uint64_t timestamp = 0;
360        timestamp = wagptr->ts.subsecs;
361        //timestamp |= (uint64_t)wagptr->ts.secs<<32;
362        timestamp = ((timestamp%44000000)*(UINT_MAX/44000000)) 
363                | ((timestamp/44000000)<<32);
364        return timestamp;
365}
366
367static int wag_get_capture_length(const struct libtrace_packet_t *packet) {
368        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
369        //return (wagptr->hdr.size);
370        return ntohs(wagptr->hdr.size);
371}
372
373static int wag_get_wire_length(const struct libtrace_packet_t *packet) {
374        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
375        //return (wagptr->hdr.size);
376        return ntohs(wagptr->hdr.size);
377}
378
379static int wag_get_framing_length(const struct libtrace_packet_t *packet) {
380        return sizeof(struct wag_data_frame);
381}
382
383static int wag_get_fd(const struct libtrace_packet_t *packet) {
384        return packet->trace->format_data->input.fd;
385}
386
387static struct libtrace_eventobj_t wag_event_trace(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
388        switch(trace->sourcetype) {
389                case DEVICE:
390                        return trace_event_device(trace,packet);
391                default:
392                        return trace_event_trace(trace,packet);
393        }
394}
395static void wag_help() {
396        printf("wag format module: $Revision$\n");
397        printf("Supported input URIs:\n");
398        printf("\twag:/dev/wagn\n");
399        printf("\twag:/path/to/trace.wag\n");
400        printf("\twag:/path/to/trace.wag.gz\n");
401        printf("\n");
402        printf("\te.g.: wag:/dev/wag0\n");
403        printf("\te.g.: wag:/tmp/trace.wag.gz\n");
404        printf("\n");
405        printf("Supported output URIs:\n");
406        printf("\tnone\n");
407        printf("\n");
408}
409
410static struct libtrace_format_t wag = {
411        "wag",
412        "$Id$",
413        "wag",
414        wag_init_input,                 /* init_input */       
415        wag_init_output,                /* init_output */
416        wag_config_output,              /* config_output */
417        wag_fin_input,                  /* fin_input */
418        wag_fin_output,                 /* fin_output */
419        wag_read_packet,                /* read_packet */
420        wag_write_packet,               /* write_packet */
421        wag_get_link,                   /* get_link */
422        wag_get_link_type,              /* get_link_type */
423        wag_get_direction,              /* get_direction */
424        NULL,                           /* set_direction */
425        wag_get_erf_timestamp,          /* get_erf_timestamp */
426        NULL,                           /* get_timeval */
427        NULL,                           /* get_seconds */
428        wag_get_capture_length,         /* get_capture_length */
429        wag_get_wire_length,            /* get_wire_length */
430        wag_get_framing_length,         /* get_framing_length */
431        NULL,                           /* set_capture_length */
432        wag_get_fd,                     /* get_fd */
433        wag_event_trace,                /* trace_event */
434        wag_help                        /* help */
435};
436
437void __attribute__((constructor)) wag_constructor() {
438        register_format(&wag);
439}
Note: See TracBrowser for help on using the repository browser.