Implementing my own tcp stack

Hi, I'm trying to build my own (simplified) tcp stack in rust as a newcomer to the language. Currently using smoltcp as a reference.

I'm wondering how I can interact with the OS to reserve a port number? I don't want to use std::net::TcpStream because that is what I'm trying to effectively recreate. Any tips or resources are appreciated

As a TCP stack, you are responsible for reserving port numbers yourself.

Generally speaking, a TCP stack needs an underlying network interface. Physical hardware is an example, but since that is inconvenient for development, TCP stacks like smoltcp support hosted mode. See "Hosted usage examples" section of smoltcp README. In the example, Linux kernel gives you a network interface called tap0.

Let's say your physical network interface is eth0. eth0 and tap0 are entirely separate network interfaces. You can think of eth0 as your Wi-Fi router, and tap0 as your laptop connected to Wi-Fi. Your question is akin to asking how to reserve a port on your Wi-Fi router. It is unrelated to how to reserve a port on your laptop.

1 Like

Hi @sanxiyn thanks for your reply, it clears some stuff I didn't understand.

So just to make sure I understand this: I can set up a virtual network interface on my laptop (MacOS), and then the TCP stack I implement is in charge of ensuring that two different processes don't utilize the same port number (maybe a simplistic version is a file that lists all the ports that are in use).

Follow up questions:

1.) Do you have any recommendations on how to set up a virtual network interface on my laptop? I looked into tun/tap and it mentions that it's inactive (no longer maintained).

2.) Once I have a virtual network interface set up, I don't really understand how two TCP clients communicate over that interface. Once I take application layer data, split it up into packets, add header information, what do I do with the raw bytes? (ie how do I hand them over to the network layer assuming I have this new virtual network interface) A follow up to that is the same on the receiving end (how do I drop incoming bytes into a buffer to then collect these packets).

Thanks in advance your help on this. I have some understanding of the OSI model from classes, but never worked on a project that actually works across different parts of the stack.

@jonhoo has made a fantastic video series where he implements exacly that. Although it is around 12 hours total, I think it's worth looking into, especially the beginning where he sets up a virtual network interface.

I'm not sure how active he is here, but I'm sure he'll gladly answer your questions.

3 Likes

How to setup a virtual network interface is OS-dependent, and unfortunately I am not familiar with how to do so on macOS. smoltcp too doesn't support hosted mode on macOS.

TUN/TAP is how it is done on Linux, and it is well documented here: Universal TUN/TAP device driver — The Linux Kernel documentation. It is part of the stable interface of Linux kernel and well maintained. I am not sure where you heard it is inactive.

Send/receieve is pretty simple for TUN/TAP. You open /dev/net/tun, and you write to it to send, and you read from it to receive.

Side node: Some other OS's have TUN/TAP drivers too, e.g. FreeBSD, but FreeBSD's have a different API than Linux'.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.