This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Cygwin's ioctl(SIOCGIFFLAGS) always sets the IFF_UP flag


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
lennox@cs.columbia.edu

--
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/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]