Guest User

Untitled

a guest
Feb 18th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.31 KB | None | 0 0
  1. #!/usr/local/kinix/luajit/bin/luajit
  2.  
  3. --[[
  4. 06 FEB 2018: karthik@houseofkodai
  5. ]]--
  6.  
  7. local load_geolite2_city_locations_csv = function(fname, cc)
  8. --geoname_id,locale_code,continent_code,continent_name,country_iso_code,country_name,subdivision_1_iso_code,subdivision_1_name,subdivision_2_iso_code,subdivision_2_name,city_name,metro_code,time_zone
  9. --1252653,en,AS,Asia,IN,India,NL,Nagaland,,,Zunheboto,,Asia/Kolkata
  10. --need 1,7,8,11
  11.  
  12. local stime = os.time()
  13. --print('START '..stime)
  14. local t = {}
  15. local n = 0
  16. for ln in io.lines(fname) do
  17. ln = ln..',' --append , so gmatch regex works
  18. local regex = '([^,]*),'
  19. local i = 0
  20. local id, scode, sname, city
  21. for w in ln:gmatch(regex) do
  22. i = i + 1
  23. if (1 == i) then
  24. id = w
  25. elseif ((5 == i) and (w ~= cc)) then
  26. break
  27. elseif (7 == i) then
  28. scode = w
  29. elseif (8 == i) then
  30. sname = w
  31. elseif (11 == i) then
  32. city = w
  33. end
  34. end
  35. if city then
  36. n = n + 1
  37. regex = '"?([^"]*)"?'
  38. t[id] = {scode, sname:match(regex), city:match(regex)}
  39. end
  40. end
  41. --print('END', (os.time()-stime), n)
  42. return t
  43. end
  44.  
  45. local load_geolite2_city_blocks_ipv4_csv = function(fname, idtbl)
  46. --network,geoname_id,registered_country_geoname_id,represented_country_geoname_id,is_anonymous_proxy,is_satellite_provider,postal_code,latitude,longitude,accuracy_radius
  47. local stime = os.time()
  48. --print('START '..stime)
  49. local n = 0
  50. local t = {}
  51.  
  52. for ln in io.lines(fname) do
  53. n = n + 1
  54. local id = ln:match('^[%d.]+/%d+,(%d+),.*$')
  55. local r = idtbl[id]
  56. if r and (r[1]:len() > 0)then
  57. local o1,o2,o3,o4,range,id,f1,f2,f3,f4,f5,lat,lng,acc = ln:match('^(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)/(%d+),(%d+),([^,]*),([^,]*),([^,]*),([^,]*),([^,]*),(%d+%.%d+),(%d+%.%d+),(%d+)$')
  58. local ipstart = 2^24*o1 + 2^16*o2 + 2^8*o3 + o4
  59. local ipend = ipstart + 2^(32-tonumber(range))
  60. --t[#t+1] = {tonumber(ipstart),tonumber(ipend),'"'..r[1]..'/'..r[3]..'"',lat,lng,acc}
  61. t[#t+1] = {tonumber(ipstart),tonumber(ipend),id,lat,lng,acc}
  62. end
  63. end
  64. --print('END', (os.time()-stime), n, #t)
  65. return t
  66. end
  67.  
  68. local _load = function(locfname, ipv4fname, cc)
  69. --pndng deal with null-cc to load everything
  70. local citytbl = load_geolite2_city_locations_csv(locfname, cc)
  71. local iptbl = load_geolite2_city_blocks_ipv4_csv(ipv4fname, citytbl)
  72. return citytbl, iptbl
  73. end
  74.  
  75. local _find = function(s, citytbl, iptbl)
  76. local o1,o2,o3,o4 = s:match('^(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)$')
  77. if not o4 then return {} end
  78. local ip = 2^24*o1 + 2^16*o2 + 2^8*o3 + o4
  79. local iptbl = iptbl or {}
  80. local citytbl = citytbl or {}
  81. for _,r in ipairs(iptbl) do
  82. if ip >= r[1] and ip < r[2] then
  83. local v = citytbl[r[3]]
  84. if v then r[3] = v[1]..':'..v[3] end
  85. return r
  86. end
  87. end
  88. return {}
  89. end
  90.  
  91. local _save = function(fname, citytbl, iptbl)
  92. local fh,err = io.open(fname, 'w')
  93. if not fh then
  94. return false,err
  95. end
  96. local t = {}
  97. for _,r in ipairs(iptbl) do
  98. if (r[3]:len() > 0) then
  99. t[#t+1] = '{'..table.concat(r, ',')..'}'
  100. end
  101. end
  102. local iptbl = table.concat(t, ',\n')
  103.  
  104. t = {}
  105. for k,v in pairs(citytbl) do
  106. t[#t+1] = '['..k..']="'..v[1]..':'..v[3]..'"'
  107. end
  108. local citytbl = table.concat(t, ',\n')
  109.  
  110. local flines = [=[
  111. return function(s)
  112. local o1,o2,o3,o4 = s:match('^(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)$')
  113. if not o4 then return end
  114. local ip = 2^24*o1 + 2^16*o2 + 2^8*o3 + o4
  115. local citytbl = {
  116. ]=]..citytbl..[=[
  117. }
  118. local iptbl = {
  119. ]=]..iptbl..[=[
  120. }
  121. for _,r in ipairs(iptbl) do
  122. if ip >= r[1] and ip < r[2] then
  123. r[3] = citytbl[r[3]] or 'UNK'
  124. return r
  125. end
  126. end
  127. end
  128. ]=]
  129. fh:write(flines)
  130. fh:close()
  131. return true
  132. end
  133.  
  134. local main = function()
  135. local locfname = 'GeoLite2-City-Locations-en.csv'
  136. local ipv4fname = 'GeoLite2-City-Blocks-IPv4.csv'
  137.  
  138. if (#arg < 1) then
  139. print('usage: geolite2.lua <country-code> <ip-to-lookup> ['..locfname..'] ['..ipv4fname..']')
  140. os.exit(1)
  141. end
  142.  
  143. local cc = arg[1]
  144. local ip = arg[2]
  145. if arg[3] then locfname = arg[3] end
  146. if arg[4] then ipv4fname = arg[4] end
  147.  
  148. local citytbl, iptbl = _load(locfname, ipv4fname, cc)
  149. _save(cc..'.lua', citytbl, iptbl)
  150.  
  151. if ip then
  152. local r = _find(ip, citytbl, iptbl)
  153. if r then print(table.concat(r,'/')) end
  154. end
  155. end
  156.  
  157. if arg ~= nil then
  158. main()
  159. end
Add Comment
Please, Sign In to add comment