77from re import findall
88from threading import Thread
99
10+ import netifaces
1011from uuid import UUID
1112import tldextract
1213import validators
1920import sys
2021import ipaddress
2122import aid_hash
22- from typing import (
23- Any ,
24- Optional ,
25- Union ,
26- List ,
27- )
23+ from typing import Any , Optional , Union , List , Dict
2824from ipaddress import IPv4Network , IPv6Network , IPv4Address , IPv6Address
2925from dataclasses import is_dataclass , asdict
3026from enum import Enum
@@ -405,26 +401,41 @@ def to_delta(self, time_in_seconds):
405401 def get_human_readable_datetime (self ) -> str :
406402 return utils .convert_format (datetime .now (), self .alerts_format )
407403
408- def get_own_ips (self ) -> list :
404+ def get_own_ips (self , ret = Dict ) -> Union [ Dict [ str , List [ str ]], List [ str ]] :
409405 """
410- Returns a list of our local and public IPs
406+ Returns a dict of our private and public IPs
407+ return a dict by default
408+ e.g. { "ipv4": [..], "ipv6": [..] }
409+ and returns a list of all the ips combined if ret=List is given
411410 """
412- if "-i" not in sys .argv :
411+ if "-i" not in sys .argv and "-g" not in sys . argv :
413412 # this method is only valid when running on an interface
414413 return []
415414
416- IPs = []
417- s = socket .socket (socket .AF_INET , socket .SOCK_DGRAM )
418- try :
419- s .connect (("10.255.255.255" , 1 ))
420- IPs .append (s .getsockname ()[0 ])
421- except Exception :
422- IPs .append ("127.0.0.1" )
423- finally :
424- s .close ()
415+ ips = {"ipv4" : [], "ipv6" : []}
425416
426- # get public ip
417+ interfaces = netifaces .interfaces ()
418+
419+ for interface in interfaces :
420+ try :
421+ addrs = netifaces .ifaddresses (interface )
427422
423+ # get IPv4 addresses
424+ if netifaces .AF_INET in addrs :
425+ for addr in addrs [netifaces .AF_INET ]:
426+ ips ["ipv4" ].append (addr ["addr" ])
427+
428+ # get IPv6 addresses
429+ if netifaces .AF_INET6 in addrs :
430+ for addr in addrs [netifaces .AF_INET6 ]:
431+ # remove interface suffix
432+ ip = addr ["addr" ].split ("%" )[0 ]
433+ ips ["ipv6" ].append (ip )
434+
435+ except Exception as e :
436+ print (f"Error processing interface { interface } : { e } " )
437+
438+ # get public ip
428439 try :
429440 response = requests .get (
430441 "http://ipinfo.io/json" ,
@@ -435,19 +446,27 @@ def get_own_ips(self) -> list:
435446 requests .exceptions .ChunkedEncodingError ,
436447 requests .exceptions .ReadTimeout ,
437448 ):
438- return IPs
449+ return ips
439450
440451 if response .status_code != 200 :
441- return IPs
452+ return ips
442453 if "Connection timed out" in response .text :
443- return IPs
454+ return ips
444455 try :
445456 response = json .loads (response .text )
446457 except json .decoder .JSONDecodeError :
447- return IPs
458+ return ips
459+
448460 public_ip = response ["ip" ]
449- IPs .append (public_ip )
450- return IPs
461+ if validators .ipv4 (public_ip ):
462+ ips ["ipv4" ].append (public_ip )
463+ elif validators .ipv6 (public_ip ):
464+ ips ["ipv6" ].append (public_ip )
465+
466+ if ret == Dict :
467+ return ips
468+ elif ret == List :
469+ return [ip for sublist in ips .values () for ip in sublist ]
451470
452471 def convert_to_mb (self , bytes ):
453472 return int (bytes ) / (10 ** 6 )
0 commit comments