Annotation of XNU/iokit/Families/IONetworking/IONetworkInterface.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1999 Apple Computer, Inc.  All rights reserved. 
                     24:  *
                     25:  * IONetworkInterface.cpp
                     26:  *
                     27:  * HISTORY
                     28:  * 8-Jan-1999       Joe Liu (jliu) created.
                     29:  *
                     30:  */
                     31: 
                     32: #include <IOKit/assert.h>
                     33: #include <IOKit/IOLib.h>
                     34: #include <IOKit/IOMessage.h>
                     35: #include <IOKit/network/IONetworkInterface.h>
                     36: #include <IOKit/network/IONetworkController.h>
                     37: #include <IOKit/network/IONetworkUserClient.h>
                     38: 
                     39: extern "C" {
                     40: #include <sys/param.h>
                     41: #include <sys/mbuf.h>
                     42: #include <sys/socket.h>
                     43: #include <sys/sockio.h>
                     44: #include <net/bpf.h>
                     45: #include <net/if.h>
                     46: #include <netinet/if_ether.h>
                     47: #include <net/if_media.h>
                     48: #include <net/dlil.h>
                     49: int copyout(void *kaddr, void *udaddr, size_t len);
                     50: }
                     51: 
                     52: //---------------------------------------------------------------------------
                     53: 
                     54: #define super IOService
                     55: 
                     56: OSDefineMetaClass( IONetworkInterface, IOService )
                     57: OSDefineAbstractStructors( IONetworkInterface, IOService )
                     58: 
                     59: //---------------------------------------------------------------------------
                     60: // Macros
                     61: 
                     62: #ifdef  DEBUG
                     63: #define DLOG(fmt, args...)  IOLog(fmt, ## args)
                     64: #else
                     65: #define DLOG
                     66: #endif
                     67: 
                     68: //---------------------------------------------------------------------------
                     69: // Initialize an IONetworkInterface instance.
                     70: //
                     71: // properties: A property dictionary.
                     72: //
                     73: // Returns true if initialized successfully, false otherwise.
                     74: 
                     75: bool IONetworkInterface::init(OSDictionary * properties = 0)
                     76: {
                     77:     _provider         = 0;      // single IONetworkController provider.
                     78:     _ifLock           = 0;      // locks interface state and data accesses.
                     79:     _clientSet        = 0;      // A set of all client objects.
                     80:     _inputFilterFunc  = 0;      // input filter tap handler.
                     81:     _outputFilterFunc = 0;      // output filter tap handler.
                     82:     _target           = 0;      // output target object.
                     83:     _outAction        = 0;      // output packet action.
                     84:     _dataDict         = 0;      // IONetworkData dict. 
                     85:     _registered       = false;
                     86: 
                     87:     inputQHead = inputQTail = 0;
                     88: 
                     89:     // Propagate the init() call to our superclass.
                     90:     //
                     91:     if (!super::init(properties))
                     92:         return false;
                     93: 
                     94:     // Create interface lock.
                     95:     //
                     96:     _ifLock = IORecursiveLockAlloc();
                     97:     if (!_ifLock)
                     98:         return false;
                     99: 
                    100:     // Create an OSSet to store client objects. Initial capacity
                    101:     // (which can grow) is set at 2 clients.
                    102:     //
                    103:     _clientSet = OSSet::withCapacity(2);
                    104:     if (!_clientSet)
                    105:         return false;
                    106: 
                    107:     // Get the ifnet structure of the network interface. Subclasses must
                    108:     // implement getIfnet() and expect this function to be called when
                    109:     // they call IONetworkInterface::init().
                    110:     //
                    111:     _ifp = getIfnet();
                    112:     if (!_ifp)
                    113:     {
                    114:         DLOG("%s: getIfnet() returned NULL\n", getName());
                    115:         return false;
                    116:     }
                    117: 
                    118:     // Intialize the ifnet structure.
                    119:     //
                    120:     if (!initIfnet(_ifp))
                    121:         return false;
                    122: 
                    123:     // Create a data dictionary.
                    124:     //
                    125:     if ((_dataDict = OSDictionary::withCapacity(5)) == 0)
                    126:         return false;
                    127: 
                    128:     IONetworkData * data = IONetworkData::withName(
                    129:                                     kIONetworkStatsKey,
                    130:                                     sizeof(IONetworkStats),
                    131:                                     (UInt8 *) &(_ifp->if_data.ifi_ipackets));
                    132:     if (data) {
                    133:         addNetworkData(data);
                    134:         data->release();
                    135:     }
                    136: 
                    137:     // Set the default filter tap mode for both directions to
                    138:     // kIOFilterTapModeInternal. Both taps will automatically receive all
                    139:     // packets that flow through the interface in their respective
                    140:     // directions.
                    141:     //
                    142:     _inputFilterTapMode = _outputFilterTapMode = kIOFilterTapModeInternal;
                    143: 
                    144:     return true;
                    145: }
                    146: 
                    147: //---------------------------------------------------------------------------
                    148: // Destroy the interface. Release all allocated resources.
                    149: 
                    150: void IONetworkInterface::free()
                    151: {
                    152:     DLOG("IONetworkInterface::free() called\n");
                    153: 
                    154:     // Must never free a registered interface.
                    155: 
                    156:     assert(_registered == false);
                    157: 
                    158:     if (_clientSet)
                    159:     {
                    160:         // Should not have any clients.
                    161:         //
                    162:         assert(_clientSet->getCount() == 0);
                    163:         _clientSet->release();
                    164:     }
                    165: 
                    166:     if (_ifLock)
                    167:     {
                    168:         IORecursiveLockFree(_ifLock);
                    169:         _ifLock = 0;
                    170:     }
                    171: 
                    172:     if (_dataDict)
                    173:         _dataDict->release();
                    174: 
                    175:     clearInputQueue();
                    176: 
                    177:     super::free();
                    178: }
                    179: 
                    180: //---------------------------------------------------------------------------
                    181: // Initialize the ifnet structure. Subclasses must override this
                    182: // method and initialize the ifnet structure given in a family specific
                    183: // manner. The implementation of this method in the subclass must call
                    184: // the version in super before it returns. The argument provided is a
                    185: // pointer to an ifnet structure obtained through getIfnet().
                    186: // IONetworkInterface uses this method to initialize the function
                    187: // pointers in ifnet.
                    188: //
                    189: // ifp: Pointer to an ifnet structure obtained through an earlier
                    190: //      getIfnet() call.
                    191: //
                    192: // Returns true if the initialization was successful.
                    193:     
                    194: bool IONetworkInterface::initIfnet(struct ifnet * ifp)
                    195: {
                    196:     lock();
                    197: 
                    198:     // Register our 'shim' functions. These function pointers
                    199:     // points to static member functions inside class.
                    200: 
                    201:     ifp->if_output   = output_shim;
                    202:     ifp->if_ioctl    = ioctl_shim;
                    203:     ifp->if_set_bpf_tap = set_bpf_tap_shim;
                    204:     ifp->if_private  = this;
                    205: 
                    206:     // Enable driver reentrancy. This allows the network stack
                    207:     // to call the driver from the same thread that sent a received
                    208:     // packet up to the stack. The netisr thread is bypassed. The context
                    209:     // switch cost is eliminated, but how long will the driver have to wait
                    210:     // before the thread can return to do driver work?
                    211:     //
                    212:     // Not enabled by default, do this on a per driver basis by calling,
                    213:     // netif->setExtraFlags(IFEF_DVR_REENTRY_OK) from the driver's
                    214:     // configureNetworkInterface() function.
                    215:     //
                    216:     // ifp->if_eflags |= IFEF_DVR_REENTRY_OK;
                    217: 
                    218:     unlock();
                    219: 
                    220:     return true;
                    221: }
                    222: 
                    223: //---------------------------------------------------------------------------
                    224: // Take the interface lock (recursive lock).
                    225: 
                    226: void IONetworkInterface::lock()
                    227: {
                    228:     IORecursiveLockLock(_ifLock);
                    229: }
                    230: 
                    231: //---------------------------------------------------------------------------
                    232: // Release the interface lock (recursive lock).
                    233: 
                    234: void IONetworkInterface::unlock()
                    235: {
                    236:     IORecursiveLockUnlock(_ifLock);
                    237: }
                    238: 
                    239: //---------------------------------------------------------------------------
                    240: // Called by handleOpen() to configure our controller after we have just
                    241: // called he controller's open() method. We open the controller only when
                    242: // we receive the initial open request from a client. Subclasses should
                    243: // override this method and setup the controller before allowing the
                    244: // client open, and they must call this method and check the return
                    245: // value in their implementation.
                    246: //
                    247: // controller: Our controller object.
                    248: //
                    249: // Must return true in order for handleOpen() to accept the client open.
                    250: // If the return is false, then the controller will be closed and the client
                    251: // open will be rejected.
                    252: 
                    253: bool IONetworkInterface::controllerDidOpen(IONetworkController * controller)
                    254: {
                    255:     return true;   // open approved.
                    256: }
                    257: 
                    258: //---------------------------------------------------------------------------
                    259: // Called by handleClose() after receiving a close from the
                    260: // last client, and just before the controller is closed. Subclasses
                    261: // can override this method to perform any cleanup action before the 
                    262: // controller is closed.
                    263: //
                    264: // controller: The controller that will be closed.
                    265: 
                    266: void IONetworkInterface::controllerWillClose(IONetworkController * controller)
                    267: {
                    268: }
                    269: 
                    270: //---------------------------------------------------------------------------
                    271: // Handle a client open on the interface. The open() method in IOService
                    272: // calls this method with the arbitration lock held. This method must
                    273: // return true to accept the client open. Subclasses should not override
                    274: // this method.
                    275: //
                    276: // client:   See IOService.
                    277: // options:  See IOService.
                    278: // argument: See IOService.
                    279: //
                    280: // Returns true to accept the client open.
                    281: 
                    282: bool IONetworkInterface::handleOpen(IOService *  client,
                    283:                                     IOOptionBits options,
                    284:                                     void *       argument)
                    285: {
                    286:     bool                  accept         = false;
                    287:     bool                  controllerOpen = false;
                    288:     IONetworkController * controller     = OSDynamicCast(IONetworkController, 
                    289:                                            getProvider());
                    290: 
                    291:     do {
                    292:         // Was this object already registered as our client?
                    293:         //
                    294:         if (_clientSet->containsObject(client))
                    295:         {
                    296:             DLOG("%s: multiple opens from client %lx\n",
                    297:                 getName(), (UInt32) client);
                    298:             accept = true;
                    299:             break;
                    300:         }
                    301: 
                    302:         // We can only provide services to a single client.
                    303:         // IONetworkUserClient are excluded from this restriction.
                    304:         //
                    305:         bool isClient = (OSDynamicCast(IONetworkUserClient, client) == 0);
                    306:         if (isClient && _client)
                    307:         {
                    308:             DLOG("%s: extra client %lx\n", getName(), (UInt32) client);
                    309:             break;
                    310:         }
                    311: 
                    312:         // If our provider has not yet been opened, then open it.
                    313:         // However if the controller open fails, then we will not allow
                    314:         // the new client to open us.
                    315:         //
                    316:         if (_provider == 0) {
                    317:             if ((controller == 0) ||
                    318:                 ((controllerOpen = controller->open(this)) == false) ||
                    319:                 (controllerDidOpen(controller) == false))
                    320:                 break;
                    321:         }
                    322: 
                    323:         // Qualify the client.
                    324:         //
                    325:         if (!handleClientOpen(controller, client))
                    326:             break;
                    327: 
                    328:         // Add the new client object to our client set.
                    329:         //
                    330:         if (!_clientSet->setObject(client))
                    331:         {
                    332:             handleClientClose(controller, client);
                    333:             break;
                    334:         }
                    335: 
                    336:         // Remember our client.
                    337:         //
                    338:         if (isClient)
                    339:             _client = client;
                    340: 
                    341:         accept = true;
                    342:     }
                    343:     while (0);
                    344: 
                    345:     // If provider was opened above, but an error has caused us to refuse
                    346:     // the client open, then close our provider. Otherwise, cache our
                    347:     // provider.
                    348:     //
                    349:     if (controllerOpen)
                    350:     {
                    351:         if (accept)
                    352:         {
                    353:             _provider = controller; // cache our provider.
                    354:         }
                    355:         else {
                    356:             controllerWillClose(controller);
                    357:             controller->close(this);
                    358:         }
                    359:     }
                    360: 
                    361:     return accept;
                    362: }
                    363: 
                    364: //---------------------------------------------------------------------------
                    365: // Handle a close by one of our clients. We close the controller when
                    366: // we receive a close from our last client. The close() method in
                    367: // IOService calls this method with the arbitration lock held.
                    368: // Subclasses should not override this method.
                    369: //
                    370: // client:   See IOService.
                    371: // options:  See IOService.
                    372: 
                    373: void IONetworkInterface::handleClose(IOService * client, IOOptionBits options)
                    374: {
                    375:     // Remove the object from the client OSSet.
                    376:     //
                    377:     if (_clientSet->containsObject(client))
                    378:     {
                    379:         bool isClient = (OSDynamicCast(IONetworkUserClient, client) == 0);
                    380: 
                    381:         // Call handleClientClose() to handle the client close.
                    382:         //
                    383:         assert(_provider);
                    384:         handleClientClose(_provider, client);
                    385: 
                    386:         if (isClient)
                    387:             _client = 0;
                    388: 
                    389:         // If this is the last client, then close our provider.
                    390:         //
                    391:         if (_clientSet->getCount() == 1)
                    392:         {
                    393:             controllerWillClose(_provider);
                    394:             _provider->close(this);
                    395:             _provider = 0;
                    396:         }
                    397: 
                    398:         // Remove the client from our OSSet.
                    399:         //
                    400:         _clientSet->removeObject(client);
                    401:     }
                    402: }
                    403: 
                    404: //---------------------------------------------------------------------------
                    405: // Returns true if the specified client, or any client if none if
                    406: // specified, presently has an open on this object. This function
                    407: // is called by IOService with the arbitration lock held.
                    408: // Subclasses should not override this method.
                    409: 
                    410: bool IONetworkInterface::handleIsOpen(const IOService * client) const
                    411: {
                    412:     if (client)
                    413:         return _clientSet->containsObject(client);
                    414:     else
                    415:         return (_clientSet->getCount() > 0);
                    416: }
                    417: 
                    418: //---------------------------------------------------------------------------
                    419: // This method is called by handleOpen() to qualify a client
                    420: // object is trying to open us. This method must return true
                    421: // true to accept the client open. The provider of the
                    422: // interface object, an IONetworkController, is also provided.
                    423: 
                    424: bool IONetworkInterface::handleClientOpen(IONetworkController * /*ctlr*/,
                    425:                                           IOService *           client)
                    426: {
                    427:     bool allowOpen = true;
                    428: 
                    429:     // Always allow opens from IOUserClients.
                    430:     //
                    431:     if (OSDynamicCast(IONetworkUserClient, client))
                    432:         return true;
                    433: 
                    434:     lock();
                    435: 
                    436:     // Packet output handler must be valid.
                    437:     //
                    438:     if (!_target || !_outAction)
                    439:         allowOpen = false;
                    440: 
                    441:     // Transition state to registered.
                    442:     //
                    443:     if (allowOpen)
                    444:         _registered = true;
                    445: 
                    446:     unlock();
                    447: 
                    448:     return allowOpen;
                    449: }
                    450: 
                    451: //---------------------------------------------------------------------------
                    452: // Called by handleClose() to handle a client close. Both the provider
                    453: // and the client that performed the close are provided.
                    454: 
                    455: void IONetworkInterface::handleClientClose(IONetworkController * /*ctlr*/,
                    456:                                            IOService *           client)
                    457: {
                    458:     if (OSDynamicCast(IONetworkUserClient, client))
                    459:         return;
                    460: 
                    461:     lock();
                    462: 
                    463:     // Transition state to unregistered.
                    464:     //
                    465:     _registered = false;
                    466: 
                    467:     unlock();
                    468: }
                    469: 
                    470: //---------------------------------------------------------------------------
                    471: // Register the output handler. The interface will forward all output packets,
                    472: // sent from the network layer, to the output handler registered through
                    473: // this method. Until a handler is registered, handleClientOpen()
                    474: // will refuse all client opens. The output handler cannot be changed
                    475: // when the interface state is kIONetworkInterfaceStateRegistered. 
                    476: //
                    477: // target: Target object that implements the output action.
                    478: // action: The action which handles output packets.
                    479: 
                    480: bool IONetworkInterface::registerOutputHandler(OSObject *      target,
                    481:                                                IOOutputAction  action)
                    482: {
                    483:     target = OSDynamicCast(OSObject, target);
                    484: 
                    485:     lock();
                    486: 
                    487:     // Sanity check on the arguments.
                    488:     //
                    489:     if (_registered || !target || !action)
                    490:     {
                    491:         unlock();
                    492:         return false;
                    493:     }
                    494: 
                    495:     _target    = target;
                    496:     _outAction = action;
                    497: 
                    498:     unlock();
                    499: 
                    500:     return true;
                    501: }
                    502: 
                    503: //---------------------------------------------------------------------------
                    504: // Functions to set and inspect the filter tap settings. These settings
                    505: // cannot change once the interface becomes registered.
                    506: 
                    507: bool IONetworkInterface::_setFilterTapMode(IOFilterTapMode * modePtr,
                    508:                                            IOFilterTapMode   mode)
                    509: {
                    510:     lock();
                    511: 
                    512:     if (_registered)
                    513:     {
                    514:         unlock();
                    515:         return false;
                    516:     }
                    517:     *modePtr = mode;
                    518: 
                    519:     unlock();
                    520:     
                    521:     return true;
                    522: }
                    523: 
                    524: bool IONetworkInterface::setInputFilterTapMode(IOFilterTapMode mode)
                    525: {
                    526:     return _setFilterTapMode(&_inputFilterTapMode, mode);
                    527: }
                    528: 
                    529: bool IONetworkInterface::setOutputFilterTapMode(IOFilterTapMode mode)
                    530: {
                    531:     return _setFilterTapMode(&_outputFilterTapMode, mode);
                    532: }
                    533: 
                    534: IOFilterTapMode IONetworkInterface::getInputFilterTapMode() const
                    535: {
                    536:     return _inputFilterTapMode;
                    537: }
                    538: 
                    539: IOFilterTapMode IONetworkInterface::getOutputFilterTapMode() const
                    540: {
                    541:     return _outputFilterTapMode;
                    542: }
                    543: 
                    544: //---------------------------------------------------------------------------
                    545: // Feed packets to the input/output BPF packet filter taps.
                    546: 
                    547: static inline void _feedFilterTap(struct ifnet * ifp,
                    548:                                   struct mbuf *  m,
                    549:                                   BPF_FUNC       func,
                    550:                                   int            mode)
                    551: {
                    552:     if (func)
                    553:         func(ifp, m);
                    554: }
                    555: 
                    556: //---------------------------------------------------------------------------
                    557: // Feed a packet to the output filter tap. This method should not be called if
                    558: // the output filter tap mode is set to kIOFilterTapModeInternal, since the tap
                    559: // would already receive every output packet that flows through the interface.
                    560: // A further call to feedOutputFilterTap() would cause the tap to receive
                    561: // multiple copies of the same output packet.
                    562: //
                    563: // pkt: The packet mbuf to pass to the output tap.
                    564: 
                    565: void IONetworkInterface::feedOutputFilterTap(struct mbuf * m)
                    566: {
                    567:     assert(m);
                    568:     _feedFilterTap(_ifp, m, _outputFilterFunc, BPF_TAP_OUTPUT);
                    569: }
                    570: 
                    571: //---------------------------------------------------------------------------
                    572: // Feed a packet to the input filter tap. This method should not be called if
                    573: // the input filter tap mode is set to kIOFilterTapModeInternal, since the tap 
                    574: // would already receive every input packet that flows through the interface.
                    575: // A further call to feedInputFilterTap() would cause the tap to receive 
                    576: // multiple copies of the same input packet
                    577: //
                    578: // pkt: The packet mbuf to pass to the input tap. The rcvif
                    579: //      field in the mbuf is modified by this method.
                    580: 
                    581: void IONetworkInterface::feedInputFilterTap(struct mbuf * m)
                    582: {
                    583:     assert(m);
                    584:     m->m_pkthdr.rcvif = _ifp;
                    585:     _feedFilterTap(_ifp, m, _inputFilterFunc, BPF_TAP_INPUT);
                    586: }
                    587: 
                    588: //---------------------------------------------------------------------------
                    589: // Called by a controller to pass a received packet
                    590: // to the network layer. Packets received by this method can
                    591: // also be placed on a queue local to the interface, that the controller
                    592: // can use to delay the packet handoff to the network layer, until all
                    593: // received packets have been transferred to the queue. A subsequent call
                    594: // of flushInputQueue(), or inputPacket() with the queue argument set to 
                    595: // false, will cause all queued packets (may be a single packet) to be 
                    596: // delivered to the network layer, by making a single dlil_input() call.
                    597: // Additional methods that manipulate the input queue are flushInputQueue() 
                    598: // and clearInputQueue(). This queue, which is nothing more than a chain of
                    599: // mbufs, is not protected by a lock since the controller is expected to
                    600: // manipulate the input queue from a single thread. If the input filter
                    601: // tap mode is set to kIOFilterTapModeInternal, then packets sent to
                    602: // this method are also fed to the input filter tap.
                    603: //
                    604: // m:      The packet mbuf containing the received frame.
                    605: //
                    606: // length: If non zero, the mbuf will be truncated to the
                    607: //         given length. If zero, then no truncation will take place.
                    608: //
                    609: // queue:  If true, the only action performed is to queue the
                    610: //         input packet. Otherwise, the dlil_input() function is
                    611: //         called to handoff all queued packets (including the packet
                    612: //         passed in).
                    613: //
                    614: // Returns the number of packets submitted to the network layer.
                    615: // Returns 0 if the packet was queued.
                    616: //
                    617: // FIXME - The current implementation does not use the new DLIL API's.
                    618: // Thus it will only work for Ethernet devices.
                    619: 
                    620: #define IN_Q_RESET  {inputQHead = 0;}
                    621: 
                    622: #define IN_Q_ENQUEUE(m)                 \
                    623: {                                       \
                    624:     if (inputQHead == 0)                \
                    625:         inputQHead = inputQTail = (m);  \
                    626:     else {                              \
                    627:         inputQTail->m_nextpkt = (m);    \
                    628:         inputQTail = (m);               \
                    629:     }                                   \
                    630: }
                    631: 
                    632: #define IN_Q_FLUSH(count)                                               \
                    633: {                                                                       \
                    634:     struct  mbuf * _m;                                                  \
                    635:     struct  ether_header * _eh;                                         \
                    636:                                                                         \
                    637:     count = 0;                                                          \
                    638:                                                                         \
                    639:     while ((_m = inputQHead)) {                                         \
                    640:         inputQHead = inputQHead->m_nextpkt;                             \
                    641:         _m->m_nextpkt = 0;                                              \
                    642:         _m->m_pkthdr.rcvif = _ifp;                                      \
                    643:                                                                         \
                    644:         if (_inputFilterTapMode == kIOFilterTapModeInternal)            \
                    645:             _feedFilterTap(_ifp, _m, _inputFilterFunc, BPF_TAP_INPUT);  \
                    646:                                                                         \
                    647:         _eh = (struct ether_header *) _m->m_data;                       \
                    648:         _m->m_len -= sizeof(struct ether_header);                       \
                    649:         _m->m_data += sizeof(struct ether_header);                      \
                    650:         _m->m_pkthdr.len -= sizeof(struct ether_header);                \
                    651:                                                                         \
                    652:         dlil_input(_ifp, _m, (char *) _eh);                                      \
                    653:         count++;                                                        \
                    654:     }                                                                   \
                    655: }
                    656: 
                    657: UInt32 IONetworkInterface::flushInputQueue()
                    658: {
                    659:     UInt32 count;
                    660: 
                    661:     IN_Q_FLUSH(count);
                    662: //  IN_Q_RESET;
                    663:     return count;
                    664: }
                    665: 
                    666: UInt32 IONetworkInterface::clearInputQueue()
                    667: {
                    668:     UInt32 count = 0;
                    669:     struct mbuf * m;
                    670:     
                    671:     while ((m = inputQHead))
                    672:     {
                    673:         inputQHead = inputQHead->m_nextpkt;
                    674:         m_freem(m);
                    675:         count++;
                    676:     }
                    677: //  IN_Q_RESET;
                    678:     return count;
                    679: }
                    680: 
                    681: UInt32 IONetworkInterface::inputPacket(struct mbuf * m,
                    682:                                        UInt32        length = 0,
                    683:                                        bool          queue  = false)
                    684: {
                    685:     assert(m);
                    686: 
                    687:     // Truncate the tail of the mbuf chain to the specified length.
                    688:     // The mbuf chain passed in will usually have the length in
                    689:     // each mbuf set to its capacity.
                    690:     //
                    691:     if (length)
                    692:     {
                    693:         struct mbuf * mb = m;
                    694:         mb->m_pkthdr.len = length;      // set total length
                    695:         do {
                    696:             if (length < (UInt) mb->m_len)
                    697:             {
                    698:                 mb->m_len = length;     // truncate mbuf to remaining length
                    699:             }
                    700:             length -= mb->m_len;        // decrement remaining length
                    701:         } while ((mb = mb->m_next));
                    702:         assert(length == 0);            // why is capacity smaller than length?
                    703:     }
                    704: 
                    705:     IN_Q_ENQUEUE(m);
                    706: 
                    707:     if (queue == false)
                    708:     {
                    709:         UInt32 count;
                    710:         IN_Q_FLUSH(count);
                    711: //      IN_Q_RESET;
                    712:         return count;
                    713:     }
                    714:     else
                    715:         return 0;
                    716: }
                    717: 
                    718: //---------------------------------------------------------------------------
                    719: // Called by the controller driver to send a network event to the network 
                    720: // layer. Possible applications include: media changed events,
                    721: // power management events, controller state change events.
                    722: //
                    723: // eventType: The event type.
                    724: // arg:       An argument associated with the event.
                    725: 
                    726: void IONetworkInterface::inputEvent(UInt32 eventType, void * arg)
                    727: {
                    728:     switch (eventType)
                    729:     {
                    730:         case kIONetworkEventMediumChange:
                    731:         case kIONetworkEventLinkChange:
                    732:             _handleMediumAndLinkChangeEvent();
                    733:             break;
                    734: 
                    735:         default:
                    736:             IOLog("IONetworkInterface: event (%x, %x) not handled\n",
                    737:                 (UInt) eventType, (UInt) arg);
                    738:             break;
                    739:     }
                    740: }
                    741: 
                    742: //---------------------------------------------------------------------------
                    743: // Handles media and link change events. Deliver a notification to
                    744: // all IONetworkUserClients.
                    745: 
                    746: void IONetworkInterface::_handleMediumAndLinkChangeEvent()
                    747: {
                    748:     OSCollectionIterator * iter;
                    749:     IONetworkUserClient *  uc;
                    750: 
                    751:     lockForArbitration();
                    752:     iter = OSCollectionIterator::withCollection(_clientSet);
                    753:     if (iter) {
                    754:         while ((uc = (IONetworkUserClient *) iter->getNextObject())) {
                    755:             if ((uc = OSDynamicCast(IONetworkUserClient, uc)) == 0)
                    756:                 continue;
                    757:             uc->deliverNotification(kIONUCNotificationTypeLinkChange);
                    758:         }
                    759:         iter->release();
                    760:     }
                    761:     unlockForArbitration();
                    762: }
                    763: 
                    764: //---------------------------------------------------------------------------
                    765: // SIOCSIFMTU (set interface MTU) ioctl handler.
                    766: 
                    767: SInt IONetworkInterface::syncSIOCSIFMTU(IONetworkController * ctlr,
                    768:                                         struct ifreq *        ifr)
                    769: {   
                    770:     SInt    error;
                    771:     UInt32  newMtu = ifr->ifr_mtu;
                    772: 
                    773:     // If change is not necessary, return success without getting the
                    774:     // controller involved.
                    775: 
                    776:     if (getMaxTransferUnit() == newMtu)
                    777:         return 0;
                    778: 
                    779:     // Request the controller to switch MTU size.
                    780:     //
                    781:     error = errnoFromReturn(ctlr->doSetMaxTransferUnit(this, newMtu));
                    782: 
                    783:     if (error == 0)
                    784:     {
                    785:         // Controller reports success. Update the interface MTU size
                    786:         // property.
                    787:         //
                    788:         setMaxTransferUnitInt(newMtu);
                    789:     }
                    790: 
                    791:     return error;
                    792: }
                    793: 
                    794: //---------------------------------------------------------------------------
                    795: // SIOCSIFMEDIA (SET interface media) ioctl handler.
                    796: 
                    797: SInt IONetworkInterface::syncSIOCSIFMEDIA(IONetworkController * ctlr,
                    798:                                           struct ifreq *        ifr)
                    799: {
                    800:     OSDictionary *    mediumDict;
                    801:     IONetworkMedium * medium;
                    802:     SInt              error;
                    803: 
                    804:     mediumDict = ctlr->copyMediumDictionary();  // creates a copy
                    805:     if (!mediumDict)
                    806:     {
                    807:         // unable to allocate memory, or no medium dictionary.
                    808:         return EOPNOTSUPP;
                    809:     }
                    810: 
                    811:     medium = IONetworkMedium::getMediumWithType(mediumDict, ifr->ifr_media);
                    812:     if (!medium)
                    813:     {
                    814:         // Exact type was not found. Try a partial match.
                    815:         // ifconfig program sets the media type and media
                    816:         // options separately. The client should not send
                    817:         // an incomplete type!!!
                    818: 
                    819:         medium = IONetworkMedium::getMediumWithType(mediumDict,
                    820:                                                     ifr->ifr_media,
                    821:                                                     ~kIOMediumTypeMask);
                    822:         if (!medium)
                    823:         {   
                    824:             mediumDict->release();
                    825:             return EINVAL;       // requested medium not found.
                    826:         }
                    827:     }
                    828: 
                    829:     // It may be possible for the controller to update the medium
                    830:     // dictionary and perhaps delete the medium entry that we have
                    831:     // selected from our copy of the stale dictionary. This should be
                    832:     // harmless since IONetworkController's doSelectMedium() should 
                    833:     // filter invalid selections before calling the driver.
                    834: 
                    835:     error = errnoFromReturn(ctlr->doSelectMedium(this, medium->getName()));
                    836: 
                    837:     if (error == 0)
                    838:     {
                    839:         // Remember the last media type sent by BSD which the driver
                    840:         // accepted. Note that _bsdMediaType may not be equal to
                    841:         // medium->getType() since we may have done a partial match.
                    842:         // The only reason for this is to be able to return the
                    843:         // _bsdMediaType as the current media type in SICGIFMEDIA.
                    844: 
                    845:         _bsdMediaType = ifr->ifr_media;
                    846:     }
                    847: 
                    848:     mediumDict->release();
                    849: 
                    850:     return error;
                    851: }
                    852: 
                    853: //---------------------------------------------------------------------------
                    854: // SIOCGIFMEDIA (GET interface media) ioctl handler.
                    855: 
                    856: SInt IONetworkInterface::syncSIOCGIFMEDIA(IONetworkController * ctlr,
                    857:                                           struct ifreq *        ifr)
                    858: {
                    859:     OSDictionary *          mediumDict  = 0;
                    860:     UInt                    mediumCount = 0;
                    861:     UInt                    maxCount;
                    862:     OSCollectionIterator *  iter = 0;
                    863:     UInt32 *                typeList;
                    864:     UInt                    typeListSize;
                    865:     OSSymbol *              keyObject;
                    866:     SInt                    error = 0;
                    867:     struct ifmediareq *     ifmr = (struct ifmediareq *) ifr;
                    868: 
                    869:     // Maximum number of medium types that the ioctl caller will accept.
                    870:     //
                    871:     maxCount = ifmr->ifm_count;
                    872: 
                    873:     do {
                    874:         mediumDict = ctlr->copyMediumDictionary();  // creates a copy
                    875:         if (!mediumDict)
                    876:         {
                    877:             error = EOPNOTSUPP;
                    878:             break;  // unable to allocate memory, or no medium dictionary.
                    879:         }
                    880: 
                    881:         if ((mediumCount = mediumDict->getCount()) == 0)
                    882:             break;  // no medium in the medium dictionary
                    883: 
                    884:         if (maxCount == 0)
                    885:             break;  //  caller is only probing for support and media count.
                    886: 
                    887:         if (maxCount < mediumCount)
                    888:         {
                    889:             // user buffer is too small to hold all medium entries.
                    890:             error = E2BIG;
                    891: 
                    892:             // Proceed with partial copy on E2BIG. This follows the
                    893:             // SIOCGIFMEDIA handling practice in bsd/net/if_media.c.
                    894:             //
                    895:             // break;
                    896:         }
                    897: 
                    898:         // Create an iterator to loop through the medium entries in the
                    899:         // dictionary.
                    900:         //
                    901:         iter = OSCollectionIterator::withCollection(mediumDict);
                    902:         if (!iter)
                    903:         {
                    904:             error = ENOMEM;
                    905:             break;
                    906:         }
                    907: 
                    908:         // Allocate memory for the copyout buffer.
                    909:         //
                    910:         typeListSize = maxCount * sizeof(UInt32);
                    911:         typeList = (UInt32 *) IOMalloc(typeListSize);
                    912:         if (!typeList)
                    913:         {
                    914:             error = ENOMEM;
                    915:             break;
                    916:         }
                    917:         bzero(typeList, typeListSize);
                    918: 
                    919:         // Iterate through the medium dictionary and copy the type of
                    920:         // each medium entry to typeList[].
                    921:         //
                    922:         mediumCount = 0;
                    923:         while ( (keyObject = (OSSymbol *) iter->getNextObject()) &&
                    924:                 (mediumCount < maxCount) )
                    925:         {
                    926:             IONetworkMedium * medium = OSDynamicCast(IONetworkMedium, 
                    927:                                        mediumDict->getObject(keyObject));
                    928:             if (!medium)
                    929:                 continue;   // should not happen!
                    930: 
                    931:             typeList[mediumCount++] = medium->getType();
                    932:         }
                    933: 
                    934:         if (mediumCount)
                    935:         {
                    936:             error = copyout((caddr_t) typeList,
                    937:                             (caddr_t) ifmr->ifm_ulist,
                    938:                             typeListSize);
                    939:         }
                    940: 
                    941:         IOFree(typeList, typeListSize);
                    942:     }
                    943:     while (0);
                    944: 
                    945:     ifmr->ifm_active = ifmr->ifm_current = IFM_NONE;
                    946:     ifmr->ifm_status = 0;
                    947:     ifmr->ifm_count  = mediumCount;
                    948: 
                    949:     // Get a copy of the controller's property table and read the
                    950:     // link status, current, and active medium.
                    951: 
                    952:     OSDictionary * pTable = ctlr->dictionaryWithProperties();
                    953:     if (pTable)
                    954:     {
                    955:         OSNumber * linkStatus = OSDynamicCast(OSNumber, 
                    956:                                 pTable->getObject(kIOLinkStatus));
                    957:         if (linkStatus)
                    958:             ifmr->ifm_status = linkStatus->unsigned32BitValue();
                    959:         
                    960:         if (mediumDict)
                    961:         {
                    962:             IONetworkMedium * medium;
                    963:             OSSymbol *        mediumName;
                    964: 
                    965:             if ((mediumName = OSDynamicCast(OSSymbol, 
                    966:                               pTable->getObject(kIOCurrentMedium))) &&
                    967:                 (medium = OSDynamicCast(IONetworkMedium,
                    968:                           mediumDict->getObject(mediumName))))
                    969:             {
                    970:                 ifmr->ifm_current = medium->getType();
                    971:                 if (IOMediumGetType(_bsdMediaType) ==
                    972:                     IOMediumGetType((UInt32) ifmr->ifm_current))
                    973:                 {
                    974:                     ifmr->ifm_current = _bsdMediaType;
                    975:                 }
                    976:             }
                    977: 
                    978:             if ((mediumName = OSDynamicCast(OSSymbol, 
                    979:                               pTable->getObject(kIOActiveMedium))) &&
                    980:                 (medium = OSDynamicCast(IONetworkMedium,
                    981:                           mediumDict->getObject(mediumName))))
                    982:             {
                    983:                 ifmr->ifm_active = medium->getType();
                    984:             }
                    985:         }
                    986:         pTable->release();
                    987:     }
                    988:     
                    989:     if (iter)
                    990:         iter->release();
                    991:     if (mediumDict)
                    992:         mediumDict->release();
                    993: 
                    994:     return error;
                    995: }
                    996: 
                    997: //---------------------------------------------------------------------------
                    998: // Handles generic socket ioctl commands sent to the interface.
                    999: // IONetworkInterface handles commands that are common to all network
                   1000: // families. A subclass of IONetworkInterface may override this method
                   1001: // in order to handle the same command that is handled here, but in a
                   1002: // different manner, or (the more like case) to augment the command
                   1003: // handling to include additional commands, and call super for any
                   1004: // commands not handled in the subclass.
                   1005: //
                   1006: // The commands handled by IONetworkInterface are:
                   1007: //    SIOCGIFMTU   - Get interface MTU size.
                   1008: //    SIOCSIFMTU   - Set interface MTU size.
                   1009: //    SIOCSIFMEDIA - Set media.
                   1010: //    SIOCGIFMEDIA - Get media and link status.
                   1011: //
                   1012: // Returns a BSD return code defined in bsd/sys/errno.h.
                   1013: 
                   1014: SInt IONetworkInterface::performCommand(IONetworkController * ctlr,
                   1015:                                         UInt32                cmd,
                   1016:                                         void *                arg0,
                   1017:                                         void *                arg1)
                   1018: {
                   1019:     SInt ret = EBUSY;
                   1020: 
                   1021:     ctlr->syncRequest(this,             /* sender */
                   1022:                       this,             /* target */
                   1023:                      (IONetworkAction) &IONetworkInterface::syncPerformCommand,
                   1024:                       (UInt32 *) &ret,  /* return */
                   1025:                       (void *) ctlr,    /* arg0 - arg3 */
                   1026:                       (void *) cmd,
                   1027:                       (void *) arg0,
                   1028:                       (void *) arg1);
                   1029: 
                   1030:     return ret;
                   1031: }
                   1032: 
                   1033: SInt IONetworkInterface::syncPerformCommand(IONetworkController * ctlr,
                   1034:                                             UInt32                cmd,
                   1035:                                             void *                arg0,
                   1036:                                             void *                arg1)
                   1037: {
                   1038:     struct ifreq * ifr = (struct ifreq *) arg1;
                   1039:     SInt           ret = EINVAL;
                   1040: 
                   1041:     if (ifr == 0)
                   1042:         return EINVAL;
                   1043: 
                   1044:     switch (cmd)
                   1045:     {
                   1046:         // Get interface MTU.
                   1047:         //
                   1048:         case SIOCGIFMTU:
                   1049:             ifr->ifr_mtu = getMaxTransferUnit();
                   1050:             ret = 0;    // no error
                   1051:             break;
                   1052: 
                   1053:         // Set interface MTU.
                   1054:         //
                   1055:         case SIOCSIFMTU:
                   1056:             ret = syncSIOCSIFMTU(ctlr, ifr);
                   1057:             break;
                   1058: 
                   1059:         // Set interface media type.
                   1060:         //
                   1061:         case SIOCSIFMEDIA:
                   1062:             ret = syncSIOCSIFMEDIA(ctlr, ifr);
                   1063:             break;
                   1064: 
                   1065:         // Get interface media type and status.
                   1066:         //
                   1067:         case SIOCGIFMEDIA:
                   1068:             ret = syncSIOCGIFMEDIA(ctlr, ifr);
                   1069:             break;
                   1070: 
                   1071:         default:
                   1072:             // DLOG(%s: command not handled (%08lx), getName(), cmd);
                   1073:             break;
                   1074:     }
                   1075: 
                   1076:     return ret;
                   1077: }
                   1078: 
                   1079: //---------------------------------------------------------------------------
                   1080: // if_ioctl() handler - Calls performCommand() when we receive an ioctl
                   1081: // command from the network stack.
                   1082: 
                   1083: int
                   1084: IONetworkInterface::ioctl_shim(struct ifnet * ifp, u_long cmd, caddr_t data)
                   1085: {
                   1086:     assert(ifp && ifp->if_private);
                   1087: 
                   1088:     IONetworkInterface * self = (IONetworkInterface *) ifp->if_private;
                   1089: 
                   1090:     assert((ifp == self->_ifp) && self->_provider);
                   1091: 
                   1092:     return self->performCommand(self->_provider,
                   1093:                                 cmd,
                   1094:                                 (void *) ifp,
                   1095:                                 (void *) data);
                   1096: }
                   1097: 
                   1098: //---------------------------------------------------------------------------
                   1099: // if_output() handler.
                   1100: //
                   1101: // Handle a call from the network stack to transmit all packets in
                   1102: // the ifnet's output queue. This queue is likely to be removed in
                   1103: // the future when DLIL gets rolled out.
                   1104: 
                   1105: int IONetworkInterface::output_shim(struct ifnet * ifp, struct mbuf * m)
                   1106: {
                   1107:     assert(ifp && ifp->if_private);
                   1108: 
                   1109:     IONetworkInterface * self = (IONetworkInterface *) ifp->if_private;
                   1110:     
                   1111:     assert(ifp == self->_ifp);
                   1112: 
                   1113:     if (m == 0)
                   1114:     {
                   1115:         DLOG("IONetworkInterface: NULL output mbuf\n");
                   1116:         return EINVAL;
                   1117:     }
                   1118: 
                   1119:     if ((m->m_flags & M_PKTHDR) == 0)
                   1120:     {
                   1121:         DLOG("IONetworkInterface: M_PKTHDR bit not set\n");
                   1122:         m_freem(m);
                   1123:         return EINVAL;
                   1124:     }
                   1125: 
                   1126:     // Feed the output filter tap.
                   1127:     //
                   1128:     if (self->_outputFilterTapMode == kIOFilterTapModeInternal)
                   1129:         _feedFilterTap(ifp, m, self->_outputFilterFunc, BPF_TAP_OUTPUT);
                   1130:     
                   1131:     // Forward the packet to the registered output packet handler.
                   1132:     //
                   1133:     return ((self->_target)->*(self->_outAction))(m);
                   1134: }
                   1135: 
                   1136: //---------------------------------------------------------------------------
                   1137: // if_set_bpf_tap() handler. Handles request from the DLIL to enable or
                   1138: // disable the input/output filter taps.
                   1139: //
                   1140: // FIXME - locking may be needed.
                   1141: 
                   1142: int IONetworkInterface::set_bpf_tap_shim(struct ifnet * ifp,
                   1143:                                          int            mode,
                   1144:                                          BPF_FUNC       func)
                   1145: {
                   1146:     assert(ifp && ifp->if_private);
                   1147: 
                   1148:     IONetworkInterface * self = (IONetworkInterface *) ifp->if_private;
                   1149: 
                   1150:     assert(ifp == self->_ifp);
                   1151: 
                   1152:     switch (mode)
                   1153:     {
                   1154:         case BPF_TAP_DISABLE:
                   1155:             self->_inputFilterFunc = self->_outputFilterFunc = 0;
                   1156:             break;
                   1157: 
                   1158:         case BPF_TAP_INPUT:
                   1159:             assert(func);
                   1160:             self->_inputFilterFunc = func;
                   1161:             break;
                   1162: 
                   1163:         case BPF_TAP_OUTPUT:
                   1164:             assert(func);
                   1165:             self->_outputFilterFunc = func;
                   1166:             break;
                   1167:         
                   1168:         case BPF_TAP_INPUT_OUTPUT:
                   1169:             assert(func);
                   1170:             self->_inputFilterFunc = self->_outputFilterFunc = func;
                   1171:             break;
                   1172: 
                   1173:         default:
                   1174:             DLOG("IONetworkInterface: Unknown BPF tap mode %d\n", mode);
                   1175:             break;
                   1176:     }
                   1177: 
                   1178:     return 0;
                   1179: }
                   1180: 
                   1181: //---------------------------------------------------------------------------
                   1182: // As the name implies, this function does nothing. This will get called
                   1183: // if the network stack tries to call the if_watchdog function pointer 
                   1184: // in ifnet. This should not happen. IOKit does not use this watchdog
                   1185: // timer facility.
                   1186: 
                   1187: void IONetworkInterface::null_shim(struct ifnet * /*ifp*/)
                   1188: {
                   1189:     IOLog("IONetworkInterface::null_shim called!\n");
                   1190: }
                   1191: 
                   1192: //---------------------------------------------------------------------------
                   1193: // ifnet field (and property table) getter/setter.
                   1194: //
                   1195: // For the setter, if restrict flag is set, that means that the property is
                   1196: // restricted from being modified once the interface's has been registered.
                   1197: 
                   1198: bool IONetworkInterface::_setInterfaceProperty(
                   1199:     UInt32   value,
                   1200:     UInt32   mask,
                   1201:     UInt32   bytes,
                   1202:     void *   addr,
                   1203:     char *   key,
                   1204:     bool     restrict)
                   1205: {
                   1206:     bool   updateOk = false;
                   1207:     UInt32 newValue;
                   1208: 
                   1209:     lock();
                   1210: 
                   1211:     if (restrict && (_registered == true))
                   1212:         goto abort;
                   1213: 
                   1214:     // Update the property in ifnet.
                   1215:     //
                   1216:     switch (bytes)
                   1217:     {
                   1218:         case 1:
                   1219:             newValue = (*((UInt8 *) addr) & mask) | value;
                   1220:             *((UInt8 *) addr) = (UInt8) newValue;
                   1221:             break;
                   1222:         case 2:
                   1223:             newValue = (*((UInt16 *) addr) & mask) | value;
                   1224:             *((UInt16 *) addr) = (UInt16) newValue;
                   1225:             break;
                   1226:         case 4:
                   1227:             newValue = (*((UInt32 *) addr) & mask) | value;
                   1228:             *((UInt32 *) addr) = (UInt32) newValue;
                   1229:             break;
                   1230:         default:
                   1231:             goto abort;
                   1232:     }
                   1233: 
                   1234:     // Update the OSNumber in the property table.
                   1235:     //
                   1236:     updateOk = key ? setProperty(key, newValue, bytes * 8) : true;
                   1237: 
                   1238: abort:
                   1239:     unlock();
                   1240:     return updateOk;
                   1241: }
                   1242: 
                   1243: #define IO_IFNET_GET(func, type, field)                        \
                   1244: type IONetworkInterface:: ## func() const                      \
                   1245: {                                                              \
                   1246:     type ret;                                                  \
                   1247:     ((IONetworkInterface *) this)->lock();                     \
                   1248:     ret = _ifp ? _ifp-> ## field : 0;                          \
                   1249:     ((IONetworkInterface *) this)->unlock();                   \
                   1250:     return ret;                                                \
                   1251: }
                   1252: 
                   1253: #define IO_IFNET_SET(func, type, field, propName)              \
                   1254: bool IONetworkInterface:: ## func ## Int(type value)           \
                   1255: {                                                              \
                   1256:     return _setInterfaceProperty(                              \
                   1257:         (UInt32) value,                                        \
                   1258:         0,                                                     \
                   1259:         sizeof(type),                                          \
                   1260:         (void *) &_ifp-> ## field,                             \
                   1261:         propName,                                              \
                   1262:         false);                                                \
                   1263: }                                                              \
                   1264:                                                                \
                   1265: bool IONetworkInterface:: ## func(type value)                  \
                   1266: {                                                              \
                   1267:     return _setInterfaceProperty(                              \
                   1268:         (UInt32) value,                                        \
                   1269:         0,                                                     \
                   1270:         sizeof(type),                                          \
                   1271:         (void *) &_ifp-> ## field,                             \
                   1272:         propName,                                              \
                   1273:         true);                                                 \
                   1274: }
                   1275: 
                   1276: #define IO_IFNET_RMW(func, type, field, propName)                            \
                   1277: bool IONetworkInterface:: ## func ## Int(type value, type clear = 0)         \
                   1278: {                                                                            \
                   1279:     return _setInterfaceProperty(                                            \
                   1280:         (UInt32) value,                                                      \
                   1281:         (UInt32) ~clear,                                                     \
                   1282:         sizeof(type),                                                        \
                   1283:         (void *) &_ifp-> ## field,                                           \
                   1284:         propName,                                                            \
                   1285:         false);                                                              \
                   1286: }                                                                            \
                   1287:                                                                              \
                   1288: bool IONetworkInterface:: ## func(type value, type clear = 0)                \
                   1289: {                                                                            \
                   1290:     return _setInterfaceProperty(                                            \
                   1291:         (UInt32) value,                                                      \
                   1292:         (UInt32) ~clear,                                                     \
                   1293:         sizeof(type),                                                        \
                   1294:         (void *) &_ifp-> ## field,                                           \
                   1295:         propName,                                                            \
                   1296:         true);                                                               \
                   1297: }
                   1298: 
                   1299: //---------------------------------------------------------------------------
                   1300: // Interface type accessors (ifp->if_type). The list of interface types is
                   1301: // defined in <bsd/net/if_types.h>.
                   1302: 
                   1303: IO_IFNET_SET(setInterfaceType, UInt8, if_type, kIOInterfaceType)
                   1304: IO_IFNET_GET(getInterfaceType, UInt8, if_type)
                   1305: 
                   1306: //---------------------------------------------------------------------------
                   1307: // Mtu (MaxTransferUnit) accessors (ifp->if_mtu).
                   1308: 
                   1309: IO_IFNET_SET(setMaxTransferUnit, UInt32, if_mtu, kIOMaxTransferUnit)
                   1310: IO_IFNET_GET(getMaxTransferUnit, UInt32, if_mtu)
                   1311: 
                   1312: //---------------------------------------------------------------------------
                   1313: // Flags accessors (ifp->if_flags). This is a read-modify-write operation.
                   1314: 
                   1315: IO_IFNET_RMW(setFlags, UInt16, if_flags, kIOInterfaceFlags)
                   1316: IO_IFNET_GET(getFlags, UInt16, if_flags)
                   1317: 
                   1318: //---------------------------------------------------------------------------
                   1319: // EFlags accessors (ifp->if_eflags). This is a read-modify-write operation.
                   1320: 
                   1321: IO_IFNET_RMW(setExtraFlags, UInt32, if_eflags, kIOInterfaceExtraFlags)
                   1322: IO_IFNET_GET(getExtraFlags, UInt32, if_eflags)
                   1323: 
                   1324: //---------------------------------------------------------------------------
                   1325: // MediaAddressLength accessors (ifp->if_addrlen)
                   1326: 
                   1327: IO_IFNET_SET(setMediaAddressLength, UInt8, if_addrlen, kIOMediaAddressLength)
                   1328: IO_IFNET_GET(getMediaAddressLength, UInt8, if_addrlen)
                   1329: 
                   1330: //---------------------------------------------------------------------------
                   1331: // MediaHeaderLength accessors (ifp->if_hdrlen)
                   1332: 
                   1333: IO_IFNET_SET(setMediaHeaderLength, UInt8, if_hdrlen, kIOMediaHeaderLength)
                   1334: IO_IFNET_GET(getMediaHeaderLength, UInt8, if_hdrlen)
                   1335: 
                   1336: //---------------------------------------------------------------------------
                   1337: // Interface unit number. The unit number for the interface is assigned
                   1338: // by our client.
                   1339: 
                   1340: IO_IFNET_SET(setUnitNumber, UInt16, if_unit, 0)
                   1341: IO_IFNET_GET(getUnitNumber, UInt16, if_unit)
                   1342: 
                   1343: //---------------------------------------------------------------------------
                   1344: // Interface name.
                   1345: 
                   1346: IO_IFNET_SET(setInterfaceName, const char *, if_name, 0)
                   1347: IO_IFNET_GET(getInterfaceName, const char *, if_name)
                   1348: 
                   1349: //---------------------------------------------------------------------------
                   1350: // Return true if the interface has been registered with the network layer,
                   1351: // false otherwise.
                   1352: 
                   1353: bool IONetworkInterface::isRegistered() const
                   1354: {
                   1355:     return _registered;
                   1356: }
                   1357: 
                   1358: //---------------------------------------------------------------------------
                   1359: // Perform a lookup of the dictionary kept by the interface,
                   1360: // and return an entry that matches the specified string key.
                   1361: //
                   1362: // key: Search for an IONetworkData entry with this key.
                   1363: //
                   1364: // Returns the matching entry, or 0 if no match was found.
                   1365: 
                   1366: IONetworkData * IONetworkInterface::getNetworkData(const OSSymbol * key) const
                   1367: {
                   1368:     return OSDynamicCast(IONetworkData, _dataDict->getObject(key));
                   1369: }
                   1370: 
                   1371: IONetworkData * IONetworkInterface::getNetworkData(const char * key) const
                   1372: {
                   1373:     return OSDynamicCast(IONetworkData, _dataDict->getObject(key));
                   1374: }
                   1375: 
                   1376: //---------------------------------------------------------------------------
                   1377: // A private function to copy the data dictionary to the property table.
                   1378: 
                   1379: bool IONetworkInterface::_copyNetworkDataDictToPropertyTable()
                   1380: {
                   1381:     OSDictionary * aCopy = OSDictionary::withDictionary(_dataDict);
                   1382:     bool           ret   = false;
                   1383: 
                   1384:     if (aCopy) {
                   1385:         ret = setProperty(kIONetworkData, _dataDict);
                   1386:         aCopy->release();
                   1387:     }
                   1388: 
                   1389:     return ret;
                   1390: }
                   1391: 
                   1392: //---------------------------------------------------------------------------
                   1393: // Remove an entry from the dictionary of IONetworkData objects.
                   1394: //
                   1395: // aKey: A key for an IONetworkData entry in the dictionary.
                   1396: //
                   1397: // Returns true if completed without errors,
                   1398: // false if the operation was aborted.
                   1399: 
                   1400: bool IONetworkInterface::removeNetworkData(const OSSymbol * aKey)
                   1401: {
                   1402:     bool ret = false;
                   1403: 
                   1404:     lockForArbitration();
                   1405: 
                   1406:     do {
                   1407:         if (_clientSet->getCount())
                   1408:             break;
                   1409: 
                   1410:         _dataDict->removeObject(aKey);
                   1411:         ret = _copyNetworkDataDictToPropertyTable();
                   1412:     }
                   1413:     while (0);
                   1414: 
                   1415:     unlockForArbitration();
                   1416: 
                   1417:     return ret;
                   1418: }
                   1419: 
                   1420: bool IONetworkInterface::removeNetworkData(const char * aKey)
                   1421: {
                   1422:     bool ret = false;
                   1423: 
                   1424:     lockForArbitration();
                   1425: 
                   1426:     do {
                   1427:         if (_clientSet->getCount())
                   1428:             break;
                   1429: 
                   1430:         _dataDict->removeObject(aKey);
                   1431:         ret = _copyNetworkDataDictToPropertyTable();
                   1432:     }
                   1433:     while (0);
                   1434: 
                   1435:     unlockForArbitration();
                   1436: 
                   1437:     return ret;
                   1438: }
                   1439: 
                   1440: //---------------------------------------------------------------------------
                   1441: // Add an IONetworkData object to a dictionary kept by
                   1442: // the interface.
                   1443: //
                   1444: // aData: An IONetworkData object.
                   1445: //
                   1446: // Returns true if the data object was added successfully, false otherwise.
                   1447: 
                   1448: bool IONetworkInterface::addNetworkData(IONetworkData * aData)
                   1449: {
                   1450:     bool ret = false;
                   1451: 
                   1452:     if (OSDynamicCast(IONetworkData, aData) == 0)
                   1453:         return false;
                   1454: 
                   1455:     lockForArbitration();
                   1456: 
                   1457:     if (_clientSet->getCount() == 0)
                   1458:     {
                   1459:         if ((ret = _dataDict->setObject(aData->getKey(), aData)))
                   1460:             ret = _copyNetworkDataDictToPropertyTable();
                   1461:     }
                   1462: 
                   1463:     unlockForArbitration();
                   1464: 
                   1465:     return ret;
                   1466: }
                   1467: 
                   1468: //---------------------------------------------------------------------------
                   1469: // Create a new IOUserClient to handle client requests. The default
                   1470: // implementation will create an IONetworkUserClient instance if
                   1471: // the type is kIONUCType.
                   1472: 
                   1473: IOReturn IONetworkInterface::newUserClient(task_t           owningTask,
                   1474:                                            void *         /*security_id*/,
                   1475:                                            UInt32           type,
                   1476:                                            IOUserClient **  handler)
                   1477: {
                   1478:     IOReturn                err = kIOReturnSuccess;
                   1479:     IONetworkUserClient *   client;
                   1480: 
                   1481:     if (type != kIONUCType)
                   1482:         return kIOReturnBadArgument;
                   1483: 
                   1484:     client = IONetworkUserClient::withTask(owningTask);
                   1485: 
                   1486:     if (!client || !client->attach(this) || !client->start(this))
                   1487:     {
                   1488:         if (client)
                   1489:         {
                   1490:             client->detach(this);
                   1491:             client->release();
                   1492:             client = 0;
                   1493:         }
                   1494:         err = kIOReturnNoMemory;
                   1495:     }
                   1496: 
                   1497:     *handler = client;
                   1498: 
                   1499:     return err;
                   1500: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.