def to_address(name): """Convert a reverse map domain name into textual address form. @param name: an IPv4 or IPv6 address in reverse-map form. @type name: name.Name object @rtype: str """ if name.is_subdomain(ipv4_reverse_domain): name = name.relativize(ipv4_reverse_domain) labels = list(name.labels) labels.reverse() text = '.'.join(labels) # run through inet_aton() to check syntax and make pretty. return ipv4.inet_ntoa(ipv4.inet_aton(text)) elif name.is_subdomain(ipv6_reverse_domain): name = name.relativize(ipv6_reverse_domain) labels = list(name.labels) labels.reverse() parts = [] i = 0 l = len(labels) while i < l: parts.append(''.join(labels[i:i+4])) i += 4 text = ':'.join(parts) # run through inet_aton() to check syntax and make pretty. return ipv6.inet_ntoa(ipv6.inet_aton(text)) else: raise exception.SyntaxError('unknown reverse-map address family')
def _validate_name(self, name): if isinstance(name, (str, unicode)): name = name.from_text(name, None) elif not isinstance(name, name.Name): raise KeyError("name parameter must be convertable to a DNS name") if name.is_absolute(): if not name.is_subdomain(self.origin): raise KeyError("name parameter must be a subdomain of the zone origin") if self.relativize: name = name.relativize(self.origin) return name
def _validate_name(self, name): if isinstance(name, (str, unicode)): name = name.from_text(name, None) elif not isinstance(name, name.Name): raise KeyError("name parameter must be convertable to a DNS name") if name.is_absolute(): if not name.is_subdomain(self.origin): raise KeyError( "name parameter must be a subdomain of the zone origin") if self.relativize: name = name.relativize(self.origin) return name
def to_e164(name, origin=public_enum_domain, want_plus_prefix=True): """Convert an ENUM domain name into an E.164 number. @param name: the ENUM domain name. @type name: name.Name object. @param origin: A domain containing the ENUM domain name. The name is relativized to this domain before being converted to text. @type origin: name.Name object or None @param want_plus_prefix: if True, add a '+' to the beginning of the returned number. @rtype: str """ if not origin is None: name = name.relativize(origin) dlabels = [d for d in name.labels if (d.isdigit() and len(d) == 1)] if len(dlabels) != len(name.labels): raise exception.SyntaxError('non-digit labels in ENUM domain name') dlabels.reverse() text = ''.join(dlabels) if want_plus_prefix: text = '+' + text return text
def _generate_line(self): # range lhs [ttl] [class] type rhs [ comment ] """Process one line containing the GENERATE statement from a DNS master file.""" if self.current_origin is None: raise UnknownOrigin token = self.tok.get() # Range (required) try: start, stop, step = grange.from_text(token.value) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except: raise exception.SyntaxError # lhs (required) try: lhs = token.value token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except: raise exception.SyntaxError # TTL try: ttl = ttl.from_text(token.value) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except ttl.BadTTL: ttl = self.ttl # Class try: rdclass = rdataclass.from_text(token.value) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except exception.SyntaxError: raise exception.SyntaxError except: rdclass = self.zone.rdclass if rdclass != self.zone.rdclass: raise exception.SyntaxError("RR class is not zone's class") # Type try: rdtype = rdatatype.from_text(token.value) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except: raise exception.SyntaxError("unknown rdatatype '%s'" % token.value) # lhs (required) try: rhs = token.value except: raise exception.SyntaxError lmod, lsign, loffset, lwidth, lbase = self._parse_modify(lhs) rmod, rsign, roffset, rwidth, rbase = self._parse_modify(rhs) for i in range(start, stop + 1, step): # +1 because bind is inclusive and python is exclusive if lsign == '+': lindex = i + int(loffset) elif lsign == '-': lindex = i - int(loffset) if rsign == '-': rindex = i - int(roffset) elif rsign == '+': rindex = i + int(roffset) lzfindex = str(lindex).zfill(int(lwidth)) rzfindex = str(rindex).zfill(int(rwidth)) name = lhs.replace('$%s' % (lmod), lzfindex) rdata = rhs.replace('$%s' % (rmod), rzfindex) self.last_name = name.from_text(name, self.current_origin) name = self.last_name if not name.is_subdomain(self.zone.origin): self._eat_line() return if self.relativize: name = name.relativize(self.zone.origin) n = self.zone.nodes.get(name) if n is None: n = self.zone.node_factory() self.zone.nodes[name] = n try: rd = rdata.from_text(rdclass, rdtype, rdata, self.current_origin, False) except exception.SyntaxError: # Catch and reraise. (ty, va) = sys.exc_info()[:2] raise va except: # All exceptions that occur in the processing of rdata # are treated as syntax errors. This is not strictly # correct, but it is correct almost all of the time. # We convert them to syntax errors so that we can emit # helpful filename:line info. (ty, va) = sys.exc_info()[:2] raise exception.SyntaxError("caught exception %s: %s" % (str(ty), str(va))) rd.choose_relativity(self.zone.origin, self.relativize) covers = rd.covers() rds = n.find_rdataset(rdclass, rdtype, covers, True) rds.add(rd, ttl)
def _rr_line(self): """Process one line from a DNS master file.""" # Name if self.current_origin is None: raise UnknownOrigin token = self.tok.get(want_leading=True) if not token.is_whitespace(): self.last_name = name.from_text(token.value, self.current_origin) else: token = self.tok.get() if token.is_eol_or_eof(): # treat leading WS followed by EOL/EOF as if they were EOL/EOF. return self.tok.unget(token) name = self.last_name if not name.is_subdomain(self.zone.origin): self._eat_line() return if self.relativize: name = name.relativize(self.zone.origin) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError # TTL try: ttl = ttl.from_text(token.value) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except ttl.BadTTL: ttl = self.ttl # Class try: rdclass = rdataclass.from_text(token.value) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except exception.SyntaxError: raise exception.SyntaxError except: rdclass = self.zone.rdclass if rdclass != self.zone.rdclass: raise exception.SyntaxError("RR class is not zone's class") # Type try: rdtype = rdatatype.from_text(token.value) except: raise exception.SyntaxError("unknown rdatatype '%s'" % token.value) n = self.zone.nodes.get(name) if n is None: n = self.zone.node_factory() self.zone.nodes[name] = n try: rd = rdata.from_text(rdclass, rdtype, self.tok, self.current_origin, False) except exception.SyntaxError: # Catch and reraise. (ty, va) = sys.exc_info()[:2] raise va except: # All exceptions that occur in the processing of rdata # are treated as syntax errors. This is not strictly # correct, but it is correct almost all of the time. # We convert them to syntax errors so that we can emit # helpful filename:line info. (ty, va) = sys.exc_info()[:2] raise exception.SyntaxError("caught exception %s: %s" % (str(ty), str(va))) rd.choose_relativity(self.zone.origin, self.relativize) covers = rd.covers() rds = n.find_rdataset(rdclass, rdtype, covers, True) rds.add(rd, ttl)
def _rr_line(self): """Process one line from a DNS master file.""" # Name if self.current_origin is None: raise UnknownOrigin token = self.tok.get(want_leading = True) if not token.is_whitespace(): self.last_name = name.from_text(token.value, self.current_origin) else: token = self.tok.get() if token.is_eol_or_eof(): # treat leading WS followed by EOL/EOF as if they were EOL/EOF. return self.tok.unget(token) name = self.last_name if not name.is_subdomain(self.zone.origin): self._eat_line() return if self.relativize: name = name.relativize(self.zone.origin) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError # TTL try: ttl = ttl.from_text(token.value) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except ttl.BadTTL: ttl = self.ttl # Class try: rdclass = rdataclass.from_text(token.value) token = self.tok.get() if not token.is_identifier(): raise exception.SyntaxError except exception.SyntaxError: raise exception.SyntaxError except: rdclass = self.zone.rdclass if rdclass != self.zone.rdclass: raise exception.SyntaxError("RR class is not zone's class") # Type try: rdtype = rdatatype.from_text(token.value) except: raise exception.SyntaxError("unknown rdatatype '%s'" % token.value) n = self.zone.nodes.get(name) if n is None: n = self.zone.node_factory() self.zone.nodes[name] = n try: rd = rdata.from_text(rdclass, rdtype, self.tok, self.current_origin, False) except exception.SyntaxError: # Catch and reraise. (ty, va) = sys.exc_info()[:2] raise va except: # All exceptions that occur in the processing of rdata # are treated as syntax errors. This is not strictly # correct, but it is correct almost all of the time. # We convert them to syntax errors so that we can emit # helpful filename:line info. (ty, va) = sys.exc_info()[:2] raise exception.SyntaxError("caught exception %s: %s" % (str(ty), str(va))) rd.choose_relativity(self.zone.origin, self.relativize) covers = rd.covers() rds = n.find_rdataset(rdclass, rdtype, covers, True) rds.add(rd, ttl)