X-Git-Url: http://git.samba.org/samba.git/?p=obnox%2Fwireshark%2Fwip.git;a=blobdiff_plain;f=packet-ipx.c;h=8a58fd392d4ffd920c72f63f1c0f32ff39b10284;hp=12a3ff5bc0aca39d703f599244c3ddebf3221d08;hb=e8808ef879294d746a27b340f5d4e92a1adee92e;hpb=897ec6fb57e0d6b0cab1bad29ae4829fcbf50fb1 diff --git a/packet-ipx.c b/packet-ipx.c index 12a3ff5bc0..8a58fd392d 100644 --- a/packet-ipx.c +++ b/packet-ipx.c @@ -1,11 +1,11 @@ /* packet-ipx.c * Routines for NetWare's IPX - * Gilbert Ramirez + * Gilbert Ramirez * - * $Id: packet-ipx.c,v 1.33 1999/11/17 02:17:06 guy Exp $ + * $Id: packet-ipx.c,v 1.46 2000/01/22 06:22:13 guy Exp $ * * Ethereal - Network traffic analyzer - * By Gerald Combs + * By Gerald Combs * Copyright 1998 Gerald Combs * * @@ -37,6 +37,9 @@ #include "packet.h" #include "packet-ipx.h" #include "packet-ncp.h" +#include "resolv.h" + +#include "packet-snmp.h" /* The information in this module (IPX, SPX, NCP) comes from: NetWare LAN Analysis, Second Edition @@ -87,6 +90,11 @@ static int hf_sap_response = -1; static gint ett_ipxsap = -1; static gint ett_ipxsap_server = -1; +static gint ett_ipxmsg = -1; +static int proto_ipxmsg = -1; +static int hf_msg_conn = -1; +static int hf_msg_sigchar = -1; + static void dissect_spx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); @@ -96,6 +104,9 @@ dissect_ipxrip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); static void dissect_ipxsap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); +static void +dissect_ipxmsg(const u_char *pd, int offset, frame_data *fd, proto_tree *tree); + typedef void (dissect_func_t)(const u_char *, int, frame_data *, proto_tree *); struct port_info { @@ -118,6 +129,11 @@ struct server_info { /* IPX */ /* ================================================================= */ +/* info on these sockets can be found in this listing from Novell: + + http://developer.novell.com/engsup/sample/tids/dsoc1b/dsoc1b.htm +*/ + #define IPX_SOCKET_NCP 0x0451 #define IPX_SOCKET_SAP 0x0452 #define IPX_SOCKET_IPXRIP 0x0453 @@ -131,6 +147,7 @@ struct server_info { #define IPX_SOCKET_ATTACHMATE_GW 0x055d #define IPX_SOCKET_IPX_MESSAGE 0x4001 #define IPX_SOCKET_ADSM 0x8522 /* www.tivoli.com */ +#define IPX_SOCKET_WIDE_AREA_ROUTER 0x9001 #define IPX_SOCKET_SNMP_AGENT 0x900F /* RFC 1906 */ #define IPX_SOCKET_SNMP_SINK 0x9010 /* RFC 1906 */ #define IPX_SOCKET_TCP_TUNNEL 0x9091 /* RFC 1791 */ @@ -152,19 +169,18 @@ static struct port_info ports[] = { { IPX_SOCKET_NWLINK_SMB_NAMEQUERY, NULL, "NWLink SMB Name Query" }, { IPX_SOCKET_NWLINK_SMB_DGRAM, dissect_nwlink_dg, - "NWLink SMB Datagram" }, - { IPX_SOCKET_NWLINK_SMB_BROWSE, NULL, - "NWLink SMB Browse" }, - { IPX_SOCKET_ATTACHMATE_GW, NULL, - "Attachmate Gateway" }, - { IPX_SOCKET_IPX_MESSAGE, NULL, - "IPX Message" }, - { IPX_SOCKET_SNMP_AGENT, NULL, "SNMP Agent" }, - { IPX_SOCKET_SNMP_SINK, NULL, "SNMP Sink" }, + "NWLink SMB Datagram" }, + { IPX_SOCKET_NWLINK_SMB_BROWSE, NULL, "NWLink SMB Browse" }, + { IPX_SOCKET_ATTACHMATE_GW, NULL, "Attachmate Gateway" }, + { IPX_SOCKET_IPX_MESSAGE, dissect_ipxmsg, "IPX Message" }, + { IPX_SOCKET_SNMP_AGENT, dissect_snmp, "SNMP Agent" }, + { IPX_SOCKET_SNMP_SINK, dissect_snmp, "SNMP Sink" }, + { IPX_SOCKET_UDP_TUNNEL, NULL, "UDP Tunnel" }, { IPX_SOCKET_TCP_TUNNEL, NULL, "TCP Tunnel" }, { IPX_SOCKET_TCP_TUNNEL, NULL, "TCP Tunnel" }, { IPX_SOCKET_ADSM, NULL, "ADSM" }, + { IPX_SOCKET_WIDE_AREA_ROUTER, NULL, "Wide Area Router" }, { 0x0000, NULL, NULL } }; @@ -195,23 +211,38 @@ port_func(guint16 port) { return NULL; } +/* + * From: + * + * http://alr.base2co.com:457/netguide/dipxD.ipx_packet_struct.html + * + * which is part of SCO's "Network Programmer's Guide and Reference". + * + * It calls type 20 "NetBIOS name packet". Microsoft Network Monitor + * calls it "WAN Broadcast"; it's also used for SMB browser announcements, + * i.e. NetBIOS (broadcast) datagrams. + */ #define IPX_PACKET_TYPE_IPX 0 -#define IPX_PACKET_TYPE_IPX_4 4 +#define IPX_PACKET_TYPE_RIP 1 +#define IPX_PACKET_TYPE_ECHO 2 +#define IPX_PACKET_TYPE_ERROR 3 +#define IPX_PACKET_TYPE_PEP 4 #define IPX_PACKET_TYPE_SPX 5 #define IPX_PACKET_TYPE_NCP 17 -#define IPX_PACKET_TYPE_WANBCAST 20 +#define IPX_PACKET_TYPE_WANBCAST 20 /* propagated NetBIOS packet? */ static const value_string ipx_packet_type_vals[] = { { IPX_PACKET_TYPE_IPX, "IPX" }, - { IPX_PACKET_TYPE_IPX_4, "IPX" }, - /* NetMon calls it "IPX" */ + { IPX_PACKET_TYPE_RIP, "RIP" }, + { IPX_PACKET_TYPE_ECHO, "Echo" }, + { IPX_PACKET_TYPE_ERROR, "Error" }, + { IPX_PACKET_TYPE_PEP, "PEP" }, /* Packet Exchange Packet */ { IPX_PACKET_TYPE_SPX, "SPX" }, { 16, "Experimental Protocol" }, { IPX_PACKET_TYPE_NCP, "NCP" }, { 18, "Experimental Protocol" }, { 19, "Experimental Protocol" }, { IPX_PACKET_TYPE_WANBCAST, "NetBIOS Broadcast" }, - /* NetMon calls it "WAN Broadcast" */ { 21, "Experimental Protocol" }, { 22, "Experimental Protocol" }, { 23, "Experimental Protocol" }, @@ -226,29 +257,29 @@ static const value_string ipx_packet_type_vals[] = { { 0, NULL } }; +static const value_string ipxmsg_sigchar_vals[] = { + { '?', "Poll inactive station" }, + { 0, NULL } +}; + gchar* ipxnet_to_string(const guint8 *ad) { - static gchar str[3][12]; - static gchar *cur; - - if (cur == &str[0][0]) { - cur = &str[1][0]; - } else if (cur == &str[1][0]) { - cur = &str[2][0]; - } else { - cur = &str[0][0]; - } - - sprintf(cur, "%02X %02X %02X %02X", ad[0], ad[1], ad[2], ad[3]); - return cur; + guint32 addr = pntohl(ad); + return ipxnet_to_str_punct(addr, ' '); } +/* We use a different representation of hardware addresses + * than ether_to_str(); we don't put punctuation between the hex + * digits. + */ + gchar* ipx_addr_to_str(guint32 net, const guint8 *ad) { - static gchar str[3][22]; + static gchar str[3][8+1+MAXNAMELEN+1]; /* 8 digits, 1 period, NAME, 1 null */ static gchar *cur; + char *name; if (cur == &str[0][0]) { cur = &str[1][0]; @@ -258,11 +289,58 @@ ipx_addr_to_str(guint32 net, const guint8 *ad) cur = &str[0][0]; } - sprintf(cur, "%X.%02x%02x%02x%02x%02x%02x", net, - ad[0], ad[1], ad[2], ad[3], ad[4], ad[5]); + name = get_ether_name_if_known(ad); + + if (name) { + sprintf(cur, "%s.%s", get_ipxnet_name(net), name); + } + else { + sprintf(cur, "%s.%s", get_ipxnet_name(net), ether_to_str_punct(ad, '\0')); + } return cur; } +gchar * +ipxnet_to_str_punct(const guint32 ad, char punct) { + static gchar str[3][12]; + static gchar *cur; + gchar *p; + int i; + guint32 octet; + static const gchar hex_digits[16] = "0123456789ABCDEF"; + static const guint32 octet_mask[4] = + { 0xff000000 , 0x00ff0000, 0x0000ff00, 0x000000ff }; + + if (cur == &str[0][0]) { + cur = &str[1][0]; + } else if (cur == &str[1][0]) { + cur = &str[2][0]; + } else { + cur = &str[0][0]; + } + p = &cur[12]; + *--p = '\0'; + i = 3; + for (;;) { + octet = (ad & octet_mask[i]) >> ((3 - i) * 8); + *--p = hex_digits[octet&0xF]; + octet >>= 4; + *--p = hex_digits[octet&0xF]; + if (i == 0) + break; + if (punct) + *--p = punct; + i--; + } + return p; +} + +void +capture_ipx(const u_char *pd, int offset, guint32 cap_len, packet_counts *ld) +{ + ld->ipx++; +} + void dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { @@ -273,7 +351,6 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { int len; guint8 *ipx_snode, *ipx_dnode, *ipx_snet, *ipx_dnet; - gchar *str_dnet, *str_snet; guint16 ipx_dsocket, ipx_ssocket; dissect_func_t *dissect; guint32 ipx_dnet_val, ipx_snet_val; @@ -281,8 +358,6 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { /* Calculate here for use in pinfo and in tree */ ipx_dnet = (guint8*)&pd[offset+6]; ipx_snet = (guint8*)&pd[offset+18]; - str_dnet = ipxnet_to_string(ipx_dnet); - str_snet = ipxnet_to_string(ipx_snet); ipx_dnet_val = pntohl(ipx_dnet); ipx_snet_val = pntohl(ipx_snet); ipx_dsocket = pntohs(&pd[offset+16]); @@ -359,7 +434,7 @@ dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { break; case IPX_PACKET_TYPE_WANBCAST: - case IPX_PACKET_TYPE_IPX_4: + case IPX_PACKET_TYPE_PEP: if (ipx_dsocket == IPX_SOCKET_NETBIOS) { dissect_nbipx(pd, offset, fd, tree); break; @@ -479,6 +554,41 @@ dissect_spx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { } } +/* ================================================================= */ +/* IPX Message */ +/* ================================================================= */ +static void +dissect_ipxmsg(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) { + proto_tree *msg_tree; + proto_item *ti; + u_char conn_number, sig_char; + + if ( ! BYTES_ARE_IN_FRAME(offset,2) ) + { + return; + } + + conn_number = pd[offset]; + sig_char = pd[offset+1]; + + if (check_col(fd, COL_PROTOCOL)) + col_add_str(fd, COL_PROTOCOL, "IPX MSG"); + if (check_col(fd, COL_PROTOCOL)) { + col_add_fstr(fd, COL_INFO, + "%s, Connection %d", + val_to_str(sig_char, ipxmsg_sigchar_vals, "Unknown Signature Char"), conn_number); + } + + if (tree) { + ti = proto_tree_add_item(tree, proto_ipxmsg, offset, END_OF_FRAME, NULL); + msg_tree = proto_item_add_subtree(ti, ett_ipxmsg); + + proto_tree_add_item(msg_tree, hf_msg_conn, offset, 1, conn_number); + proto_tree_add_item(msg_tree, hf_msg_sigchar, offset+1, 1, sig_char); + } +} + + /* ================================================================= */ /* IPX RIP */ /* ================================================================= */ @@ -816,9 +926,23 @@ proto_register_ipx(void) FT_BOOLEAN, BASE_NONE, NULL, 0x0, "TRUE if SAP response" }} }; + + static hf_register_info hf_ipxmsg[] = { + { &hf_msg_conn, + { "Connection Number", "ipxmsg.conn", + FT_UINT8, BASE_NONE, NULL, 0x0, + "Connection Number" }}, + + { &hf_msg_sigchar, + { "Signature Char", "ipxmsg.sigchar", + FT_UINT8, BASE_NONE, VALS(ipxmsg_sigchar_vals), 0x0, + "Signature Char" }} + }; + static gint *ett[] = { &ett_ipx, &ett_spx, + &ett_ipxmsg, &ett_ipxrip, &ett_ipxsap, &ett_ipxsap_server, @@ -833,6 +957,9 @@ proto_register_ipx(void) proto_ipxrip = proto_register_protocol ("IPX Routing Information Protocol", "ipxrip"); proto_register_field_array(proto_ipxrip, hf_ipxrip, array_length(hf_ipxrip)); + proto_ipxmsg = proto_register_protocol ("IPX Message", "ipxmsg"); + proto_register_field_array(proto_ipxmsg, hf_ipxmsg, array_length(hf_ipxmsg)); + proto_sap = proto_register_protocol ("Service Advertisement Protocol", "sap"); proto_register_field_array(proto_sap, hf_sap, array_length(hf_sap));