Home | History | Annotate | Download | only in test-scripts
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2009 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 """Return information about routing table entries
     19 
     20 Read and parse the system routing table. There are
     21 two classes defined here: NetworkRoutes, which contains
     22 information about all routes, and Route, which describes
     23 a single routing table entry.
     24 """
     25 
     26 ROUTES_FILE = "/proc/net/route"
     27 # The following constants are from <net/route.h>
     28 RTF_UP      = 0x0001
     29 RTF_GATEWAY = 0x0002
     30 RTF_HOST    = 0x0004
     31 
     32 import socket
     33 import struct
     34 
     35 def intToDottedQuad(addr):
     36     return socket.inet_ntoa(struct.pack('@I', addr))
     37 
     38 def convertIpToInt(i):
     39     """Convert the supplied argument to an int representing an IP address."""
     40     if isinstance(i, int):
     41         return i
     42     return struct.unpack('I', socket.inet_aton(i))[0]
     43 
     44 class Route(object):
     45     def __init__(self, iface, dest, gway, flags, mask):
     46         self.interface = iface
     47         self.destination = int(dest, 16)
     48         self.gateway = int(gway, 16)
     49         self.flagbits = int(flags, 16)
     50         self.netmask = int(mask, 16)
     51 
     52     def __str__(self):
     53         flags = ""
     54         if self.flagbits & RTF_UP:
     55             flags += "U"
     56         if self.flagbits & RTF_GATEWAY:
     57             flags += "G"
     58         if self.flagbits & RTF_HOST:
     59             flags += "H"
     60         return "<%s dest: %s gway: %s mask: %s flags: %s>" % (
     61                 self.interface,
     62                 intToDottedQuad(self.destination),
     63                 intToDottedQuad(self.gateway),
     64                 intToDottedQuad(self.netmask),
     65                 flags)
     66 
     67     def isUsable(self):
     68         return self.flagbits & RTF_UP
     69 
     70     def isHostRoute(self):
     71         return self.flagbits & RTF_HOST
     72 
     73     def isGatewayRoute(self):
     74         return self.flagbits & RTF_GATEWAY
     75 
     76     def isInterfaceRoute(self):
     77         return (self.flagbits & RTF_GATEWAY) == 0
     78 
     79     def isDefaultRoute(self):
     80         return (self.flagbits & RTF_GATEWAY) and self.destination == 0
     81 
     82     def matches(self, ip):
     83         return (ip & self.netmask) == self.destination
     84 
     85 class NetworkRoutes(object):
     86     def __init__(self, routelist=None):
     87         if not routelist:
     88             routef = open(ROUTES_FILE)
     89             routelist = routef.readlines()
     90             routef.close()
     91 
     92         # The first line is headers that will allow us
     93         # to correctly interpret the values in the following
     94         # lines
     95         colMap = {}
     96         headers = routelist[0].split()
     97         for (pos, token) in enumerate(headers):
     98             colMap[token] = pos
     99 
    100         self.routes = []
    101         for routeline in routelist[1:]:
    102             route = routeline.split()
    103             interface = route[colMap["Iface"]]
    104             destination = route[colMap["Destination"]]
    105             gateway = route[colMap["Gateway"]]
    106             flags = route[colMap["Flags"]]
    107             mask = route[colMap["Mask"]]
    108             self.routes.append(
    109                     Route(interface, destination, gateway, flags, mask))
    110 
    111     def hasDefaultRoute(self, interface):
    112         for rr in self.routes:
    113             if (rr.isUsable() and
    114                     rr.interface == interface and
    115                     rr.isDefaultRoute()):
    116                 return True
    117         return False
    118 
    119     def getDefaultRoutes(self):
    120         defroutes = []
    121         for rr in self.routes:
    122             if rr.isUsable() and rr.isDefaultRoute():
    123                 defroutes.append(rr)
    124         return defroutes
    125 
    126     def hasInterfaceRoute(self, interface):
    127         for rr in self.routes:
    128             if (rr.isUsable() and
    129                     rr.interface == interface and
    130                     rr.isInterfaceRoute()):
    131                 return True
    132             return False
    133 
    134     def getRouteFor(self, ip_as_int_or_string):
    135         ip = convertIpToInt(ip_as_int_or_string)
    136         for rr in self.routes:
    137             if rr.isUsable() and rr.matches(ip):
    138                 return rr
    139         return None
    140 
    141 
    142 if __name__ == "__main__":
    143     routes = NetworkRoutes()
    144     if routes == None:
    145         print "Failed to read routing table"
    146     else:
    147         for each_route in routes.routes:
    148             print each_route
    149 
    150         print "hasDefaultRoute(\"eth0\"):", routes.hasDefaultRoute("eth0")
    151 
    152         dflts = routes.getDefaultRoutes()
    153         if dflts == None:
    154             print "There are no default routes"
    155         else:
    156             print "There are %d default routes" % (len(dflts))
    157 
    158 
    159         print "hasInterfaceRoute(\"eth0\"):", routes.hasInterfaceRoute("eth0")
    160 
    161     routes = NetworkRoutes([
    162         "Iface Destination Gateway  Flags RefCnt "
    163         "Use Metric Mask MTU Window IRTT",
    164         "ones 00010203 FE010203 0007 0 0 0 00FFFFFF 0 0 0\n",
    165         "default 00000000 09080706 0007 0 0 0 00000000 0 0 0\n",
    166         ])
    167 
    168     print routes.getRouteFor(0x01010203)
    169     print routes.getRouteFor("3.2.1.1")
    170     print routes.getRouteFor(0x08010209)
    171