SIOCGIFCONF patch

Alexander Gottwald Alexander.Gottwald@s1999.tu-chemnitz.de
Sun Nov 10 04:41:00 GMT 2002


Corinna Vinschen wrote:

> So, I actually would like
> to ask you to take this part out.  As soon as you send the tweaked patch,
> I'll check it in.

Done

2002-11-10  Alexander Gottwald <Alexander.Gottwald@s1999.tu-chemnitz.de>

    * net.cc (get_2k_ifconf): Get the interface entries with the GetIfEntry 
    call intead of the GetIfTable call. Clean-up multiple IP address naming.

bye
    ago
-- 
 Alexander.Gottwald@informatik.tu-chemnitz.de 
 http://www.gotti.org           ICQ: 126018723
-------------- next part --------------
--- winsup/cygwin/net.cc.orig	Sun Oct  6 03:00:23 2002
+++ winsup/cygwin/net.cc	Sun Nov 10 13:37:31 2002
@@ -1216,125 +1216,170 @@ 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, lip, lnp;
   DWORD siz_ip_table = 0;
-  PMIB_IFTABLE ift;
   PMIB_IPADDRTABLE ipt;
+  PMIB_IFROW ifrow;
   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;
+      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
+      && (ifrow = (PMIB_IFROW) alloca (sizeof (MIB_IFROW)))
+      && (ipt = (PMIB_IPADDRTABLE) alloca (siz_ip_table))
+      && !GetIpAddrTable (ipt, &siz_ip_table, TRUE))
     {
-      /* 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->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;
+      
+      /* 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 = 1;
+	      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	Tue Sep 24 05:57:40 2002
+++ winsup/cygwin/autoload.cc	Sun Nov 10 13:33:24 2002
@@ -485,6 +485,7 @@ 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)
 
 LoadDLLfunc (CoInitialize, 4, ole32)


More information about the Cygwin-patches mailing list