Skip to content

Commit

Permalink
Refactored ARP related code.
Browse files Browse the repository at this point in the history
  • Loading branch information
ccie18643 committed Nov 12, 2023
1 parent 7e106ef commit 47b4417
Show file tree
Hide file tree
Showing 23 changed files with 685 additions and 475 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@

__pycache__/
venv/
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"python.analysis.extraPaths": [
"./pytcp"
],
"python.formatting.provider": "black"
"python.formatting.provider": "none",
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
}
}
3 changes: 3 additions & 0 deletions pytcp/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,6 @@
# Native support for UDP Echo (used for packet flow unit testing only and should
# always be disabled).
UDP_ECHO_NATIVE_DISABLE = True

# LRU cache size, used by packet parsers to cache parsed field values.
LRU_CACHE_SIZE = 16
68 changes: 68 additions & 0 deletions pytcp/lib/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python3

############################################################################
# #
# PyTCP - Python TCP/IP stack #
# Copyright (C) 2020-present Sebastian Majewski #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
# #
# Author's email: [email protected] #
# Github repository: https://github.com/ccie18643/PyTCP #
# #
############################################################################


"""
Module contains methods supporting errors.
pytcp/lib/errors.py
ver 2.7
"""


from __future__ import annotations


class PyTcpError(Exception):
"""
Base class for all PyTCP exceptions.
"""

...


class PacketValidationError(PyTcpError):
"""
Exception raised when packet validation fails.
"""

...


class PacketIntegrityError(PacketValidationError):
"""
Exception raised when integrity check fails.
"""

...


class PacketSanityError(PacketValidationError):
"""
Exception raised when sanity check fails.
"""

...
72 changes: 31 additions & 41 deletions pytcp/protocols/arp/fpa.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,87 +41,77 @@
from pytcp.lib.ip4_address import Ip4Address
from pytcp.lib.mac_address import MacAddress
from pytcp.lib.tracker import Tracker
from pytcp.protocols.arp.ps import ARP_HEADER_LEN, ARP_OP_REPLY, ARP_OP_REQUEST
from pytcp.protocols.ether.ps import ETHER_TYPE_ARP


class ArpAssembler:
from pytcp.protocols.arp.ps import (
ARP_HEADER_LEN,
ArpCommon,
ArpHardwareLength,
ArpHardwareType,
ArpOperation,
ArpProtocolLength,
ArpProtocolType,
)


class ArpAssembler(ArpCommon):
"""
ARP packet assembler support class.
"""

ether_type = ETHER_TYPE_ARP

def __init__(
self,
*,
sha: MacAddress = MacAddress(0),
spa: Ip4Address = Ip4Address(0),
tha: MacAddress = MacAddress(0),
tpa: Ip4Address = Ip4Address(0),
oper: int = ARP_OP_REQUEST,
oper: ArpOperation = ArpOperation.REQUEST,
echo_tracker: Tracker | None = None,
) -> None:
"""
Class constructor.
"""

assert oper in (ARP_OP_REQUEST, ARP_OP_REPLY), f"{oper=}"

self._tracker = Tracker(prefix="TX", echo_tracker=echo_tracker)

self._hrtype: int = 1
self._prtype: int = 0x0800
self._hrlen: int = 6
self._prlen: int = 4
self._oper: int = oper
self._sha: MacAddress = sha
self._spa: Ip4Address = spa
self._tha: MacAddress = tha
self._tpa: Ip4Address = tpa
self._hrtype = ArpHardwareType.ETHERNET
self._prtype = ArpProtocolType.IP4
self._hrlen = ArpHardwareLength.ETHERNET
self._prlen = ArpProtocolLength.IP4
self._oper = oper
self._sha = sha
self._spa = spa
self._tha = tha
self._tpa = tpa

def __len__(self) -> int:
"""
Length of the packet.
"""
return ARP_HEADER_LEN

def __str__(self) -> str:
"""
Packet log string.
"""
if self._oper == ARP_OP_REQUEST:
return (
f"ARP request {self._spa} / {self._sha}"
f" > {self._tpa} / {self._tha}"
)
if self._oper == ARP_OP_REPLY:
return (
f"ARP reply {self._spa} / {self._sha}"
f" > {self._tpa} / {self._tha}"
)
return f"ARP request unknown operation {self._oper}"
return ARP_HEADER_LEN

@property
def tracker(self) -> Tracker:
"""
Getter for the '_tracker' property.
"""

return self._tracker

def assemble(self, frame: memoryview) -> None:
def assemble(self, /, frame: memoryview) -> None:
"""
Assemble packet into the raw form.
"""

struct.pack_into(
"!HH BBH 6s 4s 6s 4s",
frame,
0,
self._hrtype,
self._prtype,
self._hrlen,
self._prlen,
self._oper,
int(self._hrtype),
int(self._prtype),
int(self._hrlen),
int(self._prlen),
int(self._oper),
bytes(self._sha),
bytes(self._spa),
bytes(self._tha),
Expand Down
Loading

0 comments on commit 47b4417

Please sign in to comment.