Q: How to correctly handcraft DNS packets with gopacket? I'm trying to send hand-crafted DNS packets with gopacket.
Here is my code:
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)
    }
}

There is no issue and I correctly see the UDP packet going over the wire, however, when I capture it with Wireshark, it is labelled as "UDP" in the "protocol" column, but if I try host www.google.com, the captured packets are labelled as "DNS". So I guess I'm sending malformed packets, but I can't find what I'm missing.

I have already checked this question, but it didn't solve my issue.

A: The issue seems to be on Wireshark side, I tried your code and it shows up as DNS if you either:

*

*use a standard port for DNS (53)

 udp := layers.UDP{
        SrcPort: 62003,
        DstPort: 53, // < --- changed here
 }



*Right-click on entry and choose Decode As and change UDP port 9000 and set Current as DNS

A: Try to define real MAC addresses (eth.SrcMAC and eth.DstMAC).
Also you should try crafting a question like this:
qst := layers.DNSQuestion{
    Name: []byte("www.google.com") // without the last dot
    Type:  layers.DNSTypeA,
    Class: layers.DNSClassIN,
}

dns := layers.DNS{
    RD:        true, // enable recursion (should be just enough)
    Questions: []layers.DNSQuestion{qst},
}

