diff options
-rw-r--r-- | packet-atm.c | 125 | ||||
-rw-r--r-- | wiretap/iptrace.c | 84 | ||||
-rw-r--r-- | wiretap/snoop.c | 93 |
3 files changed, 245 insertions, 57 deletions
diff --git a/packet-atm.c b/packet-atm.c index 34a67067db..412c402cc0 100644 --- a/packet-atm.c +++ b/packet-atm.c @@ -1,7 +1,7 @@ /* packet-atm.c * Routines for ATM packet disassembly * - * $Id: packet-atm.c,v 1.7 1999/11/19 07:28:15 guy Exp $ + * $Id: packet-atm.c,v 1.8 1999/11/27 01:55:29 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -414,6 +414,74 @@ static const value_string ipsilon_type_vals[] = { { 0, NULL } }; +/* + * We don't know what kind of traffic this is; try to guess. + * We at least know it's AAL5.... + */ +static void +atm_guess_content(const u_char *pd, frame_data *fd) +{ + if (fd->pseudo_header.ngsniffer_atm.Vpi == 0) { + /* + * Traffic on some PVCs with a VPI of 0 and certain + * VCIs is of particular types. + */ + switch (fd->pseudo_header.ngsniffer_atm.Vci) { + + case 5: + /* + * Signalling AAL. + */ + fd->pseudo_header.ngsniffer_atm.AppTrafType = + ATT_AAL_SIGNALLING; + return; + + case 16: + /* + * ILMI. + */ + fd->pseudo_header.ngsniffer_atm.AppTrafType |= + ATT_HL_ILMI; + return; + } + } + + /* + * OK, we can't tell what it is based on the VPI/VCI; try + * guessing based on the contents. + */ + if (pd[0] == 0xaa && pd[1] == 0xaa && pd[2] == 0x03) { + /* + * Looks like a SNAP header; assume it's LLC multiplexed + * RFC 1483 traffic. + */ + fd->pseudo_header.ngsniffer_atm.AppTrafType |= ATT_HL_LLCMX; + } else { + /* + * Assume it's LANE. + */ + fd->pseudo_header.ngsniffer_atm.AppTrafType |= ATT_HL_LANE; + if (pd[0] == 0xff && pd[1] == 0x00) { + /* + * Looks like LE Control traffic. + */ + fd->pseudo_header.ngsniffer_atm.AppHLType = + AHLT_LANE_LE_CTRL; + } else { + /* + * XXX - Ethernet, or Token Ring? + * Assume Ethernet for now; if we see earlier + * LANE traffic, we may be able to figure out + * the traffic type from that, but there may + * still be situations where the user has to + * tell us. + */ + fd->pseudo_header.ngsniffer_atm.AppHLType = + AHLT_LANE_802_3; + } + } +} + void dissect_atm(const u_char *pd, frame_data *fd, proto_tree *tree) { @@ -425,6 +493,38 @@ dissect_atm(const u_char *pd, frame_data *fd, proto_tree *tree) aal_type = fd->pseudo_header.ngsniffer_atm.AppTrafType & ATT_AALTYPE; hl_type = fd->pseudo_header.ngsniffer_atm.AppTrafType & ATT_HLTYPE; + if (aal_type == ATT_AAL5) { + if (hl_type == ATT_HL_UNKNOWN || + fd->pseudo_header.ngsniffer_atm.AppHLType == AHLT_UNKNOWN) { + /* + * The joys of a connection-oriented link layer; the type of + * traffic may be implied by the connection on which it's + * traveling, rather than being specified in the packet itself. + * + * For this packet, the program that captured the packet didn't + * save the type of traffic, presumably because it didn't know + * the traffic type (either it didn't see the connection setup + * and wasn't running on one of the endpoints, and wasn't later + * told, e.g. by the human running it, what type of traffic was + * on that circuit, or was running on one of the endpoints but + * was using, to capture the packets, a mechanism that either + * doesn't have access to data saying what's going over the + * connection or doesn't bother providing that information). + * + * For now, we try to guess the traffic type based on the VPI/VCI + * or the packet header; later, we should provide a mechanism + * by which the user can specify what sort of traffic is on a + * particular circuit. + */ + atm_guess_content(pd, fd); + + /* + * OK, now get the AAL type and high-layer type again. + */ + aal_type = fd->pseudo_header.ngsniffer_atm.AppTrafType & ATT_AALTYPE; + hl_type = fd->pseudo_header.ngsniffer_atm.AppTrafType & ATT_HLTYPE; + } + } if (check_col(fd, COL_PROTOCOL)) col_add_str(fd, COL_PROTOCOL, "ATM"); @@ -516,15 +616,28 @@ dissect_atm(const u_char *pd, frame_data *fd, proto_tree *tree) fd->pseudo_header.ngsniffer_atm.channel); break; } - proto_tree_add_text(atm_tree, 0, 0, "Cells: %u", + if (fd->pseudo_header.ngsniffer_atm.cells != 0) { + /* + * If the cell count is 0, assume it means we don't know how + * many cells it was. + * + * XXX - also, if this is AAL5 traffic, assume it means we don't + * know what was in the AAL5 trailer. We may, however, find + * some capture program that can give us the AAL5 trailer + * information but not the cell count, in which case we need + * some other way of indicating whether we have the AAL5 trailer + * information. + */ + proto_tree_add_text(atm_tree, 0, 0, "Cells: %u", fd->pseudo_header.ngsniffer_atm.cells); - if (aal_type == ATT_AAL5) { - proto_tree_add_text(atm_tree, 0, 0, "AAL5 U2U: %u", + if (aal_type == ATT_AAL5) { + proto_tree_add_text(atm_tree, 0, 0, "AAL5 U2U: %u", fd->pseudo_header.ngsniffer_atm.aal5t_u2u); - proto_tree_add_text(atm_tree, 0, 0, "AAL5 len: %u", + proto_tree_add_text(atm_tree, 0, 0, "AAL5 len: %u", fd->pseudo_header.ngsniffer_atm.aal5t_len); - proto_tree_add_text(atm_tree, 0, 0, "AAL5 checksum: 0x%08X", + proto_tree_add_text(atm_tree, 0, 0, "AAL5 checksum: 0x%08X", fd->pseudo_header.ngsniffer_atm.aal5t_chksum); + } } } diff --git a/wiretap/iptrace.c b/wiretap/iptrace.c index 1ea4e21990..2d77099d47 100644 --- a/wiretap/iptrace.c +++ b/wiretap/iptrace.c @@ -1,6 +1,6 @@ /* iptrace.c * - * $Id: iptrace.c,v 1.21 1999/11/26 17:57:13 gram Exp $ + * $Id: iptrace.c,v 1.22 1999/11/27 01:55:44 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu> @@ -35,8 +35,7 @@ static int iptrace_read_1_0(wtap *wth, int *err); static int iptrace_read_2_0(wtap *wth, int *err); static int wtap_encap_ift(unsigned int ift); -static void atm_guess_content(wtap *wth, guint8 *header, guint8 *pd); - +static void get_atm_pseudo_header(wtap *wth, guint8 *header, guint8 *pd); int iptrace_open(wtap *wth, int *err) { @@ -78,13 +77,13 @@ int iptrace_open(wtap *wth, int *err) /* iptrace 1.0, discovered through inspection */ typedef struct { /* 0-3 */ guint32 pkt_length; /* packet length + 0x16 */ -/* 4-7 */ guint8 tv_sec; /* time */ +/* 4-7 */ guint32 tv_sec; /* time stamp, seconds since the Epoch */ /* 8-11 */ guint32 junk1; /* ???, not time */ /* 12-15 */ char if_name[4]; /* null-terminated */ /* 16-27 */ char junk2[12]; /* ??? */ /* 28 */ guint8 if_type; /* BSD net/if_types.h */ /* 29 */ guint8 tx_flag; /* 0=receive, 1=transmit */ -} iptrace_1_0_phdr;; +} iptrace_1_0_phdr; /* Read the next packet */ static int iptrace_read_1_0(wtap *wth, int *err) @@ -152,13 +151,8 @@ static int iptrace_read_1_0(wtap *wth, int *err) 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); + get_atm_pseudo_header(wth, header, data_ptr); } /* If the per-file encapsulation isn't known, set it to this @@ -184,15 +178,15 @@ static int iptrace_read_1_0(wtap *wth, int *err) /* iptrace 2.0, discovered through inspection */ typedef struct { /* 0-3 */ guint32 pkt_length; /* packet length + 32 */ -/* 4-7 */ guint32 tv_sec0; +/* 4-7 */ guint32 tv_sec0; /* time stamp, seconds since the Epoch */ /* 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; +/* 32-35 */ guint32 tv_sec; /* time stamp, seconds since the Epoch */ +/* 36-39 */ guint32 tv_nsec; /* nanoseconds since that second */ } iptrace_2_0_phdr; /* Read the next packet */ @@ -261,13 +255,8 @@ static int iptrace_read_2_0(wtap *wth, int *err) 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); + get_atm_pseudo_header(wth, header, data_ptr); } /* If the per-file encapsulation isn't known, set it to this @@ -286,20 +275,33 @@ static int iptrace_read_2_0(wtap *wth, int *err) return data_offset; } -/* See comment above about writing good packet sniffers */ +/* + * Fill in the pseudo-header information we can; alas, "iptrace" 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 -atm_guess_content(wtap *wth, guint8 *header, guint8 *pd) +get_atm_pseudo_header(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); + if_text[8] = '\0'; decimal = strchr(if_text, '.'); if (decimal) { *decimal = '\0'; @@ -310,35 +312,23 @@ atm_guess_content(wtap *wth, guint8 *header, guint8 *pd) wth->phdr.pseudo_header.ngsniffer_atm.Vpi = Vpi; wth->phdr.pseudo_header.ngsniffer_atm.Vci = Vci; + /* + * OK, which value means "DTE->DCE" and which value means + * "DCE->DTE"? + */ + wth->phdr.pseudo_header.ngsniffer_atm.channel = header[29]; /* 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.AppTrafType |= ATT_HL_LLCMX; - } - else if ( Vpi == 0 && Vci == 16 ) { - wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType |= ATT_HL_ILMI; - } - else if ( Vpi == 0 && Vci == 5 ) { - /* Signalling AAL */ - wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType = ATT_AAL_SIGNALLING; - } - else { - wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType |= ATT_HL_LANE; - if (pd[0] == 0xff && pd[1] == 0x00) - wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = AHLT_LANE_LE_CTRL; - else { - /* - * XXX - Ethernet, or Token Ring? - */ - wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = AHLT_LANE_802_3; - } - } + /* Assume it's AAL5 traffic, but indicate that we don't know what + it is beyond that. */ + wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType = + ATT_AAL5|ATT_HL_UNKNOWN; + wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = AHLT_UNKNOWN; } /* Given an RFC1573 (SNMP ifType) interface type, diff --git a/wiretap/snoop.c b/wiretap/snoop.c index 5fe90e421f..c56444cdc1 100644 --- a/wiretap/snoop.c +++ b/wiretap/snoop.c @@ -1,6 +1,6 @@ /* snoop.c * - * $Id: snoop.c,v 1.15 1999/11/26 11:18:12 guy Exp $ + * $Id: snoop.c,v 1.16 1999/11/27 01:55:43 guy Exp $ * * Wiretap Library * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.edu> @@ -84,6 +84,21 @@ static int snoop_read(wtap *wth, int *err); * can handle any of them; even if it can't, this may be useful reference * information for anybody doing code to use DLPI to do raw packet * captures. + * + * http://mrpink.lerc.nasa.gov/118x/support/convert.c + * + * which is a program to convert files from the format written by + * the "atmsnoop" program that comes with the SunATM package to + * regular "snoop" format, claims that "SunATM 2.1 claimed to be DL_FDDI + * (don't ask why). SunATM 3.0 claims to be DL_IPATM, which is 0x12". + * + * It also says that "ATM Mac header is 12 bytes long.", and seems to imply + * that in an "atmsnoop" file, the header contains 2 bytes (direction and + * VPI?), 2 bytes of VCI, 6 bytes of something, and 2 bytes of Ethernet + * type; if those 6 bytes are 2 bytes of DSAP, 2 bytes of LSAP, 1 byte + * of LLC control, and 3 bytes of SNAP OUI, that'd mean that an ATM + * pseudo-header in an "atmsnoop" file is probably 1 byte of direction, + * 1 byte of VPI, and 2 bytes of VCI. */ int snoop_open(wtap *wth, int *err) { @@ -109,7 +124,7 @@ int snoop_open(wtap *wth, int *err) WTAP_ENCAP_UNKNOWN, /* not defined in "dlpi.h" */ WTAP_ENCAP_UNKNOWN, /* Fibre Channel */ WTAP_ENCAP_UNKNOWN, /* ATM */ - WTAP_ENCAP_UNKNOWN, /* ATM Classical IP */ + WTAP_ENCAP_ATM_SNIFFER, /* ATM Classical IP */ WTAP_ENCAP_UNKNOWN, /* X.25 LAPB */ WTAP_ENCAP_UNKNOWN, /* ISDN */ WTAP_ENCAP_UNKNOWN, /* HIPPI */ @@ -175,9 +190,12 @@ int snoop_open(wtap *wth, int *err) /* Read the next packet */ static int snoop_read(wtap *wth, int *err) { + guint32 rec_size; guint32 packet_size; + guint32 orig_size; int bytes_read; struct snooprec_hdr hdr; + char atm_phdr[4]; int data_offset; char padbuf[4]; int padbytes; @@ -198,6 +216,8 @@ static int snoop_read(wtap *wth, int *err) } wth->data_offset += sizeof hdr; + rec_size = ntohl(hdr.rec_len); + orig_size = ntohl(hdr.orig_len); packet_size = ntohl(hdr.incl_len); if (packet_size > WTAP_MAX_PACKET_SIZE) { /* @@ -209,6 +229,71 @@ static int snoop_read(wtap *wth, int *err) *err = WTAP_ERR_BAD_RECORD; return -1; } + + /* + * If this is an ATM packet, the first four bytes are the + * direction of the packet (transmit/receive), the VPI, and + * the VCI; read them and generate the pseudo-header from + * them. + */ + if (wth->file_encap == WTAP_ENCAP_ATM_SNIFFER) { + if (packet_size < 4) { + /* + * Uh-oh, the packet isn't big enough to even + * have a pseudo-header. + */ + g_message("snoop: atmsnoop file has a %u-byte packet, too small to have even an ATM pseudo-header\n", + packet_size); + *err = WTAP_ERR_BAD_RECORD; + return -1; + } + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(atm_phdr, 1, 4, wth->fh); + if (bytes_read != 4) { + *err = file_error(wth->fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + + /* + * OK, which value means "DTE->DCE" and which value means + * "DCE->DTE"? + */ + wth->phdr.pseudo_header.ngsniffer_atm.channel = + (atm_phdr[0] & 0x80) ? 1 : 0; + wth->phdr.pseudo_header.ngsniffer_atm.Vpi = atm_phdr[1]; + wth->phdr.pseudo_header.ngsniffer_atm.Vci = pntohs(&atm_phdr[2]); + + /* We don't have this information */ + 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; + + /* + * Assume it's AAL5; we know nothing more about it. + * + * For what it's worth, in one "atmsnoop" capture, + * the lower 7 bits of the first byte of the header + * were 0x05 for ILMI traffic, 0x06 for Signalling + * AAL traffic, and 0x02 for at least some RFC 1483-style + * LLC multiplexed traffic. + */ + wth->phdr.pseudo_header.ngsniffer_atm.AppTrafType = + ATT_AAL5|ATT_HL_UNKNOWN; + wth->phdr.pseudo_header.ngsniffer_atm.AppHLType = + AHLT_UNKNOWN; + + /* + * Don't count the pseudo-header as part of the packet. + */ + rec_size -= 4; + orig_size -= 4; + packet_size -= 4; + wth->data_offset += 4; + } + buffer_assure_space(wth->frame_buffer, packet_size); data_offset = wth->data_offset; errno = WTAP_ERR_CANT_READ; @@ -226,7 +311,7 @@ static int snoop_read(wtap *wth, int *err) wth->phdr.ts.tv_sec = ntohl(hdr.ts_sec); wth->phdr.ts.tv_usec = ntohl(hdr.ts_usec); wth->phdr.caplen = packet_size; - wth->phdr.len = ntohl(hdr.orig_len); + wth->phdr.len = orig_size; wth->phdr.pkt_encap = wth->file_encap; /* @@ -236,7 +321,7 @@ static int snoop_read(wtap *wth, int *err) * There's probably not much padding (it's probably padded only * to a 4-byte boundary), so we probably need only do one read. */ - padbytes = ntohl(hdr.rec_len) - (sizeof hdr + packet_size); + padbytes = rec_size - (sizeof hdr + packet_size); while (padbytes != 0) { bytes_to_read = padbytes; if (bytes_to_read > sizeof padbuf) |