Don't assume column index for netmask and broadcast (#79121)

* Don't assume column index for netmask and broadcast. Fixes #79117

* fix typo
pull/79386/head
Matt Martz 2 years ago committed by GitHub
parent c4d6629bce
commit f53dbf90ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,4 @@
bugfixes:
- BSD network facts - Do not assume column indexes, look for ``netmask`` and
``broadcast`` for determining the correct columns when parsing ``inet`` line
(https://github.com/ansible/ansible/issues/79117)

@ -221,24 +221,35 @@ class GenericBsdIfconfigNetwork(Network):
address['broadcast'] = words[3]
else:
# Don't just assume columns, use "netmask" as the index for the prior column
try:
netmask_idx = words.index('netmask') + 1
except ValueError:
netmask_idx = 3
# deal with hex netmask
if re.match('([0-9a-f]){8}', words[3]) and len(words[3]) == 8:
words[3] = '0x' + words[3]
if words[3].startswith('0x'):
address['netmask'] = socket.inet_ntoa(struct.pack('!L', int(words[3], base=16)))
if re.match('([0-9a-f]){8}$', words[netmask_idx]):
netmask = '0x' + words[netmask_idx]
else:
netmask = words[netmask_idx]
if netmask.startswith('0x'):
address['netmask'] = socket.inet_ntoa(struct.pack('!L', int(netmask, base=16)))
else:
# otherwise assume this is a dotted quad
address['netmask'] = words[3]
address['netmask'] = netmask
# calculate the network
address_bin = struct.unpack('!L', socket.inet_aton(address['address']))[0]
netmask_bin = struct.unpack('!L', socket.inet_aton(address['netmask']))[0]
address['network'] = socket.inet_ntoa(struct.pack('!L', address_bin & netmask_bin))
if 'broadcast' not in address:
# broadcast may be given or we need to calculate
if len(words) > 5:
address['broadcast'] = words[5]
else:
try:
broadcast_idx = words.index('broadcast') + 1
except ValueError:
address['broadcast'] = socket.inet_ntoa(struct.pack('!L', address_bin | (~netmask_bin & 0xffffffff)))
else:
address['broadcast'] = words[broadcast_idx]
# add to our list of addresses
if not words[1].startswith('127.'):

@ -173,3 +173,45 @@ class TestGenericBsdNetworkNetBSD(unittest.TestCase):
'filter': '*'}
mock_module.get_bin_path = Mock(return_value=None)
return mock_module
def test_ensure_correct_netmask_parsing(self):
n = generic_bsd.GenericBsdIfconfigNetwork(None)
lines = [
'inet 192.168.7.113 netmask 0xffffff00 broadcast 192.168.7.255',
'inet 10.109.188.206 --> 10.109.188.206 netmask 0xffffe000',
]
expected = [
(
{
'ipv4': [
{
'address': '192.168.7.113',
'netmask': '255.255.255.0',
'network': '192.168.7.0',
'broadcast': '192.168.7.255'
}
]
},
{'all_ipv4_addresses': ['192.168.7.113']},
),
(
{
'ipv4': [
{
'address': '10.109.188.206',
'netmask': '255.255.224.0',
'network': '10.109.160.0',
'broadcast': '10.109.191.255'
}
]
},
{'all_ipv4_addresses': ['10.109.188.206']},
),
]
for i, line in enumerate(lines):
words = line.split()
current_if = {'ipv4': []}
ips = {'all_ipv4_addresses': []}
n.parse_inet_line(words, current_if, ips)
self.assertDictEqual(current_if, expected[i][0])
self.assertDictEqual(ips, expected[i][1])

Loading…
Cancel
Save