1-
21import os
32from binascii import hexlify
43from socket import error , inet_aton , inet_pton , socket
@@ -28,6 +27,7 @@ class DBReader:
2827 record_bytes = None
2928 columns = []
3029 ipv6 = False
30+ blacklistfile = False
3131
3232 def __init__ (self , filename :str ):
3333 if not os .path .isfile (filename ):
@@ -54,58 +54,60 @@ def Fetch(self, ip:str):
5454
5555 v_literal = self .IP2Literal (ip )
5656 position = 0
57-
57+ previous = {}
5858 file_position = self .tree_start + self .BASE_TREE_BYTES
59- while True :
59+
60+ # Loop over tree. Will abort if we try too many times.
61+ for _ in range (257 ):
62+ previous [position ] = file_position
6063 if len (v_literal ) <= position :
6164 raise IPNotFoundException ("Invalid or nonexistant IP address specified for lookup. (EID: 8)" )
62-
63- next = 0
64- try :
65- if v_literal [position ] == "0" :
66- pos = self .ReadAt (file_position , self .TREE_BYTE_WIDTH )
67- if len (pos ) == 4 :
68- next = unpack ("<L" , pos )[0 ]
69- else :
70- pos = self .ReadAt (file_position + 4 , self .TREE_BYTE_WIDTH )
71- if len (pos ) == 4 :
72- next = unpack ("<L" , pos )[0 ]
7365
74- except Exception :
75- raise IPNotFoundException ("Invalid or nonexistant IP address specified for lookup. (EID: 9)" )
76-
77- try :
78- if next == 0 :
79- if v_literal [position ] == "0" :
80- pos = self .ReadAt (file_position + 4 , self .TREE_BYTE_WIDTH )
81- if len (pos ) == 4 :
82- next = unpack ("<L" , pos )[0 ]
83-
84- if next == 0 :
85- raise IPNotFoundException ()
86- else :
87- pos = self .ReadAt (file_position , self .TREE_BYTE_WIDTH )
88- if len (pos ) == 4 :
89- next = unpack ("<L" , pos )[0 ]
90-
91- if next == 0 :
92- raise IPNotFoundException ()
93- except Exception :
94- raise IPNotFoundException ("Invalid or nonexistant IP address specified for lookup. (EID: 10)" )
95-
96- file_position = next
66+ if v_literal [position ] == "0" :
67+ pos = self .ReadAt (file_position , self .TREE_BYTE_WIDTH )
68+ if len (pos ) == 4 :
69+ file_position = unpack ("<L" , pos )[0 ]
70+ else :
71+ pos = self .ReadAt (file_position + 4 , self .TREE_BYTE_WIDTH )
72+ if len (pos ) == 4 :
73+ file_position = unpack ("<L" , pos )[0 ]
74+
75+ if (self .blacklistfile == False ):
76+ if (file_position == 0 ):
77+ for i in range (position ):
78+ if (v_literal [position - i ] == "1" ):
79+ l = list (v_literal )
80+ l [position - i ] = "0"
81+ v_literal = '' .join (l )
82+
83+ for n in range (position - i + 1 , len (v_literal )):
84+ l = list (v_literal )
85+ l [n ] = "1"
86+ v_literal = '' .join (l )
87+
88+ position = position - i
89+ file_position = previous [position ]
90+ break
91+ continue
92+
9793 if (file_position < self .tree_end ):
94+ if (file_position == 0 ):
95+ break
9896 position += 1
9997 continue
98+
10099 try :
101100 raw = self .ReadAt (file_position , self .record_bytes )
102101 except Exception :
103102 raise IPNotFoundException ("Invalid or nonexistant IP address specified for lookup. (EID: 11)" )
104103
105104 try :
106105 return self .CreateRecord (raw )
106+
107107 except Exception :
108108 raise IPNotFoundException ("Invalid or nonexistant IP address specified for lookup. (EID: 12)" )
109+ raise IPNotFoundException ("Invalid or nonexistant IP address specified for lookup. (EID: 13)" )
110+
109111 def GetColumns (self ):
110112 return self .columns
111113
@@ -140,9 +142,12 @@ def SetupHeaders(self):
140142 if file_type .Has (BinaryOption .IPV6MAP ):
141143 self .valid = True
142144 self .ipv6 = True
143-
145+
144146 if file_type .Has (BinaryOption .BINARYDATA ):
145147 self .binary_data = True
148+
149+ if file_type .Has (BinaryOption .BLACKLISTFILE ):
150+ self .blacklistfile = True
146151
147152 if (self .valid == False ):
148153 raise FileReaderException ("Invalid file format, invalid first byte. EID 1." )
@@ -221,22 +226,27 @@ def CreateRecord(self,raw):
221226 value = unpack ("<L" , raw [current_byte :current_byte + 4 ])[0 ]
222227 record .ASN (int (value ))
223228 current_byte += 4
229+
224230 elif column .Name () == "Latitude" :
225231 value = unpack ("<f" , raw [current_byte :current_byte + 4 ])[0 ]
226232 record .Latitude (float (value ))
227233 current_byte += 4
234+
228235 elif column .Name () == "Longitude" :
229236 value = unpack ("<f" , raw [current_byte :current_byte + 4 ])[0 ]
230237 record .Longitude (float (value ))
231238 current_byte += 4
239+
232240 elif column .Name () == "ZeroFraudScore" :
233241 value = unpack ("B" , raw [current_byte :current_byte + 1 ])[0 ]
234242 record .SetFraudScore (0 , int (value ))
235243 current_byte += 1
244+
236245 elif column .Name () == "OneFraudScore" :
237246 value = unpack ("B" , raw [current_byte :current_byte + 1 ])[0 ]
238- record .ASN ( float (value ))
247+ record .SetFraudScore ( 1 , int (value ))
239248 current_byte += 1
249+
240250 else :
241251 if (column .Type ()).Has (BinaryOption .STRINGDATA ):
242252 value = self .GetRangedStringValue (unpack ("<L" , raw [current_byte :current_byte + 4 ])[0 ])
@@ -264,14 +274,17 @@ def IsIPv4(self, ip:str):
264274 try :
265275 inet_pton (AF_INET , ip )
266276 return True
277+
267278 except error :
268279 return False
269280
270281 def IsIPv6 (self , ip :str ):
271282 try :
272283 inet_pton (AF_INET6 , ip )
273284 return True
285+
274286 except error :
275287 return False
288+
276289 def __del__ (self ):
277290 self .handler .close ()
0 commit comments