|
14 | 14 |
|
15 | 15 | # For IP lookups |
16 | 16 | try: |
17 | | - import pygeoip |
| 17 | + import geoip2.database |
18 | 18 | except: |
19 | 19 | pass |
20 | 20 |
|
@@ -106,25 +106,18 @@ def __init__(self, **kwargs): |
106 | 106 | self.cleanupts = 0 |
107 | 107 |
|
108 | 108 | # instantiate and save references to lookup function |
| 109 | + geoip_dir = os.path.join(os.environ['DATAPATH'], "GeoIP") |
109 | 110 | try: |
110 | | - self.geoccdb = [pygeoip.GeoIP(os.environ[ |
111 | | - 'DATAPATH'] + '/GeoIP/GeoIP.dat', pygeoip.MEMORY_CACHE).country_code_by_addr] |
112 | | - try: |
113 | | - self.geoccdb.append(pygeoip.GeoIP(os.environ[ |
114 | | - 'DATAPATH'] + '/GeoIP/GeoIPv6.dat', pygeoip.MEMORY_CACHE).country_code_by_addr) |
115 | | - except: |
116 | | - pass |
| 111 | + self.geoccdb = geoip2.database.Reader( |
| 112 | + os.path.join(geoip_dir, "GeoLite2-Country.mmdb") |
| 113 | + ).country |
117 | 114 | except: |
118 | 115 | self.geoccdb = None |
119 | 116 |
|
120 | 117 | try: |
121 | | - self.geoasndb = [pygeoip.GeoIP( |
122 | | - os.environ['DATAPATH'] + '/GeoIP/GeoIPASNum.dat', pygeoip.MEMORY_CACHE).org_by_addr] |
123 | | - try: |
124 | | - self.geoasndb.append(pygeoip.GeoIP(os.environ[ |
125 | | - 'DATAPATH'] + '/GeoIP/GeoIPASNumv6.dat', pygeoip.MEMORY_CACHE).org_by_addr) |
126 | | - except: |
127 | | - pass |
| 118 | + self.geoasndb = geoip2.database.Reader( |
| 119 | + os.path.join(geoip_dir, "GeoLite2-ASN.mmdb") |
| 120 | + ).asn |
128 | 121 | except: |
129 | 122 | self.geoasndb = None |
130 | 123 |
|
@@ -250,41 +243,48 @@ class members will be updated from value''' |
250 | 243 | if self.name in options: |
251 | 244 | self.parseOptions(options[self.name]) |
252 | 245 |
|
253 | | - def getGeoIP(self, ip, db=[], notfound='--'): |
| 246 | + def getGeoIP(self, ip, db=None, notfound='--'): |
254 | 247 | """ |
255 | | - Get record associated with an IP |
256 | | - requires GeoIP |
| 248 | + Get country code associated with an IP. |
| 249 | + Requires GeoIP library (geoip2) and data files. |
257 | 250 | """ |
258 | | - o = None |
259 | | - if db == []: |
260 | | - db = self.geoccdb # default to self.geoccdb |
261 | | - for d in db: |
262 | | - try: |
263 | | - o = d(ip) |
264 | | - except: |
265 | | - # traceback.print_exc() # removed by bg on 20121203 |
266 | | - continue # passing ipv6 address to ipv4 lookup or v/v |
267 | | - if o: |
268 | | - return o # stop when we get a result |
269 | | - return notfound |
270 | | - |
271 | | - def getASN(self, ip, db=[], notfound='--'): |
| 251 | + if not db: |
| 252 | + db = self.geoccdb |
| 253 | + try: |
| 254 | + # Get country code based on order of importance |
| 255 | + # 1st: Country that owns an IP address registered in another |
| 256 | + # location (e.g. military bases in foreign countries) |
| 257 | + # 2nd: Country in which the IP address is registered |
| 258 | + # 3rd: Physical country where IP address is located |
| 259 | + # https://dev.maxmind.com/geoip/geoip2/whats-new-in-geoip2/#Country_Registered_Country_and_Represented_Country |
| 260 | + location = db(ip) |
| 261 | + country = ( |
| 262 | + location.represented_country.iso_code or |
| 263 | + location.registered_country.iso_code or |
| 264 | + location.country.iso_code or |
| 265 | + notfound |
| 266 | + ) |
| 267 | + return country |
| 268 | + except Exception: |
| 269 | + # Many expected exceptions can occur here. Ignore them all and |
| 270 | + # return default value. |
| 271 | + return notfound |
| 272 | + |
| 273 | + def getASN(self, ip, db=None, notfound='--'): |
272 | 274 | """ |
273 | | - Get record associated with an IP |
274 | | - requires GeoIP |
| 275 | + Get ASN associated with an IP. |
| 276 | + Requires GeoIP library (geoip2) and data files. |
275 | 277 | """ |
276 | | - o = None |
277 | | - if db == []: |
278 | | - db = self.geoasndb # default to self.geoccdb |
279 | | - for d in db: |
280 | | - try: |
281 | | - o = d(ip) |
282 | | - except: |
283 | | - # traceback.print_exc() # removed by bg on 20121203 |
284 | | - continue # passing ipv6 address to ipv4 lookup or v/v |
285 | | - if o: |
286 | | - return o # stop when we get a result |
287 | | - return notfound |
| 278 | + if not db: |
| 279 | + db = self.geoasndb |
| 280 | + try: |
| 281 | + template = "AS{0.autonomous_system_number} {0.autonomous_system_organization}" |
| 282 | + asn = template.format( db(ip) ) |
| 283 | + return asn |
| 284 | + except Exception: |
| 285 | + # Many expected exceptions can occur here. Ignore them all and |
| 286 | + # return default value. |
| 287 | + return notfound |
288 | 288 |
|
289 | 289 | def close(self, conn, ts=None): |
290 | 290 | '''for connection based decoders |
@@ -851,9 +851,9 @@ def __init__(self, decoder, addr, ts=None, pkt=None, **kwargs): |
851 | 851 | # cache |
852 | 852 | try: |
853 | 853 | self.info(sipcc=decoder.getGeoIP(self.sip, db=decoder.geoccdb), |
854 | | - sipasn=decoder.getGeoIP(self.sip, db=decoder.geoasndb), |
| 854 | + sipasn=decoder.getASN(self.sip, db=decoder.geoasndb), |
855 | 855 | dipcc=decoder.getGeoIP(self.dip, db=decoder.geoccdb), |
856 | | - dipasn=decoder.getGeoIP(self.dip, db=decoder.geoasndb)) |
| 856 | + dipasn=decoder.getASN(self.dip, db=decoder.geoasndb)) |
857 | 857 | except: |
858 | 858 | self.sipcc, self.sipasn, self.dipcc, self.dipasn = None, None, None, None |
859 | 859 |
|
|
0 commit comments