diff --git a/business/itop.business.class.inc.php b/business/itop.business.class.inc.php
index 90133dc4c..dca260fc0 100644
--- a/business/itop.business.class.inc.php
+++ b/business/itop.business.class.inc.php
@@ -980,6 +980,89 @@ class lnkInterfaces extends cmdbAbstractObject
}
}
+////////////////////////////////////////////////////////////////////////////////////
+/**
+* A subnet
+*/
+////////////////////////////////////////////////////////////////////////////////////
+class bizSubnet extends logInfra
+{
+ public static function Init()
+ {
+ $aParams = array
+ (
+ "category" => "bizmodel,searchable",
+ "name" => "Subnet",
+ "description" => "Logical or physical subnet",
+ "key_type" => "",
+ "key_label" => "id",
+ "name_attcode" => "name",
+ "state_attcode" => "",
+ "reconc_keys" => array("org_name", "name"), // inherited attributes
+ "db_table" => "subnets",
+ "db_key_field" => "id",
+ "db_finalclass_field" => "",
+ "display_template" => "",
+ );
+ MetaModel::Init_Params($aParams);
+ MetaModel::Init_InheritAttributes();
+ MetaModel::Init_AddAttribute(new AttributeString("ip", array("label"=>"IP", "description"=>"IP", "allowed_values"=>null, "sql"=>"ip", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+ MetaModel::Init_AddAttribute(new AttributeString("mask", array("label"=>"IP mask", "description"=>"IP mask", "allowed_values"=>null, "sql"=>"mask", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array())));
+
+ MetaModel::Init_InheritFilters();
+ MetaModel::Init_AddFilterFromAttribute("ip");
+ MetaModel::Init_AddFilterFromAttribute("mask");
+
+ // Display lists
+ MetaModel::Init_SetZListItems('details', array('name', 'ip','mask')); // Attributes to be displayed for the complete details
+ MetaModel::Init_SetZListItems('list', array('name', 'ip', 'mask')); // Attributes to be displayed for a list
+ // Search criteria
+ MetaModel::Init_SetZListItems('standard_search', array('name', 'ip','mask')); // Criteria of the std search form
+ MetaModel::Init_SetZListItems('advanced_search', array('name', 'ip','mask')); // Criteria of the advanced search form
+ }
+
+ function DisplayBareRelations(web_page $oPage)
+ {
+ parent::DisplayBareRelations($oPage);
+
+ $oPage->SetCurrentTabContainer('Related Objects');
+
+ $oPage->SetCurrentTab('IP Usage');
+
+ $bit_ip = ip2long($this->Get('ip'));
+ $bit_mask = ip2long($this->Get('mask'));
+ $sIPMin = long2ip($bit_ip & $bit_mask);
+ $sIPMax = long2ip(($bit_ip | (~$bit_mask)) - 1);
+
+ $oPage->p("Interfaces having an IP in the range: $sIPMin to $sIPMax");
+
+ $oIfSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT bizInterface AS if WHERE INET_ATON(if.ip_address) >= INET_ATON('$sIPMin') AND INET_ATON(if.ip_address) <= INET_ATON('$sIPMax')"));
+ self::DisplaySet($oPage, $oIfSet);
+
+ $iCountUsed = $oIfSet->Count();
+ $iCountRange = ip2long($sIPMax) - ip2long($sIPMin);
+ $iFreeCount = $iCountRange - $iCountUsed;
+
+ $oPage->SetCurrentTab('Free IPs');
+ $oPage->p("Free IPs: $iFreeCount");
+ $oPage->p("Here is an extract of 10 free IP addresses");
+
+ $aUsedIPs = $oIfSet->GetColumnAsArray('ip_address', false);
+ $i = 0;
+ while ($i < min($iFreeCount, 10))
+ {
+ $i++;
+
+ $iAnIP = ip2long($sIPMin) + $i;
+ if (in_array($iAnIP, $aUsedIPs)) continue;
+
+ $sAnIP = long2ip($iAnIP);
+ $oPage->p($sAnIP);
+ }
+
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////////
/**
* Any electronic device
diff --git a/setup/data/21.subnets.xml b/setup/data/21.subnets.xml
new file mode 100644
index 000000000..91ef1eb0d
--- /dev/null
+++ b/setup/data/21.subnets.xml
@@ -0,0 +1,11 @@
+
+
+
+3
+my subnet
+implementation
+low
+10.22.0.0
+255.255.0.0
+
+
diff --git a/setup/data/export.cmd b/setup/data/export.cmd
index 16ad1a8e5..4a2b0fc96 100644
--- a/setup/data/export.cmd
+++ b/setup/data/export.cmd
@@ -26,3 +26,4 @@ wget --output-document=17.contactchangetickets.xml --post-data="auth_user=%USER%
wget --output-document=18.contracts.xml --post-data="auth_user=%USER%&auth_pwd=%PWD%&operation=login" "%EXPORT%?expression=SELECT bizContract&format=xml"
wget --output-document=19.infracontracts.xml --post-data="auth_user=%USER%&auth_pwd=%PWD%&operation=login" "%EXPORT%?expression=SELECT lnkInfraContract&format=xml"
wget --output-document=20.contactcontracts.xml --post-data="auth_user=%USER%&auth_pwd=%PWD%&operation=login" "%EXPORT%?expression=SELECT lnkContactContract&format=xml"
+wget --output-document=21.subnets.xml --post-data="auth_user=%USER%&auth_pwd=%PWD%&operation=login" "%EXPORT%?expression=SELECT bizSubnet&format=xml"
diff --git a/setup/data/structure/1.menus.xml b/setup/data/structure/1.menus.xml
index 52f549231..4b7198209 100644
--- a/setup/data/structure/1.menus.xml
+++ b/setup/data/structure/1.menus.xml
@@ -155,7 +155,26 @@
<p></p>
<p style="text-align:center; font-family:Georgia, 'Times New Roman', Times, serif; font-size:24px;">All Servers</p>
<p></p>
-<itopblock BlockClass="DisplayBlock" objectclass="bizContact" type="list" asynchronous="false" encoding="text/sibusql">bizServer</itopblock>
+<itopblock BlockClass="DisplayBlock" objectclass="bizServer" type="list" asynchronous="false" encoding="text/sibusql">bizServer</itopblock>
+</div>
+
+application
+999
+14
+0
+
+
+All Subnets
+
+UI.php
+
+<itopblock BlockClass="DisplayBlock" objectclass="bizSubnet" type="search" asynchronous="false" encoding="text/sibusql">bizSubnet</itopblock>
+<div id="BottomPane">
+<p></p>
+<p></p>
+<p style="text-align:center; font-family:Georgia, 'Times New Roman', Times, serif; font-size:24px;">All Subnets</p>
+<p></p>
+<itopblock BlockClass="DisplayBlock" objectclass="bizSubnet" type="list" asynchronous="false" encoding="text/sibusql">bizSubnet</itopblock>
</div>
application