Raspberry PI – wan emulation



PIWan project : Here is a new, quick & dirty project to be done with a raspberry PI : At work we currently have to simulate our application for a worldwide usage. We have really great tools for that but they need expertise and specific campaigns. The purpose of this document is to describe a RPI based solution with two Ethernet cards and some clever command lines to simulate a wan network for developers. The advantage of this solution will be to cost less than 100euros and will be easy to use with the right documentation.

See next pages for implementation details:

Hardware & system requierments

PIWan - hardware

PIWan – hardware

For the creation of this tool, I used a Raspberry PI B with the Ethernet connector + un usb ethernet device branded “delock” with a moschip component based on usb-bcm2708_usb-1.3, MOSCHIP 7830/7832/7730 usb-NET adapter using smsc95xx kernel module.

On the raspberry PI I run raspbian weezy distribution on 20130525 version.

The principle of the wan emulation is to limit and add delay on the traffic passing through the two Ethernet ports. The raspberry PI standard port (eth0) will be the wan interface : the one connected to the enterprise network. The Usb Ethernet port (eth1) will be the local interface : the one connected to the developer computer.

The wan interface setup will be based on DHCP

The local interface setup will be fixed and will provide IP to local lan based on dhcp server.

A the local traffic will be NAT over the wan interface and traffic limitation and delay will be applied.

A simple web interface will be displayed on local side for wan setting.

The following software have to be installed on raspbian :

apt-get install dnsmasq

Ethernet card configuration

Basically, the wan interface is already correctly configured on raspbian, getting automatically an IP address from the local DHCP with dns & co.

The local interface must be configure as static, I’ll choose for it.

ifconfig eth1 netmask up

switch this interface to NAT to route traffic and Nat all the traffic to the wan interface

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING --out-interface eth0 -j MASQUERADE 
iptables --append FORWARD --in-interface eth0 -j ACCEPT

Configure the dns masquerading and dhcp server

echo "interface=eth1" >> /etc/dnsmasq.conf
echo "dhcp-range=eth1,,,,4h" >> /etc/dnsmasq.conf
echo "dhcp-option=option:router," >> /etc/dnsmasq.conf

Restart dnsmasq service:

/etc/init.d/dnsmasq restart

Now it is possible to connect a PC on the local interface and it should be able to access Internet through the Raspberry PI.

Traffic control

Now it is possible to control traffic using TC. To be applied in both direction (input/output) the rules will be applied on the two interface eth0 and eth1 as qdisc works on outbound traffic only.

To limit the bandwidth:

tc qdisc replace dev eth0 root handle 1:0 tbf rate 1Mbit burst 2048 latency 500ms
tc qdisc replace dev eth1 root handle 2:0 tbf rate 1Mbit burst 2048 latency 500ms

Here, the latency indicates how many time a frame can stay in the queue before being dropped

To select the latency:

tc qdisc add dev eth0 parent 1:1 handle 10: netem delay 50ms 10ms
tc qdisc add dev eth1 parent 2:1 handle 10: netem delay 50ms 10ms

This add 50ms rtd for outgoing traffic to eth0 and 50ms rtd for outgoing to eth1, simulating a 100ms total rtd. On each it add a variance of 10ms.

Now, let us making it more user friendly !

The first step is to install a web server and activate cgi scripting:

   apt-get -y install lighttpd
   lighty-enable-mod cgi
   ln -s /usr/lib/cgi-bin /var/www/
   /etc/init.d/lighttpd force-reload

Create a simple web page to enter the parameters (/var/www/index.html) :

<form name="seting" action="/cgi-bin/exectc" method="post">
Latency(ms) :<input type="text" name="latency"> Variance (ms) : <input type="text" name="var"><br/>
Bandwidth(kbit/s) :<input type="text" name="bw"><br/>
<input type="submit" value="Configure">

Then add a cgi script to execute tc commands (/usr/lib/cgi-bin/exectc)

echo "Content-type: text/html"
echo ""
latency=`echo $REPLY | tr "&" "\n" | grep latency | cut -d "=" -f 2`
bw=`echo $REPLY | tr "&" "\n" | grep bw | cut -d "=" -f 2`
var=`echo $REPLY | tr "&" "\n" | grep var | cut -d "=" -f 2`
echo "<html><head><title>PIWan</title></head><body>"
if [ -z "$latency" ] || [ -z "$bw" ] || [ -z "$var" ] ; then
   echo "Erreur dans les parametres <br/>"
   echo "<a href="/"> Retour </a>"
   lat=$(( $latency / 2 ))
   sudo tc qdisc del dev eth0 root
   sudo tc qdisc del dev eth1 root
   sudo tc qdisc add dev eth0 root handle 1:0 tbf rate ${bw}kbit burst ${bw}K latency 5000ms
   sudo tc qdisc add dev eth1 root handle 2:0 tbf rate ${bw}kbit burst ${bw}K latency 5000ms
   sudo tc qdisc add dev eth0 parent 1:1 handle 10: netem delay ${lat}ms ${var}ms
   sudo tc qdisc add dev eth1 parent 2:1 handle 10: netem delay ${lat}ms ${var}ms
   echo "Resultat<br/>"
   tc qdisc | tr "\n" "#" | sed -e "s/#/<br\/>/g"
   echo "<a href="/"> Retour </a>"

To make this script working :

echo 'www-data ALL= NOPASSWD: /sbin/tc' >> /etc/sudoers
chown www-data:www-data /usr/lib/cgi-bin/exectc
chmod +x /usr/lib/cgi-bin/exectc

It is now possible to access the configuration page from the LAN interface using then enter the parameters. It rocks !

Make it simple

The attached script automatically execute all the configuration detailed above, including html and cgi file creation. You can install it on the raspberry PI and execute it to make it working.


Copy the file into /etc/init.d directory, then use command

update-rc.d PIWan defaults 20 20


Hope this will be usefull for you too !


6 thoughts on “Raspberry PI – wan emulation

  1. Experienced some problem today deploying it at work :
    – The delay to obtain an IP adress is a little bit too long, I add a 10s pause in the script to let it the right time. (script will be updated soon)
    – The IP range for the internal network was 10.x and the proxy avoid to reach the browser page. Just changed it for and it works
    – Also add a static dns entry piwan.disk91.com
    @Todo : add in the script the modification of config file (dnsmasq) when local IP has changed.
    @Todo : add a static dnsentry with wan IP obtained at startup.

  2. Worked great – thank you for this write up. Lenovo USB Ethernet (ASIX AX88772) also has the drivers built in on current Raspbian. Now to learn more about tc 🙂

  3. Hi, thanks for the post.
    I have been trying to implement this on my RPi and the script works fine. The only problem is when trying to configure via the website, I always receive the “Erreur dans les parametres” message. I have tried looking into the solution myself with no luck. Are there any alternative ways this can be done which may bypass my error?

      • I managed to get past the error by running the configuration website as a PHP file which calls the script that way.

        Thank you very much for the article, it has been very helpful for me.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.