文档章节

mysql协议解析之握手协议(handshake)

曾经的十字镐
 曾经的十字镐
发布于 2017/11/02 17:29
字数 705
阅读 106
收藏 0
go

要解析mysql协议需要了解一下知识和软件

一、wireshark

wireshark 是一款网络抓包工具,可以让我们很方便的查看mysql协议。

二、网络字节序

网络字节序分为大端法和小端法,它们的区别可以参考其它网站,在此不做叙述。

三、golang

golang是一款非常赞的开发语言,学习成本比较低,并发性能好的特点

mysql 协议文档详见:(http://www.cnblogs.com/davygeek/p/5647175.html)

mysql 协议分为报文头和报文体 输入图片说明 输入图片说明

这里为了简单起见,没有处理任何的异常情况

package main

import (
	"bytes"
	"fmt"
	"io"
	"net"
)

type Handshake struct {
	//1Byte 协议版本号
	protocol byte
	//n Byte 服务器版本信息(Null-Termimated-String)
	version string
	//4Byte服务器线程ID
	theadID int
	//8bytes 随机挑战数
	salt1 string
	//1Byte 填充值(0x00)
	fill uint8
	//2Byte 服务器权能标志(低16位)
	capabilitiesLow int
	//1Byte字符编码
	charset uint8
	//2Byte服务器状态
	status int
	//2Byte 服务器权能标志(高16位)
	capabilitiesHigh int
	//随机挑战数(12位)
	salt2 string
	//
	pluginName string
}

const (
	ipAddr = "127.0.0.1"
	port   = "3306"
)

func main() {

	conn, _ := net.Dial("tcp", fmt.Sprintf("%s:%s", ipAddr, port))
	defer conn.Close()
	//读取消息体
	body, _ := ReadPackge(conn)

	r := bytes.NewReader(body)
	//跳过4Byte消息头
	SkipHeaderPackage(r)
	//读取1Byte协议版本号
	protoVersion, _ := r.ReadByte()

	//n Byte服务版本信息
	serverVersion := ReadNullTerminatedString(r)

	//4 byte 服务线程ID
	theadIDBuf := make([]byte, 4)
	r.Read(theadIDBuf)
	theadId := int(uint32(theadIDBuf[0]) | uint32(theadIDBuf[1])<<8 | uint32(theadIDBuf[2])<<16 | uint32(theadIDBuf[3])<<24)

	//8 byte 随机挑战数
	saltBuf := make([]byte, 8)
	salt, _ := r.Read(saltBuf)

	//跳过 1 byte填充值
	r.Seek(1, io.SeekCurrent)

	//读取 2 byte 服务器权能标识(低16位)
	capabilitiesLow1Buf := make([]byte, 2)
	r.Read(capabilitiesLow1Buf)
	capabilitiesLow := int(uint32(capabilitiesLow1Buf[0]) | uint32(capabilitiesLow1Buf[1])<<8)
	//读取1 byte 字符编码
	chartset, _ := r.ReadByte()

	//读取2 byte 服务器状态
	serverStatusBuf := make([]byte, 2)
	r.Read(serverStatusBuf)
	serverStatus := int(uint32(serverStatusBuf[0]) | uint32(serverStatusBuf[1]))

	//读取服务器权能标志(高16位)
	capabilitiesHigh2Buf := make([]byte, 2)
	r.Read(capabilitiesHigh2Buf)
	capabilitiesHigh := int(uint32(capabilitiesHigh2Buf[0]) | uint32(capabilitiesHigh2Buf[1])<<8)
	//跳过 1byte 未使用的挑战长度
	r.Seek(1, io.SeekCurrent)
	//跳过10 byte 填充值
	r.Seek(10, io.SeekCurrent)

	//读取12位挑战随机数
	salt2 := ReadNullTerminatedString(r)

	//读取密码认证插件
	pluginName := ReadNullTerminatedString(r)

	//handshake
	handshake := Handshake{
		protocol:         protoVersion,
		version:          serverVersion,
		theadID:          theadId,
		salt1:            string(salt),
		capabilitiesLow:  capabilitiesLow,
		charset:          chartset,
		status:           serverStatus,
		capabilitiesHigh: capabilitiesHigh,
		salt2:            salt2,
		pluginName:       pluginName,
	}
    //打印输出
	fmt.Println(handshake)

}

//读取已0x00结尾的字符串
func ReadNullTerminatedString(r *bytes.Reader) string {
	var str []byte
	for {
		b, _ := r.ReadByte()
		if b == 0x00 {
			return string(str)
		} else {
			str = append(str, b)
		}
	}

}

//跳过消息头
func SkipHeaderPackage(r *bytes.Reader) error {
	if _, err := r.Seek(4, io.SeekStart); err != nil {
		return err
	}
	return nil

}

//读取数据包
func ReadPackge(conn net.Conn) ([]byte, error) {

	//读取4byte消息头
	header := []byte{0, 0, 0, 0}

	if _, err := io.ReadFull(conn, header); err != nil {
		return nil, err
	}
	//获取3byte消息长度
	bodyLen := int(uint32(header[0]) | uint32(header[1]<<8) | uint32(header[2]<<16))

	body := make([]byte, bodyLen)
	//读取消息体
	n, err := io.ReadFull(conn, body)
	if err != nil {
		return nil, err
	}

	return append(header, body[0:n]...), nil

}


© 著作权归作者所有

共有 人打赏支持
曾经的十字镐

曾经的十字镐

粉丝 22
博文 25
码字总数 6795
作品 0
郑州
架构师
函数rtmp_open()

FFMPEG版本为3.2 release。 libavformat/rtmpproto.c 调用关系: 即 Open RTMP connection and verify that the stream can be played. 该函数主要包括四个功能: 1.解析url 2.打开连接 3. 三......

andrew810810
2016/12/07
15
0
WebSocket 服务端实现

WebSocket,并非HTML 5独有,WebSocket是一种协议。只是在handshake的时候,发送的链接信息头和HTTP相似。HTML 5只是实现了WebSocket的客户端。其实,难点在于服务端,服务端相对还是比较复杂...

bobo_lin
2012/08/10
0
7
转发:websocket 通信协议介绍

websocket通信协议实现的是基于浏览器的原生socket,在客户端用JS即可轻松完成,前些 天都在学习websocket 协议(但实际上websocket 协议甚为简约),并且粗略的思考过websocket的对于下一代...

红薯
2010/06/02
4.4K
7
Lync 2010 学习(七),TLS and MTLS for Lync Server 2010

TLS:Transport Layer Security ,传输层安全协议 MTLS:Mutual Transport Layer Securit,相互传输层安全协议 OSI七层模型中网络层通过数据包的路由来进行数据包的转发,而作为网络层的上一...

mozhenhua
2014/10/04
0
0
[翻译]WebSocket协议第四章——Opening Handshake

概述 本文为WebSocket协议的第四章,本文翻译的主要内容为WebSocket建立连接开始握手的内容,主要包含了客户端和服务端握手的内容,以及双方如何处理相关字段和逻辑。 4 开始握手(协议正文)...

黄Java
06/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

软件测试工具书籍与面试题汇总下载(持续更新)

简介 本文是https://github.com/china-testing/python-api-tesing/blob/master/books.md 的节选。 欢迎转载,转载请附带此简介,谢谢! 试题 软件测试综合面试题(高级测试)-试题.pdf 软件测试...

python测试开发人工智能安全
25分钟前
0
0
java.sql.SQLException: Io 异常: The Network Adapter could not establish the connection 解决

有个项目使用的log4j进行日志记录的,同时也是用log4j中的数据库配置直接把相应级别的日志直接插入oracle。 在把项目部署的另一个内网环境时候,把项目的其他配置都改了,唯独log4j中的数据库...

哥本哈根的小哥
35分钟前
1
0
耗时 2 年,用 8.5 万块乐高积木最牛复刻 Apple Park

简评:国外大佬复刻 Apple Park,看了一下细节,确实厉害!只有你想不到,没有乐高拼不起来的,有没有乐高大神挑战一下? 苹果公园以各种各样的方式鼓舞人心,让人感兴趣。从建筑、可持续性和...

极光推送
36分钟前
1
0
记一次查找Hdfs磁盘占用空间比实际存储文件大4倍的原因

在一次主备namenode发生切换后,重启datanode节点,发现磁盘空间很大,想清理一下磁盘, 通过命令Hdfs dfs -du -h --max-depth=1 / 发现实际文件的大小只有8g,通过du -h --max-depth=1 /ha...

PageYi
今天
5
0
阿里云推荐引擎使用教程

产品概述: 推荐引擎(Recommendation Engine,以下简称RecEng,特指阿里云推荐引擎)是在阿里云计算环境下建立的一套推荐服务框架,目标是让广大中小互联网企业能够在这套框架上快速的搭建满...

mcy0425
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部