MACアドレスからネットワークアダプタの情報を取得する

MACアドレスからIPアドレス/サブネットマスク/リンクスピードを取得するサンプル。

#include <windows.h>
#include <stdio.h>
#include <iphlpapi.h>
#include <vector>

const DWORD MAC_ADDR_LEN = 6;

struct SAdapterInfo {
  BYTE mac_addr[MAC_ADDR_LEN]; // MACアドレス
  DWORD ip_addr; // IPアドレス
  DWORD subnetmask; // サブネットマスク
  DWORD link_speed; // リンクスピード
};


//////////////////////////////////////////////////////////////////////////
// ネットワークアダプタの IPアドレス/サブネットマスク/リンクスピードを
// 取得する
//
// 引数
// adapter_info in/out ネットワークアダプタ情報
// mac_addr に情報を取得したいアダプタの
// MACアドレスを格納して渡す。
//
// 戻り値
// 0 成功
// 非0 失敗
//////////////////////////////////////////////////////////////////////////
int get_adapter_info( SAdapterInfo &adapter_info )
{
  PIP_ADAPTER_INFO p_addr_list = 0;
  ULONG info_size = 0;
  
  // アダプターインフォリストを取得
  if ( GetAdaptersInfo( NULL, &info_size ) != ERROR_BUFFER_OVERFLOW ) {
    printf( "GetAdaptersInfo() buffer size get failed\n" );
    return -1;
  }
  
  std::vector<BYTE> info_buffer(info_size);
  p_addr_list = (PIP_ADAPTER_INFO)&(info_buffer[0]);
  
  if ( GetAdaptersInfo( p_addr_list, &info_size ) != ERROR_SUCCESS ) {
    printf( "GetAdaptersInfo() failed\n" );
    return -1;
  }
  
  // 指定されたMACアドレスを一致する情報を取得
  PIP_ADAPTER_INFO p_info = p_addr_list;
  bool get_info = false;
  for ( int i = 0; NULL != p_info; p_info = p_info->Next, i++ ) {
    
    if ( memcmp( p_info->Address, adapter_info.mac_addr, sizeof(adapter_info.mac_addr) ) == 0 ) {
      adapter_info.ip_addr = inet_addr( p_info->IpAddressList.IpAddress.String );
      adapter_info.subnetmask = inet_addr( p_info->IpAddressList.IpMask.String );
      
      get_info = true;
      break;
    }
  }

  if ( !get_info ) {
    printf( "not get adapter info\n" );
    return -1;
  }
  
  if ( get_link_speed( adapter_info ) != 0 ) {
    printf( "get_link_speed failed\n" );
    return -1;
  }
  
  return 0;
}


int get_link_speed( SAdapterInfo &adapter_info )
{
  int retval = -1;
  
  // アダプタ数取得
  DWORD interface_num = 0;
  if ( GetNumberOfInterfaces( &interface_num ) != ERROR_SUCCESS ) {
    printf( "GetNumberOfInterfaces failed\n" );
    return -1;
  }

  // MACアドレスに一致する情報からリンクスピードを取得する
  MIB_IFROW mib_ifrow = {0};
  for ( DWORD i = 1; i <= interface_num; i++ ) {
    mib_ifrow.dwIndex = i;
    if ( GetIfEntry( &mib_ifrow ) == NO_ERROR ) {
      
      _print_mib_ifrow( mib_ifrow );
      
      if ( memcmp( adapter_info.mac_addr, mib_ifrow.bPhysAddr, sizeof(adapter_info.mac_addr) ) == 0 ) {
        adapter_info.link_speed = mib_ifrow.dwSpeed;
        retval = 0;
        break;
      }
    }
  }
  
  return retval;
}