Отправка пакетов UDP с помощью gopacket

Я пытаюсь отправить UDP-пакеты на удаленный хост, как это

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")
    }
}

Но это продолжает приводить к ошибкам при чтении пакетов с read ip4 0.0.0.0: i/o timeout, Когда я запускаю tcpdump, я вижу, что пакеты отправляются, и один ответ UDP возвращается на порт 53, все остальные - ICMP. Почему мой код не может прочитать эти пакеты?

2 ответа

Я не специалист по Go, но, похоже, вам нужно использовать функцию net.ListenUDP и указать порт для привязки сокета UDP. Затем вы используете это соединение (полученное из ListeUDP) для чтения оттуда. Я предполагаю, что вы указываете порт 53 в "спорт".

Вот простой пример клиента и сервера: https://varshneyabhi.wordpress.com/2014/12/23/simple-udp-clientserver-in-golang/

В примере вы смешиваете два разных подхода к созданию пакетов UDP. Вы должны использовать только один.

Первый подход с использованием модуля net приложения Go для подготовки и отправки пакета UDP. Это обычный способ, и в большинстве случаев вы будете использовать этот.

Secand подход, используя специальный модуль Google "gopacket" для подготовки пакета RAW сети. Это хакерский способ проверить оборудование или реализовать специальный протокол и эмулировать определенный стек протоколов. Это единственный экспертный способ создания специальных утилит и тестовых приложений.

Если вы создаете новое оборудование и пытаетесь взаимодействовать с этими устройствами, вы можете использовать gopakcet или, если вы просто создаете программное приложение, вам следует использовать сетевой пакет.

Другие вопросы по тегам