This is the mail archive of the
cygwin
mailing list for the Cygwin project.
Cygwin's ioctl(SIOCGIFFLAGS) always sets the IFF_UP flag
- From: Jonathan Lennox <lennox at cs dot columbia dot edu>
- To: cygwin at sourceware dot org
- Date: Thu, 28 Dec 2006 16:20:41 -0500
- Subject: 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/