Hi,
I have written the below program which will detect all the ethernet interface name. it is running fine and detect all interface name in linux but when i run the same program in qnx i m getting only " lo "
interface name i.e loopback interface name. i dont know why it is not detecting the en0. please tell me the solution.
What I first noticed was that the length didn’t divide into structure size evenly. That mean there were some extra bytes someplace that was messing up your ptr code.
So I copied the data into buff and looked at it in the debugger and noticed that every every interface (I have lo0 and en0) was repeated twice with 4 extra bytes on the 2nd repeat. I have NO idea why this is but it means the header file (net/if.h) is not correct with the union definition.
So I manually computed the offsets to the data and now it prints:
The issue is that a struct sockaddr_dl won’t fit in the
union of a struct ifreq (sizeof(struct sockaddr_dl) >
sizeof(struct sockaddr)). The common way to handle this
is below (eg libpcap does something similar). Note
this has been addressed in the next release and all
ioctls using a struct ifreq have been versioned. The
code below will be continue to work going forward.
-seanb
/*
Example demonstrating a common pitfal with SIOCGIFCONF handling.
*/
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
err(EXIT_FAILURE, "socket");
gifconf(s); /* Old code often used SIOCGIFCONF ioctl */
gifaddrs(s); /* New code should use getifaddrs() */
close(s);
return 0;
size = 4096;
ifc.ifc_len = size;
if ((ifc.ifc_buf = malloc(ifc.ifc_len)) == NULL)
err(EXIT_FAILURE, "malloc");
if (ioctl(s, SIOCGIFCONF, &ifc) == -1)
err(EXIT_FAILURE, "SIOCGIFCONF");
if (ifc.ifc_len >= size) {
/* realloc and try again */
errx(EXIT_FAILURE, "SIOCGIFCONF: buf too small");
}
inext = ifc.ifc_req;
iend = (struct ifreq *)(ifc.ifc_buf + ifc.ifc_len);
for (;;) {
icur = inext;
#if 0
/*
* Broken code. This would happen to work for most cases
* because previously:
*
* sizeof(struct sockaddr) + IFNAMSIZ == sizeof(struct ifreq)
*
* Under this scenario the two ‘if’ cases in the working
* case below work out to the same thing.
*/
inext = (struct ifreq *)
((char )inext + inext->ifr_addr.sa_len + IFNAMSIZ); #else
/ This will work against old / new libsocket */
if (inext->ifr_addr.sa_len + IFNAMSIZ > sizeof(struct ifreq))
inext = (struct ifreq *)
((char *)inext + inext->ifr_addr.sa_len + IFNAMSIZ);
else
inext++; #endif
if (inext > iend)
break;