请教一个关于 gopacket 包使用的问题

2018-01-03 17:00:20 +08:00
 fivestrong

go 新手,想用 go 语言实现一个简单的 http 抓包工具,按照需求输出 http request 和 response 的结果,类似格式这样:

2018-01-03 16:34:04.511 192.168.0.3     100.72.13.1     >       GET     safedog.jcloud.com      /safeCenter/uai.html?data=GNFltny5lT4wKmP2kV2UN1fuUwbJXlYYVxevSodjDvmkP%2FgC2MWX7XW%2FzkKx420J4C6tz60iDO38TevM1%2FKwz2Eho53wA95naaSa1YehC431nZ3MvKWcQvRNt9Dt%2BGatstbZ1EeAGCqFCAvpwUfdPw%3D%3D     HTTP/1.1        -       -
2018-01-03 16:34:04.516 100.72.13.1     192.168.0.3     <       -       -       -       HTTP/1.1        200     OK

这个 https://github.com/google/gopacket 实现了 libcap 抓包封装,然后官方有个 https://github.com/google/gopacket/tree/master/examples/httpassembly 例子 它在 run 函数里面用了 go 的 net/http.ReadRequest 来解析流量数据,在 BPF 设置为'tcp and dst port 80'过滤是没问题的,但是如果想要同时解析 request,response 会报错。于是我又用了 http.ReadResponse 这个函数,单独测试的时候这个函数解析 response 包是没问题的,但要两个同时使用来解析同一个 tcp 流的数据,单纯的 if else 结构判断会报错或者导致 cpu 占满,代码如下:

func (h *httpStream) run() {
	buf := bufio.NewReader(&h.r)
	for {
		req, err1 := http.ReadRequest(buf)
		if (err1 != io.EOF && err1 == nil) {
			req.Body.Close()
			log.Println("Received request from stream", h.net, h.transport, ":", req.Host)
		}

		resp, err2 := http.ReadResponse(buf, req)
		if (err2 != io.EOF && err2 == nil) {
			resp.Body.Close()
			log.Println("Received response from stream", h.net, h.transport, ":", resp.Status)
		}		
	
	}
}

官方的函数是这个:

func (h *httpStream) run() {
	buf := bufio.NewReader(&h.r)
	for {
		req, err := http.ReadRequest(buf)
		if err == io.EOF {
			// We must read until we see an EOF... very important!
			return
		} else if err != nil {
			log.Println("Error reading stream", h.net, h.transport, ":", err)
		} else {
			bodyBytes := tcpreader.DiscardBytesToEOF(req.Body)
			req.Body.Close()
			log.Println("Received request from stream", h.net, h.transport, ":", req, "with", bodyBytes, "bytes in request body")
		}
	}
}

我试过在 else if err != nil 这个分支进行 response 判断,还是有问题。不是很懂这个逻辑需要怎么弄,希望各位大神指点一二。 还有是不是跟它用到的 github.com/google/gopacket/tcpassembly 这个 tcp 流重组有关系,说实话源码工作流程没怎么看懂。

2020 次点击
所在节点    Go 编程语言
1 条回复
goofool
2018-01-04 09:21:26 +08:00
ReadRequest 不是已经把 buf 读完了吗,ReadResponse 有东西读吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/419767

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX