2016-11-18 66 views
1

使用Go什麼包,本地函數,系統調用可以用來獲得對*nix system什麼系統調用/方法我可以用它來獲取默認網關

默認網關我想,以避免產生包裝以防萬一netstat ,路由,ip等命令或讀取,解析現有文件,其思想是獲取最可行的值。

例如,這是route命令的輸出:

$ route -n get default 
    route to: default 
destination: default 
     mask: default 
    gateway: 192.168.1.1 
    interface: en1 
     flags: <UP,GATEWAY,DONE,STATIC,PRCLONING> 
recvpipe sendpipe ssthresh rtt,msec rttvar hopcount  mtu  expire 
     0   0   0   0   0   0  1500   0 

我想做點什麼simliar爲了只打印/獲得gateeway地址/接口。

+0

'net.Interfaces()'包含網關? https://golang.org/pkg/net/#Interfaces – dm03514

+0

@ dm03514我不相信它。 – captncraig

+1

出於好奇,你爲什麼需要這個? – captncraig

回答

0

https://github.com/golang/net/blob/master/internal/nettest/interface.go

示例代碼剪斷播放與RoutedInterface()代碼:

rifs := nettest.RoutedInterface("ip", net.FlagUp | net.FlagBroadcast) 
if rifs != nil { 
    fmt.Println("Routed interface is ",rifs.HardwareAddr.String()) 
    fmt.Println("Flags are", rifs.Flags.String()) 
} 

注意:您需要將golang代碼複製到當地的圖書館,因爲/內部通話不允許直接。

+0

不知道爲什麼這被接受,因爲問題詢問關於網關IP。如果你看一下interface.go鏈接,代碼對網關什麼也不做;它只是檢查本地接口上的地址並返回一個滿意的地址。 – Mark

2

一種選擇是讀取/proc/net/route。在我的系統之一,這包括:

Iface Destination Gateway  Flags RefCnt Use Metric Mask  MTU Window IRTT              
team0 00000000 010017BA 0003 0 0 0 00000000 0 0 0                    
team0 0000070A 00000000 0001 0 0 0 00FEFFFF 0 0 0                    

你可以讀到,在,捕捉一些文本處理的網關和十六進制字符串轉換爲net.IP.有點繞了一圈,但我找不到任何可以在std lib或其他地方爲你訪問的軟件包。

+0

這似乎是在Linux上,但unixes(freebsd,mac os等)如何我想要的東西不可知論。 – nbari

3

對於Linux,可以按照captncraig的建議使用procfs。下面是一個摘錄網關地址並將其轉換爲quad dotted IPV4的片段。

/* /proc/net/route file: 
Iface Destination Gateway  Flags RefCnt Use Metric Mask 
eno1 00000000 C900A8C0 0003 0 0 100 00000000 0 00                    
eno1 0000A8C0 00000000 0001 0 0 100 00FFFFFF 0 00 
*/ 

const (
    file = "/proc/net/route" 
    line = 1 // line containing the gateway addr. (first line: 0) 
    sep = "\t" // field separator 
    field = 2 // field containing hex gateway address (first field: 0) 
) 

func main() { 

    file, err := os.Open(file) 
    if err != nil { 
     log.Fatal(err) 
    } 
    defer file.Close() 

    scanner := bufio.NewScanner(file) 
    for scanner.Scan() { 

     // jump to line containing the agteway address 
     for i := 0; i < line; i++ { 
      scanner.Scan() 
     } 

     // get field containing gateway address 
     tokens := strings.Split(scanner.Text(), sep) 
     gatewayHex := "0x" + tokens[field] 

     // cast hex address to uint32 
     d, _ := strconv.ParseInt(gatewayHex, 0, 64) 
     d32 := uint32(d) 

     // make net.IP address from uint32 
     ipd32 := make(net.IP, 4) 
     binary.LittleEndian.PutUint32(ipd32, d32) 
     fmt.Printf("%T --> %[1]v\n", ipd32) 

     // format net.IP to dotted ipV4 string 
     ip := net.IP(ipd32).String() 
     fmt.Printf("%T --> %[1]v\n", ip) 

     // exit scanner 
     break 
    } 
} 
+0

這是我想避免的一種情況,我想知道一些系統調用,以便使這個更不可操作的不可知的 – nbari

+0

@nbari:系統調用不會使它更不OS不可知,系統調用更依賴於系統。每個操作系統都有自己的工具,您需要使用它。你可能會發現'netstat'命令的一些子集,它將在大多數操作系統上打印路由表,否則只需調出適合每個操作系統的命令。 – JimB

+0

@JimB我的目標是使用系統調用,儘管我必須維護系統調用,而且交叉編譯也是爲了避免依賴外部命令,這樣我就可以生成一個在幾乎所有系統上都可以運行的二進制文件。 – nbari

相關問題