# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#-------------------------------------------------------

=head1

	This is a utility plugin for z/VM.

=cut

#-------------------------------------------------------
package xCAT::zvmUtils;
use xCAT::MsgUtils;
use xCAT::Utils;
use xCAT::Table;
use strict;
use warnings;
1;

#-------------------------------------------------------

=head3   getNodeProps
	Description	: Get node properties
    Arguments	: 	Table
    				Node
    				Properties
    Returns		: Properties from specifed table
    Example		: my $propVals = xCAT::zvmUtils->getNodeProps($tabName, $node, $propNames);
    
=cut

#-------------------------------------------------------
sub getNodeProps {

	# Get inputs
	my ( $class, $tabName, $node, @propNames ) = @_;

	# Get specified table
	my $tab = xCAT::Table->new($tabName);

	# Get value from column
	my $propVals = $tab->getNodeAttribs( $node, [@propNames] );
	return ($propVals);
}

#-------------------------------------------------------

=head3   getTabPropsByKey
	Description	: Get node properties by key
    Arguments	: 	Table
    				Key
    				Key value
    				Requested properties
    Returns		: Properties from specifed table
    Example		: my $propVals = xCAT::zvmUtils->getTabPropsByKey($tabName, $key, $keyValue, @reqProps);
    
=cut

#-------------------------------------------------------
sub getTabPropsByKey {

	# Get inputs
	my ( $class, $tabName, $key, $keyVal, @propNames ) = @_;

	# Get specified table
	my $tab = xCAT::Table->new($tabName);
	my $propVals;

	# Get table attributes matching specified key
	$propVals = $tab->getAttribs( { $key => $keyVal }, @propNames );
	return ($propVals);
}

#-------------------------------------------------------

=head3   setNodeProp

	Description	: Set node property
    Arguments	: 	Table
    				Node
    				Property
    Returns		: Nothing
    Example		: xCAT::zvmUtils->setNodeProp($tabName, $node, $propName, $propVal);
    
=cut

#-------------------------------------------------------
sub setNodeProp {

	# Get inputs
	my ( $class, $tabName, $node, $propName, $propVal ) = @_;

	# Get specified table
	my $tab = xCAT::Table->new( $tabName, -create => 1, -autocommit => 0 );

	# Set property
	$tab->setAttribs( { 'node' => $node }, { $propName => $propVal } );

	# Save table
	$tab->commit;

	return;
}

#-------------------------------------------------------

=head3   delTabEntry

	Description	: Delete node
    Arguments	: 	Table
    				Node 
    Returns		: Nothing
    Example		: xCAT::zvmUtils->delTabEntry($tabName, $node);
    
=cut

#-------------------------------------------------------
sub delTabEntry {

	# Get inputs
	my ( $class, $tabName, $node ) = @_;

	# Get specified table
	my $tab = xCAT::Table->new( $tabName, -create => 1, -autocommit => 0 );

	# Delete node from table
	my %key = ( 'node' => $node );
	$tab->delEntries( \%key );

	# Save table
	$tab->commit;

	return;
}

#-------------------------------------------------------

=head3   tabStr

	Description	: Tab string (4 spaces)
    Arguments	: String
    Returns		: Tabbed string
    Example		: my $str = xCAT::zvmUtils->tabStr($str);
    
=cut

#-------------------------------------------------------
sub tabStr {

	# Get inputs
	my ( $class, $inStr ) = @_;
	my @lines = split( "\n", $inStr );

	# Tab output
	my $outStr;
	foreach (@lines) {
		$outStr .= "    $_\n";
	}

	return ($outStr);
}

#-------------------------------------------------------

=head3   trimStr

	Description	: Trim whitespaces in string
    Arguments	: String
    Returns		: Trimmed string
    Example		: my $str = xCAT::zvmUtils->trimStr($str);
    
=cut

#-------------------------------------------------------
sub trimStr {

	# Get string
	my ( $class, $str ) = @_;

	# Trim right
	$str =~ s/\s*$//;

	# Trim left
	$str =~ s/^\s*//;

	return ($str);
}

#-------------------------------------------------------

=head3   replaceStr

	Description	: Replace string
    Arguments	: String
    Returns		: Replaced string
    Example		: my $str = xCAT::zvmUtils->replaceStr($str, $pattern, $replacement);
    
=cut

#-------------------------------------------------------
sub replaceStr {

	# Get string
	my ( $class, $str, $pattern, $replacement ) = @_;

	# Replace string
	$str =~ s/$pattern/$replacement/g;

	return ($str);
}

#-------------------------------------------------------

=head3   printLn

	Description	: Print string
    Arguments	: String
    Returns		: Nothing
    Example		: xCAT::zvmUtils->printLn($callback, $str);
    
=cut

#-------------------------------------------------------
sub printLn {

	# Get inputs
	my ( $class, $callback, $str ) = @_;

	# Print string
	my $rsp;
	$rsp->{data}->[0] = "$str";
	xCAT::MsgUtils->message( "I", $rsp, $callback );

	return;
}

#-------------------------------------------------------

=head3   isZvmNode

	Description	: Check if a node is in the 'zvm' table
    Arguments	: Node
    Returns		: 	TRUE	Node exists
    				FALSE	Node does not exists
    Example		: my $out = xCAT::zvmUtils->isZvmNode($node);
    
=cut

#-------------------------------------------------------
sub isZvmNode {

	# Get inputs
	my ( $class, $node ) = @_;

	# zVM guest ID
	my $id;

	# Look in 'zvm' table
	my $tab = xCAT::Table->new( 'zvm', -create => 1, -autocommit => 0 );

	my @results = $tab->getAllAttribsWhere( "node like '%" . $node . "%'", 'userid' );
	foreach (@results) {
		$id = $_->{'userid'};

		# Get userID if one is not in the table
		if ($id) {
			return ('TRUE');
		}
	}

	return ('FALSE');
}

#-------------------------------------------------------

=head3   getIp

	Description	: Get IP address of given node
    Arguments	: Node
    Returns		: IP address
    Example		: my $ip = xCAT::zvmUtils->getIp($node);
    
=cut

#-------------------------------------------------------
sub getIp {

	# Get inputs
	my ( $class, $node ) = @_;

	# Get IP address
	my $out   = `ssh -o ConnectTimeout=10 $node "ifconfig" | grep "inet addr:" | grep -v "127.0.0.1"`;
	my @lines = split( '\n', $out );

	# Get the first IP that comes back
	my @parms = split( ' ', $lines[0] );
	foreach (@parms) {

		# Get inet addr parameter
		if ( $_ =~ m/addr:/i ) {
			my @ip = split( ':', $_ );
			return ( $ip[1] );
		}
	}

	return;
}

#-------------------------------------------------------

=head3   getIfcfg

	Description	: 	Get network configuration file path for given node
					Red Hat -- 	/etc/sysconfig/network-scripts/ifcfg-eth
					SUSE 	-- 	/etc/sysconfig/network/ifcfg-qeth
    Arguments	: Node
    Returns		: Network configuration file path
    Example		: my $ifcfg = xCAT::zvmUtils->getIfcfg($node);
    
=cut

#-------------------------------------------------------
sub getIfcfg {

	# Get inputs
	my ( $class, $node ) = @_;

	# Get OS
	my $os = xCAT::zvmCPUtils->getOs($node);

	# Get network configuration file path
	my $out;
	my @parms;

	# If it is Red Hat -- ifcfg-qeth file is in /etc/sysconfig/network-scripts
	if ( $os =~ m/Red Hat/i ) {
		$out = `ssh -o ConnectTimeout=5 $node "ls /etc/sysconfig/network-scripts/ifcfg-eth*"`;
		@parms = split( '\n', $out );
		return ( $parms[0] );
	}

	# If it is SUSE -- ifcfg-qeth file is in /etc/sysconfig/network
	elsif ( $os =~ m/SUSE/i ) {
		$out = `ssh -o ConnectTimeout=5 $node "ls /etc/sysconfig/network/ifcfg-qeth*"`;
		@parms = split( '\n', $out );
		return ( $parms[0] );
	}

	# If no file is found -- Return nothing
	return;
}

#-------------------------------------------------------

=head3   getIfcfgByNic

	Description	: Get /etc/sysconfig/network/ifcfg-qeth file name for given NIC
    Arguments	: 	Node
    				NIC address
    Returns		: /etc/sysconfig/network/ifcfg-qeth file name
    Example		: my $ifcfg = xCAT::zvmUtils->getIfcfgByNic($node, $nic);
    
=cut

#-------------------------------------------------------
sub getIfcfgByNic {

	# Get inputs
	my ( $class, $node, $nic ) = @_;

	# Get OS
	my $os = xCAT::zvmCPUtils->getOs($node);

	# Get network configuration file path
	my $out;
	my @parms;

	# If it is Red Hat -- ifcfg-qeth file is in /etc/sysconfig/network-scripts
	if ( $os =~ m/Red Hat/i ) {
		$out = `ssh -o ConnectTimeout=5 $node "ls /etc/sysconfig/network-scripts/ifcfg-eth*" | grep "$nic"`;
		@parms = split( '\n', $out );
		return ( $parms[0] );
	}

	# If it is SUSE -- ifcfg-qeth file is in /etc/sysconfig/network
	elsif ( $os =~ m/SUSE/i ) {
		$out = `ssh -o ConnectTimeout=5 $node "ls /etc/sysconfig/network/ifcfg-qeth*" | grep "$nic"`;
		@parms = split( '\n', $out );
		return ( $parms[0] );
	}

	# If no file is found -- Return nothing
	return;
}

#-------------------------------------------------------

=head3   getBroadcastIP

	Description	: Get IP broadcast of given node
    Arguments	: Node
    Returns		: IP broadcast
    Example		: my $broadcast = xCAT::zvmUtils->getBroadcastIP($node);
    
=cut

#-------------------------------------------------------
sub getBroadcastIP {

	# Get inputs
	my ( $class, $node ) = @_;

	# Get IP address
	my $out   = `ssh -o ConnectTimeout=5 $node "ifconfig" | grep "Bcast:" | cut -d: -f3`;
	my @parms = split( ' ', $out );

	return ( $parms[0] );
}

#-------------------------------------------------------

=head3   getDns

	Description	: Get DNS server of given node
    Arguments	: Node
    Returns		: DNS server
    Example		: my $dns = xCAT::zvmUtils->getDns($node);
    
=cut

#-------------------------------------------------------
sub getDns {

	# Get inputs
	my ( $class, $node ) = @_;

	# Get IP address
	my $out   = `ssh -o ConnectTimeout=5 $node "cat /etc/resolv.conf" | grep "nameserver"`;
	my @parms = split( ' ', $out );

	return ( $parms[1] );
}

#-------------------------------------------------------

=head3   getGateway

	Description	: Get default gateway of given node
    Arguments	: Node
    Returns		: Default gateway
    Example		: my $gw = xCAT::zvmUtils->getGateway($node);
    
=cut

#-------------------------------------------------------
sub getGateway {

	# Get inputs
	my ( $class, $node ) = @_;

	# Get IP address
	my $out = `ssh -o ConnectTimeout=5 $node "cat /etc/sysconfig/network/routes"`;
	my @parms = split( ' ', $out );
	return ( $parms[1] );
}

#-------------------------------------------------------

=head3   sendFile

	Description	: SCP file to given node
    Arguments	: 	Node 
    				File
    Returns		: Nothing
    Example		: my $out = xCAT::zvmUtils->sendFile($node, $file);
    
=cut

#-------------------------------------------------------
sub sendFile {

	# Get inputs
	my ( $class, $node, $file ) = @_;

	# Create destination string
	my $dest = "root@";
	$dest .= $node;

	# SCP directory entry file over to HCP
	my $out = `scp $file $dest:$file`;

	return;
}

#-------------------------------------------------------

=head3   getRootDiskAddr

	Description	: Get root disk address of given node
    Arguments	: 	Node name
    Returns		: 	Root disk address
    Example		: my $deviceNode = xCAT::zvmUtils->getRootDiskAddr($node);
    
=cut

#-------------------------------------------------------
sub getRootDiskAddr {

	# Get inputs
	my ( $class, $node ) = @_;

	# Get device node mounted on (/)
	my $out = `ssh $node  "mount" | grep "/ type" | sed 's/1//'`;
	my @parms = split( " ", $out );
	@parms = split( "/", xCAT::zvmUtils->trimStr( $parms[0] ) );
	my $devNode = $parms[0];

	# Get disk address
	$out =
	  `ssh $node "cat /proc/dasd/devices" | grep "$devNode" | sed 's/(ECKD)//' | sed 's/(FBA )//' | sed 's/0.0.//'`;
	@parms = split( " ", $out );
	return ( $parms[0] );
}

#-------------------------------------------------------

=head3   disableEnableDisk

	Description	: Disable or enable disk for given node
    Arguments	: 	Device address
    				Option [-d | -e]
    Returns		: Nothing
    Example		: my $out = xCAT::zvmUtils->disableEnableDisk($callback, $node, $option, $devAddr);
    
=cut

#-------------------------------------------------------
sub disableEnableDisk {

	# Get inputs
	my ( $class, $callback, $node, $option, $devAddr ) = @_;

	# Disable or enable disk
	if ( $option eq "-d" || $option eq "-e" ) {
		my $out = `ssh $node "chccwdev $option $devAddr"`;
	}

	return;
}

#-------------------------------------------------------

=head3   getMdisks

	Description	: Get MDisk statements in user directory entry
    Arguments	: Node
    Returns		: MDisk statements
    Example		: my @mdisks = xCAT::zvmUtils->getMdisks($callback, $node);
    
=cut

#-------------------------------------------------------
sub getMdisks {

	# Get inputs
	my ( $class, $callback, $node ) = @_;

	# Directory where executables are
	my $dir = '/opt/zhcp/bin';

	# Get HCP
	my @propNames = ( 'hcp', 'userid' );
	my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames );
	my $hcp      = $propVals->{'hcp'};

	# Get node userID
	my $userId = $propVals->{'userid'};

	my $out = `ssh $hcp "$dir/getuserentry $userId" | grep "MDISK"`;

	# Get MDISK statements
	my @lines = split( '\n', $out );
	my @disks;
	foreach (@lines) {
		$_ = xCAT::zvmUtils->trimStr($_);

		# Save MDISK statements
		push( @disks, $_ );
	}
	return (@disks);
}

#-------------------------------------------------------

=head3   readConfigFile

	Description	: Read in configuration file
    Arguments	: 	Node
    				Configuration file
    Returns		: 	Hash arrary containing node configuration
    Example		: my %nodeConfig = xCAT::zvmUtils->readConfigFile($callback, $node, $file);
    
=cut

#-------------------------------------------------------
sub readConfigFile {

	# Get inputs
	my ( $class, $callback, $node, $file ) = @_;

	# Hash array containing new node configuration
	my %target;

	# Get configuration file
	if ( !$file ) {
		xCAT::zvmUtils->printLn( $callback, "Error: Missing configuration file" );
		return;
	}
	else {

		# Open configuration file
		open( CONFIG, $file ) || die("Error: Could not open file");
		my @configFile = <CONFIG>;
		close(CONFIG);

		# Read configuration file
		my @parms;
		my $pattern = $node . ":";
		my $save    = 0;
		foreach (@configFile) {
			$_ = xCAT::zvmUtils->trimStr($_);

			# If the line contains specified node
			if ( $_ =~ m/$pattern/i ) {

				# Save configuration
				$save = 1;

				# Find ':' and replace with ''
				$_ =~ s/://g;
				$target{"Hostname"} = $_;
			}

			# Stop saving at next line containing ':'
			if ( $save == 1 && $_ =~ m/:/i ) {
				$save = 0;
			}

			# Save configuration
			if ( $save == 1 ) {

				# Create hash array
				@parms = split( "=", $_ );
				$target{"$parms[0]"} = "$parms[1]";
			}

		}    # End of foreach
	}    # End of else

	# If there is not a new node configuration
	if ( !$target{"Hostname"} ) {
		xCAT::zvmUtils->printLn( $callback, "Error: Node configuration not found" );
		return;
	}

	return %target;
}

#-------------------------------------------------------

=head3   saveDirEntryNoDisk

	Description	: 	Get user directory entry for given node,
					remove MDISK statments, and save it to a file
    Arguments	: 	Node name
    				File name
    Returns		: 	Nothing
    Example		: my $out = xCAT::zvmUtils->saveDirEntryNoDisk($callback, $node, $file);
    
=cut

#-------------------------------------------------------
sub saveDirEntryNoDisk {

	# Get inputs
	my ( $class, $callback, $node, $file ) = @_;

	# Directory where executables are
	my $dir = '/opt/zhcp/bin';

	# Get node properties from 'zvm' table
	my @propNames = ( 'hcp', 'userid' );
	my $propVals = xCAT::zvmUtils->getNodeProps( 'zvm', $node, @propNames );

	# Get HCP
	my $hcp = $propVals->{'hcp'};
	if ( !$hcp ) {
		xCAT::zvmUtils->printLn( $callback, "Error: Missing node HCP" );
		return;
	}

	# Get node userID
	my $userId = $propVals->{'userid'};
	if ( !$userId ) {
		xCAT::zvmUtils->printLn( $callback, "Error: Missing node ID" );
		return;
	}

	my $out = `ssh $hcp "$dir/getuserentry $userId" | grep -v "MDISK"`;

	# Create a file to save output
	open( DIRENTRY, ">$file" );

	# Save output
	my @lines = split( '\n', $out );
	foreach (@lines) {

		# Trim line
		$_ = xCAT::zvmUtils->trimStr($_);

		# Write directory entry into file
		print DIRENTRY "$_\n";
	}
	close(DIRENTRY);

	return;
}

#-------------------------------------------------------

=head3   appendHostname

	Description	: 	Append specified hostname in front of given string
    Arguments	: 	Hostname
    				String
    Returns		: 	String with hostname in front
    Example		: my $str = xCAT::zvmUtils->appendHostname($hostname, $str);
    
=cut

#-------------------------------------------------------
sub appendHostname {
	my ( $class, $hostname, $str ) = @_;

	# Append hostname to every line
	my @outLn = split( "\n", $str );
	$str = "";
	foreach (@outLn) {
		$str .= "$hostname: " . $_ . "\n";
	}

	return $str;
}

#-------------------------------------------------------

=head3   isOutputGood

	Description	: 	Check return of given output
    Arguments	: 	Output string
    Returns		: 	0	Good output
    				-1	Bad output
    Example		: my $ans = xCAT::zvmUtils->isOutputGood($callback, $out);
    
=cut

#-------------------------------------------------------
sub isOutputGood {
	my ( $class, $callback, $out ) = @_;

	# Check output string
	my @outLn = split( "\n", $out );
	foreach (@outLn) {

		# If output contains 'Failed' return -1
		if ( $_ =~ m/Failed/i ) {
			return -1;
		}
	}

	return 0;
}

#-------------------------------------------------------

=head3   isAddressUsed

	Description	: 	Check if given address is used
    Arguments	: 	Node
    				Disk address
    Returns		: 	0	Address used
    				-1	Address not used
    Example		: my $ans = xCAT::zvmUtils->isAddressUsed($node, $address);
    
=cut

#-------------------------------------------------------
sub isAddressUsed {
	my ( $class, $node, $address ) = @_;

	# Search for disk address
	my $out = `ssh -o ConnectTimeout=5 $node "vmcp q v dasd" | grep "DASD $address"`;
	if ($out) {
		return 0;
	}

	return -1;
}

#-------------------------------------------------------

=head3   getMacID

	Description	: Get MACID from /opt/zhcp/conf/next_mac on HCP
    Arguments	: HCP node
    Returns		: MACID
    Example		: my $mac = xCAT::zvmUtils->getMacID($hcp);
    
=cut

#-------------------------------------------------------
sub getMacID {
	my ( $class, $hcp ) = @_;

	# Check /opt/zhcp/conf directory on HCP
	my $out = `ssh -o ConnectTimeout=5 $hcp "test -d /opt/zhcp/conf && echo 'Directory exists'"`;
	if ( $out =~ m/Directory exists/i ) {

		# Read next_mac file
		$out = `ssh -o ConnectTimeout=5 $hcp "cat /opt/zhcp/conf/next_mac"`;
	}
	else {

		# Create /opt/zhcp/conf directory
		# Create next_mac -- Contains next MAC address to use
		$out = `ssh -o ConnectTimeout=5 $hcp "mkdir /opt/zhcp/conf"`;
		$out = `ssh -o ConnectTimeout=5 $hcp "echo 'FFFFFF' > /opt/zhcp/conf/next_mac"`;
	}

	# Create /opt/zhcp/conf/next_mac file on HCP
	$out = `ssh -o ConnectTimeout=5 $hcp "cat /opt/zhcp/conf/next_mac"`;
	my $mac = xCAT::zvmUtils->trimStr($out);

	return $mac;
}

#-------------------------------------------------------

=head3   generateMac

	Description	: Generate a MAC address 
    Arguments	: 	HCP node
    Returns		: MAC suffix
    Example		: my $mac = xCAT::zvmUtils->generateMac($hcp);
    
=cut

#-------------------------------------------------------
sub generateMac {
	my ( $class, $hcp ) = @_;

	# Check /opt/zhcp/conf directory on HCP
	my $out = `ssh -o ConnectTimeout=5 $hcp "test -d /opt/zhcp/conf && echo 'Directory exists'"`;
	if ( $out =~ m/Directory exists/i ) {

		# Read next_mac file
		$out = `ssh -o ConnectTimeout=5 $hcp "cat /opt/zhcp/conf/next_mac"`;
	}
	else {

		# Create /opt/zhcp/conf directory
		# Create next_mac -- Contains next MAC address to use
		$out = `ssh -o ConnectTimeout=5 $hcp "mkdir /opt/zhcp/conf"`;
		$out = `ssh -o ConnectTimeout=5 $hcp "echo 'FFFFFF' > /opt/zhcp/conf/next_mac"`;
	}

	# Read /opt/zhcp/conf/next_mac file
	$out = `ssh -o ConnectTimeout=5 $hcp "cat /opt/zhcp/conf/next_mac"`;
	my $mac = xCAT::zvmUtils->trimStr($out);
	my $int;

	if ($mac) {

		# Convert hexadecimal to decimal
		$int = hex($mac);
		$mac = sprintf( "%d", $int );

		# Generate new MAC suffix
		$mac = $mac - 1;

		# Convert decimal to hexadecimal
		$mac = sprintf( "%X", $mac );
		$out = `ssh -o ConnectTimeout=5 $hcp "echo $mac > /opt/zhcp/conf/next_mac"`;
	}

	return $mac;

	#	# Find the highest MAC address on given LAN
	#	my $newMac = 0;
	#	my $mac;
	#	my $temp;
	#	my $layer = -1;
	#	my @vars;
	#	my $out   = `ssh -o ConnectTimeout=5 $hcp "vmcp --buffer 1000000 q lan $lanName details"`;
	#	my @outLn = split( "\n", $out );
	#
	#	# Go through each line
	#	foreach (@outLn) {
	#
	#		# Get the MAC address for layer 3 LAN
	#		if ( $layer == 3 ) {
	#			@vars = split( " ", $_ );
	#			$mac  = $vars[2];
	#
	#			# Replace - with :
	#			$mac = xCAT::zvmUtils->replaceStr( $mac, "-", ":" );
	#
	#			# Convert to decimal
	#			if ($mac) {
	#
	#				# Remove dash
	#				$temp = xCAT::zvmUtils->replaceStr( $mac, ":", "" );
	#
	#				$temp = hex($temp);
	#				$mac = sprintf( "%d", $temp );
	#			}
	#
	#			# Compare MAC address value to previous one
	#			# Save the highest MAC address
	#			if ( $mac > $newMac ) {
	#				$newMac = $mac;
	#			}
	#
	#			$layer = -1;
	#		}
	#
	#		# Get the MAC address for layer 2 LAN
	#		elsif ( $layer == 2 ) {
	#			@vars = split( " ", $_ );
	#			$mac  = $vars[0];
	#
	#			# Replace - with :
	#			$mac = xCAT::zvmUtils->replaceStr( $mac, "-", ":" );
	#
	#			# Convert to decimal
	#			if ($mac) {
	#
	#				# Remove dash
	#				$temp = xCAT::zvmUtils->replaceStr( $mac, ":", "" );
	#
	#				$temp = hex($temp);
	#				$mac = sprintf( "%d", $temp );
	#			}
	#
	#			# Compare MAC address value to previous one
	#			# Save the highest MAC address
	#			if ( $mac > $newMac ) {
	#				$newMac = $mac;
	#			}
	#
	#			$layer = -1;
	#		}
	#
	#		# If the line contains 'Unicast IP/MAC Addresses' -- Then the next line contain a MAC address
	#		if ( $_ =~ m/Unicast IP Addresses/i ) {
	#			$layer = 3;
	#		}
	#		elsif ( $_ =~ m/ Unicast MAC Addresses/i ) {
	#			$layer = 2;
	#		}
	#	}
	#
	#	# Convert the highest MAC address from decimal to hexadecimal
	#	$newMac = $newMac + 1;
	#	$newMac = sprintf( "%x", $newMac );
	#
	#	# Append a zero if length is less than 12
	#	if ( length($newMac) != 12 ) {
	#		$newMac = "0" . $newMac;
	#	}
	#
	#	$newMac =
	#	    substr( $newMac, 0, 2 ) . ":"
	#	  . substr( $newMac, 2,  2 ) . ":"
	#	  . substr( $newMac, 4,  2 ) . ":"
	#	  . substr( $newMac, 6,  2 ) . ":"
	#	  . substr( $newMac, 8,  2 ) . ":"
	#	  . substr( $newMac, 10, 2 );
	#
	#	return $newMac;
}