Skip to content

Commit 4eb05c2

Browse files
committed
Added provider field and exception handling for incorrect BIN database.
1 parent 416eb79 commit 4eb05c2

File tree

4 files changed

+71
-76
lines changed

4 files changed

+71
-76
lines changed

LICENSE.TXT

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 IP2Location.com
3+
Copyright (c) 2021 IP2Location.com
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Below are the methods supported in this package.
1919
|---|---|
2020
|open|Open the IP2Proxy BIN data for lookup.|
2121
|close|Close and clean up metadata.|
22-
|getpackageversion|Get the package version (1 to 10 for PX1 to PX10 respectively).|
22+
|getpackageversion|Get the package version (1 to 11 for PX1 to PX11 respectively).|
2323
|getmoduleversion|Get the module version.|
2424
|getdatabaseversion|Get the database version.|
2525
|isproxy|Check whether if an IP address was a proxy. Returned value:<ul><li>-1 : errors</li><li>0 : not a proxy</li><li>1 : a proxy</li><li>2 : a data center IP address or search engine robot</li></ul>|
@@ -36,6 +36,7 @@ Below are the methods supported in this package.
3636
|getas|Return the autonomous system name of the proxy.|
3737
|getlastseen|Return the number of days that the proxy was last seen.|
3838
|getthreat|Return the threat type of the proxy.|
39+
|getprovider|Return the provider of the proxy.|
3940

4041
## Example
4142

ip2proxy.erl

Lines changed: 64 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-module(ip2proxy).
2-
-export([getpackageversion/0, getmoduleversion/0, getdatabaseversion/0, open/1, getall/1, getproxytype/1, getcountryshort/1, getcountrylong/1, getregion/1, getcity/1, getisp/1, getdomain/1, getusagetype/1, getasn/1, getas/1, getlastseen/1, getthreat/1, isproxy/1, close/0]).
2+
-export([getpackageversion/0, getmoduleversion/0, getdatabaseversion/0, open/1, getall/1, getproxytype/1, getcountryshort/1, getcountrylong/1, getregion/1, getcity/1, getisp/1, getdomain/1, getusagetype/1, getasn/1, getas/1, getlastseen/1, getthreat/1, getprovider/1, isproxy/1, close/0]).
33
-record(ip2proxyrecord, {
44
country_short = "-",
55
country_long = "-",
@@ -13,6 +13,7 @@
1313
as = "-",
1414
last_seen = "-",
1515
threat = "-",
16+
provider = "-",
1617
is_proxy = 0
1718
}).
1819
-define(IF(Cond), (case (Cond) of true -> (0); false -> (1) end)).
@@ -33,7 +34,7 @@ getpackageversion() ->
3334
end.
3435

3536
getmoduleversion() ->
36-
"3.0.0".
37+
"3.1.0".
3738

3839
getdatabaseversion() ->
3940
case ets:info(mymeta) of
@@ -112,49 +113,45 @@ open(InputFile) ->
112113
Ipv6databaseaddr = readuint32(S, 18),
113114
Ipv4indexbaseaddr = readuint32(S, 22),
114115
Ipv6indexbaseaddr = readuint32(S, 26),
116+
Productcode = readuint8(S, 30),
115117
Ipv4columnsize = Databasecolumn bsl 2, % 4 bytes each column
116118
Ipv6columnsize = 16 + ((Databasecolumn - 1) bsl 2), % 4 bytes each column, except IPFrom column which is 16 bytes
119+
% Producttype = readuint8(S, 31),
120+
% Filesize = readuint32(S, 32),
117121
file:close(S),
118122

119-
case ets:info(mymeta) of
120-
undefined ->
121-
ets:new(mymeta, [set, named_table]);
122-
_ ->
123-
ok % do nothing
124-
end,
125-
126-
ets:insert(mymeta, {inputfile, InputFile}),
127-
ets:insert(mymeta, {databasetype, Databasetype}),
128-
ets:insert(mymeta, {databasecolumn, Databasecolumn}),
129-
ets:insert(mymeta, {databaseyear, Databaseyear}),
130-
ets:insert(mymeta, {databasemonth, Databasemonth}),
131-
ets:insert(mymeta, {databaseday, Databaseday}),
132-
ets:insert(mymeta, {ipv4databasecount, Ipv4databasecount}),
133-
ets:insert(mymeta, {ipv4databaseaddr, Ipv4databaseaddr}),
134-
ets:insert(mymeta, {ipv6databasecount, Ipv6databasecount}),
135-
ets:insert(mymeta, {ipv6databaseaddr, Ipv6databaseaddr}),
136-
ets:insert(mymeta, {ipv4indexbaseaddr, Ipv4indexbaseaddr}),
137-
ets:insert(mymeta, {ipv6indexbaseaddr, Ipv6indexbaseaddr}),
138-
ets:insert(mymeta, {ipv4columnsize, Ipv4columnsize}),
139-
ets:insert(mymeta, {ipv6columnsize, Ipv6columnsize}),
140-
0; % zero means success
123+
if
124+
% check if is correct BIN (should be 2 for IP2Proxy BIN file), also checking for zipped file (PK being the first 2 chars)
125+
(Productcode /= 2 andalso Databaseyear >= 21) orelse (Databasetype == 80 andalso Databasecolumn == 75) ->
126+
io:format("Incorrect IP2Proxy BIN file format. Please make sure that you are using the latest IP2Proxy BIN file.~n", []),
127+
halt();
128+
true ->
129+
case ets:info(mymeta) of
130+
undefined ->
131+
ets:new(mymeta, [set, named_table]),
132+
ets:insert(mymeta, {inputfile, InputFile}),
133+
ets:insert(mymeta, {databasetype, Databasetype}),
134+
ets:insert(mymeta, {databasecolumn, Databasecolumn}),
135+
ets:insert(mymeta, {databaseyear, Databaseyear}),
136+
ets:insert(mymeta, {databasemonth, Databasemonth}),
137+
ets:insert(mymeta, {databaseday, Databaseday}),
138+
ets:insert(mymeta, {ipv4databasecount, Ipv4databasecount}),
139+
ets:insert(mymeta, {ipv4databaseaddr, Ipv4databaseaddr}),
140+
ets:insert(mymeta, {ipv6databasecount, Ipv6databasecount}),
141+
ets:insert(mymeta, {ipv6databaseaddr, Ipv6databaseaddr}),
142+
ets:insert(mymeta, {ipv4indexbaseaddr, Ipv4indexbaseaddr}),
143+
ets:insert(mymeta, {ipv6indexbaseaddr, Ipv6indexbaseaddr}),
144+
ets:insert(mymeta, {ipv4columnsize, Ipv4columnsize}),
145+
ets:insert(mymeta, {ipv6columnsize, Ipv6columnsize}),
146+
0; % zero means success
147+
_ ->
148+
ok % do nothing
149+
end
150+
end;
141151
_ ->
142152
-1 % negative one means error
143153
end.
144154

145-
% readcolcountry(S, Dbtype, Rowoffset, Col) ->
146-
% X = "NOT SUPPORTED",
147-
% case lists:nth(Dbtype, Col) of
148-
% 0 ->
149-
% {X, X};
150-
% Colpos ->
151-
% Coloffset = (Colpos - 1) bsl 2,
152-
% X0 = readuint32(S, Rowoffset + Coloffset),
153-
% X1 = readstr(S, X0),
154-
% X2 = readstr(S, X0 + 3),
155-
% {X1, X2}
156-
% end.
157-
158155
readcolcountryrow(S, R, Dbtype, Col) ->
159156
X = "NOT SUPPORTED",
160157
case lists:nth(Dbtype, Col) of
@@ -168,15 +165,6 @@ readcolcountryrow(S, R, Dbtype, Col) ->
168165
{X1, X2}
169166
end.
170167

171-
% readcolstring(S, Dbtype, Rowoffset, Col) ->
172-
% case lists:nth(Dbtype, Col) of
173-
% 0 ->
174-
% "NOT SUPPORTED";
175-
% Colpos ->
176-
% Coloffset = (Colpos - 1) bsl 2,
177-
% readstr(S, readuint32(S, Rowoffset + Coloffset))
178-
% end.
179-
180168
readcolstringrow(S, R, Dbtype, Col) ->
181169
case lists:nth(Dbtype, Col) of
182170
0 ->
@@ -187,17 +175,18 @@ readcolstringrow(S, R, Dbtype, Col) ->
187175
end.
188176

189177
readrecord(S, Dbtype, Rowoffset, Mode) ->
190-
Country_position = [0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3],
191-
Region_position = [0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4],
192-
City_position = [0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5],
193-
Isp_position = [0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6],
194-
Proxytype_position = [0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2],
195-
Domain_position = [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7],
196-
Usagetype_position = [0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8],
197-
Asn_position = [0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9],
198-
As_position = [0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10],
199-
Lastseen_position = [0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11],
200-
Threat_position = [0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12],
178+
Country_position = [0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
179+
Region_position = [0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4],
180+
City_position = [0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5],
181+
Isp_position = [0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6],
182+
Proxytype_position = [0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
183+
Domain_position = [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7],
184+
Usagetype_position = [0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8],
185+
Asn_position = [0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9],
186+
As_position = [0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10],
187+
Lastseen_position = [0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11],
188+
Threat_position = [0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12],
189+
Provider_position = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13],
201190

202191
Countryshort_field = 1,
203192
Countrylong_field = 2,
@@ -212,8 +201,9 @@ readrecord(S, Dbtype, Rowoffset, Mode) ->
212201
As_field = 1024,
213202
Lastseen_field = 2048,
214203
Threat_field = 4096,
204+
Provider_field = 8192,
215205

216-
Cols = ?IF(lists:nth(Dbtype, Country_position) == 0) + ?IF(lists:nth(Dbtype, Region_position) == 0) + ?IF(lists:nth(Dbtype, City_position) == 0) + ?IF(lists:nth(Dbtype, Isp_position) == 0) + ?IF(lists:nth(Dbtype, Proxytype_position) == 0) + ?IF(lists:nth(Dbtype, Domain_position) == 0) + ?IF(lists:nth(Dbtype, Usagetype_position) == 0) + ?IF(lists:nth(Dbtype, Asn_position) == 0) + ?IF(lists:nth(Dbtype, As_position) == 0) + ?IF(lists:nth(Dbtype, Lastseen_position) == 0) + ?IF(lists:nth(Dbtype, Threat_position) == 0),
206+
Cols = ?IF(lists:nth(Dbtype, Country_position) == 0) + ?IF(lists:nth(Dbtype, Region_position) == 0) + ?IF(lists:nth(Dbtype, City_position) == 0) + ?IF(lists:nth(Dbtype, Isp_position) == 0) + ?IF(lists:nth(Dbtype, Proxytype_position) == 0) + ?IF(lists:nth(Dbtype, Domain_position) == 0) + ?IF(lists:nth(Dbtype, Usagetype_position) == 0) + ?IF(lists:nth(Dbtype, Asn_position) == 0) + ?IF(lists:nth(Dbtype, As_position) == 0) + ?IF(lists:nth(Dbtype, Lastseen_position) == 0) + ?IF(lists:nth(Dbtype, Threat_position) == 0) + ?IF(lists:nth(Dbtype, Provider_position) == 0),
217207
Rowlength = Cols bsl 2,
218208

219209
case file:pread(S, Rowoffset - 1, Rowlength) of
@@ -224,92 +214,88 @@ readrecord(S, Dbtype, Rowoffset, Mode) ->
224214

225215
if
226216
(Mode band Proxytype_field /= 0) or (Mode band Isproxy_field /= 0) ->
227-
% Proxy_type = readcolstring(S, Dbtype, Rowoffset, Proxytype_position);
228217
Proxy_type = readcolstringrow(S, R, Dbtype, Proxytype_position);
229218
true ->
230219
Proxy_type = ""
231220
end,
232221

233222
if
234223
(Mode band Countryshort_field /= 0) or (Mode band Countrylong_field /= 0) or (Mode band Isproxy_field /= 0) ->
235-
% {Country_short, Country_long} = readcolcountry(S, Dbtype, Rowoffset, Country_position);
236224
{Country_short, Country_long} = readcolcountryrow(S, R, Dbtype, Country_position);
237225
true ->
238226
{Country_short, Country_long} = {"", ""}
239227
end,
240228

241229
if
242230
Mode band Region_field /= 0 ->
243-
% Region = readcolstring(S, Dbtype, Rowoffset, Region_position);
244231
Region = readcolstringrow(S, R, Dbtype, Region_position);
245232
true ->
246233
Region = ""
247234
end,
248235

249236
if
250237
Mode band City_field /= 0 ->
251-
% City = readcolstring(S, Dbtype, Rowoffset, City_position);
252238
City = readcolstringrow(S, R, Dbtype, City_position);
253239
true ->
254240
City = ""
255241
end,
256242

257243
if
258244
Mode band Isp_field /= 0 ->
259-
% Isp = readcolstring(S, Dbtype, Rowoffset, Isp_position);
260245
Isp = readcolstringrow(S, R, Dbtype, Isp_position);
261246
true ->
262247
Isp = ""
263248
end,
264249

265250
if
266251
Mode band Domain_field /= 0 ->
267-
% Domain = readcolstring(S, Dbtype, Rowoffset, Domain_position);
268252
Domain = readcolstringrow(S, R, Dbtype, Domain_position);
269253
true ->
270254
Domain = ""
271255
end,
272256

273257
if
274258
Mode band Usagetype_field /= 0 ->
275-
% Usage_type = readcolstring(S, Dbtype, Rowoffset, Usagetype_position);
276259
Usage_type = readcolstringrow(S, R, Dbtype, Usagetype_position);
277260
true ->
278261
Usage_type = ""
279262
end,
280263

281264
if
282265
Mode band Asn_field /= 0 ->
283-
% Asn = readcolstring(S, Dbtype, Rowoffset, Asn_position);
284266
Asn = readcolstringrow(S, R, Dbtype, Asn_position);
285267
true ->
286268
Asn = ""
287269
end,
288270

289271
if
290272
Mode band As_field /= 0 ->
291-
% As = readcolstring(S, Dbtype, Rowoffset, As_position);
292273
As = readcolstringrow(S, R, Dbtype, As_position);
293274
true ->
294275
As = ""
295276
end,
296277

297278
if
298279
Mode band Lastseen_field /= 0 ->
299-
% Last_seen = readcolstring(S, Dbtype, Rowoffset, Lastseen_position);
300280
Last_seen = readcolstringrow(S, R, Dbtype, Lastseen_position);
301281
true ->
302282
Last_seen = ""
303283
end,
304284

305285
if
306286
Mode band Threat_field /= 0 ->
307-
% Threat = readcolstring(S, Dbtype, Rowoffset, Threat_position);
308287
Threat = readcolstringrow(S, R, Dbtype, Threat_position);
309288
true ->
310289
Threat = ""
311290
end,
312291

292+
if
293+
Mode band Provider_field /= 0 ->
294+
Provider = readcolstringrow(S, R, Dbtype, Provider_position);
295+
true ->
296+
Provider = ""
297+
end,
298+
313299
if
314300
(Country_short == "-") or (Proxy_type == "-") ->
315301
Is_proxy = 0;
@@ -335,6 +321,7 @@ readrecord(S, Dbtype, Rowoffset, Mode) ->
335321
as = As,
336322
last_seen = Last_seen,
337323
threat = Threat,
324+
provider = Provider,
338325
is_proxy = Is_proxy
339326
}
340327
end.
@@ -361,10 +348,8 @@ searchtree(S, Ipnum, Dbtype, Low, High, BaseAddr, Colsize, Iptype, Mode) ->
361348
Ipnum >= Ipfrom andalso Ipnum < Ipto ->
362349
if
363350
Iptype == ipv4 ->
364-
% readrecord(S, Dbtype + 1, Rowoffset, Mode);
365351
readrecord(S, Dbtype + 1, Rowoffset + 4, Mode);
366352
true ->
367-
% readrecord(S, Dbtype + 1, Rowoffset + 12, Mode)
368353
readrecord(S, Dbtype + 1, Rowoffset + 16, Mode)
369354
end;
370355
true ->
@@ -389,6 +374,7 @@ searchtree(S, Ipnum, Dbtype, Low, High, BaseAddr, Colsize, Iptype, Mode) ->
389374
as = X,
390375
last_seen = X,
391376
threat = X,
377+
provider = X,
392378
is_proxy = -1
393379
}
394380
end.
@@ -416,7 +402,7 @@ search6(S, Ipnum, Dbtype, Low, High, Baseaddr, Indexbaseaddr, Colsize, Mode) ->
416402
end.
417403

418404
getall(Ip) ->
419-
query(Ip, 8191).
405+
query(Ip, 16383).
420406

421407
getcountryshort(Ip) ->
422408
Result = query(Ip, 1),
@@ -466,6 +452,10 @@ getthreat(Ip) ->
466452
Result = query(Ip, 4096),
467453
Result#ip2proxyrecord.threat.
468454

455+
getprovider(Ip) ->
456+
Result = query(Ip, 8192),
457+
Result#ip2proxyrecord.provider.
458+
469459
isproxy(Ip) ->
470460
Result = query(Ip, 64),
471461
Result#ip2proxyrecord.is_proxy.
@@ -537,6 +527,7 @@ query(Ip, Mode) ->
537527
as = X,
538528
last_seen = X,
539529
threat = X,
530+
provider = X,
540531
is_proxy = -1
541532
}
542533
end,
@@ -556,6 +547,7 @@ query(Ip, Mode) ->
556547
as = Y,
557548
last_seen = Y,
558549
threat = Y,
550+
provider = Y,
559551
is_proxy = -1
560552
}
561553
end

test.erl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ printme(V) ->
55
case V of
66
{} ->
77
io:format("No results.~n", []);
8-
{ip2proxyrecord, Country_short, Country_long, Region, City, Isp, Proxy_type, Domain, Usage_type, Asn, As, Last_seen, Threat, Is_proxy} ->
8+
{ip2proxyrecord, Country_short, Country_long, Region, City, Isp, Proxy_type, Domain, Usage_type, Asn, As, Last_seen, Threat, Provider, Is_proxy} ->
99
io:format("Country_short: ~p~n", [Country_short]),
1010
io:format("Country_long: ~p~n", [Country_long]),
1111
io:format("Region: ~p~n", [Region]),
@@ -18,13 +18,14 @@ printme(V) ->
1818
io:format("As: ~p~n", [As]),
1919
io:format("Last_seen: ~p~n", [Last_seen]),
2020
io:format("Threat: ~p~n", [Threat]),
21+
io:format("Provider: ~p~n", [Provider]),
2122
io:format("Is_proxy: ~p~n", [Is_proxy])
2223
end,
2324
io:format("===================================================================~n", []).
2425

2526
testme() ->
2627
X = "37.252.228.50",
27-
case ip2proxy:open("./IP2Proxy/bin/IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP-DOMAIN-USAGETYPE-ASN-LASTSEEN-THREAT-RESIDENTIAL.BIN") of
28+
case ip2proxy:open("./ip2proxy-testdata/IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP-DOMAIN-USAGETYPE-ASN-LASTSEEN-THREAT-RESIDENTIAL-PROVIDER.BIN") of
2829
0 ->
2930
io:format("getpackageversion: ~p~n", [ip2proxy:getpackageversion()]),
3031
io:format("getmoduleversion: ~p~n", [ip2proxy:getmoduleversion()]),
@@ -44,6 +45,7 @@ testme() ->
4445
io:format("AS: ~p~n", [ip2proxy:getas(X)]),
4546
io:format("Last_seen: ~p~n", [ip2proxy:getlastseen(X)]),
4647
io:format("Threat: ~p~n", [ip2proxy:getthreat(X)]),
48+
io:format("Provider: ~p~n", [ip2proxy:getprovider(X)]),
4749
io:format("Is_proxy: ~p~n", [ip2proxy:isproxy(X)]);
4850
_ ->
4951
io:format("Error reading BIN file~n", [])

0 commit comments

Comments
 (0)