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

📄 msripv6.c

📁 Vitual Ring Routing 管你知不知道
💻 C
字号:
// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs)
//
// (c) Microsoft Corporation. All rights reserved. 
//
// This file is part of the Microsoft Virtual Ring Routing distribution.
// You should have received a copy of the Microsoft Research Shared Source
// license agreement (MSR-SSLA) for this software; see the file "license.txt".
// If not, please see http://research.microsoft.com/vrr/license.htm,
// or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399.
//

//
// This file contains snips of msripv6 code being substituted for missing
// items from Windows DDK build environment.
//
#include "headers.h"

uint RandomValue;

//* Random - Generate a psuedo random value between 1 and 2^32.
//
//  This routine is a quick and dirty psuedo random number generator.
//  It has the advantages of being fast and consuming very little
//  memory (for either code or data).  The random numbers it produces are
//  not of the best quality, however.  A much better generator could be
//  had if we were willing to use an extra 256 bytes of memory for data.
//
//  This routine uses the linear congruential method (see Knuth, Vol II),
//  with specific values for the multiplier and constant taken from
//  Numerical Recipes in C Second Edition by Press, et. al.
//
uint  // Returns: A random value between 1 and 2^32.
Random(void)
{
    //
    // The algorithm is R = (aR + c) mod m, where R is the random number,
    // a is a magic multiplier, c is a constant, and the modulus m is the
    // maximum number of elements in the period.  We chose our m to be 2^32
    // in order to get the mod operation for free.
    // BUGBUG: What about concurrent calls?
    //
    RandomValue = (1664525 * RandomValue) + 1013904223;

    return RandomValue;
}

//* SeedRandom - Provide a seed value.
//
//  Called to provide a seed value for the random number generator.
//
void
SeedRandom(uint Seed)
{
    int i;

    //
    // Incorporate the seed into our random value.
    //
    RandomValue ^= Seed;

    //
    // Stir the bits.
    //
    for (i = 0; i < 100; i++)
        (void) Random();
}

//* RandomNumber
//
//  Returns a number randomly selected from a range.
//
uint
RandomNumber(uint Min, uint Max)
{
    uint Number;

    //
    // Note that the high bits of Random() are much more random
    // than the low bits.
    //
    Number = Max - Min; // Spread.
    Number = (uint)(((ULONGLONG)Random() * Number) >> 32); // Randomize spread.
    Number += Min;

    return Number;
}

//* ChecksumPacket - Calculate the Internet checksum of a packet.
//
//  Taken from msripv6\tcpip6\ip6\subr.c
//
//  Calculates the checksum of packet data. The data may be supplied
//  either with the Packet/Offset arguments, or (if Packet is NULL)
//  the Data argument. In either case, Length specifies how much
//  data to checksum.
//
//  The Packet is assumed to contain (at least) Offset + Length bytes.
//
//  Also calculates and adds-in the pseudo-header checksum,
//  using IP->Source, IP->Dest, Length, and NextHeader.
//  (With options, we may have IP->NextHeader != NextHeader.)
//
ushort
ChecksumPacket(
    PNDIS_PACKET Packet,  // Packet with data to checksum.
    uint Offset,          // Offset into packet where data starts.
    uchar *Data,          // If Packet is NULL, data to checksum.
    uint Length,          // Length of packet data.
    IPv6Addr *Source,     // Source address.
    IPv6Addr *Dest,       // Destination address.
    uchar NextHeader)     // Protocol type for pseudo-header.
{
    PNDIS_BUFFER Buffer = NULL;
    uint Checksum;
    uint PayloadLength;
    uint Size;
    uint TotalSummed;

    //
    // Start with the pseudo-header.
    //
    Checksum = Cksum((unsigned char *)Source, sizeof *Source) + Cksum((unsigned char *)Dest, sizeof *Dest);
    PayloadLength = RtlUlongByteSwap(Length);
    Checksum += (PayloadLength >> 16) + (PayloadLength & 0xffff);
    Checksum += (NextHeader << 8);

    if (Packet == NULL) {
        //
        // We do not have to initialize Buffer.
        // The checksum loop below will exit before trying to use it.
        //
        Size = Length;
        Data += Offset;
    } else {
        //
        // Skip over Offset bytes in the packet.
        //

        Buffer = NdisFirstBuffer(Packet);
        for (;;) {
            Size = NdisBufferLength(Buffer);

            //
            // There is a boundary case here: the Packet contains
            // exactly Offset bytes total, and Length is zero.
            // Checking Offset <= Size instead of Offset < Size
            // makes this work.
            //
            if (Offset <= Size) {
                //Data = NdisBufferVirtualAddressSafe(Buffer, LowPagePriority);
                Data = NdisBufferVirtualAddress(Buffer);
                if (Data == NULL)
                    return 0;

                Data += Offset;
                Size -= Offset;
                break;
            }

            Offset -= Size;
            NdisGetNextBuffer(Buffer, &Buffer);
            ASSERT(Buffer != NULL); // Caller ensures this.
        }
    }
    for (TotalSummed = 0;;) {
        ushort Temp;

        //
        // Size might be bigger than we need,
        // if there is "extra" data in the packet.
        //
        if (Size > Length)
            Size = Length;

        Temp = Cksum(Data, Size);
        if (TotalSummed & 1) {
            // We're at an odd offset into the logical buffer,
            // so we need to swap the bytes that Cksum returns.
            Checksum += (Temp >> 8) + ((Temp & 0xff) << 8);
        } else {
            Checksum += Temp;
        }
        TotalSummed += Size;

        Length -= Size;
        if (Length == 0)
            break;
        // Buffer is always initialized if we reach here.
        // So the next clause is redundant, but keeps PreFast happy.
        if (Buffer == NULL)
            break;
        NdisGetNextBuffer(Buffer, &Buffer);
        NdisQueryBufferSafe(Buffer, &Data, &Size, LowPagePriority);
        if (Data == NULL)
            return 0;
    }

    //
    // Wrap in the carries to reduce Checksum to 16 bits.
    // (Twice is sufficient because it can only overflow once.)
    //
    Checksum = (Checksum >> 16) + (Checksum & 0xffff);
    Checksum += (Checksum >> 16);

    //
    // Take ones-complement and replace 0 with 0xffff.
    //
    Checksum = (ushort) ~Checksum;
    if (Checksum == 0)
        Checksum = 0xffff;

    return (ushort) Checksum;
}


⌨️ 快捷键说明

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