Golang Raw сокет UDP не работает - PullRequest
0 голосов
/ 26 апреля 2018

Основной вопрос

Я ищу способ отправки пакетов, используя язык go, который дает мне возможность просматривать и устанавливать TTL и другие поля пакетов низкого уровня (мне не нужно изменятьЗаголовки Ethernet просто заголовки IP и UDP).Я попытался создать и отправить свои собственные пакеты в коде ниже.

При выполнении кода ниже получатель не получает никаких сообщений.Может ли кто-либо из них: а) предупредить меня о любых ошибках, которые я допустил в этом коде, или б) предложить другой способ отправки данных udp с помощью golang при сохранении доступа к заголовкам ip & udp?

(я удалил mac-адреса, их нужно будет заменить, чтобы запустить этот код)

Код

(Отправка)

основной пакет

import (
    "syscall"
    "log"
    "github.com/google/gopacket"
    "github.com/google/gopacket/layers"
    "fmt"
    "encoding/hex"
    "encoding/json"
    "net"
)

type NameTag struct {
    Name string `json:"name"`
}

func main() {
    var err error
    fd, e := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_UDP)
    if e != nil {
        fmt.Println("Problem @ location 1")
    }
    addr := syscall.SockaddrInet4{
        Port: 27289,
        Addr: [4]byte{127, 0, 0, 1},
    }
    p := pkt()
    err = syscall.Sendto(fd, p, 0, &addr)
    if err != nil {
        log.Fatal("Sendto:", err)
    }
}

func pkt() []byte {
    sb := gopacket.NewSerializeBuffer()
    nt := NameTag{"Paul"}
    b, _ := json.Marshal(nt)
    pld := gopacket.Payload(b)
    l := uint16(len(pld))
    udp := layers.UDP{
        SrcPort:  27289,
        DstPort:  27288,
        Length:   l + 8,
        Checksum: 0,
    }
    l = l + 8
    ip := layers.IPv4{
        Version:    0x4,
        IHL:        5,
        Length:     20 + l,
        TTL:        255,
        Flags:      0x40,
        FragOffset: 0,
        Checksum:   0,
        Protocol:   syscall.IPPROTO_UDP,
        DstIP:      net.IPv4(127, 0, 0, 1),
        SrcIP:      net.IPv4(127, 0, 0, 1),
    }
    l = l + 20

    eth := layers.Ethernet{
        EthernetType: layers.EthernetTypeIPv4,
        SrcMAC: net.HardwareAddr{
            0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
        },
        DstMAC: net.HardwareAddr{
            0x--, 0x--, 0x--, 0x--, 0x--, 0x--,
        },
    }
    fmt.Println(pld.SerializeTo(sb, gopacket.SerializeOptions{}))
    fmt.Println(udp.SerializeTo(sb, gopacket.SerializeOptions{}))
    fmt.Println(ip.SerializeTo(sb, gopacket.SerializeOptions{}))
    fmt.Println(eth.SerializeTo(sb, gopacket.SerializeOptions{}))

    //Debug prints here (first line is for dump to packet validator)
    fmt.Println(hex.EncodeToString(sb.Bytes()))
    fmt.Println(sb.Bytes())

    return sb.Bytes()
}

(Получение)

основной пакет

import (
    "syscall"
    "os"
    "fmt"
)

func main() {
    fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_UDP)
    if err != nil {
        fmt.Println(err)
        return
    }
    sa:= &syscall.SockaddrInet4{
        Addr: [4]byte{127,0,0,1},
        Port:27288,
    }
    e := syscall.Bind(fd, sa)
    if e != nil {
        fmt.Println("problems @ location 1")
    }
    f := os.NewFile(uintptr(fd), fmt.Sprintf("fd%d", fd))
    fmt.Println("Entering main loop")
    for {
        fmt.Println("In loop")
        buf := make([]byte, 1024)
        numRead, err := f.Read(buf)
        if err != nil {
            fmt.Println("problems @ location 2")
        }
        fmt.Printf("Loop done %v\n", buf[:numRead])
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...