2 * Routines for NetBIOS over IPX packet disassembly
3 * Gilbert Ramirez <gram@xiexie.org>
5 * $Id: packet-nbipx.c,v 1.18 2000/02/15 21:02:35 gram 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>
37 #include "packet-ipx.h"
38 #include "packet-netbios.h"
39 #include "packet-smb.h"
41 static int proto_nbipx = -1;
43 static gint ett_nbipx = -1;
44 static gint ett_nbipx_name_type_flags = -1;
52 dissect_nbipx_ns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
55 dissect_nbipx_dg(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
58 /* There is no RFC or public specification of Netware or Microsoft
59 * NetBIOS over IPX packets. I have had to decode the protocol myself,
60 * so there are holes and perhaps errors in this code. (gram)
62 * A list of "NovelNetBIOS" packet types can be found at
64 * http://www.protocols.com/pbook/novel.htm#NetBIOS
66 * and at least some of those packet types appear to match what's in
69 * Note, however, that the offset of the packet type in an NBIPX packet
70 * *DEPENDS ON THE PACKET TYPE*; "Find name" and "Name recognized" have
71 * it at one offset, "Directed datagram" has it at another. Does the
72 * NBIPX code base it on the length, or what? Non-broadcast directed
73 * datagram packets have an IPX type of "IPX", just as "Find name" and
74 * "Name recognized" do.... For now, we base it on the length.
76 #define NBIPX_FIND_NAME 1
77 #define NBIPX_NAME_RECOGNIZED 2
78 #define NBIPX_CHECK_NAME 3
79 #define NBIPX_NAME_IN_USE 4
80 #define NBIPX_DEREGISTER_NAME 5
81 #define NBIPX_SESSION_DATA 6
82 #define NBIPX_SESSION_END 7
83 #define NBIPX_SESSION_END_ACK 8
84 #define NBIPX_STATUS_QUERY 9
85 #define NBIPX_STATUS_RESPONSE 10
86 #define NBIPX_DIRECTED_DATAGRAM 11
88 static const value_string nbipx_data_stream_type_vals[] = {
89 {NBIPX_FIND_NAME, "Find name"},
90 {NBIPX_NAME_RECOGNIZED, "Name recognized"},
91 {NBIPX_CHECK_NAME, "Check name"},
92 {NBIPX_NAME_IN_USE, "Name in use"},
93 {NBIPX_DEREGISTER_NAME, "Deregister name"},
94 {NBIPX_SESSION_DATA, "Session data"},
95 {NBIPX_SESSION_END, "Session end"},
96 {NBIPX_SESSION_END_ACK, "Session end ACK"},
97 {NBIPX_STATUS_QUERY, "Status query"},
98 {NBIPX_STATUS_RESPONSE, "Status response"},
99 {NBIPX_DIRECTED_DATAGRAM, "Directed datagram"},
103 #define NWLINK_NAME_QUERY 1
105 #define NWLINK_NETBIOS_DATAGRAM 3
107 static const value_string nwlink_data_stream_type_vals[] = {
108 {NWLINK_NAME_QUERY, "Name query"},
110 {NWLINK_NETBIOS_DATAGRAM, "NetBIOS datagram"},
116 dissect_nbipx(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
118 int max_data = pi.captured_len - offset;
120 if (check_col(fd, COL_PROTOCOL))
121 col_add_str(fd, COL_PROTOCOL, "NBIPX");
124 * As said above, we look at the length of the packet to decide
125 * whether to treat it as a name-service packet or a datagram
126 * (the packet type would tell us, but it's at a *DIFFERENT
127 * LOCATION* in different types of packet...).
129 if (END_OF_FRAME == 50)
130 dissect_nbipx_ns(pd, offset, fd, tree, max_data);
132 dissect_nbipx_dg(pd, offset, fd, tree, max_data);
136 add_routers(proto_tree *tree, const u_char *pd, int offset)
142 /* Eight routers are listed */
143 for (i = 0; i < 8; i++) {
144 rtr_offset = offset + (i << 2);
145 memcpy(&router, &pd[rtr_offset], 4);
147 proto_tree_add_text(tree, rtr_offset, 4, "IPX Network: %s",
148 ipxnet_to_string((guint8*)&router));
154 dissect_nbipx_ns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
157 proto_tree *nbipx_tree;
160 guint8 name_type_flag;
161 proto_tree *name_type_flag_tree;
163 char name[(NETBIOS_NAME_LEN - 1)*4 + 1];
166 name_type_flag = pd[offset+32];
167 packet_type = pd[offset+33];
168 name_type = get_netbios_name(pd, offset+34, name);
170 if (check_col(fd, COL_INFO)) {
171 switch (packet_type) {
172 case NBIPX_FIND_NAME:
173 case NBIPX_NAME_RECOGNIZED:
174 case NBIPX_CHECK_NAME:
175 case NBIPX_NAME_IN_USE:
176 case NBIPX_DEREGISTER_NAME:
177 col_add_fstr(fd, COL_INFO, "%s %s<%02x>",
178 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"),
183 col_add_fstr(fd, COL_INFO, "%s",
184 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"));
190 ti = proto_tree_add_item(tree, proto_nbipx, offset, 50, NULL);
191 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
193 add_routers(nbipx_tree, pd, offset);
195 tf = proto_tree_add_text(nbipx_tree, offset+32, 1,
196 "Name type flag: 0x%02x", name_type_flag);
197 name_type_flag_tree = proto_item_add_subtree(tf,
198 ett_nbipx_name_type_flags);
199 proto_tree_add_text(name_type_flag_tree, offset+32,
201 decode_boolean_bitfield(name_type_flag, 0x80, 8,
202 "Group name", "Unique name"));
203 proto_tree_add_text(name_type_flag_tree, offset+32,
205 decode_boolean_bitfield(name_type_flag, 0x40, 8,
206 "Name in use", "Name not used"));
207 proto_tree_add_text(name_type_flag_tree, offset+32,
209 decode_boolean_bitfield(name_type_flag, 0x04, 8,
210 "Name registered", "Name not registered"));
211 proto_tree_add_text(name_type_flag_tree, offset+32,
213 decode_boolean_bitfield(name_type_flag, 0x02, 8,
214 "Name duplicated", "Name not duplicated"));
215 proto_tree_add_text(name_type_flag_tree, offset+32,
217 decode_boolean_bitfield(name_type_flag, 0x01, 8,
218 "Name deregistered", "Name not deregistered"));
220 proto_tree_add_text(nbipx_tree, offset+33, 1,
221 "Packet Type: %s (%02X)",
222 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"),
225 netbios_add_name("Name", pd, offset + 34,
231 dissect_nbipx_dg(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
234 proto_tree *nbipx_tree;
237 if (check_col(fd, COL_INFO))
238 col_add_fstr(fd, COL_INFO, "NetBIOS datagram over NBIPX");
241 ti = proto_tree_add_item(tree, proto_nbipx, offset,
242 2+NETBIOS_NAME_LEN+NETBIOS_NAME_LEN, NULL);
243 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
245 proto_tree_add_text(nbipx_tree, offset, 1,
246 "Connection control: 0x%02x", pd[offset]);
250 if (!BYTES_ARE_IN_FRAME(offset, 1))
252 proto_tree_add_text(nbipx_tree, offset, 1,
253 "Packet Type: %s (%02X)",
254 val_to_str(pd[offset], nbipx_data_stream_type_vals, "Unknown"),
259 if (!netbios_add_name("Receiver's Name", pd, offset,
262 offset += NETBIOS_NAME_LEN;
263 max_data -= NETBIOS_NAME_LEN;
265 if (!netbios_add_name("Sender's Name", pd, offset,
268 offset += NETBIOS_NAME_LEN;
269 max_data -= NETBIOS_NAME_LEN;
272 dissect_smb(pd, offset, fd, tree, max_data);
277 dissect_nwlink_dg(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
279 int max_data = pi.captured_len - offset;
280 proto_tree *nbipx_tree;
283 guint8 name_type_flag;
284 proto_tree *name_type_flag_tree;
286 char name[(NETBIOS_NAME_LEN - 1)*4 + 1];
288 char node_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
289 int node_name_type = 0;
291 name_type_flag = pd[offset+32];
292 packet_type = pd[offset+33];
293 name_type = get_netbios_name(pd, offset+36, name);
294 node_name_type = get_netbios_name(pd, offset+52, node_name);
296 if (check_col(fd, COL_PROTOCOL))
297 col_add_str(fd, COL_PROTOCOL, "NWLink");
299 if (check_col(fd, COL_INFO)) {
301 * XXX - Microsoft Network Monitor thinks that the octet
302 * at 32 is a packet type, e.g. "mailslot write" for
303 * browser announcements, and that the octet at 33 is a
304 * name type, in the sense of the 16th byte of a
307 * A name type of 2 shows up in a "host announcement",
308 * and a name type of 3 shows up in a "local master
309 * annoumcement", so maybe that field really *is* a
310 * name type - the fact that it's not associated with
311 * any of the NetBIOS names in the packet nonwithstanding.
313 * I haven't seen any packets with the name type octet
314 * being anything other than 2 or 3, so I don't know
315 * whether those are name service operations; however,
316 * given that NWLink, unlike socket-0x0455 NBIPX,
317 * has separate sockets for name queries and datagrams,
318 * it may be that this really is a name type, and that
319 * these are all datagrams, not name queries.
321 switch (packet_type) {
322 case NWLINK_NAME_QUERY:
323 col_add_fstr(fd, COL_INFO, "Name Query for %s<%02x>",
329 col_add_fstr(fd, COL_INFO, "SMB over NBIPX");
332 case NWLINK_NETBIOS_DATAGRAM:
333 /* Datagram? (Where did we see this?) */
334 col_add_fstr(fd, COL_INFO, "NetBIOS datagram over NBIPX");
338 col_add_str(fd, COL_INFO, "NetBIOS over IPX (NWLink)");
344 ti = proto_tree_add_item(tree, proto_nbipx, offset, 68, NULL);
345 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
347 add_routers(nbipx_tree, pd, offset);
350 * XXX - is "packet_type" really a packet type? See
353 if (packet_type != NWLINK_SMB &&
354 packet_type != NWLINK_NETBIOS_DATAGRAM) {
355 tf = proto_tree_add_text(nbipx_tree, offset+32, 1,
356 "Name type flag: 0x%02x",
358 name_type_flag_tree = proto_item_add_subtree(tf,
359 ett_nbipx_name_type_flags);
360 proto_tree_add_text(name_type_flag_tree, offset+32,
362 decode_boolean_bitfield(name_type_flag, 0x80, 8,
363 "Group name", "Unique name"));
364 proto_tree_add_text(name_type_flag_tree, offset+32,
366 decode_boolean_bitfield(name_type_flag, 0x40, 8,
367 "Name in use", "Name not used"));
368 proto_tree_add_text(name_type_flag_tree, offset+32,
370 decode_boolean_bitfield(name_type_flag, 0x04, 8,
371 "Name registered", "Name not registered"));
372 proto_tree_add_text(name_type_flag_tree, offset+32,
374 decode_boolean_bitfield(name_type_flag, 0x02, 8,
375 "Name duplicated", "Name not duplicated"));
376 proto_tree_add_text(name_type_flag_tree, offset+32,
378 decode_boolean_bitfield(name_type_flag, 0x01, 8,
379 "Name deregistered", "Name not deregistered"));
381 if (!netbios_add_name("Group name", pd, offset+36,
384 if (!netbios_add_name("Node name", pd, offset+52,
387 proto_tree_add_text(nbipx_tree, offset+33, 1,
388 "Packet Type: %s (%02X)",
389 val_to_str(packet_type, nwlink_data_stream_type_vals, "Unknown"),
392 proto_tree_add_text(nbipx_tree, offset+32, 1,
393 "Packet type: 0x%02x", name_type_flag);
394 proto_tree_add_text(nbipx_tree, offset+33, 1,
395 "Name Type: %s (0x%02x)",
396 netbios_name_type_descr(packet_type),
398 proto_tree_add_text(nbipx_tree, offset+34, 2,
399 "Message ID: 0x%04x", pletohs(&pd[offset+34]));
400 if (!netbios_add_name("Requested name", pd, offset+36,
403 if (!netbios_add_name("Source name", pd, offset+52,
413 switch (packet_type) {
415 case NWLINK_NETBIOS_DATAGRAM:
416 dissect_smb(pd, offset, fd, tree, max_data);
420 dissect_data(pd, offset, fd, tree);
427 proto_register_nbipx(void)
429 /* static hf_register_info hf[] = {
431 { "Name", "nbipx.abbreviation", TYPE, VALS_POINTER }},
433 static gint *ett[] = {
435 &ett_nbipx_name_type_flags,
438 proto_nbipx = proto_register_protocol("NetBIOS over IPX", "nbipx");
439 /* proto_register_field_array(proto_nbipx, hf, array_length(hf));*/
440 proto_register_subtree_array(ett, array_length(ett));