<?php # Copyright(C) 2004-2007 INL # Written by Eric Leblond <regit@inl.fr> # Vincent Deffontaines <gryzor@inl.fr> # Jean Gillaux <jean@inl.fr> # Damien Boucard <damien.boucard AT inl.fr> # Victor Stinner <victor.stinner AT inl.fr> # # $Id: desc.class.php 17927 2009-02-16 13:16:09Z haypo $ # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, version 3 of the License. # # 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. # # You should have received a copy of the GNU General Public License # along with this program; if not, see <http://www.gnu.org/licenses/>. require_once('elt_set.class.php'); require_once('obj_set.class.php'); require_once('version.php'); require_once('domxml-php4-to-php5.php'); require_once('network.class.php'); class desc extends elt_set { function desc($ress, $type='xml', $id=0) { if ($type == 'xml') { $this->load_xml($ress); } else if ($type=='file') { $this->ID = $id; $this->load_file($ress); } else { $this->ID = $id; $this->clone_desc($ress); } $errmsg = $this->check_consistency(); if ($errmsg) { $errmsg = sprintf(_("%s consistency error: %s!"), $this->str(), $errmsg); throw new Exception($errmsg); } } function str() { return _('Networks definition'); } function load_xml($xml) { $this->ID = $xml->get_attribute("ID"); $this->networks = new obj_set('networks', Array(), false); foreach($xml->get_elements_by_tagname("net") as $resselt){ $selt = new network($resselt); $id = $resselt->get_attribute('ID'); if (!$id) { $id = $resselt->get_attribute('id'); } if (!array_key_exists('dftroute', $selt->datas)) { $selt->datas['dftroute'] = '0'; } $this->networks->add_elt($selt, $id); } $this->addresses = new obj_set('addresses', Array(), false); foreach($xml->get_elements_by_tagname("addr") as $resselt){ $selt = new address($resselt); $id = $resselt->get_attribute('ID'); if (!$id) { $id = $resselt->get_attribute('id'); } $this->addresses->add_elt($selt, $id); } $this->interfaces = new obj_set('interfaces'); foreach($xml->get_elements_by_tagname("interface") as $resselt){ $selt = new interf($resselt); $id = $resselt->get_attribute('ID'); if (!$id) { $id = $resselt->get_attribute('id'); } $selt->ID = $id; $this->interfaces->add_elt($selt, $id); foreach($resselt->get_elements_by_tagname("elt") as $netelt){ $elt = new elt($netelt); $eid = $netelt->get_attribute('ID'); if ((!isset($eid)) or ($eid == "")) { $eid = $netelt->get_attribute('id'); } $elt->ID = $eid; $this->interfaces->elts[$id]->add_elt($elt); } } } function load_file($filename) { global $desc_xml_version; global $edenwall_integration; $dom = domxml_open_file($filename); $root = $dom->document_element(); if (!$root) throw new Exception(_('XML syntax error.')); $version = $root->get_attribute('version'); if ($version != $desc_xml_version) { throw new Exception(sprintf( _('The version is "%s" instead of "%s"!'), $version, $desc_xml_version)); } $applied = $root->get_attribute('applied'); if ($applied == '0') throw new Exception(_("You must define and apply a network configuration (with NuConf) before you use NuFace.")); $interfaces = $root->get_elements_by_tagname("interfaces"); $interfaces = $interfaces[0]; $interface_list = $interfaces->get_elements_by_tagname("interface"); foreach ($interface_list as $myint) { $newint = new elt_set($myint); $id=$myint->get_attribute("id"); if (!isset($id) or ($id=="")) { $id=$myint->get_attribute("ID"); } $hash_int[$id] = $newint; $hash_int[$id]->ID = $id; } $this->interfaces = new obj_set('interfaces', $hash_int); $nets = $root->get_elements_by_tagname("nets"); $nets = $nets[0]; $network_list = $nets->get_elements_by_tagname("net"); $hash_net = Array(); foreach ($network_list as $mynet){ $newnet = new elt($mynet); // UGLY HACK to get the default route, if exists $connection_list = $mynet->get_elements_by_tagname("connection"); $id=$mynet->get_attribute("id"); if (!isset($id) or ($id=="")) { $id=$mynet->get_attribute("ID"); } foreach ($connection_list as $myconn) { $newconn = new connection($myconn); if (isset($newconn->datas['dftgateway'])) { $newnet->datas['dftroute'] = '1'; } else { $newnet->datas['dftroute'] = '0'; } if (isset($newconn->datas['iface'])) { $ournet = new elt($mynet); unset($ournet->datas['addr']); unset($ournet->datas['dftroute']); $ournet->datas['type'] = 'network'; if (!isset($ournet->datas{'ID'})) $ournet->datas{'ID'}=$ournet->datas{'id'}; $this->interfaces->elts[$newconn->datas['iface']]->add_elt($ournet); } } $hash_net[$id] = $newnet; // END UGLY HACK } $this->networks = new obj_set('networks', $hash_net, false); $address_list = $root->get_elements_by_tagname("address"); $hash_addr = Array(); foreach ($address_list as $myaddress){ $newaddress=new address($myaddress); $id = $myaddress->get_attribute("id"); if (!isset($id) or ($id=="")) { $id = $myaddress->get_attribute("ID"); } while (isset($hash_addr[$id])) { $id++; } $hash_addr[$id] = $newaddress; } $this->addresses = new obj_set('addresses', $hash_addr, false); } function check_consistency() { if (!$this->ID) return _('Invalid identifier'); return ''; } function clone_desc($our_desc) { $this->networks = new obj_set('networks', Array(), false); foreach($our_desc->networks->elts as $net) { $net_content['ID']=$net->datas['id'];; $net_content['type']=$net->datas['type']; $net_content['addr']=$net->datas['addr']; $net_content['name']=$net->datas['name']; $net_content['dftroute']=$net->datas['dftroute']; $new_net = new network($net_content,'data',$net->datas['id']); $this->networks->add_elt($new_net,$net->datas['id']); } $this->addresses = new obj_set('addresses', Array(), false); if ($our_desc->addresses->elts) { $i=0; foreach($our_desc->addresses->elts as $net) { $i++; $net_content['ID']=$net->datas['id'];; $net_content['addr']=$net->datas['addr']; $net_content['name']=""; $new_net = new address($net_content,'data',$i); $this->addresses->add_elt($new_net,$i); } } $this->interfaces = new obj_set('interfaces'); if ($our_desc->interfaces->elts) { foreach($our_desc->interfaces->elts as $id=>$net) { $net_content['ID']=$id; $net_content['name']=$net->name; $new_net = new interf($net_content,'data',$id); $this->interfaces->add_elt($new_net,$id); $i=0; foreach ($net->elts as $net_id=>$lnet) { $i++; $lnet_content['name']=$lnet->datas['name']; $lnet_content['ID']=$i; $lnet_content['type']='network'; $new_lnet = new elt($lnet_content,'data',$i); $this->interfaces->elts[$id]->add_elt($new_lnet,$i); } } } } function xmldump($xml, $node) { $node->set_attribute('ID',$this->ID); $descnode = $xml->create_element("networks"); $node->append_child($descnode); $descsortsobjets=$this->networks->elts; foreach($descsortsobjets as $descsortsobjet){ /*$descsortsobjet = $descsortsobjet[$used_desc];*/ $descsortsobjet->xmldump($xml,$descnode); } $descnode = $xml->create_element("addresses"); $node->append_child($descnode); $descsortsobjets=$this->addresses->elts; foreach($descsortsobjets as $descsortsobjet){ /*$descsortsobjet = $descsortsobjet[$used_desc];*/ $descsortsobjet->xmldump($xml,$descnode); } $descnode = $xml->create_element("interfaces"); $node->append_child($descnode); $descsortsobjets=$this->interfaces->elts; foreach($descsortsobjets as $descsortsobjet){ /*$descsortsobjet = $descsortsobjet[$used_desc];*/ $descsortsobjet->xmldump($xml,$descnode); } } // get network by its name function get_net_by_name($name) { foreach($this->networks->elts as $network){ $network_data = $network->datas; if ($network_data['name'] == $name){ return $network; } } return null; } } function build_new_desc($desc_to_add, &$descs) { $new = new desc($desc_to_add, 'data', $descs->new_id()); $descs->add_elt($new); $_SESSION['modified']=1; add_log(_("NuFace added the new networks definition.")); return $new; } # Find right desc in document # create it if it does not exist function find_build_desc(&$document, $create=true) { try { $desc_from_file = read_desc_file(); } catch (Exception $err) { log_exception($err); return null; } $descs = &$document->descs; $used_desc = find_used_desc($desc_from_file, $descs); if (is_null($used_desc) and $create) { $new = build_new_desc($desc_from_file, $descs); $used_desc = $new->ID; } return $used_desc; } function compare_desc_networks(&$network1,&$network2) { $match1=array(); $match2=array(); $i=0; $j=0; if (isset($network1->elts)) { foreach($network1->elts as $net_desc1) { $i++; $j=0; foreach($network2->elts as $net_desc2) { $j++; if ($net_desc1->datas['id'] == $net_desc2->datas['id']) if ($net_desc1->datas['dftroute'] == $net_desc2->datas['dftroute']) if ($net_desc1->datas['type'] == $net_desc2->datas['type']) { if (Net_IPv4::compare($net_desc1->datas['addr'], $net_desc2->datas['addr'])) { $match1[$i]=1; $match2[$j]=1; } } } } } if ($i!=$j) { return(0); } for ($ii = 1; $ii <= $i; $ii++) { if ((!isset($match1[$ii]) or ($match1[$ii]!=1))) { return(0); } } for ($ij = 1; $ij <= $j; $ij++) { if ((!isset($match2[$ij]) or ($match2[$ij]!=1))) { return(0); } } return(1); } function checkdesc($filename) { global $debug_nuface, $checkdesc_script, $desc_xml_version, $edenwall_integration; $command = "$checkdesc_script $filename --check-version=".$desc_xml_version; if ($debug_nuface) $command = "$command --debug"; $log = report_execute($command, $code); if ($code != 0 and $log) { $log = "Error your desc file ($filename):\n".$log; add_log_pre($log); if (($edenwall_integration == 0) or ($edenwall_integration == false)) { throw new Exception(sprintf(_('Please fix errors in file "%s".'), $filename)); }else{ throw new Exception(sprintf(_('Please set your network configuration in the NuConf/Networks tab.'))); } } } function read_desc_file() { global $nuface_dir, $network_desc_file; try { $filename = $nuface_dir.'/'.$network_desc_file; if (!file_exists($filename)) { throw new Exception(sprintf( _("The file describing the networks is missing (%s)!"), $filename)); } #checkdesc($filename); return new desc($filename, 'file', '1'); } catch (Exception $err) { $msg = sprintf(_('Unable to load networks definition file (%s): %s'), $filename, $err->getMessage()); throw new Exception($msg); } } function build_interfaces_array($descs, $used_desc) { $array = array(); $my_desc = $descs->elts[$used_desc]; foreach ($my_desc->interfaces->elts as $id=>$content) { $string=""; foreach ($content->elts as $intid=>$intname) { if ($string) $string .= ' - '; $string.=$intname->datas['name']; } $array[$id] = $string; } return $array; } function find_used_desc($desc_to_find,$desc_array) { if (!is_array($desc_array->elts)) return(null); foreach ($desc_array->elts as $desc_id=>$desc) { if (compare_desc_networks($desc_to_find->networks,$desc->networks)!=0) { return($desc_id); } } return null; } function hasDescFile() { global $nuface_dir, $network_desc_file; if (is_array($network_desc_file)) return true; return file_exists("$nuface_dir/$network_desc_file"); } function generateDesc() { global $nuface_dir, $network_desc_file, $gendesc_script; if (hasDescFile()) { log_error(_("The networks definition already exists!")); return; } // Generate desc.xml $filename = "$nuface_dir/$network_desc_file"; $command = "$gendesc_script -o $filename"; $stdout = report_execute($command, $exit_code); if ($exit_code!=0) { log_error(_('Error of gendesc program:')); add_log_pre($stdout); return; } add_log(sprintf(_('The networks definition (%s) has been generated correctly.'), $filename)); } ?>