diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7dcc1da36..11729f7ca 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2007-06-14 Corinna Vinschen + + * autoload.cc (GetIpForwardTable): Define. + * fhandler_socket.cc (fhandler_socket::ioctl): Handle SIOCGIFDSTADDR. + * net.cc (get_routedst): New static function to get destination + address of point-to-point interfaces. + (get_xp_ifconf): Handle SIOCGIFDSTADDR. + (get_2k_ifconf): Ditto. + (get_nt_ifconf): Ditto. + (get_ifconf): Ditto. + * include/asm/socket.h (SIOCGIFDSTADDR): Define. + * include/cygwin/if.h (struct ifreq): Add ifru_dstaddr member. + (ifr_dstaddr): Define. + * include/cygwin/in.h: Cast ipv4 addresses correctly to in_addr_t in + definitions. + 2007-06-12 Christopher Faylor * signal.cc (usleep): Use useconds_t for the type as per POSIX. diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc index df8747699..3d55cddf9 100644 --- a/winsup/cygwin/autoload.cc +++ b/winsup/cygwin/autoload.cc @@ -395,6 +395,7 @@ LoadDLLfunc (WSAWaitForMultipleEvents, 20, ws2_32) LoadDLLfuncEx2 (GetAdaptersAddresses, 20, iphlpapi, 1, 50) LoadDLLfuncEx2 (GetIfEntry, 4, iphlpapi, 1, 50) LoadDLLfuncEx2 (GetIpAddrTable, 12, iphlpapi, 1, 50) +LoadDLLfuncEx2 (GetIpForwardTable, 12, iphlpapi, 1, 50) LoadDLLfuncEx2 (GetNetworkParams, 8, iphlpapi, 1, 50) LoadDLLfuncEx2 (GetTcpTable, 12, iphlpapi, 1, 50) LoadDLLfuncEx2 (SendARP, 16, iphlpapi, 1, 50) diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 59ec88e0c..ff46fbe3f 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -1519,6 +1519,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) case SIOCGIFMTU: case SIOCGIFINDEX: case SIOCGIFFRNDLYNAM: + case SIOCGIFDSTADDR: { if (!p) { diff --git a/winsup/cygwin/include/asm/socket.h b/winsup/cygwin/include/asm/socket.h index f8e93cc81..e4cec1fd6 100644 --- a/winsup/cygwin/include/asm/socket.h +++ b/winsup/cygwin/include/asm/socket.h @@ -44,6 +44,7 @@ details. */ #define SIOCGIFINDEX _IOW('s', 108, struct ifreq) /* get if index */ #define SIOGIFINDEX SIOCGIFINDEX /* backward compatibility w/ Linux typo. */ #define SIOCGIFFRNDLYNAM _IOW('s', 109, struct ifreq) /* get friendly if name */ +#define SIOCGIFDSTADDR _IOW('s', 110, struct ifreq) /* Get if dstaddr */ #define SOL_SOCKET 0xffff /* options for socket level */ diff --git a/winsup/cygwin/include/cygwin/if.h b/winsup/cygwin/include/cygwin/if.h index c61e2ada2..30474fe5a 100644 --- a/winsup/cygwin/include/cygwin/if.h +++ b/winsup/cygwin/include/cygwin/if.h @@ -64,6 +64,7 @@ struct ifreq { union { struct sockaddr ifru_addr; struct sockaddr ifru_broadaddr; + struct sockaddr ifru_dstaddr; struct sockaddr ifru_netmask; struct sockaddr ifru_hwaddr; int ifru_flags; @@ -80,6 +81,7 @@ struct ifreq { #define ifr_name ifr_ifrn.ifrn_name /* interface name */ #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ +#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* destination address */ #define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ #define ifr_flags ifr_ifru.ifru_flags /* flags */ #define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ diff --git a/winsup/cygwin/include/cygwin/in.h b/winsup/cygwin/include/cygwin/in.h index 0fd9e92c4..30ac623a8 100644 --- a/winsup/cygwin/include/cygwin/in.h +++ b/winsup/cygwin/include/cygwin/in.h @@ -197,35 +197,35 @@ struct sockaddr_in * On subnets, host and network parts are found according * to the subnet mask, not these masks. */ -#define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0) +#define IN_CLASSA(a) ((((in_addr_t) (a)) & 0x80000000) == 0) #define IN_CLASSA_NET 0xff000000 #define IN_CLASSA_NSHIFT 24 #define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) #define IN_CLASSA_MAX 128 -#define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000) +#define IN_CLASSB(a) ((((in_addr_t) (a)) & 0xc0000000) == 0x80000000) #define IN_CLASSB_NET 0xffff0000 #define IN_CLASSB_NSHIFT 16 #define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) #define IN_CLASSB_MAX 65536 -#define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000) +#define IN_CLASSC(a) ((((in_addr_t) (a)) & 0xe0000000) == 0xc0000000) #define IN_CLASSC_NET 0xffffff00 #define IN_CLASSC_NSHIFT 8 #define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) -#define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000) +#define IN_CLASSD(a) ((((in_addr_t) (a)) & 0xf0000000) == 0xe0000000) #define IN_MULTICAST(a) IN_CLASSD(a) #define IN_MULTICAST_NET 0xF0000000 -#define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xe0000000) == 0xe0000000) -#define IN_BADCLASS(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000) +#define IN_EXPERIMENTAL(a) ((((in_addr_t) (a)) & 0xe0000000) == 0xe0000000) +#define IN_BADCLASS(a) ((((in_addr_t) (a)) & 0xf0000000) == 0xf0000000) /* Address to accept any incoming messages. */ -#define INADDR_ANY ((unsigned long int) 0x00000000) +#define INADDR_ANY ((in_addr_t) 0x00000000) /* Address to send to all hosts. */ -#define INADDR_BROADCAST ((unsigned long int) 0xffffffff) +#define INADDR_BROADCAST ((in_addr_t) 0xffffffff) /* Address indicating an error return. */ #define INADDR_NONE 0xffffffff @@ -235,7 +235,7 @@ struct sockaddr_in /* Address to loopback in software to local host. */ #define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */ -#define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000) +#define IN_LOOPBACK(a) ((((in_addr_t) (a)) & 0xff000000) == 0x7f000000) /* Defines for Multicast INADDR */ #define INADDR_UNSPEC_GROUP 0xe0000000 /* 224.0.0.0 */ diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index dd316c5ea..2f443ef6d 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -1285,6 +1285,23 @@ convert_ifr_flags (u_long ws_flags) | ((ws_flags & WS_IFF_MULTICAST) << 8); } +static u_long +get_routedst (DWORD if_index) +{ + PMIB_IPFORWARDTABLE pift; + ULONG size = 0; + if (GetIpForwardTable (NULL, &size, FALSE) == ERROR_INSUFFICIENT_BUFFER + && (pift = (PMIB_IPFORWARDTABLE) alloca (size)) + && GetIpForwardTable (pift, &size, FALSE) == NO_ERROR) + for (DWORD i = 0; i < pift->dwNumEntries; ++i) + { + if (pift->table[i].dwForwardIfIndex == if_index + && pift->table[i].dwForwardMask == INADDR_BROADCAST) + return pift->table[i].dwForwardDest; + } + return INADDR_ANY; +} + /* * IFCONF XP SP1 and above. * Use IP Helpper function GetAdaptersAddresses. @@ -1364,6 +1381,20 @@ get_xp_ifconf (SOCKET s, struct ifconf *ifc, int what) &iie[iinf_idx].iiBroadcastAddress.AddressIn, sizeof (struct sockaddr_in)); break; + case SIOCGIFDSTADDR: + if (pap->IfType == IF_TYPE_PPP) + { + struct sockaddr_in *sa = (struct sockaddr_in *) + &ifr->ifr_dstaddr; + sa->sin_addr.s_addr = get_routedst (pap->IfIndex); + sa->sin_family = AF_INET; + sa->sin_port = 0; + } + else + memcpy (&ifr->ifr_addr, + &iie[iinf_idx].iiAddress.AddressIn, + sizeof (struct sockaddr_in)); + break; case SIOCGIFNETMASK: memcpy (&ifr->ifr_netmask, &iie[iinf_idx].iiNetmask.AddressIn, @@ -1565,6 +1596,17 @@ get_2k_ifconf (struct ifconf *ifc, int what) sa->sin_port = 0; #endif break; + case SIOCGIFDSTADDR: + sa = (struct sockaddr_in *) &ifr->ifr_dstaddr; + if (ifrow->dwType == MIB_IF_TYPE_PPP + || ifrow->dwType == MIB_IF_TYPE_SLIP) + sa->sin_addr.s_addr = + get_routedst (ipt->table[ip_cnt].dwIndex); + else + sa->sin_addr.s_addr = ipt->table[ip_cnt].dwAddr; + sa->sin_family = AF_INET; + sa->sin_port = 0; + break; case SIOCGIFNETMASK: sa = (struct sockaddr_in *) &ifr->ifr_netmask; sa->sin_addr.s_addr = ipt->table[ip_cnt].dwMask; @@ -1719,6 +1761,7 @@ get_nt_ifconf (struct ifconf *ifc, int what) break; case SIOCGIFCONF: case SIOCGIFADDR: + case SIOCGIFDSTADDR: sa = (struct sockaddr_in *) &ifr->ifr_addr; sa->sin_addr.s_addr = cygwin_inet_addr (dhcpaddress); @@ -1766,6 +1809,7 @@ get_nt_ifconf (struct ifconf *ifc, int what) break; case SIOCGIFCONF: case SIOCGIFADDR: + case SIOCGIFDSTADDR: sa = (struct sockaddr_in *) &ifr->ifr_addr; sa->sin_addr.s_addr = cygwin_inet_addr (ip); sa->sin_family = AF_INET; @@ -1845,6 +1889,7 @@ get_ifconf (SOCKET s, struct ifconf *ifc, int what) break; case SIOCGIFCONF: case SIOCGIFADDR: + case SIOCGIFDSTADDR: sa = (struct sockaddr_in *) &ifr->ifr_addr; sa->sin_addr.s_addr = htonl (INADDR_LOOPBACK); sa->sin_family = AF_INET;