1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 2006-2015 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@mysql.com>                           |
16   |          Ulf Wendel <uwendel@mysql.com>                              |
17   |          Georg Richter <georg@mysql.com>                             |
18   +----------------------------------------------------------------------+
19 */
20 
21 /* $Id$ */
22 
23 #ifndef MYSQLND_WIREPROTOCOL_H
24 #define MYSQLND_WIREPROTOCOL_H
25 
26 #include "mysqlnd_net.h"
27 
28 #define MYSQLND_HEADER_SIZE 4
29 #define COMPRESSED_HEADER_SIZE 3
30 
31 #define MYSQLND_NULL_LENGTH	(unsigned long) ~0
32 
33 /* Used in mysqlnd_debug.c */
34 PHPAPI extern const char mysqlnd_read_header_name[];
35 PHPAPI extern const char mysqlnd_read_body_name[];
36 
37 
38 /* Packet handling */
39 #define PACKET_WRITE(packet, conn)	((packet)->header.m->write_to_net((packet), (conn) TSRMLS_CC))
40 #define PACKET_READ(packet, conn)	((packet)->header.m->read_from_net((packet), (conn) TSRMLS_CC))
41 #define PACKET_FREE(packet) \
42 	do { \
43 		DBG_INF_FMT("PACKET_FREE(%p)", packet); \
44 		if ((packet)) { \
45 			((packet)->header.m->free_mem((packet), FALSE TSRMLS_CC)); \
46 		} \
47 	} while (0);
48 
49 PHPAPI extern const char * const mysqlnd_command_to_text[COM_END];
50 
51 /* Low-level extraction functionality */
52 typedef struct st_mysqlnd_packet_methods {
53 	size_t				struct_size;
54 	enum_func_status	(*read_from_net)(void * packet, MYSQLND_CONN_DATA * conn TSRMLS_DC);
55 	size_t				(*write_to_net)(void * packet, MYSQLND_CONN_DATA * conn TSRMLS_DC);
56 	void				(*free_mem)(void *packet, zend_bool stack_allocation TSRMLS_DC);
57 } mysqlnd_packet_methods;
58 
59 
60 typedef struct st_mysqlnd_packet_header {
61 	size_t		size;
62 	mysqlnd_packet_methods *m;
63 	zend_uchar	packet_no;
64 	zend_bool	persistent;
65 } MYSQLND_PACKET_HEADER;
66 
67 /* Server greets the client */
68 typedef struct st_mysqlnd_packet_greet {
69 	MYSQLND_PACKET_HEADER		header;
70 	uint8_t		protocol_version;
71 	char		*server_version;
72 	uint32_t	thread_id;
73 	zend_uchar	intern_auth_plugin_data[SCRAMBLE_LENGTH];
74 	zend_uchar	* auth_plugin_data;
75 	size_t		auth_plugin_data_len;
76 	/* 1 byte pad */
77 	uint32_t	server_capabilities;
78 	uint8_t		charset_no;
79 	uint16_t	server_status;
80 	/* 13 byte pad, in 5.5 first 2 bytes are more capabilities followed by 1 byte scramble_length */
81 	zend_bool	pre41;
82 	/* If error packet, we use these */
83 	char 		error[MYSQLND_ERRMSG_SIZE+1];
84 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
85 	unsigned int	error_no;
86 	char		*auth_protocol;
87 } MYSQLND_PACKET_GREET;
88 
89 
90 /* Client authenticates */
91 typedef struct st_mysqlnd_packet_auth {
92 	MYSQLND_PACKET_HEADER		header;
93 	uint32_t	client_flags;
94 	uint32_t	max_packet_size;
95 	uint8_t		charset_no;
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 	/* Here the packet ends. This is user supplied data */
102 	size_t		db_len;
103 	zend_bool	send_auth_data;
104 	zend_bool	is_change_user_packet;
105 	zend_bool	silent;
106 	HashTable	*connect_attr;
107 } MYSQLND_PACKET_AUTH;
108 
109 /* Auth response packet */
110 typedef struct st_mysqlnd_packet_auth_response {
111 	MYSQLND_PACKET_HEADER		header;
112 	uint8_t		response_code;
113 	uint64_t	affected_rows;
114 	uint64_t	last_insert_id;
115 	uint16_t	server_status;
116 	uint16_t	warning_count;
117 	char		*message;
118 	size_t		message_len;
119 	/* If error packet, we use these */
120 	char 		error[MYSQLND_ERRMSG_SIZE+1];
121 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
122 	unsigned int 	error_no;
123 
124 	char		*new_auth_protocol;
125 	size_t		new_auth_protocol_len;
126 	zend_uchar	*new_auth_protocol_data;
127 	size_t		new_auth_protocol_data_len;
128 } MYSQLND_PACKET_AUTH_RESPONSE;
129 
130 
131 /* Auth response packet */
132 typedef struct st_mysqlnd_packet_change_auth_response {
133 	MYSQLND_PACKET_HEADER		header;
134 	const zend_uchar	*auth_data;
135 	size_t				auth_data_len;
136 } MYSQLND_PACKET_CHANGE_AUTH_RESPONSE;
137 
138 
139 /* OK packet */
140 typedef struct st_mysqlnd_packet_ok {
141 	MYSQLND_PACKET_HEADER		header;
142 	uint8_t		field_count; /* always 0x0 */
143 	uint64_t	affected_rows;
144 	uint64_t	last_insert_id;
145 	uint16_t	server_status;
146 	uint16_t	warning_count;
147 	char		*message;
148 	size_t		message_len;
149 	/* If error packet, we use these */
150 	char 		error[MYSQLND_ERRMSG_SIZE+1];
151 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
152 	unsigned int 	error_no;
153 } MYSQLND_PACKET_OK;
154 
155 
156 /* Command packet */
157 typedef struct st_mysqlnd_packet_command {
158 	MYSQLND_PACKET_HEADER			header;
159 	enum php_mysqlnd_server_command	command;
160 	const zend_uchar				*argument;
161 	size_t							arg_len;
162 } MYSQLND_PACKET_COMMAND;
163 
164 
165 /* EOF packet */
166 typedef struct st_mysqlnd_packet_eof {
167 	MYSQLND_PACKET_HEADER		header;
168 	uint8_t		field_count; /* 0xFE */
169 	uint16_t	warning_count;
170 	uint16_t	server_status;
171 	/* If error packet, we use these */
172 	char 		error[MYSQLND_ERRMSG_SIZE+1];
173 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
174 	unsigned int 	error_no;
175 } MYSQLND_PACKET_EOF;
176 /* EOF packet */
177 
178 
179 /* Result Set header*/
180 typedef struct st_mysqlnd_packet_rset_header {
181 	MYSQLND_PACKET_HEADER		header;
182 	/*
183 	  0x00 => ok
184 	  ~0   => LOAD DATA LOCAL
185 	  error_no != 0 => error
186 	  others => result set -> Read res_field packets up to field_count
187 	*/
188 	unsigned long		field_count;
189 	/*
190 	  These are filled if no SELECT query. For SELECT warning_count
191 	  and server status are in the last row packet, the EOF packet.
192 	*/
193 	uint16_t	warning_count;
194 	uint16_t	server_status;
195 	uint64_t	affected_rows;
196 	uint64_t	last_insert_id;
197 	/* This is for both LOAD DATA or info, when no result set */
198 	char		*info_or_local_file;
199 	size_t		info_or_local_file_len;
200 	/* If error packet, we use these */
201 	MYSQLND_ERROR_INFO	error_info;
202 } MYSQLND_PACKET_RSET_HEADER;
203 
204 
205 /* Result set field packet */
206 typedef struct st_mysqlnd_packet_res_field {
207 	MYSQLND_PACKET_HEADER	header;
208 	MYSQLND_FIELD			*metadata;
209 	/* For table definitions, empty for result sets */
210 	zend_bool				skip_parsing;
211 	zend_bool				stupid_list_fields_eof;
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 	/* We need this to alloc bigger bufs in non-PS mode */
239 	unsigned int	bit_fields_count;
240 	size_t			bit_fields_total_len; /* trailing \0 not counted */
241 
242 	/* If error packet, we use these */
243 	MYSQLND_ERROR_INFO	error_info;
244 } MYSQLND_PACKET_ROW;
245 
246 
247 /* Statistics packet */
248 typedef struct st_mysqlnd_packet_stats {
249 	MYSQLND_PACKET_HEADER	header;
250 	char *message;
251 	/* message_len is not part of the packet*/
252 	size_t message_len;
253 } MYSQLND_PACKET_STATS;
254 
255 
256 /* COM_PREPARE response packet */
257 typedef struct st_mysqlnd_packet_prepare_response {
258 	MYSQLND_PACKET_HEADER	header;
259 	/* also known as field_count 0x00=OK , 0xFF=error */
260 	unsigned char	error_code;
261 	unsigned long	stmt_id;
262 	unsigned int	field_count;
263 	unsigned int	param_count;
264 	unsigned int	warning_count;
265 
266 	/* present in case of error */
267 	MYSQLND_ERROR_INFO	error_info;
268 } MYSQLND_PACKET_PREPARE_RESPONSE;
269 
270 
271 /* Statistics packet */
272 typedef struct st_mysqlnd_packet_chg_user_resp {
273 	MYSQLND_PACKET_HEADER	header;
274 	uint32_t			response_code;
275 
276 	/* message_len is not part of the packet*/
277 	uint16_t			server_capabilities;
278 	/* If error packet, we use these */
279 	MYSQLND_ERROR_INFO	error_info;
280 	zend_bool			server_asked_323_auth;
281 
282 	char		*new_auth_protocol;
283 	size_t		new_auth_protocol_len;
284 	zend_uchar	*new_auth_protocol_data;
285 	size_t		new_auth_protocol_data_len;
286 } MYSQLND_PACKET_CHG_USER_RESPONSE;
287 
288 
289 /* Command packet */
290 typedef struct st_mysqlnd_packet_sha256_pk_request {
291 	MYSQLND_PACKET_HEADER			header;
292 } MYSQLND_PACKET_SHA256_PK_REQUEST;
293 
294 typedef struct  st_mysqlnd_packet_sha256_pk_request_response {
295 	MYSQLND_PACKET_HEADER	header;
296 	zend_uchar 				*public_key;
297 	size_t					public_key_len;
298 } MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE;
299 
300 
301 PHPAPI void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const pass, size_t pass_len);
302 
303 unsigned long	php_mysqlnd_net_field_length(zend_uchar **packet);
304 zend_uchar *	php_mysqlnd_net_store_length(zend_uchar *packet, uint64_t length);
305 
306 PHPAPI const extern char * const mysqlnd_empty_string;
307 
308 
309 enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
310 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
311 										 zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
312 
313 
314 enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
315 										 unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
316 										 zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
317 
318 
319 PHPAPI MYSQLND_PROTOCOL * mysqlnd_protocol_init(zend_bool persistent TSRMLS_DC);
320 PHPAPI void mysqlnd_protocol_free(MYSQLND_PROTOCOL * const protocol TSRMLS_DC);
321 
322 #endif /* MYSQLND_WIREPROTOCOL_H */
323 
324 /*
325  * Local variables:
326  * tab-width: 4
327  * c-basic-offset: 4
328  * End:
329  * vim600: noet sw=4 ts=4 fdm=marker
330  * vim<600: noet sw=4 ts=4
331  */
332