#2248 - Final run over all the docstrings after running pre-commit. All tests now working. Updated CHANGELOG.md.
This commit is contained in:
@@ -20,6 +20,7 @@ class ARP(Service):
|
||||
Manages ARP for resolving network layer addresses into link layer addresses. It maintains an ARP cache,
|
||||
sends ARP requests and replies, and processes incoming ARP packets.
|
||||
"""
|
||||
|
||||
arp: Dict[IPV4Address, ARPEntry] = {}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -29,6 +30,14 @@ class ARP(Service):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def describe_state(self) -> Dict:
|
||||
"""
|
||||
Produce a dictionary describing the current state of this object.
|
||||
|
||||
:return: Current state of this object and child objects.
|
||||
"""
|
||||
state = super().describe_state()
|
||||
state.update({str(ip): arp_entry.mac_address for ip, arp_entry in self.arp.items()})
|
||||
|
||||
return super().describe_state()
|
||||
|
||||
def show(self, markdown: bool = False):
|
||||
@@ -57,11 +66,7 @@ class ARP(Service):
|
||||
self.arp.clear()
|
||||
|
||||
def add_arp_cache_entry(
|
||||
self,
|
||||
ip_address: IPV4Address,
|
||||
mac_address: str,
|
||||
network_interface: NetworkInterface,
|
||||
override: bool = False
|
||||
self, ip_address: IPV4Address, mac_address: str, network_interface: NetworkInterface, override: bool = False
|
||||
):
|
||||
"""
|
||||
Add an ARP entry to the cache.
|
||||
@@ -139,7 +144,8 @@ class ARP(Service):
|
||||
)
|
||||
else:
|
||||
self.sys_log.error(
|
||||
"Cannot send ARP request as there is no outbound Network Interface to use. Try configuring the default gateway."
|
||||
"Cannot send ARP request as there is no outbound Network Interface to use. Try configuring the default "
|
||||
"gateway."
|
||||
)
|
||||
|
||||
def send_arp_reply(self, arp_reply: ARPPacket):
|
||||
@@ -147,12 +153,10 @@ class ARP(Service):
|
||||
Sends an ARP reply in response to an ARP request.
|
||||
|
||||
:param arp_reply: The ARP packet containing the reply.
|
||||
:param from_network_interface: The NIC from which the ARP reply is sent.
|
||||
"""
|
||||
|
||||
outbound_network_interface = self.software_manager.session_manager.resolve_outbound_network_interface(
|
||||
arp_reply.target_ip_address
|
||||
)
|
||||
)
|
||||
if outbound_network_interface:
|
||||
self.sys_log.info(
|
||||
f"Sending ARP reply from {arp_reply.sender_mac_addr}/{arp_reply.sender_ip_address} "
|
||||
@@ -162,14 +166,14 @@ class ARP(Service):
|
||||
payload=arp_reply,
|
||||
dst_ip_address=arp_reply.target_ip_address,
|
||||
dst_port=self.port,
|
||||
ip_protocol=self.protocol
|
||||
ip_protocol=self.protocol,
|
||||
)
|
||||
else:
|
||||
self.sys_log.error(
|
||||
"Cannot send ARP reply as there is no outbound Network Interface to use. Try configuring the default gateway."
|
||||
"Cannot send ARP reply as there is no outbound Network Interface to use. Try configuring the default "
|
||||
"gateway."
|
||||
)
|
||||
|
||||
|
||||
@abstractmethod
|
||||
def _process_arp_request(self, arp_packet: ARPPacket, from_network_interface: NetworkInterface):
|
||||
"""
|
||||
@@ -197,7 +201,7 @@ class ARP(Service):
|
||||
self.add_arp_cache_entry(
|
||||
ip_address=arp_packet.sender_ip_address,
|
||||
mac_address=arp_packet.sender_mac_addr,
|
||||
network_interface=from_network_interface
|
||||
network_interface=from_network_interface,
|
||||
)
|
||||
|
||||
def receive(self, payload: Any, session_id: str, **kwargs) -> bool:
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import secrets
|
||||
from ipaddress import IPv4Address
|
||||
from typing import Dict, Any, Union, Optional, Tuple
|
||||
from typing import Any, Dict, Optional, Tuple, Union
|
||||
|
||||
from primaite import getLogger
|
||||
from primaite.simulator.network.hardware.base import NetworkInterface
|
||||
from primaite.simulator.network.protocols.icmp import ICMPPacket, ICMPType
|
||||
from primaite.simulator.network.transmission.data_link_layer import Frame
|
||||
from primaite.simulator.network.transmission.network_layer import IPProtocol
|
||||
@@ -19,6 +20,7 @@ class ICMP(Service):
|
||||
Enables the sending and receiving of ICMP messages such as echo requests and replies. This is typically used for
|
||||
network diagnostics, notably the ping command.
|
||||
"""
|
||||
|
||||
request_replies: Dict = {}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
@@ -28,7 +30,12 @@ class ICMP(Service):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def describe_state(self) -> Dict:
|
||||
pass
|
||||
"""
|
||||
Produce a dictionary describing the current state of this object.
|
||||
|
||||
:return: Current state of this object and child objects.
|
||||
"""
|
||||
return super().describe_state()
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
@@ -56,9 +63,7 @@ class ICMP(Service):
|
||||
self.sys_log.info(f"Pinging {target_ip_address}:", to_terminal=True)
|
||||
sequence, identifier = 0, None
|
||||
while sequence < pings:
|
||||
sequence, identifier = self._send_icmp_echo_request(
|
||||
target_ip_address, sequence, identifier, pings
|
||||
)
|
||||
sequence, identifier = self._send_icmp_echo_request(target_ip_address, sequence, identifier, pings)
|
||||
request_replies = self.software_manager.icmp.request_replies.get(identifier)
|
||||
passed = request_replies == pings
|
||||
if request_replies:
|
||||
@@ -76,7 +81,7 @@ class ICMP(Service):
|
||||
return passed
|
||||
|
||||
def _send_icmp_echo_request(
|
||||
self, target_ip_address: IPv4Address, sequence: int = 0, identifier: Optional[int] = None, pings: int = 4
|
||||
self, target_ip_address: IPv4Address, sequence: int = 0, identifier: Optional[int] = None, pings: int = 4
|
||||
) -> Tuple[int, Union[int, None]]:
|
||||
"""
|
||||
Sends an ICMP echo request to a specified target IP address.
|
||||
@@ -91,7 +96,8 @@ class ICMP(Service):
|
||||
|
||||
if not network_interface:
|
||||
self.sys_log.error(
|
||||
"Cannot send ICMP echo request as there is no outbound Network Interface to use. Try configuring the default gateway."
|
||||
"Cannot send ICMP echo request as there is no outbound Network Interface to use. Try configuring the "
|
||||
"default gateway."
|
||||
)
|
||||
return pings, None
|
||||
|
||||
@@ -105,11 +111,11 @@ class ICMP(Service):
|
||||
dst_ip_address=target_ip_address,
|
||||
dst_port=self.port,
|
||||
ip_protocol=self.protocol,
|
||||
icmp_packet=icmp_packet
|
||||
icmp_packet=icmp_packet,
|
||||
)
|
||||
return sequence, icmp_packet.identifier
|
||||
|
||||
def _process_icmp_echo_request(self, frame: Frame, from_network_interface):
|
||||
def _process_icmp_echo_request(self, frame: Frame, from_network_interface: NetworkInterface):
|
||||
"""
|
||||
Processes an ICMP echo request received by the service.
|
||||
|
||||
@@ -121,11 +127,12 @@ class ICMP(Service):
|
||||
|
||||
network_interface = self.software_manager.session_manager.resolve_outbound_network_interface(
|
||||
frame.ip.src_ip_address
|
||||
)
|
||||
)
|
||||
|
||||
if not network_interface:
|
||||
self.sys_log.error(
|
||||
"Cannot send ICMP echo reply as there is no outbound Network Interface to use. Try configuring the default gateway."
|
||||
"Cannot send ICMP echo reply as there is no outbound Network Interface to use. Try configuring the "
|
||||
"default gateway."
|
||||
)
|
||||
return
|
||||
|
||||
@@ -143,7 +150,7 @@ class ICMP(Service):
|
||||
dst_ip_address=frame.ip.src_ip_address,
|
||||
dst_port=self.port,
|
||||
ip_protocol=self.protocol,
|
||||
icmp_packet=icmp_packet
|
||||
icmp_packet=icmp_packet,
|
||||
)
|
||||
|
||||
def _process_icmp_echo_reply(self, frame: Frame):
|
||||
@@ -159,7 +166,7 @@ class ICMP(Service):
|
||||
f"bytes={len(frame.payload)}, "
|
||||
f"time={time_str}, "
|
||||
f"TTL={frame.ip.ttl}",
|
||||
to_terminal=True
|
||||
to_terminal=True,
|
||||
)
|
||||
if not self.request_replies.get(frame.icmp.identifier):
|
||||
self.request_replies[frame.icmp.identifier] = 0
|
||||
|
||||
@@ -70,10 +70,6 @@ class NTPServer(Service):
|
||||
payload = payload.generate_reply(time)
|
||||
# send reply
|
||||
self.software_manager.session_manager.receive_payload_from_software_manager(
|
||||
payload=payload,
|
||||
src_port=self.port,
|
||||
dst_port=self.port,
|
||||
ip_protocol=self.protocol,
|
||||
session_id=session_id
|
||||
payload=payload, src_port=self.port, dst_port=self.port, ip_protocol=self.protocol, session_id=session_id
|
||||
)
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user