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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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/network... ============================================================================== --- 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