#!/usr/bin/perl
#
# fritzboxtraffic
# fritzboxtraffic is a script to retrieve the traffic statistic from
# a Fritz!Box 7270 model (or similar) and present the data in a more
# human readable form
#
# Copyright (C) 2009, Klaus Singvogel, klaus@singvogel.net
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version. 
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details. 
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
#

use strict;
use Net::Telnet;
use Getopt::Std;

# either set in the ip address of the fritz!box here (alternative: hostname)
# or use the first command line argument
#
my $fritz_host = "192.168.1.254";

# enable debuggin: be more verbose
my $debug = 0;

# timeout for telnet connection
my $timeout = 15;

# declare and initialize some values
my $sentL = my $sentH = my $recvL = my $recvH = my $total = 0;
my $calls = my $connTime = my $now = my $sent = my $recv = 0;
my $line = my $date_string = "";
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst);

# process command line
our($opt_h, $opt_w);
getopts("wh");
if (defined $opt_h) {
    print "Usage: $0 [-h] [-w] [host]\n";
    print "Retrieve traffic statistic from Fritz!Box\n";
    print "\n\tOptions are:\n";
    print "\t-w\tprint in column output instead of rows\n";
    print "\t-h\tprint this help and exit\n";
    exit(1),
}
foreach (@ARGV) {
    $fritz_host = $_;
}

# open telnet connection...
my $fritz  = new Net::Telnet(Timeout => 10);
$fritz->open($fritz_host)  || die "telnet failed: $!";
$fritz->waitfor('/# $/');
# ... and receive stat file
my @lines = $fritz->cmd("cat /var/flash/stat.cfg");
# and close telnet connection
$fritz->close();

if (defined $opt_w) {
    print "                  Online-Zeit (hh:mm)  Verbind.  Traffic (Summe,gesend.,empf.)\n";
}
# process the input lines...
foreach (@lines) {
    $debug && print "debug: "; # debug output
    $debug && print ; # debug output
    chomp;
    if (/TimeStamp/) {
	$now = (split)[-1];
	chop($now);
	chop($now);
	$debug && print "debug now: now = $now "; # debug output
	($mday,$mon,$year) = (localtime($now))[3..5];
	next if (defined $opt_w);
	printf "Datum Messung:   %d-%02d-%02d\n", $year+1900, $mon+1, $mday;
    }

    # set the variables according to content
    if (/PhyConnTimeOutgoing/) {
	$connTime = (split)[-1];
	chomp($connTime);
    }
    if (/OutgoingCalls/) {
	$calls = (split)[-1];
	chomp($calls);
    }
    if (/BytesSentLow/) {
	$sentL = (split)[-1];
	chomp($sentL);
    }
    if (/BytesSentHigh/) {
	$sentH = (split)[-1];
	chomp($sentH);
    }
    if (/BytesReceivedLow/) {
	$recvL = (split)[-1];
	chomp($recvL);
    }
    if (/BytesReceivedHigh/) {
	$recvH = (split)[-1];
	chomp($recvH);
    }

    # start of a block
    if (/\s.*{/) {
        # use and save for later output correct german naming
    	$date_string = "Heute" if /Today/;
    	$date_string = "Gestern" if /Yesterday/;
    	$date_string = "Aktuelle Woche" if /ThisWeek/;
    	$date_string = "Letzte Woche" if /LastWeek/;
    	$date_string = "Aktueller Monat" if /ThisMonth/;
    	$date_string = "Letzter Monat" if /LastMonth/;
    	$date_string = "Gesamt" if /Total/;
    }
    # end of a block
    if (/\s.*}/) {
        # calculate the values, includes doing a rounding
	$total=($sentL+$sentH+$recvL+$recvH)/1024/1024 + 0.5;
	$sent = ($sentL + $sentH)/1024/1024 + 0.5;
	$recv = ($recvL + $recvH)/1024/1024 + 0.5;
	$connTime += 30;
	$connTime /= 60;

	# and now output..
	if (defined $opt_w) {
	    printf"%-19s          %4.0d:%02d    %5d    %5.0dMB,%5.0dMB,%5.0dMB\n",
		$date_string, $connTime/60, $connTime%60, $calls, $total,
		$sent, $recv;
	} else {
	    printf "$date_string:\n";
	    printf "        Onlinezeit (hh:mm):  %.0d:%02d\n", $connTime/60, $connTime%60;
	    printf "        Datenvolumen:        gesamt %.0dMB, gesendet/empfangen %.0dMB/%.0dMB\n", $total, $sent, $recv;
	    printf "        Anzahl Verbindungen: %d\n\n", $calls;
	}
    }
}
if (defined $opt_w) {
    printf "\n%58s:   %d-%02d-%02d\n", "Datum der Messung", $year+1900, $mon+1, $mday;
}
