Author: arkurth
Date: Fri Dec 12 20:17:47 2014
New Revision: 1645057

URL: http://svn.apache.org/r1645057
Log:
VCL-174
Changed iptables.pm::initialize to only check for the iptables command, not the 
service. The command can be used if firewalld is used.

Updated configure_nat to figure out the internal network address and network 
bits. The MASQUERADE rule was tightened so that it matches only if the 
destination address is not on the internal network to allow things to work if 
the public and internal networks are using the same interface.

Added check to Windows.pm::grant_access when process_connect_methods is called. 
It was not returning if process_connect_methods failed. As a result, the 
reservation did not fail when it should have.

Other
Updated Linux.pm::update_public_hostname. It was generating unnecessary 
warnings if the public IP address did not resolve. Added 
utils.pm::ip_address_to_hostname. This is called by update_public_hostname 
instead of running ipcalc. If the hostname can't be resolved the hostname is 
set to the name in the VCL database.

Updated Linux.pm::set_static_public_address to continue to try to set the 
default route even if the IP address is correct to begin with.

Modified:
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
    vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Fri Dec 12 20:17:47 2014
@@ -2112,7 +2112,7 @@ sub remove_lines_from_file {
 =cut
 
 sub execute {
-#return execute_new(@_);
+       my @original_arguments = @_;
        my ($argument) = @_;
        my ($computer_name, $command, $display_output, $timeout_seconds, 
$max_attempts, $port, $user, $password, $identity_key, $ignore_error);
        
@@ -2178,6 +2178,11 @@ sub execute {
                return;
        }
        
+       # TESTING: use the new subroutine if $ENV{execute_new} is set and the 
command isn't one that's known to fail with the new subroutine
+       if ($ENV{execute_new} && $command !~ 
/(vmkfstools|qemu-img|Convert-VHD|scp)/) {
+               return execute_new(@original_arguments);
+       }
+       
        my $arguments = {
                node => $computer_name,
                command => $command,

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Fri Dec 12 20:17:47 2014
@@ -644,8 +644,7 @@ sub update_public_hostname {
                return;
        }
        
-       my $management_node_keys = $self->data->get_management_node_keys();
-       my $computer_node_name   = $self->data->get_computer_node_name();
+       my $computer_node_name = $self->data->get_computer_node_name();
        
        # Get the IP address of the public adapter
        my $public_ip_address = $self->get_public_ip_address();
@@ -654,42 +653,11 @@ sub update_public_hostname {
                return;
        }
        notify($ERRORS{'DEBUG'}, 0, "retrieved public IP address of 
$computer_node_name: $public_ip_address");
-       sleep 5;
        
        # Get the hostname for the public IP address
-       my $ipcalc_command = "/bin/ipcalc --hostname $public_ip_address";
-       my ($ipcalc_exit_status, $ipcalc_output) = run_command($ipcalc_command);
-       if (!defined($ipcalc_output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to run ipcalc command on 
management node to determine public hostname of $computer_node_name, command: 
'$ipcalc_command'");
-               return;
-       }
-       
-       my ($public_hostname) = ("@$ipcalc_output" =~ /HOSTNAME=(.*)/i);
-       if ($public_hostname) {
-               notify($ERRORS{'DEBUG'}, 0, "determined registered public 
hostname of $computer_node_name ($public_ip_address) by running ipcalc on the 
management node: '$public_hostname'");
-       }
-       else {
-               notify($ERRORS{'DEBUG'}, 0, "failed to determine registered 
public hostname of $computer_node_name ($public_ip_address), command: 
'$ipcalc_command', output:\n" . join("\n", @$ipcalc_output));
-               
-               # Attempt to run the ipcalc command on the host
-               my ($ipcalc_exit_status, $ipcalc_output) = 
$self->execute($ipcalc_command);
-               if (!defined($ipcalc_output)) {
-                       notify($ERRORS{'WARNING'}, 0, "failed to run ipcalc 
command on $computer_node_name to determine its public hostname, command: 
'$ipcalc_command'");
-                       return;
-               }
-               
-               ($public_hostname) = ("@$ipcalc_output" =~ /HOSTNAME=(.*)/i);
-               if ($public_hostname) {
-                       notify($ERRORS{'DEBUG'}, 0, "determined registered 
public hostname of $computer_node_name ($public_ip_address) by running ipcalc 
on $computer_node_name: '$public_hostname'");
-               }
-               else {
-                       notify($ERRORS{'WARNING'}, 0, "failed to determine 
registered public hostname of $computer_node_name ($public_ip_address) by 
running ipcalc on either the management node or $computer_node_name, command: 
'$ipcalc_command', output:\n" . join("\n", @$ipcalc_output));
-                       return;
-               }
-       }
+       my $public_hostname = ip_address_to_hostname($public_ip_address) || 
$computer_node_name;
        
        # Set the node's hostname to public hostname
-
        if ($self->can("update_hostname_file")) {
                if (!$self->update_hostname_file($public_hostname)) {
                        notify($ERRORS{'WARNING'}, 0, "failed to update 
hostname file");
@@ -712,10 +680,8 @@ sub update_public_hostname {
        }
        
        return 1;
-
 }
 
-
 #/////////////////////////////////////////////////////////////////////////////
 
 =head2 update_hostname_file
@@ -856,43 +822,40 @@ EOF
        # Get the current public IP address being used by the computer
        # Pass the $ignore_error flag to prevent warnings if not defined
        my $current_public_ip_address = $self->get_public_ip_address(1);
-       if ($current_public_ip_address) {
-               if ($current_public_ip_address eq $computer_public_ip_address) {
-                       notify($ERRORS{'DEBUG'}, 0, "static public IP address 
does not need to be set, $computer_name is already configured to use 
$current_public_ip_address");
-                       return 1;
+       if ($current_public_ip_address && $current_public_ip_address eq 
$computer_public_ip_address) {
+               notify($ERRORS{'DEBUG'}, 0, "static public IP address does not 
need to be set, $computer_name is already configured to use 
$current_public_ip_address");
+       }
+       else {
+               if ($current_public_ip_address) {
+                       notify($ERRORS{'DEBUG'}, 0, "static public IP address 
needs to be set, public IP address currently being used by $computer_name 
$current_public_ip_address does NOT match correct public IP address: 
$computer_public_ip_address");
                }
                else {
-                       notify($ERRORS{'DEBUG'}, 0, "static public IP address 
needs to be set, public IP address currently being used by $computer_name 
$current_public_ip_address does NOT match correct public IP address: 
$computer_public_ip_address");
+                       notify($ERRORS{'DEBUG'}, 0, "static public IP address 
needs to be set, unable to determine public IP address currently in use on 
$computer_name");
                }
-       }
-       else {
-               notify($ERRORS{'DEBUG'}, 0, "static public IP address needs to 
be set, unable to determine public IP address currently in use on 
$computer_name");
-       }
-       
-       
-       # Make sure required info was retrieved
-       if ("$computer_public_ip_address $subnet_mask $default_gateway" =~ 
/undefined/) {
-               notify($ERRORS{'WARNING'}, 0, "failed to retrieve required 
network configuration for $computer_name:\n$configuration_info_string");
-               return;
-       }
-       else {
-               notify($ERRORS{'OK'}, 0, "attempting to set static public IP 
address on $computer_name:\n$configuration_info_string");
-       }
-       
-       # Try to ping address to make sure it's available
-       # FIXME  -- need to add other tests for checking ip_address is or is 
not available.
-       if ((_pingnode($computer_public_ip_address))) {
-               notify($ERRORS{'WARNING'}, 0, "ip_address 
$computer_public_ip_address is pingable, can not assign to $computer_name ");
-               return;
-       }
-       
-       # Assemble the ifcfg file path
-       my $network_scripts_path = "/etc/sysconfig/network-scripts";
-       my $ifcfg_file_path      = 
"$network_scripts_path/ifcfg-$interface_name";
-       notify($ERRORS{'DEBUG'}, 0, "public interface ifcfg file path: 
$ifcfg_file_path");
-       
-       # Assemble the ifcfg file contents
-       my $ifcfg_contents = <<EOF;
+               
+               # Make sure required info was retrieved
+               if ("$computer_public_ip_address $subnet_mask $default_gateway" 
=~ /undefined/) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to retrieve 
required network configuration for 
$computer_name:\n$configuration_info_string");
+                       return;
+               }
+               else {
+                       notify($ERRORS{'OK'}, 0, "attempting to set static 
public IP address on $computer_name:\n$configuration_info_string");
+               }
+               
+               # Try to ping address to make sure it's available
+               # FIXME  -- need to add other tests for checking ip_address is 
or is not available.
+               if ((_pingnode($computer_public_ip_address))) {
+                       notify($ERRORS{'WARNING'}, 0, "ip_address 
$computer_public_ip_address is pingable, can not assign to $computer_name ");
+                       return;
+               }
+               
+               # Assemble the ifcfg file path
+               my $network_scripts_path = "/etc/sysconfig/network-scripts";
+               my $ifcfg_file_path      = 
"$network_scripts_path/ifcfg-$interface_name";
+               notify($ERRORS{'DEBUG'}, 0, "public interface ifcfg file path: 
$ifcfg_file_path");
+               
+               # Assemble the ifcfg file contents
+               my $ifcfg_contents = <<EOF;
 DEVICE=$interface_name
 BOOTPROTO=static
 IPADDR=$computer_public_ip_address
@@ -902,25 +865,35 @@ STARTMODE=onboot
 ONBOOT=yes
 EOF
        
-       # Echo the contents to the ifcfg file
-       my $echo_ifcfg_command = "echo \"$ifcfg_contents\" > $ifcfg_file_path";
-       my ($echo_ifcfg_exit_status, $echo_ifcfg_output) = 
$self->execute($echo_ifcfg_command);
-       if (!defined($echo_ifcfg_output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to run command to 
recreate $ifcfg_file_path on $computer_name: '$echo_ifcfg_command'");
-               return;
-       }
-       elsif ($echo_ifcfg_exit_status || grep(/echo:/i, @$echo_ifcfg_output)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to recreate 
$ifcfg_file_path on $computer_name, exit status: $echo_ifcfg_exit_status, 
command: '$echo_ifcfg_command', output:\n" . join("\n", @$echo_ifcfg_output));
-               return;
-       }
-       else {
-               notify($ERRORS{'DEBUG'}, 0, "recreated $ifcfg_file_path on 
$computer_name:\n$ifcfg_contents");
-       }
-       
-       # Restart the interface
-       if (!$self->restart_network_interface($interface_name)) {
-               notify($ERRORS{'WARNING'}, 0, "failed to restart public 
interface $interface_name on $computer_name");
-               return;
+               # Echo the contents to the ifcfg file
+               my $echo_ifcfg_command = "echo \"$ifcfg_contents\" > 
$ifcfg_file_path";
+               my ($echo_ifcfg_exit_status, $echo_ifcfg_output) = 
$self->execute($echo_ifcfg_command);
+               if (!defined($echo_ifcfg_output)) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to run command to 
recreate $ifcfg_file_path on $computer_name: '$echo_ifcfg_command'");
+                       return;
+               }
+               elsif ($echo_ifcfg_exit_status || grep(/echo:/i, 
@$echo_ifcfg_output)) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to recreate 
$ifcfg_file_path on $computer_name, exit status: $echo_ifcfg_exit_status, 
command: '$echo_ifcfg_command', output:\n" . join("\n", @$echo_ifcfg_output));
+                       return;
+               }
+               else {
+                       notify($ERRORS{'DEBUG'}, 0, "recreated $ifcfg_file_path 
on $computer_name:\n$ifcfg_contents");
+               }
+               
+               # Restart the interface
+               if (!$self->restart_network_interface($interface_name)) {
+                       notify($ERRORS{'WARNING'}, 0, "failed to restart public 
interface $interface_name on $computer_name");
+                       return;
+               }
+               
+               my $ext_sshd_config_file_path = '/etc/ssh/external_sshd_config';
+               if ($self->file_exists($ext_sshd_config_file_path)) {
+                       # Remove existing ListenAddress lines from 
external_sshd_config
+                       
$self->remove_lines_from_file($ext_sshd_config_file_path, 'ListenAddress') || 
return;
+                       
+                       # Add ListenAddress line to the end of the file
+                       $self->append_text_file($ext_sshd_config_file_path, 
"ListenAddress $computer_public_ip_address\n") || return;
+               }
        }
        
        # Delete existing default route
@@ -956,14 +929,6 @@ EOF
                notify($ERRORS{'DEBUG'}, 0, "added default route to 
$default_gateway on public interface $interface_name on $computer_name, 
output:\n" . format_data($route_add_output));
        }
        
-       my $ext_sshd_config_file_path = '/etc/ssh/external_sshd_config';
-       
-       # Remove existing ListenAddress lines from external_sshd_config
-       $self->remove_lines_from_file($ext_sshd_config_file_path, 
'ListenAddress') || return;
-       
-       # Add ListenAddress line to the end of the file
-       $self->append_text_file($ext_sshd_config_file_path, "ListenAddress 
$computer_public_ip_address\n") || return;
-       
        # Update resolv.conf if DNS server address is configured for the 
management node
        my $resolv_conf_path = "/etc/resolv.conf";
        if (@dns_servers) {
@@ -2401,8 +2366,8 @@ sub get_network_configuration {
                elsif (!defined($network_configuration->{$interface_name})) {
                        notify($ERRORS{'WARNING'}, 0, "found default gateway 
for '$interface_name' interface but the network configuration for 
'$interface_name' was not previously retrieved, route output:\n" . join("\n", 
@$route_output) . "\nnetwork configuation:\n" . 
format_data($network_configuration));
                }
-               elsif 
(defined($network_configuration->{$interface_name}{default_gateway})) {
-                       notify($ERRORS{'WARNING'}, 0, "multiple default gateway 
are configured for '$interface_name' interface, route output:\n" . join("\n", 
@$route_output));
+               elsif 
(defined($network_configuration->{$interface_name}{default_gateway}) && 
$default_gateway ne $network_configuration->{$interface_name}{default_gateway}) 
{
+                       notify($ERRORS{'WARNING'}, 0, "multiple default 
gateways are configured for '$interface_name' interface, route output:\n" . 
join("\n", @$route_output));
                }
                else {
                        
$network_configuration->{$interface_name}{default_gateway} = $default_gateway;

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm 
(original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Linux/firewall/iptables.pm Fri 
Dec 12 20:17:47 2014
@@ -89,8 +89,8 @@ sub initialize {
        
        notify($ERRORS{'DEBUG'}, 0, "initializing " . ref($self) . " object to 
control $computer_name");
        
-       if (!$self->service_exists('iptables')) {
-               notify($ERRORS{'DEBUG'}, 0, ref($self) . " object not 
initialized to control $computer_name, iptables service does not exist");
+       if (!$self->command_exists('iptables')) {
+               notify($ERRORS{'DEBUG'}, 0, ref($self) . " object not 
initialized to control $computer_name, iptables command does not exist");
                return 0;
        }
        
@@ -641,6 +641,9 @@ sub configure_nat {
        # Figure out the public and internal interface names
        my $public_interface_name;
        my $internal_interface_name;
+       my $public_subnet_mask;
+       my $internal_subnet_mask;
+       
        my $network_configuration = $self->get_network_configuration();
        for my $interface_name (keys %$network_configuration) {
                my @ip_addresses = keys 
%{$network_configuration->{$interface_name}{ip_address}};
@@ -648,11 +651,13 @@ sub configure_nat {
                # Check if the interface is assigned the nathost.publicIPaddress
                if (grep { $_ eq $public_ip_address } @ip_addresses) {
                        $public_interface_name = $interface_name;
+                       $public_subnet_mask = 
$network_configuration->{$interface_name}{ip_address}{$public_ip_address};
                }
                
                # If nathost.internalIPaddress is set, check if interface is 
assigned matching IP address
                if (grep { $_ eq $internal_ip_address } @ip_addresses) {
                        $internal_interface_name = $interface_name;
+                       $internal_subnet_mask = 
$network_configuration->{$interface_name}{ip_address}{$internal_ip_address};
                }
        }
        if (!$public_interface_name) {
@@ -663,9 +668,11 @@ sub configure_nat {
                notify($ERRORS{'WARNING'}, 0, "failed to configure NAT host 
$computer_name, no interface is assigned the internal IP address configured in 
the nathost table: $internal_ip_address\n" . 
format_data($network_configuration));
                return;
        }
+       my ($public_network_address, $public_network_bits) = 
ip_address_to_network_address($public_ip_address, $public_subnet_mask);
+       my ($internal_network_address, $internal_network_bits) = 
ip_address_to_network_address($internal_ip_address, $internal_subnet_mask);
        notify($ERRORS{'DEBUG'}, 0, "determined NAT host interfaces:\n" .
-               "public: $public_interface_name ($public_ip_address)\n" .
-               "internal: $internal_interface_name: ($internal_ip_address)"
+               "public - interface: $public_interface_name, IP address: 
$public_ip_address/$public_subnet_mask, network: 
$public_network_address/$public_network_bits\n" .
+               "internal - interface: $internal_interface_name, IP address: 
$internal_ip_address/$internal_subnet_mask, network: 
$internal_network_address/$internal_network_bits"
        );
        
        my $natport_ranges_variable = get_variable('natport_ranges') || 
'49152-65535';
@@ -685,6 +692,7 @@ sub configure_nat {
                'chain' => 'POSTROUTING',
                'parameters' => {
                        'out-interface' => $public_interface_name,
+                       '!destination' => 
"$internal_network_address/$internal_network_bits",
                        'jump' => 'MASQUERADE',
                },
                'match_extensions' => {
@@ -706,7 +714,7 @@ sub configure_nat {
                },
                'match_extensions' => {
                        'state' => {
-                               'state' => 'RELATED,ESTABLISHED',
+                               'state' => 'NEW,RELATED,ESTABLISHED',
                        },
                        'multiport' => {
                                'destination-ports' => $destination_ports,
@@ -726,7 +734,7 @@ sub configure_nat {
                },
                'match_extensions' => {
                        'state' => {
-                               'state' => 'RELATED,ESTABLISHED',
+                               'state' => 'NEW,RELATED,ESTABLISHED',
                        },
                        'multiport' => {
                                'destination-ports' => $destination_ports,

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Fri Dec 12 20:17:47 
2014
@@ -1101,6 +1101,10 @@ sub grant_access {
        if ($self->process_connect_methods("", 1) ) {
                notify($ERRORS{'OK'}, 0, "processed connection methods on 
$computer_node_name");
        }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to process connection 
methods on $computer_node_name");
+               return;
+       }
 
        # If this is an imaging request, make sure the Administrator account is 
enabled
        if ($request_forimaging) {

Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1645057&r1=1645056&r2=1645057&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Fri Dec 12 20:17:47 2014
@@ -78,7 +78,8 @@ use XML::Simple;
 use Time::HiRes qw(gettimeofday tv_interval);
 use Crypt::OpenSSL::RSA;
 use B qw(svref_2object);
-use Socket qw(inet_ntoa);
+use Socket;
+use Net::Netmask;
 
 BEGIN {
        $ENV{PERL_RL} = 'Perl';
@@ -186,6 +187,8 @@ our @EXPORT = qw(
        insert_reload_request
        insert_request
        insertloadlog
+       ip_address_to_hostname
+       ip_address_to_network_address
        is_inblockrequest
        is_ip_assigned_query
        is_management_node_process_running
@@ -3990,8 +3993,11 @@ sub run_ssh_command {
        $port = 22 if (!$port);
        $timeout_seconds = 0 if (!$timeout_seconds);
        $identity_paths = get_management_node_info()->{keys} if (!defined 
$identity_paths || length($identity_paths) == 0);
-
-#return VCL::Module::OS::execute_new($node, $command, $output_level, 
$timeout_seconds, $max_attempts, $port, $user, '', $identity_paths);
+       
+       # TESTING: use the new subroutine if $ENV{execute_new} is set and the 
command isn't one that's known to fail with the new subroutine
+       if ($ENV{execute_new} && $command !~ 
/(vmkfstools|qemu-img|Convert-VHD|scp)/) {
+               return VCL::Module::OS::execute_new($node, $command, 
$output_level, $timeout_seconds, $max_attempts, $port, $user, '', 
$identity_paths);
+       }
        
        # TODO: Add ssh path to config file and set global variable
        # Locate the path to the ssh binary
@@ -12401,6 +12407,33 @@ sub hostname_to_ip_address {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 ip_address_to_hostname
+
+ Parameters  : $ip_address
+ Returns     : string
+ Description : Calls gethostbyaddr on the management node to determine the
+               hostname an IP address resolves to. The hostname is returned. If
+               the IP address cannot be resolved or if an error occurs, null is
+               returned.
+
+=cut
+
+sub ip_address_to_hostname {
+       my ($ip_address) = @_;
+       
+       my $hostname = gethostbyaddr(inet_aton($ip_address), AF_INET);
+       if (defined $hostname) {
+               notify($ERRORS{'DEBUG'}, 0, "determined hostname from IP 
address $ip_address: $hostname");
+               return $hostname;
+       }
+       else {
+               notify($ERRORS{'DEBUG'}, 0, "unable to determine hostname from 
IP address: $ip_address");
+               return;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 =head2 update_request_checkuser
 
  Parameters  : $request_id, $checkuser
@@ -12540,6 +12573,45 @@ EOF
 }
 
 #/////////////////////////////////////////////////////////////////////////////
+
+=head2 ip_address_to_network_address
+
+ Parameters  : $ip_address, $subnet_mask
+ Returns     : If called in array context: ($network_address, $network_bits)
+               If called in scalar context: $network_address
+ Description : Determines a network address and network bits.
+
+=cut
+
+sub ip_address_to_network_address {
+       my ($ip_address, $subnet_mask) = @_;
+       if (!defined($ip_address)) {
+               notify($ERRORS{'WARNING'}, 0, "$ip_address argument was not 
supplied");
+               return;
+       }
+       if (!defined($subnet_mask)) {
+               notify($ERRORS{'WARNING'}, 0, "$subnet_mask argument was not 
supplied");
+               return;
+       }
+       
+       my $netmask_object = new Net::Netmask("$ip_address/$subnet_mask");
+       if(!$netmask_object) {
+               notify($ERRORS{'WARNING'}, 0, "failed to create Net::Netmask 
object, IP address: $ip_address, subnet mask: $subnet_mask");
+               return;
+       }
+       
+       my $network_address = $netmask_object->base();
+       my $network_bits = $netmask_object->bits();
+       notify($ERRORS{'DEBUG'}, 0, "$ip_address/$subnet_mask --> 
$network_address/$network_bits");
+       if (wantarray) {
+               return ($network_address, $network_bits);
+       }
+       else {
+               return $network_address;
+       }
+}
+
+#/////////////////////////////////////////////////////////////////////////////
 
 1;
 __END__


Reply via email to