More work on winsock stack (ping is now working)
authorCasper Hornstrup <chorns@users.sourceforge.net>
Fri, 15 Jun 2001 17:48:43 +0000 (17:48 +0000)
committerCasper Hornstrup <chorns@users.sourceforge.net>
Fri, 15 Jun 2001 17:48:43 +0000 (17:48 +0000)
svn path=/trunk/; revision=1971

16 files changed:
reactos/apps/utils/net/ping/ping.c
reactos/drivers/net/afd/afd/afd.c
reactos/drivers/net/afd/afd/dispatch.c
reactos/drivers/net/afd/afd/event.c
reactos/drivers/net/afd/afd/opnclose.c
reactos/drivers/net/afd/afd/routines.c
reactos/drivers/net/afd/include/afd.h
reactos/drivers/net/afd/include/debug.h
reactos/drivers/net/tcpip/network/icmp.c
reactos/drivers/net/tcpip/tcpip/main.c
reactos/drivers/net/tcpip/transport/datagram/datagram.c
reactos/lib/msafd/misc/dllmain.c
reactos/lib/msafd/misc/sndrcv.c
reactos/lib/ws2_32/misc/dllmain.c
reactos/lib/ws2_32/misc/ns.c
reactos/lib/ws2_32/misc/sndrcv.c

index 486d2e2..01902d6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: ping.c,v 1.4 2001/05/01 23:08:17 chorns Exp $
+/* $Id: ping.c,v 1.5 2001/06/15 17:48:43 chorns Exp $
  *
  * COPYRIGHT:   See COPYING in the top level directory
  * PROJECT:     ReactOS ping utility
@@ -15,6 +15,8 @@
 #include <stdio.h>
 #ifndef _MSC_VER
 
+//#define DBG
+
 /* FIXME: Where should this be? */
 #define CopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length);
 
@@ -99,6 +101,25 @@ LARGE_INTEGER       TicksPerUs; /* Ticks per microsecond */
 BOOL                UsePerformanceCounter;
 
 
+/* Display the contents of a buffer */
+VOID DisplayBuffer(
+    PVOID Buffer,
+    DWORD Size)
+{
+    UINT i;
+    PCHAR p;
+
+    printf("Buffer (0x%X)  Size (0x%X).\n", Buffer, Size);
+
+    p = (PCHAR)Buffer;
+    for (i = 0; i < Size; i++) {
+      if (i % 16 == 0) {
+        printf("\n");
+      }
+      printf("%02X ", (p[i]) & 0xFF);
+    }
+}
+
 /* Display usage information on screen */
 VOID Usage(VOID)
 {
@@ -189,7 +210,7 @@ BOOL ParseCmdline(int argc, char* argv[])
     INT i;
     BOOL ShowUsage;
     BOOL FoundTarget;
-#if 0
+#if 1
     lstrcpy(TargetName, "127.0.0.1");
     PingCount = 1;
     return TRUE;
@@ -388,7 +409,7 @@ BOOL DecodeResponse(PCHAR buffer, UINT size, PSOCKADDR_IN from)
 {
     PIPv4_HEADER      IpHeader;
     PICMP_ECHO_PACKET Icmp;
-       UINT              IphLength;
+       UINT              IphLength;
     CHAR              Time[100];
     LARGE_INTEGER     RelativeTime;
     LARGE_INTEGER     LargeTime;
@@ -397,16 +418,28 @@ BOOL DecodeResponse(PCHAR buffer, UINT size, PSOCKADDR_IN from)
 
     IphLength = IpHeader->IHL * 4;
 
-    if (size  < IphLength + ICMP_MINSIZE)
+    if (size  < IphLength + ICMP_MINSIZE) {
+#ifdef DBG
+        printf("Bad size (0x%X < 0x%X)\n", size, IphLength + ICMP_MINSIZE);
+#endif DBG
         return FALSE;
+    }
 
     Icmp = (PICMP_ECHO_PACKET)(buffer + IphLength);
 
-    if (Icmp->Icmp.Type != ICMPMSG_ECHOREPLY)
+    if (Icmp->Icmp.Type != ICMPMSG_ECHOREPLY) {
+#ifdef DBG
+        printf("Bad ICMP type (0x%X should be 0x%X)\n", Icmp->Icmp.Type, ICMPMSG_ECHOREPLY);
+#endif DBG
         return FALSE;
+    }
 
-    if (Icmp->Icmp.Id != (USHORT)GetCurrentProcessId())
+    if (Icmp->Icmp.Id != (USHORT)GetCurrentProcessId()) {
+#ifdef DBG
+        printf("Bad ICMP id (0x%X should be 0x%X)\n", Icmp->Icmp.Id, (USHORT)GetCurrentProcessId());
+#endif DBG
         return FALSE;
+    }
 
     QueryTime(&LargeTime);
 
@@ -415,14 +448,14 @@ BOOL DecodeResponse(PCHAR buffer, UINT size, PSOCKADDR_IN from)
     TimeToMsString(Time, RelativeTime);
 
     printf("Reply from %s: bytes=%d time=%s TTL=%d\n", inet_ntoa(from->sin_addr), 
-               size - IphLength - sizeof(ICMP_ECHO_PACKET) , Time, IpHeader->TTL);
+      size - IphLength - sizeof(ICMP_ECHO_PACKET), Time, IpHeader->TTL);
     if (RelativeTime.QuadPart < MinRTT.QuadPart) {
-               MinRTT.QuadPart = RelativeTime.QuadPart;
-        MinRTTSet = TRUE;
+                 MinRTT.QuadPart = RelativeTime.QuadPart;
+      MinRTTSet = TRUE;
     }
-       if (RelativeTime.QuadPart > MaxRTT.QuadPart)
-               MaxRTT.QuadPart = RelativeTime.QuadPart;
-       SumRTT.QuadPart += RelativeTime.QuadPart;
+         if (RelativeTime.QuadPart > MaxRTT.QuadPart)
+             MaxRTT.QuadPart = RelativeTime.QuadPart;
+    SumRTT.QuadPart += RelativeTime.QuadPart;
 
        return TRUE;
 }
@@ -472,10 +505,17 @@ BOOL Ping(VOID)
     Timeval.tv_usec = Timeout % 1000;
     Status = select(0, NULL, &Fds, NULL, &Timeval);
     if ((Status != SOCKET_ERROR) && (Status != 0)) {
+
+#ifdef DBG
+        printf("Sending packet\n");
+        DisplayBuffer(Buffer, sizeof(ICMP_ECHO_PACKET) + DataSize);
+        printf("\n");
+#endif DBG
+
         Status = sendto(IcmpSock, Buffer, sizeof(ICMP_ECHO_PACKET) + DataSize,
             0, (SOCKADDR*)&Target, sizeof(Target));
+        SentCount++;
     }
-    SentCount++;
     if (Status == SOCKET_ERROR) {
         if (WSAGetLastError() == WSAEHOSTUNREACH) {
             printf("Destination host unreachable.\n");
@@ -496,6 +536,12 @@ BOOL Ping(VOID)
     if ((Status != SOCKET_ERROR) && (Status != 0)) {
         Length = sizeof(From);
         Status = recvfrom(IcmpSock, Buffer, Size, 0, &From, &Length);
+
+#ifdef DBG
+        printf("Received packet\n");
+        DisplayBuffer(Buffer, Status);
+        printf("\n");
+#endif DBG
     }
     if (Status == SOCKET_ERROR) {
         if (WSAGetLastError() != WSAETIMEDOUT) {
@@ -515,7 +561,7 @@ BOOL Ping(VOID)
 
     if (!DecodeResponse(Buffer, Status, (PSOCKADDR_IN)&From)) {
         /* FIXME: Wait again as it could be another ICMP message type */
-        printf("Request timed out.\n");
+        printf("Request timed out (incomplete datagram received).\n");
         LostCount++;
     }
 
@@ -563,7 +609,7 @@ int main(int argc, char* argv[])
         }
 
         if (!MinRTTSet)
-            MinRTT.QuadPart = 0;
+            MinRTT = MaxRTT;
 
         TimeToMsString(MinTime, MinRTT);
         TimeToMsString(MaxTime, MaxRTT);
index 02c6bb8..112138a 100644 (file)
@@ -19,6 +19,7 @@ DWORD DebugTraceLevel = MIN_TRACE;
 
 
 NPAGED_LOOKASIDE_LIST BufferLookasideList;
+NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
 
 
 NTSTATUS
@@ -169,6 +170,16 @@ DriverEntry(
       TAG('A', 'F', 'D', 'B'),
       0);*/
 
+/*    ExInitializeNPagedLookasideList(
+      &ReadRequestLookasideList,
+      NULL,
+      NULL,
+      0,
+      sizeof(AFD_READ_REQUEST),
+      TAG('A', 'F', 'D', 'R'),
+      0);*/
+
+    
     return STATUS_SUCCESS;
 }
 
index 88d545f..f7c1110 100644 (file)
@@ -21,46 +21,46 @@ NTSTATUS AfdDispBind(
  *     Status of operation
  */
 {
-    NTSTATUS Status;
-    UINT InputBufferLength;
-    UINT OutputBufferLength;
-    PFILE_REQUEST_BIND Request;
-    PFILE_REPLY_BIND Reply;
-    PAFDFCB FCB;
-
-    InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
-    OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
-    /* Validate parameters */
-    if ((InputBufferLength >= sizeof(FILE_REQUEST_BIND)) &&
-        (OutputBufferLength >= sizeof(FILE_REPLY_BIND))) {
-        FCB = IrpSp->FileObject->FsContext;
-
-        Request = (PFILE_REQUEST_BIND)Irp->AssociatedIrp.SystemBuffer;
-        Reply   = (PFILE_REPLY_BIND)Irp->AssociatedIrp.SystemBuffer;
-
-        switch (Request->Name.sa_family) {
-        case AF_INET:
-            Status = TdiOpenAddressFileIPv4(&FCB->TdiDeviceName,
-                &Request->Name,
-                &FCB->TdiAddressObjectHandle,
-                &FCB->TdiAddressObject);
-            break;
-        default:
-            AFD_DbgPrint(MIN_TRACE, ("Bad address family (%d).\n", Request->Name.sa_family));
-            Status = STATUS_INVALID_PARAMETER;
-        }
+  NTSTATUS Status;
+  UINT InputBufferLength;
+  UINT OutputBufferLength;
+  PFILE_REQUEST_BIND Request;
+  PFILE_REPLY_BIND Reply;
+  PAFDFCB FCB;
+
+  InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+  OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+  /* Validate parameters */
+  if ((InputBufferLength >= sizeof(FILE_REQUEST_BIND)) &&
+    (OutputBufferLength >= sizeof(FILE_REPLY_BIND))) {
+    FCB = IrpSp->FileObject->FsContext;
+
+    Request = (PFILE_REQUEST_BIND)Irp->AssociatedIrp.SystemBuffer;
+    Reply   = (PFILE_REPLY_BIND)Irp->AssociatedIrp.SystemBuffer;
+
+    switch (Request->Name.sa_family) {
+    case AF_INET:
+      Status = TdiOpenAddressFileIPv4(&FCB->TdiDeviceName,
+          &Request->Name,
+          &FCB->TdiAddressObjectHandle,
+          &FCB->TdiAddressObject);
+      break;
+    default:
+      AFD_DbgPrint(MIN_TRACE, ("Bad address family (%d).\n", Request->Name.sa_family));
+      Status = STATUS_INVALID_PARAMETER;
+    }
 
-        if (NT_SUCCESS(Status)) {
-            AfdRegisterEventHandlers(FCB);
-            FCB->State = SOCKET_STATE_BOUND;
-        }
-    } else
-        Status = STATUS_INVALID_PARAMETER;
+    if (NT_SUCCESS(Status)) {
+      AfdRegisterEventHandlers(FCB);
+      FCB->State = SOCKET_STATE_BOUND;
+    }
+  } else
+      Status = STATUS_INVALID_PARAMETER;
 
-    AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+  AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
 
-    return Status;
+  return Status;
 }
 
 
@@ -76,29 +76,29 @@ NTSTATUS AfdDispListen(
  *     Status of operation
  */
 {
-    NTSTATUS Status;
-    UINT InputBufferLength;
-    UINT OutputBufferLength;
-    PFILE_REQUEST_LISTEN Request;
-    PFILE_REPLY_LISTEN Reply;
-    PAFDFCB FCB;
+  NTSTATUS Status;
+  UINT InputBufferLength;
+  UINT OutputBufferLength;
+  PFILE_REQUEST_LISTEN Request;
+  PFILE_REPLY_LISTEN Reply;
+  PAFDFCB FCB;
 
-    InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
-    OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+  InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+  OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
 
-    /* Validate parameters */
-    if ((InputBufferLength >= sizeof(FILE_REQUEST_LISTEN)) &&
-        (OutputBufferLength >= sizeof(FILE_REPLY_LISTEN))) {
-        FCB = IrpSp->FileObject->FsContext;
+  /* Validate parameters */
+  if ((InputBufferLength >= sizeof(FILE_REQUEST_LISTEN)) &&
+    (OutputBufferLength >= sizeof(FILE_REPLY_LISTEN))) {
+    FCB = IrpSp->FileObject->FsContext;
 
-        Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
-        Reply   = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
-    } else
-        Status = STATUS_INVALID_PARAMETER;
+    Request = (PFILE_REQUEST_LISTEN)Irp->AssociatedIrp.SystemBuffer;
+    Reply   = (PFILE_REPLY_LISTEN)Irp->AssociatedIrp.SystemBuffer;
+  } else
+    Status = STATUS_INVALID_PARAMETER;
 
-    AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+  AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
 
-    return Status;
+  return Status;
 }
 
 
@@ -114,146 +114,146 @@ NTSTATUS AfdDispSendTo(
  *     Status of operation
  */
 {
-    NTSTATUS Status;
-    UINT InputBufferLength;
-    UINT OutputBufferLength;
-    PFILE_REQUEST_SENDTO Request;
-    PFILE_REPLY_SENDTO Reply;
-    PAFDFCB FCB;
-    PVOID SystemVirtualAddress;
-    PVOID DataBufferAddress;
-    ULONG BufferSize;
-    ULONG BytesCopied;
-    PMDL Mdl;
-
-    InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
-    OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
-    /* Validate parameters */
-    if ((InputBufferLength >= sizeof(FILE_REQUEST_SENDTO)) &&
-        (OutputBufferLength >= sizeof(FILE_REPLY_SENDTO))) {
-
-        AFD_DbgPrint(MAX_TRACE, ("FileObject at (0x%X).\n", IrpSp->FileObject));
-        AFD_DbgPrint(MAX_TRACE, ("FCB at (0x%X).\n", IrpSp->FileObject->FsContext));
-        AFD_DbgPrint(MAX_TRACE, ("CCB at (0x%X).\n", IrpSp->FileObject->FsContext2));
-
-        FCB = IrpSp->FileObject->FsContext;
-        Request = (PFILE_REQUEST_SENDTO)Irp->AssociatedIrp.SystemBuffer;
-        Reply   = (PFILE_REPLY_SENDTO)Irp->AssociatedIrp.SystemBuffer;
-        BufferSize = WSABufferSize(Request->Buffers, Request->BufferCount);
-
-
-        /* FIXME: Should we handle special cases here? */
-        if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
-            BufferSize += sizeof(IPv4_HEADER);
-        }
+  NTSTATUS Status;
+  UINT InputBufferLength;
+  UINT OutputBufferLength;
+  PFILE_REQUEST_SENDTO Request;
+  PFILE_REPLY_SENDTO Reply;
+  PAFDFCB FCB;
+  PVOID SystemVirtualAddress;
+  PVOID DataBufferAddress;
+  ULONG BufferSize;
+  ULONG BytesCopied;
+  PMDL Mdl;
+
+  InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+  OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+  /* Validate parameters */
+  if ((InputBufferLength >= sizeof(FILE_REQUEST_SENDTO)) &&
+    (OutputBufferLength >= sizeof(FILE_REPLY_SENDTO))) {
+
+    AFD_DbgPrint(MAX_TRACE, ("FileObject at (0x%X).\n", IrpSp->FileObject));
+    AFD_DbgPrint(MAX_TRACE, ("FCB at (0x%X).\n", IrpSp->FileObject->FsContext));
+    AFD_DbgPrint(MAX_TRACE, ("CCB at (0x%X).\n", IrpSp->FileObject->FsContext2));
+
+    FCB = IrpSp->FileObject->FsContext;
+    Request = (PFILE_REQUEST_SENDTO)Irp->AssociatedIrp.SystemBuffer;
+    Reply   = (PFILE_REPLY_SENDTO)Irp->AssociatedIrp.SystemBuffer;
+    BufferSize = WSABufferSize(Request->Buffers, Request->BufferCount);
+
+
+    /* FIXME: Should we handle special cases here? */
+    if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
+      BufferSize += sizeof(IPv4_HEADER);
+    }
 
 
-        if (BufferSize != 0) {
-            AFD_DbgPrint(MAX_TRACE, ("Allocating %d bytes for send buffer.\n", BufferSize));
-            SystemVirtualAddress = ExAllocatePool(NonPagedPool, BufferSize);
-            if (!SystemVirtualAddress) {
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-
-            /* FIXME: Should we handle special cases here? */
-            if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
-                DataBufferAddress = SystemVirtualAddress + sizeof(IPv4_HEADER);
-
-                /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
-                ((PSOCKADDR_IN)&FCB->SocketName)->sin_addr.S_un.S_addr = 0x0100007F;
-
-                BuildIPv4Header(
-                    (PIPv4_HEADER)SystemVirtualAddress,
-                    BufferSize,
-                    FCB->Protocol,
-                    &FCB->SocketName,
-                    &Request->To);
-            } else {
-                DataBufferAddress = SystemVirtualAddress;
-            }
-
-            Status = MergeWSABuffers(
-                Request->Buffers,
-                Request->BufferCount,
-                DataBufferAddress,
-                BufferSize,
-                &BytesCopied);
-            if (!NT_SUCCESS(Status)) {
-                AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
-                return Status;
-            }
-        } else {
-            SystemVirtualAddress = NULL;
-            BytesCopied = 0;
-        }
+    if (BufferSize != 0) {
+      AFD_DbgPrint(MAX_TRACE, ("Allocating %d bytes for send buffer.\n", BufferSize));
+      SystemVirtualAddress = ExAllocatePool(NonPagedPool, BufferSize);
+      if (!SystemVirtualAddress) {
+          return STATUS_INSUFFICIENT_RESOURCES;
+      }
+
+      /* FIXME: Should we handle special cases here? */
+      if ((FCB->SocketType == SOCK_RAW) && (FCB->AddressFamily == AF_INET)) {
+        DataBufferAddress = SystemVirtualAddress + sizeof(IPv4_HEADER);
+
+        /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
+        ((PSOCKADDR_IN)&FCB->SocketName)->sin_addr.S_un.S_addr = 0x0100007F;
+
+        BuildIPv4Header(
+            (PIPv4_HEADER)SystemVirtualAddress,
+            BufferSize,
+            FCB->Protocol,
+            &FCB->SocketName,
+            &Request->To);
+      } else {
+        DataBufferAddress = SystemVirtualAddress;
+      }
+
+      Status = MergeWSABuffers(
+        Request->Buffers,
+        Request->BufferCount,
+        DataBufferAddress,
+        BufferSize,
+        &BytesCopied);
+      if (!NT_SUCCESS(Status)) {
+        AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+        return Status;
+      }
+    } else {
+      SystemVirtualAddress = NULL;
+      BytesCopied = 0;
+    }
 
-        Mdl = IoAllocateMdl(
-            SystemVirtualAddress,   /* Virtual address of buffer */
-            BufferSize,             /* Length of buffer */
-            FALSE,                  /* Not secondary */
-            FALSE,                  /* Don't charge quota */
-            NULL);                  /* Don't use IRP */
-        if (!Mdl) {
-            ExFreePool(SystemVirtualAddress);
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
+    Mdl = IoAllocateMdl(
+      SystemVirtualAddress,   /* Virtual address of buffer */
+      BufferSize,             /* Length of buffer */
+      FALSE,                  /* Not secondary */
+      FALSE,                  /* Don't charge quota */
+      NULL);                  /* Don't use IRP */
+    if (!Mdl) {
+      ExFreePool(SystemVirtualAddress);
+      return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
-        MmBuildMdlForNonPagedPool(Mdl);
+    MmBuildMdlForNonPagedPool(Mdl);
 
-        AFD_DbgPrint(MAX_TRACE, ("System virtual address is (0x%X).\n", SystemVirtualAddress));
-        AFD_DbgPrint(MAX_TRACE, ("MDL for data buffer is at (0x%X).\n", Mdl));
+    AFD_DbgPrint(MAX_TRACE, ("System virtual address is (0x%X).\n", SystemVirtualAddress));
+    AFD_DbgPrint(MAX_TRACE, ("MDL for data buffer is at (0x%X).\n", Mdl));
 
-        AFD_DbgPrint(MAX_TRACE, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl));
-        AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl->MdlFlags));
-        AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Next is at (0x%X).\n", Mdl->Next));
-        AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Size is (0x%X).\n", Mdl->Size));
-        AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl->MappedSystemVa));
-        AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer StartVa is (0x%X).\n", Mdl->StartVa));
-        AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl->ByteCount));
-        AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl->ByteOffset));
+    AFD_DbgPrint(MAX_TRACE, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl));
+    AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl->MdlFlags));
+    AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Next is at (0x%X).\n", Mdl->Next));
+    AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer Size is (0x%X).\n", Mdl->Size));
+    AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl->MappedSystemVa));
+    AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer StartVa is (0x%X).\n", Mdl->StartVa));
+    AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl->ByteCount));
+    AFD_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl->ByteOffset));
 
 #if 0
 #ifdef _MSC_VER
-    try {
+  try {
 #endif
-        MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
+      MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
 #ifdef _MSC_VER
-    } except(EXCEPTION_EXECUTE_HANDLER) {
-        AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
-        IoFreeMdl(Mdl);
-        if (BufferSize != 0) {
-            ExFreePool(SystemVirtualAddress);
-        }
-        return STATUS_UNSUCCESSFUL;
-    }
+  } except(EXCEPTION_EXECUTE_HANDLER) {
+      AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
+      IoFreeMdl(Mdl);
+      if (BufferSize != 0) {
+          ExFreePool(SystemVirtualAddress);
+      }
+      return STATUS_UNSUCCESSFUL;
+  }
 #endif
 #endif
 
-        Status = TdiSendDatagram(FCB->TdiAddressObject,
-            &Request->To,
-            Mdl,
-            BufferSize);
+    Status = TdiSendDatagram(FCB->TdiAddressObject,
+        &Request->To,
+        Mdl,
+        BufferSize);
 
-        /* FIXME: Assumes synchronous operation */
+    /* FIXME: Assumes synchronous operation */
 #if 0
-        MmUnlockPages(Mdl);
+    MmUnlockPages(Mdl);
 #endif
 
-        IoFreeMdl(Mdl);
+    IoFreeMdl(Mdl);
 
-        if (BufferSize != 0) {
-            ExFreePool(SystemVirtualAddress);
-        }
+    if (BufferSize != 0) {
+        ExFreePool(SystemVirtualAddress);
+    }
 
-        Reply->NumberOfBytesSent = BufferSize;
-        Reply->Status = NO_ERROR;
-    } else
-        Status = STATUS_INVALID_PARAMETER;
+    Reply->NumberOfBytesSent = BufferSize;
+    Reply->Status = NO_ERROR;
+  } else
+    Status = STATUS_INVALID_PARAMETER;
 
-    AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+  AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
 
-    return Status;
+  return Status;
 }
 
 
@@ -269,57 +269,139 @@ NTSTATUS AfdDispRecvFrom(
  *     Status of operation
  */
 {
-    NTSTATUS Status;
-    UINT InputBufferLength;
-    UINT OutputBufferLength;
-    PFILE_REQUEST_RECVFROM Request;
-    PFILE_REPLY_RECVFROM Reply;
-    PAFD_READ_REQUEST ReadRequest;
-    KIRQL OldIrql;
-    PAFDFCB FCB;
-
-    AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
-
-    InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
-    OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
-
-    /* Validate parameters */
-    if ((InputBufferLength >= sizeof(FILE_REQUEST_RECVFROM)) &&
-        (OutputBufferLength >= sizeof(FILE_REPLY_RECVFROM))) {
-        FCB = IrpSp->FileObject->FsContext;
-
-        Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
-        Reply   = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
-
-        KeAcquireSpinLock(&FCB->ReadRequestQueueLock, &OldIrql);
-
-        if (IsListEmpty(&FCB->ReadRequestQueue)) {
-          /* Queue request and return STATUS_PENDING */
-          ReadRequest->Irp = Irp;
-          ReadRequest->RecvFromRequest = Request;
-          ReadRequest->RecvFromReply = Reply;
-          InsertTailList(&FCB->ReadRequestQueue, &ReadRequest->ListEntry);
-          KeReleaseSpinLock(&FCB->ReadRequestQueueLock, OldIrql);
-          Status = STATUS_PENDING;
-        } else {
-          /* Satisfy the request at once */
-          Status = FillWSABuffers(
-            FCB,
-            Request->Buffers,
-            Request->BufferCount,
-            &Reply->NumberOfBytesRecvd);
-          KeReleaseSpinLock(&FCB->ReadRequestQueueLock, OldIrql);
-          Reply->Status = NO_ERROR;
-        }
-    } else
-        Status = STATUS_INVALID_PARAMETER;
+  NTSTATUS Status;
+  UINT InputBufferLength;
+  UINT OutputBufferLength;
+  PFILE_REQUEST_RECVFROM Request;
+  PFILE_REPLY_RECVFROM Reply;
+  PAFD_READ_REQUEST ReadRequest;
+  DWORD NumberOfBytesRecvd;
+  KIRQL OldIrql;
+  PAFDFCB FCB;
+
+  AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+  InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+  OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+  /* Validate parameters */
+  if ((InputBufferLength >= sizeof(FILE_REQUEST_RECVFROM)) &&
+    (OutputBufferLength >= sizeof(FILE_REPLY_RECVFROM))) {
+    FCB = IrpSp->FileObject->FsContext;
+
+    Request = (PFILE_REQUEST_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
+    Reply   = (PFILE_REPLY_RECVFROM)Irp->AssociatedIrp.SystemBuffer;
+
+    KeAcquireSpinLock(&FCB->ReceiveQueueLock, &OldIrql);
+    if (IsListEmpty(&FCB->ReceiveQueue)) {
+      KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
+
+      /* Queue a read request and return STATUS_PENDING */
+
+      AFD_DbgPrint(MAX_TRACE, ("Queueing read request.\n"));
+
+      /*ReadRequest = (PAFD_READ_REQUEST)ExAllocateFromNPagedLookasideList(
+          &ReadRequestLookasideList);*/
+      ReadRequest = (PAFD_READ_REQUEST)ExAllocatePool(
+        NonPagedPool,
+        sizeof(AFD_READ_REQUEST));
+      if (ReadRequest) {
+        ReadRequest->Irp = Irp;
+        ReadRequest->RecvFromRequest = Request;
+        ReadRequest->RecvFromReply = Reply;
+
+        ExInterlockedInsertTailList(
+          &FCB->ReadRequestQueue,
+          &ReadRequest->ListEntry,
+          &FCB->ReadRequestQueueLock);
+        Status = STATUS_PENDING;
+      } else {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+      }
+    } else {
+      AFD_DbgPrint(MAX_TRACE, ("Satisfying read request.\n"));
+
+      /* Satisfy the request at once */
+      Status = FillWSABuffers(
+        FCB,
+        Request->Buffers,
+        Request->BufferCount,
+        &NumberOfBytesRecvd);
+      KeReleaseSpinLock(&FCB->ReceiveQueueLock, OldIrql);
+      Reply->Status = NO_ERROR;
+      Reply->NumberOfBytesRecvd = NumberOfBytesRecvd;
+      AFD_DbgPrint(MAX_TRACE, ("NumberOfBytesRecvd (0x%X).\n",
+        NumberOfBytesRecvd));
+    }
+  } else {
+    Status = STATUS_INVALID_PARAMETER;
+  }
 
-    AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+  AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
 
-    return Status;
+  return Status;
 }
 
 
+typedef enum {
+  soRead,
+  soWrite,
+  soExcept
+} SelectOperation;
+
+
+DWORD AfdDispSelectEx(
+    LPFD_SET FDSet,
+    SelectOperation Operation)
+{
+  NTSTATUS Status;
+  PAFDFCB Current;
+  KIRQL OldIrql;
+  DWORD Count;
+  ULONG i;
+
+  AFD_DbgPrint(MAX_TRACE, ("FDSet (0x%X)  Operation (0x%X).\n",
+    FDSet, Operation));
+
+  AFD_DbgPrint(MAX_TRACE, ("FDSet->fd_count (0x%X).\n", FDSet->fd_count));
+
+  Count = 0;
+  for (i = 0; i < FDSet->fd_count; i++) {
+    Status = ObReferenceObjectByHandle(
+      (HANDLE)FDSet->fd_array[i],
+      0,
+      IoFileObjectType,
+      KernelMode,
+      (PVOID*)&Current,
+      NULL);
+    if (NT_SUCCESS(Status)) {
+
+      switch (Operation) {
+      case soRead:
+        KeAcquireSpinLock(&Current->ReceiveQueueLock, &OldIrql);
+        if (!IsListEmpty(&Current->ReceiveQueue)) {
+          AFD_DbgPrint(MAX_TRACE, ("Socket is readable.\n"));
+          Count++;
+        }
+        KeReleaseSpinLock(&Current->ReceiveQueueLock, OldIrql);
+        break;
+      case soWrite:
+        /* FIXME: How can we check for writability? */
+        Count++;
+        break;
+      case soExcept:
+        /* FIXME: What is this? */
+        Count++;
+        break;
+      }
+
+      ObDereferenceObject(Current);
+    }
+  }
+
+  return Count;
+}
+
 NTSTATUS AfdDispSelect(
     PIRP Irp,
     PIO_STACK_LOCATION IrpSp)
@@ -332,29 +414,53 @@ NTSTATUS AfdDispSelect(
  *     Status of operation
  */
 {
-    NTSTATUS Status;
-    UINT InputBufferLength;
-    UINT OutputBufferLength;
-    PFILE_REQUEST_SELECT Request;
-    PFILE_REPLY_SELECT Reply;
-    PAFDFCB FCB;
+  NTSTATUS Status;
+  UINT InputBufferLength;
+  UINT OutputBufferLength;
+  PFILE_REQUEST_SELECT Request;
+  PFILE_REPLY_SELECT Reply;
+  DWORD SocketCount;
+  PAFDFCB FCB;
 
-    InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
-    OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+  InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+  OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+  /* Validate parameters */
+  if ((InputBufferLength >= sizeof(FILE_REQUEST_SELECT)) &&
+    (OutputBufferLength >= sizeof(FILE_REPLY_SELECT))) {
+    FCB = IrpSp->FileObject->FsContext;
+
+    Request = (PFILE_REQUEST_SELECT)Irp->AssociatedIrp.SystemBuffer;
+    Reply   = (PFILE_REPLY_SELECT)Irp->AssociatedIrp.SystemBuffer;
+
+    AFD_DbgPrint(MAX_TRACE, ("R (0x%X)  W (0x%X).\n",
+      Request->ReadFDSet, Request->WriteFDSet));
+
+    SocketCount = 0;
+
+    if (Request->ReadFDSet) {
+      AFD_DbgPrint(MAX_TRACE, ("Read.\n"));
+      SocketCount += AfdDispSelectEx(Request->ReadFDSet, soRead);
+    }
+    if (Request->WriteFDSet) {
+      AFD_DbgPrint(MAX_TRACE, ("Write.\n"));
+      SocketCount += AfdDispSelectEx(Request->WriteFDSet, soWrite);
+    }
+    if (Request->ExceptFDSet) {
+      SocketCount += AfdDispSelectEx(Request->ExceptFDSet, soExcept);
+    }
 
-    /* Validate parameters */
-    if ((InputBufferLength >= sizeof(FILE_REQUEST_SELECT)) &&
-        (OutputBufferLength >= sizeof(FILE_REPLY_SELECT))) {
-        FCB = IrpSp->FileObject->FsContext;
+    AFD_DbgPrint(MAX_TRACE, ("Sockets selected (0x%X).\n", SocketCount));
 
-        Request = (PFILE_REQUEST_SELECT)Irp->AssociatedIrp.SystemBuffer;
-        Reply   = (PFILE_REPLY_SELECT)Irp->AssociatedIrp.SystemBuffer;
-    } else
-        Status = STATUS_INVALID_PARAMETER;
+    Reply->Status = NO_ERROR;
+    Reply->SocketCount = SocketCount;
+    Status = STATUS_SUCCESS;
+  } else
+    Status = STATUS_INVALID_PARAMETER;
 
-    AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
+  AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
 
-    return Status;
+  return Status;
 }
 
 /* EOF */
index f1743bc..425df8b 100644 (file)
@@ -120,6 +120,9 @@ NTSTATUS AfdEventReceiveDatagramHandler(
     return STATUS_INSUFFICIENT_RESOURCES;
   }
 
+  /* Copy the data to a local buffer */
+  RtlCopyMemory(ReceiveBuffer, Tsdu, BytesAvailable);
+
   Buffer->Buffer.len = BytesAvailable;
   Buffer->Buffer.buf = ReceiveBuffer;
 
index 2622483..324d514 100644 (file)
@@ -45,7 +45,7 @@ PAFDFCB AfdInitializeFCB(
   KeInitializeSpinLock(&NewFCB->ReadRequestQueueLock);
 
        if (FileObject)
-               FileObject->FsContext = (PVOID)&NewFCB->NTRequiredFCB;
+               FileObject->FsContext = (PVOID)NewFCB;
 
   AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB));
 
index 987bef8..2947304 100644 (file)
@@ -8,72 +8,76 @@
  *   CSH 01/02-2001 Created
  */
 #include <afd.h>
+#include <debug.h>
 
 
 ULONG WSABufferSize(
-    LPWSABUF Buffers,
-    DWORD BufferCount)
+  LPWSABUF Buffers,
+  DWORD BufferCount)
 {
-    ULONG i;
-    LPWSABUF p;
-    ULONG Count = 0;
-
-    p = Buffers;
-    for (i = 0; i < BufferCount; i++) {
-        Count += p->len;
-        p++;
-    }
+  ULONG i;
+  LPWSABUF p;
+  ULONG Count = 0;
+
+  p = Buffers;
+  for (i = 0; i < BufferCount; i++) {
+    Count += p->len;
+    p++;
+  }
 
-    AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
+  AFD_DbgPrint(MAX_TRACE, ("Buffer is %d bytes.\n", Count));
 
-    return Count;
+  return Count;
 }
 
 
 NTSTATUS MergeWSABuffers(
-    LPWSABUF Buffers,
-    DWORD BufferCount,
-    PVOID Destination,
-    ULONG MaxLength,
-    PULONG BytesCopied)
+  LPWSABUF Buffers,
+  DWORD BufferCount,
+  PVOID Destination,
+  ULONG MaxLength,
+  PULONG BytesCopied)
 {
-    NTSTATUS Status;
-    ULONG Length;
-    LPWSABUF p;
-    ULONG i;
+  NTSTATUS Status;
+  ULONG Length;
+  LPWSABUF p;
+  ULONG i;
+
+  *BytesCopied = 0;
+  if (BufferCount == 0)
+    return STATUS_SUCCESS;
+
+  p = Buffers;
 
-    *BytesCopied = 0;
-    if (BufferCount == 0)
-        return STATUS_SUCCESS;
+  AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
+  AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
 
-    p = Buffers;
+  for (i = 0; i < BufferCount; i++) {
+    Length = p->len;
+    if (Length > MaxLength)
+      /* Don't copy out of bounds */
+      Length = MaxLength;
 
+    RtlCopyMemory(Destination, p->buf, Length);
+    Destination += Length;
     AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
+    p++;
     AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
 
-    for (i = 0; i < BufferCount; i++) {
-        Length = p->len;
-        if (Length > MaxLength)
-            /* Don't copy out of bounds */
-            Length = MaxLength;
+    *BytesCopied += Length;
 
-        RtlCopyMemory(Destination, p->buf, Length);
-        Destination += Length;
-        AFD_DbgPrint(MAX_TRACE, ("Destination is 0x%X\n", Destination));
-        p++;
-        AFD_DbgPrint(MAX_TRACE, ("p is 0x%X\n", p));
-
-        *BytesCopied += Length;
-
-        MaxLength -= Length;
-        if (MaxLength == 0)
-            /* Destination buffer is full */
-            break;
-    }
+    MaxLength -= Length;
+    if (MaxLength == 0)
+      /* Destination buffer is full */
+      break;
+  }
 
-    return STATUS_SUCCESS;
+  return STATUS_SUCCESS;
 }
 
+/*
+ * NOTES: ReceiveQueueLock must be acquired for the FCB when called
+ */
 NTSTATUS FillWSABuffers(
     PAFDFCB FCB,
     LPWSABUF Buffers,
@@ -83,7 +87,7 @@ NTSTATUS FillWSABuffers(
   NTSTATUS Status;
   PUCHAR DstData, SrcData;
   UINT DstSize, SrcSize;
-  UINT Count, Total, Length;
+  UINT Count, Total;
   PAFD_BUFFER SrcBuffer;
   PLIST_ENTRY Entry;
   ULONG Size;
@@ -92,6 +96,11 @@ NTSTATUS FillWSABuffers(
   if (BufferCount == 0)
     return STATUS_SUCCESS;
 
+  if (IsListEmpty(&FCB->ReceiveQueue))
+    return STATUS_SUCCESS;
+
+  Entry = RemoveHeadList(&FCB->ReceiveQueue);
+  SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
   SrcData = SrcBuffer->Buffer.buf;
   SrcSize = SrcBuffer->Buffer.len;
 
@@ -101,25 +110,32 @@ NTSTATUS FillWSABuffers(
   /* Copy the data */
   for (Total = 0;;) {
     /* Find out how many bytes we can copy at one time */
-    if (Length < SrcSize)
-      Count = Length;
+    if (DstSize < SrcSize)
+      Count = DstSize;
     else
       Count = SrcSize;
-    if (DstSize < Count)
-      Count = DstSize;
+
+    AFD_DbgPrint(MAX_TRACE, ("DstData (0x%X) SrcData (0x%X) Count (0x%X).\n",
+      DstData, SrcData, Count));
 
     RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, Count);
 
-    Total  += Count;
-    Length -= Count;
+    Total += Count;
 
     SrcSize -= Count;
     if (SrcSize == 0) {
       ExFreePool(SrcBuffer->Buffer.buf);
       ExFreePool(SrcBuffer);
 
-      /* No more bytes in source buffer. Proceed to
-         the next buffer in the source buffer chain */
+      /* No more bytes in source buffer. Proceed to the next buffer
+         in the source buffer chain if there is one */
+      if (IsListEmpty(&FCB->ReceiveQueue)) {
+        SrcBuffer = NULL;
+        SrcData = 0;
+        SrcSize = 0;
+        break;
+      }
+
       Entry = RemoveHeadList(&FCB->ReceiveQueue);
       SrcBuffer = CONTAINING_RECORD(Entry, AFD_BUFFER, ListEntry);
       SrcData = SrcBuffer->Buffer.buf;
@@ -137,13 +153,13 @@ NTSTATUS FillWSABuffers(
       DstData = Buffers->buf;
       DstSize = Buffers->len;
     }
-
-    if (Length == 0)
-      break;
   }
 
   if (SrcSize > 0) {
     InsertHeadList(&FCB->ReceiveQueue, Entry);
+  } else if (SrcBuffer != NULL) {
+    ExFreePool(SrcBuffer->Buffer.buf);
+    ExFreePool(SrcBuffer);
   }
 
   *BytesCopied = Total;
@@ -165,61 +181,61 @@ ULONG ChecksumCompute(
  *     Checksum of buffer
  */
 {
-    /* FIXME: This should be done in assembler */
+  /* FIXME: This should be done in assembler */
 
-    register ULONG Sum = Seed;
+  register ULONG Sum = Seed;
 
-    while (Count > 1) {
-        Sum             += *(PUSHORT)Data;
-        Count           -= 2;
-        (ULONG_PTR)Data += 2;
-    }
+  while (Count > 1) {
+    Sum             += *(PUSHORT)Data;
+    Count           -= 2;
+    (ULONG_PTR)Data += 2;
+  }
 
-    /* Add left-over byte, if any */
-    if (Count > 0)
-        Sum += *(PUCHAR)Data;
+  /* 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);
+  /* Fold 32-bit sum to 16 bits */
+  while (Sum >> 16)
+    Sum = (Sum & 0xFFFF) + (Sum >> 16);
 
-    return ~Sum;
+  return ~Sum;
 }
 
 VOID BuildIPv4Header(
-    PIPv4_HEADER IPHeader,
-    ULONG TotalSize,
-    ULONG Protocol,
-    PSOCKADDR SourceAddress,
-    PSOCKADDR DestinationAddress)
+  PIPv4_HEADER IPHeader,
+  ULONG TotalSize,
+  ULONG Protocol,
+  PSOCKADDR SourceAddress,
+  PSOCKADDR DestinationAddress)
 {
-    PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
-    PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
-
-    /* Version = 4, Length = 5 DWORDs */
-    IPHeader->VerIHL = 0x45;
-    /* Normal Type-of-Service */
-    IPHeader->Tos = 0;
-    /* Length of header and data */
-    IPHeader->TotalLength = WH2N((USHORT)TotalSize);
-    /* Identification */
-    IPHeader->Id = 0;
-    /* One fragment at offset 0 */
-    IPHeader->FlagsFragOfs = 0;
-    /* Time-to-Live is 128 */
-    IPHeader->Ttl = 128;
-    /* Protocol number */
-    IPHeader->Protocol = Protocol;
-    /* Checksum is 0 (calculated later) */
-    IPHeader->Checksum = 0;
-    /* Source address */
-    IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
-    /* Destination address */
-    IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
-
-    /* Calculate checksum of IP header */
-    IPHeader->Checksum = (USHORT)
-        ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);
+  PSOCKADDR_IN SrcNameIn = (PSOCKADDR_IN)SourceAddress;
+  PSOCKADDR_IN DstNameIn = (PSOCKADDR_IN)DestinationAddress;
+
+  /* Version = 4, Length = 5 DWORDs */
+  IPHeader->VerIHL = 0x45;
+  /* Normal Type-of-Service */
+  IPHeader->Tos = 0;
+  /* Length of header and data */
+  IPHeader->TotalLength = WH2N((USHORT)TotalSize);
+  /* Identification */
+  IPHeader->Id = 0;
+  /* One fragment at offset 0 */
+  IPHeader->FlagsFragOfs = 0;
+  /* Time-to-Live is 128 */
+  IPHeader->Ttl = 128;
+  /* Protocol number */
+  IPHeader->Protocol = Protocol;
+  /* Checksum is 0 (calculated later) */
+  IPHeader->Checksum = 0;
+  /* Source address */
+  IPHeader->SrcAddr = SrcNameIn->sin_addr.S_un.S_addr;
+  /* Destination address */
+  IPHeader->DstAddr = DstNameIn->sin_addr.S_un.S_addr;
+
+  /* Calculate checksum of IP header */
+  IPHeader->Checksum = (USHORT)
+    ChecksumCompute(IPHeader, sizeof(IPv4_HEADER), 0);
 }
 
 /* EOF */
index 7f01dde..269b75e 100644 (file)
@@ -217,6 +217,8 @@ typedef struct IPv4_HEADER {
 
 
 extern NPAGED_LOOKASIDE_LIST BufferLookasideList;
+extern NPAGED_LOOKASIDE_LIST ReadRequestLookasideList;
+
 
 /* Prototypes from dispatch.c */
 
index 2e581b0..dc1fe31 100644 (file)
@@ -53,6 +53,7 @@ extern DWORD DebugTraceLevel;
 #define ASSERT(x) if (!(x)) { AFD_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
 #endif /* NASSERT */
 
+#define ASSERT_KM(x) ASSERT((x) >= 0xC0000000)
 #define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
 
 #else /* DBG */
@@ -60,12 +61,14 @@ extern DWORD DebugTraceLevel;
 #define AFD_DbgPrint(_t_, _x_)
 
 #define ASSERT_IRQL(x)
+#define ASSERTKM(x)
 #define ASSERT(x)
 
 #endif /* DBG */
 
 
 #define assert(x) ASSERT(x)
+#define assert_km(x) ASSERT_KM(x)
 #define assert_irql(x) ASSERT_IRQL(x)
 
 
index ac957f2..1b19594 100644 (file)
@@ -197,11 +197,15 @@ VOID ICMPReceive(
             return;
 
         /* Copy ICMP header and data into new packet */
-        RtlCopyMemory(NewPacket->Data, IPPacket->Data, DataSize  + sizeof(ICMP_HEADER));
+        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;
 
+        DisplayIPPacket(IPPacket);
+
+        DisplayIPPacket(NewPacket);
+
         ICMPTransmit(NTE, NewPacket);
 
         TI_DbgPrint(DEBUG_ICMP, ("Echo reply sent.\n"));
index e4a3f73..9cbff15 100644 (file)
@@ -20,7 +20,7 @@
 
 /* See debug.h for debug/trace constants */
 DWORD DebugTraceLevel = MIN_TRACE;
-//DWORD DebugTraceLevel = MAX_TRACE;
+//DWORD DebugTraceLevel = MAX_TRACE | DEBUG_ICMP | DEBUG_BUFFER;
 
 #endif /* DBG */
 
index 3323cb8..d779b6f 100644 (file)
@@ -239,6 +239,7 @@ VOID DGDeliverData(
  *     Address  = Remote address the packet came from
  *     IPPacket = Pointer to IP packet to deliver
  *     DataSize = Number of bytes in data area
+ *                (incl. IP header for raw IP file objects)
  * NOTES:
  *     If there is a receive request, then we copy the data to the
  *     buffer supplied by the user and complete the receive request.
@@ -253,11 +254,19 @@ VOID DGDeliverData(
     PVOID SourceAddress;
     ULONG BytesTaken;
     NTSTATUS Status;
+    PVOID DataBuffer;
 
     TI_DbgPrint(MAX_TRACE, ("Called.\n"));
 
     KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
 
+    if (AddrFile->Protocol == IPPROTO_UDP) {
+        DataBuffer = IPPacket->Data;
+    } else {
+        /* Give client the IP header too if it is a raw IP file object */
+        DataBuffer = IPPacket->Header;
+    }
+
     if (!IsListEmpty(&AddrFile->ReceiveQueue)) {
         PLIST_ENTRY CurrentEntry;
         PDATAGRAM_RECEIVE_REQUEST Current;
@@ -296,7 +305,7 @@ VOID DGDeliverData(
             /* Copy the data into buffer provided by the user */
             CopyBufferToBufferChain(Current->Buffer,
                                     0,
-                                    IPPacket->Data,
+                                    DataBuffer,
                                     DataSize);
 
             /* Complete the receive request */
@@ -332,7 +341,7 @@ VOID DGDeliverData(
                                    DataSize,
                                    DataSize,
                                    &BytesTaken,
-                                   IPPacket->Data,
+                                   DataBuffer,
                                    NULL);
     } else {
       TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
index 2a0a0f3..5b206c2 100644 (file)
@@ -364,7 +364,7 @@ WSPSelect(
 
   AFD_DbgPrint(MAX_TRACE, ("readfds (0x%X)  writefds (0x%X)  exceptfds (0x%X).\n",
         readfds, writefds, exceptfds));
-
+#if 0
   /* FIXME: For now, all reads are timed out immediately */
   if (readfds != NULL) {
     AFD_DbgPrint(MID_TRACE, ("Timing out read query.\n"));
@@ -378,8 +378,7 @@ WSPSelect(
     *lpErrno = NO_ERROR;
     return 1;
   }
-
-  return 0;
+#endif
 
   ReadSize = 0;
   if ((readfds != NULL) && (readfds->fd_count > 0)) {
@@ -406,26 +405,35 @@ WSPSelect(
   }
 
   /* Put FD SETs after request structure */
-  Current = (Request + sizeof(FILE_REQUEST_SELECT));
-  Request->ReadFDSet = (LPFD_SET)Current;
+  Current = (Request + 1);
 
   if (ReadSize > 0) {
+    Request->ReadFDSet = (LPFD_SET)Current;
+    Current += ReadSize;
     RtlCopyMemory(Request->ReadFDSet, readfds, ReadSize);
+  } else {
+    Request->ReadFDSet = NULL;
   }
 
-  Current += ReadSize;
-
   if (WriteSize > 0) {
+    Request->WriteFDSet = (LPFD_SET)Current;
+    Current += WriteSize;
     RtlCopyMemory(Request->WriteFDSet, writefds, WriteSize);
+  } else {
+    Request->WriteFDSet = NULL;
   }
 
-  Current += WriteSize;
-
   if (ExceptSize > 0) {
+    Request->ExceptFDSet = (LPFD_SET)Current;
     RtlCopyMemory(Request->ExceptFDSet, exceptfds, ExceptSize);
+  } else {
+    Request->ExceptFDSet = NULL;
   }
 
-  Status = NtDeviceIoControlFile(CommandChannel,
+  AFD_DbgPrint(MAX_TRACE, ("R1 (0x%X)  W1 (0x%X).\n", Request->ReadFDSet, Request->WriteFDSet));
+
+  Status = NtDeviceIoControlFile(
+    CommandChannel,
     NULL,
                NULL,
                NULL,   
@@ -441,12 +449,7 @@ WSPSelect(
        if (Status == STATUS_PENDING) {
     AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
     /* FIXME: Wait only for blocking sockets */
-               if (!NT_SUCCESS(NtWaitForSingleObject(CommandChannel, FALSE, NULL))) {
-      AFD_DbgPrint(MIN_TRACE, ("Wait failed.\n"));
-      /* FIXME: What error code should be returned? */
-                       *lpErrno = WSAENOBUFS;
-                       return SOCKET_ERROR;
-               }
+               Status = NtWaitForSingleObject(CommandChannel, FALSE, NULL);
   }
 
   if (!NT_SUCCESS(Status)) {
@@ -455,11 +458,12 @@ WSPSelect(
     return SOCKET_ERROR;
        }
 
-  AFD_DbgPrint(MAX_TRACE, ("Select successful.\n"));
+  AFD_DbgPrint(MAX_TRACE, ("Select successful. Status (0x%X)  Count (0x%X).\n",
+    Reply.Status, Reply.SocketCount));
 
-  *lpErrno = NO_ERROR;
+  *lpErrno = Reply.Status;
 
-  return 0;
+  return Reply.SocketCount;
 }
 
 
@@ -722,6 +726,8 @@ DllMain(HANDLE hInstDll,
         break;
     }
 
+    AFD_DbgPrint(MAX_TRACE, ("DllMain of msafd.dll (leaving)\n"));
+
     return TRUE;
 }
 
index c7ef48d..c0d7dea 100644 (file)
@@ -113,12 +113,7 @@ WSPRecvFrom(
        if (Status == STATUS_PENDING) {
     AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
     /* FIXME: Wait only for blocking sockets */
-               if (!NT_SUCCESS(NtWaitForSingleObject((HANDLE)s, FALSE, NULL))) {
-      AFD_DbgPrint(MIN_TRACE, ("Wait failed.\n"));
-      /* FIXME: What error code should be returned? */
-                       *lpErrno = WSAENOBUFS;
-                       return SOCKET_ERROR;
-               }
+               Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
   }
 
   if (!NT_SUCCESS(Status)) {
@@ -127,7 +122,18 @@ WSPRecvFrom(
     return SOCKET_ERROR;
        }
 
-  AFD_DbgPrint(MAX_TRACE, ("Receive successful.\n"));
+  AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n",
+    Reply.NumberOfBytesRecvd));
+
+  AFD_DbgPrint(MAX_TRACE, ("lpNumberOfBytesRecvd (0x%X).\n",
+    lpNumberOfBytesRecvd));
+
+  *lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd;
+  //*lpFlags = 0;
+  ((PSOCKADDR_IN)lpFrom)->sin_family = AF_INET;
+  ((PSOCKADDR_IN)lpFrom)->sin_port = 0;
+  ((PSOCKADDR_IN)lpFrom)->sin_addr.S_un.S_addr = 0x0100007F;
+  *lpFromLen = sizeof(SOCKADDR_IN);
 
   return 0;
 }
@@ -223,12 +229,7 @@ WSPSendTo(
        if (Status == STATUS_PENDING) {
     AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
     /* FIXME: Wait only for blocking sockets */
-               if (!NT_SUCCESS(NtWaitForSingleObject((HANDLE)s, FALSE, NULL))) {
-      AFD_DbgPrint(MAX_TRACE, ("Wait failed.\n"));
-      /* FIXME: What error code should be returned? */
-      *lpErrno = WSAENOBUFS;
-      return SOCKET_ERROR;
-               }
+    Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
   }
 
   if (!NT_SUCCESS(Status)) {
index d7b1077..0d641e3 100644 (file)
@@ -396,6 +396,8 @@ DllMain(HANDLE hInstDll,
     break;
   }
 
+  WS_DbgPrint(MAX_TRACE, ("DllMain of ws2_32.dll. Leaving.\n"));
+
   return TRUE;
 }
 
index 11d3d09..61bf81b 100644 (file)
@@ -404,13 +404,16 @@ inet_ntoa(
     PCHAR p;
 
     p = ((PWINSOCK_THREAD_BLOCK)NtCurrentTeb()->WinSockData)->Intoa;
-    _itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10);
+    _itoa(in.S_un.S_addr & 0xFF, b, 10);
     strcpy(p, b);
-    _itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10);
-    strcat(p, b);
     _itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10);
+    strcat(p, ".");
     strcat(p, b);
-    _itoa(in.S_un.S_addr & 0xFF, b, 10);
+    _itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10);
+    strcat(p, ".");
+    strcat(p, b);
+    _itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10);
+    strcat(p, ".");
     strcat(p, b);
     return (CHAR FAR*)p;
 }
index 8b4a30d..2e8871e 100644 (file)
@@ -43,7 +43,9 @@ recvfrom(
     WSABuf.len = len;
     WSABuf.buf = (CHAR FAR*)buf;
 
-    return WSARecvFrom(s, &WSABuf, 1, &BytesReceived, (LPDWORD)&flags, from, fromlen, NULL, NULL);
+    WSARecvFrom(s, &WSABuf, 1, &BytesReceived, (LPDWORD)&flags, from, fromlen, NULL, NULL);
+
+    return BytesReceived;
 }