source: lib/format_wag.c @ b8bb4c5

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

Separated wag device and wag trace into two separate uris called wag and
wtf respectively.
Corrected wag_read to work correctly with the wag device

  • Property mode set to 100644
File size: 14.3 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;
79static struct libtrace_format_t wag_trace;
80
81#define CONNINFO libtrace->format_data->conn_info
82#define INPUT libtrace->format_data->input
83#define OUTPUT libtrace->format_data->output
84#define OPTIONS libtrace->format_data->options
85
86struct libtrace_format_data_t {
87        union {
88                /** Information about rtclients */
89                struct {
90                        char *hostname;
91                        short port;
92                } rt;
93                char *path;             /**< information for local sockets */
94        } conn_info;
95        /** Information about the current state of the input device */
96        union {
97                int fd;
98#if HAVE_ZLIB
99                gzFile *file;
100#else   
101                //FILE *file;
102                int file;
103#endif
104        } input;       
105};
106
107struct libtrace_format_data_out_t {
108        union {
109                char *path;
110        } conn_info;
111        union {
112                struct {
113                        int level;
114                } zlib;
115        } options;
116        union {
117                int fd;
118#if HAVE_ZLIB
119                gzFile *file;
120#else
121                //FILE *file;
122                int file;
123#endif
124        } output;
125};
126
127static int wag_init_input(struct libtrace_t *libtrace) {
128        struct stat buf;
129        //struct sockaddr_un unix_sock;
130        libtrace->format_data = (struct libtrace_format_data_t *) 
131                calloc(1,sizeof(struct libtrace_format_data_t));
132        CONNINFO.path = libtrace->uridata;
133       
134        if (stat(CONNINFO.path,&buf) == -1 ) {
135                perror("stat");
136                return 0;
137        }
138        if (S_ISCHR(buf.st_mode)) {
139                libtrace->sourcetype = DEVICE;
140                               
141                INPUT.fd = open(CONNINFO.path, O_RDONLY);
142
143        } else {
144                fprintf(stderr, "%s is not a valid char device, exiting\n",
145                                CONNINFO.path);
146                return 0;
147               
148        }
149        return 1;
150}
151
152static int wtf_init_input(struct libtrace_t *libtrace) {
153        struct stat buf;
154        struct sockaddr_un unix_sock;
155
156        libtrace->format_data = (struct libtrace_format_data_t *)
157                calloc(1,sizeof(struct libtrace_format_data_t));
158        CONNINFO.path = libtrace->uridata;
159
160        if (!strncmp(CONNINFO.path,"-",1)) {
161                // STDIN
162                libtrace->sourcetype = STDIN;
163                INPUT.file = LIBTRACE_FDOPEN(fileno(stdin),"r");
164
165        } else {
166
167
168                // Do we need this socket stuff at all??
169                // If we do, put it into wag_init_input as it uses
170                // INPUT.fd
171
172                /*
173                if (stat(CONNINFO.path,&buf) == -1 ) {
174                        perror("stat");
175                        return 0;
176                }
177                if (S_ISSOCK(buf.st_mode)) {
178                        libtrace->sourcetype = SOCKET;
179                        // SOCKET
180                        if ((INPUT.fd = socket(
181                                        AF_UNIX, SOCK_STREAM, 0)) == -1) {
182                                perror("socket");
183                                return 0;
184                        }
185                        unix_sock.sun_family = AF_UNIX;
186                        bzero(unix_sock.sun_path,108);
187                        snprintf(unix_sock.sun_path,
188                                        108,"%s"
189                                        ,CONNINFO.path);
190
191                        if (connect(INPUT.fd,
192                                        (struct sockaddr *)&unix_sock,
193                                        sizeof(struct sockaddr)) == -1) {
194                                perror("connect (unix)");
195                                return 0;
196                        }
197                } else {
198                */
199                        // TRACE
200                        libtrace->sourcetype = TRACE;
201                       
202                        // we use an FDOPEN call to reopen an FD
203                        // returned from open(), so that we can set
204                        // O_LARGEFILE. This gets around gzopen not
205                        // letting you do this...
206                        INPUT.file = LIBTRACE_FDOPEN(open(
207                                        CONNINFO.path,
208                                        O_LARGEFILE), "r");
209
210                //}
211        }
212        return 1;
213}
214
215
216static int wtf_init_output(struct libtrace_out_t *libtrace) {
217        char *filemode = 0;
218        libtrace->format_data = (struct libtrace_format_data_out_t *)
219                calloc(1,sizeof(struct libtrace_format_data_out_t));
220
221        OPTIONS.zlib.level = 0;
222        asprintf(&filemode,"wb%d",OPTIONS.zlib.level);
223        if (!strncmp(libtrace->uridata,"-",1)) {
224                // STDOUT                               
225                OUTPUT.file = LIBTRACE_FDOPEN(dup(1), filemode);
226        } else {
227                // TRACE
228                OUTPUT.file = LIBTRACE_FDOPEN(open(
229                                        libtrace->uridata,
230                                        O_CREAT | O_LARGEFILE | O_WRONLY,
231                                        S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP), filemode);
232        }
233
234        return 1;
235}
236
237static int wtf_config_output(struct libtrace_out_t *libtrace, int argc, char *argv[]) {
238#if HAVE_ZLIB
239        int opt;
240        int level = OPTIONS.zlib.level;
241        optind = 1;
242        while ((opt = getopt(argc, argv, "z:")) != EOF) {
243                switch (opt) {
244                        case 'z':
245                                level = atoi(optarg);
246                                break;
247                        default:
248                                printf("Bad argument to wag: %s\n", optarg);
249                                return -1;
250                }
251        }
252        if (level != OPTIONS.zlib.level) {
253                if (level > 9 || level < 0) {
254                        // retarded level choice
255                        printf("Compression level must be between 0 and 9 inclusive - you selected %i \n", level);
256                } else {
257                        OPTIONS.zlib.level = level;
258                        return gzsetparams(OUTPUT.file, level, Z_DEFAULT_STRATEGY);
259                }
260        }
261#endif
262        return 0;
263}
264
265static int wag_fin_input(struct libtrace_t *libtrace) {
266        close(INPUT.fd);
267        return 0;
268}
269
270static int wtf_fin_input(struct libtrace_t *libtrace) {
271        LIBTRACE_CLOSE(INPUT.file);
272        return 0;
273}
274
275static int wtf_fin_output(struct libtrace_out_t *libtrace) {
276        LIBTRACE_CLOSE(OUTPUT.file);
277        return 0;
278}
279
280static int wag_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
281        int numbytes;
282        int framesize;
283        assert(libtrace);
284
285        if (buffer == 0)
286                buffer = malloc(len);
287
288        // read in wag_frame_hdr
289        if ((numbytes = read(INPUT.fd, 
290                        buffer,
291                        sizeof(struct wag_frame_hdr))) != sizeof(struct wag_frame_hdr)) {
292                return -1;
293        }
294         
295        framesize = ntohs(((struct wag_frame_hdr *)buffer)->size);
296
297        if (framesize > len) {
298                return -1;
299        }
300
301        // read in remainder of packet
302        if((numbytes = read(INPUT.fd,
303                        buffer + sizeof(struct wag_frame_hdr),
304                        framesize - sizeof(struct wag_frame_hdr))) != 
305                        (framesize - sizeof(struct wag_frame_hdr))) {
306               
307                return -1;
308         
309        }
310
311        return framesize;
312}
313
314
315static int wag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
316        int numbytes;
317       
318        char buf[RP_BUFSIZE];
319        if (packet->buf_control == EXTERNAL) {
320                packet->buf_control = PACKET;
321                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
322        }
323       
324       
325        packet->trace = libtrace;
326       
327        if ((numbytes = wag_read(libtrace, (void *)packet->buffer, RP_BUFSIZE)) <= 0) {
328           
329                return numbytes;
330        }
331
332       
333//      memcpy(packet->buffer, buf, numbytes);
334       
335        packet->status.type = RT_DATA;
336        packet->status.message = 0;
337        packet->size = numbytes;
338        packet->header = packet->buffer;
339        packet->payload = packet->buffer + trace_get_framing_length(packet);
340        return numbytes;
341}
342
343static int wtf_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
344        int numbytes;
345        void *buffer = packet->buffer;
346        void *buffer2 = packet->buffer;
347        int framesize;
348        int size;
349
350        if (packet->buf_control == EXTERNAL) {
351                packet->buf_control = PACKET;
352                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
353        }
354
355       
356        if ((numbytes = LIBTRACE_READ(INPUT.file, buffer, sizeof(struct wag_frame_hdr))) == -1) {
357                perror("libtrace_read");
358                return -1;
359        }
360
361        if (numbytes == 0) {
362                return 0;
363        }
364
365        framesize = ntohs(((struct wag_frame_hdr *)buffer)->size);
366        buffer2 = buffer + sizeof(struct wag_frame_hdr);
367        size = framesize - sizeof(struct wag_frame_hdr);
368        assert(size < LIBTRACE_PACKET_BUFSIZE);
369
370       
371        if ((numbytes=LIBTRACE_READ(INPUT.file, buffer2, size)) != size) {
372                perror("libtrace read");
373                return -1;
374        }
375
376        packet->status.type = RT_DATA;
377        packet->status.message = 0;
378        packet->size = framesize;
379        packet->header = packet->buffer;
380        packet->payload = packet->buffer + trace_get_framing_length(packet);
381        return framesize;
382       
383}                               
384       
385static int wtf_write_packet(struct libtrace_out_t *libtrace, const struct libtrace_packet_t *packet) {
386        int numbytes =0 ;
387        if (packet->trace->format != &wag_trace) {
388                fprintf(stderr,"Cannot convert from wag trace format to %s format yet\n",
389                                packet->trace->format->name);
390                return -1;
391        }
392
393        /* We could just read from packet->buffer, but I feel it is more technically correct
394         * to read from the header and payload pointers
395         */
396        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, packet->header, trace_get_framing_length(packet))) == 0) {
397                perror("libtrace_write");
398                return -1;
399        }
400        if ((numbytes = LIBTRACE_WRITE(OUTPUT.file, packet->payload, 
401                        packet->size - trace_get_framing_length(packet))) == 0) {
402                perror("libtrace_write");
403                return -1;
404        }
405        return numbytes;
406}
407
408static void *wag_get_link(const struct libtrace_packet_t *packet) {
409        /*
410        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
411        void *payload = wagptr->data;
412        return (void*)payload;
413        */
414        return (void *)packet->payload;
415}
416
417static libtrace_linktype_t wag_get_link_type(const struct libtrace_packet_t *packet __attribute__((unused))) {
418        return TRACE_TYPE_80211;
419}
420
421static int8_t wag_get_direction(const struct libtrace_packet_t *packet) {
422        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
423        if (wagptr->hdr.type == 0) {
424                return wagptr->hdr.subtype;
425        }
426        return -1;
427}
428
429static uint64_t wag_get_erf_timestamp(const struct libtrace_packet_t *packet) {
430        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
431        uint64_t timestamp = 0;
432        timestamp = ((uint64_t)(ntohl(wagptr->ts.secs)) << 32) | (uint64_t)(ntohl(wagptr->ts.subsecs));
433        return timestamp;
434}
435
436static int wag_get_capture_length(const struct libtrace_packet_t *packet) {
437        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
438        //return (wagptr->hdr.size);
439        return ntohs(wagptr->hdr.size);
440}
441
442static int wag_get_wire_length(const struct libtrace_packet_t *packet) {
443        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
444        //return (wagptr->hdr.size);
445        return ntohs(wagptr->hdr.size);
446}
447
448static int wag_get_framing_length(const struct libtrace_packet_t *packet) {
449        return sizeof(struct wag_data_frame);
450}
451
452static int wag_get_fd(const struct libtrace_packet_t *packet) {
453        return packet->trace->format_data->input.fd;
454}
455
456static struct libtrace_eventobj_t wag_event_trace(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
457        switch(trace->sourcetype) {
458                case DEVICE:
459                        return trace_event_device(trace,packet);
460                default:
461                        return trace_event_trace(trace,packet);
462        }
463}
464static void wag_help() {
465        printf("wag format module: $Revision$\n");
466        printf("Supported input URIs:\n");
467        printf("\twag:/dev/wagn\n");
468        printf("\n");
469        printf("\te.g.: wag:/dev/wag0\n");
470        printf("\n");
471        printf("Supported output URIs:\n");
472        printf("\tNone\n");
473        printf("\n");
474}
475
476static void wtf_help() {
477        printf("wag trace format module: $Revision$\n");
478        printf("Supported input URIs:\n");
479        printf("\twtf:/path/to/trace.wag\n");
480        printf("\twtf:/path/to/trace.wag.gz\n");
481        printf("\n");
482        printf("\te.g.: wtf:/tmp/trace.wag.gz\n");
483        printf("\n");
484        printf("Supported output URIs:\n");
485        printf("\twtf:/path/to/trace.wag\n");
486        printf("\twtf:/path/to/trace.wag.gz\n");
487        printf("\n");
488        printf("\te.g.: wtf:/tmp/trace.wag.gz\n");
489        printf("\n");
490}
491
492static struct libtrace_format_t wag = {
493        "wag",
494        "$Id$",
495        "wtf",
496        wag_init_input,                 /* init_input */       
497        NULL,                           /* init_output */
498        NULL,                           /* config_output */
499        wag_fin_input,                  /* fin_input */
500        NULL,                           /* fin_output */
501        wag_read_packet,                /* read_packet */
502        NULL,                           /* write_packet */
503        wag_get_link,                   /* get_link */
504        wag_get_link_type,              /* get_link_type */
505        wag_get_direction,              /* get_direction */
506        NULL,                           /* set_direction */
507        wag_get_erf_timestamp,          /* get_erf_timestamp */
508        NULL,                           /* get_timeval */
509        NULL,                           /* get_seconds */
510        wag_get_capture_length,         /* get_capture_length */
511        wag_get_wire_length,            /* get_wire_length */
512        wag_get_framing_length,         /* get_framing_length */
513        NULL,                           /* set_capture_length */
514        wag_get_fd,                     /* get_fd */
515        wag_event_trace,                /* trace_event */
516        wag_help                        /* help */
517};
518
519/* wtf stands for Wag Trace Format */
520
521static struct libtrace_format_t wag_trace = {
522        "wtf",
523        "$Id$",
524        "wtf",
525        wtf_init_input,                 /* init_input */
526        wtf_init_output,                /* init_output */
527        wtf_config_output,              /* config_output */
528        wtf_fin_input,                  /* fin_input */
529        wtf_fin_output,                 /* fin_output */
530        wtf_read_packet,                /* read_packet */
531        wtf_write_packet,               /* write_packet */
532        wag_get_link,                   /* get_link */
533        wag_get_link_type,              /* get_link_type */
534        wag_get_direction,              /* get_direction */
535        NULL,                           /* set_direction */
536        wag_get_erf_timestamp,          /* get_erf_timestamp */
537        NULL,                           /* get_timeval */
538        NULL,                           /* get_seconds */
539        wag_get_capture_length,         /* get_capture_length */
540        wag_get_wire_length,            /* get_wire_length */
541        wag_get_framing_length,         /* get_framing_length */
542        NULL,                           /* set_capture_length */
543        wag_get_fd,                     /* get_fd */
544        wag_event_trace,                /* trace_event */
545        wtf_help                        /* help */
546};
547
548
549void __attribute__((constructor)) wag_constructor() {
550        register_format(&wag);
551        register_format(&wag_trace);
552}
Note: See TracBrowser for help on using the repository browser.