Working ping.
msafd: Added datagram flag to SOCK_RAW sockets
transport/* did some refactoring, added some printing.
Main thing: there is now a generic IP only header builder in rawip
that's
shared by udp and rawip.
afd: Make sure datagram sockets always select writable
Add some socket close infrastructure to kill associated active
polls
Modified: trunk/reactos/drivers/lib/ip/transport/datagram/datagram.c
Modified: trunk/reactos/drivers/lib/ip/transport/rawip/rawip.c
Modified: trunk/reactos/drivers/lib/ip/transport/udp/udp.c
Modified: trunk/reactos/drivers/net/afd/afd/bind.c
Modified: trunk/reactos/drivers/net/afd/afd/main.c
Modified: trunk/reactos/drivers/net/afd/afd/select.c
Modified: trunk/reactos/drivers/net/afd/afd/write.c
Modified: trunk/reactos/drivers/net/afd/include/afd.h
Modified: trunk/reactos/drivers/net/tcpip/include/rawip.h
Modified: trunk/reactos/drivers/net/tcpip/tcpip/dispatch.c
Modified: trunk/reactos/lib/msafd/misc/dllmain.c
_____
Modified: trunk/reactos/drivers/lib/ip/transport/datagram/datagram.c
--- trunk/reactos/drivers/lib/ip/transport/datagram/datagram.c
2005-01-22 03:54:23 UTC (rev 13206)
+++ trunk/reactos/drivers/lib/ip/transport/datagram/datagram.c
2005-01-22 06:47:33 UTC (rev 13207)
@@ -86,6 +86,10 @@
if (Found)
{
TI_DbgPrint(MAX_TRACE, ("Suitable receive request
found.\n"));
+
+ TI_DbgPrint(MAX_TRACE,
+ ("Target Buffer: %x, Source Buffer: %x, Size
%d\n",
+ Current->Buffer, DataBuffer, DataSize));
/* Copy the data into buffer provided by the user */
RtlCopyMemory( Current->Buffer,
_____
Modified: trunk/reactos/drivers/lib/ip/transport/rawip/rawip.c
--- trunk/reactos/drivers/lib/ip/transport/rawip/rawip.c
2005-01-22 03:54:23 UTC (rev 13206)
+++ trunk/reactos/drivers/lib/ip/transport/rawip/rawip.c
2005-01-22 06:47:33 UTC (rev 13207)
@@ -2,7 +2,7 @@
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS TCP/IP protocol driver
* FILE: transport/rawip/rawip.c
- * PURPOSE: Raw IP routines
+ * PURPOSE: User Datagram Protocol routines
* PROGRAMMERS: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
* REVISIONS:
* CSH 01/08-2000 Created
@@ -10,71 +10,155 @@
#include "precomp.h"
+NTSTATUS AddGenericHeaderIPv4(
+ PIP_ADDRESS RemoteAddress,
+ USHORT RemotePort,
+ PIP_ADDRESS LocalAddress,
+ USHORT LocalPort,
+ PIP_PACKET IPPacket,
+ UINT DataLength,
+ UINT Protocol,
+ UINT ExtraLength,
+ PVOID *NextHeader )
+/*
+ * FUNCTION: Adds an IPv4 and RawIp 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;
+ ULONG BufferSize;
+
+ TI_DbgPrint(MID_TRACE, ("Packet: %x NdisPacket %x\n",
+ IPPacket, IPPacket->NdisPacket));
+
+ BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER) + ExtraLength;
+
+ GetDataPtr( IPPacket->NdisPacket,
+ MaxLLHeaderSize,
+ (PCHAR *)&IPPacket->Header,
+ &IPPacket->ContigSize );
+
+ IPPacket->HeaderSize = 20;
+
+ TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at
0x%X.\n",
+ BufferSize, IPPacket->Header));
+ TI_DbgPrint(MAX_TRACE, ("Packet total length %d\n",
IPPacket->TotalSize));
+
+ /* 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 = Protocol;
+ /* 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 = RemoteAddress->Address.IPv4Address;
+
+ /* Build RawIp header */
+ *NextHeader = (((PCHAR)IPHeader) + sizeof(IPv4_HEADER));
+ IPPacket->Data = ((PCHAR)*NextHeader) + ExtraLength;
+
+ return STATUS_SUCCESS;
+}
-BOOLEAN RawIPInitialized = FALSE;
-
-NTSTATUS BuildRawIPPacket(
+NTSTATUS BuildRawIpPacket(
PIP_PACKET Packet,
- UINT DataLength,
+ PIP_ADDRESS RemoteAddress,
+ USHORT RemotePort,
PIP_ADDRESS LocalAddress,
- USHORT LocalPort )
+ USHORT LocalPort,
+ PCHAR DataBuffer,
+ UINT DataLen )
/*
- * FUNCTION: Builds an UDP packet
+ * FUNCTION: Builds an RawIp 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)
+ * 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
*/
{
- PVOID Header;
- NDIS_STATUS NdisStatus;
- PNDIS_BUFFER HeaderBuffer;
- PNDIS_PACKET NdisPacket = Packet->NdisPacket;
- /* Will be zeroed in packet by IPInitializePacket */
-
+ NTSTATUS Status;
+ PCHAR Payload;
+
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ /* FIXME: Assumes IPv4 */
+ IPInitializePacket(Packet, IP_ADDRESS_V4);
+ if (!Packet)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ Packet->TotalSize = sizeof(IPv4_HEADER) + DataLen;
+
/* Prepare packet */
- IPInitializePacket(Packet,IP_ADDRESS_V4);
- Packet->Flags = IP_PACKET_FLAG_RAW; /* Don't touch IP
header */
- Packet->TotalSize = DataLength;
- Packet->NdisPacket = NdisPacket;
+ Status = AllocatePacketWithBuffer( &Packet->NdisPacket,
+ NULL,
+ Packet->TotalSize +
MaxLLHeaderSize );
+
+ if( !NT_SUCCESS(Status) ) return Status;
- if (MaxLLHeaderSize != 0) {
- Header = ExAllocatePool(NonPagedPool, MaxLLHeaderSize);
- if (!Header) {
- TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet
headers.\n"));
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ TI_DbgPrint(MID_TRACE, ("Allocated packet: %x\n",
Packet->NdisPacket));
+ TI_DbgPrint(MID_TRACE, ("Local Addr : %s\n", A2S(LocalAddress)));
+ TI_DbgPrint(MID_TRACE, ("Remote Addr: %s\n", A2S(RemoteAddress)));
+
+ switch (RemoteAddress->Type) {
+ case IP_ADDRESS_V4:
+ Status = AddGenericHeaderIPv4
+ (RemoteAddress, RemotePort,
+ LocalAddress, LocalPort, Packet, DataLen,
+ IPPROTO_ICMP, /* XXX Figure out a better way to do this */
+ 0, (PVOID *)&Payload );
+ break;
+ case IP_ADDRESS_V6:
+ /* FIXME: Support IPv6 */
+ Status = STATUS_UNSUCCESSFUL;
+ TI_DbgPrint(MIN_TRACE, ("IPv6 RawIp datagrams are not
supported.\n"));
+ break;
- TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at
0x%X.\n",
- MaxLLHeaderSize, Header));
-
- /* Allocate NDIS buffer for maximum link level header */
- NdisAllocateBuffer(&NdisStatus,
- &HeaderBuffer,
- GlobalBufferPool,
- Header,
- MaxLLHeaderSize);
-
- if (NdisStatus != NDIS_STATUS_SUCCESS) {
- TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for
packet headers. NdisStatus = (0x%X)\n", NdisStatus));
- ExFreePool(Header);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* Chain header at front of packet */
- NdisChainBufferAtFront(Packet->NdisPacket, HeaderBuffer);
+ default:
+ Status = STATUS_UNSUCCESSFUL;
+ TI_DbgPrint(MIN_TRACE, ("Bad Address Type %d\n",
RemoteAddress->Type));
+ break;
}
-
+
+ TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n",
+ Packet->Header, Packet->Data,
+ (PCHAR)Packet->Data -
(PCHAR)Packet->Header));
+
+ RtlCopyMemory( Packet->Data, DataBuffer, DataLen );
+
+ TI_DbgPrint(MID_TRACE, ("Displaying packet\n"));
+
DISPLAY_IP_PACKET(Packet);
-
+
+ TI_DbgPrint(MID_TRACE, ("Leaving\n"));
+
return STATUS_SUCCESS;
}
-VOID RawIPSendComplete
+VOID RawIpSendPacketComplete
( PVOID Context, PNDIS_PACKET Packet, NDIS_STATUS Status ) {
FreeNdisPacket( Packet );
}
@@ -83,10 +167,10 @@
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
PCHAR BufferData,
- ULONG BufferLen,
- PULONG DataUsed )
+ ULONG DataSize,
+ PULONG DataUsed )
/*
- * FUNCTION: Sends a raw IP datagram to a remote address
+ * FUNCTION: Sends an RawIp datagram to a remote address
* ARGUMENTS:
* Request = Pointer to TDI request
* ConnInfo = Pointer to connection information
@@ -96,134 +180,258 @@
* Status of operation
*/
{
- NDIS_STATUS Status;
IP_PACKET Packet;
+ PTA_IP_ADDRESS RemoteAddressTa =
(PTA_IP_ADDRESS)ConnInfo->RemoteAddress;
+ IP_ADDRESS RemoteAddress;
+ USHORT RemotePort;
+ NTSTATUS Status;
PNEIGHBOR_CACHE_ENTRY NCE;
- IP_ADDRESS RemoteAddress;
- Status = AllocatePacketWithBuffer( &Packet.NdisPacket,
- BufferData,
- BufferLen );
+ TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
+ AddrFile, ConnInfo, BufferData, DataSize));
+ TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa));
+
+ switch( RemoteAddressTa->Address[0].AddressType ) {
+ case TDI_ADDRESS_TYPE_IP:
+ RemoteAddress.Type = IP_ADDRESS_V4;
+ RemoteAddress.Address.IPv4Address =
+ RemoteAddressTa->Address[0].Address[0].in_addr;
+ RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port;
+ break;
+
+ default:
+ return STATUS_UNSUCCESSFUL;
+ }
- TI_DbgPrint(MID_TRACE,("Packet.NdisPacket %x\n",
Packet.NdisPacket));
+ Status = BuildRawIpPacket( &Packet,
+ &RemoteAddress,
+ RemotePort,
+ &AddrFile->Address,
+ AddrFile->Port,
+ BufferData,
+ DataSize );
+
+ if( !NT_SUCCESS(Status) )
+ return Status;
- *DataUsed = BufferLen;
+ TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
- if( Status == NDIS_STATUS_SUCCESS )
- Status = BuildRawIPPacket( &Packet,
- BufferLen,
- &AddrFile->Address,
- AddrFile->Port );
+ if(!(NCE = RouteGetRouteToDestination( &RemoteAddress )))
+ return STATUS_UNSUCCESSFUL;
- if( Status == NDIS_STATUS_SUCCESS ) {
- RemoteAddress.Type = IP_ADDRESS_V4;
- RtlCopyMemory( &RemoteAddress.Address.IPv4Address,
- BufferData + FIELD_OFFSET(IPv4_HEADER, DstAddr),
- sizeof(IPv4_RAW_ADDRESS) );
+ TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
- if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
- FreeNdisPacket( Packet.NdisPacket );
- return STATUS_NO_SUCH_DEVICE;
- }
-
- IPSendDatagram( &Packet, NCE, RawIPSendComplete, NULL );
- } else
- FreeNdisPacket( Packet.NdisPacket );
+ IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL );
- return Status;
+ TI_DbgPrint(MID_TRACE,("Leaving\n"));
+
+ return STATUS_SUCCESS;
}
+VOID RawIpReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count)
{
+ PDATAGRAM_RECEIVE_REQUEST ReceiveRequest =
+ (PDATAGRAM_RECEIVE_REQUEST)Context;
+ TI_DbgPrint(MAX_TRACE,("Called\n"));
+ ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status,
Count );
+ exFreePool( ReceiveRequest );
+ TI_DbgPrint(MAX_TRACE,("Done\n"));
+}
-VOID RawIPReceive(
- PIP_INTERFACE Interface,
- PIP_PACKET IPPacket)
+NTSTATUS RawIPReceiveDatagram(
+ PADDRESS_FILE AddrFile,
+ PTDI_CONNECTION_INFORMATION ConnInfo,
+ PCHAR BufferData,
+ ULONG ReceiveLength,
+ ULONG ReceiveFlags,
+ PTDI_CONNECTION_INFORMATION ReturnInfo,
+ PULONG BytesReceived,
+ PDATAGRAM_COMPLETION_ROUTINE Complete,
+ PVOID Context)
/*
- * FUNCTION: Receives and queues a raw IP datagram
+ * FUNCTION: Attempts to receive an RawIp datagram from a remote
address
* ARGUMENTS:
- * NTE = Pointer to net table entry which the packet was
received on
- * IPPacket = Pointer to an IP packet that was received
+ * 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 low level interface for receiving ICMP datagrams.
- * It delivers the packet header and data to anyone that wants it
- * When we get here the datagram has already passed sanity checks
+ * This is the high level interface for receiving RawIp datagrams
*/
{
- PIP_ADDRESS DstAddress;
-
+ KIRQL OldIrql;
+ NTSTATUS Status;
+ PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
+
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+ TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
+ if (AF_IS_VALID(AddrFile))
+ {
+ ReceiveRequest = exAllocatePool(NonPagedPool,
sizeof(DATAGRAM_RECEIVE_REQUEST));
+ if (ReceiveRequest)
+ {
+ /* Initialize a receive request */
+
+ /* Extract the remote address filter from the request (if
any) */
+ if ((ConnInfo->RemoteAddressLength != 0) &&
+ (ConnInfo->RemoteAddress))
+ {
+ Status = AddrGetAddress(ConnInfo->RemoteAddress,
+ &ReceiveRequest->RemoteAddress,
+ &ReceiveRequest->RemotePort);
+ if (!NT_SUCCESS(Status))
+ {
+ TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ exFreePool(ReceiveRequest);
+ return Status;
+ }
+ }
+ else
+ {
+ ReceiveRequest->RemotePort = 0;
+ }
+ ReceiveRequest->ReturnInfo = ReturnInfo;
+ ReceiveRequest->Buffer = BufferData;
+ ReceiveRequest->BufferSize = ReceiveLength;
+ ReceiveRequest->UserComplete = Complete;
+ ReceiveRequest->UserContext = Context;
+ ReceiveRequest->Complete =
+ (PDATAGRAM_COMPLETION_ROUTINE)RawIpReceiveComplete;
+ ReceiveRequest->Context = ReceiveRequest;
+
+ /* Queue receive request */
+ InsertTailList(&AddrFile->ReceiveQueue,
&ReceiveRequest->ListEntry);
+ AF_SET_PENDING(AddrFile, AFF_RECEIVE);
+
+ TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
+
+ return STATUS_PENDING;
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ Status = STATUS_INVALID_ADDRESS;
+ }
+
+ TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
+ TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
+
+ return Status;
+}
- switch (IPPacket->Type) {
- /* IPv4 packet */
- case IP_ADDRESS_V4:
- DstAddress = &IPPacket->DstAddr;
- break;
- /* IPv6 packet */
- case IP_ADDRESS_V6:
- TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 raw IP datagram (%i
bytes).\n",
- IPPacket->TotalSize));
+VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
+/*
+ * FUNCTION: Receives and queues a RawIp 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 RawIp datagrams. It
strips
+* the RawIp header from a packet and delivers the data to anyone
that wants it
+*/
+{
+ AF_SEARCH SearchContext;
+ PIPv4_HEADER IPv4Header;
+ PADDRESS_FILE AddrFile;
+ PIP_ADDRESS DstAddress, SrcAddress;
+ UINT DataSize;
- /* FIXME: IPv6 is not supported */
- return;
+ TI_DbgPrint(MAX_TRACE, ("Called.\n"));
- default:
- return;
- }
+ switch (IPPacket->Type) {
+ /* IPv4 packet */
+ case IP_ADDRESS_V4:
+ IPv4Header = IPPacket->Header;
+ DstAddress = &IPPacket->DstAddr;
+ SrcAddress = &IPPacket->SrcAddr;
+ DataSize = IPPacket->TotalSize;
+ break;
- /* 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 */
+ /* IPv6 packet */
+ case IP_ADDRESS_V6:
+ TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 datagram (%i bytes).\n",
IPPacket->TotalSize));
-#if 0 /* Decide what to do here */
- AddrFile = AddrSearchFirst(DstAddress,
- 0,
- IPPROTO_ICMP,
- &SearchContext);
- if (AddrFile) {
- do {
- DGDeliverData(AddrFile,
- DstAddress,
- IPPacket,
- IPPacket->TotalSize);
- } 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 ICMP datagram to
address (0x%X).\n",
- DN2H(DstAddress->Address.IPv4Address)));
- }
-#endif
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+ /* FIXME: IPv6 is not supported */
+ return;
+
+ default:
+ return;
+ }
+
+ /* 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,
+ 0,
+ IPv4Header->Protocol,
+ &SearchContext);
+ if (AddrFile) {
+ do {
+ DGDeliverData(AddrFile,
+ SrcAddress,
+ DstAddress,
+ 0,
+ 0,
+ 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 raw datagram to
address (0x%X).\n",
+ DN2H(DstAddress->Address.IPv4Address)));
+
+ /* FIXME: Send ICMP reply */
+ }
+ TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
-NTSTATUS RawIPStartup(
- VOID)
+NTSTATUS RawIPStartup(VOID)
/*
- * FUNCTION: Initializes the Raw IP subsystem
+ * FUNCTION: Initializes the UDP subsystem
* RETURNS:
* Status of operation
*/
{
- RawIPInitialized = TRUE;
+#ifdef __NTDRIVER__
+ RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS));
+#endif
- return STATUS_SUCCESS;
+ /* Register this protocol with IP layer */
+ IPRegisterProtocol(IPPROTO_ICMP, RawIpReceive);
+
+ return STATUS_SUCCESS;
}
-NTSTATUS RawIPShutdown(
- VOID)
+NTSTATUS RawIPShutdown(VOID)
/*
- * FUNCTION: Shuts down the Raw IP subsystem
+ * FUNCTION: Shuts down the UDP subsystem
* RETURNS:
* Status of operation
*/
{
- if (!RawIPInitialized)
- return STATUS_SUCCESS;
+ /* Deregister this protocol with IP layer */
+ IPRegisterProtocol(IPPROTO_ICMP, NULL);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
/* EOF */
_____
Modified: trunk/reactos/drivers/lib/ip/transport/udp/udp.c
--- trunk/reactos/drivers/lib/ip/transport/udp/udp.c 2005-01-22
03:54:23 UTC (rev 13206)
+++ trunk/reactos/drivers/lib/ip/transport/udp/udp.c 2005-01-22
06:47:33 UTC (rev 13207)
@@ -33,51 +33,19 @@
* Status of operation
*/
{
- PIPv4_HEADER IPHeader;
PUDP_HEADER UDPHeader;
- ULONG BufferSize;
TI_DbgPrint(MID_TRACE, ("Packet: %x NdisPacket %x\n",
IPPacket, IPPacket->NdisPacket));
+
+ AddGenericHeaderIPv4
+ ( RemoteAddress, RemotePort,
+ LocalAddress, LocalPort,
+ IPPacket, DataLength, IPPROTO_UDP,
+ sizeof(UDP_HEADER), (PVOID *)&UDPHeader );
- BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER) +
sizeof(UDP_HEADER);
-
- GetDataPtr( IPPacket->NdisPacket,
- MaxLLHeaderSize,
- (PCHAR *)&IPPacket->Header,
- &IPPacket->ContigSize );
-
- IPPacket->HeaderSize = 20;
-
- TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at
0x%X.\n",
- BufferSize, IPPacket->Header));
- TI_DbgPrint(MAX_TRACE, ("Packet total length %d\n",
IPPacket->TotalSize));
-
- /* 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 = RemoteAddress->Address.IPv4Address;
-
/* Build UDP header */
- UDPHeader = (PUDP_HEADER)(((PCHAR)IPHeader) + sizeof(IPv4_HEADER));
+ UDPHeader = (PUDP_HEADER)(IPPacket->Data - sizeof(UDP_HEADER));
/* Port values are already big-endian values */
UDPHeader->SourcePort = LocalPort;
UDPHeader->DestPort = RemotePort;
@@ -89,7 +57,7 @@
IPPacket->Data = ((PCHAR)UDPHeader) + sizeof(UDP_HEADER);
TI_DbgPrint(MID_TRACE, ("Packet: %d ip %d udp %d payload\n",
- (PCHAR)UDPHeader - (PCHAR)IPHeader,
+ (PCHAR)UDPHeader - (PCHAR)IPPacket->Header,
(PCHAR)IPPacket->Data - (PCHAR)UDPHeader,
DataLength));
_____
Modified: trunk/reactos/drivers/net/afd/afd/bind.c
--- trunk/reactos/drivers/net/afd/afd/bind.c 2005-01-22 03:54:23 UTC
(rev 13206)
+++ trunk/reactos/drivers/net/afd/afd/bind.c 2005-01-22 06:47:33 UTC
(rev 13207)
@@ -74,10 +74,6 @@
/* This will be the from address for subsequent recvfrom calls
*/
TdiBuildConnectionInfo( &FCB->AddressFrom,
FCB->LocalAddress );
- /* Allocate our backup buffer */
- FCB->Recv.Window = ExAllocatePool( NonPagedPool, FCB->Recv.Size
);
- FCB->PollState |= AFD_EVENT_SEND;
- /* A datagram socket is always sendable */
AFD_DbgPrint(MID_TRACE,("Calling TdiReceiveDatagram\n"));
_____
Modified: trunk/reactos/drivers/net/afd/afd/main.c
--- trunk/reactos/drivers/net/afd/afd/main.c 2005-01-22 03:54:23 UTC
(rev 13206)
+++ trunk/reactos/drivers/net/afd/afd/main.c 2005-01-22 06:47:33 UTC
(rev 13207)
@@ -132,6 +132,18 @@
}
FileObject->FsContext = FCB;
+
+ /* It seems that UDP sockets are writable from inception */
+ if( FCB->Flags & SGID_CONNECTIONLESS ) {
+ AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
+ /* Allocate our backup buffer */
+ FCB->Recv.Window = ExAllocatePool( NonPagedPool, FCB->Recv.Size
);
+ FCB->Send.Window = ExAllocatePool( NonPagedPool, FCB->Send.Size
);
+ /* A datagram socket is always sendable */
+ FCB->PollState |= AFD_EVENT_SEND;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ }
+
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
@@ -215,6 +227,8 @@
FCB->PollState |= AFD_EVENT_CLOSE;
PollReeval( FCB->DeviceExt, FileObject );
+ KillSelectsForFCB( FCB->DeviceExt, FileObject );
+
if( FCB->EventSelect ) ObDereferenceObject( FCB->EventSelect );
FileObject->FsContext = NULL;
_____
Modified: trunk/reactos/drivers/net/afd/afd/select.c
--- trunk/reactos/drivers/net/afd/afd/select.c 2005-01-22 03:54:23 UTC
(rev 13206)
+++ trunk/reactos/drivers/net/afd/afd/select.c 2005-01-22 06:47:33 UTC
(rev 13207)
@@ -43,13 +43,23 @@
VOID SignalSocket( PAFD_ACTIVE_POLL Poll, PAFD_POLL_INFO PollReq,
NTSTATUS Status ) {
+ int i;
PIRP Irp = Poll->Irp;
AFD_DbgPrint(MID_TRACE,("Called (Status %x)\n", Status));
+ KeCancelTimer( &Poll->Timer );
Poll->Irp->IoStatus.Status = Status;
Poll->Irp->IoStatus.Information =
FIELD_OFFSET(AFD_POLL_INFO, Handles) + sizeof(AFD_HANDLE) *
PollReq->HandleCount;
CopyBackStatus( PollReq->Handles,
PollReq->HandleCount );
+ for( i = 0; i < PollReq->HandleCount; i++ ) {
+ AFD_DbgPrint
+ (MAX_TRACE,
+ ("Handle(%x): Got %x,%x\n",
+ PollReq->Handles[i].Handle,
+ PollReq->Handles[i].Events,
+ PollReq->Handles[i].Status));
+ }
UnlockHandles( AFD_HANDLES(PollReq), PollReq->HandleCount );
AFD_DbgPrint(MID_TRACE,("Completing\n"));
IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
@@ -83,6 +93,41 @@
AFD_DbgPrint(MID_TRACE,("Timeout\n"));
}
+VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject ) {
+ KIRQL OldIrql;
+ PLIST_ENTRY ListEntry;
+ PAFD_ACTIVE_POLL Poll;
+ PIRP Irp;
+ PAFD_POLL_INFO PollReq;
+ int i;
+
+ AFD_DbgPrint(MID_TRACE,("Killing selects that refer to %x\n",
FileObject));
+
+ KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
+
+ ListEntry = DeviceExt->Polls.Flink;
+ while ( ListEntry != &DeviceExt->Polls ) {
+ Poll = CONTAINING_RECORD(ListEntry, AFD_ACTIVE_POLL, ListEntry);
+ ListEntry = ListEntry->Flink;
+ Irp = Poll->Irp;
+ PollReq = Irp->AssociatedIrp.SystemBuffer;
+
+ for( i = 0; i < PollReq->HandleCount; i++ ) {
+ AFD_DbgPrint(MAX_TRACE,("Req: %x, This %x\n",
+ PollReq->Handles[i].Handle,
FileObject));
+ if( (PVOID)PollReq->Handles[i].Handle == FileObject ) {
+ ZeroEvents( PollReq->Handles, PollReq->HandleCount );
+ SignalSocket( Poll, PollReq, STATUS_SUCCESS );
+ }
+ }
+ }
+
+ KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
+
+ AFD_DbgPrint(MID_TRACE,("Done\n"));
+}
+
VOID KillExclusiveSelects( PAFD_DEVICE_EXTENSION DeviceExt ) {
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
_____
Modified: trunk/reactos/drivers/net/afd/afd/write.c
--- trunk/reactos/drivers/net/afd/afd/write.c 2005-01-22 03:54:23 UTC
(rev 13206)
+++ trunk/reactos/drivers/net/afd/afd/write.c 2005-01-22 06:47:33 UTC
(rev 13207)
@@ -165,6 +165,9 @@
/* It's ok if the FCB already died */
if( !SocketAcquireStateLock( FCB ) ) return STATUS_SUCCESS;
+ FCB->PollState |= AFD_EVENT_SEND;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+
FCB->SendIrp.InFlightRequest = NULL;
/* Request is not in flight any longer */
@@ -361,6 +364,7 @@
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE
);
FCB->EventsFired &= ~AFD_EVENT_SEND;
+ FCB->PollState &= ~AFD_EVENT_SEND;
/* Check that the socket is bound */
if( FCB->State != SOCKET_STATE_BOUND )
_____
Modified: trunk/reactos/drivers/net/afd/include/afd.h
--- trunk/reactos/drivers/net/afd/include/afd.h 2005-01-22 03:54:23 UTC
(rev 13206)
+++ trunk/reactos/drivers/net/afd/include/afd.h 2005-01-22 06:47:33 UTC
(rev 13207)
@@ -262,6 +262,8 @@
AfdEnumEvents( PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp );
VOID PollReeval( PAFD_DEVICE_EXTENSION DeviceObject, PFILE_OBJECT
FileObject );
+VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt,
+ PFILE_OBJECT FileObject );
/* tdi.c */
_____
Modified: trunk/reactos/drivers/net/tcpip/include/rawip.h
--- trunk/reactos/drivers/net/tcpip/include/rawip.h 2005-01-22
03:54:23 UTC (rev 13206)
+++ trunk/reactos/drivers/net/tcpip/include/rawip.h 2005-01-22
06:47:33 UTC (rev 13207)
@@ -7,6 +7,8 @@
#ifndef __RAWIP_H
#define __RAWIP_H
+
+
NTSTATUS RawIPSendDatagram(
PADDRESS_FILE AddrFile,
PTDI_CONNECTION_INFORMATION ConnInfo,
@@ -24,6 +26,17 @@
NTSTATUS RawIPShutdown(
VOID);
+NTSTATUS AddGenericHeaderIPv4(
+ PIP_ADDRESS RemoteAddress,
+ USHORT RemotePort,
+ PIP_ADDRESS LocalAddress,
+ USHORT LocalPort,
+ PIP_PACKET IPPacket,
+ UINT DataLength,
+ UINT Protocol,
+ UINT ExtraLength,
+ PVOID *NextHeader );
+
#endif /* __RAWIP_H */
/* EOF */
_____
Modified: trunk/reactos/drivers/net/tcpip/tcpip/dispatch.c
--- trunk/reactos/drivers/net/tcpip/tcpip/dispatch.c 2005-01-22
03:54:23 UTC (rev 13206)
+++ trunk/reactos/drivers/net/tcpip/tcpip/dispatch.c 2005-01-22
06:47:33 UTC (rev 13207)
@@ -924,12 +924,15 @@
("About to call send routine %x\n",
(*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)));
- Status =
(*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
- Request.Handle.AddressHandle,
- DgramInfo->SendDatagramInformation,
- DataBuffer,
- BufferSize,
- &Irp->IoStatus.Information);
+ if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send) )
+ Status =
(*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
+ Request.Handle.AddressHandle,
+ DgramInfo->SendDatagramInformation,
+ DataBuffer,
+ BufferSize,
+ &Irp->IoStatus.Information);
+ else
+ Status = STATUS_UNSUCCESSFUL;
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status,
Irp->IoStatus.Information);
_____
Modified: trunk/reactos/lib/msafd/misc/dllmain.c
--- trunk/reactos/lib/msafd/misc/dllmain.c 2005-01-22 03:54:23 UTC
(rev 13206)
+++ trunk/reactos/lib/msafd/misc/dllmain.c 2005-01-22 06:47:33 UTC
(rev 13207)
@@ -16,8 +16,8 @@
#include <rosrtl/string.h>
#ifdef DBG
-//DWORD DebugTraceLevel = DEBUG_ULTRA;
-DWORD DebugTraceLevel = 0;
+DWORD DebugTraceLevel = DEBUG_ULTRA;
+//DWORD DebugTraceLevel = 0;
#endif /* DBG */
HANDLE GlobalHeap;
@@ -123,8 +123,11 @@
Socket->SanData = NULL;
/* Ask alex about this */
- if( Socket->SharedData.SocketType == SOCK_DGRAM )
+ if( Socket->SharedData.SocketType == SOCK_DGRAM ||
+ Socket->SharedData.SocketType == SOCK_RAW ) {
+ AFD_DbgPrint(MID_TRACE,("Connectionless socket\n"));
Socket->SharedData.ServiceFlags1 |= XP1_CONNECTIONLESS;
+ }
/* Packet Size */
SizeOfPacket = TransportName.Length + sizeof(AFD_CREATE_PACKET)
+ sizeof(WCHAR);