Fix a bounds checking problem when handed an invalid SIP packet, as
[metze/wireshark/wip.git] / packet-nbipx.c
1 /* packet-nbipx.c
2  * Routines for NetBIOS over IPX packet disassembly
3  * Gilbert Ramirez <gram@xiexie.org>
4  *
5  * $Id: packet-nbipx.c,v 1.36 2001/01/15 04:39:28 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@zing.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * 
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.
16  * 
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.
21  * 
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.
25  */
26
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
33 #endif
34
35 #include <string.h>
36 #include <glib.h>
37 #include "packet.h"
38 #include "packet-ipx.h"
39 #include "packet-netbios.h"
40 #include "packet-smb.h"
41
42 static int proto_nbipx = -1;
43
44 static gint ett_nbipx = -1;
45 static gint ett_nbipx_conn_ctrl = -1;
46 static gint ett_nbipx_name_type_flags = -1;
47
48 enum nbipx_protocol {
49         NETBIOS_NETWARE,
50         NETBIOS_NWLINK
51 };
52
53 static void
54 dissect_nbipx_ns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
55
56 static void
57 dissect_nbipx_dg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
58
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)
62  *
63  * A list of "NovelNetBIOS" packet types can be found at
64  *
65  *      http://www.protocols.com/pbook/novel.htm#NetBIOS
66  *
67  * and at least some of those packet types appear to match what's in
68  * some NBIPX packets.
69  *
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.
76  */
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
88
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"},
101         {0,                             NULL}
102 };
103
104 #define NWLINK_NAME_QUERY       1
105 #define NWLINK_SMB              2
106 #define NWLINK_NETBIOS_DATAGRAM 3
107
108 static const value_string nwlink_data_stream_type_vals[] = {
109         {NWLINK_NAME_QUERY,             "Name query"},
110         {NWLINK_SMB,                    "SMB"},
111         {NWLINK_NETBIOS_DATAGRAM,       "NetBIOS datagram"},
112         {0,                             NULL}
113 };
114
115 /* NetWare */
116 static void
117 dissect_nbipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
118 {
119         CHECK_DISPLAY_AS_DATA(proto_nbipx, tvb, pinfo, tree);
120
121         pinfo->current_proto = "NBIPX";
122
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);
127
128         /*
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...).
133          */
134         if (tvb_reported_length(tvb) == 50)
135                 dissect_nbipx_ns(tvb, pinfo, tree);
136         else
137                 dissect_nbipx_dg(tvb, pinfo, tree);
138 }
139
140 static void
141 add_routers(proto_tree *tree, tvbuff_t *tvb, int offset)
142 {
143         int             i;
144         int             rtr_offset;
145         guint32         router;
146
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);
151                 if (router != 0) {
152                         proto_tree_add_text(tree, tvb, rtr_offset, 4,
153                             "IPX Network: %s",
154                             ipxnet_to_string((guint8*)&router));
155                 }
156         }
157 }
158
159 static void
160 dissect_nbipx_ns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
161 {
162         proto_tree              *nbipx_tree;
163         proto_item              *ti;
164         int                     offset = 0;
165         guint8                  packet_type;
166         guint8                  name_type_flag;
167         proto_tree              *name_type_flag_tree;
168         proto_item              *tf;
169         char                    name[(NETBIOS_NAME_LEN - 1)*4 + 1];
170         int                     name_type;
171
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);
175
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"),
185                                 name, name_type);
186                         break;
187
188                 default:
189                         col_add_fstr(pinfo->fd, COL_INFO, "%s",
190                                 val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"));
191                         break;
192                 }
193         }
194
195         if (tree) {
196                 ti = proto_tree_add_item(tree, proto_nbipx, tvb, offset, 50,
197                     FALSE);
198                 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
199
200                 add_routers(nbipx_tree, tvb, offset);
201
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,
207                     1, "%s",
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,
211                     1, "%s",
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,
215                     1, "%s",
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,
219                     1, "%s",
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,
223                     1, "%s",
224                     decode_boolean_bitfield(name_type_flag, 0x01, 8,
225                       "Name deregistered", "Name not deregistered"));
226
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"),
230                         packet_type);
231
232                 netbios_add_name("Name", tvb, offset + 34, nbipx_tree);
233         }
234 }
235
236 static void
237 dissect_nbipx_dg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
238 {
239         proto_tree                      *nbipx_tree = NULL;
240         proto_item                      *ti;
241         int                             offset = 0;
242         guint8                          conn_control;
243         proto_tree                      *cc_tree;
244         guint8                          packet_type;
245         tvbuff_t                        *next_tvb;
246         const guint8                    *next_pd;
247         int                             next_offset;
248
249         if (check_col(pinfo->fd, COL_INFO))
250                 col_add_fstr(pinfo->fd, COL_INFO, "NetBIOS datagram over NBIPX");
251
252         if (tree) {
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);
256
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"));
276         }
277         offset += 1;
278
279         packet_type = tvb_get_guint8(tvb, offset);
280         if (tree) {
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"),
284                                 packet_type);
285         }
286         offset += 1;
287
288         if (tree)
289                 netbios_add_name("Receiver's Name", tvb, offset, nbipx_tree);
290         offset += NETBIOS_NAME_LEN;
291
292         if (tree)
293                 netbios_add_name("Sender's Name", tvb, offset, nbipx_tree);
294         offset += NETBIOS_NAME_LEN;
295
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));
301         }
302 }
303
304 static void
305 dissect_nwlink_dg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
306 {
307         proto_tree      *nbipx_tree;
308         proto_item      *ti;
309         int             offset = 0;
310         guint8          packet_type;
311         guint8          name_type_flag;
312         proto_tree      *name_type_flag_tree;
313         proto_item      *tf;
314         char            name[(NETBIOS_NAME_LEN - 1)*4 + 1];
315         int             name_type;
316         char            node_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
317         int             node_name_type = 0;
318         tvbuff_t        *next_tvb;
319         const guint8    *next_pd;
320         int             next_offset;
321
322         /*
323          * XXX - we don't use "node_name" or "node_name_type".
324          */
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);
329
330         /*
331          * XXX - if this is labeled as "NWLink", rather than "NBIPX",
332          * should it be a separate protocol?
333          */
334         if (check_col(pinfo->fd, COL_PROTOCOL))
335                 col_set_str(pinfo->fd, COL_PROTOCOL, "NWLink");
336
337         if (check_col(pinfo->fd, COL_INFO)) {
338                 /*
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
343                  * NetBIOS name.
344                  *
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.
350                  *
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.
358                  */
359                 switch (packet_type) {
360                 case NWLINK_NAME_QUERY:
361                         col_add_fstr(pinfo->fd, COL_INFO, "Name Query for %s<%02x>",
362                                         name, name_type);
363                         break;
364
365                 case NWLINK_SMB:
366                         /* Session? */
367                         col_add_fstr(pinfo->fd, COL_INFO, "SMB over NBIPX");
368                         break;
369
370                 case NWLINK_NETBIOS_DATAGRAM:
371                         /* Datagram? (Where did we see this?) */
372                         col_add_fstr(pinfo->fd, COL_INFO, "NetBIOS datagram over NBIPX");
373                         break;
374                                 
375                 default:
376                         col_set_str(pinfo->fd, COL_INFO, "NetBIOS over IPX (NWLink)");
377                         break;
378                 }
379         }
380
381         if (tree) {
382                 ti = proto_tree_add_item(tree, proto_nbipx, tvb, offset, 68, FALSE);
383                 nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
384
385                 add_routers(nbipx_tree, tvb, offset);
386
387                 /*
388                  * XXX - is "packet_type" really a packet type?  See
389                  * above.
390                  */
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",
395                                 name_type_flag);
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,
399                             1, "%s",
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,
403                             1, "%s",
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,
407                             1, "%s",
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,
411                             1, "%s",
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,
415                             1, "%s",
416                             decode_boolean_bitfield(name_type_flag, 0x01, 8,
417                               "Name deregistered", "Name not deregistered"));
418
419                         netbios_add_name("Group name", tvb, offset+36,
420                             nbipx_tree);
421                         netbios_add_name("Node name", tvb, offset+52,
422                             nbipx_tree);
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"),
426                             packet_type);
427                 } else {
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),
433                             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,
438                             nbipx_tree);
439                         netbios_add_name("Source name", tvb, offset+52,
440                             nbipx_tree);
441                 }
442         }
443
444         offset += 68;
445
446         if (tvb_offset_exists(tvb, offset)) {
447                 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
448
449                 switch (packet_type) {
450                 case NWLINK_SMB:
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));
455                         break;
456                                 
457                 default:
458                         dissect_data(next_tvb, 0, pinfo, tree);
459                         break;
460                 }
461         }
462 }
463
464 void
465 proto_register_nbipx(void)
466 {
467 /*        static hf_register_info hf[] = {
468                 { &variable,
469                 { "Name",           "nbipx.abbreviation", TYPE, VALS_POINTER }},
470         };*/
471         static gint *ett[] = {
472                 &ett_nbipx,
473                 &ett_nbipx_conn_ctrl,
474                 &ett_nbipx_name_type_flags,
475         };
476
477         proto_nbipx = proto_register_protocol("NetBIOS over IPX",
478             "NBIPX", "nbipx");
479  /*       proto_register_field_array(proto_nbipx, hf, array_length(hf));*/
480         proto_register_subtree_array(ett, array_length(ett));
481
482         register_dissector("nbipx", dissect_nbipx, proto_nbipx);
483 }
484
485 void
486 proto_reg_handoff_nbipx(void)
487 {
488         dissector_add("ipx.socket", IPX_SOCKET_NWLINK_SMB_DGRAM,
489             dissect_nwlink_dg, proto_nbipx);
490 }