덴장......몰랐다 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();
}
}
댓글