# Monitor bandwidth usage per ip on a NAT router box [SOLVED]

## sirlark

Hi all,

So I've just successfully and painlessly set up a NAT routing box for my flat mates and myself. We each have our own machine, and share an ADSL capped line. Bandwidth where I live (SA) is pricey, especially for a bunch 'o students, so uncapped is not an option. Also we don't use the bandwidth equally, one of us games over the net, compared to myself who just uses it to check email, IM, and sync/update. Anyway, long story short, I need a way to monitor how much bandwidth is be used by each person (i.e. which person's machine), so that we can split the DSL bill fairly each month. Ideally I'd like to set up squid too, as we all hit pretty much the sort of web content, and If I can proxy/cache that it'll give us that extra bit of bandwidth, and every little bit counts. I know enough about squid to log and calculate the bandwidth usage passing through squid, but not the other stuff going straight through NAT. Also, is there a solution that does all of this (squid and NAT combined with bandwidth monitoring/reporting) together?

Thanks,

James

----------

## Hu

There may be better solutions, but a quick hack would be to use iptables itself to do the bandwidth accounting.  Each rule has two counters associated with it.  One tracks the number of packets which have matched the rule.  The other tracks the number of bytes which have matched the rule.  You could insert rules for each host, thereby accounting bandwidth on a per-host basis.  For example:

iptables -I FORWARD 1 -d 192.168.0.2

iptables -I FORWARD 2 -d 192.168.0.3

iptables -I FORWARD 3 -d 192.168.0.4

iptables -I FORWARD 4 -d 192.168.0.5

By specifying only the IP address of the destination system, but omitting all other protocol matches, the rule matches every packet coming in from the outside world to that system.  Since no action is specified, the rule is a non-terminating rule and the kernel will continue searching the table to find how to handle the packet.  If you need to account upstream bandwidth as well, add matching rules that use -s instead of -d.  If there are types of traffic for which you do not wish to account, place the accounting rules below a rule which will ACCEPT or DROP the unaccounted traffic.

One major limitation of this scheme is that you must record the counters at the right time, as well as clear them after each billing cycle.  One way to handle this would be a cron job that saves the counters to a file and then resets them.  If you go this route, I suggest having the cron job save the counters daily, so that everyone can monitor their usage over time.  This will also make it easier to recover if an unexpected crash clears the counters partway through the month.  You would lose at most a day's worth of accounting, rather than the entire month.

----------

## cjubon

Check out the packages in category net-analyzer, for example tcptrack, ipband, bwmon and what not. Alternatively, you may issue 

```
# emerge --searchdesc bandwidth
```

----------

## sirlark

Okay, I'm liking the solution Hu proposed so far (always wanted to get into and understand iptables anyway), just one question. How do I

a) extract the values of those counters mentioned

b) reset their values?

----------

## Hu

You can see the counters for all tables by running iptables-save -c, see the counters for a table by running iptables -t table --numeric --verbose --list, or see the counters for one chain in a table by running iptables -t table --numeric --verbose --list chain.  Some examples:

See everything: iptables-save -c.  This is easiest, and cheap enough that it is the most desirable, since you can always ignore some of the information later.

See the contents of the filter table (which holds the FORWARD chain that I mentioned previously): iptables -t filter --numeric --verbose --list.

See the contents of the FORWARD chain in the filter table (and hide all other chains): iptables -t filter --numeric --verbose --list FORWARD.

When using iptables-save, counters are always exact.  When using iptables, the counters are normally expressed in human-friendly terms.  This may be undesirable if you need to do precise accounting.  To force it to present the details, add --exact to your invocation of iptables.

You can clear the counters using iptables -t table --zero.  You can include the --zero and --list commands together to atomically list the table, then reset all counters.

Since the iptables-based solution uses the full matching power of iptables, you can do more complex accounting if you have the time to configure it.  For example, you could write rules which let you account traffic by type as well as by user, so you could determine which activity was the most bandwidth intensive for a given month.  This could be convenient if one of the users decides he is using too much bandwidth and wants to know which activity he should reduce in order to reduce his bill.

For reference, everything I have told you is from the iptables manpage (man 8 iptables).  You are welcome to post further questions here.  I mention the manpage because it may be more convenient to read the manpage than to wait for responses from the forum.  Also, you may find other useful capabilities which I have not mentioned, such as creating custom chains for more detailed accounting.

----------

## sirlark

Hi, I had been looking at the man page, but I was loppy about it ovbiously. The description of -Z implies the counters should be visible, without verbose (at least in my interpretation). Having now perused the entire man page, I see verbose corrects this implication. I got it working last night though, thank you very much for your help

----------

## LinuxLoader

You can use http://netacct-mysql.gabrovo.com/?section=info&lang=bg&lang=bg&lang=en or http://www.pmacct.net/

----------

## lexer

I found this page while seeking per-IP traffic counting for my Tomato 1.28 -equipped WRT-54G. 

This approach works great.  Thanks.

----------

