[SDK] One step further towards ReactOS source code tree restructure: the sdk folder...
[reactos.git] / reactos / sdk / lib / drivers / ip / network / loopback.c
diff --git a/reactos/sdk/lib/drivers/ip/network/loopback.c b/reactos/sdk/lib/drivers/ip/network/loopback.c
new file mode 100644 (file)
index 0000000..e44cc69
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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 (chorns@users.sourceforge.net)
+ * REVISIONS:
+ *   CSH 01/08-2000 Created
+ */
+
+#include "precomp.h"
+
+PIP_INTERFACE Loopback = NULL;
+
+VOID LoopPassiveWorker(
+  PVOID Context)
+{
+  PIP_PACKET IPPacket = Context;
+
+  /* IPReceive() takes care of the NDIS packet */
+  IPReceive(Loopback, IPPacket);
+
+  ExFreePool(IPPacket);
+}
+
+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)
+ */
+{
+    PCHAR PacketBuffer;
+    UINT PacketLength;
+    PNDIS_PACKET XmitPacket;
+    NDIS_STATUS NdisStatus;
+    PIP_PACKET IPPacket;
+
+    ASSERT_KM_POINTER(NdisPacket);
+    ASSERT_KM_POINTER(PC(NdisPacket));
+    ASSERT_KM_POINTER(PC(NdisPacket)->DLComplete);
+
+    TI_DbgPrint(MAX_TRACE, ("Called (NdisPacket = %x)\n", NdisPacket));
+
+    GetDataPtr( NdisPacket, 0, &PacketBuffer, &PacketLength );
+
+    NdisStatus = AllocatePacketWithBuffer
+        ( &XmitPacket, PacketBuffer, PacketLength );
+
+    if( NT_SUCCESS(NdisStatus) ) {
+        IPPacket = ExAllocatePool(NonPagedPool, sizeof(IP_PACKET));
+        if (IPPacket)
+        {
+            IPInitializePacket(IPPacket, 0);
+
+            IPPacket->NdisPacket = XmitPacket;
+
+            GetDataPtr(IPPacket->NdisPacket,
+                       0,
+                       (PCHAR*)&IPPacket->Header,
+                       &IPPacket->TotalSize);
+
+            IPPacket->MappedHeader = TRUE;
+
+            if (!ChewCreate(LoopPassiveWorker, IPPacket))
+            {
+                IPPacket->Free(IPPacket);
+                ExFreePool(IPPacket);
+                NdisStatus = NDIS_STATUS_RESOURCES;
+            }
+        }
+        else
+            NdisStatus = NDIS_STATUS_RESOURCES;
+    }
+
+    (PC(NdisPacket)->DLComplete)
+        ( PC(NdisPacket)->Context, NdisPacket, NdisStatus );
+}
+
+NDIS_STATUS LoopRegisterAdapter(
+  PNDIS_STRING AdapterName,
+  PLAN_ADAPTER *Adapter)
+/*
+ * FUNCTION: Registers loopback adapter with the network layer
+ * ARGUMENTS:
+ *   AdapterName = Unused
+ *   Adapter     = Unused
+ * RETURNS:
+ *   Status of operation
+ */
+{
+  LLIP_BIND_INFO BindInfo;
+
+  TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
+  /* Bind the adapter to network (IP) layer */
+  BindInfo.Context = NULL;
+  BindInfo.HeaderSize = 0;
+  BindInfo.MinFrameSize = 0;
+  BindInfo.Address = NULL;
+  BindInfo.AddressLength = 0;
+  BindInfo.Transmit = LoopTransmit;
+
+  Loopback = IPCreateInterface(&BindInfo);
+  if (!Loopback) return NDIS_STATUS_RESOURCES;
+    
+  Loopback->MTU = 16384;
+
+  Loopback->Name.Buffer = L"Loopback";
+  Loopback->Name.MaximumLength = Loopback->Name.Length =
+      wcslen(Loopback->Name.Buffer) * sizeof(WCHAR);
+
+  AddrInitIPv4(&Loopback->Unicast, LOOPBACK_ADDRESS_IPv4);
+  AddrInitIPv4(&Loopback->Netmask, LOOPBACK_ADDRMASK_IPv4);
+  AddrInitIPv4(&Loopback->Broadcast, LOOPBACK_BCASTADDR_IPv4);
+
+  IPRegisterInterface(Loopback);
+    
+  IPAddInterfaceRoute(Loopback);
+
+  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+
+  return NDIS_STATUS_SUCCESS;
+}
+
+
+NDIS_STATUS LoopUnregisterAdapter(
+  PLAN_ADAPTER Adapter)
+/*
+ * FUNCTION: Unregisters loopback adapter with the network layer
+ * 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 != NULL)
+    {
+      IPUnregisterInterface(Loopback);
+      IPDestroyInterface(Loopback);
+      Loopback = NULL;
+    }
+
+  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+
+  return NDIS_STATUS_SUCCESS;
+}