source: lib/format_wag.c @ 39b37d2

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

include "config.h" <- get 64bit goodness back

  • Property mode set to 100644
File size: 8.7 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#include "libtrace.h"
32#include "libtrace_int.h"
33#include "format_helper.h"
34#include "wag.h"
35#include "config.h"
36
37#ifdef HAVE_INTTYPES_H
38#  include <inttypes.h>
39#else
40#  error "Can't find inttypes.h - this needs to be fixed"
41#endif
42
43#ifdef HAVE_STDDEF_H
44#  include <stddef.h>
45#else
46# error "Can't find stddef.h - do you define ptrdiff_t elsewhere?"
47#endif
48#include <sys/types.h>
49#include <sys/socket.h>
50#include <sys/un.h>
51#include <sys/mman.h>
52#include <sys/stat.h>
53#include <fcntl.h>
54#include <unistd.h>
55#include <assert.h>
56#include <errno.h>
57#include <netdb.h>
58
59#ifndef O_LARGEFILE
60#define O_LARGEFILE 0
61#endif
62
63#define CONNINFO libtrace->format_data->conn_info
64#define INPUT libtrace->format_data->input
65struct libtrace_format_data_t {
66        union {
67                /** Information about rtclients */
68                struct {
69                        char *hostname;
70                        short port;
71                } rt;
72                char *path;             /**< information for local sockets */
73        } conn_info;
74        /** Information about the current state of the input device */
75        union {
76                int fd;
77#if HAVE_ZLIB
78                gzFile *file;
79#else   
80                FILE *file;
81#endif
82        } input;       
83};
84
85static int wag_init_input(struct libtrace_t *libtrace) {
86        struct stat buf;
87        struct hostent *he;
88        struct sockaddr_in remote;
89        struct sockaddr_un unix_sock;
90        libtrace->format_data = (struct libtrace_format_data_t *) 
91                calloc(1,sizeof(struct libtrace_format_data_t));
92        CONNINFO.path = libtrace->uridata;
93        if (!strncmp(CONNINFO.path,"-",1)) {
94                libtrace->sourcetype = STDIN;
95                // STDIN
96#if HAVE_ZLIB
97                INPUT.file = gzdopen(STDIN, "r");
98#else   
99                INPUT.file = stdin;
100#endif
101
102        } else {
103                if (stat(CONNINFO.path,&buf) == -1 ) {
104                        perror("stat");
105                        return 0;
106                }
107                if (S_ISSOCK(buf.st_mode)) {
108                        libtrace->sourcetype = SOCKET;
109                        // SOCKET
110                        if ((INPUT.fd = socket(
111                                        AF_UNIX, SOCK_STREAM, 0)) == -1) {
112                                perror("socket");
113                                return 0;
114                        }
115                        unix_sock.sun_family = AF_UNIX;
116                        bzero(unix_sock.sun_path,108);
117                        snprintf(unix_sock.sun_path,
118                                        108,"%s"
119                                        ,CONNINFO.path);
120
121                        if (connect(INPUT.fd, 
122                                        (struct sockaddr *)&unix_sock,
123                                        sizeof(struct sockaddr)) == -1) {
124                                perror("connect (unix)");
125                                return 0;
126                        }
127                } else { 
128                        // TRACE
129                        libtrace->sourcetype = TRACE;
130#if HAVE_ZLIB
131                        // using gzdopen means we can set O_LARGEFILE
132                        // ourselves. However, this way is messy and
133                        // we lose any error checking on "open"
134                        INPUT.file = 
135                                gzdopen(open(
136                                        CONNINFO.path,
137                                        O_LARGEFILE), "r");
138#else
139                        INPUT.file = 
140                                fdopen(open(
141                                        CONNINFO.path,
142                                        O_LARGEFILE), "r");
143#endif
144
145                }
146        }
147}
148
149static int wag_fin_input(struct libtrace_t *libtrace) {
150#if HAVE_ZLIB
151        gzclose(INPUT.file);
152#else   
153        fclose(INPUT.file);     
154#endif
155}
156
157static int wag_read(struct libtrace_t *libtrace, void *buffer, size_t len) {
158        int numbytes;
159        static short lctr = 0;
160        int rlen;
161        assert(libtrace);
162        assert(len >= 0);
163
164        if (buffer == 0)
165                buffer = malloc(len);
166
167        while(1) {
168                switch(libtrace->sourcetype) {
169                        case DEVICE:
170                                if ((numbytes=read(INPUT.fd, 
171                                                                buffer, 
172                                                                len)) == -1) {
173                                        perror("read");
174                                        return -1;
175                                }
176                                break;
177                        default:
178#if HAVE_ZLIB
179                                if ((numbytes=gzread(INPUT.file,
180                                                                buffer,
181                                                                len)) == -1) {
182                                        perror("gzread");
183                                        return -1;
184                                }
185#else
186                                if ((numbytes=fread(buffer,len,1,
187                                        INPUT.file)) == 0 ) {
188                                        if(feof(INPUT.file)) {
189                                                return 0;
190                                        }
191                                        if(ferror(INPUT.file)) {
192                                                perror("fread");
193                                                return -1;
194                                        }
195                                        return 0;
196                                }
197#endif
198                }
199                break;
200        }
201        return numbytes;
202
203}
204
205
206static int wag_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
207        int numbytes;
208        int size;
209        char buf[RP_BUFSIZE];
210        int read_required = 0;
211        struct wag_frame_hdr *waghdr = 0;
212
213        void *buffer = 0;
214
215        packet->trace = libtrace;
216        buffer = packet->buffer;
217       
218
219        do {
220                if (fifo_out_available(libtrace->fifo) == 0 || read_required) {
221                        if ((numbytes = wag_read(libtrace,buf,RP_BUFSIZE)) <= 0) {
222                                return numbytes;
223                        }
224                        assert(libtrace->fifo);
225                        fifo_write(libtrace->fifo,buf,numbytes);
226                        read_required = 0;
227                }
228                // read in wag_frame_hdr
229                if ((numbytes = fifo_out_read(libtrace->fifo, 
230                                                buffer,
231                                                sizeof(struct wag_frame_hdr)))
232                                == 0 ) {
233                        fifo_out_reset(libtrace->fifo);
234                        read_required = 1;
235                        continue;
236                }
237               
238                size = ntohs(((struct wag_frame_hdr *)buffer)->size);
239
240                // wag isn't in network byte order yet
241                size = htons(size);
242                //printf("%d %d\n",size,htons(size));
243
244                // read in full packet
245                if((numbytes = fifo_out_read(libtrace->fifo,buffer,size)) == 0) {
246                        fifo_out_reset(libtrace->fifo);
247                        read_required = 1;
248                        continue;
249                }
250
251                // have the whole packet
252                fifo_out_update(libtrace->fifo,size);
253                fifo_ack_update(libtrace->fifo,size);
254
255                packet->size = numbytes;
256                return numbytes;
257        } while(1);
258}
259
260static void *wag_get_link(const struct libtrace_packet_t *packet) {
261        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
262        void *payload = wagptr->data;
263        return (void*)payload;
264}
265
266static libtrace_linktype_t wag_get_link_type(const struct libtrace_packet_t *packet) {
267        return TRACE_TYPE_80211;
268}
269
270static int8_t wag_get_direction(const struct libtrace_packet_t *packet) {
271        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
272        if (wagptr->hdr.type == 0) {
273                return wagptr->hdr.subtype;
274        }
275        return -1;
276}
277
278static uint64_t wag_get_erf_timestamp(const struct libtrace_packet_t *packet) {
279        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
280        uint64_t timestamp = 0;
281        timestamp = wagptr->ts.subsecs;
282        timestamp |= (uint64_t)wagptr->ts.secs<<32;
283        timestamp = ((timestamp%44000000)*(UINT_MAX/44000000)) 
284                | ((timestamp/44000000)<<32);
285        return timestamp;
286}
287
288static int wag_get_capture_length(const struct libtrace_packet_t *packet) {
289        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
290        return (wagptr->hdr.size);
291        //return ntohs(wagptr->hdr.size);
292}
293
294static int wag_get_wire_length(const struct libtrace_packet_t *packet) {
295        struct wag_data_frame *wagptr = (struct wag_data_frame *)packet->buffer;
296        return (wagptr->hdr.size);
297        //return ntohs(wagptr->hdr.size);
298}
299
300static int wag_get_fd(const struct libtrace_packet_t *packet) {
301        return packet->trace->format_data->input.fd;
302}
303
304static struct libtrace_eventobj_t wag_event_trace(struct libtrace_t *trace, struct libtrace_packet_t *packet) {
305        switch(trace->sourcetype) {
306                case DEVICE:
307                        return trace_event_device(trace,packet);
308                default:
309                        return trace_event_trace(trace,packet);
310        }
311}
312static int wag_help() {
313        printf("wag format module: $Revision$\n");
314        printf("Supported input URIs:\n");
315        printf("\twag:/dev/wagn\n");
316        printf("\twag:/path/to/trace.wag\n");
317        printf("\twag:/path/to/trace.wag.gz\n");
318        printf("\n");
319        printf("\te.g.: wag:/dev/wag0\n");
320        printf("\te.g.: wag:/tmp/trace.wag.gz\n");
321        printf("\n");
322        printf("Supported output URIs:\n");
323        printf("\tnone\n");
324        printf("\n");
325
326}
327
328static struct libtrace_format_t wag = {
329        "wag",
330        "$Id$",
331        wag_init_input,                 /* init_input */       
332        NULL,                           /* init_output */
333        NULL,                           /* config_output */
334        wag_fin_input,                  /* fin_input */
335        NULL,                           /* fin_output */
336        wag_read_packet,                /* read_packet */
337        NULL,                           /* write_packet */
338        wag_get_link,                   /* get_link */
339        wag_get_link_type,              /* get_link_type */
340        wag_get_direction,              /* get_direction */
341        NULL,                           /* set_direction */
342        wag_get_erf_timestamp,          /* get_wag_timestamp */
343        NULL,                           /* get_timeval */
344        NULL,                           /* get_seconds */
345        wag_get_capture_length,         /* get_capture_length */
346        wag_get_wire_length,            /* get_wire_length */
347        NULL,                           /* set_capture_length */
348        wag_get_fd,                     /* get_fd */
349        wag_event_trace,                /* trace_event */
350        wag_help                        /* help */
351};
352
353void __attribute__((constructor)) wag_constructor() {
354        register_format(&wag);
355}
Note: See TracBrowser for help on using the repository browser.