Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-tns.c
blob49ebad7b26da65c8cb9a460882385b394fd33d33
1 /* packet-tns.c
2 * Routines for Oracle TNS packet dissection
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * Copied from packet-tftp.c
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include "packet-tcp.h"
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>
24 #include <wsutil/array.h>
26 void proto_register_tns(void);
28 #define TNS_HDR_LEN 8
30 /* Packet Types */
31 #define TNS_TYPE_CONNECT 1
32 #define TNS_TYPE_ACCEPT 2
33 #define TNS_TYPE_ACK 3
34 #define TNS_TYPE_REFUSE 4
35 #define TNS_TYPE_REDIRECT 5
36 #define TNS_TYPE_DATA 6
37 #define TNS_TYPE_NULL 7
38 #define TNS_TYPE_ABORT 9
39 #define TNS_TYPE_RESEND 11
40 #define TNS_TYPE_MARKER 12
41 #define TNS_TYPE_ATTENTION 13
42 #define TNS_TYPE_CONTROL 14
43 #define TNS_TYPE_DD 15
44 #define TNS_TYPE_MAX 19
46 /* Data Packet Functions */
47 #define SQLNET_SET_PROTOCOL 1
48 #define SQLNET_SET_DATATYPES 2
49 #define SQLNET_USER_OCI_FUNC 3
50 #define SQLNET_RETURN_STATUS 4
51 #define SQLNET_ACCESS_USR_ADDR 5
52 #define SQLNET_ROW_TRANSF_HDR 6
53 #define SQLNET_ROW_TRANSF_DATA 7
54 #define SQLNET_RETURN_OPI_PARAM 8
55 #define SQLNET_FUNCCOMPLETE 9
56 #define SQLNET_NERROR_RET_DEF 10
57 #define SQLNET_IOVEC_4FAST_UPI 11
58 #define SQLNET_LONG_4FAST_UPI 12
59 #define SQLNET_INVOKE_USER_CB 13
60 #define SQLNET_LOB_FILE_DF 14
61 #define SQLNET_WARNING 15
62 #define SQLNET_DESCRIBE_INFO 16
63 #define SQLNET_PIGGYBACK_FUNC 17
64 #define SQLNET_SIG_4UCS 18
65 #define SQLNET_FLUSH_BIND_DATA 19
66 #define SQLNET_SNS 0xdeadbeef
67 #define SQLNET_XTRN_PROCSERV_R1 32
68 #define SQLNET_XTRN_PROCSERV_R2 68
70 /* Return OPI Parameter's Type */
71 #define OPI_VERSION2 1
72 #define OPI_OSESSKEY 2
73 #define OPI_OAUTH 3
75 /* desegmentation of TNS over TCP */
76 static bool tns_desegment = true;
78 static dissector_handle_t tns_handle;
80 static int proto_tns;
81 static int hf_tns_request;
82 static int hf_tns_response;
83 static int hf_tns_length;
84 static int hf_tns_packet_checksum;
85 static int hf_tns_header_checksum;
86 static int hf_tns_packet_type;
87 static int hf_tns_reserved_byte;
88 static int hf_tns_version;
89 static int hf_tns_compat_version;
91 static int hf_tns_service_options;
92 static int hf_tns_sopt_flag_bconn;
93 static int hf_tns_sopt_flag_pc;
94 static int hf_tns_sopt_flag_hc;
95 static int hf_tns_sopt_flag_fd;
96 static int hf_tns_sopt_flag_hd;
97 static int hf_tns_sopt_flag_dc1;
98 static int hf_tns_sopt_flag_dc2;
99 static int hf_tns_sopt_flag_dio;
100 static int hf_tns_sopt_flag_ap;
101 static int hf_tns_sopt_flag_ra;
102 static int hf_tns_sopt_flag_sa;
104 static int hf_tns_sdu_size;
105 static int hf_tns_max_tdu_size;
107 static int hf_tns_nt_proto_characteristics;
108 static int hf_tns_ntp_flag_hangon;
109 static int hf_tns_ntp_flag_crel;
110 static int hf_tns_ntp_flag_tduio;
111 static int hf_tns_ntp_flag_srun;
112 static int hf_tns_ntp_flag_dtest;
113 static int hf_tns_ntp_flag_cbio;
114 static int hf_tns_ntp_flag_asio;
115 static int hf_tns_ntp_flag_pio;
116 static int hf_tns_ntp_flag_grant;
117 static int hf_tns_ntp_flag_handoff;
118 static int hf_tns_ntp_flag_sigio;
119 static int hf_tns_ntp_flag_sigpipe;
120 static int hf_tns_ntp_flag_sigurg;
121 static int hf_tns_ntp_flag_urgentio;
122 static int hf_tns_ntp_flag_fdio;
123 static int hf_tns_ntp_flag_testop;
125 static int hf_tns_line_turnaround;
126 static int hf_tns_value_of_one;
127 static int hf_tns_connect_data_length;
128 static int hf_tns_connect_data_offset;
129 static int hf_tns_connect_data_max;
131 static int hf_tns_connect_flags0;
132 static int hf_tns_connect_flags1;
133 static int hf_tns_conn_flag_nareq;
134 static int hf_tns_conn_flag_nalink;
135 static int hf_tns_conn_flag_enablena;
136 static int hf_tns_conn_flag_ichg;
137 static int hf_tns_conn_flag_wantna;
139 static int hf_tns_connect_data;
140 static int hf_tns_trace_cf1;
141 static int hf_tns_trace_cf2;
142 static int hf_tns_trace_cid;
144 static int hf_tns_accept_data_length;
145 static int hf_tns_accept_data_offset;
146 static int hf_tns_accept_data;
148 static int hf_tns_refuse_reason_user;
149 static int hf_tns_refuse_reason_system;
150 static int hf_tns_refuse_data_length;
151 static int hf_tns_refuse_data;
153 static int hf_tns_abort_reason_user;
154 static int hf_tns_abort_reason_system;
155 static int hf_tns_abort_data;
157 static int hf_tns_marker_type;
158 static int hf_tns_marker_data_byte;
159 /* static int hf_tns_marker_data; */
161 static int hf_tns_redirect_data_length;
162 static int hf_tns_redirect_data;
164 static int hf_tns_control_cmd;
165 static int hf_tns_control_data;
167 static int hf_tns_data_flag;
168 static int hf_tns_data_flag_send;
169 static int hf_tns_data_flag_rc;
170 static int hf_tns_data_flag_c;
171 static int hf_tns_data_flag_reserved;
172 static int hf_tns_data_flag_more;
173 static int hf_tns_data_flag_eof;
174 static int hf_tns_data_flag_dic;
175 static int hf_tns_data_flag_rts;
176 static int hf_tns_data_flag_sntt;
178 static int hf_tns_data_id;
179 static int hf_tns_data_length;
180 static int hf_tns_data_oci_id;
181 static int hf_tns_data_piggyback_id;
182 static int hf_tns_data_unused;
184 static int hf_tns_data_opi_version2_banner_len;
185 static int hf_tns_data_opi_version2_banner;
186 static int hf_tns_data_opi_version2_vsnum;
188 static int hf_tns_data_opi_num_of_params;
189 static int hf_tns_data_opi_param_length;
190 static int hf_tns_data_opi_param_name;
191 static int hf_tns_data_opi_param_value;
193 static int hf_tns_data_setp_acc_version;
194 static int hf_tns_data_setp_cli_plat;
195 static int hf_tns_data_setp_version;
196 static int hf_tns_data_setp_banner;
198 static int hf_tns_data_sns_cli_vers;
199 static int hf_tns_data_sns_srv_vers;
200 static int hf_tns_data_sns_srvcnt;
202 static int hf_tns_data_descriptor_row_count;
203 static int hf_tns_data_descriptor_row_size;
205 static int ett_tns;
206 static int ett_tns_connect;
207 static int ett_tns_accept;
208 static int ett_tns_refuse;
209 static int ett_tns_abort;
210 static int ett_tns_redirect;
211 static int ett_tns_marker;
212 static int ett_tns_attention;
213 static int ett_tns_control;
214 static int ett_tns_data;
215 static int ett_tns_data_flag;
216 static int ett_tns_acc_versions;
217 static int ett_tns_opi_params;
218 static int ett_tns_opi_par;
219 static int ett_tns_sopt_flag;
220 static int ett_tns_ntp_flag;
221 static int ett_tns_conn_flag;
222 static int ett_tns_rows;
223 static int ett_sql;
225 static expert_field ei_tns_connect_data_next_packet;
226 static expert_field ei_tns_data_descriptor_size_mismatch;
228 #define TCP_PORT_TNS 1521 /* Not IANA registered */
230 static int * const tns_connect_flags[] = {
231 &hf_tns_conn_flag_nareq,
232 &hf_tns_conn_flag_nalink,
233 &hf_tns_conn_flag_enablena,
234 &hf_tns_conn_flag_ichg,
235 &hf_tns_conn_flag_wantna,
236 NULL
239 static int * const tns_service_options[] = {
240 &hf_tns_sopt_flag_bconn,
241 &hf_tns_sopt_flag_pc,
242 &hf_tns_sopt_flag_hc,
243 &hf_tns_sopt_flag_fd,
244 &hf_tns_sopt_flag_hd,
245 &hf_tns_sopt_flag_dc1,
246 &hf_tns_sopt_flag_dc2,
247 &hf_tns_sopt_flag_dio,
248 &hf_tns_sopt_flag_ap,
249 &hf_tns_sopt_flag_ra,
250 &hf_tns_sopt_flag_sa,
251 NULL
254 static const value_string tns_type_vals[] = {
255 {TNS_TYPE_CONNECT, "Connect" },
256 {TNS_TYPE_ACCEPT, "Accept" },
257 {TNS_TYPE_ACK, "Acknowledge" },
258 {TNS_TYPE_REFUSE, "Refuse" },
259 {TNS_TYPE_REDIRECT, "Redirect" },
260 {TNS_TYPE_DATA, "Data" },
261 {TNS_TYPE_NULL, "Null" },
262 {TNS_TYPE_ABORT, "Abort" },
263 {TNS_TYPE_RESEND, "Resend"},
264 {TNS_TYPE_MARKER, "Marker"},
265 {TNS_TYPE_ATTENTION, "Attention"},
266 {TNS_TYPE_CONTROL, "Control"},
267 {TNS_TYPE_DD, "Data Descriptor"},
268 {0, NULL}
271 static const value_string tns_data_funcs[] = {
272 {SQLNET_SET_PROTOCOL, "Set Protocol"},
273 {SQLNET_SET_DATATYPES, "Set Datatypes"},
274 {SQLNET_USER_OCI_FUNC, "User OCI Functions"},
275 {SQLNET_RETURN_STATUS, "Return Status"},
276 {SQLNET_ACCESS_USR_ADDR, "Access User Address Space"},
277 {SQLNET_ROW_TRANSF_HDR, "Row Transfer Header"},
278 {SQLNET_ROW_TRANSF_DATA, "Row Transfer Data"},
279 {SQLNET_RETURN_OPI_PARAM, "Return OPI Parameter"},
280 {SQLNET_FUNCCOMPLETE, "Function Complete"},
281 {SQLNET_NERROR_RET_DEF, "N Error return definitions follow"},
282 {SQLNET_IOVEC_4FAST_UPI, "Sending I/O Vec only for fast UPI"},
283 {SQLNET_LONG_4FAST_UPI, "Sending long for fast UPI"},
284 {SQLNET_INVOKE_USER_CB, "Invoke user callback"},
285 {SQLNET_LOB_FILE_DF, "LOB/FILE data follows"},
286 {SQLNET_WARNING, "Warning messages - may be a set of them"},
287 {SQLNET_DESCRIBE_INFO, "Describe Information"},
288 {SQLNET_PIGGYBACK_FUNC, "Piggy back function follow"},
289 {SQLNET_SIG_4UCS, "Signals special action for untrusted callout support"},
290 {SQLNET_FLUSH_BIND_DATA, "Flush Out Bind data in DML/w RETURN when error"},
291 {SQLNET_XTRN_PROCSERV_R1, "External Procedures and Services Registrations"},
292 {SQLNET_XTRN_PROCSERV_R2, "External Procedures and Services Registrations"},
293 {SQLNET_SNS, "Secure Network Services"},
294 {0, NULL}
297 static const value_string tns_data_oci_subfuncs[] = {
298 {1, "Logon to Oracle"},
299 {2, "Open Cursor"},
300 {3, "Parse a Row"},
301 {4, "Execute a Row"},
302 {5, "Fetch a Row"},
303 {8, "Close Cursor"},
304 {9, "Logoff of Oracle"},
305 {10, "Describe a select list column"},
306 {11, "Define where the column goes"},
307 {12, "Auto commit on"},
308 {13, "Auto commit off"},
309 {14, "Commit"},
310 {15, "Rollback"},
311 {16, "Set fatal error options"},
312 {17, "Resume current operation"},
313 {18, "Get Oracle version-date string"},
314 {19, "Until we get rid of OASQL"},
315 {20, "Cancel the current operation"},
316 {21, "Get error message"},
317 {22, "Exit Oracle command"},
318 {23, "Special function"},
319 {24, "Abort"},
320 {25, "Dequeue by RowID"},
321 {26, "Fetch a long column value"},
322 {27, "Create Access Module"},
323 {28, "Save Access Module Statement"},
324 {29, "Save Access Module"},
325 {30, "Parse Access Module Statement"},
326 {31, "How many items?"},
327 {32, "Initialize Oracle"},
328 {33, "Change User ID"},
329 {34, "Bind by reference positional"},
330 {35, "Get n'th Bind Variable"},
331 {36, "Get n'th Into Variable"},
332 {37, "Bind by reference"},
333 {38, "Bind by reference numeric"},
334 {39, "Parse and Execute"},
335 {40, "Parse for syntax (only)"},
336 {41, "Parse for syntax and SQL Dictionary lookup"},
337 {42, "Continue serving after EOF"},
338 {43, "Array describe"},
339 {44, "Init sys pars command table"},
340 {45, "Finalize sys pars command table"},
341 {46, "Put sys par in command table"},
342 {47, "Get sys pars from command table"},
343 {48, "Start Oracle (V6)"},
344 {49, "Shutdown Oracle (V6)"},
345 {50, "Run Independent Process (V6)"},
346 {51, "Test RAM (V6)"},
347 {52, "Archive operation (V6)"},
348 {53, "Media Recovery - start (V6)"},
349 {54, "Media Recovery - record tablespace to recover (V6)"},
350 {55, "Media Recovery - get starting log seq # (V6)"},
351 {56, "Media Recovery - recover using offline log (V6)"},
352 {57, "Media Recovery - cancel media recovery (V6)"},
353 {58, "Logon to Oracle (V6)"},
354 {59, "Get Oracle version-date string in new format"},
355 {60, "Initialize Oracle"},
356 {61, "Reserved for MAC; close all cursors"},
357 {62, "Bundled execution call"},
358 {65, "For direct loader: functions"},
359 {66, "For direct loader: buffer transfer"},
360 {67, "Distrib. trans. mgr. RPC"},
361 {68, "Describe indexes for distributed query"},
362 {69, "Session operations"},
363 {70, "Execute using synchronized system commit numbers"},
364 {71, "Fast UPI calls to OPIAL7"},
365 {72, "Long Fetch (V7)"},
366 {73, "Call OPIEXE from OPIALL: no two-task access"},
367 {74, "Parse Call (V7) to deal with various flavours"},
368 {76, "RPC call from PL/SQL"},
369 {77, "Do a KGL operation"},
370 {78, "Execute and Fetch"},
371 {79, "X/Open XA operation"},
372 {80, "New KGL operation call"},
373 {81, "2nd Half of Logon"},
374 {82, "1st Half of Logon"},
375 {83, "Do Streaming Operation"},
376 {84, "Open Session (71 interface)"},
377 {85, "X/Open XA operations (71 interface)"},
378 {86, "Debugging operations"},
379 {87, "Special debugging operations"},
380 {88, "XA Start"},
381 {89, "XA Switch and Commit"},
382 {90, "Direct copy from db buffers to client address"},
383 {91, "OKOD Call (In Oracle <= 7 this used to be Connect"},
384 {93, "RPI Callback with ctxdef"},
385 {94, "Bundled execution call (V7)"},
386 {95, "Do Streaming Operation without begintxn"},
387 {96, "LOB and FILE related calls"},
388 {97, "File Create call"},
389 {98, "Describe query (V8) call"},
390 {99, "Connect (non-blocking attach host)"},
391 {100, "Open a recursive cursor"},
392 {101, "Bundled KPR Execution"},
393 {102, "Bundled PL/SQL execution"},
394 {103, "Transaction start, attach, detach"},
395 {104, "Transaction commit, rollback, recover"},
396 {105, "Cursor close all"},
397 {106, "Failover into piggyback"},
398 {107, "Session switching piggyback (V8)"},
399 {108, "Do Dummy Defines"},
400 {109, "Init sys pars (V8)"},
401 {110, "Finalize sys pars (V8)"},
402 {111, "Put sys par in par space (V8)"},
403 {112, "Terminate sys pars (V8)"},
404 {114, "Init Untrusted Callbacks"},
405 {115, "Generic authentication call"},
406 {116, "FailOver Get Instance call"},
407 {117, "Oracle Transaction service Commit remote sites"},
408 {118, "Get the session key"},
409 {119, "Describe any (V8)"},
410 {120, "Cancel All"},
411 {121, "AQ Enqueue"},
412 {122, "AQ Dequeue"},
413 {123, "Object transfer"},
414 {124, "RFS Call"},
415 {125, "Kernel programmatic notification"},
416 {126, "Listen"},
417 {127, "Oracle Transaction service Commit remote sites (V >= 8.1.3)"},
418 {128, "Dir Path Prepare"},
419 {129, "Dir Path Load Stream"},
420 {130, "Dir Path Misc. Ops"},
421 {131, "Memory Stats"},
422 {132, "AQ Properties Status"},
423 {134, "Remote Fetch Archive Log FAL"},
424 {135, "Client ID propagation"},
425 {136, "DR Server CNX Process"},
426 {138, "SPFILE parameter put"},
427 {139, "KPFC exchange"},
428 {140, "Object Transfer (V8.2)"},
429 {141, "Push Transaction"},
430 {142, "Pop Transaction"},
431 {143, "KFN Operation"},
432 {144, "Dir Path Unload Stream"},
433 {145, "AQ batch enqueue dequeue"},
434 {146, "File Transfer"},
435 {147, "Ping"},
436 {148, "TSM"},
437 {150, "Begin TSM"},
438 {151, "End TSM"},
439 {152, "Set schema"},
440 {153, "Fetch from suspended result set"},
441 {154, "Key/Value pair"},
442 {155, "XS Create session Operation"},
443 {156, "XS Session Roundtrip Operation"},
444 {157, "XS Piggyback Operation"},
445 {158, "KSRPC Execution"},
446 {159, "Streams combined capture apply"},
447 {160, "AQ replay information"},
448 {161, "SSCR"},
449 {162, "Session Get"},
450 {163, "Session RLS"},
451 {165, "Workload replay data"},
452 {166, "Replay statistic data"},
453 {167, "Query Cache Stats"},
454 {168, "Query Cache IDs"},
455 {169, "RPC Test Stream"},
456 {170, "Replay PL/SQL RPC"},
457 {171, "XStream Out"},
458 {172, "Golden Gate RPC"},
459 {0, NULL}
461 static value_string_ext tns_data_oci_subfuncs_ext = VALUE_STRING_EXT_INIT(tns_data_oci_subfuncs);
463 static const value_string tns_marker_types[] = {
464 {0, "Data Marker - 0 Data Bytes"},
465 {1, "Data Marker - 1 Data Bytes"},
466 {2, "Attention Marker"},
467 {0, NULL}
470 static const value_string tns_control_cmds[] = {
471 {1, "Oracle Trace Command"},
472 {0, NULL}
475 typedef struct _tns_conv_info_t {
476 uint32_t pending_connect_data;
477 } tns_conv_info_t;
479 void proto_reg_handoff_tns(void);
480 static int dissect_tns_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_);
482 static tns_conv_info_t*
483 tns_get_conv_info(packet_info *pinfo)
485 conversation_t *conversation = find_or_create_conversation(pinfo);
487 tns_conv_info_t *tns_info = (tns_conv_info_t *)conversation_get_proto_data(conversation, proto_tns);
488 if (!tns_info) {
489 tns_info = wmem_new0(wmem_file_scope(), tns_conv_info_t);
490 conversation_add_proto_data(conversation, proto_tns, tns_info);
492 return tns_info;
495 static unsigned get_data_func_id(tvbuff_t *tvb, int offset)
497 /* Determine Data Function id */
498 uint8_t first_byte;
500 first_byte =
501 tvb_reported_length_remaining(tvb, offset) > 0 ? tvb_get_uint8(tvb, offset) : 0;
503 if ( tvb_bytes_exist(tvb, offset, 4) && first_byte == 0xDE &&
504 tvb_get_uint24(tvb, offset+1, ENC_BIG_ENDIAN) == 0xADBEEF )
506 return SQLNET_SNS;
508 else
510 return (unsigned)first_byte;
514 static void vsnum_to_vstext_basecustom(char *result, uint32_t vsnum)
517 * Translate hex value to human readable version value, described at
518 * http://docs.oracle.com/cd/B28359_01/server.111/b28310/dba004.htm
520 snprintf(result, ITEM_LABEL_LENGTH, "%d.%d.%d.%d.%d",
521 vsnum >> 24,
522 (vsnum >> 20) & 0xf,
523 (vsnum >> 12) & 0xf,
524 (vsnum >> 8) & 0xf,
525 vsnum & 0xff);
528 static void dissect_tns_data_descriptor(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tns_tree, uint32_t length)
530 /* This is used by Oracle 12c for at least sending LOB/FILE data. */
531 proto_tree *dd_tree, *row_tree;
532 proto_item *ti;
533 uint32_t data_len, row_count, row_size, total_row_size = 0;
534 int orig_offset = offset;
536 /* We only get here after tcp_dissect_pdus(), length is guaranteed. */
537 DISSECTOR_ASSERT_CMPINT(length, >=, TNS_HDR_LEN);
539 dd_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1, ett_tns_data, NULL, "Data Descriptor");
541 /* No idea what this is. Usually 0x0003. */
542 offset += 4;
543 proto_tree_add_item_ret_uint(dd_tree, hf_tns_data_length, tvb,
544 offset, 4, ENC_BIG_ENDIAN, &data_len);
545 offset += 4;
547 /* This next parameter looks like: number of big endian shorts that follow,
548 * the sum of the shorts equals the file length above - each short maxes
549 * out at 0x1f7c = 8060, presumably related to the page size / max table
550 * row size in Microsoft SQL Server? Something about how many rows it
551 * would take to store this in-table?
553 proto_tree_add_item_ret_uint(dd_tree, hf_tns_data_descriptor_row_count, tvb,
554 offset, 4, ENC_BIG_ENDIAN, &row_count);
555 offset += 4;
556 row_tree = proto_tree_add_subtree(dd_tree, tvb, offset, row_count * 2,
557 ett_tns_rows, &ti, "Rows");
558 for (uint32_t i = 0; i < row_count; i++) {
559 proto_tree_add_item_ret_uint(row_tree, hf_tns_data_descriptor_row_size, tvb,
560 offset, 2, ENC_BIG_ENDIAN, &row_size);
561 total_row_size += row_size;
562 offset += 2;
564 proto_item_append_text(ti, " (%u bytes)", total_row_size);
565 if (total_row_size != data_len) {
566 expert_add_info(pinfo, ti, &ei_tns_data_descriptor_size_mismatch);
569 offset = orig_offset + (length - TNS_HDR_LEN);
571 call_data_dissector(tvb_new_subset_length(tvb, offset, data_len), pinfo,
572 dd_tree);
575 static void dissect_tns_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tns_tree)
577 proto_tree *data_tree;
578 unsigned data_func_id;
579 bool is_request;
580 static int * const flags[] = {
581 &hf_tns_data_flag_send,
582 &hf_tns_data_flag_rc,
583 &hf_tns_data_flag_c,
584 &hf_tns_data_flag_reserved,
585 &hf_tns_data_flag_more,
586 &hf_tns_data_flag_eof,
587 &hf_tns_data_flag_dic,
588 &hf_tns_data_flag_rts,
589 &hf_tns_data_flag_sntt,
590 NULL
593 is_request = pinfo->match_uint == pinfo->destport;
594 data_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1, ett_tns_data, NULL, "Data");
596 proto_tree_add_bitmask(data_tree, tvb, offset, hf_tns_data_flag, ett_tns_data_flag, flags, ENC_BIG_ENDIAN);
597 offset += 2;
598 data_func_id = get_data_func_id(tvb, offset);
600 /* Do this only if the Data message have a body. Otherwise, there are only Data flags. */
601 int remaining = tvb_reported_length_remaining(tvb, offset);
602 if ( remaining > 0 )
604 if (is_request) {
605 if (!PINFO_FD_VISITED(pinfo)) {
606 tns_conv_info_t *tns_info = tns_get_conv_info(pinfo);
607 if ((uint32_t)remaining == tns_info->pending_connect_data) {
608 col_append_str(pinfo->cinfo, COL_INFO, ", Connect Data");
609 proto_tree_add_item(data_tree, hf_tns_connect_data, tvb,
610 offset, -1, ENC_ASCII);
611 p_add_proto_data(wmem_file_scope(), pinfo, proto_tns, 0,
612 GUINT_TO_POINTER(tns_info->pending_connect_data));
613 tns_info->pending_connect_data = 0;
614 return;
616 } else {
617 if (p_get_proto_data(wmem_file_scope(), pinfo, proto_tns, 0) != NULL) {
618 col_append_str(pinfo->cinfo, COL_INFO, ", Connect Data");
619 proto_tree_add_item(data_tree, hf_tns_connect_data, tvb,
620 offset, -1, ENC_ASCII);
621 return;
625 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str_const(data_func_id, tns_data_funcs, "unknown"));
627 if ( (data_func_id != SQLNET_SNS) && (try_val_to_str(data_func_id, tns_data_funcs) != NULL) )
629 proto_tree_add_item(data_tree, hf_tns_data_id, tvb, offset, 1, ENC_BIG_ENDIAN);
630 offset += 1;
634 /* Handle data functions that have more than just ID */
635 switch (data_func_id)
637 case SQLNET_SET_PROTOCOL:
639 proto_tree *versions_tree;
640 proto_item *ti;
641 char sep;
642 if ( is_request )
644 versions_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1, ett_tns_acc_versions, &ti, "Accepted Versions");
645 sep = ':';
646 for (;;) {
648 * Add each accepted version as a
649 * separate item.
651 uint8_t vers;
653 vers = tvb_get_uint8(tvb, offset);
654 if (vers == 0) {
656 * A version of 0 terminates
657 * the list.
659 break;
661 proto_item_append_text(ti, "%c %u", sep, vers);
662 sep = ',';
663 proto_tree_add_uint(versions_tree, hf_tns_data_setp_acc_version, tvb, offset, 1, vers);
664 offset += 1;
666 offset += 1; /* skip the 0 terminator */
667 proto_item_set_end(ti, tvb, offset);
668 proto_tree_add_item(data_tree, hf_tns_data_setp_cli_plat, tvb, offset, -1, ENC_ASCII);
670 return; /* skip call_data_dissector */
672 else
674 int len;
675 versions_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1, ett_tns_acc_versions, &ti, "Versions");
676 sep = ':';
677 for (;;) {
679 * Add each version as a separate item.
681 uint8_t vers;
683 vers = tvb_get_uint8(tvb, offset);
684 if (vers == 0) {
686 * A version of 0 terminates
687 * the list.
689 break;
691 proto_item_append_text(ti, "%c %u", sep, vers);
692 sep = ',';
693 proto_tree_add_uint(versions_tree, hf_tns_data_setp_version, tvb, offset, 1, vers);
694 offset += 1;
696 offset += 1; /* skip the 0 terminator */
697 proto_item_set_end(ti, tvb, offset);
698 proto_tree_add_item_ret_length(data_tree, hf_tns_data_setp_banner, tvb, offset, -1, ENC_ASCII|ENC_NA, &len);
699 offset += len;
701 break;
704 case SQLNET_USER_OCI_FUNC:
705 proto_tree_add_item(data_tree, hf_tns_data_oci_id, tvb, offset, 1, ENC_BIG_ENDIAN);
706 offset += 1;
707 break;
709 case SQLNET_RETURN_OPI_PARAM:
711 uint8_t skip = 0, opi = 0;
713 if ( tvb_bytes_exist(tvb, offset, 11) )
716 * OPI_VERSION2 response has a following pattern:
718 * _ banner _ vsnum
719 * / /
720 * ..(.?)(Orac[le.+])(.?)(....).+$
722 * \ banner length (if equal to 0 then next byte indicates the length).
724 * These differences (to skip 1 or 2 bytes) due to differences in the drivers.
726 /* Orac[le.+] */
727 if ( tvb_get_ntohl(tvb, offset+2) == 0x4f726163 )
729 opi = OPI_VERSION2;
730 skip = 1;
733 else if ( tvb_get_ntohl(tvb, offset+3) == 0x4f726163 )
735 opi = OPI_VERSION2;
736 skip = 2;
740 * OPI_OSESSKEY response has a following pattern:
742 * _ pattern (v1|v2)
743 * / _ params
744 * / /
745 * (....)(........)(.+).+$
746 * ||
747 * \ if these two bytes are equal to 0x0c00 then first byte is <Param Counts> (v1),
748 * else next byte indicate it (v2).
750 /* ....AUTH (v1) */
751 else if ( tvb_get_ntoh64(tvb, offset+3) == 0x0000000c41555448 )
753 opi = OPI_OSESSKEY;
754 skip = 1;
756 /* ..AUTH_V (v2) */
757 else if ( tvb_get_ntoh64(tvb, offset+3) == 0x0c0c415554485f53 )
759 opi = OPI_OSESSKEY;
760 skip = 2;
764 * OPI_OAUTH response has a following pattern:
766 * _ pattern (v1|v2)
767 * / _ params
768 * / /
769 * (....)(........)(.+).+$
770 * ||
771 * \ if these two bytes are equal to 0x1300 then first byte is <Param Counts> (v1),
772 * else next byte indicate it (v2).
775 /* ....AUTH (v1) */
776 else if ( tvb_get_ntoh64(tvb, offset+3) == 0x0000001341555448 )
778 opi = OPI_OAUTH;
779 skip = 1;
781 /* ..AUTH_V (v2) */
782 else if ( tvb_get_ntoh64(tvb, offset+3) == 0x1313415554485f56 )
784 opi = OPI_OAUTH;
785 skip = 2;
789 if ( opi == OPI_VERSION2 )
791 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, skip, ENC_NA);
792 offset += skip;
794 uint8_t len = tvb_get_uint8(tvb, offset);
796 proto_tree_add_item(data_tree, hf_tns_data_opi_version2_banner_len, tvb, offset, 1, ENC_BIG_ENDIAN);
797 offset += 1;
799 proto_tree_add_item(data_tree, hf_tns_data_opi_version2_banner, tvb, offset, len, ENC_ASCII);
800 offset += len + (skip == 1 ? 1 : 0);
802 proto_tree_add_item(data_tree, hf_tns_data_opi_version2_vsnum, tvb, offset, 4, (skip == 1) ? ENC_BIG_ENDIAN : ENC_LITTLE_ENDIAN);
803 offset += 4;
805 else if ( opi == OPI_OSESSKEY || opi == OPI_OAUTH )
807 proto_tree *params_tree;
808 proto_item *params_ti;
809 unsigned par, params;
811 if ( skip == 1 )
813 proto_tree_add_item_ret_uint(data_tree, hf_tns_data_opi_num_of_params, tvb, offset, 1, ENC_NA, &params);
814 offset += 1;
816 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, 5, ENC_NA);
817 offset += 5;
819 else
821 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, 1, ENC_NA);
822 offset += 1;
824 proto_tree_add_item_ret_uint(data_tree, hf_tns_data_opi_num_of_params, tvb, offset, 1, ENC_NA, &params);
825 offset += 1;
827 proto_tree_add_item(data_tree, hf_tns_data_unused, tvb, offset, 2, ENC_NA);
828 offset += 2;
831 params_tree = proto_tree_add_subtree(data_tree, tvb, offset, -1, ett_tns_opi_params, &params_ti, "Parameters");
833 for ( par = 1; par <= params; par++ )
835 proto_tree *par_tree;
836 proto_item *par_ti;
837 unsigned len, offset_prev;
839 par_tree = proto_tree_add_subtree(params_tree, tvb, offset, -1, ett_tns_opi_par, &par_ti, "Parameter");
840 proto_item_append_text(par_ti, " %u", par);
842 /* Name length */
843 proto_tree_add_item_ret_uint(par_tree, hf_tns_data_opi_param_length, tvb, offset, 1, ENC_NA, &len);
844 offset += 1;
846 /* Name */
847 if ( !(len == 0 || len == 2) ) /* Not empty (2 - SQLDeveloper specific sign). */
849 proto_tree_add_item(par_tree, hf_tns_data_opi_param_name, tvb, offset, len, ENC_ASCII);
850 offset += len;
853 /* Value can be NULL. So, save offset to calculate unused data. */
854 offset_prev = offset;
855 offset += skip == 1 ? 4 : 2;
857 /* Value length */
858 if ( opi == OPI_OSESSKEY )
860 len = tvb_get_uint8(tvb, offset);
862 else /* OPI_OAUTH */
864 len = tvb_get_uint8(tvb, offset_prev) == 0 ? 0 : tvb_get_uint8(tvb, offset);
868 * Value
869 * OPI_OSESSKEY: AUTH_VFR_DATA with length 0, 9, 0x39 comes without data.
870 * OPI_OAUTH: AUTH_VFR_DATA with length 0, 0x39 comes without data.
872 if ( ((opi == OPI_OSESSKEY) && !(len == 0 || len == 9 || len == 0x39))
873 || ((opi == OPI_OAUTH) && !(len == 0 || len == 0x39)) )
875 proto_tree_add_item(par_tree, hf_tns_data_unused, tvb, offset_prev, offset - offset_prev, ENC_NA);
877 proto_tree_add_item(par_tree, hf_tns_data_opi_param_length, tvb, offset, 1, ENC_NA);
878 offset += 1;
880 proto_tree_add_item(par_tree, hf_tns_data_opi_param_value, tvb, offset, len, ENC_ASCII);
881 offset += len;
883 offset_prev = offset; /* Save offset to calculate rest of unused data */
885 else
887 offset += 1;
890 if ( opi == OPI_OSESSKEY )
892 /* SQL Developer specific fix */
893 offset += tvb_get_uint8(tvb, offset) == 2 ? 5 : 3;
895 else /* OPI_OAUTH */
897 offset += len == 0 ? 1 : 3;
900 if ( skip == 1 )
902 offset += 1 + ((len == 0 || len == 0x39) ? 3 : 4);
904 if ( opi == OPI_OAUTH )
906 offset += len == 0 ? 2 : 0;
910 proto_tree_add_item(par_tree, hf_tns_data_unused, tvb, offset_prev, offset - offset_prev, ENC_NA);
911 proto_item_set_end(par_ti, tvb, offset);
913 proto_item_set_end(params_ti, tvb, offset);
915 break;
918 case SQLNET_PIGGYBACK_FUNC:
919 proto_tree_add_item(data_tree, hf_tns_data_piggyback_id, tvb, offset, 1, ENC_BIG_ENDIAN);
920 offset += 1;
921 break;
923 case SQLNET_SNS:
925 proto_tree_add_item(data_tree, hf_tns_data_id, tvb, offset, 4, ENC_BIG_ENDIAN);
926 offset += 4;
927 proto_tree_add_item(data_tree, hf_tns_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
928 offset += 2;
930 if ( is_request )
932 proto_tree_add_item(data_tree, hf_tns_data_sns_cli_vers, tvb, offset, 4, ENC_BIG_ENDIAN);
934 else
936 proto_tree_add_item(data_tree, hf_tns_data_sns_srv_vers, tvb, offset, 4, ENC_BIG_ENDIAN);
938 offset += 4;
940 proto_tree_add_item(data_tree, hf_tns_data_sns_srvcnt, tvb, offset, 2, ENC_BIG_ENDIAN);
942 /* move back, to include data_id into data_dissector */
943 offset -= 10;
944 break;
948 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, data_tree);
951 static void dissect_tns_connect(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tns_tree)
953 proto_tree *connect_tree;
954 uint32_t cd_offset, cd_len;
955 int tns_offset = offset-8;
956 static int * const flags[] = {
957 &hf_tns_ntp_flag_hangon,
958 &hf_tns_ntp_flag_crel,
959 &hf_tns_ntp_flag_tduio,
960 &hf_tns_ntp_flag_srun,
961 &hf_tns_ntp_flag_dtest,
962 &hf_tns_ntp_flag_cbio,
963 &hf_tns_ntp_flag_asio,
964 &hf_tns_ntp_flag_pio,
965 &hf_tns_ntp_flag_grant,
966 &hf_tns_ntp_flag_handoff,
967 &hf_tns_ntp_flag_sigio,
968 &hf_tns_ntp_flag_sigpipe,
969 &hf_tns_ntp_flag_sigurg,
970 &hf_tns_ntp_flag_urgentio,
971 &hf_tns_ntp_flag_fdio,
972 &hf_tns_ntp_flag_testop,
973 NULL
976 connect_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
977 ett_tns_connect, NULL, "Connect");
979 proto_tree_add_item(connect_tree, hf_tns_version, tvb,
980 offset, 2, ENC_BIG_ENDIAN);
981 offset += 2;
983 proto_tree_add_item(connect_tree, hf_tns_compat_version, tvb,
984 offset, 2, ENC_BIG_ENDIAN);
985 offset += 2;
987 proto_tree_add_bitmask(connect_tree, tvb, offset, hf_tns_service_options, ett_tns_sopt_flag, tns_service_options, ENC_BIG_ENDIAN);
988 offset += 2;
990 proto_tree_add_item(connect_tree, hf_tns_sdu_size, tvb,
991 offset, 2, ENC_BIG_ENDIAN);
992 offset += 2;
994 proto_tree_add_item(connect_tree, hf_tns_max_tdu_size, tvb,
995 offset, 2, ENC_BIG_ENDIAN);
996 offset += 2;
998 proto_tree_add_bitmask(connect_tree, tvb, offset, hf_tns_nt_proto_characteristics, ett_tns_ntp_flag, flags, ENC_BIG_ENDIAN);
999 offset += 2;
1001 proto_tree_add_item(connect_tree, hf_tns_line_turnaround, tvb,
1002 offset, 2, ENC_BIG_ENDIAN);
1003 offset += 2;
1005 proto_tree_add_item(connect_tree, hf_tns_value_of_one, tvb,
1006 offset, 2, ENC_NA);
1007 offset += 2;
1009 proto_tree_add_item_ret_uint(connect_tree, hf_tns_connect_data_length, tvb,
1010 offset, 2, ENC_BIG_ENDIAN, &cd_len);
1011 offset += 2;
1013 proto_tree_add_item_ret_uint(connect_tree, hf_tns_connect_data_offset, tvb,
1014 offset, 2, ENC_BIG_ENDIAN, &cd_offset);
1015 offset += 2;
1017 proto_tree_add_item(connect_tree, hf_tns_connect_data_max, tvb,
1018 offset, 4, ENC_BIG_ENDIAN);
1019 offset += 4;
1021 proto_tree_add_bitmask(connect_tree, tvb, offset, hf_tns_connect_flags0, ett_tns_conn_flag, tns_connect_flags, ENC_BIG_ENDIAN);
1022 offset += 1;
1024 proto_tree_add_bitmask(connect_tree, tvb, offset, hf_tns_connect_flags1, ett_tns_conn_flag, tns_connect_flags, ENC_BIG_ENDIAN);
1025 offset += 1;
1028 * XXX - sometimes it appears that this stuff isn't present
1029 * in the packet.
1031 if ((uint32_t)(offset + 16) <= tns_offset+cd_offset)
1033 proto_tree_add_item(connect_tree, hf_tns_trace_cf1, tvb,
1034 offset, 4, ENC_BIG_ENDIAN);
1035 offset += 4;
1037 proto_tree_add_item(connect_tree, hf_tns_trace_cf2, tvb,
1038 offset, 4, ENC_BIG_ENDIAN);
1039 offset += 4;
1041 proto_tree_add_item(connect_tree, hf_tns_trace_cid, tvb,
1042 offset, 8, ENC_BIG_ENDIAN);
1043 /* offset += 8;*/
1046 if ( cd_len > 0)
1048 /* Long Connect Data (> 221 bytes?) is not in the Connect PDU
1049 * but sent in an immediately following Data PDU.
1051 if (tvb_reported_length_remaining(tvb, tns_offset + cd_offset)) {
1052 proto_tree_add_item(connect_tree, hf_tns_connect_data, tvb,
1053 tns_offset+cd_offset, -1, ENC_ASCII);
1054 } else {
1055 proto_tree_add_expert(connect_tree, pinfo, &ei_tns_connect_data_next_packet, tvb, 0, 0);
1056 if (!PINFO_FD_VISITED(pinfo)) {
1057 tns_conv_info_t *tns_info = tns_get_conv_info(pinfo);
1058 tns_info->pending_connect_data = cd_len;
1064 static void dissect_tns_accept(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tns_tree)
1066 proto_tree *accept_tree;
1067 uint32_t accept_offset, accept_len;
1068 int tns_offset = offset-8;
1070 accept_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
1071 ett_tns_accept, NULL, "Accept");
1073 proto_tree_add_item(accept_tree, hf_tns_version, tvb,
1074 offset, 2, ENC_BIG_ENDIAN);
1075 offset += 2;
1077 proto_tree_add_bitmask(accept_tree, tvb, offset, hf_tns_service_options, ett_tns_sopt_flag, tns_service_options, ENC_BIG_ENDIAN);
1078 offset += 2;
1080 proto_tree_add_item(accept_tree, hf_tns_sdu_size, tvb,
1081 offset, 2, ENC_BIG_ENDIAN);
1082 offset += 2;
1084 proto_tree_add_item(accept_tree, hf_tns_max_tdu_size, tvb,
1085 offset, 2, ENC_BIG_ENDIAN);
1086 offset += 2;
1088 proto_tree_add_item(accept_tree, hf_tns_value_of_one, tvb,
1089 offset, 2, ENC_NA);
1090 offset += 2;
1092 proto_tree_add_item_ret_uint(accept_tree, hf_tns_accept_data_length, tvb,
1093 offset, 2, ENC_BIG_ENDIAN, &accept_len);
1094 offset += 2;
1096 proto_tree_add_item_ret_uint(accept_tree, hf_tns_accept_data_offset, tvb,
1097 offset, 2, ENC_BIG_ENDIAN, &accept_offset);
1098 offset += 2;
1100 proto_tree_add_bitmask(accept_tree, tvb, offset, hf_tns_connect_flags0, ett_tns_conn_flag, tns_connect_flags, ENC_BIG_ENDIAN);
1101 offset += 1;
1103 proto_tree_add_bitmask(accept_tree, tvb, offset, hf_tns_connect_flags1, ett_tns_conn_flag, tns_connect_flags, ENC_BIG_ENDIAN);
1104 /* offset += 1; */
1106 if ( accept_len > 0)
1108 proto_tree_add_item(accept_tree, hf_tns_accept_data, tvb,
1109 tns_offset+accept_offset, -1, ENC_ASCII);
1111 return;
1115 static void dissect_tns_refuse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tns_tree)
1117 /* TODO
1118 * According to some reverse engineers, the refuse packet is also sent when the login fails.
1119 * Byte 54 shows if this is due to invalid ID (0x02) or password (0x03).
1120 * At now we do not have pcaps with such messages to check this statement.
1122 proto_tree *refuse_tree;
1124 refuse_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
1125 ett_tns_refuse, NULL, "Refuse");
1127 proto_tree_add_item(refuse_tree, hf_tns_refuse_reason_user, tvb,
1128 offset, 1, ENC_BIG_ENDIAN);
1129 offset += 1;
1131 proto_tree_add_item(refuse_tree, hf_tns_refuse_reason_system, tvb,
1132 offset, 1, ENC_BIG_ENDIAN);
1133 offset += 1;
1135 proto_tree_add_item(refuse_tree, hf_tns_refuse_data_length, tvb,
1136 offset, 2, ENC_BIG_ENDIAN);
1137 offset += 2;
1139 proto_tree_add_item(refuse_tree, hf_tns_refuse_data, tvb,
1140 offset, -1, ENC_ASCII);
1144 static void dissect_tns_abort(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tns_tree)
1146 proto_tree *abort_tree;
1148 abort_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
1149 ett_tns_abort, NULL, "Abort");
1151 proto_tree_add_item(abort_tree, hf_tns_abort_reason_user, tvb,
1152 offset, 1, ENC_BIG_ENDIAN);
1153 offset += 1;
1155 proto_tree_add_item(abort_tree, hf_tns_abort_reason_system, tvb,
1156 offset, 1, ENC_BIG_ENDIAN);
1157 offset += 1;
1159 proto_tree_add_item(abort_tree, hf_tns_abort_data, tvb,
1160 offset, -1, ENC_ASCII);
1164 static void dissect_tns_marker(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tns_tree, int is_attention)
1166 proto_tree *marker_tree;
1168 if ( is_attention )
1170 marker_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
1171 ett_tns_marker, NULL, "Marker");
1173 else
1175 marker_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
1176 ett_tns_marker, NULL, "Attention");
1179 proto_tree_add_item(marker_tree, hf_tns_marker_type, tvb,
1180 offset, 1, ENC_BIG_ENDIAN);
1181 offset += 1;
1183 proto_tree_add_item(marker_tree, hf_tns_marker_data_byte, tvb,
1184 offset, 1, ENC_BIG_ENDIAN);
1185 offset += 1;
1187 proto_tree_add_item(marker_tree, hf_tns_marker_data_byte, tvb,
1188 offset, 1, ENC_BIG_ENDIAN);
1189 /*offset += 1;*/
1192 static void dissect_tns_redirect(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tns_tree)
1194 proto_tree *redirect_tree;
1196 redirect_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
1197 ett_tns_redirect, NULL, "Redirect");
1199 proto_tree_add_item(redirect_tree, hf_tns_redirect_data_length, tvb,
1200 offset, 2, ENC_BIG_ENDIAN);
1201 offset += 2;
1203 proto_tree_add_item(redirect_tree, hf_tns_redirect_data, tvb,
1204 offset, -1, ENC_ASCII);
1207 static void dissect_tns_control(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tns_tree)
1209 proto_tree *control_tree;
1211 control_tree = proto_tree_add_subtree(tns_tree, tvb, offset, -1,
1212 ett_tns_control, NULL, "Control");
1214 proto_tree_add_item(control_tree, hf_tns_control_cmd, tvb,
1215 offset, 2, ENC_BIG_ENDIAN);
1216 offset += 2;
1218 proto_tree_add_item(control_tree, hf_tns_control_data, tvb,
1219 offset, -1, ENC_NA);
1222 static unsigned
1223 get_tns_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1226 * Get the 16-bit length of the TNS message, including header
1228 unsigned length = tvb_get_ntohs(tvb, offset);
1229 offset += 4;
1230 uint8_t type = tvb_get_uint8(tvb, offset);
1231 /* Type 0xf (data descriptor, LOB/FILE data) has data which follows
1232 * immediately (no new PDU header) but is not counted in the PDU
1233 * length field either.
1235 if (type == TNS_TYPE_DD) {
1236 offset += 8;
1237 if (!tvb_bytes_exist(tvb, offset, 4)) {
1238 /* return 0 makes tcp_dissect_pdus() report
1239 * DESEGMENT_ONE_MORE_SEGMENT to the TCP dissector.
1241 return 0;
1243 unsigned dd_len = tvb_get_ntohl(tvb, offset);
1244 return length + dd_len;
1246 return length;
1249 static unsigned
1250 get_tns_pdu_len_nochksum(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1253 * Get the 32-bit length of the TNS message, including header
1255 unsigned length = tvb_get_ntohl(tvb, offset);
1256 offset += 4;
1257 uint8_t type = tvb_get_uint8(tvb, offset);
1258 /* Type 0xf (data descriptor, LOB/FILE data) has data which follows
1259 * immediately (no new PDU header) but is not counted in the PDU
1260 * length field either.
1262 if (type == TNS_TYPE_DD) {
1263 offset += 8;
1264 if (!tvb_bytes_exist(tvb, offset, 4)) {
1265 /* return 0 makes tcp_dissect_pdus() report
1266 * DESEGMENT_ONE_MORE_SEGMENT to the TCP dissector.
1268 return 0;
1270 unsigned dd_len = tvb_get_ntohl(tvb, offset);
1271 return length + dd_len;
1274 return length;
1277 static int
1278 dissect_tns(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1280 uint32_t length;
1281 uint16_t chksum;
1282 uint8_t type;
1285 * First, do a sanity check to make sure what we have
1286 * starts with a TNS PDU.
1288 if (tvb_bytes_exist(tvb, 4, 1)) {
1290 * Well, we have the packet type; let's make sure
1291 * it's a known type.
1293 type = tvb_get_uint8(tvb, 4);
1294 if (type < TNS_TYPE_CONNECT || type > TNS_TYPE_MAX)
1295 return 0; /* it's not a known type */
1299 * In some messages (observed in Oracle12c) packet length has 4 bytes
1300 * instead of 2.
1302 * If packet length has 2 bytes, length and checksum equals two unsigned
1303 * 16-bit numbers. Packet checksum is generally unused (equal zero),
1304 * but 10g client may set 2nd byte to 4.
1306 * Else, Oracle 12c combine these two 16-bit numbers into one 32-bit.
1307 * This number represents the packet length. Checksum is omitted.
1309 chksum = tvb_get_ntohs(tvb, 2);
1311 length = (chksum == 0 || chksum == 4) ? 2 : 4;
1313 tcp_dissect_pdus(tvb, pinfo, tree, tns_desegment, TNS_HDR_LEN,
1314 (length == 2 ? get_tns_pdu_len : get_tns_pdu_len_nochksum),
1315 dissect_tns_pdu, data);
1317 return tvb_captured_length(tvb);
1320 static int
1321 dissect_tns_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1323 proto_tree *tns_tree, *ti;
1324 proto_item *hidden_item;
1325 int offset = 0;
1326 uint32_t length;
1327 uint16_t chksum;
1328 uint8_t type;
1330 col_set_str(pinfo->cinfo, COL_PROTOCOL, "TNS");
1332 col_set_str(pinfo->cinfo, COL_INFO,
1333 (pinfo->match_uint == pinfo->destport) ? "Request" : "Response");
1335 ti = proto_tree_add_item(tree, proto_tns, tvb, 0, -1, ENC_NA);
1336 tns_tree = proto_item_add_subtree(ti, ett_tns);
1338 if (pinfo->match_uint == pinfo->destport)
1340 hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_request,
1341 tvb, offset, 0, true);
1343 else
1345 hidden_item = proto_tree_add_boolean(tns_tree, hf_tns_response,
1346 tvb, offset, 0, true);
1348 proto_item_set_hidden(hidden_item);
1350 chksum = tvb_get_ntohs(tvb, offset+2);
1351 if (chksum == 0 || chksum == 4)
1353 proto_tree_add_item_ret_uint(tns_tree, hf_tns_length, tvb, offset,
1354 2, ENC_BIG_ENDIAN, &length);
1355 offset += 2;
1356 proto_tree_add_checksum(tns_tree, tvb, offset, hf_tns_packet_checksum,
1357 -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
1358 offset += 2;
1360 else
1362 /* Oracle 12c uses checksum bytes as part of the packet length. */
1363 proto_tree_add_item_ret_uint(tns_tree, hf_tns_length, tvb, offset,
1364 4, ENC_BIG_ENDIAN, &length);
1365 offset += 4;
1368 type = tvb_get_uint8(tvb, offset);
1369 proto_tree_add_uint(tns_tree, hf_tns_packet_type, tvb,
1370 offset, 1, type);
1371 offset += 1;
1373 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s (%u)",
1374 val_to_str_const(type, tns_type_vals, "Unknown"), type);
1376 proto_tree_add_item(tns_tree, hf_tns_reserved_byte, tvb,
1377 offset, 1, ENC_NA);
1378 offset += 1;
1380 proto_tree_add_checksum(tns_tree, tvb, offset, hf_tns_header_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
1381 offset += 2;
1383 switch (type)
1385 case TNS_TYPE_CONNECT:
1386 dissect_tns_connect(tvb,offset,pinfo,tns_tree);
1387 break;
1388 case TNS_TYPE_ACCEPT:
1389 dissect_tns_accept(tvb,offset,pinfo,tns_tree);
1390 break;
1391 case TNS_TYPE_REFUSE:
1392 dissect_tns_refuse(tvb,offset,pinfo,tns_tree);
1393 break;
1394 case TNS_TYPE_REDIRECT:
1395 dissect_tns_redirect(tvb,offset,pinfo,tns_tree);
1396 break;
1397 case TNS_TYPE_ABORT:
1398 dissect_tns_abort(tvb,offset,pinfo,tns_tree);
1399 break;
1400 case TNS_TYPE_MARKER:
1401 dissect_tns_marker(tvb,offset,pinfo,tns_tree, 0);
1402 break;
1403 case TNS_TYPE_ATTENTION:
1404 dissect_tns_marker(tvb,offset,pinfo,tns_tree, 1);
1405 break;
1406 case TNS_TYPE_CONTROL:
1407 dissect_tns_control(tvb,offset,pinfo,tns_tree);
1408 break;
1409 case TNS_TYPE_DATA:
1410 dissect_tns_data(tvb,offset,pinfo,tns_tree);
1411 break;
1412 case TNS_TYPE_DD:
1413 dissect_tns_data_descriptor(tvb,offset,pinfo,tns_tree, length);
1414 break;
1415 default:
1416 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo,
1417 tns_tree);
1418 break;
1421 return tvb_captured_length(tvb);
1424 void proto_register_tns(void)
1426 static hf_register_info hf[] = {
1427 { &hf_tns_response, {
1428 "Response", "tns.response", FT_BOOLEAN, BASE_NONE,
1429 NULL, 0x0, "true if TNS response", HFILL }},
1430 { &hf_tns_request, {
1431 "Request", "tns.request", FT_BOOLEAN, BASE_NONE,
1432 NULL, 0x0, "true if TNS request", HFILL }},
1433 { &hf_tns_length, {
1434 "Packet Length", "tns.length", FT_UINT32, BASE_DEC,
1435 NULL, 0x0, "Length of TNS packet", HFILL }},
1436 { &hf_tns_packet_checksum, {
1437 "Packet Checksum", "tns.packet_checksum", FT_UINT16, BASE_HEX,
1438 NULL, 0x0, "Checksum of Packet Data", HFILL }},
1439 { &hf_tns_header_checksum, {
1440 "Header Checksum", "tns.header_checksum", FT_UINT16, BASE_HEX,
1441 NULL, 0x0, "Checksum of Header Data", HFILL }},
1443 { &hf_tns_version, {
1444 "Version", "tns.version", FT_UINT16, BASE_DEC,
1445 NULL, 0x0, NULL, HFILL }},
1446 { &hf_tns_compat_version, {
1447 "Version (Compatible)", "tns.compat_version", FT_UINT16, BASE_DEC,
1448 NULL, 0x0, NULL, HFILL }},
1450 { &hf_tns_service_options, {
1451 "Service Options", "tns.service_options", FT_UINT16, BASE_HEX,
1452 NULL, 0x0, NULL, HFILL }},
1454 { &hf_tns_sopt_flag_bconn, {
1455 "Broken Connect Notify", "tns.so_flag.bconn", FT_BOOLEAN, 16,
1456 NULL, 0x2000, NULL, HFILL }},
1457 { &hf_tns_sopt_flag_pc, {
1458 "Packet Checksum", "tns.so_flag.pc", FT_BOOLEAN, 16,
1459 NULL, 0x1000, NULL, HFILL }},
1460 { &hf_tns_sopt_flag_hc, {
1461 "Header Checksum", "tns.so_flag.hc", FT_BOOLEAN, 16,
1462 NULL, 0x0800, NULL, HFILL }},
1463 { &hf_tns_sopt_flag_fd, {
1464 "Full Duplex", "tns.so_flag.fd", FT_BOOLEAN, 16,
1465 NULL, 0x0400, NULL, HFILL }},
1466 { &hf_tns_sopt_flag_hd, {
1467 "Half Duplex", "tns.so_flag.hd", FT_BOOLEAN, 16,
1468 NULL, 0x0200, NULL, HFILL }},
1469 { &hf_tns_sopt_flag_dc1, {
1470 "Don't Care", "tns.so_flag.dc1", FT_BOOLEAN, 16,
1471 NULL, 0x0100, NULL, HFILL }},
1472 { &hf_tns_sopt_flag_dc2, {
1473 "Don't Care", "tns.so_flag.dc2", FT_BOOLEAN, 16,
1474 NULL, 0x0080, NULL, HFILL }},
1475 { &hf_tns_sopt_flag_dio, {
1476 "Direct IO to Transport", "tns.so_flag.dio", FT_BOOLEAN, 16,
1477 NULL, 0x0010, NULL, HFILL }},
1478 { &hf_tns_sopt_flag_ap, {
1479 "Attention Processing", "tns.so_flag.ap", FT_BOOLEAN, 16,
1480 NULL, 0x0008, NULL, HFILL }},
1481 { &hf_tns_sopt_flag_ra, {
1482 "Can Receive Attention", "tns.so_flag.ra", FT_BOOLEAN, 16,
1483 NULL, 0x0004, NULL, HFILL }},
1484 { &hf_tns_sopt_flag_sa, {
1485 "Can Send Attention", "tns.so_flag.sa", FT_BOOLEAN, 16,
1486 NULL, 0x0002, NULL, HFILL }},
1489 { &hf_tns_sdu_size, {
1490 "Session Data Unit Size", "tns.sdu_size", FT_UINT16, BASE_DEC,
1491 NULL, 0x0, NULL, HFILL }},
1492 { &hf_tns_max_tdu_size, {
1493 "Maximum Transmission Data Unit Size", "tns.max_tdu_size", FT_UINT16, BASE_DEC,
1494 NULL, 0x0, NULL, HFILL }},
1496 { &hf_tns_nt_proto_characteristics, {
1497 "NT Protocol Characteristics", "tns.nt_proto_characteristics", FT_UINT16, BASE_HEX,
1498 NULL, 0x0, NULL, HFILL }},
1499 { &hf_tns_ntp_flag_hangon, {
1500 "Hangon to listener connect", "tns.ntp_flag.hangon", FT_BOOLEAN, 16,
1501 NULL, 0x8000, NULL, HFILL }},
1502 { &hf_tns_ntp_flag_crel, {
1503 "Confirmed release", "tns.ntp_flag.crel", FT_BOOLEAN, 16,
1504 NULL, 0x4000, NULL, HFILL }},
1505 { &hf_tns_ntp_flag_tduio, {
1506 "TDU based IO", "tns.ntp_flag.tduio", FT_BOOLEAN, 16,
1507 NULL, 0x2000, NULL, HFILL }},
1508 { &hf_tns_ntp_flag_srun, {
1509 "Spawner running", "tns.ntp_flag.srun", FT_BOOLEAN, 16,
1510 NULL, 0x1000, NULL, HFILL }},
1511 { &hf_tns_ntp_flag_dtest, {
1512 "Data test", "tns.ntp_flag.dtest", FT_BOOLEAN, 16,
1513 NULL, 0x0800, NULL, HFILL }},
1514 { &hf_tns_ntp_flag_cbio, {
1515 "Callback IO supported", "tns.ntp_flag.cbio", FT_BOOLEAN, 16,
1516 NULL, 0x0400, NULL, HFILL }},
1517 { &hf_tns_ntp_flag_asio, {
1518 "ASync IO Supported", "tns.ntp_flag.asio", FT_BOOLEAN, 16,
1519 NULL, 0x0200, NULL, HFILL }},
1520 { &hf_tns_ntp_flag_pio, {
1521 "Packet oriented IO", "tns.ntp_flag.pio", FT_BOOLEAN, 16,
1522 NULL, 0x0100, NULL, HFILL }},
1523 { &hf_tns_ntp_flag_grant, {
1524 "Can grant connection to another", "tns.ntp_flag.grant", FT_BOOLEAN, 16,
1525 NULL, 0x0080, NULL, HFILL }},
1526 { &hf_tns_ntp_flag_handoff, {
1527 "Can handoff connection to another", "tns.ntp_flag.handoff", FT_BOOLEAN, 16,
1528 NULL, 0x0040, NULL, HFILL }},
1529 { &hf_tns_ntp_flag_sigio, {
1530 "Generate SIGIO signal", "tns.ntp_flag.sigio", FT_BOOLEAN, 16,
1531 NULL, 0x0020, NULL, HFILL }},
1532 { &hf_tns_ntp_flag_sigpipe, {
1533 "Generate SIGPIPE signal", "tns.ntp_flag.sigpipe", FT_BOOLEAN, 16,
1534 NULL, 0x0010, NULL, HFILL }},
1535 { &hf_tns_ntp_flag_sigurg, {
1536 "Generate SIGURG signal", "tns.ntp_flag.sigurg", FT_BOOLEAN, 16,
1537 NULL, 0x0008, NULL, HFILL }},
1538 { &hf_tns_ntp_flag_urgentio, {
1539 "Urgent IO supported", "tns.ntp_flag.urgentio", FT_BOOLEAN, 16,
1540 NULL, 0x0004, NULL, HFILL }},
1541 { &hf_tns_ntp_flag_fdio, {
1542 "Full duplex IO supported", "tns.ntp_flag.dfio", FT_BOOLEAN, 16,
1543 NULL, 0x0002, NULL, HFILL }},
1544 { &hf_tns_ntp_flag_testop, {
1545 "Test operation", "tns.ntp_flag.testop", FT_BOOLEAN, 16,
1546 NULL, 0x0001, NULL, HFILL }},
1551 { &hf_tns_line_turnaround, {
1552 "Line Turnaround Value", "tns.line_turnaround", FT_UINT16, BASE_DEC,
1553 NULL, 0x0, NULL, HFILL }},
1554 { &hf_tns_value_of_one, {
1555 "Value of 1 in Hardware", "tns.value_of_one", FT_BYTES, BASE_NONE,
1556 NULL, 0x0, NULL, HFILL }},
1558 { &hf_tns_connect_data_length, {
1559 "Length of Connect Data", "tns.connect_data_length", FT_UINT16,
1560 BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }},
1561 { &hf_tns_connect_data_offset, {
1562 "Offset to Connect Data", "tns.connect_data_offset", FT_UINT16, BASE_DEC,
1563 NULL, 0x0, NULL, HFILL }},
1564 { &hf_tns_connect_data_max, {
1565 "Maximum Receivable Connect Data", "tns.connect_data_max", FT_UINT32, BASE_DEC,
1566 NULL, 0x0, NULL, HFILL }},
1568 { &hf_tns_connect_flags0, {
1569 "Connect Flags 0", "tns.connect_flags0", FT_UINT8, BASE_HEX,
1570 NULL, 0x0, NULL, HFILL }},
1571 { &hf_tns_connect_flags1, {
1572 "Connect Flags 1", "tns.connect_flags1", FT_UINT8, BASE_HEX,
1573 NULL, 0x0, NULL, HFILL }},
1575 { &hf_tns_conn_flag_nareq, {
1576 "NA services required", "tns.connect_flags.nareq", FT_BOOLEAN, 8,
1577 NULL, 0x10, NULL, HFILL }},
1578 { &hf_tns_conn_flag_nalink, {
1579 "NA services linked in", "tns.connect_flags.nalink", FT_BOOLEAN, 8,
1580 NULL, 0x08, NULL, HFILL }},
1581 { &hf_tns_conn_flag_enablena, {
1582 "NA services enabled", "tns.connect_flags.enablena", FT_BOOLEAN, 8,
1583 NULL, 0x04, NULL, HFILL }},
1584 { &hf_tns_conn_flag_ichg, {
1585 "Interchange is involved", "tns.connect_flags.ichg", FT_BOOLEAN, 8,
1586 NULL, 0x02, NULL, HFILL }},
1587 { &hf_tns_conn_flag_wantna, {
1588 "NA services wanted", "tns.connect_flags.wantna", FT_BOOLEAN, 8,
1589 NULL, 0x01, NULL, HFILL }},
1592 { &hf_tns_trace_cf1, {
1593 "Trace Cross Facility Item 1", "tns.trace_cf1", FT_UINT32, BASE_HEX,
1594 NULL, 0x0, NULL, HFILL }},
1595 { &hf_tns_trace_cf2, {
1596 "Trace Cross Facility Item 2", "tns.trace_cf2", FT_UINT32, BASE_HEX,
1597 NULL, 0x0, NULL, HFILL }},
1598 { &hf_tns_trace_cid, {
1599 "Trace Unique Connection ID", "tns.trace_cid", FT_UINT64, BASE_HEX,
1600 NULL, 0x0, NULL, HFILL }},
1601 { &hf_tns_connect_data, {
1602 "Connect Data", "tns.connect_data", FT_STRING, BASE_NONE,
1603 NULL, 0x0, NULL, HFILL }},
1605 { &hf_tns_accept_data_length, {
1606 "Accept Data Length", "tns.accept_data_length", FT_UINT16,
1607 BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }},
1608 { &hf_tns_accept_data, {
1609 "Accept Data", "tns.accept_data", FT_STRING, BASE_NONE,
1610 NULL, 0x0, NULL, HFILL }},
1611 { &hf_tns_accept_data_offset, {
1612 "Offset to Accept Data", "tns.accept_data_offset", FT_UINT16, BASE_DEC,
1613 NULL, 0x0, NULL, HFILL }},
1615 { &hf_tns_refuse_reason_user, {
1616 "Refuse Reason (User)", "tns.refuse_reason_user", FT_UINT8, BASE_HEX,
1617 NULL, 0x0, "Refuse Reason from Application", HFILL }},
1618 { &hf_tns_refuse_reason_system, {
1619 "Refuse Reason (System)", "tns.refuse_reason_system", FT_UINT8, BASE_HEX,
1620 NULL, 0x0, "Refuse Reason from System", HFILL }},
1621 { &hf_tns_refuse_data_length, {
1622 "Refuse Data Length", "tns.refuse_data_length", FT_UINT16,
1623 BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }},
1624 { &hf_tns_refuse_data, {
1625 "Refuse Data", "tns.refuse_data", FT_STRING, BASE_NONE,
1626 NULL, 0x0, NULL, HFILL }},
1628 { &hf_tns_abort_reason_user, {
1629 "Abort Reason (User)", "tns.abort_reason_user", FT_UINT8, BASE_HEX,
1630 NULL, 0x0, "Abort Reason from Application", HFILL }},
1631 { &hf_tns_abort_reason_system, {
1632 "Abort Reason (User)", "tns.abort_reason_system", FT_UINT8, BASE_HEX,
1633 NULL, 0x0, "Abort Reason from System", HFILL }},
1634 { &hf_tns_abort_data, {
1635 "Abort Data", "tns.abort_data", FT_STRING, BASE_NONE,
1636 NULL, 0x0, NULL, HFILL }},
1638 { &hf_tns_marker_type, {
1639 "Marker Type", "tns.marker.type", FT_UINT8, BASE_HEX,
1640 VALS(tns_marker_types), 0x0, NULL, HFILL }},
1641 { &hf_tns_marker_data_byte, {
1642 "Marker Data Byte", "tns.marker.databyte", FT_UINT8, BASE_HEX,
1643 NULL, 0x0, NULL, HFILL }},
1644 #if 0
1645 { &hf_tns_marker_data, {
1646 "Marker Data", "tns.marker.data", FT_UINT16, BASE_HEX,
1647 NULL, 0x0, NULL, HFILL }},
1648 #endif
1650 { &hf_tns_control_cmd, {
1651 "Control Command", "tns.control.cmd", FT_UINT16, BASE_HEX,
1652 VALS(tns_control_cmds), 0x0, NULL, HFILL }},
1653 { &hf_tns_control_data, {
1654 "Control Data", "tns.control.data", FT_BYTES, BASE_NONE,
1655 NULL, 0x0, NULL, HFILL }},
1657 { &hf_tns_redirect_data_length, {
1658 "Redirect Data Length", "tns.redirect_data_length", FT_UINT16,
1659 BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }},
1660 { &hf_tns_redirect_data, {
1661 "Redirect Data", "tns.redirect_data", FT_STRING, BASE_NONE,
1662 NULL, 0x0, NULL, HFILL }},
1664 { &hf_tns_data_flag, {
1665 "Data Flag", "tns.data_flag", FT_UINT16, BASE_HEX,
1666 NULL, 0x0, NULL, HFILL }},
1667 { &hf_tns_data_flag_send, {
1668 "Send Token", "tns.data_flag.send", FT_BOOLEAN, 16,
1669 NULL, 0x1, NULL, HFILL }},
1670 { &hf_tns_data_flag_rc, {
1671 "Request Confirmation", "tns.data_flag.rc", FT_BOOLEAN, 16,
1672 NULL, 0x2, NULL, HFILL }},
1673 { &hf_tns_data_flag_c, {
1674 "Confirmation", "tns.data_flag.c", FT_BOOLEAN, 16,
1675 NULL, 0x4, NULL, HFILL }},
1676 { &hf_tns_data_flag_reserved, {
1677 "Reserved", "tns.data_flag.reserved", FT_BOOLEAN, 16,
1678 NULL, 0x8, NULL, HFILL }},
1679 { &hf_tns_data_flag_more, {
1680 "More Data to Come", "tns.data_flag.more", FT_BOOLEAN, 16,
1681 NULL, 0x0020, NULL, HFILL }},
1682 { &hf_tns_data_flag_eof, {
1683 "End of File", "tns.data_flag.eof", FT_BOOLEAN, 16,
1684 NULL, 0x0040, NULL, HFILL }},
1685 { &hf_tns_data_flag_dic, {
1686 "Do Immediate Confirmation", "tns.data_flag.dic", FT_BOOLEAN, 16,
1687 NULL, 0x0080, NULL, HFILL }},
1688 { &hf_tns_data_flag_rts, {
1689 "Request To Send", "tns.data_flag.rts", FT_BOOLEAN, 16,
1690 NULL, 0x0100, NULL, HFILL }},
1691 { &hf_tns_data_flag_sntt, {
1692 "Send NT Trailer", "tns.data_flag.sntt", FT_BOOLEAN, 16,
1693 NULL, 0x0200, NULL, HFILL }},
1695 { &hf_tns_data_id, {
1696 "Data ID", "tns.data_id", FT_UINT32, BASE_HEX,
1697 VALS(tns_data_funcs), 0x0, NULL, HFILL }},
1698 { &hf_tns_data_length, {
1699 "Data Length", "tns.data_length", FT_UINT32,
1700 BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }},
1702 { &hf_tns_data_oci_id, {
1703 "Call ID", "tns.data_oci.id", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
1704 &tns_data_oci_subfuncs_ext, 0x00, NULL, HFILL }},
1706 { &hf_tns_data_piggyback_id, {
1707 /* Also Call ID.
1708 Piggyback is a message what calls a small subset of functions
1709 declared in tns_data_oci_subfuncs. */
1710 "Call ID", "tns.data_piggyback.id", FT_UINT8, BASE_HEX|BASE_EXT_STRING,
1711 &tns_data_oci_subfuncs_ext, 0x00, NULL, HFILL }},
1713 { &hf_tns_data_unused, {
1714 "Unused", "tns.data.unused", FT_BYTES, BASE_NONE,
1715 NULL, 0x0, NULL, HFILL }},
1717 { &hf_tns_data_setp_acc_version, {
1718 "Accepted Version", "tns.data_setp_req.acc_vers", FT_UINT8, BASE_DEC,
1719 NULL, 0x0, NULL, HFILL }},
1720 { &hf_tns_data_setp_cli_plat, {
1721 "Client Platform", "tns.data_setp_req.cli_plat", FT_STRINGZ, BASE_NONE,
1722 NULL, 0x0, NULL, HFILL }},
1723 { &hf_tns_data_setp_version, {
1724 "Version", "tns.data_setp_resp.version", FT_UINT8, BASE_DEC,
1725 NULL, 0x0, NULL, HFILL }},
1726 { &hf_tns_data_setp_banner, {
1727 "Server Banner", "tns.data_setp_resp.banner", FT_STRINGZ, BASE_NONE,
1728 NULL, 0x0, NULL, HFILL }},
1730 { &hf_tns_data_sns_cli_vers, {
1731 "Client Version", "tns.data_sns.cli_vers", FT_UINT32, BASE_CUSTOM,
1732 CF_FUNC(vsnum_to_vstext_basecustom), 0x0, NULL, HFILL }},
1733 { &hf_tns_data_sns_srv_vers, {
1734 "Server Version", "tns.data_sns.srv_vers", FT_UINT32, BASE_CUSTOM,
1735 CF_FUNC(vsnum_to_vstext_basecustom), 0x0, NULL, HFILL }},
1736 { &hf_tns_data_sns_srvcnt, {
1737 "Services", "tns.data_sns.srvcnt", FT_UINT16, BASE_DEC,
1738 NULL, 0x0, NULL, HFILL }},
1740 { &hf_tns_data_opi_version2_banner_len, {
1741 "Banner Length", "tns.data_opi.vers2.banner_len", FT_UINT8, BASE_DEC,
1742 NULL, 0x0, NULL, HFILL }},
1743 { &hf_tns_data_opi_version2_banner, {
1744 "Banner", "tns.data_opi.vers2.banner", FT_STRING, BASE_NONE,
1745 NULL, 0x0, NULL, HFILL }},
1746 { &hf_tns_data_opi_version2_vsnum, {
1747 "Version", "tns.data_opi.vers2.version", FT_UINT32, BASE_CUSTOM,
1748 CF_FUNC(vsnum_to_vstext_basecustom), 0x0, NULL, HFILL }},
1750 { &hf_tns_data_opi_num_of_params, {
1751 "Number of parameters", "tns.data_opi.num_of_params", FT_UINT8, BASE_DEC,
1752 NULL, 0x0, NULL, HFILL }},
1753 { &hf_tns_data_opi_param_length, {
1754 "Length", "tns.data_opi.param_length", FT_UINT8, BASE_DEC,
1755 NULL, 0x0, NULL, HFILL }},
1756 { &hf_tns_data_opi_param_name, {
1757 "Name", "tns.data_opi.param_name", FT_STRING, BASE_NONE,
1758 NULL, 0x0, NULL, HFILL }},
1759 { &hf_tns_data_opi_param_value, {
1760 "Value", "tns.data_opi.param_value", FT_STRING, BASE_NONE,
1761 NULL, 0x0, NULL, HFILL }},
1763 { &hf_tns_data_descriptor_row_count, {
1764 "Row Count", "tns.data_descriptor.row_count", FT_UINT32, BASE_DEC,
1765 NULL, 0x0, NULL, HFILL }},
1766 { &hf_tns_data_descriptor_row_size, {
1767 "Row Size", "tns.data_descriptor.row_size", FT_UINT32, BASE_DEC,
1768 NULL, 0x0, NULL, HFILL }},
1770 { &hf_tns_reserved_byte, {
1771 "Reserved Byte", "tns.reserved_byte", FT_BYTES, BASE_NONE,
1772 NULL, 0x0, NULL, HFILL }},
1773 { &hf_tns_packet_type, {
1774 "Packet Type", "tns.type", FT_UINT8, BASE_DEC,
1775 VALS(tns_type_vals), 0x0, "Type of TNS packet", HFILL }}
1779 static int *ett[] = {
1780 &ett_tns,
1781 &ett_tns_connect,
1782 &ett_tns_accept,
1783 &ett_tns_refuse,
1784 &ett_tns_abort,
1785 &ett_tns_redirect,
1786 &ett_tns_marker,
1787 &ett_tns_attention,
1788 &ett_tns_control,
1789 &ett_tns_data,
1790 &ett_tns_data_flag,
1791 &ett_tns_acc_versions,
1792 &ett_tns_opi_params,
1793 &ett_tns_opi_par,
1794 &ett_tns_sopt_flag,
1795 &ett_tns_ntp_flag,
1796 &ett_tns_conn_flag,
1797 &ett_tns_rows,
1798 &ett_sql
1801 static ei_register_info ei[] = {
1802 { &ei_tns_connect_data_next_packet, { "tns.connect_data.next_packet", PI_REQUEST_CODE, PI_CHAT, "Long Connect Data (> 221 bytes) carried in subsequent Data packet", EXPFILL }},
1803 { &ei_tns_data_descriptor_size_mismatch, { "tns.data_descriptor.size_mismatch", PI_PROTOCOL, PI_WARN, "Data size from summing row sizes differs from size in descriptor", EXPFILL }},
1806 module_t *tns_module;
1807 expert_module_t* expert_tns;
1809 proto_tns = proto_register_protocol("Transparent Network Substrate Protocol", "TNS", "tns");
1810 proto_register_field_array(proto_tns, hf, array_length(hf));
1811 proto_register_subtree_array(ett, array_length(ett));
1812 expert_tns = expert_register_protocol(proto_tns);
1813 expert_register_field_array(expert_tns, ei, array_length(ei));
1814 tns_handle = register_dissector("tns", dissect_tns, proto_tns);
1816 tns_module = prefs_register_protocol(proto_tns, NULL);
1817 prefs_register_bool_preference(tns_module, "desegment_tns_messages",
1818 "Reassemble TNS messages spanning multiple TCP segments",
1819 "Whether the TNS dissector should reassemble messages spanning multiple TCP segments. "
1820 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
1821 &tns_desegment);
1824 void
1825 proto_reg_handoff_tns(void)
1827 dissector_add_uint_with_preference("tcp.port", TCP_PORT_TNS, tns_handle);
1831 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1833 * Local variables:
1834 * c-basic-offset: 8
1835 * tab-width: 8
1836 * indent-tabs-mode: t
1837 * End:
1839 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1840 * :indentSize=8:tabSize=8:noTabs=false: