root / code / trunk / backend / emulab.py

Revision 351, 4.5 kB (checked in by bwilson, 6 months ago)

all attack markings made the same, fix events for federation

Line 
1# Copyright (C) 2007 SPARTA, Inc.
2# This software is licensed under the GPLv3 license, included in
3# ./GPLv3-LICENSE.txt in the source distribution
4
5from seer import CIDR
6from seerplatform import execAndRead, pipeIn
7import re
8import sys
9import socket
10import logging
11
12class MyState(object):
13
14        def __init__(self):
15                self.LoadEID()
16                self.LoadControlInfo()
17                self.LoadIfConfig()
18                self.LoadTopoFile()
19
20
21        def LoadEID(self):
22                """ Load the nickname file to get the node, experiment and project names """
23                try:
24                        file = open('/var/emulab/boot/swapper', 'r')
25                        self.swapper = file.readline().strip()
26                        file.close()
27
28                        file = open('/var/emulab/boot/nickname', 'r')
29                        line = file.readline()
30                        file.close()
31
32                        (self.node, self.exp, self.proj) = line.strip().split('.')
33                        self.eid = self.proj+"/"+self.exp
34                        self.controlip = socket.gethostbyname(line.strip())
35                except IOError, e:
36                        logging.error("Can't load node info from /var/emulab/boot/nickname: %s" % (e))
37
38
39        def LoadControlInfo(self):
40                """ Load the control IP address and IF name files """
41                myif = open('/var/emulab/boot/controlif', 'r')
42                self.controlif = myif.readline().strip()
43                myif.close()
44
45
46        def LoadIfConfig(self):
47                """ Load all of the interface info from emulab/boot/tmcc/ifconfig """
48                self.iplist = {}
49                self.iflist = {}
50                name = inet = mask = mac = ''
51
52                iffile = pipeIn('/usr/local/etc/emulab/tmcc ifconfig')
53
54                # Split into lines
55                for line in iffile.readlines():
56                        # Split into tokens
57                        for piece in line.split():
58                                # It is now key=val
59                                keyval = piece.split('=')
60                                if keyval[0] == 'INET':
61                                        inet = keyval[1]
62                                elif keyval[0] == 'MASK':
63                                        mask = keyval[1]
64                                elif keyval[0] == 'MAC':
65                                        mac = keyval[1]
66
67                        if (sys.platform == 'cygwin'):
68                                name = execAndRead("/usr/seer/bin/ip2pcapif %s" % (inet)).strip()
69                        else:
70                                name = execAndRead("/usr/local/etc/emulab/findif %s" % (mac)).strip()
71
72                        self.iplist[inet] = (name, mac, mask)
73                        self.iflist[name] = (inet, mac, mask)
74
75                iffile.close()
76
77        def GetIPList(self):
78                """ Return the list of experimental IP addresses for this node """
79                return self.iplist.keys()
80
81        def GetIFList(self):
82                """ Return the list of experimental interfaces for this node """
83                return self.iflist.keys()
84
85        def GetIfInfo(self, ip):
86                """ Return the interface info for a given IP address """
87                return self.iplist.get(ip)
88
89
90        def LoadTopoFile(self):
91                """
92                # nodes: vname,links
93                control,link5:10.1.1.3
94                node1,link5:10.1.1.2
95                # lans: vname,mask,cost
96                link5,255.255.255.0,1
97                """
98                readtype = 0
99                ips = {}
100                nodes = {}
101                interfaces = {}
102                lanbases = {}
103                lans = {}
104
105                topomap = open('/var/emulab/boot/topomap', 'r');
106                for line in topomap.readlines():
107                        if line.startswith('# nodes'):
108                                readtype = 1
109                                continue
110                        if line.startswith('# lans'):
111                                readtype = 2
112                                continue
113
114                        if (readtype == 1):
115                                details = re.split('[, \n]+', line.strip())
116                                node = details.pop(0)
117                                nodes[node] = {}
118                                for link in details:
119                                        if ':' not in link: continue
120                                        (linkname, linkip) = link.split(':')
121                                        nodes[node][linkname] = linkip
122                                        ips[linkip] = node
123                                        if linkname not in interfaces: # Is there a nicer way to do this, like automagically
124                                                interfaces[linkname] = {}
125                                        interfaces[linkname][node] = linkip
126                                        lanbases[linkname] = linkip # overwrites
127
128                        elif (readtype == 2):
129                                (linkname, netmask, cost) = line.split(',')     
130                                lans[linkname] = CIDR(basestr=lanbases[linkname], maskstr=netmask)
131
132                topomap.close()
133               
134                ## Sanity check the assigned IP addresses and their subnetmasks
135                for l in interfaces:
136                        for node in interfaces[l]:
137                                # Check to see if all the IPs in this subnet fit given the subnetmask
138                                c = CIDR(basestr=interfaces[l][node], maskstr=lans[l].maskstr)
139                                if (c.basestr != lans[l].basestr):
140                                        logging.error("Some of the defined subnets are not valid (%s)." % (l))
141                                        logging.error("\t%s\n\t%s\n" % (interfaces[l], lans[l]))
142
143                self.topoips = ips  # ips[ip] = node
144                self.nodes = nodes      # nodes[node][linklan] = IP
145                self.interfaces = interfaces # interfaces[linklan][node] = IP
146                self.lans = lans # lans[linklan] = CIDR for subnet
147               
148
149        def GetNodeForIP(self, ip):
150                """ Lookup the node that is linked to this IP address """
151                return self.topoips.get(ip)
152
153        def GetControlNameForIP(self, ip):
154                """ Return control plane hostname """
155                return ".".join([self.topoips.get(ip), self.exp, self.proj])
156
157        def GetIPForNode(self, node):
158                """ To make sure everyone gets the same IP, we revert to DNS lookups """
159                try:
160                        return socket.gethostbyname(node)
161                except Exception, e:
162                        return None
163
164
165# Small test if running this file directly
166if __name__ == "__main__":
167        x = MyState()
168        print x.__dict__
Note: See TracBrowser for help on using the browser.