Кто захочет может продолжить.
- Код: Выделить всё
program acctraff;
//{$APPTYPE CONSOLE}
uses
SysUtils, Classes, BaseUnix, Unix;
var
fl_cl, fl_mngl: TStringList;
arr_cl: array of array[0..5] of string;
arr_mngl: array of array[0..8] of string;
n1, n2, n3, n4, n5, n_cl, n_mngl: integer;
tmpstr, pdstr, tema_mail: string;
file_cl, file_mail, file_act, file_ini, file_http, file_test, com_mngl: string;
// from ini file
arr_ini: array[0..7] of string;
eth0, eth1, local_lan, local_mask, ip_inet, adr_root, ping_ip, http_adr: string;
//==============================================================================
//------------------------------------------------------------------------------
procedure read_ini;
var
f1: Text;
begin
if not FileExists(file_ini) then
begin
eth0:='eth0';
eth1:='eth1';
local_lan:='192.168.0.0';
local_mask:='255.255.0.0';
ip_inet:='192.168.1.1';
adr_root:='root';
ping_ip:='192.168.1.2';
http_adr:='http://www.uz';
end;
Assign(f1,file_ini);
Reset(f1);
while not Eof(f1) do
begin
Readln(f1,tmpstr);
if tmpstr[1]<>'#' then
begin
arr_ini[n1]:=tmpstr;
n1:=n1+1;
end;
end;
Close(f1);
eth0:=arr_ini[0];
eth1:=arr_ini[2];
local_lan:=arr_ini[3];
local_mask:=arr_ini[4];
ip_inet:=arr_ini[1];
adr_root:=arr_ini[5];
ping_ip:=arr_ini[6];
http_adr:=arr_ini[7];
end;
//------------------------------------------------------------------------------
procedure action;
var
f1: Text;
begin
Assign(f1,file_act);
Rewrite(f1);
Writeln(f1, '#!/bin/bash');
Writeln(f1, '#');
Writeln(f1, '/sbin/iptables -t mangle -F');
Writeln(f1, '/sbin/iptables -F FORWARD');
Writeln(f1, '/sbin/iptables -t nat -F POSTROUTING');
Writeln(f1, '');
for n1:=0 to length(arr_cl)-2 do
begin
Writeln(f1, '# Welcome to the ACCTRAFF '+arr_cl[n1,0]);
Write(f1, '/sbin/iptables -t mangle -A PREROUTING -i '+eth1+' ');
Write(f1, '-s '+arr_cl[n1,1]+'/255.255.255.255 -d ! '+local_lan);
Writeln(f1, '/'+local_mask+' -j ACCEPT');
Writeln(f1, '');
Write(f1, '/sbin/iptables -t mangle -A POSTROUTING -o '+eth0+' ');
Write(f1, '-d '+arr_cl[n1,1]+'/255.255.255.255 -s ! '+local_lan);
Writeln(f1, '/'+local_mask+' -j ACCEPT');
Writeln(f1, '');
end;
Writeln(f1, '# Welcome to INTERNET ');
Write(f1, '/sbin/iptables -t nat -A POSTROUTING -o '+eth0+' ');
Write(f1, '-s '+local_lan+'/'+local_mask);
Writeln(f1, ' -j SNAT --to-source '+ip_inet);
Writeln(f1, '');
Close(f1);
fpchmod(file_act,&755);
popen(f1,file_act,'r');
pclose(f1);
end;
//------------------------------------------------------------------------------
procedure zero_arr_cl;
begin
Finalize(arr_cl);
end;
//------------------------------------------------------------------------------
procedure zero_arr_mngl;
begin
Finalize(arr_mngl);
end;
//------------------------------------------------------------------------------
procedure mail_to_root;
var
f1: Text;
begin
popen(f1,'/bin/mail -s '+tema_mail+' root < '+file_mail,'r');
pclose(f1);
end;
//------------------------------------------------------------------------------
procedure clients_exist;
var
f1: text;
begin
if not FileExists(file_cl) then
begin
tema_mail:='From_ACCTRAFF';
Assign(f1,file_mail);
Rewrite(f1);
Writeln(f1,'');
Writeln(f1,' Отсутствует файл /etc/acctraff/clients');
Writeln(f1,'');
Writeln(f1,' Подсчет траффика не возможен!');
Writeln(f1,'');
Writeln(f1,' Создано '+FormatDateTime('dd-mmmm-yyyy hh:mm', now));
Close(f1);
mail_to_root;
halt;
end;
end;
//------------------------------------------------------------------------------
procedure read_clients;
var
f1, f2: Text;
begin
n_cl:=0;
Assign(f1,file_cl);
Reset(f1);
while not eof(f1) do
begin
Readln(f1, tmpstr);
if tmpstr[1]<>'#' then
begin
n_cl:=n_cl+1; //
end;
end;
if n_cl<1 then
begin
tema_mail:='From_ACCTRAFF';
Assign(f2,file_mail);
Rewrite(f2);
Writeln(f2,'');
Writeln(f2,' Отсутствуют записи в файле /etc/acctraff/clients');
Writeln(f2,'');
Writeln(f2,' Подсчет траффика не возможен!');
Writeln(f2,'');
Writeln(f2,' Создано '+FormatDateTime('dd-mmmm-yyyy hh:mm', now));
Close(f1);
Close(f2);
mail_to_root;
zero_arr_cl;
halt;
end;
SetLength(arr_cl,n_cl);
Reset(f1);
n1:=0;
while not eof(f1) do
begin
Readln(f1,tmpstr);
pdstr:='';
n2:=0;
if tmpstr[1]<>'#' then
begin
for n3:=1 to length(tmpstr)+1 do
begin
if not (tmpstr[n3] in [' ', #9, #0]) then
begin
pdstr:=pdstr+tmpstr[n3];
if tmpstr[n3+1] in [' ', #9, #0] then
begin
arr_cl[n1,n2]:=pdstr;
pdstr:='';
n2:=n2+1;
if n2=6 then
begin
n2:=0;
n1:=n1+1;
end;
end;
end;
end;
end;
end;
Close(f1);
end;
//------------------------------------------------------------------------------
procedure zapusk_ipt_mngl;
var
f1: Text;
begin
fl_mngl:=TStringList.Create;
popen(f1,com_mngl,'r');
while not eof(f1) do
begin
readln(f1,tmpstr);
if pos(local_lan,tmpstr)>0 then
begin
fl_mngl.add(tmpstr);
end;
end;
if fl_mngl.Count<=0 then
begin
tema_mail:='From_ACCTRAFF';
Assign(f1,file_mail);
Rewrite(f1);
Writeln(f1,'');
Writeln(f1,' Not exist or not answer mangle');
Writeln(f1,'');
Writeln(f1,' Run iptables from clients');
Writeln(f1,'');
Writeln(f1,' Created '+formatdatetime('dd-mmmm-yyyy hh:mm', now));
Close(f1);
mail_to_root;
action;
zero_arr_cl;
halt;
end;
n1:=fl_mngl.Count;
SetLength(arr_mngl,n1);
for n1:=0 to fl_mngl.Count-1 do
begin
tmpstr:=fl_mngl.Strings[n1];
pdstr:='';
n3:=0;
for n2:=1 to length(tmpstr)+1 do
begin
if not (tmpstr[n2] in [' ', #9, #0]) then
begin
pdstr:=pdstr+tmpstr[n2];
if tmpstr[n2+1] in [' ', #9, #0] then
begin
arr_mngl[n1,n3]:=pdstr;
pdstr:='';
n3:=n3+1;
end;
end;
end;
end;
end;
//------------------------------------------------------------------------------
procedure who_is_who;
var
f1: text;
begin
for n1:=0 to length(arr_cl)-2 do
begin
n3:=0;
for n2:=0 to length(arr_mngl)-1 do
begin
if (arr_cl[n1,1] = arr_mngl[n2,7]) or (arr_cl[n1,1] = arr_mngl[n2,7]) then
begin
n3:=1;
end;
end;
if n3=0 then
begin
tema_mail:='From_ACCTRAFF';
Assign(f1,file_mail);
Rewrite(f1);
Writeln(f1,'');
Writeln(f1,' Перезапускаю iptables!');
Writeln(f1,'');
Writeln(f1,' Для нового клиента - '+arr_cl[n1,0]+' '+arr_cl[n1,1]);
Writeln(f1,'');
Writeln(f1,' Created '+formatdatetime('dd-mmmm-yyyy hh:mm', now));
Close(f1);
mail_to_root;
action;
halt;
end;
end;
for n1:=0 to length(arr_mngl)-1 do
begin
n3:=0;
for n2:=0 to length(arr_cl)-2 do
begin
if (arr_cl[n2,1] = arr_mngl[n1,7]) or (arr_cl[n2,1] = arr_mngl[n1,8]) then
begin
n3:=1;
end;
end;
if n3=0 then
begin
tema_mail:='From_ACCTRAFF';
Assign(f1,file_mail);
Rewrite(f1);
Writeln(f1,'');
Writeln(f1,' Перезапускаю iptables!');
Writeln(f1,'');
Writeln(f1,' Для лишнего клиента - '+arr_mngl[n1,7]+' '+arr_mngl[n1,8]);
Writeln(f1,'');
Writeln(f1,' Created '+formatdatetime('dd-mmmm-yyyy hh:mm', now));
Close(f1);
mail_to_root;
action;
halt;
end;
end;
end;
//------------------------------------------------------------------------------
procedure podschet;
begin
for n1:=0 to length(arr_cl)-1 do
begin
arr_cl[n1,4]:='0';
end;
for n1:=0 to length(arr_cl)-2 do
begin
for n2:=0 to length(arr_mngl)-1 do
begin
if (arr_cl[n1,1] = arr_mngl[n2,7]) or (arr_cl[n1,1] = arr_mngl[n2,8]) then
begin
arr_cl[n1,3]:=IntToStr(StrToInt64(arr_mngl[n2,1]) + StrToInt64(arr_cl[n1,3]));
arr_cl[n1,4]:=IntToStr(StrToInt64(arr_mngl[n2,1]) + StrToInt64(arr_cl[n1,4]));
end;
end;
end;
n2:=length(arr_cl)-1;
arr_cl[n2,4]:='0';
for n1:=0 to length(arr_cl)-2 do
begin
arr_cl[n2,4]:=IntToStr(StrToInt64(arr_cl[n2,4]) + StrToInt64(arr_cl[n1,4]));
end;
arr_cl[n2,3]:=IntToStr(StrToInt64(arr_cl[n2,3]) + StrToInt64(arr_cl[n2,4]));
end;
//------------------------------------------------------------------------------
procedure new_clients;
var
f1: Text;
begin
Assign(f1,file_cl);
Reset(f1);
fl_cl:=TStringList.Create;
n_cl:=0;
while not Eof(f1) do
begin
Readln(f1,tmpstr);
if tmpstr[1]='#' then
begin
fl_cl.Add(tmpstr);
end
else
begin
if n_cl=0 then
begin
for n1:=0 to length(arr_cl)-1 do
begin
tmpstr:='';
for n2:=0 to 5 do
begin
if length(arr_cl[n1,n2])<19 then
begin
pdstr:=arr_cl[n1,n2];
for n3:=0 to 19-length(arr_cl[n1,n2]) do
begin
pdstr:=pdstr+' ';
end;
tmpstr:=tmpstr+pdstr;
end;
end;
fl_cl.Add(tmpstr);
end;
end;
n_cl:=1;
end;
end;
Close(f1);
Assign(f1,file_cl);
Rewrite(f1);
for n1:=0 to fl_cl.Count-1 do
begin
Writeln(f1,fl_cl.Strings[n1]);
end;
Close(f1);
fl_cl.Free;
end;
//------------------------------------------------------------------------------
procedure proverka_data;
var
f1, f2: Text;
date_before: TDateTime;
year, month, day: word;
mesac, god, chislo, date_now: string;
begin
DecodeDate(now, Year, Month, Day);
if FormatDateTime('dd-hh:mm', now)='01-00:00' then
begin
for n1:=0 to length(arr_cl)-1 do
begin
arr_cl[n1,3]:='0';
arr_cl[n1,5]:='1';
end;
Assign(f1,file_cl);
Reset(f1);
Assign(f2,file_mail);
Rewrite(f2);
while not Eof(f1) do
begin
Readln(f1, tmpstr);
Writeln(f2,tmpstr);
end;
Close(f1);
Close(f2);
if Month-1=0 then
begin
Month:=12;
Year:=Year-1;
end;
date_before:=EncodeDate(Year,Month-1,Day);
mesac:=FormatDateTime('mmmm', date_before);
god:=FormatDateTime('yyyy', date_before);
tema_mail:='Отчет за '+mesac+' '+god+' года';
mail_to_root;
new_clients;
end;
end;
//------------------------------------------------------------------------------
procedure create_http;
var
ft1:Text;
obnovleno, podschet_nachat, s: string;
begin
obnovleno:=FormatDateTime('dd.mm.yyyy в hh ч. nn мин.',Now);
podschet_nachat:=FormatDateTime('mm.yyyy',Now);
Assign(ft1,file_http);
Rewrite(ft1);
Writeln(ft1,'<html>');
Writeln(ft1,'<head>');
Writeln(ft1,'<title>Подсчёт трафика</title>');
Writeln(ft1,'<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">');
Writeln(ft1,'<meta http-equiv="Refresh" content="60">');
Writeln(ft1,'<meta name="Reply-to" content="akmal@mxx.uz">');
Writeln(ft1,'<meta name="Author" content="Алиев Акмаль, Дмитриев Василий">');
Writeln(ft1,'<body OnLoad="window.defaultStatus='+#39+'Страница подсчёта Интернет траффика'+#39+'" text="blue" bgcolor=#C0C0C0 background="paper.jpg">');
Writeln(ft1,'<table align="center" width="750"><b>');
Writeln(ft1,'<tr valign=bottom align=center>');
Writeln(ft1,'<td width="150"><b><a href=http://www.yandex.ru><img src="yandex.gif" border=0></a></b></td>');
Writeln(ft1,'<td width="150"><b><a href=http://www.google.ru><img src="google_ru.gif" border=0></a></b></td>');
Writeln(ft1,'<td width="150"><b><a href=http://www.drweb.ru><img src="drweb.gif" border=0></a></b></td>');
Writeln(ft1,'</tr></b></table><hr>');
Writeln(ft1,'<table align=center border=1 width="750"><b><caption><font size=5>Подсчет траффика по клиентам</font></caption>');
Writeln(ft1,'<tr valign=middle align=center bgcolor="blue">');
Writeln(ft1,'<td width="150"><font color="white"><b>Пользователь</b></font></td>');
Writeln(ft1,'<td width="150"><font color="white"><b>IP адрес</b></font></td>');
Writeln(ft1,'<td width="150"><font color="white"><b>Лимит (байт)</b></font></td>');
Writeln(ft1,'<td width="150"><font color="white"><b>Использовано (байт)</b></font></td>');
Writeln(ft1,'<td width="150"><font color="white"><b>Использовано за последние 5 мин.(байт)</b></font></td></tr>');
for n1:=0 to length(arr_cl)-2 do
begin
Writeln(ft1,'<tr valign=bottom>');
Writeln(ft1,'<td width="150" align=left><b>'+arr_cl[n1,0]+'</b></td>');
Writeln(ft1,'<td width="150" align=left><b>'+arr_cl[n1,1]+'</b></td>');
s:='';
n3:=0;
for n2:=0 to length(arr_cl[n1,2])-1 do
begin
s:=copy(arr_cl[n1,2],length(arr_cl[n1,2])-n2,1)+s;
n3:=n3+1;
if n3=3 then
begin
s:=' '+s;
n3:=0;
end;
end;
Writeln(ft1,'<td width="150" align=right><b>'+s{arr_cl[n1,2]}+'</b></td>');
s:='';
n3:=0;
for n2:=0 to length(arr_cl[n1,3])-1 do
begin
s:=copy(arr_cl[n1,3],length(arr_cl[n1,3])-n2,1)+s;
n3:=n3+1;
if n3=3 then
begin
s:=' '+s;
n3:=0;
end;
end;
if arr_cl[n1,5] = '0' then
begin
Writeln(ft1,'<td width="150" align=right bgcolor="red" font color="white"><b>'+s{arr_cl[n1,3]}+'</b></td>');
end
else
begin
Writeln(ft1,'<td width="150" align=right><b>'+s{arr_cl[n1,3]}+'</b></td>');
end;
s:='';
n3:=0;
for n2:=0 to length(arr_cl[n1,4])-1 do
begin
s:=copy(arr_cl[n1,4],length(arr_cl[n1,4])-n2,1)+s;
n3:=n3+1;
if n3=3 then
begin
s:=' '+s;
n3:=0;
end;
end;
Writeln(ft1,'<td width="150" align=right><b>'+s{arr_cl[n1,4]}+'</b></td></tr>');
end;
Writeln(ft1,'<tr valign=bottom>');
Writeln(ft1,'<td colspan="3" align=left><b>Общий траффик Интернет:</b></td>');
n4:=length(arr_cl)-1;
s:='';
n3:=0;
for n2:=0 to length(arr_cl[n4,3])-1 do
begin
s:=copy(arr_cl[n4,3],length(arr_cl[n4,3])-n2,1)+s;
n3:=n3+1;
if n3=3 then
begin
s:=' '+s;
n3:=0;
end;
end;
Writeln(ft1,'<td width="150" align=right><b>'+s+'</b></td>');
s:='';
n3:=0;
for n2:=0 to length(arr_cl[n4,4])-1 do
begin
s:=copy(arr_cl[n4,4],length(arr_cl[n4,4])-n2,1)+s;
n3:=n3+1;
if n3=3 then
begin
s:=' '+s;
n3:=0;
end;
end;
Writeln(ft1,'<td width="150" align=right><b>'+s+'</b></td></tr>');
Writeln(ft1,'</b></table>');
Writeln(ft1,'<table align="center" width="750">');
Writeln(ft1,'<tr valign=bottom align=center>');
Writeln(ft1,'<td><marquee beharvior=alternate loop=infinite direction=left height=30 width="100%">');
Writeln(ft1,'<font color="red" size=5>Пользователи (выделенные красным цветом) превысившие лимит будут отключены до конца текущего месяца !</font></marquee></td>');
Writeln(ft1,'</tr></b></table><hr>');
Writeln(ft1,'<table align="center" width="750"><b>');
Writeln(ft1,'<tr valign=bottom align=center>');
Writeln(ft1,'<td><b><a href=mailto:'+adr_root+'>Письмо Администратору</a></b></td>');
Writeln(ft1,'<td><b><a href='+http_adr+'>Проверка траффика от ПРОВАЙДЕРА</a></b></td>');
Writeln(ft1,'<td><b><a href=ping.txt>Проверка связи с Провайдером</a></b></td>');
Writeln(ft1,'</tr>');
Writeln(ft1,'</b>');
Writeln(ft1,'</table>');
Writeln(ft1,'<hr>');
Writeln(ft1,'<table align="center" width="750"><b>');
Writeln(ft1,'<tr valign=bottom align=center>');
Writeln(ft1,'<td><b><H4 align=center>Последнее обнавление '+obnovleno+'</H4></b></td>');
Writeln(ft1,'<td><b><H4 align=center>Подсчет траффика начат: 01.'+podschet_nachat+'</H4></b></td>');
Writeln(ft1,'</tr>');
Writeln(ft1,'</b>');
Writeln(ft1,'</table>');
Writeln(ft1,'</body>');
Writeln(ft1,'</html>');
Close(ft1);
assign(ft1,file_act);
rewrite(ft1);
writeln(ft1,'#!/bin/bash');
writeln(ft1,'#');
writeln(ft1,'/bin/cp -f '+file_http+' /var/www/html/index.html');
writeln(ft1,' ');
close(ft1);
fpchmod(file_act,&755);
popen(ft1,file_act,'R');
pclose(ft1);
end;
//------------------------------------------------------------------------------
procedure proverka_traffica;
var
f1: Text;
begin
Assign(f1,file_test);
Rewrite(f1);
Writeln(f1,'');
Writeln(f1,'');
Writeln(f1,' Проверка прохождения ip пакетов до ip адреса '+ping_ip);
Writeln(f1,'');
Writeln(f1,' Создано '+FormatDateTime('dd-mmmm-yyyy hh:mm',now));
Writeln(f1,'');
Close(f1);
Assign(f1,file_act);
Rewrite(f1);
Writeln(f1,'#!/bin/bash');
Writeln(f1,'#');
Writeln(f1,'/bin/ping '+ping_ip+' -c 4 >> '+file_test);
Writeln(f1,' ');
Close(f1);
fpchmod(file_act,&755);
popen(f1,file_act,'R');
pclose(f1);
Assign(f1,file_act);
Rewrite(f1);
Writeln(f1,'#!/bin/bash');
Writeln(f1,'#');
Writeln(f1,'#');
Writeln(f1,'/bin/cp -f '+file_test+' /var/www/html/ping.txt');
Writeln(f1,' ');
Close(f1);
fpchmod(file_act,&755);
popen(f1,file_act,'R');
pclose(f1);
end;
//------------------------------------------------------------------------------
procedure eraze_tmp;
var
f1: Text;
begin
popen(f1,'/bin/rm -f /etc/acctraff/*.tmp','R');
pclose(f1);
end;
//------------------------------------------------------------------------------
//==============================================================================
begin
file_cl:='/etc/acctraff/clients';
file_mail:='/etc/acctraff/mail.tmp';
file_act:='/etc/acctraff/action.tmp';
file_ini:='/etc/acctraff/acctraff.ini';
file_http:='/etc/acctraff/index.html';
file_test:='/etc/acctraff/ping.tmp';
com_mngl:='/sbin/iptables -t mangle -nvxL -Z';
read_ini;
clients_exist;
read_clients;
zapusk_ipt_mngl;
fl_mngl.Free;
who_is_who;
podschet;
new_clients;
proverka_data;
create_http;
zero_arr_cl;
zero_arr_mngl;
proverka_traffica;
end.
Неужель так трудно тег вставить?