2 * Routines for NetBIOS over IPX packet disassembly
3 * Gilbert Ramirez <gram@xiexie.org>
5 * $Id: packet-nbipx.c,v 1.36 2001/01/15 04:39:28 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;
54 dissect_nbipx_ns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
57 dissect_nbipx_dg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
59 /* There is no RFC or public specification of Netware or Microsoft
60 * NetBIOS over IPX packets. I have had to decode the protocol myself,
61 * so there are holes and perhaps errors in this code. (gram)
63 * A list of "NovelNetBIOS" packet types can be found at
65 * http://www.protocols.com/pbook/novel.htm#NetBIOS
67 * and at least some of those packet types appear to match what's in
70 * Note, however, that the offset of the packet type in an NBIPX packet
71 * *DEPENDS ON THE PACKET TYPE*; "Find name" and "Name recognized" have
72 * it at one offset, "Directed datagram" has it at another. Does the
73 * NBIPX code base it on the length, or what? Non-broadcast directed
74 * datagram packets have an IPX type of "IPX", just as "Find name" and
75 * "Name recognized" do.... For now, we base it on the length.
77 #define NBIPX_FIND_NAME 1
78 #define NBIPX_NAME_RECOGNIZED 2
79 #define NBIPX_CHECK_NAME 3
80 #define NBIPX_NAME_IN_USE 4
81 #define NBIPX_DEREGISTER_NAME 5
82 #define NBIPX_SESSION_DATA 6
83 #define NBIPX_SESSION_END 7
84 #define NBIPX_SESSION_END_ACK 8
85 #define NBIPX_STATUS_QUERY 9
86 #define NBIPX_STATUS_RESPONSE 10
87 #define NBIPX_DIRECTED_DATAGRAM 11
89 static const value_string nbipx_data_stream_type_vals[] = {
90 {NBIPX_FIND_NAME, "Find name"},
91 {NBIPX_NAME_RECOGNIZED, "Name recognized"},
92 {NBIPX_CHECK_NAME, "Check name"},
93 {NBIPX_NAME_IN_USE, "Name in use"},
94 {NBIPX_DEREGISTER_NAME, "Deregister name"},
95 {NBIPX_SESSION_DATA, "Session data"},
96 {NBIPX_SESSION_END, "Session end"},
97 {NBIPX_SESSION_END_ACK, "Session end ACK"},
98 {NBIPX_STATUS_QUERY, "Status query"},
99 {NBIPX_STATUS_RESPONSE, "Status response"},
100 {NBIPX_DIRECTED_DATAGRAM, "Directed datagram"},
104 #define NWLINK_NAME_QUERY 1
106 #define NWLINK_NETBIOS_DATAGRAM 3
108 static const value_string nwlink_data_stream_type_vals[] = {
109 {NWLINK_NAME_QUERY, "Name query"},
111 {NWLINK_NETBIOS_DATAGRAM, "NetBIOS datagram"},
117 dissect_nbipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
119 CHECK_DISPLAY_AS_DATA(proto_nbipx, tvb, pinfo, tree);
121 pinfo->current_proto = "NBIPX";
123 if (check_col(pinfo->fd, COL_PROTOCOL))
124 col_set_str(pinfo->fd, COL_PROTOCOL, "NBIPX");
125 if (check_col(pinfo->fd, COL_INFO))
126 col_clear(pinfo->fd, COL_INFO);
129 * As said above, we look at the length of the packet to decide
130 * whether to treat it as a name-service packet or a datagram
131 * (the packet type would tell us, but it's at a *DIFFERENT
132 * LOCATION* in different types of packet...).
134 if (tvb_reported_length(tvb) == 50)
135 dissect_nbipx_ns(tvb, pinfo, tree);
137 dissect_nbipx_dg(tvb, pinfo, tree);
141 add_routers(proto_tree *tree, tvbuff_t *tvb, int offset)
147 /* Eight routers are listed */
148 for (i = 0; i < 8; i++) {
149 rtr_offset = offset + (i << 2);
150 tvb_memcpy(tvb, (guint8 *)&router, rtr_offset, 4);
152 proto_tree_add_text(tree, tvb, rtr_offset, 4,
154 ipxnet_to_string((guint8*)&router));
160 dissect_nbipx_ns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
162 proto_tree *nbipx_tree;
166 guint8 name_type_flag;
167 proto_tree *name_type_flag_tree;
169 char name[(NETBIOS_NAME_LEN - 1)*4 + 1];
172 name_type_flag = tvb_get_guint8(tvb, offset+32);
173 packet_type = tvb_get_guint8(tvb, offset+33);
174 name_type = get_netbios_name(tvb, offset+34, name);
176 if (check_col(pinfo->fd, COL_INFO)) {
177 switch (packet_type) {
178 case NBIPX_FIND_NAME:
179 case NBIPX_NAME_RECOGNIZED:
180 case NBIPX_CHECK_NAME:
181 case NBIPX_NAME_IN_USE:
182 case NBIPX_DEREGISTER_NAME:
183 col_add_fstr(pinfo->fd, COL_INFO, "%s %s<%02x>",
184 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"),
189 col_add_fstr(pinfo->fd, COL_INFO, "%s",
190 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"));
196 ti = proto_tree_add_item(tree, proto_nbipx, tvb, offset, 50,
198 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
200 add_routers(nbipx_tree, tvb, offset);
202 tf = proto_tree_add_text(nbipx_tree, tvb, offset+32, 1,
203 "Name type flag: 0x%02x", name_type_flag);
204 name_type_flag_tree = proto_item_add_subtree(tf,
205 ett_nbipx_name_type_flags);
206 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
208 decode_boolean_bitfield(name_type_flag, 0x80, 8,
209 "Group name", "Unique name"));
210 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
212 decode_boolean_bitfield(name_type_flag, 0x40, 8,
213 "Name in use", "Name not used"));
214 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
216 decode_boolean_bitfield(name_type_flag, 0x04, 8,
217 "Name registered", "Name not registered"));
218 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
220 decode_boolean_bitfield(name_type_flag, 0x02, 8,
221 "Name duplicated", "Name not duplicated"));
222 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
224 decode_boolean_bitfield(name_type_flag, 0x01, 8,
225 "Name deregistered", "Name not deregistered"));
227 proto_tree_add_text(nbipx_tree, tvb, offset+33, 1,
228 "Packet Type: %s (%02X)",
229 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"),
232 netbios_add_name("Name", tvb, offset + 34, nbipx_tree);
237 dissect_nbipx_dg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
239 proto_tree *nbipx_tree = NULL;
246 const guint8 *next_pd;
249 if (check_col(pinfo->fd, COL_INFO))
250 col_add_fstr(pinfo->fd, COL_INFO, "NetBIOS datagram over NBIPX");
253 ti = proto_tree_add_item(tree, proto_nbipx, tvb, offset,
254 2+NETBIOS_NAME_LEN+NETBIOS_NAME_LEN, FALSE);
255 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
257 conn_control = tvb_get_guint8(tvb, offset);
258 ti = proto_tree_add_text(nbipx_tree, tvb, offset, 1,
259 "Connection control: 0x%02x", conn_control);
260 cc_tree = proto_item_add_subtree(ti, ett_nbipx_conn_ctrl);
261 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
262 decode_boolean_bitfield(conn_control, 0x80, 8,
263 "System packet", "Non-system packet"));
264 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
265 decode_boolean_bitfield(conn_control, 0x40, 8,
266 "Send acknowledge", "No send acknowledge"));
267 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
268 decode_boolean_bitfield(conn_control, 0x20, 8,
269 "Attention", "No attention"));
270 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
271 decode_boolean_bitfield(conn_control, 0x10, 8,
272 "End of message", "No end of message"));
273 proto_tree_add_text(cc_tree, tvb, offset, 1, "%s",
274 decode_boolean_bitfield(conn_control, 0x08, 8,
275 "Resend", "No resend"));
279 packet_type = tvb_get_guint8(tvb, offset);
281 proto_tree_add_text(nbipx_tree, tvb, offset, 1,
282 "Packet Type: %s (%02X)",
283 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"),
289 netbios_add_name("Receiver's Name", tvb, offset, nbipx_tree);
290 offset += NETBIOS_NAME_LEN;
293 netbios_add_name("Sender's Name", tvb, offset, nbipx_tree);
294 offset += NETBIOS_NAME_LEN;
296 if (tvb_offset_exists(tvb, offset)) {
297 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
298 tvb_compat(next_tvb, &next_pd, &next_offset);
299 dissect_smb(next_pd, next_offset, pinfo->fd, tree,
300 tvb_length(next_tvb));
305 dissect_nwlink_dg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
307 proto_tree *nbipx_tree;
311 guint8 name_type_flag;
312 proto_tree *name_type_flag_tree;
314 char name[(NETBIOS_NAME_LEN - 1)*4 + 1];
316 char node_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
317 int node_name_type = 0;
319 const guint8 *next_pd;
323 * XXX - we don't use "node_name" or "node_name_type".
325 name_type_flag = tvb_get_guint8(tvb, offset+32);
326 packet_type = tvb_get_guint8(tvb, offset+33);
327 name_type = get_netbios_name(tvb, offset+36, name);
328 node_name_type = get_netbios_name(tvb, offset+52, node_name);
331 * XXX - if this is labeled as "NWLink", rather than "NBIPX",
332 * should it be a separate protocol?
334 if (check_col(pinfo->fd, COL_PROTOCOL))
335 col_set_str(pinfo->fd, COL_PROTOCOL, "NWLink");
337 if (check_col(pinfo->fd, COL_INFO)) {
339 * XXX - Microsoft Network Monitor thinks that the octet
340 * at 32 is a packet type, e.g. "mailslot write" for
341 * browser announcements, and that the octet at 33 is a
342 * name type, in the sense of the 16th byte of a
345 * A name type of 2 shows up in a "host announcement",
346 * and a name type of 3 shows up in a "local master
347 * annoumcement", so maybe that field really *is* a
348 * name type - the fact that it's not associated with
349 * any of the NetBIOS names in the packet nonwithstanding.
351 * I haven't seen any packets with the name type octet
352 * being anything other than 2 or 3, so I don't know
353 * whether those are name service operations; however,
354 * given that NWLink, unlike socket-0x0455 NBIPX,
355 * has separate sockets for name queries and datagrams,
356 * it may be that this really is a name type, and that
357 * these are all datagrams, not name queries.
359 switch (packet_type) {
360 case NWLINK_NAME_QUERY:
361 col_add_fstr(pinfo->fd, COL_INFO, "Name Query for %s<%02x>",
367 col_add_fstr(pinfo->fd, COL_INFO, "SMB over NBIPX");
370 case NWLINK_NETBIOS_DATAGRAM:
371 /* Datagram? (Where did we see this?) */
372 col_add_fstr(pinfo->fd, COL_INFO, "NetBIOS datagram over NBIPX");
376 col_set_str(pinfo->fd, COL_INFO, "NetBIOS over IPX (NWLink)");
382 ti = proto_tree_add_item(tree, proto_nbipx, tvb, offset, 68, FALSE);
383 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
385 add_routers(nbipx_tree, tvb, offset);
388 * XXX - is "packet_type" really a packet type? See
391 if (packet_type != NWLINK_SMB &&
392 packet_type != NWLINK_NETBIOS_DATAGRAM) {
393 tf = proto_tree_add_text(nbipx_tree, tvb, offset+32, 1,
394 "Name type flag: 0x%02x",
396 name_type_flag_tree = proto_item_add_subtree(tf,
397 ett_nbipx_name_type_flags);
398 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
400 decode_boolean_bitfield(name_type_flag, 0x80, 8,
401 "Group name", "Unique name"));
402 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
404 decode_boolean_bitfield(name_type_flag, 0x40, 8,
405 "Name in use", "Name not used"));
406 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
408 decode_boolean_bitfield(name_type_flag, 0x04, 8,
409 "Name registered", "Name not registered"));
410 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
412 decode_boolean_bitfield(name_type_flag, 0x02, 8,
413 "Name duplicated", "Name not duplicated"));
414 proto_tree_add_text(name_type_flag_tree, tvb, offset+32,
416 decode_boolean_bitfield(name_type_flag, 0x01, 8,
417 "Name deregistered", "Name not deregistered"));
419 netbios_add_name("Group name", tvb, offset+36,
421 netbios_add_name("Node name", tvb, offset+52,
423 proto_tree_add_text(nbipx_tree, tvb, offset+33, 1,
424 "Packet Type: %s (%02X)",
425 val_to_str(packet_type, nwlink_data_stream_type_vals, "Unknown"),
428 proto_tree_add_text(nbipx_tree, tvb, offset+32, 1,
429 "Packet type: 0x%02x", name_type_flag);
430 proto_tree_add_text(nbipx_tree, tvb, offset+33, 1,
431 "Name Type: %s (0x%02x)",
432 netbios_name_type_descr(packet_type),
434 proto_tree_add_text(nbipx_tree, tvb, offset+34, 2,
435 "Message ID: 0x%04x",
436 tvb_get_letohs(tvb, offset+34));
437 netbios_add_name("Requested name", tvb, offset+36,
439 netbios_add_name("Source name", tvb, offset+52,
446 if (tvb_offset_exists(tvb, offset)) {
447 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
449 switch (packet_type) {
451 case NWLINK_NETBIOS_DATAGRAM:
452 tvb_compat(next_tvb, &next_pd, &next_offset);
453 dissect_smb(next_pd, next_offset, pinfo->fd, tree,
454 tvb_length(next_tvb));
458 dissect_data(next_tvb, 0, pinfo, tree);
465 proto_register_nbipx(void)
467 /* static hf_register_info hf[] = {
469 { "Name", "nbipx.abbreviation", TYPE, VALS_POINTER }},
471 static gint *ett[] = {
473 &ett_nbipx_conn_ctrl,
474 &ett_nbipx_name_type_flags,
477 proto_nbipx = proto_register_protocol("NetBIOS over IPX",
479 /* proto_register_field_array(proto_nbipx, hf, array_length(hf));*/
480 proto_register_subtree_array(ett, array_length(ett));
482 register_dissector("nbipx", dissect_nbipx, proto_nbipx);
486 proto_reg_handoff_nbipx(void)
488 dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_DGRAM,
489 dissect_nwlink_dg, proto_nbipx);