Skip to content

Commit

Permalink
Re-araranged stack subsystems
Browse files Browse the repository at this point in the history
  • Loading branch information
ccie18643 committed Sep 15, 2024
1 parent 1b21a44 commit 8820a59
Show file tree
Hide file tree
Showing 21 changed files with 404 additions and 327 deletions.
9 changes: 3 additions & 6 deletions examples/run_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
Ip6Host,
MacAddress,
)
from pytcp import TcpIpStack, initialize_interface
from pytcp import stack


@click.command()
Expand Down Expand Up @@ -104,17 +104,14 @@ def cli(
Start PyTCP stack and stop it when user presses Ctrl-C.
"""

fd, mtu = initialize_interface(interface)

if ip6_host:
ip6_host.gateway = ip6_gateway

if ip4_host:
ip4_host.gateway = ip4_gateway

stack = TcpIpStack(
fd=fd,
mtu=mtu,
stack.init(
*stack.initialize_interface(interface),
mac_address=mac_address,
ip6_host=ip6_host,
ip4_host=ip4_host,
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,5 @@ disable = """
no-member,
too-many-ancestors,
redefined-outer-name,
global-statement,
"""
135 changes: 1 addition & 134 deletions pytcp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,142 +27,9 @@


"""
Module contains the main PyTCP stack class.
Package contains the PyTCP stack modules.
pytcp/__init__.py
ver 3.0.2
"""


import fcntl
import os
import struct
import sys

from net_addr.ip4_host import Ip4HostOrigin
from net_addr.ip6_host import Ip6HostOrigin

from net_addr import Ip4Host, Ip6Host, MacAddress
from pytcp import config, stack
from pytcp.lib.logger import log
from pytcp.socket.socket import ( # noqa: F401
AddressFamily,
IpProto,
ReceiveTimeout,
Socket,
SocketType,
gaierror,
)

TUNSETIFF = 0x400454CA
IFF_TUN = 0x0001
IFF_TAP = 0x0002
IFF_NO_PI = 0x1000


def initialize_interface(if_name: str, /) -> tuple[int, int]:
"""
Initialize the TAP/TUN interface.
"""

match if_name[0:3].lower():
case "tap":
if_type = IFF_TAP
mtu = config.INTERFACE__TAP__MTU
case "tun":
if_type = IFF_TUN
mtu = config.INTERFACE__TUN__MTU
case _:
log(
"stack",
"<CRIT>Interface name must start with 'tap' or 'tun'</>",
)
sys.exit(-1)

try:
fd = os.open("/dev/net/tun", os.O_RDWR)

except FileNotFoundError:
log("stack", "<CRIT>Unable to access '/dev/net/tun' device</>")
sys.exit(-1)

fcntl.ioctl(
fd,
TUNSETIFF,
struct.pack("16sH", if_name.encode(), if_type | IFF_NO_PI),
)

return fd, mtu


class TcpIpStack:
"""
Main PyTCP library class.
"""

def __init__(
self,
fd: int,
mtu: int,
*,
mac_address: MacAddress | None = None,
ip4_host: Ip4Host | None = None,
ip6_host: Ip6Host | None = None,
):
"""
Initialize stack on the provided interface.
"""

self._fd = fd
self._mtu = mtu

# Set the MAC address.
if mac_address is not None:
stack.packet_handler._assign_mac_address(
mac_unicast=MacAddress(mac_address)
)

# Set the IPv4 address.
if config.IP4__SUPPORT_ENABLED is True:
if ip4_host is None:
config.IP4__HOST_DHCP = True
else:
ip4_host.origin = Ip4HostOrigin.STATIC
stack.packet_handler._assign_ip4_address(ip4_host=ip4_host)
config.IP4__HOST_DHCP = False

# Set the IPv6 address.
if config.IP6__SUPPORT_ENABLED is True:
if ip6_host is None:
config.IP6__LLA_AUTOCONFIG = True
config.IP6__GUA_AUTOCONFIG = True
else:
ip6_host.origin = Ip6HostOrigin.STATIC
stack.packet_handler._assign_ip6_address(ip6_host=ip6_host)
config.IP6__LLA_AUTOCONFIG = True
config.IP6__GUA_AUTOCONFIG = False

def start(self) -> None:
"""
Start stack components.
"""

stack.timer.start()
stack.arp_cache.start()
stack.nd_cache.start()
stack.rx_ring.start(fd=self._fd)
stack.tx_ring.start(fd=self._fd, mtu=self._mtu)
stack.packet_handler.start()

def stop(self) -> None:
"""
Stop stack components.
"""

stack.packet_handler.stop()
stack.tx_ring.stop()
stack.rx_ring.stop()
stack.arp_cache.stop()
stack.nd_cache.stop()
stack.timer.stop()
33 changes: 0 additions & 33 deletions pytcp/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,6 @@

assert version_info >= (3, 12), "PyTCP requires Python version 3.12 or higher."

# TAP interface MTU, describes how much payload Ethernet packet can carry.
INTERFACE__TAP__MTU = 1500

# TUN interface MTU..
INTERFACE__TUN__MTU = 1500


# Support for IPv6 and IPv4, at least one should be anabled.
IP6__SUPPORT_ENABLED = True
IP4__SUPPORT_ENABLED = True

# Logger configuration - LOG__CHANNEL sets which subsystems of stack log to the
# console, LOG__DEBUG adds info about class/method caller.
Expand Down Expand Up @@ -78,16 +68,6 @@
}
LOG__DEBUG = False

# Unicast MAC addresses assigned to stack, currently there is not any kind of
# duplicate MAC detection performed. This can be overridden when stack object
# is created.
ETHERNET__MAC_ADDRESS = "02:00:00:77:77:77"

# IPv6 address auto configuration is implemented using EUI64 addressing and
# ICMPv6 Router Advertisement messages.
IP6__LLA_AUTOCONFIG = True
IP6__GUA_AUTOCONFIG = True

# IPv6 default Hop Limit value.
IP6__DEFAULT_HOP_LIMIT = 64

Expand All @@ -104,19 +84,6 @@
IP4__FRAG_FLOW_TIMEOUT = 5
IP6__FRAG_FLOW_TIMEOUT = 5

# IPv4 DHCP based address configuration.
IP4__HOST_DHCP = True

# ARP cache configuration.
ARP__CACHE__ENTRY_MAX_AGE = 3600
ARP__CACHE__ENTRY_REFRESH_TIME = 300
ARP__CACHE__UPDATE_FROM_DIRECT_REQUEST = True
ARP__CACHE__UPDATE_FROM_GRATUITIOUS_REPLY = True

# ICMPv6 ND cache configuration.
ICMP6__ND__CACHE__ENTRY_MAX_AGE = 3600
ICMP6__ND__CACHE__ENTRY_REFRESH_TIME = 300

# TCP/UDP ephemeral port range to be used by outbound connections.
EPHEMERAL_PORT_RANGE = range(32168, 60700, 2)

Expand Down
10 changes: 6 additions & 4 deletions pytcp/socket/tcp__session.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
from enum import auto
from typing import TYPE_CHECKING, Any

from pytcp import config, stack
from pytcp import stack
from pytcp.lib.logger import log
from pytcp.lib.name_enum import NameEnum

Expand All @@ -68,6 +68,8 @@
100 # Delay between consecutive delayed ACK outbound packets
)

INTERFACE__TAP__MTU = 1500


class TcpSessionError(Exception):
"""
Expand Down Expand Up @@ -209,7 +211,7 @@ def __init__(
self._rcv_una: int = 0

# Maximum segment size
self._rcv_mss: int = config.INTERFACE__TAP__MTU - 40
self._rcv_mss: int = INTERFACE__TAP__MTU - 40

# Window size
self._rcv_wnd: int = 65535
Expand Down Expand Up @@ -883,7 +885,7 @@ def _tcp_fsm_listen(
)
# Initialize session parameters
self._snd_mss = min(
packet_rx_md.tcp__mss, config.INTERFACE__TAP__MTU - 40
packet_rx_md.tcp__mss, INTERFACE__TAP__MTU - 40
)
self._snd_wnd = (
packet_rx_md.tcp__win << self._snd_wsc
Expand Down Expand Up @@ -940,7 +942,7 @@ def _tcp_fsm_syn_sent(
):
# Initialize session parameters
self._snd_mss = min(
packet_rx_md.tcp__mss, config.INTERFACE__TAP__MTU - 40
packet_rx_md.tcp__mss, INTERFACE__TAP__MTU - 40
)
self._snd_wnd = (
packet_rx_md.tcp__win << self._snd_wsc
Expand Down
Loading

0 comments on commit 8820a59

Please sign in to comment.