[vhffs-dev] [573] Added support for IPv6 AAAA records in DNS.

[ Thread Index | Date Index | More vhffs.org/vhffs-dev Archives ]


Revision: 573
Author:   beuss
Date:     2007-04-18 07:16:07 +0000 (Wed, 18 Apr 2007)

Log Message:
-----------
Added support for IPv6 AAAA records in DNS.

Modified Paths:
--------------
    trunk/vhffs-api/src/Vhffs/Conf.pm
    trunk/vhffs-api/src/Vhffs/Functions.pm
    trunk/vhffs-api/src/Vhffs/Panel/DNS.pm
    trunk/vhffs-api/src/Vhffs/Services/DNS.pm
    trunk/vhffs-backend/conf/vhffs.conf.dist.in
    trunk/vhffs-backend/conf/vhffs.conf.in
    trunk/vhffs-panel/dns/prefs.pl
    trunk/vhffs-panel/templates/Makefile.am
    trunk/vhffs-panel/templates/dns/prefs.tmpl

Added Paths:
-----------
    trunk/vhffs-panel/templates/dns/list_aaaa_sub.tmpl


Modified: trunk/vhffs-api/src/Vhffs/Conf.pm
===================================================================
--- trunk/vhffs-api/src/Vhffs/Conf.pm	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-api/src/Vhffs/Conf.pm	2007-04-18 07:16:07 UTC (rev 573)
@@ -151,6 +151,16 @@
 
 }
 
+sub get_default_aaaa
+{
+	my $self = shift;
+    if( defined $Config{services}{dns}{default_aaaa} ) {
+        return $Config{services}{dns}{default_aaaa};
+    } else {
+        return undef;
+    }
+}
+
 sub get_users
 {
     return $Config{"users"};    

Modified: trunk/vhffs-api/src/Vhffs/Functions.pm
===================================================================
--- trunk/vhffs-api/src/Vhffs/Functions.pm	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-api/src/Vhffs/Functions.pm	2007-04-18 07:16:07 UTC (rev 573)
@@ -458,6 +458,11 @@
     return (defined $ip && $ip =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/);
 }
 
+sub check_ipv6($) {
+    my $ip = shift;
+    return (defined $ip && $ip =~ /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/);
+}
+
 sub rotate_log
 {
 	use File::Basename;

Modified: trunk/vhffs-api/src/Vhffs/Panel/DNS.pm
===================================================================
--- trunk/vhffs-api/src/Vhffs/Panel/DNS.pm	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-api/src/Vhffs/Panel/DNS.pm	2007-04-18 07:16:07 UTC (rev 573)
@@ -226,6 +226,47 @@
     die(gettext('Unknown error')."\n");
 }
 
+sub add_aaaa {
+    my ($dns, $redirect, $name, $ip) = @_;
+    die() unless(defined $dns && defined $redirect && defined $name && defined $ip);
+    my $rval;
+    if($redirect) {
+        $rval = $dns->add_aaaa($name);
+    } else {
+        $rval = $dns->add_aaaa($name, $ip);
+    }
+    return 1 if($rval > 0);
+    die(gettext('Invalid prefix')."\n") if($rval == -1);
+    die(gettext('Prefix already exists')."\n") if($rval == -2);
+    die(gettext('Unable to find default redirection address, please contact administrators')."\n") if($rval == -3);
+    die(gettext('Invalid IP v6 address')."\n") if($rval == -4);
+    die(gettext('Database error')."\n") if($rval == -5);
+    die(gettext('Unknown error')."\n");
+}
+
+sub update_aaaa {
+    my ($dns, $id, $ip) = @_;
+    die() unless(defined $dns && defined $id && defined $ip);
+    my $rval = $dns->update_aaaa($id, $ip);
+    return 1 if($rval > 0);
+    die(gettext('Invalid record')."\n") if($rval == -1);
+    die(gettext('Record does not exists')."\n") if($rval == -2);
+    die(gettext('Invalid IP address')."\n") if($rval == -3);
+    die(gettext('Database error')."\n") if($rval == -4);
+    die(gettext('Unknown error')."\n");
+}
+
+sub delete_aaaa {
+    my ($dns, $id) = @_;
+    die() unless(defined $dns && defined $id);
+    my $rval = $dns->delete_aaaa($id);
+    return 1 if($rval > 0);
+    die(gettext('Invalid record')."\n") if($rval == -1);
+    die(gettext('Record does not exists')."\n") if($rval == -2);
+    die(gettext('Database error')."\n") if($rval == -3);
+    die(gettext('Unknown error')."\n");
+}
+
 sub delete_a {
     my ($dns, $id) = @_;
     die() unless(defined $dns && defined $id);
@@ -325,7 +366,7 @@
     return 1 if($rval > 0);
     die(gettext('Invalid alias')."\n") if($rval == -1);
     die(gettext('Invalid destination host')."\n") if($rval == -2);
-    die(gettext('A CNAME or A record with the same name already exists for this domain')."\n") if($rval == -3);
+    die(gettext('A CNAME, A or AAAA record with the same name already exists for this domain')."\n") if($rval == -3);
     die(gettext('Database error')."\n") if($rval == -4);
     die(gettext('Unknown error')."\n");
 }

Modified: trunk/vhffs-api/src/Vhffs/Services/DNS.pm
===================================================================
--- trunk/vhffs-api/src/Vhffs/Services/DNS.pm	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-api/src/Vhffs/Services/DNS.pm	2007-04-18 07:16:07 UTC (rev 573)
@@ -260,12 +260,19 @@
     }
     push @params, $srv;
 
+    # Fetches AAAA records
+    $sql = 'SELECT id, zone, (CASE WHEN name = \'\' THEN \'default\' ELSE name END) AS name, type, data, aux, ttl FROM vhffs_dns_rr WHERE zone = ? AND type = \'AAAA\'';
+    $sth = $dbh->prepare($sql);
+    $sth->execute($dns_id);
+    my $aaaa = $sth->fetchall_hashref('id');
+    push @params, $aaaa;
+
     return _new Vhffs::Services::DNS($main, @params);
 }
 
 sub _new
 {
-    my ($class, $main, $dns_id, $domain, $owner_gid, $ns, $mbox, $serial, $refresh, $retry, $expire, $minimum, $ttl, $oid, $owner_uid, $date_creation, $state, $description, $a, $nsr, $cname, $mx, $srv) = @_;
+    my ($class, $main, $dns_id, $domain, $owner_gid, $ns, $mbox, $serial, $refresh, $retry, $expire, $minimum, $ttl, $oid, $owner_uid, $date_creation, $state, $description, $a, $nsr, $cname, $mx, $srv, $aaaa) = @_;
 
     my $self = $class->SUPER::_new($main, $oid, $owner_uid, $date_creation, $description, $state, Vhffs::Constants::TYPE_DNS);
 
@@ -285,18 +292,30 @@
     $self->{CNAME} = $cname;
     $self->{MX} = $mx;
     $self->{SRV} = $srv;
+    $self->{AAAA} = $aaaa;
 
     return $self;
 }
 
-# This function returns -1 if a name already exists.
-# For example, if soda.gunnm.org already exists in the dns_rr table, we return -1. Otherwise, 0.
-sub name_exists
-{
-    my ( $self , $name ) = @_;
+=pod
+
+=head2 name_exists
+
+    print 'A rr with the same name already exists in type A or CNAME' if($dns->name_exists($name, 'A', 'CNAME'));
+
+Tests if a name already exists in given record types. Returns true if the name already exists
+false otherwise.
+
+=cut
+
+sub name_exists {
+    my $self = shift;
+    my $name = shift;
+    my @types = @_;
     my $dbh = $self->get_main->get_db_object();
-    my $sql = 'SELECT id FROM vhffs_dns_rr WHERE name = ? AND zone = ? AND type IN(\'A\', \'CNAME\') LIMIT 1';
-    return ($dbh->do($sql, undef, $name, $self->{dns_id}) != 0);
+    my $in = '?'.(', ?' x (scalar(@types) - 1));
+    my $sql = 'SELECT id FROM vhffs_dns_rr WHERE name = ? AND zone = ? AND type IN('.$in.') LIMIT 1';
+    return ($dbh->do($sql, undef, $name, $self->{dns_id}, @types) != 0);
 }
 
 
@@ -449,7 +468,7 @@
     $ttl = 900 if ( ! defined $ttl );
     return -1 if( ! ($name =~ /^(?:[a-z0-9\-]+|\*)$/ ) );
     $name = '' if( $name eq 'default' );
-    return -2 if ( $self->name_exists( $name ) != 0 );
+    return -2 if ( $self->name_exists( $name, 'A', 'CNAME' ) != 0 );
 
     if( ! defined $ip ) {
         my $config = $self->{'main'}->get_config;	
@@ -681,6 +700,110 @@
     return 1;
 }
 
+=pod
+
+=head2 add_aaaa
+
+    die('Unable to add A Record\n') unless($dns->($name, $ip) > 0)
+
+Add an IPv6 AAAA record.
+
+=cut
+
+sub add_aaaa
+{
+    my ( $self , $name , $ip , $ttl ) = @_;
+    
+    $ttl = 900 if ( ! defined $ttl );
+    return -1 if( ! ($name =~ /^(?:[a-z0-9\-]+|\*)$/ ) );
+    $name = '' if( $name eq 'default' );
+    return -2 if ( $self->name_exists( $name, 'CNAME', 'AAAA' ) != 0 );
+
+    if( ! defined $ip ) {
+        my $config = $self->{'main'}->get_config;	
+    	if( defined $config->get_default_aaaa ) {
+    	    $ip = $config->get_default_aaaa;
+	    } else {
+    	    return -3;
+    	}
+    }
+    
+    return -4 unless( Vhffs::Functions::check_ipv6($ip) );
+
+    my $dbh = $self->get_main()->get_db_object();
+    my $sql = 'INSERT INTO vhffs_dns_rr (zone, name, type, data, aux, ttl) VALUES(?, ?, \'AAAA\', ?, 0, ?)';
+    $dbh->do($sql, undef, $self->{dns_id}, $name, $ip, $ttl) or return -5;
+
+    my $id = $dbh->last_insert_id(undef, undef, 'vhffs_dns_rr', undef);
+    $name = 'default' if($name eq '');
+    my $aaaa = {id => $id,
+             zone => $self->{dns_id},
+             name => $name,
+             type => 'AAAA',
+             data => $ip,
+             aux => 0,
+             ttl => $ttl
+            };
+    $self->{AAAA}{$id} = $aaaa;
+
+    $self->update_serial();
+
+    $self->add_history("Added a AAAA TYPE with name $name pointing on $ip");
+    return $id;
+}
+
+=pod
+
+=head2 update_aaaa
+
+    die("Unable to update AAAA record #$id\n") unless($dns->update_aaaa($id, $newip);
+
+Updates IPv6 address for an AAAA record
+
+=cut
+
+sub update_aaaa
+{
+    my ( $self , $id, $ip ) = @_;
+    
+    return -1 unless($id =~ /^\d+$/ );
+    my $rr = $self->{AAAA}{$id};
+    return -2 unless(defined $rr);
+    return -3 unless( Vhffs::Functions::check_ipv6($ip) );
+
+    my $dbh = $self->get_main()->get_db_object();
+    my $sql = 'UPDATE vhffs_dns_rr SET data = ? WHERE id = ? AND zone = ? AND type = \'AAAA\'';
+    $dbh->do($sql, undef, $ip, $id, $self->{dns_id}) or return -4;
+
+    $rr->{data} = $ip;
+
+    $self->add_history('Updated AAAA record '.$rr->{name}." pointing now on $ip");
+    
+    $self->update_serial();
+    return 1;
+}
+
+sub delete_aaaa
+{
+    my ($self, $id) = @_;
+
+    return -1 unless($id =~ /^\d+$/ );
+    return -2 unless(defined $self->{AAAA}{$id});
+
+    my $dbh = $self->get_main->get_db_object();
+    my $sql = 'DELETE FROM vhffs_dns_rr WHERE type = \'AAAA\' AND zone = ? AND id = ?';
+    $dbh->do($sql, undef, $self->{dns_id}, $id) or return -3;
+
+    $self->add_history('Deleted AAAA record '.$self->{AAAA}{$id}{name});
+    delete $self->{AAAA}{$id};
+    
+    $self->update_serial();
+    return 1;
+}
+
+
+
+
 sub update_cname
 {
     my ($self, $id, $dest) = @_;
@@ -709,7 +832,7 @@
     return -1 unless($name =~ /^[a-z0-9\-]+$/ );
     return -2 unless(Vhffs::Functions::check_domain_name($dest, 1));
     $name = '' if( $name eq 'default' );
-    return -3 if ( $self->name_exists( $name ) != 0 );
+    return -3 if ( $self->name_exists( $name, 'A', 'AAAA', 'CNAME' ) != 0 );
 
     # Add a '.' the the submitted name. Otherwise, if the user submit tata.toto.com IN CNAME foo.com
     # MyDNS will understand tata.toto.com IN CNAME foo.com.toto.com
@@ -822,6 +945,11 @@
     return $self->{A};
 }
 
+sub get_aaaa_type {
+    my $self = shift;
+    return $self->{AAAA};
+}
+
 sub get_cname_type
 {
     my $self = shift;

Modified: trunk/vhffs-backend/conf/vhffs.conf.dist.in
===================================================================
--- trunk/vhffs-backend/conf/vhffs.conf.dist.in	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-backend/conf/vhffs.conf.dist.in	2007-04-18 07:16:07 UTC (rev 573)
@@ -208,6 +208,7 @@
 		default_mx2 = mx2.hoster.org
 
 		default_a	= 1.2.3.4
+        default_aaaa = FEDC::1
 
 		default_ttl = 86400
 		default_aux = 0

Modified: trunk/vhffs-backend/conf/vhffs.conf.in
===================================================================
--- trunk/vhffs-backend/conf/vhffs.conf.in	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-backend/conf/vhffs.conf.in	2007-04-18 07:16:07 UTC (rev 573)
@@ -208,6 +208,7 @@
 		default_mx2 = mx2.hoster.org
 
 		default_a	= 1.2.3.4
+        default_aaaa = FEDC::1
 
 		default_ttl = 86400
 		default_aux = 0

Modified: trunk/vhffs-panel/dns/prefs.pl
===================================================================
--- trunk/vhffs-panel/dns/prefs.pl	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-panel/dns/prefs.pl	2007-04-18 07:16:07 UTC (rev 573)
@@ -126,6 +126,23 @@
                 if($@) { $panel->add_error(sprintf(gettext('Unable to delete A record: %s'), $@)); }
                 else { $panel->add_info(gettext('A Record deleted')); }
             }
+        } elsif($action eq 'manage_aaaa') {
+            if(defined $cgi->param('modify_aaaa_submit')) {
+                # User just want to modify an A record
+                eval { Vhffs::Panel::DNS::update_aaaa($dns, $id, $data); };
+                if($@) { $panel->add_error(sprintf(gettext('Unable to modify AAAA record: %s'), $@)); }
+                else { $panel->add_info(gettext('AAAA Record updated')); }
+            } else {
+                # User wants to delete it
+                eval { Vhffs::Panel::DNS::delete_aaaa($dns, $id); };
+                if($@) { $panel->add_error(sprintf(gettext('Unable to delete AAAA record: %s'), $@)); }
+                else { $panel->add_info(gettext('AAAA Record deleted')); }
+            }
+        } elsif($action eq 'add_aaaa') {
+            my $redirect = $cgi->param('redirect');
+            eval { Vhffs::Panel::DNS::add_aaaa($dns, (defined $redirect && $redirect eq 'true'), $name, $data); };
+            if($@) { $panel->add_error(sprintf(gettext('Unable to add AAAA record: %s'), $@)); }
+            else { $panel->add_info(gettext('AAAA record added')); }
         } elsif($action eq 'add_a') {
             my $redirect = $cgi->param('redirect');
             eval { Vhffs::Panel::DNS::add_a($dns, (defined $redirect && $redirect eq 'true'), $name, $data); };
@@ -198,6 +215,7 @@
 }
 	my $cnames = $dns->get_cname_type;
 	my $a_rr = $dns->get_a_type;
+    my $aaaa = $dns->get_aaaa_type;
 	my $mx = $dns->get_mx_type;
 	my $ns = $dns->get_ns_type;
     my $srv = $dns->get_srv_type;
@@ -208,13 +226,14 @@
     $template->param( DOMAIN_NAME => $domain_name );
 
     $template->param( TEXT_TYPEA => gettext("All A TYPE for you domain name") );
+    $template->param( TEXT_TYPEAAAA => gettext("All AAAA TYPE for you domain name") );
     $template->param( TEXT_TYPEMX => gettext("All MX TYPE for you domain name") );
     $template->param( TEXT_TYPECNAME => gettext("All CNAME for you domain name") );
-    $template->param( TEXT_LIST_A => gettext("List all all A reccords") );
+    $template->param( TEXT_LIST_A => gettext("List all A reccords") );
+    $template->param( TEXT_LIST_AAAA => gettext("List all AAAA reccords") );
     $template->param( TEXT_ADD_A => gettext("Add an A record") );
+    $template->param( TEXT_ADD_AAAA => gettext("Add an AAAA record") );
 
-
-
 	#Treat ACL part
     $template->param( TEXT_ACL_ADMIN => gettext( "Admin Rights on this object (ACL)") );
     $template->param( EXPLAIN_ADMIN_ACL => gettext( "You can Manage rights on this service for each user in the VHFFS database. Please read help before manage it.") );
@@ -290,6 +309,19 @@
     	$template->param( LIST_A => gettext('No A type found' ));
     }
 
+    if( scalar(keys %{$aaaa}) ) {
+        my $thirdtemplate = new HTML::Template( filename => $templatedir.'/dns/list_aaaa_sub.tmpl', global_vars => 1, die_on_bad_params => 0);
+        my @list_aaaa = sort {$a->{name} cmp $b->{name}} values(%{$aaaa});
+	    $thirdtemplate->param( DEL => gettext( 'Delete' ) );
+        $thirdtemplate->param( DOMAIN => $domain_name );
+        $thirdtemplate->param( MODIFY => gettext( 'Modify' ) );
+        $thirdtemplate->param( AAAA_RR => \@list_aaaa);
+    	$template->param( LIST_AAAA => $thirdtemplate->output );
+    } else {
+    	$template->param( LIST_AAAA => gettext('No AAAA type found' ));
+    }
+
+
 	if( scalar(keys %{$mx} ) ) {
         $thirdtemplate = new HTML::Template( filename => $templatedir.'/dns/list_mx_sub.tmpl', global_vars => 1, die_on_bad_params => 0 );
         my @list_mx = sort {$a->{aux} <=> $b->{aux}} values(%{$mx});

Modified: trunk/vhffs-panel/templates/Makefile.am
===================================================================
--- trunk/vhffs-panel/templates/Makefile.am	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-panel/templates/Makefile.am	2007-04-18 07:16:07 UTC (rev 573)
@@ -93,6 +93,7 @@
 	dns/create.tmpl \
 	dns/end.tmpl \
 	dns/list_a_sub.tmpl \
+	dns/list_aaaa_sub.tmpl \
 	dns/list_cname_sub.tmpl \
 	dns/list_mx_sub.tmpl \
 	dns/list_ns_sub.tmpl \

Added: trunk/vhffs-panel/templates/dns/list_aaaa_sub.tmpl
===================================================================
--- trunk/vhffs-panel/templates/dns/list_aaaa_sub.tmpl	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-panel/templates/dns/list_aaaa_sub.tmpl	2007-04-18 07:16:07 UTC (rev 573)
@@ -0,0 +1,16 @@
+<tmpl_loop name="AAAA_RR">
+<form method="post" action="prefs.pl">
+    <p>
+    <label for="data_<tmpl_var name="id">">
+    <TMPL_VAR NAME="name">-&gt;
+    </label>
+        <input type="text" name="data" id="data_<tmpl_var name="id">" value="<TMPL_VAR NAME="data">" />
+        <input type="hidden" name="domain" value="<TMPL_VAR NAME="DOMAIN">" />
+        <input type="hidden" name="rr_id" value="<tmpl_var name="id">" />
+        <input type="hidden" name="name" value="<TMPL_VAR NAME="name">" />
+        <input type="hidden" name="action" value="manage_aaaa"/>
+        <input type="submit" value="<TMPL_VAR NAME="MODIFY">" class="autowidth" name="modify_aaaa_submit" />
+        <input type="submit" value="<TMPL_VAR NAME="DEL">" name="delete_aaaa_submit" class="autowidth"/>
+    </p>
+</form>
+</tmpl_loop>

Modified: trunk/vhffs-panel/templates/dns/prefs.tmpl
===================================================================
--- trunk/vhffs-panel/templates/dns/prefs.tmpl	2007-04-17 20:57:00 UTC (rev 572)
+++ trunk/vhffs-panel/templates/dns/prefs.tmpl	2007-04-18 07:16:07 UTC (rev 573)
@@ -10,12 +10,6 @@
 		</label>
 		<input type="text" name="name"  id="add_a_prefix" /><strong>.<TMPL_VAR NAME="DOMAIN_NAME"></strong>
 	</p>
-	<p id="add_a_ip" style="display:none">
-		<label for="add_a_data">
-		<TMPL_VAR NAME="TEXT_ADDIP">
-		</label>
-		<input type="text" name="data" id="add_a_data" />
-	</p>
 	<p><TMPL_VAR NAME="TEXT_QUESTION_REDIRECTION">:
 		<input type="radio" name="redirect" id="redirect_true" value="true" checked="checked"
             onclick="document.getElementById('add_a_ip').style.display='none'"/>
@@ -24,6 +18,12 @@
             onclick="document.getElementById('add_a_ip').style.display='block'"/>
         <label for="redirect_false" style="display:inline;float:none"><TMPL_VAR NAME="TEXT_NO"></label>
     </p>
+	<p id="add_a_ip" style="display:none">
+		<label for="add_a_data">
+		<TMPL_VAR NAME="TEXT_ADDIP">
+		</label>
+		<input type="text" name="data" id="add_a_data" />
+	</p>
 	<p class="button">
 		<input type="hidden" name="domain" value="<TMPL_VAR NAME="DOMAIN_NAME">" />
         <input type="hidden" name="action" value="add_a"/>
@@ -31,7 +31,40 @@
 	</p>
 </form>
 
+<h2><TMPL_VAR NAME="TEXT_TYPEAAAA"></h2>
+<h3><TMPL_VAR NAME="TEXT_LIST_AAAA"></h3>
+<TMPL_VAR NAME="LIST_AAAA">
 
+<h3><TMPL_VAR NAME="TEXT_ADD_AAAA"></h3>
+<form method="post" action="prefs.pl">
+	<p>
+		<label for="add_aaaa_prefix">
+			<TMPL_VAR NAME="TEXT_DOMAINNAME">
+		</label>
+		<input type="text" name="name" id="add_aaaa_prefix" /><strong>.<TMPL_VAR NAME="DOMAIN_NAME"></strong>
+	</p>
+	<p><TMPL_VAR NAME="TEXT_QUESTION_REDIRECTION">:
+		<input type="radio" name="redirect" id="redirect_aaaa_true" value="true" checked="checked"
+            onclick="document.getElementById('add_aaaa_ip').style.display='none'"/>
+        <label for="redirect_aaaa_true" style="display:inline;float:none"><TMPL_VAR NAME="TEXT_YES"></label>
+        <input type="radio" name="redirect" value="false" id="redirect_aaaa_false"
+            onclick="document.getElementById('add_aaaa_ip').style.display='block'"/>
+        <label for="redirect_aaaa_false" style="display:inline;float:none"><TMPL_VAR NAME="TEXT_NO"></label>
+    </p>
+	<p id="add_aaaa_ip" style="display:none">
+		<label for="add_aaaa_data">
+		<TMPL_VAR NAME="TEXT_ADDIP">
+		</label>
+		<input type="text" name="data" id="add_aaaa_data" />
+	</p>
+	<p class="button">
+		<input type="hidden" name="domain" value="<TMPL_VAR NAME="DOMAIN_NAME">" />
+        <input type="hidden" name="action" value="add_aaaa"/>
+		<input type="submit" value="<TMPL_VAR NAME="TEXT_SUBMIT">" />
+	</p>
+</form>
+
+
 <h2><TMPL_VAR NAME="TEXT_TYPEMX"></h2>
 <h3><TMPL_VAR NAME="TEXT_LIST_MX"></h3>
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/