2 * Routines for mysql packet dissection
4 * Huagang XIE <huagang@intruvert.com>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * Copied from packet-tftp.c
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 * the protocol spec at
30 * http://public.logicacmg.com/~redferni/mysql/MySQL-Protocol.html
31 * and MySQL source code
39 #include <epan/packet.h>
40 #include <epan/conversation.h>
41 #include <epan/emem.h>
43 #include "packet-tcp.h"
44 #include <epan/reassemble.h>
45 #include <epan/prefs.h>
48 #define MYSQL_CAPS_LP 0x0001
49 #define MYSQL_CAPS_FR 0x0002
50 #define MYSQL_CAPS_LF 0x0004
51 #define MYSQL_CAPS_CD 0x0008
52 #define MYSQL_CAPS_NS 0x0010
53 #define MYSQL_CAPS_CP 0x0020
54 #define MYSQL_CAPS_OB 0x0040
55 #define MYSQL_CAPS_LI 0x0080
56 #define MYSQL_CAPS_IS 0x0100
57 #define MYSQL_CAPS_CU 0x0200
58 #define MYSQL_CAPS_IA 0x0400
59 #define MYSQL_CAPS_SL 0x0800
60 #define MYSQL_CAPS_II 0x1000
61 #define MYSQL_CAPS_TA 0x2000
63 static int proto_mysql = -1;
64 static int hf_mysql_packet_length= -1;
65 static int hf_mysql_packet_number= -1;
66 static int hf_mysql_opcode= -1;
67 static int hf_mysql_response_code= -1;
68 static int hf_mysql_error_code= -1;
69 static int hf_mysql_payload= -1;
70 static int hf_mysql_protocol= -1;
71 static int hf_mysql_caps= -1;
72 static int hf_mysql_cap_long_password= -1;
73 static int hf_mysql_cap_found_rows= -1;
74 static int hf_mysql_cap_long_flag= -1;
75 static int hf_mysql_cap_connect_with_db= -1;
76 static int hf_mysql_cap_no_schema= -1;
77 static int hf_mysql_cap_compress= -1;
78 static int hf_mysql_cap_odbc= -1;
79 static int hf_mysql_cap_local_files= -1;
80 static int hf_mysql_cap_ignore_space= -1;
81 static int hf_mysql_cap_change_user= -1;
82 static int hf_mysql_cap_interactive= -1;
83 static int hf_mysql_cap_ssl= -1;
84 static int hf_mysql_cap_ignore_sigpipe= -1;
85 static int hf_mysql_cap_transactions= -1;
86 static int hf_mysql_version = -1;
87 static int hf_mysql_max_packet= -1;
88 static int hf_mysql_user= -1;
89 static int hf_mysql_password= -1;
90 static int hf_mysql_thread_id = -1;
91 static int hf_mysql_salt= -1;
92 static int hf_mysql_charset= -1;
93 static int hf_mysql_status= -1;
94 static int hf_mysql_unused= -1;
95 static int hf_mysql_parameter= -1;
97 static gint ett_mysql = -1;
98 static gint ett_server_greeting = -1;
99 static gint ett_caps = -1;
100 static gint ett_request = -1;
102 static gboolean mysql_desegment = TRUE;
104 #define TCP_PORT_MySQL 3306
106 #define MySQL_SLEEP 0
108 #define MySQL_INIT_DB 2
109 #define MySQL_QUERY 3
110 #define MySQL_FIELD_LIST 4
111 #define MySQL_CREATE_DB 5
112 #define MySQL_DROP_DB 6
113 #define MySQL_REFRESH 7
114 #define MySQL_SHUTDOWN 8
115 #define MySQL_STATISTICS 9
116 #define MySQL_PROCESS_INFO 10
117 #define MySQL_CONNECT 11
118 #define MySQL_PROCESS_KILL 12
119 #define MySQL_DEBUG 13
120 #define MySQL_PING 14
121 #define MySQL_TIME 15
122 #define MySQL_DELAY_INSERT 16
123 #define MySQL_CHANGE_USER 17
124 #define MySQL_BINLOG_DUMP 18
125 #define MySQL_TABLE_DUMP 19
126 #define MySQL_CONNECT_OUT 20
129 static const value_string mysql_opcode_vals[] = {
130 { MySQL_SLEEP, "SLEEP" },
131 { MySQL_QUIT, "Quit" },
132 { MySQL_INIT_DB, "Init Database" },
133 { MySQL_QUERY, "Query" },
134 { MySQL_FIELD_LIST, "Field List" },
135 { MySQL_CREATE_DB, "Create Database" },
136 { MySQL_DROP_DB , "Drop Database" },
137 { MySQL_REFRESH , "Refresh" },
138 { MySQL_SHUTDOWN , "Shutdown" },
139 { MySQL_STATISTICS , "Statistics" },
140 { MySQL_PROCESS_INFO , "Process Info" },
141 { MySQL_CONNECT , "Connect" },
142 { MySQL_PROCESS_KILL , "Process Kill" },
143 { MySQL_DEBUG , "Debug" },
144 { MySQL_PING , "Ping" },
145 { MySQL_TIME , "Time" },
146 { MySQL_DELAY_INSERT , "Delay Insert" },
147 { MySQL_CHANGE_USER , "Change User" },
148 { MySQL_BINLOG_DUMP , "Binlog Dump" },
149 { MySQL_TABLE_DUMP, "Table Dump" },
150 { MySQL_CONNECT_OUT, "Table Connect Out" },
154 static const value_string mysql_status_vals[] = {
159 static const value_string mysql_charset_vals[] = {
193 static const value_string mysql_error_code_vals[] = {
194 { 0, "Not defined" },
195 { 1, "File not found" },
196 { 2, "Access violation" },
197 { 3, "Disk full or allocation exceeded" },
198 { 4, "Illegal MySQL Operation" },
199 { 5, "Unknown transfer ID" },
200 { 6, "File already exists" },
201 { 7, "No such user" },
202 { 8, "Option negotiation failed" },
207 static guint get_mysql_pdu_len(tvbuff_t *tvb, int offset);
208 static void dissect_mysql_pdu(tvbuff_t *tvb, packet_info *pinfo,
210 static int mysql_dissect_server_greeting(tvbuff_t *tvb, packet_info *pinfo,
211 int offset, proto_tree *tree);
212 static int mysql_dissect_authentication(tvbuff_t *tvb, packet_info *pinfo,
213 int offset, proto_tree *tree);
214 static int mysql_dissect_request(tvbuff_t *tvb, packet_info *pinfo,
215 int offset, proto_tree *tree);
216 static int mysql_dissect_response(tvbuff_t *tvb, packet_info *pinfo,
217 int offset, proto_tree *tree);
220 dissect_mysql(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
222 tcp_dissect_pdus(tvb, pinfo, tree, mysql_desegment, 3,
223 get_mysql_pdu_len, dissect_mysql_pdu);
227 get_mysql_pdu_len(tvbuff_t *tvb, int offset)
232 * Get the length of the MySQL packet.
234 plen = tvb_get_letoh24(tvb, offset);
237 * That length doesn't include the length field or the packet
238 * number itself; add them in.
244 dissect_mysql_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
246 proto_tree *mysql_tree = NULL;
248 conversation_t *conversation;
253 gboolean is_response;
255 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
256 pinfo->srcport, pinfo->destport, 0);
259 /* create a new conversation */
260 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
261 pinfo->srcport, pinfo->destport, 0);
265 if (check_col(pinfo->cinfo, COL_PROTOCOL))
266 col_set_str(pinfo->cinfo, COL_PROTOCOL, "MySQL");
268 if (pinfo->destport == pinfo->match_port) {
275 ti = proto_tree_add_item(tree, proto_mysql, tvb, offset, -1, FALSE);
276 mysql_tree = proto_item_add_subtree(ti, ett_mysql);
278 proto_tree_add_item(mysql_tree, hf_mysql_packet_length, tvb,
283 packet_number= tvb_get_guint8(tvb, offset);
285 proto_tree_add_uint(mysql_tree, hf_mysql_packet_number, tvb,
286 offset, 1, packet_number);
291 * packet == 0 && response --> server greeting
292 * packet == 1 && request --> login request
295 if( packet_number == 0 ) {
296 if (check_col(pinfo->cinfo, COL_INFO)) {
297 col_add_str(pinfo->cinfo, COL_INFO, "Server Greeting" ) ;
299 offset = mysql_dissect_server_greeting(tvb,pinfo,offset,mysql_tree);
301 if (check_col(pinfo->cinfo, COL_INFO)) {
302 col_add_str(pinfo->cinfo, COL_INFO, "Response" ) ;
304 offset = mysql_dissect_response(tvb,pinfo,offset,mysql_tree);
307 if( packet_number == 1 ) {
308 if (check_col(pinfo->cinfo, COL_INFO)) {
309 col_add_str(pinfo->cinfo, COL_INFO, "Login Request") ;
311 offset = mysql_dissect_authentication(tvb,pinfo,offset,mysql_tree);
313 if (check_col(pinfo->cinfo, COL_INFO)) {
314 col_add_str(pinfo->cinfo, COL_INFO, "Request") ;
316 offset = mysql_dissect_request(tvb,pinfo,offset,mysql_tree);
321 if (tree && tvb_reported_length_remaining(tvb, offset) > 0) {
322 proto_tree_add_item(mysql_tree, hf_mysql_payload,
323 tvb, offset, -1, FALSE);
327 mysql_dissect_response(tvbuff_t *tvb, packet_info *pinfo,
328 int offset, proto_tree *tree)
334 response_code= tvb_get_guint8(tvb, offset);
336 proto_tree_add_uint(tree, hf_mysql_response_code, tvb,
337 offset, 1, response_code);
341 if(response_code== 0xff ) {
343 error_code = tvb_get_letohs(tvb, offset);
344 if (check_col(pinfo->cinfo, COL_INFO)) {
345 col_append_fstr(pinfo->cinfo, COL_INFO, " Error Code: %x", error_code );
348 proto_tree_add_uint(tree, hf_mysql_error_code, tvb,
349 offset, 2, error_code);
354 if (check_col(pinfo->cinfo, COL_INFO)) {
355 col_append_str(pinfo->cinfo, COL_INFO, " OK" );
362 mysql_dissect_request(tvbuff_t *tvb,packet_info *pinfo,
363 int offset, proto_tree *tree)
368 proto_item *req_tree=NULL;
371 tf=proto_tree_add_text(tree,tvb,offset,-1,"Command");
372 req_tree = proto_item_add_subtree(tf ,ett_request);
375 opcode = tvb_get_guint8(tvb, offset);
377 if (check_col(pinfo->cinfo, COL_INFO)) {
378 col_append_fstr(pinfo->cinfo, COL_INFO, " Command: %s",
379 val_to_str(opcode, mysql_opcode_vals, "Unknown (%u)"));
383 proto_tree_add_uint_format(req_tree, hf_mysql_opcode, tvb,
384 offset , 1, opcode, "Command: %s (%u)",
385 val_to_str(opcode, mysql_opcode_vals, "Unknown (%u)"),opcode);
387 /* command parameter */
390 if ( (strlen = tvb_length_remaining(tvb,offset)) > 0 ) {
392 if (check_col(pinfo->cinfo, COL_INFO)) {
393 col_append_fstr(pinfo->cinfo, COL_INFO, " : %s",
394 tvb_format_text(tvb,offset,strlen));
398 proto_tree_add_item(req_tree, hf_mysql_parameter, tvb,
399 offset, strlen, FALSE );
409 mysql_dissect_authentication(tvbuff_t *tvb, packet_info *pinfo,
410 int offset, proto_tree *tree)
417 proto_item *cap_tree;
418 proto_item *login_tree=NULL;
421 tf=proto_tree_add_text(tree,tvb,offset,-1,"Login Packet");
422 login_tree = proto_item_add_subtree(tf ,ett_server_greeting);
425 client_caps= tvb_get_letohs(tvb, offset);
427 if (check_col(pinfo->cinfo, COL_INFO)) {
428 col_append_fstr(pinfo->cinfo, COL_INFO, " Caps: 0x%x",client_caps) ;
431 tf = proto_tree_add_uint_format(login_tree, hf_mysql_caps, tvb, offset , 1, client_caps, "Caps: 0x%04x ", client_caps );
432 cap_tree = proto_item_add_subtree(tf, ett_caps);
433 proto_tree_add_boolean(cap_tree, hf_mysql_cap_long_password, tvb, offset, 2, client_caps);
434 proto_tree_add_boolean(cap_tree, hf_mysql_cap_found_rows, tvb, offset, 2, client_caps);
435 proto_tree_add_boolean(cap_tree, hf_mysql_cap_long_flag, tvb, offset, 2, client_caps);
436 proto_tree_add_boolean(cap_tree, hf_mysql_cap_connect_with_db, tvb, offset, 2, client_caps);
437 proto_tree_add_boolean(cap_tree, hf_mysql_cap_no_schema, tvb, offset, 2, client_caps);
438 proto_tree_add_boolean(cap_tree, hf_mysql_cap_compress, tvb, offset, 2, client_caps);
439 proto_tree_add_boolean(cap_tree, hf_mysql_cap_odbc, tvb, offset, 2, client_caps);
440 proto_tree_add_boolean(cap_tree, hf_mysql_cap_local_files, tvb, offset, 2, client_caps);
441 proto_tree_add_boolean(cap_tree, hf_mysql_cap_ignore_space, tvb, offset, 2, client_caps);
442 proto_tree_add_boolean(cap_tree, hf_mysql_cap_change_user, tvb, offset, 2, client_caps);
443 proto_tree_add_boolean(cap_tree, hf_mysql_cap_interactive, tvb, offset, 2, client_caps);
444 proto_tree_add_boolean(cap_tree, hf_mysql_cap_ssl, tvb, offset, 2, client_caps);
445 proto_tree_add_boolean(cap_tree, hf_mysql_cap_ignore_sigpipe, tvb, offset, 2, client_caps);
446 proto_tree_add_boolean(cap_tree, hf_mysql_cap_transactions, tvb, offset, 2, client_caps);
449 /* proto_tree_add_uint(tree, hf_mysql_client_caps, tvb,
450 offset, 2, client_caps);
453 /* 3 bytes max packet, 16777216 - x */
454 max_packet = 0xffffff - tvb_get_letoh24(tvb, offset);
456 proto_tree_add_uint(login_tree, hf_mysql_max_packet, tvb,
457 offset, 3, max_packet);
461 strlen = tvb_strsize(tvb,offset);
463 if (check_col(pinfo->cinfo, COL_INFO)) {
464 col_append_fstr(pinfo->cinfo, COL_INFO, " ,user: %s",
465 tvb_get_ptr(tvb,offset,strlen));
468 proto_tree_add_item(login_tree, hf_mysql_user, tvb,
469 offset, strlen, FALSE );
474 strlen = tvb_length_remaining(tvb,offset);
476 if (check_col(pinfo->cinfo, COL_INFO)) {
477 col_append_fstr(pinfo->cinfo, COL_INFO, " ,password: %s",
478 tvb_get_ptr(tvb,offset,strlen));
481 proto_tree_add_item(login_tree, hf_mysql_password, tvb,
482 offset, strlen, FALSE );
492 mysql_dissect_server_greeting(tvbuff_t *tvb, packet_info *pinfo,
493 int offset, proto_tree *tree)
503 proto_item *greeting_tree=NULL;
504 proto_item *cap_tree;
506 protocol= tvb_get_guint8(tvb, offset);
509 tf = proto_tree_add_text(tree,tvb,offset,-1,"Server Greeting");
510 greeting_tree = proto_item_add_subtree(tf ,ett_server_greeting);
513 if (check_col(pinfo->cinfo, COL_INFO)) {
514 col_append_fstr(pinfo->cinfo, COL_INFO, " Protocol : %d",protocol) ;
517 proto_tree_add_uint(greeting_tree, hf_mysql_protocol, tvb,
518 offset, 1, protocol);
523 strlen = tvb_strsize(tvb,offset);
525 if (check_col(pinfo->cinfo, COL_INFO)) {
526 col_append_fstr(pinfo->cinfo, COL_INFO, " ,version: %s",
527 tvb_get_ptr(tvb,offset,strlen));
530 proto_tree_add_item(greeting_tree, hf_mysql_version, tvb,
531 offset, strlen, FALSE );
535 /* 4 bytes little endian thread_id */
536 thread_id = tvb_get_letohl(tvb, offset);
538 proto_tree_add_uint(greeting_tree, hf_mysql_thread_id, tvb,
539 offset, 4, thread_id);
543 strlen = tvb_strsize(tvb,offset);
545 proto_tree_add_item(greeting_tree, hf_mysql_salt, tvb,
546 offset, strlen, FALSE );
550 server_caps= tvb_get_letohs(tvb, offset);
552 if (check_col(pinfo->cinfo, COL_INFO)) {
553 col_append_fstr(pinfo->cinfo, COL_INFO, " Caps: 0x%x",server_caps) ;
556 tf = proto_tree_add_uint_format(greeting_tree, hf_mysql_caps, tvb, offset , 1, server_caps, "Caps: 0x%04x ", server_caps );
557 cap_tree = proto_item_add_subtree(tf, ett_caps);
558 proto_tree_add_boolean(cap_tree, hf_mysql_cap_long_password, tvb, offset, 2, server_caps);
559 proto_tree_add_boolean(cap_tree, hf_mysql_cap_found_rows, tvb, offset, 2, server_caps);
560 proto_tree_add_boolean(cap_tree, hf_mysql_cap_long_flag, tvb, offset, 2, server_caps);
561 proto_tree_add_boolean(cap_tree, hf_mysql_cap_connect_with_db, tvb, offset, 2, server_caps);
562 proto_tree_add_boolean(cap_tree, hf_mysql_cap_no_schema, tvb, offset, 2, server_caps);
563 proto_tree_add_boolean(cap_tree, hf_mysql_cap_compress, tvb, offset, 2, server_caps);
564 proto_tree_add_boolean(cap_tree, hf_mysql_cap_odbc, tvb, offset, 2, server_caps);
565 proto_tree_add_boolean(cap_tree, hf_mysql_cap_local_files, tvb, offset, 2, server_caps);
566 proto_tree_add_boolean(cap_tree, hf_mysql_cap_ignore_space, tvb, offset, 2, server_caps);
567 proto_tree_add_boolean(cap_tree, hf_mysql_cap_change_user, tvb, offset, 2, server_caps);
568 proto_tree_add_boolean(cap_tree, hf_mysql_cap_interactive, tvb, offset, 2, server_caps);
569 proto_tree_add_boolean(cap_tree, hf_mysql_cap_ssl, tvb, offset, 2, server_caps);
570 proto_tree_add_boolean(cap_tree, hf_mysql_cap_ignore_sigpipe, tvb, offset, 2, server_caps);
571 proto_tree_add_boolean(cap_tree, hf_mysql_cap_transactions, tvb, offset, 2, server_caps);
575 charset = tvb_get_guint8(tvb, offset);
577 proto_tree_add_uint_format(greeting_tree, hf_mysql_charset, tvb,
578 offset, 1, charset, "Charset: %s (%u)",
579 val_to_str(charset, mysql_charset_vals, "Unknown (%u)"), charset);
583 status = tvb_get_letohs(tvb, offset);
585 proto_tree_add_uint_format(greeting_tree, hf_mysql_status, tvb,
586 offset, 2, status, "Status: %s (%u)",
587 val_to_str(status, mysql_status_vals, "Unknown (%u)"), status);
591 strlen = tvb_length_remaining(tvb,offset);
594 proto_tree_add_item(greeting_tree, hf_mysql_unused, tvb,
595 offset, strlen, FALSE );
603 proto_register_mysql(void)
605 static hf_register_info hf[] = {
606 { &hf_mysql_packet_length,
607 { "Packet Length", "mysql.packet_length",
608 FT_UINT24, BASE_DEC, NULL, 0x0,
609 "MySQL packet length", HFILL }},
611 { &hf_mysql_packet_number,
612 { "Packet Number", "mysql.packet_number",
613 FT_UINT8, BASE_DEC, NULL, 0x0,
614 "MySQL Packet Number", HFILL }},
617 { "Command", "mysql.opcode",
618 FT_UINT8, BASE_DEC, NULL, 0x0,
619 "MySQL OPCODE", HFILL }},
621 { &hf_mysql_response_code,
622 { "Response Code", "mysql.response_code",
623 FT_UINT8, BASE_DEC, NULL, 0x0,
624 "MySQL Respone Code", HFILL }},
626 { &hf_mysql_error_code,
627 { "Error Code", "mysql.error_code",
628 FT_UINT16, BASE_DEC, NULL, 0x0,
629 "MySQL Error CODE", HFILL }},
631 { &hf_mysql_protocol,
632 { "Protocol", "mysql.protocol",
633 FT_UINT8, BASE_DEC, NULL, 0x0,
634 "MySQL Protocol", HFILL }},
637 { "Version", "mysql.version",
638 FT_STRINGZ, BASE_DEC, NULL, 0x0,
639 "MySQL Version", HFILL }},
642 { "Caps", "mysql.caps",
643 FT_UINT16, BASE_DEC, NULL, 0x0,
644 "MySQL Capabilities", HFILL }},
646 { &hf_mysql_cap_long_password,
647 { "Long Password","mysql.caps.lp",
648 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_LP,
651 { &hf_mysql_cap_found_rows,
652 { "Found Rows","mysql.caps.fr",
653 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_FR,
657 { &hf_mysql_cap_long_flag,
658 { "Long Flag","mysql.caps.lf",
659 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_LF,
662 { &hf_mysql_cap_connect_with_db,
663 { "Connect With Database","mysql.caps.cd",
664 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_CD,
668 { &hf_mysql_cap_no_schema,
669 { "Dont Allow database.table.column","mysql.caps.ns",
670 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_NS,
673 { &hf_mysql_cap_compress,
674 { "Can use compression protocol","mysql.caps.CP",
675 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_CP,
678 { &hf_mysql_cap_odbc,
679 { "ODBC Client","mysql.caps.ob",
680 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_OB,
684 { &hf_mysql_cap_local_files,
685 { "Can Use LOAD DATA LOCAL","mysql.caps.li",
686 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_LI,
689 { &hf_mysql_cap_ignore_space,
690 { "Ignore Spaces before (","mysql.caps.is",
691 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_IS,
695 { &hf_mysql_cap_change_user,
696 { "Support the mysql_change_user()","mysql.caps.cu",
697 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_CU,
701 { &hf_mysql_cap_interactive,
702 { "an Interactive Client","mysql.caps.ia",
703 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_IA,
708 { "Switch to SSL after handshake","mysql.caps.sl",
709 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_SL,
712 { &hf_mysql_cap_ignore_sigpipe,
713 { "Ignore sigpipes","mysql.caps.ii",
714 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_II,
717 { &hf_mysql_cap_transactions,
718 { "Client knows about transactions","mysql.caps.ta",
719 FT_BOOLEAN, 16, TFS(&flags_set_truth), MYSQL_CAPS_TA,
722 { &hf_mysql_max_packet,
723 { "MAX Packet", "mysql.max_packet",
724 FT_UINT24, BASE_DEC, NULL, 0x0,
725 "MySQL Max packet", HFILL }},
728 { "Username", "mysql.user",
729 FT_STRINGZ, BASE_DEC, NULL, 0x0,
730 "Login Username", HFILL }},
732 { &hf_mysql_password,
733 { "Password", "mysql.password",
734 FT_STRING, BASE_DEC, NULL, 0x0,
735 "Login Password", HFILL }},
738 { "Salt", "mysql.salt",
739 FT_STRINGZ, BASE_DEC, NULL, 0x0,
742 { &hf_mysql_thread_id,
743 { "Thread ID", "mysql.thread_id",
744 FT_UINT32, BASE_DEC, NULL, 0x0,
745 "MySQL Thread ID", HFILL }},
748 { "Charset", "mysql.charset",
749 FT_UINT8, BASE_DEC, NULL, 0x0,
750 "MySQL Charset", HFILL }},
753 { "Status", "mysql.status",
754 FT_UINT16, BASE_DEC, NULL, 0x0,
755 "MySQL Status", HFILL }},
758 { "Unused", "mysql.unused",
759 FT_STRING, BASE_DEC, NULL, 0x0,
762 { &hf_mysql_parameter,
763 { "Parameter", "mysql.parameter",
764 FT_STRING, BASE_DEC, NULL, 0x0,
765 "Parameter", HFILL }},
767 { "Payload", "mysql.payload",
768 FT_STRING, BASE_DEC, NULL, 0x0,
769 "MySQL Payload", HFILL }},
771 { &hf_mysql_destination_file,
772 { "DESTINATION File", "mysql.destination_file",
773 FT_STRINGZ, BASE_DEC, NULL, 0x0,
774 "MySQL source file name", HFILL }},
776 { &hf_mysql_blocknum,
777 { "Block", "mysql.block",
778 FT_UINT16, BASE_DEC, NULL, 0x0,
779 "Block number", HFILL }},
781 { &hf_mysql_error_code,
782 { "Error code", "mysql.error.code",
783 FT_UINT16, BASE_DEC, VALS(mysql_error_code_vals), 0x0,
784 "Error code in case of MySQL error message", HFILL }},
786 { &hf_mysql_error_string,
787 { "Error message", "mysql.error.message",
788 FT_STRINGZ, BASE_DEC, NULL, 0x0,
789 "Error string in case of MySQL error message", HFILL }},
792 static gint *ett[] = {
794 &ett_server_greeting,
798 module_t *mysql_module;
800 proto_mysql = proto_register_protocol("MySQL Protocol",
802 proto_register_field_array(proto_mysql, hf, array_length(hf));
803 proto_register_subtree_array(ett, array_length(ett));
805 mysql_module = prefs_register_protocol(proto_mysql, NULL);
806 prefs_register_bool_preference(mysql_module, "desegment_buffers",
807 "Reassemble MySQL buffers spanning multiple TCP segments",
808 "Whether the MySQL dissector should reassemble MySQL buffers spanning multiple TCP segments."
809 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
814 proto_reg_handoff_mysql(void)
816 dissector_handle_t mysql_handle;
818 mysql_handle = create_dissector_handle(dissect_mysql, proto_mysql);
820 dissector_add("tcp.port", TCP_PORT_MySQL, mysql_handle);