예제 #1
0
 def get_ip(self, log, options):
     """Implement AddressPlugin.get_ip()."""
     opts = dict_of_opts(options)
     if 'if' not in opts:
         raise AddressError('Required option if= missing, giving up.')
     if_ = opts['if']
     address = IpAddr()
     output = subprocess.getoutput('ip address show dev ' + if_)
     address.parse_ifconfig_output(output)
     return address
예제 #2
0
 def get_ip(self, log, options):
     """Implement AddressPlugin.get_ip()."""
     addr = IpAddr()
     opts = dict_of_opts(options)
     if 'ip' not in opts and 'ip6' not in opts:
         raise AddressError('Required option ip= or ip6= missing, giving up.')
     if 'ip' in opts:
         addr.v4 = opts['ip']
     if 'ip6' in opts:
         addr.v6 = opts['ip6']
     return addr
예제 #3
0
    def get_ip(self, log: Logger, options: [str]) -> Optional[IpAddr]:
        """Implements AddressPlugin.get_ip()."""
        urls = [DeDnshomeAddressURL.IP4, DeDnshomeAddressURL.IP6]
        ip = IpAddr(None, None)

        for url in urls:
            result = DeDnshomeWebPlugin.load_ip(log, url.value)
            if result:
                if not ip.v4 and result.v4:
                    ip.v4 = result.v4
                if not ip.v6 and result.v6:
                    ip.v6 = result.v6
        log.debug("Returning ip: " + str(ip))
        return ip if not ip.empty() else None
예제 #4
0
    def get_ip(self, log, options):
        """Implement AddressPlugin.get_ip()."""
        def check_url(url):
            """Get reply from host and decode."""
            log.debug('trying ' + url)
            try:
                with urllib.request.urlopen(url) as response:
                    if response.getcode() != 200:
                        log.debug("Bad response at %s (ignored)" % url)
                        return None
                    html = response.read().decode('ascii')
            except (urllib.error.HTTPError, urllib.error.URLError) as err:
                raise AddressError("Error reading %s :%s" % (url, err))
            log.debug("Got response: %s", html)
            pat = re.compile(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
            match = pat.search(html)
            if match:
                return html[match.start():match.end()]
            log.debug("Cannot parse address reply")
            return None

        for ix, url in enumerate(_URLS):
            ip = check_url(url)
            if ip:
                return IpAddr(ip)
            if ix + 1 < len(_URLS):
                log.info("Falling back to %s", _URLS[ix + 1])
        raise AddressError("Cannot obtain ip address (%s, %s and %s tried)" %
                           tuple(_URLS))
예제 #5
0
 def get_ip(self, log, options):
     """
     Get default interface using ip route and address using ifconfig.
     """
     if_ = None
     for line in subprocess.getoutput('ip route').split('\n'):
         words = line.split()
         if words[0] == 'default':
             if_ = self.find_device(words)
             break
     if if_ is None:
         raise AddressError("Cannot find default interface, giving up")
     address = IpAddr()
     output = subprocess.getoutput('ip address show dev ' + if_)
     address.parse_ifconfig_output(output)
     return address
예제 #6
0
    def get_ip(self, log, options):
        """Implement AddressPlugin.get_ip()."""
        def check_url(url):
            """Get reply from host and decode."""
            log.debug('trying ' + url)
            try:
                with urllib.request.urlopen(url, None, TIMEOUT) as response:
                    if response.getcode() != 200:
                        log.debug("Bad response at %s (ignored)" % url)
                        return None
                    html = response.read().decode()
            except urllib.error.URLError as err:
                log.debug("Got URLError: %s", err)
                return None
            log.debug("Got response: %s", html)
            pat = re.compile(r'[:0-9a-f]{12,}(\s|\Z)')
            match = pat.search(html)
            if match:
                return html[match.start():match.end()]
            log.debug("Cannot parse ipv6 address reply")
            return None

        urls = [
            'https://now-dns.com/ip', 'http://ipv6.whatismyip.akamai.com',
            'https://ifcfg.me/'
        ]
        for ix, url in enumerate(urls):
            log.info('Trying: %s', url)
            ip = check_url(url)
            if ip:
                return IpAddr(None, ip)
            if ix + 1 < len(urls):
                log.info("Falling back to %s", urls[ix + 1])
        raise AddressError("Cannot obtain ip6 address (%s, %s and %s tried)" %
                           tuple(urls))
예제 #7
0
 def get_ip(self, log, options):
     """Implement AddressPlugin.get_ip()."""
     opts = dict_of_opts(options)
     if 'cmd' not in opts:
         raise AddressError('Required option cmd= missing, giving up.')
     cmd = opts['cmd']
     log.debug('Running: %s', cmd)
     addr = IpAddr()
     result = subprocess.getoutput(cmd).strip()
     log.debug('result: %s', result)
     pat = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
     pat6 = re.compile(r'[:0-9a-f]{12,}(\s|\Z)')
     for word in result.split():
         if pat.fullmatch(word):
             addr.v4 = word
         elif pat6.fullmatch(word):
             addr.v6 = word
         else:
             raise AddressError('Cannot parse command output: ' + result)
     return addr
예제 #8
0
    def extract_ip(data: AnyStr) -> IpAddr:
        """Extracts the IPs from data
        Expects `data` to be an UTF-8 string holding either an single IPv4 or an IPv6 address.

        Args:
            data: Data to extract the IP from

        Returns:
            An `IpAddr` which may hold the IPv4 or IPv6 Address found.
        """

        try:
            ip = ipaddress.ip_address(data.strip())

            if isinstance(ip, ipaddress.IPv4Address):
                return IpAddr(ip.exploded, None)
            if isinstance(ip, ipaddress.IPv6Address):
                return IpAddr(None, ip.exploded)

        except ValueError:
            return IpAddr(None, None)
예제 #9
0
def ip_cache_data(opts, log, default=(IpAddr(ipv4="0.0.0.0"), 100000)):
    """
    Return an (address, cache age in minute) tuple.

    If not existing, the default value is returned.
    """
    path = ip_cache_setup(opts)
    if not os.path.exists(path):
        return default
    mtime = os.stat(path)[stat.ST_MTIME]
    now = time.time()
    delta = math.floor((now - mtime) / 60)
    with open(path) as f:
        astr = f.read().strip()
    try:
        ll = ast.literal_eval(astr)
        ip = IpAddr(ipv4=ll[0], ipv6=ll[1])
    except SyntaxError:
        log.debug("SyntaxError while reading ip cache.")
        ip_cache_clear(opts, log)
        ip, delta = default
    return ip, delta
예제 #10
0
    def get_ip(self, log, options):
        """Implement AddressPlugin.get_ip()."""
        # Documentation refers to testing on 3.4
        # f-strings are from 3.6 and exception chaining from 3.9
        # pylint: disable=raise-missing-from
        log.debug("trying " + _URL)
        try:
            with urllib.request.urlopen(_URL) as response:
                if response.getcode() != 200:
                    raise AddressError("Bad response %s from %s" %
                                       (response.getcode(), _URL))
                status = json.loads(response.read().decode("utf-8"))
        except (urllib.error.HTTPError, urllib.error.URLError) as err:
            raise AddressError("Error reading %s :%s" % (_URL, err))
        log.debug("Got response: %s", json.dumps(status))

        log.debug("WAN online: %s", status["wan"]["online"])

        return IpAddr(status["wan"]["localIpAddress"])
예제 #11
0
def ip_cache_set(opts, ip):
    """Set the cached address to IpAddr ip."""
    path = ip_cache_setup(opts)
    ip = ip if ip else IpAddr(ipv4="0.0.0.0")
    with open(path, "w") as f:
        f.write(str(ip))
예제 #12
0
 def get_ip(self, log, options):
     """Implement AddressPlugin.get_ip()."""
     return IpAddr()