diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-12-26 21:17:49 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-12-26 21:17:49 +0000 |
commit | c0ff48d6d003d03779307b8a105f202715654a16 (patch) | |
tree | adee0be2ede488a5629a0c6faceb22e45289e8ef /packet-dlsw.c | |
parent | 99502224b94aec2b2ec397379b42660c20c76a04 (diff) | |
download | wireshark-c0ff48d6d003d03779307b8a105f202715654a16.tar.gz wireshark-c0ff48d6d003d03779307b8a105f202715654a16.tar.bz2 wireshark-c0ff48d6d003d03779307b8a105f202715654a16.zip |
DLSw support, from Paul Ionescu.
svn path=/trunk/; revision=4449
Diffstat (limited to 'packet-dlsw.c')
-rw-r--r-- | packet-dlsw.c | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/packet-dlsw.c b/packet-dlsw.c new file mode 100644 index 0000000000..3e797d8690 --- /dev/null +++ b/packet-dlsw.c @@ -0,0 +1,444 @@ +/* packet-dlsw.c + * Routines for DLSw packet dissection (Data Link Switching) + * Copyright 2001, Paul Ionescu <paul@acorp.ro> + * + * $Id: packet-dlsw.c,v 1.1 2001/12/26 21:17:49 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * 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. + */ + +/* DLSw dissector ( RFC 1434, RFC 1795, RFC 2166) */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#endif + +#include <string.h> +#include <glib.h> +#include "packet.h" + +static int proto_dlsw = -1; + +static gint ett_dlsw = -1; +static gint ett_dlsw_header = -1; +static gint ett_dlsw_data = -1; +static gint ett_dlsw_vector = -1; + +#define CANUREACH 0x03 +#define ICANREACH 0x04 +#define REACH_ACK 0x05 +#define DGRMFRAME 0x06 +#define XIDFRAME 0x07 +#define CONTACT 0x08 +#define CONTACTED 0x09 +#define RESTART_DL 0x10 +#define DL_RESTARTED 0x11 +#define ENTER_BUSY 0x0C +#define EXIT_BUSY 0x0D +#define INFOFRAME 0x0A +#define HALT_DL 0x0E +#define DL_HALTED 0x0F +#define NETBIOS_NQ 0x12 +#define NETBIOS_NR 0x13 +#define DATAFRAME 0x14 +#define HALT_DL_NOACK 0x19 +#define NETBIOS_ANQ 0x1A +#define NETBIOS_ANR 0x1B +#define KEEPALIVE 0x1D +#define CAP_EXCHANGE 0x20 +#define IFCM 0x21 +#define TEST_CIRCUIT_REQ 0x7A +#define TEST_CIRCUIT_RSP 0x7B + +static const value_string dlsw_type_vals[] = { + { CANUREACH , "Can U Reach Station-circuit start" }, + { ICANREACH , "I Can Reach Station-circuit start" }, + { REACH_ACK , "Reach Acknowledgment" }, + { DGRMFRAME , "Datagram Frame" }, + { XIDFRAME , "XID Frame" }, + { CONTACT , "Contact Remote Station" }, + { CONTACTED , "Remote Station Contacted" }, + { RESTART_DL , "Restart Data Link" }, + { DL_RESTARTED , "Data Link Restarted" }, + { ENTER_BUSY , "Enter Busy" }, + { EXIT_BUSY , "Exit Busy" }, + { INFOFRAME , "Information (I) Frame" }, + { HALT_DL , "Halt Data Link" }, + { DL_HALTED , "Data Link Halted" }, + { NETBIOS_NQ , "NETBIOS Name Query-circuit setup" }, + { NETBIOS_NR , "NETBIOS Name Recog-circuit setup" }, + { DATAFRAME , "Data Frame" }, + { HALT_DL_NOACK , "Halt Data Link with no Ack" }, + { NETBIOS_ANQ , "NETBIOS Add Name Query" }, + { NETBIOS_ANR , "NETBIOS Add Name Response" }, + { KEEPALIVE , "Transport Keepalive Message" }, + { CAP_EXCHANGE , "Capabilities Exchange" }, + { IFCM , "Independent Flow Control Message" }, + { TEST_CIRCUIT_REQ , "Test Circuit Request" }, + { TEST_CIRCUIT_RSP , "Test Circuit Response" }, + { 0 , NULL } +}; +static const value_string dlsw_version_vals[] = { + { 0x31 , "Version 1 (RFC 1795)" }, + { 0x32 , "Version 2 (RFC 2166)" }, + { 0x33 , "Vendor Specific" }, + { 0x34 , "Vendor Specific" }, + { 0x35 , "Vendor Specific" }, + { 0x36 , "Vendor Specific" }, + { 0x37 , "Vendor Specific" }, + { 0x38 , "Vendor Specific" }, + { 0x39 , "Vendor Specific" }, + { 0x3A , "Vendor Specific" }, + { 0x3B , "Vendor Specific" }, + { 0x3C , "Vendor Specific" }, + { 0x3D , "Vendor Specific" }, + { 0x3E , "Vendor Specific" }, + { 0x3F , "Vendor Specific" }, + { 0x4B , "Pre 1 (RFC 1434)" }, + { 0x00 , NULL } +}; + +static const value_string dlsw_vector_vals[] = { + { 0x81 , "Vendor ID Control Vector" }, + { 0x82 , "DLSw Version Control Vector" }, + { 0x83 , "Initial Pacing Window Control Vector" }, + { 0x84 , "Version String Control Vector" }, + { 0x85 , "Mac Address Exclusivity Control Vector" }, + { 0x86 , "Supported SAP List Control Vector" }, + { 0x87 , "TCP Connections Control Vector" }, + { 0x88 , "NetBIOS Name Exclusivity Control Vector" }, + { 0x89 , "MAC Address List Control Vector" }, + { 0x8a , "NetBIOS Name List Control Vector" }, + { 0x8b , "Vendor Context Control Vector" }, + { 0x8c , "Multicast Capabilities Control Vector" }, + { 0x8d , "Reserved for future use" }, + { 0x8e , "Reserved for future use" }, + { 0x8f , "Reserved for future use" }, + { 0x90 , "Reserved for future use" }, + { 0x91 , " Control Vector" }, + { 0x92 , " Control Vector" }, + { 0x93 , " Control Vector" }, + { 0x94 , " Control Vector" }, + { 0x95 , " Control Vector" }, + { 0x96 , " Control Vector" }, + { 0x00 , NULL } +}; + +static const value_string dlsw_pri_vals[] = { + { 0 , "Unsupported" }, + { 1 , "Low Priority" }, + { 2 , "Medium Priority" }, + { 3 , "High Priority" }, + { 4 , "Highest Priority" }, + { 5 , "Reserved" }, + { 6 , "Reserved" }, + { 7 , "Reserved" } +}; + + + + +#define DLSW_GDSID_SEND 0x1520 +#define DLSW_GDSID_ACK 0x1521 +#define DLSW_GDSID_REF 0x1522 + +static const value_string dlsw_gds_vals[] = { + { DLSW_GDSID_SEND , "Request Capabilities GDS" }, + { DLSW_GDSID_ACK , "Response Capabilities GDS" }, + { DLSW_GDSID_REF , "Refuse Capabilities GDS" }, + { 0 , NULL } +}; + +static const value_string dlsw_refuse_vals[] = { + { 0x1 , "invalid GDS length for a DLWs Capabilities Exchange Request"}, + { 0x2 , "invalid GDS id for a DLSw Capabilities Exchange Request"}, + { 0x3 , "vendor Id control vector is missing"}, + { 0x4 , "DLSw Version control vector is missing"}, + { 0x5 , "initial Pacing Window control vector is missing"}, + { 0x6 , "length of control vectors doewn't correlate to the length of the GDS variable"}, + { 0x7 , "invalid control vector id"}, + { 0x8 , "length of control vector invalid"}, + { 0x9 , "invalid control vector data value"}, + { 0xa , "duplicate control vector"}, + { 0xb , "out-of-sequence control vector"}, + { 0xc , "DLSw Supported SAP List control vector is missing"}, + { 0xd , "inconsistent DLSw Version, Multicast Capabilities,\ + and TCP Connections CV received on the inbound Capabilities exchange"}, + { 0x0 , NULL } +}; + +#define UDP_PORT_DLSW 2067 +#define TCP_PORT_DLSW 2065 +#define DLSW_INFO_HEADER 16 +#define DLSW_CMD_HEADER 72 + +static dissector_handle_t dlsw_handle; + +static void +dissect_dlsw_capex(tvbuff_t *tvb, proto_tree *tree, proto_tree *ti); + +static void +dissect_dlsw(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint version,hlen = 0,mlen = 0,mtype,offset,dlchlen = 0,direction; + proto_tree *dlsw_tree = NULL, *ti,*ti2, *dlsw_header_tree = NULL; + proto_tree *dlsw_data_tree; + + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "DLSw"); + + version=tvb_get_guint8(tvb,0); + + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, "DLSw %s",val_to_str(version , dlsw_version_vals, "Unknown Version")); + + if (tree) + { + ti = proto_tree_add_item(tree, proto_dlsw, tvb, 0, tvb_length(tvb), FALSE); + dlsw_tree = proto_item_add_subtree(ti, ett_dlsw); + + hlen=tvb_get_guint8(tvb,1); + + ti2 = proto_tree_add_text (dlsw_tree, tvb, 0, hlen,"DLSw header, %s", + val_to_str(version , dlsw_version_vals, "Unknown Version")); + + dlsw_header_tree = proto_item_add_subtree(ti2, ett_dlsw_header); + proto_tree_add_text (dlsw_header_tree,tvb,0 ,1,"Version = %s", + val_to_str(version , dlsw_version_vals, "Unknown Version, dissection may be innacurate")); + proto_tree_add_text (dlsw_header_tree,tvb,1 ,1,"Header Length = %u",hlen) ; + mlen=tvb_get_ntohs(tvb,2); + proto_tree_add_text (dlsw_header_tree,tvb,2 ,2,"Message Length = %u",mlen); + proto_tree_add_text (dlsw_header_tree,tvb,4 ,4,"Remote DLC = %u",tvb_get_ntohl(tvb,4)) ; + proto_tree_add_text (dlsw_header_tree,tvb,8 ,4,"Remote DLC PID = %u",tvb_get_ntohl(tvb,8)) ; + proto_tree_add_text (dlsw_header_tree,tvb,12,2,"Reserved") ; + } ; + + mtype=tvb_get_guint8(tvb,14); + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",val_to_str(mtype , dlsw_type_vals, "Unknown message Type")); + if (tree) + { + proto_tree_add_text (dlsw_header_tree,tvb,14,1,"Message Type = %s (%d)", + val_to_str(mtype , dlsw_type_vals, "Unknown Type"),mtype); + proto_tree_add_text (dlsw_header_tree, tvb, 15,1,"Flow ctrl byte = %d",tvb_get_guint8(tvb,15)); + + if (hlen != DLSW_INFO_HEADER) + { + proto_tree_add_text (dlsw_header_tree,tvb, 16,1,"Protocol ID = %d",tvb_get_guint8(tvb,16)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 17,1,"Header Number = %d",tvb_get_guint8(tvb,17)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 18,2,"Reserved") ; + proto_tree_add_text (dlsw_header_tree,tvb, 20,1,"Largest Frame size = %d",tvb_get_guint8(tvb,20)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 21,1,"SSP Flags = %d",tvb_get_guint8(tvb,21)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 22,1,"Circuit priority = %s", + match_strval((tvb_get_guint8(tvb,22)&7),dlsw_pri_vals)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 23,1,"Old message type = %s (%d)", + val_to_str(tvb_get_guint8(tvb,23) , dlsw_type_vals, "Unknown Type"),tvb_get_guint8(tvb,23)); + if (mtype==CAP_EXCHANGE) + { + proto_tree_add_text (dlsw_header_tree,tvb, 24 ,14,"Not used for CapEx") ; + proto_tree_add_text (dlsw_header_tree,tvb, 38,1,"Frame direction = %s", + tvb_get_guint8(tvb,38)==1?"Capabilities request":"Capabilities response") ; + proto_tree_add_text (dlsw_header_tree,tvb, 39,33,"Not used for CapEx") ; + } + else + { + proto_tree_add_text (dlsw_header_tree,tvb, 24,6,"Target MAC Address = %s",tvb_bytes_to_str(tvb,24,6)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 30,6,"Origin MAC Address = %s",tvb_bytes_to_str(tvb,30,6)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 36,1,"Origin Link SAP = %02x",tvb_get_guint8(tvb,36)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 37,1,"Target Link SAP = %02x",tvb_get_guint8(tvb,37)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 38,1,"Frame direction = %d",tvb_get_guint8(tvb,38)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 39,3,"Reserved") ; + dlchlen=tvb_get_ntohs(tvb,42); + proto_tree_add_text (dlsw_header_tree,tvb, 42,2,"DLC Header Length = %d",dlchlen) ; + proto_tree_add_text (dlsw_header_tree,tvb, 44,4,"Origin DLC Port ID = %u",tvb_get_ntohl(tvb,44)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 48,4,"Origin DLC = %u",tvb_get_ntohl(tvb,48)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 52,4,"Origin Transport ID = %u",tvb_get_ntohl(tvb,52)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 56,4,"Target DLC Port ID = %u",tvb_get_ntohl(tvb,56)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 60,4,"Target DLC = %u",tvb_get_ntohl(tvb,60)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 64,4,"Target Transport ID = %u",tvb_get_ntohl(tvb,64)) ; + proto_tree_add_text (dlsw_header_tree,tvb, 68,4,"Reserved") ; + } + direction=tvb_get_guint8(tvb,38); + } + +/* end of header dissector */ + + ti2 = proto_tree_add_text (dlsw_tree, tvb, hlen, mlen,"DLSw data"); + dlsw_data_tree = proto_item_add_subtree(ti2, ett_dlsw_data); + + switch (mtype) + { + case CAP_EXCHANGE: + dissect_dlsw_capex(tvb_new_subset(tvb, hlen, mlen, -1), dlsw_data_tree,ti2); + break; + case IFCM: + case INFOFRAME: + case KEEPALIVE: + proto_tree_add_text (dlsw_data_tree,tvb,hlen,mlen,"Data") ; + break; + + default: + if (dlchlen!=0) + { + proto_tree_add_text (dlsw_data_tree,tvb,hlen,1,"DLC Header - AC byte : 0x%02x",tvb_get_guint8(tvb,hlen)) ; + proto_tree_add_text (dlsw_data_tree,tvb,hlen+1,1,"DLC Header - FC byte : 0x%02x",tvb_get_guint8(tvb,hlen+1)) ; + proto_tree_add_text (dlsw_data_tree,tvb,hlen+2,6,"DLC Header - DA : %s",tvb_bytes_to_str(tvb,hlen+2,6)) ; + proto_tree_add_text (dlsw_data_tree,tvb,hlen+8,6,"DLC Header - SA : %s",tvb_bytes_to_str(tvb,hlen+8,6)) ; + proto_tree_add_text (dlsw_data_tree,tvb,hlen+14,18,"DLC Header - RIF : %s",tvb_bytes_to_str(tvb,hlen+14,18)) ; + proto_tree_add_text (dlsw_data_tree,tvb,hlen+32,1,"DLC Header - DSAP : 0x%02x",tvb_get_guint8(tvb,hlen+32)) ; + proto_tree_add_text (dlsw_data_tree,tvb,hlen+33,1,"DLC Header - SSAP : 0x%02x",tvb_get_guint8(tvb,hlen+33)) ; + proto_tree_add_text (dlsw_data_tree,tvb,hlen+34,1,"DLC Header - Ctrl : 0x%02x",tvb_get_guint8(tvb,hlen+34)) ; + } + proto_tree_add_text (dlsw_data_tree,tvb,hlen+dlchlen,mlen-dlchlen,"Data") ; + } + + } +} + +static void +dissect_dlsw_capex(tvbuff_t *tvb, proto_tree *tree, proto_tree *ti2) +{ + int mlen,vlen,vtype,offset=4,gdsid,sap,i=0; + proto_tree *ti,*dlsw_vector_tree; + mlen=tvb_get_ntohs(tvb,0); + gdsid=tvb_get_ntohs(tvb,2); + proto_tree_add_text (tree,tvb,0,2,"Capabilities Length = %d",mlen) ; + proto_tree_add_text (tree,tvb,2,2,"%s",val_to_str( gdsid, dlsw_gds_vals, "Invalid GDS ID")); + proto_item_append_text(ti2," - %s",val_to_str( gdsid, dlsw_gds_vals, "Invalid GDS ID")); + switch (gdsid) { + case DLSW_GDSID_ACK: + break; + case DLSW_GDSID_REF: + proto_tree_add_text (tree,tvb,4,2,"Erorr pointer = %d",tvb_get_ntohs(tvb,4)); + proto_tree_add_text (tree,tvb,6,2,"Erorr cause = %s", + val_to_str(tvb_get_ntohs(tvb,6), dlsw_refuse_vals, "Unknown refuse cause")); + break; + case DLSW_GDSID_SEND: + while (offset < mlen){ + vlen=tvb_get_guint8(tvb,offset); + vtype=tvb_get_guint8(tvb,offset+1); + ti=proto_tree_add_text (tree,tvb,offset,vlen,"%s", + val_to_str(vtype,dlsw_vector_vals,"Unknown vector type")); + dlsw_vector_tree = proto_item_add_subtree(ti, ett_dlsw_vector); + proto_tree_add_text (dlsw_vector_tree,tvb,offset,1, "Vector Length = %d",vlen); + proto_tree_add_text (dlsw_vector_tree,tvb,offset+1,1,"Vector Type = %s (0x%02x)", + val_to_str(vtype,dlsw_vector_vals,"Unknown vector type"),vtype); + switch (vtype){ + case 0x81: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "OUI = 0x%06x",tvb_get_ntoh24(tvb,offset+2)); + break; + case 0x82: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "DLSw Version = %d.%d",tvb_get_guint8(tvb,offset+2),tvb_get_guint8(tvb,offset+3)); + break; + case 0x83: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "Initial Pacing Window = %d",tvb_get_ntohs(tvb,offset+2)); + break; + case 0x84: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "Version String = %s",tvb_format_text(tvb,offset+2,vlen-2)); + break; + case 0x85: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "MAC Address Exclusivity = %s",tvb_get_guint8(tvb,offset+2)==1?"On":"Off"); + break; + case 0x86: + while (i<vlen-2) + { + sap=tvb_get_guint8(tvb,offset+2+i); + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2+i,1, + "SAP List Support = 0x%x0=%s 0x%x2=%s 0x%x4=%s 0x%x6=%s 0x%x8=%s 0x%xa=%s 0x%xc=%s 0x%xe=%s", + i,sap&0x80?"on ":"off",i,sap&0x40?"on ":"off",i,sap&0x20?"on ":"off",i,sap&0x10?"on ":"off", + i,sap&0x08?"on ":"off",i,sap&0x04?"on ":"off",i,sap&0x02?"on ":"off",i,sap&0x01?"on ":"off"); + i++; + } + break; + case 0x87: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "TCP connections = %d",tvb_get_guint8(tvb,offset+2)); + break; + case 0x88: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "NetBIOS Name Exclusivity = %s",tvb_get_guint8(tvb,offset+2)==1?"On":"Off"); + break; + case 0x89: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "MAC Address List = %s / %s",tvb_bytes_to_str(tvb,offset+2,6) + ,tvb_bytes_to_str(tvb,offset+8,6)); + break; + case 0x8a: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, +/* %s */ "NetBIOS name = %s",/* tvb_get_guint8(tvb,offset+2)==0?"Individual":"Group",*/ + tvb_format_text(tvb,offset+2,vlen-2)); + break; + case 0x8b: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "Vendor OUI = 0x%06x",tvb_get_ntoh24(tvb,offset+2)); + break; + case 0x8c: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2, + "Multicast Version Number = %d",tvb_get_guint8(tvb,offset+2)); + break; + default: + proto_tree_add_text (dlsw_vector_tree,tvb,offset+2,vlen-2,"Vector Data = ???"); + } + offset+=vlen; + }; + break; + default: + proto_tree_add_text (tree,tvb,4,mlen - 4,"Unknown data"); + } + +} + +void +proto_register_dlsw(void) +{ + static gint *ett[] = { + &ett_dlsw, + &ett_dlsw_header, + &ett_dlsw_data, + &ett_dlsw_vector, + }; + proto_dlsw = proto_register_protocol("Data Link SWitching", "DLSw", "dlsw"); +/* proto_register_field_array(proto_dlsw, hf, array_length(hf)); */ + proto_register_subtree_array(ett, array_length(ett)); + dlsw_handle = find_dissector("dlsw"); +} + +void +proto_reg_handoff_dlsw(void) +{ + dlsw_handle = create_dissector_handle(dissect_dlsw, proto_dlsw); + + dissector_add("tcp.port", TCP_PORT_DLSW, dlsw_handle); + dissector_add("udp.port", UDP_PORT_DLSW, dlsw_handle); +} |