1 /* packet-gdsdb.c
2  * Routines for Firebird/Interbase dissection
3  * Copyright 2007, Moshe van der Sterre <moshevds@gmail.com>
4  *
5  * Firebird home: http://www.firebirdsql.org
6  * Source: http://sourceforge.net/projects/firebird/
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * SPDX-License-Identifier: GPL-2.0-or-later
13  */
14 
15 #include "config.h"
16 
17 #include <epan/packet.h>
18 
19 void proto_register_gdsdb(void);
20 void proto_reg_handoff_gdsdb(void);
21 
22 #define TCP_PORT	3050
23 
24 static int proto_gdsdb = -1;
25 static gint ett_gdsdb = -1;
26 static int hf_gdsdb_opcode = -1;
27 /* static gint ett_gdsdb_opcode = -1; */
28 
29 /* gdsdb_dummy */
30 /* gdsdb_connect */
31 static int hf_gdsdb_connect_operation = -1;
32 static int hf_gdsdb_connect_version = -1;
33 static int hf_gdsdb_connect_client = -1;
34 static int hf_gdsdb_connect_filename = -1;
35 static int hf_gdsdb_connect_count = -1;
36 static int hf_gdsdb_connect_userid = -1;
37 static int hf_gdsdb_connect_pref = -1;
38 static gint ett_gdsdb_connect_pref = -1;
39 static int hf_gdsdb_connect_pref_version = -1;
40 static int hf_gdsdb_connect_pref_architecture = -1;
41 static int hf_gdsdb_connect_pref_mintype = -1;
42 static int hf_gdsdb_connect_pref_maxtype = -1;
43 static int hf_gdsdb_connect_pref_weight = -1;
44 /* gdsdb_accept */
45 static int hf_gdsdb_accept_version = -1;
46 static int hf_gdsdb_accept_architecture = -1;
47 static int hf_gdsdb_accept_proto_min_type = -1;
48 /* gdsdb_request */
49 static int hf_gdsdb_request_type = -1;
50 static int hf_gdsdb_request_object = -1;
51 static int hf_gdsdb_request_partner = -1;
52 /* gdsdb_attach */
53 static int hf_gdsdb_attach_database_object_id = -1;
54 static int hf_gdsdb_attach_database_path = -1;
55 static int hf_gdsdb_attach_database_param_buf = -1;
56 /* gdsdb_compile */
57 static int hf_gdsdb_compile_database = -1;
58 static int hf_gdsdb_compile_blr = -1;
59 /* gdsdb_receive */
60 static int hf_gdsdb_receive_request = -1;
61 static int hf_gdsdb_receive_incarnation = -1;
62 static int hf_gdsdb_receive_transaction = -1;
63 static int hf_gdsdb_receive_msgnr = -1;
64 static int hf_gdsdb_receive_messages = -1;
65 static int hf_gdsdb_receive_direction = -1;
66 static int hf_gdsdb_receive_offset = -1;
67 /* gdsdb_send */
68 static int hf_gdsdb_send_request = -1;
69 static int hf_gdsdb_send_incarnation = -1;
70 static int hf_gdsdb_send_transaction = -1;
71 static int hf_gdsdb_send_msgnr = -1;
72 static int hf_gdsdb_send_messages = -1;
73 /* gdsdb_response */
74 static int hf_gdsdb_response_object = -1;
75 static int hf_gdsdb_response_blobid = -1;
76 static int hf_gdsdb_response_datasize = -1;
77 static int hf_gdsdb_response_data = -1;
78 /* gdsdb_status_vector */
79 static int hf_gdsdb_status_vector_arg = -1;
80 static int hf_gdsdb_status_vector_error_code = -1;
81 static int hf_gdsdb_status_vector_number = -1;
82 static int hf_gdsdb_status_vector_string = -1;
83 static int hf_gdsdb_status_vector_sql_state = -1;
84 /* gdsdb_transact */
85 static int hf_gdsdb_transact_database = -1;
86 static int hf_gdsdb_transact_transaction = -1;
87 #if 0
88 static int hf_gdsdb_transact_messages = -1;
89 #endif
90 /* gdsdb_transact_response */
91 static int hf_gdsdb_transactresponse_messages = -1;
92 /* gdsdb_open_blob2 */
93 static int hf_gdsdb_openblob2_bpb = -1;
94 /* gdsdb_open_blob */
95 static int hf_gdsdb_openblob_transaction = -1;
96 static int hf_gdsdb_openblob_id = -1;
97 #if 0
98 /* gdsdb_segment */
99 static int hf_gdsdb_segment_blob = -1;
100 static int hf_gdsdb_segment_length = -1;
101 static int hf_gdsdb_segment_segment = -1;
102 /* gdsdb_seek_blob */
103 static int hf_gdsdb_seekblob_blob = -1;
104 static int hf_gdsdb_seekblob_mode = -1;
105 #endif
106 /* gdsdb_reconnect */
107 static int hf_gdsdb_reconnect_handle = -1;
108 static int hf_gdsdb_reconnect_database_size = -1;
109 static int hf_gdsdb_reconnect_database = -1;
110 /* gdsdb_info & gdsdb_service_start */
111 static int hf_gdsdb_info_object = -1;
112 static int hf_gdsdb_info_incarnation = -1;
113 static int hf_gdsdb_info_items = -1;
114 static int hf_gdsdb_info_recv_items = -1;
115 static int hf_gdsdb_info_buffer_length = -1;
116 /* gdsdb_release */
117 static int hf_gdsdb_release_object = -1;
118 #if 0
119 /* gdsdb_prepare2 */
120 static int hf_gdsdb_prepare2_transaction = -1;
121 /* gdsdb_event & gdsdb_cancel_events */
122 static int hf_gdsdb_event_database = -1;
123 static int hf_gdsdb_event_items = -1;
124 static int hf_gdsdb_event_ast = -1;
125 static int hf_gdsdb_event_arg = -1;
126 static int hf_gdsdb_event_rid = -1;
127 /* gdsdb_ddl */
128 static int hf_gdsdb_ddl_database = -1;
129 static int hf_gdsdb_ddl_transaction = -1;
130 static int hf_gdsdb_ddl_blr = -1;
131 /* gdsdb_slice */
132 static int hf_gdsdb_slice_transaction = -1;
133 static int hf_gdsdb_slice_id = -1;
134 static int hf_gdsdb_slice_sdl = -1;
135 static int hf_gdsdb_slice_parameters = -1;
136 /* gdsdb_slice_response */
137 static int hf_gdsdb_sliceresponse_length = -1;
138 #endif
139 /* gdsdb_execute */
140 static int hf_gdsdb_execute_statement = -1;
141 static int hf_gdsdb_execute_transaction = -1;
142 static int hf_gdsdb_execute_message_number = -1;
143 static int hf_gdsdb_execute_messages = -1;
144 #if 0
145 /* gdsdb_execute2 */
146 static int hf_gdsdb_execute_outblr = -1;
147 static int hf_gdsdb_execute_outmsgnr = -1;
148 /* gdsdb_exec_immediate2 */
149 static int hf_gdsdb_prepare2_blr = -1;
150 static int hf_gdsdb_prepare2_number = -1;
151 static int hf_gdsdb_prepare2_messages = -1;
152 static int hf_gdsdb_prepare2_outblr = -1;
153 static int hf_gdsdb_prepare2_outmsgnr = -1;
154 #endif
155 /* gdsdb_prepare */
156 static int hf_gdsdb_prepare_transaction = -1;
157 static int hf_gdsdb_prepare_statement = -1;
158 static int hf_gdsdb_prepare_dialect = -1;
159 static int hf_gdsdb_prepare_querystr = -1;
160 static int hf_gdsdb_prepare_bufferlength = -1;
161 #if 0
162 /* gdsdb_fetch */
163 static int hf_gdsdb_fetch_statement = -1;
164 static int hf_gdsdb_fetch_message_number = -1;
165 static int hf_gdsdb_fetch_messages = -1;
166 /* gdsdb_fetch_response */
167 static int hf_gdsdb_fetchresponse_status = -1;
168 static int hf_gdsdb_fetchresponse_messages = -1;
169 #endif
170 /* gdsdb_free_statement */
171 static int hf_gdsdb_free_statement = -1;
172 static int hf_gdsdb_free_option = -1;
173 #if 0
174 /* gdsdb_insert */
175 static int hf_gdsdb_insert_statement = -1;
176 static int hf_gdsdb_insert_message_number = -1;
177 static int hf_gdsdb_insert_messages = -1;
178 /* gdsdb_cursor */
179 static int hf_gdsdb_cursor_statement = -1;
180 static int hf_gdsdb_cursor_type = -1;
181 /* gdsdb_sql_response */
182 static int hf_gdsdb_sqlresponse_messages = -1;
183 #endif
184 
185 enum
186 {
187 	op_void                   = 0,
188 	op_connect                = 1,
189 	op_exit                   = 2,
190 	op_accept                 = 3,
191 	op_reject                 = 4,
192 	op_protocol               = 5,
193 	op_disconnect             = 6,
194 	op_credit                 = 7,
195 	op_continuation           = 8,
196 	op_response               = 9,
197 	op_open_file              = 10,
198 	op_create_file            = 11,
199 	op_close_file             = 12,
200 	op_read_page              = 13,
201 	op_write_page             = 14,
202 	op_lock                   = 15,
203 	op_convert_lock           = 16,
204 	op_release_lock           = 17,
205 	op_blocking               = 18,
206 	op_attach                 = 19,
207 	op_create                 = 20,
208 	op_detach                 = 21,
209 	op_compile                = 22,
210 	op_start                  = 23,
211 	op_start_and_send         = 24,
212 	op_send                   = 25,
213 	op_receive                = 26,
214 	op_unwind                 = 27,
215 	op_release                = 28,
216 	op_transaction            = 29,
217 	op_commit                 = 30,
218 	op_rollback               = 31,
219 	op_prepare                = 32,
220 	op_reconnect              = 33,
221 	op_create_blob            = 34,
222 	op_open_blob              = 35,
223 	op_get_segment            = 36,
224 	op_put_segment            = 37,
225 	op_cancel_blob            = 38,
226 	op_close_blob             = 39,
227 	op_info_database          = 40,
228 	op_info_request           = 41,
229 	op_info_transaction       = 42,
230 	op_info_blob              = 43,
231 	op_batch_segments         = 44,
232 	op_mgr_set_affinity       = 45,
233 	op_mgr_clear_affinity     = 46,
234 	op_mgr_report             = 47,
235 	op_que_events             = 48,
236 	op_cancel_events          = 49,
237 	op_commit_retaining       = 50,
238 	op_prepare2               = 51,
239 	op_event                  = 52,
240 	op_connect_request        = 53,
241 	op_aux_connect            = 54,
242 	op_ddl                    = 55,
243 	op_open_blob2             = 56,
244 	op_create_blob2           = 57,
245 	op_get_slice              = 58,
246 	op_put_slice              = 59,
247 	op_slice                  = 60,
248 	op_seek_blob              = 61,
249 	op_allocate_statement     = 62,
250 	op_execute                = 63,
251 	op_exec_immediate         = 64,
252 	op_fetch                  = 65,
253 	op_fetch_response         = 66,
254 	op_free_statement         = 67,
255 	op_prepare_statement      = 68,
256 	op_set_cursor             = 69,
257 	op_info_sql               = 70,
258 	op_dummy                  = 71,
259 	op_response_piggyback     = 72,
260 	op_start_and_receive      = 73,
261 	op_start_send_and_receive = 74,
262 	op_exec_immediate2        = 75,
263 	op_execute2               = 76,
264 	op_insert                 = 77,
265 	op_sql_response           = 78,
266 	op_transact               = 79,
267 	op_transact_response      = 80,
268 	op_drop_database          = 81,
269 	op_service_attach         = 82,
270 	op_service_detach         = 83,
271 	op_service_info           = 84,
272 	op_service_start          = 85,
273 	op_rollback_retaining     = 86,
274 	op_update_account_info    = 87,
275 	op_authenticate_user      = 88,
276 	op_partial                = 89,
277 	op_trusted_auth           = 90,
278 	op_cancel                 = 91,
279 	op_max
280 };
281 
282 static const value_string gdsdb_opcode[] = {
283 	{ op_void,                   "Void" },
284 	{ op_connect,                "Connect" },
285 	{ op_exit,                   "Exit" },
286 	{ op_accept,                 "Accept" },
287 	{ op_reject,                 "Reject" },
288 	{ op_protocol,               "Protocol" },
289 	{ op_disconnect,             "Disconnect" },
290 	{ op_credit,                 "Credit" },
291 	{ op_continuation,           "Continuation" },
292 	{ op_response,               "Response" },
293 	{ op_open_file,              "Open file" },
294 	{ op_create_file,            "Create file" },
295 	{ op_close_file,             "Close file" },
296 	{ op_read_page,              "Read page" },
297 	{ op_write_page,             "Write page" },
298 	{ op_lock,                   "Lock" },
299 	{ op_convert_lock,           "Convert lock" },
300 	{ op_release_lock,           "Release lock" },
301 	{ op_blocking,               "Blocking" },
302 	{ op_attach,                 "Attach" },
303 	{ op_create,                 "Create" },
304 	{ op_detach,                 "Detach" },
305 	{ op_compile,                "Compile" },
306 	{ op_start,                  "Start" },
307 	{ op_start_and_send,         "Start and send" },
308 	{ op_send,                   "Send" },
309 	{ op_receive,                "Receive" },
310 	{ op_unwind,                 "Unwind" },
311 	{ op_release,                "Release" },
312 	{ op_transaction,            "Transaction" },
313 	{ op_commit,                 "Commit" },
314 	{ op_rollback,               "Rollback" },
315 	{ op_prepare,                "Prepare" },
316 	{ op_reconnect,              "Reconnect" },
317 	{ op_create_blob,            "Create blob" },
318 	{ op_open_blob,              "Open blob" },
319 	{ op_get_segment,            "Get segment" },
320 	{ op_put_segment,            "Put segment" },
321 	{ op_cancel_blob,            "Cancel blob" },
322 	{ op_close_blob,             "Close blob" },
323 	{ op_info_database,          "Info database" },
324 	{ op_info_request,           "Info request" },
325 	{ op_info_transaction,       "Info transaction" },
326 	{ op_info_blob,              "Info blob" },
327 	{ op_batch_segments,         "Batch segments" },
328 	{ op_mgr_set_affinity,       "Mgr set affinity" },
329 	{ op_mgr_clear_affinity,     "Mgr clear affinity" },
330 	{ op_mgr_report,             "Mgr report" },
331 	{ op_que_events,             "Que events" },
332 	{ op_cancel_events,          "Cancel events" },
333 	{ op_commit_retaining,       "Commit retaining" },
334 	{ op_prepare2,               "Prepare 2" },
335 	{ op_event,                  "Event" },
336 	{ op_connect_request,        "Connect request" },
337 	{ op_aux_connect,            "Aux connect" },
338 	{ op_ddl,                    "DDl" },
339 	{ op_open_blob2,             "Open blob 2" },
340 	{ op_create_blob2,           "Create blob 2" },
341 	{ op_get_slice,              "Get slice" },
342 	{ op_put_slice,              "Put slice" },
343 	{ op_slice,                  "Slice" },
344 	{ op_seek_blob,              "Seek blob" },
345 	{ op_allocate_statement,     "Allocate statement" },
346 	{ op_execute,                "Execute" },
347 	{ op_exec_immediate,         "Exec immediate" },
348 	{ op_fetch,                  "Fetch" },
349 	{ op_fetch_response,         "Fetch response" },
350 	{ op_free_statement,         "Free statement" },
351 	{ op_prepare_statement,      "Prepare statement" },
352 	{ op_set_cursor,             "Set cursor" },
353 	{ op_info_sql,               "Info sql" },
354 	{ op_dummy,                  "Dummy" },
355 	{ op_response_piggyback,     "Response piggyback" },
356 	{ op_start_and_receive,      "Start and receive" },
357 	{ op_start_send_and_receive, "Start send and receive" },
358 	{ op_exec_immediate2,        "Exec immediate 2" },
359 	{ op_execute2,               "Execute 2" },
360 	{ op_insert,                 "Insert" },
361 	{ op_sql_response,           "Sql response" },
362 	{ op_transact,               "Transact" },
363 	{ op_transact_response,      "Transact response" },
364 	{ op_drop_database,          "Drop database" },
365 	{ op_service_attach,         "Service attach" },
366 	{ op_service_detach,         "Service detach" },
367 	{ op_service_info,           "Service info" },
368 	{ op_service_start,          "Service start" },
369 	{ op_rollback_retaining,     "Rollback retaining" },
370 	{ op_update_account_info,    "update_account_info" },
371 	{ op_authenticate_user,      "authenticate_user" },
372 	{ op_partial,                "partial" },
373 	{ op_trusted_auth,           "trusted_auth" },
374 	{ op_cancel,                 "cancel" },
375 	{ 0, NULL }
376 };
377 
378 static const value_string gdsdb_architectures[] = {
379 	{  1, "Generic" },
380 	{  2, "Apollo" },
381 	{  3, "Sun" },
382 	{  4, "Vms" },
383 	{  5, "Ultrix" },
384 	{  6, "Alliant" },
385 	{  7, "MS-Dos" },
386 	{  8, "Sun 4" },
387 	{  9, "Sun 386" },
388 	{ 10, "HP-UX" },
389 	{ 11, "HP MPE/xl" },
390 	{ 12, "Mac" },
391 	{ 13, "Mac aux" },
392 	{ 14, "rt" },
393 	{ 15, "mips Ultrix" },
394 	{ 16, "HP-UX 68k" },
395 	{ 17, "Xenix" },
396 	{ 18, "Aviion" },
397 	{ 19, "SGI" },
398 	{ 20, "Apollo_dn10k" },
399 	{ 21, "Cray" },
400 	{ 22, "Imp" },
401 	{ 23, "Delta" },
402 	{ 24, "SCO" },
403 	{ 25, "Next" },
404 	{ 26, "Next 386" },
405 	{ 27, "m88k" },
406 	{ 28, "UnixWare" },
407 	{ 29, "Intel 32" },
408 	{ 30, "Epson" },
409 	{ 31, "Decosf" },
410 	{ 32, "Ncr3000" },
411 	{ 33, "NT PPC" },
412 	{ 34, "DG x86" },
413 	{ 35, "SCO ev" },
414 	{ 36, "Linux" },
415 	{ 37, "FreeBSD"  },
416 	{ 38, "NetBSD" },
417 	{ 39, "Darwin PPC" },
418 	{ 0, NULL }
419 };
420 
421 enum
422 {
423 	arg_end = 0,
424 	arg_gds = 1,
425 	arg_string = 2,
426 	arg_cstring = 3,
427 	arg_number = 4,
428 	arg_interpreted = 5,
429 	arg_vms = 6,
430 	arg_unix = 7,
431 	arg_domain = 8,
432 	arg_dos = 9,
433 	arg_mpexl = 10,
434 	arg_mpexl_ipc = 11,
435 	arg_next_mach = 15,
436 	arg_netware = 16,
437 	arg_win32 = 17,
438 	arg_warning = 18,
439 	arg_sql_state = 19
440 };
441 
442 static const value_string gdsdb_arg_types[] = {
443 	{  arg_end,  "end of argument list" },
444 	{  arg_gds,  "generic DSRI" },
445 	{  arg_string,  "string argument" },
446 	{  arg_cstring,  "count & string argument" },
447 	{  arg_number,  "numeric argument" },
448 	{  arg_interpreted,  "interpreted status code" },
449 	{  arg_vms,  "VAX/VMS status code" },
450 	{  arg_unix,  "UNIX error code" },
451 	{  arg_domain,  "Apollo/Domain error code" },
452 	{  arg_dos,  "MSDOS/OS2 error code" },
453 	{  arg_mpexl, "HP MPE/XL error code" },
454 	{  arg_mpexl_ipc, "HP MPE/XL IPC error code" },
455 	{  arg_next_mach, "NeXT/Mach error code" },
456 	{  arg_netware, "NetWare error code" },
457 	{  arg_win32, "Win32 error code" },
458 	{  arg_warning, "warning argument" },
459 	{  arg_sql_state, "SQLSTATE" },
460 	{ 0, NULL }
461 };
462 
dword_align(int length)463 static int dword_align(int length)
464 {
465 	return (length + (4-(length&3)));
466 }
467 
add_uint_string(proto_tree * tree,int hf_string,tvbuff_t * tvb,int offset)468 static int add_uint_string(proto_tree *tree, int hf_string, tvbuff_t *tvb, int offset)
469 {
470 	proto_item* ti;
471 	int length;
472 
473 	ti = proto_tree_add_item(tree, hf_string, tvb,
474 						offset, 4, ENC_ASCII|ENC_BIG_ENDIAN);
475 	length = dword_align(tvb_get_ntohl(tvb, offset))+4;
476 	proto_item_set_len(ti, length);
477 	return offset + length;
478 }
479 
add_byte_array(proto_tree * tree,int hf_len,int hf_byte,tvbuff_t * tvb,int offset)480 static int add_byte_array(proto_tree *tree, int hf_len, int hf_byte, tvbuff_t *tvb, int offset)
481 {
482 	proto_item* ti;
483 	guint32 length;
484 
485 	proto_tree_add_item_ret_uint(tree, hf_len, tvb,
486 						offset, 4, ENC_BIG_ENDIAN, &length);
487 	offset += 4;
488 	if (length > 0)
489 	{
490 		ti = proto_tree_add_item(tree, hf_byte, tvb,
491 						offset, length, ENC_NA);
492 		length = dword_align(length);
493 		proto_item_set_len(ti, length);
494 	}
495 	return offset + length;
496 }
497 
498 static int
gdsdb_dummy(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree _U_,int offset _U_)499 gdsdb_dummy(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree _U_, int offset _U_)
500 {
501 	/* Ignore data */
502 	return tvb_reported_length(tvb);
503 }
504 
505 static int
gdsdb_connect(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset)506 gdsdb_connect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
507 {
508 	int count, file_size, total_length = 16;
509 	int i, length = tvb_reported_length_remaining(tvb, offset);
510 	proto_item *ti;
511 	proto_tree *pref_tree;
512 
513 	/* Calculate if we need more data */
514 	if (length < total_length)
515 		return -1;
516 
517 	file_size = tvb_get_ntohl(tvb, offset+12);
518 	total_length += 4+dword_align(file_size);
519 	if (length < total_length+4)
520 		return -1;
521 
522 	count = tvb_get_ntohl(tvb, offset+total_length-4);
523 	total_length += (4+(count*20));
524 	if (length < total_length)
525 		return -1;
526 
527 	proto_tree_add_item(tree, hf_gdsdb_connect_operation, tvb,
528 							offset, 4, ENC_BIG_ENDIAN);
529 	offset += 4;
530 	proto_tree_add_item(tree, hf_gdsdb_connect_version, tvb,
531 							offset, 4, ENC_BIG_ENDIAN);
532 	offset += 4;
533 	proto_tree_add_item(tree, hf_gdsdb_connect_client, tvb,
534 							offset, 4, ENC_BIG_ENDIAN);
535 	offset += 4;
536 	offset = add_uint_string(tree, hf_gdsdb_connect_filename, tvb, offset);
537 
538 	proto_tree_add_item(tree, hf_gdsdb_connect_count, tvb,
539 							offset, 4, ENC_BIG_ENDIAN);
540 	offset += 4;
541 	col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", tvb_format_text(pinfo->pool, tvb, offset+4, tvb_get_ntohl(tvb, offset)));
542 	offset = add_uint_string(tree, hf_gdsdb_connect_userid, tvb, offset);
543 
544 	for(i=0;i<count;i++){
545 		ti = proto_tree_add_item(tree, hf_gdsdb_connect_pref, tvb, offset, 20, ENC_NA);
546 		pref_tree = proto_item_add_subtree(ti, ett_gdsdb_connect_pref);
547 
548 		proto_tree_add_item(pref_tree, hf_gdsdb_connect_pref_version,
549 						tvb, offset, 4, ENC_BIG_ENDIAN);
550 		offset += 4;
551 		proto_tree_add_item(pref_tree, hf_gdsdb_connect_pref_architecture,
552 						tvb, offset, 4, ENC_BIG_ENDIAN);
553 		offset += 4;
554 		proto_tree_add_item(pref_tree, hf_gdsdb_connect_pref_mintype,
555 						tvb, offset, 4, ENC_BIG_ENDIAN);
556 		offset += 4;
557 		proto_tree_add_item(pref_tree, hf_gdsdb_connect_pref_maxtype,
558 						tvb, offset, 4, ENC_BIG_ENDIAN);
559 		offset += 4;
560 		proto_tree_add_item(pref_tree, hf_gdsdb_connect_pref_weight,
561 						tvb, offset, 4, ENC_BIG_ENDIAN);
562 		offset += 4;
563 	}
564 
565 	return offset;
566 }
567 
568 static int
gdsdb_accept(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)569 gdsdb_accept(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
570 {
571 	/* Calculate if we need more data */
572 	if (tvb_reported_length_remaining(tvb, offset) < 12) {
573 		return -1;
574 	}
575 
576 	proto_tree_add_item(tree, hf_gdsdb_accept_version, tvb,
577 							offset, 4, ENC_BIG_ENDIAN);
578 	offset += 4;
579 	proto_tree_add_item(tree, hf_gdsdb_accept_architecture, tvb,
580 							offset, 4, ENC_BIG_ENDIAN);
581 	offset += 4;
582 	proto_tree_add_item(tree, hf_gdsdb_accept_proto_min_type, tvb,
583 							offset, 4, ENC_BIG_ENDIAN);
584 	offset += 4;
585 
586 	return offset;
587 }
588 
589 static int
gdsdb_request(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)590 gdsdb_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
591 {
592 	/* Calculate if we need more data */
593 	if (tvb_reported_length_remaining(tvb, offset) < 16) {
594 		return -1;
595 	}
596 
597 	proto_tree_add_item(tree, hf_gdsdb_request_type, tvb, offset, 4, ENC_BIG_ENDIAN);
598 	offset += 4;
599 
600 	proto_tree_add_item(tree, hf_gdsdb_request_object, tvb, offset, 4, ENC_BIG_ENDIAN);
601 	offset += 4;
602 
603 	proto_tree_add_item(tree, hf_gdsdb_request_partner, tvb, offset, 8, ENC_BIG_ENDIAN);
604 	offset += 8;
605 
606 	return offset;
607 }
608 
609 static int
gdsdb_attach(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset)610 gdsdb_attach(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
611 {
612 	int total_length = 12;
613 	int size, length = tvb_reported_length_remaining(tvb, offset);
614 
615 	/* Calculate if we need more data */
616 	if (length < total_length) {
617 		return -1;
618 	}
619 
620 	size = tvb_get_ntohl(tvb, offset+4);
621 	total_length += dword_align(size);
622 	if (length < total_length)
623 		return -1;
624 
625 	size = tvb_get_ntohl(tvb, offset+total_length-4);
626 	total_length += dword_align(size);
627 	if (length < total_length)
628 		return -1;
629 
630 	proto_tree_add_item(tree, hf_gdsdb_attach_database_object_id, tvb, offset, 4, ENC_BIG_ENDIAN);
631 	offset += 4;
632 
633 	col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", tvb_format_text(pinfo->pool, tvb, offset+4, tvb_get_ntohl(tvb, offset)));
634 	offset = add_uint_string(tree, hf_gdsdb_attach_database_path, tvb, offset);
635 	offset = add_uint_string(tree, hf_gdsdb_attach_database_param_buf, tvb, offset);
636 
637 	return offset;
638 }
639 
640 static int
gdsdb_compile(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)641 gdsdb_compile(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
642 {
643 	int total_length = 8;
644 	int size, length = tvb_reported_length_remaining(tvb, offset);
645 
646 	/* Calculate if we need more data */
647 	if (length < total_length) {
648 		return -1;
649 	}
650 
651 	size = tvb_get_ntohl(tvb, offset+4);
652 	total_length += dword_align(size);
653 	if (length < total_length)
654 		return -1;
655 
656 	proto_tree_add_item(tree, hf_gdsdb_compile_database, tvb, offset, 4, ENC_BIG_ENDIAN);
657 	offset += 4;
658 
659 	offset = add_uint_string(tree, hf_gdsdb_compile_blr, tvb, offset);
660 
661 	return offset;
662 }
663 
664 static int
gdsdb_receive(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)665 gdsdb_receive(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
666 {
667 	/* Calculate if we need more data */
668 	if (tvb_reported_length_remaining(tvb, offset) < 20) {
669 		return -1;
670 	}
671 
672 	proto_tree_add_item(tree, hf_gdsdb_receive_request, tvb,
673 							offset, 4, ENC_BIG_ENDIAN);
674 	offset += 4;
675 	proto_tree_add_item(tree, hf_gdsdb_receive_incarnation, tvb,
676 							offset, 4, ENC_BIG_ENDIAN);
677 	offset += 4;
678 	proto_tree_add_item(tree, hf_gdsdb_receive_transaction, tvb,
679 							offset, 4, ENC_BIG_ENDIAN);
680 	offset += 4;
681 	proto_tree_add_item(tree, hf_gdsdb_receive_msgnr, tvb,
682 							offset, 4, ENC_BIG_ENDIAN);
683 	offset += 4;
684 	proto_tree_add_item(tree, hf_gdsdb_receive_messages, tvb,
685 							offset, 4, ENC_BIG_ENDIAN);
686 	offset += 4;
687 	while (tvb_reported_length_remaining(tvb, offset) >= 12) {
688 		proto_tree_add_item(tree, hf_gdsdb_receive_direction,
689 						tvb, offset, 4, ENC_BIG_ENDIAN);
690 		offset += 4;
691 		proto_tree_add_item(tree, hf_gdsdb_receive_offset,
692 						 tvb, offset, 8, ENC_BIG_ENDIAN);
693 		offset += 8;
694 	}
695 
696 	return offset;
697 }
698 
699 static int
gdsdb_send(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)700 gdsdb_send(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
701 {
702 	/* Calculate if we need more data */
703 	if (tvb_reported_length_remaining(tvb, offset) < 20) {
704 		return -1;
705 	}
706 
707 	proto_tree_add_item(tree, hf_gdsdb_send_request, tvb,
708 							offset, 4, ENC_BIG_ENDIAN);
709 	offset += 4;
710 	proto_tree_add_item(tree, hf_gdsdb_send_incarnation, tvb,
711 							offset, 4, ENC_BIG_ENDIAN);
712 	offset += 4;
713 	proto_tree_add_item(tree, hf_gdsdb_send_transaction, tvb,
714 							offset, 4, ENC_BIG_ENDIAN);
715 	offset += 4;
716 	proto_tree_add_item(tree, hf_gdsdb_send_msgnr, tvb,
717 							offset, 4, ENC_BIG_ENDIAN);
718 	offset += 4;
719 	proto_tree_add_item(tree, hf_gdsdb_send_messages, tvb,
720 							offset, 4, ENC_BIG_ENDIAN);
721 	offset += 4;
722 
723 	return offset;
724 }
725 
726 static int
gdsdb_status_vector(proto_tree * tree,tvbuff_t * tvb,int offset)727 gdsdb_status_vector(proto_tree *tree, tvbuff_t *tvb, int offset)
728 {
729 	guint32 arg;
730 	while (tvb_reported_length_remaining(tvb, offset) >= 4)
731 	{
732 		proto_tree_add_item_ret_uint(tree, hf_gdsdb_status_vector_arg, tvb,
733 							offset, 4, ENC_BIG_ENDIAN, &arg);
734 		offset += 4;
735 		if (arg == 0)
736 			break;
737 
738 		switch(arg)
739 		{
740 		case arg_gds:
741 		default:
742 			proto_tree_add_item(tree, hf_gdsdb_status_vector_error_code, tvb,
743 							offset, 4, ENC_BIG_ENDIAN);
744 			offset += 4;
745 			break;
746 		case arg_number:
747 			proto_tree_add_item(tree, hf_gdsdb_status_vector_number, tvb,
748 							offset, 4, ENC_BIG_ENDIAN);
749 			offset += 4;
750 			break;
751 		case arg_string:
752 		case arg_interpreted:
753 			offset = add_uint_string(tree, hf_gdsdb_status_vector_string, tvb, offset);
754 			break;
755 		case arg_sql_state:
756 			offset = add_uint_string(tree, hf_gdsdb_status_vector_sql_state, tvb, offset);
757 			break;
758 		}
759 	}
760 
761 	return offset;
762 }
763 
764 static int
gdsdb_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)765 gdsdb_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
766 {
767 	int total_length = 16;
768 	int length = tvb_reported_length_remaining(tvb, offset);
769 	guint32 size_length;
770 
771 	/* Calculate if we need more data */
772 	if (length < total_length) {
773 		return -1;
774 	}
775 
776 	total_length += dword_align(tvb_get_ntohl(tvb, offset+12));
777 	if (length < total_length) {
778 		return -1;
779 	}
780 
781 	proto_tree_add_item(tree, hf_gdsdb_response_object, tvb,
782 							offset, 4, ENC_BIG_ENDIAN);
783 	offset += 4;
784 	proto_tree_add_item(tree, hf_gdsdb_response_blobid, tvb,
785 							offset, 8, ENC_BIG_ENDIAN);
786 	offset += 8;
787 	proto_tree_add_item_ret_uint(tree, hf_gdsdb_response_datasize, tvb,
788 							offset, 4, ENC_BIG_ENDIAN, &size_length);
789 	offset += 4;
790 	if (size_length > 0)
791 		proto_tree_add_item(tree, hf_gdsdb_response_data, tvb, offset, size_length, ENC_NA);
792 	offset += size_length;
793 
794 	return gdsdb_status_vector(tree, tvb, offset);
795 }
796 
797 static int
gdsdb_transact(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)798 gdsdb_transact(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
799 {
800 	/* Calculate if we need more data */
801 	if (tvb_reported_length_remaining(tvb, offset) < 8) {
802 		return -1;
803 	}
804 
805 	proto_tree_add_item(tree, hf_gdsdb_transact_database, tvb,
806 							offset, 4, ENC_BIG_ENDIAN);
807 	offset += 4;
808 	proto_tree_add_item(tree, hf_gdsdb_transact_transaction, tvb,
809 							offset, 4, ENC_BIG_ENDIAN);
810 	offset += 4;
811 
812 	return offset;
813 }
814 
815 static int
gdsdb_transact_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)816 gdsdb_transact_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
817 {
818 	/* Calculate if we need more data */
819 	if (tvb_reported_length_remaining(tvb, offset) < 4) {
820 		return -1;
821 	}
822 
823 	proto_tree_add_item(tree, hf_gdsdb_transactresponse_messages,
824 						tvb, offset, 4, ENC_BIG_ENDIAN);
825 	offset += 4;
826 
827 	return offset;
828 }
829 
830 static int
gdsdb_open_blob2(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)831 gdsdb_open_blob2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
832 {
833 	int total_length = 12;
834 	int length = tvb_reported_length_remaining(tvb, offset);
835 
836 	/* Calculate if we need more data */
837 	if (length < total_length) {
838 		return -1;
839 	}
840 
841 	total_length += dword_align(tvb_get_ntohl(tvb, offset));
842 	if (length < total_length) {
843 		return -1;
844 	}
845 
846 	offset = add_uint_string(tree, hf_gdsdb_openblob2_bpb, tvb, offset);
847 
848 	proto_tree_add_item(tree, hf_gdsdb_openblob_transaction, tvb,
849 							offset, 4, ENC_BIG_ENDIAN);
850 	offset += 4;
851 	proto_tree_add_item(tree, hf_gdsdb_openblob_id, tvb, offset,
852 								8, ENC_BIG_ENDIAN);
853 	offset += 8;
854 
855 	return offset;
856 }
857 
858 static int
gdsdb_open_blob(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)859 gdsdb_open_blob(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
860 {
861 	/* Calculate if we need more data */
862 	if (tvb_reported_length_remaining(tvb, offset) < 8) {
863 		return -1;
864 	}
865 
866 	proto_tree_add_item(tree, hf_gdsdb_openblob_transaction, tvb,
867 							offset, 4, ENC_BIG_ENDIAN);
868 	offset += 4;
869 	proto_tree_add_item(tree, hf_gdsdb_openblob_id, tvb, offset,
870 								8, ENC_BIG_ENDIAN);
871 	offset += 8;
872 
873 	return offset;
874 }
875 
876 static int
gdsdb_segment(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)877 gdsdb_segment(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
878 {
879 	/* Calculate if we need more data */
880 	if (tvb_reported_length_remaining(tvb, offset) < 12)
881 		return -1;
882 
883 	if (tree) {
884 /* hf_gdsdb_segment_blob */
885 /* hf_gdsdb_segment_length */
886 /* add_uint_string(hf_gdsdb_segment_segment )*/
887 	}
888 
889 	return tvb_reported_length(tvb);
890 }
891 
892 static int
gdsdb_seek_blob(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)893 gdsdb_seek_blob(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
894 {
895 	/* Calculate if we need more data */
896 	if (tvb_reported_length_remaining(tvb, offset) < 12)
897 		return -1;
898 
899 	if (tree) {
900 /* hf_gdsdb_seekblob_blob */
901 /* hf_gdsdb_seekblob_mode */
902 	}
903 
904 	return tvb_reported_length(tvb);
905 }
906 
907 static int
gdsdb_reconnect(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)908 gdsdb_reconnect(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
909 {
910 	int total_length = 8;
911 	int length = tvb_reported_length_remaining(tvb, offset);
912 
913 	/* Calculate if we need more data */
914 	if (length < total_length) {
915 		return -1;
916 	}
917 
918 	total_length += dword_align(tvb_get_ntohl(tvb, offset+4));
919 	if (length < total_length) {
920 		return -1;
921 	}
922 
923 	proto_tree_add_item(tree, hf_gdsdb_reconnect_handle, tvb, offset,
924 								4, ENC_BIG_ENDIAN);
925 	offset += 4;
926 	offset = add_byte_array(tree, hf_gdsdb_reconnect_database_size, hf_gdsdb_reconnect_database, tvb, offset);
927 
928 	return offset;
929 }
930 
931 static int
gdsdb_info(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)932 gdsdb_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
933 {
934 	guint opcode;
935 	int total_length = 16;
936 	int length = tvb_reported_length_remaining(tvb, offset);
937 
938 	/* Calculate if we need more data */
939 	if (length < total_length) {
940 		return -1;
941 	}
942 
943 	opcode = tvb_get_ntohl(tvb, offset-4);
944 
945 	total_length += dword_align(tvb_get_ntohl(tvb, offset+8));
946 	if (length < total_length) {
947 		return -1;
948 	}
949 
950 	if(opcode == op_service_info) {
951 		total_length += dword_align(tvb_get_ntohl(tvb, offset+total_length-8));
952 		if (length < total_length) {
953 			return -1;
954 		}
955 	}
956 
957 	proto_tree_add_item(tree, hf_gdsdb_info_object, tvb, offset,
958 								4, ENC_BIG_ENDIAN);
959 	offset += 4;
960 	proto_tree_add_item(tree, hf_gdsdb_info_incarnation, tvb,
961 							offset, 4, ENC_BIG_ENDIAN);
962 	offset += 4;
963 
964 	offset = add_uint_string(tree, hf_gdsdb_info_items, tvb, offset);
965 	if(opcode == op_service_info) {
966 		offset = add_uint_string(tree, hf_gdsdb_info_recv_items, tvb, offset);
967 	}
968 
969 	proto_tree_add_item(tree, hf_gdsdb_info_buffer_length, tvb,
970 							offset, 4, ENC_BIG_ENDIAN);
971 	offset += 4;
972 
973 	return offset;
974 }
975 
976 static int
gdsdb_service_start(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)977 gdsdb_service_start(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
978 {
979 	/* Calculate if we need more data */
980 	if (tvb_reported_length_remaining(tvb, offset) < 16)
981 		return -1;
982 
983 	if (tree) {
984 /* hf_gdsdb_info_object */
985 /* hf_gdsdb_info_incarnation */
986 /* hf_gdsdb_info_items */
987 /* hf_gdsdb_info_buffer_length */
988 	}
989 
990 	return tvb_reported_length(tvb);
991 }
992 
993 static int
gdsdb_release(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)994 gdsdb_release(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
995 {
996 	/* Calculate if we need more data */
997 	if (tvb_reported_length_remaining(tvb, offset) < 4)
998 		return -1;
999 
1000 	proto_tree_add_item(tree, hf_gdsdb_release_object, tvb, offset,
1001 								4, ENC_BIG_ENDIAN);
1002 	/* offset += 4; */
1003 
1004 	/* Unsure dissection is complete, so don't allow other commands to
1005 		follow by returning offset*/
1006 	return tvb_reported_length(tvb);
1007 }
1008 
1009 #if 0
1010 static int
1011 gdsdb_prepare2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1012 {
1013 	/* Calculate if we need more data */
1014 	if (tvb_reported_length_remaining(tvb, offset) < 8)
1015 		return -1;
1016 
1017 	if (tree) {
1018 /* hf_gdsdb_prepare2_transaction */
1019 	}
1020 
1021 	return tvb_reported_length(tvb);
1022 }
1023 #endif
1024 
1025 static int
gdsdb_event(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1026 gdsdb_event(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1027 {
1028 	/* Calculate if we need more data */
1029 	if (tvb_reported_length_remaining(tvb, offset) < 20)
1030 		return -1;
1031 
1032 	if (tree) {
1033 /* hf_gdsdb_event_database */
1034 /* add_uint_string(hf_gdsdb_event_items) */
1035 /* hf_gdsdb_event_ast */
1036 /* hf_gdsdb_event_arg */
1037 /* hf_gdsdb_event_rid */
1038 	}
1039 
1040 	return tvb_reported_length(tvb);
1041 }
1042 
1043 static int
gdsdb_cancel_events(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1044 gdsdb_cancel_events(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1045 {
1046 	/* Calculate if we need more data */
1047 	if (tvb_reported_length_remaining(tvb, offset) < 8)
1048 		return -1;
1049 
1050 	if (tree) {
1051 /* hf_gdsdb_event_database */
1052 	}
1053 
1054 	return tvb_reported_length(tvb);
1055 }
1056 
1057 static int
gdsdb_ddl(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1058 gdsdb_ddl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1059 {
1060 	/* Calculate if we need more data */
1061 	if (tvb_reported_length_remaining(tvb, offset) < 12)
1062 		return -1;
1063 
1064 	if (tree) {
1065 /* hf_gdsdb_ddl_database */
1066 /* hf_gdsdb_ddl_transaction */
1067 /* add_uint_string(hf_gdsdb_ddl_blr) */
1068 	}
1069 
1070 	return tvb_reported_length(tvb);
1071 }
1072 
1073 static int
gdsdb_slice(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1074 gdsdb_slice(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1075 {
1076 	/* Calculate if we need more data */
1077 	if (tvb_reported_length_remaining(tvb, offset) < 20)
1078 		return -1;
1079 
1080 	if (tree) {
1081 /* hf_gdsdb_slice_transaction */
1082 /* hf_gdsdb_slice_id */
1083 /* add_uint_string(hf_gdsdb_slice_sdl) */
1084 /* hf_gdsdb_slice_parameters */
1085 	}
1086 
1087 	return tvb_reported_length(tvb);
1088 }
1089 
1090 static int
gdsdb_slice_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1091 gdsdb_slice_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1092 {
1093 	/* Calculate if we need more data */
1094 	if (tvb_reported_length_remaining(tvb, offset) < 4)
1095 		return -1;
1096 
1097 	if (tree) {
1098 /* hf_gdsdb_sliceresponse_length */
1099 	}
1100 
1101 	return tvb_reported_length(tvb);
1102 }
1103 
1104 static int
gdsdb_execute(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1105 gdsdb_execute(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1106 {
1107 	/* Calculate if we need more data */
1108 	if (tvb_reported_length_remaining(tvb, offset) < 16)
1109 		return -1;
1110 
1111 	proto_tree_add_item(tree, hf_gdsdb_execute_statement, tvb,
1112 							offset, 4, ENC_BIG_ENDIAN);
1113 	offset += 4;
1114 	proto_tree_add_item(tree, hf_gdsdb_execute_transaction, tvb,
1115 							offset, 4, ENC_BIG_ENDIAN);
1116 	offset += 4;
1117 	proto_tree_add_item(tree, hf_gdsdb_execute_message_number, tvb,
1118 							offset, 4, ENC_BIG_ENDIAN);
1119 	offset += 4;
1120 	proto_tree_add_item(tree, hf_gdsdb_execute_messages, tvb,
1121 							offset, 4, ENC_BIG_ENDIAN);
1122 	/* offset += 4; */
1123 
1124 	/* Unsure dissection is complete, so don't allow other commands to
1125 		follow by returning offset*/
1126 	return tvb_reported_length(tvb);
1127 }
1128 
1129 static int
gdsdb_exec_immediate2(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1130 gdsdb_exec_immediate2(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1131 {
1132 	/* Calculate if we need more data */
1133 	if (tvb_reported_length_remaining(tvb, offset) < 40)
1134 		return -1;
1135 
1136 	if (tree) {
1137 /* hf_gdsdb_prepare2_blr */
1138 /* hf_gdsdb_prepare2_number */
1139 /* hf_gdsdb_prepare2_messages */
1140 /* hf_gdsdb_prepare2_outblr */
1141 /* hf_gdsdb_prepare2_outmsgnr */
1142 	}
1143 
1144 	return tvb_reported_length(tvb);
1145 }
1146 
1147 static int
gdsdb_prepare(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset)1148 gdsdb_prepare(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1149 {
1150 	int total_length = 20;
1151 	int length = tvb_reported_length_remaining(tvb, offset);
1152 
1153 	/* Calculate if we need more data */
1154 	if (length < total_length) {
1155 		return -1;
1156 	}
1157 
1158 	total_length += dword_align(tvb_get_ntohl(tvb, offset+12));
1159 	if (length < total_length) {
1160 		return -1;
1161 	}
1162 
1163 	proto_tree_add_item(tree, hf_gdsdb_prepare_transaction, tvb,
1164 							offset, 4, ENC_BIG_ENDIAN);
1165 	offset += 4;
1166 	proto_tree_add_item(tree, hf_gdsdb_prepare_statement, tvb,
1167 							offset, 4, ENC_BIG_ENDIAN);
1168 	offset += 4;
1169 	proto_tree_add_item(tree, hf_gdsdb_prepare_dialect, tvb,
1170 							offset, 4, ENC_BIG_ENDIAN);
1171 	offset += 4;
1172 	col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", tvb_format_text(pinfo->pool, tvb, offset+4, tvb_get_ntohl(tvb, offset)));
1173 	offset = add_uint_string(tree, hf_gdsdb_prepare_querystr, tvb, offset);
1174 
1175 	proto_tree_add_item(tree, hf_gdsdb_prepare_bufferlength, tvb,
1176 							offset, 4, ENC_BIG_ENDIAN);
1177 	offset += 4;
1178 
1179 	return offset;
1180 }
1181 
1182 static int
gdsdb_fetch(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1183 gdsdb_fetch(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1184 {
1185 	/* Calculate if we need more data */
1186 	if (tvb_reported_length_remaining(tvb, offset) < 12) {
1187 		return -1;
1188 	}
1189 
1190 	if (tree) {
1191 /* hf_gdsdb_fetch_statement */
1192 /* hf_gdsdb_fetch_message_number */
1193 /* hf_gdsdb_fetch_messages */
1194 	}
1195 
1196 	return tvb_reported_length(tvb);
1197 }
1198 
1199 static int
gdsdb_fetch_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1200 gdsdb_fetch_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1201 {
1202 	/* Calculate if we need more data */
1203 	if (tvb_reported_length_remaining(tvb, offset) < 8) {
1204 		return -1;
1205 	}
1206 
1207 	if (tree) {
1208 /* hf_gdsdb_fetchresponse_status */
1209 /* hf_gdsdb_fetchresponse_messages */
1210 	}
1211 
1212 	return tvb_reported_length(tvb);
1213 }
1214 
1215 static int
gdsdb_free_statement(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1216 gdsdb_free_statement(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1217 {
1218 	/* Calculate if we need more data */
1219 	if (tvb_reported_length_remaining(tvb, offset) < 8) {
1220 		return -1;
1221 	}
1222 
1223 	proto_tree_add_item(tree, hf_gdsdb_free_statement, tvb,
1224 							offset, 4, ENC_BIG_ENDIAN);
1225 	offset += 4;
1226 	proto_tree_add_item(tree, hf_gdsdb_free_option, tvb,
1227 							offset, 4, ENC_BIG_ENDIAN);
1228 	offset += 4;
1229 
1230 	return offset;
1231 }
1232 
1233 static int
gdsdb_insert(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1234 gdsdb_insert(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1235 {
1236 	/* Calculate if we need more data */
1237 	if (tvb_reported_length_remaining(tvb, offset) < 12) {
1238 		return -1;
1239 	}
1240 
1241 	if (tree) {
1242 /* hf_gdsdb_insert_statement */
1243 /* hf_gdsdb_insert_message_number */
1244 /* hf_gdsdb_insert_messages */
1245 	}
1246 
1247 	return tvb_reported_length(tvb);
1248 }
1249 
1250 static int
gdsdb_cursor(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1251 gdsdb_cursor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1252 {
1253 	/* Calculate if we need more data */
1254 	if (tvb_reported_length_remaining(tvb, offset) < 12) {
1255 		return -1;
1256 	}
1257 
1258 	if (tree) {
1259 /* hf_gdsdb_cursor_statement */
1260 /* hf_gdsdb_cursor_type */
1261 	}
1262 
1263 	return tvb_reported_length(tvb);
1264 }
1265 
1266 static int
gdsdb_sql_response(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int offset)1267 gdsdb_sql_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1268 {
1269 	/* Calculate if we need more data */
1270 	if (tvb_reported_length_remaining(tvb, offset) < 4) {
1271 		return -1;
1272 	}
1273 
1274 	if (tree) {
1275 /* hf_gdsdb_sqlresponse_messages */
1276 	}
1277 
1278 	return tvb_reported_length(tvb);
1279 }
1280 
1281 static int (*gdsdb_handle_opcode[])(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) = {
1282 	gdsdb_dummy,             /* op_void */
1283 	gdsdb_connect,           /* op_connect */
1284 	gdsdb_dummy,             /* op_exit */
1285 	gdsdb_accept,            /* op_accept */
1286 	gdsdb_dummy,             /* op_reject */
1287 	gdsdb_dummy,             /* op_protocol */
1288 	gdsdb_dummy,             /* op_disconnect */
1289 	gdsdb_dummy,             /* op_credit */
1290 	gdsdb_dummy,             /* op_continuation */
1291 	gdsdb_response,          /* op_response */
1292 	gdsdb_dummy,             /* op_open_file */
1293 	gdsdb_dummy,             /* op_create_file */
1294 	gdsdb_dummy,             /* op_close_file */
1295 	gdsdb_dummy,             /* op_read_page */
1296 	gdsdb_dummy,             /* op_write_page */
1297 	gdsdb_dummy,             /* op_lock */
1298 	gdsdb_dummy,             /* op_convert_lock */
1299 	gdsdb_dummy,             /* op_release_lock */
1300 	gdsdb_dummy,             /* op_blocking */
1301 	gdsdb_attach,            /* op_attach */
1302 	gdsdb_attach,            /* op_create */
1303 	gdsdb_release,           /* op_detach */
1304 	gdsdb_compile,           /* op_compile */
1305 	gdsdb_receive,           /* op_start */
1306 	gdsdb_send,              /* op_start_and_send */
1307 	gdsdb_send,              /* op_send */
1308 	gdsdb_receive,           /* op_receive */
1309 	gdsdb_release,           /* op_unwind */
1310 	gdsdb_release,           /* op_release */
1311 	gdsdb_reconnect,         /* op_transaction */
1312 	gdsdb_release,           /* op_commit */
1313 	gdsdb_release,           /* op_rollback */
1314 	gdsdb_release,           /* op_prepare */
1315 	gdsdb_reconnect,         /* op_reconnect */
1316 	gdsdb_open_blob2,        /* op_create_blob */
1317 	gdsdb_open_blob,         /* op_open_blob */
1318 	gdsdb_segment,           /* op_get_segment */
1319 	gdsdb_segment,           /* op_put_segment */
1320 	gdsdb_release,           /* op_cancel_blob */
1321 	gdsdb_release,           /* op_close_blob */
1322 	gdsdb_info,              /* op_info_database */
1323 	gdsdb_info,              /* op_info_request */
1324 	gdsdb_info,              /* op_info_transaction */
1325 	gdsdb_info,              /* op_info_blob */
1326 	gdsdb_segment,           /* op_batch_segments */
1327 	gdsdb_dummy,             /* op_mgr_set_affinity */
1328 	gdsdb_dummy,             /* op_mgr_clear_affinity */
1329 	gdsdb_dummy,             /* op_mgr_report */
1330 	gdsdb_event,             /* op_que_events */
1331 	gdsdb_cancel_events,     /* op_cancel_events */
1332 	gdsdb_release,           /* op_commit_retaining */
1333 	gdsdb_release,           /* op_prepare */
1334 	gdsdb_event,             /* op_event */
1335 	gdsdb_request,           /* op_connect_request */
1336 	gdsdb_request,           /* op_aux_connect */
1337 	gdsdb_ddl,               /* op_ddl */
1338 	gdsdb_open_blob2,        /* op_open_blob2 */
1339 	gdsdb_open_blob2,        /* op_create_blob2 */
1340 	gdsdb_slice,             /* op_get_slice */
1341 	gdsdb_slice,             /* op_put_slice */
1342 	gdsdb_slice_response,    /* op_slice */
1343 	gdsdb_seek_blob,         /* op_seek_blob */
1344 	gdsdb_release,           /* op_allocate_statement */
1345 	gdsdb_execute,           /* op_execute */
1346 	gdsdb_prepare,           /* op_exec_immediate */
1347 	gdsdb_fetch,             /* op_fetch */
1348 	gdsdb_fetch_response,    /* op_fetch_response */
1349 	gdsdb_free_statement,    /* op_free_statement */
1350 	gdsdb_prepare,           /* op_prepare_statement */
1351 	gdsdb_cursor,            /* op_set_cursor */
1352 	gdsdb_info,              /* op_info_sql */
1353 	gdsdb_dummy,             /* op_dummy */
1354 	gdsdb_response,          /* op_response_piggyback */
1355 	gdsdb_receive,           /* op_start_and_receive */
1356 	gdsdb_send,              /* op_start_send_and_receive */
1357 	gdsdb_exec_immediate2,   /* op_exec_immediate2 */
1358 	gdsdb_execute,           /* op_execute2 */
1359 	gdsdb_insert,            /* op_insert */
1360 	gdsdb_sql_response,      /* op_sql_response */
1361 	gdsdb_transact,          /* op_transact */
1362 	gdsdb_transact_response, /* op_transact_response */
1363 	gdsdb_release,           /* op_drop_database */
1364 	gdsdb_attach,            /* op_service_attach */
1365 	gdsdb_release,           /* op_service_detach */
1366 	gdsdb_info,              /* op_service_info */
1367 	gdsdb_service_start,     /* op_service_start */
1368 	gdsdb_release,           /* op_rollback_retaining */
1369 	gdsdb_dummy,             /* op_update_account_info */
1370 	gdsdb_dummy,             /* op_authenticate_user */
1371 	gdsdb_dummy,             /* op_partial */
1372 	gdsdb_dummy,             /* op_trusted_auth */
1373 	gdsdb_dummy              /* op_cancel */
1374 };
1375 
1376 static int
dissect_gdsdb(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1377 dissect_gdsdb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1378 {
1379 	proto_item  *ti;
1380 	proto_tree  *gdsdb_tree;
1381 	guint        opcode;
1382 	int          offset = 0;
1383 
1384 	if (tvb_reported_length(tvb) < 4)
1385 		return 0;
1386 
1387 	/* Ensure at least the first opcode is valid */
1388 	opcode = tvb_get_ntohl(tvb, offset);
1389 	if(opcode >= op_max)
1390 		return 0;
1391 
1392 	col_set_str(pinfo->cinfo, COL_PROTOCOL, "GDS DB");
1393 	col_clear(pinfo->cinfo, COL_INFO);
1394 
1395 	while (tvb_reported_length_remaining(tvb, offset) >= 4)
1396 	{
1397 		opcode = tvb_get_ntohl(tvb, offset);
1398 		if(opcode >= op_max)
1399 			return 0;
1400 
1401 		col_append_sep_str(pinfo->cinfo, COL_INFO, ", ",
1402 				val_to_str(opcode, gdsdb_opcode, "Unknown opcode %u"));
1403 
1404 		ti = proto_tree_add_item(tree, proto_gdsdb, tvb, offset, -1, ENC_NA);
1405 		gdsdb_tree = proto_item_add_subtree(ti, ett_gdsdb);
1406 		proto_tree_add_item(gdsdb_tree, hf_gdsdb_opcode, tvb,
1407 								offset, 4, ENC_BIG_ENDIAN);
1408 
1409 		/* opcode < op_max */
1410 		offset = gdsdb_handle_opcode[opcode](tvb, pinfo, gdsdb_tree, offset+4);
1411 		if (offset < 0)
1412 		{
1413 			/* But at this moment we don't know how much we will need */
1414 			pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
1415 			return -1; /* need more data */
1416 		}
1417 	}
1418 
1419 	return offset;
1420 }
1421 
1422 void
proto_register_gdsdb(void)1423 proto_register_gdsdb(void)
1424 {
1425 	static hf_register_info hf[] = {
1426 		{ &hf_gdsdb_opcode,
1427 			{ "Opcode", "gdsdb.opcode",
1428 			FT_UINT32, BASE_DEC, VALS(gdsdb_opcode), 0x0,
1429 			NULL, HFILL }
1430 		},
1431 		/* gdsdb_dummy */
1432 		/* gdsdb_connect */
1433 		{ &hf_gdsdb_connect_operation,
1434 			{ "Operation", "gdsdb.connect.operation",
1435 			FT_UINT32, BASE_DEC, VALS(gdsdb_opcode), 0x0,
1436 			NULL, HFILL }
1437 		},
1438 		{ &hf_gdsdb_connect_version,
1439 			{ "Version", "gdsdb.connect.version",
1440 			FT_UINT32, BASE_DEC, NULL, 0x0,
1441 			NULL, HFILL }
1442 		},
1443 		{ &hf_gdsdb_connect_client,
1444 			{ "Client Architecture", "gdsdb.connect.client",
1445 			FT_UINT32, BASE_DEC, VALS(gdsdb_architectures), 0x0,
1446 			NULL, HFILL }
1447 		},
1448 		{ &hf_gdsdb_connect_filename,
1449 			{ "Filename", "gdsdb.connect.filename",
1450 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1451 			NULL, HFILL }
1452 		},
1453 		{ &hf_gdsdb_connect_count,
1454 			{ "Version option count", "gdsdb.connect.count",
1455 			FT_UINT32, BASE_DEC, NULL, 0x0,
1456 			NULL, HFILL }
1457 		},
1458 		{ &hf_gdsdb_connect_userid,
1459 			{ "User ID", "gdsdb.connect.userid",
1460 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1461 			NULL, HFILL }
1462 		},
1463 		{ &hf_gdsdb_connect_pref,
1464 			{ "Preferred version", "gdsdb.connect.pref",
1465 			FT_NONE, BASE_NONE, NULL, 0x0,
1466 			NULL, HFILL }
1467 		},
1468 		{ &hf_gdsdb_connect_pref_version,
1469 			{ "Version", "gdsdb.connect.pref.version",
1470 			FT_INT32, BASE_DEC, NULL, 0x0,
1471 			NULL, HFILL }
1472 		},
1473 		{ &hf_gdsdb_connect_pref_architecture,
1474 			{ "Architecture", "gdsdb.connect.pref.arch",
1475 			FT_UINT32, BASE_DEC, VALS(gdsdb_architectures), 0x0,
1476 			NULL, HFILL }
1477 		},
1478 		{ &hf_gdsdb_connect_pref_mintype,
1479 			{ "Minimum type", "gdsdb.connect.pref.mintype",
1480 			FT_UINT32, BASE_DEC, NULL, 0x0,
1481 			NULL, HFILL }
1482 		},
1483 		{ &hf_gdsdb_connect_pref_maxtype,
1484 			{ "Maximum type", "gdsdb.connect.pref.maxtype",
1485 			FT_UINT32, BASE_DEC, NULL, 0x0,
1486 			NULL, HFILL }
1487 		},
1488 		{ &hf_gdsdb_connect_pref_weight,
1489 			{ "Preference weight", "gdsdb.connect.pref.weight",
1490 			FT_UINT32, BASE_DEC, NULL, 0x0,
1491 			NULL, HFILL }
1492 		},
1493 		/* gdsdb_accept */
1494 		{ &hf_gdsdb_accept_version,
1495 			{ "Version", "gdsdb.accept.version",
1496 			FT_UINT32, BASE_DEC, NULL, 0x0,
1497 			NULL, HFILL }
1498 		},
1499 		{ &hf_gdsdb_accept_architecture,
1500 			{ "Architecture", "gdsdb.accept.arch",
1501 			FT_UINT32, BASE_DEC, VALS(gdsdb_architectures), 0x0,
1502 			NULL, HFILL }
1503 		},
1504 		{ &hf_gdsdb_accept_proto_min_type,
1505 			{ "Protocol Minimum Type", "gdsdb.accept.proto_min_type",
1506 			FT_UINT32, BASE_DEC, NULL, 0x0,
1507 			NULL, HFILL }
1508 		},
1509 		/* gdsdb_request */
1510 		{ &hf_gdsdb_request_type,
1511 			{ "Type", "gdsdb.connect.type",
1512 			FT_UINT32, BASE_DEC, NULL, 0x0,
1513 			NULL, HFILL }
1514 		},
1515 		{ &hf_gdsdb_request_object,
1516 			{ "Object", "gdsdb.connect.object",
1517 			FT_UINT32, BASE_DEC, NULL, 0x0,
1518 			NULL, HFILL }
1519 		},
1520 		{ &hf_gdsdb_request_partner,
1521 			{ "Partner", "gdsdb.connect.partner",
1522 			FT_UINT64, BASE_DEC, NULL, 0x0,
1523 			NULL, HFILL }
1524 		},
1525 		/* gdsdb_attach */
1526 		{ &hf_gdsdb_attach_database_object_id,
1527 			{ "Database ObjectID", "gdsdb.attach.database_object_id",
1528 			FT_UINT32, BASE_DEC, NULL, 0x0,
1529 			NULL, HFILL }
1530 		},
1531 		{ &hf_gdsdb_attach_database_path,
1532 			{ "Database Path", "gdsdb.attach.database_path",
1533 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1534 			NULL, HFILL }
1535 		},
1536 		{ &hf_gdsdb_attach_database_param_buf,
1537 			{ "Database Parameter Buffers", "gdsdb.attach.database_param_buf",
1538 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1539 			NULL, HFILL }
1540 		},
1541 		/* gdsdb_compile */
1542 		{ &hf_gdsdb_compile_database,
1543 			{ "Database", "gdsdb.compile.filename",
1544 			FT_UINT32, BASE_DEC, NULL, 0x0,
1545 			NULL, HFILL }
1546 		},
1547 		{ &hf_gdsdb_compile_blr,
1548 			{ "BLR", "gdsdb.compile.blr",
1549 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1550 			NULL, HFILL }
1551 		},
1552 		/* gdsdb_receive */
1553 		{ &hf_gdsdb_receive_request,
1554 			{ "Request", "gdsdb.receive.request",
1555 			FT_UINT32, BASE_DEC, NULL, 0x0,
1556 			NULL, HFILL }
1557 		},
1558 		{ &hf_gdsdb_receive_incarnation,
1559 			{ "Incarnation", "gdsdb.receive.incarnation",
1560 			FT_UINT32, BASE_DEC, NULL, 0x0,
1561 			NULL, HFILL }
1562 		},
1563 		{ &hf_gdsdb_receive_transaction,
1564 			{ "Transaction", "gdsdb.receive.transaction",
1565 			FT_UINT32, BASE_DEC, NULL, 0x0,
1566 			NULL, HFILL }
1567 		},
1568 		{ &hf_gdsdb_receive_msgnr,
1569 			{ "Message number", "gdsdb.receive.msgnr",
1570 			FT_UINT32, BASE_DEC, NULL, 0x0,
1571 			NULL, HFILL }
1572 		},
1573 		{ &hf_gdsdb_receive_messages,
1574 			{ "Message Count", "gdsdb.receive.msgcount",
1575 			FT_UINT32, BASE_DEC, NULL, 0x0,
1576 			NULL, HFILL }
1577 		},
1578 		{ &hf_gdsdb_receive_direction,
1579 			{ "Scroll direction", "gdsdb.receive.direction",
1580 			FT_UINT32, BASE_DEC, NULL, 0x0,
1581 			NULL, HFILL }
1582 		},
1583 		{ &hf_gdsdb_receive_offset,
1584 			{ "Scroll offset", "gdsdb.receive.offset",
1585 			FT_UINT32, BASE_DEC, NULL, 0x0,
1586 			NULL, HFILL }
1587 		},
1588 		/* gdsdb_send */
1589 		{ &hf_gdsdb_send_request,
1590 			{ "Send request", "gdsdb.send.request",
1591 			FT_UINT32, BASE_DEC, NULL, 0x0,
1592 			NULL, HFILL }
1593 		},
1594 		{ &hf_gdsdb_send_incarnation,
1595 			{ "Send request", "gdsdb.send.incarnation",
1596 			FT_UINT32, BASE_DEC, NULL, 0x0,
1597 			NULL, HFILL }
1598 		},
1599 		{ &hf_gdsdb_send_transaction,
1600 			{ "Send request", "gdsdb.send.transaction",
1601 			FT_UINT32, BASE_DEC, NULL, 0x0,
1602 			NULL, HFILL }
1603 		},
1604 		{ &hf_gdsdb_send_msgnr,
1605 			{ "Send request", "gdsdb.send.msgnr",
1606 			FT_UINT32, BASE_DEC, NULL, 0x0,
1607 			NULL, HFILL }
1608 		},
1609 		{ &hf_gdsdb_send_messages,
1610 			{ "Send request", "gdsdb.send.messages",
1611 			FT_UINT32, BASE_DEC, NULL, 0x0,
1612 			NULL, HFILL }
1613 		},
1614 		/* gdsdb_response */
1615 		{ &hf_gdsdb_response_object,
1616 			{ "Response object", "gdsdb.response.object",
1617 			FT_UINT32, BASE_HEX, NULL, 0x0,
1618 			NULL, HFILL }
1619 		},
1620 		{ &hf_gdsdb_response_blobid,
1621 			{ "Blob ID", "gdsdb.response.blobid",
1622 			FT_UINT64, BASE_HEX, NULL, 0x0,
1623 			NULL, HFILL }
1624 		},
1625 		{ &hf_gdsdb_response_datasize,
1626 			{ "Data size", "gdsdb.response.datasize",
1627 			FT_UINT32, BASE_DEC, NULL, 0x0,
1628 			NULL, HFILL }
1629 		},
1630 		{ &hf_gdsdb_response_data,
1631 			{ "Data", "gdsdb.response.data",
1632 			FT_BYTES, BASE_NONE, NULL, 0x0,
1633 			NULL, HFILL }
1634 		},
1635 		/* gdsdb_status_vector */
1636 		{ &hf_gdsdb_status_vector_arg,
1637 			{ "Argument", "gdsdb.status_vector.arg",
1638 			FT_UINT32, BASE_DEC, VALS(gdsdb_arg_types), 0x0,
1639 			NULL, HFILL }
1640 		},
1641 		{ &hf_gdsdb_status_vector_error_code,
1642 			{ "Error code", "gdsdb.status_vector.error_code",
1643 			FT_UINT32, BASE_DEC, NULL, 0x0,
1644 			NULL, HFILL }
1645 		},
1646 		{ &hf_gdsdb_status_vector_number,
1647 			{ "Number", "gdsdb.status_vector.number",
1648 			FT_UINT32, BASE_DEC, NULL, 0x0,
1649 			NULL, HFILL }
1650 		},
1651 		{ &hf_gdsdb_status_vector_string,
1652 			{ "String", "gdsdb.status_vector.string",
1653 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1654 			NULL, HFILL }
1655 		},
1656 		{ &hf_gdsdb_status_vector_sql_state,
1657 			{ "SQL State", "gdsdb.status_vector.sql_state",
1658 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1659 			NULL, HFILL }
1660 		},
1661 		/* gdsdb_transact */
1662 		{ &hf_gdsdb_transact_database,
1663 			{ "Database", "gdsdb.transact.database",
1664 			FT_UINT32, BASE_DEC, NULL, 0x0,
1665 			NULL, HFILL }
1666 		},
1667 		{ &hf_gdsdb_transact_transaction,
1668 			{ "Database", "gdsdb.transact.transaction",
1669 			FT_UINT32, BASE_DEC, NULL, 0x0,
1670 			NULL, HFILL }
1671 		},
1672 #if 0
1673 		{ &hf_gdsdb_transact_messages,
1674 			{ "Messages", "gdsdb.transact.messages",
1675 			FT_UINT32, BASE_DEC, NULL, 0x0,
1676 			NULL, HFILL }
1677 		},
1678 #endif
1679 		/* gdsdb_transact_response */
1680 		{ &hf_gdsdb_transactresponse_messages,
1681 			{ "Messages", "gdsdb.transactresponse.messages",
1682 			FT_UINT32, BASE_DEC, NULL, 0x0,
1683 			NULL, HFILL }
1684 		},
1685 		/* gdsdb_open_blob2 */
1686 		{ &hf_gdsdb_openblob2_bpb,
1687 			{ "Blob parameter block", "gdsdb.openblob2.bpb",
1688 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1689 			NULL, HFILL }
1690 		},
1691 		/* gdsdb_open_blob */
1692 		{ &hf_gdsdb_openblob_transaction,
1693 			{ "Transaction", "gdsdb.openblob2.transaction",
1694 			FT_UINT32, BASE_DEC, NULL, 0x0,
1695 			NULL, HFILL }
1696 		},
1697 		{ &hf_gdsdb_openblob_id,
1698 			{ "ID", "gdsdb.openblob.id",
1699 			FT_UINT64, BASE_HEX, NULL, 0x0,
1700 			NULL, HFILL }
1701 		},
1702 #if 0
1703 		/* gdsdb_segment */
1704 		{ &hf_gdsdb_segment_blob,
1705 			{ "Blob", "gdsdb.segment.blob",
1706 			FT_UINT32, BASE_DEC, NULL, 0x0,
1707 			NULL, HFILL }
1708 		},
1709 		{ &hf_gdsdb_segment_length,
1710 			{ "Length", "gdsdb.segment.length",
1711 			FT_UINT32, BASE_DEC, NULL, 0x0,
1712 			NULL, HFILL }
1713 		},
1714 		{ &hf_gdsdb_segment_segment,
1715 			{ "Segment", "gdsdb.segment.segment",
1716 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1717 			NULL, HFILL }
1718 		},
1719 		/* gdsdb_seek_blob */
1720 		{ &hf_gdsdb_seekblob_blob,
1721 			{ "Blob", "gdsdb.seekblob.blob",
1722 			FT_UINT32, BASE_DEC, NULL, 0x0,
1723 			NULL, HFILL }
1724 		},
1725 		{ &hf_gdsdb_seekblob_mode,
1726 			{ "Mode", "gdsdb.seekblob.mode",
1727 			FT_UINT32, BASE_DEC, NULL, 0x0,
1728 			NULL, HFILL }
1729 		},
1730 #endif
1731 		/* gdsdb_reconnect */
1732 		{ &hf_gdsdb_reconnect_handle,
1733 			{ "Handle", "gdsdb.reconnect.handle",
1734 			FT_UINT32, BASE_DEC, NULL, 0x0,
1735 			NULL, HFILL }
1736 		},
1737 		{ &hf_gdsdb_reconnect_database_size,
1738 			{ "Database size", "gdsdb.reconnect.database_size",
1739 			FT_UINT32, BASE_DEC, NULL, 0x0,
1740 			NULL, HFILL }
1741 		},
1742 		{ &hf_gdsdb_reconnect_database,
1743 			{ "Database", "gdsdb.reconnect.database",
1744 			FT_BYTES, BASE_NONE, NULL, 0x0,
1745 			NULL, HFILL }
1746 		},
1747 		/* gdsdb_info & gdsdb_service_start */
1748 		{ &hf_gdsdb_info_object,
1749 			{ "Object", "gdsdb.info.object",
1750 			FT_UINT32, BASE_DEC, NULL, 0x0,
1751 			NULL, HFILL }
1752 		},
1753 		{ &hf_gdsdb_info_incarnation,
1754 			{ "Incarnation", "gdsdb.info.incarnation",
1755 			FT_UINT32, BASE_DEC, NULL, 0x0,
1756 			NULL, HFILL }
1757 		},
1758 		{ &hf_gdsdb_info_items,
1759 			{ "Items", "gdsdb.info.items",
1760 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1761 			NULL, HFILL }
1762 		},
1763 		{ &hf_gdsdb_info_recv_items,
1764 			{ "Items", "gdsdb.info.recv_items",
1765 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1766 			NULL, HFILL }
1767 		},
1768 		{ &hf_gdsdb_info_buffer_length,
1769 			{ "Buffer length", "gdsdb.info.bufferlength",
1770 			FT_UINT32, BASE_DEC, NULL, 0x0,
1771 			NULL, HFILL }
1772 		},
1773 		/* gdsdb_release */
1774 		{ &hf_gdsdb_release_object,
1775 			{ "Object", "gdsdb.release.object",
1776 			FT_UINT32, BASE_DEC, NULL, 0x0,
1777 			NULL, HFILL }
1778 		},
1779 #if 0
1780 		/* gdsdb_prepare2 */
1781 		{ &hf_gdsdb_prepare2_transaction,
1782 			{ "Transaction", "gdsdb.prepare2.transaction",
1783 			FT_UINT32, BASE_DEC, NULL, 0x0,
1784 			NULL, HFILL }
1785 		},
1786 		/* gdsdb_event & gdsdb_cancel_events */
1787 		{ &hf_gdsdb_event_database,
1788 			{ "Database", "gdsdb.event.database",
1789 			FT_UINT32, BASE_DEC, NULL, 0x0,
1790 			NULL, HFILL }
1791 		},
1792 		{ &hf_gdsdb_event_items,
1793 			{ "Event description block", "gdsdb.event.items",
1794 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1795 			NULL, HFILL }
1796 		},
1797 		{ &hf_gdsdb_event_ast,
1798 			{ "ast routine", "gdsdb.event.ast",
1799 			FT_UINT32, BASE_DEC, NULL, 0x0,
1800 			NULL, HFILL }
1801 		},
1802 		{ &hf_gdsdb_event_arg,
1803 			{ "Argument to ast routine", "gdsdb.event.arg",
1804 			FT_UINT32, BASE_DEC, NULL, 0x0,
1805 			NULL, HFILL }
1806 		},
1807 		{ &hf_gdsdb_event_rid,
1808 			{ "ID", "gdsdb.event.id",
1809 			FT_UINT32, BASE_DEC, NULL, 0x0,
1810 			NULL, HFILL }
1811 		},
1812 		/* gdsdb_ddl */
1813 		{ &hf_gdsdb_ddl_database,
1814 			{ "Database", "gdsdb.ddl.database",
1815 			FT_UINT32, BASE_DEC, NULL, 0x0,
1816 			NULL, HFILL }
1817 		},
1818 		{ &hf_gdsdb_ddl_transaction,
1819 			{ "Transaction", "gdsdb.ddl.transaction",
1820 			FT_UINT32, BASE_DEC, NULL, 0x0,
1821 			NULL, HFILL }
1822 		},
1823 		{ &hf_gdsdb_ddl_blr,
1824 			{ "BLR", "gdsdb.ddl.blr",
1825 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1826 			NULL, HFILL }
1827 		},
1828 		/* gdsdb_slice */
1829 		{ &hf_gdsdb_slice_transaction,
1830 			{ "Transaction", "gdsdb.slice.transaction",
1831 			FT_UINT32, BASE_DEC, NULL, 0x0,
1832 			NULL, HFILL }
1833 		},
1834 		{ &hf_gdsdb_slice_id,
1835 			{ "ID", "gdsdb.slice.id",
1836 			FT_UINT64, BASE_HEX, NULL, 0x0,
1837 			NULL, HFILL }
1838 		},
1839 		{ &hf_gdsdb_slice_sdl,
1840 			{ "Slice description language", "gdsdb.slice.sdl",
1841 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1842 			NULL, HFILL }
1843 		},
1844 		{ &hf_gdsdb_slice_parameters,
1845 			{ "Parameters", "gdsdb.slice.parameters",
1846 			FT_UINT32, BASE_DEC, NULL, 0x0,
1847 			NULL, HFILL }
1848 		},
1849 		/* gdsdb_slice_response */
1850 		{ &hf_gdsdb_sliceresponse_length,
1851 			{ "Length", "gdsdb.sliceresponse.length",
1852 			FT_UINT32, BASE_DEC, NULL, 0x0,
1853 			NULL, HFILL }
1854 		},
1855 #endif
1856 		/* gdsdb_execute */
1857 		{ &hf_gdsdb_execute_statement,
1858 			{ "Statement", "gdsdb.execute.statement",
1859 			FT_UINT32, BASE_DEC, NULL, 0x0,
1860 			NULL, HFILL }
1861 		},
1862 		{ &hf_gdsdb_execute_transaction,
1863 			{ "Transaction", "gdsdb.execute.transaction",
1864 			FT_UINT32, BASE_DEC, NULL, 0x0,
1865 			NULL, HFILL }
1866 		},
1867 		{ &hf_gdsdb_execute_message_number,
1868 			{ "Message number", "gdsdb.execute.messagenumber",
1869 			FT_UINT32, BASE_DEC, NULL, 0x0,
1870 			NULL, HFILL }
1871 		},
1872 		{ &hf_gdsdb_execute_messages,
1873 			{ "Number of messages", "gdsdb.execute.messages",
1874 			FT_UINT32, BASE_DEC, NULL, 0x0,
1875 			NULL, HFILL }
1876 		},
1877 #if 0
1878 		/* gdsdb_execute2 */
1879 		{ &hf_gdsdb_execute_outblr,
1880 			{ "Output BLR", "gdsdb.execute.outblr",
1881 			FT_UINT32, BASE_DEC, NULL, 0x0,
1882 			NULL, HFILL }
1883 		},
1884 		{ &hf_gdsdb_execute_outmsgnr,
1885 			{ "Output Message number", "gdsdb.execute.outmsgnr",
1886 			FT_UINT32, BASE_DEC, NULL, 0x0,
1887 			NULL, HFILL }
1888 		},
1889 		/* gdsdb_exec_immediate2 */
1890 		{ &hf_gdsdb_prepare2_blr,
1891 			{ "BLR", "gdsdb.prepare.blr",
1892 			FT_UINT32, BASE_DEC, NULL, 0x0,
1893 			NULL, HFILL }
1894 		},
1895 		{ &hf_gdsdb_prepare2_number,
1896 			{ "Message number", "gdsdb.prepare2.messagenumber",
1897 			FT_UINT32, BASE_DEC, NULL, 0x0,
1898 			NULL, HFILL }
1899 		},
1900 		{ &hf_gdsdb_prepare2_messages,
1901 			{ "Number of messages", "gdsdb.prepare2.messages",
1902 			FT_UINT32, BASE_DEC, NULL, 0x0,
1903 			NULL, HFILL }
1904 		},
1905 		{ &hf_gdsdb_prepare2_outblr,
1906 			{ "Output BLR", "gdsdb.prepare2.outblr",
1907 			FT_UINT32, BASE_DEC, NULL, 0x0,
1908 			NULL, HFILL }
1909 		},
1910 		{ &hf_gdsdb_prepare2_outmsgnr,
1911 			{ "Output Message number", "gdsdb.prepare2.outmsgnr",
1912 			FT_UINT32, BASE_DEC, NULL, 0x0,
1913 			NULL, HFILL }
1914 		},
1915 #endif
1916 		/* gdsdb_prepare */
1917 		{ &hf_gdsdb_prepare_transaction,
1918 			{ "Prepare, Transaction", "gdsdb.prepare.transaction",
1919 			FT_UINT32, BASE_DEC, NULL, 0x0,
1920 			NULL, HFILL }
1921 		},
1922 		{ &hf_gdsdb_prepare_statement,
1923 			{ "Prepare, Statement", "gdsdb.prepare.statement",
1924 			FT_UINT32, BASE_DEC, NULL, 0x0,
1925 			NULL, HFILL }
1926 		},
1927 		{ &hf_gdsdb_prepare_dialect,
1928 			{ "Prepare, Dialect", "gdsdb.prepare.dialect",
1929 			FT_UINT32, BASE_DEC, NULL, 0x0,
1930 			NULL, HFILL }
1931 		},
1932 		{ &hf_gdsdb_prepare_querystr,
1933 			{ "Prepare, Query", "gdsdb.prepare.querystr",
1934 			FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1935 			NULL, HFILL }
1936 		},
1937 		{ &hf_gdsdb_prepare_bufferlength,
1938 			{ "Prepare, Bufferlength", "gdsdb.prepare.bufferlen",
1939 			FT_UINT32, BASE_DEC, NULL, 0x0,
1940 			NULL, HFILL }
1941 		},
1942 #if 0
1943 		/* gdsdb_fetch */
1944 		{ &hf_gdsdb_fetch_statement,
1945 			{ "Statement", "gdsdb.fetch.statement",
1946 			FT_UINT32, BASE_DEC, NULL, 0x0,
1947 			NULL, HFILL }
1948 		},
1949 		{ &hf_gdsdb_fetch_message_number,
1950 			{ "Message number", "gdsdb.fetch.messagenr",
1951 			FT_UINT32, BASE_DEC, NULL, 0x0,
1952 			NULL, HFILL }
1953 		},
1954 		{ &hf_gdsdb_fetch_messages,
1955 			{ "Number of messages", "gdsdb.fetch.messages",
1956 			FT_UINT32, BASE_DEC, NULL, 0x0,
1957 			NULL, HFILL }
1958 		},
1959 		/* gdsdb_fetch_response */
1960 		{ &hf_gdsdb_fetchresponse_status,
1961 			{ "Status", "gdsdb.fetchresponse.status",
1962 			FT_UINT32, BASE_DEC, NULL, 0x0,
1963 			NULL, HFILL }
1964 		},
1965 		{ &hf_gdsdb_fetchresponse_messages,
1966 			{ "Number of messages", "gdsdb.fetchresponse.messages",
1967 			FT_UINT32, BASE_DEC, NULL, 0x0,
1968 			NULL, HFILL }
1969 		},
1970 #endif
1971 		/* gdsdb_free_statement */
1972 		{ &hf_gdsdb_free_statement,
1973 			{ "Statement", "gdsdb.fetchresponse.statement",
1974 			FT_UINT32, BASE_DEC, NULL, 0x0,
1975 			NULL, HFILL }
1976 		},
1977 		{ &hf_gdsdb_free_option,
1978 			{ "Option", "gdsdb.fetchresponse.option",
1979 			FT_UINT32, BASE_DEC, NULL, 0x0,
1980 			NULL, HFILL }
1981 		},
1982 #if 0
1983 		/* gdsdb_insert */
1984 		{ &hf_gdsdb_insert_statement,
1985 			{ "Statement", "gdsdb.insert.statement",
1986 			FT_UINT32, BASE_DEC, NULL, 0x0,
1987 			NULL, HFILL }
1988 		},
1989 		{ &hf_gdsdb_insert_message_number,
1990 			{ "Message number", "gdsdb.insert.messagenr",
1991 			FT_UINT32, BASE_DEC, NULL, 0x0,
1992 			NULL, HFILL }
1993 		},
1994 		{ &hf_gdsdb_insert_messages,
1995 			{ "Number of messages", "gdsdb.insert.messages",
1996 			FT_UINT32, BASE_DEC, NULL, 0x0,
1997 			NULL, HFILL }
1998 		},
1999 		/* gdsdb_cursor */
2000 		{ &hf_gdsdb_cursor_statement,
2001 			{ "Statement", "gdsdb.cursor.statement",
2002 			FT_UINT32, BASE_DEC, NULL, 0x0,
2003 			NULL, HFILL }
2004 		},
2005 		{ &hf_gdsdb_cursor_type,
2006 			{ "Type", "gdsdb.cursor.type",
2007 			FT_UINT32, BASE_DEC, NULL, 0x0,
2008 			NULL, HFILL }
2009 		},
2010 		/* gdsdb_sql_response */
2011 		{ &hf_gdsdb_sqlresponse_messages,
2012 			{ "SQL Response, Message Count", "gdsdb.sqlresponse.msgcount",
2013 			FT_UINT32, BASE_DEC, NULL, 0x0,
2014 			NULL, HFILL }
2015 		}
2016 #endif
2017 	};
2018 
2019 	static gint *ett[] = {
2020 		&ett_gdsdb,
2021 		/* &ett_gdsdb_opcode, */
2022 		&ett_gdsdb_connect_pref
2023 	};
2024 
2025 	proto_gdsdb = proto_register_protocol(
2026 		"Firebird SQL Database Remote Protocol",
2027 		"FB/IB GDS DB", "gdsdb");
2028 
2029 	proto_register_field_array(proto_gdsdb, hf, array_length(hf));
2030 	proto_register_subtree_array(ett, array_length(ett));
2031 }
2032 
2033 void
proto_reg_handoff_gdsdb(void)2034 proto_reg_handoff_gdsdb(void)
2035 {
2036 	/* Main dissector */
2037 
2038 	dissector_handle_t gdsdb_handle;
2039 
2040 	gdsdb_handle = create_dissector_handle(dissect_gdsdb,
2041 								 proto_gdsdb);
2042 	dissector_add_uint_with_preference("tcp.port", TCP_PORT, gdsdb_handle);
2043 }
2044 
2045 /*
2046  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2047  *
2048  * Local variables:
2049  * c-basic-offset: 8
2050  * tab-width: 8
2051  * indent-tabs-mode: t
2052  * End:
2053  *
2054  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2055  * :indentSize=8:tabSize=8:noTabs=false:
2056  */
2057