Get rid of extra blanks in strings.
[obnox/wireshark/wip.git] / packet-nlm.c
1 /* packet-nlm.c
2  * Routines for nlm dissection
3  *
4  * $Id: packet-nlm.c,v 1.9 2000/08/14 11:36:02 girlich Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * Copied from packet-mount.c
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
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36
37
38 #include "packet-rpc.h"
39 #include "packet-nfs.h"
40 #include "packet-nlm.h"
41
42 /*
43  * NFS Lock Manager protocol specs can only be found in actual
44  * implementations or in the nice book:
45  * Brent Callaghan: "NFS Illustrated", Addison-Wesley, ISBN 0-201-32570-5
46  * which I use here as reference (BC).
47  */
48
49 static int proto_nlm = -1;
50
51 static int hf_nlm_cookie = -1;
52 static int hf_nlm_block = -1;
53 static int hf_nlm_exclusive = -1;
54 static int hf_nlm_lock = -1;
55 static int hf_nlm_lock_caller_name = -1;
56 static int hf_nlm_lock_owner = -1;
57 static int hf_nlm_lock_svid = -1;
58 static int hf_nlm_lock_l_offset = -1;
59 static int hf_nlm_lock_l_len = -1;
60 static int hf_nlm_reclaim = -1;
61 static int hf_nlm_state = -1;
62
63 static gint ett_nlm = -1;
64 static gint ett_nlm_lock = -1;
65
66
67 const value_string names_nlm_state[] =
68 {
69         /* NLM_GRANTED is the function number 5 and the state code 0.
70          * So we use for the state the postfix _S.
71          */
72 #define NLM_GRANTED_S           0
73                 {       NLM_GRANTED_S,  "NLM_GRANTED"   },
74 #define NLM_DENIED              1
75                 {       NLM_DENIED,     "NLM_DENIED"    },
76 #define NLM_DENIED_NOLOCKS      2
77                 {       NLM_DENIED_NOLOCKS,     "NLM_DENIED_NOLOCKS"    },
78 #define NLM_BLOCKED             3
79                 {       NLM_BLOCKED,    "NLM_BLOCKED"           },
80 #define NLM_DENIED_GRACE_PERIOD 4
81                 {       NLM_DENIED_GRACE_PERIOD,        "NLM_DENIED_GRACE_PERIOD"       },
82 #define NLM_DEADLCK             5
83                 {       NLM_DEADLCK,    "NLM_DEADLCK"   },
84 #define NLM_ROFS                6
85                 {       NLM_ROFS,       "NLM_ROFS"      },
86 #define NLM_STALE_FH            7
87                 {       NLM_STALE_FH,   "NLM_STALE_FH"  },
88 #define NLM_BIG                 8
89                 {       NLM_BIG,        "NLM_BIG"       },
90 #define NLM_FAILED              9
91                 {       NLM_FAILED,     "NLM_FAILED"    },
92                 {       0,              NULL            }
93 };
94
95
96 /* generic dissecting functions */
97
98 static int
99 dissect_nlm_lock(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int version, int offset)
100 {
101         proto_item* lock_item = NULL;
102         proto_tree* lock_tree = NULL;
103         const guint8 *pd;
104         int compat_offset;
105
106         tvb_compat(tvb, &pd, &compat_offset);
107
108         if (tree) {
109                 lock_item = proto_tree_add_item(tree, hf_nlm_lock, tvb,
110                                 offset, tvb_length_remaining(tvb, offset), FALSE);
111                 if (lock_item)
112                         lock_tree = proto_item_add_subtree(lock_item, ett_nlm_lock);
113         }
114
115         offset = dissect_rpc_string_tvb(tvb,pinfo,lock_tree,
116                         hf_nlm_lock_caller_name, offset, NULL);
117         offset = dissect_nfs_fh3(pd, compat_offset+offset, pinfo->fd, lock_tree,"fh") - compat_offset;
118
119         offset = dissect_rpc_data_tvb(tvb, pinfo, lock_tree, hf_nlm_lock_owner, offset);
120
121         offset = dissect_rpc_uint32_tvb(tvb, pinfo, lock_tree, hf_nlm_lock_svid, offset);
122
123         if (version == 4) {
124                 offset = dissect_rpc_uint64_tvb(tvb, pinfo, lock_tree, hf_nlm_lock_l_offset, offset);
125                 offset = dissect_rpc_uint64_tvb(tvb, pinfo, lock_tree, hf_nlm_lock_l_len, offset);
126         }
127         else {
128                 offset = dissect_rpc_uint32_tvb(tvb, pinfo, lock_tree, hf_nlm_lock_l_offset, offset);
129                 offset = dissect_rpc_uint32_tvb(tvb, pinfo, lock_tree, hf_nlm_lock_l_len, offset);
130         }
131
132         return offset;
133 }
134
135
136 /* RPC functions */
137
138 #if 0
139 static int
140 dissect_nlm1_lock_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
141 {
142 #else
143 int
144 dissect_nlm1_lock_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
145 {
146         tvbuff_t *tvb = tvb_create_from_top(offset);
147         packet_info *pinfo = &pi;
148 #endif
149         int noffset;
150
151         noffset = dissect_rpc_data_tvb(tvb, pinfo, tree, hf_nlm_cookie, 0);
152         noffset = dissect_rpc_bool_tvb(tvb, pinfo, tree, hf_nlm_block, noffset);
153         noffset = dissect_rpc_bool_tvb(tvb, pinfo, tree, hf_nlm_exclusive, noffset);
154         noffset = dissect_nlm_lock(tvb, pinfo, tree, 1, noffset);
155         noffset = dissect_rpc_bool_tvb(tvb, pinfo, tree, hf_nlm_reclaim, noffset);
156         noffset = dissect_rpc_uint32_tvb(tvb, pinfo, tree, hf_nlm_state, noffset);
157         return tvb_raw_offset(tvb) + noffset;
158 }
159
160
161 #if 0
162 static int
163 dissect_nlm1_unlock_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
164 {
165 #else
166 int
167 dissect_nlm1_unlock_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
168 {
169         tvbuff_t *tvb = tvb_create_from_top(offset);
170         packet_info *pinfo = &pi;
171 #endif
172         int noffset;
173
174         noffset = dissect_rpc_data_tvb(tvb, pinfo, tree, hf_nlm_cookie, 0);
175         noffset = dissect_nlm_lock(tvb, pinfo, tree, 1, noffset);
176         return tvb_raw_offset(tvb) + noffset;
177 }
178
179
180 #if 0
181 static int
182 dissect_nlm1_gen_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
183 {
184 #else
185 int
186 dissect_nlm1_gen_reply(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
187 {
188         tvbuff_t *tvb = tvb_create_from_top(offset);
189         packet_info *pinfo = &pi;
190 #endif
191         int noffset;
192
193         noffset = dissect_rpc_data_tvb(tvb, pinfo, tree, hf_nlm_cookie, 0);
194         noffset = dissect_rpc_uint32_tvb(tvb, pinfo, tree, hf_nlm_state, noffset);
195         return tvb_raw_offset(tvb) + noffset;
196 }
197
198
199 /* proc number, "proc name", dissect_request, dissect_reply */
200 /* NULL as function pointer means: take the generic one. */
201 /* NLM protocol version 1 */
202 const vsff nlm1_proc[] = {
203         { NLM_NULL,             "NULL",         /* OK */
204         NULL,                           NULL },
205         { NLM_TEST,             "TEST",
206         NULL,                           NULL },
207         { NLM_LOCK,             "LOCK",         /* OK */
208         dissect_nlm1_lock_call,         dissect_nlm1_gen_reply },
209         { NLM_CANCEL,           "CANCEL",
210         NULL,                           dissect_nlm1_gen_reply },
211         { NLM_UNLOCK,           "UNLOCK",       /* OK */
212         dissect_nlm1_unlock_call,       dissect_nlm1_gen_reply },
213         { NLM_GRANTED,          "GRANTED",
214         NULL,                           NULL },
215         { NLM_TEST_MSG,         "TEST_MSG",
216         NULL,                           NULL },
217         { NLM_LOCK_MSG,         "LOCK_MSG",     /* OK */
218         dissect_nlm1_lock_call,         NULL },
219         { NLM_CANCEL_MSG,       "CANCEL_MSG",
220         NULL,                           NULL },
221         { NLM_UNLOCK_MSG,       "UNLOCK_MSG",   /* OK */
222         dissect_nlm1_unlock_call,       NULL },
223         { NLM_GRANTED_MSG,      "GRANTED_MSG",
224         NULL,                           dissect_nlm1_gen_reply },
225         { NLM_TEST_RES,         "TEST_RES",
226         NULL,                           NULL },
227         { NLM_LOCK_RES,         "LOCK_RES",     /* OK */
228         dissect_nlm1_gen_reply,         NULL },
229         { NLM_CANCEL_RES,       "CANCEL_RES",   /* OK */
230         dissect_nlm1_gen_reply,         NULL },
231         { NLM_UNLOCK_RES,       "UNLOCK_RES",   /* OK */
232         dissect_nlm1_gen_reply,         NULL },
233         { NLM_GRANTED_RES,      "GRANTED_RES",  /* OK */
234         dissect_nlm1_gen_reply,         NULL },
235         { 0,                    NULL,           NULL,   NULL }
236 };
237 /* end of NLM protocol version 1 */
238
239 /* NLM protocol version 2 */
240 const vsff nlm2_proc[] = {
241         { NLM_NULL,             "NULL",         NULL,   NULL },
242         { NLM_TEST,             "TEST",         NULL,   NULL },
243         { NLM_LOCK,             "LOCK",         NULL,   NULL },
244         { NLM_CANCEL,           "CANCEL",       NULL,   NULL },
245         { NLM_UNLOCK,           "UNLOCK",       NULL,   NULL },
246         { NLM_GRANTED,          "GRANTED",      NULL,   NULL },
247         { NLM_TEST_MSG,         "TEST_MSG",     NULL,   NULL },
248         { NLM_LOCK_MSG,         "LOCK_MSG",     NULL,   NULL },
249         { NLM_CANCEL_MSG,       "CANCEL_MSG",   NULL,   NULL },
250         { NLM_UNLOCK_MSG,       "UNLOCK_MSG",   NULL,   NULL },
251         { NLM_GRANTED_MSG,      "GRANTED_MSG",  NULL,   NULL },
252         { NLM_TEST_RES,         "TEST_RES",     NULL,   NULL },
253         { NLM_LOCK_RES,         "LOCK_RES",     NULL,   NULL },
254         { NLM_CANCEL_RES,       "CANCEL_RES",   NULL,   NULL },
255         { NLM_UNLOCK_RES,       "UNLOCK_RES",   NULL,   NULL },
256         { NLM_GRANTED_RES,      "GRANTED_RES",  NULL,   NULL },
257         { 0,                    NULL,           NULL,   NULL }
258 };
259 /* end of NLM protocol version 2 */
260
261 /* NLM protocol version 3 */
262 const vsff nlm3_proc[] = {
263         { NLM_NULL,             "NULL",         NULL,   NULL },
264         { NLM_TEST,             "TEST",         NULL,   NULL },
265         { NLM_LOCK,             "LOCK",         NULL,   NULL },
266         { NLM_CANCEL,           "CANCEL",       NULL,   NULL },
267         { NLM_UNLOCK,           "UNLOCK",       NULL,   NULL },
268         { NLM_GRANTED,          "GRANTED",      NULL,   NULL },
269         { NLM_TEST_MSG,         "TEST_MSG",     NULL,   NULL },
270         { NLM_LOCK_MSG,         "LOCK_MSG",     NULL,   NULL },
271         { NLM_CANCEL_MSG,       "CANCEL_MSG",   NULL,   NULL },
272         { NLM_UNLOCK_MSG,       "UNLOCK_MSG",   NULL,   NULL },
273         { NLM_GRANTED_MSG,      "GRANTED_MSG",  NULL,   NULL },
274         { NLM_TEST_RES,         "TEST_RES",     NULL,   NULL },
275         { NLM_LOCK_RES,         "LOCK_RES",     NULL,   NULL },
276         { NLM_CANCEL_RES,       "CANCEL_RES",   NULL,   NULL },
277         { NLM_UNLOCK_RES,       "UNLOCK_RES",   NULL,   NULL },
278         { NLM_GRANTED_RES,      "GRANTED_RES",  NULL,   NULL },
279         { NLM_SHARE,            "SHARE",        NULL,   NULL },
280         { NLM_UNSHARE,          "UNSHARE",      NULL,   NULL },
281         { NLM_NM_LOCK,          "NM_LOCK",      NULL,   NULL },
282         { NLM_FREE_ALL,         "FREE_ALL",     NULL,   NULL },
283         { 0,                    NULL,           NULL,   NULL }
284 };
285 /* end of NLM protocol version 3 */
286
287
288 #if 0
289 static int
290 dissect_nlm4_test_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
291 {
292 #else
293 int
294 dissect_nlm4_test_call(const u_char* pd, int offset, frame_data* fd, proto_tree* tree)
295 {
296         tvbuff_t *tvb = tvb_create_from_top(offset);
297         packet_info *pinfo = &pi;
298 #endif
299         int noffset;
300
301         noffset = dissect_rpc_data_tvb(tvb, pinfo, tree, hf_nlm_cookie, 0);
302         dissect_rpc_bool_tvb(tvb, pinfo, tree, hf_nlm_exclusive, noffset);
303         noffset += 4;
304         noffset = dissect_nlm_lock(tvb, pinfo, tree, 4, noffset);
305
306         return tvb_raw_offset(tvb) + noffset;
307 }
308
309
310 /* NLM protocol version 4 */
311 const vsff nlm4_proc[] = {
312         { NLM_NULL,             "NULL",         NULL,   NULL },
313         { NLM_TEST,             "TEST",         dissect_nlm4_test_call, NULL },
314         { NLM_LOCK,             "LOCK",         NULL,   NULL },
315         { NLM_CANCEL,           "CANCEL",       NULL,   NULL },
316         { NLM_UNLOCK,           "UNLOCK",       NULL,   NULL },
317         { NLM_GRANTED,          "GRANTED",      NULL,   NULL },
318         { NLM_TEST_MSG,         "TEST_MSG",     NULL,   NULL },
319         { NLM_LOCK_MSG,         "LOCK_MSG",     NULL,   NULL },
320         { NLM_CANCEL_MSG,       "CANCEL_MSG",   NULL,   NULL },
321         { NLM_UNLOCK_MSG,       "UNLOCK_MSG",   NULL,   NULL },
322         { NLM_GRANTED_MSG,      "GRANTED_MSG",  NULL,   NULL },
323         { NLM_TEST_RES,         "TEST_RES",     NULL,   NULL },
324         { NLM_LOCK_RES,         "LOCK_RES",     NULL,   NULL },
325         { NLM_CANCEL_RES,       "CANCEL_RES",   NULL,   NULL },
326         { NLM_UNLOCK_RES,       "UNLOCK_RES",   NULL,   NULL },
327         { NLM_GRANTED_RES,      "GRANTED_RES",  NULL,   NULL },
328         { NLM_SHARE,            "SHARE",        NULL,   NULL },
329         { NLM_UNSHARE,          "UNSHARE",      NULL,   NULL },
330         { NLM_NM_LOCK,          "NM_LOCK",      NULL,   NULL },
331         { NLM_FREE_ALL,         "FREE_ALL",     NULL,   NULL },
332         { 0,                    NULL,           NULL,   NULL }
333 };
334 /* end of NLM protocol version 4 */
335
336
337 static struct true_false_string yesno = { "Yes", "No" };
338
339
340 void
341 proto_register_nlm(void)
342 {
343         static hf_register_info hf[] = {
344                 { &hf_nlm_cookie, {
345                         "cookie", "nlm.cookie", FT_STRING, BASE_DEC,
346                         NULL, 0, "cookie" }},
347                 { &hf_nlm_block, {
348                         "block", "nlm.block", FT_BOOLEAN, BASE_NONE,
349                         &yesno, 0, "block" }},
350                 { &hf_nlm_exclusive, {
351                         "exclusive", "nlm.exclusive", FT_BOOLEAN, BASE_NONE,
352                         &yesno, 0, "exclusive" }},
353                 { &hf_nlm_lock, {
354                         "lock", "nlm.lock", FT_NONE, 0,
355                         NULL, 0, "lock" }},
356                 { &hf_nlm_lock_caller_name, {
357                         "caller_name", "nlm.lock.caller_name", FT_STRING, BASE_NONE,
358                         NULL, 0, "caller_name" }},
359                 { &hf_nlm_lock_owner, {
360                         "owner", "nlm.lock.owner", FT_STRING, BASE_DEC,
361                         NULL, 0, "owner" }},
362                 { &hf_nlm_lock_svid, {
363                         "svid", "nlm.lock.svid", FT_UINT32, BASE_DEC,
364                         NULL, 0, "svid" }},
365                 { &hf_nlm_lock_l_offset, {
366                         "l_offset", "nlm.lock.l_offset", FT_UINT32, BASE_DEC,
367                         NULL, 0, "l_offset" }},
368                 { &hf_nlm_lock_l_len, {
369                         "l_len", "nlm.lock.l_len", FT_UINT32, BASE_DEC,
370                         NULL, 0, "l_len" }},
371                 { &hf_nlm_reclaim, {
372                         "reclaim", "nlm.reclaim", FT_BOOLEAN, BASE_NONE,
373                         &yesno, 0, "reclaim" }},
374                 { &hf_nlm_state, {
375                         "state", "nlm.state", FT_UINT32, BASE_DEC,
376                         VALS(names_nlm_state), 0, "state" }},
377                 };
378
379         static gint *ett[] = {
380                 &ett_nlm,
381                 &ett_nlm_lock,
382         };
383
384         proto_nlm = proto_register_protocol("Network Lock Manager Protocol", "nlm");
385         proto_register_field_array(proto_nlm, hf, array_length(hf));
386         proto_register_subtree_array(ett, array_length(ett));
387 }
388
389 void
390 proto_reg_handoff_nlm(void)
391 {
392         /* Register the protocol as RPC */
393         rpc_init_prog(proto_nlm, NLM_PROGRAM, ett_nlm);
394         /* Register the procedure tables */
395         rpc_init_proc_table(NLM_PROGRAM, 1, nlm1_proc);
396         rpc_init_proc_table(NLM_PROGRAM, 2, nlm2_proc);
397         rpc_init_proc_table(NLM_PROGRAM, 3, nlm3_proc);
398         rpc_init_proc_table(NLM_PROGRAM, 4, nlm4_proc);
399 }