Add data parameter to dissect_function_t in vsff structure. The intention here is...
[metze/wireshark/wip.git] / epan / dissectors / packet-glusterfs_hndsk.c
1 /* packet-gluster_hndsk.c
2  * Routines for GlusterFS Handshake dissection
3  * Copyright 2012, Niels de Vos <ndevos@redhat.com>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  *
25  *
26  * References to source files point in general to the glusterfs sources.
27  * There is currently no RFC or other document where the protocol is
28  * completely described. The glusterfs sources can be found at:
29  * - http://git.gluster.com/?p=glusterfs.git
30  * - https://github.com/gluster/glusterfs
31  *
32  * The coding-style is roughly the same as the one use in the Linux kernel,
33  * see http://www.kernel.org/doc/Documentation/CodingStyle.
34  */
35
36 #include "config.h"
37
38 #include <glib.h>
39
40 #include <epan/packet.h>
41
42 #include "packet-rpc.h"
43 #include "packet-gluster.h"
44
45 /* Initialize the protocol and registered fields */
46 static gint proto_gluster_cbk = -1;
47 static gint proto_gluster_hndsk = -1;
48
49 /* programs and procedures */
50 static gint hf_gluster_cbk_proc = -1;
51 static gint hf_gluster_hndsk_proc = -1;
52 static gint hf_gluster_hndsk_dict = -1;
53 static gint hf_gluster_hndsk_spec = -1;         /* GETSPEC Reply */
54 static gint hf_gluster_hndsk_key = -1;          /* GETSPEC Call */
55 static gint hf_gluster_hndsk_event_op = -1;     /* EVENT NOTIFY call */
56 static gint hf_gluster_hndsk_uid = -1;          /* LOCK VERSION*/
57 static gint hf_gluster_hndsk_lk_ver= -1;
58 static gint hf_gluster_hndsk_flags = -1;
59
60 /* Initialize the subtree pointers */
61 static gint ett_gluster_cbk = -1;
62 static gint ett_gluster_hndsk = -1;
63
64 /* procedures for GLUSTER_HNDSK_PROGRAM */
65 static int
66 gluster_hndsk_setvolume_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
67                                                         proto_tree *tree, void* data _U_)
68 {
69         offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree, data);
70         offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict,
71                                                                 offset);
72         return offset;
73 }
74
75 static int
76 gluster_hndsk_setvolume_call(tvbuff_t *tvb, int offset,
77                                 packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
78 {
79         offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict,
80                                                                 offset);
81         return offset;
82 }
83
84 static int
85 gluster_hndsk_2_setvolume_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
86                                                         proto_tree *tree, void* data _U_)
87 {
88         offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree, data);
89         offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict,
90                                                                 offset);
91         return offset;
92 }
93
94 static int
95 gluster_hndsk_2_setvolume_call(tvbuff_t *tvb, int offset,
96                                 packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
97 {
98         offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict,
99                                                                 offset);
100         return offset;
101 }
102
103 static int
104 gluster_hndsk_2_getspec_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
105                                                         proto_tree *tree, void* data _U_)
106 {
107         offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree, data);
108         offset = dissect_rpc_string(tvb, tree, hf_gluster_hndsk_spec, offset,
109                                                                         NULL);
110         offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict,
111                                                                 offset);
112         return offset;
113 }
114
115 static int
116 gluster_hndsk_2_getspec_call(tvbuff_t *tvb, int offset,
117                                 packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
118 {
119         if (tree)
120                 proto_tree_add_item(tree, hf_gluster_hndsk_flags, tvb, offset,
121                                                                 4, ENC_NA);
122         offset += 4;
123         offset = dissect_rpc_string(tvb, tree, hf_gluster_hndsk_key, offset,
124                                                                 NULL);
125         offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict,
126                                                                 offset);
127         return offset;
128 }
129
130 static int
131 gluster_hndsk_2_set_lk_ver_reply(tvbuff_t *tvb, int offset, packet_info *pinfo,
132                                                         proto_tree *tree, void* data _U_)
133 {
134         offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree, data);
135         offset = dissect_rpc_uint32(tvb, tree,hf_gluster_hndsk_lk_ver, offset);
136         return offset;
137 }
138
139 static int
140 gluster_hndsk_2_set_lk_ver_call(tvbuff_t *tvb, int offset,
141                                 packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
142 {
143         offset = dissect_rpc_string(tvb, tree, hf_gluster_hndsk_uid, offset,
144                                                                         NULL);
145         offset = dissect_rpc_uint32(tvb, tree,hf_gluster_hndsk_lk_ver, offset);
146         return offset;
147 }
148
149 static int
150 gluster_hndsk_2_event_notify_call(tvbuff_t *tvb, int offset,
151                                 packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
152 {
153         offset = dissect_rpc_uint32(tvb, tree, hf_gluster_hndsk_event_op,
154                                                                 offset);
155         offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict,
156                                                                 offset);
157         return offset;
158 }
159
160 /* In  rpc/xdr/src/glusterfs3-xdr.c. xdr_gf_event_notify_rsp */
161
162 static int
163 gluster_hndsk_2_event_notify_reply(tvbuff_t *tvb, int offset,
164                                         packet_info *pinfo, proto_tree *tree, void* data _U_)
165 {
166         offset = gluster_dissect_common_reply(tvb, offset, pinfo, tree, data);
167         offset = gluster_rpc_dissect_dict(tree, tvb, hf_gluster_hndsk_dict,
168                                                                 offset);
169         return offset;
170 }
171
172 static const vsff gluster_hndsk_proc[] = {
173         { GF_HNDSK_NULL,    "NULL",    NULL, NULL },
174         {
175                 GF_HNDSK_SETVOLUME, "SETVOLUME",
176                 gluster_hndsk_setvolume_call, gluster_hndsk_setvolume_reply
177         },
178         { GF_HNDSK_GETSPEC, "GETSPEC", NULL, NULL },
179         { GF_HNDSK_PING,    "PING",    NULL, gluster_dissect_common_reply },
180         { 0, NULL, NULL, NULL }
181 };
182
183 static const vsff gluster_hndsk_2_proc[] = {
184         { GF_HNDSK_NULL, "NULL", NULL, NULL },
185         {
186                 GF_HNDSK_SETVOLUME, "SETVOLUME",
187                 gluster_hndsk_2_setvolume_call, gluster_hndsk_2_setvolume_reply
188         },
189         {
190                 GF_HNDSK_GETSPEC, "GETSPEC",
191                 gluster_hndsk_2_getspec_call, gluster_hndsk_2_getspec_reply
192         },
193         { GF_HNDSK_PING, "PING", NULL, glusterfs_gfs3_3_op_common_reply },
194         {
195                 GF_HNDSK_SET_LK_VER,"LOCK VERSION",
196                 gluster_hndsk_2_set_lk_ver_call, gluster_hndsk_2_set_lk_ver_reply
197         },
198         {
199                 GF_HNDSK_EVENT_NOTIFY, "EVENTNOTIFY",
200                 gluster_hndsk_2_event_notify_call,
201                 gluster_hndsk_2_event_notify_reply
202         },
203         { 0, NULL, NULL, NULL }
204 };
205
206
207 static const value_string gluster_hndsk_proc_vals[] = {
208         { GF_HNDSK_NULL,         "NULL" },
209         { GF_HNDSK_SETVOLUME,    "DUMP" },
210         { GF_HNDSK_GETSPEC,      "GETSPEC" },
211         { GF_HNDSK_PING,         "PING" },
212         { GF_HNDSK_SET_LK_VER,   "LOCK VERSION" },
213         { GF_HNDSK_EVENT_NOTIFY, "EVENTNOTIFY" },
214         { 0, NULL }
215 };
216
217 void
218 proto_register_gluster_hndsk(void)
219 {
220         static hf_register_info hf[] = {
221                 { &hf_gluster_hndsk_proc,
222                         { "GlusterFS Handshake", "glusterfs.hndsk.proc",
223                                 FT_UINT32, BASE_DEC,
224                                 VALS(gluster_hndsk_proc_vals), 0, NULL, HFILL }
225                 },
226                 /* fields used by Gluster Handshake */
227                 { &hf_gluster_hndsk_dict,
228                         { "Dict", "glusterfs.hndsk.dict", FT_STRING, BASE_NONE,
229                                 NULL, 0, NULL, HFILL }
230                 },
231                 /* For Gluster handshake event notify */
232                 { &hf_gluster_hndsk_event_op,
233                        { "Event Op", "glusterfs.hndsk.event_notify_op",
234                                 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
235                 },
236                 { &hf_gluster_hndsk_key,
237                         { "Key", "glusterfs.hndsk.getspec.key", FT_STRING,
238                                 BASE_NONE, NULL, 0, NULL, HFILL }
239                 },
240                 { &hf_gluster_hndsk_spec,
241                         /* FIXME: rename spec to something clearer */
242                         { "Spec", "glusterfs.hndsk.getspec", FT_STRING,
243                                 BASE_NONE, NULL, 0, NULL, HFILL }
244                 },
245                 /* For hand shake set_lk_ver */
246                 { &hf_gluster_hndsk_uid,
247                         { "Name", "glusterfs.hndsk.uid", FT_STRING, BASE_NONE,
248                                 NULL, 0, NULL, HFILL }
249                 },
250                 { &hf_gluster_hndsk_lk_ver,
251                         { "Event Op", "glusterfs.hndsk.lk_ver", FT_UINT32,
252                                 BASE_DEC, NULL, 0, NULL, HFILL }
253                 },
254                 { &hf_gluster_hndsk_flags,
255                         { "Flags", "glusterfs.hndsk.flags", FT_UINT32, BASE_OCT,
256                                 NULL, 0, NULL, HFILL }
257                 }
258         };
259
260         /* Setup protocol subtree array */
261         static gint *ett[] = {
262                 &ett_gluster_hndsk
263         };
264
265         /* Register the protocol name and description */
266         proto_gluster_hndsk = proto_register_protocol("GlusterFS Handshake",
267                                                 "GlusterFS Handshake",
268                                                 "glusterfs.hndsk");
269         proto_register_subtree_array(ett, array_length(ett));
270         proto_register_field_array(proto_gluster_hndsk, hf, array_length(hf));
271
272 }
273
274 void
275 proto_reg_handoff_gluster_hndsk(void)
276 {
277         rpc_init_prog(proto_gluster_hndsk, GLUSTER_HNDSK_PROGRAM,
278                                                         ett_gluster_hndsk);
279         rpc_init_proc_table(GLUSTER_HNDSK_PROGRAM, 1, gluster_hndsk_proc,
280                                                         hf_gluster_hndsk_proc);
281         rpc_init_proc_table(GLUSTER_HNDSK_PROGRAM, 2, gluster_hndsk_2_proc,
282                                                         hf_gluster_hndsk_proc);
283 }
284
285 /* Legacy GlusterFS Callback procedures, they don't contain any data. */
286 static const vsff gluster_cbk_proc[] = {
287         { GF_CBK_NULL,      "NULL",      NULL, NULL },
288         { GF_CBK_FETCHSPEC, "FETCHSPEC", NULL, NULL },
289         { GF_CBK_INO_FLUSH, "INO_FLUSH", NULL, NULL },
290         { 0, NULL, NULL, NULL }
291 };
292 static const value_string gluster_cbk_proc_vals[] = {
293         { GF_CBK_NULL,      "NULL" },
294         { GF_CBK_FETCHSPEC, "FETCHSPEC" },
295         { GF_CBK_INO_FLUSH, "INO_FLUSH" },
296         { 0, NULL }
297 };
298
299 void
300 proto_register_gluster_cbk(void)
301 {
302         /* Setup list of header fields  See Section 1.6.1 for details */
303         static hf_register_info hf[] = {
304                 /* programs */
305                 { &hf_gluster_cbk_proc,
306                         { "GlusterFS Callback", "glusterfs.cbk.proc",
307                                 FT_UINT32, BASE_DEC,
308                                 VALS(gluster_cbk_proc_vals), 0, NULL, HFILL }
309                 }
310         };
311
312         /* Setup protocol subtree array */
313         static gint *ett[] = {
314                 &ett_gluster_cbk
315         };
316
317         /* Register the protocol name and description */
318         proto_gluster_cbk = proto_register_protocol("GlusterFS Callback",
319                                         "GlusterFS Callback", "glusterfs.cbk");
320         proto_register_subtree_array(ett, array_length(ett));
321         proto_register_field_array(proto_gluster_cbk, hf, array_length(hf));
322 }
323
324 void
325 proto_reg_handoff_gluster_cbk(void)
326 {
327         rpc_init_prog(proto_gluster_cbk, GLUSTER_CBK_PROGRAM, ett_gluster_cbk);
328         rpc_init_proc_table(GLUSTER_CBK_PROGRAM, 1, gluster_cbk_proc,
329                                                         hf_gluster_cbk_proc);
330 }
331