Skip to content

Per-user traffic monitoring on OpenWRT

Today I had cause to want to track the per-user (per-MAC address, really) traffic counts on an OpenWRT-based router. There’s nothing I could see that was built in, so I dug around and found wrtbwmon, which is a pretty good script for this sort of thing. However, it doesn’t work with the OpenWRT version I’m running (Backfire (10.03, r20728).)

So here I document what I had to do to make it work.

To start with, grab my version of the script itself from here. I put this into /usr/local/bin on the router, and made it executable (chmod +x /usr/local/bin/wrtbwmon.)

Using crontab -e, add the following (modified as you like) to the crontab:

* * * * * /usr/local/bin/wrtbwmon setup br-lan
*/5 * * * * /usr/local/bin/wrtbwmon update /tmp/usage.db
1,6,11,16,21,26,31,36,41,46,51,56 * * * * /usr/local/bin/wrtbwmon publish /tmp/usage.db /tmp/www/usage.htm /usr/local/lib/macusers.txt
3 0 12 * * rm -f /tmp/usage.db
7 */6 * * * cp /tmp/usage.db /usr/local/lib/usage.db.bak

(the one with all the numbers is actually one long line, it may wrap on this page)

Line 1 sets up iptables to track everything it sees on the network, 2 and 3 save and write out the data every 5 minutes, and 4 resets the database when the monthly transfer quota resets. The last line backs up the database to flash every 6 hours, so that in case of power failure at most 6 hours of data are lost. The script expects the backup to be found in /usr/local/lib/usage.db.bak, so if you alter this, you’ll have to alter the script.

Running /etc/init.d/cron restart may be needed here to make the cron daemon reload the new commands.

Set up /usr/local/lib/macusers.txt to map MAC addresses to users to give a nicer output. For example:

00:aa:bb:cc:dd:ee,Person 1
11:22:33:44:55:66,Person 2

The MAC addresses should be lower case.

In /www/cgi-bin/usage I put:

#!/bin/sh
echo 'Content-Type: text/html'
echo 'X-Dummy: dummy'
echo
cat /tmp/www/usage.htm

The dummy header line is needed to work around a bug in the uhttp version on the router. chmod +x this also.

Now, you can go to http://IP_OF_ROUTER/cgi-bin/usage and it’ll give you an HTML table showing who’s been uploading and downloading what. Good for finding out who hasn’t capped their torrent client’s upload speed.

Update: added the backup cron job, updated the script to restore the backup if needed, also now adds totals to the display.

Thesis Submitted!

I meant to post this here a while back, but kinda forgot to. Anyway, on Monday last week I finally submitted my thesis. The title is “The Impact of Representation on the Evolution of Genetic Algorithms.” Now I just need to sit back and wait until the examiners get it, mark it, and probably send me corrections to make prior to it being accepted. I’m going to try for the August graduation, but that is perhaps a bit too hopeful unless the marking happens faster than I expect it will.

Unfortunately, the plans for work I had lined up in the Netherlands didn’t pan out due to the immigration system there making it very difficult for a relatively small company to get a work permit for a foreign employee. As such, I’m still looking for work, although I have enough here to tide me over for as long as I need it. That said, I’m definitely looking to get out of Dunedin, and ideally New Zealand, in the relatively short term. So if you have any ideas, let me know!

For now, I have my regular work, which I’m doing fairly short hours on right now, and a contract job for Naxos (again) upgrading their version of eMusic/J to match their new requirements. It’s good work, and the improvements will flow back into the normal version. It’ll be nice to finally get another release of that out the door, it’s been on something of a hiatus while I finished the thesis.

Monitoring Puppet with Nagios

I’ve been setting up a Puppet system at work so we can easily set up virtual servers, and also so that all the configuration is in one place.

Yesterday, someone suggested to me how I can have our existing Nagios system monitor the state of the puppet configuration. This allows me to be notified if there is something causing puppet to fail on any of the monitored nodes.

There is a Ruby script out there that is a Nagios plugin, however it requires extra Ruby libraries, and I don’t know how to handle them nicely on a Debian system. I do, however, know how to handle Perl libs. So I wrote a Perl plugin that does the same task. It’s got a lot of hard-coded paths and times and such, you’ll want to make completely sure that they work in your configuration. It’s also not well documented, but it is quite basic: check_puppet.pl

The main tricky dependency it has is on Nagios::Plugin, but it’s in CPAN, so some dh-make-perl should get you a Debian package for it easily.

Returning to Europe (hopefully)

The opportunity has come up for me to escape Dunedin, and go a long way away for an indefinite time. So, I’m jumping on the idea, and planning on moving to the Netherlands, Deventer specifically, to work for Topicus.

I’ll have a 6-month contract with them to start with, that is evaluated after 3 months to determine if it will be continued. This is because they’re a little uncertain about how a non-Dutch-speaker will work out. So, to help that along, I’ve started learning to read it so I have at least some foundation when I’m there.

As of now, I’m waiting on a work permit (tewerkstellingsvergunning). Well, really, I’m waiting on the university to open again so I can get a transcript that will then form part of the application for the permit that Topicus will be sending in for me. Once this has been done, then it’s pretty much just a matter of buying some plane tickets and getting myself over there.

If everything goes as well as we hope, I’ll be winging my way back there in the European spring-time, so April or May.

Going to Europe

I realised that I’d forgotten to mention this here, so now I’ll amend that.In July/August, I’ll be spending five weeks in Europe. I leave NZ on the 13th of July, and get back on the 22nd of August.It’s just for a holiday, so should be a fairly cruisy time. And I miss out on some winter, too.I’ll be going to the UK, Belgium, Germany and the Netherlands (in that order). I have a few events to go to along the way, which is good for working out where to go when. In between times I’ll be visiting friends.The things I’m going to are:

If you’re really keen, you can view my itinerary (OpenOffice.org spreadsheet) which goes into more detail, although is still in a state of flux to a small extent.If anyone is going to be near where I’m going, give me a yell. Time permitting, I might be able to come visit. I’ll be taking my new toy (the small one) with me, so will be reachable by the usual methods.

eMusic/J 0.25 released

First update in a while, just fixes to various things.

  • Overhauled the filename cleaning stuff, hopefully finally fixing issues on windows. — found more filenames that windows dies on, so this deals with them. Hopefully that’s the last of them.
  • If the option ‘spacesToUnderscore’ is ‘true’ then spaces will be converted to underscores in filenames. — someone asked for this, and it was easy enough to do when working on the other stuff
  • Handle the case where the emusicj script is a symlink to the real location, and use that to find the program directory — makes it nicer for people who lay their applications out in complex ways.

Find it at the usual place

Extension to the ‘Shunting Yard’ algorithm to allow variable numbers of arguments to functions

Here’s something a bit more computer-sciencey than usual. For something at work, I have had to implement a function parser, so you can type ‘1+2*b‘ and it’ll work it all out, with correct operator precedence and so forth. To do this, I use a three-step process:

  1. Tokenise the input, and at the same time convert any variables found to their numeric values
  2. Convert the input tokens to RPN using the Shunting Yard algorithm
  3. Evaluate the RPN form of the equation using an RPN parser, which is really easy to write

This did the job nicely, however the time came when it had to be extended, and able to accept functions, such as ‘max(1,2,3)‘. The standard shunting yard algorithm can handle functions, but with the restriction that the number of arguments to them is known (really, this is a limitation of the RPN algorithm, but it’s at this point in the process that we need to deal with the problem). In this case, I wanted to handle functions with a variable number of arguments, so ‘max(1,2)‘ would work, and so would ‘max(1,2,3,4,5)‘. To do this, I extended the standard algorithm. Below is the algorithm from Wikipedia. My additions are in bold. This requires two more stacks, a ‘were values‘ stack, and an ‘arg count‘ stack. It also requires that you can attach the number of arguments to an instance of a function. In my case, I did it with a small class that took the function and an argument count, with one of these created during tokenisation for each function encountered.

  • While there are tokens to be read:
  • Read a token.
  • If the token is a number, then add it to the output queue. If the were values stack has a value on it, pop it and push true.
  • If the token is a function token, then push it onto the stack. Push 0 onto the arg count stack. If the were values stack has a value on it, pop it and push true. Push false onto were values.
  • If the token is a function argument separator (e.g., a comma):
  • Until the topmost element of the stack is a left parenthesis, pop the element onto the output queue. If no left parentheses are encountered, either the separator was misplaced or parentheses were mismatched. Pop were values into w. If w is true, pop arg count into a, increment a and push back into arg count. Push false into were values.
  • If the token is an operator, o1, then:
  • while there is an operator, o2, at the top of the stack, and either
o1 is associative or left-associative and its precedence is less than (lower precedence) or equal to that of o2, or
o1 is right-associative and its precedence is less than (lower precedence) that of o2,
pop o2 off the stack, onto the output queue;
  • push o1 onto the operator stack.
  • If the token is a left parenthesis, then push it onto the stack.
  • If the token is a right parenthesis:
  • Until the token at the top of the stack is a left parenthesis, pop operators off the stack onto the output queue.
  • Pop the left parenthesis from the stack, but not onto the output queue.
  • If the token at the top of the stack is a function token
    • Pop stack into f
    • Pop arg count into a
    • Pop were values into w
    • If w is true, increment a
    • Set the argument count of f to a
    • Push f onto output queue
  • If the stack runs out without finding a left parenthesis, then there are mismatched parentheses.
  • When there are no more tokens to read:
  • While there are still operator tokens in the stack:
  • If the operator token on the top of the stack is a parenthesis, then there are mismatched parenthesis.
  • Pop the operator onto the output queue.
  • Exit.

Note that because I didn’t feel like correctly listifying most of it, consider an if to apply to the end of that sentence only. Operation order is usually important.

With this done, the part of the RPN algorithm that says:

It is known that the function takes n arguments.

can now be satisfied.

eMusic/J 0.24 released

This is a pretty small one, mostly just to fix a problem some people were having.

Changelog:

  • Truncate the pathname to save files to if it gets too long on windows (which has stupidly low limits) Some classical albums have really long names, and there were some that couldn’t be downloaded as a result. This hopefully fixes the problem, although I haven’t tested it yet.
  • Added option to allow the user to specify that they don’t want cover art to be downloaded. This is done by adding the line ‘downloadCoverArt=false’ to ~/.emusicj/emusicj.prop. Someone wanted this, I can’t remember why, but it was easy enough to do.
  • Updated build.xml to allow more flexible compiles, such as not always creating a dist build Apparently some people are making distro packages of eMusic/J, and this makes life easier for them. Related to this, I’ve started posting the source code of each release on the site, too.

It can be downloaded here.

Kiwi Foo Camp 08

Yesterday I got back from a bit of a holiday in Auckland. The purpose of the trip was to go to Kiwi Foo Camp (a.k.a. Baa Camp). It is a gathering of 150 people with creative interests in various, generally technology related, things. It’s aim is to be a way for all these people to get together in a way the breaks down normal barriers of hierarchy so that they can share ideas, plots, and schemes without these getting in the way.

I met a bunch of people that I’ve heard about or only ever talked to via email, such as Don Christie and Peter Gutmann, along with a host of people I probably would have never heard of if they weren’t there but who are also doing interesting work in a variety of fields. A nice effect, which is by design, of the 150 people cap is that you have the ability to meet nearly everyone there. It also means they can put on free beer and wine for the entire event.

Almost everyone was sleeping on the school grounds where it was hosted, or nearby, which meant that things like game playing (Werewolf is a favourite) carried on to 4am, and people were happily getting up at 8am for breakfast in the morning. I was supposed to be sleeping in the Wharenui at the school, however due to getting to bed a little late and an apparent overbooking of it meant that I ended up sleeping outside on the deck of it the first evening. From what I could tell, I got the better deal. It wasn’t hot and stuffy, and the one person out there with me didn’t snore too much. The following night was inside one of the school rooms, which was helpful because it kept the mosquitoes somewhere where I wasn’t, although I think by then they’d decided I was bled dry anyway.

As is common with conferences, and even moreso with this one being an ‘unconference’, much of the value isn’t so much from the sessions, but from chatting to people you happen to sit beside because there’s a spare seat, whether they do programming, community projects, are politicians (I talked with Judith Tizard extremely briefly), or whatever. They all seem to be doing good stuff. I did, however, do a session of my own. I was planning on doing one on neural networks and genetic algorithms, and another on Amazon web services but due to time constraints (some uncharitable folk may call it laziness) beforehand, I only had time to prepare the GA stuff. That worked out OK, as it managed to take up the whole hour anyway. I didn’t get a big turnout, but I didn’t expect one – this was a fair bit more on the computer science side than most of the things there.

The photos I took are here, many more can be found on flickr.

The rest of the time in Auckland was catching up with friends there, and spending way too much money at JB Hi-Fi on music and a little bit of anime.

eMusic/J 0.23 released

I’ve just put out eMusic/J 0.23. The main reason for getting this out there is that there is a bugfix for a problem that occurs in a certain (rare) circumstance.

Here’s a list of the changes:

  • Allow multiple tracks to be selected This means you can shift-click or control-click to perform operations on multiple tracks. This is a prelude to drag-and-drop support, which I hope to get to some time soon.
  • Adds auto-remove timer to tracks that were finished when the program started Previously, and tracks there when the program started were never cleared automatically. Now they are.
  • Trim spaces from ends of album/track/artist names as vfat doesn’t like them
  • Changed default save location of files to ~/Music or ~/My Music (whichever exists), defaulting to the first one if neither do This should make its default save location a bit nicer on various platforms.
  • Fixed an infinite loop if the album/artist/track names contain a path wildcard (e.g. %t). Thanks to Hugh Brackett for spotting this one. This caused the program to peg the CPU on this album due to the track “S#%t Outta Luck”

It can be downloaded from the eMusic/J homepage.

An extra note, a customised version of this program was developed for Reggae Country to use with their download service. Thanks for their support!