diff --git a/netlink/netlink.go b/netlink/netlink.go new file mode 100644 index 0000000..5098b4b --- /dev/null +++ b/netlink/netlink.go @@ -0,0 +1,15 @@ +// Packet netlink provide access to low level Netlink sockets and messages. +// +// Actual implementations are in: +// netlink_linux.go +// netlink_darwin.go +package netlink + +import "net" + +// A Route is a subnet associated with the interface to reach it. +type Route struct { + *net.IPNet + Iface *net.Interface + Default bool +} diff --git a/netlink/netlink_darwin.go b/netlink/netlink_darwin.go index dcc60b6..298508a 100644 --- a/netlink/netlink_darwin.go +++ b/netlink/netlink_darwin.go @@ -5,7 +5,7 @@ import ( "net" ) -func NetworkGetRoutes() ([]*net.IPNet, error) { +func NetworkGetRoutes() ([]Route, error) { return nil, fmt.Errorf("Not implemented") } diff --git a/netlink/netlink_linux.go b/netlink/netlink_linux.go index 9a937d1..ab572e3 100644 --- a/netlink/netlink_linux.go +++ b/netlink/netlink_linux.go @@ -473,7 +473,7 @@ func NetworkLinkAdd(name string, linkType string) error { // Returns an array of IPNet for all the currently routed subnets on ipv4 // This is similar to the first column of "ip route" output -func NetworkGetRoutes() ([]*net.IPNet, error) { +func NetworkGetRoutes() ([]Route, error) { native := nativeEndian() s, err := getNetlinkSocket() @@ -496,7 +496,7 @@ func NetworkGetRoutes() ([]*net.IPNet, error) { return nil, err } - res := make([]*net.IPNet, 0) + res := make([]Route, 0) done: for { @@ -525,8 +525,7 @@ done: continue } - var iface *net.Interface = nil - var ipNet *net.IPNet = nil + var r Route msg := (*RtMsg)(unsafe.Pointer(&m.Data[0:syscall.SizeofRtMsg][0])) @@ -546,8 +545,8 @@ done: } if msg.Dst_len == 0 { - // Ignore default routes - continue + // Default routes + r.Default = true } attrs, err := syscall.ParseNetlinkRouteAttr(&m) @@ -558,18 +557,17 @@ done: switch attr.Attr.Type { case syscall.RTA_DST: ip := attr.Value - ipNet = &net.IPNet{ + r.IPNet = &net.IPNet{ IP: ip, Mask: net.CIDRMask(int(msg.Dst_len), 8*len(ip)), } case syscall.RTA_OIF: index := int(native.Uint32(attr.Value[0:4])) - iface, _ = net.InterfaceByIndex(index) - _ = iface + r.Iface, _ = net.InterfaceByIndex(index) } } - if ipNet != nil { - res = append(res, ipNet) + if r.Default || r.IPNet != nil { + res = append(res, r) } } }