-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
linxiaobo
committed
Nov 22, 2017
1 parent
e742473
commit 3feaf24
Showing
12 changed files
with
953 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} |
Oops, something went wrong.