2 * Routines for NetWare Core Protocol
3 * Gilbert Ramirez <gram@verdict.uthscsa.edu>
5 * $Id: packet-ncp.c,v 1.6 1998/11/12 00:06:34 gram Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
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.
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
39 #ifdef HAVE_NETINET_IN_H
40 # include <netinet/in.h>
45 #include "packet-ipx.h"
46 #include "packet-ncp.h"
48 /* The information in this module comes from:
49 NetWare LAN Analysis, Second Edition
50 Laura A. Chappell and Dan E. Hakes
52 Novell Press, San Jose.
55 And from the ncpfs source code by Volker Lendecke
60 static value_string request_reply_values[] = {
61 { 0x1111, "Create a service connection" },
62 { 0x2222, "Service request" },
63 { 0x3333, "Service reply" },
64 { 0x5555, "Destroy service connection" },
65 { 0x7777, "Burst mode transfer" },
66 { 0x9999, "Request being processed" },
71 static value_string ncp2222_func[] = {
72 { 17, "Print and Queue Services" },
73 { 21, "Message Services" },
74 { 22, "File and Directory Services" },
75 { 23, "Binding and Rights Services" },
76 { 34, "Transaction Tacking Services" },
77 { 35, "Apple File Services" },
78 { 72, "File Services" }, /* guess */
79 { 86, "Extended Attributes Services" },
80 { 87, "File and Directory Services" },
81 { 88, "Auditing Services" },
82 { 104, "Netware Directory Services" },
83 { 123, "Netware 4.x Statistical Information Services" },
88 ncp2222_subfunc(u_short func, u_short subfunc) {
89 value_string *info_ptr = NULL;
91 /* Accounting Services */
92 static value_string ncp_23[] = {
93 { 150, "Get Current Account Status" },
94 { 151, "Submit Account Charge" },
95 { 152, "Submit Account Hold" },
96 { 153, "Submit Account Note" },
100 /* Apple File Services */
101 static value_string ncp_35[] = {
102 { 1, "AFP Create Directory" },
103 { 2, "AFP Create File" },
105 { 4, "AFP Get Entry ID from Name" },
106 { 5, "AFP Get File Information" },
107 { 6, "AFP Get Entry ID From NetWare Handle" },
109 { 8, "AFP Open File Fork" },
110 { 9, "AFP Set File Information" },
111 { 10, "AFP Scan File Information" },
112 { 11, "AFP 2.0 Alloc Temporary Directory Handle" },
113 { 12, "AFP Get Entry ID from Name Path" },
114 { 13, "AFP 2.0 Create Directory" },
115 { 14, "AFP 2.0 Create File" },
116 /* ??? { 15, "AFP 2.0 Delete File" }, just guessing */
117 { 16, "AFP 2.0 Set File Information" },
118 { 17, "AFP 2.0 Scan File Information" },
119 { 18, "AFP Get DOS Name from Entry ID" },
120 { 19, "AFP Get Macintosh Info on Deleted File" },
124 /* File services */ /* guess */
125 static value_string ncp_72[] = {
130 /* Auditing Services */
131 static value_string ncp_88[] = {
132 { 1, "Query Volume Audit Status" },
133 { 2, "Add Audit Property" },
134 { 3, "Add Auditor Access" },
153 return "Unknown function";
156 return val_to_str(subfunc, info_ptr, "Unknown");
161 ncp_read(GtkWidget *tree, const u_char *pd, int offset)
163 struct ncp_read_header header;
165 memcpy(header.handle, &pd[offset], 6);
166 header.offset = pntohl(&pd[offset+6]);
167 header.bytes = pntohs(&pd[offset+10]);
169 add_item_to_tree(tree, offset, 6,
170 "File Handle: 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X ",
171 header.handle[0], header.handle[1], header.handle[2],
172 header.handle[3], header.handle[4], header.handle[5]);
174 add_item_to_tree(tree, offset+6, 4,
175 "Starting Offset: %d", header.offset);
177 add_item_to_tree(tree, offset+10, 2,
178 "Bytes to Read: %d", header.bytes);
183 dissect_ncp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
185 GtkWidget *ncp_tree, *ti;
188 struct ncp_common_header header;
189 struct ncp_request_header request;
190 struct ncp_reply_header reply;
191 char *ncp_type_text[] = { "Unknown",
192 "Request", "Reply" };
194 ncp_type = pntohs(&pd[offset]);
195 header.type = ncp_type;
196 header.sequence = pd[offset+2];
197 header.conn_low = pd[offset+3];
198 header.task = pd[offset+4];
199 header.conn_high = pd[offset+5];
201 if (ncp_type == 0x1111 || ncp_type == 0x2222 || ncp_type == 0x5555 ||
202 ncp_type == 0x7777) {
204 request.function = pd[offset+6];
206 else if (ncp_type == 0x3333 || ncp_type == 0x9999) {
208 reply.completion_code = pd[offset+6];
209 reply.connection_state = pd[offset+7];
212 ncp_hdr = 6; /* in order to get ncp_type_text[0] */
215 if (fd->win_info[COL_NUM]) {
216 strcpy(fd->win_info[COL_PROTOCOL], "NCP");
217 /* I take advantage of the ncp_hdr length to use as an index into
218 * ncp_type_text[]. Ugly hack, but quick. */
219 sprintf(fd->win_info[COL_INFO], "%s", ncp_type_text[ncp_hdr - 6]);
224 ti = add_item_to_tree(GTK_WIDGET(tree), offset, END_OF_FRAME,
225 "NetWare Core Protocol");
226 ncp_tree = gtk_tree_new();
227 add_subtree(ti, ncp_tree, ETT_NCP);
229 add_item_to_tree(ncp_tree, offset, 2,
230 "Type: %s", val_to_str( header.type, request_reply_values,
233 add_item_to_tree(ncp_tree, offset+2, 1,
234 "Sequence Number: %d", header.sequence);
236 add_item_to_tree(ncp_tree, offset+3, 1,
237 "Connection Number Low: %d", header.conn_low);
239 add_item_to_tree(ncp_tree, offset+4, 1,
240 "Task Number: %d", header.task);
242 add_item_to_tree(ncp_tree, offset+5, 1,
243 "Connection Number High: %d", header.conn_high);
246 add_item_to_tree(ncp_tree, offset+6, 1,
247 "Completion Code: %d", reply.completion_code);
249 add_item_to_tree(ncp_tree, offset+7, 1,
250 "Connection Status: %d", reply.connection_state);
253 add_item_to_tree(ncp_tree, offset+6, 1,
254 "Function Code: %s (%d)",
255 match_strval(request.function, ncp2222_func),
261 if (ncp_type == 0x2222) {
262 /* my offset is different now */
263 add_item_to_tree(ncp_tree, offset, 1,
264 "Subfunction Code: %s (%d)",
265 ncp2222_subfunc(pd[offset-1], pd[offset]), pd[offset]);
267 if (request.function == 0x48) {
268 ncp_read(ncp_tree, pd, offset+1);
271 dissect_data(pd, offset, fd, tree);
275 dissect_data(pd, offset, fd, tree);