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/

Reply via email to