2 * Routines for NetBIOS over IPX packet disassembly
3 * Gilbert Ramirez <gram@xiexie.org>
5 * $Id: packet-nbipx.c,v 1.37 2001/02/27 07:28:47 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@zing.org>
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-netbios.h"
40 #include "packet-smb.h"
42 static int proto_nbipx = -1;
44 static gint ett_nbipx = -1;
45 static gint ett_nbipx_conn_ctrl = -1;
46 static gint ett_nbipx_name_type_flags = -1;
48 static void dissect_conn_control(tvbuff_t *tvb, int offset, proto_tree *tree);
49 static void dissect_packet_type(tvbuff_t *tvb, int offset, guint8 packet_type,
52 /* There is no RFC or public specification of Netware or Microsoft
53 * NetBIOS over IPX packets. I have had to decode the protocol myself,
54 * so there are holes and perhaps errors in this code. (gram)
56 * A list of "NovelNetBIOS" packet types can be found at
58 * http://www.protocols.com/pbook/novel.htm#NetBIOS
60 * and at least some of those packet types appear to match what's in
63 * Note, however, that it appears that sometimes NBIPX packets have
64 * 8 IPX addresses at the beginning, and sometimes they don't.
66 * In the section on "NetBIOS Broadcasts", the document at
68 * http://www.microsoft.com/technet/network/ipxrout.asp
70 * says that "the NetBIOS over IPX Broadcast header" contains 8 IPX
71 * network numbers in the "IPX WAN broadcast header", and that it's
72 * followed by a "Name Type Flags" byte (giving information about the
73 * name being registered, deregistered, or checked), a "Data Stream
74 * Type 2" byte giving the type of operation (NBIPX_FIND_NAME,
75 * NBIPX_NAME_RECOGNIZED, or NBIPX_CHECK_NAME - the latter is called
76 * "Add Name"), and a 16-byte NetBIOS name.
78 * It also says that "NetBIOS over IPX Broadcast packets" have a
79 * packet type of 0x14 (20, or IPX_PACKET_TYPE_WANBCAST) and a
80 * socket number of 0x455 (IPX_SOCKET_NETBIOS).
82 * However, there are also non-broadcast packets that *also* contain
83 * the 8 IPX network numbers; they appear to be replies to broadcast
84 * packets, and have a packet type of 0x4 (IPX_PACKET_TYPE_PEP).
86 * Other IPX_PACKET_TYPE_PEP packets to and from the IPX_SOCKET_NETBIOS
87 * socket, however, *don't* have the 8 IPX network numbers; there does
88 * not seem to be any obvious algorithm to determine whether the packet
89 * has the addresses or not. Microsoft Knowledge Base article Q128335
90 * appears to show some code from the NBIPX implementation in NT that
91 * tries to determine the packet type - and it appears to use heuristics
92 * based on the packet length and on looking at what might be the NBIPX
93 * "Data Stream Type" byte depending on whether the packet has the 8
94 * IPX network numbers or not.
96 * So, for now, we treat *all* NBIPX packets as having a "Data Stream
97 * Type" byte, preceded by another byte of NBIPX information and
98 * followed by more NBIPX stuff, and assume that it's preceded by
99 * 8 IPX network numbers iff:
101 * the packet is a WAN Broadcast packet
105 * the packet is the right size for one of those PEP name replies
106 * (50 bytes) *and* has a name packet type as the Data Stream
107 * Type byte at the offset where that byte would be if the packet
108 * does have the 8 IPX network numbers at the beginning.
112 * http://ourworld.compuserve.com/homepages/TimothyDEvans/encap.htm
114 * indicates, under "NBIPX session packets", that "NBIPX session packets"
117 * 1 byte of NBIPX connection control flag
118 * 1 byte of data stream type
119 * 2 bytes of source connection ID
120 * 2 bytes of destination connection ID
121 * 2 bytes of send sequence number
122 * 2 bytes of total data length
124 * 2 bytes of data length
125 * 2 bytes of receive sequence number
126 * 2 bytes of "bytes received"
130 * Packets with a data stream type of NBIPX_DIRECTED_DATAGRAM appear to
131 * have, following the data stream type, two NetBIOS names, the first
132 * of which is the receiver's NetBIOS name and the second of which is
133 * the sender's NetBIOS name. The page at
135 * http://support.microsoft.com/support/kb/articles/q203/0/51.asp
137 * speaks of type 4 (PEP) packets as being used for "SAP, NetBIOS sessions
138 * and directed datagrams" and type 20 (WAN Broadcast) as being used for
139 * "NetBIOS name resolution broadcasts" (but nothing about the non-broadcast
140 * type 4 name resolution stuff).
142 * We assume that this means that, once you get past the 8 IPX network
143 * numbers if present:
145 * the first byte is a name type byte for the name packets
146 * and a connection control flag for the other packets;
148 * the second byte is a data stream type;
150 * the rest of the bytes are:
152 * the NetBIOS name being registered/deregistered/etc.,
155 * the two NetBIOS names, followed by the NetBIOS
156 * datagram, for NBIPX_DIRECTED_DATAGRAM packets;
158 * the session packet header, possibly followed by
159 * session data, for session packets.
161 * We don't know yet how to interpret NBIPX_STATUS_QUERY or
162 * NBIPX_STATUS_RESPONSE.
164 * For now, we treat the datagrams and session data as SMB stuff.
166 #define NBIPX_FIND_NAME 1
167 #define NBIPX_NAME_RECOGNIZED 2
168 #define NBIPX_CHECK_NAME 3
169 #define NBIPX_NAME_IN_USE 4
170 #define NBIPX_DEREGISTER_NAME 5
171 #define NBIPX_SESSION_DATA 6
172 #define NBIPX_SESSION_END 7
173 #define NBIPX_SESSION_END_ACK 8
174 #define NBIPX_STATUS_QUERY 9
175 #define NBIPX_STATUS_RESPONSE 10
176 #define NBIPX_DIRECTED_DATAGRAM 11
178 static const value_string nbipx_data_stream_type_vals[] = {
179 {NBIPX_FIND_NAME, "Find name"},
180 {NBIPX_NAME_RECOGNIZED, "Name recognized"},
181 {NBIPX_CHECK_NAME, "Check name"},
182 {NBIPX_NAME_IN_USE, "Name in use"},
183 {NBIPX_DEREGISTER_NAME, "Deregister name"},
184 {NBIPX_SESSION_DATA, "Session data"},
185 {NBIPX_SESSION_END, "Session end"},
186 {NBIPX_SESSION_END_ACK, "Session end ACK"},
187 {NBIPX_STATUS_QUERY, "Status query"},
188 {NBIPX_STATUS_RESPONSE, "Status response"},
189 {NBIPX_DIRECTED_DATAGRAM, "Directed datagram"},
194 add_routers(proto_tree *tree, tvbuff_t *tvb, int offset)
200 /* Eight routers are listed */
201 for (i = 0; i < 8; i++) {
202 rtr_offset = offset + (i << 2);
203 tvb_memcpy(tvb, (guint8 *)&router, rtr_offset, 4);
205 proto_tree_add_text(tree, tvb, rtr_offset, 4,
207 ipxnet_to_string((guint8*)&router));
213 dissect_nbipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
216 proto_tree *nbipx_tree = NULL;
217 proto_item *ti = NULL;
220 guint8 name_type_flag;
221 proto_tree *name_type_flag_tree;
224 const guint8 *next_pd;
226 char name[(NETBIOS_NAME_LEN - 1)*4 + 1];
228 gboolean has_payload;
230 if (check_col(pinfo->fd, COL_PROTOCOL))
231 col_set_str(pinfo->fd, COL_PROTOCOL, "NBIPX");
232 if (check_col(pinfo->fd, COL_INFO))
233 col_clear(pinfo->fd, COL_INFO);
235 if (pinfo->ipxptype == IPX_PACKET_TYPE_WANBCAST) {
237 * This is a WAN Broadcast packet; we assume it will have
238 * 8 IPX addresses at the beginning.
243 * This isn't a WAN Broadcast packet, but it still might
244 * have the 8 addresses.
246 * If it's the right length for a name operation,
247 * and, if we assume it has routes, the packet type
248 * is a name operation, assume it has routes.
250 * NOTE: this will throw an exception if the byte that
251 * would be the packet type byte if this has the 8
252 * addresses isn't present; if that's the case, we don't
253 * know how to interpret this packet, so we can't dissect
256 has_routes = FALSE; /* start out assuming it doesn't */
257 if (tvb_reported_length(tvb) == 50) {
258 packet_type = tvb_get_guint8(tvb, offset + 32 + 1);
259 switch (packet_type) {
261 case NBIPX_FIND_NAME:
262 case NBIPX_NAME_RECOGNIZED:
263 case NBIPX_CHECK_NAME:
264 case NBIPX_NAME_IN_USE:
265 case NBIPX_DEREGISTER_NAME:
273 ti = proto_tree_add_item(tree, proto_nbipx, tvb, 0,
275 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
280 add_routers(nbipx_tree, tvb, 0);
284 packet_type = tvb_get_guint8(tvb, offset + 1);
286 switch (packet_type) {
288 case NBIPX_FIND_NAME:
289 case NBIPX_NAME_RECOGNIZED:
290 case NBIPX_CHECK_NAME:
291 case NBIPX_NAME_IN_USE:
292 case NBIPX_DEREGISTER_NAME:
293 name_type_flag = tvb_get_guint8(tvb, offset);
294 name_type = get_netbios_name(tvb, offset+2, name);
295 if (check_col(pinfo->fd, COL_INFO)) {
296 col_add_fstr(pinfo->fd, COL_INFO, "%s %s<%02x>",
297 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"),
301 tf = proto_tree_add_text(nbipx_tree, tvb, offset, 1,
302 "Name type flag: 0x%02x", name_type_flag);
303 name_type_flag_tree = proto_item_add_subtree(tf,
304 ett_nbipx_name_type_flags);
305 proto_tree_add_text(name_type_flag_tree, tvb, offset,
307 decode_boolean_bitfield(name_type_flag, 0x80, 8,
308 "Group name", "Unique name"));
309 proto_tree_add_text(name_type_flag_tree, tvb, offset,
311 decode_boolean_bitfield(name_type_flag, 0x40, 8,
312 "Name in use", "Name not used"));
313 proto_tree_add_text(name_type_flag_tree, tvb, offset,
315 decode_boolean_bitfield(name_type_flag, 0x04, 8,
316 "Name registered", "Name not registered"));
317 proto_tree_add_text(name_type_flag_tree, tvb, offset,
319 decode_boolean_bitfield(name_type_flag, 0x02, 8,
320 "Name duplicated", "Name not duplicated"));
321 proto_tree_add_text(name_type_flag_tree, tvb, offset,
323 decode_boolean_bitfield(name_type_flag, 0x01, 8,
324 "Name deregistered", "Name not deregistered"));
328 dissect_packet_type(tvb, offset, packet_type, nbipx_tree);
332 netbios_add_name("Name", tvb, offset, nbipx_tree);
333 offset += NETBIOS_NAME_LEN;
336 * No payload to be interpreted by another protocol.
341 case NBIPX_SESSION_DATA:
342 case NBIPX_SESSION_END:
343 case NBIPX_SESSION_END_ACK:
344 if (check_col(pinfo->fd, COL_INFO)) {
345 col_add_fstr(pinfo->fd, COL_INFO, "%s",
346 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"));
348 dissect_conn_control(tvb, offset, nbipx_tree);
351 dissect_packet_type(tvb, offset, packet_type, nbipx_tree);
355 proto_tree_add_text(nbipx_tree, tvb, offset, 2,
356 "Source connection ID: 0x%04X",
357 tvb_get_letohs(tvb, offset));
362 proto_tree_add_text(nbipx_tree, tvb, offset, 2,
363 "Destination connection ID: 0x%04X",
364 tvb_get_letohs(tvb, offset));
369 proto_tree_add_text(nbipx_tree, tvb, offset, 2,
370 "Send sequence number: %u",
371 tvb_get_letohs(tvb, offset));
376 proto_tree_add_text(nbipx_tree, tvb, offset, 2,
377 "Total data length: %u",
378 tvb_get_letohs(tvb, offset));
383 proto_tree_add_text(nbipx_tree, tvb, offset, 2,
385 tvb_get_letohs(tvb, offset));
390 proto_tree_add_text(nbipx_tree, tvb, offset, 2,
392 tvb_get_letohs(tvb, offset));
397 proto_tree_add_text(nbipx_tree, tvb, offset, 2,
398 "Receive sequence number: %u",
399 tvb_get_letohs(tvb, offset));
404 proto_tree_add_text(nbipx_tree, tvb, offset, 2,
405 "Bytes received: %u",
406 tvb_get_letohs(tvb, offset));
411 * We may have payload to dissect.
416 case NBIPX_DIRECTED_DATAGRAM:
417 if (check_col(pinfo->fd, COL_INFO)) {
418 col_add_fstr(pinfo->fd, COL_INFO, "%s",
419 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"));
421 dissect_conn_control(tvb, offset, nbipx_tree);
424 dissect_packet_type(tvb, offset, packet_type, nbipx_tree);
428 netbios_add_name("Receiver's Name", tvb, offset,
430 offset += NETBIOS_NAME_LEN;
433 netbios_add_name("Sender's Name", tvb, offset,
435 offset += NETBIOS_NAME_LEN;
438 * We may have payload to dissect.
444 if (check_col(pinfo->fd, COL_INFO)) {
445 col_add_fstr(pinfo->fd, COL_INFO, "%s",
446 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"));
450 * We don't know what the first byte is.
455 * The second byte is a data stream type byte.
457 dissect_packet_type(tvb, offset, packet_type, nbipx_tree);
461 * We don't know what the rest of the packet is.
467 * Set the length of the NBIPX tree item.
470 proto_item_set_len(ti, offset);
472 if (has_payload && tvb_offset_exists(tvb, offset)) {
473 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
474 tvb_compat(next_tvb, &next_pd, &next_offset);
475 dissect_smb(next_pd, next_offset, pinfo->fd, tree,
476 tvb_length(next_tvb));
481 dissect_conn_control(tvbuff_t *tvb, int offset, proto_tree *tree)
488 conn_control = tvb_get_guint8(tvb, offset);
489 ti = proto_tree_add_text(tree, tvb, offset, 1,
490 "Connection control: 0x%02x", conn_control);
491 cc_tree = proto_item_add_subtree(ti, ett_nbipx_conn_ctrl);
492 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
493 decode_boolean_bitfield(conn_control, 0x80, 8,
494 "System packet", "Non-system packet"));
495 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
496 decode_boolean_bitfield(conn_control, 0x40, 8,
497 "Acknowledgement required",
498 "Acknowledgement not required"));
499 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
500 decode_boolean_bitfield(conn_control, 0x20, 8,
501 "Attention", "No attention"));
502 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
503 decode_boolean_bitfield(conn_control, 0x10, 8,
504 "End of message", "No end of message"));
505 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
506 decode_boolean_bitfield(conn_control, 0x08, 8,
507 "Resend", "No resend"));
512 dissect_packet_type(tvbuff_t *tvb, int offset, guint8 packet_type,
516 proto_tree_add_text(tree, tvb, offset, 1,
517 "Packet Type: %s (%02X)",
518 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"),
524 proto_register_nbipx(void)
526 /* static hf_register_info hf[] = {
528 { "Name", "nbipx.abbreviation", TYPE, VALS_POINTER }},
530 static gint *ett[] = {
532 &ett_nbipx_conn_ctrl,
533 &ett_nbipx_name_type_flags,
536 proto_nbipx = proto_register_protocol("NetBIOS over IPX",
538 /* proto_register_field_array(proto_nbipx, hf, array_length(hf));*/
539 proto_register_subtree_array(ett, array_length(ett));
543 proto_reg_handoff_nbipx(void)
545 dissector_add("ipx.socket", IPX_SOCKET_NETBIOS, dissect_nbipx,
550 * Microsoft appear to have something they call "direct hosting", where
551 * SMB - and, I infer, related stuff, such as name resolution - runs
552 * directly over IPX. (In Windows 2000, they also run SMB directly over
553 * TCP, on port 445, and that also appears to be called "direct hosting".
554 * Ethereal handles SMB-over-TCP.)
558 * http://support.microsoft.com/support/kb/articles/q203/0/51.asp
560 * speaks of NMPI - the "Name Management Protocol on IPX" - as being
561 * "Microsoft's protocol for name management support when you use IPX
562 * without the NetBIOS interface," and says that "This process of routing
563 * the SMB protocol directly through IPX is known as Direct Hosting."
565 * It speaks of IPX socket 0x551 as being for NMPI; we define it as
566 * IPX_SOCKET_NWLINK_SMB_NAMEQUERY.
568 * We also define IPX_SOCKET_NWLINK_SMB_DGRAM as 0x0553 and define
569 * IPX_SOCKET_NWLINK_SMB_BROWSE as 0x0555 (with a "? not sure on this"
570 * comment after the latter one).
572 * We have seen at least some browser announcements on IPX socket 0x553;
573 * those are WAN broadcast packets, complete with 8 IPX network
574 * numbers, and with the header containing the usual two NetBIOS names
575 * that show up in NetBIOS datagrams.
577 * Network Monitor calls those packets NMPI packets, even though they're
578 * on socket 0x553, not socket 0x551, and contain SMB datagrams, not name
579 * resolution packets.
581 * At least some of this is discussed in the "SMBPUB.DOC" Word document
584 * ftp://ftp.microsoft.com/developr/drg/CIFS/smbpub.zip
586 * which can also be found in text form at
588 * http://www.samba.org/samba/ftp/specs/smbpub.txt
590 * which says that for "connectionless IPX transport" the sockets that
593 * SMB_SERVER_SOCKET (0x550) - SMB requests from clients
594 * SMB_NAME_SOCKET (0x551) - name claims and name query messages
595 * REDIR_SOCKET (0x552) - used by the redirector (client) for
596 * sending SMB requests and receiving SMB replies
597 * MAILSLOT_SOCKET (0x553) - used by the redirector and browser
598 * for mailslot datagrams
599 * MESSENGER_SOCKET (0x554) - used by the redirector to send
600 * messages from client to client
602 * Name claim/query packets, and mailslot datagrams, are:
604 * 8 IPX network addresses
606 * 1 byte of name type
607 * 2 bytes of message ID
608 * 16 bytes of name being sought or claimed
609 * 16 bytes of requesting machine
611 * The opcode is one of:
613 * INAME_CLAIM (0xf1) - server name claim message
614 * INAME_DELETE (0xf2) - relinquish server name
615 * INAME_QUERY (0xf3) - locate server name
616 * INAME_FOUND (0xf4) - response to INAME_QUERY
617 * IMSG_HANGUP (0xf5) - messenger hangup
618 * IMSLOT_SEND (0xfc) - mailslot write
619 * IMSLOT_FIND (0xfd) - find name for mailslot write
620 * IMSLOT_NAME (0xfe) - response to IMSLOT_FIND
622 * The name type is one of:
628 static int proto_nmpi = -1;
630 static gint ett_nmpi = -1;
631 static gint ett_nmpi_name_type_flags = -1;
636 #define INAME_CLAIM 0xf1
637 #define INAME_DELETE 0xf2
638 #define INAME_QUERY 0xf3
639 #define INAME_FOUND 0xf4
640 #define IMSG_HANGUP 0xf5
641 #define IMSLOT_SEND 0xfc
642 #define IMSLOT_FIND 0xfd
643 #define IMSLOT_NAME 0xfe
645 static const value_string nmpi_opcode_vals[] = {
646 {INAME_CLAIM, "Claim name"},
647 {INAME_DELETE, "Delete name"},
648 {INAME_QUERY, "Query name"},
649 {INAME_FOUND, "Name found"},
650 {IMSG_HANGUP, "Messenger hangup"},
651 {IMSLOT_SEND, "Mailslot write"},
652 {IMSLOT_FIND, "Find mailslot name"},
653 {IMSLOT_NAME, "Mailslot name found"},
660 #define INTYPE_MACHINE 1
661 #define INTYPE_WORKGROUP 2
662 #define INTYPE_BROWSER 3
664 static const value_string nmpi_name_type_vals[] = {
665 {INTYPE_MACHINE, "Machine"},
666 {INTYPE_WORKGROUP, "Workgroup"},
667 {INTYPE_BROWSER, "Browser"},
672 dissect_nmpi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
674 proto_tree *nmpi_tree = NULL;
678 guint8 nmpi_name_type;
679 char name[(NETBIOS_NAME_LEN - 1)*4 + 1];
681 char node_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
682 int node_name_type = 0;
684 const guint8 *next_pd;
687 if (check_col(pinfo->fd, COL_PROTOCOL))
688 col_set_str(pinfo->fd, COL_PROTOCOL, "NMPI");
689 if (check_col(pinfo->fd, COL_INFO))
690 col_clear(pinfo->fd, COL_INFO);
693 ti = proto_tree_add_item(tree, proto_nmpi, tvb, offset, 68,
695 nmpi_tree = proto_item_add_subtree(ti, ett_nmpi);
697 add_routers(nmpi_tree, tvb, offset);
702 * XXX - we don't use "node_name" or "node_name_type".
704 opcode = tvb_get_guint8(tvb, offset);
705 nmpi_name_type = tvb_get_guint8(tvb, offset+1);
706 name_type = get_netbios_name(tvb, offset+4, name);
707 node_name_type = get_netbios_name(tvb, offset+20, node_name);
709 if (check_col(pinfo->fd, COL_INFO)) {
713 col_add_fstr(pinfo->fd, COL_INFO, "Claim name %s<%02x>",
718 col_add_fstr(pinfo->fd, COL_INFO, "Delete name %s<%02x>",
723 col_add_fstr(pinfo->fd, COL_INFO, "Query name %s<%02x>",
728 col_add_fstr(pinfo->fd, COL_INFO, "Name %s<%02x> found",
733 col_add_fstr(pinfo->fd, COL_INFO,
734 "Messenger hangup on %s<%02x>", name, name_type);
738 col_add_fstr(pinfo->fd, COL_INFO,
739 "Mailslot write to %s<%02x>", name, name_type);
743 col_add_fstr(pinfo->fd, COL_INFO,
744 "Find mailslot name %s<%02x>", name, name_type);
748 col_add_fstr(pinfo->fd, COL_INFO,
749 "Mailslot name %s<%02x> found", name, name_type);
753 col_add_fstr(pinfo->fd, COL_INFO,
754 "Unknown NMPI op 0x%02x: name %s<%02x>",
755 opcode, name, name_type);
761 proto_tree_add_text(nmpi_tree, tvb, offset, 1,
762 "Opcode: %s (0x%02x)",
763 val_to_str(opcode, nmpi_opcode_vals, "Unknown"),
765 proto_tree_add_text(nmpi_tree, tvb, offset+1, 1,
766 "Name Type: %s (0x%02x)",
767 val_to_str(nmpi_name_type, nmpi_name_type_vals, "Unknown"),
769 proto_tree_add_text(nmpi_tree, tvb, offset+2, 2,
770 "Message ID: 0x%04x",
771 tvb_get_letohs(tvb, offset+2));
772 netbios_add_name("Requested name", tvb, offset+4, nmpi_tree);
773 netbios_add_name("Source name", tvb, offset+20, nmpi_tree);
776 offset += 1 + 1 + 2 + NETBIOS_NAME_LEN + NETBIOS_NAME_LEN;
778 if (opcode == IMSLOT_SEND && tvb_offset_exists(tvb, offset)) {
779 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
780 tvb_compat(next_tvb, &next_pd, &next_offset);
781 dissect_smb(next_pd, next_offset, pinfo->fd, tree,
782 tvb_length(next_tvb));
787 proto_register_nmpi(void)
789 /* static hf_register_info hf[] = {
791 { "Name", "nmpi.abbreviation", TYPE, VALS_POINTER }},
793 static gint *ett[] = {
795 &ett_nmpi_name_type_flags,
798 proto_nmpi = proto_register_protocol("Name Management Protocol over IPX",
800 /* proto_register_field_array(proto_nmpi, hf, array_length(hf));*/
801 proto_register_subtree_array(ett, array_length(ett));
805 proto_reg_handoff_nmpi(void)
807 dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_NAMEQUERY,
808 dissect_nmpi, proto_nmpi);
809 dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_MAILSLOT,
810 dissect_nmpi, proto_nmpi);