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   | http://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 	zend_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 	zend_bool	send_auth_data;
94 	zend_bool	is_change_user_packet;
95 	zend_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 	zend_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 	zval		*fields;
210 	uint32_t	field_count;
211 	zend_bool	eof;
212 	/*
213 	  These are, of course, only for SELECT in the EOF packet,
214 	  which is detected by this packet
215 	*/
216 	uint16_t	warning_count;
217 	uint16_t	server_status;
218 
219 	MYSQLND_ROW_BUFFER	row_buffer;
220 	MYSQLND_MEMORY_POOL * result_set_memory_pool;
221 
222 	zend_bool		skip_extraction;
223 	zend_bool		binary_protocol;
224 	MYSQLND_FIELD	*fields_metadata;
225 
226 	/* If error packet, we use these */
227 	MYSQLND_ERROR_INFO	error_info;
228 } MYSQLND_PACKET_ROW;
229 
230 
231 /* Statistics packet */
232 typedef struct st_mysqlnd_packet_stats {
233 	MYSQLND_PACKET_HEADER	header;
234 	MYSQLND_STRING message;
235 } MYSQLND_PACKET_STATS;
236 
237 
238 /* COM_PREPARE response packet */
239 typedef struct st_mysqlnd_packet_prepare_response {
240 	MYSQLND_PACKET_HEADER	header;
241 	/* also known as field_count 0x00=OK , 0xFF=error */
242 	unsigned char	error_code;
243 	zend_ulong	stmt_id;
244 	unsigned int	field_count;
245 	unsigned int	param_count;
246 	unsigned int	warning_count;
247 
248 	/* present in case of error */
249 	MYSQLND_ERROR_INFO	error_info;
250 } MYSQLND_PACKET_PREPARE_RESPONSE;
251 
252 
253 /* Statistics packet */
254 typedef struct st_mysqlnd_packet_chg_user_resp {
255 	MYSQLND_PACKET_HEADER	header;
256 	uint32_t			response_code;
257 
258 	/* message_len is not part of the packet*/
259 	uint16_t			server_capabilities;
260 	/* If error packet, we use these */
261 	MYSQLND_ERROR_INFO	error_info;
262 	zend_bool			server_asked_323_auth;
263 
264 	char		*new_auth_protocol;
265 	size_t		new_auth_protocol_len;
266 	zend_uchar	*new_auth_protocol_data;
267 	size_t		new_auth_protocol_data_len;
268 } MYSQLND_PACKET_CHG_USER_RESPONSE;
269 
270 
271 /* Command packet */
272 typedef struct st_mysqlnd_packet_sha256_pk_request {
273 	MYSQLND_PACKET_HEADER			header;
274 } MYSQLND_PACKET_SHA256_PK_REQUEST;
275 
276 typedef struct  st_mysqlnd_packet_sha256_pk_request_response {
277 	MYSQLND_PACKET_HEADER	header;
278 	zend_uchar 				*public_key;
279 	size_t					public_key_len;
280 } MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE;
281 
282 typedef struct st_mysqlnd_packet_cached_sha2_result {
283 	MYSQLND_PACKET_HEADER		header;
284 	uint8_t		response_code;
285 	uint8_t 	result;
286 	uint8_t 	request;
287 	zend_uchar * password;
288 	size_t password_len;
289 	/* Used for auth switch request */
290 	char		*new_auth_protocol;
291 	size_t		new_auth_protocol_len;
292 	zend_uchar	*new_auth_protocol_data;
293 	size_t		new_auth_protocol_data_len;
294 	/* Used for error result */
295 	char 		error[MYSQLND_ERRMSG_SIZE+1];
296 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
297 	unsigned int 	error_no;
298 } MYSQLND_PACKET_CACHED_SHA2_RESULT;
299 
300 
301 
302 zend_ulong		php_mysqlnd_net_field_length(const zend_uchar **packet);
303 zend_uchar *	php_mysqlnd_net_store_length(zend_uchar *packet, const uint64_t length);
304 size_t			php_mysqlnd_net_store_length_size(uint64_t length);
305 
306 PHPAPI extern const char * const mysqlnd_empty_string;
307 
308 enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fields,
309 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
310 										 zend_bool as_int_or_float, MYSQLND_STATS * stats);
311 
312 
313 enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_ROW_BUFFER * row_buffer, zval * fields,
314 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
315 										 zend_bool as_int_or_float, MYSQLND_STATS * stats);
316 
317 enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_ROW_BUFFER * row_buffer, zval * fields,
318 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
319 										 zend_bool as_int_or_float, MYSQLND_STATS * stats);
320 
321 
322 PHPAPI MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * mysqlnd_protocol_payload_decoder_factory_init(MYSQLND_CONN_DATA * conn, const zend_bool persistent);
323 PHPAPI void mysqlnd_protocol_payload_decoder_factory_free(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory);
324 
325 #endif /* MYSQLND_WIREPROTOCOL_H */
326