Advertisement
Guest User

GeoIP Pb APi

a guest
Apr 7th, 2017
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;EnableExplicit
  2.  
  3. ;By Celtic88 2016(c) v: 1.1 new update 2017 add support for ipv6
  4. Macro GEOIP_CHKBIT_V6(bit,ptr)
  5.   (ptr\u_char[((127 - bit) >> 3)] & (1 << (~(127 - bit) & 7)))
  6. EndMacro
  7.  
  8. Structure in6_addr
  9.   StructureUnion
  10.     u_char.b[16];
  11.     u_short.w[8];
  12.   EndStructureUnion
  13. EndStructure
  14.  
  15. #GeoIPMaxContry = 255
  16.  
  17. Global Dim GeoIP_CountryNames.s(#GeoIPMaxContry)
  18. Global Dim GeoIP_CountryCodes.s(#GeoIPMaxContry)
  19. Global Dim GeoIP_CountryContinent.s(#GeoIPMaxContry)
  20. Global Dim GeoIP_CountryCodes3.s(#GeoIPMaxContry)
  21. Global Dim GeoIP_Countrytimezone.s(2,715)
  22.  
  23. IncludeFile "GeoIPData.PBI"
  24.  
  25. Procedure.b GeoIP_ini()
  26.   Protected Ii.a,uo.l
  27.   Restore GeoIP_DCountryNames
  28.   For Ii = 0 To #GeoIPMaxContry
  29.     Read.s GeoIP_CountryNames(Ii)
  30.   Next
  31.   Restore GeoIP_DCountryCodes
  32.   For Ii = 0 To #GeoIPMaxContry
  33.     Read.s GeoIP_CountryCodes(Ii)
  34.   Next
  35.   Restore GeoIP_DCountryContinent
  36.   For Ii = 0 To #GeoIPMaxContry
  37.     Read.s GeoIP_CountryContinent(Ii)
  38.   Next
  39.   Restore GeoIP_DCountryCodes3
  40.   For Ii = 0 To #GeoIPMaxContry
  41.     Read.s GeoIP_CountryCodes3(Ii)
  42.   Next  
  43.   Restore GeoIP_Dtimezone
  44.   For uo = 0 To 715
  45.     For Ii = 0 To 2
  46.       Read.s GeoIP_Countrytimezone(Ii,uo)
  47.     Next
  48.   Next
  49. EndProcedure
  50.  
  51. GeoIP_ini()
  52.  
  53. #STRUCTURE_INFO_MAX_SIZE = 20
  54. #FULL_RECORD_LENGTH = 50
  55. #COUNTRY_BEGIN = 16776960
  56.  
  57. #GEOIP_COUNTRY_EDITION = 1
  58. #GEOIP_COUNTRY_EDITION_V6 = 12
  59. #GEOIP_CITY_EDITION_REV1 = 2
  60. #GEOIP_CITY_EDITION_REV1_V6 = 30
  61. #GEOIP_ASNUM_EDITION = 9
  62. #GEOIP_ASNUM_EDITION_V6 = 21
  63.  
  64. Structure GeoIP_Info
  65.   GeoIP_databaseType.a
  66.   GeoIP_Path.s
  67.   GeoIP_fCach_Memory.b
  68.   *GeoIP_datBuffer
  69.   GeoIP_File_ID.i
  70.   GeoIP_Size.l
  71.   GeoIP_databaseSegments.l
  72. EndStructure
  73.  
  74. Structure GeoIPRecord
  75.   Index_Data.l
  76.   country_code.s
  77.   country_code3.s
  78.   country_name.s
  79.   region.s
  80.   city.s
  81.   postal_code.s
  82.   latitude.f
  83.   longitude.f
  84.   metro_code.l
  85.   area_code.l
  86.   continent_code.s
  87.   Geo_Asn.s
  88.   time_zone.s
  89.   GeoIP_databaseType.a
  90. EndStructure
  91.  
  92. Procedure.b GeoIP_Free(*iGeoIP_Info.GeoIP_Info)
  93.   If *iGeoIP_Info < 1
  94.     ProcedureReturn 0
  95.   EndIf
  96.   With *iGeoIP_Info
  97.     If \GeoIP_File_ID
  98.       CloseFile(\GeoIP_File_ID)
  99.     EndIf
  100.   EndWith
  101.   ClearStructure(*iGeoIP_Info, GeoIP_Info)
  102.   FreeMemory(*iGeoIP_Info)
  103. EndProcedure
  104.  
  105. Procedure.i GeoIP_OPen(GeoIP_Path.s,GeoIP_fCach_Memory.b=0,*GeoIP_datBuffer=0,GeoIP_datBufferSize.l=0)
  106.  
  107.   Protected GetSize.l = GeoIP_datBufferSize
  108.   Protected Dim buf.a(2)
  109.   Protected Ii.l,j.l,nRdb.l
  110.   Protected GoPenf.i
  111.  
  112.   If GeoIP_fCach_Memory
  113.     If Not *GeoIP_datBuffer Or Not GeoIP_datBufferSize
  114.       ProcedureReturn -1
  115.     EndIf
  116.   Else
  117.     GetSize = FileSize(GeoIP_Path)
  118.     If GetSize > 0
  119.       GoPenf = OpenFile(#PB_Any,GeoIP_Path)
  120.     Else
  121.       ProcedureReturn -1
  122.     EndIf
  123.     If GoPenf =0
  124.       ProcedureReturn -1
  125.     EndIf
  126.   EndIf
  127.  
  128.   Protected *iGeoIP_Info.GeoIP_Info = AllocateMemory(SizeOf(GeoIP_Info))
  129.   If *iGeoIP_Info =0
  130.     CloseFile(GoPenf)
  131.     ProcedureReturn -2
  132.   EndIf
  133.  
  134.   With *iGeoIP_Info
  135.     \GeoIP_databaseType = #GEOIP_COUNTRY_EDITION
  136.     \GeoIP_databaseSegments = #COUNTRY_BEGIN    
  137.     \GeoIP_datBuffer = *GeoIP_datBuffer
  138.     \GeoIP_fCach_Memory = GeoIP_fCach_Memory
  139.     \GeoIP_File_ID = GoPenf
  140.     \GeoIP_Size = GeoIP_datBufferSize
  141.    
  142.     GetSize-3
  143.    
  144.     If Not \GeoIP_fCach_Memory
  145.       FileSeek(\GeoIP_File_ID, GetSize)
  146.     EndIf
  147.    
  148.     For Ii=0 To #STRUCTURE_INFO_MAX_SIZE - 1
  149.      
  150.       If \GeoIP_fCach_Memory
  151.         nRdb = CopyMemory(\GeoIP_datBuffer + GetSize, @BUF(), 3)
  152.       Else
  153.         nRdb = ReadData(\GeoIP_File_ID,@BUF(), 3)
  154.       EndIf
  155.      
  156.       If nRdb < 3
  157.         GeoIP_Free(*iGeoIP_Info)
  158.         ProcedureReturn -3
  159.       EndIf
  160.      
  161.       If BUF(0) = 255 And BUF(1) = 255 And BUF(2) = 255
  162.        
  163.         GetSize + 3
  164.        
  165.         If \GeoIP_fCach_Memory
  166.          
  167.           \GeoIP_databaseType = PeekA(\GeoIP_datBuffer + GetSize)
  168.           nRdb = CopyMemory(\GeoIP_datBuffer + GetSize + 1, @BUF(), 3)
  169.          
  170.         Else
  171.          
  172.           FileSeek(\GeoIP_File_ID, GetSize)
  173.           \GeoIP_databaseType = ReadAsciiCharacter(\GeoIP_File_ID)
  174.           FileSeek(\GeoIP_File_ID, GetSize + 1)
  175.           nRdb = ReadData(\GeoIP_File_ID,@BUF(), 3)
  176.          
  177.         EndIf
  178.        
  179.         If nRdb < 3
  180.           GeoIP_Free(*iGeoIP_Info)
  181.           ProcedureReturn -3
  182.         EndIf
  183.        
  184.         If \GeoIP_databaseType = #GEOIP_COUNTRY_EDITION_V6
  185.           Break
  186.         EndIf
  187.        
  188.         If \GeoIP_databaseType = #GEOIP_ASNUM_EDITION_V6 Or
  189.            \GeoIP_databaseType = #GEOIP_CITY_EDITION_REV1 Or
  190.            \GeoIP_databaseType = #GEOIP_ASNUM_EDITION Or
  191.            \GeoIP_databaseType = #GEOIP_CITY_EDITION_REV1_V6
  192.          
  193.           \GeoIP_databaseSegments = 0
  194.           For j = 0 To 2
  195.             \GeoIP_databaseSegments + (BUF(j) << (j * 8))
  196.           Next
  197.          
  198.         Else
  199.          
  200.           GeoIP_Free(*iGeoIP_Info)
  201.           ProcedureReturn -4
  202.          
  203.         EndIf
  204.        
  205.       EndIf
  206.      
  207.       GetSize - 4
  208.      
  209.       If Not \GeoIP_fCach_Memory
  210.         FileSeek(\GeoIP_File_ID, GetSize)
  211.       EndIf
  212.      
  213.     Next
  214.    
  215.     If Not \GeoIP_fCach_Memory
  216.       FileSeek(\GeoIP_File_ID, 0)
  217.     EndIf
  218.    
  219.   EndWith
  220.   ProcedureReturn *iGeoIP_Info
  221. EndProcedure
  222.  
  223. Procedure.l GeoIP_Seek_Record_IPV6(*iGeoIP_Info.GeoIP_Info,*IPAddressnum.in6_addr)
  224.  
  225.   If *iGeoIP_Info < 1
  226.     ProcedureReturn -1
  227.   EndIf
  228.  
  229.   Protected depth.l
  230.   Protected x.l ,nRdb.l
  231.   Protected Dim stack_buffer.a(2 * 3)
  232.   Protected offset.l = 0
  233.   Protected record_pair_length.l = 6
  234.   Protected byte_offset.l
  235.  
  236.   With *iGeoIP_Info
  237.    
  238.     For depth = 127 To 0 Step -1
  239.      
  240.       byte_offset = record_pair_length * offset
  241.      
  242.       If \GeoIP_fCach_Memory
  243.         nRdb = CopyMemory(\GeoIP_datBuffer + byte_offset, @stack_buffer(), record_pair_length)
  244.       Else
  245.         FileSeek(\GeoIP_File_ID,byte_offset)
  246.         nRdb = ReadData(\GeoIP_File_ID,@stack_buffer(), record_pair_length)
  247.       EndIf
  248.      
  249.       If nRdb < record_pair_length
  250.         ProcedureReturn -2
  251.       EndIf
  252.      
  253.       If GEOIP_CHKBIT_V6(depth,*IPAddressnum)
  254.        
  255.         x = (stack_buffer(3 * 1 + 0) << (0 * 8)) +
  256.             (stack_buffer(3 * 1 + 1) << (1 * 8)) +
  257.             (stack_buffer(3 * 1 + 2) << (2 * 8))
  258.        
  259.       Else
  260.        
  261.         x = (stack_buffer(3 * 0 + 0) << (0 * 8)) +
  262.             (stack_buffer(3 * 0 + 1) << (1 * 8)) +
  263.             (stack_buffer(3 * 0 + 2) << (2 * 8))
  264.        
  265.       EndIf
  266.      
  267.       If (x >= \GeoIP_databaseSegments)
  268.         ProcedureReturn x
  269.       EndIf
  270.      
  271.       offset = x
  272.     Next
  273.    
  274.   EndWith
  275. EndProcedure
  276.  
  277. Procedure.l GeoIP_Seek_Record(*iGeoIP_Info.GeoIP_Info,ipnum.q)
  278.   If *iGeoIP_Info < 1
  279.     ProcedureReturn -1
  280.   EndIf
  281.  
  282.   Protected depth.l
  283.   Protected x.l ,nRdb.l
  284.   Protected Dim stack_buffer.a(2 * 3)
  285.   Protected offset.l = 0
  286.   Protected record_pair_length.l = 6
  287.   Protected byte_offset.l
  288.  
  289.   With *iGeoIP_Info
  290.    
  291.     For depth = 31 To 0 Step -1
  292.      
  293.       byte_offset = record_pair_length * offset
  294.      
  295.       If \GeoIP_fCach_Memory
  296.         nRdb = CopyMemory(\GeoIP_datBuffer + byte_offset, @stack_buffer(), record_pair_length)
  297.       Else
  298.         FileSeek(\GeoIP_File_ID,byte_offset)
  299.         nRdb = ReadData(\GeoIP_File_ID,@stack_buffer(), record_pair_length)
  300.       EndIf
  301.      
  302.       If nRdb < record_pair_length
  303.         ProcedureReturn -2
  304.       EndIf
  305.      
  306.       If (ipnum & (1 << depth))
  307.        
  308.         x = (stack_buffer(3 * 1 + 0) << (0 * 8)) +
  309.             (stack_buffer(3 * 1 + 1) << (1 * 8)) +
  310.             (stack_buffer(3 * 1 + 2) << (2 * 8))
  311.        
  312.       Else
  313.        
  314.         x = (stack_buffer(3 * 0 + 0) << (0 * 8)) +
  315.             (stack_buffer(3 * 0 + 1) << (1 * 8)) +
  316.             (stack_buffer(3 * 0 + 2) << (2 * 8))
  317.        
  318.       EndIf
  319.      
  320.       If (x >= \GeoIP_databaseSegments)
  321.         ProcedureReturn x
  322.       EndIf
  323.      
  324.       offset = x
  325.     Next
  326.    
  327.   EndWith
  328.   ProcedureReturn 0
  329. EndProcedure
  330.  
  331. Procedure.s GeoIP_Get_ASMname(*iGeoIP_Info.GeoIP_Info,seek_record.l)
  332.  
  333.   If *iGeoIP_Info < 1
  334.     ProcedureReturn ""
  335.   EndIf
  336.  
  337.   If seek_record < 1
  338.     ProcedureReturn ""
  339.   EndIf
  340.  
  341.   Protected Dim record_buf.a(#FULL_RECORD_LENGTH-1)
  342.   Protected record_pointer.l, nRdb.l
  343.  
  344.   With *iGeoIP_Info
  345.     record_pointer = seek_record + (5) * \GeoIP_databaseSegments
  346.    
  347.     If \GeoIP_fCach_Memory
  348.       nRdb = CopyMemory(\GeoIP_datBuffer + record_pointer, @record_buf(), #FULL_RECORD_LENGTH)
  349.     Else
  350.       FileSeek(\GeoIP_File_ID, record_pointer)
  351.       nRdb = ReadData(\GeoIP_File_ID, @record_buf(), #FULL_RECORD_LENGTH)
  352.     EndIf
  353.    
  354.     If nRdb < #FULL_RECORD_LENGTH
  355.       ProcedureReturn ""
  356.     EndIf
  357.    
  358.   EndWith
  359.  
  360.   ProcedureReturn PeekS(@record_buf(),-1,#PB_UTF8)
  361. EndProcedure
  362.  
  363. Procedure.s GeoIP_Time_Zone_By_Country_and_Region(country.s, region.s)
  364.   Protected uo.l
  365.   For uo = 0 To 715
  366.     If GeoIP_Countrytimezone(0,uo) = country
  367.       If GeoIP_Countrytimezone(1,uo) <> "*" And region <> ""
  368.         For uo = uo To 715
  369.           If GeoIP_Countrytimezone(1,uo) = region
  370.             Break
  371.           EndIf        
  372.         Next
  373.         Break
  374.       Else
  375.         Break
  376.       EndIf
  377.     EndIf
  378.   Next
  379.   If uo < 716
  380.     ProcedureReturn GeoIP_Countrytimezone(2,uo)
  381.   EndIf
  382.   ProcedureReturn ""
  383. EndProcedure
  384.  
  385. Procedure.b GeoIP_Extract_Record(*iGeoIP_Info.GeoIP_Info, *iGeoIPRecord.GeoIPRecord, seek_record.l)
  386.   If *iGeoIP_Info < 1
  387.     ProcedureReturn -1
  388.   EndIf
  389.   ClearStructure(*iGeoIPRecord, GeoIPRecord)
  390.   If Not *iGeoIPRecord
  391.     ProcedureReturn -1
  392.   EndIf
  393.  
  394.   If seek_record < 0
  395.     ProcedureReturn 0
  396.   EndIf
  397.  
  398.   *iGeoIPRecord\GeoIP_databaseType = *iGeoIP_Info\GeoIP_databaseType
  399.  
  400.   If *iGeoIP_Info\GeoIP_databaseType = #GEOIP_COUNTRY_EDITION Or *iGeoIP_Info\GeoIP_databaseType = #GEOIP_COUNTRY_EDITION_V6
  401.     seek_record - *iGeoIP_Info\GeoIP_databaseSegments
  402.     If seek_record > -1 And seek_record < #GeoIPMaxContry +1
  403.       With *iGeoIPRecord
  404.         \Index_Data = seek_record
  405.         \country_name =GeoIP_CountryNames(\Index_Data )
  406.         \country_code = GeoIP_CountryCodes(\Index_Data )
  407.         \continent_code = GeoIP_CountryContinent(\Index_Data )
  408.         \country_code3 = GeoIP_CountryCodes3(\Index_Data )
  409.         \time_zone = GeoIP_time_zone_by_country_and_region(\country_code ,"")
  410.         ProcedureReturn 1
  411.       EndWith
  412.     EndIf
  413.     ProcedureReturn 0
  414.   EndIf
  415.  
  416.   Protected record_pointer.l
  417.   Protected Dim record_buf.a(#FULL_RECORD_LENGTH-1)
  418.   Protected str_length.l = 0, nRdb.l, j.l
  419.  
  420.   Protected latitude.f = 0
  421.   Protected longitude.f = 0
  422.   Protected latitudei.i = 0
  423.   Protected longitudei.i = 0  
  424.   Protected metroarea_combo.l = 0
  425.  
  426.   With *iGeoIP_Info
  427.    
  428.     record_pointer = seek_record + 5 * \GeoIP_databaseSegments
  429.    
  430.     If \GeoIP_fCach_Memory
  431.       nRdb = CopyMemory(\GeoIP_datBuffer + record_pointer, @record_buf(), #FULL_RECORD_LENGTH)
  432.     Else
  433.       FileSeek(\GeoIP_File_ID, record_pointer)
  434.       nRdb = ReadData(\GeoIP_File_ID, @record_buf(), #FULL_RECORD_LENGTH)
  435.     EndIf
  436.    
  437.     If nRdb < #FULL_RECORD_LENGTH
  438.       ProcedureReturn -2
  439.     EndIf
  440.    
  441.   EndWith
  442.  
  443.   ;   ShowMemoryViewer(@record_buf(),50)
  444.  
  445.   If record_buf(0) > -1 And record_buf(0) < #GeoIPMaxContry +1
  446.     With *iGeoIPRecord
  447.       \Index_Data = record_buf(0)
  448.       \country_name =GeoIP_CountryNames(\Index_Data )
  449.       \country_code = GeoIP_CountryCodes(\Index_Data )
  450.       \continent_code = GeoIP_CountryContinent(\Index_Data )
  451.       \country_code3 = GeoIP_CountryCodes3(\Index_Data )
  452.       \region = PeekS(@record_buf(1),-1, #PB_UTF8)
  453.       \time_zone = GeoIP_time_zone_by_country_and_region(\country_code ,\region)
  454.      
  455.       str_length + Len(\region) + 1 + 1
  456.      
  457.       \city = PeekS(@record_buf(str_length),-1,#PB_UTF8)
  458.      
  459.       str_length + Len(\city) + 1
  460.      
  461.       \postal_code = PeekS(@record_buf(str_length),-1,#PB_UTF8)
  462.      
  463.       str_length + Len(\postal_code) + 1
  464.      
  465.       For j = 0 To 2
  466.         latitudei + (record_buf(str_length + j) << (j * 8))
  467.       Next
  468.       \latitude = (latitudei / 10000 - 180)
  469.      
  470.       str_length + 3
  471.      
  472.       For j = 0 To 2
  473.         longitudei + (record_buf(str_length+j) << (j * 8))
  474.       Next
  475.       \longitude = (longitudei / 10000 - 180)
  476.      
  477.       str_length + 3
  478.      
  479.       If \country_code = "US"
  480.         For j = 0 To 2
  481.           metroarea_combo + (record_buf(str_length+j) << (j * 8))
  482.         Next
  483.         \metro_code = metroarea_combo / 1000
  484.         \area_code = metroarea_combo % 1000
  485.       EndIf
  486.      
  487.     EndWith
  488.     ProcedureReturn 1
  489.   EndIf
  490.   ProcedureReturn 0
  491. EndProcedure
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement