/* packet-ipx.c
* Routines for NetWare's IPX
- * Gilbert Ramirez <gram@verdict.uthscsa.edu>
+ * Gilbert Ramirez <gram@xiexie.org>
*
- * $Id: packet-ipx.c,v 1.39 1999/11/30 23:56:35 gram Exp $
+ * $Id: packet-ipx.c,v 1.60 2000/05/30 03:35:51 guy Exp $
*
* Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@unicom.net>
+ * By Gerald Combs <gerald@zing.org>
* Copyright 1998 Gerald Combs
*
*
#include <stdio.h>
#include <glib.h>
+#include "etypes.h"
+#include "ppptypes.h"
+#include "llcsaps.h"
#include "packet.h"
#include "packet-ipx.h"
-#include "packet-ncp.h"
+#include "packet-nbipx.h"
#include "resolv.h"
+#include "packet-snmp.h"
+
/* The information in this module (IPX, SPX, NCP) comes from:
NetWare LAN Analysis, Second Edition
Laura A. Chappell and Dan E. Hakes
static gint ett_ipx = -1;
+static dissector_table_t ipx_type_dissector_table;
+static dissector_table_t ipx_socket_dissector_table;
+
static int proto_spx = -1;
static int hf_spx_connection_control = -1;
static int hf_spx_datastream_type = -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);
static void
dissect_ipxsap(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 *);
+static void
+dissect_ipxmsg(const u_char *pd, int offset, frame_data *fd, proto_tree *tree);
+
+#define UDP_PORT_IPX 213 /* RFC 1234 */
struct port_info {
guint16 port;
- dissect_func_t *func;
char *text;
};
/* IPX */
/* ================================================================= */
-#define IPX_SOCKET_NCP 0x0451
-#define IPX_SOCKET_SAP 0x0452
-#define IPX_SOCKET_IPXRIP 0x0453
-#define IPX_SOCKET_NETBIOS 0x0455
-#define IPX_SOCKET_DIAGNOSTIC 0x0456
-#define IPX_SOCKET_SERIALIZATION 0x0457
-#define IPX_SOCKET_NWLINK_SMB_NAMEQUERY 0x0551
-#define IPX_SOCKET_NWLINK_SMB_DGRAM 0x0553
-#define IPX_SOCKET_NWLINK_SMB_BROWSE 0x0555 /* ? not sure on this
- but I guessed based on the content of the packet I saw */
-#define IPX_SOCKET_ATTACHMATE_GW 0x055d
-#define IPX_SOCKET_IPX_MESSAGE 0x4001
-#define IPX_SOCKET_ADSM 0x8522 /* www.tivoli.com */
-#define IPX_SOCKET_SNMP_AGENT 0x900F /* RFC 1906 */
-#define IPX_SOCKET_SNMP_SINK 0x9010 /* RFC 1906 */
-#define IPX_SOCKET_TCP_TUNNEL 0x9091 /* RFC 1791 */
-#define IPX_SOCKET_UDP_TUNNEL 0x9092 /* RFC 1791 */
-
static struct port_info ports[] = {
- { IPX_SOCKET_NCP, dissect_ncp,
- "NCP" },
- { IPX_SOCKET_SAP, dissect_ipxsap,
- "SAP" },
- { IPX_SOCKET_IPXRIP, dissect_ipxrip,
- "RIP" },
- { IPX_SOCKET_NETBIOS, NULL,
- "NetBIOS" },
- { IPX_SOCKET_DIAGNOSTIC, NULL,
- "Diagnostic" },
- { IPX_SOCKET_SERIALIZATION, NULL,
- "Serialization" },
- { 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" },
- { 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" },
- { 0x0000, NULL,
- NULL }
+ { IPX_SOCKET_PING_CISCO, "CISCO PING" },
+ { IPX_SOCKET_NCP, "NCP" },
+ { IPX_SOCKET_SAP, "SAP" },
+ { IPX_SOCKET_IPXRIP, "RIP" },
+ { IPX_SOCKET_NETBIOS, "NetBIOS" },
+ { IPX_SOCKET_DIAGNOSTIC, "Diagnostic" },
+ { IPX_SOCKET_SERIALIZATION, "Serialization" },
+ { IPX_SOCKET_NWLINK_SMB_NAMEQUERY, "NWLink SMB Name Query" },
+ { IPX_SOCKET_NWLINK_SMB_DGRAM, "NWLink SMB Datagram" },
+ { IPX_SOCKET_NWLINK_SMB_BROWSE, "NWLink SMB Browse" },
+ { IPX_SOCKET_ATTACHMATE_GW, "Attachmate Gateway" },
+ { IPX_SOCKET_IPX_MESSAGE, "IPX Message" },
+ { IPX_SOCKET_SNMP_AGENT, "SNMP Agent" },
+ { IPX_SOCKET_SNMP_SINK, "SNMP Sink" },
+ { IPX_SOCKET_PING_NOVELL, "NOVELL PING" },
+ { IPX_SOCKET_UDP_TUNNEL, "UDP Tunnel" },
+ { IPX_SOCKET_TCP_TUNNEL, "TCP Tunnel" },
+ { IPX_SOCKET_TCP_TUNNEL, "TCP Tunnel" },
+ { IPX_SOCKET_ADSM, "ADSM" },
+ { IPX_SOCKET_EIGRP, "Cisco EIGRP for IPX" },
+ { IPX_SOCKET_WIDE_AREA_ROUTER, "Wide Area Router" },
+ { 0x0000, NULL }
};
static char*
return "Unknown";
}
-static dissect_func_t*
-port_func(guint16 port) {
- int i=0;
-
- while (ports[i].text != NULL) {
- if (ports[i].port == port) {
- return ports[i].func;
- }
- i++;
- }
- 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_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 /* propagated NetBIOS packet? */
-
static const value_string ipx_packet_type_vals[] = {
{ IPX_PACKET_TYPE_IPX, "IPX" },
{ IPX_PACKET_TYPE_RIP, "RIP" },
{ 0, NULL }
};
+static const value_string ipxmsg_sigchar_vals[] = {
+ { '?', "Poll inactive station" },
+ { 0, NULL }
+};
+
gchar*
ipxnet_to_string(const guint8 *ad)
{
}
void
-capture_ipx(const u_char *pd, int offset, guint32 cap_len, packet_counts *ld)
+capture_ipx(const u_char *pd, int offset, packet_counts *ld)
{
ld->ipx++;
}
guint8 *ipx_snode, *ipx_dnode, *ipx_snet, *ipx_dnet;
guint16 ipx_dsocket, ipx_ssocket;
- dissect_func_t *dissect;
guint32 ipx_dnet_val, ipx_snet_val;
/* Calculate here for use in pinfo and in tree */
ipx_checksum = pntohs(&pd[offset]);
ipx_hops = pd[offset+4];
- ti = proto_tree_add_item(tree, proto_ipx, offset, 30, NULL);
+ ti = proto_tree_add_item(tree, proto_ipx, NullTVB, offset, 30, NULL);
ipx_tree = proto_item_add_subtree(ti, ett_ipx);
- proto_tree_add_item(ipx_tree, hf_ipx_checksum, offset, 2, ipx_checksum);
- proto_tree_add_item_format(ipx_tree, hf_ipx_len, offset+2, 2, ipx_length,
+ proto_tree_add_item(ipx_tree, hf_ipx_checksum, NullTVB, offset, 2, ipx_checksum);
+ proto_tree_add_uint_format(ipx_tree, hf_ipx_len, NullTVB, offset+2, 2, ipx_length,
"Length: %d bytes", ipx_length);
- proto_tree_add_item_format(ipx_tree, hf_ipx_hops, offset+4, 1, ipx_hops,
+ proto_tree_add_uint_format(ipx_tree, hf_ipx_hops, NullTVB, offset+4, 1, ipx_hops,
"Transport Control: %d hops", ipx_hops);
- proto_tree_add_item(ipx_tree, hf_ipx_packet_type, offset+5, 1, ipx_type);
- proto_tree_add_item(ipx_tree, hf_ipx_dnet, offset+6, 4, ipx_dnet_val);
- proto_tree_add_item(ipx_tree, hf_ipx_dnode, offset+10, 6, ipx_dnode);
- proto_tree_add_item_format(ipx_tree, hf_ipx_dsocket, offset+16, 2,
+ proto_tree_add_item(ipx_tree, hf_ipx_packet_type, NullTVB, offset+5, 1, ipx_type);
+ proto_tree_add_item(ipx_tree, hf_ipx_dnet, NullTVB, offset+6, 4, ipx_dnet_val);
+ proto_tree_add_item(ipx_tree, hf_ipx_dnode, NullTVB, offset+10, 6, ipx_dnode);
+ proto_tree_add_uint_format(ipx_tree, hf_ipx_dsocket, NullTVB, offset+16, 2,
ipx_dsocket, "Destination Socket: %s (0x%04X)",
port_text(ipx_dsocket), ipx_dsocket);
- proto_tree_add_item(ipx_tree, hf_ipx_snet, offset+18, 4, ipx_snet_val);
- proto_tree_add_item(ipx_tree, hf_ipx_snode, offset+22, 6, ipx_snode);
- proto_tree_add_item_format(ipx_tree, hf_ipx_ssocket, offset+28, 2,
+ proto_tree_add_item(ipx_tree, hf_ipx_snet, NullTVB, offset+18, 4, ipx_snet_val);
+ proto_tree_add_item(ipx_tree, hf_ipx_snode, NullTVB, offset+22, 6, ipx_snode);
+ proto_tree_add_uint_format(ipx_tree, hf_ipx_ssocket, NullTVB, offset+28, 2,
ipx_ssocket, "Source Socket: %s (0x%04X)", port_text(ipx_ssocket),
ipx_ssocket);
}
offset += 30;
+ if (dissector_try_port(ipx_type_dissector_table, ipx_type, pd,
+ offset, fd, tree))
+ return;
switch (ipx_type) {
- case IPX_PACKET_TYPE_SPX:
- dissect_spx(pd, offset, fd, tree);
- break;
-
- case IPX_PACKET_TYPE_NCP:
- /* Is the destination node 00:00:00:00:00:01 ? */
- if (pntohl(ipx_dnode) == 0 && pntohs(ipx_dnode + 4) == 1)
- nw_server_address = pntohl(ipx_dnet);
-
- /* Is the source node 00:00:00:00:00:01 ? */
- else if (pntohl(ipx_snode) == 0 && pntohs(ipx_snode + 4) == 1)
- nw_server_address = pntohl(ipx_snet);
- else
- nw_server_address = 0;
-
- dissect_ncp(pd, offset, fd, tree);
- break;
-
case IPX_PACKET_TYPE_WANBCAST:
case IPX_PACKET_TYPE_PEP:
if (ipx_dsocket == IPX_SOCKET_NETBIOS) {
dissect_nbipx(pd, offset, fd, tree);
- break;
+ return;
}
/* else fall through */
case 0: /* IPX, fall through to default */
/* XXX - should type 0's be dissected as NBIPX
if they're aimed at the NetBIOS socket? */
- default:
- dissect = port_func(ipx_dsocket);
- if (dissect) {
- dissect(pd, offset, fd, tree);
- }
- else {
- dissect = port_func(ipx_ssocket);
- if (dissect) {
- dissect(pd, offset, fd, tree);
- }
- else {
- dissect_data(pd, offset, fd, tree);
- }
- }
break;
}
+ if (dissector_try_port(ipx_socket_dissector_table, ipx_dsocket, pd,
+ offset, fd, tree))
+ return;
+ if (dissector_try_port(ipx_socket_dissector_table, ipx_ssocket, pd,
+ offset, fd, tree))
+ return;
+ dissect_data(pd, offset, fd, tree);
}
col_add_str(fd, COL_INFO, "SPX");
if (tree) {
- ti = proto_tree_add_item(tree, proto_spx, offset, 12, NULL);
+ ti = proto_tree_add_item(tree, proto_spx, NullTVB, offset, 12, NULL);
spx_tree = proto_item_add_subtree(ti, ett_spx);
- proto_tree_add_item_format(spx_tree, hf_spx_connection_control,
+ proto_tree_add_uint_format(spx_tree, hf_spx_connection_control, NullTVB,
offset, 1,
pd[offset],
"Connection Control: %s (0x%02X)",
spx_conn_ctrl(pd[offset]),
pd[offset]);
- proto_tree_add_item_format(spx_tree, hf_spx_datastream_type,
+ proto_tree_add_uint_format(spx_tree, hf_spx_datastream_type, NullTVB,
offset+1, 1,
pd[offset+1],
"Datastream Type: %s (0x%02X)",
spx_datastream(pd[offset+1]),
pd[offset+1]);
- proto_tree_add_item(spx_tree, hf_spx_src_id,
+ proto_tree_add_item(spx_tree, hf_spx_src_id, NullTVB,
offset+2, 2,
pntohs( &pd[offset+2] ));
- proto_tree_add_item(spx_tree, hf_spx_dst_id,
+ proto_tree_add_item(spx_tree, hf_spx_dst_id, NullTVB,
offset+4, 2,
pntohs( &pd[offset+4] ));
- proto_tree_add_item(spx_tree, hf_spx_seq_nr,
+ proto_tree_add_item(spx_tree, hf_spx_seq_nr, NullTVB,
offset+6, 2,
pntohs( &pd[offset+6] ) );
- proto_tree_add_item(spx_tree, hf_spx_ack_nr,
+ proto_tree_add_item(spx_tree, hf_spx_ack_nr, NullTVB,
offset+8, 2,
pntohs( &pd[offset+8] ) );
- proto_tree_add_item(spx_tree, hf_spx_all_nr,
+ proto_tree_add_item(spx_tree, hf_spx_all_nr, NullTVB,
offset+10, 2,
pntohs( &pd[offset+10] ) );
}
}
+/* ================================================================= */
+/* 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, NullTVB, offset, END_OF_FRAME, NULL);
+ msg_tree = proto_item_add_subtree(ti, ett_ipxmsg);
+
+ proto_tree_add_item(msg_tree, hf_msg_conn, NullTVB, offset, 1, conn_number);
+ proto_tree_add_item(msg_tree, hf_msg_sigchar, NullTVB, offset+1, 1, sig_char);
+ }
+}
+
+
/* ================================================================= */
/* IPX RIP */
/* ================================================================= */
}
if (tree) {
- ti = proto_tree_add_item(tree, proto_ipxrip, offset, END_OF_FRAME, NULL);
+ ti = proto_tree_add_item(tree, proto_ipxrip, NullTVB, offset, END_OF_FRAME, NULL);
rip_tree = proto_item_add_subtree(ti, ett_ipxrip);
if (operation < 2) {
- proto_tree_add_text(rip_tree, offset, 2,
+ proto_tree_add_text(rip_tree, NullTVB, offset, 2,
"RIP packet type: %s", rip_type[operation]);
if (operation == 0) {
proto_tree_add_item_hidden(rip_tree,
hf_ipxrip_request,
- offset, 2, 1);
+ NullTVB, offset, 2, 1);
} else {
proto_tree_add_item_hidden(rip_tree,
hf_ipxrip_response,
- offset, 2, 1);
+ NullTVB, offset, 2, 1);
}
}
else {
- proto_tree_add_text(rip_tree, offset, 2, "Unknown RIP packet type");
+ proto_tree_add_text(rip_tree, NullTVB, offset, 2, "Unknown RIP packet type");
}
- for (cursor = offset + 2; cursor < fd->cap_len; cursor += 8) {
+ for (cursor = offset + 2; cursor < pi.captured_len; cursor += 8) {
memcpy(&route.network, &pd[cursor], 4);
route.hops = pntohs(&pd[cursor+4]);
route.ticks = pntohs(&pd[cursor+6]);
if (operation == IPX_RIP_REQUEST - 1) {
- proto_tree_add_text(rip_tree, cursor, 8,
+ proto_tree_add_text(rip_tree, NullTVB, cursor, 8,
"Route Vector: %s, %d hop%s, %d tick%s",
ipxnet_to_string((guint8*)&route.network),
route.hops, route.hops == 1 ? "" : "s",
route.ticks, route.ticks == 1 ? "" : "s");
}
else {
- proto_tree_add_text(rip_tree, cursor, 8,
+ proto_tree_add_text(rip_tree, NullTVB, cursor, 8,
"Route Vector: %s, %d hop%s, %d tick%s (%d ms)",
ipxnet_to_string((guint8*)&route.network),
route.hops, route.hops == 1 ? "" : "s",
/* ================================================================= */
-/* SAP */
+/* SAP */
/* ================================================================= */
static char*
server_type(guint16 type)
}
if (tree) {
- ti = proto_tree_add_item(tree, proto_sap, offset, END_OF_FRAME, NULL);
+ ti = proto_tree_add_item(tree, proto_sap, NullTVB, offset, END_OF_FRAME, NULL);
sap_tree = proto_item_add_subtree(ti, ett_ipxsap);
if (query.query_type >= 1 && query.query_type <= 4) {
- proto_tree_add_text(sap_tree, offset, 2, sap_type[query.query_type - 1]);
+ proto_tree_add_text(sap_tree, NullTVB, offset, 2, sap_type[query.query_type - 1]);
if ((query.query_type - 1) % 2) {
proto_tree_add_item_hidden(sap_tree,
hf_sap_response,
- offset, 2, 1);
+ NullTVB, offset, 2, 1);
} else {
proto_tree_add_item_hidden(sap_tree,
hf_sap_request,
- offset, 2, 1);
+ NullTVB, offset, 2, 1);
}
}
else {
- proto_tree_add_text(sap_tree, offset, 2,
+ proto_tree_add_text(sap_tree, NullTVB, offset, 2,
"Unknown SAP Packet Type %d", query.query_type);
}
if (query.query_type == IPX_SAP_GENERAL_RESPONSE ||
query.query_type == IPX_SAP_NEAREST_RESPONSE) { /* responses */
- for (cursor = offset + 2; (cursor + 64) <= fd->cap_len; cursor += 64) {
+ for (cursor = offset + 2; (cursor + 64) <= pi.captured_len; cursor += 64) {
server.server_type = pntohs(&pd[cursor]);
memcpy(server.server_name, &pd[cursor+2], 48);
memcpy(&server.server_network, &pd[cursor+50], 4);
server.server_port = pntohs(&pd[cursor+60]);
server.intermediate_network = pntohs(&pd[cursor+62]);
- ti = proto_tree_add_text(sap_tree, cursor+2, 48,
+ ti = proto_tree_add_text(sap_tree, NullTVB, cursor+2, 48,
"Server Name: %s", server.server_name);
s_tree = proto_item_add_subtree(ti, ett_ipxsap_server);
- proto_tree_add_text(s_tree, cursor, 2, "Server Type: %s (0x%04X)",
+ proto_tree_add_text(s_tree, NullTVB, cursor, 2, "Server Type: %s (0x%04X)",
server_type(server.server_type), server.server_type);
- proto_tree_add_text(s_tree, cursor+50, 4, "Network: %s",
+ proto_tree_add_text(s_tree, NullTVB, cursor+50, 4, "Network: %s",
ipxnet_to_string((guint8*)&pd[cursor+50]));
- proto_tree_add_text(s_tree, cursor+54, 6, "Node: %s",
+ proto_tree_add_text(s_tree, NullTVB, cursor+54, 6, "Node: %s",
ether_to_str((guint8*)&pd[cursor+54]));
- proto_tree_add_text(s_tree, cursor+60, 2, "Socket: %s (0x%04X)",
+ proto_tree_add_text(s_tree, NullTVB, cursor+60, 2, "Socket: %s (0x%04X)",
port_text(server.server_port), server.server_port);
- proto_tree_add_text(s_tree, cursor+62, 2,
+ proto_tree_add_text(s_tree, NullTVB, cursor+62, 2,
"Intermediate Networks: %d",
server.intermediate_network);
}
}
else { /* queries */
- proto_tree_add_text(sap_tree, offset+2, 2, "Server Type: %s (0x%04X)",
+ proto_tree_add_text(sap_tree, NullTVB, offset+2, 2, "Server Type: %s (0x%04X)",
server_type(query.server_type), query.server_type);
}
}
}
-
void
proto_register_ipx(void)
{
static hf_register_info hf_sap[] = {
{ &hf_sap_request,
- { "Request", "sap.request",
+ { "Request", "ipxsap.request",
FT_BOOLEAN, BASE_NONE, NULL, 0x0,
"TRUE if SAP request" }},
{ &hf_sap_response,
- { "Response", "sap.response",
+ { "Response", "ipxsap.response",
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,
proto_ipxrip = proto_register_protocol ("IPX Routing Information Protocol", "ipxrip");
proto_register_field_array(proto_ipxrip, hf_ipxrip, array_length(hf_ipxrip));
- proto_sap = proto_register_protocol ("Service Advertisement Protocol", "sap");
+ 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", "ipxsap");
proto_register_field_array(proto_sap, hf_sap, array_length(hf_sap));
proto_register_subtree_array(ett, array_length(ett));
+
+ ipx_type_dissector_table = register_dissector_table("ipx.packet_type");
+ ipx_socket_dissector_table = register_dissector_table("ipx.socket");
+}
+
+void
+proto_reg_handoff_ipx(void)
+{
+ dissector_add("udp.port", UDP_PORT_IPX, dissect_ipx);
+ dissector_add("ethertype", ETHERTYPE_IPX, dissect_ipx);
+ dissector_add("ppp.protocol", PPP_IPX, dissect_ipx);
+ dissector_add("llc.dsap", SAP_NETWARE, dissect_ipx);
+ dissector_add("ipx.packet_type", IPX_PACKET_TYPE_SPX, dissect_spx);
+ dissector_add("ipx.socket", IPX_SOCKET_SAP, dissect_ipxsap);
+ dissector_add("ipx.socket", IPX_SOCKET_IPXRIP, dissect_ipxrip);
+ dissector_add("ipx.socket", IPX_SOCKET_IPX_MESSAGE, dissect_ipxmsg);
}