C program to get ip address from interface name on Linux

Interface name is something like "eth0" and the ip address of the interface can be retrieved using the ioctl function.


Here is a simple piece of code that demonstrates how :

Code

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <unistd.h>
#include <arpa/inet.h>

int main()
{
	int fd;
	struct ifreq ifr;
	
	char iface[] = "eth0";
	
	fd = socket(AF_INET, SOCK_DGRAM, 0);

	//Type of address to retrieve - IPv4 IP address
	ifr.ifr_addr.sa_family = AF_INET;

	//Copy the interface name in the ifreq structure
	strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);

	ioctl(fd, SIOCGIFADDR, &ifr);

	close(fd);

	//display result
	printf("%s - %s\n" , iface , inet_ntoa(( (struct sockaddr_in *)&ifr.ifr_addr )->sin_addr) );

	return 0;
}

Output

$ gcc ioctl.c && ./a.out
eth0 - 192.168.0.6

The socket used can be a TCP socket (SOCK_STREAM) as well.

If you also need the netmask then use the SIOCGIFNETMASK value in ioctl like this :

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <unistd.h>
#include <arpa/inet.h>

int main()
{
	int fd;
	struct ifreq ifr;
	
	char iface[] = "eth0";
	
	fd = socket(AF_INET, SOCK_DGRAM, 0);

	//Type of address to retrieve - IPv4 IP address
	ifr.ifr_addr.sa_family = AF_INET;

	//Copy the interface name in the ifreq structure
	strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);
	
	//get the ip address
	ioctl(fd, SIOCGIFADDR, &ifr);
	
	//display ip
	printf("IP address of %s - %s\n" , iface , inet_ntoa(( (struct sockaddr_in *)&ifr.ifr_addr )->sin_addr) );
	
	//get the netmask ip
	ioctl(fd, SIOCGIFNETMASK, &ifr);
	
	//display netmask
	printf("Netmask of %s - %s\n" , iface , inet_ntoa(( (struct sockaddr_in *)&ifr.ifr_addr )->sin_addr) );
	
	close(fd);
	
	return 0;
}

Output :

$ gcc ioctl.c && ./a.out
IP address of eth0 - 192.168.0.6
Netmask of eth0 - 255.255.255.0






Last Updated On : 17th March 2012

Subscribe to get updates delivered to your inbox

2 Comments + Add Comment

  • Finally someone posted some code that actually works. Thank you so much. This is such a straightforward question that receives such complicated gobbledegook on Stackoverflow. I have been looking for this for a long time. Great job.

    I don’t understand the comment above about strcpy(). Hope it isn’t a problem.

  • This code makes a common mistake in assuming that strncpy() guarantees that the resulting string is null-terminated. In fact, it only does so if the string is shorter than the length specified (i.e., IFNAMSIZ-1); otherwise, it simply copies up to the last character position that fits (i.e., ifr.ifr_name[IFNAMSIZ-2]) and stops — no ” is inserted. (This may seem stupid to the younger readers, but the purpose of the strncpy() function was to support an erstwhile popular use of fixed-length “string buffer” storage where null terminators were considered a waste of a perfectly good space in a message, for example. In any case, the C standard never required the guarantee of a null-terminator on truncated strings as a result, though some compiler vendors implemented it that way by choice, leading some to believe the behavior was part of the function definition.) Of course, in this example, the string is a fixed “eth0”, so the code works just fine, but obviously the code uses strncpy() rather than strcpy() to cover the general case where the ifname string length is unknown and could exceed the IFNAMSIZ limit. As long as this is theoretically possible, the code should ensure null-termination by following up the strncpy() with a manual termination (e.g., “ifr.ifr_name[IFNAMSIZ-1] = ”;).

Leave a comment