|
| 1 | +# PyTCP (version 1.0) |
| 2 | + |
| 3 | +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. Since goal of this project is purely educational (at least at this point) the clarity of code is preferred over its efficiency. For the same reason security features are not being implemented just yet unless they are integral part of TCP/IP suite protocols specification. |
| 4 | + |
| 5 | +PyTCP version 1.0 is not being developed anymore. Only bug fixes are being occasionally implemented. There is new version 2.0 being currently developed which has been implemented with use of new packet parser and assembler mechanisms to improve stack efficiency. |
| 6 | + |
| 7 | + |
| 8 | +#### Version 1.0 features: |
| 9 | + |
| 10 | + - Ethernet protocol - *support of Ethernet II standard frame* |
| 11 | + - Ethernet protocol - *unicast, IPv4 multicast, IPv6 multicast and broadcast addressing supported* |
| 12 | + - ARP protocol - *replies, queries, ARP cache mechanism* |
| 13 | + - ARP protocol - *ARP Probe/Announcement IP conflict detection (ACD) mechanism* |
| 14 | + - IPv4 protocol - *default routing, stack can talk to hosts over Internet using IPv4 protocol* |
| 15 | + - IPv4 protocol - *automatic address configuration using DHCP protocol* |
| 16 | + - IPv4 protocol - *inbound and outbound IP fragmentation* |
| 17 | + - IPv4 protocol - *IPv4 options accepted but not supported* |
| 18 | + - IPv4 protocol - *multiple stack's IPv4 addresses supported, each of them acts as it was assigned to separate VRF* |
| 19 | + - ICMPv4 protocol - *echo request, echo reply, port unreachable* |
| 20 | + - IPv6 protocol - *default routing, stack can talk to hosts over Internet using IPv6 protocol* |
| 21 | + - IPv6 protocol - *automatic Link Local address configuration using EUI64 and Duplicate Address Detection* |
| 22 | + - IPv6 protocol - *automatic GUA address configuration using Router Advertisement / EUI64* |
| 23 | + - IPv6 protocol - *automatic assignment of Solicited Node Multicast addresses* |
| 24 | + - IPv6 protocol - *automatic assignment of IPv6 multicast MAC addresses* |
| 25 | + - ICMPv6 protocol - *echo request, echo reply, port unreachable* |
| 26 | + - ICMPv6 protocol - *Neighbor Discovery, Duplicate Address Detection* |
| 27 | + - ICMPv6 protocol - *Neighbor Discovery cache mechanism* |
| 28 | + - ICMPv6 protocol - *Multicast Listener Discovery v2 (MLDv2) protocol implementation (only messages needed by stack)* |
| 29 | + - UDP protocol - *full support, stack is able to exchange data with other hosts using UDP protocol* |
| 30 | + - UDP sockets - *full support, stack's 'end user' API similar to Berkeley sockets* |
| 31 | + - UDP services - *UDP Echo, Discard, Daytime implemented for testing purposes* |
| 32 | + - TCP protocol - *full implementation of TCP Finite State Machine, at this point stack is able to exchange bulk data with other hosts over TCP protocol* |
| 33 | + - TCP protocol - *TCP option support for: MSS, WSCALE, SACKPERM, TIMESTAMP* |
| 34 | + - TCP protocol - *TCP sliding window mechanism with and data retransmission (fast retransmit and time based scenarios)* |
| 35 | + - TCP protocol - *TCP backoff mechanism / basic congestion control* |
| 36 | + - TCP protocol - *TCP SYN/FIN packet retransmission* |
| 37 | + - TCP sockets - *full support, stack's 'end user' API similar to Berkeley sockets* |
| 38 | + |
| 39 | + |
| 40 | +### Examples: |
| 41 | + |
| 42 | +#### Couple ping packets and two monkeys delivered via TCP over IPv6 protocol |
| 43 | + |
| 44 | + |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | + |
| 50 | + |
| 51 | + |
| 52 | + |
| 53 | + |
| 54 | + |
| 55 | + |
| 56 | + |
| 57 | +#### IPv6 Neighbor Discovery / Duplicate Address Detection / Address Auto Configuration |
| 58 | + - stack tries to auto configure it's link local address, it generates it as EUI64 address, as part od DAD process it joins appropriate solicited node multicast group and sends neighbor solicitation for the address it generated |
| 59 | + - stack doesn't receive any Neighbor Advertisement for the address it generated so assigns it to its interface |
| 60 | + - stack tries to assign preconfigured static address, as part of DAD process it joins appropriate solicited node multicast group and sends neighbor solicitation for the static address |
| 61 | + - another host that has the same address already assigned replies with Neighbor Advertisement message, this tells the stack that the address its trying to assign has been already |
| 62 | +y assigned by another host so stack cannot us it |
| 63 | + - stack sends out Router Solicitation message to check if there are any global prefixes it should use |
| 64 | + - router responds with Router Advertisement containing additional prefix |
| 65 | + - stack tries to assign address generated based on received prefix and EUI64 host portion, as part of DAD process it joins appropriate solicited node multicast group and sends neighbor solicitation for the static address |
| 66 | + - stack doesn't receive any Neighbor Advertisement for the address it generated so assigns it to its interface |
| 67 | + - after all addresses are assigned stacks sends out one more Multicast Listener report listing all of the multicast addresses it wants to listen to |
| 68 | + |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | + |
| 73 | + |
| 74 | + |
| 75 | + |
| 76 | +#### TCP Fast Retransmit in action after lost TX packet |
| 77 | + - outgoing packet is 'lost' as result of simulated packet loss mechanism |
| 78 | + - peer notices the inconsistence in packet SEQ numbers and sends out 'fast retransmit request' |
| 79 | + - stack eceives the request and retransmits lost packet |
| 80 | + |
| 81 | + |
| 82 | + |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +#### Out of order queue in action during RX packet loss event |
| 88 | + - incoming packet is 'lost' as reult of simulated packet loss mechanism |
| 89 | + - stack notices that there is an inconsistence in inbound packet's SEQ number and sends out 'fast retransmit' request |
| 90 | + - before peer receives the request it already sends multiple packets with higher SEQ than what stack is expecting, stack queues all those packets |
| 91 | + - peer retransmits lost packet |
| 92 | + - stack receives lost packet, pulls all the packets stored in ooo queue so far and processes them |
| 93 | + - stacks sends out ACK packet to acknowledge latest of the packets pulled from queue |
| 94 | + |
| 95 | + |
| 96 | + |
| 97 | + |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | +#### TCP Finite State Machine - stack is running TCP Echo service |
| 104 | + - peer opens connection |
| 105 | + - peer sends data |
| 106 | + - stack echoes the data back |
| 107 | + - peer closes connection |
| 108 | + |
| 109 | + |
| 110 | + |
| 111 | + |
| 112 | + |
| 113 | + |
| 114 | + |
| 115 | +#### TCP Finite State Machine - stack is running TCP Echo client |
| 116 | + - stack opens connection |
| 117 | + - stack sends data |
| 118 | + - peer echoes the data back |
| 119 | + - stack closes connection |
| 120 | + |
| 121 | + |
| 122 | + |
| 123 | + |
| 124 | + |
| 125 | + |
| 126 | + |
| 127 | +#### Pre-parse packet sanity check in action |
| 128 | + - first screenshot shows stack with sanity check turned off, malformed ICMPv6 packet is able to crash it |
| 129 | + - second screenshot shows stack with sanity check turned on, malformed ICMPv6 packet is being discarded before being passed to ICMPv6 protocol parser |
| 130 | + - third screenshot shows the malformed packet, number of MA records field has been set to 777 despite packet contains only one record |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | +#### ARP Probe/Announcement mechanism |
| 138 | + - stack is using ARP Probes to find any possible conflicts for every IP address that has been configured |
| 139 | + - one of IP addresses (192.168.9.102) is already taken so stack gets notified about it and skips it |
| 140 | + - rest of IP addresses are free so stack claims them by sending ARP Announcement for each of them |
| 141 | + |
| 142 | + |
| 143 | + |
| 144 | + |
| 145 | + |
| 146 | + |
| 147 | + |
| 148 | +#### ARP resolution and handling ping packets |
| 149 | + - host 192.168.9.20 tries to ping the stack, to be able to do it it first sends ARP Request packet to find out stack's MAC address |
| 150 | + - stack responds by sending ARP Reply packet (stack doesn't need to send out its own request since it already made note of the host's MAC from host's request) |
| 151 | + - hosts sends ping packets, stack responds to them |
| 152 | + |
| 153 | + |
| 154 | + |
| 155 | + |
| 156 | + |
| 157 | +#### IP fragmentation |
| 158 | + - host sends 4Kb UDP datagram using three fragmented IP packet (three fragments) |
| 159 | + - stack receives packets and assembles them into single piece, then passes it (via UDP protocol handler and UDP Socket) to UDO Echo service |
| 160 | + - UDP Echo service picks data up and puts it back into UDP Socket |
| 161 | + - UDP datagram is being passed to IP protocol handler which creates IP packet and after checking that it exceedes link MTU fragments it into three separate IP packets |
| 162 | + - IP packets are being encapsulated in Ethernet frames and put on TX ring |
| 163 | + |
| 164 | + |
| 165 | + |
| 166 | + |
| 167 | + |
0 commit comments