diff --git a/autorev2 b/autorev2 index 13842b9..fc3634b 100755 --- a/autorev2 +++ b/autorev2 @@ -45,7 +45,7 @@ class Rev: self.revzones[zone]['info'] += info #print(f"zoneinfo {zone} - {info}") - def ptr(self, zone, addr, name, vlan = "", noauto = False): + def ptr(self, zone, addr, name, network = "", noauto = False, generate = False, comment = False): self._check_zone(zone) if not (ipbyte := re.match(r"(\d+)\.(\d+)\.(\d+)\.(\d+)", addr)): raise RevInvalidAddress(f"invalid address: {addr} ({name} / rev zone: {zone})") @@ -60,8 +60,10 @@ class Rev: 'addr': addr, 'ptr': ptr, 'name': name, - 'vlan': vlan, - 'noauto': noauto + 'network': network, + 'noauto': noauto, + 'generate': generate, + 'comment': comment } #print(f"{zone} {addr} {ptr}") @@ -78,7 +80,7 @@ class Rev: ptr = [] for ip in sorted(self.revzones[zone]['ptr']): rec = self.revzones[zone]['ptr'][ip] - if rec['noauto']: + if rec['noauto'] or rec['comment']: continue; ptr.append(f"{rec['ptr']}\t\tIN PTR\t{rec['name']}") return other + ptr @@ -87,17 +89,27 @@ class Rev: self._check_zone(zone) other = self.revzones[zone]['other'] wiki = [f"^ {zone} - {self.revzones[zone]['info']} ^^^", - f"^IP cím^név^vlan^"] + f"^IP cím^név^hálózat^"] last_addr = None for ip in sorted(self.revzones[zone]['ptr']): rec = self.revzones[zone]['ptr'][ip] if last_addr and re.sub(r"(\d+)$", lambda r : str(int(r[1])+1), last_addr) != rec['addr']: wiki.append("| |||") - vlan = rec['vlan'] - if rec['noauto']: - vlan = "**M** "+ vlan - wiki.append(f"|{rec['addr']}|{rec['name']}|{vlan}|") last_addr = rec['addr'] + if rec['generate']: + if rec['generate'] == 'first': + gen_first_name = rec['name'] + gen_first_addr = rec['addr'] + continue + elif rec['generate'] == 'middle': + continue + elif rec['generate'] == 'last': + rec['name'] = f"{gen_first_name}\\\\ ...\\\\ {rec['name']}" + rec['addr'] = f"{gen_first_addr}\\\\ ...\\\\ {rec['addr']}" + network = re.sub(r'(v\d+)', '**\\1**', rec['network']) + if rec['noauto']: + network = "**M** "+ network + wiki.append(f"|{rec['addr']}|{rec['name']}|{network}|") return wiki @@ -105,7 +117,8 @@ def read_zone(zonefile, rev): with open(zonefile, 'r') as f: origin = None revzone = None - vlan = "" + network = "" + network_ptrs = False while line := f.readline(): if r := re.match(r"\s*\$ORIGIN\s*(\S*)", line): origin = r[1] @@ -119,7 +132,20 @@ def read_zone(zonefile, rev): exit(1) rev.add_zone(revzone) elif r:= re.match(r"\s*;.*?\[vlan\]\s*(.*)", line): - vlan = r[1] + network = r[1] + network_ptrs = False + print(f"warning: legacy [vlan] in zone file {zonefile}") + elif r:= re.match(r"\s*;.*?\[net(work)?\]\s*(.*)", line): + prev_network = network + network = r[2] + if prev_network and not network_ptrs: + # no ptr records in previous network + if r:= re.match(r"[0-9./]+", network): + try: + rev.ptr(revzone, r[0], f"-", network=network, comment=True) + except: + pass + network_ptrs = False if not revzone or not origin: continue if r := re.match(r"\s*([a-z0-9.-]+)\s+IN\s+A\s+([0-9.]+)(.*)", line, flags=re.I): @@ -127,10 +153,30 @@ def read_zone(zonefile, rev): if re.search(r"\[no_autorev\]", extra): continue try: - rev.ptr(revzone, addr, f"{name}.{origin}", vlan=vlan) + rev.ptr(revzone, addr, f"{name}.{origin}", network=network) + network_ptrs = True except (RevDuplicateAddress, RevInvalidAddress) as e: print(e, file=sys.stderr) exit(1) + elif r := re.match(r"\s*\$GENERATE\s+(\d+)-(\d+)\s+([a-z0-9.$-]+)\s+A\s+([0-9.$]+)", line, flags=re.I): + begin, end, name_pattern, addr_pattern = int(r[1]), int(r[2]), r[3], r[4] + if begin < 0 or begin >= end or end > 255: + raise RevInvalidAddress(f"invalid generate range: {begin}-{end}") + for i in range(begin, end + 1): + name = re.sub(r"\$", str(i), name_pattern) + addr = re.sub(r"\$", str(i), addr_pattern) + if i == begin: + gen = 'first' + elif i == end: + gen = 'last' + else: + gen = 'middle' + try: + rev.ptr(revzone, addr, f"{name}.{origin}", network=network, generate=gen) + network_ptrs = True + except (RevDuplicateAddress, RevInvalidAddress) as e: + print(e, file=sys.stderr) + exit(1) elif r := re.match(r"\s*;\s*\[autorev\]\s*(.*)", line): rev.record(revzone, r[1])