2 * Routines for NetWare's IPX
3 * Gilbert Ramirez <gram@verdict.uthscsa.edu>
5 * $Id: packet-ipx.c,v 1.32 1999/11/16 11:42:36 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
9 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
38 #include "packet-ipx.h"
39 #include "packet-ncp.h"
41 /* The information in this module (IPX, SPX, NCP) comes from:
42 NetWare LAN Analysis, Second Edition
43 Laura A. Chappell and Dan E. Hakes
45 Novell Press, San Jose.
48 And from the ncpfs source code by Volker Lendecke
52 static int proto_ipx = -1;
53 static int hf_ipx_checksum = -1;
54 static int hf_ipx_len = -1;
55 static int hf_ipx_hops = -1;
56 static int hf_ipx_packet_type = -1;
57 static int hf_ipx_dnet = -1;
58 static int hf_ipx_dnode = -1;
59 static int hf_ipx_dsocket = -1;
60 static int hf_ipx_snet = -1;
61 static int hf_ipx_snode = -1;
62 static int hf_ipx_ssocket = -1;
64 static gint ett_ipx = -1;
66 static int proto_spx = -1;
67 static int hf_spx_connection_control = -1;
68 static int hf_spx_datastream_type = -1;
69 static int hf_spx_src_id = -1;
70 static int hf_spx_dst_id = -1;
71 static int hf_spx_seq_nr = -1;
72 static int hf_spx_ack_nr = -1;
73 static int hf_spx_all_nr = -1;
75 static gint ett_spx = -1;
77 static int proto_ipxrip = -1;
78 static int hf_ipxrip_request = -1;
79 static int hf_ipxrip_response = -1;
81 static gint ett_ipxrip = -1;
83 static int proto_sap = -1;
84 static int hf_sap_request = -1;
85 static int hf_sap_response = -1;
87 static gint ett_ipxsap = -1;
88 static gint ett_ipxsap_server = -1;
91 dissect_spx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree);
94 dissect_ipxrip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree);
97 dissect_sap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree);
99 typedef void (dissect_func_t)(const u_char *, int, frame_data *, proto_tree *);
103 dissect_func_t *func;
117 /* ================================================================= */
119 /* ================================================================= */
121 #define IPX_SOCKET_NCP 0x0451
122 #define IPX_SOCKET_SAP 0x0452
123 #define IPX_SOCKET_IPXRIP 0x0453
124 #define IPX_SOCKET_NETBIOS 0x0455
125 #define IPX_SOCKET_DIAGNOSTIC 0x0456
126 #define IPX_SOCKET_SERIALIZATION 0x0457
127 #define IPX_SOCKET_NWLINK_SMB_NAMEQUERY 0x0551
128 #define IPX_SOCKET_NWLINK_SMB_DGRAM 0x0553
129 #define IPX_SOCKET_NWLINK_SMB_BROWSE 0x0555 /* ? not sure on this
130 but I guessed based on the content of the packet I saw */
131 #define IPX_SOCKET_ATTACHMATE_GW 0x055d
132 #define IPX_SOCKET_IPX_MESSAGE 0x4001
133 #define IPX_SOCKET_ADSM 0x8522 /* www.tivoli.com */
134 #define IPX_SOCKET_SNMP_AGENT 0x900F /* RFC 1906 */
135 #define IPX_SOCKET_SNMP_SINK 0x9010 /* RFC 1906 */
136 #define IPX_SOCKET_TCP_TUNNEL 0x9091 /* RFC 1791 */
137 #define IPX_SOCKET_UDP_TUNNEL 0x9092 /* RFC 1791 */
139 static struct port_info ports[] = {
140 { IPX_SOCKET_NCP, dissect_ncp,
142 { IPX_SOCKET_SAP, dissect_sap,
144 { IPX_SOCKET_IPXRIP, dissect_ipxrip,
146 { IPX_SOCKET_NETBIOS, NULL,
148 { IPX_SOCKET_DIAGNOSTIC, NULL,
150 { IPX_SOCKET_SERIALIZATION, NULL,
152 { IPX_SOCKET_NWLINK_SMB_NAMEQUERY, NULL,
153 "NWLink SMB Name Query" },
154 { IPX_SOCKET_NWLINK_SMB_DGRAM, dissect_nwlink_dg,
155 "NWLink SMB Datagram" },
156 { IPX_SOCKET_NWLINK_SMB_BROWSE, NULL,
157 "NWLink SMB Browse" },
158 { IPX_SOCKET_ATTACHMATE_GW, NULL,
159 "Attachmate Gateway" },
160 { IPX_SOCKET_IPX_MESSAGE, NULL,
162 { IPX_SOCKET_SNMP_AGENT, NULL, "SNMP Agent" },
163 { IPX_SOCKET_SNMP_SINK, NULL, "SNMP Sink" },
164 { IPX_SOCKET_UDP_TUNNEL, NULL, "UDP Tunnel" },
165 { IPX_SOCKET_TCP_TUNNEL, NULL, "TCP Tunnel" },
166 { IPX_SOCKET_TCP_TUNNEL, NULL, "TCP Tunnel" },
167 { IPX_SOCKET_ADSM, NULL, "ADSM" },
173 port_text(guint16 port) {
176 while (ports[i].text != NULL) {
177 if (ports[i].port == port) {
178 return ports[i].text;
185 static dissect_func_t*
186 port_func(guint16 port) {
189 while (ports[i].text != NULL) {
190 if (ports[i].port == port) {
191 return ports[i].func;
198 #define IPX_PACKET_TYPE_IPX 0
199 #define IPX_PACKET_TYPE_IPX_4 4
200 #define IPX_PACKET_TYPE_SPX 5
201 #define IPX_PACKET_TYPE_NCP 17
202 #define IPX_PACKET_TYPE_WANBCAST 20
204 static const value_string ipx_packet_type_vals[] = {
205 { IPX_PACKET_TYPE_IPX, "IPX" },
206 { IPX_PACKET_TYPE_IPX_4, "IPX" },
207 /* NetMon calls it "IPX" */
208 { IPX_PACKET_TYPE_SPX, "SPX" },
209 { 16, "Experimental Protocol" },
210 { IPX_PACKET_TYPE_NCP, "NCP" },
211 { 18, "Experimental Protocol" },
212 { 19, "Experimental Protocol" },
213 { IPX_PACKET_TYPE_WANBCAST, "NetBIOS Broadcast" },
214 /* NetMon calls it "WAN Broadcast" */
215 { 21, "Experimental Protocol" },
216 { 22, "Experimental Protocol" },
217 { 23, "Experimental Protocol" },
218 { 24, "Experimental Protocol" },
219 { 25, "Experimental Protocol" },
220 { 26, "Experimental Protocol" },
221 { 27, "Experimental Protocol" },
222 { 28, "Experimental Protocol" },
223 { 29, "Experimental Protocol" },
224 { 30, "Experimental Protocol" },
225 { 31, "Experimental Protocol" },
230 ipxnet_to_string(const guint8 *ad)
232 static gchar str[3][12];
235 if (cur == &str[0][0]) {
237 } else if (cur == &str[1][0]) {
243 sprintf(cur, "%02X %02X %02X %02X", ad[0], ad[1], ad[2], ad[3]);
248 ipx_addr_to_str(guint32 net, const guint8 *ad)
250 static gchar str[3][22];
253 if (cur == &str[0][0]) {
255 } else if (cur == &str[1][0]) {
261 sprintf(cur, "%X.%02x%02x%02x%02x%02x%02x", net,
262 ad[0], ad[1], ad[2], ad[3], ad[4], ad[5]);
267 dissect_ipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
269 proto_tree *ipx_tree;
271 guint8 ipx_type, ipx_hops;
272 guint16 ipx_checksum, ipx_length;
274 guint8 *ipx_snode, *ipx_dnode, *ipx_snet, *ipx_dnet;
276 gchar *str_dnet, *str_snet;
277 guint16 ipx_dsocket, ipx_ssocket;
278 dissect_func_t *dissect;
279 guint32 ipx_dnet_val, ipx_snet_val;
281 /* Calculate here for use in pinfo and in tree */
282 ipx_dnet = (guint8*)&pd[offset+6];
283 ipx_snet = (guint8*)&pd[offset+18];
284 str_dnet = ipxnet_to_string(ipx_dnet);
285 str_snet = ipxnet_to_string(ipx_snet);
286 ipx_dnet_val = pntohl(ipx_dnet);
287 ipx_snet_val = pntohl(ipx_snet);
288 ipx_dsocket = pntohs(&pd[offset+16]);
289 ipx_ssocket = pntohs(&pd[offset+28]);
290 ipx_dnode = (guint8*)&pd[offset+10];
291 ipx_snode = (guint8*)&pd[offset+22];
292 ipx_type = pd[offset+5];
293 ipx_length = pntohs(&pd[offset+2]);
295 /* Length of IPX datagram plus headers above it. */
296 len = ipx_length + offset;
298 /* Set the payload and captured-payload lengths to the minima of
299 (the IPX length plus the length of the headers above it) and
300 the frame lengths. */
303 if (pi.captured_len > len)
304 pi.captured_len = len;
306 SET_ADDRESS(&pi.net_src, AT_IPX, 10, &pd[offset+18]);
307 SET_ADDRESS(&pi.src, AT_IPX, 10, &pd[offset+18]);
308 SET_ADDRESS(&pi.net_dst, AT_IPX, 10, &pd[offset+6]);
309 SET_ADDRESS(&pi.dst, AT_IPX, 10, &pd[offset+6]);
311 if (check_col(fd, COL_PROTOCOL))
312 col_add_str(fd, COL_PROTOCOL, "IPX");
313 if (check_col(fd, COL_INFO))
314 col_add_fstr(fd, COL_INFO, "%s (0x%04X)", port_text(ipx_dsocket),
318 ipx_checksum = pntohs(&pd[offset]);
319 ipx_hops = pd[offset+4];
321 ti = proto_tree_add_item(tree, proto_ipx, offset, 30, NULL);
322 ipx_tree = proto_item_add_subtree(ti, ett_ipx);
323 proto_tree_add_item(ipx_tree, hf_ipx_checksum, offset, 2, ipx_checksum);
324 proto_tree_add_item_format(ipx_tree, hf_ipx_len, offset+2, 2, ipx_length,
325 "Length: %d bytes", ipx_length);
326 proto_tree_add_item_format(ipx_tree, hf_ipx_hops, offset+4, 1, ipx_hops,
327 "Transport Control: %d hops", ipx_hops);
328 proto_tree_add_item(ipx_tree, hf_ipx_packet_type, offset+5, 1, ipx_type);
329 proto_tree_add_item(ipx_tree, hf_ipx_dnet, offset+6, 4, ipx_dnet_val);
330 proto_tree_add_item(ipx_tree, hf_ipx_dnode, offset+10, 6, ipx_dnode);
331 proto_tree_add_item_format(ipx_tree, hf_ipx_dsocket, offset+16, 2,
332 ipx_dsocket, "Destination Socket: %s (0x%04X)",
333 port_text(ipx_dsocket), ipx_dsocket);
334 proto_tree_add_item(ipx_tree, hf_ipx_snet, offset+18, 4, ipx_snet_val);
335 proto_tree_add_item(ipx_tree, hf_ipx_snode, offset+22, 6, ipx_snode);
336 proto_tree_add_item_format(ipx_tree, hf_ipx_ssocket, offset+28, 2,
337 ipx_ssocket, "Source Socket: %s (0x%04X)", port_text(ipx_ssocket),
343 case IPX_PACKET_TYPE_SPX:
344 dissect_spx(pd, offset, fd, tree);
347 case IPX_PACKET_TYPE_NCP:
348 /* Is the destination node 00:00:00:00:00:01 ? */
349 if (pntohl(ipx_dnode) == 0 && pntohs(ipx_dnode + 4) == 1)
350 nw_server_address = pntohl(ipx_dnet);
352 /* Is the source node 00:00:00:00:00:01 ? */
353 else if (pntohl(ipx_snode) == 0 && pntohs(ipx_snode + 4) == 1)
354 nw_server_address = pntohl(ipx_snet);
356 nw_server_address = 0;
358 dissect_ncp(pd, offset, fd, tree);
361 case IPX_PACKET_TYPE_WANBCAST:
362 case IPX_PACKET_TYPE_IPX_4:
363 if (ipx_dsocket == IPX_SOCKET_NETBIOS) {
364 dissect_nbipx(pd, offset, fd, tree);
367 /* else fall through */
369 case 0: /* IPX, fall through to default */
370 /* XXX - should type 0's be dissected as NBIPX
371 if they're aimed at the NetBIOS socket? */
373 dissect = port_func(ipx_dsocket);
375 dissect(pd, offset, fd, tree);
378 dissect = port_func(ipx_ssocket);
380 dissect(pd, offset, fd, tree);
383 dissect_data(pd, offset, fd, tree);
391 /* ================================================================= */
393 /* ================================================================= */
395 spx_conn_ctrl(u_char ctrl)
399 static struct conn_info conns[] = {
400 { 0x10, "End-of-Message" },
401 { 0x20, "Attention" },
402 { 0x40, "Acknowledgment Required"},
403 { 0x80, "System Packet"},
407 while (conns[i].text != NULL) {
408 if (conns[i].ctrl == ctrl) {
409 return conns[i].text;
417 spx_datastream(u_char type)
421 return "End-of-Connection";
423 return "End-of-Connection Acknowledgment";
425 return "Client-Defined";
430 dissect_spx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
431 proto_tree *spx_tree;
434 if (check_col(fd, COL_PROTOCOL))
435 col_add_str(fd, COL_PROTOCOL, "SPX");
436 if (check_col(fd, COL_INFO))
437 col_add_str(fd, COL_INFO, "SPX");
440 ti = proto_tree_add_item(tree, proto_spx, offset, 12, NULL);
441 spx_tree = proto_item_add_subtree(ti, ett_spx);
443 proto_tree_add_item_format(spx_tree, hf_spx_connection_control,
446 "Connection Control: %s (0x%02X)",
447 spx_conn_ctrl(pd[offset]),
450 proto_tree_add_item_format(spx_tree, hf_spx_datastream_type,
453 "Datastream Type: %s (0x%02X)",
454 spx_datastream(pd[offset+1]),
457 proto_tree_add_item(spx_tree, hf_spx_src_id,
459 pntohs( &pd[offset+2] ));
461 proto_tree_add_item(spx_tree, hf_spx_dst_id,
463 pntohs( &pd[offset+4] ));
465 proto_tree_add_item(spx_tree, hf_spx_seq_nr,
467 pntohs( &pd[offset+6] ) );
469 proto_tree_add_item(spx_tree, hf_spx_ack_nr,
471 pntohs( &pd[offset+8] ) );
473 proto_tree_add_item(spx_tree, hf_spx_all_nr,
475 pntohs( &pd[offset+10] ) );
478 dissect_data(pd, offset, fd, tree);
482 /* ================================================================= */
484 /* ================================================================= */
486 dissect_ipxrip(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
487 proto_tree *rip_tree;
490 struct ipx_rt_def route;
493 char *rip_type[2] = { "Request", "Response" };
495 operation = pntohs(&pd[offset]) - 1;
497 if (check_col(fd, COL_PROTOCOL))
498 col_add_str(fd, COL_PROTOCOL, "IPX RIP");
499 if (check_col(fd, COL_PROTOCOL)) {
501 col_add_str(fd, COL_INFO, rip_type[operation]);
504 col_add_str(fd, COL_INFO, "Unknown Packet Type");
509 ti = proto_tree_add_item(tree, proto_ipxrip, offset, END_OF_FRAME, NULL);
510 rip_tree = proto_item_add_subtree(ti, ett_ipxrip);
513 proto_tree_add_text(rip_tree, offset, 2,
514 "RIP packet type: %s", rip_type[operation]);
516 if (operation == 0) {
517 proto_tree_add_item_hidden(rip_tree,
521 proto_tree_add_item_hidden(rip_tree,
528 proto_tree_add_text(rip_tree, offset, 2, "Unknown RIP packet type");
531 for (cursor = offset + 2; cursor < fd->cap_len; cursor += 8) {
532 memcpy(&route.network, &pd[cursor], 4);
533 route.hops = pntohs(&pd[cursor+4]);
534 route.ticks = pntohs(&pd[cursor+6]);
536 if (operation == IPX_RIP_REQUEST - 1) {
537 proto_tree_add_text(rip_tree, cursor, 8,
538 "Route Vector: %s, %d hop%s, %d tick%s",
539 ipxnet_to_string((guint8*)&route.network),
540 route.hops, route.hops == 1 ? "" : "s",
541 route.ticks, route.ticks == 1 ? "" : "s");
544 proto_tree_add_text(rip_tree, cursor, 8,
545 "Route Vector: %s, %d hop%s, %d tick%s (%d ms)",
546 ipxnet_to_string((guint8*)&route.network),
547 route.hops, route.hops == 1 ? "" : "s",
548 route.ticks, route.ticks == 1 ? "" : "s",
549 route.ticks * 1000 / 18);
557 /* ================================================================= */
559 /* ================================================================= */
561 server_type(guint16 type)
565 /* some of these are from ncpfs, others are from the book */
566 static struct server_info servers[] = {
568 { 0x0002, "User Group" },
569 { 0x0003, "Print Queue" },
570 { 0x0004, "File server" },
571 { 0x0005, "Job server" },
572 { 0x0007, "Print server" },
573 { 0x0008, "Archive server" },
574 { 0x0009, "Archive server" },
575 { 0x000a, "Job queue" },
576 { 0x000b, "Administration" },
577 { 0x0021, "NAS SNA gateway" },
578 { 0x0024, "Remote bridge" },
579 { 0x0026, "Bridge server" },
580 { 0x0027, "TCP/IP gateway" },
581 { 0x002d, "Time Synchronization VAP" },
582 { 0x002e, "Archive Server Dynamic SAP" },
583 { 0x0047, "Advertising print server" },
584 { 0x004b, "Btrieve VAP 5.0" },
585 { 0x004c, "SQL VAP" },
586 { 0x0050, "Btrieve VAP" },
587 { 0x0053, "Print Queue VAP" },
588 { 0x007a, "TES NetWare for VMS" },
589 { 0x0098, "NetWare access server" },
590 { 0x009a, "Named Pipes server" },
591 { 0x009e, "Portable NetWare Unix" },
592 { 0x0107, "NetWare 386" },
593 { 0x0111, "Test server" },
594 { 0x0133, "NetWare Name Service" },
595 { 0x0166, "NetWare management" },
596 { 0x023f, "SMS Testing and Development" },
597 { 0x026a, "NetWare management" },
598 { 0x026b, "Time synchronization" },
599 { 0x027b, "NetWare Management Agent" },
600 { 0x0278, "NetWare Directory server" },
601 { 0x030c, "HP LaserJet / Quick Silver" },
602 { 0x0355, "Arcada Software" },
603 { 0x0361, "NETINELO" },
604 { 0x037e, "Powerchute UPS Monitoring" },
605 { 0x03e1, "UnixWare Application Server" },
606 { 0x044c, "Archive" },
607 { 0x055d, "Attachmate SNA gateway" },
608 { 0x0610, "Adaptec SCSI Management" },
609 { 0x0640, "NT Server-RPC/GW for NW/Win95 User Level Sec" },
610 { 0x064e, "NT Server-IIS" },
611 { 0x0810, "ELAN License Server Demo" },
612 { 0x8002, "Intel NetPort Print Server" },
614 /* For any unidentified ones, I found a really big list of them at: */
615 /* http://www.inpnet.org/cnpweb/saplist.txt */
616 /* http://www.isi.edu/in-notes/iana/assignments/novell-sap-numbers */
621 while (servers[i].text != NULL) {
622 if (servers[i].type == type) {
623 return servers[i].text;
631 dissect_sap(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
633 proto_tree *sap_tree, *s_tree;
636 struct sap_query query;
637 struct sap_server_ident server;
639 char *sap_type[4] = { "General Query", "General Response",
640 "Nearest Query", "Nearest Response" };
642 query.query_type = pntohs(&pd[offset]);
643 query.server_type = pntohs(&pd[offset+2]);
645 if (check_col(fd, COL_PROTOCOL))
646 col_add_str(fd, COL_PROTOCOL, "SAP");
647 if (check_col(fd, COL_INFO)) {
648 if (query.query_type >= 1 && query.query_type <= 4) {
649 col_add_str(fd, COL_INFO, sap_type[query.query_type - 1]);
652 col_add_str(fd, COL_INFO, "Unknown Packet Type");
657 ti = proto_tree_add_item(tree, proto_sap, offset, END_OF_FRAME, NULL);
658 sap_tree = proto_item_add_subtree(ti, ett_ipxsap);
660 if (query.query_type >= 1 && query.query_type <= 4) {
661 proto_tree_add_text(sap_tree, offset, 2, sap_type[query.query_type - 1]);
662 if ((query.query_type - 1) % 2) {
663 proto_tree_add_item_hidden(sap_tree,
667 proto_tree_add_item_hidden(sap_tree,
673 proto_tree_add_text(sap_tree, offset, 2,
674 "Unknown SAP Packet Type %d", query.query_type);
677 if (query.query_type == IPX_SAP_GENERAL_RESPONSE ||
678 query.query_type == IPX_SAP_NEAREST_RESPONSE) { /* responses */
680 for (cursor = offset + 2; (cursor + 64) <= fd->cap_len; cursor += 64) {
681 server.server_type = pntohs(&pd[cursor]);
682 memcpy(server.server_name, &pd[cursor+2], 48);
683 memcpy(&server.server_network, &pd[cursor+50], 4);
684 memcpy(&server.server_node, &pd[cursor+54], 6);
685 server.server_port = pntohs(&pd[cursor+60]);
686 server.intermediate_network = pntohs(&pd[cursor+62]);
688 ti = proto_tree_add_text(sap_tree, cursor+2, 48,
689 "Server Name: %s", server.server_name);
690 s_tree = proto_item_add_subtree(ti, ett_ipxsap_server);
692 proto_tree_add_text(s_tree, cursor, 2, "Server Type: %s (0x%04X)",
693 server_type(server.server_type), server.server_type);
694 proto_tree_add_text(s_tree, cursor+50, 4, "Network: %s",
695 ipxnet_to_string((guint8*)&pd[cursor+50]));
696 proto_tree_add_text(s_tree, cursor+54, 6, "Node: %s",
697 ether_to_str((guint8*)&pd[cursor+54]));
698 proto_tree_add_text(s_tree, cursor+60, 2, "Socket: %s (0x%04X)",
699 port_text(server.server_port), server.server_port);
700 proto_tree_add_text(s_tree, cursor+62, 2,
701 "Intermediate Networks: %d",
702 server.intermediate_network);
706 proto_tree_add_text(sap_tree, offset+2, 2, "Server Type: %s (0x%04X)",
707 server_type(query.server_type), query.server_type);
714 proto_register_ipx(void)
716 static hf_register_info hf_ipx[] = {
718 { "Checksum", "ipx.checksum", FT_UINT16, BASE_HEX, NULL, 0x0,
722 { "Length", "ipx.len", FT_UINT16, BASE_DEC, NULL, 0x0,
726 { "Transport Control (Hops)", "ipx.hops", FT_UINT8, BASE_DEC, NULL, 0x0,
729 { &hf_ipx_packet_type,
730 { "Packet Type", "ipx.packet_type", FT_UINT8, BASE_HEX, VALS(ipx_packet_type_vals),
735 { "Destination Network","ipx.dst.net", FT_IPXNET, BASE_NONE, NULL, 0x0,
739 { "Destination Node", "ipx.dst.node", FT_ETHER, BASE_NONE, NULL, 0x0,
743 { "Destination Socket", "ipx.dst.socket", FT_UINT16, BASE_HEX, NULL, 0x0,
747 { "Source Network","ipx.src.net", FT_IPXNET, BASE_NONE, NULL, 0x0,
751 { "Source Node", "ipx.src.node", FT_ETHER, BASE_NONE, NULL, 0x0,
755 { "Source Socket", "ipx.src.socket", FT_UINT16, BASE_HEX, NULL, 0x0,
759 static hf_register_info hf_spx[] = {
760 { &hf_spx_connection_control,
761 { "Connection Control", "spx.ctl",
762 FT_UINT8, BASE_HEX, NULL, 0x0,
765 { &hf_spx_datastream_type,
766 { "Datastream type", "spx.type",
767 FT_UINT8, BASE_HEX, NULL, 0x0,
771 { "Source Connection ID", "spx.src",
772 FT_UINT16, BASE_DEC, NULL, 0x0,
776 { "Destination Connection ID", "spx.dst",
777 FT_UINT16, BASE_DEC, NULL, 0x0,
781 { "Sequence Number", "spx.seq",
782 FT_UINT16, BASE_DEC, NULL, 0x0,
786 { "Acknowledgment Number", "spx.ack",
787 FT_UINT16, BASE_DEC, NULL, 0x0,
791 { "Allocation Number", "spx.alloc",
792 FT_UINT16, BASE_DEC, NULL, 0x0,
796 static hf_register_info hf_ipxrip[] = {
797 { &hf_ipxrip_request,
798 { "Request", "ipxrip.request",
799 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
800 "TRUE if IPX RIP request" }},
802 { &hf_ipxrip_response,
803 { "Response", "ipxrip.response",
804 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
805 "TRUE if IPX RIP response" }}
808 static hf_register_info hf_sap[] = {
810 { "Request", "sap.request",
811 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
812 "TRUE if SAP request" }},
815 { "Response", "sap.response",
816 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
817 "TRUE if SAP response" }}
819 static gint *ett[] = {
827 proto_ipx = proto_register_protocol ("Internetwork Packet eXchange", "ipx");
828 proto_register_field_array(proto_ipx, hf_ipx, array_length(hf_ipx));
830 proto_spx = proto_register_protocol ("Sequenced Packet eXchange", "spx");
831 proto_register_field_array(proto_spx, hf_spx, array_length(hf_spx));
833 proto_ipxrip = proto_register_protocol ("IPX Routing Information Protocol", "ipxrip");
834 proto_register_field_array(proto_ipxrip, hf_ipxrip, array_length(hf_ipxrip));
836 proto_sap = proto_register_protocol ("Service Advertisement Protocol", "sap");
837 proto_register_field_array(proto_sap, hf_sap, array_length(hf_sap));
839 proto_register_subtree_array(ett, array_length(ett));