需求
监听经由历程网卡的一切mysql流量,举行剖析,可在不影响现有营业情况下,举行入侵检测(IDS)或数据集成
协定要点
早先发明 用mysql-front接见数据库和mysql 的客户端接见时数据包花样差别,纠结良久,不明白,mysql-front源码看了眼,delphi,不懂,弃
紧缩剖析
当链接mysql时,若启用-C参数示意,关于衔接数据启用紧缩,紧缩花样为zlib
mysql的紧缩函数为:
// mysql-source/mysys/my_compress.c my_bool my_compress(uchar *packet, size_t *len, size_t *complen) { DBUG_ENTER("my_compress"); if (*len < MIN_COMPRESS_LENGTH) { *complen=0; DBUG_PRINT("note",("Packet too short: Not compressed")); } else { uchar *compbuf=my_compress_alloc(packet,len,complen); if (!compbuf) DBUG_RETURN(*complen ? 0 : 1); memcpy(packet,compbuf,*len); my_free(compbuf); } DBUG_RETURN(0); } uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen) { uchar *compbuf; uLongf tmp_complen; int res; *complen= *len * 120 / 100 + 12; if (!(compbuf= (uchar *) my_malloc(key_memory_my_compress_alloc, *complen, MYF(MY_WME)))) return 0; /* Not enough memory */ tmp_complen= (uint) *complen; res= compress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet, (uLong) *len); *complen= tmp_complen; if (res != Z_OK) { my_free(compbuf); return 0; } if (*complen >= *len) { *complen= 0; my_free(compbuf); DBUG_PRINT("note",("Packet got longer on compression; Not compressed")); return 0; } /* Store length of compressed packet in *len */ swap_variables(size_t, *len, *complen); return compbuf; }
个中第35行挪用了zlib中的compress()函数,然则该处仅对compress()举行了封装,并没有协定剖析部份,我们继承往下看。
全部项目寻觅目的代码比较费力,能够先在头文件中寻觅症结信息,因而找到了下面的代码
// mysql-source/include/sql_state.h { ER_NET_UNCOMPRESS_ERROR ,"08S01", "" }
这是在mysql在剖析紧缩的数据时假如失足的提醒信息和毛病码,顺次能够查找其援用,发明了真正的数据包紧缩代码
// mysql-source/sql/net_serv.cc static uchar * compress_packet(NET *net, const uchar *packet, size_t *length) { uchar *compr_packet; size_t compr_length; const uint header_length= NET_HEADER_SIZE + COMP_HEADER_SIZE; compr_packet= (uchar *) my_malloc(key_memory_NET_compress_packet, *length + header_length, MYF(MY_WME)); if (compr_packet == NULL) return NULL; memcpy(compr_packet + header_length, packet, *length); /* Compress the encapsulated packet. */ if (my_compress(compr_packet + header_length, length, &compr_length)) { /* If the length of the compressed packet is larger than the original packet, the original packet is sent uncompressed. */ compr_length= 0; } /* Length of the compressed (original) packet. */ int3store(&compr_packet[NET_HEADER_SIZE], static_cast<uint>(compr_length)); /* Length of this packet. */ int3store(compr_packet, static_cast<uint>(*length)); /* Packet number. */ compr_packet[3]= (uchar) (net->compress_pkt_nr++); *length+= header_length; return compr_packet; }
从8-19行能够看到,紧缩数据的组包历程,前面离别加了NET_HEADER_SIZE + COMP_HEADER_SIZE 长的掌握字段
查找该宏,发明其定义以下
1 // mysql-source/include/mysql_com.h 2 3 /* Constants when using compression */ 4 #define NET_HEADER_SIZE 4 /* standard header size */ 5 #define COMP_HEADER_SIZE 3 /* compression header extra size */
NET_HEADER_SIZE 字段中 长度字段存储 数据部份 未解压时的长度
COMP_HEADER_SIZE 字段是用来存储 解压后的 数据的长度,我们能够顺次请求内存,然后挪用zlib对紧缩内容举行剖析即可。
假如不剖析直接举行对wireshark抓到的数据举行zlib剖析的话,因为掌握字段的存在会解紧缩失利,在python中的报错以下
Traceback (most recent call last): File "<stdin>", line 1, in <module>zlib.error: Error -3 while decompressing data: incorrect data check
早先看到这个毛病很头痛也不想看zlib剖析细节,才有了从mysql找缘由的本文,如今能够纪录zlib 紧缩字符串的开首常常是\x78\x9c,涌现一样毛病的能够看看是不是准确
以上就是Mysql 协定嗅探是什么的细致内容,更多请关注ki4网别的相干文章!