I had an alternate way of doing this by piping the output of the
"netstat -r -n | grep default" into my application actually. However better way to do this is through code, considering the performance benchmarks the application had to meet. After a bit of struggling to find right
mib values for sysctl using the following code I was able to enumerate the network adapters.
int
findNetworkAdapters
{
int mib[6];
size_t bufferSize = 0;
uint8_t *buffer = NULL, *nextChunk = NULL;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
mib[5] = 0;
if (sysctl(mib, 6, NULL, &bufferSize, NULL, 0) != 0)
return -1;
buffer = new uint8_t[bufferSize];
if (buffer != NULL)
{
if (sysctl(mib, 6, buffer, &bufferSize, NULL, 0) == 0)
{
struct if_msghdr *interface = (struct if_msghdr*)buffer;
for ( nextChunk = buffer;
nextChunk != buffer + bufferSize; nextChunk = nextChunk + interface->ifm_msglen)
{
interface = (struct if_msghdr*)nextChunk;
if (interface->ifm_type == RTM_IFINFO)
{
struct sockaddr_dl *link = (struct sockaddr_dl*)(interface + 1);
if (link->sdl_type == IFT_ETHER)
{
std::string name = (link->sdl_data);
printf("Interface : %s\n", name.c_str());
struct ether_addr hwaddr;
memcpy ((void*)&hwaddr, LLADDR(link), ETHER_ADDR_LEN);
printf("HW address : %x:%x:%x:%x:%x:%x\n", hwaddr.octet[0], hwaddr.octet[1], hwaddr.octet[2], hwaddr.octet[3], hwaddr.octet[4], hwaddr.octet[5]);
findIPAddress(name.c_str());
findSubnetMask(name.c_str());
printf ("\n");
}
}
}
}
free buffer;
}
return 1;
}
The job is now half done. I need to find active adapters,for this I need to get the IP address and Subnet mask assigned to the network adapter. Only active network adapters will have a valid IP and subnet mask assigned.
Thats a uncomplicated job
ioctl the socket and wallah !! I got the IP and subnet mask. Based on IP and subnet mask I could easily identify the active network adapters.
int
findIPAddress(const char* iName)
{
struct ifreq req;
struct sockaddr_in *sin;
int fd = socket(AF_INET, SOCK_DGRAM, 0);
memset((void*)&req, 0, sizeof(struct ifreq));
strcpy(req.ifr_name, iName);
if (ioctl(fd, SIOCGIFADDR, (char *)&req) == -1)
{
printf("Error : %s\n", strerror(errno));
close(fd);
return -1;
}
sin = (struct sockaddr_in*)(&(req.ifr_addr));
printf("IP : %s\n", inet_ntoa(sin->sin_addr));
close(fd);
return 1;
}
int
findSubnetMask(const char* iName)
{
struct ifreq req;
struct sockaddr_in *sin;
int fd = socket(AF_INET, SOCK_DGRAM, 0);
memset((void*)&req, 0, sizeof(struct ifreq));
strcpy(req.ifr_name, iName);
if (ioctl(fd, SIOCGIFNETMASK, (char *)&req) == -1)
{
printf("Error : %s\n", strerror(errno));
close(fd);
return -1;
}
sin = (struct sockaddr_in*)(&(req.ifr_addr));
printf("Subnet Mask : %s\n", inet_ntoa(sin->sin_addr));
close(fd);
return 1;
}
No comments:
Post a Comment