# HG changeset patch # User Alessio Caiazza # Date 1251456361 -7200 # Node ID e73de8203b16bdb5248010418e9bba0e05a59b8b # Parent 0000000000000000000000000000000000000000 initial import diff -r 0000000000000000000000000000000000000000 -r e73de8203b16bdb5248010418e9bba0e05a59b8b dns_gen.rb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dns_gen.rb Fri Aug 28 12:46:01 2009 +0200 @@ -0,0 +1,145 @@ +#!/usr/bin/env ruby + +## dns_gen.rb - BIND record generator (AAAA and PTR) for IPv6 +## Copyright (C) 2009 Alessio Caiazza +## +## This program is free software: you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . + + +IPV6_LEN = 39 + +# +# Classe per la gestione degli indirizzi IPv6 +# implementa i Range +# +class V6Addr + include Comparable + attr :addr + attr :comp_addr + + def initialize(addr) + @comp_addr = addr + @addr = expand + end + + # + # genera l'indirizzo successivo (implementazione Range) + # + def succ + splitted = @addr.split(':') + next_addr = '' + 1.upto(8) do |i| + fourNibble = (splitted[-i].to_i(16)+1).to_s(16) + if fourNibble.length <= 4 + 0.upto(8-i-1) { |j| next_addr << splitted[j]+':' } + next_addr << fourNibble + (i-1).times { next_addr << ':0000' } + return V6Addr.new(next_addr) + end + end + V6Addr.new('::0') + end + + # + # confronta due indirizzi (implementazione Range) + # + def <=>(other) + @addr <=> other.addr + end + def to_s + sprintf "%s #{inspect}", @addr + end + + # + # genera una stringa compatibile con un hostname + # + def addr_to_host(domain_pre) + splitted = @addr.split(':') + host = domain_pre.dup + 4.upto(7) { |i| host << '-'+splitted[i].to_i(16).to_s(16)} + host + end + def expand + V6Addr.expand_ipv6(@comp_addr) + end + + # + # Espande un indirizzo ipv6 dalla forma contratta alla forma estesa + # + def self.expand_ipv6(ip) + low, high = ip.split("::") + expanded = low.split(":").map{ |i| "0"*(4-i.length)+i}.join(":") + unless high.nil? + high = ":"+high.split(":").map{ |i| "0"*(4-i.length)+i}.join(":") + padding = (IPV6_LEN - (expanded+high).length) / 5 + expanded = expanded + ":0000"*padding + high + end + + return expanded + end +end + +# +# Genera i record AAAA per il range di indirizzi IPv6 +# fornito. +# domain_pref viene messo come prefisso al nome di dominio +# generato a partire dall'interface ID dell'indirizzo +# se self_domain รจ true appende al record il nome di +# dominio completo. +# +def gen_forward(range, domain, domain_pref, self_domain) + puts "; HOSTS " + range.each do |addr| + puts "#{addr.addr_to_host(domain_pref)}#{self_domain ? '' : '.'+domain+'.'}\t4800 IN AAAA #{addr.addr}" + end +end + +# +# Genera i record PTR per il range di indirizzi IPv6 +# fornito. +# I parametri domain e domain_pref hanno lo stesso significato +# descritto nel metodo +# gen_forward(range, domain, domain_pref, self_domain) +# +def gen_reverse(range, domain, domain_pref) + ip6_arpa = range.first.addr.delete(':')[0..15].reverse.split(/s*/).join('.')+'.ip6.arpa.' + puts "; REVERSE " + puts "$ORIGIN #{ip6_arpa}" + range.each do |addr| + reverse = addr.addr.delete(':')[16..-1].reverse.split(/s*/).join('.') + puts "#{reverse} IN PTR #{addr.addr_to_host(domain_pref)}.#{domain}." + end +end + +def main() + if ARGV.length < 4 + puts "Wrong parameters!\nUsage:" + puts "#{$0} 2001:db8:bear::cafe 2001:db8:bear::dead mydomain.com dhcp [--complete]" + puts "Use --complete for appending mydomain.com. on AAAA records." + exit 1 + end + first_host = V6Addr.new(ARGV[0]) + last_host = V6Addr.new(ARGV[1]) + domain=ARGV[2] + domain_pref = ARGV[3] + self_domain = true + if !ARGV[4].nil? && ARGV[4].eql?('--complete') + self_domain = false + end + gen_forward(first_host..last_host, domain, domain_pref, self_domain) + gen_reverse(first_host..last_host, domain, domain_pref) +end + +if __FILE__ == $0 + main() +end \ No newline at end of file