Skip to content

Commit

Permalink
Restoring version 2.2
Browse files Browse the repository at this point in the history
  • Loading branch information
ccie18643 committed Jun 3, 2021
1 parent b2edb5f commit 83892f3
Show file tree
Hide file tree
Showing 110 changed files with 6,392 additions and 6,210 deletions.
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# PyTCP (version 2.0)
# PyTCP (version 2.2)

PyTCP is an attempt to create fully functional TCP/IP stack in Python. It supports TCP stream based transport with reliable packet delivery based on sliding window mechanism and basic congestion control. It also supports IPv6/ICMPv6 protocols with SLAAC address configuration. It operates as user space program attached to Linux TAP interface. As of today stack is able to send and receive traffic over Internet using IPv4 and IPv6 default gateways for routing.

Expand Down Expand Up @@ -51,8 +51,9 @@ I am also working on another TCP/IP stack project that is being programmed in C

- QUIC protocol - *research and plan for the implementation, this depends on ability to create lab environment for it*
- IPv6 protocol - *redesign the RA PI option handling and ND prefix auto configuration to properly use A nad L flags, some research also needed on case when different than /64 prefix is being advertised*
- IPv6 protocol - *implement remaining extended headers*
- IPv6 protocol - *implement optional headers*
- IPv6 protocol - *validate and possibly re-implements certain IPv6 mechanisms/processes according to RFC rules*
- IPv6 protocol - *research and possibly implement support for certain optional IPv6 headers*
- IPv6 protocol - *investigate Hop-by-Hop Options header and its relation to MLD2 Report message, implement if needed for MLD2 to work properly*
- ICMPv6 protocol - *validate and possibly re-implements certain IPv6 mechanisms/processes according to RFC rules*
- ICMPv6 protocol - *implement ND Redirect message*
Expand All @@ -62,16 +63,17 @@ I am also working on another TCP/IP stack project that is being programmed in C
- TCP protocol - *proper handling on RST packets in various states, need to do research on this*
- TCP protocol - *need to rework the CLOSE syscall mechanism so FIN flag can be set on last data packet instead of being carried in separate one*
- TCP protocol - *ACK packet retransmission in case we got FIN retransmission in TIME_WAIT state <-- need to investigate this*
- TCP protocol - *implement proper response to packets containing old SEQ and/or ACK numbers <-- need to investigate this*
- TCP protocol - *implement proper response to packets containing old SEQ and/or ACK numbersi <-- need to investigate this*
- TCP protocol - *ensure that event communication from TCP session to socket works properly (eg. connection reset by peer)*
- ICMP protocols - *need to come up with some sort of "icmp socket" mechanism so ping client can bind to particular ICMP echo-reply stream*
- IPv4 protocol - *improvements in IP defragmentation mechanism are needed, out of order fragment handling, purging of orphaned fragments*
- IPv6/IPv4 protocols - *proper routing mechanism, route tables, etc...*
- IPv6/IPv4 protocols - *ability of stack to act as a router*
- ARP cache - *implement proper FSM*
- ICMPv6 ND cache - *implement proper FSM*
- UDP protocol - *need UDP echo client and mechanism to report receiving ICMP Port Unreachable message to UDP socket*
- UDP sockets - *overhaul is needed to make 'end user' interface match Berkeley sockets interface 100% so 3rd party aps can use it without porting*
- TCP sockets - *overhaul is needed to make 'end user' interface match Berkeley sockets interface 100% so 3rd party aps can use it without porting*
- UDP sockets - *overhaul is needed to make 'end user' interface match Berkeley sockets more closely so 3rd party aps can use it without porting*
- TCP sockets - *overhaul is needed to make 'end user' interface match Berkeley sockets more closely so 3rd party aps can use it without porting*


### Examples:
Expand Down
29 changes: 29 additions & 0 deletions arp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python3

############################################################################
# #
# PyTCP - Python TCP/IP stack #
# Copyright (C) 2020-2021 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 #
# #
############################################################################


#
# arp/__init__.py
#
92 changes: 92 additions & 0 deletions arp/fpa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/usr/bin/env python3

############################################################################
# #
# PyTCP - Python TCP/IP stack #
# Copyright (C) 2020-2021 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 #
# #
############################################################################


#
# arp/fpa.py - Fast Packet Assembler support class for ARP protocol
#


import struct
from typing import Optional

import arp.ps
import ether.ps
from misc.ipv4_address import IPv4Address
from misc.tracker import Tracker


class Assembler:
"""ARP packet assembler support class"""

ether_type = ether.ps.TYPE_ARP

def __init__(
self,
sha: str,
spa: IPv4Address,
tpa: IPv4Address,
tha: str = "00:00:00:00:00:00",
oper: int = arp.ps.OP_REQUEST,
echo_tracker: Optional[Tracker] = None,
) -> None:
"""Class constructor"""

self.tracker = Tracker("TX", echo_tracker)

self.hrtype = 1
self.prtype = 0x0800
self.hrlen = 6
self.prlen = 4
self.oper = oper
self.sha = sha
self.spa = IPv4Address(spa)
self.tha = tha
self.tpa = IPv4Address(tpa)

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

return arp.ps.HEADER_LEN

from arp.ps import __str__

def assemble(self, frame: bytearray, hptr: int):
"""Assemble packet into the raw form"""

return struct.pack_into(
"!HH BBH 6s 4s 6s 4s",
frame,
hptr,
self.hrtype,
self.prtype,
self.hrlen,
self.prlen,
self.oper,
bytes.fromhex(self.sha.replace(":", "")),
IPv4Address(self.spa).packed,
bytes.fromhex(self.tha.replace(":", "")),
IPv4Address(self.tpa).packed,
)
168 changes: 168 additions & 0 deletions arp/fpp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/usr/bin/env python3

############################################################################
# #
# PyTCP - Python TCP/IP stack #
# Copyright (C) 2020-2021 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 #
# #
############################################################################


#
# arp/fpp.py - Fast Packet Parser support class for ARP protocol
#


import struct

import arp.ps
import config
from misc.ipv4_address import IPv4Address
from misc.packet import PacketRx


class Parser:
"""ARP packet parser class"""

def __init__(self, packet_rx: PacketRx) -> None:
"""Class constructor"""

packet_rx.arp = self

self._frame = packet_rx.frame
self._hptr = packet_rx.hptr

packet_rx.parse_failed = self._packet_integrity_check() or self._packet_sanity_check()

def __len__(self) -> int:
"""Number of bytes remaining in the frame"""

return len(self._frame) - self._hptr

from arp.ps import __str__

@property
def hrtype(self) -> int:
"""Read 'Hardware address type' field"""

if "_cache__hrtype" not in self.__dict__:
self._cache__hrtype = struct.unpack_from("!H", self._frame, self._hptr + 0)[0]
return self._cache__hrtype

@property
def prtype(self) -> int:
"""Read 'Protocol address type' field"""

if "_cache__prtype" not in self.__dict__:
self._cache__prtype = struct.unpack_from("!H", self._frame, self._hptr + 2)[0]
return self._cache__prtype

@property
def hrlen(self) -> int:
"""Read 'Hardware address length' field"""

return self._frame[self._hptr + 4]

@property
def prlen(self) -> int:
"""Read 'Protocol address length' field"""

return self._frame[self._hptr + 5]

@property
def oper(self) -> int:
"""Read 'Operation' field"""

if "_cache__oper" not in self.__dict__:
self._cache__oper = struct.unpack_from("!H", self._frame, self._hptr + 6)[0]
return self._cache__oper

@property
def sha(self) -> str:
"""Read 'Sender hardware address' field"""

if "_cache__sha" not in self.__dict__:
self._cache__sha = ":".join([f"{_:0>2x}" for _ in self._frame[self._hptr + 8 : self._hptr + 14]])
return self._cache__sha

@property
def spa(self) -> IPv4Address:
"""Read 'Sender protocol address' field"""

if "_cache__spa" not in self.__dict__:
self._cache__spa = IPv4Address(self._frame[self._hptr + 14 : self._hptr + 18])
return self._cache__spa

@property
def tha(self) -> str:
"""Read 'Target hardware address' field"""

if "_cache__tha" not in self.__dict__:
self._cache__tha = ":".join([f"{_:0>2x}" for _ in self._frame[self._hptr + 18 : self._hptr + 24]])
return self._cache__tha

@property
def tpa(self) -> IPv4Address:
"""Read 'Target protocol address' field"""

if "_cache__tpa" not in self.__dict__:
self._cache__tpa = IPv4Address(self._frame[self._hptr + 24 : self._hptr + 28])
return self._cache__tpa

@property
def packet_copy(self) -> bytes:
"""Read the whole packet"""

if "_cache__packet_copy" not in self.__dict__:
self._cache__packet_copy = self._frame[self._hptr : self._hptr + arp.ps.HEADER_LEN]
return self._cache__packet_copy

def _packet_integrity_check(self) -> str:
"""Packet integrity check to be run on raw packet prior to parsing to make sure parsing is safe"""

if not config.packet_integrity_check:
return ""

if len(self) < arp.ps.HEADER_LEN:
return "ARP integrity - wrong packet length (I)"

return ""

def _packet_sanity_check(self) -> str:
"""Packet sanity check to be run on parsed packet to make sure packet's fields contain sane values"""

if not config.packet_sanity_check:
return ""

if self.hrtype != 1:
return "ARP sanity - 'arp_hrtype' must be 1"

if self.prtype != 0x0800:
return "ARP sanity - 'arp_prtype' must be 0x0800"

if self.hrlen != 6:
return "ARP sanity - 'arp_hrlen' must be 6"

if self.prlen != 4:
return "ARP sanity - 'arp_prlen' must be 4"

if self.oper not in {1, 2}:
return "ARP sanity - 'oper' must be [1-2]"

return ""
Loading

0 comments on commit 83892f3

Please sign in to comment.