Coverage Report

Created: 2026-01-02 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-drda.c
Line
Count
Source
1
/* packet-drda.c
2
 * Routines for Distributed Relational Database Architecture packet dissection
3
 *
4
 * metatech <metatech@flashmail.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
/*  DRDA in a nutshell
14
*
15
*   DRDA stands for Distributed Relational Database Architecture.
16
*   It is a protocol between database client and database server published by
17
*   the Open Group (www.opengroup.org) DDM (Distributed Data Management) is an
18
*   data management interface which allows to exchange structured data between
19
*   systems.  DRDA is specific to relational databases and uses a subset of DDM
20
*   to transport its data.  The IBM DB2 product uses the DRDA protocol from
21
*   version V8.  Unless negotiated differently during the handshake, the fields
22
*   of the DDM commands and reply messages are in EBCDIC.
23
*
24
*   Documentation:
25
*
26
*   DRDA Version 2, Volume 3: Distributed Data Management (DDM)
27
*     Architecture, Open Group.
28
*
29
*       https://pubs.opengroup.org/onlinepubs/009608699/toc.pdf
30
*
31
*   DRDA Version 3, Volume 3: Distributed Data Management (DDM)
32
*     Architecture Open Group.
33
*   Version 3 is no longer available.
34
*
35
*   DRDA Version 4, Volume 3: Distributed Data Management (DDM)
36
*     Architecture, Open Group.
37
*
38
*       https://pubs.opengroup.org/onlinepubs/9699939199/toc.pdf
39
*
40
*   DRDA Version 5, Volume 3: Distributed Data Management (DDM)
41
*     Architecture, Open Group.
42
*
43
*       https://publications.opengroup.org/c114
44
*
45
*   Reference for Remote DRDA Requesters and Servers, IBM.
46
*
47
*       https://www-304.ibm.com/support/docview.wss?uid=pub1sc18985301
48
*         (now dead)
49
*       https://publibfp.boulder.ibm.com/epubs/pdf/dsnudh10.pdf
50
*
51
*   Microsoft has some references that can be useful as well:
52
*
53
*       https://learn.microsoft.com/en-us/dotnet/api/microsoft.hostintegration.drda.common?view=his-dotnet
54
*/
55
56
#include "config.h"
57
58
#include <epan/packet.h>
59
#include <epan/prefs.h>
60
#include <epan/expert.h>
61
#include <epan/iana_charsets.h>
62
#include <epan/proto_data.h>
63
#include <epan/tfs.h>
64
#include "packet-tcp.h"
65
66
void proto_register_drda(void);
67
void proto_reg_handoff_drda(void);
68
69
static int proto_drda;
70
static int hf_drda_ddm_length;
71
static int hf_drda_ddm_magic;
72
static int hf_drda_ddm_format;
73
static int hf_drda_ddm_fmt_reserved;
74
static int hf_drda_ddm_fmt_chained;
75
static int hf_drda_ddm_fmt_errcont;
76
static int hf_drda_ddm_fmt_samecorr;
77
static int hf_drda_ddm_fmt_dsstyp;
78
static int hf_drda_ddm_rc;
79
static int hf_drda_ddm_length2;
80
static int hf_drda_ddm_codepoint;
81
static int hf_drda_param_length;
82
static int hf_drda_param_codepoint;
83
static int hf_drda_param_data;
84
static int hf_drda_param_data_ebcdic;
85
static int hf_drda_null_ind;
86
static int hf_drda_typdefnam;
87
static int hf_drda_clob_length;
88
static int hf_drda_sqlstatement;
89
static int hf_drda_sqlcagrp;
90
static int hf_drda_sqlcode;
91
static int hf_drda_sqlstate;
92
static int hf_drda_sqlerrproc;
93
static int hf_drda_sqlcaxgrp;
94
static int hf_drda_sqlerrd1;
95
static int hf_drda_sqlerrd2;
96
static int hf_drda_sqlerrd3;
97
static int hf_drda_sqlerrd4;
98
static int hf_drda_sqlerrd5;
99
static int hf_drda_sqlerrd6;
100
static int hf_drda_sqlwarn0;
101
static int hf_drda_sqlwarn1;
102
static int hf_drda_sqlwarn2;
103
static int hf_drda_sqlwarn3;
104
static int hf_drda_sqlwarn4;
105
static int hf_drda_sqlwarn5;
106
static int hf_drda_sqlwarn6;
107
static int hf_drda_sqlwarn7;
108
static int hf_drda_sqlwarn8;
109
static int hf_drda_sqlwarn9;
110
static int hf_drda_sqlwarna;
111
static int hf_drda_sqlerrmsg;
112
static int hf_drda_sqldhgrp;
113
static int hf_drda_sqldhold;
114
static int hf_drda_sqldreturn;
115
static int hf_drda_sqldscroll;
116
static int hf_drda_sqldsensitive;
117
static int hf_drda_sqldfcode;
118
static int hf_drda_sqldkeytype;
119
static int hf_drda_sqldoptlck;
120
static int hf_drda_sqldschema;
121
static int hf_drda_sqldmodule;
122
static int hf_drda_sqldagrp;
123
static int hf_drda_sqlprecision;
124
static int hf_drda_sqlscale;
125
static int hf_drda_sqllength;
126
static int hf_drda_sqllength32;
127
static int hf_drda_sqltype;
128
static int hf_drda_sqlarrextent;
129
static int hf_drda_sqldoptgrp;
130
static int hf_drda_sqlunnamed;
131
static int hf_drda_sqlname;
132
static int hf_drda_sqllabel;
133
static int hf_drda_sqlcomments;
134
static int hf_drda_sqludtgrp;
135
static int hf_drda_sqludtxtype;
136
static int hf_drda_sqludtschema;
137
static int hf_drda_sqludtname;
138
static int hf_drda_sqludtmodule;
139
static int hf_drda_sqldxgrp;
140
static int hf_drda_sqlxkeymem;
141
static int hf_drda_sqlxupdateable;
142
static int hf_drda_sqlxgenerated;
143
static int hf_drda_sqlxparmmode;
144
static int hf_drda_sqlxoptlck;
145
static int hf_drda_sqlxhidden;
146
static int hf_drda_sqlxcorname;
147
static int hf_drda_sqlxbasename;
148
static int hf_drda_sqlxschema;
149
static int hf_drda_sqlxname;
150
static int hf_drda_sqlxmodule;
151
static int hf_drda_sqldiaggrp;
152
static int hf_drda_sqlnum;
153
static int hf_drda_rlsconv;
154
static int hf_drda_secmec;
155
static int hf_drda_sectkn;
156
static int hf_drda_svrcod;
157
static int hf_drda_secchkcd;
158
static int hf_drda_ccsid;
159
static int hf_drda_mgrlvln;
160
static int hf_drda_monitor;
161
static int hf_drda_monitor_etime;
162
static int hf_drda_monitor_reserved;
163
static int hf_drda_etime;
164
static int hf_drda_respktsz;
165
static int hf_drda_rdbinttkn;
166
static int hf_drda_rdbcmtok;
167
static int hf_drda_rdbcolid;
168
static int hf_drda_rdbcolid_ebcdic;
169
static int hf_drda_pkgid;
170
static int hf_drda_pkgid_ebcdic;
171
static int hf_drda_pkgsn;
172
static int hf_drda_pkgcnstkn;
173
static int hf_drda_rtnsetstt;
174
static int hf_drda_rdbnam;
175
static int hf_drda_rdbnam_ebcdic;
176
static int hf_drda_outexp;
177
static int hf_drda_qryblksz;
178
static int hf_drda_uowdsp;
179
static int hf_drda_rdbalwupd;
180
static int hf_drda_sqlcsrhld;
181
static int hf_drda_qryextdtasz;
182
static int hf_drda_smldtasz;
183
static int hf_drda_meddtasz;
184
static int hf_drda_trgdftrt;
185
static int hf_drda_rtnsqlda;
186
static int hf_drda_qryattupd;
187
static int hf_drda_qryrowset;
188
static int hf_drda_qryinsid;
189
static int hf_drda_qryclsimp;
190
static int hf_drda_qryblkfct;
191
static int hf_drda_maxrslcnt;
192
static int hf_drda_maxblkext;
193
static int hf_drda_rslsetflg;
194
static int hf_drda_rslsetflg_unused;
195
static int hf_drda_rslsetflg_dsconly;
196
static int hf_drda_rslsetflg_extended;
197
static int hf_drda_rslsetflg_reserved;
198
static int hf_drda_typsqlda;
199
static int hf_drda_outovropt;
200
static int hf_drda_dyndtafmt;
201
static int hf_drda_pktobj;
202
203
static int ett_drda;
204
static int ett_drda_ddm;
205
static int ett_drda_ddm_format;
206
static int ett_drda_param;
207
static int ett_drda_monitor;
208
static int ett_drda_rslsetflg;
209
static int ett_drda_sqlcagrp;
210
static int ett_drda_sqlcaxgrp;
211
static int ett_drda_sqldhgrp;
212
static int ett_drda_sqldagrp;
213
static int ett_drda_sqldoptgrp;
214
static int ett_drda_sqludtgrp;
215
static int ett_drda_sqldxgrp;
216
static int ett_drda_sqldiaggrp;
217
218
static expert_field ei_drda_opcode_invalid_length;
219
static expert_field ei_drda_undecoded;
220
221
static dissector_handle_t drda_tcp_handle;
222
223
static dissector_table_t drda_opcode_table;
224
225
#define typdefnam_vals_ENUM_VAL_T_LIST(XXX) \
226
    XXX(TYPDEFNAM_370, 1, "QTDSQL370", "System/390 SQL type definition") \
227
    XXX(TYPDEFNAM_400, 2, "QTDSQL400", "AS/400 SQL type definition") \
228
    XXX(TYPDEFNAM_X86, 3, "QTDSQLX86", "Intel 80x86 SQL type definition") \
229
    XXX(TYPDEFNAM_ASC, 4, "QTDSQLASC", "General ASCII Big Endian SQL type definition") \
230
    XXX(TYPDEFNAM_VAX, 5, "QTDSQLVAX", "DEC VAX SQL type definition")
231
232
typedef ENUM_VAL_T_ENUM(typdefnam_vals) enum_typdefnam_t;
233
234
ENUM_VAL_T_ARRAY_STATIC(typdefnam_vals);
235
236
/* Preferences */
237
static bool drda_desegment = true;
238
static unsigned drda_default_sqlam = 7;
239
static int drda_default_typdefnam = TYPDEFNAM_X86;
240
static int drda_default_ccsidsbc = IANA_CS_UTF_8;
241
static int drda_default_ccsidmbc = IANA_CS_UTF_8;
242
243
2.96k
#define DRDA_MAGIC  0xD0
244
245
#define DRDA_CP_DATA          0x0000
246
#define DRDA_CP_CODPNT        0x000C
247
14
#define DRDA_CP_FDODSC        0x0010
248
14
#define DRDA_CP_TYPDEFNAM     0x002F
249
14
#define DRDA_CP_TYPDEFOVR     0x0035
250
#define DRDA_CP_CODPNTDR      0x0064
251
0
#define DRDA_CP_EXCSAT        0x1041
252
#define DRDA_CP_SYNCCTL       0x1055
253
#define DRDA_CP_SYNCRSY       0x1069
254
#define DRDA_CP_ACCSEC        0x106D
255
#define DRDA_CP_SECCHK        0x106E
256
#define DRDA_CP_SYNCLOG       0x106F
257
#define DRDA_CP_RSCTYP        0x111F
258
#define DRDA_CP_RSNCOD        0x1127
259
#define DRDA_CP_RSCNAM        0x112D
260
#define DRDA_CP_PRDID         0x112E
261
#define DRDA_CP_PRCCNVCD      0x113F
262
#define DRDA_CP_VRSNAM        0x1144
263
#define DRDA_CP_SRVCLSNM      0x1147
264
14
#define DRDA_CP_SVRCOD        0x1149
265
#define DRDA_CP_SYNERRCD      0x114A
266
#define DRDA_CP_SRVDGN        0x1153
267
#define DRDA_CP_SRVRLSLV      0x115A
268
#define DRDA_CP_SPVNAM        0x115D
269
#define DRDA_CP_EXTNAM        0x115E
270
#define DRDA_CP_SRVNAM        0x116D
271
#define DRDA_CP_SECMGRNM      0x1196
272
#define DRDA_CP_DEPERRCD      0x119B
273
14
#define DRDA_CP_CCSIDSBC      0x119C
274
14
#define DRDA_CP_CCSIDDBC      0x119D
275
14
#define DRDA_CP_CCSIDMBC      0x119E
276
14
#define DRDA_CP_RLSCONV       0x119F
277
#define DRDA_CP_USRID         0x11A0
278
#define DRDA_CP_PASSWORD      0x11A1
279
14
#define DRDA_CP_SECMEC        0x11A2
280
14
#define DRDA_CP_SECCHKCD      0x11A4
281
#define DRDA_CP_SVCERRNO      0x11B4
282
14
#define DRDA_CP_SECTKN        0x11DC
283
#define DRDA_CP_NEWPASSWORD   0x11DE
284
#define DRDA_CP_MGRLVLRM      0x1210
285
#define DRDA_CP_MGRDEPRM      0x1218
286
#define DRDA_CP_SECCHKRM      0x1219
287
#define DRDA_CP_CMDATHRM      0x121C
288
#define DRDA_CP_AGNPRMRM      0x1232
289
#define DRDA_CP_RSCLMTRM      0x1233
290
#define DRDA_CP_PRCCNVRM      0x1245
291
#define DRDA_CP_CMDCMPRM      0x124B
292
#define DRDA_CP_SYNTAXRM      0x124C
293
#define DRDA_CP_CMDNSPRM      0x1250
294
#define DRDA_CP_PRMNSPRM      0x1251
295
#define DRDA_CP_VALNSPRM      0x1252
296
#define DRDA_CP_OBJNSPRM      0x1253
297
#define DRDA_CP_CMDCHKRM      0x1254
298
#define DRDA_CP_TRGNSPRM      0x125F
299
#define DRDA_CP_AGENT         0x1403
300
14
#define DRDA_CP_MGRLVLLS      0x1404
301
#define DRDA_CP_SUPERVISOR    0x143C
302
#define DRDA_CP_SECMGR        0x1440
303
5
#define DRDA_CP_EXCSATRD      0x1443
304
#define DRDA_CP_CMNAPPC       0x1444
305
#define DRDA_CP_DICTIONARY    0x1458
306
#define DRDA_CP_MGRLVLN       0x1473
307
#define DRDA_CP_CMNTCPIP      0x1474
308
14
#define DRDA_CP_FDODTA        0x147A
309
#define DRDA_CP_CMNSYNCPT     0x147C
310
#define DRDA_CP_ACCSECRD      0x14AC
311
#define DRDA_CP_SYNCPTMGR     0x14C0
312
#define DRDA_CP_RSYNCMGR      0x14C1
313
0
#define DRDA_CP_CCSIDMGR      0x14CC
314
#define DRDA_CP_SNDPKT        0x1805
315
14
#define DRDA_CP_MONITOR       0x1900
316
14
#define DRDA_CP_ETIME         0x1901
317
14
#define DRDA_CP_RESPKTSZ      0x1908
318
14
#define DRDA_CP_CCSIDXML      0x1913
319
#define DRDA_CP_MONITORRD     0x1C00
320
#define DRDA_CP_XAMGR         0x1C01
321
14
#define DRDA_CP_PKTOBJ        0x1C04
322
0
#define DRDA_CP_UNICODEMGR    0x1C08
323
10
#define DRDA_CP_ACCRDB        0x2001
324
#define DRDA_CP_BGNBND        0x2002
325
#define DRDA_CP_BNDSQLSTT     0x2004
326
#define DRDA_CP_CLSQRY        0x2005
327
#define DRDA_CP_CNTQRY        0x2006
328
#define DRDA_CP_DRPPKG        0x2007
329
#define DRDA_CP_DSCSQLSTT     0x2008
330
#define DRDA_CP_ENDBND        0x2009
331
#define DRDA_CP_EXCSQLIMM     0x200A
332
#define DRDA_CP_EXCSQLSTT     0x200B
333
#define DRDA_CP_OPNQRY        0x200C
334
#define DRDA_CP_PRPSQLSTT     0x200D
335
#define DRDA_CP_RDBCMM        0x200E
336
#define DRDA_CP_RDBRLLBCK     0x200F
337
#define DRDA_CP_REBIND        0x2010
338
#define DRDA_CP_DSCRDBTBL     0x2012
339
#define DRDA_CP_EXCSQLSET     0x2014
340
#define DRDA_CP_DSCERRCD      0x2101
341
14
#define DRDA_CP_QRYPRCTYP     0x2102
342
14
#define DRDA_CP_RDBINTTKN     0x2103
343
#define DRDA_CP_PRDDTA        0x2104
344
14
#define DRDA_CP_RDBCMTOK      0x2105
345
#define DRDA_CP_RDBCOLID      0x2108
346
#define DRDA_CP_PKGID         0x2109
347
14
#define DRDA_CP_PKGNAM        0x210A
348
#define DRDA_CP_PKGSN         0x210C
349
#define DRDA_CP_PKGCNSTKN     0x210D
350
14
#define DRDA_CP_RTNSETSTT     0x210E
351
14
#define DRDA_CP_RDBACCCL      0x210F
352
#define DRDA_CP_RDBNAM        0x2110
353
14
#define DRDA_CP_OUTEXP        0x2111
354
14
#define DRDA_CP_PKGNAMCT      0x2112
355
14
#define DRDA_CP_PKGNAMCSN     0x2113
356
14
#define DRDA_CP_QRYBLKSZ      0x2114
357
14
#define DRDA_CP_UOWDSP        0x2115
358
14
#define DRDA_CP_RTNSQLDA      0x2116
359
14
#define DRDA_CP_RDBALWUPD     0x211A
360
14
#define DRDA_CP_SQLCSRHLD     0x211F
361
#define DRDA_CP_STTSTRDEL     0x2120
362
#define DRDA_CP_STTDECDEL     0x2121
363
14
#define DRDA_CP_PKGDFTCST     0x2125
364
#define DRDA_CP_QRYBLKCTL     0x2132
365
14
#define DRDA_CP_QRYEXTDTASZ   0x2134
366
#define DRDA_CP_CRRTKN        0x2135
367
14
#define DRDA_CP_SMLDTASZ      0x2136
368
14
#define DRDA_CP_MEDDTASZ      0x2137
369
#define DRDA_CP_PRCNAM        0x2138
370
14
#define DRDA_CP_PKGSNLST      0x2139
371
#define DRDA_CP_NBRROW        0x213A
372
14
#define DRDA_CP_TRGDFTRT      0x213B
373
#define DRDA_CP_QRYRELSCR     0x213C
374
#define DRDA_CP_QRYROWNBR     0x213D
375
#define DRDA_CP_QRYRFRTBL     0x213E
376
14
#define DRDA_CP_MAXRSLCNT     0x2140
377
14
#define DRDA_CP_MAXBLKEXT     0x2141
378
14
#define DRDA_CP_RSLSETFLG     0x2142
379
14
#define DRDA_CP_TYPSQLDA      0x2146
380
14
#define DRDA_CP_OUTOVROPT     0x2147
381
#define DRDA_CP_RTNEXTDTA     0x2148
382
#define DRDA_CP_QRYATTSCR     0x2149
383
14
#define DRDA_CP_DYNDTAFMT     0x214B
384
14
#define DRDA_CP_QRYATTUPD     0x2150
385
#define DRDA_CP_QRYSCRORN     0x2152
386
#define DRDA_CP_QRYROWSNS     0x2153
387
#define DRDA_CP_QRYBLKRST     0x2154
388
#define DRDA_CP_QRYRTNDTA     0x2155
389
14
#define DRDA_CP_QRYROWSET     0x2156
390
#define DRDA_CP_QRYATTSNS     0x2157
391
14
#define DRDA_CP_QRYINSID      0x215B
392
14
#define DRDA_CP_QRYCLSIMP     0x215D
393
#define DRDA_CP_QRYCLSRLS     0x215E
394
14
#define DRDA_CP_QRYBLKFCT     0x215F
395
#define DRDA_CP_DIAGLVL       0x2160
396
3
#define DRDA_CP_ACCRDBRM      0x2201
397
#define DRDA_CP_QRYNOPRM      0x2202
398
#define DRDA_CP_RDBNACRM      0x2204
399
#define DRDA_CP_OPNQRYRM      0x2205
400
#define DRDA_CP_PKGBNARM      0x2206
401
#define DRDA_CP_RDBACCRM      0x2207
402
#define DRDA_CP_BGNBNDRM      0x2208
403
#define DRDA_CP_PKGBPARM      0x2209
404
#define DRDA_CP_DSCINVRM      0x220A
405
#define DRDA_CP_ENDQRYRM      0x220B
406
#define DRDA_CP_ENDUOWRM      0x220C
407
#define DRDA_CP_ABNUOWRM      0x220D
408
#define DRDA_CP_DTAMCHRM      0x220E
409
#define DRDA_CP_QRYPOPRM      0x220F
410
#define DRDA_CP_RDBNFNRM      0x2211
411
#define DRDA_CP_OPNQFLRM      0x2212
412
#define DRDA_CP_SQLERRRM      0x2213
413
#define DRDA_CP_RDBUPDRM      0x2218
414
#define DRDA_CP_RSLSETRM      0x2219
415
#define DRDA_CP_RDBAFLRM      0x221A
416
#define DRDA_CP_CMDVLTRM      0x221D
417
#define DRDA_CP_CMMRQSRM      0x2225
418
#define DRDA_CP_RDBATHRM      0x22CB
419
0
#define DRDA_CP_SQLAM         0x2407
420
14
#define DRDA_CP_SQLCARD       0x2408
421
#define DRDA_CP_SQLCINRD      0x240B
422
#define DRDA_CP_SQLRSLRD      0x240E
423
#define DRDA_CP_RDB           0x240F
424
#define DRDA_CP_FRCFIXROW     0x2410
425
14
#define DRDA_CP_SQLDARD       0x2411
426
#define DRDA_CP_SQLDTA        0x2412
427
#define DRDA_CP_SQLDTARD      0x2413
428
14
#define DRDA_CP_SQLSTT        0x2414
429
#define DRDA_CP_OUTOVR        0x2415
430
#define DRDA_CP_LMTBLKPRC     0x2417
431
#define DRDA_CP_FIXROWPRC     0x2418
432
#define DRDA_CP_SQLSTTVRB     0x2419
433
14
#define DRDA_CP_QRYDSC        0x241A
434
14
#define DRDA_CP_QRYDTA        0x241B
435
#define DRDA_CP_CSTSYSDFT     0x2432
436
#define DRDA_CP_CSTBITS       0x2433
437
#define DRDA_CP_CSTSBCS       0x2434
438
#define DRDA_CP_CSTMBCS       0x2435
439
#define DRDA_CP_ISOLVLCHG     0x2441
440
#define DRDA_CP_ISOLVLCS      0x2442
441
#define DRDA_CP_ISOLVLALL     0x2443
442
#define DRDA_CP_ISOLVLRR      0x2444
443
#define DRDA_CP_ISOLVLNC      0x2445
444
#define DRDA_CP_SRVLST        0x244E
445
14
#define DRDA_CP_SQLATTR       0x2450
446
447
14
#define DRDA_DSSFMT_SAME_CORR 0x10
448
14
#define DRDA_DSSFMT_CONTINUE  0x20
449
14
#define DRDA_DSSFMT_CHAINED   0x40
450
14
#define DRDA_DSSFMT_RESERVED  0x80
451
452
0
#define DRDA_DSSFMT_RQSDSS    0x01
453
0
#define DRDA_DSSFMT_RPYDSS    0x02
454
#define DRDA_DSSFMT_OBJDSS    0x03
455
#define DRDA_DSSFMT_CMNDSS    0x04
456
0
#define DRDA_DSSFMT_NORPYDSS  0x05
457
458
5
#define DRDA_TEXT_DDM   "DDM"
459
6
#define DRDA_TEXT_PARAM "Parameter"
460
461
static const value_string drda_opcode_vals[] = {
462
    { DRDA_CP_DATA,         "Data" },
463
    { DRDA_CP_CODPNT,       "Code Point" },
464
    { DRDA_CP_FDODSC,       "FD:OCA Data Descriptor" },
465
    { DRDA_CP_TYPDEFNAM,    "Data Type Definition Name" },
466
    { DRDA_CP_TYPDEFOVR,    "TYPDEF Overrides" },
467
    { DRDA_CP_CODPNTDR,     "Code Point Data Representation" },
468
    { DRDA_CP_EXCSAT,       "Exchange Server Attributes" },
469
    { DRDA_CP_SYNCCTL,      "Sync Point Control Request" },
470
    { DRDA_CP_SYNCRSY,      "Sync Point Resync Command" },
471
    { DRDA_CP_ACCSEC,       "Access Security" },
472
    { DRDA_CP_SECCHK,       "Security Check" },
473
    { DRDA_CP_SYNCLOG,      "Sync Point Log" },
474
    { DRDA_CP_RSCTYP,       "Resource Type Information" },
475
    { DRDA_CP_RSNCOD,       "Reason Code Information" },
476
    { DRDA_CP_RSCNAM,       "Resource Name Information" },
477
    { DRDA_CP_PRDID,        "Product-Specific Identifier" },
478
    { DRDA_CP_PRCCNVCD,     "Conversation Protocol Error Code" },
479
    { DRDA_CP_VRSNAM,       "Version Name" },
480
    { DRDA_CP_SRVCLSNM,     "Server Class Name" },
481
    { DRDA_CP_SVRCOD,       "Severity Code" },
482
    { DRDA_CP_SYNERRCD,     "Syntax Error Code" },
483
    { DRDA_CP_SRVDGN,       "Server Diagnostic Information" },
484
    { DRDA_CP_SRVRLSLV,     "Server Product Release Level" },
485
    { DRDA_CP_SPVNAM,       "Supervisor Name" },
486
    { DRDA_CP_EXTNAM,       "External Name" },
487
    { DRDA_CP_SRVNAM,       "Server Name" },
488
    { DRDA_CP_SECMGRNM,     "Security Manager Name" },
489
    { DRDA_CP_DEPERRCD,     "Manager Dependency Error Code" },
490
    { DRDA_CP_CCSIDSBC,     "CCSID for Single-Byte Characters" },
491
    { DRDA_CP_CCSIDDBC,     "CCSID for Double-byte Characters" },
492
    { DRDA_CP_CCSIDMBC,     "CCSID for Mixed-byte Characters" },
493
    { DRDA_CP_RLSCONV,      "Release Conversation" },
494
    { DRDA_CP_USRID,        "User ID at the Target System" },
495
    { DRDA_CP_PASSWORD,     "Password" },
496
    { DRDA_CP_SECMEC,       "Security Mechanism" },
497
    { DRDA_CP_SECCHKCD,     "Security Check Code" },
498
    { DRDA_CP_SVCERRNO,     "Security Service ErrorNumber" },
499
    { DRDA_CP_SECTKN,       "Security Token" },
500
    { DRDA_CP_NEWPASSWORD,  "New Password" },
501
    { DRDA_CP_MGRLVLRM,     "Manager-Level Conflict" },
502
    { DRDA_CP_MGRDEPRM,     "Manager Dependency Error" },
503
    { DRDA_CP_SECCHKRM,     "Security Check" },
504
    { DRDA_CP_CMDATHRM,     "Not Authorized to Command" },
505
    { DRDA_CP_AGNPRMRM,     "Permanent Agent Error" },
506
    { DRDA_CP_RSCLMTRM,     "Resource Limits Reached" },
507
    { DRDA_CP_PRCCNVRM,     "Conversational Protocol Error" },
508
    { DRDA_CP_CMDCMPRM,     "Command Processing Completed" },
509
    { DRDA_CP_SYNTAXRM,     "Data Stream Syntax Error" },
510
    { DRDA_CP_CMDNSPRM,     "Command Not Supported" },
511
    { DRDA_CP_PRMNSPRM,     "Parameter Not Supported" },
512
    { DRDA_CP_VALNSPRM,     "Parameter Value Not Supported" },
513
    { DRDA_CP_OBJNSPRM,     "Object Not Supported" },
514
    { DRDA_CP_CMDCHKRM,     "Command Check" },
515
    { DRDA_CP_TRGNSPRM,     "Target Not Supported" },
516
    { DRDA_CP_AGENT,        "Agent" },
517
    { DRDA_CP_MGRLVLLS,     "Manager-Level List" },
518
    { DRDA_CP_SUPERVISOR,   "Supervisor" },
519
    { DRDA_CP_SECMGR,       "Security Manager" },
520
    { DRDA_CP_EXCSATRD,     "Server Attributes Reply Data" },
521
    { DRDA_CP_CMNAPPC,      "LU 6.2 Conversational Communications Manager" },
522
    { DRDA_CP_DICTIONARY,   "Dictionary" },
523
    { DRDA_CP_MGRLVLN,      "Manager-Level Number Attribute" },
524
    { DRDA_CP_CMNTCPIP,     "TCP/IP CommunicationManager" },
525
    { DRDA_CP_FDODTA,       "FD:OCA Data" },
526
    { DRDA_CP_CMNSYNCPT,
527
      "SNA LU 6.2 Sync Point Conversational Communications Manager" },
528
    { DRDA_CP_ACCSECRD,     "Access Security Reply Data" },
529
    { DRDA_CP_SYNCPTMGR,    "Sync Point Manager" },
530
    { DRDA_CP_RSYNCMGR,     "ResynchronizationManager" },
531
    { DRDA_CP_CCSIDMGR,     "CCSID Manager" },
532
    { DRDA_CP_SNDPKT,       "Send Packet" },
533
    { DRDA_CP_MONITOR,      "Monitor Events" },
534
    { DRDA_CP_ETIME,        "Elapsed Time" },
535
    { DRDA_CP_RESPKTSZ,     "Response Packet Size" },
536
    { DRDA_CP_CCSIDXML,     "CCSID for External Encoded XML Strings" },
537
    { DRDA_CP_MONITORRD,    "Monitor Reply Data" },
538
    { DRDA_CP_XAMGR,        "XAManager" },
539
    { DRDA_CP_PKTOBJ,       "Packet Object" },
540
    { DRDA_CP_UNICODEMGR,   "Unicode Manager" },
541
    { DRDA_CP_ACCRDB,       "Access RDB" },
542
    { DRDA_CP_BGNBND,       "Begin Binding a Package to an RDB" },
543
    { DRDA_CP_BNDSQLSTT,    "Bind SQL Statement to an RDB Package" },
544
    { DRDA_CP_CLSQRY,       "Close Query" },
545
    { DRDA_CP_CNTQRY,       "Continue Query" },
546
    { DRDA_CP_DRPPKG,       "Drop RDB Package" },
547
    { DRDA_CP_DSCSQLSTT,    "Describe SQL Statement" },
548
    { DRDA_CP_ENDBND,       "End Binding a Package to an RDB" },
549
    { DRDA_CP_EXCSQLIMM,    "Execute Immediate SQL Statement" },
550
    { DRDA_CP_EXCSQLSTT,    "Execute SQL Statement" },
551
    { DRDA_CP_OPNQRY,       "Open Query" },
552
    { DRDA_CP_PRPSQLSTT,    "Prepare SQL Statement" },
553
    { DRDA_CP_RDBCMM,       "RDB Commit Unit of Work" },
554
    { DRDA_CP_RDBRLLBCK,    "RDB Rollback Unit of Work" },
555
    { DRDA_CP_REBIND,       "Rebind an Existing RDB Package" },
556
    { DRDA_CP_DSCRDBTBL,    "Describe RDB Table" },
557
    { DRDA_CP_EXCSQLSET,    "Set SQL Environment" },
558
    { DRDA_CP_DSCERRCD,     "Description Error Code" },
559
    { DRDA_CP_QRYPRCTYP,    "Query Protocol Type" },
560
    { DRDA_CP_RDBINTTKN,    "RDB Interrupt Token" },
561
    { DRDA_CP_PRDDTA,       "Product-Specific Data" },
562
    { DRDA_CP_RDBCMTOK,     "RDB Commit Allowed" },
563
    { DRDA_CP_RDBCOLID,     "RDB Collection Identifier" },
564
    { DRDA_CP_PKGID,        "RDB Package Identifier" },
565
    { DRDA_CP_PKGNAM,       "RDB Package Name" },
566
    { DRDA_CP_PKGSN,        "RDB Package Section Number" },
567
    { DRDA_CP_PKGCNSTKN,    "RDB Package Consistency Token" },
568
    { DRDA_CP_RTNSETSTT,    "Return SET Statement" },
569
    { DRDA_CP_RDBACCCL,     "RDB Access Manager Class" },
570
    { DRDA_CP_RDBNAM,       "Relational Database Name" },
571
    { DRDA_CP_OUTEXP,       "Output Expected" },
572
    { DRDA_CP_PKGNAMCT,     "RDB Package Name and Consistency Token" },
573
    { DRDA_CP_PKGNAMCSN,
574
      "RDB Package Name, Consistency Token, and Section Number" },
575
    { DRDA_CP_QRYBLKSZ,     "Query Block Size" },
576
    { DRDA_CP_UOWDSP,       "Unit of Work Disposition" },
577
    { DRDA_CP_RTNSQLDA,     "Maximum Result Set Count" },
578
    { DRDA_CP_RDBALWUPD,    "RDB Allow Updates" },
579
    { DRDA_CP_SQLCSRHLD,    "Hold Cursor Position" },
580
    { DRDA_CP_STTSTRDEL,    "Statement String Delimiter" },
581
    { DRDA_CP_STTDECDEL,    "Statement Decimal Delimiter" },
582
    { DRDA_CP_PKGDFTCST,    "Package Default Character Subtype" },
583
    { DRDA_CP_QRYBLKCTL,    "Query Block Protocol Control" },
584
    { DRDA_CP_QRYEXTDTASZ,  "Query Externalized Data Size" },
585
    { DRDA_CP_CRRTKN,       "Correlation Token" },
586
    { DRDA_CP_SMLDTASZ,     "Maximum Size of Small Data" },
587
    { DRDA_CP_MEDDTASZ,     "Maximum Size of Medium Data" },
588
    { DRDA_CP_PRCNAM,       "Procedure Name" },
589
    { DRDA_CP_PKGSNLST,     "RDB Result Set Reply Message" },
590
    { DRDA_CP_NBRROW,       "Number of Fetch or Insert Rows" },
591
    { DRDA_CP_TRGDFTRT,     "Target Default Value Return" },
592
    { DRDA_CP_QRYRELSCR,    "Query Relative Scrolling Action" },
593
    { DRDA_CP_QRYROWNBR,    "Query Row Number" },
594
    { DRDA_CP_QRYRFRTBL,    "Query Refresh Answer Set Table" },
595
    { DRDA_CP_MAXRSLCNT,    "Maximum Result Set Count" },
596
    { DRDA_CP_MAXBLKEXT,    "Maximum Number of Extra Blocks" },
597
    { DRDA_CP_RSLSETFLG,    "Result Set Flags" },
598
    { DRDA_CP_TYPSQLDA,     "Type of SQL Descriptor Area" },
599
    { DRDA_CP_OUTOVROPT,    "Output Override Option" },
600
    { DRDA_CP_RTNEXTDTA,    "Return of EXTDTA Option" },
601
    { DRDA_CP_QRYATTSCR,    "Query Attribute for Scrollability" },
602
    { DRDA_CP_DYNDTAFMT,    "Dynamic Data Format" },
603
    { DRDA_CP_QRYATTUPD,    "Query Attribute for Updatability" },
604
    { DRDA_CP_QRYSCRORN,    "Query Scroll Orientation" },
605
    { DRDA_CP_QRYROWSNS,    "Query Row Sensitivity" },
606
    { DRDA_CP_QRYBLKRST,    "Query Block Reset" },
607
    { DRDA_CP_QRYRTNDTA,    "Query Returns Datat" },
608
    { DRDA_CP_QRYROWSET,    "Query Rowset Size" },
609
    { DRDA_CP_QRYATTSNS,    "Query Attribute for Sensitivity" },
610
    { DRDA_CP_QRYINSID,     "Query Instance Identifier" },
611
    { DRDA_CP_QRYCLSIMP,    "Query Close Implicit" },
612
    { DRDA_CP_QRYCLSRLS,    "Query Close Lock Release" },
613
    { DRDA_CP_QRYBLKFCT,    "Query Blocking Factor" },
614
    { DRDA_CP_DIAGLVL,      "SQL Error Diagnostic Level" },
615
    { DRDA_CP_ACCRDBRM,     "Access to RDB Completed" },
616
    { DRDA_CP_QRYNOPRM,     "Query Not Open" },
617
    { DRDA_CP_RDBNACRM,     "RDB Not Accessed" },
618
    { DRDA_CP_OPNQRYRM,     "Open Query Complete" },
619
    { DRDA_CP_PKGBNARM,     "RDB Package Binding Not Active" },
620
    { DRDA_CP_RDBACCRM,     "RDB Currently Accessed" },
621
    { DRDA_CP_BGNBNDRM,     "Begin Bind Error" },
622
    { DRDA_CP_PKGBPARM,     "RDB Package Binding Process Active" },
623
    { DRDA_CP_DSCINVRM,     "Invalid Description" },
624
    { DRDA_CP_ENDQRYRM,     "End of Query" },
625
    { DRDA_CP_ENDUOWRM,     "End Unit of Work Condition" },
626
    { DRDA_CP_ABNUOWRM,     "Abnormal End Unit ofWork Condition" },
627
    { DRDA_CP_DTAMCHRM,     "Data Descriptor Mismatch" },
628
    { DRDA_CP_QRYPOPRM,     "Query Previously Opened" },
629
    { DRDA_CP_RDBNFNRM,     "RDB Not Found" },
630
    { DRDA_CP_OPNQFLRM,     "Open Query Failure" },
631
    { DRDA_CP_SQLERRRM,     "SQL Error Condition" },
632
    { DRDA_CP_RDBUPDRM,     "RDB Update Reply Message" },
633
    { DRDA_CP_RSLSETRM,     "RDB Result Set Reply Message" },
634
    { DRDA_CP_RDBAFLRM,     "RDB Access Failed Reply Message" },
635
    { DRDA_CP_CMDVLTRM,     "Command Violation" },
636
    { DRDA_CP_CMMRQSRM,     "Commitment Request" },
637
    { DRDA_CP_RDBATHRM,     "Not Authorized to RDB" },
638
    { DRDA_CP_SQLAM,        "SQL Application Manager" },
639
    { DRDA_CP_SQLCARD,      "SQL Communications Area Reply Data" },
640
    { DRDA_CP_SQLCINRD,     "SQL Result Set Column Information Reply Data" },
641
    { DRDA_CP_SQLRSLRD,     "SQL Result Set Reply Data" },
642
    { DRDA_CP_RDB,          "Relational Database" },
643
    { DRDA_CP_FRCFIXROW,    "Force Fixed Row Query Protocol" },
644
    { DRDA_CP_SQLDARD,      "SQLDA Reply Data" },
645
    { DRDA_CP_SQLDTA,       "SQL Program Variable Data" },
646
    { DRDA_CP_SQLDTARD,     "SQL Data Reply Data" },
647
    { DRDA_CP_SQLSTT,       "SQL Statement" },
648
    { DRDA_CP_OUTOVR,       "Output Override Descriptor" },
649
    { DRDA_CP_LMTBLKPRC,    "Limited Block Protocol" },
650
    { DRDA_CP_FIXROWPRC,    "Fixed Row Query Protocol" },
651
    { DRDA_CP_SQLSTTVRB,    "SQL Statement Variable Descriptions" },
652
    { DRDA_CP_QRYDSC,       "Query Answer Set Description" },
653
    { DRDA_CP_QRYDTA,       "Query Answer Set Data" },
654
    { DRDA_CP_CSTSYSDFT,    "Character Subtype System Default" },
655
    { DRDA_CP_CSTBITS,      "Character Subtype Bits" },
656
    { DRDA_CP_CSTSBCS,      "Character Subtype SBCS" },
657
    { DRDA_CP_CSTMBCS,      "Character Subtype MBCS" },
658
    { DRDA_CP_ISOLVLCHG,    "Isolation Level Change" },
659
    { DRDA_CP_ISOLVLCS,     "Isolation Level Cursor Stability" },
660
    { DRDA_CP_ISOLVLALL,    "Isolation Level All" },
661
    { DRDA_CP_ISOLVLRR,     "Isolation Level Repeatable Read" },
662
    { DRDA_CP_ISOLVLNC,     "Isolation Level No Commit" },
663
    { DRDA_CP_SRVLST,       "Server List" },
664
    { DRDA_CP_SQLATTR,      "SQL Statement Attributes" },
665
    { 0,          NULL }
666
};
667
static value_string_ext drda_opcode_vals_ext = VALUE_STRING_EXT_INIT(drda_opcode_vals);
668
669
static const value_string drda_opcode_abbr[] = {
670
    { DRDA_CP_DATA,         "DATA" },
671
    { DRDA_CP_CODPNT,       "CODPNT" },
672
    { DRDA_CP_FDODSC,       "FDODSC" },
673
    { DRDA_CP_TYPDEFNAM,    "TYPDEFNAM" },
674
    { DRDA_CP_TYPDEFOVR,    "TYPDEFOVR" },
675
    { DRDA_CP_CODPNTDR,     "CODPNTDR" },
676
    { DRDA_CP_EXCSAT,       "EXCSAT" },
677
    { DRDA_CP_SYNCCTL,      "SYNCCTL" },
678
    { DRDA_CP_SYNCRSY,      "SYNCRSY" },
679
    { DRDA_CP_ACCSEC,       "ACCSEC" },
680
    { DRDA_CP_SECCHK,       "SECCHK" },
681
    { DRDA_CP_SYNCLOG,      "SYNCLOG" },
682
    { DRDA_CP_RSCTYP,       "RSCTYP" },
683
    { DRDA_CP_RSNCOD,       "RSNCOD" },
684
    { DRDA_CP_RSCNAM,       "RSCNAM" },
685
    { DRDA_CP_PRDID,        "PRDID" },
686
    { DRDA_CP_PRCCNVCD,     "PRCCNVCD" },
687
    { DRDA_CP_VRSNAM,       "VRSNAM" },
688
    { DRDA_CP_SRVCLSNM,     "SRVCLSNM" },
689
    { DRDA_CP_SVRCOD,       "SVRCOD" },
690
    { DRDA_CP_SYNERRCD,     "SYNERRCD" },
691
    { DRDA_CP_SRVDGN,       "SRVDGN" },
692
    { DRDA_CP_SRVRLSLV,     "SRVRLSLV" },
693
    { DRDA_CP_SPVNAM,       "SPVNAM" },
694
    { DRDA_CP_EXTNAM,       "EXTNAM" },
695
    { DRDA_CP_SRVNAM,       "SRVNAM" },
696
    { DRDA_CP_SECMGRNM,     "SECMGRNM" },
697
    { DRDA_CP_DEPERRCD,     "DEPERRCD" },
698
    { DRDA_CP_CCSIDSBC,     "CCSIDSBC" },
699
    { DRDA_CP_CCSIDDBC,     "CCSIDDBC" },
700
    { DRDA_CP_CCSIDMBC,     "CCSIDMBC" },
701
    { DRDA_CP_RLSCONV,      "RLSCONV" },
702
    { DRDA_CP_USRID,        "USRID" },
703
    { DRDA_CP_PASSWORD,     "PASSWORD" },
704
    { DRDA_CP_SECMEC,       "SECMEC" },
705
    { DRDA_CP_SECCHKCD,     "SECCHKCD" },
706
    { DRDA_CP_SVCERRNO,     "SVCERRNO" },
707
    { DRDA_CP_SECTKN,       "SECTKN" },
708
    { DRDA_CP_NEWPASSWORD,  "NEWPASSWORD" },
709
    { DRDA_CP_MGRLVLRM,     "MGRLVLRM" },
710
    { DRDA_CP_MGRDEPRM,     "MGRDEPRM" },
711
    { DRDA_CP_SECCHKRM,     "SECCHKRM" },
712
    { DRDA_CP_CMDATHRM,     "CMDATHRM" },
713
    { DRDA_CP_AGNPRMRM,     "AGNPRMRM" },
714
    { DRDA_CP_RSCLMTRM,     "RSCLMTRM" },
715
    { DRDA_CP_PRCCNVRM,     "PRCCNVRM" },
716
    { DRDA_CP_CMDCMPRM,     "CMDCMPRM" },
717
    { DRDA_CP_SYNTAXRM,     "SYNTAXRM" },
718
    { DRDA_CP_CMDNSPRM,     "CMDNSPRM" },
719
    { DRDA_CP_PRMNSPRM,     "PRMNSPRM" },
720
    { DRDA_CP_VALNSPRM,     "VALNSPRM" },
721
    { DRDA_CP_OBJNSPRM,     "OBJNSPRM" },
722
    { DRDA_CP_CMDCHKRM,     "CMDCHKRM" },
723
    { DRDA_CP_TRGNSPRM,     "TRGNSPRM" },
724
    { DRDA_CP_AGENT,        "AGENT" },
725
    { DRDA_CP_MGRLVLLS,     "MGRLVLLS" },
726
    { DRDA_CP_SUPERVISOR,   "SUPERVISOR" },
727
    { DRDA_CP_SECMGR,       "SECMGR" },
728
    { DRDA_CP_EXCSATRD,     "EXCSATRD" },
729
    { DRDA_CP_CMNAPPC,      "CMNAPPC" },
730
    { DRDA_CP_DICTIONARY,   "DICTIONARY" },
731
    { DRDA_CP_MGRLVLN,      "MGRLVLN" },
732
    { DRDA_CP_CMNTCPIP,     "CMNTCPIP" },
733
    { DRDA_CP_FDODTA,       "FDODTA" },
734
    { DRDA_CP_CMNSYNCPT,    "CMNSYNCPT" },
735
    { DRDA_CP_ACCSECRD,     "ACCSECRD" },
736
    { DRDA_CP_SYNCPTMGR,    "SYNCPTMGR" },
737
    { DRDA_CP_RSYNCMGR,     "RSYNCMGR" },
738
    { DRDA_CP_CCSIDMGR,     "CCSIDMGR" },
739
    { DRDA_CP_SNDPKT,       "SNDPKT" },
740
    { DRDA_CP_MONITOR,      "MONITOR" },
741
    { DRDA_CP_ETIME,        "ETIME" },
742
    { DRDA_CP_RESPKTSZ,     "RESPKTSZ" },
743
    { DRDA_CP_CCSIDXML,     "CCSIDXML" },
744
    { DRDA_CP_MONITORRD,    "MONITORRD" },
745
    { DRDA_CP_XAMGR,        "XAMGR" },
746
    { DRDA_CP_PKTOBJ,       "PKTOBJ" },
747
    { DRDA_CP_UNICODEMGR,   "UNICODEMGR" },
748
    { DRDA_CP_ACCRDB,       "ACCRDB" },
749
    { DRDA_CP_BGNBND,       "BGNBND" },
750
    { DRDA_CP_BNDSQLSTT,    "BNDSQLSTT" },
751
    { DRDA_CP_CLSQRY,       "CLSQRY" },
752
    { DRDA_CP_CNTQRY,       "CNTQRY" },
753
    { DRDA_CP_DRPPKG,       "DRPPKG" },
754
    { DRDA_CP_DSCSQLSTT,    "DSCSQLSTT" },
755
    { DRDA_CP_ENDBND,       "ENDBND" },
756
    { DRDA_CP_EXCSQLIMM,    "EXCSQLIMM" },
757
    { DRDA_CP_EXCSQLSTT,    "EXCSQLSTT" },
758
    { DRDA_CP_OPNQRY,       "OPNQRY" },
759
    { DRDA_CP_PRPSQLSTT,    "PRPSQLSTT" },
760
    { DRDA_CP_RDBCMM,       "RDBCMM" },
761
    { DRDA_CP_RDBRLLBCK,    "RDBRLLBCK" },
762
    { DRDA_CP_REBIND,       "REBIND" },
763
    { DRDA_CP_DSCRDBTBL,    "DSCRDBTBL" },
764
    { DRDA_CP_EXCSQLSET,    "EXCSQLSET" },
765
    { DRDA_CP_DSCERRCD,     "DSCERRCD" },
766
    { DRDA_CP_QRYPRCTYP,    "QRYPRCTYP" },
767
    { DRDA_CP_RDBINTTKN,    "RDBINTTKN" },
768
    { DRDA_CP_PRDDTA,       "PRDDTA" },
769
    { DRDA_CP_RDBCMTOK,     "RDBCMTOK" },
770
    { DRDA_CP_RDBCOLID,     "RDBCOLID" },
771
    { DRDA_CP_PKGID,        "PKGID" },
772
    { DRDA_CP_PKGNAM,       "PKGNAM" },
773
    { DRDA_CP_PKGSN,        "PKGSN" },
774
    { DRDA_CP_PKGCNSTKN,    "PKGCNSTKN" },
775
    { DRDA_CP_RTNSETSTT,    "RTNSETSTT" },
776
    { DRDA_CP_RDBACCCL,     "RDBACCCL" },
777
    { DRDA_CP_RDBNAM,       "RDBNAM" },
778
    { DRDA_CP_OUTEXP,       "OUTEXP" },
779
    { DRDA_CP_PKGNAMCT,     "PKGNAMCT" },
780
    { DRDA_CP_PKGNAMCSN,    "PKGNAMCSN" },
781
    { DRDA_CP_QRYBLKSZ,     "QRYBLKSZ" },
782
    { DRDA_CP_UOWDSP,       "UOWDSP" },
783
    { DRDA_CP_RTNSQLDA,     "RTNSQLDA" },
784
    { DRDA_CP_RDBALWUPD,    "RDBALWUPD" },
785
    { DRDA_CP_SQLCSRHLD,    "SQLCSRHLD" },
786
    { DRDA_CP_STTSTRDEL,    "STTSTRDEL" },
787
    { DRDA_CP_STTDECDEL,    "STTDECDEL" },
788
    { DRDA_CP_PKGDFTCST,    "PKGDFTCST" },
789
    { DRDA_CP_QRYBLKCTL,    "QRYBLKCTL" },
790
    { DRDA_CP_QRYEXTDTASZ,  "QRYEXTDTASZ" },
791
    { DRDA_CP_CRRTKN,       "CRRTKN" },
792
    { DRDA_CP_SMLDTASZ,     "SMLDTASZ" },
793
    { DRDA_CP_MEDDTASZ,     "MEDDTASZ" },
794
    { DRDA_CP_PRCNAM,       "PRCNAM" },
795
    { DRDA_CP_PKGSNLST,     "PKGSNLST" },
796
    { DRDA_CP_NBRROW,       "NBRROW" },
797
    { DRDA_CP_TRGDFTRT,     "TRGDFTRT" },
798
    { DRDA_CP_QRYRELSCR,    "QRYRELSCR" },
799
    { DRDA_CP_QRYROWNBR,    "QRYROWNBR" },
800
    { DRDA_CP_QRYRFRTBL,    "QRYRFRTBL" },
801
    { DRDA_CP_MAXRSLCNT,    "MAXRSLCNT" },
802
    { DRDA_CP_MAXBLKEXT,    "MAXBLKEXT" },
803
    { DRDA_CP_RSLSETFLG,    "RSLSETFLG" },
804
    { DRDA_CP_TYPSQLDA,     "TYPSQLDA" },
805
    { DRDA_CP_OUTOVROPT,    "OUTOVROPT" },
806
    { DRDA_CP_RTNEXTDTA,    "RTNEXTDTA" },
807
    { DRDA_CP_QRYATTSCR,    "QRYATTSCR" },
808
    { DRDA_CP_DYNDTAFMT,    "DYNDTAFMT" },
809
    { DRDA_CP_QRYATTUPD,    "QRYATTUPD" },
810
    { DRDA_CP_QRYSCRORN,    "QRYSCRORN" },
811
    { DRDA_CP_QRYROWSNS,    "QRYROWSNS" },
812
    { DRDA_CP_QRYBLKRST,    "QRYBLKRST" },
813
    { DRDA_CP_QRYRTNDTA,    "QRYRTNDTA" },
814
    { DRDA_CP_QRYROWSET,    "QRYROWSET" },
815
    { DRDA_CP_QRYATTSNS,    "QRYATTSNS" },
816
    { DRDA_CP_QRYINSID,     "QRYINSID" },
817
    { DRDA_CP_QRYCLSIMP,    "QRYCLSIMP" },
818
    { DRDA_CP_QRYCLSRLS,    "QRYCLSRLS" },
819
    { DRDA_CP_QRYBLKFCT,    "QRYBLKFCT" },
820
    { DRDA_CP_DIAGLVL,      "DIAGLVL" },
821
    { DRDA_CP_ACCRDBRM,     "ACCRDBRM" },
822
    { DRDA_CP_QRYNOPRM,     "QRYNOPRM" },
823
    { DRDA_CP_RDBNACRM,     "RDBNACRM" },
824
    { DRDA_CP_OPNQRYRM,     "OPNQRYRM" },
825
    { DRDA_CP_PKGBNARM,     "PKGBNARM" },
826
    { DRDA_CP_RDBACCRM,     "RDBACCRM" },
827
    { DRDA_CP_BGNBNDRM,     "BGNBNDRM" },
828
    { DRDA_CP_PKGBPARM,     "PKGBPARM" },
829
    { DRDA_CP_DSCINVRM,     "DSCINVRM" },
830
    { DRDA_CP_ENDQRYRM,     "ENDQRYRM" },
831
    { DRDA_CP_ENDUOWRM,     "ENDUOWRM" },
832
    { DRDA_CP_ABNUOWRM,     "ABNUOWRM" },
833
    { DRDA_CP_DTAMCHRM,     "DTAMCHRM" },
834
    { DRDA_CP_QRYPOPRM,     "QRYPOPRM" },
835
    { DRDA_CP_RDBNFNRM,     "RDBNFNRM" },
836
    { DRDA_CP_OPNQFLRM,     "OPNQFLRM" },
837
    { DRDA_CP_SQLERRRM,     "SQLERRRM" },
838
    { DRDA_CP_RDBUPDRM,     "RDBUPDRM" },
839
    { DRDA_CP_RSLSETRM,     "RSLSETRM" },
840
    { DRDA_CP_RDBAFLRM,     "RDBAFLRM" },
841
    { DRDA_CP_CMDVLTRM,     "CMDVLTRM" },
842
    { DRDA_CP_CMMRQSRM,     "CMMRQSRM" },
843
    { DRDA_CP_RDBATHRM,     "RDBATHRM" },
844
    { DRDA_CP_SQLAM,        "SQLAM" },
845
    { DRDA_CP_SQLCARD,      "SQLCARD" },
846
    { DRDA_CP_SQLCINRD,     "SQLCINRD" },
847
    { DRDA_CP_SQLRSLRD,     "SQLRSLRD" },
848
    { DRDA_CP_RDB,          "RDB" },
849
    { DRDA_CP_FRCFIXROW,    "FRCFIXROW" },
850
    { DRDA_CP_SQLDARD,      "SQLDARD" },
851
    { DRDA_CP_SQLDTA,       "SQLDTA" },
852
    { DRDA_CP_SQLDTARD,     "SQLDTARD" },
853
    { DRDA_CP_SQLSTT,       "SQLSTT" },
854
    { DRDA_CP_OUTOVR,       "OUTOVR" },
855
    { DRDA_CP_LMTBLKPRC,    "LMTBLKPRC" },
856
    { DRDA_CP_FIXROWPRC,    "FIXROWPRC" },
857
    { DRDA_CP_SQLSTTVRB,    "SQLSTTVRB" },
858
    { DRDA_CP_QRYDSC,       "QRYDSC" },
859
    { DRDA_CP_QRYDTA,       "QRYDTA" },
860
    { DRDA_CP_CSTSYSDFT,    "CSTSYSDFT" },
861
    { DRDA_CP_CSTBITS,      "CSTBITS" },
862
    { DRDA_CP_CSTSBCS,      "CSTSBCS" },
863
    { DRDA_CP_CSTMBCS,      "CSTMBCS" },
864
    { DRDA_CP_ISOLVLCHG,    "ISOLVLCHG" },
865
    { DRDA_CP_ISOLVLCS,     "ISOLVLCS" },
866
    { DRDA_CP_ISOLVLALL,    "ISOLVLALL" },
867
    { DRDA_CP_ISOLVLRR,     "ISOLVLRR" },
868
    { DRDA_CP_ISOLVLNC,     "ISOLVLNC" },
869
    { DRDA_CP_SRVLST,       "SRVLST" },
870
    { DRDA_CP_SQLATTR,      "SQLATTR" },
871
    { 0,          NULL }
872
};
873
static value_string_ext drda_opcode_abbr_ext = VALUE_STRING_EXT_INIT(drda_opcode_abbr);
874
875
static const value_string drda_dsstyp_abbr[] = {
876
    { DRDA_DSSFMT_RQSDSS,     "RQSDSS" },
877
    { DRDA_DSSFMT_RPYDSS,     "RPYDSS" },
878
    { DRDA_DSSFMT_OBJDSS,     "OBJDSS" },
879
    { DRDA_DSSFMT_CMNDSS,     "CMNDSS" },
880
    { DRDA_DSSFMT_NORPYDSS,   "NORPYDSS" },
881
    { 0,          NULL }
882
};
883
884
static const value_string drda_boolean_vals[] = {
885
    { 0xF0, "FALSE" }, /* \xf0 - EBCDIC '0' */
886
    { 0xF1, "TRUE" },  /* \xf1 - EBCDIC '1' */
887
    { 0, NULL }
888
};
889
890
static const value_string drda_max_vals[] =
891
{
892
    { -1, "Unlimited"},
893
    {  0, NULL }
894
};
895
896
static const range_string drda_null_ind_rvals[] =
897
{
898
    { 0x00, 0x00, "Complete data value follows" },
899
    { 0x01, 0x7F, "Truncation has occurred (should not occur in DRDA)" },
900
    { 0x80, 0xFD, "Reserved; no data value follows" },
901
    { 0xFE, 0xFE, "Undefined result; no data value follows" },
902
    { 0xFF, 0xFF, "NULL; no data value follows" },
903
    { 0, 0, NULL },
904
};
905
906
typedef struct _drda_encoding_t {
907
    enum_typdefnam_t typdefnam;
908
    unsigned sbc;
909
    unsigned mbc;
910
} drda_encoding_t;
911
912
typedef struct _drda_flow_t {
913
    wmem_tree_t* encoding_tree;
914
    wmem_tree_t* sqlam_tree;
915
} drda_flow_t;
916
917
typedef struct _drda_conv_info_t {
918
    drda_flow_t *client; /* AKA source system */
919
    drda_flow_t *server; /* AKA target system */
920
921
    address srv_addr;
922
    port_type srv_ptype;
923
    unsigned srv_port;
924
} drda_conv_info_t;
925
926
typedef struct _drda_pdu_info_t {
927
    unsigned sqlam;
928
    enum_typdefnam_t typdefnam;
929
    unsigned sbc;
930
    unsigned mbc;
931
} drda_pdu_info_t;
932
933
static drda_flow_t*
934
drda_new_flow(wmem_allocator_t *alloc, packet_info *pinfo)
935
6
{
936
6
    drda_flow_t *new_flow = wmem_new(alloc, drda_flow_t);
937
938
6
    new_flow->encoding_tree = wmem_tree_new(alloc);
939
6
    new_flow->sqlam_tree = wmem_tree_new(alloc);
940
6
    wmem_tree_insert32(new_flow->sqlam_tree, pinfo->num, GUINT_TO_POINTER(drda_default_sqlam));
941
942
6
    return new_flow;
943
6
}
944
945
static void
946
drda_update_flow_encoding(packet_info *pinfo, drda_flow_t *flow, const drda_pdu_info_t *pdu_info)
947
0
{
948
0
    drda_encoding_t *encoding = wmem_tree_lookup32_le(flow->encoding_tree, pinfo->num);
949
0
    if (encoding) {
950
0
        if (encoding->typdefnam == pdu_info->typdefnam && encoding->sbc == pdu_info->sbc && encoding->mbc == pdu_info->mbc) {
951
0
            return;
952
0
        }
953
0
    }
954
0
    encoding = wmem_new(wmem_file_scope(), drda_encoding_t);
955
0
    encoding->mbc = pdu_info->mbc;
956
0
    encoding->sbc = pdu_info->sbc;
957
0
    encoding->typdefnam = pdu_info->typdefnam;
958
0
    wmem_tree_insert32(flow->encoding_tree, pinfo->num, encoding);
959
0
}
960
961
static drda_conv_info_t*
962
drda_get_conv_info(packet_info *pinfo)
963
13
{
964
13
    conversation_t *conv = find_or_create_conversation(pinfo);
965
13
    drda_conv_info_t *conv_info = conversation_get_proto_data(conv, proto_drda);
966
967
13
    if (conv_info == NULL) {
968
3
        conv_info = wmem_new0(wmem_file_scope(), drda_conv_info_t);
969
970
3
        conv_info->client = drda_new_flow(wmem_file_scope(), pinfo);
971
3
        conv_info->server = drda_new_flow(wmem_file_scope(), pinfo);
972
973
3
        conversation_add_proto_data(conv, proto_drda, conv_info);
974
3
    }
975
13
    return conv_info;
976
13
}
977
978
static drda_pdu_info_t*
979
drda_get_pdu_info(packet_info *pinfo, uint32_t correl, bool is_server)
980
5
{
981
5
    drda_pdu_info_t *pdu_info;
982
983
    /* "When the TYPDEFNAM object is specified as a command/reply data object,
984
     * the value specified applies to the following command data objects and
985
     * reply data objects for that command, respectively. When TYPDEFNAM is
986
     * repeatable, the value of one TYPDEFNAM object is applicable only to
987
     * those objects (command data or reply data) that are sent before another
988
     * TYPDEFNAM object is sent. The value of TYPDEFNAM that a command
989
     * specifies is in effect only for that command. This rule applies to all
990
     * commands, unless specified otherwise." Similar for TYPDEFOVR.
991
     *
992
     * This means that encoding values are initialized to those set for the
993
     * given direction for entire conversation by ACCRDB[RM] for each
994
     * frame, or for each time the correlation ID changes (representing
995
     * a different command; shared correlation IDs in a frame (after
996
     * desegmentation, if needed) are data objects for the same command.)
997
     */
998
5
    pdu_info = p_get_proto_data(pinfo->pool, pinfo, proto_drda, correl);
999
1000
5
    if (!pdu_info) {
1001
5
        pdu_info = wmem_new(pinfo->pool, drda_pdu_info_t);
1002
5
        drda_conv_info_t *conv_info = drda_get_conv_info(pinfo);
1003
5
        drda_flow_t *flow = is_server ? conv_info->server : conv_info->client;
1004
5
        pdu_info->sqlam = GPOINTER_TO_UINT(wmem_tree_lookup32_le(flow->sqlam_tree, pinfo->num));
1005
5
        drda_encoding_t *encoding = wmem_tree_lookup32_le(flow->encoding_tree, pinfo->num);
1006
5
        if (encoding) {
1007
0
            pdu_info->typdefnam = encoding->typdefnam;
1008
0
            pdu_info->sbc = encoding->sbc;
1009
0
            pdu_info->mbc = encoding->mbc;
1010
5
        } else {
1011
5
            pdu_info->typdefnam = drda_default_typdefnam;
1012
5
            pdu_info->sbc = mibenum_charset_to_encoding((unsigned)drda_default_ccsidsbc);
1013
5
            pdu_info->mbc = mibenum_charset_to_encoding((unsigned)drda_default_ccsidmbc);
1014
5
        }
1015
1016
5
        p_set_proto_data(pinfo->pool, pinfo, proto_drda, correl, pdu_info);
1017
5
    }
1018
1019
1020
5
    return pdu_info;
1021
5
}
1022
1023
static void
1024
drda_set_server(drda_conv_info_t *conv_info, address *addr, port_type ptype, uint32_t port)
1025
0
{
1026
0
    copy_address_wmem(wmem_file_scope(), &conv_info->srv_addr, addr);
1027
0
    conv_info->srv_ptype = ptype;
1028
0
    conv_info->srv_port = port;
1029
0
}
1030
1031
static bool
1032
drda_packet_from_server(packet_info *pinfo, uint32_t command, uint8_t dsstyp)
1033
5
{
1034
5
    drda_conv_info_t *conv_info = drda_get_conv_info(pinfo);
1035
5
    if (conv_info->srv_addr.type != AT_NONE) {
1036
0
        return (conv_info->srv_ptype == pinfo->ptype) &&
1037
0
               (conv_info->srv_port == pinfo->srcport) &&
1038
0
               addresses_equal(&conv_info->srv_addr, &pinfo->src);
1039
0
    }
1040
5
    switch (command) {
1041
0
    case DRDA_CP_EXCSAT:
1042
0
    case DRDA_CP_ACCRDB:
1043
        /* Client */
1044
0
        drda_set_server(conv_info, &pinfo->dst, pinfo->ptype, pinfo->destport);
1045
0
        return false;
1046
1047
0
    case DRDA_CP_EXCSATRD:
1048
0
    case DRDA_CP_ACCRDBRM:
1049
        /* Server (EXCSATRD is OBJDSS, which itself is inconclusive.) */
1050
0
        drda_set_server(conv_info, &pinfo->src, pinfo->ptype, pinfo->srcport);
1051
0
        return true;
1052
1053
5
    }
1054
    /* The above commands are the ones that matter the most for determining
1055
     * direction.
1056
     */
1057
5
    switch (dsstyp) {
1058
0
    case DRDA_DSSFMT_RQSDSS:
1059
0
    case DRDA_DSSFMT_NORPYDSS:
1060
0
        drda_set_server(conv_info, &pinfo->dst, pinfo->ptype, pinfo->destport);
1061
0
        return false;
1062
1063
0
    case DRDA_DSSFMT_RPYDSS:
1064
0
        drda_set_server(conv_info, &pinfo->src, pinfo->ptype, pinfo->srcport);
1065
0
        return true;
1066
1067
5
    default:
1068
        /* We will be using the default values from the prefs anyway, since
1069
         * this means we won't have received ACCRDB[RM] yet.
1070
         */
1071
5
        break;
1072
5
    }
1073
1074
5
    return false;
1075
5
}
1076
1077
static int
1078
dissect_fdoca_integer(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset,int length, const drda_pdu_info_t *pdu_info, int32_t *value)
1079
0
{
1080
0
    unsigned endian;
1081
0
    switch (pdu_info->typdefnam) {
1082
0
    case TYPDEFNAM_370:
1083
0
    case TYPDEFNAM_400:
1084
0
    case TYPDEFNAM_ASC:
1085
0
        endian = ENC_BIG_ENDIAN;
1086
0
        break;
1087
0
    case TYPDEFNAM_X86:
1088
0
    case TYPDEFNAM_VAX:
1089
0
    default:
1090
0
        endian = ENC_LITTLE_ENDIAN;
1091
0
        break;
1092
0
    }
1093
0
    proto_tree_add_item_ret_int(tree, hf_index, tvb, offset, length, endian, value);
1094
0
    return offset + length;
1095
0
}
1096
1097
static int
1098
dissect_fdoca_integer64(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset,int length, const drda_pdu_info_t *pdu_info, int64_t *value)
1099
0
{
1100
0
    unsigned endian;
1101
0
    switch (pdu_info->typdefnam) {
1102
0
    case TYPDEFNAM_370:
1103
0
    case TYPDEFNAM_400:
1104
0
    case TYPDEFNAM_ASC:
1105
0
        endian = ENC_BIG_ENDIAN;
1106
0
        break;
1107
0
    case TYPDEFNAM_X86:
1108
0
    case TYPDEFNAM_VAX:
1109
0
    default:
1110
0
        endian = ENC_LITTLE_ENDIAN;
1111
0
        break;
1112
0
    }
1113
0
    proto_tree_add_item_ret_int64(tree, hf_index, tvb, offset, length, endian, value);
1114
0
    return offset + length;
1115
0
}
1116
1117
static int
1118
dissect_fdoca_fcs(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, int length, const drda_pdu_info_t *pdu_info)
1119
0
{
1120
0
    proto_tree_add_item(tree, hf_index, tvb, offset, length, pdu_info->sbc);
1121
0
    return offset + length;
1122
0
}
1123
1124
static int
1125
dissect_fdoca_vcs(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, const drda_pdu_info_t *pdu_info)
1126
0
{
1127
0
    uint32_t item_len;
1128
0
    proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &item_len);
1129
0
    offset += 2;
1130
0
    proto_tree_add_item(tree, hf_index, tvb, offset, item_len, pdu_info->sbc);
1131
0
    return offset + (int)item_len;
1132
0
}
1133
1134
static int
1135
dissect_fdoca_vcm(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, const drda_pdu_info_t *pdu_info)
1136
0
{
1137
0
    uint32_t item_len;
1138
0
    proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &item_len);
1139
0
    offset += 2;
1140
0
    proto_tree_add_item(tree, hf_index, tvb, offset, item_len, pdu_info->mbc);
1141
0
    return offset + (int)item_len;
1142
0
}
1143
1144
static int
1145
dissect_fdoca_nocs(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, const drda_pdu_info_t *pdu_info)
1146
0
{
1147
0
    uint32_t null_ind, item_length;
1148
0
    proto_tree_add_item_ret_uint(tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1149
0
    offset++;
1150
0
    if ((int8_t)null_ind >= 0) {
1151
0
        proto_tree_add_item_ret_uint(tree, hf_drda_clob_length, tvb, offset, 4, ENC_BIG_ENDIAN, &item_length);
1152
0
        offset += 4;
1153
0
        proto_tree_add_item(tree, hf_index, tvb, offset, item_length, pdu_info->sbc);
1154
0
        offset += item_length;
1155
0
    }
1156
0
    return offset;
1157
0
}
1158
1159
static int
1160
dissect_fdoca_nocm(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, const drda_pdu_info_t *pdu_info)
1161
0
{
1162
0
    uint32_t null_ind, item_length;
1163
0
    proto_tree_add_item_ret_uint(tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1164
0
    offset++;
1165
0
    if ((int8_t)null_ind >= 0) {
1166
0
        proto_tree_add_item_ret_uint(tree, hf_drda_clob_length, tvb, offset, 4, ENC_BIG_ENDIAN, &item_length);
1167
0
        offset += 4;
1168
0
        proto_tree_add_item(tree, hf_index, tvb, offset, item_length, pdu_info->mbc);
1169
0
        offset += item_length;
1170
0
    }
1171
0
    return offset;
1172
0
}
1173
1174
static int
1175
dissect_drda_typdefnam(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1176
0
{
1177
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1178
0
    const char *typdefnam;
1179
1180
0
    proto_tree_add_item_ret_string(tree, hf_drda_typdefnam, tvb, 0, tvb_reported_length(tvb), ENC_UTF_8, pinfo->pool, (const uint8_t**)&typdefnam);
1181
0
    for (int i = 0; typdefnam_vals[i].name != NULL; i++) {
1182
0
        if (strcmp(typdefnam_vals[i].name, typdefnam) == 0) {
1183
0
            pdu_info->typdefnam = typdefnam_vals[i].value;
1184
0
            break;
1185
0
        }
1186
0
    }
1187
0
    proto_tree_add_item_ret_string(tree, hf_drda_typdefnam, tvb, 0, tvb_reported_length(tvb), ENC_EBCDIC_CP500, pinfo->pool, (const uint8_t**)&typdefnam);
1188
0
    for (int i = 0; typdefnam_vals[i].name != NULL; i++) {
1189
0
        if (strcmp(typdefnam_vals[i].name, typdefnam) == 0) {
1190
0
            pdu_info->typdefnam = typdefnam_vals[i].value;
1191
0
            break;
1192
0
        }
1193
0
    }
1194
0
    return tvb_reported_length(tvb);
1195
0
}
1196
1197
static int
1198
dissect_drda_sqlstt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1199
0
{
1200
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1201
1202
0
    int offset = 0;
1203
1204
0
    uint32_t sqlstt_length;
1205
1206
    /* If SECMGR is Level 6 and higher, it's possible to select a SECMEC
1207
     * that means that the security-sensitive DDM/FD:OCA objects are encrypted.
1208
     * They are SQLDTA, SQLDTARD, SQLSTT, SQLDARD, SQLATTR, SQLCINRD,
1209
     * SQLRSLRD, SQLSTTVRB, QRYDTA, EXTDTA, and SECTKNOVR.
1210
     * XXX: We don't handle the encryption, and we don't handle looking at
1211
     * the SECMEC to see if they are encrypted.
1212
     */
1213
1214
    /* From the DRDA Specification Volume 1, 1.1 The DRDA Reference
1215
     * (Version 4 and later):
1216
     * Greater than 32,767 Byte SQL Statements
1217
     * "Existing early descriptor character fields are mapped to a Variable
1218
     * Character Mixed or a Variable Character SBCS which allow a maximum of
1219
     * 32,767 bytes. SQL Statements described by the SQL Statement Group use
1220
     * these character fields. To allow SQL Statements to extend beyond the 32K
1221
     * limit, SQL statements are changed to map to nullable Large Character
1222
     * Objects Mixed and nullable Large Character Objects SBCS to allow for
1223
     * very large SQL Statements."
1224
     *
1225
     * In other words, it changed from a pair of non nullable LONG VARCHARs
1226
     * to a pair of nullable CLOBs, meaning that each string gained a
1227
     * null indicator byte and the length field grew from 2 to 4 bytes.
1228
     *
1229
     * This requires SQLAM Level 7 on both client & server, as sent in the
1230
     * MGRLVLLS in the EXCSATRD.
1231
     *
1232
     * We can cheat a bit because we can tell which one it is by
1233
     * inspection (assuming valid data), so we don't have to check
1234
     * pdu_info->sqlam
1235
     */
1236
1237
0
    sqlstt_length = tvb_get_ntohs(tvb, offset);
1238
0
    if (sqlstt_length == 0) {
1239
0
        sqlstt_length = tvb_get_ntohs(tvb, offset + 2);
1240
0
    }
1241
0
    if (sqlstt_length + 4 == tvb_reported_length(tvb)) {
1242
        /* pdu_info->sqlam < 7 */
1243
0
        offset = dissect_fdoca_vcm(tree, hf_drda_sqlstatement, tvb, offset, pdu_info);
1244
0
        offset = dissect_fdoca_vcs(tree, hf_drda_sqlstatement, tvb, offset, pdu_info);
1245
0
    } else {
1246
0
        offset = dissect_fdoca_nocm(tree, hf_drda_sqlstatement, tvb, offset, pdu_info);
1247
0
        offset = dissect_fdoca_nocs(tree, hf_drda_sqlstatement, tvb, offset, pdu_info);
1248
0
    }
1249
0
    return offset;
1250
0
}
1251
1252
static int
1253
dissect_drda_sqldiaggrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1254
0
{
1255
0
    proto_item *ti;
1256
0
    proto_tree *subtree;
1257
0
    int offset = 0;
1258
1259
0
    uint32_t null_ind;
1260
1261
0
    ti = proto_tree_add_item(tree, hf_drda_sqldiaggrp, tvb, offset, 1, ENC_NA);
1262
0
    subtree = proto_item_add_subtree(ti, ett_drda_sqldiaggrp);
1263
0
    proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1264
0
    offset++;
1265
0
    if ((int8_t)null_ind >= 0) {
1266
0
        proto_tree_add_expert(subtree, pinfo, &ei_drda_undecoded, tvb, offset, 2);
1267
0
    }
1268
0
    proto_item_set_end(ti, tvb, offset);
1269
0
    return offset;
1270
0
}
1271
1272
static const value_string drda_udtxtype_vals[] = {
1273
1274
    { 0, "Not a UDT" },
1275
    { 1, "Distinct type" },
1276
    { 2, "Structured type" },
1277
    { 3, "Reference type" },
1278
    { 0, NULL },
1279
};
1280
1281
static int
1282
dissect_drda_sqludtgrp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
1283
0
{
1284
0
    proto_item *ti;
1285
0
    proto_tree *subtree;
1286
0
    int offset = 0;
1287
1288
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1289
0
    uint32_t null_ind;
1290
1291
0
    ti = proto_tree_add_item(tree, hf_drda_sqludtgrp, tvb, offset, 1, ENC_NA);
1292
0
    subtree = proto_item_add_subtree(ti, ett_drda_sqludtgrp);
1293
0
    proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1294
0
    offset++;
1295
0
    if ((int8_t)null_ind >= 0) {
1296
0
        if (pdu_info->sqlam > 6) {
1297
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqludtxtype, tvb, offset, 4, pdu_info, NULL);
1298
0
            offset = dissect_fdoca_vcs(subtree, hf_drda_rdbnam, tvb, offset, pdu_info);
1299
0
            offset = dissect_fdoca_vcm(subtree, hf_drda_sqludtschema, tvb, offset, pdu_info);
1300
0
            offset = dissect_fdoca_vcs(subtree, hf_drda_sqludtschema, tvb, offset, pdu_info);
1301
0
        }
1302
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqludtname, tvb, offset, pdu_info);
1303
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqludtname, tvb, offset, pdu_info);
1304
0
        if (pdu_info->sqlam >= 10) {
1305
0
            offset = dissect_fdoca_vcm(subtree, hf_drda_sqludtmodule, tvb, offset, pdu_info);
1306
0
            offset = dissect_fdoca_vcs(subtree, hf_drda_sqludtmodule, tvb, offset, pdu_info);
1307
0
        }
1308
0
    }
1309
0
    proto_item_set_end(ti, tvb, offset);
1310
0
    return offset;
1311
0
}
1312
1313
static const value_string drda_keymem_vals[] = {
1314
    { 0, "Not a member of the primary key or of a unique index" },
1315
    { 1, "Member of the primary key or of a unique index" },
1316
    { 0, NULL }
1317
};
1318
1319
static const value_string drda_updateable_vals[] = {
1320
    { 0, "Not updateable" },
1321
    { 1, "Updateable" },
1322
    { 0, NULL }
1323
};
1324
1325
static const value_string drda_generated_vals[] = {
1326
    { 0, "None of the other values of this field apply" },
1327
    { 1, "Data for this column is always generated using an expression" },
1328
    { 2, "Data for this identity column is always generated" },
1329
    { 3, "Data for this ROWID column is always generated" },
1330
    { 4, "Data for this identity column is generated by default" },
1331
    { 5, "Data for this ROWID column is generated by default" },
1332
    { 6, "Data for this row change timestamp column is always generated" },
1333
    { 7, "Data for this row change timestamp column is generated by default" },
1334
    { 0, NULL }
1335
};
1336
1337
static const value_string drda_parmmode_vals[] = {
1338
    { 0, "Not for use with a CALL statement" },
1339
    { 1, "Input-only parameter" },
1340
    { 2, "Input and output parameter" },
1341
    { 4, "Output-only parameter" },
1342
    { 0, NULL }
1343
};
1344
1345
static const value_string drda_xoptlck_vals[] = {
1346
    { 0, "Column not injected because of optimistic locking" },
1347
    { 1, "Row change token column was injected because optimistic locking was requested" },
1348
    { 2, "RID column was injected because optimistic locking was requested" },
1349
    { 0, NULL }
1350
};
1351
1352
static const value_string drda_hidden_vals[] = {
1353
    { 0, "Not a hidden column" },
1354
    { 1, "Hidden column" },
1355
    { 0, NULL }
1356
};
1357
1358
static int
1359
dissect_drda_sqldxgrp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
1360
0
{
1361
0
    proto_item *ti;
1362
0
    proto_tree *subtree;
1363
0
    int offset = 0;
1364
1365
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1366
0
    uint32_t null_ind;
1367
1368
0
    ti = proto_tree_add_item(tree, hf_drda_sqldxgrp, tvb, offset, 1, ENC_NA);
1369
0
    subtree = proto_item_add_subtree(ti, ett_drda_sqldxgrp);
1370
0
    proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1371
0
    offset++;
1372
0
    if ((int8_t)null_ind >= 0) {
1373
0
        offset = dissect_fdoca_integer(subtree, hf_drda_sqlxkeymem, tvb, offset, 2, pdu_info, NULL);
1374
0
        offset = dissect_fdoca_integer(subtree, hf_drda_sqlxupdateable, tvb, offset, 2, pdu_info, NULL);
1375
0
        offset = dissect_fdoca_integer(subtree, hf_drda_sqlxgenerated, tvb, offset, 2, pdu_info, NULL);
1376
0
        offset = dissect_fdoca_integer(subtree, hf_drda_sqlxparmmode, tvb, offset, 2, pdu_info, NULL);
1377
0
        if (pdu_info->sqlam >= 9) {
1378
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqlxoptlck, tvb, offset, 2, pdu_info, NULL);
1379
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqlxhidden, tvb, offset, 2, pdu_info, NULL);
1380
0
        }
1381
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_rdbnam, tvb, offset, pdu_info);
1382
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxcorname, tvb, offset, pdu_info);
1383
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxcorname, tvb, offset, pdu_info);
1384
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxbasename, tvb, offset, pdu_info);
1385
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxbasename, tvb, offset, pdu_info);
1386
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxschema, tvb, offset, pdu_info);
1387
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxschema, tvb, offset, pdu_info);
1388
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxname, tvb, offset, pdu_info);
1389
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxname, tvb, offset, pdu_info);
1390
0
        if (pdu_info->sqlam >= 10) {
1391
0
            offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxmodule, tvb, offset, pdu_info);
1392
0
            offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxmodule, tvb, offset, pdu_info);
1393
0
        }
1394
0
    }
1395
0
    proto_item_set_end(ti, tvb, offset);
1396
0
    return offset;
1397
0
}
1398
1399
/* Appendix D of C112. Note that some strings have multiple codes that
1400
 * map to them.
1401
 */
1402
static const value_string drda_fcode_vals[] = {
1403
1404
    {  1, "ALLOCATE CURSOR" },
1405
    {  2, "ALLOCATE DESCRIPTOR" },
1406
    {  3, "ALTER DOMAIN" },
1407
    {  4, "ALTER TABLE" },
1408
    {  6, "CREATE ASSERTION" },
1409
    {  7, "CALL" },
1410
    {  8, "CREATE CHARACTER SET" },
1411
    {  9, "CLOSE CURSOR" },
1412
    { 11, "CREATE COLLATION" },
1413
    { 12, "COMMIT WORK" },
1414
    { 13, "CONNECT" },
1415
    { 15, "DEALLOCATE DESCRIPTOR" },
1416
    { 16, "DEALLOCATE PREPARE" },
1417
    { 17, "ALTER ROUTINE" },
1418
    { 18, "DELETE CURSOR" },
1419
    { 19, "DELETE WHERE" },
1420
    { 20, "DESCRIBE" },
1421
    { 21, "SELECT" },
1422
    { 22, "DISCONNECT" },
1423
    { 23, "CREATE DOMAIN" },
1424
    { 24, "DROP ASSERTION" },
1425
    { 25, "DROP CHARACTER SET" },
1426
    { 26, "DROP COLLATION" },
1427
    { 27, "DROP DOMAIN" },
1428
    { 29, "DROP ROLE" },
1429
    { 30, "DROP ROUTINE" },
1430
    { 31, "DROP SCHEMA" },
1431
    { 32, "DROP TABLE" },
1432
    { 33, "DROP TRANSLATION" },
1433
    { 34, "DROP TRIGGER" },
1434
    { 35, "DROP TYPE" },
1435
    { 36, "DROP VIEW" },
1436
    { 37, "DYNAMIC CLOSE" },
1437
    { 38, "DYNAMIC DELETE CURSOR" },
1438
    { 39, "DYNAMIC FETCH" },
1439
    { 40, "DYNAMIC OPEN" },
1440
    { 41, "SELECT" },
1441
    { 42, "DYNAMIC UPDATE CURSOR" },
1442
    { 43, "EXECUTE IMMEDIATE" },
1443
    { 44, "EXECUTE" },
1444
    { 45, "FETCH" },
1445
    { 47, "GET DESCRIPTOR" },
1446
    { 48, "GRANT" },
1447
    { 49, "GRANT ROLE" },
1448
    { 50, "INSERT" },
1449
    { 53, "OPEN" },
1450
    { 54, "DYNAMIC DELETE CURSOR" },
1451
    { 55, "DYNAMIC UPDATE CURSOR" },
1452
    { 56, "PREPARE" },
1453
    { 57, "RELEASE SAVEPOINT" },
1454
    { 58, "RETURN" },
1455
    { 59, "REVOKE" },
1456
    { 60, "ALTER TYPE" },
1457
    { 66, "SET CATALOG" },
1458
    { 69, "SET CURRENT_PATH" },
1459
    { 70, "SET DESCRIPTOR" },
1460
    { 72, "SET NAMES" },
1461
    { 74, "SET SCHEMA" },
1462
    { 85, "SELECT CURSOR" },
1463
    { 98, "FREE LOCATOR" },
1464
    { 99, "HOLD LOCATOR" },
1465
    {101, "DECLARE CURSOR" },
1466
    {115, "DROP ORDERING" },
1467
    {116, "DROP TRANSFORM" },
1468
    {118, "SET TRANSFORM GROUP" },
1469
    { 0, NULL }
1470
};
1471
1472
static const value_string drda_hold_vals[] = {
1473
1474
    { 0, "No cursor exists, or cursor defined without WITH HOLD clause" },
1475
    { 1, "Cursor defined using WITH HOLD clause" },
1476
    {-1, "Unknown if cursor was defined using WITH HOLD clause" },
1477
    { 0, NULL }
1478
};
1479
1480
static const value_string drda_return_vals[] = {
1481
1482
    { 0, "Statement is not a query" },
1483
    { 1, "Cursor defined using the WITH RETURN CLIENT clause" },
1484
    { 2, "Cursor defined using the WITH RETURN CALLER clause" },
1485
    {-1, "Unknown if cursor is intended to be used as a result set that will be returned from a procedure" },
1486
    { 0, NULL }
1487
};
1488
1489
static const value_string drda_scroll_vals[] = {
1490
1491
    { 0, "No cursor exists, or not scrollable" },
1492
    { 1, "Cursor defined using SCROLL clause" },
1493
    {-1, "Cursor exists, but scrollability unknown" },
1494
    { 0, NULL }
1495
};
1496
1497
static const value_string drda_sensitive_vals[] = {
1498
1499
    { 0, "No cursor exists" },
1500
    { 1, "Cursor defined as SENSITIVE DYNAMIC" },
1501
    { 2, "Cursor defined as SENSITIVE STATIC" },
1502
    { 3, "Cursor defined as INSENSITIVE" },
1503
    { 4, "Cursor defined with PARTIAL SENSITIVITY and STATIC size and ordering" },
1504
    { 5, "Cursor defined with PARTIAL SENSITIVITY and DYNAMIC size and ordering" },
1505
    {-1, "Cursor exists, but sensitivity unknown" },
1506
    { 0, NULL }
1507
};
1508
1509
static const value_string drda_keytype_vals[] = {
1510
1511
    { 0, "Statement is not a query, or no columns are members of a key" },
1512
    { 1, "Select list includes all columns of the primary key of the base table referenced by the query" },
1513
    { 2, "Table reference by the query does not have a primary key, but the select list includes a set of columns that are defined as the preferred candidate key" },
1514
    { 0, NULL }
1515
};
1516
1517
static const value_string drda_doptlck_vals[] = {
1518
1519
    { 0, "Optimistic locking columns not injected" },
1520
    { 1, "Optimistic locking columns injected, but might not have the granularity to guarantee no false negatives" },
1521
    { 2, "Optimistic locking columns injected, guaranteeing no false negatives" },
1522
    { 0, NULL }
1523
};
1524
1525
static int
1526
dissect_drda_sqldhgrp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
1527
0
{
1528
0
    proto_item *sqldhgrp_ti;
1529
0
    proto_tree *sqldhgrp_tree;
1530
0
    int offset = 0, len;
1531
1532
0
    uint32_t null_ind;
1533
1534
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1535
1536
0
    sqldhgrp_ti = proto_tree_add_item(tree, hf_drda_sqldhgrp, tvb, offset, 1, ENC_NA);
1537
0
    sqldhgrp_tree = proto_item_add_subtree(sqldhgrp_ti, ett_drda_sqldhgrp);
1538
0
    proto_tree_add_item_ret_uint(sqldhgrp_tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1539
0
    offset++;
1540
0
    if ((int8_t)null_ind >= 0) {
1541
0
        len = 2;
1542
0
        offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldhold, tvb, offset, len, pdu_info, NULL);
1543
0
        offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldreturn, tvb, offset, len, pdu_info, NULL);
1544
0
        offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldscroll, tvb, offset, len, pdu_info, NULL);
1545
0
        offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldsensitive, tvb, offset, len, pdu_info, NULL);
1546
0
        offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldfcode, tvb, offset, len, pdu_info, NULL);
1547
0
        offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldkeytype, tvb, offset, len, pdu_info, NULL);
1548
0
        if (pdu_info->sqlam >= 9) {
1549
0
            offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldoptlck, tvb, offset, len, pdu_info, NULL);
1550
0
        }
1551
0
        offset = dissect_fdoca_vcs(sqldhgrp_tree, hf_drda_rdbnam, tvb, offset, pdu_info);
1552
0
        offset = dissect_fdoca_vcm(sqldhgrp_tree, hf_drda_sqldschema, tvb, offset, pdu_info);
1553
0
        offset = dissect_fdoca_vcs(sqldhgrp_tree, hf_drda_sqldschema, tvb, offset, pdu_info);
1554
0
        if (pdu_info->sqlam >= 10) {
1555
0
            offset = dissect_fdoca_vcm(sqldhgrp_tree, hf_drda_sqldmodule, tvb, offset, pdu_info);
1556
0
            offset = dissect_fdoca_vcs(sqldhgrp_tree, hf_drda_sqldmodule, tvb, offset, pdu_info);
1557
0
        }
1558
0
    }
1559
0
    proto_item_set_end(sqldhgrp_ti, tvb, offset);
1560
1561
0
    return offset;
1562
0
}
1563
1564
static const value_string drda_unnamed_vals[] = {
1565
1566
    { 0, "Column name not generated by the RDB" },
1567
    { 1, "Column name generated by the RDB" },
1568
    { 0, NULL }
1569
};
1570
1571
static int
1572
dissect_drda_sqldoptgrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1573
0
{
1574
0
    proto_item *sqldoptgrp_ti, *expert_ti;
1575
0
    proto_tree *subtree;
1576
0
    int offset = 0;
1577
1578
0
    uint32_t null_ind;
1579
1580
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1581
1582
0
    sqldoptgrp_ti = proto_tree_add_item(tree, hf_drda_sqldoptgrp, tvb, offset, 1, ENC_NA);
1583
0
    subtree = proto_item_add_subtree(sqldoptgrp_ti, ett_drda_sqldoptgrp);
1584
0
    proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1585
0
    offset++;
1586
0
    if ((int8_t)null_ind >= 0) {
1587
0
        offset = dissect_fdoca_integer(subtree, hf_drda_sqlunnamed, tvb, offset, 2, pdu_info, NULL);
1588
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqlname, tvb, offset, pdu_info);
1589
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqlname, tvb, offset, pdu_info);
1590
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqllabel, tvb, offset, pdu_info);
1591
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqllabel, tvb, offset, pdu_info);
1592
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqlcomments, tvb, offset, pdu_info);
1593
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqlcomments, tvb, offset, pdu_info);
1594
1595
0
        offset += dissect_drda_sqludtgrp(tvb_new_subset_remaining(tvb, offset), pinfo, subtree, data);
1596
0
        offset += dissect_drda_sqldxgrp(tvb_new_subset_remaining(tvb, offset), pinfo, subtree, data);
1597
0
        if (pdu_info->sqlam >= 10) {
1598
0
            expert_ti = proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1599
0
            offset++;
1600
0
            if ((int8_t)null_ind >= 0) {
1601
0
                expert_add_info(pinfo, expert_ti, &ei_drda_undecoded);
1602
                /* XXX: What is this? It's not in Version 5 of the spec. */
1603
0
            }
1604
0
        }
1605
0
    }
1606
0
    proto_item_set_end(sqldoptgrp_ti, tvb, offset);
1607
0
    return offset;
1608
0
}
1609
1610
static const value_string drda_sqltype_vals[] = {
1611
1612
    { 384, "DATE" },
1613
    { 385, "DATE (NULLABLE)" },
1614
    { 388, "TIME" },
1615
    { 389, "TIME (NULLABLE)" },
1616
    { 392, "TIMESTAMP" },
1617
    { 393, "TIMESTAMP (NULLABLE)" },
1618
    { 396, "DATALINK" },
1619
    { 397, "DATALINK (NULLABLE)" },
1620
    { 404, "BLOB" },
1621
    { 405, "BLOB (NULLABLE)" },
1622
    { 408, "CLOB" },
1623
    { 409, "CLOB (NULLABLE)" },
1624
    { 412, "DBCLOB" },
1625
    { 413, "DBCLOB (NULLABLE)" },
1626
    { 448, "VARCHAR" },
1627
    { 449, "VARCHAR (NULLABLE)" },
1628
    { 452, "CHAR" },
1629
    { 453, "CHAR (NULLABLE)" },
1630
    { 456, "LONG VARCHAR" },
1631
    { 457, "LONG VARCHAR (NULLABLE)" },
1632
    { 460, "NULL-TERMINATED CHAR" },
1633
    { 461, "NULL-TERMINATED CHAR (NULLABLE)" },
1634
    { 464, "VARGRAPHIC" },
1635
    { 465, "VARGRAPHIC (NULLABLE)" },
1636
    { 468, "GRAPHIC" },
1637
    { 469, "GRAPHIC (NULLABLE)" },
1638
    { 472, "LONG VARGRAPHIC" },
1639
    { 473, "LONG VARGRAPHIC (NULLABLE)" },
1640
    { 476, "PASCAL L STRING" },
1641
    { 477, "PASCAL L STRING (NULLABLE)" },
1642
    { 480, "FLOAT" },
1643
    { 481, "FLOAT (NULLABLE)" },
1644
    { 484, "FIXED DECIMAL" },
1645
    { 485, "FIXED DECIMAL (NULLABLE)" },
1646
    { 488, "ZONED DECIMAL" },
1647
    { 489, "ZONED DECIMAL (NULLABLE)" },
1648
    { 492, "BIGINT" },
1649
    { 493, "BIGINT (NULLABLE)" },
1650
    { 496, "INTEGER" },
1651
    { 497, "INTEGER (NULLABLE)" },
1652
    { 500, "SMALLINT" },
1653
    { 501, "SMALLINT (NULLABLE)" },
1654
    { 504, "NUMERIC CHAR" },
1655
    { 505, "NUMERIC CHAR (NULLABLE)" },
1656
    { 904, "ROWID" },
1657
    { 905, "ROWID (NULLABLE)" },
1658
    { 908, "VARBINARY" },
1659
    { 909, "VARBINARY (NULLABLE)" },
1660
    { 912, "BINARY" },
1661
    { 913, "BINARY (NULLABLE)" },
1662
    { 960, "BLOB LOCATOR" },
1663
    { 961, "BLOB LOCATOR (NULLABLE)" },
1664
    { 964, "CLOB LOCATOR" },
1665
    { 965, "CLOB LOCATOR (NULLABLE)" },
1666
    { 968, "DBCLOB LOCATOR" },
1667
    { 969, "DBCLOB LOCATOR (NULLABLE)" },
1668
    { 972, "RESULT SET LOCATOR" },
1669
    { 973, "RESULT SET LOCATOR (NULLABLE)" },
1670
    { 988, "XML" },
1671
    { 989, "XML (NULLABLE)" },
1672
    { 996, "DECFLOAT" },
1673
    { 997, "DECFLOAT (NULLABLE)" },
1674
    {2436, "BOOLEAN" },
1675
    {2437, "BOOLEAN (NULLABLE)" },
1676
    {2444, "CURSOR TYPE" },
1677
    {2445, "CURSOR TYPE (NULLABLE)" },
1678
    {2448, "TIMESTAMP WITH TIME ZONE" },
1679
    {2449, "TIMESTAMP WITH TIME ZONE (NULLABLE)" },
1680
    { 0, NULL }
1681
};
1682
1683
static int
1684
dissect_drda_sqldagrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1685
0
{
1686
0
    proto_item *sqldagrp_ti;
1687
0
    proto_tree *subtree;
1688
0
    int offset = 0;
1689
1690
    //uint32_t null_ind;
1691
1692
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1693
1694
0
    sqldagrp_ti = proto_tree_add_item(tree, hf_drda_sqldagrp, tvb, offset, 1, ENC_NA);
1695
0
    subtree = proto_item_add_subtree(sqldagrp_ti, ett_drda_sqldagrp);
1696
1697
0
    offset = dissect_fdoca_integer(subtree, hf_drda_sqlprecision, tvb, offset, 2, pdu_info, NULL);
1698
0
    offset = dissect_fdoca_integer(subtree, hf_drda_sqlscale, tvb, offset, 2, pdu_info, NULL);
1699
0
    if (pdu_info->sqlam >= 6) {
1700
0
        offset = dissect_fdoca_integer64(subtree, hf_drda_sqllength, tvb, offset, 8, pdu_info, NULL);
1701
0
    } else {
1702
0
        offset = dissect_fdoca_integer(subtree, hf_drda_sqllength32, tvb, offset, 4, pdu_info, NULL);
1703
0
    }
1704
0
    offset = dissect_fdoca_integer(subtree, hf_drda_sqltype, tvb, offset, 2, pdu_info, NULL);
1705
0
    proto_tree_add_item(subtree, hf_drda_ccsid, tvb, offset, 2, ENC_BIG_ENDIAN);
1706
0
    offset += 2;
1707
0
    if (pdu_info->sqlam >= 9) {
1708
0
        offset = dissect_fdoca_integer64(subtree, hf_drda_sqlarrextent, tvb, offset, 8, pdu_info, NULL);
1709
1710
0
        if (pdu_info->sqlam >= 10) {
1711
0
            proto_tree_add_expert(subtree, pinfo, &ei_drda_undecoded, tvb, offset, 2);
1712
            /* XXX: What is this? It's not in Version 5 of the spec. */
1713
0
            offset += 2;
1714
0
        }
1715
0
    }
1716
1717
0
    if (pdu_info->sqlam >= 7) {
1718
0
        offset += dissect_drda_sqldoptgrp(tvb_new_subset_remaining(tvb, offset), pinfo, subtree, data);
1719
0
    } else {
1720
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqlname, tvb, offset, pdu_info);
1721
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqlname, tvb, offset, pdu_info);
1722
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqllabel, tvb, offset, pdu_info);
1723
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqllabel, tvb, offset, pdu_info);
1724
0
        offset = dissect_fdoca_vcm(subtree, hf_drda_sqlcomments, tvb, offset, pdu_info);
1725
0
        offset = dissect_fdoca_vcs(subtree, hf_drda_sqlcomments, tvb, offset, pdu_info);
1726
0
        if (pdu_info->sqlam == 6) {
1727
0
            offset += dissect_drda_sqludtgrp(tvb_new_subset_remaining(tvb, offset), pinfo, subtree, data);
1728
0
        }
1729
0
    }
1730
0
    proto_item_set_end(sqldagrp_ti, tvb, offset);
1731
0
    return offset;
1732
0
}
1733
1734
static int
1735
dissect_drda_sqlcard(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1736
0
{
1737
    /* For a description of these fields (at least on DB2), see:
1738
     *  https://www.ibm.com/docs/en/db2-for-zos/12?topic=sqlca-description-fields
1739
     */
1740
1741
0
    proto_item *ti, *sqlcard_ti;
1742
0
    proto_tree *subtree, *sqlcard_tree;
1743
0
    int offset = 0, len = 4;
1744
1745
0
    uint32_t null_ind, length;
1746
1747
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1748
1749
0
    sqlcard_ti = proto_tree_add_item(tree, hf_drda_sqlcagrp, tvb, offset, 1, ENC_NA);
1750
0
    sqlcard_tree = proto_item_add_subtree(sqlcard_ti, ett_drda_sqlcagrp);
1751
0
    proto_tree_add_item_ret_uint(sqlcard_tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1752
0
    offset++;
1753
0
    if ((int8_t)null_ind >= 0) {
1754
0
        len = 4;
1755
0
        offset = dissect_fdoca_integer(sqlcard_tree, hf_drda_sqlcode, tvb, offset, len, pdu_info, NULL);
1756
0
        len = 5;
1757
0
        offset = dissect_fdoca_fcs(sqlcard_tree, hf_drda_sqlstate, tvb, offset, len, pdu_info);
1758
0
        len = 8;
1759
0
        offset = dissect_fdoca_fcs(sqlcard_tree, hf_drda_sqlerrproc, tvb, offset, len, pdu_info);
1760
1761
        /* SQLCAXGRP (nullable) */
1762
0
        proto_tree_add_item_ret_uint(sqlcard_tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
1763
0
        offset++;
1764
0
        if ((int8_t)null_ind >= 0) {
1765
0
            ti = proto_tree_add_item(sqlcard_tree, hf_drda_sqlcaxgrp, tvb, offset, 35, ENC_NA);
1766
0
            subtree = proto_item_add_subtree(ti, ett_drda_sqlcaxgrp);
1767
            /* Earlier than SQLAM Level 7, the RDBName follows here, and is
1768
             * a fixed string field of length 18. At SQLAM Level 7 and
1769
             * higher, the SQLRDBNAME is a variable character field and
1770
             * comes later, after the SQLWARN fields.
1771
             */
1772
0
            if (pdu_info->sqlam < 7) {
1773
0
                offset = dissect_fdoca_fcs(subtree, hf_drda_rdbnam, tvb, offset, 18, pdu_info);
1774
0
            }
1775
0
            len = 4;
1776
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd1, tvb, offset, len, pdu_info, NULL);
1777
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd2, tvb, offset, len, pdu_info, NULL);
1778
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd3, tvb, offset, len, pdu_info, NULL);
1779
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd4, tvb, offset, len, pdu_info, NULL);
1780
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd5, tvb, offset, len, pdu_info, NULL);
1781
0
            offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd6, tvb, offset, len, pdu_info, NULL);
1782
0
            len = 1;
1783
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn0, tvb, offset, len, pdu_info);
1784
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn1, tvb, offset, len, pdu_info);
1785
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn2, tvb, offset, len, pdu_info);
1786
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn3, tvb, offset, len, pdu_info);
1787
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn4, tvb, offset, len, pdu_info);
1788
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn5, tvb, offset, len, pdu_info);
1789
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn6, tvb, offset, len, pdu_info);
1790
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn7, tvb, offset, len, pdu_info);
1791
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn8, tvb, offset, len, pdu_info);
1792
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn9, tvb, offset, len, pdu_info);
1793
0
            offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarna, tvb, offset, len, pdu_info);
1794
0
            if (pdu_info->sqlam >= 7) {
1795
0
                offset = dissect_fdoca_vcs(subtree, hf_drda_rdbnam, tvb, offset, pdu_info);
1796
0
            }
1797
            /* SQLERRMSG_m, a variable character string using the mixed
1798
             * character CCSID. On DB2, contains one or more tokens,
1799
             * separated by X'FF', that are substituted for variables
1800
             * in the descriptions of error conditions.
1801
             */
1802
0
            proto_tree_add_item_ret_uint(subtree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
1803
0
            offset += 2;
1804
0
            int end_offset;
1805
0
            while ((end_offset = tvb_find_uint8(tvb, offset, length, 0xFF)) != -1) {
1806
0
                proto_tree_add_item(subtree, hf_drda_sqlerrmsg, tvb, offset, end_offset - offset, pdu_info->mbc);
1807
0
                length -= (end_offset + 1 - offset);
1808
0
                offset = end_offset + 1;
1809
0
            }
1810
0
            proto_tree_add_item(subtree, hf_drda_sqlerrmsg, tvb, offset, length, pdu_info->mbc);
1811
0
            offset += length;
1812
1813
            /* SQLERRMSG_s - same but using the single byte CCSID. Only one
1814
             * of these should have nonzero length.
1815
             */
1816
0
            proto_tree_add_item_ret_uint(subtree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
1817
0
            offset += 2;
1818
0
            while ((end_offset = tvb_find_uint8(tvb, offset, length, 0xFF)) != -1) {
1819
0
                proto_tree_add_item(subtree, hf_drda_sqlerrmsg, tvb, offset, end_offset - offset, pdu_info->sbc);
1820
0
                length -= (end_offset + 1 - offset);
1821
0
                offset = end_offset + 1;
1822
0
            }
1823
0
            proto_tree_add_item(subtree, hf_drda_sqlerrmsg, tvb, offset, length, pdu_info->sbc);
1824
0
            offset += length;
1825
0
            proto_item_set_end(ti, tvb, offset);
1826
0
        }
1827
1828
0
        if (pdu_info->sqlam >= 7) {
1829
0
            offset += dissect_drda_sqldiaggrp(tvb_new_subset_remaining(tvb, offset), pinfo, sqlcard_tree, data);
1830
0
        }
1831
0
    } else {
1832
        /* DRDA, Version 4, Volume 1: 5.6.4.6 SQLCAGRP:
1833
         * "A null SQLCA indicates everything is fine: SQLSTATE='00000'"
1834
         */
1835
0
        ti = proto_tree_add_int(sqlcard_tree, hf_drda_sqlcode, tvb, offset, 0, 0);
1836
0
        proto_item_set_generated(ti);
1837
0
        ti = proto_tree_add_string(sqlcard_tree, hf_drda_sqlstate, tvb, offset, 0, "00000");
1838
0
        proto_item_set_generated(ti);
1839
0
    }
1840
0
    proto_item_set_end(sqlcard_ti, tvb, offset);
1841
1842
0
    return offset;
1843
0
}
1844
1845
static int
1846
dissect_drda_sqldard(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
1847
0
{
1848
0
    int offset = 0;
1849
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
1850
1851
0
    int32_t numrows;
1852
1853
0
    offset = dissect_drda_sqlcard(tvb, pinfo, tree, data);
1854
1855
0
    if (pdu_info->sqlam >= 7) {
1856
0
        offset += dissect_drda_sqldhgrp(tvb_new_subset_remaining(tvb, offset), pinfo, tree, data);
1857
0
    }
1858
0
    offset = dissect_fdoca_integer(tree, hf_drda_sqlnum, tvb, offset, 2, pdu_info, &numrows);
1859
0
    for (int32_t i = 0; i < numrows; ++i) {
1860
0
        offset += dissect_drda_sqldagrp(tvb_new_subset_remaining(tvb, offset), pinfo, tree, data);
1861
0
    }
1862
0
    return offset;
1863
0
}
1864
1865
static int
1866
dissect_drda_undecoded(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1867
0
{
1868
0
    proto_tree_add_expert(tree, pinfo, &ei_drda_undecoded, tvb, 0, -1);
1869
0
    return tvb_captured_length(tvb);
1870
0
}
1871
1872
static const value_string drda_rlsconv_vals[] = {
1873
    { 0xF0, "NO" }, /* EBCDIC '0' */
1874
    { 0xF1, "TERMINATE" },  /* EBCDIC '1' */
1875
    { 0xF2, "REUSE" },  /* EBCDIC '2' */
1876
    { 0xF3, "NO_KDO - Presence of keep dynamic sections" },  /* EBCDIC '3' */
1877
    { 0, NULL }
1878
};
1879
1880
static int
1881
dissect_drda_rlsconv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1882
0
{
1883
0
    proto_tree_add_item(tree, hf_drda_rlsconv, tvb, 0, 1, ENC_NA);
1884
0
    return 1;
1885
0
}
1886
1887
static const value_string drda_secmec_vals[] = {
1888
    { 1, "DCESEC - Distributed Computing Environment" },
1889
    { 3, "USRIDPWD - User ID and Password" },
1890
    { 4, "UDRIDONL - User ID Only" },
1891
    { 5, "USRIDNWPWD - User ID, Password, and New Password" },
1892
    { 6, "USRSBSPWD - User ID with Substitute Password" },
1893
    { 7, "USRENCPWD - User ID with Encrypted Password" },
1894
    { 8, "USRSSBPWD - User ID with Strong Password Substitute" },
1895
    { 9, "EUSRIDPWD - Encrypted User ID and Password" },
1896
    {10, "EUSRIDNWPWD - Encrypted User ID, Password, New Password" },
1897
    {11, "KERSEC - Kerberos Security" },
1898
    {12, "EUSRIDDTA - Encrypted User ID and Security-Sensitive Data" },
1899
    {13, "EUSRPWDDTA - Encrypted User ID, Password, and Security-Sensitive Data" },
1900
    {14, "EUSRNPWDDTA - Encrypted User ID, Password, New Password, and Security-Sensitive Data" },
1901
    {15, "PLGIN - Plug-in Security" },
1902
    {16, "EUSRIDONL - Encrypted User ID Only" },
1903
    { 0, NULL }
1904
};
1905
1906
static int
1907
dissect_drda_secmec(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1908
0
{
1909
    /* REPEATABLE */
1910
0
    int offset = 0;
1911
0
    while (tvb_reported_length_remaining(tvb, offset) >= 2) {
1912
0
        proto_tree_add_item(tree, hf_drda_secmec, tvb, offset, 2, ENC_BIG_ENDIAN);
1913
0
        offset += 2;
1914
0
    }
1915
0
    return offset;
1916
0
}
1917
1918
static const value_string drda_svrcod_vals[] = {
1919
    {  0, "INFO - Information Only" },
1920
    {  4, "WARNING - Warning" },
1921
    {  8, "ERROR - Error" },
1922
    { 16, "SEVERE - Severe Error" },
1923
    { 32, "ACCDMG - Access Damage" },
1924
    { 64, "PRMDMG - Permanent Damage" },
1925
    {128, "SESDMG - Session Damage" },
1926
    { 0, NULL }
1927
};
1928
1929
static int
1930
dissect_drda_sectkn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1931
0
{
1932
0
    proto_tree_add_item(tree, hf_drda_sectkn, tvb, 0, tvb_reported_length(tvb), ENC_NA);
1933
0
    return tvb_reported_length(tvb);
1934
0
}
1935
1936
static int
1937
dissect_drda_svrcod(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1938
0
{
1939
0
    proto_tree_add_item(tree, hf_drda_svrcod, tvb, 0, 2, ENC_BIG_ENDIAN);
1940
0
    return 2;
1941
0
}
1942
1943
static const value_string drda_secchkcd_vals[] = {
1944
    {0x00, "The security information is correct and acceptable." },
1945
    {0x01, "SECMEC value not supported." },
1946
    {0x02, "DCE information status issued." },
1947
    {0x03, "DCE retryable error." },
1948
    {0x04, "DCE non-retryable error." },
1949
    {0x05, "GSSAPI informational status issued." },
1950
    {0x06, "GSSAPI retryable error." },
1951
    {0x07, "GSSAPI non-retryable error." },
1952
    {0x08, "Local Security Service informational status issued." },
1953
    {0x09, "Local Security Service retryable error." },
1954
    {0x0A, "Local Security Service non-retryable error." },
1955
    {0x0B, "SECTKN missing when it is required or it is invalid." },
1956
    {0x0E, "Password expired." },
1957
    {0x0F, "Password invalid." },
1958
    {0x10, "Password missing." },
1959
    {0x12, "User ID missing." },
1960
    {0x13, "User ID invalid." },
1961
    {0x14, "User ID revoked." },
1962
    {0x15, "New Password invalid." },
1963
    {0x16, "Authentication failed because of connectivity restrictions enforced by the security plug-in." },
1964
    {0x17, "Invalid GSS-API server credential." },
1965
    {0x18, "GSS-API server credential expired on the database server." },
1966
    {0x19, "Continue - require more security context information for authentication." },
1967
    { 0, NULL }
1968
};
1969
1970
static int
1971
dissect_drda_secchkcd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1972
0
{
1973
0
    proto_tree_add_item(tree, hf_drda_secchkcd, tvb, 0, 1, ENC_BIG_ENDIAN);
1974
0
    return 1;
1975
0
}
1976
1977
/* A few common CCSIDs, many more are at:
1978
 * https://www.ibm.com/docs/en/i/7.3?topic=information-ccsid-values-defined-i
1979
 * https://web.archive.org/web/20160304082631/http://www-01.ibm.com/software/globalization/g11n-res.html
1980
 */
1981
static const value_string drda_ccsid_vals[] = {
1982
    {    0, "Use default value" },
1983
    {   37, "IBM037" }, /* EBCDIC US Latin-1 */
1984
    {  367, "US-ASCII" },
1985
    {  500, "IBM500" }, /* EBCDIC International Latin-1 */
1986
    {  819, "ISO-8859-1" },
1987
    {  850, "IBM850" }, /* DOS Latin-1 */
1988
    { 1200, "UTF-16" }, /* UTF-16BE; UTF-16LE is 1202 */
1989
    { 1202, "UTF-16LE" },
1990
    { 1208, "UTF-8" },
1991
    { 65535, "Requested CCSID unsupported" },
1992
    { 0, NULL }
1993
};
1994
1995
static unsigned
1996
ccsid_to_encoding(uint32_t ccsid)
1997
0
{
1998
0
    switch (ccsid) {
1999
2000
0
    case 0:
2001
0
    case 500:
2002
0
    case 65535:
2003
0
        return ENC_EBCDIC_CP500;
2004
0
    case 37:
2005
0
        return ENC_EBCDIC_CP037;
2006
0
    case 367:
2007
0
        return ENC_ASCII;
2008
0
    case 819:
2009
0
        return ENC_ISO_8859_1;
2010
0
    case 850:
2011
0
        return ENC_ASCII; /* XXX: CP 850 not yet supported; CP 437 is closer, but ASCII safer */
2012
0
    case 1200:
2013
0
        return ENC_UTF_16|ENC_BIG_ENDIAN;
2014
0
    case 1202:
2015
0
        return ENC_UTF_16|ENC_LITTLE_ENDIAN;
2016
0
    case 1208:
2017
0
        return ENC_UTF_8;
2018
0
    default:
2019
0
        return ENC_UTF_8;
2020
0
    }
2021
0
}
2022
2023
static int
2024
dissect_drda_ccsid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
2025
0
{
2026
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
2027
0
    uint32_t ccsid;
2028
2029
0
    proto_tree_add_item_ret_uint(tree, hf_drda_ccsid, tvb, 0, 2, ENC_BIG_ENDIAN, &ccsid);
2030
0
    switch (pinfo->match_uint) {
2031
0
    case DRDA_CP_CCSIDSBC:
2032
0
        pdu_info->sbc = ccsid_to_encoding(ccsid);
2033
0
        break;
2034
0
    case DRDA_CP_CCSIDMBC:
2035
0
        pdu_info->mbc = ccsid_to_encoding(ccsid);
2036
0
        break;
2037
0
    default:
2038
0
        break;
2039
0
    }
2040
0
    return 2;
2041
0
}
2042
2043
static int
2044
dissect_drda_monitor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2045
0
{
2046
0
    static int * const monitor_fields[] = {
2047
0
        &hf_drda_monitor_etime,
2048
0
        &hf_drda_monitor_reserved,
2049
0
        NULL
2050
0
    };
2051
2052
0
    proto_tree_add_bitmask(tree, tvb, 0, hf_drda_monitor, ett_drda_monitor,
2053
0
        monitor_fields, ENC_BIG_ENDIAN);
2054
0
    return 4;
2055
0
}
2056
2057
static int
2058
dissect_drda_etime(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2059
0
{
2060
0
    proto_tree_add_item(tree, hf_drda_etime, tvb, 0, 8, ENC_TIME_USECS|ENC_BIG_ENDIAN);
2061
0
    return 8;
2062
0
}
2063
2064
static int
2065
dissect_drda_respktsz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2066
0
{
2067
0
    proto_tree_add_item(tree, hf_drda_respktsz, tvb, 0, 4, ENC_BIG_ENDIAN);
2068
0
    return 4;
2069
0
}
2070
2071
static int
2072
dissect_drda_rdbinttkn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2073
0
{
2074
    /* The contents of the token are unarchitected and can differe for each
2075
     * target SQLAM.
2076
     */
2077
0
    proto_tree_add_item(tree, hf_drda_rdbinttkn, tvb, 0, tvb_reported_length(tvb), ENC_NA);
2078
0
    return tvb_reported_length(tvb);
2079
0
}
2080
2081
static int
2082
dissect_drda_rdbcmtok(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2083
0
{
2084
0
    proto_tree_add_item(tree, hf_drda_rdbcmtok, tvb, 0, 1, ENC_NA);
2085
0
    return 1;
2086
0
}
2087
2088
static int
2089
dissect_drda_pkgnam(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2090
0
{
2091
0
    proto_item *ti_length;
2092
0
    int offset = 0;
2093
0
    uint32_t length;
2094
2095
    /* The PKGNAMCSN can have one of the following two formats depending on the
2096
     * length of the RDBNAM, RDBCOLID, and PKGID contained therein:
2097
     * * RDBNAM, RDBCOLID, and PKGID all have a length of 18.
2098
     *   [Possibly right padded with blank spaces.]
2099
     *   This format of the PKGNAMCSN is identical to the sole format used prior
2100
     *   to DDM Level 7 where the length is fixed at 58. The use of the SCLDTALEN
2101
     *   is disallowed with this format.
2102
     * * At least one of RDBNAM, RDBCOLID, and PKGID has a length > 18.
2103
     *   This format of the PKGNAMCSN mandates the SCLDTALEN to precede each of
2104
     *   the RDBNAM, RDBCOLID, and PKGID. With this format, the PKGNAMCSN has a
2105
     *   minimum length of 65 and a maximum length of 775.
2106
     */
2107
0
    if (tvb_reported_length(tvb) == 54) {
2108
        /* 58 - 4 bytes for the code point and length already removed. */
2109
0
        proto_tree_add_item(tree, hf_drda_rdbnam, tvb, offset, 18, ENC_UTF_8);
2110
0
        proto_tree_add_item(tree, hf_drda_rdbnam_ebcdic, tvb, offset, 18, ENC_EBCDIC_CP500);
2111
0
        offset += 18;
2112
0
        proto_tree_add_item(tree, hf_drda_rdbcolid, tvb, offset, 18, ENC_UTF_8);
2113
0
        proto_tree_add_item(tree, hf_drda_rdbcolid_ebcdic, tvb, offset, 18, ENC_EBCDIC_CP500);
2114
0
        offset += 18;
2115
0
        proto_tree_add_item(tree, hf_drda_pkgid, tvb, offset, 18, ENC_UTF_8);
2116
0
        proto_tree_add_item(tree, hf_drda_pkgid_ebcdic, tvb, offset, 18, ENC_EBCDIC_CP500);
2117
0
        offset += 18;
2118
0
    } else if (tvb_reported_length(tvb) > 64) {
2119
0
        ti_length = proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
2120
0
        if (length < 18 || length > 255) {
2121
0
            expert_add_info_format(pinfo, ti_length, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be 18-255 bytes long", length);
2122
0
        }
2123
0
        offset += 2;
2124
0
        proto_tree_add_item(tree, hf_drda_rdbnam, tvb, offset, length, ENC_UTF_8);
2125
0
        proto_tree_add_item(tree, hf_drda_rdbnam_ebcdic, tvb, offset, length, ENC_EBCDIC_CP500);
2126
0
        offset += length;
2127
0
        ti_length = proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
2128
0
        if (length < 18 || length > 255) {
2129
0
            expert_add_info_format(pinfo, ti_length, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be 18-255 bytes long", length);
2130
0
        }
2131
0
        offset += 2;
2132
0
        proto_tree_add_item(tree, hf_drda_rdbcolid, tvb, offset, length, ENC_UTF_8);
2133
0
        proto_tree_add_item(tree, hf_drda_rdbcolid_ebcdic, tvb, offset, length, ENC_EBCDIC_CP500);
2134
0
        offset += length;
2135
0
        ti_length = proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
2136
0
        if (length < 18 || length > 255) {
2137
0
            expert_add_info_format(pinfo, ti_length, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be 18-255 bytes long", length);
2138
0
        }
2139
0
        offset += 2;
2140
0
        proto_tree_add_item(tree, hf_drda_pkgid, tvb, offset, length, ENC_UTF_8);
2141
0
        proto_tree_add_item(tree, hf_drda_pkgid_ebcdic, tvb, offset, length, ENC_EBCDIC_CP500);
2142
0
        offset += length;
2143
0
    } else {
2144
0
        proto_tree_add_expert_format(tree, pinfo, &ei_drda_opcode_invalid_length, tvb, 0, tvb_reported_length(tvb), "Invalid length; RDBNAM, RDBCOLID, and PKGID should all be length 18 or larger.");
2145
0
    }
2146
2147
0
    return offset;
2148
0
}
2149
2150
static int
2151
dissect_drda_rtnsetstt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2152
0
{
2153
0
    proto_tree_add_item(tree, hf_drda_rtnsetstt, tvb, 0, 1, ENC_NA);
2154
0
    return 1;
2155
0
}
2156
2157
static int
2158
dissect_drda_outexp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2159
0
{
2160
0
    proto_tree_add_item(tree, hf_drda_outexp, tvb, 0, 1, ENC_NA);
2161
0
    return 1;
2162
0
}
2163
2164
static int
2165
dissect_drda_pkgnamct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2166
0
{
2167
0
    int offset;
2168
2169
0
    offset = dissect_drda_pkgnam(tvb_new_subset_length(tvb, 0, tvb_reported_length_remaining(tvb, 8)), pinfo, tree, data);
2170
2171
0
    proto_tree_add_item(tree, hf_drda_pkgcnstkn, tvb, offset, 8, ENC_NA);
2172
0
    offset += 8;
2173
2174
0
    return offset;
2175
0
}
2176
2177
static int
2178
dissect_drda_pkgnamcsn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2179
0
{
2180
0
    int offset;
2181
2182
0
    offset = dissect_drda_pkgnamct(tvb_new_subset_length(tvb, 0, tvb_reported_length_remaining(tvb, 2)), pinfo, tree, data);
2183
2184
0
    proto_tree_add_item(tree, hf_drda_pkgsn, tvb, offset, 2, ENC_BIG_ENDIAN);
2185
0
    offset += 2;
2186
2187
0
    return offset;
2188
0
}
2189
2190
static int
2191
dissect_drda_qryblksz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2192
0
{
2193
0
    proto_tree_add_item(tree, hf_drda_qryblksz, tvb, 0, 4, ENC_BIG_ENDIAN);
2194
0
    return 4;
2195
0
}
2196
2197
static const value_string drda_uowdsp_vals[] =
2198
{
2199
    { 1, "Committed"},
2200
    { 2, "Rolled back"},
2201
    { 0, NULL }
2202
};
2203
2204
static int
2205
dissect_drda_uowdsp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2206
0
{
2207
0
    proto_tree_add_item(tree, hf_drda_uowdsp, tvb, 0, 1, ENC_NA);
2208
0
    return 1;
2209
0
}
2210
2211
static int
2212
dissect_drda_rdbalwupd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2213
0
{
2214
0
    proto_tree_add_item(tree, hf_drda_rdbalwupd, tvb, 0, 1, ENC_NA);
2215
0
    return 1;
2216
0
}
2217
2218
static int
2219
dissect_drda_sqlcsrhld(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2220
0
{
2221
0
    proto_tree_add_item(tree, hf_drda_sqlcsrhld, tvb, 0, 1, ENC_NA);
2222
0
    return 1;
2223
0
}
2224
2225
static const val64_string drda_qryextdtasz_vals[] =
2226
{
2227
    { -1, "Not limited by this parameter"},
2228
    {  0, NULL }
2229
};
2230
2231
static int
2232
dissect_drda_qryextdtasz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2233
0
{
2234
0
    proto_tree_add_item(tree, hf_drda_qryextdtasz, tvb, 0, 8, ENC_BIG_ENDIAN);
2235
0
    return 8;
2236
0
}
2237
2238
static int
2239
dissect_drda_smldtasz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2240
0
{
2241
0
    proto_tree_add_item(tree, hf_drda_smldtasz, tvb, 0, 8, ENC_BIG_ENDIAN);
2242
0
    return 8;
2243
0
}
2244
2245
static int
2246
dissect_drda_meddtasz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2247
0
{
2248
0
    proto_tree_add_item(tree, hf_drda_meddtasz, tvb, 0, 8, ENC_BIG_ENDIAN);
2249
0
    return 8;
2250
0
}
2251
2252
static int
2253
dissect_drda_trgdftrt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2254
0
{
2255
0
    proto_tree_add_item(tree, hf_drda_trgdftrt, tvb, 0, 1, ENC_BIG_ENDIAN);
2256
0
    return 1;
2257
0
}
2258
2259
static int
2260
dissect_drda_rtnsqlda(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2261
0
{
2262
0
    proto_tree_add_item(tree, hf_drda_rtnsqlda, tvb, 0, 1, ENC_BIG_ENDIAN);
2263
0
    return 1;
2264
0
}
2265
2266
static const value_string drda_qryattupd_vals[] = {
2267
    { 0, "QRYUNK - Unknown or undefined for this cursor" },
2268
    { 1, "QRYRDO - The cursor is read-only" },
2269
    { 2, "QRYDEL - The cursor allows read and delete" },
2270
    { 4, "QRYUPD - The cursor allows read, delete, and update" },
2271
    { 0, NULL }
2272
};
2273
2274
static int
2275
dissect_drda_qryattupd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2276
0
{
2277
0
    proto_tree_add_item(tree, hf_drda_qryattupd, tvb, 0, 1, ENC_BIG_ENDIAN);
2278
0
    return 1;
2279
0
}
2280
2281
static int
2282
dissect_drda_qryrowset(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2283
0
{
2284
0
    proto_tree_add_item(tree, hf_drda_qryrowset, tvb, 0, 4, ENC_BIG_ENDIAN);
2285
0
    return 4;
2286
0
}
2287
2288
static int
2289
dissect_drda_qryinsid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2290
0
{
2291
    /* Query Instance Identifier (QRYINSID) uniquely identifies the instance of
2292
     * a query. Its contents are implementation-specific and are unarchitected
2293
     * by DDM.
2294
     */
2295
0
    proto_tree_add_item(tree, hf_drda_qryinsid, tvb, 0, tvb_reported_length(tvb), ENC_NA);
2296
0
    return tvb_reported_length(tvb);
2297
0
}
2298
2299
static const value_string drda_qryclsimp_vals[] = {
2300
    { 0, "Target server determines whether to implicitly close the cursor or not upon SQLSTATE 02000 based on the cursor type" },
2301
    { 1, "Target server must implicitly close the cursor upon SQLSTATE 02000" },
2302
    { 2, "Target server must not implicitly close the cursor upon SQLSTATE 02000" },
2303
    { 0, NULL }
2304
};
2305
2306
static int
2307
dissect_drda_qryclsimp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2308
0
{
2309
0
    proto_tree_add_item(tree, hf_drda_qryclsimp, tvb, 0, 1, ENC_BIG_ENDIAN);
2310
0
    return 1;
2311
0
}
2312
2313
static int
2314
dissect_drda_qryblkfct(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2315
0
{
2316
0
    proto_tree_add_item(tree, hf_drda_qryblkfct, tvb, 0, 4, ENC_BIG_ENDIAN);
2317
0
    return 4;
2318
0
}
2319
2320
static int
2321
dissect_drda_maxrslcnt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2322
0
{
2323
0
    proto_tree_add_item(tree, hf_drda_maxrslcnt, tvb, 0, 2, ENC_BIG_ENDIAN);
2324
0
    return 2;
2325
0
}
2326
2327
static int
2328
dissect_drda_maxblkext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2329
0
{
2330
0
    proto_tree_add_item(tree, hf_drda_maxblkext, tvb, 0, 2, ENC_BIG_ENDIAN);
2331
0
    return 2;
2332
0
}
2333
2334
static const value_string drda_rslsetflg_extended_vals[] =
2335
{
2336
    { 0, "Standard SQLDA" },
2337
    { 1, "Extended SQLDA" },
2338
    { 2, "Light SQLDA" },
2339
    { 0, NULL }
2340
};
2341
2342
static int
2343
dissect_drda_rslsetflg(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2344
0
{
2345
0
    static int * const rslsetflg_fields[] = {
2346
0
        &hf_drda_rslsetflg_unused,
2347
0
        &hf_drda_rslsetflg_dsconly,
2348
0
        &hf_drda_rslsetflg_extended,
2349
0
        &hf_drda_rslsetflg_reserved,
2350
0
        NULL
2351
0
    };
2352
2353
0
    proto_tree_add_bitmask(tree, tvb, 0, hf_drda_rslsetflg, ett_drda_rslsetflg,
2354
0
        rslsetflg_fields, ENC_BIG_ENDIAN);
2355
0
    return 4;
2356
0
}
2357
2358
static const value_string drda_typsqlda_vals[] = {
2359
    { 0, "Standard output SQLDA" },
2360
    { 1, "Standard input SQLDA" },
2361
    { 2, "Light output SQLDA" },
2362
    { 3, "Light input SQLDA" },
2363
    { 4, "Extended output SQLDA" },
2364
    { 5, "Extended input SQLDA" },
2365
    { 0, NULL }
2366
};
2367
2368
static int
2369
dissect_drda_typsqlda(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2370
0
{
2371
0
    proto_tree_add_item(tree, hf_drda_typsqlda, tvb, 0, 1, ENC_BIG_ENDIAN);
2372
0
    return 1;
2373
0
}
2374
2375
static const value_string drda_outovropt_vals[] = {
2376
    { 1, "OUTOVRFRS - Output Override Allowed on First CNTQRY" },
2377
    { 2, "OUTOVRANY - Output Override Allowed on Any CNTQRY" },
2378
    { 3, "OUTOVRNON - Output Override Not Allowed, and MINLVL is 8" },
2379
    { 0, NULL }
2380
};
2381
2382
static int
2383
dissect_drda_outovropt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2384
0
{
2385
0
    proto_tree_add_item(tree, hf_drda_outovropt, tvb, 0, 1, ENC_BIG_ENDIAN);
2386
0
    return 1;
2387
0
}
2388
2389
static int
2390
dissect_drda_dyndtafmt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2391
0
{
2392
0
    proto_tree_add_item(tree, hf_drda_dyndtafmt, tvb, 0, 1, ENC_BIG_ENDIAN);
2393
0
    return 1;
2394
0
}
2395
2396
static int
2397
dissect_drda_pktobj(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2398
0
{
2399
0
    proto_tree_add_item(tree, hf_drda_pktobj, tvb, 0, tvb_reported_length(tvb), ENC_NA);
2400
0
    return tvb_reported_length(tvb);
2401
0
}
2402
2403
static int
2404
dissect_drda_mgrlvlls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2405
0
{
2406
0
    proto_tree *drda_tree_sub;
2407
0
    proto_item *ti;
2408
2409
0
    drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
2410
2411
0
    int offset = 0;
2412
0
    uint32_t mgrlvln;
2413
0
    uint16_t iParameterCP;
2414
0
    int iLengthParam = 4;
2415
2416
0
    while (tvb_reported_length_remaining(tvb, offset) >= 2)
2417
0
    {
2418
0
        iParameterCP = tvb_get_ntohs(tvb, offset);
2419
0
        drda_tree_sub = proto_tree_add_subtree(tree, tvb, offset, iLengthParam,
2420
0
                        ett_drda_param, &ti, DRDA_TEXT_PARAM);
2421
0
        proto_item_append_text(ti, " (%s)", val_to_str_ext(pinfo->pool, iParameterCP, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
2422
0
        proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset, 2, ENC_BIG_ENDIAN);
2423
0
        switch (iParameterCP) {
2424
2425
0
        case DRDA_CP_CCSIDMGR:
2426
0
        case DRDA_CP_UNICODEMGR:
2427
            /* The default CCSID for DRDA is 500 (EBCDIC Latin-1).
2428
             * These two code points are used to propose (in an EXCSAT
2429
             * command's MGRLVLLS parameter) and accept (in an EXCSATRD
2430
             * command's MGRLVLLS parameter) a CSSID to be used for all
2431
             * character data for DDM parameters. (*Not*, note, for the
2432
             * FD:OCA (SQL statements and the like), which are governed
2433
             * by TYPDEFNAM and TYPDEFOVR as contained in ACCRDB and ACCRDBRM
2434
             * - note that they can be different in the two directions.)
2435
             *
2436
             * A 0 reply in an EXCSATRD means rejection of the request, and
2437
             * EBCDIC code page 500 (Latin-1) must be used. A 0xFFFF reply
2438
             * in an EXCSATRD means "I do support CCSIDMGR, but not the code
2439
             * page you requested, try again."
2440
             *
2441
             * UNICODEMGR and CCSIDMGR are mutually exclusive.
2442
             * UNICODEMGR should only use 1208 (UTF-8) or 0. CCSIDMGR must
2443
             * support 500 (EBCDIC Latin-1), 819 (ISO 8859-1), and 850
2444
             * (IBM PC-DOS ASCII Latin-1), and can support others.
2445
             * If the server replies with a 0 to UNICODEMGR, the client can
2446
             * try again with a CCSIDMGR.
2447
             */
2448
0
            proto_tree_add_item(drda_tree_sub, hf_drda_ccsid, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2449
0
            break;
2450
2451
0
        case DRDA_CP_SQLAM:
2452
0
            proto_tree_add_item_ret_uint(drda_tree_sub, hf_drda_mgrlvln, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &mgrlvln);
2453
0
            pdu_info->sqlam = mgrlvln;
2454
0
            break;
2455
2456
0
        default:
2457
0
            proto_tree_add_item(drda_tree_sub, hf_drda_mgrlvln, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2458
0
        }
2459
0
        offset += iLengthParam;
2460
0
    }
2461
2462
0
    return tvb_captured_length(tvb);
2463
0
}
2464
2465
static int
2466
dissect_drda_collection(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2467
0
{
2468
0
    proto_tree *drda_tree_sub;
2469
0
    proto_item *ti;
2470
0
    int offset = 0;
2471
2472
0
    uint16_t iParameterCP;
2473
0
    int iLengthParam;
2474
2475
    /* All objects in DDM are modeled as either scalars or collections.
2476
     * A collection has the length before each element.
2477
     * There are also lists of repeatable scalars, which don't have
2478
     * the length.
2479
     */
2480
2481
0
    while (tvb_reported_length_remaining(tvb, offset) >= 2)
2482
0
    {
2483
0
        iLengthParam = tvb_get_ntohs(tvb, offset + 0);
2484
0
        if (tvb_reported_length_remaining(tvb, offset) >= iLengthParam)
2485
0
        {
2486
0
            iParameterCP = tvb_get_ntohs(tvb, offset + 2);
2487
0
            drda_tree_sub = proto_tree_add_subtree(tree, tvb, offset, iLengthParam,
2488
0
                            ett_drda_param, &ti, DRDA_TEXT_PARAM);
2489
0
            proto_item_append_text(ti, " (%s)", val_to_str_ext(pinfo->pool, iParameterCP, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
2490
0
            proto_tree_add_item(drda_tree_sub, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN);
2491
0
            proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2492
0
            if (!dissector_try_uint_with_data(drda_opcode_table, iParameterCP, tvb_new_subset_length(tvb, offset + 4, iLengthParam - 4), pinfo, drda_tree_sub, false, data)) {
2493
0
                proto_tree_add_item(drda_tree_sub, hf_drda_param_data, tvb, offset + 4, iLengthParam - 4, ENC_UTF_8);
2494
0
                proto_tree_add_item(drda_tree_sub, hf_drda_param_data_ebcdic, tvb, offset + 4, iLengthParam - 4, ENC_EBCDIC_CP500);
2495
0
            }
2496
0
        }
2497
0
        offset += iLengthParam;
2498
0
    }
2499
2500
0
    return tvb_captured_length(tvb);
2501
0
}
2502
2503
static int
2504
dissect_drda_codpntdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2505
0
{
2506
0
    proto_item *ti;
2507
0
    uint32_t codpnt;
2508
2509
0
    ti = proto_tree_add_item_ret_uint(tree, hf_drda_param_codepoint, tvb, 0, 2, ENC_BIG_ENDIAN, &codpnt);
2510
0
    proto_item_append_text(ti, " - %s", val_to_str_ext(pinfo->pool, codpnt, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
2511
0
    return 2;
2512
0
}
2513
2514
static int
2515
dissect_drda_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2516
5
{
2517
5
    proto_tree  *drda_tree;
2518
5
    proto_tree  *drdaroot_tree;
2519
5
    proto_tree  *drda_tree_sub;
2520
5
    proto_item  *ti, *ddm_ti, *ti_length;
2521
5
    int offset = 0;
2522
2523
5
    drda_conv_info_t *conv_info;
2524
5
    drda_flow_t      *flow;
2525
5
    drda_pdu_info_t  *pdu_info;
2526
5
    uint64_t flags;
2527
5
    uint32_t iLength, iCommand, correl;
2528
2529
5
    uint16_t iParameterCP;
2530
5
    uint8_t dsstyp;
2531
5
    bool is_server = false;
2532
5
    int iLengthParam;
2533
2534
5
    static int * const format_flags[] = {
2535
5
        &hf_drda_ddm_fmt_reserved,
2536
5
        &hf_drda_ddm_fmt_chained,
2537
5
        &hf_drda_ddm_fmt_errcont,
2538
5
        &hf_drda_ddm_fmt_samecorr,
2539
5
        &hf_drda_ddm_fmt_dsstyp,
2540
5
        NULL
2541
5
    };
2542
2543
5
    ti = proto_tree_add_item(tree, proto_drda, tvb, 0, -1, ENC_NA);
2544
5
    drdaroot_tree = proto_item_add_subtree(ti, ett_drda);
2545
2546
5
    drda_tree = proto_tree_add_subtree(drdaroot_tree, tvb, 0, 10, ett_drda_ddm, &ddm_ti, DRDA_TEXT_DDM);
2547
2548
5
    ti_length = proto_tree_add_item_ret_uint(drda_tree, hf_drda_ddm_length, tvb, 0, 2, ENC_BIG_ENDIAN, &iLength);
2549
5
    if (iLength < 10) {
2550
0
        expert_add_info_format(pinfo, ti_length, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be at least 10 bytes long", iLength);
2551
0
        return 2;
2552
0
    }
2553
2554
5
    proto_tree_add_item(drda_tree, hf_drda_ddm_magic, tvb, 2, 1, ENC_BIG_ENDIAN);
2555
2556
5
    proto_tree_add_bitmask_ret_uint64(drda_tree, tvb, 3, hf_drda_ddm_format, ett_drda_ddm_format, format_flags, ENC_BIG_ENDIAN, &flags);
2557
5
    dsstyp = flags & 0xF;
2558
2559
5
    proto_tree_add_item_ret_uint(drda_tree, hf_drda_ddm_rc, tvb, 4, 2, ENC_BIG_ENDIAN, &correl);
2560
5
    proto_tree_add_item(drda_tree, hf_drda_ddm_length2, tvb, 6, 2, ENC_BIG_ENDIAN);
2561
2562
5
    proto_tree_add_item_ret_uint(drda_tree, hf_drda_ddm_codepoint, tvb, 8, 2, ENC_BIG_ENDIAN, &iCommand);
2563
5
    is_server = drda_packet_from_server(pinfo, iCommand, dsstyp);
2564
5
    proto_item_append_text(ti, " (%s)", val_to_str_ext(pinfo->pool, iCommand, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
2565
5
    proto_item_append_text(ddm_ti, " (%s)", val_to_str_ext(pinfo->pool, iCommand, &drda_opcode_abbr_ext, "Unknown (0x%02x)"));
2566
5
    col_append_sep_str(pinfo->cinfo, COL_INFO, " | ", val_to_str_ext(pinfo->pool, iCommand, &drda_opcode_abbr_ext, "Unknown (0x%02x)"));
2567
5
    col_set_fence(pinfo->cinfo, COL_INFO);
2568
2569
5
    pdu_info = drda_get_pdu_info(pinfo, correl, is_server);
2570
2571
    /* There are a few command objects treated differently, like SNDPKT */
2572
5
    if (!dissector_try_uint_with_data(drda_opcode_table, iCommand, tvb_new_subset_length(tvb, 10, iLength - 10), pinfo, drda_tree, false, pdu_info)) {
2573
        /* The number of attributes is variable */
2574
5
        offset = 10;
2575
14
        while (tvb_reported_length_remaining(tvb, offset) >= 2)
2576
9
        {
2577
9
            iLengthParam = tvb_get_ntohs(tvb, offset + 0);
2578
9
            if (iLengthParam == 0 || iLengthParam == 1)
2579
2
                iLengthParam = iLength - 10;
2580
9
            if (tvb_reported_length_remaining(tvb, offset) >= iLengthParam)
2581
6
            {
2582
6
                iParameterCP = tvb_get_ntohs(tvb, offset + 2);
2583
6
                drda_tree_sub = proto_tree_add_subtree(drdaroot_tree, tvb, offset, iLengthParam,
2584
6
                                ett_drda_param, &ti, DRDA_TEXT_PARAM);
2585
6
                proto_item_append_text(ti, " (%s)", val_to_str_ext(pinfo->pool, iParameterCP, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
2586
6
                proto_tree_add_item(drda_tree_sub, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN);
2587
6
                proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2588
6
                if (!dissector_try_uint_with_data(drda_opcode_table, iParameterCP, tvb_new_subset_length(tvb, offset + 4, iLengthParam - 4), pinfo, drda_tree_sub, false, pdu_info)) {
2589
6
                    proto_tree_add_item(drda_tree_sub, hf_drda_param_data, tvb, offset + 4, iLengthParam - 4, ENC_UTF_8);
2590
6
                    proto_tree_add_item(drda_tree_sub, hf_drda_param_data_ebcdic, tvb, offset + 4, iLengthParam - 4, ENC_EBCDIC_CP500);
2591
6
                }
2592
6
            }
2593
9
            offset += iLengthParam;
2594
9
        }
2595
5
    }
2596
5
    conv_info = drda_get_conv_info(pinfo);
2597
5
    if (iCommand == DRDA_CP_EXCSATRD) {
2598
        /* EXCSATRD should be from the server, it confirms the negotiated
2599
         * values for the MGRLVLLS that both directions will use. */
2600
0
        flow = conv_info->server;
2601
0
        if (GPOINTER_TO_UINT(wmem_tree_lookup32_le(flow->sqlam_tree, pinfo->num)) != pdu_info->sqlam) {
2602
0
            wmem_tree_insert32(flow->sqlam_tree, pinfo->num, GUINT_TO_POINTER(pdu_info->sqlam));
2603
0
        }
2604
0
        flow = conv_info->client;
2605
0
        if (GPOINTER_TO_UINT(wmem_tree_lookup32_le(flow->sqlam_tree, pinfo->num)) != pdu_info->sqlam) {
2606
0
            wmem_tree_insert32(flow->sqlam_tree, pinfo->num, GUINT_TO_POINTER(pdu_info->sqlam));
2607
0
        }
2608
5
    } else if (iCommand == DRDA_CP_ACCRDB || iCommand == DRDA_CP_ACCRDBRM) {
2609
        /* The parameters configured by ACCRDB and ACCRDBRM, OTOH, are
2610
          * separate per-direction. */
2611
0
        flow = (iCommand == DRDA_CP_ACCRDB) ? conv_info->client : conv_info->server;
2612
0
        drda_update_flow_encoding(pinfo, flow, pdu_info);
2613
0
    }
2614
2615
5
    return tvb_captured_length(tvb);
2616
5
}
2617
2618
static unsigned
2619
get_drda_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
2620
5
{
2621
5
    return (tvb_get_ntohs(tvb, offset));
2622
5
}
2623
2624
static int
2625
dissect_drda_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
2626
5
{
2627
5
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRDA");
2628
5
    col_clear(pinfo->cinfo, COL_INFO);
2629
2630
    /* There may be multiple DRDA commands in one frame */
2631
5
    tcp_dissect_pdus(tvb, pinfo, tree, drda_desegment, 10, get_drda_pdu_len, dissect_drda_pdu, data);
2632
5
    return tvb_captured_length(tvb);
2633
5
}
2634
2635
2636
static bool
2637
dissect_drda_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2638
3.45k
{
2639
3.45k
    conversation_t * conversation;
2640
3.45k
    if (tvb_captured_length(tvb) >= 10)
2641
2.96k
    {
2642
        /* The first header is 6 bytes long, so the length in the second header should 6 bytes less */
2643
2.96k
        uint16_t cOuterLength, cInnerLength;
2644
2.96k
        cOuterLength = tvb_get_ntohs(tvb, 0);
2645
2.96k
        cInnerLength = tvb_get_ntohs(tvb, 6);
2646
2.96k
        if ((tvb_get_uint8(tvb, 2) == DRDA_MAGIC) && ((cOuterLength - cInnerLength) == 6))
2647
3
        {
2648
            /* Register this dissector for this conversation */
2649
3
            conversation = find_or_create_conversation(pinfo);
2650
3
            conversation_set_dissector(conversation, drda_tcp_handle);
2651
2652
            /* Dissect the packet */
2653
3
            dissect_drda_tcp(tvb, pinfo, tree, data);
2654
3
            return true;
2655
3
        }
2656
2.96k
    }
2657
3.45k
    return false;
2658
3.45k
}
2659
2660
void
2661
proto_register_drda(void)
2662
14
{
2663
14
    static hf_register_info hf[] = {
2664
14
        { &hf_drda_ddm_length,
2665
14
          { "Length", "drda.ddm.length",
2666
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
2667
14
            "DDM length", HFILL }},
2668
2669
14
        { &hf_drda_ddm_magic,
2670
14
          { "Magic", "drda.ddm.ddmid",
2671
14
            FT_UINT8, BASE_HEX, NULL, 0x0,
2672
14
            "DDM magic", HFILL }},
2673
2674
14
        { &hf_drda_ddm_format,
2675
14
          { "Format", "drda.ddm.format",
2676
14
            FT_UINT8, BASE_HEX, NULL, 0x0,
2677
14
            "DDM format", HFILL }},
2678
2679
14
        { &hf_drda_ddm_fmt_reserved,
2680
14
          { "Reserved", "drda.ddm.fmt.bit0",
2681
14
            FT_BOOLEAN, 8, TFS(&tfs_set_notset), DRDA_DSSFMT_RESERVED,
2682
14
            "DSSFMT reserved", HFILL }},
2683
2684
14
        { &hf_drda_ddm_fmt_chained,
2685
14
          { "Chained", "drda.ddm.fmt.bit1",
2686
14
            FT_BOOLEAN, 8, TFS(&tfs_set_notset), DRDA_DSSFMT_CHAINED,
2687
14
            "DSSFMT chained", HFILL }},
2688
2689
14
        { &hf_drda_ddm_fmt_errcont,
2690
14
          { "Continue", "drda.ddm.fmt.bit2",
2691
14
            FT_BOOLEAN, 8, TFS(&tfs_set_notset), DRDA_DSSFMT_CONTINUE,
2692
14
            "DSSFMT continue on error", HFILL }},
2693
2694
14
        { &hf_drda_ddm_fmt_samecorr,
2695
14
          { "Same correlation", "drda.ddm.fmt.bit3",
2696
14
            FT_BOOLEAN, 8, TFS(&tfs_set_notset), DRDA_DSSFMT_SAME_CORR,
2697
14
            "DSSFMT same correlation", HFILL }},
2698
2699
14
        { &hf_drda_ddm_fmt_dsstyp,
2700
14
          { "DSS type", "drda.ddm.fmt.dsstyp",
2701
14
            FT_UINT8, BASE_DEC, VALS(drda_dsstyp_abbr), 0x0F,
2702
14
            "DSSFMT type", HFILL }},
2703
2704
14
        { &hf_drda_ddm_rc,
2705
14
          { "CorrelId", "drda.ddm.rqscrr",
2706
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
2707
14
            "DDM correlation identifier", HFILL }},
2708
2709
14
        { &hf_drda_ddm_length2,
2710
14
          { "Length2", "drda.ddm.length2",
2711
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
2712
14
            "DDM length2", HFILL }},
2713
2714
14
        { &hf_drda_ddm_codepoint,
2715
14
          { "Code point", "drda.ddm.codepoint",
2716
14
            FT_UINT16, BASE_HEX|BASE_EXT_STRING, &drda_opcode_abbr_ext, 0x0,
2717
14
            "DDM code point", HFILL }},
2718
2719
14
        { &hf_drda_param_length,
2720
14
          { "Length", "drda.param.length",
2721
14
            FT_UINT16, BASE_DEC, NULL, 0x0,
2722
14
            "Param length", HFILL }},
2723
2724
14
        { &hf_drda_param_codepoint,
2725
14
          { "Code point", "drda.param.codepoint",
2726
14
            FT_UINT16, BASE_HEX|BASE_EXT_STRING, &drda_opcode_abbr_ext, 0x0,
2727
14
            "Param code point", HFILL }},
2728
2729
14
        { &hf_drda_param_data,
2730
14
          { "Data (ASCII)", "drda.param.data",
2731
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2732
14
            "Param data left as ASCII for display", HFILL }},
2733
2734
14
        { &hf_drda_param_data_ebcdic,
2735
14
          { "Data (EBCDIC)", "drda.param.data.ebcdic",
2736
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2737
14
            "Param data converted from EBCDIC to ASCII for display", HFILL }},
2738
2739
        /* The DRDA spec really treats the NULL indicator as a FT_INT8, but
2740
         * range_strings with negative values are a little annoying.
2741
         */
2742
14
        { &hf_drda_null_ind,
2743
14
          { "SQL NULL Indicator", "drda.null_ind",
2744
14
            FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(drda_null_ind_rvals),
2745
14
            0x0, NULL, HFILL }},
2746
2747
14
        { &hf_drda_typdefnam,
2748
14
          { "Data Type Definition Name", "drda.typdefnam",
2749
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2750
14
            NULL, HFILL }},
2751
2752
14
        { &hf_drda_clob_length,
2753
14
          { "CLOB Length", "drda.clob.length",
2754
14
            FT_UINT32, BASE_DEC, NULL, 0x0,
2755
14
            NULL, HFILL }},
2756
2757
14
        { &hf_drda_sqlstatement,
2758
14
          { "SQL statement", "drda.sqlstatement",
2759
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2760
14
            NULL, HFILL }},
2761
2762
14
        { &hf_drda_sqlcagrp,
2763
14
          { "SQL Communications Area Group Description", "drda.sqlcagrp",
2764
14
            FT_NONE, BASE_NONE, NULL, 0x0,
2765
14
            NULL, HFILL }},
2766
2767
14
        { &hf_drda_sqlcode,
2768
14
          { "SQL code", "drda.sqlcode",
2769
14
            FT_INT32, BASE_DEC, NULL, 0x0,
2770
14
            NULL, HFILL }},
2771
2772
14
        { &hf_drda_sqlstate,
2773
14
          { "SQL state", "drda.sqlstate",
2774
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2775
14
            NULL, HFILL }},
2776
2777
14
        { &hf_drda_sqlerrproc,
2778
14
          { "SQLERRPROC", "drda.sqlerrproc",
2779
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2780
14
            NULL, HFILL }},
2781
2782
14
        { &hf_drda_sqlcaxgrp,
2783
14
          { "SQL Communications Area Exceptions Group", "drda.sqlcaxgrp",
2784
14
            FT_NONE, BASE_NONE, NULL, 0x0,
2785
14
            NULL, HFILL }},
2786
2787
14
        { &hf_drda_sqlerrd1,
2788
14
          { "SQLERRD1", "drda.sqlerrd1",
2789
14
            FT_INT32, BASE_DEC, NULL, 0x0,
2790
14
            NULL, HFILL }},
2791
2792
14
        { &hf_drda_sqlerrd2,
2793
14
          { "SQLERRD2", "drda.sqlerrd2",
2794
14
            FT_INT32, BASE_DEC, NULL, 0x0,
2795
14
            NULL, HFILL }},
2796
2797
14
        { &hf_drda_sqlerrd3,
2798
14
          { "SQLERRD3", "drda.sqlerrd3",
2799
14
            FT_INT32, BASE_DEC, NULL, 0x0,
2800
14
            NULL, HFILL }},
2801
2802
14
        { &hf_drda_sqlerrd4,
2803
14
          { "SQLERRD4", "drda.sqlerrd4",
2804
14
            FT_INT32, BASE_DEC, NULL, 0x0,
2805
14
            NULL, HFILL }},
2806
2807
14
        { &hf_drda_sqlerrd5,
2808
14
          { "SQLERRD5", "drda.sqlerrd5",
2809
14
            FT_INT32, BASE_DEC, NULL, 0x0,
2810
14
            NULL, HFILL }},
2811
2812
14
        { &hf_drda_sqlerrd6,
2813
14
          { "SQLERRD6", "drda.sqlerrd6",
2814
14
            FT_INT32, BASE_DEC, NULL, 0x0,
2815
14
            NULL, HFILL }},
2816
2817
14
        { &hf_drda_sqlwarn0,
2818
14
          { "SQLWARN0", "drda.sqlwarn0",
2819
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2820
14
            NULL, HFILL }},
2821
2822
14
        { &hf_drda_sqlwarn1,
2823
14
          { "SQLWARN1", "drda.sqlwarn1",
2824
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2825
14
            NULL, HFILL }},
2826
2827
14
        { &hf_drda_sqlwarn2,
2828
14
          { "SQLWARN2", "drda.sqlwarn2",
2829
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2830
14
            NULL, HFILL }},
2831
2832
14
        { &hf_drda_sqlwarn3,
2833
14
          { "SQLWARN3", "drda.sqlwarn3",
2834
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2835
14
            NULL, HFILL }},
2836
2837
14
        { &hf_drda_sqlwarn4,
2838
14
          { "SQLWARN4", "drda.sqlwarn4",
2839
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2840
14
            NULL, HFILL }},
2841
2842
14
        { &hf_drda_sqlwarn5,
2843
14
          { "SQLWARN5", "drda.sqlwarn5",
2844
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2845
14
            NULL, HFILL }},
2846
2847
14
        { &hf_drda_sqlwarn6,
2848
14
          { "SQLWARN6", "drda.sqlwarn6",
2849
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2850
14
            NULL, HFILL }},
2851
2852
14
        { &hf_drda_sqlwarn7,
2853
14
          { "SQLWARN7", "drda.sqlwarn7",
2854
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2855
14
            NULL, HFILL }},
2856
2857
14
        { &hf_drda_sqlwarn8,
2858
14
          { "SQLWARN8", "drda.sqlwarn8",
2859
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2860
14
            NULL, HFILL }},
2861
2862
14
        { &hf_drda_sqlwarn9,
2863
14
          { "SQLWARN9", "drda.sqlwarn9",
2864
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2865
14
            NULL, HFILL }},
2866
2867
14
        { &hf_drda_sqlwarna,
2868
14
          { "SQLWARNA", "drda.sqlwarna",
2869
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2870
14
            NULL, HFILL }},
2871
2872
14
        { &hf_drda_sqlerrmsg,
2873
14
          { "SQL Error Message Token", "drda.sqlerrmsg",
2874
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2875
14
            NULL, HFILL }},
2876
2877
14
        { &hf_drda_sqldhgrp,
2878
14
          { "SQL Descriptor Header Group Description", "drda.sqldhgrp",
2879
14
            FT_NONE, BASE_NONE, NULL, 0x0,
2880
14
            NULL, HFILL }},
2881
2882
14
        { &hf_drda_sqldhold,
2883
14
          { "SQLDHOLD", "drda.sqldhold",
2884
14
            FT_INT16, BASE_DEC, VALS(drda_hold_vals), 0x0,
2885
14
            NULL, HFILL }},
2886
2887
14
        { &hf_drda_sqldreturn,
2888
14
          { "SQLDRETURN", "drda.sqldreturn",
2889
14
            FT_INT16, BASE_DEC, VALS(drda_return_vals), 0x0,
2890
14
            NULL, HFILL }},
2891
2892
14
        { &hf_drda_sqldscroll,
2893
14
          { "SQLDSCROLL", "drda.sqldscroll",
2894
14
            FT_INT16, BASE_DEC, VALS(drda_scroll_vals), 0x0,
2895
14
            NULL, HFILL }},
2896
2897
14
        { &hf_drda_sqldsensitive,
2898
14
          { "SQLDSENSITIVE", "drda.sqldsensitive",
2899
14
            FT_INT16, BASE_DEC, VALS(drda_sensitive_vals), 0x0,
2900
14
            NULL, HFILL }},
2901
2902
14
        { &hf_drda_sqldfcode,
2903
14
          { "SQLDFCODE", "drda.sqldfcode",
2904
14
            FT_INT16, BASE_DEC, VALS(drda_fcode_vals), 0x0,
2905
14
            NULL, HFILL }},
2906
2907
14
        { &hf_drda_sqldkeytype,
2908
14
          { "SQLDKEYTYPE", "drda.sqldkeytype",
2909
14
            FT_INT16, BASE_DEC, VALS(drda_keytype_vals), 0x0,
2910
14
            NULL, HFILL }},
2911
2912
14
        { &hf_drda_sqldoptlck,
2913
14
          { "SQLDOPTLCK", "drda.sqldoptlck",
2914
14
            FT_INT16, BASE_DEC, VALS(drda_doptlck_vals), 0x0,
2915
14
            NULL, HFILL }},
2916
2917
14
        { &hf_drda_sqldschema,
2918
14
          { "SQLDSCHEMA", "drda.sqldschema",
2919
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2920
14
            NULL, HFILL }},
2921
2922
14
        { &hf_drda_sqldmodule,
2923
14
          { "SQLDMODULE", "drda.sqldmodule",
2924
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2925
14
            NULL, HFILL }},
2926
2927
14
        { &hf_drda_sqldagrp,
2928
14
          { "SQL Descriptor Area Group Description", "drda.sqldagrp",
2929
14
            FT_NONE, BASE_NONE, NULL, 0x0,
2930
14
            NULL, HFILL }},
2931
2932
14
        { &hf_drda_sqlprecision,
2933
14
          { "SQLPRECISION", "drda.sqlprecision",
2934
14
            FT_INT16, BASE_DEC, NULL, 0x0,
2935
14
            NULL, HFILL }},
2936
2937
14
        { &hf_drda_sqlscale,
2938
14
          { "SQLSCALE", "drda.sqlscale",
2939
14
            FT_INT16, BASE_DEC, NULL, 0x0,
2940
14
            NULL, HFILL }},
2941
2942
14
        { &hf_drda_sqllength,
2943
14
          { "SQLLENGTH", "drda.sqllength",
2944
14
            FT_INT64, BASE_DEC, NULL, 0x0,
2945
14
            NULL, HFILL }},
2946
2947
14
        { &hf_drda_sqllength32,
2948
14
          { "SQLLENGTH", "drda.sqllength",
2949
14
            FT_INT32, BASE_DEC, NULL, 0x0,
2950
14
            NULL, HFILL }},
2951
2952
14
        { &hf_drda_sqltype,
2953
14
          { "SQLTYPE", "drda.sqltype",
2954
14
            FT_INT16, BASE_DEC, VALS(drda_sqltype_vals), 0x0,
2955
14
            NULL, HFILL }},
2956
2957
14
        { &hf_drda_sqlarrextent,
2958
14
          { "SQLARREXTENT", "drda.sqlarrextent",
2959
14
            FT_INT64, BASE_DEC, NULL, 0x0,
2960
14
            NULL, HFILL }},
2961
2962
14
        { &hf_drda_sqldoptgrp,
2963
14
          { "SQL Descriptor Optional Group Description", "drda.sqldoptgrp",
2964
14
            FT_NONE, BASE_NONE, NULL, 0x0,
2965
14
            NULL, HFILL }},
2966
2967
14
        { &hf_drda_sqlunnamed,
2968
14
          { "SQLUNNAMED", "drda.sqlunnamed",
2969
14
            FT_INT16, BASE_DEC, VALS(drda_unnamed_vals), 0x0,
2970
14
            NULL, HFILL }},
2971
2972
14
        { &hf_drda_sqlname,
2973
14
          { "SQLNAME", "drda.sqlname",
2974
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2975
14
            NULL, HFILL }},
2976
2977
14
        { &hf_drda_sqllabel,
2978
14
          { "SQLLABEL", "drda.sqllabel",
2979
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2980
14
            NULL, HFILL }},
2981
2982
14
        { &hf_drda_sqlcomments,
2983
14
          { "SQLCOMMENTS", "drda.sqlcomments",
2984
14
            FT_STRING, BASE_NONE, NULL, 0x0,
2985
14
            NULL, HFILL }},
2986
2987
14
        { &hf_drda_sqludtgrp,
2988
14
          { "SQL Descriptor User-Defined Type Group Description",
2989
14
            "drda.sqludtgrp",
2990
14
            FT_NONE, BASE_NONE, NULL, 0x0,
2991
14
            NULL, HFILL }},
2992
2993
14
        { &hf_drda_sqludtxtype,
2994
14
          { "SQLUDTXTYPE", "drda.sqludtxtype",
2995
14
            FT_INT32, BASE_DEC, VALS(drda_udtxtype_vals), 0x0,
2996
14
            NULL, HFILL }},
2997
2998
14
        { &hf_drda_sqludtschema,
2999
14
          { "SQLUDTSCHEMA", "drda.sqludtschema",
3000
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3001
14
            NULL, HFILL }},
3002
3003
14
        { &hf_drda_sqludtname,
3004
14
          { "SQLUDTNAME", "drda.sqludtname",
3005
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3006
14
            NULL, HFILL }},
3007
3008
14
        { &hf_drda_sqludtmodule,
3009
14
          { "SQLUDTMODULE", "drda.sqludtmodule",
3010
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3011
14
            NULL, HFILL }},
3012
3013
14
        { &hf_drda_sqldxgrp,
3014
14
          { "SQL Descriptor Extended Type Group Description", "drda.sqldxgrp",
3015
14
            FT_NONE, BASE_NONE, NULL, 0x0,
3016
14
            NULL, HFILL }},
3017
3018
14
        { &hf_drda_sqlxkeymem,
3019
14
          { "SQLXKEYMEM", "drda.sqlxkeymem",
3020
14
            FT_INT16, BASE_DEC, VALS(drda_keymem_vals), 0x0,
3021
14
            NULL, HFILL }},
3022
3023
14
        { &hf_drda_sqlxupdateable,
3024
14
          { "SQLXUPDATEABLE", "drda.sqlxupdateable",
3025
14
            FT_INT16, BASE_DEC, VALS(drda_updateable_vals), 0x0,
3026
14
            NULL, HFILL }},
3027
3028
14
        { &hf_drda_sqlxgenerated,
3029
14
          { "SQLXGENERATED", "drda.sqlxgenerated",
3030
14
            FT_INT16, BASE_DEC, VALS(drda_generated_vals), 0x0,
3031
14
            NULL, HFILL }},
3032
3033
14
        { &hf_drda_sqlxparmmode,
3034
14
          { "SQLXPARMMODE", "drda.sqlxparmmode",
3035
14
            FT_INT16, BASE_DEC, VALS(drda_parmmode_vals), 0x0,
3036
14
            NULL, HFILL }},
3037
3038
14
        { &hf_drda_sqlxoptlck,
3039
14
          { "SQLXOPTLCK", "drda.sqlxoptlck",
3040
14
            FT_INT16, BASE_DEC, VALS(drda_xoptlck_vals), 0x0,
3041
14
            NULL, HFILL }},
3042
3043
14
        { &hf_drda_sqlxhidden,
3044
14
          { "SQLXHIDDEN", "drda.sqlxhidden",
3045
14
            FT_INT16, BASE_DEC, VALS(drda_hidden_vals), 0x0,
3046
14
            NULL, HFILL }},
3047
3048
14
        { &hf_drda_sqlxcorname,
3049
14
          { "SQLXCORNAME", "drda.sqlxcorname",
3050
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3051
14
            NULL, HFILL }},
3052
3053
14
        { &hf_drda_sqlxbasename,
3054
14
          { "SQLXBASENAME", "drda.sqlxbasename",
3055
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3056
14
            NULL, HFILL }},
3057
3058
14
        { &hf_drda_sqlxschema,
3059
14
          { "SQLXSCHEMA", "drda.sqlxschema",
3060
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3061
14
            NULL, HFILL }},
3062
3063
14
        { &hf_drda_sqlxname,
3064
14
          { "SQLXNAME", "drda.sqlxname",
3065
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3066
14
            NULL, HFILL }},
3067
3068
14
        { &hf_drda_sqlxmodule,
3069
14
          { "SQLXMODULE", "drda.sqlxmodule",
3070
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3071
14
            NULL, HFILL }},
3072
3073
14
        { &hf_drda_sqldiaggrp,
3074
14
          { "SQL Diagnostics Group Description", "drda.sqldiaggrp",
3075
14
            FT_NONE, BASE_NONE, NULL, 0x0,
3076
14
            NULL, HFILL }},
3077
3078
14
        { &hf_drda_sqlnum,
3079
14
          { "SQLNUM", "drda.sqlnum",
3080
14
            FT_INT16, BASE_DEC, NULL, 0x0,
3081
14
            NULL, HFILL }},
3082
3083
14
        { &hf_drda_rlsconv,
3084
14
          { "Release Conversation", "drda.rlsconv", FT_UINT8, BASE_NONE,
3085
14
            VALS(drda_rlsconv_vals), 0x0,
3086
14
            NULL, HFILL }},
3087
3088
14
        { &hf_drda_secmec,
3089
14
          { "Security Mechanism", "drda.secmec", FT_UINT16, BASE_DEC,
3090
14
            VALS(drda_secmec_vals), 0x0,
3091
14
            NULL, HFILL }},
3092
3093
14
        { &hf_drda_sectkn,
3094
14
          { "Security Token", "drda.sectkn", FT_BYTES, BASE_NONE,
3095
14
            NULL, 0x0,
3096
14
            NULL, HFILL }},
3097
3098
14
        { &hf_drda_svrcod,
3099
14
          { "Severity Code", "drda.svrcod", FT_UINT16, BASE_DEC,
3100
14
            VALS(drda_svrcod_vals), 0x0,
3101
14
            NULL, HFILL }},
3102
3103
14
        { &hf_drda_secchkcd,
3104
14
          { "Security Check Code", "drda.secchkcd", FT_UINT8, BASE_HEX,
3105
14
            VALS(drda_secchkcd_vals), 0x0,
3106
14
            NULL, HFILL }},
3107
3108
14
        { &hf_drda_ccsid,
3109
14
          { "CCSID", "drda.ccsid", FT_UINT16, BASE_DEC,
3110
14
            VALS(drda_ccsid_vals), 0x0,
3111
14
            "Coded Character Set Identifier", HFILL }},
3112
3113
14
        { &hf_drda_mgrlvln,
3114
14
          { "Manager-level Number", "drda.mgrlvln", FT_UINT16, BASE_DEC,
3115
14
            NULL, 0x0,
3116
14
            NULL, HFILL }},
3117
3118
14
        { &hf_drda_monitor,
3119
14
          { "Monitor", "drda.monitor", FT_UINT32, BASE_HEX,
3120
14
            NULL, 0x0,
3121
14
            NULL, HFILL }},
3122
3123
14
        { &hf_drda_monitor_etime,
3124
14
          { "Elapsed Time", "drda.monitor.etime", FT_BOOLEAN, 32,
3125
14
            NULL, 0x80000000,
3126
14
            NULL, HFILL }},
3127
3128
14
        { &hf_drda_monitor_reserved,
3129
14
          { "Reserved", "drda.monitor.reserved", FT_UINT32, BASE_HEX,
3130
14
            NULL, 0x7FFFFFFF,
3131
14
            NULL, HFILL }},
3132
3133
14
        { &hf_drda_etime,
3134
14
          { "Elapsed Time", "drda.etime", FT_RELATIVE_TIME, BASE_NONE,
3135
14
            NULL, 0x0,
3136
14
            NULL, HFILL }},
3137
3138
14
        { &hf_drda_respktsz,
3139
14
          { "Response Packet Size", "drda.respktsz", FT_UINT32, BASE_DEC,
3140
14
            NULL, 0x0,
3141
14
            NULL, HFILL }},
3142
3143
14
        { &hf_drda_rdbinttkn,
3144
14
          { "RDB Interrupt Token", "drda.rdbinttkn", FT_BYTES, BASE_NONE,
3145
14
            NULL, 0x0,
3146
14
            NULL, HFILL }},
3147
3148
14
        { &hf_drda_rdbcmtok,
3149
14
          { "RDB Commit Allowed", "drda.rdbcmtok", FT_UINT8, BASE_NONE,
3150
14
            VALS(drda_boolean_vals), 0x0,
3151
14
            NULL, HFILL }},
3152
3153
        /* This one is a 0x00 0x01 boolean, not a EBCDIC 0xf0 0xf1 boolean */
3154
14
        { &hf_drda_rtnsetstt,
3155
14
          { "Return SET Statement", "drda.rtnsetstt", FT_BOOLEAN, BASE_NONE,
3156
14
            NULL, 0x0,
3157
14
            NULL, HFILL }},
3158
3159
14
        { &hf_drda_outexp,
3160
14
          { "Output Expected", "drda.outexp", FT_UINT8, BASE_NONE,
3161
14
            VALS(drda_boolean_vals), 0x0,
3162
14
            NULL, HFILL }},
3163
3164
14
        { &hf_drda_rdbnam,
3165
14
          { "Relational Database Name (ASCII)", "drda.rdbnam", FT_STRING,
3166
14
            BASE_NONE, NULL, 0x0,
3167
14
            "RDBNAM assuming ASCII/UTF-8", HFILL }},
3168
3169
14
        { &hf_drda_rdbnam_ebcdic,
3170
14
          { "Relational Database Name (EBCDIC)", "drda.rdbnam.ebcdic", FT_STRING,
3171
14
            BASE_NONE, NULL, 0x0,
3172
14
            "RBDNAM assuming EBCDIC", HFILL }},
3173
3174
14
        { &hf_drda_rdbcolid,
3175
14
          { "RDB Collection Identifier (ASCII)", "drda.rdbcoldid", FT_STRING,
3176
14
            BASE_NONE, NULL, 0x0,
3177
14
            "RDBCOLID assuming ASCII/UTF-8", HFILL }},
3178
3179
14
        { &hf_drda_rdbcolid_ebcdic,
3180
14
          { "RDB Collection Identifier (EBCDIC)", "drda.rdbcolid.ebcdic",
3181
14
            FT_STRING, BASE_NONE, NULL, 0x0,
3182
14
            "RBDCOLID assuming EBCDIC", HFILL }},
3183
3184
14
        { &hf_drda_pkgid,
3185
14
          { "RDB Package Identifier (ASCII)", "drda.pkgid", FT_STRING, BASE_NONE,
3186
14
            NULL, 0x0,
3187
14
            "PKGID assuming ASCII/UTF-8", HFILL }},
3188
3189
14
        { &hf_drda_pkgid_ebcdic,
3190
14
          { "RDB Package Identifier (EBCDIC)", "drda.pkgid.ebcdic", FT_STRING,
3191
14
            BASE_NONE, NULL, 0x0,
3192
14
            "PKGID assuming EBCDIC", HFILL }},
3193
3194
14
        { &hf_drda_pkgsn,
3195
14
          { "RDB Package Section Number", "drda.pkgsn", FT_INT16,
3196
14
            BASE_DEC, NULL, 0x0,
3197
14
            NULL, HFILL }},
3198
3199
14
        { &hf_drda_pkgcnstkn,
3200
14
          { "RDB Package Consistency Token", "drda.pkgcnstkn", FT_BYTES,
3201
14
            BASE_NONE|BASE_SHOW_ASCII_PRINTABLE, NULL, 0x0,
3202
14
            NULL, HFILL }},
3203
3204
14
        { &hf_drda_qryblksz,
3205
14
          { "Query Block Size", "drda.qryblksz", FT_UINT32, BASE_DEC,
3206
14
            NULL, 0x0,
3207
14
            NULL, HFILL }},
3208
3209
14
        { &hf_drda_uowdsp,
3210
14
          { "Unit of Work Disposition", "drda.uowdsp", FT_UINT8, BASE_HEX,
3211
14
            VALS(drda_uowdsp_vals), 0x0,
3212
14
            NULL, HFILL }},
3213
3214
14
        { &hf_drda_rdbalwupd,
3215
14
          { "RDB Allow Updates", "drda.rdbalwupd", FT_UINT8, BASE_HEX,
3216
14
            VALS(drda_boolean_vals), 0x0,
3217
14
            NULL, HFILL }},
3218
3219
14
        { &hf_drda_sqlcsrhld,
3220
14
          { "Hold Cursor Position", "drda.sqlcsrhld", FT_UINT8, BASE_HEX,
3221
14
            VALS(drda_boolean_vals), 0x0,
3222
14
            NULL, HFILL }},
3223
3224
14
        { &hf_drda_qryextdtasz,
3225
14
          { "Query Externalized Data Size", "drda.qryextdtasz", FT_INT64,
3226
14
            BASE_DEC|BASE_VAL64_STRING|BASE_SPECIAL_VALS,
3227
14
            VALS64(drda_qryextdtasz_vals), 0x0,
3228
14
            NULL, HFILL }},
3229
3230
14
        { &hf_drda_smldtasz,
3231
14
          { "Maximum Size of Small Data", "drda.smldtasz", FT_INT64, BASE_DEC,
3232
14
            NULL, 0x0,
3233
14
            NULL, HFILL }},
3234
3235
14
        { &hf_drda_meddtasz,
3236
14
          { "Maximum Size of Medium Data", "drda.meddtasz", FT_INT64, BASE_DEC,
3237
14
            NULL, 0x0,
3238
14
            NULL, HFILL }},
3239
3240
14
        { &hf_drda_trgdftrt,
3241
14
          { "Target Default Value Return", "drda.trgdftrt", FT_UINT8, BASE_HEX,
3242
14
            VALS(drda_boolean_vals), 0x0,
3243
14
            NULL, HFILL }},
3244
3245
14
        { &hf_drda_rtnsqlda,
3246
14
          { "Return the SQLDA", "drda.rtnsqlda", FT_UINT8, BASE_HEX,
3247
14
            VALS(drda_boolean_vals), 0x0,
3248
14
            NULL, HFILL }},
3249
3250
14
        { &hf_drda_qryattupd,
3251
14
          { "Query Attribute for Updatability", "drda.qryattupd", FT_INT8,
3252
14
            BASE_DEC, VALS(drda_qryattupd_vals), 0x0,
3253
14
            NULL, HFILL }},
3254
3255
14
        { &hf_drda_qryrowset,
3256
14
          { "Query Rowset Size", "drda.qryrowset", FT_INT32, BASE_DEC,
3257
14
            NULL, 0x0,
3258
14
            NULL, HFILL }},
3259
3260
14
        { &hf_drda_qryinsid,
3261
14
          { "Query Instance Identifier", "drda.qryinsid", FT_BYTES, BASE_NONE,
3262
14
            NULL, 0x0,
3263
14
            NULL, HFILL }},
3264
3265
14
        { &hf_drda_qryclsimp,
3266
14
          { "Query Close Implicit", "drda.qryclsimp", FT_INT8, BASE_DEC,
3267
14
            VALS(drda_qryclsimp_vals), 0x0,
3268
14
            NULL, HFILL }},
3269
3270
14
        { &hf_drda_qryblkfct,
3271
14
          { "Query Blocking Factor", "drda.qryblkfct", FT_INT32, BASE_DEC,
3272
14
            NULL, 0x0,
3273
14
            NULL, HFILL }},
3274
3275
14
        { &hf_drda_maxrslcnt,
3276
14
          { "Maximum Result Set Count", "drda.maxrslcnt", FT_INT32,
3277
14
            BASE_DEC|BASE_SPECIAL_VALS, VALS(drda_max_vals), 0x0,
3278
14
            NULL, HFILL }},
3279
3280
14
        { &hf_drda_maxblkext,
3281
14
          { "Maximum Number of Extra Blocks", "drda.maxblkext", FT_INT32,
3282
14
            BASE_DEC|BASE_SPECIAL_VALS, VALS(drda_max_vals), 0x0,
3283
14
            NULL, HFILL }},
3284
3285
14
        { &hf_drda_rslsetflg,
3286
14
          { "Result Set Flags", "drda.rslsetflg", FT_UINT8, BASE_HEX,
3287
14
            NULL, 0x0,
3288
14
            NULL, HFILL }},
3289
3290
14
        { &hf_drda_rslsetflg_unused,
3291
14
          { "Unused", "drda.rslsetflg.unused", FT_UINT8, BASE_HEX,
3292
14
            NULL, 0xE0,
3293
14
            "Flags are no longer used and value should be zero", HFILL }},
3294
3295
14
        { &hf_drda_rslsetflg_dsconly,
3296
14
          { "Description Only", "drda.rslsetflg.dsconly", FT_BOOLEAN, 8,
3297
14
            NULL, 0x10,
3298
14
            "Requires the target SQLAM to return an FD:OCA description but not any answer set data", HFILL }},
3299
3300
14
        { &hf_drda_rslsetflg_extended,
3301
14
          { "Extended", "drda.rslsetflg.extended", FT_UINT8, BASE_HEX,
3302
14
            VALS(drda_rslsetflg_extended_vals), 0x0C,
3303
14
            "Identifies the type of FD:OCA SQLDA descriptor returned", HFILL }},
3304
3305
14
        { &hf_drda_rslsetflg_reserved,
3306
14
          { "Reserved", "drda.rslsetflg.reserved", FT_UINT8, BASE_HEX,
3307
14
            NULL, 0x03,
3308
14
            NULL, HFILL }},
3309
3310
14
        { &hf_drda_typsqlda,
3311
14
          { "Type of SQL Descriptor Area", "drda.typsqlda", FT_INT8, BASE_DEC,
3312
14
            VALS(drda_typsqlda_vals), 0x0,
3313
14
            NULL, HFILL }},
3314
3315
14
        { &hf_drda_outovropt,
3316
14
          { "Output Override Option", "drda.outovropt", FT_INT8, BASE_DEC,
3317
14
            VALS(drda_outovropt_vals), 0x0,
3318
14
            NULL, HFILL }},
3319
3320
14
        { &hf_drda_dyndtafmt,
3321
14
          { "Dynamic Data Format", "drda.dyndtafmt", FT_UINT8, BASE_HEX,
3322
14
            VALS(drda_boolean_vals), 0x0,
3323
14
            NULL, HFILL }},
3324
3325
14
        { &hf_drda_pktobj,
3326
14
          { "Packet Object", "drda.pktobj", FT_BYTES, BASE_NONE,
3327
14
            NULL, 0x0,
3328
14
            NULL, HFILL }},
3329
14
    };
3330
3331
14
    static int *ett[] = {
3332
14
        &ett_drda,
3333
14
        &ett_drda_ddm,
3334
14
        &ett_drda_ddm_format,
3335
14
        &ett_drda_param,
3336
14
        &ett_drda_monitor,
3337
14
        &ett_drda_rslsetflg,
3338
14
        &ett_drda_sqlcagrp,
3339
14
        &ett_drda_sqlcaxgrp,
3340
14
        &ett_drda_sqldhgrp,
3341
14
        &ett_drda_sqldagrp,
3342
14
        &ett_drda_sqldoptgrp,
3343
14
        &ett_drda_sqludtgrp,
3344
14
        &ett_drda_sqldxgrp,
3345
14
        &ett_drda_sqldiaggrp,
3346
14
    };
3347
3348
14
    static ei_register_info ei[] = {
3349
14
        { &ei_drda_opcode_invalid_length, { "drda.opcode.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length detected", EXPFILL }},
3350
14
        { &ei_drda_undecoded, { "drda.undecoded", PI_UNDECODED, PI_NOTE, "[Not decoded yet]", EXPFILL }},
3351
14
    };
3352
3353
14
    module_t *drda_module;
3354
14
    expert_module_t* expert_drda;
3355
3356
14
    proto_drda = proto_register_protocol("DRDA", "DRDA", "drda");
3357
14
    proto_register_field_array(proto_drda, hf, array_length(hf));
3358
14
    proto_register_subtree_array(ett, array_length(ett));
3359
14
    expert_drda = expert_register_protocol(proto_drda);
3360
14
    expert_register_field_array(expert_drda, ei, array_length(ei));
3361
3362
14
    drda_opcode_table = register_dissector_table("drda.opcode", "DRDA opcode",
3363
14
        proto_drda, FT_UINT16, BASE_HEX);
3364
3365
14
    drda_module = prefs_register_protocol(proto_drda, NULL);
3366
14
    prefs_register_bool_preference(drda_module, "desegment",
3367
14
                       "Reassemble DRDA messages spanning multiple TCP segments",
3368
14
                       "Whether the DRDA dissector should reassemble messages spanning"
3369
14
                       " multiple TCP segments."
3370
14
                       " To use this option, you must also enable"
3371
14
                       " \"Allow subdissectors to reassemble TCP streams\""
3372
14
                       " in the TCP protocol settings.",
3373
14
                       &drda_desegment);
3374
3375
14
    prefs_register_uint_preference(drda_module, "sqlam",
3376
14
                        "Default SQLAM Level",
3377
14
                        "Default SQL Application Manager Level in the absence"
3378
14
                        " of EXSATRD command. (Currently the only difference"
3379
14
                        " in handling is between values < 7 and >= 7.)",
3380
14
                        10, &drda_default_sqlam);
3381
3382
14
    prefs_register_enum_preference(drda_module, "typdefnam",
3383
14
                        "Default TYPDEFNAM",
3384
14
                        "Data Type Definition to use in the absence of"
3385
14
                        " ACCRDB and ACCRDBRM commands.",
3386
14
                        &drda_default_typdefnam,
3387
14
                        typdefnam_vals, false);
3388
3389
14
    prefs_register_enum_preference(drda_module, "ccsidsbc",
3390
14
                        "Default Single-byte encoding for FD:OCA data",
3391
14
                        "Single-byte encoding to use for FD:OCA character data"
3392
14
                        " in the absence of CCSIDSBC TYPDEFOVR parameter.",
3393
14
                        &drda_default_ccsidsbc,
3394
14
                        ws_supported_mibenum_vals_character_sets_ev_array,
3395
14
                        false);
3396
3397
14
    prefs_register_enum_preference(drda_module, "ccsidmbc",
3398
14
                        "Default Mixed-byte encoding for FD:OCA data",
3399
14
                        "Mixed-byte encoding to use for FD:OCA character data"
3400
14
                        " in the absence of CCSIDMBC TYPDEFOVR parameter.",
3401
14
                        &drda_default_ccsidmbc,
3402
14
                        ws_supported_mibenum_vals_character_sets_ev_array,
3403
14
                        false);
3404
3405
14
    drda_tcp_handle = register_dissector("drda", dissect_drda_tcp, proto_drda);
3406
14
}
3407
3408
void
3409
proto_reg_handoff_drda(void)
3410
14
{
3411
14
    heur_dissector_add("tcp", dissect_drda_heur, "DRDA over TCP", "drda_tcp", proto_drda, HEURISTIC_ENABLE);
3412
3413
14
    dissector_handle_t ccsid_handle;
3414
14
    dissector_handle_t codpntdr_handle;
3415
14
    dissector_handle_t collection_handle;
3416
14
    dissector_handle_t sqlstt_handle;
3417
14
    dissector_handle_t undecoded_handle;
3418
3419
14
    ccsid_handle = create_dissector_handle(dissect_drda_ccsid, proto_drda);
3420
14
    codpntdr_handle = create_dissector_handle(dissect_drda_codpntdr, proto_drda);
3421
14
    collection_handle = create_dissector_handle(dissect_drda_collection, proto_drda);
3422
14
    sqlstt_handle = create_dissector_handle(dissect_drda_sqlstt, proto_drda);
3423
14
    undecoded_handle = create_dissector_handle(dissect_drda_undecoded, proto_drda);
3424
3425
14
    dissector_add_uint("drda.opcode", DRDA_CP_TYPDEFNAM, create_dissector_handle(dissect_drda_typdefnam, proto_drda));
3426
14
    dissector_add_uint("drda.opcode", DRDA_CP_MGRLVLLS, create_dissector_handle(dissect_drda_mgrlvlls, proto_drda));
3427
14
    dissector_add_uint("drda.opcode", DRDA_CP_TYPDEFOVR, collection_handle);
3428
14
    dissector_add_uint("drda.opcode", DRDA_CP_PKGSNLST, collection_handle);
3429
14
    dissector_add_uint("drda.opcode", DRDA_CP_RLSCONV, create_dissector_handle(dissect_drda_rlsconv, proto_drda));
3430
14
    dissector_add_uint("drda.opcode", DRDA_CP_SECMEC, create_dissector_handle(dissect_drda_secmec, proto_drda));
3431
14
    dissector_add_uint("drda.opcode", DRDA_CP_SECTKN, create_dissector_handle(dissect_drda_sectkn, proto_drda));
3432
14
    dissector_add_uint("drda.opcode", DRDA_CP_SVRCOD, create_dissector_handle(dissect_drda_svrcod, proto_drda));
3433
14
    dissector_add_uint("drda.opcode", DRDA_CP_SECCHKCD, create_dissector_handle(dissect_drda_secchkcd, proto_drda));
3434
14
    dissector_add_uint("drda.opcode", DRDA_CP_CCSIDSBC, ccsid_handle);
3435
14
    dissector_add_uint("drda.opcode", DRDA_CP_CCSIDDBC, ccsid_handle);
3436
14
    dissector_add_uint("drda.opcode", DRDA_CP_CCSIDMBC, ccsid_handle);
3437
14
    dissector_add_uint("drda.opcode", DRDA_CP_CCSIDXML, ccsid_handle);
3438
3439
14
    dissector_add_uint("drda.opcode", DRDA_CP_RDBACCCL, codpntdr_handle);
3440
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYPRCTYP, codpntdr_handle);
3441
14
    dissector_add_uint("drda.opcode", DRDA_CP_PKGDFTCST, codpntdr_handle);
3442
14
    dissector_add_uint("drda.opcode", 0x2460, codpntdr_handle); /* Not in DRDA, Version 5 */
3443
3444
14
    dissector_add_uint("drda.opcode", DRDA_CP_MONITOR, create_dissector_handle(dissect_drda_monitor, proto_drda));
3445
14
    dissector_add_uint("drda.opcode", DRDA_CP_ETIME, create_dissector_handle(dissect_drda_etime, proto_drda));
3446
14
    dissector_add_uint("drda.opcode", DRDA_CP_RESPKTSZ, create_dissector_handle(dissect_drda_respktsz, proto_drda));
3447
14
    dissector_add_uint("drda.opcode", DRDA_CP_RDBINTTKN, create_dissector_handle(dissect_drda_rdbinttkn, proto_drda));
3448
14
    dissector_add_uint("drda.opcode", DRDA_CP_RDBCMTOK, create_dissector_handle(dissect_drda_rdbcmtok, proto_drda));
3449
14
    dissector_add_uint("drda.opcode", DRDA_CP_RTNSETSTT, create_dissector_handle(dissect_drda_rtnsetstt, proto_drda));
3450
14
    dissector_add_uint("drda.opcode", DRDA_CP_OUTEXP, create_dissector_handle(dissect_drda_outexp, proto_drda));
3451
14
    dissector_add_uint("drda.opcode", DRDA_CP_PKGNAM, create_dissector_handle(dissect_drda_pkgnam, proto_drda));
3452
14
    dissector_add_uint("drda.opcode", DRDA_CP_PKGNAMCT, create_dissector_handle(dissect_drda_pkgnamct, proto_drda));
3453
14
    dissector_add_uint("drda.opcode", DRDA_CP_PKGNAMCSN, create_dissector_handle(dissect_drda_pkgnamcsn, proto_drda));
3454
14
    dissector_add_uint("drda.opcode", DRDA_CP_UOWDSP, create_dissector_handle(dissect_drda_uowdsp, proto_drda));
3455
14
    dissector_add_uint("drda.opcode", DRDA_CP_RDBALWUPD, create_dissector_handle(dissect_drda_rdbalwupd, proto_drda));
3456
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYBLKSZ, create_dissector_handle(dissect_drda_qryblksz, proto_drda));
3457
14
    dissector_add_uint("drda.opcode", DRDA_CP_RTNSQLDA, create_dissector_handle(dissect_drda_rtnsqlda, proto_drda));
3458
14
    dissector_add_uint("drda.opcode", DRDA_CP_SQLCSRHLD, create_dissector_handle(dissect_drda_sqlcsrhld, proto_drda));
3459
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYEXTDTASZ, create_dissector_handle(dissect_drda_qryextdtasz, proto_drda));
3460
14
    dissector_add_uint("drda.opcode", DRDA_CP_SMLDTASZ, create_dissector_handle(dissect_drda_smldtasz, proto_drda));
3461
14
    dissector_add_uint("drda.opcode", DRDA_CP_MEDDTASZ, create_dissector_handle(dissect_drda_meddtasz, proto_drda));
3462
14
    dissector_add_uint("drda.opcode", DRDA_CP_TRGDFTRT, create_dissector_handle(dissect_drda_trgdftrt, proto_drda));
3463
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYATTUPD, create_dissector_handle(dissect_drda_qryattupd, proto_drda));
3464
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYROWSET, create_dissector_handle(dissect_drda_qryrowset, proto_drda));
3465
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYINSID, create_dissector_handle(dissect_drda_qryinsid, proto_drda));
3466
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYCLSIMP, create_dissector_handle(dissect_drda_qryclsimp, proto_drda));
3467
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYBLKFCT, create_dissector_handle(dissect_drda_qryblkfct, proto_drda));
3468
14
    dissector_add_uint("drda.opcode", DRDA_CP_MAXRSLCNT, create_dissector_handle(dissect_drda_maxrslcnt, proto_drda));
3469
14
    dissector_add_uint("drda.opcode", DRDA_CP_MAXBLKEXT, create_dissector_handle(dissect_drda_maxblkext, proto_drda));
3470
14
    dissector_add_uint("drda.opcode", DRDA_CP_RSLSETFLG, create_dissector_handle(dissect_drda_rslsetflg, proto_drda));
3471
14
    dissector_add_uint("drda.opcode", DRDA_CP_TYPSQLDA, create_dissector_handle(dissect_drda_typsqlda, proto_drda));
3472
14
    dissector_add_uint("drda.opcode", DRDA_CP_OUTOVROPT, create_dissector_handle(dissect_drda_outovropt, proto_drda));
3473
14
    dissector_add_uint("drda.opcode", DRDA_CP_DYNDTAFMT, create_dissector_handle(dissect_drda_dyndtafmt, proto_drda));
3474
3475
14
    dissector_add_uint("drda.opcode", DRDA_CP_PKTOBJ, create_dissector_handle(dissect_drda_pktobj, proto_drda));
3476
14
    dissector_add_uint("drda.opcode", DRDA_CP_SQLSTT, sqlstt_handle);
3477
14
    dissector_add_uint("drda.opcode", DRDA_CP_SQLATTR, sqlstt_handle);
3478
14
    dissector_add_uint("drda.opcode", DRDA_CP_SQLCARD, create_dissector_handle(dissect_drda_sqlcard, proto_drda));
3479
14
    dissector_add_uint("drda.opcode", DRDA_CP_SQLDARD, create_dissector_handle(dissect_drda_sqldard, proto_drda));
3480
14
    dissector_add_uint("drda.opcode", DRDA_CP_FDODSC, undecoded_handle);
3481
14
    dissector_add_uint("drda.opcode", DRDA_CP_FDODTA, undecoded_handle);
3482
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYDSC, undecoded_handle);
3483
14
    dissector_add_uint("drda.opcode", DRDA_CP_QRYDTA, undecoded_handle);
3484
14
}
3485
3486
/*
3487
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3488
 *
3489
 * Local variables:
3490
 * c-basic-offset: 4
3491
 * tab-width: 8
3492
 * indent-tabs-mode: nil
3493
 * End:
3494
 *
3495
 * vi: set shiftwidth=4 tabstop=8 expandtab:
3496
 * :indentSize=4:tabSize=8:noTabs=true:
3497
 */