sane output on linux/windows/mac

parent 577162e3
......@@ -130,20 +130,27 @@ func (r *router) route(routes routeSlice, input net.HardwareAddr, src, dst net.I
}
}
}
var mostSpecificRt *rtInfo
for _, rt := range routes {
if rt.InputIface != 0 && rt.InputIface != inputIndex {
continue
}
if src != nil && rt.Src != nil && !rt.Src.Contains(src) {
fmt.Printf("ignoring %v b/c src %v\n", rt, src)
continue
}
if rt.Dst != nil && !rt.Dst.Contains(dst) {
fmt.Printf("ignoring %v b/c dst\n", rt)
continue
}
fmt.Printf("Using route: %v\n", rt)
return int(rt.OutputIface), rt.Gateway, rt.PrefSrc, nil
if mostSpecificRt != nil {
candSpec, _ := rt.Dst.Mask.Size()
if curSpec, _ := mostSpecificRt.Dst.Mask.Size(); candSpec < curSpec {
continue
}
}
mostSpecificRt = rt
}
if mostSpecificRt != nil {
return int(mostSpecificRt.OutputIface), mostSpecificRt.Gateway, mostSpecificRt.PrefSrc, nil
}
err = fmt.Errorf("no route found for %v", dst)
return
......
......@@ -7,9 +7,31 @@ import (
func TestRoute(t *testing.T) {
r, _ := New()
_, gw, src, err := r.Route(net.IPv4(127, 0, 0, 1))
// Route to 127.0.0.1 shouldn't have a gateway
_, gw, _, err := r.Route(net.IPv4(127, 0, 0, 1))
if err != nil {
t.Fatal(err)
}
if gw != nil {
t.Fatalf("Did not expect gateway to localhost: %v", gw)
}
// Route to somewher external should.
_, gw, _, err = r.Route(net.IPv4(8, 8, 8, 8))
if err != nil {
t.Fatal(err)
}
t.Logf("Default route is via %v from %v", gw, src)
if gw == nil {
t.Fatalf("Did not expect direct link to 8.8.8.8. Are you Google?")
}
// Route to v4 and v6 should differ.
_, v6gw, _, err := r.Route(net.ParseIP("2607:f8b0:400a:809::200e")) // at one point google.
if err != nil {
t.Fatal(err)
}
if v6gw.Equal(gw) {
t.Fatalf("did not expect a v4 gw for a v6 route.")
}
}
......@@ -20,8 +20,7 @@ import (
)
var (
modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll")
modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll")
procGetBestRoute2 = modiphlpapi.NewProc("GetBestRoute2")
)
......@@ -127,23 +126,27 @@ func parseRoute(mib []byte) (*mib_row2, error) {
}
func readDestPrefix(buffer []byte, idx int) (*AddressPrefix, int, error) {
sock, idx, err := readSockAddr(buffer, idx)
sock, idx2, err := readSockAddr(buffer, idx)
if err != nil {
return nil, 0, err
}
pfixLen := buffer[idx]
return &AddressPrefix{sock, pfixLen}, idx + 1, nil
pfixLen := buffer[idx2]
if idx2-idx > 32 {
return nil, idx, fmt.Errorf("Unexpectedly large internal sockaddr struct")
}
return &AddressPrefix{sock, pfixLen}, idx + 32, nil
}
func readSockAddr(buffer []byte, idx int) (*windows.RawSockaddrAny, int, error) {
var rsa windows.RawSockaddrAny
rsa.Addr.Family = binary.LittleEndian.Uint16(buffer[idx : idx+2])
if rsa.Addr.Family == 2 /* AF_INET */ || rsa.Addr.Family == 0 /* AF_UNDEF */ {
if rsa.Addr.Family == windows.AF_INET || rsa.Addr.Family == windows.AF_UNSPEC {
copyInto(rsa.Addr.Data[:], buffer[idx+2:idx+16])
return &rsa, idx + 16, nil
} else if rsa.Addr.Family == 23 /* AF_INET6 */ {
//TODO: 24 bytes?
panic("no v6 len")
} else if rsa.Addr.Family == windows.AF_INET6 {
copyInto(rsa.Addr.Data[:], buffer[idx+2:idx+16])
copyInto(rsa.Pad[:], buffer[idx+16:idx+28])
return &rsa, idx + 28, nil
} else {
return nil, 0, fmt.Errorf("Unknown windows addr family %d", rsa.Addr.Family)
}
......@@ -177,7 +180,6 @@ func (r *winRouter) RouteWithSrc(input net.HardwareAddr, src, dst net.IP) (iface
return nil, nil, nil, err
}
if route.nextHop.Addr.Family == 0 /* AF_UNDEF */ {
route.nextHop.Addr.Family = 2
return nil, nil, pref, nil
}
addr, err := route.nextHop.Sockaddr()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment