Author: zhu
Date: Thu Aug 18 21:38:06 2016
New Revision: 72334
URL:
http://svn.reactos.org/svn/reactos?rev=72334&view=rev
Log:
Added back UDP code from the original driver I received to work on. Modified address
creation function to support UDP, ICMP, and RAW. Added TDI_QUERY_ADDRESS_INFO handler.
Modified:
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/information.c
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c
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] Thu Aug 18
21:38:06 2016
@@ -212,6 +212,10 @@
static LIST_ENTRY AddressListHead;
/* Forward-declare lwIP callback functions */
+static u8_t lwip_raw_ReceiveDatagram_callback(void *arg, struct raw_pcb *pcb, struct pbuf
*p,
+ ip_addr_t *addr);
+static void lwip_udp_ReceiveDatagram_callback(void *arg, struct udp_pcb *pcb, struct pbuf
*p,
+ ip_addr_t *addr, u16_t port);
static err_t lwip_tcp_accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err);
static err_t lwip_tcp_recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p,
err_t err);
static err_t lwip_tcp_sent_callback(void *arg, struct tcp_pcb *tpcb, u16_t len);
@@ -1690,6 +1694,90 @@
return Status;
}
+static
+BOOLEAN
+ReceiveDatagram(
+ ADDRESS_FILE* AddressFile,
+ struct pbuf *p,
+ ip_addr_t *addr,
+ u16_t port)
+{
+ KIRQL OldIrql;
+ LIST_ENTRY* ListEntry;
+ RECEIVE_DATAGRAM_REQUEST* Request;
+ ip_addr_t RequestAddr;
+ BOOLEAN Result = FALSE;
+
+ NT_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
+
+ DPRINT1("Receiving datagram for addr 0x%08x on port %u.\n",
ip4_addr_get_u32(addr), port);
+
+ /* 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 == lwip_htons(port)) ||
!port)))
+ {
+ PTA_IP_ADDRESS ReturnAddress;
+ PIRP Irp;
+
+ DPRINT1("Found a corresponding IRP.\n");
+
+ Irp = Request->Irp;
+
+ /* We found a request for this one */
+ IoSetCancelRoutine(Irp, NULL);
+ RemoveEntryList(&Request->ListEntry);
+ Result = TRUE;
+
+ KeReleaseSpinLockFromDpcLevel(&AddressFile->RequestLock);
+ IoReleaseCancelSpinLock(OldIrql);
+
+ /* In case of UDP, lwip provides a pbuf directly pointing to the data.
+ * In other case, we must skip the IP header */
+ Irp->IoStatus.Information = 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 = lwip_htons(port);
+ ReturnAddress->Address->Address->in_addr = ip4_addr_get_u32(addr);
+ RtlZeroMemory(ReturnAddress->Address->Address->sin_zero,
+ sizeof(ReturnAddress->Address->Address->sin_zero));
+
+ if (Request->BufferLength < p->tot_len)
+ Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
+ else
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
+
+ /* Start again from the beginning */
+ IoAcquireCancelSpinLock(&OldIrql);
+ KeAcquireSpinLockAtDpcLevel(&AddressFile->RequestLock);
+ }
+ }
+
+ KeReleaseSpinLockFromDpcLevel(&AddressFile->RequestLock);
+ IoReleaseCancelSpinLock(OldIrql);
+
+ return Result;
+}
+
/**
* TCP/IP Stack Functions
**/
@@ -1809,6 +1897,8 @@
{
PADDRESS_FILE AddressFile;
PLIST_ENTRY Entry;
+
+ ip_addr_t IpAddr;
/* If a netif is specified, check for AddressFile with matching netif and port in
order to
* detect duplicates */
@@ -1859,18 +1949,34 @@
RtlCopyMemory(&AddressFile->Address, Address, sizeof(*Address));
AddressFile->NetInterface = lwip_netif;
- /* Entity ID */
+ /* Entity ID and, for unconnected protocols, lwIP PCB and callback functions. */
switch (Protocol)
{
case IPPROTO_TCP :
InsertEntityInstance(CO_TL_ENTITY, &AddressFile->Instance);
break;
- case IPPROTO_ICMP :
- InsertEntityInstance(ER_ENTITY, &AddressFile->Instance);
+ case IPPROTO_UDP :
+ 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,
lwip_ntohs(AddressFile->Address.sin_port));
+ ip_set_option(AddressFile->lwip_udp_pcb, SOF_BROADCAST);
+ udp_recv(AddressFile->lwip_udp_pcb, lwip_udp_ReceiveDatagram_callback,
AddressFile);
break;
default :
- /* UDP, RAW */
- InsertEntityInstance(CL_TL_ENTITY, &AddressFile->Instance);
+ if (Protocol == IPPROTO_ICMP)
+ {
+ InsertEntityInstance(ER_ENTITY, &AddressFile->Instance);
+ }
+ else
+ {
+ InsertEntityInstance(CL_TL_ENTITY, &AddressFile->Instance);
+ }
+ ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr);
+ AddressFile->lwip_raw_pcb = raw_new(Protocol);
+ raw_bind(AddressFile->lwip_raw_pcb, &IpAddr);
+ ip_set_option(AddressFile->lwip_raw_pcb, SOF_BROADCAST);
+ raw_recv(AddressFile->lwip_raw_pcb, lwip_raw_ReceiveDatagram_callback,
AddressFile);
break;
}
@@ -1880,7 +1986,6 @@
/* UDP and RAW variables */
KeInitializeSpinLock(&AddressFile->RequestLock);
InitializeListHead(&AddressFile->RequestListHead);
- AddressFile->lwip_raw_pcb = NULL;
/* Add to master list */
InsertTailList(&AddressListHead, &AddressFile->ListEntry);
@@ -1988,6 +2093,66 @@
/**
* lwIP Callback Functions
**/
+
+static
+u8_t
+lwip_raw_ReceiveDatagram_callback(
+ void *arg,
+ struct raw_pcb *pcb,
+ struct pbuf *p,
+ ip_addr_t *addr)
+{
+ BOOLEAN Result;
+ ADDRESS_FILE* AddressFile = arg;
+
+ UNREFERENCED_PARAMETER(pcb);
+
+ /* If this is for ICMP, only process the "echo received" packets.
+ * The rest is processed by lwip. */
+ if (AddressFile->Protocol == IPPROTO_ICMP)
+ {
+ /* See icmp_input */
+ s16_t hlen;
+ struct ip_hdr *iphdr;
+
+ iphdr = (struct ip_hdr *)p->payload;
+ hlen = IPH_HL(iphdr) * 4;
+
+ /* Adjust the pbuf to skip the IP header */
+ if (pbuf_header(p, -hlen))
+ return FALSE;
+
+ if (*((u8_t*)p->payload) != ICMP_ER)
+ {
+ pbuf_header(p, hlen);
+ return FALSE;
+ }
+
+ pbuf_header(p, hlen);
+ }
+
+ Result = ReceiveDatagram(arg, p, addr, 0);
+
+ if (Result)
+ 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);
+ pbuf_free(p);
+}
static
err_t
Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/information.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/information.c [iso-8859-1]
(original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/information.c [iso-8859-1] Thu Aug
18 21:38:06 2016
@@ -158,6 +158,31 @@
/* See what we are queried */
switch (Query->QueryType)
{
+ case TDI_QUERY_ADDRESS_INFO :
+ PTDI_ADDRESS_INFO AddressInfo;
+ PADDRESS_FILE AddressFile;
+ PTA_ADDRESS TAAddress;
+
+ if (MmGetMdlByteCount(Irp->MdlAddress) < sizeof(*AddressInfo)) {
+ DPRINT1("MDL buffer too small.\n");
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ AddressFile = IrpSp->FileObject->FsContext;
+
+ AddressInfo = MmGetSystemAddressForMdl(Irp->MdlAddress);
+ AddressInfo->ActivityCount = AddressFile->RefCount;
+ AddressInfo->Address.TAAddressCount = 1;
+
+ TAAddress = AddressInfo->Address.Address;
+ TAAddress->AddressLength = TDI_ADDRESS_LENGTH_IP;
+ TAAddress->AddressType = TDI_ADDRESS_TYPE_IP;
+ RtlCopyMemory(&TAAddress->Address[0], &AddressFile->Address,
TDI_ADDRESS_LENGTH_IP);
+
+ Status = STATUS_SUCCESS;
+
+ break;
case TDI_QUERY_MAX_DATAGRAM_INFO:
{
PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo;
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] Thu Aug 18
21:38:06 2016
@@ -428,9 +428,7 @@
break;
case TDI_RECEIVE_DATAGRAM:
DPRINT1("TCPIP: TDI_RECEIVE_DATAGRAM!\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- //return TcpIpReceiveDatagram(Irp);
+ return TcpIpReceiveDatagram(Irp);
case TDI_SEND:
DPRINT1("TCPIP: TDI_SEND!\n");
@@ -456,9 +454,7 @@
case TDI_SEND_DATAGRAM:
DPRINT1("TCPIP: TDI_SEND_DATAGRAM!\n");
- Status = STATUS_NOT_IMPLEMENTED;
- break;
- //return TcpIpSendDatagram(Irp);
+ return TcpIpSendDatagram(Irp);
case TDI_ACCEPT:
DPRINT1("TCPIP: TDI_ACCEPT!\n");