文档章节

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

曾经的十字镐
 曾经的十字镐
发布于 2017/11/02 17:29
字数 705
阅读 91
收藏 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
[翻译]WebSocket协议第四章——Opening Handshake

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

黄Java
06/21
0
0
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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

nginx模块学习六 add_header 跨域访问

语法 Syntax: add_header name value [always];Default: --Context:http,server,location,if in location 例:/etc/nginx/conf.d/default.conf server {    listen       80; ......

Romanceling
今天
0
0
SpringBoot初探

#SpringBoot初探 三种创建SpringBoot项目的方式: 第一种:使用IDEA创建maven项目,选择maven-archetype-quickstart; 第二种:使用IDEA创建Spring Initializer,选择web组件; 第三种:使用...

向码而生
今天
2
0
IO

JAVA中IO技术:BIO、NIO、AIO 1、同步异步、阻塞非阻塞概念 同步和异步是针对应用程序和内核的交互而言的。 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方...

DemonsI
今天
0
0
org.apache.commons 常用工具类

一. org.apache.commons.io.IOUtils closeQuietly 关闭一个IO流、socket、或者selector且不抛出异常。通常放在finally块。 toString 转换IO流、 Uri、 byte[]为String。 copy IO流数据复制,...

sprouting
今天
0
0
linux使用Inotify监控目录或者文件状态变更

基本概念: Inotify 是一个 Linux特性,它监控文件系统操作,比如读取、写入和创建。Inotify 反应灵敏,用法非常简单,并且比 cron 任务的繁忙轮询高效得多。 需求: 1.有一个文件采集进程,...

mickelfeng
今天
0
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部