2 * Routines for MySQL/MariaDB packet dissection
4 * Huagang XIE <huagang@intruvert.com>
6 * MySQL 4.1+ protocol by Axel Schwenke <axel@mysql.com>
7 * MariaDB protocol by Georg Richter <georg@mariadb.com>
8 * & Diego Dupin <diego.dupin@mariadb.com>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * Copied from packet-tftp.c
16 * SPDX-License-Identifier: GPL-2.0-or-later
19 * the protocol specifications
21 * https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_PROTOCOL.html
23 * https://mariadb.com/kb/en/clientserver-protocol/
24 * and MySQL source code
27 /* create extra output for conversation tracking */
28 /* #define CTDEBUG 1 */
32 #include <epan/packet.h>
33 #include <epan/prefs.h>
34 #include <epan/expert.h>
36 #include <wsutil/array.h>
37 #include <epan/proto_data.h>
38 #include <epan/reassemble.h>
39 #include <epan/exceptions.h>
40 #include <epan/show_exception.h>
41 #include "packet-tcp.h"
42 #include "packet-tls-utils.h"
44 void proto_register_mysql(void);
45 void proto_reg_handoff_mysql(void);
47 /* port for protocol registration */
48 #define TCP_PORT_MySQL 3306
50 #define MYSQL_HEADER_LENGTH 4
52 /* MariaDB Server >= 10.0 sends a 5.5.5- prefix for the version, since
53 replication doesn't support a two digit version number. Version 5.5.5
54 was never released in MySQL and MariaDB */
55 #define MARIADB_RPL_VERSION_HACK "5.5.5-"
57 /* client/server capabilities
58 * Docs: https://dev.mysql.com/doc/dev/mysql-server/latest/group__group__cs__capabilities__flags.html
59 * Source: https://github.com/mysql/mysql-server/blob/8.0/include/mysql_com.h
61 #define MYSQL_CAPS_LP 0x0001 /* CLIENT_LONG_PASSWORD/CLIENT_IS_MYSQL */
62 #define MYSQL_CAPS_FR 0x0002 /* CLIENT_FOUND_ROWS */
63 #define MYSQL_CAPS_LF 0x0004 /* CLIENT_LONG_FLAG */
64 #define MYSQL_CAPS_CD 0x0008 /* CLIENT_CONNECT_WITH_DB */
65 #define MYSQL_CAPS_NS 0x0010 /* CLIENT_NO_SCHEMA */
66 #define MYSQL_CAPS_CP 0x0020 /* CLIENT_COMPRESS */
67 #define MYSQL_CAPS_OB 0x0040 /* CLIENT_ODBC */
68 #define MYSQL_CAPS_LI 0x0080 /* CLIENT_LOCAL_FILES */
69 #define MYSQL_CAPS_IS 0x0100 /* CLIENT_IGNORE_SPACE */
70 #define MYSQL_CAPS_CU 0x0200 /* CLIENT_PROTOCOL_41 */
71 #define MYSQL_CAPS_IA 0x0400 /* CLIENT_INTERACTIVE */
72 #define MYSQL_CAPS_SL 0x0800 /* CLIENT_SSL */
73 #define MYSQL_CAPS_II 0x1000 /* CLIENT_IGNORE_SPACE */
74 #define MYSQL_CAPS_TA 0x2000 /* CLIENT_TRANSACTIONS */
75 #define MYSQL_CAPS_RS 0x4000 /* CLIENT_RESERVED */
76 #define MYSQL_CAPS_SC 0x8000 /* CLIENT_SECURE_CONNECTION */
80 #define MYSQL_FLD_NOT_NULL_FLAG 0x0001
81 #define MYSQL_FLD_PRI_KEY_FLAG 0x0002
82 #define MYSQL_FLD_UNIQUE_KEY_FLAG 0x0004
83 #define MYSQL_FLD_MULTIPLE_KEY_FLAG 0x0008
84 #define MYSQL_FLD_BLOB_FLAG 0x0010
85 #define MYSQL_FLD_UNSIGNED_FLAG 0x0020
86 #define MYSQL_FLD_ZEROFILL_FLAG 0x0040
87 #define MYSQL_FLD_BINARY_FLAG 0x0080
88 #define MYSQL_FLD_ENUM_FLAG 0x0100
89 #define MYSQL_FLD_AUTO_INCREMENT_FLAG 0x0200
90 #define MYSQL_FLD_TIMESTAMP_FLAG 0x0400
91 #define MYSQL_FLD_SET_FLAG 0x0800
93 /* extended capabilities: 4.1+ client only
95 * These are libmysqlclient flags and NOT present
97 * CLIENT_REMEMBER_OPTIONS (1UL << 31)
99 #define MYSQL_CAPS_MS 0x0001 /* CLIENT_MULTI_STATEMENTS */
100 #define MYSQL_CAPS_MR 0x0002 /* CLIENT_MULTI_RESULTS */
101 #define MYSQL_CAPS_PM 0x0004 /* CLIENT_PS_MULTI_RESULTS */
102 #define MYSQL_CAPS_PA 0x0008 /* CLIENT_PLUGIN_AUTH */
103 #define MYSQL_CAPS_CA 0x0010 /* CLIENT_CONNECT_ATTRS */
104 #define MYSQL_CAPS_AL 0x0020 /* CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA */
105 #define MYSQL_CAPS_EP 0x0040 /* CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS */
106 #define MYSQL_CAPS_ST 0x0080 /* CLIENT_SESSION_TRACK */
107 #define MYSQL_CAPS_DE 0x0100 /* CLIENT_DEPRECATE_EOF */
108 #define MYSQL_CAPS_RM 0x0200 /* CLIENT_OPTIONAL_RESULTSET_METADATA */
109 #define MYSQL_CAPS_ZS 0x0400 /* CLIENT_ZSTD_COMPRESSION_ALGORITHM */
110 #define MYSQL_CAPS_QA 0x0800 /* CLIENT_QUERY_ATTRIBUTES */
111 #define MYSQL_CAPS_MF 0x1000 /* MULTI_FACTOR_AUTHENTICATION */
112 #define MYSQL_CAPS_CE 0x2000 /* CLIENT_CAPABILITY_EXTENSION */
113 #define MYSQL_CAPS_VC 0x4000 /* CLIENT_SSL_VERIFY_SERVER_CERT */
115 #define MYSQL_CAPS_UNUSED 0x8000 /* Currently only a single bit */
117 /* status bitfield */
118 #define MYSQL_STAT_IT 0x0001
119 #define MYSQL_STAT_AC 0x0002
120 #define MYSQL_STAT_MU 0x0004
121 #define MYSQL_STAT_MR 0x0008
122 #define MYSQL_STAT_BI 0x0010
123 #define MYSQL_STAT_NI 0x0020
124 #define MYSQL_STAT_CR 0x0040
125 #define MYSQL_STAT_LR 0x0080
126 #define MYSQL_STAT_DR 0x0100
127 #define MYSQL_STAT_BS 0x0200
128 #define MYSQL_STAT_MC 0x0400
129 #define MYSQL_STAT_QUERY_WAS_SLOW 0x0800
130 #define MYSQL_STAT_PS_OUT_PARAMS 0x1000
131 #define MYSQL_STAT_TRANS_READONLY 0x2000
132 #define MYSQL_STAT_SESSION_STATE_CHANGED 0x4000
134 /* bitfield for MYSQL_REFRESH */
135 #define MYSQL_RFSH_GRANT 1 /* Refresh grant tables */
136 #define MYSQL_RFSH_LOG 2 /* Start on new log file */
137 #define MYSQL_RFSH_TABLES 4 /* close all tables */
138 #define MYSQL_RFSH_HOSTS 8 /* Flush host cache */
139 #define MYSQL_RFSH_STATUS 16 /* Flush status variables */
140 #define MYSQL_RFSH_THREADS 32 /* Flush thread cache */
141 #define MYSQL_RFSH_SLAVE 64 /* Reset master info and restart slave thread */
142 #define MYSQL_RFSH_MASTER 128 /* Remove all bin logs in the index and truncate the index */
144 /* MySQL command codes (enum_server_command in mysql-server.git:include/my_command.h) */
145 #define MYSQL_SLEEP 0 /* not from client */
147 #define MYSQL_INIT_DB 2
148 #define MYSQL_QUERY 3
149 #define MYSQL_FIELD_LIST 4
150 #define MYSQL_CREATE_DB 5
151 #define MYSQL_DROP_DB 6
152 #define MYSQL_REFRESH 7
153 #define MYSQL_SHUTDOWN 8
154 #define MYSQL_STATISTICS 9
155 #define MYSQL_PROCESS_INFO 10
156 #define MYSQL_CONNECT 11 /* not from client */
157 #define MYSQL_PROCESS_KILL 12
158 #define MYSQL_DEBUG 13
159 #define MYSQL_PING 14
160 #define MYSQL_TIME 15 /* not from client */
161 #define MYSQL_DELAY_INSERT 16 /* not from client */
162 #define MYSQL_CHANGE_USER 17
163 #define MYSQL_BINLOG_DUMP 18 /* replication */
164 #define MYSQL_TABLE_DUMP 19 /* replication */
165 #define MYSQL_CONNECT_OUT 20 /* replication */
166 #define MYSQL_REGISTER_SLAVE 21 /* replication */
167 #define MYSQL_STMT_PREPARE 22
168 #define MYSQL_STMT_EXECUTE 23
169 #define MYSQL_STMT_SEND_LONG_DATA 24
170 #define MYSQL_STMT_CLOSE 25
171 #define MYSQL_STMT_RESET 26
172 #define MYSQL_SET_OPTION 27
173 #define MYSQL_STMT_FETCH 28
174 #define MYSQL_DAEMON 29
175 #define MYSQL_BINLOG_DUMP_GTID 30 /* replication */
176 #define MYSQL_RESET_CONNECTION 31
177 #define MYSQL_CLONE 32
178 #define MYSQL_SUBSCRIBE_GROUP_REPLICATION_STREAM 33
180 /* MySQL Native Cloning Commands */
181 #define MYSQL_CLONE_COM_INIT 1
182 #define MYSQL_CLONE_COM_ATTACH 2
183 #define MYSQL_CLONE_COM_REINIT 3
184 #define MYSQL_CLONE_COM_EXECUTE 4
185 #define MYSQL_CLONE_COM_ACK 5
186 #define MYSQL_CLONE_COM_EXIT 6
188 /* decoding table: clone command */
189 static const value_string mysql_clone_command_vals
[] = {
190 {MYSQL_CLONE_COM_INIT
, "Init"},
191 {MYSQL_CLONE_COM_ATTACH
, "Attach"},
192 {MYSQL_CLONE_COM_REINIT
, "Re-init"},
193 {MYSQL_CLONE_COM_EXECUTE
, "Execute"},
194 {MYSQL_CLONE_COM_ACK
, "Ack"},
195 {MYSQL_CLONE_COM_EXIT
, "Exit"},
199 /* MySQL Native Cloning Responses */
200 #define MYSQL_CLONE_COM_RES_LOCS 1
201 #define MYSQL_CLONE_COM_RES_DATA_DESC 2
202 #define MYSQL_CLONE_COM_RES_DATA 3
203 #define MYSQL_CLONE_COM_RES_PLUGIN 4
204 #define MYSQL_CLONE_COM_RES_CONFIG 5
205 #define MYSQL_CLONE_COM_RES_COLLATION 6
206 #define MYSQL_CLONE_COM_RES_PLUGIN_V2 7
207 #define MYSQL_CLONE_COM_RES_CONFIG_V3 8
208 #define MYSQL_CLONE_COM_RES_COMPLETE 99
209 #define MYSQL_CLONE_COM_RES_ERROR 100
211 /* decoding table: clone command */
212 static const value_string mysql_clone_response_vals
[] = {
213 {MYSQL_CLONE_COM_RES_LOCS
, "Remote Resource Locator"},
214 {MYSQL_CLONE_COM_RES_DATA_DESC
, "Remote Data Descriptor"},
215 {MYSQL_CLONE_COM_RES_DATA
, "Remote Data"},
216 {MYSQL_CLONE_COM_RES_PLUGIN
, "Plugin V1"},
217 {MYSQL_CLONE_COM_RES_CONFIG
, "Config"},
218 {MYSQL_CLONE_COM_RES_COLLATION
, "Collation"},
219 {MYSQL_CLONE_COM_RES_PLUGIN_V2
, "Plugin V2"},
220 {MYSQL_CLONE_COM_RES_CONFIG_V3
, "Plugin V3"},
221 {MYSQL_CLONE_COM_RES_COMPLETE
, "Complete"},
222 {MYSQL_CLONE_COM_RES_ERROR
, "Error"},
226 /* MariaDB specific commands */
227 #define MARIADB_STMT_BULK_EXECUTE 250
229 /* MariaDB bulk execute flags */
230 #define MARIADB_BULK_AUTOID 64
231 #define MARIADB_BULK_SEND_TYPES 128
233 /* MariaDB extended capabilities */
234 #define MARIADB_CAPS_PR 0x00000001 /* MARIADB_CLIENT_PROGRESS */
235 #define MARIADB_CAPS_CM 0x00000002 /* MARIADB_CLIENT_COM_MULTI */
236 #define MARIADB_CAPS_BO 0x00000004 /* MARIADB_CLIENT_STMT_BULK_OPERATIONS */
237 #define MARIADB_CAPS_EM 0x00000008 /* MARIADB_CLIENT_EXTENDED_METADATA */
238 #define MARIADB_CAPS_ME 0x00000010 /* MARIADB_CLIENT_CACHE_METADATA */
240 /* MariaDB bulk indicators */
241 #define MARIADB_INDICATOR_NONE 0
242 #define MARIADB_INDICATOR_NULL 1
243 #define MARIADB_INDICATOR_DEFAULT 2
244 #define MARIADB_INDICATOR_IGNORE 3
245 #define MARIADB_INDICATIR_IGNORE_ROW 4
248 /* MySQL cursor types */
250 #define MYSQL_CURSOR_TYPE_NO_CURSOR 0
251 #define MYSQL_CURSOR_TYPE_READ_ONLY 1
252 #define MYSQL_CURSOR_TYPE_FOR_UPDATE 2
253 #define MYSQL_CURSOR_TYPE_SCROLLABLE 4
254 #define MYSQL_PARAMETER_COUNT_AVAILABLE 8
256 /* MySQL parameter flags -- used internally by the dissector */
258 #define MYSQL_PARAM_FLAG_STREAMED 0x01
260 /* Compression states, internal to the dissector */
261 #define MYSQL_COMPRESS_NONE 0
262 #define MYSQL_COMPRESS_INIT 1
263 #define MYSQL_COMPRESS_ACTIVE 2
265 #define MYSQL_COMPRESS_ALG_ZLIB 0
266 #define MYSQL_COMPRESS_ALG_ZSTD 1
268 /* Generic Response Codes */
269 #define MYSQL_RESPONSE_OK 0x00
270 #define MYSQL_RESPONSE_ERR 0xFF
271 #define MYSQL_RESPONSE_EOF 0xFE
272 #define MYSQL_RESPONSE_INFILE 0xFB
274 /* mariadb extended keys */
275 #define MARIADB_EXT_META_TYPE 0
276 #define MARIADB_EXT_META_FORMAT 1
278 /* decoding table: command */
279 static const value_string mysql_command_vals
[] = {
280 {MYSQL_SLEEP
, "SLEEP"},
281 {MYSQL_QUIT
, "Quit"},
282 {MYSQL_INIT_DB
, "Use Database"},
283 {MYSQL_QUERY
, "Query"},
284 {MYSQL_FIELD_LIST
, "Show Fields"},
285 {MYSQL_CREATE_DB
, "Create Database"},
286 {MYSQL_DROP_DB
, "Drop Database"},
287 {MYSQL_REFRESH
, "Refresh"},
288 {MYSQL_SHUTDOWN
, "Shutdown"},
289 {MYSQL_STATISTICS
, "Statistics"},
290 {MYSQL_PROCESS_INFO
, "Process List"},
291 {MYSQL_CONNECT
, "Connect"},
292 {MYSQL_PROCESS_KILL
, "Kill Server Thread"},
293 {MYSQL_DEBUG
, "Dump Debuginfo"},
294 {MYSQL_PING
, "Ping"},
295 {MYSQL_TIME
, "Time"},
296 {MYSQL_DELAY_INSERT
, "Insert Delayed"},
297 {MYSQL_CHANGE_USER
, "Change User"},
298 {MYSQL_BINLOG_DUMP
, "Send Binlog"},
299 {MYSQL_TABLE_DUMP
, "Send Table"},
300 {MYSQL_CONNECT_OUT
, "Slave Connect"},
301 {MYSQL_REGISTER_SLAVE
, "Register Slave"},
302 {MYSQL_STMT_PREPARE
, "Prepare Statement"},
303 {MYSQL_STMT_EXECUTE
, "Execute Statement"},
304 {MYSQL_STMT_SEND_LONG_DATA
, "Send BLOB"},
305 {MYSQL_STMT_CLOSE
, "Close Statement"},
306 {MYSQL_STMT_RESET
, "Reset Statement"},
307 {MYSQL_SET_OPTION
, "Set Option"},
308 {MYSQL_STMT_FETCH
, "Fetch Data"},
309 {MYSQL_DAEMON
, "Daemon"},
310 {MYSQL_BINLOG_DUMP_GTID
, "Send Binlog GTID"},
311 {MYSQL_RESET_CONNECTION
, "Reset Connection"},
312 {MYSQL_CLONE
, "Native cloning"},
313 {MYSQL_SUBSCRIBE_GROUP_REPLICATION_STREAM
, "Subscribe Group Replication Stream"},
314 {MARIADB_STMT_BULK_EXECUTE
, "Execute Bulk Statement"},
317 static value_string_ext mysql_command_vals_ext
= VALUE_STRING_EXT_INIT(mysql_command_vals
);
319 /* decoding table: exec_flags */
320 static const value_string mysql_exec_flags_vals
[] = {
321 {MYSQL_CURSOR_TYPE_NO_CURSOR
, "Defaults"},
322 {MYSQL_CURSOR_TYPE_READ_ONLY
, "Read-only cursor"},
323 {MYSQL_CURSOR_TYPE_FOR_UPDATE
, "Cursor for update"},
324 {MYSQL_CURSOR_TYPE_SCROLLABLE
, "Scrollable cursor"},
325 {MYSQL_PARAMETER_COUNT_AVAILABLE
, "Parameter Count Available"},
329 /* decoding table: new_parameter_bound_flag */
330 static const value_string mysql_new_parameter_bound_flag_vals
[] = {
331 {0, "Subsequent call"},
332 {1, "First call or rebound"},
336 static const value_string mariadb_bulk_flags_vals[] = {
337 {MARIADB_BULK_AUTOID, "Return auto generated IDs"},
338 {MARIADB_BULK_SEND_TYPES, "Send types to server"},
342 static const value_string mariadb_bulk_indicator_vals
[] = {
343 {MARIADB_INDICATOR_NONE
, "Not set"},
344 {MARIADB_INDICATOR_NULL
, "Null Value"},
345 {MARIADB_INDICATOR_DEFAULT
, "Default Value"},
346 {MARIADB_INDICATOR_IGNORE
, "Don't Update Value"},
347 {MARIADB_INDICATIR_IGNORE_ROW
, "Ignore Row"},
351 /* decoding table: exec_time_sign */
352 static const value_string mysql_exec_time_sign_vals
[] = {
358 /* collation codes may change over time, recreate with the following SQL
360 SELECT CONCAT(' {', ID, ',"', CHARACTER_SET_NAME, ' COLLATE ', COLLATION_NAME, '"},')
361 FROM INFORMATION_SCHEMA.COLLATIONS
363 INTO OUTFILE '/var/lib/mysql-files/mysql-collations';
365 Last Update from MySQL 8.0.36
368 static const value_string mysql_collation_vals
[] = {
369 {1, "big5 COLLATE big5_chinese_ci"},
370 {2, "latin2 COLLATE latin2_czech_cs"},
371 {3, "dec8 COLLATE dec8_swedish_ci"},
372 {4, "cp850 COLLATE cp850_general_ci"},
373 {5, "latin1 COLLATE latin1_german1_ci"},
374 {6, "hp8 COLLATE hp8_english_ci"},
375 {7, "koi8r COLLATE koi8r_general_ci"},
376 {8, "latin1 COLLATE latin1_swedish_ci"},
377 {9, "latin2 COLLATE latin2_general_ci"},
378 {10, "swe7 COLLATE swe7_swedish_ci"},
379 {11, "ascii COLLATE ascii_general_ci"},
380 {12, "ujis COLLATE ujis_japanese_ci"},
381 {13, "sjis COLLATE sjis_japanese_ci"},
382 {14, "cp1251 COLLATE cp1251_bulgarian_ci"},
383 {15, "latin1 COLLATE latin1_danish_ci"},
384 {16, "hebrew COLLATE hebrew_general_ci"},
385 {18, "tis620 COLLATE tis620_thai_ci"},
386 {19, "euckr COLLATE euckr_korean_ci"},
387 {20, "latin7 COLLATE latin7_estonian_cs"},
388 {21, "latin2 COLLATE latin2_hungarian_ci"},
389 {22, "koi8u COLLATE koi8u_general_ci"},
390 {23, "cp1251 COLLATE cp1251_ukrainian_ci"},
391 {24, "gb2312 COLLATE gb2312_chinese_ci"},
392 {25, "greek COLLATE greek_general_ci"},
393 {26, "cp1250 COLLATE cp1250_general_ci"},
394 {27, "latin2 COLLATE latin2_croatian_ci"},
395 {28, "gbk COLLATE gbk_chinese_ci"},
396 {29, "cp1257 COLLATE cp1257_lithuanian_ci"},
397 {30, "latin5 COLLATE latin5_turkish_ci"},
398 {31, "latin1 COLLATE latin1_german2_ci"},
399 {32, "armscii8 COLLATE armscii8_general_ci"},
400 {33, "utf8mb3 COLLATE utf8mb3_general_ci"},
401 {34, "cp1250 COLLATE cp1250_czech_cs"},
402 {35, "ucs2 COLLATE ucs2_general_ci"},
403 {36, "cp866 COLLATE cp866_general_ci"},
404 {37, "keybcs2 COLLATE keybcs2_general_ci"},
405 {38, "macce COLLATE macce_general_ci"},
406 {39, "macroman COLLATE macroman_general_ci"},
407 {40, "cp852 COLLATE cp852_general_ci"},
408 {41, "latin7 COLLATE latin7_general_ci"},
409 {42, "latin7 COLLATE latin7_general_cs"},
410 {43, "macce COLLATE macce_bin"},
411 {44, "cp1250 COLLATE cp1250_croatian_ci"},
412 {45, "utf8mb4 COLLATE utf8mb4_general_ci"},
413 {46, "utf8mb4 COLLATE utf8mb4_bin"},
414 {47, "latin1 COLLATE latin1_bin"},
415 {48, "latin1 COLLATE latin1_general_ci"},
416 {49, "latin1 COLLATE latin1_general_cs"},
417 {50, "cp1251 COLLATE cp1251_bin"},
418 {51, "cp1251 COLLATE cp1251_general_ci"},
419 {52, "cp1251 COLLATE cp1251_general_cs"},
420 {53, "macroman COLLATE macroman_bin"},
421 {54, "utf16 COLLATE utf16_general_ci"},
422 {55, "utf16 COLLATE utf16_bin"},
423 {56, "utf16le COLLATE utf16le_general_ci"},
424 {57, "cp1256 COLLATE cp1256_general_ci"},
425 {58, "cp1257 COLLATE cp1257_bin"},
426 {59, "cp1257 COLLATE cp1257_general_ci"},
427 {60, "utf32 COLLATE utf32_general_ci"},
428 {61, "utf32 COLLATE utf32_bin"},
429 {62, "utf16le COLLATE utf16le_bin"},
430 {63, "binary COLLATE binary"},
431 {64, "armscii8 COLLATE armscii8_bin"},
432 {65, "ascii COLLATE ascii_bin"},
433 {66, "cp1250 COLLATE cp1250_bin"},
434 {67, "cp1256 COLLATE cp1256_bin"},
435 {68, "cp866 COLLATE cp866_bin"},
436 {69, "dec8 COLLATE dec8_bin"},
437 {70, "greek COLLATE greek_bin"},
438 {71, "hebrew COLLATE hebrew_bin"},
439 {72, "hp8 COLLATE hp8_bin"},
440 {73, "keybcs2 COLLATE keybcs2_bin"},
441 {74, "koi8r COLLATE koi8r_bin"},
442 {75, "koi8u COLLATE koi8u_bin"},
443 {76, "utf8mb3 COLLATE utf8mb3_tolower_ci"},
444 {77, "latin2 COLLATE latin2_bin"},
445 {78, "latin5 COLLATE latin5_bin"},
446 {79, "latin7 COLLATE latin7_bin"},
447 {80, "cp850 COLLATE cp850_bin"},
448 {81, "cp852 COLLATE cp852_bin"},
449 {82, "swe7 COLLATE swe7_bin"},
450 {83, "utf8mb3 COLLATE utf8mb3_bin"},
451 {84, "big5 COLLATE big5_bin"},
452 {85, "euckr COLLATE euckr_bin"},
453 {86, "gb2312 COLLATE gb2312_bin"},
454 {87, "gbk COLLATE gbk_bin"},
455 {88, "sjis COLLATE sjis_bin"},
456 {89, "tis620 COLLATE tis620_bin"},
457 {90, "ucs2 COLLATE ucs2_bin"},
458 {91, "ujis COLLATE ujis_bin"},
459 {92, "geostd8 COLLATE geostd8_general_ci"},
460 {93, "geostd8 COLLATE geostd8_bin"},
461 {94, "latin1 COLLATE latin1_spanish_ci"},
462 {95, "cp932 COLLATE cp932_japanese_ci"},
463 {96, "cp932 COLLATE cp932_bin"},
464 {97, "eucjpms COLLATE eucjpms_japanese_ci"},
465 {98, "eucjpms COLLATE eucjpms_bin"},
466 {99, "cp1250 COLLATE cp1250_polish_ci"},
467 {101, "utf16 COLLATE utf16_unicode_ci"},
468 {102, "utf16 COLLATE utf16_icelandic_ci"},
469 {103, "utf16 COLLATE utf16_latvian_ci"},
470 {104, "utf16 COLLATE utf16_romanian_ci"},
471 {105, "utf16 COLLATE utf16_slovenian_ci"},
472 {106, "utf16 COLLATE utf16_polish_ci"},
473 {107, "utf16 COLLATE utf16_estonian_ci"},
474 {108, "utf16 COLLATE utf16_spanish_ci"},
475 {109, "utf16 COLLATE utf16_swedish_ci"},
476 {110, "utf16 COLLATE utf16_turkish_ci"},
477 {111, "utf16 COLLATE utf16_czech_ci"},
478 {112, "utf16 COLLATE utf16_danish_ci"},
479 {113, "utf16 COLLATE utf16_lithuanian_ci"},
480 {114, "utf16 COLLATE utf16_slovak_ci"},
481 {115, "utf16 COLLATE utf16_spanish2_ci"},
482 {116, "utf16 COLLATE utf16_roman_ci"},
483 {117, "utf16 COLLATE utf16_persian_ci"},
484 {118, "utf16 COLLATE utf16_esperanto_ci"},
485 {119, "utf16 COLLATE utf16_hungarian_ci"},
486 {120, "utf16 COLLATE utf16_sinhala_ci"},
487 {121, "utf16 COLLATE utf16_german2_ci"},
488 {122, "utf16 COLLATE utf16_croatian_ci"},
489 {123, "utf16 COLLATE utf16_unicode_520_ci"},
490 {124, "utf16 COLLATE utf16_vietnamese_ci"},
491 {128, "ucs2 COLLATE ucs2_unicode_ci"},
492 {129, "ucs2 COLLATE ucs2_icelandic_ci"},
493 {130, "ucs2 COLLATE ucs2_latvian_ci"},
494 {131, "ucs2 COLLATE ucs2_romanian_ci"},
495 {132, "ucs2 COLLATE ucs2_slovenian_ci"},
496 {133, "ucs2 COLLATE ucs2_polish_ci"},
497 {134, "ucs2 COLLATE ucs2_estonian_ci"},
498 {135, "ucs2 COLLATE ucs2_spanish_ci"},
499 {136, "ucs2 COLLATE ucs2_swedish_ci"},
500 {137, "ucs2 COLLATE ucs2_turkish_ci"},
501 {138, "ucs2 COLLATE ucs2_czech_ci"},
502 {139, "ucs2 COLLATE ucs2_danish_ci"},
503 {140, "ucs2 COLLATE ucs2_lithuanian_ci"},
504 {141, "ucs2 COLLATE ucs2_slovak_ci"},
505 {142, "ucs2 COLLATE ucs2_spanish2_ci"},
506 {143, "ucs2 COLLATE ucs2_roman_ci"},
507 {144, "ucs2 COLLATE ucs2_persian_ci"},
508 {145, "ucs2 COLLATE ucs2_esperanto_ci"},
509 {146, "ucs2 COLLATE ucs2_hungarian_ci"},
510 {147, "ucs2 COLLATE ucs2_sinhala_ci"},
511 {148, "ucs2 COLLATE ucs2_german2_ci"},
512 {149, "ucs2 COLLATE ucs2_croatian_ci"},
513 {150, "ucs2 COLLATE ucs2_unicode_520_ci"},
514 {151, "ucs2 COLLATE ucs2_vietnamese_ci"},
515 {159, "ucs2 COLLATE ucs2_general_mysql500_ci"},
516 {160, "utf32 COLLATE utf32_unicode_ci"},
517 {161, "utf32 COLLATE utf32_icelandic_ci"},
518 {162, "utf32 COLLATE utf32_latvian_ci"},
519 {163, "utf32 COLLATE utf32_romanian_ci"},
520 {164, "utf32 COLLATE utf32_slovenian_ci"},
521 {165, "utf32 COLLATE utf32_polish_ci"},
522 {166, "utf32 COLLATE utf32_estonian_ci"},
523 {167, "utf32 COLLATE utf32_spanish_ci"},
524 {168, "utf32 COLLATE utf32_swedish_ci"},
525 {169, "utf32 COLLATE utf32_turkish_ci"},
526 {170, "utf32 COLLATE utf32_czech_ci"},
527 {171, "utf32 COLLATE utf32_danish_ci"},
528 {172, "utf32 COLLATE utf32_lithuanian_ci"},
529 {173, "utf32 COLLATE utf32_slovak_ci"},
530 {174, "utf32 COLLATE utf32_spanish2_ci"},
531 {175, "utf32 COLLATE utf32_roman_ci"},
532 {176, "utf32 COLLATE utf32_persian_ci"},
533 {177, "utf32 COLLATE utf32_esperanto_ci"},
534 {178, "utf32 COLLATE utf32_hungarian_ci"},
535 {179, "utf32 COLLATE utf32_sinhala_ci"},
536 {180, "utf32 COLLATE utf32_german2_ci"},
537 {181, "utf32 COLLATE utf32_croatian_ci"},
538 {182, "utf32 COLLATE utf32_unicode_520_ci"},
539 {183, "utf32 COLLATE utf32_vietnamese_ci"},
540 {192, "utf8mb3 COLLATE utf8mb3_unicode_ci"},
541 {193, "utf8mb3 COLLATE utf8mb3_icelandic_ci"},
542 {194, "utf8mb3 COLLATE utf8mb3_latvian_ci"},
543 {195, "utf8mb3 COLLATE utf8mb3_romanian_ci"},
544 {196, "utf8mb3 COLLATE utf8mb3_slovenian_ci"},
545 {197, "utf8mb3 COLLATE utf8mb3_polish_ci"},
546 {198, "utf8mb3 COLLATE utf8mb3_estonian_ci"},
547 {199, "utf8mb3 COLLATE utf8mb3_spanish_ci"},
548 {200, "utf8mb3 COLLATE utf8mb3_swedish_ci"},
549 {201, "utf8mb3 COLLATE utf8mb3_turkish_ci"},
550 {202, "utf8mb3 COLLATE utf8mb3_czech_ci"},
551 {203, "utf8mb3 COLLATE utf8mb3_danish_ci"},
552 {204, "utf8mb3 COLLATE utf8mb3_lithuanian_ci"},
553 {205, "utf8mb3 COLLATE utf8mb3_slovak_ci"},
554 {206, "utf8mb3 COLLATE utf8mb3_spanish2_ci"},
555 {207, "utf8mb3 COLLATE utf8mb3_roman_ci"},
556 {208, "utf8mb3 COLLATE utf8mb3_persian_ci"},
557 {209, "utf8mb3 COLLATE utf8mb3_esperanto_ci"},
558 {210, "utf8mb3 COLLATE utf8mb3_hungarian_ci"},
559 {211, "utf8mb3 COLLATE utf8mb3_sinhala_ci"},
560 {212, "utf8mb3 COLLATE utf8mb3_german2_ci"},
561 {213, "utf8mb3 COLLATE utf8mb3_croatian_ci"},
562 {214, "utf8mb3 COLLATE utf8mb3_unicode_520_ci"},
563 {215, "utf8mb3 COLLATE utf8mb3_vietnamese_ci"},
564 {223, "utf8mb3 COLLATE utf8mb3_general_mysql500_ci"},
565 {224, "utf8mb4 COLLATE utf8mb4_unicode_ci"},
566 {225, "utf8mb4 COLLATE utf8mb4_icelandic_ci"},
567 {226, "utf8mb4 COLLATE utf8mb4_latvian_ci"},
568 {227, "utf8mb4 COLLATE utf8mb4_romanian_ci"},
569 {228, "utf8mb4 COLLATE utf8mb4_slovenian_ci"},
570 {229, "utf8mb4 COLLATE utf8mb4_polish_ci"},
571 {230, "utf8mb4 COLLATE utf8mb4_estonian_ci"},
572 {231, "utf8mb4 COLLATE utf8mb4_spanish_ci"},
573 {232, "utf8mb4 COLLATE utf8mb4_swedish_ci"},
574 {233, "utf8mb4 COLLATE utf8mb4_turkish_ci"},
575 {234, "utf8mb4 COLLATE utf8mb4_czech_ci"},
576 {235, "utf8mb4 COLLATE utf8mb4_danish_ci"},
577 {236, "utf8mb4 COLLATE utf8mb4_lithuanian_ci"},
578 {237, "utf8mb4 COLLATE utf8mb4_slovak_ci"},
579 {238, "utf8mb4 COLLATE utf8mb4_spanish2_ci"},
580 {239, "utf8mb4 COLLATE utf8mb4_roman_ci"},
581 {240, "utf8mb4 COLLATE utf8mb4_persian_ci"},
582 {241, "utf8mb4 COLLATE utf8mb4_esperanto_ci"},
583 {242, "utf8mb4 COLLATE utf8mb4_hungarian_ci"},
584 {243, "utf8mb4 COLLATE utf8mb4_sinhala_ci"},
585 {244, "utf8mb4 COLLATE utf8mb4_german2_ci"},
586 {245, "utf8mb4 COLLATE utf8mb4_croatian_ci"},
587 {246, "utf8mb4 COLLATE utf8mb4_unicode_520_ci"},
588 {247, "utf8mb4 COLLATE utf8mb4_vietnamese_ci"},
589 {248,"gb18030 COLLATE gb18030_chinese_ci"},
590 {249,"gb18030 COLLATE gb18030_bin"},
591 {250,"gb18030 COLLATE gb18030_unicode_520_ci"},
592 {255,"utf8mb4 COLLATE utf8mb4_0900_ai_ci"},
593 {256,"utf8mb4 COLLATE utf8mb4_de_pb_0900_ai_ci"},
594 {257,"utf8mb4 COLLATE utf8mb4_is_0900_ai_ci"},
595 {258,"utf8mb4 COLLATE utf8mb4_lv_0900_ai_ci"},
596 {259,"utf8mb4 COLLATE utf8mb4_ro_0900_ai_ci"},
597 {260,"utf8mb4 COLLATE utf8mb4_sl_0900_ai_ci"},
598 {261,"utf8mb4 COLLATE utf8mb4_pl_0900_ai_ci"},
599 {262,"utf8mb4 COLLATE utf8mb4_et_0900_ai_ci"},
600 {263,"utf8mb4 COLLATE utf8mb4_es_0900_ai_ci"},
601 {264,"utf8mb4 COLLATE utf8mb4_sv_0900_ai_ci"},
602 {265,"utf8mb4 COLLATE utf8mb4_tr_0900_ai_ci"},
603 {266,"utf8mb4 COLLATE utf8mb4_cs_0900_ai_ci"},
604 {267,"utf8mb4 COLLATE utf8mb4_da_0900_ai_ci"},
605 {268,"utf8mb4 COLLATE utf8mb4_lt_0900_ai_ci"},
606 {269,"utf8mb4 COLLATE utf8mb4_sk_0900_ai_ci"},
607 {270,"utf8mb4 COLLATE utf8mb4_es_trad_0900_ai_ci"},
608 {271,"utf8mb4 COLLATE utf8mb4_la_0900_ai_ci"},
609 {273,"utf8mb4 COLLATE utf8mb4_eo_0900_ai_ci"},
610 {274,"utf8mb4 COLLATE utf8mb4_hu_0900_ai_ci"},
611 {275,"utf8mb4 COLLATE utf8mb4_hr_0900_ai_ci"},
612 {277,"utf8mb4 COLLATE utf8mb4_vi_0900_ai_ci"},
613 {278,"utf8mb4 COLLATE utf8mb4_0900_as_cs"},
614 {279,"utf8mb4 COLLATE utf8mb4_de_pb_0900_as_cs"},
615 {280,"utf8mb4 COLLATE utf8mb4_is_0900_as_cs"},
616 {281,"utf8mb4 COLLATE utf8mb4_lv_0900_as_cs"},
617 {282,"utf8mb4 COLLATE utf8mb4_ro_0900_as_cs"},
618 {283,"utf8mb4 COLLATE utf8mb4_sl_0900_as_cs"},
619 {284,"utf8mb4 COLLATE utf8mb4_pl_0900_as_cs"},
620 {285,"utf8mb4 COLLATE utf8mb4_et_0900_as_cs"},
621 {286,"utf8mb4 COLLATE utf8mb4_es_0900_as_cs"},
622 {287,"utf8mb4 COLLATE utf8mb4_sv_0900_as_cs"},
623 {288,"utf8mb4 COLLATE utf8mb4_tr_0900_as_cs"},
624 {289,"utf8mb4 COLLATE utf8mb4_cs_0900_as_cs"},
625 {290,"utf8mb4 COLLATE utf8mb4_da_0900_as_cs"},
626 {291,"utf8mb4 COLLATE utf8mb4_lt_0900_as_cs"},
627 {292,"utf8mb4 COLLATE utf8mb4_sk_0900_as_cs"},
628 {293,"utf8mb4 COLLATE utf8mb4_es_trad_0900_as_cs"},
629 {294,"utf8mb4 COLLATE utf8mb4_la_0900_as_cs"},
630 {296,"utf8mb4 COLLATE utf8mb4_eo_0900_as_cs"},
631 {297,"utf8mb4 COLLATE utf8mb4_hu_0900_as_cs"},
632 {298,"utf8mb4 COLLATE utf8mb4_hr_0900_as_cs"},
633 {300,"utf8mb4 COLLATE utf8mb4_vi_0900_as_cs"},
634 {303,"utf8mb4 COLLATE utf8mb4_ja_0900_as_cs"},
635 {304,"utf8mb4 COLLATE utf8mb4_ja_0900_as_cs_ks"},
636 {305,"utf8mb4 COLLATE utf8mb4_0900_as_ci"},
637 {306,"utf8mb4 COLLATE utf8mb4_ru_0900_ai_ci"},
638 {307,"utf8mb4 COLLATE utf8mb4_ru_0900_as_cs"},
639 {308,"utf8mb4 COLLATE utf8mb4_zh_0900_as_cs"},
640 {309,"utf8mb4 COLLATE utf8mb4_0900_bin"},
641 {310,"utf8mb4 COLLATE utf8mb4_nb_0900_ai_ci"},
642 {311,"utf8mb4 COLLATE utf8mb4_nb_0900_as_cs"},
643 {312,"utf8mb4 COLLATE utf8mb4_nn_0900_ai_ci"},
644 {313,"utf8mb4 COLLATE utf8mb4_nn_0900_as_cs"},
645 {314,"utf8mb4 COLLATE utf8mb4_sr_latn_0900_ai_ci"},
646 {315,"utf8mb4 COLLATE utf8mb4_sr_latn_0900_as_cs"},
647 {316,"utf8mb4 COLLATE utf8mb4_bs_0900_ai_ci"},
648 {317,"utf8mb4 COLLATE utf8mb4_bs_0900_as_cs"},
649 {318,"utf8mb4 COLLATE utf8mb4_bg_0900_ai_ci"},
650 {319,"utf8mb4 COLLATE utf8mb4_bg_0900_as_cs"},
651 {320,"utf8mb4 COLLATE utf8mb4_gl_0900_ai_ci"},
652 {321,"utf8mb4 COLLATE utf8mb4_gl_0900_as_cs"},
653 {322,"utf8mb4 COLLATE utf8mb4_mn_cyrl_0900_ai_ci"},
654 {323,"utf8mb4 COLLATE utf8mb4_mn_cyrl_0900_as_cs"},
659 static value_string_ext mysql_collation_vals_ext
= VALUE_STRING_EXT_INIT(mysql_collation_vals
);
661 /* MariaDB specific character sets and collations
663 Last Update: MariaDB 10.5.4 */
665 static const value_string mariadb_collation_vals
[] = {
666 {1,"big5 COLLATE big5_chinese_ci"},
667 {2,"latin2 COLLATE latin2_czech_cs"},
668 {3,"dec8 COLLATE dec8_swedish_ci"},
669 {4,"cp850 COLLATE cp850_general_ci"},
670 {5,"latin1 COLLATE latin1_german1_ci"},
671 {6,"hp8 COLLATE hp8_english_ci"},
672 {7,"koi8r COLLATE koi8r_general_ci"},
673 {8,"latin1 COLLATE latin1_swedish_ci"},
674 {9,"latin2 COLLATE latin2_general_ci"},
675 {10,"swe7 COLLATE swe7_swedish_ci"},
676 {11,"ascii COLLATE ascii_general_ci"},
677 {12,"ujis COLLATE ujis_japanese_ci"},
678 {13,"sjis COLLATE sjis_japanese_ci"},
679 {14,"cp1251 COLLATE cp1251_bulgarian_ci"},
680 {15,"latin1 COLLATE latin1_danish_ci"},
681 {16,"hebrew COLLATE hebrew_general_ci"},
682 {18,"tis620 COLLATE tis620_thai_ci"},
683 {19,"euckr COLLATE euckr_korean_ci"},
684 {20,"latin7 COLLATE latin7_estonian_cs"},
685 {21,"latin2 COLLATE latin2_hungarian_ci"},
686 {22,"koi8u COLLATE koi8u_general_ci"},
687 {23,"cp1251 COLLATE cp1251_ukrainian_ci"},
688 {24,"gb2312 COLLATE gb2312_chinese_ci"},
689 {25,"greek COLLATE greek_general_ci"},
690 {26,"cp1250 COLLATE cp1250_general_ci"},
691 {27,"latin2 COLLATE latin2_croatian_ci"},
692 {28,"gbk COLLATE gbk_chinese_ci"},
693 {29,"cp1257 COLLATE cp1257_lithuanian_ci"},
694 {30,"latin5 COLLATE latin5_turkish_ci"},
695 {31,"latin1 COLLATE latin1_german2_ci"},
696 {32,"armscii8 COLLATE armscii8_general_ci"},
697 {33,"utf8 COLLATE utf8_general_ci"},
698 {34,"cp1250 COLLATE cp1250_czech_cs"},
699 {35,"ucs2 COLLATE ucs2_general_ci"},
700 {36,"cp866 COLLATE cp866_general_ci"},
701 {37,"keybcs2 COLLATE keybcs2_general_ci"},
702 {38,"macce COLLATE macce_general_ci"},
703 {39,"macroman COLLATE macroman_general_ci"},
704 {40,"cp852 COLLATE cp852_general_ci"},
705 {41,"latin7 COLLATE latin7_general_ci"},
706 {42,"latin7 COLLATE latin7_general_cs"},
707 {43,"macce COLLATE macce_bin"},
708 {44,"cp1250 COLLATE cp1250_croatian_ci"},
709 {45,"utf8mb4 COLLATE utf8mb4_general_ci"},
710 {46,"utf8mb4 COLLATE utf8mb4_bin"},
711 {47,"latin1 COLLATE latin1_bin"},
712 {48,"latin1 COLLATE latin1_general_ci"},
713 {49,"latin1 COLLATE latin1_general_cs"},
714 {50,"cp1251 COLLATE cp1251_bin"},
715 {51,"cp1251 COLLATE cp1251_general_ci"},
716 {52,"cp1251 COLLATE cp1251_general_cs"},
717 {53,"macroman COLLATE macroman_bin"},
718 {54,"utf16 COLLATE utf16_general_ci"},
719 {55,"utf16 COLLATE utf16_bin"},
720 {56,"utf16le COLLATE utf16le_general_ci"},
721 {57,"cp1256 COLLATE cp1256_general_ci"},
722 {58,"cp1257 COLLATE cp1257_bin"},
723 {59,"cp1257 COLLATE cp1257_general_ci"},
724 {60,"utf32 COLLATE utf32_general_ci"},
725 {61,"utf32 COLLATE utf32_bin"},
726 {62,"utf16le COLLATE utf16le_bin"},
727 {63,"binary COLLATE binary"},
728 {64,"armscii8 COLLATE armscii8_bin"},
729 {65,"ascii COLLATE ascii_bin"},
730 {66,"cp1250 COLLATE cp1250_bin"},
731 {67,"cp1256 COLLATE cp1256_bin"},
732 {68,"cp866 COLLATE cp866_bin"},
733 {69,"dec8 COLLATE dec8_bin"},
734 {70,"greek COLLATE greek_bin"},
735 {71,"hebrew COLLATE hebrew_bin"},
736 {72,"hp8 COLLATE hp8_bin"},
737 {73,"keybcs2 COLLATE keybcs2_bin"},
738 {74,"koi8r COLLATE koi8r_bin"},
739 {75,"koi8u COLLATE koi8u_bin"},
740 {77,"latin2 COLLATE latin2_bin"},
741 {78,"latin5 COLLATE latin5_bin"},
742 {79,"latin7 COLLATE latin7_bin"},
743 {80,"cp850 COLLATE cp850_bin"},
744 {81,"cp852 COLLATE cp852_bin"},
745 {82,"swe7 COLLATE swe7_bin"},
746 {83,"utf8 COLLATE utf8_bin"},
747 {84,"big5 COLLATE big5_bin"},
748 {85,"euckr COLLATE euckr_bin"},
749 {86,"gb2312 COLLATE gb2312_bin"},
750 {87,"gbk COLLATE gbk_bin"},
751 {88,"sjis COLLATE sjis_bin"},
752 {89,"tis620 COLLATE tis620_bin"},
753 {90,"ucs2 COLLATE ucs2_bin"},
754 {91,"ujis COLLATE ujis_bin"},
755 {92,"geostd8 COLLATE geostd8_general_ci"},
756 {93,"geostd8 COLLATE geostd8_bin"},
757 {94,"latin1 COLLATE latin1_spanish_ci"},
758 {95,"cp932 COLLATE cp932_japanese_ci"},
759 {96,"cp932 COLLATE cp932_bin"},
760 {97,"eucjpms COLLATE eucjpms_japanese_ci"},
761 {98,"eucjpms COLLATE eucjpms_bin"},
762 {99,"cp1250 COLLATE cp1250_polish_ci"},
763 {101,"utf16 COLLATE utf16_unicode_ci"},
764 {102,"utf16 COLLATE utf16_icelandic_ci"},
765 {103,"utf16 COLLATE utf16_latvian_ci"},
766 {104,"utf16 COLLATE utf16_romanian_ci"},
767 {105,"utf16 COLLATE utf16_slovenian_ci"},
768 {106,"utf16 COLLATE utf16_polish_ci"},
769 {107,"utf16 COLLATE utf16_estonian_ci"},
770 {108,"utf16 COLLATE utf16_spanish_ci"},
771 {109,"utf16 COLLATE utf16_swedish_ci"},
772 {110,"utf16 COLLATE utf16_turkish_ci"},
773 {111,"utf16 COLLATE utf16_czech_ci"},
774 {112,"utf16 COLLATE utf16_danish_ci"},
775 {113,"utf16 COLLATE utf16_lithuanian_ci"},
776 {114,"utf16 COLLATE utf16_slovak_ci"},
777 {115,"utf16 COLLATE utf16_spanish2_ci"},
778 {116,"utf16 COLLATE utf16_roman_ci"},
779 {117,"utf16 COLLATE utf16_persian_ci"},
780 {118,"utf16 COLLATE utf16_esperanto_ci"},
781 {119,"utf16 COLLATE utf16_hungarian_ci"},
782 {120,"utf16 COLLATE utf16_sinhala_ci"},
783 {121,"utf16 COLLATE utf16_german2_ci"},
784 {122,"utf16 COLLATE utf16_croatian_mysql561_ci"},
785 {123,"utf16 COLLATE utf16_unicode_520_ci"},
786 {124,"utf16 COLLATE utf16_vietnamese_ci"},
787 {128,"ucs2 COLLATE ucs2_unicode_ci"},
788 {129,"ucs2 COLLATE ucs2_icelandic_ci"},
789 {130,"ucs2 COLLATE ucs2_latvian_ci"},
790 {131,"ucs2 COLLATE ucs2_romanian_ci"},
791 {132,"ucs2 COLLATE ucs2_slovenian_ci"},
792 {133,"ucs2 COLLATE ucs2_polish_ci"},
793 {134,"ucs2 COLLATE ucs2_estonian_ci"},
794 {135,"ucs2 COLLATE ucs2_spanish_ci"},
795 {136,"ucs2 COLLATE ucs2_swedish_ci"},
796 {137,"ucs2 COLLATE ucs2_turkish_ci"},
797 {138,"ucs2 COLLATE ucs2_czech_ci"},
798 {139,"ucs2 COLLATE ucs2_danish_ci"},
799 {140,"ucs2 COLLATE ucs2_lithuanian_ci"},
800 {141,"ucs2 COLLATE ucs2_slovak_ci"},
801 {142,"ucs2 COLLATE ucs2_spanish2_ci"},
802 {143,"ucs2 COLLATE ucs2_roman_ci"},
803 {144,"ucs2 COLLATE ucs2_persian_ci"},
804 {145,"ucs2 COLLATE ucs2_esperanto_ci"},
805 {146,"ucs2 COLLATE ucs2_hungarian_ci"},
806 {147,"ucs2 COLLATE ucs2_sinhala_ci"},
807 {148,"ucs2 COLLATE ucs2_german2_ci"},
808 {149,"ucs2 COLLATE ucs2_croatian_mysql561_ci"},
809 {150,"ucs2 COLLATE ucs2_unicode_520_ci"},
810 {151,"ucs2 COLLATE ucs2_vietnamese_ci"},
811 {159,"ucs2 COLLATE ucs2_general_mysql500_ci"},
812 {160,"utf32 COLLATE utf32_unicode_ci"},
813 {161,"utf32 COLLATE utf32_icelandic_ci"},
814 {162,"utf32 COLLATE utf32_latvian_ci"},
815 {163,"utf32 COLLATE utf32_romanian_ci"},
816 {164,"utf32 COLLATE utf32_slovenian_ci"},
817 {165,"utf32 COLLATE utf32_polish_ci"},
818 {166,"utf32 COLLATE utf32_estonian_ci"},
819 {167,"utf32 COLLATE utf32_spanish_ci"},
820 {168,"utf32 COLLATE utf32_swedish_ci"},
821 {169,"utf32 COLLATE utf32_turkish_ci"},
822 {170,"utf32 COLLATE utf32_czech_ci"},
823 {171,"utf32 COLLATE utf32_danish_ci"},
824 {172,"utf32 COLLATE utf32_lithuanian_ci"},
825 {173,"utf32 COLLATE utf32_slovak_ci"},
826 {174,"utf32 COLLATE utf32_spanish2_ci"},
827 {175,"utf32 COLLATE utf32_roman_ci"},
828 {176,"utf32 COLLATE utf32_persian_ci"},
829 {177,"utf32 COLLATE utf32_esperanto_ci"},
830 {178,"utf32 COLLATE utf32_hungarian_ci"},
831 {179,"utf32 COLLATE utf32_sinhala_ci"},
832 {180,"utf32 COLLATE utf32_german2_ci"},
833 {181,"utf32 COLLATE utf32_croatian_mysql561_ci"},
834 {182,"utf32 COLLATE utf32_unicode_520_ci"},
835 {183,"utf32 COLLATE utf32_vietnamese_ci"},
836 {192,"utf8 COLLATE utf8_unicode_ci"},
837 {193,"utf8 COLLATE utf8_icelandic_ci"},
838 {194,"utf8 COLLATE utf8_latvian_ci"},
839 {195,"utf8 COLLATE utf8_romanian_ci"},
840 {196,"utf8 COLLATE utf8_slovenian_ci"},
841 {197,"utf8 COLLATE utf8_polish_ci"},
842 {198,"utf8 COLLATE utf8_estonian_ci"},
843 {199,"utf8 COLLATE utf8_spanish_ci"},
844 {200,"utf8 COLLATE utf8_swedish_ci"},
845 {201,"utf8 COLLATE utf8_turkish_ci"},
846 {202,"utf8 COLLATE utf8_czech_ci"},
847 {203,"utf8 COLLATE utf8_danish_ci"},
848 {204,"utf8 COLLATE utf8_lithuanian_ci"},
849 {205,"utf8 COLLATE utf8_slovak_ci"},
850 {206,"utf8 COLLATE utf8_spanish2_ci"},
851 {207,"utf8 COLLATE utf8_roman_ci"},
852 {208,"utf8 COLLATE utf8_persian_ci"},
853 {209,"utf8 COLLATE utf8_esperanto_ci"},
854 {210,"utf8 COLLATE utf8_hungarian_ci"},
855 {211,"utf8 COLLATE utf8_sinhala_ci"},
856 {212,"utf8 COLLATE utf8_german2_ci"},
857 {213,"utf8 COLLATE utf8_croatian_mysql561_ci"},
858 {214,"utf8 COLLATE utf8_unicode_520_ci"},
859 {215,"utf8 COLLATE utf8_vietnamese_ci"},
860 {223,"utf8 COLLATE utf8_general_mysql500_ci"},
861 {224,"utf8mb4 COLLATE utf8mb4_unicode_ci"},
862 {225,"utf8mb4 COLLATE utf8mb4_icelandic_ci"},
863 {226,"utf8mb4 COLLATE utf8mb4_latvian_ci"},
864 {227,"utf8mb4 COLLATE utf8mb4_romanian_ci"},
865 {228,"utf8mb4 COLLATE utf8mb4_slovenian_ci"},
866 {229,"utf8mb4 COLLATE utf8mb4_polish_ci"},
867 {230,"utf8mb4 COLLATE utf8mb4_estonian_ci"},
868 {231,"utf8mb4 COLLATE utf8mb4_spanish_ci"},
869 {232,"utf8mb4 COLLATE utf8mb4_swedish_ci"},
870 {233,"utf8mb4 COLLATE utf8mb4_turkish_ci"},
871 {234,"utf8mb4 COLLATE utf8mb4_czech_ci"},
872 {235,"utf8mb4 COLLATE utf8mb4_danish_ci"},
873 {236,"utf8mb4 COLLATE utf8mb4_lithuanian_ci"},
874 {237,"utf8mb4 COLLATE utf8mb4_slovak_ci"},
875 {238,"utf8mb4 COLLATE utf8mb4_spanish2_ci"},
876 {239,"utf8mb4 COLLATE utf8mb4_roman_ci"},
877 {240,"utf8mb4 COLLATE utf8mb4_persian_ci"},
878 {241,"utf8mb4 COLLATE utf8mb4_esperanto_ci"},
879 {242,"utf8mb4 COLLATE utf8mb4_hungarian_ci"},
880 {243,"utf8mb4 COLLATE utf8mb4_sinhala_ci"},
881 {244,"utf8mb4 COLLATE utf8mb4_german2_ci"},
882 {245,"utf8mb4 COLLATE utf8mb4_croatian_mysql561_ci"},
883 {246,"utf8mb4 COLLATE utf8mb4_unicode_520_ci"},
884 {247,"utf8mb4 COLLATE utf8mb4_vietnamese_ci"},
885 {576,"utf8 COLLATE utf8_croatian_ci"},
886 {577,"utf8 COLLATE utf8_myanmar_ci"},
887 {578,"utf8 COLLATE utf8_thai_520_w2"},
888 {608,"utf8mb4 COLLATE utf8mb4_croatian_ci"},
889 {609,"utf8mb4 COLLATE utf8mb4_myanmar_ci"},
890 {610,"utf8mb4 COLLATE utf8mb4_thai_520_w2"},
891 {640,"ucs2 COLLATE ucs2_croatian_ci"},
892 {641,"ucs2 COLLATE ucs2_myanmar_ci"},
893 {642,"ucs2 COLLATE ucs2_thai_520_w2"},
894 {672,"utf16 COLLATE utf16_croatian_ci"},
895 {673,"utf16 COLLATE utf16_myanmar_ci"},
896 {674,"utf16 COLLATE utf16_thai_520_w2"},
897 {736,"utf32 COLLATE utf32_croatian_ci"},
898 {737,"utf32 COLLATE utf32_myanmar_ci"},
899 {738,"utf32 COLLATE utf32_thai_520_w2"},
900 {1025,"big5 COLLATE big5_chinese_nopad_ci"},
901 {1027,"dec8 COLLATE dec8_swedish_nopad_ci"},
902 {1028,"cp850 COLLATE cp850_general_nopad_ci"},
903 {1030,"hp8 COLLATE hp8_english_nopad_ci"},
904 {1031,"koi8r COLLATE koi8r_general_nopad_ci"},
905 {1032,"latin1 COLLATE latin1_swedish_nopad_ci"},
906 {1033,"latin2 COLLATE latin2_general_nopad_ci"},
907 {1034,"swe7 COLLATE swe7_swedish_nopad_ci"},
908 {1035,"ascii COLLATE ascii_general_nopad_ci"},
909 {1036,"ujis COLLATE ujis_japanese_nopad_ci"},
910 {1037,"sjis COLLATE sjis_japanese_nopad_ci"},
911 {1040,"hebrew COLLATE hebrew_general_nopad_ci"},
912 {1042,"tis620 COLLATE tis620_thai_nopad_ci"},
913 {1043,"euckr COLLATE euckr_korean_nopad_ci"},
914 {1046,"koi8u COLLATE koi8u_general_nopad_ci"},
915 {1048,"gb2312 COLLATE gb2312_chinese_nopad_ci"},
916 {1049,"greek COLLATE greek_general_nopad_ci"},
917 {1050,"cp1250 COLLATE cp1250_general_nopad_ci"},
918 {1052,"gbk COLLATE gbk_chinese_nopad_ci"},
919 {1054,"latin5 COLLATE latin5_turkish_nopad_ci"},
920 {1056,"armscii8 COLLATE armscii8_general_nopad_ci"},
921 {1057,"utf8 COLLATE utf8_general_nopad_ci"},
922 {1059,"ucs2 COLLATE ucs2_general_nopad_ci"},
923 {1060,"cp866 COLLATE cp866_general_nopad_ci"},
924 {1061,"keybcs2 COLLATE keybcs2_general_nopad_ci"},
925 {1062,"macce COLLATE macce_general_nopad_ci"},
926 {1063,"macroman COLLATE macroman_general_nopad_ci"},
927 {1064,"cp852 COLLATE cp852_general_nopad_ci"},
928 {1065,"latin7 COLLATE latin7_general_nopad_ci"},
929 {1067,"macce COLLATE macce_nopad_bin"},
930 {1069,"utf8mb4 COLLATE utf8mb4_general_nopad_ci"},
931 {1070,"utf8mb4 COLLATE utf8mb4_nopad_bin"},
932 {1071,"latin1 COLLATE latin1_nopad_bin"},
933 {1074,"cp1251 COLLATE cp1251_nopad_bin"},
934 {1075,"cp1251 COLLATE cp1251_general_nopad_ci"},
935 {1077,"macroman COLLATE macroman_nopad_bin"},
936 {1078,"utf16 COLLATE utf16_general_nopad_ci"},
937 {1079,"utf16 COLLATE utf16_nopad_bin"},
938 {1080,"utf16le COLLATE utf16le_general_nopad_ci"},
939 {1081,"cp1256 COLLATE cp1256_general_nopad_ci"},
940 {1082,"cp1257 COLLATE cp1257_nopad_bin"},
941 {1083,"cp1257 COLLATE cp1257_general_nopad_ci"},
942 {1084,"utf32 COLLATE utf32_general_nopad_ci"},
943 {1085,"utf32 COLLATE utf32_nopad_bin"},
944 {1086,"utf16le COLLATE utf16le_nopad_bin"},
945 {1088,"armscii8 COLLATE armscii8_nopad_bin"},
946 {1089,"ascii COLLATE ascii_nopad_bin"},
947 {1090,"cp1250 COLLATE cp1250_nopad_bin"},
948 {1091,"cp1256 COLLATE cp1256_nopad_bin"},
949 {1092,"cp866 COLLATE cp866_nopad_bin"},
950 {1093,"dec8 COLLATE dec8_nopad_bin"},
951 {1094,"greek COLLATE greek_nopad_bin"},
952 {1095,"hebrew COLLATE hebrew_nopad_bin"},
953 {1096,"hp8 COLLATE hp8_nopad_bin"},
954 {1097,"keybcs2 COLLATE keybcs2_nopad_bin"},
955 {1098,"koi8r COLLATE koi8r_nopad_bin"},
956 {1099,"koi8u COLLATE koi8u_nopad_bin"},
957 {1101,"latin2 COLLATE latin2_nopad_bin"},
958 {1102,"latin5 COLLATE latin5_nopad_bin"},
959 {1103,"latin7 COLLATE latin7_nopad_bin"},
960 {1104,"cp850 COLLATE cp850_nopad_bin"},
961 {1105,"cp852 COLLATE cp852_nopad_bin"},
962 {1106,"swe7 COLLATE swe7_nopad_bin"},
963 {1107,"utf8 COLLATE utf8_nopad_bin"},
964 {1108,"big5 COLLATE big5_nopad_bin"},
965 {1109,"euckr COLLATE euckr_nopad_bin"},
966 {1110,"gb2312 COLLATE gb2312_nopad_bin"},
967 {1111,"gbk COLLATE gbk_nopad_bin"},
968 {1112,"sjis COLLATE sjis_nopad_bin"},
969 {1113,"tis620 COLLATE tis620_nopad_bin"},
970 {1114,"ucs2 COLLATE ucs2_nopad_bin"},
971 {1115,"ujis COLLATE ujis_nopad_bin"},
972 {1116,"geostd8 COLLATE geostd8_general_nopad_ci"},
973 {1117,"geostd8 COLLATE geostd8_nopad_bin"},
974 {1119,"cp932 COLLATE cp932_japanese_nopad_ci"},
975 {1120,"cp932 COLLATE cp932_nopad_bin"},
976 {1121,"eucjpms COLLATE eucjpms_japanese_nopad_ci"},
977 {1122,"eucjpms COLLATE eucjpms_nopad_bin"},
978 {1125,"utf16 COLLATE utf16_unicode_nopad_ci"},
979 {1147,"utf16 COLLATE utf16_unicode_520_nopad_ci"},
980 {1152,"ucs2 COLLATE ucs2_unicode_nopad_ci"},
981 {1174,"ucs2 COLLATE ucs2_unicode_520_nopad_ci"},
982 {1184,"utf32 COLLATE utf32_unicode_nopad_ci"},
983 {1206,"utf32 COLLATE utf32_unicode_520_nopad_ci"},
984 {1216,"utf8 COLLATE utf8_unicode_nopad_ci"},
985 {1238,"utf8 COLLATE utf8_unicode_520_nopad_ci"},
986 {1248,"utf8mb4 COLLATE utf8mb4_unicode_nopad_ci"},
987 {1270,"utf8mb4 COLLATE utf8mb4_unicode_520_nopad_ci"},
992 static value_string_ext mariadb_collation_vals_ext
= VALUE_STRING_EXT_INIT(mariadb_collation_vals
);
997 } charset_encoding_t
;
999 static charset_encoding_t charset_encoding_array
[] =
1001 /* When character_set_results is set to NULL or "binary", that
1002 * tells the server to perform no conversion. The field charset
1003 * should still be indicated in the column description. Error
1004 * messages use presumably the server default.
1006 { "utf8mb4", ENC_UTF_8
},
1007 { "utf8", ENC_UTF_8
}, // We don't care about the distinction
1008 { "utf8mb3", ENC_UTF_8
},
1009 { "latin1", ENC_WINDOWS_1252
}, // Not ENC_ISO_8859_1
1010 { "ascii", ENC_ASCII
},
1013 { "binary", ENC_NA
},
1014 { "cp1250", ENC_WINDOWS_1250
},
1015 { "cp1251", ENC_WINDOWS_1251
},
1020 { "cp866", ENC_CP866
},
1021 // cp932 - https://dev.mysql.com/doc/refman/8.0/en/charset-cp932.html
1024 { "euckr", ENC_EUC_KR
},
1025 { "gb18030", ENC_GB18030
},
1026 { "gb2312", ENC_GB18030
}, // Backwards compatible
1027 { "gbk", ENC_GB18030
}, // Backwards compatible
1028 // geostd8 - https://datatracker.ietf.org/doc/html/draft-giasher-geostd8-00
1029 { "greek", ENC_ISO_8859_7
},
1030 { "hebrew", ENC_ISO_8859_8
},
1035 { "latin2", ENC_ISO_8859_2
},
1036 { "latin5", ENC_ISO_8859_9
},
1037 { "latin7", ENC_ISO_8859_13
},
1039 { "macroman", ENC_MAC_ROMAN
},
1043 { "ucs2", ENC_UCS_2
},
1045 { "utf16", ENC_UTF_16
| ENC_BIG_ENDIAN
},
1046 { "utf16le", ENC_UTF_16
| ENC_LITTLE_ENDIAN
},
1047 { "utf32", ENC_UCS_4
}
1050 static unsigned charset_to_encoding(const char *charset
)
1052 if (charset
== NULL
) {
1055 // Allows passing in a collation string
1056 size_t token_len
= strcspn(charset
, " ");
1057 for (size_t i
= 0; i
< array_length(charset_encoding_array
); i
++) {
1058 if (strncmp(charset
, charset_encoding_array
[i
].charset
, token_len
) == 0) {
1059 return charset_encoding_array
[i
].encoding
;
1065 static unsigned collation_to_encoding(const unsigned collation
, bool is_mariadb
)
1067 // We are concerned with the character_set_client and character_set_results
1068 // system variables.
1069 // latin1 means ENC_WINDOWS_1252, not ISO-8859-1
1070 // MariaDB defaulted to latin1 before 10.6.15-10:
1071 // https://mariadb.com/docs/server/ref/mdb/system-variables/character_set_client/
1072 // https://mariadb.com/docs/server/ref/mdb/system-variables/character_set_results/
1073 // MySQL uses utf8m4 in 8.0 and utf8 (meaning utf8m3) in 5.7
1074 // https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_character_set_client
1075 // https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_character_set_client
1076 const char* collation_str
;
1077 collation_str
= try_val_to_str_ext(collation
, is_mariadb
? &mariadb_collation_vals_ext
: &mysql_collation_vals_ext
);
1078 return charset_to_encoding(collation_str
);
1081 /* allowed MYSQL_SHUTDOWN levels */
1082 static const value_string mysql_shutdown_vals
[] = {
1084 {1, "wait for connections to finish"},
1085 {2, "wait for transactions to finish"},
1086 {8, "wait for updates to finish"},
1087 {16, "wait flush all buffers"},
1088 {17, "wait flush critical buffers"},
1089 {254, "kill running queries"},
1090 {255, "kill connections"},
1095 /* allowed MYSQL_SET_OPTION values */
1096 static const value_string mysql_option_vals
[] = {
1097 {0, "multi statements on"},
1098 {1, "multi statements off"},
1102 static const value_string mysql_session_track_type_vals
[] = {
1103 {0, "SESSION_SYSVARS_TRACKER"},
1104 {1, "CURRENT_SCHEMA_TRACKER"},
1105 {2, "SESSION_STATE_CHANGE_TRACKER"},
1106 {3, "SESSION_TRACK_GTIDS"},
1107 {4, "SESSION_TRACK_TRANSACTION_CHARACTERISTICS"},
1108 {5, "SESSION_TRACK_TRANSACTION_STATE"},
1112 static const value_string mysql_response_code_vals
[] = {
1113 { MYSQL_RESPONSE_OK
, "OK Packet" },
1114 { MYSQL_RESPONSE_ERR
, "ERR Packet" },
1115 { MYSQL_RESPONSE_EOF
, "EOF Packet" },
1116 { MYSQL_RESPONSE_INFILE
, "LOCAL INFILE Packet" },
1121 static int proto_mysql
;
1123 /* dissector configuration */
1124 static bool mysql_desegment
= true;
1125 static bool mysql_showquery
;
1127 /* expand-the-tree flags */
1128 static int ett_mysql
;
1129 static int ett_server_greeting
;
1130 static int ett_login_request
;
1131 static int ett_caps
;
1132 static int ett_extcaps
;
1133 static int ett_stat
;
1134 static int ett_row_value
;
1135 static int ett_request
;
1136 static int ett_query_attributes
;
1137 static int ett_refresh
;
1138 static int ett_field_flags
;
1139 static int ett_exec_param
;
1140 static int ett_bulk_param
;
1141 static int ett_session_track
;
1142 static int ett_session_track_data
;
1143 static int ett_extmeta
;
1144 static int ett_extmeta_data
;
1145 static int ett_connattrs
;
1146 static int ett_connattrs_attr
;
1147 static int ett_mysql_field
;
1148 static int ett_binlog_event
;
1149 static int ett_binlog_event_hb_v2
;
1150 static int ett_mysql_binary_field
;
1152 /* protocol fields */
1153 static int hf_mysql_caps_server
;
1154 static int hf_mysql_caps_client
;
1155 static int hf_mysql_cap_long_password
;
1156 static int hf_mysql_cap_found_rows
;
1157 static int hf_mysql_cap_long_flag
;
1158 static int hf_mysql_cap_connect_with_db
;
1159 static int hf_mysql_cap_no_schema
;
1160 static int hf_mysql_cap_compress
;
1161 static int hf_mysql_cap_odbc
;
1162 static int hf_mysql_cap_local_files
;
1163 static int hf_mysql_cap_ignore_space
;
1164 static int hf_mysql_cap_change_user
;
1165 static int hf_mysql_cap_interactive
;
1166 static int hf_mysql_cap_ssl
;
1167 static int hf_mysql_cap_ignore_sigpipe
;
1168 static int hf_mysql_cap_transactions
;
1169 static int hf_mysql_cap_reserved
;
1170 static int hf_mysql_cap_secure_connect
;
1171 static int hf_mysql_extcaps_server
;
1172 static int hf_mysql_extcaps_client
;
1173 static int hf_mysql_cap_multi_statements
;
1174 static int hf_mysql_cap_multi_results
;
1175 static int hf_mysql_cap_ps_multi_results
;
1176 static int hf_mysql_cap_plugin_auth
;
1177 static int hf_mysql_cap_connect_attrs
;
1178 static int hf_mysql_cap_plugin_auth_lenenc_client_data
;
1179 static int hf_mysql_cap_client_can_handle_expired_passwords
;
1180 static int hf_mysql_cap_session_track
;
1181 static int hf_mysql_cap_deprecate_eof
;
1182 static int hf_mysql_cap_optional_metadata
;
1183 static int hf_mysql_cap_compress_zstd
;
1184 static int hf_mysql_cap_query_attrs
;
1185 static int hf_mysql_cap_mf_auth
;
1186 static int hf_mysql_cap_cap_ext
;
1187 static int hf_mysql_cap_ssl_verify_server_cert
;
1188 static int hf_mysql_cap_unused
;
1189 static int hf_mysql_server_language
;
1190 static int hf_mysql_server_status
;
1191 static int hf_mysql_stat_it
;
1192 static int hf_mysql_stat_ac
;
1193 static int hf_mysql_stat_mr
;
1194 static int hf_mysql_stat_mu
;
1195 static int hf_mysql_stat_bi
;
1196 static int hf_mysql_stat_ni
;
1197 static int hf_mysql_stat_cr
;
1198 static int hf_mysql_stat_lr
;
1199 static int hf_mysql_stat_dr
;
1200 static int hf_mysql_stat_bs
;
1201 static int hf_mysql_stat_mc
;
1202 static int hf_mysql_stat_session_state_changed
;
1203 static int hf_mysql_stat_query_was_slow
;
1204 static int hf_mysql_stat_ps_out_params
;
1205 static int hf_mysql_stat_trans_readonly
;
1206 static int hf_mysql_refresh
;
1207 static int hf_mysql_rfsh_grants
;
1208 static int hf_mysql_rfsh_log
;
1209 static int hf_mysql_rfsh_tables
;
1210 static int hf_mysql_rfsh_hosts
;
1211 static int hf_mysql_rfsh_status
;
1212 static int hf_mysql_rfsh_threads
;
1213 static int hf_mysql_rfsh_slave
;
1214 static int hf_mysql_rfsh_master
;
1215 static int hf_mysql_packet_length
;
1216 static int hf_mysql_packet_number
;
1217 static int hf_mysql_request
;
1218 static int hf_mysql_command
;
1219 static int hf_mysql_response_code
;
1220 static int hf_mysql_error_code
;
1221 static int hf_mysql_error_string
;
1222 static int hf_mysql_sqlstate
;
1223 static int hf_mysql_message
;
1224 static int hf_mysql_payload
;
1225 static int hf_mysql_server_greeting
;
1226 static int hf_mysql_session_track
;
1227 static int hf_mysql_session_track_type
;
1228 static int hf_mysql_session_track_length
;
1229 static int hf_mysql_session_track_data
;
1230 static int hf_mysql_session_track_data_length
;
1231 static int hf_mysql_session_track_sysvar_length
;
1232 static int hf_mysql_session_track_sysvar_name
;
1233 static int hf_mysql_session_track_sysvar_value
;
1234 static int hf_mysql_session_track_schema
;
1235 static int hf_mysql_session_track_schema_length
;
1236 static int hf_mysql_session_state_change
;
1237 static int hf_mysql_session_track_gtids
;
1238 static int hf_mysql_session_track_gtids_encoding
;
1239 static int hf_mysql_session_track_gtids_length
;
1240 static int hf_mysql_session_track_transaction_characteristics
;
1241 static int hf_mysql_session_track_transaction_characteristics_length
;
1242 static int hf_mysql_session_track_transaction_state
;
1243 static int hf_mysql_session_track_transaction_state_length
;
1244 static int hf_mysql_protocol
;
1245 static int hf_mysql_version
;
1246 static int hf_mysql_login_request
;
1247 static int hf_mysql_max_packet
;
1248 static int hf_mysql_user
;
1249 static int hf_mysql_table_name
;
1250 static int hf_mysql_schema
;
1251 static int hf_mysql_client_auth_plugin
;
1252 static int hf_mysql_connattrs
;
1253 static int hf_mysql_connattrs_length
;
1254 static int hf_mysql_connattrs_attr
;
1255 static int hf_mysql_connattrs_name_length
;
1256 static int hf_mysql_connattrs_name
;
1257 static int hf_mysql_connattrs_value_length
;
1258 static int hf_mysql_connattrs_value
;
1259 static int hf_mysql_zstd_compression_level
;
1260 static int hf_mysql_thread_id
;
1261 static int hf_mysql_salt
;
1262 static int hf_mysql_salt2
;
1263 static int hf_mysql_auth_plugin_length
;
1264 static int hf_mysql_auth_plugin
;
1265 static int hf_mysql_collation
;
1266 static int hf_mysql_passwd
;
1267 static int hf_mysql_unused
;
1268 static int hf_mysql_affected_rows
;
1269 static int hf_mysql_insert_id
;
1270 static int hf_mysql_num_warn
;
1271 static int hf_mysql_stmt_id
;
1272 static int hf_mysql_query_attributes
;
1273 static int hf_mysql_query_attributes_count
;
1274 static int hf_mysql_query_attributes_send_types_to_server
;
1275 static int hf_mysql_query_attribute_name_type
;
1276 static int hf_mysql_query_attribute_name
;
1277 static int hf_mysql_query_attribute_value
;
1278 static int hf_mysql_query
;
1279 static int hf_mysql_shutdown
;
1280 static int hf_mysql_option
;
1281 static int hf_mysql_num_rows
;
1282 static int hf_mysql_param
;
1283 static int hf_mysql_param_name
;
1284 static int hf_mysql_num_params
;
1285 static int hf_mysql_exec_flags4
;
1286 static int hf_mysql_exec_flags5
;
1287 static int hf_mysql_exec_iter
;
1288 static int hf_mysql_binlog_position
;
1289 static int hf_mysql_binlog_position8
;
1290 static int hf_mysql_binlog_flags
;
1291 static int hf_mysql_binlog_server_id
;
1292 static int hf_mysql_binlog_file_name
;
1293 static int hf_mysql_binlog_file_name_length
;
1294 static int hf_mysql_binlog_slave_hostname_length
;
1295 static int hf_mysql_binlog_slave_hostname
;
1296 static int hf_mysql_binlog_slave_user_length
;
1297 static int hf_mysql_binlog_slave_user
;
1298 static int hf_mysql_binlog_slave_password_length
;
1299 static int hf_mysql_binlog_slave_password
;
1300 static int hf_mysql_binlog_slave_mysql_port
;
1301 static int hf_mysql_binlog_replication_rank
;
1302 static int hf_mysql_binlog_master_id
;
1303 static int hf_mysql_binlog_event_header_timestamp
;
1304 static int hf_mysql_binlog_event_header_event_type
;
1305 static int hf_mysql_binlog_event_header_server_id
;
1306 static int hf_mysql_binlog_event_header_event_size
;
1307 static int hf_mysql_binlog_event_header_log_position
;
1308 static int hf_mysql_binlog_event_header_flags
;
1309 static int hf_mysql_binlog_event_checksum
;
1310 static int hf_mysql_binlog_event_heartbeat_v2
;
1311 static int hf_mysql_binlog_event_heartbeat_v2_otw
;
1312 static int hf_mysql_binlog_event_heartbeat_v2_otw_type
;
1313 static int hf_mysql_binlog_gtid_data
;
1314 static int hf_mysql_binlog_gtid_data_length
;
1315 static int hf_mysql_binlog_hb_event_filename
;
1316 static int hf_mysql_binlog_hb_event_log_position
;
1317 static int hf_mysql_clone_command_code
;
1318 static int hf_mysql_clone_response_code
;
1319 static int hf_mysql_eof
;
1320 static int hf_mysql_num_fields
;
1321 static int hf_mysql_extra
;
1322 static int hf_mysql_fld_catalog
;
1323 static int hf_mysql_fld_db
;
1324 static int hf_mysql_fld_table
;
1325 static int hf_mysql_fld_org_table
;
1326 static int hf_mysql_fld_name
;
1327 static int hf_mysql_fld_org_name
;
1328 static int hf_mysql_fld_charsetnr
;
1329 static int hf_mysql_fld_length
;
1330 static int hf_mysql_fld_type
;
1331 static int hf_mysql_fld_flags
;
1332 static int hf_mysql_fld_not_null
;
1333 static int hf_mysql_fld_primary_key
;
1334 static int hf_mysql_fld_unique_key
;
1335 static int hf_mysql_fld_multiple_key
;
1336 static int hf_mysql_fld_blob
;
1337 static int hf_mysql_fld_unsigned
;
1338 static int hf_mysql_fld_zero_fill
;
1339 static int hf_mysql_exec_field_null
;
1340 static int hf_mysql_null_buffer
;
1341 static int hf_mysql_fld_enum
;
1342 static int hf_mysql_fld_auto_increment
;
1343 static int hf_mysql_fld_timestamp
;
1344 static int hf_mysql_fld_set
;
1345 static int hf_mysql_fld_decimals
;
1346 static int hf_mysql_fld_default
;
1347 static int hf_mysql_row_text
;
1348 static int hf_mysql_new_parameter_bound_flag
;
1349 static int hf_mysql_exec_param
;
1350 static int hf_mysql_exec_unsigned
;
1351 static int hf_mysql_exec_field_longlong
;
1352 static int hf_mysql_exec_field_unsigned_longlong
;
1353 static int hf_mysql_exec_field_bit_length
;
1354 static int hf_mysql_exec_field_bit
;
1355 static int hf_mysql_exec_field_blob_length
;
1356 static int hf_mysql_exec_field_blob
;
1357 static int hf_mysql_exec_field_geometry_length
;
1358 static int hf_mysql_exec_field_geometry
;
1359 static int hf_mysql_exec_field_json_length
;
1360 static int hf_mysql_exec_field_string_length
;
1361 static int hf_mysql_exec_field_string
;
1362 static int hf_mysql_exec_field_double
;
1363 static int hf_mysql_exec_field_datetime_length
;
1364 static int hf_mysql_exec_field_year
;
1365 static int hf_mysql_exec_field_month
;
1366 static int hf_mysql_exec_field_day
;
1367 static int hf_mysql_exec_field_hour
;
1368 static int hf_mysql_exec_field_minute
;
1369 static int hf_mysql_exec_field_second
;
1370 static int hf_mysql_exec_field_second_b
;
1371 static int hf_mysql_exec_field_int24
;
1372 static int hf_mysql_exec_field_long
;
1373 static int hf_mysql_exec_field_unsigned_long
;
1374 static int hf_mysql_exec_field_tiny
;
1375 static int hf_mysql_exec_field_unsigned_tiny
;
1376 static int hf_mysql_exec_field_short
;
1377 static int hf_mysql_exec_field_unsigned_short
;
1378 static int hf_mysql_exec_field_float
;
1379 static int hf_mysql_exec_field_time_length
;
1380 static int hf_mysql_exec_field_time_sign
;
1381 static int hf_mysql_exec_field_time_days
;
1382 static int hf_mysql_auth_switch_request_status
;
1383 static int hf_mysql_auth_switch_request_name
;
1384 static int hf_mysql_auth_switch_request_data
;
1385 static int hf_mysql_auth_switch_response_data
;
1386 static int hf_mysql_sha2_auth
;
1387 static int hf_mysql_sha2_response
;
1388 static int hf_mysql_pubkey
;
1389 static int hf_mysql_compressed_packet_length
;
1390 static int hf_mysql_compressed_packet_length_uncompressed
;
1391 static int hf_mysql_compressed_packet_number
;
1392 static int hf_mysql_loaddata_filename
;
1393 static int hf_mysql_loaddata_payload
;
1395 //static int hf_mariadb_fld_charsetnr;
1396 static int hf_mariadb_server_language
;
1397 static int hf_mariadb_collation
;
1398 static int hf_mariadb_cap_progress
;
1399 static int hf_mariadb_cap_commulti
;
1400 static int hf_mariadb_cap_bulk
;
1401 static int hf_mariadb_cap_extmetadata
;
1402 static int hf_mariadb_cap_cache_metadata
;
1403 static int hf_mariadb_extcaps_server
;
1404 static int hf_mariadb_extcaps_client
;
1405 static int hf_mariadb_bulk_flag_autoid
;
1406 static int hf_mariadb_bulk_flag_sendtypes
;
1407 static int hf_mariadb_bulk_caps_flags
;
1408 static int hf_mariadb_bulk_paramtypes
;
1409 static int hf_mariadb_bulk_indicator
;
1410 static int hf_mariadb_bulk_row_nr
;
1411 static int hf_mariadb_send_meta
;
1412 static int hf_mariadb_extmeta
;
1413 static int hf_mariadb_extmeta_data
;
1414 static int hf_mariadb_extmeta_length
;
1415 static int hf_mariadb_extmeta_key
;
1416 static int hf_mariadb_extmeta_type
;
1417 static int hf_mariadb_extmeta_format
;
1419 static dissector_handle_t mysql_handle
;
1420 static dissector_handle_t decompressed_handle
;
1421 static dissector_handle_t tls_handle
;
1423 static expert_field ei_mysql_dissector_incomplete
;
1424 static expert_field ei_mysql_streamed_param
;
1425 static expert_field ei_mysql_prepare_response_needed
;
1426 static expert_field ei_mysql_unknown_response
;
1427 static expert_field ei_mysql_command
;
1428 static expert_field ei_mysql_invalid_length
;
1429 static expert_field ei_mysql_compression
;
1431 /* Reassembly of decompressed packets in compressed packets {{{ */
1433 static int hf_mysql_fragments
;
1434 static int hf_mysql_fragment
;
1435 static int hf_mysql_fragment_overlap
;
1436 static int hf_mysql_fragment_overlap_conflicts
;
1437 static int hf_mysql_fragment_multiple_tails
;
1438 static int hf_mysql_fragment_too_long_fragment
;
1439 static int hf_mysql_fragment_error
;
1440 static int hf_mysql_fragment_count
;
1441 static int hf_mysql_reassembled_in
;
1442 static int hf_mysql_reassembled_length
;
1443 static int hf_mysql_fragment_data
;
1445 static int ett_mysql_fragment
;
1446 static int ett_mysql_fragments
;
1448 static const fragment_items mysql_frag_items
= {
1449 &ett_mysql_fragment
,
1450 &ett_mysql_fragments
,
1451 &hf_mysql_fragments
,
1453 &hf_mysql_fragment_overlap
,
1454 &hf_mysql_fragment_overlap_conflicts
,
1455 &hf_mysql_fragment_multiple_tails
,
1456 &hf_mysql_fragment_too_long_fragment
,
1457 &hf_mysql_fragment_error
,
1458 &hf_mysql_fragment_count
,
1459 &hf_mysql_reassembled_in
,
1460 &hf_mysql_reassembled_length
,
1465 static reassembly_table mysql_reassembly_table
;
1467 /* }}} Reassembly of decompressed packets */
1469 /* type constants */
1470 static const value_string type_constants
[] = {
1471 {0x00, "FIELD_TYPE_DECIMAL" },
1472 {0x01, "FIELD_TYPE_TINY" },
1473 {0x02, "FIELD_TYPE_SHORT" },
1474 {0x03, "FIELD_TYPE_LONG" },
1475 {0x04, "FIELD_TYPE_FLOAT" },
1476 {0x05, "FIELD_TYPE_DOUBLE" },
1477 {0x06, "FIELD_TYPE_NULL" },
1478 {0x07, "FIELD_TYPE_TIMESTAMP" },
1479 {0x08, "FIELD_TYPE_LONGLONG" },
1480 {0x09, "FIELD_TYPE_INT24" },
1481 {0x0a, "FIELD_TYPE_DATE" },
1482 {0x0b, "FIELD_TYPE_TIME" },
1483 {0x0c, "FIELD_TYPE_DATETIME" },
1484 {0x0d, "FIELD_TYPE_YEAR" },
1485 {0x0e, "FIELD_TYPE_NEWDATE" },
1486 {0x0f, "FIELD_TYPE_VARCHAR" },
1487 {0x10, "FIELD_TYPE_BIT" },
1488 {0xf5, "FIELD_TYPE_JSON" },
1489 {0xf6, "FIELD_TYPE_NEWDECIMAL" },
1490 {0xf7, "FIELD_TYPE_ENUM" },
1491 {0xf8, "FIELD_TYPE_SET" },
1492 {0xf9, "FIELD_TYPE_TINY_BLOB" },
1493 {0xfa, "FIELD_TYPE_MEDIUM_BLOB"},
1494 {0xfb, "FIELD_TYPE_LONG_BLOB" },
1495 {0xfc, "FIELD_TYPE_BLOB" },
1496 {0xfd, "FIELD_TYPE_VAR_STRING" },
1497 {0xfe, "FIELD_TYPE_STRING" },
1498 {0xff, "FIELD_TYPE_GEOMETRY" },
1502 typedef enum mysql_state
{
1512 RESPONSE_SHOW_FIELDS
,
1517 PREPARED_PARAMETERS
,
1519 AUTH_SWITCH_REQUEST
,
1520 AUTH_SWITCH_RESPONSE
,
1528 RESPONSE_LOCALINFILE
,
1532 static const value_string state_vals
[] = {
1533 {UNDEFINED
, "undefined"},
1535 {REQUEST
, "request"},
1536 {RESPONSE_OK
, "response OK"},
1537 {RESPONSE_ERROR
, "response ERROR"},
1538 {RESPONSE_EOF
, "response EOF"},
1539 {INTERMEDIATE_EOF
, "intermediate EOF"},
1540 {RESPONSE_MESSAGE
, "response message"},
1541 {RESPONSE_TABULAR
, "tabular response"},
1542 {RESPONSE_SHOW_FIELDS
, "response to SHOW FIELDS"},
1543 {FIELD_PACKET
, "field packet"},
1544 {ROW_PACKET
, "row packet"},
1545 {COLUMN_COUNT
, "column count"},
1546 {RESPONSE_PREPARE
, "response to PREPARE"},
1547 {PREPARED_PARAMETERS
, "parameters in response to PREPARE"},
1548 {PREPARED_FIELDS
, "fields in response to PREPARE"},
1549 {AUTH_SWITCH_REQUEST
, "authentication switch request"},
1550 {AUTH_SWITCH_RESPONSE
, "authentication switch response"},
1551 {AUTH_SHA2
, "caching_sha2_password"},
1552 {AUTH_PUBKEY
, "public key request"},
1553 {AUTH_SHA2_RESPONSE
, "caching_sha2_password response"},
1554 {BINLOG_DUMP
, "binlog event"},
1555 {CLONE_INIT
, "cloning initializing"},
1556 {CLONE_ACTIVE
, "cloning active"},
1557 {CLONE_EXIT
, "cloning shutting down"},
1558 {RESPONSE_LOCALINFILE
, "local infile"},
1559 {INFILE_DATA
, "local infile data"},
1563 typedef enum mysql_resultset_fmt
{
1566 } mysql_resultset_fmt_t
;
1568 #define MAX_MY_METADATA_COUNT INT16_MAX // Arbitrary; is 32k enough?
1573 unsigned* encodings
;
1574 } my_metadata_list_t
;
1576 /* Data for the entire conversation. Most data is fixed once known.
1577 * For data which changes from packet to packet such as the state,
1578 * this holds the value of the last value seen during the first
1579 * sequential pass. On subsequent passes, for random packet access,
1580 * the per-packet frame data below should be used to access the state.
1582 typedef struct mysql_conn_data
{
1584 uint16_t srv_caps_ext
;
1586 uint16_t clnt_caps_ext
;
1589 uint32_t generation
;
1591 uint8_t major_version
;
1592 uint32_t frame_start_ssl
;
1593 uint32_t frame_start_compressed
;
1594 uint8_t compressed_state
;
1595 uint8_t compressed_alg
;
1596 bool is_mariadb_server
; /* set to 1, if connected to a MariaDB server */
1597 bool is_mariadb_client
; /* set to 1, if connected from a MariaDB client */
1598 uint32_t mariadb_server_ext_caps
;
1599 uint32_t mariadb_client_ext_caps
;
1600 uint8_t *auth_method
;
1601 streaming_reassembly_info_t
*reassembly_info
;
1603 /* The members below refer to the latest state or prepared statement,
1604 * and is only valid during the first pass. For random access on
1605 * later passes, use the data stored in the mysql_frame_data. */
1606 mysql_state_t state
;
1607 mysql_resultset_fmt_t resultset_fmt
;
1609 uint64_t remaining_field_packet_count
;
1610 my_metadata_list_t field_metas
;
1611 unsigned encoding_client
;
1612 unsigned encoding_results
;
1613 } mysql_conn_data_t
;
1615 /* Data stored for a particular PDU. Use this on random access after
1616 * the first pass to obtain the state at the start of a PDU.
1618 typedef struct mysql_frame_data
{
1619 mysql_state_t state
;
1620 mysql_resultset_fmt_t resultset_fmt
;
1621 uint32_t stmt_id
; /* The last prepared stmt ID before this PDU */
1622 uint64_t remaining_field_packet_count
;
1623 my_metadata_list_t field_metas
;
1624 unsigned encoding_client
;
1625 unsigned encoding_results
;
1626 } mysql_frame_data_t
;
1628 typedef struct my_stmt_data
{
1629 my_metadata_list_t param_metas
;
1630 my_metadata_list_t field_metas
;
1631 uint16_t bulk_flags
;
1634 typedef struct mysql_exec_dissector
{
1636 uint8_t unsigned_flag
;
1637 void (*dissector
)(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned charset
);
1638 } mysql_exec_dissector_t
;
1640 /* function prototypes */
1641 static int mysql_dissect_error_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, const mysql_frame_data_t
*my_frame_data
);
1642 static int mysql_dissect_ok_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
);
1643 static int mysql_dissect_server_status(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, uint16_t *server_status
);
1644 static int mysql_dissect_caps(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, int mysql_caps
, uint16_t *caps
);
1645 static int mysql_dissect_extcaps(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, int mysql_extcaps
, uint16_t *caps
);
1646 static int mysql_dissect_result_header(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
, const mysql_frame_data_t
*my_frame_data
);
1647 static int mysql_dissect_field_packet(tvbuff_t
*tvb
, proto_item
*pi
, int offset
, proto_tree
*tree
, packet_info
*pinfo
, mysql_conn_data_t
*conn_data
, const mysql_frame_data_t
*my_frame_data
);
1648 static int mysql_dissect_text_row_packet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const mysql_frame_data_t
*my_frame_data
);
1649 static int mysql_dissect_binary_row_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_item
*pi
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
, const mysql_frame_data_t
*my_frame_data
);
1650 static int mysql_dissect_binlog_event_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, proto_item
*pi
);
1651 static int mysql_dissect_response_prepare(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
);
1652 static int mysql_dissect_auth_switch_request(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
);
1653 static int mysql_dissect_eof(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_item
*pi
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
);
1654 static int mysql_dissect_auth_switch_response(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
);
1655 static int mysql_dissect_auth_sha2(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
);
1656 static int mysql_dissect_loaddata(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
);
1657 static void mysql_dissect_exec_bit(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1658 static void mysql_dissect_exec_blob(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1659 static void mysql_dissect_exec_geometry(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1660 static void mysql_dissect_exec_string(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1661 static void mysql_dissect_exec_json(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1662 static void mysql_dissect_exec_datetime(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1663 static void mysql_dissect_exec_tiny(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1664 static void mysql_dissect_exec_unsigned_tiny(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1665 static void mysql_dissect_exec_short(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1666 static void mysql_dissect_exec_unsigned_short(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1667 static void mysql_dissect_exec_int24(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1668 static void mysql_dissect_exec_long(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1669 static void mysql_dissect_exec_unsigned_long(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1670 static void mysql_dissect_exec_float(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1671 static void mysql_dissect_exec_double(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1672 static void mysql_dissect_exec_longlong(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1673 static void mysql_dissect_exec_unsigned_longlong(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1674 static void mysql_dissect_exec_year(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1675 static void mysql_dissect_exec_null(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1676 static char mysql_dissect_exec_param(proto_item
*req_tree
, tvbuff_t
*tvb
, int *offset
,
1677 int *param_offset
, uint8_t param_flags
, packet_info
*pinfo
, unsigned encoding
, bool queryattrs
);
1678 static char mysql_dissect_binary_row_value(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_item
*pi
, int *offset
,
1679 proto_item
*tree
, uint8_t field_type
, uint16_t field_flag
, unsigned field_encoding
);
1681 static void mysql_dissect_exec_primitive(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
,
1682 proto_item
*field_tree
, const int hfindex
, const int offset
);
1683 static void mysql_dissect_exec_time(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
);
1684 static int mariadb_dissect_caps_or_flags(tvbuff_t
*tvb
, int offset
, enum ftenum type
, proto_tree
*tree
,
1685 int mariadb_caps
, int * const *fields
, void *value
);
1687 static int my_tvb_strsize(tvbuff_t
*tvb
, int offset
);
1688 static int tvb_get_fle(tvbuff_t
*tvb
, proto_tree
* tree
, int offset
, uint64_t *res
, uint8_t *is_null
);
1690 static int mysql_field_add_lestring(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, int field
, unsigned encoding
);
1691 static int dissect_mysql_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
);
1692 static unsigned get_mysql_pdu_len(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, void *data _U_
);
1694 // type, unsigned, dissector
1695 static const mysql_exec_dissector_t mysql_exec_dissectors
[] = {
1696 { 0x01, 0, mysql_dissect_exec_tiny
}, // FIELD_TYPE_TINY
1697 { 0x01, 1, mysql_dissect_exec_unsigned_tiny
}, // FIELD_TYPE_TINY
1698 { 0x02, 0, mysql_dissect_exec_short
}, // FIELD_TYPE_SHORT
1699 { 0x02, 1, mysql_dissect_exec_unsigned_short
}, // FIELD_TYPE_SHORT
1700 { 0x03, 0, mysql_dissect_exec_long
}, // FIELD_TYPE_LONG
1701 { 0x03, 1, mysql_dissect_exec_unsigned_long
}, // FIELD_TYPE_LONG
1702 { 0x04, 0, mysql_dissect_exec_float
}, // FIELD_TYPE_FLOAT
1703 { 0x05, 0, mysql_dissect_exec_double
}, // FIELD_TYPE_DOUBLE
1704 { 0x06, 0, mysql_dissect_exec_null
}, // FIELD_TYPE_NULL
1705 { 0x07, 0, mysql_dissect_exec_datetime
}, // FIELD_TYPE_TIMESTAMP
1706 { 0x07, 1, mysql_dissect_exec_datetime
}, // FIELD_TYPE_TIMESTAMP
1707 { 0x08, 0, mysql_dissect_exec_longlong
}, // FIELD_TYPE_LONGLONG
1708 { 0x08, 1, mysql_dissect_exec_unsigned_longlong
}, // FIELD_TYPE_LONGLONG
1709 { 0x09, 0, mysql_dissect_exec_int24
}, // FIELD_TYPE_INT24
1710 { 0x09, 1, mysql_dissect_exec_int24
}, // FIELD_TYPE_INT24
1711 { 0x0a, 0, mysql_dissect_exec_datetime
}, // FIELD_TYPE_DATE
1712 { 0x0b, 0, mysql_dissect_exec_time
}, // FIELD_TYPE_TIME
1713 { 0x0c, 0, mysql_dissect_exec_datetime
}, // FIELD_TYPE_DATETIME
1714 { 0x0d, 0, mysql_dissect_exec_year
}, // FIELD_TYPE_YEAR
1715 { 0x0d, 1, mysql_dissect_exec_year
}, // FIELD_TYPE_YEAR
1716 { 0x10, 1, mysql_dissect_exec_bit
}, // FIELD_TYPE_BIT
1717 { 0x10, 1, mysql_dissect_exec_bit
}, // FIELD_TYPE_BIT
1718 { 0xf5, 0, mysql_dissect_exec_json
}, // FIELD_TYPE_JSON
1719 { 0xf6, 0, mysql_dissect_exec_string
}, // FIELD_TYPE_NEWDECIMAL
1720 { 0xfc, 0, mysql_dissect_exec_blob
}, // FIELD_TYPE_BLOB
1721 { 0xfd, 0, mysql_dissect_exec_string
}, // FIELD_TYPE_VAR_STRING
1722 { 0xfe, 0, mysql_dissect_exec_string
}, // FIELD_TYPE_STRING
1723 { 0xff, 0, mysql_dissect_exec_geometry
}, // FIELD_TYPE_GEOMETRY
1727 static int * const mysql_rfsh_flags
[] = {
1728 &hf_mysql_rfsh_grants
,
1730 &hf_mysql_rfsh_tables
,
1731 &hf_mysql_rfsh_hosts
,
1732 &hf_mysql_rfsh_status
,
1733 &hf_mysql_rfsh_threads
,
1734 &hf_mysql_rfsh_slave
,
1735 &hf_mysql_rfsh_master
,
1739 static int * const mysql_stat_flags
[] = {
1751 &hf_mysql_stat_query_was_slow
,
1752 &hf_mysql_stat_ps_out_params
,
1753 &hf_mysql_stat_trans_readonly
,
1754 &hf_mysql_stat_session_state_changed
,
1758 static int * const mysql_caps_flags
[] = {
1759 &hf_mysql_cap_long_password
,
1760 &hf_mysql_cap_found_rows
,
1761 &hf_mysql_cap_long_flag
,
1762 &hf_mysql_cap_connect_with_db
,
1763 &hf_mysql_cap_no_schema
,
1764 &hf_mysql_cap_compress
,
1766 &hf_mysql_cap_local_files
,
1767 &hf_mysql_cap_ignore_space
,
1768 &hf_mysql_cap_change_user
,
1769 &hf_mysql_cap_interactive
,
1771 &hf_mysql_cap_ignore_sigpipe
,
1772 &hf_mysql_cap_transactions
,
1773 &hf_mysql_cap_reserved
,
1774 &hf_mysql_cap_secure_connect
,
1778 static int * const mysql_extcaps_flags
[] = {
1779 &hf_mysql_cap_multi_statements
,
1780 &hf_mysql_cap_multi_results
,
1781 &hf_mysql_cap_ps_multi_results
,
1782 &hf_mysql_cap_plugin_auth
,
1783 &hf_mysql_cap_connect_attrs
,
1784 &hf_mysql_cap_plugin_auth_lenenc_client_data
,
1785 &hf_mysql_cap_client_can_handle_expired_passwords
,
1786 &hf_mysql_cap_session_track
,
1787 &hf_mysql_cap_deprecate_eof
,
1788 &hf_mysql_cap_optional_metadata
,
1789 &hf_mysql_cap_compress_zstd
,
1790 &hf_mysql_cap_query_attrs
,
1791 &hf_mysql_cap_mf_auth
,
1792 &hf_mysql_cap_cap_ext
,
1793 &hf_mysql_cap_ssl_verify_server_cert
,
1794 &hf_mysql_cap_unused
,
1798 static int * const mariadb_extcaps_flags
[] = {
1799 &hf_mariadb_cap_progress
,
1800 &hf_mariadb_cap_commulti
,
1801 &hf_mariadb_cap_bulk
,
1802 &hf_mariadb_cap_extmetadata
,
1803 &hf_mariadb_cap_cache_metadata
,
1807 static int * const mariadb_bulk_caps_flags
[] = {
1808 &hf_mariadb_bulk_flag_autoid
,
1809 &hf_mariadb_bulk_flag_sendtypes
,
1813 static int * const mysql_fld_flags
[] = {
1814 &hf_mysql_fld_not_null
,
1815 &hf_mysql_fld_primary_key
,
1816 &hf_mysql_fld_unique_key
,
1817 &hf_mysql_fld_multiple_key
,
1819 &hf_mysql_fld_unsigned
,
1820 &hf_mysql_fld_zero_fill
,
1822 &hf_mysql_fld_auto_increment
,
1823 &hf_mysql_fld_timestamp
,
1828 /* Helper function to only set state on first pass */
1829 static void mysql_set_conn_state(packet_info
*pinfo
, mysql_conn_data_t
*conn_data
, mysql_state_t state
)
1831 if (!pinfo
->fd
->visited
)
1833 conn_data
->state
= state
;
1837 static void mysql_set_resultset_fmt(packet_info
*pinfo
, mysql_conn_data_t
*conn_data
, mysql_resultset_fmt_t fmt
)
1839 if (!pinfo
->fd
->visited
)
1841 conn_data
->resultset_fmt
= fmt
;
1845 static void mysql_set_prepared_stmt_id(packet_info
*pinfo
, mysql_conn_data_t
*conn_data
, uint32_t stmt_id
)
1847 if (!pinfo
->fd
->visited
)
1849 conn_data
->stmt_id
= stmt_id
;
1853 /* Decrements the number of remaining field packets. Returns true if this
1854 * was the last field packet (and thus the state should change.)
1856 static bool mysql_dec_remaining_field_packet_count(packet_info
*pinfo
, mysql_conn_data_t
*conn_data
)
1858 if (!pinfo
->fd
->visited
)
1860 conn_data
->remaining_field_packet_count
--;
1861 return (conn_data
->remaining_field_packet_count
== 0);
1866 static void mysql_set_remaining_field_packet_count(packet_info
*pinfo
, mysql_conn_data_t
*conn_data
, uint64_t num_fields
)
1868 if (!pinfo
->fd
->visited
)
1870 conn_data
->remaining_field_packet_count
= num_fields
;
1874 static void mysql_set_field_metas(packet_info
*pinfo
, mysql_conn_data_t
*conn_data
, my_metadata_list_t
*field_metas
)
1876 if (!pinfo
->fd
->visited
)
1878 conn_data
->field_metas
= *field_metas
;
1882 static void mysql_set_encoding_client(packet_info
*pinfo
, mysql_conn_data_t
*conn_data
, unsigned encoding
)
1884 if (!pinfo
->fd
->visited
)
1886 conn_data
->encoding_client
= encoding
;
1890 static void mysql_set_encoding_results(packet_info
*pinfo
, mysql_conn_data_t
*conn_data
, unsigned encoding
)
1892 if (!pinfo
->fd
->visited
)
1894 conn_data
->encoding_results
= encoding
;
1899 mysql_dissect_greeting(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
1900 proto_tree
*tree
, mysql_conn_data_t
*conn_data
,
1901 const mysql_frame_data_t
*my_frame_data
)
1908 proto_item
*greeting_tree
;
1911 protocol
= tvb_get_uint8(tvb
, offset
);
1913 if (protocol
== 0xff) {
1914 return mysql_dissect_error_packet(tvb
, pinfo
, offset
+1, tree
, my_frame_data
);
1917 mysql_set_conn_state(pinfo
, conn_data
, LOGIN
);
1919 tf
= proto_tree_add_item(tree
, hf_mysql_server_greeting
, tvb
, offset
, -1, ENC_NA
);
1920 greeting_tree
= proto_item_add_subtree(tf
, ett_server_greeting
);
1922 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " proto=%d", protocol
) ;
1924 proto_tree_add_item(greeting_tree
, hf_mysql_protocol
, tvb
, offset
, 1, ENC_NA
);
1928 /* version string */
1929 lenstr
= tvb_strsize(tvb
,offset
);
1931 /* check if it is a MariaDB Server: MariaDB always sends 5.5.5- before real version number */
1932 tvb_get_raw_bytes_as_string(tvb
, offset
, buffer
, 7);
1933 if (lenstr
> 6 && strncmp(buffer
, MARIADB_RPL_VERSION_HACK
, sizeof(MARIADB_RPL_VERSION_HACK
) - 1) == 0)
1935 conn_data
->is_mariadb_server
= 1;
1936 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " version=%s ",
1937 tvb_format_text(pinfo
->pool
, tvb
, offset
+ 6, lenstr
- 7));
1939 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " version=%s ",
1940 tvb_format_text(pinfo
->pool
, tvb
, offset
, lenstr
-1));
1943 col_set_fence(pinfo
->cinfo
, COL_INFO
);
1945 proto_tree_add_item(greeting_tree
, hf_mysql_version
, tvb
, offset
, lenstr
, ENC_ASCII
);
1946 conn_data
->major_version
= 0;
1947 for (ver_offset
= 0; ver_offset
< lenstr
; ver_offset
++) {
1948 uint8_t ver_char
= tvb_get_uint8(tvb
, offset
+ ver_offset
);
1949 if (ver_char
== '.') break;
1950 conn_data
->major_version
= conn_data
->major_version
* 10 + ver_char
- '0';
1954 /* 4 bytes little endian thread_id */
1955 proto_tree_add_item(greeting_tree
, hf_mysql_thread_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1959 lenstr
= tvb_strsize(tvb
,offset
);
1960 proto_tree_add_item(greeting_tree
, hf_mysql_salt
, tvb
, offset
, lenstr
, ENC_ASCII
);
1963 /* rest is optional */
1964 if (!tvb_reported_length_remaining(tvb
, offset
)) return offset
;
1967 offset
= mysql_dissect_caps(tvb
, offset
, greeting_tree
, hf_mysql_caps_server
, &conn_data
->srv_caps
);
1969 /* MariaDB server don't have the CLIENT_MYSQL/CLIENT_LONG_PASSWORD capability */
1970 if (!(conn_data
->srv_caps
& MYSQL_CAPS_LP
))
1972 conn_data
->is_mariadb_server
= 1;
1975 /* rest is optional */
1976 if (!tvb_reported_length_remaining(tvb
, offset
)) return offset
;
1978 proto_tree_add_item(greeting_tree
, conn_data
->is_mariadb_server
? hf_mariadb_server_language
: hf_mysql_server_language
, tvb
, offset
, 1, ENC_NA
);
1979 offset
+= 1; /* for charset */
1981 offset
= mysql_dissect_server_status(tvb
, offset
, greeting_tree
, NULL
);
1983 /* 2 bytes ExtCAPS */
1984 offset
= mysql_dissect_extcaps(tvb
, offset
, greeting_tree
, hf_mysql_extcaps_server
, &conn_data
->srv_caps_ext
);
1986 /* 1 byte Auth Plugin Length */
1987 proto_tree_add_item(greeting_tree
, hf_mysql_auth_plugin_length
, tvb
, offset
, 1, ENC_NA
);
1990 if (conn_data
->is_mariadb_server
)
1992 /* 6 bytes unused */
1993 proto_tree_add_item(greeting_tree
, hf_mysql_unused
, tvb
, offset
, 6, ENC_NA
);
1995 /* MariaDB specific extended capabilities */
1996 offset
= mariadb_dissect_caps_or_flags(tvb
, offset
, FT_UINT32
, greeting_tree
,
1997 hf_mariadb_extcaps_server
, mariadb_extcaps_flags
, &conn_data
->mariadb_server_ext_caps
);
1999 /* 10 bytes unused */
2000 proto_tree_add_item(greeting_tree
, hf_mysql_unused
, tvb
, offset
, 10, ENC_NA
);
2004 /* 4.1+ server: rest of salt */
2005 if (tvb_reported_length_remaining(tvb
, offset
)) {
2006 lenstr
= tvb_strsize(tvb
,offset
);
2007 proto_tree_add_item(greeting_tree
, hf_mysql_salt2
, tvb
, offset
, lenstr
, ENC_ASCII
);
2011 /* 5.x server: auth plugin */
2012 if (tvb_reported_length_remaining(tvb
, offset
)) {
2013 lenstr
= tvb_strsize(tvb
,offset
);
2014 proto_tree_add_item(greeting_tree
, hf_mysql_auth_plugin
, tvb
, offset
, lenstr
, ENC_ASCII
);
2015 conn_data
->auth_method
= tvb_get_string_enc(wmem_file_scope(), tvb
, offset
, lenstr
, ENC_ASCII
);
2024 Add a connect attributes entry to the connattrs subtree
2029 add_connattrs_entry_to_tree(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_item
*tree
, int offset
) {
2031 int orig_offset
= offset
, lenfle
;
2033 proto_tree
*connattrs_tree
;
2036 ti
= proto_tree_add_item(tree
, hf_mysql_connattrs_attr
, tvb
, offset
, 1, ENC_NA
);
2037 connattrs_tree
= proto_item_add_subtree(ti
, ett_connattrs_attr
);
2039 lenfle
= tvb_get_fle(tvb
, connattrs_tree
, offset
, &lenstr
, NULL
);
2040 proto_tree_add_uint64(connattrs_tree
, hf_mysql_connattrs_name_length
, tvb
, offset
, lenfle
, lenstr
);
2043 proto_tree_add_item_ret_string(connattrs_tree
, hf_mysql_connattrs_name
, tvb
, offset
, (int)lenstr
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
2044 proto_item_append_text(ti
, " - %s", str
);
2045 offset
+= (int)lenstr
;
2047 lenfle
= tvb_get_fle(tvb
, connattrs_tree
, offset
, &lenstr
, NULL
);
2048 proto_tree_add_uint64(connattrs_tree
, hf_mysql_connattrs_value_length
, tvb
, offset
, lenfle
, lenstr
);
2051 proto_tree_add_item_ret_string(connattrs_tree
, hf_mysql_connattrs_value
, tvb
, offset
, (int)lenstr
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
2052 proto_item_append_text(ti
, ": %s", str
);
2053 offset
+= (int)lenstr
;
2055 proto_item_set_len(ti
, offset
- orig_offset
);
2057 return (offset
- orig_offset
);
2061 mysql_dissect_login(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
2062 proto_tree
*tree
, mysql_conn_data_t
*conn_data
)
2067 proto_item
*login_tree
;
2069 /* after login there can be OK or DENIED */
2070 if (conn_data
->clnt_caps
& MYSQL_CAPS_SL
) {
2071 mysql_set_conn_state(pinfo
, conn_data
, LOGIN
);
2072 } else if (!(conn_data
->clnt_caps
== 0)) {
2073 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2076 tf
= proto_tree_add_item(tree
, hf_mysql_login_request
, tvb
, offset
, -1, ENC_NA
);
2077 login_tree
= proto_item_add_subtree(tf
, ett_login_request
);
2079 offset
= mysql_dissect_caps(tvb
, offset
, login_tree
, hf_mysql_caps_client
, &conn_data
->clnt_caps
);
2081 /* MariaDB clients don't have the CLIENT_MYSQL/CLIENT_LONG_PASSWORD capability */
2082 if (!(conn_data
->clnt_caps
& MYSQL_CAPS_LP
))
2084 conn_data
->is_mariadb_client
= 1;
2087 if (!(conn_data
->frame_start_ssl
) && conn_data
->clnt_caps
& MYSQL_CAPS_SL
) /* Next packet will be use SSL */
2089 col_set_str(pinfo
->cinfo
, COL_INFO
, "Response: SSL Handshake");
2090 conn_data
->frame_start_ssl
= pinfo
->num
;
2091 ssl_starttls_ack(tls_handle
, pinfo
, mysql_handle
);
2093 if (conn_data
->clnt_caps
& MYSQL_CAPS_CU
) /* 4.1 protocol */{
2094 offset
= mysql_dissect_extcaps(tvb
, offset
, login_tree
, hf_mysql_extcaps_client
, &conn_data
->clnt_caps_ext
);
2096 proto_tree_add_item(login_tree
, hf_mysql_max_packet
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2100 proto_tree_add_item_ret_uint(login_tree
, conn_data
->is_mariadb_server
? hf_mariadb_collation
: hf_mysql_collation
, tvb
, offset
, 1, ENC_NA
, &collation
);
2101 unsigned encoding
= collation_to_encoding(collation
, conn_data
->is_mariadb_server
);
2102 mysql_set_encoding_client(pinfo
, conn_data
, encoding
);
2103 mysql_set_encoding_results(pinfo
, conn_data
, encoding
);
2104 offset
+= 1; /* for charset */
2106 if (conn_data
->is_mariadb_client
){
2107 /* 19 bytes unused */
2108 proto_tree_add_item(login_tree
, hf_mysql_unused
, tvb
, offset
, 19, ENC_NA
);
2110 offset
= mariadb_dissect_caps_or_flags(tvb
, offset
, FT_UINT32
, login_tree
, hf_mariadb_extcaps_client
, mariadb_extcaps_flags
, &conn_data
->mariadb_client_ext_caps
);
2112 /* 23 bytes unused */
2113 proto_tree_add_item(login_tree
, hf_mysql_unused
, tvb
, offset
, 23, ENC_NA
);
2117 } else { /* pre-4.1 */
2118 proto_tree_add_item(login_tree
, hf_mysql_max_packet
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
2123 lenstr
= my_tvb_strsize(tvb
, offset
);
2124 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " user=%s ",
2125 tvb_format_text(pinfo
->pool
, tvb
, offset
, lenstr
-1));
2126 proto_tree_add_item(login_tree
, hf_mysql_user
, tvb
, offset
, lenstr
, ENC_ASCII
);
2129 /* rest is optional */
2130 if (!tvb_reported_length_remaining(tvb
, offset
)) {
2131 col_set_fence(pinfo
->cinfo
, COL_INFO
);
2135 /* password: asciiz or length+ascii */
2136 if (conn_data
->clnt_caps
& MYSQL_CAPS_SC
) {
2137 lenstr
= tvb_get_uint8(tvb
, offset
);
2140 lenstr
= my_tvb_strsize(tvb
, offset
);
2142 if (tree
&& lenstr
> 1) {
2143 proto_tree_add_item(login_tree
, hf_mysql_passwd
, tvb
, offset
, lenstr
, ENC_NA
);
2147 /* optional: initial schema */
2148 if (conn_data
->clnt_caps
& MYSQL_CAPS_CD
)
2150 lenstr
= my_tvb_strsize(tvb
,offset
);
2155 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "db=%s ",
2156 tvb_format_text(pinfo
->pool
, tvb
, offset
, lenstr
-1));
2157 col_set_fence(pinfo
->cinfo
, COL_INFO
);
2159 proto_tree_add_item(login_tree
, hf_mysql_schema
, tvb
, offset
, lenstr
, ENC_ASCII
);
2163 /* optional: authentication plugin */
2164 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_PA
)
2166 mysql_set_conn_state(pinfo
, conn_data
, AUTH_SWITCH_REQUEST
);
2167 lenstr
= my_tvb_strsize(tvb
,offset
);
2168 proto_tree_add_item(login_tree
, hf_mysql_client_auth_plugin
, tvb
, offset
, lenstr
, ENC_ASCII
);
2169 conn_data
->auth_method
= tvb_get_string_enc(wmem_file_scope(), tvb
, offset
, lenstr
, ENC_ASCII
);
2173 /* optional: connection attributes */
2174 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_CA
&& tvb_reported_length_remaining(tvb
, offset
))
2176 proto_tree
*connattrs_tree
;
2178 uint64_t connattrs_length
;
2181 lenfle
= tvb_get_fle(tvb
, login_tree
, offset
, &connattrs_length
, NULL
);
2182 tf
= proto_tree_add_item(login_tree
, hf_mysql_connattrs
, tvb
, offset
, (uint32_t)connattrs_length
, ENC_NA
);
2183 connattrs_tree
= proto_item_add_subtree(tf
, ett_connattrs
);
2184 proto_tree_add_uint64(connattrs_tree
, hf_mysql_connattrs_length
, tvb
, offset
, lenfle
, connattrs_length
);
2187 while (connattrs_length
> 0) {
2188 length
= add_connattrs_entry_to_tree(tvb
, pinfo
, connattrs_tree
, offset
);
2190 connattrs_length
-= length
;
2194 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_ZS
)
2196 proto_tree_add_item(login_tree
, hf_mysql_zstd_compression_level
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2203 mysql_dissect_exec_string(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int *param_offset
, proto_item
*field_tree
, unsigned encoding
)
2208 lenfle
= tvb_get_fle(tvb
, field_tree
, *param_offset
, ¶m_len
, NULL
);
2209 proto_tree_add_item(field_tree
, hf_mysql_exec_field_string_length
, tvb
, *param_offset
, lenfle
, ENC_ASCII
);
2210 *param_offset
+= lenfle
;
2212 if (encoding
== ENC_NA
) {
2213 proto_tree_add_item(field_tree
, hf_mysql_exec_field_blob
,
2214 tvb
, *param_offset
, (int)param_len
, ENC_NA
);
2216 proto_tree_add_item(field_tree
, hf_mysql_exec_field_string
,
2217 tvb
, *param_offset
, (int)param_len
, encoding
);
2219 *param_offset
+= (int)param_len
;
2223 mysql_dissect_exec_bit(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2228 lenfle
= tvb_get_fle(tvb
, field_tree
, *param_offset
, ¶m_len
, NULL
);
2229 proto_tree_add_item(field_tree
, hf_mysql_exec_field_bit_length
, tvb
, *param_offset
, lenfle
, ENC_ASCII
);
2230 *param_offset
+= lenfle
;
2232 proto_tree_add_item(field_tree
, hf_mysql_exec_field_bit
,
2233 tvb
, *param_offset
, (int)param_len
, ENC_NA
);
2234 *param_offset
+= (int)param_len
;
2238 mysql_dissect_exec_blob(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2243 lenfle
= tvb_get_fle(tvb
, field_tree
, *param_offset
, ¶m_len
, NULL
);
2244 proto_tree_add_item(field_tree
, hf_mysql_exec_field_blob_length
, tvb
, *param_offset
, lenfle
, ENC_ASCII
);
2245 *param_offset
+= lenfle
;
2247 proto_tree_add_item(field_tree
, hf_mysql_exec_field_blob
,
2248 tvb
, *param_offset
, (int)param_len
, ENC_NA
);
2249 *param_offset
+= (int)param_len
;
2253 mysql_dissect_exec_geometry(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2258 lenfle
= tvb_get_fle(tvb
, field_tree
, *param_offset
, ¶m_len
, NULL
);
2259 proto_tree_add_item(field_tree
, hf_mysql_exec_field_geometry_length
, tvb
, *param_offset
, lenfle
, ENC_ASCII
);
2260 *param_offset
+= lenfle
;
2262 proto_tree_add_item(field_tree
, hf_mysql_exec_field_geometry
,
2263 tvb
, *param_offset
, (int)param_len
, ENC_NA
);
2264 *param_offset
+= (int)param_len
;
2268 mysql_dissect_exec_json(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2270 static dissector_handle_t json_handle
;
2275 json_handle
= find_dissector("json");
2276 lenfle
= tvb_get_fle(tvb
, field_tree
, *param_offset
, ¶m_len
, NULL
);
2277 proto_tree_add_item(field_tree
, hf_mysql_exec_field_json_length
, tvb
, *param_offset
, lenfle
, ENC_ASCII
);
2278 *param_offset
+= lenfle
;
2280 next_tvb
= tvb_new_subset_length(tvb
, *param_offset
, (int)param_len
);
2281 call_dissector_only(json_handle
, next_tvb
, pinfo
, field_tree
, NULL
);
2282 *param_offset
+= (int)param_len
;
2286 mysql_dissect_exec_time(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2290 param_len
= tvb_get_uint8(tvb
, *param_offset
);
2291 proto_tree_add_item(field_tree
, hf_mysql_exec_field_time_length
, tvb
, *param_offset
, 1, ENC_NA
);
2293 if (param_len
>= 1) {
2294 proto_tree_add_item(field_tree
, hf_mysql_exec_field_time_sign
, tvb
, *param_offset
, 1, ENC_NA
);
2296 if (param_len
>= 5) {
2297 proto_tree_add_item(field_tree
, hf_mysql_exec_field_time_days
, tvb
, *param_offset
+ 1, 4, ENC_LITTLE_ENDIAN
);
2299 if (param_len
>= 8) {
2300 proto_tree_add_item(field_tree
, hf_mysql_exec_field_hour
, tvb
, *param_offset
+ 5, 1, ENC_NA
);
2301 proto_tree_add_item(field_tree
, hf_mysql_exec_field_minute
, tvb
, *param_offset
+ 6, 1, ENC_NA
);
2302 proto_tree_add_item(field_tree
, hf_mysql_exec_field_second
, tvb
, *param_offset
+ 7, 1, ENC_NA
);
2304 if (param_len
>= 12) {
2305 proto_tree_add_item(field_tree
, hf_mysql_exec_field_second_b
, tvb
, *param_offset
+ 8, 4, ENC_LITTLE_ENDIAN
);
2307 *param_offset
+= param_len
;
2311 mysql_dissect_exec_datetime(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2315 param_len
= tvb_get_uint8(tvb
, *param_offset
);
2316 proto_tree_add_item(field_tree
, hf_mysql_exec_field_datetime_length
, tvb
, *param_offset
, 1, ENC_NA
);
2318 if (param_len
>= 2) {
2319 proto_tree_add_item(field_tree
, hf_mysql_exec_field_year
, tvb
, *param_offset
, 2, ENC_LITTLE_ENDIAN
);
2321 if (param_len
>= 4) {
2322 proto_tree_add_item(field_tree
, hf_mysql_exec_field_month
, tvb
, *param_offset
+ 2, 1, ENC_NA
);
2323 proto_tree_add_item(field_tree
, hf_mysql_exec_field_day
, tvb
, *param_offset
+ 3, 1, ENC_NA
);
2325 if (param_len
>= 7) {
2326 proto_tree_add_item(field_tree
, hf_mysql_exec_field_hour
, tvb
, *param_offset
+ 4, 1, ENC_NA
);
2327 proto_tree_add_item(field_tree
, hf_mysql_exec_field_minute
, tvb
, *param_offset
+ 5, 1, ENC_NA
);
2328 proto_tree_add_item(field_tree
, hf_mysql_exec_field_second
, tvb
, *param_offset
+ 6, 1, ENC_NA
);
2330 if (param_len
>= 11) {
2331 proto_tree_add_item(field_tree
, hf_mysql_exec_field_second_b
, tvb
, *param_offset
+ 7, 4, ENC_LITTLE_ENDIAN
);
2333 *param_offset
+= param_len
;
2337 mysql_dissect_exec_primitive(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int *param_offset
, proto_item
*field_tree
, const int hfindex
, const int offset
)
2339 proto_tree_add_item(field_tree
, hfindex
, tvb
, *param_offset
, offset
, ENC_LITTLE_ENDIAN
);
2340 *param_offset
+= offset
;
2344 mysql_dissect_exec_tiny(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2346 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_tiny
, 1);
2350 mysql_dissect_exec_unsigned_tiny(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2352 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_unsigned_tiny
, 1);
2356 mysql_dissect_exec_short(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2358 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_short
, 2);
2362 mysql_dissect_exec_unsigned_short(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2364 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_unsigned_short
, 2);
2367 // Note that int24 is transferred in the binary protocol using 4 bytes, not 3.
2369 mysql_dissect_exec_int24(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2371 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_int24
, 4);
2375 mysql_dissect_exec_long(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2377 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_long
, 4);
2381 mysql_dissect_exec_unsigned_long(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2383 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_unsigned_long
, 4);
2387 mysql_dissect_exec_float(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2389 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_float
, 4);
2393 mysql_dissect_exec_double(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2395 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_double
, 8);
2399 mysql_dissect_exec_longlong(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2401 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_longlong
, 8);
2405 mysql_dissect_exec_unsigned_longlong(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2407 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_unsigned_longlong
, 8);
2411 mysql_dissect_exec_year(tvbuff_t
*tvb
, packet_info
*pinfo
, int *param_offset
, proto_item
*field_tree
, unsigned encoding _U_
)
2413 mysql_dissect_exec_primitive(tvb
, pinfo
, param_offset
, field_tree
, hf_mysql_exec_field_year
, 2);
2417 mysql_dissect_exec_null(tvbuff_t
*tvb _U_
, packet_info
*pinfo _U_
, int *param_offset _U_
, proto_item
*field_tree _U_
, unsigned encoding _U_
)
2421 mysql_dissect_exec_param(proto_item
*req_tree
, tvbuff_t
*tvb
, int *offset
,
2422 int *param_offset
, uint8_t param_flags
,
2423 packet_info
*pinfo
, unsigned encoding
, bool queryattrs
)
2425 uint8_t param_type
, param_unsigned
, lenfle
;
2426 uint64_t param_name_len
;
2428 proto_item
*field_tree
;
2429 int dissector_index
= 0;
2431 tf
= proto_tree_add_item(req_tree
, hf_mysql_exec_param
, tvb
, *offset
, 2, ENC_NA
);
2432 field_tree
= proto_item_add_subtree(tf
, ett_stat
);
2433 proto_tree_add_item(field_tree
, hf_mysql_fld_type
, tvb
, *offset
, 1, ENC_NA
);
2434 param_type
= tvb_get_uint8(tvb
, *offset
);
2435 *offset
+= 1; /* type */
2437 proto_tree_add_item(field_tree
, hf_mysql_exec_unsigned
, tvb
, *offset
, 1, ENC_NA
);
2438 if ((tvb_get_uint8(tvb
, *offset
) & 128) == 128) {
2443 *offset
+= 1; /* signedness */
2445 // Length-encoded parameter name if query attributes are enabled.
2447 lenfle
= tvb_get_fle(tvb
, field_tree
, *offset
, ¶m_name_len
, NULL
);
2449 if (param_name_len
>0) {
2450 proto_tree_add_item(field_tree
, hf_mysql_param_name
, tvb
, *offset
, (int)param_name_len
, ENC_ASCII
);
2451 *offset
+= (int)param_name_len
;
2455 if ((param_flags
& MYSQL_PARAM_FLAG_STREAMED
) == MYSQL_PARAM_FLAG_STREAMED
) {
2456 expert_add_info(pinfo
, field_tree
, &ei_mysql_streamed_param
);
2459 while (mysql_exec_dissectors
[dissector_index
].dissector
!= NULL
) {
2460 if (mysql_exec_dissectors
[dissector_index
].type
== param_type
&&
2461 mysql_exec_dissectors
[dissector_index
].unsigned_flag
== param_unsigned
) {
2462 mysql_exec_dissectors
[dissector_index
].dissector(tvb
, pinfo
, param_offset
, field_tree
, encoding
);
2470 /* Calculate param_offset if Query Attributes are used
2473 * <lenenc string> param_name
2476 mysql_exec_param_offset(tvbuff_t
*tvb
, proto_tree
*req_tree
, int offset
, int param_count
)
2479 uint64_t param_length
;
2481 for (int i
= 0; i
<param_count
; i
++) {
2483 tvb_ensure_bytes_exist(tvb
, offset
, 2);
2486 lenfle
= tvb_get_fle(tvb
, req_tree
, offset
, ¶m_length
, NULL
);
2489 tvb_ensure_bytes_exist(tvb
, offset
, (int)param_length
);
2490 offset
+= (int)param_length
;
2497 mysql_dissect_request(tvbuff_t
*tvb
,packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
, const mysql_frame_data_t
*my_frame_data
)
2501 proto_item
*request_item
, *tf
= NULL
, *ti
;
2502 proto_item
*req_tree
;
2504 my_stmt_data_t
*stmt_data
;
2505 int stmt_pos
, param_offset
;
2506 mysql_state_t current_state
= my_frame_data
->state
;
2508 /* LOCAL INFILE Request sends an empty packet after sending the file content
2509 * https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query_response_local_infile_request.html */
2510 if (tvb_reported_length_remaining(tvb
, offset
) == 0)
2513 switch(current_state
) {
2514 case AUTH_SWITCH_RESPONSE
:
2515 return mysql_dissect_auth_switch_response(tvb
, pinfo
, offset
, tree
, conn_data
);
2517 return mysql_dissect_auth_sha2(tvb
, pinfo
, offset
, tree
, conn_data
);
2519 return mysql_dissect_loaddata(tvb
, pinfo
, offset
, tree
, conn_data
);
2523 request_item
= proto_tree_add_item(tree
, hf_mysql_request
, tvb
, offset
, -1, ENC_NA
);
2524 req_tree
= proto_item_add_subtree(request_item
, ett_request
);
2526 opcode
= tvb_get_uint8(tvb
, offset
);
2527 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s", val_to_str_ext(opcode
, &mysql_command_vals_ext
, "Unknown (%u) "));
2529 proto_tree_add_item(req_tree
, hf_mysql_command
, tvb
, offset
, 1, ENC_NA
);
2530 proto_item_append_text(request_item
, " %s", val_to_str_ext(opcode
, &mysql_command_vals_ext
, "Unknown (%u)"));
2539 case MYSQL_PROCESS_INFO
:
2540 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_TABULAR
);
2541 mysql_set_resultset_fmt(pinfo
, conn_data
, TEXT
);
2546 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2549 case MYSQL_STATISTICS
:
2550 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_MESSAGE
);
2554 case MYSQL_CREATE_DB
:
2556 lenstr
= my_tvb_strsize(tvb
, offset
);
2557 proto_tree_add_item(req_tree
, hf_mysql_schema
, tvb
, offset
, lenstr
, ENC_ASCII
);
2559 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2563 /* Check both the extended capabilities of the client and server. The flag is set by the client
2564 * even if the server didn't set it. This is only actively used if both set the flag. */
2565 if ((conn_data
->clnt_caps_ext
& MYSQL_CAPS_QA
) && (conn_data
->srv_caps_ext
& MYSQL_CAPS_QA
)){
2566 proto_item
*query_attrs_item
= proto_tree_add_item(req_tree
, hf_mysql_query_attributes
, tvb
, offset
, -1, ENC_NA
);
2567 proto_item
*query_attrs_tree
= proto_item_add_subtree(query_attrs_item
, ett_query_attributes
);
2568 // XXX - https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query.html
2569 // suggests n_params is length encoded. Use tvb_get_fle?
2570 // (More than 250 parameters *does* seem unlikely.)
2571 int n_params
= tvb_get_uint8(tvb
, offset
);
2572 proto_tree_add_item(query_attrs_tree
, hf_mysql_query_attributes_count
, tvb
, offset
, 1, ENC_ASCII
);
2576 int null_count
= (n_params
+ 7) / 8;
2577 proto_tree_add_item(query_attrs_tree
, hf_mysql_unused
, tvb
, offset
, null_count
, ENC_ASCII
);
2578 offset
+= null_count
;
2580 proto_tree_add_item(query_attrs_tree
, hf_mysql_query_attributes_send_types_to_server
, tvb
, offset
, 1, ENC_ASCII
);
2583 unsigned encoding
= my_frame_data
->encoding_client
;
2585 for (int i
= 0; i
< n_params
; ++i
) {
2586 proto_tree_add_item(query_attrs_tree
, hf_mysql_query_attribute_name_type
, tvb
, offset
, 2, ENC_ASCII
);
2588 offset
= mysql_field_add_lestring(tvb
, offset
, query_attrs_tree
, hf_mysql_query_attribute_name
, encoding
);
2590 for (int i
= 0; i
< n_params
; ++i
) {
2591 offset
= mysql_field_add_lestring(tvb
, offset
, query_attrs_tree
, hf_mysql_query_attribute_value
, encoding
);
2595 // The SQL statement is a string<EOF>, because it can
2596 // contain embedded NUL bytes.
2597 // However, we check for a edge case.
2598 lenstr
= my_tvb_strsize(tvb
, offset
);
2599 // A query string of less than 2 doesn't make sense, this is *likely* to be a case where
2600 // we don't have the capability flags from the login/greeting and are missing MYSQL_CAPS_QA
2601 // Note that MYSQL_CAPS_QA is only used on recent MySQL and only if both the client and server
2602 // set it, so assuming this is set when we don't have the login/greeting will break many other
2605 // If this is the case we skip 2 bytes and try again.
2606 // XXX - This only catches the case when the parameter count is
2607 // 0. A more complicated heuristic would involve retrieving the
2608 // string from the entire packet according to our chosen encoding,
2609 // verifying if it consists entirely of printable characters, and
2610 // if not, verify if the string would be printable if we assumed
2611 // that query attributes were present, or perhaps checking that
2612 // the interpretation of the next several bytes as parameter_count
2613 // and parameter_set_count is reasonable.
2617 lenstr
= tvb_reported_length_remaining(tvb
, offset
);
2618 proto_tree_add_item(req_tree
, hf_mysql_query
, tvb
, offset
, lenstr
, my_frame_data
->encoding_client
);
2619 if (mysql_showquery
) {
2620 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " { %s } ",
2621 tvb_format_text(pinfo
->pool
, tvb
, offset
, lenstr
));
2622 col_set_fence(pinfo
->cinfo
, COL_INFO
);
2625 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_TABULAR
);
2626 mysql_set_resultset_fmt(pinfo
, conn_data
, TEXT
);
2629 case MYSQL_STMT_PREPARE
:
2630 // The SQL Statement is a string<EOF>; it can have embedded NUL bytes.
2631 lenstr
= tvb_reported_length_remaining(tvb
, offset
);
2632 proto_tree_add_item(req_tree
, hf_mysql_query
, tvb
, offset
, lenstr
, ENC_ASCII
);
2634 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_PREPARE
);
2637 case MYSQL_STMT_CLOSE
:
2638 proto_tree_add_item(req_tree
, hf_mysql_stmt_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2640 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
2643 case MYSQL_STMT_RESET
:
2644 proto_tree_add_item(req_tree
, hf_mysql_stmt_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2646 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2649 case MYSQL_FIELD_LIST
:
2650 lenstr
= my_tvb_strsize(tvb
, offset
);
2651 proto_tree_add_item(req_tree
, hf_mysql_table_name
, tvb
, offset
, lenstr
, ENC_ASCII
);
2653 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_SHOW_FIELDS
);
2656 case MYSQL_PROCESS_KILL
:
2657 proto_tree_add_item(req_tree
, hf_mysql_thread_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2659 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2662 case MYSQL_CHANGE_USER
:
2663 lenstr
= tvb_strsize(tvb
, offset
);
2664 proto_tree_add_item(req_tree
, hf_mysql_user
, tvb
, offset
, lenstr
, ENC_ASCII
);
2667 if (conn_data
->clnt_caps
& MYSQL_CAPS_SC
) {
2668 lenstr
= tvb_get_uint8(tvb
, offset
);
2671 lenstr
= tvb_strsize(tvb
, offset
);
2673 proto_tree_add_item(req_tree
, hf_mysql_passwd
, tvb
, offset
, lenstr
, ENC_NA
);
2676 lenstr
= my_tvb_strsize(tvb
, offset
);
2677 proto_tree_add_item(req_tree
, hf_mysql_schema
, tvb
, offset
, lenstr
, ENC_ASCII
);
2680 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
2682 proto_tree_add_item_ret_uint(req_tree
, conn_data
->is_mariadb_server
? hf_mariadb_collation
: hf_mysql_collation
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &collation
);
2683 unsigned encoding
= collation_to_encoding(collation
, conn_data
->is_mariadb_server
);
2684 mysql_set_encoding_client(pinfo
, conn_data
, encoding
);
2685 mysql_set_encoding_results(pinfo
, conn_data
, encoding
);
2686 offset
+= 2; /* for charset */
2688 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2690 /* optional: authentication plugin */
2691 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_PA
)
2693 mysql_set_conn_state(pinfo
, conn_data
, AUTH_SWITCH_REQUEST
);
2694 lenstr
= my_tvb_strsize(tvb
,offset
);
2695 proto_tree_add_item(req_tree
, hf_mysql_client_auth_plugin
, tvb
, offset
, lenstr
, ENC_ASCII
);
2699 /* optional: connection attributes */
2700 if ((conn_data
->clnt_caps_ext
& MYSQL_CAPS_CA
) && (tvb_reported_length_remaining(tvb
, offset
) > 0))
2702 proto_tree
*connattrs_tree
;
2704 uint64_t connattrs_length
;
2707 lenfle
= tvb_get_fle(tvb
, req_tree
, offset
, &connattrs_length
, NULL
);
2708 tf
= proto_tree_add_item(req_tree
, hf_mysql_connattrs
, tvb
, offset
, (uint32_t)connattrs_length
, ENC_NA
);
2709 connattrs_tree
= proto_item_add_subtree(tf
, ett_connattrs
);
2710 proto_tree_add_uint64(connattrs_tree
, hf_mysql_connattrs_length
, tvb
, offset
, lenfle
, connattrs_length
);
2713 while (connattrs_length
> 0) {
2714 length
= add_connattrs_entry_to_tree(tvb
, pinfo
, connattrs_tree
, offset
);
2716 connattrs_length
-= length
;
2722 proto_tree_add_bitmask_with_flags(req_tree
, tvb
, offset
,
2723 hf_mysql_refresh
, ett_refresh
, mysql_rfsh_flags
,
2724 ENC_BIG_ENDIAN
, BMT_NO_APPEND
);
2726 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2729 case MYSQL_SHUTDOWN
:
2730 proto_tree_add_item(req_tree
, hf_mysql_shutdown
, tvb
, offset
, 1, ENC_NA
);
2732 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2735 case MYSQL_SET_OPTION
:
2736 proto_tree_add_item(req_tree
, hf_mysql_option
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2738 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_OK
);
2741 case MYSQL_STMT_FETCH
:
2742 proto_tree_add_item(req_tree
, hf_mysql_stmt_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2745 proto_tree_add_item(req_tree
, hf_mysql_num_rows
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2747 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_TABULAR
);
2748 mysql_set_resultset_fmt(pinfo
, conn_data
, BINARY
);
2751 case MYSQL_STMT_SEND_LONG_DATA
:
2752 proto_tree_add_item(req_tree
, hf_mysql_stmt_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2753 stmt_id
= tvb_get_letohl(tvb
, offset
);
2756 stmt_data
= (my_stmt_data_t
*)wmem_tree_lookup32(conn_data
->stmts
, stmt_id
);
2757 if (stmt_data
!= NULL
) {
2758 uint16_t data_param
= tvb_get_letohs(tvb
, offset
);
2759 if (stmt_data
->param_metas
.count
> data_param
) {
2760 stmt_data
->param_metas
.flags
[data_param
] |= MYSQL_PARAM_FLAG_STREAMED
;
2764 proto_tree_add_item(req_tree
, hf_mysql_param
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2768 lenstr
= tvb_reported_length_remaining(tvb
, offset
);
2769 if (tree
&& lenstr
> 0) {
2770 proto_tree_add_item(req_tree
, hf_mysql_payload
, tvb
, offset
, lenstr
, ENC_NA
);
2773 if (current_state
!= RESPONSE_PREPARE
) {
2774 // if pipelining, keeping PREPARE state
2775 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
2779 case MARIADB_STMT_BULK_EXECUTE
:
2780 proto_tree_add_item(req_tree
, hf_mysql_stmt_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2781 stmt_id
= tvb_get_letohl(tvb
, offset
);
2784 // use last prepared statement
2785 if (stmt_id
== 0xffffffff) {
2786 stmt_id
= my_frame_data
->stmt_id
;
2789 stmt_data
= (my_stmt_data_t
*)wmem_tree_lookup32(conn_data
->stmts
, stmt_id
);
2791 if (stmt_data
!= NULL
) {
2792 uint32_t row_nr
= 1;
2793 proto_item
*param_tree
;
2795 mariadb_dissect_caps_or_flags(tvb
, offset
, FT_UINT16
, req_tree
, hf_mariadb_bulk_caps_flags
, mariadb_bulk_caps_flags
, &stmt_data
->bulk_flags
);
2798 if ((stmt_data
->bulk_flags
& MARIADB_BULK_SEND_TYPES
) && stmt_data
->param_metas
.count
)
2800 tf
= proto_tree_add_item(req_tree
, hf_mariadb_bulk_paramtypes
, tvb
, offset
, -1, ENC_NA
);
2801 param_tree
= proto_item_add_subtree(tf
, ett_exec_param
);
2802 for (stmt_pos
= 0; stmt_pos
< stmt_data
->param_metas
.count
; stmt_pos
++) {
2803 stmt_data
->param_metas
.types
[stmt_pos
] = tvb_get_uint8(tvb
, offset
);
2804 proto_tree_add_item(param_tree
, hf_mysql_fld_type
, tvb
, offset
, 1, ENC_NA
);
2806 stmt_data
->param_metas
.flags
[stmt_pos
] = tvb_get_uint8(tvb
, offset
);
2807 proto_tree_add_item(param_tree
, hf_mysql_exec_unsigned
, tvb
, offset
, 1, ENC_NA
);
2811 while (tvb_reported_length_remaining(tvb
, offset
) > 0){
2812 tf
= proto_tree_add_uint_format(req_tree
, hf_mariadb_bulk_row_nr
, tvb
, offset
, 0, row_nr
, "%d. Dataset", row_nr
);
2813 proto_item_set_generated(tf
);
2814 param_tree
= proto_item_add_subtree(tf
, ett_bulk_param
);
2816 for (stmt_pos
= 0; stmt_pos
< stmt_data
->param_metas
.count
; stmt_pos
++)
2818 uint8_t indicator
= tvb_get_uint8(tvb
, offset
);
2819 proto_tree_add_item(param_tree
, hf_mariadb_bulk_indicator
, tvb
, offset
, 1, ENC_NA
);
2821 /* If no indicator was specified, data will follow */
2823 int dissector_index
= 0;
2824 while (mysql_exec_dissectors
[dissector_index
].dissector
!= NULL
) {
2825 if (mysql_exec_dissectors
[dissector_index
].type
== stmt_data
->param_metas
.types
[stmt_pos
])
2827 mysql_exec_dissectors[dissector_index].unsigned_flag == stmt_data->param_flags[stmt_pos]) */
2829 mysql_exec_dissectors
[dissector_index
].dissector(tvb
, pinfo
, &offset
, param_tree
, stmt_data
->param_metas
.encodings
[stmt_pos
]);
2839 if (current_state
!= RESPONSE_PREPARE
) {
2840 // if pipelining, keeping PREPARE state
2841 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
2846 case MYSQL_STMT_EXECUTE
:
2847 // https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_stmt_execute.html
2848 proto_tree_add_item(req_tree
, hf_mysql_stmt_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2849 stmt_id
= tvb_get_letohl(tvb
, offset
);
2852 if (conn_data
->major_version
>= 5) {
2853 proto_tree_add_item(req_tree
, hf_mysql_exec_flags5
, tvb
, offset
, 1, ENC_NA
);
2855 proto_tree_add_item(req_tree
, hf_mysql_exec_flags4
, tvb
, offset
, 1, ENC_NA
);
2857 uint8_t exec_flags
= tvb_get_uint8(tvb
, offset
);
2860 proto_tree_add_item(req_tree
, hf_mysql_exec_iter
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2863 // use last prepared statement
2864 if (stmt_id
== 0xffffffff) {
2865 stmt_id
= my_frame_data
->stmt_id
;
2867 stmt_data
= (my_stmt_data_t
*)wmem_tree_lookup32(conn_data
->stmts
, stmt_id
);
2868 if (stmt_data
!= NULL
) {
2869 uint64_t param_count
= stmt_data
->param_metas
.count
;
2870 if ((conn_data
->clnt_caps_ext
& MYSQL_CAPS_QA
)
2871 && (exec_flags
& MYSQL_PARAMETER_COUNT_AVAILABLE
)) {
2872 uint8_t lenfle
= tvb_get_fle(tvb
, req_tree
, offset
, ¶m_count
, NULL
);
2873 proto_tree_add_uint64(req_tree
, hf_mysql_num_params
, tvb
, offset
, lenfle
, param_count
);
2876 if (param_count
!= 0) {
2878 int null_bitmap_length
;
2880 null_bitmap_length
= (int)((param_count
+ 7) / 8);
2881 tvb_ensure_bytes_exist(tvb
, offset
, null_bitmap_length
);
2882 offset
+= null_bitmap_length
;
2883 proto_tree_add_item(req_tree
, hf_mysql_new_parameter_bound_flag
, tvb
, offset
, 1, ENC_NA
);
2884 stmt_bound
= tvb_get_uint8(tvb
, offset
);
2886 if (stmt_bound
== 1) {
2887 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_QA
) {
2888 param_offset
= mysql_exec_param_offset(tvb
, req_tree
, offset
, (unsigned)param_count
);
2890 param_offset
= offset
+ (unsigned)param_count
* 2;
2893 /* The character set for a parameter
2894 * is character_set_client. */
2895 unsigned encoding
= my_frame_data
->encoding_client
;
2896 for (stmt_pos
= 0; stmt_pos
< (int)param_count
; stmt_pos
++) {
2897 if (stmt_pos
>= stmt_data
->param_metas
.count
) {
2898 // With Query Attributes we can have more params than during the prepare.
2899 // this means we don't have flags for them.
2902 flags
= (uint8_t)stmt_data
->param_metas
.flags
[stmt_pos
];
2904 if (!mysql_dissect_exec_param(req_tree
, tvb
, &offset
, ¶m_offset
,
2905 flags
, pinfo
, encoding
,
2906 conn_data
->clnt_caps_ext
& MYSQL_CAPS_QA
))
2909 offset
= param_offset
;
2913 lenstr
= tvb_reported_length_remaining(tvb
, offset
);
2914 if (tree
&& lenstr
> 0) {
2915 ti
= proto_tree_add_item(req_tree
, hf_mysql_payload
, tvb
, offset
, lenstr
, ENC_NA
);
2916 expert_add_info(pinfo
, ti
, &ei_mysql_prepare_response_needed
);
2921 if (current_state
!= RESPONSE_PREPARE
) {
2922 // if pipelining, keeping PREPARE state
2923 mysql_set_conn_state(pinfo
, conn_data
, RESPONSE_TABULAR
);
2925 mysql_set_resultset_fmt(pinfo
, conn_data
, BINARY
);
2929 case MYSQL_BINLOG_DUMP_GTID
:
2930 // See mysql_binlog_open() in "sql-common/client.cc"
2932 proto_tree_add_item(req_tree
, hf_mysql_binlog_flags
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2935 proto_tree_add_item(req_tree
, hf_mysql_binlog_server_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2938 lenstr
= tvb_get_uint32(tvb
, offset
, ENC_LITTLE_ENDIAN
);
2939 proto_tree_add_item(req_tree
, hf_mysql_binlog_file_name_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2942 if (tree
&& lenstr
> 0) {
2943 proto_tree_add_item(req_tree
, hf_mysql_binlog_file_name
, tvb
, offset
, lenstr
, ENC_ASCII
);
2947 proto_tree_add_item(req_tree
, hf_mysql_binlog_position8
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
2950 lenstr
= tvb_get_uint32(tvb
, offset
, ENC_LITTLE_ENDIAN
);
2951 proto_tree_add_item(req_tree
, hf_mysql_binlog_gtid_data_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2954 proto_tree_add_item(req_tree
, hf_mysql_binlog_gtid_data
, tvb
, offset
, lenstr
, ENC_ASCII
);
2957 mysql_set_conn_state(pinfo
, conn_data
, BINLOG_DUMP
);
2959 case MYSQL_BINLOG_DUMP
:
2960 proto_tree_add_item(req_tree
, hf_mysql_binlog_position
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2963 proto_tree_add_item(req_tree
, hf_mysql_binlog_flags
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2966 proto_tree_add_item(req_tree
, hf_mysql_binlog_server_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2969 /* binlog file name ? */
2970 lenstr
= tvb_reported_length_remaining(tvb
, offset
);
2971 if (tree
&& lenstr
> 0) {
2972 proto_tree_add_item(req_tree
, hf_mysql_binlog_file_name
, tvb
, offset
, lenstr
, ENC_ASCII
);
2976 mysql_set_conn_state(pinfo
, conn_data
, BINLOG_DUMP
);
2979 case MYSQL_REGISTER_SLAVE
:
2980 proto_tree_add_item(req_tree
, hf_mysql_binlog_server_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2983 lenstr
= tvb_get_uint8(tvb
, offset
);
2984 proto_tree_add_item(req_tree
, hf_mysql_binlog_slave_hostname_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2987 proto_tree_add_item(req_tree
, hf_mysql_binlog_slave_hostname
, tvb
, offset
, lenstr
, ENC_ASCII
);
2990 lenstr
= tvb_get_uint8(tvb
, offset
);
2991 proto_tree_add_item(req_tree
, hf_mysql_binlog_slave_user_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2994 proto_tree_add_item(req_tree
, hf_mysql_binlog_slave_user
, tvb
, offset
, lenstr
, ENC_ASCII
);
2997 lenstr
= tvb_get_uint8(tvb
, offset
);
2998 proto_tree_add_item(req_tree
, hf_mysql_binlog_slave_password_length
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3001 proto_tree_add_item(req_tree
, hf_mysql_binlog_slave_password
, tvb
, offset
, lenstr
, ENC_ASCII
);
3004 proto_tree_add_item(req_tree
, hf_mysql_binlog_slave_mysql_port
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3007 proto_tree_add_item(req_tree
, hf_mysql_binlog_replication_rank
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
3010 proto_tree_add_item(req_tree
, hf_mysql_binlog_master_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
3013 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3016 /* FIXME: implement replication packets */
3017 case MYSQL_TABLE_DUMP
:
3018 case MYSQL_CONNECT_OUT
:
3019 ti
= proto_tree_add_item(req_tree
, hf_mysql_payload
, tvb
, offset
, -1, ENC_NA
);
3020 expert_add_info_format(pinfo
, ti
, &ei_mysql_dissector_incomplete
, "FIXME: implement replication packets");
3021 offset
+= tvb_reported_length_remaining(tvb
, offset
);
3022 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3026 mysql_set_conn_state(pinfo
, conn_data
, CLONE_INIT
);
3029 case MYSQL_RESET_CONNECTION
:
3033 ti
= proto_tree_add_item(req_tree
, hf_mysql_payload
, tvb
, offset
, -1, ENC_NA
);
3034 expert_add_info(pinfo
, ti
, &ei_mysql_command
);
3035 offset
+= tvb_reported_length_remaining(tvb
, offset
);
3036 mysql_set_conn_state(pinfo
, conn_data
, UNDEFINED
);
3039 proto_item_set_end(request_item
, tvb
, offset
);
3044 mysql_dissect_response(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
3045 proto_tree
*tree
, mysql_conn_data_t
*conn_data
, proto_item
*pi
, const mysql_frame_data_t
*my_frame_data
)
3051 mysql_state_t current_state
= my_frame_data
->state
;
3052 my_stmt_data_t
*stmt_data
= NULL
;
3053 if (my_frame_data
->stmt_id
) {
3054 stmt_data
= (my_stmt_data_t
*)wmem_tree_lookup32(conn_data
->stmts
, my_frame_data
->stmt_id
);
3057 response_code
= tvb_get_uint8(tvb
, offset
);
3058 switch (response_code
) {
3060 proto_tree_add_item(tree
, hf_mysql_response_code
, tvb
, offset
, 1, ENC_NA
);
3061 proto_item_append_text(pi
, " - %s", val_to_str(RESPONSE_ERROR
, state_vals
, "Unknown (%u)"));
3062 offset
= mysql_dissect_error_packet(tvb
, pinfo
, offset
+1, tree
, my_frame_data
);
3063 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3066 proto_tree_add_item(tree
, hf_mysql_response_code
, tvb
, offset
, 1, ENC_NA
);
3067 proto_tree_add_item(tree
, hf_mysql_eof
, tvb
, offset
, 1, ENC_NA
);
3070 if (tvb_reported_length_remaining(tvb
, offset
) <= 5) {
3072 offset
= mysql_dissect_eof(tvb
, pinfo
, pi
, offset
, tree
, conn_data
);
3074 if (current_state
== PREPARED_PARAMETERS
) {
3075 if (stmt_data
!= NULL
&& stmt_data
->field_metas
.count
> 0) {
3076 proto_item_append_text(pi
, " - %s", val_to_str(INTERMEDIATE_EOF
, state_vals
, "Unknown (%u)"));
3077 mysql_set_remaining_field_packet_count(pinfo
, conn_data
, stmt_data
->field_metas
.count
);
3078 mysql_set_conn_state(pinfo
, conn_data
, PREPARED_FIELDS
);
3080 proto_item_append_text(pi
, " - %s", val_to_str(RESPONSE_EOF
, state_vals
, "Unknown (%u)"));
3081 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3083 } else if (current_state
== FIELD_PACKET
) {
3084 // intermediate EOF packet
3085 proto_item_append_text(pi
, " - %s", val_to_str(INTERMEDIATE_EOF
, state_vals
, "Unknown (%u)"));
3086 mysql_set_conn_state(pinfo
, conn_data
, ROW_PACKET
);
3088 // ending EOF packet
3089 proto_item_append_text(pi
, " - %s", val_to_str(RESPONSE_EOF
, state_vals
, "Unknown (%u)"));
3090 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3092 } else if (tvb_reported_length_remaining(tvb
, offset
) < 0xffffff) {
3094 if (current_state
== AUTH_SWITCH_REQUEST
) {
3095 proto_item_append_text(pi
, " - %s", val_to_str(AUTH_SWITCH_REQUEST
, state_vals
, "Unknown (%u)"));
3096 offset
= mysql_dissect_auth_switch_request(tvb
, pinfo
, offset
, tree
, conn_data
);
3098 proto_item_append_text(pi
, " - %s", val_to_str(RESPONSE_OK
, state_vals
, "Unknown (%u)"));
3099 offset
= mysql_dissect_ok_packet(tvb
, pinfo
, offset
, tree
, conn_data
);
3100 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3104 proto_item_append_text(pi
, " - %s", val_to_str(ROW_PACKET
, state_vals
, "Unknown (%u)"));
3105 mysql_set_conn_state(pinfo
, conn_data
, ROW_PACKET
);
3106 offset
= mysql_dissect_text_row_packet(tvb
, offset
, tree
, my_frame_data
);
3111 switch (current_state
) {
3112 case RESPONSE_PREPARE
:
3113 proto_tree_add_item(tree
, hf_mysql_response_code
, tvb
, offset
, 1, ENC_NA
);
3115 proto_item_append_text(pi
, " - %s", val_to_str(RESPONSE_PREPARE
, state_vals
, "Unknown (%u)"));
3116 offset
= mysql_dissect_response_prepare(tvb
, pinfo
, offset
, tree
, conn_data
);
3119 proto_item_append_text(pi
, " - %s", val_to_str(ROW_PACKET
, state_vals
, "Unknown (%u)"));
3120 if (my_frame_data
->resultset_fmt
== BINARY
) {
3121 proto_tree_add_item(tree
, hf_mysql_response_code
, tvb
, offset
, 1, ENC_NA
);
3123 offset
= mysql_dissect_binary_row_packet(tvb
, pinfo
, pi
, offset
, tree
, conn_data
, my_frame_data
);
3125 offset
= mysql_dissect_text_row_packet(tvb
, offset
, tree
, my_frame_data
);
3129 proto_tree_add_item(tree
, hf_mysql_response_code
, tvb
, offset
, 1, ENC_NA
);
3131 proto_item_append_text(pi
, " - %s", val_to_str(BINLOG_DUMP
, state_vals
, "Unknown (%u)"));
3132 offset
= mysql_dissect_binlog_event_packet(tvb
, pinfo
, offset
, tree
, pi
);
3135 proto_tree_add_item(tree
, hf_mysql_response_code
, tvb
, offset
, 1, ENC_NA
);
3137 proto_item_append_text(pi
, " - %s", val_to_str(RESPONSE_OK
, state_vals
, "Unknown (%u)"));
3138 offset
= mysql_dissect_ok_packet(tvb
, pinfo
, offset
, tree
, conn_data
);
3139 if (conn_data
->compressed_state
== MYSQL_COMPRESS_INIT
) {
3140 /* This is the OK packet which follows the compressed protocol setup */
3141 conn_data
->compressed_state
= MYSQL_COMPRESS_ACTIVE
;
3143 if (current_state
== CLONE_INIT
)
3144 mysql_set_conn_state(pinfo
, conn_data
, CLONE_ACTIVE
);
3149 switch (current_state
) {
3150 case RESPONSE_MESSAGE
:
3151 if ((lenstr
= tvb_reported_length_remaining(tvb
, offset
))) {
3152 proto_tree_add_item(tree
, hf_mysql_message
, tvb
, offset
, lenstr
, ENC_ASCII
);
3155 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3158 case RESPONSE_TABULAR
:
3159 case REQUEST
: /* That shouldn't be the case; maybe two requests in a row (s. bug 15074), or after pipelining */
3160 if (response_code
== 0xfb) {
3161 /* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query_response_local_infile_request.html */
3162 col_append_str(pinfo
->cinfo
, COL_INFO
, " LOCAL INFILE");
3163 proto_tree_add_item(tree
, hf_mysql_response_code
, tvb
, offset
, 1, ENC_NA
);
3164 proto_item_append_text(pi
, " - %s", val_to_str(RESPONSE_LOCALINFILE
, state_vals
, "Unknown (%u)"));
3166 lenstr
= tvb_reported_length_remaining(tvb
, ++offset
);
3167 proto_tree_add_item(tree
, hf_mysql_loaddata_filename
, tvb
, offset
, lenstr
, ENC_ASCII
);
3169 mysql_set_conn_state(pinfo
, conn_data
, INFILE_DATA
);
3172 proto_item_append_text(pi
, " - %s", val_to_str(COLUMN_COUNT
, state_vals
, "Unknown (%u)"));
3173 offset
= mysql_dissect_result_header(tvb
, pinfo
, offset
, tree
, conn_data
, my_frame_data
);
3175 case PREPARED_PARAMETERS
:
3176 proto_item_append_text(pi
, " - %s", val_to_str(current_state
, state_vals
, "Unknown (%u)"));
3177 offset
= mysql_dissect_field_packet(tvb
, pi
, offset
, tree
, pinfo
, conn_data
, my_frame_data
);
3178 if (mysql_dec_remaining_field_packet_count(pinfo
, conn_data
)) {
3179 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_DE
) {
3180 if (stmt_data
!= NULL
&& stmt_data
->field_metas
.count
> 0) {
3181 mysql_set_remaining_field_packet_count(pinfo
, conn_data
, stmt_data
->field_metas
.count
);
3182 mysql_set_conn_state(pinfo
, conn_data
, PREPARED_FIELDS
);
3184 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3191 case RESPONSE_SHOW_FIELDS
:
3192 proto_item_append_text(pi
, " - %s", val_to_str(current_state
, state_vals
, "Unknown (%u)"));
3193 offset
= mysql_dissect_field_packet(tvb
, pi
, offset
, tree
, pinfo
, conn_data
, my_frame_data
);
3194 if (mysql_dec_remaining_field_packet_count(pinfo
, conn_data
) && (conn_data
->clnt_caps_ext
& MYSQL_CAPS_DE
)) {
3195 mysql_set_conn_state(pinfo
, conn_data
, ROW_PACKET
);
3200 proto_item_append_text(pi
, " - %s", val_to_str(current_state
, state_vals
, "Unknown (%u)"));
3201 offset
= mysql_dissect_text_row_packet(tvb
, offset
, tree
, my_frame_data
);
3204 case PREPARED_FIELDS
:
3205 proto_item_append_text(pi
, " - %s", val_to_str(current_state
, state_vals
, "Unknown (%u)"));
3206 offset
= mysql_dissect_field_packet(tvb
, pi
, offset
, tree
, pinfo
, conn_data
, my_frame_data
);
3207 if (mysql_dec_remaining_field_packet_count(pinfo
, conn_data
) && (conn_data
->clnt_caps_ext
& MYSQL_CAPS_DE
)) {
3208 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3212 case AUTH_SWITCH_REQUEST
:
3213 if (tvb_reported_length_remaining(tvb
,offset
) == 2) {
3214 proto_item_append_text(pi
, " - %s", val_to_str(AUTH_SHA2
, state_vals
, "Unknown (%u)"));
3215 offset
= mysql_dissect_auth_sha2(tvb
, pinfo
, offset
, tree
, conn_data
);
3217 proto_item_append_text(pi
, " - %s", val_to_str(AUTH_SWITCH_REQUEST
, state_vals
, "Unknown (%u)"));
3218 offset
= mysql_dissect_auth_switch_request(tvb
, pinfo
, offset
, tree
, conn_data
);
3223 proto_item_append_text(pi
, " - %s", val_to_str(AUTH_SHA2
, state_vals
, "Unknown (%u)"));
3224 offset
= mysql_dissect_auth_sha2(tvb
, pinfo
, offset
, tree
, conn_data
);
3228 ti
= proto_tree_add_item(tree
, hf_mysql_payload
, tvb
, offset
, -1, ENC_NA
);
3229 expert_add_info(pinfo
, ti
, &ei_mysql_unknown_response
);
3230 offset
+= tvb_reported_length_remaining(tvb
, offset
);
3231 mysql_set_conn_state(pinfo
, conn_data
, UNDEFINED
);
3240 mysql_dissect_error_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
3241 int offset
, proto_tree
*tree
,
3242 const mysql_frame_data_t
*my_frame_data
)
3244 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Error %d ", tvb_get_letohs(tvb
, offset
));
3245 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3247 proto_tree_add_item(tree
, hf_mysql_error_code
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3250 if (tvb_get_uint8(tvb
, offset
) == '#')
3253 proto_tree_add_item(tree
, hf_mysql_sqlstate
, tvb
, offset
, 5, ENC_ASCII
);
3257 proto_tree_add_item(tree
, hf_mysql_error_string
, tvb
, offset
, -1, my_frame_data
->encoding_results
);
3258 offset
+= tvb_reported_length_remaining(tvb
, offset
);
3264 Add a session track entry to the session tracking subtree
3269 add_session_tracker_entry_to_tree(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_item
*tree
, int offset
, mysql_conn_data_t
*conn_data
) {
3270 uint8_t data_type
; /* session tracker type */
3271 uint64_t length
; /* complete length of session tracking entry */
3273 int orig_offset
= offset
, lenfle
;
3274 proto_item
*item
, *ti
;
3275 proto_tree
*session_track_tree
;
3276 const uint8_t *sysvar_value
;
3277 bool charset_client
= false, charset_results
= false;
3279 ti
= proto_tree_add_item(tree
, hf_mysql_session_track
, tvb
, offset
, 1, ENC_NA
);
3280 session_track_tree
= proto_item_add_subtree(ti
, ett_session_track
);
3282 proto_tree_add_item(session_track_tree
, hf_mysql_session_track_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3283 data_type
= tvb_get_uint8(tvb
, offset
);
3286 lenfle
= tvb_get_fle(tvb
, session_track_tree
, offset
, &length
, NULL
);
3287 proto_tree_add_uint64(session_track_tree
, hf_mysql_session_track_length
, tvb
, offset
, lenfle
, length
);
3290 switch (data_type
) {
3291 case 0: /* SESSION_SYSVARS_TRACKER */
3292 lenfle
= tvb_get_fle(tvb
, session_track_tree
, offset
, &lenstr
, NULL
);
3293 proto_tree_add_uint64(session_track_tree
, hf_mysql_session_track_sysvar_length
, tvb
, offset
, lenfle
, lenstr
);
3296 proto_tree_add_item(session_track_tree
, hf_mysql_session_track_sysvar_name
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3297 if (tvb_strneql(tvb
, offset
, "character_set_client", lenstr
) == 0) {
3298 charset_client
= true;
3299 } else if (tvb_strneql(tvb
, offset
, "character_set_results", lenstr
) == 0) {
3300 charset_results
= true;
3302 offset
+= (int)lenstr
;
3304 lenfle
= tvb_get_fle(tvb
, session_track_tree
, offset
, &lenstr
, NULL
);
3305 proto_tree_add_uint64(session_track_tree
, hf_mysql_session_track_sysvar_length
, tvb
, offset
, lenfle
, lenstr
);
3308 proto_tree_add_item_ret_string(session_track_tree
, hf_mysql_session_track_sysvar_value
, tvb
, offset
, (int)lenstr
, ENC_ASCII
, pinfo
->pool
, &sysvar_value
);
3309 if (charset_client
) {
3310 mysql_set_encoding_client(pinfo
, conn_data
, charset_to_encoding(sysvar_value
));
3311 } else if (charset_results
) {
3312 mysql_set_encoding_results(pinfo
, conn_data
, charset_to_encoding(sysvar_value
));
3314 offset
+= (int)lenstr
;
3316 case 1: /* CURRENT_SCHEMA_TRACKER */
3317 lenfle
= tvb_get_fle(tvb
, session_track_tree
, offset
, &lenstr
, NULL
);
3318 proto_tree_add_uint64(session_track_tree
, hf_mysql_session_track_schema_length
, tvb
, offset
, lenfle
, lenstr
);
3321 proto_tree_add_item(session_track_tree
, hf_mysql_session_track_schema
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3322 offset
+= (int)lenstr
;
3324 case 2: /* SESSION_STATE_CHANGE_TRACKER */
3325 proto_tree_add_item(session_track_tree
, hf_mysql_session_state_change
, tvb
, offset
, 1, ENC_ASCII
);
3328 case 3: /* SESSION_TRACK_GTIDS */
3329 proto_tree_add_item(session_track_tree
, hf_mysql_session_track_gtids_encoding
, tvb
, offset
, 1, ENC_NA
);
3331 lenfle
= tvb_get_fle(tvb
, session_track_tree
, offset
, &lenstr
, NULL
);
3332 proto_tree_add_uint64(session_track_tree
, hf_mysql_session_track_gtids_length
, tvb
, offset
, lenfle
, lenstr
);
3335 proto_tree_add_item(session_track_tree
, hf_mysql_session_track_gtids
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3336 offset
+= (int)lenstr
;
3338 case 4: /* SESSION_TRACK_TRANSACTION_CHARACTERISTICS */
3339 lenfle
= tvb_get_fle(tvb
, session_track_tree
, offset
, &lenstr
, NULL
);
3340 proto_tree_add_uint64(session_track_tree
, hf_mysql_session_track_transaction_characteristics_length
, tvb
, offset
, lenfle
, lenstr
);
3343 proto_tree_add_item(session_track_tree
, hf_mysql_session_track_transaction_characteristics
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3344 offset
+= (int)lenstr
;
3346 case 5: /* SESSION_TRACK_TRANSACTION_STATE */
3347 lenfle
= tvb_get_fle(tvb
, session_track_tree
, offset
, &lenstr
, NULL
);
3348 proto_tree_add_uint64(session_track_tree
, hf_mysql_session_track_transaction_state_length
, tvb
, offset
, lenfle
, lenstr
);
3351 proto_tree_add_item(session_track_tree
, hf_mysql_session_track_transaction_state
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3352 offset
+= (int)lenstr
;
3354 default: /* unsupported types skipped */
3355 item
= proto_tree_add_item(session_track_tree
, hf_mysql_payload
, tvb
, offset
, (int)length
, ENC_NA
);
3356 expert_add_info_format(pinfo
, item
, &ei_mysql_dissector_incomplete
, "FIXME: unrecognized session tracker data");
3357 offset
+= (int)length
;
3359 proto_item_set_len(ti
, offset
- orig_offset
);
3361 return (offset
- orig_offset
);
3366 Add a extended metadata entry to the extended meta subtree
3371 add_extended_meta_entry_to_tree(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_item
*tree
, int offset
) {
3374 int orig_offset
= offset
, lenfle
;
3375 proto_item
*item
, *ti
;
3376 proto_tree
*extmeta_tree
;
3378 ti
= proto_tree_add_item(tree
, hf_mariadb_extmeta
, tvb
, offset
, 1, ENC_NA
);
3379 extmeta_tree
= proto_item_add_subtree(ti
, ett_extmeta
);
3381 proto_tree_add_item(extmeta_tree
, hf_mariadb_extmeta_key
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3382 data_type
= tvb_get_uint8(tvb
, offset
);
3385 lenfle
= tvb_get_fle(tvb
, extmeta_tree
, offset
, &lenstr
, NULL
);
3386 proto_tree_add_uint64(extmeta_tree
, hf_mariadb_extmeta_length
, tvb
, offset
, lenfle
, lenstr
);
3389 switch (data_type
) {
3391 proto_tree_add_item(extmeta_tree
, hf_mariadb_extmeta_type
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3392 offset
+= (int)lenstr
;
3394 case 1: /* FORMAT */
3395 proto_tree_add_item(extmeta_tree
, hf_mariadb_extmeta_format
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3396 offset
+= (int)lenstr
;
3398 default: /* unsupported types skipped */
3399 item
= proto_tree_add_item(extmeta_tree
, hf_mysql_payload
, tvb
, offset
, (int)lenstr
, ENC_NA
);
3400 expert_add_info_format(pinfo
, item
, &ei_mysql_dissector_incomplete
, "FIXME: unrecognized extended metadata data");
3401 offset
+= (int)lenstr
;
3403 proto_item_set_len(ti
, offset
- orig_offset
);
3405 return (offset
- orig_offset
);
3409 mysql_dissect_ok_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
3410 proto_tree
*tree
, mysql_conn_data_t
*conn_data
)
3412 uint64_t lenstr
= 0;
3413 uint64_t affected_rows
;
3416 uint16_t server_status
= 0;
3418 col_append_str(pinfo
->cinfo
, COL_INFO
, " OK " );
3419 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3421 fle
= tvb_get_fle(tvb
, tree
, offset
, &affected_rows
, NULL
);
3422 proto_tree_add_uint64(tree
, hf_mysql_affected_rows
, tvb
, offset
, fle
, affected_rows
);
3425 fle
= tvb_get_fle(tvb
, tree
, offset
, &insert_id
, NULL
);
3426 if (tree
&& insert_id
) {
3427 proto_tree_add_uint64(tree
, hf_mysql_insert_id
, tvb
, offset
, fle
, insert_id
);
3431 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3432 offset
= mysql_dissect_server_status(tvb
, offset
, tree
, &server_status
);
3434 /* 4.1+ protocol only: 2 bytes number of warnings */
3435 if (conn_data
->clnt_caps
& conn_data
->srv_caps
& MYSQL_CAPS_CU
) {
3436 proto_tree_add_item(tree
, hf_mysql_num_warn
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3437 lenstr
= tvb_get_ntohs(tvb
, offset
);
3442 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_ST
) {
3443 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3444 uint64_t session_track_length
;
3446 proto_item
*session_track_tree
= NULL
;
3449 offset
+= tvb_get_fle(tvb
, tree
, offset
, &lenstr
, NULL
);
3450 /* first read the optional message */
3452 proto_tree_add_item(tree
, hf_mysql_message
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3453 offset
+= (int)lenstr
;
3456 /* session state tracking */
3457 if (server_status
& MYSQL_STAT_SESSION_STATE_CHANGED
) {
3458 fle
= tvb_get_fle(tvb
, tree
, offset
, &session_track_length
, NULL
);
3459 tf
= proto_tree_add_item(tree
, hf_mysql_session_track_data
, tvb
, offset
, -1, ENC_NA
);
3460 session_track_tree
= proto_item_add_subtree(tf
, ett_session_track_data
);
3461 proto_tree_add_uint64(tf
, hf_mysql_session_track_data_length
, tvb
, offset
, fle
, session_track_length
);
3464 while (session_track_length
> 0) {
3465 length
= add_session_tracker_entry_to_tree(tvb
, pinfo
, session_track_tree
, offset
, conn_data
);
3467 session_track_length
-= length
;
3472 /* optional: message string */
3473 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3474 if(lenstr
> (uint64_t)tvb_reported_length_remaining(tvb
, offset
))
3475 lenstr
= tvb_reported_length_remaining(tvb
, offset
);
3476 proto_tree_add_item(tree
, hf_mysql_message
, tvb
, offset
, (int)lenstr
, ENC_ASCII
);
3477 offset
+= (int)lenstr
;
3481 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3487 mysql_dissect_server_status(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, uint16_t *server_status
)
3490 if (server_status
) {
3491 *server_status
= tvb_get_letohs(tvb
, offset
);
3493 proto_tree_add_bitmask_with_flags(tree
, tvb
, offset
, hf_mysql_server_status
, ett_stat
, mysql_stat_flags
, ENC_LITTLE_ENDIAN
, BMT_NO_APPEND
);
3502 mysql_dissect_caps(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, int mysql_caps
, uint16_t *caps
)
3505 *caps
= tvb_get_letohs(tvb
, offset
);
3507 proto_tree_add_bitmask_with_flags(tree
, tvb
, offset
, mysql_caps
, ett_caps
, mysql_caps_flags
, ENC_LITTLE_ENDIAN
, BMT_NO_APPEND
);
3514 mysql_dissect_extcaps(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, int mysql_extcaps
, uint16_t *ext_caps
)
3517 *ext_caps
= tvb_get_letohs(tvb
, offset
);
3519 proto_tree_add_bitmask_with_flags(tree
, tvb
, offset
, mysql_extcaps
, ett_extcaps
, mysql_extcaps_flags
, ENC_LITTLE_ENDIAN
, BMT_NO_APPEND
);
3525 static int mariadb_dissect_caps_or_flags(tvbuff_t
*tvb
, int offset
, enum ftenum type
, proto_tree
*tree
,
3526 int mariadb_caps
, int * const *fields
, void *value
)
3532 *((uint8_t *)value
)= tvb_get_uint8(tvb
, offset
);
3536 *((uint16_t *)value
)= tvb_get_letohs(tvb
, offset
);
3540 *((uint32_t *)value
)= tvb_get_letohl(tvb
, offset
);
3546 proto_tree_add_bitmask_with_flags(tree
, tvb
, offset
, mariadb_caps
, ett_extcaps
, fields
, ENC_LITTLE_ENDIAN
, BMT_NO_APPEND
);
3553 mysql_dissect_result_header(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
3554 proto_tree
*tree
, mysql_conn_data_t
*conn_data
,
3555 const mysql_frame_data_t
*my_frame_data
)
3558 uint64_t num_fields
, extra
;
3559 uint8_t send_meta
= 0;
3560 my_metadata_list_t
*field_metas
;
3561 my_stmt_data_t
*stmt_data
;
3563 col_append_str(pinfo
->cinfo
, COL_INFO
, "TABULAR " );
3564 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3566 fle
= tvb_get_fle(tvb
, tree
, offset
, &num_fields
, NULL
);
3567 proto_tree_add_uint64(tree
, hf_mysql_num_fields
, tvb
, offset
, fle
, num_fields
);
3570 /** skip info flag **/
3572 if (conn_data
->mariadb_client_ext_caps
& MARIADB_CAPS_ME
3573 && conn_data
->mariadb_server_ext_caps
& MARIADB_CAPS_ME
3574 && tvb_reported_length_remaining(tvb
, offset
)) {
3575 send_meta
= tvb_get_uint8(tvb
, offset
);
3576 proto_tree_add_item(tree
, hf_mariadb_send_meta
, tvb
, offset
, 1, ENC_NA
);
3581 if (num_fields
> MAX_MY_METADATA_COUNT
) {
3582 expert_add_info_format(pinfo
, tree
, &ei_mysql_invalid_length
, "Invalid length: %" PRIu64
, num_fields
);
3583 return tvb_reported_length_remaining(tvb
, 0);
3584 } else if (send_meta
) {
3585 field_metas
= wmem_new(wmem_file_scope(), my_metadata_list_t
);
3586 field_metas
->count
= (uint16_t)num_fields
;
3587 field_metas
->flags
= (uint16_t *)wmem_alloc0_array(wmem_file_scope(), uint16_t, (size_t)num_fields
);
3588 field_metas
->types
= (uint8_t *)wmem_alloc0_array(wmem_file_scope(), uint8_t, (size_t)num_fields
);
3589 field_metas
->encodings
= (unsigned *)wmem_alloc0_array(wmem_file_scope(), unsigned, (size_t)num_fields
);
3590 mysql_set_field_metas(pinfo
, conn_data
, field_metas
);
3592 if (my_frame_data
->stmt_id
) {
3593 stmt_data
= (my_stmt_data_t
*)wmem_tree_lookup32(conn_data
->stmts
, my_frame_data
->stmt_id
);
3594 if (stmt_data
!= NULL
) {
3595 field_metas
= &stmt_data
->field_metas
;
3596 mysql_set_field_metas(pinfo
, conn_data
, field_metas
);
3602 if (tvb_reported_length_remaining(tvb
, offset
)) {
3603 fle
= tvb_get_fle(tvb
, tree
, offset
, &extra
, NULL
);
3604 proto_tree_add_uint64(tree
, hf_mysql_extra
, tvb
, offset
, fle
, extra
);
3610 mysql_set_conn_state(pinfo
, conn_data
, FIELD_PACKET
);
3611 mysql_set_remaining_field_packet_count(pinfo
, conn_data
, num_fields
);
3613 mysql_set_remaining_field_packet_count(pinfo
, conn_data
, 0);
3614 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_DE
) {
3615 mysql_set_conn_state(pinfo
, conn_data
, ROW_PACKET
);
3617 /** Intermediate EOF follow **/
3618 mysql_set_conn_state(pinfo
, conn_data
, FIELD_PACKET
);
3622 mysql_set_conn_state(pinfo
, conn_data
, ROW_PACKET
);
3630 * Add length encoded string to tree
3633 mysql_field_add_lestring(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, int field
, unsigned encoding
)
3637 header_field_info
* hfi
;
3639 proto_tree
* sub_tree
;
3640 int start_offset
= offset
;
3642 hfi
= proto_registrar_get_nth(field
);
3643 DISSECTOR_ASSERT(hfi
!= NULL
);
3645 sub_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
, -1, ett_mysql_field
, &ti
, "%s", hfi
->name
);
3647 offset
+= tvb_get_fle(tvb
, sub_tree
, offset
, &lelen
, &is_null
);
3649 proto_tree_add_string(sub_tree
, field
, tvb
, offset
, 0, "NULL");
3652 proto_tree_add_item(sub_tree
, field
, tvb
, offset
, (int)lelen
, encoding
);
3653 /* Prevent infinite loop due to overflow */
3654 if (offset
+ (int)lelen
< offset
) {
3655 offset
= tvb_reported_length(tvb
);
3658 offset
+= (int)lelen
;
3661 proto_item_set_len(ti
, offset
-start_offset
);
3667 mysql_dissect_field_packet(tvbuff_t
*tvb
, proto_item
*pi _U_
, int offset
, proto_tree
*tree
, packet_info
*pinfo _U_
, mysql_conn_data_t
*conn_data
, const mysql_frame_data_t
*my_frame_data
)
3671 unsigned fld_encoding
;
3672 int length
= tvb_reported_length(tvb
);
3673 mysql_state_t current_state
= my_frame_data
->state
;
3675 unsigned encoding
= my_frame_data
->encoding_results
;
3677 /* Are these fields optional? a trace suggests they are...*/
3678 offset
= mysql_field_add_lestring(tvb
, offset
, tree
, hf_mysql_fld_catalog
, encoding
);
3679 if (offset
>= length
) {
3682 offset
= mysql_field_add_lestring(tvb
, offset
, tree
, hf_mysql_fld_db
, encoding
);
3683 offset
= mysql_field_add_lestring(tvb
, offset
, tree
, hf_mysql_fld_table
, encoding
);
3684 offset
= mysql_field_add_lestring(tvb
, offset
, tree
, hf_mysql_fld_org_table
, encoding
);
3685 offset
= mysql_field_add_lestring(tvb
, offset
, tree
, hf_mysql_fld_name
, encoding
);
3686 offset
= mysql_field_add_lestring(tvb
, offset
, tree
, hf_mysql_fld_org_name
, encoding
);
3688 // mariadb extended metadata infos
3689 if (conn_data
->mariadb_client_ext_caps
& MARIADB_CAPS_EM
3690 && conn_data
->mariadb_server_ext_caps
& MARIADB_CAPS_EM
) {
3691 uint64_t extended_length
;
3692 proto_item
*extended_tree
= NULL
;
3696 fle
= tvb_get_fle(tvb
, tree
, offset
, &extended_length
, NULL
);
3697 tf
= proto_tree_add_item(tree
, hf_mariadb_extmeta_data
, tvb
, offset
, fle
+ (uint32_t) extended_length
, ENC_NA
);
3698 extended_tree
= proto_item_add_subtree(tf
, ett_extmeta_data
);
3699 proto_tree_add_uint64(tf
, hf_mariadb_extmeta_length
, tvb
, offset
, fle
, extended_length
);
3702 while (extended_length
> 0) {
3703 length
= add_extended_meta_entry_to_tree(tvb
, pinfo
, extended_tree
, offset
);
3705 extended_length
-= length
;
3709 offset
+=1; /* filler */
3712 proto_tree_add_item_ret_uint(tree
, hf_mysql_fld_charsetnr
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &charsetnr
);
3713 fld_encoding
= collation_to_encoding(charsetnr
, conn_data
->is_mariadb_server
);
3714 offset
+= 2; /* charset */
3716 proto_tree_add_item(tree
, hf_mysql_fld_length
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
3717 offset
+= 4; /* length */
3719 proto_tree_add_item(tree
, hf_mysql_fld_type
, tvb
, offset
, 1, ENC_NA
);
3720 fld_type
= tvb_get_uint8(tvb
, offset
);
3721 offset
+= 1; /* type */
3723 proto_tree_add_bitmask_with_flags(tree
, tvb
, offset
, hf_mysql_fld_flags
, ett_field_flags
, mysql_fld_flags
, ENC_LITTLE_ENDIAN
, BMT_NO_APPEND
);
3724 fld_flag
= tvb_get_letohs(tvb
, offset
);
3725 offset
+= 2; /* flags */
3727 proto_tree_add_item(tree
, hf_mysql_fld_decimals
, tvb
, offset
, 1, ENC_NA
);
3728 offset
+= 1; /* decimals */
3730 offset
+= 2; /* filler */
3732 if (current_state
== FIELD_PACKET
|| current_state
== PREPARED_FIELDS
) {
3733 if (my_frame_data
->field_metas
.count
) {
3734 uint64_t fieldpos
= my_frame_data
->field_metas
.count
- my_frame_data
->remaining_field_packet_count
;
3735 if (fieldpos
>= my_frame_data
->field_metas
.count
) {
3736 expert_add_info_format(pinfo
, tree
, &ei_mysql_invalid_length
, "Invalid length: %" PRIu64
, fieldpos
);
3737 return tvb_reported_length_remaining(tvb
, 0);
3739 my_frame_data
->field_metas
.types
[fieldpos
] = fld_type
;
3740 my_frame_data
->field_metas
.flags
[fieldpos
] = fld_flag
;
3741 my_frame_data
->field_metas
.encodings
[fieldpos
] = fld_encoding
;
3745 /* default (Only use for show fields) */
3746 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3747 offset
= mysql_field_add_lestring(tvb
, offset
, tree
, hf_mysql_fld_default
, encoding
);
3754 mysql_dissect_text_row_packet(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, const mysql_frame_data_t
*my_frame_data
)
3758 while (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3759 if (fieldpos
< my_frame_data
->field_metas
.count
) {
3760 encoding
= my_frame_data
->field_metas
.encodings
[fieldpos
];
3762 encoding
= my_frame_data
->encoding_results
;
3764 offset
= mysql_field_add_lestring(tvb
, offset
, tree
, hf_mysql_row_text
, encoding
);
3772 mysql_dissect_binary_row_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_item
*pi
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data _U_
, const mysql_frame_data_t
*my_frame_data
)
3776 proto_tree
* bf_tree
;
3778 if (my_frame_data
->field_metas
.count
) {
3781 int nfields
= my_frame_data
->field_metas
.count
;
3782 int null_len
= (nfields
+ 9) / 8;
3785 null_buffer
= (uint8_t *)wmem_alloc(pinfo
->pool
, (size_t)null_len
+ 1);
3786 tvb_get_raw_bytes_as_string(tvb
, offset
, null_buffer
, (size_t)null_len
+ 1);
3787 proto_tree_add_bytes_with_length(tree
, hf_mysql_null_buffer
, tvb
, offset
, null_len
, null_buffer
, null_len
);
3790 for (fieldpos
= 0; fieldpos
< nfields
; fieldpos
++) {
3791 if ((null_buffer
[(fieldpos
+ 2) / 8] & (1 << ((fieldpos
+ 2) % 8))) == 0) {
3793 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
3794 bf_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_mysql_binary_field
, &ti
, "Binary Field");
3795 if (!mysql_dissect_binary_row_value(tvb
, pinfo
, pi
, &offset
, bf_tree
,
3796 my_frame_data
->field_metas
.types
[fieldpos
],
3797 my_frame_data
->field_metas
.flags
[fieldpos
],
3798 my_frame_data
->field_metas
.encodings
[fieldpos
]))
3802 proto_tree_add_item(tree
, hf_mysql_exec_field_null
, tvb
, offset
, 0, ENC_NA
);
3812 mysql_dissect_binary_row_value(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_item
*pi _U_
, int *offset
, proto_item
*tree
, uint8_t field_type
, uint16_t field_flag
, unsigned field_encoding
)
3814 int dissector_index
= 0;
3815 uint8_t param_unsigned
= 0;
3816 if (field_flag
& MYSQL_FLD_UNSIGNED_FLAG
) {
3820 while (mysql_exec_dissectors
[dissector_index
].dissector
!= NULL
) {
3821 if (mysql_exec_dissectors
[dissector_index
].type
== field_type
&&
3822 mysql_exec_dissectors
[dissector_index
].unsigned_flag
== param_unsigned
) {
3823 mysql_exec_dissectors
[dissector_index
].dissector(tvb
, pinfo
, offset
, tree
, field_encoding
);
3832 mysql_dissect_response_prepare(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data
)
3834 my_stmt_data_t
*stmt_data
;
3835 my_metadata_list_t
*field_metas
;
3836 my_metadata_list_t
*param_metas
;
3839 uint16_t stmt_num_fields
;
3840 uint16_t stmt_num_params
;
3842 proto_tree_add_item_ret_uint(tree
, hf_mysql_stmt_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &stmt_id
);
3843 mysql_set_prepared_stmt_id(pinfo
, conn_data
, stmt_id
);
3845 proto_tree_add_item(tree
, hf_mysql_num_fields
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3846 stmt_num_fields
= tvb_get_letohs(tvb
, offset
);
3848 proto_tree_add_item(tree
, hf_mysql_num_params
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3849 stmt_num_params
= tvb_get_letohs(tvb
, offset
);
3851 if (!pinfo
->fd
->visited
) {
3853 /* XXX: Can statement ids be reused on the same connection?
3854 * If so, the tree should be a multimap or similar. If not,
3855 * there should be an expert info if we see a reused one.
3857 if (wmem_tree_lookup32(conn_data
->stmts
, stmt_id
) != NULL
) {
3862 stmt_data
= wmem_new(wmem_file_scope(), struct my_stmt_data
);
3863 param_metas
= wmem_new(wmem_file_scope(), my_metadata_list_t
);
3864 param_metas
->count
= stmt_num_params
;
3865 param_metas
->flags
= (uint16_t *)wmem_alloc0_array(wmem_file_scope(), uint16_t, param_metas
->count
);
3866 param_metas
->types
= (uint8_t *)wmem_alloc0_array(wmem_file_scope(), uint8_t, param_metas
->count
);
3867 //param_metas->encodings = (unsigned *)wmem_alloc0_array(wmem_file_scope(), unsigned, param_metas->count);
3868 stmt_data
->param_metas
= *param_metas
;
3870 field_metas
= wmem_new(wmem_file_scope(), my_metadata_list_t
);
3871 field_metas
->count
= stmt_num_fields
;
3872 field_metas
->flags
= (uint16_t *)wmem_alloc0_array(wmem_file_scope(), uint16_t, field_metas
->count
);
3873 field_metas
->types
= (uint8_t *)wmem_alloc0_array(wmem_file_scope(), uint8_t, field_metas
->count
);
3874 field_metas
->encodings
= (unsigned *)wmem_alloc0_array(wmem_file_scope(), unsigned, field_metas
->count
);
3875 stmt_data
->field_metas
= *field_metas
;
3877 wmem_tree_insert32(conn_data
->stmts
, stmt_id
, stmt_data
);
3879 mysql_set_field_metas(pinfo
, conn_data
, field_metas
);
3885 proto_tree_add_item(tree
, hf_mysql_num_warn
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3887 if (stmt_num_params
> 0) {
3888 mysql_set_remaining_field_packet_count(pinfo
, conn_data
, stmt_num_params
);
3889 mysql_set_conn_state(pinfo
, conn_data
, PREPARED_PARAMETERS
);
3890 } else if (stmt_num_fields
> 0) {
3891 mysql_set_remaining_field_packet_count(pinfo
, conn_data
, stmt_num_fields
);
3892 mysql_set_conn_state(pinfo
, conn_data
, PREPARED_FIELDS
);
3894 mysql_set_remaining_field_packet_count(pinfo
, conn_data
, 0);
3895 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
3898 return offset
+ tvb_reported_length_remaining(tvb
, offset
);
3902 Enumeration type for the different types of log events.
3904 For MySQL, see Log_event_type in
3905 https://github.com/mysql/mysql-server/blob/trunk/libs/mysql/binlog/event/binlog_event.h
3908 https://mariadb.com/kb/en/2-binlog-event-header/#event-type
3910 enum Log_event_type
{
3912 Every time you add a type, you have to
3913 - Assign it a number explicitly. Otherwise it will cause trouble
3914 if a event type before is deprecated and removed directly from
3916 - Fix Format_description_event::Format_description_event().
3920 Deprecated since mysql 8.0.2. It is just a placeholder,
3921 should not be used anywhere else.
3931 APPEND_BLOCK_EVENT
= 9,
3932 DELETE_FILE_EVENT
= 11,
3935 USER_VAR_EVENT
= 14,
3936 FORMAT_DESCRIPTION_EVENT
= 15,
3938 BEGIN_LOAD_QUERY_EVENT
= 17,
3939 EXECUTE_LOAD_QUERY_EVENT
= 18,
3941 TABLE_MAP_EVENT
= 19,
3944 The V1 event numbers are used from 5.1.16 until mysql-5.6.
3946 WRITE_ROWS_EVENT_V1
= 23,
3947 UPDATE_ROWS_EVENT_V1
= 24,
3948 DELETE_ROWS_EVENT_V1
= 25,
3951 Something out of the ordinary happened on the master
3953 INCIDENT_EVENT
= 26,
3956 Heartbeat event to be send by master at its idle time
3957 to ensure master's online status to slave
3959 HEARTBEAT_LOG_EVENT
= 27,
3962 In some situations, it is necessary to send over ignorable
3963 data to the slave: data that a slave can handle in case there
3964 is code for handling it, but which can be ignored if it is not
3967 IGNORABLE_LOG_EVENT
= 28,
3968 ROWS_QUERY_LOG_EVENT
= 29,
3970 /** Version 2 of the Row events */
3971 WRITE_ROWS_EVENT
= 30,
3972 UPDATE_ROWS_EVENT
= 31,
3973 DELETE_ROWS_EVENT
= 32,
3975 GTID_LOG_EVENT
= 33,
3976 ANONYMOUS_GTID_LOG_EVENT
= 34,
3978 PREVIOUS_GTIDS_LOG_EVENT
= 35,
3980 TRANSACTION_CONTEXT_EVENT
= 36,
3982 VIEW_CHANGE_EVENT
= 37,
3984 /* Prepared XA transaction terminal event similar to Xid */
3985 XA_PREPARE_LOG_EVENT
= 38,
3988 Extension of UPDATE_ROWS_EVENT, allowing partial values according
3989 to binlog_row_value_options.
3991 PARTIAL_UPDATE_ROWS_EVENT
= 39,
3993 TRANSACTION_PAYLOAD_EVENT
= 40,
3995 HEARTBEAT_LOG_EVENT_V2
= 41,
3997 Add new events here - right above this comment!
3998 Existing events (except ENUM_END_EVENT) should never change their numbers
4001 /* MariaDB specific events, starting at 0xa0 / 160 */
4002 ANNOTATE_ROWS_EVENT
= 160,
4003 BINLOG_CHECKPOINT_EVENT
= 161,
4005 GTID_LIST_EVENT
= 163,
4006 START_ENCRYPTION_EVENT
= 164,
4007 QUERY_COMPRESSED_EVENT
= 165,
4008 WRITE_ROWS_COMPRESSED_V1
= 166,
4009 UPDATE_ROWS_COMPRESSED_V1
= 167,
4010 DELETE_ROWS_COMPRESSED_V1
= 168,
4011 WRITE_ROWS_V1
= 169,
4012 UPDATE_ROWS_V1
= 170,
4013 DELETE_ROWS_V1
= 171,
4015 ENUM_END_EVENT
/* end marker */
4018 static const value_string mysql_binlog_event_type_vals
[] = {
4021 {1, "START_EVENT_V3"},
4029 {9, "Append_block"},
4030 {11, "Delete_file"},
4034 {15, "Format_desc"},
4036 {17, "Begin_load_query"},
4037 {18, "Execute_load_query"},
4040 {23, "Write_rows_v1"},
4041 {24, "Update_rows_v1"},
4042 {25, "Delete_rows_v1"},
4048 {31, "Update_rows"},
4049 {32, "Delete_rows"},
4051 {34, "Anonymous_Gtid"},
4052 {35, "Previous_gtids"},
4053 {36, "Transaction_context"},
4054 {37, "View_change"},
4056 {39, "Update_rows_partial"},
4057 {40, "Transaction_payload"},
4058 {41, "Heartbeat_v2"},
4059 {42, "GTID_tagged"},
4062 {160, "Annotate_rows"},
4063 {161, "Binlog_checkpoint"},
4066 {164, "Start_encryption"},
4067 {165, "Query_compressed"},
4068 {166, "Write_rows_compressed"},
4069 {167, "Update_rows_compressed"},
4070 {168, "Delete_rows_compressed"},
4071 {169, "MariaDB_Write_rows_v1"},
4072 {170, "MariaDB_Update_rows_v1"},
4073 {171, "MariaDB_Delete_rows_v1"},
4079 mysql_dissect_binlog_event_heartbeat_v2(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
)
4083 proto_item
*item
, *parent_item
;
4084 proto_item
*hb_v2_tree
, *hb_v2_subtree
;
4086 col_append_str(pinfo
->cinfo
, COL_INFO
, "Heartbeat_v2 ");
4087 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4088 item
= proto_tree_add_item(tree
, hf_mysql_binlog_event_heartbeat_v2
, tvb
, offset
, -1, ENC_NA
);
4089 hb_v2_tree
= proto_item_add_subtree(item
, ett_binlog_event
);
4091 // OTW_HB_LOG_FILENAME_FIELD
4092 parent_item
= proto_tree_add_item(hb_v2_tree
, hf_mysql_binlog_event_heartbeat_v2_otw
, tvb
, offset
, -1, ENC_NA
);
4093 hb_v2_subtree
= proto_item_add_subtree(parent_item
, ett_binlog_event_hb_v2
);
4095 item
= proto_tree_add_item(hb_v2_subtree
, hf_mysql_binlog_event_heartbeat_v2_otw_type
, tvb
, offset
, 1, ENC_NA
);
4096 proto_item_append_text(item
, " (OTW_HB_LOG_FILENAME_FIELD)");
4097 proto_item_append_text(parent_item
, " OTW_HB_LOG_FILENAME_FIELD");
4100 fle
= tvb_get_fle(tvb
, hb_v2_subtree
, offset
, &num
, ENC_NA
);
4103 proto_tree_add_item(hb_v2_subtree
, hf_mysql_binlog_hb_event_filename
, tvb
, offset
, (int) num
, ENC_ASCII
);
4106 // OTW_HB_LOG_POSITION_FIELD
4107 parent_item
= proto_tree_add_item(hb_v2_tree
, hf_mysql_binlog_event_heartbeat_v2_otw
, tvb
, offset
, -1, ENC_NA
);
4108 hb_v2_subtree
= proto_item_add_subtree(parent_item
, ett_binlog_event_hb_v2
);
4109 item
= proto_tree_add_item(hb_v2_subtree
, hf_mysql_binlog_event_heartbeat_v2_otw_type
, tvb
, offset
, 1, ENC_NA
);
4110 proto_item_append_text(item
, " (OTW_HB_LOG_POSITION_FIELD)");
4111 proto_item_append_text(parent_item
, " OTW_HB_LOG_POSITION_FIELD");
4114 fle
= tvb_get_fle(tvb
, hb_v2_subtree
, offset
, &num
, NULL
);
4117 fle
= tvb_get_fle(tvb
, hb_v2_subtree
, offset
, &num
, NULL
);
4118 proto_tree_add_uint64(hb_v2_subtree
, hf_mysql_binlog_hb_event_log_position
, tvb
, offset
, fle
, num
);
4121 // OTW_HB_LOG_FILENAME_FIELD
4122 parent_item
= proto_tree_add_item(hb_v2_tree
, hf_mysql_binlog_event_heartbeat_v2_otw
, tvb
, offset
, -1, ENC_NA
);
4123 hb_v2_subtree
= proto_item_add_subtree(parent_item
, ett_binlog_event_hb_v2
);
4124 item
= proto_tree_add_item(hb_v2_subtree
, hf_mysql_binlog_event_heartbeat_v2_otw_type
, tvb
, offset
, 1, ENC_NA
);
4125 proto_item_append_text(item
, " (OTW_HB_HEADER_END_MARK)");
4126 proto_item_append_text(parent_item
, " OTW_HB_HEADER_END_MARK");
4132 mysql_dissect_binlog_event_header(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, proto_item
*pi
)
4134 proto_tree_add_item(tree
, hf_mysql_binlog_event_header_timestamp
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4137 proto_tree_add_item(tree
, hf_mysql_binlog_event_header_event_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4138 proto_item_append_text(pi
, ": %s", val_to_str(tvb_get_uint8(tvb
, offset
), mysql_binlog_event_type_vals
, "Unknown event type: %d"));
4141 proto_tree_add_item(tree
, hf_mysql_binlog_event_header_server_id
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4144 proto_tree_add_item(tree
, hf_mysql_binlog_event_header_event_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4147 proto_tree_add_item(tree
, hf_mysql_binlog_event_header_log_position
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4150 proto_tree_add_item(tree
, hf_mysql_binlog_event_header_flags
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4157 mysql_dissect_binlog_event_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, proto_item
*pi
)
4162 col_append_str(pinfo
->cinfo
, COL_INFO
, "Binlog Event " );
4163 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4165 event_type
= tvb_get_uint8(tvb
, offset
+ 4);
4166 offset
= mysql_dissect_binlog_event_header(tvb
, offset
, tree
, pi
);
4168 switch (event_type
) {
4169 case HEARTBEAT_LOG_EVENT_V2
:
4170 offset
= mysql_dissect_binlog_event_heartbeat_v2(tvb
, pinfo
, offset
, tree
);
4173 fle
= tvb_reported_length_remaining(tvb
, offset
);
4178 proto_tree_add_item(tree
, hf_mysql_binlog_event_checksum
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4185 mysql_dissect_eof(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_item
*pi _U_
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data _U_
)
4187 uint16_t server_status
= 0;
4188 proto_tree_add_item(tree
, hf_mysql_num_warn
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4190 offset
= mysql_dissect_server_status(tvb
, offset
, tree
, &server_status
);
4191 return offset
+ tvb_reported_length_remaining(tvb
, offset
);
4195 mysql_dissect_auth_switch_request(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data _U_
)
4199 col_set_str(pinfo
->cinfo
, COL_INFO
, "Auth Switch Request " );
4200 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4201 mysql_set_conn_state(pinfo
, conn_data
, AUTH_SWITCH_RESPONSE
);
4203 if (conn_data
->clnt_caps_ext
& MYSQL_CAPS_PA
) {
4204 /* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_auth_switch_request.html */
4207 lenstr
= my_tvb_strsize(tvb
, offset
);
4208 proto_tree_add_item(tree
, hf_mysql_auth_switch_request_name
, tvb
, offset
, lenstr
, ENC_ASCII
);
4209 conn_data
->auth_method
= tvb_get_string_enc(wmem_file_scope(), tvb
, offset
, lenstr
, ENC_ASCII
);
4213 lenstr
= my_tvb_strsize(tvb
, offset
);
4214 proto_tree_add_item(tree
, hf_mysql_auth_switch_request_data
, tvb
, offset
, lenstr
, ENC_NA
);
4217 /* https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_old_auth_switch_request.html */
4219 /* Status (Always 0xfe) */
4220 proto_tree_add_item(tree
, hf_mysql_auth_switch_request_status
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4224 return offset
+ tvb_reported_length_remaining(tvb
, offset
);
4228 mysql_dissect_auth_switch_response(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data _U_
)
4232 col_set_str(pinfo
->cinfo
, COL_INFO
, "Auth Switch Response " );
4233 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4236 lenstr
= my_tvb_strsize(tvb
, offset
);
4237 proto_tree_add_item(tree
, hf_mysql_auth_switch_response_data
, tvb
, offset
, lenstr
, ENC_NA
);
4240 if (g_strcmp0(conn_data
->auth_method
,"caching_sha2_password") == 0) {
4241 mysql_set_conn_state(pinfo
, conn_data
, AUTH_SHA2
);
4244 return offset
+ tvb_reported_length_remaining(tvb
, offset
);
4249 caching_sha2_password authentication state
4251 Doc: https://dev.mysql.com/doc/dev/mysql-server/latest/page_caching_sha2_authentication_exchanges.html
4254 mysql_dissect_auth_sha2(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data _U_
)
4256 col_set_str(pinfo
->cinfo
, COL_INFO
, "Caching_sha2_password " );
4257 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4259 if (tvb_reported_length_remaining(tvb
,offset
) == 2)
4262 uint8_t c
= tvb_get_uint8(tvb
, offset
);
4265 auth2_state
= "request_public_key";
4266 mysql_set_conn_state(pinfo
, conn_data
, AUTH_PUBKEY
);
4269 auth2_state
= "fast_auth_success";
4272 auth2_state
= "perform_full_authentication";
4273 mysql_set_conn_state(pinfo
, conn_data
, AUTH_SHA2
);
4276 auth2_state
= "unknown";
4278 col_append_str(pinfo
->cinfo
, COL_INFO
, auth2_state
);
4279 proto_tree_add_string(tree
, hf_mysql_sha2_auth
, tvb
, offset
, 1, auth2_state
);
4282 return offset
+ tvb_reported_length_remaining(tvb
, offset
);
4286 Public key as requested during caching_sha2_password authentication
4289 mysql_dissect_pubkey(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
4290 proto_tree
*tree
, mysql_conn_data_t
*conn_data _U_
, proto_item
*pi _U_
, mysql_state_t current_state _U_
)
4293 col_set_str(pinfo
->cinfo
, COL_INFO
, "Public key " );
4294 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4295 mysql_set_conn_state(pinfo
, conn_data
, AUTH_SHA2_RESPONSE
);
4298 int len
= tvb_reported_length_remaining(tvb
, offset
) - 1;
4299 next_tvb
= tvb_new_subset_length(tvb
, offset
, len
);
4300 add_new_data_source(pinfo
, next_tvb
, "public key");
4301 proto_tree_add_item(tree
, hf_mysql_pubkey
, tvb
, offset
, len
, ENC_ASCII
);
4304 return offset
+ tvb_reported_length_remaining(tvb
,offset
);
4308 If caching_sha2_password authentication is used over a non-secure channel
4309 then the authentication response (password) is encrypted with a RSA public key.
4311 This means that we can't dissect this response without access to the RSA private key.
4314 mysql_dissect_sha2_response(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
,
4315 proto_tree
*tree _U_
, mysql_conn_data_t
*conn_data _U_
, proto_item
*pi _U_
, mysql_state_t current_state _U_
)
4317 int len
= tvb_reported_length_remaining(tvb
, offset
);
4318 proto_tree_add_item(tree
, hf_mysql_sha2_response
, tvb
, offset
, len
, ENC_NA
);
4319 return offset
+ tvb_reported_length_remaining(tvb
, offset
);
4323 mysql_dissect_clone_request(tvbuff_t
*tvb _U_
, packet_info
*pinfo _U_
, int offset _U_
,
4324 proto_tree
*tree _U_
, mysql_conn_data_t
*conn_data _U_
, proto_item
*pi _U_
, mysql_state_t current_state _U_
)
4326 uint8_t req_code
= tvb_get_uint8(tvb
, offset
);
4328 case MYSQL_CLONE_COM_INIT
:
4329 case MYSQL_CLONE_COM_ATTACH
:
4330 case MYSQL_CLONE_COM_REINIT
:
4331 case MYSQL_CLONE_COM_EXECUTE
:
4332 case MYSQL_CLONE_COM_ACK
:
4333 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s", val_to_str(req_code
, mysql_clone_command_vals
, "Unknown clone request: %d"));
4334 proto_tree_add_item(tree
, hf_mysql_clone_command_code
, tvb
, offset
, 1, ENC_NA
);
4336 case MYSQL_CLONE_COM_EXIT
:
4337 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s", val_to_str(req_code
, mysql_clone_command_vals
, "Unknown clone request: %d"));
4338 proto_tree_add_item(tree
, hf_mysql_clone_command_code
, tvb
, offset
, 1, ENC_NA
);
4339 mysql_set_conn_state(pinfo
, conn_data
, CLONE_EXIT
);
4342 col_append_str(pinfo
->cinfo
, COL_INFO
, " Unknown Clone Command Code") ;
4343 /* TODO, Set error etc */
4351 mysql_dissect_clone_response(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
4352 proto_tree
*tree
, mysql_conn_data_t
*conn_data
, proto_item
*pi _U_
, mysql_state_t current_state
)
4354 uint8_t resp_code
= tvb_get_uint8(tvb
, offset
);
4355 switch (resp_code
) {
4356 case MYSQL_CLONE_COM_RES_LOCS
:
4357 case MYSQL_CLONE_COM_RES_DATA_DESC
:
4358 case MYSQL_CLONE_COM_RES_DATA
:
4359 case MYSQL_CLONE_COM_RES_PLUGIN
:
4360 case MYSQL_CLONE_COM_RES_CONFIG
:
4361 case MYSQL_CLONE_COM_RES_COLLATION
:
4362 case MYSQL_CLONE_COM_RES_PLUGIN_V2
:
4363 case MYSQL_CLONE_COM_RES_CONFIG_V3
:
4364 case MYSQL_CLONE_COM_RES_COMPLETE
:
4365 if (current_state
== CLONE_EXIT
)
4366 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
4368 case MYSQL_CLONE_COM_RES_ERROR
:
4369 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s", val_to_str(resp_code
, mysql_clone_response_vals
, "unknown clone request: %d"));
4370 proto_tree_add_item(tree
, hf_mysql_clone_response_code
, tvb
, offset
, 1, ENC_NA
);
4373 col_append_str(pinfo
->cinfo
, COL_INFO
, " Unknown Clone Response Code") ;
4374 /* TODO, Set error etc */
4382 This is the payload (file content) of the LOAD DATA LOCAL INFILE
4383 https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_query_response_local_infile_data.html
4386 mysql_dissect_loaddata(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
, proto_tree
*tree
, mysql_conn_data_t
*conn_data _U_
)
4388 col_append_str(pinfo
->cinfo
, COL_INFO
, " LOCAL INFILE Payload");
4389 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4390 int lenstr
= tvb_reported_length_remaining(tvb
, offset
);
4391 tvbuff_t
*next_tvb
= tvb_new_subset_length(tvb
, offset
, lenstr
);
4392 add_new_data_source(pinfo
, next_tvb
, "local infile");
4393 proto_tree_add_item(tree
, hf_mysql_loaddata_payload
, tvb
, offset
, lenstr
, ENC_NA
);
4395 mysql_set_conn_state(pinfo
, conn_data
, REQUEST
);
4400 get length of string in packet buffer
4405 offset current offset
4408 deliver length of string, delimited by either \0 or end of buffer
4411 length of string found, including \0 (if present)
4415 my_tvb_strsize(tvbuff_t
*tvb
, int offset
)
4417 int len
= tvb_strnlen(tvb
, offset
, -1);
4419 len
= tvb_reported_length_remaining(tvb
, offset
);
4421 len
++; /* the trailing \0 */
4427 read "field length encoded" value from packet buffer
4431 tvb in packet buffer
4432 tree in....protocol tree
4433 offset in offset in buffer
4434 res out where to store FLE value, may be NULL
4435 is_null out where to store ISNULL flag, may be NULL
4438 read FLE from packet buffer and store its value and ISNULL flag
4439 in caller provided variables
4441 Docs: https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_dt_integers.html
4447 tvb_get_fle(tvbuff_t
*tvb
, proto_tree
*tree _U_
, int offset
, uint64_t *res
, uint8_t *is_null
)
4453 prefix
= tvb_get_uint8(tvb
, offset
);
4469 length
= (uint64_t)tvb_get_uint16(tvb
, offset
, ENC_LITTLE_ENDIAN
);
4474 length
= (uint64_t)tvb_get_uint24(tvb
, offset
, ENC_LITTLE_ENDIAN
);
4479 length
= tvb_get_uint64(tvb
, offset
, ENC_LITTLE_ENDIAN
);
4483 length
= tvb_get_uint8(tvb
, offset
);
4493 get_mysql_compressed_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
4495 /* Compressed packet header: compressed length (3) + sequence number (1)
4496 * + uncompressed packet length (3) */
4497 unsigned len
= 7 + tvb_get_letoh24(tvb
, offset
);
4501 /* dissector helper: length of PDU */
4503 get_mysql_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
4505 /* Regular packet header: length (3) + sequence number (1) */
4506 unsigned len
= 4 + tvb_get_letoh24(tvb
, offset
);
4510 /* dissector main function: handle one PDU */
4512 dissect_mysql_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
4514 proto_tree
*mysql_tree
= NULL
;
4516 conversation_t
*conversation
;
4518 unsigned packet_number
;
4519 bool is_response
, is_tls
= false;
4520 mysql_conn_data_t
*conn_data
;
4522 mysql_state_t conn_state_in
, conn_state_out
, frame_state
;
4523 uint64_t generation
;
4526 struct mysql_frame_data
*mysql_frame_data_p
;
4528 /* get conversation, create if necessary*/
4529 conversation
= find_or_create_conversation(pinfo
);
4531 /* get associated state information, create if necessary */
4532 conn_data
= (mysql_conn_data_t
*)conversation_get_proto_data(conversation
, proto_mysql
);
4534 conn_data
= wmem_new0(wmem_file_scope(), mysql_conn_data_t
);
4535 conn_data
->stmts
= wmem_tree_new(wmem_file_scope());
4536 conn_data
->encoding_client
= ENC_UTF_8
;
4537 conn_data
->encoding_results
= ENC_UTF_8
;
4539 // Client and server capability flags
4540 // Set in case the conversation doesn't start with greeting/login
4541 conn_data
->clnt_caps
= MYSQL_CAPS_CU
; // CLIENT_PROTOCOL_41
4542 conn_data
->clnt_caps_ext
= MYSQL_CAPS_DE
// CLIENT_DEPRECATE_EOF
4543 ^ MYSQL_CAPS_ST
; // CLIENT_SESSION_TRACK
4544 conn_data
->srv_caps
= MYSQL_CAPS_CU
; // CLIENT_PROTOCOL_41
4545 conn_data
->srv_caps_ext
= MYSQL_CAPS_DE
; // CLIENT_DEPRECATE_EOF
4547 conversation_add_proto_data(conversation
, proto_mysql
, conn_data
);
4550 /* Using tvb_raw_offset(tvb) allows storage of multiple "proto data" in a single frame
4551 * (when there are multiple MySQL pdus in a single frame) */
4552 mysql_frame_data_p
= (struct mysql_frame_data
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_mysql
, tvb_raw_offset(tvb
));
4553 if (!mysql_frame_data_p
) {
4554 /* We haven't seen this frame before. Store the state of the
4555 * conversation now so if/when we dissect the frame again
4556 * we'll start with the same state.
4558 mysql_frame_data_p
= wmem_new(wmem_file_scope(), struct mysql_frame_data
);
4559 mysql_frame_data_p
->state
= conn_data
->state
;
4560 mysql_frame_data_p
->resultset_fmt
= conn_data
->resultset_fmt
;
4561 mysql_frame_data_p
->stmt_id
= conn_data
->stmt_id
;
4562 mysql_frame_data_p
->remaining_field_packet_count
= conn_data
->remaining_field_packet_count
;
4563 mysql_frame_data_p
->field_metas
= conn_data
->field_metas
;
4564 mysql_frame_data_p
->encoding_client
= conn_data
->encoding_client
;
4565 mysql_frame_data_p
->encoding_results
= conn_data
->encoding_results
;
4566 p_add_proto_data(wmem_file_scope(), pinfo
, proto_mysql
, tvb_raw_offset(tvb
), mysql_frame_data_p
);
4569 ti
= proto_tree_add_item(tree
, proto_mysql
, tvb
, offset
, -1, ENC_NA
);
4570 mysql_tree
= proto_item_add_subtree(ti
, ett_mysql
);
4571 proto_tree_add_item(mysql_tree
, hf_mysql_packet_length
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
4574 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MySQL");
4576 if (pinfo
->destport
== pinfo
->match_uint
) {
4582 packet_number
= tvb_get_uint8(tvb
, offset
);
4583 proto_tree_add_item(mysql_tree
, hf_mysql_packet_number
, tvb
, offset
, 1, ENC_NA
);
4587 conn_state_in
= conn_data
->state
;
4588 frame_state
= mysql_frame_data_p
->state
;
4589 generation
= conn_data
->generation
;
4591 pi
= proto_tree_add_debug_text(mysql_tree
, "conversation: %p", conversation
);
4592 proto_item_set_generated(pi
);
4593 pi
= proto_tree_add_debug_text(mysql_tree
, "generation: %" PRId64
, generation
);
4594 proto_item_set_generated(pi
);
4595 pi
= proto_tree_add_debug_text(mysql_tree
, "conn state: %s (%u)",
4596 val_to_str(conn_state_in
, state_vals
, "Unknown (%u)"),
4598 proto_item_set_generated(pi
);
4599 pi
= proto_tree_add_debug_text(mysql_tree
, "frame state: %s (%u)",
4600 val_to_str(frame_state
, state_vals
, "Unknown (%u)"),
4602 proto_item_set_generated(pi
);
4606 is_tls
= proto_is_frame_protocol(pinfo
->layers
, "tls");
4609 if (packet_number
== 0 && mysql_frame_data_p
->state
== UNDEFINED
) {
4610 col_set_str(pinfo
->cinfo
, COL_INFO
, "Server Greeting ");
4611 offset
= mysql_dissect_greeting(tvb
, pinfo
, offset
, mysql_tree
, conn_data
, mysql_frame_data_p
);
4612 } else if ((mysql_frame_data_p
->state
== CLONE_ACTIVE
) || (mysql_frame_data_p
->state
== CLONE_EXIT
)) {
4613 col_set_str(pinfo
->cinfo
, COL_INFO
, "Clone Response");
4614 offset
= mysql_dissect_clone_response(tvb
, pinfo
, offset
, mysql_tree
, conn_data
, ti
, mysql_frame_data_p
->state
);
4615 } else if (mysql_frame_data_p
->state
== AUTH_PUBKEY
) {
4616 col_set_str(pinfo
->cinfo
, COL_INFO
, "Public key ");
4617 offset
= mysql_dissect_pubkey(tvb
, pinfo
, offset
, mysql_tree
, conn_data
, ti
, mysql_frame_data_p
->state
);
4619 col_set_str(pinfo
->cinfo
, COL_INFO
, "Response ");
4620 offset
= mysql_dissect_response(tvb
, pinfo
, offset
, mysql_tree
, conn_data
, ti
, mysql_frame_data_p
);
4623 if (mysql_frame_data_p
->state
== LOGIN
&& (packet_number
== 1 || (packet_number
== 2 && is_tls
))) {
4624 col_set_str(pinfo
->cinfo
, COL_INFO
, "Login Request");
4625 offset
= mysql_dissect_login(tvb
, pinfo
, offset
, mysql_tree
, conn_data
);
4627 // If both zlib and ZSTD flags are set then zlib is used.
4628 if ((conn_data
->srv_caps
& MYSQL_CAPS_CP
) && (conn_data
->clnt_caps
& MYSQL_CAPS_CP
)) {
4629 conn_data
->frame_start_compressed
= pinfo
->num
;
4630 conn_data
->compressed_state
= MYSQL_COMPRESS_INIT
;
4631 conn_data
->compressed_alg
= MYSQL_COMPRESS_ALG_ZLIB
;
4632 } else if ((conn_data
->srv_caps_ext
& MYSQL_CAPS_ZS
) && (conn_data
->clnt_caps_ext
& MYSQL_CAPS_ZS
)) {
4633 conn_data
->frame_start_compressed
= pinfo
->num
;
4634 conn_data
->compressed_state
= MYSQL_COMPRESS_INIT
;
4635 conn_data
->compressed_alg
= MYSQL_COMPRESS_ALG_ZSTD
;
4637 } else if ((mysql_frame_data_p
->state
== CLONE_ACTIVE
) || (mysql_frame_data_p
->state
== CLONE_EXIT
)) {
4638 col_set_str(pinfo
->cinfo
, COL_INFO
, "Clone Request");
4639 offset
= mysql_dissect_clone_request(tvb
, pinfo
, offset
, mysql_tree
, conn_data
, ti
, mysql_frame_data_p
->state
);
4640 } else if (mysql_frame_data_p
->state
== AUTH_SHA2_RESPONSE
) {
4641 col_set_str(pinfo
->cinfo
, COL_INFO
, "Caching_sha2_password response");
4642 offset
= mysql_dissect_sha2_response(tvb
, pinfo
, offset
, mysql_tree
, conn_data
, ti
, mysql_frame_data_p
->state
);
4644 col_set_str(pinfo
->cinfo
, COL_INFO
, "Request");
4645 offset
= mysql_dissect_request(tvb
, pinfo
, offset
, mysql_tree
, conn_data
, mysql_frame_data_p
);
4650 conn_state_out
= conn_data
->state
;
4651 ++(conn_data
->generation
);
4652 pi
= proto_tree_add_debug_text(mysql_tree
, "next proto state: %s (%u)",
4653 val_to_str(conn_state_out
, state_vals
, "Unknown (%u)"),
4655 proto_item_set_generated(pi
);
4658 /* remaining payload indicates an error */
4659 if (tvb_reported_length_remaining(tvb
, offset
) > 0) {
4660 ti
= proto_tree_add_item(mysql_tree
, hf_mysql_payload
, tvb
, offset
, -1, ENC_NA
);
4661 expert_add_info(pinfo
, ti
, &ei_mysql_dissector_incomplete
);
4664 return tvb_reported_length(tvb
);
4667 /* A helper function to reassemble MySQL decompressed PDUs on top of compressed
4668 * packets. Decompressed PDUs may span multiple compressed packets:
4669 * https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_compression_packet.html
4670 * "The payload can be anything from a piece of a MySQL Packet to several MySQL
4673 * Some of this error checking is likely unnecessary when dealing with PDUs
4674 * that have been decompressed (would decompression really have succeeded),
4675 * but this could be used later instead of tcp_dissect_pdus() for the
4676 * uncompressed base case as well.
4679 dissect_mysql_decompressed_pdus(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
4681 tvbuff_t
*volatile next_tvb
;
4682 volatile int offset
= 0;
4684 unsigned int remaining
, pdu_len
;
4685 while (tvb_reported_length_remaining(tvb
, offset
)) {
4686 remaining
= tvb_ensure_reported_length_remaining(tvb
, offset
);
4687 if (remaining
< 3) {
4688 pinfo
->desegment_len
= 3 - remaining
;
4689 /* reassemble_streaming_data_and_call_subdissector()
4690 * expects the remaining bytes of the fixed header
4691 * instead of ONE_MORE_SEGMENT. */
4692 return tvb_reported_length(tvb
);
4695 pdu_len
= get_mysql_pdu_len(pinfo
, tvb
, offset
, data
);
4696 if (pdu_len
< MYSQL_HEADER_LENGTH
) {
4697 /* The length value overflowed when adding the
4699 show_reported_bounds_error(tvb
, pinfo
, tree
);
4701 if (remaining
< pdu_len
&& pinfo
->can_desegment
) {
4702 pinfo
->desegment_offset
= offset
;
4703 pinfo
->desegment_len
= pdu_len
- remaining
;
4704 return tvb_reported_length(tvb
);
4707 next_tvb
= tvb_new_subset_length(tvb
, offset
, pdu_len
);
4708 if (remaining
< pdu_len
&& !pinfo
->can_desegment
) {
4709 tvb_set_fragment(next_tvb
);
4712 dissect_mysql_pdu(next_tvb
, pinfo
, tree
, data
);
4714 CATCH_NONFATAL_ERRORS
{
4715 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
4716 /* We don't need to restore pinfo->current_proto,
4717 * because MySQL doesn't call anything else.
4721 offset_before
= offset
;
4723 if (offset
<= offset_before
)
4726 return tvb_reported_length(tvb
);
4730 * Decode a compressed packet
4731 * https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_compression.html
4734 dissect_mysql_compressed_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
4736 proto_tree
*mysql_tree
;
4740 conversation_t
*conversation
;
4741 mysql_conn_data_t
*conn_data
;
4743 unsigned clen
, ulen
;
4745 /* get conversation, create if necessary*/
4746 conversation
= find_or_create_conversation(pinfo
);
4748 /* get associated state information, create if necessary */
4749 conn_data
= (mysql_conn_data_t
*)conversation_get_proto_data(conversation
, proto_mysql
);
4751 conn_data
= wmem_new0(wmem_file_scope(), mysql_conn_data_t
);
4752 conn_data
->stmts
= wmem_tree_new(wmem_file_scope());
4753 conn_data
->compressed_state
= MYSQL_COMPRESS_ACTIVE
;
4754 conn_data
->encoding_client
= ENC_UTF_8
;
4755 conn_data
->encoding_results
= ENC_UTF_8
;
4756 conversation_add_proto_data(conversation
, proto_mysql
, conn_data
);
4758 if (!conn_data
->reassembly_info
) {
4759 conn_data
->reassembly_info
= streaming_reassembly_info_new();
4762 ti
= proto_tree_add_item(tree
, proto_mysql
, tvb
, offset
, 7, ENC_NA
);
4763 proto_item_append_text(ti
, " - compressed packet header");
4764 mysql_tree
= proto_item_add_subtree(ti
, ett_mysql
);
4766 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "MySQL");
4768 clen
= tvb_get_letoh24(tvb
, offset
);
4769 proto_tree_add_item(mysql_tree
, hf_mysql_compressed_packet_length
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
4772 proto_tree_add_item(mysql_tree
, hf_mysql_compressed_packet_number
, tvb
, offset
, 1, ENC_NA
);
4775 ulen
= tvb_get_letoh24(tvb
, offset
);
4776 proto_tree_add_item(mysql_tree
, hf_mysql_compressed_packet_length_uncompressed
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
4780 switch (conn_data
->compressed_alg
) {
4782 case MYSQL_COMPRESS_ALG_ZSTD
:
4783 next_tvb
= tvb_child_uncompress_zstd(tvb
, tvb
, offset
, clen
);
4786 case MYSQL_COMPRESS_ALG_ZLIB
:
4788 next_tvb
= tvb_child_uncompress_zlib(tvb
, tvb
, offset
, clen
);
4792 add_new_data_source(pinfo
, next_tvb
, "compressed data");
4793 reassemble_streaming_data_and_call_subdissector(next_tvb
, pinfo
, 0, ulen
, mysql_tree
, tree
, mysql_reassembly_table
, conn_data
->reassembly_info
, get_virtual_frame_num64(next_tvb
, pinfo
, 0), decompressed_handle
, tree
, data
, "MySQL", &mysql_frag_items
, hf_mysql_fragment_data
);
4797 expert_add_info_format(pinfo
, mysql_tree
, &ei_mysql_compression
, "Can't uncompress packet");
4800 /* No compression was chosen. It's unlikely that there are
4801 * multiple PDUs, and extremely unlikely that they span
4802 * frame boundaries (otherwise compression would have been
4803 * used), but it doesn't hurt to do this.
4805 reassemble_streaming_data_and_call_subdissector(tvb
, pinfo
, offset
, tvb_reported_length_remaining(tvb
, offset
), mysql_tree
, tree
, mysql_reassembly_table
, conn_data
->reassembly_info
, get_virtual_frame_num64(tvb
, pinfo
, offset
), decompressed_handle
, tree
, data
, "MySQL", &mysql_frag_items
, hf_mysql_fragment_data
);
4806 offset
= tvb_reported_length(tvb
);
4813 /* dissector entrypoint, handles TCP-desegmentation */
4815 dissect_mysql(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
4817 conversation_t
*conversation
;
4818 mysql_conn_data_t
*conn_data
= NULL
;
4820 conversation
= find_conversation_pinfo(pinfo
, 0);
4822 conn_data
= (mysql_conn_data_t
*)conversation_get_proto_data(conversation
, proto_mysql
);
4824 if (conn_data
&& conn_data
->compressed_state
== MYSQL_COMPRESS_ACTIVE
&& pinfo
->num
> conn_data
->frame_start_compressed
) {
4825 tcp_dissect_pdus(tvb
, pinfo
, tree
, mysql_desegment
,
4826 MYSQL_HEADER_LENGTH
+ 3,
4827 get_mysql_compressed_pdu_len
,
4828 dissect_mysql_compressed_pdu
, data
);
4830 tcp_dissect_pdus(tvb
, pinfo
, tree
, mysql_desegment
,
4831 MYSQL_HEADER_LENGTH
, get_mysql_pdu_len
,
4832 dissect_mysql_pdu
, data
);
4835 return tvb_reported_length(tvb
);
4838 /* protocol registration */
4839 void proto_register_mysql(void)
4841 static hf_register_info hf
[]=
4843 { &hf_mysql_packet_length
,
4844 { "Packet Length", "mysql.packet_length",
4845 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
4848 { &hf_mysql_packet_number
,
4849 { "Packet Number", "mysql.packet_number",
4850 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4851 "Packet Number (now called: Sequence ID)", HFILL
}},
4853 { &hf_mysql_request
,
4854 { "Request Command", "mysql.request",
4855 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4858 { &hf_mysql_command
,
4859 { "Command", "mysql.command",
4860 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &mysql_command_vals_ext
, 0x0,
4863 { &hf_mysql_response_code
,
4864 { "Response Code", "mysql.response_code",
4865 FT_UINT8
, BASE_HEX
, VALS(mysql_response_code_vals
), 0x0,
4868 { &hf_mysql_error_code
,
4869 { "Error Code", "mysql.error_code",
4870 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4873 { &hf_mysql_error_string
,
4874 { "Error message", "mysql.error.message",
4875 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4876 "Error string in case of MySQL error message", HFILL
}},
4878 { &hf_mysql_sqlstate
,
4879 { "SQL state", "mysql.sqlstate",
4880 FT_STRING
, BASE_NONE
, NULL
, 0x0,
4883 { &hf_mysql_message
,
4884 { "Message", "mysql.message",
4885 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4888 { &hf_mysql_server_greeting
,
4889 { "Server Greeting", "mysql.server_greeting",
4890 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4893 { &hf_mysql_protocol
,
4894 { "Protocol", "mysql.protocol",
4895 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4896 "Protocol Version", HFILL
}},
4898 { &hf_mysql_version
,
4899 { "Version", "mysql.version",
4900 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4901 "MySQL Version", HFILL
}},
4903 { &hf_mysql_session_track
,
4904 { "Session Track", "mysql.session_track",
4905 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4908 { &hf_mysql_session_track_type
,
4909 { "Session tracking type", "mysql.session_track.type",
4910 FT_UINT8
, BASE_DEC
, VALS(mysql_session_track_type_vals
), 0x0,
4913 { &hf_mysql_session_track_length
,
4914 { "Session tracking length", "mysql.session_track.length",
4915 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
4918 { &hf_mysql_session_track_data
,
4919 { "Session tracking data", "mysql.session_track.data",
4920 FT_NONE
, BASE_NONE
, NULL
, 0x0,
4923 { &hf_mysql_session_track_data_length
,
4924 { "Session tracking data length", "mysql.session_track.data.length",
4925 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
4928 { &hf_mysql_session_track_sysvar_length
,
4929 { "System variable change Length", "mysql.session_track.sysvar.length",
4930 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
4933 { &hf_mysql_session_track_sysvar_name
,
4934 { "System variable change Name", "mysql.session_track.sysvar.name",
4935 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4938 { &hf_mysql_session_track_sysvar_value
,
4939 { "System variable change Value", "mysql.session_track.sysvar.value",
4940 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4943 { &hf_mysql_session_track_schema_length
,
4944 { "Schema change length", "mysql.session_track.schema.length",
4945 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
4948 { &hf_mysql_session_track_schema
,
4949 { "Schema change", "mysql.session_track.schema",
4950 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4953 { &hf_mysql_session_state_change
,
4954 { "State change", "mysql.session_track.state_change",
4955 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4958 { &hf_mysql_session_track_gtids_encoding
,
4959 { "GTIDs encoding", "mysql.session_track.gtids.encoding",
4960 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
4963 { &hf_mysql_session_track_gtids_length
,
4964 { "GTIDs length", "mysql.session_track.gtids.length",
4965 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
4968 { &hf_mysql_session_track_gtids
,
4969 { "GTIDs", "mysql.session_track.gtids",
4970 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4973 { &hf_mysql_session_track_transaction_characteristics_length
,
4974 { "Transaction characteristics length", "mysql.session_track.transaction_characteristics.length",
4975 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
4978 { &hf_mysql_session_track_transaction_characteristics
,
4979 { "Transaction characteristics", "mysql.session_track.transaction_characteristics",
4980 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4983 { &hf_mysql_session_track_transaction_state_length
,
4984 { "Transaction state length", "mysql.session_track.transaction_state.length",
4985 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
4988 { &hf_mysql_session_track_transaction_state
,
4989 { "Transaction state", "mysql.session_track.transaction_state",
4990 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
4993 { &hf_mysql_caps_server
,
4994 { "Server Capabilities", "mysql.caps.server",
4995 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
4996 "MySQL Capabilities", HFILL
}},
4998 { &hf_mysql_caps_client
,
4999 { "Client Capabilities", "mysql.caps.client",
5000 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5001 "MySQL Capabilities", HFILL
}},
5003 { &hf_mysql_cap_long_password
,
5004 { "Long Password","mysql.caps.lp",
5005 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_LP
,
5008 { &hf_mysql_cap_found_rows
,
5009 { "Found Rows","mysql.caps.fr",
5010 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_FR
,
5013 { &hf_mysql_cap_long_flag
,
5014 { "Long Column Flags","mysql.caps.lf",
5015 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_LF
,
5018 { &hf_mysql_cap_connect_with_db
,
5019 { "Connect With Database","mysql.caps.cd",
5020 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_CD
,
5023 { &hf_mysql_cap_no_schema
,
5024 { "Don't Allow database.table.column","mysql.caps.ns",
5025 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_NS
,
5028 { &hf_mysql_cap_compress
,
5029 { "Can use compression protocol","mysql.caps.cp",
5030 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_CP
,
5033 { &hf_mysql_cap_odbc
,
5034 { "ODBC Client","mysql.caps.ob",
5035 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_OB
,
5038 { &hf_mysql_cap_local_files
,
5039 { "Can Use LOAD DATA LOCAL","mysql.caps.li",
5040 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_LI
,
5043 { &hf_mysql_cap_ignore_space
,
5044 { "Ignore Spaces before '('","mysql.caps.is",
5045 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_IS
,
5048 { &hf_mysql_cap_change_user
,
5049 { "Speaks 4.1 protocol (new flag)","mysql.caps.cu",
5050 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_CU
,
5053 { &hf_mysql_cap_interactive
,
5054 { "Interactive Client","mysql.caps.ia",
5055 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_IA
,
5058 { &hf_mysql_cap_ssl
,
5059 { "Switch to SSL after handshake","mysql.caps.sl",
5060 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_SL
,
5063 { &hf_mysql_cap_ignore_sigpipe
,
5064 { "Ignore sigpipes","mysql.caps.ii",
5065 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_II
,
5068 { &hf_mysql_cap_transactions
,
5069 { "Knows about transactions","mysql.caps.ta",
5070 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_TA
,
5073 { &hf_mysql_cap_reserved
,
5074 { "Speaks 4.1 protocol (old flag)","mysql.caps.rs",
5075 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_RS
,
5078 { &hf_mysql_cap_secure_connect
,
5079 { "Can do 4.1 authentication","mysql.caps.sc",
5080 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_SC
,
5083 { &hf_mysql_extcaps_server
,
5084 { "Extended Server Capabilities", "mysql.extcaps.server",
5085 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5086 "MySQL Extended Capabilities", HFILL
}},
5088 { &hf_mysql_extcaps_client
,
5089 { "Extended Client Capabilities", "mysql.extcaps.client",
5090 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5091 "MySQL Extended Capabilities", HFILL
}},
5093 { &hf_mysql_cap_multi_statements
,
5094 { "Multiple statements","mysql.caps.ms",
5095 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_MS
,
5098 { &hf_mysql_cap_multi_results
,
5099 { "Multiple results","mysql.caps.mr",
5100 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_MR
,
5103 { &hf_mysql_cap_ps_multi_results
,
5104 { "PS Multiple results","mysql.caps.pm",
5105 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_PM
,
5108 { &hf_mysql_cap_plugin_auth
,
5109 { "Plugin Auth","mysql.caps.pa",
5110 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_PA
,
5113 { &hf_mysql_cap_connect_attrs
,
5114 { "Connect attrs","mysql.caps.ca",
5115 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_CA
,
5118 { &hf_mysql_cap_plugin_auth_lenenc_client_data
,
5119 { "Plugin Auth LENENC Client Data","mysql.caps.cd",
5120 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_AL
,
5123 { &hf_mysql_cap_client_can_handle_expired_passwords
,
5124 { "Client can handle expired passwords","mysql.caps.ep",
5125 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_EP
,
5128 { &hf_mysql_cap_session_track
,
5129 { "Session variable tracking","mysql.caps.session_track",
5130 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_ST
,
5133 { &hf_mysql_cap_deprecate_eof
,
5134 { "Deprecate EOF","mysql.caps.deprecate_eof",
5135 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_DE
,
5138 { &hf_mysql_cap_optional_metadata
,
5139 { "Client can handle optional resultset metadata","mysql.caps.optional_metadata",
5140 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_RM
,
5143 { &hf_mysql_cap_compress_zstd
,
5144 { "ZSTD Compression Algorithm","mysql.caps.compress_zsd",
5145 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_ZS
,
5148 { &hf_mysql_cap_query_attrs
,
5149 { "Query Attributes","mysql.caps.query_attrs",
5150 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_QA
,
5153 { &hf_mysql_cap_mf_auth
,
5154 { "Multifactor Authentication","mysql.caps.mf_auth",
5155 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_MF
,
5158 { &hf_mysql_cap_cap_ext
,
5159 { "Capability Extension","mysql.caps.cap_ext",
5160 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_CE
,
5163 { &hf_mysql_cap_ssl_verify_server_cert
,
5164 { "Client verifies server's TLS/SSL certificate","mysql.caps.vc",
5165 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_CAPS_VC
,
5168 { &hf_mysql_cap_unused
,
5169 { "Unused","mysql.caps.unused",
5170 FT_UINT16
, BASE_HEX
, NULL
, MYSQL_CAPS_UNUSED
,
5173 { &hf_mysql_login_request
,
5174 { "Login Request", "mysql.login_request",
5175 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5178 { &hf_mysql_max_packet
,
5179 { "MAX Packet", "mysql.max_packet",
5180 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5181 "MySQL Max packet", HFILL
}},
5183 { &hf_mysql_collation
,
5184 { "Collation", "mysql.collation",
5185 FT_UINT16
, BASE_DEC
|BASE_EXT_STRING
, &mysql_collation_vals_ext
, 0x0,
5186 "MySQL Collation", HFILL
}},
5188 { &hf_mariadb_collation
,
5189 { "Collation", "mariadb.collation",
5190 FT_UINT16
, BASE_DEC
|BASE_EXT_STRING
, &mariadb_collation_vals_ext
, 0x0,
5191 "MariaDB Collation", HFILL
}},
5193 { &hf_mysql_table_name
,
5194 { "Table Name", "mysql.table_name",
5195 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5199 { "Username", "mysql.user",
5200 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5201 "Login Username", HFILL
}},
5204 { "Schema", "mysql.schema",
5205 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5206 "Login Schema", HFILL
}},
5208 { &hf_mysql_client_auth_plugin
,
5209 { "Client Auth Plugin", "mysql.client_auth_plugin",
5210 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5213 { &hf_mysql_connattrs
,
5214 { "Connection Attributes", "mysql.connattrs",
5215 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5218 { &hf_mysql_connattrs_length
,
5219 { "Connection Attributes length", "mysql.connattrs.length",
5220 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5223 { &hf_mysql_connattrs_attr
,
5224 { "Connection Attribute", "mysql.connattrs.attr",
5225 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5228 { &hf_mysql_connattrs_name_length
,
5229 { "Connection Attribute Name Length", "mysql.connattrs.name.length",
5230 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5233 { &hf_mysql_connattrs_name
,
5234 { "Connection Attribute Name", "mysql.connattrs.name",
5235 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5238 { &hf_mysql_connattrs_value_length
,
5239 { "Connection Attribute Value Length", "mysql.connattrs.value.length",
5240 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5243 { &hf_mysql_connattrs_value
,
5244 { "Connection Attribute Value", "mysql.connattrs.value",
5245 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5248 { &hf_mysql_zstd_compression_level
,
5249 { "ZSTD Compression Level", "mysql.compression.zstd_level",
5250 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5254 { &hf_mariadb_extmeta_data
,
5255 { "Extended metadata data", "mysql.extmeta_data",
5256 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5259 { &hf_mariadb_extmeta
,
5260 { "Extended metadata", "mysql.extmeta",
5261 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5264 { &hf_mariadb_extmeta_length
,
5265 { "Extended metadata length", "mysql.extmeta.length",
5266 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5269 { &hf_mariadb_extmeta_key
,
5270 { "Extended metadata key", "mysql.extmeta.key",
5271 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5274 { &hf_mariadb_extmeta_type
,
5275 { "Extended metadata type", "mysql.extmeta.type",
5276 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5279 { &hf_mariadb_extmeta_format
,
5280 { "Extended metadata format", "mysql.extmeta.format",
5281 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5285 { "Salt", "mysql.salt",
5286 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5290 { "Salt", "mysql.salt2",
5291 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5294 { &hf_mysql_auth_plugin_length
,
5295 { "Authentication Plugin Length", "mysql.auth_plugin.length",
5296 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5299 { &hf_mysql_auth_plugin
,
5300 { "Authentication Plugin", "mysql.auth_plugin",
5301 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5304 { &hf_mysql_thread_id
,
5305 { "Thread ID", "mysql.thread_id",
5306 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5307 "MySQL Thread ID", HFILL
}},
5309 { &hf_mysql_server_language
,
5310 { "Server Language", "mysql.server_language",
5311 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &mysql_collation_vals_ext
, 0x0,
5312 "MySQL Charset", HFILL
}},
5314 { &hf_mariadb_server_language
,
5315 { "Server Language", "mariadb.server_language",
5316 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &mariadb_collation_vals_ext
, 0x0,
5317 "MySQL Charset", HFILL
}},
5319 { &hf_mysql_server_status
,
5320 { "Server Status", "mysql.server_status",
5321 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5322 "MySQL Status", HFILL
}},
5324 { &hf_mysql_stat_it
,
5325 { "In transaction", "mysql.stat.it",
5326 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_IT
,
5329 { &hf_mysql_stat_ac
,
5330 { "AUTO_COMMIT", "mysql.stat.ac",
5331 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_AC
,
5334 { &hf_mysql_stat_mr
,
5335 { "More results", "mysql.stat.mr",
5336 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_MR
,
5339 { &hf_mysql_stat_mu
,
5340 { "Multi query / Unused", "mysql.stat.mu",
5341 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_MU
,
5342 "Multi query / Unused with MySQL >= 5.6", HFILL
}},
5344 { &hf_mysql_stat_bi
,
5345 { "Bad index used", "mysql.stat.bi",
5346 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_BI
,
5349 { &hf_mysql_stat_ni
,
5350 { "No index used", "mysql.stat.ni",
5351 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_NI
,
5354 { &hf_mysql_stat_cr
,
5355 { "Cursor exists", "mysql.stat.cr",
5356 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_CR
,
5359 { &hf_mysql_stat_lr
,
5360 { "Last row sent", "mysql.stat.lr",
5361 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_LR
,
5364 { &hf_mysql_stat_dr
,
5365 { "Database dropped", "mysql.stat.dr",
5366 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_DR
,
5369 { &hf_mysql_stat_bs
,
5370 { "No backslash escapes", "mysql.stat.bs",
5371 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_BS
,
5374 { &hf_mysql_stat_mc
,
5375 { "Metadata changed", "mysql.stat.mc",
5376 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_MC
,
5379 { &hf_mysql_stat_session_state_changed
,
5380 { "Session state changed", "mysql.stat.session_state_changed",
5381 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_SESSION_STATE_CHANGED
,
5384 { &hf_mysql_stat_query_was_slow
,
5385 { "Query was slow", "mysql.stat.query_was_slow",
5386 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_QUERY_WAS_SLOW
,
5389 { &hf_mysql_stat_ps_out_params
,
5390 { "PS Out Params", "mysql.stat.ps_out_params",
5391 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_PS_OUT_PARAMS
,
5394 { &hf_mysql_stat_trans_readonly
,
5395 { "In Trans Readonly", "mysql.stat.trans_readonly",
5396 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_STAT_TRANS_READONLY
,
5399 { &hf_mysql_refresh
,
5400 { "Refresh Option", "mysql.refresh",
5401 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
5404 { &hf_mysql_rfsh_grants
,
5405 { "reload permissions", "mysql.rfsh.grants",
5406 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), MYSQL_RFSH_GRANT
,
5409 { &hf_mysql_rfsh_log
,
5410 { "flush logfiles", "mysql.rfsh.log",
5411 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), MYSQL_RFSH_LOG
,
5414 { &hf_mysql_rfsh_tables
,
5415 { "flush tables", "mysql.rfsh.tables",
5416 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), MYSQL_RFSH_TABLES
,
5419 { &hf_mysql_rfsh_hosts
,
5420 { "flush hosts", "mysql.rfsh.hosts",
5421 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), MYSQL_RFSH_HOSTS
,
5424 { &hf_mysql_rfsh_status
,
5425 { "reset statistics", "mysql.rfsh.status",
5426 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), MYSQL_RFSH_STATUS
,
5429 { &hf_mysql_rfsh_threads
,
5430 { "empty thread cache", "mysql.rfsh.threads",
5431 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), MYSQL_RFSH_THREADS
,
5434 { &hf_mysql_rfsh_slave
,
5435 { "flush slave status", "mysql.rfsh.slave",
5436 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), MYSQL_RFSH_SLAVE
,
5439 { &hf_mysql_rfsh_master
,
5440 { "flush master status", "mysql.rfsh.master",
5441 FT_BOOLEAN
, 8, TFS(&tfs_set_notset
), MYSQL_RFSH_MASTER
,
5445 { "Unused", "mysql.unused",
5446 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5450 { "Password", "mysql.passwd",
5451 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5454 { &hf_mysql_payload
,
5455 { "Payload", "mysql.payload",
5456 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5457 "Additional Payload", HFILL
}},
5459 { &hf_mysql_affected_rows
,
5460 { "Affected Rows", "mysql.affected_rows",
5461 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5464 { &hf_mysql_insert_id
,
5465 { "Last INSERT ID", "mysql.insert_id",
5466 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5469 { &hf_mysql_num_warn
,
5470 { "Warnings", "mysql.warnings",
5471 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5474 { &hf_mysql_stmt_id
,
5475 { "Statement ID", "mysql.stmt_id",
5476 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5479 { &hf_mysql_query_attributes
,
5480 { "Query Attributes", "mysql.query_attrs",
5481 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5484 { &hf_mysql_query_attributes_count
,
5485 { "Count", "mysql.query_attrs_count",
5486 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5489 { &hf_mysql_query_attributes_send_types_to_server
,
5490 { "Send types to server", "mysql.query_attrs_send_types_to_server",
5491 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5494 { &hf_mysql_query_attribute_name_type
,
5495 { "Attribute Name Type", "mysql.query_attr_name_type",
5496 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5499 { &hf_mysql_query_attribute_name
,
5500 { "Attribute Name", "mysql.query_attr_name",
5501 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5504 { &hf_mysql_query_attribute_value
,
5505 { "Attribute Value", "mysql.query_attr_value",
5506 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5510 { "Statement", "mysql.query",
5511 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5514 { &hf_mysql_shutdown
,
5515 { "Shutdown Level", "mysql.shutdown",
5516 FT_UINT8
, BASE_DEC
, VALS(mysql_shutdown_vals
), 0x0,
5520 { "Option", "mysql.option",
5521 FT_UINT16
, BASE_DEC
, VALS(mysql_option_vals
), 0x0,
5525 { "Parameter", "mysql.param",
5526 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5529 { &hf_mysql_param_name
,
5530 { "Name", "mysql.param_name",
5531 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5534 { &hf_mysql_num_params
,
5535 { "Number of parameter", "mysql.num_params",
5536 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5539 { &hf_mysql_num_rows
,
5540 { "Rows to fetch", "mysql.num_rows",
5541 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5544 { &hf_mysql_exec_flags4
,
5545 { "Flags (unused)", "mysql.exec_flags",
5546 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5549 { &hf_mysql_exec_flags5
,
5550 { "Flags", "mysql.exec_flags",
5551 FT_UINT8
, BASE_DEC
, VALS(mysql_exec_flags_vals
), 0x0,
5554 { &hf_mysql_new_parameter_bound_flag
,
5555 { "New parameter bound flag", "mysql.new_parameter_bound_flag",
5556 FT_UINT8
, BASE_DEC
, VALS(mysql_new_parameter_bound_flag_vals
), 0x0,
5559 { &hf_mysql_exec_iter
,
5560 { "Iterations (unused)", "mysql.exec_iter",
5561 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5564 { &hf_mysql_binlog_position
,
5565 { "Binlog Position", "mysql.binlog.position",
5566 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5567 "Position to start at", HFILL
}},
5569 { &hf_mysql_binlog_position8
,
5570 { "Binlog Position", "mysql.binlog.position8",
5571 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5572 "Position to start at", HFILL
}},
5574 { &hf_mysql_binlog_flags
,
5575 { "Binlog Flags", "mysql.binlog.flags",
5576 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5577 "(currently not used; always 0)", HFILL
}},
5579 { &hf_mysql_binlog_server_id
,
5580 { "Binlog server id", "mysql.binlog.server_id",
5581 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5582 "server_id of the slave", HFILL
}},
5584 { &hf_mysql_binlog_slave_hostname_length
,
5585 { "Slave hostname length", "mysql.binlog.slave_hostname_length",
5586 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5587 "slave_hostname field length", HFILL
}},
5589 { &hf_mysql_binlog_slave_hostname
,
5590 { "Slave hostname", "mysql.binlog.slave_hostname",
5591 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5592 "slave_hostname", HFILL
}},
5594 { &hf_mysql_binlog_slave_user_length
,
5595 { "Slave user length", "mysql.binlog.slave_user_length",
5596 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5597 "slave_hostname field length", HFILL
}},
5599 { &hf_mysql_binlog_slave_user
,
5600 { "Slave user", "mysql.binlog.slave_user",
5601 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5602 "slave_user", HFILL
}},
5604 { &hf_mysql_binlog_slave_password_length
,
5605 { "Slave password length", "mysql.binlog.slave_password_length",
5606 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5607 "slave_password field length", HFILL
}},
5609 { &hf_mysql_binlog_slave_password
,
5610 { "Slave password", "mysql.binlog.slave_password",
5611 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5612 "slave_password", HFILL
}},
5614 { &hf_mysql_binlog_slave_mysql_port
,
5615 { "Slave MySQL port", "mysql.binlog.slave_mysql_port",
5616 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
5617 "slave's mysql port", HFILL
}},
5619 { &hf_mysql_binlog_replication_rank
,
5620 { "Replication rank", "mysql.binlog.replication_rank",
5621 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5622 "ignored", HFILL
}},
5624 { &hf_mysql_binlog_master_id
,
5625 { "Master id", "mysql.binlog.master_id",
5626 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
5627 "master_id of the slave", HFILL
}},
5629 { &hf_mysql_binlog_file_name
,
5630 { "Binlog file name", "mysql.binlog.file_name",
5631 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
5634 { &hf_mysql_binlog_file_name_length
,
5635 { "Binlog file name length", "mysql.binlog.file_name_length",
5636 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5639 { &hf_mysql_binlog_gtid_data
,
5640 { "Binlog GTID Data", "mysql.binlog.gtid_data",
5641 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5644 { &hf_mysql_binlog_gtid_data_length
,
5645 { "Binlog file GTID data length", "mysql.binlog.gtid_data_length",
5646 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5649 { &hf_mysql_binlog_event_header_timestamp
,
5650 { "Timestamp", "mysql.binlog.event_header.timestamp",
5651 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0x0,
5654 { &hf_mysql_binlog_event_header_event_type
,
5655 { "Binlog Event Type", "mysql.binlog.event_header.event_type",
5656 FT_UINT8
, BASE_DEC
, VALS(mysql_binlog_event_type_vals
), 0x0,
5659 { &hf_mysql_binlog_event_header_server_id
,
5660 { "Server ID", "mysql.binlog.event_header.server_id",
5661 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5662 "server-id of the originating mysql-server", HFILL
}},
5664 { &hf_mysql_binlog_event_header_event_size
,
5665 { "Event Size", "mysql.binlog.event_header.event_size",
5666 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5667 "size of the event (header, post-header, body)", HFILL
}},
5669 { &hf_mysql_binlog_event_header_log_position
,
5670 { "Binlog Position", "mysql.binlog.event_header.log_position",
5671 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5672 "position of the next event", HFILL
}},
5674 { &hf_mysql_binlog_event_header_flags
,
5675 { "Binlog Event Flags", "mysql.binlog.event_header.flags",
5676 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5679 { &hf_mysql_binlog_event_checksum
,
5680 { "Checksum", "mysql.binlog.event_checksum",
5681 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
5682 "binlog event checksum", HFILL
}},
5684 { &hf_mysql_binlog_event_heartbeat_v2
,
5685 { "Binlog Event: HEARTBEAT_LOG_EVENT_V2", "mysql.binlog.event_heartbeat_v2",
5686 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5689 { &hf_mysql_binlog_event_heartbeat_v2_otw
,
5690 { "Entry", "mysql.binlog.event_heartbeat_v2_otw",
5691 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5694 { &hf_mysql_binlog_event_heartbeat_v2_otw_type
,
5695 { "Type", "mysql.binlog.event_heartbeat_v2_otw_type",
5696 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5699 { &hf_mysql_binlog_hb_event_filename
,
5700 { "Binlog Filename", "mysql.binlog.hb_event.filename",
5701 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5704 { &hf_mysql_binlog_hb_event_log_position
,
5705 { "Binlog Position", "mysql.binlog.hb_event.log_position",
5706 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5707 "position of the next event", HFILL
}},
5709 { &hf_mysql_clone_command_code
,
5710 { "Clone Command Code", "mysql.clone.command_code",
5711 FT_UINT8
, BASE_HEX
, VALS(mysql_clone_command_vals
), 0x0,
5714 { &hf_mysql_clone_response_code
,
5715 { "Clone Response Code", "mysql.clone.response_code",
5716 FT_UINT8
, BASE_HEX
, VALS(mysql_clone_response_vals
), 0x0,
5720 { "EOF marker", "mysql.eof",
5721 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5724 { &hf_mysql_num_fields
,
5725 { "Number of fields", "mysql.num_fields",
5726 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5729 { &hf_mariadb_send_meta
,
5730 { "send metadata", "mysql.metadata_follows",
5731 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5735 { "Extra data", "mysql.extra",
5736 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5739 { &hf_mysql_fld_catalog
,
5740 { "Catalog", "mysql.field.catalog",
5741 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5742 "Field: catalog", HFILL
}},
5745 { "Database", "mysql.field.db",
5746 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5747 "Field: database", HFILL
}},
5749 { &hf_mysql_fld_table
,
5750 { "Table", "mysql.field.table",
5751 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5752 "Field: table", HFILL
}},
5754 { &hf_mysql_fld_org_table
,
5755 { "Original table", "mysql.field.org_table",
5756 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5757 "Field: original table", HFILL
}},
5759 { &hf_mysql_fld_name
,
5760 { "Name", "mysql.field.name",
5761 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5762 "Field: name", HFILL
}},
5764 { &hf_mysql_fld_org_name
,
5765 { "Original name", "mysql.field.org_name",
5766 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5767 "Field: original name", HFILL
}},
5769 { &hf_mysql_fld_charsetnr
,
5770 { "Charset number", "mysql.field.charsetnr",
5771 FT_UINT16
, BASE_DEC
|BASE_EXT_STRING
, &mysql_collation_vals_ext
, 0x0,
5772 "Field: charset number", HFILL
}},
5774 //{ &hf_mariadb_fld_charsetnr,
5775 //{ "Charset number", "mariadb.field.charsetnr",
5776 //FT_UINT16, BASE_DEC|BASE_EXT_STRING, &mariadb_collation_vals_ext, 0x0,
5777 //"Field: charset number", HFILL }},
5779 { &hf_mysql_fld_length
,
5780 { "Length", "mysql.field.length",
5781 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5782 "Field: length", HFILL
}},
5784 { &hf_mysql_fld_type
,
5785 { "Type", "mysql.field.type",
5786 FT_UINT8
, BASE_DEC
, VALS(type_constants
), 0x0,
5787 "Field: type", HFILL
}},
5789 { &hf_mysql_fld_flags
,
5790 { "Flags", "mysql.field.flags",
5791 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
5792 "Field: flags", HFILL
}},
5794 { &hf_mysql_fld_not_null
,
5795 { "Not null", "mysql.field.flags.not_null",
5796 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_NOT_NULL_FLAG
,
5797 "Field: flag not null", HFILL
}},
5799 { &hf_mysql_fld_primary_key
,
5800 { "Primary key", "mysql.field.flags.primary_key",
5801 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_PRI_KEY_FLAG
,
5802 "Field: flag primary key", HFILL
}},
5804 { &hf_mysql_fld_unique_key
,
5805 { "Unique key", "mysql.field.flags.unique_key",
5806 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_UNIQUE_KEY_FLAG
,
5807 "Field: flag unique key", HFILL
}},
5809 { &hf_mysql_fld_multiple_key
,
5810 { "Multiple key", "mysql.field.flags.multiple_key",
5811 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_MULTIPLE_KEY_FLAG
,
5812 "Field: flag multiple key", HFILL
}},
5814 { &hf_mysql_fld_blob
,
5815 { "Blob", "mysql.field.flags.blob",
5816 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_BLOB_FLAG
,
5817 "Field: flag blob", HFILL
}},
5819 { &hf_mysql_fld_unsigned
,
5820 { "Unsigned", "mysql.field.flags.unsigned",
5821 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_UNSIGNED_FLAG
,
5822 "Field: flag unsigned", HFILL
}},
5824 { &hf_mysql_fld_zero_fill
,
5825 { "Zero fill", "mysql.field.flags.zero_fill",
5826 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_ZEROFILL_FLAG
,
5827 "Field: flag zero fill", HFILL
}},
5829 { &hf_mysql_null_buffer
,
5830 { "Row null buffer", "mysql.row.nullbuffer",
5831 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5834 { &hf_mysql_fld_enum
,
5835 { "Enum", "mysql.field.flags.enum",
5836 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_ENUM_FLAG
,
5837 "Field: flag enum", HFILL
}},
5839 { &hf_mysql_fld_auto_increment
,
5840 { "Auto increment", "mysql.field.flags.auto_increment",
5841 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_AUTO_INCREMENT_FLAG
,
5842 "Field: flag auto increment", HFILL
}},
5844 { &hf_mysql_fld_timestamp
,
5845 { "Timestamp", "mysql.field.flags.timestamp",
5846 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_TIMESTAMP_FLAG
,
5847 "Field: flag timestamp", HFILL
}},
5849 { &hf_mysql_fld_set
,
5850 { "Set", "mysql.field.flags.set",
5851 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MYSQL_FLD_SET_FLAG
,
5852 "Field: flag set", HFILL
}},
5854 { &hf_mysql_fld_decimals
,
5855 { "Decimals", "mysql.field.decimals",
5856 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5857 "Field: decimals", HFILL
}},
5859 { &hf_mysql_fld_default
,
5860 { "Default", "mysql.field.default",
5861 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5862 "Field: default", HFILL
}},
5864 { &hf_mysql_row_text
,
5865 { "text", "mysql.row.text",
5866 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5867 "Field: row packet text", HFILL
}},
5869 { &hf_mysql_exec_param
,
5870 { "Parameter", "mysql.exec_param",
5871 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5874 { &hf_mysql_exec_unsigned
,
5875 { "Unsigned", "mysql.exec.unsigned",
5876 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5879 { &hf_mysql_exec_field_longlong
,
5880 { "Value (INT64)", "mysql.exec.field.longlong",
5881 FT_INT64
, BASE_DEC
, NULL
, 0x0,
5884 { &hf_mysql_exec_field_unsigned_longlong
,
5885 { "Value (UINT64)", "mysql.exec.field.unsigned_longlong",
5886 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
5889 { &hf_mysql_exec_field_bit_length
,
5890 { "Length (Bit)", "mysql.exec.field.bit.length",
5891 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
5894 { &hf_mysql_exec_field_bit
,
5895 { "Value (Bit)", "mysql.exec.field.bit",
5896 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5899 { &hf_mysql_exec_field_blob_length
,
5900 { "Length (BLOB)", "mysql.exec.field.blob.length",
5901 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
5904 { &hf_mysql_exec_field_blob
,
5905 { "Value (BLOB)", "mysql.exec.field.blob",
5906 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5909 { &hf_mysql_exec_field_geometry_length
,
5910 { "Length (Geometry)", "mysql.exec.field.geometry.length",
5911 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
5914 { &hf_mysql_exec_field_geometry
,
5915 { "Value (Geometry)", "mysql.exec.field.geometry",
5916 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5919 { &hf_mysql_exec_field_json_length
,
5920 { "Length (JSON)", "mysql.exec.field.json.length",
5921 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
5924 { &hf_mysql_exec_field_string_length
,
5925 { "Length (String)", "mysql.exec.field.string.length",
5926 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
5929 { &hf_mysql_exec_field_string
,
5930 { "Value (String)", "mysql.exec.field.string",
5931 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5934 { &hf_mysql_exec_field_double
,
5935 { "Value (Double)", "mysql.exec.field.double",
5936 FT_DOUBLE
, BASE_NONE
, NULL
, 0x0,
5939 { &hf_mysql_exec_field_datetime_length
,
5940 { "Length", "mysql.exec.field.datetime.length",
5941 FT_INT8
, BASE_DEC
, NULL
, 0x0,
5944 { &hf_mysql_exec_field_year
,
5945 { "Year", "mysql.exec.field.year",
5946 FT_INT16
, BASE_DEC
, NULL
, 0x0,
5949 { &hf_mysql_exec_field_month
,
5950 { "Month", "mysql.exec.field.month",
5951 FT_INT8
, BASE_DEC
, NULL
, 0x0,
5954 { &hf_mysql_exec_field_day
,
5955 { "Day", "mysql.exec.field.day",
5956 FT_INT8
, BASE_DEC
, NULL
, 0x0,
5959 { &hf_mysql_exec_field_hour
,
5960 { "Hour", "mysql.exec.field.hour",
5961 FT_INT8
, BASE_DEC
, NULL
, 0x0,
5964 { &hf_mysql_exec_field_minute
,
5965 { "Minute", "mysql.exec.field.minute",
5966 FT_INT8
, BASE_DEC
, NULL
, 0x0,
5969 { &hf_mysql_exec_field_second
,
5970 { "Second", "mysql.exec.field.second",
5971 FT_INT8
, BASE_DEC
, NULL
, 0x0,
5974 { &hf_mysql_exec_field_second_b
,
5975 { "Billionth of a second", "mysql.exec.field.secondb",
5976 FT_INT32
, BASE_DEC
, NULL
, 0x0,
5979 { &hf_mysql_exec_field_int24
,
5980 { "Value (INT24)", "mysql.exec.field.int24",
5981 FT_INT32
, BASE_DEC
, NULL
, 0x0,
5984 { &hf_mysql_exec_field_long
,
5985 { "Value (INT32)", "mysql.exec.field.long",
5986 FT_INT32
, BASE_DEC
, NULL
, 0x0,
5989 { &hf_mysql_exec_field_unsigned_long
,
5990 { "Value (UINT32)", "mysql.exec.field.unsigned_long",
5991 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5994 { &hf_mysql_exec_field_tiny
,
5995 { "Value (INT8)", "mysql.exec.field.tiny",
5996 FT_INT8
, BASE_DEC
, NULL
, 0x0,
5999 { &hf_mysql_exec_field_unsigned_tiny
,
6000 { "Value (UINT8)", "mysql.exec.field.unsigned_tiny",
6001 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
6004 { &hf_mysql_exec_field_short
,
6005 { "Value (INT16)", "mysql.exec.field.short",
6006 FT_INT16
, BASE_DEC
, NULL
, 0x0,
6009 { &hf_mysql_exec_field_unsigned_short
,
6010 { "Value (UINT16)", "mysql.exec.field.unsigned_short",
6011 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
6014 { &hf_mysql_exec_field_float
,
6015 { "Value (Float)", "mysql.exec.field.float",
6016 FT_FLOAT
, BASE_NONE
, NULL
, 0x0,
6019 { &hf_mysql_exec_field_null
,
6020 { "Value: -NULL-", "mysql.exec.field.null",
6021 FT_NONE
, BASE_NONE
, NULL
, 0x0,
6024 { &hf_mysql_exec_field_time_length
,
6025 { "Length", "mysql.exec.field.time.length",
6026 FT_INT8
, BASE_DEC
, NULL
, 0x0,
6029 { &hf_mysql_exec_field_time_sign
,
6030 { "Flags", "mysql.exec.field.time.sign",
6031 FT_UINT8
, BASE_DEC
, VALS(mysql_exec_time_sign_vals
), 0x0,
6034 { &hf_mysql_exec_field_time_days
,
6035 { "Days", "mysql.exec.field.time.days",
6036 FT_INT32
, BASE_DEC
, NULL
, 0x0,
6039 { &hf_mysql_auth_switch_request_status
,
6040 { "Status", "mysql.auth_switch_request.status",
6041 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
6044 { &hf_mysql_auth_switch_request_name
,
6045 { "Auth Method Name", "mysql.auth_switch_request.name",
6046 FT_STRING
, BASE_NONE
, NULL
, 0x0,
6049 { &hf_mysql_auth_switch_request_data
,
6050 { "Auth Method Data", "mysql.auth_switch_request.data",
6051 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
6054 { &hf_mysql_auth_switch_response_data
,
6055 { "Auth Method Data", "mysql.auth_switch_response.data",
6056 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
6059 { &hf_mysql_sha2_auth
,
6060 { "SHA2 Auth State", "mysql.hf_mysql_sha2_auth.name",
6061 FT_STRING
, BASE_NONE
, NULL
, 0x0,
6065 { "Public Key", "mysql.hf_mysql_pubkey",
6066 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
6069 { &hf_mysql_sha2_response
,
6070 { "SHA2 Auth Response", "mysql.hf_mysql_sha2_response",
6071 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
6074 { &hf_mysql_compressed_packet_length
,
6075 { "Compressed Packet Length", "mysql.compressed_packet_length",
6076 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
6079 { &hf_mysql_compressed_packet_number
,
6080 { "Compressed Packet Number", "mysql.compressed_packet_number",
6081 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
6084 { &hf_mysql_compressed_packet_length_uncompressed
,
6085 { "Uncompressed Packet Length", "mysql.compressed_packet_length_uncompressed",
6086 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
6089 { &hf_mysql_loaddata_filename
,
6090 { "LOCAL INFILE Filename", "mysql.load_data.filename",
6091 FT_STRING
, BASE_NONE
, NULL
, 0x0,
6094 { &hf_mysql_loaddata_payload
,
6095 { "LOCAL INFILE Payload", "mysql.load_data.payload",
6096 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
6099 { &hf_mariadb_cap_progress
,
6100 { "Progress indication", "mariadb.caps.pr",
6101 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), MARIADB_CAPS_PR
,
6104 { &hf_mariadb_cap_commulti
,
6105 { "Multi commands", "mariadb.caps.cm",
6106 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), MARIADB_CAPS_CM
,
6109 { &hf_mariadb_cap_bulk
,
6110 { "Bulk Operations", "mariadb.caps.bo",
6111 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), MARIADB_CAPS_BO
,
6114 { &hf_mariadb_cap_extmetadata
,
6115 { "Extended metadata", "mariadb.caps.em",
6116 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), MARIADB_CAPS_EM
,
6119 { &hf_mariadb_cap_cache_metadata
,
6120 { "Cache metadata", "mariadb.caps.me",
6121 FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), MARIADB_CAPS_ME
,
6124 { &hf_mariadb_extcaps_server
,
6125 { "MariaDB Extended Server Capabilities", "mariadb.extcaps.server",
6126 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
6129 { &hf_mariadb_extcaps_client
,
6130 { "MariaDB Extended Client Capabilities", "mariadb.extcaps.client",
6131 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
6134 { &hf_mariadb_bulk_flag_autoid
,
6135 { "Return Generated Autoincrement IDs", "mariadb.bulk.flag.autoid",
6136 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MARIADB_BULK_AUTOID
,
6139 { &hf_mariadb_bulk_flag_sendtypes
,
6140 { "Send Parameter Types", "mariadb.bulk.flag.sendtypes",
6141 FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), MARIADB_BULK_SEND_TYPES
,
6144 { &hf_mariadb_bulk_caps_flags
,
6145 { "MariaDB Bulk Capabilities", "mariadb.bulk.flags",
6146 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
6149 { &hf_mariadb_bulk_paramtypes
,
6150 { "Bulk Parameter Types", "mariadb.bulk.paramtypesg",
6151 FT_NONE
, BASE_NONE
, NULL
, 0x0,
6154 { &hf_mariadb_bulk_indicator
,
6155 { "Indicator", "mariadb.bulk.indicators",
6156 FT_UINT8
, BASE_HEX
, VALS(mariadb_bulk_indicator_vals
), 0x00,
6159 { &hf_mariadb_bulk_row_nr
,
6160 { "Row nr", "mariadb.bulk.row_nr",
6161 FT_UINT32
, BASE_DEC
, NULL
, 0x00,
6164 { &hf_mysql_fragments
,
6165 { "Reassembled MySQL fragments", "mysql.fragments",
6166 FT_NONE
, BASE_NONE
, NULL
, 0x0,
6169 { &hf_mysql_fragment
,
6170 { "MySQL fragment", "mysql.fragment",
6171 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
6174 { &hf_mysql_fragment_overlap
,
6175 { "Fragment overlap", "mysql.fragment.overlap",
6176 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6179 { &hf_mysql_fragment_overlap_conflicts
,
6180 { "Conflicting data in fragment overlap", "mysql.fragment.overlap.conflicts",
6181 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6184 { &hf_mysql_fragment_multiple_tails
,
6185 { "Multiple tail fragments found", "mysql.fragment.multiple_tails",
6186 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x00,
6189 { &hf_mysql_fragment_too_long_fragment
,
6190 { "Fragment too long", "mysql.fragment.too_long_fragment",
6191 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
6194 { &hf_mysql_fragment_error
,
6195 { "Defragmentation error", "mysql.fragment.error",
6196 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
6199 { &hf_mysql_fragment_count
,
6200 { "Fragment count", "mysql.fragment.count",
6201 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
6204 { &hf_mysql_reassembled_in
,
6205 { "Reassembled in", "mysql.reassembled.in",
6206 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
6209 { &hf_mysql_reassembled_length
,
6210 { "Reassembled length", "mysql.reassembled.length",
6211 FT_UINT32
, BASE_DEC
, NULL
, 0x00, NULL
, HFILL
} },
6213 { &hf_mysql_fragment_data
,
6214 { "MySQL fragment data", "mysql.fragment.data",
6215 FT_BYTES
, BASE_NONE
, NULL
, 0x00, NULL
, HFILL
} },
6222 &ett_server_greeting
,
6234 &ett_session_track_data
,
6238 &ett_connattrs_attr
,
6240 &ett_query_attributes
,
6242 &ett_binlog_event_hb_v2
,
6243 &ett_mysql_fragment
,
6244 &ett_mysql_fragments
,
6245 &ett_mysql_binary_field
,
6248 static ei_register_info ei
[] = {
6249 { &ei_mysql_dissector_incomplete
, { "mysql.dissector_incomplete", PI_UNDECODED
, PI_WARN
, "FIXME - dissector is incomplete", EXPFILL
}},
6250 { &ei_mysql_streamed_param
, { "mysql.streamed_param", PI_SEQUENCE
, PI_CHAT
, "This parameter was streamed, its value can be found in Send BLOB packets", EXPFILL
}},
6251 { &ei_mysql_prepare_response_needed
, { "mysql.prepare_response_needed", PI_UNDECODED
, PI_WARN
, "PREPARE Response packet is needed to dissect the payload", EXPFILL
}},
6252 { &ei_mysql_command
, { "mysql.command.invalid", PI_PROTOCOL
, PI_WARN
, "Unknown/invalid command code", EXPFILL
}},
6253 { &ei_mysql_unknown_response
, { "mysql.unknown_response", PI_UNDECODED
, PI_WARN
, "unknown/invalid response", EXPFILL
}},
6254 { &ei_mysql_invalid_length
, { "mysql.invalid_length", PI_MALFORMED
, PI_ERROR
, "Invalid length", EXPFILL
}},
6255 { &ei_mysql_compression
, { "mysql.uncompress_failure", PI_MALFORMED
, PI_WARN
, "Uncompression failed", EXPFILL
}},
6258 module_t
*mysql_module
;
6259 expert_module_t
* expert_mysql
;
6261 proto_mysql
= proto_register_protocol("MySQL Protocol", "MySQL", "mysql");
6262 proto_register_field_array(proto_mysql
, hf
, array_length(hf
));
6263 proto_register_subtree_array(ett
, array_length(ett
));
6264 expert_mysql
= expert_register_protocol(proto_mysql
);
6265 expert_register_field_array(expert_mysql
, ei
, array_length(ei
));
6267 mysql_module
= prefs_register_protocol(proto_mysql
, NULL
);
6268 prefs_register_bool_preference(mysql_module
, "desegment_buffers",
6269 "Reassemble MySQL buffers spanning multiple TCP segments",
6270 "Whether the MySQL dissector should reassemble MySQL buffers spanning multiple TCP segments."
6271 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
6273 prefs_register_bool_preference(mysql_module
, "show_sql_query",
6274 "Show SQL Query string in INFO column",
6275 "Whether the MySQL dissector should display the SQL query string in the INFO column.",
6278 reassembly_table_register(&mysql_reassembly_table
,
6279 &addresses_ports_reassembly_table_functions
);
6280 mysql_handle
= register_dissector("mysql", dissect_mysql
, proto_mysql
);
6283 /* dissector registration */
6284 void proto_reg_handoff_mysql(void)
6286 tls_handle
= find_dissector("tls");
6287 decompressed_handle
= create_dissector_handle(dissect_mysql_decompressed_pdus
, proto_mysql
);
6288 dissector_add_uint_with_preference("tcp.port", TCP_PORT_MySQL
, mysql_handle
);
6292 * Editor modelines - https://www.wireshark.org/tools/modelines.html
6297 * indent-tabs-mode: t
6300 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
6301 * :indentSize=8:tabSize=8:noTabs=false: