Thursday, January 10, 2008

Programmatically determining an interface IP Address in Linux - C

To determine the IP Adrress, Subnet mask or Broadcast address of an interface in Linux, programmer can use ioctl system call with SIOCGIFADDR request.

The third parameter to ioctl represents a pointer to the structure ifreq, defined in :

struct ifreq {
char ifr_name[IFNAMSIZ];/* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
struct ifmapifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char * ifr_data;
};
};
  • ifr_name is the name of the interface for which information is to be retrieved. The OS/400 implementation requires this field to be set to a NULL-terminated string that represents the interface IP address in dotted decimal format. Depending on the request, one of the fields in the
  • ifr_ifru union will be set upon return from the ioctl() call.
  • ifr_addr is the local IP address of the interface.
  • ifru_mask is the subnetwork mask associated with the interface.
  • ifru_broadaddr is the broadcast address.
  • ifru_flags contains flags that give some information about an interface (for example, token-ring routing support, whether interface is active, broadcast address, and so on).
  • ifru_mtu is the maximum transfer unit configured for the interface.
  • ifru_rbufsize is the reassembly buffer size of the interface.
  • ifru_linename is the line name associated with the interface.
  • ifru_TOS is the type of service configured for the interface.
Sample code:
#include
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char* argv[])
{
int socketd;
char szIPAddr[255];
char szNetmask[255];
char szBroadcast[255];
struct ifreq ifr;

socketd = socket(AF_INET, SOCK_DGRAM, 0);
if (socketd <= 0)
{
perror("socket");
return -1;
}

strcpy(ifr.ifr_name, "eth0");

if (0 == ioctl(socketd, SIOCGIFADDR, &ifr))
{
strcpy(szIPAddr, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
}

if (0 == ioctl(socketd, SIOCGIFNETMASK, &ifr))
{
strcpy(szNetmask, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr));
}

if (0 == ioctl(socketd, SIOCGIFBRDADDR, &ifr))
{
strcpy(szBroadcast, inet_ntoa(((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr));
}

printf("IP: %s Netmask: %s Broadcast: %s\n",
szIPAddr, szNetmask, szBroadcast);

close(socketd);
}

No comments: