From e1cf5b12e8b8b8c576b1ff516fa9abd6ca86bbe5 Mon Sep 17 00:00:00 2001 From: kimballo Date: Thu, 3 Oct 2019 13:02:09 -0600 Subject: [PATCH] added dns.edns.ECSOption.from_text() --- dns/edns.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/dns/edns.py b/dns/edns.py index 57dd256a..8fe3c616 100644 --- a/dns/edns.py +++ b/dns/edns.py @@ -202,6 +202,57 @@ class ECSOption(Option): def to_text(self): return "ECS {}/{} scope/{}".format(self.address, self.srclen, self.scopelen) + @staticmethod + def from_text(text): + """Convert a string into a `dns.edns.ECSOption` + + :param text: string + :return: `dns.edns.ECSOption` + + Examples: + + >>> import dns.edns + >>> + >>> # basic example + >>> dns.edns.ECSOption.from_text('1.2.3.4/24') + >>> + >>> # also understands scope + >>> dns.edns.ECSOption.from_text('1.2.3.4/24/32') + >>> + >>> # IPv6 + >>> dns.edns.ECSOption.from_text('2001:4b98::1/64/64') + >>> + >>> # it understands results from `dns.edns.ECSOption.to_text()` + >>> dns.edns.ECSOption.from_text('ECS 1.2.3.4/24/32') + """ + optional_prefix = 'ECS' + tokens = text.split() + ecs_text = None + if len(tokens) == 1: + ecs_text = tokens[0] + elif len(tokens) == 2: + if tokens[0] != optional_prefix: + raise ValueError(f'could not parse ECS from "{text}"') + ecs_text = tokens[1] + else: + raise ValueError(f'could not parse ECS from "{text}"') + n_slashes = ecs_text.count('/') + if n_slashes == 1: + address, srclen = ecs_text.split('/') + scope = 0 + elif n_slashes == 2: + address, srclen, scope = ecs_text.split('/') + else: + raise ValueError(f'could not parse ECS from "{text}"') + try: + scope = int(scope) + except ValueError: + raise ValueError(f'invalid scope "{scope}": scope must be an integer') + try: + srclen = int(srclen) + except ValueError: + raise ValueError(f'invalid srclen "{srclen}": srclen must be an integer') + return ECSOption(address, srclen, scope) def to_wire(self, file): file.write(struct.pack('!H', self.family)) -- 2.47.3