📄 ipv4.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 + -