A network stack for the xv6 operating system, written in Rust.
Building and running the xv6-net the project requries the following dependencies:
- A C compiler (e.g. GCC)
- Make
- Rust (and the i586-unknown-linux-gnu toolchain)
- QEMU
On Ubuntu-like operating systems, a C compiler (GCC) and Make can be installed
as part of the build-essential package:
sudo apt-get install build-essentialRust can be installed by following the instructions on the Rust project's
homepage. The
i586-unknown-linux-gnu toolchain can be installed using the rustup tool:
rustup toolchain install i586-unknown-linux-gnuQEMU can be installed via the qemu package:
apt-get install qemuIn addition to the standard Make targets provided by the xv6 project, the
xv6-net project adds a qemu-net Make target. This target uses QEMU's -nic
flag to emulate an E1000
family network device. The -nic
flag creates a new
TAP device which may require root
privileges.
The xv6 network stack supports a single interface which is assigned a fixed
address of 10.0.0.2.
The project can be built with make:
$ makeOnce built, the xv6 operating system can be started with the qemu-net target:
$ make qemu-netAfter assigning an address to the TAP interface:
$ ip addr add 10.0.0.2 dev tap0The xv6 operating system should respond to ping.
$ ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.026 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.035 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=0.021 msThe implementation of network stack adds 7 new system calls: socket, bind,
connect, listen, accept, send and recv. As only UDP is currently
supported, the listen and accept system calls are currently nops.
socket- Creates a new socket of the specified type (currently UDP only)bind- Associates a socket with a local address and portconnect- Associates a socket with a remote address and portlisten- Not implementedaccept- Not implementedsend- Send data to a remote socketrecv- Receive data from a remote socket
An example netcat like userspace program, nc, is provided to exercise the
network stack.
The nc program operates in two modes, client or server:
nc [-c|-s] [address] [port]In client mode (-c), the program will send data from stdin to the specified
port of the host located at address. For example, to send data to 10.0.0.1 on port 4444:
$ nc -c 10.0.0.1 4444
$ hello, world!In server mode (-s), the program will listen for data on the specified port.
To listen to data on port 5555:
$ nc -s 10.0.0.2 5555As the network interface has a fixed local address (10.0.0.2), the address
argument is currently ignored in server mode.
- The network interface is assigned a fixed address of
10.0.0.2 - The connect(...) system call is blocking on establishing the ARP resolution of the hardware address of the remote host.
- The send(...) system call is blocking on the successful write of a transmit descriptor to the network device.
- The recv(...) system call is non-blocking, returning immediately if no data is available. This is until the functionality of proc.c is ported to Rust.