⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 miniport.c

📁 Vitual Ring Routing 管你知不知道
💻 C
📖 第 1 页 / 共 5 页
字号:

    case METRIC_TYPE_WCETT:
        VRR_INIT_CONTROL_WCETT(Control);
        (void) GetRegDWORDValue(Key, L"Alpha",
                                (PULONG)&Control->MetricParams.Wcett.Alpha);
        (void) GetRegDWORDValue(Key, L"PenaltyFactor",
                                (PULONG)&Control->MetricParams.Wcett.PenaltyFactor);
        (void) GetRegDWORDValue(Key, L"LossInterval",
                                (PULONG)&Control->MetricParams.Wcett.LossInterval);
        (void) GetRegDWORDValue(Key, L"Beta",
                                (PULONG)&Control->MetricParams.Wcett.Beta);
        (void) GetRegDWORDValue(Key, L"PktPairProbePeriod",
                                (PULONG)&Control->MetricParams.Wcett.PktPairProbePeriod);
        (void) GetRegDWORDValue(Key, L"PktPairMinOverProbes",
                                (PULONG)&Control->MetricParams.Wcett.PktPairMinOverProbes);
        break;
    }

    ZwClose(Key);
}

//* MiniportControl
//
//  Sets configuration parameters from the structure.
//  Note that CryptoKeyMAC, CryptoKeyAES, and MetricType
//  can not be modified.
//
NTSTATUS
MiniportControl(
    MiniportAdapter *VA,
    VRR_CONTROL_VIRTUAL_ADAPTER *Control)
{
    // 
    // Check each parameter first.
    //

    if ((Control->MetricType != (uint)-1) &&
        (Control->MetricType != VA->MetricType)) {
        //
        // We do not allow the MetricType to change.
        //
        return STATUS_INVALID_PARAMETER_2;
    }

    switch (Control->MetricType) {

    case METRIC_TYPE_PKTPAIR:
        if (Control->MetricParams.PktPair.Alpha != (uint)-1) {
            //
            // Alpha is interpreted as Alpha/MAXALPHA.
            // Since the result of this division should
            // not exceed 1, the maximum value of Alpha is MAXALPHA.
            //   
            if (Control->MetricParams.PktPair.Alpha > MAXALPHA)
                return STATUS_INVALID_PARAMETER_3;
        }

        if (Control->MetricParams.PktPair.ProbePeriod != (uint)-1) {
            //
            // The probe period should not be less than 100ms to
            // prevent system overload.
            // 
            if (Control->MetricParams.PktPair.ProbePeriod < 100 * MILLISECOND)
                return STATUS_INVALID_PARAMETER_4;
        }

        if (Control->MetricParams.PktPair.PenaltyFactor != (uint)-1) {
            //
            // The penalty factor should be at most 32 to avoid
            // overflow problems.
            // 
            if ((Control->MetricParams.PktPair.PenaltyFactor < 1) ||
                (Control->MetricParams.PktPair.PenaltyFactor > 32))
                return STATUS_INVALID_PARAMETER_5;
        }
        break;


    case METRIC_TYPE_WCETT:

        if (Control->MetricParams.Wcett.LossInterval != (uint)-1) {
            //
            // The loss interval should not be less than 100ms. 
            // to prevent system overload. The upper bound is 1 minute
            // to prevent too much memory consumption.
            // 
            if ((Control->MetricParams.Wcett.LossInterval < 100 * MILLISECOND) || 
                (Control->MetricParams.Wcett.LossInterval > 1 * MINUTE))
                return STATUS_INVALID_PARAMETER_4;
        }

        if (Control->MetricParams.Wcett.Alpha != (uint)-1) {
            //
            // Alpha is interpreted as Alpha/MAXALPHA.
            // Since the result of this division should
            // not exceed 1, the maximum value of Alpha is MAXALPHA.
            //   
            if (Control->MetricParams.Wcett.Alpha > MAXALPHA)
                return STATUS_INVALID_PARAMETER_5;
        }

        if (Control->MetricParams.Wcett.PenaltyFactor != (uint)-1) {
            //
            // The penalty factor should be at most 32 to avoid
            // overflow problems. 
            // 
            if ((Control->MetricParams.Wcett.PenaltyFactor < 1) ||
                (Control->MetricParams.Wcett.PenaltyFactor > 32))
                return STATUS_INVALID_PARAMETER_6;
        }

        if (Control->MetricParams.Wcett.Beta != (uint)-1) {
            //
            // Beta is interpreted as Beta/MAXALPHA.
            // Since the result of this division should
            // not exceed 1, the maximum value of Weight is MAXALPHA.
            //   
            if (Control->MetricParams.Wcett.Beta > MAXALPHA)
                return STATUS_INVALID_PARAMETER_7;
        }

        if (Control->MetricParams.Wcett.PktPairProbePeriod != (uint)-1) {
            //
            // The probe period should not be less than 100ms to
            // prevent system overload.
            // 
            if (Control->MetricParams.Wcett.PktPairProbePeriod < 100 * MILLISECOND)
                return STATUS_INVALID_PARAMETER_8;
        }

        if (Control->MetricParams.Wcett.PktPairMinOverProbes != (uint)-1) {
            //
            // The number of probes should be at least one.
            //
            if (Control->MetricParams.Wcett.PktPairMinOverProbes < 1)
                return STATUS_INVALID_PARAMETER_9;
        }
        break;
    }

    //
    // Now, set the ones that we need to set.
    //

    if (Control->Snooping != (boolint) -1)
        VA->Snooping = Control->Snooping;

    if (Control->ArtificialDrop != (boolint) -1)
        VA->ArtificialDrop = Control->ArtificialDrop;

    if (Control->Crypto != (boolint) -1)
        VA->Crypto = Control->Crypto;

    if (Control->LinkTimeout != (uint)-1)
        VA->LinkTimeout = (Time)Control->LinkTimeout * SECOND;

    switch (Control->MetricType) {

    case METRIC_TYPE_PKTPAIR:
        if (Control->MetricParams.PktPair.Alpha != (uint)-1)
            VA->MetricParams.PktPair.Alpha = Control->MetricParams.PktPair.Alpha;
        if (Control->MetricParams.PktPair.ProbePeriod != (uint)-1)
            VA->MetricParams.PktPair.ProbePeriod = Control->MetricParams.PktPair.ProbePeriod;
        if (Control->MetricParams.PktPair.PenaltyFactor != (uint)-1)
            VA->MetricParams.PktPair.PenaltyFactor = Control->MetricParams.PktPair.PenaltyFactor;
        break;

    case METRIC_TYPE_WCETT:
        if (Control->MetricParams.Wcett.ProbePeriod != (uint)-1)
            VA->MetricParams.Wcett.ProbePeriod = Control->MetricParams.Wcett.ProbePeriod;
        if (Control->MetricParams.Wcett.LossInterval != (uint)-1)
            VA->MetricParams.Wcett.LossInterval = Control->MetricParams.Wcett.LossInterval;
        if (Control->MetricParams.Wcett.Alpha != (uint)-1)
            VA->MetricParams.Wcett.Alpha = Control->MetricParams.Wcett.Alpha;
        if (Control->MetricParams.Wcett.PenaltyFactor != (uint)-1)
            VA->MetricParams.Wcett.PenaltyFactor = Control->MetricParams.Wcett.PenaltyFactor;
        if (Control->MetricParams.Wcett.Beta != (uint)-1)
            VA->MetricParams.Wcett.Beta = Control->MetricParams.Wcett.Beta;
        if (Control->MetricParams.Wcett.PktPairProbePeriod != (uint)-1)
            VA->MetricParams.Wcett.PktPairProbePeriod = Control->MetricParams.Wcett.PktPairProbePeriod;
        if (Control->MetricParams.Wcett.PktPairMinOverProbes != (uint)-1)
            VA->MetricParams.Wcett.PktPairMinOverProbes = Control->MetricParams.Wcett.PktPairMinOverProbes;
        break;
    }

    return STATUS_SUCCESS;
}

//* MiniportInitialize
//
//  Called by NDIS to initialize an adapter.
//
NDIS_STATUS
MiniportInitialize(
    OUT PNDIS_STATUS OpenErrorStatus,
    OUT PUINT SelectedMediumIndex,
    IN PNDIS_MEDIUM MediumArray,
    IN UINT MediumArraySize,
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_HANDLE WrapperConfigurationContext)
{
    VRR_CONTROL_VIRTUAL_ADAPTER Control;
    MiniportAdapter *VA;
    HANDLE KeyHandle;
    LARGE_INTEGER Timeout;
    KIRQL OldIrql;
    NDIS_STATUS Status;
    NTSTATUS NtStatus;
    uint i;

    UNREFERENCED_PARAMETER(OpenErrorStatus);
    UNREFERENCED_PARAMETER(WrapperConfigurationContext);

    //
    // We emulate 802.3. Figure out which index that is.
    //
    for (i = 0; ; i++) {
        if (i == MediumArraySize) {
            Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
            goto ErrorReturn;
        }

        if (MediumArray[i] == NdisMedium802_3) {
            *SelectedMediumIndex = i;
            break;
        }
    }

    //
    // Allocate our virtual adapter structure.
    //
    VA = (MiniportAdapter *) ExAllocatePool(NonPagedPool, sizeof *VA);
    if (VA == NULL) {
        Status = NDIS_STATUS_RESOURCES;
        goto ErrorReturn;
    }

    KdPrint(("VRR!MiniportInitialize -> VA %p\n", VA));

    RtlZeroMemory(VA, sizeof *VA);
    VA->Index = InterlockedIncrement((PLONG)&NextVirtualAdapterIndex);
    KeInitializeSpinLock(&VA->Lock);
    NeighborCacheInit(&VA->NC);
    NodeTableInit(&VA->NT);
    RouteTableInit(&VA->RT);
    TearDownCacheInit(&VA->TDC);
    ProbeListInit(&VA->PL);
    ZeroListInit(&VA->ZL);
    PacketIndexInit(&VA->PX);
    BroadcastListInit(&VA->BL);
    PbackInit(VA);
    VA->MiniportHandle = MiniportAdapterContext;

    VA->Snooping = TRUE;
    VA->ArtificialDrop = FALSE;
    VA->LinkTimeout = (Time)1 * MINUTE;

    VA->LookAhead = 0;
    VA->MediumLinkSpeed = 100000; // 10 Mbps.
    VA->MediumMinPacketLen = MINIPORT_HEADER_SIZE;
    VA->MediumMaxPacketLen = MINIPORT_HEADER_SIZE + MINIPORT_MAX_FRAME_SIZE;
    VA->MediumMacHeaderLen = MINIPORT_HEADER_SIZE;
    VA->MediumMaxFrameLen = MINIPORT_MAX_FRAME_SIZE;

    VA->MinVersionSeen = Version;
    VA->MaxVersionSeen = Version;

    VA->RateAdmitThreshold = RATE_ADMIT_DEFAULT;
    VA->RateEvictThreshold = RATE_EVICT_DEFAULT;

    VA->RssiAdmitThreshold = RSSI_ADMIT_DEFAULT;
    VA->RssiEvictThreshold = RSSI_EVICT_DEFAULT;

    //
    // Get our device objects.
    //
    NdisMGetDeviceProperty(MiniportAdapterContext,
                           &VA->PhysicalDeviceObject,
                           &VA->DeviceObject,
                           NULL, NULL, NULL);

    //
    // Allocate a packet pool.
    //
    NdisAllocatePacketPool(&Status, &VA->PacketPool,
                           PACKET_POOL_SZ, sizeof(PacketContext));
    if (Status != NDIS_STATUS_SUCCESS) {
        KdPrint(("VRR!NdisAllocatePacketPool -> %x\n", Status));
        goto ErrorFreePool;
    }

    //
    // Allocate a buffer pool.
    //
    NdisAllocateBufferPool(&Status, &VA->BufferPool, PACKET_POOL_SZ * 2);
    if (Status != NDIS_STATUS_SUCCESS) {
        KdPrint(("VRR!NdisAllocateBufferPool -> %x\n", Status));
        goto ErrorFreePacketPool;
    }

    //
    // Give NDIS some information about our virtual adapter.
    //
    NdisMSetAttributesEx(MiniportAdapterContext, VA, 0,
                         NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS |
                         NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
                         NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT |
                         NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND |
                         NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK |
                         NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS |
                         NDIS_ATTRIBUTE_DESERIALIZE,
                         0);

    //
    // Open our configuration information in the registry.
    //
    NtStatus = IoOpenDeviceRegistryKey(VA->PhysicalDeviceObject,
                                       PLUGPLAY_REGKEY_DRIVER,
                                       GENERIC_READ,
                                       &KeyHandle);
    if (! NT_SUCCESS(NtStatus)) {
        KdPrint(("VRR!IoOpenDeviceRegistryKey -> %x\n", NtStatus));
        Status = NDIS_STATUS_FAILURE;
        goto ErrorFreeBufferPool;
    }

    //
    // Read the adapter's virtual link-layer address.
    //
    Status = MiniportReadOrCreateAdapterAddress(KeyHandle, VA->Address);
    if (Status != NDIS_STATUS_SUCCESS)
        goto ErrorCloseRegistry;

    Uint64ToVirtualAddress(VirtualAddressToUint64(VA->Address)-1,VA->AddressDec);
    Uint64ToVirtualAddress(VirtualAddressToUint64(VA->Address)+1,VA->AddressInc);

    VrrTrace(VA,1,"MP:**=Addresses(self-1,self,self+1)",
             VA->AddressDec, VA->Address, VA->AddressInc,NULL,0,NULL,0);

    //
    // Read the adapter's guid.
    //
    NtStatus = GetRegGuid(KeyHandle, L"NetCfgInstanceId", &VA->Guid);
    if (! NT_SUCCESS(NtStatus)) {
        KdPrint(("VRR!GetRegGuid -> %x\n", NtStatus));
        Status = NDIS_STATUS_FAILURE;
        goto ErrorCloseRegistry;
    }

    ZwClose(KeyHandle);

    //
    // Read configuration parameters from the registry.
    //
    MiniportReadControl(VA, &Control);

    // 
    // Initialize Metric parameters.
    // The default MetricType was WCETT - which is now imposed.
    // 
    Control.MetricType = METRIC_TYPE_WCETT;
    switch (Control.MetricType) {
    case METRIC_TYPE_PKTPAIR:
        VA->MetricType = METRIC_TYPE_PKTPAIR;
        PktPairInit(VA);
        break;
    case METRIC_TYPE_WCETT:
    default:
        VA->MetricType = METRIC_TYPE_WCETT;
        WcettInit(VA);
        break;
    }
    
    if (VRR_KEY_PRESENT(Control.CryptoKeyMAC) &&
        VRR_KEY_PRESENT(Control.CryptoKeyAES)) {
        //
        // Initialize the crypto parameters.
        // Crypto will be enabled, unless MiniportControl overrides.
        //
        VA->Crypto = TRUE;
        RtlCopyMemory(VA->CryptoKeyMAC, Control.CryptoKeyMAC,
                      sizeof VA->CryptoKeyMAC);
        RtlCopyMemory(VA->CryptoKeyAES, Control.CryptoKeyAES,
                      sizeof VA->CryptoKeyAES);
    }

#if BUILD_CRYPTO // DDK
    //
    // Modify our MAC key, using Version and MetricType.
    // If they disagree then nodes should fail to communicate.
    //
    CryptoKeyMACModify(VA, VA->CryptoKeyMAC);
#endif

    //
    // Update the virtual adapter using the parameters.
    // This can modify VA->Crypto but not MetricType,
    // CryptoKeyMAC, or CryptoKeyAES.
    //
    (void) MiniportControl(VA, &Control);

    VA->JoiningOnHold = JOINING_ON_HOLD;
    VA->PartitionRepairEnabled = PARTITION_REPAIR_ENABLED;
    VA->BroadcastRelay = BROADCAST_RELAY_ENABLED;
    VA->BroadcastJitterMinMs = BC_MIN_JITTER;
    VA->BroadcastJitterMaxMs = BC_MAX_JITTER;
    VA->TxDropAllButHello = TX_DROP_ALL;
    VA->TxDropAllHello = TX_DROP_HELLO;
    VA->VrrTraceNoiseLevel = DEFAULT_TRACE_NOISE;
    VA->DriverLoadTime = KeQueryInterruptTime() + DriverLoadDelay;

    //
    // Init VrrGlobal.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -