gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 21:11:20 24 4
gpt4 key购买 nike

我正在尝试使用 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 .某些标志可能不受支持。

关于go - 在 Mac 上的 golang 中使用 AF_ROUTE 添加路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60700271/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com