|
|
@ -860,44 +860,87 @@ class GenericBsdIfconfigNetwork(Network):
|
|
|
|
if line:
|
|
|
|
if line:
|
|
|
|
words = line.split()
|
|
|
|
words = line.split()
|
|
|
|
if re.match('^\S', line) and len(words) > 3:
|
|
|
|
if re.match('^\S', line) and len(words) > 3:
|
|
|
|
|
|
|
|
current_if = self.parse_interface_line(words)
|
|
|
|
|
|
|
|
interfaces[ current_if['device'] ] = current_if
|
|
|
|
|
|
|
|
elif words[0].startswith('options='):
|
|
|
|
|
|
|
|
self.parse_options_line(words, current_if, ips)
|
|
|
|
|
|
|
|
elif words[0] == 'nd6':
|
|
|
|
|
|
|
|
self.parse_nd6_line(words, current_if, ips)
|
|
|
|
|
|
|
|
elif words[0] == 'ether':
|
|
|
|
|
|
|
|
self.parse_ether_line(words, current_if, ips)
|
|
|
|
|
|
|
|
elif words[0] == 'media:':
|
|
|
|
|
|
|
|
self.parse_media_line(words, current_if, ips)
|
|
|
|
|
|
|
|
elif words[0] == 'status:':
|
|
|
|
|
|
|
|
self.parse_status_line(words, current_if, ips)
|
|
|
|
|
|
|
|
elif words[0] == 'lladdr':
|
|
|
|
|
|
|
|
self.parse_lladdr_line(words, current_if, ips)
|
|
|
|
|
|
|
|
elif words[0] == 'inet':
|
|
|
|
|
|
|
|
self.parse_inet_line(words, current_if, ips)
|
|
|
|
|
|
|
|
elif words[0] == 'inet6':
|
|
|
|
|
|
|
|
self.parse_inet6_line(words, current_if, ips)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
self.parse_unknown_line(words, current_if, ips)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return interfaces, ips
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_interface_line(self, words):
|
|
|
|
device = words[0][0:-1]
|
|
|
|
device = words[0][0:-1]
|
|
|
|
current_if = {'device': device, 'ipv4': [], 'ipv6': [], 'type': 'unknown'}
|
|
|
|
current_if = {'device': device, 'ipv4': [], 'ipv6': [], 'type': 'unknown'}
|
|
|
|
interfaces[device] = current_if
|
|
|
|
|
|
|
|
current_if['flags'] = self.get_options(words[1])
|
|
|
|
current_if['flags'] = self.get_options(words[1])
|
|
|
|
current_if['mtu'] = words[3]
|
|
|
|
current_if['mtu'] = words[3]
|
|
|
|
current_if['macaddress'] = 'unknown' # will be overwritten later
|
|
|
|
current_if['macaddress'] = 'unknown' # will be overwritten later
|
|
|
|
elif words[0].startswith('options='):
|
|
|
|
return current_if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_options_line(self, words, current_if, ips):
|
|
|
|
# Mac has options like this...
|
|
|
|
# Mac has options like this...
|
|
|
|
current_if['options'] = self.get_options(words[0])
|
|
|
|
current_if['options'] = self.get_options(words[0])
|
|
|
|
elif words[0] == 'nd6':
|
|
|
|
|
|
|
|
|
|
|
|
def parse_nd6_line(self, words, current_if, ips):
|
|
|
|
# FreBSD has options like this...
|
|
|
|
# FreBSD has options like this...
|
|
|
|
current_if['options'] = self.get_options(words[1])
|
|
|
|
current_if['options'] = self.get_options(words[1])
|
|
|
|
elif words[0] == 'ether':
|
|
|
|
|
|
|
|
|
|
|
|
def parse_ether_line(self, words, current_if, ips):
|
|
|
|
current_if['macaddress'] = words[1]
|
|
|
|
current_if['macaddress'] = words[1]
|
|
|
|
elif words[0] == 'media:':
|
|
|
|
|
|
|
|
|
|
|
|
def parse_media_line(self, words, current_if, ips):
|
|
|
|
# not sure if this is useful - we also drop information
|
|
|
|
# not sure if this is useful - we also drop information
|
|
|
|
current_if['media'] = words[1]
|
|
|
|
current_if['media'] = words[1]
|
|
|
|
elif words[0] == 'status:':
|
|
|
|
if len(words) > 2:
|
|
|
|
|
|
|
|
current_if['media_select'] = words[2]
|
|
|
|
|
|
|
|
if len(words) > 3:
|
|
|
|
|
|
|
|
current_if['media_type'] = words[3][1:]
|
|
|
|
|
|
|
|
if len(words) > 4:
|
|
|
|
|
|
|
|
current_if['media_options'] = self.get_options(words[4])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_status_line(self, words, current_if, ips):
|
|
|
|
current_if['status'] = words[1]
|
|
|
|
current_if['status'] = words[1]
|
|
|
|
elif words[0] == 'lladdr':
|
|
|
|
|
|
|
|
|
|
|
|
def parse_lladdr_line(self, words, current_if, ips):
|
|
|
|
current_if['lladdr'] = words[1]
|
|
|
|
current_if['lladdr'] = words[1]
|
|
|
|
elif words[0] == 'inet':
|
|
|
|
|
|
|
|
|
|
|
|
def parse_inet_line(self, words, current_if, ips):
|
|
|
|
address = {'address': words[1]}
|
|
|
|
address = {'address': words[1]}
|
|
|
|
|
|
|
|
# deal with hex netmask
|
|
|
|
if words[3].startswith('0x'):
|
|
|
|
if words[3].startswith('0x'):
|
|
|
|
address['netmask'] = socket.inet_ntoa(struct.pack('!L', int(words[3], base=16)))
|
|
|
|
address['netmask'] = socket.inet_ntoa(struct.pack('!L', int(words[3], base=16)))
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
|
|
|
|
# otherwise assume this is a dotted quad
|
|
|
|
address['netmask'] = words[3]
|
|
|
|
address['netmask'] = words[3]
|
|
|
|
if len(words) > 5:
|
|
|
|
|
|
|
|
address['broadcast'] = words[5]
|
|
|
|
|
|
|
|
# calculate the network
|
|
|
|
# calculate the network
|
|
|
|
address_bin = struct.unpack('!L', socket.inet_aton(address['address']))[0]
|
|
|
|
address_bin = struct.unpack('!L', socket.inet_aton(address['address']))[0]
|
|
|
|
netmask_bin = struct.unpack('!L', socket.inet_aton(address['netmask']))[0]
|
|
|
|
netmask_bin = struct.unpack('!L', socket.inet_aton(address['netmask']))[0]
|
|
|
|
address['network'] = socket.inet_ntoa(struct.pack('!L', address_bin & netmask_bin))
|
|
|
|
address['network'] = socket.inet_ntoa(struct.pack('!L', address_bin & netmask_bin))
|
|
|
|
|
|
|
|
# broadcast may be given or we need to calculate
|
|
|
|
|
|
|
|
if len(words) > 5:
|
|
|
|
|
|
|
|
address['broadcast'] = words[5]
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
address['broadcast'] = socket.inet_ntoa(struct.pack('!L', address_bin | (~netmask_bin & 0xffffffff)))
|
|
|
|
# add to our list of addresses
|
|
|
|
# add to our list of addresses
|
|
|
|
if not words[1].startswith('127.'):
|
|
|
|
if not words[1].startswith('127.'):
|
|
|
|
ips['all_ipv4_addresses'].append(address['address'])
|
|
|
|
ips['all_ipv4_addresses'].append(address['address'])
|
|
|
|
current_if['ipv4'].append(address)
|
|
|
|
current_if['ipv4'].append(address)
|
|
|
|
elif words[0] == 'inet6':
|
|
|
|
|
|
|
|
|
|
|
|
def parse_inet6_line(self, words, current_if, ips):
|
|
|
|
address = {'address': words[1]}
|
|
|
|
address = {'address': words[1]}
|
|
|
|
if (len(words) >= 4) and (words[2] == 'prefixlen'):
|
|
|
|
if (len(words) >= 4) and (words[2] == 'prefixlen'):
|
|
|
|
address['prefix'] = words[3]
|
|
|
|
address['prefix'] = words[3]
|
|
|
@ -906,11 +949,15 @@ class GenericBsdIfconfigNetwork(Network):
|
|
|
|
if not address['address'] == '::1' and not address['address'] == 'fe80::1%lo0':
|
|
|
|
if not address['address'] == '::1' and not address['address'] == 'fe80::1%lo0':
|
|
|
|
ips['all_ipv6_addresses'].append(address['address'])
|
|
|
|
ips['all_ipv6_addresses'].append(address['address'])
|
|
|
|
current_if['ipv6'].append(address)
|
|
|
|
current_if['ipv6'].append(address)
|
|
|
|
return interfaces, ips
|
|
|
|
|
|
|
|
|
|
|
|
def parse_unknown_line(self, words, current_if, ips):
|
|
|
|
|
|
|
|
# we are going to ignore unknown lines here - this may be
|
|
|
|
|
|
|
|
# a bad idea - but you can override it in your subclass
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def get_options(self, option_string):
|
|
|
|
def get_options(self, option_string):
|
|
|
|
start = option_string.find('<') + 1
|
|
|
|
start = option_string.find('<') + 1
|
|
|
|
end = option_string.rfind('>') - 1
|
|
|
|
end = option_string.rfind('>')
|
|
|
|
if (start > 0) and (end > 0) and (end > start + 1):
|
|
|
|
if (start > 0) and (end > 0) and (end > start + 1):
|
|
|
|
option_csv = option_string[start:end]
|
|
|
|
option_csv = option_string[start:end]
|
|
|
|
return option_csv.split(',')
|
|
|
|
return option_csv.split(',')
|
|
|
@ -936,6 +983,17 @@ class DarwinNetwork(GenericBsdIfconfigNetwork, Network):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
platform = 'Darwin'
|
|
|
|
platform = 'Darwin'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# media line is different to the default FreeBSD one
|
|
|
|
|
|
|
|
def parse_media_line(self, words, current_if, ips):
|
|
|
|
|
|
|
|
# not sure if this is useful - we also drop information
|
|
|
|
|
|
|
|
current_if['media'] = 'Unknown' # Mac does not give us this
|
|
|
|
|
|
|
|
current_if['media_select'] = words[1]
|
|
|
|
|
|
|
|
if len(words) > 2:
|
|
|
|
|
|
|
|
current_if['media_type'] = words[2][1:]
|
|
|
|
|
|
|
|
if len(words) > 3:
|
|
|
|
|
|
|
|
current_if['media_options'] = self.get_options(words[3])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FreeBSDNetwork(GenericBsdIfconfigNetwork, Network):
|
|
|
|
class FreeBSDNetwork(GenericBsdIfconfigNetwork, Network):
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
This is the FreeBSD Network Class.
|
|
|
|
This is the FreeBSD Network Class.
|
|
|
|