/* * 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; }