2 * Routines for NetWare's IPX
3 * Gilbert Ramirez <gram@alumni.rice.edu>
5 * $Id: packet-ipx.c,v 1.116 2002/10/19 01:17:13 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include <epan/packet.h>
34 #include "packet-ipx.h"
35 #include <epan/resolv.h>
40 #include "arcnet_pids.h"
42 /* The information in this module (IPX, SPX, NCP) comes from:
43 NetWare LAN Analysis, Second Edition
44 Laura A. Chappell and Dan E. Hakes
46 Novell Press, San Jose.
49 And from the ncpfs source code by Volker Lendecke
53 static int proto_ipx = -1;
54 static int hf_ipx_checksum = -1;
55 static int hf_ipx_len = -1;
56 static int hf_ipx_hops = -1;
57 static int hf_ipx_packet_type = -1;
58 static int hf_ipx_dnet = -1;
59 static int hf_ipx_dnode = -1;
60 static int hf_ipx_dsocket = -1;
61 static int hf_ipx_snet = -1;
62 static int hf_ipx_snode = -1;
63 static int hf_ipx_ssocket = -1;
65 static gint ett_ipx = -1;
67 static dissector_table_t ipx_type_dissector_table;
68 static dissector_table_t ipx_socket_dissector_table;
69 static dissector_table_t spx_socket_dissector_table;
71 static int proto_spx = -1;
72 static int hf_spx_connection_control = -1;
73 static int hf_spx_datastream_type = -1;
74 static int hf_spx_src_id = -1;
75 static int hf_spx_dst_id = -1;
76 static int hf_spx_seq_nr = -1;
77 static int hf_spx_ack_nr = -1;
78 static int hf_spx_all_nr = -1;
80 static gint ett_spx = -1;
82 static int proto_ipxrip = -1;
83 static int hf_ipxrip_request = -1;
84 static int hf_ipxrip_response = -1;
86 static gint ett_ipxrip = -1;
88 static int proto_sap = -1;
89 static int hf_sap_request = -1;
90 static int hf_sap_response = -1;
92 static gint ett_ipxsap = -1;
93 static gint ett_ipxsap_server = -1;
95 static gint ett_ipxmsg = -1;
96 static int proto_ipxmsg = -1;
97 static int hf_msg_conn = -1;
98 static int hf_msg_sigchar = -1;
100 static dissector_handle_t data_handle;
103 dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
106 dissect_ipxrip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
109 dissect_ipxsap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
112 dissect_ipxmsg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
114 #define UDP_PORT_IPX 213 /* RFC 1234 */
116 #define IPX_HEADER_LEN 30 /* It's *always* 30 bytes */
118 /* ================================================================= */
120 /* ================================================================= */
121 static const value_string ipx_socket_vals[] = {
122 { IPX_SOCKET_PING_CISCO, "CISCO PING" },
123 { IPX_SOCKET_NCP, "NCP" },
124 { IPX_SOCKET_SAP, "SAP" },
125 { IPX_SOCKET_IPXRIP, "RIP" },
126 { IPX_SOCKET_NETBIOS, "NetBIOS" },
127 { IPX_SOCKET_DIAGNOSTIC, "Diagnostic" },
128 { IPX_SOCKET_SERIALIZATION, "Serialization" },
129 { IPX_SOCKET_NWLINK_SMB_SERVER, "NWLink SMB Server" },
130 { IPX_SOCKET_NWLINK_SMB_NAMEQUERY, "NWLink SMB Name Query" },
131 { IPX_SOCKET_NWLINK_SMB_REDIR, "NWLink SMB Redirector" },
132 { IPX_SOCKET_NWLINK_SMB_MAILSLOT, "NWLink SMB Mailslot Datagram" },
133 { IPX_SOCKET_NWLINK_SMB_MESSENGER, "NWLink SMB Messenger" },
134 { IPX_SOCKET_NWLINK_SMB_BROWSE, "NWLink SMB Browse" },
135 { IPX_SOCKET_ATTACHMATE_GW, "Attachmate Gateway" },
136 { IPX_SOCKET_IPX_MESSAGE, "IPX Message" },
137 { IPX_SOCKET_IPX_MESSAGE1, "IPX Message" },
138 { IPX_SOCKET_SNMP_AGENT, "SNMP Agent" },
139 { IPX_SOCKET_SNMP_SINK, "SNMP Sink" },
140 { IPX_SOCKET_PING_NOVELL, "Novell PING" },
141 { IPX_SOCKET_UDP_TUNNEL, "UDP Tunnel" },
142 { IPX_SOCKET_TCP_TUNNEL, "TCP Tunnel" },
143 { IPX_SOCKET_TCP_TUNNEL, "TCP Tunnel" },
144 { IPX_SOCKET_ADSM, "ADSM" },
145 { IPX_SOCKET_EIGRP, "Cisco EIGRP for IPX" },
146 { IPX_SOCKET_WIDE_AREA_ROUTER, "Wide Area Router" },
147 { SPX_SOCKET_PA, "NDPS Printer Agent/PSM" },
148 { SPX_SOCKET_BROKER, "NDPS Broker" },
149 { SPX_SOCKET_SRS, "NDPS Service Registry Service" },
150 { SPX_SOCKET_ENS, "NDPS Event Notification Service" },
151 { SPX_SOCKET_RMS, "NDPS Remote Management Service" },
152 { SPX_SOCKET_NOTIFY_LISTENER, "NDPS Notify Listener" },
153 { 0xE885, "NT Server-RPC/GW" },
154 { 0x400C, "HP LaserJet/QuickSilver" },
155 { 0x907B, "SMS Testing and Development" },
156 { 0x8F83, "Powerchute UPS Monitoring" },
157 { 0x4006, "NetWare Directory Server" },
158 { 0x8104, "NetWare 386" },
163 socket_text(guint16 socket)
165 return val_to_str(socket, ipx_socket_vals, "Unknown");
168 static const value_string ipx_packet_type_vals[] = {
169 { IPX_PACKET_TYPE_IPX, "IPX" },
170 { IPX_PACKET_TYPE_RIP, "RIP" },
171 { IPX_PACKET_TYPE_ECHO, "Echo" },
172 { IPX_PACKET_TYPE_ERROR, "Error" },
173 { IPX_PACKET_TYPE_PEP, "PEP" }, /* Packet Exchange Packet */
174 { IPX_PACKET_TYPE_SPX, "SPX" },
175 { 16, "Experimental Protocol" },
176 { IPX_PACKET_TYPE_NCP, "NCP" },
177 { 18, "Experimental Protocol" },
178 { 19, "Experimental Protocol" },
179 { IPX_PACKET_TYPE_WANBCAST, "NetBIOS Broadcast" },
180 { 21, "Experimental Protocol" },
181 { 22, "Experimental Protocol" },
182 { 23, "Experimental Protocol" },
183 { 24, "Experimental Protocol" },
184 { 25, "Experimental Protocol" },
185 { 26, "Experimental Protocol" },
186 { 27, "Experimental Protocol" },
187 { 28, "Experimental Protocol" },
188 { 29, "Experimental Protocol" },
189 { 30, "Experimental Protocol" },
190 { 31, "Experimental Protocol" },
194 static const value_string ipxmsg_sigchar_vals[] = {
195 { '?', "Poll inactive station" },
196 { 'Y', "Station is still using the connection" },
197 { '!', "Broadcast message waiting" },
203 capture_ipx(packet_counts *ld)
209 dissect_ipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
213 proto_tree *ipx_tree;
216 const guint8 *src_net_node, *dst_net_node;
218 guint8 ipx_type, ipx_hops;
221 guint16 ipx_dsocket, ipx_ssocket;
222 guint16 low_socket, high_socket;
224 if (check_col(pinfo->cinfo, COL_PROTOCOL))
225 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX");
226 if (check_col(pinfo->cinfo, COL_INFO))
227 col_clear(pinfo->cinfo, COL_INFO);
229 /* Calculate here for use in pinfo and in tree */
230 ipx_dsocket = tvb_get_ntohs(tvb, 16);
231 ipx_ssocket = tvb_get_ntohs(tvb, 28);
232 ipx_type = tvb_get_guint8(tvb, 5);
233 ipx_length = tvb_get_ntohs(tvb, 2);
235 pinfo->ptype = PT_IPX;
236 pinfo->srcport = ipx_ssocket;
237 pinfo->destport = ipx_dsocket;
239 /* Adjust the tvbuff length to include only the IPX datagram. */
240 set_actual_length(tvb, ipx_length);
242 src_net_node = tvb_get_ptr(tvb, 18, 10);
243 dst_net_node = tvb_get_ptr(tvb, 6, 10);
245 SET_ADDRESS(&pinfo->net_src, AT_IPX, 10, src_net_node);
246 SET_ADDRESS(&pinfo->src, AT_IPX, 10, src_net_node);
247 SET_ADDRESS(&pinfo->net_dst, AT_IPX, 10, dst_net_node);
248 SET_ADDRESS(&pinfo->dst, AT_IPX, 10, dst_net_node);
250 if (check_col(pinfo->cinfo, COL_INFO))
251 col_add_fstr(pinfo->cinfo, COL_INFO, "%s (0x%04x)",
252 socket_text(ipx_dsocket), ipx_dsocket);
256 ti = proto_tree_add_item(tree, proto_ipx, tvb, 0, IPX_HEADER_LEN, FALSE);
257 ipx_tree = proto_item_add_subtree(ti, ett_ipx);
259 proto_tree_add_item(ipx_tree, hf_ipx_checksum, tvb, 0, 2, FALSE);
260 proto_tree_add_uint_format(ipx_tree, hf_ipx_len, tvb, 2, 2, ipx_length,
261 "Length: %d bytes", ipx_length);
262 ipx_hops = tvb_get_guint8(tvb, 4);
263 proto_tree_add_uint_format(ipx_tree, hf_ipx_hops, tvb, 4, 1, ipx_hops,
264 "Transport Control: %d hops", ipx_hops);
265 proto_tree_add_uint(ipx_tree, hf_ipx_packet_type, tvb, 5, 1, ipx_type);
268 proto_tree_add_item(ipx_tree, hf_ipx_dnet, tvb, 6, 4, FALSE);
269 proto_tree_add_item(ipx_tree, hf_ipx_dnode, tvb, 10, 6, FALSE);
270 proto_tree_add_uint(ipx_tree, hf_ipx_dsocket, tvb, 16, 2,
274 proto_tree_add_item(ipx_tree, hf_ipx_snet, tvb, 18, 4, FALSE);
275 proto_tree_add_item(ipx_tree, hf_ipx_snode, tvb, 22, 6, FALSE);
276 proto_tree_add_uint(ipx_tree, hf_ipx_ssocket, tvb, 28, 2,
280 /* Make the next tvbuff */
281 next_tvb = tvb_new_subset(tvb, IPX_HEADER_LEN, -1, -1);
284 * Let the subdissector know what type of IPX packet this is.
286 pinfo->ipxptype = ipx_type;
289 * Check the socket numbers before we check the packet type;
290 * we've seen non-NCP packets with a type of NCP and a
291 * destination socket of IPX_SOCKET_IPX_MESSAGE, and SAP
292 * packets with a type of NCP and a destination socket of
295 * Assume the lower-numbered socket number is more likely
296 * to be the right one, along the lines of what we do for
297 * TCP and UDP. We've seen NCP packets with a type of NCP,
298 * a source socket of IPX_SOCKET_NCP, and a destination
299 * socket of IPX_SOCKET_IPX_MESSAGE, and we've seen NCP
300 * packets with a type of NCP, a source socket of
301 * IPX_SOCKET_IPX_MESSAGE, and a destination socket of
304 if (ipx_ssocket > ipx_dsocket) {
305 low_socket = ipx_dsocket;
306 high_socket = ipx_ssocket;
308 low_socket = ipx_ssocket;
309 high_socket = ipx_dsocket;
311 if (dissector_try_port(ipx_socket_dissector_table, low_socket,
312 next_tvb, pinfo, tree))
314 if (dissector_try_port(ipx_socket_dissector_table, high_socket,
315 next_tvb, pinfo, tree))
319 * Neither of them are known; try the packet type, which will
320 * at least let us, for example, dissect SPX packets as SPX.
322 if (dissector_try_port(ipx_type_dissector_table, ipx_type, next_tvb,
326 call_dissector(data_handle,next_tvb, pinfo, tree);
330 /* ================================================================= */
332 /* ================================================================= */
334 spx_conn_ctrl(guint8 ctrl)
338 static const value_string conn_vals[] = {
339 { 0x10, "End-of-Message" },
340 { 0x20, "Attention" },
341 { 0x40, "Acknowledgment Required"},
342 { 0x50, "Send Ack: End Message"},
343 { 0x80, "System Packet"},
344 { 0xc0, "System Packet: Send Ack"},
348 p = match_strval((ctrl & 0xf0), conn_vals );
359 spx_datastream(guint8 type)
363 return "End-of-Connection";
365 return "End-of-Connection Acknowledgment";
367 return "Client-Defined";
371 #define SPX_HEADER_LEN 12
374 dissect_spx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
376 proto_tree *spx_tree = NULL;
381 guint8 datastream_type;
382 const char *spx_msg_string;
383 guint16 low_socket, high_socket;
385 if (check_col(pinfo->cinfo, COL_PROTOCOL))
386 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SPX");
387 if (check_col(pinfo->cinfo, COL_INFO))
388 col_set_str(pinfo->cinfo, COL_INFO, "SPX");
391 ti = proto_tree_add_item(tree, proto_spx, tvb, 0, SPX_HEADER_LEN, FALSE);
392 spx_tree = proto_item_add_subtree(ti, ett_spx);
395 conn_ctrl = tvb_get_guint8(tvb, 0);
396 spx_msg_string = spx_conn_ctrl(conn_ctrl);
397 if (check_col(pinfo->cinfo, COL_INFO))
398 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", spx_msg_string);
400 proto_tree_add_uint_format(spx_tree, hf_spx_connection_control, tvb,
402 "Connection Control: %s (0x%02X)",
403 spx_msg_string, conn_ctrl);
405 datastream_type = tvb_get_guint8(tvb, 1);
406 proto_tree_add_uint_format(spx_tree, hf_spx_datastream_type, tvb,
407 1, 1, datastream_type,
408 "Datastream Type: %s (0x%02X)",
409 spx_datastream(datastream_type), datastream_type);
411 proto_tree_add_item(spx_tree, hf_spx_src_id, tvb, 2, 2, FALSE);
412 proto_tree_add_item(spx_tree, hf_spx_dst_id, tvb, 4, 2, FALSE);
413 proto_tree_add_item(spx_tree, hf_spx_seq_nr, tvb, 6, 2, FALSE);
414 proto_tree_add_item(spx_tree, hf_spx_ack_nr, tvb, 8, 2, FALSE);
415 proto_tree_add_item(spx_tree, hf_spx_all_nr, tvb, 10, 2, FALSE);
418 if (tvb_reported_length_remaining(tvb, SPX_HEADER_LEN) > 0) {
420 * Call subdissectors based on the IPX socket numbers; a
421 * subdissector might have registered with our IPX socket
422 * dissector table rather than the IPX dissector's socket
425 * Assume the lower-numbered socket number is more likely
426 * to be the right one, along the lines of what we do for
427 * TCP and UDP. We've seen NCP packets with a type of NCP,
428 * a source socket of IPX_SOCKET_NCP, and a destination
429 * socket of IPX_SOCKET_IPX_MESSAGE, and we've seen NCP
430 * packets with a type of NCP, a source socket of
431 * IPX_SOCKET_IPX_MESSAGE, and a destination socket of
434 if (pinfo->srcport > pinfo->destport) {
435 low_socket = pinfo->destport;
436 high_socket = pinfo->srcport;
438 low_socket = pinfo->srcport;
439 high_socket = pinfo->destport;
442 next_tvb = tvb_new_subset(tvb, SPX_HEADER_LEN, -1, -1);
443 if (dissector_try_port(spx_socket_dissector_table, low_socket,
444 next_tvb, pinfo, tree))
446 if (dissector_try_port(spx_socket_dissector_table, high_socket,
447 next_tvb, pinfo, tree))
449 call_dissector(data_handle, next_tvb, pinfo, tree);
453 /* ================================================================= */
455 /* ================================================================= */
457 dissect_ipxmsg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
459 proto_tree *msg_tree;
461 guint8 conn_number, sig_char;
463 if (check_col(pinfo->cinfo, COL_PROTOCOL))
464 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX MSG");
465 if (check_col(pinfo->cinfo, COL_INFO))
466 col_clear(pinfo->cinfo, COL_INFO);
468 conn_number = tvb_get_guint8(tvb, 0);
469 sig_char = tvb_get_guint8(tvb, 1);
471 if (check_col(pinfo->cinfo, COL_INFO)) {
472 col_add_fstr(pinfo->cinfo, COL_INFO,
474 val_to_str(sig_char, ipxmsg_sigchar_vals, "Unknown Signature Char"), conn_number);
478 ti = proto_tree_add_item(tree, proto_ipxmsg, tvb, 0, -1, FALSE);
479 msg_tree = proto_item_add_subtree(ti, ett_ipxmsg);
481 proto_tree_add_uint(msg_tree, hf_msg_conn, tvb, 0, 1, conn_number);
482 proto_tree_add_uint(msg_tree, hf_msg_sigchar, tvb, 1, 1, sig_char);
487 /* ================================================================= */
489 /* ================================================================= */
491 dissect_ipxrip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
493 proto_tree *rip_tree;
496 struct ipx_rt_def route;
498 int available_length;
500 static char *rip_type[3] = { "Request", "Response", "Unknown" };
502 if (check_col(pinfo->cinfo, COL_PROTOCOL))
503 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX RIP");
504 if (check_col(pinfo->cinfo, COL_INFO))
505 col_clear(pinfo->cinfo, COL_INFO);
507 operation = tvb_get_ntohs(tvb, 0) - 1;
509 if (check_col(pinfo->cinfo, COL_INFO)) {
510 /* rip_types 0 and 1 are valid, anything else becomes 2 or "Unknown" */
511 col_set_str(pinfo->cinfo, COL_INFO, rip_type[MIN(operation, 2)]);
515 ti = proto_tree_add_item(tree, proto_ipxrip, tvb, 0, -1, FALSE);
516 rip_tree = proto_item_add_subtree(ti, ett_ipxrip);
519 proto_tree_add_text(rip_tree, tvb, 0, 2,
520 "RIP packet type: %s", rip_type[operation]);
522 if (operation == 0) {
523 proto_tree_add_boolean_hidden(rip_tree,
527 proto_tree_add_boolean_hidden(rip_tree,
534 proto_tree_add_text(rip_tree, tvb, 0, 2, "Unknown RIP packet type");
537 available_length = tvb_reported_length(tvb);
538 for (cursor = 2; cursor < available_length; cursor += 8) {
539 tvb_memcpy(tvb, (guint8 *)&route.network, cursor, 4);
540 route.hops = tvb_get_ntohs(tvb, cursor+4);
541 route.ticks = tvb_get_ntohs(tvb, cursor+6);
543 if (operation == IPX_RIP_REQUEST - 1) {
544 proto_tree_add_text(rip_tree, tvb, cursor, 8,
545 "Route Vector: %s, %d hop%s, %d tick%s",
546 ipxnet_to_string((guint8*)&route.network),
547 route.hops, route.hops == 1 ? "" : "s",
548 route.ticks, route.ticks == 1 ? "" : "s");
551 proto_tree_add_text(rip_tree, tvb, cursor, 8,
552 "Route Vector: %s, %d hop%s, %d tick%s (%d ms)",
553 ipxnet_to_string((guint8*)&route.network),
554 route.hops, route.hops == 1 ? "" : "s",
555 route.ticks, route.ticks == 1 ? "" : "s",
556 route.ticks * 1000 / 18);
564 /* ================================================================= */
566 /* ================================================================= */
568 server_type(guint16 type)
573 * Some of these are from ncpfs, others are from the book,
574 * others are from the page at
576 * http://www.iana.org/assignments/novell-sap-numbers
578 * and some from the page at
580 * http://www.rware.demon.co.uk/ipxsap.htm
582 * (see also the page at
584 * http://developer.novell.com/research/appnotes/1998/february/03/06.htm
586 * which has a huge list - but many of the entries list only the
587 * organization owning the SAP type, not what the type is for).
589 static const value_string server_vals[] = {
590 { 0x0000, "Unknown" },
592 { 0x0002, "User Group" },
593 { 0x0003, "Print Queue or Print Group" },
594 { 0x0004, "File Server (SLIST source)" },
595 { 0x0005, "Job Server" },
596 { 0x0006, "Gateway" },
597 { 0x0007, "Print Server or Silent Print Server" },
598 { 0x0008, "Archive Queue" },
599 { 0x0009, "Archive Server" },
600 { 0x000a, "Job Queue" },
601 { 0x000b, "Administration" },
602 { 0x000F, "Novell TI-RPC" },
603 { 0x0017, "Diagnostics" },
604 { 0x0020, "NetBIOS" },
605 { 0x0021, "NAS SNA Gateway" },
606 { 0x0023, "NACS Async Gateway or Asynchronous Gateway" },
607 { 0x0024, "Remote Bridge or Routing Service" },
608 { 0x0026, "Bridge Server or Asynchronous Bridge Server" },
609 { 0x0027, "TCP/IP Gateway Server" },
610 { 0x0028, "Point to Point (Eicon) X.25 Bridge Server" },
611 { 0x0029, "Eicon 3270 Gateway" },
612 { 0x002a, "CHI Corp" },
613 { 0x002c, "PC Chalkboard" },
614 { 0x002d, "Time Synchronization Server or Asynchronous Timer" },
615 { 0x002e, "ARCserve 5.0 / Palindrome Backup Director 4.x (PDB4)" },
616 { 0x0045, "DI3270 Gateway" },
617 { 0x0047, "Advertising Print Server" },
618 { 0x004a, "NetBlazer Modems" },
619 { 0x004b, "Btrieve VAP/NLM 5.0" },
620 { 0x004c, "NetWare SQL VAP/NLM Server" },
621 { 0x004d, "Xtree Network Version/NetWare XTree" },
622 { 0x0050, "Btrieve VAP 4.11" },
623 { 0x0052, "QuickLink (Cubix)" },
624 { 0x0053, "Print Queue User" },
625 { 0x0058, "Multipoint X.25 Eicon Router" },
626 { 0x0060, "STLB/NLM" },
627 { 0x0064, "ARCserve" },
628 { 0x0066, "ARCserve 3.0" },
629 { 0x0072, "WAN Copy Utility" },
630 { 0x007a, "TES-NetWare for VMS" },
631 { 0x0092, "WATCOM Debugger or Emerald Tape Backup Server" },
632 { 0x0095, "DDA OBGYN" },
633 { 0x0098, "NetWare Access Server (Asynchronous gateway)" },
634 { 0x009a, "NetWare for VMS II or Named Pipe Server" },
635 { 0x009b, "NetWare Access Server" },
636 { 0x009e, "Portable NetWare Server or SunLink NVT" },
637 { 0x00a1, "Powerchute APC UPS NLM" },
638 { 0x00aa, "LAWserve" },
639 { 0x00ac, "Compaq IDA Status Monitor" },
640 { 0x0100, "PIPE STAIL" },
641 { 0x0102, "LAN Protect Bindery" },
642 { 0x0103, "Oracle DataBase Server" },
643 { 0x0107, "NetWare 386 or RSPX Remote Console" },
644 { 0x010f, "Novell SNA Gateway" },
645 { 0x0111, "Test Server" },
646 { 0x0112, "Print Server (HP)" },
647 { 0x0114, "CSA MUX (f/Communications Executive)" },
648 { 0x0115, "CSA LCA (f/Communications Executive)" },
649 { 0x0116, "CSA CM (f/Communications Executive)" },
650 { 0x0117, "CSA SMA (f/Communications Executive)" },
651 { 0x0118, "CSA DBA (f/Communications Executive)" },
652 { 0x0119, "CSA NMA (f/Communications Executive)" },
653 { 0x011a, "CSA SSA (f/Communications Executive)" },
654 { 0x011b, "CSA STATUS (f/Communications Executive)" },
655 { 0x011e, "CSA APPC (f/Communications Executive)" },
656 { 0x0126, "SNA TEST SSA Profile" },
657 { 0x012a, "CSA TRACE (f/Communications Executive)" },
658 { 0x012b, "NetWare for SAA" },
659 { 0x012e, "IKARUS virus scan utility" },
660 { 0x0130, "Communications Executive" },
661 { 0x0133, "NNS Domain Server or NetWare Naming Services Domain" },
662 { 0x0135, "NetWare Naming Services Profile" },
663 { 0x0137, "NetWare 386 Print Queue or NNS Print Queue" },
664 { 0x0141, "LAN Spool Server (Vap, Intel)" },
665 { 0x0152, "IRMALAN Gateway" },
666 { 0x0154, "Named Pipe Server" },
667 { 0x0166, "NetWare Management" },
668 { 0x0168, "Intel PICKIT Comm Server or Intel CAS Talk Server" },
669 { 0x0173, "Compaq" },
670 { 0x0174, "Compaq SNMP Agent" },
671 { 0x0175, "Compaq" },
672 { 0x0180, "XTree Server or XTree Tools" },
673 { 0x018A, "NASI services broadcast server (Novell)" },
674 { 0x01b0, "GARP Gateway (net research)" },
675 { 0x01b1, "Binfview (Lan Support Group)" },
676 { 0x01bf, "Intel LanDesk Manager" },
678 { 0x01cb, "Shiva NetModem/E" },
679 { 0x01cc, "Shiva LanRover/E" },
680 { 0x01cd, "Shiva LanRover/T" },
681 { 0x01ce, "Shiva Universal" },
682 { 0x01d8, "Castelle FAXPress Server" },
683 { 0x01da, "Castelle LANPress Print Server" },
684 { 0x01dc, "Castelle FAX/Xerox 7033 Fax Server/Excel Lan Fax" },
685 { 0x01f0, "LEGATO" },
686 { 0x01f5, "LEGATO" },
687 { 0x0233, "NMS Agent or NetWare Management Agent" },
688 { 0x0237, "NMS IPX Discovery or LANtern Read/Write Channel" },
689 { 0x0238, "NMS IP Discovery or LANtern Trap/Alarm Channel" },
690 { 0x023a, "LANtern" },
691 { 0x023c, "MAVERICK" },
692 { 0x023f, "SMS Testing and Development" },
693 { 0x024e, "NetWare Connect" },
694 { 0x024f, "NASI server broadcast (Cisco)" },
695 { 0x026a, "Network Management (NMS) Service Console" },
696 { 0x026b, "Time Synchronization Server (NetWare 4.x)" },
697 { 0x0278, "Directory Server (NetWare 4.x)" },
698 { 0x027b, "NetWare Management Agent" },
699 { 0x0280, "Novell File and Printer Sharing Service for PC" },
700 { 0x0304, "Novell SAA Gateway" },
701 { 0x0308, "COM or VERMED 1" },
702 { 0x030a, "Galacticomm's Worldgroup Server" },
703 { 0x030c, "Intel Netport 2 or HP JetDirect or HP Quicksilver" },
704 { 0x0320, "Attachmate Gateway" },
705 { 0x0327, "Microsoft Diagnostics" },
706 { 0x0328, "WATCOM SQL server" },
707 { 0x0335, "MultiTech Systems Multisynch Comm Server" },
708 { 0x0343, "Xylogics Remote Access Server or LAN Modem" },
709 { 0x0355, "Arcada Backup Exec" },
710 { 0x0358, "MSLCD1" },
711 { 0x0361, "NETINELO" },
712 { 0x037e, "Powerchute UPS Monitoring" },
713 { 0x037f, "ViruSafe Notify" },
714 { 0x0386, "HP Bridge" },
715 { 0x0387, "HP Hub" },
716 { 0x0394, "NetWare SAA Gateway" },
717 { 0x039b, "Lotus Notes" },
718 { 0x03b7, "Certus Anti Virus NLM" },
719 { 0x03c4, "ARCserve 4.0 (Cheyenne)" },
720 { 0x03c7, "LANspool 3.5 (Intel)" },
721 { 0x03d7, "Lexmark printer server (type 4033-011)" },
722 { 0x03d8, "Lexmark XLE printer server (type 4033-301)" },
723 { 0x03dd, "Banyan ENS for NetWare Client NLM" },
724 { 0x03de, "Gupta Sequel Base Server or NetWare SQL" },
725 { 0x03e1, "Univel Unixware" },
726 { 0x03e4, "Univel Unixware" },
727 { 0x03fc, "Intel Netport" },
728 { 0x03fd, "Intel Print Server Queue" },
729 { 0x040A, "ipnServer" },
730 { 0x040D, "LVERRMAN" },
732 { 0x0414, "NET Silicon (DPI)/Kyocera" },
733 { 0x0429, "Site Lock Virus (Brightworks)" },
734 { 0x0432, "UFHELP R" },
735 { 0x0433, "Synoptics 281x Advanced SNMP Agent" },
736 { 0x0444, "Microsoft NT SNA Server" },
737 { 0x0448, "Oracle" },
738 { 0x044c, "ARCserve 5.01" },
739 { 0x0457, "Canon GP55 Running on a Canon GP55 network printer" },
740 { 0x045a, "QMS Printers" },
741 { 0x045b, "Dell SCSI Array (DSA) Monitor" },
742 { 0x0491, "NetBlazer Modems" },
743 { 0x04ac, "On-Time Scheduler NLM" },
744 { 0x04b0, "CD-Net (Meridian)" },
745 { 0x0513, "Emulex NQA" },
746 { 0x0520, "Site Lock Checks" },
747 { 0x0529, "Site Lock Checks (Brightworks)" },
748 { 0x052d, "Citrix OS/2 App Server" },
749 { 0x0535, "Tektronix" },
751 { 0x055d, "Attachmate SNA gateway" },
752 { 0x056b, "IBM 8235 modem server" },
753 { 0x056c, "Shiva LanRover/E PLUS" },
754 { 0x056d, "Shiva LanRover/T PLUS" },
755 { 0x0580, "McAfee's NetShield anti-virus" },
756 { 0x05B8, "NLM to workstation communication (Revelation Software)" },
757 { 0x05BA, "Compatible Systems Routers" },
758 { 0x05BE, "Cheyenne Hierarchical Storage Manager" },
759 { 0x0606, "JCWatermark Imaging" },
760 { 0x060c, "AXIS Network Printer" },
761 { 0x0610, "Adaptec SCSI Management" },
762 { 0x0621, "IBM AntiVirus NLM" },
763 { 0x0640, "Microsoft Gateway Services for NetWare" },
764 /* { 0x0640, "NT Server-RPC/GW for NW/Win95 User Level Sec" }, */
765 { 0x064e, "Microsoft Internet Information Server" },
766 { 0x067b, "Microsoft Win95/98 File and Print Sharing for NetWare" },
767 { 0x067c, "Microsoft Win95/98 File and Print Sharing for NetWare" },
769 { 0x079b, "Shiva LanRover/E 115" },
770 { 0x079c, "Shiva LanRover/T 115" },
771 { 0x07B4, "Cubix WorldDesk" },
772 { 0x07c2, "Quarterdeck IWare Connect V2.x NLM" },
773 { 0x07c1, "Quarterdeck IWare Connect V3.x NLM" },
774 { 0x0810, "ELAN License Server Demo" },
775 { 0x0824, "Shiva LanRover Access Switch/E" },
776 { 0x086a, "ISSC collector NLMs" },
777 { 0x087f, "ISSC DAS agent for AIX" },
778 { 0x0880, "Intel Netport PRO" },
779 { 0x0881, "Intel Netport PRO" },
780 { 0x0b29, "Site Lock" },
781 { 0x0c29, "Site Lock Applications" },
782 { 0x0c2c, "Licensing Server" },
783 { 0x2101, "Performance Technology Instant Internet" },
784 { 0x2380, "LAI Site Lock" },
785 { 0x238c, "Meeting Maker" },
786 { 0x4808, "Site Lock Server or Site Lock Metering VAP/NLM" },
787 { 0x5555, "Site Lock User" },
788 { 0x6312, "Tapeware" },
789 { 0x6f00, "Rabbit Gateway (3270)" },
791 { 0x8002, "NetPort Printers (Intel) or LANport" },
792 { 0x8003, "SEH InterCon Printserver" },
793 { 0x8008, "WordPerfect Network Version" },
794 { 0x85BE, "Cisco Enhanced Interior Routing Protocol (EIGRP)" },
795 { 0x8888, "WordPerfect Network Version or Quick Network Management" },
796 { 0x9000, "McAfee's NetShield anti-virus" },
797 { 0x9604, "CSA-NT_MON" },
798 { 0xb6a8, "Ocean Isle Reachout Remote Control" },
799 { 0xf11f, "Site Lock Metering VAP/NLM" },
800 { 0xf1ff, "Site Lock" },
801 { 0xf503, "Microsoft SQL Server" },
802 { 0xf905, "IBM Time and Place/2 application" },
803 { 0xfbfb, "TopCall III fax server" },
804 { 0xffff, "Any Service or Wildcard" },
808 p = match_strval(type, server_vals);
818 dissect_ipxsap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
820 proto_tree *sap_tree, *s_tree;
823 struct sap_query query;
824 struct sap_server_ident server;
826 static char *sap_type[4] = { "General Query", "General Response",
827 "Nearest Query", "Nearest Response" };
829 if (check_col(pinfo->cinfo, COL_PROTOCOL))
830 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX SAP");
831 if (check_col(pinfo->cinfo, COL_INFO))
832 col_clear(pinfo->cinfo, COL_INFO);
834 query.query_type = tvb_get_ntohs(tvb, 0);
835 query.server_type = tvb_get_ntohs(tvb, 2);
837 if (check_col(pinfo->cinfo, COL_INFO)) {
838 if (query.query_type >= 1 && query.query_type <= 4) {
839 col_set_str(pinfo->cinfo, COL_INFO, sap_type[query.query_type - 1]);
842 col_set_str(pinfo->cinfo, COL_INFO, "Unknown Packet Type");
847 ti = proto_tree_add_item(tree, proto_sap, tvb, 0, -1, FALSE);
848 sap_tree = proto_item_add_subtree(ti, ett_ipxsap);
850 if (query.query_type >= 1 && query.query_type <= 4) {
851 proto_tree_add_text(sap_tree, tvb, 0, 2, sap_type[query.query_type - 1]);
852 if ((query.query_type - 1) % 2) {
853 proto_tree_add_boolean_hidden(sap_tree,
857 proto_tree_add_boolean_hidden(sap_tree,
863 proto_tree_add_text(sap_tree, tvb, 0, 2,
864 "Unknown SAP Packet Type %d", query.query_type);
867 if (query.query_type == IPX_SAP_GENERAL_RESPONSE ||
868 query.query_type == IPX_SAP_NEAREST_RESPONSE) { /* responses */
870 int available_length = tvb_reported_length(tvb);
871 for (cursor = 2; (cursor + 64) <= available_length; cursor += 64) {
872 server.server_type = tvb_get_ntohs(tvb, cursor);
873 tvb_memcpy(tvb, (guint8 *)server.server_name,
875 tvb_memcpy(tvb, (guint8 *)&server.server_network,
877 tvb_memcpy(tvb, (guint8 *)&server.server_node,
879 server.server_port = tvb_get_ntohs(tvb, cursor+60);
880 server.intermediate_network = tvb_get_ntohs(tvb, cursor+62);
882 ti = proto_tree_add_text(sap_tree, tvb, cursor+2, 48,
883 "Server Name: %s", server.server_name);
884 s_tree = proto_item_add_subtree(ti, ett_ipxsap_server);
886 proto_tree_add_text(s_tree, tvb, cursor, 2, "Server Type: %s (0x%04X)",
887 server_type(server.server_type), server.server_type);
888 proto_tree_add_text(s_tree, tvb, cursor+50, 4, "Network: %s",
889 ipxnet_to_string((guint8*)tvb_get_ptr(tvb, cursor+50, 4)));
890 proto_tree_add_text(s_tree, tvb, cursor+54, 6, "Node: %s",
891 ether_to_str((guint8*)tvb_get_ptr(tvb, cursor+54, 6)));
892 proto_tree_add_text(s_tree, tvb, cursor+60, 2, "Socket: %s (0x%04x)",
893 socket_text(server.server_port), server.server_port);
894 proto_tree_add_text(s_tree, tvb, cursor+62, 2,
895 "Intermediate Networks: %d",
896 server.intermediate_network);
900 proto_tree_add_text(sap_tree, tvb, 2, 2, "Server Type: %s (0x%04X)",
901 server_type(query.server_type), query.server_type);
907 proto_register_ipx(void)
909 static hf_register_info hf_ipx[] = {
911 { "Checksum", "ipx.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
915 { "Length", "ipx.len", FT_UINT16, BASE_DEC, NULL, 0x0,
919 { "Transport Control (Hops)", "ipx.hops", FT_UINT8, BASE_DEC, NULL, 0x0,
922 { &hf_ipx_packet_type,
923 { "Packet Type", "ipx.packet_type", FT_UINT8, BASE_HEX, VALS(ipx_packet_type_vals),
928 { "Destination Network","ipx.dst.net", FT_IPXNET, BASE_NONE, NULL, 0x0,
932 { "Destination Node", "ipx.dst.node", FT_ETHER, BASE_NONE, NULL, 0x0,
936 { "Destination Socket", "ipx.dst.socket", FT_UINT16, BASE_HEX,
937 VALS(ipx_socket_vals), 0x0,
941 { "Source Network","ipx.src.net", FT_IPXNET, BASE_NONE, NULL, 0x0,
945 { "Source Node", "ipx.src.node", FT_ETHER, BASE_NONE, NULL, 0x0,
949 { "Source Socket", "ipx.src.socket", FT_UINT16, BASE_HEX,
950 VALS(ipx_socket_vals), 0x0,
954 static hf_register_info hf_spx[] = {
955 { &hf_spx_connection_control,
956 { "Connection Control", "spx.ctl",
957 FT_UINT8, BASE_HEX, NULL, 0x0,
960 { &hf_spx_datastream_type,
961 { "Datastream type", "spx.type",
962 FT_UINT8, BASE_HEX, NULL, 0x0,
966 { "Source Connection ID", "spx.src",
967 FT_UINT16, BASE_DEC, NULL, 0x0,
971 { "Destination Connection ID", "spx.dst",
972 FT_UINT16, BASE_DEC, NULL, 0x0,
976 { "Sequence Number", "spx.seq",
977 FT_UINT16, BASE_DEC, NULL, 0x0,
981 { "Acknowledgment Number", "spx.ack",
982 FT_UINT16, BASE_DEC, NULL, 0x0,
986 { "Allocation Number", "spx.alloc",
987 FT_UINT16, BASE_DEC, NULL, 0x0,
990 static hf_register_info hf_ipxrip[] = {
991 { &hf_ipxrip_request,
992 { "Request", "ipxrip.request",
993 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
994 "TRUE if IPX RIP request", HFILL }},
996 { &hf_ipxrip_response,
997 { "Response", "ipxrip.response",
998 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
999 "TRUE if IPX RIP response", HFILL }}
1002 static hf_register_info hf_sap[] = {
1004 { "Request", "ipxsap.request",
1005 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1006 "TRUE if SAP request", HFILL }},
1009 { "Response", "ipxsap.response",
1010 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1011 "TRUE if SAP response", HFILL }}
1014 static hf_register_info hf_ipxmsg[] = {
1016 { "Connection Number", "ipxmsg.conn",
1017 FT_UINT8, BASE_DEC, NULL, 0x0,
1018 "Connection Number", HFILL }},
1021 { "Signature Char", "ipxmsg.sigchar",
1022 FT_UINT8, BASE_DEC, VALS(ipxmsg_sigchar_vals), 0x0,
1023 "Signature Char", HFILL }}
1026 static gint *ett[] = {
1035 proto_ipx = proto_register_protocol("Internetwork Packet eXchange",
1037 proto_register_field_array(proto_ipx, hf_ipx, array_length(hf_ipx));
1039 register_dissector("ipx", dissect_ipx, proto_ipx);
1041 proto_spx = proto_register_protocol("Sequenced Packet eXchange",
1043 proto_register_field_array(proto_spx, hf_spx, array_length(hf_spx));
1045 proto_ipxrip = proto_register_protocol("IPX Routing Information Protocol",
1046 "IPX RIP", "ipxrip");
1047 proto_register_field_array(proto_ipxrip, hf_ipxrip, array_length(hf_ipxrip));
1049 proto_ipxmsg = proto_register_protocol("IPX Message", "IPX MSG",
1051 proto_register_field_array(proto_ipxmsg, hf_ipxmsg, array_length(hf_ipxmsg));
1053 proto_sap = proto_register_protocol("Service Advertisement Protocol",
1054 "IPX SAP", "ipxsap");
1055 register_dissector("ipxsap", dissect_ipxsap, proto_sap);
1057 proto_register_field_array(proto_sap, hf_sap, array_length(hf_sap));
1059 proto_register_subtree_array(ett, array_length(ett));
1061 ipx_type_dissector_table = register_dissector_table("ipx.packet_type",
1062 "IPX packet type", FT_UINT8, BASE_HEX);
1063 ipx_socket_dissector_table = register_dissector_table("ipx.socket",
1064 "IPX socket", FT_UINT16, BASE_HEX);
1065 spx_socket_dissector_table = register_dissector_table("spx.socket",
1066 "SPX socket", FT_UINT16, BASE_HEX);
1070 proto_reg_handoff_ipx(void)
1072 dissector_handle_t ipx_handle, spx_handle;
1073 dissector_handle_t ipxsap_handle, ipxrip_handle;
1074 dissector_handle_t ipxmsg_handle;
1076 ipx_handle = find_dissector("ipx");
1077 dissector_add("udp.port", UDP_PORT_IPX, ipx_handle);
1078 dissector_add("ethertype", ETHERTYPE_IPX, ipx_handle);
1079 dissector_add("chdlctype", ETHERTYPE_IPX, ipx_handle);
1080 dissector_add("ppp.protocol", PPP_IPX, ipx_handle);
1081 dissector_add("llc.dsap", SAP_NETWARE, ipx_handle);
1082 dissector_add("null.type", BSD_AF_IPX, ipx_handle);
1083 dissector_add("gre.proto", ETHERTYPE_IPX, ipx_handle);
1084 dissector_add("arcnet.protocol_id", ARCNET_PROTO_IPX, ipx_handle);
1086 spx_handle = create_dissector_handle(dissect_spx, proto_spx);
1087 dissector_add("ipx.packet_type", IPX_PACKET_TYPE_SPX, spx_handle);
1089 ipxsap_handle = find_dissector("ipxsap");
1090 dissector_add("ipx.socket", IPX_SOCKET_SAP, ipxsap_handle);
1092 ipxrip_handle = create_dissector_handle(dissect_ipxrip, proto_ipxrip);
1093 dissector_add("ipx.socket", IPX_SOCKET_IPXRIP, ipxrip_handle);
1095 ipxmsg_handle = create_dissector_handle(dissect_ipxmsg, proto_ipxmsg);
1096 dissector_add("ipx.socket", IPX_SOCKET_IPX_MESSAGE, ipxmsg_handle);
1097 dissector_add("ipx.socket", IPX_SOCKET_IPX_MESSAGE1, ipxmsg_handle);
1099 data_handle = find_dissector("data");