Added networking code from Casper Hornstrup

svn path=/trunk/; revision=1283
This commit is contained in:
David Welch
2000-08-02 00:24:26 +00:00
parent b5ff23bb2f
commit a859ee0c1e
82 changed files with 13646 additions and 12262 deletions
+19 -5
View File
@@ -34,11 +34,16 @@ LOADERS = dos
#
# Select the device drivers and filesystems you want
#
DEVICE_DRIVERS = blue ide keyboard null parallel serial vidport floppy
# DEVICE_DRIVERS = beep event floppy ide_test mouse sound test test1
FS_DRIVERS = vfat minix
DEVICE_DRIVERS = vga blue ide keyboard null parallel serial vidport
# DEVICE_DRIVERS = beep event floppy ide_test mouse sound test test1
FS_DRIVERS = vfat
# FS_DRIVERS = minix ext2 template
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS)
# ndis tdi tcpip tditest
NET_DRIVERS = ndis tcpip tditest
KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS) $(NET_DRIVERS)
APPS = args hello shell test cat bench apc shm lpc thread event file gditest \
pteb consume
@@ -54,7 +59,7 @@ clean: buildno_clean $(COMPONENTS:%=%_clean) $(DLLS:%=%_clean) $(LOADERS:%=%_cle
.PHONY: clean
install_floppy: make_floppy_dirs autoexec_floppy $(COMPONENTS:%=%_floppy) \
floppy: make_floppy_dirs autoexec_floppy $(COMPONENTS:%=%_floppy) \
$(DLLS:%=%_floppy) $(LOADERS:%=%_floppy) \
$(KERNEL_SERVICES:%=%_floppy) $(SUBSYS:%=%_floppy) \
$(APPS:%=%_floppy)
@@ -155,6 +160,15 @@ $(FS_DRIVERS:%=%_dist): %_dist:
.PHONY: $(FS_DRIVERS) $(FS_DRIVERS:%=%_clean) $(FS_DRIVERS:%=%_floppy) \
$(FS_DRIVERS:%=%_dist)
$(NET_DRIVERS): %:
make -C services/net/$*
$(NET_DRIVERS:%=%_clean): %_clean:
make -C services/net/$* clean
.PHONY: $(NET_DRIVERS) $(NET_DRIVERS:%=%_clean)
#
# Kernel loaders
+5 -5
View File
@@ -1,5 +1,5 @@
DIRS= datalink \
network \
transport \
tcpip
DIRS= datalink \
network \
transport \
tcpip
+7 -7
View File
@@ -1,7 +1,7 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
+13 -13
View File
@@ -1,13 +1,13 @@
TARGETNAME=datalink
TARGETPATH=..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\include;$(BASEDIR)\INC;..\..\..\..\include\net
SOURCES= arp.c \
lan.c \
loopback.c
MSC_WARNING_LEVEL=/W3 /WX
TARGETNAME=datalink
TARGETPATH=..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\include;$(BASEDIR)\INC;..\..\..\..\include\net
SOURCES= arp.c \
lan.c \
loopback.c
MSC_WARNING_LEVEL=/W3 /WX
+277 -277
View File
@@ -1,277 +1,277 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: datalink/arp.c
* PURPOSE: Address Resolution Protocol routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <arp.h>
#include <routines.h>
#include <neighbor.h>
#include <address.h>
#include <pool.h>
#include <lan.h>
PNDIS_PACKET PrepareARPPacket(
USHORT HardwareType,
USHORT ProtocolType,
UCHAR LinkAddressLength,
UCHAR ProtoAddressLength,
PVOID SenderLinkAddress,
PVOID SenderProtoAddress,
PVOID TargetLinkAddress,
PVOID TargetProtoAddress,
USHORT Opcode)
/*
* FUNCTION: Prepares an ARP packet
* ARGUMENTS:
* HardwareType = Hardware type (in network byte order)
* ProtocolType = Protocol type (in network byte order)
* LinkAddressLength = Length of link address fields
* ProtoAddressLength = Length of protocol address fields
* SenderLinkAddress = Sender's link address
* SenderProtoAddress = Sender's protocol address
* TargetLinkAddress = Target's link address (NULL if don't care)
* TargetProtoAddress = Target's protocol address
* Opcode = ARP opcode (in network byte order)
* RETURNS:
* Pointer to NDIS packet, NULL if there is not enough free resources
*/
{
PNDIS_PACKET NdisPacket;
PNDIS_BUFFER NdisBuffer;
NDIS_STATUS NdisStatus;
PARP_HEADER Header;
PVOID DataBuffer;
ULONG Size;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* Prepare ARP packet */
Size = MaxLLHeaderSize + sizeof(ARP_HEADER) +
2 * LinkAddressLength + /* Hardware address length */
2 * ProtoAddressLength; /* Protocol address length */
Size = MAX(Size, MinLLFrameSize);
DataBuffer = ExAllocatePool(NonPagedPool, Size);
if (!DataBuffer)
return NULL;
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
ExFreePool(DataBuffer);
return NULL;
}
/* Allocate NDIS buffer for maximum link level header and ARP packet */
NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
DataBuffer, Size);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
NdisFreePacket(NdisPacket);
ExFreePool(DataBuffer);
return NULL;
}
/* Link NDIS buffer into packet */
NdisChainBufferAtFront(NdisPacket, NdisBuffer);
RtlZeroMemory(DataBuffer, Size);
Header = (PARP_HEADER)((ULONG_PTR)DataBuffer + MaxLLHeaderSize);
Header->HWType = HardwareType;
Header->ProtoType = ProtocolType;
Header->HWAddrLen = LinkAddressLength;
Header->ProtoAddrLen = ProtoAddressLength;
Header->Opcode = Opcode; /* Already swapped */
DataBuffer = (PVOID)((ULONG_PTR)Header + sizeof(ARP_HEADER));
/* Our hardware address */
RtlCopyMemory(DataBuffer, SenderLinkAddress, LinkAddressLength);
(ULONG_PTR)DataBuffer += LinkAddressLength;
/* Our protocol address */
RtlCopyMemory(DataBuffer, SenderProtoAddress, ProtoAddressLength);
if (TargetLinkAddress) {
(ULONG_PTR)DataBuffer += ProtoAddressLength;
/* Target hardware address */
RtlCopyMemory(DataBuffer, TargetLinkAddress, LinkAddressLength);
(ULONG_PTR)DataBuffer += LinkAddressLength;
} else
/* Don't care about target hardware address */
(ULONG_PTR)DataBuffer += (ProtoAddressLength + LinkAddressLength);
/* Target protocol address */
RtlCopyMemory(DataBuffer, TargetProtoAddress, ProtoAddressLength);
return NdisPacket;
}
VOID ARPTransmitComplete(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus)
/*
* FUNCTION: ARP request transmit completion handler
* ARGUMENTS:
* Context = Pointer to context information (IP_INTERFACE)
* Packet = Pointer to NDIS packet that was sent
* NdisStatus = NDIS status of operation
* NOTES:
* This routine is called when an ARP request has been sent
*/
{
TI_DbgPrint(MID_TRACE, ("Called.\n"));
FreeNdisPacket(NdisPacket);
}
BOOLEAN ARPTransmit(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE)
/*
* FUNCTION: Creates an ARP request and transmits it on a network
* ARGUMENTS:
* Address = Pointer to IP address to resolve
* NTE = Pointer to net table entru to use for transmitting request
* RETURNS:
* TRUE if the request was successfully sent, FALSE if not
*/
{
PIP_INTERFACE Interface;
PNDIS_PACKET NdisPacket;
UCHAR ProtoAddrLen;
USHORT ProtoType;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Interface = NTE->Interface;
switch (Address->Type) {
case IP_ADDRESS_V4:
ProtoType = (USHORT)ETYPE_IPv4; /* IPv4 */
ProtoAddrLen = 4; /* Length of IPv4 address */
break;
case IP_ADDRESS_V6:
ProtoType = (USHORT)ETYPE_IPv6; /* IPv6 */
ProtoAddrLen = 16; /* Length of IPv6 address */
break;
default:
/* Should not happen */
return FALSE;
}
NdisPacket = PrepareARPPacket(
WN2H(0x0001), /* FIXME: Ethernet only */
ProtoType, /* Protocol type */
(UCHAR)Interface->AddressLength, /* Hardware address length */
(UCHAR)ProtoAddrLen, /* Protocol address length */
Interface->Address, /* Sender's (local) hardware address */
&NTE->Address->Address, /* Sender's (local) protocol address */
NULL, /* Don't care */
&Address->Address, /* Target's (remote) protocol address */
ARP_OPCODE_REQUEST); /* ARP request */
PC(NdisPacket)->DLComplete = ARPTransmitComplete;
(*Interface->Transmit)(Interface->Context, NdisPacket,
MaxLLHeaderSize, NULL, LAN_PROTO_ARP);
return TRUE;
}
VOID ARPReceive(
PVOID Context,
PIP_PACKET Packet)
/*
* FUNCTION: Receives an ARP packet
* ARGUMENTS:
* Context = Pointer to context information (IP_INTERFACE)
* Packet = Pointer to packet
*/
{
PARP_HEADER Header;
PIP_ADDRESS Address;
PVOID SenderHWAddress;
PVOID SenderProtoAddress;
PVOID TargetProtoAddress;
PADDRESS_ENTRY ADE;
PNEIGHBOR_CACHE_ENTRY NCE;
PNDIS_PACKET NdisPacket;
PIP_INTERFACE Interface = (PIP_INTERFACE)Context;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Header = (PARP_HEADER)Packet->Header;
/* FIXME: Ethernet only */
if (WN2H(Header->HWType) != 1)
return;
/* Check protocol type */
if (Header->ProtoType != ETYPE_IPv4)
return;
SenderHWAddress = (PVOID)((ULONG_PTR)Header + sizeof(ARP_HEADER));
SenderProtoAddress = (PVOID)((ULONG_PTR)SenderHWAddress + Header->HWAddrLen);
/* Check if we have the target protocol address */
TargetProtoAddress = (PVOID)((ULONG_PTR)SenderProtoAddress +
Header->ProtoAddrLen + Header->HWAddrLen);
Address = AddrBuildIPv4(*(PULONG)(TargetProtoAddress));
ADE = IPLocateADE(Address, ADE_UNICAST);
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return;
}
/* Check if we know the sender */
AddrInitIPv4(Address, *(PULONG)(SenderProtoAddress));
NCE = NBLocateNeighbor(Address);
if (NCE) {
DereferenceObject(Address);
/* We know the sender. Update the hardware address
and state in our neighbor address cache */
NBUpdateNeighbor(NCE, SenderHWAddress, NUD_REACHABLE);
} else {
/* The packet had our protocol address as target. The sender
may want to communicate with us soon, so add his address
to our address cache */
NCE = NBAddNeighbor(Interface, Address, SenderHWAddress,
Header->HWAddrLen, NUD_REACHABLE);
}
if (NCE)
DereferenceObject(NCE)
if (Header->Opcode != ARP_OPCODE_REQUEST)
return;
/* This is a request for our address. Swap the addresses and
send an ARP reply back to the sender */
NdisPacket = PrepareARPPacket(
Header->HWType, /* Hardware type */
Header->ProtoType, /* Protocol type */
(UCHAR)Interface->AddressLength, /* Hardware address length */
(UCHAR)Header->ProtoAddrLen, /* Protocol address length */
Interface->Address, /* Sender's (local) hardware address */
&ADE->Address->Address, /* Sender's (local) protocol address */
SenderHWAddress, /* Target's (remote) hardware address */
SenderProtoAddress, /* Target's (remote) protocol address */
ARP_OPCODE_REPLY); /* ARP reply */
if (NdisPacket) {
PC(NdisPacket)->DLComplete = ARPTransmitComplete;
(*Interface->Transmit)(Interface->Context, NdisPacket,
MaxLLHeaderSize, SenderHWAddress, LAN_PROTO_ARP);
}
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: datalink/arp.c
* PURPOSE: Address Resolution Protocol routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <arp.h>
#include <routines.h>
#include <neighbor.h>
#include <address.h>
#include <pool.h>
#include <lan.h>
PNDIS_PACKET PrepareARPPacket(
USHORT HardwareType,
USHORT ProtocolType,
UCHAR LinkAddressLength,
UCHAR ProtoAddressLength,
PVOID SenderLinkAddress,
PVOID SenderProtoAddress,
PVOID TargetLinkAddress,
PVOID TargetProtoAddress,
USHORT Opcode)
/*
* FUNCTION: Prepares an ARP packet
* ARGUMENTS:
* HardwareType = Hardware type (in network byte order)
* ProtocolType = Protocol type (in network byte order)
* LinkAddressLength = Length of link address fields
* ProtoAddressLength = Length of protocol address fields
* SenderLinkAddress = Sender's link address
* SenderProtoAddress = Sender's protocol address
* TargetLinkAddress = Target's link address (NULL if don't care)
* TargetProtoAddress = Target's protocol address
* Opcode = ARP opcode (in network byte order)
* RETURNS:
* Pointer to NDIS packet, NULL if there is not enough free resources
*/
{
PNDIS_PACKET NdisPacket;
PNDIS_BUFFER NdisBuffer;
NDIS_STATUS NdisStatus;
PARP_HEADER Header;
PVOID DataBuffer;
ULONG Size;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* Prepare ARP packet */
Size = MaxLLHeaderSize + sizeof(ARP_HEADER) +
2 * LinkAddressLength + /* Hardware address length */
2 * ProtoAddressLength; /* Protocol address length */
Size = MAX(Size, MinLLFrameSize);
DataBuffer = ExAllocatePool(NonPagedPool, Size);
if (!DataBuffer)
return NULL;
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
ExFreePool(DataBuffer);
return NULL;
}
/* Allocate NDIS buffer for maximum link level header and ARP packet */
NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
DataBuffer, Size);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
NdisFreePacket(NdisPacket);
ExFreePool(DataBuffer);
return NULL;
}
/* Link NDIS buffer into packet */
NdisChainBufferAtFront(NdisPacket, NdisBuffer);
RtlZeroMemory(DataBuffer, Size);
Header = (PARP_HEADER)((ULONG_PTR)DataBuffer + MaxLLHeaderSize);
Header->HWType = HardwareType;
Header->ProtoType = ProtocolType;
Header->HWAddrLen = LinkAddressLength;
Header->ProtoAddrLen = ProtoAddressLength;
Header->Opcode = Opcode; /* Already swapped */
DataBuffer = (PVOID)((ULONG_PTR)Header + sizeof(ARP_HEADER));
/* Our hardware address */
RtlCopyMemory(DataBuffer, SenderLinkAddress, LinkAddressLength);
(ULONG_PTR)DataBuffer += LinkAddressLength;
/* Our protocol address */
RtlCopyMemory(DataBuffer, SenderProtoAddress, ProtoAddressLength);
if (TargetLinkAddress) {
(ULONG_PTR)DataBuffer += ProtoAddressLength;
/* Target hardware address */
RtlCopyMemory(DataBuffer, TargetLinkAddress, LinkAddressLength);
(ULONG_PTR)DataBuffer += LinkAddressLength;
} else
/* Don't care about target hardware address */
(ULONG_PTR)DataBuffer += (ProtoAddressLength + LinkAddressLength);
/* Target protocol address */
RtlCopyMemory(DataBuffer, TargetProtoAddress, ProtoAddressLength);
return NdisPacket;
}
VOID ARPTransmitComplete(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus)
/*
* FUNCTION: ARP request transmit completion handler
* ARGUMENTS:
* Context = Pointer to context information (IP_INTERFACE)
* Packet = Pointer to NDIS packet that was sent
* NdisStatus = NDIS status of operation
* NOTES:
* This routine is called when an ARP request has been sent
*/
{
TI_DbgPrint(MID_TRACE, ("Called.\n"));
FreeNdisPacket(NdisPacket);
}
BOOLEAN ARPTransmit(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE)
/*
* FUNCTION: Creates an ARP request and transmits it on a network
* ARGUMENTS:
* Address = Pointer to IP address to resolve
* NTE = Pointer to net table entru to use for transmitting request
* RETURNS:
* TRUE if the request was successfully sent, FALSE if not
*/
{
PIP_INTERFACE Interface;
PNDIS_PACKET NdisPacket;
UCHAR ProtoAddrLen;
USHORT ProtoType;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Interface = NTE->Interface;
switch (Address->Type) {
case IP_ADDRESS_V4:
ProtoType = (USHORT)ETYPE_IPv4; /* IPv4 */
ProtoAddrLen = 4; /* Length of IPv4 address */
break;
case IP_ADDRESS_V6:
ProtoType = (USHORT)ETYPE_IPv6; /* IPv6 */
ProtoAddrLen = 16; /* Length of IPv6 address */
break;
default:
/* Should not happen */
return FALSE;
}
NdisPacket = PrepareARPPacket(
WN2H(0x0001), /* FIXME: Ethernet only */
ProtoType, /* Protocol type */
(UCHAR)Interface->AddressLength, /* Hardware address length */
(UCHAR)ProtoAddrLen, /* Protocol address length */
Interface->Address, /* Sender's (local) hardware address */
&NTE->Address->Address, /* Sender's (local) protocol address */
NULL, /* Don't care */
&Address->Address, /* Target's (remote) protocol address */
ARP_OPCODE_REQUEST); /* ARP request */
PC(NdisPacket)->DLComplete = ARPTransmitComplete;
(*Interface->Transmit)(Interface->Context, NdisPacket,
MaxLLHeaderSize, NULL, LAN_PROTO_ARP);
return TRUE;
}
VOID ARPReceive(
PVOID Context,
PIP_PACKET Packet)
/*
* FUNCTION: Receives an ARP packet
* ARGUMENTS:
* Context = Pointer to context information (IP_INTERFACE)
* Packet = Pointer to packet
*/
{
PARP_HEADER Header;
PIP_ADDRESS Address;
PVOID SenderHWAddress;
PVOID SenderProtoAddress;
PVOID TargetProtoAddress;
PADDRESS_ENTRY ADE;
PNEIGHBOR_CACHE_ENTRY NCE;
PNDIS_PACKET NdisPacket;
PIP_INTERFACE Interface = (PIP_INTERFACE)Context;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Header = (PARP_HEADER)Packet->Header;
/* FIXME: Ethernet only */
if (WN2H(Header->HWType) != 1)
return;
/* Check protocol type */
if (Header->ProtoType != ETYPE_IPv4)
return;
SenderHWAddress = (PVOID)((ULONG_PTR)Header + sizeof(ARP_HEADER));
SenderProtoAddress = (PVOID)((ULONG_PTR)SenderHWAddress + Header->HWAddrLen);
/* Check if we have the target protocol address */
TargetProtoAddress = (PVOID)((ULONG_PTR)SenderProtoAddress +
Header->ProtoAddrLen + Header->HWAddrLen);
Address = AddrBuildIPv4(*(PULONG)(TargetProtoAddress));
ADE = IPLocateADE(Address, ADE_UNICAST);
if (!ADE) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return;
}
/* Check if we know the sender */
AddrInitIPv4(Address, *(PULONG)(SenderProtoAddress));
NCE = NBLocateNeighbor(Address);
if (NCE) {
DereferenceObject(Address);
/* We know the sender. Update the hardware address
and state in our neighbor address cache */
NBUpdateNeighbor(NCE, SenderHWAddress, NUD_REACHABLE);
} else {
/* The packet had our protocol address as target. The sender
may want to communicate with us soon, so add his address
to our address cache */
NCE = NBAddNeighbor(Interface, Address, SenderHWAddress,
Header->HWAddrLen, NUD_REACHABLE);
}
if (NCE)
DereferenceObject(NCE)
if (Header->Opcode != ARP_OPCODE_REQUEST)
return;
/* This is a request for our address. Swap the addresses and
send an ARP reply back to the sender */
NdisPacket = PrepareARPPacket(
Header->HWType, /* Hardware type */
Header->ProtoType, /* Protocol type */
(UCHAR)Interface->AddressLength, /* Hardware address length */
(UCHAR)Header->ProtoAddrLen, /* Protocol address length */
Interface->Address, /* Sender's (local) hardware address */
&ADE->Address->Address, /* Sender's (local) protocol address */
SenderHWAddress, /* Target's (remote) hardware address */
SenderProtoAddress, /* Target's (remote) protocol address */
ARP_OPCODE_REPLY); /* ARP reply */
if (NdisPacket) {
PC(NdisPacket)->DLComplete = ARPTransmitComplete;
(*Interface->Transmit)(Interface->Context, NdisPacket,
MaxLLHeaderSize, SenderHWAddress, LAN_PROTO_ARP);
}
}
/* EOF */
File diff suppressed because it is too large Load Diff
+224 -224
View File
@@ -1,224 +1,224 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: datalink/loopback.c
* PURPOSE: Loopback adapter
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <loopback.h>
#include <ip.h>
#include <address.h>
#include <receive.h>
#include <transmit.h>
#include <routines.h>
WORK_QUEUE_ITEM LoopWorkItem;
PIP_INTERFACE Loopback = NULL;
/* Indicates wether the loopback interface is currently transmitting */
BOOLEAN LoopBusy = FALSE;
/* Loopback transmit queue */
PNDIS_PACKET LoopQueueHead = (PNDIS_PACKET)NULL;
PNDIS_PACKET LoopQueueTail = (PNDIS_PACKET)NULL;
/* Spin lock for protecting loopback transmit queue */
KSPIN_LOCK LoopLock;
VOID RealTransmit(
PVOID Context)
/*
* FUNCTION: Transmits one or more packet(s) in loopback queue to ourselves
* ARGUMENTS:
* Context = Pointer to context information (loopback interface)
*/
{
KIRQL OldIrql;
PNDIS_PACKET NdisPacket;
IP_PACKET IPPacket;
PNDIS_BUFFER Buffer;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&LoopLock);
for (;;) {
/* Get the next packet from the queue (if any) */
NdisPacket = LoopQueueHead;
if (!NdisPacket)
break;
LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->MacReserved;
KeReleaseSpinLockFromDpcLevel(&LoopLock);
IPPacket.NdisPacket = NdisPacket;
NdisGetFirstBufferFromPacket(NdisPacket,
&Buffer,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
IPReceive(Context, &IPPacket);
AdjustPacket(NdisPacket, 0, PC(NdisPacket)->DLOffset);
PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
/* Lower IRQL for a moment to prevent starvation */
KeLowerIrql(OldIrql);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&LoopLock);
}
LoopBusy = FALSE;
KeReleaseSpinLockFromDpcLevel(&LoopLock);
KeLowerIrql(OldIrql);
}
VOID LoopTransmit(
PVOID Context,
PNDIS_PACKET NdisPacket,
UINT Offset,
PVOID LinkAddress,
USHORT Type)
/*
* FUNCTION: Transmits a packet
* ARGUMENTS:
* Context = Pointer to context information (NULL)
* NdisPacket = Pointer to NDIS packet to send
* Offset = Offset in packet where packet data starts
* LinkAddress = Pointer to link address
* Type = LAN protocol type (unused)
*/
{
PNDIS_PACKET *pNdisPacket;
KIRQL OldIrql;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
/* NDIS send routines don't have an offset argument so we
must offset the data in upper layers and adjust the
packet here. We save the offset in the packet context
area so it can be undone before we release the packet */
AdjustPacket(NdisPacket, Offset, 0);
PC(NdisPacket)->DLOffset = Offset;
pNdisPacket = (PNDIS_PACKET*)NdisPacket->MacReserved;
*pNdisPacket = NULL;
KeAcquireSpinLock(&LoopLock, &OldIrql);
/* Add packet to transmit queue */
if (LoopQueueHead) {
/* Transmit queue is not empty */
pNdisPacket = (PNDIS_PACKET*)LoopQueueTail->MacReserved;
*pNdisPacket = NdisPacket;
} else
/* Transmit queue is empty */
LoopQueueHead = NdisPacket;
LoopQueueTail = NdisPacket;
/* If LoopTransmit is not running (or scheduled), schedule it to run */
if (!LoopBusy) {
ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
LoopBusy = TRUE;
}
KeReleaseSpinLock(&LoopLock, OldIrql);
}
NDIS_STATUS LoopRegisterAdapter(
PNDIS_STRING AdapterName,
PLAN_ADAPTER *Adapter)
/*
* FUNCTION: Registers loopback adapter
* ARGUMENTS:
* AdapterName = Unused
* Adapter = Unused
* RETURNS:
* Status of operation
*/
{
PIP_ADDRESS Address;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Address = AddrBuildIPv4(LOOPBACK_ADDRESS_IPv4);
if (Address) {
LLIP_BIND_INFO BindInfo;
/* Bind the adapter to IP layer */
BindInfo.Context = NULL;
BindInfo.HeaderSize = 0;
BindInfo.MinFrameSize = 0;
BindInfo.MTU = 16384;
BindInfo.Address = NULL;
BindInfo.AddressLength = 0;
BindInfo.Transmit = LoopTransmit;
Loopback = IPCreateInterface(&BindInfo);
if ((Loopback) && (IPCreateNTE(Loopback, Address, 8))) {
/* Reference the interface for the NTE. The reference for
the address is just passed on to the NTE */
ReferenceObject(Loopback);
IPRegisterInterface(Loopback);
ExInitializeWorkItem(&LoopWorkItem, RealTransmit, Loopback);
KeInitializeSpinLock(&LoopLock);
LoopBusy = FALSE;
} else
Status = NDIS_STATUS_RESOURCES;
} else
Status = NDIS_STATUS_RESOURCES;
if (!NT_SUCCESS(Status))
LoopUnregisterAdapter(NULL);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return Status;
}
NDIS_STATUS LoopUnregisterAdapter(
PLAN_ADAPTER Adapter)
/*
* FUNCTION: Unregisters loopback adapter
* ARGUMENTS:
* Adapter = Unused
* RETURNS:
* Status of operation
* NOTES:
* Does not care wether we have registered loopback adapter
*/
{
TI_DbgPrint(MID_TRACE, ("Called.\n"));
if (Loopback) {
IPUnregisterInterface(Loopback);
IPDestroyInterface(Loopback);
Loopback = NULL;
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return NDIS_STATUS_SUCCESS;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: datalink/loopback.c
* PURPOSE: Loopback adapter
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <loopback.h>
#include <ip.h>
#include <address.h>
#include <receive.h>
#include <transmit.h>
#include <routines.h>
WORK_QUEUE_ITEM LoopWorkItem;
PIP_INTERFACE Loopback = NULL;
/* Indicates wether the loopback interface is currently transmitting */
BOOLEAN LoopBusy = FALSE;
/* Loopback transmit queue */
PNDIS_PACKET LoopQueueHead = (PNDIS_PACKET)NULL;
PNDIS_PACKET LoopQueueTail = (PNDIS_PACKET)NULL;
/* Spin lock for protecting loopback transmit queue */
KSPIN_LOCK LoopLock;
VOID RealTransmit(
PVOID Context)
/*
* FUNCTION: Transmits one or more packet(s) in loopback queue to ourselves
* ARGUMENTS:
* Context = Pointer to context information (loopback interface)
*/
{
KIRQL OldIrql;
PNDIS_PACKET NdisPacket;
IP_PACKET IPPacket;
PNDIS_BUFFER Buffer;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&LoopLock);
for (;;) {
/* Get the next packet from the queue (if any) */
NdisPacket = LoopQueueHead;
if (!NdisPacket)
break;
LoopQueueHead = *(PNDIS_PACKET*)NdisPacket->MacReserved;
KeReleaseSpinLockFromDpcLevel(&LoopLock);
IPPacket.NdisPacket = NdisPacket;
NdisGetFirstBufferFromPacket(NdisPacket,
&Buffer,
&IPPacket.Header,
&IPPacket.ContigSize,
&IPPacket.TotalSize);
IPReceive(Context, &IPPacket);
AdjustPacket(NdisPacket, 0, PC(NdisPacket)->DLOffset);
PC(NdisPacket)->DLComplete(Context, NdisPacket, NDIS_STATUS_SUCCESS);
/* Lower IRQL for a moment to prevent starvation */
KeLowerIrql(OldIrql);
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&LoopLock);
}
LoopBusy = FALSE;
KeReleaseSpinLockFromDpcLevel(&LoopLock);
KeLowerIrql(OldIrql);
}
VOID LoopTransmit(
PVOID Context,
PNDIS_PACKET NdisPacket,
UINT Offset,
PVOID LinkAddress,
USHORT Type)
/*
* FUNCTION: Transmits a packet
* ARGUMENTS:
* Context = Pointer to context information (NULL)
* NdisPacket = Pointer to NDIS packet to send
* Offset = Offset in packet where packet data starts
* LinkAddress = Pointer to link address
* Type = LAN protocol type (unused)
*/
{
PNDIS_PACKET *pNdisPacket;
KIRQL OldIrql;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
/* NDIS send routines don't have an offset argument so we
must offset the data in upper layers and adjust the
packet here. We save the offset in the packet context
area so it can be undone before we release the packet */
AdjustPacket(NdisPacket, Offset, 0);
PC(NdisPacket)->DLOffset = Offset;
pNdisPacket = (PNDIS_PACKET*)NdisPacket->MacReserved;
*pNdisPacket = NULL;
KeAcquireSpinLock(&LoopLock, &OldIrql);
/* Add packet to transmit queue */
if (LoopQueueHead) {
/* Transmit queue is not empty */
pNdisPacket = (PNDIS_PACKET*)LoopQueueTail->MacReserved;
*pNdisPacket = NdisPacket;
} else
/* Transmit queue is empty */
LoopQueueHead = NdisPacket;
LoopQueueTail = NdisPacket;
/* If LoopTransmit is not running (or scheduled), schedule it to run */
if (!LoopBusy) {
ExQueueWorkItem(&LoopWorkItem, CriticalWorkQueue);
LoopBusy = TRUE;
}
KeReleaseSpinLock(&LoopLock, OldIrql);
}
NDIS_STATUS LoopRegisterAdapter(
PNDIS_STRING AdapterName,
PLAN_ADAPTER *Adapter)
/*
* FUNCTION: Registers loopback adapter
* ARGUMENTS:
* AdapterName = Unused
* Adapter = Unused
* RETURNS:
* Status of operation
*/
{
PIP_ADDRESS Address;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
Address = AddrBuildIPv4(LOOPBACK_ADDRESS_IPv4);
if (Address) {
LLIP_BIND_INFO BindInfo;
/* Bind the adapter to IP layer */
BindInfo.Context = NULL;
BindInfo.HeaderSize = 0;
BindInfo.MinFrameSize = 0;
BindInfo.MTU = 16384;
BindInfo.Address = NULL;
BindInfo.AddressLength = 0;
BindInfo.Transmit = LoopTransmit;
Loopback = IPCreateInterface(&BindInfo);
if ((Loopback) && (IPCreateNTE(Loopback, Address, 8))) {
/* Reference the interface for the NTE. The reference for
the address is just passed on to the NTE */
ReferenceObject(Loopback);
IPRegisterInterface(Loopback);
ExInitializeWorkItem(&LoopWorkItem, RealTransmit, Loopback);
KeInitializeSpinLock(&LoopLock);
LoopBusy = FALSE;
} else
Status = NDIS_STATUS_RESOURCES;
} else
Status = NDIS_STATUS_RESOURCES;
if (!NT_SUCCESS(Status))
LoopUnregisterAdapter(NULL);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return Status;
}
NDIS_STATUS LoopUnregisterAdapter(
PLAN_ADAPTER Adapter)
/*
* FUNCTION: Unregisters loopback adapter
* ARGUMENTS:
* Adapter = Unused
* RETURNS:
* Status of operation
* NOTES:
* Does not care wether we have registered loopback adapter
*/
{
TI_DbgPrint(MID_TRACE, ("Called.\n"));
if (Loopback) {
IPUnregisterInterface(Loopback);
IPDestroyInterface(Loopback);
Loopback = NULL;
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return NDIS_STATUS_SUCCESS;
}
/* EOF */
+63 -63
View File
@@ -1,63 +1,63 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/address.h
* PURPOSE: Address manipulation prototypes
*/
#ifndef __ADDRESS_H
#define __ADDRESS_H
/*
* Initialize an IPv4 style address
* VOID AddrInitIPv4(
* PIP_ADDRESS IPAddress,
* IPv4_RAW_ADDRESS RawAddress)
*/
#define AddrInitIPv4(IPAddress, RawAddress) \
{ \
(IPAddress)->RefCount = 1; \
(IPAddress)->Type = IP_ADDRESS_V4; \
(IPAddress)->Address.IPv4Address = (RawAddress); \
}
BOOLEAN AddrIsUnspecified(
PIP_ADDRESS Address);
NTSTATUS AddrGetAddress(
PTRANSPORT_ADDRESS AddrList,
PIP_ADDRESS *Address,
PUSHORT Port,
PIP_ADDRESS *Cache);
BOOLEAN AddrIsEqual(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2);
INT AddrCompare(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2);
BOOLEAN AddrIsEqualIPv4(
PIP_ADDRESS Address1,
IPv4_RAW_ADDRESS Address2);
PIP_ADDRESS AddrBuildIPv4(
IPv4_RAW_ADDRESS Address);
PADDRESS_ENTRY AddrLocateADEv4(
IPv4_RAW_ADDRESS Address);
PADDRESS_FILE AddrSearchFirst(
PIP_ADDRESS Address,
USHORT Port,
USHORT Protocol,
PAF_SEARCH SearchContext);
PADDRESS_FILE AddrSearchNext(
PAF_SEARCH SearchContext);
#endif /* __ADDRESS_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/address.h
* PURPOSE: Address manipulation prototypes
*/
#ifndef __ADDRESS_H
#define __ADDRESS_H
/*
* Initialize an IPv4 style address
* VOID AddrInitIPv4(
* PIP_ADDRESS IPAddress,
* IPv4_RAW_ADDRESS RawAddress)
*/
#define AddrInitIPv4(IPAddress, RawAddress) \
{ \
(IPAddress)->RefCount = 1; \
(IPAddress)->Type = IP_ADDRESS_V4; \
(IPAddress)->Address.IPv4Address = (RawAddress); \
}
BOOLEAN AddrIsUnspecified(
PIP_ADDRESS Address);
NTSTATUS AddrGetAddress(
PTRANSPORT_ADDRESS AddrList,
PIP_ADDRESS *Address,
PUSHORT Port,
PIP_ADDRESS *Cache);
BOOLEAN AddrIsEqual(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2);
INT AddrCompare(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2);
BOOLEAN AddrIsEqualIPv4(
PIP_ADDRESS Address1,
IPv4_RAW_ADDRESS Address2);
PIP_ADDRESS AddrBuildIPv4(
IPv4_RAW_ADDRESS Address);
PADDRESS_ENTRY AddrLocateADEv4(
IPv4_RAW_ADDRESS Address);
PADDRESS_FILE AddrSearchFirst(
PIP_ADDRESS Address,
USHORT Port,
USHORT Protocol,
PAF_SEARCH SearchContext);
PADDRESS_FILE AddrSearchNext(
PAF_SEARCH SearchContext);
#endif /* __ADDRESS_H */
/* EOF */
+37 -37
View File
@@ -1,37 +1,37 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/arp.h
* PURPOSE: Address Resolution Protocol definitions
*/
#ifndef __ARP_H
#define __ARP_H
typedef struct ARP_HEADER {
USHORT HWType; /* Hardware Type */
USHORT ProtoType; /* Protocol Type */
UCHAR HWAddrLen; /* Hardware Address Length */
UCHAR ProtoAddrLen; /* Protocol Address Length */
USHORT Opcode; /* Opcode */
/* Sender's Hardware Address */
/* Sender's Protocol Address */
/* Target's Hardware Address */
/* Target's Protocol Address */
} ARP_HEADER, *PARP_HEADER;
/* We swap constants so we can compare values at runtime without swapping them */
#define ARP_OPCODE_REQUEST WH2N(0x0001) /* ARP request */
#define ARP_OPCODE_REPLY WH2N(0x0002) /* ARP reply */
BOOLEAN ARPTransmit(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE);
VOID ARPReceive(
PVOID Context,
PIP_PACKET Packet);
#endif /* __ARP_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/arp.h
* PURPOSE: Address Resolution Protocol definitions
*/
#ifndef __ARP_H
#define __ARP_H
typedef struct ARP_HEADER {
USHORT HWType; /* Hardware Type */
USHORT ProtoType; /* Protocol Type */
UCHAR HWAddrLen; /* Hardware Address Length */
UCHAR ProtoAddrLen; /* Protocol Address Length */
USHORT Opcode; /* Opcode */
/* Sender's Hardware Address */
/* Sender's Protocol Address */
/* Target's Hardware Address */
/* Target's Protocol Address */
} ARP_HEADER, *PARP_HEADER;
/* We swap constants so we can compare values at runtime without swapping them */
#define ARP_OPCODE_REQUEST WH2N(0x0001) /* ARP request */
#define ARP_OPCODE_REPLY WH2N(0x0002) /* ARP reply */
BOOLEAN ARPTransmit(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE);
VOID ARPReceive(
PVOID Context,
PIP_PACKET Packet);
#endif /* __ARP_H */
/* EOF */
+27 -27
View File
@@ -1,27 +1,27 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/checksum.h
* PURPOSE: Checksum routine definitions
*/
#ifndef __CHECKSUM_H
#define __CHECKSUM_H
ULONG ChecksumCompute(
PVOID Data,
UINT Count,
ULONG Seed);
#define IPv4Checksum(Data, Count, Seed)(ChecksumCompute(Data, Count, Seed))
/*
* Macro to check for a correct checksum
* BOOLEAN CorrectChecksum(PVOID Data, UINT Count)
*/
#define CorrectChecksum(Data, Count) \
(BOOLEAN)(IPv4Checksum(Data, Count, 0) == DH2N(0x0000FFFF))
#endif /* __CHECKSUM_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/checksum.h
* PURPOSE: Checksum routine definitions
*/
#ifndef __CHECKSUM_H
#define __CHECKSUM_H
ULONG ChecksumCompute(
PVOID Data,
UINT Count,
ULONG Seed);
#define IPv4Checksum(Data, Count, Seed)(ChecksumCompute(Data, Count, Seed))
/*
* Macro to check for a correct checksum
* BOOLEAN CorrectChecksum(PVOID Data, UINT Count)
*/
#define CorrectChecksum(Data, Count) \
(BOOLEAN)(IPv4Checksum(Data, Count, 0) == DH2N(0x0000FFFF))
#endif /* __CHECKSUM_H */
/* EOF */
+49 -49
View File
@@ -1,49 +1,49 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/datagram.h
* PURPOSE: Datagram types and constants
*/
#ifndef __DATAGRAM_H
#define __DATAGRAM_H
#include <titypes.h>
VOID DGSend(
PVOID Context,
PDATAGRAM_SEND_REQUEST SendRequest);
VOID DGCancelSendRequest(
PADDRESS_FILE AddrFile,
PVOID Context);
VOID DGCancelReceiveRequest(
PADDRESS_FILE AddrFile,
PVOID Context);
NTSTATUS DGSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize,
DATAGRAM_BUILD_ROUTINE Build);
NTSTATUS DGReceiveDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived);
NTSTATUS DGStartup(
VOID);
NTSTATUS DGShutdown(
VOID);
#endif /* __DATAGRAM_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/datagram.h
* PURPOSE: Datagram types and constants
*/
#ifndef __DATAGRAM_H
#define __DATAGRAM_H
#include <titypes.h>
VOID DGSend(
PVOID Context,
PDATAGRAM_SEND_REQUEST SendRequest);
VOID DGCancelSendRequest(
PADDRESS_FILE AddrFile,
PVOID Context);
VOID DGCancelReceiveRequest(
PADDRESS_FILE AddrFile,
PVOID Context);
NTSTATUS DGSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize,
DATAGRAM_BUILD_ROUTINE Build);
NTSTATUS DGReceiveDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived);
NTSTATUS DGStartup(
VOID);
NTSTATUS DGShutdown(
VOID);
#endif /* __DATAGRAM_H */
/* EOF */
+99 -99
View File
@@ -1,99 +1,99 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/debug.h
* PURPOSE: Debugging support macros
* DEFINES: DBG - Enable debug output
* NASSERT - Disable assertions
*/
#ifndef __DEBUG_H
#define __DEBUG_H
#define NORMAL_MASK 0x000000FF
#define SPECIAL_MASK 0xFFFFFF00
#define MIN_TRACE 0x00000001
#define MID_TRACE 0x00000002
#define MAX_TRACE 0x00000003
#define DEBUG_MEMORY 0x00000100
#define DEBUG_BUFFER 0x00000200
#define DEBUG_IRP 0x00000400
#define DEBUG_REFCOUNT 0x00000800
#define DEBUG_ADDRFILE 0x00001000
#define DEBUG_IP 0x00002000
#define DEBUG_ROUTER 0x00004000
#define DEBUG_RCACHE 0x00008000
#define DEBUG_NCACHE 0x00010000
#define DEBUG_ULTRA 0xFFFFFFFF
#ifdef DBG
extern DWORD DebugTraceLevel;
#ifdef _MSC_VER
#define TI_DbgPrint(_t_, _x_) \
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
DbgPrint("(%s:%d) ", __FILE__, __LINE__); \
DbgPrint _x_ ; \
}
#else /* _MSC_VER */
#define TI_DbgPrint(_t_, _x_) \
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
DbgPrint("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
DbgPrint _x_ ; \
}
#endif /* _MSC_VER */
#ifdef ASSERT
#undef ASSERT
#endif
#ifdef NASSERT
#define ASSERT(x)
#else /* NASSERT */
#define ASSERT(x) if (!(x)) { TI_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
#endif /* NASSERT */
#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
#else /* DBG */
#define TI_DbgPrint(_t_, _x_)
#define ASSERT_IRQL(x)
#define ASSERT(x)
#endif /* DBG */
#define assert(x) ASSERT(x)
#define assert_irql(x) ASSERT_IRQL(x)
#ifdef _MSC_VER
#define UNIMPLEMENTED \
TI_DbgPrint(MIN_TRACE, ("The function at %s:%d is unimplemented, \
but come back another day.\n", __FILE__, __LINE__));
#else /* _MSC_VER */
#define UNIMPLEMENTED \
TI_DbgPrint(MIN_TRACE, ("(%s:%d)(%s) is unimplemented, \
but come back another day.\n", __FILE__, __LINE__, __FUNCTION__));
#endif /* _MSC_VER */
#define CHECKPOINT \
do { TI_DbgPrint(MIN_TRACE, ("(%s:%d)\n", __FILE__, __LINE__)); } while(0);
#endif /* __DEBUG_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/debug.h
* PURPOSE: Debugging support macros
* DEFINES: DBG - Enable debug output
* NASSERT - Disable assertions
*/
#ifndef __DEBUG_H
#define __DEBUG_H
#define NORMAL_MASK 0x000000FF
#define SPECIAL_MASK 0xFFFFFF00
#define MIN_TRACE 0x00000001
#define MID_TRACE 0x00000002
#define MAX_TRACE 0x00000003
#define DEBUG_MEMORY 0x00000100
#define DEBUG_BUFFER 0x00000200
#define DEBUG_IRP 0x00000400
#define DEBUG_REFCOUNT 0x00000800
#define DEBUG_ADDRFILE 0x00001000
#define DEBUG_IP 0x00002000
#define DEBUG_ROUTER 0x00004000
#define DEBUG_RCACHE 0x00008000
#define DEBUG_NCACHE 0x00010000
#define DEBUG_ULTRA 0xFFFFFFFF
#ifdef DBG
extern DWORD DebugTraceLevel;
#ifdef _MSC_VER
#define TI_DbgPrint(_t_, _x_) \
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
DbgPrint("(%s:%d) ", __FILE__, __LINE__); \
DbgPrint _x_ ; \
}
#else /* _MSC_VER */
#define TI_DbgPrint(_t_, _x_) \
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
DbgPrint("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
DbgPrint _x_ ; \
}
#endif /* _MSC_VER */
#ifdef ASSERT
#undef ASSERT
#endif
#ifdef NASSERT
#define ASSERT(x)
#else /* NASSERT */
#define ASSERT(x) if (!(x)) { TI_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
#endif /* NASSERT */
#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
#else /* DBG */
#define TI_DbgPrint(_t_, _x_)
#define ASSERT_IRQL(x)
#define ASSERT(x)
#endif /* DBG */
#define assert(x) ASSERT(x)
#define assert_irql(x) ASSERT_IRQL(x)
#ifdef _MSC_VER
#define UNIMPLEMENTED \
TI_DbgPrint(MIN_TRACE, ("The function at %s:%d is unimplemented, \
but come back another day.\n", __FILE__, __LINE__));
#else /* _MSC_VER */
#define UNIMPLEMENTED \
TI_DbgPrint(MIN_TRACE, ("(%s:%d)(%s) is unimplemented, \
but come back another day.\n", __FILE__, __LINE__, __FUNCTION__));
#endif /* _MSC_VER */
#define CHECKPOINT \
do { TI_DbgPrint(MIN_TRACE, ("(%s:%d)\n", __FILE__, __LINE__)); } while(0);
#endif /* __DEBUG_H */
/* EOF */
+61 -61
View File
@@ -1,61 +1,61 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/dispatch.h
* PURPOSE: Dispatch routine prototypes
*/
#ifndef __DISPATCH_H
#define __DISPATCH_H
NTSTATUS DispTdiAccept(
PIRP Irp);
NTSTATUS DispTdiAssociateAddress(
PIRP Irp);
NTSTATUS DispTdiConnect(
PIRP Irp);
NTSTATUS DispTdiDisassociateAddress(
PIRP Irp);
NTSTATUS DispTdiDisconnect(
PIRP Irp);
NTSTATUS DispTdiListen(
PIRP Irp);
NTSTATUS DispTdiQueryInformation(
PDEVICE_OBJECT DeviceObject,
PIRP Irp);
NTSTATUS DispTdiReceive(
PIRP Irp);
NTSTATUS DispTdiReceiveDatagram(
PIRP Irp);
NTSTATUS DispTdiSend(
PIRP Irp);
NTSTATUS DispTdiSendDatagram(
PIRP Irp);
NTSTATUS DispTdiSetEventHandler(
PIRP Irp);
NTSTATUS DispTdiSetInformation(
PIRP Irp);
NTSTATUS DispTdiQueryInformationEx(
PIRP Irp,
PIO_STACK_LOCATION IrpSp);
NTSTATUS DispTdiSetInformationEx(
PIRP Irp,
PIO_STACK_LOCATION IrpSp);
#endif /* __DISPATCH_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/dispatch.h
* PURPOSE: Dispatch routine prototypes
*/
#ifndef __DISPATCH_H
#define __DISPATCH_H
NTSTATUS DispTdiAccept(
PIRP Irp);
NTSTATUS DispTdiAssociateAddress(
PIRP Irp);
NTSTATUS DispTdiConnect(
PIRP Irp);
NTSTATUS DispTdiDisassociateAddress(
PIRP Irp);
NTSTATUS DispTdiDisconnect(
PIRP Irp);
NTSTATUS DispTdiListen(
PIRP Irp);
NTSTATUS DispTdiQueryInformation(
PDEVICE_OBJECT DeviceObject,
PIRP Irp);
NTSTATUS DispTdiReceive(
PIRP Irp);
NTSTATUS DispTdiReceiveDatagram(
PIRP Irp);
NTSTATUS DispTdiSend(
PIRP Irp);
NTSTATUS DispTdiSendDatagram(
PIRP Irp);
NTSTATUS DispTdiSetEventHandler(
PIRP Irp);
NTSTATUS DispTdiSetInformation(
PIRP Irp);
NTSTATUS DispTdiQueryInformationEx(
PIRP Irp,
PIO_STACK_LOCATION IrpSp);
NTSTATUS DispTdiSetInformationEx(
PIRP Irp,
PIO_STACK_LOCATION IrpSp);
#endif /* __DISPATCH_H */
/* EOF */
+32 -32
View File
@@ -1,32 +1,32 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/fileobjs.h
* PURPOSE: File object routine prototypes
*/
#ifndef __FILEOBJS_H
#define __FILEOBJS_H
extern LIST_ENTRY AddressFileListHead;
extern KSPIN_LOCK AddressFileListLock;
NTSTATUS FileOpenAddress(
PTDI_REQUEST Request,
PTA_ADDRESS_IP AddrList,
USHORT Protocol,
PVOID Options);
NTSTATUS FileCloseAddress(
PTDI_REQUEST Request);
NTSTATUS FileCloseConnection(
PTDI_REQUEST Request);
NTSTATUS FileCloseControlChannel(
PTDI_REQUEST Request);
#endif /* __FILEOBJS_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/fileobjs.h
* PURPOSE: File object routine prototypes
*/
#ifndef __FILEOBJS_H
#define __FILEOBJS_H
extern LIST_ENTRY AddressFileListHead;
extern KSPIN_LOCK AddressFileListLock;
NTSTATUS FileOpenAddress(
PTDI_REQUEST Request,
PTA_ADDRESS_IP AddrList,
USHORT Protocol,
PVOID Options);
NTSTATUS FileCloseAddress(
PTDI_REQUEST Request);
NTSTATUS FileCloseConnection(
PTDI_REQUEST Request);
NTSTATUS FileCloseControlChannel(
PTDI_REQUEST Request);
#endif /* __FILEOBJS_H */
/* EOF */
+68 -68
View File
@@ -1,68 +1,68 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/icmp.h
* PURPOSE: Internet Control Message Protocol definitions
*/
#ifndef __ICMP_H
#define __ICMP_H
typedef struct ICMP_HEADER {
UCHAR Type; /* ICMP message type */
UCHAR Code; /* ICMP message code */
USHORT Checksum; /* ICMP message checksum */
ULONG Unused; /* ICMP unused */
} ICMP_HEADER, *PICMP_HEADER;
/* ICMP message types */
#define ICMP_TYPE_ECHO_REPLY 0 /* Echo reply */
#define ICMP_TYPE_DEST_UNREACH 3 /* Destination unreachable */
#define ICMP_TYPE_SOURCE_QUENCH 4 /* Source quench */
#define ICMP_TYPE_REDIRECT 5 /* Redirect */
#define ICMP_TYPE_ECHO_REQUEST 8 /* Echo request */
#define ICMP_TYPE_TIME_EXCEEDED 11 /* Time exceeded */
#define ICMP_TYPE_PARAMETER 12 /* Parameter problem */
#define ICMP_TYPE_TIMESTAMP_REQUEST 13 /* Timestamp request */
#define ICMP_TYPE_TIMESTAMP_REPLY 14 /* Timestamp reply */
#define ICMP_TYPE_INFO_REQUEST 15 /* Information request */
#define ICMP_TYPE_INFO_REPLY 16 /* Information reply */
/* ICMP codes for ICMP_TYPE_DEST_UNREACH */
#define ICMP_CODE_DU_NET_UNREACH 0 /* Network unreachable */
#define ICMP_CODE_DU_HOST_UNREACH 1 /* Host unreachable */
#define ICMP_CODE_DU_PROTOCOL_UNREACH 2 /* Protocol unreachable */
#define ICMP_CODE_DU_PORT_UNREACH 3 /* Port unreachable */
#define ICMP_CODE_DU_FRAG_DF_SET 4 /* Fragmentation needed and DF set */
#define ICMP_CODE_DU_SOURCE_ROUTE_FAILED 5 /* Source route failed */
/* ICMP codes for ICMP_TYPE_REDIRECT */
#define ICMP_CODE_RD_NET 0 /* Redirect datagrams for the network */
#define ICMP_CODE_RD_HOST 1 /* Redirect datagrams for the host */
#define ICMP_CODE_RD_TOS_NET 2 /* Redirect datagrams for the Type of Service and network */
#define ICMP_CODE_RD_TOS_HOST 3 /* Redirect datagrams for the Type of Service and host */
/* ICMP codes for ICMP_TYPE_TIME_EXCEEDED */
#define ICMP_CODE_TE_TTL 0 /* Time to live exceeded in transit */
#define ICMP_CODE_TE_REASSEMBLY 1 /* Fragment reassembly time exceeded */
/* ICMP codes for ICMP_TYPE_PARAMETER */
#define ICMP_CODE_TP_POINTER 1 /* Pointer indicates the error */
VOID ICMPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
VOID ICMPTransmit(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
VOID ICMPReply(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket,
UCHAR Type,
UCHAR Code);
#endif /* __ICMP_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/icmp.h
* PURPOSE: Internet Control Message Protocol definitions
*/
#ifndef __ICMP_H
#define __ICMP_H
typedef struct ICMP_HEADER {
UCHAR Type; /* ICMP message type */
UCHAR Code; /* ICMP message code */
USHORT Checksum; /* ICMP message checksum */
ULONG Unused; /* ICMP unused */
} ICMP_HEADER, *PICMP_HEADER;
/* ICMP message types */
#define ICMP_TYPE_ECHO_REPLY 0 /* Echo reply */
#define ICMP_TYPE_DEST_UNREACH 3 /* Destination unreachable */
#define ICMP_TYPE_SOURCE_QUENCH 4 /* Source quench */
#define ICMP_TYPE_REDIRECT 5 /* Redirect */
#define ICMP_TYPE_ECHO_REQUEST 8 /* Echo request */
#define ICMP_TYPE_TIME_EXCEEDED 11 /* Time exceeded */
#define ICMP_TYPE_PARAMETER 12 /* Parameter problem */
#define ICMP_TYPE_TIMESTAMP_REQUEST 13 /* Timestamp request */
#define ICMP_TYPE_TIMESTAMP_REPLY 14 /* Timestamp reply */
#define ICMP_TYPE_INFO_REQUEST 15 /* Information request */
#define ICMP_TYPE_INFO_REPLY 16 /* Information reply */
/* ICMP codes for ICMP_TYPE_DEST_UNREACH */
#define ICMP_CODE_DU_NET_UNREACH 0 /* Network unreachable */
#define ICMP_CODE_DU_HOST_UNREACH 1 /* Host unreachable */
#define ICMP_CODE_DU_PROTOCOL_UNREACH 2 /* Protocol unreachable */
#define ICMP_CODE_DU_PORT_UNREACH 3 /* Port unreachable */
#define ICMP_CODE_DU_FRAG_DF_SET 4 /* Fragmentation needed and DF set */
#define ICMP_CODE_DU_SOURCE_ROUTE_FAILED 5 /* Source route failed */
/* ICMP codes for ICMP_TYPE_REDIRECT */
#define ICMP_CODE_RD_NET 0 /* Redirect datagrams for the network */
#define ICMP_CODE_RD_HOST 1 /* Redirect datagrams for the host */
#define ICMP_CODE_RD_TOS_NET 2 /* Redirect datagrams for the Type of Service and network */
#define ICMP_CODE_RD_TOS_HOST 3 /* Redirect datagrams for the Type of Service and host */
/* ICMP codes for ICMP_TYPE_TIME_EXCEEDED */
#define ICMP_CODE_TE_TTL 0 /* Time to live exceeded in transit */
#define ICMP_CODE_TE_REASSEMBLY 1 /* Fragment reassembly time exceeded */
/* ICMP codes for ICMP_TYPE_PARAMETER */
#define ICMP_CODE_TP_POINTER 1 /* Pointer indicates the error */
VOID ICMPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
VOID ICMPTransmit(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
VOID ICMPReply(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket,
UCHAR Type,
UCHAR Code);
#endif /* __ICMP_H */
/* EOF */
+93 -93
View File
@@ -1,93 +1,93 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/info.h
* PURPOSE: TdiQueryInformation definitions
*/
#ifndef __INFO_H
#define __INFO_H
typedef struct IPSNMP_INFO {
ULONG Forwarding;
ULONG DefaultTTL;
ULONG InReceives;
ULONG InHdrErrors;
ULONG InAddrErrors;
ULONG ForwDatagrams;
ULONG InUnknownProtos;
ULONG InDiscards;
ULONG InDelivers;
ULONG OutRequests;
ULONG RoutingDiscards;
ULONG OutDiscards;
ULONG OutNoRoutes;
ULONG ReasmTimeout;
ULONG ReasmReqds;
ULONG ReasmOks;
ULONG ReasmFails;
ULONG FragOks;
ULONG FragFails;
ULONG FragCreates;
ULONG NumIf;
ULONG NumAddr;
ULONG NumRoutes;
} IPSNMP_INFO, *PIPSNMP_INFO;
typedef struct IPADDR_ENTRY {
ULONG Addr;
ULONG Index;
ULONG Mask;
ULONG BcastAddr;
ULONG ReasmSize;
USHORT Context;
USHORT Pad;
} IPADDR_ENTRY, *PIPADDR_ENTRY;
#define IP_MIB_STATS_ID 1
#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
#define MAX_PHYSADDR_SIZE 8
/* Only UDP is supported */
#define TDI_SERVICE_FLAGS (TDI_SERVICE_CONNECTIONLESS_MODE | \
TDI_SERVICE_BROADCAST_SUPPORTED)
#define TCP_MIB_STAT_ID 1
#define UDP_MIB_STAT_ID 1
#define TCP_MIB_TABLE_ID 0x101
#define UDP_MIB_TABLE_ID 0x101
#define TL_INSTANCE 0
typedef struct ADDRESS_INFO {
ULONG LocalAddress;
ULONG LocalPort;
} ADDRESS_INFO, *PADDRESS_INFO;
typedef union TDI_INFO {
TDI_CONNECTION_INFO ConnInfo;
TDI_ADDRESS_INFO AddrInfo;
TDI_PROVIDER_INFO ProviderInfo;
TDI_PROVIDER_STATISTICS ProviderStats;
} TDI_INFO, *PTDI_INFO;
TDI_STATUS InfoTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context);
TDI_STATUS InfoTdiSetInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PVOID Buffer,
UINT BufferSize);
#endif /* __INFO_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/info.h
* PURPOSE: TdiQueryInformation definitions
*/
#ifndef __INFO_H
#define __INFO_H
typedef struct IPSNMP_INFO {
ULONG Forwarding;
ULONG DefaultTTL;
ULONG InReceives;
ULONG InHdrErrors;
ULONG InAddrErrors;
ULONG ForwDatagrams;
ULONG InUnknownProtos;
ULONG InDiscards;
ULONG InDelivers;
ULONG OutRequests;
ULONG RoutingDiscards;
ULONG OutDiscards;
ULONG OutNoRoutes;
ULONG ReasmTimeout;
ULONG ReasmReqds;
ULONG ReasmOks;
ULONG ReasmFails;
ULONG FragOks;
ULONG FragFails;
ULONG FragCreates;
ULONG NumIf;
ULONG NumAddr;
ULONG NumRoutes;
} IPSNMP_INFO, *PIPSNMP_INFO;
typedef struct IPADDR_ENTRY {
ULONG Addr;
ULONG Index;
ULONG Mask;
ULONG BcastAddr;
ULONG ReasmSize;
USHORT Context;
USHORT Pad;
} IPADDR_ENTRY, *PIPADDR_ENTRY;
#define IP_MIB_STATS_ID 1
#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
#define MAX_PHYSADDR_SIZE 8
/* Only UDP is supported */
#define TDI_SERVICE_FLAGS (TDI_SERVICE_CONNECTIONLESS_MODE | \
TDI_SERVICE_BROADCAST_SUPPORTED)
#define TCP_MIB_STAT_ID 1
#define UDP_MIB_STAT_ID 1
#define TCP_MIB_TABLE_ID 0x101
#define UDP_MIB_TABLE_ID 0x101
#define TL_INSTANCE 0
typedef struct ADDRESS_INFO {
ULONG LocalAddress;
ULONG LocalPort;
} ADDRESS_INFO, *PADDRESS_INFO;
typedef union TDI_INFO {
TDI_CONNECTION_INFO ConnInfo;
TDI_ADDRESS_INFO AddrInfo;
TDI_PROVIDER_INFO ProviderInfo;
TDI_PROVIDER_STATISTICS ProviderStats;
} TDI_INFO, *PTDI_INFO;
TDI_STATUS InfoTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context);
TDI_STATUS InfoTdiSetInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PVOID Buffer,
UINT BufferSize);
#endif /* __INFO_H */
/* EOF */
+245 -245
View File
@@ -1,245 +1,245 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/ip.h
* PURPOSE: Internet Protocol related definitions
*/
#ifndef __IP_H
#define __IP_H
/* Raw IPv4 style address */
typedef ULONG IPv4_RAW_ADDRESS;
typedef IPv4_RAW_ADDRESS *PIPv4_RAW_ADDRESS;
/* Raw IPv6 style address */
typedef USHORT IPv6_RAW_ADDRESS[8];
typedef IPv6_RAW_ADDRESS *PIPv6_RAW_ADDRESS;
/* IP style address */
typedef struct IP_ADDRESS {
ULONG RefCount; /* Number of references to this address */
UCHAR Type; /* Type of IP address */
union {
IPv4_RAW_ADDRESS IPv4Address; /* IPv4 address */
PIPv6_RAW_ADDRESS IPv6Address; /* IPv6 address */
} Address;
} IP_ADDRESS, *PIP_ADDRESS;
/* IP type constants */
#define IP_ADDRESS_V4 0x00 /* IPv4 style address */
#define IP_ADDRESS_V6 0x01 /* IPv6 style address */
/* IPv4 header format */
typedef struct IPv4_HEADER {
UCHAR VerIHL; /* 4-bit version, 4-bit Internet Header Length */
UCHAR Tos; /* Type of Service */
USHORT TotalLength; /* Total Length */
USHORT Id; /* Identification */
USHORT FlagsFragOfs; /* 3-bit Flags, 13-bit Fragment Offset */
UCHAR Ttl; /* Time to Live */
UCHAR Protocol; /* Protocol */
USHORT Checksum; /* Header Checksum */
IPv4_RAW_ADDRESS SrcAddr; /* Source Address */
IPv4_RAW_ADDRESS DstAddr; /* Destination Address */
} IPv4_HEADER, *PIPv4_HEADER;
#define IPv4_FRAGOFS_MASK 0x1FFF
#define IPv4_MF_MASK 0x2000
#define IPv4_MAX_HEADER_SIZE 60
/* Packet completion handler prototype */
typedef VOID (*PACKET_COMPLETION_ROUTINE)(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus);
/* Structure for an IP packet */
typedef struct IP_PACKET {
ULONG RefCount; /* Reference count for this object */
UCHAR Type; /* Type of IP packet (see IP_ADDRESS_xx above) */
PVOID Header; /* Pointer to IP header for this packet */
UINT HeaderSize; /* Size of IP header */
PVOID Data; /* Current pointer into packet data */
UINT TotalSize; /* Total amount of data in packet (IP header and data) */
UINT ContigSize; /* Number of contiguous bytes left in current buffer */
UINT Position; /* Current logical offset into packet */
PNDIS_PACKET NdisPacket; /* Pointer to NDIS packet */
IP_ADDRESS SrcAddr; /* Source address */
IP_ADDRESS DstAddr; /* Destination address */
} IP_PACKET, *PIP_PACKET;
/* Packet context */
typedef struct PACKET_CONTEXT {
PACKET_COMPLETION_ROUTINE Complete; /* Transport level completion handler */
PVOID Context; /* Context information for handler */
PACKET_COMPLETION_ROUTINE DLComplete; /* Data link level completion handler. Also
used to link to next packet in a queue */
UINT DLOffset; /* Offset where data (IP header) starts */
} PACKET_CONTEXT, *PPACKET_CONTEXT;
/* The ProtocolReserved field is structured as a PACKET_CONTEXT */
#define PC(Packet) ((PPACKET_CONTEXT)(&Packet->ProtocolReserved))
/* Address information a.k.a ADE */
typedef struct _ADDRESS_ENTRY {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
struct _NET_TABLE_ENTRY *NTE; /* NTE associated with this address */
UCHAR Type; /* Address type */
PIP_ADDRESS Address; /* Pointer to address identifying this entry */
} ADDRESS_ENTRY, *PADDRESS_ENTRY;
/* Values for address type */
#define ADE_UNICAST 0x01
#define ADE_MULTICAST 0x02
#define ADE_ADDRMASK 0x03
/* There is one NTE for each source (unicast) address assigned to an interface */
typedef struct _NET_TABLE_ENTRY {
LIST_ENTRY IFListEntry; /* Entry on interface list */
LIST_ENTRY NTListEntry; /* Entry on net table list */
struct _IP_INTERFACE *Interface; /* Pointer to interface on this net */
struct _PREFIX_LIST_ENTRY *PLE; /* Pointer to prefix list entry for this net */
ULONG RefCount; /* Reference count */
PIP_ADDRESS Address; /* Pointer to unicast address for this net */
} NET_TABLE_ENTRY, *PNET_TABLE_ENTRY;
/* Link layer transmit prototype */
typedef VOID (*LL_TRANSMIT_ROUTINE)(
PVOID Context,
PNDIS_PACKET NdisPacket,
UINT Offset,
PVOID LinkAddress,
USHORT Type);
/* Link layer to IP binding information */
typedef struct _LLIP_BIND_INFO {
PVOID Context; /* Pointer to link layer context information */
UINT HeaderSize; /* Size of link level header */
UINT MinFrameSize; /* Minimum frame size in bytes */
UINT MTU; /* Maximum transmission unit */
PUCHAR Address; /* Pointer to interface address */
UINT AddressLength; /* Length of address in bytes */
LL_TRANSMIT_ROUTINE Transmit; /* Transmit function for this interface */
} LLIP_BIND_INFO, *PLLIP_BIND_INFO;
/* Information about an IP interface */
typedef struct _IP_INTERFACE {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
KSPIN_LOCK Lock; /* Spin lock for this object */
LIST_ENTRY NTEListHead; /* List of NTEs on this interface */
LIST_ENTRY ADEListHead; /* List of ADEs on this interface */
PVOID Context; /* Pointer to link layer context information */
UINT HeaderSize; /* Size of link level header */
UINT MinFrameSize; /* Minimum frame size in bytes */
UINT MTU; /* Maximum transmission unit */
PUCHAR Address; /* Pointer to interface address */
UINT AddressLength; /* Length of address in bytes */
LL_TRANSMIT_ROUTINE Transmit; /* Pointer to transmit function */
} IP_INTERFACE, *PIP_INTERFACE;
/* Prefix List Entry */
typedef struct _PREFIX_LIST_ENTRY {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
PIP_INTERFACE Interface; /* Pointer to interface */
PIP_ADDRESS Prefix; /* Pointer to prefix */
UINT PrefixLength; /* Length of prefix */
} PREFIX_LIST_ENTRY, *PPREFIX_LIST_ENTRY;
#define IP_PROTOCOL_TABLE_SIZE 0x100
typedef VOID (*IP_PROTOCOL_HANDLER)(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
/* Loopback adapter address information (network byte order) */
#define LOOPBACK_ADDRESS_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0x7F000001))
#define LOOPBACK_BCASTADDR_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0x7F0000FF))
#define LOOPBACK_ADDRMASK_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0xFFFFFF00))
/* Protocol definitions */
#define IPPROTO_ICMP 1 /* Internet Control Message Protocol */
#define IPPROTO_IGMP 2 /* Internet Group Management Protocol */
#define IPPROTO_TCP 6 /* Transmission Control Protocol */
#define IPPROTO_UDP 17 /* User Datagram Protocol */
/* Timeout timer constants */
#define IP_TICKS_SECOND 2 /* Two ticks per second */
#define IP_TIMEOUT (1000 / IP_TICKS_SECOND) /* Timeout in milliseconds */
extern LIST_ENTRY InterfaceListHead;
extern KSPIN_LOCK InterfaceListLock;
extern LIST_ENTRY NetTableListHead;
extern KSPIN_LOCK NetTableListLock;
extern LIST_ENTRY PrefixListHead;
extern KSPIN_LOCK PrefixListLock;
extern UINT MaxLLHeaderSize;
extern UINT MinLLFrameSize;
PNET_TABLE_ENTRY IPCreateNTE(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
UINT PrefixLength);
PIP_INTERFACE IPCreateInterface(
PLLIP_BIND_INFO BindInfo);
VOID IPDestroyInterface(
PIP_INTERFACE IF);
BOOLEAN IPRegisterInterface(
PIP_INTERFACE IF);
VOID IPUnregisterInterface(
PIP_INTERFACE IF);
PNET_TABLE_ENTRY IPLocateNTEOnInterface(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
PUINT AddressType);
PNET_TABLE_ENTRY IPLocateNTE(
PIP_ADDRESS Address,
PUINT AddressType);
PADDRESS_ENTRY IPLocateADE(
PIP_ADDRESS Address,
UINT AddressType);
PADDRESS_ENTRY IPGetDefaultADE(
UINT AddressType);
VOID IPTimeout(
PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2);
VOID IPDispatchProtocol(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
VOID IPRegisterProtocol(
UINT ProtocolNumber,
IP_PROTOCOL_HANDLER Handler);
NTSTATUS IPStartup(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
NTSTATUS IPShutdown(
VOID);
#endif /* __IP_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/ip.h
* PURPOSE: Internet Protocol related definitions
*/
#ifndef __IP_H
#define __IP_H
/* Raw IPv4 style address */
typedef ULONG IPv4_RAW_ADDRESS;
typedef IPv4_RAW_ADDRESS *PIPv4_RAW_ADDRESS;
/* Raw IPv6 style address */
typedef USHORT IPv6_RAW_ADDRESS[8];
typedef IPv6_RAW_ADDRESS *PIPv6_RAW_ADDRESS;
/* IP style address */
typedef struct IP_ADDRESS {
ULONG RefCount; /* Number of references to this address */
UCHAR Type; /* Type of IP address */
union {
IPv4_RAW_ADDRESS IPv4Address; /* IPv4 address */
PIPv6_RAW_ADDRESS IPv6Address; /* IPv6 address */
} Address;
} IP_ADDRESS, *PIP_ADDRESS;
/* IP type constants */
#define IP_ADDRESS_V4 0x00 /* IPv4 style address */
#define IP_ADDRESS_V6 0x01 /* IPv6 style address */
/* IPv4 header format */
typedef struct IPv4_HEADER {
UCHAR VerIHL; /* 4-bit version, 4-bit Internet Header Length */
UCHAR Tos; /* Type of Service */
USHORT TotalLength; /* Total Length */
USHORT Id; /* Identification */
USHORT FlagsFragOfs; /* 3-bit Flags, 13-bit Fragment Offset */
UCHAR Ttl; /* Time to Live */
UCHAR Protocol; /* Protocol */
USHORT Checksum; /* Header Checksum */
IPv4_RAW_ADDRESS SrcAddr; /* Source Address */
IPv4_RAW_ADDRESS DstAddr; /* Destination Address */
} IPv4_HEADER, *PIPv4_HEADER;
#define IPv4_FRAGOFS_MASK 0x1FFF
#define IPv4_MF_MASK 0x2000
#define IPv4_MAX_HEADER_SIZE 60
/* Packet completion handler prototype */
typedef VOID (*PACKET_COMPLETION_ROUTINE)(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus);
/* Structure for an IP packet */
typedef struct IP_PACKET {
ULONG RefCount; /* Reference count for this object */
UCHAR Type; /* Type of IP packet (see IP_ADDRESS_xx above) */
PVOID Header; /* Pointer to IP header for this packet */
UINT HeaderSize; /* Size of IP header */
PVOID Data; /* Current pointer into packet data */
UINT TotalSize; /* Total amount of data in packet (IP header and data) */
UINT ContigSize; /* Number of contiguous bytes left in current buffer */
UINT Position; /* Current logical offset into packet */
PNDIS_PACKET NdisPacket; /* Pointer to NDIS packet */
IP_ADDRESS SrcAddr; /* Source address */
IP_ADDRESS DstAddr; /* Destination address */
} IP_PACKET, *PIP_PACKET;
/* Packet context */
typedef struct PACKET_CONTEXT {
PACKET_COMPLETION_ROUTINE Complete; /* Transport level completion handler */
PVOID Context; /* Context information for handler */
PACKET_COMPLETION_ROUTINE DLComplete; /* Data link level completion handler. Also
used to link to next packet in a queue */
UINT DLOffset; /* Offset where data (IP header) starts */
} PACKET_CONTEXT, *PPACKET_CONTEXT;
/* The ProtocolReserved field is structured as a PACKET_CONTEXT */
#define PC(Packet) ((PPACKET_CONTEXT)(&Packet->ProtocolReserved))
/* Address information a.k.a ADE */
typedef struct _ADDRESS_ENTRY {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
struct _NET_TABLE_ENTRY *NTE; /* NTE associated with this address */
UCHAR Type; /* Address type */
PIP_ADDRESS Address; /* Pointer to address identifying this entry */
} ADDRESS_ENTRY, *PADDRESS_ENTRY;
/* Values for address type */
#define ADE_UNICAST 0x01
#define ADE_MULTICAST 0x02
#define ADE_ADDRMASK 0x03
/* There is one NTE for each source (unicast) address assigned to an interface */
typedef struct _NET_TABLE_ENTRY {
LIST_ENTRY IFListEntry; /* Entry on interface list */
LIST_ENTRY NTListEntry; /* Entry on net table list */
struct _IP_INTERFACE *Interface; /* Pointer to interface on this net */
struct _PREFIX_LIST_ENTRY *PLE; /* Pointer to prefix list entry for this net */
ULONG RefCount; /* Reference count */
PIP_ADDRESS Address; /* Pointer to unicast address for this net */
} NET_TABLE_ENTRY, *PNET_TABLE_ENTRY;
/* Link layer transmit prototype */
typedef VOID (*LL_TRANSMIT_ROUTINE)(
PVOID Context,
PNDIS_PACKET NdisPacket,
UINT Offset,
PVOID LinkAddress,
USHORT Type);
/* Link layer to IP binding information */
typedef struct _LLIP_BIND_INFO {
PVOID Context; /* Pointer to link layer context information */
UINT HeaderSize; /* Size of link level header */
UINT MinFrameSize; /* Minimum frame size in bytes */
UINT MTU; /* Maximum transmission unit */
PUCHAR Address; /* Pointer to interface address */
UINT AddressLength; /* Length of address in bytes */
LL_TRANSMIT_ROUTINE Transmit; /* Transmit function for this interface */
} LLIP_BIND_INFO, *PLLIP_BIND_INFO;
/* Information about an IP interface */
typedef struct _IP_INTERFACE {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
KSPIN_LOCK Lock; /* Spin lock for this object */
LIST_ENTRY NTEListHead; /* List of NTEs on this interface */
LIST_ENTRY ADEListHead; /* List of ADEs on this interface */
PVOID Context; /* Pointer to link layer context information */
UINT HeaderSize; /* Size of link level header */
UINT MinFrameSize; /* Minimum frame size in bytes */
UINT MTU; /* Maximum transmission unit */
PUCHAR Address; /* Pointer to interface address */
UINT AddressLength; /* Length of address in bytes */
LL_TRANSMIT_ROUTINE Transmit; /* Pointer to transmit function */
} IP_INTERFACE, *PIP_INTERFACE;
/* Prefix List Entry */
typedef struct _PREFIX_LIST_ENTRY {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
PIP_INTERFACE Interface; /* Pointer to interface */
PIP_ADDRESS Prefix; /* Pointer to prefix */
UINT PrefixLength; /* Length of prefix */
} PREFIX_LIST_ENTRY, *PPREFIX_LIST_ENTRY;
#define IP_PROTOCOL_TABLE_SIZE 0x100
typedef VOID (*IP_PROTOCOL_HANDLER)(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
/* Loopback adapter address information (network byte order) */
#define LOOPBACK_ADDRESS_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0x7F000001))
#define LOOPBACK_BCASTADDR_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0x7F0000FF))
#define LOOPBACK_ADDRMASK_IPv4 ((IPv4_RAW_ADDRESS)DH2N(0xFFFFFF00))
/* Protocol definitions */
#define IPPROTO_ICMP 1 /* Internet Control Message Protocol */
#define IPPROTO_IGMP 2 /* Internet Group Management Protocol */
#define IPPROTO_TCP 6 /* Transmission Control Protocol */
#define IPPROTO_UDP 17 /* User Datagram Protocol */
/* Timeout timer constants */
#define IP_TICKS_SECOND 2 /* Two ticks per second */
#define IP_TIMEOUT (1000 / IP_TICKS_SECOND) /* Timeout in milliseconds */
extern LIST_ENTRY InterfaceListHead;
extern KSPIN_LOCK InterfaceListLock;
extern LIST_ENTRY NetTableListHead;
extern KSPIN_LOCK NetTableListLock;
extern LIST_ENTRY PrefixListHead;
extern KSPIN_LOCK PrefixListLock;
extern UINT MaxLLHeaderSize;
extern UINT MinLLFrameSize;
PNET_TABLE_ENTRY IPCreateNTE(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
UINT PrefixLength);
PIP_INTERFACE IPCreateInterface(
PLLIP_BIND_INFO BindInfo);
VOID IPDestroyInterface(
PIP_INTERFACE IF);
BOOLEAN IPRegisterInterface(
PIP_INTERFACE IF);
VOID IPUnregisterInterface(
PIP_INTERFACE IF);
PNET_TABLE_ENTRY IPLocateNTEOnInterface(
PIP_INTERFACE IF,
PIP_ADDRESS Address,
PUINT AddressType);
PNET_TABLE_ENTRY IPLocateNTE(
PIP_ADDRESS Address,
PUINT AddressType);
PADDRESS_ENTRY IPLocateADE(
PIP_ADDRESS Address,
UINT AddressType);
PADDRESS_ENTRY IPGetDefaultADE(
UINT AddressType);
VOID IPTimeout(
PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2);
VOID IPDispatchProtocol(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
VOID IPRegisterProtocol(
UINT ProtocolNumber,
IP_PROTOCOL_HANDLER Handler);
NTSTATUS IPStartup(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
NTSTATUS IPShutdown(
VOID);
#endif /* __IP_H */
/* EOF */
+100 -100
View File
@@ -1,100 +1,100 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/lan.h
* PURPOSE: LAN adapter definitions
*/
#ifndef __LAN_H
#define __LAN_H
/* Medias we support */
#define MEDIA_ETH 0
#define MAX_MEDIA 1
#define IEEE_802_ADDR_LENGTH 6
/* Ethernet header layout */
typedef struct ETH_HEADER {
UCHAR DstAddr[IEEE_802_ADDR_LENGTH]; /* Destination MAC address */
UCHAR SrcAddr[IEEE_802_ADDR_LENGTH]; /* Source MAC address */
USHORT EType; /* Ethernet protocol type */
} ETH_HEADER, *PETH_HEADER;
#define MAX_MEDIA_ETH sizeof(ETH_HEADER)
/* Broadcast masks */
#define BCAST_ETH_MASK 0x01
/* Broadcast values to check against */
#define BCAST_ETH_CHECK 0x01
/* Offset of broadcast address */
#define BCAST_ETH_OFFSET 0x00
/* Per adapter information */
typedef struct LAN_ADAPTER {
struct LAN_ADAPTER *Next; /* Pointer to next adapter */
KSPIN_LOCK Lock; /* Lock for this structure */
UCHAR State; /* State of the adapter */
KEVENT Event; /* Opening event */
PVOID Context; /* Upper layer context information */
NDIS_HANDLE NdisHandle; /* NDIS binding handle */
NDIS_STATUS NdisStatus; /* NDIS status of last request */
NDIS_MEDIUM Media; /* Media type */
UCHAR HWAddress[IEEE_802_ADDR_LENGTH]; /* Local HW address */
UINT HWAddressLength; /* Length of HW address */
UCHAR BCastMask; /* Mask for checking broadcast */
UCHAR BCastCheck; /* Value to check against */
UCHAR BCastOffset; /* Offset in frame to check against */
UCHAR HeaderSize; /* Size of link-level header */
USHORT MTU; /* Maximum Transfer Unit */
UINT MinFrameSize; /* Minimum frame size in bytes */
UINT MaxPacketSize; /* Maximum packet size when sending */
UINT MaxSendPackets; /* Maximum number of packets per send */
UINT MacOptions; /* MAC options for NIC driver/adapter */
UINT Speed; /* Link speed */
UINT PacketFilter; /* Packet filter for this adapter */
PNDIS_PACKET TDPackets; /* Transfer Data packets */
} LAN_ADAPTER, *PLAN_ADAPTER;
/* LAN adapter state constants */
#define LAN_STATE_OPENING 0
#define LAN_STATE_RESETTING 1
#define LAN_STATE_STARTED 2
#define LAN_STATE_STOPPED 3
/* Size of out lookahead buffer */
#define LOOKAHEAD_SIZE 128
/* Ethernet types. We swap constants so we can compare values at runtime
without swapping them */
#define ETYPE_IPv4 WH2N(0x0800)
#define ETYPE_IPv6 WH2N(0x0000) /* FIXME */
#define ETYPE_ARP WH2N(0x0806)
/* Protocols */
#define LAN_PROTO_IPv4 0x0000 /* Internet Protocol version 4 */
#define LAN_PROTO_IPv6 0x0001 /* Internet Protocol version 6 */
#define LAN_PROTO_ARP 0x0002 /* Address Resolution Protocol */
extern PLAN_ADAPTER Adapters;
NDIS_STATUS LANRegisterAdapter(
PNDIS_STRING AdapterName,
PLAN_ADAPTER *Adapter);
NDIS_STATUS LANUnregisterAdapter(
PLAN_ADAPTER Adapter);
NTSTATUS LANRegisterProtocol(
STRING *Name);
VOID LANUnregisterProtocol(
VOID);
#endif /* __LAN_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/lan.h
* PURPOSE: LAN adapter definitions
*/
#ifndef __LAN_H
#define __LAN_H
/* Medias we support */
#define MEDIA_ETH 0
#define MAX_MEDIA 1
#define IEEE_802_ADDR_LENGTH 6
/* Ethernet header layout */
typedef struct ETH_HEADER {
UCHAR DstAddr[IEEE_802_ADDR_LENGTH]; /* Destination MAC address */
UCHAR SrcAddr[IEEE_802_ADDR_LENGTH]; /* Source MAC address */
USHORT EType; /* Ethernet protocol type */
} ETH_HEADER, *PETH_HEADER;
#define MAX_MEDIA_ETH sizeof(ETH_HEADER)
/* Broadcast masks */
#define BCAST_ETH_MASK 0x01
/* Broadcast values to check against */
#define BCAST_ETH_CHECK 0x01
/* Offset of broadcast address */
#define BCAST_ETH_OFFSET 0x00
/* Per adapter information */
typedef struct LAN_ADAPTER {
struct LAN_ADAPTER *Next; /* Pointer to next adapter */
KSPIN_LOCK Lock; /* Lock for this structure */
UCHAR State; /* State of the adapter */
KEVENT Event; /* Opening event */
PVOID Context; /* Upper layer context information */
NDIS_HANDLE NdisHandle; /* NDIS binding handle */
NDIS_STATUS NdisStatus; /* NDIS status of last request */
NDIS_MEDIUM Media; /* Media type */
UCHAR HWAddress[IEEE_802_ADDR_LENGTH]; /* Local HW address */
UINT HWAddressLength; /* Length of HW address */
UCHAR BCastMask; /* Mask for checking broadcast */
UCHAR BCastCheck; /* Value to check against */
UCHAR BCastOffset; /* Offset in frame to check against */
UCHAR HeaderSize; /* Size of link-level header */
USHORT MTU; /* Maximum Transfer Unit */
UINT MinFrameSize; /* Minimum frame size in bytes */
UINT MaxPacketSize; /* Maximum packet size when sending */
UINT MaxSendPackets; /* Maximum number of packets per send */
UINT MacOptions; /* MAC options for NIC driver/adapter */
UINT Speed; /* Link speed */
UINT PacketFilter; /* Packet filter for this adapter */
PNDIS_PACKET TDPackets; /* Transfer Data packets */
} LAN_ADAPTER, *PLAN_ADAPTER;
/* LAN adapter state constants */
#define LAN_STATE_OPENING 0
#define LAN_STATE_RESETTING 1
#define LAN_STATE_STARTED 2
#define LAN_STATE_STOPPED 3
/* Size of out lookahead buffer */
#define LOOKAHEAD_SIZE 128
/* Ethernet types. We swap constants so we can compare values at runtime
without swapping them */
#define ETYPE_IPv4 WH2N(0x0800)
#define ETYPE_IPv6 WH2N(0x0000) /* FIXME */
#define ETYPE_ARP WH2N(0x0806)
/* Protocols */
#define LAN_PROTO_IPv4 0x0000 /* Internet Protocol version 4 */
#define LAN_PROTO_IPv6 0x0001 /* Internet Protocol version 6 */
#define LAN_PROTO_ARP 0x0002 /* Address Resolution Protocol */
extern PLAN_ADAPTER Adapters;
NDIS_STATUS LANRegisterAdapter(
PNDIS_STRING AdapterName,
PLAN_ADAPTER *Adapter);
NDIS_STATUS LANUnregisterAdapter(
PLAN_ADAPTER Adapter);
NTSTATUS LANRegisterProtocol(
STRING *Name);
VOID LANUnregisterProtocol(
VOID);
#endif /* __LAN_H */
/* EOF */
+25 -25
View File
@@ -1,25 +1,25 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/loopback.h
* PURPOSE: Loopback adapter definitions
*/
#ifndef __LOOPBACK_H
#define __LOOPBACK_H
#include <lan.h>
extern PIP_INTERFACE Loopback;
NDIS_STATUS LoopRegisterAdapter(
PNDIS_STRING AdapterName,
PLAN_ADAPTER *Adapter);
NDIS_STATUS LoopUnregisterAdapter(
PLAN_ADAPTER Adapter);
#endif /* __LOOPBACK_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/loopback.h
* PURPOSE: Loopback adapter definitions
*/
#ifndef __LOOPBACK_H
#define __LOOPBACK_H
#include <lan.h>
extern PIP_INTERFACE Loopback;
NDIS_STATUS LoopRegisterAdapter(
PNDIS_STRING AdapterName,
PLAN_ADAPTER *Adapter);
NDIS_STATUS LoopUnregisterAdapter(
PLAN_ADAPTER Adapter);
#endif /* __LOOPBACK_H */
/* EOF */
+101 -101
View File
@@ -1,101 +1,101 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/neighbor.h
* PURPOSE: Neighbor definitions
*/
#ifndef __NEIGHBOR_H
#define __NEIGHBOR_H
#define NB_HASHMASK 0xF /* Hash mask for neighbor cache */
typedef struct NEIGHBOR_CACHE_TABLE {
struct NEIGHBOR_CACHE_ENTRY *Cache; /* Pointer to cache */
KSPIN_LOCK Lock; /* Protecting lock */
} NEIGHBOR_CACHE_TABLE, *PNEIGHBOR_CACHE_TABLE;
/* Information about a neighbor */
typedef struct NEIGHBOR_CACHE_ENTRY {
struct NEIGHBOR_CACHE_ENTRY *Next; /* Pointer to next entry */
struct NEIGHBOR_CACHE_TABLE *Table; /* Pointer to table */
ULONG RefCount; /* Number of references */
UCHAR State; /* State of NCE */
UINT EventTimer; /* Ticks since last event */
UINT EventCount; /* Number of events */
PIP_INTERFACE Interface; /* Pointer to interface */
PIP_ADDRESS Address; /* IP address of neighbor */
UINT LinkAddressLength; /* Length of link address */
PVOID LinkAddress; /* Pointer to link address */
PNDIS_PACKET WaitQueue; /* Pointer to NDIS packets
waiting to be sent */
} NEIGHBOR_CACHE_ENTRY, *PNEIGHBOR_CACHE_ENTRY;
/* NCE states */
#define NUD_NONE 0x00
#define NUD_INCOMPLETE 0x01
#define NUD_REACHABLE 0x02
#define NUD_STALE 0x04
#define NUD_DELAY 0x08
#define NUD_PROBE 0x10
#define NUD_FAILED 0x20
#define NUD_NOARP 0x40
#define NUD_PERMANENT 0x80
#define NUD_IN_TIMER (NUD_INCOMPLETE | NUD_DELAY | NUD_PROBE)
#define NUD_VALID (NUD_REACHABLE | NUD_NOARP | NUD_STALE | NUD_DELAY | \
NUD_PROBE | NUD_PERMANENT)
#define NUD_CONNECTED (NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE)
/* Maximum number of retransmissions of multicast solicits */
#define MAX_MULTICAST_SOLICIT 3 /* 3 transmissions */
/* Number of ticks between address resolution messages */
#define RETRANS_TIMER IP_TICKS_SECOND /* One second */
extern NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
VOID NBTimeout(
VOID);
VOID NBStartup(
VOID);
VOID NBShutdown(
VOID);
VOID NBSendSolicit(
PNEIGHBOR_CACHE_ENTRY NCE);
PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
PIP_INTERFACE Interface,
PIP_ADDRESS Address,
PVOID LinkAddress,
UINT LinkAddressLength,
UCHAR Type);
VOID NBUpdateNeighbor(
PNEIGHBOR_CACHE_ENTRY NCE,
PVOID LinkAddress,
UCHAR State);
PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
PIP_ADDRESS Address);
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
PIP_INTERFACE Interface,
PIP_ADDRESS Address);
BOOLEAN NBQueuePacket(
PNEIGHBOR_CACHE_ENTRY NCE,
PNDIS_PACKET NdisPacket);
VOID NBRemoveNeighbor(
PNEIGHBOR_CACHE_ENTRY NCE);
#endif /* __NEIGHBOR_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/neighbor.h
* PURPOSE: Neighbor definitions
*/
#ifndef __NEIGHBOR_H
#define __NEIGHBOR_H
#define NB_HASHMASK 0xF /* Hash mask for neighbor cache */
typedef struct NEIGHBOR_CACHE_TABLE {
struct NEIGHBOR_CACHE_ENTRY *Cache; /* Pointer to cache */
KSPIN_LOCK Lock; /* Protecting lock */
} NEIGHBOR_CACHE_TABLE, *PNEIGHBOR_CACHE_TABLE;
/* Information about a neighbor */
typedef struct NEIGHBOR_CACHE_ENTRY {
struct NEIGHBOR_CACHE_ENTRY *Next; /* Pointer to next entry */
struct NEIGHBOR_CACHE_TABLE *Table; /* Pointer to table */
ULONG RefCount; /* Number of references */
UCHAR State; /* State of NCE */
UINT EventTimer; /* Ticks since last event */
UINT EventCount; /* Number of events */
PIP_INTERFACE Interface; /* Pointer to interface */
PIP_ADDRESS Address; /* IP address of neighbor */
UINT LinkAddressLength; /* Length of link address */
PVOID LinkAddress; /* Pointer to link address */
PNDIS_PACKET WaitQueue; /* Pointer to NDIS packets
waiting to be sent */
} NEIGHBOR_CACHE_ENTRY, *PNEIGHBOR_CACHE_ENTRY;
/* NCE states */
#define NUD_NONE 0x00
#define NUD_INCOMPLETE 0x01
#define NUD_REACHABLE 0x02
#define NUD_STALE 0x04
#define NUD_DELAY 0x08
#define NUD_PROBE 0x10
#define NUD_FAILED 0x20
#define NUD_NOARP 0x40
#define NUD_PERMANENT 0x80
#define NUD_IN_TIMER (NUD_INCOMPLETE | NUD_DELAY | NUD_PROBE)
#define NUD_VALID (NUD_REACHABLE | NUD_NOARP | NUD_STALE | NUD_DELAY | \
NUD_PROBE | NUD_PERMANENT)
#define NUD_CONNECTED (NUD_PERMANENT | NUD_NOARP | NUD_REACHABLE)
/* Maximum number of retransmissions of multicast solicits */
#define MAX_MULTICAST_SOLICIT 3 /* 3 transmissions */
/* Number of ticks between address resolution messages */
#define RETRANS_TIMER IP_TICKS_SECOND /* One second */
extern NEIGHBOR_CACHE_TABLE NeighborCache[NB_HASHMASK + 1];
VOID NBTimeout(
VOID);
VOID NBStartup(
VOID);
VOID NBShutdown(
VOID);
VOID NBSendSolicit(
PNEIGHBOR_CACHE_ENTRY NCE);
PNEIGHBOR_CACHE_ENTRY NBAddNeighbor(
PIP_INTERFACE Interface,
PIP_ADDRESS Address,
PVOID LinkAddress,
UINT LinkAddressLength,
UCHAR Type);
VOID NBUpdateNeighbor(
PNEIGHBOR_CACHE_ENTRY NCE,
PVOID LinkAddress,
UCHAR State);
PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(
PIP_ADDRESS Address);
PNEIGHBOR_CACHE_ENTRY NBFindOrCreateNeighbor(
PIP_INTERFACE Interface,
PIP_ADDRESS Address);
BOOLEAN NBQueuePacket(
PNEIGHBOR_CACHE_ENTRY NCE,
PNDIS_PACKET NdisPacket);
VOID NBRemoveNeighbor(
PNEIGHBOR_CACHE_ENTRY NCE);
#endif /* __NEIGHBOR_H */
/* EOF */
+19 -19
View File
@@ -1,19 +1,19 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/pool.h
* PURPOSE: Prototypes for memory pooling
*/
#ifndef __POOL_H
#define __POOL_H
PVOID PoolAllocateBuffer(
ULONG Size);
VOID PoolFreeBuffer(
PVOID Buffer);
#endif /* __POOL_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/pool.h
* PURPOSE: Prototypes for memory pooling
*/
#ifndef __POOL_H
#define __POOL_H
PVOID PoolAllocateBuffer(
ULONG Size);
VOID PoolFreeBuffer(
PVOID Buffer);
#endif /* __POOL_H */
/* EOF */
+24 -24
View File
@@ -1,24 +1,24 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/rawip.h
* PURPOSE: Raw IP types and constants
*/
#ifndef __RAWIP_H
#define __RAWIP_H
NTSTATUS RawIPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
NTSTATUS RawIPStartup(
VOID);
NTSTATUS RawIPShutdown(
VOID);
#endif /* __RAWIP_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/rawip.h
* PURPOSE: Raw IP types and constants
*/
#ifndef __RAWIP_H
#define __RAWIP_H
NTSTATUS RawIPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
NTSTATUS RawIPStartup(
VOID);
NTSTATUS RawIPShutdown(
VOID);
#endif /* __RAWIP_H */
/* EOF */
+61 -61
View File
@@ -1,61 +1,61 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/receive.h
* PURPOSE: Internet Protocol receive prototypes
*/
#ifndef __RECEIVE_H
#define __RECEIVE_H
#include <ip.h>
/* IP datagram fragment descriptor. Used to store IP datagram fragments */
typedef struct IP_FRAGMENT {
LIST_ENTRY ListEntry; /* Entry on list */
PVOID Data; /* Pointer to fragment data */
UINT Offset; /* Offset into datagram where this fragment is */
UINT Size; /* Size of this fragment */
} IP_FRAGMENT, *PIP_FRAGMENT;
/* IP datagram hole descriptor. Used to reassemble IP datagrams */
typedef struct IPDATAGRAM_HOLE {
LIST_ENTRY ListEntry; /* Entry on list */
UINT First; /* Offset of first octet of the hole */
UINT Last; /* Offset of last octet of the hole */
} IPDATAGRAM_HOLE, *PIPDATAGRAM_HOLE;
/* IP datagram reassembly information */
typedef struct IPDATAGRAM_REASSEMBLY {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Protecting spin lock */
ULONG RefCount; /* Reference count for this object */
UINT DataSize; /* Size of datagram data area */
IP_ADDRESS SrcAddr; /* Source address */
IP_ADDRESS DstAddr; /* Destination address */
UCHAR Protocol; /* Internet Protocol number */
USHORT Id; /* Identification number */
PIPv4_HEADER IPv4Header; /* Pointer to IP header */
UINT HeaderSize; /* Length of IP header */
LIST_ENTRY FragmentListHead; /* IP fragment list */
LIST_ENTRY HoleListHead; /* IP datagram hole list */
} IPDATAGRAM_REASSEMBLY, *PIPDATAGRAM_REASSEMBLY;
extern LIST_ENTRY ReassemblyListHead;
extern KSPIN_LOCK ReassemblyListLock;
VOID IPFreeReassemblyList(
VOID);
VOID IPDatagramReassemblyTimeout(
VOID);
VOID IPReceive(
PVOID Context,
PIP_PACKET IPPacket);
#endif /* __RECEIVE_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/receive.h
* PURPOSE: Internet Protocol receive prototypes
*/
#ifndef __RECEIVE_H
#define __RECEIVE_H
#include <ip.h>
/* IP datagram fragment descriptor. Used to store IP datagram fragments */
typedef struct IP_FRAGMENT {
LIST_ENTRY ListEntry; /* Entry on list */
PVOID Data; /* Pointer to fragment data */
UINT Offset; /* Offset into datagram where this fragment is */
UINT Size; /* Size of this fragment */
} IP_FRAGMENT, *PIP_FRAGMENT;
/* IP datagram hole descriptor. Used to reassemble IP datagrams */
typedef struct IPDATAGRAM_HOLE {
LIST_ENTRY ListEntry; /* Entry on list */
UINT First; /* Offset of first octet of the hole */
UINT Last; /* Offset of last octet of the hole */
} IPDATAGRAM_HOLE, *PIPDATAGRAM_HOLE;
/* IP datagram reassembly information */
typedef struct IPDATAGRAM_REASSEMBLY {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Protecting spin lock */
ULONG RefCount; /* Reference count for this object */
UINT DataSize; /* Size of datagram data area */
IP_ADDRESS SrcAddr; /* Source address */
IP_ADDRESS DstAddr; /* Destination address */
UCHAR Protocol; /* Internet Protocol number */
USHORT Id; /* Identification number */
PIPv4_HEADER IPv4Header; /* Pointer to IP header */
UINT HeaderSize; /* Length of IP header */
LIST_ENTRY FragmentListHead; /* IP fragment list */
LIST_ENTRY HoleListHead; /* IP datagram hole list */
} IPDATAGRAM_REASSEMBLY, *PIPDATAGRAM_REASSEMBLY;
extern LIST_ENTRY ReassemblyListHead;
extern KSPIN_LOCK ReassemblyListLock;
VOID IPFreeReassemblyList(
VOID);
VOID IPDatagramReassemblyTimeout(
VOID);
VOID IPReceive(
PVOID Context,
PIP_PACKET IPPacket);
#endif /* __RECEIVE_H */
/* EOF */
+75 -75
View File
@@ -1,75 +1,75 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/route.h
* PURPOSE: Routing cache definitions
*/
#ifndef __ROUTE_H
#define __ROUTE_H
#include <neighbor.h>
#include <address.h>
#include <router.h>
#include <pool.h>
#include <arp.h>
/* Route Cache Node structure.
* The primary purpose of the RCN is to cache selected source and
* next-hop addresses. The routing cache is implemented as a binary
* search tree to provide fast lookups when many RCNs are in the cache.
*/
typedef struct ROUTE_CACHE_NODE {
struct ROUTE_CACHE_NODE *Parent; /* Pointer to parent */
struct ROUTE_CACHE_NODE *Left; /* Pointer to left child */
struct ROUTE_CACHE_NODE *Right; /* Pointer to right child */
/* Memebers above this line must not be moved */
ULONG RefCount; /* Reference count */
UCHAR State; /* RCN state (RCN_STATE_*) */
IP_ADDRESS Destination; /* Destination address */
PNET_TABLE_ENTRY NTE; /* Preferred NTE */
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE for first hop (NULL if none) */
UINT PathMTU; /* Path MTU to destination */
} ROUTE_CACHE_NODE, *PROUTE_CACHE_NODE;
/* RCN states */
#define RCN_STATE_PERMANENT 0x00 /* RCN is permanent (properly local) */
#define RCN_STATE_COMPUTED 0x01 /* RCN is computed */
#define IsExternalRCN(RCN) \
(RCN == ExternalRCN)
#define IsInternalRCN(RCN) \
(RCN != ExternalRCN)
NTSTATUS RouteStartup(
VOID);
NTSTATUS RouteShutdown(
VOID);
UINT RouteGetRouteToDestination(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE,
PROUTE_CACHE_NODE *RCN);
PROUTE_CACHE_NODE RouteAddRouteToDestination(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE IF,
PNEIGHBOR_CACHE_ENTRY NCE);
VOID RouteRemoveRouteToDestination(
PROUTE_CACHE_NODE RCN);
VOID RouteInvalidateNTE(
PNET_TABLE_ENTRY NTE);
VOID RouteInvalidateNCE(
PNEIGHBOR_CACHE_ENTRY NCE);
#endif /* __ROUTE_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/route.h
* PURPOSE: Routing cache definitions
*/
#ifndef __ROUTE_H
#define __ROUTE_H
#include <neighbor.h>
#include <address.h>
#include <router.h>
#include <pool.h>
#include <arp.h>
/* Route Cache Node structure.
* The primary purpose of the RCN is to cache selected source and
* next-hop addresses. The routing cache is implemented as a binary
* search tree to provide fast lookups when many RCNs are in the cache.
*/
typedef struct ROUTE_CACHE_NODE {
struct ROUTE_CACHE_NODE *Parent; /* Pointer to parent */
struct ROUTE_CACHE_NODE *Left; /* Pointer to left child */
struct ROUTE_CACHE_NODE *Right; /* Pointer to right child */
/* Memebers above this line must not be moved */
ULONG RefCount; /* Reference count */
UCHAR State; /* RCN state (RCN_STATE_*) */
IP_ADDRESS Destination; /* Destination address */
PNET_TABLE_ENTRY NTE; /* Preferred NTE */
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE for first hop (NULL if none) */
UINT PathMTU; /* Path MTU to destination */
} ROUTE_CACHE_NODE, *PROUTE_CACHE_NODE;
/* RCN states */
#define RCN_STATE_PERMANENT 0x00 /* RCN is permanent (properly local) */
#define RCN_STATE_COMPUTED 0x01 /* RCN is computed */
#define IsExternalRCN(RCN) \
(RCN == ExternalRCN)
#define IsInternalRCN(RCN) \
(RCN != ExternalRCN)
NTSTATUS RouteStartup(
VOID);
NTSTATUS RouteShutdown(
VOID);
UINT RouteGetRouteToDestination(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE,
PROUTE_CACHE_NODE *RCN);
PROUTE_CACHE_NODE RouteAddRouteToDestination(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE,
PIP_INTERFACE IF,
PNEIGHBOR_CACHE_ENTRY NCE);
VOID RouteRemoveRouteToDestination(
PROUTE_CACHE_NODE RCN);
VOID RouteInvalidateNTE(
PNET_TABLE_ENTRY NTE);
VOID RouteInvalidateNCE(
PNEIGHBOR_CACHE_ENTRY NCE);
#endif /* __ROUTE_H */
/* EOF */
+62 -62
View File
@@ -1,62 +1,62 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/router.h
* PURPOSE: IP routing definitions
*/
#ifndef __ROUTER_H
#define __ROUTER_H
#include <neighbor.h>
/* Forward Information Base Entry */
typedef struct _FIB_ENTRY {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
PIP_ADDRESS NetworkAddress; /* Address of network */
PIP_ADDRESS Netmask; /* Netmask of network */
PNET_TABLE_ENTRY NTE; /* Pointer to NTE to use */
PNEIGHBOR_CACHE_ENTRY Router; /* Pointer to NCE of router to use */
UINT Metric; /* Cost of this route */
} FIB_ENTRY, *PFIB_ENTRY;
PNET_TABLE_ENTRY RouterFindBestNTE(
PIP_INTERFACE Interface,
PIP_ADDRESS Destination);
PIP_INTERFACE RouterFindOnLinkInterface(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE);
PFIB_ENTRY RouterAddRoute(
PIP_ADDRESS NetworkAddress,
PIP_ADDRESS Netmask,
PNET_TABLE_ENTRY NTE,
PNEIGHBOR_CACHE_ENTRY Router,
UINT Metric);
PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE);
VOID RouterRemoveRoute(
PFIB_ENTRY FIBE);
PFIB_ENTRY RouterCreateRouteIPv4(
IPv4_RAW_ADDRESS NetworkAddress,
IPv4_RAW_ADDRESS Netmask,
IPv4_RAW_ADDRESS RouterAddress,
PNET_TABLE_ENTRY NTE,
UINT Metric);
NTSTATUS RouterStartup(
VOID);
NTSTATUS RouterShutdown(
VOID);
#endif /* __ROUTER_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/router.h
* PURPOSE: IP routing definitions
*/
#ifndef __ROUTER_H
#define __ROUTER_H
#include <neighbor.h>
/* Forward Information Base Entry */
typedef struct _FIB_ENTRY {
LIST_ENTRY ListEntry; /* Entry on list */
ULONG RefCount; /* Reference count */
PIP_ADDRESS NetworkAddress; /* Address of network */
PIP_ADDRESS Netmask; /* Netmask of network */
PNET_TABLE_ENTRY NTE; /* Pointer to NTE to use */
PNEIGHBOR_CACHE_ENTRY Router; /* Pointer to NCE of router to use */
UINT Metric; /* Cost of this route */
} FIB_ENTRY, *PFIB_ENTRY;
PNET_TABLE_ENTRY RouterFindBestNTE(
PIP_INTERFACE Interface,
PIP_ADDRESS Destination);
PIP_INTERFACE RouterFindOnLinkInterface(
PIP_ADDRESS Address,
PNET_TABLE_ENTRY NTE);
PFIB_ENTRY RouterAddRoute(
PIP_ADDRESS NetworkAddress,
PIP_ADDRESS Netmask,
PNET_TABLE_ENTRY NTE,
PNEIGHBOR_CACHE_ENTRY Router,
UINT Metric);
PNEIGHBOR_CACHE_ENTRY RouterGetRoute(
PIP_ADDRESS Destination,
PNET_TABLE_ENTRY NTE);
VOID RouterRemoveRoute(
PFIB_ENTRY FIBE);
PFIB_ENTRY RouterCreateRouteIPv4(
IPv4_RAW_ADDRESS NetworkAddress,
IPv4_RAW_ADDRESS Netmask,
IPv4_RAW_ADDRESS RouterAddress,
PNET_TABLE_ENTRY NTE,
UINT Metric);
NTSTATUS RouterStartup(
VOID);
NTSTATUS RouterShutdown(
VOID);
#endif /* __ROUTER_H */
/* EOF */
+53 -53
View File
@@ -1,53 +1,53 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/routines.h
* PURPOSE: Common routine prototypes
*/
#ifndef __ROUTINES_H
#define __ROUTINES_H
UINT Random(
VOID);
UINT CopyBufferToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PUCHAR SrcData,
UINT Length);
UINT CopyBufferChainToBuffer(
PUCHAR DstData,
PNDIS_BUFFER SrcBuffer,
UINT SrcOffset,
UINT Length);
UINT CopyPacketToBuffer(
PUCHAR DstData,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length);
UINT CopyPacketToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length);
VOID FreeNdisPacket(
PNDIS_PACKET Packet);
PVOID AdjustPacket(
PNDIS_PACKET Packet,
UINT Available,
UINT Needed);
UINT ResizePacket(
PNDIS_PACKET Packet,
UINT Size);
#endif /* __ROUTINES_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/routines.h
* PURPOSE: Common routine prototypes
*/
#ifndef __ROUTINES_H
#define __ROUTINES_H
UINT Random(
VOID);
UINT CopyBufferToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PUCHAR SrcData,
UINT Length);
UINT CopyBufferChainToBuffer(
PUCHAR DstData,
PNDIS_BUFFER SrcBuffer,
UINT SrcOffset,
UINT Length);
UINT CopyPacketToBuffer(
PUCHAR DstData,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length);
UINT CopyPacketToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length);
VOID FreeNdisPacket(
PNDIS_PACKET Packet);
PVOID AdjustPacket(
PNDIS_PACKET Packet,
UINT Available,
UINT Needed);
UINT ResizePacket(
PNDIS_PACKET Packet,
UINT Size);
#endif /* __ROUTINES_H */
/* EOF */
+18 -18
View File
@@ -1,18 +1,18 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/tcp.h
* PURPOSE: Transmission Control Protocol definitions
*/
#ifndef __TCP_H
#define __TCP_H
NTSTATUS TCPStartup(
VOID);
NTSTATUS TCPShutdown(
VOID);
#endif /* __TCP_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/tcp.h
* PURPOSE: Transmission Control Protocol definitions
*/
#ifndef __TCP_H
#define __TCP_H
NTSTATUS TCPStartup(
VOID);
NTSTATUS TCPShutdown(
VOID);
#endif /* __TCP_H */
/* EOF */
+131 -131
View File
@@ -1,131 +1,131 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/tcpip.h
* PURPOSE: TCP/IP protocol driver definitions
* NOTES: Spin lock acquire order:
* - Net table list lock
* - Interface lock
* - Interface list lock
* - Prefix list lock
* - Neighbor cache lock
* - Route cache lock
*/
#ifndef __TCPIP_H
#define __TCPIP_H
#ifdef _MSC_VER
#include <basetsd.h>
#include <ntddk.h>
#include <windef.h>
#include <ndis.h>
#include <tdikrnl.h>
#include <tdiinfo.h>
#else
#include <ddk/ntddk.h>
#include <net/ndis.h>
#include <net/tdikrnl.h>
#include <net/tdiinfo.h>
#endif
#include <debug.h>
/* Define _NTTEST_ to make test version. Device names are prefixed with
'NT' to allow the driver to run side by side with MS TCP/IP driver */
#define _NTTEST_
/* FIXME: The following should be moved to ntddk.h or tdi headers */
#ifndef _MSC_VER
#ifndef IO_NETWORK_INCREMENT
#define IO_NETWORK_INCREMENT 2
#endif
#endif
#ifdef _MSC_VER
/* EXPORTED is already defined ddk/defines.h */
#define EXPORTED __declspec(dllexport)
#endif
#include <titypes.h>
#include <ticonsts.h>
#include <udp.h>
/* Macros */
#define MIN(value1, value2) \
((value1 < value2)? value1 : value2)
#define MAX(value1, value2) \
((value1 > value2)? value1 : value2)
#ifdef i386
/* DWORD network to host byte order conversion for i386 */
#define DN2H(dw) \
((((dw) & 0xFF000000L) >> 24) | \
(((dw) & 0x00FF0000L) >> 8) | \
(((dw) & 0x0000FF00L) << 8) | \
(((dw) & 0x000000FFL) << 24))
/* DWORD host to network byte order conversion for i386 */
#define DH2N(dw) \
((((dw) & 0xFF000000L) >> 24) | \
(((dw) & 0x00FF0000L) >> 8) | \
(((dw) & 0x0000FF00L) << 8) | \
(((dw) & 0x000000FFL) << 24))
/* WORD network to host order conversion for i386 */
#define WN2H(w) \
((((w) & 0xFF00) >> 8) | \
(((w) & 0x00FF) << 8))
/* WORD host to network byte order conversion for i386 */
#define WH2N(w) \
((((w) & 0xFF00) >> 8) | \
(((w) & 0x00FF) << 8))
#else /* i386 */
/* DWORD network to host byte order conversion for other architectures */
#define DN2H(dw) \
(dw)
/* DWORD host to network byte order conversion for other architectures */
#define DH2N(dw) \
(dw)
/* WORD network to host order conversion for other architectures */
#define WN2H(w) \
(w)
/* WORD host to network byte order conversion for other architectures */
#define WH2N(w) \
(w)
#endif /* i386 */
/* Global variable */
extern PDEVICE_OBJECT TCPDeviceObject;
extern PDEVICE_OBJECT UDPDeviceObject;
extern PDEVICE_OBJECT IPDeviceObject;
extern PDEVICE_OBJECT RawIPDeviceObject;
extern LIST_ENTRY InterfaceListHead;
extern KSPIN_LOCK InterfaceListLock;
extern LIST_ENTRY AddressFileListHead;
extern KSPIN_LOCK AddressFileListLock;
extern NDIS_HANDLE GlobalPacketPool;
extern NDIS_HANDLE GlobalBufferPool;
extern TDIEntityID *EntityList;
extern ULONG EntityCount;
extern UDP_STATISTICS UDPStats;
#endif /* __TCPIP_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/tcpip.h
* PURPOSE: TCP/IP protocol driver definitions
* NOTES: Spin lock acquire order:
* - Net table list lock
* - Interface lock
* - Interface list lock
* - Prefix list lock
* - Neighbor cache lock
* - Route cache lock
*/
#ifndef __TCPIP_H
#define __TCPIP_H
#ifdef _MSC_VER
#include <basetsd.h>
#include <ntddk.h>
#include <windef.h>
#include <ndis.h>
#include <tdikrnl.h>
#include <tdiinfo.h>
#else
#include <ddk/ntddk.h>
#include <net/ndis.h>
#include <net/tdikrnl.h>
#include <net/tdiinfo.h>
#endif
#include <debug.h>
/* Define _NTTEST_ to make test version. Device names are prefixed with
'NT' to allow the driver to run side by side with MS TCP/IP driver */
#define _NTTEST_
/* FIXME: The following should be moved to ntddk.h or tdi headers */
#ifndef _MSC_VER
#ifndef IO_NETWORK_INCREMENT
#define IO_NETWORK_INCREMENT 2
#endif
#endif
#ifdef _MSC_VER
/* EXPORTED is already defined ddk/defines.h */
#define EXPORTED __declspec(dllexport)
#endif
#include <titypes.h>
#include <ticonsts.h>
#include <udp.h>
/* Macros */
#define MIN(value1, value2) \
((value1 < value2)? value1 : value2)
#define MAX(value1, value2) \
((value1 > value2)? value1 : value2)
#ifdef i386
/* DWORD network to host byte order conversion for i386 */
#define DN2H(dw) \
((((dw) & 0xFF000000L) >> 24) | \
(((dw) & 0x00FF0000L) >> 8) | \
(((dw) & 0x0000FF00L) << 8) | \
(((dw) & 0x000000FFL) << 24))
/* DWORD host to network byte order conversion for i386 */
#define DH2N(dw) \
((((dw) & 0xFF000000L) >> 24) | \
(((dw) & 0x00FF0000L) >> 8) | \
(((dw) & 0x0000FF00L) << 8) | \
(((dw) & 0x000000FFL) << 24))
/* WORD network to host order conversion for i386 */
#define WN2H(w) \
((((w) & 0xFF00) >> 8) | \
(((w) & 0x00FF) << 8))
/* WORD host to network byte order conversion for i386 */
#define WH2N(w) \
((((w) & 0xFF00) >> 8) | \
(((w) & 0x00FF) << 8))
#else /* i386 */
/* DWORD network to host byte order conversion for other architectures */
#define DN2H(dw) \
(dw)
/* DWORD host to network byte order conversion for other architectures */
#define DH2N(dw) \
(dw)
/* WORD network to host order conversion for other architectures */
#define WN2H(w) \
(w)
/* WORD host to network byte order conversion for other architectures */
#define WH2N(w) \
(w)
#endif /* i386 */
/* Global variable */
extern PDEVICE_OBJECT TCPDeviceObject;
extern PDEVICE_OBJECT UDPDeviceObject;
extern PDEVICE_OBJECT IPDeviceObject;
extern PDEVICE_OBJECT RawIPDeviceObject;
extern LIST_ENTRY InterfaceListHead;
extern KSPIN_LOCK InterfaceListLock;
extern LIST_ENTRY AddressFileListHead;
extern KSPIN_LOCK AddressFileListLock;
extern NDIS_HANDLE GlobalPacketPool;
extern NDIS_HANDLE GlobalBufferPool;
extern TDIEntityID *EntityList;
extern ULONG EntityCount;
extern UDP_STATISTICS UDPStats;
#endif /* __TCPIP_H */
/* EOF */
+56 -56
View File
@@ -1,56 +1,56 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/ticonsts.h
* PURPOSE: TCP/IP protocol driver constants
*/
#ifndef __TICONSTS_H
#define __TICONSTS_H
/* NDIS version this driver supports */
#define NDIS_VERSION_MAJOR 3
#define NDIS_VERSION_MINOR 0
#ifdef _NTTEST_
/* Name of devices */
#define DD_TCP_DEVICE_NAME L"\\Device\\NTTcp"
#define DD_UDP_DEVICE_NAME L"\\Device\\NTUdp"
#define DD_IP_DEVICE_NAME L"\\Device\\NTIp"
#define DD_RAWIP_DEVICE_NAME L"\\Device\\NTRawIp"
/* For NDIS protocol registration */
#define IP_DEVICE_NAME "\\Device\\NTIp"
#else
#define DD_TCP_DEVICE_NAME L"\\Device\\Tcp"
#define DD_UDP_DEVICE_NAME L"\\Device\\Udp"
#define DD_IP_DEVICE_NAME L"\\Device\\Ip"
#define DD_RAWIP_DEVICE_NAME L"\\Device\\RawIp"
/* For NDIS protocol registration */
#define IP_DEVICE_NAME "\\Device\\Ip"
#endif /* _NTTEST_ */
/* TCP/UDP/RawIP IOCTL code definitions */
#define FSCTL_TCP_BASE FILE_DEVICE_NETWORK
#define _TCP_CTL_CODE(Function, Method, Access) \
CTL_CODE(FSCTL_TCP_BASE, Function, Method, Access)
#define IOCTL_TCP_QUERY_INFORMATION_EX \
_TCP_CTL_CODE(0, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_TCP_SET_INFORMATION_EX \
_TCP_CTL_CODE(1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
/* Unique error values for log entries */
#define TI_ERROR_DRIVERENTRY 0
/* Internal status codes */
#define IP_SUCCESS 0x0000 /* Successful */
#define IP_NO_RESOURCES 0x0001 /* Not enough free resources */
#define IP_NO_ROUTE_TO_DESTINATION 0x0002 /* No route to destination */
#endif /* __TICONSTS_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/ticonsts.h
* PURPOSE: TCP/IP protocol driver constants
*/
#ifndef __TICONSTS_H
#define __TICONSTS_H
/* NDIS version this driver supports */
#define NDIS_VERSION_MAJOR 3
#define NDIS_VERSION_MINOR 0
#ifdef _NTTEST_
/* Name of devices */
#define DD_TCP_DEVICE_NAME L"\\Device\\NTTcp"
#define DD_UDP_DEVICE_NAME L"\\Device\\NTUdp"
#define DD_IP_DEVICE_NAME L"\\Device\\NTIp"
#define DD_RAWIP_DEVICE_NAME L"\\Device\\NTRawIp"
/* For NDIS protocol registration */
#define IP_DEVICE_NAME "\\Device\\NTIp"
#else
#define DD_TCP_DEVICE_NAME L"\\Device\\Tcp"
#define DD_UDP_DEVICE_NAME L"\\Device\\Udp"
#define DD_IP_DEVICE_NAME L"\\Device\\Ip"
#define DD_RAWIP_DEVICE_NAME L"\\Device\\RawIp"
/* For NDIS protocol registration */
#define IP_DEVICE_NAME "\\Device\\Ip"
#endif /* _NTTEST_ */
/* TCP/UDP/RawIP IOCTL code definitions */
#define FSCTL_TCP_BASE FILE_DEVICE_NETWORK
#define _TCP_CTL_CODE(Function, Method, Access) \
CTL_CODE(FSCTL_TCP_BASE, Function, Method, Access)
#define IOCTL_TCP_QUERY_INFORMATION_EX \
_TCP_CTL_CODE(0, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_TCP_SET_INFORMATION_EX \
_TCP_CTL_CODE(1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
/* Unique error values for log entries */
#define TI_ERROR_DRIVERENTRY 0
/* Internal status codes */
#define IP_SUCCESS 0x0000 /* Successful */
#define IP_NO_RESOURCES 0x0001 /* Not enough free resources */
#define IP_NO_ROUTE_TO_DESTINATION 0x0002 /* No route to destination */
#endif /* __TICONSTS_H */
/* EOF */
+215 -215
View File
@@ -1,215 +1,215 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/titypes.h
* PURPOSE: TCP/IP protocol driver types
*/
#ifndef __TITYPES_H
#define __TITYPES_H
#include <ip.h>
#ifdef DBG
#define DEBUG_REFCHECK(Object) { \
if ((Object)->RefCount <= 0) { \
TI_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \
(Object), (Object)->RefCount)); \
} \
}
#else
#define DEBUG_REFCHECK(Object)
#endif
/*
* VOID ReferenceObject(
* PVOID Object)
*/
#define ReferenceObject(Object) \
{ \
DEBUG_REFCHECK(Object); \
TI_DbgPrint(DEBUG_REFCOUNT, ("Referencing object at (0x%X). RefCount (%d).\n", \
(Object), (Object)->RefCount)); \
\
InterlockedIncrement(&((Object)->RefCount)); \
}
/*
* VOID DereferenceObject(
* PVOID Object)
*/
#define DereferenceObject(Object) \
{ \
DEBUG_REFCHECK(Object); \
TI_DbgPrint(DEBUG_REFCOUNT, ("Dereferencing object at (0x%X). RefCount (%d).\n", \
(Object), (Object)->RefCount)); \
\
if (InterlockedDecrement(&((Object)->RefCount)) == 0) \
PoolFreeBuffer(Object); \
}
typedef NTSTATUS (*DATAGRAM_SEND_ROUTINE)(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
/* Datagram completion handler prototype */
typedef VOID (*DATAGRAM_COMPLETION_ROUTINE)(
PVOID Context,
NDIS_STATUS Status,
ULONG Count);
typedef struct _DATAGRAM_RECEIVE_REQUEST {
LIST_ENTRY ListEntry; /* Entry on list */
PIP_ADDRESS RemoteAddress; /* Remote address we receive from (NULL means any) */
USHORT RemotePort; /* Remote port we receive from (0 means any) */
PTDI_CONNECTION_INFORMATION ReturnInfo; /* Return information */
PNDIS_BUFFER Buffer; /* Pointer to receive buffer */
ULONG BufferSize; /* Size of Buffer */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
PVOID Context; /* Pointer to context information */
} DATAGRAM_RECEIVE_REQUEST, *PDATAGRAM_RECEIVE_REQUEST;
/* Datagram build routine prototype */
typedef NTSTATUS (*DATAGRAM_BUILD_ROUTINE)(
PVOID Context,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET *IPPacket);
typedef struct _DATAGRAM_SEND_REQUEST {
LIST_ENTRY ListEntry; /* Entry on list */
PIP_ADDRESS RemoteAddress; /* Pointer to remote IP address */
USHORT RemotePort; /* Remote port number */
PNDIS_BUFFER Buffer; /* Pointer to NDIS buffer to send */
DWORD BufferSize; /* Size of Buffer */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
PVOID Context; /* Pointer to context information */
DATAGRAM_BUILD_ROUTINE Build; /* Datagram build routine */
} DATAGRAM_SEND_REQUEST, *PDATAGRAM_SEND_REQUEST;
/* Transport (TCP/UDP) endpoint context structure. The FileObject->FsContext
field holds a pointer to this structure */
typedef struct _TRANSPORT_CONTEXT {
union {
HANDLE AddressHandle;
CONNECTION_CONTEXT ConnectionContext;
HANDLE ControlChannel;
} Handle;
ULONG RefCount;
BOOL CancelIrps;
KEVENT CleanupEvent;
} TRANSPORT_CONTEXT, *PTRANSPORT_CONTEXT;
typedef struct _ADDRESS_FILE {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */
ULONG RefCount; /* Number of references to this object */
USHORT Flags; /* Flags for address file (see below) */
PADDRESS_ENTRY ADE; /* Associated address entry */
USHORT Protocol; /* Protocol number */
USHORT Port; /* Network port (network byte order) */
WORK_QUEUE_ITEM WorkItem; /* Work queue item handle */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine for delete request */
PVOID Context; /* Delete request context */
DATAGRAM_SEND_ROUTINE Send; /* Routine to send a datagram */
LIST_ENTRY ReceiveQueue; /* List of outstanding receive requests */
LIST_ENTRY TransmitQueue; /* List of outstanding transmit requests */
PIP_ADDRESS AddrCache; /* One entry address cache (destination
address of last packet transmitted) */
/* The following members are used to control event notification */
/* Connection indication handler */
PTDI_IND_CONNECT ConnectionHandler;
PVOID ConnectionHandlerContext;
BOOL RegisteredConnectionHandler;
/* Disconnect indication handler */
PTDI_IND_DISCONNECT DisconnectHandler;
PVOID DisconnectHandlerContext;
BOOL RegisteredDisconnectHandler;
/* Receive indication handler */
PTDI_IND_RECEIVE ReceiveHandler;
PVOID ReceiveHandlerContext;
BOOL RegisteredReceiveHandler;
/* Expedited receive indication handler */
PTDI_IND_RECEIVE_EXPEDITED ExpeditedReceiveHandler;
PVOID ExpeditedReceiveHandlerContext;
BOOL RegisteredExpeditedReceiveHandler;
/* Receive datagram indication handler */
PTDI_IND_RECEIVE_DATAGRAM ReceiveDatagramHandler;
PVOID ReceiveDatagramHandlerContext;
BOOL RegisteredReceiveDatagramHandler;
/* Error indication handler */
PTDI_IND_ERROR ErrorHandler;
PVOID ErrorHandlerContext;
PVOID ErrorHandlerOwner;
BOOL RegisteredErrorHandler;
} ADDRESS_FILE, *PADDRESS_FILE;
/* Address File Flag constants */
#define AFF_VALID 0x0001 /* Address file object is valid for use */
#define AFF_BUSY 0x0002 /* Address file object is exclusive to someone */
#define AFF_DELETE 0x0004 /* Address file object is sheduled to be deleted */
#define AFF_SEND 0x0008 /* A send request is pending */
#define AFF_RECEIVE 0x0010 /* A receive request is pending */
#define AFF_PENDING 0x001C /* A request is pending */
/* Macros for manipulating address file object flags */
#define AF_IS_VALID(ADF) ((ADF)->Flags & AFF_VALID)
#define AF_SET_VALID(ADF) ((ADF)->Flags |= AFF_VALID)
#define AF_CLR_VALID(ADF) ((ADF)->Flags &= ~AFF_VALID)
#define AF_IS_BUSY(ADF) ((ADF)->Flags & AFF_BUSY)
#define AF_SET_BUSY(ADF) ((ADF)->Flags |= AFF_BUSY)
#define AF_CLR_BUSY(ADF) ((ADF)->Flags &= ~AFF_BUSY)
#define AF_IS_PENDING(ADF, X) (ADF->Flags & X)
#define AF_SET_PENDING(ADF, X) (ADF->Flags |= X)
#define AF_CLR_PENDING(ADF, X) (ADF->Flags &= ~X)
/* Structure used to search through Address Files */
typedef struct _AF_SEARCH {
PLIST_ENTRY Next; /* Next address file to check */
PIP_ADDRESS Address; /* Pointer to address to be found */
USHORT Port; /* Network port */
USHORT Protocol; /* Protocol number */
} AF_SEARCH, *PAF_SEARCH;
/* Transport connection context structure. The FileObject->FsContext2
field holds a pointer to this structure */
typedef struct _CONNECTION_ENDPOINT {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to protect this structure */
ULONG RefCount; /* Number of references to this object */
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
/* Transport control channel context structure. The FileObject->FsContext2
field holds a pointer to this structure */
typedef struct _CONTROL_CHANNEL {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to protect this structure */
ULONG RefCount; /* Number of references to this object */
} CONTROL_CHANNEL, *PCONTROL_CHANNEL;
typedef struct _TI_QUERY_CONTEXT {
PIRP Irp;
PMDL InputMdl;
PMDL OutputMdl;
TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo;
} TI_QUERY_CONTEXT, *PTI_QUERY_CONTEXT;
#endif /* __TITYPES_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/titypes.h
* PURPOSE: TCP/IP protocol driver types
*/
#ifndef __TITYPES_H
#define __TITYPES_H
#include <ip.h>
#ifdef DBG
#define DEBUG_REFCHECK(Object) { \
if ((Object)->RefCount <= 0) { \
TI_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \
(Object), (Object)->RefCount)); \
} \
}
#else
#define DEBUG_REFCHECK(Object)
#endif
/*
* VOID ReferenceObject(
* PVOID Object)
*/
#define ReferenceObject(Object) \
{ \
DEBUG_REFCHECK(Object); \
TI_DbgPrint(DEBUG_REFCOUNT, ("Referencing object at (0x%X). RefCount (%d).\n", \
(Object), (Object)->RefCount)); \
\
InterlockedIncrement(&((Object)->RefCount)); \
}
/*
* VOID DereferenceObject(
* PVOID Object)
*/
#define DereferenceObject(Object) \
{ \
DEBUG_REFCHECK(Object); \
TI_DbgPrint(DEBUG_REFCOUNT, ("Dereferencing object at (0x%X). RefCount (%d).\n", \
(Object), (Object)->RefCount)); \
\
if (InterlockedDecrement(&((Object)->RefCount)) == 0) \
PoolFreeBuffer(Object); \
}
typedef NTSTATUS (*DATAGRAM_SEND_ROUTINE)(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
/* Datagram completion handler prototype */
typedef VOID (*DATAGRAM_COMPLETION_ROUTINE)(
PVOID Context,
NDIS_STATUS Status,
ULONG Count);
typedef struct _DATAGRAM_RECEIVE_REQUEST {
LIST_ENTRY ListEntry; /* Entry on list */
PIP_ADDRESS RemoteAddress; /* Remote address we receive from (NULL means any) */
USHORT RemotePort; /* Remote port we receive from (0 means any) */
PTDI_CONNECTION_INFORMATION ReturnInfo; /* Return information */
PNDIS_BUFFER Buffer; /* Pointer to receive buffer */
ULONG BufferSize; /* Size of Buffer */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
PVOID Context; /* Pointer to context information */
} DATAGRAM_RECEIVE_REQUEST, *PDATAGRAM_RECEIVE_REQUEST;
/* Datagram build routine prototype */
typedef NTSTATUS (*DATAGRAM_BUILD_ROUTINE)(
PVOID Context,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET *IPPacket);
typedef struct _DATAGRAM_SEND_REQUEST {
LIST_ENTRY ListEntry; /* Entry on list */
PIP_ADDRESS RemoteAddress; /* Pointer to remote IP address */
USHORT RemotePort; /* Remote port number */
PNDIS_BUFFER Buffer; /* Pointer to NDIS buffer to send */
DWORD BufferSize; /* Size of Buffer */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
PVOID Context; /* Pointer to context information */
DATAGRAM_BUILD_ROUTINE Build; /* Datagram build routine */
} DATAGRAM_SEND_REQUEST, *PDATAGRAM_SEND_REQUEST;
/* Transport (TCP/UDP) endpoint context structure. The FileObject->FsContext
field holds a pointer to this structure */
typedef struct _TRANSPORT_CONTEXT {
union {
HANDLE AddressHandle;
CONNECTION_CONTEXT ConnectionContext;
HANDLE ControlChannel;
} Handle;
ULONG RefCount;
BOOL CancelIrps;
KEVENT CleanupEvent;
} TRANSPORT_CONTEXT, *PTRANSPORT_CONTEXT;
typedef struct _ADDRESS_FILE {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */
ULONG RefCount; /* Number of references to this object */
USHORT Flags; /* Flags for address file (see below) */
PADDRESS_ENTRY ADE; /* Associated address entry */
USHORT Protocol; /* Protocol number */
USHORT Port; /* Network port (network byte order) */
WORK_QUEUE_ITEM WorkItem; /* Work queue item handle */
DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine for delete request */
PVOID Context; /* Delete request context */
DATAGRAM_SEND_ROUTINE Send; /* Routine to send a datagram */
LIST_ENTRY ReceiveQueue; /* List of outstanding receive requests */
LIST_ENTRY TransmitQueue; /* List of outstanding transmit requests */
PIP_ADDRESS AddrCache; /* One entry address cache (destination
address of last packet transmitted) */
/* The following members are used to control event notification */
/* Connection indication handler */
PTDI_IND_CONNECT ConnectionHandler;
PVOID ConnectionHandlerContext;
BOOL RegisteredConnectionHandler;
/* Disconnect indication handler */
PTDI_IND_DISCONNECT DisconnectHandler;
PVOID DisconnectHandlerContext;
BOOL RegisteredDisconnectHandler;
/* Receive indication handler */
PTDI_IND_RECEIVE ReceiveHandler;
PVOID ReceiveHandlerContext;
BOOL RegisteredReceiveHandler;
/* Expedited receive indication handler */
PTDI_IND_RECEIVE_EXPEDITED ExpeditedReceiveHandler;
PVOID ExpeditedReceiveHandlerContext;
BOOL RegisteredExpeditedReceiveHandler;
/* Receive datagram indication handler */
PTDI_IND_RECEIVE_DATAGRAM ReceiveDatagramHandler;
PVOID ReceiveDatagramHandlerContext;
BOOL RegisteredReceiveDatagramHandler;
/* Error indication handler */
PTDI_IND_ERROR ErrorHandler;
PVOID ErrorHandlerContext;
PVOID ErrorHandlerOwner;
BOOL RegisteredErrorHandler;
} ADDRESS_FILE, *PADDRESS_FILE;
/* Address File Flag constants */
#define AFF_VALID 0x0001 /* Address file object is valid for use */
#define AFF_BUSY 0x0002 /* Address file object is exclusive to someone */
#define AFF_DELETE 0x0004 /* Address file object is sheduled to be deleted */
#define AFF_SEND 0x0008 /* A send request is pending */
#define AFF_RECEIVE 0x0010 /* A receive request is pending */
#define AFF_PENDING 0x001C /* A request is pending */
/* Macros for manipulating address file object flags */
#define AF_IS_VALID(ADF) ((ADF)->Flags & AFF_VALID)
#define AF_SET_VALID(ADF) ((ADF)->Flags |= AFF_VALID)
#define AF_CLR_VALID(ADF) ((ADF)->Flags &= ~AFF_VALID)
#define AF_IS_BUSY(ADF) ((ADF)->Flags & AFF_BUSY)
#define AF_SET_BUSY(ADF) ((ADF)->Flags |= AFF_BUSY)
#define AF_CLR_BUSY(ADF) ((ADF)->Flags &= ~AFF_BUSY)
#define AF_IS_PENDING(ADF, X) (ADF->Flags & X)
#define AF_SET_PENDING(ADF, X) (ADF->Flags |= X)
#define AF_CLR_PENDING(ADF, X) (ADF->Flags &= ~X)
/* Structure used to search through Address Files */
typedef struct _AF_SEARCH {
PLIST_ENTRY Next; /* Next address file to check */
PIP_ADDRESS Address; /* Pointer to address to be found */
USHORT Port; /* Network port */
USHORT Protocol; /* Protocol number */
} AF_SEARCH, *PAF_SEARCH;
/* Transport connection context structure. The FileObject->FsContext2
field holds a pointer to this structure */
typedef struct _CONNECTION_ENDPOINT {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to protect this structure */
ULONG RefCount; /* Number of references to this object */
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
/* Transport control channel context structure. The FileObject->FsContext2
field holds a pointer to this structure */
typedef struct _CONTROL_CHANNEL {
LIST_ENTRY ListEntry; /* Entry on list */
KSPIN_LOCK Lock; /* Spin lock to protect this structure */
ULONG RefCount; /* Number of references to this object */
} CONTROL_CHANNEL, *PCONTROL_CHANNEL;
typedef struct _TI_QUERY_CONTEXT {
PIRP Irp;
PMDL InputMdl;
PMDL OutputMdl;
TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo;
} TI_QUERY_CONTEXT, *PTI_QUERY_CONTEXT;
#endif /* __TITYPES_H */
/* EOF */
+47 -47
View File
@@ -1,47 +1,47 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/transmit.h
* PURPOSE: Internet Protocol transmit prototypes
*/
#ifndef __TRANSMIT_H
#define __TRANSMIT_H
#include <neighbor.h>
#include <route.h>
#include <ip.h>
/* IP fragment context information */
typedef struct IPFRAGMENT_CONTEXT {
struct IPFRAGMENT_CONTEXT *Next; /* Pointer to next in list */
PNDIS_PACKET Datagram; /* Pointer to original NDIS packet */
PVOID DatagramData; /* Pointer to datagram data */
UINT HeaderSize; /* IP datagram header size */
PNDIS_PACKET NdisPacket; /* Pointer to NDIS packet */
PNDIS_BUFFER NdisBuffer; /* Pointer to NDIS buffer */
PVOID Header; /* Pointer to IP header in fragment buffer */
PVOID Data; /* Pointer to fragment data */
UINT Position; /* Current fragment offset */
UINT BytesLeft; /* Number of bytes left to send */
UINT PathMTU; /* Path Maximum Transmission Unit */
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE to use */
} IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT;
VOID IPSendComplete(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus);
NTSTATUS IPSendFragment(
PNDIS_PACKET NdisPacket,
PNEIGHBOR_CACHE_ENTRY NCE);
NTSTATUS IPSendDatagram(
PIP_PACKET IPPacket,
PROUTE_CACHE_NODE RCN);
#endif /* __TRANSMIT_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/transmit.h
* PURPOSE: Internet Protocol transmit prototypes
*/
#ifndef __TRANSMIT_H
#define __TRANSMIT_H
#include <neighbor.h>
#include <route.h>
#include <ip.h>
/* IP fragment context information */
typedef struct IPFRAGMENT_CONTEXT {
struct IPFRAGMENT_CONTEXT *Next; /* Pointer to next in list */
PNDIS_PACKET Datagram; /* Pointer to original NDIS packet */
PVOID DatagramData; /* Pointer to datagram data */
UINT HeaderSize; /* IP datagram header size */
PNDIS_PACKET NdisPacket; /* Pointer to NDIS packet */
PNDIS_BUFFER NdisBuffer; /* Pointer to NDIS buffer */
PVOID Header; /* Pointer to IP header in fragment buffer */
PVOID Data; /* Pointer to fragment data */
UINT Position; /* Current fragment offset */
UINT BytesLeft; /* Number of bytes left to send */
UINT PathMTU; /* Path Maximum Transmission Unit */
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE to use */
} IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT;
VOID IPSendComplete(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus);
NTSTATUS IPSendFragment(
PNDIS_PACKET NdisPacket,
PNEIGHBOR_CACHE_ENTRY NCE);
NTSTATUS IPSendDatagram(
PIP_PACKET IPPacket,
PROUTE_CACHE_NODE RCN);
#endif /* __TRANSMIT_H */
/* EOF */
+68 -68
View File
@@ -1,68 +1,68 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/udp.h
* PURPOSE: User Datagram Protocol definitions
*/
#ifndef __UDP_H
#define __UDP_H
/* UDPv4 header structure */
typedef struct UDP_HEADER {
USHORT SourcePort; /* Source port */
USHORT DestPort; /* Destination port */
USHORT Length; /* Size of header and data */
USHORT Checksum; /* Checksum of datagram */
} UDP_HEADER, *PUDP_HEADER;
/* UDPv4 pseudo header */
typedef struct UDP_PSEUDO_HEADER {
ULONG SourceAddress; /* Source address */
ULONG DestAddress; /* Destination address */
UCHAR Zero; /* Reserved */
UCHAR Protocol; /* Protocol */
USHORT UDPLength; /* Size of UDP datagram */
} UDP_PSEUDO_HEADER, *PUDP_PSEUDO_HEADER;
typedef struct UDP_STATISTICS {
ULONG InputDatagrams;
ULONG NumPorts;
ULONG InputErrors;
ULONG OutputDatagrams;
ULONG NumAddresses;
} UDP_STATISTICS, *PUDP_STATISTICS;
VOID UDPSend(
PVOID Context,
PDATAGRAM_SEND_REQUEST SendRequest);
NTSTATUS UDPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
NTSTATUS UDPReceiveDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived);
VOID UDPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
NTSTATUS UDPStartup(
VOID);
NTSTATUS UDPShutdown(
VOID);
#endif /* __UDP_H */
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: include/udp.h
* PURPOSE: User Datagram Protocol definitions
*/
#ifndef __UDP_H
#define __UDP_H
/* UDPv4 header structure */
typedef struct UDP_HEADER {
USHORT SourcePort; /* Source port */
USHORT DestPort; /* Destination port */
USHORT Length; /* Size of header and data */
USHORT Checksum; /* Checksum of datagram */
} UDP_HEADER, *PUDP_HEADER;
/* UDPv4 pseudo header */
typedef struct UDP_PSEUDO_HEADER {
ULONG SourceAddress; /* Source address */
ULONG DestAddress; /* Destination address */
UCHAR Zero; /* Reserved */
UCHAR Protocol; /* Protocol */
USHORT UDPLength; /* Size of UDP datagram */
} UDP_PSEUDO_HEADER, *PUDP_PSEUDO_HEADER;
typedef struct UDP_STATISTICS {
ULONG InputDatagrams;
ULONG NumPorts;
ULONG InputErrors;
ULONG OutputDatagrams;
ULONG NumAddresses;
} UDP_STATISTICS, *PUDP_STATISTICS;
VOID UDPSend(
PVOID Context,
PDATAGRAM_SEND_REQUEST SendRequest);
NTSTATUS UDPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize);
NTSTATUS UDPReceiveDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived);
VOID UDPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket);
NTSTATUS UDPStartup(
VOID);
NTSTATUS UDPShutdown(
VOID);
#endif /* __UDP_H */
/* EOF */
+132 -132
View File
@@ -1,132 +1,132 @@
# TCPIP.SYS - TCP/IP protocol driver
TARGETNAME=tcpip
BASE_CFLAGS = -I./include -I../../../include
RESOURCE_OBJECT = $(TARGETNAME).coff
TCPIP_OBJECTS = tcpip/main.o tcpip/address.o tcpip/checksum.o \
tcpip/dispatch.o tcpip/fileobjs.o tcpip/info.o \
tcpip/pool.o tcpip/routines.o
DATALINK_OBJECTS = datalink/arp.o datalink/lan.o datalink/loopback.o
NETWORK_OBJECTS = network/icmp.o network/ip.o network/neighbor.o \
network/receive.o network/route.o network/router.o \
network/transmit.o
DATAGRAM_OBJECTS = transport/datagram/datagram.o
RAWIP_OBJECTS = transport/rawip/rawip.o
TCP_OBJECTS = transport/tcp/tcp.o
UDP_OBJECTS = transport/udp/udp.o
all: objects $(TARGETNAME).sys
objects:
mkdir objects
objects/tcpip.o: $(TCPIP_OBJECTS)
$(LD) -r -o objects/tcpip.o $(TCPIP_OBJECTS)
objects/datalink.o: $(DATALINK_OBJECTS)
$(LD) -r -o objects/datalink.o $(DATALINK_OBJECTS)
objects/network.o: $(NETWORK_OBJECTS)
$(LD) -r -o objects/network.o $(NETWORK_OBJECTS)
objects/datagram.o: $(DATAGRAM_OBJECTS)
$(LD) -r -o objects/datagram.o $(DATAGRAM_OBJECTS)
objects/rawip.o: $(RAWIP_OBJECTS)
$(LD) -r -o objects/rawip.o $(RAWIP_OBJECTS)
objects/tcp.o: $(TCP_OBJECTS)
$(LD) -r -o objects/tcp.o $(TCP_OBJECTS)
objects/udp.o: $(UDP_OBJECTS)
$(LD) -r -o objects/udp.o $(UDP_OBJECTS)
OBJECTS = objects/tcpip.o objects/datalink.o objects/network.o \
objects/datagram.o objects/rawip.o objects/tcp.o objects/udp.o \
$(RESOURCE_OBJECT) \
../../../ntoskrnl/ntoskrnl.a ../ndis/ndis.a
$(TARGETNAME).coff: $(TARGETNAME).rc ../../../include/reactos/resource.h
ifeq ($(DOSCLI),yes)
CLEAN_FILES = \
*.o objects\*.o tcpip\*.o datalink\*.o network\*.o \
transport\datagram\*.o transport\rawip\*.o \
transport\tcp\*.o transport\udp\*.o $(TARGETNAME).coff \
$(TARGETNAME).a junk.tmp base.tmp temp.exp \
$(TARGETNAME).sys $(TARGETNAME).sym
else
CLEAN_FILES = \
*.o objects/*.o tcpip/*.o datalink/*.o network/*.o \
transport/datagram/*.o transport/rawip/*.o \
transport/tcp/*.o transport/udp/*.o $(TARGETNAME).coff \
$(TARGETNAME).a junk.tmp base.tmp temp.exp \
$(TARGETNAME).sys $(TARGETNAME).sym
endif
$(TARGETNAME).sys: $(OBJECTS)
$(DLLTOOL) \
--dllname $(TARGETNAME).sys \
--def $(TARGETNAME).def \
--kill-at \
--output-lib $(TARGETNAME).a
$(CC) \
-mdll \
-specs=../../svc_specs \
-Wl,-e,_DriverEntry@8 \
-Wl,--base-file,base.tmp \
-Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ \
-Wl,--defsym,_etext=etext \
$(OBJECTS) \
-o junk.tmp
- $(RM) junk.tmp
$(DLLTOOL) \
--dllname $(TARGETNAME).sys \
--base-file base.tmp \
--output-exp temp.exp \
--def $(TARGETNAME).edf
- $(RM) base.tmp
$(CC) \
-mdll \
-specs=../../svc_specs \
-Wl,--image-base,0x10000 \
-Wl,-e,_DriverEntry@8 \
-Wl,temp.exp \
$(OBJECTS) \
-o $(TARGETNAME).sys
- $(RM) temp.exp
$(NM) --numeric-sort $(TARGETNAME).sys > $(TARGETNAME).sym
clean: $(CLEAN_FILES:%=%_clean)
$(CLEAN_FILES:%=%_clean): %_clean:
- $(RM) $*
.PHONY: clean $(CLEAN_FILES:%=%_clean)
floppy: $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
$(FLOPPY_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)\drivers\$(TARGETNAME).sys
else
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
endif
dist: $(DIST_DIR)/drivers/$(TARGETNAME).sys
$(DIST_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGETNAME).sys ..\..\$(DIST_DIR)\drivers\$(TARGETNAME).sys
else
$(CP) $(TARGETNAME).sys ../../$(DIST_DIR)/drivers/$(TARGETNAME).sys
endif
#WITH_DEBUGGING = yes
#WIN32_LEAN_AND_MEAN = yes
#WARNINGS_ARE_ERRORS = yes
include ../../../rules.mak
# TCPIP.SYS - TCP/IP protocol driver
TARGETNAME=tcpip
BASE_CFLAGS = -I./include -I../../../include
RESOURCE_OBJECT = $(TARGETNAME).coff
TCPIP_OBJECTS = tcpip/main.o tcpip/address.o tcpip/checksum.o \
tcpip/dispatch.o tcpip/fileobjs.o tcpip/info.o \
tcpip/pool.o tcpip/routines.o
DATALINK_OBJECTS = datalink/arp.o datalink/lan.o datalink/loopback.o
NETWORK_OBJECTS = network/icmp.o network/ip.o network/neighbor.o \
network/receive.o network/route.o network/router.o \
network/transmit.o
DATAGRAM_OBJECTS = transport/datagram/datagram.o
RAWIP_OBJECTS = transport/rawip/rawip.o
TCP_OBJECTS = transport/tcp/tcp.o
UDP_OBJECTS = transport/udp/udp.o
all: objects $(TARGETNAME).sys
objects:
mkdir objects
objects/tcpip.o: $(TCPIP_OBJECTS)
$(LD) -r -o objects/tcpip.o $(TCPIP_OBJECTS)
objects/datalink.o: $(DATALINK_OBJECTS)
$(LD) -r -o objects/datalink.o $(DATALINK_OBJECTS)
objects/network.o: $(NETWORK_OBJECTS)
$(LD) -r -o objects/network.o $(NETWORK_OBJECTS)
objects/datagram.o: $(DATAGRAM_OBJECTS)
$(LD) -r -o objects/datagram.o $(DATAGRAM_OBJECTS)
objects/rawip.o: $(RAWIP_OBJECTS)
$(LD) -r -o objects/rawip.o $(RAWIP_OBJECTS)
objects/tcp.o: $(TCP_OBJECTS)
$(LD) -r -o objects/tcp.o $(TCP_OBJECTS)
objects/udp.o: $(UDP_OBJECTS)
$(LD) -r -o objects/udp.o $(UDP_OBJECTS)
OBJECTS = objects/tcpip.o objects/datalink.o objects/network.o \
objects/datagram.o objects/rawip.o objects/tcp.o objects/udp.o \
$(RESOURCE_OBJECT) \
../../../ntoskrnl/ntoskrnl.a ../ndis/ndis.a
$(TARGETNAME).coff: $(TARGETNAME).rc ../../../include/reactos/resource.h
ifeq ($(DOSCLI),yes)
CLEAN_FILES = \
*.o objects\*.o tcpip\*.o datalink\*.o network\*.o \
transport\datagram\*.o transport\rawip\*.o \
transport\tcp\*.o transport\udp\*.o $(TARGETNAME).coff \
$(TARGETNAME).a junk.tmp base.tmp temp.exp \
$(TARGETNAME).sys $(TARGETNAME).sym
else
CLEAN_FILES = \
*.o objects/*.o tcpip/*.o datalink/*.o network/*.o \
transport/datagram/*.o transport/rawip/*.o \
transport/tcp/*.o transport/udp/*.o $(TARGETNAME).coff \
$(TARGETNAME).a junk.tmp base.tmp temp.exp \
$(TARGETNAME).sys $(TARGETNAME).sym
endif
$(TARGETNAME).sys: $(OBJECTS)
$(DLLTOOL) \
--dllname $(TARGETNAME).sys \
--def $(TARGETNAME).def \
--kill-at \
--output-lib $(TARGETNAME).a
$(CC) \
-mdll \
-specs=../../svc_specs \
-Wl,-e,_DriverEntry@8 \
-Wl,--base-file,base.tmp \
-Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ \
-Wl,--defsym,_etext=etext \
$(OBJECTS) \
-o junk.tmp
- $(RM) junk.tmp
$(DLLTOOL) \
--dllname $(TARGETNAME).sys \
--base-file base.tmp \
--output-exp temp.exp \
--def $(TARGETNAME).edf
- $(RM) base.tmp
$(CC) \
-mdll \
-specs=../../svc_specs \
-Wl,--image-base,0x10000 \
-Wl,-e,_DriverEntry@8 \
-Wl,temp.exp \
$(OBJECTS) \
-o $(TARGETNAME).sys
- $(RM) temp.exp
$(NM) --numeric-sort $(TARGETNAME).sys > $(TARGETNAME).sym
clean: $(CLEAN_FILES:%=%_clean)
$(CLEAN_FILES:%=%_clean): %_clean:
- $(RM) $*
.PHONY: clean $(CLEAN_FILES:%=%_clean)
floppy: $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
$(FLOPPY_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)\drivers\$(TARGETNAME).sys
else
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
endif
dist: $(DIST_DIR)/drivers/$(TARGETNAME).sys
$(DIST_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGETNAME).sys ..\..\$(DIST_DIR)\drivers\$(TARGETNAME).sys
else
$(CP) $(TARGETNAME).sys ../../$(DIST_DIR)/drivers/$(TARGETNAME).sys
endif
#WITH_DEBUGGING = yes
#WIN32_LEAN_AND_MEAN = yes
#WARNINGS_ARE_ERRORS = yes
include ../../../rules.mak
+7 -7
View File
@@ -1,7 +1,7 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
+20 -20
View File
@@ -1,20 +1,20 @@
TARGETNAME=network
TARGETPATH=..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\include;$(BASEDIR)\INC;..\..\..\..\include\net
SOURCES= icmp.c \
ip.c \
neighbor.c \
receive.c \
route.c \
router.c \
transmit.c
MSC_WARNING_LEVEL=/W3 /WX
TARGETNAME=network
TARGETPATH=..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\include;$(BASEDIR)\INC;..\..\..\..\include\net
SOURCES= icmp.c \
ip.c \
neighbor.c \
receive.c \
route.c \
router.c \
transmit.c
MSC_WARNING_LEVEL=/W3 /WX
+299 -299
View File
@@ -1,299 +1,299 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: network/icmp.c
* PURPOSE: Internet Control Message Protocol routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <icmp.h>
#include <checksum.h>
#include <routines.h>
#include <transmit.h>
#include <pool.h>
VOID SendICMPComplete(
PVOID Context,
PNDIS_PACKET Packet,
NDIS_STATUS NdisStatus)
/*
* FUNCTION: ICMP datagram transmit completion handler
* ARGUMENTS:
* Context = Pointer to context infomation (IP_PACKET)
* Packet = Pointer to NDIS packet
* NdisStatus = Status of transmit operation
* NOTES:
* This routine is called by IP when a ICMP send completes
*/
{
PIP_PACKET IPPacket = (PIP_PACKET)Context;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(MAX_TRACE, ("Freeing NDIS packet (%X).\n", Packet));
/* Free packet */
FreeNdisPacket(Packet);
TI_DbgPrint(MAX_TRACE, ("Freeing IP packet at %X.\n", IPPacket));
PoolFreeBuffer(IPPacket);
}
PIP_PACKET PrepareICMPPacket(
PNET_TABLE_ENTRY NTE,
PIP_ADDRESS Destination,
UINT DataSize)
/*
* FUNCTION: Prepares an ICMP packet
* ARGUMENTS:
* NTE = Pointer to net table entry to use
* Destination = Pointer to destination address
* DataSize = Size of dataarea
* RETURNS:
* Pointer to IP packet, NULL if there is not enough free resources
*/
{
PIP_PACKET IPPacket;
PNDIS_PACKET NdisPacket;
PNDIS_BUFFER NdisBuffer;
NDIS_STATUS NdisStatus;
PIPv4_HEADER IPHeader;
PVOID DataBuffer;
ULONG Size;
TI_DbgPrint(MAX_TRACE, ("Called. DataSize = %d.\n", DataSize));
/* Prepare ICMP packet */
IPPacket = PoolAllocateBuffer(sizeof(IP_PACKET));
if (!IPPacket)
return NULL;
TI_DbgPrint(MAX_TRACE, ("IPPacket at %X.\n", IPPacket));
Size = MaxLLHeaderSize + sizeof(IPv4_HEADER) +
sizeof(ICMP_HEADER) + DataSize;
DataBuffer = ExAllocatePool(NonPagedPool, Size);
if (!DataBuffer) {
PoolFreeBuffer(IPPacket);
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("Size = %d, Data at %X.\n", Size, DataBuffer));
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PoolFreeBuffer(IPPacket);
ExFreePool(DataBuffer);
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("NdisPacket at %X.\n", NdisPacket));
/* Allocate NDIS buffer for maximum link level header and ICMP packet */
NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
DataBuffer, Size);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PoolFreeBuffer(IPPacket);
NdisFreePacket(NdisPacket);
ExFreePool(DataBuffer);
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("NdisBuffer at %X.\n", NdisBuffer));
/* Link NDIS buffer into packet */
NdisChainBufferAtFront(NdisPacket, NdisBuffer);
IPPacket->NdisPacket = NdisPacket;
IPPacket->Header = (PVOID)((ULONG_PTR)DataBuffer + MaxLLHeaderSize);
IPPacket->Data = (PVOID)((ULONG_PTR)DataBuffer + MaxLLHeaderSize + sizeof(IPv4_HEADER));
IPPacket->HeaderSize = sizeof(IPv4_HEADER);
IPPacket->TotalSize = Size - MaxLLHeaderSize;
RtlCopyMemory(&IPPacket->DstAddr, Destination, sizeof(IP_ADDRESS));
/* Build IPv4 header. FIXME: IPv4 only */
IPHeader = (PIPv4_HEADER)IPPacket->Header;
/* Version = 4, Length = 5 DWORDs */
IPHeader->VerIHL = 0x45;
/* Normal Type-of-Service */
IPHeader->Tos = 0;
/* Length of data and header */
IPHeader->TotalLength = WH2N((USHORT)DataSize +
sizeof(IPv4_HEADER) + sizeof(ICMP_HEADER));
/* Identification */
IPHeader->Id = (USHORT)Random();
/* One fragment at offset 0 */
IPHeader->FlagsFragOfs = 0;
/* Time-to-Live is 128 */
IPHeader->Ttl = 128;
/* Internet Control Message Protocol */
IPHeader->Protocol = IPPROTO_ICMP;
/* Checksum is 0 (for later calculation of this) */
IPHeader->Checksum = 0;
/* Source address */
IPHeader->SrcAddr = NTE->Address->Address.IPv4Address;
/* Destination address */
IPHeader->DstAddr = Destination->Address.IPv4Address;
/* Completion handler */
PC(NdisPacket)->Complete = SendICMPComplete;
PC(NdisPacket)->Context = IPPacket;
return IPPacket;
}
VOID ICMPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
/*
* FUNCTION: Receives an ICMP packet
* ARGUMENTS:
* NTE = Pointer to net table entry which the packet was received on
* IPPacket = Pointer to an IP packet that was received
*/
{
PICMP_HEADER ICMPHeader;
PIP_PACKET NewPacket;
UINT DataSize;
ULONG Checksum;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
ICMPHeader = (PICMP_HEADER)IPPacket->Data;
TI_DbgPrint(MID_TRACE, ("Size = %d.\n", IPPacket->TotalSize));
TI_DbgPrint(MID_TRACE, ("HeaderSize = %d.\n", IPPacket->HeaderSize));
TI_DbgPrint(MID_TRACE, ("Type = %d.\n", ICMPHeader->Type));
TI_DbgPrint(MID_TRACE, ("Code = %d.\n", ICMPHeader->Code));
TI_DbgPrint(MID_TRACE, ("Checksum = %X.\n", ICMPHeader->Checksum));
/* Checksum ICMP header and data and compare */
Checksum = DN2H(IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0));
if (Checksum != 0xFFFF) {
TI_DbgPrint(MIN_TRACE, ("Bad ICMP checksum (0x%X).\n", Checksum));
/* Discard packet */
return;
}
switch (ICMPHeader->Type) {
case ICMP_TYPE_ECHO_REQUEST:
/* Reply with an ICMP echo reply message */
DataSize = IPPacket->TotalSize - IPPacket->HeaderSize - sizeof(ICMP_HEADER);
NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize);
if (!NewPacket)
return;
/* Copy ICMP header and data into new packet */
RtlCopyMemory(NewPacket->Data, IPPacket->Data, DataSize + sizeof(ICMP_HEADER));
((PICMP_HEADER)NewPacket->Data)->Type = ICMP_TYPE_ECHO_REPLY;
((PICMP_HEADER)NewPacket->Data)->Code = 0;
((PICMP_HEADER)NewPacket->Data)->Checksum = 0;
ICMPTransmit(NTE, NewPacket);
TI_DbgPrint(MID_TRACE, ("Echo reply sent.\n"));
return;
default:
TI_DbgPrint(MID_TRACE, ("Discarded ICMP datagram of unknown type.\n"));
/* Discard packet */
break;
}
}
VOID ICMPTransmit(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
/*
* FUNCTION: Transmits an ICMP packet
* ARGUMENTS:
* NTE = Pointer to net table entry to use (NULL if don't care)
* IPPacket = Pointer to IP packet to transmit
*/
{
PROUTE_CACHE_NODE RCN;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* Calculate checksum of ICMP header and data */
((PICMP_HEADER)IPPacket->Data)->Checksum = (USHORT)
IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0);
/* Get a route to the destination address */
if (RouteGetRouteToDestination(&IPPacket->DstAddr, NTE, &RCN) == IP_SUCCESS) {
/* Send the packet */
if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS) {
FreeNdisPacket(IPPacket->NdisPacket);
PoolFreeBuffer(IPPacket);
}
/* We're done with the RCN */
DereferenceObject(RCN);
} else {
TI_DbgPrint(MIN_TRACE, ("RCN at 0x%X.\n", RCN));
/* No route to destination (or no free resources) */
TI_DbgPrint(MIN_TRACE, ("No route to destination address 0x%X.\n",
IPPacket->DstAddr.Address.IPv4Address));
/* Discard packet */
FreeNdisPacket(IPPacket->NdisPacket);
PoolFreeBuffer(IPPacket);
}
}
VOID ICMPReply(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket,
UCHAR Type,
UCHAR Code)
/*
* FUNCTION: Transmits an ICMP packet in response to an incoming packet
* ARGUMENTS:
* NTE = Pointer to net table entry to use
* IPPacket = Pointer to IP packet that was received
* Type = ICMP message type
* Code = ICMP message code
* NOTES:
* We have received a packet from someone and is unable to
* process it due to error(s) in the packet or we have run out
* of resources. We transmit an ICMP message to the host to
* notify him of the problem
*/
{
UINT DataSize;
PIP_PACKET NewPacket;
TI_DbgPrint(MID_TRACE, ("Called (Type=%d, Code=%d).\n", Type, Code));
DataSize = IPPacket->TotalSize;
if ((DataSize) > (576 - sizeof(IPv4_HEADER) - sizeof(ICMP_HEADER)))
DataSize = 576;
NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize);
if (!NewPacket)
return;
RtlCopyMemory((PVOID)((ULONG_PTR)NewPacket->Data + sizeof(ICMP_HEADER)),
IPPacket->Header, DataSize);
((PICMP_HEADER)NewPacket->Data)->Type = Type;
((PICMP_HEADER)NewPacket->Data)->Code = Code;
((PICMP_HEADER)NewPacket->Data)->Checksum = 0;
ICMPTransmit(NTE, NewPacket);
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: network/icmp.c
* PURPOSE: Internet Control Message Protocol routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <icmp.h>
#include <checksum.h>
#include <routines.h>
#include <transmit.h>
#include <pool.h>
VOID SendICMPComplete(
PVOID Context,
PNDIS_PACKET Packet,
NDIS_STATUS NdisStatus)
/*
* FUNCTION: ICMP datagram transmit completion handler
* ARGUMENTS:
* Context = Pointer to context infomation (IP_PACKET)
* Packet = Pointer to NDIS packet
* NdisStatus = Status of transmit operation
* NOTES:
* This routine is called by IP when a ICMP send completes
*/
{
PIP_PACKET IPPacket = (PIP_PACKET)Context;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(MAX_TRACE, ("Freeing NDIS packet (%X).\n", Packet));
/* Free packet */
FreeNdisPacket(Packet);
TI_DbgPrint(MAX_TRACE, ("Freeing IP packet at %X.\n", IPPacket));
PoolFreeBuffer(IPPacket);
}
PIP_PACKET PrepareICMPPacket(
PNET_TABLE_ENTRY NTE,
PIP_ADDRESS Destination,
UINT DataSize)
/*
* FUNCTION: Prepares an ICMP packet
* ARGUMENTS:
* NTE = Pointer to net table entry to use
* Destination = Pointer to destination address
* DataSize = Size of dataarea
* RETURNS:
* Pointer to IP packet, NULL if there is not enough free resources
*/
{
PIP_PACKET IPPacket;
PNDIS_PACKET NdisPacket;
PNDIS_BUFFER NdisBuffer;
NDIS_STATUS NdisStatus;
PIPv4_HEADER IPHeader;
PVOID DataBuffer;
ULONG Size;
TI_DbgPrint(MAX_TRACE, ("Called. DataSize = %d.\n", DataSize));
/* Prepare ICMP packet */
IPPacket = PoolAllocateBuffer(sizeof(IP_PACKET));
if (!IPPacket)
return NULL;
TI_DbgPrint(MAX_TRACE, ("IPPacket at %X.\n", IPPacket));
Size = MaxLLHeaderSize + sizeof(IPv4_HEADER) +
sizeof(ICMP_HEADER) + DataSize;
DataBuffer = ExAllocatePool(NonPagedPool, Size);
if (!DataBuffer) {
PoolFreeBuffer(IPPacket);
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("Size = %d, Data at %X.\n", Size, DataBuffer));
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PoolFreeBuffer(IPPacket);
ExFreePool(DataBuffer);
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("NdisPacket at %X.\n", NdisPacket));
/* Allocate NDIS buffer for maximum link level header and ICMP packet */
NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
DataBuffer, Size);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PoolFreeBuffer(IPPacket);
NdisFreePacket(NdisPacket);
ExFreePool(DataBuffer);
return NULL;
}
TI_DbgPrint(MAX_TRACE, ("NdisBuffer at %X.\n", NdisBuffer));
/* Link NDIS buffer into packet */
NdisChainBufferAtFront(NdisPacket, NdisBuffer);
IPPacket->NdisPacket = NdisPacket;
IPPacket->Header = (PVOID)((ULONG_PTR)DataBuffer + MaxLLHeaderSize);
IPPacket->Data = (PVOID)((ULONG_PTR)DataBuffer + MaxLLHeaderSize + sizeof(IPv4_HEADER));
IPPacket->HeaderSize = sizeof(IPv4_HEADER);
IPPacket->TotalSize = Size - MaxLLHeaderSize;
RtlCopyMemory(&IPPacket->DstAddr, Destination, sizeof(IP_ADDRESS));
/* Build IPv4 header. FIXME: IPv4 only */
IPHeader = (PIPv4_HEADER)IPPacket->Header;
/* Version = 4, Length = 5 DWORDs */
IPHeader->VerIHL = 0x45;
/* Normal Type-of-Service */
IPHeader->Tos = 0;
/* Length of data and header */
IPHeader->TotalLength = WH2N((USHORT)DataSize +
sizeof(IPv4_HEADER) + sizeof(ICMP_HEADER));
/* Identification */
IPHeader->Id = (USHORT)Random();
/* One fragment at offset 0 */
IPHeader->FlagsFragOfs = 0;
/* Time-to-Live is 128 */
IPHeader->Ttl = 128;
/* Internet Control Message Protocol */
IPHeader->Protocol = IPPROTO_ICMP;
/* Checksum is 0 (for later calculation of this) */
IPHeader->Checksum = 0;
/* Source address */
IPHeader->SrcAddr = NTE->Address->Address.IPv4Address;
/* Destination address */
IPHeader->DstAddr = Destination->Address.IPv4Address;
/* Completion handler */
PC(NdisPacket)->Complete = SendICMPComplete;
PC(NdisPacket)->Context = IPPacket;
return IPPacket;
}
VOID ICMPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
/*
* FUNCTION: Receives an ICMP packet
* ARGUMENTS:
* NTE = Pointer to net table entry which the packet was received on
* IPPacket = Pointer to an IP packet that was received
*/
{
PICMP_HEADER ICMPHeader;
PIP_PACKET NewPacket;
UINT DataSize;
ULONG Checksum;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
ICMPHeader = (PICMP_HEADER)IPPacket->Data;
TI_DbgPrint(MID_TRACE, ("Size = %d.\n", IPPacket->TotalSize));
TI_DbgPrint(MID_TRACE, ("HeaderSize = %d.\n", IPPacket->HeaderSize));
TI_DbgPrint(MID_TRACE, ("Type = %d.\n", ICMPHeader->Type));
TI_DbgPrint(MID_TRACE, ("Code = %d.\n", ICMPHeader->Code));
TI_DbgPrint(MID_TRACE, ("Checksum = %X.\n", ICMPHeader->Checksum));
/* Checksum ICMP header and data and compare */
Checksum = DN2H(IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0));
if (Checksum != 0xFFFF) {
TI_DbgPrint(MIN_TRACE, ("Bad ICMP checksum (0x%X).\n", Checksum));
/* Discard packet */
return;
}
switch (ICMPHeader->Type) {
case ICMP_TYPE_ECHO_REQUEST:
/* Reply with an ICMP echo reply message */
DataSize = IPPacket->TotalSize - IPPacket->HeaderSize - sizeof(ICMP_HEADER);
NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize);
if (!NewPacket)
return;
/* Copy ICMP header and data into new packet */
RtlCopyMemory(NewPacket->Data, IPPacket->Data, DataSize + sizeof(ICMP_HEADER));
((PICMP_HEADER)NewPacket->Data)->Type = ICMP_TYPE_ECHO_REPLY;
((PICMP_HEADER)NewPacket->Data)->Code = 0;
((PICMP_HEADER)NewPacket->Data)->Checksum = 0;
ICMPTransmit(NTE, NewPacket);
TI_DbgPrint(MID_TRACE, ("Echo reply sent.\n"));
return;
default:
TI_DbgPrint(MID_TRACE, ("Discarded ICMP datagram of unknown type.\n"));
/* Discard packet */
break;
}
}
VOID ICMPTransmit(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
/*
* FUNCTION: Transmits an ICMP packet
* ARGUMENTS:
* NTE = Pointer to net table entry to use (NULL if don't care)
* IPPacket = Pointer to IP packet to transmit
*/
{
PROUTE_CACHE_NODE RCN;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* Calculate checksum of ICMP header and data */
((PICMP_HEADER)IPPacket->Data)->Checksum = (USHORT)
IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0);
/* Get a route to the destination address */
if (RouteGetRouteToDestination(&IPPacket->DstAddr, NTE, &RCN) == IP_SUCCESS) {
/* Send the packet */
if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS) {
FreeNdisPacket(IPPacket->NdisPacket);
PoolFreeBuffer(IPPacket);
}
/* We're done with the RCN */
DereferenceObject(RCN);
} else {
TI_DbgPrint(MIN_TRACE, ("RCN at 0x%X.\n", RCN));
/* No route to destination (or no free resources) */
TI_DbgPrint(MIN_TRACE, ("No route to destination address 0x%X.\n",
IPPacket->DstAddr.Address.IPv4Address));
/* Discard packet */
FreeNdisPacket(IPPacket->NdisPacket);
PoolFreeBuffer(IPPacket);
}
}
VOID ICMPReply(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket,
UCHAR Type,
UCHAR Code)
/*
* FUNCTION: Transmits an ICMP packet in response to an incoming packet
* ARGUMENTS:
* NTE = Pointer to net table entry to use
* IPPacket = Pointer to IP packet that was received
* Type = ICMP message type
* Code = ICMP message code
* NOTES:
* We have received a packet from someone and is unable to
* process it due to error(s) in the packet or we have run out
* of resources. We transmit an ICMP message to the host to
* notify him of the problem
*/
{
UINT DataSize;
PIP_PACKET NewPacket;
TI_DbgPrint(MID_TRACE, ("Called (Type=%d, Code=%d).\n", Type, Code));
DataSize = IPPacket->TotalSize;
if ((DataSize) > (576 - sizeof(IPv4_HEADER) - sizeof(ICMP_HEADER)))
DataSize = 576;
NewPacket = PrepareICMPPacket(NTE, &IPPacket->SrcAddr, DataSize);
if (!NewPacket)
return;
RtlCopyMemory((PVOID)((ULONG_PTR)NewPacket->Data + sizeof(ICMP_HEADER)),
IPPacket->Header, DataSize);
((PICMP_HEADER)NewPacket->Data)->Type = Type;
((PICMP_HEADER)NewPacket->Data)->Code = Code;
((PICMP_HEADER)NewPacket->Data)->Checksum = 0;
ICMPTransmit(NTE, NewPacket);
}
/* EOF */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+328 -328
View File
@@ -1,328 +1,328 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: network/transmit.c
* PURPOSE: Internet Protocol transmit routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <transmit.h>
#include <routines.h>
#include <checksum.h>
#include <pool.h>
#include <arp.h>
#include <lan.h>
BOOLEAN PrepareNextFragment(
PIPFRAGMENT_CONTEXT IFC)
/*
* FUNCTION: Prepares the next fragment of an IP datagram for transmission
* ARGUMENTS:
* IFC = Pointer to IP fragment context
* RETURNS:
* TRUE if a fragment was prepared for transmission, FALSE if
* there are no more fragments to send
*/
{
UINT MaxData;
UINT DataSize;
PIPv4_HEADER Header;
BOOLEAN MoreFragments;
USHORT FragOfs;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
if (IFC->BytesLeft != 0) {
TI_DbgPrint(MAX_TRACE, ("Preparing 1 fragment.\n"));
MaxData = IFC->PathMTU - IFC->HeaderSize;
/* Make fragment a multiplum of 64bit */
MaxData -= MaxData % 8;
if (IFC->BytesLeft > MaxData) {
DataSize = MaxData;
MoreFragments = TRUE;
} else {
DataSize = IFC->BytesLeft;
MoreFragments = FALSE;
}
RtlCopyMemory(IFC->Data, IFC->DatagramData, DataSize);
FragOfs = (USHORT)IFC->Position; // Swap?
if (MoreFragments)
FragOfs |= IPv4_MF_MASK;
else
FragOfs &= ~IPv4_MF_MASK;
Header = IFC->Header;
Header->FlagsFragOfs = FragOfs;
/* FIXME: Handle options */
/* Calculate checksum of IP header */
Header->Checksum = 0;
Header->Checksum = (USHORT)IPv4Checksum(Header, IFC->HeaderSize, 0);
/* Update pointers */
(ULONG_PTR)IFC->DatagramData += DataSize;
IFC->Position += DataSize;
IFC->BytesLeft -= DataSize;
return TRUE;
} else {
TI_DbgPrint(MAX_TRACE, ("No more fragments.\n"));
return FALSE;
}
}
NTSTATUS SendFragments(
PIP_PACKET IPPacket,
PNEIGHBOR_CACHE_ENTRY NCE,
UINT PathMTU)
/*
* FUNCTION: Fragments and sends the first fragment of an IP datagram
* ARGUMENTS:
* IPPacket = Pointer to an IP packet
* NCE = Pointer to NCE for first hop to destination
* PathMTU = Size of Maximum Transmission Unit of path
* RETURNS:
* Status of operation
* NOTES:
* IP datagram is larger than PathMTU when this is called
*/
{
PIPFRAGMENT_CONTEXT IFC;
NDIS_STATUS NdisStatus;
PVOID Data;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
IFC = PoolAllocateBuffer(sizeof(IPFRAGMENT_CONTEXT));
if (!IFC)
return STATUS_INSUFFICIENT_RESOURCES;
/* We allocate a buffer for a PathMTU sized packet and reuse
it for all fragments */
Data = ExAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
if (!IFC->Header) {
PoolFreeBuffer(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &IFC->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
ExFreePool(Data);
PoolFreeBuffer(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate NDIS buffer */
NdisAllocateBuffer(&NdisStatus, &IFC->NdisBuffer,
GlobalBufferPool, Data, MaxLLHeaderSize + PathMTU);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
NdisFreePacket(IFC->NdisPacket);
ExFreePool(Data);
PoolFreeBuffer(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Link NDIS buffer into packet */
NdisChainBufferAtFront(IFC->NdisPacket, IFC->NdisBuffer);
IFC->Header = (PVOID)((ULONG_PTR)Data + MaxLLHeaderSize);
IFC->Datagram = IPPacket->NdisPacket;
IFC->DatagramData = IPPacket->Header;
IFC->HeaderSize = IPPacket->HeaderSize;
IFC->PathMTU = PathMTU;
IFC->NCE = NCE;
IFC->Position = 0;
IFC->BytesLeft = IPPacket->TotalSize - IPPacket->HeaderSize;
IFC->Data = (PVOID)((ULONG_PTR)IFC->Header + IPPacket->HeaderSize);
PC(IFC->NdisPacket)->DLComplete = IPSendComplete;
/* Set upper layer completion function to NULL to indicate that
this packet is an IP datagram fragment and thus we should
check for more fragments to send. If this is NULL the
Context field is a pointer to an IPFRAGMENT_CONTEXT structure */
PC(IFC->NdisPacket)->Complete = NULL;
PC(IFC->NdisPacket)->Context = IFC;
/* Copy IP datagram header to fragment buffer */
RtlCopyMemory(IFC->Header, IPPacket->Header, IPPacket->HeaderSize);
/* Prepare next fragment for transmission and send it */
PrepareNextFragment(IFC);
IPSendFragment(IFC->NdisPacket, NCE);
return STATUS_SUCCESS;
}
VOID IPSendComplete(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus)
/*
* FUNCTION: IP datagram fragment send completion handler
* ARGUMENTS:
* Context = Pointer to context information (IP_INTERFACE)
* Packet = Pointer to NDIS packet that was sent
* NdisStatus = NDIS status of operation
* NOTES:
* This routine is called when an IP datagram fragment has been sent
*/
{
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
/* FIXME: Stop sending fragments and cleanup datagram buffers if
there was an error */
if (PC(NdisPacket)->Complete)
/* This datagram was only one fragment long so call completion handler now */
(*PC(NdisPacket)->Complete)(PC(NdisPacket)->Context, NdisPacket, NdisStatus);
else {
/* This was one of many fragments of an IP datagram. Prepare
next fragment and send it or if there are no more fragments,
call upper layer completion routine */
PIPFRAGMENT_CONTEXT IFC = (PIPFRAGMENT_CONTEXT)PC(NdisPacket)->Context;
if (PrepareNextFragment(IFC)) {
/* A fragment was prepared for transmission, so send it */
IPSendFragment(IFC->NdisPacket, IFC->NCE);
} else {
TI_DbgPrint(MAX_TRACE, ("Calling completion handler.\n"));
/* There are no more fragments to transmit, so call completion handler */
NdisPacket = IFC->Datagram;
FreeNdisPacket(IFC->NdisPacket);
PoolFreeBuffer(IFC);
(*PC(NdisPacket)->Complete)(PC(NdisPacket)->Context, NdisPacket, NdisStatus);
}
}
}
NTSTATUS IPSendFragment(
PNDIS_PACKET NdisPacket,
PNEIGHBOR_CACHE_ENTRY NCE)
/*
* FUNCTION: Sends an IP datagram fragment to a neighbor
* ARGUMENTS:
* NdisPacket = Pointer to an NDIS packet containing fragment
* NCE = Pointer to NCE for first hop to destination
* RETURNS:
* Status of operation
* NOTES:
* Lowest level IP send routine
*/
{
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(MAX_TRACE, ("NCE->State = %d.\n", NCE->State));
switch (NCE->State) {
case NUD_PERMANENT:
/* Neighbor is always valid */
break;
case NUD_REACHABLE:
/* Neighbor is reachable */
/* FIXME: Set reachable timer */
break;
case NUD_STALE:
/* Enter delay state and send packet */
/* FIXME: Enter delay state */
break;
case NUD_DELAY:
case NUD_PROBE:
/* In these states we send the packet and hope the neighbor
hasn't changed hardware address */
break;
case NUD_INCOMPLETE:
TI_DbgPrint(MAX_TRACE, ("Queueing packet.\n"));
/* We don't know the hardware address of the first hop to
the destination. Queue the packet on the NCE and return */
NBQueuePacket(NCE, NdisPacket);
return STATUS_SUCCESS;
default:
/* Should not happen */
TI_DbgPrint(MIN_TRACE, ("Unknown NCE state.\n"));
return STATUS_SUCCESS;
}
PC(NdisPacket)->DLComplete = IPSendComplete;
(*NCE->Interface->Transmit)(NCE->Interface->Context, NdisPacket,
MaxLLHeaderSize, NCE->LinkAddress, LAN_PROTO_IPv4);
return STATUS_SUCCESS;
}
NTSTATUS IPSendDatagram(
PIP_PACKET IPPacket,
PROUTE_CACHE_NODE RCN)
/*
* FUNCTION: Sends an IP datagram to a remote address
* ARGUMENTS:
* IPPacket = Pointer to an IP packet
* RCN = Pointer to route cache node
* RETURNS:
* Status of operation
* NOTES:
* This is the highest level IP send routine. It possibly breaks the packet
* into two or more fragments before passing it on to the next lower level
* send routine (IPSendFragment)
*/
{
PNEIGHBOR_CACHE_ENTRY NCE;
UINT PathMTU;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
NCE = RCN->NCE;
#if DBG
if (!NCE) {
TI_DbgPrint(MIN_TRACE, ("No NCE to use.\n"));
FreeNdisPacket(IPPacket->NdisPacket);
return STATUS_SUCCESS;
}
#endif
/* Fetch path MTU now, because it may change */
PathMTU = RCN->PathMTU;
if (IPPacket->TotalSize > PathMTU) {
return SendFragments(IPPacket, NCE, PathMTU);
} else {
/* Calculate checksum of IP header */
((PIPv4_HEADER)IPPacket->Header)->Checksum = 0;
((PIPv4_HEADER)IPPacket->Header)->Checksum = (USHORT)
IPv4Checksum(IPPacket->Header, IPPacket->HeaderSize, 0);
TI_DbgPrint(MAX_TRACE, ("Sending packet (length is %d).\n", WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength)));
return IPSendFragment(IPPacket->NdisPacket, NCE);
}
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: network/transmit.c
* PURPOSE: Internet Protocol transmit routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <transmit.h>
#include <routines.h>
#include <checksum.h>
#include <pool.h>
#include <arp.h>
#include <lan.h>
BOOLEAN PrepareNextFragment(
PIPFRAGMENT_CONTEXT IFC)
/*
* FUNCTION: Prepares the next fragment of an IP datagram for transmission
* ARGUMENTS:
* IFC = Pointer to IP fragment context
* RETURNS:
* TRUE if a fragment was prepared for transmission, FALSE if
* there are no more fragments to send
*/
{
UINT MaxData;
UINT DataSize;
PIPv4_HEADER Header;
BOOLEAN MoreFragments;
USHORT FragOfs;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
if (IFC->BytesLeft != 0) {
TI_DbgPrint(MAX_TRACE, ("Preparing 1 fragment.\n"));
MaxData = IFC->PathMTU - IFC->HeaderSize;
/* Make fragment a multiplum of 64bit */
MaxData -= MaxData % 8;
if (IFC->BytesLeft > MaxData) {
DataSize = MaxData;
MoreFragments = TRUE;
} else {
DataSize = IFC->BytesLeft;
MoreFragments = FALSE;
}
RtlCopyMemory(IFC->Data, IFC->DatagramData, DataSize);
FragOfs = (USHORT)IFC->Position; // Swap?
if (MoreFragments)
FragOfs |= IPv4_MF_MASK;
else
FragOfs &= ~IPv4_MF_MASK;
Header = IFC->Header;
Header->FlagsFragOfs = FragOfs;
/* FIXME: Handle options */
/* Calculate checksum of IP header */
Header->Checksum = 0;
Header->Checksum = (USHORT)IPv4Checksum(Header, IFC->HeaderSize, 0);
/* Update pointers */
(ULONG_PTR)IFC->DatagramData += DataSize;
IFC->Position += DataSize;
IFC->BytesLeft -= DataSize;
return TRUE;
} else {
TI_DbgPrint(MAX_TRACE, ("No more fragments.\n"));
return FALSE;
}
}
NTSTATUS SendFragments(
PIP_PACKET IPPacket,
PNEIGHBOR_CACHE_ENTRY NCE,
UINT PathMTU)
/*
* FUNCTION: Fragments and sends the first fragment of an IP datagram
* ARGUMENTS:
* IPPacket = Pointer to an IP packet
* NCE = Pointer to NCE for first hop to destination
* PathMTU = Size of Maximum Transmission Unit of path
* RETURNS:
* Status of operation
* NOTES:
* IP datagram is larger than PathMTU when this is called
*/
{
PIPFRAGMENT_CONTEXT IFC;
NDIS_STATUS NdisStatus;
PVOID Data;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
IFC = PoolAllocateBuffer(sizeof(IPFRAGMENT_CONTEXT));
if (!IFC)
return STATUS_INSUFFICIENT_RESOURCES;
/* We allocate a buffer for a PathMTU sized packet and reuse
it for all fragments */
Data = ExAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
if (!IFC->Header) {
PoolFreeBuffer(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &IFC->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
ExFreePool(Data);
PoolFreeBuffer(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate NDIS buffer */
NdisAllocateBuffer(&NdisStatus, &IFC->NdisBuffer,
GlobalBufferPool, Data, MaxLLHeaderSize + PathMTU);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
NdisFreePacket(IFC->NdisPacket);
ExFreePool(Data);
PoolFreeBuffer(IFC);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Link NDIS buffer into packet */
NdisChainBufferAtFront(IFC->NdisPacket, IFC->NdisBuffer);
IFC->Header = (PVOID)((ULONG_PTR)Data + MaxLLHeaderSize);
IFC->Datagram = IPPacket->NdisPacket;
IFC->DatagramData = IPPacket->Header;
IFC->HeaderSize = IPPacket->HeaderSize;
IFC->PathMTU = PathMTU;
IFC->NCE = NCE;
IFC->Position = 0;
IFC->BytesLeft = IPPacket->TotalSize - IPPacket->HeaderSize;
IFC->Data = (PVOID)((ULONG_PTR)IFC->Header + IPPacket->HeaderSize);
PC(IFC->NdisPacket)->DLComplete = IPSendComplete;
/* Set upper layer completion function to NULL to indicate that
this packet is an IP datagram fragment and thus we should
check for more fragments to send. If this is NULL the
Context field is a pointer to an IPFRAGMENT_CONTEXT structure */
PC(IFC->NdisPacket)->Complete = NULL;
PC(IFC->NdisPacket)->Context = IFC;
/* Copy IP datagram header to fragment buffer */
RtlCopyMemory(IFC->Header, IPPacket->Header, IPPacket->HeaderSize);
/* Prepare next fragment for transmission and send it */
PrepareNextFragment(IFC);
IPSendFragment(IFC->NdisPacket, NCE);
return STATUS_SUCCESS;
}
VOID IPSendComplete(
PVOID Context,
PNDIS_PACKET NdisPacket,
NDIS_STATUS NdisStatus)
/*
* FUNCTION: IP datagram fragment send completion handler
* ARGUMENTS:
* Context = Pointer to context information (IP_INTERFACE)
* Packet = Pointer to NDIS packet that was sent
* NdisStatus = NDIS status of operation
* NOTES:
* This routine is called when an IP datagram fragment has been sent
*/
{
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
/* FIXME: Stop sending fragments and cleanup datagram buffers if
there was an error */
if (PC(NdisPacket)->Complete)
/* This datagram was only one fragment long so call completion handler now */
(*PC(NdisPacket)->Complete)(PC(NdisPacket)->Context, NdisPacket, NdisStatus);
else {
/* This was one of many fragments of an IP datagram. Prepare
next fragment and send it or if there are no more fragments,
call upper layer completion routine */
PIPFRAGMENT_CONTEXT IFC = (PIPFRAGMENT_CONTEXT)PC(NdisPacket)->Context;
if (PrepareNextFragment(IFC)) {
/* A fragment was prepared for transmission, so send it */
IPSendFragment(IFC->NdisPacket, IFC->NCE);
} else {
TI_DbgPrint(MAX_TRACE, ("Calling completion handler.\n"));
/* There are no more fragments to transmit, so call completion handler */
NdisPacket = IFC->Datagram;
FreeNdisPacket(IFC->NdisPacket);
PoolFreeBuffer(IFC);
(*PC(NdisPacket)->Complete)(PC(NdisPacket)->Context, NdisPacket, NdisStatus);
}
}
}
NTSTATUS IPSendFragment(
PNDIS_PACKET NdisPacket,
PNEIGHBOR_CACHE_ENTRY NCE)
/*
* FUNCTION: Sends an IP datagram fragment to a neighbor
* ARGUMENTS:
* NdisPacket = Pointer to an NDIS packet containing fragment
* NCE = Pointer to NCE for first hop to destination
* RETURNS:
* Status of operation
* NOTES:
* Lowest level IP send routine
*/
{
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
TI_DbgPrint(MAX_TRACE, ("NCE->State = %d.\n", NCE->State));
switch (NCE->State) {
case NUD_PERMANENT:
/* Neighbor is always valid */
break;
case NUD_REACHABLE:
/* Neighbor is reachable */
/* FIXME: Set reachable timer */
break;
case NUD_STALE:
/* Enter delay state and send packet */
/* FIXME: Enter delay state */
break;
case NUD_DELAY:
case NUD_PROBE:
/* In these states we send the packet and hope the neighbor
hasn't changed hardware address */
break;
case NUD_INCOMPLETE:
TI_DbgPrint(MAX_TRACE, ("Queueing packet.\n"));
/* We don't know the hardware address of the first hop to
the destination. Queue the packet on the NCE and return */
NBQueuePacket(NCE, NdisPacket);
return STATUS_SUCCESS;
default:
/* Should not happen */
TI_DbgPrint(MIN_TRACE, ("Unknown NCE state.\n"));
return STATUS_SUCCESS;
}
PC(NdisPacket)->DLComplete = IPSendComplete;
(*NCE->Interface->Transmit)(NCE->Interface->Context, NdisPacket,
MaxLLHeaderSize, NCE->LinkAddress, LAN_PROTO_IPv4);
return STATUS_SUCCESS;
}
NTSTATUS IPSendDatagram(
PIP_PACKET IPPacket,
PROUTE_CACHE_NODE RCN)
/*
* FUNCTION: Sends an IP datagram to a remote address
* ARGUMENTS:
* IPPacket = Pointer to an IP packet
* RCN = Pointer to route cache node
* RETURNS:
* Status of operation
* NOTES:
* This is the highest level IP send routine. It possibly breaks the packet
* into two or more fragments before passing it on to the next lower level
* send routine (IPSendFragment)
*/
{
PNEIGHBOR_CACHE_ENTRY NCE;
UINT PathMTU;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
NCE = RCN->NCE;
#if DBG
if (!NCE) {
TI_DbgPrint(MIN_TRACE, ("No NCE to use.\n"));
FreeNdisPacket(IPPacket->NdisPacket);
return STATUS_SUCCESS;
}
#endif
/* Fetch path MTU now, because it may change */
PathMTU = RCN->PathMTU;
if (IPPacket->TotalSize > PathMTU) {
return SendFragments(IPPacket, NCE, PathMTU);
} else {
/* Calculate checksum of IP header */
((PIPv4_HEADER)IPPacket->Header)->Checksum = 0;
((PIPv4_HEADER)IPPacket->Header)->Checksum = (USHORT)
IPv4Checksum(IPPacket->Header, IPPacket->HeaderSize, 0);
TI_DbgPrint(MAX_TRACE, ("Sending packet (length is %d).\n", WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength)));
return IPSendFragment(IPPacket->NdisPacket, NCE);
}
}
/* EOF */
+19 -19
View File
@@ -1,19 +1,19 @@
Build instructions for TCP/IP protocol driver
---------------------------------------------
Building with Visual C++ and Windows NT DDK:
Variables:
%BASEDIR% = path to NT4 DDK (e.g. c:\ntddk)
%DDKBUILDENV% = DDK build environment (free or checked)
DDK environment variables must be set! (run setenv.bat)
- Create the directory objects/i386/%DDKBUILDENV%
- Run "build" to build the driver
Building with Mingw32 and ReactOS include files:
- Build NDIS.SYS (i.e. "make ndis")
- Run "make tcpip" FROM THE ReactOS ROOT DIRECTORY to build the driver
Build instructions for TCP/IP protocol driver
---------------------------------------------
Building with Visual C++ and Windows NT DDK:
Variables:
%BASEDIR% = path to NT4 DDK (e.g. c:\ntddk)
%DDKBUILDENV% = DDK build environment (free or checked)
DDK environment variables must be set! (run setenv.bat)
- Create the directory objects/i386/%DDKBUILDENV%
- Run "build" to build the driver
Building with Mingw32 and ReactOS include files:
- Build NDIS.SYS (i.e. "make ndis")
- Run "make tcpip" FROM THE ReactOS ROOT DIRECTORY to build the driver
+32 -32
View File
@@ -1,32 +1,32 @@
; TCPIP.SYS - TCP/IP protocol driver
LIBRARY tcpip.sys
EXPORTS
;FreeIprBuff
;GetIFAndLink
IPAddInterface@20
;IPAllocBuff
IPDelInterface@4
;IPDelayedNdisReEnumerateBindings
;IPDeregisterARP
;IPDisableSniffer
;IPEnableSniffer
;IPFreeBuff
;IPGetAddrType
;IPGetBestInterface
;IPGetInfo
;IPInjectPkt
;IPProxyNdisRequest
;IPRegisterARP
;IPRegisterProtocol
;IPSetIPSecStatus
;IPTransmit
LookupRoute@8
;LookupRouteInformation
;SendICMPErr
;SetIPSecPtr
;UnSetIPSecPtr
;UnSetIPSecSendPtr
; EOF
; TCPIP.SYS - TCP/IP protocol driver
LIBRARY tcpip.sys
EXPORTS
;FreeIprBuff
;GetIFAndLink
IPAddInterface@20
;IPAllocBuff
IPDelInterface@4
;IPDelayedNdisReEnumerateBindings
;IPDeregisterARP
;IPDisableSniffer
;IPEnableSniffer
;IPFreeBuff
;IPGetAddrType
;IPGetBestInterface
;IPGetInfo
;IPInjectPkt
;IPProxyNdisRequest
;IPRegisterARP
;IPRegisterProtocol
;IPSetIPSecStatus
;IPTransmit
LookupRoute@8
;LookupRouteInformation
;SendICMPErr
;SetIPSecPtr
;UnSetIPSecPtr
;UnSetIPSecSendPtr
; EOF
+32 -32
View File
@@ -1,32 +1,32 @@
; TCPIP.SYS - TCP/IP protocol driver
LIBRARY tcpip.sys
EXPORTS
;FreeIprBuff
;GetIFAndLink
IPAddInterface=IPAddInterface@20
;IPAllocBuff
IPDelInterface=IPDelInterface@4
;IPDelayedNdisReEnumerateBindings
;IPDeregisterARP
;IPDisableSniffer
;IPEnableSniffer
;IPFreeBuff
;IPGetAddrType
;IPGetBestInterface
;IPGetInfo
;IPInjectPkt
;IPProxyNdisRequest
;IPRegisterARP
;IPRegisterProtocol
;IPSetIPSecStatus
;IPTransmit
LookupRoute=LookupRoute@8
;LookupRouteInformation
;SendICMPErr
;SetIPSecPtr
;UnSetIPSecPtr
;UnSetIPSecSendPtr
; EOF
; TCPIP.SYS - TCP/IP protocol driver
LIBRARY tcpip.sys
EXPORTS
;FreeIprBuff
;GetIFAndLink
IPAddInterface=IPAddInterface@20
;IPAllocBuff
IPDelInterface=IPDelInterface@4
;IPDelayedNdisReEnumerateBindings
;IPDeregisterARP
;IPDisableSniffer
;IPEnableSniffer
;IPFreeBuff
;IPGetAddrType
;IPGetBestInterface
;IPGetInfo
;IPInjectPkt
;IPProxyNdisRequest
;IPRegisterARP
;IPRegisterProtocol
;IPSetIPSecStatus
;IPTransmit
LookupRoute=LookupRoute@8
;LookupRouteInformation
;SendICMPErr
;SetIPSecPtr
;UnSetIPSecPtr
;UnSetIPSecSendPtr
; EOF
+38 -38
View File
@@ -1,38 +1,38 @@
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "TCP/IP protocol driver\0"
VALUE "FileVersion", "0.0.0\0"
VALUE "InternalName", "tcpip\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "tcpip.sys\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "TCP/IP protocol driver\0"
VALUE "FileVersion", "0.0.0\0"
VALUE "InternalName", "tcpip\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "tcpip.sys\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
+335 -335
View File
@@ -1,335 +1,335 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/info.c
* PURPOSE: TDI query and set information routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/07-2000 Created
*/
#include <tcpip.h>
#include <routines.h>
#include <info.h>
TDI_STATUS IPTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context)
/*
* FUNCTION: Returns extended information about network layer
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = TDI object ID
* Buffer = Pointer to buffer with data to use.
* BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
* Context = Pointer to context buffer
* RETURNS:
* Status of operation
*/
{
IPADDR_ENTRY IpAddress;
IPSNMP_INFO SnmpInfo;
PADDRESS_ENTRY ADE;
PIP_INTERFACE IF;
ULONG Temp;
UINT Count;
ULONG Entity;
KIRQL OldIrql;
UINT BufSize = *BufferSize;
/* Make return parameters consistent every time */
*BufferSize = 0;
Entity = ID->toi_entity.tei_entity;
if (Entity != CL_NL_ENTITY) {
/* We can't handle this entity */
return TDI_INVALID_PARAMETER;
}
if (ID->toi_entity.tei_instance != TL_INSTANCE)
/* We only support a single instance */
return TDI_INVALID_REQUEST;
if (ID->toi_class == INFO_CLASS_GENERIC) {
if (ID->toi_type == INFO_TYPE_PROVIDER &&
ID->toi_id == ENTITY_TYPE_ID) {
if (BufSize < sizeof(ULONG))
return TDI_BUFFER_TOO_SMALL;
Temp = CL_NL_IP;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
return TDI_INVALID_PARAMETER;
}
if (ID->toi_class == INFO_CLASS_PROTOCOL) {
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
switch (ID->toi_id) {
case IP_MIB_ADDRTABLE_ENTRY_ID:
Temp = 0;
KeAcquireSpinLock(&InterfaceLock, &OldIrql);
/*
/* Search the interface list */
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
if (CurrentIF != Loopback) {
/* Search the address entry list and return the first appropriate ADE found */
CurrentADEEntry = CurrentIF->ADEListHead.Flink;
while (CurrentADEEntry != &CurrentIF->ADEListHead) {
CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
if (CurrentADE->Type == AddressType)
ReferenceAddress(CurrentADE->Address);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentADE;
}
CurrentADEEntry = CurrentADEEntry->Flink;
} else
LoopbackIsRegistered = TRUE;
CurrentIFEntry = CurrentIFEntry->Flink;
}
*/
for (IF = InterfaceList; IF != NULL; IF = IF->Next) {
if (Temp + sizeof(IPADDR_ENTRY) > BufSize) {
KeReleaseSpinLock(&InterfaceLock, OldIrql);
return TDI_BUFFER_TOO_SMALL;
}
IpAddress.Addr = 0;
IpAddress.BcastAddr = 0;
IpAddress.Mask = 0;
/* Locate the diffrent addresses and put them the right place */
for (ADE = IF->ADE; ADE != NULL; ADE = ADE->Next) {
switch (ADE->Type) {
case ADE_UNICAST : IpAddress.Addr = ADE->Address->Address.IPv4Address;
case ADE_MULTICAST: IpAddress.BcastAddr = ADE->Address->Address.IPv4Address;
case ADE_ADDRMASK : IpAddress.Mask = ADE->Address->Address.IPv4Address;
}
}
/* Pack the address information into IPADDR_ENTRY structure */
IpAddress.Index = 0;
IpAddress.ReasmSize = 0;
IpAddress.Context = 0;
IpAddress.Pad = 0;
Count = CopyBufferToBufferChain(Buffer, Temp, (PUCHAR)&IpAddress, sizeof(IPADDR_ENTRY));
Temp += sizeof(IPADDR_ENTRY);
}
KeReleaseSpinLock(&InterfaceLock, OldIrql);
return TDI_SUCCESS;
case IP_MIB_STATS_ID:
if (BufSize < sizeof(IPSNMP_INFO))
return TDI_BUFFER_TOO_SMALL;
RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
/* Count number of addresses */
Count = 0;
KeAcquireSpinLock(&InterfaceLock, &OldIrql);
for (IF = InterfaceList; IF != NULL; IF = IF->Next)
Count++;
KeReleaseSpinLock(&InterfaceLock, OldIrql);
SnmpInfo.NumAddr = Count;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&SnmpInfo, sizeof(IPSNMP_INFO));
return TDI_SUCCESS;
default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
return TDI_INVALID_PARAMETER;
}
TDI_STATUS InfoTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context)
/*
* FUNCTION: Returns extended information
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = TDI object ID
* Buffer = Pointer to buffer with data to use
* BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
* Context = Pointer to context buffer
* RETURNS:
* Status of operation
*/
{
PADDRESS_FILE AddrFile;
PADDRESS_ENTRY ADE;
ADDRESS_INFO Info;
KIRQL OldIrql;
UINT Entity;
UINT Count;
UINT Size;
ULONG Temp;
UINT Offset = 0;
UINT BufSize = *BufferSize;
/* Check wether it is a query for a list of entities */
Entity = ID->toi_entity.tei_entity;
if (Entity == GENERIC_ENTITY) {
if (ID->toi_class != INFO_CLASS_GENERIC ||
ID->toi_type != INFO_TYPE_PROVIDER ||
ID->toi_id != ENTITY_LIST_ID)
return TDI_INVALID_PARAMETER;
*BufferSize = 0;
Size = EntityCount * sizeof(TDIEntityID);
if (BufSize < Size)
/* The buffer is too small to contain requested data */
return TDI_BUFFER_TOO_SMALL;
/* Return entity list */
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
*BufferSize = Size;
return TDI_SUCCESS;
}
if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY)) {
/* We can't handle this entity, pass it on */
return IPTdiQueryInformationEx(
Request, ID, Buffer, BufferSize, Context);
}
/* Make return parameters consistent every time */
*BufferSize = 0;
if (ID->toi_entity.tei_instance != TL_INSTANCE)
/* We only support a single instance */
return TDI_INVALID_REQUEST;
if (ID->toi_class == INFO_CLASS_GENERIC) {
if (ID->toi_type != INFO_TYPE_PROVIDER ||
ID->toi_id != ENTITY_TYPE_ID)
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(ULONG))
return TDI_BUFFER_TOO_SMALL;
if (Entity == CL_TL_ENTITY)
Temp = CL_TL_UDP;
else if (Entity == CO_TL_ENTITY)
Temp = CO_TL_TCP;
else
return TDI_INVALID_PARAMETER;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
if (ID->toi_class == INFO_CLASS_PROTOCOL) {
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
switch (ID->toi_id) {
case UDP_MIB_STAT_ID:
if (Entity != CL_TL_ENTITY)
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(UDPStats))
return TDI_BUFFER_TOO_SMALL;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&UDPStats, sizeof(UDP_STATISTICS));
return TDI_SUCCESS;
case UDP_MIB_TABLE_ID:
if (Entity != CL_TL_ENTITY)
return TDI_INVALID_PARAMETER;
Offset = 0;
KeAcquireSpinLock(&AddressFileLock, &OldIrql);
for (AddrFile = AddressFileList;
AddrFile->Next != NULL;
AddrFile = AddrFile->Next) {
if (Offset + sizeof(ADDRESS_INFO) > BufSize) {
KeReleaseSpinLock(&AddressFileLock, OldIrql);
*BufferSize = Offset;
return TDI_BUFFER_OVERFLOW;
}
for (ADE = AddrFile->ADE; ADE != NULL; ADE = ADE->Next) {
/* We only care about IPv4 unicast address */
if ((ADE->Type == ADE_UNICAST) &&
(ADE->Address->Type == IP_ADDRESS_V4))
Info.LocalAddress = ADE->Address->Address.IPv4Address;
}
Info.LocalPort = AddrFile->Port;
Count = CopyBufferToBufferChain(Buffer, Offset, (PUCHAR)&Info, sizeof(ADDRESS_INFO));
Offset += Count;
}
KeReleaseSpinLock(&AddressFileLock, OldIrql);
*BufferSize = Offset;
return STATUS_SUCCESS;
default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
return TDI_INVALID_PARAMETER;
}
TDI_STATUS InfoTdiSetInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PVOID Buffer,
UINT BufferSize)
/*
* FUNCTION: Sets extended information
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = Pointer to TDI object ID
* Buffer = Pointer to buffer with data to use
* BufferSize = Size of Buffer
* RETURNS:
* Status of operation
*/
{
/* FIXME: Set extended information */
return TDI_INVALID_REQUEST;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/info.c
* PURPOSE: TDI query and set information routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/07-2000 Created
*/
#include <tcpip.h>
#include <routines.h>
#include <info.h>
TDI_STATUS IPTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context)
/*
* FUNCTION: Returns extended information about network layer
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = TDI object ID
* Buffer = Pointer to buffer with data to use.
* BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
* Context = Pointer to context buffer
* RETURNS:
* Status of operation
*/
{
IPADDR_ENTRY IpAddress;
IPSNMP_INFO SnmpInfo;
PADDRESS_ENTRY ADE;
PIP_INTERFACE IF;
ULONG Temp;
UINT Count;
ULONG Entity;
KIRQL OldIrql;
UINT BufSize = *BufferSize;
/* Make return parameters consistent every time */
*BufferSize = 0;
Entity = ID->toi_entity.tei_entity;
if (Entity != CL_NL_ENTITY) {
/* We can't handle this entity */
return TDI_INVALID_PARAMETER;
}
if (ID->toi_entity.tei_instance != TL_INSTANCE)
/* We only support a single instance */
return TDI_INVALID_REQUEST;
if (ID->toi_class == INFO_CLASS_GENERIC) {
if (ID->toi_type == INFO_TYPE_PROVIDER &&
ID->toi_id == ENTITY_TYPE_ID) {
if (BufSize < sizeof(ULONG))
return TDI_BUFFER_TOO_SMALL;
Temp = CL_NL_IP;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
return TDI_INVALID_PARAMETER;
}
if (ID->toi_class == INFO_CLASS_PROTOCOL) {
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
switch (ID->toi_id) {
case IP_MIB_ADDRTABLE_ENTRY_ID:
Temp = 0;
KeAcquireSpinLock(&InterfaceLock, &OldIrql);
/*
/* Search the interface list */
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
if (CurrentIF != Loopback) {
/* Search the address entry list and return the first appropriate ADE found */
CurrentADEEntry = CurrentIF->ADEListHead.Flink;
while (CurrentADEEntry != &CurrentIF->ADEListHead) {
CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
if (CurrentADE->Type == AddressType)
ReferenceAddress(CurrentADE->Address);
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return CurrentADE;
}
CurrentADEEntry = CurrentADEEntry->Flink;
} else
LoopbackIsRegistered = TRUE;
CurrentIFEntry = CurrentIFEntry->Flink;
}
*/
for (IF = InterfaceList; IF != NULL; IF = IF->Next) {
if (Temp + sizeof(IPADDR_ENTRY) > BufSize) {
KeReleaseSpinLock(&InterfaceLock, OldIrql);
return TDI_BUFFER_TOO_SMALL;
}
IpAddress.Addr = 0;
IpAddress.BcastAddr = 0;
IpAddress.Mask = 0;
/* Locate the diffrent addresses and put them the right place */
for (ADE = IF->ADE; ADE != NULL; ADE = ADE->Next) {
switch (ADE->Type) {
case ADE_UNICAST : IpAddress.Addr = ADE->Address->Address.IPv4Address;
case ADE_MULTICAST: IpAddress.BcastAddr = ADE->Address->Address.IPv4Address;
case ADE_ADDRMASK : IpAddress.Mask = ADE->Address->Address.IPv4Address;
}
}
/* Pack the address information into IPADDR_ENTRY structure */
IpAddress.Index = 0;
IpAddress.ReasmSize = 0;
IpAddress.Context = 0;
IpAddress.Pad = 0;
Count = CopyBufferToBufferChain(Buffer, Temp, (PUCHAR)&IpAddress, sizeof(IPADDR_ENTRY));
Temp += sizeof(IPADDR_ENTRY);
}
KeReleaseSpinLock(&InterfaceLock, OldIrql);
return TDI_SUCCESS;
case IP_MIB_STATS_ID:
if (BufSize < sizeof(IPSNMP_INFO))
return TDI_BUFFER_TOO_SMALL;
RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
/* Count number of addresses */
Count = 0;
KeAcquireSpinLock(&InterfaceLock, &OldIrql);
for (IF = InterfaceList; IF != NULL; IF = IF->Next)
Count++;
KeReleaseSpinLock(&InterfaceLock, OldIrql);
SnmpInfo.NumAddr = Count;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&SnmpInfo, sizeof(IPSNMP_INFO));
return TDI_SUCCESS;
default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
return TDI_INVALID_PARAMETER;
}
TDI_STATUS InfoTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context)
/*
* FUNCTION: Returns extended information
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = TDI object ID
* Buffer = Pointer to buffer with data to use
* BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
* Context = Pointer to context buffer
* RETURNS:
* Status of operation
*/
{
PADDRESS_FILE AddrFile;
PADDRESS_ENTRY ADE;
ADDRESS_INFO Info;
KIRQL OldIrql;
UINT Entity;
UINT Count;
UINT Size;
ULONG Temp;
UINT Offset = 0;
UINT BufSize = *BufferSize;
/* Check wether it is a query for a list of entities */
Entity = ID->toi_entity.tei_entity;
if (Entity == GENERIC_ENTITY) {
if (ID->toi_class != INFO_CLASS_GENERIC ||
ID->toi_type != INFO_TYPE_PROVIDER ||
ID->toi_id != ENTITY_LIST_ID)
return TDI_INVALID_PARAMETER;
*BufferSize = 0;
Size = EntityCount * sizeof(TDIEntityID);
if (BufSize < Size)
/* The buffer is too small to contain requested data */
return TDI_BUFFER_TOO_SMALL;
/* Return entity list */
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
*BufferSize = Size;
return TDI_SUCCESS;
}
if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY)) {
/* We can't handle this entity, pass it on */
return IPTdiQueryInformationEx(
Request, ID, Buffer, BufferSize, Context);
}
/* Make return parameters consistent every time */
*BufferSize = 0;
if (ID->toi_entity.tei_instance != TL_INSTANCE)
/* We only support a single instance */
return TDI_INVALID_REQUEST;
if (ID->toi_class == INFO_CLASS_GENERIC) {
if (ID->toi_type != INFO_TYPE_PROVIDER ||
ID->toi_id != ENTITY_TYPE_ID)
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(ULONG))
return TDI_BUFFER_TOO_SMALL;
if (Entity == CL_TL_ENTITY)
Temp = CL_TL_UDP;
else if (Entity == CO_TL_ENTITY)
Temp = CO_TL_TCP;
else
return TDI_INVALID_PARAMETER;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
if (ID->toi_class == INFO_CLASS_PROTOCOL) {
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
switch (ID->toi_id) {
case UDP_MIB_STAT_ID:
if (Entity != CL_TL_ENTITY)
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(UDPStats))
return TDI_BUFFER_TOO_SMALL;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&UDPStats, sizeof(UDP_STATISTICS));
return TDI_SUCCESS;
case UDP_MIB_TABLE_ID:
if (Entity != CL_TL_ENTITY)
return TDI_INVALID_PARAMETER;
Offset = 0;
KeAcquireSpinLock(&AddressFileLock, &OldIrql);
for (AddrFile = AddressFileList;
AddrFile->Next != NULL;
AddrFile = AddrFile->Next) {
if (Offset + sizeof(ADDRESS_INFO) > BufSize) {
KeReleaseSpinLock(&AddressFileLock, OldIrql);
*BufferSize = Offset;
return TDI_BUFFER_OVERFLOW;
}
for (ADE = AddrFile->ADE; ADE != NULL; ADE = ADE->Next) {
/* We only care about IPv4 unicast address */
if ((ADE->Type == ADE_UNICAST) &&
(ADE->Address->Type == IP_ADDRESS_V4))
Info.LocalAddress = ADE->Address->Address.IPv4Address;
}
Info.LocalPort = AddrFile->Port;
Count = CopyBufferToBufferChain(Buffer, Offset, (PUCHAR)&Info, sizeof(ADDRESS_INFO));
Offset += Count;
}
KeReleaseSpinLock(&AddressFileLock, OldIrql);
*BufferSize = Offset;
return STATUS_SUCCESS;
default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
return TDI_INVALID_PARAMETER;
}
TDI_STATUS InfoTdiSetInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PVOID Buffer,
UINT BufferSize)
/*
* FUNCTION: Sets extended information
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = Pointer to TDI object ID
* Buffer = Pointer to buffer with data to use
* BufferSize = Size of Buffer
* RETURNS:
* Status of operation
*/
{
/* FIXME: Set extended information */
return TDI_INVALID_REQUEST;
}
/* EOF */
+7 -7
View File
@@ -1,7 +1,7 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
+28 -28
View File
@@ -1,28 +1,28 @@
TARGETNAME=tcpip
TARGETPATH=..\objects
TARGETTYPE=EXPORT_DRIVER
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib \
..\objects\*\free\datagram.lib \
..\objects\*\free\datalink.lib \
..\objects\*\free\network.lib \
..\objects\*\free\rawip.lib \
..\objects\*\free\tcp.lib \
..\objects\*\free\udp.lib
INCLUDES=..\include;$(BASEDIR)\INC;..\..\..\..\include\net
SOURCES= address.c \
checksum.c \
dispatch.c \
fileobjs.c \
info.c \
main.c \
pool.c \
routines.c \
RESOURCE.RC
MSC_WARNING_LEVEL=/W3 /WX
TARGETNAME=tcpip
TARGETPATH=..\objects
TARGETTYPE=EXPORT_DRIVER
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib \
..\objects\*\free\datagram.lib \
..\objects\*\free\datalink.lib \
..\objects\*\free\network.lib \
..\objects\*\free\rawip.lib \
..\objects\*\free\tcp.lib \
..\objects\*\free\udp.lib
INCLUDES=..\include;$(BASEDIR)\INC;..\..\..\..\include\net
SOURCES= address.c \
checksum.c \
dispatch.c \
fileobjs.c \
info.c \
main.c \
pool.c \
routines.c \
RESOURCE.RC
MSC_WARNING_LEVEL=/W3 /WX
+312 -312
View File
@@ -1,312 +1,312 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/address.c
* PURPOSE: Routines for handling addresses
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <address.h>
#include <pool.h>
#include <ip.h>
BOOLEAN AddrIsUnspecified(
PIP_ADDRESS Address)
/*
* FUNCTION: Return wether IP address is an unspecified address
* ARGUMENTS:
* Address = Pointer to an IP address structure
* RETURNS:
* TRUE if the IP address is an unspecified address, FALSE if not
*/
{
switch (Address->Type) {
case IP_ADDRESS_V4:
return (Address->Address.IPv4Address == 0);
case IP_ADDRESS_V6:
/* FIXME: IPv6 is not supported */
default:
return FALSE;
}
}
/*
* FUNCTION: Extract IP address from TDI address structure
* ARGUMENTS:
* AddrList = Pointer to transport address list to extract from
* Address = Address of a pointer to where an IP address is stored
* Port = Pointer to where port number is stored
* Cache = Address of pointer to a cached address (updated on return)
* RETURNS:
* Status of operation
*/
NTSTATUS AddrGetAddress(
PTRANSPORT_ADDRESS AddrList,
PIP_ADDRESS *Address,
PUSHORT Port,
PIP_ADDRESS *Cache)
{
PTA_ADDRESS CurAddr;
INT i;
/* We can only use IP addresses. Search the list until we find one */
CurAddr = AddrList->Address;
for (i = 0; i < AddrList->TAAddressCount; i++) {
switch (CurAddr->AddressType) {
case TDI_ADDRESS_TYPE_IP:
if (CurAddr->AddressLength >= TDI_ADDRESS_LENGTH_IP) {
/* This is an IPv4 address */
PIP_ADDRESS IPAddress;
PTDI_ADDRESS_IP ValidAddr = (PTDI_ADDRESS_IP)CurAddr->Address;
*Port = ValidAddr->sin_port;
if (*Cache) {
if (((*Cache)->Type == IP_ADDRESS_V4) &&
((*Cache)->Address.IPv4Address == ValidAddr->in_addr)) {
*Address = *Cache;
return STATUS_SUCCESS;
} else {
/* Release the cached address as we cannot use it this time */
DereferenceObject(*Cache);
*Cache = NULL;
}
}
IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
if (IPAddress) {
AddrInitIPv4(IPAddress, ValidAddr->in_addr);
*Address = IPAddress;
/* Update address cache */
*Cache = IPAddress;
ReferenceObject(*Cache);
return STATUS_SUCCESS;
} else
return STATUS_INSUFFICIENT_RESOURCES;
} else
return STATUS_INVALID_ADDRESS;
default:
/* This is an unsupported address type.
Skip it and go to the next in the list */
CurAddr = (PTA_ADDRESS)((ULONG_PTR)CurAddr->Address + CurAddr->AddressLength);
}
}
return STATUS_INVALID_ADDRESS;
}
/*
* FUNCTION: Returns wether two addresses are equal
* ARGUMENTS:
* Address1 = Pointer to first address
* Address2 = Pointer to last address
* RETURNS:
* TRUE if Address1 = Address2, FALSE if not
*/
BOOLEAN AddrIsEqual(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2)
{
if (Address1->Type != Address2->Type)
return FALSE;
switch (Address1->Type) {
case IP_ADDRESS_V4:
return (Address1->Address.IPv4Address == Address2->Address.IPv4Address);
case IP_ADDRESS_V6:
return (RtlCompareMemory(&Address1->Address, &Address2->Address,
sizeof(IPv6_RAW_ADDRESS)) == sizeof(IPv6_RAW_ADDRESS));
break;
}
return FALSE;
}
/*
* FUNCTION: Returns wether Address1 is less than Address2
* ARGUMENTS:
* Address1 = Pointer to first address
* Address2 = Pointer to last address
* RETURNS:
* -1 if Address1 < Address2, 1 if Address1 > Address2,
* or 0 if they are equal
*/
INT AddrCompare(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2)
{
switch (Address1->Type) {
case IP_ADDRESS_V4: {
ULONG Addr1, Addr2;
if (Address2->Type == IP_ADDRESS_V4) {
Addr1 = DN2H(Address1->Address.IPv4Address);
Addr2 = DN2H(Address2->Address.IPv4Address);
if (Addr1 < Addr2)
return -1;
else
if (Addr1 == Addr2)
return 0;
else
return 1;
} else
/* FIXME: Support IPv6 */
return -1;
case IP_ADDRESS_V6:
/* FIXME: Support IPv6 */
break;
}
}
return FALSE;
}
/*
* FUNCTION: Returns wether two addresses are equal with IPv4 as input
* ARGUMENTS:
* Address1 = Pointer to first address
* Address2 = Pointer to last address
* RETURNS:
* TRUE if Address1 = Address2, FALSE if not
*/
BOOLEAN AddrIsEqualIPv4(
PIP_ADDRESS Address1,
IPv4_RAW_ADDRESS Address2)
{
if (Address1->Type == IP_ADDRESS_V4)
return (Address1->Address.IPv4Address == Address2);
return FALSE;
}
/*
* FUNCTION: Build an IPv4 style address
* ARGUMENTS:
* Address = Raw IPv4 address
* RETURNS:
* Pointer to IP address structure, NULL if there was not enough free
* non-paged memory
*/
PIP_ADDRESS AddrBuildIPv4(
IPv4_RAW_ADDRESS Address)
{
PIP_ADDRESS IPAddress;
IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
if (IPAddress) {
IPAddress->RefCount = 1;
IPAddress->Type = IP_ADDRESS_V4;
IPAddress->Address.IPv4Address = Address;
}
return IPAddress;
}
/*
* FUNCTION: Locates and returns an address entry using IPv4 adress as argument
* ARGUMENTS:
* Address = Raw IPv4 address
* RETURNS:
* Pointer to address entry if found, NULL if not found
* NOTES:
* Only unicast addresses are considered.
* If found, the address is referenced
*/
PADDRESS_ENTRY AddrLocateADEv4(
IPv4_RAW_ADDRESS Address)
{
IP_ADDRESS Addr;
AddrInitIPv4(&Addr, Address);
return IPLocateADE(&Addr, ADE_UNICAST);
}
/*
* FUNCTION: Searches through address file entries to find the first match
* ARGUMENTS:
* Address = IP address
* Port = Port number
* Protocol = Protocol number
* SearchContext = Pointer to search context
* RETURNS:
* Pointer to address file, NULL if none was found
*/
PADDRESS_FILE AddrSearchFirst(
PIP_ADDRESS Address,
USHORT Port,
USHORT Protocol,
PAF_SEARCH SearchContext)
{
SearchContext->Address = Address;
SearchContext->Port = Port;
SearchContext->Next = AddressFileListHead.Flink;
SearchContext->Protocol = Protocol;
return AddrSearchNext(SearchContext);
}
/*
* FUNCTION: Searches through address file entries to find next match
* ARGUMENTS:
* SearchContext = Pointer to search context
* RETURNS:
* Pointer to address file, NULL if none was found
*/
PADDRESS_FILE AddrSearchNext(
PAF_SEARCH SearchContext)
{
PLIST_ENTRY CurrentEntry;
PIP_ADDRESS IPAddress;
KIRQL OldIrql;
PADDRESS_FILE Current = NULL;
BOOLEAN Found = FALSE;
if (IsListEmpty(SearchContext->Next))
return NULL;
CurrentEntry = SearchContext->Next;
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
while (CurrentEntry != &AddressFileListHead) {
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry);
/* See if this address matches the search criteria */
IPAddress = Current->ADE->Address;
if (((Current->Port == SearchContext->Port) &&
(Current->Protocol == SearchContext->Protocol) &&
(AddrIsEqual(IPAddress, SearchContext->Address))) ||
(AddrIsUnspecified(IPAddress))) {
/* We've found a match */
Found = TRUE;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
if (Found) {
SearchContext->Next = CurrentEntry->Flink;
return Current;
} else
return NULL;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/address.c
* PURPOSE: Routines for handling addresses
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <address.h>
#include <pool.h>
#include <ip.h>
BOOLEAN AddrIsUnspecified(
PIP_ADDRESS Address)
/*
* FUNCTION: Return wether IP address is an unspecified address
* ARGUMENTS:
* Address = Pointer to an IP address structure
* RETURNS:
* TRUE if the IP address is an unspecified address, FALSE if not
*/
{
switch (Address->Type) {
case IP_ADDRESS_V4:
return (Address->Address.IPv4Address == 0);
case IP_ADDRESS_V6:
/* FIXME: IPv6 is not supported */
default:
return FALSE;
}
}
/*
* FUNCTION: Extract IP address from TDI address structure
* ARGUMENTS:
* AddrList = Pointer to transport address list to extract from
* Address = Address of a pointer to where an IP address is stored
* Port = Pointer to where port number is stored
* Cache = Address of pointer to a cached address (updated on return)
* RETURNS:
* Status of operation
*/
NTSTATUS AddrGetAddress(
PTRANSPORT_ADDRESS AddrList,
PIP_ADDRESS *Address,
PUSHORT Port,
PIP_ADDRESS *Cache)
{
PTA_ADDRESS CurAddr;
INT i;
/* We can only use IP addresses. Search the list until we find one */
CurAddr = AddrList->Address;
for (i = 0; i < AddrList->TAAddressCount; i++) {
switch (CurAddr->AddressType) {
case TDI_ADDRESS_TYPE_IP:
if (CurAddr->AddressLength >= TDI_ADDRESS_LENGTH_IP) {
/* This is an IPv4 address */
PIP_ADDRESS IPAddress;
PTDI_ADDRESS_IP ValidAddr = (PTDI_ADDRESS_IP)CurAddr->Address;
*Port = ValidAddr->sin_port;
if (*Cache) {
if (((*Cache)->Type == IP_ADDRESS_V4) &&
((*Cache)->Address.IPv4Address == ValidAddr->in_addr)) {
*Address = *Cache;
return STATUS_SUCCESS;
} else {
/* Release the cached address as we cannot use it this time */
DereferenceObject(*Cache);
*Cache = NULL;
}
}
IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
if (IPAddress) {
AddrInitIPv4(IPAddress, ValidAddr->in_addr);
*Address = IPAddress;
/* Update address cache */
*Cache = IPAddress;
ReferenceObject(*Cache);
return STATUS_SUCCESS;
} else
return STATUS_INSUFFICIENT_RESOURCES;
} else
return STATUS_INVALID_ADDRESS;
default:
/* This is an unsupported address type.
Skip it and go to the next in the list */
CurAddr = (PTA_ADDRESS)((ULONG_PTR)CurAddr->Address + CurAddr->AddressLength);
}
}
return STATUS_INVALID_ADDRESS;
}
/*
* FUNCTION: Returns wether two addresses are equal
* ARGUMENTS:
* Address1 = Pointer to first address
* Address2 = Pointer to last address
* RETURNS:
* TRUE if Address1 = Address2, FALSE if not
*/
BOOLEAN AddrIsEqual(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2)
{
if (Address1->Type != Address2->Type)
return FALSE;
switch (Address1->Type) {
case IP_ADDRESS_V4:
return (Address1->Address.IPv4Address == Address2->Address.IPv4Address);
case IP_ADDRESS_V6:
return (RtlCompareMemory(&Address1->Address, &Address2->Address,
sizeof(IPv6_RAW_ADDRESS)) == sizeof(IPv6_RAW_ADDRESS));
break;
}
return FALSE;
}
/*
* FUNCTION: Returns wether Address1 is less than Address2
* ARGUMENTS:
* Address1 = Pointer to first address
* Address2 = Pointer to last address
* RETURNS:
* -1 if Address1 < Address2, 1 if Address1 > Address2,
* or 0 if they are equal
*/
INT AddrCompare(
PIP_ADDRESS Address1,
PIP_ADDRESS Address2)
{
switch (Address1->Type) {
case IP_ADDRESS_V4: {
ULONG Addr1, Addr2;
if (Address2->Type == IP_ADDRESS_V4) {
Addr1 = DN2H(Address1->Address.IPv4Address);
Addr2 = DN2H(Address2->Address.IPv4Address);
if (Addr1 < Addr2)
return -1;
else
if (Addr1 == Addr2)
return 0;
else
return 1;
} else
/* FIXME: Support IPv6 */
return -1;
case IP_ADDRESS_V6:
/* FIXME: Support IPv6 */
break;
}
}
return FALSE;
}
/*
* FUNCTION: Returns wether two addresses are equal with IPv4 as input
* ARGUMENTS:
* Address1 = Pointer to first address
* Address2 = Pointer to last address
* RETURNS:
* TRUE if Address1 = Address2, FALSE if not
*/
BOOLEAN AddrIsEqualIPv4(
PIP_ADDRESS Address1,
IPv4_RAW_ADDRESS Address2)
{
if (Address1->Type == IP_ADDRESS_V4)
return (Address1->Address.IPv4Address == Address2);
return FALSE;
}
/*
* FUNCTION: Build an IPv4 style address
* ARGUMENTS:
* Address = Raw IPv4 address
* RETURNS:
* Pointer to IP address structure, NULL if there was not enough free
* non-paged memory
*/
PIP_ADDRESS AddrBuildIPv4(
IPv4_RAW_ADDRESS Address)
{
PIP_ADDRESS IPAddress;
IPAddress = PoolAllocateBuffer(sizeof(IP_ADDRESS));
if (IPAddress) {
IPAddress->RefCount = 1;
IPAddress->Type = IP_ADDRESS_V4;
IPAddress->Address.IPv4Address = Address;
}
return IPAddress;
}
/*
* FUNCTION: Locates and returns an address entry using IPv4 adress as argument
* ARGUMENTS:
* Address = Raw IPv4 address
* RETURNS:
* Pointer to address entry if found, NULL if not found
* NOTES:
* Only unicast addresses are considered.
* If found, the address is referenced
*/
PADDRESS_ENTRY AddrLocateADEv4(
IPv4_RAW_ADDRESS Address)
{
IP_ADDRESS Addr;
AddrInitIPv4(&Addr, Address);
return IPLocateADE(&Addr, ADE_UNICAST);
}
/*
* FUNCTION: Searches through address file entries to find the first match
* ARGUMENTS:
* Address = IP address
* Port = Port number
* Protocol = Protocol number
* SearchContext = Pointer to search context
* RETURNS:
* Pointer to address file, NULL if none was found
*/
PADDRESS_FILE AddrSearchFirst(
PIP_ADDRESS Address,
USHORT Port,
USHORT Protocol,
PAF_SEARCH SearchContext)
{
SearchContext->Address = Address;
SearchContext->Port = Port;
SearchContext->Next = AddressFileListHead.Flink;
SearchContext->Protocol = Protocol;
return AddrSearchNext(SearchContext);
}
/*
* FUNCTION: Searches through address file entries to find next match
* ARGUMENTS:
* SearchContext = Pointer to search context
* RETURNS:
* Pointer to address file, NULL if none was found
*/
PADDRESS_FILE AddrSearchNext(
PAF_SEARCH SearchContext)
{
PLIST_ENTRY CurrentEntry;
PIP_ADDRESS IPAddress;
KIRQL OldIrql;
PADDRESS_FILE Current = NULL;
BOOLEAN Found = FALSE;
if (IsListEmpty(SearchContext->Next))
return NULL;
CurrentEntry = SearchContext->Next;
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
while (CurrentEntry != &AddressFileListHead) {
Current = CONTAINING_RECORD(CurrentEntry, ADDRESS_FILE, ListEntry);
/* See if this address matches the search criteria */
IPAddress = Current->ADE->Address;
if (((Current->Port == SearchContext->Port) &&
(Current->Protocol == SearchContext->Protocol) &&
(AddrIsEqual(IPAddress, SearchContext->Address))) ||
(AddrIsUnspecified(IPAddress))) {
/* We've found a match */
Found = TRUE;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
if (Found) {
SearchContext->Next = CurrentEntry->Flink;
return Current;
} else
return NULL;
}
/* EOF */
+50 -50
View File
@@ -1,50 +1,50 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/checksum.c
* PURPOSE: Checksum routines
* NOTES: The checksum routine is from RFC 1071
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <checksum.h>
ULONG ChecksumCompute(
PVOID Data,
UINT Count,
ULONG Seed)
/*
* FUNCTION: Calculate checksum of a buffer
* ARGUMENTS:
* Data = Pointer to buffer with data
* Count = Number of bytes in buffer
* Seed = Previously calculated checksum (if any)
* RETURNS:
* Checksum of buffer
*/
{
/* FIXME: This should be done in assembler */
register ULONG Sum = Seed;
while (Count > 1) {
Sum += *(PUSHORT)Data;
Count -= 2;
(ULONG_PTR)Data += 2;
}
/* Add left-over byte, if any */
if (Count > 0)
Sum += *(PUCHAR)Data;
/* Fold 32-bit sum to 16 bits */
while (Sum >> 16)
Sum = (Sum & 0xFFFF) + (Sum >> 16);
return ~Sum;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/checksum.c
* PURPOSE: Checksum routines
* NOTES: The checksum routine is from RFC 1071
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <checksum.h>
ULONG ChecksumCompute(
PVOID Data,
UINT Count,
ULONG Seed)
/*
* FUNCTION: Calculate checksum of a buffer
* ARGUMENTS:
* Data = Pointer to buffer with data
* Count = Number of bytes in buffer
* Seed = Previously calculated checksum (if any)
* RETURNS:
* Checksum of buffer
*/
{
/* FIXME: This should be done in assembler */
register ULONG Sum = Seed;
while (Count > 1) {
Sum += *(PUSHORT)Data;
Count -= 2;
(ULONG_PTR)Data += 2;
}
/* Add left-over byte, if any */
if (Count > 0)
Sum += *(PUCHAR)Data;
/* Fold 32-bit sum to 16 bits */
while (Sum >> 16)
Sum = (Sum & 0xFFFF) + (Sum >> 16);
return ~Sum;
}
/* EOF */
File diff suppressed because it is too large Load Diff
+396 -396
View File
@@ -1,396 +1,396 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/fileobjs.c
* PURPOSE: Routines for handling file objects
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <datagram.h>
#include <address.h>
#include <pool.h>
#include <rawip.h>
#include <udp.h>
#include <ip.h>
#include <fileobjs.h>
LIST_ENTRY AddressFileListHead;
KSPIN_LOCK AddressFileListLock;
/*
* FUNCTION: Deletes an address file object
* ARGUMENTS:
* AddrFile = Pointer to address file object to delete
*/
VOID DeleteAddress(
PADDRESS_FILE AddrFile)
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PLIST_ENTRY NextEntry;
PDATAGRAM_SEND_REQUEST SendRequest;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* Remove address file from the global list */
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
RemoveEntryList(&AddrFile->ListEntry);
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* FIXME: Kill TCP connections on this address file object */
/* Return pending requests with error */
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
/* Go through pending receive request list and cancel them all */
CurrentEntry = AddrFile->ReceiveQueue.Flink;
while (CurrentEntry != &AddrFile->ReceiveQueue) {
NextEntry = CurrentEntry->Flink;
ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
/* Abort the request and free its resources */
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
PoolFreeBuffer(ReceiveRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
CurrentEntry = NextEntry;
}
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
/* Go through pending send request list and cancel them all */
CurrentEntry = AddrFile->TransmitQueue.Flink;
while (CurrentEntry != &AddrFile->TransmitQueue) {
NextEntry = CurrentEntry->Flink;
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
/* Abort the request and free its resources */
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
(*SendRequest->Complete)(SendRequest->Context, STATUS_ADDRESS_CLOSED, 0);
PoolFreeBuffer(SendRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
CurrentEntry = NextEntry;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* Dereference address entry */
DereferenceObject(AddrFile->ADE);
/* Dereference address cache */
if (AddrFile->AddrCache)
DereferenceObject(AddrFile->AddrCache);
#ifdef DBG
/* Remove reference provided at creation time */
AddrFile->RefCount--;
if (AddrFile->RefCount != 0)
TI_DbgPrint(DEBUG_REFCOUNT, ("AddrFile->RefCount is (%d) (should be 0).\n", AddrFile->RefCount));
#endif
PoolFreeBuffer(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID RequestWorker(
PVOID Context)
/*
* FUNCTION: Worker routine for processing address file object requests
* ARGUMENTS:
* Context = Pointer to context information (ADDRESS_FILE)
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PADDRESS_FILE AddrFile = Context;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Check it the address file should be deleted */
if (AF_IS_PENDING(AddrFile, AFF_DELETE)) {
DATAGRAM_COMPLETION_ROUTINE RtnComplete;
PVOID RtnContext;
RtnComplete = AddrFile->Complete;
RtnContext = AddrFile->Context;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
(*RtnComplete)(RtnContext, TDI_SUCCESS, 0);
TI_DbgPrint(MAX_TRACE, ("Leaving (delete).\n"));
return;
}
/* Check if there is a pending send request */
if (AF_IS_PENDING(AddrFile, AFF_SEND)) {
if (!IsListEmpty(&AddrFile->TransmitQueue)) {
PDATAGRAM_SEND_REQUEST SendRequest;
CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
AF_CLR_BUSY(AddrFile);
ReferenceObject(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* The send routine processes the send requests in
the transmit queue on the address file. When the
queue is empty the pending send flag is cleared.
The routine may return with the pending send flag
set. This can happen if there was not enough free
resources available to complete all send requests */
DGSend(AddrFile, SendRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
DereferenceObject(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (send request).\n"));
return;
} else
/* There was a pending send, but no send request.
Print a debug message and continue */
TI_DbgPrint(MIN_TRACE, ("Pending send, but no send request.\n"));
}
AF_CLR_BUSY(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
/*
* FUNCTION: Open an address file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* Address = Pointer to address to be opened
* Protocol = Protocol on which to open the address
* Options = Pointer to option buffer
* RETURNS:
* Status of operation
*/
NTSTATUS FileOpenAddress(
PTDI_REQUEST Request,
PTA_ADDRESS_IP Address,
USHORT Protocol,
PVOID Options)
{
PADDRESS_FILE AddrFile;
IPv4_RAW_ADDRESS IPv4Address;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
AddrFile = PoolAllocateBuffer(sizeof(ADDRESS_FILE));
if (!AddrFile) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
TI_DbgPrint(DEBUG_ADDRFILE, ("Address file object allocated at (0x%X).\n", AddrFile));
RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE));
/* Make sure address is a local unicast address or 0 */
/* Locate address entry. If specified address is 0, a random address is chosen */
IPv4Address = Address->Address[0].Address[0].in_addr;
if (IPv4Address == 0)
AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
else
AddrFile->ADE = AddrLocateADEv4(IPv4Address);
if (!AddrFile->ADE) {
PoolFreeBuffer(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
}
TI_DbgPrint(DEBUG_ADDRFILE, ("Opening address (0x%X) for communication.\n",
DN2H(AddrFile->ADE->Address->Address.IPv4Address)));
/* Protocol specific handling */
switch (Protocol) {
case IPPROTO_TCP:
/* FIXME: TCP */
TI_DbgPrint(MIN_TRACE, ("TCP is not supported.\n"));
DereferenceObject(AddrFile->ADE);
PoolFreeBuffer(AddrFile);
return STATUS_INVALID_PARAMETER;
case IPPROTO_UDP:
/* FIXME: If specified port is 0, a port is chosen dynamically */
AddrFile->Port = Address->Address[0].Address[0].sin_port;
AddrFile->Send = UDPSendDatagram;
break;
default:
/* Use raw IP for all other protocols */
AddrFile->Send = RawIPSendDatagram;
break;
}
/* Set protocol */
AddrFile->Protocol = Protocol;
/* Initialize receive and transmit queues */
InitializeListHead(&AddrFile->ReceiveQueue);
InitializeListHead(&AddrFile->TransmitQueue);
/* Initialize work queue item. We use this for pending requests */
ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);
/* Initialize spin lock that protects the address file object */
KeInitializeSpinLock(&AddrFile->Lock);
/* Reference the object */
AddrFile->RefCount = 1;
/* Set valid flag so the address can be used */
AF_SET_VALID(AddrFile);
/* Return address file object */
Request->Handle.AddressHandle = AddrFile;
/* Add address file to global list */
ExInterlockedInsertTailList(&AddressFileListHead, &AddrFile->ListEntry, &AddressFileListLock);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_SUCCESS;
}
/*
* FUNCTION: Closes an address file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileCloseAddress(
PTDI_REQUEST Request)
{
KIRQL OldIrql;
PADDRESS_FILE AddrFile;
NTSTATUS Status = STATUS_SUCCESS;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
AddrFile = Request->Handle.AddressHandle;
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if ((!AF_IS_BUSY(AddrFile)) && (AddrFile->RefCount == 1)) {
/* Set address file object exclusive to us */
AF_SET_BUSY(AddrFile);
AF_CLR_VALID(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
} else {
if (!AF_IS_PENDING(AddrFile, AFF_DELETE)) {
AddrFile->Complete = Request->RequestNotifyObject;
AddrFile->Context = Request->RequestContext;
/* Shedule address file for deletion */
AF_SET_PENDING(AddrFile, AFF_DELETE);
AF_CLR_VALID(AddrFile);
if (!AF_IS_BUSY(AddrFile)) {
/* Worker function is not running, so shedule it to run */
AF_SET_BUSY(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
ExQueueWorkItem(&AddrFile->WorkItem, CriticalWorkQueue);
} else
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
return STATUS_PENDING;
} else
Status = STATUS_ADDRESS_CLOSED;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return Status;
}
/*
* FUNCTION: Opens a connection file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileOpenConnection(
PTDI_REQUEST Request)
{
return STATUS_NOT_IMPLEMENTED;
}
/*
* FUNCTION: Closes an connection file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileCloseConnection(
PTDI_REQUEST Request)
{
return STATUS_NOT_IMPLEMENTED;
}
/*
* FUNCTION: Opens a control channel file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileOpenControlChannel(
PTDI_REQUEST Request)
{
return STATUS_NOT_IMPLEMENTED;
}
/*
* FUNCTION: Closes a control channel file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileCloseControlChannel(
PTDI_REQUEST Request)
{
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/fileobjs.c
* PURPOSE: Routines for handling file objects
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <datagram.h>
#include <address.h>
#include <pool.h>
#include <rawip.h>
#include <udp.h>
#include <ip.h>
#include <fileobjs.h>
LIST_ENTRY AddressFileListHead;
KSPIN_LOCK AddressFileListLock;
/*
* FUNCTION: Deletes an address file object
* ARGUMENTS:
* AddrFile = Pointer to address file object to delete
*/
VOID DeleteAddress(
PADDRESS_FILE AddrFile)
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PLIST_ENTRY NextEntry;
PDATAGRAM_SEND_REQUEST SendRequest;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
/* Remove address file from the global list */
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
RemoveEntryList(&AddrFile->ListEntry);
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* FIXME: Kill TCP connections on this address file object */
/* Return pending requests with error */
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile));
/* Go through pending receive request list and cancel them all */
CurrentEntry = AddrFile->ReceiveQueue.Flink;
while (CurrentEntry != &AddrFile->ReceiveQueue) {
NextEntry = CurrentEntry->Flink;
ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
/* Abort the request and free its resources */
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
(*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_ADDRESS_CLOSED, 0);
PoolFreeBuffer(ReceiveRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
CurrentEntry = NextEntry;
}
TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile));
/* Go through pending send request list and cancel them all */
CurrentEntry = AddrFile->TransmitQueue.Flink;
while (CurrentEntry != &AddrFile->TransmitQueue) {
NextEntry = CurrentEntry->Flink;
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
/* Abort the request and free its resources */
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
(*SendRequest->Complete)(SendRequest->Context, STATUS_ADDRESS_CLOSED, 0);
PoolFreeBuffer(SendRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
CurrentEntry = NextEntry;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* Dereference address entry */
DereferenceObject(AddrFile->ADE);
/* Dereference address cache */
if (AddrFile->AddrCache)
DereferenceObject(AddrFile->AddrCache);
#ifdef DBG
/* Remove reference provided at creation time */
AddrFile->RefCount--;
if (AddrFile->RefCount != 0)
TI_DbgPrint(DEBUG_REFCOUNT, ("AddrFile->RefCount is (%d) (should be 0).\n", AddrFile->RefCount));
#endif
PoolFreeBuffer(AddrFile);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
VOID RequestWorker(
PVOID Context)
/*
* FUNCTION: Worker routine for processing address file object requests
* ARGUMENTS:
* Context = Pointer to context information (ADDRESS_FILE)
*/
{
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PADDRESS_FILE AddrFile = Context;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
/* Check it the address file should be deleted */
if (AF_IS_PENDING(AddrFile, AFF_DELETE)) {
DATAGRAM_COMPLETION_ROUTINE RtnComplete;
PVOID RtnContext;
RtnComplete = AddrFile->Complete;
RtnContext = AddrFile->Context;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
(*RtnComplete)(RtnContext, TDI_SUCCESS, 0);
TI_DbgPrint(MAX_TRACE, ("Leaving (delete).\n"));
return;
}
/* Check if there is a pending send request */
if (AF_IS_PENDING(AddrFile, AFF_SEND)) {
if (!IsListEmpty(&AddrFile->TransmitQueue)) {
PDATAGRAM_SEND_REQUEST SendRequest;
CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
AF_CLR_BUSY(AddrFile);
ReferenceObject(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* The send routine processes the send requests in
the transmit queue on the address file. When the
queue is empty the pending send flag is cleared.
The routine may return with the pending send flag
set. This can happen if there was not enough free
resources available to complete all send requests */
DGSend(AddrFile, SendRequest);
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
DereferenceObject(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (send request).\n"));
return;
} else
/* There was a pending send, but no send request.
Print a debug message and continue */
TI_DbgPrint(MIN_TRACE, ("Pending send, but no send request.\n"));
}
AF_CLR_BUSY(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
/*
* FUNCTION: Open an address file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* Address = Pointer to address to be opened
* Protocol = Protocol on which to open the address
* Options = Pointer to option buffer
* RETURNS:
* Status of operation
*/
NTSTATUS FileOpenAddress(
PTDI_REQUEST Request,
PTA_ADDRESS_IP Address,
USHORT Protocol,
PVOID Options)
{
PADDRESS_FILE AddrFile;
IPv4_RAW_ADDRESS IPv4Address;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
AddrFile = PoolAllocateBuffer(sizeof(ADDRESS_FILE));
if (!AddrFile) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
TI_DbgPrint(DEBUG_ADDRFILE, ("Address file object allocated at (0x%X).\n", AddrFile));
RtlZeroMemory(AddrFile, sizeof(ADDRESS_FILE));
/* Make sure address is a local unicast address or 0 */
/* Locate address entry. If specified address is 0, a random address is chosen */
IPv4Address = Address->Address[0].Address[0].in_addr;
if (IPv4Address == 0)
AddrFile->ADE = IPGetDefaultADE(ADE_UNICAST);
else
AddrFile->ADE = AddrLocateADEv4(IPv4Address);
if (!AddrFile->ADE) {
PoolFreeBuffer(AddrFile);
TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", DN2H(IPv4Address)));
return STATUS_INVALID_PARAMETER;
}
TI_DbgPrint(DEBUG_ADDRFILE, ("Opening address (0x%X) for communication.\n",
DN2H(AddrFile->ADE->Address->Address.IPv4Address)));
/* Protocol specific handling */
switch (Protocol) {
case IPPROTO_TCP:
/* FIXME: TCP */
TI_DbgPrint(MIN_TRACE, ("TCP is not supported.\n"));
DereferenceObject(AddrFile->ADE);
PoolFreeBuffer(AddrFile);
return STATUS_INVALID_PARAMETER;
case IPPROTO_UDP:
/* FIXME: If specified port is 0, a port is chosen dynamically */
AddrFile->Port = Address->Address[0].Address[0].sin_port;
AddrFile->Send = UDPSendDatagram;
break;
default:
/* Use raw IP for all other protocols */
AddrFile->Send = RawIPSendDatagram;
break;
}
/* Set protocol */
AddrFile->Protocol = Protocol;
/* Initialize receive and transmit queues */
InitializeListHead(&AddrFile->ReceiveQueue);
InitializeListHead(&AddrFile->TransmitQueue);
/* Initialize work queue item. We use this for pending requests */
ExInitializeWorkItem(&AddrFile->WorkItem, RequestWorker, AddrFile);
/* Initialize spin lock that protects the address file object */
KeInitializeSpinLock(&AddrFile->Lock);
/* Reference the object */
AddrFile->RefCount = 1;
/* Set valid flag so the address can be used */
AF_SET_VALID(AddrFile);
/* Return address file object */
Request->Handle.AddressHandle = AddrFile;
/* Add address file to global list */
ExInterlockedInsertTailList(&AddressFileListHead, &AddrFile->ListEntry, &AddressFileListLock);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return STATUS_SUCCESS;
}
/*
* FUNCTION: Closes an address file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileCloseAddress(
PTDI_REQUEST Request)
{
KIRQL OldIrql;
PADDRESS_FILE AddrFile;
NTSTATUS Status = STATUS_SUCCESS;
TI_DbgPrint(MID_TRACE, ("Called.\n"));
AddrFile = Request->Handle.AddressHandle;
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if ((!AF_IS_BUSY(AddrFile)) && (AddrFile->RefCount == 1)) {
/* Set address file object exclusive to us */
AF_SET_BUSY(AddrFile);
AF_CLR_VALID(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
DeleteAddress(AddrFile);
} else {
if (!AF_IS_PENDING(AddrFile, AFF_DELETE)) {
AddrFile->Complete = Request->RequestNotifyObject;
AddrFile->Context = Request->RequestContext;
/* Shedule address file for deletion */
AF_SET_PENDING(AddrFile, AFF_DELETE);
AF_CLR_VALID(AddrFile);
if (!AF_IS_BUSY(AddrFile)) {
/* Worker function is not running, so shedule it to run */
AF_SET_BUSY(AddrFile);
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
ExQueueWorkItem(&AddrFile->WorkItem, CriticalWorkQueue);
} else
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
return STATUS_PENDING;
} else
Status = STATUS_ADDRESS_CLOSED;
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
return Status;
}
/*
* FUNCTION: Opens a connection file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileOpenConnection(
PTDI_REQUEST Request)
{
return STATUS_NOT_IMPLEMENTED;
}
/*
* FUNCTION: Closes an connection file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileCloseConnection(
PTDI_REQUEST Request)
{
return STATUS_NOT_IMPLEMENTED;
}
/*
* FUNCTION: Opens a control channel file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileOpenControlChannel(
PTDI_REQUEST Request)
{
return STATUS_NOT_IMPLEMENTED;
}
/*
* FUNCTION: Closes a control channel file object
* ARGUMENTS:
* Request = Pointer to TDI request structure for this request
* RETURNS:
* Status of operation
*/
NTSTATUS FileCloseControlChannel(
PTDI_REQUEST Request)
{
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */
+339 -339
View File
@@ -1,339 +1,339 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/info.c
* PURPOSE: TDI query and set information routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <info.h>
#include <routines.h>
TDI_STATUS IPTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context)
/*
* FUNCTION: Returns extended information about network layer
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = TDI object ID
* Buffer = Pointer to buffer with data to use.
* BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
* Context = Pointer to context buffer
* RETURNS:
* Status of operation
*/
{
PLIST_ENTRY CurrentIFEntry;
PLIST_ENTRY CurrentADEEntry;
PIP_INTERFACE CurrentIF;
PADDRESS_ENTRY CurrentADE;
IPADDR_ENTRY IpAddress;
IPSNMP_INFO SnmpInfo;
ULONG Temp;
UINT Count;
ULONG Entity;
KIRQL OldIrql;
UINT BufSize = *BufferSize;
/* Make return parameters consistent every time */
*BufferSize = 0;
Entity = ID->toi_entity.tei_entity;
if (Entity != CL_NL_ENTITY) {
/* We can't handle this entity */
return TDI_INVALID_PARAMETER;
}
if (ID->toi_entity.tei_instance != TL_INSTANCE)
/* We only support a single instance */
return TDI_INVALID_REQUEST;
if (ID->toi_class == INFO_CLASS_GENERIC) {
if (ID->toi_type == INFO_TYPE_PROVIDER &&
ID->toi_id == ENTITY_TYPE_ID) {
if (BufSize < sizeof(ULONG))
return TDI_BUFFER_TOO_SMALL;
Temp = CL_NL_IP;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
return TDI_INVALID_PARAMETER;
}
if (ID->toi_class == INFO_CLASS_PROTOCOL) {
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
switch (ID->toi_id) {
case IP_MIB_ADDRTABLE_ENTRY_ID:
Temp = 0;
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
if (Temp + sizeof(IPADDR_ENTRY) > BufSize) {
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return TDI_BUFFER_TOO_SMALL;
}
IpAddress.Addr = 0;
IpAddress.BcastAddr = 0;
IpAddress.Mask = 0;
/* Locate the diffrent addresses and put them the right place */
CurrentADEEntry = CurrentIF->ADEListHead.Flink;
while (CurrentADEEntry != &CurrentIF->ADEListHead) {
CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
switch (CurrentADE->Type) {
case ADE_UNICAST:
IpAddress.Addr = CurrentADE->Address->Address.IPv4Address;
break;
case ADE_MULTICAST:
IpAddress.BcastAddr = CurrentADE->Address->Address.IPv4Address;
break;
case ADE_ADDRMASK:
IpAddress.Mask = CurrentADE->Address->Address.IPv4Address;
break;
default:
/* Should not happen */
TI_DbgPrint(MIN_TRACE, ("Unknown address entry type (0x%X)\n", CurrentADE->Type));
break;
}
CurrentADEEntry = CurrentADEEntry->Flink;
}
/* Pack the address information into IPADDR_ENTRY structure */
IpAddress.Index = 0;
IpAddress.ReasmSize = 0;
IpAddress.Context = 0;
IpAddress.Pad = 0;
Count = CopyBufferToBufferChain(Buffer, Temp, (PUCHAR)&IpAddress, sizeof(IPADDR_ENTRY));
Temp += sizeof(IPADDR_ENTRY);
CurrentIFEntry = CurrentIFEntry->Flink;
}
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return TDI_SUCCESS;
case IP_MIB_STATS_ID:
if (BufSize < sizeof(IPSNMP_INFO))
return TDI_BUFFER_TOO_SMALL;
RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
/* Count number of addresses */
Count = 0;
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
Count++;
CurrentIFEntry = CurrentIFEntry->Flink;
}
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
SnmpInfo.NumAddr = Count;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&SnmpInfo, sizeof(IPSNMP_INFO));
return TDI_SUCCESS;
default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
return TDI_INVALID_PARAMETER;
}
TDI_STATUS InfoTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context)
/*
* FUNCTION: Returns extended information
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = TDI object ID
* Buffer = Pointer to buffer with data to use
* BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
* Context = Pointer to context buffer
* RETURNS:
* Status of operation
*/
{
PLIST_ENTRY CurrentADFEntry;
PADDRESS_FILE CurrentADF;
ADDRESS_INFO Info;
KIRQL OldIrql;
UINT Entity;
UINT Count;
UINT Size;
ULONG Temp;
UINT Offset = 0;
UINT BufSize = *BufferSize;
/* Check wether it is a query for a list of entities */
Entity = ID->toi_entity.tei_entity;
if (Entity == GENERIC_ENTITY) {
if (ID->toi_class != INFO_CLASS_GENERIC ||
ID->toi_type != INFO_TYPE_PROVIDER ||
ID->toi_id != ENTITY_LIST_ID)
return TDI_INVALID_PARAMETER;
*BufferSize = 0;
Size = EntityCount * sizeof(TDIEntityID);
if (BufSize < Size)
/* The buffer is too small to contain requested data */
return TDI_BUFFER_TOO_SMALL;
/* Return entity list */
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
*BufferSize = Size;
return TDI_SUCCESS;
}
if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY)) {
/* We can't handle this entity, pass it on */
return IPTdiQueryInformationEx(
Request, ID, Buffer, BufferSize, Context);
}
/* Make return parameters consistent every time */
*BufferSize = 0;
if (ID->toi_entity.tei_instance != TL_INSTANCE)
/* We only support a single instance */
return TDI_INVALID_REQUEST;
if (ID->toi_class == INFO_CLASS_GENERIC) {
if (ID->toi_type != INFO_TYPE_PROVIDER ||
ID->toi_id != ENTITY_TYPE_ID)
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(ULONG))
return TDI_BUFFER_TOO_SMALL;
if (Entity == CL_TL_ENTITY)
Temp = CL_TL_UDP;
else if (Entity == CO_TL_ENTITY)
Temp = CO_TL_TCP;
else
return TDI_INVALID_PARAMETER;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
if (ID->toi_class == INFO_CLASS_PROTOCOL) {
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
switch (ID->toi_id) {
case UDP_MIB_STAT_ID:
if (Entity != CL_TL_ENTITY)
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(UDPStats))
return TDI_BUFFER_TOO_SMALL;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&UDPStats, sizeof(UDP_STATISTICS));
return TDI_SUCCESS;
case UDP_MIB_TABLE_ID:
if (Entity != CL_TL_ENTITY)
return TDI_INVALID_PARAMETER;
Offset = 0;
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
CurrentADFEntry = AddressFileListHead.Flink;
while (CurrentADFEntry != &AddressFileListHead) {
CurrentADF = CONTAINING_RECORD(CurrentADFEntry, ADDRESS_FILE, ListEntry);
if (Offset + sizeof(ADDRESS_INFO) > BufSize) {
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
*BufferSize = Offset;
return TDI_BUFFER_OVERFLOW;
}
Info.LocalAddress = CurrentADF->ADE->Address->Address.IPv4Address;
Info.LocalPort = CurrentADF->Port;
Count = CopyBufferToBufferChain(Buffer, Offset, (PUCHAR)&Info, sizeof(ADDRESS_INFO));
Offset += Count;
CurrentADFEntry = CurrentADFEntry->Flink;
}
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
*BufferSize = Offset;
return STATUS_SUCCESS;
default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
return TDI_INVALID_PARAMETER;
}
TDI_STATUS InfoTdiSetInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PVOID Buffer,
UINT BufferSize)
/*
* FUNCTION: Sets extended information
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = Pointer to TDI object ID
* Buffer = Pointer to buffer with data to use
* BufferSize = Size of Buffer
* RETURNS:
* Status of operation
*/
{
/* FIXME: Set extended information */
return TDI_INVALID_REQUEST;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/info.c
* PURPOSE: TDI query and set information routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <info.h>
#include <routines.h>
TDI_STATUS IPTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context)
/*
* FUNCTION: Returns extended information about network layer
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = TDI object ID
* Buffer = Pointer to buffer with data to use.
* BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
* Context = Pointer to context buffer
* RETURNS:
* Status of operation
*/
{
PLIST_ENTRY CurrentIFEntry;
PLIST_ENTRY CurrentADEEntry;
PIP_INTERFACE CurrentIF;
PADDRESS_ENTRY CurrentADE;
IPADDR_ENTRY IpAddress;
IPSNMP_INFO SnmpInfo;
ULONG Temp;
UINT Count;
ULONG Entity;
KIRQL OldIrql;
UINT BufSize = *BufferSize;
/* Make return parameters consistent every time */
*BufferSize = 0;
Entity = ID->toi_entity.tei_entity;
if (Entity != CL_NL_ENTITY) {
/* We can't handle this entity */
return TDI_INVALID_PARAMETER;
}
if (ID->toi_entity.tei_instance != TL_INSTANCE)
/* We only support a single instance */
return TDI_INVALID_REQUEST;
if (ID->toi_class == INFO_CLASS_GENERIC) {
if (ID->toi_type == INFO_TYPE_PROVIDER &&
ID->toi_id == ENTITY_TYPE_ID) {
if (BufSize < sizeof(ULONG))
return TDI_BUFFER_TOO_SMALL;
Temp = CL_NL_IP;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
return TDI_INVALID_PARAMETER;
}
if (ID->toi_class == INFO_CLASS_PROTOCOL) {
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
switch (ID->toi_id) {
case IP_MIB_ADDRTABLE_ENTRY_ID:
Temp = 0;
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
if (Temp + sizeof(IPADDR_ENTRY) > BufSize) {
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return TDI_BUFFER_TOO_SMALL;
}
IpAddress.Addr = 0;
IpAddress.BcastAddr = 0;
IpAddress.Mask = 0;
/* Locate the diffrent addresses and put them the right place */
CurrentADEEntry = CurrentIF->ADEListHead.Flink;
while (CurrentADEEntry != &CurrentIF->ADEListHead) {
CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
switch (CurrentADE->Type) {
case ADE_UNICAST:
IpAddress.Addr = CurrentADE->Address->Address.IPv4Address;
break;
case ADE_MULTICAST:
IpAddress.BcastAddr = CurrentADE->Address->Address.IPv4Address;
break;
case ADE_ADDRMASK:
IpAddress.Mask = CurrentADE->Address->Address.IPv4Address;
break;
default:
/* Should not happen */
TI_DbgPrint(MIN_TRACE, ("Unknown address entry type (0x%X)\n", CurrentADE->Type));
break;
}
CurrentADEEntry = CurrentADEEntry->Flink;
}
/* Pack the address information into IPADDR_ENTRY structure */
IpAddress.Index = 0;
IpAddress.ReasmSize = 0;
IpAddress.Context = 0;
IpAddress.Pad = 0;
Count = CopyBufferToBufferChain(Buffer, Temp, (PUCHAR)&IpAddress, sizeof(IPADDR_ENTRY));
Temp += sizeof(IPADDR_ENTRY);
CurrentIFEntry = CurrentIFEntry->Flink;
}
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
return TDI_SUCCESS;
case IP_MIB_STATS_ID:
if (BufSize < sizeof(IPSNMP_INFO))
return TDI_BUFFER_TOO_SMALL;
RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
/* Count number of addresses */
Count = 0;
KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
CurrentIFEntry = InterfaceListHead.Flink;
while (CurrentIFEntry != &InterfaceListHead) {
CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
Count++;
CurrentIFEntry = CurrentIFEntry->Flink;
}
KeReleaseSpinLock(&InterfaceListLock, OldIrql);
SnmpInfo.NumAddr = Count;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&SnmpInfo, sizeof(IPSNMP_INFO));
return TDI_SUCCESS;
default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
return TDI_INVALID_PARAMETER;
}
TDI_STATUS InfoTdiQueryInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PNDIS_BUFFER Buffer,
PUINT BufferSize,
PVOID Context)
/*
* FUNCTION: Returns extended information
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = TDI object ID
* Buffer = Pointer to buffer with data to use
* BufferSize = Pointer to buffer with size of Buffer. On return
* this is filled with number of bytes returned
* Context = Pointer to context buffer
* RETURNS:
* Status of operation
*/
{
PLIST_ENTRY CurrentADFEntry;
PADDRESS_FILE CurrentADF;
ADDRESS_INFO Info;
KIRQL OldIrql;
UINT Entity;
UINT Count;
UINT Size;
ULONG Temp;
UINT Offset = 0;
UINT BufSize = *BufferSize;
/* Check wether it is a query for a list of entities */
Entity = ID->toi_entity.tei_entity;
if (Entity == GENERIC_ENTITY) {
if (ID->toi_class != INFO_CLASS_GENERIC ||
ID->toi_type != INFO_TYPE_PROVIDER ||
ID->toi_id != ENTITY_LIST_ID)
return TDI_INVALID_PARAMETER;
*BufferSize = 0;
Size = EntityCount * sizeof(TDIEntityID);
if (BufSize < Size)
/* The buffer is too small to contain requested data */
return TDI_BUFFER_TOO_SMALL;
/* Return entity list */
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
*BufferSize = Size;
return TDI_SUCCESS;
}
if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY)) {
/* We can't handle this entity, pass it on */
return IPTdiQueryInformationEx(
Request, ID, Buffer, BufferSize, Context);
}
/* Make return parameters consistent every time */
*BufferSize = 0;
if (ID->toi_entity.tei_instance != TL_INSTANCE)
/* We only support a single instance */
return TDI_INVALID_REQUEST;
if (ID->toi_class == INFO_CLASS_GENERIC) {
if (ID->toi_type != INFO_TYPE_PROVIDER ||
ID->toi_id != ENTITY_TYPE_ID)
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(ULONG))
return TDI_BUFFER_TOO_SMALL;
if (Entity == CL_TL_ENTITY)
Temp = CL_TL_UDP;
else if (Entity == CO_TL_ENTITY)
Temp = CO_TL_TCP;
else
return TDI_INVALID_PARAMETER;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
return TDI_SUCCESS;
}
if (ID->toi_class == INFO_CLASS_PROTOCOL) {
if (ID->toi_type != INFO_TYPE_PROVIDER)
return TDI_INVALID_PARAMETER;
switch (ID->toi_id) {
case UDP_MIB_STAT_ID:
if (Entity != CL_TL_ENTITY)
return TDI_INVALID_PARAMETER;
if (BufSize < sizeof(UDPStats))
return TDI_BUFFER_TOO_SMALL;
Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&UDPStats, sizeof(UDP_STATISTICS));
return TDI_SUCCESS;
case UDP_MIB_TABLE_ID:
if (Entity != CL_TL_ENTITY)
return TDI_INVALID_PARAMETER;
Offset = 0;
KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
CurrentADFEntry = AddressFileListHead.Flink;
while (CurrentADFEntry != &AddressFileListHead) {
CurrentADF = CONTAINING_RECORD(CurrentADFEntry, ADDRESS_FILE, ListEntry);
if (Offset + sizeof(ADDRESS_INFO) > BufSize) {
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
*BufferSize = Offset;
return TDI_BUFFER_OVERFLOW;
}
Info.LocalAddress = CurrentADF->ADE->Address->Address.IPv4Address;
Info.LocalPort = CurrentADF->Port;
Count = CopyBufferToBufferChain(Buffer, Offset, (PUCHAR)&Info, sizeof(ADDRESS_INFO));
Offset += Count;
CurrentADFEntry = CurrentADFEntry->Flink;
}
KeReleaseSpinLock(&AddressFileListLock, OldIrql);
*BufferSize = Offset;
return STATUS_SUCCESS;
default:
/* We can't handle this ID */
return TDI_INVALID_PARAMETER;
}
}
return TDI_INVALID_PARAMETER;
}
TDI_STATUS InfoTdiSetInformationEx(
PTDI_REQUEST Request,
TDIObjectID *ID,
PVOID Buffer,
UINT BufferSize)
/*
* FUNCTION: Sets extended information
* ARGUMENTS:
* Request = Pointer to TDI request structure for the request
* ID = Pointer to TDI object ID
* Buffer = Pointer to buffer with data to use
* BufferSize = Size of Buffer
* RETURNS:
* Status of operation
*/
{
/* FIXME: Set extended information */
return TDI_INVALID_REQUEST;
}
/* EOF */
File diff suppressed because it is too large Load Diff
+50 -50
View File
@@ -1,50 +1,50 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/pool.c
* PURPOSE: Routines for controling pools
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <pool.h>
PVOID PoolAllocateBuffer(
ULONG Size)
/*
* FUNCTION: Returns a buffer from the free buffer pool
* RETURNS:
* Pointer to buffer, NULL if there was not enough
* free resources
*/
{
PVOID Buffer;
/* FIXME: Get buffer from a free buffer pool with enough room */
Buffer = ExAllocatePool(NonPagedPool, Size);
TI_DbgPrint(DEBUG_MEMORY, ("Allocated (%i) bytes at (0x%X).\n", Size, Buffer));
return Buffer;
}
VOID PoolFreeBuffer(
PVOID Buffer)
/*
* FUNCTION: Returns a buffer to the free buffer pool
* ARGUMENTS:
* Buffer = Buffer to return to free buffer pool
*/
{
/* FIXME: Put buffer in free buffer pool */
TI_DbgPrint(DEBUG_MEMORY, ("Freeing buffer at (0x%X).\n", Buffer));
ExFreePool(Buffer);
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/pool.c
* PURPOSE: Routines for controling pools
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <pool.h>
PVOID PoolAllocateBuffer(
ULONG Size)
/*
* FUNCTION: Returns a buffer from the free buffer pool
* RETURNS:
* Pointer to buffer, NULL if there was not enough
* free resources
*/
{
PVOID Buffer;
/* FIXME: Get buffer from a free buffer pool with enough room */
Buffer = ExAllocatePool(NonPagedPool, Size);
TI_DbgPrint(DEBUG_MEMORY, ("Allocated (%i) bytes at (0x%X).\n", Size, Buffer));
return Buffer;
}
VOID PoolFreeBuffer(
PVOID Buffer)
/*
* FUNCTION: Returns a buffer to the free buffer pool
* ARGUMENTS:
* Buffer = Buffer to return to free buffer pool
*/
{
/* FIXME: Put buffer in free buffer pool */
TI_DbgPrint(DEBUG_MEMORY, ("Freeing buffer at (0x%X).\n", Buffer));
ExFreePool(Buffer);
}
/* EOF */
+10 -10
View File
@@ -1,10 +1,10 @@
#include <windows.h>
#include <ntverp.h>
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
#define VER_FILEDESCRIPTION_STR "TCP/IP protocol driver"
#define VER_INTERNALNAME_STR "TCPIP.SYS"
#define VER_ORIGINALFILENAME_STR "TCPIP.SYS"
#include "common.ver"
#include <windows.h>
#include <ntverp.h>
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_NETWORK
#define VER_FILEDESCRIPTION_STR "TCP/IP protocol driver"
#define VER_INTERNALNAME_STR "TCPIP.SYS"
#define VER_ORIGINALFILENAME_STR "TCPIP.SYS"
#include "common.ver"
+403 -403
View File
@@ -1,403 +1,403 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/routines.c
* PURPOSE: Common routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <routines.h>
#include <pool.h>
UINT RandomNumber = 0x12345678;
UINT Random(
VOID)
/*
* FUNCTION: Returns a pseudo random number
* RETURNS:
* Pseudo random number
*/
{
RandomNumber ^= 0x78563412;
return RandomNumber;
}
__inline INT SkipToOffset(
PNDIS_BUFFER Buffer,
UINT Offset,
PUCHAR *Data,
PUINT Size)
/*
* FUNCTION: Skip Offset bytes into a buffer chain
* ARGUMENTS:
* Buffer = Pointer to NDIS buffer
* Offset = Number of bytes to skip
* Data = Address of a pointer that on return will contain the
* address of the offset in the buffer
* Size = Address of a pointer that on return will contain the
* size of the destination buffer
* RETURNS:
* Offset into buffer, -1 if buffer chain was smaller than Offset bytes
* NOTES:
* Buffer may be NULL
*/
{
for (;;) {
if (!Buffer)
return -1;
NdisQueryBuffer(Buffer, Data, Size);
if (Offset < *Size) {
((ULONG_PTR)*Data) += Offset;
*Size -= Offset;
break;
}
Offset -= *Size;
NdisGetNextBuffer(Buffer, &Buffer);
}
return Offset;
}
UINT CopyBufferToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PUCHAR SrcData,
UINT Length)
/*
* FUNCTION: Copies data from a buffer to an NDIS buffer chain
* ARGUMENTS:
* DstBuffer = Pointer to destination NDIS buffer
* DstOffset = Destination start offset
* SrcData = Pointer to source buffer
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the destination
* buffer size
*/
{
UINT BytesCopied, BytesToCopy, DstSize;
PUCHAR DstData;
TI_DbgPrint(DEBUG_BUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcData, Length));
/* Skip DstOffset bytes in the destination buffer chain */
if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
return 0;
/* Start copying the data */
BytesCopied = 0;
for (;;) {
BytesToCopy = MIN(DstSize, Length);
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
BytesCopied += BytesToCopy;
(ULONG_PTR)SrcData += BytesToCopy;
Length -= BytesToCopy;
if (Length == 0)
break;
DstSize -= BytesToCopy;
if (DstSize == 0) {
/* No more bytes in desination buffer. Proceed to
the next buffer in the destination buffer chain */
NdisGetNextBuffer(DstBuffer, &DstBuffer);
if (!DstBuffer)
break;
NdisQueryBuffer(DstBuffer, &DstData, &DstSize);
}
}
return BytesCopied;
}
UINT CopyBufferChainToBuffer(
PUCHAR DstData,
PNDIS_BUFFER SrcBuffer,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS buffer chain to a buffer
* ARGUMENTS:
* DstData = Pointer to destination buffer
* SrcBuffer = Pointer to source NDIS buffer
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source
* buffer size
*/
{
UINT BytesCopied, BytesToCopy, SrcSize;
PUCHAR SrcData;
TI_DbgPrint(DEBUG_BUFFER, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData,SrcBuffer, SrcOffset, Length));
/* Skip SrcOffset bytes in the source buffer chain */
if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
return 0;
/* Start copying the data */
BytesCopied = 0;
for (;;) {
BytesToCopy = MIN(SrcSize, Length);
TI_DbgPrint(DEBUG_BUFFER, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData));
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
BytesCopied += BytesToCopy;
(ULONG_PTR)DstData += BytesToCopy;
Length -= BytesToCopy;
if (Length == 0)
break;
SrcSize -= BytesToCopy;
if (SrcSize == 0) {
/* No more bytes in source buffer. Proceed to
the next buffer in the source buffer chain */
NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
if (!SrcBuffer)
break;
NdisQueryBuffer(SrcBuffer, &SrcData, &SrcSize);
}
}
return BytesCopied;
}
UINT CopyPacketToBuffer(
PUCHAR DstData,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS packet to a buffer
* ARGUMENTS:
* DstData = Pointer to destination buffer
* SrcPacket = Pointer to source NDIS packet
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source
* buffer size
*/
{
PNDIS_BUFFER FirstBuffer;
PVOID Address;
UINT FirstLength;
UINT TotalLength;
TI_DbgPrint(DEBUG_BUFFER, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData, SrcPacket, SrcOffset, Length));
NdisGetFirstBufferFromPacket(SrcPacket,
&FirstBuffer,
&Address,
&FirstLength,
&TotalLength);
return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length);
}
UINT CopyPacketToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
* ARGUMENTS:
* DstBuffer = Pointer to destination NDIS buffer
* DstOffset = Destination start offset
* SrcPacket = Pointer to source NDIS packet
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source and
* destination buffer sizes
*/
{
PNDIS_BUFFER SrcBuffer;
PUCHAR DstData, SrcData;
UINT DstSize, SrcSize;
UINT Count, Total;
TI_DbgPrint(DEBUG_BUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length));
/* Skip DstOffset bytes in the destination buffer chain */
NdisQueryBuffer(DstBuffer, &DstData, &DstSize);
if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
return 0;
/* Skip SrcOffset bytes in the source packet */
NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, &SrcData, &SrcSize, &Total);
if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
return 0;
/* Copy the data */
for (Total = 0;;) {
/* Find out how many bytes we can copy at one time */
if (Length < SrcSize)
Count = Length;
else
Count = SrcSize;
if (DstSize < Count)
Count = DstSize;
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
Total += Count;
Length -= Count;
if (Length == 0)
break;
DstSize -= Count;
if (DstSize == 0) {
/* No more bytes in destination buffer. Proceed to
the next buffer in the destination buffer chain */
NdisGetNextBuffer(DstBuffer, &DstBuffer);
if (!DstBuffer)
break;
NdisQueryBuffer(DstBuffer, &DstData, &DstSize);
}
SrcSize -= Count;
if (SrcSize == 0) {
/* No more bytes in source buffer. Proceed to
the next buffer in the source buffer chain */
NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
if (!SrcBuffer)
break;
NdisQueryBuffer(SrcBuffer, &SrcData, &SrcSize);
}
}
return Total;
}
VOID FreeNdisPacket(
PNDIS_PACKET Packet)
/*
* FUNCTION: Frees an NDIS packet
* ARGUMENTS:
* Packet = Pointer to NDIS packet to be freed
*/
{
PNDIS_BUFFER Buffer, NextBuffer;
TI_DbgPrint(DEBUG_BUFFER, ("Packet (0x%X)\n", Packet));
/* Free all the buffers in the packet first */
NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
for (; Buffer != NULL; Buffer = NextBuffer) {
PVOID Data;
UINT Length;
NdisGetNextBuffer(Buffer, &NextBuffer);
NdisQueryBuffer(Buffer, &Data, &Length);
NdisFreeBuffer(Buffer);
ExFreePool(Data);
}
/* Finally free the NDIS packet discriptor */
NdisFreePacket(Packet);
}
PVOID AdjustPacket(
PNDIS_PACKET Packet,
UINT Available,
UINT Needed)
/*
* FUNCTION: Adjusts the amount of unused space at the beginning of the packet
* ARGUMENTS:
* Packet = Pointer to packet
* Available = Number of bytes available at start of first buffer
* Needed = Number of bytes needed for the header
* RETURNS:
* Pointer to start of packet
*/
{
PNDIS_BUFFER NdisBuffer;
INT Adjust;
TI_DbgPrint(DEBUG_BUFFER, ("Available = %d, Needed = %d.\n", Available, Needed));
Adjust = Available - Needed;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
/* If Adjust is zero there is no need to adjust this packet as
there is no additional space at start the of first buffer */
if (Adjust != 0) {
#if 0
(ULONG_PTR)(NdisBuffer->MappedSystemVa) += Adjust;
(ULONG_PTR)(NdisBuffer->StartVa) += Adjust;
NdisBuffer->ByteCount -= Adjust;
#else
(ULONG_PTR)(NdisBuffer->MappedSystemVa) += Adjust;
NdisBuffer->ByteOffset += Adjust;
NdisBuffer->ByteCount -= Adjust;
#endif
}
return NdisBuffer->MappedSystemVa;
}
UINT ResizePacket(
PNDIS_PACKET Packet,
UINT Size)
/*
* FUNCTION: Resizes an NDIS packet
* ARGUMENTS:
* Packet = Pointer to packet
* Size = Number of bytes in first buffer
* RETURNS:
* Previous size of first buffer
*/
{
PNDIS_BUFFER NdisBuffer;
UINT OldSize;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
OldSize = NdisBuffer->ByteCount;
if (Size != OldSize)
NdisBuffer->ByteCount = Size;
return OldSize;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: tcpip/routines.c
* PURPOSE: Common routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <routines.h>
#include <pool.h>
UINT RandomNumber = 0x12345678;
UINT Random(
VOID)
/*
* FUNCTION: Returns a pseudo random number
* RETURNS:
* Pseudo random number
*/
{
RandomNumber ^= 0x78563412;
return RandomNumber;
}
__inline INT SkipToOffset(
PNDIS_BUFFER Buffer,
UINT Offset,
PUCHAR *Data,
PUINT Size)
/*
* FUNCTION: Skip Offset bytes into a buffer chain
* ARGUMENTS:
* Buffer = Pointer to NDIS buffer
* Offset = Number of bytes to skip
* Data = Address of a pointer that on return will contain the
* address of the offset in the buffer
* Size = Address of a pointer that on return will contain the
* size of the destination buffer
* RETURNS:
* Offset into buffer, -1 if buffer chain was smaller than Offset bytes
* NOTES:
* Buffer may be NULL
*/
{
for (;;) {
if (!Buffer)
return -1;
NdisQueryBuffer(Buffer, Data, Size);
if (Offset < *Size) {
((ULONG_PTR)*Data) += Offset;
*Size -= Offset;
break;
}
Offset -= *Size;
NdisGetNextBuffer(Buffer, &Buffer);
}
return Offset;
}
UINT CopyBufferToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PUCHAR SrcData,
UINT Length)
/*
* FUNCTION: Copies data from a buffer to an NDIS buffer chain
* ARGUMENTS:
* DstBuffer = Pointer to destination NDIS buffer
* DstOffset = Destination start offset
* SrcData = Pointer to source buffer
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the destination
* buffer size
*/
{
UINT BytesCopied, BytesToCopy, DstSize;
PUCHAR DstData;
TI_DbgPrint(DEBUG_BUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcData (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcData, Length));
/* Skip DstOffset bytes in the destination buffer chain */
if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
return 0;
/* Start copying the data */
BytesCopied = 0;
for (;;) {
BytesToCopy = MIN(DstSize, Length);
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
BytesCopied += BytesToCopy;
(ULONG_PTR)SrcData += BytesToCopy;
Length -= BytesToCopy;
if (Length == 0)
break;
DstSize -= BytesToCopy;
if (DstSize == 0) {
/* No more bytes in desination buffer. Proceed to
the next buffer in the destination buffer chain */
NdisGetNextBuffer(DstBuffer, &DstBuffer);
if (!DstBuffer)
break;
NdisQueryBuffer(DstBuffer, &DstData, &DstSize);
}
}
return BytesCopied;
}
UINT CopyBufferChainToBuffer(
PUCHAR DstData,
PNDIS_BUFFER SrcBuffer,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS buffer chain to a buffer
* ARGUMENTS:
* DstData = Pointer to destination buffer
* SrcBuffer = Pointer to source NDIS buffer
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source
* buffer size
*/
{
UINT BytesCopied, BytesToCopy, SrcSize;
PUCHAR SrcData;
TI_DbgPrint(DEBUG_BUFFER, ("DstData 0x%X SrcBuffer 0x%X SrcOffset 0x%X Length %d\n",DstData,SrcBuffer, SrcOffset, Length));
/* Skip SrcOffset bytes in the source buffer chain */
if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
return 0;
/* Start copying the data */
BytesCopied = 0;
for (;;) {
BytesToCopy = MIN(SrcSize, Length);
TI_DbgPrint(DEBUG_BUFFER, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData));
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
BytesCopied += BytesToCopy;
(ULONG_PTR)DstData += BytesToCopy;
Length -= BytesToCopy;
if (Length == 0)
break;
SrcSize -= BytesToCopy;
if (SrcSize == 0) {
/* No more bytes in source buffer. Proceed to
the next buffer in the source buffer chain */
NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
if (!SrcBuffer)
break;
NdisQueryBuffer(SrcBuffer, &SrcData, &SrcSize);
}
}
return BytesCopied;
}
UINT CopyPacketToBuffer(
PUCHAR DstData,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS packet to a buffer
* ARGUMENTS:
* DstData = Pointer to destination buffer
* SrcPacket = Pointer to source NDIS packet
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source
* buffer size
*/
{
PNDIS_BUFFER FirstBuffer;
PVOID Address;
UINT FirstLength;
UINT TotalLength;
TI_DbgPrint(DEBUG_BUFFER, ("DstData (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstData, SrcPacket, SrcOffset, Length));
NdisGetFirstBufferFromPacket(SrcPacket,
&FirstBuffer,
&Address,
&FirstLength,
&TotalLength);
return CopyBufferChainToBuffer(DstData, FirstBuffer, SrcOffset, Length);
}
UINT CopyPacketToBufferChain(
PNDIS_BUFFER DstBuffer,
UINT DstOffset,
PNDIS_PACKET SrcPacket,
UINT SrcOffset,
UINT Length)
/*
* FUNCTION: Copies data from an NDIS packet to an NDIS buffer chain
* ARGUMENTS:
* DstBuffer = Pointer to destination NDIS buffer
* DstOffset = Destination start offset
* SrcPacket = Pointer to source NDIS packet
* SrcOffset = Source start offset
* Length = Number of bytes to copy
* RETURNS:
* Number of bytes copied to destination buffer
* NOTES:
* The number of bytes copied may be limited by the source and
* destination buffer sizes
*/
{
PNDIS_BUFFER SrcBuffer;
PUCHAR DstData, SrcData;
UINT DstSize, SrcSize;
UINT Count, Total;
TI_DbgPrint(DEBUG_BUFFER, ("DstBuffer (0x%X) DstOffset (0x%X) SrcPacket (0x%X) SrcOffset (0x%X) Length (%d)\n", DstBuffer, DstOffset, SrcPacket, SrcOffset, Length));
/* Skip DstOffset bytes in the destination buffer chain */
NdisQueryBuffer(DstBuffer, &DstData, &DstSize);
if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
return 0;
/* Skip SrcOffset bytes in the source packet */
NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, &SrcData, &SrcSize, &Total);
if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
return 0;
/* Copy the data */
for (Total = 0;;) {
/* Find out how many bytes we can copy at one time */
if (Length < SrcSize)
Count = Length;
else
Count = SrcSize;
if (DstSize < Count)
Count = DstSize;
RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
Total += Count;
Length -= Count;
if (Length == 0)
break;
DstSize -= Count;
if (DstSize == 0) {
/* No more bytes in destination buffer. Proceed to
the next buffer in the destination buffer chain */
NdisGetNextBuffer(DstBuffer, &DstBuffer);
if (!DstBuffer)
break;
NdisQueryBuffer(DstBuffer, &DstData, &DstSize);
}
SrcSize -= Count;
if (SrcSize == 0) {
/* No more bytes in source buffer. Proceed to
the next buffer in the source buffer chain */
NdisGetNextBuffer(SrcBuffer, &SrcBuffer);
if (!SrcBuffer)
break;
NdisQueryBuffer(SrcBuffer, &SrcData, &SrcSize);
}
}
return Total;
}
VOID FreeNdisPacket(
PNDIS_PACKET Packet)
/*
* FUNCTION: Frees an NDIS packet
* ARGUMENTS:
* Packet = Pointer to NDIS packet to be freed
*/
{
PNDIS_BUFFER Buffer, NextBuffer;
TI_DbgPrint(DEBUG_BUFFER, ("Packet (0x%X)\n", Packet));
/* Free all the buffers in the packet first */
NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
for (; Buffer != NULL; Buffer = NextBuffer) {
PVOID Data;
UINT Length;
NdisGetNextBuffer(Buffer, &NextBuffer);
NdisQueryBuffer(Buffer, &Data, &Length);
NdisFreeBuffer(Buffer);
ExFreePool(Data);
}
/* Finally free the NDIS packet discriptor */
NdisFreePacket(Packet);
}
PVOID AdjustPacket(
PNDIS_PACKET Packet,
UINT Available,
UINT Needed)
/*
* FUNCTION: Adjusts the amount of unused space at the beginning of the packet
* ARGUMENTS:
* Packet = Pointer to packet
* Available = Number of bytes available at start of first buffer
* Needed = Number of bytes needed for the header
* RETURNS:
* Pointer to start of packet
*/
{
PNDIS_BUFFER NdisBuffer;
INT Adjust;
TI_DbgPrint(DEBUG_BUFFER, ("Available = %d, Needed = %d.\n", Available, Needed));
Adjust = Available - Needed;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
/* If Adjust is zero there is no need to adjust this packet as
there is no additional space at start the of first buffer */
if (Adjust != 0) {
#if 0
(ULONG_PTR)(NdisBuffer->MappedSystemVa) += Adjust;
(ULONG_PTR)(NdisBuffer->StartVa) += Adjust;
NdisBuffer->ByteCount -= Adjust;
#else
(ULONG_PTR)(NdisBuffer->MappedSystemVa) += Adjust;
NdisBuffer->ByteOffset += Adjust;
NdisBuffer->ByteCount -= Adjust;
#endif
}
return NdisBuffer->MappedSystemVa;
}
UINT ResizePacket(
PNDIS_PACKET Packet,
UINT Size)
/*
* FUNCTION: Resizes an NDIS packet
* ARGUMENTS:
* Packet = Pointer to packet
* Size = Number of bytes in first buffer
* RETURNS:
* Previous size of first buffer
*/
{
PNDIS_BUFFER NdisBuffer;
UINT OldSize;
NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
OldSize = NdisBuffer->ByteCount;
if (Size != OldSize)
NdisBuffer->ByteCount = Size;
return OldSize;
}
/* EOF */
+32
View File
@@ -0,0 +1,32 @@
; TCPIP.SYS - TCP/IP protocol driver
LIBRARY tcpip.sys
EXPORTS
;FreeIprBuff
;GetIFAndLink
IPAddInterface
;IPAllocBuff
IPDelInterface
;IPDelayedNdisReEnumerateBindings
;IPDeregisterARP
;IPDisableSniffer
;IPEnableSniffer
;IPFreeBuff
;IPGetAddrType
;IPGetBestInterface
;IPGetInfo
;IPInjectPkt
;IPProxyNdisRequest
;IPRegisterARP
;IPRegisterProtocol
;IPSetIPSecStatus
;IPTransmit
LookupRoute
;LookupRouteInformation
;SendICMPErr
;SetIPSecPtr
;UnSetIPSecPtr
;UnSetIPSecSendPtr
; EOF
+5 -5
View File
@@ -1,5 +1,5 @@
DIRS= datagram \
rawip \
tcp \
udp
DIRS= datagram \
rawip \
tcp \
udp
@@ -1,7 +1,7 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
@@ -1,13 +1,13 @@
TARGETNAME=datagram
TARGETPATH=..\..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\..\include;$(BASEDIR)\INC;..\..\..\..\..\include\net
SOURCES= datagram.c
MSC_WARNING_LEVEL=/W3 /WX
TARGETNAME=datagram
TARGETPATH=..\..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\..\include;$(BASEDIR)\INC;..\..\..\..\..\include\net
SOURCES= datagram.c
MSC_WARNING_LEVEL=/W3 /WX
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,7 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
@@ -1,13 +1,13 @@
TARGETNAME=rawip
TARGETPATH=..\..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\..\include;$(BASEDIR)\INC;..\..\..\..\..\include\net
SOURCES= rawip.c
MSC_WARNING_LEVEL=/W3 /WX
TARGETNAME=rawip
TARGETPATH=..\..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\..\include;$(BASEDIR)\INC;..\..\..\..\..\include\net
SOURCES= rawip.c
MSC_WARNING_LEVEL=/W3 /WX
+113 -113
View File
@@ -1,113 +1,113 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: transport/rawip/rawip.c
* PURPOSE: Raw IP routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <datagram.h>
#include <rawip.h>
#include <pool.h>
BOOLEAN RawIPInitialized = FALSE;
NTSTATUS BuildRawIPPacket(
PVOID Context,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET *IPPacket)
/*
* FUNCTION: Builds an UDP packet
* ARGUMENTS:
* Context = Pointer to context information (DATAGRAM_SEND_REQUEST)
* LocalAddress = Pointer to our local address (NULL)
* LocalPort = The port we send this datagram from (0)
* IPPacket = Address of pointer to IP packet
* RETURNS:
* Status of operation
*/
{
PIP_PACKET Packet;
NDIS_STATUS NdisStatus;
PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
/* Prepare packet */
Packet = PoolAllocateBuffer(sizeof(IP_PACKET));
if (!Packet)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(Packet, sizeof(IP_PACKET));
Packet->RefCount = 1;
Packet->TotalSize = SendRequest->BufferSize;
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PoolFreeBuffer(Packet);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Chain buffer to packet */
NdisChainBufferAtFront(Packet->NdisPacket, SendRequest->Buffer);
*IPPacket = Packet;
return STATUS_SUCCESS;
}
NTSTATUS RawIPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize)
/*
* FUNCTION: Sends a raw IP datagram to a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer with data
* DataSize = Size in bytes of data to be sent
* RETURNS:
* Status of operation
*/
{
return DGSendDatagram(Request, ConnInfo,
Buffer, DataSize, BuildRawIPPacket);
}
NTSTATUS RawIPStartup(
VOID)
/*
* FUNCTION: Initializes the Raw IP subsystem
* RETURNS:
* Status of operation
*/
{
RawIPInitialized = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS RawIPShutdown(
VOID)
/*
* FUNCTION: Shuts down the Raw IP subsystem
* RETURNS:
* Status of operation
*/
{
if (!RawIPInitialized)
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: transport/rawip/rawip.c
* PURPOSE: Raw IP routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <datagram.h>
#include <rawip.h>
#include <pool.h>
BOOLEAN RawIPInitialized = FALSE;
NTSTATUS BuildRawIPPacket(
PVOID Context,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET *IPPacket)
/*
* FUNCTION: Builds an UDP packet
* ARGUMENTS:
* Context = Pointer to context information (DATAGRAM_SEND_REQUEST)
* LocalAddress = Pointer to our local address (NULL)
* LocalPort = The port we send this datagram from (0)
* IPPacket = Address of pointer to IP packet
* RETURNS:
* Status of operation
*/
{
PIP_PACKET Packet;
NDIS_STATUS NdisStatus;
PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
/* Prepare packet */
Packet = PoolAllocateBuffer(sizeof(IP_PACKET));
if (!Packet)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(Packet, sizeof(IP_PACKET));
Packet->RefCount = 1;
Packet->TotalSize = SendRequest->BufferSize;
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
PoolFreeBuffer(Packet);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Chain buffer to packet */
NdisChainBufferAtFront(Packet->NdisPacket, SendRequest->Buffer);
*IPPacket = Packet;
return STATUS_SUCCESS;
}
NTSTATUS RawIPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize)
/*
* FUNCTION: Sends a raw IP datagram to a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer with data
* DataSize = Size in bytes of data to be sent
* RETURNS:
* Status of operation
*/
{
return DGSendDatagram(Request, ConnInfo,
Buffer, DataSize, BuildRawIPPacket);
}
NTSTATUS RawIPStartup(
VOID)
/*
* FUNCTION: Initializes the Raw IP subsystem
* RETURNS:
* Status of operation
*/
{
RawIPInitialized = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS RawIPShutdown(
VOID)
/*
* FUNCTION: Shuts down the Raw IP subsystem
* RETURNS:
* Status of operation
*/
{
if (!RawIPInitialized)
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
/* EOF */
@@ -1,7 +1,7 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
+13 -13
View File
@@ -1,13 +1,13 @@
TARGETNAME=tcp
TARGETPATH=..\..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\..\include;$(BASEDIR)\INC;..\..\..\..\..\include\net
SOURCES= tcp.c
MSC_WARNING_LEVEL=/W3 /WX
TARGETNAME=tcp
TARGETPATH=..\..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\..\include;$(BASEDIR)\INC;..\..\..\..\..\include\net
SOURCES= tcp.c
MSC_WARNING_LEVEL=/W3 /WX
+44 -44
View File
@@ -1,44 +1,44 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: transport/tcp/tcp.c
* PURPOSE: Transmission Control Protocol
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
BOOLEAN TCPInitialized = FALSE;
NTSTATUS TCPStartup(
VOID)
/*
* FUNCTION: Initializes the TCP subsystem
* RETURNS:
* Status of operation
*/
{
TCPInitialized = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS TCPShutdown(
VOID)
/*
* FUNCTION: Shuts down the TCP subsystem
* RETURNS:
* Status of operation
*/
{
if (!TCPInitialized)
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: transport/tcp/tcp.c
* PURPOSE: Transmission Control Protocol
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
BOOLEAN TCPInitialized = FALSE;
NTSTATUS TCPStartup(
VOID)
/*
* FUNCTION: Initializes the TCP subsystem
* RETURNS:
* Status of operation
*/
{
TCPInitialized = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS TCPShutdown(
VOID)
/*
* FUNCTION: Shuts down the TCP subsystem
* RETURNS:
* Status of operation
*/
{
if (!TCPInitialized)
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
/* EOF */
@@ -1,7 +1,7 @@
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
+12 -12
View File
@@ -1,12 +1,12 @@
TARGETNAME=udp
TARGETPATH=..\..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\..\include;$(BASEDIR)\INC;..\..\..\..\..\include\net
SOURCES= udp.c
MSC_WARNING_LEVEL=/W3 /WX
TARGETNAME=udp
TARGETPATH=..\..\objects
TARGETTYPE=LIBRARY
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
INCLUDES=..\..\include;$(BASEDIR)\INC;..\..\..\..\..\include\net
SOURCES= udp.c
MSC_WARNING_LEVEL=/W3 /WX
+437 -437
View File
@@ -1,437 +1,437 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: transport/udp/udp.c
* PURPOSE: User Datagram Protocol routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <udp.h>
#include <routines.h>
#include <transmit.h>
#include <datagram.h>
#include <checksum.h>
#include <address.h>
#include <pool.h>
BOOLEAN UDPInitialized = FALSE;
NTSTATUS AddUDPHeaderIPv4(
PDATAGRAM_SEND_REQUEST SendRequest,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET IPPacket)
/*
* FUNCTION: Adds an IPv4 and UDP header to an IP packet
* ARGUMENTS:
* SendRequest = Pointer to send request
* LocalAddress = Pointer to our local address
* LocalPort = The port we send this datagram from
* IPPacket = Pointer to IP packet
* RETURNS:
* Status of operation
*/
{
PIPv4_HEADER IPHeader;
PUDP_HEADER UDPHeader;
PVOID Header;
ULONG BufferSize;
NDIS_STATUS NdisStatus;
PNDIS_BUFFER HeaderBuffer;
BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER) + sizeof(UDP_HEADER);
Header = PoolAllocateBuffer(BufferSize);
if (!Header) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate NDIS buffer for maximum Link level, IP and UDP header */
NdisAllocateBuffer(&NdisStatus,
&HeaderBuffer,
GlobalBufferPool,
Header,
BufferSize);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for packet headers. NdisStatus = (0x%X)\n", NdisStatus));
PoolFreeBuffer(Header);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Chain header at front of NDIS packet */
NdisChainBufferAtFront(IPPacket->NdisPacket, HeaderBuffer);
IPPacket->Header = (PVOID)((ULONG_PTR)Header + MaxLLHeaderSize);
IPPacket->HeaderSize = 20;
/* Build IPv4 header */
IPHeader = (PIPv4_HEADER)IPPacket->Header;
/* Version = 4, Length = 5 DWORDs */
IPHeader->VerIHL = 0x45;
/* Normal Type-of-Service */
IPHeader->Tos = 0;
/* Length of header and data */
IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
/* Identification */
IPHeader->Id = 0;
/* One fragment at offset 0 */
IPHeader->FlagsFragOfs = 0;
/* Time-to-Live is 128 */
IPHeader->Ttl = 128;
/* User Datagram Protocol */
IPHeader->Protocol = IPPROTO_UDP;
/* Checksum is 0 (for later calculation of this) */
IPHeader->Checksum = 0;
/* Source address */
IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
/* Destination address. FIXME: IPv4 only */
IPHeader->DstAddr = SendRequest->RemoteAddress->Address.IPv4Address;
/* Build UDP header */
UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPHeader + sizeof(IPv4_HEADER));
/* Port values are already big-endian values */
UDPHeader->SourcePort = LocalPort;
UDPHeader->DestPort = SendRequest->RemotePort;
/* FIXME: Calculate UDP checksum and put it in UDP header */
UDPHeader->Checksum = 0;
/* Length of UDP header and data */
UDPHeader->Length = WH2N((USHORT)IPPacket->TotalSize - IPPacket->HeaderSize);
return STATUS_SUCCESS;
}
NTSTATUS BuildUDPPacket(
PVOID Context,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET *IPPacket)
/*
* FUNCTION: Builds an UDP packet
* ARGUMENTS:
* Context = Pointer to context information (DATAGRAM_SEND_REQUEST)
* LocalAddress = Pointer to our local address
* LocalPort = The port we send this datagram from
* IPPacket = Address of pointer to IP packet
* RETURNS:
* Status of operation
*/
{
NTSTATUS Status;
PIP_PACKET Packet;
NDIS_STATUS NdisStatus;
PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
/* Prepare packet */
Packet = PoolAllocateBuffer(sizeof(IP_PACKET));
if (!Packet) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(Packet, sizeof(IP_PACKET));
Packet->RefCount = 1;
Packet->TotalSize = sizeof(IPv4_HEADER) +
sizeof(UDP_HEADER) +
SendRequest->BufferSize;
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus));
PoolFreeBuffer(Packet);
return STATUS_INSUFFICIENT_RESOURCES;
}
switch (SendRequest->RemoteAddress->Type) {
case IP_ADDRESS_V4:
Status = AddUDPHeaderIPv4(SendRequest, LocalAddress, LocalPort, Packet);
break;
case IP_ADDRESS_V6:
/* FIXME: Support IPv6 */
TI_DbgPrint(MIN_TRACE, ("IPv6 UDP datagrams are not supported.\n"));
default:
Status = STATUS_UNSUCCESSFUL;
break;
}
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Cannot add UDP header. Status = (0x%X)\n", Status));
NdisFreePacket(Packet->NdisPacket);
PoolFreeBuffer(Packet);
return Status;
}
/* Chain data after header */
NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
*IPPacket = Packet;
return STATUS_SUCCESS;
}
VOID DeliverUDPData(
PADDRESS_FILE AddrFile,
PIP_ADDRESS Address,
PIP_PACKET IPPacket,
UINT DataSize)
/*
* FUNCTION: Delivers UDP data to a user
* ARGUMENTS:
* AddrFile = Address file to deliver data to
* Address = Remote address the packet came from
* IPPacket = Pointer to IP packet to deliver
* DataSize = Number of bytes in data area
* NOTES:
* If there is a receive request, then we copy the data to the
* buffer supplied by the user and complete the receive request.
* If no suitable receive request exists, then we call the event
* handler if it exists, otherwise we drop the packet.
*/
{
KIRQL OldIrql;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (!IsListEmpty(&AddrFile->ReceiveQueue)) {
PLIST_ENTRY CurrentEntry;
PDATAGRAM_RECEIVE_REQUEST Current;
BOOLEAN Found;
/* Search receive request list to find a match */
Found = FALSE;
CurrentEntry = AddrFile->ReceiveQueue.Flink;
while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
if (!Current->RemoteAddress)
Found = TRUE;
else if (AddrIsEqual(Address, Current->RemoteAddress))
Found = TRUE;
if (Found) {
/* FIXME: Maybe we should check if the buffer of this
receive request is large enough and if not, search
for another. Also a 'best fit' strategy could be used. */
/* Remove the request from the queue */
RemoveEntryList(&Current->ListEntry);
AddrFile->RefCount--;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
if (Found) {
/* Copy the data into buffer provided by the user */
CopyBufferToBufferChain(Current->Buffer,
0,
IPPacket->Data,
DataSize);
/* Complete the receive request */
(*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize);
/* Finally free the receive request */
if (Current->RemoteAddress)
PoolFreeBuffer(Current->RemoteAddress);
PoolFreeBuffer(Current);
}
} else {
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* FIXME: Call event handler */
TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n"));
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
NTSTATUS UDPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize)
/*
* FUNCTION: Sends an UDP datagram to a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer with data
* DataSize = Size in bytes of data to be sent
* RETURNS:
* Status of operation
*/
{
return DGSendDatagram(Request,
ConnInfo,
Buffer,
DataSize,
BuildUDPPacket);
}
NTSTATUS UDPReceiveDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived)
/*
* FUNCTION: Attempts to receive an UDP datagram from a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer chain to store received data
* ReceiveLength = Maximum size to use of buffer, 0 if all can be used
* ReceiveFlags = Receive flags (None, Normal, Peek)
* ReturnInfo = Pointer to structure for return information
* BytesReceive = Pointer to structure for number of bytes received
* RETURNS:
* Status of operation
* NOTES:
* This is the high level interface for receiving UDP datagrams
*/
{
return DGReceiveDatagram(Request,
ConnInfo,
Buffer,
ReceiveLength,
ReceiveFlags,
ReturnInfo,
BytesReceived);
}
VOID UDPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
/*
* FUNCTION: Receives and queues a UDP datagram
* ARGUMENTS:
* NTE = Pointer to net table entry which the packet was received on
* IPPacket = Pointer to an IP packet that was received
* NOTES:
* This is the low level interface for receiving UDP datagrams. It strips
* the UDP header from a packet and delivers the data to anyone that wants it
*/
{
AF_SEARCH SearchContext;
PIPv4_HEADER IPv4Header;
PADDRESS_FILE AddrFile;
PUDP_HEADER UDPHeader;
PIP_ADDRESS DstAddress;
UINT DataSize, i;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
switch (IPPacket->Type) {
/* IPv4 packet */
case IP_ADDRESS_V4:
IPv4Header = IPPacket->Header;
DstAddress = &IPPacket->DstAddr;
break;
/* IPv6 packet */
case IP_ADDRESS_V6:
TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 UDP datagram (%i bytes).\n", IPPacket->TotalSize));
/* FIXME: IPv6 is not supported */
return;
}
UDPHeader = (PUDP_HEADER)IPPacket->Data;
/* FIXME: Calculate and validate UDP checksum */
/* Sanity checks */
i = WH2N(UDPHeader->Length);
if ((i < sizeof(UDP_HEADER)) || (i > IPPacket->TotalSize - IPPacket->Position)) {
/* Incorrect or damaged packet received, discard it */
TI_DbgPrint(MIN_TRACE, ("Incorrect or damaged UDP packet received.\n"));
return;
}
DataSize = i - sizeof(UDP_HEADER);
/* Go to UDP data area */
(ULONG_PTR)IPPacket->Data += sizeof(UDP_HEADER);
/* Locate a receive request on destination address file object
and deliver the packet if one is found. If there is no receive
request on the address file object, call the associated receive
handler. If no receive handler is registered, drop the packet */
AddrFile = AddrSearchFirst(DstAddress,
UDPHeader->DestPort,
IPPROTO_UDP,
&SearchContext);
if (AddrFile) {
do {
DeliverUDPData(AddrFile,
DstAddress,
IPPacket,
DataSize);
} while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
} else {
/* There are no open address files that will take this datagram */
/* FIXME: IPv4 only */
TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 UDP datagram to address (0x%X).\n",
DN2H(DstAddress->Address.IPv4Address)));
/* FIXME: Send ICMP reply */
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
NTSTATUS UDPStartup(
VOID)
/*
* FUNCTION: Initializes the UDP subsystem
* RETURNS:
* Status of operation
*/
{
RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS));
/* Register this protocol with IP layer */
IPRegisterProtocol(IPPROTO_UDP, UDPReceive);
UDPInitialized = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS UDPShutdown(
VOID)
/*
* FUNCTION: Shuts down the UDP subsystem
* RETURNS:
* Status of operation
*/
{
if (!UDPInitialized)
return STATUS_SUCCESS;
/* Deregister this protocol with IP layer */
IPRegisterProtocol(IPPROTO_UDP, NULL);
return STATUS_SUCCESS;
}
/* EOF */
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: transport/udp/udp.c
* PURPOSE: User Datagram Protocol routines
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tcpip.h>
#include <udp.h>
#include <routines.h>
#include <transmit.h>
#include <datagram.h>
#include <checksum.h>
#include <address.h>
#include <pool.h>
BOOLEAN UDPInitialized = FALSE;
NTSTATUS AddUDPHeaderIPv4(
PDATAGRAM_SEND_REQUEST SendRequest,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET IPPacket)
/*
* FUNCTION: Adds an IPv4 and UDP header to an IP packet
* ARGUMENTS:
* SendRequest = Pointer to send request
* LocalAddress = Pointer to our local address
* LocalPort = The port we send this datagram from
* IPPacket = Pointer to IP packet
* RETURNS:
* Status of operation
*/
{
PIPv4_HEADER IPHeader;
PUDP_HEADER UDPHeader;
PVOID Header;
ULONG BufferSize;
NDIS_STATUS NdisStatus;
PNDIS_BUFFER HeaderBuffer;
BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER) + sizeof(UDP_HEADER);
Header = PoolAllocateBuffer(BufferSize);
if (!Header) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Allocate NDIS buffer for maximum Link level, IP and UDP header */
NdisAllocateBuffer(&NdisStatus,
&HeaderBuffer,
GlobalBufferPool,
Header,
BufferSize);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for packet headers. NdisStatus = (0x%X)\n", NdisStatus));
PoolFreeBuffer(Header);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Chain header at front of NDIS packet */
NdisChainBufferAtFront(IPPacket->NdisPacket, HeaderBuffer);
IPPacket->Header = (PVOID)((ULONG_PTR)Header + MaxLLHeaderSize);
IPPacket->HeaderSize = 20;
/* Build IPv4 header */
IPHeader = (PIPv4_HEADER)IPPacket->Header;
/* Version = 4, Length = 5 DWORDs */
IPHeader->VerIHL = 0x45;
/* Normal Type-of-Service */
IPHeader->Tos = 0;
/* Length of header and data */
IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
/* Identification */
IPHeader->Id = 0;
/* One fragment at offset 0 */
IPHeader->FlagsFragOfs = 0;
/* Time-to-Live is 128 */
IPHeader->Ttl = 128;
/* User Datagram Protocol */
IPHeader->Protocol = IPPROTO_UDP;
/* Checksum is 0 (for later calculation of this) */
IPHeader->Checksum = 0;
/* Source address */
IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
/* Destination address. FIXME: IPv4 only */
IPHeader->DstAddr = SendRequest->RemoteAddress->Address.IPv4Address;
/* Build UDP header */
UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPHeader + sizeof(IPv4_HEADER));
/* Port values are already big-endian values */
UDPHeader->SourcePort = LocalPort;
UDPHeader->DestPort = SendRequest->RemotePort;
/* FIXME: Calculate UDP checksum and put it in UDP header */
UDPHeader->Checksum = 0;
/* Length of UDP header and data */
UDPHeader->Length = WH2N((USHORT)IPPacket->TotalSize - IPPacket->HeaderSize);
return STATUS_SUCCESS;
}
NTSTATUS BuildUDPPacket(
PVOID Context,
PIP_ADDRESS LocalAddress,
USHORT LocalPort,
PIP_PACKET *IPPacket)
/*
* FUNCTION: Builds an UDP packet
* ARGUMENTS:
* Context = Pointer to context information (DATAGRAM_SEND_REQUEST)
* LocalAddress = Pointer to our local address
* LocalPort = The port we send this datagram from
* IPPacket = Address of pointer to IP packet
* RETURNS:
* Status of operation
*/
{
NTSTATUS Status;
PIP_PACKET Packet;
NDIS_STATUS NdisStatus;
PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
/* Prepare packet */
Packet = PoolAllocateBuffer(sizeof(IP_PACKET));
if (!Packet) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(Packet, sizeof(IP_PACKET));
Packet->RefCount = 1;
Packet->TotalSize = sizeof(IPv4_HEADER) +
sizeof(UDP_HEADER) +
SendRequest->BufferSize;
/* Allocate NDIS packet */
NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus));
PoolFreeBuffer(Packet);
return STATUS_INSUFFICIENT_RESOURCES;
}
switch (SendRequest->RemoteAddress->Type) {
case IP_ADDRESS_V4:
Status = AddUDPHeaderIPv4(SendRequest, LocalAddress, LocalPort, Packet);
break;
case IP_ADDRESS_V6:
/* FIXME: Support IPv6 */
TI_DbgPrint(MIN_TRACE, ("IPv6 UDP datagrams are not supported.\n"));
default:
Status = STATUS_UNSUCCESSFUL;
break;
}
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Cannot add UDP header. Status = (0x%X)\n", Status));
NdisFreePacket(Packet->NdisPacket);
PoolFreeBuffer(Packet);
return Status;
}
/* Chain data after header */
NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
*IPPacket = Packet;
return STATUS_SUCCESS;
}
VOID DeliverUDPData(
PADDRESS_FILE AddrFile,
PIP_ADDRESS Address,
PIP_PACKET IPPacket,
UINT DataSize)
/*
* FUNCTION: Delivers UDP data to a user
* ARGUMENTS:
* AddrFile = Address file to deliver data to
* Address = Remote address the packet came from
* IPPacket = Pointer to IP packet to deliver
* DataSize = Number of bytes in data area
* NOTES:
* If there is a receive request, then we copy the data to the
* buffer supplied by the user and complete the receive request.
* If no suitable receive request exists, then we call the event
* handler if it exists, otherwise we drop the packet.
*/
{
KIRQL OldIrql;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (!IsListEmpty(&AddrFile->ReceiveQueue)) {
PLIST_ENTRY CurrentEntry;
PDATAGRAM_RECEIVE_REQUEST Current;
BOOLEAN Found;
/* Search receive request list to find a match */
Found = FALSE;
CurrentEntry = AddrFile->ReceiveQueue.Flink;
while ((CurrentEntry != &AddrFile->ReceiveQueue) && (!Found)) {
Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
if (!Current->RemoteAddress)
Found = TRUE;
else if (AddrIsEqual(Address, Current->RemoteAddress))
Found = TRUE;
if (Found) {
/* FIXME: Maybe we should check if the buffer of this
receive request is large enough and if not, search
for another. Also a 'best fit' strategy could be used. */
/* Remove the request from the queue */
RemoveEntryList(&Current->ListEntry);
AddrFile->RefCount--;
break;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
if (Found) {
/* Copy the data into buffer provided by the user */
CopyBufferToBufferChain(Current->Buffer,
0,
IPPacket->Data,
DataSize);
/* Complete the receive request */
(*Current->Complete)(Current->Context, STATUS_SUCCESS, DataSize);
/* Finally free the receive request */
if (Current->RemoteAddress)
PoolFreeBuffer(Current->RemoteAddress);
PoolFreeBuffer(Current);
}
} else {
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* FIXME: Call event handler */
TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n"));
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
NTSTATUS UDPSendDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG DataSize)
/*
* FUNCTION: Sends an UDP datagram to a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer with data
* DataSize = Size in bytes of data to be sent
* RETURNS:
* Status of operation
*/
{
return DGSendDatagram(Request,
ConnInfo,
Buffer,
DataSize,
BuildUDPPacket);
}
NTSTATUS UDPReceiveDatagram(
PTDI_REQUEST Request,
PTDI_CONNECTION_INFORMATION ConnInfo,
PNDIS_BUFFER Buffer,
ULONG ReceiveLength,
ULONG ReceiveFlags,
PTDI_CONNECTION_INFORMATION ReturnInfo,
PULONG BytesReceived)
/*
* FUNCTION: Attempts to receive an UDP datagram from a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
* Buffer = Pointer to NDIS buffer chain to store received data
* ReceiveLength = Maximum size to use of buffer, 0 if all can be used
* ReceiveFlags = Receive flags (None, Normal, Peek)
* ReturnInfo = Pointer to structure for return information
* BytesReceive = Pointer to structure for number of bytes received
* RETURNS:
* Status of operation
* NOTES:
* This is the high level interface for receiving UDP datagrams
*/
{
return DGReceiveDatagram(Request,
ConnInfo,
Buffer,
ReceiveLength,
ReceiveFlags,
ReturnInfo,
BytesReceived);
}
VOID UDPReceive(
PNET_TABLE_ENTRY NTE,
PIP_PACKET IPPacket)
/*
* FUNCTION: Receives and queues a UDP datagram
* ARGUMENTS:
* NTE = Pointer to net table entry which the packet was received on
* IPPacket = Pointer to an IP packet that was received
* NOTES:
* This is the low level interface for receiving UDP datagrams. It strips
* the UDP header from a packet and delivers the data to anyone that wants it
*/
{
AF_SEARCH SearchContext;
PIPv4_HEADER IPv4Header;
PADDRESS_FILE AddrFile;
PUDP_HEADER UDPHeader;
PIP_ADDRESS DstAddress;
UINT DataSize, i;
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
switch (IPPacket->Type) {
/* IPv4 packet */
case IP_ADDRESS_V4:
IPv4Header = IPPacket->Header;
DstAddress = &IPPacket->DstAddr;
break;
/* IPv6 packet */
case IP_ADDRESS_V6:
TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 UDP datagram (%i bytes).\n", IPPacket->TotalSize));
/* FIXME: IPv6 is not supported */
return;
}
UDPHeader = (PUDP_HEADER)IPPacket->Data;
/* FIXME: Calculate and validate UDP checksum */
/* Sanity checks */
i = WH2N(UDPHeader->Length);
if ((i < sizeof(UDP_HEADER)) || (i > IPPacket->TotalSize - IPPacket->Position)) {
/* Incorrect or damaged packet received, discard it */
TI_DbgPrint(MIN_TRACE, ("Incorrect or damaged UDP packet received.\n"));
return;
}
DataSize = i - sizeof(UDP_HEADER);
/* Go to UDP data area */
(ULONG_PTR)IPPacket->Data += sizeof(UDP_HEADER);
/* Locate a receive request on destination address file object
and deliver the packet if one is found. If there is no receive
request on the address file object, call the associated receive
handler. If no receive handler is registered, drop the packet */
AddrFile = AddrSearchFirst(DstAddress,
UDPHeader->DestPort,
IPPROTO_UDP,
&SearchContext);
if (AddrFile) {
do {
DeliverUDPData(AddrFile,
DstAddress,
IPPacket,
DataSize);
} while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
} else {
/* There are no open address files that will take this datagram */
/* FIXME: IPv4 only */
TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 UDP datagram to address (0x%X).\n",
DN2H(DstAddress->Address.IPv4Address)));
/* FIXME: Send ICMP reply */
}
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
NTSTATUS UDPStartup(
VOID)
/*
* FUNCTION: Initializes the UDP subsystem
* RETURNS:
* Status of operation
*/
{
RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS));
/* Register this protocol with IP layer */
IPRegisterProtocol(IPPROTO_UDP, UDPReceive);
UDPInitialized = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS UDPShutdown(
VOID)
/*
* FUNCTION: Shuts down the UDP subsystem
* RETURNS:
* Status of operation
*/
{
if (!UDPInitialized)
return STATUS_SUCCESS;
/* Deregister this protocol with IP layer */
IPRegisterProtocol(IPPROTO_UDP, NULL);
return STATUS_SUCCESS;
}
/* EOF */
+1
View File
@@ -0,0 +1 @@
DIRS= tditest
@@ -0,0 +1,90 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TDI test driver
* FILE: include/debug.h
* PURPOSE: Debugging support macros
* DEFINES: DBG - Enable debug output
* NASSERT - Disable assertions
*/
#ifndef __DEBUG_H
#define __DEBUG_H
#define NORMAL_MASK 0x000000FF
#define SPECIAL_MASK 0xFFFFFF00
#define MIN_TRACE 0x00000001
#define MID_TRACE 0x00000002
#define MAX_TRACE 0x00000003
#define DEBUG_ULTRA 0xFFFFFFFF
#ifdef DBG
extern DWORD DebugTraceLevel;
#ifdef _MSC_VER
#define TDI_DbgPrint(_t_, _x_) \
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
DbgPrint("(%s:%d) ", __FILE__, __LINE__); \
DbgPrint _x_ ; \
}
#else /* _MSC_VER */
#define TDI_DbgPrint(_t_, _x_) \
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
DbgPrint("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
DbgPrint _x_ ; \
}
#endif /* _MSC_VER */
#ifdef ASSERT
#undef ASSERT
#endif
#ifdef NASSERT
#define ASSERT(x)
#else /* NASSERT */
#define ASSERT(x) if (!(x)) { TDI_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
#endif /* NASSERT */
#define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
#else /* DBG */
#define TDI_DbgPrint(_t_, _x_)
#define ASSERT_IRQL(x)
#define ASSERT(x)
#endif /* DBG */
#define assert(x) ASSERT(x)
#define assert_irql(x) ASSERT_IRQL(x)
#ifdef _MSC_VER
#define UNIMPLEMENTED \
TDI_DbgPrint(MIN_TRACE, ("The function at %s:%d is unimplemented, \
but come back another day.\n", __FILE__, __LINE__));
#else /* _MSC_VER */
#define UNIMPLEMENTED \
TDI_DbgPrint(MIN_TRACE, ("%s at %s:%d is unimplemented, \
but come back another day.\n", __FUNCTION__, __FILE__, __LINE__));
#endif /* _MSC_VER */
#define CHECKPOINT \
do { TDI_DbgPrint(MIN_TRACE, ("%s:%d\n", __FILE__, __LINE__)); } while(0);
#endif /* __DEBUG_H */
/* EOF */
@@ -0,0 +1,131 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TDI test driver
* FILE: include/tditest.h
* PURPOSE: Testing TDI drivers
*/
#ifndef __TDITEST_H
#define __TDITEST_H
#ifdef _MSC_VER
#include <basetsd.h>
#include <ntddk.h>
#include <windef.h>
#include <tdikrnl.h>
#include <tdiinfo.h>
#else
#include <ddk/ntddk.h>
#include <net/tdikrnl.h>
#include <net/tdiinfo.h>
#endif
#include <debug.h>
/* Name of UDP device */
//#define UDP_DEVICE_NAME L"\\Device\\Udp"
#define UDP_DEVICE_NAME L"\\Device\\NTUdp"
#ifdef i386
/* DWORD network to host byte order conversion for i386 */
#define DN2H(dw) \
((((dw) & 0xFF000000L) >> 24) | \
(((dw) & 0x00FF0000L) >> 8) | \
(((dw) & 0x0000FF00L) << 8) | \
(((dw) & 0x000000FFL) << 24))
/* DWORD host to network byte order conversion for i386 */
#define DH2N(dw) \
((((dw) & 0xFF000000L) >> 24) | \
(((dw) & 0x00FF0000L) >> 8) | \
(((dw) & 0x0000FF00L) << 8) | \
(((dw) & 0x000000FFL) << 24))
/* WORD network to host order conversion for i386 */
#define WN2H(w) \
((((w) & 0xFF00) >> 8) | \
(((w) & 0x00FF) << 8))
/* WORD host to network byte order conversion for i386 */
#define WH2N(w) \
((((w) & 0xFF00) >> 8) | \
(((w) & 0x00FF) << 8))
#else /* i386 */
/* DWORD network to host byte order conversion for other architectures */
#define DN2H(dw) \
(dw)
/* DWORD host to network byte order conversion for other architectures */
#define DH2N(dw) \
(dw)
/* WORD network to host order conversion for other architectures */
#define WN2H(w) \
(w)
/* WORD host to network byte order conversion for other architectures */
#define WH2N(w) \
(w)
#endif /* i386 */
typedef struct IPSNMP_INFO {
ULONG Forwarding;
ULONG DefaultTTL;
ULONG InReceives;
ULONG InHdrErrors;
ULONG InAddrErrors;
ULONG ForwDatagrams;
ULONG InUnknownProtos;
ULONG InDiscards;
ULONG InDelivers;
ULONG OutRequests;
ULONG RoutingDiscards;
ULONG OutDiscards;
ULONG OutNoRoutes;
ULONG ReasmTimeout;
ULONG ReasmReqds;
ULONG ReasmOks;
ULONG ReasmFails;
ULONG FragOks;
ULONG FragFails;
ULONG FragCreates;
ULONG NumIf;
ULONG NumAddr;
ULONG NumRoutes;
} IPSNMP_INFO, *PIPSNMP_INFO;
typedef struct IPADDR_ENTRY {
ULONG Addr;
ULONG Index;
ULONG Mask;
ULONG BcastAddr;
ULONG ReasmSize;
USHORT Context;
USHORT Pad;
} IPADDR_ENTRY, *PIPADDR_ENTRY;
#define TL_INSTANCE 0
#define IP_MIB_STATS_ID 0x1
#define IP_MIB_ADDRTABLE_ENTRY_ID 0x102
/* IOCTL codes */
#define IOCTL_TCP_QUERY_INFORMATION_EX \
CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_TCP_SET_INFORMATION_EX \
CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define TEST_PORT 2000
#endif /*__TDITEST_H */
/* EOF */
+84
View File
@@ -0,0 +1,84 @@
# TDITEST.SYS - TDI test driver
TARGETNAME=tditest
BASE_CFLAGS = -I./include -I../../../include
RESOURCE_OBJECT = $(TARGETNAME).coff
TDITEST_OBJECTS = tditest/tditest.o
all: objects $(TARGETNAME).sys
objects:
mkdir objects
$(TARGETNAME).coff: $(TARGETNAME).rc ../../../include/reactos/resource.h
OBJECTS = $(TDITEST_OBJECTS) $(RESOURCE_OBJECT) ../../../ntoskrnl/ntoskrnl.a
ifeq ($(DOSCLI),yes)
CLEAN_FILES = *.o objects\*.o tditest\*.o $(TARGETNAME).coff $(TARGETNAME).o \
junk.tmp base.tmp temp.exp $(TARGETNAME).sys $(TARGETNAME).sym
else
CLEAN_FILES = *.o objects/*.o tditest/*.o $(TARGETNAME).coff $(TARGETNAME).o \
junk.tmp base.tmp temp.exp $(TARGETNAME).sys $(TARGETNAME).sym
endif
$(TARGETNAME).sys: $(OBJECTS)
$(CC) \
-mdll \
-specs=../../svc_specs \
-Wl,-e,_DriverEntry@8 \
-Wl,--base-file,base.tmp \
-Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ \
-Wl,--defsym,_etext=etext \
$(OBJECTS) \
-o junk.tmp
- $(RM) junk.tmp
$(DLLTOOL) \
--dllname $(TARGETNAME).sys \
--base-file base.tmp \
--output-exp temp.exp
- $(RM) base.tmp
$(CC) \
-mdll \
-specs=../../svc_specs \
-Wl,--image-base,0x10000 \
-Wl,-e,_DriverEntry@8 \
-Wl,temp.exp \
$(OBJECTS) \
-o $(TARGETNAME).sys
- $(RM) temp.exp
$(NM) --numeric-sort $(TARGETNAME).sys > $(TARGETNAME).sym
clean: $(CLEAN_FILES:%=%_clean)
$(CLEAN_FILES:%=%_clean): %_clean:
- $(RM) $*
.PHONY: clean $(CLEAN_FILES:%=%_clean)
floppy: $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
$(FLOPPY_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)\drivers\$(TARGETNAME).sys
else
$(CP) $(TARGETNAME).sys $(FLOPPY_DIR)/drivers/$(TARGETNAME).sys
endif
dist: $(DIST_DIR)/drivers/$(TARGETNAME).sys
$(DIST_DIR)/drivers/$(TARGETNAME).sys: $(TARGETNAME).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGETNAME).sys ..\..\$(DIST_DIR)\drivers\$(TARGETNAME).sys
else
$(CP) $(TARGETNAME).sys ../../$(DIST_DIR)/drivers/$(TARGETNAME).sys
endif
#WITH_DEBUGGING = yes
#WIN32_LEAN_AND_MEAN = yes
#WARNINGS_ARE_ERRORS = yes
include ../../../rules.mak
+18
View File
@@ -0,0 +1,18 @@
Build instructions for TDITEST driver
-------------------------------------
Building with Visual C++ and Windows NT DDK:
Variables:
%BASEDIR% = path to NT4 DDK (e.g. c:\ntddk)
%DDKBUILDENV% = DDK build environment (free or checked)
DDK environment variables must be set! (run setenv.bat)
- Create the directory objects/i386/%DDKBUILDENV%
- Run "build" to build the driver
Building with Mingw32 and ReactOS include files:
- Run "make tditest" FROM THE ReactOS ROOT DIRECTORY to build the driver
+7
View File
@@ -0,0 +1,7 @@
; TDI test driver - ReactOS Operating System
LIBRARY TDITEST.SYS
EXPORTS
; EOF
+38
View File
@@ -0,0 +1,38 @@
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "TDI test driver\0"
VALUE "FileVersion", "0.0.0\0"
VALUE "InternalName", "tditest\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "tditest.sys\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
@@ -0,0 +1,8 @@
# MAKEFILE for ARTICLE
#
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
# file to this component. This file merely indirects to the real make file
# that is shared by all the driver components of the Windows NT DDK
#
!INCLUDE $(NTMAKEENV)\makefile.def
@@ -0,0 +1,14 @@
TARGETNAME=tditest
TARGETPATH=..\objects
TARGETTYPE=DRIVER
TARGETLIBS=$(DDK_LIB_PATH)\tdi.lib \
$(DDK_LIB_PATH)\ndis.lib
C_DEFINES=$(C_DEFINES) -DDBG
INCLUDES=..\include;..\..\..\..\include\net;$(BASEDIR)\inc
SOURCES= tditest.c
MSC_WARNING_LEVEL=/W3 /WX
@@ -0,0 +1,947 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TDI test driver
* FILE: tditest.c
* PURPOSE: Testing TDI drivers
* PROGRAMMERS: Casper S. Hornstrup ([email protected])
* REVISIONS:
* CSH 01/08-2000 Created
*/
#include <tditest.h>
#ifdef DBG
/* See debug.h for debug/trace constants */
DWORD DebugTraceLevel = MIN_TRACE;
#endif /* DBG */
HANDLE TdiTransport = 0;
PFILE_OBJECT TdiTransportObject = NULL;
ULONG LocalAddress;
BOOLEAN OpenError;
KEVENT StopEvent;
HANDLE SendThread;
KEVENT SendThreadEvent;
HANDLE ReceiveThread;
KEVENT ReceiveThreadEvent;
PVOID ReceiveThreadObject;
PVOID SendThreadObject;
NTSTATUS TdiCall(
PIRP Irp,
PDEVICE_OBJECT DeviceObject,
PIO_STATUS_BLOCK IoStatusBlock,
BOOLEAN CanCancel)
/*
* FUNCTION: Calls a transport driver device
* ARGUMENTS:
* Irp = Pointer to I/O Request Packet
* DeviceObject = Pointer to device object to call
* IoStatusBlock = Address of buffer with I/O status block
* CanCancel = TRUE if the IRP can be cancelled, FALSE if not
* RETURNS:
* Status of operation
* NOTES
* All requests are completed synchronously. A request may be cancelled
*/
{
KEVENT Event;
PKEVENT Events[2];
NTSTATUS Status;
Events[0] = &StopEvent;
Events[1] = &Event;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
Irp->UserEvent = &Event;
Irp->UserIosb = IoStatusBlock;
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) {
if (CanCancel) {
Status = KeWaitForMultipleObjects(2,
(PVOID)&Events,
WaitAny,
Executive,
KernelMode,
FALSE,
NULL,
NULL);
if (KeReadStateEvent(&StopEvent) != 0) {
if (IoCancelIrp(Irp)) {
TDI_DbgPrint(MAX_TRACE, ("Cancelled IRP.\n"));
} else {
TDI_DbgPrint(MIN_TRACE, ("Could not cancel IRP.\n"));
}
return STATUS_CANCELLED;
}
} else
Status = KeWaitForSingleObject(&Event,
Executive,
KernelMode,
FALSE,
NULL);
}
return (Status == STATUS_SUCCESS)? IoStatusBlock->Status : STATUS_SUCCESS;
}
NTSTATUS TdiOpenDevice(
PWSTR Protocol,
ULONG EaLength,
PFILE_FULL_EA_INFORMATION EaInfo,
PHANDLE Handle,
PFILE_OBJECT *Object)
/*
* FUNCTION: Opens a device
* ARGUMENTS:
* Protocol = Pointer to buffer with name of device
* EaLength = Length of EA information
* EaInfo = Pointer to buffer with EA information
* Handle = Address of buffer to place device handle
* Object = Address of buffer to place device object
* RETURNS:
* Status of operation
*/
{
OBJECT_ATTRIBUTES Attr;
IO_STATUS_BLOCK Iosb;
UNICODE_STRING Name;
NTSTATUS Status;
RtlInitUnicodeString(&Name, Protocol);
InitializeObjectAttributes(&Attr, /* Attribute buffer */
&Name, /* Device name */
OBJ_CASE_INSENSITIVE, /* Attributes */
NULL, /* Root directory */
NULL); /* Security descriptor */
Status = ZwCreateFile(Handle, /* Return file handle */
GENERIC_READ | GENERIC_WRITE, /* Desired access */
&Attr, /* Object attributes */
&Iosb, /* IO status */
0, /* Initial allocation size */
FILE_ATTRIBUTE_NORMAL, /* File attributes */
FILE_SHARE_READ | FILE_SHARE_WRITE, /* Share access */
FILE_OPEN_IF, /* Create disposition */
0, /* Create options */
EaInfo, /* EA buffer */
EaLength); /* EA length */
if (NT_SUCCESS(Status)) {
Status = ObReferenceObjectByHandle(*Handle, /* Handle to open file */
GENERIC_READ | GENERIC_WRITE, /* Access mode */
NULL, /* Object type */
KernelMode, /* Access mode */
(PVOID*)Object, /* Pointer to object */
NULL); /* Handle information */
if (!NT_SUCCESS(Status)) {
TDI_DbgPrint(MIN_TRACE, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status));
ZwClose(*Handle);
}
} else {
TDI_DbgPrint(MIN_TRACE, ("ZwCreateFile() failed with status (0x%X)\n", Status));
}
return Status;
}
NTSTATUS TdiCloseDevice(
HANDLE Handle,
PFILE_OBJECT FileObject)
{
if (FileObject)
ObDereferenceObject(FileObject);
if (Handle)
ZwClose(Handle);
return STATUS_SUCCESS;
}
NTSTATUS TdiOpenTransport(
PWSTR Protocol,
USHORT Port,
PHANDLE Transport,
PFILE_OBJECT *TransportObject)
/*
* FUNCTION: Opens a transport driver
* ARGUMENTS:
* Protocol = Pointer to buffer with name of device
* Port = Port number to use
* Transport = Address of buffer to place transport device handle
* TransportObject = Address of buffer to place transport object
* RETURNS:
* Status of operation
*/
{
PFILE_FULL_EA_INFORMATION EaInfo;
PTA_ADDRESS_IP Address;
NTSTATUS Status;
ULONG EaLength;
EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
sizeof(TdiTransportAddress) +
sizeof(TA_ADDRESS_IP) + 1;
EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
if (!EaInfo) {
TDI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(EaInfo, EaLength);
EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
RtlCopyMemory (EaInfo->EaName,
TdiTransportAddress,
sizeof(TdiTransportAddress));
EaInfo->EaValueLength = sizeof(TA_ADDRESS_IP);
Address = (PTA_ADDRESS_IP)(EaInfo->EaName + sizeof(TdiTransportAddress));
Address->TAAddressCount = 1;
Address->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
Address->Address[0].Address[0].sin_port = WH2N(Port);
Address->Address[0].Address[0].in_addr = 0;
Status = TdiOpenDevice(Protocol,
EaLength,
EaInfo,
Transport,
TransportObject);
ExFreePool(EaInfo);
return Status;
}
NTSTATUS TdiQueryDeviceControl(
PFILE_OBJECT FileObject,
ULONG IoControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG Return)
/*
* FUNCTION: Queries a device for information
* ARGUMENTS:
* FileObject = Pointer to device object
* IoControlCode = I/O control code
* InputBuffer = Pointer to buffer with input data
* InputBufferLength = Length of InputBuffer
* OutputBuffer = Address of buffer to place output data
* OutputBufferLength = Length of OutputBuffer
* RETURNS:
* Status of operation
*/
{
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION IoStack;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
PIRP Irp;
DeviceObject = IoGetRelatedDeviceObject(FileObject);
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
DeviceObject,
InputBuffer,
InputBufferLength,
OutputBuffer,
OutputBufferLength,
FALSE,
NULL,
NULL);
if (!Irp) {
TDI_DbgPrint(MIN_TRACE, ("IoBuildDeviceIoControlRequest() failed.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
IoStack = IoGetNextIrpStackLocation(Irp);
IoStack->DeviceObject = DeviceObject;
IoStack->FileObject = FileObject;
Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE);
if (Return)
*Return = Iosb.Information;
return Status;
}
NTSTATUS TdiQueryInformationEx(
PFILE_OBJECT FileObject,
ULONG Entity,
ULONG Instance,
ULONG Class,
ULONG Type,
ULONG Id,
PVOID OutputBuffer,
PULONG OutputLength)
/*
* FUNCTION: Extended query for information
* ARGUMENTS:
* FileObject = Pointer to transport object
* Entity = Entity
* Instance = Instance
* Class = Entity class
* Type = Entity type
* Id = Entity id
* OutputBuffer = Address of buffer to place data
* OutputLength = Address of buffer with length of OutputBuffer (updated)
* RETURNS:
* Status of operation
*/
{
TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo;
RtlZeroMemory(&QueryInfo, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
QueryInfo.ID.toi_entity.tei_entity = Entity;
QueryInfo.ID.toi_entity.tei_instance = Instance;
QueryInfo.ID.toi_class = Class;
QueryInfo.ID.toi_type = Type;
QueryInfo.ID.toi_id = Id;
return TdiQueryDeviceControl(FileObject, /* Transport/connection object */
IOCTL_TCP_QUERY_INFORMATION_EX, /* Control code */
&QueryInfo, /* Input buffer */
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), /* Input buffer length */
OutputBuffer, /* Output buffer */
*OutputLength, /* Output buffer length */
OutputLength); /* Return information */
}
NTSTATUS TdiQueryAddress(
PFILE_OBJECT FileObject,
PULONG Address)
/*
* FUNCTION: Queries for a local IP address
* ARGUMENTS:
* FileObject = Pointer to file object
* Address = Address of buffer to place local address
* RETURNS:
* Status of operation
*/
{
UINT i;
TDIEntityID *Entities;
ULONG EntityCount;
ULONG EntityType;
IPSNMP_INFO SnmpInfo;
PIPADDR_ENTRY IpAddress;
ULONG BufferSize;
NTSTATUS Status = STATUS_SUCCESS;
TDI_DbgPrint(MAX_TRACE, ("Called\n"));
BufferSize = sizeof(TDIEntityID) * 20;
Entities = (TDIEntityID*)ExAllocatePool(NonPagedPool, BufferSize);
if (!Entities) {
TDI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Query device for supported entities */
Status = TdiQueryInformationEx(FileObject, /* File object */
GENERIC_ENTITY, /* Entity */
TL_INSTANCE, /* Instance */
INFO_CLASS_GENERIC, /* Entity class */
INFO_TYPE_PROVIDER, /* Entity type */
ENTITY_LIST_ID, /* Entity id */
Entities, /* Output buffer */
&BufferSize); /* Output buffer size */
if (!NT_SUCCESS(Status)) {
TDI_DbgPrint(MIN_TRACE, ("Unable to get list of supported entities (Status = 0x%X).\n", Status));
ExFreePool(Entities);
return Status;
}
/* Locate an IP entity */
EntityCount = BufferSize / sizeof(TDIEntityID);
TDI_DbgPrint(MAX_TRACE, ("EntityCount = %d\n", EntityCount));
for (i = 0; i < EntityCount; i++) {
if (Entities[i].tei_entity == CL_NL_ENTITY) {
/* Query device for entity type */
BufferSize = sizeof(EntityType);
Status = TdiQueryInformationEx(FileObject, /* File object */
CL_NL_ENTITY, /* Entity */
Entities[i].tei_instance, /* Instance */
INFO_CLASS_GENERIC, /* Entity class */
INFO_TYPE_PROVIDER, /* Entity type */
ENTITY_TYPE_ID, /* Entity id */
&EntityType, /* Output buffer */
&BufferSize); /* Output buffer size */
if (!NT_SUCCESS(Status) || (EntityType != CL_NL_IP)) {
TDI_DbgPrint(MIN_TRACE, ("Unable to get entity of type IP (Status = 0x%X).\n", Status));
break;
}
/* Query device for SNMP information */
BufferSize = sizeof(SnmpInfo);
Status = TdiQueryInformationEx(FileObject, /* File object */
CL_NL_ENTITY, /* Entity */
Entities[i].tei_instance, /* Instance */
INFO_CLASS_PROTOCOL, /* Entity class */
INFO_TYPE_PROVIDER, /* Entity type */
IP_MIB_STATS_ID, /* Entity id */
&SnmpInfo, /* Output buffer */
&BufferSize); /* Output buffer size */
if (!NT_SUCCESS(Status) || (SnmpInfo.NumAddr == 0)) {
TDI_DbgPrint(MIN_TRACE, ("Unable to get SNMP information or no IP addresses available (Status = 0x%X).\n", Status));
break;
}
/* Query device for all IP addresses */
if (SnmpInfo.NumAddr != 0) {
BufferSize = SnmpInfo.NumAddr * sizeof(IPADDR_ENTRY);
IpAddress = (PIPADDR_ENTRY)ExAllocatePool(NonPagedPool, BufferSize);
if (!IpAddress) {
TDI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
break;
}
Status = TdiQueryInformationEx(FileObject, /* File object */
CL_NL_ENTITY, /* Entity */
Entities[i].tei_instance, /* Instance */
INFO_CLASS_PROTOCOL, /* Entity class */
INFO_TYPE_PROVIDER, /* Entity type */
IP_MIB_ADDRTABLE_ENTRY_ID, /* Entity id */
IpAddress, /* Output buffer */
&BufferSize); /* Output buffer size */
if (!NT_SUCCESS(Status)) {
TDI_DbgPrint(MIN_TRACE, ("Unable to get IP address (Status = 0x%X).\n", Status));
ExFreePool(IpAddress);
break;
}
/* Select the first address returned */
*Address = DN2H(IpAddress->Addr);
ExFreePool(IpAddress);
} else {
Status = STATUS_UNSUCCESSFUL;
break;
}
}
}
ExFreePool(Entities);
TDI_DbgPrint(MAX_TRACE, ("Leaving\n"));
return Status;
}
NTSTATUS TdiSendDatagram(
PFILE_OBJECT TransportObject,
USHORT Port,
ULONG Address,
PVOID Buffer,
ULONG BufferSize)
/*
* FUNCTION: Sends a datagram
* ARGUMENTS:
* TransportObject = Pointer to transport object
* Port = Remote port
* Address = Remote address
* Buffer = Pointer to buffer with data to send
* BufferSize = Length of Buffer
* RETURNS:
* Status of operation
*/
{
PIRP Irp;
PMDL Mdl;
PDEVICE_OBJECT DeviceObject;
PTDI_CONNECTION_INFORMATION ConnectInfo;
PTA_ADDRESS_IP TA;
PTDI_ADDRESS_IP IpAddress;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
ConnectInfo = (PTDI_CONNECTION_INFORMATION)
ExAllocatePool(NonPagedPool,
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TA_ADDRESS_IP));
if (!ConnectInfo)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(ConnectInfo,
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TA_ADDRESS_IP));
ConnectInfo->RemoteAddressLength = sizeof(TA_ADDRESS_IP);
ConnectInfo->RemoteAddress = (PUCHAR)
((ULONG)ConnectInfo + sizeof(TDI_CONNECTION_INFORMATION));
TA = (PTA_ADDRESS_IP)(ConnectInfo->RemoteAddress);
TA->TAAddressCount = 1;
TA->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
TA->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
IpAddress = (PTDI_ADDRESS_IP)(TA->Address[0].Address);
IpAddress->sin_port = WH2N(Port);
IpAddress->in_addr = DH2N(Address);
Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND_DATAGRAM, /* Sub function */
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Event */
NULL); /* Return buffer */
if (!Irp) {
TDI_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
ExFreePool(ConnectInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
Mdl = IoAllocateMdl(Buffer, /* Virtual address of buffer */
BufferSize, /* Length of buffer */
FALSE, /* Not secondary */
FALSE, /* Don't charge quota */
NULL); /* Don't use IRP */
if (!Mdl) {
TDI_DbgPrint(MIN_TRACE, ("IoAllocateMdl() failed.\n"));
IoFreeIrp(Irp);
ExFreePool(ConnectInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
#ifdef _MSC_VER
try {
#endif
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
#ifdef _MSC_VER
} except(EXCEPTION_EXECUTE_HANDLER) {
TDI_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
IoFreeMdl(Mdl);
IoFreeIrp(Irp);
ExFreePool(ConnectInfo);
return STATUS_UNSUCCESSFUL;
}
#endif
TdiBuildSendDatagram(Irp, /* I/O Request Packet */
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Completion routine */
NULL, /* Completion context */
Mdl, /* Descriptor for data buffer */
BufferSize, /* Size of data to send */
ConnectInfo); /* Connection information */
Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE);
ExFreePool(ConnectInfo);
return Status;
}
NTSTATUS TdiReceiveDatagram(
PFILE_OBJECT TransportObject,
USHORT Port,
PULONG Address,
PUCHAR Buffer,
PULONG BufferSize)
/*
* FUNCTION: Receives a datagram
* ARGUMENTS:
* TransportObject = Pointer to transport object
* Port = Port to receive on
* Address = Address of buffer to place remote address
* Buffer = Address of buffer to place received data
* BufferSize = Address of buffer with length of Buffer (updated)
* RETURNS:
* Status of operation
*/
{
PTDI_CONNECTION_INFORMATION ReceiveInfo;
PTDI_CONNECTION_INFORMATION ReturnInfo;
PTA_ADDRESS_IP ReturnAddress;
PDEVICE_OBJECT DeviceObject;
PTDI_ADDRESS_IP IpAddress;
IO_STATUS_BLOCK Iosb;
PVOID MdlBuffer;
NTSTATUS Status;
PIRP Irp;
PMDL Mdl;
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject)
return STATUS_INVALID_PARAMETER;
ReceiveInfo = (PTDI_CONNECTION_INFORMATION)
ExAllocatePool(NonPagedPool,
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TA_ADDRESS_IP));
if (!ReceiveInfo)
return STATUS_INSUFFICIENT_RESOURCES;
MdlBuffer = ExAllocatePool(PagedPool, *BufferSize);
if (!MdlBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(ReceiveInfo,
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TA_ADDRESS_IP));
RtlCopyMemory(MdlBuffer, Buffer, *BufferSize);
/* Receive from any address */
ReceiveInfo->RemoteAddressLength = 0;
ReceiveInfo->RemoteAddress = NULL;
ReturnInfo = (PTDI_CONNECTION_INFORMATION)
((ULONG)ReceiveInfo + sizeof(TDI_CONNECTION_INFORMATION));
ReturnInfo->RemoteAddressLength = sizeof(TA_ADDRESS_IP);
ReturnInfo->RemoteAddress = (PUCHAR)
((ULONG)ReturnInfo + sizeof(TDI_CONNECTION_INFORMATION));
ReturnAddress = (PTA_ADDRESS_IP)(ReturnInfo->RemoteAddress);
ReturnAddress->TAAddressCount = 1;
ReturnAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
ReturnAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
IpAddress = (PTDI_ADDRESS_IP)(ReturnAddress->Address[0].Address);
IpAddress->sin_port = WH2N(Port);
IpAddress->in_addr = DH2N(LocalAddress);
Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE_DATAGRAM, /* Sub function */
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Event */
NULL); /* Return buffer */
if (!Irp) {
ExFreePool(MdlBuffer);
ExFreePool(ReceiveInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
Mdl = IoAllocateMdl(MdlBuffer, /* Virtual address */
*BufferSize, /* Length of buffer */
FALSE, /* Not secondary */
FALSE, /* Don't charge quota */
NULL); /* Don't use IRP */
if (!Mdl) {
IoFreeIrp(Irp);
ExFreePool(MdlBuffer);
ExFreePool(ReceiveInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
#ifdef _MSC_VER
try {
#endif
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
#ifdef _MSC_VER
} except (EXCEPTION_EXECUTE_HANDLER) {
TDI_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
IoFreeMdl(Mdl);
IoFreeIrp(Irp);
ExFreePool(MdlBuffer);
ExFreePool(ReceiveInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
#endif
TdiBuildReceiveDatagram(Irp, /* I/O Request Packet */
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Completion routine */
NULL, /* Completion context */
Mdl, /* Data buffer */
*BufferSize, /* Size of data buffer */
ReceiveInfo, /* Connection information */
ReturnInfo, /* Connection information */
TDI_RECEIVE_NORMAL); /* Flags */
Status = TdiCall(Irp, DeviceObject, &Iosb, TRUE);
if (NT_SUCCESS(Status)) {
RtlCopyMemory(Buffer, MdlBuffer, Iosb.Information);
*BufferSize = Iosb.Information;
*Address = DN2H(IpAddress->in_addr);
}
ExFreePool(MdlBuffer);
ExFreePool(ReceiveInfo);
return Status;
}
VOID TdiSendThread(
PVOID Context)
/*
* FUNCTION: Send thread
* ARGUMENTS:
* Context = Pointer to context information
* NOTES:
* Transmits an UDP packet every two seconds to ourselves on the chosen port
*/
{
KEVENT Event;
PKEVENT Events[2];
LARGE_INTEGER Timeout;
NTSTATUS Status = STATUS_SUCCESS;
UCHAR Data[40] = "Testing one, two, three, ...";
if (!OpenError) {
Timeout.QuadPart = 10000000L; /* Second factor */
Timeout.QuadPart *= 2; /* Number of seconds */
Timeout.QuadPart = -(Timeout.QuadPart); /* Relative time */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
Events[0] = &StopEvent;
Events[1] = &Event;
while (NT_SUCCESS(Status)) {
/* Wait until timeout or stop flag is set */
KeWaitForMultipleObjects(
2,
(PVOID)&Events,
WaitAny,
Executive,
KernelMode,
FALSE,
&Timeout,
NULL);
if (KeReadStateEvent(&StopEvent) != 0) {
TDI_DbgPrint(MAX_TRACE, ("Received terminate signal...\n"));
break;
}
DbgPrint("Sending data - '%s'\n", Data);
Status = TdiSendDatagram(TdiTransportObject,
TEST_PORT,
LocalAddress,
Data,
sizeof(Data));
if (!NT_SUCCESS(Status))
DbgPrint("Failed sending data (Status = 0x%X)\n", Status);
}
}
TDI_DbgPrint(MAX_TRACE, ("Terminating send thread...\n"));
KeSetEvent(&SendThreadEvent, 0, FALSE);
PsTerminateSystemThread(STATUS_SUCCESS);
}
VOID TdiReceiveThread(
PVOID Context)
/*
* FUNCTION: Receive thread
* ARGUMENTS:
* Context = Pointer to context information
* NOTES:
* Waits until an UDP packet is received on the chosen endpoint and displays the data
*/
{
ULONG Address;
UCHAR Data[40];
ULONG Size;
NTSTATUS Status = STATUS_SUCCESS;
if (!OpenError) {
while (NT_SUCCESS(Status)) {
Size = sizeof(Data);
RtlZeroMemory(Data, Size);
Status = TdiReceiveDatagram(TdiTransportObject,
TEST_PORT,
&Address,
Data,
&Size);
if (NT_SUCCESS(Status)) {
DbgPrint("Received data - '%s'\n", Data);
} else
if (Status != STATUS_CANCELLED) {
TDI_DbgPrint(MIN_TRACE, ("Receive error (Status = 0x%X).\n", Status));
} else {
TDI_DbgPrint(MAX_TRACE, ("IRP was cancelled.\n"));
}
}
}
TDI_DbgPrint(MAX_TRACE, ("Terminating receive thread...\n"));
KeSetEvent(&ReceiveThreadEvent, 0, FALSE);
PsTerminateSystemThread(STATUS_SUCCESS);
}
VOID TdiOpenThread(
PVOID Context)
/*
* FUNCTION: Open thread
* ARGUMENTS:
* Context = Pointer to context information (event)
*/
{
NTSTATUS Status;
TDI_DbgPrint(MAX_TRACE, ("Called.\n"));
OpenError = TRUE;
Status = TdiOpenTransport(UDP_DEVICE_NAME,
TEST_PORT,
&TdiTransport,
&TdiTransportObject);
if (NT_SUCCESS(Status)) {
Status = TdiQueryAddress(TdiTransportObject, &LocalAddress);
if (NT_SUCCESS(Status)) {
OpenError = FALSE;
DbgPrint("Using local IP address 0x%X\n", LocalAddress);
} else {
TDI_DbgPrint(MIN_TRACE, ("Unable to determine local IP address.\n"));
}
} else
TDI_DbgPrint(MIN_TRACE, ("Cannot open transport (Status = 0x%X).\n", Status));
TDI_DbgPrint(MAX_TRACE, ("Setting close event.\n"));
KeSetEvent((PKEVENT)Context, 0, FALSE);
TDI_DbgPrint(MIN_TRACE, ("Leaving.\n"));
}
VOID TdiUnload(
PDRIVER_OBJECT DriverObject)
/*
* FUNCTION: Unload routine
* ARGUMENTS:
* DriverObject = Pointer to a driver object for this driver
*/
{
TDI_DbgPrint(MAX_TRACE, ("Setting stop flag\n"));
KeSetEvent(&StopEvent, 0, FALSE);
/* Wait for send thread to stop */
KeWaitForSingleObject(&SendThreadEvent,
Executive,
KernelMode,
FALSE,
NULL);
ObDereferenceObject(SendThreadObject);
/* Wait for receive thread to stop */
KeWaitForSingleObject(&ReceiveThreadEvent,
Executive,
KernelMode,
FALSE,
NULL);
ObDereferenceObject(ReceiveThreadObject);
/* Close device */
TdiCloseDevice(TdiTransport, TdiTransportObject);
}
NTSTATUS
#ifndef _MSC_VER
STDCALL
#endif
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Main driver entry point
* ARGUMENTS:
* DriverObject = Pointer to a driver object for this driver
* RegistryPath = Registry node for configuration parameters
* RETURNS:
* Status of driver initialization
*/
{
KEVENT Event;
NTSTATUS Status;
WORK_QUEUE_ITEM WorkItem;
KeInitializeEvent(&StopEvent, NotificationEvent, FALSE);
KeInitializeEvent(&SendThreadEvent, NotificationEvent, FALSE);
KeInitializeEvent(&ReceiveThreadEvent, NotificationEvent, FALSE);
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
ExInitializeWorkItem(&WorkItem, TdiOpenThread, &Event);
ExQueueWorkItem(&WorkItem, DelayedWorkQueue);
KeWaitForSingleObject(&Event,
Executive,
KernelMode,
TRUE,
NULL);
Status = PsCreateSystemThread(&SendThread, /* Thread handle */
0, /* Desired access */
NULL, /* Object attributes */
NULL, /* Process handle */
NULL, /* Client id */
(PKSTART_ROUTINE)TdiSendThread, /* Start routine */
NULL); /* Start context */
if (!NT_SUCCESS(Status)) {
TDI_DbgPrint(MIN_TRACE, ("PsCreateSystemThread() failed for send thread (Status = 0x%X).\n", Status));
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Get a pointer to the thread object */
ObReferenceObjectByHandle(SendThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&SendThreadObject,
NULL);
Status = PsCreateSystemThread(&ReceiveThread, /* Thread handle */
0, /* Desired access */
NULL, /* Object attributes */
NULL, /* Process handle */
NULL, /* Client id */
(PKSTART_ROUTINE)TdiReceiveThread, /* Start routine */
NULL); /* Start context */
if (!NT_SUCCESS(Status)) {
TDI_DbgPrint(MIN_TRACE, ("PsCreateSystemThread() failed for receive thread (Status = 0x%X).\n", Status));
ZwClose(SendThread);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Get a pointer to the thread object */
ObReferenceObjectByHandle(ReceiveThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&ReceiveThreadObject,
NULL);
/* Don't need these for anything, so we might as well close them now.
The threads will call PsTerminateSystemThread themselves when they are done */
ZwClose(SendThread);
ZwClose(ReceiveThread);
DriverObject->DriverUnload = (PDRIVER_UNLOAD)TdiUnload;
return STATUS_SUCCESS;
}
/* EOF */