RE: Retrieving subnet mask
From: Christoffer Bergman (christoffer.bergman_at_audiodev.com)
Date: 02/27/04
- Next message: pete1967: "programatic equivalent of RasEntryDlg"
- Previous message: Arkady Frenkel: "Re: Windows Registry - Incoming Data?"
- In reply to: Christoffer Bergman: "Retrieving subnet mask"
- Messages sorted by: [ date ] [ thread ]
Date: Fri, 27 Feb 2004 08:01:08 -0800
I managed to find the solution to the problem myself :)
There is an undocumented flag to WSAIoctl called SIO_GET_INTERFACE_LIST that retrieves IP, subnet and broadcast for all your ethernet cards (however, broadcast seems to always be 255.255.255.255). So I wrote this method to retrieve a correct (?!) broadcast address for a local IP number:
#define MAX_NBR_OF_ETHERNET_CARDS 32
/**
* This function calculates a suitable broadcast address to use with
* the supplied IP number.
* It will do it by locating the subnet mask for that IP number. Then
* it will calculate the broadcast address as:
* broadcast = ip | ~(subnet)
* The purpose of this function is that the request for broadcast address
* in WSAIoctl() often returns 255.255.255.255 even if a more narrow broadcast
* address should be used.
*
* @param dwIp The IP number in net byte order
* @return A broadcast address for that IP (255.255.255.255 if that IP wasn't found)
* @author Christoffer Bergman
*/
DWORD GetBroadcastAddress(DWORD dwIp)
{
// Create a socket that is just used to get the IP info
SOCKET s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET) {
return INADDR_BROADCAST;
}
// Gather the IP Info
INTERFACE_INFO info[MAX_NBR_OF_ETHERNET_CARDS];
DWORD dwBytesRead;
if(WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0,
(void*)info, sizeof(info), &dwBytesRead, NULL, NULL) != 0) {
closesocket(s);
return INADDR_BROADCAST;
}
DWORD dwBroadcast = INADDR_BROADCAST;
// Search all ip infos for the requested ip number
for(int i = 0; i < (dwBytesRead / sizeof(INTERFACE_INFO)); i++) {
// Notice: the INTERFACE_INFO contains a broadcast address
// but that can't be used since it is always 255.255.255.255
if(info[i].iiAddress.AddressIn.sin_addr.s_addr == dwIp) {
DWORD dwSubnet = info[i].iiNetmask.AddressIn.sin_addr.s_addr;
dwBroadcast = dwIp | ~(dwSubnet);
break;
}
}
closesocket(s);
return dwBroadcast;
}
- Next message: pete1967: "programatic equivalent of RasEntryDlg"
- Previous message: Arkady Frenkel: "Re: Windows Registry - Incoming Data?"
- In reply to: Christoffer Bergman: "Retrieving subnet mask"
- Messages sorted by: [ date ] [ thread ]