본문 바로가기
Com/c++

GetBestInterface 서버로 접속하는 네트워크어댑터 찾기

by 까바라 2008. 12. 17.
반응형

덴장......몰랐다 GetBestInterface  이런게 있었다니.....
랜카드여러개일때 어떤걸로 인터넷이 되는지 ... 어떻게 해야하나 고민이었는데...
ㅎㅎ ㅇㅋ

=================================================================================
접속하고자하는 서버에 호스트의 IP 주소를 알려주어야 할 경우가 종종 있다. 즉, FTP 서버와 연결하여서 DATA 연동을 위한 IP 및 포트 번호를 FTP 서버로 전달할 때와 같은 경우이다. 보통 FTP 클라이언트의 경우에는 TCP 로 FTP 서버와 연결하므로 socket 의 my ip 정보를 가져오면 FTP 서버와 연결할 때에 사용한 호스트의 IP 주소를 구할 수 있다. 그러나, UDP 서버와 통신하는 경우에는 위와 같은 방법을 사용할 수 없다. 아마 본 프로그램은 SIP 관련 프로그램에서 SDP 제작하실 때에 필요하실 겁니다. *^^*


이에 호스트의 라우팅 정보 및 네트워크 디바이스 정보를 이용하여서 서버와 연결되어 있는 IP 주소를 찾는 방법을 알아보도록 하자.


(1) GetBestInterface 함수를 이용하여서 서버와 연결할 때에 사용할 가능성이 가장 높은 네트워크 인터페이스를 찾는다. 이 함수는 호스트의 라우팅 정보를 이용하여서 서버와 가장 현명하게 접속할 수 있는 네트워크 인터페이스 아이디를 알려준다.


(2) iphlpapi 라이브러리를 이용하여서 호스트에 연결된 네트워크 디바이스 및 IP 주소를 검색한다. 위에서 찾아낸 네트워크 인터페이스 아이디와 동일한 네트워크 디바이스를 찾는다.


(3) 네트워크 디바이스에 설정된 default gw 와 동일한 네트워크 IP 주소를 가진 IP 주소를 찾는다.


위의 프로시저를 실행하는 소스 코드는 아래와 같다.


void PrintIP3( const char * szIp )
{
if( hDll == NULL )
{
   hDll = LoadLibrary( "iphlpapi.dll" );
}

if( hDll )
{
   if( GetBestInterface == NULL )
   {
      GetBestInterface = (GETBESTINTERFACE)GetProcAddress( hDll

                                          , "GetBestInterface" );
      if( GetBestInterface == NULL ) goto NORMAL_CASE;
   }

   DWORD iAddr = inet_addr( szIp );
   DWORD iIndex;
   bool  fisFound = false;

   GetBestInterface( iAddr, &iIndex );

   printf( "interface index = %d ", iIndex );

   DWORD dwErr, dwAdapterInfoSize = 0;
   PIP_ADAPTER_INFO    pAdapterInfo, pAdapt;
   PIP_ADDR_STRING        pAddrStr;

   if( GetAdaptersInfo == NULL )
   {
     GetAdaptersInfo = (GETADAPTERSINFO) GetProcAddress( hDll,

                                           "GetAdaptersInfo" );
     if( GetAdaptersInfo == NULL ) goto NORMAL_CASE;
   }

   if((dwErr = GetAdaptersInfo(NULL,&dwAdapterInfoSize) ) != 0 )
   {
     if( dwErr != ERROR_BUFFER_OVERFLOW )
     {
       goto NORMAL_CASE;
     }
   }

   
// Allocate memory from sizing information
    if( ( pAdapterInfo = (PIP_ADAPTER_INFO) GlobalAlloc( GPTR,

                                   dwAdapterInfoSize )) == NULL )
   {
     goto NORMAL_CASE;
   }

   
// Get actual adapter information
    if( ( dwErr = GetAdaptersInfo( pAdapterInfo,

                                  &dwAdapterInfoSize ) ) != 0 )
   {
     GlobalFree( pAdapterInfo );
     goto NORMAL_CASE;
   }

   for( pAdapt = pAdapterInfo; pAdapt; pAdapt = pAdapt->Next )
   {
     printf( "pAdapt->index = %d ", pAdapt->Index );

     if( pAdapt->Index != iIndex ) continue;

     switch ( pAdapt->Type )
     {
       case MIB_IF_TYPE_ETHERNET:
       case MIB_IF_TYPE_PPP:
         if( strlen( pAdapt->GatewayList.IpAddress.String ) > 0 )
         {
           DWORD    dwGwIp, dwMask, dwIp, dwGwNetwork, dwNetwork;

           dwGwIp=inet_addr(

                          pAdapt->GatewayList.IpAddress.String );

           printf( "Gateway address = [%s] "

                   , pAdapt->GatewayList.IpAddress.String );
           printf( "Gateway mask = [%s] "

                   , pAdapt->GatewayList.IpMask.String );

           for( pAddrStr = &(pAdapt->IpAddressList);

                 pAddrStr;

                 pAddrStr = pAddrStr->Next )
           {
             if( strlen(pAddrStr->IpAddress.String) > 0 )
             {
               dwIp = inet_addr( pAddrStr->IpAddress.String );
               dwMask = inet_addr( pAddrStr->IpMask.String );
               dwNetwork = dwIp & dwMask;
               dwGwNetwork = dwGwIp & dwMask;

               printf( "IP address = [%s], network = %08x "

                      , pAddrStr->IpAddress.String, dwNetwork );
                           
               if( dwGwNetwork == dwNetwork )
               {
                 printf( "ip address = %s "

                         , pAddrStr->IpAddress.String );
                 fisFound = true;
                 break;
               }
             }
           }
         }
         break;
       default:
         break;
     }

     if( fisFound == true ) break;
   }

   GlobalFree( pAdapterInfo );

   if( fisFound == false ) goto NORMAL_CASE;
}
else
{
   printf( "iphlpapi.dll is not loaded " );
NORMAL_CASE:
   printf( "normal local host ip lookup " );
   //PrintIP();
}
}

댓글