#1724 - Added documentation for the transport layer down to data link layer
This commit is contained in:
@@ -17,3 +17,4 @@ Contents
|
|||||||
|
|
||||||
simulation_structure
|
simulation_structure
|
||||||
simulation_components/network/physical_layer
|
simulation_components/network/physical_layer
|
||||||
|
simulation_components/network/transport_to_data_link_layer
|
||||||
|
|||||||
@@ -0,0 +1,135 @@
|
|||||||
|
.. only:: comment
|
||||||
|
|
||||||
|
© Crown-owned copyright 2023, Defence Science and Technology Laboratory UK
|
||||||
|
|
||||||
|
Transport Layer to Data Link Layer
|
||||||
|
==================================
|
||||||
|
|
||||||
|
From the `OSI Model <[OSI Model](https://en.wikipedia.org/wiki/OSI_model,>`_, the transport layer (layer 4) through to
|
||||||
|
the data link layer (layer 2) have been loosely modelled to provide somewhat realistic network Frame generation.
|
||||||
|
|
||||||
|
Transport Layer (Layer 4)
|
||||||
|
#########################
|
||||||
|
|
||||||
|
**UDPHeader:** Represents a UDP header for the transport layer of a Network Frame. It includes source and destination
|
||||||
|
ports. UDP (User Datagram Protocol) is a connectionless and unreliable transport protocol used for data transmission.
|
||||||
|
|
||||||
|
**TCPFlags:** Enum representing TCP control flags used in a TCP connection, such as SYN, ACK, FIN, and RST. TCP
|
||||||
|
(Transmission Control Protocol) is a connection-oriented and reliable transport protocol used for establishing and
|
||||||
|
maintaining data streams.
|
||||||
|
|
||||||
|
**TCPHeader:** Represents a TCP header for the transport layer of a Network Frame. It includes source and destination
|
||||||
|
ports and TCP flags. This header is used for establishing and managing TCP connections.
|
||||||
|
|
||||||
|
Network Layer (Layer 3)
|
||||||
|
#######################
|
||||||
|
|
||||||
|
|
||||||
|
**IPProtocol:** Enum representing transport layer protocols in the IP header, such as TCP, UDP, and ICMP. It is used to
|
||||||
|
indicate the type of transport layer protocol being used in the IP header.
|
||||||
|
|
||||||
|
**Precedence:** Enum representing the Precedence levels in Quality of Service (QoS) for IP packets. It is used to
|
||||||
|
specify the priority of IP packets for Quality of Service handling.
|
||||||
|
|
||||||
|
**ICMPType:** Enumeration of common ICMP (Internet Control Message Protocol) types. It defines various types of ICMP
|
||||||
|
messages used for network troubleshooting and error reporting.
|
||||||
|
|
||||||
|
**ICMPHeader:** Models an ICMP header and includes ICMP type, code, identifier, and sequence number. It is used to
|
||||||
|
create ICMP packets for network control and error reporting.
|
||||||
|
|
||||||
|
**IPPacket:** Represents the IP layer of a network frame. It includes source and destination IP addresses, protocol
|
||||||
|
(TCP/UDP/ICMP), Time to Live (TTL), and Precedence for QoS. This header is used to route data packets across the
|
||||||
|
network based on IP addresses.
|
||||||
|
|
||||||
|
|
||||||
|
PrimAITE Layer (Custom Layer)
|
||||||
|
#############################
|
||||||
|
|
||||||
|
The PrimAITE layer has a custom header represented by the ``PrimaiteHeader`` class. It is designed to carry
|
||||||
|
PrimAITE-specific metadata required for reinforcement learning (RL) purposes.
|
||||||
|
|
||||||
|
**PrimaiteHeader:** This is a custom header for carrying PrimAITE-specific metadata. It contains the following fields:
|
||||||
|
- **agent_source:** Enum representing the agent source of the transmission, such as RED, GREEN, or BLUE. This field helps identify the source or category of the data transmission.
|
||||||
|
- **data_status:** Enum representing the status of the data in transmission, such as GOOD, COMPROMISED, or CORRUPT. This field indicates the integrity of the data being transmitted.
|
||||||
|
|
||||||
|
Data Link Layer (Layer 2)
|
||||||
|
#########################
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|
||||||
|
**Frame:** Represents a complete network frame with all layers. It includes an ``EthernetHeader``, an ``IPPacket``, an
|
||||||
|
optional ``TCPHeader``, ``UDPHeader``, or ``ICMPHeader``, a ``PrimaiteHeader`` and an optional payload. This class
|
||||||
|
combines all the headers and data to create a complete network frame that can be sent over the network and used in the
|
||||||
|
PrimAITE simulation.
|
||||||
|
|
||||||
|
Basic Usage
|
||||||
|
###########
|
||||||
|
|
||||||
|
TCP SYN Frame
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Here we will model a TCP synchronize request from a port 80 on the host 192.168.0.100 which has a NIC with a MAC
|
||||||
|
address of 'aa:bb:cc:dd:ee:ff' to port 8080 on the host 10.0.0.10 which has a NIC with a MAC address of
|
||||||
|
'11:22:33:44:55:66'.
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from primaite.simulator.network.transmission.data_link_layer import EthernetHeader, Frame
|
||||||
|
from primaite.simulator.network.transmission.network_layer import IPPacket, IPProtocol
|
||||||
|
from primaite.simulator.network.transmission.transport_layer import TCPFlags, TCPHeader
|
||||||
|
|
||||||
|
# Transport Layer
|
||||||
|
tcp_header = TCPHeader(
|
||||||
|
src_port=80,
|
||||||
|
dst_port=8080,
|
||||||
|
flags=[TCPFlags.SYN]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Network Layer
|
||||||
|
ip_packet = IPPacket(
|
||||||
|
src_ip="192.168.0.100",
|
||||||
|
dst_ip="10.0.0.10",
|
||||||
|
protocol=IPProtocol.TCP
|
||||||
|
)
|
||||||
|
# Data Link Layer
|
||||||
|
ethernet_header = EthernetHeader(
|
||||||
|
src_mac_addr="aa:bb:cc:dd:ee:ff",
|
||||||
|
dst_mac_addr="11:22:33:44:55:66"
|
||||||
|
)
|
||||||
|
|
||||||
|
frame = Frame(
|
||||||
|
ethernet=ethernet_header,
|
||||||
|
ip=ip_packet,
|
||||||
|
tcp=tcp_header,
|
||||||
|
)
|
||||||
|
|
||||||
|
This produces the following ``Frame`` (displayed in json format)
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"ethernet": {
|
||||||
|
"src_mac_addr": "aa:bb:cc:dd:ee:ff",
|
||||||
|
"dst_mac_addr": "11:22:33:44:55:66"
|
||||||
|
},
|
||||||
|
"ip": {
|
||||||
|
"src_ip": "192.168.0.100",
|
||||||
|
"dst_ip": "10.0.0.10",
|
||||||
|
"protocol": "tcp",
|
||||||
|
"ttl": 64,
|
||||||
|
"precedence": 0
|
||||||
|
},
|
||||||
|
"tcp": {
|
||||||
|
"src_port": 80,
|
||||||
|
"dst_port": 8080,
|
||||||
|
"flags": [
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primaite": {
|
||||||
|
"agent_source": 2,
|
||||||
|
"data_status": 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -89,12 +89,12 @@ class Frame(BaseModel):
|
|||||||
"UDP header."
|
"UDP header."
|
||||||
icmp: Optional[ICMPHeader] = None
|
icmp: Optional[ICMPHeader] = None
|
||||||
"ICMP header."
|
"ICMP header."
|
||||||
primaite_header: PrimaiteHeader = PrimaiteHeader()
|
primaite: PrimaiteHeader = PrimaiteHeader()
|
||||||
"PrimAITE header."
|
"PrimAITE header."
|
||||||
payload: Optional[Any] = None
|
payload: Optional[Any] = None
|
||||||
"Raw data payload."
|
"Raw data payload."
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def size(self) -> int:
|
def size(self) -> int:
|
||||||
"""The size of the Frame in Bytes."""
|
"""The size in Bytes."""
|
||||||
return len(self.model_dump_json().encode("utf-8"))
|
return len(self.model_dump_json().encode("utf-8"))
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|||||||
import re
|
import re
|
||||||
import secrets
|
import secrets
|
||||||
from ipaddress import IPv4Address, IPv4Network
|
from ipaddress import IPv4Address, IPv4Network
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Dict, List, Optional
|
||||||
|
|
||||||
from primaite import getLogger
|
from primaite import getLogger
|
||||||
from primaite.exceptions import NetworkError
|
from primaite.exceptions import NetworkError
|
||||||
@@ -221,16 +221,19 @@ class Link(SimComponent):
|
|||||||
current_load: int = 0
|
current_load: int = 0
|
||||||
"The current load on the link in Mbps."
|
"The current load on the link in Mbps."
|
||||||
|
|
||||||
def model_post_init(self, __context: Any) -> None:
|
def __init__(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Ensure that endpoint_a and endpoint_b are not the same NIC.
|
Ensure that endpoint_a and endpoint_b are not the same NIC.
|
||||||
|
|
||||||
|
Connect the link to the NICs after creation.
|
||||||
|
|
||||||
:raises ValueError: If endpoint_a and endpoint_b are the same NIC.
|
:raises ValueError: If endpoint_a and endpoint_b are the same NIC.
|
||||||
"""
|
"""
|
||||||
if self.endpoint_a == self.endpoint_b:
|
if kwargs["endpoint_a"] == kwargs["endpoint_b"]:
|
||||||
msg = "endpoint_a and endpoint_b cannot be the same NIC"
|
msg = "endpoint_a and endpoint_b cannot be the same NIC"
|
||||||
_LOGGER.error(msg)
|
_LOGGER.error(msg)
|
||||||
raise ValueError(msg)
|
raise ValueError(msg)
|
||||||
|
super().__init__(**kwargs)
|
||||||
self.endpoint_a.connect_link(self)
|
self.endpoint_a.connect_link(self)
|
||||||
self.endpoint_b.connect_link(self)
|
self.endpoint_b.connect_link(self)
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ def test_frame_minimal_instantiation():
|
|||||||
assert frame.tcp.flags == [TCPFlags.SYN]
|
assert frame.tcp.flags == [TCPFlags.SYN]
|
||||||
|
|
||||||
# Check primaite custom header default values
|
# Check primaite custom header default values
|
||||||
assert frame.primaite_header.agent_source == AgentSource.GREEN
|
assert frame.primaite.agent_source == AgentSource.GREEN
|
||||||
assert frame.primaite_header.data_status == DataStatus.GOOD
|
assert frame.primaite.data_status == DataStatus.GOOD
|
||||||
|
|
||||||
# Check that model can be dumped down to json and returned as size in Bytes
|
# Check that model can be dumped down to json and returned as size in Bytes
|
||||||
assert frame.size
|
assert frame.size
|
||||||
|
|||||||
Reference in New Issue
Block a user