--- winsup/cygwin/net.cc.orig Sat Nov 9 18:36:52 2002 +++ winsup/cygwin/net.cc Sat Nov 9 18:38:23 2002 @@ -1216,125 +1216,189 @@ static void get_2k_ifconf (struct ifconf *ifc, int what) { int cnt = 0; - char eth[2] = "/", ppp[2] = "/", slp[2] = "/", sub[2] = "0", tok[2] = "/"; + int ethId = 0, pppId = 0, slpId = 0, tokId = 0; /* Union maps buffer to correct struct */ struct ifreq *ifr = ifc->ifc_req; - DWORD if_cnt, ip_cnt, lip, lnp; - DWORD siz_if_table = 0; + DWORD ip_cnt, ipf_cnt, lip, lnp; DWORD siz_ip_table = 0; - PMIB_IFTABLE ift; + DWORD siz_ipfwd_table = 0; PMIB_IPADDRTABLE ipt; + PMIB_IFROW ifrow; + PMIB_IPFORWARDTABLE ipfwdt; struct sockaddr_in *sa = NULL; struct sockaddr *so = NULL; - if (GetIfTable (NULL, &siz_if_table, TRUE) == ERROR_INSUFFICIENT_BUFFER && - GetIpAddrTable (NULL, &siz_ip_table, TRUE) == ERROR_INSUFFICIENT_BUFFER && - (ift = (PMIB_IFTABLE) alloca (siz_if_table)) && - (ipt = (PMIB_IPADDRTABLE) alloca (siz_ip_table)) && - !GetIfTable (ift, &siz_if_table, TRUE) && - !GetIpAddrTable (ipt, &siz_ip_table, TRUE)) + typedef struct ifcount_t { + DWORD ifIndex; + DWORD routeIndex; + DWORD metric; + size_t count; + unsigned int enumerated; // for eth0:1 + unsigned int classId; // for eth0, tok0 ... + + }; + ifcount_t *iflist, *ifEntry; + + if (GetIpAddrTable (NULL, &siz_ip_table, TRUE) == ERROR_INSUFFICIENT_BUFFER + && GetIpForwardTable(NULL, &siz_ipfwd_table, FALSE) == ERROR_INSUFFICIENT_BUFFER + && (ifrow = (PMIB_IFROW) alloca (sizeof (MIB_IFROW))) + && (ipt = (PMIB_IPADDRTABLE) alloca (siz_ip_table)) + && (ipfwdt = (PMIB_IPFORWARDTABLE) alloca (siz_ipfwd_table)) + && !GetIpAddrTable (ipt, &siz_ip_table, TRUE) + && !GetIpForwardTable(ipfwdt, &siz_ipfwd_table, FALSE)) { - /* Iterate over all known interfaces */ - for (if_cnt = 0; if_cnt < ift->dwNumEntries; ++if_cnt) + iflist = (ifcount_t *)alloca(sizeof(ifcount_t) * (ipt->dwNumEntries + 1)); + memset(iflist, 0, sizeof(ifcount_t) * (ipt->dwNumEntries + 1)); + for (ip_cnt = 0; ip_cnt < ipt->dwNumEntries; ++ip_cnt) + { + ifEntry = iflist; + /* search for matching entry (and stop at first free entry) */ + while (ifEntry->count != 0) { + if (ifEntry->ifIndex == ipt->table[ip_cnt].dwIndex) + break; + ifEntry++; + } + if (ifEntry->count == 0) { + ifEntry->count = 1; + ifEntry->metric = 1; + ifEntry->ifIndex = ipt->table[ip_cnt].dwIndex; + } else { + ifEntry->count++; + } + } + // reset the last element. This is just the stopper for the loop. + iflist[ipt->dwNumEntries].count = 0; + + ifEntry = iflist; + while (ifEntry->count > 0) { + for (ipf_cnt = 0; ipf_cnt < ipfwdt->dwNumEntries; ++ipf_cnt) + if (ipfwdt->table[ipf_cnt].dwForwardIfIndex == ifEntry->ifIndex) { + ifEntry->routeIndex = ipf_cnt; + ifEntry->metric = ipfwdt->table[ipf_cnt].dwForwardMetric1; + break; + } + ifEntry++; + } + + /* Iterate over all configured IP-addresses */ + for (ip_cnt = 0; ip_cnt < ipt->dwNumEntries; ++ip_cnt) { - *sub = '0'; - /* Iterate over all configured IP-addresses */ - for (ip_cnt = 0; ip_cnt < ipt->dwNumEntries; ++ip_cnt) + memset (ifrow, 0, sizeof (MIB_IFROW)); + ifrow->dwIndex = ipt->table[ip_cnt].dwIndex; + if (GetIfEntry (ifrow) != NO_ERROR) + continue; + + ifcount_t *ifEntry = iflist; + /* search for matching entry (and stop at first free entry) */ + while (ifEntry->count != 0) { + if (ifEntry->ifIndex == ipt->table[ip_cnt].dwIndex) + break; + ifEntry++; + } + + /* Setup the interface name */ + switch (ifrow->dwType) { - /* Does the IP address belong to the interface? */ - if (ipt->table[ip_cnt].dwIndex == ift->table[if_cnt].dwIndex) - { - /* Setup the interface name */ - switch (ift->table[if_cnt].dwType) - { - case MIB_IF_TYPE_TOKENRING: - ++*tok; - strcpy (ifr->ifr_name, "tok"); - strcat (ifr->ifr_name, tok); - break; - case MIB_IF_TYPE_ETHERNET: - if (*sub == '0') - ++*eth; - strcpy (ifr->ifr_name, "eth"); - strcat (ifr->ifr_name, eth); - break; - case MIB_IF_TYPE_PPP: - ++*ppp; - strcpy (ifr->ifr_name, "ppp"); - strcat (ifr->ifr_name, ppp); - break; - case MIB_IF_TYPE_SLIP: - ++*slp; - strcpy (ifr->ifr_name, "slp"); - strcat (ifr->ifr_name, slp); - break; - case MIB_IF_TYPE_LOOPBACK: - strcpy (ifr->ifr_name, "lo"); - break; - default: - continue; - } - if (*sub > '0') - { - strcat (ifr->ifr_name, ":"); - strcat (ifr->ifr_name, sub); - } - ++*sub; - /* setup sockaddr struct */ - switch (what) - { - case SIOCGIFCONF: - case SIOCGIFADDR: - sa = (struct sockaddr_in *) &ifr->ifr_addr; - sa->sin_addr.s_addr = ipt->table[ip_cnt].dwAddr; - sa->sin_family = AF_INET; - sa->sin_port = 0; - break; - case SIOCGIFBRDADDR: - sa = (struct sockaddr_in *) &ifr->ifr_broadaddr; + case MIB_IF_TYPE_TOKENRING: + if (ifEntry->enumerated == 0) { + ifEntry->classId = tokId++; + __small_sprintf(ifr->ifr_name, "tok%u", ifEntry->classId); + } else { + __small_sprintf(ifr->ifr_name, "tok%u:%u", ifEntry->classId, + ifEntry->enumerated-1); + } + ifEntry->enumerated++; + break; + case MIB_IF_TYPE_ETHERNET: + if (ifEntry->enumerated == 0) { + ifEntry->classId = ethId++; + __small_sprintf(ifr->ifr_name, "eth%u", ifEntry->classId); + } else { + __small_sprintf(ifr->ifr_name, "eth%u:%u", ifEntry->classId, + ifEntry->enumerated-1); + } + ifEntry->enumerated++; + break; + case MIB_IF_TYPE_PPP: + if (ifEntry->enumerated == 0) { + ifEntry->classId = pppId++; + __small_sprintf(ifr->ifr_name, "ppp%u", ifEntry->classId); + } else { + __small_sprintf(ifr->ifr_name, "ppp%u:%u", ifEntry->classId, + ifEntry->enumerated-1); + } + ifEntry->enumerated++; + break; + case MIB_IF_TYPE_SLIP: + if (ifEntry->enumerated == 0) { + ifEntry->classId = slpId++; + __small_sprintf(ifr->ifr_name, "slp%u", ifEntry->classId); + } else { + __small_sprintf(ifr->ifr_name, "slp%u:%u", ifEntry->classId, + ifEntry->enumerated-1); + } + ifEntry->enumerated++; + break; + case MIB_IF_TYPE_LOOPBACK: + strcpy (ifr->ifr_name, "lo"); + break; + default: + continue; + } + /* setup sockaddr struct */ + switch (what) + { + case SIOCGIFCONF: + case SIOCGIFADDR: + sa = (struct sockaddr_in *) &ifr->ifr_addr; + sa->sin_addr.s_addr = ipt->table[ip_cnt].dwAddr; + sa->sin_family = AF_INET; + sa->sin_port = 0; + break; + case SIOCGIFBRDADDR: + sa = (struct sockaddr_in *) &ifr->ifr_broadaddr; #if 0 - /* Unfortunately, the field returns only crap. */ - sa->sin_addr.s_addr = ipt->table[ip_cnt].dwBCastAddr; + /* Unfortunately, the field returns only crap. */ + sa->sin_addr.s_addr = ipt->table[ip_cnt].dwBCastAddr; #else - lip = ipt->table[ip_cnt].dwAddr; - lnp = ipt->table[ip_cnt].dwMask; - sa->sin_addr.s_addr = lip & lnp | ~lnp; - sa->sin_family = AF_INET; - sa->sin_port = 0; + lip = ipt->table[ip_cnt].dwAddr; + lnp = ipt->table[ip_cnt].dwMask; + sa->sin_addr.s_addr = lip & lnp | ~lnp; + sa->sin_family = AF_INET; + sa->sin_port = 0; #endif - break; - case SIOCGIFNETMASK: - sa = (struct sockaddr_in *) &ifr->ifr_netmask; - sa->sin_addr.s_addr = ipt->table[ip_cnt].dwMask; - sa->sin_family = AF_INET; - sa->sin_port = 0; - break; - case SIOCGIFHWADDR: - so = &ifr->ifr_hwaddr; - for (UINT i = 0; i < IFHWADDRLEN; ++i) - if (i >= ift->table[if_cnt].dwPhysAddrLen) - so->sa_data[i] = '\0'; - else - so->sa_data[i] = ift->table[if_cnt].bPhysAddr[i]; - so->sa_family = AF_INET; - break; - case SIOCGIFMETRIC: - ifr->ifr_metric = 1; - break; - case SIOCGIFMTU: - ifr->ifr_mtu = ift->table[if_cnt].dwMtu; - break; - } - ++cnt; - if ((caddr_t) ++ifr > - ifc->ifc_buf + ifc->ifc_len - sizeof (struct ifreq)) - goto done; - } + break; + case SIOCGIFNETMASK: + sa = (struct sockaddr_in *) &ifr->ifr_netmask; + sa->sin_addr.s_addr = ipt->table[ip_cnt].dwMask; + sa->sin_family = AF_INET; + sa->sin_port = 0; + break; + case SIOCGIFHWADDR: + so = &ifr->ifr_hwaddr; + for (UINT i = 0; i < IFHWADDRLEN; ++i) + if (i >= ifrow->dwPhysAddrLen) + so->sa_data[i] = '\0'; + else + so->sa_data[i] = ifrow->bPhysAddr[i]; + so->sa_family = AF_INET; + break; + case SIOCGIFMETRIC: + ifr->ifr_metric = ifEntry->metric; + break; + case SIOCGIFMTU: + ifr->ifr_mtu = ifrow->dwMtu; + break; } + ++cnt; + if ((caddr_t)++ ifr > + ifc->ifc_buf + ifc->ifc_len - sizeof (struct ifreq)) + goto done; } } + done: /* Set the correct length */ ifc->ifc_len = cnt * sizeof (struct ifreq); --- winsup/cygwin/autoload.cc.orig Sat Nov 9 18:36:52 2002 +++ winsup/cygwin/autoload.cc Sat Nov 9 18:42:17 2002 @@ -485,7 +485,9 @@ LoadDLLfuncEx (WSAEventSelect, 12, ws2_3 LoadDLLfuncEx (WSAEnumNetworkEvents, 12, ws2_32, 1) LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1) +LoadDLLfuncEx (GetIfEntry, 4, iphlpapi, 1) LoadDLLfuncEx (GetIpAddrTable, 12, iphlpapi, 1) +LoadDLLfuncEx (GetIpForwardTable, 12, iphlpapi, 1) LoadDLLfunc (CoInitialize, 4, ole32) LoadDLLfunc (CoUninitialize, 0, ole32)