Exemplo n.º 1
0
bool HoRNDISInterface::init(IONetworkController * controller, int mtu) {
	if (IOEthernetInterface::init(controller) == false)
		return false;
	LOG(V_NOTE, "starting up with MTU %d", mtu);
	setMaxTransferUnit(mtu);
	return true;
}
int IOEthernetInterface::syncSIOCSIFMTU( IONetworkController * ctr,
                                         struct ifreq *        ifr,
										 bool setAltMTU)
{

	IOReturn ret = kIOReturnSuccess;
	UInt32	newControllerMTU, oldControllerMTU;
	UInt32	softMTU = getMaxTransferUnit();
	UInt32	requestedMTU = ifr->ifr_mtu;
	
    UInt32  maxFrameSize = kIOEthernetMaxPacketSize;  // 1518
	UInt32	minFrameSize = kIOEthernetMinPacketSize;
	UInt32	tempSize;
	
	// Determine controller's max allowable mtu...
	if ( ctr->getMaxPacketSize( &tempSize ) == kIOReturnSuccess )
		maxFrameSize = max( tempSize, kIOEthernetMaxPacketSize );
	
	// ...and reject requests that are too big.
	if ( MTU_TO_FRAMESIZE( requestedMTU ) > maxFrameSize )
		return EINVAL;	// MTU is too large for the controller.

	// Determine controller's min allowable mtu...
	ctr->getMinPacketSize( &minFrameSize );

	// ...and reject requests that are too small.
	if ( MTU_TO_FRAMESIZE( requestedMTU ) < minFrameSize && !(setAltMTU && requestedMTU==0))  //allow setting dev MTU to 0 to turn it off
		return EINVAL;	// MTU is too small for the controller.
	
	//the controller gets the max of the mtu we're changing and the one we're not.
	newControllerMTU = max(requestedMTU, setAltMTU ? softMTU : _altMTU);
	
	// determine what's currently set on the controller (the max of current soft and alt settings)
	oldControllerMTU = max(softMTU, _altMTU);
		
	// we only have to change the controller if the new value is different from the old,
	// and either the new value is bigger than the standard max ethernet or the old value was.
	if(newControllerMTU != oldControllerMTU && 
	   ( (MTU_TO_FRAMESIZE(newControllerMTU) > kIOEthernetMaxPacketSize) ||
		 (MTU_TO_FRAMESIZE(oldControllerMTU) > kIOEthernetMaxPacketSize) )
	   )
	{
		ret = ctr->setMaxPacketSize( max(MTU_TO_FRAMESIZE(newControllerMTU), kIOEthernetMaxPacketSize)); //don't set smaller than standard max ethernet
	}
	if(ret == kIOReturnSuccess) //if we successfully set value in controller (or didn't need to) then store the new value
	{
		
		if(setAltMTU)
			_altMTU = requestedMTU;
		else
			setMaxTransferUnit( requestedMTU );
	}
	return errnoFromReturn( ret );
}
bool IOEthernetInterface::init(IONetworkController * controller)
{
    OSObject *  obj;

    _reserved = IONew( ExpansionData, 1 );
	if( _reserved == 0 )
		return false;
	memset(_reserved, 0, sizeof(ExpansionData));
	
    if ( super::init(controller) == false )
    	return false;

	// initialize enet specific fields.
	setInterfaceType(IFT_ETHER);
	setMaxTransferUnit( ETHERMTU );
	setMediaAddressLength( ETHER_ADDR_LEN );
	setMediaHeaderLength( ETHER_HDR_LEN );
	setFlags( IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS,
			  IFF_RUNNING   | IFF_MULTICAST );
	
    // Add an IONetworkData with room to hold an IOEthernetStats structure.
    // This class does not reference the data object created, and no harm
    // is done if the data object is released or replaced.

    IONetworkData * data = IONetworkData::withInternalBuffer(
                                              kIOEthernetStatsKey,
                                              sizeof(IOEthernetStats));
    if (data)
    {
        addNetworkData(data);
        data->release();
    }

    _inputEventThreadCall = thread_call_allocate(
                            handleEthernetInputEvent, this );
    if (!_inputEventThreadCall)
        return false;

    // Create and initialize the filter dictionaries.

    _requiredFilters = OSDictionary::withCapacity(2);
    _activeFilters   = OSDictionary::withCapacity(2);

    if ( (_requiredFilters == 0) || (_activeFilters == 0) )
        return false;

    obj = controller->copyProperty(kIOPacketFilters);
    if (obj && ((_supportedFilters = OSDynamicCast(OSDictionary, obj)) == 0))
        obj->release();
    if (!_supportedFilters)
        return false;

    // Cache the bit mask of wake filters supported by the driver.
    // This value will not change.

    _supportedWakeFilters = GET_SUPPORTED_FILTERS(
                            gIOEthernetWakeOnLANFilterGroup );

    // Retain the Disabled WOL filters OSNumber.
    // Its value will be updated live for link and WOL changed events.

    obj = _supportedFilters->getObject(
            gIOEthernetDisabledWakeOnLANFilterGroup );
    _disabledWakeFilters = OSDynamicCast(OSNumber, obj);
    if (_disabledWakeFilters)
        _disabledWakeFilters->retain();

    // Controller's Unicast (directed) and Broadcast filters should always
    // be enabled. Those bits should never be cleared.

    if ( !SET_REQUIRED_FILTERS( gIONetworkFilterGroup,
                                kIOPacketFilterUnicast |
                                kIOPacketFilterBroadcast )
      || !SET_REQUIRED_FILTERS( gIOEthernetWakeOnLANFilterGroup, 0 )
      || !SET_ACTIVE_FILTERS(   gIONetworkFilterGroup, 0 )
      || !SET_ACTIVE_FILTERS(   gIOEthernetWakeOnLANFilterGroup, 0 ) )
    {
         return false;
    }

    _publishedFeatureID = 0;

    // Publish filter dictionaries to property table.

    setProperty( kIORequiredPacketFilters, _requiredFilters );
    setProperty( kIOActivePacketFilters,   _activeFilters );

    return true;
}