GOREPLAY使用GO语言编写,源码下载后,安装好GO的运行环境,安装PCAP等linux应用后,还需要对GOREPLAY依赖的GO包进行下载并且放到指定的目录,GO通常是通过GIT获取依赖的包,但因为机器在内网,不能连接互联网,所以我采取的方式把依赖下载到本地,再上传到GO的GOPATH,按路径放好,最后go build可以编译出一个可运行的二进制可执行文件。
命令行参数
GOREPLAY支持很多种命令行参数。具体支持的命令行参数可以goreplay --help来查看,我们主要使用GOREPLAY转发HTTP,通常命令为:
goreplay --input-raw :8080 --output-tcp 10.60.20.8:8080
意思就是监听本机的8080端口,把8080端口上的数据报文转发到10.60.20.8:8080。
GOREPLAY是如何处理这些命令行参数的?首先从程序的入口说起,GO语言应用的默认入口在main函数。即在gor.go文件中。但go除了在Package main里的main是入口函数之外,还保留了另一个入口,即在任意package中的init函数。如setting.go中的init函数,该函数会在程序启动时甚至先于main执行。go的函数以及变量的初始化,可以深入读读,这里面有比较深的门路,不深入展开(真实的原因是现在我也不太熟^_^)。
go有一个命令行参数的处理模块,叫flag,使用的过程可以通过一个样例程序大概了解:
package main import ( "flag" "fmt" ) func main() { var src string flag.StringVar(&src, "src", "", "source file") var level *int level = flag.Int("level", 0, "debug level") var memo string flag.StringVar(&memo, "memo", "", "the memory") flag.Parse() flag.Usage() fmt.Printf("src=%s, level=%d, memo=%s\n", src, *level, memo) }
执行 args.exe -src="123" -level=4 -memo="567",输出如下:
Usage of args.exe: -level int debug level -memo string the memory -src string source file src=123, level=4, memo=567
大概的过程就是先绑定命令行上的key,parse时就真正的value取出到指定变量上。
继续加来goreplay源码,执行完setting.go里的init函数之后,即把命令行key与变更绑定,在main函数中的flag.parse()之后,即解析到setting的变量中,随后InitPlugins完成根据命令行指定参数模块的初始化加载。当前命令行为:
goreplay --input-raw :8080 --output-tcp 10.60.20.8:8080
即input_raw.go以及output_tcp.go会初始化加载,初始化过程也是挺多go的API的,有一些我也没有非常了解,类似一些反射之类的,还需要继续深入,但goreplay的命令行参数对程序运行影响大体的流程以及意义就像上面所说的了。后续我们要改造goreplay时,就知道如何增加命令行参数,并且增加对应的代码模块。
下一篇会真正真正进入如何解析TCP以及HTTP协议,完成对一个报文转发前的识别,敬请期待。