monitoring bandwidth usage

1,095 views
Skip to first unread message

vkapovit

unread,
Feb 8, 2012, 12:11:45 PM2/8/12
to tunnelbli...@googlegroups.com
I use tunnelblick from home to access library resources at the university.
Sometimes I forget to disconnect tunnelblick afterwards (the menu icon is rather small) and it then runs up high bandwidth consumption when I later download some personal files unrelated to the university and not requiring tunnelblick.  This gets me a scolding from the university (they monitor  the VPN bandwidth usage). This happened twice in the last six months.

I believe it should be possible to write some kind of script that monitors the bandwidth usage (or just the time that tunnelblick connection is up) and pops up a warning on the screen if a certain treshhold is reached. I can see from tunnelblick documentation that it does support scripting.
I know a little shell and apple scripting but I'm not a programmer and I would appreciate any advice on how to do this.

jkbull...gmail.com

unread,
Feb 8, 2012, 1:36:55 PM2/8/12
to tunnelbli...@googlegroups.com
To monitor bandwidth through the VPN you would either need to monitor bandwidth overall (via some OS X mechanism) or modify the Tunnelblick source code to enable and track bandwidth messages from OpenVPN.

You could write some scripts that would track the time that Tunnelblick is connected to a VPN, fairly easily, I would think:
  • An UP script that would use launchd to start a MONITOR script, then return (because the UP script must return for Tunnelblick to continue).
  • A MONITOR script that would start a timer then go into a loop that slept for a while, then updated the timer (and put up a warning window if too much time had elapsed).
  • A DOWN script that would kill the MONITOR script execution, then return.
If you want to do that, I recommend using "connected.sh" and "post-disconnect.sh" scripts inside a Tunnelblick VPN Configuration (see Using ScriptsSetting up Tunnelblick, and ".tblk" Details).

vkapovit

unread,
Feb 8, 2012, 2:24:14 PM2/8/12
to tunnelbli...@googlegroups.com
Thanks,
I think I can do the second thing you suggest pretty easily.  but could you please clarify your first suggestion?
I'm probably not up to modifying the tunnelblick source code myself (as I said I'm not a programmer) but could you expand on what's required here? The option of monitoring bandwidth usage using outside OS X mechanism would probably be easier for me to implement but I don't know I don't know how read off that info.

jkbull...gmail.com

unread,
Feb 8, 2012, 2:33:38 PM2/8/12
to tunnelbli...@googlegroups.com
On Wednesday, February 8, 2012 2:24:14 PM UTC-5, vkapovit wrote:
The option of monitoring bandwidth usage using outside OS X mechanism would probably be easier for me to implement but I don't know I don't know how read off that info.

Sorry, but neither do I! You'd could ask in some more general OS X networking forum.

There is a -- non-free -- VPN client for OS X does track usage, but I don't know if it can alert you as you want. Take a look at http://www.thesparklabs.com/viscosity/

Nicholas Williams

unread,
Feb 8, 2012, 2:59:58 PM2/8/12
to tunnelbli...@googlegroups.com
Jonathan,

Sorry for my recent absence in several discussions that needed me. I've been very busy and have some catching up to do. You'll be hearing from me more soon. But I digress...

In my experience with many different VPN servers and clients, Tunnelblick is actually the exception when it comes to bandwidth monitoring. Every other one I've used provides a "kb/s" snapshot and a "use since up" aggregate. It's actually a very nice-to-have feature that I don't think would be that difficult to add to Tunnelblick in an upcoming version.

A quick example is the iStat and iStat Pro Dashboard Widgets. They show this information for interfaces of your choice. However, iStat takes no part in aggregating this information. Mac OS X provides a utility for retrieving usage information for any given interface; the key is simply in figuring out what the OS-X-provided API is. Once you have that figured out, adding a display and even optional alerts is a rather trivial matter.

Just my $0.02.

Nick

--
You received this message because you are subscribed to the Google Groups "tunnelblick-discuss" group.
To view this discussion on the web visit https://groups.google.com/d/msg/tunnelblick-discuss/-/g8otvBEK-JIJ.

To post to this group, send email to tunnelbli...@googlegroups.com.
To unsubscribe from this group, send email to tunnelblick-dis...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/tunnelblick-discuss?hl=en.

jkbull...gmail.com

unread,
Feb 8, 2012, 3:06:57 PM2/8/12
to tunnelbli...@googlegroups.com
Thanks, Nicholas. I'll consider adding this, but I have a lot of other things on my plate at the moment.

OpenVPN itself can send info to Tunnelblick via the management interface. By using that, Tunnelblick could track and/or alert on per-connection usage.

vkapovit

unread,
Feb 8, 2012, 7:55:46 PM2/8/12
to tunnelbli...@googlegroups.com
Thanks all. Certainly if bandwidth monitoring can be added to tunnelblick itself I would be grateful. I think many others will find it useful too. OS X definitely provides relevant APIs btw.  There are lots and lots of 3rd party programs that do this like iStat (mentioned above), LittleSnitch, Surplusmeter, Netmeter, Menumeters etc. I'm quite sure they all use OS X APIs to get the bandwidth information. after a little googling I also found a couple of terminal commands that do this in os x: netstat and top. I'll just parse the netstat output in my script that will be periodically executed as you suggested. still, this is a kludge and a built-in bandwidth monitoring tool would be much nicer.

Nicholas Williams

unread,
Feb 8, 2012, 9:36:40 PM2/8/12
to tunnelbli...@googlegroups.com
I have attached a code sample for monitoring network traffic on a particular interface. Compiling and executing is very simple:

$ g++ bandwidth.c -o bandwidth
$ ./bandwidth

Near the top is a line that you can change the name of the interface being monitored:

const char * IFACE_CODE = "tap0";

You can change it to tap1 or tun0 or en0 or en1 or whatever is necessary.

This program displays ten samples taken one second apart, each sample displaying total packets in/out, total bytes in/out, and average bandwidth over the last second.

The source code should be very useful (to either of you) for modifying Tunnelblick to monitor network traffic.

The only unfortunate thing is that even after the VPN is disconnected and reconnected, the total packets and bytes are not reset until the computer is restarted. So this number will not represent "traffic since connected" but rather "traffic since boot." It's unfortunate, but I can't find a way around it. Unlike linux, Mac OS X does not appear to have a way to reset network statistics on an interface.

Don't know how much it will help, but hopefully it will some.

Nick

Here is some sample output from this on en1 (Airport) during a speedtest.net test:

$ ./bandwidth 
Packets: in = 2234504, out = 1435886
Bytes: in = 1.16 GB, out = 129 MB
Bandwidth: in = 0 B/s, out = 0 B/s

Packets: in = 2238104, out = 1436666
Bytes: in = 1.17 GB, out = 129 MB
Bandwidth: in = 2.59 MB/s, out = 21.4 KB/s

Packets: in = 2241670, out = 1437488
Bytes: in = 1.17 GB, out = 129 MB
Bandwidth: in = 2.57 MB/s, out = 21.7 KB/s

Packets: in = 2245206, out = 1438356
Bytes: in = 1.17 GB, out = 129 MB
Bandwidth: in = 2.55 MB/s, out = 24.3 KB/s

Packets: in = 2248688, out = 1439202
Bytes: in = 1.17 GB, out = 129 MB
Bandwidth: in = 2.51 MB/s, out = 22.3 KB/s

Packets: in = 2252218, out = 1439830
Bytes: in = 1.18 GB, out = 129 MB
Bandwidth: in = 2.55 MB/s, out = 16.6 KB/s

Packets: in = 2253080, out = 1439944
Bytes: in = 1.18 GB, out = 129 MB
Bandwidth: in = 629 KB/s, out = 3.01 KB/s

Packets: in = 2256370, out = 1440336
Bytes: in = 1.18 GB, out = 129 MB
Bandwidth: in = 2.37 MB/s, out = 11.2 KB/s

Packets: in = 2258644, out = 1440566
Bytes: in = 1.18 GB, out = 129 MB
Bandwidth: in = 1.64 MB/s, out = 6.36 KB/s

Packets: in = 2258788, out = 1440590
Bytes: in = 1.18 GB, out = 129 MB
Bandwidth: in = 100 KB/s, out = 2.57 KB/s

$ ./bandwidth 
Packets: in = 2265334, out = 1443784
Bytes: in = 1.18 GB, out = 131 MB
Bandwidth: in = 0 B/s, out = 0 B/s

Packets: in = 2265598, out = 1444382
Bytes: in = 1.18 GB, out = 131 MB
Bandwidth: in = 7.2 KB/s, out = 419 KB/s

Packets: in = 2265984, out = 1445096
Bytes: in = 1.18 GB, out = 131 MB
Bandwidth: in = 10.9 KB/s, out = 517 KB/s

Packets: in = 2266332, out = 1445940
Bytes: in = 1.18 GB, out = 132 MB
Bandwidth: in = 9.41 KB/s, out = 600 KB/s

Packets: in = 2266680, out = 1446520
Bytes: in = 1.19 GB, out = 132 MB
Bandwidth: in = 10.5 KB/s, out = 409 KB/s

Packets: in = 2267136, out = 1447542
Bytes: in = 1.19 GB, out = 133 MB
Bandwidth: in = 12.3 KB/s, out = 723 KB/s

Packets: in = 2267366, out = 1447892
Bytes: in = 1.19 GB, out = 133 MB
Bandwidth: in = 6.1 KB/s, out = 248 KB/s

Packets: in = 2267686, out = 1448802
Bytes: in = 1.19 GB, out = 134 MB
Bandwidth: in = 9.35 KB/s, out = 634 KB/s

Packets: in = 2268218, out = 1449602
Bytes: in = 1.19 GB, out = 135 MB
Bandwidth: in = 16.5 KB/s, out = 571 KB/s

Packets: in = 2268566, out = 1450446
Bytes: in = 1.19 GB, out = 135 MB
Bandwidth: in = 9.46 KB/s, out = 596 KB/s

And against tap0 during normal activity:

$ ./bandwidth 
Packets: in = 3782, out = 3308
Bytes: in = 825 KB, out = 475 KB
Bandwidth: in = 0 B/s, out = 0 B/s

Packets: in = 3787, out = 3310
Bytes: in = 829 KB, out = 476 KB
Bandwidth: in = 3.92 KB/s, out = 132 B/s

Packets: in = 3790, out = 3312
Bytes: in = 832 KB, out = 476 KB
Bandwidth: in = 3.46 KB/s, out = 132 B/s

Packets: in = 3793, out = 3314
Bytes: in = 836 KB, out = 476 KB
Bandwidth: in = 3.41 KB/s, out = 132 B/s

Packets: in = 3796, out = 3316
Bytes: in = 839 KB, out = 476 KB
Bandwidth: in = 3.41 KB/s, out = 132 B/s

Packets: in = 3799, out = 3319
Bytes: in = 843 KB, out = 476 KB
Bandwidth: in = 3.54 KB/s, out = 480 B/s

Packets: in = 3802, out = 3321
Bytes: in = 846 KB, out = 476 KB
Bandwidth: in = 3.55 KB/s, out = 132 B/s

Packets: in = 3805, out = 3323
Bytes: in = 850 KB, out = 477 KB
Bandwidth: in = 3.55 KB/s, out = 132 B/s

Packets: in = 3808, out = 3325
Bytes: in = 853 KB, out = 477 KB
Bandwidth: in = 3.55 KB/s, out = 132 B/s

Packets: in = 3809, out = 3326
Bytes: in = 854 KB, out = 477 KB
Bandwidth: in = 866 B/s, out = 66 B/s
bandwidth.c

jkbull...gmail.com

unread,
Feb 8, 2012, 10:31:30 PM2/8/12
to tunnelbli...@googlegroups.com
Thanks, Nicholas.

vkapovit

unread,
Feb 8, 2012, 11:24:50 PM2/8/12
to tunnelblick-discuss
Thanks a lot, Nicholas,
This is indeed quite useful.

Vitali

On Feb 8, 9:36 pm, Nicholas Williams <nicho...@nicholaswilliams.net>
wrote:
> I have attached a code sample for monitoring network traffic on a
> particular interface. Compiling and executing is very simple:
>
> $ g++ bandwidth.c -o bandwidth
> $ ./bandwidth
>
> Near the top is a line that you can change the name of the interface being
> monitored:
>
> const char * IFACE_CODE = "tap0";
>
> You can change it to tap1 or tun0 or en0 or en1 or whatever is necessary.
>
> This program displays ten samples taken one second apart, each sample
> displaying total packets in/out, total bytes in/out, and average bandwidth
> over the last second.
>
> The source code should be very useful (to either of you) for modifying
> Tunnelblick to monitor network traffic.
>
> The only unfortunate thing is that even after the VPN is disconnected and
> reconnected, the total packets and bytes are not reset until the computer
> is restarted. So this number will not represent "traffic since connected"
> but rather "traffic since boot." It's unfortunate, but I can't find a way
> around it. Unlike linux, Mac OS X does not appear to have a way to reset
> network statistics on an interface.
>
> Don't know how much it will help, but hopefully it will some.
>
> Nick
>
> *Here is some sample output from this on en1 (Airport) during a
> speedtest.net test:*
> *And against tap0 during normal activity:*
>  bandwidth.c
> 2KViewDownload
Message has been deleted

vkapovit

unread,
Feb 12, 2012, 10:37:48 AM2/12/12
to tunnelbli...@googlegroups.com
A small update.
I followed your first suggestion and it seems to work well. My monitor script displays a notification via Growl every minute after 20 minutes of VPN connection or after 100MB bandwidth traffic is reached (I used the script that Nicholas made). I use Growl to create the notification itself as I don't know how to create nice looking notifications directly.
None of this was hard but I suspect most end users such as myself would not be able to do it on their own so a built in bandwidth monitoring feature in tunnelblick would be welcome.
Best,
Vitali

jkbull...gmail.com

unread,
Feb 12, 2012, 10:59:59 AM2/12/12
to tunnelbli...@googlegroups.com
That's great! I'd love to include your script(s) in the User Contributed Scripts section of the Downloads page.

vkapovit

unread,
Feb 12, 2012, 1:50:45 PM2/12/12
to tunnelbli...@googlegroups.com
Well, ok. I'm attaching the scripts. But please keep in mind that they were made for internal consumption and as such they are not exactly polished.
The two shell scripts are very basic. The first starts the monitor script (which is an app /Applications/timer.app). The post-disconnect.sh script kills off the timer process once the VPN connection closes.
The two scripts as well as the .vpn configuration file should be placed in a folder. give that folder a .tblk extension and double-click it to install it as a tunnelblick configuration.

The main content is the monitor file. I made that with applescript because I wanted to display the notifications using Growl which has nice applescript support.  That is contained in the timer.zip file. unzip it and put the app timer.app in the main Applications folder.

Here is the content of that script

tell application "System Events"
    set isRunning to (count of (every process whose bundle identifier is "com.Growl.GrowlHelperApp")) > 0
    --checking to see if Growl is running.
end tell
--if Growl is not running, start it up

if not isRunning then tell application "Growl" to launch

delay 1

set gb_in to (do shell script "/Library/Scripts/myscripts/bandwidth-mine| awk '{print $4}'")
--MB in
set gb_out to (do shell script "/Library/Scripts/myscripts/bandwidth-mine| awk '{print $8}'")
--MB out
set initial_traffic to gb_in + gb_out
--total network traffic in and out measured in MB

tell application id "com.Growl.GrowlHelperApp"
    -- Make a list of all the notification types
    -- that this script will ever send:
    set the allNotificationsList to ¬
        {"Test Notification", "Another Test Notification"}
   
    -- Make a list of the notifications
    -- that will be enabled by default.     
    -- Those not enabled by default can be enabled later
    -- in the 'Applications' tab of the growl prefpane.
    set the enabledNotificationsList to ¬
        {"Test Notification", "Another Test Notification"}
   
    register as application ¬
        "Timer" all notifications allNotificationsList ¬
        default notifications enabledNotificationsList ¬
        icon of application "Tunnelblick"
   
end tell

set x to 0
-- x is the timer from the connection start in seconds
repeat
   
    set x to x + 60
    delay 60
    if x ≥ 1200 then
        say ("Tunnelblick has been up for " & (x div 60) as text) & "minutes"
        -- notifies that tunnelblick is running every minute after 20 minutes of connection uptime
       
        --       Send a Growl Notification too…
        tell application id "com.Growl.GrowlHelperApp"
            notify with name ¬
                "Test Notification" title ¬
                "Test Notification" description ¬
                "Tunnelblick has been up for " & ((x div 60) as text) & "minutes" application name "Timer"
        end tell
    end if
   
    set current_gb_in to (do shell script "/Library/Scripts/myscripts/bandwidth-mine| awk '{print $4}'")
    -- current MB in
    set current_gb_out to (do shell script "/Library/Scripts/myscripts/bandwidth-mine| awk '{print $8}'")
    --current MB out
    set current_traffic to current_gb_in + current_gb_out
    --total  current network traffic in and out measured in MB
    if current_traffic - initial_traffic > 100 then
        --       Send a Growl Notification if total network activity from the time the VPN connection was established has exceeds 100MB
        tell application id "com.Growl.GrowlHelperApp"
            notify with name ¬
                "Another Test Notification" title ¬
                "Another Test Notification" description ¬
                ("Network traffic with tunnelblick active has exceeded " & (current_traffic - initial_traffic) as text) & "MBs" application name "Timer"
        end tell
    end if
end repeat


Of course, Growl needs to be installed first in order for the script to work. The script can be easily modified as needed.
Also, after I saved it as an app  (called timer.app) I modified the info.plist for timer.app so that it doesn't show up in the dock when it runs. That's done by adding the following two lines to the info.plist:

<key>LSUIElement</key>
    <string>1</string>


Note that the script refers to yet another shell script /Library/Scripts/myscripts/bandwidth-mine. That's a shellscript I made using the code that Nocholas posted. It measures the total network traffic via the VPN connection. I attach the complied file as well as the source code (main.c). I put it in /Library/Scripts/myscripts but you  of course it can be stored anywhere you want.

I think that's about it. Feel free to modify and improve. This was done to suit my basic needs so i didn't try to polish it in any way.

Vitali
connected.sh
post-disconnect.sh
timer.zip
bandwidth-mine.zip

jkbull...gmail.com

unread,
Feb 21, 2012, 8:18:49 AM2/21/12
to tunnelbli...@googlegroups.com
Thanks!

I have added your files to the "User Contributed Scripts" section of the Downloadspage

jkbull...gmail.com

unread,
Mar 20, 2012, 6:49:38 AM3/20/12
to tunnelbli...@googlegroups.com
An update:

Tunnelblick 3.3beta02 tracks usage on a per-configuration basis and includes AppleScript hooks to get at the usage figures.

Usage is displayed in Tunnelblick's standard Growl-like notification window, which also now appears whenever you move the pointer (mouse) over the Tunnelblick icon in the menu bar.

Two AppleScript "nouns" are available for each connection, "bytesIn" and "bytesOut". See AppleScript Support for details and examples.

vkapovit

unread,
Apr 25, 2012, 10:44:57 PM4/25/12
to tunnelbli...@googlegroups.com
Cool!  Thanks a lot for adding those features! And thanks for providing the applescript handlers to access the bytes in/out data. when I have time I will rewrite my scripts to make use of them and get rid of the compiled binaries I was using.
Vitali
Reply all
Reply to author
Forward
0 new messages