function collect_mactrack_data($start, $site_id = 0) {
	global $max_run_duration, $config, $debug, $scan_date;

	if (defined('CACTI_BASE_PATH')) {
		$config["base_path"] = CACTI_BASE_PATH;
	}

	/* reset the processes table */
	db_execute("TRUNCATE TABLE mac_track_processes");

	/* dns resolver binary */
	$resolver_launched = FALSE;

	if (read_config_option("mt_reverse_dns") == "on") {
		$dns_resolver_required = TRUE;
	}else{
		$dns_resolver_required = FALSE;
	}

	/* get php binary path */
	$command_string = read_config_option("path_php_binary");

	/* save the scan date information */
	if ($site_id == '') {
		$scan_date = date("Y-m-d H:i:s");
		db_execute("REPLACE INTO settings (name, value) VALUES ('mt_scan_date', '$scan_date')");
	}

	/* just in case we've run too long */
	$exit_mactrack = FALSE;

	/* start mainline processing, order by site_id to keep routers grouped with switches */
	if ($site_id > 0) {
		$device_ids = db_fetch_assoc("SELECT device_id FROM mac_track_devices WHERE site_id='" . $site_id . "' and disabled=''");
	}else{
		$device_ids = db_fetch_assoc("SELECT device_id FROM mac_track_devices WHERE disabled='' ORDER BY site_id");
	}

	$total_devices = sizeof($device_ids);

	$concurrent_processes = read_config_option("mt_processes");

	if ($debug == TRUE) {
		$e_debug = " -d";
	}else{
		$e_debug = "";
	}

	if ($site_id) {
		$e_site = " -sid=$site_id";
	}else{
		$e_site = "";
	}

	/* add the parent process to the process list */
	db_process_add("-1");

	if ($total_devices > 0) {
		/* grab arpwatch data */
		if (read_config_option("mt_arpwatch") == "on") {
			$arp_db     = read_config_option("mt_arpwatch_path");
			$delim      = read_config_option("mt_mac_delim");
			$mac_ip_dns = array();

			if (file_exists($arp_db)) {
				$arp_dat = fopen($arp_db, "r");

				if ($arp_dat) {
					while (!feof($arp_dat)) {
						$line = fgets($arp_dat, 4096);

						if ($line != null) {
							$line = explode ("	", $line);

							$mac_ad = explode(":",$line[0]);
							for ($k=0;$k<6;$k++) {
								$mac_ad[$k] = strtoupper($mac_ad[$k]);
								if (1 == strlen($mac_ad[$k])) {
									$mac_ad[$k] = "0" . $mac_ad[$k];
								}
							}

							/* create the mac address */
							$mac = $mac_ad[0] . $delim . $mac_ad[1] . $delim . $mac_ad[2] . $delim . $mac_ad[3] . $delim . $mac_ad[4] . $delim . $mac_ad[5];

							/* update the array */
							$mac_ip_dns[$mac]["ip"]  = $line[1];
							$mac_ip_dns[$mac]["dns"] = $line[3];
						}
					}
					fclose($arp_dat);

					mactrack_debug("ARPWATCH: IP, DNS & MAC collection complete with ArpWatch");
				}else{
					cacti_log("ERROR: cannot open file ArpWatch database '$arp_db'");exit;
				}
			}
		}

		/* scan through all devices */
		$j = 0;
		$i = 0;
		$last_time = strtotime("now");
		$processes_available = $concurrent_processes;
		while ($j < $total_devices) {
			/* retreive the number of concurrent mac_track processes to run */
			/* default to 10 for now */
			$concurrent_processes = db_fetch_cell("SELECT value FROM settings WHERE name='mt_processes'");

			for ($i = 0; $i < $processes_available; $i++) {
				if (($j+$i) >= $total_devices) break;

				$extra_args = " -q " . $config["base_path"] . "/plugins/mactrack/mactrack_scanner.php -id=" . $device_ids[$i+$j]["device_id"] . $e_debug;
				mactrack_debug("CMD: " . $command_string . $extra_args);
				exec_background($command_string, $extra_args);
			}
			$j = $j + $i;

			/* launch the dns resolver if it hasn't been yet */
			if (($dns_resolver_required) && (!$resolver_launched)) {
				sleep(2);
				exec_background($command_string, " -q " . $config["base_path"] . "/plugins/mactrack/mactrack_resolver.php" . $e_debug . $e_site);
				$resolver_launched = TRUE;
				mactrack_debug("DNS Resolver process launched");
			}

			mactrack_debug("A process cycle launch just completed.");

			/* wait the correct number of seconds for proccesses prior to
			   attempting to update records */
			sleep(2);
			$current_time = strtotime("now");
			if (($current_time - $last_time) > read_config_option("mt_dns_prime_interval")) {
				/* resolve some ip's to mac addresses to let the resolver knock them out */
				db_execute("UPDATE mac_track_temp_ports
							INNER JOIN mac_track_ips
							ON (mac_track_temp_ports.mac_address=mac_track_ips.mac_address
							AND mac_track_temp_ports.site_id=mac_track_ips.site_id)
							SET mac_track_temp_ports.ip_address=mac_track_ips.ip_address,
							mac_track_temp_ports.updated=1
							WHERE mac_track_temp_ports.updated=0 AND mac_track_ips.scan_date='$scan_date'");
				mactrack_debug("Interum IP addresses to MAC addresses association pass complete.");

				$last_time = $current_time;
			}

			$processes_running = db_fetch_cell("SELECT count(*) FROM mac_track_processes");

			if ($dns_resolver_required) {
				$processes_available = $concurrent_processes - $processes_running + 1;
			}else{
				$processes_available = $concurrent_processes - $processes_running;
			}

			/* take time to check for an exit condition */
			list($micro,$seconds) = explode(" ", microtime());
			$current = $seconds + $micro;

			/* exit if we've run too long */
			if (($current - $start) > $max_run_duration) {
				$exit_mactrack = TRUE;
				cacti_log("ERROR: MacTracking timed out during main script processing.\n");
				db_execute("DELETE FROM settings WHERE name='mactrack_process_status'");
				db_process_remove("-1");
				break;
			}else{
				db_execute("REPLACE INTO settings SET name='mactrack_process_status', value='Total:$total_devices Completed:$j'");
			}
		}

		/* wait for last process to exit */
		$processes_running = db_fetch_cell("SELECT count(*) FROM mac_track_processes WHERE device_id > 0");
		while (($processes_running > 0) && (!$exit_mactrack)) {
			$processes_running = db_fetch_cell("SELECT count(*) FROM mac_track_processes WHERE device_id > 0");
			$devices_running = db_fetch_cell("SELECT group_concat(CAST(`device_id` as CHAR) SEPARATOR ', ') as t FROM mac_track_processes;");
			/* wait the correct number of seconds for proccesses prior to
			   attempting to update records */
			sleep(2);
			$current_time = strtotime("now");
			if (($current_time - $last_time) > read_config_option("mt_dns_prime_interval")) {
				/* resolve some ip's to mac addresses to let the resolver knock them out */
				db_execute("UPDATE mac_track_temp_ports
							INNER JOIN mac_track_ips
							ON (mac_track_temp_ports.mac_address=mac_track_ips.mac_address
							AND mac_track_temp_ports.site_id=mac_track_ips.site_id)
							SET mac_track_temp_ports.ip_address=mac_track_ips.ip_address,
							mac_track_temp_ports.updated=1
							WHERE mac_track_temp_ports.updated=0 AND mac_track_ips.scan_date='$scan_date'");
				mactrack_debug("Interum IP addresses to MAC addresses association pass complete.");
			}

			/* take time to check for an exit condition */
			list($micro,$seconds) = explode(" ", microtime());
			$current = $seconds + $micro;

			/* exit if we've run too long */
			if (($current - $start) > $max_run_duration) {
				$exit_mactrack = TRUE;
				cacti_log("ERROR: MacTracking timed out during main script processing.\n");
				break;
			}

			mactrack_debug("Waiting on " . $processes_running . " with id = [" . $devices_running ."] to complete prior to exiting.");
		}

		/* if arpwatch is enabled, let's let it pick up the stragglers, based upon IP address first */
		if ((read_config_option("mt_arpwatch") == "on") && (sizeof($mac_ip_dns))) {
			$ports = db_fetch_assoc("SELECT site_id, device_id, mac_address
				FROM mac_track_temp_ports
				WHERE updated=0");

			if (sizeof($ports)) {
			foreach($ports as $port) {
				if (isset($mac_ip_dns[$port["mac_address"]])) {
					db_execute("UPDATE mac_track_temp_ports
						SET updated=1, ip_address='" . $mac_ip_dns[$port["mac_address"]]["ip"] . "'" .
						($mac_ip_dns[$port["mac_address"]]["dns"] != '' ? ", dns_hostname='" . $mac_ip_dns[$port["mac_address"]]["dns"] . "'" : "") . "
						WHERE site_id=" . $port["site_id"] . "
						AND device_id=" . $port["device_id"] . "
						AND mac_address='" . $port["mac_address"] . "'");
				}
			}
			}
		}

		/* resolve some ip's to mac addresses to let the resolver knock them out */
		db_execute("UPDATE mac_track_temp_ports
					INNER JOIN mac_track_ips
					ON (mac_track_temp_ports.mac_address=mac_track_ips.mac_address
					AND mac_track_temp_ports.site_id=mac_track_ips.site_id)
					SET mac_track_temp_ports.ip_address=mac_track_ips.ip_address
					WHERE mac_track_temp_ports.updated=0 AND mac_track_ips.scan_date='$scan_date'");
		mactrack_debug("Interum IP addresses to MAC addresses association pass complete.");

		/* populate the vendor_macs for this pass */
		db_execute("UPDATE mac_track_temp_ports SET vendor_mac=SUBSTRING(mac_address,1,8);");
		mactrack_debug("MAC addresses to Vendor MACS association pass complete.");

		/* update the vlan id's table */
		db_execute("UPDATE mac_track_vlans SET present='0'");
		db_execute("INSERT INTO mac_track_vlans (vlan_id, site_id, device_id, vlan_name, present) SELECT vlan_id, site_id, device_id, vlan_name, '1' AS present FROM mac_track_temp_ports ON DUPLICATE KEY UPDATE vlan_name=VALUES(vlan_name), present=VALUES(present);");
		db_execute("DELETE FROM mac_track_vlans WHERE present='0'");
		mactrack_debug("MAC VLAN's in VLAN Table Updated.");

		/* let the resolver know that the parent process is finished and then wait
		   for the resolver if applicable */
		db_process_remove("-1");

		while (!$exit_mactrack) {
			/* checking to see if the resolver is running */
			$resolver_running = db_fetch_row("SELECT * FROM mac_track_processes WHERE device_id=0");

			if (sizeof($resolver_running) == 0) {
				break;
			}

			/* take time to check for an exit condition */
			list($micro,$seconds) = explode(" ", microtime());
			$current = $seconds + $micro;

			/* exit if we've run too long */
			if (($current - $start) > $max_run_duration) {
				$exit_mactrack = TRUE;
				cacti_log("ERROR: MacTracking timed out during main script processing.\n");
				break;
			}
		}

		/* transfer temp port results into permanent table */
		db_execute("INSERT INTO mac_track_ports
					(site_id, device_id, hostname, dns_hostname, device_name,
					vlan_id, vlan_name, mac_address, vendor_mac, ip_address,
					port_number, port_name, scan_date, authorized)
					SELECT site_id, device_id, hostname, dns_hostname, device_name,
					vlan_id, vlan_name, mac_address, vendor_mac, ip_address,
					port_number, port_name, scan_date, authorized
					FROM mac_track_temp_ports
					ON DUPLICATE KEY UPDATE site_id=VALUES(site_id), hostname=VALUES(hostname),
					device_name=VALUES(device_name), vlan_id=VALUES(vlan_id), vlan_name=VALUES(vlan_name),
					vendor_mac=VALUES(vendor_mac), ip_address=VALUES(ip_address), dns_hostname=VALUES(dns_hostname),
					port_name=VALUES(port_name), authorized=VALUES(authorized)");
		mactrack_debug("Finished transferring scan results to main table.");

		/* transfer the subnet information, although primative, into the ip_ranges table */
		$ip_ranges = db_fetch_assoc("SELECT SUBSTRING_INDEX(`ip_address`,'.',3) AS ip_range,
					site_id,
					COUNT(DISTINCT ip_address) AS ips_current,
					scan_date AS ips_current_date
					FROM mac_track_temp_ports
					WHERE ip_address != ''
					GROUP BY ip_range, site_id");

		if (is_array($ip_ranges)) {
			foreach($ip_ranges as $ip_range) {
				$range_record = db_fetch_row("SELECT * FROM mac_track_ip_ranges WHERE ip_range='" . $ip_range["ip_range"] .
					"' AND site_id='" . $ip_range["site_id"] . "'");

				if (sizeof($range_record) == 0) {
					db_execute("REPLACE INTO `mac_track_ip_ranges`
						(ip_range, site_id, ips_current, ips_current_date)
						VALUES ('" .
						$ip_range["ip_range"] . "'," .
						$ip_range["site_id"] . ",'" .
						$ip_range["ips_current"] . "','" .
						$ip_range["ips_current_date"] . "')");
				}else{
					db_execute("UPDATE `mac_track_ip_ranges`
						SET ips_current='" . $ip_range["ips_current"] . "', " .
						"ips_current_date='" . $ip_range["ips_current_date"] . "'" .
						"WHERE ip_range='" . $range_record["ip_range"] . "' AND " .
						"site_id='" . $range_record["site_id"] . "'");
				}
			}
		}

		/* update the max values if required */
		db_execute("UPDATE `mac_track_ip_ranges`
					SET ips_max=ips_current, ips_max_date=ips_current_date
					WHERE ips_current > ips_max");

		/* collect statistics */
		if ($site_id == 0) {
			$stats = db_fetch_assoc("SELECT site_id,
							count(device_id) as total_devices,
							sum(ports_active) as total_oper_ports,
							sum(macs_active) as total_macs,
							sum(ports_total) as total_user_ports
							FROM mac_track_devices
							GROUP BY site_id");
		}else{
			$stats = db_fetch_assoc("SELECT site_id,
							count(device_id) as total_devices,
							sum(ports_active) as total_oper_ports,
							sum(macs_active) as total_macs,
							sum(ports_total) as total_user_ports
							FROM mac_track_devices
							WHERE site_id='$site_id'
							GROUP BY site_id");
		}

		/* collect total device errors */
		$errors = db_fetch_assoc("SELECT site_id, snmp_status, count(device_id) as total_device_errors
						FROM mac_track_devices
						GROUP BY site_id, snmp_status");

		$ips = array_rekey(db_fetch_assoc("SELECT site_id, count(ip_address) as total_ips
						FROM mac_track_ips
						WHERE scan_date='$scan_date'
						GROUP BY site_id"), "site_id", "total_ips");

		foreach($errors as $error) {
			if (!isset($error_count[$error["site_id"]])) {
				$error_count[$error["site_id"]] = 0;
			}
			if ($error["snmp_status"] <> 3) {
				$error_count[$error["site_id"]] += $error["total_device_errors"];
			}
		}

		foreach($stats as $stat) {
			$num_ips = @$ips[$stat["site_id"]];
			if (empty($num_ips)) $num_ips = 0;

			$update_string = "UPDATE mac_track_sites SET " .
				"total_devices='" . $stat["total_devices"] . "', " .
				"total_ips='" . $num_ips . "', " .
				"total_macs='" . $stat["total_macs"] . "', " .
				"total_oper_ports='" . $stat["total_oper_ports"] . "', " .
				"total_user_ports='" . $stat["total_user_ports"] . "', " .
				"total_device_errors='" . $error_count[$stat["site_id"]] . "' " .
				"WHERE site_id='" . $stat["site_id"] . "'";

			db_execute($update_string);
		}
		mactrack_debug("Finished updating site table with collection statistics.");

		/* process macwatch data */
		$macwatches = db_fetch_assoc("SELECT * FROM mac_track_macwatch");
		if (sizeof($macwatches)) {
			$from     = read_config_option("mt_from_email");
			$fromname = read_config_option("mt_from_name");

			foreach($macwatches as $record) {
				/* determine if we should check this one */
				$found = db_fetch_row("SELECT *
					FROM mac_track_temp_ports
					WHERE mac_address='" . $record["mac_address"] . "'");

				if (sizeof($found)) {
					/* set the subject */
					$subject = "MACAUTH Notification: Mac Address '" . $record["mac_address"] . "' Found, For: '" . $record["name"] . "'";

					/* set the message with replacements */
					$message = str_replace("<IP>", $found["ip_address"], $record["description"]);
					$message = str_replace("<MAC>", $found["mac_address"], $message);
					$message = str_replace("<TICKET>", $record["ticket_number"], $message);
					$message = str_replace("<SITENAME>", db_fetch_cell("SELECT site_name FROM mac_track_sites WHERE site_id=" . $found["site_id"]), $message);
					$message = str_replace("<DEVICEIP>", $found["hostname"], $message);
					$message = str_replace("<DEVICENAME>", $found["device_name"], $message);
					$message = str_replace("<PORTNUMBER>", $found["port_number"], $message);
					$message = str_replace("<PORTNAME>", $found["port_name"], $message);

					/* send out the email */
					if (!$record["discovered"] || $record["notify_schedule"] >= "2") {
						$mail = true;

						if ($record["notify_schedule"] > 2) {
							if (strtotime($record["date_last_notif"]) + $record["notify_schedule"] > time()) {
								$mail = false;
							}
						}

						if ($mail) {
							mactrack_mail($record["email_addresses"], $from, $fromname, $subject, $message, $headers = '');
						}
					}

					/* update the the correct information */
					db_execute("UPDATE mac_track_macwatch
						SET
							discovered=1,
							date_last_seen=NOW()" .
							(strtotime($record["date_first_seen"]) == 0 ? ", date_first_seen=NOW()":"") . "
						WHERE mac_address='" . $record["mac_address"] . "'");
				}
			}
		}

		/* process macauth data */
		$mac_auth_frequency = read_config_option("mt_macauth_email_frequency");
		if ($mac_auth_frequency != "disabled") {
			$last_macauth_time = read_config_option("mt_last_macauth_time");

			/* if it's time to e-mail */
			if (($last_macauth_time + ($mac_auth_frequency*60) > time()) ||
				($mac_auth_frequency == 0)) {
				mactrack_process_mac_auth_report($mac_auth_frequency, $last_macauth_time);
			}
		}

		/* process aggregated data */
		db_execute("UPDATE mac_track_aggregated_ports SET active_last=0;");
		db_execute("INSERT INTO mac_track_aggregated_ports
			(site_id, device_id, hostname, device_name,
			vlan_id, vlan_name, mac_address, vendor_mac, ip_address, dns_hostname,
			port_number, port_name, date_last, first_scan_date, count_rec, active_last, authorized)
			SELECT site_id, device_id, hostname, device_name,
			vlan_id, vlan_name, mac_address, vendor_mac, ip_address, dns_hostname,
			port_number, port_name, scan_date, scan_date, 1, 1, authorized
			FROM mac_track_temp_ports
			ON DUPLICATE KEY UPDATE count_rec=count_rec+1, active_last=1, date_last=mac_track_temp_ports.scan_date");

		/* purge the ip address and temp port table */
		db_execute("TRUNCATE TABLE mac_track_temp_ports");
		db_execute("DELETE FROM mac_track_ips WHERE scan_date<'$scan_date'");
		db_execute("OPTIMIZE TABLE mac_track_ips");
		db_execute("TRUNCATE TABLE mac_track_scan_dates");
		db_execute("REPLACE INTO mac_track_scan_dates (SELECT DISTINCT scan_date from mac_track_ports);");
	}else{
		cacti_log("NOTE: MACTRACK has no devices to process at this time\n");
	}
}
Esempio n. 2
0
	case "-h":
	case "-v":
	case "--version":
	case "--help":
		display_help();
		exit;
	default:
		print "ERROR: Invalid Parameter " . $parameter . "\n\n";
		display_help();
		exit;
	}
}

/* place a process marker in the database */
if (!$test_mode) {
	db_process_add($device_id, TRUE);
}

/* get device information */
$device = db_fetch_row("SELECT * FROM mac_track_devices WHERE device_id =" . $device_id);
if (sizeof($device) == 0) {
	mactrack_debug("ERROR: Device with Id of '$device_id' not found in database.  Can not continue.");
	db_process_remove($device_id);
	exit;
}

/* get the site name */
$site = db_fetch_cell("SELECT site_name FROM mac_track_sites WHERE site_id ='" . $device["site_id"] . "'");
if (strlen($site) == 0) {
	mactrack_debug("ERROR: Site not found in database. Can not continue.");
	db_process_remove($device_id);
                exit;
        }
    }
}
/* check if you need to run or not */
if (read_config_option('mt_reverse_dns') == 'on') {
    $timeout = read_config_option('mt_dns_timeout');
    $dns_primary = read_config_option('mt_dns_primary');
    $dns_secondary = read_config_option('mt_dns_secondary');
    $primary_down = FALSE;
    $secondary_down = FALSE;
} else {
    exit;
}
/* place a process marker in the database for the ip resolver */
db_process_add(0, TRUE);
if ($site_id != '') {
    $sql_where = 'AND site_id=$site_id';
} else {
    $sql_where = '';
}
/* loop until you are it */
while (1) {
    $processes_running = db_fetch_cell('SELECT COUNT(*)
		FROM mac_track_processes
		WHERE device_id != 0');
    $run_status = db_fetch_assoc("SELECT last_rundate,\n\t\tCOUNT(last_rundate) AS devices\n\t\tFROM mac_track_devices\n\t\tWHERE disabled = ''\n\t\t{$sql_where}\n\t\tGROUP BY last_rundate\n\t\tORDER BY last_rundate DESC");
    if (sizeof($run_status) == 1 && $processes_running == 0) {
        $break = TRUE;
    } else {
        $break = FALSE;