Author: jgardou
Date: Mon Nov 10 18:00:09 2014
New Revision: 65362
URL:
http://svn.reactos.org/svn/reactos?rev=65362&view=rev
Log:
[TCPIP]
Start a new implementation using lwip *for real*.
The goal being to let lwip do all the dirty work for us, taking the full power of it,
including TCP, ICMP, SNMP, UDP, raw IP, etc.
Commmit what I got so far, including:
- registering the tcp/ip protocol to NDIS
- Creating the loopback/adapter interface as wrappers around lwip_netif structures.
- Querying a few pieces of information from the said interface.
- Sending and receiving raw/UDP diagrams through lwip (not quite working yet, but soon).
- Registering entities "instances".
Added:
branches/tcpip_revolution/drivers/network/tcpip/CMakeLists.txt (with props)
branches/tcpip_revolution/drivers/network/tcpip/address.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/address.h (with props)
branches/tcpip_revolution/drivers/network/tcpip/connection.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/entities.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/entities.h (with props)
branches/tcpip_revolution/drivers/network/tcpip/information.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/information.h (with props)
branches/tcpip_revolution/drivers/network/tcpip/interface.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/interface.h (with props)
branches/tcpip_revolution/drivers/network/tcpip/main.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.h (with props)
branches/tcpip_revolution/drivers/network/tcpip/precomp.h (with props)
branches/tcpip_revolution/drivers/network/tcpip/stubs.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/tcp.c (with props)
branches/tcpip_revolution/drivers/network/tcpip/tcp.h (with props)
branches/tcpip_revolution/drivers/network/tcpip/tcpip.rc (with props)
branches/tcpip_revolution/drivers/network/tcpip/tcpip.spec (with props)
Added: branches/tcpip_revolution/drivers/network/tcpip/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/CMakeLists.txt (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/CMakeLists.txt [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,31 @@
+
+include_directories(
+ ${REACTOS_SOURCE_DIR}/lib/drivers/lwip/src/include
+ ${REACTOS_SOURCE_DIR}/lib/drivers/lwip/src/include/ipv4)
+
+add_definitions(-DNDIS51)
+
+spec2def(tcpip.sys tcpip.spec)
+
+list(APPEND SOURCE
+ address.c
+ entities.c
+ information.c
+ interface.c
+ main.c
+ ndis_lwip.c
+ tcp.c
+ stubs.c
+ precomp.h
+)
+
+add_library(tcpip SHARED
+ ${SOURCE}
+ tcpip.rc
+ ${CMAKE_CURRENT_BINARY_DIR}/tcpip.def)
+
+target_link_libraries(tcpip lwip ${PSEH_LIB} libcntpr)
+set_module_type(tcpip kernelmodedriver)
+add_importlibs(tcpip ndis ntoskrnl hal)
+add_pch(tcpip precomp.h SOURCE)
+add_cd_file(TARGET tcpip DESTINATION reactos/system32/drivers FOR all)
Propchange: branches/tcpip_revolution/drivers/network/tcpip/CMakeLists.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/tcpip_revolution/drivers/network/tcpip/address.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/address.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/address.c [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,584 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/address.c
+ * PURPOSE: tcpip.sys: addresses abstraction
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+typedef struct
+{
+ LIST_ENTRY ListEntry;
+ TDI_ADDRESS_IP RemoteAddress;
+ PIRP Irp;
+ PVOID Buffer;
+ ULONG BufferLength;
+ PTDI_CONNECTION_INFORMATION ReturnInfo;
+} RECEIVE_DATAGRAM_REQUEST;
+
+/* The pool tags we will use for all of our allocation */
+#define TAG_ADDRESS_FILE 'FrdA'
+
+/* The list of shared addresses */
+static KSPIN_LOCK AddressListLock;
+static LIST_ENTRY AddressListHead;
+
+void
+TcpIpInitializeAddresses(void)
+{
+ KeInitializeSpinLock(&AddressListLock);
+ InitializeListHead(&AddressListHead);
+}
+
+static
+BOOLEAN
+AddrIsUnspecified(
+ _In_ PTDI_ADDRESS_IP Address)
+{
+ return ((Address->in_addr == 0) || (Address->in_addr == 0xFFFFFFFF));
+}
+
+static
+BOOLEAN
+ReceiveDatagram(
+ ADDRESS_FILE* AddressFile,
+ struct pbuf *p,
+ ip_addr_t *addr,
+ u16_t port,
+ BOOLEAN MustFree)
+{
+ KIRQL OldIrql;
+ LIST_ENTRY* ListEntry;
+ RECEIVE_DATAGRAM_REQUEST* Request;
+ ip_addr_t RequestAddr;
+ BOOLEAN Result = FALSE;
+
+ /* Block any cancellation that could occur */
+ IoAcquireCancelSpinLock(&OldIrql);
+ KeAcquireSpinLockAtDpcLevel(&AddressFile->RequestLock);
+
+ ListEntry = AddressFile->RequestListHead.Flink;
+ while (ListEntry != &AddressFile->RequestListHead)
+ {
+ Request = CONTAINING_RECORD(ListEntry, RECEIVE_DATAGRAM_REQUEST, ListEntry);
+ ListEntry = ListEntry->Flink;
+
+ ip4_addr_set_u32(&RequestAddr, Request->RemoteAddress.in_addr);
+
+ if ((RequestAddr.addr == IPADDR_ANY) ||
+ (ip_addr_cmp(&RequestAddr, addr) &&
+ ((Request->RemoteAddress.sin_port == port) || !port)))
+ {
+ PTA_IP_ADDRESS ReturnAddress;
+
+ /* We found a request for this one */
+ IoSetCancelRoutine(Request->Irp, NULL);
+ RemoveEntryList(&Request->ListEntry);
+
+ KeReleaseSpinLockFromDpcLevel(&AddressFile->RequestLock);
+ IoReleaseCancelSpinLock(OldIrql);
+
+ /* Return what we have to */
+ pbuf_copy_partial(p, Request->Buffer, Request->BufferLength, 0);
+ ReturnAddress = Request->ReturnInfo->RemoteAddress;
+ ReturnAddress->Address->AddressLength = TDI_ADDRESS_LENGTH_IP;
+ ReturnAddress->Address->AddressType = TDI_ADDRESS_TYPE_IP;
+ ReturnAddress->Address->Address->sin_port = port;
+ ReturnAddress->Address->Address->in_addr = ip4_addr_get_u32(addr);
+ RtlZeroMemory(ReturnAddress->Address->Address->sin_zero,
+ sizeof(ReturnAddress->Address->Address->sin_zero));
+
+ Request->Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ Result = TRUE;
+
+ IoCompleteRequest(Request->Irp, IO_NETWORK_INCREMENT);
+
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
+
+ /* Restart from the beginning of the list */
+ IoAcquireCancelSpinLock(&OldIrql);
+ KeAcquireSpinLockAtDpcLevel(&AddressFile->RequestLock);
+ ListEntry = AddressFile->RequestListHead.Flink;
+ }
+ }
+
+ KeReleaseSpinLockFromDpcLevel(&AddressFile->RequestLock);
+ IoReleaseCancelSpinLock(OldIrql);
+ if (Result || MustFree)
+ pbuf_free(p);
+
+ return Result;
+}
+
+static
+void
+lwip_udp_ReceiveDatagram_callback(
+ void *arg,
+ struct udp_pcb *pcb,
+ struct pbuf *p,
+ ip_addr_t *addr,
+ u16_t port)
+{
+ UNREFERENCED_PARAMETER(pcb);
+
+ ReceiveDatagram(arg, p, addr, port, TRUE);
+}
+
+static
+u8_t
+lwip_raw_ReceiveDatagram_callback(
+ void *arg,
+ struct raw_pcb *pcb,
+ struct pbuf *p,
+ ip_addr_t *addr)
+{
+ UNREFERENCED_PARAMETER(pcb);
+
+ return ReceiveDatagram(arg, p, addr, 0, FALSE);
+}
+
+NTSTATUS
+TcpIpCreateAddress(
+ _Inout_ PIRP Irp,
+ _Inout_ PTDI_ADDRESS_IP Address,
+ _In_ IPPROTO Protocol
+)
+{
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ ADDRESS_FILE *AddressFile;
+ LIST_ENTRY* ListEntry;
+ KIRQL OldIrql;
+ USHORT Port = 1;
+
+ /* See if this port is already taken, and find a free one if needed. */
+ KeAcquireSpinLock(&AddressListLock, &OldIrql);
+
+ ListEntry = AddressListHead.Flink;
+ while (ListEntry != &AddressListHead)
+ {
+ AddressFile = CONTAINING_RECORD(ListEntry, ADDRESS_FILE, ListEntry);
+
+ if (Address->sin_port)
+ {
+ if ((AddressFile->Protocol == Protocol) &&
+ (AddressFile->Address.sin_port == Address->sin_port))
+ {
+ if (IrpSp->Parameters.Create.ShareAccess)
+ {
+ /* Good, we found the shared address we were looking for */
+ InterlockedIncrement(&AddressFile->RefCount);
+ KeReleaseSpinLock(&AddressListLock, OldIrql);
+ goto Success;
+ }
+
+ KeReleaseSpinLock(&AddressListLock, OldIrql);
+ return STATUS_ADDRESS_ALREADY_EXISTS;
+ }
+ }
+ else if ((AddressFile->Address.sin_port == Port)
+ && AddressFile->Protocol == Protocol)
+ {
+ Port++;
+ if (Port == 0)
+ {
+ /* Oh no. Already 65535 ports occupied! */
+ DPRINT1("No more free ports for protocol %d!\n", Protocol);
+ KeReleaseSpinLock(&AddressListLock, OldIrql);
+ return STATUS_TOO_MANY_ADDRESSES;
+ }
+
+ /* We must start anew to check again the previous entries in the list */
+ ListEntry = &AddressListHead;
+ }
+ ListEntry = ListEntry->Flink;
+ }
+
+ if (!AddrIsUnspecified(Address))
+ {
+ /* Find the local interface for this address */
+ struct netif* lwip_netif = netif_list;
+ ip_addr_t IpAddr;
+
+ ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
+ while (lwip_netif)
+ {
+ if (ip_addr_cmp(&IpAddr, &lwip_netif->ip_addr))
+ {
+ break;
+ }
+ lwip_netif = lwip_netif->next;
+ }
+
+ if (!lwip_netif)
+ {
+ DPRINT1("Cound not find an interface for address 0x08x\n",
AddressFile->Address.in_addr);
+ KeReleaseSpinLock(&AddressListLock, OldIrql);
+ return STATUS_INVALID_ADDRESS;
+ }
+ }
+
+ /* Allocate our new address file */
+ AddressFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(*AddressFile),
TAG_ADDRESS_FILE);
+ if (!AddressFile)
+ {
+ return STATUS_NO_MEMORY;
+ }
+
+ RtlZeroMemory(AddressFile, sizeof(*AddressFile));
+ AddressFile->RefCount = 1;
+ RtlCopyMemory(&AddressFile->Address, Address, sizeof(*Address));
+ AddressFile->Protocol = Protocol;
+ if (!Address->sin_port)
+ AddressFile->Address.sin_port = Port;
+
+ /* Initialize the datagram request stuff */
+ KeInitializeSpinLock(&AddressFile->RequestLock);
+ InitializeListHead(&AddressFile->RequestListHead);
+
+ /* Give it an entity ID and open a PCB is needed. */
+ switch (Protocol)
+ {
+ case IPPROTO_TCP:
+ InsertEntityInstance(CO_TL_ENTITY, &AddressFile->Instance);
+ break;
+ case IPPROTO_UDP:
+ {
+ ip_addr_t IpAddr;
+ ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
+ InsertEntityInstance(CL_TL_ENTITY, &AddressFile->Instance);
+ AddressFile->lwip_udp_pcb = udp_new();
+ udp_bind(AddressFile->lwip_udp_pcb, &IpAddr,
AddressFile->Address.sin_port);
+ ip_set_option(AddressFile->lwip_udp_pcb, SOF_BROADCAST);
+ /* Register our recv handler to lwip */
+ udp_recv(
+ AddressFile->lwip_udp_pcb,
+ lwip_udp_ReceiveDatagram_callback,
+ AddressFile);
+ break;
+ }
+ default:
+ {
+ ip_addr_t IpAddr;
+ ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
+ if (Protocol == IPPROTO_ICMP)
+ InsertEntityInstance(ER_ENTITY, &AddressFile->Instance);
+ else
+ InsertEntityInstance(CL_TL_ENTITY, &AddressFile->Instance);
+ AddressFile->lwip_raw_pcb = raw_new(Protocol);
+ raw_bind(AddressFile->lwip_raw_pcb, &IpAddr);
+ ip_set_option(AddressFile->lwip_raw_pcb, SOF_BROADCAST);
+ /* Register our recv handler for lwip */
+ raw_recv(
+ AddressFile->lwip_raw_pcb,
+ lwip_raw_ReceiveDatagram_callback,
+ AddressFile);
+ break;
+ }
+ }
+
+ /* Insert it into the list. */
+ InsertTailList(&AddressListHead, &AddressFile->ListEntry);
+ KeReleaseSpinLock(&AddressListLock, OldIrql);
+
+Success:
+ IrpSp->FileObject->FsContext = AddressFile;
+ IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+TcpIpCloseAddress(
+ _Inout_ ADDRESS_FILE* AddressFile
+)
+{
+ KIRQL OldIrql;
+
+ /* Lock the global address list */
+ KeAcquireSpinLock(&AddressListLock, &OldIrql);
+
+ if (InterlockedDecrement(&AddressFile->RefCount) != 0)
+ {
+ /* There are still some open handles for this address */
+ KeReleaseSpinLock(&AddressListLock, OldIrql);
+ return STATUS_SUCCESS;
+ }
+
+ /* Remove from the list and free the structure */
+ RemoveEntryList(&AddressFile->ListEntry);
+ KeReleaseSpinLock(&AddressListLock, OldIrql);
+
+ RemoveEntityInstance(&AddressFile->Instance);
+ ExFreePoolWithTag(AddressFile, TAG_ADDRESS_FILE);
+
+
+ return STATUS_SUCCESS;
+}
+
+static
+NTSTATUS
+ExtractAddressFromList(
+ _In_ PTRANSPORT_ADDRESS AddressList,
+ _Out_ PTDI_ADDRESS_IP Address)
+{
+ PTA_ADDRESS CurrentAddress;
+ INT i;
+
+ CurrentAddress = &AddressList->Address[0];
+
+ /* We can only use IP addresses. Search the list until we find one */
+ for (i = 0; i < AddressList->TAAddressCount; i++)
+ {
+ if (CurrentAddress->AddressType == TDI_ADDRESS_TYPE_IP)
+ {
+ if (CurrentAddress->AddressLength == TDI_ADDRESS_LENGTH_IP)
+ {
+ /* This is an IPv4 address */
+ RtlCopyMemory(Address, &CurrentAddress->Address[0],
CurrentAddress->AddressLength);
+ return STATUS_SUCCESS;
+ }
+ }
+ CurrentAddress =
(PTA_ADDRESS)&CurrentAddress->Address[CurrentAddress->AddressLength];
+ }
+ return STATUS_INVALID_ADDRESS;
+}
+
+static
+VOID
+NTAPI
+CancelReceiveDatagram(
+ _Inout_ struct _DEVICE_OBJECT* DeviceObject,
+ _Inout_ _IRQL_uses_cancel_ struct _IRP *Irp)
+{
+ PIO_STACK_LOCATION IrpSp;
+ ADDRESS_FILE* AddressFile;
+ RECEIVE_DATAGRAM_REQUEST* Request;
+ KIRQL OldIrql;
+ LIST_ENTRY* ListEntry;
+
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ AddressFile = IrpSp->FileObject->FsContext;
+
+ /* Find this IRP in the list of requests */
+ KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
+ ListEntry = AddressFile->RequestListHead.Flink;
+ while (ListEntry != &AddressFile->RequestListHead)
+ {
+ Request = CONTAINING_RECORD(ListEntry, RECEIVE_DATAGRAM_REQUEST, ListEntry);
+ if (Request->Irp == Irp)
+ break;
+ ListEntry = ListEntry->Flink;
+ }
+
+ /* We must have found it */
+ NT_ASSERT(ListEntry != &AddressFile->RequestListHead);
+
+ RemoveEntryList(&Request->ListEntry);
+ KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
+
+ Irp->IoStatus.Status = STATUS_CANCELLED;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
+}
+
+
+NTSTATUS
+TcpIpReceiveDatagram(
+ _Inout_ PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ ADDRESS_FILE *AddressFile;
+ RECEIVE_DATAGRAM_REQUEST* Request = NULL;
+ PTDI_REQUEST_KERNEL_RECEIVEDG RequestInfo;
+ NTSTATUS Status;
+ KIRQL OldIrql;
+
+ /* Check this is really an address file */
+ if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE)
+ {
+ Status = STATUS_FILE_INVALID;
+ goto Failure;
+ }
+
+ /* Get the address file */
+ AddressFile = IrpSp->FileObject->FsContext;
+
+ if (AddressFile->Protocol == IPPROTO_TCP)
+ {
+ /* TCP has no such thing as datagrams */
+ DPRINT1("Received TDI_RECEIVE_DATAGRAM for a TCP adress file.\n");
+ Status = STATUS_INVALID_ADDRESS;
+ goto Failure;
+ }
+
+ /* Queue the request */
+ Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_ADDRESS_FILE);
+ if (!Request)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Failure;
+ }
+ RtlZeroMemory(Request, sizeof(*Request));
+ Request->Irp = Irp;
+
+ /* Get details about what we should be receiving */
+ RequestInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&IrpSp->Parameters;
+
+ /* Get the address */
+ if (RequestInfo->ReceiveDatagramInformation->RemoteAddressLength != 0)
+ {
+ Status = ExtractAddressFromList(
+ RequestInfo->ReceiveDatagramInformation->RemoteAddress,
+ &Request->RemoteAddress);
+ if (!NT_SUCCESS(Status))
+ goto Failure;
+ }
+
+ /* Get the buffer */
+ Request->Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ Request->BufferLength = MmGetMdlByteCount(Irp->MdlAddress);
+
+ Request->ReturnInfo = RequestInfo->ReturnDatagramInformation;
+
+ /* Prepare for potential cancellation */
+ IoAcquireCancelSpinLock(&OldIrql);
+ IoSetCancelRoutine(Irp, CancelReceiveDatagram);
+ IoReleaseCancelSpinLock(OldIrql);
+
+ /* Mark pending */
+ Irp->IoStatus.Status = STATUS_PENDING;
+ IoMarkIrpPending(Irp);
+
+ /* We're ready to go */
+ ExInterlockedInsertTailList(
+ &AddressFile->RequestListHead,
+ &Request->ListEntry,
+ &AddressFile->RequestLock);
+
+ return STATUS_PENDING;
+
+Failure:
+ if (Request)
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ return Status;
+}
+
+
+NTSTATUS
+TcpIpSendDatagram(
+ _Inout_ PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ ADDRESS_FILE *AddressFile;
+ PTDI_REQUEST_KERNEL_SENDDG RequestInfo;
+ NTSTATUS Status;
+ ip_addr_t IpAddr;
+ u16_t Port;
+ PVOID Buffer;
+ ULONG BufferLength;
+ struct pbuf* p = NULL;
+ err_t lwip_error;
+
+ /* Check this is really an address file */
+ if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE)
+ {
+ Status = STATUS_FILE_INVALID;
+ goto Finish;
+ }
+
+ /* Get the address file */
+ AddressFile = IrpSp->FileObject->FsContext;
+
+ if (AddressFile->Protocol == IPPROTO_TCP)
+ {
+ /* TCP has no such thing as datagrams */
+ DPRINT1("Received TDI_SEND_DATAGRAM for a TCP adress file.\n");
+ Status = STATUS_INVALID_ADDRESS;
+ goto Finish;
+ }
+
+ /* Get details about what we should be receiving */
+ RequestInfo = (PTDI_REQUEST_KERNEL_SENDDG)&IrpSp->Parameters;
+
+ /* Get the address */
+ if (RequestInfo->SendDatagramInformation->RemoteAddressLength != 0)
+ {
+ TDI_ADDRESS_IP Address;
+ Status = ExtractAddressFromList(
+ RequestInfo->SendDatagramInformation->RemoteAddress,
+ &Address);
+ if (!NT_SUCCESS(Status))
+ goto Finish;
+ ip4_addr_set_u32(&IpAddr, Address.in_addr);
+ Port = Address.sin_port;
+ }
+ else
+ {
+ ip_addr_set_any(&IpAddr);
+ Port = 0;
+ }
+
+ /* Get the buffer */
+ Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ BufferLength = MmGetMdlByteCount(Irp->MdlAddress);
+ p = pbuf_alloc(PBUF_RAW, BufferLength, PBUF_REF);
+ if (!p)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Finish;
+ }
+ p->payload = Buffer;
+
+ /* Send it for real */
+ switch (AddressFile->Protocol)
+ {
+ case IPPROTO_UDP:
+ lwip_error = udp_sendto(AddressFile->lwip_udp_pcb, p, &IpAddr, Port);
+ break;
+ default:
+ lwip_error = raw_sendto(AddressFile->lwip_raw_pcb, p, &IpAddr);
+ break;
+ }
+
+ switch (lwip_error)
+ {
+ case ERR_OK:
+ Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = BufferLength;
+ break;
+ case ERR_MEM:
+ case ERR_BUF:
+ DPRINT1("Received ERR_MEM from lwip.\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ break;
+ case ERR_RTE:
+ DPRINT1("Received ERR_RTE from lwip.\n");
+ Status = STATUS_INVALID_ADDRESS;
+ break;
+ case ERR_VAL:
+ DPRINT1("Received ERR_VAL from lwip.\n");
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ default:
+ DPRINT1("Received error %d from lwip.\n", lwip_error);
+ Status = STATUS_UNEXPECTED_NETWORK_ERROR;
+ }
+
+Finish:
+ if (p)
+ pbuf_free(p);
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ return Status;
+}
Propchange: branches/tcpip_revolution/drivers/network/tcpip/address.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/address.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/address.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/address.h
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/address.h (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/address.h [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,41 @@
+
+#pragma once
+
+typedef struct
+{
+ LIST_ENTRY ListEntry;
+ LONG RefCount;
+ IPPROTO Protocol;
+ TDI_ADDRESS_IP Address;
+ TCPIP_INSTANCE Instance;
+ KSPIN_LOCK RequestLock;
+ LIST_ENTRY RequestListHead;
+ union
+ {
+ struct raw_pcb* lwip_raw_pcb;
+ struct udp_pcb* lwip_udp_pcb;
+ };
+} ADDRESS_FILE;
+
+void
+TcpIpInitializeAddresses(void);
+
+NTSTATUS
+TcpIpCreateAddress(
+ _Inout_ PIRP Irp,
+ _In_ PTDI_ADDRESS_IP Address,
+ _In_ IPPROTO Protocol
+);
+
+NTSTATUS
+TcpIpCloseAddress(
+ _Inout_ ADDRESS_FILE* AddressFile
+);
+
+NTSTATUS
+TcpIpReceiveDatagram(
+ _Inout_ PIRP Irp);
+
+NTSTATUS
+TcpIpSendDatagram(
+ _Inout_ PIRP Irp);
Propchange: branches/tcpip_revolution/drivers/network/tcpip/address.h
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/address.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/address.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/connection.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/connection.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/connection.c [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,12 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/address.c
+ * PURPOSE: tcpip.sys: addresses abstraction
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
Propchange: branches/tcpip_revolution/drivers/network/tcpip/connection.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/connection.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/connection.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/entities.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/entities.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/entities.c [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,322 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/address.c
+ * PURPOSE: tcpip.sys: entity list implementation
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+#define TAG_ENTITIES 'nIpI'
+
+static const ULONG EntityList[] = {
+ AT_ENTITY,
+ CL_NL_ENTITY,
+ CO_NL_ENTITY,
+ CL_TL_ENTITY,
+ CO_TL_ENTITY,
+ ER_ENTITY,
+ IF_ENTITY
+};
+
+static LIST_ENTRY AtInstancesListHead;
+static LIST_ENTRY ClNlInstancesListHead;
+static LIST_ENTRY CoNlInstancesListHead;
+static LIST_ENTRY ClTlInstancesListHead;
+static LIST_ENTRY CoTlInstancesListHead;
+static LIST_ENTRY ErInstancesListHead;
+static LIST_ENTRY IfInstancesListHead;
+
+/* The corresponding locks */
+static KSPIN_LOCK AtInstanceLock;
+static KSPIN_LOCK ClNlInstanceLock;
+static KSPIN_LOCK CoNlInstanceLock;
+static KSPIN_LOCK ClTlInstanceLock;
+static KSPIN_LOCK CoTlInstanceLock;
+static KSPIN_LOCK ErInstanceLock;
+static KSPIN_LOCK IfInstanceLock;
+
+/* We keep track of those just for the sake of speed,
+ * as our network stack thinks it's clever to get the entity list often */
+static ULONG InstanceCount;
+
+static
+PLIST_ENTRY
+GetInstanceListHeadAcquireLock(
+ _In_ ULONG Entity,
+ _Out_ PKIRQL OldIrql
+)
+{
+ switch (Entity)
+ {
+ case AT_ENTITY:
+ KeAcquireSpinLock(&AtInstanceLock, OldIrql);
+ return &AtInstancesListHead;
+ case CL_NL_ENTITY:
+ KeAcquireSpinLock(&ClNlInstanceLock, OldIrql);
+ return &ClNlInstancesListHead;
+ case CO_NL_ENTITY:
+ KeAcquireSpinLock(&CoNlInstanceLock, OldIrql);
+ return &CoNlInstancesListHead;
+ case CL_TL_ENTITY:
+ KeAcquireSpinLock(&ClTlInstanceLock, OldIrql);
+ return &ClTlInstancesListHead;
+ case CO_TL_ENTITY:
+ KeAcquireSpinLock(&CoTlInstanceLock, OldIrql);
+ return &CoTlInstancesListHead;
+ case ER_ENTITY:
+ KeAcquireSpinLock(&ErInstanceLock, OldIrql);
+ return &ErInstancesListHead;
+ case IF_ENTITY:
+ KeAcquireSpinLock(&IfInstanceLock, OldIrql);
+ return &IfInstancesListHead;
+ default:
+ DPRINT1("Got unknown entity ID %x\n", Entity);
+ return NULL;
+ }
+}
+
+static
+void
+AcquireEntityLock(
+ _In_ ULONG Entity,
+ _Out_ KIRQL* OldIrql)
+{
+ switch (Entity)
+ {
+ case AT_ENTITY:
+ KeAcquireSpinLock(&AtInstanceLock, OldIrql);
+ return;
+ case CL_NL_ENTITY:
+ KeAcquireSpinLock(&ClNlInstanceLock, OldIrql);
+ return;
+ case CO_NL_ENTITY:
+ KeAcquireSpinLock(&CoNlInstanceLock, OldIrql);
+ return;
+ case CL_TL_ENTITY:
+ KeAcquireSpinLock(&ClTlInstanceLock, OldIrql);
+ return;
+ case CO_TL_ENTITY:
+ KeAcquireSpinLock(&CoTlInstanceLock, OldIrql);
+ return;
+ case ER_ENTITY:
+ KeAcquireSpinLock(&ErInstanceLock, OldIrql);
+ return;
+ case IF_ENTITY:
+ KeAcquireSpinLock(&IfInstanceLock, OldIrql);
+ return;
+ default:
+ DPRINT1("Got unknown entity ID %x\n", Entity);
+ ASSERT(FALSE);
+ }
+}
+
+static
+void
+ReleaseEntityLock(
+ _In_ ULONG Entity,
+ _In_ KIRQL OldIrql)
+{
+ switch (Entity)
+ {
+ case AT_ENTITY:
+ KeReleaseSpinLock(&AtInstanceLock, OldIrql);
+ return;
+ case CL_NL_ENTITY:
+ KeReleaseSpinLock(&ClNlInstanceLock, OldIrql);
+ return;
+ case CO_NL_ENTITY:
+ KeReleaseSpinLock(&CoNlInstanceLock, OldIrql);
+ return;
+ case CL_TL_ENTITY:
+ KeReleaseSpinLock(&ClTlInstanceLock, OldIrql);
+ return;
+ case CO_TL_ENTITY:
+ KeReleaseSpinLock(&CoTlInstanceLock, OldIrql);
+ return;
+ case ER_ENTITY:
+ KeReleaseSpinLock(&ErInstanceLock, OldIrql);
+ return;
+ case IF_ENTITY:
+ KeReleaseSpinLock(&IfInstanceLock, OldIrql);
+ return;
+ default:
+ DPRINT1("Got unknown entity ID %x\n", Entity);
+ ASSERT(FALSE);
+ }
+}
+
+VOID
+TcpIpInitializeEntities(void)
+{
+ /* Initialize the locks */
+ KeInitializeSpinLock(&AtInstanceLock);
+ KeInitializeSpinLock(&ClNlInstanceLock);
+ KeInitializeSpinLock(&CoNlInstanceLock);
+ KeInitializeSpinLock(&ClTlInstanceLock);
+ KeInitializeSpinLock(&CoTlInstanceLock);
+ KeInitializeSpinLock(&ErInstanceLock);
+ KeInitializeSpinLock(&IfInstanceLock);
+
+ /* And the list heads */
+ InitializeListHead(&AtInstancesListHead);
+ InitializeListHead(&ClNlInstancesListHead);
+ InitializeListHead(&CoNlInstancesListHead);
+ InitializeListHead(&ClTlInstancesListHead);
+ InitializeListHead(&CoTlInstancesListHead);
+ InitializeListHead(&ErInstancesListHead);
+ InitializeListHead(&IfInstancesListHead);
+
+ /* We don't have anything for now */
+ InstanceCount = 0;
+}
+
+NTSTATUS
+QueryEntityList(
+ _In_ TDIEntityID ID,
+ _In_ PVOID Context,
+ _Out_opt_ PVOID OutBuffer,
+ _Inout_ ULONG* BufferSize)
+{
+ KIRQL OldIrql;
+ TDIEntityID* Entity = OutBuffer;
+ ULONG RemainingSize = *BufferSize, TotalSize = 0;
+ TCPIP_INSTANCE* Instance;
+ LIST_ENTRY* ListHead;
+ LIST_ENTRY* ListEntry;
+ ULONG i;
+
+ UNREFERENCED_PARAMETER(ID);
+ UNREFERENCED_PARAMETER(Context);
+
+ DPRINT("Gathering the entity list.\n");
+
+ if (!OutBuffer)
+ {
+ *BufferSize = InstanceCount * sizeof(TDIEntityID);
+ return STATUS_SUCCESS;
+ }
+
+ /* Go through the bitmaps */
+ for (i = 0; i < sizeof(EntityList)/sizeof(EntityList[0]); i++)
+ {
+ ListHead = GetInstanceListHeadAcquireLock(EntityList[i], &OldIrql);
+
+ ListEntry = ListHead->Flink;
+ while(ListEntry != ListHead)
+ {
+ if (RemainingSize < sizeof(TDIEntityID))
+ {
+ *BufferSize = InstanceCount * sizeof(TDIEntityID);
+ ReleaseEntityLock(EntityList[i], OldIrql);
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ Instance = CONTAINING_RECORD(ListEntry, TCPIP_INSTANCE, ListEntry);
+
+ *Entity++ = Instance->InstanceId;
+ RemainingSize -= sizeof(*Entity);
+ TotalSize += sizeof(*Entity);
+
+ ListEntry = ListEntry->Flink;
+ }
+
+ ReleaseEntityLock(EntityList[i], OldIrql);
+ }
+
+ *BufferSize = TotalSize;
+ return STATUS_SUCCESS;
+}
+
+VOID
+InsertEntityInstance(
+ _In_ ULONG Entity,
+ _Out_ TCPIP_INSTANCE* OutInstance)
+{
+ KIRQL OldIrql;
+ LIST_ENTRY* ListHead;
+ LIST_ENTRY* ListEntry;
+ TCPIP_INSTANCE* Instance;
+ ULONG InstanceId = 1;
+
+ ListHead = GetInstanceListHeadAcquireLock(Entity, &OldIrql);
+ NT_ASSERT(ListHead);
+
+ ListEntry = ListHead->Flink;
+
+ /* Find an instance number for this guy */
+ while (ListEntry != ListHead)
+ {
+ Instance = CONTAINING_RECORD(ListEntry, TCPIP_INSTANCE, ListEntry);
+
+ if (Instance->InstanceId.tei_instance != InstanceId)
+ break;
+ InstanceId++;
+ ListEntry = ListEntry->Flink;
+ }
+
+ OutInstance->InstanceId.tei_entity = Entity;
+ OutInstance->InstanceId.tei_instance = InstanceId;
+
+ /* Keep this list sorted */
+ InsertHeadList(ListEntry, &OutInstance->ListEntry);
+
+ ReleaseEntityLock(Entity, OldIrql);
+
+ InterlockedIncrement((LONG*)&InstanceCount);
+}
+
+void
+RemoveEntityInstance(
+ _In_ TCPIP_INSTANCE* Instance)
+{
+ KIRQL OldIrql;
+
+ AcquireEntityLock(Instance->InstanceId.tei_entity, &OldIrql);
+
+ RemoveEntryList(&Instance->ListEntry);
+
+ ReleaseEntityLock(Instance->InstanceId.tei_entity, OldIrql);
+
+ InterlockedDecrement((LONG*)&InstanceCount);
+}
+
+NTSTATUS
+GetInstance(
+ _In_ TDIEntityID ID,
+ _Out_ TCPIP_INSTANCE** OutInstance)
+{
+ KIRQL OldIrql;
+ LIST_ENTRY *ListHead, *ListEntry;
+ TCPIP_INSTANCE* Instance;
+
+ ListHead = GetInstanceListHeadAcquireLock(ID.tei_entity, &OldIrql);
+ NT_ASSERT(ListHead != NULL);
+
+ ListEntry = ListHead->Flink;
+ while (ListEntry != ListHead)
+ {
+ Instance = CONTAINING_RECORD(ListEntry, TCPIP_INSTANCE, ListEntry);
+
+ NT_ASSERT(Instance->InstanceId.tei_entity == ID.tei_entity);
+ if (Instance->InstanceId.tei_instance == ID.tei_instance)
+ {
+ *OutInstance = Instance;
+ ReleaseEntityLock(ID.tei_entity, OldIrql);
+ return STATUS_SUCCESS;
+ }
+
+ /* The list is sorted, so we can cut the loop a bit */
+ if (ID.tei_instance < Instance->InstanceId.tei_instance)
+ break;
+
+ ListEntry = ListEntry->Flink;
+ }
+
+ ReleaseEntityLock(ID.tei_entity, OldIrql);
+ /* Maybe we could find a more descriptive status */
+ return STATUS_INVALID_PARAMETER;
+}
Propchange: branches/tcpip_revolution/drivers/network/tcpip/entities.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/entities.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/entities.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/entities.h
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/entities.h (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/entities.h [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,33 @@
+
+#pragma once
+
+typedef struct
+{
+ TDIEntityID InstanceId;
+ LIST_ENTRY ListEntry;
+} TCPIP_INSTANCE;
+
+VOID
+TcpIpInitializeEntities(void);
+
+VOID
+InsertEntityInstance(
+ _In_ ULONG Entity,
+ _Out_ TCPIP_INSTANCE* OutInstance);
+
+void
+RemoveEntityInstance(
+ _In_ TCPIP_INSTANCE* Instance);
+
+NTSTATUS
+GetInstance(
+ _In_ TDIEntityID,
+ _Out_ TCPIP_INSTANCE** Instance);
+
+/* IOCTL_TCP_QUERY_INFORMATION_EX handler */
+NTSTATUS
+QueryEntityList(
+ _In_ TDIEntityID ID,
+ _In_ PVOID Context,
+ _Out_opt_ PVOID OutBuffer,
+ _Inout_ ULONG* BufferSize);
Propchange: branches/tcpip_revolution/drivers/network/tcpip/entities.h
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/entities.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/entities.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/information.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/information.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/information.c [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,179 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/address.c
+ * PURPOSE: tcpip.sys: TCP_QUERY_INFORMATION_EX and TCP_SET_INFORMATION_EX ioctls
implementation
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+typedef NTSTATUS (*QUERY_INFO_HANDLER)(
+ _In_ TDIEntityID ID,
+ _In_ PVOID Context,
+ _Out_opt_ PVOID OutBuffer,
+ _Inout_ ULONG* BufferSize);
+
+static
+struct
+{
+ ULONG Entity, Class, Type, Id;
+ QUERY_INFO_HANDLER Handler;
+
+} InfoHandlers[] =
+{
+ { GENERIC_ENTITY, INFO_CLASS_GENERIC, INFO_TYPE_PROVIDER, ENTITY_LIST_ID,
QueryEntityList },
+ { IF_ENTITY, INFO_CLASS_PROTOCOL, INFO_TYPE_PROVIDER, IP_MIB_STATS_ID,
QueryInterfaceEntry},
+ { CL_NL_ENTITY, INFO_CLASS_PROTOCOL, INFO_TYPE_PROVIDER,
IP_MIB_ADDRTABLE_ENTRY_ID, QueryInterfaceAddrTable},
+ { (ULONG)-1, (ULONG)-1, (ULONG)-1, (ULONG)-1, NULL }
+};
+
+
+NTSTATUS
+TcpIpQueryInformation(
+ _Inout_ PIRP Irp
+)
+{
+ PIO_STACK_LOCATION IrpSp;
+ TCP_REQUEST_QUERY_INFORMATION_EX* Query;
+ QUERY_INFO_HANDLER Handler = NULL;
+ PMDL QueryMdl = NULL, OutputMdl = NULL;
+ BOOL QueryLocked = FALSE, OutputLocked = FALSE;
+ ULONG OutputBufferLength;
+ PVOID OutputBuffer = NULL;
+ NTSTATUS Status;
+ ULONG i;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ /* Check input buffer size */
+ if (IrpSp->Parameters.DeviceIoControl.InputBufferLength <
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX))
+ return STATUS_INVALID_PARAMETER;
+
+ /* Get the input buffer */
+ Query = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ QueryMdl = IoAllocateMdl(Query, sizeof(*Query), FALSE, TRUE, NULL);
+ if (!QueryMdl)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ _SEH2_TRY
+ {
+ MmProbeAndLockPages(QueryMdl, Irp->RequestorMode, IoReadAccess);
+ QueryLocked = TRUE;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
+ } _SEH2_END
+
+ /* Get the outputbuffer, if any */
+ OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+ if (OutputBufferLength)
+ {
+ OutputBuffer = Irp->UserBuffer;
+ OutputMdl = IoAllocateMdl(OutputBuffer, OutputBufferLength, FALSE, TRUE, NULL);
+ if (!OutputMdl)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Cleanup;
+ }
+
+ _SEH2_TRY
+ {
+ MmProbeAndLockPages(OutputMdl, Irp->RequestorMode, IoWriteAccess);
+ OutputLocked = TRUE;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ goto Cleanup;
+ }
+ _SEH2_END
+ }
+
+ /* Find the handler for this particular query */
+ for (i = 0; InfoHandlers[i].Handler != NULL; i++)
+ {
+ if ((InfoHandlers[i].Entity == Query->ID.toi_entity.tei_entity) &&
+ (InfoHandlers[i].Class == Query->ID.toi_class) &&
+ (InfoHandlers[i].Type == Query->ID.toi_type) &&
+ (InfoHandlers[i].Id == Query->ID.toi_id))
+ {
+ Handler = InfoHandlers[i].Handler;
+ break;
+ }
+ }
+
+ if (!Handler)
+ {
+ DPRINT1("TCPIP - Unknown query: entity 0x%x, class 0x%x, type 0x%x, Id
0x%x.\n",
+ Query->ID.toi_entity.tei_entity, Query->ID.toi_class,
Query->ID.toi_type, Query->ID.toi_id);
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Cleanup;
+ }
+
+ Status = Handler(Query->ID.toi_entity, Query->Context, OutputBuffer,
&OutputBufferLength);
+
+ Irp->IoStatus.Information = OutputBufferLength;
+
+Cleanup:
+ if (QueryMdl)
+ {
+ if (QueryLocked)
+ MmUnlockPages(QueryMdl);
+ IoFreeMdl(QueryMdl);
+ }
+ if (OutputMdl)
+ {
+ if (OutputLocked)
+ MmUnlockPages(OutputMdl);
+ IoFreeMdl(OutputMdl);
+ }
+ return Status;
+}
+
+NTSTATUS
+TcpIpQueryKernelInformation(
+ _Inout_ PIRP Irp
+)
+{
+ PIO_STACK_LOCATION IrpSp;
+ PTDI_REQUEST_KERNEL_QUERY_INFORMATION Query;
+ NTSTATUS Status;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ Query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
+
+ /* See what we are queried */
+ switch (Query->QueryType)
+ {
+ case TDI_QUERY_MAX_DATAGRAM_INFO:
+ {
+ PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo;
+
+ if (MmGetMdlByteCount(Irp->MdlAddress) < sizeof(*MaxDatagramInfo))
+ {
+ DPRINT1("MDL buffer too small.\n");
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ MaxDatagramInfo = MmGetSystemAddressForMdl(Irp->MdlAddress);
+
+ MaxDatagramInfo->MaxDatagramSize = 0xFFFF;
+
+ Status = STATUS_SUCCESS;
+ break;
+ }
+ default:
+ DPRINT1("Unknown query: 0x%08x.\n", Query->QueryType);
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ return Status;
+}
Propchange: branches/tcpip_revolution/drivers/network/tcpip/information.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/information.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/information.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/information.h
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/information.h (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/information.h [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,12 @@
+
+#pragma once
+
+NTSTATUS
+TcpIpQueryInformation(
+ _In_ PIRP Irp
+);
+
+NTSTATUS
+TcpIpQueryKernelInformation(
+ _In_ PIRP Irp
+);
Propchange: branches/tcpip_revolution/drivers/network/tcpip/information.h
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/information.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/information.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/interface.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/interface.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/interface.c [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,230 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/interface.c
+ * PURPOSE: tcpip.sys: ndis <-> lwip bridge implementation
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+TCPIP_INTERFACE* LoopbackInterface;
+
+static
+VOID
+GetInterfaceOperStatus(
+ _In_ TCPIP_INTERFACE* Interface,
+ _Out_ ULONG* OperStatus)
+{
+ NDIS_STATUS Status;
+ NDIS_REQUEST Request;
+ NDIS_MEDIA_STATE MediaState;
+
+ if (Interface->NdisContext == NULL)
+ {
+ /* This is the looback interface */
+ *OperStatus = MIB_IF_OPER_STATUS_CONNECTED;
+ return;
+ }
+
+ /* Get the connection status from NDIS */
+ Request.RequestType = NdisRequestQueryInformation;
+ Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MEDIA_CONNECT_STATUS;
+ Request.DATA.QUERY_INFORMATION.InformationBuffer = &MediaState;
+ Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(ULONG);
+ NdisRequest(&Status, Interface->NdisContext, &Request);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not get connection status from the NIC driver. Status
0x%08x\n", Status);
+ *OperStatus = MIB_IF_OPER_STATUS_NON_OPERATIONAL;
+ return;
+ }
+
+ switch(MediaState)
+ {
+ case NdisMediaStateConnected:
+ *OperStatus = MIB_IF_OPER_STATUS_CONNECTED;
+ break;
+ case NdisMediaStateDisconnected:
+ *OperStatus = MIB_IF_OPER_STATUS_DISCONNECTED;
+ break;
+ default:
+ DPRINT1("Got unknown media state from NIC driver: %d.\n",
MediaState);
+ *OperStatus = MIB_IF_OPER_STATUS_NON_OPERATIONAL;
+ }
+}
+
+NTSTATUS
+QueryInterfaceEntry(
+ _In_ TDIEntityID ID,
+ _In_ PVOID Context,
+ _Out_opt_ PVOID OutBuffer,
+ _Inout_ ULONG* BufferSize)
+{
+ TCPIP_INSTANCE* Instance;
+ TCPIP_INTERFACE* Interface;
+ NTSTATUS Status;
+ IFEntry* IfEntry = OutBuffer;
+ ULONG NeededSize;
+
+ NT_ASSERT(ID.tei_entity == IF_ENTITY);
+
+ Status = GetInstance(ID, &Instance);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Interface = CONTAINING_RECORD(Instance, TCPIP_INTERFACE, IfInstance);
+
+ NeededSize = FIELD_OFFSET(IFEntry, if_descr) +
+ RTL_FIELD_SIZE(IFEntry, if_descr[0]) * (Interface->DeviceName.Length / 2 +
1);
+
+ if (!OutBuffer)
+ {
+ *BufferSize = NeededSize;
+ return STATUS_SUCCESS;
+ }
+
+ if (*BufferSize < NeededSize)
+ {
+ *BufferSize = NeededSize;
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ /* Fill in the data from our interface */
+ IfEntry->if_index = Interface->lwip_netif.num;
+ IfEntry->if_type = (Interface->lwip_netif.flags & NETIF_FLAG_ETHARP) ?
+ IF_TYPE_ETHERNET_CSMACD : IF_TYPE_SOFTWARE_LOOPBACK;
+ IfEntry->if_mtu = Interface->lwip_netif.mtu;
+ IfEntry->if_speed = Interface->Speed;
+ IfEntry->if_physaddrlen = Interface->lwip_netif.hwaddr_len;
+ RtlCopyMemory(IfEntry->if_physaddr, Interface->lwip_netif.hwaddr,
IfEntry->if_physaddrlen);
+ IfEntry->if_adminstatus = MIB_IF_ADMIN_STATUS_UP;
+ GetInterfaceOperStatus(Interface, &IfEntry->if_operstatus);
+
+ // FIXME: Fill those
+ IfEntry->if_lastchange = 0;
+ IfEntry->if_inoctets = 0;
+ IfEntry->if_inucastpkts = 0;
+ IfEntry->if_innucastpkts = 0;
+ IfEntry->if_inerrors = 0;
+ IfEntry->if_inunknownprotos = 0;
+ IfEntry->if_outoctets = 0;
+ IfEntry->if_outucastpkts = 0;
+ IfEntry->if_outnucastpkts = 0;
+ IfEntry->if_outdiscards = 0;
+ IfEntry->if_outerrors = 0;
+ IfEntry->if_outqlen = 0;
+
+ /* Set name */
+ RtlUnicodeToMultiByteN(
+ (PCHAR)&IfEntry->if_descr[0],
+ *BufferSize - FIELD_OFFSET(IFEntry, if_descr),
+ &IfEntry->if_descrlen,
+ Interface->DeviceName.Buffer,
+ Interface->DeviceName.Length);
+
+ *BufferSize = NeededSize;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+QueryInterfaceAddrTable(
+ _In_ TDIEntityID ID,
+ _In_ PVOID Context,
+ _Out_opt_ PVOID OutBuffer,
+ _Inout_ ULONG* BufferSize)
+{
+ TCPIP_INSTANCE* Instance;
+ TCPIP_INTERFACE* Interface;
+ NTSTATUS Status;
+ IPAddrEntry* AddrEntry = OutBuffer;
+
+ NT_ASSERT(ID.tei_entity == CL_NL_ENTITY);
+
+ Status = GetInstance(ID, &Instance);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ Interface = CONTAINING_RECORD(Instance, TCPIP_INTERFACE, ClNlInstance);
+
+ // FIXME: return more than 'one' address
+ if (!OutBuffer)
+ {
+ *BufferSize = sizeof(IPAddrEntry);
+ return STATUS_SUCCESS;
+ }
+
+ if (*BufferSize < sizeof(IPAddrEntry))
+ {
+ *BufferSize = sizeof(IPAddrEntry);
+ return STATUS_BUFFER_OVERFLOW;
+ }
+
+ AddrEntry->iae_addr = Interface->lwip_netif.ip_addr.addr;
+ AddrEntry->iae_index = Interface->lwip_netif.num;
+ AddrEntry->iae_mask = Interface->lwip_netif.netmask.addr;
+ _BitScanReverse(&AddrEntry->iae_bcastaddr, AddrEntry->iae_addr |
~AddrEntry->iae_mask);
+ /* FIXME: set those */
+ AddrEntry->iae_reasmsize = 0;
+ AddrEntry->iae_context = 0;
+ AddrEntry->iae_pad = 0;
+
+ return STATUS_SUCCESS;
+}
+
+/* callback provided to lwip for initializing the loopback interface */
+static
+err_t
+lwip_netif_loopback_init(struct netif *netif)
+{
+ NETIF_INIT_SNMP(netif, snmp_ifType_softwareLoopback, 0);
+
+ netif->name[0] = 'l';
+ netif->name[1] = 'o';
+ netif->output = netif_loop_output;
+ return ERR_OK;
+}
+
+NTSTATUS
+TcpIpCreateLoopbackInterface(void)
+{
+ err_t lwip_error;
+ struct ip_addr IpAddr, SubnetMask, GatewayAddr;
+
+ LoopbackInterface = ExAllocatePoolWithTag(NonPagedPool, sizeof(*LoopbackInterface),
TAG_INTERFACE);
+ if (!LoopbackInterface)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlZeroMemory(LoopbackInterface, sizeof(*LoopbackInterface));
+
+ /* Add it to lwip stack */
+ IP4_ADDR(&GatewayAddr, 127,0,0,1);
+ IP4_ADDR(&IpAddr, 127,0,0,1);
+ IP4_ADDR(&SubnetMask, 255,0,0,0);
+ lwip_error = netifapi_netif_add(
+ &LoopbackInterface->lwip_netif,
+ &IpAddr,
+ &SubnetMask,
+ &GatewayAddr,
+ LoopbackInterface,
+ lwip_netif_loopback_init,
+ tcpip_input);
+ if (lwip_error != ERR_OK)
+ {
+ ExFreePoolWithTag(LoopbackInterface, TAG_INTERFACE);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ netifapi_netif_set_up(&LoopbackInterface->lwip_netif);
+
+ /* Add this interface into the entities DB */
+ InsertEntityInstance(CL_NL_ENTITY, &LoopbackInterface->ClNlInstance);
+ InsertEntityInstance(IF_ENTITY, &LoopbackInterface->IfInstance);
+ InsertEntityInstance(AT_ENTITY, &LoopbackInterface->AtInstance);
+
+ RtlInitUnicodeString(&LoopbackInterface->DeviceName, L"Loopback");
+
+ return STATUS_SUCCESS;
+}
Propchange: branches/tcpip_revolution/drivers/network/tcpip/interface.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/interface.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/interface.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/interface.h
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/interface.h (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/interface.h [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,35 @@
+
+#pragma once
+
+#define TAG_INTERFACE 'fIpI'
+
+typedef struct
+{
+ struct netif lwip_netif;
+ TCPIP_INSTANCE IfInstance;
+ TCPIP_INSTANCE AtInstance;
+ TCPIP_INSTANCE ClNlInstance;
+ UNICODE_STRING DeviceName;
+ NDIS_HANDLE NdisContext;
+ UINT MediumIndex;
+ ULONG Speed;
+} TCPIP_INTERFACE;
+
+extern TCPIP_INTERFACE* LoopbackInterface;
+
+NTSTATUS
+TcpIpCreateLoopbackInterface(void);
+
+NTSTATUS
+QueryInterfaceEntry(
+ _In_ TDIEntityID ID,
+ _In_ PVOID Context,
+ _Out_opt_ PVOID OutBuffer,
+ _Inout_ ULONG* BufferSize);
+
+NTSTATUS
+QueryInterfaceAddrTable(
+ _In_ TDIEntityID ID,
+ _In_ PVOID Context,
+ _Out_opt_ PVOID OutBuffer,
+ _Inout_ ULONG* BufferSize);
Propchange: branches/tcpip_revolution/drivers/network/tcpip/interface.h
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/interface.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/interface.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/main.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/main.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/main.c [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,505 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/main.c
+ * PURPOSE: tcpip.sys driver entry
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* DriverEntry, DriverUnload and dispatch routines declaration */
+DRIVER_INITIALIZE DriverEntry;
+static DRIVER_UNLOAD TcpIpUnload;
+static DRIVER_DISPATCH TcpIpCreate;
+static DRIVER_DISPATCH TcpIpClose;
+static DRIVER_DISPATCH TcpIpDispatchInternal;
+static DRIVER_DISPATCH TcpIpDispatch;
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(PAGE, TcpIpUnload)
+#pragma alloc_text(PAGE, TcpIpCreate)
+#pragma alloc_text(PAGE, TcpIpClose)
+#pragma alloc_text(PAGE, TcpIpDispatchInternal)
+#pragma alloc_text(PAGE, TcpIpDispatch)
+#endif
+
+/* Our device objects. TCP, UPD, IP, and RAW */
+PDEVICE_OBJECT TcpDeviceObject = NULL;
+PDEVICE_OBJECT UdpDeviceObject = NULL;
+PDEVICE_OBJECT IpDeviceObject = NULL;
+PDEVICE_OBJECT RawIpDeviceObject = NULL;
+
+/* And the corresponding device names */
+#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"
+
+/* This is a small utility which get the IPPROTO_* constant from the device object this
driver was passed */
+static
+IPPROTO
+ProtocolFromIrp(
+ _In_ PDEVICE_OBJECT DeviceObject,
+ _In_ PIO_STACK_LOCATION IrpSp)
+{
+ UNICODE_STRING ProtocolName;
+ PWCHAR Name;
+ ULONG Value;
+ NTSTATUS Status;
+
+ if (DeviceObject == TcpDeviceObject)
+ return IPPROTO_TCP;
+ if (DeviceObject == UdpDeviceObject)
+ return IPPROTO_UDP;
+ if (DeviceObject == IpDeviceObject)
+ return IPPROTO_RAW;
+
+ /* Get it from the IRP file object */
+ Name = IrpSp->FileObject->FileName.Buffer;
+
+ if (*Name++ != L'\\')
+ {
+ DPRINT1("Could not deduce protocol from file name %wZ.\n",
&IrpSp->FileObject->FileName);
+ return (IPPROTO)-1;
+ }
+
+ RtlInitUnicodeString(&ProtocolName, Name);
+ Status = RtlUnicodeStringToInteger(&ProtocolName, 10, &Value);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not deduce protocol from file name %wZ.\n",
&IrpSp->FileObject->FileName);
+ return (IPPROTO)-1;
+ }
+
+ if (Value >= IPPROTO_RESERVED_MAX)
+ {
+ DPRINT1("Could not deduce protocol from file name %wZ.\n",
&IrpSp->FileObject->FileName);
+ return (IPPROTO)-1;
+ }
+
+ return (IPPROTO)Value;
+}
+
+NTSTATUS
+NTAPI
+DriverEntry(
+ _In_ struct _DRIVER_OBJECT *DriverObject,
+ _In_ PUNICODE_STRING RegistryPath
+)
+{
+ UNICODE_STRING IpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
+ UNICODE_STRING RawIpDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
+ UNICODE_STRING UdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
+ UNICODE_STRING TcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
+ NTSTATUS Status;
+
+ /* Initialize the lwip library */
+ tcpip_init(NULL, NULL);
+
+ /* Create the device objects */
+ Status = IoCreateDevice(
+ DriverObject,
+ 0,
+ &IpDeviceName,
+ FILE_DEVICE_NETWORK,
+ 0,
+ FALSE,
+ &IpDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not create device object. Status: 0x%08x\n", Status);
+ goto Failure;
+ }
+
+ Status = IoCreateDevice(
+ DriverObject,
+ 0,
+ &UdpDeviceName,
+ FILE_DEVICE_NETWORK,
+ 0,
+ FALSE,
+ &UdpDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not create device object. Status: 0x%08x\n", Status);
+ goto Failure;
+ }
+
+ Status = IoCreateDevice(
+ DriverObject,
+ 0,
+ &TcpDeviceName,
+ FILE_DEVICE_NETWORK,
+ 0,
+ FALSE,
+ &TcpDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not create device object. Status: 0x%08x\n", Status);
+ goto Failure;
+ }
+
+ Status = IoCreateDevice(
+ DriverObject,
+ 0,
+ &RawIpDeviceName,
+ FILE_DEVICE_NETWORK,
+ 0,
+ FALSE,
+ &RawIpDeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not create device object. Status: 0x%08x\n", Status);
+ goto Failure;
+ }
+
+ /* Use direct I/O with this devices */
+ IpDeviceObject->Flags |= DO_DIRECT_IO;
+ RawIpDeviceObject->Flags |= DO_DIRECT_IO;
+ UdpDeviceObject->Flags |= DO_DIRECT_IO;
+ TcpDeviceObject->Flags |= DO_DIRECT_IO;
+
+ /* Set driver object entry points */
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = TcpIpCreate;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = TcpIpClose;
+ DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
TcpIpDispatchInternal;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TcpIpDispatch;
+ DriverObject->DriverUnload = TcpIpUnload;
+
+ /* Initialize various parts of the driver */
+ TcpIpInitializeAddresses();
+ TcpIpInitializeTcp();
+ TcpIpInitializeEntities();
+ Status = TcpIpRegisterNdisProtocol();
+ if (!NT_SUCCESS(Status))
+ goto Failure;
+
+ /* Create the loopback interface */
+ Status = TcpIpCreateLoopbackInterface();
+ if (!NT_SUCCESS(Status))
+ goto Failure;
+
+ return STATUS_SUCCESS;
+
+Failure:
+ TcpIpUnregisterNdisProtocol();
+
+ if (IpDeviceObject)
+ IoDeleteDevice(IpDeviceObject);
+ if (TcpDeviceObject)
+ IoDeleteDevice(TcpDeviceObject);
+ if (UdpDeviceObject)
+ IoDeleteDevice(UdpDeviceObject);
+ if (RawIpDeviceObject)
+ IoDeleteDevice(RawIpDeviceObject);
+
+ return Status;
+}
+
+static
+NTSTATUS
+NTAPI
+TcpIpCreate(
+ _Inout_ struct _DEVICE_OBJECT *DeviceObject,
+ _Inout_ struct _IRP *Irp
+)
+{
+ NTSTATUS Status;
+ PFILE_FULL_EA_INFORMATION FileInfo;
+ IPPROTO Protocol;
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ /* Grab the info describing the file */
+ FileInfo = Irp->AssociatedIrp.SystemBuffer;
+
+ if (!FileInfo)
+ {
+ /* Caller just wants a control channel. We don't need any structure for this
kind of "file" */
+ IrpSp->FileObject->FsContext = NULL;
+ IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONTROL_CHANNEL_FILE;
+ Status = STATUS_SUCCESS;
+ goto Quickie;
+ }
+
+ /* Validate it */
+ switch (FileInfo->EaNameLength)
+ {
+ case TDI_TRANSPORT_ADDRESS_LENGTH:
+ {
+ PTA_IP_ADDRESS Address;
+
+ if (strncmp(&FileInfo->EaName[0], TdiTransportAddress,
TDI_TRANSPORT_ADDRESS_LENGTH) != 0)
+ {
+ DPRINT1("TCPIP: Should maybe open file %*s.\n",
FileInfo->EaNameLength, &FileInfo->EaName[0]);
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+ /* Get the address info right after the file name info */
+ Address = (PTA_IP_ADDRESS)(&FileInfo->EaName[FileInfo->EaNameLength
+ 1]);
+
+ /* Validate it */
+ if ((FileInfo->EaValueLength < sizeof(*Address)) ||
+ (Address->TAAddressCount != 1) ||
+ (Address->Address[0].AddressLength < TDI_ADDRESS_LENGTH_IP) ||
+ (Address->Address[0].AddressType != TDI_ADDRESS_TYPE_IP))
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+
+ /* Get the protocol this address will be created for. */
+ Protocol = ProtocolFromIrp(DeviceObject, IrpSp);
+ if (Protocol == (IPPROTO)-1)
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+
+ /* All good. */
+ Status = TcpIpCreateAddress(Irp, &Address->Address[0].Address[0],
Protocol);
+ break;
+ }
+
+ case TDI_CONNECTION_CONTEXT_LENGTH:
+ if (strncmp(&FileInfo->EaName[0], TdiConnectionContext,
TDI_CONNECTION_CONTEXT_LENGTH) != 0)
+ {
+ DPRINT1("TCPIP: Should maybe open file %*s.\n",
FileInfo->EaNameLength, &FileInfo->EaName[0]);
+ return STATUS_INVALID_PARAMETER;
+ }
+ DPRINT1("Should create a connection!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ default:
+ DPRINT1("TCPIP: Should open file %*s.\n",
FileInfo->EaNameLength, &FileInfo->EaName[0]);
+ Status = STATUS_INVALID_PARAMETER;
+ }
+
+Quickie:
+ Irp->IoStatus.Status = Status;
+ if (Status == STATUS_PENDING)
+ {
+ IoMarkIrpPending(Irp);
+ }
+ else
+ {
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ }
+
+ return Status;
+}
+
+static
+NTSTATUS
+NTAPI
+TcpIpClose(
+ _Inout_ struct _DEVICE_OBJECT *DeviceObject,
+ _Inout_ struct _IRP *Irp
+)
+{
+ PIO_STACK_LOCATION IrpSp;
+ NTSTATUS Status;
+ ULONG_PTR FileType;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ FileType = (ULONG_PTR)IrpSp->FileObject->FsContext2;
+
+ switch (FileType)
+ {
+ case TDI_TRANSPORT_ADDRESS_FILE:
+ if (!IrpSp->FileObject->FsContext)
+ {
+ DPRINT1("TCPIP: Got a close request without a file to
close!\n");
+ Status = STATUS_INVALID_PARAMETER;
+ goto Quickie;
+ }
+ Status = TcpIpCloseAddress(IrpSp->FileObject->FsContext);
+ break;
+ case TDI_CONTROL_CHANNEL_FILE:
+ /* We didn't allocate anything for this. */
+ Status = STATUS_SUCCESS;
+ break;
+ default:
+ DPRINT1("TCPIP: Should close file %Iu.\n", FileType);
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+Quickie:
+ Irp->IoStatus.Status = Status;
+
+ return Irp->IoStatus.Status;
+}
+
+static
+NTSTATUS
+NTAPI
+TcpIpDispatchInternal(
+ _Inout_ struct _DEVICE_OBJECT *DeviceObject,
+ _Inout_ struct _IRP *Irp
+)
+{
+ NTSTATUS Status;
+ PIO_STACK_LOCATION IrpSp;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ switch (IrpSp->MinorFunction)
+ {
+ case TDI_RECEIVE:
+ DPRINT1("TCPIP: TDI_RECEIVE!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_RECEIVE_DATAGRAM:
+ return TcpIpReceiveDatagram(Irp);
+
+ case TDI_SEND:
+ DPRINT1("TCPIP: TDI_SEND!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_SEND_DATAGRAM:
+ return TcpIpSendDatagram(Irp);
+
+ case TDI_ACCEPT:
+ DPRINT1("TCPIP: TDI_ACCEPT!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_LISTEN:
+ DPRINT1("TCPIP: TDI_LISTEN!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_CONNECT:
+ DPRINT1("TCPIP: TDI_CONNECT!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_DISCONNECT:
+ DPRINT1("TCPIP: TDI_DISCONNECT!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_ASSOCIATE_ADDRESS:
+ DPRINT1("TCPIP: TDI_ASSOCIATE_ADDRESS!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_DISASSOCIATE_ADDRESS:
+ DPRINT1("TCPIP: TDI_DISASSOCIATE_ADDRESS!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_QUERY_INFORMATION:
+ return TcpIpQueryKernelInformation(Irp);
+
+ case TDI_SET_INFORMATION:
+ DPRINT1("TCPIP: TDI_SET_INFORMATION!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_SET_EVENT_HANDLER:
+ DPRINT1("TCPIP: TDI_SET_EVENT_HANDLER!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case TDI_ACTION:
+ DPRINT1("TDI_ACTION!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ /* An unsupported IOCTL code was submitted */
+ default:
+ DPRINT1("TCPIP: Unknown internal IOCTL: 0x%x.\n",
IrpSp->MinorFunction);
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+
+ Irp->IoStatus.Status = Status;
+ if (Status == STATUS_PENDING)
+ {
+ IoMarkIrpPending(Irp);
+ }
+ else
+ {
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ }
+
+ return Status;
+}
+
+static
+NTSTATUS
+NTAPI
+TcpIpDispatch(
+ _Inout_ struct _DEVICE_OBJECT *DeviceObject,
+ _Inout_ struct _IRP *Irp
+)
+{
+ NTSTATUS Status;
+ PIO_STACK_LOCATION IrpSp;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ Irp->IoStatus.Information = 0;
+
+ switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
+ {
+ case IOCTL_TCP_QUERY_INFORMATION_EX:
+ Status = TcpIpQueryInformation(Irp);
+ break;
+
+ case IOCTL_TCP_SET_INFORMATION_EX:
+ DPRINT1("TCPIP: Should handle IOCTL_TCP_SET_INFORMATION_EX.\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case IOCTL_SET_IP_ADDRESS:
+ DPRINT1("TCPIP: Should handle IOCTL_SET_IP_ADDRESS.\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ case IOCTL_DELETE_IP_ADDRESS:
+ DPRINT1("TCPIP: Should handle IOCTL_DELETE_IP_ADDRESS.\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ default:
+ DPRINT1("TCPIP: Unknown IOCTL 0x%#x\n",
IrpSp->Parameters.DeviceIoControl.IoControlCode);
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ DPRINT("TCPIP dispatched with status 0x%08x.\n", Status);
+
+ Irp->IoStatus.Status = Status;
+ if (Status == STATUS_PENDING)
+ {
+ IoMarkIrpPending(Irp);
+ }
+ else
+ {
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ }
+
+ return Status;
+}
+
+static
+VOID
+NTAPI
+TcpIpUnload(
+ _In_ struct _DRIVER_OBJECT *DriverObject
+)
+{
+ IoDeleteDevice(IpDeviceObject);
+ IoDeleteDevice(RawIpDeviceObject);
+ IoDeleteDevice(UdpDeviceObject);
+ IoDeleteDevice(TcpDeviceObject);
+ TcpIpUnregisterNdisProtocol();
+}
Propchange: branches/tcpip_revolution/drivers/network/tcpip/main.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/main.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/main.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.c [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,339 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/ndis_proto.c
+ * PURPOSE: tcpip.sys: ndis protocol bindings
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+// FIXME: Maybe more in the future ?
+static NDIS_MEDIUM NdisMediaArray[] = { NdisMedium802_3 };
+
+/* The handle we got from NDIS for this protocol */
+static NDIS_HANDLE NdisHandle;
+
+/* Initializes the various values lwip will need */
+static
+NDIS_STATUS
+InitializeInterface(
+ _Inout_ TCPIP_INTERFACE* Interface)
+{
+ NDIS_STATUS Status;
+ NDIS_REQUEST Request;
+ UINT MTU;
+ NDIS_OID QueryAddrOid;
+ UINT PacketFilter;
+
+ /* Add this interface into the entities DB */
+ InsertEntityInstance(CL_NL_ENTITY, &Interface->ClNlInstance);
+ InsertEntityInstance(IF_ENTITY, &Interface->IfInstance);
+ InsertEntityInstance(AT_ENTITY, &Interface->AtInstance);
+
+ /* Get the MTU from the NIC */
+ Request.RequestType = NdisRequestQueryInformation;
+ Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_FRAME_SIZE;
+ Request.DATA.QUERY_INFORMATION.InformationBuffer = &MTU;
+ Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(UINT);
+ NdisRequest(&Status, Interface->NdisContext, &Request);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not get MTU from the NIC driver!\n");
+ return Status;
+ }
+ Interface->lwip_netif.mtu = MTU;
+
+ /* Setup media type related data. */
+ switch (NdisMediaArray[Interface->MediumIndex])
+ {
+ case NdisMedium802_3:
+ Interface->lwip_netif.hwaddr_len = ETHARP_HWADDR_LEN;
+ QueryAddrOid = OID_802_3_CURRENT_ADDRESS;
+ PacketFilter = NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_DIRECTED |
NDIS_PACKET_TYPE_MULTICAST;
+ break;
+ default:
+ /* This is currently impossible */
+ DPRINT1("Unknown medium!\n");
+ NT_ASSERT(FALSE);
+ return NDIS_STATUS_UNSUPPORTED_MEDIA;
+ }
+
+ /* Get the address */
+ Request.RequestType = NdisRequestQueryInformation;
+ Request.DATA.QUERY_INFORMATION.Oid = QueryAddrOid;
+ Request.DATA.QUERY_INFORMATION.InformationBuffer =
&Interface->lwip_netif.hwaddr[0];
+ Request.DATA.QUERY_INFORMATION.InformationBufferLength = NETIF_MAX_HWADDR_LEN;
+ NdisRequest(&Status, Interface->NdisContext, &Request);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not get HW address from the NIC driver!\n");
+ return Status;
+ }
+
+ /* Get the link speed */
+ Request.RequestType = NdisRequestQueryInformation;
+ Request.DATA.QUERY_INFORMATION.Oid = OID_GEN_LINK_SPEED;
+ Request.DATA.QUERY_INFORMATION.InformationBuffer = &Interface->Speed;
+ Request.DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(ULONG);
+ NdisRequest(&Status, Interface->NdisContext, &Request);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not get link speed NIC driver!\n");
+ /* Good old 10Mb/s as default */
+ Interface->Speed = 100000;
+ }
+ /* NDIS drivers give it in 100bps unit */
+ Interface->Speed *= 100;
+
+ /* Set the packet filter */
+ Request.RequestType = NdisRequestSetInformation;
+ Request.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
+ Request.DATA.SET_INFORMATION.InformationBuffer = &PacketFilter;
+ Request.DATA.SET_INFORMATION.InformationBufferLength = sizeof(PacketFilter);
+ NdisRequest(&Status, Interface->NdisContext, &Request);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not get HW address from the NIC driver!\n");
+ return Status;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+/* The various callbacks we will give to NDIS */
+static
+VOID
+NTAPI
+ProtocolOpenAdapterComplete(
+ _In_ NDIS_HANDLE ProtocolBindingContext,
+ _In_ NDIS_STATUS Status,
+ _In_ NDIS_STATUS OpenErrorStatus)
+{
+ TCPIP_INTERFACE* Interface = (TCPIP_INTERFACE*)ProtocolBindingContext;
+
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(Interface, TAG_INTERFACE);
+ return;
+ }
+
+ Status = InitializeInterface(Interface);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Unbind the interface and that's all */
+ NdisCloseAdapter(&Status, Interface->NdisContext);
+ }
+}
+
+static
+VOID
+NTAPI
+ProtocolCloseAdapterComplete(
+ _In_ NDIS_HANDLE ProtocolBindingContext,
+ _In_ NDIS_STATUS Status)
+{
+ UNIMPLEMENTED
+}
+
+static
+VOID
+NTAPI
+ProtocolResetComplete(
+ _In_ NDIS_HANDLE ProtocolBindingContext,
+ _In_ NDIS_STATUS Status)
+{
+ UNIMPLEMENTED
+}
+
+static
+VOID
+NTAPI
+ProtocolRequestComplete(
+ _In_ NDIS_HANDLE ProtocolBindingContext,
+ _In_ PNDIS_REQUEST NdisRequest,
+ _In_ NDIS_STATUS Status)
+{
+ UNIMPLEMENTED
+}
+
+static
+VOID
+NTAPI
+ProtocolReceiveComplete(
+ _In_ NDIS_HANDLE ProtocolBindingContext)
+{
+ UNIMPLEMENTED
+}
+
+static
+VOID
+NTAPI
+ProtocolStatusComplete(
+ _In_ NDIS_HANDLE ProtocolBindingContext)
+{
+ UNIMPLEMENTED
+}
+
+/* bridge between NDIS and lwip: send data to the adapter */
+static
+err_t
+lwip_netif_linkoutput(
+ struct netif *netif,
+ struct pbuf *p)
+{
+ UNIMPLEMENTED
+ return ERR_OK;
+}
+
+/* lwip interface initialisation function */
+static
+err_t
+lwip_netif_init(
+ struct netif* lwip_netif)
+{
+ /* Set output callbacks */
+ lwip_netif->output = etharp_output;
+ lwip_netif->linkoutput = lwip_netif_linkoutput;
+
+ /* We use ARP and broadcasting */
+ lwip_netif->flags |= NETIF_FLAG_ETHARP | NETIF_FLAG_BROADCAST;
+
+ /* Let's say we're ethernet */
+ lwip_netif->name[0] = 'e';
+ lwip_netif->name[1] = 'n';
+
+ return ERR_OK;
+}
+
+static
+VOID
+NTAPI
+ProtocolBindAdapter(
+ _Out_ PNDIS_STATUS Status,
+ _In_ NDIS_HANDLE BindContext,
+ _In_ PNDIS_STRING DeviceName,
+ _In_ PVOID SystemSpecific1,
+ _In_ PVOID SystemSpecific2)
+{
+ TCPIP_INTERFACE* Interface;
+ NDIS_STATUS OpenErrorStatus;
+ UNICODE_STRING RealDeviceName;
+ struct ip_addr IpAddr, SubnetMask, GatewayAddr;
+ err_t lwip_error;
+
+ /* The device name comes in the \Device\AdapterName form */
+ RealDeviceName.Buffer = DeviceName->Buffer + 8;
+ RealDeviceName.Length = DeviceName->Length - (8 * sizeof(WCHAR));
+ RealDeviceName.MaximumLength = DeviceName->MaximumLength - (8 * sizeof(WCHAR));
+
+ /* Allocate an interface for this NIC */
+ Interface = ExAllocatePoolWithTag(PagedPool,
+ sizeof(*Interface) + RealDeviceName.MaximumLength,
+ TAG_INTERFACE);
+ if (!Interface)
+ {
+ DPRINT1("Could not allocate an interface structure!\n");
+ *Status = NDIS_STATUS_RESOURCES;
+ return;
+ }
+
+ /* Copy the device name */
+ RtlInitEmptyUnicodeString(&Interface->DeviceName, (PWSTR)(Interface + 1),
RealDeviceName.MaximumLength);
+ RtlCopyUnicodeString(&Interface->DeviceName, &RealDeviceName);
+
+ /* Add the interface to the lwip list */
+ ip_addr_set_zero(&IpAddr);
+ ip_addr_set_zero(&SubnetMask);
+ ip_addr_set_zero(&GatewayAddr);
+ lwip_error = netifapi_netif_add(
+ &Interface->lwip_netif,
+ &IpAddr,
+ &SubnetMask,
+ &GatewayAddr,
+ Interface,
+ lwip_netif_init,
+ ethernet_input);
+ if (lwip_error != ERR_OK)
+ {
+ DPRINT1("netifapi_netif_add failed with error %d.\n", lwip_error);
+ *Status = NDIS_STATUS_RESOURCES;
+ return;
+ }
+
+ /* Get a adapter handle from NDIS */
+ NdisOpenAdapter(
+ Status,
+ &OpenErrorStatus,
+ &Interface->NdisContext,
+ &Interface->MediumIndex,
+ NdisMediaArray,
+ sizeof(NdisMediaArray) / sizeof(NdisMediaArray[0]),
+ NdisHandle,
+ Interface,
+ DeviceName,
+ 0,
+ NULL);
+ if (*Status == NDIS_STATUS_PENDING)
+ {
+ /* Silently return, as the binding will be finished in the async call */
+ return;
+ }
+
+ if (*Status != NDIS_STATUS_SUCCESS)
+ {
+ DPRINT1("NdisOpenAdapter failed with status 0x%08x.\n", *Status);
+ ExFreePoolWithTag(Interface, TAG_INTERFACE);
+ return;
+ }
+
+ /* Finish the bind request in sync */
+ *Status = InitializeInterface(Interface);
+}
+
+static
+VOID
+NTAPI
+ProtocolUnbindAdapter(
+ _Out_ PNDIS_STATUS Status,
+ _In_ NDIS_HANDLE ProtocolBindingContext,
+ _In_ NDIS_HANDLE UnbindContext)
+{
+ UNIMPLEMENTED
+}
+
+NTSTATUS
+TcpIpRegisterNdisProtocol(void)
+{
+ NDIS_STATUS Status;
+ NDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics;
+
+ /* Simply fill in the structure and pass it to the NDIS driver. */
+ RtlZeroMemory(&ProtocolCharacteristics, sizeof(ProtocolCharacteristics));
+ ProtocolCharacteristics.MajorNdisVersion = NDIS_PROTOCOL_MAJOR_VERSION;
+ ProtocolCharacteristics.MinorNdisVersion = NDIS_PROTOCOL_MINOR_VERSION;
+ ProtocolCharacteristics.Reserved = 0;
+ ProtocolCharacteristics.OpenAdapterCompleteHandler = ProtocolOpenAdapterComplete;
+ ProtocolCharacteristics.CloseAdapterCompleteHandler = ProtocolCloseAdapterComplete;
+ ProtocolCharacteristics.ResetCompleteHandler = ProtocolResetComplete;
+ ProtocolCharacteristics.RequestCompleteHandler = ProtocolRequestComplete;
+ ProtocolCharacteristics.ReceiveCompleteHandler = ProtocolReceiveComplete;
+ ProtocolCharacteristics.StatusCompleteHandler = ProtocolStatusComplete;
+ ProtocolCharacteristics.BindAdapterHandler = ProtocolBindAdapter;
+ ProtocolCharacteristics.UnbindAdapterHandler = ProtocolUnbindAdapter;
+ RtlInitUnicodeString(&ProtocolCharacteristics.Name, L"TcpIp");
+
+ NdisRegisterProtocol(&Status, &NdisHandle, &ProtocolCharacteristics,
sizeof(ProtocolCharacteristics));
+
+ return Status;
+}
+
+void
+TcpIpUnregisterNdisProtocol(void)
+{
+ NDIS_STATUS Status;
+
+ NdisDeregisterProtocol(&Status, NdisHandle);
+}
Propchange: branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.h
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.h (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.h [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,8 @@
+
+#pragma once
+
+NTSTATUS
+TcpIpRegisterNdisProtocol(void);
+
+void
+TcpIpUnregisterNdisProtocol(void);
Propchange: branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.h
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/ndis_lwip.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/precomp.h
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/precomp.h (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/precomp.h [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,34 @@
+
+#ifndef __TCPIP_PRECOMP_H__
+#define __TCPIP_PRECOMP_H__
+
+#include <ntifs.h>
+#include <windef.h>
+#include <tdi.h>
+#include <tdiinfo.h>
+#include <tdikrnl.h>
+#include <tcpioctl.h>
+#include <ndis.h>
+#include <ipifcons.h>
+
+typedef unsigned short u_short;
+#include <ws2def.h>
+
+#include <rtlfuncs.h>
+
+#include <pseh/pseh2.h>
+
+#include <lwip/tcpip.h>
+#include <lwip/snmp.h>
+#include <lwip/raw.h>
+#include <lwip/udp.h>
+#include <netif/etharp.h>
+
+#include "entities.h"
+#include "address.h"
+#include "information.h"
+#include "interface.h"
+#include "ndis_lwip.h"
+#include "tcp.h"
+
+#endif /* __TCPIP_PRECOMP_H__ */
Propchange: branches/tcpip_revolution/drivers/network/tcpip/precomp.h
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/precomp.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/precomp.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/stubs.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/stubs.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/stubs.c [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,42 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/main.c
+ * PURPOSE: tcpip.sys unimplemented functions
+ */
+
+#include "precomp.h"
+
+#define NDEBUG
+#include <debug.h>
+
+VOID
+NTAPI
+IPAddInterface(
+ ULONG Unknown0,
+ ULONG Unknown1,
+ ULONG Unknown2,
+ ULONG Unknown3,
+ ULONG Unknown4)
+{
+ UNIMPLEMENTED
+}
+
+
+VOID
+NTAPI
+IPDelInterface(
+ ULONG Unknown0)
+{
+ UNIMPLEMENTED
+}
+
+
+VOID
+NTAPI
+LookupRoute(
+ ULONG Unknown0,
+ ULONG Unknown1)
+{
+ UNIMPLEMENTED
+}
Propchange: branches/tcpip_revolution/drivers/network/tcpip/stubs.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/stubs.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/stubs.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/tcp.c
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/tcp.c (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/tcp.c [iso-8859-1] Mon Nov 10 18:00:09
2014
@@ -0,0 +1,64 @@
+/*
+ * PROJECT: ReactOS tcpip.sys
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * FILE: drivers/network/tcpip/main.c
+ * PURPOSE: tcpip.sys TCP functionality
+ */
+
+#include "precomp.h"
+
+#include <intsafe.h>
+
+#define NDEBUG
+#include <debug.h>
+
+static KSPIN_LOCK PortBitmapSpinlock;
+static RTL_BITMAP PortBitmap;
+static ULONG PortBitmapBuffer[(USHORT_MAX + 1) / 32];
+static USHORT PortNumberHint = 1;
+
+void
+TcpIpInitializeTcp(void)
+{
+ /* Initialize the port stuff */
+ KeInitializeSpinLock(&PortBitmapSpinlock);
+ RtlInitializeBitMap(&PortBitmap, PortBitmapBuffer, USHORT_MAX + 1);
+ RtlClearAllBits(&PortBitmap);
+ /* Reserve the port 0 */
+ RtlSetBit(&PortBitmap, 0);
+}
+
+BOOLEAN
+AllocateTcpPort(
+ _Inout_ USHORT* PortNumber,
+ _In_ BOOLEAN Shared)
+{
+ KIRQL OldIrql;
+ ULONG_PTR Bit;
+
+ KeAcquireSpinLock(&PortBitmapSpinlock, &OldIrql);
+
+ if (*PortNumber)
+ {
+ if (RtlCheckBit(&PortBitmap, *PortNumber))
+ {
+ if (!Shared)
+ *PortNumber = 0;
+ KeReleaseSpinLock(&PortBitmapSpinlock, OldIrql);
+ return TRUE;
+ }
+
+ RtlSetBit(&PortBitmap, *PortNumber);
+ KeReleaseSpinLock(&PortBitmapSpinlock, OldIrql);
+ return FALSE;
+ }
+
+ Bit = RtlFindClearBitsAndSet(&PortBitmap, 1, PortNumberHint);
+ if (Bit == ULONG_PTR_MAX)
+ *PortNumber = 0;
+ else
+ *PortNumber = Bit;
+ PortNumberHint = *PortNumber;
+ return FALSE;
+}
+
Propchange: branches/tcpip_revolution/drivers/network/tcpip/tcp.c
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/tcp.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/tcp.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/tcp.h
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/tcp.h (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/tcp.h [iso-8859-1] Mon Nov 10 18:00:09
2014
@@ -0,0 +1,10 @@
+
+#pragma once
+
+void
+TcpIpInitializeTcp(void);
+
+BOOLEAN
+AllocateTcpPort(
+ _Inout_ USHORT* PortNumber,
+ _In_ BOOLEAN Shared);
Propchange: branches/tcpip_revolution/drivers/network/tcpip/tcp.h
------------------------------------------------------------------------------
charset = UTF-8
Propchange: branches/tcpip_revolution/drivers/network/tcpip/tcp.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/tcpip_revolution/drivers/network/tcpip/tcp.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/tcpip_revolution/drivers/network/tcpip/tcpip.rc
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/tcpip.rc (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/tcpip.rc [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "TCP/IP protocol driver"
+#define REACTOS_STR_INTERNAL_NAME "tcpip"
+#define REACTOS_STR_ORIGINAL_FILENAME "tcpip.sys"
+#include <reactos/version.rc>
Propchange: branches/tcpip_revolution/drivers/network/tcpip/tcpip.rc
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/tcpip_revolution/drivers/network/tcpip/tcpip.spec
URL:
http://svn.reactos.org/svn/reactos/branches/tcpip_revolution/drivers/networ…
==============================================================================
--- branches/tcpip_revolution/drivers/network/tcpip/tcpip.spec (added)
+++ branches/tcpip_revolution/drivers/network/tcpip/tcpip.spec [iso-8859-1] Mon Nov 10
18:00:09 2014
@@ -0,0 +1,25 @@
+;FreeIprBuff
+;GetIFAndLink
+@ stdcall IPAddInterface(long long long long long)
+;IPAllocBuff
+@ stdcall IPDelInterface(long)
+;IPDelayedNdisReEnumerateBindings
+;IPDeregisterARP
+;IPDisableSniffer
+;IPEnableSniffer
+;IPFreeBuff
+;IPGetAddrType
+;IPGetBestInterface
+;IPGetInfo
+;IPInjectPkt
+;IPProxyNdisRequest
+;IPRegisterARP
+;IPRegisterProtocol
+;IPSetIPSecStatus
+;IPTransmit
+@ stdcall LookupRoute(long long)
+;LookupRouteInformation
+;SendICMPErr
+;SetIPSecPtr
+;UnSetIPSecPtr
+;UnSetIPSecSendPtr
Propchange: branches/tcpip_revolution/drivers/network/tcpip/tcpip.spec
------------------------------------------------------------------------------
svn:eol-style = native