]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/if_media.c
xnu-344.tar.gz
[apple/xnu.git] / bsd / net / if_media.c
index 59778216b5220aadd65b950b05648026e66780c1..ed5ec87ab3546dbfd390db869db01662c7ca54cd 100644 (file)
@@ -20,6 +20,7 @@
  * @APPLE_LICENSE_HEADER_END@
  */
 /*     $NetBSD: if_media.c,v 1.1 1997/03/17 02:55:15 thorpej Exp $     */
+/* $FreeBSD: src/sys/net/if_media.c,v 1.9.2.4 2001/07/04 00:12:38 brooks Exp $ */
 
 /*
  * Copyright (c) 1997
@@ -109,6 +110,19 @@ ifmedia_init(ifm, dontcare_mask, change_callback, status_callback)
        ifm->ifm_status = status_callback;
 }
 
+void
+ifmedia_removeall(ifm)
+       struct ifmedia *ifm;
+{
+       struct ifmedia_entry *entry;
+
+       for (entry = LIST_FIRST(&ifm->ifm_list); entry;
+            entry = LIST_FIRST(&ifm->ifm_list)) {
+               LIST_REMOVE(entry, ifm_list);
+               FREE(entry, M_IFADDR);
+       }
+}
+
 /*
  * Add a media configuration to the list of supported media
  * for a specific interface instance.
@@ -133,7 +147,7 @@ ifmedia_add(ifm, mword, data, aux)
        }
 #endif
 
-       entry = _MALLOC(sizeof(*entry), M_IFADDR, M_WAITOK);
+       entry = _MALLOC(sizeof(*entry), M_IFADDR, M_NOWAIT);
        if (entry == NULL)
                panic("ifmedia_add: can't malloc entry");
 
@@ -277,6 +291,7 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd)
        {
                struct ifmedia_entry *ep;
                int *kptr, count;
+               int usermax;    /* user requested max */
 
                kptr = NULL;            /* XXX gcc */
 
@@ -287,7 +302,25 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd)
                (*ifm->ifm_status)(ifp, ifmr);
 
                count = 0;
-               ep = ifm->ifm_list.lh_first;
+               usermax = 0;
+
+               /*
+                * If there are more interfaces on the list, count
+                * them.  This allows the caller to set ifmr->ifm_count
+                * to 0 on the first call to know how much space to
+                * allocate.
+                */
+               LIST_FOREACH(ep, &ifm->ifm_list, ifm_list)
+                       usermax++;
+
+               /*
+                * Don't allow the user to ask for too many
+                * or a negative number.
+                */
+               if (ifmr->ifm_count > usermax)
+                       ifmr->ifm_count = usermax;
+               else if (ifmr->ifm_count < 0)
+                       return (EINVAL);
 
                if (ifmr->ifm_count != 0) {
                        kptr = (int *) _MALLOC(ifmr->ifm_count * sizeof(int),
@@ -296,23 +329,17 @@ ifmedia_ioctl(ifp, ifr, ifm, cmd)
                        /*
                         * Get the media words from the interface's list.
                         */
+                       ep = LIST_FIRST(&ifm->ifm_list);
                        for (; ep != NULL && count < ifmr->ifm_count;
-                           ep = ep->ifm_list.le_next, count++)
+                           ep = LIST_NEXT(ep, ifm_list), count++)
                                kptr[count] = ep->ifm_media;
 
                        if (ep != NULL)
                                error = E2BIG;  /* oops! */
+               } else {
+                       count = usermax;
                }
 
-               /*
-                * If there are more interfaces on the list, count
-                * them.  This allows the caller to set ifmr->ifm_count
-                * to 0 on the first call to know how much space to
-                * callocate.
-                */
-               for (; ep != NULL; ep = ep->ifm_list.le_next)
-                       count++;
-
                /*
                 * We do the copyout on E2BIG, because that's
                 * just our way of telling userland that there
@@ -358,8 +385,7 @@ ifmedia_match(ifm, target, mask)
        match = NULL;
        mask = ~mask;
 
-       for (next = ifm->ifm_list.lh_first; next != NULL;
-           next = next->ifm_list.le_next) {
+       LIST_FOREACH(next, &ifm->ifm_list, ifm_list) {
                if ((next->ifm_media & mask) == (target & mask)) {
 #if defined(IFMEDIA_DEBUG) || defined(DIAGNOSTIC)
                        if (match) {