project initialized
This commit is contained in:
commit
a7a1195150
69
.gitignore
vendored
Normal file
69
.gitignore
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
# Created by .ignore support plugin (hsz.mobi)
|
||||
### JetBrains template
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
# User-specific stuff:
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/dictionaries
|
||||
|
||||
# Sensitive or high-churn files:
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.xml
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
|
||||
# Gradle:
|
||||
.idea/**/gradle.xml
|
||||
.idea/**/libraries
|
||||
|
||||
# Mongo Explorer plugin:
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
## File-based project format:
|
||||
*.iws
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# IntelliJ
|
||||
/out/
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
### Go template
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||
.glide/
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
vendor/
|
||||
glide.lock
|
||||
.DS_Store
|
||||
dist/
|
||||
debug
|
||||
Gopkg.lock
|
32
.vscode/launch.json
vendored
Normal file
32
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"remotePath": "",
|
||||
"port": 2345,
|
||||
"host": "127.0.0.1",
|
||||
"program": "${workspaceRoot}/main.go",
|
||||
"env": {},
|
||||
"args": [],
|
||||
"showLog": true
|
||||
},
|
||||
{
|
||||
"name": "File Debug",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"remotePath": "",
|
||||
"port": 2345,
|
||||
"host": "127.0.0.1",
|
||||
"program": "${fileDirname}",
|
||||
"env": {},
|
||||
"args": [],
|
||||
"showLog": true
|
||||
}
|
||||
|
||||
]
|
||||
}
|
14
.vscode/settings.json
vendored
Normal file
14
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"editor.autoClosingBrackets": true,
|
||||
"editor.trimAutoWhitespace": true,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"files.trimFinalNewlines": true,
|
||||
"go.testFlags": [
|
||||
"-v",
|
||||
],
|
||||
"go.testTimeout": "300s"
|
||||
}
|
30
Gopkg.toml
Normal file
30
Gopkg.toml
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
162
net/gateway/gateway-common.go
Normal file
162
net/gateway/gateway-common.go
Normal file
|
@ -0,0 +1,162 @@
|
|||
package gateway
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var errNoGateway = errors.New("no gateway found")
|
||||
|
||||
func parseWindowsRoutePrint(output []byte) (net.IP, string, error) {
|
||||
// Windows route output format is always like this:
|
||||
// ===========================================================================
|
||||
// Active Routes:
|
||||
// Network Destination Netmask Gateway Interface Metric
|
||||
// 0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.100 20
|
||||
// ===========================================================================
|
||||
// I'm trying to pick the active route,
|
||||
// then jump 2 lines and pick the third IP
|
||||
// Not using regex because output is quite standard from Windows XP to 8 (NEEDS TESTING)
|
||||
lines := strings.Split(string(output), "\n")
|
||||
for idx, line := range lines {
|
||||
if strings.HasPrefix(line, "Active Routes:") {
|
||||
if len(lines) <= idx+2 {
|
||||
return nil, "", errNoGateway
|
||||
}
|
||||
|
||||
fields := strings.Fields(lines[idx+2])
|
||||
if len(fields) < 3 {
|
||||
return nil, "", errNoGateway
|
||||
}
|
||||
|
||||
ip := net.ParseIP(fields[2])
|
||||
if ip != nil {
|
||||
return ip, fields[3], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, "", errNoGateway
|
||||
}
|
||||
|
||||
func parseLinuxIPRoute(output []byte) (net.IP, string, error) {
|
||||
// Linux '/usr/bin/ip route show' format looks like this:
|
||||
// default via 192.168.178.1 dev wlp3s0 metric 303
|
||||
// 192.168.178.0/24 dev wlp3s0 proto kernel scope link src 192.168.178.76 metric 303
|
||||
lines := strings.Split(string(output), "\n")
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 3 && fields[0] == "default" {
|
||||
ip := net.ParseIP(fields[2])
|
||||
if ip != nil {
|
||||
return ip, fields[4], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, "", errNoGateway
|
||||
}
|
||||
|
||||
func parseLinuxRoute(output []byte) (net.IP, string, error) {
|
||||
// Linux route out format is always like this:
|
||||
// Kernel IP routing table
|
||||
// Destination Gateway Genmask Flags Metric Ref Use Iface
|
||||
// 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
|
||||
lines := strings.Split(string(output), "\n")
|
||||
for _, line := range lines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 2 && fields[0] == "0.0.0.0" {
|
||||
ip := net.ParseIP(fields[1])
|
||||
if ip != nil {
|
||||
return ip, fields[7], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, "", errNoGateway
|
||||
}
|
||||
|
||||
func parseDarwinRouteGet(output []byte) (net.IP, string, error) {
|
||||
// Darwin route out format is always like this:
|
||||
// route to: default
|
||||
// destination: default
|
||||
// mask: default
|
||||
// gateway: 192.168.1.1
|
||||
// interface: tun0
|
||||
// flags: <UP,GATEWAY,DONE,STATIC,PRCLONING>
|
||||
// lines := strings.Split(string(output), "\n")
|
||||
// for _, line := range lines {
|
||||
// fields := strings.Fields(line)
|
||||
// if len(fields) >= 2 && fields[0] == "gateway:" {
|
||||
// ip := net.ParseIP(fields[1])
|
||||
// if ip != nil {
|
||||
// return ip, "", nil
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Darwin route out format is always like this:
|
||||
// Internet:
|
||||
// Destination Gateway Flags Refs Use Netif Expire
|
||||
// default 192.168.10.254 UGSc 194 0 en3
|
||||
// 127 127.0.0.1 UCS 0 429 lo0
|
||||
// 127.0.0.1 127.0.0.1 UH 1 587632 lo0
|
||||
// 169.254 link#7 UCS 0 0 en3
|
||||
// 192.168.10 link#7 UCS 4 0 en3
|
||||
// 192.168.10.1 0:11:32:7f:20:61 UHLWIi 1 202 en3 1065
|
||||
// 224.0.0/4 link#7 UmCS 3 0 en3
|
||||
// 224.0.0.251 1:0:5e:0:0:fb UHmLWI 0 2325 en3
|
||||
// 239.192.152.143 1:0:5e:40:98:8f UHmLWI 0 22892 en3
|
||||
// 239.255.255.250 1:0:5e:7f:ff:fa UHmLWI 0 15988 en3
|
||||
// 255.255.255.255/32 link#7 UCS 0 0 en3
|
||||
|
||||
// Internet6:
|
||||
// Destination Gateway Flags Netif Expire
|
||||
// default fe80::%utun0 UGcI utun0
|
||||
// default fe80::%utun1 UGcI utun1
|
||||
// default fe80::%utun2 UGcI utun2
|
||||
// default fe80::%utun3 UGcI utun3
|
||||
outputLines := strings.Split(string(output), "\n")
|
||||
for _, line := range outputLines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 2 && fields[0] == "default" {
|
||||
ip := net.ParseIP(fields[1])
|
||||
if ip != nil {
|
||||
return ip, fields[5], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, "", errNoGateway
|
||||
}
|
||||
|
||||
func parseBSDSolarisNetstat(output []byte) (net.IP, string, error) {
|
||||
// netstat -rn produces the following on FreeBSD:
|
||||
// Routing tables
|
||||
//
|
||||
// Internet:
|
||||
// Destination Gateway Flags Netif Expire
|
||||
// default 10.88.88.2 UGS em0
|
||||
// 10.88.88.0/24 link#1 U em0
|
||||
// 10.88.88.148 link#1 UHS lo0
|
||||
// 127.0.0.1 link#2 UH lo0
|
||||
//
|
||||
// Internet6:
|
||||
// Destination Gateway Flags Netif Expire
|
||||
// ::/96 ::1 UGRS lo0
|
||||
// ::1 link#2 UH lo0
|
||||
// ::ffff:0.0.0.0/96 ::1 UGRS lo0
|
||||
// fe80::/10 ::1 UGRS lo0
|
||||
// ...
|
||||
outputLines := strings.Split(string(output), "\n")
|
||||
for _, line := range outputLines {
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) >= 2 && fields[0] == "default" {
|
||||
ip := net.ParseIP(fields[1])
|
||||
if ip != nil {
|
||||
return ip, fields[3], nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, "", errNoGateway
|
||||
}
|
16
net/gateway/gateway_darwin.go
Normal file
16
net/gateway/gateway_darwin.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package gateway
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func DiscoverGateway() (ip net.IP, iface string, err error) {
|
||||
routeCmd := exec.Command("netstat", "-rn")
|
||||
output, err := routeCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return parseDarwinRouteGet(output)
|
||||
}
|
16
net/gateway/gateway_freebsd.go
Normal file
16
net/gateway/gateway_freebsd.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package gateway
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func DiscoverGateway() (ip net.IP, iface string, err error) {
|
||||
routeCmd := exec.Command("netstat", "-rn")
|
||||
output, err := routeCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return parseBSDSolarisNetstat(output)
|
||||
}
|
34
net/gateway/gateway_linux.go
Normal file
34
net/gateway/gateway_linux.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package gateway
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func DiscoverGateway() (ip net.IP, iface string, err error) {
|
||||
ip, iface, err = discoverGatewayUsingRoute()
|
||||
if err != nil {
|
||||
ip, iface, err = discoverGatewayUsingIp()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func discoverGatewayUsingIp() (net.IP, string, error) {
|
||||
routeCmd := exec.Command("ip", "route", "show")
|
||||
output, err := routeCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return parseLinuxIPRoute(output)
|
||||
}
|
||||
|
||||
func discoverGatewayUsingRoute() (net.IP, string, error) {
|
||||
routeCmd := exec.Command("route", "-n")
|
||||
output, err := routeCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return parseLinuxRoute(output)
|
||||
}
|
16
net/gateway/gateway_solaris.go
Normal file
16
net/gateway/gateway_solaris.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package gateway
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func DiscoverGateway() (ip net.IP, iface string, err error) {
|
||||
routeCmd := exec.Command("netstat", "-rn")
|
||||
output, err := routeCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return parseBSDSolarisNetstat(output)
|
||||
}
|
248
net/gateway/gateway_test.go
Normal file
248
net/gateway/gateway_test.go
Normal file
|
@ -0,0 +1,248 @@
|
|||
package gateway
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testcase struct {
|
||||
output []byte
|
||||
ok bool
|
||||
gateway string
|
||||
}
|
||||
|
||||
func TestParseWindowsRoutePrint(t *testing.T) {
|
||||
correctData := []byte(`
|
||||
IPv4 Route Table
|
||||
===========================================================================
|
||||
Active Routes:
|
||||
Network Destination Netmask Gateway Interface Metric
|
||||
0.0.0.0 0.0.0.0 10.88.88.2 10.88.88.149 10
|
||||
===========================================================================
|
||||
Persistent Routes:
|
||||
`)
|
||||
randomData := []byte(`
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||
sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
|
||||
`)
|
||||
noRoute := []byte(`
|
||||
IPv4 Route Table
|
||||
===========================================================================
|
||||
Active Routes:
|
||||
`)
|
||||
badRoute1 := []byte(`
|
||||
IPv4 Route Table
|
||||
===========================================================================
|
||||
Active Routes:
|
||||
===========================================================================
|
||||
Persistent Routes:
|
||||
`)
|
||||
badRoute2 := []byte(`
|
||||
IPv4 Route Table
|
||||
===========================================================================
|
||||
Active Routes:
|
||||
Network Destination Netmask Gateway Interface Metric
|
||||
0.0.0.0 0.0.0.0 foo 10.88.88.149 10
|
||||
===========================================================================
|
||||
Persistent Routes:
|
||||
`)
|
||||
|
||||
testcases := []testcase{
|
||||
{correctData, true, "10.88.88.2"},
|
||||
{randomData, false, ""},
|
||||
{noRoute, false, ""},
|
||||
{badRoute1, false, ""},
|
||||
{badRoute2, false, ""},
|
||||
}
|
||||
|
||||
test(t, testcases, parseWindowsRoutePrint)
|
||||
}
|
||||
|
||||
func TestParseLinuxIPRoutePrint(t *testing.T) {
|
||||
correctData := []byte(`
|
||||
default via 192.168.178.1 dev wlp3s0 metric 303
|
||||
192.168.178.0/24 dev wlp3s0 proto kernel scope link src 192.168.178.76 metric 303
|
||||
`)
|
||||
randomData := []byte(`
|
||||
test
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||
sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
|
||||
`)
|
||||
noRoute := []byte(`
|
||||
192.168.178.0/24 dev wlp3s0 proto kernel scope link src 192.168.178.76 metric 303
|
||||
`)
|
||||
badRoute := []byte(`
|
||||
default via foo dev wlp3s0 metric 303
|
||||
192.168.178.0/24 dev wlp3s0 proto kernel scope link src 192.168.178.76 metric 303
|
||||
`)
|
||||
|
||||
testcases := []testcase{
|
||||
{correctData, true, "192.168.178.1"},
|
||||
{randomData, false, ""},
|
||||
{noRoute, false, ""},
|
||||
{badRoute, false, ""},
|
||||
}
|
||||
|
||||
test(t, testcases, parseLinuxIPRoute)
|
||||
}
|
||||
|
||||
func TestParseLinuxRoutePrint(t *testing.T) {
|
||||
correctData := []byte(`
|
||||
Kernel IP routing table
|
||||
Destination Gateway Genmask Flags Metric Ref Use Iface
|
||||
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
|
||||
`)
|
||||
randomData := []byte(`
|
||||
test
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||
sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
|
||||
`)
|
||||
noRoute := []byte(`
|
||||
Kernel IP routing table
|
||||
Destination Gateway Genmask Flags Metric Ref Use Iface
|
||||
`)
|
||||
badRoute := []byte(`
|
||||
Kernel IP routing table
|
||||
Destination Gateway Genmask Flags Metric Ref Use Iface
|
||||
0.0.0.0 foo 0.0.0.0 UG 0 0 0 eth0
|
||||
`)
|
||||
|
||||
testcases := []testcase{
|
||||
{correctData, true, "192.168.1.1"},
|
||||
{randomData, false, ""},
|
||||
{noRoute, false, ""},
|
||||
{badRoute, false, ""},
|
||||
}
|
||||
|
||||
test(t, testcases, parseLinuxRoute)
|
||||
}
|
||||
|
||||
func TestParseDarwinRouteGet(t *testing.T) {
|
||||
correctData := []byte(`
|
||||
route to: 0.0.0.0
|
||||
destination: default
|
||||
mask: default
|
||||
gateway: 172.16.32.1
|
||||
interface: en0
|
||||
flags: <UP,GATEWAY,DONE,STATIC,PRCLONING>
|
||||
recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
|
||||
0 0 0 0 0 0 1500 0
|
||||
`)
|
||||
randomData := []byte(`
|
||||
test
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||
sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
|
||||
`)
|
||||
noRoute := []byte(`
|
||||
route to: 0.0.0.0
|
||||
destination: default
|
||||
mask: default
|
||||
`)
|
||||
badRoute := []byte(`
|
||||
route to: 0.0.0.0
|
||||
destination: default
|
||||
mask: default
|
||||
gateway: foo
|
||||
interface: en0
|
||||
flags: <UP,GATEWAY,DONE,STATIC,PRCLONING>
|
||||
recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire
|
||||
0 0 0 0 0 0 1500 0
|
||||
`)
|
||||
|
||||
testcases := []testcase{
|
||||
{correctData, true, "172.16.32.1"},
|
||||
{randomData, false, ""},
|
||||
{noRoute, false, ""},
|
||||
{badRoute, false, ""},
|
||||
}
|
||||
|
||||
test(t, testcases, parseDarwinRouteGet)
|
||||
}
|
||||
|
||||
func TestParseBSDSolarisNetstat(t *testing.T) {
|
||||
correctDataFreeBSD := []byte(`
|
||||
Routing tables
|
||||
|
||||
Internet:
|
||||
Destination Gateway Flags Netif Expire
|
||||
default 10.88.88.2 UGS em0
|
||||
10.88.88.0/24 link#1 U em0
|
||||
10.88.88.148 link#1 UHS lo0
|
||||
127.0.0.1 link#2 UH lo0
|
||||
|
||||
Internet6:
|
||||
Destination Gateway Flags Netif Expire
|
||||
::/96 ::1 UGRS lo0
|
||||
::1 link#2 UH lo0
|
||||
::ffff:0.0.0.0/96 ::1 UGRS lo0
|
||||
fe80::/10 ::1 UGRS lo0
|
||||
`)
|
||||
correctDataSolaris := []byte(`
|
||||
Routing Table: IPv4
|
||||
Destination Gateway Flags Ref Use Interface
|
||||
-------------------- -------------------- ----- ----- ---------- ---------
|
||||
default 172.16.32.1 UG 2 76419 net0
|
||||
127.0.0.1 127.0.0.1 UH 2 36 lo0
|
||||
172.16.32.0 172.16.32.17 U 4 8100 net0
|
||||
|
||||
Routing Table: IPv6
|
||||
Destination/Mask Gateway Flags Ref Use If
|
||||
--------------------------- --------------------------- ----- --- ------- -----
|
||||
::1 ::1 UH 3 75382 lo0
|
||||
2001:470:deeb:32::/64 2001:470:deeb:32::17 U 3 2744 net0
|
||||
fe80::/10 fe80::6082:52ff:fedc:7df0 U 3 8430 net0
|
||||
`)
|
||||
randomData := []byte(`
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
|
||||
sed do eiusmod tempor incididunt ut labore et dolore magna
|
||||
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
|
||||
`)
|
||||
noRoute := []byte(`
|
||||
Internet:
|
||||
Destination Gateway Flags Netif Expire
|
||||
10.88.88.0/24 link#1 U em0
|
||||
10.88.88.148 link#1 UHS lo0
|
||||
127.0.0.1 link#2 UH lo0
|
||||
`)
|
||||
badRoute := []byte(`
|
||||
Internet:
|
||||
Destination Gateway Flags Netif Expire
|
||||
default foo UGS em0
|
||||
10.88.88.0/24 link#1 U em0
|
||||
10.88.88.148 link#1 UHS lo0
|
||||
127.0.0.1 link#2 UH lo0
|
||||
`)
|
||||
|
||||
testcases := []testcase{
|
||||
{correctDataFreeBSD, true, "10.88.88.2"},
|
||||
{correctDataSolaris, true, "172.16.32.1"},
|
||||
{randomData, false, ""},
|
||||
{noRoute, false, ""},
|
||||
{badRoute, false, ""},
|
||||
}
|
||||
|
||||
test(t, testcases, parseBSDSolarisNetstat)
|
||||
}
|
||||
|
||||
func test(t *testing.T, testcases []testcase, fn func([]byte) (net.IP, string, error)) {
|
||||
for i, tc := range testcases {
|
||||
net, iface, err := fn(tc.output)
|
||||
if tc.ok {
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error in test #%d: %v", i, err)
|
||||
}
|
||||
if net.String() != tc.gateway {
|
||||
t.Errorf("Unexpected gateway address %v != %s", net, tc.gateway)
|
||||
}
|
||||
if "" == iface {
|
||||
t.Errorf("Unexpected interface")
|
||||
}
|
||||
} else if err == nil {
|
||||
t.Errorf("Unexpected nil error in test #%d", i)
|
||||
}
|
||||
}
|
||||
}
|
14
net/gateway/gateway_unimplemented.go
Normal file
14
net/gateway/gateway_unimplemented.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
// +build !darwin,!linux,!windows,!solaris,!freebsd
|
||||
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func DiscoverGateway() (ip net.IP, iface string, err error) {
|
||||
err = fmt.Errorf("DiscoverGateway not implemented for OS %s", runtime.GOOS)
|
||||
return
|
||||
}
|
16
net/gateway/gateway_windows.go
Normal file
16
net/gateway/gateway_windows.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package gateway
|
||||
|
||||
import (
|
||||
"net"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func DiscoverGateway() (ip net.IP, iface string, err error) {
|
||||
routeCmd := exec.Command("route", "print", "0.0.0.0")
|
||||
output, err := routeCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return parseWindowsRoutePrint(output)
|
||||
}
|
Loading…
Reference in New Issue
Block a user