2 # Copyright (c) 2012, 2013, Intel Corporation
3 # Copyright (c) 2009 David Wolinsky <davidiw@ufl.edu), University of Florida
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # 3. The name of the author may not be used to endorse or promote products
15 # derived from this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 import socket,fcntl, struct, thread
32 SMACKFS_LOAD="/sys/fs/smackfs/load2"
33 SMACKFS_NETLABEL="/sys/fs/smackfs/netlabel"
35 SIOCGIFNETMASK = 0x891b
37 def get_ip_address(ifname):
38 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
39 return fcntl.ioctl(s.fileno(), SIOCGIFADDR,
40 struct.pack('256s', ifname.encode("utf-8")))[20:24]
42 def get_netmask(ifname):
43 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
44 return fcntl.ioctl(s.fileno(), SIOCGIFNETMASK,
45 struct.pack('256s', ifname.encode("utf-8")))[20:24]
47 def applynetlabeltags(interface, addr):
48 if not interface.startswith("lo"):
49 bmask = get_netmask(interface.encode("utf-8"))
50 prefix = bin(struct.unpack(">L", bmask)[0]).count("1")
52 addr+"/"+str(prefix)+" Network::Local\n",
53 "0.0.0.0/0 Network::Cloud\n",
54 "127.0.0.1/8 -CIPSO\n"]
55 smackfs_netlabel(tags)
57 def loadnetlabelrules():
59 "System Network::Cloud w\n",
60 "System Network::Local w\n",
61 "Network::Cloud System w\n",
62 "Network::Local System w\n"]
63 smackfs_load2(rulesSystem)
65 def smackfs_load2 (rules):
66 with open(SMACKFS_LOAD, "w") as load2:
70 def smackfs_netlabel (tags):
72 with open(SMACKFS_NETLABEL, "w") as netlabel:
76 Source of: Class ip monitor, and other functions named bellow.
77 Original author: David Wolinsky <davidiw@ufl.edu
78 Copied from: https://github.com/davidiw/Grid-Appliance/blob/master/scripts/ip_monitor.py
82 """4 byte alignment"""
86 return inc + ((4 - diff) % 4)
89 """Parse an ifaddr packet"""
93 def __init__(self, packet):
94 self.family, self.prefixlen, self.flags, self.scope, self.index = \
95 struct.unpack("BBBBI", packet[:8])
98 """Parse a rtattr packet"""
99 GRP_IPV4_IFADDR = 0x10
105 def __init__(self, packet):
106 self.len, self.type = struct.unpack("HH", packet[:4])
107 if self.type == ifaddr.LOCAL:
108 addr = struct.unpack("BBBB", packet[4:self.len])
109 self.payload = "%s.%s.%s.%s" % (addr[0], addr[1], addr[2], addr[3])
110 elif self.type == ifaddr.LABEL:
111 self.payload = packet[4:self.len].strip("\0")
113 self.payload = packet[4:self.len]
116 """Parse a netlink packet"""
122 def __init__(self, packet):
123 self.msglen, self.msgtype, self.flags, self.seq, self.pid = \
124 struct.unpack("IHHII", packet[:16])
127 self.ifa = ifaddr(packet[16:24])
133 while pos < self.msglen:
135 rta = rtattr(packet[pos:])
138 pos += align(rta.len)
139 self.rtas[rta.type] = rta.payload
142 def __init__(self, callback = None):
144 callback = self.print_cb
145 self._callback = callback
147 def print_cb(self, label, addr):
148 print (label + " => " + addr)
150 def request_addrs(self, sock):
151 sock.send(struct.pack("IHHIIBBBBI", 24, rtattr.GETADDR, \
152 netlink.REQUEST | netlink.ROOT | netlink.MATCH, 0, sock.getsockname()[0], \
153 socket.AF_INET, 0, 0, 0, 0))
155 def start_thread(self):
156 thread.start_new_thread(self.run, ())
159 sock = socket.socket(socket.AF_NETLINK, socket.SOCK_RAW, socket.NETLINK_ROUTE)
160 sock.bind((0, rtattr.GRP_IPV4_IFADDR))
161 self.request_addrs(sock)
164 data = sock.recv(4096)
166 while pos < len(data):
167 nl = netlink(data[pos:])
168 if nl.msgtype == netlink.DONE:
170 pos += align(nl.msglen)
171 if nl.msgtype != rtattr.NEWADDR:
173 self._callback(nl.rtas[ifaddr.LABEL], nl.rtas[ifaddr.LOCAL])
176 if not os.path.isfile(SMACKFS_LOAD):
177 print ("Smack not found.")
181 ip_monitor(applynetlabeltags).run()
183 if __name__ == "__main__":