<?php
/*
$Id: update_cache.php 579 2014-05-17 21:23:44Z bhockney $
(C) 2003-2014 by Bob Hockney <zeus@ix.netcom.com>

update hostnames cache

This code is distributed under the terms of GNU GPL
*/
?>

<?php

if (!isset($sql_update)) {

	$refresh = 1;
	$link = db("open", "$database");

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" 
		"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
  <title>Webfwlog - Update Cache</title>
  <LINK REL=StyleSheet HREF="style.css" TYPE="text/css" MEDIA=screen>
</head>

<body bgcolor=#FFFFFF>
	<?php if ($config["debug"]) include "include/debug.php"; ?>
	<div align="center"><h1><?php print "{$config["title"]}"; ?></h1></div>

	<font size="+2">
	<p>
	Updating hostname cache now..<br>
	<br>
	This may take a LONG time...<br>
	<br>

	<form action="<?php print "$self"; ?>" method="POST">
<?php
	foreach ($FWLOG as $a => $b) {
		if (!($a == "action" or $a == "data_tables")) {
			print "<input type='hidden' name='".htmlspecialchars("$a", ENT_QUOTES).
				"' value='".htmlspecialchars("$b", ENT_QUOTES)."'>\n";
		}
	}
?>

	<input type="submit" name="action" value="cancel">
	<p>

<?php

} else {

// If cache is being updated at time report is run, only update
// hostnames and services appearing in report

	$refresh = 2;
}

flush();

if (isset($config["php_update_timeout"]))
	set_time_limit("{$config["php_update_timeout"]}");

if (isset($FWLOG["action"]) and strtolower("{$FWLOG["action"]}") == "resolve hosts") {
	$a = "{$config["addr_type"]}";
	$t = "";
} else {
	$a = "_t";
	$t = "_t";
}

if (isset($config["iptype"])) {
	if ($config["wfwl_iptype"] == "int") {
	if ($config["iptype"] == "int") {
		$ip_saddr = "$tmp_output.ip_saddr$a";
		$ip_daddr = "$tmp_output.ip_daddr$a";
	} else {
		$ip_saddr = "$inet_aton($tmp_output.ip_saddr$a)";
		$ip_daddr = "$inet_aton($tmp_output.ip_daddr$a)";
	}
	} elseif ($config["wfwl_iptype"] == "inet") {  // postgresql
	if ($config["iptype"] == "inet") {
		$ip_saddr = "$tmp_output.ip_saddr$a";
		$ip_daddr = "$tmp_output.ip_daddr$a";
	} elseif ($config["iptype"] == "int") {
		$ip_saddr = "$inet_ntoa($tmp_output.ip_saddr$a)::inet";
		$ip_daddr = "$inet_ntoa($tmp_output.ip_daddr$a)::inet";
	} else {  // iptype = text
		$ip_saddr = "trim($tmp_output.ip_saddr$a)::inet";
		$ip_daddr = "trim($tmp_output.ip_daddr$a)::inet";
	}
	} elseif ($config["wfwl_iptype"] == "bin") {  // mysql
	if ($config["iptype"] == "bin") {
		$ip_saddr = "$tmp_output.{$q}ip_saddr$a{$q}";
		$ip_daddr = "$tmp_output.{$q}ip_daddr$a{$q}";
	} elseif ($config["iptype"] == "int")  {
		$ip_saddr = "$inet_pton(".AF_INET6.", $inet_ntoa($tmp_output.ip_saddr$a))";
		$ip_daddr = "$inet_pton(".AF_INET6.", $inet_ntoa($tmp_output.ip_daddr$a))";
	} else {
		$ip_saddr = "$inet_pton(".AF_INET6.", $tmp_output.ip_saddr$a)";
		$ip_daddr = "$inet_pton(".AF_INET6.", $tmp_output.ip_daddr$a)";
	}
	}
}

$hostupdatetime = 0;
$servicesupdatetime = 0;
$cachepopulatetime = 0;
if (!isset($querytime))
	$querytime = 0;


if ($config["have_hostnames"] and (isset($FWLOG["c_dst_host"]) or isset($FWLOG["c_src_host"])
		or isset($FWLOG["populate_cache"]) 
		or isset($FWLOG["populate_cache_full"])
		or (isset($FWLOG["action"])
			and (strtolower("{$FWLOG["action"]}") == "update cache"
				or strtolower("{$FWLOG["action"]}") == "resolve hosts")))) {
	if (isset($sql_update) and $config["db"] == "mysql") {
		if ($config["wfwl_iptype"] == "int")
			$addr_type = "INTEGER UNSIGNED";
		else // type = bin
			$addr_type = "VARBINARY(16)"; 
		db("statement",
			"CREATE TEMPORARY TABLE $update\n".
				"\t(refresh INTEGER UNSIGNED NOT NULL DEFAULT 1,\n".
				"\tip_addr $addr_type DEFAULT NULL)", $link
		);
	}
	if (isset($sql_update) and isset($FWLOG["upd_hosts"]) and isset($FWLOG["c_dst_host"])) {
		if ($config["db"] == "mysql") {
			db("statement",
				"INSERT INTO $update (refresh, ip_addr)\n".
					"\tSELECT DISTINCT 2, $ip_daddr FROM $tmp_output\n".
					"\t\tLEFT JOIN $hostnames ON $ip_daddr=$hostnames.ip_addr\n".
					"\tWHERE $hostnames.ip_addr IS NULL OR $hostnames.refresh=1", $link
			);
		} elseif ($config["db"] == "pgsql") {
			db("statement",
				"UPDATE $hostnames SET refresh=2 FROM $tmp_output\n".
					"\tWHERE $hostnames.ip_addr=$ip_daddr\n".
					"\tAND $hostnames.refresh=1;", $link
			);
			db("statement",
				"INSERT INTO $hostnames (refresh, ip_addr)\n".
					"\tSELECT DISTINCT 2, $ip_daddr FROM $tmp_output\n".
					"\t\tLEFT JOIN $hostnames ON $ip_daddr=ip_addr\n".
					"\tWHERE ip_addr IS NULL;", $link
			);
		}
	}
	if (isset($sql_update) and isset($FWLOG["upd_hosts"]) and isset($FWLOG["c_src_host"])) {
		if ($config["db"] == "mysql") {
			db("statement",
				"INSERT INTO $update (refresh, ip_addr)\n".
					"\tSELECT DISTINCT 2, $ip_saddr FROM $tmp_output\n".
					"\t\tLEFT JOIN $hostnames ON $ip_saddr=$hostnames.ip_addr\n".
					"\tWHERE $hostnames.ip_addr IS NULL OR $hostnames.refresh=1", $link
			);
		} elseif ($config["db"] == "pgsql") {
			db("statement",
				"UPDATE $hostnames SET refresh=2 FROM $tmp_output\n".
					"\tWHERE $hostnames.ip_addr=$ip_saddr\n".
					"\tAND $hostnames.refresh=1;", $link
			);
			db("statement",
				"INSERT INTO $hostnames (refresh, ip_addr)\n".
					"\tSELECT DISTINCT 2, $ip_saddr FROM $tmp_output\n".
					"\t\tLEFT JOIN $hostnames ON $ip_saddr=ip_addr\n".
					"\tWHERE ip_addr IS NULL;", $link
			);
		}
	}
	if (isset($sql_update) and isset($FWLOG["upd_hosts"]) and $config["db"] == "mysql") {
		db("statement",
			"REPLACE INTO $hostnames (refresh, ip_addr)\n".
				"\tSELECT DISTINCT refresh, ip_addr FROM $update", $link
		);
		db("statement", "DROP TABLE $update", $link);
	}
	$hostupdatetime = time() - $time - $querytime;
	if (isset($sql_update) and (isset($FWLOG["populate_cache"]) or isset($FWLOG["populate_cache_full"]))) {
		if ($config["db"] == "mysql") {
			if (isset($FWLOG["c_dst_host"]) or isset($FWLOG["populate_cache_full"]))
				db("statement",
					"INSERT IGNORE INTO $hostnames (refresh, ip_addr)\n".
						"\tSELECT DISTINCT 1, $ip_daddr FROM $tmp_output\n", $link
				);
			if (isset($FWLOG["c_src_host"]) or isset($FWLOG["populate_cache_full"]))
				db("statement",
					"INSERT IGNORE INTO $hostnames (refresh, ip_addr)\n".
						"\tSELECT DISTINCT 1, $ip_saddr FROM $tmp_output\n", $link
				);
		} elseif ($config["db"] == "pgsql") {
			if (isset($FWLOG["c_dst_host"]) or isset($FWLOG["populate_cache_full"]))
				db("statement",
					"INSERT INTO $hostnames (refresh, ip_addr)\n".
						"\tSELECT DISTINCT 1, $ip_daddr FROM $tmp_output\n".
						"\t\tLEFT JOIN $hostnames ON $ip_daddr=ip_addr\n".
						"\tWHERE ip_addr IS NULL", $link
				);
			if (isset($FWLOG["c_src_host"]) or isset($FWLOG["populate_cache_full"]))
				db("statement",
					"INSERT INTO $hostnames (refresh, ip_addr)\n".
						"\tSELECT DISTINCT 1, $ip_saddr FROM $tmp_output\n".
						"\t\tLEFT JOIN $hostnames ON $ip_saddr=ip_addr\n".
						"\tWHERE ip_addr IS NULL;", $link
				);
		}
	}
	$cachepopulatetime = time() - $time - $hostupdatetime - $querytime;
	$newhosts = db("statement", "SELECT ip_addr FROM $hostnames WHERE refresh>=$refresh;", $link);
	$newrows = db("totalrows", $newhosts);
	if (!isset($sql_update)) {
		print "$newrows New unique hosts found!<br>\n";
		if ($newrows) print "Resolving $newrows new hostnames ";
		flush();
	}

	$tick_count = 10;
	$progress = $tick_count;
	$rownum = 0;
	while ($line = db("nextrow", $newhosts)) {
		if (!isset($sql_update) and ++$progress > $tick_count) {
			print ". ";
			flush();
			$progress = 0;
		}
		$addr = "{$line["ip_addr"]}";
		if ($config["wfwl_iptype"] == "int")
			$str_addr = long2ip($addr);
		elseif ($config["wfwl_iptype"] == "bin")
			$str_addr = $php_inet_ntop($addr);
		else
			$str_addr = "$addr";
		$host = gethostbyaddr("$str_addr");
		if ($host == "$str_addr") $host = "-";
		if ($config["wfwl_iptype"] == "inet")
			db("statement", "UPDATE $hostnames SET refresh=0, hostname='$host' WHERE ip_addr='$addr';", $link);
		elseif ($config["wfwl_iptype"] == "bin")
			db("statement", "UPDATE $hostnames SET refresh=0, hostname='$host' WHERE ip_addr=$inet_pton(".AF_INET6.", '$str_addr');", $link);
		else // type = int
			db("statement", "UPDATE $hostnames SET refresh=0, hostname='$host' WHERE ip_addr=$addr;", $link);
	}
	if (!isset($sql_update))
		print "<br>\n";

	$hostupdatetime = time() - $time - $cachepopulatetime - $querytime;
}
if (!isset($sql_update)) {
	print "<br>\n";
	$hostupdatetime = $hostupdatetime + $cachepopulatetime;
	$cachepopulatetime = 0;
}

if ($config["have_services"] and (isset($FWLOG["c_dst_service"]) or isset($FWLOG["c_src_service"])
		or isset($FWLOG["populate_cache"])
		or (isset($FWLOG["action"])
			and (strtolower("{$FWLOG["action"]}") == "update cache"
				or strtolower("{$FWLOG["action"]}") == "resolve hosts")))) {
	if ($config["db"] == "mysql") {
		if (isset($sql_update) and isset($FWLOG["upd_hosts"])) 
			db("statement",
				"CREATE TEMPORARY TABLE $update\n".
					"\t(refresh INTEGER UNSIGNED NOT NULL DEFAULT 1,\n".
					"\tip_protocol INTEGER UNSIGNED DEFAULT NULL,\n".
					"\tport INTEGER UNSIGNED NULL DEFAULT NULL)", $link
			);
	}
	if (isset($sql_update) and isset($FWLOG["upd_hosts"]) and isset($FWLOG["c_dst_service"])) {
		if ($config["db"] == "mysql") {
			db("statement",
				"INSERT INTO $update (refresh, ip_protocol, port)\n".
					"\tSELECT DISTINCT 2, $tmp_output.ip_protocol$t, $tmp_output.tcp_dport$t FROM $tmp_output\n".
					"\t\tLEFT JOIN $services\n".
					"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND tcp_dport$t=$services.port\n".
					"\tWHERE (tcp_dport$t IS NOT NULL AND ($services.port IS NULL OR $services.refresh=1))", $link
			);
			db("statement",
				"INSERT INTO $update (refresh, ip_protocol, port)\n".
					"\tSELECT DISTINCT 2, $tmp_output.ip_protocol$t, $tmp_output.udp_dport$t FROM $tmp_output\n".
					"\t\tLEFT JOIN $services\n".
					"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND udp_dport$t=$services.port\n".
					"\tWHERE (udp_dport$t IS NOT NULL AND ($services.port IS NULL OR $services.refresh=1))", $link
			);
		} elseif ($config["db"] == "pgsql") {
			db("statement",
				"UPDATE $services SET refresh=2 FROM $tmp_output\n".
					"\tWHERE $services.ip_protocol=$tmp_output.ip_protocol$t\n".
					"\tAND (port=tcp_dport$t OR port=udp_dport$t)\n".
					"\tAND $services.refresh=1;", $link
			);
			db("statement",
				"INSERT INTO $services (refresh, ip_protocol, port)\n".
					"\tSELECT DISTINCT 2, $tmp_output.ip_protocol$t, udp_dport$t FROM $tmp_output\n".
					"\t\tLEFT JOIN $services\n".
					"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND udp_dport$t=port\n".
					"\tWHERE (udp_dport$t IS NOT NULL AND port IS NULL)\n".
					"\tUNION\n".
					"\tSELECT DISTINCT 2, $tmp_output.ip_protocol$t, tcp_dport$t FROM $tmp_output\n".
					"\t\tLEFT JOIN $services\n".
					"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND tcp_dport$t=port\n".
					"\tWHERE (tcp_dport$t IS NOT NULL AND port IS NULL);", $link
			);


		}
	}
	if (isset($sql_update) and isset($FWLOG["upd_hosts"]) and isset($FWLOG["c_src_service"])) {
		if ($config["db"] == "mysql") {
			db("statement",
				"INSERT INTO $update (refresh, ip_protocol, port)\n".
					"\tSELECT DISTINCT 2, $tmp_output.ip_protocol$t, $tmp_output.tcp_sport$t FROM $tmp_output\n".
					"\t\tLEFT JOIN $services\n".
					"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND tcp_sport$t=$services.port\n".
					"\tWHERE (tcp_sport$t IS NOT NULL AND ($services.port IS NULL OR $services.refresh=1))", $link
			);
			db("statement",
				"INSERT INTO $update (refresh, ip_protocol, port)\n".
					"\tSELECT DISTINCT 2, $tmp_output.ip_protocol$t, $tmp_output.udp_sport$t FROM $tmp_output\n".
					"\t\tLEFT JOIN $services\n".
					"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND udp_sport$t=$services.port\n".
					"\tWHERE (udp_sport$t IS NOT NULL AND ($services.port IS NULL OR $services.refresh=1))", $link
			);
		} elseif ($config["db"] == "pgsql") {
			db("statement",
				"UPDATE $services SET refresh=2 FROM $tmp_output\n".
					"\tWHERE $services.ip_protocol=$tmp_output.ip_protocol$t\n".
					"\tAND (port=tcp_sport$t OR port=udp_sport$t)\n".
					"\tAND $services.refresh=1;", $link
			);
			db("statement",
				"INSERT INTO $services (refresh, ip_protocol, port)\n".
					"\tSELECT DISTINCT 2, $tmp_output.ip_protocol$t, udp_sport$t FROM $tmp_output\n".
					"\t\tLEFT JOIN $services\n".
					"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND udp_sport$t=port\n".
					"\tWHERE (udp_sport$t IS NOT NULL AND port IS NULL)\n".
					"\tUNION\n".
					"\tSELECT DISTINCT 2, $tmp_output.ip_protocol$t, tcp_sport$t FROM $tmp_output\n".
					"\t\tLEFT JOIN $services\n".
					"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND tcp_sport$t=port\n".
					"\tWHERE (tcp_sport$t IS NOT NULL AND port IS NULL);", $link
			);
		}
	}
	if (isset($sql_update) and isset($FWLOG["upd_hosts"]) and $config["db"] == "mysql") {
		db("statement",
			"REPLACE INTO $services (refresh, ip_protocol, port)\n".
				"\tSELECT DISTINCT refresh, ip_protocol, port FROM $update", $link
		);
		db("statement", "DROP TABLE $update", $link);
	}
	$servicesupdatetime = time() - $time - $hostupdatetime - $cachepopulatetime - $querytime;
	if (isset($sql_update) and (isset($FWLOG["populate_cache"]) or isset($FWLOG["populate_cache_full"]))) {
		if ($config["db"] == "mysql") {
			if (isset($FWLOG["c_dst_service"]) or isset($FWLOG["populate_cache_full"])) {
				db("statement",
					"INSERT IGNORE INTO $services (refresh, ip_protocol, port)\n".
						"\tSELECT DISTINCT 1, ip_protocol$t, tcp_dport$t FROM $tmp_output\n".
						"\tWHERE tcp_dport$t IS NOT NULL;", $link
				);
				db("statement",
					"INSERT IGNORE INTO $services (refresh, ip_protocol, port)\n".
						"\tSELECT DISTINCT 1, ip_protocol$t, udp_dport$t FROM $tmp_output\n".
						"\tWHERE udp_dport$t IS NOT NULL;", $link
				);
			}
			if (isset($FWLOG["c_src_service"]) or isset($FWLOG["populate_cache_full"])) {
				db("statement",
					"INSERT IGNORE INTO $services (refresh, ip_protocol, port)\n".
						"\tSELECT DISTINCT 1, ip_protocol$t, tcp_sport$t FROM $tmp_output\n".
						"\tWHERE tcp_sport$t IS NOT NULL;", $link
				);
				db("statement",
					"INSERT IGNORE INTO $services (refresh, ip_protocol, port)\n".
						"\tSELECT DISTINCT 1, ip_protocol$t, udp_sport$t FROM $tmp_output\n".
						"\tWHERE udp_sport$t IS NOT NULL;", $link
				);
			}
		} elseif ($config["db"] == "pgsql") {
			if (isset($FWLOG["c_dst_service"]) or isset($FWLOG["populate_cache_full"]))
				db("statement",
					"INSERT INTO $services (refresh, ip_protocol, port)\n".
						"\tSELECT DISTINCT 1, $tmp_output.ip_protocol$t, tcp_dport$t FROM $tmp_output\n".
						"\t\tLEFT JOIN $services\n".
						"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND tcp_dport$t=port\n".
						"\tWHERE (tcp_dport$t IS NOT NULL AND port IS NULL)\n".
						"\tUNION\n".
						"\tSELECT DISTINCT 1, $tmp_output.ip_protocol$t, udp_dport$t FROM $tmp_output\n".
						"\t\tLEFT JOIN $services\n".
						"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND udp_dport$t=port\n".
						"\tWHERE (udp_dport$t IS NOT NULL AND port IS NULL)", $link
				);
			if (isset($FWLOG["c_src_service"]) or isset($FWLOG["populate_cache_full"]))
				db("statement",
					"INSERT INTO $services (refresh, ip_protocol, port)\n".
						"\tSELECT DISTINCT 1, $tmp_output.ip_protocol$t, tcp_sport$t FROM $tmp_output\n".
						"\t\tLEFT JOIN $services\n".
						"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND tcp_sport$t=port\n".
						"\tWHERE (tcp_sport$t IS NOT NULL AND port IS NULL)\n".
						"\tUNION\n".
						"\tSELECT DISTINCT 1, $tmp_output.ip_protocol$t, udp_sport$t FROM $tmp_output\n".
						"\t\tLEFT JOIN $services\n".
						"\t\t\tON $tmp_output.ip_protocol$t=$services.ip_protocol AND udp_sport$t=port\n".
						"\tWHERE (udp_sport$t IS NOT NULL AND port IS NULL);", $link
				);
		}
	}
	$cachepopulatetime = time() - $time - $hostupdatetime - $servicesupdatetime - $querytime;
	$newservices = db("statement", "SELECT port, ip_protocol FROM $services WHERE refresh>=$refresh;", $link);
	$newrows = db("totalrows", $newservices);
	if (!isset($sql_update)) {
		print "$newrows New services found!<br>\n";
		if ($newrows) print "Resolving $newrows new services . . . <br>\n";
		flush();
	}
	$rownum = 0;
	while ($line = db("nextrow", $newservices)) {
		$port = $line["port"];
		$proto = $line["ip_protocol"];
		$service = getservbyport($port, getprotobynumber($proto));
		if ($service == "") $service = "-";
		db("statement", "UPDATE $services SET refresh=0, service='$service' WHERE port=$port AND ip_protocol=$proto;", $link);
	}
	$servicesupdatetime = time() - $time - $hostupdatetime - $cachepopulatetime - $querytime;
}
if (!isset($sql_update)) {
	print "<br>\n";

	$serviceupdatetime = $servicesupdatetime + $cachepopulatetime;

	db("close", $link);

	print "Host Update time was $hostupdatetime seconds<br>\n";
	print "Services Update time was $servicesupdatetime seconds<br>\n";

?>
	<p>
	<input type="submit" name="action" value="Done">
	</font>
	
</body>
</html>
<?php
}

// vim:set ts=4:

?>
