
Last week I got funny little assignment through a colleague of the Networking department. They've got a huge set of routes set in a major internet exchange machine in Amsterdam, and wanted to have a program to optimize the routes. Optimizing the routes is not only important for performance reasons, but also because of money — some connections are more expensive than others.
This assignment is interesting for a number of reasons:
- I feel like I haven't coded anything useful for ages
- I will not be writing the code, but designing it together with a co-worker, who will do the actual implementation
- Someone will actually be using this
- This will save the boss money (we could've been rich ...!)
- The internet might benefit from this, implicitly pleasing many people (the good folks at home)
- It involves some good old-fashioned bit-mucking about (and I love it!)
Network address Destination
10.0.1.0/24 172.16.3.91
10.0.2.0/22 172.16.4.1
10.0.0.0/16 192.168.2.2
Let's call these three routes A, B, and C. Now, let's pretend that using route A is more expensive than using route C. Anyone can see in this (pretty bad) example, that route C is such a large network, that it encompasses both A and B — the network address ranges of A and B both fit in C. Therefore, route A and B can be eliminated and we can cheaply use route C.
To be able to do this programmatically, one must realize that IPv4 addresses are 4 bytes. The decimal dotted quad 10.0.1.0 translates to 4 bytes (hexidecimal notation): 0A 00 01 00, or the 32 bit word 0A000100.
I like writing this in hexadecimal because the network range '/24' translates to a bit mask; '/24' means the first 24 bits of the 32 bit word are 1s, giving a bit mask of FFFFFF00. Likewise, a /22 gives FFFFFC00 and /16 is FFFF0000.
Why is this important? Well, it shows how the internals of the internet work, and why it is so fast. For example, a source IP address of 10.0.1.18 is bitwise AND masked with its network address, and it will match route A in the routing table. The packet is consequently sent to the configured destination (in this case, 172.16.3.91).
Finding the cheapest route now only breaks down to this:
- Find a route that has a smaller bitmask, but still matches the address
- The route has to be cheaper in terms of cost, we don't like spending more money
10.0.1.0/24 => 0A000100 AND FFFFFF00
10.0.2.0/22 => 0A000200 AND FFFFFF00
10.0.0.0/16 => 0A000000 AND FFFF0000
0A000100 AND FFFF0000 == 0A000000, so route A fits in C
If we would have a route D like 10.10.0.0/16, it would not fit in C:
10.10.0.0/16 => 0A0A0000
0A0A0000 != 0A000000, so route D does not fit in C.
As you can see, routing is just simply bitmasking and using a lookup table (the "routing table"). If there is one thing that hardware can do fast, it's bitwise AND operations.
I came up with a funny statement that creates the bitmask from the slash-notation:
((1 SHIFTLEFT (32 - numbits)) - 1) XOR FFFFFFFF
This is overly complicated. It is possible to look at it in another way; e.g. with a /16 all the left-hand side bits are set, and all the right-hand side bits are clear. So it is possible to start with all bits set, and shift the clear bits in from right to left:
FFFFFFFF SHIFTLEFT (32 - numbits)
Be mindful that this works only for 32 bit registers, otherwise the mask will overflow. You can prevent this be explicitly selecting the least 32 bits:
(FFFFFFFF SHIFTLEFT (32 - numbits)) AND FFFFFFFF
We can do even better than this. There is a cool operation named arithmetic shift right which is ideal for the job, but it is not present in all programming languages. The arithmetic shift right copies the highest bit into the next bit, which is exactly what we want:
80000000 ARITHMETICSHIFTRIGHT (numbits - 1)
Just for the fun of it, I thought about implementing this in assembly language. There are many implementations possible, depending on what CPU you are programming. Just for the kick of it, I picked a 32 bits ARM processor. You have to be a bit clever with the bit operations, especially on this system.
@@ first solution, using (-1 SHL (32 - numbits))@LDR R0, numbitsMOV R1, #32SUB R1, R1, R0 @ R1 is (32 - numbits)MVN R0, #0 @ R0 is FFFFFFFFMOV R0, R0, LSL R1 @ R0 becomes the bitmask@@ second solution, using an arithmetic shift right@MOV R0, #1MOV R0, R0, LSL #31 @ R0 has only highest bit setLDR R1, numbitsSUB R1, R1, #1 @ R1 is (numbits - 1)MOV R0, R0, ASR R1 @ R0 becomes the bitmask
Note that the routing theory holds true for IPv6 as well, except that for IPv6, you have to work with 64 bits addresses rather than with 32 bits addresses.


Programming games is fun. Games typically run in fullscreen mode, so in today's world, it's important to have a portable way of setting a full screen mode. It looks like this is more of a hassle than you'd think it is.
I read an interesting interview with John Carmack, lead programmer at id Software, famous (1) for creating the game DOOM. In the interview, he talked a little about his game engines with the cool sounding code names "Tech 4", "Tech 5", "Tech 6", etc. To my surprise, there were some very negative comments to this article, people complaining that Carmack is not doing anything innovative at all, as he is recreating the same old game over and again. He is obsessed with his engine and not creating fun games any more.
I already wrote about the buggy installation procedure of Ubuntu Hardy Heron. After a few weeks of using Ubuntu Hardy, I am near to throwing it off my system (!) It is simply frustrating, I seem to hit a bug every time I try to use it. The whole release is just a hodge-podge of "latest greatest" releases of software. There is no stability factor involved, the whole thing just feels like a "testing" release. I used Ubuntu Feisty and Gutsy and in fact, I was happy with Gutsy. Maybe I should reinstall Gutsy, argh.
A while back I wrote a blog entry about the
As you might know, I too fell for Apple's sleek looking hardware and its apparent easy-to-use software. The company from California that is being run by the no-nonsense genius Steve Jobs has a good reputation (well, at least for the last couple of years, ever since the ipods and Mac OS X) of delivering high quality products. Sadly, the Airport Express is a major letdown. I would go as far as to say that Apple is selling a broken product and is lying to their customers about it.
The latest buzz in Linux land is the new stable (or Long Term Support) release of Ubuntu, also known as "Hardy Heron" or plain "hardy". Upgrading should be a breeze, but it still cost me a few hours of sleep as it wasn't until 0:30 AM before I got the stupid thing to work. I am generally content with Ubuntu and I have seen systems where it just works, just never with mine. My main frustration is that the same issues were present 2 years ago, and haven't been fixed.

When I first switched to Linux (it was 1993 or 1994 so, and the music was way better back then), I wrote a
I've been programming for a fairly long time now. I didn't start out as young as some did, though. My first program was a school assignment, a birthday calendar written in Commodore BASIC. I used the computer in class, I didn't have one at home.