AlternC/upnp/m_upnp.php

174 lines
5.8 KiB
PHP

<?php
/*
----------------------------------------------------------------------
AlternC - Web Hosting System
Copyright (C) 2000-2012 by the AlternC Development Team.
https://alternc.org/
----------------------------------------------------------------------
LICENSE
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License (GPL)
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.
To read the license please visit http://www.gnu.org/copyleft/gpl.html
----------------------------------------------------------------------
Purpose of file: Manage UPnP ports forwarding from router
----------------------------------------------------------------------
*/
/**
* This class handle UPnP forwarding from a IGD/UPnP compliant router
* you need this only when you are behind a IGD-compliant router
* each class may exports a hook that defined named port/protocol to
* forward to the local IP address of the server.
* this class manage the upnp table
* and its configuration from admin control panel
*/
class m_upnp {
/* ----------------------------------------------------------------- */
/** get the list of current upnp forwards and their status
* @return array the attributes of all port-forwards
*/
function get_forward_list() {
global $db,$err;
$err->log("upnp","get_forward_list");
$db->query("SELECT * FROM upnp");
$res=array();
while ($db->next_record()) {
$res[]=$db->Record;
}
return $res;
}
/* ----------------------------------------------------------------- */
/** enable a upnp port in the upnp table
* @param integer the id of the port to enable
* @return boolean TRUE if the port has been properly forwarded
* FALSE if an error occurred
*/
function enable_port($id) {
global $db,$err;
$id=intval($id);
$err->log("upnp","enable_port($id)");
$db->query("SELECT enabled FROM upnp WHERE id=$id;");
if (!$db->next_record()) {
$err->raise("upnp",_("The required port is not currently defined"));
return false;
}
if (!$db->f("enabled")) {
$db->query("UPDATE upnp SET enabled=1 WHERE id=$id;");
$err->raise("upnp",_("The specified upnp port is now enabled"));
return true;
}
$err->raise("upnp",_("The specified upnp port is already enabled"));
return true;
}
/* ----------------------------------------------------------------- */
/** disable a upnp port in the upnp table
* @param integer the id of the port to disable
* @return boolean TRUE if the port has been properly forwarded
* FALSE if an error occurred
*/
function disable_port($id) {
global $db,$err;
$id=intval($id);
$err->log("upnp","disable_port($id)");
$db->query("SELECT enabled,mandatory FROM upnp WHERE id=$id;");
if (!$db->next_record()) {
$err->raise("upnp",_("The required port is not currently defined"));
return false;
}
if ($db->f("mandatory")) {
$err->raise("upnp",_("You can't disable that mandatory port forward"));
return false;
}
if ($db->f("enabled")) {
$db->query("UPDATE upnp SET enabled=0 WHERE id=$id;");
$err->raise("upnp",_("The specified upnp port is now disabled"));
return true;
}
$err->raise("upnp",_("The specified upnp port is already disabled"));
return true;
}
/* ----------------------------------------------------------------- */
/** cron launched every minute to check the status of UPnP forwarding
*/
function cron() {
global $hooks;
// if we check anything less than 5 minutes ago, or if the upnp table is empty, let's make a check...
$db->query("SELECT UNIX_TIMESTAMP(lastcheck) AS lc, * FROM upnp ORDER BY lastcheck ASC;");
$forwards=array();
$bigcheck=false;
if (!$db->next_record()) {
$bigcheck=true;
} else {
if ($db->f("lc")+600<time()) {
$bigcheck=true;
}
do {
$db->Record["found"]=false;
$forwards[]=$db->Record;
} while ($db->next_record());
}
if ($bigcheck) {
// Do the check first by calling the hooks & comparing the arrays
$res=$hooks->invoke("hooks_upnp_list");
foreach($res as $c=>$tmp) {
foreach($tmp as $name=>$v) {
// We compare the hook array with the forwards array
$found=false;
for($i=0;$i<count($forwards);$i++) {
if ($forwards[$i]["class"]==$c &&
$forwards[$i]["name"]==$name &&
$forwards[$i]["protocol"]==$v["protocol"] &&
$forwards[$i]["port"]==$v["port"] &&
$forwards[$i]["mandatory"]==$v["mandatory"]) {
// Found it and unchanged
$forwards[$i]["found"]=true;
$found=true;
}
} // compare with forwards class.
if (!$found) {
// Mark it for creation
$db->query("INSERT INTO upnp SET mandatory='".addslashes($v["mandatory"])."', protocol='".addslashes($v["protocol"])."', port='".addslashes($v["port"])."', name='".addslashes($name)."', action='CREATE'");
$id=$db->last_id();
$forwards[]=array("id"=>$id, "mandatory" => intval($v["mandatory"]), "protocol" => $v["protocol"], "port" => intval($v["port"]), "name" => $name, "action" => "CREATE");
}
} // for each port forward in that class
} // for each hooked class
// We search the "not found" and remove them from the array
for($i=0;$i<count($forwards);$i++) {
if (!$forwards[$i]["found"]) {
$forwards[$i]["action"]="DELETING";
$db->query("UPDATE upnp SET action='DELETING' WHERE id=".$forwards[$i]["id"].";");
}
}
} // bigcheck ?
}
} /* Class UPnP */