Merge remote-tracking branch 'devops/dev' into feature/1801-Database
# Conflicts: # src/primaite/simulator/network/container.py # src/primaite/simulator/network/hardware/base.py
This commit is contained in:
@@ -14,20 +14,19 @@ Pre-Requisites
|
||||
In order to get **PrimAITE** installed, you will need to have a python version between 3.8 and 3.10 installed. If you don't already have it, this is how to install it:
|
||||
|
||||
|
||||
.. tabs:: lang
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix
|
||||
sudo add-apt-repository ppa:deadsnakes/ppa
|
||||
sudo apt install python3.10
|
||||
sudo apt-get install python3-pip
|
||||
sudo apt-get install python3-venv
|
||||
|
||||
sudo add-apt-repository ppa:deadsnakes/ppa
|
||||
sudo apt install python3.10
|
||||
sudo apt-get install python3-pip
|
||||
sudo apt-get install python3-venv
|
||||
|
||||
.. code-tab:: text
|
||||
:caption: Windows (Powershell)
|
||||
.. code-block:: text
|
||||
:caption: Windows (Powershell)
|
||||
|
||||
- Manual install from: https://www.python.org/downloads/release/python-31011/
|
||||
- Manual install from: https://www.python.org/downloads/release/python-31011/
|
||||
|
||||
**PrimAITE** is designed to be OS-agnostic, and thus should work on most variations/distros of Linux, Windows, and MacOS.
|
||||
|
||||
@@ -36,30 +35,30 @@ Install PrimAITE
|
||||
|
||||
1. Create a primaite directory in your home directory:
|
||||
|
||||
.. tabs:: lang
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix
|
||||
|
||||
mkdir ~/primaite/2.0.0
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
mkdir ~/primaite/2.0.0
|
||||
|
||||
mkdir ~\primaite\2.0.0
|
||||
.. code-block:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
|
||||
mkdir ~\primaite\2.0.0
|
||||
|
||||
2. Navigate to the primaite directory and create a new python virtual environment (venv)
|
||||
|
||||
.. tabs:: lang
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix
|
||||
|
||||
cd ~/primaite/2.0.0
|
||||
python3 -m venv .venv
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
cd ~/primaite/2.0.0
|
||||
python3 -m venv .venv
|
||||
|
||||
.. code-block:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
|
||||
cd ~\primaite\2.0.0
|
||||
python3 -m venv .venv
|
||||
@@ -67,44 +66,41 @@ Install PrimAITE
|
||||
|
||||
3. Activate the venv
|
||||
|
||||
.. tabs:: lang
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
|
||||
source .venv/bin/activate
|
||||
source .venv/bin/activate
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
.. code-block:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
|
||||
.\.venv\Scripts\activate
|
||||
.\.venv\Scripts\activate
|
||||
|
||||
|
||||
4. Install PrimAITE using pip from PyPi
|
||||
|
||||
.. tabs:: lang
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
|
||||
pip install primaite
|
||||
pip install primaite
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
.. code-block:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
|
||||
pip install primaite
|
||||
pip install primaite
|
||||
|
||||
5. Perform the PrimAITE setup
|
||||
|
||||
.. tabs:: lang
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
|
||||
primaite setup
|
||||
primaite setup
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
.. code-block:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
|
||||
primaite setup
|
||||
|
||||
@@ -123,33 +119,31 @@ of your choice:
|
||||
|
||||
Create and activate your Python virtual environment (venv)
|
||||
|
||||
.. tabs:: lang
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
.. code-block:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
|
||||
python3 -m venv venv
|
||||
.\venv\Scripts\activate
|
||||
python3 -m venv venv
|
||||
.\venv\Scripts\activate
|
||||
|
||||
Install PrimAITE with the dev extra
|
||||
|
||||
.. tabs:: lang
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix
|
||||
.. code-block:: bash
|
||||
:caption: Unix
|
||||
|
||||
pip install -e .[dev]
|
||||
pip install -e .[dev]
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
.. code-block:: powershell
|
||||
:caption: Windows (Powershell)
|
||||
|
||||
pip install -e .[dev]
|
||||
pip install -e .[dev]
|
||||
|
||||
|
||||
To view the complete list of packages installed during PrimAITE installation, go to the dependencies page (:ref:`Dependencies`).
|
||||
|
||||
@@ -15,31 +15,31 @@ A PrimAITE session can be ran either with the ``primaite session`` command from
|
||||
Both the ``primaite session`` and :func:`primaite.main.run` take a training config and a lay down config as parameters.
|
||||
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix CLI
|
||||
|
||||
cd ~/primaite/2.0.0
|
||||
source ./.venv/bin/activate
|
||||
primaite session --tc ./config/my_training_config.yaml --ldc ./config/my_lay_down_config.yaml
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Powershell CLI
|
||||
|
||||
cd ~\primaite\2.0.0
|
||||
.\.venv\Scripts\activate
|
||||
primaite session --tc .\config\my_training_config.yaml --ldc .\config\my_lay_down_config.yaml
|
||||
|
||||
|
||||
.. code-tab:: python
|
||||
:caption: Python
|
||||
.. code-block:: bash
|
||||
:caption: Unix CLI
|
||||
|
||||
from primaite.main import run
|
||||
cd ~/primaite/2.0.0
|
||||
source ./.venv/bin/activate
|
||||
primaite session --tc ./config/my_training_config.yaml --ldc ./config/my_lay_down_config.yaml
|
||||
|
||||
training_config = <path to training config yaml file>
|
||||
lay_down_config = <path to lay down config yaml file>
|
||||
run(training_config, lay_down_config)
|
||||
.. code-block:: powershell
|
||||
:caption: Powershell CLI
|
||||
|
||||
cd ~\primaite\2.0.0
|
||||
.\.venv\Scripts\activate
|
||||
primaite session --tc .\config\my_training_config.yaml --ldc .\config\my_lay_down_config.yaml
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
:caption: Python
|
||||
|
||||
from primaite.main import run
|
||||
|
||||
training_config = <path to training config yaml file>
|
||||
lay_down_config = <path to lay down config yaml file>
|
||||
run(training_config, lay_down_config)
|
||||
|
||||
When a session is ran, a session output sub-directory is created in the users app sessions directory (``~/primaite/2.0.0/sessions``).
|
||||
The sub-directory is formatted as such: ``~/primaite/2.0.0/sessions/<yyyy-mm-dd>/<yyyy-mm-dd>_<hh-mm-dd>/``
|
||||
@@ -51,31 +51,33 @@ For example, when running a session at 17:30:00 on 31st January 2023, the sessio
|
||||
|
||||
To run a PrimAITE session using legacy training or laydown config files, add the ``--legacy-tc`` and/or ``legacy-ldc`` options.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: bash
|
||||
:caption: Unix CLI
|
||||
|
||||
cd ~/primaite/2.0.0
|
||||
source ./.venv/bin/activate
|
||||
primaite session --tc ./config/my_legacy_training_config.yaml --legacy-tc --ldc ./config/my_legacy_lay_down_config.yaml --legacy-ldc
|
||||
|
||||
.. code-tab:: powershell
|
||||
:caption: Powershell CLI
|
||||
|
||||
cd ~\primaite\2.0.0
|
||||
.\.venv\Scripts\activate
|
||||
primaite session --tc .\config\my_legacy_training_config.yaml --legacy-tc --ldc .\config\my_legacy_lay_down_config.yaml --legacy-ldc
|
||||
|
||||
|
||||
.. code-tab:: python
|
||||
:caption: Python
|
||||
.. code-block:: bash
|
||||
:caption: Unix CLI
|
||||
|
||||
cd ~/primaite/2.0.0
|
||||
source ./.venv/bin/activate
|
||||
primaite session --tc ./config/my_legacy_training_config.yaml --legacy-tc --ldc ./config/my_legacy_lay_down_config.yaml --legacy-ldc
|
||||
|
||||
.. code-block:: powershell
|
||||
:caption: Powershell CLI
|
||||
|
||||
cd ~\primaite\2.0.0
|
||||
.\.venv\Scripts\activate
|
||||
primaite session --tc .\config\my_legacy_training_config.yaml --legacy-tc --ldc .\config\my_legacy_lay_down_config.yaml --legacy-ldc
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
:caption: Python
|
||||
|
||||
from primaite.main import run
|
||||
|
||||
training_config = <path to legacy training config yaml file>
|
||||
lay_down_config = <path to legacy lay down config yaml file>
|
||||
run(training_config, lay_down_config, legacy_training_config=True, legacy_lay_down_config=True)
|
||||
|
||||
from primaite.main import run
|
||||
|
||||
training_config = <path to legacy training config yaml file>
|
||||
lay_down_config = <path to legacy lay down config yaml file>
|
||||
run(training_config, lay_down_config, legacy_training_config=True, legacy_lay_down_config=True)
|
||||
|
||||
|
||||
Outputs
|
||||
|
||||
@@ -18,3 +18,6 @@ Contents
|
||||
simulation_structure
|
||||
simulation_components/network/base_hardware
|
||||
simulation_components/network/transport_to_data_link_layer
|
||||
simulation_components/network/router
|
||||
simulation_components/network/switch
|
||||
simulation_components/network/network
|
||||
|
||||
115
docs/source/simulation_components/network/network.rst
Normal file
115
docs/source/simulation_components/network/network.rst
Normal file
@@ -0,0 +1,115 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2023, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _about:
|
||||
|
||||
Network
|
||||
=======
|
||||
|
||||
The ``Network`` class serves as the backbone of the simulation. It offers a framework to manage various network
|
||||
components such as routers, switches, servers, and clients. This document provides a detailed explanation of how to
|
||||
effectively use the ``Network`` class.
|
||||
|
||||
Example Usage
|
||||
-------------
|
||||
|
||||
Below demonstrates how to use the Router node to connect Nodes, and block traffic using ACLs. For this demonstration,
|
||||
we'll use the following Network that has a client, server, two switches, and a router.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
+------------+ +------------+ +------------+ +------------+ +------------+
|
||||
| | | | | | | | | |
|
||||
| client_1 +------+ switch_2 +------+ router_1 +------+ switch_1 +------+ server_1 |
|
||||
| | | | | | | | | |
|
||||
+------------+ +------------+ +------------+ +------------+ +------------+
|
||||
|
||||
1. Relevant imports
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from primaite.simulator.network.container import Network
|
||||
from primaite.simulator.network.hardware.base import NIC
|
||||
from primaite.simulator.network.hardware.nodes.computer import Computer
|
||||
from primaite.simulator.network.hardware.nodes.router import Router, ACLAction
|
||||
from primaite.simulator.network.hardware.nodes.server import Server
|
||||
from primaite.simulator.network.hardware.nodes.switch import Switch
|
||||
from primaite.simulator.network.transmission.network_layer import IPProtocol
|
||||
from primaite.simulator.network.transmission.transport_layer import Port
|
||||
|
||||
2. Create the Network
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
network = Network()
|
||||
|
||||
3. Create and configure the Router
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
router_1 = Router(hostname="router_1", num_ports=3)
|
||||
router_1.power_on()
|
||||
router_1.configure_port(port=1, ip_address="192.168.1.1", subnet_mask="255.255.255.0")
|
||||
router_1.configure_port(port=2, ip_address="192.168.2.1", subnet_mask="255.255.255.0")
|
||||
|
||||
4. Create and configure the two Switches
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
switch_1 = Switch(hostname="switch_1", num_ports=6)
|
||||
switch_1.power_on()
|
||||
switch_2 = Switch(hostname="switch_2", num_ports=6)
|
||||
switch_2.power_on()
|
||||
|
||||
5. Connect the Switches to the Router
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
network.connect(endpoint_a=router_1.ethernet_ports[1], endpoint_b=switch_1.switch_ports[6])
|
||||
router_1.enable_port(1)
|
||||
network.connect(endpoint_a=router_1.ethernet_ports[2], endpoint_b=switch_2.switch_ports[6])
|
||||
router_1.enable_port(2)
|
||||
|
||||
6. Create the Client and Server nodes.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
client_1 = Computer(
|
||||
hostname="client_1",
|
||||
ip_address="192.168.2.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.2.1"
|
||||
)
|
||||
client_1.power_on()
|
||||
server_1 = Server(
|
||||
hostname="server_1",
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.1.1"
|
||||
)
|
||||
server_1.power_on()
|
||||
|
||||
7. Connect the Client and Server to the relevant Switch
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
network.connect(endpoint_a=switch_2.switch_ports[1], endpoint_b=client_1.ethernet_port[1])
|
||||
network.connect(endpoint_a=switch_1.switch_ports[1], endpoint_b=server_1.ethernet_port[1])
|
||||
|
||||
8. Add ACL rules on the Router to allow ARP and ICMP traffic.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
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
|
||||
)
|
||||
73
docs/source/simulation_components/network/router.rst
Normal file
73
docs/source/simulation_components/network/router.rst
Normal file
@@ -0,0 +1,73 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2023, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _about:
|
||||
|
||||
Router Module
|
||||
=============
|
||||
|
||||
The router module contains classes for simulating the functions of a network router.
|
||||
|
||||
Router
|
||||
------
|
||||
|
||||
The Router class represents a multi-port network router that can receive, process, and route network packets between its ports and other Nodes
|
||||
|
||||
The router maintains internal state including:
|
||||
|
||||
- RouteTable - Routing table to lookup where to forward packets.
|
||||
- AccessControlList - Access control rules to block or allow packets.
|
||||
- ARP cache - MAC address lookups for connected devices.
|
||||
- ICMP handler - Handles ICMP requests to router interfaces.
|
||||
|
||||
The router receives incoming frames on enabled ports. It processes the frame headers and applies the following logic:
|
||||
|
||||
1. Checks the AccessControlList if the packet is permitted. If blocked, it is dropped.
|
||||
2. For permitted packets, routes the frame based on:
|
||||
- ARP cache lookups for destination MAC address.
|
||||
- ICMP echo requests handled directly.
|
||||
- RouteTable lookup to forward packet out other ports.
|
||||
3. Updates ARP cache as it learns new information about the Network.
|
||||
|
||||
|
||||
|
||||
RouteTable
|
||||
----------
|
||||
|
||||
The RouteTable holds RouteEntry objects representing routes. It finds the best route for a destination IP using a metric and the longest prefix match algorithm.
|
||||
|
||||
Routes can be added and looked up based on destination IP address. The RouteTable is used by the Router when forwarding packets between other Nodes.
|
||||
|
||||
AccessControlList
|
||||
-----------------
|
||||
|
||||
The AccessControlList defines Access Control Rules to block or allow packets. Packets are checked against the rules to determine if they are permitted to be forwarded.
|
||||
|
||||
Rules can be added to deny or permit traffic based on IP, port, and protocol. The ACL is checked by the Router when packets are received.
|
||||
|
||||
Packet Processing
|
||||
-----------------
|
||||
|
||||
-The Router supports the following protocols and packet types:
|
||||
|
||||
ARP
|
||||
^^^
|
||||
|
||||
- Handles both ARP requests and responses.
|
||||
- Updates ARP cache.
|
||||
- Proxies ARP replies for connected networks.
|
||||
- Routes ARP requests.
|
||||
|
||||
ICMP
|
||||
^^^^
|
||||
|
||||
- Responds to ICMP echo requests to Router interfaces.
|
||||
- Routes other ICMP messages based on routes.
|
||||
|
||||
TCP/UDP
|
||||
^^^^^^^
|
||||
|
||||
- Forwards packets based on routes like IP.
|
||||
- Applies ACL rules based on protocol, source/destination IP address, and source/destination port numbers.
|
||||
- Decrements TTL and drops expired TTL packets.
|
||||
@@ -64,9 +64,9 @@ Data Link Layer (Layer 2)
|
||||
|
||||
- **request:** ARP operation. Set to True for a request and False for a reply.
|
||||
- **sender_mac_addr:** Sender's MAC address.
|
||||
- **sender_ip:** Sender's IP address (IPv4 format).
|
||||
- **sender_ip_address:** Sender's IP address (IPv4 format).
|
||||
- **target_mac_addr:** Target's MAC address.
|
||||
- **target_ip:** Target's IP address (IPv4 format).
|
||||
- **target_ip_address:** Target's IP address (IPv4 format).
|
||||
|
||||
**EthernetHeader:** Represents the Ethernet layer of a network frame. It includes source and destination MAC addresses.
|
||||
This header is used to identify the physical hardware addresses of devices on a local network.
|
||||
@@ -102,8 +102,8 @@ address of 'aa:bb:cc:dd:ee:ff' to port 8080 on the host 10.0.0.10 which has a NI
|
||||
|
||||
# Network Layer
|
||||
ip_packet = IPPacket(
|
||||
src_ip="192.168.0.100",
|
||||
dst_ip="10.0.0.10",
|
||||
src_ip_address="192.168.0.100",
|
||||
dst_ip_address="10.0.0.10",
|
||||
protocol=IPProtocol.TCP
|
||||
)
|
||||
# Data Link Layer
|
||||
@@ -128,8 +128,8 @@ This produces the following ``Frame`` (displayed in json format)
|
||||
"dst_mac_addr": "11:22:33:44:55:66"
|
||||
},
|
||||
"ip": {
|
||||
"src_ip": "192.168.0.100",
|
||||
"dst_ip": "10.0.0.10",
|
||||
"src_ip_address": "192.168.0.100",
|
||||
"dst_ip_address": "10.0.0.10",
|
||||
"protocol": "tcp",
|
||||
"ttl": 64,
|
||||
"precedence": 0
|
||||
|
||||
Reference in New Issue
Block a user