ipfreemmap.py 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. # binary tree search of data file for countrycode
  2. #
  3. # by Greg Hazel
  4. import os
  5. import mmap
  6. import struct
  7. import socket
  8. import bisect
  9. root, file = os.path.split(__file__)
  10. addrmap = os.path.join(root, "addrmap.dat")
  11. if not os.path.exists(addrmap):
  12. from BTL.platform import get_module_filename
  13. root, file = os.path.split(get_module_filename())
  14. addrmap = os.path.join(root, "addrmap.dat")
  15. if not os.path.exists(addrmap):
  16. addrmap = os.path.abspath("addrmap.dat")
  17. ### generates the addrmap file
  18. ##import ipfree
  19. ##f = open(addrmap, 'wb')
  20. ##for e in ipfree.addrmap:
  21. ## # stupid 0 padded nonsense.
  22. ## d = '.'.join([ str(int(i)) for i in e[0].split('.') ])
  23. ## ip = socket.inet_aton(d)
  24. ## f.write(ip + e[1])
  25. ##f.close()
  26. def int_to_ip(i):
  27. s = struct.pack("!L", i)
  28. return socket.inet_ntoa(s)
  29. def ip_to_int(ip):
  30. s = socket.inet_aton(ip)
  31. return struct.unpack("!L", s)[0]
  32. class ListMMap(object):
  33. def __init__(self):
  34. self.f = open(addrmap, 'rb')
  35. self.size = os.path.getsize(addrmap)
  36. self.m = mmap.mmap(self.f.fileno(), self.size, access=mmap.ACCESS_READ)
  37. def __getitem__(self, i):
  38. p = i * 6
  39. if p + 6 > self.size:
  40. raise IndexError("memory map index out of range")
  41. s = self.m[p:p+6]
  42. d = struct.unpack("!L", s[:4])[0]
  43. return (d, s[4:])
  44. def __len__(self):
  45. return self.size / 6
  46. def find(self, ip):
  47. d = ip_to_int(ip)
  48. i = max(bisect.bisect_right(self, (d, )) - 1, 0)
  49. return self[i][1]
  50. l = ListMMap()
  51. lookup = l.find
  52. if __name__ == "__main__":
  53. assert l.find("129.97.128.15") == "CA"
  54. assert l.find("217.198.112.1") == "EU"
  55. assert l.find("221.97.211.1") == "US"
  56. assert l.find("0.0.0.0") == "US"
  57. assert l.find("0.0.0.1") == "US"
  58. assert l.find("0.255.255.255") == "US"
  59. assert l.find("1.0.0.1") == "IN"
  60. assert l.find("1.0.0.255") == "IN"