diff options
author | Guy Harris <guy@alum.mit.edu> | 2000-01-24 18:46:45 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2000-01-24 18:46:45 +0000 |
commit | c38ed66e9cb374a4784e96977fb1e4c660ec029f (patch) | |
tree | 22f799aae007bc52da41671f594cbe97c00ef0d2 | |
parent | 2727167b2da0c361f9fdc4347a6e3037a551aa1a (diff) | |
download | wireshark-c38ed66e9cb374a4784e96977fb1e4c660ec029f.tar.gz wireshark-c38ed66e9cb374a4784e96977fb1e4c660ec029f.tar.bz2 wireshark-c38ed66e9cb374a4784e96977fb1e4c660ec029f.zip |
Add support for Cisco ISL.
svn path=/trunk/; revision=1537
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | packet-eth.c | 22 | ||||
-rw-r--r-- | packet-isl.c | 287 | ||||
-rw-r--r-- | packet.h | 4 |
4 files changed, 313 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am index 7369548eac..7ddb59b36c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.157 2000/01/18 20:35:40 guy Exp $ +# $Id: Makefile.am,v 1.158 2000/01/24 18:46:44 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs <gerald@zing.org> @@ -84,6 +84,7 @@ DISSECTOR_SOURCES = \ packet-isis-lsp.c \ packet-isis-snp.h \ packet-isis-snp.c \ + packet-isl.c \ packet-l2tp.c \ packet-lapb.c \ packet-lapd.c \ diff --git a/packet-eth.c b/packet-eth.c index a4a6f64f5f..3784d2c5ec 100644 --- a/packet-eth.c +++ b/packet-eth.c @@ -1,7 +1,7 @@ /* packet-eth.c * Routines for ethernet packet disassembly * - * $Id: packet-eth.c,v 1.27 2000/01/24 01:15:37 guy Exp $ + * $Id: packet-eth.c,v 1.28 2000/01/24 18:46:44 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -94,6 +94,16 @@ capture_eth(const u_char *pd, int offset, packet_counts *ld) ethhdr_type = ETHERNET_802_2; } + /* Oh, yuck. Cisco ISL frames require special interpretation of the + destination address field; fortunately, they can be recognized by + checking the first 5 octets of the destination address, which are + 01-00-0C-00-00 for ISL frames. */ + if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C + && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) { + capture_isl(pd, offset, ld); + return; + } + /* Convert the LLC length from the 802.3 header to a total frame length, by adding in the size of any data that preceded the Ethernet header, and adding in the Ethernet header size, @@ -162,6 +172,16 @@ dissect_eth(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) ethhdr_type = ETHERNET_802_2; } + /* Oh, yuck. Cisco ISL frames require special interpretation of the + destination address field; fortunately, they can be recognized by + checking the first 5 octets of the destination address, which are + 01-00-0C-00-00 for ISL frames. */ + if (pd[offset] == 0x01 && pd[offset+1] == 0x00 && pd[offset+2] == 0x0C + && pd[offset+3] == 0x00 && pd[offset+4] == 0x00) { + dissect_isl(pd, offset, fd, tree); + return; + } + if (check_col(fd, COL_INFO)) { col_add_fstr(fd, COL_INFO, "IEEE 802.3 %s", (ethhdr_type == ETHERNET_802_3 ? "Raw " : "")); diff --git a/packet-isl.c b/packet-isl.c new file mode 100644 index 0000000000..0aa813c247 --- /dev/null +++ b/packet-isl.c @@ -0,0 +1,287 @@ +/* packet-isl.c + * Routines for Cisco ISL Ethernet header disassembly + * + * $Id: packet-isl.c,v 1.1 2000/01/24 18:46:45 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@zing.org> + * Copyright 1998 Gerald Combs + * + * + * 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 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#endif + +#include <glib.h> +#include "packet.h" +#include "etypes.h" + +/* + * See + * + * http://www.cisco.com/warp/public/741/4.html + * + * and + * + * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm + * + * for information on ISL. + */ +static int proto_isl = -1; +static int hf_isl_dst = -1; +static int hf_isl_type = -1; +static int hf_isl_user_eth = -1; +static int hf_isl_user = -1; +static int hf_isl_src = -1; +static int hf_isl_len = -1; +static int hf_isl_hsa = -1; +static int hf_isl_vlan_id = -1; +static int hf_isl_bpdu = -1; +static int hf_isl_index = -1; +static int hf_isl_src_vlan_id = -1; +static int hf_isl_explorer = -1; +static int hf_isl_dst_route_descriptor = -1; +static int hf_isl_src_route_descriptor = -1; +static int hf_isl_fcs_not_incl = -1; +static int hf_isl_esize = -1; + +static gint ett_isl = -1; + +#define ISL_HEADER_SIZE 26 + +#define TYPE_ETHER 0x0 +#define TYPE_TR 0x1 +#define TYPE_FDDI 0x2 +#define TYPE_ATM 0x3 + +void +capture_isl(const u_char *pd, int offset, packet_counts *ld) +{ + guint8 type; + + if (!BYTES_ARE_IN_FRAME(offset, ISL_HEADER_SIZE)) { + ld->other++; + return; + } + + type = (pd[offset+5] >> 4)&0x0F; + + switch (type) { + + case TYPE_ETHER: + offset += 14+12; /* skip the header */ + capture_eth(pd, offset, ld); + break; + + case TYPE_TR: + offset += 14+17; /* skip the header */ + capture_tr(pd, offset, ld); + break; + + default: + ld->other++; + break; + } +} + +static const value_string type_vals[] = { + {TYPE_ETHER, "Ethernet"}, + {TYPE_TR, "Token-Ring"}, + {TYPE_FDDI, "FDDI"}, + {TYPE_ATM, "ATM"}, + {0, NULL} +}; + +static const value_string ether_user_vals[] = { + {0x0, "Normal priority"}, + {0x1, "Priority 1"}, + {0x2, "Priority 2"}, + {0x3, "Highest priority"}, + {0, NULL} +}; + +static const true_false_string bpdu_tfs = { + "Yes", + "No" +}; + +static const true_false_string explorer_tfs = { + "Explorer frame", + "Data frame" +}; + +void +dissect_isl(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) +{ + proto_tree *fh_tree = NULL; + proto_item *ti; + guint8 type; + guint16 length; + + if (!BYTES_ARE_IN_FRAME(offset, ISL_HEADER_SIZE)) { + dissect_data(pd, offset, fd, tree); + return; + } + + if (check_col(fd, COL_PROTOCOL)) + col_add_str(fd, COL_PROTOCOL, "ISL"); + + if (tree) { + ti = proto_tree_add_item_format(tree, proto_isl, offset, ISL_HEADER_SIZE, + NULL, "ISL"); + fh_tree = proto_item_add_subtree(ti, ett_isl); + proto_tree_add_item(fh_tree, hf_isl_dst, offset+0, 6, &pd[offset+0]); + type = (pd[offset+5] >> 4)&0x0F; + proto_tree_add_item(fh_tree, hf_isl_type, offset+5, 1, pd[offset+5]); + switch (type) { + + case TYPE_ETHER: + proto_tree_add_item(fh_tree, hf_isl_user_eth, offset+5, 1, + pd[offset+5]&0x03); + break; + + default: + /* XXX - the spec appears to indicate that the "User" field is + used for TYPE_TR to distinguish between types of packets. */ + proto_tree_add_item(fh_tree, hf_isl_user, offset+5, 1, pd[offset+5]); + break; + } + proto_tree_add_item(fh_tree, hf_isl_src, offset+6, 6, &pd[offset+6]); + length = pntohs(&pd[offset+12]); + proto_tree_add_item(fh_tree, hf_isl_len, offset+12, 2, length); + offset += 14; + + /* This part looks sort of like a SNAP-encapsulated LLC header... */ + proto_tree_add_text(fh_tree, offset, 1, "DSAP: 0x%X", pd[offset]); + proto_tree_add_text(fh_tree, offset+1, 1, "SSAP: 0x%X", pd[offset+1]); + proto_tree_add_text(fh_tree, offset+2, 1, "Control: 0x%X", pd[offset+2]); + + /* ...but this is the manufacturer's ID portion of the source address + field (which is, admittedly, an OUI). */ + proto_tree_add_item(fh_tree, hf_isl_hsa, offset+3, 3, + pd[offset+3] << 16 | pd[offset+4] << 8 | pd[offset+5]); + proto_tree_add_item(fh_tree, hf_isl_vlan_id, offset+6, 2, + pntohs(&pd[offset+6])); + proto_tree_add_item(fh_tree, hf_isl_bpdu, offset+6, 2, + pntohs(&pd[offset+6])); + proto_tree_add_item(fh_tree, hf_isl_index, offset+8, 2, + pntohs(&pd[offset+8])); + + switch (type) { + + case TYPE_ETHER: + offset += 12; /* skip the header */ + dissect_eth(pd, offset, fd, tree); + break; + + case TYPE_TR: + proto_tree_add_item(fh_tree, hf_isl_src_vlan_id, offset+10, 2, + pntohs(&pd[offset+10])); + proto_tree_add_item(fh_tree, hf_isl_explorer, offset+10, 2, + pntohs(&pd[offset+10])); + proto_tree_add_item(fh_tree, hf_isl_dst_route_descriptor, offset+12, 2, + pntohs(&pd[offset+12])); + proto_tree_add_item(fh_tree, hf_isl_src_route_descriptor, offset+14, 2, + pntohs(&pd[offset+14])); + proto_tree_add_item(fh_tree, hf_isl_fcs_not_incl, offset+16, 1, + pd[offset+16]); + proto_tree_add_item(fh_tree, hf_isl_esize, offset+16, 1, + pd[offset+16]); + offset += 17; /* skip the header */ + dissect_tr(pd, offset, fd, tree); + break; + + default: + offset += 12; /* skip the header */ + dissect_data(pd, offset, fd, tree); + break; + } + } +} + +void +proto_register_isl(void) +{ + static hf_register_info hf[] = { + { &hf_isl_dst, + { "Destination", "isl.dst", FT_ETHER, BASE_NONE, NULL, 0x0, + "Destination Address" }}, + { &hf_isl_type, + { "Type", "isl.type", FT_UINT8, BASE_NONE, + VALS(type_vals), 0xF0, "Type" }}, + { &hf_isl_user_eth, + { "User", "isl.user_eth", FT_UINT8, BASE_NONE, + VALS(ether_user_vals), 0x0F, "Priority (for Ethernet)" }}, + { &hf_isl_user, + { "User", "isl.user", FT_UINT8, BASE_HEX, NULL, 0x0F, + "User-defined bits" }}, + { &hf_isl_src, + { "Source", "isl.src", FT_ETHER, BASE_NONE, NULL, 0x0, + "Source Hardware Address" }}, + { &hf_isl_len, + { "Length", "isl.len", FT_UINT16, BASE_DEC, NULL, 0x0, + "" }}, + { &hf_isl_hsa, + { "HSA", "isl.hsa", FT_UINT24, BASE_HEX, NULL, 0x0, + "High bits of source address" }}, + { &hf_isl_vlan_id, + { "VLAN ID", "isl.vlan_id", FT_UINT16, BASE_HEX, NULL, + 0xFFFE, "Virtual LAN ID" }}, + { &hf_isl_bpdu, + { "BPDU", "isl.bpdu", FT_BOOLEAN, 16, + TFS(&bpdu_tfs), 0x0001, "BPDU indicator" }}, + { &hf_isl_index, + { "Index", "isl.index", FT_UINT16, BASE_DEC, NULL, 0x0, + "Port index of packet source" }}, + { &hf_isl_src_vlan_id, + { "Source VLAN ID", "isl.src_vlan_id", FT_UINT16, BASE_HEX, NULL, + 0xFFFE, "Source Virtual LAN ID" }}, + { &hf_isl_explorer, + { "Explorer", "isl.explorer", FT_BOOLEAN, 16, + TFS(&explorer_tfs), 0x0001, "Explorer" }}, + { &hf_isl_dst_route_descriptor, + { "Destination route descriptor", "isl.dst_route_desc", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Route descriptor to be used for forwarding" }}, + { &hf_isl_src_route_descriptor, + { "Source-route descriptor", "isl.src_route_desc", + FT_UINT16, BASE_HEX, NULL, 0x0, + "Route descriptor to be used for source learning" }}, + { &hf_isl_fcs_not_incl, + { "FCS Not Included", "isl.fcs_not_incl", FT_BOOLEAN, 9, + NULL, 0x40, "FCS not included" }}, + { &hf_isl_esize, + { "Esize", "isl.esize", FT_UINT8, BASE_DEC, NULL, + 0x3F, "Frame size for frames less than 64 bytes" }}, + }; + static gint *ett[] = { + &ett_isl, + }; + + proto_isl = proto_register_protocol("Cisco ISL", "isl"); + proto_register_field_array(proto_isl, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} @@ -1,7 +1,7 @@ /* packet.h * Definitions for packet disassembly structures and routines * - * $Id: packet.h,v 1.167 2000/01/23 08:55:37 guy Exp $ + * $Id: packet.h,v 1.168 2000/01/24 18:46:45 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -287,6 +287,7 @@ void capture_raw(const u_char *, packet_counts *); void capture_eth(const u_char *, int, packet_counts *); void capture_ip(const u_char *, int, packet_counts *); void capture_ipx(const u_char *, int, packet_counts *); +void capture_isl(const u_char *, int, packet_counts *); void capture_llc(const u_char *, int, packet_counts *); void capture_netbios(const u_char *, int, packet_counts *); void capture_tr(const u_char *, int, packet_counts *); @@ -355,6 +356,7 @@ void dissect_ipv6(const u_char *, int, frame_data *, proto_tree *); void dissect_ipx(const u_char *, int, frame_data *, proto_tree *); void dissect_irc(const u_char *, int, frame_data *, proto_tree *); void dissect_isis(const u_char *, int, frame_data *, proto_tree *); +void dissect_isl(const u_char *, int, frame_data *, proto_tree *); void dissect_ldap(const u_char *, int, frame_data *, proto_tree *); void dissect_llc(const u_char *, int, frame_data *, proto_tree *); void dissect_lpd(const u_char *, int, frame_data *, proto_tree *); |