在Windows中取得PPP/SLIP拨号时的外部IP地址
在Windows通过拨号方式接入互联网时,不论是通过SLIP还是PPP,系统都会自动得到一个外部IP地址,互联网的其他机器都可以通过这个IP访问到我们,下面我们将通过程序得到这个地址。
1、 首先我们来看看怎么取得内部IP地址,也就是在局域网中分配到的IP地址:
u_long GetLocalIp()
... {
char szName[128];
//取得主机名称
if(gethostname(szName, 128) ==0) ...{
//根据主机名称得到IP地址
LPHOSTENT pHostent = gethostbyname(szName);
if(pHostent == NULL) ...{
return htonl(INADDR_ANY);
} else ...{
return *(u_long*)pHostent->h_addr;
}
}
return 0L;
}
... {
char szName[128];
//取得主机名称
if(gethostname(szName, 128) ==0) ...{
//根据主机名称得到IP地址
LPHOSTENT pHostent = gethostbyname(szName);
if(pHostent == NULL) ...{
return htonl(INADDR_ANY);
} else ...{
return *(u_long*)pHostent->h_addr;
}
}
return 0L;
}
2、 在取得外部IP地址之前,我们要先查询当前主机连接到互联网的方式,可以使用InternetGetConnectedState()函数得到系统的连接方式,该函数在wininet.h中定义,需要包含wininet.lib。然后通过GetAdaptersInfo()函数得到每个网卡的信息,从中可以提取每个网卡关联的IP地址,该函数在iphlpapi.h中定义,需要包含iphlpapi.lib。结合这两个函数我们可以得到各种连接方式下的IP地址:
u_long GetWANIp()
... {
u_long ip = 0;
DWORD dwFlags = 0;
if (InternetGetConnectedState(&dwFlags, 0)) ...{
if (dwFlags & INTERNET_CONNECTION_MODEM)
...{
// 通过moden拨号连接到互联网,使用GetAdaptersInfo得到ip地址
PIP_ADAPTER_INFO pInfo = NULL;
ULONG ulSize = 0;
DWORD dwStatus;
//得到网卡信息
dwStatus = GetAdaptersInfo(pInfo, &ulSize);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
pInfo = (PIP_ADAPTER_INFO) new char[ulSize];
dwStatus = GetAdaptersInfo(pInfo, &ulSize);
if (dwStatus == ERROR_SUCCESS) ...{
while (pInfo != NULL) ...{
if(pInfo->Type == MIB_IF_TYPE_PPP || pInfo->Type == MIB_IF_TYPE_SLIP) ...{
ip = inet_addr(pInfo->IpAddressList.IpAddress.String);
}
pInfo = pInfo->Next;
}
}
} else ...{
ip = GetLANIp();
}
} else ...{
ip = GetLANIp();
}
return ip;
}
... {
u_long ip = 0;
DWORD dwFlags = 0;
if (InternetGetConnectedState(&dwFlags, 0)) ...{
if (dwFlags & INTERNET_CONNECTION_MODEM)
...{
// 通过moden拨号连接到互联网,使用GetAdaptersInfo得到ip地址
PIP_ADAPTER_INFO pInfo = NULL;
ULONG ulSize = 0;
DWORD dwStatus;
//得到网卡信息
dwStatus = GetAdaptersInfo(pInfo, &ulSize);
if (dwStatus == ERROR_BUFFER_OVERFLOW)
pInfo = (PIP_ADAPTER_INFO) new char[ulSize];
dwStatus = GetAdaptersInfo(pInfo, &ulSize);
if (dwStatus == ERROR_SUCCESS) ...{
while (pInfo != NULL) ...{
if(pInfo->Type == MIB_IF_TYPE_PPP || pInfo->Type == MIB_IF_TYPE_SLIP) ...{
ip = inet_addr(pInfo->IpAddressList.IpAddress.String);
}
pInfo = pInfo->Next;
}
}
} else ...{
ip = GetLANIp();
}
} else ...{
ip = GetLANIp();
}
return ip;
}
InternetGetConnectedState() 参考 http://msdn2.microsoft.com/en-us/library/aa384702.aspx
GetAdaptersInfo() 参考http://msdn2.microsoft.com/en-us/library/aa365917.aspx