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 }