blob: 78ea0b854d3f4f1700d7ba06f793c81d7c596389 [file] [log] [blame]
Paul Stewart98d75b62011-04-01 15:04:27 -07001# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import re, socket, subprocess
6from autotest_lib.client.common_lib import error
7
8class HostRoute(object):
9 """
10 Host Route: A utility for retrieving information about our route to a host
11
12 """
13
14 def __init__(self, host):
15 self.host = host # Remote host
16 self.calculate()
17
18 def calculate(self):
19 output = self.run_command(["ip", "route", "get", self.host])
20 # This converts "172.22.18.53 via 10.0.0.1 dev eth0 src 10.0.0.200 \n.."
21 # into ("via", "10.0.0.1", "dev", "eth0", "src", "10.0.0.200")
22 route_info = re.split("\s*", output.split("\n")[0].rstrip(' '))[1:]
23
24 # Further, convert the list into a dict {"via": "10.0.0.1", ...}
25 self.route_info = dict(tuple(route_info[i:i+2])
26 for i in range(0, len(route_info), 2))
27
28 if 'src' not in self.route_info:
29 raise error.TestFail('Cannot find route to host %s' % self.host)
30
31class LocalHostRoute(HostRoute):
32 """
33 Self Host Route: Retrieve host route for the test-host machine
34
35 """
36 def __init__(self, host):
37 # TODO(pstew): If we could depend on the host having the "ip" command
38 # we would just be able to do this:
39 #
40 # HostRoute.__init__(self, host)
41 #
42 # but alas, we can't depend on this, so we fake it by creating a
43 # socket and figuring out what local address we bound to if we
44 # connected to the client
45 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
46 sock.connect((host, 22)) # NB: Port doesn't matter
47 self.route_info = { 'src': sock.getsockname()[0] }
48
49 def run_command(self, args):
50 return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
51
52class RemoteHostRoute(HostRoute):
53 """
54 Remote Host Route: Retrieve host route for a remote (DUT, server) machine
55
56 """
57 def __init__(self, remote, host):
58 self.remote = remote
59 HostRoute.__init__(self, host)
60
61 def run_command(self, args):
62 return self.remote.run(' '.join(args)).stdout