A simple api that uses ripe and freegeoip to gather information about the given ip
Controller example:
/* trace ip adress
*
*/
public function traceIp($ip){
public function traceIp($format = "html", $ip = "no.ip"){
$octets = explode(".",$ip);
if($ip =="no.ip" OR count($octets) != 4){
$ip = $_SERVER['REMOTE_ADDR'];
}
$date = date("Y-m-d"); // used for logging
$time = date("H:i:s"); // used for logging
$this->load->library('user_agent');
/* if the address is new we should insert it or the tracedetails cant be added later */
if($this->iplog_model->checkIfIpExists($ip) == TRUE){
$this->iplog_model->updateFromIplink($ip, $date, $time); //known address update record
}ELSE{
$dns = gethostbyaddr($ip);
$this->iplog_model->insertIntoIplink($ip, $dns, $date, $time); //new address insert into ip_link
}
//$this->iplog_model->insertIntoIplog($ip, $_SERVER['REQUEST_URI'], $date, $time); //always write to the log, except when only tracing this ip
$request['target'] = $ip;
$request['date'] = $date."T".$time;
$request['request'] = $_SERVER['REMOTE_ADDR'];
$apiArray = array(
array("uri" => "http://www.freegeoip.net/xml/",
"name" => "geo",
"format" => "xml",
"fields" => array()),
array("uri" => "https://stat.ripe.net/data/whois/data.json?resource=",
"name" => "registrant",
"format" => "json",
"fields" => array())
);
$apiAttempts = 3; //3 * 5(usleep) * 2(api's) = 30 sec max running time
if($this->iplog_model->checkIfIpHasTraceDetails($ip) == FALSE){ //if no details are found start trace
//do api calls
foreach($apiArray as $api){
$attempts = 0;
$file = FALSE;
while($file == FALSE and $attempts < $apiAttempts){
$file = file_get_contents($api['uri'].$ip);
$$api['name'] = $file;
usleep(5000000);
$attempts++;
}
}
//convert geo data
$xml = simplexml_load_string($geo);
$json = json_encode($xml);
$geoArray = json_decode($json,TRUE);
//convert registrant data
$registrantArray= json_decode($registrant,TRUE);
$newRegistrantArray = array();
$loop = 0;
foreach ($registrantArray['data']['records'][0] as $row){
if($row['key'] == "netname"){
$newRegistrantArray['netname']=$row['value'];
}
if($row['key'] == "descr"){
$newRegistrantArray['descr']=$row['value'];
}
if($row['key'] == "admin-c"){
$newRegistrantArray['admin-c']=$row['value'];
}
//echo $registrantArray['data']['records'][0][$loop]['key'];
$loop++;
//print_r($row);
}
foreach ($registrantArray['data']['irr_records'][0] as $row){
if($row['key'] == "mnt-by"){
$newRegistrantArray['mnt-by']=$row['value'];
}
}
//validate the registrant array
$validateArray = array("netname","descr","admin-c","mnt-by");
foreach($validateArray as $row){
$validatedRegistrantArray[$row]=$row." unknown";
if(isset($newRegistrantArray[$row]) and !is_array($newRegistrantArray[$row]) and $newRegistrantArray[$row] != ""){
$validatedRegistrantArray[$row]=$newRegistrantArray[$row];
}
}
//validate the geo array
$validateArray = array("CountryCode","CountryName","RegionCode","RegionName","City","ZipCode","TimeZone","Latitude","Longitude");
foreach($validateArray as $row){
$newGeoArray[$row]=$row." unknown";
if(!is_array($geoArray[$row]) and $geoArray[$row] != ""){
$newGeoArray[$row]=$geoArray[$row];
}
}
$locationSave= implode(",", $newGeoArray);
$registrantSave = implode(",", $validatedRegistrantArray);
$this->iplog_model->updateIpTraceDetails($ip, $locationSave, $registrantSave);
}
//details found, no trace needed
$result = $this->iplog_model->getTraceDetailsFor($ip);
$geoArray= explode(",",$result['0']['location']);
$registrantArray = explode(",",$result['0']['registrant']);
$dns = $result['0']['dns'];
$response = array("request" => $request['request'],
"target" => $request['target'],
"date" => $request['date'],
"ip" => $ip,
"dns" => $dns,
"country_code" => $geoArray['0'],
"country_name" => $geoArray['1'],
"region_code" => $geoArray['2'],
"region_name" => $geoArray['3'],
"city" => $geoArray['4'],
"zipcode" => $geoArray['5'],
"timezone" => $geoArray['6'],
"latitude" => $geoArray['7'],
"longitude" => $geoArray['8'],
"network" => $registrantArray[0].$registrantArray[1],
"admin" => $registrantArray[2],
"provider" => $registrantArray[3],
"platform" => $this->agent->platform,
"browser" => $this->agent->browser." / ".$this->agent->version,
"geo_link" => $apiArray[0]['uri'].$ip,
"registar_link" => $apiArray[1]['uri'].$ip,
"google_link" => "https.www.google.nl/maps/place/".$geoArray['7'].",".$geoArray['8']);
//use $format to select template
switch($format){
case 'html':
$this->parser->parse('site/trace/trace.html.php',$response);
break;
case 'xml':
$this->parser->parse('site/trace/trace.xml.php',$response);
break;
case 'soap':
$this->parser->parse('site/trace/trace.soap.php',$response);
break;
case 'json':
$this->parser->parse('site/trace/trace.json.php',$response);
break;
default:
$this->parser->parse('site/trace/trace.html.php',$response);
break;
}
}
The code for the view is very minimal. The api calls in the controller create
quite some latency. Therefore we use jQuery to load the results in the required template.
View example:
<a href="#" data-toggle="tooltip" data-placement="top" title="{ip}">
<i class="fa fa-terminal fa-1x">
{ip}
</i>
</a>
<br />
<a href="#" data-toggle="tooltip" data-placement="top" title="{dns}">
<i class="fa fa-compress fa-1x">
{dns}
</i>
</a>
<br />
<a href="#" data-toggle="tooltip" data-placement="top" title="{country}">
<i class="fa fa-globe fa-1x">
{country}
</i>
</a>
<br />
<a href="#" data-toggle="tooltip" data-placement="top" title="{region}">
<i class="fa fa-map-signs fa-1x">
{region}
</i>
</a>
<br />
<a href="#" data-toggle="tooltip" data-placement="top" title="{network}">
<i class="fa fa-map-signs fa-1x">
{network}
</i>
</a>
<br />
<a href="#" data-toggle="tooltip" data-placement="top" title="{provider}">
<i class="fa fa-map-signs fa-1x">
{provider}
</i>
</a>
<br />
jQuery example:
<script>
$( "#result" ).load( "/site/traceip/html/" );
</script>