*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*
*/
#include "config.h"
#include "iptrace.h"
#include <stdlib.h>
#include <string.h>
#include "wtap-int.h"
#include "file_wrappers.h"
#include "atm.h"
* Private per-wtap_t data needed to read a file.
*/
typedef struct {
GHashTable *interface_ids;
unsigned num_interface_ids;
} iptrace_t;
#define IPTRACE_IFT_HF 0x3d
#define IPTRACE_IFT_IB 0xc7
static void iptrace_close(wtap *wth);
static bool iptrace_read_1_0(wtap *wth, wtap_rec *rec,
Buffer *buf, int *err, char **err_info, int64_t *data_offset);
static bool iptrace_seek_read_1_0(wtap *wth, int64_t seek_off,
wtap_rec *rec, Buffer *buf, int *err, char **err_info);
static bool iptrace_read_2_0(wtap *wth, wtap_rec *rec,
Buffer *buf, int *err, char **err_info, int64_t *data_offset);
static bool iptrace_seek_read_2_0(wtap *wth, int64_t seek_off,
wtap_rec *rec, Buffer *buf, int *err, char **err_info);
static bool iptrace_read_rec_data(FILE_T fh, Buffer *buf,
wtap_rec *rec, int *err, char **err_info);
static void fill_in_pseudo_header(int encap,
union wtap_pseudo_header *pseudo_header, const char *pkt_text);
static int wtap_encap_ift(unsigned int ift);
* Size of the version string in the file header.
*/
#define VERSION_STRING_SIZE 11
* Hash table to map interface name and description, and link-layer
* type, to interface ID.
*/
#define PREFIX_SIZE 4
typedef struct {
char prefix[PREFIX_SIZE+1];
uint8_t unit;
uint8_t if_type;
} if_info;
static int iptrace_1_0_file_type_subtype = -1;
static int iptrace_2_0_file_type_subtype = -1;
void register_iptrace(void);
static gboolean destroy_if_info(void *key, void *value _U_,
void *user_data _U_)
{
if_info *info = (if_info *)key;
g_free(info);
return true;
}
static unsigned if_info_hash(const void *info_arg)
{
if_info *info = (if_info *)info_arg;
return g_str_hash(info->prefix) + info->unit + info->if_type;
}
static gboolean if_info_equal(const void *info1_arg, const void *info2_arg)
{
if_info *info1 = (if_info *)info1_arg;
if_info *info2 = (if_info *)info2_arg;
return strcmp(info1->prefix, info2->prefix) == 0 &&
info1->unit == info2->unit &&
info1->if_type == info2->if_type;
}
wtap_open_return_val iptrace_open(wtap *wth, int *err, char **err_info)
{
char version_string[VERSION_STRING_SIZE+1];
iptrace_t *iptrace;
if (!wtap_read_bytes(wth->fh, version_string, VERSION_STRING_SIZE,
err, err_info)) {
if (*err != WTAP_ERR_SHORT_READ)
return WTAP_OPEN_ERROR;
return WTAP_OPEN_NOT_MINE;
}
version_string[VERSION_STRING_SIZE] = '\0';
if (strcmp(version_string, "iptrace 1.0") == 0) {
wth->file_type_subtype = iptrace_1_0_file_type_subtype;
wth->subtype_read = iptrace_read_1_0;
wth->subtype_seek_read = iptrace_seek_read_1_0;
wth->file_tsprec = WTAP_TSPREC_SEC;
}
else if (strcmp(version_string, "iptrace 2.0") == 0) {
wth->file_type_subtype = iptrace_2_0_file_type_subtype;
wth->subtype_read = iptrace_read_2_0;
wth->subtype_seek_read = iptrace_seek_read_2_0;
wth->file_tsprec = WTAP_TSPREC_NSEC;
}
else {
return WTAP_OPEN_NOT_MINE;
}
wth->subtype_close = iptrace_close;
iptrace = g_new(iptrace_t, 1);
iptrace->interface_ids = g_hash_table_new(if_info_hash, if_info_equal);
iptrace->num_interface_ids = 0;
wth->priv = (void *)iptrace;
return WTAP_OPEN_MINE;
}
static void iptrace_close(wtap *wth)
{
iptrace_t *iptrace = (iptrace_t *)wth->priv;
g_hash_table_foreach_remove(iptrace->interface_ids, destroy_if_info, NULL);
g_hash_table_destroy(iptrace->interface_ids);
}
static void add_new_if_info(iptrace_t *iptrace, if_info *info, void * *result)
{
if_info *new_info = g_new(if_info, 1);
*new_info = *info;
*result = GUINT_TO_POINTER(iptrace->num_interface_ids);
g_hash_table_insert(iptrace->interface_ids, (void *)new_info, *result);
iptrace->num_interface_ids++;
}
* iptrace 1.0 *
***********************************************************/
* iptrace 1.0, discovered through inspection
*
* Packet record contains:
*
* an initial header, with a length field and a time stamp, in
* seconds since the Epoch;
*
* data, with the specified length.
*
* The data contains:
*
* a bunch of information about the packet;
*
* padding, at least for FDDI;
*
* the raw packet data.
*/
* Offsets of fields in the initial header.
*/
#define IPTRACE_1_0_REC_LENGTH_OFFSET 0
#define IPTRACE_1_0_TV_SEC_OFFSET 4
#define IPTRACE_1_0_PHDR_SIZE 8
* Offsets of fields in the packet information.
*/
#define IPTRACE_1_0_UNIT_OFFSET 3
#define IPTRACE_1_0_PREFIX_OFFSET 4
#define IPTRACE_1_0_PKT_TEXT_OFFSET 8
#define IPTRACE_1_0_IF_TYPE_OFFSET 20
#define IPTRACE_1_0_TX_FLAGS_OFFSET 21
#define IPTRACE_1_0_PINFO_SIZE 22
static bool
iptrace_read_rec_1_0(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf,
int *err, char **err_info)
{
iptrace_t *iptrace = (iptrace_t *)wth->priv;
uint8_t header[IPTRACE_1_0_PHDR_SIZE];
uint32_t record_length;
uint8_t pkt_info[IPTRACE_1_0_PINFO_SIZE];
if_info info;
uint32_t packet_size;
void *result;
if (!wtap_read_bytes_or_eof(fh, header, IPTRACE_1_0_PHDR_SIZE, err,
err_info)) {
return false;
}
record_length = pntoh32(&header[IPTRACE_1_0_REC_LENGTH_OFFSET]);
if (record_length < IPTRACE_1_0_PINFO_SIZE) {
* Uh-oh, the record isn't big enough to even have a
* packet information header.
*/
*err = WTAP_ERR_BAD_FILE;
*err_info = ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet information header",
record_length);
return false;
}
* Get the packet information.
*/
if (!wtap_read_bytes(fh, pkt_info, IPTRACE_1_0_PINFO_SIZE, err,
err_info)) {
return false;
}
* The if_type field of the frame header appears to be an SNMP
* ifType value giving the type of the interface. Check out the
* <net/if_types.h> header file.
*/
info.if_type = pkt_info[IPTRACE_1_0_IF_TYPE_OFFSET];
rec->rec_header.packet_header.pkt_encap = wtap_encap_ift(info.if_type);
if (rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_UNKNOWN) {
*err = WTAP_ERR_UNSUPPORTED;
*err_info = ws_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
info.if_type);
return false;
}
packet_size = record_length - IPTRACE_1_0_PINFO_SIZE;
* AIX appears to put 3 bytes of padding in front of FDDI
* frames; strip that crap off.
*/
if (rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
* The packet size is really a record size and includes
* the padding.
*/
if (packet_size < 3) {
* Uh-oh, the record isn't big enough to even have
* the padding.
*/
*err = WTAP_ERR_BAD_FILE;
*err_info = ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
record_length);
return false;
}
packet_size -= 3;
* Skip the padding.
*/
if (!wtap_read_bytes(fh, NULL, 3, err, err_info))
return false;
}
if (packet_size > WTAP_MAX_PACKET_SIZE_STANDARD) {
* Probably a corrupt capture file; don't blow up trying
* to allocate space for an immensely-large packet.
*/
*err = WTAP_ERR_BAD_FILE;
*err_info = ws_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u",
packet_size, WTAP_MAX_PACKET_SIZE_STANDARD);
return false;
}
rec->rec_type = REC_TYPE_PACKET;
rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
rec->presence_flags = WTAP_HAS_TS | WTAP_HAS_INTERFACE_ID;
rec->rec_header.packet_header.len = packet_size;
rec->rec_header.packet_header.caplen = packet_size;
rec->ts.secs = pntoh32(&header[IPTRACE_1_0_TV_SEC_OFFSET]);
rec->ts.nsecs = 0;
wtap_block_add_uint32_option(rec->block, OPT_PKT_FLAGS,
pkt_info[IPTRACE_1_0_TX_FLAGS_OFFSET] ?
(PACK_FLAGS_DIRECTION_OUTBOUND << PACK_FLAGS_DIRECTION_SHIFT) :
(PACK_FLAGS_DIRECTION_INBOUND << PACK_FLAGS_DIRECTION_SHIFT));
fill_in_pseudo_header(rec->rec_header.packet_header.pkt_encap,
&rec->rec_header.packet_header.pseudo_header,
(const char *)&pkt_info[IPTRACE_1_0_PKT_TEXT_OFFSET]);
if (!iptrace_read_rec_data(fh, buf, rec, err, err_info))
return false;
* No errors - get the interface ID.
*
* We do *not* trust the name to be null-terminated.
*/
memcpy(info.prefix, &pkt_info[IPTRACE_1_0_PREFIX_OFFSET],
sizeof info.prefix);
info.prefix[PREFIX_SIZE] = '\0';
info.unit = pkt_info[IPTRACE_1_0_UNIT_OFFSET];
* Try to find the entry with that name, description, and
* interface type.
*/
if (!g_hash_table_lookup_extended(iptrace->interface_ids,
(const void *)&info, NULL, &result)) {
wtap_block_t int_data;
wtapng_if_descr_mandatory_t *int_data_mand;
* Not found; make a new entry.
*/
add_new_if_info(iptrace, &info, &result);
* Now make a new IDB and add it.
*/
int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
int_data_mand = (wtapng_if_descr_mandatory_t *)wtap_block_get_mandatory_data(int_data);
int_data_mand->wtap_encap = rec->rec_header.packet_header.pkt_encap;
int_data_mand->tsprecision = WTAP_TSPREC_SEC;
int_data_mand->time_units_per_second = 1;
int_data_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 0);
int_data_mand->num_stat_entries = 0;
int_data_mand->interface_statistics = NULL;
wtap_block_set_string_option_value_format(int_data,
OPT_IDB_NAME, "%s%u", info.prefix, info.unit);
wtap_add_idb(wth, int_data);
}
rec->rec_header.packet_header.interface_id = GPOINTER_TO_UINT(result);
return true;
}
static bool iptrace_read_1_0(wtap *wth, wtap_rec *rec,
Buffer *buf, int *err, char **err_info, int64_t *data_offset)
{
*data_offset = file_tell(wth->fh);
if (!iptrace_read_rec_1_0(wth, wth->fh, rec, buf, err, err_info)) {
return false;
}
packet's encapsulation.
If it *is* known, and it isn't this packet's encapsulation,
set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
have a single encapsulation for all packets in the file. */
if (wth->file_encap == WTAP_ENCAP_UNKNOWN)
wth->file_encap = rec->rec_header.packet_header.pkt_encap;
else {
if (wth->file_encap != rec->rec_header.packet_header.pkt_encap)
wth->file_encap = WTAP_ENCAP_PER_PACKET;
}
return true;
}
static bool iptrace_seek_read_1_0(wtap *wth, int64_t seek_off,
wtap_rec *rec, Buffer *buf, int *err, char **err_info)
{
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
return false;
if (!iptrace_read_rec_1_0(wth, wth->random_fh, rec, buf, err,
err_info)) {
if (*err == 0)
*err = WTAP_ERR_SHORT_READ;
return false;
}
return true;
}
* iptrace 2.0 *
***********************************************************/
* iptrace 2.0, discovered through inspection
*
* Packet record contains:
*
* an initial header, with a length field and a time stamp, in
* seconds since the Epoch;
*
* data, with the specified length.
*
* The data contains:
*
* a bunch of information about the packet;
*
* padding, at least for FDDI;
*
* the raw packet data.
*/
* Offsets of fields in the initial header.
*/
#define IPTRACE_2_0_REC_LENGTH_OFFSET 0
#define IPTRACE_2_0_TV_SEC0_OFFSET 4
#define IPTRACE_2_0_PHDR_SIZE 8
* Offsets of fields in the packet information.
*/
#define IPTRACE_2_0_UNIT_OFFSET 3
#define IPTRACE_2_0_PREFIX_OFFSET 4
#define IPTRACE_2_0_PKT_TEXT_OFFSET 8
#define IPTRACE_2_0_IF_TYPE_OFFSET 20
#define IPTRACE_2_0_TX_FLAGS_OFFSET 21
#define IPTRACE_2_0_TV_SEC_OFFSET 24
#define IPTRACE_2_0_TV_NSEC_OFFSET 28
#define IPTRACE_2_0_PINFO_SIZE 32
static bool
iptrace_read_rec_2_0(wtap *wth, FILE_T fh, wtap_rec *rec, Buffer *buf,
int *err, char **err_info)
{
iptrace_t *iptrace = (iptrace_t *)wth->priv;
uint8_t header[IPTRACE_2_0_PHDR_SIZE];
uint32_t record_length;
uint8_t pkt_info[IPTRACE_2_0_PINFO_SIZE];
if_info info;
uint32_t packet_size;
void *result;
if (!wtap_read_bytes_or_eof(fh, header, IPTRACE_2_0_PHDR_SIZE, err,
err_info)) {
return false;
}
record_length = pntoh32(&header[IPTRACE_2_0_REC_LENGTH_OFFSET]);
if (record_length < IPTRACE_2_0_PINFO_SIZE) {
* Uh-oh, the record isn't big enough to even have a
* packet information header.
*/
*err = WTAP_ERR_BAD_FILE;
*err_info = ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet information header",
record_length);
return false;
}
* Get the packet information.
*/
if (!wtap_read_bytes(fh, pkt_info, IPTRACE_2_0_PINFO_SIZE, err,
err_info)) {
return false;
}
* The if_type field of the frame header appears to be an SNMP
* ifType value giving the type of the interface. Check out the
* <net/if_types.h> header file.
*/
info.if_type = pkt_info[IPTRACE_2_0_IF_TYPE_OFFSET];
rec->rec_header.packet_header.pkt_encap = wtap_encap_ift(info.if_type);
#if 0
* We used to error out if the interface type in iptrace was
* unknown/unhandled, but an iptrace may contain packets
* from a variety of interfaces, some known, and others
* unknown.
*
* It is better to display the data even for unknown interface
* types, isntead of erroring out. In the future, it would be
* nice to be able to flag which frames are shown as data
* because their interface type is unknown, and also present
* the interface type number to the user so that it can be
* reported easily back to the Wireshark developer.
*
* XXX - what types are there that are used in files but
* that we don't handle?
*/
if (rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_UNKNOWN) {
*err = WTAP_ERR_UNSUPPORTED;
*err_info = ws_strdup_printf("iptrace: interface type IFT=0x%02x unknown or unsupported",
info.if_type);
return false;
}
#endif
packet_size = record_length - IPTRACE_2_0_PINFO_SIZE;
* AIX appears to put 3 bytes of padding in front of FDDI
* frames; strip that crap off.
*/
if (rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_FDDI_BITSWAPPED) {
* The packet size is really a record size and includes
* the padding.
*/
if (packet_size < 3) {
* Uh-oh, the record isn't big enough to even have
* the padding.
*/
*err = WTAP_ERR_BAD_FILE;
*err_info = ws_strdup_printf("iptrace: file has a %u-byte record, too small to have even a packet meta-data header",
record_length);
return false;
}
packet_size -= 3;
* Skip the padding.
*/
if (!wtap_read_bytes(fh, NULL, 3, err, err_info))
return false;
}
if (packet_size > WTAP_MAX_PACKET_SIZE_STANDARD) {
* Probably a corrupt capture file; don't blow up trying
* to allocate space for an immensely-large packet.
*/
*err = WTAP_ERR_BAD_FILE;
*err_info = ws_strdup_printf("iptrace: File has %u-byte packet, bigger than maximum of %u",
packet_size, WTAP_MAX_PACKET_SIZE_STANDARD);
return false;
}
rec->rec_type = REC_TYPE_PACKET;
rec->block = wtap_block_create(WTAP_BLOCK_PACKET);
rec->presence_flags = WTAP_HAS_TS | WTAP_HAS_INTERFACE_ID;
rec->rec_header.packet_header.len = packet_size;
rec->rec_header.packet_header.caplen = packet_size;
rec->ts.secs = pntoh32(&pkt_info[IPTRACE_2_0_TV_SEC_OFFSET]);
rec->ts.nsecs = pntoh32(&pkt_info[IPTRACE_2_0_TV_NSEC_OFFSET]);
wtap_block_add_uint32_option(rec->block, OPT_PKT_FLAGS,
pkt_info[IPTRACE_2_0_TX_FLAGS_OFFSET] ?
(PACK_FLAGS_DIRECTION_OUTBOUND << PACK_FLAGS_DIRECTION_SHIFT) :
(PACK_FLAGS_DIRECTION_INBOUND << PACK_FLAGS_DIRECTION_SHIFT));
fill_in_pseudo_header(rec->rec_header.packet_header.pkt_encap,
&rec->rec_header.packet_header.pseudo_header,
(const char *)&pkt_info[IPTRACE_1_0_PKT_TEXT_OFFSET]);
if (!iptrace_read_rec_data(fh, buf, rec, err, err_info))
return false;
* No errors - get the interface ID.
*
* We do *not* trust the name to be null-terminated.
*/
memcpy(info.prefix, &pkt_info[IPTRACE_2_0_PREFIX_OFFSET],
sizeof info.prefix);
info.prefix[PREFIX_SIZE] = '\0';
info.unit = pkt_info[IPTRACE_2_0_UNIT_OFFSET];
* Try to find the entry with that name, description, and
* interface type.
*/
if (!g_hash_table_lookup_extended(iptrace->interface_ids,
(const void *)&info, NULL, &result)) {
wtap_block_t int_data;
wtapng_if_descr_mandatory_t *int_data_mand;
* Not found; make a new entry.
*/
add_new_if_info(iptrace, &info, &result);
* Now make a new IDB and add it.
*/
int_data = wtap_block_create(WTAP_BLOCK_IF_ID_AND_INFO);
int_data_mand = (wtapng_if_descr_mandatory_t *)wtap_block_get_mandatory_data(int_data);
int_data_mand->wtap_encap = rec->rec_header.packet_header.pkt_encap;
int_data_mand->tsprecision = WTAP_TSPREC_NSEC;
int_data_mand->time_units_per_second = 1000000000;
int_data_mand->snap_len = WTAP_MAX_PACKET_SIZE_STANDARD;
wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 0x09);
int_data_mand->num_stat_entries = 0;
int_data_mand->interface_statistics = NULL;
wtap_block_set_string_option_value_format(int_data,
OPT_IDB_NAME, "%s%u", info.prefix, info.unit);
wtap_add_idb(wth, int_data);
}
rec->rec_header.packet_header.interface_id = GPOINTER_TO_UINT(result);
return true;
}
static bool iptrace_read_2_0(wtap *wth, wtap_rec *rec,
Buffer *buf, int *err, char **err_info, int64_t *data_offset)
{
*data_offset = file_tell(wth->fh);
if (!iptrace_read_rec_2_0(wth, wth->fh, rec, buf, err, err_info)) {
return false;
}
packet's encapsulation.
If it *is* known, and it isn't this packet's encapsulation,
set it to WTAP_ENCAP_PER_PACKET, as this file doesn't
have a single encapsulation for all packets in the file. */
if (wth->file_encap == WTAP_ENCAP_UNKNOWN)
wth->file_encap = rec->rec_header.packet_header.pkt_encap;
else {
if (wth->file_encap != rec->rec_header.packet_header.pkt_encap)
wth->file_encap = WTAP_ENCAP_PER_PACKET;
}
return true;
}
static bool iptrace_seek_read_2_0(wtap *wth, int64_t seek_off,
wtap_rec *rec, Buffer *buf, int *err, char **err_info)
{
if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
return false;
if (!iptrace_read_rec_2_0(wth, wth->random_fh, rec, buf, err,
err_info)) {
if (*err == 0)
*err = WTAP_ERR_SHORT_READ;
return false;
}
return true;
}
static bool
iptrace_read_rec_data(FILE_T fh, Buffer *buf, wtap_rec *rec,
int *err, char **err_info)
{
if (!wtap_read_packet_bytes(fh, buf, rec->rec_header.packet_header.caplen, err, err_info))
return false;
if (rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_ATM_PDUS) {
* Attempt to guess from the packet data, the VPI,
* and the VCI information about the type of traffic.
*/
atm_guess_traffic_type(rec, ws_buffer_start_ptr(buf));
}
return true;
}
* Fill in the pseudo-header information we can.
*
* For ATM traffic, "iptrace", alas, doesn't tell us what type of traffic
* is in the packet - it was presumably run on a machine that was one of
* the endpoints of the connection, so in theory it could presumably have
* told us, but, for whatever reason, it failed to do so - perhaps the
* low-level mechanism that feeds the presumably-AAL5 frames to us doesn't
* have access to that information (e.g., because it's in the ATM driver,
* and the ATM driver merely knows that stuff on VPI/VCI X.Y should be
* handed up to some particular client, it doesn't know what that client is).
*
* We let our caller try to figure out what kind of traffic it is, either
* by guessing based on the VPI/VCI, guessing based on the header of the
* packet, seeing earlier traffic that set up the circuit and specified
* in some fashion what sort of traffic it is, or being told by the user.
*/
static void
fill_in_pseudo_header(int encap, union wtap_pseudo_header *pseudo_header,
const char *pkt_text)
{
char if_text[9];
char *decimal;
int Vpi = 0;
int Vci = 0;
switch (encap) {
case WTAP_ENCAP_ATM_PDUS:
memcpy(if_text, &pkt_text[4], 8);
if_text[8] = '\0';
decimal = strchr(if_text, '.');
if (decimal) {
*decimal = '\0';
Vpi = (int)strtoul(if_text, NULL, 10);
decimal++;
Vci = (int)strtoul(decimal, NULL, 10);
}
* OK, which value means "DTE->DCE" and which value means
* "DCE->DTE"?
*/
pseudo_header->atm.channel = pkt_text[13];
pseudo_header->atm.vpi = Vpi;
pseudo_header->atm.vci = Vci;
pseudo_header->atm.flags = 0;
pseudo_header->atm.cells = 0;
pseudo_header->atm.aal5t_u2u = 0;
pseudo_header->atm.aal5t_len = 0;
pseudo_header->atm.aal5t_chksum = 0;
break;
case WTAP_ENCAP_ETHERNET:
pseudo_header->eth.fcs_len = 0;
break;
}
}
* return the appropriate Wiretap Encapsulation Type.
*/
static int
wtap_encap_ift(unsigned int ift)
{
static const int ift_encap[] = {
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_RAW_IP,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_ETHERNET,
WTAP_ENCAP_ETHERNET,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_TOKEN_RING,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_RAW_IP,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_FDDI_BITSWAPPED,
WTAP_ENCAP_LAPB,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_RAW_IP,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_UNKNOWN,
WTAP_ENCAP_ATM_PDUS,
};
#define NUM_IFT_ENCAPS array_length(ift_encap)
if (ift < NUM_IFT_ENCAPS) {
return ift_encap[ift];
}
else {
switch(ift) {
case IPTRACE_IFT_IB:
return WTAP_ENCAP_INFINIBAND;
case IPTRACE_IFT_HF:
in the packet trace. It's unclear if the HFI
can be configured for any other protocol, and if
any field in the iptrace header indicates what
that protocol is. For now, we are hard-coding
this as RAW_IP, but if we find another iptrace file
using HFI that provides another protocol, we will
have to figure out which field in the iptrace file
encodes it. */
return WTAP_ENCAP_RAW_IP;
default:
return WTAP_ENCAP_UNKNOWN;
}
}
}
static const struct supported_option_type interface_block_options_supported[] = {
{ OPT_IDB_NAME, ONE_OPTION_SUPPORTED }
};
static const struct supported_block_type iptrace_1_0_blocks_supported[] = {
* iptrace supports multiple interfaces, with descriptions, and
* supports associating packets with interfaces. Interface
* description blocks are used for that.
*/
{ WTAP_BLOCK_IF_ID_AND_INFO, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_block_options_supported) },
* iptrace is a capture format, so it obviously supports packets.
* It supports no packet options, however.
*/
{ WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED }
};
static const struct file_type_subtype_info iptrace_1_0_info = {
"AIX iptrace 1.0", "iptrace_1", NULL, NULL,
false, BLOCKS_SUPPORTED(iptrace_1_0_blocks_supported),
NULL, NULL, NULL
};
static const struct supported_block_type iptrace_2_0_blocks_supported[] = {
* iptrace supports multiple interfaces, with descriptions, and
* supports associating packets with interfaces. Interface
* description blocks are used for that.
*/
{ WTAP_BLOCK_IF_ID_AND_INFO, MULTIPLE_BLOCKS_SUPPORTED, OPTION_TYPES_SUPPORTED(interface_block_options_supported) },
* iptrace is a capture format, so it obviously supports packets.
* It supports no packet options, however.
*/
{ WTAP_BLOCK_PACKET, MULTIPLE_BLOCKS_SUPPORTED, NO_OPTIONS_SUPPORTED }
};
static const struct file_type_subtype_info iptrace_2_0_info = {
"AIX iptrace 2.0", "iptrace_2", NULL, NULL,
false, BLOCKS_SUPPORTED(iptrace_2_0_blocks_supported),
NULL, NULL, NULL
};
void register_iptrace(void)
{
iptrace_1_0_file_type_subtype = wtap_register_file_type_subtype(&iptrace_1_0_info);
iptrace_2_0_file_type_subtype = wtap_register_file_type_subtype(&iptrace_2_0_info);
* Register names for backwards compatibility with the
* wtap_filetypes table in Lua.
*/
wtap_register_backwards_compatibility_lua_name("IPTRACE_1_0",
iptrace_1_0_file_type_subtype);
wtap_register_backwards_compatibility_lua_name("IPTRACE_2_0",
iptrace_2_0_file_type_subtype);
}
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: t
* End:
*
* vi: set shiftwidth=8 tabstop=8 noexpandtab:
* :indentSize=8:tabSize=8:noTabs=false:
*/