2010-10-20 00:36:53 +00:00
|
|
|
/* ipfix.c
|
|
|
|
*
|
|
|
|
* Wiretap Library
|
|
|
|
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
|
|
|
|
*
|
|
|
|
* File format support for ipfix file format
|
|
|
|
* Copyright (c) 2010 by Hadriel Kaplan <hadrielk@yahoo.com>
|
|
|
|
* with generous copying from other wiretaps, such as pcapng
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2012-06-28 22:56:06 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2010-10-20 00:36:53 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* File format reference:
|
|
|
|
* RFC 5655 and 5101
|
|
|
|
* http://tools.ietf.org/rfc/rfc5655
|
|
|
|
* http://tools.ietf.org/rfc/rfc5101
|
|
|
|
*
|
|
|
|
* This wiretap is for an ipfix file format reader, per RFC 5655/5101.
|
|
|
|
* All "records" in the file are IPFIX messages, beginning with an IPFIX
|
|
|
|
* message header of 16 bytes as follows from RFC 5101:
|
|
|
|
0 1 2 3
|
|
|
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
| Version Number | Length |
|
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
| Export Time |
|
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
| Sequence Number |
|
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
| Observation Domain ID |
|
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
|
|
|
|
Figure F: IPFIX Message Header Format
|
|
|
|
|
|
|
|
* which is then followed by one or more "Sets": Data Sets, Template Sets,
|
|
|
|
* and Options Template Sets. Each Set then has one or more Records in
|
|
|
|
* it.
|
|
|
|
*
|
|
|
|
* All IPFIX files are recorded in big-endian form (network byte order),
|
|
|
|
* per the RFCs. That means if we're on a little-endian system, all
|
|
|
|
* hell will break loose if we don't g_ntohX.
|
|
|
|
*
|
|
|
|
* Since wireshark already has an IPFIX dissector (implemented in
|
|
|
|
* packet-netflow.c), this reader will just set that dissector upon
|
|
|
|
* reading each message. Thus, an IPFIX Message is treated as a packet
|
|
|
|
* as far as the dissector is concerned.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include "wtap-int.h"
|
|
|
|
#include "file_wrappers.h"
|
2014-07-15 23:40:46 +00:00
|
|
|
#include <wsutil/buffer.h>
|
2010-10-20 00:36:53 +00:00
|
|
|
#include "libpcap.h"
|
|
|
|
#include "pcap-common.h"
|
|
|
|
#include "pcap-encap.h"
|
|
|
|
#include "ipfix.h"
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
#define ipfix_debug0(str) g_warning(str)
|
|
|
|
#define ipfix_debug1(str,p1) g_warning(str,p1)
|
|
|
|
#define ipfix_debug2(str,p1,p2) g_warning(str,p1,p2)
|
|
|
|
#define ipfix_debug3(str,p1,p2,p3) g_warning(str,p1,p2,p3)
|
|
|
|
#else
|
|
|
|
#define ipfix_debug0(str)
|
|
|
|
#define ipfix_debug1(str,p1)
|
|
|
|
#define ipfix_debug2(str,p1,p2)
|
|
|
|
#define ipfix_debug3(str,p1,p2,p3)
|
|
|
|
#endif
|
|
|
|
|
2010-10-20 17:20:56 +00:00
|
|
|
#define RECORDS_FOR_IPFIX_CHECK 20
|
|
|
|
|
2014-05-23 10:50:02 +00:00
|
|
|
static gboolean
|
2014-05-09 05:18:49 +00:00
|
|
|
ipfix_read(wtap *wth, int *err, gchar **err_info,
|
2010-10-20 00:36:53 +00:00
|
|
|
gint64 *data_offset);
|
2014-05-23 10:50:02 +00:00
|
|
|
static gboolean
|
2014-05-09 05:18:49 +00:00
|
|
|
ipfix_seek_read(wtap *wth, gint64 seek_off,
|
|
|
|
struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info);
|
2010-10-20 00:36:53 +00:00
|
|
|
|
|
|
|
#define IPFIX_VERSION 10
|
|
|
|
|
|
|
|
/* ipfix: message header */
|
|
|
|
typedef struct ipfix_message_header_s {
|
|
|
|
guint16 version;
|
|
|
|
guint16 message_length;
|
|
|
|
guint32 export_time_secs;
|
|
|
|
guint32 sequence_number;
|
|
|
|
guint32 observation_id; /* might be 0 for none */
|
|
|
|
/* x bytes msg_body */
|
|
|
|
} ipfix_message_header_t;
|
|
|
|
#define IPFIX_MSG_HDR_SIZE 16
|
|
|
|
|
|
|
|
/* ipfix: common Set header for every Set type */
|
|
|
|
typedef struct ipfix_set_header_s {
|
|
|
|
guint16 set_type;
|
|
|
|
guint16 set_length;
|
|
|
|
/* x bytes set_body */
|
|
|
|
} ipfix_set_header_t;
|
|
|
|
#define IPFIX_SET_HDR_SIZE 4
|
|
|
|
|
|
|
|
|
2013-05-17 07:28:34 +00:00
|
|
|
/* Read IPFIX message header from file. Return true on success. Set *err to
|
|
|
|
* 0 on EOF, any other value for "real" errors (EOF is ok, since return
|
|
|
|
* value is still FALSE)
|
2010-10-20 00:36:53 +00:00
|
|
|
*/
|
2010-10-20 17:20:56 +00:00
|
|
|
static gboolean
|
2013-05-17 07:28:34 +00:00
|
|
|
ipfix_read_message_header(ipfix_message_header_t *pfx_hdr, FILE_T fh, int *err, gchar **err_info)
|
2010-10-20 00:36:53 +00:00
|
|
|
{
|
Add some higher-level file-read APIs and use them.
Add wtap_read_bytes(), which takes a FILE_T, a pointer, a byte count, an
error number pointer, and an error string pointer as arguments, and that
treats a short read of any sort, including a read that returns 0 bytes,
as a WTAP_ERR_SHORT_READ error, and that returns the error number and
string through its last two arguments.
Add wtap_read_bytes_or_eof(), which is similar, but that treats a read
that returns 0 bytes as an EOF, supplying an error number of 0 as an EOF
indication.
Use those in file readers; that simplifies the code and makes it less
likely that somebody will fail to supply the error number and error
string on a file read error.
Change-Id: Ia5dba2a6f81151e87b614461349d611cffc16210
Reviewed-on: https://code.wireshark.org/review/4512
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2014-10-07 01:00:57 +00:00
|
|
|
if (!wtap_read_bytes_or_eof(fh, pfx_hdr, IPFIX_MSG_HDR_SIZE, err, err_info))
|
|
|
|
return FALSE;
|
2010-10-20 00:36:53 +00:00
|
|
|
|
|
|
|
/* fix endianess, because IPFIX files are always big-endian */
|
2013-05-17 07:28:34 +00:00
|
|
|
pfx_hdr->version = g_ntohs(pfx_hdr->version);
|
|
|
|
pfx_hdr->message_length = g_ntohs(pfx_hdr->message_length);
|
|
|
|
pfx_hdr->export_time_secs = g_ntohl(pfx_hdr->export_time_secs);
|
|
|
|
pfx_hdr->sequence_number = g_ntohl(pfx_hdr->sequence_number);
|
|
|
|
pfx_hdr->observation_id = g_ntohl(pfx_hdr->observation_id);
|
2010-10-20 00:36:53 +00:00
|
|
|
|
|
|
|
/* is the version number one we expect? */
|
2013-05-17 07:28:34 +00:00
|
|
|
if (pfx_hdr->version != IPFIX_VERSION) {
|
2010-10-20 00:36:53 +00:00
|
|
|
/* Not an ipfix file. */
|
2011-12-13 09:53:50 +00:00
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
2013-05-17 07:28:34 +00:00
|
|
|
*err_info = g_strdup_printf("ipfix: wrong version %d", pfx_hdr->version);
|
2010-10-20 00:36:53 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2013-05-17 07:28:34 +00:00
|
|
|
if (pfx_hdr->message_length < 16) {
|
2011-12-13 09:53:50 +00:00
|
|
|
*err = WTAP_ERR_BAD_FILE;
|
2013-05-17 07:28:34 +00:00
|
|
|
*err_info = g_strdup_printf("ipfix: message length %u is too short", pfx_hdr->message_length);
|
2010-10-20 00:36:53 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* go back to before header */
|
|
|
|
if (file_seek(fh, 0 - IPFIX_MSG_HDR_SIZE, SEEK_CUR, err) == -1) {
|
|
|
|
ipfix_debug0("ipfix_read: couldn't go back in file before header");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2013-05-17 07:28:34 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Read IPFIX message header from file and fill in the struct wtap_pkthdr
|
2013-06-17 21:18:47 +00:00
|
|
|
* for the packet, and, if that succeeds, read the packet data.
|
|
|
|
* Return true on success. Set *err to 0 on EOF, any other value for "real"
|
|
|
|
* errors (EOF is ok, since return value is still FALSE).
|
2013-05-17 07:28:34 +00:00
|
|
|
*/
|
|
|
|
static gboolean
|
2013-06-17 21:18:47 +00:00
|
|
|
ipfix_read_message(FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, int *err, gchar **err_info)
|
2013-05-17 07:28:34 +00:00
|
|
|
{
|
|
|
|
ipfix_message_header_t msg_hdr;
|
|
|
|
|
|
|
|
if (!ipfix_read_message_header(&msg_hdr, fh, err, err_info))
|
|
|
|
return FALSE;
|
|
|
|
|
2014-05-24 18:28:30 +00:00
|
|
|
phdr->rec_type = REC_TYPE_PACKET;
|
2013-05-17 07:45:36 +00:00
|
|
|
phdr->presence_flags = WTAP_HAS_TS;
|
2013-05-17 07:28:34 +00:00
|
|
|
phdr->len = msg_hdr.message_length;
|
|
|
|
phdr->caplen = msg_hdr.message_length;
|
2013-05-17 07:45:36 +00:00
|
|
|
phdr->ts.secs = msg_hdr.export_time_secs;
|
2013-05-17 07:28:34 +00:00
|
|
|
phdr->ts.nsecs = 0;
|
2013-05-17 06:41:20 +00:00
|
|
|
|
2013-06-17 21:18:47 +00:00
|
|
|
return wtap_read_packet_bytes(fh, buf, msg_hdr.message_length, err, err_info);
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-10-09 23:44:15 +00:00
|
|
|
/* classic wtap: open capture file. Return WTAP_OPEN_MINE on success,
|
|
|
|
* WTAP_OPEN_NOT_MINE on normal failure like malformed format,
|
|
|
|
* WTAP_OPEN_ERROR on bad error like file system
|
2010-10-20 00:36:53 +00:00
|
|
|
*/
|
2014-10-09 23:44:15 +00:00
|
|
|
wtap_open_return_val
|
2014-05-09 05:18:49 +00:00
|
|
|
ipfix_open(wtap *wth, int *err, gchar **err_info)
|
2010-10-20 00:36:53 +00:00
|
|
|
{
|
|
|
|
gint i, n, records_for_ipfix_check = RECORDS_FOR_IPFIX_CHECK;
|
|
|
|
gchar *s;
|
|
|
|
guint16 checked_len = 0;
|
|
|
|
ipfix_message_header_t msg_hdr;
|
|
|
|
ipfix_set_header_t set_hdr;
|
|
|
|
|
|
|
|
ipfix_debug0("ipfix_open: opening file");
|
|
|
|
|
2010-10-21 14:23:22 +00:00
|
|
|
/* number of records to scan before deciding if this really is IPFIX */
|
2010-10-20 00:36:53 +00:00
|
|
|
if ((s = getenv("IPFIX_RECORDS_TO_CHECK")) != NULL) {
|
|
|
|
if ((n = atoi(s)) > 0 && n < 101) {
|
|
|
|
records_for_ipfix_check = n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* IPFIX is a little hard because there's no magic number; we look at
|
|
|
|
* the first few records and see if they look enough like IPFIX
|
|
|
|
* records.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < records_for_ipfix_check; i++) {
|
|
|
|
/* read first message header to check version */
|
2014-05-09 05:18:49 +00:00
|
|
|
if (!ipfix_read_message_header(&msg_hdr, wth->fh, err, err_info)) {
|
2010-10-20 17:20:56 +00:00
|
|
|
ipfix_debug3("ipfix_open: couldn't read message header #%d with err code #%d (%s)",
|
|
|
|
i, *err, *err_info);
|
2011-12-13 09:53:50 +00:00
|
|
|
if (*err == WTAP_ERR_BAD_FILE) {
|
2010-10-20 17:20:56 +00:00
|
|
|
*err = 0; /* not actually an error in this case */
|
|
|
|
g_free(*err_info);
|
|
|
|
*err_info = NULL;
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_NOT_MINE;
|
2010-10-20 17:20:56 +00:00
|
|
|
}
|
Do not call wtap_file_read_unknown_bytes() or
wtap_file_read_expected_bytes() from an open routine - open routines are
supposed to return -1 on error, 0 if the file doesn't appear to be a
file of the specified type, or 1 if the file does appear to be a file of
the specified type, but those macros will cause the caller to return
FALSE on errors (so that, even if there's an I/O error, it reports "the
file isn't a file of the specified type" rather than "we got an error
trying to read the file").
When doing reads in an open routine before we've concluded that the file
is probably of the right type, return 0, rather than -1, if we get
WTAP_ERR_SHORT_READ - if we don't have enough data to check whether a
file is of a given type, we should keep trying other types, not give up.
For reads done *after* we've concluded the file is probably of the right
type, if a read doesn't return the number of bytes we asked for, but
returns an error of 0, return WTAP_ERR_SHORT_READ - the file is
apparently cut short.
For NetMon and NetXRay/Windows Sniffer files, use a #define for the
magic number size, and use that for both magic numbers.
svn path=/trunk/; revision=46803
2012-12-27 12:19:25 +00:00
|
|
|
if (*err != 0 && *err != WTAP_ERR_SHORT_READ)
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_ERROR; /* real failure */
|
2010-10-20 00:36:53 +00:00
|
|
|
/* else it's EOF */
|
|
|
|
if (i < 1) {
|
|
|
|
/* we haven't seen enough to prove this is a ipfix file */
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_NOT_MINE;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
2013-05-17 07:28:34 +00:00
|
|
|
/*
|
|
|
|
* If we got here, it's EOF and we haven't yet seen anything
|
|
|
|
* that doesn't look like an IPFIX record - i.e. everything
|
|
|
|
* we've seen looks like an IPFIX record - so we assume this
|
|
|
|
* is an IPFIX file.
|
|
|
|
*/
|
2010-10-20 00:36:53 +00:00
|
|
|
break;
|
|
|
|
}
|
2014-05-09 05:18:49 +00:00
|
|
|
if (file_seek(wth->fh, IPFIX_MSG_HDR_SIZE, SEEK_CUR, err) == -1) {
|
2010-10-20 00:36:53 +00:00
|
|
|
ipfix_debug1("ipfix_open: failed seek to next message in file, %d bytes away",
|
|
|
|
msg_hdr.message_length);
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_NOT_MINE;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
|
|
|
checked_len = IPFIX_MSG_HDR_SIZE;
|
|
|
|
|
|
|
|
/* check each Set in IPFIX Message for sanity */
|
|
|
|
while (checked_len < msg_hdr.message_length) {
|
Add some higher-level file-read APIs and use them.
Add wtap_read_bytes(), which takes a FILE_T, a pointer, a byte count, an
error number pointer, and an error string pointer as arguments, and that
treats a short read of any sort, including a read that returns 0 bytes,
as a WTAP_ERR_SHORT_READ error, and that returns the error number and
string through its last two arguments.
Add wtap_read_bytes_or_eof(), which is similar, but that treats a read
that returns 0 bytes as an EOF, supplying an error number of 0 as an EOF
indication.
Use those in file readers; that simplifies the code and makes it less
likely that somebody will fail to supply the error number and error
string on a file read error.
Change-Id: Ia5dba2a6f81151e87b614461349d611cffc16210
Reviewed-on: https://code.wireshark.org/review/4512
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2014-10-07 01:00:57 +00:00
|
|
|
if (!wtap_read_bytes(wth->fh, &set_hdr, IPFIX_SET_HDR_SIZE,
|
2014-10-07 07:39:54 +00:00
|
|
|
err, err_info)) {
|
Add some higher-level file-read APIs and use them.
Add wtap_read_bytes(), which takes a FILE_T, a pointer, a byte count, an
error number pointer, and an error string pointer as arguments, and that
treats a short read of any sort, including a read that returns 0 bytes,
as a WTAP_ERR_SHORT_READ error, and that returns the error number and
string through its last two arguments.
Add wtap_read_bytes_or_eof(), which is similar, but that treats a read
that returns 0 bytes as an EOF, supplying an error number of 0 as an EOF
indication.
Use those in file readers; that simplifies the code and makes it less
likely that somebody will fail to supply the error number and error
string on a file read error.
Change-Id: Ia5dba2a6f81151e87b614461349d611cffc16210
Reviewed-on: https://code.wireshark.org/review/4512
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2014-10-07 01:00:57 +00:00
|
|
|
if (*err == WTAP_ERR_SHORT_READ) {
|
2014-09-23 01:13:59 +00:00
|
|
|
/* Not a valid IPFIX Set, so not an IPFIX file. */
|
|
|
|
ipfix_debug1("ipfix_open: error %d reading set", *err);
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_NOT_MINE;
|
2014-09-23 01:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* A real I/O error; fail. */
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_ERROR;
|
2014-09-23 01:13:59 +00:00
|
|
|
}
|
2010-10-20 00:36:53 +00:00
|
|
|
set_hdr.set_length = g_ntohs(set_hdr.set_length);
|
|
|
|
if ((set_hdr.set_length < IPFIX_SET_HDR_SIZE) ||
|
|
|
|
((set_hdr.set_length + checked_len) > msg_hdr.message_length)) {
|
|
|
|
ipfix_debug1("ipfix_open: found invalid set_length of %d",
|
|
|
|
set_hdr.set_length);
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_NOT_MINE;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
|
|
|
|
2014-05-09 05:18:49 +00:00
|
|
|
if (file_seek(wth->fh, set_hdr.set_length - IPFIX_SET_HDR_SIZE,
|
2010-10-20 00:36:53 +00:00
|
|
|
SEEK_CUR, err) == -1)
|
|
|
|
{
|
|
|
|
ipfix_debug1("ipfix_open: failed seek to next set in file, %d bytes away",
|
|
|
|
set_hdr.set_length - IPFIX_SET_HDR_SIZE);
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_ERROR;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
|
|
|
checked_len += set_hdr.set_length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-09 23:44:15 +00:00
|
|
|
/* go back to beginning of file */
|
|
|
|
if (file_seek (wth->fh, 0, SEEK_SET, err) != 0)
|
|
|
|
{
|
|
|
|
return WTAP_OPEN_ERROR;
|
|
|
|
}
|
|
|
|
|
2010-10-20 00:36:53 +00:00
|
|
|
/* all's good, this is a IPFIX file */
|
2014-05-09 05:18:49 +00:00
|
|
|
wth->file_encap = WTAP_ENCAP_RAW_IPFIX;
|
|
|
|
wth->snapshot_length = 0;
|
2014-09-28 18:37:06 +00:00
|
|
|
wth->file_tsprec = WTAP_TSPREC_SEC;
|
2014-05-09 05:18:49 +00:00
|
|
|
wth->subtype_read = ipfix_read;
|
|
|
|
wth->subtype_seek_read = ipfix_seek_read;
|
|
|
|
wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_IPFIX;
|
2010-10-20 00:36:53 +00:00
|
|
|
|
2014-10-09 23:44:15 +00:00
|
|
|
return WTAP_OPEN_MINE;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* classic wtap: read packet */
|
2014-05-23 10:50:02 +00:00
|
|
|
static gboolean
|
2014-05-09 05:18:49 +00:00
|
|
|
ipfix_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
|
2010-10-20 00:36:53 +00:00
|
|
|
{
|
2014-05-09 05:18:49 +00:00
|
|
|
*data_offset = file_tell(wth->fh);
|
2012-05-04 16:56:18 +00:00
|
|
|
ipfix_debug1("ipfix_read: data_offset is initially %" G_GINT64_MODIFIER "d", *data_offset);
|
2010-10-20 00:36:53 +00:00
|
|
|
|
2014-05-09 05:18:49 +00:00
|
|
|
if (!ipfix_read_message(wth->fh, &wth->phdr, wth->frame_buffer, err, err_info)) {
|
2010-10-20 00:36:53 +00:00
|
|
|
ipfix_debug2("ipfix_read: couldn't read message header with code: %d\n, and error '%s'",
|
|
|
|
*err, *err_info);
|
2014-05-23 10:50:02 +00:00
|
|
|
return FALSE;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
|
|
|
|
2014-05-23 10:50:02 +00:00
|
|
|
return TRUE;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* classic wtap: seek to file position and read packet */
|
2014-05-23 10:50:02 +00:00
|
|
|
static gboolean
|
2014-05-09 05:18:49 +00:00
|
|
|
ipfix_seek_read(wtap *wth, gint64 seek_off, struct wtap_pkthdr *phdr,
|
2014-01-02 20:47:21 +00:00
|
|
|
Buffer *buf, int *err, gchar **err_info)
|
2010-10-20 00:36:53 +00:00
|
|
|
{
|
|
|
|
/* seek to the right file position */
|
2014-05-09 05:18:49 +00:00
|
|
|
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) {
|
2010-10-20 00:36:53 +00:00
|
|
|
ipfix_debug2("ipfix_seek_read: couldn't read message header with code: %d\n, and error '%s'",
|
|
|
|
*err, *err_info);
|
2014-05-23 10:50:02 +00:00
|
|
|
return FALSE; /* Seek error */
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ipfix_debug1("ipfix_seek_read: reading at offset %" G_GINT64_MODIFIER "u", seek_off);
|
|
|
|
|
2014-05-09 05:18:49 +00:00
|
|
|
if (!ipfix_read_message(wth->random_fh, phdr, buf, err, err_info)) {
|
2013-05-17 06:41:20 +00:00
|
|
|
ipfix_debug0("ipfix_seek_read: couldn't read message header");
|
2013-06-17 21:18:47 +00:00
|
|
|
if (*err == 0)
|
|
|
|
*err = WTAP_ERR_SHORT_READ;
|
2014-05-23 10:50:02 +00:00
|
|
|
return FALSE;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|
2014-05-23 10:50:02 +00:00
|
|
|
return TRUE;
|
2010-10-20 00:36:53 +00:00
|
|
|
}
|