From 2894ae38d01a38b6fd305533b2fce62193998baa Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Tue, 9 Jul 2024 13:23:44 +0200 Subject: [PATCH] mysql: Support non-string query attributes The query attributes aren't exposed to script layer right now, but this should at least parse over them once encountered and some fixups. --- .../protocol/mysql/mysql-protocol.pac | 144 ++++++++++++++++-- .../mysql.log | 54 +++++++ .../out | 132 ++++++++++++++++ .../mysql.log | 14 ++ .../out | 10 ++ .../btest/Traces/mysql/many-query-attrs.pcap | Bin 0 -> 37064 bytes .../base/protocols/mysql/many-query-attr.test | 35 +++++ .../mysql/query-attr-non-string.test | 35 +++++ 8 files changed, 412 insertions(+), 12 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/mysql.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/out create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/mysql.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/out create mode 100644 testing/btest/Traces/mysql/many-query-attrs.pcap create mode 100644 testing/btest/scripts/base/protocols/mysql/many-query-attr.test create mode 100644 testing/btest/scripts/base/protocols/mysql/query-attr-non-string.test diff --git a/src/analyzer/protocol/mysql/mysql-protocol.pac b/src/analyzer/protocol/mysql/mysql-protocol.pac index c992927b37..bc350c747c 100644 --- a/src/analyzer/protocol/mysql/mysql-protocol.pac +++ b/src/analyzer/protocol/mysql/mysql-protocol.pac @@ -173,6 +173,85 @@ enum Client_Capabilities { CLIENT_QUERY_ATTRIBUTES = 0x08000000, }; +# Binary Protocol Resultset encoding. +# +# https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_binary_resultset.html +# +# Values taken from here: https://dev.mysql.com/doc/dev/mysql-server/latest/namespaceclassic__protocol_1_1field__type.html +enum field_types { + TYPE_DECIMAL = 0x00, + TYPE_TINY = 0x01, + TYPE_SHORT = 0x02, + TYPE_LONG = 0x03, + TYPE_FLOAT = 0x04, + TYPE_DOUBLE = 0x05, + TYPE_NULL = 0x06, + TYPE_TIMESTAMP = 0x07, + TYPE_LONGLONG = 0x08, + TYPE_INT24 = 0x09, + TYPE_DATE = 0x0a, + TYPE_TIME = 0x0b, + TYPE_DATETIME = 0x0c, + TYPE_YEAR = 0x0d, + TYPE_VARCHAR = 0x0f, + TYPE_BIT = 0x10, + TYPE_TIMESTAMP2 = 0x11, + TYPE_JSON = 0xf5, + TYPE_NEWDECIMAL = 0xf6, + TYPE_ENUM = 0xf7, + TYPE_SET = 0xf8, + TYPE_TINYBLOB = 0xf9, + TYPE_MEDIUMBLOB = 0xfa, + TYPE_LONGBLOB = 0xfb, + TYPE_BLOB = 0xfc, + TYPE_VARSTRING = 0xfd, + TYPE_STRING = 0xfe, + TYPE_GEOMETRY = 0xff, +}; + +type BinaryDate = record { + len: uint8 &enforce(len == 0 || len == 4 || len == 7 || len == 11); + not_implemented: bytestring &length=len; +}; + +type BinaryTime = record { + len: uint8 &enforce(len == 0 || len == 8 || len == 12); + not_implemented: bytestring &length=len; +}; + +type BinaryValue(type: uint16) = record { + value: case ( type ) of { + TYPE_DECIMAL -> decimal_val: LengthEncodedInteger; + TYPE_TINY -> tiny_val: int8; + TYPE_SHORT -> short_val: int16; + TYPE_LONG -> long_val: int32; + TYPE_FLOAT -> float_val: bytestring &length=4; + TYPE_DOUBLE -> double_val: bytestring &length=8; + TYPE_NULL -> null_val: empty; # in null_bitmap + TYPE_TIMESTAMP -> timestamp_val: BinaryDate; + TYPE_LONGLONG -> longlong_val: int64; + TYPE_INT24 -> int24_val: int32; + TYPE_DATE -> date_val: BinaryDate; + TYPE_TIME -> time_val: BinaryTime; + TYPE_DATETIME -> datetime_val: BinaryDate; + TYPE_YEAR -> year_val: int16; + TYPE_VARCHAR -> varchar_val: LengthEncodedString; + TYPE_BIT -> bit_val: LengthEncodedString; + TYPE_TIMESTAMP2 -> timestamp2_val: BinaryDate; + TYPE_JSON -> json_val: LengthEncodedString; + TYPE_NEWDECIMAL -> newdecimal_val: LengthEncodedString; + TYPE_ENUM -> enum_val: LengthEncodedString; + TYPE_SET -> set_val: LengthEncodedString; + TYPE_TINYBLOB -> tinyblob_val: LengthEncodedString; + TYPE_MEDIUMBLOB -> mediumblob_val: LengthEncodedString; + TYPE_LONGBLOB -> longblob_val: LengthEncodedString; + TYPE_BLOB -> blob_val: LengthEncodedString; + TYPE_VARSTRING -> varstring_val: LengthEncodedString; + TYPE_STRING -> string_val: LengthEncodedString; + TYPE_GEOMETRY -> geometry_val: LengthEncodedString; + }; +}; + type NUL_String = RE/[^\0]*\0/; type EmptyOrNUL_String = RE/([^\0]*\0)?/; @@ -335,29 +414,51 @@ type Connection_Phase_Packets = case $context.connection.get_conn_expectation() EXPECT_AUTH_DATA -> auth_data: AuthMoreData(true); }; -# Command Request - +# Query attribute handling for COM_QUERY +# type AttributeTypeAndName = record { - type: uint16; + type: uint8; + unsigned_flag: uint8; name: LengthEncodedString; }; -type Attributes(count: uint8) = record { - unused : uint8; - send_types_to_server: uint8; # Always 1. +type AttributeValue(is_null: bool, type: uint8) = record { + null: case is_null of { + false -> val: BinaryValue(type); + true -> null_val: empty; + }; +} &let { + # Move parsing the next query attribute. + done = $context.connection.next_query_attr(); +}; + +type Attributes(count: int) = record { + null_bitmap : bytestring &length=(count + 7) / 8; + send_types_to_server: uint8 &enforce(send_types_to_server == 1); names : AttributeTypeAndName[count]; - values : LengthEncodedString[count]; + values : AttributeValue( + # Check if null_bitmap contains this attribute index. This + # will pass true if the attribute value is NULL and parsing + # skipped in AttributeValue above. + (null_bitmap[$context.connection.query_attr_idx() / 8] >> ($context.connection.query_attr_idx() % 8)) & 0x01, + names[$context.connection.query_attr_idx()].type + )[] &until($context.connection.query_attr_idx() >= count); }; type Query_Attributes = record { - count : uint8; - set_coun : uint8; - have_attr : case ( count > 0 ) of { - true -> attrs: Attributes(count); + count : LengthEncodedInteger; + set_count: LengthEncodedInteger; + have_attr: case ( attr_count > 0 ) of { + true -> attrs: Attributes(attr_count); false -> none: empty; - }; + } &requires(new_query_attrs); +} &let { + attr_count: int = to_int()(count); + new_query_attrs = $context.connection.new_query_attrs(); }; +# Command Request + type Command_Request_Packet = record { command: uint8; attrs : case ( command == COM_QUERY && $context.connection.get_client_query_attrs() && $context.connection.get_server_query_attrs() ) of { @@ -554,6 +655,7 @@ refine connection MySQL_Conn += { bool server_query_attrs_; bool client_query_attrs_; std::string auth_plugin_; + int query_attr_idx_; %} %init{ @@ -568,6 +670,7 @@ refine connection MySQL_Conn += { deprecate_eof_ = false; server_query_attrs_ = false; client_query_attrs_ = false; + query_attr_idx_ = 0; %} function get_version(): uint8 @@ -825,4 +928,21 @@ refine connection MySQL_Conn += { ++results_seen_; return true; %} + + function query_attr_idx(): int + %{ + return query_attr_idx_; + %} + + function new_query_attrs(): bool + %{ + query_attr_idx_ = 0; + return true; + %} + + function next_query_attr(): bool + %{ + query_attr_idx_++; + return true; + %} }; diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/mysql.log b/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/mysql.log new file mode 100644 index 0000000000..1f6d2899e8 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/mysql.log @@ -0,0 +1,54 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path mysql +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd arg success rows response +#types time string addr port addr port string string bool count string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 login root T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 query show databases T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 query show tables T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list columns_priv T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list component T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list db T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list default_roles T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list engine_cost T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list func T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list general_log T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list global_grants T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list gtid_executed T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list help_category T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list help_keyword T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list help_relation T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list help_topic T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list innodb_index_stats T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list innodb_table_stats T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list ndb_binlog_index T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list password_history T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list plugin T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list procs_priv T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list proxies_priv T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list replication_asynchronous_connection_failover T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list replication_asynchronous_connection_failover_managed T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list replication_group_configuration_version T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list replication_group_member_actions T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list role_edges T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list server_cost T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list servers T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list slave_master_info T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list slave_relay_log_info T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list slave_worker_info T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list slow_log T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list tables_priv T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone_leap_second T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone_name T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone_transition T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list time_zone_transition_type T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 field_list user T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 query select @@version_comment limit 1 T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 query SELECT mysql_query_attribute_string('n1'), mysql_query_attribute_string('n2') T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33592 127.0.0.1 3306 quit (empty) - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/out b/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/out new file mode 100644 index 0000000000..a064e5f357 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.many-query-attr/out @@ -0,0 +1,132 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql handshake, root +mysql ok, 0 +mysql request, 3, show databases +mysql result row, [information_schema] +mysql result row, [mysql] +mysql result row, [performance_schema] +mysql result row, [sys] +mysql ok, 0 +mysql request, 3, show tables +mysql result row, [columns_priv] +mysql result row, [component] +mysql result row, [db] +mysql result row, [default_roles] +mysql result row, [engine_cost] +mysql result row, [func] +mysql result row, [general_log] +mysql result row, [global_grants] +mysql result row, [gtid_executed] +mysql result row, [help_category] +mysql result row, [help_keyword] +mysql result row, [help_relation] +mysql result row, [help_topic] +mysql result row, [innodb_index_stats] +mysql result row, [innodb_table_stats] +mysql result row, [ndb_binlog_index] +mysql result row, [password_history] +mysql result row, [plugin] +mysql result row, [procs_priv] +mysql result row, [proxies_priv] +mysql result row, [replication_asynchronous_connection_failover] +mysql result row, [replication_asynchronous_connection_failover_managed] +mysql result row, [replication_group_configuration_version] +mysql result row, [replication_group_member_actions] +mysql result row, [role_edges] +mysql result row, [server_cost] +mysql result row, [servers] +mysql result row, [slave_master_info] +mysql result row, [slave_relay_log_info] +mysql result row, [slave_worker_info] +mysql result row, [slow_log] +mysql result row, [tables_priv] +mysql result row, [time_zone] +mysql result row, [time_zone_leap_second] +mysql result row, [time_zone_name] +mysql result row, [time_zone_transition] +mysql result row, [time_zone_transition_type] +mysql result row, [user] +mysql ok, 0 +mysql request, 4, columns_priv\x00 +mysql ok, 0 +mysql request, 4, component\x00 +mysql ok, 0 +mysql request, 4, db\x00 +mysql ok, 0 +mysql request, 4, default_roles\x00 +mysql ok, 0 +mysql request, 4, engine_cost\x00 +mysql ok, 0 +mysql request, 4, func\x00 +mysql ok, 0 +mysql request, 4, general_log\x00 +mysql ok, 0 +mysql request, 4, global_grants\x00 +mysql ok, 0 +mysql request, 4, gtid_executed\x00 +mysql ok, 0 +mysql request, 4, help_category\x00 +mysql ok, 0 +mysql request, 4, help_keyword\x00 +mysql ok, 0 +mysql request, 4, help_relation\x00 +mysql ok, 0 +mysql request, 4, help_topic\x00 +mysql ok, 0 +mysql request, 4, innodb_index_stats\x00 +mysql ok, 0 +mysql request, 4, innodb_table_stats\x00 +mysql ok, 0 +mysql request, 4, ndb_binlog_index\x00 +mysql ok, 0 +mysql request, 4, password_history\x00 +mysql ok, 0 +mysql request, 4, plugin\x00 +mysql ok, 0 +mysql request, 4, procs_priv\x00 +mysql ok, 0 +mysql request, 4, proxies_priv\x00 +mysql ok, 0 +mysql request, 4, replication_asynchronous_connection_failover\x00 +mysql ok, 0 +mysql request, 4, replication_asynchronous_connection_failover_managed\x00 +mysql ok, 0 +mysql request, 4, replication_group_configuration_version\x00 +mysql ok, 0 +mysql request, 4, replication_group_member_actions\x00 +mysql ok, 0 +mysql request, 4, role_edges\x00 +mysql ok, 0 +mysql request, 4, server_cost\x00 +mysql ok, 0 +mysql request, 4, servers\x00 +mysql ok, 0 +mysql request, 4, slave_master_info\x00 +mysql ok, 0 +mysql request, 4, slave_relay_log_info\x00 +mysql ok, 0 +mysql request, 4, slave_worker_info\x00 +mysql ok, 0 +mysql request, 4, slow_log\x00 +mysql ok, 0 +mysql request, 4, tables_priv\x00 +mysql ok, 0 +mysql request, 4, time_zone\x00 +mysql ok, 0 +mysql request, 4, time_zone_leap_second\x00 +mysql ok, 0 +mysql request, 4, time_zone_name\x00 +mysql ok, 0 +mysql request, 4, time_zone_transition\x00 +mysql ok, 0 +mysql request, 4, time_zone_transition_type\x00 +mysql ok, 0 +mysql request, 4, user\x00 +mysql ok, 0 +mysql request, 3, select @@version_comment limit 1 +mysql result row, [MySQL Community Server - GPL] +mysql ok, 0 +mysql request, 3, SELECT mysql_query_attribute_string('n1'), mysql_query_attribute_string('n2') +mysql result row, [42, v2] +mysql ok, 0 +mysql request, 1, diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/mysql.log b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/mysql.log new file mode 100644 index 0000000000..8ae14a6dc2 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/mysql.log @@ -0,0 +1,14 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path mysql +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p cmd arg success rows response +#types time string addr port addr port string string bool count string +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33754 127.0.0.1 3306 login root T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33754 127.0.0.1 3306 ping (empty) T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33754 127.0.0.1 3306 query SELECT version() T 0 - +XXXXXXXXXX.XXXXXX CHhAvVGS1DHFjwGM9 127.0.0.1 33754 127.0.0.1 3306 quit (empty) - - - +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/out b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/out new file mode 100644 index 0000000000..0924f49140 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.mysql.query-attr-non-string/out @@ -0,0 +1,10 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +mysql handshake, root +mysql ok, 0 +mysql request, 14, +mysql ok, 0 +mysql request, 3, SELECT version() +mysql eof, T +mysql result row, [9.0.0] +mysql eof, F +mysql request, 1, diff --git a/testing/btest/Traces/mysql/many-query-attrs.pcap b/testing/btest/Traces/mysql/many-query-attrs.pcap new file mode 100644 index 0000000000000000000000000000000000000000..175e5a9644a21ad189cec7b03f14385249267f02 GIT binary patch literal 37064 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≈0df` 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 H`0D=vR>j^i literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/mysql/many-query-attr.test b/testing/btest/scripts/base/protocols/mysql/many-query-attr.test new file mode 100644 index 0000000000..5ff2e4cb92 --- /dev/null +++ b/testing/btest/scripts/base/protocols/mysql/many-query-attr.test @@ -0,0 +1,35 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/mysql/many-query-attrs.pcap %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff mysql.log + +@load base/protocols/mysql + +event mysql_ok(c: connection, affected_rows: count) + { + print "mysql ok", affected_rows; + } + +event mysql_eof(c: connection, is_intermediate: bool) + { + print "mysql eof", is_intermediate; + } + +event mysql_result_row(c: connection, row: string_vec) + { + print "mysql result row", row; + } + +event mysql_error(c: connection, code: count, msg: string) + { + print "mysql error", code, msg; + } + +event mysql_command_request(c: connection, command: count, arg: string) + { + print "mysql request", command, arg; + } + +event mysql_handshake(c: connection, username: string) + { + print "mysql handshake", username; + } diff --git a/testing/btest/scripts/base/protocols/mysql/query-attr-non-string.test b/testing/btest/scripts/base/protocols/mysql/query-attr-non-string.test new file mode 100644 index 0000000000..ef6ef4d8b7 --- /dev/null +++ b/testing/btest/scripts/base/protocols/mysql/query-attr-non-string.test @@ -0,0 +1,35 @@ +# @TEST-EXEC: zeek -b -C -r $TRACES/mysql/mysql-9.0.0-query-attributes.pcap %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff mysql.log + +@load base/protocols/mysql + +event mysql_ok(c: connection, affected_rows: count) + { + print "mysql ok", affected_rows; + } + +event mysql_eof(c: connection, is_intermediate: bool) + { + print "mysql eof", is_intermediate; + } + +event mysql_result_row(c: connection, row: string_vec) + { + print "mysql result row", row; + } + +event mysql_error(c: connection, code: count, msg: string) + { + print "mysql error", code, msg; + } + +event mysql_command_request(c: connection, command: count, arg: string) + { + print "mysql request", command, arg; + } + +event mysql_handshake(c: connection, username: string) + { + print "mysql handshake", username; + }