I am writing a program which can read the IP address that I have been assigned on a specific network interface (VLAN: eth0.32). I won't know if I have been assigned an IPv4 or a IPv6 address so I try to write it protocol family agnostic.
The way it works is: with a for, I navigate through the list of available network interfaces and I stop at the point where I find my VLAN (eth0.32) to read the IP address. Anyways, at this point of development I just want that it works for IPv4 but leave it ready when I want to implement IPv6 support.
The program works and reads the IPv4 address if I create the socket normally:
sd=socket(PF_INET, SOCK_DGRAM, 0);
But as I won't be able to read IPv6 addresses with this socket family (PF_INET=IPv4) I do it like this:
sd=socket(PF_INET6, SOCK_DGRAM, 0);
setsockopt(sd, SOL_SOCKET, IPV6_V6ONLY, 0, sizeof(int));
The problem is that with this IPv6 socket, it fails to accomplish the if condition to read the ip address:
if (ioctl(sd, SIOCGIFCONF, &ifc) == 0)
For more information, this is my whole code:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <netdb.h>
#include <net/if.h>
int main(int argc, char **argv)
{
struct ifconf ifc;
struct ifreq ifr[MAX_NETWORK_INTERFACES];
int ifc_num, addr, i;
static uint8 sd=0;
sd=socket(PF_INET6, SOCK_DGRAM, 0);
setsockopt(sd, SOL_SOCKET, IPV6_V6ONLY, 0, sizeof(int)); //I change the socket option IPV6_V6ONLY to false, so it should be compatible with IPv4
if (sd > 0)
{
ifc.ifc_len = sizeof(ifr);
ifc.ifc_ifcu.ifcu_buf = (caddr_t)ifr; //Buffer address
if (ioctl(sd, SIOCGIFCONF, &ifc) == 0)
{
ifc_num = ifc.ifc_len / sizeof(struct ifreq); //Number of network interfaces found
for (i = 0; i < ifc_num; i++)
{
if(ifr[i].ifr_addr.sa_family != AF_INET) //If it is not an IPv4 address, we do nothing
{
continue;
}
if (strcmp(ifr[i].ifr_ifrn.ifrn_name,"eth0.32")==0)
{
if (ioctl(sd, SIOCGIFADDR, &ifr[i]) == 0) // HERE IS WHERE THE IPv6 SOCKET DOESN'T ENTER!!!
{
addr = ntohl(((struct sockaddr_in *)(&ifr[i].ifr_addr))->sin_addr.s_addr);
}
fclose(fp);
break; // end loop
}
}
}
}
return addr;
}
Thanks in advance for your help!