Location: PHPKode > projects > PortWatcher > PortWatcher/MACUpdate.php
<?
$q_mode = false;
$args = $_SERVER['argv'];

if ($args[1] == "q")
{
	$q_mode = true;
}

define_syslog_variables();
openlog("eventhorizon", LOG_CONS, LOG_LOCAL0);
syslog(LOG_NOTICE, "Running PortWatcher.");	
$SNMPErrorLog = "/var/log/SNMPErrorLog";
include("config.php");

# Now define some SNMP OIDs
$SNMP_dot1dTpFdbAddress = ".1.3.6.1.2.1.17.4.3.1.1"; 
$SNMP_dot1dTpFdbPort = ".1.3.6.1.2.1.17.4.3.1.2"; 
$SNMP_dot1dBasePortIfIndex = ".1.3.6.1.2.1.17.1.4.1.2"; 
$SNMP_ifName = ".1.3.6.1.2.1.31.1.1.1.1"; 
$SNMP_ifDescr = ".1.3.6.1.2.1.2.2.1.2.1";
$snmpDomain = "eh-master-dev.lanifex.com";  # localize per customer

function find_in_array ($searching_in, $searching_for)
{
	$position = -1;
	$size=sizeof($searching_in);
    for($count = 0; $count < $size; $count++) 
	{
		$search = strstr($searching_in[$count], $searching_for);
		if ($search != false)
		{
			$position = $count;
			break;
		}
	}
	return $position;
}


function UpdateMacPort() 
{
	global $db,$ReportMail,$SNMPErrorLog, $community_base, $q_mode;
	global $SNMP_dot1dTpFdbAddress, $SNMP_dot1dTpFdbPort, $SNMP_dot1dBasePortIfIndex, $SNMP_ifName, $snmpDomain, $SNMP_ifDescr;

	$sql = "SELECT * FROM switches where status='1'";
	
	$stacksResult = mysql_query($sql);
	$macportResult = mysql_query("SELECT * FROM macport ORDER BY portindex");
	if ($macportResult)
	{
		while ($macportrow = mysql_fetch_array($macportResult)) 
		{
		    $macportArray[$macportrow["bsipaddress"]]["$macportrow[mac]:$macportrow[port]"]["mac"] = $macportrow["mac"];
		    $macportArray[$macportrow["bsipaddress"]]["$macportrow[mac]:$macportrow[port]"]["updatetime"] = $macportrow["updatetime"];
//		    $macportArray[$macportrow["bsipaddress"]]["$macportrow[mac]:$macportrow[port]"]["status"] = $macportrow["status"];
		}
	}	

	$macipResult = mysql_query("SELECT * FROM macip ORDER BY mac");
	if($macipResult)
	{
		while ($maciprow = mysql_fetch_array($macipResult)) 
		{
			$macipArray[$maciprow["ipaddress"]]["mac"] = $maciprow["mac"];
			$macipArray[$maciprow["ipaddress"]]["oldmac"] = $maciprow["oldmac"];
		}
	}
	
	$now = date("Y-m-d H:i:s");
	if($stacksResult)
	{
		while($myrow = mysql_fetch_row($stacksResult)) 
		{
		
		    $target = $myrow[6];
			$tempor = $myrow[13];
			if ($tempor == "")
				$port_filter = null;
			else
				$port_filter = explode(" ", $tempor);
			$sensorip = $myrow[14];
			$community_base = $myrow[15];
			$snmp_version = $myrow[16];
			
			if (!$q_mode) echo "<h3>Commencing scan of switch $target using community string $community_base</h3>\n";
			else echo "Commencing scan of switch $target using community string $community_base:\n";
			syslog(LOG_NOTICE, "PortWatcher: Scanning switch $target using community string $community_base");	
			//$line = exec('ping -c5 -i0.2 -f '.$target, $dummy,  $ping_result);
			
			$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
			socket_set_nonblock($sock);
			socket_connect($sock, $target, 23);
			socket_set_block($sock);
			switch(socket_select($r = array($sock), $w = array($sock), $f = array($sock), 5))
			{
			        case 2:
			                $ping_result = 1;
			                break;
			        case 1:
			                $ping_result = 0;
			                break;
			        case 0:
			                $ping_result = 1;
			                break;
			}
			
			if ($ping_result == 0)
			{
				$upd = mysql_query("UPDATE switches set last_polled = '$now' where ipaddress = '$target'");
				unset($snmpArray); # clear array for finding ports each time through
				$cmd = "/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target $SNMP_dot1dTpFdbAddress | fgrep -v '255.255.255.255.255.255'";
				$step_inter = chop(shell_exec($cmd));  
				$snmpArray = explode("\n", $step_inter);
				$step1 = explode("\n", $step_inter);
				
				$step_inter = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target $SNMP_dot1dTpFdbPort"));  
				$step2 = explode("\n", $step_inter);
				$step_inter = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target $SNMP_dot1dBasePortIfIndex"));  
				$step3 = explode("\n", $step_inter);
				$step_inter = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target $SNMP_ifName"));  
				$step_inters = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target $SNMP_ifDescr"));  
				$step_tog = $step_inter."\n".$step_inters;
				$step4 = explode("\n", $step_tog);
				/*FIND IP FOR THAT MAC*/
				$stepy = chop(shell_exec("/sbin/arp -an"));  //
				$step5 = explode("\n", $stepy);
				if ($myrow[10] != NULL)
					$vlanList = split(" ", $myrow[10]);  # get list of VLANs on this switch
				else
					$vlanList[0] = 0;
				
				$sysDescr = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target system.sysDescr"));
			    $sysUpTime = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target system.sysUpTime"));
			    $sysName = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target system.sysName"));
			    $sysLocation = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target system.sysLocation"));
			    $sysContact = chop(shell_exec("/usr/bin/snmpwalk -Os -c $community_base -v $snmp_version $target system.sysContact"));
			    
				$sysDescr = str_replace("sysDescr.0 = STRING: ","",$sysDescr);
				$sysUpTime = str_replace("sysUpTime.0 = Timeticks: ","",$sysUpTime);
				$sysLocation = str_replace("sysLocation.0 = STRING:","",$sysLocation);
				$sysContact = str_replace("sysContact.0 = STRING:","",$sysContact);
				$sysName = str_replace("sysName.0 = STRING:","",$sysName);          
				if (!$q_mode) 
				{
					echo "<table border=\"1\">";
				    if ($sysDescr) { echo "<tr><td>System Description:</td><td> $sysDescr</td></tr>"; }
				    if ($sysUpTime) { echo "<tr><td>System UpTime:</td><td> $sysUpTime</td></tr>"; }
				    if ($sysName) { echo "<tr><td>System Name: </td><td>$sysName</td></tr>"; }
				    if ($sysLocation) { echo "<tr><td>System Location: </td><td>$sysLocation</td></tr>"; }
				    if ($sysContact) { echo "<tr><td>System Contact: </td><td>$sysContact</td></tr>"; }
				    echo "</table><br/>\n";
				}
				 flush();		

				reset($vlanList);
			    while (list($key,$value) = each($vlanList)) 
				{
					
				    if ($value == 0) 
					{
						$community = $community_base;
						$value = 1;
				    } 
					else 
					{
						$community = $community_base . '@' . $value;
				    }

				   if (!$q_mode) echo "\n<h3>Checking VLAN $value using community string $community</h3>\n ";
				   else echo "\nChecking VLAN $value using community string $community:\n";
					syslog(LOG_NOTICE, "PortWatcher: Checking VLAN $value on switch $target");	 
					
					if (count($snmpArray) == 0) 
					{
				        if (!$q_mode) echo "<p>No ports found on $target.</p>\n";
						else echo "No ports found on $target.\n";
						syslog(LOG_NOTICE, "PortWatcher: No ports found on $target.");	
				    }
					else 
					{
				        if (!$q_mode) 
						{
							echo "<p>Found <strong>" . count($snmpArray) . "</strong> MAC ";
							if (count($snmpArray) == 1)
								echo "address. ";
							else
								echo "addresses. ";
								
							if (count($port_filter) > 0)
							{
								echo "(".count($port_filter);
								if (count($port_filter) == 1)
									echo " port ignored)";
								else
									echo " ports ignored)";
							}
							echo "</p>\n";
						}
						else echo "Found " . count($snmpArray) . " ports.\n";
						syslog(LOG_NOTICE, "PortWatcher: Found ".count($snmpArray)." ports on switch $target.");	
						if (!$q_mode) echo "<ol>\n";
				        for ($i=0; $i < count($snmpArray);$i++) 
						{
					        list($snmpKey,$snmpValue) = split(' = ',$snmpArray[$i]);
							$snmpUnit = 1;
					        $snmpPort_count = $i+1;
					        $snmpMAC = str_replace("Hex-STRING","",$snmpValue);
					        $snmpMAC_ns = str_replace(":","",$snmpMAC);
							$snmpMAC_ns = ltrim($snmpMAC_ns);
							$snmpMAC_search = str_replace(" ",":",$snmpMAC_ns);
							$snmpMAC = str_replace(" ","",$snmpMAC_ns);
							$tempast = explode(" ", $snmpMAC_ns);
							$decimal_version = "";
							for ($count = 0; $count < 6; $count++)
							{
								$decimal_version = $decimal_version . hexdec($tempast[$count]) . ".";
							}
							$decimal_version = rtrim($decimal_version, ".");
							
							$pos = find_in_array($step2, $decimal_version);
					        if ($pos != -1)
							{
								$interm = explode ("INTEGER:", $step2[$pos]);
								$integer1 = ltrim($interm[1]);
								$pos2 = find_in_array($step3, $integer1);
						        if ($pos2 != -1)
								{
									$interm2 = explode ("INTEGER:", $step3[$pos2]);
									$integer2 = ltrim($interm2[1]);
									$pos3 = find_in_array($step4, ".".$integer2);
							        if ($pos3 != -1)
									{
										$interm3 = explode ("STRING:", $step4[$pos3]);
										$interm4 = explode ("/", $interm3[1]);
										$snmpPort = $interm4[1];
									}
								}
							}
							
								if ($port_filter == null || !in_array($snmpPort, $port_filter, true))
								{
									if (!$q_mode) echo "<li>\nPort <b>$snmpPort</b>: $snmpMAC_ns\n";
									$posy = find_in_array($step5, $snmpMAC_search);
									$snmpIP = false;
							        if ($posy != -1)
									{
										$ip_start = strpos($step5[$posy], "(");
										$ip_end = strpos($step5[$posy], ")");
										$snmpIP = substr($step5[$posy], $ip_start+1, $ip_end-$ip_start-1 );
									}
									
									if ($snmpIP != false)
									{
										$dnsname = gethostbyaddr($snmpIP);
										if ($dnsname == $snmpIP  || $dnsname == $snmpDomain) 
										{
											$dnsname = "Not in the DNS";
											$dns = 0;
										}
										else 
										{
											$dns = 1;
										}
									
									
										if (isset($macipArray[$snmpIP])) 
										{
											$oldmac = $macipArray[$snmpIP]["mac"];
											if ($macipArray[$snmpIP]["mac"] != $snmpMAC) 
											{
												$updateResult = mysql_query("UPDATE macip set mac = '$snmpMAC', oldmac = '$oldmac',	updatetime = '$now' where ipaddress = '$snmpIP'");
												if (!$q_mode) echo "<br/>IP address ".$snmpIP." changed its MAC address from ".$oldmac." to ".$snmpMAC." on switch [".$target."]\n";
												syslog(LOG_NOTICE, "PortWatcher: IP address ".$snmpIP." changed its MAC address from ".$oldmac." to ".$snmpMAC." on switch [".$target."]");	
												$checkResult = mysql_query("SELECT * FROM maciphistory where ipaddress = '$snmpIP'",$db);
												if (!mysql_fetch_row($checkResult)) 
												{
												    $insertResult = mysql_query("INSERT INTO maciphistory (ipaddress,mac,updatetime ) VALUES ('$snmpIP','$oldmac','$now')",$db);
												}
												$insertResult = mysql_query("INSERT INTO maciphistory (ipaddress,mac,updatetime) VALUES ('$snmpIP','$snmpMAC','$now')",$db);
											}
										}
										else 
										{
											//alert that new ip address appeared
											$insertResult = mysql_query("INSERT INTO macip (mac,ipaddress,oldmac,updatetime,sortipaddress,dns)
																		VALUES ('$snmpMAC','$snmpIP','','$now','$sortipaddress','$dns')",$db);
											if (!$q_mode) echo "<br/>New IP address found: ".$snmpIP." with MAC address ".$snmpMAC." on switch [".$target."]\n";
											syslog(LOG_NOTICE, "PortWatcher: New IP address found: ".$snmpIP." with MAC address ".$snmpMAC." on switch [".$target."]");	
										}
									}
									
									if (isset($macportArray[$target]["$snmpMAC:$snmpPort"]))  //mac\port combo did not change
									{
										$updateResult = mysql_query("UPDATE macport set status = '$snmpStatus' , 
																		updatetime = '$now' where bsipaddress = '$target' AND mac = '$snmpMAC' AND port = '$snmpPort'",$db);
									}
									else //something changed
									{
										$checkCount = mysql_query("SELECT mac FROM macport WHERE bsipaddress = '$target' AND port = '$snmpPort'",$db);
										if (mysql_num_rows($checkCount) == 1)
										{
											$tm_oldMAC = mysql_fetch_row($checkCount);
											$oldMAC = $tm_oldMAC[0];
										}
										else if (mysql_num_rows($checkCount) == 0)
										{
											$oldMAC = "";
										}
										else
										{
											$oldMAC = "Multiple";
										}
										//do a query on that port and count the result
										//if there is more then one thing on that port - old_mac = "multiple"
										// if there is only one then old_mac = to the result's mac
										
										$insertRes = mysql_query("INSERT INTO macporthistory (bsipaddress, port, mac, updatetime)
																	VALUES ('$target','$snmpPort','$snmpMAC','$now')",$db);

							            $insertResult = mysql_query("INSERT INTO macport (bsipaddress, port, mac, updatetime, oldmac) 
																	VALUES ('$target','$snmpPort','$snmpMAC','$now', '$oldMAC')",$db);
										$checkMoved = mysql_query("SELECT * FROM macport WHERE bsipaddress = '$target' AND mac = '$snmpMAC' 
																		AND port != '$snmpPort'",$db);
										if (mysql_num_rows($checkMoved) > 0)								
										{
											while($check = mysql_fetch_array($checkMoved)) 
											{
												if (!$q_mode) echo "<br/>MAC address ".$snmpMAC." moved from port ".$check[port]." to port ".$snmpPort." on switch [".$target."]\n";
												syslog(LOG_NOTICE, "PortWatcher: MAC address ".$snmpMAC." moved from port ".$check[port]." to port ".$snmpPort." on switch [".$target."]");	
												$removeMove = mysql_query("DELETE FROM macport WHERE portindex=\"$check[portindex]\" AND mac =\"$check[mac]\";",$db);
											}
										}
										else
										{
											if (!$q_mode) echo "<br/>New MAC address detected on switch [".$target."] on port ".$snmpPort.": ".$snmpMAC."\n";
											syslog(LOG_NOTICE, "PortWatcher: New MAC address detected on switch [".$target."] on port ".$snmpPort.": ".$snmpMAC);						
										}
							        }
									if (!$q_mode) echo "</li>\n";
								}
						}
						if (!$q_mode) echo "</ol>\n";
					}
			    }
			    flush();
			}
			else
			{
				echo "<h3>The switch is either off or unreachable.</h3>";
			}
		}
	}
	else
	{
		echo "No switches found in the database.";
	}
}

if (!$q_mode)
{
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
            "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
	<link rel="stylesheet" href="index.css" type="text/css" />
	<title>Lanifex PortWatcher</title>
</head>

<body>
	<div class="header">
	<a href="http://www.lanifex.com"><img src="img/logo.jpg" alt=""></a>
	</div>
	<div class="menu">
			<a href="index.html"><span>Home</span></a>
			<a href="MACUpdate.php"><span>SNMP scan</span></a>
			<a href="MACTools.php"><span>DB review</span></a>
			<a href="switch_man.php"><span>Switch management</span></a>
	</div>
	<div class="content">
<? 
}

if (!$q_mode) echo "<h2>Checking Ports of Switches</h2>\n";

$db = mysql_connect($dbserver, $dbuser, $dbpasswd);
mysql_select_db($dbname, $db);

UpdateMacPort();
mysql_close($db);

if (!$q_mode) 
{
?>
<div class="clear"></div>
	</div>
	<div class="footer"></div>
</body>
</html>
<?
}
else
{
	echo "\nScan completed!\n";
}
syslog(LOG_NOTICE, "PortWatcher: Scan completed.");	
closelog();
?>
Return current item: PortWatcher