CONTADOR DE SESIONES PARA LINUX
Hola,
Para los que estéis accediendo con el ordenador a internet través del móvil y estéis usando Linux, seguramente os sea de utilidad un script que he desarrollado, y que adjunto a continuación. Es un contador de "sesiones", tal como las define Vodafone (10 minutos o 256KB), las cuales sirven para tarificar el acceso a internet. Puede adaptarse facilmente a otros operadores y tipos de sesión.
Personalmente lo utilizo a diario y su funcionamiento creo que es correcto. Si encontráis algún error no dudéis en poneros en contacto conmigo (libnet_ algarroba myway.com).
Como veréis en la documentación que hay al principio del script, es también útil para la Promoción Verano, ya que nos permite ver el progreso en el consumo de las 1000 sesiones gratuitas por periodo de facturacion que incluye la oferta.
Si os parece bien, una vez que lo hayais probado y que hayamos podido depurar cualquier posible error, se podría guardar por ejemplo en la sección "Files", para facilitar la descarga del fichero y que así la gente no tenga que copiar y pegar a mano el script.
Espero que os sea útil
Libnet
------------------------------------------------------------------------------
Fichero adjunto: conta_ses.pl
------------------------------------------------------------------------------
#!/usr/bin/perl
#
# conta_ses.pl
#
# Contador de "sesiones" de Internet.
# Version 0.9 (12-ago-2006)
#
#
#
# POR QUE este script:
#
# - En Vodafone (y posiblemente en otros operadores), el consumo de internet se
# tarifica por "sesiones". Una "sesión" se define como 256KB de transferencia
# o 10 minutos de tiempo (lo que ocurra primero).
#
# - Por tanto, para saber el numero de "sesiones" consumidas, no basta con saber
# el total de datos transferidos o el tiempo total de conexión. Es preciso ir
# contando las sesiones conforme se van consumiendo.
#
# - Las sesiones se cobran por adelantado, es decir, antes de consumirlas. Nada
# mas conectar, ya has gastado una sesion. Por ejemplo, si conectas y
# desconectas rápidamente 3 veces (sin apenas consumir tiempo ni datos), te
# cobran 3 "sesiones".
#
# - Otro ejemplo. La Promoción Verano de este año anuncia "250MB gratis", pero
# en realidad son "1000 sesiones gratis". Si te conectaras a internet el
# primer día de facturación, y te desconectaras el último dia de facturación,
# sin haber transferido datos en todo el tiempo, tendrías que pagar
# aproximadamente (teniendo en cuenta que 1000 sesiones dan para
# 1000*10 minutos =~ 7 dias):
#
# (30-7)*24*(60/10) sesiones * 0.5 euros/sesion = 1656 euros
#
# Es decir, tendrías que pagar 1656 euros, a pesar de no haber consumido ni
# 1KB de los "250MB gratis".
#
#
# QUE HACE este script:
#
# - Cuenta el numero de "sesiones" conforme se van consumiendo.
#
# - Para ello, tiene en cuenta conexiones y desconexiones, tiempo de conexión,
# y datos transferidos (subida y bajada).
#
# - Va acumulando en un fichero (contador.txt) las sesiones contabilizadas.
# Para poner a cero el contador, sólo hay que borrar (o renombrar) el fichero.
#
# - Va generando un fichero de bitácora (conta_ses.log) con el historial de
# sesiones consumidas.
#
# - Es fácilmente adaptable a cualquier operador, a cualquier interfaz, y
# a cualesquiera cantidades que definan una "sesión".
#
#
# CUAN FIABLE es este script:
#
# - Este script funciona por muestreo. Es decir, cada cierto tiempo (periodo de
# muestreo) recoge muestras del estado de la interfaz (conectada o
# desconectada) y de los datos transferidos hasta el momento (bajada+subida).
#
# - Por tanto, no conoce el momento exacto en el que la interfaz cambia de
# estado o en el que se alcanza el máximo de datos de una sesión, ya eso que
# puede ocurrir en cualquier momento entre dos muestras.
#
# - Sin embargo, al ser el periodo de muestreo muy bajo (por defecto, de una
# décima de segundo), el error cometido también es muy bajo, lo suficiente
# como para afirmar que la contabilización de sesiones es muy fiable. No es
# exacta, pero sí muy aproximada.
#
# - Esto significa que no debe usarse este script, por ejemplo, para apurar "al
# máximo" un bono de acceso a internet (para consumir hasta la última sesión
# pero sin pasarse). Es decir, si tenemos un bono de 400 sesiones, y el script
# lleva contabilizadas 380, no podemos pretender llegar justo hasta 400,
# porque puede ser que se hayan contado algunas de menos o de mas. Aunque nos
# indique que hemos consumido 380, puede que en realidad hayamos consumido
# 377 o 383 (por poner un ejemplo).
#
# - Sí puede usarse para saber, con una fiabilidad bastante alta, cuánto hemos
# consumido.
#
# - Si se desea, puede aumentarse la exactitud modificando el periodo de
# muestreo. Cuanto mas pequeño sea este, mas pequeño será el error, y
# por tanto mas exacta será la contabilización de sesiones. Por ejemplo, en
# vez del periodo por defecto de una décima de segundo (0"1 seg.), puede
# utilizarse una centésima (0"01 seg.) o incluso con una milésima
# (0"001 seg.). La contrapartida es que, cuanto mas rápido se muestree, mayor
# será el uso del procesador por parte del script.
#
#
# CUANDO debe ejecutarse este script:
#
# - El script debe estar ejecutandose siempre que se realice una conexión, y
# no debe detenerse (control+c) hasta que finalice la conexión.
#
# - Si se lanza cuando ya está establecida una conexion, hará una estimación
# del número de sesiones consumidas durante la conexión, calculando el número
# de sesiones equivalentes a los datos transferidos.
#
# - El script sólo contabiliza sesiones mientras se está ejecutando, no
# contabiliza sesiones correspondientes a conexiones antiguas en las que no
# se estaba ejecutando. Por ejemplo: si, sin estar ejecutándose el script, se
# realiza una conexión, se transfieren datos, y se termina la conexión, las
# sesiones consumidas durante la conexión habrán quedado sin contabilizar.
#
# - Por tanto, se recomienda lanzar el script nada mas encender el ordenador,
# antes de realizar cualquier conexión, y dejarlo funcionando continuamente.
#
#
# COMO ejecutar este script:
#
# - Hay 2 comandos posibles:
#
# - perl conta_ses.pl
#
# - ./conta_ses.pl (darle antes permiso de ejecución (chmod +x conta_ses.pl))
#
# - Puede llamarse desde cualquier directorio (y desde cualquier script).
#
#
# REQUISITOS:
#
# - Ordenador gnulinux con interfaz lógica de red. Normalmente será la interfaz
# que utilices para la conexión punto-a-punto con el móvil (por ejemplo ppp0),
# pero puede servir cualquier interfaz (puedes probar con: lo, eth0, ...).
# - Perl.
# - Módulo Time::HiRes (viene de serie desde Perl 5.8) (disponible en cpan.org).
# - Kernel linux 2.6 (o superior). (proporciona el arbol /sys)
#
#
# Restricciones de LIBERTAD:
#
# - Este programa es Software Libre.
# - Eso significa que eres libre de usarlo, copiarlo, compartirlo y modificarlo
# (entre otras cosas).
# - Licencia GNU GPL 2.0 (disponible en www.gnu.org/licenses/gpl.html).
# - Y por supuesto, puedes contribuir a mejorarlo. Por ejemplo, detectando
# errores, añadiendo funcionalidad, traduciendo a otros idiomas, etc.
#
#
# AUTOR:
#
# - Libnet (libnet_ algarroba myway.com).
#
## Bibliotecas
use Time::HiRes qw( time sleep ); ## si no está instalada, descargar de CPAN.
use FindBin qw( $RealBin ); ## directorio del script
## Configuracion
$int = "ppp0"; ## interfaz [ppp0]
$ses_t = 10 * 60; ## tiempo de sesión (segundos) [10 minutos]
$ses_d = 256 * 1024; ## datos de sesión (bytes) [256 KB]
$p_mues = 0.1; ## periodo de muestreo (segundos) [1 décima]
$f_cont = "${RealBin}/contador.txt"; ## fich con el contador (núm. de sesiones)
$f_log = "${RealBin}/conta_ses.log"; ## fichero de bitácora
## Info interfaz
$int_d = "/sys/class/net/$int"; ## directorio de la interfaz
$int_d_es = "${int_d}/statistics"; ## direc de estadisticas de la interfaz
$int_f_su = "${int_d_es}/tx_bytes"; ## fichero contador de subida
$int_f_ba = "${int_d_es}/rx_bytes"; ## fichero contador de bajada
## Inicio bitácora
impri_log ("------ Iniciado programa");
## Contador acumulado
if (-e $f_cont) ## existe fichero contador -> leemos
{
open FCONT, "< $f_cont";
chomp ($f_ini_cont = <FCONT>); ## fecha inicio del contador (1a linea)
chomp ($n_ses = <FCONT>); ## numero de sesiones consumidas (2a)
close FCONT;
}
else ## no existe fichero contador -> creamos
{
$f_ini_cont = localtime;
$n_ses = 0;
guar_cont(); ## guardamos contador en fichero
}
impri ("Contador iniciado: $f_ini_cont");
impri ("Sesiones consumidas:");
impri ("= $n_ses");
## Bucle principal
$conectado = 0; ## conectado en este momento? (= hay sesion ahora?)
$ini_ses_t = 0; ## instante de inicio de la sesion actual
$ini_ses_d = 0; ## datos transferidos al iniciarse la sesion actual
$t_dorm = 0; ## tiempo a dormir
$mues_t = time; ## muestra de tiempo actual
$mues_t_sig = $mues_t; ## muestra de tiempo siguiente (muestreamos ya)
$mues_t_ant = $mues_t; ## muestra de tiempo anterior
$t_imp = 0; ## instante de ultima impresion por pantalla
$| = 1; ## escritura en pantalla sin buffer
while (1)
{
## Dormimos hasta siguiente muestra
$t_dorm = $mues_t_sig - time; ## rectifica desviaciones de tiempo
if ($t_dorm > 0)
{
sleep $t_dorm; ## dormimos el tiempo calculado
}
else
{
$t_dorm = 0;
}
## Datos de la muestra actual
$mues_t_ant = $mues_t; ## muestra de tiempo anterior
$mues_t = $mues_t_sig; ## muestra de tiempo actual
$nue_ses = 0; ## es nueva sesion?
## Casos posibles
if (-e $int_d) ## existe la interfaz (= conectado)
{
if ($conectado) ## estaba conectado -> sigue conectado
{
$mues_d = dat_act(); ## muestra de datos
$dif_t = $mues_t - $ini_ses_t; ## diferencia de tiempo entre muestras
$dif_d = $mues_d - $ini_ses_d; ## diferencia de datos entre muestras
if ($dif_t >= $ses_t) ## superado el tiempo de sesion
{
$n_ses++; ## una sesion mas
guar_cont(); ## guardamos contador en fichero
$nue_ses = 1; ## es nueva sesion
$ini_ses_t += $ses_t; ## instante de inicio de la nueva session
$ini_ses_d = $mues_d; ## datos transferidos al iniciarse la sesion
impri ("+1 = $n_ses Tiempo");
$mues_t_sig = $ini_ses_t + $p_mues; ## muestra de tiempo siguiente
}
elsif ($dif_d >= $ses_d) ## superados los datos de sesion
{
$inc_n_ses = int ($dif_d / $ses_d); ## sesiones equivalentes
$n_ses += $inc_n_ses; ## anadimos incremento de sesiones
guar_cont(); ## guardamos contador en fichero
$nue_ses = 1; ## es nueva sesion
$ini_ses_t = ($mues_t + $mues_t_ant) / 2; ## estimamos que los datos se
## superaron a mitad del intervalo
$dec_d = $dif_d % $ses_d; ## decremento de datos
$ini_ses_d = $mues_d - $dec_d; ## datos al iniciarse la sesion
impri ("+$inc_n_ses = $n_ses Datos");
$mues_t_sig = $ini_ses_t + $p_mues; ## muestra de tiempo siguiente
}
else ## no superados tiempo ni datos
{
$mues_t_sig = $mues_t + $p_mues; ## muestra de tiempo siguiente
}
}
else ## no estaba conectado -> acaba de conectarse
{
$n_ses++; ## una sesion mas
guar_cont(); ## guardamos contador en fichero
$nue_ses = 1; ## es nueva sesion
$ini_ses_t = ($mues_t + $mues_t_ant) / 2; ## estimamos a mitad del interv.
$ini_ses_d = 0; ## datos transferidos al iniciarse la sesion
impri ("+1 = $n_ses Iniciada conexion");
$mues_t_sig = $mues_t + $p_mues; ## muestra de tiempo siguiente
}
## Informacion en pantalla
if (
(($mues_t - $t_imp) >= 0.9) ## refrescamos pantalla cada 0"9 seg.
or
$nue_ses ## o cuando hay nueva sesion
)
{
## Tiempo
$minus = int ($dif_t / 60); ## minutos
$segs = $dif_t % 60; ## segundos
## Datos
$dats = ($dif_d >= 10 * 1024**2) ? sprintf ("%d MB", $dif_d / 1024**2)
: ($dif_d >= 1000 * 1024) ? sprintf ("%.01f MB", $dif_d / 1024**2)
: ($dif_d >= 10 * 1024) ? sprintf ("%d KB", $dif_d / 1024)
: ($dif_d >= 1000 * 1) ? sprintf ("%.01f KB", $dif_d / 1024)
: sprintf ("%d B", $dif_d);
## Porcentage
$porc_t = int (100 * $dif_t / $ses_t); ## porcentage de tiempo
$porc_d = int (100 * $dif_d / $ses_d); ## porcentage de datos
$porc = ($porc_t > $porc_d) ? $porc_t : $porc_d; ## el mayor
## Linea a imprimir
$tex = sprintf ("[%02d:%02d %7s %4s%]", $minus, $segs, $dats, $porc);
print ""x79, " "x79, ""x79,
" ", $tex;
## Tiempo de impresion
$t_imp = $mues_t;
}
## Cerca de tiempo máximo?
($mues_t_sig > ($ini_ses_t + $ses_t)) ## muestrear fuera de sesión
and $mues_t_sig = $ini_ses_t + $ses_t; ## muestrear justo al terminar
$conectado = 1;
}
else ## no existe la interfaz (= desconectado)
{
if ($conectado) ## estaba conectado -> acaba de desconectar
{
impri ("= $n_ses Terminada conexion");
}
else ## no estaba conectado -> sigue desconectado
{
}
$mues_t_sig = $mues_t + $p_mues; ## muestra de tiempo siguiente
$conectado = 0;
}
}
#######################
sub impri ## imprime en pantalla y en bitácora
{
my ($tex) = @_;
my ($s, $m, $h) = localtime;
print ""x79, " "x79, ""x79,
sprintf("[%02d:%02d:%02d]", $h, $m, $s),
" ", $tex, " ";
impri_log($tex);
}
#######################
sub impri_log ## imprime sólo en bitácora
{
my ($tex) = @_;
open FLOG, ">> $f_log"
or die "No puedo abrir fichero de bitacora";
print FLOG "[", scalar(localtime), "] $tex ";
close FLOG;
}
#######################
sub dat_act ## obtiene datos transferidos actuales
{
my ($dat_sub, $dat_baj);
open FSUB, "< $int_f_su"
or die "No puedo abrir fichero de subida";
chomp ($dat_sub = <FSUB>);
close FSUB;
open FBAJ, "< $int_f_ba"
or die "No puedo abrir fichero de bajada";
chomp ($dat_baj = <FBAJ>);
close FBAJ;
return $dat_sub + $dat_baj;
}
#######################
sub guar_cont ## guarda contador
{
$f_cont_tmp = $f_cont . ".tmp";
open FCONTTMP, "> $f_cont_tmp"
or die "No puedo abrir fichero temporal de bitacora";
print FCONTTMP $f_ini_cont, " ",
$n_ses, " ";
close FCONTTMP;
rename $f_cont_tmp, $f_cont
or die "No puedo renombrar fichero temporal de bitacora";
}
#######################