#1800 - Added ACL and routing classes.
- Added .show() methods to new router classes to enable inspection of the components as you would a real router. - Removed gateway from the NIC and added default_gateway to Node so that Node has a single default gateway. - Added some routing tests to check that ping can be performed when router between subnets.
This commit is contained in:
@@ -3,14 +3,13 @@ from primaite.simulator.network.hardware.base import Link, NIC, Node, Switch
|
||||
|
||||
def test_node_to_node_ping():
|
||||
"""Tests two Nodes are able to ping each other."""
|
||||
# TODO Add actual checks. Manual check performed for now.
|
||||
node_a = Node(hostname="node_a")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0")
|
||||
node_a.connect_nic(nic_a)
|
||||
node_a.power_on()
|
||||
|
||||
node_b = Node(hostname="node_b")
|
||||
nic_b = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_b = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0")
|
||||
node_b.connect_nic(nic_b)
|
||||
node_b.power_on()
|
||||
|
||||
@@ -23,19 +22,19 @@ def test_multi_nic():
|
||||
"""Tests that Nodes with multiple NICs can ping each other and the data go across the correct links."""
|
||||
# TODO Add actual checks. Manual check performed for now.
|
||||
node_a = Node(hostname="node_a")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0")
|
||||
node_a.connect_nic(nic_a)
|
||||
node_a.power_on()
|
||||
|
||||
node_b = Node(hostname="node_b")
|
||||
nic_b1 = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_b2 = NIC(ip_address="10.0.0.12", subnet_mask="255.0.0.0", gateway="10.0.0.1")
|
||||
nic_b1 = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0")
|
||||
nic_b2 = NIC(ip_address="10.0.0.12", subnet_mask="255.0.0.0")
|
||||
node_b.connect_nic(nic_b1)
|
||||
node_b.connect_nic(nic_b2)
|
||||
node_b.power_on()
|
||||
|
||||
node_c = Node(hostname="node_c")
|
||||
nic_c = NIC(ip_address="10.0.0.13", subnet_mask="255.0.0.0", gateway="10.0.0.1")
|
||||
nic_c = NIC(ip_address="10.0.0.13", subnet_mask="255.0.0.0")
|
||||
node_c.connect_nic(nic_c)
|
||||
node_c.power_on()
|
||||
|
||||
@@ -52,22 +51,22 @@ def test_switched_network():
|
||||
"""Tests a larges network of Nodes and Switches with one node pinging another."""
|
||||
# TODO Add actual checks. Manual check performed for now.
|
||||
pc_a = Node(hostname="pc_a")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0")
|
||||
pc_a.connect_nic(nic_a)
|
||||
pc_a.power_on()
|
||||
|
||||
pc_b = Node(hostname="pc_b")
|
||||
nic_b = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_b = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0")
|
||||
pc_b.connect_nic(nic_b)
|
||||
pc_b.power_on()
|
||||
|
||||
pc_c = Node(hostname="pc_c")
|
||||
nic_c = NIC(ip_address="192.168.0.12", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_c = NIC(ip_address="192.168.0.12", subnet_mask="255.255.255.0")
|
||||
pc_c.connect_nic(nic_c)
|
||||
pc_c.power_on()
|
||||
|
||||
pc_d = Node(hostname="pc_d")
|
||||
nic_d = NIC(ip_address="192.168.0.13", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_d = NIC(ip_address="192.168.0.13", subnet_mask="255.255.255.0")
|
||||
pc_d.connect_nic(nic_d)
|
||||
pc_d.power_on()
|
||||
|
||||
|
||||
@@ -4,18 +4,17 @@ from primaite.simulator.network.hardware.base import Link, NIC, Node
|
||||
def test_link_up():
|
||||
"""Tests Nodes, NICs, and Links can all be connected and be in an enabled/up state."""
|
||||
node_a = Node(hostname="node_a")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0")
|
||||
node_a.connect_nic(nic_a)
|
||||
node_a.power_on()
|
||||
assert nic_a.enabled
|
||||
|
||||
node_b = Node(hostname="node_b")
|
||||
nic_b = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
nic_b = NIC(ip_address="192.168.0.11", subnet_mask="255.255.255.0")
|
||||
node_b.connect_nic(nic_b)
|
||||
node_b.power_on()
|
||||
|
||||
assert nic_b.enabled
|
||||
|
||||
link = Link(endpoint_a=nic_a, endpoint_b=nic_b)
|
||||
|
||||
assert nic_a.enabled
|
||||
assert nic_b.enabled
|
||||
assert link.is_up
|
||||
|
||||
@@ -8,7 +8,6 @@ def test_link_fails_with_same_nic():
|
||||
with pytest.raises(ValueError):
|
||||
nic_a = NIC(
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
gateway="192.168.0.1",
|
||||
subnet_mask="255.255.255.0"
|
||||
)
|
||||
Link(endpoint_a=nic_a, endpoint_b=nic_a)
|
||||
|
||||
@@ -1,27 +1,55 @@
|
||||
from primaite.simulator.network.hardware.base import Node, NIC, Link
|
||||
from primaite.simulator.network.hardware.nodes.router import Router
|
||||
from typing import Tuple
|
||||
|
||||
import pytest
|
||||
|
||||
from primaite.simulator.network.hardware.base import Link, NIC, Node
|
||||
from primaite.simulator.network.hardware.nodes.router import ACLAction, Router
|
||||
from primaite.simulator.network.transmission.network_layer import IPProtocol
|
||||
from primaite.simulator.network.transmission.transport_layer import Port
|
||||
|
||||
|
||||
def test_ping_fails_with_no_route():
|
||||
"""Tests a larges network of Nodes and Switches with one node pinging another."""
|
||||
pc_a = Node(hostname="pc_a")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0", gateway="192.168.0.1")
|
||||
@pytest.fixture(scope="function")
|
||||
def pc_a_pc_b_router_1() -> Tuple[Node, Node, Router]:
|
||||
pc_a = Node(hostname="pc_a", default_gateway="192.168.0.1")
|
||||
nic_a = NIC(ip_address="192.168.0.10", subnet_mask="255.255.255.0")
|
||||
pc_a.connect_nic(nic_a)
|
||||
pc_a.power_on()
|
||||
|
||||
pc_b = Node(hostname="pc_b")
|
||||
nic_b = NIC(ip_address="192.168.1.10", subnet_mask="255.255.255.0", gateway="192.168.1.1")
|
||||
pc_b = Node(hostname="pc_b", default_gateway="192.168.1.1")
|
||||
nic_b = NIC(ip_address="192.168.1.10", subnet_mask="255.255.255.0")
|
||||
pc_b.connect_nic(nic_b)
|
||||
pc_b.power_on()
|
||||
|
||||
router_1 = Router(hostname="router_1")
|
||||
router_1.power_on()
|
||||
|
||||
router_1.configure_port(1, "192.168.0.1", "255.255.255.0")
|
||||
router_1.configure_port(2, "192.168.1.1", "255.255.255.0")
|
||||
|
||||
router_1.power_on()
|
||||
router_1.show()
|
||||
Link(endpoint_a=nic_a, endpoint_b=router_1.ethernet_ports[1])
|
||||
Link(endpoint_a=nic_b, endpoint_b=router_1.ethernet_ports[2])
|
||||
router_1.enable_port(1)
|
||||
router_1.enable_port(2)
|
||||
|
||||
link_nic_a_router_1 = Link(endpoint_a=nic_a, endpoint_b=router_1.ethernet_ports[1])
|
||||
link_nic_b_router_1 = Link(endpoint_a=nic_b, endpoint_b=router_1.ethernet_ports[2])
|
||||
router_1.power_on()
|
||||
#assert pc_a.ping("192.168.1.10")
|
||||
router_1.acl.add_rule(action=ACLAction.PERMIT, src_port=Port.ARP, dst_port=Port.ARP, position=22)
|
||||
|
||||
router_1.acl.add_rule(action=ACLAction.PERMIT, protocol=IPProtocol.ICMP, position=23)
|
||||
return pc_a, pc_b, router_1
|
||||
|
||||
|
||||
def test_ping_default_gateway(pc_a_pc_b_router_1):
|
||||
pc_a, pc_b, router_1 = pc_a_pc_b_router_1
|
||||
|
||||
assert pc_a.ping(pc_a.default_gateway)
|
||||
|
||||
|
||||
def test_ping_other_router_port(pc_a_pc_b_router_1):
|
||||
pc_a, pc_b, router_1 = pc_a_pc_b_router_1
|
||||
|
||||
assert pc_a.ping(pc_b.default_gateway)
|
||||
|
||||
|
||||
def test_host_on_other_subnet(pc_a_pc_b_router_1):
|
||||
pc_a, pc_b, router_1 = pc_a_pc_b_router_1
|
||||
|
||||
assert pc_a.ping("192.168.1.10")
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
from ipaddress import IPv4Address
|
||||
|
||||
from primaite.simulator.network.hardware.nodes.router import AccessControlList, ACLAction, ACLRule
|
||||
from primaite.simulator.network.transmission.network_layer import IPProtocol
|
||||
from primaite.simulator.network.transmission.transport_layer import Port
|
||||
|
||||
|
||||
def test_add_rule():
|
||||
acl = AccessControlList()
|
||||
acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
src_ip=IPv4Address("192.168.1.1"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.2"),
|
||||
dst_port=Port(80),
|
||||
position=1,
|
||||
)
|
||||
assert acl.acl[1].action == ACLAction.PERMIT
|
||||
assert acl.acl[1].protocol == IPProtocol.TCP
|
||||
assert acl.acl[1].src_ip == IPv4Address("192.168.1.1")
|
||||
assert acl.acl[1].src_port == Port(8080)
|
||||
assert acl.acl[1].dst_ip == IPv4Address("192.168.1.2")
|
||||
assert acl.acl[1].dst_port == Port(80)
|
||||
|
||||
|
||||
def test_remove_rule():
|
||||
acl = AccessControlList()
|
||||
acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
src_ip=IPv4Address("192.168.1.1"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.2"),
|
||||
dst_port=Port(80),
|
||||
position=1,
|
||||
)
|
||||
acl.remove_rule(1)
|
||||
assert not acl.acl[1]
|
||||
|
||||
|
||||
def test_rules():
|
||||
acl = AccessControlList()
|
||||
acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
src_ip=IPv4Address("192.168.1.1"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.2"),
|
||||
dst_port=Port(80),
|
||||
position=1,
|
||||
)
|
||||
acl.add_rule(
|
||||
action=ACLAction.DENY,
|
||||
protocol=IPProtocol.TCP,
|
||||
src_ip=IPv4Address("192.168.1.3"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.4"),
|
||||
dst_port=Port(80),
|
||||
position=2,
|
||||
)
|
||||
assert acl.is_permitted(
|
||||
protocol=IPProtocol.TCP,
|
||||
src_ip=IPv4Address("192.168.1.1"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.2"),
|
||||
dst_port=Port(80),
|
||||
)
|
||||
assert not acl.is_permitted(
|
||||
protocol=IPProtocol.TCP,
|
||||
src_ip=IPv4Address("192.168.1.3"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.4"),
|
||||
dst_port=Port(80),
|
||||
)
|
||||
|
||||
|
||||
def test_default_rule():
|
||||
acl = AccessControlList()
|
||||
acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
src_ip=IPv4Address("192.168.1.1"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.2"),
|
||||
dst_port=Port(80),
|
||||
position=1,
|
||||
)
|
||||
acl.add_rule(
|
||||
action=ACLAction.DENY,
|
||||
protocol=IPProtocol.TCP,
|
||||
src_ip=IPv4Address("192.168.1.3"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.4"),
|
||||
dst_port=Port(80),
|
||||
position=2,
|
||||
)
|
||||
assert not acl.is_permitted(
|
||||
protocol=IPProtocol.UDP,
|
||||
src_ip=IPv4Address("192.168.1.5"),
|
||||
src_port=Port(8080),
|
||||
dst_ip=IPv4Address("192.168.1.12"),
|
||||
dst_port=Port(80),
|
||||
)
|
||||
@@ -32,10 +32,8 @@ def test_nic_ip_address_type_conversion():
|
||||
nic = NIC(
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
gateway="192.168.0.1",
|
||||
)
|
||||
assert isinstance(nic.ip_address, IPv4Address)
|
||||
assert isinstance(nic.gateway, IPv4Address)
|
||||
|
||||
|
||||
def test_nic_deserialize():
|
||||
@@ -43,7 +41,6 @@ def test_nic_deserialize():
|
||||
nic = NIC(
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
gateway="192.168.0.1",
|
||||
)
|
||||
|
||||
nic_json = nic.model_dump_json()
|
||||
@@ -51,21 +48,10 @@ def test_nic_deserialize():
|
||||
assert nic == deserialized_nic
|
||||
|
||||
|
||||
def test_nic_ip_address_as_gateway_fails():
|
||||
"""Tests NIC creation fails if ip address is the same as the gateway."""
|
||||
with pytest.raises(ValueError):
|
||||
NIC(
|
||||
ip_address="192.168.0.1",
|
||||
subnet_mask="255.255.255.0",
|
||||
gateway="192.168.0.1",
|
||||
)
|
||||
|
||||
|
||||
def test_nic_ip_address_as_network_address_fails():
|
||||
"""Tests NIC creation fails if ip address and subnet mask are a network address."""
|
||||
with pytest.raises(ValueError):
|
||||
NIC(
|
||||
ip_address="192.168.0.0",
|
||||
subnet_mask="255.255.255.0",
|
||||
gateway="192.168.0.1",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user