aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/network_instruments.c
diff options
context:
space:
mode:
Diffstat (limited to 'wiretap/network_instruments.c')
-rw-r--r--wiretap/network_instruments.c269
1 files changed, 154 insertions, 115 deletions
diff --git a/wiretap/network_instruments.c b/wiretap/network_instruments.c
index 726c1b7d05..c6c19bec36 100644
--- a/wiretap/network_instruments.c
+++ b/wiretap/network_instruments.c
@@ -42,10 +42,6 @@ static const int observer_encap[] = {
};
#define NUM_OBSERVER_ENCAPS (sizeof observer_encap / sizeof observer_encap[0])
-#define OBSERVER_UNDEFINED 0xFF
-#define OBSERVER_ETHERNET 0x00
-#define OBSERVER_TOKENRING 0x01
-#define OBSERVER_FDDI 0x02
static const int from_wtap_encap[] = {
OBSERVER_UNDEFINED,
OBSERVER_ETHERNET,
@@ -55,9 +51,6 @@ static const int from_wtap_encap[] = {
#define CAPTUREFILE_HEADER_SIZE sizeof(capture_file_header)
-#define INFORMATION_TYPE_ALIAS_LIST 0x01
-#define INFORMATION_TYPE_COMMENT 0x02
-
/*
* The time in Observer files is in nanoseconds since midnight, January 1,
* 2000, 00:00:00 local time.
@@ -95,12 +88,17 @@ static void init_time_offset(void)
}
}
-static gboolean fill_time_struct(guint64 ns_since2000, observer_time* time_conversion);
static gboolean observer_read(wtap *wth, int *err, gchar **err_info,
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, gchar **err_info);
+static int read_packet_header(FILE_T fh, packet_entry_header *packet_header,
+ int *err, gchar **err_info);
+static gboolean read_packet_data(FILE_T fh, int offset_to_frame, int offset,
+ guint8 *pd, int length, int *err, char **err_info);
+static gboolean skip_to_next_packet(wtap *wth, int offset,
+ int offset_to_next_packet, int *err, char **err_info);
static gboolean observer_dump_close(wtap_dumper *wdh, int *err);
static gboolean observer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
const union wtap_pseudo_header *pseudo_header, const guchar *pd, int *err);
@@ -165,7 +163,7 @@ int network_instruments_open(wtap *wth, int *err, gchar **err_info)
/* Check the data link type. */
if (packet_header.network_type >= NUM_OBSERVER_ENCAPS) {
*err = WTAP_ERR_UNSUPPORTED_ENCAP;
- *err_info = g_strdup_printf("observer: network type %u unknown or unsupported", packet_header.network_type);
+ *err_info = g_strdup_printf("Observer: network type %u unknown or unsupported", packet_header.network_type);
return -1;
}
wth->file_encap = observer_encap[packet_header.network_type];
@@ -198,13 +196,8 @@ int network_instruments_open(wtap *wth, int *err, gchar **err_info)
static gboolean observer_read(wtap *wth, int *err, gchar **err_info,
long *data_offset)
{
- int bytes_read;
- long seek_increment;
- long seconds, useconds;
-
+ int offset;
packet_entry_header packet_header;
-
- observer_time packet_time;
/*
* Skip records other than data records.
@@ -212,87 +205,57 @@ static gboolean observer_read(wtap *wth, int *err, gchar **err_info,
for (;;) {
*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;
+ /* process the packet header, including TLVs */
+ offset = read_packet_header(wth->fh, &packet_header, err,
+ err_info);
+ if (offset <= 0)
+ return FALSE; /* EOF or error */
- /* 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) {
- *err = WTAP_ERR_BAD_RECORD;
- *err_info = g_strdup_printf("Observer: bad record: Invalid magic number 0x%08x",
- GUINT32_FROM_LE(packet_header.packet_magic));
- return FALSE;
- }
+ wth->data_offset += offset;
- /* check the packet's record type, and skip non-data
- packets */
- if (packet_header.packet_type == TYPE_DATA_PACKET)
+ if (packet_header.packet_type == PACKET_TYPE_DATA_PACKET)
break;
/* skip to next packet */
packet_header.offset_to_next_packet =
GUINT16_FROM_LE(packet_header.offset_to_next_packet);
- if (packet_header.offset_to_next_packet < sizeof(packet_header)) {
- *err = WTAP_ERR_BAD_RECORD;
- *err_info = g_strdup_printf("Observer: bad record (offset to next packet %u < %lu)",
- packet_header.offset_to_next_packet,
- (unsigned long)sizeof(packet_header));
- return FALSE;
- }
- seek_increment = packet_header.offset_to_next_packet - sizeof(packet_header);
- if(seek_increment>0) {
- if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
- return FALSE;
- }
- wth->data_offset += seek_increment;
+ if (!skip_to_next_packet(wth, offset,
+ packet_header.offset_to_next_packet, err, err_info))
+ return FALSE; /* EOF or error */
}
- /* 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;
-
/* set-up the packet header */
packet_header.network_size =
GUINT16_FROM_LE(packet_header.network_size);
+ /* neglect frame markers for wiretap */
+ if (packet_header.network_size < 4) {
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("Observer: bad record: Packet length %u < 4",
+ packet_header.network_size);
+ return FALSE;
+ }
+ packet_header.network_size -= 4;
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.len = packet_header.network_size;
wth->phdr.caplen = MIN(packet_header.captured_size, wth->phdr.len);
- wth->phdr.ts.secs = seconds;
- wth->phdr.ts.nsecs = useconds * 1000;
-
- /* 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)) {
- *err = WTAP_ERR_BAD_RECORD;
- *err_info = g_strdup_printf("Observer: bad record (offset to frame %u < %lu)",
- packet_header.offset_to_frame,
- (unsigned long)sizeof(packet_header));
- return FALSE;
- }
- seek_increment = packet_header.offset_to_frame - sizeof(packet_header);
- if(seek_increment>0) {
- if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
- return FALSE;
- }
- wth->data_offset += seek_increment;
+ packet_header.nano_seconds_since_2000 =
+ GUINT64_FROM_LE(packet_header.nano_seconds_since_2000);
+ wth->phdr.ts.secs =
+ (time_t) (packet_header.nano_seconds_since_2000/1000000000 + seconds1970to2000);
+ wth->phdr.ts.nsecs = packet_header.nano_seconds_since_2000%1000000000;
/* 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);
+
+ /* read data */
+ if (!read_packet_data(wth->fh, packet_header.offset_to_frame, offset,
+ buffer_start_ptr(wth->frame_buffer), packet_header.captured_size,
+ err, err_info))
+ return FALSE;
wth->data_offset += packet_header.captured_size;
+ offset += packet_header.captured_size;
/* update the pseudo header */
switch (wth->file_encap) {
@@ -312,66 +275,142 @@ static gboolean observer_seek_read(wtap *wth, long seek_off,
int *err, gchar **err_info)
{
packet_entry_header packet_header;
- long seek_increment;
- int bytes_read;
+ int offset;
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
return FALSE;
+ /* process the packet header, including TLVs */
+ offset = read_packet_header(wth->random_fh, &packet_header, err,
+ err_info);
+ if (offset <= 0)
+ return FALSE; /* EOF or error */
+
+ /* read data */
+ if (!read_packet_data(wth->random_fh, packet_header.offset_to_frame,
+ offset, pd, length, err, err_info))
+ 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 int
+read_packet_header(FILE_T fh, packet_entry_header *packet_header, int *err,
+ gchar **err_info)
+{
+ int offset;
+ int bytes_read;
+ guint i;
+ tlv_header tlvh;
+ int seek_increment;
+
+ offset = 0;
+
/* 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);
+ bytes_read = file_read(packet_header, sizeof *packet_header, 1, fh);
+ if (bytes_read != sizeof *packet_header) {
+ *err = file_error(fh);
if (*err != 0)
return -1;
- return 0;
+ return 0; /* EOF */
}
+ offset += bytes_read;
- /* check the packets magic number */
- if (packet_header.packet_magic != observer_packet_magic) {
+ /* 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) {
*err = WTAP_ERR_BAD_RECORD;
- *err_info = g_strdup("Observer: bad magic number for record in observer_seek_read");
- return FALSE;
+ *err_info = g_strdup_printf("Observer: bad record: Invalid magic number 0x%08x",
+ GUINT32_FROM_LE(packet_header->packet_magic));
+ return -1;
}
+ /* process extra information */
+ for (i = 0; i < packet_header->number_of_information_elements; i++) {
+ /* read the TLV header */
+ bytes_read = file_read(&tlvh, sizeof tlvh, 1, fh);
+ if (bytes_read != sizeof tlvh) {
+ *err = file_error(fh);
+ if (*err == 0)
+ *err = WTAP_ERR_SHORT_READ;
+ return -1;
+ }
+ offset += bytes_read;
- /* get the frame offset */
- packet_header.offset_to_frame =
- GUINT16_FROM_LE(packet_header.offset_to_frame);
- seek_increment = packet_header.offset_to_frame - sizeof(packet_header);
- if(seek_increment>0) {
- if (file_seek(wth->random_fh, seek_increment, SEEK_CUR, err) == -1)
- return FALSE;
- }
+ tlvh.length = GUINT16_FROM_LE(tlvh.length);
+ if (tlvh.length < sizeof tlvh) {
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("Observer: bad record (TLV length %u < %lu)",
+ tlvh.length, (unsigned long)sizeof tlvh);
+ return -1;
+ }
- /* read in the packet */
- bytes_read = file_read(pd, 1, length, wth->random_fh);
- if (bytes_read != length) {
- *err = file_error(wth->fh);
- return FALSE;
+ /* skip the TLV data */
+ seek_increment = tlvh.length - sizeof tlvh;
+ if(seek_increment>0) {
+ if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1)
+ return -1;
+ }
+ offset += seek_increment;
}
- /* update the pseudo header */
- switch (wth->file_encap) {
+ packet_header->offset_to_frame =
+ GUINT16_FROM_LE(packet_header->offset_to_frame);
- case WTAP_ENCAP_ETHERNET:
- /* There is no FCS in the frame */
- pseudo_header->eth.fcs_len = 0;
- break;
+ return offset;
+}
+
+static gboolean
+read_packet_data(FILE_T fh, int offset_to_frame, int offset, guint8 *pd,
+ int length, int *err, char **err_info)
+{
+ int seek_increment;
+
+ /* get to the packet data */
+ if (offset_to_frame < offset) {
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("Observer: bad record (offset to frame %d < %d)",
+ offset_to_frame, offset);
+ return FALSE;
+ }
+ seek_increment = offset_to_frame - offset;
+ if(seek_increment>0) {
+ if (file_seek(fh, seek_increment, SEEK_CUR, err) == -1)
+ return FALSE;
}
+ /* read in the packet */
+ wtap_file_read_expected_bytes(pd, length, fh, err);
return TRUE;
}
-gboolean fill_time_struct(guint64 ns_since2000, observer_time* time_conversion)
+static gboolean
+skip_to_next_packet(wtap *wth, int offset, int offset_to_next_packet, int *err,
+ char **err_info)
{
- 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 = (time_t) (seconds1970to2000 + time_conversion->sec_since2000);
- time_conversion->useconds_from_1970 = ((guint64)seconds1970to2000*1000000)+time_conversion->us_since2000;
+ int seek_increment;
+ if (offset_to_next_packet < offset) {
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup_printf("Observer: bad record (offset to next packet %d < %d)",
+ offset_to_next_packet, offset);
+ return FALSE;
+ }
+ seek_increment = offset_to_next_packet - offset;
+ if(seek_increment>0) {
+ if (file_seek(wth->fh, seek_increment, SEEK_CUR, err) == -1)
+ return FALSE;
+ }
+ wth->data_offset += seek_increment;
return TRUE;
}
@@ -425,7 +464,7 @@ gboolean network_instruments_dump_open(wtap_dumper *wdh, gboolean cant_seek, int
memset(&file_header, 0x00, sizeof(capture_file_header));
strcpy(file_header.observer_version, network_instruments_magic);
file_header.offset_to_first_packet = sizeof(capture_file_header) + sizeof(tlv_header) + strlen(comment);
- file_header.extra_information_present = 0x01; /* actually the number of information elements */
+ file_header.number_of_information_elements = 1;
if(!fwrite(&file_header, sizeof(capture_file_header), 1, wdh->fh)) {
*err = errno;
return FALSE;
@@ -477,8 +516,8 @@ static gboolean observer_dump(wtap_dumper *wdh, const struct wtap_pkthdr *phdr,
packet_header.offset_to_next_packet = GUINT16_TO_LE(sizeof(packet_entry_header) + phdr->caplen);
packet_header.network_type = niobserver->network_type;
packet_header.flags = 0x00;
- packet_header.extra_information = 0x00;
- packet_header.packet_type = 0x00;
+ packet_header.number_of_information_elements = 0;
+ packet_header.packet_type = PACKET_TYPE_DATA_PACKET;
packet_header.packet_number = GUINT64_TO_LE(niobserver->packet_count);
packet_header.original_packet_number = GUINT64_TO_LE(niobserver->packet_count);
niobserver->packet_count++;