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(packet)	((packet)->header.m->write_to_net((packet)))
35 #define PACKET_READ(packet)		((packet)->header.m->read_from_net((packet)))
36 #define PACKET_FREE(packet) \
37 	do { \
38 		DBG_INF_FMT("PACKET_FREE(%p)", packet); \
39 		if ((packet)) { \
40 			((packet)->header.m->free_mem((packet), FALSE)); \
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 	size_t				struct_size;
49 	enum_func_status	(*read_from_net)(void * packet);
50 	size_t				(*write_to_net)(void * packet);
51 	void				(*free_mem)(void *packet, zend_bool stack_allocation);
52 } mysqlnd_packet_methods;
53 
54 
55 typedef struct st_mysqlnd_packet_header {
56 	size_t		size;
57 	zend_uchar	packet_no;
58 	zend_bool	persistent;
59 
60 	mysqlnd_packet_methods *m;
61 
62 	MYSQLND_CONN_DATA * conn;
63 	MYSQLND_PFC * protocol_frame_codec;
64 	MYSQLND_VIO * vio;
65 	MYSQLND_ERROR_INFO * error_info;
66 	MYSQLND_STATS * stats;
67 	MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * factory;
68 	MYSQLND_CONNECTION_STATE * connection_state;
69 } MYSQLND_PACKET_HEADER;
70 
71 /* Server greets the client */
72 typedef struct st_mysqlnd_packet_greet {
73 	MYSQLND_PACKET_HEADER		header;
74 	uint8_t		protocol_version;
75 	char		*server_version;
76 	uint32_t	thread_id;
77 	char		intern_auth_plugin_data[SCRAMBLE_LENGTH];
78 	MYSQLND_STRING authentication_plugin_data;
79 	/* 1 byte pad */
80 	uint32_t	server_capabilities;
81 	uint8_t		charset_no;
82 	uint16_t	server_status;
83 	/* 13 byte pad, in 5.5 first 2 bytes are more capabilities followed by 1 byte scramble_length */
84 	zend_bool	pre41;
85 	/* If error packet, we use these */
86 	char 		error[MYSQLND_ERRMSG_SIZE+1];
87 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
88 	unsigned int	error_no;
89 	char		*auth_protocol;
90 } MYSQLND_PACKET_GREET;
91 
92 
93 /* Client authenticates */
94 typedef struct st_mysqlnd_packet_auth {
95 	MYSQLND_PACKET_HEADER		header;
96 	const char	*user;
97 	const zend_uchar	*auth_data;
98 	size_t		auth_data_len;
99 	const char	*db;
100 	const char	*auth_plugin_name;
101 	uint32_t	client_flags;
102 	uint32_t	max_packet_size;
103 	uint8_t		charset_no;
104 	/* Here the packet ends. This is user supplied data */
105 	zend_bool	send_auth_data;
106 	zend_bool	is_change_user_packet;
107 	zend_bool	silent;
108 	HashTable	*connect_attr;
109 	size_t		db_len;
110 } MYSQLND_PACKET_AUTH;
111 
112 /* Auth response packet */
113 typedef struct st_mysqlnd_packet_auth_response {
114 	MYSQLND_PACKET_HEADER		header;
115 	uint8_t		response_code;
116 	uint64_t	affected_rows;
117 	uint64_t	last_insert_id;
118 	uint16_t	server_status;
119 	uint16_t	warning_count;
120 	char		*message;
121 	size_t		message_len;
122 	/* If error packet, we use these */
123 	char 		error[MYSQLND_ERRMSG_SIZE+1];
124 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
125 	unsigned int 	error_no;
126 
127 	char		*new_auth_protocol;
128 	size_t		new_auth_protocol_len;
129 	zend_uchar	*new_auth_protocol_data;
130 	size_t		new_auth_protocol_data_len;
131 } MYSQLND_PACKET_AUTH_RESPONSE;
132 
133 
134 /* Auth response packet */
135 typedef struct st_mysqlnd_packet_change_auth_response {
136 	MYSQLND_PACKET_HEADER		header;
137 	const zend_uchar	*auth_data;
138 	size_t				auth_data_len;
139 } MYSQLND_PACKET_CHANGE_AUTH_RESPONSE;
140 
141 
142 /* OK packet */
143 typedef struct st_mysqlnd_packet_ok {
144 	MYSQLND_PACKET_HEADER		header;
145 	uint8_t		field_count; /* always 0x0 */
146 	uint64_t	affected_rows;
147 	uint64_t	last_insert_id;
148 	uint16_t	server_status;
149 	uint16_t	warning_count;
150 	char		*message;
151 	size_t		message_len;
152 	/* If error packet, we use these */
153 	char 		error[MYSQLND_ERRMSG_SIZE+1];
154 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
155 	unsigned int 	error_no;
156 } MYSQLND_PACKET_OK;
157 
158 
159 /* Command packet */
160 typedef struct st_mysqlnd_packet_command {
161 	MYSQLND_PACKET_HEADER			header;
162 	enum php_mysqlnd_server_command	command;
163 	MYSQLND_CSTRING	argument;
164 } MYSQLND_PACKET_COMMAND;
165 
166 
167 /* EOF packet */
168 typedef struct st_mysqlnd_packet_eof {
169 	MYSQLND_PACKET_HEADER		header;
170 	uint8_t		field_count; /* 0xFE */
171 	uint16_t	warning_count;
172 	uint16_t	server_status;
173 	/* If error packet, we use these */
174 	char 		error[MYSQLND_ERRMSG_SIZE+1];
175 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
176 	unsigned int 	error_no;
177 } MYSQLND_PACKET_EOF;
178 /* EOF packet */
179 
180 
181 /* Result Set header*/
182 typedef struct st_mysqlnd_packet_rset_header {
183 	MYSQLND_PACKET_HEADER header;
184 	/*
185 	  0x00 => ok
186 	  ~0   => LOAD DATA LOCAL
187 	  error_no != 0 => error
188 	  others => result set -> Read res_field packets up to field_count
189 	*/
190 	zend_ulong		field_count;
191 	/*
192 	  These are filled if no SELECT query. For SELECT warning_count
193 	  and server status are in the last row packet, the EOF packet.
194 	*/
195 	uint16_t	warning_count;
196 	uint16_t	server_status;
197 	uint64_t	affected_rows;
198 	uint64_t	last_insert_id;
199 	/* This is for both LOAD DATA or info, when no result set */
200 	MYSQLND_STRING info_or_local_file;
201 	/* If error packet, we use these */
202 	MYSQLND_ERROR_INFO	error_info;
203 } MYSQLND_PACKET_RSET_HEADER;
204 
205 
206 /* Result set field packet */
207 typedef struct st_mysqlnd_packet_res_field {
208 	MYSQLND_PACKET_HEADER	header;
209 	MYSQLND_FIELD			*metadata;
210 	/* For table definitions, empty for result sets */
211 	zend_bool				skip_parsing;
212 	zend_bool				persistent_alloc;
213 
214 	MYSQLND_ERROR_INFO		error_info;
215 } MYSQLND_PACKET_RES_FIELD;
216 
217 
218 /* Row packet */
219 typedef struct st_mysqlnd_packet_row {
220 	MYSQLND_PACKET_HEADER	header;
221 	zval		*fields;
222 	uint32_t	field_count;
223 	zend_bool	eof;
224 	/*
225 	  These are, of course, only for SELECT in the EOF packet,
226 	  which is detected by this packet
227 	*/
228 	uint16_t	warning_count;
229 	uint16_t	server_status;
230 
231 	struct st_mysqlnd_memory_pool_chunk	*row_buffer;
232 	MYSQLND_MEMORY_POOL * result_set_memory_pool;
233 
234 	zend_bool		skip_extraction;
235 	zend_bool		binary_protocol;
236 	zend_bool		persistent_alloc;
237 	MYSQLND_FIELD	*fields_metadata;
238 
239 	/* If error packet, we use these */
240 	MYSQLND_ERROR_INFO	error_info;
241 } MYSQLND_PACKET_ROW;
242 
243 
244 /* Statistics packet */
245 typedef struct st_mysqlnd_packet_stats {
246 	MYSQLND_PACKET_HEADER	header;
247 	MYSQLND_STRING message;
248 } MYSQLND_PACKET_STATS;
249 
250 
251 /* COM_PREPARE response packet */
252 typedef struct st_mysqlnd_packet_prepare_response {
253 	MYSQLND_PACKET_HEADER	header;
254 	/* also known as field_count 0x00=OK , 0xFF=error */
255 	unsigned char	error_code;
256 	zend_ulong	stmt_id;
257 	unsigned int	field_count;
258 	unsigned int	param_count;
259 	unsigned int	warning_count;
260 
261 	/* present in case of error */
262 	MYSQLND_ERROR_INFO	error_info;
263 } MYSQLND_PACKET_PREPARE_RESPONSE;
264 
265 
266 /* Statistics packet */
267 typedef struct st_mysqlnd_packet_chg_user_resp {
268 	MYSQLND_PACKET_HEADER	header;
269 	uint32_t			response_code;
270 
271 	/* message_len is not part of the packet*/
272 	uint16_t			server_capabilities;
273 	/* If error packet, we use these */
274 	MYSQLND_ERROR_INFO	error_info;
275 	zend_bool			server_asked_323_auth;
276 
277 	char		*new_auth_protocol;
278 	size_t		new_auth_protocol_len;
279 	zend_uchar	*new_auth_protocol_data;
280 	size_t		new_auth_protocol_data_len;
281 } MYSQLND_PACKET_CHG_USER_RESPONSE;
282 
283 
284 /* Command packet */
285 typedef struct st_mysqlnd_packet_sha256_pk_request {
286 	MYSQLND_PACKET_HEADER			header;
287 } MYSQLND_PACKET_SHA256_PK_REQUEST;
288 
289 typedef struct  st_mysqlnd_packet_sha256_pk_request_response {
290 	MYSQLND_PACKET_HEADER	header;
291 	zend_uchar 				*public_key;
292 	size_t					public_key_len;
293 } MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE;
294 
295 
296 zend_ulong		php_mysqlnd_net_field_length(const zend_uchar **packet);
297 zend_uchar *	php_mysqlnd_net_store_length(zend_uchar *packet, const uint64_t length);
298 size_t			php_mysqlnd_net_store_length_size(uint64_t length);
299 
300 PHPAPI extern const char * const mysqlnd_empty_string;
301 
302 enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
303 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
304 										 zend_bool as_int_or_float, MYSQLND_STATS * stats);
305 
306 
307 enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
308 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
309 										 zend_bool as_int_or_float, MYSQLND_STATS * stats);
310 
311 enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval * fields,
312 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
313 										 zend_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 zend_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 
321 /*
322  * Local variables:
323  * tab-width: 4
324  * c-basic-offset: 4
325  * End:
326  * vim600: noet sw=4 ts=4 fdm=marker
327  * vim<600: noet sw=4 ts=4
328  */
329