1 /* 2 +----------------------------------------------------------------------+ 3 | Copyright (c) The PHP Group | 4 +----------------------------------------------------------------------+ 5 | This source file is subject to version 3.01 of the PHP license, | 6 | that is bundled with this package in the file LICENSE, and is | 7 | available through the world-wide-web at the following url: | 8 | https://www.php.net/license/3_01.txt | 9 | If you did not receive a copy of the PHP license and are unable to | 10 | obtain it through the world-wide-web, please send a note to | 11 | license@php.net so we can mail you a copy immediately. | 12 +----------------------------------------------------------------------+ 13 | Authors: Andrey Hristov <andrey@php.net> | 14 | Ulf Wendel <uw@php.net> | 15 +----------------------------------------------------------------------+ 16 */ 17 18 #ifndef MYSQLND_WIREPROTOCOL_H 19 #define MYSQLND_WIREPROTOCOL_H 20 21 #define MYSQLND_HEADER_SIZE 4 22 #define COMPRESSED_HEADER_SIZE 3 23 24 #define MYSQLND_NULL_LENGTH (zend_ulong) ~0 25 26 /* Used in mysqlnd_debug.c */ 27 PHPAPI extern const char mysqlnd_read_header_name[]; 28 PHPAPI extern const char mysqlnd_read_body_name[]; 29 30 31 /* Packet handling */ 32 #define PACKET_WRITE(conn, packet) ((packet)->header.m->write_to_net((conn), (packet))) 33 #define PACKET_READ(conn, packet) ((packet)->header.m->read_from_net((conn), (packet))) 34 #define PACKET_FREE(packet) \ 35 do { \ 36 DBG_INF_FMT("PACKET_FREE(%p)", packet); \ 37 if ((packet)->header.m->free_mem) { \ 38 ((packet)->header.m->free_mem((packet))); \ 39 } \ 40 } while (0); 41 42 PHPAPI extern const char * const mysqlnd_command_to_text[COM_END]; 43 44 /* Low-level extraction functionality */ 45 typedef struct st_mysqlnd_packet_methods { 46 enum_func_status (*read_from_net)(MYSQLND_CONN_DATA * conn, void * packet); 47 size_t (*write_to_net)(MYSQLND_CONN_DATA * conn, void * packet); 48 void (*free_mem)(void *packet); 49 } mysqlnd_packet_methods; 50 51 52 typedef struct st_mysqlnd_packet_header { 53 size_t size; 54 zend_uchar packet_no; 55 56 mysqlnd_packet_methods *m; 57 } MYSQLND_PACKET_HEADER; 58 59 /* Server greets the client */ 60 typedef struct st_mysqlnd_packet_greet { 61 MYSQLND_PACKET_HEADER header; 62 uint8_t protocol_version; 63 char *server_version; 64 uint32_t thread_id; 65 char intern_auth_plugin_data[SCRAMBLE_LENGTH]; 66 MYSQLND_STRING authentication_plugin_data; 67 /* 1 byte pad */ 68 uint32_t server_capabilities; 69 uint8_t charset_no; 70 uint16_t server_status; 71 /* 13 byte pad, in 5.5 first 2 bytes are more capabilities followed by 1 byte scramble_length */ 72 bool pre41; 73 /* If error packet, we use these */ 74 char error[MYSQLND_ERRMSG_SIZE+1]; 75 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 76 unsigned int error_no; 77 char *auth_protocol; 78 } MYSQLND_PACKET_GREET; 79 80 81 /* Client authenticates */ 82 typedef struct st_mysqlnd_packet_auth { 83 MYSQLND_PACKET_HEADER header; 84 const char *user; 85 const zend_uchar *auth_data; 86 size_t auth_data_len; 87 const char *db; 88 const char *auth_plugin_name; 89 uint32_t client_flags; 90 uint32_t max_packet_size; 91 uint8_t charset_no; 92 /* Here the packet ends. This is user supplied data */ 93 bool send_auth_data; 94 bool is_change_user_packet; 95 bool silent; 96 HashTable *connect_attr; 97 size_t db_len; 98 } MYSQLND_PACKET_AUTH; 99 100 /* Auth response packet */ 101 typedef struct st_mysqlnd_packet_auth_response { 102 MYSQLND_PACKET_HEADER header; 103 uint8_t response_code; 104 uint64_t affected_rows; 105 uint64_t last_insert_id; 106 uint16_t server_status; 107 uint16_t warning_count; 108 char *message; 109 size_t message_len; 110 /* If error packet, we use these */ 111 char error[MYSQLND_ERRMSG_SIZE+1]; 112 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 113 unsigned int error_no; 114 115 char *new_auth_protocol; 116 size_t new_auth_protocol_len; 117 zend_uchar *new_auth_protocol_data; 118 size_t new_auth_protocol_data_len; 119 } MYSQLND_PACKET_AUTH_RESPONSE; 120 121 122 /* Auth response packet */ 123 typedef struct st_mysqlnd_packet_change_auth_response { 124 MYSQLND_PACKET_HEADER header; 125 const zend_uchar *auth_data; 126 size_t auth_data_len; 127 } MYSQLND_PACKET_CHANGE_AUTH_RESPONSE; 128 129 130 /* OK packet */ 131 typedef struct st_mysqlnd_packet_ok { 132 MYSQLND_PACKET_HEADER header; 133 uint8_t field_count; /* always 0x0 */ 134 uint64_t affected_rows; 135 uint64_t last_insert_id; 136 uint16_t server_status; 137 uint16_t warning_count; 138 char *message; 139 size_t message_len; 140 /* If error packet, we use these */ 141 char error[MYSQLND_ERRMSG_SIZE+1]; 142 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 143 unsigned int error_no; 144 } MYSQLND_PACKET_OK; 145 146 147 /* Command packet */ 148 typedef struct st_mysqlnd_packet_command { 149 MYSQLND_PACKET_HEADER header; 150 enum php_mysqlnd_server_command command; 151 MYSQLND_CSTRING argument; 152 } MYSQLND_PACKET_COMMAND; 153 154 155 /* EOF packet */ 156 typedef struct st_mysqlnd_packet_eof { 157 MYSQLND_PACKET_HEADER header; 158 uint8_t field_count; /* 0xFE */ 159 uint16_t warning_count; 160 uint16_t server_status; 161 /* If error packet, we use these */ 162 char error[MYSQLND_ERRMSG_SIZE+1]; 163 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 164 unsigned int error_no; 165 } MYSQLND_PACKET_EOF; 166 /* EOF packet */ 167 168 169 /* Result Set header*/ 170 typedef struct st_mysqlnd_packet_rset_header { 171 MYSQLND_PACKET_HEADER header; 172 /* 173 0x00 => ok 174 ~0 => LOAD DATA LOCAL 175 error_no != 0 => error 176 others => result set -> Read res_field packets up to field_count 177 */ 178 zend_ulong field_count; 179 /* 180 These are filled if no SELECT query. For SELECT warning_count 181 and server status are in the last row packet, the EOF packet. 182 */ 183 uint16_t warning_count; 184 uint16_t server_status; 185 uint64_t affected_rows; 186 uint64_t last_insert_id; 187 /* This is for both LOAD DATA or info, when no result set */ 188 MYSQLND_STRING info_or_local_file; 189 /* If error packet, we use these */ 190 MYSQLND_ERROR_INFO error_info; 191 } MYSQLND_PACKET_RSET_HEADER; 192 193 194 /* Result set field packet */ 195 typedef struct st_mysqlnd_packet_res_field { 196 MYSQLND_PACKET_HEADER header; 197 MYSQLND_MEMORY_POOL *memory_pool; 198 MYSQLND_FIELD *metadata; 199 /* For table definitions, empty for result sets */ 200 bool skip_parsing; 201 202 MYSQLND_ERROR_INFO error_info; 203 } MYSQLND_PACKET_RES_FIELD; 204 205 206 /* Row packet */ 207 typedef struct st_mysqlnd_packet_row { 208 MYSQLND_PACKET_HEADER header; 209 uint32_t field_count; 210 bool eof; 211 /* 212 These are, of course, only for SELECT in the EOF packet, 213 which is detected by this packet 214 */ 215 uint16_t warning_count; 216 uint16_t server_status; 217 218 MYSQLND_ROW_BUFFER row_buffer; 219 MYSQLND_MEMORY_POOL * result_set_memory_pool; 220 221 bool binary_protocol; 222 MYSQLND_FIELD *fields_metadata; 223 224 /* If error packet, we use these */ 225 MYSQLND_ERROR_INFO error_info; 226 } MYSQLND_PACKET_ROW; 227 228 229 /* Statistics packet */ 230 typedef struct st_mysqlnd_packet_stats { 231 MYSQLND_PACKET_HEADER header; 232 MYSQLND_STRING message; 233 } MYSQLND_PACKET_STATS; 234 235 236 /* COM_PREPARE response packet */ 237 typedef struct st_mysqlnd_packet_prepare_response { 238 MYSQLND_PACKET_HEADER header; 239 /* also known as field_count 0x00=OK , 0xFF=error */ 240 unsigned char error_code; 241 zend_ulong stmt_id; 242 unsigned int field_count; 243 unsigned int param_count; 244 unsigned int warning_count; 245 246 /* present in case of error */ 247 MYSQLND_ERROR_INFO error_info; 248 } MYSQLND_PACKET_PREPARE_RESPONSE; 249 250 251 /* Statistics packet */ 252 typedef struct st_mysqlnd_packet_chg_user_resp { 253 MYSQLND_PACKET_HEADER header; 254 uint32_t response_code; 255 256 /* message_len is not part of the packet*/ 257 uint16_t server_capabilities; 258 /* If error packet, we use these */ 259 MYSQLND_ERROR_INFO error_info; 260 bool server_asked_323_auth; 261 262 char *new_auth_protocol; 263 size_t new_auth_protocol_len; 264 zend_uchar *new_auth_protocol_data; 265 size_t new_auth_protocol_data_len; 266 } MYSQLND_PACKET_CHG_USER_RESPONSE; 267 268 269 /* Command packet */ 270 typedef struct st_mysqlnd_packet_sha256_pk_request { 271 MYSQLND_PACKET_HEADER header; 272 } MYSQLND_PACKET_SHA256_PK_REQUEST; 273 274 typedef struct st_mysqlnd_packet_sha256_pk_request_response { 275 MYSQLND_PACKET_HEADER header; 276 zend_uchar *public_key; 277 size_t public_key_len; 278 } MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE; 279 280 typedef struct st_mysqlnd_packet_cached_sha2_result { 281 MYSQLND_PACKET_HEADER header; 282 uint8_t response_code; 283 uint8_t result; 284 uint8_t request; 285 zend_uchar * password; 286 size_t password_len; 287 /* Used for auth switch request */ 288 char *new_auth_protocol; 289 size_t new_auth_protocol_len; 290 zend_uchar *new_auth_protocol_data; 291 size_t new_auth_protocol_data_len; 292 /* Used for error result */ 293 char error[MYSQLND_ERRMSG_SIZE+1]; 294 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 295 unsigned int error_no; 296 } MYSQLND_PACKET_CACHED_SHA2_RESULT; 297 298 299 300 zend_ulong php_mysqlnd_net_field_length(const zend_uchar **packet); 301 zend_uchar * php_mysqlnd_net_store_length(zend_uchar *packet, const uint64_t length); 302 size_t php_mysqlnd_net_store_length_size(uint64_t length); 303 304 PHPAPI extern const char * const mysqlnd_empty_string; 305 306 enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fields, 307 unsigned int field_count, const MYSQLND_FIELD * fields_metadata, 308 bool as_int_or_float, MYSQLND_STATS * stats); 309 310 311 enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fields, 312 unsigned int field_count, const MYSQLND_FIELD * fields_metadata, 313 bool as_int_or_float, MYSQLND_STATS * stats); 314 315 316 PHPAPI MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * mysqlnd_protocol_payload_decoder_factory_init(MYSQLND_CONN_DATA * conn, const bool persistent); 317 PHPAPI void mysqlnd_protocol_payload_decoder_factory_free(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory); 318 319 #endif /* MYSQLND_WIREPROTOCOL_H */ 320