
Код: Выделить всё
#!/usr/local/bin/php
<?php
#скрипт генерации правил шейперов. должен запускаться по крону
include ("/netup/wkbill/config.php");
###функции
######################################################правила для IPFW
#создание файла для ipfw
function ipfw_create_file($ipfw_commands_file) {
$file=fopen($ipfw_commands_file,"w+");
fwrite($file, "#!/bin/sh\n");
fwrite($file, "fwcmd=\"/sbin/ipfw -q\"\n");
fclose($file);
}
#создание пайпа dummynet
function ipfw_create_pipe($ipfw_commands_file,$pipe_id,$in_speed,$out_speed,$tariff_id,$tariff_name) {
$file=fopen($ipfw_commands_file,"a+");
fwrite($file,"#Tariff ID: $tariff_id Name: $tariff_name\n");
fwrite($file,"\${fwcmd} pipe $pipe_id config mask dst-ip 0xffffffff bw ".$in_speed."Kbit/s\n");
$pipe_id=$pipe_id+1000;
fwrite($file,"\${fwcmd} pipe $pipe_id config mask src-ip 0xffffffff bw ".$out_speed."Kbit/s\n");
fclose($file);
}
function ipfw_table_add($ipfw_commands_file,$ip,$pipe) {
$file=fopen($ipfw_commands_file,"a+");
fwrite($file,"\${fwcmd} table 1 add $ip $pipe\n");
$pipe=$pipe+1000;
fwrite($file,"\${fwcmd} table 2 add $ip $pipe\n");
fclose($file);
}
function ipfw_table_del($ipfw_commands_file,$ip) {
$file=fopen($ipfw_commands_file,"a+");
fwrite($file,"\${fwcmd} table 1 delete $ip\n");
fwrite($file,"\${fwcmd} table 2 delete $ip\n");
fclose($file);
}
#################################################основной скрипт
$utm5dblink = mysql_connect($utm5dbhost , $utm5dbuser, $utm5dbpass)or die ("Возникла ошибка при подключении к базе данных\n"); //подключаемся к базе
mysql_select_db($utm5dbname) or die ("Возникла ошибка при выборе базы данных\n");
#узнаем текущий час
$cur_hour=date("H:i:s");
$current_time=strtotime(now);
#создаем файл в который будем писать комманды для шейперов
ipfw_create_file($ipfw_commands_file);
#запрос на получение существующих правил для тарифов
$query = mysql_query("SELECT * FROM tariffs, wk_shaper_rules WHERE wk_shaper_rules.tariff_id = tariffs.id AND tariffs.is_deleted=0") or die("не удается получить список правил для тарифов");
$numresults = mysql_num_rows($query);
for ($i=0; $i <$numresults; $i++){
$row=mysql_fetch_array($query);
$id=$row[0]; //id пользователя
$tariff_id=iconv("cp1251", "KOI8-R", $row['tariff_id']); //ID тарифа $comment = iconv("cp1251", "UTF-8", $comment);
$tariff_name=$row['name']; //Название тарифа
$day_mode_start=$row['day_mode_start']; //начало дневного режима
$day_mode_end=$row['day_mode_end']; //конец дневного режима
$day_in_speed=$row['day_in_speed']; //входящая скорость дневного режима
$day_out_speed=$row['day_out_speed']; //исходящая скорость дневного режима
$night_mode_start=$row['night_mode_start']; //начало ночного режима
$night_mode_end=$row['night_mode_end']; //конец дневного режима
$night_in_speed=$row['night_in_speed']; //входящая скорость ночного режима
$night_out_speed=$row['night_out_speed']; //исходящая скорость ночного режима
$boost_in_speed=$row['boost_in_speed']; //входящая скорость n2o boost
$boost_out_speed=$row['boost_out_speed']; //исходящая скорость n2o boost
$night_boost_in_speed=$row['night_boost_in_speed']; //входящая скорость n2o boost ночь
$night_boost_out_speed=$row['night_boost_out_speed']; //исходящая скорость n2o boost ночь
#создаем правила шейпинга ночного режима
if ($cur_hour>=$night_mode_start AND $cur_hour<=$night_mode_end) {
ipfw_create_pipe($ipfw_commands_file,$tariff_id,$night_in_speed,$night_out_speed,$tariff_id,$tariff_name);
}
#в остальном случае создаем стандартные правила шейпинга
else {
ipfw_create_pipe($ipfw_commands_file,$tariff_id,$day_in_speed,$day_out_speed,$tariff_id,$tariff_name);
}
#если на тарифе есть услуга N2O Boost то создаем отдельные правила
if ($boost_in_speed>0 AND $boost_out_speed>0) {
$boost_id=$tariff_id+2000;
#n2o boost ночной режим
if ($cur_hour>=$night_mode_start AND $cur_hour<=$night_mode_end) {
ipfw_create_pipe($ipfw_commands_file,$boost_id,$night_boost_in_speed,$night_boost_out_speed,$tariff_id,$tariff_name);
}
#в остальном случае стандартные правила для n2o boost
else {
ipfw_create_pipe($ipfw_commands_file,$boost_id,$boost_in_speed,$boost_out_speed,$tariff_id,$tariff_name);
}
}
}
#пишем комманды на удаление/добавление правил в созданные пайпы
$query = mysql_query ("SELECT sl.account_id, INET_NTOA(ip & 4294967295) AS ip, tsl.tariff_id, ac.int_status FROM ip_groups ig, iptraffic_service_links il, service_links sl, tariffs_services_link tsl, accounts ac WHERE ig.is_deleted =0 AND il.is_deleted =0 AND sl.is_deleted =0 AND ig.ip_group_id = il.ip_group_id AND sl.id = il.id AND sl.service_id = tsl.service_id AND ac.id = sl.account_id AND ig.ip_type =1") or die("Запрос к бд на получение правил доступа не прошел");
$numresults = mysql_num_rows($query);
for ($i=0; $i <$numresults; $i++){
$row=mysql_fetch_array($query);
$tariff_id_out=0;
$id = $row[0]; //ID пользователя
$ip=$row['ip']; //IP адрес
$tariff_id=$row['tariff_id']; //ID тарифа
$tariff_id_out=$tariff_id+1000;
$int_status=$row['int_status']; //статус интернета (1 - включен 0 - выключен)
#проверяем. сменился ли тариф с предыдущего запуска или нет. если изменился то сначала удаляем старые правила
$c_query = mysql_query("SELECT id FROM wk_shaper_rules_cache WHERE ip='$ip' AND tariff_id='$tariff_id'") or die("не удалось проверить правила с предыдущего запуска");
if (mysql_num_rows($c_query)==0) {
print("У пользователя $id сменился тарифф\n");
ipfw_table_del($ipfw_commands_file,$ip);
mysql_query("DELETE FROM wk_shaper_rules_cache WHERE ip='$ip'") or die("не удается удалить старую запись из кеша");
mysql_query("INSERT INTO wk_shaper_rules_cache (ip, tariff_id) VALUES ('$ip', '$tariff_id')");
}
#если интернет включен то даем разрешающее правило
if ($int_status==1) {
#сначала проверяем услугу N2O Boost
#проверяем не требуется ли подключить услугу
$n2o_query = mysql_query ("SELECT * FROM wk_service_n2o_boost WHERE boost_start_time<=$current_time AND boost_end_time>=$current_time AND ip_addr='$ip'") or die("не удается провертить подключение услуги N2O Boost");
if (mysql_num_rows($n2o_query)!=0) {
$n2o_row=mysql_fetch_array($n2o_query);
if ($n2o_row['status']==0) {
mysql_query("UPDATE wk_service_n2o_boost SET status=1 WHERE id=$n2o_row[0]");
ipfw_table_del($ipfw_commands_file,$ip);
}
$boost_id=$tariff_id+2000;
ipfw_table_add($ipfw_commands_file,$ip,$boost_id);
}
#проверяем не требуется ли отключить услугу
$n2o_query = mysql_query("SELECT * FROM wk_service_n2o_boost WHERE boost_end_time<=$current_time AND status=1 AND ip_addr='$ip'") or die ("Запрос не прошел");
if (mysql_num_rows($n2o_query)!=0) {
$n2o_row=mysql_fetch_array($n2o_query);
if ($n2o_row['status']==1) {
mysql_query("UPDATE wk_service_n2o_boost SET status=0 WHERE id=$n2o_row[0]");
ipfw_table_del($ipfw_commands_file,$ip);
}
ipfw_table_add($ipfw_commands_file,$ip,$tariff_id);
}
#если допуслуг нету то просто разрешаем доступ в интернет
else {
ipfw_table_add($ipfw_commands_file,$ip,$tariff_id);
}
}
#если интернет выключен то даем команду на удаление из таблиц
if ($int_status==0) {
ipfw_table_del($ipfw_commands_file,$ip);
}
}
mysql_close($utm5dblink);
?>
wk_shaper_rules
Код: Выделить всё
CREATE TABLE IF NOT EXISTS `wk_shaper_rules` (
`id` int(11) NOT NULL auto_increment,
`tariff_id` int(11) NOT NULL,
`day_in_speed` int(11) NOT NULL,
`day_out_speed` int(11) NOT NULL,
`night_mode_start` time NOT NULL,
`night_mode_end` time NOT NULL,
`night_in_speed` int(11) NOT NULL,
`night_out_speed` int(11) NOT NULL,
`boost_in_speed` int(11) NOT NULL,
`boost_out_speed` int(11) NOT NULL,
`night_boost_in_speed` int(11) NOT NULL default '0',
`night_boost_out_speed` int(11) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=koi8r;
Код: Выделить всё
CREATE TABLE IF NOT EXISTS `wk_service_n2o_boost` (
`id` int(11) NOT NULL auto_increment,
`account_id` int(11) NOT NULL,
`boost_id` int(11) NOT NULL,
`boost_start_time` int(11) NOT NULL,
`boost_end_time` int(11) NOT NULL,
`tariff_id` int(11) NOT NULL,
`status` int(11) NOT NULL default '0',
`ip_addr` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=koi8r;
Код: Выделить всё
CREATE TABLE IF NOT EXISTS `wk_shaper_rules_cache` (
`id` int(11) NOT NULL auto_increment,
`ip` varchar(255) NOT NULL,
`tariff_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=koi8r;
Код: Выделить всё
#Правила шейпера
*/5 * * * * /netup/wkbill/shaper_rules.php 2>&1
Код: Выделить всё
#!/bin/sh
#скрипт для скачивания правил шейпирования с маршрутизатора и их применения
ftp_login="xxxxx"
ftp_passw="xxxx"
/usr/bin/fetch -o /usr/local/wkt_scripts/ipfw_commands ftp://$ftp_login:$ftp_passw@195.93.xxx.xxx/ipfw_commands
/bin/sh /usr/local/wkt_scripts/ipfw_commands


собстно скриншот управления правилами
