要获取某些RTF_*标志的值,可以使用什么系统调用?

huangapple go评论76阅读模式
英文:

what syscall to use in order to obtain the value of some RTF_* flags

问题

使用go,我想从netstat(1)的手册页面中获取一些RTF_*标志的值(UGHS):

G	  RTF_GATEWAY  目标需要通过中间人进行转发
H	  RTF_HOST	   主机条目(否则为网络条目)
S	  RTF_STATIC   手动添加
U	  RTF_UP	   可用路由

你知道我可以使用哪些系统调用/方法来获取这些值吗?我看到它们在https://golang.org/pkg/syscall/中被声明,但我想知道如何使用它们?

我需要找到添加到路由表中的网关的IP,主要是在连接到VPN时(在macOS、FreeBSD中使用netstat):

 netstat -rna -f inet | grep UGHS | awk '{print $1}' 

有什么建议吗?

英文:

Using go, I would like to obtain the value of some RTF_* flags, (UGHS) from netstat(1) man page:

G	  RTF_GATEWAY  Destination requires	forwarding by intermediary
H	  RTF_HOST	   Host	entry (net otherwise)
S	  RTF_STATIC   Manually added
U	  RTF_UP	   Route usable

Any idea of what syscall/methods could I use to retrieve does values? I see they are declared https://golang.org/pkg/syscall/ but would like to know to use them?

I need this to find the IP of gateways added to the route table, mainly when connecting to VPN's, currently using netstat for this (withing macOS, FreeBSD):

 netstat -rna -f inet | grep UGHS | awk '{print $1}' 

Any ideas?

答案1

得分: 3

根据@JimB的建议,使用route包,我能够查询当前路由并获取与特定标志匹配的IP地址,例如UGSHUGSc

基本示例代码:

package main

import (
	"fmt"
	"net"
	"syscall"

	"golang.org/x/net/route"
)

const (
	UGSH = syscall.RTF_UP | syscall.RTF_GATEWAY | syscall.RTF_STATIC | syscall.RTF_HOST
	UGSc = syscall.RTF_UP | syscall.RTF_GATEWAY | syscall.RTF_STATIC | syscall.RTF_PRCLONING
)

func main() {
	if rib, err := route.FetchRIB(syscall.AF_UNSPEC, route.RIBTypeRoute, 0); err == nil {
		if msgs, err := route.ParseRIB(route.RIBTypeRoute, rib); err == nil {
			for _, msg := range msgs {
				m := msg.(*route.RouteMessage)
				if m.Flags == UGSH || m.Flags == UGSc {
					var ip net.IP
					switch a := m.Addrs[syscall.AF_UNSPEC].(type) {
					case *route.Inet4Addr:
						ip = net.IPv4(a.IP[0], a.IP[1], a.IP[2], a.IP[3])
					case *route.Inet6Addr:
						ip = make(net.IP, net.IPv6len)
						copy(ip, a.IP[:])
					}
					fmt.Printf("ip = %s\n", ip)
				}
			}
		}
	}
}
英文:

As @JimB suggested by using the route package I was able to query the current routes and get only IP's matching certain flags, in this case" UGSH, UGSc.

Basic example code:

package main

import (
	"fmt"
	"net"
	"syscall"

	"golang.org/x/net/route"
)

const (
	UGSH = syscall.RTF_UP | syscall.RTF_GATEWAY | syscall.RTF_STATIC | syscall.RTF_HOST
	UGSc = syscall.RTF_UP | syscall.RTF_GATEWAY | syscall.RTF_STATIC | syscall.RTF_PRCLONING
)

func main() {
	if rib, err := route.FetchRIB(syscall.AF_UNSPEC, route.RIBTypeRoute, 0); err == nil {
		if msgs, err := route.ParseRIB(route.RIBTypeRoute, rib); err == nil {
			for _, msg := range msgs {
				m := msg.(*route.RouteMessage)
				if m.Flags == UGSH || m.Flags == UGSc {
					var ip net.IP
					switch a := m.Addrs[syscall.AF_UNSPEC].(type) {
					case *route.Inet4Addr:
						ip = net.IPv4(a.IP[0], a.IP[1], a.IP[2], a.IP[3])
					case *route.Inet6Addr:
						ip = make(net.IP, net.IPv6len)
						copy(ip, a.IP[:])
					}
					fmt.Printf("ip = %s\n", ip)
				}
			}
		}
	}
}

答案2

得分: 0

strace netstat的等效命令(在MacOS上是dtruss,请参考https://opensourcehacker.com/2011/12/02/osx-strace-equivalent-dtruss-seeing-inside-applications-what-they-do-and-why-they-hang/)将给出netstat所进行的系统调用列表,您可以根据需要确定您需要进行的系统调用。

英文:

The equivalent of strace netstat (dtruss on MacOS, see https://opensourcehacker.com/2011/12/02/osx-strace-equivalent-dtruss-seeing-inside-applications-what-they-do-and-why-they-hang/) should give you a list of system calls it makes and you can decide what system calls you need to make for your problem.

huangapple
  • 本文由 发表于 2017年3月21日 22:46:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/42930401.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定