C#でコードを書いてみる。

コードを書くと言っても、実は全く難しいプロセスはない。ちょっとしたオプションをソケット(Socket)に対して指定するだけである。

Socket s = new Socket(
    AddressFamily.InterNetworkV6,
    SocketType.Stream,
    ProtocolType.Tcp);

// Teredoを有効にする
const int IPV6_PROTECTION_LEVEL = 23;
const int PROTECTION_LEVEL_UNRESTRICTED = 10;
s.SetSocketOption(
    SocketOptionLevel.IPv6,
    (SocketOptionName)IPV6_PROTECTION_LEVEL,
    PROTECTION_LEVEL_UNRESTRICTED);

たったこれだけ。後は普通のコードと同じ。NATに守られているはずのマシンの情報がWANに漏れることになるので、セキュリティに関しては若干の注意が必要だが、この手軽さは捨てがたい魅力だ。

自分に割り当てられたTeredoIPv6アドレスを取得する

普通はipconfig /allで確認することが出来るが、プログラムから取得するには、ちょっとだけ面倒なことをする必要がある。さらに、アダプタ詳細で判断して良いのかどうかは不明。

IPAddress GetTeredoIPv6Address()
{
    if(!NetworkInterface.GetIsNetworkAvailable())
        throw new ApplicationException("Network is not available!");
    
    if(!Socket.OSSupportsIPv6)
        throw new ApplicationException("IPv6 not enabled!");
    
    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
    if(nics == null || nics.Length == 0)
        throw new ApplicationException("No network interfaces found.");

    foreach(NetworkInterface adapter in nics)
    {
        if(!adapter.Supports(NetworkInterfaceComponent.IPv6))
            continue;
        if(!adapter.Description.Contains("Teredo"))
            continue;
        IPInterfaceProperties props = adapter.GetIPProperties();
       foreach(UnicastIPAddressInformation uiai in props.UnicastAddresses)
       {
           IPAddress addr = uiai.Address;
           if(addr.IsIPv6LinkLocal || addr.IsIPv6SiteLocal)
               continue;
           return addr;
       }
    }
    
    throw new ApplicationException("Teredo adapter is not found!");
    return null;
}