aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/iptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'wiretap/iptrace.c')
-rw-r--r--wiretap/iptrace.c198
1 files changed, 159 insertions, 39 deletions
diff --git a/wiretap/iptrace.c b/wiretap/iptrace.c
index 7d004458d9..90fa479b03 100644
--- a/wiretap/iptrace.c
+++ b/wiretap/iptrace.c
@@ -1,6 +1,6 @@
/* iptrace.c
*
- * $Id: iptrace.c,v 1.16 1999/11/17 07:50:33 guy Exp $
+ * $Id: iptrace.c,v 1.17 1999/11/18 08:50:34 gram Exp $
*
* Wiretap Library
* Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu>
@@ -33,6 +33,22 @@
#include "iptrace.h"
static int iptrace_read(wtap *wth, int *err);
+static int wtap_encap_ift(unsigned int ift);
+static void atm_guess_content(wtap *wth, guint8 *header, guint8 *pd);
+
+/* This structure was guessed */
+typedef struct {
+/* 0-3 */ guint32 pkt_length; /* packet length + 32 */
+/* 4-7 */ guint32 tv_sec0;
+/* 8-11 */ guint32 junk1; /* ?? */
+/* 12-15 */ char if_name[4]; /* null-terminated */
+/* 16-27 */ char if_desc[12]; /* interface description. */
+/* 28 */ guint8 if_type; /* BSD net/if_types.h */
+/* 29 */ guint8 tx_flag; /* 0=receive, 1=transmit */
+/* 30-31 */ guint16 junk3;
+/* 32-35 */ guint32 tv_sec;
+/* 36-39 */ guint32 tv_usec;
+} iptrace_phdr;
int iptrace_open(wtap *wth, int *err)
{
@@ -63,11 +79,13 @@ int iptrace_open(wtap *wth, int *err)
/* Read the next packet */
static int iptrace_read(wtap *wth, int *err)
{
- int bytes_read;
- int data_offset;
- guint16 packet_size;
- guint8 header[40];
- char if_name1, if_name2;
+ int bytes_read;
+ int data_offset;
+ guint32 packet_size;
+ guint8 header[40];
+ guint8 *data_ptr;
+ iptrace_phdr pkt_hdr;
+ char if_name1, if_name2;
/* Read the descriptor data */
errno = WTAP_ERR_CANT_READ;
@@ -84,18 +102,13 @@ static int iptrace_read(wtap *wth, int *err)
}
wth->data_offset += 40;
- /*
- * Is this a 2-byte value, with two bytes of other information
- * before it, or is it a 4-byte value?
- */
- packet_size = pntohs(&header[2]) - 32;
-
/* Read the packet data */
- buffer_assure_space(wth->frame_buffer, packet_size);
+ packet_size = pntohl(&header[0]) - 32;
+ buffer_assure_space( wth->frame_buffer, packet_size );
data_offset = wth->data_offset;
errno = WTAP_ERR_CANT_READ;
- bytes_read = file_read(buffer_start_ptr(wth->frame_buffer), 1,
- packet_size, wth->fh);
+ data_ptr = buffer_start_ptr( wth->frame_buffer );
+ bytes_read = file_read( data_ptr, 1, packet_size, wth->fh );
if (bytes_read != packet_size) {
*err = file_error(wth->fh);
@@ -105,12 +118,14 @@ static int iptrace_read(wtap *wth, int *err)
}
wth->data_offset += packet_size;
- wth->phdr.len = packet_size;
- wth->phdr.caplen = packet_size;
- wth->phdr.ts.tv_sec = pntohl(&header[32]);
+
/* AIX saves time in nsec, not usec. It's easier to make iptrace
* files more Unix-compliant here than try to get the calling
* program to know when to use nsec or usec */
+
+ wth->phdr.len = packet_size;
+ wth->phdr.caplen = packet_size;
+ wth->phdr.ts.tv_sec = pntohl(&header[32]);
wth->phdr.ts.tv_usec = pntohl(&header[36]) / 1000;
/*
@@ -118,28 +133,32 @@ static int iptrace_read(wtap *wth, int *err)
* value giving the type of the interface. Check out the
* <net/if_types.h> header file.
*/
- if_name1 = header[12];
- if_name2 = header[13];
- if (if_name1 == 't' && if_name2 == 'r') {
- wth->phdr.pkt_encap = WTAP_ENCAP_TR;
- }
- else if (if_name1 == 'e' && if_name2 == 'n') {
- wth->phdr.pkt_encap = WTAP_ENCAP_ETHERNET;
- }
- else if (if_name1 == 'f' && if_name2 == 'd') {
- wth->phdr.pkt_encap = WTAP_ENCAP_FDDI_BITSWAPPED;
- }
- else if (if_name1 == 'l' && if_name2 == 'o') { /* loopback */
- wth->phdr.pkt_encap = WTAP_ENCAP_RAW_IP;
- }
- else if (if_name1 == 'x' && if_name2 == 'd') { /* X.25 */
- wth->phdr.pkt_encap = WTAP_ENCAP_RAW_IP;
+ pkt_hdr.if_type = header[28];
+ wth->phdr.pkt_encap = wtap_encap_ift(pkt_hdr.if_type);
+
+ /* What does a loopback trace store for its if_type? I don't know yet */
+ if (wth->phdr.pkt_encap == WTAP_ENCAP_UNKNOWN) {
+ if_name1 = header[12];
+ if_name2 = header[13];
+
+ if (if_name1 == 'l' && if_name2 == 'o') {
+ wth->phdr.pkt_encap = WTAP_ENCAP_RAW_IP;
+ }
+ else {
+ g_message("iptrace: interface type %c%c (IFT=0x%02x) unknown or unsupported",
+ if_name1, if_name2, pkt_hdr.if_type);
+ *err = WTAP_ERR_BAD_RECORD;
+ return -1;
+ }
}
- else {
- g_message("iptrace: interface type %c%c unknown or unsupported",
- if_name1, if_name2);
- *err = WTAP_ERR_BAD_RECORD;
- return -1;
+
+ /* IBM couldn't make it easy on me, could they? For anyone out there
+ * who is thinking about writing a packet capture program, be sure
+ * to store all pertinent information about a packet in the trace file.
+ * Let us know what the next layer is!
+ */
+ if ( wth->phdr.pkt_encap == WTAP_ENCAP_ATM_SNIFFER ) {
+ atm_guess_content(wth, header, data_ptr);
}
/* If the per-file encapsulation isn't known, set it to this
@@ -154,5 +173,106 @@ static int iptrace_read(wtap *wth, int *err)
if (wth->file_encap != wth->phdr.pkt_encap)
wth->file_encap = WTAP_ENCAP_PER_PACKET;
}
+
return data_offset;
}
+
+/* See comment above about writing good packet sniffers */
+static void
+atm_guess_content(wtap *wth, guint8 *header, guint8 *pd)
+{
+ char if_text[9];
+ char *decimal;
+ int Vpi = 0;
+ int Vci = 0;
+
+ wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType = ATT_AAL5;
+
+ /* Rip apart the "x.y" text into Vpi/Vci numbers */
+ header[8] = '\0';
+ memcpy(if_text, &header[20], 8);
+ decimal = strchr(if_text, '.');
+ if (decimal) {
+ *decimal = '\0';
+ Vpi = strtoul(if_text, NULL, 10);
+ decimal++;
+ Vci = strtoul(decimal, NULL, 10);
+ }
+ wth->phdr.pseudo_header.ngsniffer_atm.Vpi = Vpi;
+ wth->phdr.pseudo_header.ngsniffer_atm.Vci = Vci;
+
+
+ /* We don't have this information */
+ wth->phdr.pseudo_header.ngsniffer_atm.channel = 0;
+ wth->phdr.pseudo_header.ngsniffer_atm.cells = 0;
+ wth->phdr.pseudo_header.ngsniffer_atm.aal5t_u2u = 0;
+ wth->phdr.pseudo_header.ngsniffer_atm.aal5t_len = 0;
+ wth->phdr.pseudo_header.ngsniffer_atm.aal5t_chksum = 0;
+
+ if (pd[0] == 0xaa && pd[1] == 0xaa && pd[2] == 0x03) {
+ wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = ATT_HL_LLCMX;
+ }
+ else if ( Vpi == 0 && Vci == 16 ) {
+ wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = ATT_HL_ILMI;
+ }
+ else {
+ wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = ATT_HL_LANE;
+ }
+}
+
+/* Given an RFC1573 (SNMP ifType) interface type,
+ * return the appropriate Wiretap Encapsulation Type.
+ */
+static int
+wtap_encap_ift(unsigned int ift)
+{
+
+ static const int ift_encap[] = {
+/* 0x0 */ WTAP_ENCAP_UNKNOWN,
+/* 0x1 */ WTAP_ENCAP_UNKNOWN,
+/* 0x2 */ WTAP_ENCAP_UNKNOWN,
+/* 0x3 */ WTAP_ENCAP_UNKNOWN,
+/* 0x4 */ WTAP_ENCAP_UNKNOWN,
+/* 0x5 */ WTAP_ENCAP_RAW_IP, /* X.25 */
+/* 0x6 */ WTAP_ENCAP_ETHERNET,
+/* 0x7 */ WTAP_ENCAP_UNKNOWN,
+/* 0x8 */ WTAP_ENCAP_UNKNOWN,
+/* 0x9 */ WTAP_ENCAP_TR,
+/* 0xa */ WTAP_ENCAP_UNKNOWN,
+/* 0xb */ WTAP_ENCAP_UNKNOWN,
+/* 0xc */ WTAP_ENCAP_UNKNOWN,
+/* 0xd */ WTAP_ENCAP_UNKNOWN,
+/* 0xe */ WTAP_ENCAP_UNKNOWN,
+/* 0xf */ WTAP_ENCAP_FDDI_BITSWAPPED,
+/* 0x10 */ WTAP_ENCAP_LAPB,
+/* 0x11 */ WTAP_ENCAP_UNKNOWN,
+/* 0x12 */ WTAP_ENCAP_UNKNOWN,
+/* 0x13 */ WTAP_ENCAP_UNKNOWN,
+/* 0x14 */ WTAP_ENCAP_UNKNOWN,
+/* 0x15 */ WTAP_ENCAP_UNKNOWN,
+/* 0x16 */ WTAP_ENCAP_UNKNOWN,
+/* 0x17 */ WTAP_ENCAP_UNKNOWN,
+/* 0x18 */ WTAP_ENCAP_UNKNOWN,
+/* 0x19 */ WTAP_ENCAP_UNKNOWN,
+/* 0x1a */ WTAP_ENCAP_UNKNOWN,
+/* 0x1b */ WTAP_ENCAP_UNKNOWN,
+/* 0x1c */ WTAP_ENCAP_UNKNOWN,
+/* 0x1d */ WTAP_ENCAP_UNKNOWN,
+/* 0x1e */ WTAP_ENCAP_UNKNOWN,
+/* 0x1f */ WTAP_ENCAP_UNKNOWN,
+/* 0x20 */ WTAP_ENCAP_UNKNOWN,
+/* 0x21 */ WTAP_ENCAP_UNKNOWN,
+/* 0x22 */ WTAP_ENCAP_UNKNOWN,
+/* 0x23 */ WTAP_ENCAP_UNKNOWN,
+/* 0x24 */ WTAP_ENCAP_UNKNOWN,
+/* 0x25 */ WTAP_ENCAP_ATM_SNIFFER,
+ };
+ #define NUM_IFT_ENCAPS (sizeof ift_encap / sizeof ift_encap[0])
+
+ if (ift < NUM_IFT_ENCAPS) {
+ return ift_encap[ift];
+ }
+ else {
+ return WTAP_ENCAP_UNKNOWN;
+ }
+}