routing.py revision 2f48d9572459c2c90d68e8b017b86eb843fe2a74
1#!/usr/bin/env python 2# Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Return information about routing table entries 7 8Read and parse the system routing table. There are 9two classes defined here: NetworkRoutes, which contains 10information about all routes, and Route, which describes 11a single routing table entry. 12""" 13 14ROUTES_FILE = "/proc/net/route" 15# The following constants are from <net/route.h> 16RTF_UP = 0x0001 17RTF_GATEWAY = 0x0002 18RTF_HOST = 0x0004 19 20import socket 21import struct 22 23def intToDottedQuad(addr): 24 return socket.inet_ntoa(struct.pack('@I', addr)) 25 26def convertIpToInt(i): 27 """Convert the supplied argument to an int representing an IP address.""" 28 if isinstance(i, int): 29 return i 30 return struct.unpack('I', socket.inet_aton(i))[0] 31 32class Route(object): 33 def __init__(self, iface, dest, gway, flags, mask): 34 self.interface = iface 35 self.destination = int(dest, 16) 36 self.gateway = int(gway, 16) 37 self.flagbits = int(flags, 16) 38 self.netmask = int(mask, 16) 39 40 def __str__(self): 41 flags = "" 42 if self.flagbits & RTF_UP: 43 flags += "U" 44 if self.flagbits & RTF_GATEWAY: 45 flags += "G" 46 if self.flagbits & RTF_HOST: 47 flags += "H" 48 return "<%s dest: %s gway: %s mask: %s flags: %s>" % ( 49 self.interface, 50 intToDottedQuad(self.destination), 51 intToDottedQuad(self.gateway), 52 intToDottedQuad(self.netmask), 53 flags) 54 55 def isUsable(self): 56 return self.flagbits & RTF_UP 57 58 def isHostRoute(self): 59 return self.flagbits & RTF_HOST 60 61 def isGatewayRoute(self): 62 return self.flagbits & RTF_GATEWAY 63 64 def isInterfaceRoute(self): 65 return (self.flagbits & RTF_GATEWAY) == 0 66 67 def isDefaultRoute(self): 68 return (self.flagbits & RTF_GATEWAY) and self.destination == 0 69 70 def matches(self, ip): 71 return (ip & self.netmask) == self.destination 72 73class NetworkRoutes(object): 74 def __init__(self, routelist=None): 75 if not routelist: 76 routef = open(ROUTES_FILE) 77 routelist = routef.readlines() 78 routef.close() 79 80 # The first line is headers that will allow us 81 # to correctly interpret the values in the following 82 # lines 83 colMap = {} 84 headers = routelist[0].split() 85 for (pos, token) in enumerate(headers): 86 colMap[token] = pos 87 88 self.routes = [] 89 for routeline in routelist[1:]: 90 route = routeline.split() 91 interface = route[colMap["Iface"]] 92 destination = route[colMap["Destination"]] 93 gateway = route[colMap["Gateway"]] 94 flags = route[colMap["Flags"]] 95 mask = route[colMap["Mask"]] 96 self.routes.append( 97 Route(interface, destination, gateway, flags, mask)) 98 99 def hasDefaultRoute(self, interface): 100 for rr in self.routes: 101 if (rr.isUsable() and 102 rr.interface == interface and 103 rr.isDefaultRoute()): 104 return True 105 return False 106 107 def getDefaultRoutes(self): 108 defroutes = [] 109 for rr in self.routes: 110 if rr.isUsable() and rr.isDefaultRoute(): 111 defroutes.append(rr) 112 return defroutes 113 114 def hasInterfaceRoute(self, interface): 115 for rr in self.routes: 116 if (rr.isUsable() and 117 rr.interface == interface and 118 rr.isInterfaceRoute()): 119 return True 120 return False 121 122 def getRouteFor(self, ip_as_int_or_string): 123 ip = convertIpToInt(ip_as_int_or_string) 124 for rr in self.routes: 125 if rr.isUsable() and rr.matches(ip): 126 return rr 127 return None 128 129 130if __name__ == "__main__": 131 routes = NetworkRoutes() 132 if routes == None: 133 print "Failed to read routing table" 134 else: 135 for each_route in routes.routes: 136 print each_route 137 138 print "hasDefaultRoute(\"eth0\"):", routes.hasDefaultRoute("eth0") 139 140 dflts = routes.getDefaultRoutes() 141 if dflts == None: 142 print "There are no default routes" 143 else: 144 print "There are %d default routes" % (len(dflts)) 145 146 147 print "hasInterfaceRoute(\"eth0\"):", routes.hasInterfaceRoute("eth0") 148 149 routes = NetworkRoutes([ 150 "Iface Destination Gateway Flags RefCnt " 151 "Use Metric Mask MTU Window IRTT", 152 "ones 00010203 FE010203 0007 0 0 0 00FFFFFF 0 0 0\n", 153 "default 00000000 09080706 0007 0 0 0 00000000 0 0 0\n", 154 ]) 155 156 print routes.getRouteFor(0x01010203) 157 print routes.getRouteFor("3.2.1.1") 158 print routes.getRouteFor(0x08010209) 159