3497 lines
134 KiB
C
3497 lines
134 KiB
C
/* packet-drda.c
|
|
* Routines for Distributed Relational Database Architecture packet dissection
|
|
*
|
|
* metatech <metatech@flashmail.com>
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
/* DRDA in a nutshell
|
|
*
|
|
* DRDA stands for Distributed Relational Database Architecture.
|
|
* It is a protocol between database client and database server published by
|
|
* the Open Group (www.opengroup.org) DDM (Distributed Data Management) is an
|
|
* data management interface which allows to exchange structured data between
|
|
* systems. DRDA is specific to relational databases and uses a subset of DDM
|
|
* to transport its data. The IBM DB2 product uses the DRDA protocol from
|
|
* version V8. Unless negotiated differently during the handshake, the fields
|
|
* of the DDM commands and reply messages are in EBCDIC.
|
|
*
|
|
* Documentation:
|
|
*
|
|
* DRDA Version 2, Volume 3: Distributed Data Management (DDM)
|
|
* Architecture, Open Group.
|
|
*
|
|
* https://pubs.opengroup.org/onlinepubs/009608699/toc.pdf
|
|
*
|
|
* DRDA Version 3, Volume 3: Distributed Data Management (DDM)
|
|
* Architecture Open Group.
|
|
* Version 3 is no longer available.
|
|
*
|
|
* DRDA Version 4, Volume 3: Distributed Data Management (DDM)
|
|
* Architecture, Open Group.
|
|
*
|
|
* https://pubs.opengroup.org/onlinepubs/9699939199/toc.pdf
|
|
*
|
|
* DRDA Version 5, Volume 3: Distributed Data Management (DDM)
|
|
* Architecture, Open Group.
|
|
*
|
|
* https://publications.opengroup.org/c114
|
|
*
|
|
* Reference for Remote DRDA Requesters and Servers, IBM.
|
|
*
|
|
* https://www-304.ibm.com/support/docview.wss?uid=pub1sc18985301
|
|
* (now dead)
|
|
* https://publibfp.boulder.ibm.com/epubs/pdf/dsnudh10.pdf
|
|
*
|
|
* Microsoft has some references that can be useful as well:
|
|
*
|
|
* https://learn.microsoft.com/en-us/dotnet/api/microsoft.hostintegration.drda.common?view=his-dotnet
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <epan/packet.h>
|
|
#include <epan/prefs.h>
|
|
#include <epan/expert.h>
|
|
#include <epan/iana_charsets.h>
|
|
#include <epan/proto_data.h>
|
|
#include "packet-tcp.h"
|
|
|
|
void proto_register_drda(void);
|
|
void proto_reg_handoff_drda(void);
|
|
|
|
static int proto_drda;
|
|
static int hf_drda_ddm_length;
|
|
static int hf_drda_ddm_magic;
|
|
static int hf_drda_ddm_format;
|
|
static int hf_drda_ddm_fmt_reserved;
|
|
static int hf_drda_ddm_fmt_chained;
|
|
static int hf_drda_ddm_fmt_errcont;
|
|
static int hf_drda_ddm_fmt_samecorr;
|
|
static int hf_drda_ddm_fmt_dsstyp;
|
|
static int hf_drda_ddm_rc;
|
|
static int hf_drda_ddm_length2;
|
|
static int hf_drda_ddm_codepoint;
|
|
static int hf_drda_param_length;
|
|
static int hf_drda_param_codepoint;
|
|
static int hf_drda_param_data;
|
|
static int hf_drda_param_data_ebcdic;
|
|
static int hf_drda_null_ind;
|
|
static int hf_drda_typdefnam;
|
|
static int hf_drda_clob_length;
|
|
static int hf_drda_sqlstatement;
|
|
static int hf_drda_sqlcagrp;
|
|
static int hf_drda_sqlcode;
|
|
static int hf_drda_sqlstate;
|
|
static int hf_drda_sqlerrproc;
|
|
static int hf_drda_sqlcaxgrp;
|
|
static int hf_drda_sqlerrd1;
|
|
static int hf_drda_sqlerrd2;
|
|
static int hf_drda_sqlerrd3;
|
|
static int hf_drda_sqlerrd4;
|
|
static int hf_drda_sqlerrd5;
|
|
static int hf_drda_sqlerrd6;
|
|
static int hf_drda_sqlwarn0;
|
|
static int hf_drda_sqlwarn1;
|
|
static int hf_drda_sqlwarn2;
|
|
static int hf_drda_sqlwarn3;
|
|
static int hf_drda_sqlwarn4;
|
|
static int hf_drda_sqlwarn5;
|
|
static int hf_drda_sqlwarn6;
|
|
static int hf_drda_sqlwarn7;
|
|
static int hf_drda_sqlwarn8;
|
|
static int hf_drda_sqlwarn9;
|
|
static int hf_drda_sqlwarna;
|
|
static int hf_drda_sqlerrmsg;
|
|
static int hf_drda_sqldhgrp;
|
|
static int hf_drda_sqldhold;
|
|
static int hf_drda_sqldreturn;
|
|
static int hf_drda_sqldscroll;
|
|
static int hf_drda_sqldsensitive;
|
|
static int hf_drda_sqldfcode;
|
|
static int hf_drda_sqldkeytype;
|
|
static int hf_drda_sqldoptlck;
|
|
static int hf_drda_sqldschema;
|
|
static int hf_drda_sqldmodule;
|
|
static int hf_drda_sqldagrp;
|
|
static int hf_drda_sqlprecision;
|
|
static int hf_drda_sqlscale;
|
|
static int hf_drda_sqllength;
|
|
static int hf_drda_sqllength32;
|
|
static int hf_drda_sqltype;
|
|
static int hf_drda_sqlarrextent;
|
|
static int hf_drda_sqldoptgrp;
|
|
static int hf_drda_sqlunnamed;
|
|
static int hf_drda_sqlname;
|
|
static int hf_drda_sqllabel;
|
|
static int hf_drda_sqlcomments;
|
|
static int hf_drda_sqludtgrp;
|
|
static int hf_drda_sqludtxtype;
|
|
static int hf_drda_sqludtschema;
|
|
static int hf_drda_sqludtname;
|
|
static int hf_drda_sqludtmodule;
|
|
static int hf_drda_sqldxgrp;
|
|
static int hf_drda_sqlxkeymem;
|
|
static int hf_drda_sqlxupdateable;
|
|
static int hf_drda_sqlxgenerated;
|
|
static int hf_drda_sqlxparmmode;
|
|
static int hf_drda_sqlxoptlck;
|
|
static int hf_drda_sqlxhidden;
|
|
static int hf_drda_sqlxcorname;
|
|
static int hf_drda_sqlxbasename;
|
|
static int hf_drda_sqlxschema;
|
|
static int hf_drda_sqlxname;
|
|
static int hf_drda_sqlxmodule;
|
|
static int hf_drda_sqldiaggrp;
|
|
static int hf_drda_sqlnum;
|
|
static int hf_drda_rlsconv;
|
|
static int hf_drda_secmec;
|
|
static int hf_drda_sectkn;
|
|
static int hf_drda_svrcod;
|
|
static int hf_drda_secchkcd;
|
|
static int hf_drda_ccsid;
|
|
static int hf_drda_mgrlvln;
|
|
static int hf_drda_monitor;
|
|
static int hf_drda_monitor_etime;
|
|
static int hf_drda_monitor_reserved;
|
|
static int hf_drda_etime;
|
|
static int hf_drda_respktsz;
|
|
static int hf_drda_rdbinttkn;
|
|
static int hf_drda_rdbcmtok;
|
|
static int hf_drda_rdbcolid;
|
|
static int hf_drda_rdbcolid_ebcdic;
|
|
static int hf_drda_pkgid;
|
|
static int hf_drda_pkgid_ebcdic;
|
|
static int hf_drda_pkgsn;
|
|
static int hf_drda_pkgcnstkn;
|
|
static int hf_drda_rtnsetstt;
|
|
static int hf_drda_rdbnam;
|
|
static int hf_drda_rdbnam_ebcdic;
|
|
static int hf_drda_outexp;
|
|
static int hf_drda_qryblksz;
|
|
static int hf_drda_uowdsp;
|
|
static int hf_drda_rdbalwupd;
|
|
static int hf_drda_sqlcsrhld;
|
|
static int hf_drda_qryextdtasz;
|
|
static int hf_drda_smldtasz;
|
|
static int hf_drda_meddtasz;
|
|
static int hf_drda_trgdftrt;
|
|
static int hf_drda_rtnsqlda;
|
|
static int hf_drda_qryattupd;
|
|
static int hf_drda_qryrowset;
|
|
static int hf_drda_qryinsid;
|
|
static int hf_drda_qryclsimp;
|
|
static int hf_drda_qryblkfct;
|
|
static int hf_drda_maxrslcnt;
|
|
static int hf_drda_maxblkext;
|
|
static int hf_drda_rslsetflg;
|
|
static int hf_drda_rslsetflg_unused;
|
|
static int hf_drda_rslsetflg_dsconly;
|
|
static int hf_drda_rslsetflg_extended;
|
|
static int hf_drda_rslsetflg_reserved;
|
|
static int hf_drda_typsqlda;
|
|
static int hf_drda_outovropt;
|
|
static int hf_drda_dyndtafmt;
|
|
static int hf_drda_pktobj;
|
|
|
|
static gint ett_drda;
|
|
static gint ett_drda_ddm;
|
|
static gint ett_drda_ddm_format;
|
|
static gint ett_drda_param;
|
|
static gint ett_drda_monitor;
|
|
static gint ett_drda_rslsetflg;
|
|
static gint ett_drda_sqlcagrp;
|
|
static gint ett_drda_sqlcaxgrp;
|
|
static gint ett_drda_sqldhgrp;
|
|
static gint ett_drda_sqldagrp;
|
|
static gint ett_drda_sqldoptgrp;
|
|
static gint ett_drda_sqludtgrp;
|
|
static gint ett_drda_sqldxgrp;
|
|
static gint ett_drda_sqldiaggrp;
|
|
|
|
static expert_field ei_drda_opcode_invalid_length;
|
|
static expert_field ei_drda_undecoded;
|
|
|
|
static dissector_handle_t drda_tcp_handle;
|
|
|
|
static dissector_table_t drda_opcode_table;
|
|
|
|
#define typdefnam_vals_ENUM_VAL_T_LIST(XXX) \
|
|
XXX(TYPDEFNAM_370, 1, "QTDSQL370", "System/390 SQL type definition") \
|
|
XXX(TYPDEFNAM_400, 2, "QTDSQL400", "AS/400 SQL type definition") \
|
|
XXX(TYPDEFNAM_X86, 3, "QTDSQLX86", "Intel 80x86 SQL type definition") \
|
|
XXX(TYPDEFNAM_ASC, 4, "QTDSQLASC", "General ASCII Big Endian SQL type definition") \
|
|
XXX(TYPDEFNAM_VAX, 5, "QTDSQLVAX", "DEC VAX SQL type definition")
|
|
|
|
typedef ENUM_VAL_T_ENUM(typdefnam_vals) enum_typdefnam_t;
|
|
|
|
ENUM_VAL_T_ARRAY_STATIC(typdefnam_vals);
|
|
|
|
/* Preferences */
|
|
static gboolean drda_desegment = TRUE;
|
|
static guint drda_default_sqlam = 7;
|
|
static gint drda_default_typdefnam = TYPDEFNAM_X86;
|
|
static gint drda_default_ccsidsbc = IANA_CS_UTF_8;
|
|
static gint drda_default_ccsidmbc = IANA_CS_UTF_8;
|
|
|
|
#define DRDA_MAGIC 0xD0
|
|
|
|
#define DRDA_CP_DATA 0x0000
|
|
#define DRDA_CP_CODPNT 0x000C
|
|
#define DRDA_CP_FDODSC 0x0010
|
|
#define DRDA_CP_TYPDEFNAM 0x002F
|
|
#define DRDA_CP_TYPDEFOVR 0x0035
|
|
#define DRDA_CP_CODPNTDR 0x0064
|
|
#define DRDA_CP_EXCSAT 0x1041
|
|
#define DRDA_CP_SYNCCTL 0x1055
|
|
#define DRDA_CP_SYNCRSY 0x1069
|
|
#define DRDA_CP_ACCSEC 0x106D
|
|
#define DRDA_CP_SECCHK 0x106E
|
|
#define DRDA_CP_SYNCLOG 0x106F
|
|
#define DRDA_CP_RSCTYP 0x111F
|
|
#define DRDA_CP_RSNCOD 0x1127
|
|
#define DRDA_CP_RSCNAM 0x112D
|
|
#define DRDA_CP_PRDID 0x112E
|
|
#define DRDA_CP_PRCCNVCD 0x113F
|
|
#define DRDA_CP_VRSNAM 0x1144
|
|
#define DRDA_CP_SRVCLSNM 0x1147
|
|
#define DRDA_CP_SVRCOD 0x1149
|
|
#define DRDA_CP_SYNERRCD 0x114A
|
|
#define DRDA_CP_SRVDGN 0x1153
|
|
#define DRDA_CP_SRVRLSLV 0x115A
|
|
#define DRDA_CP_SPVNAM 0x115D
|
|
#define DRDA_CP_EXTNAM 0x115E
|
|
#define DRDA_CP_SRVNAM 0x116D
|
|
#define DRDA_CP_SECMGRNM 0x1196
|
|
#define DRDA_CP_DEPERRCD 0x119B
|
|
#define DRDA_CP_CCSIDSBC 0x119C
|
|
#define DRDA_CP_CCSIDDBC 0x119D
|
|
#define DRDA_CP_CCSIDMBC 0x119E
|
|
#define DRDA_CP_RLSCONV 0x119F
|
|
#define DRDA_CP_USRID 0x11A0
|
|
#define DRDA_CP_PASSWORD 0x11A1
|
|
#define DRDA_CP_SECMEC 0x11A2
|
|
#define DRDA_CP_SECCHKCD 0x11A4
|
|
#define DRDA_CP_SVCERRNO 0x11B4
|
|
#define DRDA_CP_SECTKN 0x11DC
|
|
#define DRDA_CP_NEWPASSWORD 0x11DE
|
|
#define DRDA_CP_MGRLVLRM 0x1210
|
|
#define DRDA_CP_MGRDEPRM 0x1218
|
|
#define DRDA_CP_SECCHKRM 0x1219
|
|
#define DRDA_CP_CMDATHRM 0x121C
|
|
#define DRDA_CP_AGNPRMRM 0x1232
|
|
#define DRDA_CP_RSCLMTRM 0x1233
|
|
#define DRDA_CP_PRCCNVRM 0x1245
|
|
#define DRDA_CP_CMDCMPRM 0x124B
|
|
#define DRDA_CP_SYNTAXRM 0x124C
|
|
#define DRDA_CP_CMDNSPRM 0x1250
|
|
#define DRDA_CP_PRMNSPRM 0x1251
|
|
#define DRDA_CP_VALNSPRM 0x1252
|
|
#define DRDA_CP_OBJNSPRM 0x1253
|
|
#define DRDA_CP_CMDCHKRM 0x1254
|
|
#define DRDA_CP_TRGNSPRM 0x125F
|
|
#define DRDA_CP_AGENT 0x1403
|
|
#define DRDA_CP_MGRLVLLS 0x1404
|
|
#define DRDA_CP_SUPERVISOR 0x143C
|
|
#define DRDA_CP_SECMGR 0x1440
|
|
#define DRDA_CP_EXCSATRD 0x1443
|
|
#define DRDA_CP_CMNAPPC 0x1444
|
|
#define DRDA_CP_DICTIONARY 0x1458
|
|
#define DRDA_CP_MGRLVLN 0x1473
|
|
#define DRDA_CP_CMNTCPIP 0x1474
|
|
#define DRDA_CP_FDODTA 0x147A
|
|
#define DRDA_CP_CMNSYNCPT 0x147C
|
|
#define DRDA_CP_ACCSECRD 0x14AC
|
|
#define DRDA_CP_SYNCPTMGR 0x14C0
|
|
#define DRDA_CP_RSYNCMGR 0x14C1
|
|
#define DRDA_CP_CCSIDMGR 0x14CC
|
|
#define DRDA_CP_SNDPKT 0x1805
|
|
#define DRDA_CP_MONITOR 0x1900
|
|
#define DRDA_CP_ETIME 0x1901
|
|
#define DRDA_CP_RESPKTSZ 0x1908
|
|
#define DRDA_CP_CCSIDXML 0x1913
|
|
#define DRDA_CP_MONITORRD 0x1C00
|
|
#define DRDA_CP_XAMGR 0x1C01
|
|
#define DRDA_CP_PKTOBJ 0x1C04
|
|
#define DRDA_CP_UNICODEMGR 0x1C08
|
|
#define DRDA_CP_ACCRDB 0x2001
|
|
#define DRDA_CP_BGNBND 0x2002
|
|
#define DRDA_CP_BNDSQLSTT 0x2004
|
|
#define DRDA_CP_CLSQRY 0x2005
|
|
#define DRDA_CP_CNTQRY 0x2006
|
|
#define DRDA_CP_DRPPKG 0x2007
|
|
#define DRDA_CP_DSCSQLSTT 0x2008
|
|
#define DRDA_CP_ENDBND 0x2009
|
|
#define DRDA_CP_EXCSQLIMM 0x200A
|
|
#define DRDA_CP_EXCSQLSTT 0x200B
|
|
#define DRDA_CP_OPNQRY 0x200C
|
|
#define DRDA_CP_PRPSQLSTT 0x200D
|
|
#define DRDA_CP_RDBCMM 0x200E
|
|
#define DRDA_CP_RDBRLLBCK 0x200F
|
|
#define DRDA_CP_REBIND 0x2010
|
|
#define DRDA_CP_DSCRDBTBL 0x2012
|
|
#define DRDA_CP_EXCSQLSET 0x2014
|
|
#define DRDA_CP_DSCERRCD 0x2101
|
|
#define DRDA_CP_QRYPRCTYP 0x2102
|
|
#define DRDA_CP_RDBINTTKN 0x2103
|
|
#define DRDA_CP_PRDDTA 0x2104
|
|
#define DRDA_CP_RDBCMTOK 0x2105
|
|
#define DRDA_CP_RDBCOLID 0x2108
|
|
#define DRDA_CP_PKGID 0x2109
|
|
#define DRDA_CP_PKGNAM 0x210A
|
|
#define DRDA_CP_PKGSN 0x210C
|
|
#define DRDA_CP_PKGCNSTKN 0x210D
|
|
#define DRDA_CP_RTNSETSTT 0x210E
|
|
#define DRDA_CP_RDBACCCL 0x210F
|
|
#define DRDA_CP_RDBNAM 0x2110
|
|
#define DRDA_CP_OUTEXP 0x2111
|
|
#define DRDA_CP_PKGNAMCT 0x2112
|
|
#define DRDA_CP_PKGNAMCSN 0x2113
|
|
#define DRDA_CP_QRYBLKSZ 0x2114
|
|
#define DRDA_CP_UOWDSP 0x2115
|
|
#define DRDA_CP_RTNSQLDA 0x2116
|
|
#define DRDA_CP_RDBALWUPD 0x211A
|
|
#define DRDA_CP_SQLCSRHLD 0x211F
|
|
#define DRDA_CP_STTSTRDEL 0x2120
|
|
#define DRDA_CP_STTDECDEL 0x2121
|
|
#define DRDA_CP_PKGDFTCST 0x2125
|
|
#define DRDA_CP_QRYBLKCTL 0x2132
|
|
#define DRDA_CP_QRYEXTDTASZ 0x2134
|
|
#define DRDA_CP_CRRTKN 0x2135
|
|
#define DRDA_CP_SMLDTASZ 0x2136
|
|
#define DRDA_CP_MEDDTASZ 0x2137
|
|
#define DRDA_CP_PRCNAM 0x2138
|
|
#define DRDA_CP_PKGSNLST 0x2139
|
|
#define DRDA_CP_NBRROW 0x213A
|
|
#define DRDA_CP_TRGDFTRT 0x213B
|
|
#define DRDA_CP_QRYRELSCR 0x213C
|
|
#define DRDA_CP_QRYROWNBR 0x213D
|
|
#define DRDA_CP_QRYRFRTBL 0x213E
|
|
#define DRDA_CP_MAXRSLCNT 0x2140
|
|
#define DRDA_CP_MAXBLKEXT 0x2141
|
|
#define DRDA_CP_RSLSETFLG 0x2142
|
|
#define DRDA_CP_TYPSQLDA 0x2146
|
|
#define DRDA_CP_OUTOVROPT 0x2147
|
|
#define DRDA_CP_RTNEXTDTA 0x2148
|
|
#define DRDA_CP_QRYATTSCR 0x2149
|
|
#define DRDA_CP_DYNDTAFMT 0x214B
|
|
#define DRDA_CP_QRYATTUPD 0x2150
|
|
#define DRDA_CP_QRYSCRORN 0x2152
|
|
#define DRDA_CP_QRYROWSNS 0x2153
|
|
#define DRDA_CP_QRYBLKRST 0x2154
|
|
#define DRDA_CP_QRYRTNDTA 0x2155
|
|
#define DRDA_CP_QRYROWSET 0x2156
|
|
#define DRDA_CP_QRYATTSNS 0x2157
|
|
#define DRDA_CP_QRYINSID 0x215B
|
|
#define DRDA_CP_QRYCLSIMP 0x215D
|
|
#define DRDA_CP_QRYCLSRLS 0x215E
|
|
#define DRDA_CP_QRYBLKFCT 0x215F
|
|
#define DRDA_CP_DIAGLVL 0x2160
|
|
#define DRDA_CP_ACCRDBRM 0x2201
|
|
#define DRDA_CP_QRYNOPRM 0x2202
|
|
#define DRDA_CP_RDBNACRM 0x2204
|
|
#define DRDA_CP_OPNQRYRM 0x2205
|
|
#define DRDA_CP_PKGBNARM 0x2206
|
|
#define DRDA_CP_RDBACCRM 0x2207
|
|
#define DRDA_CP_BGNBNDRM 0x2208
|
|
#define DRDA_CP_PKGBPARM 0x2209
|
|
#define DRDA_CP_DSCINVRM 0x220A
|
|
#define DRDA_CP_ENDQRYRM 0x220B
|
|
#define DRDA_CP_ENDUOWRM 0x220C
|
|
#define DRDA_CP_ABNUOWRM 0x220D
|
|
#define DRDA_CP_DTAMCHRM 0x220E
|
|
#define DRDA_CP_QRYPOPRM 0x220F
|
|
#define DRDA_CP_RDBNFNRM 0x2211
|
|
#define DRDA_CP_OPNQFLRM 0x2212
|
|
#define DRDA_CP_SQLERRRM 0x2213
|
|
#define DRDA_CP_RDBUPDRM 0x2218
|
|
#define DRDA_CP_RSLSETRM 0x2219
|
|
#define DRDA_CP_RDBAFLRM 0x221A
|
|
#define DRDA_CP_CMDVLTRM 0x221D
|
|
#define DRDA_CP_CMMRQSRM 0x2225
|
|
#define DRDA_CP_RDBATHRM 0x22CB
|
|
#define DRDA_CP_SQLAM 0x2407
|
|
#define DRDA_CP_SQLCARD 0x2408
|
|
#define DRDA_CP_SQLCINRD 0x240B
|
|
#define DRDA_CP_SQLRSLRD 0x240E
|
|
#define DRDA_CP_RDB 0x240F
|
|
#define DRDA_CP_FRCFIXROW 0x2410
|
|
#define DRDA_CP_SQLDARD 0x2411
|
|
#define DRDA_CP_SQLDTA 0x2412
|
|
#define DRDA_CP_SQLDTARD 0x2413
|
|
#define DRDA_CP_SQLSTT 0x2414
|
|
#define DRDA_CP_OUTOVR 0x2415
|
|
#define DRDA_CP_LMTBLKPRC 0x2417
|
|
#define DRDA_CP_FIXROWPRC 0x2418
|
|
#define DRDA_CP_SQLSTTVRB 0x2419
|
|
#define DRDA_CP_QRYDSC 0x241A
|
|
#define DRDA_CP_QRYDTA 0x241B
|
|
#define DRDA_CP_CSTSYSDFT 0x2432
|
|
#define DRDA_CP_CSTBITS 0x2433
|
|
#define DRDA_CP_CSTSBCS 0x2434
|
|
#define DRDA_CP_CSTMBCS 0x2435
|
|
#define DRDA_CP_ISOLVLCHG 0x2441
|
|
#define DRDA_CP_ISOLVLCS 0x2442
|
|
#define DRDA_CP_ISOLVLALL 0x2443
|
|
#define DRDA_CP_ISOLVLRR 0x2444
|
|
#define DRDA_CP_ISOLVLNC 0x2445
|
|
#define DRDA_CP_SRVLST 0x244E
|
|
#define DRDA_CP_SQLATTR 0x2450
|
|
|
|
#define DRDA_DSSFMT_SAME_CORR 0x10
|
|
#define DRDA_DSSFMT_CONTINUE 0x20
|
|
#define DRDA_DSSFMT_CHAINED 0x40
|
|
#define DRDA_DSSFMT_RESERVED 0x80
|
|
|
|
#define DRDA_DSSFMT_RQSDSS 0x01
|
|
#define DRDA_DSSFMT_RPYDSS 0x02
|
|
#define DRDA_DSSFMT_OBJDSS 0x03
|
|
#define DRDA_DSSFMT_CMNDSS 0x04
|
|
#define DRDA_DSSFMT_NORPYDSS 0x05
|
|
|
|
#define DRDA_TEXT_DDM "DDM"
|
|
#define DRDA_TEXT_PARAM "Parameter"
|
|
|
|
static const value_string drda_opcode_vals[] = {
|
|
{ DRDA_CP_DATA, "Data" },
|
|
{ DRDA_CP_CODPNT, "Code Point" },
|
|
{ DRDA_CP_FDODSC, "FD:OCA Data Descriptor" },
|
|
{ DRDA_CP_TYPDEFNAM, "Data Type Definition Name" },
|
|
{ DRDA_CP_TYPDEFOVR, "TYPDEF Overrides" },
|
|
{ DRDA_CP_CODPNTDR, "Code Point Data Representation" },
|
|
{ DRDA_CP_EXCSAT, "Exchange Server Attributes" },
|
|
{ DRDA_CP_SYNCCTL, "Sync Point Control Request" },
|
|
{ DRDA_CP_SYNCRSY, "Sync Point Resync Command" },
|
|
{ DRDA_CP_ACCSEC, "Access Security" },
|
|
{ DRDA_CP_SECCHK, "Security Check" },
|
|
{ DRDA_CP_SYNCLOG, "Sync Point Log" },
|
|
{ DRDA_CP_RSCTYP, "Resource Type Information" },
|
|
{ DRDA_CP_RSNCOD, "Reason Code Information" },
|
|
{ DRDA_CP_RSCNAM, "Resource Name Information" },
|
|
{ DRDA_CP_PRDID, "Product-Specific Identifier" },
|
|
{ DRDA_CP_PRCCNVCD, "Conversation Protocol Error Code" },
|
|
{ DRDA_CP_VRSNAM, "Version Name" },
|
|
{ DRDA_CP_SRVCLSNM, "Server Class Name" },
|
|
{ DRDA_CP_SVRCOD, "Severity Code" },
|
|
{ DRDA_CP_SYNERRCD, "Syntax Error Code" },
|
|
{ DRDA_CP_SRVDGN, "Server Diagnostic Information" },
|
|
{ DRDA_CP_SRVRLSLV, "Server Product Release Level" },
|
|
{ DRDA_CP_SPVNAM, "Supervisor Name" },
|
|
{ DRDA_CP_EXTNAM, "External Name" },
|
|
{ DRDA_CP_SRVNAM, "Server Name" },
|
|
{ DRDA_CP_SECMGRNM, "Security Manager Name" },
|
|
{ DRDA_CP_DEPERRCD, "Manager Dependency Error Code" },
|
|
{ DRDA_CP_CCSIDSBC, "CCSID for Single-Byte Characters" },
|
|
{ DRDA_CP_CCSIDDBC, "CCSID for Double-byte Characters" },
|
|
{ DRDA_CP_CCSIDMBC, "CCSID for Mixed-byte Characters" },
|
|
{ DRDA_CP_RLSCONV, "Release Conversation" },
|
|
{ DRDA_CP_USRID, "User ID at the Target System" },
|
|
{ DRDA_CP_PASSWORD, "Password" },
|
|
{ DRDA_CP_SECMEC, "Security Mechanism" },
|
|
{ DRDA_CP_SECCHKCD, "Security Check Code" },
|
|
{ DRDA_CP_SVCERRNO, "Security Service ErrorNumber" },
|
|
{ DRDA_CP_SECTKN, "Security Token" },
|
|
{ DRDA_CP_NEWPASSWORD, "New Password" },
|
|
{ DRDA_CP_MGRLVLRM, "Manager-Level Conflict" },
|
|
{ DRDA_CP_MGRDEPRM, "Manager Dependency Error" },
|
|
{ DRDA_CP_SECCHKRM, "Security Check" },
|
|
{ DRDA_CP_CMDATHRM, "Not Authorized to Command" },
|
|
{ DRDA_CP_AGNPRMRM, "Permanent Agent Error" },
|
|
{ DRDA_CP_RSCLMTRM, "Resource Limits Reached" },
|
|
{ DRDA_CP_PRCCNVRM, "Conversational Protocol Error" },
|
|
{ DRDA_CP_CMDCMPRM, "Command Processing Completed" },
|
|
{ DRDA_CP_SYNTAXRM, "Data Stream Syntax Error" },
|
|
{ DRDA_CP_CMDNSPRM, "Command Not Supported" },
|
|
{ DRDA_CP_PRMNSPRM, "Parameter Not Supported" },
|
|
{ DRDA_CP_VALNSPRM, "Parameter Value Not Supported" },
|
|
{ DRDA_CP_OBJNSPRM, "Object Not Supported" },
|
|
{ DRDA_CP_CMDCHKRM, "Command Check" },
|
|
{ DRDA_CP_TRGNSPRM, "Target Not Supported" },
|
|
{ DRDA_CP_AGENT, "Agent" },
|
|
{ DRDA_CP_MGRLVLLS, "Manager-Level List" },
|
|
{ DRDA_CP_SUPERVISOR, "Supervisor" },
|
|
{ DRDA_CP_SECMGR, "Security Manager" },
|
|
{ DRDA_CP_EXCSATRD, "Server Attributes Reply Data" },
|
|
{ DRDA_CP_CMNAPPC, "LU 6.2 Conversational Communications Manager" },
|
|
{ DRDA_CP_DICTIONARY, "Dictionary" },
|
|
{ DRDA_CP_MGRLVLN, "Manager-Level Number Attribute" },
|
|
{ DRDA_CP_CMNTCPIP, "TCP/IP CommunicationManager" },
|
|
{ DRDA_CP_FDODTA, "FD:OCA Data" },
|
|
{ DRDA_CP_CMNSYNCPT,
|
|
"SNA LU 6.2 Sync Point Conversational Communications Manager" },
|
|
{ DRDA_CP_ACCSECRD, "Access Security Reply Data" },
|
|
{ DRDA_CP_SYNCPTMGR, "Sync Point Manager" },
|
|
{ DRDA_CP_RSYNCMGR, "ResynchronizationManager" },
|
|
{ DRDA_CP_CCSIDMGR, "CCSID Manager" },
|
|
{ DRDA_CP_SNDPKT, "Send Packet" },
|
|
{ DRDA_CP_MONITOR, "Monitor Events" },
|
|
{ DRDA_CP_ETIME, "Elapsed Time" },
|
|
{ DRDA_CP_RESPKTSZ, "Response Packet Size" },
|
|
{ DRDA_CP_CCSIDXML, "CCSID for External Encoded XML Strings" },
|
|
{ DRDA_CP_MONITORRD, "Monitor Reply Data" },
|
|
{ DRDA_CP_XAMGR, "XAManager" },
|
|
{ DRDA_CP_PKTOBJ, "Packet Object" },
|
|
{ DRDA_CP_UNICODEMGR, "Unicode Manager" },
|
|
{ DRDA_CP_ACCRDB, "Access RDB" },
|
|
{ DRDA_CP_BGNBND, "Begin Binding a Package to an RDB" },
|
|
{ DRDA_CP_BNDSQLSTT, "Bind SQL Statement to an RDB Package" },
|
|
{ DRDA_CP_CLSQRY, "Close Query" },
|
|
{ DRDA_CP_CNTQRY, "Continue Query" },
|
|
{ DRDA_CP_DRPPKG, "Drop RDB Package" },
|
|
{ DRDA_CP_DSCSQLSTT, "Describe SQL Statement" },
|
|
{ DRDA_CP_ENDBND, "End Binding a Package to an RDB" },
|
|
{ DRDA_CP_EXCSQLIMM, "Execute Immediate SQL Statement" },
|
|
{ DRDA_CP_EXCSQLSTT, "Execute SQL Statement" },
|
|
{ DRDA_CP_OPNQRY, "Open Query" },
|
|
{ DRDA_CP_PRPSQLSTT, "Prepare SQL Statement" },
|
|
{ DRDA_CP_RDBCMM, "RDB Commit Unit of Work" },
|
|
{ DRDA_CP_RDBRLLBCK, "RDB Rollback Unit of Work" },
|
|
{ DRDA_CP_REBIND, "Rebind an Existing RDB Package" },
|
|
{ DRDA_CP_DSCRDBTBL, "Describe RDB Table" },
|
|
{ DRDA_CP_EXCSQLSET, "Set SQL Environment" },
|
|
{ DRDA_CP_DSCERRCD, "Description Error Code" },
|
|
{ DRDA_CP_QRYPRCTYP, "Query Protocol Type" },
|
|
{ DRDA_CP_RDBINTTKN, "RDB Interrupt Token" },
|
|
{ DRDA_CP_PRDDTA, "Product-Specific Data" },
|
|
{ DRDA_CP_RDBCMTOK, "RDB Commit Allowed" },
|
|
{ DRDA_CP_RDBCOLID, "RDB Collection Identifier" },
|
|
{ DRDA_CP_PKGID, "RDB Package Identifier" },
|
|
{ DRDA_CP_PKGNAM, "RDB Package Name" },
|
|
{ DRDA_CP_PKGSN, "RDB Package Section Number" },
|
|
{ DRDA_CP_PKGCNSTKN, "RDB Package Consistency Token" },
|
|
{ DRDA_CP_RTNSETSTT, "Return SET Statement" },
|
|
{ DRDA_CP_RDBACCCL, "RDB Access Manager Class" },
|
|
{ DRDA_CP_RDBNAM, "Relational Database Name" },
|
|
{ DRDA_CP_OUTEXP, "Output Expected" },
|
|
{ DRDA_CP_PKGNAMCT, "RDB Package Name and Consistency Token" },
|
|
{ DRDA_CP_PKGNAMCSN,
|
|
"RDB Package Name, Consistency Token, and Section Number" },
|
|
{ DRDA_CP_QRYBLKSZ, "Query Block Size" },
|
|
{ DRDA_CP_UOWDSP, "Unit of Work Disposition" },
|
|
{ DRDA_CP_RTNSQLDA, "Maximum Result Set Count" },
|
|
{ DRDA_CP_RDBALWUPD, "RDB Allow Updates" },
|
|
{ DRDA_CP_SQLCSRHLD, "Hold Cursor Position" },
|
|
{ DRDA_CP_STTSTRDEL, "Statement String Delimiter" },
|
|
{ DRDA_CP_STTDECDEL, "Statement Decimal Delimiter" },
|
|
{ DRDA_CP_PKGDFTCST, "Package Default Character Subtype" },
|
|
{ DRDA_CP_QRYBLKCTL, "Query Block Protocol Control" },
|
|
{ DRDA_CP_QRYEXTDTASZ, "Query Externalized Data Size" },
|
|
{ DRDA_CP_CRRTKN, "Correlation Token" },
|
|
{ DRDA_CP_SMLDTASZ, "Maximum Size of Small Data" },
|
|
{ DRDA_CP_MEDDTASZ, "Maximum Size of Medium Data" },
|
|
{ DRDA_CP_PRCNAM, "Procedure Name" },
|
|
{ DRDA_CP_PKGSNLST, "RDB Result Set Reply Message" },
|
|
{ DRDA_CP_NBRROW, "Number of Fetch or Insert Rows" },
|
|
{ DRDA_CP_TRGDFTRT, "Target Default Value Return" },
|
|
{ DRDA_CP_QRYRELSCR, "Query Relative Scrolling Action" },
|
|
{ DRDA_CP_QRYROWNBR, "Query Row Number" },
|
|
{ DRDA_CP_QRYRFRTBL, "Query Refresh Answer Set Table" },
|
|
{ DRDA_CP_MAXRSLCNT, "Maximum Result Set Count" },
|
|
{ DRDA_CP_MAXBLKEXT, "Maximum Number of Extra Blocks" },
|
|
{ DRDA_CP_RSLSETFLG, "Result Set Flags" },
|
|
{ DRDA_CP_TYPSQLDA, "Type of SQL Descriptor Area" },
|
|
{ DRDA_CP_OUTOVROPT, "Output Override Option" },
|
|
{ DRDA_CP_RTNEXTDTA, "Return of EXTDTA Option" },
|
|
{ DRDA_CP_QRYATTSCR, "Query Attribute for Scrollability" },
|
|
{ DRDA_CP_DYNDTAFMT, "Dynamic Data Format" },
|
|
{ DRDA_CP_QRYATTUPD, "Query Attribute for Updatability" },
|
|
{ DRDA_CP_QRYSCRORN, "Query Scroll Orientation" },
|
|
{ DRDA_CP_QRYROWSNS, "Query Row Sensitivity" },
|
|
{ DRDA_CP_QRYBLKRST, "Query Block Reset" },
|
|
{ DRDA_CP_QRYRTNDTA, "Query Returns Datat" },
|
|
{ DRDA_CP_QRYROWSET, "Query Rowset Size" },
|
|
{ DRDA_CP_QRYATTSNS, "Query Attribute for Sensitivity" },
|
|
{ DRDA_CP_QRYINSID, "Query Instance Identifier" },
|
|
{ DRDA_CP_QRYCLSIMP, "Query Close Implicit" },
|
|
{ DRDA_CP_QRYCLSRLS, "Query Close Lock Release" },
|
|
{ DRDA_CP_QRYBLKFCT, "Query Blocking Factor" },
|
|
{ DRDA_CP_DIAGLVL, "SQL Error Diagnostic Level" },
|
|
{ DRDA_CP_ACCRDBRM, "Access to RDB Completed" },
|
|
{ DRDA_CP_QRYNOPRM, "Query Not Open" },
|
|
{ DRDA_CP_RDBNACRM, "RDB Not Accessed" },
|
|
{ DRDA_CP_OPNQRYRM, "Open Query Complete" },
|
|
{ DRDA_CP_PKGBNARM, "RDB Package Binding Not Active" },
|
|
{ DRDA_CP_RDBACCRM, "RDB Currently Accessed" },
|
|
{ DRDA_CP_BGNBNDRM, "Begin Bind Error" },
|
|
{ DRDA_CP_PKGBPARM, "RDB Package Binding Process Active" },
|
|
{ DRDA_CP_DSCINVRM, "Invalid Description" },
|
|
{ DRDA_CP_ENDQRYRM, "End of Query" },
|
|
{ DRDA_CP_ENDUOWRM, "End Unit of Work Condition" },
|
|
{ DRDA_CP_ABNUOWRM, "Abnormal End Unit ofWork Condition" },
|
|
{ DRDA_CP_DTAMCHRM, "Data Descriptor Mismatch" },
|
|
{ DRDA_CP_QRYPOPRM, "Query Previously Opened" },
|
|
{ DRDA_CP_RDBNFNRM, "RDB Not Found" },
|
|
{ DRDA_CP_OPNQFLRM, "Open Query Failure" },
|
|
{ DRDA_CP_SQLERRRM, "SQL Error Condition" },
|
|
{ DRDA_CP_RDBUPDRM, "RDB Update Reply Message" },
|
|
{ DRDA_CP_RSLSETRM, "RDB Result Set Reply Message" },
|
|
{ DRDA_CP_RDBAFLRM, "RDB Access Failed Reply Message" },
|
|
{ DRDA_CP_CMDVLTRM, "Command Violation" },
|
|
{ DRDA_CP_CMMRQSRM, "Commitment Request" },
|
|
{ DRDA_CP_RDBATHRM, "Not Authorized to RDB" },
|
|
{ DRDA_CP_SQLAM, "SQL Application Manager" },
|
|
{ DRDA_CP_SQLCARD, "SQL Communications Area Reply Data" },
|
|
{ DRDA_CP_SQLCINRD, "SQL Result Set Column Information Reply Data" },
|
|
{ DRDA_CP_SQLRSLRD, "SQL Result Set Reply Data" },
|
|
{ DRDA_CP_RDB, "Relational Database" },
|
|
{ DRDA_CP_FRCFIXROW, "Force Fixed Row Query Protocol" },
|
|
{ DRDA_CP_SQLDARD, "SQLDA Reply Data" },
|
|
{ DRDA_CP_SQLDTA, "SQL Program Variable Data" },
|
|
{ DRDA_CP_SQLDTARD, "SQL Data Reply Data" },
|
|
{ DRDA_CP_SQLSTT, "SQL Statement" },
|
|
{ DRDA_CP_OUTOVR, "Output Override Descriptor" },
|
|
{ DRDA_CP_LMTBLKPRC, "Limited Block Protocol" },
|
|
{ DRDA_CP_FIXROWPRC, "Fixed Row Query Protocol" },
|
|
{ DRDA_CP_SQLSTTVRB, "SQL Statement Variable Descriptions" },
|
|
{ DRDA_CP_QRYDSC, "Query Answer Set Description" },
|
|
{ DRDA_CP_QRYDTA, "Query Answer Set Data" },
|
|
{ DRDA_CP_CSTSYSDFT, "Character Subtype System Default" },
|
|
{ DRDA_CP_CSTBITS, "Character Subtype Bits" },
|
|
{ DRDA_CP_CSTSBCS, "Character Subtype SBCS" },
|
|
{ DRDA_CP_CSTMBCS, "Character Subtype MBCS" },
|
|
{ DRDA_CP_ISOLVLCHG, "Isolation Level Change" },
|
|
{ DRDA_CP_ISOLVLCS, "Isolation Level Cursor Stability" },
|
|
{ DRDA_CP_ISOLVLALL, "Isolation Level All" },
|
|
{ DRDA_CP_ISOLVLRR, "Isolation Level Repeatable Read" },
|
|
{ DRDA_CP_ISOLVLNC, "Isolation Level No Commit" },
|
|
{ DRDA_CP_SRVLST, "Server List" },
|
|
{ DRDA_CP_SQLATTR, "SQL Statement Attributes" },
|
|
{ 0, NULL }
|
|
};
|
|
static value_string_ext drda_opcode_vals_ext = VALUE_STRING_EXT_INIT(drda_opcode_vals);
|
|
|
|
static const value_string drda_opcode_abbr[] = {
|
|
{ DRDA_CP_DATA, "DATA" },
|
|
{ DRDA_CP_CODPNT, "CODPNT" },
|
|
{ DRDA_CP_FDODSC, "FDODSC" },
|
|
{ DRDA_CP_TYPDEFNAM, "TYPDEFNAM" },
|
|
{ DRDA_CP_TYPDEFOVR, "TYPDEFOVR" },
|
|
{ DRDA_CP_CODPNTDR, "CODPNTDR" },
|
|
{ DRDA_CP_EXCSAT, "EXCSAT" },
|
|
{ DRDA_CP_SYNCCTL, "SYNCCTL" },
|
|
{ DRDA_CP_SYNCRSY, "SYNCRSY" },
|
|
{ DRDA_CP_ACCSEC, "ACCSEC" },
|
|
{ DRDA_CP_SECCHK, "SECCHK" },
|
|
{ DRDA_CP_SYNCLOG, "SYNCLOG" },
|
|
{ DRDA_CP_RSCTYP, "RSCTYP" },
|
|
{ DRDA_CP_RSNCOD, "RSNCOD" },
|
|
{ DRDA_CP_RSCNAM, "RSCNAM" },
|
|
{ DRDA_CP_PRDID, "PRDID" },
|
|
{ DRDA_CP_PRCCNVCD, "PRCCNVCD" },
|
|
{ DRDA_CP_VRSNAM, "VRSNAM" },
|
|
{ DRDA_CP_SRVCLSNM, "SRVCLSNM" },
|
|
{ DRDA_CP_SVRCOD, "SVRCOD" },
|
|
{ DRDA_CP_SYNERRCD, "SYNERRCD" },
|
|
{ DRDA_CP_SRVDGN, "SRVDGN" },
|
|
{ DRDA_CP_SRVRLSLV, "SRVRLSLV" },
|
|
{ DRDA_CP_SPVNAM, "SPVNAM" },
|
|
{ DRDA_CP_EXTNAM, "EXTNAM" },
|
|
{ DRDA_CP_SRVNAM, "SRVNAM" },
|
|
{ DRDA_CP_SECMGRNM, "SECMGRNM" },
|
|
{ DRDA_CP_DEPERRCD, "DEPERRCD" },
|
|
{ DRDA_CP_CCSIDSBC, "CCSIDSBC" },
|
|
{ DRDA_CP_CCSIDDBC, "CCSIDDBC" },
|
|
{ DRDA_CP_CCSIDMBC, "CCSIDMBC" },
|
|
{ DRDA_CP_RLSCONV, "RLSCONV" },
|
|
{ DRDA_CP_USRID, "USRID" },
|
|
{ DRDA_CP_PASSWORD, "PASSWORD" },
|
|
{ DRDA_CP_SECMEC, "SECMEC" },
|
|
{ DRDA_CP_SECCHKCD, "SECCHKCD" },
|
|
{ DRDA_CP_SVCERRNO, "SVCERRNO" },
|
|
{ DRDA_CP_SECTKN, "SECTKN" },
|
|
{ DRDA_CP_NEWPASSWORD, "NEWPASSWORD" },
|
|
{ DRDA_CP_MGRLVLRM, "MGRLVLRM" },
|
|
{ DRDA_CP_MGRDEPRM, "MGRDEPRM" },
|
|
{ DRDA_CP_SECCHKRM, "SECCHKRM" },
|
|
{ DRDA_CP_CMDATHRM, "CMDATHRM" },
|
|
{ DRDA_CP_AGNPRMRM, "AGNPRMRM" },
|
|
{ DRDA_CP_RSCLMTRM, "RSCLMTRM" },
|
|
{ DRDA_CP_PRCCNVRM, "PRCCNVRM" },
|
|
{ DRDA_CP_CMDCMPRM, "CMDCMPRM" },
|
|
{ DRDA_CP_SYNTAXRM, "SYNTAXRM" },
|
|
{ DRDA_CP_CMDNSPRM, "CMDNSPRM" },
|
|
{ DRDA_CP_PRMNSPRM, "PRMNSPRM" },
|
|
{ DRDA_CP_VALNSPRM, "VALNSPRM" },
|
|
{ DRDA_CP_OBJNSPRM, "OBJNSPRM" },
|
|
{ DRDA_CP_CMDCHKRM, "CMDCHKRM" },
|
|
{ DRDA_CP_TRGNSPRM, "TRGNSPRM" },
|
|
{ DRDA_CP_AGENT, "AGENT" },
|
|
{ DRDA_CP_MGRLVLLS, "MGRLVLLS" },
|
|
{ DRDA_CP_SUPERVISOR, "SUPERVISOR" },
|
|
{ DRDA_CP_SECMGR, "SECMGR" },
|
|
{ DRDA_CP_EXCSATRD, "EXCSATRD" },
|
|
{ DRDA_CP_CMNAPPC, "CMNAPPC" },
|
|
{ DRDA_CP_DICTIONARY, "DICTIONARY" },
|
|
{ DRDA_CP_MGRLVLN, "MGRLVLN" },
|
|
{ DRDA_CP_CMNTCPIP, "CMNTCPIP" },
|
|
{ DRDA_CP_FDODTA, "FDODTA" },
|
|
{ DRDA_CP_CMNSYNCPT, "CMNSYNCPT" },
|
|
{ DRDA_CP_ACCSECRD, "ACCSECRD" },
|
|
{ DRDA_CP_SYNCPTMGR, "SYNCPTMGR" },
|
|
{ DRDA_CP_RSYNCMGR, "RSYNCMGR" },
|
|
{ DRDA_CP_CCSIDMGR, "CCSIDMGR" },
|
|
{ DRDA_CP_SNDPKT, "SNDPKT" },
|
|
{ DRDA_CP_MONITOR, "MONITOR" },
|
|
{ DRDA_CP_ETIME, "ETIME" },
|
|
{ DRDA_CP_RESPKTSZ, "RESPKTSZ" },
|
|
{ DRDA_CP_CCSIDXML, "CCSIDXML" },
|
|
{ DRDA_CP_MONITORRD, "MONITORRD" },
|
|
{ DRDA_CP_XAMGR, "XAMGR" },
|
|
{ DRDA_CP_PKTOBJ, "PKTOBJ" },
|
|
{ DRDA_CP_UNICODEMGR, "UNICODEMGR" },
|
|
{ DRDA_CP_ACCRDB, "ACCRDB" },
|
|
{ DRDA_CP_BGNBND, "BGNBND" },
|
|
{ DRDA_CP_BNDSQLSTT, "BNDSQLSTT" },
|
|
{ DRDA_CP_CLSQRY, "CLSQRY" },
|
|
{ DRDA_CP_CNTQRY, "CNTQRY" },
|
|
{ DRDA_CP_DRPPKG, "DRPPKG" },
|
|
{ DRDA_CP_DSCSQLSTT, "DSCSQLSTT" },
|
|
{ DRDA_CP_ENDBND, "ENDBND" },
|
|
{ DRDA_CP_EXCSQLIMM, "EXCSQLIMM" },
|
|
{ DRDA_CP_EXCSQLSTT, "EXCSQLSTT" },
|
|
{ DRDA_CP_OPNQRY, "OPNQRY" },
|
|
{ DRDA_CP_PRPSQLSTT, "PRPSQLSTT" },
|
|
{ DRDA_CP_RDBCMM, "RDBCMM" },
|
|
{ DRDA_CP_RDBRLLBCK, "RDBRLLBCK" },
|
|
{ DRDA_CP_REBIND, "REBIND" },
|
|
{ DRDA_CP_DSCRDBTBL, "DSCRDBTBL" },
|
|
{ DRDA_CP_EXCSQLSET, "EXCSQLSET" },
|
|
{ DRDA_CP_DSCERRCD, "DSCERRCD" },
|
|
{ DRDA_CP_QRYPRCTYP, "QRYPRCTYP" },
|
|
{ DRDA_CP_RDBINTTKN, "RDBINTTKN" },
|
|
{ DRDA_CP_PRDDTA, "PRDDTA" },
|
|
{ DRDA_CP_RDBCMTOK, "RDBCMTOK" },
|
|
{ DRDA_CP_RDBCOLID, "RDBCOLID" },
|
|
{ DRDA_CP_PKGID, "PKGID" },
|
|
{ DRDA_CP_PKGNAM, "PKGNAM" },
|
|
{ DRDA_CP_PKGSN, "PKGSN" },
|
|
{ DRDA_CP_PKGCNSTKN, "PKGCNSTKN" },
|
|
{ DRDA_CP_RTNSETSTT, "RTNSETSTT" },
|
|
{ DRDA_CP_RDBACCCL, "RDBACCCL" },
|
|
{ DRDA_CP_RDBNAM, "RDBNAM" },
|
|
{ DRDA_CP_OUTEXP, "OUTEXP" },
|
|
{ DRDA_CP_PKGNAMCT, "PKGNAMCT" },
|
|
{ DRDA_CP_PKGNAMCSN, "PKGNAMCSN" },
|
|
{ DRDA_CP_QRYBLKSZ, "QRYBLKSZ" },
|
|
{ DRDA_CP_UOWDSP, "UOWDSP" },
|
|
{ DRDA_CP_RTNSQLDA, "RTNSQLDA" },
|
|
{ DRDA_CP_RDBALWUPD, "RDBALWUPD" },
|
|
{ DRDA_CP_SQLCSRHLD, "SQLCSRHLD" },
|
|
{ DRDA_CP_STTSTRDEL, "STTSTRDEL" },
|
|
{ DRDA_CP_STTDECDEL, "STTDECDEL" },
|
|
{ DRDA_CP_PKGDFTCST, "PKGDFTCST" },
|
|
{ DRDA_CP_QRYBLKCTL, "QRYBLKCTL" },
|
|
{ DRDA_CP_QRYEXTDTASZ, "QRYEXTDTASZ" },
|
|
{ DRDA_CP_CRRTKN, "CRRTKN" },
|
|
{ DRDA_CP_SMLDTASZ, "SMLDTASZ" },
|
|
{ DRDA_CP_MEDDTASZ, "MEDDTASZ" },
|
|
{ DRDA_CP_PRCNAM, "PRCNAM" },
|
|
{ DRDA_CP_PKGSNLST, "PKGSNLST" },
|
|
{ DRDA_CP_NBRROW, "NBRROW" },
|
|
{ DRDA_CP_TRGDFTRT, "TRGDFTRT" },
|
|
{ DRDA_CP_QRYRELSCR, "QRYRELSCR" },
|
|
{ DRDA_CP_QRYROWNBR, "QRYROWNBR" },
|
|
{ DRDA_CP_QRYRFRTBL, "QRYRFRTBL" },
|
|
{ DRDA_CP_MAXRSLCNT, "MAXRSLCNT" },
|
|
{ DRDA_CP_MAXBLKEXT, "MAXBLKEXT" },
|
|
{ DRDA_CP_RSLSETFLG, "RSLSETFLG" },
|
|
{ DRDA_CP_TYPSQLDA, "TYPSQLDA" },
|
|
{ DRDA_CP_OUTOVROPT, "OUTOVROPT" },
|
|
{ DRDA_CP_RTNEXTDTA, "RTNEXTDTA" },
|
|
{ DRDA_CP_QRYATTSCR, "QRYATTSCR" },
|
|
{ DRDA_CP_DYNDTAFMT, "DYNDTAFMT" },
|
|
{ DRDA_CP_QRYATTUPD, "QRYATTUPD" },
|
|
{ DRDA_CP_QRYSCRORN, "QRYSCRORN" },
|
|
{ DRDA_CP_QRYROWSNS, "QRYROWSNS" },
|
|
{ DRDA_CP_QRYBLKRST, "QRYBLKRST" },
|
|
{ DRDA_CP_QRYRTNDTA, "QRYRTNDTA" },
|
|
{ DRDA_CP_QRYROWSET, "QRYROWSET" },
|
|
{ DRDA_CP_QRYATTSNS, "QRYATTSNS" },
|
|
{ DRDA_CP_QRYINSID, "QRYINSID" },
|
|
{ DRDA_CP_QRYCLSIMP, "QRYCLSIMP" },
|
|
{ DRDA_CP_QRYCLSRLS, "QRYCLSRLS" },
|
|
{ DRDA_CP_QRYBLKFCT, "QRYBLKFCT" },
|
|
{ DRDA_CP_DIAGLVL, "DIAGLVL" },
|
|
{ DRDA_CP_ACCRDBRM, "ACCRDBRM" },
|
|
{ DRDA_CP_QRYNOPRM, "QRYNOPRM" },
|
|
{ DRDA_CP_RDBNACRM, "RDBNACRM" },
|
|
{ DRDA_CP_OPNQRYRM, "OPNQRYRM" },
|
|
{ DRDA_CP_PKGBNARM, "PKGBNARM" },
|
|
{ DRDA_CP_RDBACCRM, "RDBACCRM" },
|
|
{ DRDA_CP_BGNBNDRM, "BGNBNDRM" },
|
|
{ DRDA_CP_PKGBPARM, "PKGBPARM" },
|
|
{ DRDA_CP_DSCINVRM, "DSCINVRM" },
|
|
{ DRDA_CP_ENDQRYRM, "ENDQRYRM" },
|
|
{ DRDA_CP_ENDUOWRM, "ENDUOWRM" },
|
|
{ DRDA_CP_ABNUOWRM, "ABNUOWRM" },
|
|
{ DRDA_CP_DTAMCHRM, "DTAMCHRM" },
|
|
{ DRDA_CP_QRYPOPRM, "QRYPOPRM" },
|
|
{ DRDA_CP_RDBNFNRM, "RDBNFNRM" },
|
|
{ DRDA_CP_OPNQFLRM, "OPNQFLRM" },
|
|
{ DRDA_CP_SQLERRRM, "SQLERRRM" },
|
|
{ DRDA_CP_RDBUPDRM, "RDBUPDRM" },
|
|
{ DRDA_CP_RSLSETRM, "RSLSETRM" },
|
|
{ DRDA_CP_RDBAFLRM, "RDBAFLRM" },
|
|
{ DRDA_CP_CMDVLTRM, "CMDVLTRM" },
|
|
{ DRDA_CP_CMMRQSRM, "CMMRQSRM" },
|
|
{ DRDA_CP_RDBATHRM, "RDBATHRM" },
|
|
{ DRDA_CP_SQLAM, "SQLAM" },
|
|
{ DRDA_CP_SQLCARD, "SQLCARD" },
|
|
{ DRDA_CP_SQLCINRD, "SQLCINRD" },
|
|
{ DRDA_CP_SQLRSLRD, "SQLRSLRD" },
|
|
{ DRDA_CP_RDB, "RDB" },
|
|
{ DRDA_CP_FRCFIXROW, "FRCFIXROW" },
|
|
{ DRDA_CP_SQLDARD, "SQLDARD" },
|
|
{ DRDA_CP_SQLDTA, "SQLDTA" },
|
|
{ DRDA_CP_SQLDTARD, "SQLDTARD" },
|
|
{ DRDA_CP_SQLSTT, "SQLSTT" },
|
|
{ DRDA_CP_OUTOVR, "OUTOVR" },
|
|
{ DRDA_CP_LMTBLKPRC, "LMTBLKPRC" },
|
|
{ DRDA_CP_FIXROWPRC, "FIXROWPRC" },
|
|
{ DRDA_CP_SQLSTTVRB, "SQLSTTVRB" },
|
|
{ DRDA_CP_QRYDSC, "QRYDSC" },
|
|
{ DRDA_CP_QRYDTA, "QRYDTA" },
|
|
{ DRDA_CP_CSTSYSDFT, "CSTSYSDFT" },
|
|
{ DRDA_CP_CSTBITS, "CSTBITS" },
|
|
{ DRDA_CP_CSTSBCS, "CSTSBCS" },
|
|
{ DRDA_CP_CSTMBCS, "CSTMBCS" },
|
|
{ DRDA_CP_ISOLVLCHG, "ISOLVLCHG" },
|
|
{ DRDA_CP_ISOLVLCS, "ISOLVLCS" },
|
|
{ DRDA_CP_ISOLVLALL, "ISOLVLALL" },
|
|
{ DRDA_CP_ISOLVLRR, "ISOLVLRR" },
|
|
{ DRDA_CP_ISOLVLNC, "ISOLVLNC" },
|
|
{ DRDA_CP_SRVLST, "SRVLST" },
|
|
{ DRDA_CP_SQLATTR, "SQLATTR" },
|
|
{ 0, NULL }
|
|
};
|
|
static value_string_ext drda_opcode_abbr_ext = VALUE_STRING_EXT_INIT(drda_opcode_abbr);
|
|
|
|
static const value_string drda_dsstyp_abbr[] = {
|
|
{ DRDA_DSSFMT_RQSDSS, "RQSDSS" },
|
|
{ DRDA_DSSFMT_RPYDSS, "RPYDSS" },
|
|
{ DRDA_DSSFMT_OBJDSS, "OBJDSS" },
|
|
{ DRDA_DSSFMT_CMNDSS, "CMNDSS" },
|
|
{ DRDA_DSSFMT_NORPYDSS, "NORPYDSS" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_boolean_vals[] = {
|
|
{ 0xF0, "FALSE" }, /* \xf0 - EBCDIC '0' */
|
|
{ 0xF1, "TRUE" }, /* \xf1 - EBCDIC '1' */
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_max_vals[] =
|
|
{
|
|
{ -1, "Unlimited"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const range_string drda_null_ind_rvals[] =
|
|
{
|
|
{ 0x00, 0x00, "Complete data value follows" },
|
|
{ 0x01, 0x7F, "Truncation has occurred (should not occur in DRDA)" },
|
|
{ 0x80, 0xFD, "Reserved; no data value follows" },
|
|
{ 0xFE, 0xFE, "Undefined result; no data value follows" },
|
|
{ 0xFF, 0xFF, "NULL; no data value follows" },
|
|
{ 0, 0, NULL },
|
|
};
|
|
|
|
typedef struct _drda_encoding_t {
|
|
enum_typdefnam_t typdefnam;
|
|
guint sbc;
|
|
guint mbc;
|
|
} drda_encoding_t;
|
|
|
|
typedef struct _drda_flow_t {
|
|
wmem_tree_t* encoding_tree;
|
|
wmem_tree_t* sqlam_tree;
|
|
} drda_flow_t;
|
|
|
|
typedef struct _drda_conv_info_t {
|
|
drda_flow_t *client; /* AKA source system */
|
|
drda_flow_t *server; /* AKA target system */
|
|
|
|
address srv_addr;
|
|
port_type srv_ptype;
|
|
guint srv_port;
|
|
} drda_conv_info_t;
|
|
|
|
typedef struct _drda_pdu_info_t {
|
|
guint sqlam;
|
|
enum_typdefnam_t typdefnam;
|
|
guint sbc;
|
|
guint mbc;
|
|
} drda_pdu_info_t;
|
|
|
|
static drda_flow_t*
|
|
drda_new_flow(wmem_allocator_t *alloc, packet_info *pinfo)
|
|
{
|
|
drda_flow_t *new_flow = wmem_new(alloc, drda_flow_t);
|
|
|
|
new_flow->encoding_tree = wmem_tree_new(alloc);
|
|
new_flow->sqlam_tree = wmem_tree_new(alloc);
|
|
wmem_tree_insert32(new_flow->sqlam_tree, pinfo->num, GUINT_TO_POINTER(drda_default_sqlam));
|
|
|
|
return new_flow;
|
|
}
|
|
|
|
static void
|
|
drda_update_flow_encoding(packet_info *pinfo, drda_flow_t *flow, const drda_pdu_info_t *pdu_info)
|
|
{
|
|
drda_encoding_t *encoding = wmem_tree_lookup32_le(flow->encoding_tree, pinfo->num);
|
|
if (encoding) {
|
|
if (encoding->typdefnam == pdu_info->typdefnam && encoding->sbc == pdu_info->sbc && encoding->mbc == pdu_info->mbc) {
|
|
return;
|
|
}
|
|
}
|
|
encoding = wmem_new(wmem_file_scope(), drda_encoding_t);
|
|
encoding->mbc = pdu_info->mbc;
|
|
encoding->sbc = pdu_info->sbc;
|
|
encoding->typdefnam = pdu_info->typdefnam;
|
|
wmem_tree_insert32(flow->encoding_tree, pinfo->num, encoding);
|
|
}
|
|
|
|
static drda_conv_info_t*
|
|
drda_get_conv_info(packet_info *pinfo)
|
|
{
|
|
conversation_t *conv = find_or_create_conversation(pinfo);
|
|
drda_conv_info_t *conv_info = conversation_get_proto_data(conv, proto_drda);
|
|
|
|
if (conv_info == NULL) {
|
|
conv_info = wmem_new0(wmem_file_scope(), drda_conv_info_t);
|
|
|
|
conv_info->client = drda_new_flow(wmem_file_scope(), pinfo);
|
|
conv_info->server = drda_new_flow(wmem_file_scope(), pinfo);
|
|
|
|
conversation_add_proto_data(conv, proto_drda, conv_info);
|
|
}
|
|
return conv_info;
|
|
}
|
|
|
|
static drda_pdu_info_t*
|
|
drda_get_pdu_info(packet_info *pinfo, guint32 correl, gboolean is_server)
|
|
{
|
|
drda_pdu_info_t *pdu_info;
|
|
|
|
/* "When the TYPDEFNAM object is specified as a command/reply data object,
|
|
* the value specified applies to the following command data objects and
|
|
* reply data objects for that command, respectively. When TYPDEFNAM is
|
|
* repeatable, the value of one TYPDEFNAM object is applicable only to
|
|
* those objects (command data or reply data) that are sent before another
|
|
* TYPDEFNAM object is sent. The value of TYPDEFNAM that a command
|
|
* specifies is in effect only for that command. This rule applies to all
|
|
* commands, unless specified otherwise." Similar for TYPDEFOVR.
|
|
*
|
|
* This means that encoding values are initialized to those set for the
|
|
* given direction for entire conversation by ACCRDB[RM] for each
|
|
* frame, or for each time the correlation ID changes (representing
|
|
* a different command; shared correlation IDs in a frame (after
|
|
* desegmentation, if needed) are data objects for the same command.)
|
|
*/
|
|
pdu_info = p_get_proto_data(pinfo->pool, pinfo, proto_drda, correl);
|
|
|
|
if (!pdu_info) {
|
|
pdu_info = wmem_new(pinfo->pool, drda_pdu_info_t);
|
|
drda_conv_info_t *conv_info = drda_get_conv_info(pinfo);
|
|
drda_flow_t *flow = is_server ? conv_info->server : conv_info->client;
|
|
pdu_info->sqlam = GPOINTER_TO_UINT(wmem_tree_lookup32_le(flow->sqlam_tree, pinfo->num));
|
|
drda_encoding_t *encoding = wmem_tree_lookup32_le(flow->encoding_tree, pinfo->num);
|
|
if (encoding) {
|
|
pdu_info->typdefnam = encoding->typdefnam;
|
|
pdu_info->sbc = encoding->sbc;
|
|
pdu_info->mbc = encoding->mbc;
|
|
} else {
|
|
pdu_info->typdefnam = drda_default_typdefnam;
|
|
pdu_info->sbc = mibenum_charset_to_encoding((guint)drda_default_ccsidsbc);
|
|
pdu_info->mbc = mibenum_charset_to_encoding((guint)drda_default_ccsidmbc);
|
|
}
|
|
|
|
p_set_proto_data(pinfo->pool, pinfo, proto_drda, correl, pdu_info);
|
|
}
|
|
|
|
|
|
return pdu_info;
|
|
}
|
|
|
|
static void
|
|
drda_set_server(drda_conv_info_t *conv_info, address *addr, port_type ptype, guint32 port)
|
|
{
|
|
copy_address_wmem(wmem_file_scope(), &conv_info->srv_addr, addr);
|
|
conv_info->srv_ptype = ptype;
|
|
conv_info->srv_port = port;
|
|
}
|
|
|
|
static gboolean
|
|
drda_packet_from_server(packet_info *pinfo, guint32 command, guint8 dsstyp)
|
|
{
|
|
drda_conv_info_t *conv_info = drda_get_conv_info(pinfo);
|
|
if (conv_info->srv_addr.type != AT_NONE) {
|
|
return (conv_info->srv_ptype == pinfo->ptype) &&
|
|
(conv_info->srv_port == pinfo->srcport) &&
|
|
addresses_equal(&conv_info->srv_addr, &pinfo->src);
|
|
}
|
|
switch (command) {
|
|
case DRDA_CP_EXCSAT:
|
|
case DRDA_CP_ACCRDB:
|
|
/* Client */
|
|
drda_set_server(conv_info, &pinfo->dst, pinfo->ptype, pinfo->destport);
|
|
return FALSE;
|
|
|
|
case DRDA_CP_EXCSATRD:
|
|
case DRDA_CP_ACCRDBRM:
|
|
/* Server (EXCSATRD is OBJDSS, which itself is inconclusive.) */
|
|
drda_set_server(conv_info, &pinfo->src, pinfo->ptype, pinfo->srcport);
|
|
return TRUE;
|
|
|
|
}
|
|
/* The above commands are the ones that matter the most for determining
|
|
* direction.
|
|
*/
|
|
switch (dsstyp) {
|
|
case DRDA_DSSFMT_RQSDSS:
|
|
case DRDA_DSSFMT_NORPYDSS:
|
|
drda_set_server(conv_info, &pinfo->dst, pinfo->ptype, pinfo->destport);
|
|
return FALSE;
|
|
|
|
case DRDA_DSSFMT_RPYDSS:
|
|
drda_set_server(conv_info, &pinfo->src, pinfo->ptype, pinfo->srcport);
|
|
return TRUE;
|
|
|
|
default:
|
|
/* We will be using the default values from the prefs anyway, since
|
|
* this means we won't have received ACCRDB[RM] yet.
|
|
*/
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static int
|
|
dissect_fdoca_integer(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset,int length, const drda_pdu_info_t *pdu_info, guint32 *value)
|
|
{
|
|
guint endian;
|
|
switch (pdu_info->typdefnam) {
|
|
case TYPDEFNAM_370:
|
|
case TYPDEFNAM_400:
|
|
case TYPDEFNAM_ASC:
|
|
endian = ENC_BIG_ENDIAN;
|
|
break;
|
|
case TYPDEFNAM_X86:
|
|
case TYPDEFNAM_VAX:
|
|
default:
|
|
endian = ENC_LITTLE_ENDIAN;
|
|
break;
|
|
}
|
|
proto_tree_add_item_ret_int(tree, hf_index, tvb, offset, length, endian, value);
|
|
return offset + length;
|
|
}
|
|
|
|
static int
|
|
dissect_fdoca_integer64(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset,int length, const drda_pdu_info_t *pdu_info, guint64 *value)
|
|
{
|
|
guint endian;
|
|
switch (pdu_info->typdefnam) {
|
|
case TYPDEFNAM_370:
|
|
case TYPDEFNAM_400:
|
|
case TYPDEFNAM_ASC:
|
|
endian = ENC_BIG_ENDIAN;
|
|
break;
|
|
case TYPDEFNAM_X86:
|
|
case TYPDEFNAM_VAX:
|
|
default:
|
|
endian = ENC_LITTLE_ENDIAN;
|
|
break;
|
|
}
|
|
proto_tree_add_item_ret_int64(tree, hf_index, tvb, offset, length, endian, value);
|
|
return offset + length;
|
|
}
|
|
|
|
static int
|
|
dissect_fdoca_fcs(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, int length, const drda_pdu_info_t *pdu_info)
|
|
{
|
|
proto_tree_add_item(tree, hf_index, tvb, offset, length, pdu_info->sbc);
|
|
return offset + length;
|
|
}
|
|
|
|
static int
|
|
dissect_fdoca_vcs(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, const drda_pdu_info_t *pdu_info)
|
|
{
|
|
guint32 item_len;
|
|
proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &item_len);
|
|
offset += 2;
|
|
proto_tree_add_item(tree, hf_index, tvb, offset, item_len, pdu_info->sbc);
|
|
return offset + (int)item_len;
|
|
}
|
|
|
|
static int
|
|
dissect_fdoca_vcm(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, const drda_pdu_info_t *pdu_info)
|
|
{
|
|
guint32 item_len;
|
|
proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &item_len);
|
|
offset += 2;
|
|
proto_tree_add_item(tree, hf_index, tvb, offset, item_len, pdu_info->mbc);
|
|
return offset + (int)item_len;
|
|
}
|
|
|
|
static int
|
|
dissect_fdoca_nocs(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, const drda_pdu_info_t *pdu_info)
|
|
{
|
|
guint32 null_ind, item_length;
|
|
proto_tree_add_item_ret_uint(tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
proto_tree_add_item_ret_uint(tree, hf_drda_clob_length, tvb, offset, 4, ENC_BIG_ENDIAN, &item_length);
|
|
offset += 4;
|
|
proto_tree_add_item(tree, hf_index, tvb, offset, item_length, pdu_info->sbc);
|
|
offset += item_length;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_fdoca_nocm(proto_tree *tree, int hf_index, tvbuff_t *tvb, int offset, const drda_pdu_info_t *pdu_info)
|
|
{
|
|
guint32 null_ind, item_length;
|
|
proto_tree_add_item_ret_uint(tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
proto_tree_add_item_ret_uint(tree, hf_drda_clob_length, tvb, offset, 4, ENC_BIG_ENDIAN, &item_length);
|
|
offset += 4;
|
|
proto_tree_add_item(tree, hf_index, tvb, offset, item_length, pdu_info->mbc);
|
|
offset += item_length;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_typdefnam(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
|
{
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
const guint8 *typdefnam;
|
|
|
|
proto_tree_add_item_ret_string(tree, hf_drda_typdefnam, tvb, 0, tvb_reported_length(tvb), ENC_UTF_8, pinfo->pool, &typdefnam);
|
|
for (int i = 0; typdefnam_vals[i].name != NULL; i++) {
|
|
if (strcmp(typdefnam_vals[i].name, typdefnam) == 0) {
|
|
pdu_info->typdefnam = typdefnam_vals[i].value;
|
|
break;
|
|
}
|
|
}
|
|
proto_tree_add_item_ret_string(tree, hf_drda_typdefnam, tvb, 0, tvb_reported_length(tvb), ENC_EBCDIC_CP500, pinfo->pool, &typdefnam);
|
|
for (int i = 0; typdefnam_vals[i].name != NULL; i++) {
|
|
if (strcmp(typdefnam_vals[i].name, typdefnam) == 0) {
|
|
pdu_info->typdefnam = typdefnam_vals[i].value;
|
|
break;
|
|
}
|
|
}
|
|
return tvb_reported_length(tvb);
|
|
}
|
|
|
|
static int
|
|
dissect_drda_sqlstt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
|
|
int offset = 0;
|
|
|
|
guint32 sqlstt_length;
|
|
|
|
/* If SECMGR is Level 6 and higher, it's possible to select a SECMEC
|
|
* that means that the security-sensitive DDM/FD:OCA objects are encrypted.
|
|
* They are SQLDTA, SQLDTARD, SQLSTT, SQLDARD, SQLATTR, SQLCINRD,
|
|
* SQLRSLRD, SQLSTTVRB, QRYDTA, EXTDTA, and SECTKNOVR.
|
|
* XXX: We don't handle the encryption, and we don't handle looking at
|
|
* the SECMEC to see if they are encrypted.
|
|
*/
|
|
|
|
/* From the DRDA Specification Volume 1, 1.1 The DRDA Reference
|
|
* (Version 4 and later):
|
|
* Greater than 32,767 Byte SQL Statements
|
|
* "Existing early descriptor character fields are mapped to a Variable
|
|
* Character Mixed or a Variable Character SBCS which allow a maximum of
|
|
* 32,767 bytes. SQL Statements described by the SQL Statement Group use
|
|
* these character fields. To allow SQL Statements to extend beyond the 32K
|
|
* limit, SQL statements are changed to map to nullable Large Character
|
|
* Objects Mixed and nullable Large Character Objects SBCS to allow for
|
|
* very large SQL Statements."
|
|
*
|
|
* In other words, it changed from a pair of non nullable LONG VARCHARs
|
|
* to a pair of nullable CLOBs, meaning that each string gained a
|
|
* null indicator byte and the length field grew from 2 to 4 bytes.
|
|
*
|
|
* This requires SQLAM Level 7 on both client & server, as sent in the
|
|
* MGRLVLLS in the EXCSATRD.
|
|
*
|
|
* We can cheat a bit because we can tell which one it is by
|
|
* inspection (assuming valid data), so we don't have to check
|
|
* pdu_info->sqlam
|
|
*/
|
|
|
|
sqlstt_length = tvb_get_ntohs(tvb, offset);
|
|
if (sqlstt_length == 0) {
|
|
sqlstt_length = tvb_get_ntohs(tvb, offset + 2);
|
|
}
|
|
if (sqlstt_length + 4 == tvb_reported_length(tvb)) {
|
|
/* pdu_info->sqlam < 7 */
|
|
offset = dissect_fdoca_vcm(tree, hf_drda_sqlstatement, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(tree, hf_drda_sqlstatement, tvb, offset, pdu_info);
|
|
} else {
|
|
offset = dissect_fdoca_nocm(tree, hf_drda_sqlstatement, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_nocs(tree, hf_drda_sqlstatement, tvb, offset, pdu_info);
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_sqldiaggrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_item *ti;
|
|
proto_tree *subtree;
|
|
int offset = 0;
|
|
|
|
guint32 null_ind;
|
|
|
|
ti = proto_tree_add_item(tree, hf_drda_sqldiaggrp, tvb, offset, 1, ENC_NA);
|
|
subtree = proto_item_add_subtree(ti, ett_drda_sqldiaggrp);
|
|
proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
proto_tree_add_expert(subtree, pinfo, &ei_drda_undecoded, tvb, offset, 2);
|
|
}
|
|
proto_item_set_end(ti, tvb, offset);
|
|
return offset;
|
|
}
|
|
|
|
static const value_string drda_udtxtype_vals[] = {
|
|
|
|
{ 0, "Not a UDT" },
|
|
{ 1, "Distinct type" },
|
|
{ 2, "Structured type" },
|
|
{ 3, "Reference type" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static int
|
|
dissect_drda_sqludtgrp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
|
|
{
|
|
proto_item *ti;
|
|
proto_tree *subtree;
|
|
int offset = 0;
|
|
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
guint32 null_ind;
|
|
|
|
ti = proto_tree_add_item(tree, hf_drda_sqludtgrp, tvb, offset, 1, ENC_NA);
|
|
subtree = proto_item_add_subtree(ti, ett_drda_sqludtgrp);
|
|
proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
if (pdu_info->sqlam > 6) {
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqludtxtype, tvb, offset, 4, pdu_info, NULL);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_rdbnam, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqludtschema, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqludtschema, tvb, offset, pdu_info);
|
|
}
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqludtname, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqludtname, tvb, offset, pdu_info);
|
|
if (pdu_info->sqlam >= 10) {
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqludtmodule, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqludtmodule, tvb, offset, pdu_info);
|
|
}
|
|
}
|
|
proto_item_set_end(ti, tvb, offset);
|
|
return offset;
|
|
}
|
|
|
|
static const value_string drda_keymem_vals[] = {
|
|
{ 0, "Not a member of the primary key or of a unique index" },
|
|
{ 1, "Member of the primary key or of a unique index" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_updateable_vals[] = {
|
|
{ 0, "Not updateable" },
|
|
{ 1, "Updateable" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_generated_vals[] = {
|
|
{ 0, "None of the other values of this field apply" },
|
|
{ 1, "Data for this column is always generated using an expression" },
|
|
{ 2, "Data for this identity column is always generated" },
|
|
{ 3, "Data for this ROWID column is always generated" },
|
|
{ 4, "Data for this identity column is generated by default" },
|
|
{ 5, "Data for this ROWID column is generated by default" },
|
|
{ 6, "Data for this row change timestamp column is always generated" },
|
|
{ 7, "Data for this row change timestamp column is generated by default" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_parmmode_vals[] = {
|
|
{ 0, "Not for use with a CALL statement" },
|
|
{ 1, "Input-only parameter" },
|
|
{ 2, "Input and output parameter" },
|
|
{ 4, "Output-only parameter" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_xoptlck_vals[] = {
|
|
{ 0, "Column not injected because of optimistic locking" },
|
|
{ 1, "Row change token column was injected because optimistic locking was requested" },
|
|
{ 2, "RID column was injected because optimistic locking was requested" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_hidden_vals[] = {
|
|
{ 0, "Not a hidden column" },
|
|
{ 1, "Hidden column" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_sqldxgrp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
|
|
{
|
|
proto_item *ti;
|
|
proto_tree *subtree;
|
|
int offset = 0;
|
|
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
guint32 null_ind;
|
|
|
|
ti = proto_tree_add_item(tree, hf_drda_sqldxgrp, tvb, offset, 1, ENC_NA);
|
|
subtree = proto_item_add_subtree(ti, ett_drda_sqldxgrp);
|
|
proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlxkeymem, tvb, offset, 2, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlxupdateable, tvb, offset, 2, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlxgenerated, tvb, offset, 2, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlxparmmode, tvb, offset, 2, pdu_info, NULL);
|
|
if (pdu_info->sqlam >= 9) {
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlxoptlck, tvb, offset, 2, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlxhidden, tvb, offset, 2, pdu_info, NULL);
|
|
}
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_rdbnam, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxcorname, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxcorname, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxbasename, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxbasename, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxschema, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxschema, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxname, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxname, tvb, offset, pdu_info);
|
|
if (pdu_info->sqlam >= 10) {
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlxmodule, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlxmodule, tvb, offset, pdu_info);
|
|
}
|
|
}
|
|
proto_item_set_end(ti, tvb, offset);
|
|
return offset;
|
|
}
|
|
|
|
/* Appendix D of C112. Note that some strings have multiple codes that
|
|
* map to them.
|
|
*/
|
|
static const value_string drda_fcode_vals[] = {
|
|
|
|
{ 1, "ALLOCATE CURSOR" },
|
|
{ 2, "ALLOCATE DESCRIPTOR" },
|
|
{ 3, "ALTER DOMAIN" },
|
|
{ 4, "ALTER TABLE" },
|
|
{ 6, "CREATE ASSERTION" },
|
|
{ 7, "CALL" },
|
|
{ 8, "CREATE CHARACTER SET" },
|
|
{ 9, "CLOSE CURSOR" },
|
|
{ 11, "CREATE COLLATION" },
|
|
{ 12, "COMMIT WORK" },
|
|
{ 13, "CONNECT" },
|
|
{ 15, "DEALLOCATE DESCRIPTOR" },
|
|
{ 16, "DEALLOCATE PREPARE" },
|
|
{ 17, "ALTER ROUTINE" },
|
|
{ 18, "DELETE CURSOR" },
|
|
{ 19, "DELETE WHERE" },
|
|
{ 20, "DESCRIBE" },
|
|
{ 21, "SELECT" },
|
|
{ 22, "DISCONNECT" },
|
|
{ 23, "CREATE DOMAIN" },
|
|
{ 24, "DROP ASSERTION" },
|
|
{ 25, "DROP CHARACTER SET" },
|
|
{ 26, "DROP COLLATION" },
|
|
{ 27, "DROP DOMAIN" },
|
|
{ 29, "DROP ROLE" },
|
|
{ 30, "DROP ROUTINE" },
|
|
{ 31, "DROP SCHEMA" },
|
|
{ 32, "DROP TABLE" },
|
|
{ 33, "DROP TRANSLATION" },
|
|
{ 34, "DROP TRIGGER" },
|
|
{ 35, "DROP TYPE" },
|
|
{ 36, "DROP VIEW" },
|
|
{ 37, "DYNAMIC CLOSE" },
|
|
{ 38, "DYNAMIC DELETE CURSOR" },
|
|
{ 39, "DYNAMIC FETCH" },
|
|
{ 40, "DYNAMIC OPEN" },
|
|
{ 41, "SELECT" },
|
|
{ 42, "DYNAMIC UPDATE CURSOR" },
|
|
{ 43, "EXECUTE IMMEDIATE" },
|
|
{ 44, "EXECUTE" },
|
|
{ 45, "FETCH" },
|
|
{ 47, "GET DESCRIPTOR" },
|
|
{ 48, "GRANT" },
|
|
{ 49, "GRANT ROLE" },
|
|
{ 50, "INSERT" },
|
|
{ 53, "OPEN" },
|
|
{ 54, "DYNAMIC DELETE CURSOR" },
|
|
{ 55, "DYNAMIC UPDATE CURSOR" },
|
|
{ 56, "PREPARE" },
|
|
{ 57, "RELEASE SAVEPOINT" },
|
|
{ 58, "RETURN" },
|
|
{ 59, "REVOKE" },
|
|
{ 60, "ALTER TYPE" },
|
|
{ 66, "SET CATALOG" },
|
|
{ 69, "SET CURRENT_PATH" },
|
|
{ 70, "SET DESCRIPTOR" },
|
|
{ 72, "SET NAMES" },
|
|
{ 74, "SET SCHEMA" },
|
|
{ 85, "SELECT CURSOR" },
|
|
{ 98, "FREE LOCATOR" },
|
|
{ 99, "HOLD LOCATOR" },
|
|
{101, "DECLARE CURSOR" },
|
|
{115, "DROP ORDERING" },
|
|
{116, "DROP TRANSFORM" },
|
|
{118, "SET TRANSFORM GROUP" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_hold_vals[] = {
|
|
|
|
{ 0, "No cursor exists, or cursor defined without WITH HOLD clause" },
|
|
{ 1, "Cursor defined using WITH HOLD clause" },
|
|
{-1, "Unknown if cursor was defined using WITH HOLD clause" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_return_vals[] = {
|
|
|
|
{ 0, "Statement is not a query" },
|
|
{ 1, "Cursor defined using the WITH RETURN CLIENT clause" },
|
|
{ 2, "Cursor defined using the WITH RETURN CALLER clause" },
|
|
{-1, "Unknown if cursor is intended to be used as a result set that will be returned from a procedure" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_scroll_vals[] = {
|
|
|
|
{ 0, "No cursor exists, or not scrollable" },
|
|
{ 1, "Cursor defined using SCROLL clause" },
|
|
{-1, "Cursor exists, but scrollability unknown" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_sensitive_vals[] = {
|
|
|
|
{ 0, "No cursor exists" },
|
|
{ 1, "Cursor defined as SENSITIVE DYNAMIC" },
|
|
{ 2, "Cursor defined as SENSITIVE STATIC" },
|
|
{ 3, "Cursor defined as INSENSITIVE" },
|
|
{ 4, "Cursor defined with PARTIAL SENSITIVITY and STATIC size and ordering" },
|
|
{ 5, "Cursor defined with PARTIAL SENSITIVITY and DYNAMIC size and ordering" },
|
|
{-1, "Cursor exists, but sensitivity unknown" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_keytype_vals[] = {
|
|
|
|
{ 0, "Statement is not a query, or no columns are members of a key" },
|
|
{ 1, "Select list includes all columns of the primary key of the base table referenced by the query" },
|
|
{ 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" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string drda_doptlck_vals[] = {
|
|
|
|
{ 0, "Optimistic locking columns not injected" },
|
|
{ 1, "Optimistic locking columns injected, but might not have the granularity to guarantee no false negatives" },
|
|
{ 2, "Optimistic locking columns injected, guaranteeing no false negatives" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_sqldhgrp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
|
|
{
|
|
proto_item *sqldhgrp_ti;
|
|
proto_tree *sqldhgrp_tree;
|
|
int offset = 0, len;
|
|
|
|
guint32 null_ind;
|
|
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
|
|
sqldhgrp_ti = proto_tree_add_item(tree, hf_drda_sqldhgrp, tvb, offset, 1, ENC_NA);
|
|
sqldhgrp_tree = proto_item_add_subtree(sqldhgrp_ti, ett_drda_sqldhgrp);
|
|
proto_tree_add_item_ret_uint(sqldhgrp_tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
len = 2;
|
|
offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldhold, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldreturn, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldscroll, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldsensitive, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldfcode, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldkeytype, tvb, offset, len, pdu_info, NULL);
|
|
if (pdu_info->sqlam >= 9) {
|
|
offset = dissect_fdoca_integer(sqldhgrp_tree, hf_drda_sqldoptlck, tvb, offset, len, pdu_info, NULL);
|
|
}
|
|
offset = dissect_fdoca_vcs(sqldhgrp_tree, hf_drda_rdbnam, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(sqldhgrp_tree, hf_drda_sqldschema, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(sqldhgrp_tree, hf_drda_sqldschema, tvb, offset, pdu_info);
|
|
if (pdu_info->sqlam >= 10) {
|
|
offset = dissect_fdoca_vcm(sqldhgrp_tree, hf_drda_sqldmodule, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(sqldhgrp_tree, hf_drda_sqldmodule, tvb, offset, pdu_info);
|
|
}
|
|
}
|
|
proto_item_set_end(sqldhgrp_ti, tvb, offset);
|
|
|
|
return offset;
|
|
}
|
|
|
|
static const value_string drda_unnamed_vals[] = {
|
|
|
|
{ 0, "Column name not generated by the RDB" },
|
|
{ 1, "Column name generated by the RDB" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_sqldoptgrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
proto_item *sqldoptgrp_ti, *expert_ti;
|
|
proto_tree *subtree;
|
|
int offset = 0;
|
|
|
|
guint32 null_ind;
|
|
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
|
|
sqldoptgrp_ti = proto_tree_add_item(tree, hf_drda_sqldoptgrp, tvb, offset, 1, ENC_NA);
|
|
subtree = proto_item_add_subtree(sqldoptgrp_ti, ett_drda_sqldoptgrp);
|
|
proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlunnamed, tvb, offset, 2, pdu_info, NULL);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlname, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlname, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqllabel, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqllabel, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlcomments, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlcomments, tvb, offset, pdu_info);
|
|
|
|
offset += dissect_drda_sqludtgrp(tvb_new_subset_remaining(tvb, offset), pinfo, subtree, data);
|
|
offset += dissect_drda_sqldxgrp(tvb_new_subset_remaining(tvb, offset), pinfo, subtree, data);
|
|
if (pdu_info->sqlam >= 10) {
|
|
expert_ti = proto_tree_add_item_ret_uint(subtree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
expert_add_info(pinfo, expert_ti, &ei_drda_undecoded);
|
|
/* XXX: What is this? It's not in Version 5 of the spec. */
|
|
}
|
|
}
|
|
}
|
|
proto_item_set_end(sqldoptgrp_ti, tvb, offset);
|
|
return offset;
|
|
}
|
|
|
|
static const value_string drda_sqltype_vals[] = {
|
|
|
|
{ 384, "DATE" },
|
|
{ 385, "DATE (NULLABLE)" },
|
|
{ 388, "TIME" },
|
|
{ 389, "TIME (NULLABLE)" },
|
|
{ 392, "TIMESTAMP" },
|
|
{ 393, "TIMESTAMP (NULLABLE)" },
|
|
{ 396, "DATALINK" },
|
|
{ 397, "DATALINK (NULLABLE)" },
|
|
{ 404, "BLOB" },
|
|
{ 405, "BLOB (NULLABLE)" },
|
|
{ 408, "CLOB" },
|
|
{ 409, "CLOB (NULLABLE)" },
|
|
{ 412, "DBCLOB" },
|
|
{ 413, "DBCLOB (NULLABLE)" },
|
|
{ 448, "VARCHAR" },
|
|
{ 449, "VARCHAR (NULLABLE)" },
|
|
{ 452, "CHAR" },
|
|
{ 453, "CHAR (NULLABLE)" },
|
|
{ 456, "LONG VARCHAR" },
|
|
{ 457, "LONG VARCHAR (NULLABLE)" },
|
|
{ 460, "NULL-TERMINATED CHAR" },
|
|
{ 461, "NULL-TERMINATED CHAR (NULLABLE)" },
|
|
{ 464, "VARGRAPHIC" },
|
|
{ 465, "VARGRAPHIC (NULLABLE)" },
|
|
{ 468, "GRAPHIC" },
|
|
{ 469, "GRAPHIC (NULLABLE)" },
|
|
{ 472, "LONG VARGRAPHIC" },
|
|
{ 473, "LONG VARGRAPHIC (NULLABLE)" },
|
|
{ 476, "PASCAL L STRING" },
|
|
{ 477, "PASCAL L STRING (NULLABLE)" },
|
|
{ 480, "FLOAT" },
|
|
{ 481, "FLOAT (NULLABLE)" },
|
|
{ 484, "FIXED DECIMAL" },
|
|
{ 485, "FIXED DECIMAL (NULLABLE)" },
|
|
{ 488, "ZONED DECIMAL" },
|
|
{ 489, "ZONED DECIMAL (NULLABLE)" },
|
|
{ 492, "BIGINT" },
|
|
{ 493, "BIGINT (NULLABLE)" },
|
|
{ 496, "INTEGER" },
|
|
{ 497, "INTEGER (NULLABLE)" },
|
|
{ 500, "SMALLINT" },
|
|
{ 501, "SMALLINT (NULLABLE)" },
|
|
{ 504, "NUMERIC CHAR" },
|
|
{ 505, "NUMERIC CHAR (NULLABLE)" },
|
|
{ 904, "ROWID" },
|
|
{ 905, "ROWID (NULLABLE)" },
|
|
{ 908, "VARBINARY" },
|
|
{ 909, "VARBINARY (NULLABLE)" },
|
|
{ 912, "BINARY" },
|
|
{ 913, "BINARY (NULLABLE)" },
|
|
{ 960, "BLOB LOCATOR" },
|
|
{ 961, "BLOB LOCATOR (NULLABLE)" },
|
|
{ 964, "CLOB LOCATOR" },
|
|
{ 965, "CLOB LOCATOR (NULLABLE)" },
|
|
{ 968, "DBCLOB LOCATOR" },
|
|
{ 969, "DBCLOB LOCATOR (NULLABLE)" },
|
|
{ 972, "RESULT SET LOCATOR" },
|
|
{ 973, "RESULT SET LOCATOR (NULLABLE)" },
|
|
{ 988, "XML" },
|
|
{ 989, "XML (NULLABLE)" },
|
|
{ 996, "DECFLOAT" },
|
|
{ 997, "DECFLOAT (NULLABLE)" },
|
|
{2436, "BOOLEAN" },
|
|
{2437, "BOOLEAN (NULLABLE)" },
|
|
{2444, "CURSOR TYPE" },
|
|
{2445, "CURSOR TYPE (NULLABLE)" },
|
|
{2448, "TIMESTAMP WITH TIME ZONE" },
|
|
{2449, "TIMESTAMP WITH TIME ZONE (NULLABLE)" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_sqldagrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
proto_item *sqldagrp_ti;
|
|
proto_tree *subtree;
|
|
int offset = 0;
|
|
|
|
//guint32 null_ind;
|
|
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
|
|
sqldagrp_ti = proto_tree_add_item(tree, hf_drda_sqldagrp, tvb, offset, 1, ENC_NA);
|
|
subtree = proto_item_add_subtree(sqldagrp_ti, ett_drda_sqldagrp);
|
|
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlprecision, tvb, offset, 2, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlscale, tvb, offset, 2, pdu_info, NULL);
|
|
if (pdu_info->sqlam >= 6) {
|
|
offset = dissect_fdoca_integer64(subtree, hf_drda_sqllength, tvb, offset, 8, pdu_info, NULL);
|
|
} else {
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqllength32, tvb, offset, 4, pdu_info, NULL);
|
|
}
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqltype, tvb, offset, 2, pdu_info, NULL);
|
|
proto_tree_add_item(subtree, hf_drda_ccsid, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
if (pdu_info->sqlam >= 9) {
|
|
offset = dissect_fdoca_integer64(subtree, hf_drda_sqlarrextent, tvb, offset, 8, pdu_info, NULL);
|
|
|
|
if (pdu_info->sqlam >= 10) {
|
|
proto_tree_add_expert(subtree, pinfo, &ei_drda_undecoded, tvb, offset, 2);
|
|
/* XXX: What is this? It's not in Version 5 of the spec. */
|
|
offset += 2;
|
|
}
|
|
}
|
|
|
|
if (pdu_info->sqlam >= 7) {
|
|
offset += dissect_drda_sqldoptgrp(tvb_new_subset_remaining(tvb, offset), pinfo, subtree, data);
|
|
} else {
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlname, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlname, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqllabel, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqllabel, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcm(subtree, hf_drda_sqlcomments, tvb, offset, pdu_info);
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_sqlcomments, tvb, offset, pdu_info);
|
|
if (pdu_info->sqlam == 6) {
|
|
offset += dissect_drda_sqludtgrp(tvb_new_subset_remaining(tvb, offset), pinfo, subtree, data);
|
|
}
|
|
}
|
|
proto_item_set_end(sqldagrp_ti, tvb, offset);
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_sqlcard(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
/* For a description of these fields (at least on DB2), see:
|
|
* https://www.ibm.com/docs/en/db2-for-zos/12?topic=sqlca-description-fields
|
|
*/
|
|
|
|
proto_item *ti, *sqlcard_ti;
|
|
proto_tree *subtree, *sqlcard_tree;
|
|
int offset = 0, len = 4;
|
|
|
|
guint32 null_ind, length;
|
|
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
|
|
sqlcard_ti = proto_tree_add_item(tree, hf_drda_sqlcagrp, tvb, offset, 1, ENC_NA);
|
|
sqlcard_tree = proto_item_add_subtree(sqlcard_ti, ett_drda_sqlcagrp);
|
|
proto_tree_add_item_ret_uint(sqlcard_tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
len = 4;
|
|
offset = dissect_fdoca_integer(sqlcard_tree, hf_drda_sqlcode, tvb, offset, len, pdu_info, NULL);
|
|
len = 5;
|
|
offset = dissect_fdoca_fcs(sqlcard_tree, hf_drda_sqlstate, tvb, offset, len, pdu_info);
|
|
len = 8;
|
|
offset = dissect_fdoca_fcs(sqlcard_tree, hf_drda_sqlerrproc, tvb, offset, len, pdu_info);
|
|
|
|
/* SQLCAXGRP (nullable) */
|
|
proto_tree_add_item_ret_uint(sqlcard_tree, hf_drda_null_ind, tvb, offset, 1, ENC_NA, &null_ind);
|
|
offset++;
|
|
if ((gint8)null_ind >= 0) {
|
|
ti = proto_tree_add_item(sqlcard_tree, hf_drda_sqlcaxgrp, tvb, offset, 35, ENC_NA);
|
|
subtree = proto_item_add_subtree(ti, ett_drda_sqlcaxgrp);
|
|
/* Earlier than SQLAM Level 7, the RDBName follows here, and is
|
|
* a fixed string field of length 18. At SQLAM Level 7 and
|
|
* higher, the SQLRDBNAME is a variable character field and
|
|
* comes later, after the SQLWARN fields.
|
|
*/
|
|
if (pdu_info->sqlam < 7) {
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_rdbnam, tvb, offset, 18, pdu_info);
|
|
}
|
|
len = 4;
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd1, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd2, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd3, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd4, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd5, tvb, offset, len, pdu_info, NULL);
|
|
offset = dissect_fdoca_integer(subtree, hf_drda_sqlerrd6, tvb, offset, len, pdu_info, NULL);
|
|
len = 1;
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn0, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn1, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn2, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn3, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn4, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn5, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn6, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn7, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn8, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarn9, tvb, offset, len, pdu_info);
|
|
offset = dissect_fdoca_fcs(subtree, hf_drda_sqlwarna, tvb, offset, len, pdu_info);
|
|
if (pdu_info->sqlam >= 7) {
|
|
offset = dissect_fdoca_vcs(subtree, hf_drda_rdbnam, tvb, offset, pdu_info);
|
|
}
|
|
/* SQLERRMSG_m, a variable character string using the mixed
|
|
* character CCSID. On DB2, contains one or more tokens,
|
|
* separated by X'FF', that are substituted for variables
|
|
* in the descriptions of error conditions.
|
|
*/
|
|
proto_tree_add_item_ret_uint(subtree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
|
|
offset += 2;
|
|
gint end_offset;
|
|
while ((end_offset = tvb_find_guint8(tvb, offset, length, 0xFF)) != -1) {
|
|
proto_tree_add_item(subtree, hf_drda_sqlerrmsg, tvb, offset, end_offset - offset, pdu_info->mbc);
|
|
length -= (end_offset + 1 - offset);
|
|
offset = end_offset + 1;
|
|
}
|
|
proto_tree_add_item(subtree, hf_drda_sqlerrmsg, tvb, offset, length, pdu_info->mbc);
|
|
offset += length;
|
|
|
|
/* SQLERRMSG_s - same but using the single byte CCSID. Only one
|
|
* of these should have nonzero length.
|
|
*/
|
|
proto_tree_add_item_ret_uint(subtree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
|
|
offset += 2;
|
|
while ((end_offset = tvb_find_guint8(tvb, offset, length, 0xFF)) != -1) {
|
|
proto_tree_add_item(subtree, hf_drda_sqlerrmsg, tvb, offset, end_offset - offset, pdu_info->sbc);
|
|
length -= (end_offset + 1 - offset);
|
|
offset = end_offset + 1;
|
|
}
|
|
proto_tree_add_item(subtree, hf_drda_sqlerrmsg, tvb, offset, length, pdu_info->sbc);
|
|
offset += length;
|
|
proto_item_set_end(ti, tvb, offset);
|
|
}
|
|
|
|
if (pdu_info->sqlam >= 7) {
|
|
offset += dissect_drda_sqldiaggrp(tvb_new_subset_remaining(tvb, offset), pinfo, sqlcard_tree, data);
|
|
}
|
|
} else {
|
|
/* DRDA, Version 4, Volume 1: 5.6.4.6 SQLCAGRP:
|
|
* "A null SQLCA indicates everything is fine: SQLSTATE='00000'"
|
|
*/
|
|
ti = proto_tree_add_int(sqlcard_tree, hf_drda_sqlcode, tvb, offset, 0, 0);
|
|
proto_item_set_generated(ti);
|
|
ti = proto_tree_add_string(sqlcard_tree, hf_drda_sqlstate, tvb, offset, 0, "00000");
|
|
proto_item_set_generated(ti);
|
|
}
|
|
proto_item_set_end(sqlcard_ti, tvb, offset);
|
|
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_sqldard(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
|
|
{
|
|
int offset = 0;
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
|
|
guint32 numrows;
|
|
|
|
offset = dissect_drda_sqlcard(tvb, pinfo, tree, data);
|
|
|
|
if (pdu_info->sqlam >= 7) {
|
|
offset += dissect_drda_sqldhgrp(tvb_new_subset_remaining(tvb, offset), pinfo, tree, data);
|
|
}
|
|
offset = dissect_fdoca_integer(tree, hf_drda_sqlnum, tvb, offset, 2, pdu_info, &numrows);
|
|
for (guint32 i = 0; i < numrows; ++i) {
|
|
offset += dissect_drda_sqldagrp(tvb_new_subset_remaining(tvb, offset), pinfo, tree, data);
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_undecoded(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_expert(tree, pinfo, &ei_drda_undecoded, tvb, 0, -1);
|
|
return tvb_captured_length(tvb);
|
|
}
|
|
|
|
static const value_string drda_rlsconv_vals[] = {
|
|
{ 0xF0, "NO" }, /* EBCDIC '0' */
|
|
{ 0xF1, "TERMINATE" }, /* EBCDIC '1' */
|
|
{ 0xF2, "REUSE" }, /* EBCDIC '2' */
|
|
{ 0xF3, "NO_KDO - Presence of keep dynamic sections" }, /* EBCDIC '3' */
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_rlsconv(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_rlsconv, tvb, 0, 1, ENC_NA);
|
|
return 1;
|
|
}
|
|
|
|
static const value_string drda_secmec_vals[] = {
|
|
{ 1, "DCESEC - Distributed Computing Environment" },
|
|
{ 3, "USRIDPWD - User ID and Password" },
|
|
{ 4, "UDRIDONL - User ID Only" },
|
|
{ 5, "USRIDNWPWD - User ID, Password, and New Password" },
|
|
{ 6, "USRSBSPWD - User ID with Substitute Password" },
|
|
{ 7, "USRENCPWD - User ID with Encrypted Password" },
|
|
{ 8, "USRSSBPWD - User ID with Strong Password Substitute" },
|
|
{ 9, "EUSRIDPWD - Encrypted User ID and Password" },
|
|
{10, "EUSRIDNWPWD - Encrypted User ID, Password, New Password" },
|
|
{11, "KERSEC - Kerberos Security" },
|
|
{12, "EUSRIDDTA - Encrypted User ID and Security-Sensitive Data" },
|
|
{13, "EUSRPWDDTA - Encrypted User ID, Password, and Security-Sensitive Data" },
|
|
{14, "EUSRNPWDDTA - Encrypted User ID, Password, New Password, and Security-Sensitive Data" },
|
|
{15, "PLGIN - Plug-in Security" },
|
|
{16, "EUSRIDONL - Encrypted User ID Only" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_secmec(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
/* REPEATABLE */
|
|
int offset = 0;
|
|
while (tvb_reported_length_remaining(tvb, offset) >= 2) {
|
|
proto_tree_add_item(tree, hf_drda_secmec, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
}
|
|
return offset;
|
|
}
|
|
|
|
static const value_string drda_svrcod_vals[] = {
|
|
{ 0, "INFO - Information Only" },
|
|
{ 4, "WARNING - Warning" },
|
|
{ 8, "ERROR - Error" },
|
|
{ 16, "SEVERE - Severe Error" },
|
|
{ 32, "ACCDMG - Access Damage" },
|
|
{ 64, "PRMDMG - Permanent Damage" },
|
|
{128, "SESDMG - Session Damage" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_sectkn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_sectkn, tvb, 0, tvb_reported_length(tvb), ENC_NA);
|
|
return tvb_reported_length(tvb);
|
|
}
|
|
|
|
static int
|
|
dissect_drda_svrcod(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_svrcod, tvb, 0, 2, ENC_BIG_ENDIAN);
|
|
return 2;
|
|
}
|
|
|
|
static const value_string drda_secchkcd_vals[] = {
|
|
{0x00, "The security information is correct and acceptable." },
|
|
{0x01, "SECMEC value not supported." },
|
|
{0x02, "DCE information status issued." },
|
|
{0x03, "DCE retryable error." },
|
|
{0x04, "DCE non-retryable error." },
|
|
{0x05, "GSSAPI informational status issued." },
|
|
{0x06, "GSSAPI retryable error." },
|
|
{0x07, "GSSAPI non-retryable error." },
|
|
{0x08, "Local Security Service informational status issued." },
|
|
{0x09, "Local Security Service retryable error." },
|
|
{0x0A, "Local Security Service non-retryable error." },
|
|
{0x0B, "SECTKN missing when it is required or it is invalid." },
|
|
{0x0E, "Password expired." },
|
|
{0x0F, "Password invalid." },
|
|
{0x10, "Password missing." },
|
|
{0x12, "User ID missing." },
|
|
{0x13, "User ID invalid." },
|
|
{0x14, "User ID revoked." },
|
|
{0x15, "New Password invalid." },
|
|
{0x16, "Authentication failed because of connectivity restrictions enforced by the security plug-in." },
|
|
{0x17, "Invalid GSS-API server credential." },
|
|
{0x18, "GSS-API server credential expired on the database server." },
|
|
{0x19, "Continue - require more security context information for authentication." },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_secchkcd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_secchkcd, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
return 1;
|
|
}
|
|
|
|
/* A few common CCSIDs, many more are at:
|
|
* https://www.ibm.com/docs/en/i/7.3?topic=information-ccsid-values-defined-i
|
|
* https://web.archive.org/web/20160304082631/http://www-01.ibm.com/software/globalization/g11n-res.html
|
|
*/
|
|
static const value_string drda_ccsid_vals[] = {
|
|
{ 0, "Use default value" },
|
|
{ 37, "IBM037" }, /* EBCDIC US Latin-1 */
|
|
{ 367, "US-ASCII" },
|
|
{ 500, "IBM500" }, /* EBCDIC International Latin-1 */
|
|
{ 819, "ISO-8859-1" },
|
|
{ 850, "IBM850" }, /* DOS Latin-1 */
|
|
{ 1200, "UTF-16" }, /* UTF-16BE; UTF-16LE is 1202 */
|
|
{ 1202, "UTF-16LE" },
|
|
{ 1208, "UTF-8" },
|
|
{ 65535, "Requested CCSID unsupported" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static guint
|
|
ccsid_to_encoding(guint32 ccsid)
|
|
{
|
|
switch (ccsid) {
|
|
|
|
case 0:
|
|
case 500:
|
|
case 65535:
|
|
return ENC_EBCDIC_CP500;
|
|
case 37:
|
|
return ENC_EBCDIC_CP037;
|
|
case 367:
|
|
return ENC_ASCII;
|
|
case 819:
|
|
return ENC_ISO_8859_1;
|
|
case 850:
|
|
return ENC_ASCII; /* XXX: CP 850 not yet supported; CP 437 is closer, but ASCII safer */
|
|
case 1200:
|
|
return ENC_UTF_16|ENC_BIG_ENDIAN;
|
|
case 1202:
|
|
return ENC_UTF_16|ENC_LITTLE_ENDIAN;
|
|
case 1208:
|
|
return ENC_UTF_8;
|
|
default:
|
|
return ENC_UTF_8;
|
|
}
|
|
}
|
|
|
|
static int
|
|
dissect_drda_ccsid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
|
|
{
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
guint32 ccsid;
|
|
|
|
proto_tree_add_item_ret_uint(tree, hf_drda_ccsid, tvb, 0, 2, ENC_BIG_ENDIAN, &ccsid);
|
|
switch (pinfo->match_uint) {
|
|
case DRDA_CP_CCSIDSBC:
|
|
pdu_info->sbc = ccsid_to_encoding(ccsid);
|
|
break;
|
|
case DRDA_CP_CCSIDMBC:
|
|
pdu_info->mbc = ccsid_to_encoding(ccsid);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 2;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_monitor(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
static int * const monitor_fields[] = {
|
|
&hf_drda_monitor_etime,
|
|
&hf_drda_monitor_reserved,
|
|
NULL
|
|
};
|
|
|
|
proto_tree_add_bitmask(tree, tvb, 0, hf_drda_monitor, ett_drda_monitor,
|
|
monitor_fields, ENC_BIG_ENDIAN);
|
|
return 4;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_etime(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_etime, tvb, 0, 8, ENC_TIME_USECS);
|
|
return 8;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_respktsz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_respktsz, tvb, 0, 4, ENC_BIG_ENDIAN);
|
|
return 4;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_rdbinttkn(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
/* The contents of the token are unarchitected and can differe for each
|
|
* target SQLAM.
|
|
*/
|
|
proto_tree_add_item(tree, hf_drda_rdbinttkn, tvb, 0, tvb_reported_length(tvb), ENC_NA);
|
|
return tvb_reported_length(tvb);
|
|
}
|
|
|
|
static int
|
|
dissect_drda_rdbcmtok(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_rdbcmtok, tvb, 0, 1, ENC_NA);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_pkgnam(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_item *ti_length;
|
|
int offset = 0;
|
|
guint32 length;
|
|
|
|
/* The PKGNAMCSN can have one of the following two formats depending on the
|
|
* length of the RDBNAM, RDBCOLID, and PKGID contained therein:
|
|
* * RDBNAM, RDBCOLID, and PKGID all have a length of 18.
|
|
* [Possibly right padded with blank spaces.]
|
|
* This format of the PKGNAMCSN is identical to the sole format used prior
|
|
* to DDM Level 7 where the length is fixed at 58. The use of the SCLDTALEN
|
|
* is disallowed with this format.
|
|
* * At least one of RDBNAM, RDBCOLID, and PKGID has a length > 18.
|
|
* This format of the PKGNAMCSN mandates the SCLDTALEN to precede each of
|
|
* the RDBNAM, RDBCOLID, and PKGID. With this format, the PKGNAMCSN has a
|
|
* minimum length of 65 and a maximum length of 775.
|
|
*/
|
|
if (tvb_reported_length(tvb) == 54) {
|
|
/* 58 - 4 bytes for the code point and length already removed. */
|
|
proto_tree_add_item(tree, hf_drda_rdbnam, tvb, offset, 18, ENC_UTF_8);
|
|
proto_tree_add_item(tree, hf_drda_rdbnam_ebcdic, tvb, offset, 18, ENC_EBCDIC_CP500);
|
|
offset += 18;
|
|
proto_tree_add_item(tree, hf_drda_rdbcolid, tvb, offset, 18, ENC_UTF_8);
|
|
proto_tree_add_item(tree, hf_drda_rdbcolid_ebcdic, tvb, offset, 18, ENC_EBCDIC_CP500);
|
|
offset += 18;
|
|
proto_tree_add_item(tree, hf_drda_pkgid, tvb, offset, 18, ENC_UTF_8);
|
|
proto_tree_add_item(tree, hf_drda_pkgid_ebcdic, tvb, offset, 18, ENC_EBCDIC_CP500);
|
|
offset += 18;
|
|
} else if (tvb_reported_length(tvb) > 64) {
|
|
ti_length = proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
|
|
if (length < 18 || length > 255) {
|
|
expert_add_info_format(pinfo, ti_length, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be 18-255 bytes long", length);
|
|
}
|
|
offset += 2;
|
|
proto_tree_add_item(tree, hf_drda_rdbnam, tvb, offset, length, ENC_UTF_8);
|
|
proto_tree_add_item(tree, hf_drda_rdbnam_ebcdic, tvb, offset, length, ENC_EBCDIC_CP500);
|
|
offset += length;
|
|
ti_length = proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
|
|
if (length < 18 || length > 255) {
|
|
expert_add_info_format(pinfo, ti_length, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be 18-255 bytes long", length);
|
|
}
|
|
offset += 2;
|
|
proto_tree_add_item(tree, hf_drda_rdbcolid, tvb, offset, length, ENC_UTF_8);
|
|
proto_tree_add_item(tree, hf_drda_rdbcolid_ebcdic, tvb, offset, length, ENC_EBCDIC_CP500);
|
|
offset += length;
|
|
ti_length = proto_tree_add_item_ret_uint(tree, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
|
|
if (length < 18 || length > 255) {
|
|
expert_add_info_format(pinfo, ti_length, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be 18-255 bytes long", length);
|
|
}
|
|
offset += 2;
|
|
proto_tree_add_item(tree, hf_drda_pkgid, tvb, offset, length, ENC_UTF_8);
|
|
proto_tree_add_item(tree, hf_drda_pkgid_ebcdic, tvb, offset, length, ENC_EBCDIC_CP500);
|
|
offset += length;
|
|
} else {
|
|
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.");
|
|
}
|
|
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_rtnsetstt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_rtnsetstt, tvb, 0, 1, ENC_NA);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_outexp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_outexp, tvb, 0, 1, ENC_NA);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_pkgnamct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
int offset;
|
|
|
|
offset = dissect_drda_pkgnam(tvb_new_subset_length(tvb, 0, tvb_reported_length_remaining(tvb, 8)), pinfo, tree, data);
|
|
|
|
proto_tree_add_item(tree, hf_drda_pkgcnstkn, tvb, offset, 8, ENC_UTF_8);
|
|
offset += 8;
|
|
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_pkgnamcsn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
int offset;
|
|
|
|
offset = dissect_drda_pkgnamct(tvb_new_subset_length(tvb, 0, tvb_reported_length_remaining(tvb, 2)), pinfo, tree, data);
|
|
|
|
proto_tree_add_item(tree, hf_drda_pkgsn, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
|
|
return offset;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_qryblksz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_qryblksz, tvb, 0, 4, ENC_BIG_ENDIAN);
|
|
return 4;
|
|
}
|
|
|
|
static const value_string drda_uowdsp_vals[] =
|
|
{
|
|
{ 1, "Committed"},
|
|
{ 2, "Rolled back"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_uowdsp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_uowdsp, tvb, 0, 1, ENC_NA);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_rdbalwupd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_rdbalwupd, tvb, 0, 1, ENC_NA);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_sqlcsrhld(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_sqlcsrhld, tvb, 0, 1, ENC_NA);
|
|
return 1;
|
|
}
|
|
|
|
static const val64_string drda_qryextdtasz_vals[] =
|
|
{
|
|
{ -1, "Not limited by this parameter"},
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_qryextdtasz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_qryextdtasz, tvb, 0, 8, ENC_BIG_ENDIAN);
|
|
return 8;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_smldtasz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_smldtasz, tvb, 0, 8, ENC_BIG_ENDIAN);
|
|
return 8;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_meddtasz(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_meddtasz, tvb, 0, 8, ENC_BIG_ENDIAN);
|
|
return 8;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_trgdftrt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_trgdftrt, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_rtnsqlda(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_rtnsqlda, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
return 1;
|
|
}
|
|
|
|
static const value_string drda_qryattupd_vals[] = {
|
|
{ 0, "QRYUNK - Unknown or undefined for this cursor" },
|
|
{ 1, "QRYRDO - The cursor is read-only" },
|
|
{ 2, "QRYDEL - The cursor allows read and delete" },
|
|
{ 4, "QRYUPD - The cursor allows read, delete, and update" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_qryattupd(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_qryattupd, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_qryrowset(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_qryrowset, tvb, 0, 4, ENC_BIG_ENDIAN);
|
|
return 4;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_qryinsid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
/* Query Instance Identifier (QRYINSID) uniquely identifies the instance of
|
|
* a query. Its contents are implementation-specific and are unarchitected
|
|
* by DDM.
|
|
*/
|
|
proto_tree_add_item(tree, hf_drda_qryinsid, tvb, 0, tvb_reported_length(tvb), ENC_NA);
|
|
return tvb_reported_length(tvb);
|
|
}
|
|
|
|
static const value_string drda_qryclsimp_vals[] = {
|
|
{ 0, "Target server determines whether to implicitly close the cursor or not upon SQLSTATE 02000 based on the cursor type" },
|
|
{ 1, "Target server must implicitly close the cursor upon SQLSTATE 02000" },
|
|
{ 2, "Target server must not implicitly close the cursor upon SQLSTATE 02000" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_qryclsimp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_qryclsimp, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_qryblkfct(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_qryblkfct, tvb, 0, 4, ENC_BIG_ENDIAN);
|
|
return 4;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_maxrslcnt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_maxrslcnt, tvb, 0, 2, ENC_BIG_ENDIAN);
|
|
return 2;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_maxblkext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_maxblkext, tvb, 0, 2, ENC_BIG_ENDIAN);
|
|
return 2;
|
|
}
|
|
|
|
static const value_string drda_rslsetflg_extended_vals[] =
|
|
{
|
|
{ 0, "Standard SQLDA" },
|
|
{ 1, "Extended SQLDA" },
|
|
{ 2, "Light SQLDA" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_rslsetflg(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
static int * const rslsetflg_fields[] = {
|
|
&hf_drda_rslsetflg_unused,
|
|
&hf_drda_rslsetflg_dsconly,
|
|
&hf_drda_rslsetflg_extended,
|
|
&hf_drda_rslsetflg_reserved,
|
|
NULL
|
|
};
|
|
|
|
proto_tree_add_bitmask(tree, tvb, 0, hf_drda_rslsetflg, ett_drda_rslsetflg,
|
|
rslsetflg_fields, ENC_BIG_ENDIAN);
|
|
return 4;
|
|
}
|
|
|
|
static const value_string drda_typsqlda_vals[] = {
|
|
{ 0, "Standard output SQLDA" },
|
|
{ 1, "Standard input SQLDA" },
|
|
{ 2, "Light output SQLDA" },
|
|
{ 3, "Light input SQLDA" },
|
|
{ 4, "Extended output SQLDA" },
|
|
{ 5, "Extended input SQLDA" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_typsqlda(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_typsqlda, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
return 1;
|
|
}
|
|
|
|
static const value_string drda_outovropt_vals[] = {
|
|
{ 1, "OUTOVRFRS - Output Override Allowed on First CNTQRY" },
|
|
{ 2, "OUTOVRANY - Output Override Allowed on Any CNTQRY" },
|
|
{ 3, "OUTOVRNON - Output Override Not Allowed, and MINLVL is 8" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static int
|
|
dissect_drda_outovropt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_outovropt, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_dyndtafmt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_dyndtafmt, tvb, 0, 1, ENC_BIG_ENDIAN);
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_pktobj(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
|
|
{
|
|
proto_tree_add_item(tree, hf_drda_pktobj, tvb, 0, tvb_reported_length(tvb), ENC_NA);
|
|
return tvb_reported_length(tvb);
|
|
}
|
|
|
|
static int
|
|
dissect_drda_mgrlvlls(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
|
|
{
|
|
proto_tree *drda_tree_sub;
|
|
proto_item *ti;
|
|
|
|
drda_pdu_info_t *pdu_info = (drda_pdu_info_t*)data;
|
|
|
|
gint offset = 0;
|
|
guint32 mgrlvln;
|
|
guint16 iParameterCP;
|
|
gint iLengthParam = 4;
|
|
|
|
while (tvb_reported_length_remaining(tvb, offset) >= 2)
|
|
{
|
|
iParameterCP = tvb_get_ntohs(tvb, offset);
|
|
drda_tree_sub = proto_tree_add_subtree(tree, tvb, offset, iLengthParam,
|
|
ett_drda_param, &ti, DRDA_TEXT_PARAM);
|
|
proto_item_append_text(ti, " (%s)", val_to_str_ext(iParameterCP, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
switch (iParameterCP) {
|
|
|
|
case DRDA_CP_CCSIDMGR:
|
|
case DRDA_CP_UNICODEMGR:
|
|
/* The default CCSID for DRDA is 500 (EBCDIC Latin-1).
|
|
* These two code points are used to propose (in an EXCSAT
|
|
* command's MGRLVLLS parameter) and accept (in an EXCSATRD
|
|
* command's MGRLVLLS parameter) a CSSID to be used for all
|
|
* character data for DDM parameters. (*Not*, note, for the
|
|
* FD:OCA (SQL statements and the like), which are governed
|
|
* by TYPDEFNAM and TYPDEFOVR as contained in ACCRDB and ACCRDBRM
|
|
* - note that they can be different in the two directions.)
|
|
*
|
|
* A 0 reply in an EXCSATRD means rejection of the request, and
|
|
* EBCDIC code page 500 (Latin-1) must be used. A 0xFFFF reply
|
|
* in an EXCSATRD means "I do support CCSIDMGR, but not the code
|
|
* page you requested, try again."
|
|
*
|
|
* UNICODEMGR and CCSIDMGR are mutually exclusive.
|
|
* UNICODEMGR should only use 1208 (UTF-8) or 0. CCSIDMGR must
|
|
* support 500 (EBCDIC Latin-1), 819 (ISO 8859-1), and 850
|
|
* (IBM PC-DOS ASCII Latin-1), and can support others.
|
|
* If the server replies with a 0 to UNICODEMGR, the client can
|
|
* try again with a CCSIDMGR.
|
|
*/
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_ccsid, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
|
|
break;
|
|
|
|
case DRDA_CP_SQLAM:
|
|
proto_tree_add_item_ret_uint(drda_tree_sub, hf_drda_mgrlvln, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &mgrlvln);
|
|
pdu_info->sqlam = mgrlvln;
|
|
break;
|
|
|
|
default:
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_mgrlvln, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
|
|
}
|
|
offset += iLengthParam;
|
|
}
|
|
|
|
return tvb_captured_length(tvb);
|
|
}
|
|
|
|
static int
|
|
dissect_drda_collection(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data)
|
|
{
|
|
proto_tree *drda_tree_sub;
|
|
proto_item *ti;
|
|
gint offset = 0;
|
|
|
|
guint16 iParameterCP;
|
|
gint iLengthParam;
|
|
|
|
/* All objects in DDM are modeled as either scalars or collections.
|
|
* A collection has the length before each element.
|
|
* There are also lists of repeatable scalars, which don't have
|
|
* the length.
|
|
*/
|
|
|
|
while (tvb_reported_length_remaining(tvb, offset) >= 2)
|
|
{
|
|
iLengthParam = tvb_get_ntohs(tvb, offset + 0);
|
|
if (tvb_reported_length_remaining(tvb, offset) >= iLengthParam)
|
|
{
|
|
iParameterCP = tvb_get_ntohs(tvb, offset + 2);
|
|
drda_tree_sub = proto_tree_add_subtree(tree, tvb, offset, iLengthParam,
|
|
ett_drda_param, &ti, DRDA_TEXT_PARAM);
|
|
proto_item_append_text(ti, " (%s)", val_to_str_ext(iParameterCP, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
|
|
if (!dissector_try_uint_new(drda_opcode_table, iParameterCP, tvb_new_subset_length(tvb, offset + 4, iLengthParam - 4), pinfo, drda_tree_sub, FALSE, data)) {
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_data, tvb, offset + 4, iLengthParam - 4, ENC_UTF_8);
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_data_ebcdic, tvb, offset + 4, iLengthParam - 4, ENC_EBCDIC_CP500);
|
|
}
|
|
}
|
|
offset += iLengthParam;
|
|
}
|
|
|
|
return tvb_captured_length(tvb);
|
|
}
|
|
|
|
static int
|
|
dissect_drda_codpntdr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
|
|
{
|
|
proto_item *ti;
|
|
guint32 codpnt;
|
|
|
|
ti = proto_tree_add_item_ret_uint(tree, hf_drda_param_codepoint, tvb, 0, 2, ENC_BIG_ENDIAN, &codpnt);
|
|
proto_item_append_text(ti, " - %s", val_to_str_ext(codpnt, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
|
|
return 2;
|
|
}
|
|
|
|
static int
|
|
dissect_drda_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
|
{
|
|
proto_tree *drda_tree;
|
|
proto_tree *drdaroot_tree;
|
|
proto_tree *drda_tree_sub;
|
|
proto_item *ti, *ddm_ti, *ti_length;
|
|
gint offset = 0;
|
|
|
|
drda_conv_info_t *conv_info;
|
|
drda_flow_t *flow;
|
|
drda_pdu_info_t *pdu_info;
|
|
guint64 flags;
|
|
guint32 iLength, iCommand, correl;
|
|
|
|
guint16 iParameterCP;
|
|
guint8 dsstyp;
|
|
gboolean is_server = FALSE;
|
|
gint iLengthParam;
|
|
|
|
static int * const format_flags[] = {
|
|
&hf_drda_ddm_fmt_reserved,
|
|
&hf_drda_ddm_fmt_chained,
|
|
&hf_drda_ddm_fmt_errcont,
|
|
&hf_drda_ddm_fmt_samecorr,
|
|
&hf_drda_ddm_fmt_dsstyp,
|
|
NULL
|
|
};
|
|
|
|
ti = proto_tree_add_item(tree, proto_drda, tvb, 0, -1, ENC_NA);
|
|
drdaroot_tree = proto_item_add_subtree(ti, ett_drda);
|
|
|
|
drda_tree = proto_tree_add_subtree(drdaroot_tree, tvb, 0, 10, ett_drda_ddm, &ddm_ti, DRDA_TEXT_DDM);
|
|
|
|
ti_length = proto_tree_add_item_ret_uint(drda_tree, hf_drda_ddm_length, tvb, 0, 2, ENC_BIG_ENDIAN, &iLength);
|
|
if (iLength < 10) {
|
|
expert_add_info_format(pinfo, ti_length, &ei_drda_opcode_invalid_length, "Invalid length detected (%u): should be at least 10 bytes long", iLength);
|
|
return 2;
|
|
}
|
|
|
|
proto_tree_add_item(drda_tree, hf_drda_ddm_magic, tvb, 2, 1, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_bitmask_ret_uint64(drda_tree, tvb, 3, hf_drda_ddm_format, ett_drda_ddm_format, format_flags, ENC_BIG_ENDIAN, &flags);
|
|
dsstyp = flags & 0xF;
|
|
|
|
proto_tree_add_item_ret_uint(drda_tree, hf_drda_ddm_rc, tvb, 4, 2, ENC_BIG_ENDIAN, &correl);
|
|
proto_tree_add_item(drda_tree, hf_drda_ddm_length2, tvb, 6, 2, ENC_BIG_ENDIAN);
|
|
|
|
proto_tree_add_item_ret_uint(drda_tree, hf_drda_ddm_codepoint, tvb, 8, 2, ENC_BIG_ENDIAN, &iCommand);
|
|
is_server = drda_packet_from_server(pinfo, iCommand, dsstyp);
|
|
proto_item_append_text(ti, " (%s)", val_to_str_ext(iCommand, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
|
|
proto_item_append_text(ddm_ti, " (%s)", val_to_str_ext(iCommand, &drda_opcode_abbr_ext, "Unknown (0x%02x)"));
|
|
col_append_sep_str(pinfo->cinfo, COL_INFO, " | ", val_to_str_ext(iCommand, &drda_opcode_abbr_ext, "Unknown (0x%02x)"));
|
|
col_set_fence(pinfo->cinfo, COL_INFO);
|
|
|
|
pdu_info = drda_get_pdu_info(pinfo, correl, is_server);
|
|
|
|
/* There are a few command objects treated differently, like SNDPKT */
|
|
if (!dissector_try_uint_new(drda_opcode_table, iCommand, tvb_new_subset_length(tvb, 10, iLength - 10), pinfo, drda_tree, FALSE, pdu_info)) {
|
|
/* The number of attributes is variable */
|
|
offset = 10;
|
|
while (tvb_reported_length_remaining(tvb, offset) >= 2)
|
|
{
|
|
iLengthParam = tvb_get_ntohs(tvb, offset + 0);
|
|
if (iLengthParam == 0 || iLengthParam == 1)
|
|
iLengthParam = iLength - 10;
|
|
if (tvb_reported_length_remaining(tvb, offset) >= iLengthParam)
|
|
{
|
|
iParameterCP = tvb_get_ntohs(tvb, offset + 2);
|
|
drda_tree_sub = proto_tree_add_subtree(drdaroot_tree, tvb, offset, iLengthParam,
|
|
ett_drda_param, &ti, DRDA_TEXT_PARAM);
|
|
proto_item_append_text(ti, " (%s)", val_to_str_ext(iParameterCP, &drda_opcode_vals_ext, "Unknown (0x%02x)"));
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_length, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_codepoint, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
|
|
if (!dissector_try_uint_new(drda_opcode_table, iParameterCP, tvb_new_subset_length(tvb, offset + 4, iLengthParam - 4), pinfo, drda_tree_sub, FALSE, pdu_info)) {
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_data, tvb, offset + 4, iLengthParam - 4, ENC_UTF_8);
|
|
proto_tree_add_item(drda_tree_sub, hf_drda_param_data_ebcdic, tvb, offset + 4, iLengthParam - 4, ENC_EBCDIC_CP500);
|
|
}
|
|
}
|
|
offset += iLengthParam;
|
|
}
|
|
}
|
|
conv_info = drda_get_conv_info(pinfo);
|
|
if (iCommand == DRDA_CP_EXCSATRD) {
|
|
/* EXCSATRD should be from the server, it confirms the negotiated
|
|
* values for the MGRLVLLS that both directions will use. */
|
|
flow = conv_info->server;
|
|
if (GPOINTER_TO_UINT(wmem_tree_lookup32_le(flow->sqlam_tree, pinfo->num)) != pdu_info->sqlam) {
|
|
wmem_tree_insert32(flow->sqlam_tree, pinfo->num, GUINT_TO_POINTER(pdu_info->sqlam));
|
|
}
|
|
flow = conv_info->client;
|
|
if (GPOINTER_TO_UINT(wmem_tree_lookup32_le(flow->sqlam_tree, pinfo->num)) != pdu_info->sqlam) {
|
|
wmem_tree_insert32(flow->sqlam_tree, pinfo->num, GUINT_TO_POINTER(pdu_info->sqlam));
|
|
}
|
|
} else if (iCommand == DRDA_CP_ACCRDB || iCommand == DRDA_CP_ACCRDBRM) {
|
|
/* The parameters configured by ACCRDB and ACCRDBRM, OTOH, are
|
|
* separate per-direction. */
|
|
flow = (iCommand == DRDA_CP_ACCRDB) ? conv_info->client : conv_info->server;
|
|
drda_update_flow_encoding(pinfo, flow, pdu_info);
|
|
}
|
|
|
|
return tvb_captured_length(tvb);
|
|
}
|
|
|
|
static guint
|
|
get_drda_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
|
|
{
|
|
return (tvb_get_ntohs(tvb, offset));
|
|
}
|
|
|
|
static int
|
|
dissect_drda_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
|
|
{
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DRDA");
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
/* There may be multiple DRDA commands in one frame */
|
|
tcp_dissect_pdus(tvb, pinfo, tree, drda_desegment, 10, get_drda_pdu_len, dissect_drda_pdu, data);
|
|
return tvb_captured_length(tvb);
|
|
}
|
|
|
|
|
|
static gboolean
|
|
dissect_drda_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|
{
|
|
conversation_t * conversation;
|
|
if (tvb_captured_length(tvb) >= 10)
|
|
{
|
|
/* The first header is 6 bytes long, so the length in the second header should 6 bytes less */
|
|
guint16 cOuterLength, cInnerLength;
|
|
cOuterLength = tvb_get_ntohs(tvb, 0);
|
|
cInnerLength = tvb_get_ntohs(tvb, 6);
|
|
if ((tvb_get_guint8(tvb, 2) == DRDA_MAGIC) && ((cOuterLength - cInnerLength) == 6))
|
|
{
|
|
/* Register this dissector for this conversation */
|
|
conversation = find_or_create_conversation(pinfo);
|
|
conversation_set_dissector(conversation, drda_tcp_handle);
|
|
|
|
/* Dissect the packet */
|
|
dissect_drda_tcp(tvb, pinfo, tree, data);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
proto_register_drda(void)
|
|
{
|
|
static hf_register_info hf[] = {
|
|
{ &hf_drda_ddm_length,
|
|
{ "Length", "drda.ddm.length",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"DDM length", HFILL }},
|
|
|
|
{ &hf_drda_ddm_magic,
|
|
{ "Magic", "drda.ddm.ddmid",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0,
|
|
"DDM magic", HFILL }},
|
|
|
|
{ &hf_drda_ddm_format,
|
|
{ "Format", "drda.ddm.format",
|
|
FT_UINT8, BASE_HEX, NULL, 0x0,
|
|
"DDM format", HFILL }},
|
|
|
|
{ &hf_drda_ddm_fmt_reserved,
|
|
{ "Reserved", "drda.ddm.fmt.bit0",
|
|
FT_BOOLEAN, 8, TFS(&tfs_set_notset), DRDA_DSSFMT_RESERVED,
|
|
"DSSFMT reserved", HFILL }},
|
|
|
|
{ &hf_drda_ddm_fmt_chained,
|
|
{ "Chained", "drda.ddm.fmt.bit1",
|
|
FT_BOOLEAN, 8, TFS(&tfs_set_notset), DRDA_DSSFMT_CHAINED,
|
|
"DSSFMT chained", HFILL }},
|
|
|
|
{ &hf_drda_ddm_fmt_errcont,
|
|
{ "Continue", "drda.ddm.fmt.bit2",
|
|
FT_BOOLEAN, 8, TFS(&tfs_set_notset), DRDA_DSSFMT_CONTINUE,
|
|
"DSSFMT continue on error", HFILL }},
|
|
|
|
{ &hf_drda_ddm_fmt_samecorr,
|
|
{ "Same correlation", "drda.ddm.fmt.bit3",
|
|
FT_BOOLEAN, 8, TFS(&tfs_set_notset), DRDA_DSSFMT_SAME_CORR,
|
|
"DSSFMT same correlation", HFILL }},
|
|
|
|
{ &hf_drda_ddm_fmt_dsstyp,
|
|
{ "DSS type", "drda.ddm.fmt.dsstyp",
|
|
FT_UINT8, BASE_DEC, VALS(drda_dsstyp_abbr), 0x0F,
|
|
"DSSFMT type", HFILL }},
|
|
|
|
{ &hf_drda_ddm_rc,
|
|
{ "CorrelId", "drda.ddm.rqscrr",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"DDM correlation identifier", HFILL }},
|
|
|
|
{ &hf_drda_ddm_length2,
|
|
{ "Length2", "drda.ddm.length2",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"DDM length2", HFILL }},
|
|
|
|
{ &hf_drda_ddm_codepoint,
|
|
{ "Code point", "drda.ddm.codepoint",
|
|
FT_UINT16, BASE_HEX|BASE_EXT_STRING, &drda_opcode_abbr_ext, 0x0,
|
|
"DDM code point", HFILL }},
|
|
|
|
{ &hf_drda_param_length,
|
|
{ "Length", "drda.param.length",
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
|
"Param length", HFILL }},
|
|
|
|
{ &hf_drda_param_codepoint,
|
|
{ "Code point", "drda.param.codepoint",
|
|
FT_UINT16, BASE_HEX|BASE_EXT_STRING, &drda_opcode_abbr_ext, 0x0,
|
|
"Param code point", HFILL }},
|
|
|
|
{ &hf_drda_param_data,
|
|
{ "Data (ASCII)", "drda.param.data",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"Param data left as ASCII for display", HFILL }},
|
|
|
|
{ &hf_drda_param_data_ebcdic,
|
|
{ "Data (EBCDIC)", "drda.param.data.ebcdic",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"Param data converted from EBCDIC to ASCII for display", HFILL }},
|
|
|
|
/* The DRDA spec really treats the NULL indicator as a FT_INT8, but
|
|
* range_strings with negative values are a little annoying.
|
|
*/
|
|
{ &hf_drda_null_ind,
|
|
{ "SQL NULL Indicator", "drda.null_ind",
|
|
FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(drda_null_ind_rvals),
|
|
0x0, NULL, HFILL }},
|
|
|
|
{ &hf_drda_typdefnam,
|
|
{ "Data Type Definition Name", "drda.typdefnam",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_clob_length,
|
|
{ "CLOB Length", "drda.clob.length",
|
|
FT_UINT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlstatement,
|
|
{ "SQL statement", "drda.sqlstatement",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlcagrp,
|
|
{ "SQL Communications Area Group Description", "drda.sqlcagrp",
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlcode,
|
|
{ "SQL code", "drda.sqlcode",
|
|
FT_INT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlstate,
|
|
{ "SQL state", "drda.sqlstate",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlerrproc,
|
|
{ "SQLERRPROC", "drda.sqlerrproc",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlcaxgrp,
|
|
{ "SQL Communications Area Exceptions Group", "drda.sqlcaxgrp",
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlerrd1,
|
|
{ "SQLERRD1", "drda.sqlerrd1",
|
|
FT_INT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlerrd2,
|
|
{ "SQLERRD2", "drda.sqlerrd2",
|
|
FT_INT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlerrd3,
|
|
{ "SQLERRD3", "drda.sqlerrd3",
|
|
FT_INT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlerrd4,
|
|
{ "SQLERRD4", "drda.sqlerrd4",
|
|
FT_INT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlerrd5,
|
|
{ "SQLERRD5", "drda.sqlerrd5",
|
|
FT_INT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlerrd6,
|
|
{ "SQLERRD6", "drda.sqlerrd6",
|
|
FT_INT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn0,
|
|
{ "SQLWARN0", "drda.sqlwarn0",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn1,
|
|
{ "SQLWARN1", "drda.sqlwarn1",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn2,
|
|
{ "SQLWARN2", "drda.sqlwarn2",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn3,
|
|
{ "SQLWARN3", "drda.sqlwarn3",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn4,
|
|
{ "SQLWARN4", "drda.sqlwarn4",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn5,
|
|
{ "SQLWARN5", "drda.sqlwarn5",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn6,
|
|
{ "SQLWARN6", "drda.sqlwarn6",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn7,
|
|
{ "SQLWARN7", "drda.sqlwarn7",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn8,
|
|
{ "SQLWARN8", "drda.sqlwarn8",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarn9,
|
|
{ "SQLWARN9", "drda.sqlwarn9",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlwarna,
|
|
{ "SQLWARNA", "drda.sqlwarna",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlerrmsg,
|
|
{ "SQL Error Message Token", "drda.sqlerrmsg",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldhgrp,
|
|
{ "SQL Descriptor Header Group Description", "drda.sqldhgrp",
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldhold,
|
|
{ "SQLDHOLD", "drda.sqldhold",
|
|
FT_INT16, BASE_DEC, VALS(drda_hold_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldreturn,
|
|
{ "SQLDRETURN", "drda.sqldreturn",
|
|
FT_INT16, BASE_DEC, VALS(drda_return_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldscroll,
|
|
{ "SQLDSCROLL", "drda.sqldscroll",
|
|
FT_INT16, BASE_DEC, VALS(drda_scroll_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldsensitive,
|
|
{ "SQLDSENSITIVE", "drda.sqldsensitive",
|
|
FT_INT16, BASE_DEC, VALS(drda_sensitive_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldfcode,
|
|
{ "SQLDFCODE", "drda.sqldfcode",
|
|
FT_INT16, BASE_DEC, VALS(drda_fcode_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldkeytype,
|
|
{ "SQLDKEYTYPE", "drda.sqldkeytype",
|
|
FT_INT16, BASE_DEC, VALS(drda_keytype_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldoptlck,
|
|
{ "SQLDOPTLCK", "drda.sqldoptlck",
|
|
FT_INT16, BASE_DEC, VALS(drda_doptlck_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldschema,
|
|
{ "SQLDSCHEMA", "drda.sqldschema",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldmodule,
|
|
{ "SQLDMODULE", "drda.sqldmodule",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldagrp,
|
|
{ "SQL Descriptor Area Group Description", "drda.sqldagrp",
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlprecision,
|
|
{ "SQLPRECISION", "drda.sqlprecision",
|
|
FT_INT16, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlscale,
|
|
{ "SQLSCALE", "drda.sqlscale",
|
|
FT_INT16, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqllength,
|
|
{ "SQLLENGTH", "drda.sqllength",
|
|
FT_INT64, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqllength32,
|
|
{ "SQLLENGTH", "drda.sqllength",
|
|
FT_INT32, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqltype,
|
|
{ "SQLTYPE", "drda.sqltype",
|
|
FT_INT16, BASE_DEC, VALS(drda_sqltype_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlarrextent,
|
|
{ "SQLARREXTENT", "drda.sqlarrextent",
|
|
FT_INT64, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldoptgrp,
|
|
{ "SQL Descriptor Optional Group Description", "drda.sqldoptgrp",
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlunnamed,
|
|
{ "SQLUNNAMED", "drda.sqlunnamed",
|
|
FT_INT16, BASE_DEC, VALS(drda_unnamed_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlname,
|
|
{ "SQLNAME", "drda.sqlname",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqllabel,
|
|
{ "SQLLABEL", "drda.sqllabel",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlcomments,
|
|
{ "SQLCOMMENTS", "drda.sqlcomments",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqludtgrp,
|
|
{ "SQL Descriptor User-Defined Type Group Description",
|
|
"drda.sqludtgrp",
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqludtxtype,
|
|
{ "SQLUDTXTYPE", "drda.sqludtxtype",
|
|
FT_INT32, BASE_DEC, VALS(drda_udtxtype_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqludtschema,
|
|
{ "SQLUDTSCHEMA", "drda.sqludtschema",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqludtname,
|
|
{ "SQLUDTNAME", "drda.sqludtname",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqludtmodule,
|
|
{ "SQLUDTMODULE", "drda.sqludtmodule",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldxgrp,
|
|
{ "SQL Descriptor Extended Type Group Description", "drda.sqldxgrp",
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxkeymem,
|
|
{ "SQLXKEYMEM", "drda.sqlxkeymem",
|
|
FT_INT16, BASE_DEC, VALS(drda_keymem_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxupdateable,
|
|
{ "SQLXUPDATEABLE", "drda.sqlxupdateable",
|
|
FT_INT16, BASE_DEC, VALS(drda_updateable_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxgenerated,
|
|
{ "SQLXGENERATED", "drda.sqlxgenerated",
|
|
FT_INT16, BASE_DEC, VALS(drda_generated_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxparmmode,
|
|
{ "SQLXPARMMODE", "drda.sqlxparmmode",
|
|
FT_INT16, BASE_DEC, VALS(drda_parmmode_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxoptlck,
|
|
{ "SQLXOPTLCK", "drda.sqlxoptlck",
|
|
FT_INT16, BASE_DEC, VALS(drda_xoptlck_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxhidden,
|
|
{ "SQLXHIDDEN", "drda.sqlxhidden",
|
|
FT_INT16, BASE_DEC, VALS(drda_hidden_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxcorname,
|
|
{ "SQLXCORNAME", "drda.sqlxcorname",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxbasename,
|
|
{ "SQLXBASENAME", "drda.sqlxbasename",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxschema,
|
|
{ "SQLXSCHEMA", "drda.sqlxschema",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxname,
|
|
{ "SQLXNAME", "drda.sqlxname",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlxmodule,
|
|
{ "SQLXMODULE", "drda.sqlxmodule",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqldiaggrp,
|
|
{ "SQL Diagnostics Group Description", "drda.sqldiaggrp",
|
|
FT_NONE, BASE_NONE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlnum,
|
|
{ "SQLNUM", "drda.sqlnum",
|
|
FT_INT16, BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_rlsconv,
|
|
{ "Release Conversation", "drda.rlsconv", FT_UINT8, BASE_NONE,
|
|
VALS(drda_rlsconv_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_secmec,
|
|
{ "Security Mechanism", "drda.secmec", FT_UINT16, BASE_DEC,
|
|
VALS(drda_secmec_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sectkn,
|
|
{ "Security Token", "drda.sectkn", FT_BYTES, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_svrcod,
|
|
{ "Severity Code", "drda.svrcod", FT_UINT16, BASE_DEC,
|
|
VALS(drda_svrcod_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_secchkcd,
|
|
{ "Security Check Code", "drda.secchkcd", FT_UINT8, BASE_HEX,
|
|
VALS(drda_secchkcd_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_ccsid,
|
|
{ "CCSID", "drda.ccsid", FT_UINT16, BASE_DEC,
|
|
VALS(drda_ccsid_vals), 0x0,
|
|
"Coded Character Set Identifier", HFILL }},
|
|
|
|
{ &hf_drda_mgrlvln,
|
|
{ "Manager-level Number", "drda.mgrlvln", FT_UINT16, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_monitor,
|
|
{ "Monitor", "drda.monitor", FT_UINT32, BASE_HEX,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_monitor_etime,
|
|
{ "Elapsed Time", "drda.monitor.etime", FT_BOOLEAN, 32,
|
|
NULL, 0x80000000,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_monitor_reserved,
|
|
{ "Reserved", "drda.monitor.reserved", FT_UINT32, BASE_HEX,
|
|
NULL, 0x7FFFFFFF,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_etime,
|
|
{ "Elapsed Time", "drda.etime", FT_RELATIVE_TIME, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_respktsz,
|
|
{ "Response Packet Size", "drda.respktsz", FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_rdbinttkn,
|
|
{ "RDB Interrupt Token", "drda.rdbinttkn", FT_BYTES, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_rdbcmtok,
|
|
{ "RDB Commit Allowed", "drda.rdbcmtok", FT_UINT8, BASE_NONE,
|
|
VALS(drda_boolean_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
/* This one is a 0x00 0x01 boolean, not a EBCDIC 0xf0 0xf1 boolean */
|
|
{ &hf_drda_rtnsetstt,
|
|
{ "Return SET Statement", "drda.rtnsetstt", FT_BOOLEAN, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_outexp,
|
|
{ "Output Expected", "drda.outexp", FT_UINT8, BASE_NONE,
|
|
VALS(drda_boolean_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_rdbnam,
|
|
{ "Relational Database Name (ASCII)", "drda.rdbnam", FT_STRING,
|
|
BASE_NONE, NULL, 0x0,
|
|
"RDBNAM assuming ASCII/UTF-8", HFILL }},
|
|
|
|
{ &hf_drda_rdbnam_ebcdic,
|
|
{ "Relational Database Name (EBCDIC)", "drda.rdbnam.ebcdic", FT_STRING,
|
|
BASE_NONE, NULL, 0x0,
|
|
"RBDNAM assuming EBCDIC", HFILL }},
|
|
|
|
{ &hf_drda_rdbcolid,
|
|
{ "RDB Collection Identifier (ASCII)", "drda.rdbcoldid", FT_STRING,
|
|
BASE_NONE, NULL, 0x0,
|
|
"RDBCOLID assuming ASCII/UTF-8", HFILL }},
|
|
|
|
{ &hf_drda_rdbcolid_ebcdic,
|
|
{ "RDB Collection Identifier (EBCDIC)", "drda.rdbcolid.ebcdic",
|
|
FT_STRING, BASE_NONE, NULL, 0x0,
|
|
"RBDCOLID assuming EBCDIC", HFILL }},
|
|
|
|
{ &hf_drda_pkgid,
|
|
{ "RDB Package Identifier (ASCII)", "drda.pkgid", FT_STRING, BASE_NONE,
|
|
NULL, 0x0,
|
|
"PKGID assuming ASCII/UTF-8", HFILL }},
|
|
|
|
{ &hf_drda_pkgid_ebcdic,
|
|
{ "RDB Package Identifier (EBCDIC)", "drda.pkgid.ebcdic", FT_STRING,
|
|
BASE_NONE, NULL, 0x0,
|
|
"PKGID assuming EBCDIC", HFILL }},
|
|
|
|
{ &hf_drda_pkgsn,
|
|
{ "RDB Package Section Number", "drda.pkgsn", FT_INT16,
|
|
BASE_DEC, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_pkgcnstkn,
|
|
{ "RDB Package Consistency Token", "drda.pkgcnstkn", FT_BYTES,
|
|
BASE_NONE|BASE_SHOW_ASCII_PRINTABLE, NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_qryblksz,
|
|
{ "Query Block Size", "drda.qryblksz", FT_UINT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_uowdsp,
|
|
{ "Unit of Work Disposition", "drda.uowdsp", FT_UINT8, BASE_HEX,
|
|
VALS(drda_uowdsp_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_rdbalwupd,
|
|
{ "RDB Allow Updates", "drda.rdbalwupd", FT_UINT8, BASE_HEX,
|
|
VALS(drda_boolean_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_sqlcsrhld,
|
|
{ "Hold Cursor Position", "drda.sqlcsrhld", FT_UINT8, BASE_HEX,
|
|
VALS(drda_boolean_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_qryextdtasz,
|
|
{ "Query Externalized Data Size", "drda.qryextdtasz", FT_INT64,
|
|
BASE_DEC|BASE_VAL64_STRING|BASE_SPECIAL_VALS,
|
|
VALS64(drda_qryextdtasz_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_smldtasz,
|
|
{ "Maximum Size of Small Data", "drda.smldtasz", FT_INT64, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_meddtasz,
|
|
{ "Maximum Size of Medium Data", "drda.meddtasz", FT_INT64, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_trgdftrt,
|
|
{ "Target Default Value Return", "drda.trgdftrt", FT_UINT8, BASE_HEX,
|
|
VALS(drda_boolean_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_rtnsqlda,
|
|
{ "Return the SQLDA", "drda.rtnsqlda", FT_UINT8, BASE_HEX,
|
|
VALS(drda_boolean_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_qryattupd,
|
|
{ "Query Attribute for Updatability", "drda.qryattupd", FT_INT8,
|
|
BASE_DEC, VALS(drda_qryattupd_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_qryrowset,
|
|
{ "Query Rowset Size", "drda.qryrowset", FT_INT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_qryinsid,
|
|
{ "Query Instance Identifier", "drda.qryinsid", FT_BYTES, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_qryclsimp,
|
|
{ "Query Close Implicit", "drda.qryclsimp", FT_INT8, BASE_DEC,
|
|
VALS(drda_qryclsimp_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_qryblkfct,
|
|
{ "Query Blocking Factor", "drda.qryblkfct", FT_INT32, BASE_DEC,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_maxrslcnt,
|
|
{ "Maximum Result Set Count", "drda.maxrslcnt", FT_INT32,
|
|
BASE_DEC|BASE_SPECIAL_VALS, VALS(drda_max_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_maxblkext,
|
|
{ "Maximum Number of Extra Blocks", "drda.maxblkext", FT_INT32,
|
|
BASE_DEC|BASE_SPECIAL_VALS, VALS(drda_max_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_rslsetflg,
|
|
{ "Result Set Flags", "drda.rslsetflg", FT_UINT8, BASE_HEX,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_rslsetflg_unused,
|
|
{ "Unused", "drda.rslsetflg.unused", FT_UINT8, BASE_HEX,
|
|
NULL, 0xE0,
|
|
"Flags are no longer used and value should be zero", HFILL }},
|
|
|
|
{ &hf_drda_rslsetflg_dsconly,
|
|
{ "Description Only", "drda.rslsetflg.dsconly", FT_BOOLEAN, 8,
|
|
NULL, 0x10,
|
|
"Requires the target SQLAM to return an FD:OCA description but not any answer set data", HFILL }},
|
|
|
|
{ &hf_drda_rslsetflg_extended,
|
|
{ "Extended", "drda.rslsetflg.extended", FT_UINT8, BASE_HEX,
|
|
VALS(drda_rslsetflg_extended_vals), 0x0C,
|
|
"Identifies the type of FD:OCA SQLDA descriptor returned", HFILL }},
|
|
|
|
{ &hf_drda_rslsetflg_reserved,
|
|
{ "Reserved", "drda.rslsetflg.reserved", FT_UINT8, BASE_HEX,
|
|
NULL, 0x03,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_typsqlda,
|
|
{ "Type of SQL Descriptor Area", "drda.typsqlda", FT_INT8, BASE_DEC,
|
|
VALS(drda_typsqlda_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_outovropt,
|
|
{ "Output Override Option", "drda.outovropt", FT_INT8, BASE_DEC,
|
|
VALS(drda_outovropt_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_dyndtafmt,
|
|
{ "Dynamic Data Format", "drda.dyndtafmt", FT_UINT8, BASE_HEX,
|
|
VALS(drda_boolean_vals), 0x0,
|
|
NULL, HFILL }},
|
|
|
|
{ &hf_drda_pktobj,
|
|
{ "Packet Object", "drda.pktobj", FT_BYTES, BASE_NONE,
|
|
NULL, 0x0,
|
|
NULL, HFILL }},
|
|
};
|
|
|
|
static gint *ett[] = {
|
|
&ett_drda,
|
|
&ett_drda_ddm,
|
|
&ett_drda_ddm_format,
|
|
&ett_drda_param,
|
|
&ett_drda_monitor,
|
|
&ett_drda_rslsetflg,
|
|
&ett_drda_sqlcagrp,
|
|
&ett_drda_sqlcaxgrp,
|
|
&ett_drda_sqldhgrp,
|
|
&ett_drda_sqldagrp,
|
|
&ett_drda_sqldoptgrp,
|
|
&ett_drda_sqludtgrp,
|
|
&ett_drda_sqldxgrp,
|
|
&ett_drda_sqldiaggrp,
|
|
};
|
|
|
|
static ei_register_info ei[] = {
|
|
{ &ei_drda_opcode_invalid_length, { "drda.opcode.invalid_length", PI_MALFORMED, PI_ERROR, "Invalid length detected", EXPFILL }},
|
|
{ &ei_drda_undecoded, { "drda.undecoded", PI_UNDECODED, PI_NOTE, "[Not decoded yet]", EXPFILL }},
|
|
};
|
|
|
|
module_t *drda_module;
|
|
expert_module_t* expert_drda;
|
|
|
|
proto_drda = proto_register_protocol("DRDA", "DRDA", "drda");
|
|
proto_register_field_array(proto_drda, hf, array_length(hf));
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
expert_drda = expert_register_protocol(proto_drda);
|
|
expert_register_field_array(expert_drda, ei, array_length(ei));
|
|
|
|
drda_opcode_table = register_dissector_table("drda.opcode", "DRDA opcode",
|
|
proto_drda, FT_UINT16, BASE_HEX);
|
|
|
|
drda_module = prefs_register_protocol(proto_drda, NULL);
|
|
prefs_register_bool_preference(drda_module, "desegment",
|
|
"Reassemble DRDA messages spanning multiple TCP segments",
|
|
"Whether the DRDA dissector should reassemble messages spanning"
|
|
" multiple TCP segments."
|
|
" To use this option, you must also enable"
|
|
" \"Allow subdissectors to reassemble TCP streams\""
|
|
" in the TCP protocol settings.",
|
|
&drda_desegment);
|
|
|
|
prefs_register_uint_preference(drda_module, "sqlam",
|
|
"Default SQLAM Level",
|
|
"Default SQL Application Manager Level in the absence"
|
|
" of EXSATRD command. (Currently the only difference"
|
|
" in handling is between values < 7 and >= 7.)",
|
|
10, &drda_default_sqlam);
|
|
|
|
prefs_register_enum_preference(drda_module, "typdefnam",
|
|
"Default TYPDEFNAM",
|
|
"Data Type Definition to use in the absence of"
|
|
" ACCRDB and ACCRDBRM commands.",
|
|
&drda_default_typdefnam,
|
|
typdefnam_vals, FALSE);
|
|
|
|
prefs_register_enum_preference(drda_module, "ccsidsbc",
|
|
"Default Single-byte encoding for FD:OCA data",
|
|
"Single-byte encoding to use for FD:OCA character data"
|
|
" in the absence of CCSIDSBC TYPDEFOVR parameter.",
|
|
&drda_default_ccsidsbc,
|
|
ws_supported_mibenum_vals_character_sets_ev_array,
|
|
FALSE);
|
|
|
|
prefs_register_enum_preference(drda_module, "ccsidmbc",
|
|
"Default Mixed-byte encoding for FD:OCA data",
|
|
"Mixed-byte encoding to use for FD:OCA character data"
|
|
" in the absence of CCSIDMBC TYPDEFOVR parameter.",
|
|
&drda_default_ccsidmbc,
|
|
ws_supported_mibenum_vals_character_sets_ev_array,
|
|
FALSE);
|
|
|
|
drda_tcp_handle = register_dissector("drda", dissect_drda_tcp, proto_drda);
|
|
}
|
|
|
|
void
|
|
proto_reg_handoff_drda(void)
|
|
{
|
|
heur_dissector_add("tcp", dissect_drda_heur, "DRDA over TCP", "drda_tcp", proto_drda, HEURISTIC_ENABLE);
|
|
|
|
dissector_handle_t ccsid_handle;
|
|
dissector_handle_t codpntdr_handle;
|
|
dissector_handle_t collection_handle;
|
|
dissector_handle_t sqlstt_handle;
|
|
dissector_handle_t undecoded_handle;
|
|
|
|
ccsid_handle = create_dissector_handle(dissect_drda_ccsid, proto_drda);
|
|
codpntdr_handle = create_dissector_handle(dissect_drda_codpntdr, proto_drda);
|
|
collection_handle = create_dissector_handle(dissect_drda_collection, proto_drda);
|
|
sqlstt_handle = create_dissector_handle(dissect_drda_sqlstt, proto_drda);
|
|
undecoded_handle = create_dissector_handle(dissect_drda_undecoded, proto_drda);
|
|
|
|
dissector_add_uint("drda.opcode", DRDA_CP_TYPDEFNAM, create_dissector_handle(dissect_drda_typdefnam, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_MGRLVLLS, create_dissector_handle(dissect_drda_mgrlvlls, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_TYPDEFOVR, collection_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_PKGSNLST, collection_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RLSCONV, create_dissector_handle(dissect_drda_rlsconv, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SECMEC, create_dissector_handle(dissect_drda_secmec, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SECTKN, create_dissector_handle(dissect_drda_sectkn, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SVRCOD, create_dissector_handle(dissect_drda_svrcod, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SECCHKCD, create_dissector_handle(dissect_drda_secchkcd, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_CCSIDSBC, ccsid_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_CCSIDDBC, ccsid_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_CCSIDMBC, ccsid_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_CCSIDXML, ccsid_handle);
|
|
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RDBACCCL, codpntdr_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYPRCTYP, codpntdr_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_PKGDFTCST, codpntdr_handle);
|
|
dissector_add_uint("drda.opcode", 0x2460, codpntdr_handle); /* Not in DRDA, Version 5 */
|
|
|
|
dissector_add_uint("drda.opcode", DRDA_CP_MONITOR, create_dissector_handle(dissect_drda_monitor, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_ETIME, create_dissector_handle(dissect_drda_etime, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RESPKTSZ, create_dissector_handle(dissect_drda_respktsz, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RDBINTTKN, create_dissector_handle(dissect_drda_rdbinttkn, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RDBCMTOK, create_dissector_handle(dissect_drda_rdbcmtok, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RTNSETSTT, create_dissector_handle(dissect_drda_rtnsetstt, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_OUTEXP, create_dissector_handle(dissect_drda_outexp, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_PKGNAM, create_dissector_handle(dissect_drda_pkgnam, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_PKGNAMCT, create_dissector_handle(dissect_drda_pkgnamct, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_PKGNAMCSN, create_dissector_handle(dissect_drda_pkgnamcsn, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_UOWDSP, create_dissector_handle(dissect_drda_uowdsp, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RDBALWUPD, create_dissector_handle(dissect_drda_rdbalwupd, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYBLKSZ, create_dissector_handle(dissect_drda_qryblksz, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RTNSQLDA, create_dissector_handle(dissect_drda_rtnsqlda, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SQLCSRHLD, create_dissector_handle(dissect_drda_sqlcsrhld, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYEXTDTASZ, create_dissector_handle(dissect_drda_qryextdtasz, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SMLDTASZ, create_dissector_handle(dissect_drda_smldtasz, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_MEDDTASZ, create_dissector_handle(dissect_drda_meddtasz, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_TRGDFTRT, create_dissector_handle(dissect_drda_trgdftrt, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYATTUPD, create_dissector_handle(dissect_drda_qryattupd, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYROWSET, create_dissector_handle(dissect_drda_qryrowset, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYINSID, create_dissector_handle(dissect_drda_qryinsid, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYCLSIMP, create_dissector_handle(dissect_drda_qryclsimp, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYBLKFCT, create_dissector_handle(dissect_drda_qryblkfct, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_MAXRSLCNT, create_dissector_handle(dissect_drda_maxrslcnt, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_MAXBLKEXT, create_dissector_handle(dissect_drda_maxblkext, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_RSLSETFLG, create_dissector_handle(dissect_drda_rslsetflg, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_TYPSQLDA, create_dissector_handle(dissect_drda_typsqlda, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_OUTOVROPT, create_dissector_handle(dissect_drda_outovropt, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_DYNDTAFMT, create_dissector_handle(dissect_drda_dyndtafmt, proto_drda));
|
|
|
|
dissector_add_uint("drda.opcode", DRDA_CP_PKTOBJ, create_dissector_handle(dissect_drda_pktobj, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SQLSTT, sqlstt_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SQLATTR, sqlstt_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SQLCARD, create_dissector_handle(dissect_drda_sqlcard, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_SQLDARD, create_dissector_handle(dissect_drda_sqldard, proto_drda));
|
|
dissector_add_uint("drda.opcode", DRDA_CP_FDODSC, undecoded_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_FDODTA, undecoded_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYDSC, undecoded_handle);
|
|
dissector_add_uint("drda.opcode", DRDA_CP_QRYDTA, undecoded_handle);
|
|
}
|
|
|
|
/*
|
|
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
|
*
|
|
* Local variables:
|
|
* c-basic-offset: 4
|
|
* tab-width: 8
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*
|
|
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
*/
|