]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/net/if_media.c
xnu-344.49.tar.gz
[apple/xnu.git] / bsd / net / if_media.c
index 59778216b5220aadd65b950b05648026e66780c1..249f394e193df1cc40c5b3286e4dda3cb3a58879 100644 (file)
@@ -3,23 +3,27 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @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 +113,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 +150,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 +294,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 +305,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 +332,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 +388,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) {