mirror of
				https://github.com/40t/go-sniffer.git
				synced 2025-11-04 19:16:25 +08:00 
			
		
		
		
	
							
								
								
									
										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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user