I've discovered that Cygwin's ioctl(SIOCGIFFLAGS) call always sets the IFF_UP flag, even if the interface being queried is disabled or unconfigured.
Compare the output of the program local-if.c (attached below) to the output of ipconfig.exe, when I have one interface disabled: $ ./local-if eth0: AF=2 (INET): flags=0x63 (up broadcast notrailers running) addr=0.0.0.0 lo: AF=2 (INET): flags=0x69 (up loopback notrailers running) addr=127.0.0.1 eth1: AF=2 (INET): flags=0x63 (up broadcast notrailers running) addr=192.168.1.104 eth2: AF=2 (INET): flags=0x63 (up broadcast notrailers running) addr=192.168.1.173 $ ipconfig Windows IP Configuration Ethernet adapter Wireless Network Connection: IP Address. . . . . . . . . . . . : 192.168.1.104 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : 192.168.1.1 Ethernet adapter Local Area Connection 3: IP Address. . . . . . . . . . . . : 192.168.1.173 Subnet Mask . . . . . . . . . . . : 255.255.255.0 Default Gateway . . . . . . . . . : Ethernet adapter Local Area Connection 4: Media State . . . . . . . . . . . : Media disconnected Some experimentation shows that following get_2k_ifconf's call to GetIfEntry, Windows does indeed set MIB_IFROW.dwOperStatus to MIB_IF_OPER_STATUS_NON_OPERATIONAL, but the cygwin library ignores this field. A non-configured interface should be easily reproducable; any DHCP interface should enter this state following "ipconfig /release". This is on Windows XP SP2; the actual unconfigured interface I'm using is an OpenVPN tunnel.
#include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> const char *afname(int af) { switch (af) { case AF_INET: return "INET"; default: return "Unknown"; } } void print_flags(int flags) { const char* sep = "", *sp = " "; if (flags & IFF_UP) { printf("%sup", sep); sep = sp; } if (flags & IFF_BROADCAST) { printf("%sbroadcast", sep); sep = sp; } if (flags & IFF_LOOPBACK) { printf("%sloopback", sep); sep = sp; } if (flags & IFF_NOTRAILERS) { printf("%snotrailers", sep); sep = sp; } if (flags & IFF_RUNNING) { printf("%srunning", sep); sep = sp; } if (flags & IFF_PROMISC) { printf("%spromisc", sep); sep = sp; } if (flags & IFF_MULTICAST) { printf("%smulticast", sep); sep = sp; } } int main() { int sock = socket(AF_INET, SOCK_DGRAM, 0); char buf[256 * sizeof(struct ifreq)]; struct ifreq* ifr, ifr2; char* ifrp; struct ifconf ifc; if (sock == -1) { perror("socket"); exit(1); } ifc.ifc_len = sizeof(buf); ifc.ifc_buf = buf; if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) { perror("ioctl(SIOCGIFCONF)"); exit(1); } for (ifrp = ifc.ifc_buf; (ifrp - ifc.ifc_buf) < ifc.ifc_len; ifrp += sizeof(ifr->ifr_name) + sizeof(struct sockaddr)) { ifr = (struct ifreq*)ifrp; ifr2 = *ifr; if (ioctl(sock, SIOCGIFFLAGS, &ifr2) == -1) { perror("ioctl(SIOCGIFFLAGS"); exit(1); } printf("%s: AF=%d (%s): flags=%#x (", ifr->ifr_name, ifr->ifr_addr.sa_family, afname(ifr->ifr_addr.sa_family), ifr2.ifr_flags); print_flags(ifr2.ifr_flags); printf(")"); switch (ifr->ifr_addr.sa_family) { case AF_INET: printf(" addr=%s", inet_ntoa(((struct sockaddr_in*)(&ifr->ifr_addr))->sin_addr)); break; default: printf(" [AF Unsupported]"); break; } printf("\n"); } close(sock); return 0; }
-- Jonathan Lennox [EMAIL PROTECTED]
-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/