diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2007-01-22 01:54:05 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2007-01-22 01:54:05 +0300 |
commit | bff438913761968193960dc32b1db372ebe509ee (patch) | |
tree | ea2cb2770237834082201c46df2fdd9108b0562b /winsup/cygwin/fhandler_socket.cc | |
parent | f89533c1ffb2ff780ad8e678a1cd9c7e6035725f (diff) |
* autoload.cc (WSAIoctl): Define.
(SendARP): Define.
* cygwin.din: Export if_freenameindex, if_indextoname, if_nameindex and
if_nametoindex.
* fhandler_procnet.cc: Drop including wchar.h. Drop definitions of
GAA_FLAG_INCLUDE_ALL_INTERFACES, IP_ADAPTER_UNICAST_ADDRESS_VISTA.
(fhandler_procnet::exists): Check for has_gaa_prefixes. Call
get_adapters_addresses here.
(fhandler_procnet::readdir): Ditto.
(prefix): Move to net.cc.
(fhandler_procnet::fill_filebuf): Call get_adapters_addresses here.
Simplify allocation. Use AdapterName rather than FriendlyName as
interface name. Use IfIndex if available, Ipv6IfIndex otherwise.
(in6_are_prefix_equal): Move to net.cc.
* fhandler_socket.cc: Define old SIOCGxxx values.
(CONV_OLD_TO_NEW_SIO): Convert old SIOCGxxx value to new one.
(struct __old_ifreq): Define old struct ifreq.
(fhandler_socket::ioctl): Handle old SIOCGxxx values. Handle new
SIOCGIFFRNDLYNAM command. Simplify copying ifreq data to user space.
Call get_ifconf with additional SOCKET parameter.
* net.cc (IP_ADAPTER_UNICAST_ADDRESS_LH): Define.
(IP_ADAPTER_ADDRESSES_LH): Define.
(SIO_GET_INTERFACE_LIST): Define.
(sockaddr_in6_old): Define.
(sockaddr_gen): Define.
(INTERFACE_INFO): Define.
(IN_LOOPBACK): Define.
(in_are_prefix_equal): New static function.
(ip_addr_prefix): New function, replaces prefix function, add AF_INET
handling.
(GAA_FLAG_INCLUDE_ALL_INTERFACES): Define.
(get_adapters_addresses): New function.
(WS_IFF_xxx): Define Winsock interface flag values.
(convert_ifr_flags): New function to convert Winsock interface flag
values to Cygwin interface flag values.
(get_xp_ifconf): New get_ifconf implementation for XP SP1 and above.
(get_2k_ifconf): Fix interface index. Fix formatting.
(get_nt_ifconf): Fix formatting.
(get_95_ifconf): Ditto.
(get_ifconf): Take additional SOCKET parameter. Call get_xp_ifconf
on XP SP1 and above.
(if_nametoindex): New function.
(if_indextoname): New function.
(if_nameindex): New function.
(if_freenameindex): New function.
(in6_are_prefix_equal): Moved here from fhandler_procnet.cc.
* wincap.cc (wincap_xp): Define has_gaa_prefixes as true by default.
(wincapc::init): Assume has_osversioninfoex by default. Call
GetVersionEx with OSVERSIONINFOEX first. Call with OSVERSIONINFO only
if that fails. Simplify NT4 case and try to avoid strcmp. Check XP
Service Pack using version.wServicePackMajor to avoid strcmp.
* include/asm/socket.h (SIOCGIFFRNDLYNAM): Define.
* include/cygwin/if.h: Fix formatting.
(IFF_POINTTOPOINT): Define.
(IFF_NOARP): Define.
(IFF_LOWER_UP): Define.
(IFF_DORMANT): Define.
(struct if_nameindex): Define.
(IFRF_FRIENDLYNAMESIZ): Define.
(struct ifreq_frndlyname): Define.
(IFNAMSIZ): Redefine as 44.
(IF_NAMESIZE): Define.
(struct ifreq): Redefine ifru_flags as int. Define ifru_data. Pad size
to sizeof sockaddr_in6 for further extensions.
(ifr_data): Define.
(ifr_frndlyname): Define.
(if_nametoindex): Declare.
(if_indextoname): Declare.
(if_nameindex): Declare.
(if_freenameindex): Declare.
* include/cygwin/version.h: Bump API minor number.
(CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ): Define check for old vs. new
ifreq structure.
Diffstat (limited to 'winsup/cygwin/fhandler_socket.cc')
-rw-r--r-- | winsup/cygwin/fhandler_socket.cc | 159 |
1 files changed, 120 insertions, 39 deletions
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 0ef0f593d..1dadb9604 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -1391,13 +1391,43 @@ fhandler_socket::close () return res; } +/* Definitions of old ifreq stuff used prior to Cygwin 1.7.0. */ +#define OLD_SIOCGIFFLAGS _IOW('s', 101, struct __old_ifreq) +#define OLD_SIOCGIFADDR _IOW('s', 102, struct __old_ifreq) +#define OLD_SIOCGIFBRDADDR _IOW('s', 103, struct __old_ifreq) +#define OLD_SIOCGIFNETMASK _IOW('s', 104, struct __old_ifreq) +#define OLD_SIOCGIFHWADDR _IOW('s', 105, struct __old_ifreq) +#define OLD_SIOCGIFMETRIC _IOW('s', 106, struct __old_ifreq) +#define OLD_SIOCGIFMTU _IOW('s', 107, struct __old_ifreq) +#define OLD_SIOCGIFINDEX _IOW('s', 108, struct __old_ifreq) + +#define CONV_OLD_TO_NEW_SIO(old) (((old)&0xff00ffff)|(((long)sizeof(struct ifreq)&IOCPARM_MASK)<<16)) + +struct __old_ifreq { +#define __OLD_IFNAMSIZ 16 + union { + char ifrn_name[__OLD_IFNAMSIZ]; /* if name, e.g. "en0" */ + } ifr_ifrn; + + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_broadaddr; + struct sockaddr ifru_netmask; + struct sockaddr ifru_hwaddr; + short ifru_flags; + int ifru_metric; + int ifru_mtu; + int ifru_ifindex; + } ifr_ifru; +}; + int fhandler_socket::ioctl (unsigned int cmd, void *p) { - extern int get_ifconf (struct ifconf *ifc, int what); /* net.cc */ + extern int get_ifconf (SOCKET s, struct ifconf *ifc, int what); /* net.cc */ int res; struct ifconf ifc, *ifcp; - struct ifreq *ifr, *ifrp; + struct ifreq *ifrp; switch (cmd) { @@ -1408,10 +1438,47 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) set_errno (EINVAL); return -1; } - res = get_ifconf (ifcp, cmd); + if (CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ) + { + ifc.ifc_len = ifcp->ifc_len / sizeof (struct __old_ifreq) + * sizeof (struct ifreq); + ifc.ifc_buf = (caddr_t) alloca (ifc.ifc_len); + } + else + { + ifc.ifc_len = ifcp->ifc_len; + ifc.ifc_buf = ifcp->ifc_buf; + } + res = get_ifconf (get_socket (), &ifc, cmd); if (res) debug_printf ("error in get_ifconf"); + if (CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ) + { + struct __old_ifreq *ifr = (struct __old_ifreq *) ifcp->ifc_buf; + for (ifrp = ifc.ifc_req; + (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len; + ++ifrp, ++ifr) + { + memcpy (&ifr->ifr_ifrn, &ifrp->ifr_ifrn, sizeof ifr->ifr_ifrn); + ifr->ifr_name[__OLD_IFNAMSIZ - 1] = '\0'; + memcpy (&ifr->ifr_ifru, &ifrp->ifr_ifru, sizeof ifr->ifr_ifru); + } + ifcp->ifc_len = ifc.ifc_len / sizeof (struct ifreq) + * sizeof (struct __old_ifreq); + } + else + ifcp->ifc_len = ifc.ifc_len; break; + case OLD_SIOCGIFFLAGS: + case OLD_SIOCGIFADDR: + case OLD_SIOCGIFBRDADDR: + case OLD_SIOCGIFNETMASK: + case OLD_SIOCGIFHWADDR: + case OLD_SIOCGIFMETRIC: + case OLD_SIOCGIFMTU: + case OLD_SIOCGIFINDEX: + cmd = CONV_OLD_TO_NEW_SIO (cmd); + /*FALLTHRU*/ case SIOCGIFFLAGS: case SIOCGIFBRDADDR: case SIOCGIFNETMASK: @@ -1420,61 +1487,75 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) case SIOCGIFMETRIC: case SIOCGIFMTU: case SIOCGIFINDEX: + case SIOCGIFFRNDLYNAM: { - ifc.ifc_len = 2048; - ifc.ifc_buf = (char *) alloca (2048); - - ifr = (struct ifreq *) p; - if (ifr == 0) + if (!p) { debug_printf ("ifr == NULL"); set_errno (EINVAL); return -1; } - res = get_ifconf (&ifc, cmd); + if (cmd > SIOCGIFINDEX && CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ) + { + debug_printf ("cmd not supported on this platform"); + set_errno (EINVAL); + return -1; + } + ifc.ifc_len = 64 * sizeof (struct ifreq); + ifc.ifc_buf = (caddr_t) alloca (ifc.ifc_len); + if (cmd == SIOCGIFFRNDLYNAM) + { + struct ifreq_frndlyname *iff = (struct ifreq_frndlyname *) + alloca (64 * sizeof (struct ifreq_frndlyname)); + for (int i = 0; i < 64; ++i) + ifc.ifc_req[i].ifr_frndlyname = &iff[i]; + } + + res = get_ifconf (get_socket (), &ifc, cmd); if (res) { debug_printf ("error in get_ifconf"); break; } - debug_printf (" name: %s", ifr->ifr_name); - for (ifrp = ifc.ifc_req; - (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len; - ++ifrp) + if (CYGWIN_VERSION_CHECK_FOR_OLD_IFREQ) { - debug_printf ("testname: %s", ifrp->ifr_name); - if (! strcmp (ifrp->ifr_name, ifr->ifr_name)) + struct __old_ifreq *ifr = (struct __old_ifreq *) p; + debug_printf (" name: %s", ifr->ifr_name); + for (ifrp = ifc.ifc_req; + (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len; + ++ifrp) { - switch (cmd) + debug_printf ("testname: %s", ifrp->ifr_name); + if (! strcmp (ifrp->ifr_name, ifr->ifr_name)) { - case SIOCGIFFLAGS: - ifr->ifr_flags = ifrp->ifr_flags; - break; - case SIOCGIFADDR: - ifr->ifr_addr = ifrp->ifr_addr; - break; - case SIOCGIFBRDADDR: - ifr->ifr_broadaddr = ifrp->ifr_broadaddr; - break; - case SIOCGIFNETMASK: - ifr->ifr_netmask = ifrp->ifr_netmask; - break; - case SIOCGIFHWADDR: - ifr->ifr_hwaddr = ifrp->ifr_hwaddr; - break; - case SIOCGIFMETRIC: - ifr->ifr_metric = ifrp->ifr_metric; + memcpy (&ifr->ifr_ifru, &ifrp->ifr_ifru, + sizeof ifr->ifr_ifru); break; - case SIOCGIFMTU: - ifr->ifr_mtu = ifrp->ifr_mtu; - break; - case SIOCGIFINDEX: - ifr->ifr_ifindex = ifrp->ifr_ifindex; + } + } + } + else + { + struct ifreq *ifr = (struct ifreq *) p; + debug_printf (" name: %s", ifr->ifr_name); + for (ifrp = ifc.ifc_req; + (caddr_t) ifrp < ifc.ifc_buf + ifc.ifc_len; + ++ifrp) + { + debug_printf ("testname: %s", ifrp->ifr_name); + if (! strcmp (ifrp->ifr_name, ifr->ifr_name)) + { + if (cmd == SIOCGIFFRNDLYNAM) + /* The application has to care for the space. */ + memcpy (ifr->ifr_frndlyname, ifrp->ifr_frndlyname, + sizeof (struct ifreq_frndlyname)); + else + memcpy (&ifr->ifr_ifru, &ifrp->ifr_ifru, + sizeof ifr->ifr_ifru); break; } - break; } } if ((caddr_t) ifrp >= ifc.ifc_buf + ifc.ifc_len) |