diff options
author | guy <guy@f5534014-38df-0310-8fa8-9805f1628bb7> | 2003-10-31 00:43:21 +0000 |
---|---|---|
committer | guy <guy@f5534014-38df-0310-8fa8-9805f1628bb7> | 2003-10-31 00:43:21 +0000 |
commit | fc0299d3f2732176121836ecb01d1e6812c16f69 (patch) | |
tree | 5a53e326f6692d879d2277af6107a9906020de5c /wiretap | |
parent | 576ec1e750a2ec66601fc2f951b70e4953a55e5e (diff) |
From Scott Emberley: support for reading Network Instruments version 9
capture files.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@8840 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'wiretap')
-rw-r--r-- | wiretap/AUTHORS | 2 | ||||
-rw-r--r-- | wiretap/Makefile.am | 4 | ||||
-rw-r--r-- | wiretap/Makefile.nmake | 3 | ||||
-rw-r--r-- | wiretap/file_access.c | 8 | ||||
-rw-r--r-- | wiretap/network_instruments.c | 290 | ||||
-rw-r--r-- | wiretap/network_instruments.h | 87 | ||||
-rw-r--r-- | wiretap/wtap.h | 5 |
7 files changed, 393 insertions, 6 deletions
diff --git a/wiretap/AUTHORS b/wiretap/AUTHORS index 8194ce4ddd..5216c86a3d 100644 --- a/wiretap/AUTHORS +++ b/wiretap/AUTHORS @@ -20,4 +20,4 @@ Martin Warnes <martin.warnes[AT]ntlworld.com> Thierry Martin <thierry.martin[AT]accellent-group.com> Jesper Peterson <jesper[AT]endace.com> Marcel Holtmann <marcel[AT]holtmann.org> - +Scott Emberley <scotte[AT]netinst.com> diff --git a/wiretap/Makefile.am b/wiretap/Makefile.am index 9780aff8e4..7b7acb9ee6 100644 --- a/wiretap/Makefile.am +++ b/wiretap/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Wiretap # -# $Id: Makefile.am,v 1.46 2003/10/30 03:11:02 guy Exp $ +# $Id: Makefile.am,v 1.47 2003/10/31 00:43:21 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@ethereal.com> @@ -69,6 +69,8 @@ libwiretap_a_SOURCES = \ netmon.h \ nettl.c \ nettl.h \ + network_instruments.c \ + network_instruments.h \ netxray.c \ netxray.h \ ngsniffer.c \ diff --git a/wiretap/Makefile.nmake b/wiretap/Makefile.nmake index 9e38b2f7b6..ed2d3f41b2 100644 --- a/wiretap/Makefile.nmake +++ b/wiretap/Makefile.nmake @@ -1,5 +1,5 @@ # -# $Id: Makefile.nmake,v 1.36 2003/10/30 03:11:02 guy Exp $ +# $Id: Makefile.nmake,v 1.37 2003/10/31 00:43:21 guy Exp $ # include ..\config.nmake @@ -32,6 +32,7 @@ OBJECTS=ascend-grammar.obj \ libpcap.obj \ netmon.obj \ nettl.obj \ + network_instruments.obj \ netxray.obj \ ngsniffer.obj \ radcom.obj \ diff --git a/wiretap/file_access.c b/wiretap/file_access.c index f5ef156da1..5efc3fb735 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -1,6 +1,6 @@ /* file_access.c * - * $Id: file_access.c,v 1.4 2003/10/30 03:11:02 guy Exp $ + * $Id: file_access.c,v 1.5 2003/10/31 00:43:21 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -71,6 +71,7 @@ #include "5views.h" #include "erf.h" #include "hcidump.h" +#include "network_instruments.h" /* The open_file_* routines should return: * @@ -104,6 +105,7 @@ static int (*const open_routines[])(wtap *, int *) = { nettl_open, visual_open, _5views_open, + network_instruments_open, /* Files that don't have magic bytes at a fixed location, * but that instead require a heuristic of some sort to @@ -441,6 +443,10 @@ static const struct file_type_info { /* WTAP_FILE_HCIDUMP */ { "Bluetooth HCI dump", "hcidump", NULL, NULL }, + + /* WTAP_FILE_NETWORK_INSTRUMENTS_V9 */ + { "Network Instruments Observer version 9", "niobserverv9", + NULL, NULL }, }; /* Name that should be somewhat descriptive. */ diff --git a/wiretap/network_instruments.c b/wiretap/network_instruments.c new file mode 100644 index 0000000000..bc74ea20e6 --- /dev/null +++ b/wiretap/network_instruments.c @@ -0,0 +1,290 @@ +/* + * $Id: network_instruments.c,v 1.1 2003/10/31 00:43:21 guy Exp $ + */ + +/*************************************************************************** + NetworkInstruments.c - description + ------------------- + begin : Wed Oct 29 2003 + copyright : (C) 2003 by root + email : scotte[AT}netinst.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include "wtap-int.h" +#include "file_wrappers.h" +#include "buffer.h" +#include "network_instruments.h" + +static const char network_instruments_magic[] = {"ObserverPktBufferVersion=09.00"}; +static const int true_magic_length = 17; + +static const guint32 observer_packet_magic = 0x88888888; + + static const int observer_encap[] = { + WTAP_ENCAP_ETHERNET, + WTAP_ENCAP_TOKEN_RING + }; +#define NUM_OBSERVER_ENCAPS (sizeof observer_encap / sizeof observer_encap[0]) + +static gboolean fill_time_struct(guint64 ns_since2000, observer_time* time_conversion); +static gboolean observer_read(wtap *wth, int *err, long *data_offset); +static gboolean observer_seek_read(wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, guchar *pd, int length, int *err); + +int network_instruments_open(wtap *wth, int *err) +{ + int bytes_read; + long seek_value; + + capture_file_header file_header; + packet_entry_header packet_header; + + errno = WTAP_ERR_CANT_READ; + + /* Read in the buffer file header */ + bytes_read = file_read(&file_header, sizeof file_header, 1, wth->fh); + if (bytes_read != sizeof file_header) { + *err = file_error(wth->fh); + if (*err != 0) + return -1; + return 0; + } + + /* check the magic number */ + if (memcmp(file_header.observer_version, network_instruments_magic, true_magic_length)!=0) { + return 0; + } + + /* check the version */ + if (strncmp(network_instruments_magic, file_header.observer_version, 30)!=0) { + g_message("Observer: unsupported file version %s", file_header.observer_version); + *err = WTAP_ERR_UNSUPPORTED_ENCAP; + return -1; + } + + /* get to the first packet */ + file_header.offset_to_first_packet = + GUINT16_FROM_LE(file_header.offset_to_first_packet); + seek_value = file_seek(wth->fh, file_header.offset_to_first_packet, SEEK_SET, err); + if (seek_value != file_header.offset_to_first_packet) { + *err = file_error(wth->fh); + if (*err != 0) + return -1; + return 0; + } + + /* pull off the packet header */ + bytes_read = file_read(&packet_header, sizeof packet_header, 1, wth->fh); + if (bytes_read != sizeof packet_header) { + *err = file_error(wth->fh); + if (*err != 0) + return -1; + return 0; + } + + /* check the packet's magic number; the magic number is all 8's, + so the byte order doesn't matter */ + if (packet_header.packet_magic != observer_packet_magic) { + g_message("Observer: unsupported packet version %ul", packet_header.packet_magic); + *err = WTAP_ERR_UNSUPPORTED_ENCAP; + return -1; + } + + /* Check the data link type. */ + if (packet_header.network_type >= NUM_OBSERVER_ENCAPS) { + g_message("observer: network type %u unknown or unsupported", packet_header.network_type); + *err = WTAP_ERR_UNSUPPORTED_ENCAP; + return -1; + } + wth->file_encap = observer_encap[packet_header.network_type]; + + wth->file_type = WTAP_FILE_NETWORK_INSTRUMENTS_V9; + + /* set up the rest of the capture parameters */ + wth->subtype_read = observer_read; + wth->subtype_seek_read = observer_seek_read; + wth->subtype_close = NULL; + wth->subtype_sequential_close = NULL; + wth->snapshot_length = 0; + + /* reset the pointer to the first packet */ + seek_value = file_seek(wth->fh, file_header.offset_to_first_packet, SEEK_SET, err); + if (seek_value != file_header.offset_to_first_packet) { + *err = file_error(wth->fh); + if (*err != 0) + return -1; + return 0; + } + wth->data_offset = file_header.offset_to_first_packet; + + return 1; +} + +/* reads the next packet */ +static gboolean observer_read(wtap *wth, int *err, long *data_offset) +{ + int bytes_read; + long seek_value, seek_increment; + long seconds, useconds; + + packet_entry_header packet_header; + + observer_time packet_time; + + *data_offset = wth->data_offset; + + /* pull off the packet header */ + bytes_read = file_read(&packet_header, sizeof packet_header, 1, wth->fh); + if (bytes_read != sizeof packet_header) { + *err = file_error(wth->fh); + if (*err != 0) + return -1; + return 0; + } + wth->data_offset += bytes_read; + + /* check the packet's magic number; the magic number is all 8's, + so the byte order doesn't matter */ + if (packet_header.packet_magic != observer_packet_magic) { + g_message("Observer: bad record"); + *err = WTAP_ERR_BAD_RECORD; + return FALSE; + } + + /* convert from observer time to wiretap time */ + packet_header.nano_seconds_since_2000 = + GUINT64_FROM_LE(packet_header.nano_seconds_since_2000); + fill_time_struct(packet_header.nano_seconds_since_2000, &packet_time); + useconds = (long)(packet_time.useconds_from_1970 - ((guint64)packet_time.seconds_from_1970)*1000000); + seconds = (long)packet_time.seconds_from_1970 - packet_time.time_stamp.tm_gmtoff; + + /* set-up the packet header */ + packet_header.network_size = + GUINT16_FROM_LE(packet_header.network_size); + packet_header.captured_size = + GUINT16_FROM_LE(packet_header.captured_size); + wth->phdr.pkt_encap = observer_encap[packet_header.network_type]; + wth->phdr.len = packet_header.network_size-4; /* neglect frame markers for wiretap */ + wth->phdr.caplen = MIN(packet_header.captured_size, wth->phdr.len); + wth->phdr.ts.tv_sec = seconds; + wth->phdr.ts.tv_usec = useconds; + + /* get to the frame data */ + packet_header.offset_to_frame = + GUINT16_FROM_LE(packet_header.offset_to_frame); + if (packet_header.offset_to_frame < sizeof(packet_header)) { + g_message("Observer: bad record (offset to frame %u < %lu)", + packet_header.offset_to_frame, + (unsigned long)sizeof(packet_header)); + *err = WTAP_ERR_BAD_RECORD; + return FALSE; + } + seek_increment = packet_header.offset_to_frame - sizeof(packet_header); + if(seek_increment>0) { + seek_value = file_seek(wth->fh, seek_increment, SEEK_CUR, err); + if (seek_value != seek_increment) { + *err = file_error(wth->fh); + g_message("Observer: bad record"); + *err = WTAP_ERR_BAD_RECORD; + return FALSE; + } + } + wth->data_offset += seek_increment; + + /* set-up the packet buffer */ + buffer_assure_space(wth->frame_buffer, packet_header.captured_size); + wtap_file_read_expected_bytes(buffer_start_ptr(wth->frame_buffer), packet_header.captured_size, wth->fh, err); + wth->data_offset += packet_header.captured_size; + + /* update the pseudo header */ + switch (wth->file_encap) { + + case WTAP_ENCAP_ETHERNET: + /* There is no FCS in the frame */ + wth->pseudo_header.eth.fcs_len = 0; + break; + } + + return TRUE; +} + +/* reads a packet at an offset */ +static gboolean observer_seek_read(wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, guchar *pd, int length, int *err) +{ + packet_entry_header packet_header; + + int bytes_read; + + if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) + return FALSE; + + /* pull off the packet header */ + bytes_read = file_read(&packet_header, sizeof packet_header, 1, wth->random_fh); + if (bytes_read != sizeof packet_header) { + *err = file_error(wth->fh); + if (*err != 0) + return -1; + return 0; + } + + /* check the packets magic number */ + if (packet_header.packet_magic != observer_packet_magic) { + g_message("Observer: bad record in observer_seek_read"); + *err = WTAP_ERR_BAD_RECORD; + return FALSE; + } + + /* read in the packet */ + bytes_read = file_read(pd, 1, length, wth->random_fh); + if (bytes_read != length) { + *err = file_error(wth->fh); + g_message("Observer: read error in observer_seek_read"); + return FALSE; + } + + /* update the pseudo header */ + switch (wth->file_encap) { + + case WTAP_ENCAP_ETHERNET: + /* There is no FCS in the frame */ + pseudo_header->eth.fcs_len = 0; + break; + } + + return TRUE; +} + +static guint32 seconds1970to2000 = (((30*365)+7)*24*60*60); /* 7 leap years */ +gboolean fill_time_struct(guint64 ns_since2000, observer_time* time_conversion) +{ + time_conversion->ns_since2000 = ns_since2000; + time_conversion->us_since2000 = ns_since2000/1000; + time_conversion->sec_since2000 = ns_since2000/1000000000; + + time_conversion->seconds_from_1970 = seconds1970to2000 + time_conversion->sec_since2000; + time_conversion->useconds_from_1970 = ((guint64)seconds1970to2000*1000000)+time_conversion->us_since2000; + +#if 0 + time_conversion->time_stamp = *localtime(&time_conversion->seconds_from_1970); +#endif + + return TRUE; +} + diff --git a/wiretap/network_instruments.h b/wiretap/network_instruments.h new file mode 100644 index 0000000000..be151976c5 --- /dev/null +++ b/wiretap/network_instruments.h @@ -0,0 +1,87 @@ +/* + * $Id: network_instruments.h,v 1.1 2003/10/31 00:43:21 guy Exp $ + */ + +/*************************************************************************** + NetworkInstruments.h - description + ------------------- + begin : Wed Oct 29 2003 + copyright : (C) 2003 by root + email : scotte[AT}netinst.com + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef __NETWORK_INSTRUMENTS_H__ +#define __NETWORK_INSTRUMENTS_H__ + +int network_instruments_open(wtap *wth, int *err); + +typedef struct capture_file_header +{ + char observer_version[32]; + guint16 offset_to_first_packet; + char probe_instance; + char extra_information_present; +} capture_file_header; + +typedef struct packet_entry_header +{ + guint32 packet_magic; + guint32 network_speed; + guint16 captured_size; + guint16 network_size; + guint16 offset_to_frame; + guint16 offset_to_next_packet; + guint8 network_type; + guint8 flags; + guint8 extra_information; + guint8 packet_type; + guint16 errors; + guint16 reserved; + guint64 packet_number; + guint64 original_packet_number; + guint64 nano_seconds_since_2000; +} packet_entry_header; + +typedef struct tlv_header +{ + guint16 type; + guint16 length; +} tlv_header; + +typedef struct tlv_alias_list +{ + tlv_header header; + char alias_list[1]; +} tlv_alias_list; + +typedef struct tlv_user_commnent +{ + tlv_header header; + char user_comment[1]; +} tlv_user_comment; + +typedef struct observer_time +{ + guint64 ns_since2000; /* given in packet_entry_header */ + struct tm time_stamp; + + guint64 us_since2000; /* Micro-Seconds since 1-1-2000 */ + guint64 sec_since2000; /* Seconds since 1-1-2000 */ + + time_t seconds_from_1970; + guint64 useconds_from_1970; + +} observer_time; + + +#endif + diff --git a/wiretap/wtap.h b/wiretap/wtap.h index b752515843..cdc174b7e8 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1,6 +1,6 @@ /* wtap.h * - * $Id: wtap.h,v 1.143 2003/10/30 03:11:03 guy Exp $ + * $Id: wtap.h,v 1.144 2003/10/31 00:43:21 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu> @@ -174,9 +174,10 @@ #define WTAP_FILE_5VIEWS 34 #define WTAP_FILE_ERF 35 #define WTAP_FILE_HCIDUMP 36 +#define WTAP_FILE_NETWORK_INSTRUMENTS_V9 37 /* last WTAP_FILE_ value + 1 */ -#define WTAP_NUM_FILE_TYPES 37 +#define WTAP_NUM_FILE_TYPES 38 /* * Maximum packet size we'll support. |