diff --git a/docs/source/simulation_components/network/nodes/firewall.rst b/docs/source/simulation_components/network/nodes/firewall.rst index f2d7e61a..73151db4 100644 --- a/docs/source/simulation_components/network/nodes/firewall.rst +++ b/docs/source/simulation_components/network/nodes/firewall.rst @@ -156,8 +156,8 @@ To prevent all external traffic from accessing the internal network, with except # Exception rule to allow HTTP traffic from external to internal network firewall.internal_inbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], - dst_port=Port["HTTP"], + protocol=PROTOCOL_LOOKUP["TCP"], + dst_port=PORT_LOOKUP["HTTP"], dst_ip_address="192.168.1.0", dst_wildcard_mask="0.0.0.255", position=2 @@ -172,16 +172,16 @@ To enable external traffic to access specific services hosted within the DMZ: # Allow HTTP and HTTPS traffic to the DMZ firewall.dmz_inbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], - dst_port=Port["HTTP"], + protocol=PROTOCOL_LOOKUP["TCP"], + dst_port=PORT_LOOKUP["HTTP"], dst_ip_address="172.16.0.0", dst_wildcard_mask="0.0.0.255", position=3 ) firewall.dmz_inbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], - dst_port=Port["HTTPS"], + protocol=PROTOCOL_LOOKUP["TCP"], + dst_port=PORT_LOOKUP["HTTPS"], dst_ip_address="172.16.0.0", dst_wildcard_mask="0.0.0.255", position=4 @@ -196,9 +196,9 @@ To permit SSH access from a designated external IP to a specific server within t # Allow SSH from a specific external IP to an internal server firewall.internal_inbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], + protocol=PROTOCOL_LOOKUP["TCP"], src_ip_address="10.0.0.2", - dst_port=Port["SSH"], + dst_port=PORT_LOOKUP["SSH"], dst_ip_address="192.168.1.10", position=5 ) @@ -212,9 +212,9 @@ To limit database server access to selected external IP addresses: # Allow PostgreSQL traffic from an authorized external IP to the internal DB server firewall.internal_inbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], + protocol=PROTOCOL_LOOKUP["TCP"], src_ip_address="10.0.0.3", - dst_port=Port["POSTGRES_SERVER"], + dst_port=PORT_LOOKUP["POSTGRES_SERVER"], dst_ip_address="192.168.1.20", position=6 ) @@ -222,8 +222,8 @@ To limit database server access to selected external IP addresses: # Deny all other PostgreSQL traffic from external sources firewall.internal_inbound_acl.add_rule( action=ACLAction.DENY, - protocol=IPProtocol["TCP"], - dst_port=Port["POSTGRES_SERVER"], + protocol=PROTOCOL_LOOKUP["TCP"], + dst_port=PORT_LOOKUP["POSTGRES_SERVER"], dst_ip_address="192.168.1.0", dst_wildcard_mask="0.0.0.255", position=7 @@ -247,15 +247,15 @@ To authorize HTTP/HTTPS access to a DMZ-hosted web server, excluding known malic # Allow HTTP/HTTPS traffic to the DMZ web server firewall.dmz_inbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], - dst_port=Port["HTTP"], + protocol=PROTOCOL_LOOKUP["TCP"], + dst_port=PORT_LOOKUP["HTTP"], dst_ip_address="172.16.0.2", position=9 ) firewall.dmz_inbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], - dst_port=Port["HTTPS"], + protocol=PROTOCOL_LOOKUP["TCP"], + dst_port=PORT_LOOKUP["HTTPS"], dst_ip_address="172.16.0.2", position=10 ) @@ -269,9 +269,9 @@ To facilitate restricted access from the internal network to DMZ-hosted services # Permit specific internal application server HTTPS access to a DMZ-hosted API firewall.internal_outbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], + protocol=PROTOCOL_LOOKUP["TCP"], src_ip_address="192.168.1.30", # Internal application server IP - dst_port=Port["HTTPS"], + dst_port=PORT_LOOKUP["HTTPS"], dst_ip_address="172.16.0.3", # DMZ API server IP position=11 ) @@ -289,9 +289,9 @@ To facilitate restricted access from the internal network to DMZ-hosted services # Corresponding rule in DMZ inbound ACL to allow the traffic from the specific internal server firewall.dmz_inbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], + protocol=PROTOCOL_LOOKUP["TCP"], src_ip_address="192.168.1.30", # Ensuring this specific source is allowed - dst_port=Port["HTTPS"], + dst_port=PORT_LOOKUP["HTTPS"], dst_ip_address="172.16.0.3", # DMZ API server IP position=13 ) @@ -301,7 +301,7 @@ To facilitate restricted access from the internal network to DMZ-hosted services action=ACLAction.DENY, src_ip_address="192.168.1.0", src_wildcard_mask="0.0.0.255", - dst_port=Port["HTTPS"], + dst_port=PORT_LOOKUP["HTTPS"], dst_ip_address="172.16.0.3", # DMZ API server IP position=14 ) @@ -315,8 +315,8 @@ To block all SSH access attempts from the external network: # Deny all SSH traffic from any external source firewall.external_inbound_acl.add_rule( action=ACLAction.DENY, - protocol=IPProtocol["TCP"], - dst_port=Port["SSH"], + protocol=PROTOCOL_LOOKUP["TCP"], + dst_port=PORT_LOOKUP["SSH"], position=1 ) @@ -329,8 +329,8 @@ To allow the internal network to initiate HTTP connections to the external netwo # Permit outgoing HTTP traffic from the internal network to any external destination firewall.external_outbound_acl.add_rule( action=ACLAction.PERMIT, - protocol=IPProtocol["TCP"], - dst_port=Port["HTTP"], + protocol=PROTOCOL_LOOKUP["TCP"], + dst_port=PORT_LOOKUP["HTTP"], position=2 ) diff --git a/docs/source/simulation_components/network/transport_to_data_link_layer.rst b/docs/source/simulation_components/network/transport_to_data_link_layer.rst index 54118c90..7d6fec2c 100644 --- a/docs/source/simulation_components/network/transport_to_data_link_layer.rst +++ b/docs/source/simulation_components/network/transport_to_data_link_layer.rst @@ -104,7 +104,7 @@ address of 'aa:bb:cc:dd:ee:ff' to port 8080 on the host 10.0.0.10 which has a NI ip_packet = IPPacket( src_ip_address="192.168.0.100", dst_ip_address="10.0.0.10", - protocol=IPProtocol["TCP"] + protocol=PROTOCOL_LOOKUP["TCP"] ) # Data Link Layer ethernet_header = EthernetHeader( diff --git a/docs/source/simulation_components/system/applications/nmap.rst b/docs/source/simulation_components/system/applications/nmap.rst index 06badf7e..cb879b15 100644 --- a/docs/source/simulation_components/system/applications/nmap.rst +++ b/docs/source/simulation_components/system/applications/nmap.rst @@ -167,8 +167,8 @@ Perform a horizontal port scan on port 5432 across multiple IP addresses: { IPv4Address('192.168.1.12'): { - : [ - + : [ + ] } } @@ -202,9 +202,9 @@ Perform a vertical port scan on multiple ports on a single IP address: { IPv4Address('192.168.1.12'): { - : [ - , - + : [ + , + ] } } @@ -243,15 +243,15 @@ Perform a box scan on multiple ports across multiple IP addresses: { IPv4Address('192.168.1.13'): { - : [ - , - + : [ + , + ] }, IPv4Address('192.168.1.12'): { - : [ - , - + : [ + , + ] } } @@ -291,36 +291,36 @@ Perform a full box scan on all ports, over both TCP and UDP, on a whole subnet: { IPv4Address('192.168.1.11'): { - : [ - + : [ + ] }, IPv4Address('192.168.1.1'): { - : [ - + : [ + ] }, IPv4Address('192.168.1.12'): { - : [ - , - , - , - + : [ + , + , + , + ], - : [ - , - + : [ + , + ] }, IPv4Address('192.168.1.13'): { - : [ - , - , - + : [ + , + , + ], - : [ - , - + : [ + , + ] } } diff --git a/docs/source/simulation_components/system/services/ftp_client.rst b/docs/source/simulation_components/system/services/ftp_client.rst index db425b92..be4d73e4 100644 --- a/docs/source/simulation_components/system/services/ftp_client.rst +++ b/docs/source/simulation_components/system/services/ftp_client.rst @@ -15,7 +15,7 @@ Key features - Connects to the :ref:`FTPServer` via the ``SoftwareManager``. - Simulates FTP requests and FTPPacket transfer across a network - Allows the emulation of FTP commands between an FTP client and server: - - PORT: specifies the port that server should connect to on the client (currently only uses ``Port["FTP"]``) + - PORT: specifies the port that server should connect to on the client (currently only uses ``PORT_LOOKUP["FTP"]``) - STOR: stores a file from client to server - RETR: retrieves a file from the FTP server - QUIT: disconnect from server diff --git a/src/primaite/simulator/network/hardware/nodes/network/firewall.py b/src/primaite/simulator/network/hardware/nodes/network/firewall.py index c872b8b3..d2716f08 100644 --- a/src/primaite/simulator/network/hardware/nodes/network/firewall.py +++ b/src/primaite/simulator/network/hardware/nodes/network/firewall.py @@ -57,8 +57,8 @@ class Firewall(Router, discriminator="firewall"): >>> # Permit HTTP traffic to the DMZ >>> firewall.dmz_inbound_acl.add_rule( ... action=ACLAction.PERMIT, - ... protocol=IPProtocol["TCP"], - ... dst_port=Port["HTTP"], + ... protocol=PROTOCOL_LOOKUP["TCP"], + ... dst_port=PORT_LOOKUP["HTTP"], ... src_ip_address="0.0.0.0", ... src_wildcard_mask="0.0.0.0", ... dst_ip_address="172.16.0.0", diff --git a/src/primaite/simulator/network/hardware/nodes/network/router.py b/src/primaite/simulator/network/hardware/nodes/network/router.py index 33b55b9d..db9eeabe 100644 --- a/src/primaite/simulator/network/hardware/nodes/network/router.py +++ b/src/primaite/simulator/network/hardware/nodes/network/router.py @@ -265,7 +265,7 @@ class AccessControlList(SimComponent): >>> acl = AccessControlList() >>> acl.add_rule( ... action=ACLAction.PERMIT, - ... protocol=IPProtocol["TCP"], + ... protocol=PROTOCOL_LOOKUP["TCP"], ... src_ip_address="192.168.1.0", ... src_wildcard_mask="0.0.0.255", ... dst_ip_address="192.168.2.0", @@ -399,11 +399,11 @@ class AccessControlList(SimComponent): >>> router = Router("router") >>> router.add_rule( ... action=ACLAction.DENY, - ... protocol=IPProtocol["TCP"], + ... protocol=PROTOCOL_LOOKUP["TCP"], ... src_ip_address="192.168.1.0", ... src_wildcard_mask="0.0.0.255", ... dst_ip_address="10.10.10.5", - ... dst_port=Port["SSH"], + ... dst_port=PORT_LOOKUP["SSH"], ... position=5 ... ) >>> # This permits SSH traffic from the 192.168.1.0/24 subnet to the 10.10.10.5 server. @@ -411,10 +411,10 @@ class AccessControlList(SimComponent): >>> # Then if we want to allow a specific IP address from this subnet to SSH into the server >>> router.add_rule( ... action=ACLAction.PERMIT, - ... protocol=IPProtocol["TCP"], + ... protocol=PROTOCOL_LOOKUP["TCP"], ... src_ip_address="192.168.1.25", ... dst_ip_address="10.10.10.5", - ... dst_port=Port["SSH"], + ... dst_port=PORT_LOOKUP["SSH"], ... position=4 ... ) diff --git a/src/primaite/simulator/network/transmission/network_layer.py b/src/primaite/simulator/network/transmission/network_layer.py index 7a6b34c9..6996be0d 100644 --- a/src/primaite/simulator/network/transmission/network_layer.py +++ b/src/primaite/simulator/network/transmission/network_layer.py @@ -61,7 +61,7 @@ class IPPacket(BaseModel): >>> ip_packet = IPPacket( ... src_ip_address=IPv4Address('192.168.0.1'), ... dst_ip_address=IPv4Address('10.0.0.1'), - ... protocol=IPProtocol["TCP"], + ... protocol=PROTOCOL_LOOKUP["TCP"], ... ttl=64, ... precedence=Precedence.CRITICAL ... ) diff --git a/src/primaite/simulator/network/transmission/transport_layer.py b/src/primaite/simulator/network/transmission/transport_layer.py index 689eea2f..fa258afa 100644 --- a/src/primaite/simulator/network/transmission/transport_layer.py +++ b/src/primaite/simulator/network/transmission/transport_layer.py @@ -15,8 +15,8 @@ class UDPHeader(BaseModel): :Example: >>> udp_header = UDPHeader( - ... src_port=Port["HTTP_ALT"], - ... dst_port=Port["HTTP"], + ... src_port=PORT_LOOKUP["HTTP_ALT"], + ... dst_port=PORT_LOOKUP["HTTP"], ... ) """ @@ -54,8 +54,8 @@ class TCPHeader(BaseModel): :Example: >>> tcp_header = TCPHeader( - ... src_port=Port["HTTP_ALT"], - ... dst_port=Port["HTTP"], + ... src_port=PORT_LOOKUP["HTTP_ALT"], + ... dst_port=PORT_LOOKUP["HTTP"], ... flags=[TCPFlags.SYN, TCPFlags.ACK] ... ) """ diff --git a/src/primaite/simulator/system/applications/red_applications/dos_bot.py b/src/primaite/simulator/system/applications/red_applications/dos_bot.py index 1528de57..5b9f0286 100644 --- a/src/primaite/simulator/system/applications/red_applications/dos_bot.py +++ b/src/primaite/simulator/system/applications/red_applications/dos_bot.py @@ -128,7 +128,7 @@ class DoSBot(DatabaseClient, discriminator="dos-bot"): Configure the Denial of Service bot. :param: target_ip_address: The IP address of the Node containing the target service. - :param: target_port: The port of the target service. Optional - Default is `Port["HTTP"]` + :param: target_port: The port of the target service. Optional - Default is `PORT_LOOKUP["HTTP"]` :param: payload: The payload the DoS Bot will throw at the target service. Optional - Default is `None` :param: repeat: If True, the bot will maintain the attack. Optional - Default is `True` :param: port_scan_p_of_success: The chance of the port scan being successful. Optional - Default is 0.1 (10%) diff --git a/src/primaite/simulator/system/core/session_manager.py b/src/primaite/simulator/system/core/session_manager.py index 26e3be79..6690340e 100644 --- a/src/primaite/simulator/system/core/session_manager.py +++ b/src/primaite/simulator/system/core/session_manager.py @@ -332,7 +332,7 @@ class SessionManager: ) # TODO: Only create IP packet if not ARP # ip_packet = None - # if dst_port != Port["ARP"]: + # if dst_port != PORT_LOOKUP["ARP"]: # IPPacket( # src_ip_address=outbound_network_interface.ip_address, # dst_ip_address=dst_ip_address, diff --git a/src/primaite/simulator/system/services/ftp/ftp_client.py b/src/primaite/simulator/system/services/ftp/ftp_client.py index 5e97243a..6b32aee6 100644 --- a/src/primaite/simulator/system/services/ftp/ftp_client.py +++ b/src/primaite/simulator/system/services/ftp/ftp_client.py @@ -215,7 +215,7 @@ class FTPClient(FTPServiceABC, discriminator="ftp-client"): :param: dest_file_name: The name of the file to be saved on the FTP Server. :type: dest_file_name: str - :param: dest_port: The open port of the machine that hosts the FTP Server. Default is Port["FTP"]. + :param: dest_port: The open port of the machine that hosts the FTP Server. Default is PORT_LOOKUP["FTP"]. :type: dest_port: Optional[Port] :param: session_id: The id of the session @@ -276,7 +276,7 @@ class FTPClient(FTPServiceABC, discriminator="ftp-client"): :param: dest_file_name: The name of the file to be saved on the FTP Server. :type: dest_file_name: str - :param: dest_port: The open port of the machine that hosts the FTP Server. Default is Port["FTP"]. + :param: dest_port: The open port of the machine that hosts the FTP Server. Default is PORT_LOOKUP["FTP"]. :type: dest_port: Optional[int] """ self._active = True diff --git a/src/primaite/simulator/system/services/ftp/ftp_service.py b/src/primaite/simulator/system/services/ftp/ftp_service.py index 13acda70..77582c3c 100644 --- a/src/primaite/simulator/system/services/ftp/ftp_service.py +++ b/src/primaite/simulator/system/services/ftp/ftp_service.py @@ -114,7 +114,7 @@ class FTPServiceABC(Service, ABC): :param: dest_ip_address: The IP address of the machine that hosts the FTP Server. :type: dest_ip_address: Optional[IPv4Address] - :param: dest_port: The open port of the machine that hosts the FTP Server. Default is Port["FTP"]. + :param: dest_port: The open port of the machine that hosts the FTP Server. Default is PORT_LOOKUP["FTP"]. :type: dest_port: Optional[Port] :param: session_id: session ID linked to the FTP Packet. Optional. diff --git a/src/primaite/simulator/system/services/icmp/router_icmp.py b/src/primaite/simulator/system/services/icmp/router_icmp.py deleted file mode 100644 index 4c69e381..00000000 --- a/src/primaite/simulator/system/services/icmp/router_icmp.py +++ /dev/null @@ -1,91 +0,0 @@ -# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK -# class RouterICMP(icmp): -# """ -# A class to represent a router's Internet Control Message Protocol (icmp) handler. -# -# :param sys_log: System log for logging network events and errors. -# :type sys_log: SysLog -# :param arp_cache: The arp cache for resolving MAC addresses. -# :type arp_cache: ARPCache -# :param router: The router to which this icmp handler belongs. -# :type router: Router -# """ -# -# router: Router -# -# def __init__(self, sys_log: SysLog, arp_cache: ARPCache, router: Router): -# super().__init__(sys_log, arp_cache) -# self.router = router -# -# def process_icmp(self, frame: Frame, from_network_interface: NIC, is_reattempt: bool = False): -# """ -# Process incoming icmp frames based on icmp type. -# -# :param frame: The incoming frame to process. -# :param from_network_interface: The network interface where the frame is coming from. -# :param is_reattempt: Flag to indicate if the process is a reattempt. -# """ -# if frame.icmp.icmp_type == ICMPType.ECHO_REQUEST: -# # determine if request is for router interface or whether it needs to be routed -# -# for network_interface in self.router.network_interfaces.values(): -# if network_interface.ip_address == frame.ip.dst_ip_address: -# if network_interface.enabled: -# # reply to the request -# if not is_reattempt: -# self.sys_log.info(f"Received echo request from {frame.ip.src_ip_address}") -# target_mac_address = self.arp.get_arp_cache_mac_address(frame.ip.src_ip_address) -# src_nic = self.arp.get_arp_cache_network_interface(frame.ip.src_ip_address) -# tcp_header = TCPHeader(src_port=Port["arp"], dst_port=Port["arp"]) -# -# # Network Layer -# ip_packet = IPPacket( -# src_ip_address=network_interface.ip_address, -# dst_ip_address=frame.ip.src_ip_address, -# protocol=IPProtocol["icmp"], -# ) -# # Data Link Layer -# ethernet_header = EthernetHeader( -# src_mac_addr=src_nic.mac_address, dst_mac_addr=target_mac_address -# ) -# icmp_reply_packet = ICMPPacket( -# icmp_type=ICMPType.ECHO_REPLY, -# icmp_code=0, -# identifier=frame.icmp.identifier, -# sequence=frame.icmp.sequence + 1, -# ) -# payload = secrets.token_urlsafe(int(32 / 1.3)) # Standard icmp 32 bytes size -# frame = Frame( -# ethernet=ethernet_header, -# ip=ip_packet, -# tcp=tcp_header, -# icmp=icmp_reply_packet, -# payload=payload, -# ) -# self.sys_log.info(f"Sending echo reply to {frame.ip.dst_ip_address}") -# -# src_nic.send_frame(frame) -# return -# -# # Route the frame -# self.router.process_frame(frame, from_network_interface) -# -# elif frame.icmp.icmp_type == ICMPType.ECHO_REPLY: -# for network_interface in self.router.network_interfaces.values(): -# if network_interface.ip_address == frame.ip.dst_ip_address: -# if network_interface.enabled: -# time = frame.transmission_duration() -# time_str = f"{time}ms" if time > 0 else "<1ms" -# self.sys_log.info( -# f"Reply from {frame.ip.src_ip_address}: " -# f"bytes={len(frame.payload)}, " -# f"time={time_str}, " -# f"TTL={frame.ip.ttl}" -# ) -# if not self.request_replies.get(frame.icmp.identifier): -# self.request_replies[frame.icmp.identifier] = 0 -# self.request_replies[frame.icmp.identifier] += 1 -# -# return -# # Route the frame -# self.router.process_frame(frame, from_network_interface)