我最近(1月)开始学习golang。我想重现一个我们在内部使用Go编写的Python工具。使用gopacket作为初学者学习golang
所以我有这个工具完全用于DNS的UDP解码,但是我一直在努力尝试获得基于TCP的DNS解码。我的目标是记录每个打包到我们DNS服务器的数据包的DNS来源,目的地,查询和答案。与dnstap类似,但我们有一个内部解决方案,目前使用Python来适应我们的内部自定义日志记录和事件关联系统。
func Listen(h *pcap.Handle, c *Config, logger chan<- *dnslog) {
qType := decodeQuery()
OpCode := decodeOpCode()
parser := gopacket.NewDecodingLayerParser(
layers.LayerTypeEthernet,
ð,
&ip4,
&ip6,
&tcp,
&udp,
&dns,
)
decoded := make([]gopacket.LayerType, 0, 10)
for {
data, _, err := h.ZeroCopyReadPacketData()
if err != nil {
log.Println("Error reading packet data ", err)
continue
}
dnslog := &dnslog{}
err = parser.DecodeLayers(data, &decoded)
for _, layer := range decoded {
switch layer {
case layers.LayerTypeIPv4:
dnslog.Dst = ip4.DstIP.String()
dnslog.Src = ip4.SrcIP.String()
case layers.LayerTypeIPv6:
dnslog.Dst = ip6.DstIP.String()
dnslog.Src = ip6.SrcIP.String()
case layers.LayerTypeTCP:
dnslog.Srcport = fmt.Sprintf("%d", tcp.SrcPort)
dnslog.Dstport = fmt.Sprintf("%d", tcp.DstPort)
case layers.LayerTypeUDP:
dnslog.Srcport = fmt.Sprintf("%d", udp.SrcPort)
dnslog.Dstport = fmt.Sprintf("%d", udp.DstPort)
case layers.LayerTypeDNS:
dnslog.Truncated = dns.TC
for _, q := range dns.Questions {
dnslog.OpCode = OpCode[uint8(dns.OpCode)]
dnslog.QueryCount = dns.QDCount
dnslog.AnswerCount = dns.ANCount
}
}
}
logger <- dnslog
}
我试图迫使NextLayerType在层/ tcp.go到DNS Layertype等,试图找到我丢失的东西。到目前为止没有运气。任何建议将是王牌。我们用UDP看到的是以下输出。 (pprint JSON编码输出)
[{ "src": "172.10.56.23", "src_port": "52464", "dst": "172.10.16.120", "dst_port": "53", "bytes": 63, "transport": "UDP", "reply_code": "Query", "query_count": 1, "answer_count": 0, "question": ["helposx.apple.com"], "query_type": "A", "answer": null, "truncated": false }, { "src": "172.10.16.120", "src_port": "53", "dst": "172.10.56.23", "dst_port": "52464", "bytes": 156, "transport": "UDP", "reply_code": "Query", "query_count": 1, "answer_count": 3, "question": ["helposx.apple.com"], "query_type": "A", "answer": [{ "response-name": "helposx.apple.com", "response-query_type": "CNAME", "response-ttl": 4607, "response-bytes": 31, "response-cname": "helposx.apple.com.edgekey.net", "response-soa": {}, "response-srv": {}, "response-mx": {} }, { "response-name": "helposx.apple.com.edgekey.net", "response-query_type": "CNAME", "response-ttl": 33, "response-bytes": 22, "response-cname": "e3167.e9.akamaiedge.net", "response-soa": {}, "response-srv": {}, "response-mx": {} }, { "response-name": "e3167.e9.akamaiedge.net", "response-query_type": "A", "response-ttl": 13, "response-bytes": 4, "response-ip": "104.98.20.77", "response-soa": {}, "response-srv": {}, "response-mx": {} }], "truncated": false }]
如果我现在用挖+ TCP(TCP力)我得到以下输出做同样的查询。
[{ "src": "172.10.56.23", "src_port": "57188", "dst": "172.10.16.120", "dst_port": "53", "bytes": 64, "transport": "TCP", "reply_code": "", "query_count": 0, "answer_count": 0, "question": null, "query_type": "", "answer": null, "truncated": false }, { "src": "172.10.16.120", "src_port": "53", "dst": "172.10.56.23", "dst_port": "57188", "bytes": 60, "transport": "TCP", "reply_code": "", "query_count": 0, "answer_count": 0, "question": null, "query_type": "", "answer": null, "truncated": false }, { "src": "172.10.56.23", "src_port": "57188", "dst": "172.10.16.120", "dst_port": "53", "bytes": 52, "transport": "TCP", "reply_code": "", "query_count": 0, "answer_count": 0, "question": null, "query_type": "", "answer": null, "truncated": false }, { "src": "172.10.56.23", "src_port": "57188", "dst": "172.10.16.120", "dst_port": "53", "bytes": 86, "transport": "TCP", "reply_code": "", "query_count": 0, "answer_count": 0, "question": null, "query_type": "", "answer": null, "truncated": false }, { "src": "172.10.16.120", "src_port": "53", "dst": "172.10.56.23", "dst_port": "57188", "bytes": 102, "transport": "TCP", "reply_code": "", "query_count": 0, "answer_count": 0, "question": null, "query_type": "", "answer": null, "truncated": false }, { "src": "172.10.56.23", "src_port": "57188", "dst": "172.10.16.120", "dst_port": "53", "bytes": 52, "transport": "TCP", "reply_code": "", "query_count": 0, "answer_count": 0, "question": null, "query_type": "", "answer": null, "truncated": false }]
从wireshark中查看相同的数据包,我可以看到那些不同的数据包是TCP握手,然后是响应。哪个没有解码。
当我在for _,layer:= range解码后添加一个fmt.Println(layer)时,我得到以下内容。
以太网 的IPv4 TCP < < JSON输出之上。
VS
以太网 的IPv4 UDP DNS
正如你可以看到有永远的TCP基于DNS的下一个解码器。它只停留在TCP。我不确定解决方案是什么。读取上游库看起来应该起作用。然而,它并没有,我很困惑,我应该在哪里寻找。作为新的去它是送我循环。
如果没有更多数据,很难/无法回答。建议制作并发布_brief_示例(尽可能小),以说明您确切的问题 - 包括您希望在什么时候显示哪些数据(例如,某些fmt.Printf(“这应该是X但是打印Y:%... “);以及你如何获得程序的输入 - 只需从”挖“或什么?提供确切的命令行。)如果你还没有:请阅读本文:http://stackoverflow.com/help/mcve –
你是否设法解决这个问题?而且......是你的解决方案开源吗?我需要解决一个非常类似的问题,我很乐意重用您的解决方案。 – fons