2016-06-10 100 views
0

我最近(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, 
      &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 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。我不確定解決方案是什麼。讀取上游庫看起來應該起作用。然而,它並沒有,我很困惑,我應該在哪裏尋找。作爲新的去它是送我循環。

+0

如果沒有更多數據,很難/無法回答。建議製作併發布_brief_示例(儘可能小),以說明您確切的問題 - 包括您希望在什麼時候顯示哪些數據(例如,某些fmt.Printf(「這應該是X但是打印Y:%... 「);以及你如何獲得程序的輸入 - 只需從」挖「或什麼?提供確切的命令行。)如果你還沒有:請閱讀本文:http://stackoverflow.com/help/mcve –

+0

你是否設法解決這個問題?而且......是你的解決方案開源嗎?我需要解決一個非常類似的問題,我很樂意重用您的解決方案。 – fons

回答