diff options
Diffstat (limited to 'vendor/github.com/google/gopacket/routing/routing.go')
-rw-r--r-- | vendor/github.com/google/gopacket/routing/routing.go | 241 |
1 files changed, 0 insertions, 241 deletions
diff --git a/vendor/github.com/google/gopacket/routing/routing.go b/vendor/github.com/google/gopacket/routing/routing.go deleted file mode 100644 index cbbeb6e..0000000 --- a/vendor/github.com/google/gopacket/routing/routing.go +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2012 Google, Inc. All rights reserved. -// -// Use of this source code is governed by a BSD-style license -// that can be found in the LICENSE file in the root of the source -// tree. - -// +build linux - -// Package routing provides a very basic but mostly functional implementation of -// a routing table for IPv4/IPv6 addresses. It uses a routing table pulled from -// the kernel via netlink to find the correct interface, gateway, and preferred -// source IP address for packets destined to a particular location. -// -// The routing package is meant to be used with applications that are sending -// raw packet data, which don't have the benefit of having the kernel route -// packets for them. -package routing - -import ( - "bytes" - "errors" - "fmt" - "net" - "sort" - "strings" - "syscall" - "unsafe" -) - -// Pulled from http://man7.org/linux/man-pages/man7/rtnetlink.7.html -// See the section on RTM_NEWROUTE, specifically 'struct rtmsg'. -type routeInfoInMemory struct { - Family byte - DstLen byte - SrcLen byte - TOS byte - - Table byte - Protocol byte - Scope byte - Type byte - - Flags uint32 -} - -// rtInfo contains information on a single route. -type rtInfo struct { - Src, Dst *net.IPNet - Gateway, PrefSrc net.IP - // We currently ignore the InputIface. - InputIface, OutputIface uint32 - Priority uint32 -} - -// routeSlice implements sort.Interface to sort routes by Priority. -type routeSlice []*rtInfo - -func (r routeSlice) Len() int { - return len(r) -} -func (r routeSlice) Less(i, j int) bool { - return r[i].Priority < r[j].Priority -} -func (r routeSlice) Swap(i, j int) { - r[i], r[j] = r[j], r[i] -} - -type router struct { - ifaces []net.Interface - addrs []ipAddrs - v4, v6 routeSlice -} - -func (r *router) String() string { - strs := []string{"ROUTER", "--- V4 ---"} - for _, route := range r.v4 { - strs = append(strs, fmt.Sprintf("%+v", *route)) - } - strs = append(strs, "--- V6 ---") - for _, route := range r.v6 { - strs = append(strs, fmt.Sprintf("%+v", *route)) - } - return strings.Join(strs, "\n") -} - -type ipAddrs struct { - v4, v6 net.IP -} - -func (r *router) Route(dst net.IP) (iface *net.Interface, gateway, preferredSrc net.IP, err error) { - return r.RouteWithSrc(nil, nil, dst) -} - -func (r *router) RouteWithSrc(input net.HardwareAddr, src, dst net.IP) (iface *net.Interface, gateway, preferredSrc net.IP, err error) { - var ifaceIndex int - switch { - case dst.To4() != nil: - ifaceIndex, gateway, preferredSrc, err = r.route(r.v4, input, src, dst) - case dst.To16() != nil: - ifaceIndex, gateway, preferredSrc, err = r.route(r.v6, input, src, dst) - default: - err = errors.New("IP is not valid as IPv4 or IPv6") - return - } - - // Interfaces are 1-indexed, but we store them in a 0-indexed array. - ifaceIndex-- - - iface = &r.ifaces[ifaceIndex] - if preferredSrc == nil { - switch { - case dst.To4() != nil: - preferredSrc = r.addrs[ifaceIndex].v4 - case dst.To16() != nil: - preferredSrc = r.addrs[ifaceIndex].v6 - } - } - return -} - -func (r *router) route(routes routeSlice, input net.HardwareAddr, src, dst net.IP) (iface int, gateway, preferredSrc net.IP, err error) { - var inputIndex uint32 - if input != nil { - for i, iface := range r.ifaces { - if bytes.Equal(input, iface.HardwareAddr) { - // Convert from zero- to one-indexed. - inputIndex = uint32(i + 1) - break - } - } - } - for _, rt := range routes { - if rt.InputIface != 0 && rt.InputIface != inputIndex { - continue - } - if rt.Src != nil && !rt.Src.Contains(src) { - continue - } - if rt.Dst != nil && !rt.Dst.Contains(dst) { - continue - } - return int(rt.OutputIface), rt.Gateway, rt.PrefSrc, nil - } - err = fmt.Errorf("no route found for %v", dst) - return -} - -// New creates a new router object. The router returned by New currently does -// not update its routes after construction... care should be taken for -// long-running programs to call New() regularly to take into account any -// changes to the routing table which have occurred since the last New() call. -func New() (Router, error) { - rtr := &router{} - tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_UNSPEC) - if err != nil { - return nil, err - } - msgs, err := syscall.ParseNetlinkMessage(tab) - if err != nil { - return nil, err - } -loop: - for _, m := range msgs { - switch m.Header.Type { - case syscall.NLMSG_DONE: - break loop - case syscall.RTM_NEWROUTE: - rt := (*routeInfoInMemory)(unsafe.Pointer(&m.Data[0])) - routeInfo := rtInfo{} - attrs, err := syscall.ParseNetlinkRouteAttr(&m) - if err != nil { - return nil, err - } - switch rt.Family { - case syscall.AF_INET: - rtr.v4 = append(rtr.v4, &routeInfo) - case syscall.AF_INET6: - rtr.v6 = append(rtr.v6, &routeInfo) - default: - continue loop - } - for _, attr := range attrs { - switch attr.Attr.Type { - case syscall.RTA_DST: - routeInfo.Dst = &net.IPNet{ - IP: net.IP(attr.Value), - Mask: net.CIDRMask(int(rt.DstLen), len(attr.Value)*8), - } - case syscall.RTA_SRC: - routeInfo.Src = &net.IPNet{ - IP: net.IP(attr.Value), - Mask: net.CIDRMask(int(rt.SrcLen), len(attr.Value)*8), - } - case syscall.RTA_GATEWAY: - routeInfo.Gateway = net.IP(attr.Value) - case syscall.RTA_PREFSRC: - routeInfo.PrefSrc = net.IP(attr.Value) - case syscall.RTA_IIF: - routeInfo.InputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_OIF: - routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PRIORITY: - routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - } - } - } - } - sort.Sort(rtr.v4) - sort.Sort(rtr.v6) - ifaces, err := net.Interfaces() - if err != nil { - return nil, err - } - for i, iface := range ifaces { - if i != iface.Index-1 { - return nil, fmt.Errorf("out of order iface %d = %v", i, iface) - } - rtr.ifaces = append(rtr.ifaces, iface) - var addrs ipAddrs - ifaceAddrs, err := iface.Addrs() - if err != nil { - return nil, err - } - for _, addr := range ifaceAddrs { - if inet, ok := addr.(*net.IPNet); ok { - // Go has a nasty habit of giving you IPv4s as ::ffff:1.2.3.4 instead of 1.2.3.4. - // We want to use mapped v4 addresses as v4 preferred addresses, never as v6 - // preferred addresses. - if v4 := inet.IP.To4(); v4 != nil { - if addrs.v4 == nil { - addrs.v4 = v4 - } - } else if addrs.v6 == nil { - addrs.v6 = inet.IP - } - } - } - rtr.addrs = append(rtr.addrs, addrs) - } - return rtr, nil -} |