Skip to content

Commit

Permalink
Refactor Arp and Ethernet parsers to use from_bytes method for header…
Browse files Browse the repository at this point in the history
… extraction
  • Loading branch information
ccie18643 committed Jul 15, 2024
1 parent ad3147b commit 0784938
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 19 deletions.
6 changes: 6 additions & 0 deletions pytcp/protocols/arp/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import struct
from abc import ABC
from dataclasses import dataclass
from typing import override

from pytcp.lib.enum import ProtoEnum
from pytcp.lib.ip4_address import Ip4Address
Expand Down Expand Up @@ -74,6 +75,7 @@ class ArpHardwareType(ProtoEnum):

ETHERNET = 0x0001

@override
@staticmethod
def _from_bytes(bytes: bytes) -> int:
return int.from_bytes(bytes[:2])
Expand All @@ -86,6 +88,7 @@ class ArpProtocolType(ProtoEnum):

IP4 = 0x0800

@override
@staticmethod
def _from_bytes(bytes: bytes) -> int:
return int.from_bytes(bytes[:2])
Expand All @@ -98,6 +101,7 @@ class ArpHardwareLength(ProtoEnum):

ETHERNET = 6

@override
@staticmethod
def _from_bytes(bytes: bytes) -> int:
return int.from_bytes(bytes[:1])
Expand All @@ -110,6 +114,7 @@ class ArpProtocolLength(ProtoEnum):

IP4 = 4

@override
@staticmethod
def _from_bytes(bytes: bytes) -> int:
return int.from_bytes(bytes[:1])
Expand All @@ -123,6 +128,7 @@ class ArpOperation(ProtoEnum):
REQUEST = 1
REPLY = 2

@override
@staticmethod
def _from_bytes(bytes: bytes) -> int:
return int.from_bytes(bytes[:2])
Expand Down
2 changes: 2 additions & 0 deletions pytcp/protocols/ethernet/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import struct
from abc import ABC
from dataclasses import dataclass
from typing import override

from pytcp.lib.enum import ProtoEnum
from pytcp.lib.mac_address import MacAddress
Expand Down Expand Up @@ -70,6 +71,7 @@ class EthernetType(ProtoEnum):
IP6 = 0x86DD
RAW = 0xFFFF

@override
@staticmethod
def _from_bytes(bytes: bytes) -> int:
return int.from_bytes(bytes[:2])
Expand Down
37 changes: 19 additions & 18 deletions pytcp/protocols/ip4/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
############################################################################

# pylint: disable = too-many-instance-attributes
# pylint: disable = redefined-builtin


"""
Module contains header support classes for the IPv4 protocol.
Expand Down Expand Up @@ -74,8 +76,8 @@ class Ip4Proto(ProtoEnum):
RAW = 255

@staticmethod
def _extract(frame: bytes) -> int:
return frame[9]
def _from_bytes(bytes: bytes) -> int:
return int.from_bytes(bytes[:1])


@dataclass
Expand Down Expand Up @@ -126,27 +128,26 @@ def __bytes__(self) -> bytes:
)

@staticmethod
def from_frame(frame: bytes) -> Ip4Header:
def from_bytes(bytes: bytes) -> Ip4Header:
"""
Populate the header from the raw frame.
"""

return Ip4Header(
ver=frame[0] >> 4,
hlen=(frame[0] & 0b00001111) << 2,
dscp=(frame[1] & 0b11111100) >> 2,
ecn=frame[1] & 0b00000011,
plen=struct.unpack("!H", frame[2:4])[0],
id=struct.unpack("!H", frame[4:6])[0],
flag_df=bool(frame[6] & 0b01000000),
flag_mf=bool(frame[6] & 0b00100000),
offset=(struct.unpack("!H", frame[6:8])[0] & 0b0001111111111111)
<< 3,
ttl=frame[8],
proto=Ip4Proto.from_frame(frame),
cksum=struct.unpack("!H", frame[10:12])[0],
src=Ip4Address(frame[12:16]),
dst=Ip4Address(frame[16:20]),
ver=bytes[0] >> 4,
hlen=(bytes[0] & 0b00001111) << 2,
dscp=(bytes[1] & 0b11111100) >> 2,
ecn=bytes[1] & 0b00000011,
plen=int.from_bytes(bytes[2:4]),
id=int.from_bytes(bytes[4:6]),
flag_df=bool(bytes[6] & 0b01000000),
flag_mf=bool(bytes[6] & 0b00100000),
offset=(int.from_bytes(bytes[6:8]) & 0b0001111111111111) << 3,
ttl=bytes[8],
proto=Ip4Proto.from_bytes(bytes[9:10]),
cksum=int.from_bytes(bytes[10:12]),
src=Ip4Address.from_bytes(bytes[12:16]),
dst=Ip4Address.from_bytes(bytes[16:20]),
)


Expand Down
2 changes: 1 addition & 1 deletion pytcp/protocols/ip4/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def _parse(self) -> None:
Parse IPv4 packet.
"""

self._header = Ip4Header.from_frame(self._frame)
self._header = Ip4Header.from_bytes(self._frame)
self._options = Ip4Options.from_bytes(
self._frame[IP4_HEADER_LEN : self._header.hlen]
)
Expand Down

0 comments on commit 0784938

Please sign in to comment.