首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用gopacket作为入门学习Golang

使用gopacket作为入门学习Golang
EN

Stack Overflow用户
提问于 2016-06-10 10:22:42
回答 1查看 1.8K关注 0票数 1

我最近(一月)开始学习戈朗语。我正在尝试复制我们内部的一个工具,它是在Go中用Python编写的。

所以我有一个工具完全用于DNS的UDP解码,然而我已经挣扎了一个星期,试图获得基于TCP的DNS解码。我的目标是记录每个到达我们DNS服务器的数据包的DNS源、目的地、查询和应答。以与dnstap类似的方式,我们目前有一个内部解决方案使用Python来适应我们内部的自定义日志和事件关联系统。

代码语言:javascript
运行
复制
    func Listen(h *pcap.Handle, c *Config, logger chan<- *dnslog) {
        qType := decodeQuery()
        OpCode := decodeOpCode()
        parser := gopacket.NewDecodingLayerParser(
            layers.LayerTypeEthernet,
            &eth,
            &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层类型等,试图找到我遗漏的东西。到目前为止还没什么好消息。任何建议都是王牌。我们在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 }]

如果我现在使用dig +tcp (强制TCP)执行完全相同的查询,我会得到以下输出。

通过查看wireshark中相同的数据包,我可以看到这些不同的数据包是[{ "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 }]握手,然后是响应。它没有被解码。

当我在for _,layer := range解码行之后添加一个层(Layer)时,我得到以下结果。

以太网IPv4 TCP << JSON上面的输出。

VS

以太网IPv4 UDP

正如你所看到的,基于TCP的DNS永远不会有下一个解码器。它只是在TCP上停止。我不确定解决方案是什么。读取上游库看起来应该可以工作。然而,它没有,我困惑于我应该在哪里寻找。作为一个新的Go,它让我陷入了循环。

EN

回答 1

Stack Overflow用户

发布于 2016-11-16 22:34:34

I requested support for support for DNS over TCP但最终成为了implementing it myself in the end

它还不支持TCP段的分段,但对于我的用例来说(目前)已经足够好了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37738975

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档