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