Created a new protocol tree implementation and a new display filter
[obnox/wireshark/wip.git] / packet-nbipx.c
1 /* packet-nbipx.c
2  * Routines for NetBIOS over IPX packet disassembly
3  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
4  *
5  * $Id: packet-nbipx.c,v 1.8 1999/07/07 22:51:47 gram 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 <memory.h>*/
36 #include <glib.h>
37 #include "packet.h"
38 #include "packet-ipx.h" /* for ipxnet_to_string() */
39
40 enum nbipx_protocol {
41         NETBIOS_NETWARE,
42         NETBIOS_NWLINK
43 };
44
45 static void
46 nbipx_ns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
47                 enum nbipx_protocol nbipx, int max_data);
48
49 /* There is no RFC or public specification of Netware or Microsoft
50  * NetBIOS over IPX packets. I have had to decode the protocol myself,
51  * so there are holes and perhaps errors in this code. (gram)
52  */
53 static char
54 *packet_type[] = {
55                 "",
56                 "Name Query"
57 };
58
59 struct nbipx_header {
60         /* Netware & NT NetBIOS over IPX */
61         guint32         router[8];
62         guint8          name_type;
63         guint8          packet_type;
64
65         char            name[17];
66
67         /* NT NetBIOS over IPX */
68         guint16         junk;
69         char            node_name[17];
70         
71 };
72
73
74 /* NetWare */
75 void
76 dissect_nbipx_ns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
77                 int max_data)
78 {
79         nbipx_ns(pd, offset, fd, tree, NETBIOS_NETWARE, max_data);
80 }
81
82 void
83 dissect_nwlink_dg(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
84                 int max_data)
85 {
86         nbipx_ns(pd, offset, fd, tree, NETBIOS_NWLINK, max_data);
87 }
88
89
90 static void
91 nbipx_ns(const u_char *pd, int offset, frame_data *fd, proto_tree *tree,
92                 enum nbipx_protocol nbipx, int max_data)
93 {
94         proto_tree                      *nbipx_tree;
95         proto_item                      *ti;
96         struct nbipx_header     header;
97         int                                     i, rtr_offset;
98         int                                     name_offset;
99
100         if (nbipx == NETBIOS_NETWARE) {
101                 name_offset = 34;
102         }
103         else {
104                 name_offset = 36;
105         }
106
107
108         header.name_type = pd[offset+32];
109         header.packet_type = pd[offset+33];
110         memcpy(header.name, &pd[offset+name_offset], 16);
111         header.name[16] = 0; /* null-terminate the string */
112
113         if (nbipx == NETBIOS_NWLINK) {
114                 memcpy(header.node_name, &pd[offset+52], 16);
115                 header.node_name[17] = 0; /* null-terminate the string */
116         }
117
118         if (check_col(fd, COL_PROTOCOL)) {
119                 if (nbipx == NETBIOS_NETWARE) {
120                         col_add_str(fd, COL_PROTOCOL, "NetBIOS");
121                 }
122                 else {
123                         col_add_str(fd, COL_PROTOCOL, "NWLink");
124                 }
125         }
126
127         if (check_col(fd, COL_INFO)) {
128                         switch (header.packet_type) {
129                                 case 1:
130                                         col_add_fstr(fd, COL_INFO, "Name Query for %s", header.name);
131                                         break;
132
133                                 case 2:
134                                         col_add_fstr(fd, COL_INFO, "SMB over NBIPX");
135                                         break;
136                                 
137
138                                 default:
139                                         col_add_str(fd, COL_INFO, "NetBIOS over IPX");
140                         }
141         }
142
143         if (tree) {
144                 ti = proto_tree_add_text(tree, offset, 68,
145                                 "NetBIOS over IPX");
146                 nbipx_tree = proto_item_add_subtree(ti, ETT_NBIPX);
147
148                 if (header.packet_type <= 1) {
149                         proto_tree_add_text(nbipx_tree, offset+33, 1,
150                                         "Packet Type: %s (%02X)", packet_type[header.packet_type],
151                                         header.packet_type);
152                 }
153                 else {
154                         proto_tree_add_text(nbipx_tree, offset+33, 1,
155                                         "Packet Type: Unknown (%02X)", header.packet_type);
156                 }
157
158                 /* Eight routers are listed */
159                 for (i = 0; i < 8; i++) {
160                         rtr_offset = offset + (i << 2);
161                         memcpy(&header.router[i], &pd[rtr_offset], 4);
162                         if (header.router[i] != 0) {
163                                 proto_tree_add_text(nbipx_tree, rtr_offset, 4, "IPX Network: %s",
164                                                 ipxnet_to_string((guint8*)&header.router[i]));
165                         }
166                 }
167
168                 proto_tree_add_text(nbipx_tree, offset+32, 1, "Name Type: %02X",
169                                 header.name_type);
170
171                 if (nbipx == NETBIOS_NETWARE) {
172                         proto_tree_add_text(nbipx_tree, offset+name_offset, 16,
173                                         "Name String: %s", header.name);
174                 }
175                 else {
176                         proto_tree_add_text(nbipx_tree, offset+name_offset, 16,
177                                         "Group Name String: %s", header.name);
178                         proto_tree_add_text(nbipx_tree, offset+52, 16,
179                                         "Node Name String: %s", header.node_name);
180
181                 }
182         }
183
184         if (nbipx == NETBIOS_NWLINK) {
185                 switch (header.packet_type) {
186                         case 2:
187                                 dissect_smb(pd, offset + 68, fd, tree, max_data - 68);
188                                 break;
189                                 
190                         default:
191                                 dissect_data(pd, offset + 68, fd, tree);
192                                 break;
193                 }
194         }
195 }
196
197
198
199