Source code for server.iptools

"""
Tools related to IP operations, mainly getting IP's and checking if servers exist at a certain IP:port combination.
"""
import netifaces

__author__ = 'Curtis West'
__copyright__ = 'Copyright 2017, Curtis West'
__version__ = '3.0'
__maintainer__ = 'Curtis West'
__email__ = 'curtis@curtiswest.net'
__status__ = 'Development'


[docs]class IPTools(object): """ Static methods that work on IPv4-based connections, such as getting current IP, gateway IP, etc. """ @staticmethod
[docs] def current_ips(): # type: () -> [str] """ Gets the best-candidate IPs of this computer on the network. """ candidates = [] gateway = None for interface in netifaces.interfaces(): try: candidates.append(netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']) gateway = IPTools.gateway_ip() except (KeyError, IndexError): pass if gateway: gateway_subnet = IPTools.get_first_digits_from(gateway, 1) if any(c.startswith(gateway_subnet) for c in candidates): candidates = (c for c in candidates if c.startswith(gateway_subnet)) elif any(not c.startswith('127') for c in candidates): candidates = (c for c in candidates if not c.startswith('127')) # Remove any localhost 127.x.x.x IPs return list(candidates)
@staticmethod
[docs] def gateway_ip(): # type: () -> str """ Gets the IP of this computer's gateway, if it exists. """ try: return str(netifaces.gateways()['default'][netifaces.AF_INET][0]) except (KeyError, IndexError): return None
@staticmethod
[docs] def get_first_digits_from(ip, num_digits, with_dot=True): # type: (str, int, bool) -> str """ Gets the given sets of digits from an IP, with or without the trailing period. :note: if ``num_digits`` exceeds 4, the ``ip`` is returned unchanged. :param ip: the IP address string to trim :param num_digits: the number of digit sets to keep :param with_dot: True to keep the trailing period, False to not """ if num_digits > 4: return ip return ".".join(ip.split('.')[0:num_digits]) + ('.' if with_dot else '')
@staticmethod
[docs] def get_subnet_from(ip, with_dot=True): # type: (str, bool) -> str """ Gets the first 3 sets of digits from an IP, with or without the trailing period. :param ip: the IP address string to trim :param with_dot: True to keep the trailing period, False to not """ if len(ip.split('.')) < 4: return ip if ip[-1] == '.' and with_dot else ip[0:-1] return ".".join(ip.split('.')[0:3]) + ('.' if with_dot else '')