source: lib/format_legacy.c @ dd06159

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

Add support for cisco hdlc over pos

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