source: lib/format_wag.c @ 0ef6536

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

Fixed minor bit-shifting problem with get_erf_timestamp

  • Property mode set to 100644
File size: 11.2 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        if (packet->buf_control == EXTERNAL) {
279                packet->buf_control = PACKET;
280                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
281        }
282        packet->trace = libtrace;
283        buffer = packet->buffer;
284       
285
286        do {
287                if (tracefifo_out_available(libtrace->fifo) == 0 || read_required) {
288                        if ((numbytes = wag_read(libtrace,buf,RP_BUFSIZE)) <= 0) {
289                                return numbytes;
290                        }
291                        assert(libtrace->fifo);
292                        tracefifo_write(libtrace->fifo,buf,numbytes);
293                        read_required = 0;
294                }
295                // read in wag_frame_hdr
296                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
297                                                buffer,
298                                                sizeof(struct wag_frame_hdr)))
299                                == 0 ) {
300                        tracefifo_out_reset(libtrace->fifo);
301                        read_required = 1;
302                        continue;
303                }
304               
305                size = ntohs(((struct wag_frame_hdr *)buffer)->size);
306
307                // wag isn't in network byte order yet
308                //size = htons(size);
309                //printf("%d %d\n",size,htons(size));
310
311                // read in full packet
312                if((numbytes = tracefifo_out_read(libtrace->fifo,buffer,size)) == 0) {
313                        tracefifo_out_reset(libtrace->fifo);
314                        read_required = 1;
315                        continue;
316                }
317
318                // have the whole packet
319                tracefifo_out_update(libtrace->fifo,size);
320                tracefifo_ack_update(libtrace->fifo,size);
321
322                packet->status.type = RT_DATA;
323                packet->status.message = 0;
324                packet->header = packet->buffer;
325                packet->payload = packet->buffer + trace_get_framing_length(packet);
326                packet->size = numbytes;
327                return numbytes;
328        } while(1);
329}
330
331static int wag_write_packet(struct libtrace_out_t *libtrace, const struct libtrace_packet_t *packet) {
332        int numbytes =0 ;
333        if (packet->trace->format != &wag) {
334                fprintf(stderr,"Cannot convert from wag to %s format yet\n",
335                                packet->trace->format->name);
336                return -1;
337        }
338        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, packet->buffer, packet->size)) == 0) {
339                perror("libtrace_write");
340                return -1;
341        }
342        return numbytes;
343}
344
345static void *wag_get_link(const struct libtrace_packet_t *packet) {
346        return (void *)packet->payload;
347        /*
348        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
349        void *payload = wagptr->data;
350        return (void*)payload;
351        */
352}
353
354static libtrace_linktype_t wag_get_link_type(const struct libtrace_packet_t *packet __attribute__((unused))) {
355        return TRACE_TYPE_80211;
356}
357
358static int8_t wag_get_direction(const struct libtrace_packet_t *packet) {
359        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->header;
360        if (wagptr->hdr.type == 0) {
361                return wagptr->hdr.subtype;
362        }
363        return -1;
364}
365
366static uint64_t wag_get_erf_timestamp(const struct libtrace_packet_t *packet) {
367        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->header;
368        uint64_t timestamp = 0;
369        timestamp = (((uint64_t)wagptr->ts.secs) << 32) + wagptr->ts.subsecs;
370        //timestamp |= (uint64_t)wagptr->ts.secs<<32;
371        //timestamp = ((timestamp%44000000)*(UINT_MAX/44000000))
372        //      | ((timestamp/44000000)<<32);
373        return timestamp;
374}
375
376static int wag_get_capture_length(const struct libtrace_packet_t *packet) {
377        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->header;
378        //return (wagptr->hdr.size);
379        return ntohs(wagptr->hdr.size);
380}
381
382static int wag_get_wire_length(const struct libtrace_packet_t *packet) {
383        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->header;
384        //return (wagptr->hdr.size);
385        return ntohs(wagptr->hdr.size);
386}
387
388static int wag_get_framing_length(const struct libtrace_packet_t *packet UNUSED) {
389        return sizeof(struct wag_data_frame);
390}
391
392static int wag_get_fd(const struct libtrace_packet_t *packet) {
393        return packet->trace->format_data->input.fd;
394}
395
396static struct libtrace_eventobj_t wag_event_trace(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
397        switch(trace->sourcetype) {
398                case DEVICE:
399                        return trace_event_device(trace,packet);
400                default:
401                        return trace_event_trace(trace,packet);
402        }
403}
404static void wag_help() {
405        printf("wag format module: $Revision$\n");
406        printf("Supported input URIs:\n");
407        printf("\twag:/dev/wagn\n");
408        printf("\twag:/path/to/trace.wag\n");
409        printf("\twag:/path/to/trace.wag.gz\n");
410        printf("\n");
411        printf("\te.g.: wag:/dev/wag0\n");
412        printf("\te.g.: wag:/tmp/trace.wag.gz\n");
413        printf("\n");
414        printf("Supported output URIs:\n");
415        printf("\tnone\n");
416        printf("\n");
417}
418
419static struct libtrace_format_t wag = {
420        "wag",
421        "$Id$",
422        "wag",
423        wag_init_input,                 /* init_input */       
424        wag_init_output,                /* init_output */
425        wag_config_output,              /* config_output */
426        wag_fin_input,                  /* fin_input */
427        wag_fin_output,                 /* fin_output */
428        wag_read_packet,                /* read_packet */
429        wag_write_packet,               /* write_packet */
430        wag_get_link,                   /* get_link */
431        wag_get_link_type,              /* get_link_type */
432        wag_get_direction,              /* get_direction */
433        NULL,                           /* set_direction */
434        wag_get_erf_timestamp,          /* get_erf_timestamp */
435        NULL,                           /* get_timeval */
436        NULL,                           /* get_seconds */
437        wag_get_capture_length,         /* get_capture_length */
438        wag_get_wire_length,            /* get_wire_length */
439        wag_get_framing_length,         /* get_framing_length */
440        NULL,                           /* set_capture_length */
441        wag_get_fd,                     /* get_fd */
442        wag_event_trace,                /* trace_event */
443        wag_help                        /* help */
444};
445
446void __attribute__((constructor)) wag_constructor() {
447        register_format(&wag);
448}
Note: See TracBrowser for help on using the repository browser.