Strotmann.de
26 Mar 2011

DNS information in IPv6 Router Advertisement on MacOS X

Saturday Mar 26, 2011

On my IPv6 router, I have the router advertisement daemon 'radvd' running:

blackbox# more /etc/radvd.conf 
interface eth0
{
        AdvOtherConfigFlag on;
        AdvManagedFlag off;
        AdvSendAdvert on;
        RDNSS 2001:db8:2b6::1 {
           AdvRDNSSLifetime 84600;
        };

        prefix 2001:db8:2b6::/64
        {
                AdvOnLink on;
                AdvAutonomous on;
        };
};

The Line 'RDNSS 2001:db8:2b6::1' configures the advertisement daemon to send the DNS Servers IPv6 address '2001:db8:2b6::1' with a lifetime of 24 hours (86400 seconds).

When the 'rdnssd' service is then started on a MacOS X client, it will receive the DNS server information and write it into the file '/usr/local/var/run/rdnssd/resolv.conf' (this file location can be changed with the commandline option '–resolv-file' (however 'rdnssd' should never write directly into '/etc/resolv.conf', as this will overwrite any data received via DHCP). The content of this file after receiving the DNS information is

more /usr/local/var/run/rdnssd/resolv.conf
nameserver 2001:db8:2b6::1

Whenever the 'rdnssd' daemon updates its 'resolv.conf' file, it can start a script (the script location can be configured with '–merge-hook merge-hook', the default location is '/usr/local/etc/rdnssd/merge-hook' ('rdnssd' comes with an example script for Linux, but this will not work on MacOS X).

simple 'rdnssd' script hook:

#! /bin/sh
#
# resolv.conf merge hook for rdnssd
# MacOS X 10.6 version
# Carsten Strotmann, March 2011 
# partly based on a scipt by Stephan Oeste 
set -e

system_resolv="/etc/resolv.conf"
rdnssd_resolv="/usr/local/var/run/rdnssd/resolv.conf"

# make sure that each IP only appears once
cat $system_resolv $rdnssd_resolv | sort | uniq > /tmp/resolv.conf.tmp 

# get the IP addresses of all DNS servers
ip=`cat /tmp/resolv.conf.tmp |  grep "nameserver" | awk '{printf "%s ", $2}'`
# get the local domain
domain=`cat /tmp/resolv.conf.tmp |  grep "domain" | awk '{printf "%s ", $2}'`

rm /tmp/resolv.conf.tmp

PSID=$( (scutil | grep PrimaryService | sed -e 's/.*PrimaryService : //')<< EOF
open
get State:/Network/Global/IPv4
d.show
quit
EOF
)

scutil << EOF
open
d.init
d.add ServerAddresses * $ip  
d.add DomainName $domain
set State:/Network/Service/$PSID/DNS
quit
EOF

This is the LaunchDaemon description for the 'rdnssd' service:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd" >
<plist version='1.0'>
<dict>
<key>Label</key><string>net.linkfanel.ndisc6</string>
<key>ServiceDescription</key>
<string>Recursive DNS Solicitation Daemon</string>

<key>ProgramArguments</key>
<array>
        <string>/usr/local/sbin/rdnssd</string>
        <string>-f</string>
        <string>-H/usr/local/etc/rdnssd/merge-hook</string>
        <string>-r/usr/local/var/run/rdnssd/resolv.conf</string>
</array>
<key>WorkingDirectory</key>
<string>/</string>
<key>Debug</key><false/>
<key>Disabled</key><false/>
<key>OnDemand</key><false/>
<key>RunAtLoad</key><true/>
</dict>
</plist>

To start the 'rdnssd' service, copy the above plist into /Library/LaunchDaemons/net.linkfanel.ndisc6.rdnssd.plist and reconfigure launchd with sudo launchctl load -w /Library/LaunchDaemons/net.linkfanel.ndisc6.rdnssd.plist.

Other posts
Creative Commons License
strotmann.de by Carsten Strotmann is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License .