Trivial implementation of SIOCGIFCOUNT.
If you search the archives, this was suggested and rejected
6 years ago. But there maybe legacy Unix applications that
could actually use it.

Signed-off-by: Stephen Hemminger <[EMAIL PROTECTED]>
---
 net/core/dev.c |   50 ++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 4dc93cc..6779aa4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1987,7 +1987,7 @@ int register_gifconf(unsigned int family, gifconf_func_t 
* gifconf)
  *     match.  --pb
  */
 
-static int dev_ifname(struct ifreq __user *arg)
+static int dev_ifname(void __user *arg)
 {
        struct net_device *dev;
        struct ifreq ifr;
@@ -2020,7 +2020,7 @@ static int dev_ifname(struct ifreq __user *arg)
  *     Thus we will need a 'compatibility mode'.
  */
 
-static int dev_ifconf(char __user *arg)
+static int dev_ifconf(void __user *arg)
 {
        struct ifconf ifc;
        struct net_device *dev;
@@ -2071,6 +2071,32 @@ static int dev_ifconf(char __user *arg)
        return copy_to_user(arg, &ifc, sizeof(struct ifconf)) ? -EFAULT : 0;
 }
 
+/*
+ *     Perform SIOCGIFCONF give estimate of number of interfaces.
+ *     This show the poor design of Berkeley ioctl interface because number
+ *     of interfaces can change at any time.
+ */
+static int dev_ifcount(char __user *arg)
+{
+       struct ifconf ifc;
+       struct net_device *dev;
+       int i, total = 0;
+
+       for (dev = dev_base; dev; dev = dev->next)
+               for (i = 0; i < NPROTO; i++)
+                       if (gifconf_list[i]) {
+                               int done = gifconf_list[i](dev, NULL, 0);
+                               if (done > 0)
+                                       total += done;
+                                       
+               }
+
+       memset(&ifc, 0, sizeof(ifc));
+       ifc.ifc_len = total;
+       return copy_to_user(arg, &ifc, sizeof(struct ifconf)) ? -EFAULT : 0;
+}
+
+
 #ifdef CONFIG_PROC_FS
 /*
  *     This is invoked by the /proc filesystem handler to display a device
@@ -2643,19 +2669,23 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
        int ret;
        char *colon;
 
-       /* One special case: SIOCGIFCONF takes ifconf argument
-          and requires shared lock, because it sleeps writing
-          to user space.
-        */
+       /* Special case ioctl's that don't relate to a specific device */
+       switch(cmd) {
+       case SIOCGIFCONF:
+               rtnl_lock();
+               ret = dev_ifconf(arg);
+               rtnl_unlock();
+               return ret;
 
-       if (cmd == SIOCGIFCONF) {
+       case SIOCGIFCOUNT:
                rtnl_lock();
-               ret = dev_ifconf((char __user *) arg);
+               ret = dev_ifcount(arg);
                rtnl_unlock();
                return ret;
+
+       case SIOCGIFNAME:
+               return dev_ifname(arg);
        }
-       if (cmd == SIOCGIFNAME)
-               return dev_ifname((struct ifreq __user *)arg);
 
        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
                return -EFAULT;
-- 
1.5.0.6

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to