github.com/Cloud-Foundations/Dominator@v0.3.4/lib/net/util/getDefaultRoute.go (about)

     1  package util
     2  
     3  import (
     4  	"bufio"
     5  	"errors"
     6  	"fmt"
     7  	"net"
     8  	"os"
     9  )
    10  
    11  const procNetRoute = "/proc/net/route"
    12  
    13  func getDefaultRoute() (*DefaultRouteInfo, error) {
    14  	if routeTable, err := GetRouteTable(); err != nil {
    15  		return nil, err
    16  	} else if routeTable.DefaultRoute == nil {
    17  		return nil, errors.New("could not find default route")
    18  	} else {
    19  		return routeTable.DefaultRoute, nil
    20  	}
    21  }
    22  
    23  func getRouteTable() (*RouteTable, error) {
    24  	file, err := os.Open(procNetRoute)
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	defer file.Close()
    29  	scanner := bufio.NewScanner(file)
    30  	var allRoutes, routes []*RouteEntry
    31  	var defaultRouteAddr net.IP
    32  	var defaultRouteInterface string
    33  	for scanner.Scan() {
    34  		var interfaceName string
    35  		var destAddr, gatewayAddr, flags, mask uint32
    36  		var ign int
    37  		nCopied, err := fmt.Sscanf(scanner.Text(),
    38  			"%s %x %x %x %d %d %d %x %d %d %d",
    39  			&interfaceName, &destAddr, &gatewayAddr, &flags, &ign, &ign, &ign,
    40  			&mask, &ign, &ign, &ign)
    41  		if err != nil || nCopied < 11 {
    42  			continue
    43  		}
    44  		routeEntry := &RouteEntry{
    45  			BaseAddr:      intToIP(destAddr),
    46  			BroadcastAddr: intToIP(destAddr | (0xffffffff ^ mask)),
    47  			Flags:         flags,
    48  			InterfaceName: interfaceName,
    49  			Mask:          net.IPMask(intToIP(mask)),
    50  		}
    51  		if flags&RouteFlagGateway != 0 {
    52  			routeEntry.GatewayAddr = intToIP(gatewayAddr)
    53  		}
    54  		allRoutes = append(allRoutes, routeEntry)
    55  		if destAddr == 0 &&
    56  			flags&RouteFlagGateway != 0 &&
    57  			flags&RouteFlagUp != 0 {
    58  			defaultRouteAddr = intToIP(gatewayAddr)
    59  			defaultRouteInterface = interfaceName
    60  			continue
    61  		}
    62  		if destAddr != 0 && flags == RouteFlagUp && gatewayAddr == 0 {
    63  			routes = append(routes, routeEntry)
    64  		}
    65  	}
    66  	if err := scanner.Err(); err != nil {
    67  		return nil, err
    68  	}
    69  	if len(defaultRouteAddr) == 0 {
    70  		return &RouteTable{RouteEntries: allRoutes}, nil
    71  	}
    72  	defaultRoute := &DefaultRouteInfo{
    73  		Address:   defaultRouteAddr,
    74  		Interface: defaultRouteInterface,
    75  	}
    76  	for _, route := range routes {
    77  		if route.InterfaceName == defaultRouteInterface &&
    78  			defaultRouteAddr.Mask(route.Mask).Equal(route.BaseAddr) {
    79  			defaultRoute.Mask = route.Mask
    80  			break
    81  		}
    82  	}
    83  	return &RouteTable{DefaultRoute: defaultRoute, RouteEntries: allRoutes}, nil
    84  }
    85  
    86  func intToIP(ip uint32) net.IP {
    87  	result := make(net.IP, 4)
    88  	for i := range result {
    89  		result[i] = byte(ip >> uint(8*i))
    90  	}
    91  	return result
    92  }