アーカイブ「2023年01月」

C#で、IPアドレスを取得する際、Dns.GetHostEntryを使うという記事がよく出てきます。

当然、DNSサーバを利用する前提なので、DNSサーバから正引きできないと、

結局は、ローカルループバックアドレスしか取れなかったりします。

ローカルネットワークであっても、

consulやdnsmasqなどをつかって、DNS設定くらいちゃんとしとけよというのはもちろんですが、

IPアドレスだけで済むなら、そうしたいのものかと思います。(WINSサーバについては不明です)

このように、正引きできないが、ローカルアドレスを取りたい場合、

NICを直接見に行くほうが楽です。

自分のTCPサーバ・クライアントライブラリに、将来的に使いそうな気がして、実装しておきました。

https://github.com/shigenobu/PurpleSofa/blob/master/PurpleSofa/PsNetwork.cs

v4のアドレス取得部分だけ抜粋します。

    private static readonly IEnumerable<NetworkInterface> NetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces()
        .Where(i =>
            i.OperationalStatus == OperationalStatus.Up &&
            i.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
            i.NetworkInterfaceType != NetworkInterfaceType.Loopback);

    public static IEnumerable<IPAddress> GetLocalIpv4Addresses()
    {
        List<IPAddress> addresses = new();
        foreach (var networkInterface in NetworkInterfaces)
        {
            var address = networkInterface.GetIPProperties().UnicastAddresses
                .Where(a => a.Address.AddressFamily == AddressFamily.InterNetwork)
                .Select(a => a.Address)
                .FirstOrDefault();
            if (address != null)
                addresses.Add(address);
        }

        return addresses;
    }

要は、起動中のイーサネットのNICだけを取得して、それをIEnumerableで返している感じです。

これでWIFIも取れるかと思います。(LINUXでは大丈夫だったが)

NICを複数持っているケース、

たとえばゲートウェイサーバのように、外向きと内向きのアドレスを持つ場合などについては、

https://learn.microsoft.com/ja-jp/dotnet/api/microsoft.aspnetcore.httpoverrides.ipnetwork?view=aspnetcore-7.0

なんていうクラス(ASPですが)を使うことで、

取得したアドレスが、指定のアドレス範囲内かどうかを判断して、取捨選択も出来るかと思います。

以上

投稿日時:2023年01月12日 23:27   カテゴリー:c#   [コメントがあればどうぞ]

私が作成しているPurpleSofaの0.0.9で、IPv6対応をしました。

https://www.nuget.org/packages/PurpleSofa/

v6のサーバというのは、初めて作ったのですが、

フォーマットや省略ルールなど、以下のIBMのサイトがよくまとめられていたので、記載します。

https://www.ibm.com/docs/ja/i/7.1?topic=6-ipv6-concepts

C#の実装におけるポイントですが、

  • v4の「0.0.0.0」(anywhere)は、v6では「::」に相当
  • ソケットオプションで、v6でlistenする場合は、v6onlyをfalseにしておくとv4のソケットをv6として扱ってくれる

ぐらいでした。

(v6でlistenしても、v4を扱う設定)

_socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);

クラウドなんかでは、フロントとなるCDNとかロードバランサが、v6→v4変換とかもしれくれるので、

あんまりv6を直接扱う需要性は低いような気はしますが、

海外では、v6アドレスしか提供しないプロバイダなんかもあるようで、

ある程度v6の対応というか準備もしておいたほうがいいのかなと思うこの頃です。

以上

投稿日時:2023年01月12日 22:59   カテゴリー:c#   [コメントがあればどうぞ]