Wednesday 28 January 2015

How To Power Your Raspberry Pi With a PC's PSU

Introduction

Well, putting a Raspberry Pi inside a PC case is not that difficult. But that's not what this tutorial is about: the main goal is to power the Pi with a standard PC power adapter.
I did this because I wanted to build a home server for file and printer sharing, but the tangled up cables attached to the Pi annoyed me. 

The Plan

Since I wanted to share files, I also needed a quite big storage space, so my plan includes a USB hard disk attached to the Pi. 
The idea is to power both the Pi and the hard disk with the same adapter. This is easily accomplished through a USB Y cable for external hard drives: that's a cable that can be attached to the hard drive on one side, while on the other side it forks into two type A USB plugs. 
One of the plugs carries both power and data, while the other only carries power. Since the power lines are shared by all of the plugs, it's sufficient to connect only one of them with the power source: that will be the power-only plug, while the power and data plug will be connected with the RaspPi.



The Raspberry Pi will be back-powered through its type A USB receptacle: the fuse protection will be bypassed, because the fuse is located right after the micro USB socket, but in my experience this should not be a problem. I think that a standard PC power supply should have this kind of protection built-in anyways.

I used the PC's power supply to power the Pi, but the latter is not tied to the PC's power state: the PC can be turned off and the Pi will still function correctly. The idea is that the Pi will be shut down infrequently, mainly because of its low power consumption and its use as a server.

I attached a USB receptacle to the power supply by modifying a couple of cables. This step requires some basic soldering skills.

All in all it's not a dangerous process, but you may be worried about the stability of such a system, and possible fires or short-circuits or who-knows-what. As always I don't take any responsibility and you do everything at your own risk. As long as you're a bit careful though, you won't need to face these catastrophic circumstances.

Requirements

Since this project requires a hardware modification, you will need specific tools and components:
  • Soldering iron
  • Solder supply
  • USB extension cable
  • Wire cutters or strong scissors
  • Heat-shrink tubing
  • Heat gun
You will also need some basic soldering skills.

USB receptacle

One of the forked USB cable plugs must be connected to a USB receptacle to receive power, so the first step is to get a USB receptacle with wire. 
The easiest way to get what you need is probably to buy a USB extension cable, that is a cable with a USB type A receptacle at one end and a USB type A plug at the other end: just cut the plug away with a pair of scissors, and expose the four internal wires. The black wire is intended to be ground (negative side of the circuit) while the red one should bring positive voltage.

I didn't want to buy a new USB extension cable or use one that I had, so I made my own cable. I desoldered the receptacle from a non-working USB power adapter, and I soldered two wires to it. I applied some glue in the area between the joints in order to round its shape, then I enclosed everything with heat-shrinking tubes.
The result, more or less equivalent to a USB extension cable with the plug cut off, is shown in the picture.
Note that I connected only two wires: that's because this cable is never going to transfer any data, so the data wires are not necessary.

If you cut the extension cable, you will find four wires inside it. You are only interested in the red and black ones, which are respectively for positive voltage and ground. This picture I found on the web shows the wires:
Free the ends of the red and black wires from their plastic casing, because you're going to solder them.

ATX cable

Now let's take a look at the PC's PSU (Power Supply Unit). The first thing you want to know is the amount of standby current it can provide. You can usually find this information on the PSU's label:
The standby voltage is 5 V, and it's labeled as +5Vsb. In my case, the maximum current amounts to 3 A, for a total of 15 W max power-draw. To power a Raspberry Pi and 2.5" hard disk you will need at least 1.5 A, let's say 2 A to be on the safe side. If you won't use a hard disk then 0.5 A will be sufficient.
The PSU has a cable with many connectors, but for this task you're interested in only one of them: the one that is attached to the motherboard. Nowadays most desktop PSUs and motherboards follow the ATX design standard. Connectors can have 20 or 24 pins, but the location of the wires that you're going to modify doesn't change. Pay some attention to the following diagram, which shows the pin disposition of the male connector (the PSU's end as opposed to the motherboard's).

Pin 9 (marked as +5VSB in the picture) is the one carrying the standby current. Mark the wire that ends in this location, so that you can easily identify it later. The other wire should be one whose pin is marked as COM in the picture. It doesn't matter which one you pick, as long as it's marked as COM: that's a ground wire and it's usually black. I chose pin 7, because it's the nearest one with respect to pin 9.
Since I didn't want to directly modify the PSU's wires (who knows what could go wrong?), I bought an ATX extension cable for just a few bucks and I modified it instead. The process is the same: you have to identify the wires based on their pin location. An ATX extension cable looks like this:
If you search on the Internet for schemes of the wires, you may find a reference to the wires' colors. Since the colors are not always standard (an example is my extension cable, as seen in the previous photo), I suggest you don't rely solely on this information.
Here I marked the wires/pins of interest:
Once you have identified the two wires, cut the Vsb one with a wire cutter and remove insulation at the cut ends. Insert a heat-shrinking tube of appropriate width on one end, and get ready to solder together three wires: the two ends of the Vsb wire and the red wire from the USB receptacle we prepared earlier. The next picture shows a black wire, but let's just pretend that it's red for now.

Carefully apply some solder with your soldering iron...
 ...hopefully doing a better job than I did.
When the joint has cooled, slide the heat-shrinking tube over it.
 Finally apply heat with a heat-gun.
A
Repeat this process to join the other wires together.
This is the resulting item:
Now you just have to connect the cables the right way. Remember to attach the power-only plug of the Y cable to the USB extension you just made:
Finally connect the USB cable and the Raspberry Pi. This is the final result:
If you have a Model B+, a cleaner solution might be to connect the Raspi with a micro-USB cable and power the hard disk through the Raspi. If that's what you intend to do, be sure to add one or both of these flags to config.txt in the SD card's boot partition:

 safe_mode_gpio=4
 max_usb_current=1 


Conclusion

I just showed you how I connected my Raspberry Pi to my PC's power supply unit. Now it can also benefit from the UPS that I attached to the PSU. I like this solution mainly because this way there are less cables around (just one for ethernet) and because of the increased power stability (lots of amps and UPS).

Saturday 27 September 2014

How to use Marionnet and create networks of relativistic virtual machines


Marionnet


This tutorial will guide through the creation of a simple virtual network with Marionnet.

Devices


Let's take a quick look at the devices that Marionnet offers:



Machine


This is the representation of a classical computer running Linux. Usually the end point of a communication, it's emulated with User Mode Linux, and offers all its functionalities.

Hub


A hub is layer 2 device that just relays frames to all its connected ports. Nowadays in real life hubs are often replaced by switches, but hubs can make it easy to intercept frames transmitted between multiple devices, so you could place one if you plan on capturing frames with auditing tools like wireshark.

Switch


You can think of a switch as smart hub. Instead of blindly repeating the signals received, a switch forwards received frames only to ports that lead to the destination host. Use it to create simple or complex local area networks. The switch is implemented with VDE. If you want to try complex experiments with switches, be sure to check out Virtual Square's wiki: http://wiki.v2.cs.unibo.it/wiki/index.php/VDE .

Router


A router is a machine that can connect multiple subnetworks together. In Marionnet routers are implemented with a User Mode Linux process running on a small filesystem that includes the quagga routing suite. The filesystems provided by Marionnet are named Pinocchio and Guignol.

Straight cable


Marionnet makes the distinction between stright cables and crossover cables: the connection will not work if you chose the wrong cable type. Straight cables are able to connect different kinds of devices.

Crossover cable


Marionnet makes the distinction between stright cables and crossover cables: the connection will not work if you chose the wrong cable type. Crossover cables are able to connect machines of the same kind.

Unknown layer 2 sub-network


This is the abstract representation of an unknown subnetwork. We don't know what is in the cloud, we only know what enters it and what comes out of it. Although the effects in the virtual network are the same as those of a hub, this element highlights a lack of information about the network topology.

Real world access


Under this section you will find two subdevices called Gateway and Bridge. These can be used to connect the virtual network with the real network of your host machine.

Simple network


Let's start by creating a very basic network with Marionnet. We will create two machines and connect them with a cable.

Before adding the devices, we need to specify a location for our new project. Click on Project and select New from the menu. A classic path selection window will appear. Navigate to the location where you want your project to be saved and choose a file name for it. Marionnet is somewhat picky with project file paths: it will not accept some special characters, but it will not warn you either. This should not be a problem if you don't choose fancy path names, but be wary of the ' ' character (whitespace) because it won't be accepted.

The file name should also not include dots '.', because the first dot will be interpreted as the beginning of the extension, which must be .mar
After creating the project file, you will find yourself with an empty canvas. It's time add some devices!
Click on the Machine icon on the left, and select add from the menu.
 A popup with a form will appear, asking you to configure the new machine.

You can type any name for Name and Label (the latter is optional). I suggest labelling the machine with the IP address that you intend to assign it.



Hardware

For this example you can leave Memory and Ethernet cards to their default value. User Mode Linux doesn't need much memory, and you will probably want more only for running graphical programs like wireshark.

Machines can have multiple ethernet ports, but in our example we need only one port per machine.



Software

The Distribution field instructs Marionnet on what filesystem it should use for the new machine. A few filesystems are already provided by marionnet, but you can add your own to the list, if you wish. If you installed Marionnet with marionnet_from_scratch with the default parameters, it will look for virtual filesystems in /usr/local/share/marionnet/filesystems. You can change this location by editing /etc/marionnet/marionnet.conf. If you want your custom filesystem to be recognized by marionnet, be sure to name the file with the prefix “machine-”.

Variants are modified versions of the standard filesystems, and are handy if you want to run a copy of the same machine in multiple networks or projects. For now, you can safely ignore this field.

The Kernel field allows you to select the UML (User Mode Linux) kernel version to use. Marionnet provides its own patched kernels, but you can easily build your own. The mechanics are similar to those for filesystems: the default location is /usr/local/share/marionnet/kernels, files must be named with the prefix “linux-”.



Access

I see no reason to edit this field, but if desired here you can change the way that X windows are displayed.



Relativization

I added this section myself, and I don't know if it will be included in the official Marionnet project. To experiment with the relativization feature, get the patched Marionnet, or just the patch. For information on compiling and installing Marionnet check out its wiki.

The controls in this section let you change the virtual frequency of properly patched UML machines. The Frequency field sets the frequency of the virtual clock. It is expressed as the number of Hz of the virtual frequency: the number of virtual seconds elapsed for each real second. A value less than 1 will generate a virtual time slower than the real one, while a value greater than 1 will generate a virtual time faster than the real one. Note that this doesn't affect the speed of operation. Indeed, from the point of view of virtual machines with high frequency all operations will seem proportionally slower!

Convergence is the point in time when real and virtual time are the same. For virtual frequencies different than 1, the virtual time will diverge from this point, meaning that at great time distances the virtual date and the real one will look very different. The value of Convergence is expressed as a Unix timestamp, that is the number of seconds elapsed since the Epoch (00:00:00 UTC, 1 Jan 1970).

When you're done click on OK. Repeat the process to add the second machine.

To connect these machines we're going to add a crossover cable. Click on the Crossover cable icon and select Add. In the dialog that appears you can name the cable and optionally assign a label to it. More importantly, you can choose the names of the machines that you want to connect and their port numbers. In our case we're fine with the default values.


The resulting network graph should look like this:


Let's start up the machines by clicking on the Start all button. After a while two terminal emulator windows will appear. Login in both terminals with the default username/password: root/root. When you create networks with lots of machines, all those terminal windows could be confusing. To find out the machine which the terminal is attached to, look at the window's title: it will show the machine name and, in parenthesis, the virtual filesystem image.

Before the machines can talk to each other, you must configure them. In my debian wheezy image I have the ip command, so I can issue this:
[0 root@m1 ~]$ ip addr add 192.168.50.2/24 dev eth0
[0 root@m1 ~]$ ip link set eth0 up
[0 root@m2 ~]$ ip addr add 192.168.50.3/24 dev eth0
[0 root@m2 ~]$ ip link set eth0 up
If ip is not installed, try with ifconfig:
[0 root@m1 ~]$ ifconfig eth0 192.168.50.2/24 up
[0 root@m2 ~]$ ifconfig eth0 192.168.50.3/24 up

Now the machines should be properly connected. Let's test them by pinging m2 from m1:
[0 root@m1 ~]$ ping -c 3 192.168.50.3
PING 192.168.50.3 (192.168.50.3) 56(84) bytes of data.
64 bytes from 192.168.50.3: icmp_req=1 ttl=64 time=0.827 ms
64 bytes from 192.168.50.3: icmp_req=2 ttl=64 time=1.03 ms
64 bytes from 192.168.50.3: icmp_req=3 ttl=64 time=0.809 ms

--- 192.168.50.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 0.809/0.889/1.032/0.104 ms
As you can see we have correctly set up the network.
To shutdown the machines, click on the Shutdown all button in the bottom of Marionnet's window. You can also shutdown the machines individually by clicking on the Machine icon and selecting Stop, then the machine name. The opposite can be achieved by selecting Start.
Now we want to save the project, so click on Project and select Save or Save as. If you try to close the project without saving it, Marionnet will warn you and ask if you want to save. The saved project will keep all the machines disk information, but the changes made by the commands we issued were not stored, so the next time when you open the project you will have to configure the machines again.

Adding Real World Access: Gateway

There are many reasons why you may want to connect your virtual network to the real world, but you usually want it to install new packages in the virtual filesystems. Read on to find out how to achieve this.
On the left panel you will find the Real world access icon. After clicking it you have to choose between two types of device. In the wiki you can read a guide on how to use Bridge. I recommend choosing Gateway as way to access the host network because it is much simpler to set up.
Select Gateway, then Add. This window will pop up:





Name and Label fields are unimportant, since usually you don't need more than one gateway to the real world in your virtual network.
By modifying the IPv4 address fields you can set the address that the gateway will have inside the virtual network, meaning that virtual devices must be configured to connect to this address. For this example set the address to 192.168.50.1/24.
If DHCP service is checked the gateway will keep and internal pool of IP addresses and automatically assign them to devices that wish to connect to it. DHCP is quite handy, so we're going to check the box.
Integrated switch ports is self-explaining: it is the number of ports of the integrated switch. The default is 4, meaning that up to four devices can directly connect to this gateway simultaneously. For our purposes the default is fine.
When you're done click the OK button.
Now you have to connect machine m1 to gateway G1. Marionnet's gateway device has the Auto-MDIX feature, so either a straight cable or a crossover cable can be used to connect the gateway.
For example, you could modify the cable you added earlier: click on the Crossover cable icon and select Modify, then just change m2 to G1 in the To section (or From, if you attached the cable that way).
If you are logged in m1 as root, I suggest you logout and log back in as a regular user. The default regular username is “student”, with password “student”. Changing the password could be a good idea, and you should feel free to take additional security measures. We you are ready, insert this in m1's terminal emulator have it be automatically assigned an IP address by G1:
[0 student@m1 ~]$ sudo dhclient eth0
Now you are connected to same network as your host machine, so if you connect your machine to the Internet you will be able to access it from m1. My ping tests failed, probably because ICMP requests are filtered at some level. You can still test the connection with something like telnet:
[0 student@m1 ~]$ telnet www.google.com 80
Trying 173.194.65.147...
Connected to www.google.com.
Escape character is '^]'.
(press ctl+C to terminate the connection) or with web browsers like lynx and links.
Now that you have a working internet connection, you can download and install distribution packages. If you want to install distribution packages, now you can do that. Mind that before installing, you must download the package index files (aptitude update) and that can take time, as well as disk space. Try installing pv and mtr:
[0 student@m1 ~]$ sudo aptitude update && sudo aptitude install pv mtr-tiny
Aptitude seems to be unbelievably slow in Marionnet's virtual machines, so the console might appear to be stuck during the update, but you have to be patient. Grab a cup of coffe or make good use of your operating system multitasking feature.

Variants

After booting up your virtual machines, sometimes you make permanent changes to them, i.e. You modify their filesystem status. Normally, when you save the project the filesystem status of all the virtual machines within the project is saved. What is actually stored though is the differences between the standard Marionnet's filesystem image and the modified one.
The new filesystems are limited to their respective project and cannot be reused for new machines. Sometimes you may want to export modified filesystems for reuse in other projects, for example if you installed new packages that you use often: you have to create Variants.
Let's create a variant for the current status of machine m1's filesystem (where you installed some packages).
If the virtual machines are still running, click on the Shutdown all button to stop them.
On the lower part of Marionnet's main window, click on
Disks to bring up that tab. You will be shown a list of the machines present in the current project. Click on the left arrows to expand the rows. Expand m1 until you reach the last level, then right click on it. Select Export as machine variant.



 

Write the name for the new variant in the dialog that appears, following the rules explained in it. After clicking OK it will take some time to save the data on disk, so be patient.
Now, when you add a new machine with the same base filesystem as the one of the exported variant, you can choose the variant from the menu.


 

Relativization experiment

This example shows how to set up the relativization parameters to test a well-known clock synchronization protocol: NTP.
We want a simple network consisting of two connected machines. If you followed the steps described in the Simple network tutorial you know how to set it up.
When adding the machines, or later by modifying them with Machine → Modify → m1/m2, you have to change the relativization parameters. Set m1's frequency to 10.1 and m2's frequency to 10.0. Set the convergence value to something near the current time. You can get the current time with unix “date”:
asig@asig-laptop:~$ date +%s
1408721348
If you set the convergence time to something too far in the past you can cause critical errors in the virtual machines. This is especially true if your virtual kernels are for the x86 32 bit processor architecture, because internally they use a smaller amount of memory to represent timestamps.
The frequencies chosen differ, so eventually (actually, almost immediately) the time kept by the two machines will differ: they are not synchronized. Why did we set virtual times that are 10 times faster than real time? NTP gradually adjusts timekeeping in order to synchronize the local machine's frequency with the frequency of other machine's clocks. This process, that includes regular information requests, is rather slow, mainly not to cause errors in the local machine's programs. Since maybe you don't want to spend a lot of time for this experiment, I chose higher frequencies to hasten the process. The higher frequencies come with less accurate virtual clocks, but we don't mind too much for the purposes of this example.
Start all the devices by clicking Start all. Set m1's and m2's addresses to 192.168.50.2 and 192.168.50.3 m1 will be the client and m2 will be the server: m1 will try to adjust to m2's frequency. In m1 edit /etc/ntp.conf (that is the NTP configuration file). To keep things simple it's best to erase the contents of the file, then add the following lines:
#Server to query
server 192.168.50.3 iburst minpoll 4 maxpoll 6
server 127.127.1.0

#Calculate and store drift
driftfile /etc/ntp.drift
This way m1 will ask 192.168.50.3 (that is m2) for the correct time, and it will ask itself if m2 is not reachable. The flag iburst instructs the NTP deamon (ntpd) to send more requests at startup, while minpoll and maxpoll are useful to reduce the time elapsed between requests.
Now edit m2's ntp.conf so that it looks like this:
#Self-sync
server 127.127.1.0 iburst

#Respond to local requests
restrict 192.168.50.0 mask 255.255.255.0 nomodify notrap
This way m2 will synchronize with itself, and will act as an NTP server for the 192.168.50.0/24 network, that includes m1.
Before starting the ntpd daemon, verify that the two machines are not running at the same frequency. You can check the current setting for the frequency like this:
[0 root@m1 ~]$ cat /proc/uml_reltime/frequency
10.1000000000
[0 root@m2 ~]$ cat /proc/uml_reltime/frequency
10.0
However, if you want to have more visual feedback, you could compare the seconds ticking on two graphical clocks:
[0 root@m1 ~]$ xclock -update 1 &
[0 root@m2 ~]$ xclock -update 1 &
Two windows will pop up, showing you two traditional analog clocks. A 0.1 Hz skew is quite big, so this difference can be easily seen.
If you don't like the idea of launching a graphical application just to check the time, you may obtain a similar effect with these commands:
[0 root@m1 ~]$ watch -n 1 date
[0 root@m2 ~]$ watch -n 1 date
When you are ready, start the ntpd daemon on both machines:
[0 root@m1 ~]$ /etc/init.d/ntp start
[0 root@m2 ~]$ /etc/init.d/ntp start
If you keep monitoring the two clocks you will see that, given enough time, they will show approximately the same values. In contrast with the difference in frequency, with time the two clocks will progressively converge. Note that, if the initial offset between the clocks is too big, ntpd will panic and you will not be able to see the convergence. To solve this, try to set the clocks to the same value, reduce the frequency offset, or set the Convergence field to some point in the near future.
Wireshark
To better monitor NTP doing its job, you could observe the packets exchanged. Wireshark is a graphical packet sniffer tool included in Marionnet's debian filesystems. Is is very useful to localize network problems and to understand routing and switching, among other things.
Start wireshark in m2:
[0 root@m2 ~]$ wireshark &
When the window has been loaded, select Capture → Interfaces, check the box next to eth0, then click Start.

Adding switches and routers

This tutorial assumes that you know the basics explained in the simple tutorial, and you set up a network like the one described there.
If you have saved the project described in the simple tutorial, open it by clicking on Project, selecting Open and choosing the correct project file.
This is how the network looks like:





We want to add a third machine, and connect all three machines together. Start by adding a new machine as described in the simple tutorial and set its label to the address you want to assign it: 192.168.50.4/24. Remember that if you want to change the label or other parameters later, you can do that by shutting down the machine, clicking on the Machine icon and selecting Modify. The form is the same as that generated when you add a machine, with the exception that you can't change the filesystem. So you can change most parameters at any time, if the the machine that you are interested in is not running.

We have three machines, each with only one ethernet port. To connect them together, the best solution is to add a switch: all the machines will be connected to the switch, and the switch will forward packets between the machines. Click on the Switch icon and select Add:

The default settings are fine.

Now we have to attach cables to our devices, but first the crossover cable must be removed. Click on the Crossover cable icon on the left panel and select Remove: you see a list of all the cables name, which for now includes only d1. Click the name to remove the cable and confirm by answering Yes to the following question.

Add three cables. We are connecting machines to a switch, so we need straight cables. Click on the Straight cable icon and select Add. You will notice that the dialog looks just like that of the crrossover cable. Select name m1 and port eth0 in the From section and name S1 and port port1 in the To section. The port number of the switch doesn't actually need to be exacly 1, you can select any port. Also note that even though the dialog sections are named From and To, ethernet cables are actually bidirectional and without orientation, so it doesn't matter if you invert these fields.

Repeat the process for the other two machines and you will obtain something like this:



 
You may notice that one of the cables is twisted, and that could be a little confusing when you build a complex network. The default setting for displaying cables is a “top-to-bottom” arrangement, which will try to place the devices on the canvas in a vertical fashion. You can change this behaviour by clicking on the right-pointing arrow icon in the right panel. This is how the canvas will look like:
 
Alternatively, you could invert the cable placement in the image: click on the circling arrow in the right panel and select the name of the cable that you wish to move.



Now let's start everything by clicking on the Start all button on the lower panel.

Only three terminal windows will appear, because we didn't check the Show VDE terminal option when we added the switch. However, the switch ports can be checked for connectivity by looking at the little window that popped up beside the terminals: the green leds indicate activity on the corresponding ports.

It's time to configure the machines. Since we plan on using this network again, this time we will set a permanent configuration in the machines' filesystems. I will show you the easiest way to store network configurations in debian, although there are other methods for different distributions.

Login with root/root in every terminal. Edit the file /etc/network/interfaces. I like the vim editor and I found it preinstalled in the virtual filesystems, so that's what I used for editing the files. Other editors that I found preinstalled are vi and nano, but there may be other ones that I don't know of. In the future I will also show you how to install packages from the Internet on the virtual machines, so you shouldn't worry if your favourite editor is not already installed. Anyways, this is how the file for machine m1 looks like:
[0 root@m1 ~]$ vim /etc/network/interfaces

# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
That two lines will make the loopback network interface be brought up when the system boots.
Add these lines to bring up the eth0 interface with a static IP address when the system boots:
#static address for eth0
auto eth0
iface eth0 inet static
address 192.168.50.2
netmask 255.255.255.0
The meaning is pretty straightforward. Read this for more information on setting a static IP in Debian. The netmask is here written in the dot notation, whereas before we used to write it with the “/24” suffix.
To quickly make the changes effective without restarting the machine:
[0 root@m1 ~]$ service networking restart
Now test the connection between any couple of machines, with ping:
[0 root@m1 ~]$ ping 192.168.50.4
PING 192.168.50.4 (192.168.50.4) 56(84) bytes of data.
64 bytes from 192.168.50.4: icmp_req=1 ttl=64 time=2.31 ms
64 bytes from 192.168.50.4: icmp_req=2 ttl=64 time=1.25 ms
64 bytes from 192.168.50.4: icmp_req=3 ttl=64 time=1.10 ms
64 bytes from 192.168.50.4: icmp_req=4 ttl=64 time=1.21 ms
64 bytes from 192.168.50.4: icmp_req=5 ttl=64 time=0.460 ms
64 bytes from 192.168.50.4: icmp_req=6 ttl=64 time=1.06 ms
^C
--- 192.168.50.4 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5023ms
rtt min/avg/max/mdev = 0.460/1.235/2.310/0.548 ms
This shows that m1 and m3 are connected.
You may also try to compare these ping statistics with the ones we got in the Simple network experiment. In my case the number of test packets is quite small, so it's not an accurate estimation, but the results show that our new network has a slightly higher round trip time (rtt). This is probably caused by a little overhead induced by the switch. It's nothing to worry about, but in a large network this effect may become noticeable.
Let's add more machines to create a separate network. Add two machines, named m4 and m5, and assign them the addresses 192.168.100.2/24 192.168.100.3/24 respectively.
To quickly assign the addresses permanently you can make use of the Interfaces tab. Click on its name in the lower part of Marionnet's window. You will find a list of all of your project's level 3 devices. Expand the rows to see their interfaces (ports). You can change the MAC address of the interfaces, their MTU, and their IP parameters. Click on a field to edit its value. Set m4's IPv4 address and IPv4 netmask to 192.168.100.2 and 255.255.255.0. Repeat to set m5's address. When you start the machines they will be automatically assigned the addresses you set.

 

In this screenshot I was reducing the minimum edge size (cable length) by moving the slider in the right panel. This way I can see the whole network topology in one screenful.
Notice that the addresses for the new machines define a new subnetwork, because the netmask 255.255.255.0 implies that only the addresses whose first 24 bits (3 bytes) match (between addresses) belong to the same subnetwork.
To verify this, connect the new machine to the switch with a straight cable, configure the machine with the address that you wrote in its label, and start the machine (you can start it with MachineStart → m4 or with the Start all button). If you try pinging from, say, m1 to m4:
 
We need a router to connect the subnetworks together.
Click on the Router icon in the left panel and select Add.

 
In marionnet a router is simply a machine with the quagga routing suite installed and running. In the Add router dialog you will find familiar parameters, like filesystem and kernel images. Marionnet provides “Pinocchio” and “Guignol” as router filesystems. The latter is not included in the stable version, but a script is available in the development version to create it.
In addition you can pre-configure the IP address of the first port of the router, port0, and optionally enable or disable the virtual terminal window for this device. The reason behind this is that port0 has by default some open TCP ports in order to let you access the router terminal via ssh, or the quagga daemons via telnet, so if you know its address you will not need the terminal window. In this example however I suggest you check the Show unix terminal item in the Access section.
The help window (accessed by clicking the Help button) will show you, among other things, a brief reminder of the usernames, TCP ports, and password required for accessing the quagga daemons via telnet.
Select the address 192.168.50.1/24 for the first port. We're going to set the address for the second port via the unix terminal.
Start up the router with the Start all button.
Login as root/root and set the eth1 interface to 192.168.100.1/24:
[0 root@R1 ~]$ ip addr add 192.168.100.1/24 broadcast 192.168.100.255 dev eth1
[0 root@R1 ~]$ ip link set eth1 up
The router is already configured to forward packets between its interfaces, so we're almost done. Connect the router to the switch with a straight cable: be sure to attach one end to port0 of router R1. We want to connect both m4 and m5 to the network. We have two choices: we can connect m4 and m5 directly to R1 with crossover cables, or add one switch and have it connected with m4, m5 and R1, using straight cables. The first alternative looks a bit weird to me, because the addresses that we choose suggest that m4 and m5 belong to the same subnetwork. Indeed, that's why I chose those addresses. So let's add another switch with default parameters and call it S2.
After adding the new switch remember to start it by clicking Start all.
We need to attach three straight cables: one to m4 and S2, one to m5 and S2, and one to S2 and R1. Be sure to attach the last one to port1 of R1, like this:
  Once everything is connected, it will look like this:

 
At this point I actually tried to ping m1 from m5. As you might have predicted, my test failed because the network was unreachable. This happens because m5 doesn't know where to send packets that are not destinated to its own network. To fix this, set the default gateway for m5:
[0 root@m5 ~]$ route add default gw 192.168.100.1 eth0
 To make this change permanent, add this line to /etc/network/interfaces
gateway 192.168.100.1
Now try to ping m1:
 
This time the network is not unreachable, but we can't receive any response packets. This is because we added the default gateway only for m5, but not for m1. m1 receives our packets, but then it doesn't know on which interface it should send the response. Add the default gateway for m1:
[0 root@m1 ~]$ route add default gw 192.168.50.1 eth0
Now the ping finally succeeds. Until now we always used ping to perform our tests, but there are other tools as well. For example, “traceroute” will show us the path taken by packets to reach their final destination (their route will be traced):
 
As you can see, the packets go through R1 before reaching m1. The result is quite obvious given our network topology and our static routing policy, but in a network that includes many routers and dynamic routing it might help you find errors in the routing policies. Another good tool is mtr. Try it, it basically is like ping and traceroute in one single command.

Set the default gateway in a similar way for the other machines to connect them together. If you want to save the gateway to permanent memory, edit /etc/network/interfaces like this:
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback

#static address for eth0
auto eth0
iface eth0 inet static
address 192.168.50.2
netmask 255.255.255.0
gateway 192.168.50.1
That's the configuration file for m1, where we added the last line.

Relativization experiment

It's time to play with relativization again. This time you will see how the virtual network bandwidth is affected by time relativity. You will simply transfer one big file between two machines.
If you have previously installed the pv package and exported a variant of the filesystem, you won't need to do that again. The pv program is easy to use and it provides a good visual feedback, but there are good alternatives, so don't feel forced to install it.
Remove machine m3 and add it back with the variant you created. Start everything up, and login in m3 and m5. Test the connection between m3 and m5 with the usual ping command. Alternatively if you installed the package mtr-tiny you can test the connection with mtr, although you would find more use for it if you had to diagnose more complex network problems.
[0 root@m3 ~]$ mtr 192.168.100.3
Netcat is yet another useful tool, often rightfully regarded as the swiss army knife of networking. IN this instance you will use netcat to create a simple TCP stream between m3 and m5.
Set up m5 as the server:
[0 root@m5 ~]$ nc -l -v -p 30000 > /dev/null
The '-l' flag tells netcat to listen for new connections. The '-v' makes netcat verbose and '-p 2000' specifies the TCP port to listen on. The output will just be thrown away (/dev/null).
You want m3 to be the client that sends data to m5, but first you must create some data to send:
[0 root@m3 ~]$ truncate -s 20M newfile
[0 root@m3 ~]$ pv newfile | nc -w 3 192.168.100.3 30000
With truncate you create a new sparse file called “newfile”, of size 20 MB. The second line tells netcat to connect with m5, with the input given by pv. You will immediately see a loading bar, and statistics like transfer speed. This is what it looks like after the file has been transfered:
20MB 0:00:48 [ 424kB/s] [==================================>] 100%
So the virtual bandwidth is approximately 400 kB/s.
Now shutdown everything with the Shutdown all button. In the upper menu bar select Options → Relativization. This is the dialog that you will get:

It contains the same relativization parameters that you can modify in machine and router Add/Modify dialogs. The values that you select here will be used as default when you add new machines or routers. If you leave the option Apply to existing machines checked, the values will also be applied to machines and routers that you already created, provided that they are not running. Leave the option checked and set frequency to 0.4 and convergence to any value, preferably near the current time. When you're done click OK. You can check that the values have been changed by opening the Modify dialogs for any machine or router.
After applying the new parameters, click Start all to restart the network. Connect m3 and m5 with netcat as before, and transfer the 20 MB file. This is the output for m3:
20MB 0:00:19 [1.01MB/s] [==================================>] 100%
As you can see, this time the tranfer was perceived as much faster by m3, and the speed was around 1 MB/s. Let's compare with speed with the one we got without relativization. We notice that
(1 MB/s) / (0.4 MB/s) = 2.5
So by decreasing the virtual frequency by a 0.4 factor, we get a transfer speed two times and a half faster than normal. This happens because the virtual machine perceives time as running slower, but the real transfer speed actually remained the same, so the virtual machine thinks that only 19 s elapsed after starting the transfer, instead of the real 48. In fact, 2,5 is the factor by which the virtual speed is increased and it's the inverse of the virtual frequency.
If you are interested in relativization, try other commands like ping and see how they are affected by frequency. This feature is also potentially useful to test the behaviour of your own programs.

Defects

Marionnet offers the possibility to introduce defects in various devices. We will see how to set the defects through some examples. The network used in the example is the one built in the Switch and Router tutorial.

In the bottom of the Marionnet window there are four tabs: Image, Interfaces, Defects, Disks.

Until now you probably used the Image tab most of all, because it lets you view the network topology, but the other tabs have useful functions as well.

Click on the Defects tab on the lower part of the window.

 
As you can see the Defects tab presents a list of all the devices in the network, including cables. If you expand anything that is not a cable, it will display the list of its own ports/interfaces. Cables and ports can be edited to introduce defects in them. You can alter the properties of frames in either one or both directions.

There are five editable numeric fields: Loss, Duplication, Flipped bits, Minimum delay, Maximum delay. All of them accept rational numbers as input. To edit one field just click on it (initially all fields will be 0), write the new value for it, and click somewhere else or press Enter. You can edit these parameters even while the devices are running. Do not enter empty strings as values, because Marionnet will not like it.

In the example I chose the cable named d1, which connects machine m1 with switch S1, and tried to add defects to it.

Loss

It's simply the percentage of lost frames. For example, if you set it to 50, approximately one half of the frames that go in the chosen direction will be lost. This is a ping test from m1 to m2, where the cable connecting m1 to S1 drops 50% of the frames destinated to S1.
[0 root@m1 ~]$ ping -c 6 192.168.50.3
PING 192.168.50.3 (192.168.50.3) 56(84) bytes of data.
64 bytes from 192.168.50.3: icmp_req=1 ttl=64 time=1.17 ms
64 bytes from 192.168.50.3: icmp_req=2 ttl=64 time=1.40 ms
64 bytes from 192.168.50.3: icmp_req=3 ttl=64 time=1.40 ms
64 bytes from 192.168.50.3: icmp_req=4 ttl=64 time=1.11 ms

--- 192.168.50.3 ping statistics ---
6 packets transmitted, 4 received, 33% packet loss, time 5030ms
rtt min/avg/max/mdev = 1.119/1.273/1.405/0.137 ms
Ping sent 6 packets, but received only 4 responses. The estimated packet loss is 33%, because we tested only a few packets. The more the packets sent, the more accurate the estimation would be, because we actually set the probability of loss, so it's not always exact.



Duplication

In a way this is like the opposite of frame loss: some frames are duplicated. As with Loss, the field represents the probability of errors of this kind to be present in the communication.

This is a ping test from m1 to m2, with Duplication set to 25 in the m1-to-S1 direction.
[0 root@m1 ~]$ ping -c 8 192.168.50.3
PING 192.168.50.3 (192.168.50.3) 56(84) bytes of data.
64 bytes from 192.168.50.3: icmp_req=1 ttl=64 time=1.18 ms
64 bytes from 192.168.50.3: icmp_req=2 ttl=64 time=1.16 ms
64 bytes from 192.168.50.3: icmp_req=3 ttl=64 time=0.513 ms
64 bytes from 192.168.50.3: icmp_req=4 ttl=64 time=0.947 ms
64 bytes from 192.168.50.3: icmp_req=5 ttl=64 time=1.24 ms
64 bytes from 192.168.50.3: icmp_req=6 ttl=64 time=1.25 ms
64 bytes from 192.168.50.3: icmp_req=7 ttl=64 time=1.29 ms
64 bytes from 192.168.50.3: icmp_req=7 ttl=64 time=1.30 ms (DUP!)
64 bytes from 192.168.50.3: icmp_req=8 ttl=64 time=0.800 ms

--- 192.168.50.3 ping statistics ---
8 packets transmitted, 8 received, +1 duplicates, 0% packet loss, time 7156ms
rtt min/avg/max/mdev = 0.513/1.076/1.301/0.258 ms
Highlighted by the (DUP!) tag, we see that the seventh response was received two times.

Flipped bits

This arguably is the most dangerous type of error in a communication system: when random bits are flipped (0 becomes 1 and 1 becomes 0), the frame is considered corrupted and must be discarded. It's more dangerous than loss and duplication because frames must be checked and correctly recognized as clean or corrupt. The IEEE 802.3 standards defines an efficient technique of finding errors, called cyclic redundancy check (CRC), thus most corrupted frames will be discarded. At the application level, discarded packets (consequence of discarded frames) have the same effects of lost frames.

The field represents the probability of flipped bits occurring, although I am not sure on how this probability is defined. It probably is the total number of bits divided by the number of flipped bits. Targeted testing or reading the source code could help to solve this doubt.

This are the ping results with Flipped bits set to 0.05 in the outgoing direction.
[0 root@m1 ~]$ ping -c 6 192.168.50.3
PING 192.168.50.3 (192.168.50.3) 56(84) bytes of data.
64 bytes from 192.168.50.3: icmp_req=2 ttl=64 time=1.26 ms
64 bytes from 192.168.50.3: icmp_req=3 ttl=64 time=1.28 ms
64 bytes from 192.168.50.3: icmp_req=4 ttl=64 time=1.18 ms
64 bytes from 192.168.50.3: icmp_req=5 ttl=64 time=1.13 ms
64 bytes from 192.168.50.3: icmp_req=6 ttl=64 time=1.31 ms

--- 192.168.50.3 ping statistics ---
6 packets transmitted, 5 received, 16% packet loss, time 5019ms
rtt min/avg/max/mdev = 1.137/1.238/1.315/0.079 ms

Minimum delay and Maximum delay

These two values, expressed as time intervals in milliseconds, define the delay range. There many reasons for a long delay in real life, like overloaded routers and faults. A slightly increased simulated delay could also be used as a representation of very long cables.

My tests with ping showed that Marionnet is not very accurate in the calculation of increased delays. This is the result of a ping from m1 to m2, with cable d1 (that connects m1 and S1) having Minimum delay and Maximum delay set to 20 and 100 respectively, in both directions.
[0 root@m1 ~]$ ping -c 6 192.168.50.3
PING 192.168.50.3 (192.168.50.3) 56(84) bytes of data.
64 bytes from 192.168.50.3: icmp_req=1 ttl=64 time=180 ms
64 bytes from 192.168.50.3: icmp_req=2 ttl=64 time=79.4 ms
64 bytes from 192.168.50.3: icmp_req=3 ttl=64 time=41.4 ms
64 bytes from 192.168.50.3: icmp_req=4 ttl=64 time=111 ms
64 bytes from 192.168.50.3: icmp_req=5 ttl=64 time=52.8 ms
64 bytes from 192.168.50.3: icmp_req=6 ttl=64 time=3.41 ms

--- 192.168.50.3 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5029ms
rtt min/avg/max/mdev = 3.413/78.254/180.835/56.610 ms
As ping calculates rtt (round trip time) and the delay, min is supposed to be greater than 40 ms and max possibly less than 200 ms. Unexpectedly, min is only 3.413 ms. I did other tests, which showed the same behaviour. This issue might have been fixed in the more recent releases of Marionnet.

Even though inaccurate, this feature is still useful for simulating long delays, especially very irregular ones.
 

Conclusion

After following these tutorials, it is your time to play with Marionnet and relativization. Learn more about network management or time-related problems and come back to test them out. Try to think of new ways to make use this software. Have fun!