source: lib/format_legacy.c @ 91b72d3

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 91b72d3 was 91b72d3, checked in by Perry Lorier <perry@…>, 12 years ago

Try to autoguess the tracetype if the format uri specify is not present

  • Property mode set to 100644
File size: 17.0 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2007,2008 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#define _GNU_SOURCE
31
32#include "config.h"
33#include "common.h"
34#include "libtrace.h"
35#include "libtrace_int.h"
36#include "format_helper.h"
37#include "wandio.h"
38
39#include <sys/stat.h>
40#include <assert.h>
41#include <errno.h>
42#include <fcntl.h>
43#include <stdio.h>
44#include <string.h>
45#include <stdlib.h>
46#include <regex.h>
47
48#ifdef WIN32
49#  include <io.h>
50#  include <share.h>
51#endif
52
53
54/* Catch undefined O_LARGEFILE on *BSD etc */
55#ifndef O_LARGEFILE
56#  define O_LARGEFILE 0
57#endif
58
59#ifndef UINT32_MAX
60#  define UINT32_MAX 0xffffffff
61#endif
62
63#define DATA(x) ((struct legacy_format_data_t *)x->format_data)
64
65struct legacy_format_data_t {
66        time_t starttime;       /* Used for legacy_nzix */
67        uint64_t ts_high;       /* Used for legacy_nzix */
68        uint32_t ts_old;        /* Used for legacy_nzix */
69};
70
71static void legacy_init_format_data(libtrace_t *libtrace) {
72        libtrace->format_data = malloc(sizeof(struct legacy_format_data_t));
73       
74        DATA(libtrace)->ts_high = 0;
75        DATA(libtrace)->ts_old = 0;
76        DATA(libtrace)->starttime = 0;
77}
78
79static int legacyeth_get_framing_length(const libtrace_packet_t *packet UNUSED) 
80{
81        return sizeof(legacy_ether_t);
82}
83
84static int legacypos_get_framing_length(const libtrace_packet_t *packet UNUSED) 
85{
86        return sizeof(legacy_pos_t);
87}
88
89static int legacyatm_get_framing_length(const libtrace_packet_t *packet UNUSED) 
90{
91        return sizeof(legacy_cell_t);
92}
93
94static int legacynzix_get_framing_length(const libtrace_packet_t *packet UNUSED)
95{
96        return sizeof(legacy_nzix_t);
97}
98
99static int erf_init_input(libtrace_t *libtrace) 
100{
101        legacy_init_format_data(libtrace);
102
103        return 0;
104}
105
106static time_t trtime(char *s) {
107        /* XXX: this function may not be particularly portable to
108         * other platforms, e.g. *BSDs, Windows */
109        struct tm tm;
110        char *tz;
111        time_t ret;
112        static char envbuf[256];
113
114        if(sscanf(s, "%4u%2u%2u-%2u%2u%2u", &tm.tm_year, &tm.tm_mon,
115                                &tm.tm_mday, &tm.tm_hour, &tm.tm_min,
116                                &tm.tm_sec) != 6) {
117                return (time_t)0;
118        }
119        tm.tm_year = tm.tm_year - 1900;
120        tm.tm_mon --;
121        tm.tm_wday = 0; /* ignored */
122        tm.tm_yday = 0; /* ignored */
123        tm.tm_isdst = -1; /* forces check for summer time */
124       
125        tz = getenv("TZ");
126        if (putenv("TZ=Pacific/Auckland")) {
127                perror("putenv");
128                return (time_t)0;
129        }
130        tzset();
131        ret = mktime(&tm);
132
133        return ret;
134}
135       
136
137static int legacynzix_init_input(libtrace_t *libtrace) {
138
139        int retval;
140        char *filename = libtrace->uridata;
141        regex_t reg;
142        regmatch_t match;
143
144
145        legacy_init_format_data(libtrace);     
146        if((retval = regcomp(&reg, "[0-9]{8}-[0-9]{6}", REG_EXTENDED)) != 0) {
147                trace_set_err(libtrace, errno, "Failed to compile regex");
148                return -1;
149        }
150        if ((retval = regexec(&reg, filename, 1, &match, 0)) !=0) {
151                trace_set_err(libtrace, errno, "Failed to exec regex");
152                return -1;
153        }
154        DATA(libtrace)->starttime = trtime(&filename[match.rm_so]);
155        return 0;
156}
157
158static int erf_start_input(libtrace_t *libtrace)
159{
160        if (libtrace->io)
161                return 0; /* Already open */
162
163        libtrace->io = trace_open_file(libtrace);
164
165        if (libtrace->io)
166                return 0;
167
168        return -1;
169}
170
171static int erf_fin_input(libtrace_t *libtrace) {
172        wandio_destroy(libtrace->io);
173        free(libtrace->format_data);
174        return 0;
175}
176
177static int legacy_prepare_packet(libtrace_t *libtrace, 
178                libtrace_packet_t *packet, void *buffer, 
179                libtrace_rt_types_t rt_type, uint32_t flags) {
180
181        if (packet->buffer != buffer &&
182                        packet->buf_control == TRACE_CTRL_PACKET) {
183                free(packet->buffer);
184        }
185
186        if ((flags & TRACE_PREP_OWN_BUFFER) == TRACE_PREP_OWN_BUFFER) {
187                packet->buf_control = TRACE_CTRL_PACKET;
188        } else
189                packet->buf_control = TRACE_CTRL_EXTERNAL;
190
191
192        packet->buffer = buffer;
193        packet->header = buffer;
194        packet->type = rt_type;
195        packet->payload = (void*)((char*)packet->buffer + 
196                libtrace->format->get_framing_length(packet));
197
198
199        if (libtrace->format_data == NULL) {
200                legacy_init_format_data(libtrace);
201        }
202        return 0;
203}
204
205static int legacy_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
206        int numbytes;
207        void *buffer;
208        uint32_t flags = 0;
209       
210        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
211                packet->buffer=malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
212        }
213        flags |= TRACE_PREP_OWN_BUFFER;
214        buffer = packet->buffer;
215
216        switch(libtrace->format->type) {
217                case TRACE_FORMAT_LEGACY_ATM:
218                        packet->type = TRACE_RT_DATA_LEGACY_ATM;
219                        break;
220                case TRACE_FORMAT_LEGACY_POS:
221                        packet->type = TRACE_RT_DATA_LEGACY_POS;
222                        break;
223                case TRACE_FORMAT_LEGACY_ETH:
224                        packet->type = TRACE_RT_DATA_LEGACY_ETH;
225                        break;
226                default:
227                        assert(0);
228        }
229
230        /* This is going to block until we either get an entire record
231         * or we reach the end of the file */
232        while (1) {
233       
234                if ((numbytes=wandio_read(libtrace->io,
235                                                buffer,
236                                                (size_t)64)) != 64) {
237                        if (numbytes < 0) {
238                                trace_set_err(libtrace,errno,"read(%s)",libtrace->uridata);
239                        } else if (numbytes > 0) {
240                               
241                                continue;
242                        }
243                        return numbytes;
244                }
245                break;
246        }
247       
248        if (legacy_prepare_packet(libtrace, packet, packet->buffer, 
249                                packet->type, flags)) {
250                return -1;
251        }
252       
253        return 64;
254       
255}
256
257static int legacynzix_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) {
258        /* Firstly, I apologize for all the constants being thrown around in
259         * this function, but it does befit the hackish origins of the
260         * NZIX format that I use them. Anyone who wants to clean them up is
261         * welcome to do so */
262        int numbytes;
263        void *buffer;
264        char *data_ptr;
265        uint32_t flags = 0;
266       
267        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
268                packet->buffer=malloc((size_t)LIBTRACE_PACKET_BUFSIZE);
269        }
270        flags |= TRACE_PREP_OWN_BUFFER;
271       
272        buffer = packet->buffer;
273        packet->type = TRACE_RT_DATA_LEGACY_NZIX;
274       
275        while (1) {
276                if ((numbytes = wandio_read(libtrace->io, buffer,
277                                                (size_t)68)) != 68) {
278                        if (numbytes < 0) {
279                                trace_set_err(libtrace,errno,"read(%s)",libtrace->uridata);
280                        } else if (numbytes > 0)
281                                continue;
282                        return numbytes;
283                } 
284                /* Packets with a zero length are GPS timestamp packets
285                 * but they aren't inserted at the right time to be
286                 * useful - instead we'll ignore them unless we can think
287                 * of a compelling reason to do otherwise */
288                if (((legacy_nzix_t *)buffer)->len == 0)
289                        continue;
290               
291                break;
292        }
293
294        /* lets move the padding so that it's in the framing header */
295        data_ptr = ((char *)buffer) + 12;
296        memmove(data_ptr + 2, data_ptr, 26);
297
298        if (legacy_prepare_packet(libtrace, packet, packet->buffer, 
299                                packet->type, flags)) {
300                return -1;
301        }
302        return 68;
303}
304               
305
306static libtrace_linktype_t legacypos_get_link_type(
307                const libtrace_packet_t *packet) {
308        /* POS can be PPP over HDLC (DLT_PPP_SERIAL), or it can be
309         * just straight PPP.  Sigh.
310         *
311         * Ref: RFC 1549
312         *      - Perry Lorier (2008-11-04)
313         */
314        if (((char *)packet->payload)[0] == '\xFF'
315                && ((char*)packet->payload)[1] == '\x03')
316                return TRACE_TYPE_POS;
317        else 
318                return TRACE_TYPE_PPP;
319}
320
321static libtrace_linktype_t legacyatm_get_link_type(
322                const libtrace_packet_t *packet UNUSED) {
323        return TRACE_TYPE_ATM;
324}
325
326static libtrace_linktype_t legacyeth_get_link_type(const libtrace_packet_t *packet UNUSED) {
327        return TRACE_TYPE_ETH;
328}
329
330static libtrace_linktype_t legacynzix_get_link_type(const libtrace_packet_t *packet UNUSED) {
331        return TRACE_TYPE_ETH;
332}
333
334static int legacy_get_capture_length(const libtrace_packet_t *packet UNUSED) {
335        return 64;
336}
337
338static int legacynzix_get_capture_length(const libtrace_packet_t *packet UNUSED)
339{
340        return 54;
341}
342
343static int legacypos_get_wire_length(const libtrace_packet_t *packet) {
344        legacy_pos_t *lpos = (legacy_pos_t *)packet->header;
345        assert(ntohl(lpos->wlen)>0);
346        return ntohl(lpos->wlen);
347}
348
349static int legacyatm_get_wire_length(const libtrace_packet_t *packet UNUSED) {
350        return 53;
351}
352
353static int legacyeth_get_wire_length(const libtrace_packet_t *packet) {
354        legacy_ether_t *leth = (legacy_ether_t *)packet->header;
355        return leth->wlen;
356}
357
358static int legacynzix_get_wire_length(const libtrace_packet_t *packet) {
359        legacy_nzix_t *lnzix = (legacy_nzix_t *)packet->header;
360        return lnzix->len;
361}
362
363static uint64_t legacy_get_erf_timestamp(const libtrace_packet_t *packet)
364{
365        legacy_ether_t *legacy = (legacy_ether_t*)packet->header;
366        return legacy->ts;
367} 
368
369static uint32_t ts_cmp(uint32_t ts_a, uint32_t ts_b) {
370       
371        /* each ts is actually a 30 bit value */
372        ts_a <<= 2;
373        ts_b <<= 2;
374
375
376        if (ts_a > ts_b) 
377                return (ts_a - ts_b);
378        else
379                return (ts_b - ts_a);
380       
381}
382
383static struct timeval legacynzix_get_timeval(const libtrace_packet_t *packet) {
384        uint64_t new_ts = DATA(packet->trace)->ts_high;
385        uint32_t old_ts = DATA(packet->trace)->ts_old;
386        struct timeval tv;
387        uint32_t hdr_ts;
388
389        double dts;
390       
391        legacy_nzix_t *legacy = (legacy_nzix_t *)packet->header;
392               
393        hdr_ts = legacy->ts;
394
395        /* seems we only need 30 bits to represent our timestamp */
396        hdr_ts >>=2;
397        /* try a sequence number wrap-around comparison */
398        if (ts_cmp(hdr_ts, old_ts) > (UINT32_MAX / 2) )
399                new_ts += (1LL << 30); /* wraparound */
400        new_ts &= ~((1LL << 30) -1);    /* mask lower 30 bits */
401        new_ts += hdr_ts;               /* packet ts is the new 30 bits */
402        DATA(packet->trace)->ts_old = hdr_ts;
403
404        tv.tv_sec = DATA(packet->trace)->starttime + (new_ts / (1000 * 1000));
405        tv.tv_usec = new_ts % (1000 * 1000);
406        DATA(packet->trace)->ts_high = new_ts;
407
408
409        dts = tv.tv_sec + (double)tv.tv_usec / 1000 / 1000;
410        return tv;
411       
412}       
413
414static void legacypos_help(void) {
415        printf("legacypos format module: $Revision$\n");
416        printf("Supported input URIs:\n");
417        printf("\tlegacypos:/path/to/file\t(uncompressed)\n");
418        printf("\tlegacypos:/path/to/file.gz\t(gzip-compressed)\n");
419        printf("\tlegacypos:-\t(stdin, either compressed or not)\n");
420        printf("\n");
421        printf("\te.g.: legacypos:/tmp/trace.gz\n");
422        printf("\n");
423}
424
425static void legacyatm_help(void) {
426        printf("legacyatm format module: $Revision$\n");
427        printf("Supported input URIs:\n");
428        printf("\tlegacyatm:/path/to/file\t(uncompressed)\n");
429        printf("\tlegacyatm:/path/to/file.gz\t(gzip-compressed)\n");
430        printf("\tlegacyatm:-\t(stdin, either compressed or not)\n");
431        printf("\n");
432        printf("\te.g.: legacyatm:/tmp/trace.gz\n");
433        printf("\n");
434}
435
436static void legacyeth_help(void) {
437        printf("legacyeth format module: $Revision$\n");
438        printf("Supported input URIs:\n");
439        printf("\tlegacyeth:/path/to/file\t(uncompressed)\n");
440        printf("\tlegacyeth:/path/to/file.gz\t(gzip-compressed)\n");
441        printf("\tlegacyeth:-\t(stdin, either compressed or not)\n");
442        printf("\n");
443        printf("\te.g.: legacyeth:/tmp/trace.gz\n");
444        printf("\n");
445}
446
447static void legacynzix_help(void) {
448        printf("legacynzix format module: $Revision$\n");
449        printf("Supported input URIs:\n");
450        printf("\tlegacynzix:/path/to/file\t(uncompressed)\n");
451        printf("\tlegacynzix:/path/to/file.gz\t(gzip-compressed)\n");
452        printf("\tlegacynzix:-\t(stdin, either compressed or not)\n");
453        printf("\n");
454        printf("\te.g.: legacynzix:/tmp/trace.gz\n");
455        printf("\n");
456}
457
458static struct libtrace_format_t legacyatm = {
459        "legacyatm",
460        "$Id$",
461        TRACE_FORMAT_LEGACY_ATM,
462        NULL,                           /* probe filename */
463        NULL,                           /* probe magic */
464        erf_init_input,                 /* init_input */       
465        NULL,                           /* config_input */
466        erf_start_input,                /* start_input */
467        NULL,                           /* pause_input */
468        NULL,                           /* init_output */
469        NULL,                           /* config_output */
470        NULL,                           /* start_output */
471        erf_fin_input,                  /* fin_input */
472        NULL,                           /* fin_output */
473        legacy_read_packet,             /* read_packet */
474        legacy_prepare_packet,          /* prepare_packet */
475        NULL,                           /* fin_packet */
476        NULL,                           /* write_packet */
477        legacyatm_get_link_type,        /* get_link_type */
478        NULL,                           /* get_direction */
479        NULL,                           /* set_direction */
480        legacy_get_erf_timestamp,       /* get_erf_timestamp */
481        NULL,                           /* get_timeval */
482        NULL,                           /* get_seconds */
483        NULL,                           /* seek_erf */
484        NULL,                           /* seek_timeval */
485        NULL,                           /* seek_seconds */
486        legacy_get_capture_length,      /* get_capture_length */
487        legacyatm_get_wire_length,      /* get_wire_length */
488        legacyatm_get_framing_length,   /* get_framing_length */
489        NULL,                           /* set_capture_length */
490        NULL,                           /* get_received_packets */
491        NULL,                           /* get_filtered_packets */
492        NULL,                           /* get_dropped_packets */
493        NULL,                           /* get_captured_packets */
494        NULL,                           /* get_fd */
495        trace_event_trace,              /* trace_event */
496        legacyatm_help,                 /* help */
497        NULL                            /* next pointer */
498};
499
500static struct libtrace_format_t legacyeth = {
501        "legacyeth",
502        "$Id$",
503        TRACE_FORMAT_LEGACY_ETH,
504        NULL,                           /* probe filename */
505        NULL,                           /* probe magic */
506        erf_init_input,                 /* init_input */       
507        NULL,                           /* config_input */
508        erf_start_input,                /* start_input */
509        NULL,                           /* pause_input */
510        NULL,                           /* init_output */
511        NULL,                           /* config_output */
512        NULL,                           /* start_output */
513        erf_fin_input,                  /* fin_input */
514        NULL,                           /* fin_output */
515        legacy_read_packet,             /* read_packet */
516        legacy_prepare_packet,          /* prepare_packet */
517        NULL,                           /* fin_packet */
518        NULL,                           /* write_packet */
519        legacyeth_get_link_type,        /* get_link_type */
520        NULL,                           /* get_direction */
521        NULL,                           /* set_direction */
522        legacy_get_erf_timestamp,       /* get_erf_timestamp */
523        NULL,                           /* get_timeval */
524        NULL,                           /* get_seconds */
525        NULL,                           /* seek_erf */
526        NULL,                           /* seek_timeval */
527        NULL,                           /* seek_seconds */
528        legacy_get_capture_length,      /* get_capture_length */
529        legacyeth_get_wire_length,      /* get_wire_length */
530        legacyeth_get_framing_length,   /* get_framing_length */
531        NULL,                           /* set_capture_length */
532        NULL,                           /* get_received_packets */
533        NULL,                           /* get_filtered_packets */
534        NULL,                           /* get_dropped_packets */
535        NULL,                           /* get_captured_packets */
536        NULL,                           /* get_fd */
537        trace_event_trace,              /* trace_event */
538        legacyeth_help,                 /* help */
539        NULL                            /* next pointer */
540};
541
542static struct libtrace_format_t legacypos = {
543        "legacypos",
544        "$Id$",
545        TRACE_FORMAT_LEGACY_POS,
546        NULL,                           /* probe filename */
547        NULL,                           /* probe magic */
548        erf_init_input,                 /* init_input */       
549        NULL,                           /* config_input */
550        erf_start_input,                /* start_input */
551        NULL,                           /* pause_input */
552        NULL,                           /* init_output */
553        NULL,                           /* config_output */
554        NULL,                           /* start_output */
555        erf_fin_input,                  /* fin_input */
556        NULL,                           /* fin_output */
557        legacy_read_packet,             /* read_packet */
558        legacy_prepare_packet,          /* prepare_packet */
559        NULL,                           /* fin_packet */
560        NULL,                           /* write_packet */
561        legacypos_get_link_type,        /* get_link_type */
562        NULL,                           /* get_direction */
563        NULL,                           /* set_direction */
564        legacy_get_erf_timestamp,       /* get_erf_timestamp */
565        NULL,                           /* get_timeval */
566        NULL,                           /* get_seconds */
567        NULL,                           /* seek_erf */
568        NULL,                           /* seek_timeval */
569        NULL,                           /* seek_seconds */
570        legacy_get_capture_length,      /* get_capture_length */
571        legacypos_get_wire_length,      /* get_wire_length */
572        legacypos_get_framing_length,   /* get_framing_length */
573        NULL,                           /* set_capture_length */
574        NULL,                           /* get_received_packets */
575        NULL,                           /* get_filtered_packets */
576        NULL,                           /* get_dropped_packets */
577        NULL,                           /* get_captured_packets */
578        NULL,                           /* get_fd */
579        trace_event_trace,              /* trace_event */
580        legacypos_help,                 /* help */
581        NULL,                           /* next pointer */
582};
583
584static struct libtrace_format_t legacynzix = {
585        "legacynzix",
586        "$Id$",
587        TRACE_FORMAT_LEGACY_NZIX,
588        NULL,                           /* probe filename */
589        NULL,                           /* probe magic */
590        legacynzix_init_input,          /* init_input */       
591        NULL,                           /* config_input */
592        erf_start_input,                /* start_input */
593        NULL,                           /* pause_input */
594        NULL,                           /* init_output */
595        NULL,                           /* config_output */
596        NULL,                           /* start_output */
597        erf_fin_input,                  /* fin_input */
598        NULL,                           /* fin_output */
599        legacynzix_read_packet,         /* read_packet */
600        legacy_prepare_packet,          /* prepare_packet */
601        NULL,                           /* fin_packet */
602        NULL,                           /* write_packet */
603        legacynzix_get_link_type,       /* get_link_type */
604        NULL,                           /* get_direction */
605        NULL,                           /* set_direction */
606        NULL,                           /* get_erf_timestamp */
607        legacynzix_get_timeval,         /* get_timeval */
608        NULL,                           /* get_seconds */
609        NULL,                           /* seek_erf */
610        NULL,                           /* seek_timeval */
611        NULL,                           /* seek_seconds */
612        legacynzix_get_capture_length,  /* get_capture_length */
613        legacynzix_get_wire_length,     /* get_wire_length */
614        legacynzix_get_framing_length,  /* get_framing_length */
615        NULL,                           /* set_capture_length */
616        NULL,                           /* get_received_packets */
617        NULL,                           /* get_filtered_packets */
618        NULL,                           /* get_dropped_packets */
619        NULL,                           /* get_captured_packets */
620        NULL,                           /* get_fd */
621        trace_event_trace,              /* trace_event */
622        legacynzix_help,                /* help */
623        NULL,                           /* next pointer */
624};
625       
626void legacy_constructor(void) {
627        register_format(&legacypos);
628        register_format(&legacyeth);
629        register_format(&legacyatm);
630        register_format(&legacynzix);
631}
Note: See TracBrowser for help on using the repository browser.