aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gopacket/routing/routing.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/google/gopacket/routing/routing.go')
-rw-r--r--vendor/github.com/google/gopacket/routing/routing.go241
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
-}