freenetis-github/application/models/subnet.php @ 4b851957
8baed187 | Michal Kliment | <?php defined('SYSPATH') or die('No direct script access.');
|
|
/*
|
|||
* This file is part of open source system FreenetIS
|
|||
* and it is release under GPLv3 licence.
|
|||
*
|
|||
* More info about licence can be found:
|
|||
* http://www.gnu.org/licenses/gpl-3.0.html
|
|||
*
|
|||
* More info about project can be found:
|
|||
* http://www.freenetis.org/
|
|||
*
|
|||
*/
|
|||
/**
|
|||
* Subnet is part of net grouped to clouds.
|
|||
*
|
|||
* @package Model
|
|||
*
|
|||
* @property integer $id
|
|||
* @property integer $OSPF_area_id
|
|||
* @property string $name
|
|||
* @property string $network_address
|
|||
* @property string $netmask
|
|||
* @property integer $redirect
|
|||
c1bdc1c4 | Michal Kliment | * @property integer $dhcp
|
|
* @property boolean $dhcp_expired
|
|||
* @property integer $dns
|
|||
8baed187 | Michal Kliment | * @property Subnets_owner_Model $subnets_owner
|
|
* @property ORM_Iterator $clouds
|
|||
* @property ORM_Iterator $ip_addresses
|
|||
* @property ORM_Iterator $allowed_subnets
|
|||
c1bdc1c4 | Michal Kliment | * @property ORM_Iterator $connection_requests
|
|
8baed187 | Michal Kliment | */
|
|
class Subnet_Model extends ORM
|
|||
{
|
|||
protected $has_one = array('subnets_owner');
|
|||
c1bdc1c4 | Michal Kliment | protected $has_many = array('ip_addresses', 'allowed_subnets', 'connection_requests');
|
|
8baed187 | Michal Kliment | protected $has_and_belongs_to_many = array('clouds');
|
|
c1bdc1c4 | Michal Kliment | /**
|
|
* Sets all subnets as (not) expired.
|
|||
*
|
|||
* @param int $flag expired (1) or not (0) [optional]
|
|||
*/
|
|||
public function set_expired_all_subnets($flag = 1)
|
|||
{
|
|||
$this->db->query("
|
|||
UPDATE subnets
|
|||
SET dhcp_expired = ?
|
|||
WHERE dhcp = 1
|
|||
", $flag);
|
|||
}
|
|||
/**
|
|||
* Sets subnets as (not) expired.
|
|||
*
|
|||
* @param array|int $subnets Multiple subnet IDs or a single subnet ID
|
|||
* @param int $flag expired (1) or not (0) [optional]
|
|||
*/
|
|||
public function set_expired_subnets($subnets, $flag = 1)
|
|||
{
|
|||
if (!is_array($subnets))
|
|||
{
|
|||
$subnets = array($subnets);
|
|||
}
|
|||
if (count($subnets))
|
|||
{
|
|||
$this->db->query("
|
|||
UPDATE subnets s
|
|||
SET s.dhcp_expired = ?
|
|||
WHERE s.dhcp > 0 AND
|
|||
s.id IN (" . implode(',', array_map('intval', $subnets)) . ")
|
|||
", $flag);
|
|||
}
|
|||
}
|
|||
/**
|
|||
* Sets subnets of device as (not) expired
|
|||
*
|
|||
* @author Michal Kliment <kliment@freenetis.org>
|
|||
* @param type $device_id ID of device
|
|||
* @param type $flag sexpired (1) or not (0) [optional]
|
|||
*/
|
|||
public function set_expired_subnets_of_device($device_id, $flag = 1)
|
|||
{
|
|||
$this->db->query("
|
|||
UPDATE subnets s
|
|||
JOIN ip_addresses ip ON ip.subnet_id = s.id AND ip.gateway = 1
|
|||
JOIN ifaces i ON ip.iface_id = i.id
|
|||
SET s.dhcp_expired = ?
|
|||
WHERE s.dhcp > 0 AND i.device_id = ?
|
|||
", array($flag, $device_id));
|
|||
}
|
|||
/**
|
|||
* Check if any of device subnet on that the device is gateway is expired
|
|||
*
|
|||
* @param int $device_id
|
|||
* @return boolean
|
|||
*/
|
|||
public function is_any_subnet_of_device_expired($device_id)
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT COUNT(*) AS c
|
|||
FROM ifaces i
|
|||
JOIN ip_addresses ip ON i.id = ip.iface_id
|
|||
JOIN subnets s ON s.id = ip.subnet_id
|
|||
WHERE i.device_id = ? AND s.dhcp > 0 AND s.dhcp_expired > 0
|
|||
AND ip.gateway > 0
|
|||
", $device_id)->current()->c > 0;
|
|||
}
|
|||
/**
|
|||
* Check if the MAC address is unique in the subnet.
|
|||
*
|
|||
* @param string $mac MAC address
|
|||
* @param int $ip_address_id Iface ID - for edit purposes
|
|||
* @param int $subnet_id Subnet id [Optional - deafult self ID]
|
|||
* @return bool
|
|||
*/
|
|||
public function is_mac_unique_in_subnet($mac, $ip_address_id = NULL, $subnet_id = NULL)
|
|||
{
|
|||
if ($subnet_id === NULL)
|
|||
{
|
|||
$subnet_id = $this->id;
|
|||
}
|
|||
$ip_address = new Ip_address_Model($ip_address_id);
|
|||
$max_count = 0;
|
|||
if ($ip_address && $ip_address->id && ($ip_address->iface->mac == $mac))
|
|||
{
|
|||
$max_count = 1;
|
|||
}
|
|||
$result = $this->db->query("
|
|||
SELECT COUNT(*) AS count
|
|||
FROM subnets s
|
|||
JOIN ip_addresses ip ON ip.subnet_id = s.id
|
|||
JOIN ifaces i ON i.id = ip.iface_id
|
|||
WHERE s.id = ? AND i.mac = ?
|
|||
", $subnet_id, $mac);
|
|||
return ($result->count() && $result->current()->count <= $max_count);
|
|||
}
|
|||
8baed187 | Michal Kliment | /**
|
|
* Gets mask and net of subnet
|
|||
*
|
|||
* @param integer $subnet_id
|
|||
* @return ORM_Iterator
|
|||
*/
|
|||
public function get_net_and_mask_of_subnet($subnet_id = NULL)
|
|||
{
|
|||
if (empty($subnet_id))
|
|||
{
|
|||
$subnet_id = $this->id;
|
|||
}
|
|||
return $this->select(
|
|||
"inet_aton(network_address) as net",
|
|||
"32-log2((~inet_aton(netmask) & 0xffffffff) + 1) as mask"
|
|||
)->where('id', $subnet_id)
|
|||
->find();
|
|||
}
|
|||
/**
|
|||
* Gets redirected ranges.
|
|||
* Any IP address belonging to these subnet ranges can be redirected.
|
|||
*
|
|||
* @see Web_interface_Controller
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_redirected_ranges()
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT DISTINCT CONCAT(
|
|||
network_address, '/',
|
|||
32-log2((~inet_aton(netmask) & 0xffffffff) + 1)
|
|||
) AS subnet_range
|
|||
FROM subnets
|
|||
WHERE redirect = 1
|
|||
ORDER BY INET_ATON(network_address)
|
|||
");
|
|||
}
|
|||
/**
|
|||
* Function counts all subnets specified by filter.
|
|||
*
|
|||
* @param array $filter_values
|
|||
* @return integer
|
|||
*/
|
|||
public function count_all_subnets($filter_sql = '')
|
|||
{
|
|||
return $this->get_all_subnets(NULL, NULL, 'id', 'asc', $filter_sql)
|
|||
->count();
|
|||
}
|
|||
/**
|
|||
* Function gets all subnets specified by filter.
|
|||
*
|
|||
* @param integer $limit_from
|
|||
* @param integer $limit_results
|
|||
* @param string $order_by
|
|||
* @param string $order_by_direction
|
|||
* @param array $filter_values
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_all_subnets($limit_from = 0, $limit_results = NULL,
|
|||
$order_by = 'id', $order_by_direction = 'ASC', $filter_sql = '')
|
|||
{
|
|||
$where = '';
|
|||
$limit = '';
|
|||
$order_by = $this->db->escape_column($order_by);
|
|||
// order by direction check
|
|||
if (strtolower($order_by_direction) != 'desc')
|
|||
{
|
|||
$order_by_direction = 'asc';
|
|||
}
|
|||
// filter
|
|||
if ($filter_sql != '')
|
|||
$where = "WHERE $filter_sql";
|
|||
// limit is set
|
|||
if ($limit_results)
|
|||
$limit = "LIMIT ".intval($limit_from) . "," . intval($limit_results);
|
|||
// query
|
|||
return $this->db->query("
|
|||
SELECT * FROM
|
|||
(
|
|||
SELECT s.id, s.id AS subnet_id, s.redirect, s.name AS subnet_name,
|
|||
CONCAT(network_address,'/', 32-log2((~inet_aton(netmask) & 0xffffffff) + 1)) AS cidr_address,
|
|||
INET_ATON(network_address) AS cidr,
|
|||
network_address, netmask,
|
|||
IFNULL(ROUND((
|
|||
SELECT COUNT(*)
|
|||
FROM ip_addresses
|
|||
c1bdc1c4 | Michal Kliment | WHERE subnet_id = s.id
|
|
8baed187 | Michal Kliment | )/((~inet_aton(s.netmask) & 0xffffffff)+1)*100,1),0) AS used,
|
|
c1bdc1c4 | Michal Kliment | m.id AS member_id, m.name AS member_name, dhcp, dns, qos
|
|
8baed187 | Michal Kliment | FROM subnets s
|
|
LEFT JOIN subnets_owners so ON s.id = so.subnet_id
|
|||
LEFT JOIN members m ON so.member_id = m.id
|
|||
) s
|
|||
$where
|
|||
ORDER BY $order_by $order_by_direction
|
|||
$limit
|
|||
");
|
|||
}
|
|||
/**
|
|||
* Gets clouds of subnet
|
|||
*
|
|||
* @param integer $subnet_id
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_clouds_of_subnet($subnet_id)
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT c.*
|
|||
FROM clouds_subnets cs
|
|||
LEFT JOIN clouds c ON c.id = cs.cloud_id
|
|||
WHERE cs.subnet_id = ?
|
|||
ORDER BY c.name
|
|||
", $subnet_id);
|
|||
}
|
|||
/**
|
|||
* Function finds subnet to which given ip address belongs to.
|
|||
*
|
|||
* @param string $ip_address
|
|||
* @return Database_Result
|
|||
*/
|
|||
public function get_subnet_of_ip_address($ip_address)
|
|||
{
|
|||
$result = $this->db->query("
|
|||
SELECT * FROM subnets
|
|||
WHERE inet_aton(netmask) & inet_aton(?) = inet_aton(network_address)
|
|||
", $ip_address);
|
|||
return ($result && $result->count()) ? $result->current() : null;
|
|||
}
|
|||
/**
|
|||
* Function tries to find subnet of user. Used in devices/add.
|
|||
*
|
|||
* @param integer $user_id
|
|||
* @return Database_Result
|
|||
*/
|
|||
public function get_subnet_of_user($user_id)
|
|||
{
|
|||
$result = $this->db->query("
|
|||
SELECT DISTINCT s.id, s.name
|
|||
FROM subnets s
|
|||
JOIN ip_addresses ip ON ip.subnet_id = s.id
|
|||
JOIN ifaces i ON i.id = ip.iface_id
|
|||
JOIN devices d ON d.id = i.device_id
|
|||
WHERE d.user_id = ?
|
|||
", $user_id);
|
|||
return ($result && $result->count()) ? $result->current() : null;
|
|||
}
|
|||
/**
|
|||
* Function gets items of subnet to export.
|
|||
*
|
|||
* @param integer $subnet_id
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_items_of_subnet($subnet_id)
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT su.id, su.name AS subnet_name, ip.ip_address,
|
|||
i.mac, l.name AS link_name, d.name AS device_name,
|
|||
IFNULL(f.translated_term, e.value) AS device_type,
|
|||
u.name AS user_name, u.surname, m.name AS member_name,
|
|||
GROUP_CONCAT(vs.variable_symbol) AS variable_symbol, m.entrance_date, st.street, ap.street_number,
|
|||
t.town, t.quarter, t.zip_code, m.comment
|
|||
FROM subnets su
|
|||
LEFT JOIN ip_addresses ip ON ip.subnet_id = su.id
|
|||
LEFT JOIN ifaces i ON i.id = ip.iface_id
|
|||
LEFT JOIN links l ON l.id = i.link_id
|
|||
LEFT JOIN devices d ON d.id = i.device_id
|
|||
LEFT JOIN enum_types e on d.type = e.id
|
|||
LEFT JOIN translations f ON lang = ? AND e.value = f.original_term
|
|||
LEFT JOIN users u ON u.id = d.user_id
|
|||
LEFT JOIN members m ON m.id = u.member_id
|
|||
LEFT JOIN address_points ap ON ap.id = m.address_point_id
|
|||
LEFT JOIN towns t ON t.id = ap.town_id
|
|||
LEFT JOIN streets st ON st.id = ap.street_id
|
|||
LEFT JOIN accounts a ON a.member_id = m.id
|
|||
LEFT JOIN variable_symbols vs ON vs.account_id = a.id
|
|||
WHERE su.id = ?
|
|||
GROUP BY ip_address
|
|||
ORDER BY inet_aton(ip_address)
|
|||
", Config::get('lang'), $subnet_id);
|
|||
}
|
|||
/**
|
|||
* Function gets all subnets of the ip prefix.
|
|||
*
|
|||
* @author Lubomir Buben
|
|||
* @param string $ip_prefix
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_subnet_of_ip_prefix($ip_prefix)
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT s.id
|
|||
FROM subnets s
|
|||
WHERE s.network_address LIKE ? COLLATE utf8_general_ci
|
|||
", "$ip_prefix%");
|
|||
}
|
|||
/**
|
|||
* Function gets phone numbers of users of subnet.
|
|||
*
|
|||
* @author Sevcik Roman
|
|||
* @param integer $subnet_id
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_phones_of_subnet($subnet_id)
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT DISTINCT (co.value)
|
|||
FROM subnets su
|
|||
LEFT JOIN ip_addresses ip ON ip.subnet_id = su.id
|
|||
LEFT JOIN ifaces i ON i.id = ip.iface_id
|
|||
LEFT JOIN devices d ON d.id = i.device_id
|
|||
LEFT JOIN users u ON u.id = d.user_id
|
|||
LEFT JOIN members m ON m.id = u.member_id
|
|||
LEFT JOIN users_contacts uc ON uc.user_id = u.id
|
|||
LEFT JOIN contacts co ON co.id = uc.contact_id
|
|||
WHERE su.id = ? AND co.type = ? AND m.id <> 1 AND m.locked <> 1;
|
|||
", array($subnet_id, Contact_Model::TYPE_PHONE));
|
|||
}
|
|||
/**
|
|||
* Returns all subnets without allowed subnets of member
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @param integer $member_id
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_all_subnets_without_allowed_subnets_of_member ($member_id)
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT
|
|||
s.id,
|
|||
CONCAT(network_address,'/', 32-log2((~inet_aton(netmask) & 0xffffffff) + 1), ': ',s.name) AS name,
|
|||
inet_aton(network_address) AS net
|
|||
FROM subnets s
|
|||
WHERE s.id NOT IN (SELECT a.subnet_id FROM allowed_subnets a WHERE a.member_id = ?)
|
|||
ORDER BY net
|
|||
", array($member_id));
|
|||
}
|
|||
/**
|
|||
* Returns subnet by ip address without member's allowed subnets
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @param integer $member_id
|
|||
* @param string $ip_address
|
|||
* @return Mysql_Result object
|
|||
*/
|
|||
public function get_subnet_without_allowed_subnets_of_member_by_ip_address($member_id, $ip_address)
|
|||
{
|
|||
$result = $this->db->query("
|
|||
SELECT *
|
|||
FROM subnets s
|
|||
WHERE inet_aton(netmask) & inet_aton(?) = inet_aton(network_address) AND
|
|||
s.id NOT IN (
|
|||
SELECT a.subnet_id
|
|||
FROM allowed_subnets a
|
|||
WHERE a.member_id = ?
|
|||
)
|
|||
", array($ip_address, $member_id));
|
|||
return ($result && $result->count()) ? $result->current() : null;
|
|||
}
|
|||
/**
|
|||
* Gets list of subnets ordered by net for dropdown
|
|||
*
|
|||
* @author Ondřej Fibich
|
|||
* @return array[string]
|
|||
*/
|
|||
public function select_list_by_net()
|
|||
{
|
|||
// get subnets
|
|||
$subnets = $this->db->query("
|
|||
SELECT id, name, network_address as net_str,
|
|||
32-log2((~inet_aton(netmask) & 0xffffffff) + 1) as mask
|
|||
FROM subnets s
|
|||
ORDER BY INET_ATON(s.network_address)
|
|||
");
|
|||
// array
|
|||
$arr_subnets = array();
|
|||
// for each subnet
|
|||
foreach ($subnets as $subnet)
|
|||
{
|
|||
$arr_subnets[$subnet->id] = $subnet->net_str.'/'. $subnet->mask.': '.$subnet->name;
|
|||
}
|
|||
// result
|
|||
return $arr_subnets;
|
|||
}
|
|||
/**
|
|||
* Checks of overlaps of subnets
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @param string $network_address
|
|||
* @param string $netmask
|
|||
* @param type $subnet_id
|
|||
* @return bool
|
|||
*/
|
|||
public function check_overlaps_of_subnets ($network_address, $netmask, $subnet_id = NULL)
|
|||
{
|
|||
$where = "";
|
|||
if ($subnet_id)
|
|||
$where = "WHERE id <> ".intval($subnet_id);
|
|||
$results = $this->db->query("
|
|||
SELECT COUNT(*) AS total FROM
|
|||
(
|
|||
SELECT
|
|||
INET_ATON(network_address) AS start,
|
|||
INET_ATON(network_address) +
|
|||
(~inet_aton(netmask) & 0xffffffff) + 1 AS end
|
|||
FROM subnets s
|
|||
$where
|
|||
) s
|
|||
WHERE
|
|||
(
|
|||
(INET_ATON(?) >= start AND INET_ATON(?) < end) OR
|
|||
(
|
|||
(INET_ATON(?)+(~INET_ATON(?) & 0xffffffff)) >= start AND
|
|||
(INET_ATON(?)+(~INET_ATON(?) & 0xffffffff)) < end
|
|||
)
|
|||
) OR
|
|||
(
|
|||
(start >= INET_ATON(?) AND start <= INET_ATON(?)+(~inet_aton(?) & 0xffffffff)) AND
|
|||
(end >= INET_ATON(?) AND end <= INET_ATON(?)+(~inet_aton(?) & 0xffffffff))
|
|||
)
|
|||
", $network_address, $network_address, $network_address,
|
|||
$netmask, $network_address, $netmask,
|
|||
$network_address, $network_address, $netmask,
|
|||
$network_address, $network_address, $netmask,
|
|||
$network_address, $network_address, $netmask);
|
|||
if ($results && $results->current())
|
|||
return (bool) $results->current()->total;
|
|||
else
|
|||
return false;
|
|||
}
|
|||
/**
|
|||
* Returns array of free IP addresses of subnet
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @return array
|
|||
*/
|
|||
public function get_free_ip_addresses()
|
|||
{
|
|||
$arr_ip_addresses = array();
|
|||
if (!$this->id)
|
|||
return $arr_ip_addresses;
|
|||
$network = ip2long($this->network_address);
|
|||
$total_available = (~ip2long($this->netmask) & 0xffffffff)-1;
|
|||
$ip_queries = array();
|
|||
c1bdc1c4 | Michal Kliment | ||
if ($total_available > 1)
|
|||
{
|
|||
for ($i = 1; $i <= $total_available; $i++)
|
|||
$ip_queries[] = "SELECT '".long2ip($network+$i)."' AS ip_address";
|
|||
}
|
|||
// for special 1-host subnet (mask /32) add only 1 IP address with network address (#507)
|
|||
else
|
|||
{
|
|||
$ip_queries[] = "SELECT '".long2ip($network)."' AS ip_address";
|
|||
}
|
|||
8baed187 | Michal Kliment | ||
if (!count($ip_queries))
|
|||
return array();
|
|||
$ip_query = implode("\nUNION\n", $ip_queries);
|
|||
$ips = $this->db->query("
|
|||
SELECT ip_address
|
|||
FROM
|
|||
(
|
|||
$ip_query
|
|||
) AS ip
|
|||
WHERE ip_address NOT IN
|
|||
(
|
|||
SELECT ip_address
|
|||
FROM ip_addresses
|
|||
WHERE subnet_id = ?
|
|||
)
|
|||
", $this->id);
|
|||
foreach ($ips as $ip)
|
|||
$arr_ip_addresses[] = $ip->ip_address;
|
|||
return $arr_ip_addresses;
|
|||
}
|
|||
/**
|
|||
* Returns all subnets with owner
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_all_subnets_with_owner ()
|
|||
{
|
|||
return $this
|
|||
->select('subnets.*','subnets_owners.member_id')
|
|||
->join('subnets_owners','subnets.id', 'subnets_owners.subnet_id')
|
|||
->where('subnets_owners.member_id IS NOT NULL')
|
|||
->find_all();
|
|||
}
|
|||
/**
|
|||
* Returns all members with at least one ip address in subnet
|
|||
* @param type $subnet_id
|
|||
* @return type
|
|||
*/
|
|||
public function get_members ($subnet_id = NULL)
|
|||
{
|
|||
if (!$subnet_id)
|
|||
$subnet_id = $this->id;
|
|||
return ORM::factory('member')->get_members_of_subnet($subnet_id);
|
|||
}
|
|||
/**
|
|||
* Returns all subnets by device
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @param type $device_id
|
|||
* @return type
|
|||
*/
|
|||
public function get_all_subnets_by_device ($device_id = NULL, $gateway = FALSE)
|
|||
{
|
|||
if (!$device_id)
|
|||
$device_id = $this->id;
|
|||
$where = '';
|
|||
if ($gateway)
|
|||
$where .= ' AND gateway = 1';
|
|||
return $this->db->query("
|
|||
SELECT
|
|||
s.*, ip.gateway,
|
|||
32-log2((~inet_aton(netmask) & 0xffffffff) + 1) AS subnet_range,
|
|||
ip.ip_address, INET_NTOA(INET_ATON(ip.ip_address)+1) AS subnet_range_start,
|
|||
INET_NTOA(INET_ATON(ip.ip_address)+(~inet_aton(netmask) & 0xffffffff)-2) AS subnet_range_end,
|
|||
c1bdc1c4 | Michal Kliment | INET_NTOA(INET_ATON(ip.ip_address)+(~inet_aton(netmask) & 0xffffffff)-1) AS broadcast,
|
|
8baed187 | Michal Kliment | i.name AS iface
|
|
FROM ip_addresses ip
|
|||
JOIN subnets s ON s.id = ip.subnet_id
|
|||
JOIN ifaces i ON i.id = ip.iface_id
|
|||
WHERE i.device_id = ? $where
|
|||
ORDER BY INET_ATON(ip_address)
|
|||
", $device_id);
|
|||
}
|
|||
/**
|
|||
* Returns all unique subnets by device
|
|||
*
|
|||
* @author David Raska
|
|||
* @param type $device_id
|
|||
* @return type
|
|||
*/
|
|||
public function get_all_unique_subnets_by_device ($device_id = NULL)
|
|||
{
|
|||
if (!$device_id)
|
|||
$device_id = $this->id;
|
|||
return $this->db->query("
|
|||
SELECT s.id
|
|||
FROM ip_addresses ip
|
|||
JOIN ifaces i ON i.id = ip.iface_id
|
|||
JOIN subnets s ON s.id = ip.subnet_id
|
|||
JOIN devices d ON d.id = i.device_id
|
|||
JOIN users u ON u.id = d.user_id
|
|||
WHERE i.device_id = ? AND s.id NOT IN
|
|||
(
|
|||
SELECT s2.id
|
|||
FROM users u2
|
|||
JOIN devices d2 ON d2.user_id = u2.id
|
|||
JOIN ifaces i2 ON i2.device_id = d2.id
|
|||
JOIN ip_addresses ip2 ON ip2.iface_id = i2.id
|
|||
JOIN subnets s2 ON s2.id = ip2.subnet_id
|
|||
WHERE d2.id <> ? AND u2.member_id = u.member_id
|
|||
)
|
|||
ORDER BY INET_ATON(ip_address)
|
|||
", $device_id, $device_id);
|
|||
}
|
|||
/**
|
|||
* Returns all dependent subnets of device
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @param type $device_id
|
|||
* @return type
|
|||
*/
|
|||
public function get_all_dependent_subnets_by_device ($device_id = NULL, $recursive = TRUE)
|
|||
{
|
|||
$subnets = array();
|
|||
$device_model = new Device_Model();
|
|||
// find all subnets of which device is gateway
|
|||
$gateway_subnets = arr::from_objects(
|
|||
$this->get_all_subnets_by_device($device_id, TRUE), 'id'
|
|||
);
|
|||
$subnets += $gateway_subnets;
|
|||
if ($recursive && count($gateway_subnets))
|
|||
{
|
|||
// finds all dependent devices of device's subnets
|
|||
$dependent_devices = $device_model
|
|||
->get_all_service_devices_of_subnets($gateway_subnets);
|
|||
foreach ($dependent_devices as $dependent_device)
|
|||
{
|
|||
// recursively find dependent subnets of dependent device
|
|||
$subnets += $this->get_all_dependent_subnets_by_device($dependent_device->id, $recursive);
|
|||
}
|
|||
}
|
|||
return $subnets;
|
|||
}
|
|||
c1bdc1c4 | Michal Kliment | /**
|
|
* Get gateway of subnet
|
|||
*
|
|||
* @author Michal Kliment <kliment@freenetis.org>
|
|||
* @param type $subnet_id
|
|||
* @return type
|
|||
*/
|
|||
public function get_gateway($subnet_id = NULL)
|
|||
{
|
|||
if (!$subnet_id && $this->id)
|
|||
$subnet_id = $this->id;
|
|||
return ORM::factory('ip_address')->get_gateway_of_subnet($subnet_id);
|
|||
}
|
|||
/**
|
|||
* Check whether subnet has gateway
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @param type $subnet_id
|
|||
* @return type
|
|||
*/
|
|||
public function has_gateway($subnet_id = NULL)
|
|||
{
|
|||
if (!$subnet_id && $this->id)
|
|||
$subnet_id = $this->id;
|
|||
$gateway = $this->get_gateway($subnet_id);
|
|||
return ($gateway && $gateway->id);
|
|||
}
|
|||
/**
|
|||
* This method is used for determining whether the user is connected
|
|||
* from registered connection. If he is the null is returned.
|
|||
* If not then subnet from which he is connected is searched.
|
|||
* If the user may obtain this IP from the searched subnet
|
|||
* the ID of subnet is returned. (but there must not be any connection
|
|||
* request on this connection already in tha database)
|
|||
*
|
|||
* @author Ondřej Fibich
|
|||
* @param string $ip_address IP address from which the connection request is made
|
|||
* @return int|null Subnet ID or null if invalid request was made
|
|||
*/
|
|||
public function get_subnet_for_connection_request($ip_address)
|
|||
{
|
|||
$result = $this->db->query("
|
|||
SELECT s.subnet_id FROM (
|
|||
SELECT s.id AS subnet_id
|
|||
FROM subnets s
|
|||
WHERE inet_aton(s.netmask) & inet_aton(?) = inet_aton(s.network_address)
|
|||
) s
|
|||
LEFT JOIN ip_addresses ip ON ip.subnet_id = s.subnet_id AND inet_aton(ip.ip_address) = inet_aton(?)
|
|||
WHERE ? NOT IN (
|
|||
SELECT cr.ip_address FROM connection_requests cr
|
|||
WHERE cr.state = ?
|
|||
)
|
|||
GROUP BY s.subnet_id
|
|||
HAVING COUNT(ip.id) = 0
|
|||
", $ip_address, $ip_address, $ip_address, Connection_request_Model::STATE_UNDECIDED);
|
|||
return ($result->count() > 0 ? $result->current()->subnet_id : NULL);
|
|||
}
|
|||
/**
|
|||
* Returns all subnets with existing gateway
|
|||
*
|
|||
* @author Michal Kliment
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_all_subnets_with_gateway()
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT s.*
|
|||
FROM subnets s
|
|||
JOIN ip_addresses ip ON ip.subnet_id = s.id AND ip.gateway = 1
|
|||
");
|
|||
}
|
|||
/**
|
|||
* Return all subnets on which DHCP is running and has no gateway.
|
|||
*
|
|||
* @return Mysql_Result
|
|||
*/
|
|||
public function get_all_dhcp_subnets_without_gateway()
|
|||
{
|
|||
return $this->db->query("
|
|||
SELECT s.*
|
|||
FROM subnets s
|
|||
WHERE s.dhcp > 0 AND s.id NOT IN (
|
|||
SELECT s2.id
|
|||
FROM subnets s2
|
|||
JOIN ip_addresses ip ON ip.subnet_id = s2.id
|
|||
AND ip.gateway = 1
|
|||
)
|
|||
");
|
|||
}
|
|||
8baed187 | Michal Kliment | }
|