LAN ケーブルは繋がっていますか?(Part.2)

前回からの続きです。
今回は、IP Helper の GetIfTable() を使って LAN ケーブルの接続状態を調べてみます。

ネットを探してみると、GetIfTable() の情報はたくさんあるので、今回は、GetIfTable2() を使ってみます。
あまり大差はないのですが…。

なお、GetIfTable2() は、Windows Vista 以降で使える API です。
まずは、GetIfTable2() で取得できる MIB_IF_TABLE2 構造体の Description メンバーだけを使ってアダプター情報だけ
を取得してみます。

すると…

GetIftable2_一覧

やっぱり、こんな結果になりました。IPv6 情報も取得できているようです。

Win32_NetworkAdapter でやったときのように、物理アダプターだけにフィルタリングしてみると、いい感じになりました。
具体的には MIB_IF_TABLE2 構造体の HardwareInterface メンバーを参照します。

bool IsHardware(DWORD dwIndex)
{
  return
   (_pInfoBuffer2->Table[dwIndex].InterfaceAndOperStatusFlags.HardwareInterface) ? true : false;
}

そして、ケーブル接続状態ですが、MIB_IF_TABLE2 構造体の MediaConnectState メンバーを参照して判別してみました。
前回同様に “ケーブルを繋いで実行”、”ケーブルを抜いて実行” の結果は、次のようになり、Win32_NetworkAdapter と
同じ結果になりました。同じ結果になって良かったです。

GetIftable2_結果

次のようなコードを書いて検証してみました。クラスにしたのは、デストラクタで後処理(メモリ解放)をするためです。

class CMyNetworkInterface
{
public:
    MIB_IF_TABLE2 * _pInfoBuffer2;

public:
    CMyNetworkInterface() : _pInfoBuffer2(NULL) { }
    ~CMyNetworkInterface()
    {
        if (_pInfoBuffer2) 
            FreeMibTable(_pInfoBuffer2); 
    }

public:
    // アダプター数は?
    DWORD GetNicCount(void)
    {
        if (IsValidInfo2() == false)
            return 0;
        return (_pInfoBuffer2->NumEntries);
    }

    // アダプター名は?
    void ShowNicName(DWORD dwIndex)
    {
        printf("Adapter Name: %ls\n", _pInfoBuffer2->Table[dwIndex].Description);
    }

    bool IsEthernet(DWORD dwIndex)
    {
        if (dwIndex >= GetNicCount2())
            return false;
        return (_pInfoBuffer2->Table[dwIndex].Type == IF_TYPE_ETHERNET_CSMACD) ? true : false;
    }

    bool IsHardware(DWORD dwIndex)
    {
        return
        (_pInfoBuffer2->Table[dwIndex].InterfaceAndOperStatusFlags.HardwareInterface) ? true : false;
    }

    void ShowConnectionStatus(DWORD dwIndex)
    {
        switch (_pInfoBuffer2->Table[dwIndex].MediaConnectState)
        {
        case MediaConnectStateUnknown:
        default:
            printf("Media Status: Unknown.\n"); break;
        case MediaConnectStateConnected:
            printf("Media Status: Connected.\n"); break;
        case MediaConnectStateDisconnected:
            printf("Media Status: Disconnected.\n"); break;
        }
    }

    void ShowMacAddress(DWORD dwIndex)
    {
        TCHAR strMacAddress[256];
        *strMacAddress = ”;
        for (int j = 0; j < (int) _pInfoBuffer2->Table[dwIndex].PhysicalAddressLength; j++)
        {
            if (j == (_pInfoBuffer2->Table[dwIndex].PhysicalAddressLength – 1))
                wsprintf(strMacAddress+(j*3), "%.2X",
                    (int) _pInfoBuffer2->Table[dwIndex].PhysicalAddress[j]);
            else
                wsprintf(strMacAddress+(j*3), "%.2X-",
                    (int) _pInfoBuffer2->Table[dwIndex].PhysicalAddress[j]);
        }
        printf("MAC Address : %s\n", strMacAddress);
    }

protected:
    bool GetNicInformation()
    {
        DWORD ret = GetIfTable2(&_pInfoBuffer2);
        if (ret != NO_ERROR)
            return false;
        return true;
    }

    // クラス内にアダプターデータを取得済みかチェック
    bool IsValidInfo(void)
    {
        if (_pInfoBuffer2)
            return true;
        // もし、取得していなければ取得する
        return GetNicInformation();
    }
};

int IsMediaStatus()
{
    CMyNetworkInterface    cDevice;
    DWORD dwSize = cDevice.GetNicCount2();
    for (DWORD i = 0; i < dwSize; i++)
    {
        if (cDevice.IsHardware(i) == true)
        {
            cDevice.ShowNicName(i);
            cDevice.ShowMacAddress(i);
            cDevice.ShowConnectionStatus(i);
        }
    }
    return 0;
}

実際の使用シナリオでは、監視用スレッドを用意して、そこに実装してもいいかもしれません。
そういえば、ワイヤレス LAN だとどうなるんだろうか。まぁ、いっか。

3 Responses to LAN ケーブルは繋がっていますか?(Part.2)

  1. 川口 より:

    MIB_WIFRO2を使おうとしたのですが、Iphlpapi.hをインクルードしても定義されていない識別子となり
    使えません。ヘッダファイルは何をインクルードされたのか教えて頂けないでしょうか。

    • とうがらし より:

      コメントありがとうございます。早速ですが、MIB_WIFRO2 という MIB を見たことがないのですが、これはスペルミスではなく、本当にあるものでしょうか?ネットで検索しても見つかりませんでした。

  2. |。・ω・) 普通に考えて MIB_IF_ROW2 の入力ミスのような…。

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。