geolocation ip with maxmind geoip "support only the free version!"
you need geoip data :
Site : http://dev.maxmind.com/geoip/legacy/geolite/
for ipv4
GeoLite Country : http://geolite.maxmind.com/download/geo ... oIP.dat.gz
GeoLite City : http://geolite.maxmind.com/download/geo ... ity.dat.gz
for ipv6
GeoLite Country : http://geolite.maxmind.com/download/geo ... Pv6.dat.gz
GeoLite City :
http://geolite.maxmind.com/download/geo ... yv6.dat.gz
...Download and extract the archive .
Code: Select all
EnableExplicit
;By Celtic88 2016(c) v: 1.1 new update 2017 add support for ipv6
Structure GeoIP_Info
GeoIP_databaseType.l
GeoIP_Path.s{260}
GeoIP_File_ID.i
GeoIP_Size.l
GeoIP_databaseSegments.l
EndStructure
Structure GeoIPRecord
Index_Data.l
latitude.f
longitude.f
metro_code.l
area_code.l
GeoIP_databaseType.l
country_name.s{1024}
region.s{1024}
city.s{1024}
country_code.s{260}
postal_code.s{260}
EndStructure
Structure in6_addr
StructureUnion
u_char.b[16];
u_short.w[8];
EndStructureUnion
EndStructure
OpenLibrary(0,"Ws2_32")
Prototype InetPtonW(Family.l,pszAddrString.s,*pAddrBuf)
Global InetPtonW.InetPtonW = GetFunction(0,"InetPtonW")
Macro GEOIP_CHKBIT_V6(bit,ptr)
(ptr\u_char[((127 - bit) >> 3)] & (1 << (~(127 - bit) & 7)))
EndMacro
Macro IN6_IS_ADDR_LOOPBACK(adr)
((adr\u_short[0] = 0) And (adr\u_short[1] = 0) And
(adr\u_short[2] = 0) And (adr\u_short[3] = 0) And
(adr\u_short[4] = 0) And (adr\u_short[5] = 0) And
(adr\u_short[6] = 0) And (adr\u_short[7] = $0100))
EndMacro
Macro IN6_IS_ADDR_LINKLOCAL(adr)
((adr\u_char[0] = $fffffffffffffffe) And ((adr\u_char[1] & $ffffffffffffffc0) = $ffffffffffffff80))
EndMacro
#AF_INET6 = 23
#STRUCTURE_INFO_MAX_SIZE = 20
#FULL_RECORD_LENGTH = 50
#COUNTRY_BEGIN = 16776960
#GEOIP_COUNTRY_EDITION = 1
#GEOIP_COUNTRY_EDITION_V6 = 12
#GEOIP_CITY_EDITION_REV1 = 2
#GEOIP_CITY_EDITION_REV1_V6 = 30
#GeoIPMaxContry = 255
Global Dim GeoIP_CountryNames.s{260}(#GeoIPMaxContry)
Global Dim GeoIP_CountryCodes.s{260}(#GeoIPMaxContry)
Procedure GeoIP_Name_ini()
Protected CountryNamesCodes.s = PeekS(?GeoIP_DCountryNamesCodes,-1,#PB_Ascii)
Protected Ii,io
For Ii = 0 To #GeoIPMaxContry
io + 1
GeoIP_CountryNames(Ii) = StringField(CountryNamesCodes, io,"|")
Next
For Ii = 0 To #GeoIPMaxContry
io + 1
GeoIP_CountryCodes(Ii) = StringField(CountryNamesCodes, io,"|")
Next
EndProcedure
ProcedureDLL GeoIP_Free(*iGeoIP_Info.GeoIP_Info)
If *iGeoIP_Info < 1
ProcedureReturn 0
EndIf
With *iGeoIP_Info
If \GeoIP_File_ID
CloseFile(\GeoIP_File_ID)
EndIf
EndWith
ClearStructure(*iGeoIP_Info, GeoIP_Info)
FreeMemory(*iGeoIP_Info)
EndProcedure
ProcedureDLL GeoIP_Open(GeoIP_Path.s)
Protected Dim buf.a(2)
Protected Ii.l,j.l,nRdb.l
Protected GoPenf.i
Protected GetSize = FileSize(GeoIP_Path)
If GetSize > 0
GoPenf = OpenFile(#PB_Any,GeoIP_Path,#PB_File_SharedRead)
If GoPenf = 0
ProcedureReturn 0
EndIf
Else
ProcedureReturn 0
EndIf
Protected *iGeoIP_Info.GeoIP_Info = AllocateMemory(SizeOf(GeoIP_Info))
If *iGeoIP_Info =0
CloseFile(GoPenf)
ProcedureReturn 0
EndIf
With *iGeoIP_Info
\GeoIP_databaseType = #GEOIP_COUNTRY_EDITION
\GeoIP_databaseSegments = #COUNTRY_BEGIN
\GeoIP_File_ID = GoPenf
\GeoIP_Size = GetSize
GetSize-3
FileSeek(\GeoIP_File_ID, GetSize)
For Ii=0 To #STRUCTURE_INFO_MAX_SIZE - 1
nRdb = ReadData(\GeoIP_File_ID,@BUF(), 3)
If nRdb < 3
GeoIP_Free(*iGeoIP_Info)
ProcedureReturn 0
EndIf
If BUF(0) = 255 And BUF(1) = 255 And BUF(2) = 255
GetSize + 3
FileSeek(\GeoIP_File_ID, GetSize)
\GeoIP_databaseType = ReadAsciiCharacter(\GeoIP_File_ID)
FileSeek(\GeoIP_File_ID, GetSize + 1)
nRdb = ReadData(\GeoIP_File_ID,@BUF(), 3)
If nRdb < 3
GeoIP_Free(*iGeoIP_Info)
ProcedureReturn 0
EndIf
If \GeoIP_databaseType = #GEOIP_COUNTRY_EDITION_V6
Break
EndIf
If \GeoIP_databaseType = #GEOIP_CITY_EDITION_REV1 Or
\GeoIP_databaseType = #GEOIP_CITY_EDITION_REV1_V6
\GeoIP_databaseSegments = 0
For j = 0 To 2
\GeoIP_databaseSegments + (BUF(j) << (j * 8))
Next
Else
GeoIP_Free(*iGeoIP_Info)
ProcedureReturn 0
EndIf
EndIf
GetSize - 4
FileSeek(\GeoIP_File_ID, GetSize)
Next
FileSeek(\GeoIP_File_ID, 0)
EndWith
ProcedureReturn *iGeoIP_Info
EndProcedure
ProcedureDLL.l GeoIP_Seek_Record_V6(*iGeoIP_Info.GeoIP_Info,*IPAddressnum.in6_addr)
If *iGeoIP_Info < 1
ProcedureReturn 0
EndIf
Protected depth.l
Protected x.l ,nRdb.l
Protected Dim stack_buffer.a(2 * 3)
Protected offset.l = 0
Protected record_pair_length.l = 6
Protected byte_offset.l
With *iGeoIP_Info
For depth = 127 To 0 Step -1
byte_offset = record_pair_length * offset
FileSeek(\GeoIP_File_ID,byte_offset)
nRdb = ReadData(\GeoIP_File_ID,@stack_buffer(), record_pair_length)
If nRdb < record_pair_length
ProcedureReturn 0
EndIf
If GEOIP_CHKBIT_V6(depth,*IPAddressnum)
x = (stack_buffer(3 * 1 + 0) << (0 * 8)) +
(stack_buffer(3 * 1 + 1) << (1 * 8)) +
(stack_buffer(3 * 1 + 2) << (2 * 8))
Else
x = (stack_buffer(3 * 0 + 0) << (0 * 8)) +
(stack_buffer(3 * 0 + 1) << (1 * 8)) +
(stack_buffer(3 * 0 + 2) << (2 * 8))
EndIf
If (x >= \GeoIP_databaseSegments)
ProcedureReturn x
EndIf
offset = x
Next
EndWith
ProcedureReturn 0
EndProcedure
ProcedureDLL.l GeoIP_Seek_Record(*iGeoIP_Info.GeoIP_Info,ipnum.q)
If *iGeoIP_Info < 1
ProcedureReturn 0
EndIf
Protected depth.l
Protected x.l ,nRdb.l
Protected Dim stack_buffer.a(2 * 3)
Protected offset.l = 0
Protected record_pair_length.l = 6
Protected byte_offset.l
With *iGeoIP_Info
For depth = 31 To 0 Step -1
byte_offset = record_pair_length * offset
FileSeek(\GeoIP_File_ID,byte_offset)
nRdb = ReadData(\GeoIP_File_ID,@stack_buffer(), record_pair_length)
If nRdb < record_pair_length
ProcedureReturn 0
EndIf
If (ipnum & (1 << depth))
x = (stack_buffer(3 * 1 + 0) << (0 * 8)) +
(stack_buffer(3 * 1 + 1) << (1 * 8)) +
(stack_buffer(3 * 1 + 2) << (2 * 8))
Else
x = (stack_buffer(3 * 0 + 0) << (0 * 8)) +
(stack_buffer(3 * 0 + 1) << (1 * 8)) +
(stack_buffer(3 * 0 + 2) << (2 * 8))
EndIf
If (x >= \GeoIP_databaseSegments)
ProcedureReturn x
EndIf
offset = x
Next
EndWith
ProcedureReturn 0
EndProcedure
ProcedureDLL GeoIP_Extract_Record(*iGeoIP_Info.GeoIP_Info, *iGeoIPRecord.GeoIPRecord, seek_record.l)
If *iGeoIP_Info < 1 Or *iGeoIPRecord < 1 Or seek_record < 0
ProcedureReturn 0
EndIf
ClearStructure(*iGeoIPRecord, GeoIPRecord)
*iGeoIPRecord\GeoIP_databaseType = *iGeoIP_Info\GeoIP_databaseType
If *iGeoIP_Info\GeoIP_databaseType = #GEOIP_COUNTRY_EDITION Or
*iGeoIP_Info\GeoIP_databaseType = #GEOIP_COUNTRY_EDITION_V6
seek_record - *iGeoIP_Info\GeoIP_databaseSegments
If seek_record > -1 And seek_record <= #GeoIPMaxContry
With *iGeoIPRecord
\Index_Data = seek_record
\country_name =GeoIP_CountryNames(\Index_Data )
\country_code = GeoIP_CountryCodes(\Index_Data )
ProcedureReturn 1
EndWith
EndIf
ProcedureReturn 0
EndIf
Protected record_pointer.l
Protected Dim record_buf.a(#FULL_RECORD_LENGTH-1)
Protected str_length.l = 0, nRdb.l, j.l
Protected latitude.f = 0
Protected longitude.f = 0
Protected latitudei.i = 0
Protected longitudei.i = 0
Protected metroarea_combo.l = 0
With *iGeoIP_Info
record_pointer = seek_record + 5 * \GeoIP_databaseSegments
FileSeek(\GeoIP_File_ID, record_pointer)
nRdb = ReadData(\GeoIP_File_ID, @record_buf(), #FULL_RECORD_LENGTH)
If nRdb < #FULL_RECORD_LENGTH
ProcedureReturn 0
EndIf
EndWith
; ShowMemoryViewer(@record_buf(),50)
If record_buf(0) > -1 And record_buf(0) <= #GeoIPMaxContry
With *iGeoIPRecord
\Index_Data = record_buf(0)
\country_name =GeoIP_CountryNames(\Index_Data )
\country_code = GeoIP_CountryCodes(\Index_Data )
\region = PeekS(@record_buf(1),-1, #PB_Ascii)
str_length + Len(\region) + 1 + 1
\city = PeekS(@record_buf(str_length),-1,#PB_Ascii)
str_length + Len(\city) + 1
\postal_code = PeekS(@record_buf(str_length),-1,#PB_Ascii)
str_length + Len(\postal_code) + 1
For j = 0 To 2
latitudei + (record_buf(str_length + j) << (j * 8))
Next
\latitude = (latitudei / 10000 - 180)
str_length + 3
For j = 0 To 2
longitudei + (record_buf(str_length+j) << (j * 8))
Next
\longitude = (longitudei / 10000 - 180)
EndWith
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
ProcedureDLL GeoIP_IPNumIsPrivate(ipnum.q)
ProcedureReturn Bool((ipnum >= 167772160 And ipnum <= 184549375) Or
(ipnum >= 2851995648 And ipnum <= 2852061183) Or
(ipnum >= 2886729728 And ipnum <= 2887778303) Or
(ipnum >= 3232235520 And ipnum <= 3232301055) Or
(ipnum >= 2130706432 And ipnum <= 2147483647))
EndProcedure
ProcedureDLL.q GeoIP_IPConvertToNum(Address.s)
If CountString(Address, ".") = 3
Protected RET.q = (Pow(256,3) * Val(StringField(Address, 1, "."))) +
(Pow(256,2) * Val(StringField(Address, 2, "."))) +
(256 * Val(StringField(Address, 3, "."))) +
Val(StringField(Address, 4, "."))
ProcedureReturn RET
EndIf
ProcedureReturn 0
EndProcedure
ProcedureDLL GeoIP_IPNumIsPrivate_V6(*IPAddressnum.in6_addr)
If IN6_IS_ADDR_LOOPBACK(*IPAddressnum) =1 Or IN6_IS_ADDR_LINKLOCAL(*IPAddressnum) =1
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
ProcedureDLL.i GeoIP_IPConvertToNum_V6(IPAddress.s, *IPAddressnum.in6_addr)
If InetPtonW
ProcedureReturn InetPtonW(#AF_INET6, IPAddress, *IPAddressnum)
EndIf
EndProcedure
ProcedureDLL GeoIP_GetInfo(*iGeoIP_Info.GeoIP_Info, ip.s, *GeoIPRecord.GeoIPRecord)
*GeoIPRecord\country_name = "<Local>"
Protected Seek_Record.l,IPnum.q
If *iGeoIP_Info\GeoIP_databaseType = #GEOIP_COUNTRY_EDITION_V6 Or
*iGeoIP_Info\GeoIP_databaseType = #GEOIP_CITY_EDITION_REV1_V6
Protected IPAddressnum.in6_addr
IPnum = GeoIP_IPConvertToNum_V6(ip,IPAddressnum)
Seek_Record = GeoIP_Seek_Record_V6(*iGeoIP_Info,IPAddressnum)
If Seek_Record
If GeoIP_Extract_Record(*iGeoIP_Info, *GeoIPRecord, Seek_Record)
ProcedureReturn 1
EndIf
EndIf
Else
IPnum = GeoIP_IPConvertToNum(ip)
If GeoIP_IPNumIsPrivate(IPnum) = 0 ; is local ip
*GeoIPRecord\country_name = "?"
Seek_Record = GeoIP_Seek_Record(*iGeoIP_Info,IPnum)
If Seek_Record
If GeoIP_Extract_Record(*iGeoIP_Info, *GeoIPRecord, Seek_Record)
ProcedureReturn 1
EndIf
EndIf
EndIf
EndIf
ProcedureReturn 0
EndProcedure
GeoIP_Name_ini()
DataSection
GeoIP_DCountryNamesCodes:
Data.a "N/A|Asia/Pacific Region|Europe|Andorra|United Arab Emirates|Afghanistan|Antigua and Barbuda|Anguilla|Albania|Armenia|Curacao|Angola|Antarctica|Argentina|American Samoa|Austria|Australia|Aruba|Azerbaijan|Bosnia and Herzegovina|Barbados|Bangladesh|Belgium|Burkina Faso|Bulgaria|Bahrain|Burundi|Benin|Bermuda|Brunei Darussalam|Bolivia|Brazil|Bahamas|Bhutan|Bouvet Island|Botswana|Belarus|Belize|Canada|Cocos (Keeling) Islands|Congo, The Democratic Republic of the|Central African Republic|Congo|Switzerland|Cote D'Ivoire|Cook Islands|Chile|Cameroon|China|Colombia|Costa Rica|Cuba|Cape Verde|Christmas Island|Cyprus|Czech Republic|Germany|Djibouti|Denmark|Dominica|Dominican Republic|Algeria|Ecuador|Estonia|Egypt|Western Sahara|Eritrea|Spain|Ethiopia|Finland|Fiji|Falkland Islands (Malvinas)|Micronesia, Federated States of|Faroe Islands|France|Sint Maarten (Dutch part)|Gabon|United Kingdom|Grenada|Georgia|French Guiana|Ghana|Gibraltar|Greenland|Gambia|Guinea|Guadeloupe|Equatorial Guinea|Greece|South Georgia and the South Sandwich Islands|Guatemala|Guam|Guinea-Bissau|Guyana|Hong Kong|Heard Island and McDonald Islands|Honduras|Croatia|Haiti|Hungary|Indonesia|Ireland|Israel|India|British Indian Ocean Territory|Iraq|Iran, Islamic Republic of|Iceland|Italy|Jamaica|Jordan|Japan|Kenya|Kyrgyzstan|Cambodia|Kiribati|Comoros|Saint Kitts and Nevis|Korea, Democratic People's Republic of|Korea, Republic of|Kuwait|Cayman Islands|Kazakhstan|Lao People's Democratic Republic|Lebanon|Saint Lucia|Liechtenstein|Sri Lanka|Liberia|Lesotho|Lithuania|Luxembourg|Latvia|Libya|Morocco|Monaco|Moldova, Republic of|Madagascar|Marshall Islands|Macedonia|Mali|Myanmar|Mongolia|Macau|Northern Mariana Islands|Martinique|Mauritania|Montserrat|Malta|Mauritius|Maldives|Malawi|Mexico|Malaysia|Mozambique|Namibia|New Caledonia|Niger|Norfolk Island|Nigeria|Nicaragua|Netherlands|Norway|Nepal|Nauru|Niue|New Zealand|Oman|Panama|Peru|French Polynesia|Papua New Guinea|Philippines|Pakistan|Poland|Saint Pierre and Miquelon|Pitcairn Islands|Puerto Rico|Palestinian Territory|Portugal|Palau|Paraguay|Qatar|Reunion|Romania|Russian Federation|Rwanda|Saudi Arabia|Solomon Islands|Seychelles|Sudan|Sweden|Singapore|Saint Helena|Slovenia|Svalbard and Jan Mayen|Slovakia|Sierra Leone|San Marino|Senegal|Somalia|Suriname|Sao Tome and Principe|El Salvador|Syrian Arab Republic|Swaziland|Turks and Caicos Islands|Chad|French Southern Territories|Togo|Thailand|Tajikistan|Tokelau|Turkmenistan|Tunisia|Tonga|Timor-Leste|Turkey|Trinidad and Tobago|Tuvalu|Taiwan|Tanzania, United Republic of|Ukraine|Uganda|United States Minor Outlying Islands|United States|Uruguay|Uzbekistan|Holy See (Vatican City State)|Saint Vincent and the Grenadines|Venezuela|Virgin Islands, British|Virgin Islands, U.S.|Vietnam|Vanuatu|Wallis and Futuna|Samoa|Yemen|Mayotte|Serbia|South Africa|Zambia|Montenegro|Zimbabwe|Anonymous Proxy|Satellite Provider|Other|Aland Islands|Guernsey|Isle of Man|Jersey|Saint Barthelemy|Saint Martin|Bonaire, Saint Eustatius and Saba|South Sudan|Other|--|AP|EU|AD|AE|AF|AG|AI|AL|AM|CW|AO|AQ|AR|AS|AT|AU|AW|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EE|EG|EH|ER|ES|ET|FI|FJ|FK|FM|FO|FR|SX|GA|GB|GD|GE|GF|GH|GI|GL|GM|GN|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IN|IO|IQ|IR|IS|IT|JM|JO|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|MG|MH|MK|ML|MM|MN|MO|MP|MQ|MR|MS|MT|MU|MV|MW|MX|MY|MZ|NA|NC|NE|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PS|PT|PW|PY|QA|RE|RO|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SV|SY|SZ|TC|TD|TF|TG|TH|TJ|TK|TM|TN|TO|TL|TR|TT|TV|TW|TZ|UA|UG|UM|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|YE|YT|RS|ZA|ZM|ME|ZW|A1|A2|O1|AX|GG|IM|JE|BL|MF|BQ|SS|O1|"
Data.l 0
EndDataSection
DisableExplicit