diff --git a/rtnl/route.go b/rtnl/route.go index 24565af..c15f919 100644 --- a/rtnl/route.go +++ b/rtnl/route.go @@ -1,6 +1,7 @@ package rtnl import ( + "errors" "net" "github.com/jsimonetti/rtnetlink/internal/unix" @@ -8,6 +9,12 @@ import ( "github.com/jsimonetti/rtnetlink" ) +// Route represents a route table entry +type Route struct { + Gateway net.IP + Interface *net.Interface +} + // generating route message func genRouteMessage(ifc *net.Interface, dst net.IPNet, gw net.IP, options ...RouteOption) (rm *rtnetlink.RouteMessage, err error) { @@ -93,3 +100,35 @@ func (c *Conn) RouteDel(ifc *net.Interface, dst net.IPNet) error { } return c.Conn.Route.Delete(tx) } + +// RouteGet gets a single route to the given destination address. +func (c *Conn) RouteGet(dst net.IP) (*Route, error) { + af, err := addrFamily(dst) + if err != nil { + return nil, err + } + attr := rtnetlink.RouteAttributes{ + Dst: dst, + } + tx := &rtnetlink.RouteMessage{ + Family: uint8(af), + Table: unix.RT_TABLE_MAIN, + Attributes: attr, + } + rx, err := c.Conn.Route.Get(tx) + if err != nil { + return nil, err + } + if len(rx) == 0 { + return nil, errors.New("route wrong length") + } + ifindex := int(rx[0].Attributes.OutIface) + iface, err := c.LinkByIndex(ifindex) + if err != nil { + return nil, err + } + return &Route{ + Gateway: rx[0].Attributes.Gateway, + Interface: iface, + }, nil +}