mirror of https://github.com/40t/go-sniffer.git
commit
76d7a00755
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018 Jing
|
Copyright (c) 2018 40t<jtjinggm@gmail.com>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
87
README.md
87
README.md
|
@ -1,10 +1,7 @@
|
||||||
|
|
||||||
# go-sniffer
|
# go-sniffer
|
||||||
|
|
||||||
> 捕获mysql,redis,http,mongodb等协议...完善中
|
> Capture mysql,redis,http,mongodb etc protocol...
|
||||||
> - 抓取项目中的数据库请求,如:执行的mysql查询语句
|
|
||||||
> - 不需要修改项目代码,通过指定端口抓包解析协议
|
|
||||||
> - 快速预览项目中所有的数据请求,便于程序调试
|
|
||||||
|
|
||||||
[](https://github.com/40t/go-sniffer/blob/master/LICENSE)
|
[](https://github.com/40t/go-sniffer/blob/master/LICENSE)
|
||||||
|
|
||||||
|
@ -24,18 +21,21 @@ $ go-sniffer en0 mysql
|
||||||
```
|
```
|
||||||

|

|
||||||
## Setup:
|
## Setup:
|
||||||
- 支持 : `MacOS` `Linux` `Unix`
|
- support : `MacOS` `Linux` `Unix`
|
||||||
- 不支持 : `windows`
|
- not support : `windows`
|
||||||
- 依赖:`google/gopacket`库
|
|
||||||
|
|
||||||
### 依赖库安装:Centos
|
### Centos
|
||||||
``` bash
|
``` bash
|
||||||
$ yum install libcap-devel
|
$ yum install libcap-devel
|
||||||
```
|
```
|
||||||
### 依赖库安装: Ubuntu
|
### Ubuntu
|
||||||
``` bash
|
``` bash
|
||||||
$ apt-get install libcap-dev
|
$ apt-get install libcap-dev
|
||||||
```
|
```
|
||||||
|
### MacOs
|
||||||
|
``` bash
|
||||||
|
All is ok
|
||||||
|
```
|
||||||
### RUN
|
### RUN
|
||||||
``` bash
|
``` bash
|
||||||
$ go get -v github.com/40t/go-sniffer
|
$ go get -v github.com/40t/go-sniffer
|
||||||
|
@ -44,59 +44,36 @@ $ go run main.go
|
||||||
```
|
```
|
||||||
## Usage:
|
## Usage:
|
||||||
``` bash
|
``` bash
|
||||||
=======================================================================
|
==================================================================================
|
||||||
[使用说明]
|
[Usage]
|
||||||
|
|
||||||
go-sniffer [设备名] [插件名] [插件参数(可选)]
|
go-sniffer [device] [plug] [plug's params(optional)]
|
||||||
|
|
||||||
[例子]
|
[Example]
|
||||||
go-sniffer en0 redis 抓取redis数据包
|
go-sniffer en0 redis Capture redis packet
|
||||||
go-sniffer en0 mysql -p 3306 抓取mysql数据包,端口3306
|
go-sniffer en0 mysql -p 3306 Capture mysql packet
|
||||||
|
|
||||||
go-sniffer --[命令]
|
go-sniffer --[commend]
|
||||||
--help 帮助信息
|
--help "this page"
|
||||||
--env 环境变量
|
--env "environment variable"
|
||||||
--list 插件列表
|
--list "Plug-in list"
|
||||||
--ver 版本信息
|
--ver "version"
|
||||||
--dev 设备列表
|
--dev "device"
|
||||||
[例子]
|
[Example]
|
||||||
go-sniffer --list 查看可抓取的协议
|
go-sniffer --list "show all plug-in"
|
||||||
|
|
||||||
=======================================================================
|
==================================================================================
|
||||||
[设备名] : lo0 : 127.0.0.1
|
[device] : lo0 : 127.0.0.1
|
||||||
[设备名] : en0 : x:x:x:x:x5:x 192.168.1.3
|
[device] : en0 : xx:xx:xx:xx:xx:xx 192.168.199.221
|
||||||
[设备名] : utun2 : 1.1.11.1
|
==================================================================================
|
||||||
=======================================================================
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### mysql
|
### Example:
|
||||||
> 支持预处理语句等常大部分语句
|
|
||||||
``` bash
|
``` bash
|
||||||
$ go-sniffer [设备名] mysql [参数]
|
$ go-sniffer lo0 mysql
|
||||||
-p 置顶端口,默认3306
|
$ go-sniffer en0 redis
|
||||||
|
$ go-sniffer eth0 http -p 8080
|
||||||
|
$ go-sniffer eth1 mongodb
|
||||||
```
|
```
|
||||||

|
|
||||||
|
|
||||||
### redis
|
|
||||||
``` bash
|
|
||||||
$ go-sniffer [设备名] redis [参数]
|
|
||||||
-p 置顶端口,默认6379
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### http
|
|
||||||
``` bash
|
|
||||||
$ go-sniffer [设备名] http [参数]
|
|
||||||
-p 置顶端口,默认80
|
|
||||||
```
|
|
||||||

|
|
||||||
|
|
||||||
### mongodb
|
|
||||||
``` bash
|
|
||||||
$ go-sniffer [设备名] mongodb [参数]
|
|
||||||
-p 端口,默认27017
|
|
||||||
```
|
|
||||||
- 支持大部分语句,只有个别少数语句没有实现
|
|
||||||
|
|
||||||
## License:
|
## License:
|
||||||
[MIT](http://opensource.org/licenses/MIT)
|
[MIT](http://opensource.org/licenses/MIT)
|
||||||
|
|
67
core/cmd.go
67
core/cmd.go
|
@ -10,11 +10,11 @@ import (
|
||||||
|
|
||||||
const InternalCmdPrefix = "--"
|
const InternalCmdPrefix = "--"
|
||||||
const (
|
const (
|
||||||
InternalCmdHelp = "help" //帮助文档
|
InternalCmdHelp = "help"
|
||||||
InternalCmdEnv = "env" //环境变量
|
InternalCmdEnv = "env"
|
||||||
InternalCmdList = "list" //插件列表
|
InternalCmdList = "list"
|
||||||
InternalCmdVer = "ver" //版本信息
|
InternalCmdVer = "ver"
|
||||||
InternalDevice = "dev" //设备链表
|
InternalDevice = "dev"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cmd struct {
|
type Cmd struct {
|
||||||
|
@ -32,13 +32,13 @@ func NewCmd(p *Plug) *Cmd {
|
||||||
//start
|
//start
|
||||||
func (cm *Cmd) Run() {
|
func (cm *Cmd) Run() {
|
||||||
|
|
||||||
//使用帮助
|
//print help
|
||||||
if len(os.Args) <= 1 {
|
if len(os.Args) <= 1 {
|
||||||
cm.printHelpMessage();
|
cm.printHelpMessage()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
//解析命令
|
//parse command
|
||||||
firstArg := string(os.Args[1])
|
firstArg := string(os.Args[1])
|
||||||
if strings.HasPrefix(firstArg, InternalCmdPrefix) {
|
if strings.HasPrefix(firstArg, InternalCmdPrefix) {
|
||||||
cm.parseInternalCmd()
|
cm.parseInternalCmd()
|
||||||
|
@ -47,7 +47,8 @@ func (cm *Cmd) Run() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//解析内部参数
|
//parse internal commend
|
||||||
|
//like --help, --env, --device
|
||||||
func (cm *Cmd) parseInternalCmd() {
|
func (cm *Cmd) parseInternalCmd() {
|
||||||
|
|
||||||
arg := string(os.Args[1])
|
arg := string(os.Args[1])
|
||||||
|
@ -56,9 +57,9 @@ func (cm *Cmd) parseInternalCmd() {
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case InternalCmdHelp:
|
case InternalCmdHelp:
|
||||||
cm.printHelpMessage()
|
cm.printHelpMessage()
|
||||||
break;
|
break
|
||||||
case InternalCmdEnv:
|
case InternalCmdEnv:
|
||||||
fmt.Println("插件路径:"+cm.plugHandle.dir)
|
fmt.Println("External plug-in path : "+cm.plugHandle.dir)
|
||||||
break
|
break
|
||||||
case InternalCmdList:
|
case InternalCmdList:
|
||||||
cm.plugHandle.PrintList()
|
cm.plugHandle.PrintList()
|
||||||
|
@ -68,45 +69,45 @@ func (cm *Cmd) parseInternalCmd() {
|
||||||
break
|
break
|
||||||
case InternalDevice:
|
case InternalDevice:
|
||||||
cm.printDevice()
|
cm.printDevice()
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
//使用说明
|
//usage
|
||||||
func (cm *Cmd) printHelpMessage() {
|
func (cm *Cmd) printHelpMessage() {
|
||||||
|
|
||||||
fmt.Println("==================================================================================")
|
fmt.Println("==================================================================================")
|
||||||
fmt.Println("[使用说明]")
|
fmt.Println("[Usage]")
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println(" go-sniffer [设备名] [插件名] [插件参数(可选)]")
|
fmt.Println(" go-sniffer [device] [plug] [plug's params(optional)]")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" [例子]")
|
fmt.Println(" [exp]")
|
||||||
fmt.Println(" go-sniffer en0 redis 抓取redis数据包")
|
fmt.Println(" go-sniffer en0 redis Capture redis packet")
|
||||||
fmt.Println(" go-sniffer en0 mysql -p 3306 抓取mysql数据包,端口3306")
|
fmt.Println(" go-sniffer en0 mysql -p 3306 Capture mysql packet")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println(" go-sniffer --[命令]")
|
fmt.Println(" go-sniffer --[commend]")
|
||||||
fmt.Println(" --help 帮助信息")
|
fmt.Println(" --help \"this page\"")
|
||||||
fmt.Println(" --env 环境变量")
|
fmt.Println(" --env \"environment variable\"")
|
||||||
fmt.Println(" --list 插件列表")
|
fmt.Println(" --list \"Plug-in list\"")
|
||||||
fmt.Println(" --ver 版本信息")
|
fmt.Println(" --ver \"version\"")
|
||||||
fmt.Println(" --dev 设备列表")
|
fmt.Println(" --dev \"device\"")
|
||||||
fmt.Println(" [例子]")
|
fmt.Println(" [exp]")
|
||||||
fmt.Println(" go-sniffer --list 查看可抓取的协议")
|
fmt.Println(" go-sniffer --list \"show all plug-in\"")
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("==================================================================================")
|
fmt.Println("==================================================================================")
|
||||||
cm.printDevice()
|
cm.printDevice()
|
||||||
fmt.Println("==================================================================================")
|
fmt.Println("==================================================================================")
|
||||||
}
|
}
|
||||||
|
|
||||||
//打印插件
|
//print plug-in list
|
||||||
func (cm *Cmd) printPlugList() {
|
func (cm *Cmd) printPlugList() {
|
||||||
l := len(cm.plugHandle.InternalPlugList)
|
l := len(cm.plugHandle.InternalPlugList)
|
||||||
l += len(cm.plugHandle.ExternalPlugList)
|
l += len(cm.plugHandle.ExternalPlugList)
|
||||||
fmt.Println("# 插件数量:"+strconv.Itoa(l))
|
fmt.Println("# Number of plug-ins : "+strconv.Itoa(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
//打印设备
|
//print device
|
||||||
func (cm *Cmd) printDevice() {
|
func (cm *Cmd) printDevice() {
|
||||||
ifaces, err:= net.Interfaces()
|
ifaces, err:= net.Interfaces()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -117,19 +118,19 @@ func (cm *Cmd) printDevice() {
|
||||||
for _,a:=range addrs {
|
for _,a:=range addrs {
|
||||||
if ipnet, ok := a.(*net.IPNet); ok {
|
if ipnet, ok := a.(*net.IPNet); ok {
|
||||||
if ip4 := ipnet.IP.To4(); ip4 != nil {
|
if ip4 := ipnet.IP.To4(); ip4 != nil {
|
||||||
fmt.Println("[设备名] : "+iface.Name+" : "+iface.HardwareAddr.String()+" "+ip4.String())
|
fmt.Println("[device] : "+iface.Name+" : "+iface.HardwareAddr.String()+" "+ip4.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//解析插件需要的参数
|
//Parameters needed for plug-ins
|
||||||
func (cm *Cmd) parsePlugCmd() {
|
func (cm *Cmd) parsePlugCmd() {
|
||||||
|
|
||||||
if len(os.Args) < 3 {
|
if len(os.Args) < 3 {
|
||||||
fmt.Println("缺少[插件名]")
|
fmt.Println("not found [Plug-in name]")
|
||||||
fmt.Println("go-sniffer [设备名] [插件名] [插件参数(可选)]")
|
fmt.Println("go-sniffer [device] [plug] [plug's params(optional)]")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
type Core struct{
|
type Core struct{
|
||||||
//版本信息
|
|
||||||
Version string
|
Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,13 +15,13 @@ func New() Core {
|
||||||
|
|
||||||
func (c *Core) Run() {
|
func (c *Core) Run() {
|
||||||
|
|
||||||
//插件
|
//new plugin
|
||||||
plug := NewPlug()
|
plug := NewPlug()
|
||||||
|
|
||||||
//解析参数
|
//parse commend
|
||||||
cmd := NewCmd(plug)
|
cmd := NewCmd(plug)
|
||||||
cmd.Run()
|
cmd.Run()
|
||||||
|
|
||||||
//开启抓包
|
//dispatch
|
||||||
NewDispatch(plug, cmd).Capture()
|
NewDispatch(plug, cmd).Capture()
|
||||||
}
|
}
|
|
@ -26,24 +26,24 @@ func NewDispatch(plug *Plug, cmd *Cmd) *Dispatch {
|
||||||
|
|
||||||
func (d *Dispatch) Capture() {
|
func (d *Dispatch) Capture() {
|
||||||
|
|
||||||
// Init device
|
//init device
|
||||||
handle, err := pcap.OpenLive(d.device, 65535, false, pcap.BlockForever)
|
handle, err := pcap.OpenLive(d.device, 65535, false, pcap.BlockForever)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set filter
|
//set filter
|
||||||
fmt.Println(d.Plug.BPF)
|
fmt.Println(d.Plug.BPF)
|
||||||
err = handle.SetBPFFilter(d.Plug.BPF)
|
err = handle.SetBPFFilter(d.Plug.BPF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Capture
|
//capture
|
||||||
src := gopacket.NewPacketSource(handle, handle.LinkType())
|
src := gopacket.NewPacketSource(handle, handle.LinkType())
|
||||||
packets := src.Packets()
|
packets := src.Packets()
|
||||||
|
|
||||||
// Set up assembly
|
//set up assembly
|
||||||
streamFactory := &ProtocolStreamFactory{
|
streamFactory := &ProtocolStreamFactory{
|
||||||
dispatch:d,
|
dispatch:d,
|
||||||
}
|
}
|
||||||
|
@ -51,14 +51,14 @@ func (d *Dispatch) Capture() {
|
||||||
assembler := NewAssembler(streamPool)
|
assembler := NewAssembler(streamPool)
|
||||||
ticker := time.Tick(time.Minute)
|
ticker := time.Tick(time.Minute)
|
||||||
|
|
||||||
// Loop until ctrl+z
|
//loop until ctrl+z
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case packet := <-packets:
|
case packet := <-packets:
|
||||||
if packet.NetworkLayer() == nil ||
|
if packet.NetworkLayer() == nil ||
|
||||||
packet.TransportLayer() == nil ||
|
packet.TransportLayer() == nil ||
|
||||||
packet.TransportLayer().LayerType() != layers.LayerTypeTCP {
|
packet.TransportLayer().LayerType() != layers.LayerTypeTCP {
|
||||||
fmt.Println("包不能解析")
|
fmt.Println("ERR : Unknown Packet -_-")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
tcp := packet.TransportLayer().(*layers.TCP)
|
tcp := packet.TransportLayer().(*layers.TCP)
|
||||||
|
@ -91,7 +91,7 @@ func (m *ProtocolStreamFactory) New(net, transport gopacket.Flow) tcpassembly.St
|
||||||
}
|
}
|
||||||
|
|
||||||
//new stream
|
//new stream
|
||||||
fmt.Println("# 新连接:", net, transport)
|
fmt.Println("# Start new stream:", net, transport)
|
||||||
|
|
||||||
//decode packet
|
//decode packet
|
||||||
go m.dispatch.Plug.ResolveStream(net, transport, &(stm.r))
|
go m.dispatch.Plug.ResolveStream(net, transport, &(stm.r))
|
||||||
|
|
37
core/plug.go
37
core/plug.go
|
@ -16,36 +16,26 @@ import (
|
||||||
|
|
||||||
type Plug struct {
|
type Plug struct {
|
||||||
|
|
||||||
//当前插件路径
|
|
||||||
dir string
|
dir string
|
||||||
//解析包
|
|
||||||
ResolveStream func(net gopacket.Flow, transport gopacket.Flow, r io.Reader)
|
ResolveStream func(net gopacket.Flow, transport gopacket.Flow, r io.Reader)
|
||||||
//BPF
|
|
||||||
BPF string
|
BPF string
|
||||||
|
|
||||||
//内部插件列表
|
|
||||||
InternalPlugList map[string]PlugInterface
|
InternalPlugList map[string]PlugInterface
|
||||||
//外部插件列表
|
|
||||||
ExternalPlugList map[string]ExternalPlug
|
ExternalPlugList map[string]ExternalPlug
|
||||||
}
|
}
|
||||||
|
|
||||||
// 内部插件必须实现此接口
|
// All internal plug-ins must implement this interface
|
||||||
// ResolvePacket - 包入口
|
// ResolvePacket - entry
|
||||||
// BPFFilter - 设置BPF规则,例如mysql: (tcp and port 3306)
|
// BPFFilter - set BPF, like: mysql(tcp and port 3306)
|
||||||
// SetFlag - 设置参数
|
// SetFlag - plug-in params
|
||||||
// Version - 返回插件版本,例如0.1.0
|
// Version - plug-in version
|
||||||
type PlugInterface interface {
|
type PlugInterface interface {
|
||||||
//解析流
|
|
||||||
ResolveStream(net gopacket.Flow, transport gopacket.Flow, r io.Reader)
|
ResolveStream(net gopacket.Flow, transport gopacket.Flow, r io.Reader)
|
||||||
//BPF
|
|
||||||
BPFFilter() string
|
BPFFilter() string
|
||||||
//设置插件需要的参数
|
|
||||||
SetFlag([]string)
|
SetFlag([]string)
|
||||||
//获取版本
|
|
||||||
Version() string
|
Version() string
|
||||||
}
|
}
|
||||||
|
|
||||||
//外部插件
|
|
||||||
type ExternalPlug struct {
|
type ExternalPlug struct {
|
||||||
Name string
|
Name string
|
||||||
Version string
|
Version string
|
||||||
|
@ -54,24 +44,17 @@ type ExternalPlug struct {
|
||||||
SetFlag func([]string)
|
SetFlag func([]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
//实例化
|
|
||||||
func NewPlug() *Plug {
|
func NewPlug() *Plug {
|
||||||
|
|
||||||
var p Plug
|
var p Plug
|
||||||
|
|
||||||
//设置默认插件目录
|
|
||||||
p.dir, _ = filepath.Abs( "./plug/")
|
p.dir, _ = filepath.Abs( "./plug/")
|
||||||
|
|
||||||
//加载内部插件
|
|
||||||
p.LoadInternalPlugList()
|
p.LoadInternalPlugList()
|
||||||
|
|
||||||
//加载外部插件
|
|
||||||
p.LoadExternalPlugList()
|
p.LoadExternalPlugList()
|
||||||
|
|
||||||
return &p
|
return &p
|
||||||
}
|
}
|
||||||
|
|
||||||
//加载内部插件
|
|
||||||
func (p *Plug) LoadInternalPlugList() {
|
func (p *Plug) LoadInternalPlugList() {
|
||||||
|
|
||||||
list := make(map[string]PlugInterface)
|
list := make(map[string]PlugInterface)
|
||||||
|
@ -91,12 +74,11 @@ func (p *Plug) LoadInternalPlugList() {
|
||||||
p.InternalPlugList = list
|
p.InternalPlugList = list
|
||||||
}
|
}
|
||||||
|
|
||||||
//加载外部so后缀插件
|
|
||||||
func (p *Plug) LoadExternalPlugList() {
|
func (p *Plug) LoadExternalPlugList() {
|
||||||
|
|
||||||
dir, err := ioutil.ReadDir(p.dir)
|
dir, err := ioutil.ReadDir(p.dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(p.dir + "不存在,或者无权访问")
|
panic(p.dir + "not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.ExternalPlugList = make(map[string]ExternalPlug)
|
p.ExternalPlugList = make(map[string]ExternalPlug)
|
||||||
|
@ -141,17 +123,15 @@ func (p *Plug) LoadExternalPlugList() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//改变插件地址
|
|
||||||
func (p *Plug) ChangePath(dir string) {
|
func (p *Plug) ChangePath(dir string) {
|
||||||
p.dir = dir
|
p.dir = dir
|
||||||
}
|
}
|
||||||
|
|
||||||
//打印插件列表
|
|
||||||
func (p *Plug) PrintList() {
|
func (p *Plug) PrintList() {
|
||||||
|
|
||||||
//Print Internal Plug
|
//Print Internal Plug
|
||||||
for inPlugName, _ := range p.InternalPlugList {
|
for inPlugName, _ := range p.InternalPlugList {
|
||||||
fmt.Println("内部插件:"+inPlugName)
|
fmt.Println("internal plug : "+inPlugName)
|
||||||
}
|
}
|
||||||
|
|
||||||
//split
|
//split
|
||||||
|
@ -159,11 +139,10 @@ func (p *Plug) PrintList() {
|
||||||
|
|
||||||
//print External Plug
|
//print External Plug
|
||||||
for exPlugName, _ := range p.ExternalPlugList {
|
for exPlugName, _ := range p.ExternalPlugList {
|
||||||
fmt.Println("外部插件:"+exPlugName)
|
fmt.Println("external plug : "+exPlugName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//选择当前使用的插件 && 加载插件
|
|
||||||
func (p *Plug) SetOption(plugName string, plugParams []string) {
|
func (p *Plug) SetOption(plugName string, plugParams []string) {
|
||||||
|
|
||||||
//Load Internal Plug
|
//Load Internal Plug
|
||||||
|
|
BIN
images/demo.gif
BIN
images/demo.gif
Binary file not shown.
Before Width: | Height: | Size: 669 KiB After Width: | Height: | Size: 3.3 MiB |
BIN
images/http.gif
BIN
images/http.gif
Binary file not shown.
Before Width: | Height: | Size: 54 KiB |
BIN
images/mysql.gif
BIN
images/mysql.gif
Binary file not shown.
Before Width: | Height: | Size: 181 KiB |
BIN
images/redis.gif
BIN
images/redis.gif
Binary file not shown.
Before Width: | Height: | Size: 83 KiB |
|
@ -21,8 +21,8 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type H struct {
|
type H struct {
|
||||||
port int//端口
|
port int
|
||||||
version string//插件版本
|
version string
|
||||||
}
|
}
|
||||||
|
|
||||||
var hp *H
|
var hp *H
|
||||||
|
@ -81,7 +81,7 @@ func (m *H) SetFlag(flg []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c >> 1 == 0 {
|
if c >> 1 == 0 {
|
||||||
fmt.Println("http参数数量不正确!")
|
fmt.Println("ERR : Http Number of parameters")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
for i:=0;i<c;i=i+2 {
|
for i:=0;i<c;i=i+2 {
|
||||||
|
@ -93,14 +93,14 @@ func (m *H) SetFlag(flg []string) {
|
||||||
port, err := strconv.Atoi(val);
|
port, err := strconv.Atoi(val);
|
||||||
m.port = port
|
m.port = port
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("端口数不正确")
|
panic("ERR : port")
|
||||||
}
|
}
|
||||||
if port < 0 || port > 65535 {
|
if port < 0 || port > 65535 {
|
||||||
panic("参数不正确: 端口范围(0-65535)")
|
panic("ERR : port(0-65535)")
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
panic("参数不正确")
|
panic("ERR : mysql's params")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,12 +27,12 @@ type stream struct {
|
||||||
|
|
||||||
type packet struct {
|
type packet struct {
|
||||||
|
|
||||||
isClientFlow bool //客户端->服务器端流
|
isClientFlow bool //client->server
|
||||||
|
|
||||||
messageLength int //总消息大小
|
messageLength int
|
||||||
requestID int //此消息的标识符
|
requestID int
|
||||||
responseTo int //从原始请求的requestID
|
responseTo int
|
||||||
opCode int //请求类型
|
opCode int //request type
|
||||||
|
|
||||||
payload io.Reader
|
payload io.Reader
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func (m *Mongodb) SetFlag(flg []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c >> 1 != 1 {
|
if c >> 1 != 1 {
|
||||||
panic("Mongodb参数数量不正确!")
|
panic("ERR : Mongodb Number of parameters")
|
||||||
}
|
}
|
||||||
for i:=0;i<c;i=i+2 {
|
for i:=0;i<c;i=i+2 {
|
||||||
key := flg[i]
|
key := flg[i]
|
||||||
|
@ -66,15 +66,15 @@ func (m *Mongodb) SetFlag(flg []string) {
|
||||||
case CmdPort:
|
case CmdPort:
|
||||||
p, err := strconv.Atoi(val);
|
p, err := strconv.Atoi(val);
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("端口数不正确")
|
panic("ERR : port")
|
||||||
}
|
}
|
||||||
mongodbInstance.port = p
|
mongodbInstance.port = p
|
||||||
if p < 0 || p > 65535 {
|
if p < 0 || p > 65535 {
|
||||||
panic("参数不正确: 端口范围(0-65535)")
|
panic("ERR : port(0-65535)")
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
panic("参数不正确")
|
panic("ERR : mysql's params")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,10 +125,10 @@ func (m *Mongodb) newPacket(net, transport gopacket.Flow, r io.Reader) *packet {
|
||||||
|
|
||||||
//stream close
|
//stream close
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
fmt.Println(net, transport, " 关闭")
|
fmt.Println(net, transport, " close")
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
fmt.Println("流解析错误", net, transport, ":", err)
|
fmt.Println("ERR : Unknown stream", net, transport, ":", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ func (stm *stream) resolveClientPacket(pk *packet) {
|
||||||
_ = zero
|
_ = zero
|
||||||
_ = flags
|
_ = flags
|
||||||
|
|
||||||
msg = fmt.Sprintf(" [更新] [集合:%s] 语句: %v %v",
|
msg = fmt.Sprintf(" [Update] [coll:%s] %v %v",
|
||||||
fullCollectionName,
|
fullCollectionName,
|
||||||
selector,
|
selector,
|
||||||
update,
|
update,
|
||||||
|
@ -185,7 +185,7 @@ func (stm *stream) resolveClientPacket(pk *packet) {
|
||||||
command := ReadBson2Json(pk.payload)
|
command := ReadBson2Json(pk.payload)
|
||||||
_ = flags
|
_ = flags
|
||||||
|
|
||||||
msg = fmt.Sprintf(" [插入] [集合:%s] 语句: %v",
|
msg = fmt.Sprintf(" [Insert] [coll:%s] %v",
|
||||||
fullCollectionName,
|
fullCollectionName,
|
||||||
command,
|
command,
|
||||||
)
|
)
|
||||||
|
@ -202,7 +202,7 @@ func (stm *stream) resolveClientPacket(pk *packet) {
|
||||||
command := ReadBson2Json(pk.payload)
|
command := ReadBson2Json(pk.payload)
|
||||||
selector := ReadBson2Json(pk.payload)
|
selector := ReadBson2Json(pk.payload)
|
||||||
|
|
||||||
msg = fmt.Sprintf(" [查询] [集合:%s] 语句: %v %v",
|
msg = fmt.Sprintf(" [Query] [coll:%s] %v %v",
|
||||||
fullCollectionName,
|
fullCollectionName,
|
||||||
command,
|
command,
|
||||||
selector,
|
selector,
|
||||||
|
@ -215,7 +215,7 @@ func (stm *stream) resolveClientPacket(pk *packet) {
|
||||||
commandArgs := ReadBson2Json(pk.payload)
|
commandArgs := ReadBson2Json(pk.payload)
|
||||||
inputDocs := ReadBson2Json(pk.payload)
|
inputDocs := ReadBson2Json(pk.payload)
|
||||||
|
|
||||||
msg = fmt.Sprintf(" [命令] [数据库:%s] [命令名:%s] %v %v %v",
|
msg = fmt.Sprintf(" [Commend] [DB:%s] [Cmd:%s] %v %v %v",
|
||||||
database,
|
database,
|
||||||
commandName,
|
commandName,
|
||||||
metaData,
|
metaData,
|
||||||
|
@ -230,7 +230,7 @@ func (stm *stream) resolveClientPacket(pk *packet) {
|
||||||
cursorId := ReadInt64(pk.payload)
|
cursorId := ReadInt64(pk.payload)
|
||||||
_ = zero
|
_ = zero
|
||||||
|
|
||||||
msg = fmt.Sprintf(" [查询更多] [集合:%s] [回复数量:%v] [游标:%v]",
|
msg = fmt.Sprintf(" [Query more] [coll:%s] [num of reply:%v] [cursor:%v]",
|
||||||
fullCollectionName,
|
fullCollectionName,
|
||||||
numberToReturn,
|
numberToReturn,
|
||||||
cursorId,
|
cursorId,
|
||||||
|
@ -244,7 +244,7 @@ func (stm *stream) resolveClientPacket(pk *packet) {
|
||||||
_ = zero
|
_ = zero
|
||||||
_ = flags
|
_ = flags
|
||||||
|
|
||||||
msg = fmt.Sprintf(" [删除] [集合:%s] 语句: %v",
|
msg = fmt.Sprintf(" [Delete] [coll:%s] %v",
|
||||||
fullCollectionName,
|
fullCollectionName,
|
||||||
selector,
|
selector,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package build
|
package build
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ComQueryRequestPacket string = "【查询】"
|
ComQueryRequestPacket string = "【Query】"
|
||||||
OkPacket string = "【正确】"
|
OkPacket string = "【Ok】"
|
||||||
ErrorPacket string = "【错误】"
|
ErrorPacket string = "【Err】"
|
||||||
PreparePacket string = "【预处理】"
|
PreparePacket string = "【Pretreatment】"
|
||||||
SendClientHandshakePacket string = "【用户认证】"
|
SendClientHandshakePacket string = "【User Auth】"
|
||||||
SendServerHandshakePacket string = "【登录认证】"
|
SendServerHandshakePacket string = "【Login】"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -22,9 +22,9 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Mysql struct {
|
type Mysql struct {
|
||||||
port int//端口
|
port int
|
||||||
version string//插件版本
|
version string
|
||||||
source map[string]*stream//流
|
source map[string]*stream
|
||||||
}
|
}
|
||||||
|
|
||||||
type stream struct {
|
type stream struct {
|
||||||
|
@ -101,7 +101,7 @@ func (m *Mysql) SetFlag(flg []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c >> 1 == 0 {
|
if c >> 1 == 0 {
|
||||||
fmt.Println("Mysql参数数量不正确!")
|
fmt.Println("ERR : Mysql Number of parameters")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
for i:=0;i<c;i=i+2 {
|
for i:=0;i<c;i=i+2 {
|
||||||
|
@ -113,14 +113,14 @@ func (m *Mysql) SetFlag(flg []string) {
|
||||||
port, err := strconv.Atoi(val);
|
port, err := strconv.Atoi(val);
|
||||||
m.port = port
|
m.port = port
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("端口数不正确")
|
panic("ERR : port")
|
||||||
}
|
}
|
||||||
if port < 0 || port > 65535 {
|
if port < 0 || port > 65535 {
|
||||||
panic("参数不正确: 端口范围(0-65535)")
|
panic("ERR : port(0-65535)")
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
panic("参数不正确")
|
panic("ERR : mysql's params")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,10 +137,10 @@ func (m *Mysql) newPacket(net, transport gopacket.Flow, r io.Reader) *packet {
|
||||||
|
|
||||||
//close stream
|
//close stream
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
fmt.Println(net, transport, " 关闭")
|
fmt.Println(net, transport, " close")
|
||||||
return nil
|
return nil
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
fmt.Println("错误流:", net, transport, ":", err)
|
fmt.Println("ERR : Unknown stream", net, transport, ":", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//generate new packet
|
//generate new packet
|
||||||
|
@ -165,7 +165,7 @@ func (m *Mysql) resolvePacketTo(r io.Reader, w io.Writer) (uint8, error) {
|
||||||
if n == 0 && err == io.EOF {
|
if n == 0 && err == io.EOF {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
return 0, errors.New("错误流")
|
return 0, errors.New("ERR : Unknown stream")
|
||||||
}
|
}
|
||||||
|
|
||||||
length := int(uint32(header[0]) | uint32(header[1])<<8 | uint32(header[2])<<16)
|
length := int(uint32(header[0]) | uint32(header[1])<<8 | uint32(header[2])<<16)
|
||||||
|
@ -174,9 +174,9 @@ func (m *Mysql) resolvePacketTo(r io.Reader, w io.Writer) (uint8, error) {
|
||||||
seq = header[3]
|
seq = header[3]
|
||||||
|
|
||||||
if n, err := io.CopyN(w, r, int64(length)); err != nil {
|
if n, err := io.CopyN(w, r, int64(length)); err != nil {
|
||||||
return 0, errors.New("错误流")
|
return 0, errors.New("ERR : Unknown stream")
|
||||||
} else if n != int64(length) {
|
} else if n != int64(length) {
|
||||||
return 0, errors.New("错误流")
|
return 0, errors.New("ERR : Unknown stream")
|
||||||
} else {
|
} else {
|
||||||
return seq, nil
|
return seq, nil
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ func (stm *stream) resolveServerPacket(payload []byte, seq int) {
|
||||||
errorCode := int(binary.LittleEndian.Uint16(payload[1:3]))
|
errorCode := int(binary.LittleEndian.Uint16(payload[1:3]))
|
||||||
errorMsg,_ := ReadStringFromByte(payload[4:])
|
errorMsg,_ := ReadStringFromByte(payload[4:])
|
||||||
|
|
||||||
msg = GetNowStr(false)+"%s 错误代码:%s,错误信息:%s"
|
msg = GetNowStr(false)+"%s Err code:%s,Err msg:%s"
|
||||||
msg = fmt.Sprintf(msg, ErrorPacket, strconv.Itoa(errorCode), strings.TrimSpace(errorMsg))
|
msg = fmt.Sprintf(msg, ErrorPacket, strconv.Itoa(errorCode), strings.TrimSpace(errorMsg))
|
||||||
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
|
@ -230,7 +230,7 @@ func (stm *stream) resolveServerPacket(payload []byte, seq int) {
|
||||||
l,_ := LengthBinary(payload[pos:])
|
l,_ := LengthBinary(payload[pos:])
|
||||||
affectedRows := int(l)
|
affectedRows := int(l)
|
||||||
|
|
||||||
msg += GetNowStr(false)+"%s 影响行数:%s"
|
msg += GetNowStr(false)+"%s Effect Row:%s"
|
||||||
msg = fmt.Sprintf(msg, OkPacket, strconv.Itoa(affectedRows))
|
msg = fmt.Sprintf(msg, OkPacket, strconv.Itoa(affectedRows))
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -250,7 +250,7 @@ func (stm *stream) resolveClientPacket(payload []byte, seq int) {
|
||||||
msg = fmt.Sprintf("USE %s;\n", payload[1:])
|
msg = fmt.Sprintf("USE %s;\n", payload[1:])
|
||||||
case COM_DROP_DB:
|
case COM_DROP_DB:
|
||||||
|
|
||||||
msg = fmt.Sprintf("删除数据库 %s;\n", payload[1:])
|
msg = fmt.Sprintf("Drop DB %s;\n", payload[1:])
|
||||||
case COM_CREATE_DB, COM_QUERY:
|
case COM_CREATE_DB, COM_QUERY:
|
||||||
|
|
||||||
statement := string(payload[1:])
|
statement := string(payload[1:])
|
||||||
|
@ -259,17 +259,17 @@ func (stm *stream) resolveClientPacket(payload []byte, seq int) {
|
||||||
|
|
||||||
serverPacket := stm.findStmtPacket(stm.packets, seq+1)
|
serverPacket := stm.findStmtPacket(stm.packets, seq+1)
|
||||||
if serverPacket == nil {
|
if serverPacket == nil {
|
||||||
log.Println("找不到预处理响应包")
|
log.Println("ERR : Not found stm packet")
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取响应包中预处理id
|
//fetch stm id
|
||||||
stmtID := binary.LittleEndian.Uint32(serverPacket.payload[1:5])
|
stmtID := binary.LittleEndian.Uint32(serverPacket.payload[1:5])
|
||||||
stmt := &Stmt{
|
stmt := &Stmt{
|
||||||
ID: stmtID,
|
ID: stmtID,
|
||||||
Query: string(payload[1:]),
|
Query: string(payload[1:]),
|
||||||
}
|
}
|
||||||
|
|
||||||
//记录预处理语句
|
//record stm sql
|
||||||
stm.stmtMap[stmtID] = stmt
|
stm.stmtMap[stmtID] = stmt
|
||||||
stmt.FieldCount = binary.LittleEndian.Uint16(serverPacket.payload[5:7])
|
stmt.FieldCount = binary.LittleEndian.Uint16(serverPacket.payload[5:7])
|
||||||
stmt.ParamCount = binary.LittleEndian.Uint16(serverPacket.payload[7:9])
|
stmt.ParamCount = binary.LittleEndian.Uint16(serverPacket.payload[7:9])
|
||||||
|
@ -305,19 +305,19 @@ func (stm *stream) resolveClientPacket(payload []byte, seq int) {
|
||||||
var stmt *Stmt
|
var stmt *Stmt
|
||||||
var ok bool
|
var ok bool
|
||||||
if stmt, ok = stm.stmtMap[stmtID]; ok == false {
|
if stmt, ok = stm.stmtMap[stmtID]; ok == false {
|
||||||
log.Println("未发现预处理id: ", stmtID)
|
log.Println("ERR : Not found stm id", stmtID)
|
||||||
}
|
}
|
||||||
|
|
||||||
//参数
|
//params
|
||||||
pos += 5
|
pos += 5
|
||||||
if stmt.ParamCount > 0 {
|
if stmt.ParamCount > 0 {
|
||||||
|
|
||||||
//空位图(Null-Bitmap,长度 = (参数数量 + 7) / 8 字节)
|
//(Null-Bitmap,len = (paramsCount + 7) / 8 byte)
|
||||||
step := int((stmt.ParamCount + 7) / 8)
|
step := int((stmt.ParamCount + 7) / 8)
|
||||||
nullBitmap := payload[pos : pos+step]
|
nullBitmap := payload[pos : pos+step]
|
||||||
pos += step
|
pos += step
|
||||||
|
|
||||||
//参数分隔标志
|
//Parameter separator
|
||||||
flag := payload[pos]
|
flag := payload[pos]
|
||||||
|
|
||||||
pos++
|
pos++
|
||||||
|
@ -325,19 +325,18 @@ func (stm *stream) resolveClientPacket(payload []byte, seq int) {
|
||||||
var pTypes []byte
|
var pTypes []byte
|
||||||
var pValues []byte
|
var pValues []byte
|
||||||
|
|
||||||
//如果参数分隔标志值为1
|
//if flag == 1
|
||||||
//n 每个参数的类型值(长度 = 参数数量 * 2 字节)
|
//n (len = paramsCount * 2 byte)
|
||||||
//n 每个参数的值
|
|
||||||
if flag == 1 {
|
if flag == 1 {
|
||||||
pTypes = payload[pos : pos+int(stmt.ParamCount)*2]
|
pTypes = payload[pos : pos+int(stmt.ParamCount)*2]
|
||||||
pos += int(stmt.ParamCount) * 2
|
pos += int(stmt.ParamCount) * 2
|
||||||
pValues = payload[pos:]
|
pValues = payload[pos:]
|
||||||
}
|
}
|
||||||
|
|
||||||
//绑定参数
|
//bind params
|
||||||
err := stmt.BindArgs(nullBitmap, pTypes, pValues)
|
err := stmt.BindArgs(nullBitmap, pTypes, pValues)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("预处理绑定参数失败: ", err)
|
log.Println("ERR : Could not bind params", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msg = string(stmt.WriteToText())
|
msg = string(stmt.WriteToText())
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,7 +22,7 @@ func (stmt *Stmt) WriteToText() []byte {
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
str := fmt.Sprintf("预处理编号[%d]: '%s';\n", stmt.ID, stmt.Query)
|
str := fmt.Sprintf("Stm id[%d]: '%s';\n", stmt.ID, stmt.Query)
|
||||||
buf.WriteString(str)
|
buf.WriteString(str)
|
||||||
|
|
||||||
for i := 0; i < int(stmt.ParamCount); i++ {
|
for i := 0; i < int(stmt.ParamCount); i++ {
|
||||||
|
@ -40,7 +39,7 @@ func (stmt *Stmt) WriteToText() []byte {
|
||||||
buf.WriteString(str)
|
buf.WriteString(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
str = fmt.Sprintf("执行预处理[%d]: ", stmt.ID)
|
str = fmt.Sprintf("Execute stm id[%d]: ", stmt.ID)
|
||||||
buf.WriteString(str)
|
buf.WriteString(str)
|
||||||
for i := 0; i < int(stmt.ParamCount); i++ {
|
for i := 0; i < int(stmt.ParamCount); i++ {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
|
@ -54,7 +53,7 @@ func (stmt *Stmt) WriteToText() []byte {
|
||||||
}
|
}
|
||||||
buf.WriteString(";\n")
|
buf.WriteString(";\n")
|
||||||
|
|
||||||
str = fmt.Sprintf("丢弃预处理[%d];\n", stmt.ID)
|
str = fmt.Sprintf("Drop stm id[%d];\n", stmt.ID)
|
||||||
buf.WriteString(str)
|
buf.WriteString(str)
|
||||||
|
|
||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
|
@ -72,13 +71,11 @@ func (stmt *Stmt) BindArgs(nullBitmap, paramTypes, paramValues []byte) error {
|
||||||
|
|
||||||
for i := 0; i < int(stmt.ParamCount); i++ {
|
for i := 0; i < int(stmt.ParamCount); i++ {
|
||||||
|
|
||||||
//判断参数是否为null
|
|
||||||
if nullBitmap[i>>3]&(1<<(uint(i)%8)) > 0 {
|
if nullBitmap[i>>3]&(1<<(uint(i)%8)) > 0 {
|
||||||
args[i] = nil
|
args[i] = nil
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
//参数类型
|
|
||||||
typ := paramTypes[i<<1]
|
typ := paramTypes[i<<1]
|
||||||
unsigned := (paramTypes[(i<<1)+1] & 0x80) > 0
|
unsigned := (paramTypes[(i<<1)+1] & 0x80) > 0
|
||||||
|
|
||||||
|
@ -168,7 +165,7 @@ func (stmt *Stmt) BindArgs(nullBitmap, paramTypes, paramValues []byte) error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return errors.New(fmt.Sprintf("预处理未知类型 %d", typ))
|
return errors.New(fmt.Sprintf("ERR : Unknown stm type %d", typ))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -31,19 +31,15 @@ func NewInstance() *Redis{
|
||||||
return redis
|
return redis
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
解析流
|
|
||||||
*/
|
|
||||||
func (red Redis) ResolveStream(net, transport gopacket.Flow, r io.Reader) {
|
func (red Redis) ResolveStream(net, transport gopacket.Flow, r io.Reader) {
|
||||||
|
|
||||||
//只解析clint发出去的包
|
|
||||||
buf := bufio.NewReader(r)
|
buf := bufio.NewReader(r)
|
||||||
var cmd string
|
var cmd string
|
||||||
var cmdCount = 0
|
var cmdCount = 0
|
||||||
for {
|
for {
|
||||||
|
|
||||||
line, _, _ := buf.ReadLine()
|
line, _, _ := buf.ReadLine()
|
||||||
//判断链接是否断开
|
|
||||||
if len(line) == 0 {
|
if len(line) == 0 {
|
||||||
buff := make([]byte, 1)
|
buff := make([]byte, 1)
|
||||||
_, err := r.Read(buff)
|
_, err := r.Read(buff)
|
||||||
|
@ -53,17 +49,17 @@ func (red Redis) ResolveStream(net, transport gopacket.Flow, r io.Reader) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//过滤无用数据
|
//Filtering useless data
|
||||||
if !strings.HasPrefix(string(line), "*") {
|
if !strings.HasPrefix(string(line), "*") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
//过滤服务器返回数据
|
//Do not display
|
||||||
if strings.EqualFold(transport.Src().String(), strconv.Itoa(red.port)) == true {
|
if strings.EqualFold(transport.Src().String(), strconv.Itoa(red.port)) == true {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
//解析
|
//run
|
||||||
l := string(line[1])
|
l := string(line[1])
|
||||||
cmdCount, _ = strconv.Atoi(l)
|
cmdCount, _ = strconv.Atoi(l)
|
||||||
cmd = ""
|
cmd = ""
|
||||||
|
@ -87,7 +83,7 @@ func (red *Redis) SetFlag(flg []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if c >> 1 != 1 {
|
if c >> 1 != 1 {
|
||||||
panic("Redis参数数量不正确!")
|
panic("ERR : Redis num of params")
|
||||||
}
|
}
|
||||||
for i:=0;i<c;i=i+2 {
|
for i:=0;i<c;i=i+2 {
|
||||||
key := flg[i]
|
key := flg[i]
|
||||||
|
@ -98,14 +94,14 @@ func (red *Redis) SetFlag(flg []string) {
|
||||||
port, err := strconv.Atoi(val);
|
port, err := strconv.Atoi(val);
|
||||||
redis.port = port
|
redis.port = port
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("端口数不正确")
|
panic("ERR : Port error")
|
||||||
}
|
}
|
||||||
if port < 0 || port > 65535 {
|
if port < 0 || port > 65535 {
|
||||||
panic("参数不正确: 端口范围(0-65535)")
|
panic("ERR : Port(0-65535)")
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
panic("参数不正确")
|
panic("ERR : redis's params")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,13 +110,13 @@ func (red *Redis) SetFlag(flg []string) {
|
||||||
BPFFilter
|
BPFFilter
|
||||||
*/
|
*/
|
||||||
func (red *Redis) BPFFilter() string {
|
func (red *Redis) BPFFilter() string {
|
||||||
return "tcp and port "+strconv.Itoa(redis.port);
|
return "tcp and port "+strconv.Itoa(redis.port)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Version
|
Version
|
||||||
*/
|
*/
|
||||||
func (red *Redis) Version() string {
|
func (red *Redis) Version() string {
|
||||||
return red.version;
|
return red.version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue