Skip to content

Commit

Permalink
Add project
Browse files Browse the repository at this point in the history
  • Loading branch information
linxiaobo committed Nov 22, 2017
1 parent e742473 commit 3feaf24
Show file tree
Hide file tree
Showing 12 changed files with 953 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,10 @@

# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
.vscode
bin
pkg
github.com
golang.org
sourcegraph.com
sqlparser
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# Michael
GOPATH=$(pwd) go get github.com/VividCortex/golibpcap/pcap
GOPATH=$(pwd) go get github.com/go-sql-driver/mysql
7 changes: 7 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
all: build
build:
GOPATH=$(shell pwd) gofmt -w src/main src/lib/*
GOPATH=$(shell pwd) go build -o pcapagent main

clean:
rm -f pcapagent
25 changes: 25 additions & 0 deletions src/lib/logger/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package logger

import (
"io"
"log"
)

var (
// Trace blabla
Trace *log.Logger
// Info blabla
Info *log.Logger
// Warning blabla
Warning *log.Logger
// Error blabla
Error *log.Logger
)

// InitLogger blabla
func InitLogger(traceHandle io.Writer, infoHandle io.Writer, warningHandle io.Writer, errorHandle io.Writer) {
Trace = log.New(traceHandle, "TRACE: ", log.Ldate|log.Ltime|log.Lshortfile)
Info = log.New(infoHandle, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
Warning = log.New(warningHandle, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
Error = log.New(errorHandle, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
}
117 changes: 117 additions & 0 deletions src/lib/mysqlprotocol/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package mysqlprotocol

import (
"errors"
)

var (
errNotFount = errors.New("not found")
errPacketTooShort = errors.New("packet too short")
errPacketNotParse = errors.New("packet not parse")
errPacketNotError = errors.New("packet not error") // 当前包还有剩余数据
errPacketParsed = errors.New("packet parsed") // 当前包没有剩余数据
)

var serverStatusFlag = map[uint16]string{
1: "SERVER_STATUS_IN_TRANS", //A transaction is currently active
2: "SERVER_STATUS_AUTOCOMMIT", // Autocommit mode is set
8: "SERVER_MORE_RESULTS_EXISTS", //more results exists (more packet follow)
16: "SERVER_QUERY_NO_GOOD_INDEX_USED",
32: "SERVER_QUERY_NO_INDEX_USED",
64: "SERVER_STATUS_CURSOR_EXISTS", // when using COM_STMT_FETCH, indicate that current cursor still has result (deprecated)
128: "SERVER_STATUS_LAST_ROW_SENT", // when using COM_STMT_FETCH, indicate that current cursor has finished to send results (deprecated)
1 << 8: "SERVER_STATUS_DB_DROPPED", // database has been dropped
1 << 9: "SERVER_STATUS_NO_BACKSLASH_ESCAPES", // current escape mode is "no backslash escape"
1 << 10: "SERVER_STATUS_METADATA_CHANGED", // A DDL change did have an impact on an existing PREPARE (an automatic reprepare has been executed)
1 << 11: "SERVER_QUERY_WAS_SLOW", //
1 << 12: "SERVER_PS_OUT_PARAMs", // this resultset contain stored procedure output parameter
1 << 13: "SERVER_STATUS_IN_TRANS_READONLY", // current transaction is a read-only transaction
1 << 14: "SERVER_SESSION_STATE_CHANGED", // session state change. see Session change type for more information
}

var cmdMap = map[uint16]string{
0x00: "COM_SLEEP", // (内部线程状态) (无)
0x01: "COM_QUIT", // 关闭连接 mysql_close
0x02: "COM_INIT_DB", // 切换数据库 mysql_select_db
0x03: "COM_QUERY", // SQL查询请求 mysql_real_query
0x04: "COM_FIELD_LIST", // 获取数据表字段信息 mysql_list_fields
0x05: "COM_CREATE_DB", // 创建数据库 mysql_create_db
0x06: "COM_DROP_DB", // 删除数据库 mysql_drop_db
0x07: "COM_REFRESH", // 清除缓存 mysql_refresh
0x08: "COM_SHUTDOWN", // 停止服务器 mysql_shutdown
0x09: "COM_STATISTICS", // 获取服务器统计信息 mysql_stat
0x0A: "COM_PROCESS_INFO", // 获取当前连接的列表 mysql_list_processes
0x0B: "COM_CONNECT", // (内部线程状态) (无)
0x0C: "COM_PROCESS_KILL", // 中断某个连接 mysql_kill
0x0D: "COM_DEBUG", // 保存服务器调试信息 mysql_dump_debug_info
0x0E: "COM_PING", // 测试连通性 mysql_ping
0x0F: "COM_TIME", // (内部线程状态) (无)
0x10: "COM_DELAYED_INSERT", // (内部线程状态) (无)
0x11: "COM_CHANGE_USER", // 重新登陆(不断连接) mysql_change_user
0x12: "COM_BINLOG_DUMP", // 获取二进制日志信息 (无)
0x13: "COM_TABLE_DUMP", // 获取数据表结构信息 (无)
0x14: "COM_CONNECT_OUT", // (内部线程状态) (无)
0x15: "COM_REGISTER_SLAVE", // 从服务器向主服务器进行注册 (无)
0x16: "COM_STMT_PREPARE", // 预处理SQL语句 mysql_stmt_prepare
0x17: "COM_STMT_EXECUTE", // 执行预处理语句 mysql_stmt_execute
0x18: "COM_STMT_SEND_LONG_DATA", // 发送BLOB类型的数据 mysql_stmt_send_long_data
0x19: "COM_STMT_CLOSE", // 销毁预处理语句 mysql_stmt_close
0x1A: "COM_STMT_RESET", // 清除预处理语句参数缓存 mysql_stmt_reset
0x1B: "COM_SET_OPTION", // 设置语句选项 mysql_set_server_option
0x1C: "COM_STMT_FETCH", // 获取预处理语句的执行结果 mysql_stmt_fetch
}

var comStmtExecuteFlag = map[uint16]string{
0: "no cursor",
1: "read only",
2: "cursor for update",
4: "scrollable cursor",
}

var resultSetFieldTypes = map[uint16]string{
0: "MYSQL_TYPE_DECIMAL",
1: "MYSQL_TYPE_TINY",
2: "MYSQL_TYPE_SHORT",
3: "MYSQL_TYPE_LONG",
4: "MYSQL_TYPE_FLOAT",
5: "MYSQL_TYPE_DOUBLE",
6: "MYSQL_TYPE_NULL",
7: "MYSQL_TYPE_TIMESTAMP",
8: "MYSQL_TYPE_LONGLONG",
9: "MYSQL_TYPE_INT24",
10: "MYSQL_TYPE_DATE",
11: "MYSQL_TYPE_TIME",
12: "MYSQL_TYPE_DATETIME",
13: "MYSQL_TYPE_YEAR",
14: "MYSQL_TYPE_NEWDATE",
15: "MYSQL_TYPE_VARCHAR",
16: "MYSQL_TYPE_BIT",
17: "MYSQL_TYPE_TIMESTAMP2",
18: "MYSQL_TYPE_DATETIME2",
19: "MYSQL_TYPE_TIME2",
246: "MYSQL_TYPE_NEWDECIMAL",
247: "MYSQL_TYPE_ENUM",
248: "MYSQL_TYPE_SET",
249: "MYSQL_TYPE_TINY_BLOB",
250: "MYSQL_TYPE_MEDIUM_BLOB",
251: "MYSQL_TYPE_LONG_BLOB",
252: "MYSQL_TYPE_BLOB",
253: "MYSQL_TYPE_VAR_STRING",
254: "MYSQL_TYPE_STRING",
255: "MYSQL_TYPE_GEOMETRY",
}

var resultSetFieldDetailFlag = map[uint16]string{
1: "NOT_NULL", //field cannot be null
2: "PRIMARY_KEY", //field is a primary key
4: "UNIQUE_KEY", //field is unique
8: "MULTIPLE_KEY", //field is in a multiple key
16: "BLOB", //is this field a Blob
32: "UNSIGNED", //is this field unsigned
64: "DECIMAL", //is this field a decimal
128: "BINARY_COLLATION", //whether this field has a binary collation
256: "ENUM", //Field is an enumeration
512: "AUTO_INCREMENT", //field auto-increment
1024: "TIMESTAMP", //field is a timestamp value
2048: "SET", //field is a SET
}
127 changes: 127 additions & 0 deletions src/lib/mysqlprotocol/mysqlparser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package mysqlprotocol

import (
"lib/logger"
)

// PcapInfo blabla
type PcapInfo struct {
Data []byte
Port uint16
IPDst string
IPSrc string
TCPDst uint16
TCPSrc uint16
}

// MySQLNet blabla
type MySQLNet struct {
Port uint16
IPDst string
IPSrc string
TCPDst uint16
TCPSrc uint16
}

// MySQLBase blabla
type MySQLBase struct {
Net *MySQLNet
Base *MySQLParser
Data []byte
Cursor uint64
}

// MySQLRequest blabla
type MySQLRequest struct {
*MySQLBase
Cmd uint16
}

// MySQLResponse blabla
type MySQLResponse struct {
*MySQLBase
}

// MySQLParser blabla
type MySQLParser struct {
Req *MySQLRequest
Res *MySQLResponse
}

// CreateMySQLParser blabla
func CreateMySQLParser() *MySQLParser {
return &MySQLParser{}
}

// Parse blabla
func (m *MySQLParser) Parse(channel chan *PcapInfo) {
for {
data := <-channel
if data == nil {
break
}
if data.Port == data.TCPDst {
if m.Req == nil {
m.Req = &MySQLRequest{MySQLBase: &MySQLBase{
Net: &MySQLNet{Port: data.Port, IPDst: data.IPDst, IPSrc: data.IPSrc, TCPDst: data.TCPDst, TCPSrc: data.TCPSrc},
Data: data.Data,
Base: m,
Cursor: 0,
}}
} else {
m.Req.Data = append(m.Req.Data, data.Data...)
}
m.tryParse(m.Req)
} else if data.Port == data.TCPSrc {
if m.Req == nil {
break
}
if m.Res == nil {
m.Res = &MySQLResponse{MySQLBase: &MySQLBase{
Net: &MySQLNet{Port: data.Port, IPDst: data.IPDst, IPSrc: data.IPSrc, TCPDst: data.TCPDst, TCPSrc: data.TCPSrc},
Data: data.Data,
Base: m,
Cursor: 0,
}}
} else {
m.Res.Data = append(m.Res.Data, data.Data...)
}
m.tryParse(m.Res)
} else {
break
}
}
}

// IParse blabla
type IParse interface {
parseNormal() error
cutOne()
// parseCompress
}

func (m *MySQLParser) tryParse(i IParse) {
for {
err := m.catchParse(i)
if err == errPacketParsed {
break
} else if err == errPacketTooShort {
break
} else if err == errPacketNotError {
continue
} else if err == errPacketNotParse {
i.cutOne()
} else {
i.cutOne()
}
}
}

func (m *MySQLParser) catchParse(i IParse) error {
defer func() {
if err := recover(); err != nil {
logger.Warning.Println("catchParse err:", err)
}
}()
return i.parseNormal()
}
Loading

0 comments on commit 3feaf24

Please sign in to comment.