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

📄 ipv4.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 procedures for supporting IPv4 over VRR.
//

#include "headers.h"
#include <packon.h>
#include <ipexport.h>

extern void
MiniportTransmitPacket(
    MiniportAdapter *VA,
    NDIS_PACKET *Packet);

extern void
MiniportFreePacket(
    ProtocolAdapter *PA,
    NDIS_PACKET *Packet);

extern void
MiniportReceiveLocally(
    MiniportAdapter *VA,
    SRPacket *srp,
    void (*Complete)(MiniportAdapter *VA, SRPacket *srp, NDIS_STATUS Status));

extern void
MiniportReceiveComplete(
    MiniportAdapter *VA,
    SRPacket *srp,
    NDIS_STATUS Status);

// Forward declaration.
boolint
IPv6FakeDHTtxNA(
    MiniportAdapter *VA,
    IPv6Addr SolicitSource);



#define ETYPE_IPv6 0x86dd
// gregos: these so we can snip types from ipv6 header files.
typedef unsigned char   u_char;
typedef unsigned short  u_short;
typedef unsigned int    u_int;
typedef unsigned long   u_long;
typedef unsigned char   uchar;
typedef unsigned short  ushort;
typedef unsigned long   ulong;
typedef struct in6_addr in6_addr;

//
// Ref arpdef.h
// Ref ip.h for struct IPv4 header.
//
typedef struct ARPHeader {
    ushort      HardwareType;
    ushort      ProtoType;
    uchar       HWAddrLen;
    uchar       ProtoAddrLen;
    ushort      Opcode;
    uchar       SrcHWAddr[IEEE_802_ADDR_LENGTH];
    IPAddr      SrcProtoAddr;
    uchar       DestHWAddr[IEEE_802_ADDR_LENGTH];
    IPAddr      DestProtoAddr;
} ARPHeader;

#define ETYPE_IP            0x800                 // This in network byte order.
#define ETYPE_ARP           0x806                 // This in network byte order.
#define ARP_OPCODE_REQUEST  1
#define ARP_HW_TYPE_ETH     1
#define ARP_HW_TYPE_802     6

//* IPv4TrapOutboundARPRequest
//
// ARP is handled by a DHT application, in support of which we
// trap outbound ARP requests, send them via upcall to VRR API,
// and drop the original packet.
//
boolint
IPv4TrapOutboundARPRequest(
    MiniportAdapter *VA,
    NDIS_PACKET *Packet,
    EtherHeader *eth)
{
    char *BufferAddress;
    uint BufferLength;
    uint PacketLength;
    NDIS_BUFFER *Buffer;
    char *FlatBuffer;
    const uint MinPacketLength = sizeof(EtherHeader)
                               + sizeof(ARPHeader);
    EtherHeader UNALIGNED *FlatEth;
    ARPHeader UNALIGNED *ARP;
    uint Result = FALSE;

    //
    // Low cost check that this ought to be an ARP packet.
    //
    if (RtlUshortByteSwap(eth->Type) != ETYPE_ARP)
        return FALSE;

    //
    // More thorough checking that this is ARP request.
    //
    Buffer = NdisFirstBuffer(Packet);
    NdisQueryBuffer(Buffer, &BufferAddress, &BufferLength);
    NdisQueryPacketLength(Packet, &PacketLength);

    if (PacketLength < MinPacketLength)
        return FALSE;

    //
    // Construct a local flat buffer from (multiple) buffers.
    //
    FlatBuffer = AllocFlatBuffer(Packet,PacketLength);

    if (FlatBuffer == NULL)
        return FALSE;

    FlatEth = (EtherHeader UNALIGNED *)FlatBuffer;
    ARP = (ARPHeader UNALIGNED *)(FlatEth + 1);

    if (RtlUshortByteSwap(ARP->HardwareType) != ARP_HW_TYPE_ETH && 
        RtlUshortByteSwap(ARP->HardwareType) != ARP_HW_TYPE_802)
        goto ReleaseAndReturn;

    if (RtlUshortByteSwap(ARP->ProtoType) != ETYPE_IP ||
        ARP->HWAddrLen != sizeof(PhysicalAddress) ||
        ARP->ProtoAddrLen != sizeof(IPAddr) ||
        RtlUshortByteSwap(ARP->Opcode) != ARP_OPCODE_REQUEST)
        goto ReleaseAndReturn;

    //
    // We believe this to be an ARP request. Punt (upcall) the
    // whole as payload to a DHT_TRAP_PACKET call, and drop the
    // original packet.
    //
    KdPrint(("VrrKdPrint: (%u) IPv4TrapARPReq: saw ARP request for %08x\n",
             TIMESTAMP, RtlUlongByteSwap(ARP->DestProtoAddr)));

    DHTDriverRequest(VA,
                     DHT_TRAP_PACKET,
                     (DHTHeader *)FlatBuffer,
                     (ushort)PacketLength,
                     DHT_DEFAULT_UDP_PORT);

    Result = TRUE;

ReleaseAndReturn:

    if (FlatBuffer != NULL)
        ExFreePool(FlatBuffer);

    return Result;

}

#include <packoff.h>

⌨️ 快捷键说明

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