0

我正在尝试使用 gopacket 发送手工制作的 DNS 数据包。

这是我的代码:

package main

import (
    "net"

    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "github.com/google/gopacket/pcap"
)

func main() {
    handle, err := pcap.OpenLive("lo", 1500, false, pcap.BlockForever)
    if err != nil {
        panic(err)
    }

    // Create ethernet layer
    eth := layers.Ethernet{
        SrcMAC:       net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        DstMAC:       net.HardwareAddr{0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        EthernetType: layers.EthernetTypeIPv4,
    }

    // Create ip layer
    ip := layers.IPv4{
        Version:  4,
        TTL:      64,
        SrcIP:    net.IP{1, 3, 3, 7},
        DstIP:    net.IP{127, 0, 0, 1},
        Protocol: layers.IPProtocolUDP,
    }

    // Create udp layer
    udp := layers.UDP{
        SrcPort: 62003,
        DstPort: 9000,
    }
    udp.SetNetworkLayerForChecksum(&ip)

    qst := layers.DNSQuestion{
        Name:  []byte{'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm', '.'},
        Type:  layers.DNSTypeCNAME,
        Class: layers.DNSClassIN,
    }

    dns := layers.DNS{
        BaseLayer:    layers.BaseLayer{},
        ID:           0,
        QR:           true,
        OpCode:       0,
        AA:           false,
        TC:           false,
        RD:           true,
        RA:           true,
        Z:            0,
        ResponseCode: 0,
        QDCount:      1,
        ANCount:      1,
        NSCount:      0,
        ARCount:      0,
        Questions:    []layers.DNSQuestion{qst},
    }

    buffer := gopacket.NewSerializeBuffer()
    options := gopacket.SerializeOptions{
        ComputeChecksums: true,
        FixLengths:       true,
    }

    if err = gopacket.SerializeLayers(buffer, options,
        &eth,
        &ip,
        &udp,
        &dns,
    ); err != nil {
        panic(err)
    }
    outgoingPacket := buffer.Bytes()

    if err = handle.WritePacketData(outgoingPacket); err != nil {
        panic(err)
    }
}

没有问题,我正确地看到了通过线路传输的 UDP 数据包,但是,当我使用 Wireshark 捕获它时,它在“协议”列中被标记为“UDP”,但如果我尝试host www.google.com,捕获的数据包被标记为“DNS”。所以我想我正在发送格式错误的数据包,但我找不到我丢失的东西。

我用 Wireshark 捕获的数据包在协议部分有错误的标签

我已经检查过这个问题,但它并没有解决我的问题。

4

2 回答 2

0

问题似乎出在 Wireshark 方面,我尝试了您的代码,如果您有以下任一情况,它就会显示为 DNS:

  1. 为 DNS 使用标准端口 (53)
 udp := layers.UDP{
        SrcPort: 62003,
        DstPort: 53, // < --- changed here
 }
  1. 右键单击条目并选择Decode As并更改 UDP 端口 9000 并设置CurrentDNS
于 2021-02-16T09:09:19.307 回答
0

尝试定义真实的 MAC 地址(eth.SrcMACeth.DstMAC)。

此外,您应该尝试制作这样的问题:

qst := layers.DNSQuestion{
    Name:  []byte{'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm'}, // without last dot
    Type:  layers.DNSTypeA,
    Class: layers.DNSClassIN,
}

dns := layers.DNS{
    RD:        true, // enable recursion (should be just enough)
    Questions: []layers.DNSQuestion{qst},
}
于 2022-01-21T13:00:29.620 回答