Bug Summary

File:builds/wireshark/wireshark/epan/dissectors/packet-tns.c
Warning:line 1334, column 3
Value stored to 'len' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name packet-tns.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan/dissectors -isystem /builds/wireshark/wireshark/build/epan/dissectors -isystem /usr/include/mit-krb5 -isystem /usr/include/libxml2 -isystem /builds/wireshark/wireshark/epan -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-10-04-101257-3662-1 -x c /builds/wireshark/wireshark/epan/dissectors/packet-tns.c
1/* packet-tns.c
2 * Routines for Oracle TNS packet dissection
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * Copied from packet-tftp.c
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13#include "config.h"
14
15#include <epan/packet.h>
16#include "packet-tcp.h"
17
18#include <epan/prefs.h>
19#include <epan/expert.h>
20#include <epan/conversation.h>
21#include <epan/proto_data.h>
22#include <epan/unit_strings.h>
23
24#include <wsutil/array.h>
25
26void proto_register_tns(void);
27
28#define TNS_HDR_LEN8 8
29
30/* Packet Types */
31#define TNS_TYPE_CONNECT1 1
32#define TNS_TYPE_ACCEPT2 2
33#define TNS_TYPE_ACK3 3
34#define TNS_TYPE_REFUSE4 4
35#define TNS_TYPE_REDIRECT5 5
36#define TNS_TYPE_DATA6 6
37#define TNS_TYPE_NULL7 7
38#define TNS_TYPE_ABORT9 9
39#define TNS_TYPE_RESEND11 11
40#define TNS_TYPE_MARKER12 12
41#define TNS_TYPE_ATTENTION13 13
42#define TNS_TYPE_CONTROL14 14
43#define TNS_TYPE_DD15 15
44#define TNS_TYPE_MAX19 19
45
46/*
47 * Oracle datatype codes as they appear on the wire and in tns_data_types[].
48 * python-oracledb lists most of these as its ORA_TYPE_NUM_* constants.
49 */
50#define TNS_DATATYPE_VARCHAR1 1
51#define TNS_DATATYPE_NUMBER2 2
52#define TNS_DATATYPE_INTEGER3 3 /* BINARY_INTEGER */
53#define TNS_DATATYPE_FLOAT4 4
54#define TNS_DATATYPE_STRING5 5
55#define TNS_DATATYPE_VARNUM6 6
56#define TNS_DATATYPE_DECIMAL7 7
57#define TNS_DATATYPE_LONG8 8
58#define TNS_DATATYPE_VCS9 9
59#define TNS_DATATYPE_ROWID11 11 /* RID */
60#define TNS_DATATYPE_DATE12 12
61#define TNS_DATATYPE_VBI15 15
62#define TNS_DATATYPE_RAW23 23
63#define TNS_DATATYPE_LONG_RAW24 24
64#define TNS_DATATYPE_CHAR96 96
65#define TNS_DATATYPE_BINARY_FLOAT100 100
66#define TNS_DATATYPE_BINARY_DOUBLE101 101
67#define TNS_DATATYPE_REFCURSOR102 102
68#define TNS_DATATYPE_ROWID_EXT104 104 /* ROWID */
69#define TNS_DATATYPE_ADT109 109 /* object */
70#define TNS_DATATYPE_REF111 111
71#define TNS_DATATYPE_CLOB112 112
72#define TNS_DATATYPE_BLOB113 113
73#define TNS_DATATYPE_BFILE114 114
74#define TNS_DATATYPE_RSET116 116
75#define TNS_DATATYPE_JSON119 119 /* OSON */
76#define TNS_DATATYPE_VECTOR127 127
77#define TNS_DATATYPE_TIMESTAMP180 180
78#define TNS_DATATYPE_TIMESTAMP_TZ181 181
79#define TNS_DATATYPE_INTERVAL_YM182 182
80#define TNS_DATATYPE_INTERVAL_DS183 183
81#define TNS_DATATYPE_UROWID208 208
82#define TNS_DATATYPE_TIMESTAMP_LTZ231 231
83#define TNS_DATATYPE_BOOLEAN252 252
84
85/* DALC length byte marking a slot with no value (see get_dalc_custom). */
86#define TNS_DALC_ABSENT0xFD 0xFD
87
88/* TTC field versions (compile capability 7), as python-oracledb's
89 * TNS_CCAP_FIELD_VERSION_* name them. The wire shape of several messages
90 * depends on the one a connection negotiates. */
91#define TNS_CCAP_FIELD_VERSION7 7
92#define TNS_FV_11_26 6
93#define TNS_FV_12_17 7
94#define TNS_FV_12_28 8
95#define TNS_FV_12_2_EXT19 9
96#define TNS_FV_18_110 10
97#define TNS_FV_18_1_EXT_111 11
98#define TNS_FV_19_112 12
99#define TNS_FV_19_1_EXT_113 13
100#define TNS_FV_20_114 14
101#define TNS_FV_20_1_EXT_115 15
102#define TNS_FV_21_116 16
103#define TNS_FV_23_117 17
104#define TNS_FV_23_1_EXT_118 18
105#define TNS_FV_23_1_EXT_219 19
106#define TNS_FV_23_1_EXT_320 20
107#define TNS_FV_23_1_EXT_421 21
108#define TNS_FV_23_1_EXT_522 22
109#define TNS_FV_23_3_EXT_623 23
110#define TNS_FV_23_424 24
111
112/* Data Packet Functions */
113#define SQLNET_SET_PROTOCOL1 1
114#define SQLNET_SET_DATATYPES2 2
115#define SQLNET_USER_OCI_FUNC3 3
116#define SQLNET_RETURN_STATUS4 4
117#define SQLNET_ACCESS_USR_ADDR5 5
118#define SQLNET_ROW_TRANSF_HDR6 6
119#define SQLNET_ROW_TRANSF_DATA7 7
120#define SQLNET_RETURN_OPI_PARAM8 8
121#define SQLNET_FUNCCOMPLETE9 9
122#define SQLNET_NERROR_RET_DEF10 10
123#define SQLNET_IOVEC_4FAST_UPI11 11
124#define SQLNET_LONG_4FAST_UPI12 12
125#define SQLNET_INVOKE_USER_CB13 13
126#define SQLNET_LOB_FILE_DF14 14
127#define SQLNET_WARNING15 15
128#define SQLNET_DESCRIBE_INFO16 16
129#define SQLNET_PIGGYBACK_FUNC17 17
130#define SQLNET_SIG_4UCS18 18
131#define SQLNET_FLUSH_BIND_DATA19 19
132#define SQLNET_BIT_VECTOR21 21
133#define SQLNET_SERVER_PIGGYBACK23 23
134#define SQLNET_IMPLICIT_RESULTS27 27
135#define SQLNET_END_OF_RESPONSE29 29
136#define SQLNET_TOKEN33 33
137#define SQLNET_SNS0xdeadbeef 0xdeadbeef
138#define SQLNET_XTRN_PROCSERV_R132 32
139#define SQLNET_XTRN_PROCSERV_R268 68
140
141/* Return OPI Parameter's Type */
142#define OPI_VERSION21 1
143#define OPI_OSESSKEY2 2
144#define OPI_OAUTH3 3
145
146/* An OCI client's execute preamble: offsets from the TTI_FUN byte, and
147 * the 8-byte pointer indicator its fixed slots sit between. */
148#define TNS_OCI_INDICATOR0xfeffffffffffffffUL UINT64_C(0xfeffffffffffffff)0xfeffffffffffffffUL
149#define TNS_OCI_ALL8_CURSOR7 7
150#define TNS_OCI_ALL8_IND11 11
151#define TNS_OCI_ALL8_SQLLEN319 19
152#define TNS_OCI_ALL8_IND2_NARROW23 23
153#define TNS_OCI_ALL8_IND2_WIDE27 27
154
155/* OCI function ids (TTI_FUN sub-functions). */
156#define TTI_REEXECUTE4 4
157#define TTI_FETCH5 5
158#define TTI_REEXECUTE_AND_FETCH78 78
159#define TTI_ALL894 94
160#define TTI_LOBOPS96 96
161#define TTI_TPC_TXN_SWITCH103 103
162#define TTI_TPC_TXN_CHANGE_STATE104 104
163#define TTI_CLOSE_CURSORS105 105
164#define TTI_SET_END_TO_END_ATTR135 135
165#define TTI_SET_SCHEMA152 152
166#define TTI_SESSION_RELEASE163 163
167#define TTI_SESSION_STATE176 176
168#define TTI_PIPELINE_BEGIN199 199
169#define TTI_PIPELINE_END200 200
170#define TTI_END_USER_SEC_CTX205 205
171
172/* desegmentation of TNS over TCP */
173static bool_Bool tns_desegment = true1;
174
175static dissector_handle_t tns_handle;
176
177static int proto_tns;
178static int hf_tns_request;
179static int hf_tns_response;
180static int hf_tns_length;
181static int hf_tns_packet_checksum;
182static int hf_tns_header_checksum;
183static int hf_tns_packet_type;
184static int hf_tns_reserved_byte;
185static int hf_tns_version;
186static int hf_tns_compat_version;
187
188static int hf_tns_service_options;
189static int hf_tns_sopt_flag_bconn;
190static int hf_tns_sopt_flag_pc;
191static int hf_tns_sopt_flag_hc;
192static int hf_tns_sopt_flag_fd;
193static int hf_tns_sopt_flag_hd;
194static int hf_tns_sopt_flag_dc1;
195static int hf_tns_sopt_flag_dc2;
196static int hf_tns_sopt_flag_dio;
197static int hf_tns_sopt_flag_ap;
198static int hf_tns_sopt_flag_ra;
199static int hf_tns_sopt_flag_sa;
200
201static int hf_tns_sdu_size;
202static int hf_tns_max_tdu_size;
203
204static int hf_tns_nt_proto_characteristics;
205static int hf_tns_ntp_flag_hangon;
206static int hf_tns_ntp_flag_crel;
207static int hf_tns_ntp_flag_tduio;
208static int hf_tns_ntp_flag_srun;
209static int hf_tns_ntp_flag_dtest;
210static int hf_tns_ntp_flag_cbio;
211static int hf_tns_ntp_flag_asio;
212static int hf_tns_ntp_flag_pio;
213static int hf_tns_ntp_flag_grant;
214static int hf_tns_ntp_flag_handoff;
215static int hf_tns_ntp_flag_sigio;
216static int hf_tns_ntp_flag_sigpipe;
217static int hf_tns_ntp_flag_sigurg;
218static int hf_tns_ntp_flag_urgentio;
219static int hf_tns_ntp_flag_fdio;
220static int hf_tns_ntp_flag_testop;
221
222static int hf_tns_line_turnaround;
223static int hf_tns_value_of_one;
224static int hf_tns_connect_data_length;
225static int hf_tns_connect_data_offset;
226static int hf_tns_connect_data_max;
227
228static int hf_tns_connect_flags0;
229static int hf_tns_connect_flags1;
230static int hf_tns_conn_flag_nareq;
231static int hf_tns_conn_flag_nalink;
232static int hf_tns_conn_flag_enablena;
233static int hf_tns_conn_flag_ichg;
234static int hf_tns_conn_flag_wantna;
235
236static int hf_tns_connect_data;
237static int hf_tns_trace_cf1;
238static int hf_tns_trace_cf2;
239static int hf_tns_trace_cid;
240
241static int hf_tns_accept_data_length;
242static int hf_tns_accept_data_offset;
243static int hf_tns_accept_sdu;
244static int hf_tns_accept_flags2;
245static int hf_tns_accept_flags2_check_oob;
246static int hf_tns_accept_flags2_end_of_response;
247static int hf_tns_accept_flags2_fast_auth;
248static int hf_tns_accept_data;
249
250static int hf_tns_refuse_reason_user;
251static int hf_tns_refuse_reason_system;
252static int hf_tns_refuse_data_length;
253static int hf_tns_refuse_data;
254
255static int hf_tns_abort_reason_user;
256static int hf_tns_abort_reason_system;
257static int hf_tns_abort_data;
258
259static int hf_tns_marker_type;
260static int hf_tns_marker_data_byte;
261static int hf_tns_marker_function;
262/* static int hf_tns_marker_data; */
263
264static int hf_tns_redirect_data_length;
265static int hf_tns_redirect_data;
266
267static int hf_tns_control_cmd;
268static int hf_tns_control_data;
269
270static int hf_tns_data_flag;
271static int hf_tns_data_flag_send;
272static int hf_tns_data_flag_rc;
273static int hf_tns_data_flag_c;
274static int hf_tns_data_flag_reserved;
275static int hf_tns_data_flag_more;
276static int hf_tns_data_flag_eof;
277static int hf_tns_data_flag_dic;
278static int hf_tns_data_flag_rts;
279static int hf_tns_data_flag_sntt;
280static int hf_tns_data_flag_end_of_request;
281static int hf_tns_data_flag_begin_pipeline;
282static int hf_tns_data_flag_end_of_response;
283
284static int hf_tns_data_id;
285static int hf_tns_data_length;
286static int hf_tns_data_oci_id;
287static int hf_tns_data_tseq;
288static int hf_tns_data_token;
289static int hf_tns_data_piggyback_id;
290static int hf_tns_data_unused;
291
292static int hf_tns_cursor;
293
294static int hf_tns_data_opi_version2_banner_len;
295static int hf_tns_data_opi_version2_banner;
296static int hf_tns_data_opi_version2_vsnum;
297
298static int hf_tns_data_opi_num_of_params;
299static int hf_tns_data_opi_param_length;
300static int hf_tns_data_opi_param_name;
301static int hf_tns_data_opi_param_value;
302static int hf_tns_data_auth_mode;
303static int hf_tns_data_auth_mode_logon;
304static int hf_tns_data_auth_mode_change_password;
305static int hf_tns_data_auth_mode_sysdba;
306static int hf_tns_data_auth_mode_sysoper;
307static int hf_tns_data_auth_mode_with_password;
308static int hf_tns_data_auth_user;
309
310static int hf_tns_data_setp_acc_version;
311static int hf_tns_data_setp_cli_plat;
312static int hf_tns_data_setp_version;
313static int hf_tns_data_setp_banner;
314static int hf_tns_data_setp_charset;
315static int hf_tns_data_setp_flags;
316static int hf_tns_data_setp_ncharset;
317static int hf_tns_data_setp_compile_caps;
318static int hf_tns_data_setp_runtime_caps;
319static int hf_tns_data_setp_field_version;
320
321static int hf_tns_data_sns_cli_vers;
322static int hf_tns_data_sns_srv_vers;
323static int hf_tns_data_sns_srvcnt;
324static int hf_tns_data_sns_error;
325static int hf_tns_data_sns_service;
326static int hf_tns_data_sns_subpackets;
327static int hf_tns_data_sns_svc_error;
328static int hf_tns_data_sns_sub_type;
329static int hf_tns_data_sns_sub_data;
330static int hf_tns_data_sns_version;
331static int hf_tns_data_sns_encryption;
332static int hf_tns_data_sns_integrity;
333
334static int hf_tns_data_setdt_charset_in;
335static int hf_tns_data_setdt_charset_out;
336static int hf_tns_data_setdt_flag;
337static int hf_tns_data_setdt_caphdr;
338static int hf_tns_data_setdt_caphdr_version;
339static int hf_tns_data_setdt_caphdr_flags;
340static int hf_tns_data_setdt_field_version;
341static int hf_tns_data_field_version;
342static int hf_tns_data_setdt_tblhdr;
343static int hf_tns_data_setdt_idmap;
344static int hf_tns_data_setdt_overrides;
345static int hf_tns_data_setdt_override_client;
346static int hf_tns_data_setdt_override_repr;
347static int hf_tns_data_setdt_override_format;
348
349static int hf_tns_data_oer_call_status;
350static int hf_tns_data_oer_rowcount;
351static int hf_tns_data_oer_err_code;
352static int hf_tns_data_oer_cursor_id;
353static int hf_tns_data_oer_n_batch_errcodes;
354static int hf_tns_data_oer_n_batch_offsets;
355static int hf_tns_data_oer_n_batch_messages;
356static int hf_tns_data_oer_message;
357static int hf_tns_data_oer_err_num_ext;
358static int hf_tns_data_oer_rowcount_ext;
359static int hf_tns_data_oer_sql_type;
360static int hf_tns_data_oer_checksum;
361
362static int hf_tns_data_rpa_num_al8o4;
363static int hf_tns_data_rpa_al8o4;
364static int hf_tns_data_rpa_al8txl;
365static int hf_tns_data_rpa_num_kv;
366static int hf_tns_data_rpa_registration;
367static int hf_tns_data_rpa_num_rowcounts;
368static int hf_tns_data_rpa_dml_rowcount;
369static int hf_tns_data_spb_opcode;
370static int hf_tns_data_spb_ltxid;
371static int hf_tns_data_spb_os_pid;
372static int hf_tns_data_spb_num_kv;
373static int hf_tns_data_spb_flags;
374static int hf_tns_data_spb_session_id;
375static int hf_tns_data_spb_serial_num;
376static int hf_tns_data_kv_text;
377static int hf_tns_data_kv_binary;
378static int hf_tns_data_kv_keyword;
379
380static int hf_tns_data_wrn_code;
381static int hf_tns_data_wrn_length;
382static int hf_tns_data_wrn_flags;
383static int hf_tns_data_wrn_message;
384
385static int hf_tns_data_oci_oer_status;
386static int hf_tns_data_oci_oer_seq;
387static int hf_tns_data_oci_oer_category;
388static int hf_tns_data_oci_oer_error_pos;
389static int hf_tns_data_oci_oer_command;
390static int hf_tns_data_oci_oer_call_seq;
391
392static int hf_tns_data_sta_call_status;
393static int hf_tns_data_sta_seq;
394static int hf_tns_data_call_status_txn;
395static int hf_tns_data_call_status_sess_release;
396
397static int hf_tns_data_iov_num_binds;
398static int hf_tns_data_iov_bind_dir;
399static int hf_tns_data_bind_retcode;
400
401static int hf_tns_data_dcb_num_columns;
402static int hf_tns_data_col_type;
403static int hf_tns_data_col_precision;
404static int hf_tns_data_col_scale;
405static int hf_tns_data_col_max_length;
406static int hf_tns_data_col_charset;
407static int hf_tns_data_col_csform;
408static int hf_tns_data_col_max_size;
409static int hf_tns_data_col_nulls_ok;
410static int hf_tns_data_col_name;
411static int hf_tns_data_col_uds_flags;
412static int hf_tns_data_col_domain_schema;
413static int hf_tns_data_col_domain_name;
414static int hf_tns_data_col_annotation;
415static int hf_tns_data_col_vector_dims;
416static int hf_tns_data_col_vector_format;
417
418static int hf_tns_data_rxh_num_requests;
419static int hf_tns_data_rxh_iter_num;
420static int hf_tns_data_rxh_num_iters;
421static int hf_tns_data_bit_vector;
422static int hf_tns_data_bvc_num_cols_sent;
423static int hf_tns_data_irs_num_results;
424
425static int hf_tns_data_all8_options;
426static int hf_tns_data_all8_opt_parse;
427static int hf_tns_data_all8_opt_bind;
428static int hf_tns_data_all8_opt_define;
429static int hf_tns_data_all8_opt_execute;
430static int hf_tns_data_all8_opt_commit;
431static int hf_tns_data_all8_opt_plsql;
432static int hf_tns_data_all8_opt_fetch;
433static int hf_tns_data_all8_opt_not_plsql;
434static int hf_tns_data_all8_opt_describe;
435static int hf_tns_data_all8_opt_batch_errors;
436static int hf_tns_data_all8_iterations;
437static int hf_tns_data_all8_prefetch;
438static int hf_tns_data_all8_is_query;
439static int hf_tns_data_all8_exec_flags;
440static int hf_tns_data_all8_xflag_scrollable;
441static int hf_tns_data_all8_xflag_no_cancel_on_eof;
442static int hf_tns_data_all8_xflag_dml_rowcounts;
443static int hf_tns_data_all8_xflag_implicit_rs;
444static int hf_tns_data_all8_fetch_orientation;
445static int hf_tns_data_all8_fetch_pos;
446static int hf_tns_data_all8_fetch_rows;
447static int hf_tns_data_all8_bind_count;
448static int hf_tns_data_all8_define_count;
449static int hf_tns_data_all8_oci_preamble;
450static int hf_tns_data_all8_sql;
451static int hf_tns_data_bind_value;
452static int hf_tns_data_fetch_rows;
453static int hf_tns_data_reexec_iterations;
454static int hf_tns_data_reexec_options2;
455static int hf_tns_data_reexec_opt2_commit;
456static int hf_tns_data_lob_op;
457static int hf_tns_data_lob_offset;
458static int hf_tns_data_lob_locator;
459static int hf_tns_data_lob_charset;
460static int hf_tns_data_lob_data;
461static int hf_tns_data_lob_amount;
462static int hf_tns_data_lob_flag;
463static int hf_tns_data_tpc_switch_op;
464static int hf_tns_data_release_tag;
465static int hf_tns_data_release_mode;
466static int hf_tns_data_release_mode_deauth;
467static int hf_tns_data_tpc_change_op;
468static int hf_tns_data_tpc_format_id;
469static int hf_tns_data_tpc_gtrid;
470static int hf_tns_data_tpc_bqual;
471static int hf_tns_data_tpc_flags;
472static int hf_tns_data_tpc_timeout;
473static int hf_tns_data_tpc_state;
474static int hf_tns_data_tpc_context;
475static int hf_tns_data_tpc_app_value;
476static int hf_tns_data_tpc_internal_name;
477static int hf_tns_data_tpc_external_name;
478static int hf_tns_data_lob_total_size;
479static int hf_tns_data_pgy_schema;
480static int hf_tns_data_pgy_session_state;
481static int hf_tns_data_pgy_e2e_flags;
482static int hf_tns_data_pgy_client_id;
483static int hf_tns_data_pgy_module;
484static int hf_tns_data_pgy_action;
485static int hf_tns_data_pgy_client_info;
486static int hf_tns_data_pgy_dbop;
487static int hf_tns_data_pgy_error_set_id;
488static int hf_tns_data_pgy_error_set_mode;
489static int hf_tns_data_pgy_pipeline_mode;
490static int hf_tns_data_pgy_sec_flags;
491static int hf_tns_data_pgy_sec_key;
492static int hf_tns_data_pgy_sec_value;
493static int hf_tns_data_col_value;
494static int hf_tns_data_lob_size;
495static int hf_tns_data_lob_chunk_size;
496static int hf_tns_data_json_image;
497static int hf_tns_data_vector_image;
498static int hf_tns_data_obj_toid;
499static int hf_tns_data_obj_image;
500
501static int hf_tns_data_descriptor_row_count;
502static int hf_tns_data_descriptor_row_size;
503
504static int ett_tns;
505static int ett_tns_connect;
506static int ett_tns_accept;
507static int ett_tns_refuse;
508static int ett_tns_abort;
509static int ett_tns_redirect;
510static int ett_tns_marker;
511static int ett_tns_attention;
512static int ett_tns_control;
513static int ett_tns_data;
514static int ett_tns_data_flag;
515static int ett_tns_acc_versions;
516static int ett_tns_opi_params;
517static int ett_tns_opi_par;
518static int ett_tns_sopt_flag;
519static int ett_tns_ntp_flag;
520static int ett_tns_conn_flag;
521static int ett_tns_accept_flags2;
522static int ett_tns_rows;
523static int ett_tns_setdt_caphdr;
524static int ett_tns_setdt_overrides;
525static int ett_tns_setdt_override;
526static int ett_tns_oer;
527static int ett_tns_call_status;
528static int ett_tns_auth_mode;
529static int ett_tns_sns_service;
530static int ett_tns_sns_subpacket;
531static int ett_tns_release_mode;
532static int ett_tns_rpa;
533static int ett_tns_kv;
534static int ett_tns_iov;
535static int ett_tns_dcb_col;
536static int ett_tns_all8_options;
537static int ett_tns_all8_i4;
538static int ett_tns_all8_exec_flags;
539static int ett_tns_binds;
540static int ett_tns_bind;
541static int ett_tns_defines;
542static int ett_tns_reexec_options2;
543static int ett_tns_bind_row;
544static int ett_tns_rxd_row;
545static int ett_tns_value;
546static int ett_tns_irs;
547static int ett_tns_out_binds;
548static int ett_sql;
549
550static expert_field ei_tns_connect_data_next_packet;
551static expert_field ei_tns_data_descriptor_size_mismatch;
552static expert_field ei_tns_data_piggyback_cursors;
553static expert_field ei_tns_data_count_too_large;
554static expert_field ei_tns_data_encrypted;
555
556#define TCP_PORT_TNS1521 1521 /* Not IANA registered */
557
558/* The ACCEPT's flags2 word, what the server offers from version 318. */
559static int * const tns_accept_flags2[] = {
560 &hf_tns_accept_flags2_check_oob,
561 &hf_tns_accept_flags2_end_of_response,
562 &hf_tns_accept_flags2_fast_auth,
563 NULL((void*)0)
564};
565
566static int * const tns_connect_flags[] = {
567 &hf_tns_conn_flag_nareq,
568 &hf_tns_conn_flag_nalink,
569 &hf_tns_conn_flag_enablena,
570 &hf_tns_conn_flag_ichg,
571 &hf_tns_conn_flag_wantna,
572 NULL((void*)0)
573};
574
575static int * const tns_service_options[] = {
576 &hf_tns_sopt_flag_bconn,
577 &hf_tns_sopt_flag_pc,
578 &hf_tns_sopt_flag_hc,
579 &hf_tns_sopt_flag_fd,
580 &hf_tns_sopt_flag_hd,
581 &hf_tns_sopt_flag_dc1,
582 &hf_tns_sopt_flag_dc2,
583 &hf_tns_sopt_flag_dio,
584 &hf_tns_sopt_flag_ap,
585 &hf_tns_sopt_flag_ra,
586 &hf_tns_sopt_flag_sa,
587 NULL((void*)0)
588};
589
590/* TTI_ALL8 (SQL execute) options bitmask. */
591static int * const tns_all8_options[] = {
592 &hf_tns_data_all8_opt_parse,
593 &hf_tns_data_all8_opt_bind,
594 &hf_tns_data_all8_opt_define,
595 &hf_tns_data_all8_opt_execute,
596 &hf_tns_data_all8_opt_fetch,
597 &hf_tns_data_all8_opt_commit,
598 &hf_tns_data_all8_opt_plsql,
599 &hf_tns_data_all8_opt_not_plsql,
600 &hf_tns_data_all8_opt_describe,
601 &hf_tns_data_all8_opt_batch_errors,
602 NULL((void*)0)
603};
604
605static const value_string tns_type_vals[] = {
606 {TNS_TYPE_CONNECT1, "Connect" },
607 {TNS_TYPE_ACCEPT2, "Accept" },
608 {TNS_TYPE_ACK3, "Acknowledge" },
609 {TNS_TYPE_REFUSE4, "Refuse" },
610 {TNS_TYPE_REDIRECT5, "Redirect" },
611 {TNS_TYPE_DATA6, "Data" },
612 {TNS_TYPE_NULL7, "Null" },
613 {TNS_TYPE_ABORT9, "Abort" },
614 {TNS_TYPE_RESEND11, "Resend"},
615 {TNS_TYPE_MARKER12, "Marker"},
616 {TNS_TYPE_ATTENTION13, "Attention"},
617 {TNS_TYPE_CONTROL14, "Control"},
618 {TNS_TYPE_DD15, "Data Descriptor"},
619 {0, NULL((void*)0)}
620};
621
622static const value_string tns_data_funcs[] = {
623 {SQLNET_SET_PROTOCOL1, "Set Protocol"},
624 {SQLNET_SET_DATATYPES2, "Set Datatypes"},
625 {SQLNET_USER_OCI_FUNC3, "User OCI Functions"},
626 {SQLNET_RETURN_STATUS4, "Return Status"},
627 {SQLNET_ACCESS_USR_ADDR5, "Access User Address Space"},
628 {SQLNET_ROW_TRANSF_HDR6, "Row Transfer Header"},
629 {SQLNET_ROW_TRANSF_DATA7, "Row Transfer Data"},
630 {SQLNET_RETURN_OPI_PARAM8, "Return OPI Parameter"},
631 {SQLNET_FUNCCOMPLETE9, "Function Complete"},
632 {SQLNET_NERROR_RET_DEF10, "N Error return definitions follow"},
633 {SQLNET_IOVEC_4FAST_UPI11, "Sending I/O Vec only for fast UPI"},
634 {SQLNET_LONG_4FAST_UPI12, "Sending long for fast UPI"},
635 {SQLNET_INVOKE_USER_CB13, "Invoke user callback"},
636 {SQLNET_LOB_FILE_DF14, "LOB/FILE data follows"},
637 {SQLNET_WARNING15, "Warning messages - may be a set of them"},
638 {SQLNET_DESCRIBE_INFO16, "Describe Information"},
639 {SQLNET_PIGGYBACK_FUNC17, "Piggy back function follow"},
640 {SQLNET_SIG_4UCS18, "Signals special action for untrusted callout support"},
641 {SQLNET_FLUSH_BIND_DATA19, "Flush Out Bind data in DML/w RETURN when error"},
642 {SQLNET_BIT_VECTOR21, "Bit Vector"},
643 {SQLNET_SERVER_PIGGYBACK23, "Server-side Piggyback"},
644 {SQLNET_IMPLICIT_RESULTS27, "Implicit Result Sets"},
645 {SQLNET_END_OF_RESPONSE29, "End of Response"},
646 {SQLNET_TOKEN33, "Token"},
647 {SQLNET_XTRN_PROCSERV_R132, "External Procedures and Services Registrations"},
648 {SQLNET_XTRN_PROCSERV_R268, "External Procedures and Services Registrations"},
649 {SQLNET_SNS0xdeadbeef, "Secure Network Services"},
650 {0, NULL((void*)0)}
651};
652
653/* The authentication mode of an authentication call. */
654static int * const tns_auth_modes[] = {
655 &hf_tns_data_auth_mode_logon,
656 &hf_tns_data_auth_mode_change_password,
657 &hf_tns_data_auth_mode_sysdba,
658 &hf_tns_data_auth_mode_sysoper,
659 &hf_tns_data_auth_mode_with_password,
660 NULL((void*)0)
661};
662
663/* The mode of a DRCP session release. */
664static int * const tns_release_modes[] = {
665 &hf_tns_data_release_mode_deauth,
666 NULL((void*)0)
667};
668
669/* The second options word of a re-execute. */
670static int * const tns_reexec_options2[] = {
671 &hf_tns_data_reexec_opt2_commit,
672 NULL((void*)0)
673};
674
675/* Execute flags, the al8i4[9] word of a TTI_ALL8 execute. */
676static int * const tns_all8_exec_flags[] = {
677 &hf_tns_data_all8_xflag_scrollable,
678 &hf_tns_data_all8_xflag_no_cancel_on_eof,
679 &hf_tns_data_all8_xflag_dml_rowcounts,
680 &hf_tns_data_all8_xflag_implicit_rs,
681 NULL((void*)0)
682};
683
684/* Scrollable-cursor fetch orientation, al8i4[10] of a TTI_ALL8 execute. */
685static const value_string tns_fetch_orientations[] = {
686 {0x00, "None"},
687 {0x01, "Current"},
688 {0x02, "Next"},
689 {0x04, "First"},
690 {0x08, "Last"},
691 {0x10, "Prior"},
692 {0x20, "Absolute"},
693 {0x40, "Relative"},
694 {0, NULL((void*)0)}
695};
696
697/* Server-side piggyback opcodes (python-oracledb's
698 * TNS_SERVER_PIGGYBACK_*). */
699#define TNS_SPB_QUERY_CACHE_INVALIDATION1 1
700#define TNS_SPB_OS_PID_MTS2 2
701#define TNS_SPB_TRACE_EVENT3 3
702#define TNS_SPB_SESS_RET4 4
703#define TNS_SPB_SYNC5 5
704#define TNS_SPB_LTXID7 7
705#define TNS_SPB_AC_REPLAY_CONTEXT8 8
706#define TNS_SPB_EXT_SYNC9 9
707#define TNS_SPB_SESS_SIGNATURE10 10
708
709static const value_string tns_spb_opcodes[] = {
710 {TNS_SPB_QUERY_CACHE_INVALIDATION1, "Query Cache Invalidation"},
711 {TNS_SPB_OS_PID_MTS2, "OS PID (shared server)"},
712 {TNS_SPB_TRACE_EVENT3, "Trace Event"},
713 {TNS_SPB_SESS_RET4, "Session Return"},
714 {TNS_SPB_SYNC5, "Session State Sync"},
715 {TNS_SPB_LTXID7, "Logical Transaction Id"},
716 {TNS_SPB_AC_REPLAY_CONTEXT8, "Application Continuity Replay Context"},
717 {TNS_SPB_EXT_SYNC9, "Extended Sync"},
718 {TNS_SPB_SESS_SIGNATURE10, "Session Signature"},
719 {0, NULL((void*)0)}
720};
721
722/* Status byte of an OCI client's status block. */
723static const value_string tns_oci_oer_status_vals[] = {
724 {1, "Success"},
725 {5, "Error"},
726 {0, NULL((void*)0)}
727};
728
729/* Statement command types, as V$SQL.COMMAND_TYPE numbers them. */
730static const value_string tns_command_types[] = {
731 {1, "CREATE TABLE"},
732 {2, "INSERT"},
733 {3, "SELECT"},
734 {6, "UPDATE"},
735 {7, "DELETE"},
736 {9, "CREATE INDEX"},
737 {12, "DROP TABLE"},
738 {15, "ALTER TABLE"},
739 {21, "CREATE VIEW"},
740 {22, "DROP VIEW"},
741 {44, "COMMIT"},
742 {45, "ROLLBACK"},
743 {47, "PL/SQL EXECUTE"},
744 {85, "TRUNCATE TABLE"},
745 {0, NULL((void*)0)}
746};
747
748static const value_string tns_field_versions[] = {
749 {TNS_FV_11_26, "11.2"},
750 {TNS_FV_12_17, "12.1"},
751 {TNS_FV_12_28, "12.2"},
752 {TNS_FV_12_2_EXT19, "12.2 ext 1"},
753 {TNS_FV_18_110, "18.1"},
754 {TNS_FV_18_1_EXT_111, "18.1 ext 1"},
755 {TNS_FV_19_112, "19.1"},
756 {TNS_FV_19_1_EXT_113, "19.1 ext 1"},
757 {TNS_FV_20_114, "20.1"},
758 {TNS_FV_20_1_EXT_115, "20.1 ext 1"},
759 {TNS_FV_21_116, "21.1"},
760 {TNS_FV_23_117, "23.1"},
761 {TNS_FV_23_1_EXT_118, "23.1 ext 1"},
762 {TNS_FV_23_1_EXT_219, "23.1 ext 2"},
763 {TNS_FV_23_1_EXT_320, "23.1 ext 3"},
764 {TNS_FV_23_1_EXT_421, "23.1 ext 4"},
765 {TNS_FV_23_1_EXT_522, "23.1 ext 5"},
766 {TNS_FV_23_3_EXT_623, "23.3 ext 6"},
767 {TNS_FV_23_424, "23.4"},
768 {0, NULL((void*)0)}
769};
770
771/* Two-phase commit operations (python-oracledb's TNS_TPC_*). */
772static const value_string tns_tpc_switch_ops[] = {
773 {0x01, "Start"},
774 {0x02, "Detach"},
775 {0x04, "Post-detach"},
776 {0, NULL((void*)0)}
777};
778
779static const value_string tns_tpc_change_ops[] = {
780 {0x01, "Commit"},
781 {0x02, "Abort"},
782 {0x03, "Prepare"},
783 {0x04, "Forget"},
784 {0, NULL((void*)0)}
785};
786
787static const value_string tns_tpc_states[] = {
788 {0, "Prepared"},
789 {1, "Requires commit"},
790 {2, "Committed"},
791 {3, "Aborted"},
792 {4, "Read only"},
793 {5, "Forgotten"},
794 {0, NULL((void*)0)}
795};
796
797/* Native network services (ANO) negotiation: services, sub-packet types
798 * and the encryption and integrity algorithm ids. */
799#define TNS_ANO_AUTHENTICATION1 1
800#define TNS_ANO_ENCRYPTION2 2
801#define TNS_ANO_DATA_INTEGRITY3 3
802#define TNS_ANO_SUPERVISOR4 4
803#define TNS_ANO_SP_BYTES1 1
804#define TNS_ANO_SP_UB12 2
805#define TNS_ANO_SP_VERSION5 5
806
807static const value_string tns_sns_services[] = {
808 {TNS_ANO_AUTHENTICATION1, "Authentication"},
809 {TNS_ANO_ENCRYPTION2, "Encryption"},
810 {TNS_ANO_DATA_INTEGRITY3, "Data Integrity"},
811 {TNS_ANO_SUPERVISOR4, "Supervisor"},
812 {0, NULL((void*)0)}
813};
814
815static const value_string tns_sns_subpacket_types[] = {
816 {0, "String"},
817 {1, "Bytes"},
818 {2, "UB1"},
819 {3, "UB2"},
820 {4, "UB4"},
821 {5, "Version"},
822 {6, "Status"},
823 {0, NULL((void*)0)}
824};
825
826static const value_string tns_sns_encryption_algs[] = {
827 {0, "None"},
828 {1, "RC4_40"},
829 {2, "DES"},
830 {3, "DES40"},
831 {6, "RC4_256"},
832 {8, "RC4_56"},
833 {10, "RC4_128"},
834 {11, "3DES112"},
835 {12, "3DES168"},
836 {15, "AES128"},
837 {16, "AES192"},
838 {17, "AES256"},
839 {0, NULL((void*)0)}
840};
841
842static const value_string tns_sns_integrity_algs[] = {
843 {0, "None"},
844 {1, "MD5"},
845 {3, "SHA1"},
846 {4, "SHA512"},
847 {5, "SHA256"},
848 {6, "SHA384"},
849 {0, NULL((void*)0)}
850};
851
852/* Keyword numbers of the key/value pairs a server reports back, for a
853 * session attribute a statement changed (python-oracledb's
854 * TNS_KEYWORD_NUM_*). */
855static const value_string tns_kv_keywords[] = {
856 {168, "CURRENT_SCHEMA"},
857 {172, "EDITION"},
858 {201, "TRANSACTION_ID"},
859 {0, NULL((void*)0)}
860};
861
862/* Oracle TNS native data-type ids. Used by the Set Datatypes
863 * negotiation to label override entries with human names. */
864static const value_string tns_data_types[] = {
865 {TNS_DATATYPE_VARCHAR1, "VARCHAR"},
866 {TNS_DATATYPE_NUMBER2, "NUMBER"},
867 {TNS_DATATYPE_INTEGER3, "BINARY_INTEGER"},
868 {TNS_DATATYPE_FLOAT4, "FLOAT"},
869 {TNS_DATATYPE_STRING5, "STRING"},
870 {TNS_DATATYPE_VARNUM6, "VARNUM"},
871 {TNS_DATATYPE_DECIMAL7, "DECIMAL"},
872 {TNS_DATATYPE_LONG8, "LONG"},
873 {TNS_DATATYPE_VCS9, "VCS"},
874 {TNS_DATATYPE_ROWID11, "RID"},
875 {TNS_DATATYPE_DATE12, "DATE"},
876 {TNS_DATATYPE_VBI15, "VBI"},
877 {TNS_DATATYPE_RAW23, "RAW"},
878 {TNS_DATATYPE_LONG_RAW24, "LONG RAW"},
879 {TNS_DATATYPE_CHAR96, "CHAR"},
880 {TNS_DATATYPE_BINARY_FLOAT100, "BINARY_FLOAT"},
881 {TNS_DATATYPE_BINARY_DOUBLE101, "BINARY_DOUBLE"},
882 {TNS_DATATYPE_REFCURSOR102, "REFCURSOR"},
883 {TNS_DATATYPE_ROWID_EXT104, "ROWID"},
884 {TNS_DATATYPE_ADT109, "ADT"},
885 {TNS_DATATYPE_REF111, "REF"},
886 {TNS_DATATYPE_CLOB112, "CLOB"},
887 {TNS_DATATYPE_BLOB113, "BLOB"},
888 {TNS_DATATYPE_BFILE114, "BFILE"},
889 {TNS_DATATYPE_RSET116, "RSET"},
890 {TNS_DATATYPE_JSON119, "JSON"},
891 {TNS_DATATYPE_VECTOR127, "VECTOR"},
892 {TNS_DATATYPE_TIMESTAMP180, "TIMESTAMP"},
893 {TNS_DATATYPE_TIMESTAMP_TZ181, "TIMESTAMP WITH TIME ZONE"},
894 {TNS_DATATYPE_INTERVAL_YM182, "INTERVAL YEAR TO MONTH"},
895 {TNS_DATATYPE_INTERVAL_DS183, "INTERVAL DAY TO SECOND"},
896 {TNS_DATATYPE_UROWID208, "UROWID"},
897 {TNS_DATATYPE_TIMESTAMP_LTZ231, "TIMESTAMP WITH LOCAL TIME ZONE"},
898 {TNS_DATATYPE_BOOLEAN252, "BOOLEAN"},
899 {0, NULL((void*)0)}
900};
901
902/* Oracle NLS character-set ids - the well-known subset, enough to name
903 * the charsets seen in a Set Datatypes negotiation. */
904static const value_string tns_charsets[] = {
905 {31, "WE8ISO8859P1"},
906 {32, "EE8ISO8859P2"},
907 {35, "CL8ISO8859P5"},
908 {170, "EE8MSWIN1250"},
909 {171, "CL8MSWIN1251"},
910 {178, "WE8MSWIN1252"},
911 {830, "JA16EUC"},
912 {852, "ZHS16GBK"},
913 {865, "ZHT16BIG5"},
914 {867, "ZHT16MSWIN950"},
915 {871, "US7ASCII"},
916 {873, "AL32UTF8"},
917 {2000, "AL16UTF16"},
918 {0, NULL((void*)0)}
919};
920
921/* TTI_LOBOPS operation opcodes. */
922#define TNS_LOB_OP_FILE_ISOPEN0x00400 0x00400
923#define TNS_LOB_OP_FILE_EXISTS0x00800 0x00800
924#define TNS_LOB_OP_CREATE_TEMP0x00110 0x00110
925#define TNS_LOB_OP_IS_OPEN0x11000 0x11000
926
927static const value_string tns_lob_ops[] = {
928 {0x00001, "GET_LENGTH"},
929 {0x00002, "READ"},
930 {0x00020, "TRIM"},
931 {0x00040, "WRITE"},
932 {0x00100, "FILE_OPEN"},
933 {0x00110, "CREATE_TEMP"},
934 {0x00111, "FREE_TEMP"},
935 {0x00200, "FILE_CLOSE"},
936 {0x00400, "FILE_ISOPEN"},
937 {0x00800, "FILE_EXISTS"},
938 {0x04000, "GET_CHUNK_SIZE"},
939 {0x08000, "OPEN"},
940 {0x10000, "CLOSE"},
941 {0x11000, "IS_OPEN"},
942 {0x80000, "ARRAY"},
943 {0, NULL((void*)0)}
944};
945
946/* Column character-set form (csfrm) in an OAC descriptor: whether char data
947 * is in the database charset or the national (AL16UTF16) charset. */
948#define TNS_CSFORM_NCHAR2 2
949static const value_string tns_csform_vals[] = {
950 {1, "Database charset"},
951 {2, "National (AL16UTF16)"},
952 {0, NULL((void*)0)}
953};
954
955/* Bind directions reported per bind in a TTI_IOV vector (TNS_BIND_DIR_*),
956 * cross-referenced with python-oracledb's constants. */
957#define TNS_BIND_DIR_INPUT32 32
958static const value_string tns_iov_bind_dirs[] = {
959 {16, "OUT"},
960 {32, "IN"},
961 {48, "IN OUT"},
962 {0, NULL((void*)0)}
963};
964
965static const value_string tns_data_oci_subfuncs[] = {
966 {1, "Logon to Oracle"},
967 {2, "Open Cursor"},
968 {3, "Parse a Row"},
969 {4, "Execute a Row"},
970 {5, "Fetch a Row"},
971 {8, "Close Cursor"},
972 {9, "Logoff of Oracle"},
973 {10, "Describe a select list column"},
974 {11, "Define where the column goes"},
975 {12, "Auto commit on"},
976 {13, "Auto commit off"},
977 {14, "Commit"},
978 {15, "Rollback"},
979 {16, "Set fatal error options"},
980 {17, "Resume current operation"},
981 {18, "Get Oracle version-date string"},
982 {19, "Until we get rid of OASQL"},
983 {20, "Cancel the current operation"},
984 {21, "Get error message"},
985 {22, "Exit Oracle command"},
986 {23, "Special function"},
987 {24, "Abort"},
988 {25, "Dequeue by RowID"},
989 {26, "Fetch a long column value"},
990 {27, "Create Access Module"},
991 {28, "Save Access Module Statement"},
992 {29, "Save Access Module"},
993 {30, "Parse Access Module Statement"},
994 {31, "How many items?"},
995 {32, "Initialize Oracle"},
996 {33, "Change User ID"},
997 {34, "Bind by reference positional"},
998 {35, "Get n'th Bind Variable"},
999 {36, "Get n'th Into Variable"},
1000 {37, "Bind by reference"},
1001 {38, "Bind by reference numeric"},
1002 {39, "Parse and Execute"},
1003 {40, "Parse for syntax (only)"},
1004 {41, "Parse for syntax and SQL Dictionary lookup"},
1005 {42, "Continue serving after EOF"},
1006 {43, "Array describe"},
1007 {44, "Init sys pars command table"},
1008 {45, "Finalize sys pars command table"},
1009 {46, "Put sys par in command table"},
1010 {47, "Get sys pars from command table"},
1011 {48, "Start Oracle (V6)"},
1012 {49, "Shutdown Oracle (V6)"},
1013 {50, "Run Independent Process (V6)"},
1014 {51, "Test RAM (V6)"},
1015 {52, "Archive operation (V6)"},
1016 {53, "Media Recovery - start (V6)"},
1017 {54, "Media Recovery - record tablespace to recover (V6)"},
1018 {55, "Media Recovery - get starting log seq # (V6)"},
1019 {56, "Media Recovery - recover using offline log (V6)"},
1020 {57, "Media Recovery - cancel media recovery (V6)"},
1021 {58, "Logon to Oracle (V6)"},
1022 {59, "Get Oracle version-date string in new format"},
1023 {60, "Initialize Oracle"},
1024 {61, "Reserved for MAC; close all cursors"},
1025 {62, "Bundled execution call"},
1026 {65, "For direct loader: functions"},
1027 {66, "For direct loader: buffer transfer"},
1028 {67, "Distrib. trans. mgr. RPC"},
1029 {68, "Describe indexes for distributed query"},
1030 {69, "Session operations"},
1031 {70, "Execute using synchronized system commit numbers"},
1032 {71, "Fast UPI calls to OPIAL7"},
1033 {72, "Long Fetch (V7)"},
1034 {73, "Call OPIEXE from OPIALL: no two-task access"},
1035 {74, "Parse Call (V7) to deal with various flavours"},
1036 {76, "RPC call from PL/SQL"},
1037 {77, "Do a KGL operation"},
1038 {78, "Execute and Fetch"},
1039 {79, "X/Open XA operation"},
1040 {80, "New KGL operation call"},
1041 {81, "2nd Half of Logon"},
1042 {82, "1st Half of Logon"},
1043 {83, "Do Streaming Operation"},
1044 {84, "Open Session (71 interface)"},
1045 {85, "X/Open XA operations (71 interface)"},
1046 {86, "Debugging operations"},
1047 {87, "Special debugging operations"},
1048 {88, "XA Start"},
1049 {89, "XA Switch and Commit"},
1050 {90, "Direct copy from db buffers to client address"},
1051 {91, "OKOD Call (In Oracle <= 7 this used to be Connect"},
1052 {93, "RPI Callback with ctxdef"},
1053 {94, "Bundled execution call (V7)"},
1054 {95, "Do Streaming Operation without begintxn"},
1055 {96, "LOB and FILE related calls"},
1056 {97, "File Create call"},
1057 {98, "Describe query (V8) call"},
1058 {99, "Connect (non-blocking attach host)"},
1059 {100, "Open a recursive cursor"},
1060 {101, "Bundled KPR Execution"},
1061 {102, "Bundled PL/SQL execution"},
1062 {103, "Transaction start, attach, detach"},
1063 {104, "Transaction commit, rollback, recover"},
1064 {105, "Cursor close all"},
1065 {106, "Failover into piggyback"},
1066 {107, "Session switching piggyback (V8)"},
1067 {108, "Do Dummy Defines"},
1068 {109, "Init sys pars (V8)"},
1069 {110, "Finalize sys pars (V8)"},
1070 {111, "Put sys par in par space (V8)"},
1071 {112, "Terminate sys pars (V8)"},
1072 {114, "Init Untrusted Callbacks"},
1073 {115, "Generic authentication call"},
1074 {116, "FailOver Get Instance call"},
1075 {117, "Oracle Transaction service Commit remote sites"},
1076 {118, "Get the session key"},
1077 {119, "Describe any (V8)"},
1078 {120, "Cancel All"},
1079 {121, "AQ Enqueue"},
1080 {122, "AQ Dequeue"},
1081 {123, "Object transfer"},
1082 {124, "RFS Call"},
1083 {125, "Kernel programmatic notification"},
1084 {126, "Listen"},
1085 {127, "Oracle Transaction service Commit remote sites (V >= 8.1.3)"},
1086 {128, "Dir Path Prepare"},
1087 {129, "Dir Path Load Stream"},
1088 {130, "Dir Path Misc. Ops"},
1089 {131, "Memory Stats"},
1090 {132, "AQ Properties Status"},
1091 {134, "Remote Fetch Archive Log FAL"},
1092 {135, "Client ID propagation"},
1093 {136, "DR Server CNX Process"},
1094 {138, "SPFILE parameter put"},
1095 {139, "KPFC exchange"},
1096 {140, "Object Transfer (V8.2)"},
1097 {141, "Push Transaction"},
1098 {142, "Pop Transaction"},
1099 {143, "KFN Operation"},
1100 {144, "Dir Path Unload Stream"},
1101 {145, "AQ batch enqueue dequeue"},
1102 {146, "File Transfer"},
1103 {147, "Ping"},
1104 {148, "TSM"},
1105 {150, "Begin TSM"},
1106 {151, "End TSM"},
1107 {152, "Set schema"},
1108 {153, "Fetch from suspended result set"},
1109 {154, "Key/Value pair"},
1110 {155, "XS Create session Operation"},
1111 {156, "XS Session Roundtrip Operation"},
1112 {157, "XS Piggyback Operation"},
1113 {158, "KSRPC Execution"},
1114 {159, "Streams combined capture apply"},
1115 {160, "AQ replay information"},
1116 {161, "SSCR"},
1117 {162, "Session Get"},
1118 {163, "Session RLS"},
1119 {165, "Workload replay data"},
1120 {166, "Replay statistic data"},
1121 {167, "Query Cache Stats"},
1122 {168, "Query Cache IDs"},
1123 {169, "RPC Test Stream"},
1124 {170, "Replay PL/SQL RPC"},
1125 {171, "XStream Out"},
1126 {172, "Golden Gate RPC"},
1127 {176, "Session state"},
1128 {187, "Notify"},
1129 {199, "Pipeline begin"},
1130 {200, "Pipeline end"},
1131 {205, "End-user security context"},
1132 {0, NULL((void*)0)}
1133};
1134static value_string_ext tns_data_oci_subfuncs_ext = VALUE_STRING_EXT_INIT(tns_data_oci_subfuncs){ _try_val_to_str_ext_init, 0, (sizeof (tns_data_oci_subfuncs
) / sizeof ((tns_data_oci_subfuncs)[0]))-1, tns_data_oci_subfuncs
, "tns_data_oci_subfuncs", ((void*)0) }
;
1135
1136/* The final byte of a TNS_MARKER body selects break vs reset:
1137 * 01 00 01 = break, 01 00 02 = reset. */
1138static const value_string tns_marker_functions[] = {
1139 {1, "Break (interrupt call)"},
1140 {2, "Reset (clear line)"},
1141 {0, NULL((void*)0)}
1142};
1143
1144static const value_string tns_marker_types[] = {
1145 {0, "Data Marker - 0 Data Bytes"},
1146 {1, "Data Marker - 1 Data Bytes"},
1147 {2, "Attention Marker"},
1148 {0, NULL((void*)0)}
1149};
1150
1151static const value_string tns_control_cmds[] = {
1152 {1, "Oracle Trace Command"},
1153 {0, NULL((void*)0)}
1154};
1155
1156/* What a value decoder needs to know about one column or bind: its
1157 * datatype, character set form, and the data length (buffer size) the
1158 * describe gave it. */
1159typedef struct _tns_column_t {
1160 uint8_t type;
1161 uint8_t csform; /* character set form: 2 = national */
1162 uint32_t data_len;
1163} tns_column_t;
1164
1165/* Columns from the most recent describe (TTI_DCB), threaded to a later
1166 * TTI_RXD response so its row values can be split per column. */
1167typedef struct _tns_describe_t {
1168 uint32_t num_cols;
1169 tns_column_t *cols;
1170} tns_describe_t;
1171
1172/* The bind types of a cursor, from the execute that opened it. A later
1173 * execute of the same cursor may send its values with no descriptors. */
1174typedef struct _tns_binds_t {
1175 uint32_t count;
1176 uint32_t num_return; /* the last num_return are RETURNING ... INTO binds */
1177 tns_column_t *cols;
1178} tns_binds_t;
1179
1180/* The call a response answers: some response messages can only be read
1181 * knowing what was asked. */
1182typedef struct _tns_call_t {
1183 uint8_t func; /* OCI function id */
1184 uint32_t exec_flags; /* al8i4[9] of a TTI_ALL8 execute */
1185 uint32_t num_binds; /* bind types of an execute */
1186 uint32_t num_return; /* ... of which the last are RETURNING ... INTO binds */
1187 tns_column_t *binds;
1188 uint32_t lob_op; /* TTI_LOBOPS operation */
1189 uint32_t lob_locator_len; /* ... its source locator length */
1190 bool_Bool lob_amount; /* ... whether it sent an amount */
1191} tns_call_t;
1192
1193typedef struct _tns_conv_info_t {
1194 uint32_t pending_connect_data;
1195 /* The most recent call the client made. */
1196 tns_call_t *last_call;
1197 /* The client speaks the OCI dialect: fixed-width little-endian
1198 * integers and 8-byte pointer indicators, where a thin client uses
1199 * variable-length integers and 1-byte pointer flags. */
1200 bool_Bool oci_dialect;
1201 /* The TTC field version the client and server settled on, from the
1202 * client's TTI_DTY; 0 until seen. */
1203 uint8_t field_version;
1204 /* The TTC field version the server offered in its TTI_PRO reply,
1205 * which can be higher; 0 until seen. */
1206 uint8_t server_field_version;
1207 /* Native network encryption: the server picked an algorithm, and
1208 * the frame of the client's last negotiation packet, after which the
1209 * data packets are encrypted. */
1210 bool_Bool ano_encryption;
1211 uint32_t ano_active_after;
1212 tns_describe_t *last_describe;
1213 /* Bind types of an execute that opened a new cursor, waiting for the
1214 * status that names the cursor id. */
1215 tns_binds_t *pending_binds;
1216 /* Cursor id -> tns_binds_t. */
1217 wmem_map_t *cursor_binds;
1218} tns_conv_info_t;
1219
1220/* p_add_proto_data key for the describe a TTI_RXD response packet uses. */
1221#define TNS_PROTO_DATA_DESCRIBE1 1
1222/* p_add_proto_data key for the remembered binds of a re-execute. */
1223#define TNS_PROTO_DATA_BINDS2 2
1224/* p_add_proto_data key for the call a response packet answers. */
1225#define TNS_PROTO_DATA_CALL3 3
1226/* p_add_proto_data key for whether a packet is in the OCI dialect. */
1227#define TNS_PROTO_DATA_OCI4 4
1228/* p_add_proto_data key for the field version in force for a packet. */
1229#define TNS_PROTO_DATA_FV5 5
1230/* p_add_proto_data key for whether a packet is encrypted. */
1231#define TNS_PROTO_DATA_ENCRYPTED6 6
1232/* p_add_proto_data key for the field version the server offered. */
1233#define TNS_PROTO_DATA_SERVER_FV7 7
1234
1235/* Execute flag asking for the rows each array DML iteration affected. */
1236#define TNS_EXEC_FLAGS_DML_ROWCOUNTS0x4000 0x4000
1237
1238void proto_reg_handoff_tns(void);
1239static int dissect_tns_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U___attribute__((unused)));
1240
1241static tns_conv_info_t*
1242tns_get_conv_info(packet_info *pinfo)
1243{
1244 conversation_t *conversation = find_or_create_conversation(pinfo);
1245
1246 tns_conv_info_t *tns_info = (tns_conv_info_t *)conversation_get_proto_data(conversation, proto_tns);
1247 if (!tns_info) {
1248 tns_info = wmem_new0(wmem_file_scope(), tns_conv_info_t)((tns_conv_info_t*)wmem_alloc0((wmem_file_scope()), sizeof(tns_conv_info_t
)))
;
1249 tns_info->cursor_binds = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
1250 conversation_add_proto_data(conversation, proto_tns, tns_info);
1251 }
1252 return tns_info;
1253}
1254
1255/* The TTC field version negotiated on the packet's connection, or 0 when
1256 * the negotiation was not seen - which the decoders read as the 11g
1257 * shape. Stored per packet on the first pass. */
1258static unsigned tns_field_version(packet_info *pinfo)
1259{
1260 void *stored = p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_FV5);
1261 if ( stored || PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
1262 return stored ? GPOINTER_TO_UINT(stored)((guint) (gulong) (stored)) - 1 : 0;
1263
1264 unsigned fv = tns_get_conv_info(pinfo)->field_version;
1265 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_FV5, GUINT_TO_POINTER(fv + 1)((gpointer) (gulong) (fv + 1)));
1266 return fv;
1267}
1268
1269/* The TTC field version the server offered on the packet's connection -
1270 * its own release, before the client lowered it - or 0 when the
1271 * negotiation was not seen. Stored per packet on the first pass. */
1272static unsigned tns_server_field_version(packet_info *pinfo)
1273{
1274 void *stored = p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_SERVER_FV7);
1275 if ( stored || PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
1276 return stored ? GPOINTER_TO_UINT(stored)((guint) (gulong) (stored)) - 1 : 0;
1277
1278 unsigned fv = tns_get_conv_info(pinfo)->server_field_version;
1279 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_SERVER_FV7, GUINT_TO_POINTER(fv + 1)((gpointer) (gulong) (fv + 1)));
1280 return fv;
1281}
1282
1283/* Whether the connection is known to predate 11g (a 10g server): its
1284 * describe lacks the fields 11g added. */
1285static bool_Bool tns_before_11g(packet_info *pinfo)
1286{
1287 unsigned fv = tns_field_version(pinfo);
1288 return fv != 0 && fv < TNS_FV_11_26;
1289}
1290
1291/* Whether a data packet is encrypted by native network encryption.
1292 * Stored per packet on the first pass. */
1293static bool_Bool tns_is_encrypted(packet_info *pinfo)
1294{
1295 void *stored = p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_ENCRYPTED6);
1296 if ( stored || PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
1297 return GPOINTER_TO_UINT(stored)((guint) (gulong) (stored)) == 2;
1298
1299 tns_conv_info_t *tns_info = tns_get_conv_info(pinfo);
1300 bool_Bool encrypted = tns_info->ano_active_after && pinfo->num > tns_info->ano_active_after;
1301 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_ENCRYPTED6, GUINT_TO_POINTER(encrypted ? 2 : 1)((gpointer) (gulong) (encrypted ? 2 : 1)));
1302 return encrypted;
1303}
1304
1305static unsigned get_data_func_id(tvbuff_t *tvb, int offset)
1306{
1307 /* Determine Data Function id */
1308 uint8_t first_byte;
1309
1310 first_byte =
1311 tvb_reported_length_remaining(tvb, offset) > 0 ? tvb_get_uint8(tvb, offset) : 0;
1312
1313 if ( tvb_bytes_exist(tvb, offset, 4) && first_byte == 0xDE &&
1314 tvb_get_uint24(tvb, offset+1, ENC_BIG_ENDIAN0x00000000) == 0xADBEEF )
1315 {
1316 return SQLNET_SNS0xdeadbeef;
1317 }
1318 else
1319 {
1320 return (unsigned)first_byte;
1321 }
1322}
1323
1324static int get_strtype_custom(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1325{
1326 int ret = 1; // 1st byte contains 254 or length if smaller than 64
1327 int len = 0;
1328
1329 wmem_strbuf_t *strbuf = wmem_strbuf_new(pinfo->pool, "");
1330
1331 len = tvb_get_uint8(tvb, offset);
1332 if (len == 254) {
1333 int actual_len = 0;
1334 len = 0;
Value stored to 'len' is never read
1335 do { // walk over the chunks
1336 len = tvb_get_uint8(tvb, offset + ret);
1337 ret++; // 1st byte with the chunk size
1338 wmem_strbuf_append(strbuf, (const char *)tvb_get_string_enc(pinfo->pool, tvb, offset + ret, len, ENC_ASCII0x00000000|ENC_NA0x00000000));
1339 ret += len; // length of the string's chunk
1340 actual_len += len;
1341 } while (len == 64);
1342 ret++; // has to be null-terminated
1343 len = actual_len;
1344 }
1345 else {
1346 ret += len;
1347 wmem_strbuf_append(strbuf, (const char *)tvb_get_string_enc(pinfo->pool, tvb, offset + 1, len, ENC_ASCII0x00000000|ENC_NA0x00000000));
1348 }
1349
1350 proto_tree_add_uint(tree, hf_tns_data_opi_param_length, tvb, offset, 1, len);
1351 proto_tree_add_string(tree, hf_tns_data_opi_param_value, tvb, offset+1, ret-1, wmem_strbuf_get_str(strbuf));
1352
1353 return ret;
1354}
1355
1356/* Decode an Oracle variable-length integer (ub4 / sb4):
1357 * a length byte, then that many big-endian magnitude bytes. The low 7 bits
1358 * of the length byte are the magnitude width (0..4); the high bit flags a
1359 * negative value in sign-magnitude form (not two's complement) — so -1 is
1360 * 0x81 0x01 and NUMBER scale -127 is 0x81 0x7f.
1361 * Returns the number of bytes consumed. */
1362static int get_sb4_custom(tvbuff_t *tvb, int offset, int *result)
1363{
1364 uint8_t first_byte = tvb_get_uint8(tvb, offset); // Contains length of a value
1365 bool_Bool negative = (first_byte & 0x80) != 0;
1366 uint8_t width = first_byte & 0x7f;
1367 int magnitude = 0;
1368
1369 switch(width)
1370 {
1371 case 0:
1372 magnitude = 0;
1373 break;
1374 case 1:
1375 magnitude = tvb_get_uint8(tvb, offset+1);
1376 break;
1377 case 2:
1378 magnitude = tvb_get_ntohs(tvb, offset+1);
1379 break;
1380 case 3:
1381 magnitude = tvb_get_ntoh24(tvb, offset+1);
1382 break;
1383 case 4:
1384 magnitude = tvb_get_ntohl(tvb, offset+1);
1385 break;
1386 default:
1387 /* Width 5..0x7f is not a valid 1..4-byte integer. In practice
1388 * only a raw ub2 counter read through this helper reaches here;
1389 * the historic client behaviour is to consume two bytes and
1390 * return the negated second byte, which keeps the stream
1391 * aligned. The value is discarded by such callers. */
1392 if ( tvb_reported_length_remaining(tvb, offset) < 2 )
1393 {
1394 /* Not even that second byte is present. The width came
1395 * off the wire, so this is malformed input rather than
1396 * a bug in the dissector - step over the width alone. */
1397 *result = 0;
1398 return 1;
1399 }
1400 *result = -(int)tvb_get_uint8(tvb, offset+1);
1401 return 2;
1402 }
1403 *result = negative ? -magnitude : magnitude;
1404 return width + 1;
1405}
1406
1407/* Decode an Oracle variable-length ub8: a width byte (0..8), then that
1408 * many big-endian bytes. Returns the number of bytes consumed. */
1409static int get_ub8_custom(tvbuff_t *tvb, int offset, uint64_t *result)
1410{
1411 uint8_t width = tvb_get_uint8(tvb, offset);
1412 uint64_t value = 0;
1413
1414 if ( width > 8 )
1415 {
1416 /* Not a valid width; the value came off the wire, so step over
1417 * the width byte alone rather than claim bytes. */
1418 *result = 0;
1419 return 1;
1420 }
1421 for ( int i = 0; i < width; i++ )
1422 value = (value << 8) | tvb_get_uint8(tvb, offset + 1 + i);
1423 *result = value;
1424 return 1 + width;
1425}
1426
1427/* Walk the chunks of a chunked (0xFE) value, starting after the 0xFE:
1428 * (length, bytes) pairs until a zero length. A length is one byte up to
1429 * field version 12.1 and a variable-length ub4 from 12.2 on. The data is
1430 * appended to strbuf as UTF-8 when strbuf is not NULL. Returns the bytes
1431 * consumed, the terminating zero included. */
1432static int tns_chunks_len(tvbuff_t *tvb, packet_info *pinfo, int offset, wmem_strbuf_t *strbuf)
1433{
1434 bool_Bool ub4_lengths = tns_field_version(pinfo) >= TNS_FV_12_28;
1435 int o = offset;
1436
1437 while ( tvb_reported_length_remaining(tvb, o) > 0 )
1438 {
1439 int chunk_len;
1440 if ( ub4_lengths )
1441 o += get_sb4_custom(tvb, o, &chunk_len);
1442 else
1443 {
1444 chunk_len = tvb_get_uint8(tvb, o);
1445 o += 1;
1446 }
1447 if ( chunk_len <= 0 )
1448 break;
1449 if ( strbuf )
1450 wmem_strbuf_append(strbuf, (const char *)tvb_get_string_enc(pinfo->pool, tvb, o, chunk_len, ENC_UTF_80x00000002|ENC_NA0x00000000));
1451 o += chunk_len;
1452 }
1453 return o - offset;
1454}
1455
1456/* Decode a DALC (Data-Length-And-Content) blob. The leading byte is a
1457 * length only in the middle of its range:
1458 *
1459 * 0x00 empty
1460 * 0x01..0xFC that many data bytes follow (252 is the longest)
1461 * 0xFD absent value: the two-byte placeholder FD 01, no data
1462 * 0xFE chunked: (len, bytes) pairs until a 0-length chunk
1463 * 0xFF null - a marker only, no data follows
1464 *
1465 * The top three bytes are markers, not lengths. The null marker consumes
1466 * just itself. The absent-value placeholder fills a bind slot that has no
1467 * inline value - a pure OUT bind, or a NULL of a type with no inline form
1468 * such as BOOLEAN - and consumes itself plus the 0x01 after it. Reading
1469 * either as a length would claim bytes that are not there and misalign
1470 * every field after it, so they have to be spelled out rather than left
1471 * to the default.
1472 *
1473 * The chunk lengths in the 0xFE form are single bytes up to field version
1474 * 12.1, and variable-length ub4s from 12.2 on.
1475 *
1476 * Returns the number of bytes consumed from the tvb and, when content
1477 * is non-empty, a UTF-8 string allocated from pinfo->pool. */
1478static int get_dalc_custom(tvbuff_t *tvb, packet_info *pinfo, int offset, const char **out_str)
1479{
1480 uint8_t first = tvb_get_uint8(tvb, offset);
1481 if ( first == 0 || first == 255 )
1482 {
1483 if ( out_str )
1484 *out_str = NULL((void*)0);
1485 return 1;
1486 }
1487 if ( first == TNS_DALC_ABSENT0xFD )
1488 {
1489 if ( out_str )
1490 *out_str = NULL((void*)0);
1491 return 2;
1492 }
1493 if ( first != 254 )
1494 {
1495 if ( out_str )
1496 *out_str = (const char *)tvb_get_string_enc(pinfo->pool, tvb, offset + 1, first, ENC_UTF_80x00000002|ENC_NA0x00000000);
1497 return 1 + first;
1498 }
1499
1500 /* Chunked form: (len, bytes)+ until a zero-length chunk. */
1501 wmem_strbuf_t *strbuf = wmem_strbuf_new(pinfo->pool, "");
1502 int used = 1 + tns_chunks_len(tvb, pinfo, offset + 1, strbuf);
1503 if ( out_str )
1504 *out_str = wmem_strbuf_get_str(strbuf);
1505 return used;
1506}
1507
1508/* A server's message text carries a trailing newline; a client strips it
1509 * before showing the error. Returns a pinfo->pool string, or NULL. */
1510static const char *tns_trim_message(packet_info *pinfo, const char *msg)
1511{
1512 size_t len;
1513
1514 if ( !msg )
1515 return NULL((void*)0);
1516 len = strlen(msg);
1517 while ( len > 0 && (msg[len - 1] == '\n' || msg[len - 1] == '\r' || msg[len - 1] == ' ') )
1518 len--;
1519 return wmem_strndup(pinfo->pool, msg, len);
1520}
1521
1522/* Decode a bytes_with_length / str_with_length field: a ub4 count, and
1523 * a DALC carrying the value only when that count is non-zero. The count
1524 * is not simply a byte to step over - an empty field is the count
1525 * alone, so reading a DALC anyway consumes whatever follows it.
1526 * Returns bytes consumed; *out_str (when non-NULL) gets the string, or
1527 * NULL when the field is empty. */
1528static int get_field_with_length(tvbuff_t *tvb, packet_info *pinfo, int offset, const char **out_str)
1529{
1530 int count = 0;
1531 int used = get_sb4_custom(tvb, offset, &count);
1532 if ( out_str )
1533 *out_str = NULL((void*)0);
1534 if ( count > 0 )
1535 used += get_dalc_custom(tvb, pinfo, offset + used, out_str);
1536 return used;
1537}
1538
1539/* Render an Oracle NUMBER value as a decimal string.
1540 * Base-100 float: byte 0 is the biased exponent (top bit = sign, inverted
1541 * for negatives); the rest are base-100 mantissa groups, with a trailing
1542 * 0x66 terminator on negatives.
1543 * Returns a pinfo->pool string, or NULL if the value is not renderable. */
1544static const char *tns_format_number(packet_info *pinfo, const uint8_t *data, int len)
1545{
1546 if ( len <= 0 )
1547 return NULL((void*)0);
1548 if ( len == 1 )
1549 return (data[0] == 0x80) ? "0" : NULL((void*)0); /* 0x80 = zero; sentinels skipped */
1550
1551 uint8_t exp_byte = data[0];
1552 bool_Bool is_pos = (exp_byte & 0x80) != 0;
1553 int exponent = is_pos ? (exp_byte & 0x7f) - 65 : ((~exp_byte) & 0x7f) - 65;
1554
1555 int mant_len = len - 1;
1556 if ( !is_pos && mant_len > 0 && data[len - 1] == 0x66 )
1557 mant_len--; /* drop the negative terminator */
1558
1559 /* Build the base-100 digit string (two decimal digits per group). */
1560 wmem_strbuf_t *digits = wmem_strbuf_new(pinfo->pool, "");
1561 for ( int i = 0; i < mant_len; i++ )
1562 {
1563 int pair = is_pos ? (data[1 + i] - 1) : (101 - data[1 + i]);
1564 if ( pair < 0 || pair > 99 )
1565 return NULL((void*)0); /* malformed */
1566 wmem_strbuf_append_printf(digits, "%02d", pair);
1567 }
1568 const char *ds = wmem_strbuf_get_str(digits);
1569 int dlen = (int)wmem_strbuf_get_len(digits);
1570 int int_digits = (exponent + 1) * 2;
1571
1572 wmem_strbuf_t *ip = wmem_strbuf_new(pinfo->pool, "");
1573 wmem_strbuf_t *fp = wmem_strbuf_new(pinfo->pool, "");
1574 if ( int_digits >= dlen )
1575 {
1576 wmem_strbuf_append(ip, ds);
1577 for ( int i = 0; i < int_digits - dlen; i++ )
1578 wmem_strbuf_append_c(ip, '0');
1579 }
1580 else if ( int_digits <= 0 )
1581 {
1582 wmem_strbuf_append_c(ip, '0');
1583 for ( int i = 0; i < -int_digits; i++ )
1584 wmem_strbuf_append_c(fp, '0');
1585 wmem_strbuf_append(fp, ds);
1586 }
1587 else
1588 {
1589 wmem_strbuf_append(ip, wmem_strndup(pinfo->pool, ds, int_digits));
1590 wmem_strbuf_append(fp, ds + int_digits);
1591 }
1592
1593 /* Trim leading zeros on the integer part, trailing zeros on the fraction. */
1594 const char *ips = wmem_strbuf_get_str(ip);
1595 while ( ips[0] == '0' && ips[1] != '\0' )
1596 ips++;
1597 char *fps = wmem_strdup(pinfo->pool, wmem_strbuf_get_str(fp));
1598 int flen = (int)strlen(fps);
1599 while ( flen > 0 && fps[flen - 1] == '0' )
1600 fps[--flen] = '\0';
1601
1602 const char *sign = is_pos ? "" : "-";
1603 if ( flen > 0 )
1604 return wmem_strdup_printf(pinfo->pool, "%s%s.%s", sign, ips, fps);
1605 return wmem_strdup_printf(pinfo->pool, "%s%s", sign, ips);
1606}
1607
1608/* Render an Oracle DATE / TIMESTAMP value as an
1609 * ISO-ish string. 7 bytes: century+100, year+100, month, day, hour+1,
1610 * minute+1, second+1; 11 bytes add 4-byte big-endian nanoseconds.
1611 * Returns a pinfo->pool string, or NULL. */
1612static const char *tns_format_date(packet_info *pinfo, const uint8_t *data, int len)
1613{
1614 if ( len < 7 )
1615 return NULL((void*)0);
1616 int year = (data[0] - 100) * 100 + (data[1] - 100);
1617 int month = data[2], day = data[3];
1618 int hour = data[4] - 1, minute = data[5] - 1, second = data[6] - 1;
1619 if ( month < 1 || month > 12 || day < 1 || day > 31 ||
1620 hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59 )
1621 return NULL((void*)0);
1622 if ( len >= 11 )
1623 {
1624 uint32_t nsec = ((uint32_t)data[7] << 24) | ((uint32_t)data[8] << 16) |
1625 ((uint32_t)data[9] << 8) | data[10];
1626 if ( nsec > 0 )
1627 return wmem_strdup_printf(pinfo->pool, "%04d-%02d-%02d %02d:%02d:%02d.%09u",
1628 year, month, day, hour, minute, second, nsec);
1629 }
1630 return wmem_strdup_printf(pinfo->pool, "%04d-%02d-%02d %02d:%02d:%02d",
1631 year, month, day, hour, minute, second);
1632}
1633
1634/* Days since 1970-01-01 of a proleptic Gregorian date, and back. */
1635static int64_t tns_days_from_civil(int64_t y, unsigned m, unsigned d)
1636{
1637 y -= m <= 2;
1638 int64_t era = (y >= 0 ? y : y - 399) / 400;
1639 unsigned yoe = (unsigned)(y - era * 400);
1640 unsigned doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1;
1641 unsigned doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
1642 return era * 146097 + (int64_t)doe - 719468;
1643}
1644
1645static void tns_civil_from_days(int64_t z, int64_t *y, unsigned *m, unsigned *d)
1646{
1647 z += 719468;
1648 int64_t era = (z >= 0 ? z : z - 146096) / 146097;
1649 unsigned doe = (unsigned)(z - era * 146097);
1650 unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
1651 unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
1652 unsigned mp = (5 * doy + 2) / 153;
1653 *d = doy - (153 * mp + 2) / 5 + 1;
1654 *m = mp < 10 ? mp + 3 : mp - 9;
1655 *y = (int64_t)yoe + era * 400 + (*m <= 2);
1656}
1657
1658/* Render an Oracle TIMESTAMP WITH TIME ZONE value: 13 bytes, the
1659 * 11-byte TIMESTAMP form holding the instant in UTC, then two zone
1660 * bytes. With the top bit of the first clear they are an offset, hour
1661 * + 20 and minute + 60, and the value is shown in local time with that
1662 * offset; with it set they hold a named zone's region id,
1663 * ((b0 & 0x7f) << 6) + (b1 >> 2), and the value is shown in UTC.
1664 * Returns a pinfo->pool string, or NULL. */
1665static const char *tns_format_timestamp_tz(packet_info *pinfo, const uint8_t *data, int len)
1666{
1667 const char *utc;
1668 uint32_t nsec;
1669 int64_t minutes, days, year;
1670 unsigned month, day;
1671 int tz_hour, tz_min, minute_of_day;
1672 char sign;
1673
1674 if ( len != 13 )
1675 return tns_format_date(pinfo, data, len);
1676 utc = tns_format_date(pinfo, data, 11);
1677 if ( !utc )
1678 return NULL((void*)0);
1679 if ( data[11] & 0x80 )
1680 return wmem_strdup_printf(pinfo->pool, "%s UTC (time zone region %u)", utc,
1681 ((unsigned)(data[11] & 0x7f) << 6) + (data[12] >> 2));
1682
1683 /* Shift the UTC wall clock by the offset, in whole minutes. */
1684 tz_hour = data[11] - 20;
1685 tz_min = data[12] - 60;
1686 days = tns_days_from_civil((data[0] - 100) * 100 + (data[1] - 100), data[2], data[3]);
1687 minutes = days * 1440 + (data[4] - 1) * 60 + (data[5] - 1) + tz_hour * 60 + tz_min;
1688 days = minutes >= 0 ? minutes / 1440 : -((-minutes + 1439) / 1440);
1689 minute_of_day = (int)(minutes - days * 1440);
1690 tns_civil_from_days(days, &year, &month, &day);
1691
1692 nsec = ((uint32_t)data[7] << 24) | ((uint32_t)data[8] << 16) | ((uint32_t)data[9] << 8) | data[10];
1693 /* The sign goes on the whole offset: -03:30 is hour -3, minute -30. */
1694 sign = (tz_hour < 0 || tz_min < 0) ? '-' : '+';
1695 if ( nsec )
1696 return wmem_strdup_printf(pinfo->pool, "%04" PRId64"l" "d" "-%02u-%02u %02d:%02d:%02d.%09u %c%02d:%02d",
1697 year, month, day, minute_of_day / 60, minute_of_day % 60, data[6] - 1, nsec,
1698 sign, abs(tz_hour), abs(tz_min));
1699 return wmem_strdup_printf(pinfo->pool, "%04" PRId64"l" "d" "-%02u-%02u %02d:%02d:%02d %c%02d:%02d",
1700 year, month, day, minute_of_day / 60, minute_of_day % 60, data[6] - 1,
1701 sign, abs(tz_hour), abs(tz_min));
1702}
1703
1704/* Render an Oracle INTERVAL YEAR TO MONTH (5 bytes: years as a
1705 * big-endian ub4 biased by 2^31, months biased by 60) or INTERVAL DAY TO
1706 * SECOND (11 bytes: days as a ub4 biased by 2^31, hours, minutes and
1707 * seconds each biased by 60, nanoseconds as a ub4 biased by 2^31). All
1708 * fields carry the interval's sign. Rendered as Oracle writes an
1709 * interval literal: [-]Y-MM, or [-]D HH:MM:SS[.fffffffff].
1710 * Returns a pinfo->pool string, or NULL. */
1711static const char *tns_format_interval(packet_info *pinfo, uint8_t dtype, const uint8_t *data, int len)
1712{
1713 int32_t lead = (int32_t)((((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) |
1714 ((uint32_t)data[2] << 8) | data[3]) - 0x80000000u);
1715
1716 if ( dtype == TNS_DATATYPE_INTERVAL_YM182 && len == 5 )
1717 {
1718 int months = data[4] - 60;
1719 bool_Bool neg = lead < 0 || months < 0;
1720 return wmem_strdup_printf(pinfo->pool, "%s%d-%02d", neg ? "-" : "",
1721 abs(lead), abs(months));
1722 }
1723 if ( dtype == TNS_DATATYPE_INTERVAL_DS183 && len == 11 )
1724 {
1725 int hours = data[4] - 60, minutes = data[5] - 60, seconds = data[6] - 60;
1726 int32_t nsec = (int32_t)((((uint32_t)data[7] << 24) | ((uint32_t)data[8] << 16) |
1727 ((uint32_t)data[9] << 8) | data[10]) - 0x80000000u);
1728 bool_Bool neg = lead < 0 || hours < 0 || minutes < 0 || seconds < 0 || nsec < 0;
1729 if ( nsec )
1730 return wmem_strdup_printf(pinfo->pool, "%s%d %02d:%02d:%02d.%09d", neg ? "-" : "",
1731 abs(lead), abs(hours), abs(minutes), abs(seconds), abs(nsec));
1732 return wmem_strdup_printf(pinfo->pool, "%s%d %02d:%02d:%02d", neg ? "-" : "",
1733 abs(lead), abs(hours), abs(minutes), abs(seconds));
1734 }
1735 return NULL((void*)0);
1736}
1737
1738/* Render an Oracle BINARY_FLOAT (4 bytes) / BINARY_DOUBLE (8 bytes) value
1739 * Stored in an order-preserving IEEE-754 form: if the
1740 * high bit is set the value was positive (clear it), else it was negative
1741 * (invert all bits); then read as big-endian IEEE-754. Returns a
1742 * pinfo->pool string, or NULL. */
1743static const char *tns_format_binary_float(packet_info *pinfo, const uint8_t *data, int len)
1744{
1745 char buf[G_ASCII_DTOSTR_BUF_SIZE(29 + 10)];
1746
1747 if ( len == 4 )
1748 {
1749 uint32_t u = ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) |
1750 ((uint32_t)data[2] << 8) | data[3];
1751 u = (u & 0x80000000u) ? (u & 0x7fffffffu) : ~u;
1752 float f;
1753 memcpy(&f, &u, 4);
1754 /* Locale-independent '.' decimal separator. */
1755 g_ascii_formatd(buf, sizeof(buf), "%g", (double)f);
1756 return wmem_strdup(pinfo->pool, buf);
1757 }
1758 if ( len == 8 )
1759 {
1760 uint64_t u = 0;
1761 for ( int i = 0; i < 8; i++ )
1762 u = (u << 8) | data[i];
1763 u = (u & UINT64_C(0x8000000000000000)0x8000000000000000UL) ? (u & UINT64_C(0x7fffffffffffffff)0x7fffffffffffffffUL) : ~u;
1764 double d;
1765 memcpy(&d, &u, 8);
1766 g_ascii_formatd(buf, sizeof(buf), "%g", d);
1767 return wmem_strdup(pinfo->pool, buf);
1768 }
1769 return NULL((void*)0);
1770}
1771
1772/* The base-64 alphabet of Oracle's printable rowids. */
1773static const char tns_rowid_alphabet[] =
1774 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1775
1776/* Append value to buf as `digits` base-64 characters, most significant
1777 * first. */
1778static void tns_rowid_append(wmem_strbuf_t *buf, uint32_t value, int digits)
1779{
1780 char chars[6];
1781
1782 for ( int i = digits - 1; i >= 0; i-- )
1783 {
1784 chars[i] = tns_rowid_alphabet[value & 0x3f];
1785 value >>= 6;
1786 }
1787 wmem_strbuf_append_len(buf, chars, digits);
1788}
1789
1790/* Render a physical rowid as the 18-character extended rowid ROWIDTOCHAR
1791 * prints: object, file, block and slot in 6, 3, 6 and 3 base-64 digits.
1792 * Returns a pinfo->pool string. */
1793static const char *tns_format_rowid(packet_info *pinfo, uint32_t rba, uint32_t part, uint32_t block, uint32_t slot)
1794{
1795 wmem_strbuf_t *buf = wmem_strbuf_new(pinfo->pool, "");
1796
1797 tns_rowid_append(buf, rba, 6);
1798 tns_rowid_append(buf, part, 3);
1799 tns_rowid_append(buf, block, 6);
1800 tns_rowid_append(buf, slot, 3);
1801 return wmem_strbuf_get_str(buf);
1802}
1803
1804/* Render a universal rowid. A leading type byte of 1 marks a physical
1805 * rowid, printed as above; anything else is a logical one - an
1806 * index-organized table's, carrying its primary key - printed as "*" and
1807 * the base-64 of the bytes after the type byte, unpadded. Returns a
1808 * pinfo->pool string, or NULL. */
1809static const char *tns_format_urowid(packet_info *pinfo, const uint8_t *data, int len)
1810{
1811 if ( len >= 13 && data[0] == 1 )
1812 return tns_format_rowid(pinfo,
1813 ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 8) | data[4],
1814 ((uint32_t)data[5] << 8) | data[6],
1815 ((uint32_t)data[7] << 24) | ((uint32_t)data[8] << 16) | ((uint32_t)data[9] << 8) | data[10],
1816 ((uint32_t)data[11] << 8) | data[12]);
1817 if ( len < 2 )
1818 return NULL((void*)0);
1819
1820 wmem_strbuf_t *buf = wmem_strbuf_new(pinfo->pool, "*");
1821 for ( int i = 1; i < len; i += 3 )
1822 {
1823 int n = MIN(3, len - i)(((3) < (len - i)) ? (3) : (len - i));
1824 uint32_t group = (uint32_t)data[i] << 16;
1825 if ( n > 1 )
1826 group |= (uint32_t)data[i + 1] << 8;
1827 if ( n > 2 )
1828 group |= data[i + 2];
1829 /* n bytes give n + 1 characters */
1830 for ( int k = 0; k <= n; k++ )
1831 wmem_strbuf_append_c(buf, tns_rowid_alphabet[(group >> (18 - 6 * k)) & 0x3f]);
1832 }
1833 return wmem_strbuf_get_str(buf);
1834}
1835
1836static void vsnum_to_vstext_basecustom(char *result, uint32_t vsnum)
1837{
1838 /*
1839 * Translate hex value to human readable version value, described at
1840 * http://docs.oracle.com/cd/B28359_01/server.111/b28310/dba004.htm
1841 */
1842 snprintf(result, ITEM_LABEL_LENGTH240, "%d.%d.%d.%d.%d",
1843 vsnum >> 24,
1844 (vsnum >> 20) & 0xf,
1845 (vsnum >> 12) & 0xf,
1846 (vsnum >> 8) & 0xf,
1847 vsnum & 0xff);
1848}
1849
1850/* End-of-call status flags, carried by both TTI_OER and TTI_STA. */
1851#define TNS_CALL_STATUS_TXN_IN_PROGRESS0x00000002 0x00000002
1852#define TNS_CALL_STATUS_SESS_RELEASE0x00008000 0x00008000
1853
1854/* Break out the flag bits of a call status item. A client reads the
1855 * transaction bit to decide whether closing or releasing the connection
1856 * owes a rollback. */
1857static void tns_add_call_status_flags(proto_item *ti, tvbuff_t *tvb, int start, int len, uint32_t status)
1858{
1859 proto_tree *st = proto_item_add_subtree(ti, ett_tns_call_status);
1860 proto_tree_add_boolean(st, hf_tns_data_call_status_txn, tvb, start, len, status);
1861 proto_tree_add_boolean(st, hf_tns_data_call_status_sess_release, tvb, start, len, status);
1862}
1863
1864/* Decode an OAC (Oracle Access Column) descriptor — the type/format core
1865 * shared by describe columns and bind descriptors. Fields
1866 * use the Oracle variable-length form (get_sb4_custom). From field version
1867 * 12.2 the scale is a single signed byte, where 11g sends a variable-length
1868 * sb4 (NUMBER's default -127 as 0x81 0x7f), and a ub4 oaccolid follows the
1869 * max size.
1870 * When col is not NULL it receives the type and data length.
1871 * Returns the new offset. */
1872static int dissect_tns_oac(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, tns_column_t *col)
1873{
1874 int v = 0, start;
1875 uint64_t u = 0;
1876 bool_Bool fv_12_2 = tns_field_version(pinfo) >= TNS_FV_12_28;
1877
1878 if ( col )
1879 col->type = tvb_get_uint8(tvb, offset);
1880 /* type (ub1) */
1881 proto_tree_add_item(tree, hf_tns_data_col_type, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1882 offset += 1;
1883 /* flag (ub1, skip) */
1884 offset += 1;
1885 /* precision (sb1) */
1886 proto_tree_add_item(tree, hf_tns_data_col_precision, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1887 offset += 1;
1888 /* scale (may be negative — NUMBER default is -127) */
1889 start = offset;
1890 if ( fv_12_2 )
1891 {
1892 v = (int8_t)tvb_get_uint8(tvb, offset);
1893 offset += 1;
1894 }
1895 else
1896 offset += get_sb4_custom(tvb, offset, &v);
1897 proto_tree_add_int(tree, hf_tns_data_col_scale, tvb, start, offset - start, v);
1898 /* max data length / buffer size (ub4) */
1899 start = offset;
1900 offset += get_sb4_custom(tvb, offset, &v);
1901 proto_tree_add_uint(tree, hf_tns_data_col_max_length, tvb, start, offset - start, v);
1902 if ( col )
1903 col->data_len = (uint32_t)v;
1904 /* max array elements (ub4, skip) */
1905 offset += get_sb4_custom(tvb, offset, &v);
1906 /* cont flags (ub8, skip) */
1907 offset += get_ub8_custom(tvb, offset, &u);
1908 /* type OID (bytes_with_length, skip) */
1909 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
1910 /* version (ub4, skip) */
1911 offset += get_sb4_custom(tvb, offset, &v);
1912 /* charset id (ub4) */
1913 start = offset;
1914 offset += get_sb4_custom(tvb, offset, &v);
1915 proto_tree_add_uint(tree, hf_tns_data_col_charset, tvb, start, offset - start, v);
1916 /* charset form (ub1) */
1917 proto_tree_add_item(tree, hf_tns_data_col_csform, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1918 if ( col )
1919 col->csform = tvb_get_uint8(tvb, offset);
1920 offset += 1;
1921 /* max size (ub4) */
1922 start = offset;
1923 offset += get_sb4_custom(tvb, offset, &v);
1924 proto_tree_add_uint(tree, hf_tns_data_col_max_size, tvb, start, offset - start, v);
1925 /* oaccolid (ub4, skip) */
1926 if ( fv_12_2 )
1927 offset += get_sb4_custom(tvb, offset, &v);
1928
1929 return offset;
1930}
1931
1932/* Decode one per-column metadata block of a TTI_DCB describe (11g
1933 * shape): an OAC descriptor plus the nullability and naming fields.
1934 * When col is not NULL it receives what a row decoder needs.
1935 * Returns the new offset. */
1936static int dissect_tns_dcb_column(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int idx, tns_column_t *col)
1937{
1938 unsigned fv = tns_field_version(pinfo);
1939 int start;
1940 proto_tree *col_tree;
1941 proto_item *col_item;
1942 int col_start = offset, v = 0;
1943 uint8_t col_type = tvb_get_uint8(tvb, offset);
1944 const char *name = NULL((void*)0);
1945
1946 col_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
1947 ett_tns_dcb_col, &col_item, "Column %d", idx);
1948
1949 offset = dissect_tns_oac(tvb, pinfo, col_tree, offset, col);
1950
1951 /* nulls allowed (ub1) */
1952 proto_tree_add_item(col_tree, hf_tns_data_col_nulls_ok, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
1953 offset += 1;
1954 /* v7 name length (ub1, skip) */
1955 offset += 1;
1956 /* column name (str_with_length) */
1957 int name_start = offset;
1958 offset += get_field_with_length(tvb, pinfo, offset, &name);
1959 if ( name )
1960 proto_tree_add_string(col_tree, hf_tns_data_col_name, tvb, name_start, offset - name_start, name);
1961 /* schema name, type name (str_with_length, skip) */
1962 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
1963 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
1964 /* column position (ub4, skip) */
1965 offset += get_sb4_custom(tvb, offset, &v);
1966 /* uds flags (ub4) — an 11g addition; it marks a JSON column */
1967 if ( !tns_before_11g(pinfo) )
1968 {
1969 start = offset;
1970 offset += get_sb4_custom(tvb, offset, &v);
1971 proto_tree_add_uint(col_tree, hf_tns_data_col_uds_flags, tvb, start, offset - start, v);
1972 }
1973 /* 23ai: the column's SQL domain, its annotations, and a vector
1974 * column's dimensions and format */
1975 if ( fv >= TNS_FV_23_117 )
1976 {
1977 const char *str = NULL((void*)0);
1978 start = offset;
1979 offset += get_field_with_length(tvb, pinfo, offset, &str);
1980 if ( str )
1981 proto_tree_add_string(col_tree, hf_tns_data_col_domain_schema, tvb, start, offset - start, str);
1982 start = offset;
1983 offset += get_field_with_length(tvb, pinfo, offset, &str);
1984 if ( str )
1985 proto_tree_add_string(col_tree, hf_tns_data_col_domain_name, tvb, start, offset - start, str);
1986 }
1987 if ( fv >= TNS_FV_23_1_EXT_320 )
1988 {
1989 int num = 0;
1990 offset += get_sb4_custom(tvb, offset, &num);
1991 if ( num > 0 )
1992 {
1993 offset += 1;
1994 offset += get_sb4_custom(tvb, offset, &num);
1995 offset += 1;
1996 for ( int i = 0; i < num && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
1997 {
1998 const char *key = NULL((void*)0), *value = NULL((void*)0);
1999 start = offset;
2000 offset += get_field_with_length(tvb, pinfo, offset, &key);
2001 offset += get_field_with_length(tvb, pinfo, offset, &value);
2002 proto_tree_add_string_format_value(col_tree, hf_tns_data_col_annotation, tvb,
2003 start, offset - start, key ? key : "", "%s = %s",
2004 key ? key : "", value ? value : "");
2005 offset += get_sb4_custom(tvb, offset, &v); /* flags */
2006 }
2007 offset += get_sb4_custom(tvb, offset, &v); /* flags */
2008 }
2009 }
2010 if ( fv >= TNS_FV_23_424 )
2011 {
2012 start = offset;
2013 offset += get_sb4_custom(tvb, offset, &v);
2014 proto_tree_add_uint(col_tree, hf_tns_data_col_vector_dims, tvb, start, offset - start, v);
2015 proto_tree_add_item(col_tree, hf_tns_data_col_vector_format, tvb, offset, 1, ENC_NA0x00000000);
2016 offset += 1;
2017 offset += 1; /* vector flags */
2018 }
2019
2020 if ( name )
2021 proto_item_append_text(col_item, ": %s (%s)", name,
2022 val_to_str_const(col_type, tns_data_types, "unknown"));
2023 proto_item_set_len(col_item, offset - col_start);
2024 return offset;
2025}
2026
2027/* Decode a describe body - the column metadata of a result set - as a
2028 * TTI_DCB carries it after its preamble: a ub4 max row size, a ub4 column
2029 * count, a reserved byte when there are columns, the columns, and a
2030 * trailer. When out is not NULL it receives the columns, allocated in
2031 * file scope. Returns the new offset. */
2032static int dissect_tns_describe_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, tns_describe_t **out)
2033{
2034 int v = 0, num_cols = 0, nc_start;
2035 tns_column_t *cols = NULL((void*)0);
2036
2037 /* max row size (ub4, skip) */
2038 offset += get_sb4_custom(tvb, offset, &v);
2039 /* number of columns */
2040 nc_start = offset;
2041 offset += get_sb4_custom(tvb, offset, &num_cols);
2042 proto_tree_add_uint(tree, hf_tns_data_dcb_num_columns, tvb, nc_start, offset - nc_start, num_cols);
2043 /* The count comes off the wire and sizes the allocation below, so a
2044 * count larger than the data left cannot be real - report it and
2045 * decode no columns. */
2046 if ( num_cols < 0 ||
2047 (unsigned)num_cols > tvb_reported_length_remaining(tvb, offset) )
2048 {
2049 proto_tree_add_expert(tree, pinfo, &ei_tns_data_count_too_large,
2050 tvb, nc_start, offset - nc_start);
2051 num_cols = 0;
2052 }
2053 if ( num_cols > 0 )
2054 offset += 1; /* reserved byte */
2055
2056 if ( out && num_cols > 0 )
2057 cols = wmem_alloc0_array(wmem_file_scope(), tns_column_t, num_cols)((tns_column_t*)wmem_alloc0((wmem_file_scope()), (((((num_cols
)) <= 0) || ((size_t)sizeof(tns_column_t) > (9223372036854775807L
/ (size_t)((num_cols))))) ? 0 : (sizeof(tns_column_t) * ((num_cols
))))))
;
2058 for ( int i = 0; i < num_cols && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
2059 offset = dissect_tns_dcb_column(tvb, pinfo, tree, offset, i + 1,
2060 cols ? &cols[i] : NULL((void*)0));
2061 if ( cols )
2062 {
2063 tns_describe_t *desc = wmem_new0(wmem_file_scope(), tns_describe_t)((tns_describe_t*)wmem_alloc0((wmem_file_scope()), sizeof(tns_describe_t
)))
;
2064 desc->num_cols = num_cols;
2065 desc->cols = cols;
2066 *out = desc;
2067 }
2068
2069 /* Trailer: current date (bytes_with_length), four ub4 flags,
2070 * and the query-cache key (bytes_with_length) — all skipped. The key
2071 * came with the 11g result cache: a 10g describe ends after the
2072 * flags. */
2073 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
2074 for ( int i = 0; i < 4; i++ )
2075 offset += get_sb4_custom(tvb, offset, &v);
2076 if ( !tns_before_11g(pinfo) )
2077 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
2078 return offset;
2079}
2080
2081/* Decode one row/bind value by its data type, and add it as a
2082 * "<prefix> N (TYPE)" item under `hf`. Ordinary values are a
2083 * DALC blob; ROWID / UROWID / LONG / LOB / JSON / VECTOR / object carry
2084 * their own framings. Returns the new offset. */
2085static int dissect_tns_value(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint8_t dtype, uint8_t csform, int idx, int hf, const char *prefix)
2086{
2087 int v_start = offset, disp_start = offset, v = 0;
2088 int is_null = 0, is_absent = 0;
2089 uint8_t first;
2090 const char *rendered = NULL((void*)0);
2091 /* LOB metadata: size and chunk size, with where they sit */
2092 bool_Bool lob_meta = false0;
2093 uint64_t lob_size = 0;
2094 int lob_chunk = 0, size_start = 0, size_len = 0, lchunk_start = 0, lchunk_len = 0;
2095 int image_start = 0, image_len = 0, obj_toid_start = 0, obj_toid_len = 0;
2096 proto_item *ti;
2097
2098 switch ( dtype )
2099 {
2100 case TNS_DATATYPE_REFCURSOR102:
2101 {
2102 /* A cursor - a CURSOR(...) column, or a REF CURSOR OUT
2103 * bind: a ub1 length (a fixed value, ignored), the describe
2104 * of the cursor's result set inline, and the ub2 id the
2105 * client drains it with. The value's length is known only
2106 * once the describe is read, so read it once to size the
2107 * item and again to show it. */
2108 proto_item *ci;
2109 proto_tree *ct;
2110 int end, cursor = 0, start;
2111
2112 end = dissect_tns_describe_body(tvb, pinfo, NULL((void*)0), offset + 1, NULL((void*)0));
2113 end += get_sb4_custom(tvb, end, &cursor);
2114 ci = proto_tree_add_bytes_format(tree, hf, tvb, offset, end - offset, NULL((void*)0),
2115 "%s %d (%s): cursor %d", prefix, idx,
2116 val_to_str_const(dtype, tns_data_types, "unknown"), cursor);
2117 ct = proto_item_add_subtree(ci, ett_tns_value);
2118 offset = dissect_tns_describe_body(tvb, pinfo, ct, offset + 1, NULL((void*)0));
2119 start = offset;
2120 offset += get_sb4_custom(tvb, offset, &cursor);
2121 proto_tree_add_uint(ct, hf_tns_cursor, tvb, start, offset - start, cursor);
2122 return offset;
2123 }
2124
2125 case TNS_DATATYPE_ADT109:
2126 {
2127 /* An object - or an XMLType, which is an ADT by describe - is
2128 * framed the same way whether it is NULL or not:
2129 * bytes_with_length type OID | bytes_with_length OID |
2130 * bytes_with_length snapshot | ub2 version |
2131 * ub4 image length | ub2 flags | [DALC image]
2132 * A NULL object has an image length of 0 and no image. */
2133 int toid_start = offset, img_len = 0;
2134 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
2135 obj_toid_start = toid_start;
2136 obj_toid_len = offset - toid_start;
2137 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0)); /* OID */
2138 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0)); /* snapshot */
2139 offset += get_sb4_custom(tvb, offset, &v); /* version */
2140 offset += get_sb4_custom(tvb, offset, &img_len);
2141 offset += get_sb4_custom(tvb, offset, &v); /* flags */
2142 if ( img_len > 0 )
2143 {
2144 image_start = offset;
2145 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
2146 image_len = offset - image_start;
2147 rendered = wmem_strdup_printf(pinfo->pool, "object, %d-byte image", img_len);
2148 }
2149 else
2150 rendered = "NULL object";
2151 break;
2152 }
2153
2154 case TNS_DATATYPE_JSON119: /* OSON */
2155 case TNS_DATATYPE_VECTOR127:
2156 /* LOB-class, but the value itself rides in the row: the LOB
2157 * metadata framing with the image spliced in ahead of the
2158 * locator,
2159 * ub4 locator length | ub8 image size | ub4 chunk size |
2160 * DALC image | DALC locator
2161 * The locator is a placeholder. A 0x00 is NULL. A server may
2162 * instead send a bare locator, as for a CLOB, and leave the
2163 * image to a LOB read; that is told apart as for a CLOB. */
2164 first = tvb_get_uint8(tvb, offset);
2165 if ( first == 0 )
2166 {
2167 offset += 1;
2168 is_null = 1;
2169 break;
2170 }
2171 offset += get_sb4_custom(tvb, offset, &v);
2172 if ( v > 8 && tvb_get_uint8(tvb, offset) == v )
2173 {
2174 /* bare locator */
2175 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
2176 rendered = "locator only";
2177 break;
2178 }
2179 lob_meta = true1;
2180 size_start = offset;
2181 offset += get_ub8_custom(tvb, offset, &lob_size);
2182 size_len = offset - size_start;
2183 lchunk_start = offset;
2184 offset += get_sb4_custom(tvb, offset, &lob_chunk);
2185 lchunk_len = offset - lchunk_start;
2186 image_start = offset;
2187 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
2188 image_len = offset - image_start;
2189 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
2190 rendered = wmem_strdup_printf(pinfo->pool, "%s image, %" PRIu64"l" "u" " bytes",
2191 dtype == TNS_DATATYPE_JSON119 ? "OSON" : "vector", lob_size);
2192 break;
2193
2194 case TNS_DATATYPE_ROWID11:
2195 {
2196 /* a present indicator (0 / 0xff = NULL), then the object id
2197 * (ub4), file number (ub2), an unused byte, block number
2198 * (ub4) and slot number (ub2) */
2199 int rba = 0, part = 0, block = 0, slot = 0;
2200 first = tvb_get_uint8(tvb, offset);
2201 offset += 1;
2202 if ( first == 0 || first == 0xff )
2203 {
2204 is_null = 1;
2205 break;
2206 }
2207 offset += get_sb4_custom(tvb, offset, &rba);
2208 offset += get_sb4_custom(tvb, offset, &part);
2209 offset += 1;
2210 offset += get_sb4_custom(tvb, offset, &block);
2211 offset += get_sb4_custom(tvb, offset, &slot);
2212 rendered = tns_format_rowid(pinfo, (uint32_t)rba, (uint32_t)part, (uint32_t)block, (uint32_t)slot);
2213 break;
2214 }
2215
2216 case TNS_DATATYPE_UROWID208: /* ub4 num_bytes, a length echo byte, then the bytes */
2217 offset += get_sb4_custom(tvb, offset, &v);
2218 if ( v > 0 )
2219 {
2220 offset += 1;
2221 rendered = tns_format_urowid(pinfo, tvb_get_ptr(tvb, offset, v), v);
2222 offset += v;
2223 }
2224 else
2225 is_null = 1;
2226 break;
2227
2228 case TNS_DATATYPE_LONG8:
2229 case TNS_DATATYPE_LONG_RAW24: /* value then two trailing ub4 length indicators */
2230 first = tvb_get_uint8(tvb, offset);
2231 if ( first == 0 )
2232 {
2233 offset += 1;
2234 is_null = 1;
2235 }
2236 else if ( first == 0xfe ) /* chunked */
2237 offset += 1 + tns_chunks_len(tvb, pinfo, offset + 1, NULL((void*)0));
2238 else
2239 offset += 1 + first;
2240 offset += get_sb4_custom(tvb, offset, &v);
2241 offset += get_sb4_custom(tvb, offset, &v);
2242 break;
2243
2244 case TNS_DATATYPE_CLOB112:
2245 case TNS_DATATYPE_BLOB113:
2246 case TNS_DATATYPE_BFILE114:
2247 /* 0x00 NULL, else a ub4 locator length and the locator. A
2248 * server sends CLOB / BLOB in one of two forms: with the LOB's
2249 * size (ub8) and chunk size (ub4) between the two, or bare -
2250 * and which one it picks for a client is not known. They are
2251 * told apart by the byte after the length: the bare form's is
2252 * the locator's own length prefix (or 0xFE when chunked), the
2253 * metadata form's is the size's width, at most 8. A real
2254 * locator is far longer than 8 bytes, so the two cannot meet.
2255 * A BFILE is always bare. */
2256 first = tvb_get_uint8(tvb, offset);
2257 if ( first == 0 )
2258 {
2259 offset += 1;
2260 is_null = 1;
2261 }
2262 else
2263 {
2264 offset += get_sb4_custom(tvb, offset, &v);
2265 if ( dtype != TNS_DATATYPE_BFILE114 && v > 8 )
2266 {
2267 uint8_t next = tvb_get_uint8(tvb, offset);
2268 if ( next <= 8 && next != v )
2269 {
2270 lob_meta = true1;
2271 size_start = offset;
2272 offset += get_ub8_custom(tvb, offset, &lob_size);
2273 size_len = offset - size_start;
2274 lchunk_start = offset;
2275 offset += get_sb4_custom(tvb, offset, &lob_chunk);
2276 lchunk_len = offset - lchunk_start;
2277 rendered = wmem_strdup_printf(pinfo->pool, "locator, size %" PRIu64"l" "u", lob_size);
2278 }
2279 }
2280 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
2281 }
2282 break;
2283
2284 default: /* ordinary: a single DALC value */
2285 first = tvb_get_uint8(tvb, offset);
2286 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
2287 if ( first == 0 )
2288 is_null = 1;
2289 else if ( first == TNS_DALC_ABSENT0xFD )
2290 is_absent = 1;
2291 else
2292 {
2293 disp_start = v_start + 1; /* show the value bytes, not the length */
2294 /* Render common scalar types (never chunked): NUMBER as
2295 * decimal, DATE / TIMESTAMP / TIMESTAMP LTZ as a datetime. */
2296 if ( first != 254 && offset > disp_start )
2297 {
2298 const uint8_t *vb = tvb_get_ptr(tvb, disp_start, offset - disp_start);
2299 int vlen = offset - disp_start;
2300 /* A BINARY_INTEGER carries NUMBER bytes, not a native
2301 * integer. */
2302 if ( dtype == TNS_DATATYPE_NUMBER2 || dtype == TNS_DATATYPE_INTEGER3 )
2303 rendered = tns_format_number(pinfo, vb, vlen);
2304 else if ( dtype == TNS_DATATYPE_DATE12 || dtype == TNS_DATATYPE_TIMESTAMP180 || dtype == TNS_DATATYPE_TIMESTAMP_LTZ231 )
2305 rendered = tns_format_date(pinfo, vb, vlen);
2306 else if ( dtype == TNS_DATATYPE_TIMESTAMP_TZ181 )
2307 rendered = tns_format_timestamp_tz(pinfo, vb, vlen);
2308 else if ( (dtype == TNS_DATATYPE_INTERVAL_YM182 || dtype == TNS_DATATYPE_INTERVAL_DS183) && vlen >= 5 )
2309 rendered = tns_format_interval(pinfo, dtype, vb, vlen);
2310 else if ( dtype == TNS_DATATYPE_BOOLEAN252 )
2311 /* an encoded integer: 00 false, 01 01 true */
2312 rendered = vb[0] == 1 ? "TRUE" : "FALSE";
2313 else if ( dtype == TNS_DATATYPE_BINARY_FLOAT100 || dtype == TNS_DATATYPE_BINARY_DOUBLE101 )
2314 rendered = tns_format_binary_float(pinfo, vb, vlen);
2315 else if ( dtype == TNS_DATATYPE_VARCHAR1 || dtype == TNS_DATATYPE_STRING5 || dtype == TNS_DATATYPE_CHAR96 )
2316 /* VARCHAR / STRING / CHAR: character data, in the
2317 * session charset (ordinarily UTF-8), or UTF-16BE
2318 * for the national charset form (NCHAR,
2319 * NVARCHAR2) - in a column and an OUT bind alike. */
2320 rendered = (const char *)tvb_get_string_enc(pinfo->pool,
2321 tvb, disp_start, vlen,
2322 csform == TNS_CSFORM_NCHAR2 ? ENC_UTF_160x00000004|ENC_BIG_ENDIAN0x00000000 : ENC_UTF_80x00000002|ENC_NA0x00000000);
2323 }
2324 }
2325 break;
2326 }
2327
2328 if ( is_null )
2329 proto_tree_add_bytes_format(tree, hf, tvb,
2330 v_start, offset - v_start, NULL((void*)0), "%s %d (%s): NULL", prefix, idx,
2331 val_to_str_const(dtype, tns_data_types, "unknown"));
2332 else if ( is_absent )
2333 proto_tree_add_bytes_format(tree, hf, tvb,
2334 v_start, offset - v_start, NULL((void*)0), "%s %d (%s): no value", prefix, idx,
2335 val_to_str_const(dtype, tns_data_types, "unknown"));
2336 else if ( rendered )
2337 {
2338 ti = proto_tree_add_bytes_format(tree, hf, tvb,
2339 disp_start, offset - disp_start, NULL((void*)0), "%s %d (%s): %s", prefix, idx,
2340 val_to_str_const(dtype, tns_data_types, "unknown"), rendered);
2341 if ( dtype == TNS_DATATYPE_ADT109 )
2342 {
2343 proto_tree *vt = proto_item_add_subtree(ti, ett_tns_value);
2344 /* the type OID, without its ub4 count and DALC length */
2345 if ( obj_toid_len > 2 )
2346 {
2347 int w = 1 + (tvb_get_uint8(tvb, obj_toid_start) & 0x7f);
2348 proto_tree_add_item(vt, hf_tns_data_obj_toid, tvb,
2349 obj_toid_start + w + 1, obj_toid_len - w - 1, ENC_NA0x00000000);
2350 }
2351 if ( image_len > 1 )
2352 {
2353 bool_Bool chunked = tvb_get_uint8(tvb, image_start) == 0xfe;
2354 proto_tree_add_item(vt, hf_tns_data_obj_image, tvb,
2355 chunked ? image_start : image_start + 1, chunked ? image_len : image_len - 1, ENC_NA0x00000000);
2356 }
2357 }
2358 if ( lob_meta )
2359 {
2360 proto_tree *vt = proto_item_add_subtree(ti, ett_tns_value);
2361 proto_tree_add_uint64(vt, hf_tns_data_lob_size, tvb, size_start, size_len, lob_size);
2362 proto_tree_add_uint(vt, hf_tns_data_lob_chunk_size, tvb, lchunk_start, lchunk_len, lob_chunk);
2363 /* the image of a prefetched JSON / VECTOR value, without its
2364 * DALC length byte (chunked images are shown whole) */
2365 if ( image_len > 1 )
2366 {
2367 bool_Bool chunked = tvb_get_uint8(tvb, image_start) == 0xfe;
2368 proto_tree_add_item(vt, dtype == TNS_DATATYPE_JSON119 ? hf_tns_data_json_image : hf_tns_data_vector_image,
2369 tvb, chunked ? image_start : image_start + 1, chunked ? image_len : image_len - 1, ENC_NA0x00000000);
2370 }
2371 }
2372 }
2373 else
2374 proto_tree_add_bytes_format(tree, hf, tvb,
2375 disp_start, offset - disp_start, NULL((void*)0), "%s %d (%s)", prefix, idx,
2376 val_to_str_const(dtype, tns_data_types, "unknown"));
2377 return offset;
2378}
2379
2380/* The describe a row-data message is split by: the conversation's most
2381 * recent one, stored per packet on the first pass so a later pass uses
2382 * the same. */
2383static tns_describe_t *tns_current_describe(packet_info *pinfo)
2384{
2385 tns_describe_t *desc;
2386
2387 if ( PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
2388 return (tns_describe_t *)p_get_proto_data(wmem_file_scope(), pinfo,
2389 proto_tns, TNS_PROTO_DATA_DESCRIBE1);
2390
2391 desc = tns_get_conv_info(pinfo)->last_describe;
2392 if ( desc && !p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_DESCRIBE1) )
2393 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns,
2394 TNS_PROTO_DATA_DESCRIBE1, desc);
2395 return desc;
2396}
2397
2398/* Count the RETURNING ... INTO binds of a statement: the placeholders
2399 * after INTO, in a DML statement that has RETURNING ... INTO. Each
2400 * placeholder is a bind of its own, and those after INTO come last. A
2401 * PL/SQL block is never this form - a RETURNING INTO inside one is its
2402 * own PL/SQL, and its target an ordinary OUT bind. String literals and
2403 * comments are skipped. */
2404static unsigned tns_count_return_binds(const char *sql)
2405{
2406 const char *p = sql;
2407 bool_Bool first_word = true1, returning = false0, into = false0;
2408 unsigned n = 0;
2409
2410 while ( *p )
2411 {
2412 if ( *p == '\'' )
2413 {
2414 for ( p++; *p && *p != '\''; p++ )
2415 ;
2416 if ( *p )
2417 p++;
2418 }
2419 else if ( p[0] == '-' && p[1] == '-' )
2420 {
2421 while ( *p && *p != '\n' )
2422 p++;
2423 }
2424 else if ( p[0] == '/' && p[1] == '*' )
2425 {
2426 const char *end = strstr(p + 2, "*/");
2427 p = end ? end + 2 : p + strlen(p);
2428 }
2429 else if ( g_ascii_isalpha(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_ALPHA) != 0) )
2430 {
2431 const char *w = p;
2432 size_t len;
2433 while ( g_ascii_isalnum(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_ALNUM) != 0) || *p == '_' || *p == '$' || *p == '#' )
2434 p++;
2435 len = p - w;
2436 if ( first_word )
2437 {
2438 first_word = false0;
2439 if ( !((len == 6 && (g_ascii_strncasecmp(w, "INSERT", 6) == 0
2440 || g_ascii_strncasecmp(w, "UPDATE", 6) == 0
2441 || g_ascii_strncasecmp(w, "DELETE", 6) == 0))
2442 || (len == 5 && g_ascii_strncasecmp(w, "MERGE", 5) == 0)) )
2443 return 0;
2444 }
2445 else if ( !returning && len == 9 && g_ascii_strncasecmp(w, "RETURNING", 9) == 0 )
2446 returning = true1;
2447 else if ( returning && !into && len == 4 && g_ascii_strncasecmp(w, "INTO", 4) == 0 )
2448 into = true1;
2449 }
2450 else if ( *p == ':' && into && (g_ascii_isalnum(p[1])((g_ascii_table[(guchar) (p[1])] & G_ASCII_ALNUM) != 0) || p[1] == '_' || p[1] == '"') )
2451 {
2452 n++;
2453 for ( p++; g_ascii_isalnum(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_ALNUM) != 0) || *p == '_' || *p == '"'; p++ )
2454 ;
2455 }
2456 else
2457 p++;
2458 }
2459 return n;
2460}
2461
2462/* Look up the bind types remembered for a cursor, for an execute that
2463 * sends its values without descriptors. Stashed per packet on the first
2464 * pass, so a later pass gets the same answer. */
2465static tns_binds_t *tns_lookup_cursor_binds(packet_info *pinfo, uint32_t cursor)
2466{
2467 if ( PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
2468 return (tns_binds_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_BINDS2);
2469
2470 tns_conv_info_t *tns_info = tns_get_conv_info(pinfo);
2471 tns_binds_t *binds = (tns_binds_t *)wmem_map_lookup(tns_info->cursor_binds, GUINT_TO_POINTER(cursor)((gpointer) (gulong) (cursor)));
2472 if ( binds )
2473 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_BINDS2, binds);
2474 return binds;
2475}
2476
2477/* Decode the TTI_RXD value rows of a bind section - one row per
2478 * execution - with each value typed by cols[]. A CLOB / BLOB bind
2479 * carries a temp-LOB locator form not unpacked here, so rows with one are
2480 * left alone. Returns the new offset. */
2481static int dissect_tns_bind_rows(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, const tns_column_t *cols, uint32_t count)
2482{
2483 int rownum = 0;
2484
2485 for ( uint32_t i = 0; i < count; i++ )
2486 if ( cols[i].type == TNS_DATATYPE_CLOB112 || cols[i].type == TNS_DATATYPE_BLOB113 )
2487 return offset;
2488
2489 while ( tvb_reported_length_remaining(tvb, offset) > 0
2490 && tvb_get_uint8(tvb, offset) == SQLNET_ROW_TRANSF_DATA7 )
2491 {
2492 proto_tree *row_tree;
2493 proto_item *row_item;
2494 int r_start = offset;
2495
2496 offset += 1; /* TTI_RXD token */
2497 row_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1,
2498 ett_tns_bind_row, &row_item, "Row %d", ++rownum);
2499 for ( uint32_t i = 0; i < count
2500 && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
2501 offset = dissect_tns_value(tvb, pinfo, row_tree, offset,
2502 cols[i].type, cols[i].csform, i + 1, hf_tns_data_bind_value, "Bind");
2503 proto_item_set_len(row_item, offset - r_start);
2504 }
2505 return offset;
2506}
2507
2508/* Remember the call a request makes, so the response can be read in its
2509 * light. Returns the record to fill in, or NULL on a later pass. */
2510static tns_call_t *tns_remember_call(packet_info *pinfo, uint8_t func)
2511{
2512 if ( PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
2513 return NULL((void*)0);
2514
2515 tns_call_t *call = wmem_new0(wmem_file_scope(), tns_call_t)((tns_call_t*)wmem_alloc0((wmem_file_scope()), sizeof(tns_call_t
)))
;
2516 call->func = func;
2517 tns_get_conv_info(pinfo)->last_call = call;
2518 return call;
2519}
2520
2521/* The call a response packet answers, or NULL if none was seen. */
2522static tns_call_t *tns_answered_call(packet_info *pinfo)
2523{
2524 if ( PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
2525 return (tns_call_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_CALL3);
2526
2527 tns_call_t *call = tns_get_conv_info(pinfo)->last_call;
2528 if ( call )
2529 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_CALL3, call);
2530 return call;
2531}
2532
2533/* Decode num key/value pairs: each a ub2 text length and text, a ub2
2534 * binary length and bytes, and a ub2 keyword number saying which session
2535 * attribute the value is for. Returns the new offset. */
2536static int dissect_tns_kv_pairs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int num)
2537{
2538 for ( int i = 0; i < num && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
2539 {
2540 proto_tree *kv_tree;
2541 proto_item *kv_item;
2542 const char *text = NULL((void*)0);
2543 int kv_start = offset, len = 0, keyword = 0, start;
2544
2545 kv_tree = proto_tree_add_subtree_format(tree, tvb, offset, -1, ett_tns_kv,
2546 &kv_item, "Key/Value Pair %d", i + 1);
2547 offset += get_sb4_custom(tvb, offset, &len);
2548 if ( len > 0 )
2549 {
2550 start = offset;
2551 offset += get_dalc_custom(tvb, pinfo, offset, &text);
2552 proto_tree_add_string(kv_tree, hf_tns_data_kv_text, tvb, start, offset - start, text);
2553 }
2554 offset += get_sb4_custom(tvb, offset, &len);
2555 if ( len > 0 )
2556 {
2557 start = offset;
2558 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
2559 proto_tree_add_item(kv_tree, hf_tns_data_kv_binary, tvb, start + 1, offset - start - 1, ENC_NA0x00000000);
2560 }
2561 start = offset;
2562 offset += get_sb4_custom(tvb, offset, &keyword);
2563 proto_tree_add_uint(kv_tree, hf_tns_data_kv_keyword, tvb, start, offset - start, keyword);
2564 proto_item_append_text(kv_item, ": %s", val_to_str(pinfo->pool, keyword, tns_kv_keywords, "keyword %u"));
2565 if ( text )
2566 proto_item_append_text(kv_item, " = %s", text);
2567 proto_item_set_len(kv_item, offset - kv_start);
2568 }
2569 return offset;
2570}
2571
2572/* Decode the return-parameters block (TTI_RPA) that answers an execute,
2573 * ahead of its closing status. With DML_ROWCOUNTS requested it ends with
2574 * the rows each iteration of an array DML affected. Returns the new
2575 * offset. */
2576static int dissect_tns_return_params(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, bool_Bool rowcounts)
2577{
2578 proto_tree *rpa_tree;
2579 proto_item *rpa_item;
2580 int rpa_start = offset, num = 0, len = 0, start;
2581
2582 rpa_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_tns_rpa, &rpa_item, "Return Parameters");
2583
2584 /* al8o4l: a count of ub4 words */
2585 start = offset;
2586 offset += get_sb4_custom(tvb, offset, &num);
2587 proto_tree_add_uint(rpa_tree, hf_tns_data_rpa_num_al8o4, tvb, start, offset - start, num);
2588 for ( int i = 0; i < num && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
2589 {
2590 int v = 0;
2591 start = offset;
2592 offset += get_sb4_custom(tvb, offset, &v);
2593 proto_tree_add_uint(rpa_tree, hf_tns_data_rpa_al8o4, tvb, start, offset - start, v);
2594 }
2595 /* al8txl: a byte count and the bytes */
2596 offset += get_sb4_custom(tvb, offset, &len);
2597 if ( len > 0 )
2598 {
2599 proto_tree_add_item(rpa_tree, hf_tns_data_rpa_al8txl, tvb, offset, len, ENC_NA0x00000000);
2600 offset += len;
2601 }
2602 /* key/value pairs: a changed session attribute is reported here */
2603 start = offset;
2604 offset += get_sb4_custom(tvb, offset, &num);
2605 proto_tree_add_uint(rpa_tree, hf_tns_data_rpa_num_kv, tvb, start, offset - start, num);
2606 offset = dissect_tns_kv_pairs(tvb, pinfo, rpa_tree, offset, num);
2607 /* registration: a byte count and the bytes */
2608 offset += get_sb4_custom(tvb, offset, &len);
2609 if ( len > 0 )
2610 {
2611 proto_tree_add_item(rpa_tree, hf_tns_data_rpa_registration, tvb, offset, len, ENC_NA0x00000000);
2612 offset += len;
2613 }
2614 /* per-iteration row counts, when the execute asked for them */
2615 if ( rowcounts )
2616 {
2617 start = offset;
2618 offset += get_sb4_custom(tvb, offset, &num);
2619 proto_tree_add_uint(rpa_tree, hf_tns_data_rpa_num_rowcounts, tvb, start, offset - start, num);
2620 for ( int i = 0; i < num && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
2621 {
2622 uint64_t rows = 0;
2623 start = offset;
2624 offset += get_ub8_custom(tvb, offset, &rows);
2625 proto_tree_add_uint64(rpa_tree, hf_tns_data_rpa_dml_rowcount, tvb, start, offset - start, rows);
2626 }
2627 }
2628 proto_item_set_len(rpa_item, offset - rpa_start);
2629 return offset;
2630}
2631
2632/* From field version 23.1 ext 1 a call or piggyback header carries a ub8
2633 * token after its sequence number, which the reply echoes in a TOKEN
2634 * message. Returns the new offset. */
2635static int dissect_tns_call_token(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
2636{
2637 uint64_t token = 0;
2638 int start = offset;
2639
2640 if ( tns_field_version(pinfo) < TNS_FV_23_1_EXT_118 )
2641 return offset;
2642 offset += get_ub8_custom(tvb, offset, &token);
2643 proto_tree_add_uint64(tree, hf_tns_data_token, tvb, start, offset - start, token);
2644 return offset;
2645}
2646
2647/* Decode a two-phase commit call: a transaction switch (103) - start,
2648 * detach - or a state change (104) - prepare, commit, abort, forget. The
2649 * header gives an operation, the lengths of a transaction context and of
2650 * the XID's parts, and for a switch the names; the context, the XID and
2651 * the rest follow. The XID is padded to 128 bytes. Returns the new
2652 * offset. */
2653static int dissect_tns_tpc_call(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint32_t func)
2654{
2655 int v = 0, ctx_len = 0, gtrid_len = 0, bqual_len = 0, xid_len = 0;
2656 int int_len = 0, ext_len = 0, start;
2657 uint8_t ctx_ptr, xid_ptr, int_ptr = 0, ext_ptr = 0;
2658
2659 start = offset;
2660 offset += get_sb4_custom(tvb, offset, &v);
2661 proto_tree_add_uint(tree, func == TTI_TPC_TXN_SWITCH103 ? hf_tns_data_tpc_switch_op : hf_tns_data_tpc_change_op,
2662 tvb, start, offset - start, v);
2663 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", val_to_str_const(v,
2664 func == TTI_TPC_TXN_SWITCH103 ? tns_tpc_switch_ops : tns_tpc_change_ops, "unknown"));
2665 ctx_ptr = tvb_get_uint8(tvb, offset);
2666 offset += 1;
2667 offset += get_sb4_custom(tvb, offset, &ctx_len);
2668 start = offset;
2669 offset += get_sb4_custom(tvb, offset, &v);
2670 proto_tree_add_uint(tree, hf_tns_data_tpc_format_id, tvb, start, offset - start, v);
2671 offset += get_sb4_custom(tvb, offset, &gtrid_len);
2672 offset += get_sb4_custom(tvb, offset, &bqual_len);
2673 xid_ptr = tvb_get_uint8(tvb, offset);
2674 offset += 1;
2675 offset += get_sb4_custom(tvb, offset, &xid_len);
2676 if ( func == TTI_TPC_TXN_SWITCH103 )
2677 {
2678 start = offset;
2679 offset += get_sb4_custom(tvb, offset, &v);
2680 proto_tree_add_uint(tree, hf_tns_data_tpc_flags, tvb, start, offset - start, v);
2681 start = offset;
2682 offset += get_sb4_custom(tvb, offset, &v);
2683 proto_tree_add_uint(tree, hf_tns_data_tpc_timeout, tvb, start, offset - start, v);
2684 offset += 3; /* application value, return context and its length pointers */
2685 int_ptr = tvb_get_uint8(tvb, offset);
2686 offset += 1;
2687 offset += get_sb4_custom(tvb, offset, &int_len);
2688 ext_ptr = tvb_get_uint8(tvb, offset);
2689 offset += 1;
2690 offset += get_sb4_custom(tvb, offset, &ext_len);
2691 }
2692 else
2693 {
2694 start = offset;
2695 offset += get_sb4_custom(tvb, offset, &v);
2696 proto_tree_add_uint(tree, hf_tns_data_tpc_timeout, tvb, start, offset - start, v);
2697 start = offset;
2698 offset += get_sb4_custom(tvb, offset, &v);
2699 proto_tree_add_uint(tree, hf_tns_data_tpc_state, tvb, start, offset - start, v);
2700 offset += 1; /* out state pointer */
2701 start = offset;
2702 offset += get_sb4_custom(tvb, offset, &v);
2703 proto_tree_add_uint(tree, hf_tns_data_tpc_flags, tvb, start, offset - start, v);
2704 }
2705 if ( ctx_ptr && ctx_len > 0 )
2706 {
2707 proto_tree_add_item(tree, hf_tns_data_tpc_context, tvb, offset, ctx_len, ENC_NA0x00000000);
2708 offset += ctx_len;
2709 }
2710 if ( xid_ptr && xid_len > 0 )
2711 {
2712 if ( gtrid_len >= 0 && bqual_len >= 0 && gtrid_len + bqual_len <= xid_len )
2713 {
2714 proto_tree_add_item(tree, hf_tns_data_tpc_gtrid, tvb, offset, gtrid_len, ENC_NA0x00000000);
2715 proto_tree_add_item(tree, hf_tns_data_tpc_bqual, tvb, offset + gtrid_len, bqual_len, ENC_NA0x00000000);
2716 }
2717 offset += xid_len;
2718 }
2719 if ( func == TTI_TPC_TXN_SWITCH103 )
2720 {
2721 start = offset;
2722 offset += get_sb4_custom(tvb, offset, &v);
2723 proto_tree_add_uint(tree, hf_tns_data_tpc_app_value, tvb, start, offset - start, v);
2724 if ( int_ptr && int_len > 0 )
2725 {
2726 proto_tree_add_item(tree, hf_tns_data_tpc_internal_name, tvb, offset, int_len, ENC_UTF_80x00000002);
2727 offset += int_len;
2728 }
2729 if ( ext_ptr && ext_len > 0 )
2730 {
2731 proto_tree_add_item(tree, hf_tns_data_tpc_external_name, tvb, offset, ext_len, ENC_UTF_80x00000002);
2732 offset += ext_len;
2733 }
2734 }
2735 return offset;
2736}
2737
2738/* Decode the body of a piggyback other than close-cursors. Layouts
2739 * follow python-oracledb's _write_*_piggyback. Sets *walk when the body
2740 * was understood, so the call behind it can be decoded. Returns the new
2741 * offset. */
2742static int dissect_tns_piggyback_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, uint8_t piggyback_id, bool_Bool *walk)
2743{
2744 int v = 0, start;
2745 uint64_t u = 0;
2746
2747 switch ( piggyback_id )
2748 {
2749 case TTI_LOBOPS96:
2750 {
2751 /* close temporary LOBs: a FREE_TEMP | ARRAY LOB operation
2752 * whose locators, each with its own ub2 length prefix, follow
2753 * back to back - as many bytes as the total says. */
2754 int total = 0, op = 0;
2755 offset += 1; /* pointer */
2756 start = offset;
2757 offset += get_sb4_custom(tvb, offset, &total);
2758 proto_tree_add_uint(tree, hf_tns_data_lob_total_size, tvb, start, offset - start, total);
2759 offset += 1; /* dest locator pointer */
2760 offset += get_sb4_custom(tvb, offset, &v); /* dest locator length */
2761 offset += get_sb4_custom(tvb, offset, &v); /* source locator */
2762 offset += get_sb4_custom(tvb, offset, &v);
2763 offset += 3; /* offsets, charset */
2764 start = offset;
2765 offset += get_sb4_custom(tvb, offset, &op);
2766 proto_tree_add_uint(tree, hf_tns_data_lob_op, tvb, start, offset - start, op);
2767 offset += 1; /* scn */
2768 offset += get_sb4_custom(tvb, offset, &v); /* losbscn */
2769 offset += get_ub8_custom(tvb, offset, &u); /* lobscnl */
2770 offset += get_ub8_custom(tvb, offset, &u);
2771 offset += 1;
2772 for ( int i = 0; i < 3; i++ ) /* array LOB fields */
2773 {
2774 offset += 1;
2775 offset += get_sb4_custom(tvb, offset, &v);
2776 }
2777 if ( total < 0 || (unsigned)total > tvb_reported_length_remaining(tvb, offset) )
2778 {
2779 proto_tree_add_expert(tree, pinfo, &ei_tns_data_count_too_large, tvb, offset, 0);
2780 return offset;
2781 }
2782 for ( int end = offset + total; offset + 2 <= end; )
2783 {
2784 int len = 2 + tvb_get_ntohs(tvb, offset);
2785 if ( offset + len > end )
2786 len = end - offset;
2787 proto_tree_add_item(tree, hf_tns_data_lob_locator, tvb, offset, len, ENC_NA0x00000000);
2788 offset += len;
2789 }
2790 break;
2791 }
2792
2793 case TTI_SET_SCHEMA152:
2794 {
2795 const char *schema = NULL((void*)0);
2796 offset += 1; /* pointer */
2797 start = offset;
2798 offset += get_field_with_length(tvb, pinfo, offset, &schema);
2799 if ( schema )
2800 proto_tree_add_string(tree, hf_tns_data_pgy_schema, tvb, start, offset - start, schema);
2801 break;
2802 }
2803
2804 case TTI_SESSION_STATE176:
2805 start = offset;
2806 offset += get_ub8_custom(tvb, offset, &u);
2807 proto_tree_add_uint64(tree, hf_tns_data_pgy_session_state, tvb, start, offset - start, u);
2808 break;
2809
2810 case TTI_PIPELINE_BEGIN199:
2811 start = offset;
2812 offset += get_sb4_custom(tvb, offset, &v);
2813 proto_tree_add_uint(tree, hf_tns_data_pgy_error_set_id, tvb, start, offset - start, v);
2814 proto_tree_add_item(tree, hf_tns_data_pgy_error_set_mode, tvb, offset, 1, ENC_NA0x00000000);
2815 offset += 1;
2816 proto_tree_add_item(tree, hf_tns_data_pgy_pipeline_mode, tvb, offset, 1, ENC_NA0x00000000);
2817 offset += 1;
2818 break;
2819
2820 case TTI_SET_END_TO_END_ATTR135:
2821 {
2822 /* End-to-end attributes: a flags word saying which changed,
2823 * then a (pointer, length) header for each attribute - some
2824 * never used - and finally the strings of those that have a
2825 * value, in the same order. */
2826 static int * const hfs[] = { &hf_tns_data_pgy_client_id, &hf_tns_data_pgy_module,
2827 &hf_tns_data_pgy_action, NULL((void*)0), &hf_tns_data_pgy_client_info, NULL((void*)0), NULL((void*)0),
2828 &hf_tns_data_pgy_dbop };
2829 int lens[array_length(hfs)(sizeof (hfs) / sizeof (hfs)[0])];
2830
2831 offset += 2; /* cidnam, cidser pointers */
2832 start = offset;
2833 offset += get_sb4_custom(tvb, offset, &v);
2834 proto_tree_add_uint(tree, hf_tns_data_pgy_e2e_flags, tvb, start, offset - start, v);
2835 for ( unsigned i = 0; i < array_length(hfs)(sizeof (hfs) / sizeof (hfs)[0]); i++ )
2836 {
2837 uint8_t ptr = tvb_get_uint8(tvb, offset);
2838 offset += 1;
2839 offset += get_sb4_custom(tvb, offset, &lens[i]);
2840 if ( !ptr || !hfs[i] )
2841 lens[i] = 0;
2842 if ( i == 3 ) /* cideci is followed by cidcct, cidecs */
2843 {
2844 offset += 1;
2845 offset += get_sb4_custom(tvb, offset, &v);
2846 }
2847 }
2848 for ( unsigned i = 0; i < array_length(hfs)(sizeof (hfs) / sizeof (hfs)[0]); i++ )
2849 {
2850 const char *str = NULL((void*)0);
2851 if ( lens[i] <= 0 )
2852 continue;
2853 start = offset;
2854 offset += get_dalc_custom(tvb, pinfo, offset, &str);
2855 if ( str )
2856 proto_tree_add_string(tree, *hfs[i], tvb, start, offset - start, str);
2857 }
2858 break;
2859 }
2860
2861 case TTI_END_USER_SEC_CTX205:
2862 {
2863 /* End-user security context: flags, then key/value pairs, each
2864 * a flags word and a key, a text and a value in the
2865 * bytes_with_length form. */
2866 int num = 0;
2867 start = offset;
2868 offset += get_sb4_custom(tvb, offset, &v);
2869 proto_tree_add_uint(tree, hf_tns_data_pgy_sec_flags, tvb, start, offset - start, v);
2870 offset += 1; /* pointer */
2871 offset += get_sb4_custom(tvb, offset, &num);
2872 for ( int i = 0; i < num && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
2873 {
2874 const char *key = NULL((void*)0);
2875 offset += get_sb4_custom(tvb, offset, &v); /* flags */
2876 start = offset;
2877 offset += get_field_with_length(tvb, pinfo, offset, &key);
2878 if ( key )
2879 proto_tree_add_string(tree, hf_tns_data_pgy_sec_key, tvb, start, offset - start, key);
2880 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0)); /* text */
2881 start = offset;
2882 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
2883 proto_tree_add_item(tree, hf_tns_data_pgy_sec_value, tvb, start, offset - start, ENC_NA0x00000000);
2884 }
2885 break;
2886 }
2887
2888 default:
2889 /* An unknown body has an unknown length. */
2890 return offset;
2891 }
2892 *walk = true1;
2893 return offset;
2894}
2895
2896static void dissect_tns_data_descriptor(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tns_tree, uint32_t length)
2897{
2898 /* This is used by Oracle 12c for at least sending LOB/FILE data. */
2899 proto_tree *dd_tree, *row_tree;
2900 proto_item *ti;
2901 uint32_t data_len, row_count, row_size, total_row_size = 0;
2902 int orig_offset = offset;
2903
2904 /* We only get here after tcp_dissect_pdus(), length is guaranteed. */
2905 DISSECTOR_ASSERT_CMPINT(length, >=, TNS_HDR_LEN)((void) ((length >= 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion " "length" " " ">=" " " "8" " ("
"%" "l" "d" " " ">=" " " "%" "l" "d" ")", "epan/dissectors/packet-tns.c"
, 2905, (int64_t)length, (int64_t)8))))
;
2906
2907 dd_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1, ett_tns_data, NULL((void*)0), "Data Descriptor");
2908
2909 /* No idea what this is. Usually 0x0003. */
2910 offset += 4;
2911 proto_tree_add_item_ret_uint(dd_tree, hf_tns_data_length, tvb,
2912 offset, 4, ENC_BIG_ENDIAN0x00000000, &data_len);
2913 offset += 4;
2914
2915 /* This next parameter looks like: number of big endian shorts that follow,
2916 * the sum of the shorts equals the file length above - each short maxes
2917 * out at 0x1f7c = 8060, presumably related to the page size / max table
2918 * row size in Microsoft SQL Server? Something about how many rows it
2919 * would take to store this in-table?
2920 */
2921 proto_tree_add_item_ret_uint(dd_tree, hf_tns_data_descriptor_row_count, tvb,
2922 offset, 4, ENC_BIG_ENDIAN0x00000000, &row_count);
2923 offset += 4;
2924 row_tree = proto_tree_add_subtree(dd_tree, tvb, offset, row_count * 2,
2925 ett_tns_rows, &ti, "Rows");
2926 for (uint32_t i = 0; i < row_count; i++) {
2927 proto_tree_add_item_ret_uint(row_tree, hf_tns_data_descriptor_row_size, tvb,
2928 offset, 2, ENC_BIG_ENDIAN0x00000000, &row_size);
2929 total_row_size += row_size;
2930 offset += 2;
2931 }
2932 proto_item_append_text(ti, " (%u bytes)", total_row_size);
2933 if (total_row_size != data_len) {
2934 expert_add_info(pinfo, ti, &ei_tns_data_descriptor_size_mismatch);
2935 }
2936
2937 offset = orig_offset + (length - TNS_HDR_LEN8);
2938
2939 call_data_dissector(tvb_new_subset_length(tvb, offset, data_len), pinfo,
2940 dd_tree);
2941}
2942
2943/* State carried from one TTC message to the next within a packet. */
2944typedef struct _tns_msg_ctx_t {
2945 /* The decoder ended exactly on its message's last byte. */
2946 bool_Bool walk;
2947 /* Which columns the next row sends, from a row header or a TTI_BVC:
2948 * a clear bit means the value repeats the previous row's. NULL when
2949 * every column is sent. */
2950 const uint8_t *bit_vector;
2951 unsigned bit_vector_len;
2952 /* After a TTI_IOV: the call it answers and each bind's direction, so
2953 * the TTI_RXD after it can be read as the OUT bind values. */
2954 const tns_call_t *out_call;
2955 const uint8_t *bind_dirs;
2956} tns_msg_ctx_t;
2957
2958static int dissect_tns_message(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *data_tree, bool_Bool is_request, unsigned data_func_id, tns_msg_ctx_t *ctx);
2959
2960/* Whether a message that follows another in the same packet is one we
2961 * step into. A response is a run of messages back to back - a describe,
2962 * a row header, the rows, a status - and a request may put piggybacks in
2963 * front of its call. */
2964static bool_Bool tns_is_next_message(unsigned data_func_id, bool_Bool is_request)
2965{
2966 if ( is_request )
2967 return data_func_id == SQLNET_USER_OCI_FUNC3 || data_func_id == SQLNET_PIGGYBACK_FUNC17;
2968
2969 switch ( data_func_id )
2970 {
2971 case SQLNET_RETURN_STATUS4:
2972 case SQLNET_FLUSH_BIND_DATA19:
2973 case SQLNET_FUNCCOMPLETE9:
2974 case SQLNET_WARNING15:
2975 case SQLNET_LOB_FILE_DF14:
2976 case SQLNET_BIT_VECTOR21:
2977 case SQLNET_SERVER_PIGGYBACK23:
2978 case SQLNET_IMPLICIT_RESULTS27:
2979 case SQLNET_TOKEN33:
2980 case SQLNET_END_OF_RESPONSE29:
2981 case SQLNET_ROW_TRANSF_HDR6:
2982 case SQLNET_ROW_TRANSF_DATA7:
2983 case SQLNET_RETURN_OPI_PARAM8:
2984 case SQLNET_IOVEC_4FAST_UPI11:
2985 case SQLNET_DESCRIBE_INFO16:
2986 return true1;
2987 default:
2988 return false0;
2989 }
2990}
2991
2992static void dissect_tns_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tns_tree)
2993{
2994 proto_tree *data_tree;
2995 unsigned data_func_id;
2996 bool_Bool is_request;
2997 static int * const flags[] = {
2998 &hf_tns_data_flag_send,
2999 &hf_tns_data_flag_rc,
3000 &hf_tns_data_flag_c,
3001 &hf_tns_data_flag_reserved,
3002 &hf_tns_data_flag_more,
3003 &hf_tns_data_flag_eof,
3004 &hf_tns_data_flag_dic,
3005 &hf_tns_data_flag_rts,
3006 &hf_tns_data_flag_sntt,
3007 &hf_tns_data_flag_end_of_request,
3008 &hf_tns_data_flag_begin_pipeline,
3009 &hf_tns_data_flag_end_of_response,
3010 NULL((void*)0)
3011 };
3012
3013 is_request = pinfo->match_uint == pinfo->destport;
3014 data_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1, ett_tns_data, NULL((void*)0), "Data");
3015
3016 proto_tree_add_bitmask(data_tree, tvb, offset, hf_tns_data_flag, ett_tns_data_flag, flags, ENC_BIG_ENDIAN0x00000000);
3017 offset += 2;
3018 data_func_id = get_data_func_id(tvb, offset);
3019
3020 /* Once native network encryption is on, a data packet is ciphertext
3021 * followed by a padding and a key-fold byte; nothing in it can be
3022 * decoded without the session key. */
3023 if ( tns_is_encrypted(pinfo) && data_func_id != SQLNET_SNS0xdeadbeef )
3024 {
3025 col_append_str(pinfo->cinfo, COL_INFO, ", Encrypted Data");
3026 proto_tree_add_expert(data_tree, pinfo, &ei_tns_data_encrypted, tvb, offset, tvb_reported_length_remaining(tvb, offset));
3027 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, data_tree);
3028 return;
3029 }
3030
3031 /* The field version the connection negotiated decides the shape of
3032 * several messages; show the one in force. */
3033 unsigned fv = tns_field_version(pinfo);
3034 if ( fv )
3035 proto_item_set_generated(proto_tree_add_uint(data_tree, hf_tns_data_field_version, tvb, 0, 0, fv));
3036
3037 /* Do this only if the Data message have a body. Otherwise, there are only Data flags. */
3038 int remaining = tvb_reported_length_remaining(tvb, offset);
3039 if ( remaining > 0 )
3040 {
3041 if (is_request) {
3042 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
3043 tns_conv_info_t *tns_info = tns_get_conv_info(pinfo);
3044 if ((uint32_t)remaining == tns_info->pending_connect_data) {
3045 col_append_str(pinfo->cinfo, COL_INFO, ", Connect Data");
3046 proto_tree_add_item(data_tree, hf_tns_connect_data, tvb,
3047 offset, -1, ENC_ASCII0x00000000);
3048 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns, 0,
3049 GUINT_TO_POINTER(tns_info->pending_connect_data)((gpointer) (gulong) (tns_info->pending_connect_data)));
3050 tns_info->pending_connect_data = 0;
3051 return;
3052 }
3053 } else {
3054 if (p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, 0) != NULL((void*)0)) {
3055 col_append_str(pinfo->cinfo, COL_INFO, ", Connect Data");
3056 proto_tree_add_item(data_tree, hf_tns_connect_data, tvb,
3057 offset, -1, ENC_ASCII0x00000000);
3058 return;
3059 }
3060 }
3061 }
3062 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(data_func_id, tns_data_funcs, "unknown"));
3063
3064 if ( (data_func_id != SQLNET_SNS0xdeadbeef) && (try_val_to_str(data_func_id, tns_data_funcs) != NULL((void*)0)) )
3065 {
3066 proto_tree_add_item(data_tree, hf_tns_data_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3067 offset += 1;
3068 }
3069 }
3070
3071 /* Decode the first message, then step into each one after it for as
3072 * long as the previous decoder ended exactly on its last byte. */
3073 tns_msg_ctx_t ctx = { 0 };
3074 offset = dissect_tns_message(tvb, offset, pinfo, data_tree, is_request, data_func_id, &ctx);
3075 while ( ctx.walk && tvb_reported_length_remaining(tvb, offset) > 0 )
3076 {
3077 data_func_id = tvb_get_uint8(tvb, offset);
3078 if ( !tns_is_next_message(data_func_id, is_request) )
3079 break;
3080 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(data_func_id, tns_data_funcs, "unknown"));
3081 proto_tree_add_item(data_tree, hf_tns_data_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3082 offset += 1;
3083 ctx.walk = false0;
3084 offset = dissect_tns_message(tvb, offset, pinfo, data_tree, is_request, data_func_id, &ctx);
3085 }
3086
3087 if ( tvb_reported_length_remaining(tvb, offset) > 0 )
3088 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, data_tree);
3089}
3090
3091/* Whether a packet belongs to a conversation whose client speaks the OCI
3092 * dialect. Stored per packet on the first pass. */
3093static bool_Bool tns_is_oci(packet_info *pinfo)
3094{
3095 void *stored = p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_OCI4);
3096 if ( stored || PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
3097 return GPOINTER_TO_UINT(stored)((guint) (gulong) (stored)) == 2;
3098
3099 bool_Bool oci = tns_get_conv_info(pinfo)->oci_dialect;
3100 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns, TNS_PROTO_DATA_OCI4, GUINT_TO_POINTER(oci ? 2 : 1)((gpointer) (gulong) (oci ? 2 : 1)));
3101 return oci;
3102}
3103
3104/* Decode a server message to an OCI client. Its integers are fixed-width
3105 * little-endian, so only the status messages, whose layout is known, are
3106 * decoded; the rest is left to the data dissector. Returns the new
3107 * offset. */
3108static int dissect_tns_oci_message(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *data_tree, unsigned data_func_id)
3109{
3110 switch ( data_func_id )
3111 {
3112 case SQLNET_RETURN_STATUS4:
3113 {
3114 /* The OCI status block: 136 bytes, or a compact 24 for a
3115 * query's execute status, the end of a fetch and a no-row
3116 * status. Offsets count from the message id byte; a field
3117 * this decoder skips is a constant or not understood. The
3118 * error message follows the full form. */
3119 proto_tree *oer_tree;
3120 proto_item *oer_item;
3121 int base = offset - 1;
3122 bool_Bool full = tvb_reported_length_remaining(tvb, base) >= 136;
3123 uint32_t err_code;
3124
3125 if ( tvb_reported_length_remaining(tvb, base) < 24 )
3126 return offset;
3127 oer_tree = proto_tree_add_subtree(data_tree, tvb, base, full ? 136 : 24, ett_tns_oer, &oer_item,
3128 full ? "Oracle Error Return (OCI)" : "Oracle Error Return (OCI, compact)");
3129 proto_tree_add_item(oer_tree, hf_tns_data_oci_oer_status, tvb, base + 1, 1, ENC_NA0x00000000);
3130 proto_tree_add_item(oer_tree, hf_tns_data_oci_oer_seq, tvb, base + 5, 2, ENC_LITTLE_ENDIAN0x80000000);
3131 proto_tree_add_int(oer_tree, hf_tns_data_oer_rowcount, tvb, base + 8, 4, (int32_t)tvb_get_letohl(tvb, base + 8));
3132 err_code = tvb_get_letohl(tvb, base + 12);
3133 proto_tree_add_int(oer_tree, hf_tns_data_oer_err_code, tvb, base + 12, 4, (int32_t)err_code);
3134 proto_tree_add_item(oer_tree, hf_tns_data_oci_oer_category, tvb, base + 18, 1, ENC_NA0x00000000);
3135 proto_tree_add_item(oer_tree, hf_tns_data_oci_oer_error_pos, tvb, base + 20, 1, ENC_NA0x00000000);
3136 proto_tree_add_item(oer_tree, hf_tns_data_oci_oer_command, tvb, base + 22, 1, ENC_NA0x00000000);
3137 if ( !full )
3138 return base + 24;
3139 /* the sequence number of the call this answers - the client's
3140 * own, not the counter at offset 5 */
3141 proto_tree_add_item(oer_tree, hf_tns_data_oci_oer_call_seq, tvb, base + 49, 2, ENC_LITTLE_ENDIAN0x80000000);
3142 offset = base + 136;
3143 if ( err_code != 0 && tvb_reported_length_remaining(tvb, offset) > 0 )
3144 {
3145 const char *msg = NULL((void*)0);
3146 int msg_start = offset;
3147 offset += get_dalc_custom(tvb, pinfo, offset, &msg);
3148 msg = tns_trim_message(pinfo, msg);
3149 if ( msg )
3150 {
3151 proto_tree_add_string(oer_tree, hf_tns_data_oer_message, tvb, msg_start, offset - msg_start, msg);
3152 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", msg);
3153 }
3154 proto_item_set_len(oer_item, offset - base);
3155 }
3156 return offset;
3157 }
3158
3159 case SQLNET_FUNCCOMPLETE9:
3160 /* TTI_STA, answering a commit, a rollback or a logoff: a
3161 * ub4 LE call status and a ub2 LE end-to-end sequence */
3162 if ( !tvb_bytes_exist(tvb, offset, 6) )
3163 return offset;
3164 tns_add_call_status_flags(
3165 proto_tree_add_item(data_tree, hf_tns_data_sta_call_status, tvb, offset, 4, ENC_LITTLE_ENDIAN0x80000000),
3166 tvb, offset, 4, tvb_get_letohl(tvb, offset));
3167 proto_tree_add_item(data_tree, hf_tns_data_sta_seq, tvb, offset + 4, 2, ENC_LITTLE_ENDIAN0x80000000);
3168 return offset + 6;
3169
3170 default:
3171 return offset;
3172 }
3173}
3174
3175/* Decode the body of one TTC message, whose id byte has already been
3176 * consumed. Sets ctx->walk when the decoder ended exactly on the
3177 * message's last byte, so the caller can step into whatever follows it.
3178 * Returns the new offset. */
3179static int dissect_tns_message(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *data_tree, bool_Bool is_request, unsigned data_func_id, tns_msg_ctx_t *ctx)
3180{
3181 /* The thin decoders below would misread the fixed-width integers of
3182 * a server talking to an OCI client. */
3183 if ( !is_request && data_func_id != SQLNET_SNS0xdeadbeef && data_func_id != SQLNET_RETURN_OPI_PARAM8
3184 && tns_is_oci(pinfo) )
3185 return dissect_tns_oci_message(tvb, offset, pinfo, data_tree, data_func_id);
3186
3187 /* Handle data functions that have more than just ID */
3188 switch (data_func_id)
3189 {
3190 case SQLNET_SET_PROTOCOL1:
3191 {
3192 proto_tree *versions_tree;
3193 proto_item *ti;
3194 char sep;
3195 if ( is_request )
3196 {
3197 versions_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1, ett_tns_acc_versions, &ti, "Accepted Versions");
3198 sep = ':';
3199 for (;;) {
3200 /*
3201 * Add each accepted version as a
3202 * separate item.
3203 */
3204 uint8_t vers;
3205
3206 vers = tvb_get_uint8(tvb, offset);
3207 if (vers == 0) {
3208 /*
3209 * A version of 0 terminates
3210 * the list.
3211 */
3212 break;
3213 }
3214 proto_item_append_text(ti, "%c %u", sep, vers);
3215 sep = ',';
3216 proto_tree_add_uint(versions_tree, hf_tns_data_setp_acc_version, tvb, offset, 1, vers);
3217 offset += 1;
3218 }
3219 offset += 1; /* skip the 0 terminator */
3220 proto_item_set_end(ti, tvb, offset);
3221 proto_tree_add_item(data_tree, hf_tns_data_setp_cli_plat, tvb, offset, -1, ENC_ASCII0x00000000);
3222
3223 return tvb_reported_length(tvb); /* skip call_data_dissector */
3224 }
3225 else
3226 {
3227 unsigned len;
3228 versions_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1, ett_tns_acc_versions, &ti, "Versions");
3229 sep = ':';
3230 for (;;) {
3231 /*
3232 * Add each version as a separate item.
3233 */
3234 uint8_t vers;
3235
3236 vers = tvb_get_uint8(tvb, offset);
3237 if (vers == 0) {
3238 /*
3239 * A version of 0 terminates
3240 * the list.
3241 */
3242 break;
3243 }
3244 proto_item_append_text(ti, "%c %u", sep, vers);
3245 sep = ',';
3246 proto_tree_add_uint(versions_tree, hf_tns_data_setp_version, tvb, offset, 1, vers);
3247 offset += 1;
3248 }
3249 offset += 1; /* skip the 0 terminator */
3250 proto_item_set_end(ti, tvb, offset);
3251 proto_tree_add_item_ret_length(data_tree, hf_tns_data_setp_banner, tvb, offset, -1, ENC_ASCII0x00000000|ENC_NA0x00000000, &len);
3252 offset += len;
3253
3254 /* After the banner: the server's charset (LE), flags, a
3255 * count of 5-byte elements (LE), the "fdo" block (a BE
3256 * length) whose tail names the national charset, and the
3257 * server's compile and runtime capabilities, each behind a
3258 * length byte. Capability 7 is the highest TTC field
3259 * version the server offers. */
3260 if ( tvb_reported_length_remaining(tvb, offset) < 5 )
3261 break;
3262 proto_tree_add_item(data_tree, hf_tns_data_setp_charset, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3263 offset += 2;
3264 proto_tree_add_item(data_tree, hf_tns_data_setp_flags, tvb, offset, 1, ENC_NA0x00000000);
3265 offset += 1;
3266 unsigned num_elem = tvb_get_letohs(tvb, offset);
3267 offset += 2 + 5 * num_elem;
3268 unsigned fdo_len = tvb_get_ntohs(tvb, offset);
3269 offset += 2;
3270 if ( fdo_len >= 7 )
3271 {
3272 unsigned ix = 6 + tvb_get_uint8(tvb, offset + 5) + tvb_get_uint8(tvb, offset + 6);
3273 if ( ix + 5 <= fdo_len )
3274 proto_tree_add_item(data_tree, hf_tns_data_setp_ncharset, tvb, offset + ix + 3, 2, ENC_BIG_ENDIAN0x00000000);
3275 }
3276 offset += fdo_len;
3277 uint8_t caps_len = tvb_get_uint8(tvb, offset);
3278 proto_tree_add_item(data_tree, hf_tns_data_setp_compile_caps, tvb, offset, 1 + caps_len, ENC_NA0x00000000);
3279 if ( caps_len > TNS_CCAP_FIELD_VERSION7 )
3280 {
3281 proto_tree_add_item(data_tree, hf_tns_data_setp_field_version, tvb,
3282 offset + 1 + TNS_CCAP_FIELD_VERSION7, 1, ENC_NA0x00000000);
3283 if ( !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
3284 tns_get_conv_info(pinfo)->server_field_version =
3285 tvb_get_uint8(tvb, offset + 1 + TNS_CCAP_FIELD_VERSION7);
3286 }
3287 offset += 1 + caps_len;
3288 caps_len = tvb_get_uint8(tvb, offset);
3289 proto_tree_add_item(data_tree, hf_tns_data_setp_runtime_caps, tvb, offset, 1 + caps_len, ENC_NA0x00000000);
3290 offset += 1 + caps_len;
3291 }
3292 break;
3293 }
3294
3295 case SQLNET_SET_DATATYPES2:
3296 {
3297 /* TTI_DTY: Data Type Negotiation, sent right after TTI_PRO
3298 * during the TTC handshake. The body is a fixed-shape blob
3299 * the client uses to tell the server which native Oracle
3300 * data types it understands and what wire representation it
3301 * wants for each. Layout cross-referenced with
3302 * python-oracledb.
3303 *
3304 * charset_in 2 bytes LE NLS_LANGUAGE charset id
3305 * charset_out 2 bytes LE NLS_NCHAR charset id
3306 * flag 1 byte capability flag (1 = std)
3307 * capability header 39 bytes version triple + flag bytes
3308 * table header 8 bytes group/sub counts
3309 * identity map 980 bytes 245 x (type, type, 1, 0)
3310 * type overrides var entries, terminated by 0
3311 */
3312 proto_tree *caphdr_tree, *ov_tree;
3313 proto_item *caphdr_item, *ov_item;
3314
3315 if ( !is_request )
3316 break;
3317
3318 proto_tree_add_item(data_tree, hf_tns_data_setdt_charset_in, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3319 offset += 2;
3320 proto_tree_add_item(data_tree, hf_tns_data_setdt_charset_out, tvb, offset, 2, ENC_LITTLE_ENDIAN0x80000000);
3321 offset += 2;
3322 proto_tree_add_item(data_tree, hf_tns_data_setdt_flag, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3323 offset += 1;
3324
3325 caphdr_item = proto_tree_add_item(data_tree, hf_tns_data_setdt_caphdr, tvb, offset, 39, ENC_NA0x00000000);
3326 caphdr_tree = proto_item_add_subtree(caphdr_item, ett_tns_setdt_caphdr);
3327 proto_tree_add_item(caphdr_tree, hf_tns_data_setdt_caphdr_version, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
3328 proto_tree_add_item(caphdr_tree, hf_tns_data_setdt_caphdr_flags, tvb, offset + 3, 36, ENC_NA0x00000000);
3329 /* The header opens with the length of the client's compile
3330 * capabilities, and capability 7 is the TTC field version.
3331 * The client has already lowered it to the server's, so it
3332 * is the one the connection uses. */
3333 if ( tvb_get_uint8(tvb, offset) > TNS_CCAP_FIELD_VERSION7 )
3334 {
3335 uint8_t fv = tvb_get_uint8(tvb, offset + 1 + TNS_CCAP_FIELD_VERSION7);
3336 proto_tree_add_item(caphdr_tree, hf_tns_data_setdt_field_version, tvb,
3337 offset + 1 + TNS_CCAP_FIELD_VERSION7, 1, ENC_NA0x00000000);
3338 if ( !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
3339 tns_get_conv_info(pinfo)->field_version = fv;
3340 }
3341 offset += 39;
3342
3343 proto_tree_add_item(data_tree, hf_tns_data_setdt_tblhdr, tvb, offset, 8, ENC_NA0x00000000);
3344 offset += 8;
3345 proto_tree_add_item(data_tree, hf_tns_data_setdt_idmap, tvb, offset, 980, ENC_NA0x00000000);
3346 offset += 980;
3347
3348 /* Walk type-override entries until the 0 terminator. Each
3349 * entry is (client_type, server_repr[, format]); a 0 in the
3350 * server_repr slot marks a short "client knows the id but
3351 * has no override" entry. */
3352 ov_item = proto_tree_add_item(data_tree, hf_tns_data_setdt_overrides, tvb, offset, -1, ENC_NA0x00000000);
3353 ov_tree = proto_item_add_subtree(ov_item, ett_tns_setdt_overrides);
3354 int ov_start = offset;
3355 while ( tvb_reported_length_remaining(tvb, offset) > 0 )
3356 {
3357 uint8_t client_type = tvb_get_uint8(tvb, offset);
3358 if ( client_type == 0 )
3359 {
3360 proto_tree_add_item(ov_tree, hf_tns_data_setdt_override_client, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3361 offset += 1;
3362 break;
3363 }
3364 uint8_t repr = tvb_get_uint8(tvb, offset + 1);
3365 int entry_len = (repr == 0) ? 2 : 4;
3366 proto_tree *e_tree = proto_tree_add_subtree_format(ov_tree, tvb, offset, entry_len,
3367 ett_tns_setdt_override, NULL((void*)0), "Type %u (%s)",
3368 client_type, val_to_str_const(client_type, tns_data_types, "unknown"));
3369 proto_tree_add_item(e_tree, hf_tns_data_setdt_override_client, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3370 if ( entry_len == 4 )
3371 {
3372 proto_tree_add_item(e_tree, hf_tns_data_setdt_override_repr, tvb, offset + 1, 1, ENC_BIG_ENDIAN0x00000000);
3373 proto_tree_add_item(e_tree, hf_tns_data_setdt_override_format, tvb, offset + 2, 1, ENC_BIG_ENDIAN0x00000000);
3374 }
3375 offset += entry_len;
3376 }
3377 proto_item_set_len(ov_item, offset - ov_start);
3378 break;
3379 }
3380
3381 case SQLNET_RETURN_STATUS4:
3382 {
3383 /* TTI_OER: server-side end-of-call status block. Emitted at
3384 * the end of every response — success or failure. Layout
3385 * cross-referenced with python-oracledb's
3386 * _process_error_info, in the Oracle 11g shape (no extended
3387 * ub4 error number / ub8 rowcount that 12c+ adds).
3388 *
3389 * All multi-byte integers are stored in the ub4 variable-
3390 * length form (see get_sb4_custom): first byte holds the
3391 * value's width (0..4), followed by that many big-endian
3392 * data bytes. */
3393 proto_tree *oer_tree;
3394 proto_item *oer_item;
3395 int oer_start = offset;
3396 int v;
3397
3398 oer_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1, ett_tns_oer, &oer_item, "Oracle Error Return");
3399
3400 /* call_status */
3401 offset += get_sb4_custom(tvb, offset, &v);
3402 tns_add_call_status_flags(
3403 proto_tree_add_int(oer_tree, hf_tns_data_oer_call_status, tvb, oer_start, offset - oer_start, v),
3404 tvb, oer_start, offset - oer_start, (uint32_t)v);
3405 /* end-to-end seq# (skipped) */
3406 offset += get_sb4_custom(tvb, offset, &v);
3407 /* rowcount (DML affected rows on 11g) */
3408 int rc_start = offset;
3409 offset += get_sb4_custom(tvb, offset, &v);
3410 proto_tree_add_int(oer_tree, hf_tns_data_oer_rowcount, tvb, rc_start, offset - rc_start, v);
3411 /* err_code (ORA-NNNNN, 0 on success) */
3412 int ec_start = offset;
3413 int err_code = 0;
3414 offset += get_sb4_custom(tvb, offset, &err_code);
3415 proto_tree_add_int(oer_tree, hf_tns_data_oer_err_code, tvb, ec_start, offset - ec_start, err_code);
3416 /* array elem error #1, #2 (skipped) */
3417 offset += get_sb4_custom(tvb, offset, &v);
3418 offset += get_sb4_custom(tvb, offset, &v);
3419 /* cursor_id */
3420 int ci_start = offset;
3421 offset += get_sb4_custom(tvb, offset, &v);
3422 proto_tree_add_int(oer_tree, hf_tns_data_oer_cursor_id, tvb, ci_start, offset - ci_start, v);
3423 /* The status of an execute that opened a new cursor names it:
3424 * its bind types now belong to that cursor id. */
3425 if ( !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && v != 0 )
3426 {
3427 tns_conv_info_t *tns_info = tns_get_conv_info(pinfo);
3428 if ( tns_info->pending_binds )
3429 {
3430 wmem_map_insert(tns_info->cursor_binds, GUINT_TO_POINTER(v)((gpointer) (gulong) (v)), tns_info->pending_binds);
3431 tns_info->pending_binds = NULL((void*)0);
3432 }
3433 }
3434 /* error position (skipped) */
3435 offset += get_sb4_custom(tvb, offset, &v);
3436 /* 6 single-byte fields: sql_type, fatal, flags, user_cursor_opts, upi_param, warn_flags */
3437 offset += 6;
3438 /* rowid: ub4 rba, ub2 part_id, 1 byte reserved, ub4 block, ub2 slot */
3439 offset += get_sb4_custom(tvb, offset, &v);
3440 offset += get_sb4_custom(tvb, offset, &v);
3441 offset += 1;
3442 offset += get_sb4_custom(tvb, offset, &v);
3443 offset += get_sb4_custom(tvb, offset, &v);
3444 /* os error (skipped) */
3445 offset += get_sb4_custom(tvb, offset, &v);
3446 /* statement #, call # (1 byte each) */
3447 offset += 2;
3448 /* padding ub2 + successful iterations ub4 */
3449 offset += get_sb4_custom(tvb, offset, &v);
3450 offset += get_sb4_custom(tvb, offset, &v);
3451 /* oerrdd (logical rowid), a bytes_with_length — skipped */
3452 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
3453
3454 /* Batch error arrays (array DML). The code and offset arrays
3455 * are each a ub4 count followed by one DALC packing that many
3456 * ub4 values back to back; the message array is a ub4 count,
3457 * an indicator byte, and then that many str_with_length
3458 * entries each with a 2-byte trailer. All three counts are
3459 * zero for an ordinary statement. */
3460 int n_codes = 0, n_offs = 0, n_msgs = 0;
3461 int nb_start = offset;
3462 offset += get_sb4_custom(tvb, offset, &n_codes);
3463 proto_tree_add_int(oer_tree, hf_tns_data_oer_n_batch_errcodes, tvb, nb_start, offset - nb_start, n_codes);
3464 if ( n_codes > 0 )
3465 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
3466 nb_start = offset;
3467 offset += get_sb4_custom(tvb, offset, &n_offs);
3468 proto_tree_add_int(oer_tree, hf_tns_data_oer_n_batch_offsets, tvb, nb_start, offset - nb_start, n_offs);
3469 if ( n_offs > 0 )
3470 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
3471 nb_start = offset;
3472 offset += get_sb4_custom(tvb, offset, &n_msgs);
3473 proto_tree_add_int(oer_tree, hf_tns_data_oer_n_batch_messages, tvb, nb_start, offset - nb_start, n_msgs);
3474 if ( n_msgs > 0 )
3475 {
3476 offset += 1;
3477 for ( int i = 0; i < n_msgs; i++ )
3478 {
3479 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
3480 offset += 2;
3481 }
3482 }
3483
3484 /* From 12.1 the block goes on with the error number and row
3485 * count at their full widths (a ub4 and a ub8), and from 20.1
3486 * with the SQL type and a server checksum. The extended error
3487 * number is the one that says whether a message follows.
3488 * The first pair follows the negotiated field version, the
3489 * second the server's own release: a 21c or later server
3490 * sends it even to a session that settled on 12.1 or 19c. */
3491 unsigned fv = tns_field_version(pinfo);
3492 unsigned server_fv = tns_server_field_version(pinfo);
3493 if ( fv >= TNS_FV_12_17 )
3494 {
3495 uint64_t rows = 0;
3496 int start = offset;
3497 offset += get_sb4_custom(tvb, offset, &err_code);
3498 proto_tree_add_uint(oer_tree, hf_tns_data_oer_err_num_ext, tvb, start, offset - start, err_code);
3499 start = offset;
3500 offset += get_ub8_custom(tvb, offset, &rows);
3501 proto_tree_add_uint64(oer_tree, hf_tns_data_oer_rowcount_ext, tvb, start, offset - start, rows);
3502 }
3503 if ( fv >= TNS_FV_12_17 && (server_fv ? server_fv : fv) >= TNS_FV_20_114 )
3504 {
3505 int start = offset;
3506 offset += get_sb4_custom(tvb, offset, &v);
3507 proto_tree_add_uint(oer_tree, hf_tns_data_oer_sql_type, tvb, start, offset - start, v);
3508 start = offset;
3509 offset += get_sb4_custom(tvb, offset, &v);
3510 proto_tree_add_uint(oer_tree, hf_tns_data_oer_checksum, tvb, start, offset - start, v);
3511 }
3512
3513 /* Trailing message DALC — present (and meaningful) only when
3514 * err_code is non-zero. */
3515 if ( err_code != 0 && tvb_reported_length_remaining(tvb, offset) > 0 )
3516 {
3517 const char *msg = NULL((void*)0);
3518 int msg_start = offset;
3519 offset += get_dalc_custom(tvb, pinfo, offset, &msg);
3520 msg = tns_trim_message(pinfo, msg);
3521 if ( msg )
3522 {
3523 proto_tree_add_string(oer_tree, hf_tns_data_oer_message, tvb, msg_start, offset - msg_start, msg);
3524 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", msg);
3525 }
3526 }
3527 proto_item_set_len(oer_item, offset - oer_start);
3528 /* With the field version known the block ends where it
3529 * should, so an end-of-response marker after it can be read. */
3530 ctx->walk = fv != 0;
3531 break;
3532 }
3533
3534 case SQLNET_FUNCCOMPLETE9:
3535 {
3536 /* TTI_STA: a bare status, with no error block. It answers a
3537 * commit, a rollback or a logoff: a ub4 call status and the
3538 * ub2 end-to-end sequence number. */
3539 int v = 0, start;
3540
3541 if ( is_request )
3542 break;
3543
3544 start = offset;
3545 offset += get_sb4_custom(tvb, offset, &v);
3546 tns_add_call_status_flags(
3547 proto_tree_add_uint(data_tree, hf_tns_data_sta_call_status, tvb, start, offset - start, v),
3548 tvb, start, offset - start, (uint32_t)v);
3549 start = offset;
3550 offset += get_sb4_custom(tvb, offset, &v);
3551 proto_tree_add_uint(data_tree, hf_tns_data_sta_seq, tvb, start, offset - start, v);
3552 ctx->walk = true1;
3553 break;
3554 }
3555
3556 case SQLNET_LOB_FILE_DF14:
3557 {
3558 /* LOB content: what a TTI_LOBOPS READ returns, ahead of the
3559 * return parameters. Raw bytes for a BLOB or BFILE, the LOB's
3560 * character set (usually UTF-16BE) for a CLOB. */
3561 int start = offset;
3562
3563 if ( is_request )
3564 break;
3565
3566 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
3567 if ( tvb_get_uint8(tvb, start) == 0xfe ) /* chunked: shown whole */
3568 proto_tree_add_item(data_tree, hf_tns_data_lob_data, tvb, start, offset - start, ENC_NA0x00000000);
3569 else if ( offset - start > 1 )
3570 proto_tree_add_item(data_tree, hf_tns_data_lob_data, tvb, start + 1, offset - start - 1, ENC_NA0x00000000);
3571 ctx->walk = true1;
3572 break;
3573 }
3574
3575 case SQLNET_WARNING15:
3576 {
3577 /* TTI_WRN: a warning that does not fail the call - PL/SQL
3578 * compiled with errors, say. A ub2 warning number, a ub2
3579 * message length and ub2 flags, then the message itself when
3580 * both are non-zero. */
3581 int code = 0, len = 0, v = 0, start;
3582
3583 if ( is_request )
3584 break;
3585
3586 start = offset;
3587 offset += get_sb4_custom(tvb, offset, &code);
3588 proto_tree_add_uint(data_tree, hf_tns_data_wrn_code, tvb, start, offset - start, code);
3589 start = offset;
3590 offset += get_sb4_custom(tvb, offset, &len);
3591 proto_tree_add_uint(data_tree, hf_tns_data_wrn_length, tvb, start, offset - start, len);
3592 start = offset;
3593 offset += get_sb4_custom(tvb, offset, &v);
3594 proto_tree_add_uint(data_tree, hf_tns_data_wrn_flags, tvb, start, offset - start, v);
3595 if ( code != 0 && len > 0 )
3596 {
3597 const char *msg = NULL((void*)0);
3598 start = offset;
3599 offset += get_dalc_custom(tvb, pinfo, offset, &msg);
3600 msg = tns_trim_message(pinfo, msg);
3601 if ( msg )
3602 {
3603 proto_tree_add_string(data_tree, hf_tns_data_wrn_message, tvb, start, offset - start, msg);
3604 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", msg);
3605 }
3606 }
3607 ctx->walk = true1;
3608 break;
3609 }
3610
3611 case SQLNET_SERVER_PIGGYBACK23:
3612 {
3613 /* A piggyback from the server: state it pushes to the client
3614 * alongside a reply, selected by an opcode. Layouts follow
3615 * python-oracledb's _process_server_side_piggyback. */
3616 int v = 0, num = 0, start;
3617 uint8_t opcode;
3618
3619 if ( is_request )
3620 break;
3621
3622 proto_tree_add_item_ret_uint8(data_tree, hf_tns_data_spb_opcode, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &opcode);
3623 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
3624 val_to_str_const(opcode, tns_spb_opcodes, "unknown"));
3625 offset += 1;
3626 switch ( opcode )
3627 {
3628 case TNS_SPB_QUERY_CACHE_INVALIDATION1:
3629 case TNS_SPB_TRACE_EVENT3:
3630 break;
3631 case TNS_SPB_LTXID7:
3632 offset += get_sb4_custom(tvb, offset, &v);
3633 if ( v > 0 )
3634 {
3635 start = offset;
3636 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
3637 proto_tree_add_item(data_tree, hf_tns_data_spb_ltxid, tvb, start + 1, offset - start - 1, ENC_NA0x00000000);
3638 }
3639 break;
3640 case TNS_SPB_OS_PID_MTS2:
3641 {
3642 const char *pid = NULL((void*)0);
3643 offset += get_sb4_custom(tvb, offset, &v);
3644 start = offset;
3645 offset += get_dalc_custom(tvb, pinfo, offset, &pid);
3646 if ( pid )
3647 proto_tree_add_string(data_tree, hf_tns_data_spb_os_pid, tvb, start, offset - start, pid);
3648 break;
3649 }
3650 case TNS_SPB_SYNC5:
3651 /* Session state the statement changed - a new current
3652 * schema, edition or NLS setting - as key/value pairs. */
3653 offset += get_sb4_custom(tvb, offset, &v); /* number of DTYs */
3654 offset += 1; /* length of DTYs */
3655 start = offset;
3656 offset += get_sb4_custom(tvb, offset, &num);
3657 proto_tree_add_uint(data_tree, hf_tns_data_spb_num_kv, tvb, start, offset - start, num);
3658 offset += 1; /* length */
3659 offset = dissect_tns_kv_pairs(tvb, pinfo, data_tree, offset, num);
3660 start = offset;
3661 offset += get_sb4_custom(tvb, offset, &v);
3662 proto_tree_add_uint(data_tree, hf_tns_data_spb_flags, tvb, start, offset - start, v);
3663 break;
3664 case TNS_SPB_EXT_SYNC9:
3665 offset += get_sb4_custom(tvb, offset, &v); /* number of DTYs */
3666 offset += 1; /* length of DTYs */
3667 break;
3668 case TNS_SPB_AC_REPLAY_CONTEXT8:
3669 offset += get_sb4_custom(tvb, offset, &v); /* number of DTYs */
3670 offset += 1; /* length of DTYs */
3671 offset += get_sb4_custom(tvb, offset, &v); /* flags */
3672 offset += get_sb4_custom(tvb, offset, &v); /* error code */
3673 offset += 1; /* queue */
3674 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0)); /* replay context */
3675 break;
3676 case TNS_SPB_SESS_RET4:
3677 offset += get_sb4_custom(tvb, offset, &v); /* number of DTYs */
3678 offset += 1; /* length of DTYs */
3679 offset += get_sb4_custom(tvb, offset, &num);
3680 if ( num > 0 )
3681 {
3682 offset += 1;
3683 for ( int i = 0; i < num && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
3684 {
3685 offset += get_sb4_custom(tvb, offset, &v); /* key */
3686 if ( v > 0 )
3687 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
3688 offset += get_sb4_custom(tvb, offset, &v); /* value */
3689 if ( v > 0 )
3690 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
3691 offset += get_sb4_custom(tvb, offset, &v); /* flags */
3692 }
3693 }
3694 start = offset;
3695 offset += get_sb4_custom(tvb, offset, &v);
3696 proto_tree_add_uint(data_tree, hf_tns_data_spb_flags, tvb, start, offset - start, v);
3697 start = offset;
3698 offset += get_sb4_custom(tvb, offset, &v);
3699 proto_tree_add_uint(data_tree, hf_tns_data_spb_session_id, tvb, start, offset - start, v);
3700 start = offset;
3701 offset += get_sb4_custom(tvb, offset, &v);
3702 proto_tree_add_uint(data_tree, hf_tns_data_spb_serial_num, tvb, start, offset - start, v);
3703 break;
3704 case TNS_SPB_SESS_SIGNATURE10:
3705 {
3706 uint64_t u = 0;
3707 offset += get_sb4_custom(tvb, offset, &v); /* number of DTYs */
3708 offset += 1; /* length of DTYs */
3709 offset += get_ub8_custom(tvb, offset, &u); /* signature flags */
3710 offset += get_ub8_custom(tvb, offset, &u); /* client signature */
3711 offset += get_ub8_custom(tvb, offset, &u); /* server signature */
3712 break;
3713 }
3714 default:
3715 /* Unknown opcode: its length is unknown too. */
3716 return offset;
3717 }
3718 ctx->walk = true1;
3719 break;
3720 }
3721
3722 case SQLNET_IMPLICIT_RESULTS27:
3723 {
3724 /* The result sets a PL/SQL block returned with
3725 * DBMS_SQL.RETURN_RESULT: a ub4 count, then per result a
3726 * length-prefixed opaque blob, the describe of its columns,
3727 * and the ub2 cursor id the client fetches it with. */
3728 int num = 0, start;
3729
3730 if ( is_request )
3731 break;
3732
3733 start = offset;
3734 offset += get_sb4_custom(tvb, offset, &num);
3735 proto_tree_add_uint(data_tree, hf_tns_data_irs_num_results, tvb, start, offset - start, num);
3736 for ( int i = 0; i < num && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
3737 {
3738 proto_tree *rs_tree;
3739 proto_item *rs_item;
3740 int rs_start = offset, cursor = 0;
3741
3742 rs_tree = proto_tree_add_subtree_format(data_tree, tvb, offset, -1,
3743 ett_tns_irs, &rs_item, "Result Set %d", i + 1);
3744 offset += 1 + tvb_get_uint8(tvb, offset);
3745 offset = dissect_tns_describe_body(tvb, pinfo, rs_tree, offset, NULL((void*)0));
3746 start = offset;
3747 offset += get_sb4_custom(tvb, offset, &cursor);
3748 proto_tree_add_uint(rs_tree, hf_tns_cursor, tvb, start, offset - start, cursor);
3749 proto_item_append_text(rs_item, ": cursor %d", cursor);
3750 proto_item_set_len(rs_item, offset - rs_start);
3751 }
3752 ctx->walk = true1;
3753 break;
3754 }
3755
3756 case SQLNET_TOKEN33:
3757 {
3758 /* the token of the call this answers */
3759 uint64_t token = 0;
3760 int start = offset;
3761
3762 if ( is_request )
3763 break;
3764 offset += get_ub8_custom(tvb, offset, &token);
3765 proto_tree_add_uint64(data_tree, hf_tns_data_token, tvb, start, offset - start, token);
3766 ctx->walk = true1;
3767 break;
3768 }
3769
3770 case SQLNET_FLUSH_BIND_DATA19:
3771 /* Sent when a DML with a RETURNING clause fails: the client
3772 * drops the out-bind data it was collecting. There is no
3773 * body, and the error follows. */
3774 if ( !is_request )
3775 ctx->walk = true1;
3776 break;
3777
3778 case SQLNET_END_OF_RESPONSE29:
3779 /* Marks the end of a response for a client that negotiated
3780 * it; there is no body. */
3781 ctx->walk = true1;
3782 break;
3783
3784 case SQLNET_IOVEC_4FAST_UPI11:
3785 {
3786 /* TTI_IOV: the server's I/O vector for an executed anonymous
3787 * PL/SQL block that carried bind variables. It lists each
3788 * bind's direction (IN / OUT / IN OUT); when any bind is
3789 * OUT / IN OUT the returned values follow as a TTI_RXD row.
3790 * Layout cross-referenced with python-oracledb's
3791 * _process_io_vector, and
3792 * verified against XE 11g.
3793 *
3794 * All the leading counters are stored in the ub4 variable-
3795 * length form (see get_sb4_custom). The per-bind directions
3796 * are one raw byte each. The trailing RXD values need each
3797 * bind's declared type to decode, so they are read only when
3798 * the execute this answers was seen. */
3799 int num_requests = 0, num_iters = 0, v = 0, bv_len = 0, rid_len = 0;
3800
3801 if ( !is_request )
3802 {
3803 /* flag (ub1, skip) */
3804 offset += 1;
3805 offset += get_sb4_custom(tvb, offset, &num_requests);
3806 offset += get_sb4_custom(tvb, offset, &num_iters);
3807 int num_binds = num_iters * 256 + num_requests;
3808 proto_tree_add_uint(data_tree, hf_tns_data_iov_num_binds, tvb, offset, 0, num_binds);
3809 /* num iters this time (skip) */
3810 offset += get_sb4_custom(tvb, offset, &v);
3811 /* uac buffer length (skip) */
3812 offset += get_sb4_custom(tvb, offset, &v);
3813 /* fast-fetch bit-vector: length + bytes (skip) */
3814 offset += get_sb4_custom(tvb, offset, &bv_len);
3815 if ( bv_len > 0 )
3816 offset += bv_len;
3817 /* rowid: length + bytes (skip) */
3818 offset += get_sb4_custom(tvb, offset, &rid_len);
3819 if ( rid_len > 0 )
3820 offset += rid_len;
3821
3822 /* Per-bind direction bytes, in bind order. Bound by both
3823 * the reported count and the bytes actually present so a
3824 * malformed vector cannot run away. */
3825 proto_tree *iov_tree;
3826 proto_item *iov_item;
3827 int iov_start = offset;
3828 iov_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1, ett_tns_iov, &iov_item, "Bind Directions");
3829 for ( int i = 0; i < num_binds && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
3830 {
3831 proto_tree_add_item(iov_tree, hf_tns_data_iov_bind_dir, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
3832 offset += 1;
3833 }
3834 proto_item_set_len(iov_item, offset - iov_start);
3835
3836 /* The OUT and IN OUT values follow as a TTI_RXD, typed by
3837 * the binds of the execute this answers - readable only
3838 * when that execute was seen and bound as many. */
3839 const tns_call_t *call = tns_answered_call(pinfo);
3840 if ( call && call->binds && call->num_binds == (uint32_t)num_binds
3841 && offset - iov_start == num_binds )
3842 {
3843 ctx->out_call = call;
3844 ctx->bind_dirs = tvb_memdup(pinfo->pool, tvb, iov_start, num_binds);
3845 ctx->walk = true1;
3846 }
3847 }
3848 break;
3849 }
3850
3851 case SQLNET_DESCRIBE_INFO16:
3852 {
3853 /* TTI_DCB: describe (column metadata) for a SELECT result set,
3854 * in the Oracle 11g shape: a preamble, then the describe body.
3855 * The columns are remembered, once, so a later TTI_RXD can
3856 * split its row values. */
3857 tns_describe_t *desc = NULL((void*)0);
3858
3859 if ( is_request )
3860 break;
3861
3862 /* describe-info preamble (chunked bytes: cursor uuid + date) */
3863 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
3864 offset = dissect_tns_describe_body(tvb, pinfo, data_tree, offset,
3865 PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) ? NULL((void*)0) : &desc);
3866 if ( desc )
3867 tns_get_conv_info(pinfo)->last_describe = desc;
3868 ctx->walk = true1;
3869 break;
3870 }
3871
3872 case SQLNET_ROW_TRANSF_HDR6:
3873 {
3874 /* TTI_RXH: row transfer header, precedes the row data in a
3875 * SELECT response. All numeric fields use the ub4 variable-
3876 * length form. Layout cross-referenced with
3877 * python-oracledb's _process_row_header. */
3878 int v = 0, bv_len = 0, start;
3879
3880 if ( is_request )
3881 break;
3882
3883 /* flag (ub1, skip) */
3884 offset += 1;
3885 /* number of requests */
3886 start = offset;
3887 offset += get_sb4_custom(tvb, offset, &v);
3888 proto_tree_add_uint(data_tree, hf_tns_data_rxh_num_requests, tvb, start, offset - start, v);
3889 /* iteration number */
3890 start = offset;
3891 offset += get_sb4_custom(tvb, offset, &v);
3892 proto_tree_add_uint(data_tree, hf_tns_data_rxh_iter_num, tvb, start, offset - start, v);
3893 /* number of iterations */
3894 start = offset;
3895 offset += get_sb4_custom(tvb, offset, &v);
3896 proto_tree_add_uint(data_tree, hf_tns_data_rxh_num_iters, tvb, start, offset - start, v);
3897 /* buffer length (ub4, skip) */
3898 offset += get_sb4_custom(tvb, offset, &v);
3899 /* bit vector: length + [repeated length byte + vector bytes],
3900 * saying which columns the first row sends */
3901 offset += get_sb4_custom(tvb, offset, &bv_len);
3902 if ( bv_len > 0 )
3903 {
3904 offset += 1; /* repeated length byte */
3905 proto_tree_add_item(data_tree, hf_tns_data_bit_vector, tvb, offset, bv_len, ENC_NA0x00000000);
3906 ctx->bit_vector = tvb_memdup(pinfo->pool, tvb, offset, bv_len);
3907 ctx->bit_vector_len = bv_len;
3908 offset += bv_len; /* bit vector */
3909 }
3910 /* rxhrid (bytes_with_length, skip) */
3911 offset += get_field_with_length(tvb, pinfo, offset, NULL((void*)0));
3912 ctx->walk = true1;
3913 break;
3914 }
3915
3916 case SQLNET_BIT_VECTOR21:
3917 {
3918 /* TTI_BVC: which columns the next row sends. A row that
3919 * repeats values from the row before sends only the ones that
3920 * changed, and the clear bits name those it left out. A ub2
3921 * count of columns sent, then one bit per described column. */
3922 tns_describe_t *desc;
3923 int v = 0, start;
3924
3925 if ( is_request )
3926 break;
3927
3928 start = offset;
3929 offset += get_sb4_custom(tvb, offset, &v);
3930 proto_tree_add_uint(data_tree, hf_tns_data_bvc_num_cols_sent, tvb, start, offset - start, v);
3931 desc = tns_current_describe(pinfo);
3932 if ( !desc )
3933 break;
3934 unsigned bv_len = (desc->num_cols + 7) / 8;
3935 proto_tree_add_item(data_tree, hf_tns_data_bit_vector, tvb, offset, bv_len, ENC_NA0x00000000);
3936 ctx->bit_vector = tvb_memdup(pinfo->pool, tvb, offset, bv_len);
3937 ctx->bit_vector_len = bv_len;
3938 offset += bv_len;
3939 ctx->walk = true1;
3940 break;
3941 }
3942
3943 case SQLNET_ROW_TRANSF_DATA7:
3944 {
3945 /* TTI_RXD: row data for a SELECT result set — typically a
3946 * TTI_FETCH continuation, where the describe (TTI_DCB) arrived
3947 * in an earlier packet. Split each row into columns using the
3948 * types remembered from that describe (threaded through
3949 * conversation state); ordinary values are shown raw.
3950 *
3951 * The leading RXD token was already consumed above, so offset
3952 * sits on the first row's first value. A row that follows a
3953 * bit vector sends only the columns whose bit is set. */
3954 tns_describe_t *desc;
3955
3956 if ( is_request )
3957 break;
3958
3959 if ( ctx->bind_dirs )
3960 {
3961 /* The OUT and IN OUT bind values of a PL/SQL execute, in
3962 * bind order, each followed by its sb4 return code. Out of
3963 * a fetch, ROWID and UROWID come as strings and a LONG has
3964 * no trailing indicators. */
3965 proto_tree *ob_tree;
3966 proto_item *ob_item;
3967 int ob_start = offset, rc = 0, start;
3968
3969 ob_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1,
3970 ett_tns_out_binds, &ob_item, "Out Binds");
3971 for ( uint32_t i = 0; i < ctx->out_call->num_binds
3972 && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
3973 {
3974 uint8_t btype = ctx->out_call->binds[i].type;
3975 if ( ctx->bind_dirs[i] == TNS_BIND_DIR_INPUT32 )
3976 continue;
3977 if ( btype == TNS_DATATYPE_ROWID11 || btype == TNS_DATATYPE_UROWID208
3978 || btype == TNS_DATATYPE_LONG8 )
3979 btype = TNS_DATATYPE_VARCHAR1;
3980 else if ( btype == TNS_DATATYPE_LONG_RAW24 )
3981 btype = TNS_DATATYPE_RAW23;
3982 offset = dissect_tns_value(tvb, pinfo, ob_tree, offset, btype,
3983 ctx->out_call->binds[i].csform, i + 1,
3984 hf_tns_data_bind_value, "Bind");
3985 start = offset;
3986 offset += get_sb4_custom(tvb, offset, &rc);
3987 proto_tree_add_int(ob_tree, hf_tns_data_bind_retcode, tvb, start, offset - start, rc);
3988 }
3989 proto_item_set_len(ob_item, offset - ob_start);
3990 ctx->bind_dirs = NULL((void*)0);
3991 ctx->walk = true1;
3992 break;
3993 }
3994
3995 const tns_call_t *rcall = tns_answered_call(pinfo);
3996 if ( rcall && rcall->num_return > 0 && rcall->binds )
3997 {
3998 /* The values a DML RETURNING ... INTO returned: for each
3999 * return bind a ub4 row count - every row the statement
4000 * touched - then that many values, each followed by its
4001 * sb4 return code. */
4002 proto_tree *rv_tree;
4003 proto_item *rv_item;
4004 int rv_start = offset, rc = 0, start;
4005
4006 rv_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1,
4007 ett_tns_out_binds, &rv_item, "Returned Values");
4008 for ( uint32_t i = rcall->num_binds - rcall->num_return; i < rcall->num_binds
4009 && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
4010 {
4011 int rows = 0;
4012 offset += get_sb4_custom(tvb, offset, &rows);
4013 for ( int j = 0; j < rows && tvb_reported_length_remaining(tvb, offset) > 0; j++ )
4014 {
4015 offset = dissect_tns_value(tvb, pinfo, rv_tree, offset, rcall->binds[i].type,
4016 rcall->binds[i].csform, i + 1, hf_tns_data_bind_value, "Bind");
4017 start = offset;
4018 offset += get_sb4_custom(tvb, offset, &rc);
4019 proto_tree_add_int(rv_tree, hf_tns_data_bind_retcode, tvb, start, offset - start, rc);
4020 }
4021 }
4022 proto_item_set_len(rv_item, offset - rv_start);
4023 ctx->walk = true1;
4024 break;
4025 }
4026
4027 desc = tns_current_describe(pinfo);
4028
4029 if ( desc && desc->num_cols > 0 )
4030 {
4031 int rownum = 0, first_row = 1;
4032 while ( tvb_reported_length_remaining(tvb, offset) > 0 )
4033 {
4034 proto_tree *row_tree;
4035 proto_item *row_item;
4036 int r_start;
4037
4038 if ( !first_row )
4039 {
4040 if ( tvb_get_uint8(tvb, offset) != SQLNET_ROW_TRANSF_DATA7 )
4041 break;
4042 offset += 1; /* RXD token for subsequent rows */
4043 }
4044 first_row = 0;
4045
4046 r_start = offset;
4047 row_tree = proto_tree_add_subtree_format(data_tree, tvb, offset, -1,
4048 ett_tns_rxd_row, &row_item, "Row %d", ++rownum);
4049 for ( uint32_t c = 0; c < desc->num_cols
4050 && tvb_reported_length_remaining(tvb, offset) > 0; c++ )
4051 {
4052 const tns_column_t *col = &desc->cols[c];
4053 if ( ctx->bit_vector && c / 8 < ctx->bit_vector_len
4054 && !(ctx->bit_vector[c / 8] & (1 << (c % 8))) )
4055 {
4056 proto_tree_add_bytes_format(row_tree, hf_tns_data_col_value,
4057 tvb, offset, 0, NULL((void*)0), "Column %u (%s): same as previous row",
4058 c + 1, val_to_str_const(col->type, tns_data_types, "unknown"));
4059 continue;
4060 }
4061 /* A column the describe gives no data length is
4062 * NULL by definition (SELECT NULL, SELECT '')
4063 * and sends no bytes at all - not even an empty
4064 * DALC. LONG, LONG RAW and UROWID are the
4065 * exceptions: they always carry their value. */
4066 if ( col->data_len == 0 && col->type != TNS_DATATYPE_LONG8
4067 && col->type != TNS_DATATYPE_LONG_RAW24
4068 && col->type != TNS_DATATYPE_UROWID208 )
4069 {
4070 proto_tree_add_bytes_format(row_tree, hf_tns_data_col_value,
4071 tvb, offset, 0, NULL((void*)0), "Column %u (%s): NULL (no data length)",
4072 c + 1, val_to_str_const(col->type, tns_data_types, "unknown"));
4073 continue;
4074 }
4075 offset = dissect_tns_value(tvb, pinfo, row_tree, offset,
4076 col->type, col->csform, c + 1, hf_tns_data_col_value, "Column");
4077 }
4078 proto_item_set_len(row_item, offset - r_start);
4079 /* A bit vector covers one row only. */
4080 ctx->bit_vector = NULL((void*)0);
4081 }
4082 ctx->walk = true1;
4083 }
4084 break;
4085 }
4086
4087 case SQLNET_USER_OCI_FUNC3:
4088 {
4089 guint32 oci_id = 0;
4090 tns_call_t *call;
4091 int fun_start = offset - 1; /* the TTI_FUN byte */
4092 proto_tree_add_item_ret_uint(data_tree, hf_tns_data_oci_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000, &oci_id);
4093 offset += 1;
4094 call = is_request ? tns_remember_call(pinfo, (uint8_t)oci_id) : NULL((void*)0);
4095 /* Name the specific OCI call in the Info column — otherwise every
4096 * function call reads only as the generic "User OCI Functions". */
4097 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
4098 val_to_str_ext_const(oci_id, &tns_data_oci_subfuncs_ext, "unknown"));
4099 proto_tree_add_item(data_tree, hf_tns_data_tseq, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4100 offset += 1;
4101 offset = dissect_tns_call_token(tvb, pinfo, data_tree, offset);
4102 if((oci_id == 115) || (oci_id == 118)){
4103 /* The two authentication calls: the session key request
4104 * (118) and the authentication itself (115). A pointer
4105 * and a ub4 user name length, the ub4 mode, a pointer, the
4106 * ub4 number of key/value pairs, two pointers, the user
4107 * name, and the pairs - each a key and a value with two
4108 * lengths and a ub4 flags word. The first call's pairs
4109 * carry the client's identity (program, machine, terminal,
4110 * process id, OS user), which is what the server records
4111 * for the session; the second's the proof, the driver name
4112 * and the session settings. */
4113 int user_len = 0, mode = 0, num = 0, start;
4114 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, 1, ENC_NA0x00000000);
4115 offset += 1;
4116 offset += get_sb4_custom(tvb, offset, &user_len);
4117 start = offset;
4118 offset += get_sb4_custom(tvb, offset, &mode);
4119 proto_tree_add_bitmask_value(data_tree, tvb, start, hf_tns_data_auth_mode,
4120 ett_tns_auth_mode, tns_auth_modes, (uint64_t)(uint32_t)mode);
4121 offset += 1; /* pointer */
4122 start = offset;
4123 offset += get_sb4_custom(tvb, offset, &num);
4124 proto_tree_add_uint(data_tree, hf_tns_data_opi_num_of_params, tvb, start, offset - start, num);
4125 offset += 2; /* pointers */
4126 if ( user_len > 0 )
4127 {
4128 const char *user = NULL((void*)0);
4129 start = offset;
4130 offset += get_dalc_custom(tvb, pinfo, offset, &user);
4131 if ( user )
4132 {
4133 proto_tree_add_string(data_tree, hf_tns_data_auth_user, tvb, start, offset - start, user);
4134 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", user);
4135 }
4136 }
4137 for ( int i = 0; i < num && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
4138 {
4139 proto_tree *par_tree;
4140 proto_item *par_ti;
4141 const char *key = NULL((void*)0), *value = NULL((void*)0);
4142 int v = 0, par_start = offset;
4143
4144 par_tree = proto_tree_add_subtree_format(data_tree, tvb, offset, -1,
4145 ett_tns_opi_par, &par_ti, "Parameter %d", i + 1);
4146 start = offset;
4147 offset += get_field_with_length(tvb, pinfo, offset, &key);
4148 if ( key )
4149 proto_tree_add_string(par_tree, hf_tns_data_opi_param_name, tvb, start, offset - start, key);
4150 start = offset;
4151 offset += get_field_with_length(tvb, pinfo, offset, &value);
4152 if ( value )
4153 proto_tree_add_string(par_tree, hf_tns_data_opi_param_value, tvb, start, offset - start, value);
4154 offset += get_sb4_custom(tvb, offset, &v); /* flags */
4155 if ( key )
4156 proto_item_append_text(par_ti, ": %s = %s", key, value ? value : "");
4157 proto_item_set_len(par_ti, offset - par_start);
4158 }
4159 }
4160 else if ( oci_id == TTI_FETCH5 )
4161 {
4162 /* TTI_FETCH: fetch more rows from an open cursor.
4163 * [TTI_FUN, TTI_FETCH, seq] then cursor id and the row
4164 * count, both ub4. */
4165 int v = 0, start;
4166
4167 start = offset;
4168 offset += get_sb4_custom(tvb, offset, &v);
4169 proto_tree_add_uint(data_tree, hf_tns_cursor, tvb, start, offset - start, v);
4170 start = offset;
4171 offset += get_sb4_custom(tvb, offset, &v);
4172 proto_tree_add_uint(data_tree, hf_tns_data_fetch_rows, tvb, start, offset - start, v);
4173 }
4174 else if ( oci_id == TTI_PIPELINE_END200 )
4175 {
4176 /* ends a pipeline begun by the pipeline-begin piggyback: a
4177 * ub4 id, unused */
4178 int v = 0;
4179 offset += get_sb4_custom(tvb, offset, &v);
4180 }
4181 else if ( oci_id == TTI_SESSION_RELEASE163 )
4182 {
4183 /* DRCP: hand the session back to the pool - a tag name
4184 * (a pointer and a length byte) and the release mode */
4185 int v = 0, start;
4186 uint8_t tag_ptr = tvb_get_uint8(tvb, offset);
4187 uint8_t tag_len = tvb_get_uint8(tvb, offset + 1);
4188 offset += 2;
4189 if ( tag_ptr && tag_len > 0 )
4190 {
4191 proto_tree_add_item(data_tree, hf_tns_data_release_tag, tvb, offset, tag_len, ENC_UTF_80x00000002);
4192 offset += tag_len;
4193 }
4194 start = offset;
4195 offset += get_sb4_custom(tvb, offset, &v);
4196 proto_tree_add_bitmask_value(data_tree, tvb, start, hf_tns_data_release_mode,
4197 ett_tns_release_mode, tns_release_modes, (uint64_t)(uint32_t)v);
4198 }
4199 else if ( oci_id == TTI_TPC_TXN_SWITCH103 || oci_id == TTI_TPC_TXN_CHANGE_STATE104 )
4200 offset = dissect_tns_tpc_call(tvb, pinfo, data_tree, offset, oci_id);
4201 else if ( oci_id == TTI_REEXECUTE4 || oci_id == TTI_REEXECUTE_AND_FETCH78 )
4202 {
4203 /* Re-execute of a cursor whose statement already ran and
4204 * whose bind types did not change: the cursor id, the
4205 * iteration count (the prefetch size for 78, the number
4206 * of executions for 4) and two options words, then one
4207 * TTI_RXD row of values per iteration with no bind
4208 * descriptors - the values are typed by the execute that
4209 * opened the cursor. */
4210 int v = 0, cursor = 0, start;
4211
4212 start = offset;
4213 offset += get_sb4_custom(tvb, offset, &cursor);
4214 proto_tree_add_uint(data_tree, hf_tns_cursor, tvb, start, offset - start, cursor);
4215 start = offset;
4216 offset += get_sb4_custom(tvb, offset, &v);
4217 proto_tree_add_uint(data_tree, oci_id == TTI_REEXECUTE_AND_FETCH78 ?
4218 hf_tns_data_all8_prefetch : hf_tns_data_reexec_iterations,
4219 tvb, start, offset - start, v);
4220 start = offset;
4221 offset += get_sb4_custom(tvb, offset, &v);
4222 proto_tree_add_bitmask_value(data_tree, tvb, start, hf_tns_data_all8_options,
4223 ett_tns_all8_options, tns_all8_options, (uint64_t)(uint32_t)v);
4224 start = offset;
4225 offset += get_sb4_custom(tvb, offset, &v);
4226 proto_tree_add_bitmask_value(data_tree, tvb, start, hf_tns_data_reexec_options2,
4227 ett_tns_reexec_options2, tns_reexec_options2, (uint64_t)(uint32_t)v);
4228
4229 tns_binds_t *binds = tns_lookup_cursor_binds(pinfo, cursor);
4230 if ( binds && tvb_reported_length_remaining(tvb, offset) > 0 )
4231 {
4232 proto_item *binds_item;
4233 proto_tree *binds_tree;
4234 int binds_start = offset;
4235
4236 binds_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1,
4237 ett_tns_binds, &binds_item, "Binds");
4238 /* RETURNING ... INTO binds send no value */
4239 offset = dissect_tns_bind_rows(tvb, pinfo, binds_tree, offset, binds->cols,
4240 binds->count - binds->num_return);
4241 proto_item_set_len(binds_item, offset - binds_start);
4242 }
4243 if ( call && binds )
4244 {
4245 call->num_binds = binds->count;
4246 call->num_return = binds->num_return;
4247 call->binds = binds->cols;
4248 }
4249 }
4250 else if ( oci_id == TTI_ALL894 && tvb_bytes_exist(tvb, fun_start + TNS_OCI_ALL8_IND11, 8)
4251 && tvb_get_ntoh64(tvb, fun_start + TNS_OCI_ALL8_IND11) == TNS_OCI_INDICATOR0xfeffffffffffffffUL )
4252 {
4253 /* An OCI client's execute (sqlplus and other thick
4254 * clients): a fixed preamble of 8-byte pointer indicators
4255 * FE FF FF FF FF FF FF FF with little-endian scalar slots
4256 * between them, and the ub1-length-prefixed SQL at the
4257 * end. Offsets count from the TTI_FUN byte. The scalar
4258 * slots are 8 bytes wide or 4, fixed for a connection;
4259 * the second indicator tells which - it sits at 27 in the
4260 * wide form and 23 in the narrow one, and the two cannot
4261 * both hold. The cursor id and SQL length precede every
4262 * slot and do not move; the bind count and the SQL do. */
4263 int base = fun_start, bind_count_off, sql_off;
4264 uint32_t cursor, sql_len, bind_count;
4265 bool_Bool wide;
4266
4267 if ( tvb_bytes_exist(tvb, base + TNS_OCI_ALL8_IND2_WIDE27, 8)
4268 && tvb_get_ntoh64(tvb, base + TNS_OCI_ALL8_IND2_WIDE27) == TNS_OCI_INDICATOR0xfeffffffffffffffUL )
4269 wide = true1;
4270 else if ( tvb_bytes_exist(tvb, base + TNS_OCI_ALL8_IND2_NARROW23, 8)
4271 && tvb_get_ntoh64(tvb, base + TNS_OCI_ALL8_IND2_NARROW23) == TNS_OCI_INDICATOR0xfeffffffffffffffUL )
4272 wide = false0;
4273 else
4274 break;
4275 if ( !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
4276 tns_get_conv_info(pinfo)->oci_dialect = true1;
4277
4278 proto_tree_add_string(data_tree, hf_tns_data_all8_oci_preamble, tvb, base, 0,
4279 wide ? "OCI, wide (8-byte slots)" : "OCI, narrow (4-byte slots)");
4280 cursor = tvb_get_letohl(tvb, base + TNS_OCI_ALL8_CURSOR7);
4281 proto_tree_add_uint(data_tree, hf_tns_cursor, tvb, base + TNS_OCI_ALL8_CURSOR7, 4, cursor);
4282 /* three times the SQL length */
4283 sql_len = tvb_get_letohl(tvb, base + TNS_OCI_ALL8_SQLLEN319) / 3;
4284 bind_count_off = base + (wide ? 83 : 71);
4285 sql_off = base + (wide ? 196 : 176);
4286 bind_count = tvb_get_letohl(tvb, bind_count_off);
4287 proto_tree_add_uint(data_tree, hf_tns_data_all8_bind_count, tvb, bind_count_off, 4, bind_count);
4288 if ( sql_len > 0 && tvb_bytes_exist(tvb, sql_off - 1, 1) )
4289 {
4290 const char *sql = NULL((void*)0);
4291 int start = sql_off - 1;
4292 uint8_t prefix = tvb_get_uint8(tvb, start);
4293
4294 if ( prefix == 0xfe || prefix == sql_len )
4295 {
4296 offset = start + get_dalc_custom(tvb, pinfo, start, &sql);
4297 if ( sql )
4298 {
4299 /* sqlplus NUL-terminates its own queries; the
4300 * string ends there */
4301 proto_tree_add_string(data_tree, hf_tns_data_all8_sql, tvb, start, offset - start, sql);
4302 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", sql);
4303 }
4304 }
4305 }
4306 }
4307 else if ( oci_id == TTI_ALL894 )
4308 {
4309 /* TTI_ALL8: the generic SQL execute — SELECT, DML and
4310 * PL/SQL all ride this call, in the Oracle 11g shape of a
4311 * thin client, whose integers use the ub4 variable-length
4312 * form. The bind (or define) descriptors and the value
4313 * rows follow the al8 array. */
4314 int v = 0, options = 0, cursor = 0, query_len = 0, all8_len = 0;
4315 int fetch = 0, bind_count = 0, define_count = 0, start;
4316 const uint8_t *sql = NULL((void*)0);
4317 uint8_t query_flag;
4318
4319 /* options (ub4) + flag breakdown */
4320 start = offset;
4321 offset += get_sb4_custom(tvb, offset, &options);
4322 proto_tree_add_bitmask_value(data_tree, tvb, start, hf_tns_data_all8_options,
4323 ett_tns_all8_options, tns_all8_options, (uint64_t)(uint32_t)options);
4324 /* cursor id (ub4) */
4325 start = offset;
4326 offset += get_sb4_custom(tvb, offset, &cursor);
4327 proto_tree_add_uint(data_tree, hf_tns_cursor, tvb, start, offset - start, cursor);
4328 /* query present flag (ub1) */
4329 query_flag = tvb_get_uint8(tvb, offset);
4330 offset += 1;
4331 /* query length (ub4) */
4332 offset += get_sb4_custom(tvb, offset, &query_len);
4333 /* all8 present flag (ub1) */
4334 offset += 1;
4335 /* all8 length (ub4) */
4336 offset += get_sb4_custom(tvb, offset, &all8_len);
4337 /* two reserved bytes */
4338 offset += 2;
4339 /* long max value (ub4, skip) */
4340 offset += get_sb4_custom(tvb, offset, &v);
4341 /* fetch rows (ub4) */
4342 start = offset;
4343 offset += get_sb4_custom(tvb, offset, &fetch);
4344 proto_tree_add_uint(data_tree, hf_tns_data_all8_fetch_rows, tvb, start, offset - start, fetch);
4345 /* max value (ub4, skip) */
4346 offset += get_sb4_custom(tvb, offset, &v);
4347 /* bind indicator (ub1) */
4348 offset += 1;
4349 /* bind count (ub4) */
4350 start = offset;
4351 offset += get_sb4_custom(tvb, offset, &bind_count);
4352 proto_tree_add_uint(data_tree, hf_tns_data_all8_bind_count, tvb, start, offset - start, bind_count);
4353 /* The count comes off the wire and sizes an allocation
4354 * further down, so a count larger than the data left
4355 * cannot be real - report it and decode no binds. */
4356 if ( bind_count < 0 ||
4357 (unsigned)bind_count > tvb_reported_length_remaining(tvb, offset) )
4358 {
4359 proto_tree_add_expert(data_tree, pinfo, &ei_tns_data_count_too_large,
4360 tvb, start, offset - start);
4361 bind_count = 0;
4362 }
4363 /* five reserved bytes */
4364 offset += 5;
4365 /* define-columns present flag (ub1) */
4366 offset += 1;
4367 /* define-columns count (ub4) */
4368 start = offset;
4369 offset += get_sb4_custom(tvb, offset, &define_count);
4370 proto_tree_add_uint(data_tree, hf_tns_data_all8_define_count, tvb, start, offset - start, define_count);
4371 if ( define_count < 0 ||
4372 (unsigned)define_count > tvb_reported_length_remaining(tvb, offset) )
4373 {
4374 proto_tree_add_expert(data_tree, pinfo, &ei_tns_data_count_too_large,
4375 tvb, start, offset - start);
4376 define_count = 0;
4377 }
4378 /* registration id (low half), the al8objlist / al8objlen /
4379 * al8blv pointers, al8blvl, the al8dnam pointer, al8dnaml
4380 * and the registration id's high half */
4381 offset += get_sb4_custom(tvb, offset, &v);
4382 offset += 3;
4383 offset += get_sb4_custom(tvb, offset, &v);
4384 offset += 1;
4385 offset += get_sb4_custom(tvb, offset, &v);
4386 offset += get_sb4_custom(tvb, offset, &v);
4387 /* 12.1 adds the per-row DML count block (a pointer, the
4388 * execution count, a pointer), 12.2 the SQL signature and
4389 * SQL id fields, 12.2 ext 1 the chunk ids */
4390 unsigned fv = tns_field_version(pinfo);
4391 if ( fv >= TNS_FV_12_17 )
4392 {
4393 offset += 1;
4394 offset += get_sb4_custom(tvb, offset, &v);
4395 offset += 1;
4396 }
4397 if ( fv >= TNS_FV_12_28 )
4398 {
4399 offset += 1;
4400 offset += get_sb4_custom(tvb, offset, &v);
4401 offset += 1;
4402 offset += get_sb4_custom(tvb, offset, &v);
4403 offset += 1;
4404 }
4405 if ( fv >= TNS_FV_12_2_EXT19 )
4406 {
4407 offset += 1;
4408 offset += get_sb4_custom(tvb, offset, &v);
4409 }
4410 /* SQL text: a flat run of query_len bytes on 11g, length
4411 * prefixed (and chunked when long) from 12.1 */
4412 if ( query_flag && query_len > 0 && fv >= TNS_FV_12_17 )
4413 {
4414 const char *text = NULL((void*)0);
4415 start = offset;
4416 offset += get_dalc_custom(tvb, pinfo, offset, &text);
4417 if ( text )
4418 {
4419 sql = (const uint8_t *)text;
4420 proto_tree_add_string(data_tree, hf_tns_data_all8_sql, tvb, start, offset - start, text);
4421 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", text);
4422 }
4423 }
4424 else if ( query_flag && query_len > 0 )
4425 {
4426 proto_tree_add_item_ret_string(data_tree, hf_tns_data_all8_sql, tvb,
4427 offset, query_len, ENC_UTF_80x00000002|ENC_NA0x00000000, pinfo->pool, &sql);
4428 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", sql);
4429 offset += query_len;
4430 }
4431 /* al8i4 option array: all8_len ub4 elements. Slot 1 is
4432 * the execution count for DML but the number of rows to
4433 * prefetch for a query, and slot 7 says which - so read
4434 * the array before showing any of it. */
4435 {
4436 int al8i4[13] = {0}, al8i4_start[13] = {0}, al8i4_len[13] = {0};
4437 int i4_start = offset;
4438 proto_tree *i4_tree;
4439 proto_item *i4_item;
4440
4441 for ( int i = 0; i < all8_len && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
4442 {
4443 start = offset;
4444 offset += get_sb4_custom(tvb, offset, &v);
4445 if ( i < (int)array_length(al8i4)(sizeof (al8i4) / sizeof (al8i4)[0]) )
4446 {
4447 al8i4[i] = v;
4448 al8i4_start[i] = start;
4449 al8i4_len[i] = offset - start;
4450 }
4451 }
4452 if ( all8_len >= (int)array_length(al8i4)(sizeof (al8i4) / sizeof (al8i4)[0]) )
4453 {
4454 i4_tree = proto_tree_add_subtree(data_tree, tvb, i4_start, offset - i4_start,
4455 ett_tns_all8_i4, &i4_item, "Execute Arguments (al8i4)");
4456 proto_tree_add_uint(i4_tree, al8i4[7] ? hf_tns_data_all8_prefetch : hf_tns_data_all8_iterations,
4457 tvb, al8i4_start[1], al8i4_len[1], al8i4[1]);
4458 proto_tree_add_boolean(i4_tree, hf_tns_data_all8_is_query,
4459 tvb, al8i4_start[7], al8i4_len[7], al8i4[7]);
4460 proto_tree_add_bitmask_value(i4_tree, tvb, al8i4_start[9], hf_tns_data_all8_exec_flags,
4461 ett_tns_all8_exec_flags, tns_all8_exec_flags, (uint64_t)(uint32_t)al8i4[9]);
4462 proto_tree_add_uint(i4_tree, hf_tns_data_all8_fetch_orientation,
4463 tvb, al8i4_start[10], al8i4_len[10], al8i4[10]);
4464 proto_tree_add_uint(i4_tree, hf_tns_data_all8_fetch_pos,
4465 tvb, al8i4_start[11], al8i4_len[11], al8i4[11]);
4466 if ( call )
4467 call->exec_flags = (uint32_t)al8i4[9];
4468 }
4469 }
4470
4471 /* Bind section: one bare OAC descriptor per bind column,
4472 * then one TTI_RXD row of values per iteration. A cached
4473 * re-execute may leave the descriptors out and rely on
4474 * the ones the cursor was opened with. Whether they are
4475 * there is decided by the wire, not by the SQL text: an
4476 * execute with no SQL often still carries them (every
4477 * executemany after the first), and they are absent
4478 * exactly when the bind area starts on a TTI_RXD, in
4479 * which case the types remembered for the cursor apply.
4480 *
4481 * An execute that opens a new cursor (cursor id 0) learns
4482 * its id only from the status that answers it, so its
4483 * bind types wait for that. */
4484 tns_conv_info_t *tns_info = NULL((void*)0);
4485 if ( !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
4486 {
4487 tns_info = tns_get_conv_info(pinfo);
4488 if ( cursor == 0 )
4489 tns_info->pending_binds = NULL((void*)0);
4490 }
4491 if ( bind_count > 0 && tvb_reported_length_remaining(tvb, offset) > 0
4492 && tvb_get_uint8(tvb, offset) == SQLNET_ROW_TRANSF_DATA7 )
4493 {
4494 tns_binds_t *binds = cursor ? tns_lookup_cursor_binds(pinfo, cursor) : NULL((void*)0);
4495 if ( binds && binds->count == (uint32_t)bind_count )
4496 {
4497 if ( call )
4498 {
4499 call->num_binds = binds->count;
4500 call->num_return = binds->num_return;
4501 call->binds = binds->cols;
4502 }
4503 proto_item *binds_item;
4504 proto_tree *binds_tree;
4505 int binds_start = offset;
4506
4507 binds_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1,
4508 ett_tns_binds, &binds_item, "Binds");
4509 offset = dissect_tns_bind_rows(tvb, pinfo, binds_tree, offset, binds->cols,
4510 binds->count - binds->num_return);
4511 proto_item_set_len(binds_item, offset - binds_start);
4512 }
4513 }
4514 else if ( bind_count > 0 && tvb_reported_length_remaining(tvb, offset) > 0 )
4515 {
4516 proto_tree *binds_tree, *bind_tree;
4517 proto_item *binds_item, *bind_item;
4518 int binds_start = offset;
4519 tns_column_t *bcols;
4520
4521 bcols = wmem_alloc0_array(tns_info ? wmem_file_scope() : pinfo->pool, tns_column_t, bind_count)((tns_column_t*)wmem_alloc0((tns_info ? wmem_file_scope() : pinfo
->pool), (((((bind_count)) <= 0) || ((size_t)sizeof(tns_column_t
) > (9223372036854775807L / (size_t)((bind_count))))) ? 0 :
(sizeof(tns_column_t) * ((bind_count))))))
;
4522 binds_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1,
4523 ett_tns_binds, &binds_item, "Binds");
4524
4525 for ( int i = 0; i < bind_count && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
4526 {
4527 int b_start = offset;
4528 uint8_t btype = tvb_get_uint8(tvb, offset);
4529 bind_tree = proto_tree_add_subtree_format(binds_tree, tvb, offset, -1,
4530 ett_tns_bind, &bind_item, "Bind %d: %s", i + 1,
4531 val_to_str_const(btype, tns_data_types, "unknown"));
4532 offset = dissect_tns_oac(tvb, pinfo, bind_tree, offset, &bcols[i]);
4533 /* Below 12.2 a CLOB/BLOB bind OAC still carries a
4534 * trailing oaccolid byte; from 12.2 every OAC does,
4535 * and the OAC decoder reads it. */
4536 if ( (btype == TNS_DATATYPE_CLOB112 || btype == TNS_DATATYPE_BLOB113)
4537 && tns_field_version(pinfo) < TNS_FV_12_28 )
4538 offset += 1;
4539 proto_item_set_len(bind_item, offset - b_start);
4540 }
4541
4542 /* A DML RETURNING ... INTO statement sends no values for
4543 * its return binds, the last ones. */
4544 unsigned num_return = sql ? tns_count_return_binds((const char *)sql) : 0;
4545 if ( num_return > (unsigned)bind_count )
4546 num_return = 0;
4547
4548 if ( call )
4549 {
4550 call->num_binds = bind_count;
4551 call->num_return = num_return;
4552 call->binds = bcols;
4553 }
4554
4555 /* Remember the types for later executes of the cursor
4556 * that leave the descriptors out. */
4557 if ( tns_info )
4558 {
4559 tns_binds_t *binds = wmem_new0(wmem_file_scope(), tns_binds_t)((tns_binds_t*)wmem_alloc0((wmem_file_scope()), sizeof(tns_binds_t
)))
;
4560 binds->count = bind_count;
4561 binds->num_return = num_return;
4562 binds->cols = bcols;
4563 if ( cursor != 0 )
4564 wmem_map_insert(tns_info->cursor_binds, GUINT_TO_POINTER(cursor)((gpointer) (gulong) (cursor)), binds);
4565 else
4566 tns_info->pending_binds = binds;
4567 }
4568
4569 /* Value rows: a TTI_RXD token then one DALC value per bind
4570 * column (an ordinary execute sends one row, executemany
4571 * sends N), decoded and rendered by the bind's type. */
4572 offset = dissect_tns_bind_rows(tvb, pinfo, binds_tree, offset, bcols, bind_count - num_return);
4573 proto_item_set_len(binds_item, offset - binds_start);
4574 }
4575
4576 /* Define section: a client that wants a column in some
4577 * other form than the describe gave - a CLOB as a string,
4578 * say - re-executes the cursor with the DEFINE option and
4579 * one OAC per column, in the bind OAC layout. It carries
4580 * no binds. */
4581 if ( define_count > 0 )
4582 {
4583 proto_tree *defs_tree, *def_tree;
4584 proto_item *defs_item, *def_item;
4585 int defs_start = offset;
4586 tns_column_t *dcols = NULL((void*)0);
4587
4588 if ( !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
4589 dcols = wmem_alloc0_array(pinfo->pool, tns_column_t, define_count)((tns_column_t*)wmem_alloc0((pinfo->pool), (((((define_count
)) <= 0) || ((size_t)sizeof(tns_column_t) > (9223372036854775807L
/ (size_t)((define_count))))) ? 0 : (sizeof(tns_column_t) * (
(define_count))))))
;
4590 defs_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1,
4591 ett_tns_defines, &defs_item, "Defines");
4592 for ( int i = 0; i < define_count && tvb_reported_length_remaining(tvb, offset) > 0; i++ )
4593 {
4594 int d_start = offset;
4595 uint8_t dtype = tvb_get_uint8(tvb, offset);
4596 def_tree = proto_tree_add_subtree_format(defs_tree, tvb, offset, -1,
4597 ett_tns_bind, &def_item, "Define %d: %s", i + 1,
4598 val_to_str_const(dtype, tns_data_types, "unknown"));
4599 offset = dissect_tns_oac(tvb, pinfo, def_tree, offset, dcols ? &dcols[i] : NULL((void*)0));
4600 proto_item_set_len(def_item, offset - d_start);
4601 }
4602 proto_item_set_len(defs_item, offset - defs_start);
4603
4604 /* The rows that answer a define come framed the way
4605 * it asked - a CLOB defined as LONG arrives inline,
4606 * with no locator - and so do the rows of every later
4607 * execute of the cursor. Rows are still split by the
4608 * describe's columns, so replace each column's type
4609 * with the one its define gives. */
4610 if ( tns_info && dcols && tns_info->last_describe
4611 && tns_info->last_describe->num_cols == (uint32_t)define_count )
4612 {
4613 tns_describe_t *desc = wmem_new0(wmem_file_scope(), tns_describe_t)((tns_describe_t*)wmem_alloc0((wmem_file_scope()), sizeof(tns_describe_t
)))
;
4614 desc->num_cols = define_count;
4615 desc->cols = (tns_column_t *)wmem_memdup(wmem_file_scope(),
4616 tns_info->last_describe->cols, define_count * sizeof(tns_column_t));
4617 for ( int i = 0; i < define_count; i++ )
4618 {
4619 desc->cols[i].type = dcols[i].type;
4620 desc->cols[i].csform = dcols[i].csform;
4621 }
4622 tns_info->last_describe = desc;
4623 }
4624 }
4625 }
4626 else if ( oci_id == TTI_LOBOPS96 )
4627 {
4628 /* TTI_LOBOPS: the LOB operation family (read, write, get
4629 * length, create/free temp, open/close, BFILE ops). One
4630 * common request layout selects behaviour by the operation
4631 * opcode:
4632 * ub1 source pointer | ub4 source locator length |
4633 * ub1 dest pointer | ub4 dest length |
4634 * ub4 short source offset | ub4 short dest offset |
4635 * ub1 charset pointer | ub1 short amount pointer |
4636 * ub1 null-LOB pointer | ub4 operation |
4637 * ub1 SCN array pointer | ub1 SCN array length |
4638 * ub8 source offset | ub8 dest offset |
4639 * ub1 amount pointer | 3 x ub2 array-LOB slots (fixed) |
4640 * [locator] | [ub4 charset, CREATE_TEMP] |
4641 * [0x0E and the data, WRITE] | [ub8 amount]
4642 * The locator is as long as the source locator length says;
4643 * a temporary LOB's carries its own ub2 length prefix, which
4644 * that length counts. */
4645 int v = 0, op = 0, loc_len = 0, start;
4646 uint8_t src_ptr, charset_ptr, amount_ptr;
4647 uint64_t u = 0;
4648
4649 src_ptr = tvb_get_uint8(tvb, offset);
4650 offset += 1; /* source pointer flag */
4651 offset += get_sb4_custom(tvb, offset, &loc_len); /* source locator length */
4652 offset += 1; /* dest pointer flag */
4653 offset += get_sb4_custom(tvb, offset, &v); /* dest length */
4654 offset += get_sb4_custom(tvb, offset, &v); /* short source offset */
4655 offset += get_sb4_custom(tvb, offset, &v); /* short dest offset */
4656 charset_ptr = tvb_get_uint8(tvb, offset);
4657 offset += 3; /* charset / amount / null-lob flags */
4658 /* operation opcode */
4659 start = offset;
4660 offset += get_sb4_custom(tvb, offset, &op);
4661 proto_tree_add_uint(data_tree, hf_tns_data_lob_op, tvb, start, offset - start, op);
4662 col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]",
4663 val_to_str_const(op, tns_lob_ops, "unknown"));
4664 /* scn-array pointer flag + length */
4665 offset += 2;
4666 /* source offset (ub8, 1-based into the LOB) */
4667 start = offset;
4668 offset += get_ub8_custom(tvb, offset, &u);
4669 proto_tree_add_uint64(data_tree, hf_tns_data_lob_offset, tvb, start, offset - start, u);
4670 /* dest offset (ub8, skip) */
4671 offset += get_ub8_custom(tvb, offset, &u);
4672 amount_ptr = tvb_get_uint8(tvb, offset);
4673 offset += 1; /* amount pointer flag */
4674 offset += 6; /* array-LOB slots */
4675 if ( src_ptr && loc_len > 0 )
4676 {
4677 proto_tree_add_item(data_tree, hf_tns_data_lob_locator, tvb, offset, loc_len, ENC_NA0x00000000);
4678 offset += loc_len;
4679 }
4680 if ( charset_ptr )
4681 {
4682 start = offset;
4683 offset += get_sb4_custom(tvb, offset, &v);
4684 proto_tree_add_uint(data_tree, hf_tns_data_lob_charset, tvb, start, offset - start, v);
4685 }
4686 if ( tvb_reported_length_remaining(tvb, offset) > 0
4687 && tvb_get_uint8(tvb, offset) == SQLNET_LOB_FILE_DF14 )
4688 {
4689 /* WRITE: a LOB_DATA marker, then the data */
4690 offset += 1;
4691 start = offset;
4692 offset += get_dalc_custom(tvb, pinfo, offset, NULL((void*)0));
4693 if ( tvb_get_uint8(tvb, start) == 0xfe ) /* chunked: shown whole */
4694 proto_tree_add_item(data_tree, hf_tns_data_lob_data, tvb, start, offset - start, ENC_NA0x00000000);
4695 else if ( offset - start > 1 )
4696 proto_tree_add_item(data_tree, hf_tns_data_lob_data, tvb, start + 1, offset - start - 1, ENC_NA0x00000000);
4697 }
4698 if ( amount_ptr )
4699 {
4700 start = offset;
4701 offset += get_ub8_custom(tvb, offset, &u);
4702 proto_tree_add_uint64(data_tree, hf_tns_data_lob_amount, tvb, start, offset - start, u);
4703 }
4704 if ( call )
4705 {
4706 call->lob_op = (uint32_t)op;
4707 call->lob_locator_len = src_ptr ? (uint32_t)loc_len : 0;
4708 call->lob_amount = amount_ptr != 0;
4709 }
4710 }
4711 break;
4712 }
4713 case SQLNET_RETURN_OPI_PARAM8:
4714 {
4715 uint8_t skip = 0, opi = 0;
4716
4717 if ( tvb_bytes_exist(tvb, offset, 11) )
4718 {
4719 /*
4720 * OPI_VERSION2 response has a following pattern:
4721 *
4722 * _ banner _ vsnum
4723 * / /
4724 * ..(.?)(Orac[le.+])(.?)(....).+$
4725 * |
4726 * \ banner length (if equal to 0 then next byte indicates the length).
4727 *
4728 * These differences (to skip 1 or 2 bytes) due to differences in the drivers.
4729 */
4730 /* Orac[le.+] */
4731 if ( tvb_get_ntohl(tvb, offset+2) == 0x4f726163 )
4732 {
4733 opi = OPI_VERSION21;
4734 skip = 1;
4735 }
4736
4737 else if ( tvb_get_ntohl(tvb, offset+3) == 0x4f726163 )
4738 {
4739 opi = OPI_VERSION21;
4740 skip = 2;
4741 }
4742
4743 /*
4744 * OPI_OSESSKEY response has a following pattern:
4745 *
4746 * _ pattern (v1|v2)
4747 * / _ params
4748 * / /
4749 * (....)(........)(.+).+$
4750 * ||
4751 * \ if these two bytes are equal to 0x0c00 then first byte is <Param Counts> (v1),
4752 * else next byte indicate it (v2).
4753 */
4754 /* ....AUTH (v1) */
4755 else if ( tvb_get_ntoh64(tvb, offset+3) == 0x0000000c41555448 )
4756 {
4757 opi = OPI_OSESSKEY2;
4758 skip = 1;
4759 }
4760 /* ..AUTH_V (v2) */
4761 else if ( tvb_get_ntoh64(tvb, offset+3) == 0x0c0c415554485f53 )
4762 {
4763 opi = OPI_OSESSKEY2;
4764 skip = 2;
4765 }
4766
4767 /*
4768 * OPI_OAUTH response has a following pattern:
4769 *
4770 * _ pattern (v1|v2)
4771 * / _ params
4772 * / /
4773 * (....)(........)(.+).+$
4774 * ||
4775 * \ if these two bytes are equal to 0x1300 then first byte is <Param Counts> (v1),
4776 * else next byte indicate it (v2).
4777 */
4778
4779 /* ....AUTH (v1) */
4780 else if ( tvb_get_ntoh64(tvb, offset+3) == 0x0000001341555448 )
4781 {
4782 opi = OPI_OAUTH3;
4783 skip = 1;
4784 }
4785 /* ..AUTH_V (v2) */
4786 else if ( tvb_get_ntoh64(tvb, offset+3) == 0x1313415554485f56 )
4787 {
4788 opi = OPI_OAUTH3;
4789 skip = 2;
4790 }
4791 }
4792
4793 if ( opi == OPI_VERSION21 )
4794 {
4795 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, skip, ENC_NA0x00000000);
4796 offset += skip;
4797
4798 uint8_t len = tvb_get_uint8(tvb, offset);
4799
4800 proto_tree_add_item(data_tree, hf_tns_data_opi_version2_banner_len, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4801 offset += 1;
4802
4803 proto_tree_add_item(data_tree, hf_tns_data_opi_version2_banner, tvb, offset, len, ENC_ASCII0x00000000);
4804 offset += len + (skip == 1 ? 1 : 0);
4805
4806 proto_tree_add_item(data_tree, hf_tns_data_opi_version2_vsnum, tvb, offset, 4, (skip == 1) ? ENC_BIG_ENDIAN0x00000000 : ENC_LITTLE_ENDIAN0x80000000);
4807 offset += 4;
4808 }
4809 else if ( opi == OPI_OSESSKEY2 || opi == OPI_OAUTH3 )
4810 {
4811 proto_tree *params_tree;
4812 proto_item *params_ti;
4813 unsigned par, params;
4814
4815 if ( skip == 1 )
4816 {
4817 proto_tree_add_item_ret_uint(data_tree, hf_tns_data_opi_num_of_params, tvb, offset, 1, ENC_NA0x00000000, &params);
4818 offset += 1;
4819
4820 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, 5, ENC_NA0x00000000);
4821 offset += 5;
4822 }
4823 else
4824 {
4825 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, 1, ENC_NA0x00000000);
4826 offset += 1;
4827
4828 proto_tree_add_item_ret_uint(data_tree, hf_tns_data_opi_num_of_params, tvb, offset, 1, ENC_NA0x00000000, &params);
4829 offset += 1;
4830
4831 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, 2, ENC_NA0x00000000);
4832 offset += 2;
4833 }
4834
4835 params_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1, ett_tns_opi_params, &params_ti, "Parameters");
4836
4837 for ( par = 1; par <= params; par++ )
4838 {
4839 proto_tree *par_tree;
4840 proto_item *par_ti;
4841 unsigned len, offset_prev;
4842
4843 par_tree = proto_tree_add_subtree(params_tree, tvb, offset, -1, ett_tns_opi_par, &par_ti, "Parameter");
4844 proto_item_append_text(par_ti, " %u", par);
4845
4846 /* Name length */
4847 proto_tree_add_item_ret_uint(par_tree, hf_tns_data_opi_param_length, tvb, offset, 1, ENC_NA0x00000000, &len);
4848 offset += 1;
4849
4850 /* Name */
4851 if ( !(len == 0 || len == 2) ) /* Not empty (2 - SQLDeveloper specific sign). */
4852 {
4853 proto_tree_add_item(par_tree, hf_tns_data_opi_param_name, tvb, offset, len, ENC_ASCII0x00000000);
4854 offset += len;
4855 }
4856
4857 /* Value can be NULL. So, save offset to calculate unused data. */
4858 offset_prev = offset;
4859 offset += skip == 1 ? 4 : 2;
4860
4861 /* Value length */
4862 if ( opi == OPI_OSESSKEY2 )
4863 {
4864 len = get_strtype_custom(tvb, pinfo, par_tree, offset);
4865 }
4866 else /* OPI_OAUTH */
4867 {
4868 len = tvb_get_uint8(tvb, offset_prev) == 0 ? 0 : get_strtype_custom(tvb, pinfo, par_tree, offset);
4869 }
4870
4871 /*
4872 * Value
4873 * OPI_OSESSKEY: AUTH_VFR_DATA with length 0, 9, 0x39 comes without data.
4874 * OPI_OAUTH: AUTH_VFR_DATA with length 0, 0x39 comes without data.
4875 */
4876 if ( ((opi == OPI_OSESSKEY2) && !(len == 0 || len == 9 || len == 0x39))
4877 || ((opi == OPI_OAUTH3) && !(len == 0 || len == 0x39)) )
4878 {
4879 proto_tree_add_item(par_tree, hf_tns_data_unused, tvb, offset_prev, offset - offset_prev, ENC_NA0x00000000);
4880 offset += len;
4881
4882 offset_prev = offset; /* Save offset to calculate rest of unused data */
4883 }
4884 else
4885 {
4886 offset += 1;
4887 }
4888
4889 if ( opi == OPI_OSESSKEY2 )
4890 {
4891 /* SQL Developer specific fix */
4892 offset += tvb_get_uint8(tvb, offset) == 2 ? 5 : 3;
4893 }
4894 else /* OPI_OAUTH */
4895 {
4896 offset += len == 0 ? 1 : 3;
4897 }
4898
4899 if ( skip == 1 )
4900 {
4901 offset += 1 + ((len == 0 || len == 0x39) ? 3 : 4);
4902
4903 if ( opi == OPI_OAUTH3 )
4904 {
4905 offset += len == 0 ? 2 : 0;
4906 }
4907 }
4908
4909 proto_tree_add_item(par_tree, hf_tns_data_unused, tvb, offset_prev, offset - offset_prev, ENC_NA0x00000000);
4910 proto_item_set_end(par_ti, tvb, offset);
4911 }
4912 proto_item_set_end(params_ti, tvb, offset);
4913 }
4914 else if ( !is_request )
4915 {
4916 /* Not an authentication reply: an execute answers with
4917 * its return parameters. */
4918 tns_call_t *call = tns_answered_call(pinfo);
4919 if ( call && (call->func == TTI_ALL894 || call->func == TTI_REEXECUTE4
4920 || call->func == TTI_REEXECUTE_AND_FETCH78) )
4921 {
4922 offset = dissect_tns_return_params(tvb, pinfo, data_tree, offset,
4923 (call->exec_flags & TNS_EXEC_FLAGS_DML_ROWCOUNTS0x4000) != 0);
4924 ctx->walk = true1;
4925 }
4926 else if ( call && call->func == TTI_TPC_TXN_SWITCH103 )
4927 {
4928 /* the application value and the transaction context
4929 * (a ub2 length and the bytes) */
4930 int v = 0, len = 0, start = offset;
4931 offset += get_sb4_custom(tvb, offset, &v);
4932 proto_tree_add_uint(data_tree, hf_tns_data_tpc_app_value, tvb, start, offset - start, v);
4933 offset += get_sb4_custom(tvb, offset, &len);
4934 if ( len > 0 )
4935 {
4936 proto_tree_add_item(data_tree, hf_tns_data_tpc_context, tvb, offset, len, ENC_NA0x00000000);
4937 offset += len;
4938 }
4939 ctx->walk = true1;
4940 }
4941 else if ( call && call->func == TTI_TPC_TXN_CHANGE_STATE104 )
4942 {
4943 int v = 0, start = offset;
4944 offset += get_sb4_custom(tvb, offset, &v);
4945 proto_tree_add_uint(data_tree, hf_tns_data_tpc_state, tvb, start, offset - start, v);
4946 ctx->walk = true1;
4947 }
4948 else if ( call && call->func == TTI_LOBOPS96 )
4949 {
4950 /* A LOB operation's reply: the locator as the server
4951 * now sees it - as long as the one sent, and changed
4952 * by a mutating call - then per operation the new
4953 * temporary LOB's charset, the amount, or a boolean. */
4954 uint64_t u = 0;
4955 int start;
4956
4957 if ( call->lob_locator_len > 0 )
4958 {
4959 proto_tree_add_item(data_tree, hf_tns_data_lob_locator, tvb, offset,
4960 call->lob_locator_len, ENC_NA0x00000000);
4961 offset += call->lob_locator_len;
4962 }
4963 if ( call->lob_op == TNS_LOB_OP_CREATE_TEMP0x00110 )
4964 {
4965 int v = 0;
4966 start = offset;
4967 offset += get_sb4_custom(tvb, offset, &v);
4968 proto_tree_add_uint(data_tree, hf_tns_data_lob_charset, tvb, start, offset - start, v);
4969 offset += 1; /* trailing flags */
4970 }
4971 else if ( call->lob_amount )
4972 {
4973 start = offset;
4974 offset += get_ub8_custom(tvb, offset, &u);
4975 proto_tree_add_uint64(data_tree, hf_tns_data_lob_amount, tvb, start, offset - start, u);
4976 }
4977 if ( call->lob_op == TNS_LOB_OP_IS_OPEN0x11000 || call->lob_op == TNS_LOB_OP_FILE_EXISTS0x00800
4978 || call->lob_op == TNS_LOB_OP_FILE_ISOPEN0x00400 )
4979 {
4980 proto_tree_add_item(data_tree, hf_tns_data_lob_flag, tvb, offset, 1, ENC_NA0x00000000);
4981 offset += 1;
4982 }
4983 ctx->walk = true1;
4984 }
4985 }
4986 break;
4987 }
4988
4989 case SQLNET_PIGGYBACK_FUNC17:
4990 {
4991 int cursors_len = 0;
4992 int cursors_start;
4993 uint8_t piggyback_id = tvb_get_uint8(tvb, offset);
4994 proto_tree_add_item(data_tree, hf_tns_data_piggyback_id, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4995 offset += 1;
4996 proto_tree_add_item(data_tree, hf_tns_data_tseq, tvb, offset, 1, ENC_BIG_ENDIAN0x00000000);
4997 offset += 1;
4998 offset = dissect_tns_call_token(tvb, pinfo, data_tree, offset);
4999 /* Only the close-cursors piggyback carries a cursor list:
5000 * a pointer byte, a ub4 count, then that many ub4 cursor
5001 * ids. The other piggybacks have bodies of their own. */
5002 if ( piggyback_id != TTI_CLOSE_CURSORS105 )
5003 {
5004 offset = dissect_tns_piggyback_body(tvb, pinfo, data_tree, offset, piggyback_id, &ctx->walk);
5005 break;
5006 }
5007 offset += 1; /* pointer */
5008 cursors_start = offset;
5009 offset += get_sb4_custom(tvb, offset, &cursors_len);
5010 /* The count comes off the wire and every cursor takes at
5011 * least one byte, so a count larger than the data left
5012 * cannot be real. Say so and stop, rather than looping on
5013 * a number somebody else chose. */
5014 if ( cursors_len < 0 ||
5015 (unsigned)cursors_len > tvb_reported_length_remaining(tvb, offset) )
5016 {
5017 proto_tree_add_expert(data_tree, pinfo, &ei_tns_data_piggyback_cursors,
5018 tvb, cursors_start, offset - cursors_start);
5019 break;
5020 }
5021 for(int i = 0; i < cursors_len; i++) {
5022 int cursor = 0;
5023 int len = get_sb4_custom(tvb, offset, &cursor);
5024 proto_tree_add_uint(data_tree, hf_tns_cursor, tvb, offset, len, cursor);
5025 offset += len;
5026 }
5027 /* The call this piggyback rides in front of follows it. */
5028 ctx->walk = true1;
5029 break;
5030 }
5031 case SQLNET_SNS0xdeadbeef:
5032 {
5033 proto_tree_add_item(data_tree, hf_tns_data_id, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
5034 offset += 4;
5035 proto_tree_add_item(data_tree, hf_tns_data_length, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5036 offset += 2;
5037
5038 if ( is_request )
5039 {
5040 proto_tree_add_item(data_tree, hf_tns_data_sns_cli_vers, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
5041 }
5042 else
5043 {
5044 proto_tree_add_item(data_tree, hf_tns_data_sns_srv_vers, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
5045 }
5046 offset += 4;
5047
5048 uint16_t num_services = tvb_get_ntohs(tvb, offset);
5049 proto_tree_add_item(data_tree, hf_tns_data_sns_srvcnt, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5050 /* With encryption picked, the client's next negotiation packet
5051 * - its Diffie-Hellman public key - is the last in the clear. */
5052 if ( is_request && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) )
5053 {
5054 tns_conv_info_t *tns_info = tns_get_conv_info(pinfo);
5055 if ( tns_info->ano_encryption && !tns_info->ano_active_after )
5056 tns_info->ano_active_after = pinfo->num;
5057 }
5058 offset += 2;
5059 proto_tree_add_item(data_tree, hf_tns_data_sns_error, tvb, offset, 1, ENC_NA0x00000000);
5060 offset += 1;
5061
5062 /* Each service: a type, a sub-packet count and an error, then
5063 * the sub-packets, each a length, a type and that many bytes
5064 * of payload - all big-endian. A service opens with its
5065 * version; in the encryption and integrity services the
5066 * sub-packet after it lists the algorithms a client offers,
5067 * or holds the one the server picked. */
5068 for ( unsigned i = 0; i < num_services && tvb_bytes_exist(tvb, offset, 8); i++ )
5069 {
5070 proto_tree *svc_tree;
5071 proto_item *svc_item;
5072 int svc_start = offset;
5073 uint16_t svc_type = tvb_get_ntohs(tvb, offset);
5074 uint16_t num_sub = tvb_get_ntohs(tvb, offset + 2);
5075
5076 svc_tree = proto_tree_add_subtree_format(data_tree, tvb, offset, -1, ett_tns_sns_service,
5077 &svc_item, "Service: %s", val_to_str_const(svc_type, tns_sns_services, "unknown"));
5078 proto_tree_add_item(svc_tree, hf_tns_data_sns_service, tvb, offset, 2, ENC_BIG_ENDIAN0x00000000);
5079 proto_tree_add_item(svc_tree, hf_tns_data_sns_subpackets, tvb, offset + 2, 2, ENC_BIG_ENDIAN0x00000000);
5080 proto_tree_add_item(svc_tree, hf_tns_data_sns_svc_error, tvb, offset + 4, 4, ENC_BIG_ENDIAN0x00000000);
5081 offset += 8;
5082 for ( unsigned j = 0; j < num_sub && tvb_bytes_exist(tvb, offset, 4); j++ )
5083 {
5084 uint16_t len = tvb_get_ntohs(tvb, offset);
5085 uint16_t sub_type = tvb_get_ntohs(tvb, offset + 2);
5086 proto_tree *sub_tree = proto_tree_add_subtree_format(svc_tree, tvb, offset, 4 + len,
5087 ett_tns_sns_subpacket, NULL((void*)0), "Sub-packet %u: %s, %u bytes", j + 1,
5088 val_to_str_const(sub_type, tns_sns_subpacket_types, "unknown"), len);
5089 proto_tree_add_item(sub_tree, hf_tns_data_sns_sub_type, tvb, offset + 2, 2, ENC_BIG_ENDIAN0x00000000);
5090 offset += 4;
5091 bool_Bool algs = j == 1 && (sub_type == TNS_ANO_SP_BYTES1 || sub_type == TNS_ANO_SP_UB12);
5092 if ( sub_type == TNS_ANO_SP_VERSION5 && len == 4 )
5093 proto_tree_add_item(sub_tree, hf_tns_data_sns_version, tvb, offset, 4, ENC_BIG_ENDIAN0x00000000);
5094 else if ( algs && svc_type == TNS_ANO_ENCRYPTION2 )
5095 {
5096 for ( unsigned k = 0; k < len; k++ )
5097 proto_tree_add_item(sub_tree, hf_tns_data_sns_encryption, tvb, offset + k, 1, ENC_NA0x00000000);
5098 /* the server's pick: anything but none turns
5099 * encryption on once the client has answered */
5100 if ( !is_request && !PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited) && len == 1 && tvb_get_uint8(tvb, offset) != 0 )
5101 tns_get_conv_info(pinfo)->ano_encryption = true1;
5102 }
5103 else if ( algs && svc_type == TNS_ANO_DATA_INTEGRITY3 )
5104 for ( unsigned k = 0; k < len; k++ )
5105 proto_tree_add_item(sub_tree, hf_tns_data_sns_integrity, tvb, offset + k, 1, ENC_NA0x00000000);
5106 else if ( len > 0 )
5107 proto_tree_add_item(sub_tree, hf_tns_data_sns_sub_data, tvb, offset, len, ENC_NA0x00000000);
5108 offset += len;
5109 }
5110 proto_item_set_len(svc_item, offset - svc_start);
5111 }
5112 break;
5113 }
5114 }
5115
5116 return offset;
5117}
5118
5119static void dissect_tns_connect(tvbuff_t *tvb, int offset, packet_info *pinfo _U___attribute__((unused)), proto_tree *tns_tree)
5120{
5121 proto_tree *connect_tree;
5122 uint32_t cd_offset, cd_len;
5123 int tns_offset = offset-8;
5124 static int * const flags[] = {
5125 &hf_tns_ntp_flag_hangon,
5126 &hf_tns_ntp_flag_crel,
5127 &hf_tns_ntp_flag_tduio,
5128 &hf_tns_ntp_flag_srun,
5129 &hf_tns_ntp_flag_dtest,
5130 &hf_tns_ntp_flag_cbio,
5131 &hf_tns_ntp_flag_asio,
5132 &hf_tns_ntp_flag_pio,
5133 &hf_tns_ntp_flag_grant,
5134 &hf_tns_ntp_flag_handoff,
5135 &hf_tns_ntp_flag_sigio,
5136 &hf_tns_ntp_flag_sigpipe,
5137 &hf_tns_ntp_flag_sigurg,
5138 &hf_tns_ntp_flag_urgentio,
5139 &hf_tns_ntp_flag_fdio,
5140 &hf_tns_ntp_flag_testop,
5141 NULL((void*)0)
5142 };
5143
5144 connect_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
5145 ett_tns_connect, NULL((void*)0), "Connect");
5146
5147 proto_tree_add_item(connect_tree, hf_tns_version, tvb,
5148 offset, 2, ENC_BIG_ENDIAN0x00000000);
5149 offset += 2;
5150
5151 proto_tree_add_item(connect_tree, hf_tns_compat_version, tvb,
5152 offset, 2, ENC_BIG_ENDIAN0x00000000);
5153 offset += 2;
5154
5155 proto_tree_add_bitmask(connect_tree, tvb, offset, hf_tns_service_options, ett_tns_sopt_flag, tns_service_options, ENC_BIG_ENDIAN0x00000000);
5156 offset += 2;
5157
5158 proto_tree_add_item(connect_tree, hf_tns_sdu_size, tvb,
5159 offset, 2, ENC_BIG_ENDIAN0x00000000);
5160 offset += 2;
5161
5162 proto_tree_add_item(connect_tree, hf_tns_max_tdu_size, tvb,
5163 offset, 2, ENC_BIG_ENDIAN0x00000000);
5164 offset += 2;
5165
5166 proto_tree_add_bitmask(connect_tree, tvb, offset, hf_tns_nt_proto_characteristics, ett_tns_ntp_flag, flags, ENC_BIG_ENDIAN0x00000000);
5167 offset += 2;
5168
5169 proto_tree_add_item(connect_tree, hf_tns_line_turnaround, tvb,
5170 offset, 2, ENC_BIG_ENDIAN0x00000000);
5171 offset += 2;
5172
5173 proto_tree_add_item(connect_tree, hf_tns_value_of_one, tvb,
5174 offset, 2, ENC_NA0x00000000);
5175 offset += 2;
5176
5177 proto_tree_add_item_ret_uint(connect_tree, hf_tns_connect_data_length, tvb,
5178 offset, 2, ENC_BIG_ENDIAN0x00000000, &cd_len);
5179 offset += 2;
5180
5181 proto_tree_add_item_ret_uint(connect_tree, hf_tns_connect_data_offset, tvb,
5182 offset, 2, ENC_BIG_ENDIAN0x00000000, &cd_offset);
5183 offset += 2;
5184
5185 proto_tree_add_item(connect_tree, hf_tns_connect_data_max, tvb,
5186 offset, 4, ENC_BIG_ENDIAN0x00000000);
5187 offset += 4;
5188
5189 proto_tree_add_bitmask(connect_tree, tvb, offset, hf_tns_connect_flags0, ett_tns_conn_flag, tns_connect_flags, ENC_BIG_ENDIAN0x00000000);
5190 offset += 1;
5191
5192 proto_tree_add_bitmask(connect_tree, tvb, offset, hf_tns_connect_flags1, ett_tns_conn_flag, tns_connect_flags, ENC_BIG_ENDIAN0x00000000);
5193 offset += 1;
5194
5195 /*
5196 * XXX - sometimes it appears that this stuff isn't present
5197 * in the packet.
5198 */
5199 if ((uint32_t)(offset + 16) <= tns_offset+cd_offset)
5200 {
5201 proto_tree_add_item(connect_tree, hf_tns_trace_cf1, tvb,
5202 offset, 4, ENC_BIG_ENDIAN0x00000000);
5203 offset += 4;
5204
5205 proto_tree_add_item(connect_tree, hf_tns_trace_cf2, tvb,
5206 offset, 4, ENC_BIG_ENDIAN0x00000000);
5207 offset += 4;
5208
5209 proto_tree_add_item(connect_tree, hf_tns_trace_cid, tvb,
5210 offset, 8, ENC_BIG_ENDIAN0x00000000);
5211 /* offset += 8;*/
5212 }
5213
5214 if ( cd_len > 0)
5215 {
5216 /* Long Connect Data (> 221 bytes?) is not in the Connect PDU
5217 * but sent in an immediately following Data PDU.
5218 */
5219 if (tvb_reported_length_remaining(tvb, tns_offset + cd_offset)) {
5220 proto_tree_add_item(connect_tree, hf_tns_connect_data, tvb,
5221 tns_offset+cd_offset, -1, ENC_ASCII0x00000000);
5222 } else {
5223 proto_tree_add_expert(connect_tree, pinfo, &ei_tns_connect_data_next_packet, tvb, 0, 0);
5224 if (!PINFO_FD_VISITED(pinfo)((pinfo)->fd->visited)) {
5225 tns_conv_info_t *tns_info = tns_get_conv_info(pinfo);
5226 tns_info->pending_connect_data = cd_len;
5227 }
5228 }
5229 }
5230}
5231
5232static void dissect_tns_accept(tvbuff_t *tvb, int offset, packet_info *pinfo _U___attribute__((unused)), proto_tree *tns_tree)
5233{
5234 proto_tree *accept_tree;
5235 uint32_t accept_offset, accept_len;
5236 uint16_t version;
5237 int tns_offset = offset-8;
5238
5239 accept_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
5240 ett_tns_accept, NULL((void*)0), "Accept");
5241
5242 proto_tree_add_item(accept_tree, hf_tns_version, tvb,
5243 offset, 2, ENC_BIG_ENDIAN0x00000000);
5244 offset += 2;
5245
5246 proto_tree_add_bitmask(accept_tree, tvb, offset, hf_tns_service_options, ett_tns_sopt_flag, tns_service_options, ENC_BIG_ENDIAN0x00000000);
5247 offset += 2;
5248
5249 proto_tree_add_item(accept_tree, hf_tns_sdu_size, tvb,
5250 offset, 2, ENC_BIG_ENDIAN0x00000000);
5251 offset += 2;
5252
5253 proto_tree_add_item(accept_tree, hf_tns_max_tdu_size, tvb,
5254 offset, 2, ENC_BIG_ENDIAN0x00000000);
5255 offset += 2;
5256
5257 proto_tree_add_item(accept_tree, hf_tns_value_of_one, tvb,
5258 offset, 2, ENC_NA0x00000000);
5259 offset += 2;
5260
5261 proto_tree_add_item_ret_uint(accept_tree, hf_tns_accept_data_length, tvb,
5262 offset, 2, ENC_BIG_ENDIAN0x00000000, &accept_len);
5263 offset += 2;
5264
5265 proto_tree_add_item_ret_uint(accept_tree, hf_tns_accept_data_offset, tvb,
5266 offset, 2, ENC_BIG_ENDIAN0x00000000, &accept_offset);
5267 offset += 2;
5268
5269 proto_tree_add_bitmask(accept_tree, tvb, offset, hf_tns_connect_flags0, ett_tns_conn_flag, tns_connect_flags, ENC_BIG_ENDIAN0x00000000);
5270 offset += 1;
5271
5272 proto_tree_add_bitmask(accept_tree, tvb, offset, hf_tns_connect_flags1, ett_tns_conn_flag, tns_connect_flags, ENC_BIG_ENDIAN0x00000000);
5273
5274 /* From version 315 the session data unit is offered again as 32
5275 * bits, 24 bytes into the ACCEPT, and from 318 a flags2 word follows
5276 * at 33 - both ahead of any connect data. */
5277 version = tvb_get_ntohs(tvb, tns_offset + 8);
5278 if ( version >= 315 && accept_offset >= 8 + 24 + 4 && tvb_bytes_exist(tvb, tns_offset + 8 + 24, 4) )
5279 proto_tree_add_item(accept_tree, hf_tns_accept_sdu, tvb, tns_offset + 8 + 24, 4, ENC_BIG_ENDIAN0x00000000);
5280 if ( version >= 318 && accept_offset >= 8 + 33 + 4 && tvb_bytes_exist(tvb, tns_offset + 8 + 33, 4) )
5281 proto_tree_add_bitmask(accept_tree, tvb, tns_offset + 8 + 33, hf_tns_accept_flags2,
5282 ett_tns_accept_flags2, tns_accept_flags2, ENC_BIG_ENDIAN0x00000000);
5283
5284 if ( accept_len > 0)
5285 {
5286 proto_tree_add_item(accept_tree, hf_tns_accept_data, tvb,
5287 tns_offset+accept_offset, -1, ENC_ASCII0x00000000);
5288 }
5289 return;
5290}
5291
5292
5293static void dissect_tns_refuse(tvbuff_t *tvb, int offset, packet_info *pinfo _U___attribute__((unused)), proto_tree *tns_tree)
5294{
5295 /* TODO
5296 * According to some reverse engineers, the refuse packet is also sent when the login fails.
5297 * Byte 54 shows if this is due to invalid ID (0x02) or password (0x03).
5298 * At now we do not have pcaps with such messages to check this statement.
5299 */
5300 proto_tree *refuse_tree;
5301
5302 refuse_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
5303 ett_tns_refuse, NULL((void*)0), "Refuse");
5304
5305 proto_tree_add_item(refuse_tree, hf_tns_refuse_reason_user, tvb,
5306 offset, 1, ENC_BIG_ENDIAN0x00000000);
5307 offset += 1;
5308
5309 proto_tree_add_item(refuse_tree, hf_tns_refuse_reason_system, tvb,
5310 offset, 1, ENC_BIG_ENDIAN0x00000000);
5311 offset += 1;
5312
5313 proto_tree_add_item(refuse_tree, hf_tns_refuse_data_length, tvb,
5314 offset, 2, ENC_BIG_ENDIAN0x00000000);
5315 offset += 2;
5316
5317 proto_tree_add_item(refuse_tree, hf_tns_refuse_data, tvb,
5318 offset, -1, ENC_ASCII0x00000000);
5319}
5320
5321
5322static void dissect_tns_abort(tvbuff_t *tvb, int offset, packet_info *pinfo _U___attribute__((unused)), proto_tree *tns_tree)
5323{
5324 proto_tree *abort_tree;
5325
5326 abort_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
5327 ett_tns_abort, NULL((void*)0), "Abort");
5328
5329 proto_tree_add_item(abort_tree, hf_tns_abort_reason_user, tvb,
5330 offset, 1, ENC_BIG_ENDIAN0x00000000);
5331 offset += 1;
5332
5333 proto_tree_add_item(abort_tree, hf_tns_abort_reason_system, tvb,
5334 offset, 1, ENC_BIG_ENDIAN0x00000000);
5335 offset += 1;
5336
5337 proto_tree_add_item(abort_tree, hf_tns_abort_data, tvb,
5338 offset, -1, ENC_ASCII0x00000000);
5339}
5340
5341
5342static void dissect_tns_marker(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tns_tree, int is_attention)
5343{
5344 proto_tree *marker_tree;
5345
5346 marker_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
5347 ett_tns_marker, NULL((void*)0), is_attention ? "Attention" : "Marker");
5348
5349 proto_tree_add_item(marker_tree, hf_tns_marker_type, tvb,
5350 offset, 1, ENC_BIG_ENDIAN0x00000000);
5351 offset += 1;
5352
5353 proto_tree_add_item(marker_tree, hf_tns_marker_data_byte, tvb,
5354 offset, 1, ENC_BIG_ENDIAN0x00000000);
5355 offset += 1;
5356
5357 /* The last byte selects break vs reset for a data marker. */
5358 if ( tvb_reported_length_remaining(tvb, offset) > 0 )
5359 {
5360 uint32_t func = tvb_get_uint8(tvb, offset);
5361 proto_tree_add_item(marker_tree, hf_tns_marker_function, tvb,
5362 offset, 1, ENC_BIG_ENDIAN0x00000000);
5363 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
5364 val_to_str_const(func, tns_marker_functions, "Unknown"));
5365 }
5366}
5367
5368static void dissect_tns_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo _U___attribute__((unused)), proto_tree *tns_tree)
5369{
5370 proto_tree *redirect_tree;
5371
5372 redirect_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
5373 ett_tns_redirect, NULL((void*)0), "Redirect");
5374
5375 proto_tree_add_item(redirect_tree, hf_tns_redirect_data_length, tvb,
5376 offset, 2, ENC_BIG_ENDIAN0x00000000);
5377 offset += 2;
5378
5379 proto_tree_add_item(redirect_tree, hf_tns_redirect_data, tvb,
5380 offset, -1, ENC_ASCII0x00000000);
5381}
5382
5383static void dissect_tns_control(tvbuff_t *tvb, int offset, packet_info *pinfo _U___attribute__((unused)), proto_tree *tns_tree)
5384{
5385 proto_tree *control_tree;
5386
5387 control_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
5388 ett_tns_control, NULL((void*)0), "Control");
5389
5390 proto_tree_add_item(control_tree, hf_tns_control_cmd, tvb,
5391 offset, 2, ENC_BIG_ENDIAN0x00000000);
5392 offset += 2;
5393
5394 proto_tree_add_item(control_tree, hf_tns_control_data, tvb,
5395 offset, -1, ENC_NA0x00000000);
5396}
5397
5398static unsigned
5399get_tns_pdu_len(packet_info *pinfo _U___attribute__((unused)), tvbuff_t *tvb, int offset, void *data _U___attribute__((unused)))
5400{
5401 /*
5402 * Get the 16-bit length of the TNS message, including header
5403 */
5404 unsigned length = tvb_get_ntohs(tvb, offset);
5405 offset += 4;
5406 uint8_t type = tvb_get_uint8(tvb, offset);
5407 /* Type 0xf (data descriptor, LOB/FILE data) has data which follows
5408 * immediately (no new PDU header) but is not counted in the PDU
5409 * length field either.
5410 */
5411 if (type == TNS_TYPE_DD15) {
5412 offset += 8;
5413 if (!tvb_bytes_exist(tvb, offset, 4)) {
5414 /* return 0 makes tcp_dissect_pdus() report
5415 * DESEGMENT_ONE_MORE_SEGMENT to the TCP dissector.
5416 */
5417 return 0;
5418 }
5419 unsigned dd_len = tvb_get_ntohl(tvb, offset);
5420 return length + dd_len;
5421 }
5422 return length;
5423}
5424
5425static unsigned
5426get_tns_pdu_len_nochksum(packet_info *pinfo _U___attribute__((unused)), tvbuff_t *tvb, int offset, void *data _U___attribute__((unused)))
5427{
5428 /*
5429 * Get the 32-bit length of the TNS message, including header
5430 */
5431 unsigned length = tvb_get_ntohl(tvb, offset);
5432 offset += 4;
5433 uint8_t type = tvb_get_uint8(tvb, offset);
5434 /* Type 0xf (data descriptor, LOB/FILE data) has data which follows
5435 * immediately (no new PDU header) but is not counted in the PDU
5436 * length field either.
5437 */
5438 if (type == TNS_TYPE_DD15) {
5439 offset += 8;
5440 if (!tvb_bytes_exist(tvb, offset, 4)) {
5441 /* return 0 makes tcp_dissect_pdus() report
5442 * DESEGMENT_ONE_MORE_SEGMENT to the TCP dissector.
5443 */
5444 return 0;
5445 }
5446 unsigned dd_len = tvb_get_ntohl(tvb, offset);
5447 return length + dd_len;
5448 }
5449
5450 return length;
5451}
5452
5453static int
5454dissect_tns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5455{
5456 uint32_t length;
5457 uint16_t chksum;
5458 uint8_t type;
5459
5460 /*
5461 * First, do a sanity check to make sure what we have
5462 * starts with a TNS PDU.
5463 */
5464 if (tvb_bytes_exist(tvb, 4, 1)) {
5465 /*
5466 * Well, we have the packet type; let's make sure
5467 * it's a known type.
5468 */
5469 type = tvb_get_uint8(tvb, 4);
5470 if (type < TNS_TYPE_CONNECT1 || type > TNS_TYPE_MAX19)
5471 return 0; /* it's not a known type */
5472 }
5473
5474 /*
5475 * In some messages (observed in Oracle12c) packet length has 4 bytes
5476 * instead of 2.
5477 *
5478 * If packet length has 2 bytes, length and checksum equals two unsigned
5479 * 16-bit numbers. Packet checksum is generally unused (equal zero),
5480 * but 10g client may set 2nd byte to 4.
5481 *
5482 * Else, Oracle 12c combine these two 16-bit numbers into one 32-bit.
5483 * This number represents the packet length. Checksum is omitted.
5484 */
5485 chksum = tvb_get_ntohs(tvb, 2);
5486
5487 length = (chksum == 0 || chksum == 4) ? 2 : 4;
5488
5489 tcp_dissect_pdus(tvb, pinfo, tree, tns_desegment, TNS_HDR_LEN8,
5490 (length == 2 ? get_tns_pdu_len : get_tns_pdu_len_nochksum),
5491 dissect_tns_pdu, data);
5492
5493 return tvb_captured_length(tvb);
5494}
5495
5496static int
5497dissect_tns_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U___attribute__((unused)))
5498{
5499 proto_tree *tns_tree, *ti;
5500 proto_item *hidden_item;
5501 unsigned offset = 0;
5502 uint32_t length;
5503 uint16_t chksum;
5504 uint8_t type;
5505
5506 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TNS");
5507
5508 col_set_str(pinfo->cinfo, COL_INFO,
5509 (pinfo->match_uint == pinfo->destport) ? "Request" : "Response");
5510
5511 ti = proto_tree_add_item(tree, proto_tns, tvb, 0, -1, ENC_NA0x00000000);
5512 tns_tree = proto_item_add_subtree(ti, ett_tns);
5513
5514 if (pinfo->match_uint == pinfo->destport)
5515 {
5516 hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_request,
5517 tvb, offset, 0, true1);
5518 }
5519 else
5520 {
5521 hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_response,
5522 tvb, offset, 0, true1);
5523 }
5524 proto_item_set_hidden(hidden_item);
5525
5526 chksum = tvb_get_ntohs(tvb, offset+2);
5527 if (chksum == 0 || chksum == 4)
5528 {
5529 proto_tree_add_item_ret_uint(tns_tree, hf_tns_length, tvb, offset,
5530 2, ENC_BIG_ENDIAN0x00000000, &length);
5531 offset += 2;
5532 proto_tree_add_checksum(tns_tree, tvb, offset, hf_tns_packet_checksum,
5533 -1, NULL((void*)0), pinfo, 0, ENC_BIG_ENDIAN0x00000000, PROTO_CHECKSUM_NO_FLAGS0x00);
5534 offset += 2;
5535 }
5536 else
5537 {
5538 /* Oracle 12c uses checksum bytes as part of the packet length. */
5539 proto_tree_add_item_ret_uint(tns_tree, hf_tns_length, tvb, offset,
5540 4, ENC_BIG_ENDIAN0x00000000, &length);
5541 offset += 4;
5542 }
5543
5544 type = tvb_get_uint8(tvb, offset);
5545 proto_tree_add_uint(tns_tree, hf_tns_packet_type, tvb,
5546 offset, 1, type);
5547 offset += 1;
5548
5549 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s (%u)",
5550 val_to_str_const(type, tns_type_vals, "Unknown"), type);
5551
5552 proto_tree_add_item(tns_tree, hf_tns_reserved_byte, tvb,
5553 offset, 1, ENC_NA0x00000000);
5554 offset += 1;
5555
5556 proto_tree_add_checksum(tns_tree, tvb, offset, hf_tns_header_checksum, -1, NULL((void*)0), pinfo, 0, ENC_BIG_ENDIAN0x00000000, PROTO_CHECKSUM_NO_FLAGS0x00);
5557 offset += 2;
5558
5559 switch (type)
5560 {
5561 case TNS_TYPE_CONNECT1:
5562 dissect_tns_connect(tvb,offset,pinfo,tns_tree);
5563 break;
5564 case TNS_TYPE_ACCEPT2:
5565 dissect_tns_accept(tvb,offset,pinfo,tns_tree);
5566 break;
5567 case TNS_TYPE_REFUSE4:
5568 dissect_tns_refuse(tvb,offset,pinfo,tns_tree);
5569 break;
5570 case TNS_TYPE_REDIRECT5:
5571 dissect_tns_redirect(tvb,offset,pinfo,tns_tree);
5572 break;
5573 case TNS_TYPE_ABORT9:
5574 dissect_tns_abort(tvb,offset,pinfo,tns_tree);
5575 break;
5576 case TNS_TYPE_MARKER12:
5577 dissect_tns_marker(tvb,offset,pinfo,tns_tree, 0);
5578 break;
5579 case TNS_TYPE_ATTENTION13:
5580 dissect_tns_marker(tvb,offset,pinfo,tns_tree, 1);
5581 break;
5582 case TNS_TYPE_CONTROL14:
5583 dissect_tns_control(tvb,offset,pinfo,tns_tree);
5584 break;
5585 case TNS_TYPE_DATA6:
5586 dissect_tns_data(tvb,offset,pinfo,tns_tree);
5587 break;
5588 case TNS_TYPE_DD15:
5589 dissect_tns_data_descriptor(tvb,offset,pinfo,tns_tree, length);
5590 break;
5591 default:
5592 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo,
5593 tns_tree);
5594 break;
5595 }
5596
5597 return tvb_captured_length(tvb);
5598}
5599
5600void proto_register_tns(void)
5601{
5602 static hf_register_info hf[] = {
5603 { &hf_tns_response, {
5604 "Response", "tns.response", FT_BOOLEAN, BASE_NONE,
5605 NULL((void*)0), 0x0, "true if TNS response", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5606 { &hf_tns_request, {
5607 "Request", "tns.request", FT_BOOLEAN, BASE_NONE,
5608 NULL((void*)0), 0x0, "true if TNS request", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5609 { &hf_tns_length, {
5610 "Packet Length", "tns.length", FT_UINT32, BASE_DEC,
5611 NULL((void*)0), 0x0, "Length of TNS packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5612 { &hf_tns_packet_checksum, {
5613 "Packet Checksum", "tns.packet_checksum", FT_UINT16, BASE_HEX,
5614 NULL((void*)0), 0x0, "Checksum of Packet Data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5615 { &hf_tns_header_checksum, {
5616 "Header Checksum", "tns.header_checksum", FT_UINT16, BASE_HEX,
5617 NULL((void*)0), 0x0, "Checksum of Header Data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5618
5619 { &hf_tns_version, {
5620 "Version", "tns.version", FT_UINT16, BASE_DEC,
5621 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5622 { &hf_tns_compat_version, {
5623 "Version (Compatible)", "tns.compat_version", FT_UINT16, BASE_DEC,
5624 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5625
5626 { &hf_tns_service_options, {
5627 "Service Options", "tns.service_options", FT_UINT16, BASE_HEX,
5628 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5629
5630 { &hf_tns_sopt_flag_bconn, {
5631 "Broken Connect Notify", "tns.so_flag.bconn", FT_BOOLEAN, 16,
5632 NULL((void*)0), 0x2000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5633 { &hf_tns_sopt_flag_pc, {
5634 "Packet Checksum", "tns.so_flag.pc", FT_BOOLEAN, 16,
5635 NULL((void*)0), 0x1000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5636 { &hf_tns_sopt_flag_hc, {
5637 "Header Checksum", "tns.so_flag.hc", FT_BOOLEAN, 16,
5638 NULL((void*)0), 0x0800, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5639 { &hf_tns_sopt_flag_fd, {
5640 "Full Duplex", "tns.so_flag.fd", FT_BOOLEAN, 16,
5641 NULL((void*)0), 0x0400, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5642 { &hf_tns_sopt_flag_hd, {
5643 "Half Duplex", "tns.so_flag.hd", FT_BOOLEAN, 16,
5644 NULL((void*)0), 0x0200, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5645 { &hf_tns_sopt_flag_dc1, {
5646 "Don't Care", "tns.so_flag.dc1", FT_BOOLEAN, 16,
5647 NULL((void*)0), 0x0100, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5648 { &hf_tns_sopt_flag_dc2, {
5649 "Don't Care", "tns.so_flag.dc2", FT_BOOLEAN, 16,
5650 NULL((void*)0), 0x0080, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5651 { &hf_tns_sopt_flag_dio, {
5652 "Direct IO to Transport", "tns.so_flag.dio", FT_BOOLEAN, 16,
5653 NULL((void*)0), 0x0010, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5654 { &hf_tns_sopt_flag_ap, {
5655 "Attention Processing", "tns.so_flag.ap", FT_BOOLEAN, 16,
5656 NULL((void*)0), 0x0008, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5657 { &hf_tns_sopt_flag_ra, {
5658 "Can Receive Attention", "tns.so_flag.ra", FT_BOOLEAN, 16,
5659 NULL((void*)0), 0x0004, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5660 { &hf_tns_sopt_flag_sa, {
5661 "Can Send Attention", "tns.so_flag.sa", FT_BOOLEAN, 16,
5662 NULL((void*)0), 0x0002, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5663
5664
5665 { &hf_tns_sdu_size, {
5666 "Session Data Unit Size", "tns.sdu_size", FT_UINT16, BASE_DEC,
5667 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5668 { &hf_tns_max_tdu_size, {
5669 "Maximum Transmission Data Unit Size", "tns.max_tdu_size", FT_UINT16, BASE_DEC,
5670 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5671
5672 { &hf_tns_nt_proto_characteristics, {
5673 "NT Protocol Characteristics", "tns.nt_proto_characteristics", FT_UINT16, BASE_HEX,
5674 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5675 { &hf_tns_ntp_flag_hangon, {
5676 "Hangon to listener connect", "tns.ntp_flag.hangon", FT_BOOLEAN, 16,
5677 NULL((void*)0), 0x8000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5678 { &hf_tns_ntp_flag_crel, {
5679 "Confirmed release", "tns.ntp_flag.crel", FT_BOOLEAN, 16,
5680 NULL((void*)0), 0x4000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5681 { &hf_tns_ntp_flag_tduio, {
5682 "TDU based IO", "tns.ntp_flag.tduio", FT_BOOLEAN, 16,
5683 NULL((void*)0), 0x2000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5684 { &hf_tns_ntp_flag_srun, {
5685 "Spawner running", "tns.ntp_flag.srun", FT_BOOLEAN, 16,
5686 NULL((void*)0), 0x1000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5687 { &hf_tns_ntp_flag_dtest, {
5688 "Data test", "tns.ntp_flag.dtest", FT_BOOLEAN, 16,
5689 NULL((void*)0), 0x0800, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5690 { &hf_tns_ntp_flag_cbio, {
5691 "Callback IO supported", "tns.ntp_flag.cbio", FT_BOOLEAN, 16,
5692 NULL((void*)0), 0x0400, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5693 { &hf_tns_ntp_flag_asio, {
5694 "ASync IO Supported", "tns.ntp_flag.asio", FT_BOOLEAN, 16,
5695 NULL((void*)0), 0x0200, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5696 { &hf_tns_ntp_flag_pio, {
5697 "Packet oriented IO", "tns.ntp_flag.pio", FT_BOOLEAN, 16,
5698 NULL((void*)0), 0x0100, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5699 { &hf_tns_ntp_flag_grant, {
5700 "Can grant connection to another", "tns.ntp_flag.grant", FT_BOOLEAN, 16,
5701 NULL((void*)0), 0x0080, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5702 { &hf_tns_ntp_flag_handoff, {
5703 "Can handoff connection to another", "tns.ntp_flag.handoff", FT_BOOLEAN, 16,
5704 NULL((void*)0), 0x0040, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5705 { &hf_tns_ntp_flag_sigio, {
5706 "Generate SIGIO signal", "tns.ntp_flag.sigio", FT_BOOLEAN, 16,
5707 NULL((void*)0), 0x0020, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5708 { &hf_tns_ntp_flag_sigpipe, {
5709 "Generate SIGPIPE signal", "tns.ntp_flag.sigpipe", FT_BOOLEAN, 16,
5710 NULL((void*)0), 0x0010, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5711 { &hf_tns_ntp_flag_sigurg, {
5712 "Generate SIGURG signal", "tns.ntp_flag.sigurg", FT_BOOLEAN, 16,
5713 NULL((void*)0), 0x0008, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5714 { &hf_tns_ntp_flag_urgentio, {
5715 "Urgent IO supported", "tns.ntp_flag.urgentio", FT_BOOLEAN, 16,
5716 NULL((void*)0), 0x0004, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5717 { &hf_tns_ntp_flag_fdio, {
5718 "Full duplex IO supported", "tns.ntp_flag.dfio", FT_BOOLEAN, 16,
5719 NULL((void*)0), 0x0002, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5720 { &hf_tns_ntp_flag_testop, {
5721 "Test operation", "tns.ntp_flag.testop", FT_BOOLEAN, 16,
5722 NULL((void*)0), 0x0001, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5723
5724
5725
5726
5727 { &hf_tns_line_turnaround, {
5728 "Line Turnaround Value", "tns.line_turnaround", FT_UINT16, BASE_DEC,
5729 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5730 { &hf_tns_value_of_one, {
5731 "Value of 1 in Hardware", "tns.value_of_one", FT_BYTES, BASE_NONE,
5732 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5733
5734 { &hf_tns_connect_data_length, {
5735 "Length of Connect Data", "tns.connect_data_length", FT_UINT16,
5736 BASE_DEC|BASE_UNIT_STRING0x00001000, UNS(&units_byte_bytes)((0 ? (const struct unit_name_string*)0 : ((&units_byte_bytes
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5737 { &hf_tns_connect_data_offset, {
5738 "Offset to Connect Data", "tns.connect_data_offset", FT_UINT16, BASE_DEC,
5739 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5740 { &hf_tns_connect_data_max, {
5741 "Maximum Receivable Connect Data", "tns.connect_data_max", FT_UINT32, BASE_DEC,
5742 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5743
5744 { &hf_tns_connect_flags0, {
5745 "Connect Flags 0", "tns.connect_flags0", FT_UINT8, BASE_HEX,
5746 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5747 { &hf_tns_connect_flags1, {
5748 "Connect Flags 1", "tns.connect_flags1", FT_UINT8, BASE_HEX,
5749 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5750
5751 { &hf_tns_conn_flag_nareq, {
5752 "NA services required", "tns.connect_flags.nareq", FT_BOOLEAN, 8,
5753 NULL((void*)0), 0x10, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5754 { &hf_tns_conn_flag_nalink, {
5755 "NA services linked in", "tns.connect_flags.nalink", FT_BOOLEAN, 8,
5756 NULL((void*)0), 0x08, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5757 { &hf_tns_conn_flag_enablena, {
5758 "NA services enabled", "tns.connect_flags.enablena", FT_BOOLEAN, 8,
5759 NULL((void*)0), 0x04, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5760 { &hf_tns_conn_flag_ichg, {
5761 "Interchange is involved", "tns.connect_flags.ichg", FT_BOOLEAN, 8,
5762 NULL((void*)0), 0x02, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5763 { &hf_tns_conn_flag_wantna, {
5764 "NA services wanted", "tns.connect_flags.wantna", FT_BOOLEAN, 8,
5765 NULL((void*)0), 0x01, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5766
5767
5768 { &hf_tns_trace_cf1, {
5769 "Trace Cross Facility Item 1", "tns.trace_cf1", FT_UINT32, BASE_HEX,
5770 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5771 { &hf_tns_trace_cf2, {
5772 "Trace Cross Facility Item 2", "tns.trace_cf2", FT_UINT32, BASE_HEX,
5773 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5774 { &hf_tns_trace_cid, {
5775 "Trace Unique Connection ID", "tns.trace_cid", FT_UINT64, BASE_HEX,
5776 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5777 { &hf_tns_connect_data, {
5778 "Connect Data", "tns.connect_data", FT_STRING, BASE_NONE,
5779 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5780
5781 { &hf_tns_accept_data_length, {
5782 "Accept Data Length", "tns.accept_data_length", FT_UINT16,
5783 BASE_DEC|BASE_UNIT_STRING0x00001000, UNS(&units_byte_bytes)((0 ? (const struct unit_name_string*)0 : ((&units_byte_bytes
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5784 { &hf_tns_accept_data, {
5785 "Accept Data", "tns.accept_data", FT_STRING, BASE_NONE,
5786 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5787 { &hf_tns_accept_sdu, {
5788 "Session Data Unit Size (32-bit)", "tns.accept_sdu", FT_UINT32, BASE_DEC,
5789 NULL((void*)0), 0x0, "The session data unit a version 315 or later ACCEPT offers, past the 16-bit field's reach", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5790 { &hf_tns_accept_flags2, {
5791 "Flags 2", "tns.accept_flags2", FT_UINT32, BASE_HEX,
5792 NULL((void*)0), 0x0, "What a version 318 or later server offers the client", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5793 { &hf_tns_accept_flags2_check_oob, {
5794 "Check Out-of-Band", "tns.accept_flags2.check_oob", FT_BOOLEAN, 32,
5795 NULL((void*)0), 0x00000001, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5796 { &hf_tns_accept_flags2_end_of_response, {
5797 "End of Response", "tns.accept_flags2.end_of_response", FT_BOOLEAN, 32,
5798 NULL((void*)0), 0x02000000, "Replies end with an end-of-response marker, so the client can pipeline calls", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5799 { &hf_tns_accept_flags2_fast_auth, {
5800 "Fast Authentication", "tns.accept_flags2.fast_auth", FT_BOOLEAN, 32,
5801 NULL((void*)0), 0x10000000, "The client may send its protocol, data types and session key in one bundle", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5802 { &hf_tns_accept_data_offset, {
5803 "Offset to Accept Data", "tns.accept_data_offset", FT_UINT16, BASE_DEC,
5804 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5805
5806 { &hf_tns_refuse_reason_user, {
5807 "Refuse Reason (User)", "tns.refuse_reason_user", FT_UINT8, BASE_HEX,
5808 NULL((void*)0), 0x0, "Refuse Reason from Application", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5809 { &hf_tns_refuse_reason_system, {
5810 "Refuse Reason (System)", "tns.refuse_reason_system", FT_UINT8, BASE_HEX,
5811 NULL((void*)0), 0x0, "Refuse Reason from System", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5812 { &hf_tns_refuse_data_length, {
5813 "Refuse Data Length", "tns.refuse_data_length", FT_UINT16,
5814 BASE_DEC|BASE_UNIT_STRING0x00001000, UNS(&units_byte_bytes)((0 ? (const struct unit_name_string*)0 : ((&units_byte_bytes
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5815 { &hf_tns_refuse_data, {
5816 "Refuse Data", "tns.refuse_data", FT_STRING, BASE_NONE,
5817 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5818
5819 { &hf_tns_abort_reason_user, {
5820 "Abort Reason (User)", "tns.abort_reason_user", FT_UINT8, BASE_HEX,
5821 NULL((void*)0), 0x0, "Abort Reason from Application", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5822 { &hf_tns_abort_reason_system, {
5823 "Abort Reason (User)", "tns.abort_reason_system", FT_UINT8, BASE_HEX,
5824 NULL((void*)0), 0x0, "Abort Reason from System", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5825 { &hf_tns_abort_data, {
5826 "Abort Data", "tns.abort_data", FT_STRING, BASE_NONE,
5827 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5828
5829 { &hf_tns_marker_type, {
5830 "Marker Type", "tns.marker.type", FT_UINT8, BASE_HEX,
5831 VALS(tns_marker_types)((0 ? (const struct _value_string*)0 : ((tns_marker_types)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5832 { &hf_tns_marker_data_byte, {
5833 "Marker Data Byte", "tns.marker.databyte", FT_UINT8, BASE_HEX,
5834 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5835 { &hf_tns_marker_function, {
5836 "Marker Function", "tns.marker.function", FT_UINT8, BASE_DEC,
5837 VALS(tns_marker_functions)((0 ? (const struct _value_string*)0 : ((tns_marker_functions
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5838#if 0
5839 { &hf_tns_marker_data, {
5840 "Marker Data", "tns.marker.data", FT_UINT16, BASE_HEX,
5841 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5842#endif
5843
5844 { &hf_tns_control_cmd, {
5845 "Control Command", "tns.control.cmd", FT_UINT16, BASE_HEX,
5846 VALS(tns_control_cmds)((0 ? (const struct _value_string*)0 : ((tns_control_cmds)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5847 { &hf_tns_control_data, {
5848 "Control Data", "tns.control.data", FT_BYTES, BASE_NONE,
5849 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5850
5851 { &hf_tns_redirect_data_length, {
5852 "Redirect Data Length", "tns.redirect_data_length", FT_UINT16,
5853 BASE_DEC|BASE_UNIT_STRING0x00001000, UNS(&units_byte_bytes)((0 ? (const struct unit_name_string*)0 : ((&units_byte_bytes
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5854 { &hf_tns_redirect_data, {
5855 "Redirect Data", "tns.redirect_data", FT_STRING, BASE_NONE,
5856 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5857
5858 { &hf_tns_data_flag, {
5859 "Data Flag", "tns.data_flag", FT_UINT16, BASE_HEX,
5860 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5861 { &hf_tns_data_flag_send, {
5862 "Send Token", "tns.data_flag.send", FT_BOOLEAN, 16,
5863 NULL((void*)0), 0x1, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5864 { &hf_tns_data_flag_rc, {
5865 "Request Confirmation", "tns.data_flag.rc", FT_BOOLEAN, 16,
5866 NULL((void*)0), 0x2, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5867 { &hf_tns_data_flag_c, {
5868 "Confirmation", "tns.data_flag.c", FT_BOOLEAN, 16,
5869 NULL((void*)0), 0x4, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5870 { &hf_tns_data_flag_reserved, {
5871 "Reserved", "tns.data_flag.reserved", FT_BOOLEAN, 16,
5872 NULL((void*)0), 0x8, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5873 { &hf_tns_data_flag_more, {
5874 "More Data to Come", "tns.data_flag.more", FT_BOOLEAN, 16,
5875 NULL((void*)0), 0x0020, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5876 { &hf_tns_data_flag_eof, {
5877 "End of File", "tns.data_flag.eof", FT_BOOLEAN, 16,
5878 NULL((void*)0), 0x0040, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5879 { &hf_tns_data_flag_dic, {
5880 "Do Immediate Confirmation", "tns.data_flag.dic", FT_BOOLEAN, 16,
5881 NULL((void*)0), 0x0080, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5882 { &hf_tns_data_flag_rts, {
5883 "Request To Send", "tns.data_flag.rts", FT_BOOLEAN, 16,
5884 NULL((void*)0), 0x0100, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5885 { &hf_tns_data_flag_sntt, {
5886 "Send NT Trailer", "tns.data_flag.sntt", FT_BOOLEAN, 16,
5887 NULL((void*)0), 0x0200, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5888 { &hf_tns_data_flag_end_of_request, {
5889 "End of Request", "tns.data_flag.end_of_request", FT_BOOLEAN, 16,
5890 NULL((void*)0), 0x0800, "The packet ends one of a pipeline's calls", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5891 { &hf_tns_data_flag_begin_pipeline, {
5892 "Begin Pipeline", "tns.data_flag.begin_pipeline", FT_BOOLEAN, 16,
5893 NULL((void*)0), 0x1000, "The packet carries the first call of a pipeline", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5894 { &hf_tns_data_flag_end_of_response, {
5895 "End of Response", "tns.data_flag.end_of_response", FT_BOOLEAN, 16,
5896 NULL((void*)0), 0x2000, "The packet ends a reply, which closes with an end-of-response marker", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5897
5898 { &hf_tns_data_id, {
5899 "Data ID", "tns.data_id", FT_UINT32, BASE_HEX,
5900 VALS(tns_data_funcs)((0 ? (const struct _value_string*)0 : ((tns_data_funcs)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5901 { &hf_tns_data_length, {
5902 "Data Length", "tns.data_length", FT_UINT32,
5903 BASE_DEC|BASE_UNIT_STRING0x00001000, UNS(&units_byte_bytes)((0 ? (const struct unit_name_string*)0 : ((&units_byte_bytes
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5904
5905 { &hf_tns_data_oci_id, {
5906 "Call ID", "tns.data_oci.id", FT_UINT8, BASE_HEX|BASE_EXT_STRING0x00000200,
5907 &tns_data_oci_subfuncs_ext, 0x00, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5908
5909 { &hf_tns_data_tseq, {
5910 "TSeq", "tns.data_tseq", FT_UINT8, BASE_HEX,
5911 NULL((void*)0), 0x00, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5912
5913 { &hf_tns_data_token, {
5914 "Token", "tns.data.token", FT_UINT64, BASE_DEC,
5915 NULL((void*)0), 0x0, "Call token (23ai); the reply echoes it", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5916 { &hf_tns_data_piggyback_id, {
5917 /* Also Call ID.
5918 Piggyback is a message what calls a small subset of functions
5919 declared in tns_data_oci_subfuncs. */
5920 "Call ID", "tns.data_piggyback.id", FT_UINT8, BASE_HEX|BASE_EXT_STRING0x00000200,
5921 &tns_data_oci_subfuncs_ext, 0x00, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5922
5923 { &hf_tns_data_unused, {
5924 "Unused", "tns.data.unused", FT_BYTES, BASE_NONE,
5925 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5926
5927 { &hf_tns_cursor, {
5928 "Cursor", "tns.data.cursor", FT_UINT32, BASE_DEC,
5929 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5930
5931 { &hf_tns_data_setp_acc_version, {
5932 "Accepted Version", "tns.data_setp_req.acc_vers", FT_UINT8, BASE_DEC,
5933 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5934 { &hf_tns_data_setp_cli_plat, {
5935 "Client Platform", "tns.data_setp_req.cli_plat", FT_STRINGZ, BASE_NONE,
5936 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5937 { &hf_tns_data_setp_version, {
5938 "Version", "tns.data_setp_resp.version", FT_UINT8, BASE_DEC,
5939 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5940 { &hf_tns_data_setp_charset, {
5941 "Charset", "tns.data_setp_resp.charset", FT_UINT16, BASE_DEC,
5942 VALS(tns_charsets)((0 ? (const struct _value_string*)0 : ((tns_charsets)))), 0x0, "The database character set", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5943 { &hf_tns_data_setp_flags, {
5944 "Server Flags", "tns.data_setp_resp.flags", FT_UINT8, BASE_HEX,
5945 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5946 { &hf_tns_data_setp_ncharset, {
5947 "National Charset", "tns.data_setp_resp.ncharset", FT_UINT16, BASE_DEC,
5948 VALS(tns_charsets)((0 ? (const struct _value_string*)0 : ((tns_charsets)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5949 { &hf_tns_data_setp_compile_caps, {
5950 "Compile Capabilities", "tns.data_setp_resp.compile_caps", FT_BYTES, BASE_NONE,
5951 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5952 { &hf_tns_data_setp_runtime_caps, {
5953 "Runtime Capabilities", "tns.data_setp_resp.runtime_caps", FT_BYTES, BASE_NONE,
5954 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5955 { &hf_tns_data_setp_field_version, {
5956 "Field Version", "tns.data_setp_resp.field_version", FT_UINT8, BASE_DEC,
5957 VALS(tns_field_versions)((0 ? (const struct _value_string*)0 : ((tns_field_versions))
))
, 0x0, "The highest TTC field version the server offers", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5958 { &hf_tns_data_setp_banner, {
5959 "Server Banner", "tns.data_setp_resp.banner", FT_STRINGZ, BASE_NONE,
5960 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5961
5962 { &hf_tns_data_sns_cli_vers, {
5963 "Client Version", "tns.data_sns.cli_vers", FT_UINT32, BASE_CUSTOM,
5964 CF_FUNC(vsnum_to_vstext_basecustom)((const void *) (size_t) (vsnum_to_vstext_basecustom)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5965 { &hf_tns_data_sns_srv_vers, {
5966 "Server Version", "tns.data_sns.srv_vers", FT_UINT32, BASE_CUSTOM,
5967 CF_FUNC(vsnum_to_vstext_basecustom)((const void *) (size_t) (vsnum_to_vstext_basecustom)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5968 { &hf_tns_data_sns_srvcnt, {
5969 "Services", "tns.data_sns.srvcnt", FT_UINT16, BASE_DEC,
5970 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5971 { &hf_tns_data_sns_error, {
5972 "Error", "tns.data_sns.error", FT_UINT8, BASE_DEC,
5973 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5974 { &hf_tns_data_sns_service, {
5975 "Service", "tns.data_sns.service", FT_UINT16, BASE_DEC,
5976 VALS(tns_sns_services)((0 ? (const struct _value_string*)0 : ((tns_sns_services)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5977 { &hf_tns_data_sns_subpackets, {
5978 "Sub-packets", "tns.data_sns.subpackets", FT_UINT16, BASE_DEC,
5979 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5980 { &hf_tns_data_sns_svc_error, {
5981 "Service Error", "tns.data_sns.service_error", FT_UINT32, BASE_DEC,
5982 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5983 { &hf_tns_data_sns_sub_type, {
5984 "Sub-packet Type", "tns.data_sns.sub_type", FT_UINT16, BASE_DEC,
5985 VALS(tns_sns_subpacket_types)((0 ? (const struct _value_string*)0 : ((tns_sns_subpacket_types
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5986 { &hf_tns_data_sns_version, {
5987 "Version", "tns.data_sns.version", FT_UINT32, BASE_HEX,
5988 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5989 { &hf_tns_data_sns_sub_data, {
5990 "Sub-packet Data", "tns.data_sns.sub_data", FT_BYTES, BASE_NONE,
5991 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5992 { &hf_tns_data_sns_encryption, {
5993 "Encryption Algorithm", "tns.data_sns.encryption", FT_UINT8, BASE_DEC,
5994 VALS(tns_sns_encryption_algs)((0 ? (const struct _value_string*)0 : ((tns_sns_encryption_algs
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5995 { &hf_tns_data_sns_integrity, {
5996 "Integrity Algorithm", "tns.data_sns.integrity", FT_UINT8, BASE_DEC,
5997 VALS(tns_sns_integrity_algs)((0 ? (const struct _value_string*)0 : ((tns_sns_integrity_algs
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
5998
5999 { &hf_tns_data_setdt_charset_in, {
6000 "Charset In", "tns.data_setdt.charset_in", FT_UINT16, BASE_DEC,
6001 VALS(tns_charsets)((0 ? (const struct _value_string*)0 : ((tns_charsets)))), 0x0, "NLS_LANGUAGE charset id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6002 { &hf_tns_data_setdt_charset_out, {
6003 "Charset Out", "tns.data_setdt.charset_out", FT_UINT16, BASE_DEC,
6004 VALS(tns_charsets)((0 ? (const struct _value_string*)0 : ((tns_charsets)))), 0x0, "NLS_NCHAR charset id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6005 { &hf_tns_data_setdt_flag, {
6006 "Flag", "tns.data_setdt.flag", FT_UINT8, BASE_HEX,
6007 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6008 { &hf_tns_data_setdt_caphdr, {
6009 "Capability Header", "tns.data_setdt.caphdr", FT_BYTES, BASE_NONE,
6010 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6011 { &hf_tns_data_setdt_caphdr_version, {
6012 "Version", "tns.data_setdt.caphdr.version", FT_UINT24, BASE_HEX,
6013 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6014 { &hf_tns_data_setdt_caphdr_flags, {
6015 "Flags", "tns.data_setdt.caphdr.flags", FT_BYTES, BASE_NONE,
6016 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6017 { &hf_tns_data_field_version, {
6018 "Field Version", "tns.data.field_version", FT_UINT8, BASE_DEC,
6019 VALS(tns_field_versions)((0 ? (const struct _value_string*)0 : ((tns_field_versions))
))
, 0x0, "TTC field version in force on the connection", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6020 { &hf_tns_data_setdt_field_version, {
6021 "Field Version", "tns.data_setdt.field_version", FT_UINT8, BASE_DEC,
6022 VALS(tns_field_versions)((0 ? (const struct _value_string*)0 : ((tns_field_versions))
))
, 0x0, "TTC field version the connection uses", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6023 { &hf_tns_data_setdt_tblhdr, {
6024 "Table Header", "tns.data_setdt.tblhdr", FT_BYTES, BASE_NONE,
6025 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6026 { &hf_tns_data_setdt_idmap, {
6027 "Identity Map", "tns.data_setdt.idmap", FT_BYTES, BASE_NONE,
6028 NULL((void*)0), 0x0, "245 entries: type N -> repr N (default mapping)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6029 { &hf_tns_data_setdt_overrides, {
6030 "Type Overrides", "tns.data_setdt.overrides", FT_NONE, BASE_NONE,
6031 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6032 { &hf_tns_data_setdt_override_client, {
6033 "Client Type", "tns.data_setdt.override.client", FT_UINT8, BASE_DEC,
6034 VALS(tns_data_types)((0 ? (const struct _value_string*)0 : ((tns_data_types)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6035 { &hf_tns_data_setdt_override_repr, {
6036 "Server Repr", "tns.data_setdt.override.repr", FT_UINT8, BASE_DEC,
6037 VALS(tns_data_types)((0 ? (const struct _value_string*)0 : ((tns_data_types)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6038 { &hf_tns_data_setdt_override_format, {
6039 "Format", "tns.data_setdt.override.format", FT_UINT8, BASE_DEC,
6040 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6041
6042 { &hf_tns_data_rpa_num_al8o4, {
6043 "Number of al8o4 Words", "tns.data_rpa.num_al8o4", FT_UINT32, BASE_DEC,
6044 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6045 { &hf_tns_data_rpa_al8o4, {
6046 "al8o4", "tns.data_rpa.al8o4", FT_UINT32, BASE_HEX,
6047 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6048 { &hf_tns_data_rpa_al8txl, {
6049 "al8txl", "tns.data_rpa.al8txl", FT_BYTES, BASE_NONE,
6050 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6051 { &hf_tns_data_rpa_num_kv, {
6052 "Number of Key/Value Pairs", "tns.data_rpa.num_kv", FT_UINT32, BASE_DEC,
6053 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6054 { &hf_tns_data_rpa_registration, {
6055 "Registration", "tns.data_rpa.registration", FT_BYTES, BASE_NONE,
6056 NULL((void*)0), 0x0, "Query registration; the last 8 bytes are the query id", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6057 { &hf_tns_data_rpa_num_rowcounts, {
6058 "Number of Row Counts", "tns.data_rpa.num_rowcounts", FT_UINT32, BASE_DEC,
6059 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6060 { &hf_tns_data_rpa_dml_rowcount, {
6061 "DML Row Count", "tns.data_rpa.dml_rowcount", FT_UINT64, BASE_DEC,
6062 NULL((void*)0), 0x0, "Rows one iteration of an array DML affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6063 { &hf_tns_data_spb_opcode, {
6064 "Opcode", "tns.data_spb.opcode", FT_UINT8, BASE_DEC,
6065 VALS(tns_spb_opcodes)((0 ? (const struct _value_string*)0 : ((tns_spb_opcodes)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6066 { &hf_tns_data_spb_ltxid, {
6067 "Logical Transaction Id", "tns.data_spb.ltxid", FT_BYTES, BASE_NONE,
6068 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6069 { &hf_tns_data_spb_os_pid, {
6070 "OS PID", "tns.data_spb.os_pid", FT_STRING, BASE_NONE,
6071 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6072 { &hf_tns_data_spb_num_kv, {
6073 "Number of Key/Value Pairs", "tns.data_spb.num_kv", FT_UINT32, BASE_DEC,
6074 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6075 { &hf_tns_data_spb_flags, {
6076 "Flags", "tns.data_spb.flags", FT_UINT32, BASE_HEX,
6077 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6078 { &hf_tns_data_spb_session_id, {
6079 "Session Id", "tns.data_spb.session_id", FT_UINT32, BASE_DEC,
6080 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6081 { &hf_tns_data_spb_serial_num, {
6082 "Serial Number", "tns.data_spb.serial_num", FT_UINT16, BASE_DEC,
6083 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6084 { &hf_tns_data_kv_text, {
6085 "Text Value", "tns.data_kv.text", FT_STRING, BASE_NONE,
6086 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6087 { &hf_tns_data_kv_binary, {
6088 "Binary Value", "tns.data_kv.binary", FT_BYTES, BASE_NONE,
6089 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6090 { &hf_tns_data_kv_keyword, {
6091 "Keyword", "tns.data_kv.keyword", FT_UINT16, BASE_DEC,
6092 VALS(tns_kv_keywords)((0 ? (const struct _value_string*)0 : ((tns_kv_keywords)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6093 { &hf_tns_data_wrn_code, {
6094 "Warning Code", "tns.data_wrn.code", FT_UINT16, BASE_DEC,
6095 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6096 { &hf_tns_data_wrn_length, {
6097 "Message Length", "tns.data_wrn.length", FT_UINT16, BASE_DEC,
6098 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6099 { &hf_tns_data_wrn_flags, {
6100 "Flags", "tns.data_wrn.flags", FT_UINT16, BASE_HEX,
6101 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6102 { &hf_tns_data_wrn_message, {
6103 "Message", "tns.data_wrn.message", FT_STRING, BASE_NONE,
6104 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6105 { &hf_tns_data_oci_oer_status, {
6106 "Status", "tns.data_oer.oci_status", FT_UINT8, BASE_DEC,
6107 VALS(tns_oci_oer_status_vals)((0 ? (const struct _value_string*)0 : ((tns_oci_oer_status_vals
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6108 { &hf_tns_data_oci_oer_seq, {
6109 "End-to-End Sequence", "tns.data_oer.seq", FT_UINT16, BASE_DEC,
6110 NULL((void*)0), 0x0, "A per-session counter the server advances with each reply", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6111 { &hf_tns_data_oci_oer_category, {
6112 "Statement Category", "tns.data_oer.category", FT_UINT8, BASE_DEC,
6113 NULL((void*)0), 0x0, "2 for a statement that produces rows or values, 1 for one that does not", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6114 { &hf_tns_data_oci_oer_error_pos, {
6115 "Error Position", "tns.data_oer.error_pos", FT_UINT8, BASE_DEC,
6116 NULL((void*)0), 0x0, "Offset into the SQL text of the parse error", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6117 { &hf_tns_data_oci_oer_command, {
6118 "Command Type", "tns.data_oer.command_type", FT_UINT8, BASE_DEC,
6119 VALS(tns_command_types)((0 ? (const struct _value_string*)0 : ((tns_command_types)))
)
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6120 { &hf_tns_data_oci_oer_call_seq, {
6121 "Call Sequence", "tns.data_oer.call_seq", FT_UINT16, BASE_DEC,
6122 NULL((void*)0), 0x0, "Sequence number of the call this status answers", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6123 { &hf_tns_data_auth_mode, {
6124 "Authentication Mode", "tns.data_auth.mode", FT_UINT32, BASE_HEX,
6125 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6126 { &hf_tns_data_auth_mode_logon, {
6127 "Logon", "tns.data_auth.mode.logon", FT_BOOLEAN, 32,
6128 NULL((void*)0), 0x00000001, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6129 { &hf_tns_data_auth_mode_change_password, {
6130 "Change Password", "tns.data_auth.mode.change_password", FT_BOOLEAN, 32,
6131 NULL((void*)0), 0x00000002, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6132 { &hf_tns_data_auth_mode_sysdba, {
6133 "SYSDBA", "tns.data_auth.mode.sysdba", FT_BOOLEAN, 32,
6134 NULL((void*)0), 0x00000020, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6135 { &hf_tns_data_auth_mode_sysoper, {
6136 "SYSOPER", "tns.data_auth.mode.sysoper", FT_BOOLEAN, 32,
6137 NULL((void*)0), 0x00000040, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6138 { &hf_tns_data_auth_mode_with_password, {
6139 "With Password", "tns.data_auth.mode.with_password", FT_BOOLEAN, 32,
6140 NULL((void*)0), 0x00000100, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6141 { &hf_tns_data_auth_user, {
6142 "User", "tns.data_auth.user", FT_STRING, BASE_NONE,
6143 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6144 { &hf_tns_data_sta_call_status, {
6145 "Call Status", "tns.data_sta.call_status", FT_UINT32, BASE_HEX,
6146 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6147 { &hf_tns_data_sta_seq, {
6148 "End-to-End Sequence", "tns.data_sta.seq", FT_UINT16, BASE_DEC,
6149 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6150 { &hf_tns_data_call_status_txn, {
6151 "Transaction in progress", "tns.data.call_status.txn_in_progress", FT_BOOLEAN, 32,
6152 NULL((void*)0), TNS_CALL_STATUS_TXN_IN_PROGRESS0x00000002, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6153 { &hf_tns_data_call_status_sess_release, {
6154 "Session release", "tns.data.call_status.sess_release", FT_BOOLEAN, 32,
6155 NULL((void*)0), TNS_CALL_STATUS_SESS_RELEASE0x00008000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6156 { &hf_tns_data_oer_call_status, {
6157 "Call Status", "tns.data_oer.call_status", FT_INT32, BASE_DEC,
6158 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6159 { &hf_tns_data_oer_rowcount, {
6160 "Row Count", "tns.data_oer.rowcount", FT_INT32, BASE_DEC,
6161 NULL((void*)0), 0x0, "DML affected rows (11g)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6162 { &hf_tns_data_oer_err_code, {
6163 "Error Code", "tns.data_oer.err_code", FT_INT32, BASE_DEC,
6164 NULL((void*)0), 0x0, "ORA-NNNNN (0 = success)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6165 { &hf_tns_data_oer_cursor_id, {
6166 "Cursor Id", "tns.data_oer.cursor_id", FT_INT32, BASE_DEC,
6167 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6168 { &hf_tns_data_oer_n_batch_errcodes, {
6169 "Batch Error Codes", "tns.data_oer.n_batch_errcodes", FT_INT32, BASE_DEC,
6170 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6171 { &hf_tns_data_oer_n_batch_offsets, {
6172 "Batch Error Offsets", "tns.data_oer.n_batch_offsets", FT_INT32, BASE_DEC,
6173 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6174 { &hf_tns_data_oer_n_batch_messages, {
6175 "Batch Error Messages", "tns.data_oer.n_batch_messages", FT_INT32, BASE_DEC,
6176 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6177 { &hf_tns_data_oer_err_num_ext, {
6178 "Error Number", "tns.data_oer.err_num", FT_UINT32, BASE_DEC,
6179 NULL((void*)0), 0x0, "The error code at its full width (12.1 and later)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6180 { &hf_tns_data_oer_rowcount_ext, {
6181 "Row Count (64 bit)", "tns.data_oer.rowcount64", FT_UINT64, BASE_DEC,
6182 NULL((void*)0), 0x0, "The row count at its full width (12.1 and later)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6183 { &hf_tns_data_oer_sql_type, {
6184 "SQL Type", "tns.data_oer.sql_type", FT_UINT32, BASE_DEC,
6185 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6186 { &hf_tns_data_oer_checksum, {
6187 "Server Checksum", "tns.data_oer.checksum", FT_UINT32, BASE_HEX,
6188 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6189 { &hf_tns_data_oer_message, {
6190 "Message", "tns.data_oer.message", FT_STRING, BASE_NONE,
6191 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6192
6193 { &hf_tns_data_opi_version2_banner_len, {
6194 "Banner Length", "tns.data_opi.vers2.banner_len", FT_UINT8, BASE_DEC,
6195 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6196 { &hf_tns_data_opi_version2_banner, {
6197 "Banner", "tns.data_opi.vers2.banner", FT_STRING, BASE_NONE,
6198 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6199 { &hf_tns_data_opi_version2_vsnum, {
6200 "Version", "tns.data_opi.vers2.version", FT_UINT32, BASE_CUSTOM,
6201 CF_FUNC(vsnum_to_vstext_basecustom)((const void *) (size_t) (vsnum_to_vstext_basecustom)), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6202
6203 { &hf_tns_data_opi_num_of_params, {
6204 "Number of parameters", "tns.data_opi.num_of_params", FT_UINT8, BASE_DEC,
6205 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6206 { &hf_tns_data_opi_param_length, {
6207 "Length", "tns.data_opi.param_length", FT_UINT8, BASE_DEC,
6208 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6209 { &hf_tns_data_opi_param_name, {
6210 "Name", "tns.data_opi.param_name", FT_STRING, BASE_NONE,
6211 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6212 { &hf_tns_data_opi_param_value, {
6213 "Value", "tns.data_opi.param_value", FT_STRING, BASE_NONE,
6214 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6215
6216 { &hf_tns_data_iov_num_binds, {
6217 "Number of Binds", "tns.data_iov.num_binds", FT_UINT32, BASE_DEC,
6218 NULL((void*)0), 0x0, "num_iters * 256 + num_requests", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6219 { &hf_tns_data_iov_bind_dir, {
6220 "Bind Direction", "tns.data_iov.bind_dir", FT_UINT8, BASE_DEC,
6221 VALS(tns_iov_bind_dirs)((0 ? (const struct _value_string*)0 : ((tns_iov_bind_dirs)))
)
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6222
6223 { &hf_tns_data_bind_retcode, {
6224 "Return Code", "tns.data_bind.retcode", FT_INT32, BASE_DEC,
6225 NULL((void*)0), 0x0, "Non-zero when an OUT value was truncated", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6226 { &hf_tns_data_dcb_num_columns, {
6227 "Number of Columns", "tns.data_dcb.num_columns", FT_UINT32, BASE_DEC,
6228 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6229 { &hf_tns_data_col_type, {
6230 "Data Type", "tns.data_col.type", FT_UINT8, BASE_DEC,
6231 VALS(tns_data_types)((0 ? (const struct _value_string*)0 : ((tns_data_types)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6232 { &hf_tns_data_col_precision, {
6233 "Precision", "tns.data_col.precision", FT_UINT8, BASE_DEC,
6234 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6235 { &hf_tns_data_col_scale, {
6236 "Scale", "tns.data_col.scale", FT_INT32, BASE_DEC,
6237 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6238 { &hf_tns_data_col_max_length, {
6239 "Max Data Length", "tns.data_col.max_length", FT_UINT32, BASE_DEC,
6240 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6241 { &hf_tns_data_col_charset, {
6242 "Charset", "tns.data_col.charset", FT_UINT32, BASE_DEC,
6243 VALS(tns_charsets)((0 ? (const struct _value_string*)0 : ((tns_charsets)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6244 { &hf_tns_data_col_csform, {
6245 "Charset Form", "tns.data_col.csform", FT_UINT8, BASE_DEC,
6246 VALS(tns_csform_vals)((0 ? (const struct _value_string*)0 : ((tns_csform_vals)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6247 { &hf_tns_data_col_max_size, {
6248 "Max Size", "tns.data_col.max_size", FT_UINT32, BASE_DEC,
6249 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6250 { &hf_tns_data_col_nulls_ok, {
6251 "Nulls Allowed", "tns.data_col.nulls_ok", FT_UINT8, BASE_DEC,
6252 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6253 { &hf_tns_data_col_name, {
6254 "Column Name", "tns.data_col.name", FT_STRING, BASE_NONE,
6255 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6256
6257 { &hf_tns_data_col_uds_flags, {
6258 "UDS Flags", "tns.data_col.uds_flags", FT_UINT32, BASE_HEX,
6259 NULL((void*)0), 0x0, "Marks a JSON column", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6260 { &hf_tns_data_col_domain_schema, {
6261 "Domain Schema", "tns.data_col.domain_schema", FT_STRING, BASE_NONE,
6262 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6263 { &hf_tns_data_col_domain_name, {
6264 "Domain Name", "tns.data_col.domain_name", FT_STRING, BASE_NONE,
6265 NULL((void*)0), 0x0, "The column's SQL domain", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6266 { &hf_tns_data_col_annotation, {
6267 "Annotation", "tns.data_col.annotation", FT_STRING, BASE_NONE,
6268 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6269 { &hf_tns_data_col_vector_dims, {
6270 "Vector Dimensions", "tns.data_col.vector_dims", FT_UINT32, BASE_DEC,
6271 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6272 { &hf_tns_data_col_vector_format, {
6273 "Vector Format", "tns.data_col.vector_format", FT_UINT8, BASE_DEC,
6274 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6275 { &hf_tns_data_rxh_num_requests, {
6276 "Number of Requests", "tns.data_rxh.num_requests", FT_UINT32, BASE_DEC,
6277 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6278 { &hf_tns_data_rxh_iter_num, {
6279 "Iteration Number", "tns.data_rxh.iter_num", FT_UINT32, BASE_DEC,
6280 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6281 { &hf_tns_data_bit_vector, {
6282 "Bit Vector", "tns.data.bit_vector", FT_BYTES, BASE_NONE,
6283 NULL((void*)0), 0x0, "Columns the next row sends; a clear bit repeats the previous row's value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6284 { &hf_tns_data_bvc_num_cols_sent, {
6285 "Columns Sent", "tns.data_bvc.num_cols_sent", FT_UINT16, BASE_DEC,
6286 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6287 { &hf_tns_data_irs_num_results, {
6288 "Number of Result Sets", "tns.data_irs.num_results", FT_UINT32, BASE_DEC,
6289 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6290 { &hf_tns_data_rxh_num_iters, {
6291 "Number of Iterations", "tns.data_rxh.num_iters", FT_UINT32, BASE_DEC,
6292 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6293
6294 { &hf_tns_data_all8_options, {
6295 "Options", "tns.data_all8.options", FT_UINT32, BASE_HEX,
6296 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6297 { &hf_tns_data_all8_opt_parse, {
6298 "Parse", "tns.data_all8.options.parse", FT_BOOLEAN, 32,
6299 NULL((void*)0), 0x00000001, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6300 { &hf_tns_data_all8_opt_bind, {
6301 "Bind Values Present", "tns.data_all8.options.bind", FT_BOOLEAN, 32,
6302 NULL((void*)0), 0x00000008, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6303 { &hf_tns_data_all8_opt_define, {
6304 "Define Columns Present", "tns.data_all8.options.define", FT_BOOLEAN, 32,
6305 NULL((void*)0), 0x00000010, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6306 { &hf_tns_data_all8_opt_execute, {
6307 "Execute", "tns.data_all8.options.execute", FT_BOOLEAN, 32,
6308 NULL((void*)0), 0x00000020, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6309 { &hf_tns_data_all8_opt_commit, {
6310 "Autocommit", "tns.data_all8.options.commit", FT_BOOLEAN, 32,
6311 NULL((void*)0), 0x00000100, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6312 { &hf_tns_data_all8_opt_plsql, {
6313 "PL/SQL Binds", "tns.data_all8.options.plsql", FT_BOOLEAN, 32,
6314 NULL((void*)0), 0x00000400, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6315 { &hf_tns_data_all8_opt_fetch, {
6316 "Fetch", "tns.data_all8.options.fetch", FT_BOOLEAN, 32,
6317 NULL((void*)0), 0x00000040, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6318 { &hf_tns_data_all8_opt_not_plsql, {
6319 "Not PL/SQL", "tns.data_all8.options.not_plsql", FT_BOOLEAN, 32,
6320 NULL((void*)0), 0x00008000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6321 { &hf_tns_data_all8_opt_describe, {
6322 "Describe", "tns.data_all8.options.describe", FT_BOOLEAN, 32,
6323 NULL((void*)0), 0x00020000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6324 { &hf_tns_data_all8_opt_batch_errors, {
6325 "Batch Errors", "tns.data_all8.options.batch_errors", FT_BOOLEAN, 32,
6326 NULL((void*)0), 0x00080000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6327 { &hf_tns_data_all8_fetch_rows, {
6328 "Fetch Rows", "tns.data_all8.fetch_rows", FT_UINT32, BASE_DEC,
6329 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6330 { &hf_tns_data_all8_iterations, {
6331 "Execution Count", "tns.data_all8.iterations", FT_UINT32, BASE_DEC,
6332 NULL((void*)0), 0x0, "Number of times a DML statement runs (array DML)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6333 { &hf_tns_data_all8_prefetch, {
6334 "Prefetch Rows", "tns.data_all8.prefetch", FT_UINT32, BASE_DEC,
6335 NULL((void*)0), 0x0, "Rows a query returns with the execute, before any fetch", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6336 { &hf_tns_data_all8_is_query, {
6337 "Query", "tns.data_all8.is_query", FT_BOOLEAN, BASE_NONE,
6338 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6339 { &hf_tns_data_all8_exec_flags, {
6340 "Execute Flags", "tns.data_all8.exec_flags", FT_UINT32, BASE_HEX,
6341 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6342 { &hf_tns_data_all8_xflag_scrollable, {
6343 "Scrollable", "tns.data_all8.exec_flags.scrollable", FT_BOOLEAN, 32,
6344 NULL((void*)0), 0x00000002, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6345 { &hf_tns_data_all8_xflag_no_cancel_on_eof, {
6346 "No Cancel on EOF", "tns.data_all8.exec_flags.no_cancel_on_eof", FT_BOOLEAN, 32,
6347 NULL((void*)0), 0x00000080, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6348 { &hf_tns_data_all8_xflag_dml_rowcounts, {
6349 "DML Row Counts", "tns.data_all8.exec_flags.dml_rowcounts", FT_BOOLEAN, 32,
6350 NULL((void*)0), 0x00004000, "Return the rows each iteration of an array DML affected", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6351 { &hf_tns_data_all8_xflag_implicit_rs, {
6352 "Implicit Result Sets", "tns.data_all8.exec_flags.implicit_resultset", FT_BOOLEAN, 32,
6353 NULL((void*)0), 0x00008000, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6354 { &hf_tns_data_all8_fetch_orientation, {
6355 "Fetch Orientation", "tns.data_all8.fetch_orientation", FT_UINT32, BASE_HEX,
6356 VALS(tns_fetch_orientations)((0 ? (const struct _value_string*)0 : ((tns_fetch_orientations
))))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6357 { &hf_tns_data_all8_fetch_pos, {
6358 "Fetch Position", "tns.data_all8.fetch_pos", FT_UINT32, BASE_DEC,
6359 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6360 { &hf_tns_data_reexec_iterations, {
6361 "Execution Count", "tns.data_reexec.iterations", FT_UINT32, BASE_DEC,
6362 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6363 { &hf_tns_data_reexec_options2, {
6364 "Options 2", "tns.data_reexec.options2", FT_UINT32, BASE_HEX,
6365 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6366 { &hf_tns_data_reexec_opt2_commit, {
6367 "Autocommit", "tns.data_reexec.options2.commit", FT_BOOLEAN, 32,
6368 NULL((void*)0), 0x00000001, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6369 { &hf_tns_data_all8_oci_preamble, {
6370 "Preamble", "tns.data_all8.oci_preamble", FT_STRING, BASE_NONE,
6371 NULL((void*)0), 0x0, "The fixed execute preamble of an OCI client", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6372 { &hf_tns_data_all8_define_count, {
6373 "Define Count", "tns.data_all8.define_count", FT_UINT32, BASE_DEC,
6374 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6375 { &hf_tns_data_all8_bind_count, {
6376 "Bind Count", "tns.data_all8.bind_count", FT_UINT32, BASE_DEC,
6377 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6378 { &hf_tns_data_all8_sql, {
6379 "SQL Text", "tns.data_all8.sql", FT_STRING, BASE_NONE,
6380 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6381 { &hf_tns_data_bind_value, {
6382 "Bind Value", "tns.data_bind.value", FT_BYTES, BASE_NONE,
6383 NULL((void*)0), 0x0, "Raw type-encoded bind value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6384 { &hf_tns_data_fetch_rows, {
6385 "Rows to Fetch", "tns.data_fetch.rows", FT_UINT32, BASE_DEC,
6386 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6387 { &hf_tns_data_lob_op, {
6388 "LOB Operation", "tns.data_lob.op", FT_UINT32, BASE_HEX,
6389 VALS(tns_lob_ops)((0 ? (const struct _value_string*)0 : ((tns_lob_ops)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6390 { &hf_tns_data_lob_offset, {
6391 "Source Offset", "tns.data_lob.offset", FT_UINT64, BASE_DEC,
6392 NULL((void*)0), 0x0, "1-based offset into the LOB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6393 { &hf_tns_data_lob_locator, {
6394 "Locator", "tns.data_lob.locator", FT_BYTES, BASE_NONE,
6395 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6396 { &hf_tns_data_lob_charset, {
6397 "Charset", "tns.data_lob.charset", FT_UINT32, BASE_DEC,
6398 VALS(tns_charsets)((0 ? (const struct _value_string*)0 : ((tns_charsets)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6399 { &hf_tns_data_lob_data, {
6400 "Data", "tns.data_lob.data", FT_BYTES, BASE_NONE,
6401 NULL((void*)0), 0x0, "LOB content; UTF-16BE for a CLOB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6402 { &hf_tns_data_lob_total_size, {
6403 "Total Locator Size", "tns.data_lob.total_size", FT_UINT32, BASE_DEC,
6404 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6405 { &hf_tns_data_pgy_schema, {
6406 "Current Schema", "tns.data_piggyback.schema", FT_STRING, BASE_NONE,
6407 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6408 { &hf_tns_data_pgy_session_state, {
6409 "Session State", "tns.data_piggyback.session_state", FT_UINT64, BASE_HEX,
6410 NULL((void*)0), 0x0, "Request boundary: the client begins or ends a request", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6411 { &hf_tns_data_pgy_e2e_flags, {
6412 "Changed Attributes", "tns.data_piggyback.e2e_flags", FT_UINT32, BASE_HEX,
6413 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6414 { &hf_tns_data_pgy_client_id, {
6415 "Client Identifier", "tns.data_piggyback.client_id", FT_STRING, BASE_NONE,
6416 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6417 { &hf_tns_data_pgy_module, {
6418 "Module", "tns.data_piggyback.module", FT_STRING, BASE_NONE,
6419 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6420 { &hf_tns_data_pgy_action, {
6421 "Action", "tns.data_piggyback.action", FT_STRING, BASE_NONE,
6422 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6423 { &hf_tns_data_pgy_client_info, {
6424 "Client Info", "tns.data_piggyback.client_info", FT_STRING, BASE_NONE,
6425 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6426 { &hf_tns_data_pgy_dbop, {
6427 "Database Operation", "tns.data_piggyback.dbop", FT_STRING, BASE_NONE,
6428 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6429 { &hf_tns_data_pgy_error_set_id, {
6430 "Error Set Id", "tns.data_piggyback.error_set_id", FT_UINT16, BASE_DEC,
6431 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6432 { &hf_tns_data_pgy_error_set_mode, {
6433 "Error Set Mode", "tns.data_piggyback.error_set_mode", FT_UINT8, BASE_DEC,
6434 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6435 { &hf_tns_data_pgy_pipeline_mode, {
6436 "Pipeline Mode", "tns.data_piggyback.pipeline_mode", FT_UINT8, BASE_DEC,
6437 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6438 { &hf_tns_data_pgy_sec_flags, {
6439 "Security Context Flags", "tns.data_piggyback.sec_flags", FT_UINT32, BASE_HEX,
6440 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6441 { &hf_tns_data_pgy_sec_key, {
6442 "Security Context Key", "tns.data_piggyback.sec_key", FT_STRING, BASE_NONE,
6443 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6444 { &hf_tns_data_pgy_sec_value, {
6445 "Security Context Value", "tns.data_piggyback.sec_value", FT_BYTES, BASE_NONE,
6446 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6447 { &hf_tns_data_release_tag, {
6448 "Tag", "tns.data_release.tag", FT_STRING, BASE_NONE,
6449 NULL((void*)0), 0x0, "Session tag for the pool", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6450 { &hf_tns_data_release_mode, {
6451 "Release Mode", "tns.data_release.mode", FT_UINT32, BASE_HEX,
6452 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6453 { &hf_tns_data_release_mode_deauth, {
6454 "Deauthenticate", "tns.data_release.mode.deauthenticate", FT_BOOLEAN, 32,
6455 NULL((void*)0), 0x00000002, "The session is being closed, not just returned", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6456 { &hf_tns_data_tpc_switch_op, {
6457 "Operation", "tns.data_tpc.switch_op", FT_UINT32, BASE_HEX,
6458 VALS(tns_tpc_switch_ops)((0 ? (const struct _value_string*)0 : ((tns_tpc_switch_ops))
))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6459 { &hf_tns_data_tpc_change_op, {
6460 "Operation", "tns.data_tpc.change_op", FT_UINT32, BASE_HEX,
6461 VALS(tns_tpc_change_ops)((0 ? (const struct _value_string*)0 : ((tns_tpc_change_ops))
))
, 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6462 { &hf_tns_data_tpc_format_id, {
6463 "XID Format Id", "tns.data_tpc.format_id", FT_UINT32, BASE_DEC,
6464 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6465 { &hf_tns_data_tpc_gtrid, {
6466 "Global Transaction Id", "tns.data_tpc.gtrid", FT_BYTES, BASE_NONE,
6467 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6468 { &hf_tns_data_tpc_bqual, {
6469 "Branch Qualifier", "tns.data_tpc.bqual", FT_BYTES, BASE_NONE,
6470 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6471 { &hf_tns_data_tpc_flags, {
6472 "Flags", "tns.data_tpc.flags", FT_UINT32, BASE_HEX,
6473 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6474 { &hf_tns_data_tpc_timeout, {
6475 "Timeout", "tns.data_tpc.timeout", FT_UINT32, BASE_DEC,
6476 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6477 { &hf_tns_data_tpc_state, {
6478 "State", "tns.data_tpc.state", FT_UINT32, BASE_DEC,
6479 VALS(tns_tpc_states)((0 ? (const struct _value_string*)0 : ((tns_tpc_states)))), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6480 { &hf_tns_data_tpc_context, {
6481 "Transaction Context", "tns.data_tpc.context", FT_BYTES, BASE_NONE,
6482 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6483 { &hf_tns_data_tpc_app_value, {
6484 "Application Value", "tns.data_tpc.app_value", FT_UINT32, BASE_DEC,
6485 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6486 { &hf_tns_data_tpc_internal_name, {
6487 "Internal Name", "tns.data_tpc.internal_name", FT_STRING, BASE_NONE,
6488 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6489 { &hf_tns_data_tpc_external_name, {
6490 "External Name", "tns.data_tpc.external_name", FT_STRING, BASE_NONE,
6491 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6492 { &hf_tns_data_lob_flag, {
6493 "Result", "tns.data_lob.flag", FT_BOOLEAN, BASE_NONE,
6494 NULL((void*)0), 0x0, "Whether the LOB is open, or the file exists", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6495 { &hf_tns_data_lob_amount, {
6496 "Amount", "tns.data_lob.amount", FT_UINT64, BASE_DEC,
6497 NULL((void*)0), 0x0, "Characters for a CLOB, bytes for a BLOB; the mode for OPEN", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6498 { &hf_tns_data_col_value, {
6499 "Column Value", "tns.data_col.value", FT_BYTES, BASE_NONE,
6500 NULL((void*)0), 0x0, "Raw type-encoded row column value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6501
6502 { &hf_tns_data_lob_size, {
6503 "LOB Size", "tns.data_lob.size", FT_UINT64, BASE_DEC,
6504 NULL((void*)0), 0x0, "Characters for a CLOB, bytes for a BLOB", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6505 { &hf_tns_data_lob_chunk_size, {
6506 "LOB Chunk Size", "tns.data_lob.chunk_size", FT_UINT32, BASE_DEC,
6507 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6508 { &hf_tns_data_json_image, {
6509 "OSON Image", "tns.data_json.image", FT_BYTES, BASE_NONE,
6510 NULL((void*)0), 0x0, "Binary JSON (OSON) value", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6511 { &hf_tns_data_vector_image, {
6512 "Vector Image", "tns.data_vector.image", FT_BYTES, BASE_NONE,
6513 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6514 { &hf_tns_data_obj_toid, {
6515 "Type OID", "tns.data_obj.toid", FT_BYTES, BASE_NONE,
6516 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6517 { &hf_tns_data_obj_image, {
6518 "Object Image", "tns.data_obj.image", FT_BYTES, BASE_NONE,
6519 NULL((void*)0), 0x0, "Packed object attributes, or an XMLType document", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6520 { &hf_tns_data_descriptor_row_count, {
6521 "Row Count", "tns.data_descriptor.row_count", FT_UINT32, BASE_DEC,
6522 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6523 { &hf_tns_data_descriptor_row_size, {
6524 "Row Size", "tns.data_descriptor.row_size", FT_UINT32, BASE_DEC,
6525 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6526
6527 { &hf_tns_reserved_byte, {
6528 "Reserved Byte", "tns.reserved_byte", FT_BYTES, BASE_NONE,
6529 NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }},
6530 { &hf_tns_packet_type, {
6531 "Packet Type", "tns.type", FT_UINT8, BASE_DEC,
6532 VALS(tns_type_vals)((0 ? (const struct _value_string*)0 : ((tns_type_vals)))), 0x0, "Type of TNS packet", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) }}
6533
6534 };
6535
6536 static int *ett[] = {
6537 &ett_tns,
6538 &ett_tns_connect,
6539 &ett_tns_accept,
6540 &ett_tns_refuse,
6541 &ett_tns_abort,
6542 &ett_tns_redirect,
6543 &ett_tns_marker,
6544 &ett_tns_attention,
6545 &ett_tns_control,
6546 &ett_tns_data,
6547 &ett_tns_data_flag,
6548 &ett_tns_acc_versions,
6549 &ett_tns_opi_params,
6550 &ett_tns_opi_par,
6551 &ett_tns_sopt_flag,
6552 &ett_tns_ntp_flag,
6553 &ett_tns_conn_flag,
6554 &ett_tns_accept_flags2,
6555 &ett_tns_rows,
6556 &ett_tns_setdt_caphdr,
6557 &ett_tns_setdt_overrides,
6558 &ett_tns_setdt_override,
6559 &ett_tns_oer,
6560 &ett_tns_call_status,
6561 &ett_tns_auth_mode,
6562 &ett_tns_sns_service,
6563 &ett_tns_sns_subpacket,
6564 &ett_tns_release_mode,
6565 &ett_tns_rpa,
6566 &ett_tns_kv,
6567 &ett_tns_iov,
6568 &ett_tns_dcb_col,
6569 &ett_tns_all8_options,
6570 &ett_tns_all8_i4,
6571 &ett_tns_all8_exec_flags,
6572 &ett_tns_binds,
6573 &ett_tns_bind,
6574 &ett_tns_defines,
6575 &ett_tns_reexec_options2,
6576 &ett_tns_bind_row,
6577 &ett_tns_rxd_row,
6578 &ett_tns_value,
6579 &ett_tns_irs,
6580 &ett_tns_out_binds,
6581 &ett_sql
6582 };
6583
6584 static ei_register_info ei[] = {
6585 { &ei_tns_connect_data_next_packet, { "tns.connect_data.next_packet", PI_REQUEST_CODE0x04000000, PI_CHAT0x00200000, "Long Connect Data (> 221 bytes) carried in subsequent Data packet", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
6586 { &ei_tns_data_descriptor_size_mismatch, { "tns.data_descriptor.size_mismatch", PI_PROTOCOL0x09000000, PI_WARN0x00600000, "Data size from summing row sizes differs from size in descriptor", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
6587 { &ei_tns_data_piggyback_cursors, { "tns.data.piggyback.cursors.invalid", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Cursor count is larger than the data left in the packet", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
6588 { &ei_tns_data_count_too_large, { "tns.data.count.invalid", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Count is larger than the data left in the packet", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
6589 { &ei_tns_data_encrypted, { "tns.data.encrypted", PI_DECRYPTION0x0c000000, PI_NOTE0x00400000, "Encrypted by native network encryption", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE
, BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE
, -1, ((void*)0)}}
}},
6590 };
6591
6592 module_t *tns_module;
6593 expert_module_t* expert_tns;
6594
6595 proto_tns = proto_register_protocol("Transparent Network Substrate Protocol", "TNS", "tns");
6596 proto_register_field_array(proto_tns, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0]));
6597 proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0]));
6598 expert_tns = expert_register_protocol(proto_tns);
6599 expert_register_field_array(expert_tns, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
6600 tns_handle = register_dissector("tns", dissect_tns, proto_tns);
6601
6602 tns_module = prefs_register_protocol(proto_tns, NULL((void*)0));
6603 prefs_register_bool_preference(tns_module, "desegment_tns_messages",
6604 "Reassemble TNS messages spanning multiple TCP segments",
6605 "Whether the TNS dissector should reassemble messages spanning multiple TCP segments. "
6606 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
6607 &tns_desegment);
6608}
6609
6610void
6611proto_reg_handoff_tns(void)
6612{
6613 dissector_add_uint_with_preference("tcp.port", TCP_PORT_TNS1521, tns_handle);
6614}
6615
6616/*
6617 * Editor modelines - https://www.wireshark.org/tools/modelines.html
6618 *
6619 * Local variables:
6620 * c-basic-offset: 8
6621 * tab-width: 8
6622 * indent-tabs-mode: t
6623 * End:
6624 *
6625 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
6626 * :indentSize=8:tabSize=8:noTabs=false:
6627 */