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