IPv6のアドレスを比較するには?

解決


RTE  2011-11-02 15:05:47  No: 72987  IP: [192.*.*.*]

環境は、
VC++、 Windows Vistaです。

IPv6のアドレスを使用するために使われる構造体としては、
SDKのin6addr.hに以下のように定義されています。

typedef struct in6_addr {
    union {
        UCHAR       Byte[16];
        USHORT      Word[8];
    } u;
} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;


これを比較(等しいか等しくないか)するために、以下のような関数を作ったのですが、
もう少しスマートな方法がありましたら、教えてください。
BOOL FuncA(){
  for(int i = 0; i < 16; i++)
  {
    if( addr1->u.Byte[i] != addr2->u.Byte[i] )
    {
      return FALSE;
    }
  }
  for(int j = 0; j < 8; j++)
  {
    if( addr1->u.Word[j] != addr2->u.Word[j] )
    {
      return FALSE;
    }
  }
  return TRUE;
}

編集 削除
瀬戸っぷ  2011-11-02 15:30:39  No: 72988  IP: [192.*.*.*]

>typedef struct in6_addr {
>    union {
>        UCHAR       Byte[16];
>        USHORT      Word[8];
>    } u;
>} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;

unionですから…
>for(int i = 0; i < 16; i++)
>for(int j = 0; j < 8; j++)
と2回確認する必要はありません。
ループ回数が少なくて済みますから、u.Word[]の方で判定するだけでよいかと思われます。
# 関数作らなくても、構造体をmemcmp()する。なんて手もあるんじゃないですかね。
# この構造体ならパディングでゴミが入ることもないでしょうし。

編集 削除
tetrapod  2011-11-02 15:38:49  No: 72989  IP: [192.*.*.*]

何をもってスマートと呼ぶか、次第だったりするが・・・
・ソースコード的に見やすい?
・高速?(不一致発見で即終了するよう分岐をたくさん設ける)
・高速?(キャッシュペナルティ最小になるよう分岐を設けない)
・処理系が標準で用意していて移植性が高い?

とりあえず VS2005 の PlatformSDK/Include/WS2tcpip.h には
インライン関数 IN6_ADDR_EQUAL っつのが用意されているのでこれを使うとか。
(こいつの中身は memcmp)
# HPUX 11.11 に ipv6 アドレスの比較マクロ・インライン関数は無かった
# openSUSE 11.4 には IN6_ARE_ADDR_EQUAL マクロがあった
# ってことは IN6_ADDR_EQUAL も [世界標準] ではないってことだ。

編集 削除
RTE  2011-11-02 16:09:22  No: 72990  IP: [192.*.*.*]

瀬戸っぷさま

確かにおっしゃる通りですね。unionでした。。

tetrapod さま
・ソースコード的に見やすい?
を意味していました。  
IN6_ADDR_EQUALを使ってみます。

編集 削除
gak  2011-11-02 17:59:23  No: 72991  IP: [192.*.*.*]

> # ってことは IN6_ADDR_EQUAL も [世界標準] ではないってことだ。
参考としてだけど、RFCでは一応↓のように規定はされている様子。
http://tools.ietf.org/html/rfc3542#section-2.3

編集 削除