geoip-lite
Advanced tools
Comparing version 1.0.4 to 1.0.5
136
lib/geoip.js
@@ -5,69 +5,94 @@ var fs = require('fs'), | ||
// First we have to define readUInt32 correctly based on the node version in use | ||
// Our fault for using unstable APIs | ||
var readUInt32; | ||
if(process.version.match(/^v0\.4\./)) { | ||
readUInt32 = function(b, offset, bigEndian) { | ||
if(bigEndian) { | ||
return ((b[offset]<<24)+ | ||
(b[offset+1]<<16)+ | ||
(b[offset+2]<<8)+ | ||
(b[offset+3]))>>>0; | ||
} | ||
else { | ||
return ((b[offset+3]<<24)+ | ||
(b[offset+2]<<16)+ | ||
(b[offset+1]<<8)+ | ||
(b[offset]))>>>0; | ||
} | ||
}; | ||
(function() { | ||
var ifile, ifd, sz, recsz, buff, lrecsz, lbuff; | ||
try { | ||
file = path.join(__dirname, '/../data/geoip-city-names.dat'); | ||
fd = fs.openSync(file, "r"); | ||
sz = fs.fstatSync(fd).size; | ||
lrecsz = 32; | ||
lbuff = new Buffer(sz); | ||
fs.readSync(fd, lbuff, 0, sz, 0); | ||
fs.closeSync(fd); | ||
file = path.join(__dirname, '/../data/geoip-city.dat'); | ||
fd = fs.openSync(file, "r"); | ||
sz = fs.fstatSync(fd).size; | ||
recsz = 12; | ||
} | ||
else if(process.version == 'v0.5.3') { | ||
readUInt32 = function(b, offset, bigEndian) { | ||
return b.readUInt32(offset, bigEndian?"big":"little"); | ||
}; | ||
catch(err) { | ||
if(err.code != 'ENOENT') { | ||
throw err; | ||
} | ||
console.warn("\n======================== Warning ========================"); | ||
console.warn(" City data not found, falling back to country data."); | ||
console.warn(" Get the latest city data files from\n"); | ||
console.warn(" https://github.com/bluesmoon/node-geoip/tree/master/data\n"); | ||
console.warn(" You need geoip-city-names.dat and geoip-city.dat"); | ||
console.warn(" Put them into the data/ directory for this package"); | ||
console.warn("======================== Warning ========================\n\n"); | ||
file = path.join(__dirname, '/../data/geoip-country.dat'); | ||
fd = fs.openSync(file, "r"); | ||
sz = fs.fstatSync(fd).size; | ||
recsz = 10; | ||
} | ||
else if(process.version == 'v0.5.4') { | ||
readUInt32 = function(b, offset, bigEndian) { | ||
return b.readUInt32(offset, bigEndian); | ||
}; | ||
} | ||
else if((new Buffer(0).readUInt32BE)) { | ||
readUInt32 = function(b, offset, bigEndian) { | ||
if(bigEndian) | ||
return b.readUInt32BE(offset); | ||
else | ||
return b.readUInt32LE(offset); | ||
}; | ||
} | ||
(function() { | ||
buff = new Buffer(sz); | ||
fs.readSync(fd, buff, 0, sz, 0); | ||
fs.closeSync(fd); | ||
var ifile = path.join(__dirname, '/../data/geoip-country.dat'); | ||
var ifd = fs.openSync(ifile, "r"); | ||
var sz = fs.fstatSync(ifd).size; | ||
var lastline = sz/recsz-1; | ||
var lastip = buff.readUInt32BE(lastline*recsz+4); | ||
var firstip = buff.readUInt32BE(0); | ||
var buff = new Buffer(sz); | ||
fs.readSync(ifd, buff, 0, sz, 0); | ||
fs.closeSync(ifd); | ||
var private_ranges = [ | ||
[aton4("10.0.0.0"), aton4("10.255.255.255")], | ||
[aton4("172.16.0.0"), aton4("172.31.255.255")], | ||
[aton4("192.168.0.0"), aton4("192.168.255.255")] | ||
]; | ||
var lastline = sz/10-1; | ||
var lastip = readUInt32(buff, lastline*10+4, true); | ||
var firstip = readUInt32(buff, 0, true); | ||
lookup4 = function(ip) { | ||
var fline=0, floor=lastip, cline=lastline, ceil=firstip, line; | ||
var fline=0, floor=lastip, cline=lastline, ceil=firstip, line, locId, cc, rg, city, lat, lon, i; | ||
// outside IPv4 range | ||
if(ip > lastip || ip < firstip) { | ||
return null; | ||
} | ||
// private IP | ||
for(i=0; i<private_ranges.length; i++) { | ||
if(ip >= private_ranges[i][0] && ip <= private_ranges[i][1]) { | ||
return null; | ||
} | ||
} | ||
do { | ||
line = Math.round((cline-fline)/2)+fline; | ||
floor = readUInt32(buff, line*10, true); | ||
ceil = readUInt32(buff, line*10+4, true); | ||
floor = buff.readUInt32BE(line*recsz); | ||
ceil = buff.readUInt32BE(line*recsz+4); | ||
if(floor <= ip && ceil >= ip) { | ||
var cc = buff.toString('utf8', line*10+8, line*10+10); | ||
return { range: [floor, ceil], country: cc }; | ||
if(recsz == 10) { | ||
cc = buff.toString('utf8', line*recsz+8, line*recsz+10); | ||
rg = city = ""; | ||
lat = lon = 0; | ||
} | ||
else { | ||
locId = buff.readUInt32BE(line*recsz+8)-1; | ||
cc = lbuff.toString('utf8', locId*lrecsz+0, locId*lrecsz+2).replace(/\u0000.*/, ''); | ||
rg = lbuff.toString('utf8', locId*lrecsz+2, locId*lrecsz+4).replace(/\u0000.*/, ''); | ||
lat = lbuff.readInt32BE(locId*lrecsz+4)/10000; | ||
lon = lbuff.readInt32BE(locId*lrecsz+8)/10000; | ||
city = lbuff.toString('utf8', locId*lrecsz+12, locId*lrecsz+lrecsz).replace(/\u0000.*/, ''); | ||
} | ||
return { | ||
range: [floor, ceil], | ||
country: cc, | ||
region: rg, | ||
city: city, | ||
ll: [ lat, lon ] | ||
}; | ||
} | ||
@@ -109,2 +134,3 @@ else if(fline == cline) { | ||
var sz = fs.fstatSync(ifd).size; | ||
var recsz = 34; | ||
@@ -115,3 +141,3 @@ var buff = new Buffer(sz); | ||
var lastline = sz/34-1; | ||
var lastline = sz/recsz-1; | ||
// XXX We only use the first 8 bytes of an IPv6 address | ||
@@ -125,3 +151,3 @@ // This identifies the network, but not the host within | ||
for(ii=0; ii<2; ii++) | ||
ip.push(readUInt32(buff, line*34+offset*16+ii*4, true)); | ||
ip.push(buff.readUInt32BE(line*recsz+offset*16+ii*4)); | ||
return ip; | ||
@@ -145,4 +171,4 @@ } | ||
if(cmp6(floor, ip) <= 0 && cmp6(ceil, ip) >= 0) { | ||
var cc = buff.toString('utf8', line*34+32, line*34+34); | ||
return { range: [floor, ceil], country: cc }; | ||
var cc = buff.toString('utf8', line*recsz+32, line*recsz+34); | ||
return { range: [floor, ceil], country: cc, region: "", city: "", ll: [0, 0] }; // We do not currently have region/city info for IPv6 | ||
} | ||
@@ -149,0 +175,0 @@ else if(fline == cline) { |
{ | ||
"name" : "geoip-lite", | ||
"version" : "1.0.4", | ||
"version" : "1.0.5", | ||
"description" : "A light weight native JavaScript implementation of GeoIP API from MaxMind", | ||
@@ -8,7 +8,7 @@ "keywords" : ["geo", "geoip", "ip", "ipv4", "ipv6", "geolookup", "maxmind", "geolite"], | ||
"author" : "Philip Tellis <philip@bluesmoon.info> (http://bluesmoon.info/)", | ||
"files" : ["lib/", "data/", "test/" ], | ||
"files" : ["lib/", "data/geoip-country.dat", "data/geoip-country6.dat", "test/" ], | ||
"main" : "lib/geoip.js", | ||
"repository" : { "type": "git", "url": "git://github.com/bluesmoon/node-geoip.git" }, | ||
"engines" : { "node": "~0.4.11 || >=0.5.3" } | ||
"engines" : { "node": ">=0.5.7" } | ||
} | ||
var assert = require('assert'); | ||
var t1=+new Date; | ||
var geoip = require('../lib/geoip'); | ||
var t2=+new Date; | ||
if(process.argv.length > 2) { | ||
console.dir(geoip.lookup(process.argv[2])); | ||
var t3 = +new Date; | ||
console.log("Startup: %dms, exec: %dms", t2-t1, t3-t2); | ||
process.exit(); | ||
@@ -43,3 +47,4 @@ } | ||
console.log("Found %d (%d/%d) ips in %dms (%s ip/s) (%sμs/ip)", n, f.length, nf.length, te-ts, (n*1000/(te-ts)).toFixed(3), ((te-ts)*1000/n).toFixed(0)); | ||
console.log("Took %d ms to startup", t2-t1); | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
55574859
9
409
3
6