From f09255b0d71745b34e7041ba73de228c6763e8ce Mon Sep 17 00:00:00 2001 From: xHire Date: Sat, 22 Nov 2008 21:35:24 +0100 Subject: [PATCH] Basic sceleton Configuration file Resolver listens and receives but not replies yet Pure class of the Wrapper just to be --- README | 21 ++++++++++++ TODO | 34 ++++++++++++++++++++ conf/wrapsix.conf | 10 ++++++ lib/resolver.rb | 82 +++++++++++++++++++++++++++++++++++++++++++++++ lib/wrapper.rb | 20 ++++++++++++ wrapsix.rb | 65 +++++++++++++++++++++++++++++++++++++ 6 files changed, 232 insertions(+) create mode 100644 README create mode 100644 TODO create mode 100644 conf/wrapsix.conf create mode 100644 lib/resolver.rb create mode 100644 lib/wrapper.rb create mode 100755 wrapsix.rb diff --git a/README b/README new file mode 100644 index 0000000..7f3f744 --- /dev/null +++ b/README @@ -0,0 +1,21 @@ +##### +## WrapSix readme +#### +# Author: Michal Zima, 2008 +# E-mail: xhire@tuxportal.cz +##### + +== About == +WrapSix is a revolutionary piece of software that make possible to reach IPv4-only servers from IPv6-only networks. It stands as a wrapper of faked IPv6 addresses to real IPv4 addresses. + +== Requirements == +WrapSix is very simple to use. You only need: +* GNU/Linux system +* Ruby (I've tested version 1.8.7) + +== Configuration == + +== Running == + +== Getting help == +You can visit official WrapSix IRC channel #wrapsix on server irc.tuxportal.cz. Thank you for feedback. diff --git a/TODO b/TODO new file mode 100644 index 0000000..0d9239f --- /dev/null +++ b/TODO @@ -0,0 +1,34 @@ +##### +## WrapSix ToDo +##### + +== First stage == +* basic skeleton +* configuration +* purely mediate function of DNS resolver -> implement it's protocol +( write some test scripts ) + +== Second stage == +- stay as a DNS wrapping resolver - create faked AAAA entries instead of A + (only if AAAA is required) +- running with arguments + +== Third stage == +- listen on all ports & all set IPv6 addresses +- wrap all connections to IPv4-in-IPv6 addresses + +== ... == + +== Final stage == +- choose a licence ;c) +- test a lot +- revise documentation +- create a package with some simple installator + +== Optional stage == +- implement cache for DNS +- create man pages +- create some home web page (may be a wiki?) + +== PostFinal stage == +- rewrite to C :c) diff --git a/conf/wrapsix.conf b/conf/wrapsix.conf new file mode 100644 index 0000000..f6d9e5e --- /dev/null +++ b/conf/wrapsix.conf @@ -0,0 +1,10 @@ +### Configuration of Resolver +resolver: 1 +resolver_ip: '::1' +secondary_resolver: 10.0.0.139 # if not set => /etc/resolv.conf + +### Configuration of Wrapper +wrapper: 0 + +### Others +debug: 1 diff --git a/lib/resolver.rb b/lib/resolver.rb new file mode 100644 index 0000000..10a3154 --- /dev/null +++ b/lib/resolver.rb @@ -0,0 +1,82 @@ +##### +## WrapSix +### +#> lib/resolver.rb +#~ WrapSix Resolver +#### +# Author: Michal Zima, 2008 +# E-mail: xhire@tuxportal.cz +##### + +### Include all necessary libraries +require 'resolv' + +class Resolver + def initialize + @debug = $config['debug'] + end + + def start + @resolver = UDPSocket.open Socket::AF_INET6 + if @resolver.bind $config['resolver_ip'], 53 + p "Started DNS resolver on IPv6 address #{$config['resolver_ip']}" if @debug + else + p "DNS resolver not started!" if @debug + end + + # just for now + #@hosts = [ + #{:name => "example.com", :type => "A", :data => "192.168.0.1"} + #] + + loop do + # Receive and parse query + data = @resolver.recvfrom 2048 + p "Client: #{data[1].join(' ')}" if @debug + + query = Resolv::DNS::Message::decode data[0] + print "Whole query: " if @debug + p query if @debug + + # Setup an answer + answer = Resolv::DNS::Message::new query.id + answer.qr = 1 # 0 = Query, 1 = Response + answer.opcode = query.opcode # Type of Query; copy from query + answer.aa = 0 # Is this an authoritative response: 0 = No, 1 = Yes + answer.rd = query.rd # Is Recursion Desired, copied from query + answer.ra = 1 # Does name server support recursion: 0 = No, 1 = Yes + answer.rcode = 0 # Response code: 0 = No errors + + query.each_question do |question, typeclass| # There may be multiple questions per query + name = question.to_s # The domain name looked for in the query. + p "Looking for: #{name}" if @debug + record_type = typeclass.name.split("::").last # For example "A", "MX" + p "RR: #{typeclass}" if @debug + p "RR: #{record_type}" if @debug + + # So let's look for it :c) (in secondary resolver) + sr = Resolv::DNS::new :nameserver => $config['secondary_resolver'] + sr_data = sr.getresource name, typeclass + sr_answer = sr_data.address # this is acceptable only for A or so + p sr_answer if @debug + + # temporary code + #ttl = 16000 + #ttl = 86400 # 1 day + #record = @hosts.find{|host| host[:name] == name && host[:type] == record_type } + #unless record.nil? + # Setup answer to this question + #answer.add_answer(name + ".",ttl,typeclass.new(record[:data])) + #answer.encode + #end + end + end + + # Send the response + #server.send answer.encode, 0, data[1][2], data[1][1] + end + + def exit + @resolver.close + end +end diff --git a/lib/wrapper.rb b/lib/wrapper.rb new file mode 100644 index 0000000..b7fb9d6 --- /dev/null +++ b/lib/wrapper.rb @@ -0,0 +1,20 @@ +##### +## WrapSix +### +#> lib/wrapper.rb +#~ WrapSix Wrapper +#### +# Author: Michal Zima, 2008 +# E-mail: xhire@tuxportal.cz +##### + +class Wrapper + def initializer + end + + def start + end + + def exit + end +end diff --git a/wrapsix.rb b/wrapsix.rb new file mode 100755 index 0000000..758e6d2 --- /dev/null +++ b/wrapsix.rb @@ -0,0 +1,65 @@ +#!/usr/bin/env ruby +##### +## WrapSix +### +#> wrapsix.rb +#~ Description... +#### +# Author: Michal Zima, 2008 +# E-mail: xhire@tuxportal.cz +##### + +### Hardcoded configuration => configured by system administrator +$config = {} +$config['config_file'] = 'conf/wrapsix.conf' + +#------------------------------------------------------------------------------# + +### Include all necessary libraries +require 'yaml' +require 'socket' +# WrapSix libs +require 'lib/resolver' +require 'lib/wrapper' + +### Parse command line arguments if any + +### Load configuration +configuration = YAML.load_file $config['config_file'] + +## Merge both configs +$config.merge! configuration # FIX: this overwrites those configs from command line! +#p $config + +### Start logging facility (system wide one) + +### Handle some signals +# todo: replace this with right variables +def exit + $resolver.exit if $config['resolver'] + $wrapper.exit if $config['wrapper'] + Process.exit +end + +# TERM -KILL- QUIT INT +trap "INT" do; exit; end +trap "TERM" do; exit; end +trap "QUIT" do; exit; end + +services = [] +### Start DNS resolver function +if $config['resolver'] + $resolver = Resolver.new + services << Thread.start do; $resolver.start; end +end + +### Start IPv6-to-IPv4 wrapper +if $config['wrapper'] + $wrapper = Wrapper.new + services << Thread.start do; $wrapper.start; end +end + +### Start WrapSix +# in best conditions it would *never* stop +services.each do |srvc| srvc.join end +