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/network/tcpip/address.c?rev=72334&r1=72333&r2=72334&view=diff
==============================================================================
--- 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/network/tcpip/information.c?rev=72334&r1=72333&r2=72334&view=diff
==============================================================================
--- 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/network/tcpip/main.c?rev=72334&r1=72333&r2=72334&view=diff
==============================================================================
--- 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");


Reply via email to