Support for AS-external LSAs added.
[obnox/wireshark/wip.git] / packet-ncp.c
1 /* packet-ncp.c
2  * Routines for NetWare Core Protocol
3  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
4  *
5  * $Id: packet-ncp.c,v 1.2 1998/09/27 22:12:33 gerald Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@unicom.net>
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 #include <pcap.h>
33
34 #include <stdio.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
47 /* The information in this module comes from:
48         NetWare LAN Analysis, Second Edition
49         Laura A. Chappell and Dan E. Hakes
50         (c) 1994 Novell, Inc.
51         Novell Press, San Jose.
52         ISBN: 0-7821-1362-1
53
54   And from the ncpfs source code by Volker Lendecke
55 */
56
57
58 struct req_info {
59         u_short req;
60         char    *text;
61 };
62
63
64 /* ================================================================= */
65 /* NCP                                                               */
66 /* ================================================================= */
67 static char*
68 req_text(u_short req) {
69         int i=0;
70
71         static struct req_info  reqs[] = {
72                 { 0x1111,       "Create a service connection" },
73                 { 0x2222, "Service request" },
74                 { 0x3333, "Service reply" },
75                 { 0x5555, "Destroy service connection" },
76                 { 0x7777, "Burst mode transfer" },
77                 { 0x9999, "Request being processed" },
78                 { 0x0000, NULL }
79         };
80
81         while (reqs[i].text != NULL) {
82                 if (reqs[i].req == req) {
83                         return reqs[i].text;
84                 }
85                 i++;
86         }
87         return "Unknown";
88 }
89
90 static char*
91 ncp2222_func(u_short func) {
92         int i=0;
93
94         static struct req_info  ncp[] = {
95                 { 17,   "Print and Queue Services" },
96                 { 21,   "Message Services" },
97                 { 22,   "File and Directory Services" },
98                 { 23,   "Binding and Rights Services" },
99                 { 34,   "Transaction Tacking Services" },
100                 { 35,   "Apple File Services" },
101                 { 86,   "Extended Attributes Services" },
102                 { 87,   "File and Directory Services" },
103                 { 88,   "Auditing Services" },
104                 { 104,  "Netware Directory Services" },
105                 { 123,  "Netware 4.x Statistical Information Services" },
106                 { 0,    NULL }
107         };
108
109         while (ncp[i].text != NULL) {
110                 if (ncp[i].req == func) {
111                         return ncp[i].text;
112                 }
113                 i++;
114         }
115         return "Unknown";
116 }
117
118 static char*
119 ncp2222_subfunc(u_short func, u_short subfunc) {
120         int i=0;
121         struct req_info *info_ptr = NULL;
122
123         /* Accounting Services */
124         static struct req_info  ncp_23[] = {
125                 { 150,  "Get Current Account Status" },
126                 { 151,  "Submit Account Charge" },
127                 { 152,  "Submit Account Hold" },
128                 { 153,  "Submit Account Note" },
129                 { 0,    NULL }
130         };
131
132         /* Apple File Services */
133         static struct req_info  ncp_35[] = {
134                 { 1,    "AFP Create Directory" },
135                 { 2,    "AFP Create File" },
136                 { 3,    "AFP Delete" },
137                 { 4,    "AFP Get Entry ID from Name" },
138                 { 5,    "AFP Get File Information" },
139                 { 6,    "AFP Get Entry ID From NetWare Handle" },
140                 { 7,    "AFP Rename" },
141                 { 8,    "AFP Open File Fork" },
142                 { 9,    "AFP Set File Information" },
143                 { 10,   "AFP Scan File Information" },
144                 { 11,   "AFP 2.0 Alloc Temporary Directory Handle" },
145                 { 12,   "AFP Get Entry ID from Name Path" },
146                 { 13,   "AFP 2.0 Create Directory" },
147                 { 14,   "AFP 2.0 Create File" },
148 /* ???  { 15,   "AFP 2.0 Delete File" }, just guessing */
149                 { 16,   "AFP 2.0 Set File Information" },
150                 { 17,   "AFP 2.0 Scan File Information" },
151                 { 18,   "AFP Get DOS Name from Entry ID" },
152                 { 19,   "AFP Get Macintosh Info on Deleted File" },
153                 { 0,    NULL }
154         };
155
156         /* Auditing Services */
157         static struct req_info  ncp_88[] = {
158                 { 1,    "Query Volume Audit Status" },
159                 { 2,    "Add Audit Property" },
160                 { 3,    "Add Auditor Access" },
161
162                 { 0,    NULL }
163         };
164
165         switch (func) {
166                 case 23:
167                         info_ptr = ncp_23;
168                         break;
169                 case 35:
170                         info_ptr = ncp_35;
171                         break;
172                 case 88:
173                         info_ptr = ncp_88;
174                         break;
175                 default:
176                         return "Unkown function";
177         }
178
179
180         while (info_ptr[i].text != NULL) {
181                 if (info_ptr[i].req == subfunc) {
182                         printf("subfunc=%s\n", info_ptr[i].text);
183                         return info_ptr[i].text;
184                 }
185                 i++;
186         }
187         return "Unknown";
188 }
189
190
191 void
192 dissect_ncp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
193
194         GtkWidget       *ncp_tree, *ti;
195         guint16         ncp_type;
196         int                     ncp_hdr;
197
198         if (fd->win_info[COL_NUM]) {
199                 strcpy(fd->win_info[COL_PROTOCOL], "NCP");
200                 strcpy(fd->win_info[COL_INFO], "NCP");
201         }
202
203         ncp_type = pntohs(&pd[offset]);
204
205         if (ncp_type == 0x1111 || ncp_type == 0x2222 || ncp_type == 0x5555 ||
206                 ncp_type == 0x7777) {
207                 ncp_hdr = 6;
208         }
209         else if (ncp_type == 0x3333 || ncp_type == 0x9999) {
210                 ncp_hdr = 8;
211         }
212         else {
213                 ncp_hdr = 1; /* ? */
214         }
215
216         if (tree) {
217                 ti = add_item_to_tree(GTK_WIDGET(tree), offset, ncp_hdr,
218                         "NetWare Core Protocol");
219                 ncp_tree = gtk_tree_new();
220                 add_subtree(ti, ncp_tree, ETT_NCP);
221
222                 add_item_to_tree(ncp_tree, offset,      2,
223                         "Type: %s", req_text( pntohs( &pd[offset] ) ) );
224
225                 add_item_to_tree(ncp_tree, offset+2,    1,
226                         "Sequence Number: %d", pd[offset+2]);
227
228                 add_item_to_tree(ncp_tree, offset+3,    1,
229                         "Connection Number Low: %d", pd[offset+3]);
230
231                 add_item_to_tree(ncp_tree, offset+4,    1,
232                         "Task Number: %d", pd[offset+4]);
233
234                 add_item_to_tree(ncp_tree, offset+5,    1,
235                         "Connection Number High: %d", pd[offset+5]);
236
237                 if (ncp_hdr == 8) {
238                         add_item_to_tree(ncp_tree, offset+6,    1,
239                                 "Completion Code: %d", pd[offset+6]);
240
241                         add_item_to_tree(ncp_tree, offset+7,    1,
242                                 "Connection Status: %d", pd[offset+7]);
243                 }
244
245                 offset += ncp_hdr;
246
247                 if (ncp_type == 0x2222) {
248                         /* my offset is different now */
249                         add_item_to_tree(ncp_tree, offset,              1,
250                                 "Function Code: %s (%d)",
251                                 ncp2222_func(pd[offset]), pd[offset]);
252
253                         add_item_to_tree(ncp_tree, offset+2,    1,
254                                 "Subfunction Code: %s (%d)",
255                                 ncp2222_subfunc(pd[offset], pd[offset+2]), pd[offset+2]);
256
257                         offset += 3;
258                 }
259
260                 dissect_data(pd, offset, fd, tree);
261         }
262 }