Skip to content

Commit 09d9d5b

Browse files
committed
Support PX9 and PX10.
1 parent aa7ac37 commit 09d9d5b

File tree

4 files changed

+99
-39
lines changed

4 files changed

+99
-39
lines changed

IP2Proxy.py

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import sys
1818
import struct
1919
import socket
20+
import ipaddress
2021

2122
if sys.version < '3':
2223
def u(x):
@@ -50,7 +51,7 @@ def inet_pton(t, addr):
5051
return out_addr_p.raw
5152
socket.inet_pton = inet_pton
5253

53-
_VERSION = '2.2.0'
54+
_VERSION = '3.0.0'
5455
_NO_IP = 'MISSING IP ADDRESS'
5556
_FIELD_NOT_SUPPORTED = 'NOT SUPPORTED'
5657
_INVALID_IP_ADDRESS = 'INVALID IP ADDRESS'
@@ -71,23 +72,25 @@ class IP2ProxyRecord:
7172
asn = _FIELD_NOT_SUPPORTED
7273
last_seen = _FIELD_NOT_SUPPORTED
7374
domain = _FIELD_NOT_SUPPORTED
75+
threat = _FIELD_NOT_SUPPORTED
7476

7577
def __str__(self):
7678
return str(self.__dict__)
7779

7880
def __repr__(self):
7981
return repr(self.__dict__)
8082

81-
_COUNTRY_POSITION = (0, 2, 3, 3, 3, 3, 3, 3, 3)
82-
_REGION_POSITION = (0, 0, 0, 4, 4, 4, 4, 4, 4)
83-
_CITY_POSITION = (0, 0, 0, 5, 5, 5, 5, 5, 5)
84-
_ISP_POSITION = (0, 0, 0, 0, 6, 6, 6, 6, 6)
85-
_PROXYTYPE_POSITION = (0, 0, 2, 2, 2, 2, 2, 2, 2)
86-
_DOMAIN_POSITION = (0, 0, 0, 0, 0, 7, 7, 7, 7)
87-
_USAGETYPE_POSITION = (0, 0, 0, 0, 0, 0, 8, 8, 8)
88-
_ASN_POSITION = (0, 0, 0, 0, 0, 0, 0, 9, 9)
89-
_AS_POSITION = (0, 0, 0, 0, 0, 0, 0, 10, 10)
90-
_LASTSEEN_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 11)
83+
_COUNTRY_POSITION = (0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3)
84+
_REGION_POSITION = (0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4)
85+
_CITY_POSITION = (0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5)
86+
_ISP_POSITION = (0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6)
87+
_PROXYTYPE_POSITION = (0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2)
88+
_DOMAIN_POSITION = (0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7)
89+
_USAGETYPE_POSITION = (0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8)
90+
_ASN_POSITION = (0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9)
91+
_AS_POSITION = (0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10)
92+
_LASTSEEN_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11)
93+
_THREAT_POSITION = (0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12)
9194

9295
class IP2Proxy(object):
9396
''' IP2Proxy database '''
@@ -196,10 +199,17 @@ def is_proxy(self, ip):
196199
''' Determine whether is a proxy '''
197200
try:
198201
rec = self._get_record(ip)
199-
if self._dbtype == 1:
200-
is_proxy = 0 if (rec.country_short == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
202+
# if self._dbtype == 1:
203+
# is_proxy = 0 if (rec.country_short == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
204+
# else:
205+
# is_proxy = 0 if (rec.proxy_type == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
206+
if rec.country_short != _INVALID_IP_ADDRESS:
207+
if self._dbtype == 1:
208+
is_proxy = 0 if (rec.country_short == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
209+
else:
210+
is_proxy = 0 if (rec.proxy_type == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
201211
else:
202-
is_proxy = 0 if (rec.proxy_type == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
212+
is_proxy = -1
203213
except:
204214
is_proxy = -1
205215
return is_proxy
@@ -265,10 +275,13 @@ def get_all(self, ip):
265275
as_name = rec.as_name
266276
last_seen = rec.last_seen
267277

268-
if self._dbtype == 1:
269-
is_proxy = 0 if (rec.country_short == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
278+
if rec.country_short != _INVALID_IP_ADDRESS:
279+
if self._dbtype == 1:
280+
is_proxy = 0 if (rec.country_short == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
281+
else:
282+
is_proxy = 0 if (rec.proxy_type == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
270283
else:
271-
is_proxy = 0 if (rec.proxy_type == '-') else ( 2 if ((rec.proxy_type == 'DCH') | (rec.proxy_type == 'SES')) else 1)
284+
is_proxy = -1
272285
except:
273286
country_short = _INVALID_IP_ADDRESS
274287
country_long = _INVALID_IP_ADDRESS
@@ -410,9 +423,23 @@ def __iter__(self):
410423
yield self._read_record(low, 6)
411424
low += 1
412425

426+
def _validate_addr(self, addr):
427+
''' Validate IP address '''
428+
try:
429+
# ip = ipaddress.ip_address(addr)
430+
ip = ipaddress.ip_address(u(addr))
431+
return True
432+
except ValueError:
433+
return False
434+
413435
def _parse_addr(self, addr):
414436
''' Parses address and returns IP version. Raises exception on invalid argument '''
415437
ipv = 0
438+
ipnum = -1
439+
ipvalidateresult = self._validate_addr(addr)
440+
# print ("IP " + str(addr) + " is " + str(ipvalidateresult) + ".")
441+
if (ipvalidateresult == False):
442+
return ipv, ipnum
416443
try:
417444
# socket.inet_pton(socket.AF_INET6, addr)
418445
a, b = struct.unpack('!QQ', socket.inet_pton(socket.AF_INET6, addr))
@@ -496,6 +523,20 @@ def _get_record(self, ip):
496523
rec.as_name = _NO_IP
497524
rec.last_seen = _NO_IP
498525
return rec
526+
else:
527+
rec = IP2ProxyRecord()
528+
rec.country_short = _INVALID_IP_ADDRESS
529+
rec.country_long = _INVALID_IP_ADDRESS
530+
rec.region = _INVALID_IP_ADDRESS
531+
rec.city = _INVALID_IP_ADDRESS
532+
rec.isp = _INVALID_IP_ADDRESS
533+
rec.proxy_type = _INVALID_IP_ADDRESS
534+
rec.domain = _INVALID_IP_ADDRESS
535+
rec.usage_type = _INVALID_IP_ADDRESS
536+
rec.asn = _INVALID_IP_ADDRESS
537+
rec.as_name = _INVALID_IP_ADDRESS
538+
rec.last_seen = _INVALID_IP_ADDRESS
539+
return rec
499540

500541
while low <= high:
501542
# mid = int((low + high) / 2)

README.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Below are the methods supported in this library.
3232
|get_asn|Return the autonomous system number (ASN) of proxy's IP address or domain name.|
3333
|get_as_name|Return the autonomous system (AS) name of proxy's IP address or domain name.|
3434
|get_last_seen|Return the last seen days ago value of proxy's IP address or domain name.|
35+
|get_threat|Return the threat types reported to proxy's IP address or domain name.|
3536

3637
## Requirements
3738
1. Python 2.2 and above
@@ -55,7 +56,7 @@ import IP2Proxy
5556
db = IP2Proxy.IP2Proxy()
5657

5758
# open IP2Proxy BIN database for proxy lookup
58-
db.open("IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP-DOMAIN-USAGETYPE-ASN-LASTSEEN.BIN")
59+
db.open("IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP-DOMAIN-USAGETYPE-ASN-LASTSEEN-THREAT-RESIDENTIAL.BIN")
5960

6061
# get versioning information
6162
print ('Module Version: ' + db.get_module_version())
@@ -75,6 +76,7 @@ print ('Usage Type: ' + db.get_usage_type("4.0.0.47"))
7576
print ('ASN: ' + db.get_asn("4.0.0.47"))
7677
print ('AS Name: ' + db.get_as_name("4.0.0.47"))
7778
print ('Last Seen: ' + db.get_last_seen("4.0.0.47"))
79+
print ('Threat: ' + db.get_threat("4.0.0.47"))
7880

7981
# single function to get all proxy data returned in array
8082
record = db.get_all("4.0.0.47")
@@ -91,12 +93,13 @@ print ('Usage Type: ' + record['usage_type'])
9193
print ('ASN: ' + record['asn'])
9294
print ('AS Name: ' + record['as_name'])
9395
print ('Last Seen: ' + record['last_seen'])
96+
print ('Threat: ' + record['threat'])
9497

9598
# close IP2Proxy BIN database
9699
db.close()
97100
```
98101

99-
### Proxy Type
102+
## Proxy Type
100103

101104
| Proxy Type | Description |
102105
| ---------- | ------------------------------ |
@@ -106,6 +109,7 @@ db.close()
106109
| WEB | Web Proxies. |
107110
| DCH | Hosting Providers/Data Center. |
108111
| SES | Search Engine Robots. |
112+
| RES | Residential Proxies [PX10+] |
109113

110114
## Usage Type
111115

@@ -124,6 +128,15 @@ db.close()
124128
| SES | Search Engine Spider |
125129
| RSV | Reserved |
126130

131+
## Threat Type
132+
133+
| Threat Type | Description |
134+
| ----------- | -------------------------- |
135+
| SPAM | Spammer |
136+
| SCANNER | Security Scanner or Attack |
137+
| BOTNET | Spyware or Malware |
138+
139+
127140

128141
## Support
129142

example.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
# open IP2Proxy BIN database for proxy lookup
66
# db.open(os.path.join("data", "IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP.SAMPLE.BIN"))
7-
db.open("IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP-DOMAIN-USAGETYPE-ASN-LASTSEEN.BIN")
7+
db.open("IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP-DOMAIN-USAGETYPE-ASN-LASTSEEN-THREAT-RESIDENTIAL.BIN")
88

99
# get versioning information
1010
print ('Module Version: ' + db.get_module_version())
@@ -24,6 +24,7 @@
2424
print ('ASN: ' + db.get_asn("4.0.0.47"))
2525
print ('AS Name: ' + db.get_as_name("4.0.0.47"))
2626
print ('Last Seen: ' + db.get_last_seen("4.0.0.47"))
27+
print ('Threat: ' + db.get_threat("4.0.0.47"))
2728

2829
# single function to get all proxy data returned in array
2930
record = db.get_all("4.0.0.47")
@@ -40,6 +41,7 @@
4041
print ('ASN: ' + record['asn'])
4142
print ('AS Name: ' + record['as_name'])
4243
print ('Last Seen: ' + record['last_seen'])
44+
print ('Threat: ' + record['threat'])
4345

4446
# close IP2Proxy BIN database
4547
db.close()

setup.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,29 @@
11
import setuptools
22

33
with open("README.md", "r") as fh:
4-
long_description = fh.read()
4+
long_description = fh.read()
55

66
setuptools.setup(
7-
name="IP2Proxy",
8-
version="2.2.0",
9-
author="IP2Location",
10-
author_email="support@ip2location.com",
11-
description="Python API for IP2Proxy database. It can be used to query an IP address if it was being used as open proxy, web proxy, VPN anonymizer and TOR exits.",
12-
long_description=long_description,
13-
long_description_content_type="text/markdown",
14-
py_modules=['IP2Proxy'],
15-
url="https://github.com/ip2location/ip2proxy-python",
16-
packages=setuptools.find_packages(),
17-
classifiers=(
18-
"Development Status :: 5 - Production/Stable",
19-
"Intended Audience :: Developers",
20-
"Topic :: Software Development :: Libraries :: Python Modules",
21-
"Programming Language :: Python :: 3",
22-
"License :: OSI Approved :: MIT License",
23-
"Operating System :: OS Independent",
24-
),
7+
name="IP2Proxy",
8+
version="3.0.0",
9+
author="IP2Location",
10+
author_email="support@ip2location.com",
11+
description="Python API for IP2Proxy database. It can be used to query an IP address if it was being used as open proxy, web proxy, VPN anonymizer and TOR exits.",
12+
long_description=long_description,
13+
long_description_content_type="text/markdown",
14+
py_modules=['IP2Proxy'],
15+
url="https://github.com/ip2location/ip2proxy-python",
16+
packages=setuptools.find_packages(),
17+
install_requires=[
18+
'ipaddress;python_version<"3.3"',
19+
]
20+
classifiers=(
21+
"Development Status :: 5 - Production/Stable",
22+
"Intended Audience :: Developers",
23+
"Topic :: Software Development :: Libraries :: Python Modules",
24+
"Programming Language :: Python :: 2.7",
25+
"Programming Language :: Python :: 3",
26+
"License :: OSI Approved :: MIT License",
27+
"Operating System :: OS Independent",
28+
),
2529
)

0 commit comments

Comments
 (0)