diff --git a/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_matcher.c b/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_matcher.c index e6cb17417a15d6c3ccefccb3716b1cebaaa288c3..0199520c33e129d150ead42c7ea2a32e9ad27b85 100644 --- a/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_matcher.c +++ b/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_matcher.c @@ -253,77 +253,77 @@ static int ProcessPackets(size_t req_index, struct mysql_packet_msg_s *req, stru u64 rsp_timestamp; switch (req->command_t) { // Internal commands with response: ERR_Packet. - case kConnect: - case kConnectOut: - case kTime: - case kDelayedInsert: - case kDaemon: - case kInitDB: - case kCreateDB: - case kDropDB: + case CMD_CONNECT: + case CMD_CONNECT_OUT: + case CMD_TIME: + case CMD_DELAYED_INSERT: + case CMD_DAEMON: + case CMD_INITDB: + case CMD_CREATDB: + case CMD_DROPDB: // Basic Commands with response: OK_Packet or ERR_Packet - case kSleep: - case kRegisterSlave: - case kResetConnection: - case kProcessKill: - case kRefresh: // Deprecated. - case kPing: // COM_PING can't actually send ERR_Packet. + case CMD_SLEEP: + case CMD_REGISTER_SLAVE: + case CMD_RESET_CONNECTION: + case CMD_PROCESS_KILL: + case CMD_REFRESH: // Deprecated. + case CMD_PING: // COM_PING can't actually send ERR_Packet. // Basic Commands with response: EOF_Packet or ERR_Packet. - case kShutdown: // Deprecated. - case kSetOption: - case kDebug: + case CMD_SHUTDOWN: // Deprecated. + case CMD_SET_OPTION: + case CMD_DEBUG: parse_state = ProcessRequestWithBasicResponse(req, resp_packets_view, &rsp_timestamp, record_buf); break; - case kBrokenData: + case CMD_BROKEN_DATA: parse_state = ProcessDataIncomplete(req, resp_packets_view, &rsp_timestamp, record_buf); break; - case kQuit: // Response: OK_Packet or a connection close. + case CMD_QUIT: // Response: OK_Packet or a connection close. parse_state = ProcessQuit(req, resp_packets_view, &rsp_timestamp, record_buf); break; // COM_FIELD_LIST has its own COM_FIELD_LIST meta response (ERR_Packet or one // or more Column Definition packets and a closing EOF_Packet). - case kFieldList: // Deprecated. + case CMD_FIELDLIST: // Deprecated. parse_state = ProcessFieldList(req, resp_packets_view, &rsp_timestamp, record_buf); break; // COM_QUERY has its own COM_QUERY meta response (ERR_Packet, OK_Packet, // Protocol::LOCAL_INFILE_Request, or ProtocolText::Resultset). - case kQuery: + case CMD_QUERY: parse_state = ProcessQuery(req, resp_packets_view, &rsp_timestamp, record_buf); break; // COM_STMT_PREPARE returns COM_STMT_PREPARE_OK on success, ERR_Packet // otherwise. - case kStmtPrepare: + case CMD_STMT_PREPARE: parse_state = ProcessStmtPrepare(req, resp_packets_view, &rsp_timestamp, record_buf); break; // COM_STMT_SEND_LONG_DATA has no response. - case kStmtSendLongData: + case CMD_STMT_SEND_LONG_DATA: parse_state = ProcessStmtSendLongData(req, resp_packets_view, &rsp_timestamp, record_buf); break; // COM_STMT_EXECUTE has its own COM_STMT_EXECUTE meta response (OK_Packet, // ERR_Packet or a resultset: Binary Protocol Resultset). - case kStmtExecute: + case CMD_STMT_EXECUTE: parse_state = ProcessStmtExecute(req, resp_packets_view, &rsp_timestamp, record_buf); break; // COM_CLOSE has no response. - case kStmtClose: + case CMD_STMT_CLOSE: parse_state = ProcessStmtClose(req, resp_packets_view, &rsp_timestamp, record_buf); break; // COM_STMT_RESET response is OK_Packet if the statement could be reset, // ERR_Packet if not. - case kStmtReset: + case CMD_STMT_RESET: parse_state = ProcessStmtReset(req, resp_packets_view, &rsp_timestamp, record_buf); break; // COM_STMT_FETCH has a meta response (multi-resultset, or ERR_Packet). - case kStmtFetch: + case CMD_STMT_FETCH: parse_state = ProcessStmtFetch(req, resp_packets_view, &rsp_timestamp, record_buf); break; - case kProcessInfo: // a ProtocolText::Resultset or ERR_Packet - case kChangeUser: // Authentication Method Switch Request Packet or + case CMD_PROCESS_INFO: // a ProtocolText::Resultset or ERR_Packet + case CMD_CHANGE_USER: // Authentication Method Switch Request Packet or // ERR_Packet - case kBinlogDumpGTID: // binlog network stream, ERR_Packet or EOF_Packet - case kBinlogDump: // binlog network stream, ERR_Packet or EOF_Packet - case kTableDump: // a table dump or ERR_Packet - case kStatistics: // string.EOF + case CMD_BINLOG_DUMP_GTID: // binlog network stream, ERR_Packet or EOF_Packet + case CMD_BINLOG_DUMP: // binlog network stream, ERR_Packet or EOF_Packet + case CMD_TABLE_DUMP: // a table dump or ERR_Packet + case CMD_STATISTICS: // string.EOF // Rely on recovery to re-sync responses based on timestamps. parse_state = STATE_INVALID; break; diff --git a/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_matcher_wrapper.c b/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_matcher_wrapper.c index 33a1ef9482c4d97cabd4895c333ba39aded0d4ae..da4276e4f7143d0e7b4c8d5f66c78c7265281f30 100644 --- a/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_matcher_wrapper.c +++ b/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_matcher_wrapper.c @@ -183,7 +183,7 @@ bool DissectNonStringParam(struct mysql_packet_msg_s* rsp_msg, size_t* param_off */ bool IsEOFPacket(struct mysql_packet_msg_s* rsp_msg) { - return ((rsp_msg->command_t == kRespHeaderEOF) && rsp_msg->data_len == 5); + return ((rsp_msg->command_t == RESP_HEADER_EOF) && rsp_msg->data_len == 5); } /** @@ -191,7 +191,7 @@ bool IsEOFPacket(struct mysql_packet_msg_s* rsp_msg) */ bool IsErrPacket(struct mysql_packet_msg_s* rsp_msg) { - return ((rsp_msg->command_t == kRespHeaderErr) && rsp_msg->data_len > 3); + return ((rsp_msg->command_t == RESP_HEADER_ERR) && rsp_msg->data_len > 3); } /** @@ -202,10 +202,10 @@ bool IsOKPacket(struct mysql_packet_msg_s* rsp_msg) { u8 header = rsp_msg->command_t; - if (header == kRespHeaderOK && rsp_msg->data_len >= 7) { + if (header == RESP_HEADER_OK && rsp_msg->data_len >= 7) { return true; } - if (header == kRespHeaderEOF && rsp_msg->data_len < 9 && !IsEOFPacket(rsp_msg)) { + if (header == RESP_HEADER_EOF && rsp_msg->data_len < 9 && !IsEOFPacket(rsp_msg)) { return true; } return false; diff --git a/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_msg_format.h b/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_msg_format.h index c02fd72aa4635c6828f15fbd435d2802cfafd58d..58386cd7712c98b13e9867856823e3f2491bfadf 100644 --- a/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_msg_format.h +++ b/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_msg_format.h @@ -23,23 +23,12 @@ #include "hash.h" #include "../../include/data_stream.h" -/** - * The MySQL parsing structure has 3 different levels of abstraction. From low to high level: - * 1. MySQL Packet (Output of MySQL Parser). The content of it is not parsed. - * https://dev.mysql.com/doc/internals/en/mysql-packet.html - * 2. MySQL Message, a Request or Response, consisting of one or more MySQL Packets. It contains - * parsed out fields based on the type of request/response. - * 3. MySQL Event, containing a request and response pair. - */ +#define MAX_PACKET_LENGTH (1 << 24) - 1 +#define PACKET_HEADER_LENGTH 4 -// Command Types -// https://dev.mysql.com/doc/internals/en/command-phase.html -#define kMaxPacketLength (1 << 24) - 1 -#define kPacketHeaderLength 4 - -#define kRespHeaderEOF 0xfe -#define kRespHeaderErr 0xff -#define kRespHeaderOK 0x00 +#define RESP_HEADER_EOF 0xfe +#define RESP_HEADER_ERR 0xff +#define RESP_HEADER_OK 0x00 // 定义 NumberRange 结构体 typedef struct { @@ -47,50 +36,44 @@ typedef struct { int max; } NumberRange; -//----------------------------------------------------------------------------- -// Packet Level Definitions -//----------------------------------------------------------------------------- - -// Command Types -// https://dev.mysql.com/doc/internals/en/command-phase.html typedef enum { - kSleep = 0x00, - kQuit = 0x01, - kInitDB = 0x02, - kQuery = 0x03, - kFieldList = 0x04, - kCreateDB = 0x05, - kDropDB = 0x06, - kRefresh = 0x07, - kShutdown = 0x08, - kStatistics = 0x09, - kProcessInfo = 0x0a, - kConnect = 0x0b, - kProcessKill = 0x0c, - kDebug = 0x0d, - kPing = 0x0e, - kTime = 0x0f, - kDelayedInsert = 0x10, - kChangeUser = 0x11, - kBinlogDump = 0x12, - kTableDump = 0x13, - kConnectOut = 0x14, - kRegisterSlave = 0x15, - kStmtPrepare = 0x16, - kStmtExecute = 0x17, - kStmtSendLongData = 0x18, - kStmtClose = 0x19, - kStmtReset = 0x1a, - kSetOption = 0x1b, - kStmtFetch = 0x1c, - kDaemon = 0x1d, - kBinlogDumpGTID = 0x1e, - kResetConnection = 0x1f, - kBrokenData = 0x20, -} Command; + CMD_SLEEP = 0x00, + CMD_QUIT = 0x01, + CMD_INITDB = 0x02, + CMD_QUERY = 0x03, + CMD_FIELDLIST = 0x04, + CMD_CREATDB = 0x05, + CMD_DROPDB = 0x06, + CMD_REFRESH = 0x07, + CMD_SHUTDOWN = 0x08, + CMD_STATISTICS = 0x09, + CMD_PROCESS_INFO = 0x0a, + CMD_CONNECT = 0x0b, + CMD_PROCESS_KILL = 0x0c, + CMD_DEBUG = 0x0d, + CMD_PING = 0x0e, + CMD_TIME = 0x0f, + CMD_DELAYED_INSERT = 0x10, + CMD_CHANGE_USER = 0x11, + CMD_BINLOG_DUMP = 0x12, + CMD_TABLE_DUMP = 0x13, + CMD_CONNECT_OUT = 0x14, + CMD_REGISTER_SLAVE = 0x15, + CMD_STMT_PREPARE = 0x16, + CMD_STMT_EXECUTE = 0x17, + CMD_STMT_SEND_LONG_DATA = 0x18, + CMD_STMT_CLOSE = 0x19, + CMD_STMT_RESET = 0x1a, + CMD_SET_OPTION = 0x1b, + CMD_STMT_FETCH = 0x1c, + CMD_DAEMON = 0x1d, + CMD_BINLOG_DUMP_GTID = 0x1e, + CMD_RESET_CONNECTION = 0x1f, + CMD_BROKEN_DATA = 0x20, +} MySQLCommand; // 定义最大命令值 -#define kMaxCommandValue 0x1f +#define MAX_COMMAND_VALUE 0x1f struct mysql_packet_msg_s { // current_pos有效值:[0, data_len - 1],current_pos = data_len时,证明已解析完当前data[] diff --git a/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_parser.c b/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_parser.c index 1275c10654242251ff859c602d947bbce973f7e0..a02cbf7e8cfe4f4406e844bfef50d6166710a90f 100644 --- a/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_parser.c +++ b/src/probes/extends/ebpf.probe/src/l7probe/protocol/mysql/mysql_parser.c @@ -22,43 +22,43 @@ static bool is_first_packet = true; static NumberRange cmd_length_ranges[32] = { - [kSleep] = {1, 1}, - [kQuit] = {1, 1}, - [kInitDB] = {1, kMaxPacketLength}, - [kQuery] = {1, kMaxPacketLength}, - [kFieldList] = {2, kMaxPacketLength}, - [kCreateDB] = {1, kMaxPacketLength}, - [kDropDB] = {1, kMaxPacketLength}, - [kRefresh] = {2, 2}, - [kShutdown] = {1, 2}, - [kStatistics] = {1, 1}, - [kProcessInfo] = {1, 1}, - [kConnect] = {1, 1}, - [kProcessKill] = {1, 5}, - [kDebug] = {1, 1}, - [kPing] = {1, 1}, - [kTime] = {1, 1}, - [kDelayedInsert] = {1, 1}, - [kChangeUser] = {4, kMaxPacketLength}, - [kBinlogDump] = {11, kMaxPacketLength}, - [kTableDump] = {3, kMaxPacketLength}, - [kConnectOut] = {1, 1}, - [kRegisterSlave] = {18, kMaxPacketLength}, - [kStmtPrepare] = {1, kMaxPacketLength}, - [kStmtExecute] = {10, kMaxPacketLength}, - [kStmtSendLongData] = {7, kMaxPacketLength}, - [kStmtClose] = {5, 5}, - [kStmtReset] = {5, 5}, - [kSetOption] = {3, 3}, - [kStmtFetch] = {9, 9}, - [kDaemon] = {1, 1}, - [kBinlogDumpGTID] = {19, 19}, - [kResetConnection] = {1, 1} + [CMD_SLEEP] = {1, 1}, + [CMD_QUIT] = {1, 1}, + [CMD_INITDB] = {1, MAX_PACKET_LENGTH}, + [CMD_QUERY] = {1, MAX_PACKET_LENGTH}, + [CMD_FIELDLIST] = {2, MAX_PACKET_LENGTH}, + [CMD_CREATDB] = {1, MAX_PACKET_LENGTH}, + [CMD_DROPDB] = {1, MAX_PACKET_LENGTH}, + [CMD_REFRESH] = {2, 2}, + [CMD_SHUTDOWN] = {1, 2}, + [CMD_STATISTICS] = {1, 1}, + [CMD_PROCESS_INFO] = {1, 1}, + [CMD_CONNECT] = {1, 1}, + [CMD_PROCESS_KILL] = {1, 5}, + [CMD_DEBUG] = {1, 1}, + [CMD_PING] = {1, 1}, + [CMD_TIME] = {1, 1}, + [CMD_DELAYED_INSERT] = {1, 1}, + [CMD_CHANGE_USER] = {4, MAX_PACKET_LENGTH}, + [CMD_BINLOG_DUMP] = {11, MAX_PACKET_LENGTH}, + [CMD_TABLE_DUMP] = {3, MAX_PACKET_LENGTH}, + [CMD_CONNECT_OUT] = {1, 1}, + [CMD_REGISTER_SLAVE] = {18, MAX_PACKET_LENGTH}, + [CMD_STMT_PREPARE] = {1, MAX_PACKET_LENGTH}, + [CMD_STMT_EXECUTE] = {10, MAX_PACKET_LENGTH}, + [CMD_STMT_SEND_LONG_DATA] = {7, MAX_PACKET_LENGTH}, + [CMD_STMT_CLOSE] = {5, 5}, + [CMD_STMT_RESET] = {5, 5}, + [CMD_SET_OPTION] = {3, 3}, + [CMD_STMT_FETCH] = {9, 9}, + [CMD_DAEMON] = {1, 1}, + [CMD_BINLOG_DUMP_GTID] = {19, 19}, + [CMD_RESET_CONNECTION] = {1, 1} }; static bool IsValidCommand(uint8_t command_byte) { - if (command_byte > kMaxCommandValue) { + if (command_byte > MAX_COMMAND_VALUE) { return false; } // The following are internal commands, and should not be sent on the connection. @@ -66,11 +66,11 @@ static bool IsValidCommand(uint8_t command_byte) // error. But for the sake of identifying mis-classified MySQL connections, it helps to call these // out as invalid commands. switch (command_byte) { - case kSleep: - case kTime: - case kDelayedInsert: - case kConnectOut: - case kDaemon: + case CMD_SLEEP: + case CMD_TIME: + case CMD_DELAYED_INSERT: + case CMD_CONNECT_OUT: + case CMD_DAEMON: return false; default: return true; @@ -107,7 +107,7 @@ parse_state_t mysql_parse_frame(enum message_type_t msg_type, struct raw_data_s return STATE_INVALID; } - if (raw_data->data_len <= kPacketHeaderLength) { + if (raw_data->data_len <= PACKET_HEADER_LENGTH) { return STATE_NEEDS_MORE_DATA; } @@ -122,11 +122,11 @@ parse_state_t mysql_parse_frame(enum message_type_t msg_type, struct raw_data_s ((u8)raw_data->data[raw_data->current_pos + 1] << 8) | ((u8)raw_data->data[raw_data->current_pos + 2] << 16); sequence_id = raw_data->data[raw_data->current_pos + 3]; - command = raw_data->data[raw_data->current_pos + kPacketHeaderLength]; + command = raw_data->data[raw_data->current_pos + PACKET_HEADER_LENGTH]; if (raw_data->isBrokeData) { - packet_length = raw_data->data_len - raw_data->current_pos - kPacketHeaderLength; + packet_length = raw_data->data_len - raw_data->current_pos - PACKET_HEADER_LENGTH; } - if ((raw_data->data_len < raw_data->current_pos + kPacketHeaderLength + packet_length) && (raw_data->isBrokeData == 0)) { + if ((raw_data->data_len < raw_data->current_pos + PACKET_HEADER_LENGTH + packet_length) && (raw_data->isBrokeData == 0)) { return STATE_NEEDS_MORE_DATA; } } @@ -158,7 +158,7 @@ parse_state_t mysql_parse_frame(enum message_type_t msg_type, struct raw_data_s packet_msg->data_len = packet_length; packet_msg->sequence_id = sequence_id; if (raw_data->isBrokeData == 1) { - command = (u8)kBrokenData; + command = (u8)CMD_BROKEN_DATA; } packet_msg->command_t = command; @@ -175,22 +175,22 @@ size_t mysql_find_frame_boundary(enum message_type_t msg_type, struct raw_data_s // the first packet. return raw_data->current_pos; } - if (raw_data->data_len < kPacketHeaderLength) { + if (raw_data->data_len < PACKET_HEADER_LENGTH) { return PARSER_INVALID_BOUNDARY_INDEX; } if (msg_type == MESSAGE_RESPONSE) { // No real search implemented for responses. return raw_data->current_pos; } - if (raw_data->data_len == kPacketHeaderLength) { + if (raw_data->data_len == PACKET_HEADER_LENGTH) { return 0; } - // Need at least kPacketHeaderLength bytes + 1 command byte in buf. + // Need at least PACKET_HEADER_LENGTH bytes + 1 command byte in buf. size_t i = raw_data->current_pos; u32 packet_length = (u8)raw_data->data[i] | ((u8)raw_data->data[i + 1] << 8) | ((u8)raw_data->data[i + 2] << 16); u8 sequence_id = raw_data->data[i + 3]; - u8 command = raw_data->data[i + kPacketHeaderLength]; + u8 command = raw_data->data[i + PACKET_HEADER_LENGTH]; // Requests must have sequence id of 0. if (sequence_id != 0) { @@ -198,7 +198,7 @@ size_t mysql_find_frame_boundary(enum message_type_t msg_type, struct raw_data_s } // If the command byte isn't a valid command, then this can't a message boundary. - if (command < 0 || command > kMaxCommandValue) { + if (command < 0 || command > MAX_COMMAND_VALUE) { return PARSER_INVALID_BOUNDARY_INDEX; }