Skip to content

Instantly share code, notes, and snippets.

@jamesstout
Created April 29, 2013 13:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesstout/5481535 to your computer and use it in GitHub Desktop.
Save jamesstout/5481535 to your computer and use it in GitHub Desktop.
Script to look up the location of a list of IP addresses. Uses ipinfodb.com. Writes known IP info to a file to prevent repeat lookups.
<?php
// URL is http://api.ipinfodb.com/v3/ip-city/?key=526979f6d541396cee8be6452c39419e6d7eff9433febf55fe0bb1c27b14bb95&ip=74.125.45.100
/* response should be something like
{
"statusCode" : "OK",
"statusMessage" : "",
"ipAddress" : "180.169.76.237",
"countryCode" : "CN",
"countryName" : "CHINA",
"regionName" : "SHANGHAI",
"cityName" : "SHANGHAI",
"zipCode" : "-",
"latitude" : "31.2222",
"longitude" : "121.458",
"timeZone" : "+08:00"
}
Errors include:
"statusCode" : "ERROR",
"statusMessage" : "Invalid API key.",
*/
if (!ini_get('display_errors')) {
ini_set('display_errors', 0);
}
header('Content-type: text/html');
outputHeader();
set_time_limit(0);
ini_set('max_execution_time', 300);
$curl_error_str;
$curl_error_no;
$info = array();
$path = dirname(__FILE__);
$dodgyIPsFile = $path . '/dodgyIPs.txt';
$newIPsFile = $path . '/newIPs.txt';
//get IPs we have already looked up
// and stored to our file
$dodgyIPsAlreadyDone = readIPInfoFromFile();
// read in new IPs (actually it's all the IPs, not just new)
// can contain duplicates as we weed them out later
$newDodgyIPs = readNEWIPsFromFile();
#echo "<pre> All IPs = ".count($newDodgyIPs)."</pre>";
// remove dupes
$newDodgyIPs = array_unique($newDodgyIPs);
#echo "<pre> All UNIQUE IPs = ".count($newDodgyIPs)."</pre>";
//var_dump($newDodgyIPs);
// now we need to trim $newDodgyIPs so it only contains truly new IPs
$newDodgyIPs = trimDodgyIPs($newDodgyIPs, $dodgyIPsAlreadyDone);
//var_dump($newDodgyIPs);
//echo "<pre>".count($newDodgyIPs, 1)."</pre>";
//echo "<pre>".print_r($newDodgyIPs,1)."</pre>";
#echo count($newDodgyIPs) . "\n";
// re-written to do 5 look-ups each time
// to prevent timeout
if(count($newDodgyIPs)>5){
echo "<pre> New IP count is > 5: ".count($newDodgyIPs,1)."</pre>";
echo "<pre> Just doing 5 IPs, keep refreshing to complete</pre>";
echo "</body></html>";
}
try {
$count = 0;
foreach ($newDodgyIPs as $key => $IP) {
//echo "<pre>" .print_r($key,1). " = " .print_r($IP,1)."</pre>";
$count++;
#echo "count is $count\n";
if($count > 5){
break;
}
$response = getIPLocayData($IP);
if (is_array($response)) {
$info[$key] = $response;
}
// rate limit for the IP lookup Web site
sleep(1);
}
// combine new info array with $dodgyIPsAlreadyDone
foreach ($info as $key => $val) {
// use array_push as the array_diff
// in trimDodgyIPs() does not reset the keys
array_push($dodgyIPsAlreadyDone, $val );
}
// write the updated info array back to the file
writeInfoToFile($dodgyIPsAlreadyDone);
// if we get here, all is good, let's output a table
if(count($newDodgyIPs) < 6){
outputResultsTable($dodgyIPsAlreadyDone);
}
}
catch (Exception $ex) {
die("ERROR: " . $ex->getMessage());
}
exit;
function trimDodgyIPs($newDodgyIPs, $dodgyIPsAlreadyDone) {
// grab known IPs
$knownIPs = array();
foreach ($dodgyIPsAlreadyDone as $k=>$v) {
foreach ($v as $column=>$val) {
if ($column == "IP") {
$knownIPs[] = $val;
}
}
}
//echo "<pre> known IPs".count($knownIPs, 1)."</pre>";
//echo "<pre> new IPs".print_r($newDodgyIPs, 1)."</pre>";
// get the diff - note keys are not reset
$realNewDodgyIPs = array_diff($newDodgyIPs, $knownIPs);
//echo "<pre> new IPs".print_r($realNewDodgyIPs, 1)."</pre>";
return $realNewDodgyIPs;
}
function writeInfoToFile($info) {
global $dodgyIPsFile;
//seralise the array to store to disk
$serializedInfo = serialize_safe($info);
// open output file for writing, truncate and in binary mode
// binary mode preserves the line endings in the input file
// \n for Unix, \r\n for Windows.
if (!$handle = fopen($dodgyIPsFile , "w+b")) {
die ("Cannot open $dodgyIPsFile");
}
// Write $serializedInfo to our opened file.
if (fwrite($handle, $serializedInfo) === FALSE) {
echo "Cannot write to file ($dodgyIPsFile)\n";
exit;
}
fclose($handle);
}
function readIPInfoFromFile() {
global $dodgyIPsFile;
if (!$lines = file($dodgyIPsFile)) {
die ("Cannot open $dodgyIPsFile");
}
else {
// it's one base 64 encoded line
$info = unserialize_safe($lines[0]);
//echo "<pre>".print_r($info, 1)."</pre>";
return $info;
}
}
function readNEWIPsFromFile() {
global $newIPsFile;
if (!$lines = file($newIPsFile, FILE_IGNORE_NEW_LINES)) {
die ("Cannot open $newIPsFile");
}
else {
// file() returns an aray
return $lines;
}
}
/**
*
*/
function outputResultsTable($info) {
echo '<table id="box-table-a" >';
echo "<thead><tr>";
foreach ($info as $k=>$v) {
if ($k > 0) {
break;
}
echo "<th>Count</th>";
foreach ($v as $column=>$val) {
if ($column != "IP") echo "<th>$column</th>";
}
}
echo "</tr></thead><tbody>";
$count=1;
foreach ($info as $k=>$v) {
echo "<tr>";
echo "<td>$count</td>";
$count++;
foreach ($v as $column=>$val) {
if ($column != "IP") echo "<td>$val</td>";
}
echo "</tr>";
}
echo "</tbody></table></body></html>";
}
function outputHeader() {
$head=<<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Dodgy IP Addresses</title>
<style>
body{line-height:1.6em}#box-table-a{font-family:"Lucida Sans Unicode","Lucida Grande",Sans-Serif;font-size:12px;margin:45px;width:1250px;text-align:left;border-collapse:collapse}#box-table-a th{font-size:13px;font-weight:normal;padding:8px;background:#b9c9fe;border-top:4px solid #aabcfe;border-bottom:1px solid #fff;color:#039}#box-table-a td{padding:8px;background:#e8edff;border-bottom:1px solid #fff;color:#669;border-top:1px solid transparent}
</style>
</head>
<body>
EOF;
echo $head;
}
/**
*
*
*
*/
function getIPLocayData($IP) {
global $curl_error_str;
global $curl_error_no;
$IPLookupURL = "http://api.ipinfodb.com/v3/ip-city/?key=526979f6d541396cee8be6452c39419e6d7eff9433febf55fe0bb1c27b14bb95&format=json&ip=" . $IP;
$result = CURL($IPLookupURL);
// ensure the request succeeded
if ($curl_error_no != 0) {
throw new Exception("CURL" . $curl_error_str);
}
/**
* For testing various responses
*
*
*/
// test invalid response format
//$result = '"statusCode" : "OK", "statusMessage" : "", "ipAddress" : ""}';
// test statusMessage set response format
//$result = '{"statusCode" : "ERROR", "statusMessage" : "XXX", "ipAddress" : "180.169.76.237", "countryCode" : "CN", "countryName" : "CHINA"}';
// test statusCode mising response format
//$result = '{"statusMessage" : "", "ipAddress" : "180.169.76.237", "countryCode" : "CN", "countryName" : "CHINA"}';
// parse the response data
$data = json_decode($result);
// ensure response data was a valid JSON string
if (!is_object($data)) {
throw new Exception('Invalid response data, not JSON object: ' . $result );
}
// ensure the expected statusCode is present
if (!isset($data->statusCode) ) {
throw new Exception('Invalid response data, statusCode missing: ' . $result );
}
if ($data->statusCode == "ERROR" || $data->statusCode != "OK" ) {
// we have an error, I don't know all the errors, only ERROR
throw new Exception("API error: " . (isset($data->statusMessage) ? $data->statusMessage : "UNKNOWN ERROR" ));
}
// build the response array with the returned data
return array(
'Country Code' => $data->countryCode,
'CountryName' => $data->countryName,
'RegionName' => $data->regionName,
'City' => $data->cityName,
'Zip Code' => $data->zipCode,
'Time Zone' => $data->timeZone,
'Latitude/Longitude'=> "$data->latitude, $data->longitude",
'Google Maps Link' => "<a href=https://maps.google.com/?ll=$data->latitude,$data->longitude > $IP </a>",
'IP' => $IP
);
}
function CURL($url, $retries = 3) {
global $curl_error_str;
global $curl_error_no;
$curl = curl_init($url);
if (is_resource($curl) === true) {
curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 15);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_NOSIGNAL, 1);
curl_setopt($curl, CURLOPT_MAXCONNECTS, 1);
// for testing cURl errors
//curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, 2);
$result = false;
//echo "<pre>".print_r($curl,1)."</pre>";
while (($result === false) && (--$retries > 0)) {
//echo "CURL retries = $retries\n";
$result = curl_exec($curl);
}
// Check if any error occured
if (curl_errno($curl)) {
$curl_error_str = curl_error($curl);
$curl_error_no = curl_errno($curl);
//echo 'Curl error: ' . curl_error($curl);
//echo 'Curl error no: ' . curl_errno($curl);
}
curl_close($curl);
//echo "<pre>Closing CURL</pre>";
}
else {
$curl_error_no = 999;
$curl_error_str = "curl_init() failed for $url";
}
return $result;
}
/**
* Returns a serialized, base64-encoded string from a PHP object
*
*/
function serialize_safe($data = null) {
return base64_encode(serialize($data));
}
/**
* Returns a PHP object from a base64-encoded, serialized string
*
*/
function unserialize_safe($base64_data = '') {
return unserialize(base64_decode($base64_data));
}
?>
01.226.166.237
101.114.4.207
101.210.101.170
101.226.166.237
101.226.167.218
101.226.169.207
101.226.169.226
101.226.169.232
101.226.169.235
103.28.241.101
103.28.241.98
105.173.106.29
106.187.46.48
107.20.73.101
107.22.139.189
107.22.42.94
108.163.128.206
108.163.188.186
108.175.154.229
108.178.2.107
108.21.102.135
108.39.73.191
108.59.252.133
108.59.8.70
108.61.63.165
109.163.231.48
109.75.162.9
109.99.128.37
110.80.92.164
110.85.112.220
110.85.71.200
111.4.120.60
112.111.176.80
112.213.84.166
112.248.75.63
113.162.164.162
114.242.87.141
114.32.109.44
114.80.138.6
115.119.161.62
115.187.79.147
115.68.15.54
116.11.252.194
116.229.239.189
117.135.241.112
117.24.50.163
117.26.201.66
117.26.84.127
117.27.139.8
117.28.79.21
117.32.153.137
118.122.33.160
118.139.177.86
118.142.98.189
118.26.233.211
119.31.233.40
119.36.186.44
119.63.196.96
120.43.8.102
121.119.187.55
121.54.44.182
121.8.148.61
121.8.154.28
121.98.180.83
122.175.130.107
122.192.35.240
122.226.34.150
123.125.71.18
123.125.71.76
123.125.71.81
123.127.160.102
123.138.37.73
123.151.139.210
123.151.148.175
123.151.148.179
123.151.148.184
123.151.148.186
123.163.143.204
123.164.66.216
123.164.66.219
124.160.194.27
124.171.39.75
124.202.191.32
124.217.186.137
124.217.239.87
124.95.160.148
125.211.221.97
125.39.29.120
125.55.238.145
125.65.108.74
129.97.125.155
130.185.156.189
140.237.77.143
142.196.207.249
142.4.208.185
142.54.182.186
147.255.162.81
150.214.190.39
150.70.172.102
151.248.123.211
157.56.93.82
157.7.169.57
161.184.228.198
163.43.132.41
166.137.156.28
166.137.156.38
166.216.130.95
168.144.196.233
171.25.190.77
173.166.75.217
173.192.235.226
173.199.114.171
173.199.114.51
173.199.114.75
173.199.115.171
173.199.115.3
173.199.115.75
173.199.115.91
173.199.116.179
173.199.116.219
173.199.116.59
173.199.116.91
173.208.150.250
173.208.165.178
173.208.173.251
173.208.180.58
173.214.189.107
173.230.144.201
173.236.157.204
173.236.199.253
173.236.50.206
173.242.125.191
173.242.125.206
173.245.6.132
173.252.39.135
173.44.39.10
173.65.228.137
174.121.241.14
174.121.92.190
174.122.142.191
174.123.98.98
174.127.117.77
174.37.117.82
174.61.82.148
174.62.106.80
174.7.163.172
175.42.81.229
176.123.0.105
176.123.0.112
176.123.0.231
176.123.0.233
176.123.0.99
176.223.199.2
176.9.78.117
176.9.89.12
178.137.160.45
178.137.165.66
178.139.142.241
178.151.143.69
178.192.158.236
178.208.91.196
178.210.32.14
178.255.225.89
178.43.149.44
178.43.232.243
178.43.245.201
178.63.253.197
178.77.97.114
180.169.76.237
180.188.194.54
180.235.134.107
180.68.206.92
180.76.5.13
180.76.5.160
180.76.5.49
182.118.20.168
182.118.20.203
182.118.20.231
182.118.21.227
182.118.21.242
182.118.21.248
182.118.22.221
182.50.141.162
183.47.234.181
184.105.235.28
184.107.150.58
184.107.237.66
184.154.115.10
184.154.36.210
184.168.109.23
184.168.112.26
184.168.114.10
185.15.196.72
185.3.132.52
186.235.238.242
188.143.232.144
188.143.232.173
188.143.232.211
188.143.232.224
188.143.232.30
188.143.233.30
188.143.235.63
188.165.202.45
188.190.98.26
188.40.166.133
188.40.69.202
188.92.75.82
189.107.38.183
189.234.1.12
189.79.142.43
189.83.76.94
190.6.176.20
190.82.84.203
190.98.219.99
192.119.154.144
192.157.202.170
192.74.243.125
192.95.30.136
193.169.80.51
193.180.115.113
193.33.186.241
194.231.138.35
194.247.30.126
194.28.172.172
195.189.82.66
195.205.87.132
195.225.171.122
195.23.48.154
195.230.119.151
195.240.85.229
198.1.103.205
198.1.127.222
198.1.66.225
198.143.130.125
198.144.116.100
198.144.116.144
198.144.116.174
198.144.116.177
198.144.116.204
198.144.116.215
198.144.116.39
198.144.116.77
198.144.116.91
198.144.157.117
198.154.104.44
198.154.229.38
198.178.121.122
198.178.121.123
198.178.121.124
198.178.121.125
198.244.100.149
198.27.64.56
198.57.163.161
198.98.113.47
199.102.76.250
199.116.250.88
199.180.132.2
199.180.135.244
199.180.252.22
199.195.143.121
199.223.214.154
199.58.86.211
2.49.246.205
2.80.249.137
200.37.170.9
200.38.75.72
201.58.47.184
201.69.22.21
202.103.36.43
202.117.54.242
202.121.166.203
202.199.224.25
202.214.8.82
202.232.236.66
202.70.136.23
202.97.194.171
203.170.192.62
203.98.75.98
204.12.198.106
204.12.208.218
204.12.214.170
204.93.60.111
204.93.60.12
204.93.60.128
204.93.60.164
204.93.60.182
204.93.60.200
204.93.60.207
204.93.60.208
204.93.60.30
204.93.60.57
204.93.60.75
204.93.60.84
204.93.60.92
205.186.183.101
207.223.240.182
207.58.129.221
207.58.139.238
207.58.185.126
208.113.168.4
208.113.170.83
208.113.184.10
208.113.184.22
208.113.186.170
208.113.197.94
208.113.198.153
208.113.198.170
208.115.125.60
208.116.36.230
208.116.44.112
209.222.102.195
209.51.142.178
209.73.151.152
209.73.151.229
209.73.151.74
209.73.151.97
209.85.238.24
210.123.1.169
210.14.78.21
210.188.201.162
210.188.201.41
210.210.178.20
210.44.159.49
211.169.127.86
212.156.66.62
212.55.8.177
213.182.92.242
216.15.166.34
216.15.166.5
216.172.147.109
216.172.147.122
216.172.147.19
216.172.147.205
216.172.147.239
216.172.147.251
216.172.147.57
216.172.147.97
216.224.169.123
216.224.175.71
216.244.78.71
217.167.129.14
218.102.223.188
218.102.68.153
218.102.73.50
218.102.75.207
218.103.141.84
218.108.0.91
218.108.85.245
218.213.138.17
218.246.71.229
218.25.251.19
218.26.89.179
218.27.252.7
218.6.130.215
218.66.123.62
218.7.204.208
218.94.106.246
219.148.104.202
219.77.99.128
220.160.26.214
220.181.108.114
220.181.108.147
220.181.108.170
220.181.108.178
220.181.108.185
220.181.108.186
220.181.108.88
220.181.94.220
221.10.112.134
221.143.48.248
221.175.225.245
221.224.33.70
221.234.42.9
221.241.239.75
222.114.39.171
222.128.152.109
222.171.156.100
222.186.59.219
222.255.237.26
222.59.10.6
222.68.193.150
222.80.184.46
223.3.58.122
223.4.9.111
223.98.149.130
24.116.44.205
24.177.51.251
24.207.109.125
24.230.50.166
24.234.3.189
24.27.17.15
24.92.78.94
27.153.211.61
27.199.121.99
31.210.36.18
31.210.86.205
31.22.104.28
31.6.71.84
31.6.80.252
36.248.161.19
36.249.76.57
37.1.223.19
37.122.210.0
37.140.234.126
37.247.99.82
37.59.152.160
37.59.91.151
37.72.190.177
37.9.53.50
37.9.53.91
38.101.148.120
41.43.193.90
46.118.121.165
46.118.126.198
46.118.158.87
46.119.122.31
46.162.87.101
46.165.198.100
46.182.80.58
46.246.31.101
46.252.193.47
46.32.226.96
46.45.181.35
49.205.36.114
5.135.158.104
5.135.4.20
5.149.248.84
5.9.23.167
50.117.80.153
50.117.80.168
50.117.80.207
50.135.194.63
50.17.94.111
50.19.1.73
50.22.184.2
50.22.199.170
50.22.236.98
50.23.55.135
50.31.98.92
50.62.145.225
50.63.154.219
50.63.67.12
50.93.205.47
58.215.82.148
58.225.75.228
59.161.254.21
59.58.151.219
59.60.115.61
59.90.242.87
60.13.74.23
60.168.159.98
60.169.22.118
60.190.243.250
60.191.19.2
60.191.30.92
60.215.230.175
60.217.229.252
61.130.254.91
61.158.164.59
61.19.248.138
61.236.64.56
61.238.156.106
61.240.36.1
61.255.198.241
61.54.105.38
61.98.134.14
62.143.204.231
62.212.73.211
62.219.8.230
63.147.126.183
63.147.126.185
64.111.124.4
64.202.240.136
64.207.146.169
64.22.33.10
64.34.169.168
65.254.168.168
65.254.40.154
65.44.220.57
65.55.213.193
65.55.213.244
65.55.24.243
65.60.19.242
65.60.29.133
66.135.37.211
66.147.226.141
66.154.54.43
66.155.8.206
66.172.57.16
66.249.73.161
66.249.73.194
66.249.73.81
66.249.74.92
66.249.74.95
66.249.74.96
66.249.74.99
66.249.75.165
66.249.76.165
66.36.228.123
66.55.144.244
66.55.79.29
66.7.203.158
67.205.1.74
67.205.24.238
67.205.39.2
67.205.45.170
67.205.45.80
67.205.46.10
67.205.50.6
67.205.67.147
67.215.243.250
67.222.150.43
67.87.118.63
68.203.4.152
69.163.164.44
69.163.183.221
69.163.202.16
69.163.221.149
69.174.241.113
69.174.254.88
69.195.198.111
69.30.238.162
70.193.195.125
70.211.73.81
70.32.112.125
70.36.134.230
71.231.148.235
72.14.185.153
72.167.13.19
72.18.198.4
72.232.113.70
72.233.119.245
72.29.68.51
72.32.68.101
74.111.23.38
74.117.61.88
74.125.16.210
74.125.16.211
74.125.16.215
74.125.178.83
74.125.179.86
74.192.8.47
74.200.224.226
74.207.224.242
74.208.66.177
76.250.48.46
77.235.47.247
77.242.21.106
77.29.174.66
77.56.58.253
77.66.3.219
77.88.234.171
77.93.192.212
78.111.80.205
78.142.63.82
78.46.34.77
79.138.81.23
79.176.202.159
79.180.167.234
79.191.207.105
8.29.131.248
80.13.235.11
80.57.78.214
80.68.95.137
80.78.247.92
80.86.105.174
80.95.160.178
81.144.138.34
81.50.221.85
82.194.82.102
82.232.76.153
82.80.249.137
82.80.249.139
83.149.126.98
83.168.215.63
83.243.57.33
83.27.143.137
83.27.36.55
83.28.53.137
83.8.62.213
84.10.217.140
84.19.171.221
84.235.61.72
84.40.37.34
85.10.195.141
85.105.225.142
85.108.28.177
85.119.183.223
85.158.215.36
85.168.156.219
85.190.5.212
85.214.153.62
85.214.27.40
85.214.45.181
85.25.73.37
85.95.238.76
86.56.232.218
87.253.162.6
88.119.151.2
88.227.86.178
88.234.131.18
89.165.3.186
89.216.25.130
89.233.216.208
89.38.207.234
89.44.200.154
89.67.195.78
89.75.186.223
91.102.16.156
91.121.152.5
91.183.46.128
91.184.49.98
91.203.108.132
91.207.60.50
91.224.160.143
91.232.96.23
91.232.96.24
91.236.74.152
91.65.240.55
92.114.86.81
93.114.41.220
93.114.43.144
93.114.46.11
93.170.50.174
93.187.140.18
94.102.3.151
94.138.206.66
94.199.51.7
94.23.23.127
94.23.234.227
94.23.27.29
94.23.42.135
94.249.26.195
94.250.44.130
95.154.234.101
95.173.186.104
95.80.97.110
96.127.139.170
96.127.139.186
96.127.149.213
96.44.132.138
98.130.2.3
98.155.242.255
99.73.226.124
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment