pf-tools commit: r772 [ccaillet-guest] - in /branches/next-gen: debian/changelog doc/hostfile-syntax doc/networkfile-syntax lib/PFTools/Conf.pm lib/PFTools/Net.pm

parmelan-guest at users.alioth.debian.org parmelan-guest at users.alioth.debian.org
Mon Jul 19 14:54:38 UTC 2010


Author: ccaillet-guest
Date: Mon Jul 19 14:54:37 2010
New Revision: 772

URL: http://svn.debian.org/wsvn/pf-tools/?sc=1&rev=772
Log:
Partial commit for backup all mods but need to implement scope feature when creating zones

Modified:
    branches/next-gen/debian/changelog
    branches/next-gen/doc/hostfile-syntax
    branches/next-gen/doc/networkfile-syntax
    branches/next-gen/lib/PFTools/Conf.pm
    branches/next-gen/lib/PFTools/Net.pm

Modified: branches/next-gen/debian/changelog
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/debian/changelog?rev=772&op=diff
==============================================================================
--- branches/next-gen/debian/changelog (original)
+++ branches/next-gen/debian/changelog Mon Jul 19 14:54:37 2010
@@ -1,4 +1,4 @@
-pf-tools (0.99.0-0) lucid; urgency=low
+pf-tools (0.99.0-0) unstable; urgency=low
 
   [Christophe Caillet]
   * doc/hostfile-syntax : adding file describing the new grammar for host
@@ -16,6 +16,7 @@
     - using PFTools::Parser and PFTools::Logger
     - adding __Translate_old2new_host for translating Parser_pftools result hash to
     hash Parser_ini hash result with new syntax file
+    - Init_GLOBAL_NETCONFIG : similar to old function Init_lib_net
   * lib/PFTools/Parser.pm
     - introducing this package from splitting Conf.pm function with old parser
     - adding parsing with ini standard parser based on Config::IniFiles
@@ -27,18 +28,19 @@
   * lib/PFTools/Net.pm
     - using new packages Parser.pm et Logger.pm
     - adding entries in new global structure build the DNS zone for sites
-    - __Add_zone : adding zone into the new global structure
-    - __Add_site : adding sites into the new global structure
-    - __Add_network : adding network into the new global structure
-    - __Check_host_interfaces : checking interfaces for host definition
-    
+    - Add_zone : adding zone into the new global structure
+    - Add_site : adding sites into the new global structure
+    - Add_network : adding network into the new global structure
+    - Check_host_interfaces : checking interfaces for host definition
+    - Add_server : adding server (hosts defined into pf-tools only for IPs
+    and name accessing by filters)
+    - Add_host : adding pf-tools host configuration
   * lib/PFTools/Packages.pm
     - using new packages Parser.pm et Logger.pm
   * lib/PFTools/Update.pm
     - using new packages Parser.pm et Logger.pm
-  * 
-
- -- Christophe Caillet <tof at sitadelle.com>  Thu, 08 Jul 2010 17:27:37 +0200
+
+ -- Christophe Caillet <quadchris at free.fr>  Mon, 19 Jul 2010 16:47:59 +0200
 
 pf-tools (0.34.0-0WIP) unstable; urgency=low
 

Modified: branches/next-gen/doc/hostfile-syntax
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/doc/hostfile-syntax?rev=772&op=diff
==============================================================================
--- branches/next-gen/doc/hostfile-syntax (original)
+++ branches/next-gen/doc/hostfile-syntax Mon Jul 19 14:54:37 2010
@@ -1,6 +1,6 @@
 [interface::ethX]
 	? mac[.%HOSTNUM%]				::= <MAC_ADDR> WARNING this directive MUST BE defined for interface which is used for deployment
-	! vlan[.%HOSTNUM%]				::= <VLAN_NAME> as defined in network configurations part in PF-TOOLS
+	! vlan[.%HOSTNUM%]				::= <NETWORK_NAME> as defined in network configurations part in PF-TOOLS
 	! ipv4[.%HOSTNUM%]				::= <IPV4_ADDR> if default is used then act as old ipstart directive
 	? ipv6[.%HOSTNUM%]				::= <IPV6_ADDR> if default is used then act as old ipstart directive
 	? iface_opt[.%HOSTNUM%]			::= <IFACE_OPT> define here iface options (ip link syntax)
@@ -8,7 +8,7 @@
 	? @route6[.default|%HOSTNUM%]	::= <SUBNET>/<NETMASK> [via <GATEWAY>] (ip route syntax)
 
 [interface::ethX.TAGY]
-	! vlan[.%HOSTNUM%]		::= <VLAN_NAME> as defined in network configurations part in PF-TOOLS
+	! vlan[.%HOSTNUM%]		::= <NETWORK_NAME> as defined in network configurations part in PF-TOOLS
 	! ipv4[.%HOSTNUM%]		::= <IPV4_ADDR> if default is used then act as old ipstart directive
 	? ipv6[.%HOSTNUM%]		::= <IPV6_ADDR> if default is used then act as old ipstart directive
 	? iface_opt[%HOSTNUM%]	::= <IFACE_OPT> define here iface options (ip link syntax)
@@ -19,7 +19,7 @@
 	! slaves[.%HOSTNUM%]	::= <IFACE>,<IFACE>,... abort parsing if one <IFACE> is defined into [interface::<IFACE>] section
 	? mode[.%HOSTNUM%]		::= active-backup|802.3ad ... see kernel Docs for different modes default value is active-backup
 	? options[.%HOSTNUM%]	::= see kernel docs for misc options like xmit_hash_policy (space separated list)
-	! vlan[.%HOSTNUM%]		::= <VLAN_NAME> as defined in network configurations part in PF-TOOLS
+	! vlan[.%HOSTNUM%]		::= <NETWORK_NAME> as defined in network configurations part in PF-TOOLS
 	! ipv4[.%HOSTNUM%]		::= <IPV4_ADDR> if default is used then act as old ipstart directive
 	? ipv6[.%HOSTNUM%]		::= <IPV6_ADDR> if default is used then act as old ipstart directive
 	? iface_opt[.%HOSTNUM%]	::= <IFACE_OPT> define here iface options (ip link syntax)
@@ -27,7 +27,7 @@
 	? @route6[.%HOSTNUM%]	::= <SUBNET>/<NETMASK> [via <GATEWAY>] (ip route syntax)
 
 [interface::bondX.TAGY]
-	! vlan[.%HOSTNUM%]		::= <VLAN_NAME> as defined in network configurations part in PF-TOOLS
+	! vlan[.%HOSTNUM%]		::= <NETWORK_NAME> as defined in network configurations part in PF-TOOLS
 	! ipv4[.%HOSTNUM%]		::= <IPV4_ADDR> if default is used then act as old ipstart directive
 	? ipv6[.%HOSTNUM%]		::= <IPV6_ADDR> if default is used then act as old ipstart directive
 	? iface_opt[.%HOSTNUM%]	::= <IFACE_OPT> define here iface options (ip link syntax)
@@ -39,7 +39,7 @@
 	! mode[.%HOSTNUM%]		::= debian|ubuntu|kickstart
 	! arch[.%HOSTNUM%]		::= i386|amd64
 	! distrib[.%HOSTNUM%]	::= <DISTRIB_NAME>
-	? dhcpvlan[.%HOSTNUM%]	::= <VLAN_NAME>
+	? dhcpvlan[.%HOSTNUM%]	::= <NETWORK_NAME>
 
 [hostgroup]
 	! site		::= <SITE_NAME>
@@ -62,13 +62,13 @@
 
 [dns]
 	! resolver[.%HOSTNUM%]		::= <IPV4_ADDR|IPV6_ADDR|HOSTNAME>[,<IPV4_ADDR|IPV6_ADDR|HOSTNAME>] : HOSTNAME as defined in PF-TOOLS configurations
-	? shortname[.%HOSTNUM%]		::= <VLAN_NAME> as defined in network configurations part in PF-TOOLS, if not defined use the vlan value defined in dhcpvlan from private-network
-	? alias.<name>[.%HOSTNUM%]	::= <VLAN_NAME> as defined in network configurations part in PF-TOOLS now if %HOSTNUM% is used then we have an alias for each host in hostgroup
+	? shortname[.%HOSTNUM%]		::= <NETWORK_NAME> as defined in network configurations part in PF-TOOLS, if not defined use the vlan value defined in dhcpvlan from private-network
+	? alias.<name>[.%HOSTNUM%]	::= <NETWORK_NAME> as defined in network configurations part in PF-TOOLS now if %HOSTNUM% is used then we have an alias for each host in hostgroup
 
 ##### NEED TO BE IMPLEMENTED
 [monitoring]
 	! type[.default|%HOSTNUM%]		::= nagios
-	! interface[.default|%HOSTNUM%]	::= <VLAN_NAME> as defined in network configurations part in PF-TOOLS
+	! interface[.default|%HOSTNUM%]	::= <NETWORK_NAME> as defined in network configurations part in PF-TOOLS
 	! @system[.default|%HOSTNUM%]	::= <CHECK_COMMAND> as defined in NAGIOS configurations
 	! @service[.default|%HOSTNUM%]	::= <CHECK_COMMAND> as defined in NAGIOS configurations
 #####

Modified: branches/next-gen/doc/networkfile-syntax
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/doc/networkfile-syntax?rev=772&op=diff
==============================================================================
--- branches/next-gen/doc/networkfile-syntax (original)
+++ branches/next-gen/doc/networkfile-syntax Mon Jul 19 14:54:37 2010
@@ -21,8 +21,8 @@
 	? room		::= <STR>
 	? alias		::= [a-z]{3}\d
 	? confdir	::= <PATH> define here the directory for configuration access refined by Get_source
-	! dhcpvlan	::= <VLAN_NAME>
-	? console	::= (default|ttyS0,115200n8)
+	! dhcpvlan	::= <NETWORK_NAME>
+	! console	::= (default|ttyS0,115200n8)
 
 [<NETWORK_NAME>]
 	! type		::= network
@@ -36,10 +36,22 @@
 	! scope		::= private|public, if private is defined this network will be ONLY added on zone private for site
 	? gateway	::= <IPV4>
 
+[<SERVER_NAME>]
+	! type							::= server
+	? comment						::= <STR>
+	! site							::= <STR>
+	! number						::= <INT>
+	? nodes							::= <INT>
+	! ipv4.<VLAN_NAME>[.%HOSTNUM%]	::= <IPV4>
+	? ipv6.<VLAN_NAME>[.%HOSTNUM%]	::= <IPV6>
+	? alias.<NAME>[.%HOSTNUM%]		::= <NETWORK_NAME>
+	? shortname[.%HOSTNUM%]			::= <NETWORK_NAME>
+
 [<FILENAME>]
 	! type		::= include
 
 [<SERVICE_NAME>]
 	! type		::= service
 	? comment	::= <STR>
+	! site		::= <STR>
 	! @hosts	::= <STR> add here the hostfile name one per hostgroup

Modified: branches/next-gen/lib/PFTools/Conf.pm
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/lib/PFTools/Conf.pm?rev=772&op=diff
==============================================================================
--- branches/next-gen/lib/PFTools/Conf.pm (original)
+++ branches/next-gen/lib/PFTools/Conf.pm Mon Jul 19 14:54:37 2010
@@ -26,6 +26,7 @@
 use warnings;
 
 use Exporter;
+use PFTools::Net;
 use PFTools::Parser;
 use PFTools::Logger;
 use Data::Dumper;
@@ -36,6 +37,7 @@
 	%SUBST
 	$PF_STATUS_DIR
 	$PFTOOLSCONF
+	$PF_CONFIG
 	$CVS_WORKING_DIR
 	$CVS_TMP_DIR
 	$CVS_OLD_DIR
@@ -51,6 +53,8 @@
 	$CVS_BRANCHE
 
 	Init_SUBST
+	Init_PF_CONFIG
+	Init_GLOBAL_NETCONFIG
 	__Translate_old2new_host
 	Load_conf
 );
@@ -158,7 +162,7 @@
 	'@mx'				=> '\d+\s+[\w\-\.]+',
 };
 $DEF_SECTIONS->{'network'}->{'site'} = {
-	'MANDATORY_KEYS'	=> [ 'state', 'zone', 'dhcpvlan' ],
+	'MANDATORY_KEYS'	=> [ 'state', 'zone', 'dhcpvlan', 'console' ],
 	'comment'			=> 'undefined',
 	'location'			=> 'undefined',
 	'room'				=> 'undefined',
@@ -184,9 +188,19 @@
 	'gateway6'			=> 'undefined'
 };
 $DEF_SECTIONS->{'network'}->{'service'} = {
-	'MANDATORY_KEYS'	=> [ '@host' ],
+	'MANDATORY_KEYS'	=> [ 'site','@host' ],
 	'comment'			=> 'undefined',
-	'@host'				=> '\w+'
+	'@host'				=> '[\w\-]+'
+};
+$DEF_SECTIONS->{'network'}->{'server'} = {
+	'MANDATORY_KEYS'	=> [ 'site', 'number', ],
+	'comment'			=> 'undefined',
+	'site'				=> '(ALL|[\w\-]+(\s*,\s*[\w\-]+)*)',
+	'number'			=> '\d+',
+	'ipv4'				=> '([\d]{1,3})((\.[\d]{1,3}){1,3})?',
+	'ipv6'				=> 'undefined',
+	'alias'				=> '[a-z][a-z0-9\-]+[a-z0-9]',
+	'shortname'			=> '[a-z][a-z0-9\-]+[a-z0-9]'
 };
 $DEF_SECTIONS->{'config'}->{'addfile'} = {
 	'MANDATORY_KEYS'	=> [ 'source' ],
@@ -253,6 +267,12 @@
 our $PF_CONFIG	= {};
 $PF_CONFIG->{'path'} = {
 	'status_dir'	=> '/var/lib/pftools',
+	'distrib_dir'	=> '/distrib',
+	'tftp_dir'		=> '/distrib/tftpboot'
+};
+$PF_CONFIG->{'features'} = {
+	'ipv4'			=> 1,
+	'ipv6'			=> 0
 };
 $PF_CONFIG->{'vcs'} = {
 	'type'		=> 'cvs',
@@ -263,6 +283,10 @@
 	'module'	=> 'config',
 	'command'	=> '',
 	'branche'	=> ''
+};
+$PF_CONFIG->{'regex'} = {
+	'hostname'	=> $HOST_CONFIG_REGEX,
+	'hosttype'	=> $HOSTTYPE_CONFIG_REGEX
 };
 
 sub Init_PF_CONFIG ($;$) {
@@ -761,6 +785,71 @@
 	return $parsed;
 }
 
+### Like old Init_lib_net
+sub Init_GLOBAL_NETCONFIG ($$;$) {
+	my ( $start_file, $hash_subst, $pf_config ) = @_;
+
+	if ( ! defined $pf_config ) {
+		$pf_config = $PF_CONFIG;
+	}
+
+	my $GLOBAL = {
+		'SITE'		=> {
+			'BY_NAME'	=> {},
+		}
+	};
+	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+		next if ( ! $pf_config->{'features'}->{$ip_type} );
+		my $zone_key = ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+		my $dhcp_key = ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
+		$GLOBAL->{$zone_key} = {
+			'BY_NAME'	=> {},
+			'BY_SITE'	=> {}
+		};
+		$GLOBAL->{$dhcp_key} = {
+			'BY_SITE'	=> {}
+		};
+	}
+
+	my $net_parsed = Load_conf ( $start_file, $hash_subst, 'network', 'nx' );
+	foreach my $section ( @{$net_parsed->{'__sections_order'}} ) {
+		if ( $net_parsed->{$section}->{'type'} eq 'zone' ) {
+			Add_zone ( $start_file, $section, $net_parsed->{$section}, $GLOBAL, $pf_config );
+		}
+	}
+	foreach my $section ( @{$net_parsed->{'__sections_order'}} ) {
+		if ( $net_parsed->{$section}->{'type'} eq 'site' ) {
+			Add_site ( $start_file, $section, $net_parsed->{$section}, $GLOBAL, $pf_config );
+		}
+	}
+	foreach my $section ( @{$net_parsed->{'__sections_order'}} ) {
+		if ( $net_parsed->{$section}->{'type'} eq 'network' ) {
+			Add_network ( $start_file, $section, $net_parsed->{$section}, $GLOBAL, $pf_config );
+		}
+	}
+	foreach my $section ( @{$net_parsed->{'__sections_order'}} ) {
+		if ( $net_parsed->{$section}->{'type'} eq 'server' ) {
+			Add_server ( $start_file, $section, $net_parsed->{$section}, $GLOBAL, $pf_config );
+		}
+	}
+	foreach my $section ( @{$net_parsed->{'__sections_order'}} ) {
+		if ( $net_parsed->{$section}->{'type'} eq 'service' ) {
+			my $site_list = Get_site_list ( $net_parsed->{$section}, $GLOBAL );
+			foreach my $site ( @{$site_list} ) {
+				my $service_part = $GLOBAL->{'SITE'}->{'BY_NAME'}->{$site}->{'SERVICE'}->{'BY_NAME'};
+				foreach my $host ( @{$net_parsed->{$section}->{'@host'}} ) {
+					my $hostfile	= Get_source ( $host );
+					my $host_parsed	= Load_conf ( $hostfile, $hash_subst, 'host', 'nx' );
+					Add_host ( $hostfile, $host_parsed, $GLOBAL, $pf_config );
+					push ( @{$service_part->{$section}}, $host );
+				}
+				
+			}
+		}
+	}
+	return $GLOBAL;
+}
+
 # Print_conf
 sub Print_conf {
     my ($C) = @_;

Modified: branches/next-gen/lib/PFTools/Net.pm
URL: http://svn.debian.org/wsvn/pf-tools/branches/next-gen/lib/PFTools/Net.pm?rev=772&op=diff
==============================================================================
--- branches/next-gen/lib/PFTools/Net.pm (original)
+++ branches/next-gen/lib/PFTools/Net.pm Mon Jul 19 14:54:37 2010
@@ -30,7 +30,6 @@
 our @ISA = ('Exporter');
 
 our @EXPORT = qw(
-
     Init_lib_net
 
     Get_Active_Filename
@@ -55,10 +54,12 @@
     cmpif
     Host_class
     
-    __Add_network
-    __Add_site
-    __Add_zone
-    __Check_host_interfaces
+    Add_network
+    Add_site
+    Add_zone
+    Add_server
+    Add_host
+    Get_site_list
 );
 
 our @EXPORT_OK = qw();
@@ -66,7 +67,7 @@
 use Fcntl ':mode';
 use POSIX qw(ceil floor);
 
-use PFTools::Conf;
+# use PFTools::Conf;
 use PFTools::Logger;
 use PFTools::Parser;
 use NetAddr::IP;
@@ -74,6 +75,39 @@
 use Data::Dumper;
 #$Data::Dumper::Sortkeys = 1;
 #$Data::Dumper::Useperl = 1;
+
+our $HOST_CONFIG_REGEX = qr{
+	\A
+	(				# HOSTTYPE
+	(
+	    (			# POPNAME (optional)
+		[a-z]{3}\d{1}
+	    )
+	    -
+	)?
+	(
+	    [a-z0-9-]+[a-z-]	# host type (without the POP name)
+	)
+    )
+    %*				# % sign designate the number of digit at the end of real hostname
+    \z
+}xms;
+our $HOSTTYPE_CONFIG_REGEX = qr{
+	\A
+	(				# HOSTTYPE
+	(
+	    (			# POPNAME (optional)
+		[a-z]{3}\d{1}
+	    )
+	    -
+	)?
+	(
+	    [a-z0-9-]+[a-z-]	# host type (without the POP name)
+	)
+    )
+    \z
+}xms;
+
 
 my @DEFAULTDHCPVLAN = ('vlan-7');
 
@@ -681,31 +715,36 @@
 ### Rewrite with new syntax
 ### Enhancement : creating DNS entries when adding network or hosts
 
-sub __Add_zone ($$$$) {
-	my ( $netfile, $zone_name, $zone2add, $global_config ) = @_;
+sub Add_zone ($$$$$) {
+	my ( $netfile, $zone_name, $zone2add, $global_config, $pf_config ) = @_;
 	
-	my $zone_part = $global_config->{'ZONE'}->{'BY_NAME'};
-	if ( defined $zone_part->{$zone_name} ) {
-		Warn ( $CODE->{'WARNING'}, "Zone ".$zone_name." from file ".$netfile." already exists : skipping the new definition" );
-		return;
-	}
-	$zone_part->{$zone_name} = {};
-	$zone_part->{$zone_name}->{'SOA'}		= $zone2add;
-	$zone_part->{$zone_name}->{'BY_SITE'}	= {};
-}
-
-sub __Add_site ($$$$) {
-	my ( $netfile, $site_name, $site2add, $global_config ) = @_;
+	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+		next if ( ! $pf_config->{'features'}->{$ip_type} );
+		my $zone_key	= ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+		my $zone_part = $global_config->{$zone_key}->{'BY_NAME'};
+		if ( defined $zone_part->{$zone_name} ) {
+			Warn ( $CODE->{'WARNING'}, "Zone ".$zone_name." from file ".$netfile." already exists : skipping the new definition" );
+			return;
+		}
+		$zone_part->{$zone_name} = {
+			'SOA'				=> $zone2add,
+			'BY_SITE'			=> {},
+			'__network_order'	=> {},
+			'__hostclass_order'	=> {}
+		};
+		$zone_part->{$zone_name}->{'SOA'}		= $zone2add;
+		$zone_part->{$zone_name}->{'BY_SITE'}	= {};
+	}
+}
+
+sub Add_site ($$$$$) {
+	my ( $netfile, $site_name, $site2add, $global_config, $pf_config ) = @_;
 	
 	my $site_part = $global_config->{'SITE'};
 	if ( defined $site_part->{'BY_NAME'}->{$site_name} ) {
 		Warn ( $CODE->{'WARNING'}, "Site ".$site_name." from file ".$netfile." already exists : skipping the new definition" );
 		return;
 	}
-	if ( ! defined $global_config->{'ZONE'}->{'BY_NAME'}->{$site2add->{'zone'}} ) {
-		Abort ( $CODE->{'INVALID_VALUE'},
-			"Zone ".$site2add->{'zone'}." for site ".$site_name." defined into ".$netfile." doesn't exist in global configuration" );
-	}
 	if ( $site2add->{'state'} eq 'ROOT' ) {
 		if ( $site_part->{'ROOT'} ) {
 			Warn ( $CODE->{'WARNING'}, "Site ".$site_name." from file ".$netfile." cannot be defined as ROOT site : skipping the new definition" );
@@ -719,27 +758,59 @@
 	$site_part->{'BY_NAME'}->{$site_name} = $site2add;
 	$site_part->{'BY_NAME'}->{$site_name}->{'NETWORK'} = {
 		'BY_NAME'	=> {},
-		'BY_ADDR'	=> {},
-		'BY_ADDR6'	=> {},
 		'BY_TAG'	=> {}
 	};
 	$site_part->{'BY_NAME'}->{$site_name}->{'HOST'} = {
 		'BY_NAME'	=> {},
-		'BY_ADDR'	=> {},
-		'BY_ADDR6'	=> {},
 		'BY_MAC'	=> {}
 	};
+	$site_part->{'BY_NAME'}->{$site_name}->{'SERVICE'} = {
+		'BY_NAME'	=> {}
+	};
 	push ( @{$site_part->{'__site_list'}}, $site_name );
-	$global_config->{'ZONE'}->{'BY_NAME'}->{$site2add->{'zone'}}->{'BY_SITE'}->{$site_name} = {};
-	$global_config->{'ZONE'}->{'BY_SITE'}->{$site_name} = $site2add->{'zone'};
-}
-
-sub __Get_site_list ($$) {
+	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+		next if ( ! $pf_config->{'features'}->{$ip_type} );
+		my $zone_key	= ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+		my $dhcp_key	= ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
+		my $addr_key	= ( $ip_type eq 'ipv6' ) ? 'BY_ADDR6' : 'BY_ADDR';
+		if ( ! defined $global_config->{$zone_key}->{'BY_NAME'}->{$site2add->{'zone'}} ) {
+			Abort ( $CODE->{'INVALID_VALUE'},
+				"Zone ".$site2add->{'zone'}." for site ".$site_name." defined into ".$netfile." doesn't exist in global configuration" );
+		}
+		$site_part->{'BY_NAME'}->{$site_name}->{'NETWORK'}->{$addr_key} = {};
+		$site_part->{'BY_NAME'}->{$site_name}->{'HOST'}->{$addr_key}	= {};
+		$global_config->{$zone_key}->{'BY_NAME'}->{$site2add->{'zone'}}->{'BY_SITE'}->{$site_name} = {};
+		$global_config->{$zone_key}->{'BY_SITE'}->{$site_name} = $site2add->{'zone'};
+		$global_config->{$dhcp_key}->{'BY_SITE'}->{$site_name} = {
+			$site2add->{'dhcpvlan'}	=> {
+				'subnet'	=> '',
+				'netmask'	=> ''
+			}
+		};
+	}
+}
+
+sub __Get_site_prefix ($$) {
+	my ( $site, $ref_site ) = @_;
+	
+	my $prefix		= ( $ref_site->{'state'} eq 'EDGE' )
+		? $site.'-'
+		: '';
+	return $prefix;
+}
+
+sub __Get_site_zone ($$) {
+	my ( $site, $ref_site ) = @_;
+	
+	return $ref_site->{'zone'};
+}
+
+sub Get_site_list ($$) {
 	my ( $sect_hash, $global_config ) = @_;
 	my $ref_list;
 	
 	if ( $sect_hash->{'site'} eq 'ALL' ) {
-		return $global_config->{'__site_list'};
+		return $global_config->{'SITE'}->{'__site_list'};
 	}
 	else {
 		@{$ref_list} = split ( /\s*\,\s*/, $sect_hash->{'site'} );
@@ -750,135 +821,128 @@
 sub __Get_netblock_from_vlan ($$) {
 	my ( $type, $net_hash ) = @_;
 	
-	my $suffix = ( $type eq 'ipv6' )
-		? '6'
-		: '';
+	my $suffix = ( $type eq 'ipv6' ) ? '6' : '';
 	my $block = ( $net_hash->{'netmask'.$suffix} =~/^\// )
 		? new NetAddr::IP ( $net_hash->{'network'.$suffix}.$net_hash->{'netmask'.$suffix} )
 		: new NetAddr::IP ( $net_hash->{'network'.$suffix}, $net_hash->{'netmask'.$suffix} );
 	return $block;
 }
 
-sub __Add_network ($$$$) {
-	my ( $netfile, $net_name, $net2add, $global_config ) = @_;
-	my ( $block, $block6, $site_list, $net_part );
-
-	my $site_part	= $global_config->{'SITE'};
-	$site_list = __Get_site_list ( $net2add, $global_config );
+sub Add_network ($$$$$) {
+	my ( $netfile, $net_name, $ref_net, $global_config, $pf_config ) = @_;
+	my ( $block, $block6, $site_list, $net_part, $dhcp_part, $net2add, $ip_gw, $ip6_gw );
+
+	my $site_part		= $global_config->{'SITE'};
+	$site_list			= Get_site_list ( $ref_net, $global_config );
+	$net2add->{'scope'}	= $ref_net->{'scope'};
 	# Check TAG
-	if ( $net2add->{'tag'} && ( $net2add->{'tag'} < 0 || $net2add->{'tag'} > 4095 ) ) {
+	if ( $ref_net->{'tag'} && ( $ref_net->{'tag'} < 0 || $ref_net->{'tag'} > 4095 ) ) {
 		Abort ( $CODE->{'INVALID_VALUE'}, 
-		"Invalid 802.1q tag ".$net2add->{'tag'}." for file ".$netfile." into ".$net_name." definition" );
-	}
-	# Check IPv4 values
-	$block = __Get_netblock_from_vlan ( 'ipv4', $net2add );
-	if ( ! defined $block ) {
-		Abort ( $CODE->{'INVALID_VALUE'}, 
-			"Invalid IPv4 definition for network ".$net2add->{'network'}
-			." and/or ".$net2add->{'netmask'}." from file ".$netfile." into ".$net_name." definition" );
-	}
-	if ( $net2add->{'gateway'} ) {
-		my $ip_gw = new NetAddr::IP ( $block->prefix().$net2add->{'gateway'} );
-		if ( ! defined $ip_gw ) {
-			Abort ( $CODE->{'UNDEF_KEY'},
-				"Unable to check IPv4 gateway defined from ".$netfile." into ".$net_name." definition" );
-		}
-		elsif ( ! $block->contains ( $ip_gw ) ) {
-			Abort (
-				"Gateway ".$ip_gw." is out of range from network ".$net2add->{'network'}
-				." from file ".$netfile." into ".$net_name." definition" );
-		}
-	}
-	# Check IPv6 values if defined
-	if ( $net2add->{'network6'} ) {
-		$block6 = __Get_netblock_from_network ( 'ipv6', $net2add );
-		if ( ! defined $block6 ) {
-			Abort ( $CODE->{'INVALID_VALUE'},
-				"Invalid IPv6 definition for network ".$net2add->{'network6'}
-				." and/or ".$net2add->{'netmask6'}." from file ".$netfile." into ".$net_name." definition" );
-		}
-		if ( $net2add->{'gateway'} ) {
-			my $ip_gw = new NetAddr::IP ( $block->prefix().$net2add->{'gateway'} );
+		"Invalid 802.1q tag ".$ref_net->{'tag'}." for file ".$netfile." into ".$net_name." definition" );
+	}
+	# Check IP values
+	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+		next if ( ! $pf_config->{'features'}->{$ip_type} );
+		my $suffix		= ( $ip_type eq 'ipv6') ? '6' : '';
+		my $net_block	= __Get_netblock_from_vlan ( $ip_type, $ref_net );
+		if ( ! defined $net_block ) {
+			Abort ( $CODE->{'INVALID_VALUE'}, 
+				"Invalid ".$ip_type." definition for network ".$ref_net->{'network'}
+				." and/or ".$ref_net->{'netmask'}." from file ".$netfile." into ".$net_name." definition" );
+		}
+		$net2add->{'network'.$suffix} = $net_block->addr();
+		$net2add->{'netmask'.$suffix} = $net_block->mask();
+		if ( $ref_net->{'gateway'.$suffix} ) {
+			$ip_gw = new NetAddr::IP ( $net_block->prefix().$ref_net->{'gateway'}, $net_block->mask() );
 			if ( ! defined $ip_gw ) {
 				Abort ( $CODE->{'UNDEF_KEY'},
-					"Unable to check IPv4 gateway defined from ".$netfile." into ".$net_name." definition" );
+					"Unable to check ".$ip_type." gateway defined from ".$netfile." into ".$net_name." definition" );
 			}
-			elsif ( ! $block->contains ( $ip_gw ) ) {
+			elsif ( ! $net_block->contains ( $ip_gw ) ) {
 				Abort (
-					"Gateway ".$ip_gw." is out of range from network ".$net2add->{'network'}
+					"Gateway ".$ip_gw." is out of range from network ".$ref_net->{'network'}
 					." from file ".$netfile." into ".$net_name." definition" );
 			}
-		}
-	}
-
-	# Already defined in sites for which it will be : by name ? by tag ? by subnet
+			$net2add->{'gateway'.$suffix}	= $ip_gw->addr();
+		}
+		$net2add->{'tag'} = $ref_net->{'tag'};
+	}
+
+	# Already defined in sites for which it will be : by name ? by tag ?
 	foreach my $site ( @{$site_list} ) {
-		$net_part = $site_part->{'BY_NAME'}->{$site}->{'NETWORK'};
+		$net_part	= $site_part->{'BY_NAME'}->{$site}->{'NETWORK'};
 		if ( $net_part->{'BY_NAME'}->{$net_name} ) {
 			Warn ( $CODE->{'DUPLICATE_VALUE'},
 					"Network ".$net_name." from file ".$netfile." is already defined for site ".$site." : skipping declaration" );
 		}
-		else {
-			if ( $net2add->{'tag'} &&  $net_part->{'BY_TAG'}->{$net2add->{'tag'}} ) {
+		elsif ( $ref_net->{'tag'} &&  $net_part->{'BY_TAG'}->{$ref_net->{'tag'}} ) {
+			Abort ( $CODE->{'DUPLICATE_VALUE'},
+				"802.1q tag ".$ref_net->{'tag'}." for network ".$net_name." is already in use on site "
+				.$site." for network ".$net_part->{'BY_TAG'}->{$ref_net->{'tag'}} );
+		}
+		foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+			next if ( ! $pf_config->{'features'}->{$ip_type} ) ;
+			my $net_block = __Get_netblock_from_vlan ( $ip_type, $ref_net );
+			if ( ! defined $net_block ) {
+				Abort ( $CODE->{'INVALID_VALUE'}, 
+					"Invalid ".$ip_type." definition for network ".$ref_net->{'network'}
+					." and/or ".$ref_net->{'netmask'}." from file ".$netfile." into ".$net_name." definition" );
+			}
+			my $block = $net_block->cidr();
+			if ( $net_part->{'BY_ADDR'}->{$block} && $net_part->{'BY_ADDR'}->{$block} ne $net_name ) {
 				Abort ( $CODE->{'DUPLICATE_VALUE'},
-					"802.1q tag ".$net2add->{'tag'}." for network ".$net_name." is already in use on site "
-					.$site." for network ".$net_part->{'BY_TAG'}->{$net2add->{'tag'}} );
-			}
-			elsif ( $net_part->{'BY_ADDR'}->{$block} && $net_part->{'BY_ADDR'}->{$block} ne $net_name ) {
-				Abort ( $CODE->{'DUPLICATE_VALUE'},
-					"IPv4 subnet ".$block." for network ".$net_name." from file ".$netfile
+					$ip_type." subnet ".$block." for network ".$net_name." from file ".$netfile
 					." is already in use in site ".$site." for network ".$net_part->{'BY_ADDR'}->{$block} );
 			}
-			elsif ( $block6 && $net_part->{'BY_ADDR6'}->{$block6} && $net_part->{'BY_ADDR6'}->{$block6} ne $net_name ) {
-				Abort ( $CODE->{'DUPLICATE_VALUE'},
-					"IPv6 subnet ".$block6." for network ".$net_name." from file ".$netfile
-					." is already in use in site ".$site." for network ".$net_part->{'BY_ADDR6'}->{$block} );
+		}
+	}
+
+	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+		next if ( ! $pf_config->{'features'}->{$ip_type} );
+		my $zone_key	= ( $ip_type eq 'ipv6') ? 'ZONE6' : 'ZONE';
+		my $dhcp_key	= ( $ip_type eq 'ipv6') ? 'DHCP6' : 'DHCP';
+		my $netaddr_key	= ( $ip_type eq 'ipv6') ? 'BY_ADDR6' : 'BY_ADDR';
+		my $net_block	= __Get_netblock_from_vlan ( $ip_type, $ref_net );
+		foreach my $site ( @{$site_list} ) {
+			# Adding network to the network part of the global structure
+			$net_part										= $site_part->{'BY_NAME'}->{$site}->{'NETWORK'};
+			$dhcp_part										= $global_config->{$dhcp_key}->{'BY_SITE'}->{$site};
+			$net_part->{'BY_NAME'}->{$net_name}				= $net2add;
+			$net_part->{$netaddr_key}->{$net_block->cidr()}	= $net_name;
+			$net_part->{'BY_TAG'}->{$ref_net->{'tag'}}		= $net_name if ( $ref_net->{'tag'} );
+			# Adding entries for network, netmask, broadcast etc. into the DNS zone
+			my $zone		= __Get_site_zone ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
+			my $zone_part = $global_config->{$zone_key}->{'BY_NAME'}->{$zone};
+			push ( @{$zone_part->{'__network_order'}->{$site}}, $net_name );
+			$zone_part->{'BY_SITE'}->{$site}->{$net_name} = {};
+			# Adding IPv4 entries
+			$zone_part->{'BY_SITE'}->{$site}->{$net_name}->{'network'} = "A\t".$net_block->addr();
+			$zone_part->{'BY_SITE'}->{$site}->{$net_name}->{'netmask'} = "A\t".$net_block->mask();
+			my $broad	= $net_block->broadcast(); $broad =~ s/\/.*$//;
+			$zone_part->{'BY_SITE'}->{$site}->{$net_name}->{'broadcast'} = "A\t".$broad;
+			if ( defined $dhcp_part->{$net_name} ) {
+				$dhcp_part->{$net_name}->{'subnet'}		= $net_block->addr();
+				$dhcp_part->{$net_name}->{'netmask'}	= $net_block->mask();
+				if ( defined $net2add->{'gateway'} ) {
+					$dhcp_part->{$net_name}->{'routers'}	= $net2add->{'gateway'};
+				}
 			}
 		}
 	}
-
-	foreach my $site ( @{$site_list} ) {
-		# Adding network to the network part of the global structure
-		$net_part = $site_part->{'BY_NAME'}->{$site}->{'NETWORK'};
-		$net_part->{'BY_NAME'}->{$net_name}			= $net2add;
-		$net_part->{'BY_ADDR'}->{$block}			= $net_name;
-		$net_part->{'BY_ADDR6'}->{$block6}			= $net_name if ( $block6 );
-		$net_part->{'BY_TAG'}->{$net2add->{'tag'}}	= $net_name if ( $net2add->{'tag'} );
-		# Adding entries for network, netmask, broadcast etc. into the DNS zone
-		my $zone = $global_config->{'ZONE'}->{'BY_SITE'}->{$site};
-		my $zone_part = $global_config->{'ZONE'}->{'BY_NAME'}->{$zone};
-		$zone_part->{'__network_order'} = {} if ( ! defined $zone_part->{'__network_order'} );
-		push ( @{$zone_part->{'__network_order'}->{$site}}, $net_name );
-		# Adding IPv4 entries
-		$zone_part->{'BY_SITE'}->{$site}->{'network.'.$net_name} = "A\t".$net2add->{'network'};
-		$zone_part->{'BY_SITE'}->{$site}->{'netmask.'.$net_name} = ( $net2add->{'netmask'} =~ /^\// )
-			? "A\t".$block->mask()
-			: "A\t".$net2add->{'netmask'};
-		my $broad	= $block->broadcast(); $broad =~ s/\/.*$//;
-		$zone_part->{'BY_SITE'}->{$site}->{'broadcast.'.$net_name} = "A\t".$broad;
-		if ( $block6 ) {
-			$zone_part->{'BY_SITE'}->{$site}->{'network6.'.$net_name} = "A\t".$net2add->{'network6'};
-			$zone_part->{'BY_SITE'}->{$site}->{'netmask6.'.$net_name} = ( $net2add->{'netmask6'} =~ /^\// )
-				? "A\t".$block6->mask()
-				: "A\t".$net2add->{'netmask6'};
-			my $broad6 = $block6->broadcast(); $broad6 =~ s/\/.*$//;
-			$zone_part->{'BY_SITE'}->{$site}->{'broadcast6'.$net_name} = "A\t".$broad6;
-		}
-	}
 }
 
 sub __Get_host_indexes ($$) {
-	my ( $ref_host, $host_name ) = @_;
+	my ( $ref_hostgroup, $hostname_model ) = @_;
 	my ( $node_last, $num_last, $digits, $nodes );
 	
 	
-	$node_last	= ( $ref_host->{'nodes'} )
-		? ( $ref_host->{'nodes'} -1 )
+	$node_last	= ( $ref_hostgroup->{'nodes'} )
+		? ( $ref_hostgroup->{'nodes'} -1 )
 		: 0;
-	$num_last				= $ref_host->{'number'} - 1;
-	$ref_host->{'hostname'}	=~ /(%*)(_*)$/;
-	$digits					= length ($1) || 0;
-	$nodes					= length ($2) || 0;
+	$num_last		= $ref_hostgroup->{'number'} - 1;
+	$hostname_model	=~ /(%*)(_*)$/;
+	$digits			= length ($1) || 0;
+	$nodes			= length ($2) || 0;
 	# Checking nodes
 	if ( $node_last && ! $nodes ) {
 		Abort ( $CODE->{'INVALID_VALUE'},
@@ -886,120 +950,197 @@
 	}
 	elsif ( $node_last && ceil ( log($node_last) / log(26) ) > $nodes ) {
 		Warn ( $CODE->{'INVALID_VALUE'},
-			"Not enough places for indexing nodes definition for host ".$ref_host->{'hostgroup'}->{'hostname'} );
+			"Not enough places for indexing nodes definition for host ".$hostname_model );
 	}
 	# Checking hostnum
 	if ( $num_last && ! $digits ) {
 		Abort ( $CODE->{'INVALID_VALUE'},
-			"Unable to affect all host number(s) : no % defined in key hostname" );
+			"Unable to affect all host number(s) : no % defined in key hostname ".$hostname_model );
 	}
 	elsif ( $num_last && $num_last > 10**$digits ) {
 		Warn ( $CODE->{'INVALID_VALUE'},
-			"Not enough places for indexing host number(s) according to hostname ".$host_name );
+			"Not enough places for indexing host number(s) according to hostname ".$hostname_model );
 	}
 	return ( $num_last, $node_last );
 }
 
-sub __Check_host_interfaces ($$$$$) {
-	my ( $ref_host, $host_name, $host_num, $site, $network_site ) = @_;
-	my ( @if_list, $vlan );
-	
-	foreach my $section ( keys %{$ref_host} ) {
+sub __Get_hostname_from_model ($$$$) {
+	my ( $hostname_model, $hostnum, $hostnode, $site_prefix ) = @_;
+	my ( $hostname, $digits, $nodes, $index );
+
+	$hostname = $hostname_model;
+	if ( $hostname !~ /%+/ && $hostname !~ /_+/ ) {
+		return $hostname;
+	}
+	$hostname_model	=~ /(%*)(_*)$/;
+	$digits			= length ($1) || 0;
+	$nodes			= length ($2) || 0;
+	$index			= "";
+	while ( $digits > length ( $hostnum ) ) {
+		$index .= "0";
+		$digits--;
+	}
+	$index = ( $hostnode )
+		? $index.$hostnum.$hostnode
+		: $index.$hostnum;
+	$hostname =~ s/(%*)(_*)$/$index/;
+	$hostname = $site_prefix.$hostname;
+	return $hostname;
+}
+
+
+sub __Get_host_interfaces ($) {
+	my ( $ref_src ) = @_;
+	my ( @if_list );
+
+	foreach my $section ( keys %{$ref_src} ) {
 		next if ( $section !~ /^interface/ );
 		$section =~ /^interface::(((eth|bond)[\d]+)(\.(TAG[\d]+))?)$/;
 		push ( @if_list, $2 );
 	}
-	foreach my $iface ( @if_list ) {
-		my $iface_section = 'interface::'.$iface;
-		$iface =~ /^(eth|bond[\d]+)(\.(TAG[\d]+))?$/;
-		my ( $ifraw, $iftag ) = ( $1, $3 );
-		my $vlan = $ref_host->{$iface_section}->{'vlan'};
-		# Check tag
-		if ( $iftag && $iftag =~ /^\d+$/ ) {
-			Abort ( $CODE->{'INVALID_VALUE'},
-				"Tag ".$iftag." defined on section name ".$iface_section." differs from "
-				.$ref_host->{'vlan'}." network definition" );
-		}
-		if ( $iface =~ /^bond/ && ! $iftag ) {
-			# Check if slaves not in use
-			my @slaves = ( $ref_host->{$iface_section}->{'slaves.'.$host_num} )
-				? split ( /\s*,\s*/, $ref_host->{$iface_section}->{'slaves.'.$host_num} )
-				: split ( /\s*,\s*/, $ref_host->{$iface_section}->{'slaves'} );
-			foreach my $if ( @slaves ) {
-				Abort ( $CODE->{'INVALID_VALUE'},
-					"Interface ".$if." cannot be enslaved by ".$iface." : already in use for "
-					.$host_name ) if ( grep ( /$if/, @if_list ) );
-			}
-		}
-		# Check vlan
-		if ( ! defined $network_site->{'BY_NAME'}->{$vlan} ) {
-			Abort ( $CODE->{'INVALID_VALUE'},
-				"Unknown vlan ".$vlan." on site ".$site." for interface ".$iface.
-				" defined on host ".$host_name );
-		}
-		# Check address and route values
-		foreach my $ip_type ( 'ipv4', 'ipv6' ) {
-			next if ( ! $ref_host->{$iface_section}->{$ip_type} );
-			my $netblock = __Get_netblock_from_vlan ( $ip_type, $network_site->{'BY_NAME'}->{$vlan} );
-			if ( ! defined $netblock ) {
-				Abort ( $CODE->{'INVALID_VALUE'},
-					"Unable to retrieve network block of type ".$ip_type." for vlan ".$vlan
-					." on site ".$site." for host ".$host_name );
-			}
-			my $prefix = $netblock->prefix();
-			my $realip = ( $ref_host->{$iface_section}->{$ip_type.'.'.$host_num} )
-				? new NetAddr::IP ( $prefix.$ref_host->{$iface_section}->{$ip_type.'.'.$host_num} )
-				: new NetAddr::IP ( $prefix.$ref_host->{$iface_section}->{$ip_type} );
-			if ( ! defined $realip ) {
-				Abort ( $CODE->{'INVALID_VALUE'},
-					"Unable to check ".$ip_type." realip for vlan ".$vlan
-					." for host ".$host_name." on site ".$site );
-			}
-			elsif ( ! $netblock->contains ( $realip ) ) {
-				Abort ( $CODE->{'INVALID_VALUE'},
-					"IP of type ".$ip_type." on vlan ".$vlan." is out of "
-					.$netblock." for host ".$host_name." on site ".$site );
-			}
-			my $route_key	= ( $ip_type eq 'ipv6' ) ? '@route6' : '@route';
-			my $gw_key		= ( $ip_type eq 'ipv6' ) ? 'gateway6' : 'gateway';
-			if ( defined $ref_host->{$iface_section}->{$route_key} ) {
-				foreach my $route ( @{$ref_host->{$iface_section}->{$route_key}} ) {
-					$route =~ /^(\S+)\s*(via\s*(\S+))?$/;
-					my ( $dest, $via ) = ( $1, $3 );
-					if ( $dest ne 'default' ) {
-						print "$dest, $via|\n";
-						if ( $dest =~ /[g-zG-Z]+/ && ! defined $network_site->{'BY_NAME'}->{$dest} ) {
+	return @if_list;
+}
+
+sub __Get_ip_from_hostindex ($$;$$$) {
+	my ( $net_block, $ipstart, $hostnum, $hostnode, $nodes ) = @_;
+	
+	my $ip = new NetAddr::IP ( $net_block->prefix().$ipstart, $net_block->mask() );
+	if ( ! defined $ip ) {
+		Abort ( $CODE->{'UNDEF_KEY'},
+			"Unable to create IP object from prefix ".$net_block->prefix()." and host ".$ipstart );
+	}
+	if ( $hostnum ) {
+		my $add = ( $hostnode )
+			? ( $hostnum * $nodes ) + $hostnode
+			: $hostnum;
+		$ip = $ip + $add;
+	}
+	return $ip;
+}
+
+sub __Check_host_ip ($$$$$$$$) {
+	my ( $ip_type, $vlan_block, $ipstart, $hostnum, $hostnode, $nodes, $site, $ref_site ) = @_;
+
+	my $prefix = $vlan_block->prefix();
+	my $realip = __Get_ip_from_hostindex ( $vlan_block, $ipstart, $hostnum, $hostnode, $nodes ) ;
+	my $host_addr_site = $ref_site->{'HOST'}->{'BY_ADDR'};
+	if ( defined $host_addr_site->{$realip->addr()} ) {
+		Abort ( $CODE->{'DUPLICATE_VALUE'},
+			"IP ".$realip->addr()." is already in use by host ".$host_addr_site->{$realip->cidr()}
+			." on site ".$site );
+	}
+	if ( ! $vlan_block->contains ( $realip ) ) {
+		Abort ( $CODE->{'INVALID_VALUE'},
+			"IP of type ".$ip_type." is out of ".$vlan_block->cidr()." on site ".$site );
+	}
+	return $realip;
+}
+
+sub __Get_srv_vlan_list ($) {
+	my ( $ref_srv ) = @_;
+	my $vlan_list = [];
+
+	foreach my $key ( keys %{$ref_srv} ) {
+		next if ( $key !~ /^ipv/ );
+		my ( $type, $vlan, $num ) = split ( /\./, $key );
+		push ( @{$vlan_list}, $vlan ) if ( ! grep ( /^$vlan$/, @{$vlan_list} ) );
+	}
+	return $vlan_list;
+}
+
+sub __Get_alias_for_vlan ($$;$) {
+	my ( $ref_parsed, $vlan, $host_number ) = @_;
+	my $alias_list = [];
+
+	foreach my $key ( keys %{$ref_parsed} ) {
+		next if ( $key !~ /^alias/ );
+		my ( $alias, $name, $host_num ) = split ( /\./, $key );
+		next if ( $host_number && $host_num && $host_num ne $host_number );
+		push ( @{$alias_list}, $name ) if ( 
+			$vlan eq $ref_parsed->{$key}
+			&& ! grep ( /^$name$/, @{$alias_list} ) );
+	}
+	return $alias_list;
+}
+
+sub Add_server ($$$$$) {
+	my ( $srvfile, $srvname_model, $srv2add, $global_config, $pf_config ) = @_;
+	
+	$srvname_model					=~ /^$pf_config->{'regex'}->{'hostname'}$/ ;
+	my $shortname					= $1;
+	my $hostclass					= $shortname;
+	my $site_list					= Get_site_list ( $srv2add, $global_config );
+	my ( $host_last, $node_last )	= __Get_host_indexes ( $srv2add, $srvname_model );
+	my $nodes						= $srv2add->{'nodes'} || 0;
+	foreach my $site ( @{$site_list} ) {
+		my $site_part	= $global_config->{'SITE'}->{'BY_NAME'}->{$site};
+		if ( ! defined $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
+			$site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
+		}
+		my $srv_part	= $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass};
+		my $zone		= __Get_site_zone ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
+		my $prefix		= __Get_site_prefix ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
+		my $vlan_list	= __Get_srv_vlan_list ( $srv2add );
+		foreach my $hostnum ( 0 .. $host_last ) {
+			foreach my $hostnode (  0 .. $node_last ) {
+				my $srvname = __Get_hostname_from_model ( $srvname_model, $hostnum, $hostnode, $prefix );
+				if ( $srv_part->{$srvname} ) {
+					Warn ( $CODE->{'DUPLICATE_VALUE'},
+						"Hostclass ".$hostclass." already contains hostname ".$srvname." definition from file "
+						.$srvfile." and for site ".$site." : skipping this hostname" );
+					next;
+				}
+				my $srv_number	= ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
+				my $short_vlan	= $srv2add->{'shortname.'.$srv_number} || $srv2add->{'shortname'} || "";
+				my $iface_idx	= 0;
+				foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+					next if ( ! $pf_config->{'features'}->{$ip_type} );
+					my $addr_key	= ( $ip_type eq 'ipv6' ) ? 'BY_ADDR6' : 'BY_ADDR';
+					my $zone_key	= ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+					my $dhcp_key	= ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
+					my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
+					my $zone_part	= $global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'BY_SITE'}->{$site};
+					foreach my $vlan ( @{$vlan_list} ) {
+						my $net_block	= __Get_netblock_from_vlan ( $ip_type, $site_part->{'NETWORK'}->{'BY_NAME'}->{$vlan} );
+						if ( ! defined $net_block ) {
 							Abort ( $CODE->{'INVALID_VALUE'},
-								"Unknown network ".$dest." on site ".$site );
+								"Unable to retrieve network block of type ".$ip_type." for vlan ".$vlan
+								." on site ".$site." for host ".$srvname );
+						}
+						my $realip;
+						if ( $srv2add->{$ip_type.'.'.$vlan.'.'.$srv_number} ) {
+							$realip = __Check_host_ip ( $ip_type, $net_block, $srv2add->{$ip_type.'.'.$vlan.'.'.$srv_number}, 0, 0, 0, $site, $site_part );
 						}
 						else {
-							my $ip_dest = new NetAddr::IP ( $dest );
-							if ( ! defined $ip_dest ) {
-								Abort ( $CODE->{'INVALID_VALUE'},
-									"Unable to check dest IP ".$dest." of type ".$ip_type." on \@route key for interface ".$iface
-									." for host ".$host_name." on site ".$site );
+							$realip = __Check_host_ip ( $ip_type, $net_block, $srv2add->{$ip_type.'.'.$vlan}, $hostnum, $hostnode, $nodes, $site, $site_part );
+						}
+						$srv_part->{$srvname} = {
+							'interfaces'	=> {}
+						} if ( ! defined $srv_part->{$srvname} );
+						$srv_part->{$srvname}->{'interfaces'}->{'eth'.$iface_idx} = {
+							$ip_type			=> $realip->addr(),
+							'netmask'.$suffix	=> $realip->mask(),
+							'vlan'				=> $vlan
+						};
+						$iface_idx++;
+						$site_part->{'HOST'}->{$addr_key}->{$realip->addr()} = $srvname.'.'.$vlan;
+						if ( ! defined $zone_part->{$hostclass} ){
+							$zone_part->{$hostclass} = {};
+							push ( @{$global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'__hostclass_order'}->{$site}}, $hostclass );
+						}
+						$zone_part->{$hostclass}->{$srvname.'.'.$vlan}		= "A\t".$realip->addr();
+						if ( $short_vlan eq $vlan && $shortname ne $srvname ) {
+							print $shortname."\n";
+							print Dumper $zone_part->{$hostclass};
+							push ( @{$zone_part->{$hostclass}->{$shortname.'.'.$vlan}}, "A\t".$realip->addr() );
+						}
+						my $alias_list = __Get_alias_for_vlan ( $srv2add, $vlan, $srv_number );
+						foreach my $alias ( @{$alias_list} ) {
+							if ( ! defined $zone_part->{$hostclass}->{$alias.'.'.$vlan} ) {
+								$zone_part->{$hostclass}->{$alias.'.'.$vlan} = "CNAME\t".$shortname.'.'.$vlan;
 							}
-						}
-					}
-					if ( $via ) {
-						if ( $via eq 'GATEWAY' && ! defined  $network_site->{'BY_NAME'}->{$vlan}->{$gw_key} ) {
-							Abort ( $CODE->{'INVALID_VALUE'},
-								"Unable to define default route by vlan ".$vlan." : no gateway defined on this one" );
-						}
-						elsif ( $via =~ /[g-zG-Z]+/ ) {
-							# Potentially not parsed host ... skipping this case for now
-						}
-						else {
-							my $ip_via = new NetAddr::IP ( $via );
-							if ( ! defined $ip_via ) {
-								Abort ( $CODE->{'INVALID_VALUE'},
-									"Unable to check IP ".$via." of type ".$ip_type." as gateway for interface ".$iface
-									." for host ".$host_name." on site ".$site );
-							}
-							elsif ( ! $netblock->contains ( $ip_via ) ) {
-								Abort ( $CODE->{'INVALID_VALUE'},
-									"IP ".$ip_via." of type ".$ip_type." for gateway on interface ".$iface
-									." is out of ".$netblock." for host ".$host_name." on site ".$site );
+							if ( $shortname ne $srvname ) {
+								$zone_part->{$hostclass}->{$alias.$srv_number.'.'.$vlan}	= "CNAME\t".$srvname.'.'.$vlan;
 							}
 						}
 					}
@@ -1009,30 +1150,261 @@
 	}
 }
 
-sub __Add_host ($$$) {
-	my ( $hostfile, $host2add, $global_config ) = @_;
-
-	my $host_name = $host2add->{'hostgroup'}->{'hostname'};
-	my $site_list = __Get_site_list ( $host2add, $global_config );
+sub __Add_host_interface ($$$$$$$$$) {
+	my ( $iface, $hostname, $hostnum, $hostnode, $ref_host, $ref_if_list, $site, $ref_site, $pf_config ) = @_;
+	my ( @if_list, $vlan, $ifraw, $iftag, $add_if );
+
+	my $network_site	= $ref_site->{'NETWORK'};
+	my $host_site		= $ref_site->{'HOST'};	
+	my $iface_section	= 'interface::'.$iface;
+	my $nodes			= $ref_host->{'hostgroup'}->{'nodes'} || 0;
+	my $host_number		= ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
+	$iface =~ /^(eth|bond[\d]+)(\.(TAG[\d]+))?$/;
+	( $ifraw, $iftag )	= ( $1, $3 );
+	$vlan = $ref_host->{$iface_section}->{'vlan.'.$host_number} || $ref_host->{$iface_section}->{'vlan'};
+	$add_if->{'vlan'}	= $vlan;
+	# Check MAC address if defined
+	if ( defined $ref_host->{$iface_section}->{'mac.'.$host_number} ) {
+		my $mac = $ref_host->{$iface_section}->{'mac.'.$host_number};
+		if ( $host_site->{'BY_MAC'}->{$mac} ) {
+			my ( $ifdef, $hostdef, $vlandef ) = split ( /\./, $host_site->{'BY_MAC'}->{$mac} );
+			Abort ( $CODE->{'DUPLICATE_VALUE'},
+				"MAC address ".$mac." is already defined for interface ".$ifdef." in host ".$hostdef
+				." which is on vlan ".$vlandef );
+		}
+		$add_if->{'mac'}	= $mac;
+	}
+	# Check tag
+	if ( $iftag && $iftag =~ /^\d+$/ ) {
+		Abort ( $CODE->{'INVALID_VALUE'},
+			"Tag ".$iftag." defined on section name ".$iface_section." differs from "
+			.$ref_host->{'vlan'}." network definition" );
+	}
+	if ( $iface =~ /^bond/ && ! $iftag ) {
+		# Check if slaves not in use
+		my @slaves = ( $ref_host->{$iface_section}->{'slaves.'.$host_number} )
+			? split ( /\s*,\s*/, $ref_host->{$iface_section}->{'slaves.'.$host_number} )
+			: split ( /\s*,\s*/, $ref_host->{$iface_section}->{'slaves'} );
+		foreach my $if ( @slaves ) {
+			Abort ( $CODE->{'INVALID_VALUE'},
+				"Interface ".$if." cannot be enslaved by ".$iface." : already in use for "
+				.$hostname ) if ( grep ( /$if/, @{$ref_if_list} ) );
+		}
+	}
+	# Check vlan
+	if ( ! defined $network_site->{'BY_NAME'}->{$vlan} ) {
+		Abort ( $CODE->{'INVALID_VALUE'},
+			"Unknown vlan ".$vlan." on site ".$site." for interface ".$iface.
+			" defined on host ".$hostname );
+	}
+	# Check address and route values
+	foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+		next if ( ! $pf_config->{'features'}->{$ip_type} );
+		my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
+		my $netblock	= __Get_netblock_from_vlan ( $ip_type, $network_site->{'BY_NAME'}->{$vlan} );
+		if ( ! defined $netblock ) {
+			Abort ( $CODE->{'INVALID_VALUE'},
+				"Unable to retrieve network block of type ".$ip_type." for vlan ".$vlan
+				." on site ".$site." for host ".$hostname );
+		}
+		my $realip;
+		if ( $ref_host->{$iface_section}->{$ip_type.'.'.$host_number} ) {
+			$realip = __Check_host_ip ( $ip_type, $netblock, $ref_host->{$iface_section}->{$ip_type.'.'.$host_number}, 0, 0, 0, $site, $ref_site );
+		}
+		else {
+			$realip = __Check_host_ip ( $ip_type, $netblock, $ref_host->{$iface_section}->{$ip_type}, $hostnum, $hostnode, $nodes, $site, $ref_site );
+		}
+ 		$add_if->{$ip_type}				= $realip->addr();
+		$add_if->{'netmask'.$suffix}	= $realip->mask();
+		my $route_key	= ( $ip_type eq 'ipv6' ) ? '@route6' : '@route';
+		$route_key		.= $hostnum if ( $ref_host->{$iface_section}->{$route_key.'.'.$host_number} );
+		my $gw_key		= ( $ip_type eq 'ipv6' ) ? 'gateway6' : 'gateway';
+		if ( defined $ref_host->{$iface_section}->{$route_key} ) {
+			foreach my $route ( @{$ref_host->{$iface_section}->{$route_key}} ) {
+				$route =~ /^(\S+)\s*(via\s*(\S+))?$/;
+				my ( $dest, $via ) = ( $1, $3 );
+				my $route2add = '';
+				if ( $dest ne 'default' ) {
+					my $ip_dest;
+					if ( $dest =~ /[g-zG-Z]+/ ) {
+						if ( defined $network_site->{'BY_NAME'}->{$dest} ) {
+							# Dest is a defined network ... translating into IP
+							$ip_dest = new NetAddr::IP ( $network_site->{'BY_NAME'}->{$dest}->{'network'}, $network_site->{'BY_NAME'}->{$dest}->{'netmask'} );
+							$route2add .= $ip_dest->cidr()." via ";
+						}
+						else {
+							# Potentially not parsed host on this site
+							$route2add .= $dest." via ";
+						}
+					}
+					else {
+						$ip_dest = new NetAddr::IP ( $dest );
+						if ( ! defined $ip_dest ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"Unable to check dest IP ".$dest." of type ".$ip_type." on \@route key for interface ".$iface
+								." for host ".$hostname." on site ".$site );
+						}
+						$route2add .= $ip_dest->cidr()." via ";
+					}
+				}
+				else {
+					$route2add .= "default via ";
+				}
+				if ( $via ) {
+					my $ip_via;
+					if ( $via eq 'GATEWAY' ) {
+						if ( ! defined  $network_site->{'BY_NAME'}->{$vlan}->{$gw_key} ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"Unable to define default route by vlan ".$vlan." : no gateway defined on this one" );
+						}
+						$route2add .= $network_site->{'BY_NAME'}->{$vlan}->{$gw_key};
+					}
+					elsif ( $via =~ /[g-zG-Z]+/ ) {
+						# Potentially not parsed host ... skipping this case for now
+						$route2add .= $via;
+					}
+					else {
+						my $ip_via = new NetAddr::IP ( $via );
+						if ( ! defined $ip_via ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"Unable to check IP ".$via." of type ".$ip_type." as gateway for interface ".$iface
+								." for host ".$hostname." on site ".$site );
+						}
+						elsif ( ! $netblock->contains ( $ip_via ) ) {
+							Abort ( $CODE->{'INVALID_VALUE'},
+								"IP ".$ip_via." of type ".$ip_type." for gateway on interface ".$iface
+								." is out of ".$netblock." for host ".$hostname." on site ".$site );
+						}
+						$route2add .= $ip_via->addr();
+					}
+				}
+				push ( @{$add_if->{$route_key}}, $route2add );
+			}
+		}
+	}
+	return $add_if;
+}
+
+sub Add_host ($$$$) {
+	my ( $hostfile, $host2add, $global_config, $pf_config ) = @_;
+
+	my $hostname_model	= $host2add->{'hostgroup'}->{'hostname'};
+	$hostname_model		=~ /^$pf_config->{'regex'}->{'hostname'}$/ ;
+	my $shortname		= $1;
+	my $hostclass		= $host2add->{'hostgroup'}->{'hosttype'} || $shortname;
+	my $site_list		= Get_site_list ( $host2add->{'hostgroup'}, $global_config );
+	my $pf_tftp_dir		= $pf_config->{'path'}->{'tftp_dir'};
+	$pf_tftp_dir		.= '/' if ( $pf_tftp_dir !~ /\/$/ );
+	my ( $host_last, $node_last )	= __Get_host_indexes ( $host2add->{'hostgroup'}, $hostname_model );
+	
 	foreach my $site ( @{$site_list} ) {
 		my $site_part	= $global_config->{'SITE'}->{'BY_NAME'}->{$site};
-		my $host_part	= $site_part->{'HOST'};
-		my ( $host_last, $node_last ) = __Get_host_indexes ( $host2add, $host_name );
+		if ( ! defined $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
+			$site_part->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
+		}
+		my $host_part	= $site_part->{'HOST'}->{'BY_NAME'}->{$hostclass};
+		my $zone		= __Get_site_zone ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
+		my $prefix		= __Get_site_prefix ( $site, $global_config->{'SITE'}->{'BY_NAME'}->{$site} );
 		foreach my $hostnum ( 0 .. $host_last ) {
 			foreach my $hostnode (  0 .. $node_last ) {
-				my $dhcpvlan = ( $host2add->{'deployment'}->{'dhcpvlan'} )
-					? $host2add->{'deployment'}->{'dhcpvlan'}
-					: $site_part->{'dhcpvlan'};
+				my $hostname = __Get_hostname_from_model ( $hostname_model, $hostnum, $hostnode, $prefix );
+				if ( $host_part->{$hostname} ) {
+					Warn ( $CODE->{'DUPLICATE_VALUE'},
+						"Hostclass ".$hostclass." already contains hostname ".$hostname." definition from file "
+						.$hostfile." and for site ".$site." : skipping this hostname" );
+					next;
+				}
+				my $host_number = ( $hostnode ) ? $hostnum.$hostnode : $hostnum;
+				# Checking path for PXE elements kernel, initrd ...
+				foreach my $key ( 'pxefilename', 'kernel', 'initrd', 'kerneluml', 'initrduml', 'console', 'cmdline' ) {
+					my $value;
+					if ( $key eq 'console' ) {
+						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key} || $site_part->{$key};
+					}
+					elsif ( $key eq 'cmdline' ) {
+						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key} || "";
+					}
+					else {
+						$value = $host2add->{'boot'}->{$key.'.'.$host_number} || $host2add->{'boot'}->{$key};
+						next if ( ! defined $value );
+						if ( ! -e $pf_tftp_dir.$value ) {
+							Warn ( $CODE->{'OPEN'},
+								"Unable to find file ".$pf_tftp_dir.$value." for key ".$key." for host ".$hostname." from file ".$hostfile );
+						}
+					}
+					$host_part->{$hostname}->{'boot'}->{$key}	= $value;
+				}
+				my $dhcpvlan = $host2add->{'deployment'}->{'dhcpvlan.'.$host_number} || $host2add->{'deployment'}->{'dhcpvlan'} || $site_part->{'dhcpvlan'};
 				if ( ! defined $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan} ) {
 					Abort ( $CODE->{'INVALID_VALUE'},
-						"Vlan ".$dhcpvlan." defined for ".$host_name." from file "
-						.$hostfile." doesn't exist on site ".$site );
+						"Vlan ".$dhcpvlan." defined for ".$hostname." from file ".$hostfile." doesn't exist on site ".$site );
+				}
+				foreach my $key ( 'arch', 'distrib', 'mode', 'os_type' ) {
+					my $value = $host2add->{'deployment'}->{$key.'.'.$host_number} || $host2add->{'deployment'}->{$key};
+					next if ( ! defined $value );
+					$host_part->{$hostname}->{'deployment'}->{$key} = $value;
+				}
+				# Check interfaces
+				my @if_list = __Get_host_interfaces ($host2add);
+				foreach my $iface ( @if_list ) {
+					my $if2add = __Add_host_interface ( $iface, $hostname, $hostnum, $hostnode, $host2add, \@if_list, $site, $site_part, $pf_config );
+					# Adding interface and IPs into site's zone
+					$host_part->{$hostname}->{'interfaces'}						= {} if ( ! defined $host_part->{$hostname}->{'interfaces'} );
+					$host_part->{$hostname}->{'interfaces'}->{$iface}			= $if2add;
+					$site_part->{'HOST'}->{'BY_MAC'}->{$if2add->{'mac'}}		= $iface.'.'.$hostname.'.'.$if2add->{'vlan'} if ( $if2add->{'mac'} );
+					if ( $if2add->{'vlan'} eq $dhcpvlan && ! defined $if2add->{'mac'} ) {
+						Abort ( $CODE->{'UNDEF_KEY'},
+							"MAC address MUST BE defined for interface ".$iface." which is on dhcpvlan ".$dhcpvlan );
+					}
+					foreach my $ip_type ( 'ipv4', 'ipv6' ) {
+						next if ( ! $pf_config->{'features'}->{$ip_type} );
+						my $addr_key	= ( $ip_type eq 'ipv6' ) ? 'BY_ADDR6' : 'BY_ADDR';
+						my $zone_key	= ( $ip_type eq 'ipv6' ) ? 'ZONE6' : 'ZONE';
+						my $dhcp_key	= ( $ip_type eq 'ipv6' ) ? 'DHCP6' : 'DHCP';
+						my $suffix		= ( $ip_type eq 'ipv6' ) ? '6' : '';
+						my $zone_part	= $global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'BY_SITE'}->{$site};
+						my $dhcp_part	= $global_config->{$dhcp_key}->{'BY_SITE'}->{$site};
+						$site_part->{'HOST'}->{$addr_key}->{$if2add->{$ip_type}} = $hostname.'.'.$if2add->{'vlan'};
+						if ( ! defined $zone_part->{$hostclass} ) {
+							$zone_part->{$hostclass} = {};
+							push ( @{$global_config->{$zone_key}->{'BY_NAME'}->{$zone}->{'__hostclass_order'}->{$site}}, $hostclass );
+						}
+						$zone_part->{$hostclass}->{$hostname.'.'.$if2add->{'vlan'}}		= "A\t".$if2add->{$ip_type};
+						my $shortname_vlan	= $host2add->{'dns'}->{'shortname.'.$host_number} || $host2add->{'dns'}->{'shortname'} || "";
+						if ( $shortname_vlan eq $if2add->{'vlan'} ) {
+							push ( @{$zone_part->{$hostclass}->{$shortname.'.'.$if2add->{'vlan'}}}, "A\t".$if2add->{$ip_type} );
+						}
+						foreach my $key ( keys %{$host2add->{'dns'}} ) {
+							next if ( $key !~ /^alias/ );
+							my ( $key_type, $alias, $host_num ) = split ( /\./, $key );
+							if ( $host2add->{'dns'}->{$key} eq $if2add->{'vlan'} ) {
+								$zone_part->{$hostclass}->{$alias.'.'.$if2add->{'vlan'}}				= "CNAME\t".$shortname.'.'.$if2add->{'vlan'};
+								$zone_part->{$hostclass}->{$alias.$host_number.'.'.$if2add->{'vlan'}}	= "CNAME\t".$hostname.'.'.$if2add->{'vlan'};
+							}
+						}
+						my $resolver = $host2add->{'dns'}->{'resolver.'.$host_number} || $host2add->{'dns'}->{'resolver'};
+						if ( $if2add->{'vlan'} eq $dhcpvlan ) {
+							if ( ! defined $dhcp_part->{$dhcpvlan} ) {
+								$dhcp_part->{$dhcpvlan} = {};
+								$dhcp_part->{$dhcpvlan}->{'subnet'}		= $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'network'.$suffix};
+								$dhcp_part->{$dhcpvlan}->{'netmask'}	= $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'netmask'.$suffix};
+								if ( $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'gateway'.$suffix} ) {
+									$dhcp_part->{$dhcpvlan}->{'routers'} = $site_part->{'NETWORK'}->{'BY_NAME'}->{$dhcpvlan}->{'gateway'.$suffix};
+								}
+							}
+							$dhcp_part->{$dhcpvlan}->{$hostclass} = {} if ( ! defined $dhcp_part->{$dhcpvlan}->{$hostclass} );
+							$dhcp_part->{$dhcpvlan}->{$hostclass}->{$hostname} = [
+								'hardware ethernet '.$if2add->{'mac'}.';',
+								'fixed-address '.$if2add->{$ip_type}.';',
+								'filename '.$host2add->{'boot'}->{'pxefilename'}.';',
+								'option domain-name-servers '.$resolver.';'
+							];
+						}
+					}
 				}
 			}
 		}
-		$host_part->{'BY_NAME'}->{$host_name} = $host2add;
-	}
-	# Add others sections
+	}
 }
 
 #
@@ -1042,49 +1414,49 @@
 #	Une reference sur la structure est retournee.
 #
 #=============================================================================================
-sub Init_lib_net {
-    my ( $fic_conf, $syntax ) = @_;
-
-    my $C;
-    my $Z;
-    my $s;
-
-    # Initialisation de la structure de donnees
-    $Z = {};
-    $Z->{'NETWORK'} = { { 'BY_ADDR', {} }, { 'BY_NAME', {} } };
-    $Z->{'SERVERS'} = { { 'BY_ADDR', {} }, { 'BY_NAME', {} } };
-    $Z->{'SOA'}   = {};
-    $Z->{'NS'}    = [];
-    $Z->{'MX'}    = [];
-    $Z->{'ALIAS'} = {};
-
-    # Chargement du fichier de configuration reseau
-    $C = Load_conf( $fic_conf, \%SUBST, 'network', $syntax );
-
-    # Calcul de la conf reseau et de la zone
-    foreach $s ( keys %$C ) {
-	if ( $C->{$s}->{'type'} =~ /network$/ ) {
-	    Add_network( $Z, $C->{$s}, $s );
-	}
-
-	# Prise en compte de la zone
-	if ( $C->{$s}->{'type'} =~ /zone$/ ) {
-	    Add_zone( $Z, $C->{$s}, $s );
-	}
-    }
-
-    # Calcul de la conf serveur
-    # (Il doit obligatoirement etre fait en seconde passe
-    # il utilise les donnees reseau et zone)
-    foreach $s ( keys %$C ) {
-	if ( $C->{$s}->{'type'} =~ /server$/ ) {
-	    Add_server( $Z, $C->{$s}, $s );
-	}
-    }
-
-    # Retour de la structure de donnees
-    return ($Z);
-}
+# sub Init_lib_net {
+#     my ( $fic_conf, $syntax ) = @_;
+# 
+#     my $C;
+#     my $Z;
+#     my $s;
+# 
+#     # Initialisation de la structure de donnees
+#     $Z = {};
+#     $Z->{'NETWORK'} = { { 'BY_ADDR', {} }, { 'BY_NAME', {} } };
+#     $Z->{'SERVERS'} = { { 'BY_ADDR', {} }, { 'BY_NAME', {} } };
+#     $Z->{'SOA'}   = {};
+#     $Z->{'NS'}    = [];
+#     $Z->{'MX'}    = [];
+#     $Z->{'ALIAS'} = {};
+# 
+#     # Chargement du fichier de configuration reseau
+#     $C = Load_conf( $fic_conf, \%SUBST, 'network', $syntax );
+# 
+#     # Calcul de la conf reseau et de la zone
+#     foreach $s ( keys %$C ) {
+# 	if ( $C->{$s}->{'type'} =~ /network$/ ) {
+# 	    Add_network( $Z, $C->{$s}, $s );
+# 	}
+# 
+# 	# Prise en compte de la zone
+# 	if ( $C->{$s}->{'type'} =~ /zone$/ ) {
+# 	    Add_zone( $Z, $C->{$s}, $s );
+# 	}
+#     }
+# 
+#     # Calcul de la conf serveur
+#     # (Il doit obligatoirement etre fait en seconde passe
+#     # il utilise les donnees reseau et zone)
+#     foreach $s ( keys %$C ) {
+# 	if ( $C->{$s}->{'type'} =~ /server$/ ) {
+# 	    Add_server( $Z, $C->{$s}, $s );
+# 	}
+#     }
+# 
+#     # Retour de la structure de donnees
+#     return ($Z);
+# }
 
 #
 #	VOID Add_server (HASHREF $Z, HASHREF $S, STRING $srv)
@@ -1093,498 +1465,498 @@
 #	En entree $S contient les informations sur les serveurs de type $srv
 #
 #===================================================================================
-sub Add_server {
-    my ( $Z, $S, $srv ) = @_;
-    my $start;
-    my $s;
-
-    # Calcul de la plage d'adresse alouee et du nombre de serveurs a definir
-
-    if ( !defined( $S->{'nodes'} ) ) {
-	$S->{'nodes'} = 1;
-    }
-    my $nodeslast = $S->{'nodes'} - 1;
-    if ( $nodeslast < 0 ) {
-	$nodeslast = 0;
-    }
-
-    if ( !defined( $S->{'number'} ) ) {
-	$S->{'number'} = 1;
-    }
-    my $last = $S->{'number'} - 1;
-    if ( $last < 0 ) {
-	$last = 0;
-    }
-
-    $srv =~ s/(_*)$//;
-    my $nodes = length($1);
-    $srv =~ s/(%*)$//;
-    my $digit = length($1);
-
-    # Pas de nodes et plusieurs nodes
-    if ( $nodeslast > 0 && ( !defined($nodes) || $nodes <= 0 ) ) {
-	Abort( $ERR_SYNTAX,
-	    "Plusieurs nodes " . $srv . " et pas de place pour l'index!" );
-    }
-
-    # Pas assez de nodes pour le nombre de nodes
-    if ( $nodeslast > 1 && ceil( log($nodeslast) / log(26) ) > $nodes ) {
-	Warn( $ERR_SYNTAX,
-	          "Dernier node " 
-		. $srv . " = "
-		. $nodeslast
-		. " et pas assez de place ("
-		. $nodes
-		. ") pour l'index!" );
-    }
-
-    # Pas de digits et plusieurs machines
-    if ( $last > 0 && ( !defined($digit) || $digit <= 0 ) ) {
-	Abort( $ERR_SYNTAX,
-	    "Plusieurs " . $srv . " et pas de place pour le numero!" );
-    }
-
-    # Pas assez de digits pour le nombre de machines
-    if ( $last > 1 && length( sprintf( "%s", $last ) ) > $digit ) {
-	Warn( $ERR_SYNTAX,
-	          "Dernier " 
-		. $srv . " = " 
-		. $last
-		. " et pas assez de place ("
-		. $digit
-		. ") pour le numero!" );
-    }
-
-    # Initialisation de la structure pour ces serveurs
-    my $N = {};
-    $N->{'comment'} = $S->{'comment'} || "Server $srv <no comment specified>";
-    $N->{'type'} = $S->{'type'};
-
-    #$N->{range}   = $S->{range};
-    $N->{'number'} = $S->{'number'};
-    $N->{'nodes'}  = $S->{'nodes'};
-
-    $N->{'order'} = $S->{'order'};
-
-    $N->{SRVLIST} = {};
-
-    my $ipincrement = 1;
-    if ( defined $S->{'ipincrement'} ) {
-	$ipincrement = $S->{'ipincrement'};
-    }
-
-    # Traitement de chaque occurence
-    my $ipindex = -$ipincrement;
-    foreach $s ( 0 .. $last ) {
-	for my $n ( 0 .. $nodeslast ) {
-	    my $M = {};
-	    my $i;
-	    my $j;
-	    my $mnam;
-
-	    $ipindex += $ipincrement;
-
-	    # Definition du nom
-	    my $cnamindex    = "";
-	    my $cnamindexnum = "";
-	    if ( defined($digit) && $digit > 0 ) {
-		$cnamindex .= sprintf( "%0" . $digit . "s", $s );
-		$cnamindexnum .= sprintf( "%s", $s );
-	    }
-	    my $mnamindex    = $cnamindex;
-	    my $mnamindexnum = $cnamindexnum;
-	    if ( defined($nodes) && $nodes > 0 ) {
-		$mnamindex
-		    = $cnamindex
-		    . sprintf( "%0" . $nodes . "s",
-		    node2index( $n, $nodes ) );
-		$mnamindexnum
-		    = $cnamindexnum
-		    . sprintf( "%0" . $nodes . "s",
-		    node2index( $n, $nodes ) );
-	    }
-
-	    $mnam = $srv . $mnamindex;
-	    if ( $cnamindexnum eq "" ) {
-		$cnamindexnum = "0";
-	    }
-	    if ( $mnamindexnum eq "" ) {
-		$mnamindexnum = "0";
-	    }
-
-	    $M->{'name'}     = $mnam;
-	    $M->{'zone'}     = {};
-	    $M->{'ifup'}     = {};
-	    $M->{'route'}    = {};
-	    $M->{'delroute'} = {};
-
-	    my @common_keys = (
-		'filename',
-		'pxefilename',
-		'umlfilename',
-		'vmwfilename',
-		'pxelinuxconf',
-		'pxetemplate',
-		'deploymode',
-		'dns',
-		'arch',
-		'distrib',
-		'initrd',
-		'cmdline',
-		'console'
-	    ) ;
-	    foreach my $key ( @common_keys ) {
-		if ( defined ( $S->{$key}->{$mnamindexnum} ) ) {
-		    if ( $key eq 'arch' && $S->{$key}->{$mnamindexnum} !~ /^$ALLOWED_ARCH$/ ) {
-			Abort( $ERR_SYNTAX, "Invalid architecture for host ".$srv.$mnamindexnum." : ".$S->{$key}->{$mnamindexnum} ) ;
-		    } elsif ( $key eq 'deploymode' ) {
-			Abort ( $ERR_SYNTAX, "Invalid deploymode key for host ".$srv.$mnamindexnum." : ".$S->{$key}->{$mnamindexnum} )
-				if ( $S->{$key}->{$mnamindexnum} !~ /^$ALLOWED_DEPLOYMODE$/ ) ;
-		    }
-		    $M->{$key} = $S->{$key}->{$mnamindexnum} ;
-		}
-		elsif ( defined ( $S->{$key}->{'default'} ) ) {
-		    if ( $key eq 'arch' && $S->{$key}->{'default'} !~ /^$ALLOWED_ARCH$/ ) {
-			Abort( $ERR_SYNTAX, "Invalid default architecture for host ".$srv." : ".$S->{$key}->{'default'} ) ;
-		    } elsif ( $key eq 'deploymode' ) {
-			Abort ( $ERR_SYNTAX, "Invalid default deploymode key ".$S->{$key}->{'default'} )
-				if ( $S->{$key}->{'default'} !~ /^$ALLOWED_DEPLOYMODE$/ ) ;
-		    }
-		    $M->{$key} = $S->{$key}->{'default'} ;
-		}
-		elsif ( $key eq 'deploymode' ) {
-		    $M->{'deploymode'} = 'pf-tools' ;
-		}
-		elsif ( $key eq 'initrd' && $M->{'deploymode'} eq 'pf-tools' ) {
-		    $M->{'initrd'} = 'initrd' ;
-		}
-		elsif ( $key eq 'arch' ) {
-		    $M->{'arch'} = 'i386' ;
-		}
-		elsif ( $key eq 'console' && defined $Z->{'SOA'}->{'console'} ) {
-			$M->{'console'} = $Z->{'SOA'}->{'console'};
-		}
-	    }
-
-	    delete $M->{'console'} if $M->{'console'} and $M->{'console'} eq 'default';
-
-	    if ( defined $S->{'bonding'} ) {
-		foreach my $bond ( keys %{$S->{'bonding'}} ) {
-		    if ( defined $S->{'bonding'}->{$bond}->{$mnamindexnum} ) {
-		    	@{$M->{'bonding'}->{$bond}} = split ( /,/, $S->{'bonding'}->{$bond}->{$mnamindexnum} ) ;
-		    }
-		    elsif ( defined $S->{'bonding'}->{$bond}->{'default'} ) {
-		    	@{$M->{'bonding'}->{$bond}} = split ( /,/, $S->{'bonding'}->{$bond}->{'default'} ) ;
-		    }
-		    else {
-			Abort( $ERR_SYNTAX, "No default bonding config defined for interface ".$bond ) ;
-		    }
-		    foreach my $iface ( @{$M->{'bonding'}->{$bond}} ) {
-		    	if ( defined $S->{'interface'}->{$iface} ) {
-			    if ( ref ( $S->{'interface'}->{$iface} ) eq 'HASH' ) {
-				if ( defined $S->{'interface'}->{$iface}->{$mnamindexnum} ) {
-				    Abort( $ERR_SYNTAX, "Cannot define interface $iface: already used in bonding definition $bond" );
-				}
-			    }
-			    else {
-			    	Abort( $ERR_SYNTAX, "Cannot define interface $iface: already used in bonding definition $bond" );
-			    }
-			}
-		    }
-		}
-	    }
-
-	    # vrrp?
-	    my $vrrp;
-	    foreach $j ( keys %{ $S->{'vrrp'} } ) {
-		if ( $S->{'vrrp'}->{$j} eq $s
-		    || ( $S->{'vrrp'}->{$j} eq "last" && $s == $last ) )
-		{
-		    $vrrp = $j;
-		    $mnam = $j;
-		}
-	    }
-
-	    my $goteth1 = 0;
-
-	    # Traitement de chaque interface (ou reseau)
-	    foreach $i ( sort { cmpif( $a, $b ) }
-		keys %{ $S->{'interface'} } )
-	    {
-		my $nam;
-
-		if ( $i eq 'eth1' ) {
-		    $goteth1 = 1;
-		}
-
-		$j = $i;
-		if ( $j =~ m/^eth3/ && $NOETH3 ) {
-		    if ($goteth1) {
-			$j = 'eth1' . $' . ':9999';
-		    }
-		    else {
-			$j = 'eth1' . $';
-		    }
-		}
-
-		# Definition de l'entree DNS pour cette interface
-		my $lan ;
-		if ( ref ( $S->{'interface'}->{$i} ) eq 'HASH' ) {
-		    if ( defined $S->{'interface'}->{$i}->{$mnamindexnum} ) {
-			$lan = $S->{'interface'}->{$i}->{$mnamindexnum} ;
-		    }
-		    elsif ( ! defined $S->{'interface'}->{$i}->{'default'} ) {
-			Warn( $ERR_SYNTAX, "No default vlan defined for interface ".$i." skipping this interface for host $mnam" ) ;
-			next ;
-		    }
-		    else {
-			$lan = $S->{'interface'}->{$i}->{'default'} ;
-		    }
-		}
-		else {
-		    $lan = $S->{'interface'}->{$i} ;
-		}
-		
-		if ( $i =~ /^(?:eth|bond)[\d]+\.((TAG)?[\d]+)$/ ) {
-		    my $tag = $1 ;
-		    if ( defined $Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'tag'} ) {
-			Warn ( $ERR_SYNTAX, "Tag ".$tag." differs from defined tag "
-				.$Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'tag'}." for vlan ".$lan." on ".$i." for host ".$mnam )
-			    if ( $tag =~ /^[\d]+/ && $tag != $Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'tag'} );
-		    }
-		    else {
-			Abort ( $ERR_SYNTAX, "Tag is not defined for vlan ".$lan ); # if ( $1 =~ /^TAG/ );
-		    }
-		}
-		
-		$nam = $mnam . "." . $lan;
-		
-		if ( $M->{'ifup'}->{$nam} ) {
-		    Abort ( $ERR_SYNTAX, "Cannot define $i on vlan ".$lan." ".$M->{'ifup'}->{$nam}." is already on this vlan for host ".$mnam ) ;
-		}
-
-		my $addr = $Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'network'};
-
-		if ( defined $S->{'ip'}->{$lan}->{$mnamindexnum} ) {
-		    $start = $S->{'ip'}->{$lan}->{$mnamindexnum}
-		}
-		elsif ( defined $S->{'ipstart'}->{$lan} ) {
-		    $start = $S->{'ipstart'}->{$lan};
-		}
-		elsif ( defined $S->{'ipstart'}->{'default'} ) {
-		    $start = $S->{'ipstart'}->{'default'};
-		}
-		elsif ( defined $S->{'shortname'} ) {
-		    $start = $S->{'ipstart'}->{ $S->{'shortname'} };
-		}
-
-		if ( !defined $start ) {
-		    Abort( $ERR_SYNTAX, "No ipstart for " . $nam );
-		}
-
-		$M->{'zone'}->{$nam} = {};
-		if ( defined $S->{'ip'}->{$lan}->{$mnamindexnum} ) {
-		    $M->{'zone'}->{$nam}->{'FIELD'}
-		        = Address ( $addr, $start, 0 ) ;
-		}
-		else {
-		    $M->{'zone'}->{$nam}->{'FIELD'}
-		        = Address( $addr, $start, $ipindex );
-		}
-		
-		$M->{'zone'}->{$nam}->{'TYPE'} = 'A';
-
-		# Adresse ethernet (pas forcement avec dhcp, eg tftp)
-		if ( defined( $S->{'ether'}->{$mnamindexnum} ) ) {
-		    $M->{'zone'}->{$nam}->{'ether'}
-			= $S->{'ether'}->{$mnamindexnum};
-		}
-
-		if ( defined( $S->{'vmether'}->{$mnamindexnum} ) ) {
-		    $M->{'zone'}->{$nam}->{'vmether'}
-			= $S->{'vmether'}->{$mnamindexnum};
-		}
-		elsif ( defined( $S->{'ether'}->{$mnamindexnum} ) ) {
-		    $M->{'zone'}->{$nam}->{'vmether'} = '00:50:56:' . sprintf(
-			"%02x:%02x:%02x",
-			unpack( "L", $mnam ) % 255,    # L : long unsigned,
-			unpack( "L", reverse $mnam ) % 255,
-			$start + $ipindex
-		    );
-		}
-
-		# Definition de l'alias DNS principal
-		if ( defined $S->{'shortname'} && $S->{'shortname'} eq $lan ) {
-		    $M->{'zone'}->{$mnam}            = {};
-		    $M->{'zone'}->{$mnam}->{'FIELD'} = $nam;
-		    $M->{'zone'}->{$mnam}->{'TYPE'}  = 'CNAME';
-		}
-
-		# Alias de vlan pour la classe
-		if ( !defined( $Z->{'ALIAS'}->{ $srv . '.' . $lan } ) ) {
-		    $Z->{'ALIAS'}->{ $srv . '.' . $lan } = [];
-		}
-		if (scalar(
-			grep( /^$nam$/, $Z->{'ALIAS'}->{ $srv . '.' . $lan } )
-		    ) == 0
-		    )
-		{
-		    push(
-			@{ $Z->{'ALIAS'}->{ $srv . '.' . $lan } },
-			$M->{'zone'}->{$nam}->{'FIELD'}
-		    );
-		}
-
-		# Alias de vlan pour le cluster
-		if ( $nodeslast > 0 ) {
-		    if (!defined(
-			    $Z->{'ALIAS'}->{ $srv . $cnamindex . '.' . $lan }
-			)
-			)
-		    {
-			$Z->{'ALIAS'}->{ $srv . $cnamindex . '.' . $lan }
-			    = [];
-		    }
-		    if (scalar(
-			    grep( /^$nam$/,
-				$Z->{'ALIAS'}
-				    ->{ $srv . $cnamindex . '.' . $lan } )
-			) == 0
-			)
-		    {
-			push(
-			    @{  $Z->{'ALIAS'}
-				    ->{ $srv . $cnamindex . '.' . $lan }
-				},
-			    $M->{'zone'}->{$nam}->{'FIELD'}
-			);
-		    }
-		}
-
-		# Traduction du tag si format <iface>\.TAG[\d]+
-		if ( $j =~ /TAG[\d]+$/ ) {
-			$j =~ s/TAG[\d]+$/$Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'tag'}/ ;
-		}
-
-		# Definition de l'entree dans /etc/network/interface
-		if ( defined( $S->{'dhcp'} ) && $i eq $S->{'dhcp'} ) {
-		    $M->{'ifup'}->{'dhcp'} = $j;
-		}
-		else {
-		    $M->{'ifup'}->{$nam} = $j;
-		}
-
-		# Traitement des routes
-		my $r;
-		foreach $r ( keys %{ $S->{$i} } ) {
-		    if ( $r =~ m/^(route|delroute)/ ) {
-			my $act = $1 ;
-			if ( ref ( $S->{$i}->{$r} ) eq 'HASH' ) {
-			    if ( defined $S->{$i}->{$r}->{$mnamindexnum} ) {
-				$M->{$act}->{$j}->{$r} = $S->{$i}->{$r}->{$mnamindexnum} ;
-			    } elsif ( ! defined $S->{$i}->{$r}->{'default'} ) {
-				Warn ( $ERR_SYNTAX, "No default route defined for interface ".$i." skipping this route for host $mnam" ) ;
-			    } else {
-				$M->{$act}->{$j}->{$r} = $S->{$i}->{$r}->{'default'} ;
-			    }
-			} else {
-			    $M->{$act}->{$j}->{$r} = $S->{$i}->{$r};
-			}
-		    }
-		}
-
-		# Traitement des mtu
-		if ( defined( $S->{$i}->{'mtu'} ) ) {
-		    $M->{'mtu'}->{$j} = $S->{$i}->{'mtu'};
-		}
-
-		# Traitement des media
-		if ( defined( $S->{$i}->{'media'} ) ) {
-		    $M->{'media'}->{$j} = $S->{$i}->{'media'};
-		}
-
-		# Traitement des noarp
-		if ( defined( $S->{$i}->{'noarp'} ) ) {
-		    $M->{'noarp'}->{$j} = $S->{$i}->{'noarp'};
-		}
-	    }
-
-	    # Definition des alias DNS
-	    foreach $j ( keys %{ $S->{'alias'} } ) {
-		my $lan;
-		my $nam;
-		my $addr;
-
-		# Alias par machine
-		$lan = $S->{'alias'}->{$j};
-		$nam = $j . $mnamindex;
-
-		# ne pas ecraser si shortname deja existant
-		if ( !defined $M->{'zone'}->{$nam} ) {
-		    $M->{'zone'}->{$nam}            = {};
-		    $M->{'zone'}->{$nam}->{'FIELD'} = $mnam . "." . $lan;
-		    $M->{'zone'}->{$nam}->{'TYPE'}  = 'CNAME';
-		}
-
-	     # Alias "round robin" pour l'ensemble de cette classe de serveurs
-		$nam = $mnam . "." . $lan;
-
-		#if ( !defined( $Z->{ALIAS}->{$j} ) ) {
-		#    $Z->{ALIAS}->{$j} = [];
-		#}
-		#push ( @{ $Z->{ALIAS}->{$j} }, $M->{zone}->{$nam}->{FIELD} );
-		if ( $s == 0 && $n == 0 && !defined $M->{'zone'}->{$j} ) {
-		    $M->{'zone'}->{$j}            = {};
-		    $M->{'zone'}->{$j}->{'FIELD'} = $srv . "." . $lan;
-		    $M->{'zone'}->{$j}->{'TYPE'}  = 'CNAME';
-		}
-		if (   $nodeslast > 0
-		    && $s == 0
-		    && $n == 0
-		    && !defined $M->{'zone'}->{ $j . $cnamindex } )
-		{
-		    $M->{'zone'}->{ $j . $cnamindex } = {};
-		    $M->{'zone'}->{ $j . $cnamindex }->{'FIELD'}
-			= $srv . $cnamindex . "." . $lan;
-		    $M->{'zone'}->{ $j . $cnamindex }->{'TYPE'} = 'CNAME';
-		}
-	    }
-
-	    # Insertion du serveur dans sa classe
-	    $N->{'SRVLIST'}->{$mnam} = $M;
-	}
-
-	# Vips du cluster
-    }
-
-    # Insertion de la classe de serveurs dans la structure principale
-    if ( defined $S->{'shortname'} ) {
-	if ( defined $S->{'ipstart'}->{ $S->{'shortname'} } ) {
-	    $start = $S->{'ipstart'}->{ $S->{'shortname'} };
-	}
-	else {
-	    $start = $S->{'ipstart'}->{'default'};
-	}
-
-	my $srv_addr = Address ( $Z->{'NETWORK'}->{'BY_NAME'}->{ $S->{'shortname'} }->{'network'}, $start, 0 );
-	if ( defined $Z->{'SERVERS'}->{'BY_ADDR'}->{$srv_addr} ) {
-	    Warn ( $ERR_SYNTAX, "Address ".$srv_addr." for server ".$srv." is already in use" );
-	}
-	else {
-		push ( @{$Z->{'SERVERS'}->{'BY_ADDR'}->{$srv_addr}}, $N );
-	}
-    }
-
-    $Z->{'SERVERS'}->{'BY_NAME'}->{$srv} = $N;
-
-    # Remapping UM
-    if ($PFTOOLS_VARS->{'UML'}) {
-	my $mnam;
-	foreach $mnam ( keys %{ $N->{'SRVLIST'} } ) {
-	    UMRemap_If( $Z, $mnam );
-	}
-    }
-}
+# sub Add_server {
+#     my ( $Z, $S, $srv ) = @_;
+#     my $start;
+#     my $s;
+# 
+#     # Calcul de la plage d'adresse alouee et du nombre de serveurs a definir
+# 
+#     if ( !defined( $S->{'nodes'} ) ) {
+# 	$S->{'nodes'} = 1;
+#     }
+#     my $nodeslast = $S->{'nodes'} - 1;
+#     if ( $nodeslast < 0 ) {
+# 	$nodeslast = 0;
+#     }
+# 
+#     if ( !defined( $S->{'number'} ) ) {
+# 	$S->{'number'} = 1;
+#     }
+#     my $last = $S->{'number'} - 1;
+#     if ( $last < 0 ) {
+# 	$last = 0;
+#     }
+# 
+#     $srv =~ s/(_*)$//;
+#     my $nodes = length($1);
+#     $srv =~ s/(%*)$//;
+#     my $digit = length($1);
+# 
+#     # Pas de nodes et plusieurs nodes
+#     if ( $nodeslast > 0 && ( !defined($nodes) || $nodes <= 0 ) ) {
+# 	Abort( $ERR_SYNTAX,
+# 	    "Plusieurs nodes " . $srv . " et pas de place pour l'index!" );
+#     }
+# 
+#     # Pas assez de nodes pour le nombre de nodes
+#     if ( $nodeslast > 1 && ceil( log($nodeslast) / log(26) ) > $nodes ) {
+# 	Warn( $ERR_SYNTAX,
+# 	          "Dernier node " 
+# 		. $srv . " = "
+# 		. $nodeslast
+# 		. " et pas assez de place ("
+# 		. $nodes
+# 		. ") pour l'index!" );
+#     }
+# 
+#     # Pas de digits et plusieurs machines
+#     if ( $last > 0 && ( !defined($digit) || $digit <= 0 ) ) {
+# 	Abort( $ERR_SYNTAX,
+# 	    "Plusieurs " . $srv . " et pas de place pour le numero!" );
+#     }
+# 
+#     # Pas assez de digits pour le nombre de machines
+#     if ( $last > 1 && length( sprintf( "%s", $last ) ) > $digit ) {
+# 	Warn( $ERR_SYNTAX,
+# 	          "Dernier " 
+# 		. $srv . " = " 
+# 		. $last
+# 		. " et pas assez de place ("
+# 		. $digit
+# 		. ") pour le numero!" );
+#     }
+# 
+#     # Initialisation de la structure pour ces serveurs
+#     my $N = {};
+#     $N->{'comment'} = $S->{'comment'} || "Server $srv <no comment specified>";
+#     $N->{'type'} = $S->{'type'};
+# 
+#     #$N->{range}   = $S->{range};
+#     $N->{'number'} = $S->{'number'};
+#     $N->{'nodes'}  = $S->{'nodes'};
+# 
+#     $N->{'order'} = $S->{'order'};
+# 
+#     $N->{SRVLIST} = {};
+# 
+#     my $ipincrement = 1;
+#     if ( defined $S->{'ipincrement'} ) {
+# 	$ipincrement = $S->{'ipincrement'};
+#     }
+# 
+#     # Traitement de chaque occurence
+#     my $ipindex = -$ipincrement;
+#     foreach $s ( 0 .. $last ) {
+# 	for my $n ( 0 .. $nodeslast ) {
+# 	    my $M = {};
+# 	    my $i;
+# 	    my $j;
+# 	    my $mnam;
+# 
+# 	    $ipindex += $ipincrement;
+# 
+# 	    # Definition du nom
+# 	    my $cnamindex    = "";
+# 	    my $cnamindexnum = "";
+# 	    if ( defined($digit) && $digit > 0 ) {
+# 		$cnamindex .= sprintf( "%0" . $digit . "s", $s );
+# 		$cnamindexnum .= sprintf( "%s", $s );
+# 	    }
+# 	    my $mnamindex    = $cnamindex;
+# 	    my $mnamindexnum = $cnamindexnum;
+# 	    if ( defined($nodes) && $nodes > 0 ) {
+# 		$mnamindex
+# 		    = $cnamindex
+# 		    . sprintf( "%0" . $nodes . "s",
+# 		    node2index( $n, $nodes ) );
+# 		$mnamindexnum
+# 		    = $cnamindexnum
+# 		    . sprintf( "%0" . $nodes . "s",
+# 		    node2index( $n, $nodes ) );
+# 	    }
+# 
+# 	    $mnam = $srv . $mnamindex;
+# 	    if ( $cnamindexnum eq "" ) {
+# 		$cnamindexnum = "0";
+# 	    }
+# 	    if ( $mnamindexnum eq "" ) {
+# 		$mnamindexnum = "0";
+# 	    }
+# 
+# 	    $M->{'name'}     = $mnam;
+# 	    $M->{'zone'}     = {};
+# 	    $M->{'ifup'}     = {};
+# 	    $M->{'route'}    = {};
+# 	    $M->{'delroute'} = {};
+# 
+# 	    my @common_keys = (
+# 		'filename',
+# 		'pxefilename',
+# 		'umlfilename',
+# 		'vmwfilename',
+# 		'pxelinuxconf',
+# 		'pxetemplate',
+# 		'deploymode',
+# 		'dns',
+# 		'arch',
+# 		'distrib',
+# 		'initrd',
+# 		'cmdline',
+# 		'console'
+# 	    ) ;
+# 	    foreach my $key ( @common_keys ) {
+# 		if ( defined ( $S->{$key}->{$mnamindexnum} ) ) {
+# 		    if ( $key eq 'arch' && $S->{$key}->{$mnamindexnum} !~ /^$ALLOWED_ARCH$/ ) {
+# 			Abort( $ERR_SYNTAX, "Invalid architecture for host ".$srv.$mnamindexnum." : ".$S->{$key}->{$mnamindexnum} ) ;
+# 		    } elsif ( $key eq 'deploymode' ) {
+# 			Abort ( $ERR_SYNTAX, "Invalid deploymode key for host ".$srv.$mnamindexnum." : ".$S->{$key}->{$mnamindexnum} )
+# 				if ( $S->{$key}->{$mnamindexnum} !~ /^$ALLOWED_DEPLOYMODE$/ ) ;
+# 		    }
+# 		    $M->{$key} = $S->{$key}->{$mnamindexnum} ;
+# 		}
+# 		elsif ( defined ( $S->{$key}->{'default'} ) ) {
+# 		    if ( $key eq 'arch' && $S->{$key}->{'default'} !~ /^$ALLOWED_ARCH$/ ) {
+# 			Abort( $ERR_SYNTAX, "Invalid default architecture for host ".$srv." : ".$S->{$key}->{'default'} ) ;
+# 		    } elsif ( $key eq 'deploymode' ) {
+# 			Abort ( $ERR_SYNTAX, "Invalid default deploymode key ".$S->{$key}->{'default'} )
+# 				if ( $S->{$key}->{'default'} !~ /^$ALLOWED_DEPLOYMODE$/ ) ;
+# 		    }
+# 		    $M->{$key} = $S->{$key}->{'default'} ;
+# 		}
+# 		elsif ( $key eq 'deploymode' ) {
+# 		    $M->{'deploymode'} = 'pf-tools' ;
+# 		}
+# 		elsif ( $key eq 'initrd' && $M->{'deploymode'} eq 'pf-tools' ) {
+# 		    $M->{'initrd'} = 'initrd' ;
+# 		}
+# 		elsif ( $key eq 'arch' ) {
+# 		    $M->{'arch'} = 'i386' ;
+# 		}
+# 		elsif ( $key eq 'console' && defined $Z->{'SOA'}->{'console'} ) {
+# 			$M->{'console'} = $Z->{'SOA'}->{'console'};
+# 		}
+# 	    }
+# 
+# 	    delete $M->{'console'} if $M->{'console'} and $M->{'console'} eq 'default';
+# 
+# 	    if ( defined $S->{'bonding'} ) {
+# 		foreach my $bond ( keys %{$S->{'bonding'}} ) {
+# 		    if ( defined $S->{'bonding'}->{$bond}->{$mnamindexnum} ) {
+# 		    	@{$M->{'bonding'}->{$bond}} = split ( /,/, $S->{'bonding'}->{$bond}->{$mnamindexnum} ) ;
+# 		    }
+# 		    elsif ( defined $S->{'bonding'}->{$bond}->{'default'} ) {
+# 		    	@{$M->{'bonding'}->{$bond}} = split ( /,/, $S->{'bonding'}->{$bond}->{'default'} ) ;
+# 		    }
+# 		    else {
+# 			Abort( $ERR_SYNTAX, "No default bonding config defined for interface ".$bond ) ;
+# 		    }
+# 		    foreach my $iface ( @{$M->{'bonding'}->{$bond}} ) {
+# 		    	if ( defined $S->{'interface'}->{$iface} ) {
+# 			    if ( ref ( $S->{'interface'}->{$iface} ) eq 'HASH' ) {
+# 				if ( defined $S->{'interface'}->{$iface}->{$mnamindexnum} ) {
+# 				    Abort( $ERR_SYNTAX, "Cannot define interface $iface: already used in bonding definition $bond" );
+# 				}
+# 			    }
+# 			    else {
+# 			    	Abort( $ERR_SYNTAX, "Cannot define interface $iface: already used in bonding definition $bond" );
+# 			    }
+# 			}
+# 		    }
+# 		}
+# 	    }
+# 
+# 	    # vrrp?
+# 	    my $vrrp;
+# 	    foreach $j ( keys %{ $S->{'vrrp'} } ) {
+# 		if ( $S->{'vrrp'}->{$j} eq $s
+# 		    || ( $S->{'vrrp'}->{$j} eq "last" && $s == $last ) )
+# 		{
+# 		    $vrrp = $j;
+# 		    $mnam = $j;
+# 		}
+# 	    }
+# 
+# 	    my $goteth1 = 0;
+# 
+# 	    # Traitement de chaque interface (ou reseau)
+# 	    foreach $i ( sort { cmpif( $a, $b ) }
+# 		keys %{ $S->{'interface'} } )
+# 	    {
+# 		my $nam;
+# 
+# 		if ( $i eq 'eth1' ) {
+# 		    $goteth1 = 1;
+# 		}
+# 
+# 		$j = $i;
+# 		if ( $j =~ m/^eth3/ && $NOETH3 ) {
+# 		    if ($goteth1) {
+# 			$j = 'eth1' . $' . ':9999';
+# 		    }
+# 		    else {
+# 			$j = 'eth1' . $';
+# 		    }
+# 		}
+# 
+# 		# Definition de l'entree DNS pour cette interface
+# 		my $lan ;
+# 		if ( ref ( $S->{'interface'}->{$i} ) eq 'HASH' ) {
+# 		    if ( defined $S->{'interface'}->{$i}->{$mnamindexnum} ) {
+# 			$lan = $S->{'interface'}->{$i}->{$mnamindexnum} ;
+# 		    }
+# 		    elsif ( ! defined $S->{'interface'}->{$i}->{'default'} ) {
+# 			Warn( $ERR_SYNTAX, "No default vlan defined for interface ".$i." skipping this interface for host $mnam" ) ;
+# 			next ;
+# 		    }
+# 		    else {
+# 			$lan = $S->{'interface'}->{$i}->{'default'} ;
+# 		    }
+# 		}
+# 		else {
+# 		    $lan = $S->{'interface'}->{$i} ;
+# 		}
+# 		
+# 		if ( $i =~ /^(?:eth|bond)[\d]+\.((TAG)?[\d]+)$/ ) {
+# 		    my $tag = $1 ;
+# 		    if ( defined $Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'tag'} ) {
+# 			Warn ( $ERR_SYNTAX, "Tag ".$tag." differs from defined tag "
+# 				.$Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'tag'}." for vlan ".$lan." on ".$i." for host ".$mnam )
+# 			    if ( $tag =~ /^[\d]+/ && $tag != $Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'tag'} );
+# 		    }
+# 		    else {
+# 			Abort ( $ERR_SYNTAX, "Tag is not defined for vlan ".$lan ); # if ( $1 =~ /^TAG/ );
+# 		    }
+# 		}
+# 		
+# 		$nam = $mnam . "." . $lan;
+# 		
+# 		if ( $M->{'ifup'}->{$nam} ) {
+# 		    Abort ( $ERR_SYNTAX, "Cannot define $i on vlan ".$lan." ".$M->{'ifup'}->{$nam}." is already on this vlan for host ".$mnam ) ;
+# 		}
+# 
+# 		my $addr = $Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'network'};
+# 
+# 		if ( defined $S->{'ip'}->{$lan}->{$mnamindexnum} ) {
+# 		    $start = $S->{'ip'}->{$lan}->{$mnamindexnum}
+# 		}
+# 		elsif ( defined $S->{'ipstart'}->{$lan} ) {
+# 		    $start = $S->{'ipstart'}->{$lan};
+# 		}
+# 		elsif ( defined $S->{'ipstart'}->{'default'} ) {
+# 		    $start = $S->{'ipstart'}->{'default'};
+# 		}
+# 		elsif ( defined $S->{'shortname'} ) {
+# 		    $start = $S->{'ipstart'}->{ $S->{'shortname'} };
+# 		}
+# 
+# 		if ( !defined $start ) {
+# 		    Abort( $ERR_SYNTAX, "No ipstart for " . $nam );
+# 		}
+# 
+# 		$M->{'zone'}->{$nam} = {};
+# 		if ( defined $S->{'ip'}->{$lan}->{$mnamindexnum} ) {
+# 		    $M->{'zone'}->{$nam}->{'FIELD'}
+# 		        = Address ( $addr, $start, 0 ) ;
+# 		}
+# 		else {
+# 		    $M->{'zone'}->{$nam}->{'FIELD'}
+# 		        = Address( $addr, $start, $ipindex );
+# 		}
+# 		
+# 		$M->{'zone'}->{$nam}->{'TYPE'} = 'A';
+# 
+# 		# Adresse ethernet (pas forcement avec dhcp, eg tftp)
+# 		if ( defined( $S->{'ether'}->{$mnamindexnum} ) ) {
+# 		    $M->{'zone'}->{$nam}->{'ether'}
+# 			= $S->{'ether'}->{$mnamindexnum};
+# 		}
+# 
+# 		if ( defined( $S->{'vmether'}->{$mnamindexnum} ) ) {
+# 		    $M->{'zone'}->{$nam}->{'vmether'}
+# 			= $S->{'vmether'}->{$mnamindexnum};
+# 		}
+# 		elsif ( defined( $S->{'ether'}->{$mnamindexnum} ) ) {
+# 		    $M->{'zone'}->{$nam}->{'vmether'} = '00:50:56:' . sprintf(
+# 			"%02x:%02x:%02x",
+# 			unpack( "L", $mnam ) % 255,    # L : long unsigned,
+# 			unpack( "L", reverse $mnam ) % 255,
+# 			$start + $ipindex
+# 		    );
+# 		}
+# 
+# 		# Definition de l'alias DNS principal
+# 		if ( defined $S->{'shortname'} && $S->{'shortname'} eq $lan ) {
+# 		    $M->{'zone'}->{$mnam}            = {};
+# 		    $M->{'zone'}->{$mnam}->{'FIELD'} = $nam;
+# 		    $M->{'zone'}->{$mnam}->{'TYPE'}  = 'CNAME';
+# 		}
+# 
+# 		# Alias de vlan pour la classe
+# 		if ( !defined( $Z->{'ALIAS'}->{ $srv . '.' . $lan } ) ) {
+# 		    $Z->{'ALIAS'}->{ $srv . '.' . $lan } = [];
+# 		}
+# 		if (scalar(
+# 			grep( /^$nam$/, $Z->{'ALIAS'}->{ $srv . '.' . $lan } )
+# 		    ) == 0
+# 		    )
+# 		{
+# 		    push(
+# 			@{ $Z->{'ALIAS'}->{ $srv . '.' . $lan } },
+# 			$M->{'zone'}->{$nam}->{'FIELD'}
+# 		    );
+# 		}
+# 
+# 		# Alias de vlan pour le cluster
+# 		if ( $nodeslast > 0 ) {
+# 		    if (!defined(
+# 			    $Z->{'ALIAS'}->{ $srv . $cnamindex . '.' . $lan }
+# 			)
+# 			)
+# 		    {
+# 			$Z->{'ALIAS'}->{ $srv . $cnamindex . '.' . $lan }
+# 			    = [];
+# 		    }
+# 		    if (scalar(
+# 			    grep( /^$nam$/,
+# 				$Z->{'ALIAS'}
+# 				    ->{ $srv . $cnamindex . '.' . $lan } )
+# 			) == 0
+# 			)
+# 		    {
+# 			push(
+# 			    @{  $Z->{'ALIAS'}
+# 				    ->{ $srv . $cnamindex . '.' . $lan }
+# 				},
+# 			    $M->{'zone'}->{$nam}->{'FIELD'}
+# 			);
+# 		    }
+# 		}
+# 
+# 		# Traduction du tag si format <iface>\.TAG[\d]+
+# 		if ( $j =~ /TAG[\d]+$/ ) {
+# 			$j =~ s/TAG[\d]+$/$Z->{'NETWORK'}->{'BY_NAME'}->{$lan}->{'tag'}/ ;
+# 		}
+# 
+# 		# Definition de l'entree dans /etc/network/interface
+# 		if ( defined( $S->{'dhcp'} ) && $i eq $S->{'dhcp'} ) {
+# 		    $M->{'ifup'}->{'dhcp'} = $j;
+# 		}
+# 		else {
+# 		    $M->{'ifup'}->{$nam} = $j;
+# 		}
+# 
+# 		# Traitement des routes
+# 		my $r;
+# 		foreach $r ( keys %{ $S->{$i} } ) {
+# 		    if ( $r =~ m/^(route|delroute)/ ) {
+# 			my $act = $1 ;
+# 			if ( ref ( $S->{$i}->{$r} ) eq 'HASH' ) {
+# 			    if ( defined $S->{$i}->{$r}->{$mnamindexnum} ) {
+# 				$M->{$act}->{$j}->{$r} = $S->{$i}->{$r}->{$mnamindexnum} ;
+# 			    } elsif ( ! defined $S->{$i}->{$r}->{'default'} ) {
+# 				Warn ( $ERR_SYNTAX, "No default route defined for interface ".$i." skipping this route for host $mnam" ) ;
+# 			    } else {
+# 				$M->{$act}->{$j}->{$r} = $S->{$i}->{$r}->{'default'} ;
+# 			    }
+# 			} else {
+# 			    $M->{$act}->{$j}->{$r} = $S->{$i}->{$r};
+# 			}
+# 		    }
+# 		}
+# 
+# 		# Traitement des mtu
+# 		if ( defined( $S->{$i}->{'mtu'} ) ) {
+# 		    $M->{'mtu'}->{$j} = $S->{$i}->{'mtu'};
+# 		}
+# 
+# 		# Traitement des media
+# 		if ( defined( $S->{$i}->{'media'} ) ) {
+# 		    $M->{'media'}->{$j} = $S->{$i}->{'media'};
+# 		}
+# 
+# 		# Traitement des noarp
+# 		if ( defined( $S->{$i}->{'noarp'} ) ) {
+# 		    $M->{'noarp'}->{$j} = $S->{$i}->{'noarp'};
+# 		}
+# 	    }
+# 
+# 	    # Definition des alias DNS
+# 	    foreach $j ( keys %{ $S->{'alias'} } ) {
+# 		my $lan;
+# 		my $nam;
+# 		my $addr;
+# 
+# 		# Alias par machine
+# 		$lan = $S->{'alias'}->{$j};
+# 		$nam = $j . $mnamindex;
+# 
+# 		# ne pas ecraser si shortname deja existant
+# 		if ( !defined $M->{'zone'}->{$nam} ) {
+# 		    $M->{'zone'}->{$nam}            = {};
+# 		    $M->{'zone'}->{$nam}->{'FIELD'} = $mnam . "." . $lan;
+# 		    $M->{'zone'}->{$nam}->{'TYPE'}  = 'CNAME';
+# 		}
+# 
+# 	     # Alias "round robin" pour l'ensemble de cette classe de serveurs
+# 		$nam = $mnam . "." . $lan;
+# 
+# 		#if ( !defined( $Z->{ALIAS}->{$j} ) ) {
+# 		#    $Z->{ALIAS}->{$j} = [];
+# 		#}
+# 		#push ( @{ $Z->{ALIAS}->{$j} }, $M->{zone}->{$nam}->{FIELD} );
+# 		if ( $s == 0 && $n == 0 && !defined $M->{'zone'}->{$j} ) {
+# 		    $M->{'zone'}->{$j}            = {};
+# 		    $M->{'zone'}->{$j}->{'FIELD'} = $srv . "." . $lan;
+# 		    $M->{'zone'}->{$j}->{'TYPE'}  = 'CNAME';
+# 		}
+# 		if (   $nodeslast > 0
+# 		    && $s == 0
+# 		    && $n == 0
+# 		    && !defined $M->{'zone'}->{ $j . $cnamindex } )
+# 		{
+# 		    $M->{'zone'}->{ $j . $cnamindex } = {};
+# 		    $M->{'zone'}->{ $j . $cnamindex }->{'FIELD'}
+# 			= $srv . $cnamindex . "." . $lan;
+# 		    $M->{'zone'}->{ $j . $cnamindex }->{'TYPE'} = 'CNAME';
+# 		}
+# 	    }
+# 
+# 	    # Insertion du serveur dans sa classe
+# 	    $N->{'SRVLIST'}->{$mnam} = $M;
+# 	}
+# 
+# 	# Vips du cluster
+#     }
+# 
+#     # Insertion de la classe de serveurs dans la structure principale
+#     if ( defined $S->{'shortname'} ) {
+# 	if ( defined $S->{'ipstart'}->{ $S->{'shortname'} } ) {
+# 	    $start = $S->{'ipstart'}->{ $S->{'shortname'} };
+# 	}
+# 	else {
+# 	    $start = $S->{'ipstart'}->{'default'};
+# 	}
+# 
+# 	my $srv_addr = Address ( $Z->{'NETWORK'}->{'BY_NAME'}->{ $S->{'shortname'} }->{'network'}, $start, 0 );
+# 	if ( defined $Z->{'SERVERS'}->{'BY_ADDR'}->{$srv_addr} ) {
+# 	    Warn ( $ERR_SYNTAX, "Address ".$srv_addr." for server ".$srv." is already in use" );
+# 	}
+# 	else {
+# 		push ( @{$Z->{'SERVERS'}->{'BY_ADDR'}->{$srv_addr}}, $N );
+# 	}
+#     }
+# 
+#     $Z->{'SERVERS'}->{'BY_NAME'}->{$srv} = $N;
+# 
+#     # Remapping UM
+#     if ($PFTOOLS_VARS->{'UML'}) {
+# 	my $mnam;
+# 	foreach $mnam ( keys %{ $N->{'SRVLIST'} } ) {
+# 	    UMRemap_If( $Z, $mnam );
+# 	}
+#     }
+# }
 
 #
 #	VOID Add_zone (HASHREF $Z, HASHREF $S, STRING $zone)
@@ -1594,84 +1966,84 @@
 #	dans la section $S
 #
 #================================================================================
-sub Add_zone {
-    my ( $Z, $S, $zone ) = @_;
-
-    my $c;
-    my $t_secs;
-    my $t_text;
-    my $mail;
-    my $soa;
-
-    # Verification de l'unicite de la declaration
-    if ( defined( $Z->{'SOA'}->{'name'} ) ) {
-	Abort( $ERR_SYNTAX,
-	          "Declaration zone dupliquee ("
-		. $Z->{'SOA'}->{'name'}
-		. ") et ("
-		. $zone
-		. ")" );
-    }
-
-    # Ajout des informations SOA
-    # Le numero de serie est genere automatiquement, on prends
-    # l'heure system en seconde.
-    # l'adresse mail est corrigee si besoin (@ => .)
-    # Les adresse SOA et Mail sont complettes (.$)
-
-    $t_secs = time();
-    $t_text = localtime($t_secs);
-
-    $mail = $S->{'mail'};
-    $mail =~ s/@/\./;
-    $mail =~ s/([^\.])$/$1./;
-
-    $soa = $S->{'soa'};
-    $soa =~ s/([^\.])$/$1./;
-
-    if ( defined $S->{'serial'} && $S->{'serial'} =~ m|([\d.]+)| ) {
-	my $rev = $1;
-
-	$rev =~ s/\.//g;
-
-	$Z->{'SOA'}->{'serial'}
-	    = $rev . "\t; Serial (" . $S->{'serial'} . ")";
-    }
-    else {
-	$Z->{'SOA'}->{'serial'} = $t_secs . "\t; Serial (" . $t_text . ")";
-    }
-    $Z->{'SOA'}->{'name'}    = $zone;
-    $Z->{'SOA'}->{'comment'} = $S->{'comment'}
-	|| "Zone $zone <no comment specified>";
-    $Z->{'SOA'}->{'soa'}     = $soa;
-    $Z->{'SOA'}->{'mail'}    = $mail;
-    $Z->{'SOA'}->{'refresh'} = $S->{'refresh'};
-    $Z->{'SOA'}->{'retry'}   = $S->{'retry'};
-    $Z->{'SOA'}->{'expire'}  = $S->{'expire'};
-    $Z->{'SOA'}->{'negttl'}  = $S->{'negttl'};
-    $Z->{'SOA'}->{'ttl'}     = $S->{'ttl'};
-
-    if ( defined $S->{'dhcpvlan'} ) {
-	@{ $Z->{'SOA'}->{'dhcpvlan'} } = split( /[,\s]+/, $S->{'dhcpvlan'} );
-    }
-    else {
-	@{ $Z->{SOA}->{'dhcpvlan'} } = @DEFAULTDHCPVLAN;
-    }
-
-    if ( $S->{'console'} and $S->{'console'} ne 'default' ) {
-	$Z->{SOA}->{'console'} = $S->{'console'};
-    }
-
-    # Ajout des champs NS
-    foreach $c ( sort ( keys %{ $S->{'ns'} } ) ) {
-	push( @{ $Z->{'NS'} }, $S->{'ns'}->{$c} );
-    }
-
-    # Ajout des champs MX
-    foreach $c ( sort ( keys %{ $S->{'mx'} } ) ) {
-	push( @{ $Z->{'MX'} }, $S->{'mx'}->{$c} );
-    }
-}
+# sub Add_zone {
+#     my ( $Z, $S, $zone ) = @_;
+# 
+#     my $c;
+#     my $t_secs;
+#     my $t_text;
+#     my $mail;
+#     my $soa;
+# 
+#     # Verification de l'unicite de la declaration
+#     if ( defined( $Z->{'SOA'}->{'name'} ) ) {
+# 	Abort( $ERR_SYNTAX,
+# 	          "Declaration zone dupliquee ("
+# 		. $Z->{'SOA'}->{'name'}
+# 		. ") et ("
+# 		. $zone
+# 		. ")" );
+#     }
+# 
+#     # Ajout des informations SOA
+#     # Le numero de serie est genere automatiquement, on prends
+#     # l'heure system en seconde.
+#     # l'adresse mail est corrigee si besoin (@ => .)
+#     # Les adresse SOA et Mail sont complettes (.$)
+# 
+#     $t_secs = time();
+#     $t_text = localtime($t_secs);
+# 
+#     $mail = $S->{'mail'};
+#     $mail =~ s/@/\./;
+#     $mail =~ s/([^\.])$/$1./;
+# 
+#     $soa = $S->{'soa'};
+#     $soa =~ s/([^\.])$/$1./;
+# 
+#     if ( defined $S->{'serial'} && $S->{'serial'} =~ m|([\d.]+)| ) {
+# 	my $rev = $1;
+# 
+# 	$rev =~ s/\.//g;
+# 
+# 	$Z->{'SOA'}->{'serial'}
+# 	    = $rev . "\t; Serial (" . $S->{'serial'} . ")";
+#     }
+#     else {
+# 	$Z->{'SOA'}->{'serial'} = $t_secs . "\t; Serial (" . $t_text . ")";
+#     }
+#     $Z->{'SOA'}->{'name'}    = $zone;
+#     $Z->{'SOA'}->{'comment'} = $S->{'comment'}
+# 	|| "Zone $zone <no comment specified>";
+#     $Z->{'SOA'}->{'soa'}     = $soa;
+#     $Z->{'SOA'}->{'mail'}    = $mail;
+#     $Z->{'SOA'}->{'refresh'} = $S->{'refresh'};
+#     $Z->{'SOA'}->{'retry'}   = $S->{'retry'};
+#     $Z->{'SOA'}->{'expire'}  = $S->{'expire'};
+#     $Z->{'SOA'}->{'negttl'}  = $S->{'negttl'};
+#     $Z->{'SOA'}->{'ttl'}     = $S->{'ttl'};
+# 
+#     if ( defined $S->{'dhcpvlan'} ) {
+# 	@{ $Z->{'SOA'}->{'dhcpvlan'} } = split( /[,\s]+/, $S->{'dhcpvlan'} );
+#     }
+#     else {
+# 	@{ $Z->{SOA}->{'dhcpvlan'} } = @DEFAULTDHCPVLAN;
+#     }
+# 
+#     if ( $S->{'console'} and $S->{'console'} ne 'default' ) {
+# 	$Z->{SOA}->{'console'} = $S->{'console'};
+#     }
+# 
+#     # Ajout des champs NS
+#     foreach $c ( sort ( keys %{ $S->{'ns'} } ) ) {
+# 	push( @{ $Z->{'NS'} }, $S->{'ns'}->{$c} );
+#     }
+# 
+#     # Ajout des champs MX
+#     foreach $c ( sort ( keys %{ $S->{'mx'} } ) ) {
+# 	push( @{ $Z->{'MX'} }, $S->{'mx'}->{$c} );
+#     }
+# }
 
 #
 #	VOID Add_network (HASHREF $Z, HASHREF $S, STRING $net)
@@ -1680,48 +2052,48 @@
 #	En entree $S contient les informations sur les reseaux de type $net
 #
 #===================================================================================
-sub Add_network {
-    my ( $Z, $S, $net ) = @_;
-
-    my $N = {};
-
-    # Verification des declarations
-    if ( !defined( $S->{'network'} ) ) {
-	Abort( $ERR_SYNTAX,
-	    "Adresse de reseau manquante pour le reseau " . $net );
-    }
-
-    if ( !defined( $S->{'netmask'} ) ) {
-	Abort( $ERR_SYNTAX,
-	    "Masque de reseau manquant pour le reseau " . $net );
-    }
-
-    if ( defined( $Z->{'NETWORK'}->{'BY_ADDR'}->{ $S->{'network'} } ) ) {
-	Abort( $ERR_SYNTAX,
-	          "Adresse de reseau dupliquee ("
-		. $S->{'network'}
-		. ") pour le reseau "
-		. $net . " avec le reseau "
-		. $Z->{'NETWORK'}->{'BY_ADDR'}->{ $S->{'network'} }->{'name'} );
-    }
-
-    # Calcul des adresses, netmasks et broadcasts
-    $N->{'name'}      = $net;
-    $N->{'network'}   = $S->{'network'};
-    $N->{'netmask'}   = $S->{'netmask'};
-    $N->{'broadcast'} = Broadcast( $N->{'network'}, $N->{'netmask'} );
-    $N->{'prefix'}    = netmask2prefix( $S->{'netmask'} );
-    $N->{'mtu'}       = $S->{'mtu'};
-    $N->{'tag'}       = $S->{'tag'};
-    $N->{'media'}     = $S->{'media'};
-    $N->{'comment'}   = $S->{'comment'}
-	|| "Network $net <no comment specified>";
-    $N->{'scope'}     = $S->{'scope'} if ( defined $S->{'scope'} );
-
-    # Insertion dans la structure principale
-    $Z->{'NETWORK'}->{'BY_ADDR'}->{ $N->{'network'} } = $N;
-    $Z->{'NETWORK'}->{'BY_NAME'}->{ $N->{'name'} }    = $N;
-}
+# sub Add_network {
+#     my ( $Z, $S, $net ) = @_;
+# 
+#     my $N = {};
+# 
+#     # Verification des declarations
+#     if ( !defined( $S->{'network'} ) ) {
+# 	Abort( $ERR_SYNTAX,
+# 	    "Adresse de reseau manquante pour le reseau " . $net );
+#     }
+# 
+#     if ( !defined( $S->{'netmask'} ) ) {
+# 	Abort( $ERR_SYNTAX,
+# 	    "Masque de reseau manquant pour le reseau " . $net );
+#     }
+# 
+#     if ( defined( $Z->{'NETWORK'}->{'BY_ADDR'}->{ $S->{'network'} } ) ) {
+# 	Abort( $ERR_SYNTAX,
+# 	          "Adresse de reseau dupliquee ("
+# 		. $S->{'network'}
+# 		. ") pour le reseau "
+# 		. $net . " avec le reseau "
+# 		. $Z->{'NETWORK'}->{'BY_ADDR'}->{ $S->{'network'} }->{'name'} );
+#     }
+# 
+#     # Calcul des adresses, netmasks et broadcasts
+#     $N->{'name'}      = $net;
+#     $N->{'network'}   = $S->{'network'};
+#     $N->{'netmask'}   = $S->{'netmask'};
+#     $N->{'broadcast'} = Broadcast( $N->{'network'}, $N->{'netmask'} );
+#     $N->{'prefix'}    = netmask2prefix( $S->{'netmask'} );
+#     $N->{'mtu'}       = $S->{'mtu'};
+#     $N->{'tag'}       = $S->{'tag'};
+#     $N->{'media'}     = $S->{'media'};
+#     $N->{'comment'}   = $S->{'comment'}
+# 	|| "Network $net <no comment specified>";
+#     $N->{'scope'}     = $S->{'scope'} if ( defined $S->{'scope'} );
+# 
+#     # Insertion dans la structure principale
+#     $Z->{'NETWORK'}->{'BY_ADDR'}->{ $N->{'network'} } = $N;
+#     $Z->{'NETWORK'}->{'BY_NAME'}->{ $N->{'name'} }    = $N;
+# }
 
 #
 #	STRING Host_class (STRING $host)




More information about the pf-tools-commits mailing list