source: lib/format_wag.c @ 3b8a5ef

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

I hate shane

  • Property mode set to 100644
File size: 11.1 KB
RevLine 
[37a39b7]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
[9c6aa95]31#define _GNU_SOURCE
[79dbcef]32#include "config.h"
33#include "common.h"
[37a39b7]34#include "libtrace.h"
[9e2a109]35#include "libtrace_int.h"
[72bfe20]36#include "format_helper.h"
[37a39b7]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>
[ffc8c8d]51#include <sys/time.h>
52#include <time.h>
[37a39b7]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>
[b69afb1]62#include <stdio.h>
[9c6aa95]63#include <string.h>
64#include <stdlib.h>
[37a39b7]65
[53f8305]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
[37a39b7]74#ifndef O_LARGEFILE
75#define O_LARGEFILE 0
76#endif
[9e2a109]77
[f3ed52a]78static struct libtrace_format_t wag;
[3073c04]79
[72bfe20]80#define CONNINFO libtrace->format_data->conn_info
81#define INPUT libtrace->format_data->input
[3073c04]82#define OUTPUT libtrace->format_data->output
83#define OPTIONS libtrace->format_data->options
84
[9e2a109]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   
[f66a4933]100                //FILE *file;
101                int file;
[9e2a109]102#endif
103        } input;       
104};
105
[3073c04]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
[f66a4933]120                //FILE *file;
121                int file;
[3073c04]122#endif
123        } output;
124};
125
[37a39b7]126static int wag_init_input(struct libtrace_t *libtrace) {
127        struct stat buf;
128        struct sockaddr_un unix_sock;
[9e2a109]129        libtrace->format_data = (struct libtrace_format_data_t *) 
130                calloc(1,sizeof(struct libtrace_format_data_t));
[72bfe20]131        CONNINFO.path = libtrace->uridata;
132        if (!strncmp(CONNINFO.path,"-",1)) {
[37a39b7]133                // STDIN
[641dc7c]134                libtrace->sourcetype = STDIN;
[79dbcef]135                INPUT.file = LIBTRACE_FDOPEN(fileno(stdin),"r");
[37a39b7]136
137        } else {
[72bfe20]138                if (stat(CONNINFO.path,&buf) == -1 ) {
[37a39b7]139                        perror("stat");
140                        return 0;
141                }
142                if (S_ISSOCK(buf.st_mode)) {
[72bfe20]143                        libtrace->sourcetype = SOCKET;
[37a39b7]144                        // SOCKET
[72bfe20]145                        if ((INPUT.fd = socket(
[37a39b7]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"
[72bfe20]154                                        ,CONNINFO.path);
[37a39b7]155
[72bfe20]156                        if (connect(INPUT.fd, 
[37a39b7]157                                        (struct sockaddr *)&unix_sock,
158                                        sizeof(struct sockaddr)) == -1) {
159                                perror("connect (unix)");
160                                return 0;
161                        }
162                } else { 
163                        // TRACE
[72bfe20]164                        libtrace->sourcetype = TRACE;
[641dc7c]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(
[72bfe20]171                                        CONNINFO.path,
[37a39b7]172                                        O_LARGEFILE), "r");
173
174                }
175        }
[ffc8c8d]176        return 1;
[37a39b7]177}
178
[3073c04]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                               
[641dc7c]188                OUTPUT.file = LIBTRACE_FDOPEN(dup(1), filemode);
[3073c04]189        } else {
190                // TRACE
[641dc7c]191                OUTPUT.file = LIBTRACE_FDOPEN(open(
[3073c04]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:
[9c6aa95]211                                printf("Bad argument to wag: %s\n", optarg);
[3073c04]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
[37a39b7]228static int wag_fin_input(struct libtrace_t *libtrace) {
[641dc7c]229        LIBTRACE_CLOSE(INPUT.file);
[9c6aa95]230        return 0;
[37a39b7]231}
232
[3073c04]233static int wag_fin_output(struct libtrace_out_t *libtrace) {
[641dc7c]234        LIBTRACE_CLOSE(OUTPUT.file);
[9c6aa95]235        return 0;
[3073c04]236}
237
[1f2220f]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:
[72bfe20]248                                if ((numbytes=read(INPUT.fd, 
[1f2220f]249                                                                buffer, 
250                                                                len)) == -1) {
251                                        perror("read");
252                                        return -1;
253                                }
254                                break;
255                        default:
[641dc7c]256                                if ((numbytes=LIBTRACE_READ(INPUT.file,
[1f2220f]257                                                                buffer,
258                                                                len)) == -1) {
[641dc7c]259                                        perror("libtrace_read");
[1f2220f]260                                        return -1;
261                                }
262                }
263                break;
264        }
265        return numbytes;
266
267}
268
269
[37a39b7]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
[14d8a63]278        if (packet->buf_control == EXTERNAL) {
279                packet->buf_control = PACKET;
280                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
281        }
[37a39b7]282        packet->trace = libtrace;
283        buffer = packet->buffer;
284       
285
286        do {
[b5cd711]287                if (tracefifo_out_available(libtrace->fifo) == 0 || read_required) {
[37a39b7]288                        if ((numbytes = wag_read(libtrace,buf,RP_BUFSIZE)) <= 0) {
289                                return numbytes;
290                        }
291                        assert(libtrace->fifo);
[b5cd711]292                        tracefifo_write(libtrace->fifo,buf,numbytes);
[37a39b7]293                        read_required = 0;
294                }
295                // read in wag_frame_hdr
[b5cd711]296                if ((numbytes = tracefifo_out_read(libtrace->fifo, 
[37a39b7]297                                                buffer,
298                                                sizeof(struct wag_frame_hdr)))
299                                == 0 ) {
[b5cd711]300                        tracefifo_out_reset(libtrace->fifo);
[37a39b7]301                        read_required = 1;
302                        continue;
303                }
[1f2220f]304               
[37a39b7]305                size = ntohs(((struct wag_frame_hdr *)buffer)->size);
306
[1f2220f]307                // wag isn't in network byte order yet
[ffc8c8d]308                //size = htons(size);
[1f2220f]309                //printf("%d %d\n",size,htons(size));
310
[37a39b7]311                // read in full packet
[b5cd711]312                if((numbytes = tracefifo_out_read(libtrace->fifo,buffer,size)) == 0) {
313                        tracefifo_out_reset(libtrace->fifo);
[37a39b7]314                        read_required = 1;
315                        continue;
316                }
317
318                // have the whole packet
[b5cd711]319                tracefifo_out_update(libtrace->fifo,size);
320                tracefifo_ack_update(libtrace->fifo,size);
[37a39b7]321
[8013711]322                packet->status.type = RT_DATA;
323                packet->status.message = 0;
[14d8a63]324                packet->header = packet->buffer;
[3840760]325                packet->payload = packet->buffer + trace_get_framing_length(packet);
[37a39b7]326                packet->size = numbytes;
327                return numbytes;
328        } while(1);
329}
330
[17ffb8a]331static int wag_write_packet(struct libtrace_out_t *libtrace, const struct libtrace_packet_t *packet) {
[3073c04]332        int numbytes =0 ;
[7c8eacf]333        if (packet->trace->format != &wag) {
[3073c04]334                fprintf(stderr,"Cannot convert from wag to %s format yet\n",
335                                packet->trace->format->name);
336                return -1;
337        }
[641dc7c]338        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, packet->buffer, packet->size)) == 0) {
339                perror("libtrace_write");
[3073c04]340                return -1;
341        }
342        return numbytes;
343}
344
[37a39b7]345static void *wag_get_link(const struct libtrace_packet_t *packet) {
[14d8a63]346        return (void *)packet->payload;
347        /*
[37a39b7]348        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
349        void *payload = wagptr->data;
350        return (void*)payload;
[14d8a63]351        */
[37a39b7]352}
353
[9c6aa95]354static libtrace_linktype_t wag_get_link_type(const struct libtrace_packet_t *packet __attribute__((unused))) {
[37a39b7]355        return TRACE_TYPE_80211;
356}
357
358static int8_t wag_get_direction(const struct libtrace_packet_t *packet) {
[14d8a63]359        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->header;
[37a39b7]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) {
[14d8a63]367        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->header;
[37a39b7]368        uint64_t timestamp = 0;
369        timestamp = wagptr->ts.subsecs;
[ffc8c8d]370        //timestamp |= (uint64_t)wagptr->ts.secs<<32;
[37a39b7]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) {
[14d8a63]377        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->header;
[ffc8c8d]378        //return (wagptr->hdr.size);
379        return ntohs(wagptr->hdr.size);
[37a39b7]380}
381
382static int wag_get_wire_length(const struct libtrace_packet_t *packet) {
[14d8a63]383        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->header;
[ffc8c8d]384        //return (wagptr->hdr.size);
385        return ntohs(wagptr->hdr.size);
[37a39b7]386}
387
[3b8a5ef]388static int wag_get_framing_length(const struct libtrace_packet_t *packet UNUSED) {
[7c8eacf]389        return sizeof(struct wag_data_frame);
390}
391
[72bfe20]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}
[9c6aa95]404static void wag_help() {
[fe43699]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");
[dd22d84]417}
418
[9e2a109]419static struct libtrace_format_t wag = {
[37a39b7]420        "wag",
421        "$Id$",
[1974620]422        "wag",
[37a39b7]423        wag_init_input,                 /* init_input */       
[3073c04]424        wag_init_output,                /* init_output */
425        wag_config_output,              /* config_output */
[37a39b7]426        wag_fin_input,                  /* fin_input */
[3073c04]427        wag_fin_output,                 /* fin_output */
[37a39b7]428        wag_read_packet,                /* read_packet */
[3073c04]429        wag_write_packet,               /* write_packet */
[37a39b7]430        wag_get_link,                   /* get_link */
431        wag_get_link_type,              /* get_link_type */
432        wag_get_direction,              /* get_direction */
433        NULL,                           /* set_direction */
[ffc8c8d]434        wag_get_erf_timestamp,          /* get_erf_timestamp */
[37a39b7]435        NULL,                           /* get_timeval */
436        NULL,                           /* get_seconds */
437        wag_get_capture_length,         /* get_capture_length */
438        wag_get_wire_length,            /* get_wire_length */
[7c8eacf]439        wag_get_framing_length,         /* get_framing_length */
[dd22d84]440        NULL,                           /* set_capture_length */
[72bfe20]441        wag_get_fd,                     /* get_fd */
442        wag_event_trace,                /* trace_event */
[dd22d84]443        wag_help                        /* help */
[37a39b7]444};
445
446void __attribute__((constructor)) wag_constructor() {
[7c8eacf]447        register_format(&wag);
[37a39b7]448}
Note: See TracBrowser for help on using the repository browser.