[英]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.