Author: zhu
Date: Fri Jun 17 17:12:07 2016
New Revision: 71652
URL:
http://svn.reactos.org/svn/reactos?rev=71652&view=rev
Log:
TDI_SEND and TDI_RECEIVE handlers code-complete. None of it has been tested yet.
Modified:
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c
branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/CMakeLists.txt
Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c [iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c [iso-8859-1] Fri Jun 17
17:12:07 2016
@@ -27,6 +27,7 @@
static KSPIN_LOCK AddressListLock;
static LIST_ENTRY AddressListHead;
+/* implementation in testing */
NTSTATUS
PrepareIrpForCancel(
PIRP Irp,
@@ -54,6 +55,7 @@
return Irp->IoStatus.Status;
}
+/* implementation in testing */
VOID
NTAPI
CancelRequestRoutine(
@@ -235,6 +237,7 @@
pbuf_free(p);
}
+/* implementation in testing */
static
err_t
lwip_tcp_accept_callback(
@@ -258,26 +261,112 @@
Irp->Cancel = FALSE;
IoReleaseCancelSpinLock(OldIrql);
- DPRINT1("\nnewpcb %08x\n", newpcb);
- if (AddressFile->ConnectionContext)
- {
- if (AddressFile->ConnectionContext->lwip_tcp_pcb)
+ AddressFile->ConnectionContext->lwip_tcp_pcb = newpcb;
+
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+ return ERR_OK;
+}
+
+/* implementation in testing */
+static
+err_t
+lwip_tcp_sent_callback(
+ void *arg,
+ struct tcp_pcb *tpcb,
+ u16_t len
+)
+{
+ return ERR_OK;
+}
+
+/* This implementation does not take into account any flags */
+static
+err_t
+lwip_tcp_receive_callback(
+ void *arg,
+ struct tcp_pcb *tpcb,
+ struct pbuf *p,
+ err_t err
+)
+{
+ PIRP Irp;
+ PNDIS_BUFFER Buffer;
+ PIO_STACK_LOCATION IrpSp;
+ PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
+ KIRQL OldIrql;
+
+ INT CopiedLength;
+ INT RemainingDestBytes;
+ INT RemainingSrceBytes;
+ UCHAR *CurrentDestLocation;
+ UCHAR *CurrentSrceLocation;
+
+ DPRINT1("lwIP TCP Receive Callback\n");
+
+ Irp = (PIRP)arg;
+
+ IoAcquireCancelSpinLock(&OldIrql);
+ IoSetCancelRoutine(Irp, NULL);
+ Irp->Cancel = FALSE;
+ IoReleaseCancelSpinLock(OldIrql);
+
+ Buffer = (PNDIS_BUFFER)Irp->MdlAddress;
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters;
+
+ if (ReceiveInfo->ReceiveLength <= p->len)
+ {
+ RtlCopyMemory(Buffer, p->payload, ReceiveInfo->ReceiveLength);
+ CopiedLength = ReceiveInfo->ReceiveLength;
+ goto RETURN;
+ }
+ else
+ {
+ CopiedLength = 0;
+ RemainingDestBytes = ReceiveInfo->ReceiveLength;
+ RemainingSrceBytes = p->len;
+ CurrentDestLocation = (UCHAR*)Buffer;
+ CurrentSrceLocation = p->payload;
+
+ while (1)
{
- DPRINT1("\nlwip_tcp_pcb %08x\n",
AddressFile->ConnectionContext->lwip_tcp_pcb);
+ if (RemainingSrceBytes < RemainingDestBytes)
+ {
+ RtlCopyMemory(CurrentDestLocation, CurrentSrceLocation, RemainingSrceBytes);
+
+ CopiedLength += p->len;
+ RemainingDestBytes -= p->len;
+ CurrentDestLocation += p->len;
+
+ if (p->next)
+ {
+ RemainingSrceBytes = p->next->len;
+ CurrentSrceLocation = p->next->payload;
+
+ p = p->next;
+
+ continue;
+ }
+ else
+ {
+ goto RETURN;
+ }
+ }
+ else
+ {
+ RtlCopyMemory(CurrentDestLocation, CurrentSrceLocation, RemainingDestBytes);
+ CopiedLength += RemainingDestBytes;
+
+ goto RETURN;
+ }
}
- else
- {
- DPRINT1("\nlwip_tcp_pcb is NULL\n");
- }
- }
- else
- {
- DPRINT1("ConnectionContext is NULL\n");
- }
-
- AddressFile->ConnectionContext->lwip_tcp_pcb = newpcb;
-
+ }
+
+RETURN:
Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = CopiedLength;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
return ERR_OK;
@@ -328,6 +417,7 @@
return Result;
}
+/* implementation in testing */
static
err_t
lwip_tcp_Connected_callback(
@@ -336,48 +426,28 @@
err_t err)
{
PIRP Irp;
- PIO_STACK_LOCATION IrpSp;
KIRQL OldIrql;
- PADDRESS_FILE AddressFile;
DPRINT1("lwIP TCP Connected Callback\n");
Irp = (PIRP)arg;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- AddressFile = (PADDRESS_FILE)IrpSp->FileObject->FsContext;
IoAcquireCancelSpinLock(&OldIrql);
IoSetCancelRoutine(Irp, NULL);
Irp->Cancel = FALSE;
IoReleaseCancelSpinLock(OldIrql);
- DPRINT1("\ntpcb %08x\n", tpcb);
- if (AddressFile->ConnectionContext)
- {
- if (AddressFile->ConnectionContext->lwip_tcp_pcb)
- {
- DPRINT1("\nlwip_tcp_pcb %08x\n",
AddressFile->ConnectionContext->lwip_tcp_pcb);
- }
- else
- {
- DPRINT1("\nlwip_tcp_pcb is NULL\n");
- }
- }
- else
- {
- DPRINT1("ConnectionContext is NULL\n");
- }
-
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
return ERR_OK;
}
+/* implementation in testing */
NTSTATUS
TcpIpCreateAddress(
_Inout_ PIRP Irp,
- _Inout_ PTDI_ADDRESS_IP Address,
+ _In_ PTDI_ADDRESS_IP Address,
_In_ IPPROTO Protocol
)
{
@@ -552,15 +622,35 @@
return STATUS_SUCCESS;
}
+/* implementation in testing */
NTSTATUS
TcpIpCreateContext(
_Inout_ PIRP Irp,
+ _In_ PTDI_ADDRESS_IP Address,
_In_ IPPROTO Protocol
)
{
PIO_STACK_LOCATION IrpSp;
PTCP_CONTEXT Context;
+ ULONG *temp;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ temp = (ULONG*)Address;
+ DPRINT1("\n TcpIpCreateAddress Input Dump\n %08x %08x %08x %08x\n",
+ temp[3], temp[2],
+ temp[1], temp[0]);
+ if (IrpSp->FileObject && IrpSp->FileObject->FsContext)
+ {
+ temp = IrpSp->FileObject->FsContext;
+ if (temp) {
+ DPRINT1("\n IrpSp Dump\n %08x %08x %08x %08x\n %08x %08x %08x %08x\n",
+ temp[7], temp[6], temp[5], temp[4],
+ temp[3], temp[2], temp[1], temp[0]);
+ }
+ }
+
Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Context), TAG_ADDRESS_FILE);
if (!Context)
{
@@ -573,20 +663,20 @@
return STATUS_INVALID_PARAMETER;
}
Context->Protocol = Protocol;
+ Context->RequestAddress = *Address;
Context->lwip_tcp_pcb = tcp_new();
if (Context->lwip_tcp_pcb == NULL)
{
return STATUS_NO_MEMORY;
}
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
IrpSp->FileObject->FsContext = (PVOID)Context;
IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONNECTION_FILE;
return STATUS_SUCCESS;
}
+/* implementation in testing */
NTSTATUS
TcpIpCloseAddress(
_Inout_ ADDRESS_FILE* AddressFile
@@ -600,6 +690,7 @@
if (InterlockedDecrement(&AddressFile->RefCount) != 0)
{
/* There are still some open handles for this address */
+ DPRINT1("TcpIpCloseAddress on address with open handles\n");
KeReleaseSpinLock(&AddressListLock, OldIrql);
return STATUS_SUCCESS;
}
@@ -609,7 +700,10 @@
udp_remove(AddressFile->lwip_udp_pcb);
else if (AddressFile->Protocol == IPPROTO_TCP &&
AddressFile->ConnectionContext)
{
- tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb);
+ if (AddressFile->ConnectionContext->lwip_tcp_pcb)
+ {
+ tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb);
+ }
ExFreePoolWithTag(AddressFile->ConnectionContext, TAG_ADDRESS_FILE);
}
else if (AddressFile->Protocol == IPPROTO_RAW)
@@ -742,8 +836,6 @@
AddressFile->ConnectionContext->lwip_tcp_pcb->local_ip,
AddressFile->ConnectionContext->lwip_tcp_pcb->local_port);
- PrepareIrpForCancel(Irp, CancelRequestRoutine);
-
lwip_err = tcp_connect(AddressFile->ConnectionContext->lwip_tcp_pcb,
(ip_addr_t *)&SocketAddressInRemote->sin_addr.s_addr,
SocketAddressInRemote->sin_port,
@@ -753,35 +845,42 @@
{
case (ERR_VAL) :
{
+ DPRINT1("lwip ERR_VAL\n");
return STATUS_INVALID_PARAMETER;
}
case (ERR_ISCONN) :
{
+ DPRINT1("lwip ERR_ISCONN\n");
return STATUS_CONNECTION_ACTIVE;
}
case (ERR_RTE) :
{
/* several errors look right here */
+ DPRINT1("lwip ERR_RTE\n");
return STATUS_NETWORK_UNREACHABLE;
}
case (ERR_BUF) :
{
/* use correct error once NDIS errors are included
this return value means local port unavailable */
+ DPRINT1("lwip ERR_BUF\n");
return STATUS_ADDRESS_ALREADY_EXISTS;
}
case (ERR_USE) :
{
/* STATUS_CONNECTION_ACTIVE maybe? */
+ DPRINT1("lwip ERR_USE\n");
return STATUS_ADDRESS_ALREADY_EXISTS;
}
case (ERR_MEM) :
{
+ DPRINT1("lwip ERR_MEM\n");
return STATUS_NO_MEMORY;
}
case (ERR_OK) :
{
DPRINT1("lwip ERR_OK\n");
+ PrepareIrpForCancel(Irp, CancelRequestRoutine);
tcp_arg(AddressFile->ConnectionContext->lwip_tcp_pcb, Irp);
break;
}
@@ -852,6 +951,7 @@
if (AddressFile->Address.in_addr == 0)
{
+ // should really look through address file list for an interface
AddressFile->Address.in_addr = 0x0100007f;
}
@@ -860,10 +960,12 @@
AddressFile->Address.in_addr);
/* Finally calling into lwip to perform socket bind */
+ ip_set_option(Context->lwip_tcp_pcb, SOF_REUSEADDR);
lwip_err = tcp_bind(
Context->lwip_tcp_pcb,
(ip_addr_t *)&AddressFile->Address.in_addr,
AddressFile->Address.sin_port);
+ ip_set_option(Context->lwip_tcp_pcb, SOF_BROADCAST);
DPRINT1("lwip error %d\n TCP PCB:\n Local Address: %08x\n Local Port: %04x\n
Remote Address: %08x\n Remote Port: %04x\n",
lwip_err,
Context->lwip_tcp_pcb->local_ip,
@@ -909,7 +1011,6 @@
}
}
}
- ip_set_option(Context->lwip_tcp_pcb, SOF_BROADCAST);
Context->AddressFile = AddressFile;
AddressFile->ConnectionContext = Context;
@@ -996,7 +1097,7 @@
either INVALID_ADDRESS or NO_MEMORY
if SO_REUSE is enabled in lwip options */
DPRINT1("lwip tcp_listen error\n");
- return STATUS_NO_MEMORY;
+ return STATUS_INVALID_ADDRESS;
}
else
{
@@ -1007,6 +1108,111 @@
tcp_accept(ConnectionContext->lwip_tcp_pcb, lwip_tcp_accept_callback);
tcp_arg(ConnectionContext->lwip_tcp_pcb, Irp);
+
+ return STATUS_PENDING;
+}
+
+NTSTATUS
+TcpIpSend(
+ _Inout_ PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp;
+ PTDI_REQUEST_KERNEL_SEND Request;
+ PADDRESS_FILE AddressFile;
+ PTCP_CONTEXT Context;
+ PNDIS_BUFFER Buffer;
+
+ err_t lwip_err;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ Request = (PTDI_REQUEST_KERNEL_SEND)&IrpSp->Parameters;
+
+ if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE)
+ {
+ DPRINT1("TcpIpSend without a TDI_TRANSPORT_ADDRESS_FILE\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+ AddressFile = IrpSp->FileObject->FsContext;
+
+ if (!AddressFile->ConnectionContext)
+ {
+ DPRINT1("TcpIpSend with no TCP_CONTEXT\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+ Context = AddressFile->ConnectionContext;
+
+ if (!Irp->MdlAddress)
+ {
+ DPRINT1("TcpIpSendEmpty\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+ Buffer = (PNDIS_BUFFER)Irp->MdlAddress;
+
+ if (!Context->lwip_tcp_pcb)
+ {
+ DPRINT1("TcpIpSend with no lwIP tcp_pcb\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ lwip_err = tcp_write(Context->lwip_tcp_pcb, Buffer, Request->SendLength, 0);
+ switch (lwip_err)
+ {
+ case ERR_OK:
+ DPRINT1("lwIP ERR_OK\n");
+ break;
+ case ERR_MEM:
+ DPRINT1("lwIP ERR_MEM\n");
+ return STATUS_NO_MEMORY;
+ case ERR_ARG:
+ DPRINT1("lwIP ERR_ARG\n");
+ return STATUS_INVALID_PARAMETER;
+ case ERR_CONN:
+ DPRINT1("lwIP ERR_CONN\n");
+ return STATUS_CONNECTION_ACTIVE;
+ default:
+ DPRINT1("Unknwon lwIP Error: %d\n", lwip_err);
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ tcp_arg(Context->lwip_tcp_pcb, Irp);
+ tcp_sent(Context->lwip_tcp_pcb, lwip_tcp_sent_callback);
+
+ return STATUS_PENDING;
+}
+
+NTSTATUS
+TcpIpReceive(
+ _Inout_ PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp;
+ PADDRESS_FILE AddressFile;
+ PTCP_CONTEXT Context;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+
+ if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE)
+ {
+ DPRINT1("TcpIpReceive on something that is not an address file\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+ AddressFile = IrpSp->FileObject->FsContext;
+
+ if (!AddressFile->ConnectionContext)
+ {
+ DPRINT1("Receiving on TCP address file with no connection context\n");
+ return STATUS_INVALID_ADDRESS;
+ }
+ Context = AddressFile->ConnectionContext;
+
+ if (!Context->lwip_tcp_pcb)
+ {
+ DPRINT1("Connection context does not contain a lwIP tcp_pcb\n");
+ return STATUS_INVALID_ADDRESS;
+ }
+
+ PrepareIrpForCancel(Irp, CancelRequestRoutine);
+ tcp_recv(Context->lwip_tcp_pcb, lwip_tcp_receive_callback);
+ tcp_arg(Context->lwip_tcp_pcb, Irp);
return STATUS_PENDING;
}
Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h [iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h [iso-8859-1] Fri Jun 17
17:12:07 2016
@@ -21,6 +21,7 @@
ADDRESS_FILE *AddressFile;
LIST_ENTRY ListEntry;
IPPROTO Protocol;
+ TDI_ADDRESS_IP RequestAddress;
LONG RefCount;
KSPIN_LOCK Lock;
KIRQL OldIrql;
@@ -40,6 +41,7 @@
NTSTATUS
TcpIpCreateContext(
_Inout_ PIRP Irp,
+ _In_ PTDI_ADDRESS_IP Address,
_In_ IPPROTO Protocol
);
@@ -65,12 +67,22 @@
NTSTATUS
TcpIpListen(
- _Inout_ PIRP Irp);
+ _Inout_ PIRP Irp
+);
+
+NTSTATUS
+TcpIpReceive(
+ _Inout_ PIRP Irp
+);
NTSTATUS
TcpIpReceiveDatagram(
_Inout_ PIRP Irp);
+NTSTATUS
+TcpIpSend(
+ _Inout_ PIRP Irp);
+
NTSTATUS
TcpIpSendDatagram(
_Inout_ PIRP Irp);
Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c [iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c [iso-8859-1] Fri Jun 17
17:12:07 2016
@@ -316,7 +316,7 @@
DPRINT1("\n PTA_IP_ADDRESS dump before\n %08x %08x %08x %08x\n %08x %08x %08x
%08x\n",
temp[7], temp[6], temp[5], temp[4],
temp[3], temp[2], temp[1], temp[0]);
- Status = TcpIpCreateContext(Irp, Protocol);
+ Status = TcpIpCreateContext(Irp, &Address->Address[0].Address[0], Protocol);
DPRINT1("\n PTA_IP_ADDRESS dump after\n %08x %08x %08x %08x\n %08x %08x %08x
%08x\n",
temp[7], temp[6], temp[5], temp[4],
temp[3], temp[2], temp[1], temp[0]);
@@ -399,25 +399,62 @@
{
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp;
+ PADDRESS_FILE AddressFile;
DPRINT1("TcpIpDispatchInternal\n");
IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ AddressFile = IrpSp->FileObject->FsContext;
+
switch (IrpSp->MinorFunction)
{
case TDI_RECEIVE:
DPRINT1("TCPIP: TDI_RECEIVE!\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
-
+ switch (AddressFile->Protocol)
+ {
+ case IPPROTO_TCP:
+ Status = TcpIpReceive(Irp);
+ break;
+ case IPPROTO_UDP:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ case IPPROTO_RAW:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ default:
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+ if (Status == STATUS_NOT_IMPLEMENTED)
+ {
+ DPRINT1("Received TDI_RECEIVE for non-TCP protocol\n");
+
+ }
+ break;
case TDI_RECEIVE_DATAGRAM:
DPRINT1("TCPIP: TDI_RECEIVE_DATAGRAM!\n");
return TcpIpReceiveDatagram(Irp);
case TDI_SEND:
DPRINT1("TCPIP: TDI_SEND!\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ switch (AddressFile->Protocol)
+ {
+ case IPPROTO_TCP:
+ Status = TcpIpSend(Irp);
+ break;
+ case IPPROTO_UDP:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ case IPPROTO_RAW:
+ Status = STATUS_NOT_IMPLEMENTED;
+ break;
+ default:
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+ if (Status == STATUS_NOT_IMPLEMENTED)
+ {
+ DPRINT1("Received TDI_SEND for non-TCP protocol\n");
+ }
break;
case TDI_SEND_DATAGRAM:
Modified: branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/sdk/lib/dr…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/CMakeLists.txt [iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/CMakeLists.txt [iso-8859-1] Fri Jun 17
17:12:07 2016
@@ -2,7 +2,7 @@
add_subdirectory(chew)
add_subdirectory(csq)
add_subdirectory(hidparser)
-add_subdirectory(ip)
+#add_subdirectory(ip)
add_subdirectory(libusb)
add_subdirectory(lwip)
add_subdirectory(ntoskrnl_vista)