Your here: Main Page / WiFi / DD-WRT Tutorials / Scripting / Bandwidth Monitor for DD-WRT

Bandwidth Monitor: GeneralEdit

The file is a script which is run on a wrt firmware based router. The script is used to record and generate display information on a per MAC basis.

It is been completely re-written but is based on the wrtbwmon script created by Emanual Brucy ( The biggest difference from this script and the original (wrtbwmon) is the amount of data that is recorded and is able to be displayed, and its use of resources (I/O etc).

Because of the volume of data that is recorded and displayed, this version is a bit heavier on disk space and RAM (storing data for each day and generating/converting the data to a java script objects).

I am in the process of allowing users to turn off the daily usage, and purely record the total usage either periodically (reset day) or continually(as the current wrtbwmon does). THIS IS AVAILABLE IN VERSION 0.6 and above

It allows a router administrator to setup users to MAC's (1 to 1), or User Groups to a list of MAC's (1 to many).

The script starts of by setting up iptables rules (per IP), and recording download and upload data on a per-day basis (day 1 to day 31).

This data will be periodically saved to a usage file, which will be used to publish a java script file, which represents the data contained within the file (but converted into java script objects).

This java script output will then be used within an html file for displaying usage data in a friendly and effective manner to users (via a script link).

The script supports automatic usage reset and archiving (saving usage file and java script to a history), which can be triggered on any day of the month (at midnight).

The script is highly customizable and attempts to limit the amount of I/O by performing many functions within RAM.

Future PlansEdit

Release HistoryEdit

Version 1.0Edit

  • Added a new option to show MAC addresses in the html file if a client is Auto Added (showMAC - Option 17)
  • Provided very basic logging. This is enabled by supplying a log path and file name (logFilePath - Option 18)
  • General Code Cleanup

Version 0.9Edit

  • Allows a user to change between 1000 and 1024 via Query String Parameters.
  • Added 2 new optional script arguments, Auto Add MAC's, and Bit32 Support.
  • When the page refreshes, it will keep the usage day and the bytes base you have selected (via query parameters)
  • Added bc support (Mandatory)
  • Removed redundant sed global checks (improved performance)
  • Changed interface.html to monitor.html
  • removed wanup script and kept startup script ONLY
  • Fixed up the DNSMASQ to USERS.FILE function to allow more than one underscore .
  • Added a line to the startup script which allows you to automatically change the javascript path in the html file.
  • Made changes to the iptables setup methods to ensure rule is always at top of the list and there is ONLY ever 1.
  • Fixed reset method
  • Added new exit condition when no users are found in the file.
  • the setupIPRule function is ONLY called at the very start and every subsequent publish.

Version 0.8Edit

Changed HTML file now include total usage (down and up) for the 'Day Usage' section.

Changed the bytes function to now use base 1000. I am in the process of making this an option value that can be set by the user

Bandwidth Monitor: ManualEdit


Required Packages and Commands#Linux OS that supports shell scripts

  1. This is designed to run on a router.

The following lists what commands are used by the script. YOU must ensure you can run the following commands from your command line.

If you cannot, and the command IS NOT optional, then you must install it.

Used Commands and PackagesEdit

Example Test Outcome Optional
iptables iptables -L FORWARD list ALL FORWARD rules NO
sed echo "bandwidth monitor " | sed 's/bandwidth/bw/' bw monitor NO
grep echo "bandwidth monitor" | grep 'monitor' bandwidth monitor NO
awk echo "bandwidth monitor" | awk '{print $1}' bandwidth NO
sort echo "bandwidth,monitor" | sort -t, +1 -2 bandwidth,monitor YES (Script Argument)
test [ 1 -gt 0 ] && echo "true" true NO
chmod +x run it on a script file check for NO errors NO
expr expr 3 + 4 7 NO
bc echo "3 + 7" | bc (You will need to get the right package for your model) 10 NO
echo if you dont have this, you dont have linux GET LINUX NO
date date +%d current day NO
md5sum md5sum /tmp/somefile print out a string of characters NO

Install PackagesEdit

I am not too sure where you can find all the required packages. The package also sometimes depends on the router model or the linux version so you really need to do some research.

I can only provide some links that may guide you:

View this thread -

wget ipkg -d root install bc_1.06.94-1_mipsel.ipk

Minimum RequirementsEdit

The minimum requirements depends on how many users/clients you wish monitor and the number machines each client has.

As a general guide, please use the following.

MAC's Usage database(Disk) Javascript(only for 1 file)
1 2.23KB (31 Lines) 4.3KB (96 Lines)
10 23.1KB (310 Lines) 40KB (960 Lines)
100 240KB (3100 Lines) 500KB (9600 Lines)

Each file can also gets read into RAM, so their must be an equal amount of RAM available as well. Also, if you chose to keep the mac_usage data in RAM, the disk space is not required for it.

For an average user, I would recommend 50 MAC's to be monitored. This would mean having around 450-550KB of RAM and 600KB of disk. This again depends on if you store usage data on the file system or in RAM and if you keep the last months javascript file (user set)

Important FilesEdit


File Purpose Required The main script file. Can be executed from anywhere. YES
user definition file This can be a custom user file or an dnsmasq file. YES
HTML File (monitor.html) This is the template html file that will be called by a user to view the usage web page. This contains the link to the created java script page. YES


File Purpose Required
mac usage store file Path and File name of the file that will store usage information NO
monitor-stop Used to prevent the script from continually creating a new instance of the script (see bw_monitor.wanup) NO

System Generated or UsedEdit

File Purpose Always Generated/Used
monitor-started.lock This file is used for locking the instance of the script to only 1. It will be created in the /tmp/ directory YES
mac usage store file See optional Files NO
user_details.js The file where the java script output is placed YES
backup file The file where usage data is backed up to and restored from YES


The usage data is recorded in the following format:


Field Purpose GETS UPDATED
MAC Mac address of machine YES
IP Current IP Address of MAC (when value read) YES
DOWNLOAD The amount of bytes downloaded since the last update YES
UPLOAD The amount of bytes uploaded since the last update YES
DAY The current day (prefixed with a 0 if below 10) NO


The user file must be in the following format: MAC,IP,USER,TYPE

Field Purpose Required Value
MAC Mac address of machine YES
IP Expected static IP address of machine (Not used at present) NO
USER This is the primary identifier for the MAC. It can be a user name or a goup Name. Must be alphanumeric and contain no spaces YES
TYPE This is the description of the MAC. Must be alphanumeric but can contain spaces. Limit 20 characters NO
DISPLAY Indicates if usage results for this MAC should be included in the display. Values are no value or 1 = Display or 0 = don't display NO




 DNSMASQ FILES (Setting up users through the Web UI)

 A typical dnsmasq file will look somthing like this when opened using the 'cat' command:
 root@DD-WRT:/tmp# cat dnsmasq.conf

The system will monitor and convert the file into the users.file format (MAC,IP,USER,TYPE) and place it in the /tmp/ directory as dnsmasq2users.file. Never edit this file as the changes will NOT persist after reboot

Using the dnsmasq file does not allow a user to setup the MAC DISPLAY flag (this is being looked into).

To define a USER,TYPE via the web UI, the user name entry must be in the following format:

[USER]_[TYPE] - The underscore represents the delimiter between user/group and type.



 The above will be converted into:



If you change the path of the (web address) of the stored java script page, you will need to also update this page as well.

<script type="text/javascript" src="">

NOTE: This is NOW part of the startup/wanup script (see below)

Setup GuideEdit


There are a few way to get this running on your system.

I will focus on two of them

One way is to use persistant storage, such as flash drive or somthing similar (samba, jffs etc)

  1. Downlaod the script and save it
  2. chmod +x the script. This makes it executable
  3. Download the monitor.html file
  4. Create and modify the below script and save it as a startup or a wanup script (this is described in detail in the Startup/Wanup Scripts section below):
 while [ ! -f /tmp/monitor-started.lock ] && [ ! -f /tmp/monitor-stop ]; do
         if [ ! -f /tmp/www/monitor.html ]; then
                 sed 's/src=.*>/src="http:\/\/\/user\/user_details.js"><\/script>/' /mnt/monitor/setup/monitor.html > /tmp/www/monitor.html
         /mnt/monitor/setup/ 30 3 30 4 /mnt/monitor/setup/users.file /mnt/monitor/mac_usage.backup /mnt/monitor/history/ 1 '' 1 1 1 1 1 1''
         if [ ! -f /tmp/monitor-started.lock ]; then
                 sleep 10

The second way to set up a startup script as described above, but instead of storing the and the monitor.html file, you amend the startup script to download them using wget.

The following assumes you have NO persistant storage


 wget -O /tmp/ && chmod +x /tmp/
 wget -O /tmp/monitor.html
 #If not using dnsmasq file
 echo 'MAC,IP,USER,TYPE' > /tmp/users.file
 echo 'MAC,IP,USER,TYPE' >> /tmp/users.file
 echo 'MAC,IP,USER,TYPE' >> /tmp/users.file
 while [ ! -f /tmp/monitor-started.lock ] && [ ! -f /tmp/monitor-stop ]; do
         if [ ! -f /tmp/www/monitor.html ]; then
                 sed 's/src=.*>/src="http:\/\/\/user\/user_details.js"><\/script>/' /tmp/monitor.html > /tmp/www/monitor.html
         /tmp/ 30 3 30 4 /tmp/users.file /tmp/mac_usage.backup /tmp/ /tmp/mac_usage.db '' 1 1 1 1 1 1''
         if [ ! -f /tmp/monitor-started.lock ]; then
                 sleep 10
 rm /tmp/monitor.html

Ideally, you would have some sort of cron job that backups the mac_usage.db file (maybe an FTP site etc) and an extra call to place the backed up file back into temp (before the script is started) so it can be restored after subsequent restarts.

Script ArgumentsEdit

The script takes in up to 14 arguments.

They are as follows and must be supplied in order.

Note: All PATH only parameters MUST contain a slash / at the end. e.g. /mnt/monitor/ NOT /mnt/monitor

Parameter Name Description Value(s) Mandatory Default Value
1 Update Interval This indicates in seconds how often the usage data should be retrieved from the iptables and updated. Integer only YES N/A
2 Publish Iteration Indicates how many update iterations must past before a publish is done. Integer only YES N/A
3 Backup Iteration Indicates how many update iterations must past before a backup is done. This typically has a longer interval compared to publish as this writes to a persistant store area. Integer only YES N/A
4 Reset Day Indicates what day at midnight should the usage data be reset back to 0 and backed up to history. If an invalid reset value is passed, no reset will occur 1 to 29 or -1 YES NONE
5 User File Path The path and file name for where user data is saved. The users file can be a custom file or the system generated dnsmasq file file path and name e.g. /mnt/users.file YES N/A
6 Backup Usage File Path The path and file name for the interval back up of the usage file. Does NOT support FTP (yet) file path and name e.g. /mnt/usage.backup YES N/A
7 Backup History Path The path for where history files will be kept. Used when a reset occurs. file path ONLY /mnt/ MUST contain last / YES N/A
8 MAC Usage File Path Indicates the path and file name for usage data or if the data should remain in memory ONLY. A Value of 1 will keep the usage in memory A valid path and file name or 1 NO /tmp/mac_usage.db
9 Javascript Output Path The path for where the user_details.js output file should be saved A valid path ONLY e.g. /tmp/www/ NO /tmp/www/
10 Do Usage File Restore Indicates if the usage file is restored from the backed up location when the monitor is started 0 (Dont restore) or 1 (Restore) NO 1
11 Use Sort Indicates if we should use the sort command. 0 (No) or 1 (Yes) NO 1
12 Keep Last Javascript File Indicates if a last_user_details.js file should be kept in the javascript output folder for showing last months usage (after reset). 0 (Dont store file) or 1 (keep backup) NO 0
13 History Javascript File Indicates if the javascript file should also be backed up to history 0 (No) or 1 (Backup) NO 0
14 Record Daily Usage Indicates if you would like to record daily usage or not. If you do not, usage will be stored against DAY 1 always. 0 (No) or 1 (Record by day) NO 0
15 Auto Add MAC Addresses Indicates if the system is to auto add MAC addresses that do not exist in the users file 0 (No) or 1 (Insert MAC) NO 1
16 Add 32 BIT support Indicates the value that should be used to divide the usage value by Must be a value greater than 0 NO 0 (Router supports large values)
17 Show MAC Addresses Indicates if you would like to show the MAC address of a auto added client. Also indicates if no TYPE (in user file) is defined, then the MAC address will show. 0 (Never Show) or 1 (Show) NO Default is 0
18 LOG If you provide a value, the system will start logging certain calls. Must be a valid path and file name NO no value means NO logging. Any value will start logging so be careful

For ALL optional values, you can supply NO value or empty string . This will cause the defaults to be used.


Do not copy and past the following examples. It has been formatted for viewing only (contains spaces that it shouldnt).

The numbers in brackets refer to the script arguments defined in the table above. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17]  [18]
Example 1
[1] [2] [3] [4]            [5]                              [6]                   [7]              [8] [9] [10] [11] [12] [13] [14] [15]  [16]  [17]   [18]  30  3  30   4 /mnt/monitor/setup/users.file /mnt/monitor/mac_usage.backup /mnt/monitor/history/

#This will use all the defaults for the optional values. No Logging
Example 2
[1] [2] [3] [4]            [5]                              [6]                   [7]              [8] [9] [10] [11] [12] [13] [14] [15]  [16]  [17]  [18]  30  3  30   4 /mnt/monitor/setup/users.file /mnt/monitor/mac_usage.backup /mnt/monitor/history/    1      1   1     1    1   1    1      0    0

#This example enables ALL optional values, but uses the default javascript path ([9]), and does not store usage data in a file, its kept in memory ([8])
Example 3
[1] [2] [3] [4]            [5]                              [6]                   [7]              [8] [9] [10] [11] [12] [13] [14] [15]  [16]  [17]   [18]  30  3  30   4 /mnt/monitor/setup/users.file /mnt/monitor/mac_usage.backup /mnt/monitor/history/    1      1   1     0    0   1    1     0     0

#This example enables all optional values, except for keeping the last javascript file, and backing up the javascrit file to history. It does not store usage data in a file, its kept in memory ([8])
Example 4
[1] [2] [3] [4]            [5]                              [6]                   [7]                 [8]           [9] [10] [11] [12] [13] [14] [15]  [16]   [17]   [18]  30  3  30   4 /mnt/monitor/setup/users.file /mnt/monitor/mac_usage.backup /mnt/monitor/history/  /tmp/mac_usage.db     1    1    0    0   1    1      0    0

#This example is the same as example 3, BUT we are saving the usage data to a file ([8]) /tmp/mac_usage.db.
Example 5
[1] [2] [3] [4]      [5]                       [6]                     [7]                   [8]        [9] [10] [11] [12] [13] [14] [15]  [16]  [17]    [18]  30  3  30   4 /tmp/dnsmasq.conf /mnt/monitor/mac_usage.backup /mnt/monitor/history/  /tmp/mac_usage.db     1    1    0    0   1    1     0    0

#This example is the same as example 4, BUT we are using the dnsmasq file instead of a custom users file. As mentioned in the USER FILES section, this script will convert the contents of this file and save it as a tmp file dnsmasq2users.file.
Example 6
[1] [2] [3] [4]      [5]                       [6]                     [7]                   [8]        [9] [10] [11] [12] [13] [14] [15] [16]  [17      [18]  30  3  30   4 /tmp/dnsmasq.conf /mnt/monitor/mac_usage.backup /mnt/monitor/history/  /tmp/mac_usage.db     1    1    0    0   1    1    0     0    /tmp/bw_monitor.log

#This example is the same as example 5, BUT we are also using logging

Startup/Wanup ScriptsEdit

A typical setup would copy the html file to the web server, and then initialise (start) the script.

For the below example, I continually loop until the monitor-started.lock file is created. I however have include a monitor-stop file in the loop condition as well. If this file exists, it will break the loop.

Its main purpose is for those that implement the below in a .wanup script.

The below script also allows you to change the javascript script path in the html file. This uses sed and replaces the cp command for moving the html file to the correct location.

 while [ ! -f /tmp/monitor-started.lock ] && [ ! -f /tmp/monitor-stop ]; do
         if [ ! -f /tmp/www/monitor.html ]; then
                 sed 's/src=.*>/src="http:\/\/\/user\/user_details.js"><\/script>/' /mnt/monitor/setup/monitor.html > /tmp/www/monitor.html
         /mnt/monitor/setup/ 30 3 30 4 /mnt/monitor/setup/users.file /mnt/monitor/mac_usage.backup /mnt/monitor/history/ 1 '' 1 1 1 1 1 1''
         if [ ! -f /tmp/monitor-started.lock ]; then
                 sleep 10

Query ParametersEdit

When you have the script up and running, you can view the results using the monitor.html file.

As well as viewing information on this page, I have supplied a few query parameters that allow to change some of the information

And example is below

The above tells the page to use 1024 as the bytes conversion base


dd-wrt - Bandwidth Usage Monitor Thread
Project Home

Community content is available under CC-BY-SA unless otherwise noted.