Sending UDP packets with gopacket

2019-09-10 17:10发布

问题:

I am trying to send UDP packets to a remote host like this

conn, err := net.ListenPacket("ip4:udp", "0.0.0.0")
if err != nil {
    panic(err)
}
ip := &layers.IPv4{
    SrcIP:    saddr,
    DstIP:    dip,
    Protocol: layers.IPProtocolUDP,
}
udp := &layers.UDP{
    SrcPort: layers.UDPPort(sport),
    DstPort: layers.UDPPort(us.Port),
}
udp.SetNetworkLayerForChecksum(ip)
buf := gopacket.NewSerializeBuffer()
opts := gopacket.SerializeOptions{
    ComputeChecksums: true,
    FixLengths:       true,
}
if err := gopacket.SerializeLayers(buf, opts, udp); err != nil {
    fmt.Printf("%v", err)
}
if _, err := us.Conn.WriteTo(buf.Bytes(), &net.IPAddr{IP: dip}); err != nil {
    panic(err)
}

// reading
for {
    buf2 := make([]byte, 4096)
    n, addr, err := us.Conn.ReadFrom(buf2)
    if err != nil {
        fmt.Printf("%v", err)
    }
    if addr.String() == dip.String() {
        fmt.Printf("Got a reply")
    }
}

But this keeps erring out while reading packets with read ip4 0.0.0.0: i/o timeout. When I tcpdump, I see packets being sent out and one UDP response coming back on port 53 others are all ICMP. Why can't my code read those packets?

回答1:

I'm not an expert in Go but it seems you have to use function net.ListenUDP and specify the port to bind the UDP socket. Then you use that connection (obtained from ListeUDP) to read from there. I assume you are specifying port 53 in 'sport'.

Here there is a simple example of a client and server: https://varshneyabhi.wordpress.com/2014/12/23/simple-udp-clientserver-in-golang/



回答2:

You mix in example two different approach to UDP packet creation. You should use only one.

First approach using Go application "net" module to prepare and send UDP packet. This is common way and in most common way you will use this one.

Secand approach using Google special "gopacket" module to prepare RAW network packet. This is hacker way to check hardware or implement special protocol and emulate some specific protocol stack. This only expert way to create special utility and test application.

It you create new hardware and try to interopt with this devices you may use gopakcet or if you simple create software application you should use net package.