Nodecon: Implement network property.

The network property will return an IPv4Network or IPv6Network based on the
nodecon.  If the policy has host bits set, the ipaddress module will
simply ignore the host bits, so there may be unexpected results in network
comparisons.

Closes #108
This commit is contained in:
Chris PeBenito 2017-09-16 10:43:56 -04:00
parent bfa50a42f8
commit 78a15c92ac
10 changed files with 148 additions and 136 deletions

View File

@ -1,4 +1,5 @@
# Copyright 2016, Tresys Technology, LLC
# Copyright 2017, Chris PeBenito <pebenito@ieee.org>
#
# This file is part of SETools.
#
@ -71,13 +72,12 @@ class NodeconWrapper(Wrapper):
"""Wrap nodecon statements for diff purposes."""
__slots__ = ("ip_version", "address", "netmask")
__slots__ = ("ip_version", "network")
def __init__(self, ocon):
self.origin = ocon
self.ip_version = ocon.ip_version
self.address = ocon.address
self.netmask = ocon.netmask
self.network = ocon.network
self.key = hash(ocon)
def __hash__(self):
@ -88,5 +88,4 @@ class NodeconWrapper(Wrapper):
def __eq__(self, other):
return self.ip_version == other.ip_version and \
self.address == other.address and \
self.netmask == other.netmask
self.network == other.network

View File

@ -1,4 +1,5 @@
# Copyright 2014-2015, Tresys Technology, LLC
# Copyright 2017, Chris PeBenito <pebenito@ieee.org>
#
# This file is part of SETools.
#
@ -102,27 +103,11 @@ class NodeconQuery(MatchContext, PolicyQuery):
for nodecon in self.policy.nodecons():
if self.network:
netmask = ipaddress.ip_address(nodecon.netmask)
# Python 3.4's IPv6Network constructor does not support
# expanded netmasks, only CIDR numbers. Convert netmask
# into CIDR.
# This is Brian Kernighan's method for counting set bits.
# If the netmask happens to be invalid, this will
# not detect it.
CIDR = 0
int_netmask = int(netmask)
while int_netmask:
int_netmask &= int_netmask - 1
CIDR += 1
net = ipaddress.ip_network('{0}/{1}'.format(nodecon.address, CIDR))
if self.network_overlap:
if not self.network.overlaps(net):
if not self.network.overlaps(nodecon.network):
continue
else:
if not net == self.network:
if not nodecon.network == self.network:
continue
if self.ip_version and self.ip_version != nodecon.ip_version:

View File

@ -1,5 +1,5 @@
# Copyright 2014, 2016, Tresys Technology, LLC
# Copyright 2016, Chris PeBenito <pebenito@ieee.org>
# Copyright 2016, 2017, Chris PeBenito <pebenito@ieee.org>
#
# This file is part of SETools.
#
@ -19,8 +19,11 @@
#
from socket import AF_INET, AF_INET6, IPPROTO_TCP, IPPROTO_UDP, getprotobyname
from collections import namedtuple
from ipaddress import ip_address, ip_network
import socket
import warnings
import logging
from . import qpol
from . import symbol
@ -119,18 +122,17 @@ class Nodecon(NetContext):
"""A nodecon statement."""
def __str__(self):
return "nodecon {0.address} {0.netmask} {0.context}".format(self)
return "nodecon {1} {0.context}".format(self, self.network.with_netmask.replace("/", " "))
def __hash__(self):
return hash("nodecon|{0.address}|{0.netmask}".format(self))
return hash("nodecon|{}".format(self.network.with_netmask))
def __eq__(self, other):
# Libqpol allocates new C objects in the
# nodecons iterator, so pointer comparison
# in the PolicySymbol object doesn't work.
try:
return (self.address == other.address and
self.netmask == other.netmask and
return (self.network == other.network and
self.context == other.context)
except AttributeError:
return (str(self) == str(other))
@ -146,13 +148,46 @@ class Nodecon(NetContext):
@property
def address(self):
"""The network address for the nodecon."""
warnings.warn("Nodecon.address will be removed in SETools 2.3, please use nodecon.network",
DeprecationWarning)
return self.qpol_symbol.addr(self.policy)
@property
def netmask(self):
"""The network mask for the nodecon."""
warnings.warn("Nodecon.netmask will be removed in SETools 2.3, please use nodecon.network",
DeprecationWarning)
return self.qpol_symbol.mask(self.policy)
@property
def network(self):
"""The network for the nodecon."""
CIDR = 0
addr = self.qpol_symbol.addr(self.policy)
mask = self.qpol_symbol.mask(self.policy)
# Python 3.4's IPv6Network constructor does not support
# expanded netmasks, only CIDR numbers. Convert netmask
# into CIDR.
# This is Brian Kernighan's method for counting set bits.
# If the netmask happens to be invalid, this will
# not detect it.
int_mask = int(ip_address(mask))
while int_mask:
int_mask &= int_mask - 1
CIDR += 1
net_with_mask = "{0}/{1}".format(addr, CIDR)
try:
# checkpolicy does not verify that no host bits are set,
# so strict will raise an exception if host bits are set.
return ip_network(net_with_mask)
except ValueError as ex:
log = logging.getLogger(__name__)
log.warning("Nodecon with network {} {} has host bits set. Analyses may have "
"unexpected results.".format(addr, mask))
return ip_network(net_with_mask, strict=False)
class PortconProtocol(int, PolicyEnum):

View File

@ -35,7 +35,7 @@ class NodeconTableModel(SEToolsTableModel):
if role == Qt.DisplayRole:
if col == 0:
return "{0.address}/{0.netmask}".format(rule)
return str(rule.network.with_netmask)
elif col == 1:
return str(rule.context)

View File

@ -1,5 +1,5 @@
# Copyright 2015-2016, Tresys Technology, LLC
# Copyright 2016, Chris PeBenito <pebenito@ieee.org>
# Copyright 2016, 2017, Chris PeBenito <pebenito@ieee.org>
#
# This file is part of SETools.
#
@ -18,6 +18,7 @@
#
import unittest
from socket import IPPROTO_TCP, IPPROTO_UDP
from ipaddress import IPv4Network, IPv6Network
from setools import SELinuxPolicy, PolicyDifference
from setools import BoundsRuletype as BRT
@ -1174,23 +1175,19 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
# new IPv4
nodecon = l[0]
self.assertEqual("127.0.0.4", nodecon.address)
self.assertEqual("255.255.255.255", nodecon.netmask)
self.assertEqual(IPv4Network("124.0.0.0/8"), nodecon.network)
# changed IPv4 netmask
nodecon = l[1]
self.assertEqual("127.0.0.5", nodecon.address)
self.assertEqual("255.255.255.0", nodecon.netmask)
self.assertEqual(IPv4Network("125.0.0.0/16"), nodecon.network)
# new IPv6
nodecon = l[2]
self.assertEqual("::4", nodecon.address)
self.assertEqual("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", nodecon.netmask)
self.assertEqual(IPv6Network("ff04::/62"), nodecon.network)
# changed IPv6 netmask
nodecon = l[3]
self.assertEqual("::5", nodecon.address)
self.assertEqual("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", nodecon.netmask)
self.assertEqual(IPv6Network("ff05::/60"), nodecon.network)
def test_removed_nodecons(self):
"""Diff: removed nodecons."""
@ -1199,23 +1196,19 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
# new IPv4
nodecon = l[0]
self.assertEqual("127.0.0.2", nodecon.address)
self.assertEqual("255.255.255.255", nodecon.netmask)
self.assertEqual(IPv4Network("122.0.0.0/8"), nodecon.network)
# changed IPv4 netmask
nodecon = l[1]
self.assertEqual("127.0.0.5", nodecon.address)
self.assertEqual("255.255.255.255", nodecon.netmask)
self.assertEqual(IPv4Network("125.0.0.0/8"), nodecon.network)
# new IPv6
nodecon = l[2]
self.assertEqual("::2", nodecon.address)
self.assertEqual("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", nodecon.netmask)
self.assertEqual(IPv6Network("ff02::/62"), nodecon.network)
# changed IPv6 netmask
nodecon = l[3]
self.assertEqual("::5", nodecon.address)
self.assertEqual("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", nodecon.netmask)
self.assertEqual(IPv6Network("ff05::/62"), nodecon.network)
def test_modified_nodecons(self):
"""Diff: modified nodecons."""
@ -1224,15 +1217,13 @@ class PolicyDifferenceTest(ValidateRule, unittest.TestCase):
# changed IPv4
nodecon, added_context, removed_context = l[0]
self.assertEqual("127.0.0.3", nodecon.address)
self.assertEqual("255.255.255.255", nodecon.netmask)
self.assertEqual(IPv4Network("123.0.0.0/8"), nodecon.network)
self.assertEqual("modified_change_level:object_r:system:s2:c0", added_context)
self.assertEqual("modified_change_level:object_r:system:s2:c1", removed_context)
# changed IPv6
nodecon, added_context, removed_context = l[1]
self.assertEqual("::3", nodecon.address)
self.assertEqual("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", nodecon.netmask)
self.assertEqual(IPv6Network("ff03::/62"), nodecon.network)
self.assertEqual("modified_change_level:object_r:system:s2:c1", added_context)
self.assertEqual("modified_change_level:object_r:system:s2:c0.c1", removed_context)

View File

@ -878,17 +878,17 @@ netifcon mod_pkt_netif system:object_r:system:s0 removed_user:object_r:system:s0
netifcon mod_both_netif removed_user:object_r:system:s0 removed_user:object_r:system:s0
# matched nodecons
nodecon 127.0.0.1 255.255.255.255 system:object_r:system:s0
nodecon ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system:s0
nodecon 121.0.0.0 255.0.0.0 system:object_r:system:s0
nodecon ff01:: ffff:ffff:ffff:fffc:: system:object_r:system:s0
# removed nodecons
nodecon 127.0.0.2 255.255.255.255 removed_user:object_r:system:s0
nodecon ::2 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff removed_user:object_r:system:s0
nodecon 122.0.0.0 255.0.0.0 removed_user:object_r:system:s0
nodecon ff02:: ffff:ffff:ffff:fffc:: removed_user:object_r:system:s0
# modified nodecons
nodecon 127.0.0.3 255.255.255.255 modified_change_level:object_r:system:s2:c1
nodecon ::3 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff modified_change_level:object_r:system:s2:c0,c1
nodecon 123.0.0.0 255.0.0.0 modified_change_level:object_r:system:s2:c1
nodecon ff03:: ffff:ffff:ffff:fffc:: modified_change_level:object_r:system:s2:c0,c1
# change netmask (add/remove)
nodecon 127.0.0.5 255.255.255.255 system:object_r:system:s0
nodecon ::5 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system:s0
nodecon 125.0.0.0 255.0.0.0 system:object_r:system:s0
nodecon ff05:: ffff:ffff:ffff:fffc:: system:object_r:system:s0

View File

@ -800,17 +800,17 @@ netifcon mod_pkt_netif system:object_r:system removed_user:object_r:system
netifcon mod_both_netif removed_user:object_r:system removed_user:object_r:system
# matched nodecons
nodecon 127.0.0.1 255.255.255.255 system:object_r:system
nodecon ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system
nodecon 121.0.0.0 255.0.0.0 system:object_r:system
nodecon ff01:: ffff:ffff:ffff:fffc:: system:object_r:system
# removed nodecons
nodecon 127.0.0.2 255.255.255.255 removed_user:object_r:system
nodecon ::2 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff removed_user:object_r:system
nodecon 122.0.0.0 255.0.0.0 removed_user:object_r:system
nodecon ff02:: ffff:ffff:ffff:fffc:: removed_user:object_r:system
# modified nodecons
nodecon 127.0.0.3 255.255.255.255 modified_change_level:object_r:system
nodecon ::3 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff modified_change_level:object_r:system
nodecon 123.0.0.0 255.0.0.0 modified_change_level:object_r:system
nodecon ff03:: ffff:ffff:ffff:fffc:: modified_change_level:object_r:system
# change netmask (add/remove)
nodecon 127.0.0.5 255.255.255.255 system:object_r:system
nodecon ::5 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system
nodecon 125.0.0.0 255.0.0.0 system:object_r:system
nodecon ff05:: ffff:ffff:ffff:fffc:: system:object_r:system

View File

@ -902,17 +902,17 @@ netifcon mod_pkt_netif system:object_r:system:s0 added_user:object_r:system:s0
netifcon mod_both_netif added_user:object_r:system:s0 added_user:object_r:system:s0
# matched nodecons
nodecon 127.0.0.1 255.255.255.255 system:object_r:system:s0
nodecon ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system:s0
nodecon 121.0.0.0 255.0.0.0 system:object_r:system:s0
nodecon ff01:: ffff:ffff:ffff:fffc:: system:object_r:system:s0
# added nodecons
nodecon 127.0.0.4 255.255.255.255 added_user:object_r:system:s0
nodecon ::4 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff added_user:object_r:system:s0
nodecon 124.0.0.0 255.0.0.0 added_user:object_r:system:s0
nodecon ff04:: ffff:ffff:ffff:fffc:: added_user:object_r:system:s0
# modified nodecons
nodecon 127.0.0.3 255.255.255.255 modified_change_level:object_r:system:s2:c0
nodecon ::3 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff modified_change_level:object_r:system:s2:c1
nodecon 123.0.0.0 255.0.0.0 modified_change_level:object_r:system:s2:c0
nodecon ff03:: ffff:ffff:ffff:fffc:: modified_change_level:object_r:system:s2:c1
# change netmask (add/remove)
nodecon 127.0.0.5 255.255.255.0 system:object_r:system:s0
nodecon ::5 ffff:ffff:ffff:ffff:ffff:ffff:ffff:: system:object_r:system:s0
nodecon 125.0.0.0 255.255.0.0 system:object_r:system:s0
nodecon ff05:: ffff:ffff:ffff:fff0:: system:object_r:system:s0

View File

@ -242,20 +242,20 @@ nodecon 10.1.54.1 255.255.255.255 system:system:system:s4:c1 - s4:c1.c3
nodecon 10.1.55.1 255.255.255.255 system:system:system:s5:c1 - s5:c1.c3
# test 100:
# network: 10.1.100.0/24, equal
# network: 192.168.1.0/24, equal
# user: unset
# role: unset
# type: unset
# range: unset
nodecon 10.1.100.0 255.255.255.0 system:system:system:s0:c0.c1
nodecon 192.168.1.0 255.255.255.0 system:system:system:s0:c0.c1
# test 101:
# network: 10.1.101.128/25, overlap
# network: 192.168.201.0/24, overlap
# user: unset
# role: unset
# type: unset
# range: unset
nodecon 10.1.101.0 255.255.255.0 system:system:system:s0:c0.c1
nodecon 192.168.200.0 255.255.252.0 system:system:system:s0:c0.c1
# test 110:
# network: 1100::/16, equal

View File

@ -1,4 +1,5 @@
# Copyright 2014, Tresys Technology, LLC
# Copyright 2017, Chris PeBenito <pebenito@ieee.org>
#
# This file is part of SETools.
#
@ -18,6 +19,7 @@
import sys
import unittest
from socket import AF_INET6
from ipaddress import IPv4Network, IPv6Network
from setools import SELinuxPolicy, NodeconQuery
@ -42,201 +44,201 @@ class NodeconQueryTest(unittest.TestCase):
"""Nodecon query with IP version match."""
q = NodeconQuery(self.p, ip_version=AF_INET6)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["1100::", "1110::"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv6Network("1100::/16"), IPv6Network("1110::/16")], nodecons)
def test_020_user_exact(self):
"""Nodecon query with context user exact match"""
q = NodeconQuery(self.p, user="user20", user_regex=False)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.20.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.20.1/32")], nodecons)
def test_021_user_regex(self):
"""Nodecon query with context user regex match"""
q = NodeconQuery(self.p, user="user21(a|b)", user_regex=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.21.1", "10.1.21.2"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.21.1/32"), IPv4Network("10.1.21.2/32")], nodecons)
def test_030_role_exact(self):
"""Nodecon query with context role exact match"""
q = NodeconQuery(self.p, role="role30_r", role_regex=False)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.30.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.30.1/32")], nodecons)
def test_031_role_regex(self):
"""Nodecon query with context role regex match"""
q = NodeconQuery(self.p, role="role31(a|c)_r", role_regex=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.31.1", "10.1.31.3"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.31.1/32"), IPv4Network("10.1.31.3/32")], nodecons)
def test_040_type_exact(self):
"""Nodecon query with context type exact match"""
q = NodeconQuery(self.p, type_="type40", type_regex=False)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.40.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.40.1/32")], nodecons)
def test_041_type_regex(self):
"""Nodecon query with context type regex match"""
q = NodeconQuery(self.p, type_="type41(b|c)", type_regex=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.41.2", "10.1.41.3"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.41.2/32"), IPv4Network("10.1.41.3/32")], nodecons)
def test_050_range_exact(self):
"""Nodecon query with context range exact match"""
q = NodeconQuery(self.p, range_="s0:c1 - s0:c0.c4")
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.50.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.50.1/32")], nodecons)
def test_051_range_overlap1(self):
"""Nodecon query with context range overlap match (equal)"""
q = NodeconQuery(self.p, range_="s1:c1 - s1:c0.c4", range_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.51.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.51.1/32")], nodecons)
def test_051_range_overlap2(self):
"""Nodecon query with context range overlap match (subset)"""
q = NodeconQuery(self.p, range_="s1:c1,c2 - s1:c0.c3", range_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.51.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.51.1/32")], nodecons)
def test_051_range_overlap3(self):
"""Nodecon query with context range overlap match (superset)"""
q = NodeconQuery(self.p, range_="s1 - s1:c0.c4", range_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.51.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.51.1/32")], nodecons)
def test_051_range_overlap4(self):
"""Nodecon query with context range overlap match (overlap low level)"""
q = NodeconQuery(self.p, range_="s1 - s1:c1,c2", range_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.51.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.51.1/32")], nodecons)
def test_051_range_overlap5(self):
"""Nodecon query with context range overlap match (overlap high level)"""
q = NodeconQuery(self.p, range_="s1:c1,c2 - s1:c0.c4", range_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.51.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.51.1/32")], nodecons)
def test_052_range_subset1(self):
"""Nodecon query with context range subset match"""
q = NodeconQuery(self.p, range_="s2:c1,c2 - s2:c0.c3", range_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.52.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.52.1/32")], nodecons)
def test_052_range_subset2(self):
"""Nodecon query with context range subset match (equal)"""
q = NodeconQuery(self.p, range_="s2:c1 - s2:c1.c3", range_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.52.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.52.1/32")], nodecons)
def test_053_range_superset1(self):
"""Nodecon query with context range superset match"""
q = NodeconQuery(self.p, range_="s3 - s3:c0.c4", range_superset=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.53.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.53.1/32")], nodecons)
def test_053_range_superset2(self):
"""Nodecon query with context range superset match (equal)"""
q = NodeconQuery(self.p, range_="s3:c1 - s3:c1.c3", range_superset=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.53.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.53.1/32")], nodecons)
def test_054_range_proper_subset1(self):
"""Nodecon query with context range proper subset match"""
q = NodeconQuery(self.p, range_="s4:c1,c2", range_subset=True, range_proper=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.54.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.54.1/32")], nodecons)
def test_054_range_proper_subset2(self):
"""Nodecon query with context range proper subset match (equal)"""
q = NodeconQuery(self.p, range_="s4:c1 - s4:c1.c3", range_subset=True, range_proper=True)
nodecons = sorted(n.address for n in q.results())
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([], nodecons)
def test_054_range_proper_subset3(self):
"""Nodecon query with context range proper subset match (equal low only)"""
q = NodeconQuery(self.p, range_="s4:c1 - s4:c1.c2", range_subset=True, range_proper=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.54.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.54.1/32")], nodecons)
def test_054_range_proper_subset4(self):
"""Nodecon query with context range proper subset match (equal high only)"""
q = NodeconQuery(self.p, range_="s4:c1,c2 - s4:c1.c3", range_subset=True, range_proper=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.54.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.54.1/32")], nodecons)
def test_055_range_proper_superset1(self):
"""Nodecon query with context range proper superset match"""
q = NodeconQuery(self.p, range_="s5 - s5:c0.c4", range_superset=True, range_proper=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.55.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.55.1/32")], nodecons)
def test_055_range_proper_superset2(self):
"""Nodecon query with context range proper superset match (equal)"""
q = NodeconQuery(self.p, range_="s5:c1 - s5:c1.c3", range_superset=True, range_proper=True)
nodecons = sorted(n.address for n in q.results())
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([], nodecons)
def test_055_range_proper_superset3(self):
"""Nodecon query with context range proper superset match (equal low)"""
q = NodeconQuery(self.p, range_="s5:c1 - s5:c1.c4", range_superset=True, range_proper=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.55.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.55.1/32")], nodecons)
def test_055_range_proper_superset4(self):
"""Nodecon query with context range proper superset match (equal high)"""
q = NodeconQuery(self.p, range_="s5 - s5:c1.c3", range_superset=True, range_proper=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.55.1"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("10.1.55.1/32")], nodecons)
def test_100_v4network_equal(self):
"""Nodecon query with IPv4 equal network"""
q = NodeconQuery(self.p, network="10.1.100.0/24", network_overlap=False)
q = NodeconQuery(self.p, network="192.168.1.0/24", network_overlap=False)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.100.0"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("192.168.1.0/24")], nodecons)
def test_101_v4network_overlap(self):
"""Nodecon query with IPv4 network overlap"""
q = NodeconQuery(self.p, network="10.1.101.128/25", network_overlap=True)
q = NodeconQuery(self.p, network="192.168.201.0/24", network_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["10.1.101.0"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv4Network("192.168.200.0/22")], nodecons)
def test_110_v6network_equal(self):
"""Nodecon query with IPv6 equal network"""
q = NodeconQuery(self.p, network="1100::/16", network_overlap=False)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["1100::"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv6Network("1100::/16")], nodecons)
def test_111_v6network_overlap(self):
"""Nodecon query with IPv6 network overlap"""
q = NodeconQuery(self.p, network="1110:8000::/17", network_overlap=True)
nodecons = sorted(n.address for n in q.results())
self.assertListEqual(["1110::"], nodecons)
nodecons = sorted(n.network for n in q.results())
self.assertListEqual([IPv6Network("1110::/16")], nodecons)