簡體   English   中英

在 Mac 上的 golang 中使用 AF_ROUTE 添加路由

[英]Add routes using AF_ROUTE in golang on Mac

我正在嘗試使用 golang 中的 AF_ROUTE 套接字在我的 Mac 機器中添加路由。 我用 C 編寫了一個程序,並試圖將其轉換為 golang。 下面是我的 golang 程序:

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "syscall"
    "unsafe"
)

/* Copied and Converted from
https://unix.superglobalmegacorp.com/Net2/newsrc/net/route.h.html
*/

type rt_metrics struct {
    rmx_locks    uint64    /* Kernel must leave these values alone */
    rmx_mtu      uint64    /* MTU for this path */
    rmx_hopcount uint64    /* max hops expected */
    rmx_expire   uint64    /* lifetime for route, e.g. redirect */
    rmx_recvpipe uint64    /* inbound delay-bandwith product */
    rmx_sendpipe uint64    /* outbound delay-bandwith product */
    rmx_ssthresh uint64    /* outbound gateway buffer limit */
    rmx_rtt      uint64    /* estimated round trip time */
    rmx_rttvar   uint64    /* estimated rtt variance */
    rmx_pksent   uint32    /* packets sent using this route */
    rmx_state    uint32    /* route state */
    rmx_filler   [3]uint32 /* will be used for T/TCP later */
}

/* Copied and Converted from
https://unix.superglobalmegacorp.com/Net2/newsrc/net/route.h.html
*/

type rt_msghdr struct {
    rtm_msglen  uint16     /* to skip over non-understood messages */
    rtm_version uint8      /* future binary compatability */
    rtm_type    uint8      /* message type */
    rtm_index   uint16     /* index for associated ifp */
    rtm_pid     uint32     /* identify sender */
    rtm_addrs   int        /* bitmask identifying sockaddrs in msg */
    rtm_seq     int        /* for sender to identify action */
    rtm_errno   int        /* why failed */
    rtm_flags   int        /* flags, incl. kern & message, e.g. DONE */
    rtm_use     int        /* from rtentry */
    rtm_inits   uint64     /* which metrics we are initializing */
    rtm_rmx     rt_metrics /* metrics themselves */
}

type rt_msg struct {
    hdr   rt_msghdr
    addr1 syscall.RawSockaddrInet4
    addr2 syscall.RawSockaddrInet4
}

//Init initialize ROUTE Socket
func main() {
    address1 := [4]byte{12, 13, 14, 15}
    address2 := [4]byte{16, 17, 18, 19}
    zero1 := [8]int8{0, 0, 0, 0, 0, 0, 0, 0}
    addr1 := syscall.RawSockaddrInet4{
        0,
        syscall.AF_INET,
        0,
        address1,
        zero1,
    }
    addr2 := syscall.RawSockaddrInet4{
        0,
        syscall.AF_INET,
        0,
        address2,
        zero1,
    }
    var dummy rt_msghdr
    a := unsafe.Sizeof(dummy)
    b := unsafe.Sizeof(addr1) + unsafe.Sizeof(addr1)
    c := a + b
    //  fmt.Print(" a  ", a)
    //  fmt.Print(" b  ", b)
    //  fmt.Print(" c  ", c)
    msgheader := rt_msghdr{
        uint16(c),
        syscall.RTM_VERSION,
        syscall.RTM_ADD,
        (syscall.RTA_DST | syscall.RTA_GATEWAY),
        uint32(syscall.Getpid()),
        syscall.RTA_DST | syscall.RTA_GATEWAY,
        1,
        0,
        0,
        0,
        0,
        rt_metrics{},
    }

    msg := rt_msg{msgheader, addr1, addr2}

    fd, err := syscall.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
    if err != nil {
        fmt.Printf("Could not create Raw Socket")
    }
    defer func() {
        recover()
    }()
    msgtosend := new(bytes.Buffer)
    json.NewEncoder(msgtosend).Encode(msg)
    fmt.Print(" lenght of data ", len(msgtosend.Bytes()))
    d, e := syscall.Write(fd, msgtosend.Bytes())
    fmt.Print(" written ", d, " error is ", e, "\n\n")
}

在這個當我運行這個程序時它說緩沖區不可用。 任何人都可以幫助這里可能是什么問題。 可能是我的結構不正確,或者可能缺少一些基本的東西。

您提到“可能是您的結構不正確嗎?”,是的.. 導出字段的名稱並在這些字段上使用結構標記,也為rt_msghdr使編碼器知道正確的名稱。

type rt_msg struct {
    Hdr   rt_msghdr                   `json:"hdr"`
    Addr1 syscall.RawSockaddrInet4    `json:"addr1"`
    Addr2 syscall.RawSockaddrInet4    `json:"addr2"`
}

type rt_msghdr struct {
    Rtm_msglen  uint16 `json:"rtm_msglen"`    /* to skip over non-understood messages */
    // ... and so on
    Rtm_rmx     rt_metrics `json:"rtm_rmx"` /* metrics themselves */
}

type rt_metrics struct {
    Rmx_locks    uint64    `json:"rmx_locks"` /* Kernel must leave these values alone */
    // ... and so on
}

上面的代碼修復了空字節發送到fd 如果no buffer space available您可以查看此鏈接: https : //docs.netgate.com/pfsense/en/latest/routing/no-buffer-space-available.html 編譯您的代碼可能會在其他操作系統上遇到一些問題,因為它使用syscall 某些標志可能不受支持。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM