/*
server.php: Web interface into tr2dot.py
Copyright (C) 2004, Perry Lorier
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact me:
IRC: Isomer on Undernet
Email: tr at isomer meta net nz
Requires the "graphviz" package to work
Expects the directories "data/" and "output/" to be writable by the webserver
process:
mkdir data output
chmod a+w,o+t data output
You'll need some truetype fonts installed somewhere, otherwise graphviz
tends to look "ass".
*/
$only = $_REQUEST["only"];
$host = $_REQUEST["host"];
$magic = $_REQUEST["magic"];
$version = $_REQUEST["version"];
$server = $_REQUEST["server"];
/* Deal with traceroute from this host only */
if (isset($only)=="Traceroute from this host only") {
header("Location: $server?ip=$host");
exit;
}
$error=array();
if ($magic=="more magic" && $version<7 && strlen($version)!=0) {
$error[]="Your version of tr.php is out of date
Please update your client
\n";
}
if (!file_exists("data")) {
?>
data/ directory doesn't exist. server.php needs the data directory to exist
and to be writable by the webserver process.
eg:
mkdir data
chmod a+w,o+t data
See the top of server.php for details.
exit;
}
if (!file_exists("output")) {
?>
output/ directory doesn't exist. server.php needs the output directory to exist
and to be writable by the webserver process. This directory is used to store
the final output images. You may wish to create a cron job to clean out
files in this directory that are older than a few days.
eg:
mkdir output
chmod a+w,o+t output
See the top of server.php for details.
exit;
}
require('DB.php');
$db=DB::Connect('pgsql://www-data@unix(/var/run/postgresql)/tr');
if (PEAR::isError($db)) {
die($db->getMessage());
}
function as2name($asn)
{
global $db;
if ($db) {
$res=$db->getOne("SELECT name FROM asnames WHERE asnum=?",$asn);
if (!PEAR::IsError($res) && $res)
$asn=$res;
}
return $asn;
}
function ip2as($ip)
{
/* Look up the AS of the IP of the host */
$f=@fsockopen("localhost",1234);
if ($f===FALSE)
return 0;
fwrite($f,$ip."\n");
$asn=0;
while(!feof($f)) {
$l=fgets($f,1024);
if (substr($l,0,1)=="%")
continue;
if (strpos($l,":")) {
list($key,$value) = explode(":",$l);
if ($key=="origin") {
$asn=substr(trim($value),2);
break;
}
}
}
fclose($f);
return $asn;
}
function display_server($server)
{
global $db;
$ret='";
$ret.=htmlspecialchars($server["servername"]);
$ret.="
\n";
return $ret;
}
function cmp_asname($a, $b)
{
$aval = $a["asname"];
$bval = $b["asname"];
return strcmp($aval, $bval);
}
/* Load the databases */
function load_hosts() {
global $db;
$hosts_res=$db->query("SELECT * FROM hosts WHERE lastseen>now()::abstime::int4-30*24*60*60");
$hosts=array();
$hostinfo=array();
$ases=array();
while($host=$hosts_res->fetchrow(DB_FETCHMODE_ASSOC)) {
$hosts[]=$host["hostname"];
/* Do IP and AS lookup now so we can sort on them */
$host["servername"] = preg_replace("@http://([^:/]*).*@", "$1",
$host["hostname"]);
if (!strlen($host["error"]) && !strlen($host["ip"])) {
$host["ip"]=gethostbyname($host["servername"]);
if ($host["ip"]===FALSE) {
$host["error"]="Unable to resolve ".$host["servername"];
}
$db->query("UPDATE hosts SET ip=?, error=? WHERE hostname=?",
array($host["ip"],$host["error"],$host["hostname"]));
}
$host["asn"] = ip2as($host["ip"]);
$host["asname"] = as2name($host["asn"]);
$ases[$host["asn"]] = $host["asname"];
$hostinfo[$host["hostname"]]=$host;
}
uasort($hostinfo, "cmp_asname");
return array($hosts,$hostinfo, $ases);
}
if (!isset($host) && $_REQUEST["action"]!="results") {
/* Add the server */
$this_host=$_SERVER["HTTP_REFERER"];
$matches=array();
preg_match("@://([^:/]*)@",$this_host,$matches);
$hostname=$matches[1];
if (strlen($this_host) && $hostname
&& $_REQUEST["magic"]="more magic") {
if ($ip===FALSE
||preg_match("/^192\.168\./",$hostname)
||preg_match("/^10\./",$hostname)) {
$error[]="Cannot resolve your host";
} else if (!preg_match("/\/(tr|traceroute(mesh)?)\.(php|ashx)$/",$this_host)) {
$error[]="Can't find script to register";
} else {
$ip=gethostbyname($hostname);
$res=$db->query("SELECT * FROM hosts WHERE hostname=? or ip=?",array(
$this_host,$ip));
if ($res->numrows()==0) {
$db->query("INSERT INTO hosts (hostname,lastseen,ip) VALUES (?,?,?)",
array($this_host,time(),$ip));
}
else {
$res=$db->query("UPDATE hosts set hostname=?,lastseen=?,ip=? WHERE ip=? or hostname=?",
array($this_host,time(),$ip,$ip,$this_host));
$res=$db->query("SELECT * FROM hosts WHERE hostname=?",array($this_host));
$row=$res->fetchrow(DB_FETCHMODE_ASSOC);
}
}
}
?>
Note: Traceroutes may take a couple of minutes to complete, please be patient.
The full mesh picture will be large, scroll around to see the full thing.