Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time

Getting Started

Level-IP is a TCP/IP stack that is run as a single daemon process on your Linux host. Networking is achieved by configuring your Linux host to forward packets to/from Level-IP.

To interface applications against Level-IP, a wrapper library for standard libc calls is provided. This wrapper can then be used with existing binaries such as curl, surf and firefox to redirect communications to Level-IP.

DISCLAIMER: Level-IP is not a production-ready networking stack, and does not intend to be one. The nature of lower-level networking imposes a great responsiblity to the software and any security vulnerabilities can be disastrous. Hence, do not run Level-IP for extended periods of time, purely because it has bugs (and as all software, will continue to have them).


Standard make stuff.

$ make all

This builds lvl-ip itself, but also the libc wrapper and provided example applications.

When building, sudo setcap ... probably asks super user permissions from you. This is because lvl-ip needs the CAP_NET_ADMIN capability to setup itself. After the setup, it drops that capability.

Currently, lvl-ip also configures the tap interface through the ip tool. Hence, give it permissions too:

$ which ip
$ sudo setcap cap_net_admin=ep /usr/bin/ip


Level-IP uses a Linux TAP device to communicate to the outside world. In short, the tap device is initialized in the host Linux' networking stack, and lvl-ip can then read the L2 frames:

$ sudo mknod /dev/net/tap c 10 200
$ sudo chmod 0666 /dev/net/tap

In essence, lvl-ip operates as a host inside the tap device's subnet. Therefore, in order to communicate with other hosts, the tap device needs to be set in a forwarding mode:

An example from my (Arch) Linux machine, where wlp2s0 is my outgoing interface, and tap0 is the tap device for lvl-ip:

$ sysctl -w net.ipv4.ip_forward=1
$ iptables -I INPUT --source -j ACCEPT
$ iptables -t nat -I POSTROUTING --out-interface wlp2s0 -j MASQUERADE
$ iptables -I FORWARD --in-interface wlp2s0 --out-interface tap0 -j ACCEPT
$ iptables -I FORWARD --in-interface tap0 --out-interface wlp2s0 -j ACCEPT

Now, packets coming from lvl-ip ( in this case) should be NATed by the host Linux interfaces and traverse the FORWARD chain correctly to the host's outgoing gateway.

See for more info.


When you've built lvl-ip and setup your host stack to forward packets, you can try communicating to the Internet:

$ ./lvl-ip

The userspace TCP/IP stack should start. Now, first test communications with the provided applications:

$ cd tools
$ ./level-ip ../apps/curl/curl 80

./level-ip is just a bash-script that allows to take precedence over the libc socket API calls.

The important point is that ./level-ip aims to be usable against any existing dynamically-linked application. Let's try the real curl:

[saminiir@localhost tools]$ curl --version
curl 7.50.0 (x86_64-pc-linux-gnu) libcurl/7.50.0 OpenSSL/1.0.2h zlib/1.2.8 libidn/1.33 libssh2/1.7.0
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP UnixSockets
[saminiir@localhost tools]$ curl
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<H1>302 Moved</H1>
The document has moved
<A HREF=";ei=otEWWbbDGbGr8weExqg4">here</A>.

And instead of using the Linux' TCP/IP stack, let's try it with lvl-ip:

[saminiir@localhost tools]$ ./level-ip curl
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<H1>302 Moved</H1>
The document has moved
<A HREF=";ei=3NIWWZGjHqar8wf_kKf4Bg">here</A>.

The result is exactly the same. Under the hood, however, curl calls the libc socket API but these calls are redirected to lvl-ip instead.

Try browsing the Web, with Level-IP doing the packet transfer:

[saminiir@localhost tools]$ firefox --version
Mozilla Firefox 47.0.1
[saminiir@localhost tools]$ ./level-ip firefox

That's it!