2 * Routines for NetBIOS over IPX packet disassembly
3 * Gilbert Ramirez <gram@alumni.rice.edu>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
16 #include <wsutil/array.h>
17 #include "packet-ipx.h"
18 #include "packet-netbios.h"
20 void proto_register_nbipx(void);
21 void proto_reg_handoff_nbipx(void);
22 void proto_register_nmpi(void);
23 void proto_reg_handoff_nmpi(void);
25 static dissector_handle_t nbipx_handle
;
26 static dissector_handle_t nmpi_handle
;
28 static int proto_nbipx
;
29 static int hf_nbipx_packettype
;
30 static int hf_nbipx_name_flags
;
31 static int hf_nbipx_name_flags_group
;
32 static int hf_nbipx_name_flags_in_use
;
33 static int hf_nbipx_name_flags_registered
;
34 static int hf_nbipx_name_flags_duplicated
;
35 static int hf_nbipx_name_flags_deregistered
;
36 static int hf_nbipx_conn_control
;
37 static int hf_nbipx_conn_control_sys_packet
;
38 static int hf_nbipx_conn_control_ack
;
39 static int hf_nbipx_conn_control_attention
;
40 static int hf_nbipx_conn_control_end_msg
;
41 static int hf_nbipx_conn_control_resend
;
42 static int hf_nbipx_session_src_conn_id
;
43 static int hf_nbipx_session_dest_conn_id
;
44 static int hf_nbipx_session_send_seq_number
;
45 static int hf_nbipx_session_total_data_length
;
46 static int hf_nbipx_session_offset
;
47 static int hf_nbipx_session_data_length
;
48 static int hf_nbipx_session_recv_seq_number
;
49 static int hf_nbipx_session_bytes_received
;
50 static int hf_nbipx_ipx_network
;
51 static int hf_nbipx_opcode
;
52 static int hf_nbipx_name_type
;
53 static int hf_nbipx_messageid
;
56 static int ett_nbipx_conn_ctrl
;
57 static int ett_nbipx_name_type_flags
;
59 static void dissect_conn_control(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
);
61 static heur_dissector_list_t netbios_heur_subdissector_list
;
63 /* There is no RFC or public specification of Netware or Microsoft
64 * NetBIOS over IPX packets. I have had to decode the protocol myself,
65 * so there are holes and perhaps errors in this code. (gram)
67 * A list of "NovelNetBIOS" packet types can be found at
69 * http://web.archive.org/web/20150319134837/http://www.protocols.com/pbook/novel.htm#NetBIOS
71 * and at least some of those packet types appear to match what's in
74 * Note, however, that it appears that sometimes NBIPX packets have
75 * 8 IPX addresses at the beginning, and sometimes they don't.
77 * In the section on "NetBIOS Broadcasts", the document at
79 * http://www.microsoft.com/technet/network/ipxrout.asp
81 * says that "the NetBIOS over IPX Broadcast header" contains 8 IPX
82 * network numbers in the "IPX WAN broadcast header", and that it's
83 * followed by a "Name Type Flags" byte (giving information about the
84 * name being registered, deregistered, or checked), a "Data Stream
85 * Type 2" byte giving the type of operation (NBIPX_FIND_NAME,
86 * NBIPX_NAME_RECOGNIZED, or NBIPX_CHECK_NAME - the latter is called
87 * "Add Name"), and a 16-byte NetBIOS name.
89 * It also says that "NetBIOS over IPX Broadcast packets" have a
90 * packet type of 0x14 (20, or IPX_PACKET_TYPE_WANBCAST) and a
91 * socket number of 0x455 (IPX_SOCKET_NETBIOS).
93 * However, there are also non-broadcast packets that *also* contain
94 * the 8 IPX network numbers; they appear to be replies to broadcast
95 * packets, and have a packet type of 0x4 (IPX_PACKET_TYPE_PEP).
97 * Other IPX_PACKET_TYPE_PEP packets to and from the IPX_SOCKET_NETBIOS
98 * socket, however, *don't* have the 8 IPX network numbers; there does
99 * not seem to be any obvious algorithm to determine whether the packet
100 * has the addresses or not. Microsoft Knowledge Base article Q128335
101 * appears to show some code from the NBIPX implementation in NT that
102 * tries to determine the packet type - and it appears to use heuristics
103 * based on the packet length and on looking at what might be the NBIPX
104 * "Data Stream Type" byte depending on whether the packet has the 8
105 * IPX network numbers or not.
107 * So, for now, we treat *all* NBIPX packets as having a "Data Stream
108 * Type" byte, preceded by another byte of NBIPX information and
109 * followed by more NBIPX stuff, and assume that it's preceded by
110 * 8 IPX network numbers iff:
112 * the packet is a WAN Broadcast packet
116 * the packet is the right size for one of those PEP name replies
117 * (50 bytes) *and* has a name packet type as the Data Stream
118 * Type byte at the offset where that byte would be if the packet
119 * does have the 8 IPX network numbers at the beginning.
123 * http://ourworld.compuserve.com/homepages/TimothyDEvans/encap.htm
125 * indicates, under "NBIPX session packets", that "NBIPX session packets"
128 * 1 byte of NBIPX connection control flag
129 * 1 byte of data stream type
130 * 2 bytes of source connection ID
131 * 2 bytes of destination connection ID
132 * 2 bytes of send sequence number
133 * 2 bytes of total data length
135 * 2 bytes of data length
136 * 2 bytes of receive sequence number
137 * 2 bytes of "bytes received"
141 * Packets with a data stream type of NBIPX_DIRECTED_DATAGRAM appear to
142 * have, following the data stream type, two NetBIOS names, the first
143 * of which is the receiver's NetBIOS name and the second of which is
144 * the sender's NetBIOS name. The page at
146 * http://support.microsoft.com/support/kb/articles/q203/0/51.asp
148 * speaks of type 4 (PEP) packets as being used for "SAP, NetBIOS sessions
149 * and directed datagrams" and type 20 (WAN Broadcast) as being used for
150 * "NetBIOS name resolution broadcasts" (but nothing about the non-broadcast
151 * type 4 name resolution stuff).
153 * We assume that this means that, once you get past the 8 IPX network
154 * numbers if present:
156 * the first byte is a name type byte for the name packets
157 * and a connection control flag for the other packets;
159 * the second byte is a data stream type;
161 * the rest of the bytes are:
163 * the NetBIOS name being registered/deregistered/etc.,
166 * the two NetBIOS names, followed by the NetBIOS
167 * datagram, for NBIPX_DIRECTED_DATAGRAM packets;
169 * the session packet header, possibly followed by
170 * session data, for session packets.
172 * We don't know yet how to interpret NBIPX_STATUS_QUERY or
173 * NBIPX_STATUS_RESPONSE.
175 * For now, we treat the datagrams and session data as SMB stuff.
177 #define NBIPX_FIND_NAME 1
178 #define NBIPX_NAME_RECOGNIZED 2
179 #define NBIPX_CHECK_NAME 3
180 #define NBIPX_NAME_IN_USE 4
181 #define NBIPX_DEREGISTER_NAME 5
182 #define NBIPX_SESSION_DATA 6
183 #define NBIPX_SESSION_END 7
184 #define NBIPX_SESSION_END_ACK 8
185 #define NBIPX_STATUS_QUERY 9
186 #define NBIPX_STATUS_RESPONSE 10
187 #define NBIPX_DIRECTED_DATAGRAM 11
189 static const value_string nbipx_data_stream_type_vals
[] = {
190 {NBIPX_FIND_NAME
, "Find name"},
191 {NBIPX_NAME_RECOGNIZED
, "Name recognized"},
192 {NBIPX_CHECK_NAME
, "Check name"},
193 {NBIPX_NAME_IN_USE
, "Name in use"},
194 {NBIPX_DEREGISTER_NAME
, "Deregister name"},
195 {NBIPX_SESSION_DATA
, "Session data"},
196 {NBIPX_SESSION_END
, "Session end"},
197 {NBIPX_SESSION_END_ACK
, "Session end ACK"},
198 {NBIPX_STATUS_QUERY
, "Status query"},
199 {NBIPX_STATUS_RESPONSE
, "Status response"},
200 {NBIPX_DIRECTED_DATAGRAM
, "Directed datagram"},
207 #define INAME_CLAIM 0xf1
208 #define INAME_DELETE 0xf2
209 #define INAME_QUERY 0xf3
210 #define INAME_FOUND 0xf4
211 #define IMSG_HANGUP 0xf5
212 #define IMSLOT_SEND 0xfc
213 #define IMSLOT_FIND 0xfd
214 #define IMSLOT_NAME 0xfe
216 static const value_string nmpi_opcode_vals
[] = {
217 {INAME_CLAIM
, "Claim name"},
218 {INAME_DELETE
, "Delete name"},
219 {INAME_QUERY
, "Query name"},
220 {INAME_FOUND
, "Name found"},
221 {IMSG_HANGUP
, "Messenger hangup"},
222 {IMSLOT_SEND
, "Mailslot write"},
223 {IMSLOT_FIND
, "Find mailslot name"},
224 {IMSLOT_NAME
, "Mailslot name found"},
231 #define INTYPE_MACHINE 1
232 #define INTYPE_WORKGROUP 2
233 #define INTYPE_BROWSER 3
235 static const value_string nmpi_name_type_vals
[] = {
236 {INTYPE_MACHINE
, "Machine"},
237 {INTYPE_WORKGROUP
, "Workgroup"},
238 {INTYPE_BROWSER
, "Browser"},
242 static const true_false_string tfs_system_non_system
= { "System packet", "Non-system packet" };
245 add_routers(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
249 /* Eight routers are listed */
250 for (i
= 0; i
< 8; i
++) {
251 if (tvb_get_ntohl(tvb
, offset
) != 0) {
252 proto_tree_add_item(tree
, hf_nbipx_ipx_network
, tvb
, offset
, 4, ENC_NA
);
259 dissect_netbios_payload(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
261 heur_dtbl_entry_t
*hdtbl_entry
;
264 * Try the heuristic dissectors for NetBIOS; if none of them
265 * accept the packet, dissect it as data.
267 if (!dissector_try_heuristic(netbios_heur_subdissector_list
,
268 tvb
, pinfo
, tree
, &hdtbl_entry
, NULL
))
269 call_data_dissector(tvb
, pinfo
, tree
);
273 dissect_nbipx(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
276 proto_tree
*nbipx_tree
= NULL
;
277 proto_item
*ti
= NULL
;
280 proto_tree
*name_type_flag_tree
;
282 char name
[(NETBIOS_NAME_LEN
- 1)*4 + 1];
288 /* Reject the packet if data is NULL */
291 ipxh
= (ipxhdr_t
*)data
;
293 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "NBIPX");
294 col_clear(pinfo
->cinfo
, COL_INFO
);
296 if (ipxh
->ipx_type
== IPX_PACKET_TYPE_WANBCAST
) {
298 * This is a WAN Broadcast packet; we assume it will have
299 * 8 IPX addresses at the beginning.
304 * This isn't a WAN Broadcast packet, but it still might
305 * have the 8 addresses.
307 * If it's the right length for a name operation,
308 * and, if we assume it has routes, the packet type
309 * is a name operation, assume it has routes.
311 * NOTE: this will throw an exception if the byte that
312 * would be the packet type byte if this has the 8
313 * addresses isn't present; if that's the case, we don't
314 * know how to interpret this packet, so we can't dissect
317 has_routes
= false; /* start out assuming it doesn't */
318 if (tvb_reported_length(tvb
) == 50) {
319 packet_type
= tvb_get_uint8(tvb
, offset
+ 32 + 1);
320 switch (packet_type
) {
322 case NBIPX_FIND_NAME
:
323 case NBIPX_NAME_RECOGNIZED
:
324 case NBIPX_CHECK_NAME
:
325 case NBIPX_NAME_IN_USE
:
326 case NBIPX_DEREGISTER_NAME
:
334 ti
= proto_tree_add_item(tree
, proto_nbipx
, tvb
, 0,
336 nbipx_tree
= proto_item_add_subtree(ti
, ett_nbipx
);
341 add_routers(nbipx_tree
, tvb
, 0);
345 packet_type
= tvb_get_uint8(tvb
, offset
+ 1);
347 switch (packet_type
) {
349 case NBIPX_FIND_NAME
:
350 case NBIPX_NAME_RECOGNIZED
:
351 case NBIPX_CHECK_NAME
:
352 case NBIPX_NAME_IN_USE
:
353 case NBIPX_DEREGISTER_NAME
:
354 name_type
= get_netbios_name(tvb
, offset
+2, name
, (NETBIOS_NAME_LEN
- 1)*4 + 1);
355 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s<%02x>",
356 val_to_str_const(packet_type
, nbipx_data_stream_type_vals
, "Unknown"),
360 tf
= proto_tree_add_item(nbipx_tree
, hf_nbipx_name_flags
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
361 name_type_flag_tree
= proto_item_add_subtree(tf
, ett_nbipx_name_type_flags
);
363 proto_tree_add_item(name_type_flag_tree
, hf_nbipx_name_flags_group
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
364 proto_tree_add_item(name_type_flag_tree
, hf_nbipx_name_flags_in_use
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
365 proto_tree_add_item(name_type_flag_tree
, hf_nbipx_name_flags_registered
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
366 proto_tree_add_item(name_type_flag_tree
, hf_nbipx_name_flags_duplicated
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
367 proto_tree_add_item(name_type_flag_tree
, hf_nbipx_name_flags_deregistered
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
371 proto_tree_add_uint(nbipx_tree
, hf_nbipx_packettype
, tvb
, offset
, 1, packet_type
);
375 netbios_add_name("Name", tvb
, offset
, nbipx_tree
);
376 offset
+= NETBIOS_NAME_LEN
;
379 * No payload to be interpreted by another protocol.
384 case NBIPX_SESSION_DATA
:
385 case NBIPX_SESSION_END
:
386 case NBIPX_SESSION_END_ACK
:
387 col_set_str(pinfo
->cinfo
, COL_INFO
,
388 val_to_str_const(packet_type
, nbipx_data_stream_type_vals
, "Unknown"));
390 dissect_conn_control(tvb
, offset
, nbipx_tree
);
393 proto_tree_add_uint(nbipx_tree
, hf_nbipx_packettype
, tvb
, offset
, 1, packet_type
);
396 proto_tree_add_item(nbipx_tree
, hf_nbipx_session_src_conn_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
399 proto_tree_add_item(nbipx_tree
, hf_nbipx_session_dest_conn_id
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
402 proto_tree_add_item(nbipx_tree
, hf_nbipx_session_send_seq_number
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
405 proto_tree_add_item(nbipx_tree
, hf_nbipx_session_total_data_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
408 proto_tree_add_item(nbipx_tree
, hf_nbipx_session_offset
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
411 proto_tree_add_item(nbipx_tree
, hf_nbipx_session_data_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
414 proto_tree_add_item(nbipx_tree
, hf_nbipx_session_recv_seq_number
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
417 proto_tree_add_item(nbipx_tree
, hf_nbipx_session_bytes_received
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
421 * We may have payload to dissect.
426 case NBIPX_DIRECTED_DATAGRAM
:
427 col_set_str(pinfo
->cinfo
, COL_INFO
,
428 val_to_str_const(packet_type
, nbipx_data_stream_type_vals
, "Unknown"));
430 dissect_conn_control(tvb
, offset
, nbipx_tree
);
433 proto_tree_add_uint(nbipx_tree
, hf_nbipx_packettype
, tvb
, offset
, 1, packet_type
);
437 netbios_add_name("Receiver's Name", tvb
, offset
,
439 offset
+= NETBIOS_NAME_LEN
;
442 netbios_add_name("Sender's Name", tvb
, offset
,
444 offset
+= NETBIOS_NAME_LEN
;
447 * We may have payload to dissect.
453 col_set_str(pinfo
->cinfo
, COL_INFO
,
454 val_to_str_const(packet_type
, nbipx_data_stream_type_vals
, "Unknown"));
457 * We don't know what the first byte is.
462 * The second byte is a data stream type byte.
464 proto_tree_add_uint(nbipx_tree
, hf_nbipx_packettype
, tvb
, offset
, 1, packet_type
);
468 * We don't know what the rest of the packet is.
474 * Set the length of the NBIPX tree item.
477 proto_item_set_len(ti
, offset
);
479 if (has_payload
&& tvb_offset_exists(tvb
, offset
)) {
480 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
481 dissect_netbios_payload(next_tvb
, pinfo
, tree
);
484 return tvb_captured_length(tvb
);
488 dissect_conn_control(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
)
494 ti
= proto_tree_add_item(tree
, hf_nbipx_conn_control
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
495 cc_tree
= proto_item_add_subtree(ti
, ett_nbipx_conn_ctrl
);
496 proto_tree_add_item(cc_tree
, hf_nbipx_conn_control_sys_packet
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
497 proto_tree_add_item(cc_tree
, hf_nbipx_conn_control_ack
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
498 proto_tree_add_item(cc_tree
, hf_nbipx_conn_control_attention
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
499 proto_tree_add_item(cc_tree
, hf_nbipx_conn_control_end_msg
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
500 proto_tree_add_item(cc_tree
, hf_nbipx_conn_control_resend
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
505 proto_register_nbipx(void)
507 static hf_register_info hf
[] = {
508 { &hf_nbipx_packettype
,
509 { "Packet Type", "nmpi.packettype",
510 FT_UINT8
, BASE_HEX
, VALS(nbipx_data_stream_type_vals
), 0,
513 { &hf_nbipx_name_flags
,
514 { "Name type flag", "nmpi.name_flags",
515 FT_UINT8
, BASE_HEX
, NULL
, 0,
518 { &hf_nbipx_name_flags_group
,
519 { "Name", "nmpi.name_flags.group",
520 FT_BOOLEAN
, 8, TFS(&tfs_group_unique_name
), 0x80,
523 { &hf_nbipx_name_flags_in_use
,
524 { "In use", "nmpi.name_flags.in_use",
525 FT_BOOLEAN
, 8, TFS(&tfs_used_notused
), 0x40,
528 { &hf_nbipx_name_flags_registered
,
529 { "Registered", "nmpi.name_flags.registered",
530 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x04,
533 { &hf_nbipx_name_flags_duplicated
,
534 { "Duplicated", "nmpi.name_flags.duplicated",
535 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x02,
538 { &hf_nbipx_name_flags_deregistered
,
539 { "Deregistered", "nmpi.name_flags.deregistered",
540 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x01,
543 { &hf_nbipx_conn_control
,
544 { "Connection control", "nmpi.conn_control",
545 FT_UINT8
, BASE_HEX
, NULL
, 0,
548 { &hf_nbipx_conn_control_sys_packet
,
549 { "Packet", "nmpi.conn_control.sys_packet",
550 FT_BOOLEAN
, 8, TFS(&tfs_system_non_system
), 0x80,
553 { &hf_nbipx_conn_control_ack
,
554 { "Acknowledgement", "nmpi.conn_control.ack",
555 FT_BOOLEAN
, 8, TFS(&tfs_required_not_required
), 0x40,
558 { &hf_nbipx_conn_control_attention
,
559 { "Attention", "nmpi.conn_control.attention",
560 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x20,
563 { &hf_nbipx_conn_control_end_msg
,
564 { "End of message", "nmpi.conn_control.end_msg",
565 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x10,
568 { &hf_nbipx_conn_control_resend
,
569 { "Resend", "nmpi.conn_control.resend",
570 FT_BOOLEAN
, 8, TFS(&tfs_yes_no
), 0x08,
573 { &hf_nbipx_session_src_conn_id
,
574 { "Source connection ID", "nmpi.session.src_conn_id",
575 FT_UINT16
, BASE_HEX
, NULL
, 0,
578 { &hf_nbipx_session_dest_conn_id
,
579 { "Destination connection ID", "nmpi.session.dest_conn_id",
580 FT_UINT16
, BASE_HEX
, NULL
, 0,
583 { &hf_nbipx_session_send_seq_number
,
584 { "Send sequence number", "nmpi.session.send_seq_number",
585 FT_UINT16
, BASE_DEC
, NULL
, 0,
588 { &hf_nbipx_session_total_data_length
,
589 { "Total data length", "nmpi.session.total_data_length",
590 FT_UINT16
, BASE_DEC
, NULL
, 0,
593 { &hf_nbipx_session_offset
,
594 { "Offset", "nmpi.session.offset",
595 FT_UINT16
, BASE_DEC
, NULL
, 0,
598 { &hf_nbipx_session_data_length
,
599 { "Data length", "nmpi.session.data_length",
600 FT_UINT16
, BASE_DEC
, NULL
, 0,
603 { &hf_nbipx_session_recv_seq_number
,
604 { "Receive sequence number", "nmpi.session.recv_seq_number",
605 FT_UINT16
, BASE_DEC
, NULL
, 0,
608 { &hf_nbipx_session_bytes_received
,
609 { "Bytes received", "nmpi.session.bytes_received",
610 FT_UINT16
, BASE_DEC
, NULL
, 0,
613 { &hf_nbipx_ipx_network
,
614 { "IPX Network", "nmpi.ipx_network",
615 FT_IPXNET
, BASE_NONE
, NULL
, 0,
619 { "Opcode", "nmpi.opcode",
620 FT_UINT8
, BASE_HEX
, VALS(nmpi_opcode_vals
), 0,
623 { &hf_nbipx_name_type
,
624 { "Name Type", "nmpi.name_type",
625 FT_UINT8
, BASE_HEX
, VALS(nmpi_name_type_vals
), 0,
628 { &hf_nbipx_messageid
,
629 { "Message ID", "nmpi.messageid",
630 FT_UINT16
, BASE_HEX
, NULL
, 0,
635 static int *ett
[] = {
637 &ett_nbipx_conn_ctrl
,
638 &ett_nbipx_name_type_flags
,
641 proto_nbipx
= proto_register_protocol("NetBIOS over IPX", "NBIPX", "nbipx");
642 proto_register_field_array(proto_nbipx
, hf
, array_length(hf
));
643 proto_register_subtree_array(ett
, array_length(ett
));
645 nbipx_handle
= register_dissector("nbipx", dissect_nbipx
, proto_nbipx
);
649 proto_reg_handoff_nbipx(void)
651 dissector_add_uint("ipx.socket", IPX_SOCKET_NETBIOS
, nbipx_handle
);
652 netbios_heur_subdissector_list
= find_heur_dissector_list("netbios");
656 * Microsoft appear to have something they call "direct hosting", where
657 * SMB - and, I infer, related stuff, such as name resolution - runs
658 * directly over IPX. (In Windows 2000, they also run SMB directly over
659 * TCP, on port 445, and that also appears to be called "direct hosting".
660 * Wireshark handles SMB-over-TCP.)
664 * http://support.microsoft.com/support/kb/articles/q203/0/51.asp
666 * speaks of NMPI - the "Name Management Protocol on IPX" - as being
667 * "Microsoft's protocol for name management support when you use IPX
668 * without the NetBIOS interface," and says that "This process of routing
669 * the SMB protocol directly through IPX is known as Direct Hosting."
671 * It speaks of IPX socket 0x551 as being for NMPI; we define it as
672 * IPX_SOCKET_NWLINK_SMB_NAMEQUERY.
674 * We also define IPX_SOCKET_NWLINK_SMB_DGRAM as 0x0553 and define
675 * IPX_SOCKET_NWLINK_SMB_BROWSE as 0x0555 (with a "? not sure on this"
676 * comment after the latter one).
678 * We have seen at least some browser announcements on IPX socket 0x553;
679 * those are WAN broadcast packets, complete with 8 IPX network
680 * numbers, and with the header containing the usual two NetBIOS names
681 * that show up in NetBIOS datagrams.
683 * Network Monitor calls those packets NMPI packets, even though they're
684 * on socket 0x553, not socket 0x551, and contain SMB datagrams, not name
685 * resolution packets.
687 * At least some of this is discussed in the "SMBPUB.DOC" Word document
690 * ftp://ftp.microsoft.com/developr/drg/CIFS/smbpub.zip
692 * which can also be found in text form at
694 * http://www.samba.org/samba/ftp/specs/smbpub.txt
696 * which says that for "connectionless IPX transport" the sockets that
699 * SMB_SERVER_SOCKET (0x550) - SMB requests from clients
700 * SMB_NAME_SOCKET (0x551) - name claims and name query messages
701 * REDIR_SOCKET (0x552) - used by the redirector (client) for
702 * sending SMB requests and receiving SMB replies
703 * MAILSLOT_SOCKET (0x553) - used by the redirector and browser
704 * for mailslot datagrams
705 * MESSENGER_SOCKET (0x554) - used by the redirector to send
706 * messages from client to client
708 * Name claim/query packets, and mailslot datagrams, are:
710 * 8 IPX network addresses
712 * 1 byte of name type
713 * 2 bytes of message ID
714 * 16 bytes of name being sought or claimed
715 * 16 bytes of requesting machine
717 * The opcode is one of:
719 * INAME_CLAIM (0xf1) - server name claim message
720 * INAME_DELETE (0xf2) - relinquish server name
721 * INAME_QUERY (0xf3) - locate server name
722 * INAME_FOUND (0xf4) - response to INAME_QUERY
723 * IMSG_HANGUP (0xf5) - messenger hangup
724 * IMSLOT_SEND (0xfc) - mailslot write
725 * IMSLOT_FIND (0xfd) - find name for mailslot write
726 * IMSLOT_NAME (0xfe) - response to IMSLOT_FIND
728 * The name type is one of:
734 static int proto_nmpi
;
737 static int ett_nmpi_name_type_flags
;
741 dissect_nmpi(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
743 proto_tree
*nmpi_tree
= NULL
;
747 char name
[(NETBIOS_NAME_LEN
- 1)*4 + 1];
749 char node_name
[(NETBIOS_NAME_LEN
- 1)*4 + 1];
750 /*int node_name_type = 0;*/
753 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "NMPI");
754 col_clear(pinfo
->cinfo
, COL_INFO
);
757 ti
= proto_tree_add_item(tree
, proto_nmpi
, tvb
, offset
, 68,
759 nmpi_tree
= proto_item_add_subtree(ti
, ett_nmpi
);
761 add_routers(nmpi_tree
, tvb
, offset
);
766 * XXX - we don't use "node_name" or "node_name_type".
768 opcode
= tvb_get_uint8(tvb
, offset
);
769 name_type
= get_netbios_name(tvb
, offset
+4, name
, (NETBIOS_NAME_LEN
- 1)*4 + 1);
770 /*node_name_type = */get_netbios_name(tvb
, offset
+20, node_name
, (NETBIOS_NAME_LEN
- 1)*4 + 1);
775 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Claim name %s<%02x>",
780 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Delete name %s<%02x>",
785 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Query name %s<%02x>",
790 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Name %s<%02x> found",
795 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
796 "Messenger hangup on %s<%02x>", name
, name_type
);
800 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
801 "Mailslot write to %s<%02x>", name
, name_type
);
805 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
806 "Find mailslot name %s<%02x>", name
, name_type
);
810 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
811 "Mailslot name %s<%02x> found", name
, name_type
);
815 col_add_fstr(pinfo
->cinfo
, COL_INFO
,
816 "Unknown NMPI op 0x%02x: name %s<%02x>",
817 opcode
, name
, name_type
);
822 proto_tree_add_item(nmpi_tree
, hf_nbipx_opcode
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
823 proto_tree_add_item(nmpi_tree
, hf_nbipx_name_type
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
824 proto_tree_add_item(nmpi_tree
, hf_nbipx_messageid
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
825 netbios_add_name("Requested name", tvb
, offset
+4, nmpi_tree
);
826 netbios_add_name("Source name", tvb
, offset
+20, nmpi_tree
);
829 offset
+= 1 + 1 + 2 + NETBIOS_NAME_LEN
+ NETBIOS_NAME_LEN
;
831 if (opcode
== IMSLOT_SEND
&& tvb_offset_exists(tvb
, offset
)) {
832 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
833 dissect_netbios_payload(next_tvb
, pinfo
, tree
);
835 return tvb_captured_length(tvb
);
839 proto_register_nmpi(void)
842 static hf_register_info hf[] = {
844 { "Name", "nmpi.abbreviation", TYPE, VALS_POINTER }},
846 static int *ett
[] = {
848 &ett_nmpi_name_type_flags
,
851 proto_nmpi
= proto_register_protocol("Name Management Protocol over IPX",
853 /* proto_register_field_array(proto_nmpi, hf, array_length(hf));*/
854 proto_register_subtree_array(ett
, array_length(ett
));
856 nmpi_handle
= register_dissector("nmpi", dissect_nmpi
, proto_nmpi
);
860 proto_reg_handoff_nmpi(void)
862 dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_NAMEQUERY
,
864 dissector_add_uint("ipx.socket", IPX_SOCKET_NWLINK_SMB_MAILSLOT
,
869 * Editor modelines - https://www.wireshark.org/tools/modelines.html
874 * indent-tabs-mode: t
877 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
878 * :indentSize=8:tabSize=8:noTabs=false: