I am trying to add route in my Mac machine using AF_ROUTE socket in golang. I took one pragram in C and trying to convert it to golang. below is my golang program:
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")
}
in this when i am running this program it says buffer is not available. could anyone help what could be the issue here. Could be my structs are not correct or something basic might be missing.