文档章节

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

曾经的十字镐
 曾经的十字镐
发布于 2017/11/02 17:29
字数 705
阅读 123
收藏 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

}


© 著作权归作者所有

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

曾经的十字镐

粉丝 23
博文 25
码字总数 6795
作品 0
郑州
架构师
私信 提问
mysql 协议的服务端握手包及对其解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangyangzhizhou/article/details/54142203 概况 mysql客户端登陆到mysql服务端需要一个交互的过程,这里先看...

超人汪小建(seaboat)
2017/01/06
0
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
深入解析redis cluster gossip机制

社区版redis cluster是一个P2P无中心节点的集群架构,依靠gossip协议传播协同自动化修复集群的状态。本文将深入redis cluster gossip协议的细节,剖析redis cluster gossip协议机制如何运转。...

羽洵
2018/12/18
0
0
WebSocket 服务端实现

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

bobo_lin
2012/08/10
0
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

没有更多内容

加载失败,请刷新页面

加载更多

Spark in action on Kubernetes - Playground搭建与架构浅析

前言 Spark是非常流行的大数据处理引擎,数据科学家们使用Spark以及相关生态的大数据套件完成了大量又丰富场景的数据分析与挖掘。Spark目前已经逐渐成为了业界在数据处理领域的行业标准。但是...

阿里云官方博客
10分钟前
1
0
小白大数据学习路线

学习大数据首先了解大数据技术得板块划分: 数据计算(离线计算):Hadoop、spark 数据计算(实时计算):storm、spartstreaming、flink 其他框架:zookeeper 数据采集:flume、Kafka 数据存...

董黎明
23分钟前
0
0
mariadb 内存占用优化

本文由云+社区发表 作者:工程师小熊 摘要:我们在使用mariadb的时候发现有时候不能启动起来,在使用过程中mariadb占用的内存很大,在这里学习下mariadb与内存相关的配置项,对mariadb进行调...

腾讯云加社区
今天
3
0
spring security 自定义登录认证

spring security 自定义认证登录 1.概要 1.1.简介 spring security是一种基于 Spring AOP 和 Servlet 过滤器的安全框架,以此来管理权限认证等。 1.2.spring security 自定义认证流程 1)认证...

EasyProgramming
今天
1
0
Win下Jenkins-2.138源码编译及填坑笔记

源码编译篇 1、 安装JDK1.8-181,操作系统添加JDK环境变量。Java -version验证一下。 注:Jenkins2.138版本,JDK必须jkd1.8.0-101以上,不支持Java9,Maven必须3.5.3以上。 2、 解压Maven3....

编程SHA
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部