diff options
Diffstat (limited to 'wiretap/iptrace.c')
-rw-r--r-- | wiretap/iptrace.c | 198 |
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; + } +} |