* Sync the recent cmake branch changes.
authorAmine Khaldi <amine.khaldi@reactos.org>
Mon, 6 Jun 2011 20:39:26 +0000 (20:39 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Mon, 6 Jun 2011 20:39:26 +0000 (20:39 +0000)
svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52122

189 files changed:
drivers/network/afd/afd/bind.c
drivers/network/afd/afd/connect.c
drivers/network/afd/afd/listen.c
drivers/network/afd/afd/main.c
drivers/network/afd/afd/tdi.c
drivers/network/tcpip/CMakeLists.txt
drivers/network/tcpip/include/debug.h
drivers/network/tcpip/include/precomp.h
drivers/network/tcpip/include/tcp.h
drivers/network/tcpip/include/tcpip.h
drivers/network/tcpip/include/titypes.h
drivers/network/tcpip/tcpip/dispatch.c
drivers/network/tcpip/tcpip/fileobjs.c
drivers/network/tcpip/tcpip/main.c
lib/drivers/CMakeLists.txt
lib/drivers/ip/CMakeLists.txt
lib/drivers/ip/network/ip.c
lib/drivers/ip/network/routines.c
lib/drivers/ip/transport/tcp/accept.c
lib/drivers/ip/transport/tcp/event.c
lib/drivers/ip/transport/tcp/if.c
lib/drivers/ip/transport/tcp/tcp.c
lib/drivers/lwip/CHANGELOG [new file with mode: 0644]
lib/drivers/lwip/CMakeLists.txt [new file with mode: 0644]
lib/drivers/lwip/COPYING [new file with mode: 0644]
lib/drivers/lwip/FILES [new file with mode: 0644]
lib/drivers/lwip/README [new file with mode: 0644]
lib/drivers/lwip/UPGRADING [new file with mode: 0644]
lib/drivers/lwip/doc/FILES [new file with mode: 0644]
lib/drivers/lwip/doc/contrib.txt [new file with mode: 0644]
lib/drivers/lwip/doc/rawapi.txt [new file with mode: 0644]
lib/drivers/lwip/doc/savannah.txt [new file with mode: 0644]
lib/drivers/lwip/doc/snmp_agent.txt [new file with mode: 0644]
lib/drivers/lwip/doc/sys_arch.txt [new file with mode: 0644]
lib/drivers/lwip/lwip.rbuild [new file with mode: 0755]
lib/drivers/lwip/src/FILES [new file with mode: 0644]
lib/drivers/lwip/src/api/api_lib.c [new file with mode: 0644]
lib/drivers/lwip/src/api/api_msg.c [new file with mode: 0644]
lib/drivers/lwip/src/api/err.c [new file with mode: 0644]
lib/drivers/lwip/src/api/netbuf.c [new file with mode: 0644]
lib/drivers/lwip/src/api/netdb.c [new file with mode: 0644]
lib/drivers/lwip/src/api/netifapi.c [new file with mode: 0644]
lib/drivers/lwip/src/api/sockets.c [new file with mode: 0644]
lib/drivers/lwip/src/api/tcpip.c [new file with mode: 0644]
lib/drivers/lwip/src/core/def.c [new file with mode: 0644]
lib/drivers/lwip/src/core/dhcp.c [new file with mode: 0644]
lib/drivers/lwip/src/core/dns.c [new file with mode: 0644]
lib/drivers/lwip/src/core/init.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv4/autoip.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv4/icmp.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv4/igmp.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv4/inet.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv4/inet_chksum.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv4/ip.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv4/ip_addr.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv4/ip_frag.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv6/README [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv6/icmp6.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv6/inet6.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv6/ip6.c [new file with mode: 0644]
lib/drivers/lwip/src/core/ipv6/ip6_addr.c [new file with mode: 0644]
lib/drivers/lwip/src/core/mem.c [new file with mode: 0644]
lib/drivers/lwip/src/core/memp.c [new file with mode: 0644]
lib/drivers/lwip/src/core/netif.c [new file with mode: 0644]
lib/drivers/lwip/src/core/pbuf.c [new file with mode: 0644]
lib/drivers/lwip/src/core/raw.c [new file with mode: 0644]
lib/drivers/lwip/src/core/snmp/asn1_dec.c [new file with mode: 0644]
lib/drivers/lwip/src/core/snmp/asn1_enc.c [new file with mode: 0644]
lib/drivers/lwip/src/core/snmp/mib2.c [new file with mode: 0644]
lib/drivers/lwip/src/core/snmp/mib_structs.c [new file with mode: 0644]
lib/drivers/lwip/src/core/snmp/msg_in.c [new file with mode: 0644]
lib/drivers/lwip/src/core/snmp/msg_out.c [new file with mode: 0644]
lib/drivers/lwip/src/core/stats.c [new file with mode: 0644]
lib/drivers/lwip/src/core/sys.c [new file with mode: 0644]
lib/drivers/lwip/src/core/tcp.c [new file with mode: 0644]
lib/drivers/lwip/src/core/tcp_in.c [new file with mode: 0644]
lib/drivers/lwip/src/core/tcp_out.c [new file with mode: 0644]
lib/drivers/lwip/src/core/timers.c [new file with mode: 0644]
lib/drivers/lwip/src/core/udp.c [new file with mode: 0644]
lib/drivers/lwip/src/include/arch/bpstruct.h [new file with mode: 0755]
lib/drivers/lwip/src/include/arch/cc.h [new file with mode: 0755]
lib/drivers/lwip/src/include/arch/epstruct.h [new file with mode: 0755]
lib/drivers/lwip/src/include/arch/perf.h [new file with mode: 0755]
lib/drivers/lwip/src/include/arch/sys_arch.h [new file with mode: 0755]
lib/drivers/lwip/src/include/ipv4/lwip/autoip.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv4/lwip/icmp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv4/lwip/igmp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv4/lwip/inet.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv4/lwip/inet_chksum.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv4/lwip/ip.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv4/lwip/ip_addr.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv4/lwip/ip_frag.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv6/lwip/icmp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv6/lwip/inet.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv6/lwip/ip.h [new file with mode: 0644]
lib/drivers/lwip/src/include/ipv6/lwip/ip_addr.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/api.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/api_msg.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/arch.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/debug.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/def.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/dhcp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/dns.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/err.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/init.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/mem.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/memp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/memp_std.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/netbuf.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/netdb.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/netif.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/netifapi.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/opt.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/pbuf.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/raw.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/sio.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/snmp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/snmp_asn1.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/snmp_msg.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/snmp_structs.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/sockets.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/stats.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/sys.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/tcp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/tcp_impl.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/tcpip.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/timers.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwip/udp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/lwipopts.h [new file with mode: 0755]
lib/drivers/lwip/src/include/netif/etharp.h [new file with mode: 0644]
lib/drivers/lwip/src/include/netif/loopif.h [new file with mode: 0644]
lib/drivers/lwip/src/include/netif/ppp_oe.h [new file with mode: 0644]
lib/drivers/lwip/src/include/netif/slipif.h [new file with mode: 0644]
lib/drivers/lwip/src/include/rosip.h [new file with mode: 0755]
lib/drivers/lwip/src/netif/FILES [new file with mode: 0644]
lib/drivers/lwip/src/netif/etharp.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ethernetif.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/loopif.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/auth.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/auth.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/chap.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/chap.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/chpms.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/chpms.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/fsm.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/fsm.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/ipcp.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/ipcp.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/lcp.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/lcp.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/magic.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/magic.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/md5.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/md5.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/pap.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/pap.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/ppp.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/ppp.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/ppp_oe.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/pppdebug.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/randm.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/randm.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/vj.c [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/vj.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/ppp/vjbsdhdr.h [new file with mode: 0644]
lib/drivers/lwip/src/netif/slipif.c [new file with mode: 0644]
lib/drivers/lwip/src/rosip.c [new file with mode: 0755]
lib/drivers/lwip/src/rosmem.c [new file with mode: 0755]
lib/drivers/lwip/src/rostcp.c [new file with mode: 0755]
lib/drivers/lwip/src/sys_arch.c [new file with mode: 0755]
lib/drivers/lwip/test/unit/lwip_check.h [new file with mode: 0644]
lib/drivers/lwip/test/unit/lwip_unittests.c [new file with mode: 0644]
lib/drivers/lwip/test/unit/tcp/tcp_helper.c [new file with mode: 0644]
lib/drivers/lwip/test/unit/tcp/tcp_helper.h [new file with mode: 0644]
lib/drivers/lwip/test/unit/tcp/test_tcp.c [new file with mode: 0644]
lib/drivers/lwip/test/unit/tcp/test_tcp.h [new file with mode: 0644]
lib/drivers/lwip/test/unit/tcp/test_tcp_oos.c [new file with mode: 0644]
lib/drivers/lwip/test/unit/tcp/test_tcp_oos.h [new file with mode: 0644]
lib/drivers/lwip/test/unit/udp/test_udp.c [new file with mode: 0644]
lib/drivers/lwip/test/unit/udp/test_udp.h [new file with mode: 0644]
tests/simplesocket/client.c [new file with mode: 0644]
tests/simplesocket/client.exe [new file with mode: 0644]
tests/simplesocket/client_delayed.exe [new file with mode: 0644]
tests/simplesocket/client_multi.exe [new file with mode: 0644]
tests/simplesocket/server.c [new file with mode: 0644]
tests/simplesocket/server.exe [new file with mode: 0644]
tests/simplesocket/server_multi.exe [new file with mode: 0644]
todo_gsoc.txt [new file with mode: 0644]
tools/pefixup.c [new file with mode: 0644]

index 8144d03..ac52f1f 100644 (file)
 #include "tdiconn.h"
 #include "debug.h"
 
-NTSTATUS WarmSocketForBind( PAFD_FCB FCB ) {
+NTSTATUS WarmSocketForBind( PAFD_FCB FCB )
+{
     NTSTATUS Status;
 
     AFD_DbgPrint(MID_TRACE,("Called (AF %d)\n",
                             FCB->LocalAddress->Address[0].AddressType));
 
-    if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) {
+    if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer )
+    {
         AFD_DbgPrint(MID_TRACE,("Null Device\n"));
         return STATUS_NO_SUCH_DEVICE;
     }
-    if( !FCB->LocalAddress ) {
+    if( !FCB->LocalAddress )
+    {
         AFD_DbgPrint(MID_TRACE,("No local address\n"));
         return STATUS_INVALID_PARAMETER;
     }
@@ -54,7 +57,8 @@ NTSTATUS WarmSocketForBind( PAFD_FCB FCB ) {
 
 NTSTATUS NTAPI
 AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
-             PIO_STACK_LOCATION IrpSp) {
+             PIO_STACK_LOCATION IrpSp)
+{
     NTSTATUS Status = STATUS_SUCCESS;
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
@@ -62,41 +66,44 @@ AfdBindSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
 
     AFD_DbgPrint(MID_TRACE,("Called\n"));
 
-    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
-    if( !(BindReq = LockRequest( Irp, IrpSp )) )
-       return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
-                                      Irp, 0 );
+    if ( !SocketAcquireStateLock( FCB ) )
+        return LostSocket( Irp );
+    if ( !(BindReq = LockRequest( Irp, IrpSp )) )
+           return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
 
-    if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
-    FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );
+    if ( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
+        FCB->LocalAddress = TaCopyTransportAddress( &BindReq->Address );
 
-    if( FCB->LocalAddress )
-       Status = TdiBuildConnectionInfo( &FCB->AddressFrom,
-                                        FCB->LocalAddress );
+    if (FCB->LocalAddress)
+           Status = TdiBuildConnectionInfo( &FCB->AddressFrom,
+                                            FCB->LocalAddress );
 
-    if( NT_SUCCESS(Status) )
-       Status = WarmSocketForBind( FCB );
+    if (NT_SUCCESS(Status))
+           Status = WarmSocketForBind( FCB );
+    
     AFD_DbgPrint(MID_TRACE,("FCB->Flags %x\n", FCB->Flags));
 
-    if( !NT_SUCCESS(Status) )
+    if (!NT_SUCCESS(Status))
         return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
 
-    if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) {
-       AFD_DbgPrint(MID_TRACE,("Calling TdiReceiveDatagram\n"));
-
-       Status = TdiReceiveDatagram
-           ( &FCB->ReceiveIrp.InFlightRequest,
-             FCB->AddressFile.Object,
-             0,
-             FCB->Recv.Window,
-             FCB->Recv.Size,
-             FCB->AddressFrom,
-             &FCB->ReceiveIrp.Iosb,
-             PacketSocketRecvComplete,
-             FCB );
-
-       /* We don't want to wait for this read to complete. */
-       if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS;
+    if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
+    {
+           AFD_DbgPrint(MID_TRACE,("Calling TdiReceiveDatagram\n"));
+
+           Status = TdiReceiveDatagram
+               ( &FCB->ReceiveIrp.InFlightRequest,
+                 FCB->AddressFile.Object,
+                 0,
+                 FCB->Recv.Window,
+                 FCB->Recv.Size,
+                 FCB->AddressFrom,
+                 &FCB->ReceiveIrp.Iosb,
+                 PacketSocketRecvComplete,
+                 FCB );
+
+           /* We don't want to wait for this read to complete. */
+           if (Status == STATUS_PENDING)
+            Status = STATUS_SUCCESS;
     }
 
     if (NT_SUCCESS(Status))
index 28fcfad..837a975 100644 (file)
@@ -185,10 +185,12 @@ AfdSetConnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
 }
 
 
-NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
+NTSTATUS WarmSocketForConnection( PAFD_FCB FCB )
+{
     NTSTATUS Status;
 
-    if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer ) {
+    if( !FCB->TdiDeviceName.Length || !FCB->TdiDeviceName.Buffer )
+    {
         AFD_DbgPrint(MID_TRACE,("Null Device\n"));
         return STATUS_NO_SUCH_DEVICE;
     }
@@ -197,7 +199,8 @@ NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
                                            &FCB->Connection.Handle,
                                            &FCB->Connection.Object );
 
-    if( NT_SUCCESS(Status) ) {
+    if( NT_SUCCESS(Status) )
+    {
         Status = TdiAssociateAddressFile( FCB->AddressFile.Handle,
                                           FCB->Connection.Object );
     }
@@ -205,7 +208,8 @@ NTSTATUS WarmSocketForConnection( PAFD_FCB FCB ) {
     return Status;
 }
 
-NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB ) {
+NTSTATUS MakeSocketIntoConnection( PAFD_FCB FCB )
+{
     NTSTATUS Status;
 
     ASSERT(!FCB->Recv.Window);
@@ -265,6 +269,8 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
 
     AFD_DbgPrint(MID_TRACE,("Called: FCB %x, FO %x\n",
                            Context, FCB->FileObject));
+    DbgPrint("[StreamSocketConnectComplete] Called: FCB %x, FO %x\n",
+                           Context, FCB->FileObject);
 
     /* I was wrong about this before as we can have pending writes to a not
      * yet connected socket */
@@ -276,39 +282,53 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
 
     FCB->ConnectIrp.InFlightRequest = NULL;
 
-    if( FCB->State == SOCKET_STATE_CLOSED ) {
+    if( FCB->State == SOCKET_STATE_CLOSED )
+    {
         /* Cleanup our IRP queue because the FCB is being destroyed */
-        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) ) {
-              NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
-              NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
-              NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
-              NextIrp->IoStatus.Information = 0;
-              if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
-               (void)IoSetCancelRoutine(NextIrp, NULL);
-              IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) )
+        {
+               NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
+               NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
+               NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
+               NextIrp->IoStatus.Information = 0;
+              
+            if( NextIrp->MdlAddress )
+                UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
+            (void)IoSetCancelRoutine(NextIrp, NULL);
+              
+            IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
         }
-       SocketStateUnlock( FCB );
-       return STATUS_FILE_CLOSED;
+           SocketStateUnlock( FCB );
+           return STATUS_FILE_CLOSED;
     }
 
-    if( !NT_SUCCESS(Irp->IoStatus.Status) ) {
-       FCB->PollState |= AFD_EVENT_CONNECT_FAIL;
+    if( !NT_SUCCESS(Irp->IoStatus.Status) )
+    {
+           FCB->PollState |= AFD_EVENT_CONNECT_FAIL;
         FCB->PollStatus[FD_CONNECT_BIT] = Irp->IoStatus.Status;
-       AFD_DbgPrint(MID_TRACE,("Going to bound state\n"));
-       FCB->State = SOCKET_STATE_BOUND;
+           
+        AFD_DbgPrint(MID_TRACE,("[StreamSocketConnectComplete] Going to bound state\n"));
+           
+        FCB->State = SOCKET_STATE_BOUND;
         PollReeval( FCB->DeviceExt, FCB->FileObject );
     }
 
     /* Succeed pending irps on the FUNCTION_CONNECT list */
-    while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) ) {
-       NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
-       NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
-       AFD_DbgPrint(MID_TRACE,("Completing connect %x\n", NextIrp));
-       NextIrp->IoStatus.Status = Status;
-       NextIrp->IoStatus.Information = NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0;
-       if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
-        (void)IoSetCancelRoutine(NextIrp, NULL);
-       IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
+    while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) )
+    {
+        NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]);
+           NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
+           
+        AFD_DbgPrint(MID_TRACE,("Completing connect %x\n", NextIrp));
+        DbgPrint("[StreamSocketConnectComplete] Completing connect %x\n", NextIrp);
+           
+        NextIrp->IoStatus.Status = Status;
+           NextIrp->IoStatus.Information = NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0;
+           
+        if( NextIrp->MdlAddress )
+            UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) );
+            (void)IoSetCancelRoutine(NextIrp, NULL);
+           IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
     }
 
     if( NT_SUCCESS(Status) ) {
@@ -362,7 +382,8 @@ static NTSTATUS NTAPI StreamSocketConnectComplete
    stream type. */
 NTSTATUS NTAPI
 AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
-                      PIO_STACK_LOCATION IrpSp) {
+                      PIO_STACK_LOCATION IrpSp)
+{
     NTSTATUS Status = STATUS_INVALID_PARAMETER;
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
@@ -376,106 +397,114 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                                       0 );
 
     AFD_DbgPrint(MID_TRACE,("Connect request:\n"));
+    DbgPrint("[AfdStreamSocketConnect] Connect request:\n");
 #if 0
     OskitDumpBuffer
        ( (PCHAR)ConnectReq,
          IrpSp->Parameters.DeviceIoControl.InputBufferLength );
 #endif
 
-   if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
-   {
-       if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
-       FCB->RemoteAddress =
-           TaCopyTransportAddress( &ConnectReq->RemoteAddress );
-
-       if( !FCB->RemoteAddress )
-           Status = STATUS_NO_MEMORY;
-       else
-           Status = STATUS_SUCCESS;
-
-       return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
-   }
-
-    switch( FCB->State ) {
-    case SOCKET_STATE_CONNECTED:
-       Status = STATUS_SUCCESS;
-       break;
-
-    case SOCKET_STATE_CONNECTING:
-       return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
+    if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
+    {
+        if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
+        FCB->RemoteAddress =
+               TaCopyTransportAddress( &ConnectReq->RemoteAddress );
 
-    case SOCKET_STATE_CREATED:
-       if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
-       FCB->LocalAddress =
-           TaCopyTransportAddress( &ConnectReq->RemoteAddress );
+        if( !FCB->RemoteAddress )
+               Status = STATUS_NO_MEMORY;
+        else
+               Status = STATUS_SUCCESS;
 
-       if( FCB->LocalAddress ) {
-           Status = WarmSocketForBind( FCB );
+        return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
+    }
 
-           if( NT_SUCCESS(Status) )
-               FCB->State = SOCKET_STATE_BOUND;
-           else
-               return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
-       } else
-           return UnlockAndMaybeComplete
-               ( FCB, STATUS_NO_MEMORY, Irp, 0 );
+    switch( FCB->State )
+    {
+        case SOCKET_STATE_CONNECTED:
+               Status = STATUS_SUCCESS;
+               break;
+
+        case SOCKET_STATE_CONNECTING:
+               return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
+
+        case SOCKET_STATE_CREATED:
+               if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
+               FCB->LocalAddress =
+                   TaCopyTransportAddress( &ConnectReq->RemoteAddress );
+
+               if( FCB->LocalAddress )
+            {
+                   Status = WarmSocketForBind( FCB );
+
+                   if( NT_SUCCESS(Status) )
+                       FCB->State = SOCKET_STATE_BOUND;
+                   else
+                       return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
+               }
+            else
+                   return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 );
     
-    /* Drop through to SOCKET_STATE_BOUND */
-
-    case SOCKET_STATE_BOUND:
-       if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
-       FCB->RemoteAddress =
-           TaCopyTransportAddress( &ConnectReq->RemoteAddress );
-
-       if( !FCB->RemoteAddress ) {
-           Status = STATUS_NO_MEMORY;
-           break;
-       }
-
-       Status = WarmSocketForConnection( FCB );
-
-       if( !NT_SUCCESS(Status) )
-           break;
-
-       Status = TdiBuildConnectionInfo
-           ( &FCB->ConnectInfo,
-             &ConnectReq->RemoteAddress );
-
-        if( NT_SUCCESS(Status) )
-            Status = TdiBuildConnectionInfo(&TargetAddress,
-                                           &ConnectReq->RemoteAddress);
-        else break;
-
-
-       if( NT_SUCCESS(Status) ) {
-            TargetAddress->UserData = FCB->ConnectData;
-            TargetAddress->UserDataLength = FCB->ConnectDataSize;
-            TargetAddress->Options = FCB->ConnectOptions;
-            TargetAddress->OptionsLength = FCB->ConnectOptionsSize;
-
-           Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
-                                FCB->Connection.Object,
-                                TargetAddress,
-                                FCB->ConnectInfo,
-                                &FCB->ConnectIrp.Iosb,
-                                StreamSocketConnectComplete,
-                                FCB );
-
-            ExFreePool(TargetAddress);
-
-           AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp));
-
-           if( Status == STATUS_PENDING ) {
-                FCB->State = SOCKET_STATE_CONNECTING;
-               return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
-            }
-       }
-       break;
-
-    default:
-       AFD_DbgPrint(MID_TRACE,("Inappropriate socket state %d for connect\n",
-                               FCB->State));
-       break;
+        /* Drop through to SOCKET_STATE_BOUND */
+
+        case SOCKET_STATE_BOUND:
+               if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress );
+                   FCB->RemoteAddress =
+                       TaCopyTransportAddress( &ConnectReq->RemoteAddress );
+
+               if( !FCB->RemoteAddress )
+            {
+                   Status = STATUS_NO_MEMORY;
+                   break;
+               }
+
+               Status = WarmSocketForConnection( FCB );
+
+               if( !NT_SUCCESS(Status) )
+                   break;
+
+               Status = TdiBuildConnectionInfo
+                   ( &FCB->ConnectInfo,
+                     &ConnectReq->RemoteAddress );
+
+            if( NT_SUCCESS(Status) )
+                Status = TdiBuildConnectionInfo(&TargetAddress,
+                                               &ConnectReq->RemoteAddress);
+            else break;
+
+               if( NT_SUCCESS(Status) )
+            {
+                TargetAddress->UserData = FCB->ConnectData;
+                TargetAddress->UserDataLength = FCB->ConnectDataSize;
+                TargetAddress->Options = FCB->ConnectOptions;
+                TargetAddress->OptionsLength = FCB->ConnectOptionsSize;
+
+                   Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
+                                        FCB->Connection.Object,
+                                        TargetAddress,
+                                        FCB->ConnectInfo,
+                                        &FCB->ConnectIrp.Iosb,
+                                        StreamSocketConnectComplete,
+                                        FCB );
+
+                    ExFreePool(TargetAddress);
+
+                   AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp));
+                DbgPrint("[AfdStreamSocketConnect] Queueing IRP %x\n", Irp);
+
+                   if( Status == STATUS_PENDING )
+                {
+                        FCB->State = SOCKET_STATE_CONNECTING;
+                               return LeaveIrpUntilLater(FCB, Irp, FUNCTION_CONNECT);
+                }
+               }
+               break;
+
+        default:
+               AFD_DbgPrint(MID_TRACE,("Inappropriate socket state %d for connect\n",
+                                       FCB->State));
+            DbgPrint("[AfdStreamSocketConnect] Inappropriate socket state %d for connect\n",
+                        FCB->State);
+               break;
     }
 
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
index f6eb110..4184cea 100644 (file)
@@ -24,6 +24,7 @@ static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt,
 
     /* Transfer the connection to the new socket, launch the opening read */
     AFD_DbgPrint(MID_TRACE,("Completing a real accept (FCB %x)\n", FCB));
+    DbgPrint("[SatisfyAccept] Completing a real accept (FCB %x)\n", FCB);
 
     FCB->Connection = Qelt->Object;
 
@@ -42,7 +43,8 @@ static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt,
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
 
-static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) {
+static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt )
+{
     PAFD_RECEIVED_ACCEPT_DATA ListenReceive =
        (PAFD_RECEIVED_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer;
     PTA_IP_ADDRESS IPAddr;
@@ -54,6 +56,11 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) {
                             &ListenReceive->Address,
                             Qelt->ConnInfo->RemoteAddress));
 
+    DbgPrint("[SatisfyPreAccept] Giving SEQ %d to userland\n", Qelt->Seq);
+    DbgPrint("[SatisfyPreAccept] Socket Address (K) %x (U) %x\n",
+                            &ListenReceive->Address,
+                            Qelt->ConnInfo->RemoteAddress);
+
     TaCopyTransportAddressInPlace( &ListenReceive->Address,
                                   Qelt->ConnInfo->RemoteAddress );
 
@@ -79,6 +86,17 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) {
     AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_addr %x\n",
                             IPAddr->Address[0].Address[0].in_addr));
 
+    DbgPrint("IPAddr->TAAddressCount %d\n",
+                            IPAddr->TAAddressCount);
+    DbgPrint("IPAddr->Address[0].AddressType %d\n",
+                            IPAddr->Address[0].AddressType);
+    DbgPrint("IPAddr->Address[0].AddressLength %d\n",
+                            IPAddr->Address[0].AddressLength);
+    DbgPrint("IPAddr->Address[0].Address[0].sin_port %x\n",
+                            IPAddr->Address[0].Address[0].sin_port);
+    DbgPrint("IPAddr->Address[0].Address[0].sin_addr %x\n",
+                            IPAddr->Address[0].Address[0].in_addr);
+
     if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) );
 
     Irp->IoStatus.Information = ((PCHAR)&IPAddr[1]) - ((PCHAR)ListenReceive);
@@ -91,7 +109,8 @@ static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) {
 static NTSTATUS NTAPI ListenComplete
 ( PDEVICE_OBJECT DeviceObject,
   PIRP Irp,
-  PVOID Context ) {
+  PVOID Context )
+{
     NTSTATUS Status = STATUS_SUCCESS;
     PAFD_FCB FCB = (PAFD_FCB)Context;
     PAFD_TDI_OBJECT_QELT Qelt;
@@ -103,9 +122,11 @@ static NTSTATUS NTAPI ListenComplete
 
     FCB->ListenIrp.InFlightRequest = NULL;
 
-    if( FCB->State == SOCKET_STATE_CLOSED ) {
+    if( FCB->State == SOCKET_STATE_CLOSED )
+    {
         /* Cleanup our IRP queue because the FCB is being destroyed */
-        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) ) {
+        while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) )
+        {
               NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_PREACCEPT]);
               NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry);
               NextIrp->IoStatus.Status = STATUS_FILE_CLOSED;
@@ -135,29 +156,40 @@ static NTSTATUS NTAPI ListenComplete
             FCB->ListenIrp.ConnectionCallInfo = NULL;
         }
 
-       SocketStateUnlock( FCB );
-       return STATUS_FILE_CLOSED;
+           SocketStateUnlock( FCB );
+           return STATUS_FILE_CLOSED;
     }
 
     AFD_DbgPrint(MID_TRACE,("Completing listen request.\n"));
     AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", FCB->ListenIrp.Iosb.Status));
 
+    DbgPrint("[AFD, ListenComplete] Completing listen request.\n");
+    DbgPrint("[AFD, ListenComplete] IoStatus was %x\n", FCB->ListenIrp.Iosb.Status);
+
     Qelt = ExAllocatePool( NonPagedPool, sizeof(*Qelt) );
-    if( !Qelt ) {
-       Status = STATUS_NO_MEMORY;
-    } else {
-        UINT AddressType =
-            FCB->LocalAddress->Address[0].AddressType;
+    if( !Qelt )
+    {
+           Status = STATUS_NO_MEMORY;
+    }
+    else
+    {
+        UINT AddressType = FCB->LocalAddress->Address[0].AddressType;
 
-       Qelt->Object = FCB->Connection;
-       Qelt->Seq = FCB->ConnSeq++;
+           Qelt->Object = FCB->Connection;
+           Qelt->Seq = FCB->ConnSeq++;
         AFD_DbgPrint(MID_TRACE,("Address Type: %d (RA %x)\n",
                                 AddressType,
                                 FCB->ListenIrp.
                                 ConnectionReturnInfo->RemoteAddress));
 
+        DbgPrint("[AFD, ListenComplete] Address Type: %d (RA %x)\n",
+                    AddressType,
+                    FCB->ListenIrp.
+                    ConnectionReturnInfo->RemoteAddress);
+
         Status = TdiBuildNullConnectionInfo( &Qelt->ConnInfo, AddressType );
-        if( NT_SUCCESS(Status) ) {
+        if( NT_SUCCESS(Status) )
+        {
             TaCopyTransportAddressInPlace
                ( Qelt->ConnInfo->RemoteAddress,
                  FCB->ListenIrp.ConnectionReturnInfo->RemoteAddress );
@@ -167,23 +199,25 @@ static NTSTATUS NTAPI ListenComplete
 
     /* Satisfy a pre-accept request if one is available */
     if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) &&
-       !IsListEmpty( &FCB->PendingConnections ) ) {
-       PLIST_ENTRY PendingIrp  =
-           RemoveHeadList( &FCB->PendingIrpList[FUNCTION_PREACCEPT] );
-       PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
-       SatisfyPreAccept
-           ( CONTAINING_RECORD( PendingIrp, IRP,
-                                Tail.Overlay.ListEntry ),
-             CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT,
-                                ListEntry ) );
+           !IsListEmpty( &FCB->PendingConnections ) )
+    {
+           PLIST_ENTRY PendingIrp  =
+               RemoveHeadList( &FCB->PendingIrpList[FUNCTION_PREACCEPT] );
+           PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
+           SatisfyPreAccept( CONTAINING_RECORD( PendingIrp, IRP,
+                                    Tail.Overlay.ListEntry ),
+                 CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT,
+                                    ListEntry ) );
     }
 
-    if( FCB->ListenIrp.ConnectionCallInfo ) {
+    if( FCB->ListenIrp.ConnectionCallInfo )
+    {
         ExFreePool( FCB->ListenIrp.ConnectionCallInfo );
         FCB->ListenIrp.ConnectionCallInfo = NULL;
     }
 
-    if( FCB->ListenIrp.ConnectionReturnInfo ) {
+    if( FCB->ListenIrp.ConnectionReturnInfo )
+    {
         ExFreePool( FCB->ListenIrp.ConnectionReturnInfo );
         FCB->ListenIrp.ConnectionReturnInfo = NULL;
     }
@@ -191,11 +225,13 @@ static NTSTATUS NTAPI ListenComplete
     FCB->NeedsNewListen = TRUE;
 
     /* Trigger a select return if appropriate */
-    if( !IsListEmpty( &FCB->PendingConnections ) ) {
-       FCB->PollState |= AFD_EVENT_ACCEPT;
+    if( !IsListEmpty( &FCB->PendingConnections ) )
+    {
+           FCB->PollState |= AFD_EVENT_ACCEPT;
         FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
         PollReeval( FCB->DeviceExt, FCB->FileObject );
-    } else
+    }
+    else
         FCB->PollState &= ~AFD_EVENT_ACCEPT;
 
     SocketStateUnlock( FCB );
@@ -204,44 +240,50 @@ static NTSTATUS NTAPI ListenComplete
 }
 
 NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
-                        PIO_STACK_LOCATION IrpSp) {
+                        PIO_STACK_LOCATION IrpSp)
+{
     NTSTATUS Status = STATUS_SUCCESS;
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_LISTEN_DATA ListenReq;
 
     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
+    DbgPrint("[AfdListenSocket] Called on %x\n", FCB);
 
-    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+    if( !SocketAcquireStateLock( FCB ) )
+        return LostSocket( Irp );
 
     if( !(ListenReq = LockRequest( Irp, IrpSp )) )
-       return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp,
-                                      0 );
+           return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
 
-    if( FCB->State != SOCKET_STATE_BOUND ) {
-       Status = STATUS_INVALID_PARAMETER;
-       AFD_DbgPrint(MID_TRACE,("Could not listen an unbound socket\n"));
-       return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
+    if( FCB->State != SOCKET_STATE_BOUND )
+    {
+           Status = STATUS_INVALID_PARAMETER;
+           AFD_DbgPrint(MID_TRACE,("Could not listen an unbound socket\n"));
+        DbgPrint("[AfdListenSocket] Could not listen an unbound socket\n");
+           return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
     }
 
     FCB->DelayedAccept = ListenReq->UseDelayedAcceptance;
 
     AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle));
+    DbgPrint("[AfdListenSocket] ADDRESSFILE: %x\n", FCB->AddressFile.Handle);
 
     Status = WarmSocketForConnection( FCB );
 
     AFD_DbgPrint(MID_TRACE,("Status from warmsocket %x\n", Status));
+    DbgPrint("[AfdListenSocket] Status from warmsocket %x\n", Status);
 
-    if( !NT_SUCCESS(Status) ) return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
+    if ( !NT_SUCCESS(Status) )
+        return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 
-    Status = TdiBuildNullConnectionInfo
-       ( &FCB->ListenIrp.ConnectionCallInfo,
+    Status = TdiBuildNullConnectionInfo(&FCB->ListenIrp.ConnectionCallInfo,
          FCB->LocalAddress->Address[0].AddressType );
 
-    if (!NT_SUCCESS(Status)) return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
+    if (!NT_SUCCESS(Status))
+        return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
 
-    Status = TdiBuildNullConnectionInfo
-       ( &FCB->ListenIrp.ConnectionReturnInfo,
+    Status = TdiBuildNullConnectionInfo(&FCB->ListenIrp.ConnectionReturnInfo,
          FCB->LocalAddress->Address[0].AddressType );
 
     if (!NT_SUCCESS(Status))
@@ -261,56 +303,67 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                        ListenComplete,
                        FCB );
 
-    if( Status == STATUS_PENDING )
-       Status = STATUS_SUCCESS;
+    if (Status == STATUS_PENDING)
+           Status = STATUS_SUCCESS;
 
     if (NT_SUCCESS(Status))
         FCB->NeedsNewListen = FALSE;
 
     AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+    DbgPrint("[AfdListenSocket] Returning %x\n", Status);
+    
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 }
 
 NTSTATUS AfdWaitForListen( PDEVICE_OBJECT DeviceObject, PIRP Irp,
-                          PIO_STACK_LOCATION IrpSp ) {
+                          PIO_STACK_LOCATION IrpSp )
+{
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
     NTSTATUS Status;
 
     AFD_DbgPrint(MID_TRACE,("Called\n"));
 
-    if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
+    if( !SocketAcquireStateLock( FCB ) )
+        return LostSocket( Irp );
 
-    if( !IsListEmpty( &FCB->PendingConnections ) ) {
-       PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
+    if( !IsListEmpty( &FCB->PendingConnections ) )
+    {
+           PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink;
 
-       /* We have a pending connection ... complete this irp right away */
-       Status = SatisfyPreAccept
-           ( Irp,
-             CONTAINING_RECORD
-             ( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry ) );
+           /* We have a pending connection ... complete this irp right away */
+           Status = SatisfyPreAccept
+               ( Irp,
+                 CONTAINING_RECORD
+                 ( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry ) );
 
-       AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
+           AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
+        DbgPrint("[AfdWaitForListen] Completed a wait for accept\n");
 
         if ( !IsListEmpty( &FCB->PendingConnections ) )
         {
-             FCB->PollState |= AFD_EVENT_ACCEPT;
-             FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
-             PollReeval( FCB->DeviceExt, FCB->FileObject );
-        } else
-             FCB->PollState &= ~AFD_EVENT_ACCEPT;
-
-       SocketStateUnlock( FCB );
-       return Status;
-    } else {
-       AFD_DbgPrint(MID_TRACE,("Holding\n"));
-
-       return LeaveIrpUntilLater( FCB, Irp, FUNCTION_PREACCEPT );
+                FCB->PollState |= AFD_EVENT_ACCEPT;
+                FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
+                PollReeval( FCB->DeviceExt, FCB->FileObject );
+        }
+        else
+            FCB->PollState &= ~AFD_EVENT_ACCEPT;
+
+           SocketStateUnlock( FCB );
+           return Status;
+    }
+    else
+    {
+           AFD_DbgPrint(MID_TRACE,("Holding\n"));
+        DbgPrint("[AfdWaitForListen] Holding\n");
+
+           return LeaveIrpUntilLater( FCB, Irp, FUNCTION_PREACCEPT );
     }
 }
 
 NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
-                   PIO_STACK_LOCATION IrpSp ) {
+                   PIO_STACK_LOCATION IrpSp )
+{
     NTSTATUS Status = STATUS_SUCCESS;
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_DEVICE_EXTENSION DeviceExt =
@@ -320,40 +373,45 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
     PLIST_ENTRY PendingConn;
 
     AFD_DbgPrint(MID_TRACE,("Called\n"));
+    DbgPrint("[AfdAccept] Called\n");
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
 
-    if( FCB->NeedsNewListen ) {
-       AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle));
-
-       /* Launch new accept socket */
-       Status = WarmSocketForConnection( FCB );
-
-       if( Status == STATUS_SUCCESS ) {
-            Status = TdiBuildNullConnectionInfo
-               ( &FCB->ListenIrp.ConnectionCallInfo,
-                 FCB->LocalAddress->Address[0].AddressType );
-
-           if (!NT_SUCCESS(Status)) return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
-
-           Status = TdiBuildNullConnectionInfo
-               ( &FCB->ListenIrp.ConnectionReturnInfo,
-                 FCB->LocalAddress->Address[0].AddressType );
+    if( FCB->NeedsNewListen )
+    {
+           AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle));
+        DbgPrint("[AfdAccept] ADDRESSFILE: %x\n", FCB->AddressFile.Handle);
 
-           if (!NT_SUCCESS(Status))
-           {
-               ExFreePool(FCB->ListenIrp.ConnectionCallInfo);
-               FCB->ListenIrp.ConnectionCallInfo = NULL;
-               return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
-           }
+           /* Launch new accept socket */
+           Status = WarmSocketForConnection( FCB );
 
-           Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
-                               FCB->Connection.Object,
-                               &FCB->ListenIrp.ConnectionCallInfo,
-                               &FCB->ListenIrp.ConnectionReturnInfo,
-                               &FCB->ListenIrp.Iosb,
-                               ListenComplete,
-                               FCB );
+           if( Status == STATUS_SUCCESS )
+        {
+                Status = TdiBuildNullConnectionInfo
+                   ( &FCB->ListenIrp.ConnectionCallInfo,
+                     FCB->LocalAddress->Address[0].AddressType );
+
+               if (!NT_SUCCESS(Status))
+                return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
+
+               Status = TdiBuildNullConnectionInfo
+                   ( &FCB->ListenIrp.ConnectionReturnInfo,
+                     FCB->LocalAddress->Address[0].AddressType );
+
+               if (!NT_SUCCESS(Status))
+               {
+                   ExFreePool(FCB->ListenIrp.ConnectionCallInfo);
+                   FCB->ListenIrp.ConnectionCallInfo = NULL;
+                   return UnlockAndMaybeComplete(FCB, Status, Irp, 0);
+               }
+
+               Status = TdiListen( &FCB->ListenIrp.InFlightRequest,
+                                   FCB->Connection.Object,
+                                   &FCB->ListenIrp.ConnectionCallInfo,
+                                   &FCB->ListenIrp.ConnectionReturnInfo,
+                                   &FCB->ListenIrp.Iosb,
+                                   ListenComplete,
+                                   FCB );
 
             if( Status == STATUS_PENDING )
                 Status = STATUS_SUCCESS;
@@ -361,58 +419,70 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp,
             if( !NT_SUCCESS(Status) )
                 return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 
-           FCB->NeedsNewListen = FALSE;
-       } else return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
+               FCB->NeedsNewListen = FALSE;
+           }
+        else
+            return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
     }
 
     for( PendingConn = FCB->PendingConnections.Flink;
-        PendingConn != &FCB->PendingConnections;
-        PendingConn = PendingConn->Flink ) {
-       PAFD_TDI_OBJECT_QELT PendingConnObj =
-           CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry );
+            PendingConn != &FCB->PendingConnections;
+            PendingConn = PendingConn->Flink )
+    {
+           PAFD_TDI_OBJECT_QELT PendingConnObj =
+               CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry );
 
-       AFD_DbgPrint(MID_TRACE,("Comparing Seq %d to Q %d\n",
-                               AcceptData->SequenceNumber,
-                               PendingConnObj->Seq));
+           AFD_DbgPrint(MID_TRACE,("Comparing Seq %d to Q %d\n",
+                                   AcceptData->SequenceNumber,
+                                   PendingConnObj->Seq));
+        DbgPrint("[AfdAccept] Comparing Seq %d to Q %d\n",
+                                   AcceptData->SequenceNumber,
+                                   PendingConnObj->Seq);
 
-       if( PendingConnObj->Seq == AcceptData->SequenceNumber ) {
-           PFILE_OBJECT NewFileObject = NULL;
+           if( PendingConnObj->Seq == AcceptData->SequenceNumber )
+        {
+               PFILE_OBJECT NewFileObject = NULL;
 
-           RemoveEntryList( PendingConn );
+               RemoveEntryList( PendingConn );
 
-           Status = ObReferenceObjectByHandle
-               ( AcceptData->ListenHandle,
-                 FILE_ALL_ACCESS,
-                 NULL,
-                 KernelMode,
-                 (PVOID *)&NewFileObject,
-                 NULL );
+               Status = ObReferenceObjectByHandle( AcceptData->ListenHandle,
+                                 FILE_ALL_ACCESS,
+                                 NULL,
+                                 KernelMode,
+                                 (PVOID *)&NewFileObject,
+                                 NULL );
 
-            if( !NT_SUCCESS(Status) ) return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
+            if( !NT_SUCCESS(Status) )
+                return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
 
             ASSERT(NewFileObject != FileObject);
             ASSERT(NewFileObject->FsContext != FCB);
 
-           /* We have a pending connection ... complete this irp right away */
-           Status = SatisfyAccept( DeviceExt, Irp, NewFileObject, PendingConnObj );
+               /* We have a pending connection ... complete this irp right away */
+               Status = SatisfyAccept( DeviceExt, Irp, NewFileObject, PendingConnObj );
 
-           ObDereferenceObject( NewFileObject );
+               ObDereferenceObject( NewFileObject );
 
-           AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
+               AFD_DbgPrint(MID_TRACE,("Completed a wait for accept\n"));
+            DbgPrint("[AfdAccept] Completed a wait for accept\n");
 
-           ExFreePool( PendingConnObj );
+               ExFreePool( PendingConnObj );
 
-           if( !IsListEmpty( &FCB->PendingConnections ) ) {
-               FCB->PollState |= AFD_EVENT_ACCEPT;
+               if( !IsListEmpty( &FCB->PendingConnections ) )
+            {
+                       FCB->PollState |= AFD_EVENT_ACCEPT;
                 FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS;
-               PollReeval( FCB->DeviceExt, FCB->FileObject );
-            } else
+                   PollReeval( FCB->DeviceExt, FCB->FileObject );
+            }
+            else
                 FCB->PollState &= ~AFD_EVENT_ACCEPT;
 
-           SocketStateUnlock( FCB );
-           return Status;
-       }
+               SocketStateUnlock( FCB );
+               return Status;
+           }
     }
 
+    DbgPrint("[AfdAccept] Done");
+
     return UnlockAndMaybeComplete( FCB, STATUS_UNSUCCESSFUL, Irp, 0 );
 }
index 03598f0..5755332 100644 (file)
@@ -25,13 +25,17 @@ DWORD DebugTraceLevel = 0;
 
 #endif /* DBG */
 
-void OskitDumpBuffer( PCHAR Data, UINT Len ) {
+void OskitDumpBuffer( PCHAR Data, UINT Len )
+{
     unsigned int i;
 
-    for( i = 0; i < Len; i++ ) {
-       if( i && !(i & 0xf) ) DbgPrint( "\n" );
-       if( !(i & 0xf) ) DbgPrint( "%08x: ", (UINT)(Data + i) );
-       DbgPrint( " %02x", Data[i] & 0xff );
+    for( i = 0; i < Len; i++ )
+    {
+           if( i && !(i & 0xf) )
+            DbgPrint( "\n" );
+           if( !(i & 0xf) )
+            DbgPrint( "%08x: ", (UINT)(Data + i) );
+           DbgPrint( " %02x", Data[i] & 0xff );
     }
     DbgPrint("\n");
 }
@@ -239,7 +243,8 @@ AfdGetTdiHandles(PDEVICE_OBJECT DeviceObject, PIRP Irp,
 
 static NTSTATUS NTAPI
 AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
-               PIO_STACK_LOCATION IrpSp) {
+               PIO_STACK_LOCATION IrpSp)
+{
     PAFD_FCB FCB;
     PFILE_OBJECT FileObject;
     PAFD_DEVICE_EXTENSION DeviceExt;
@@ -253,6 +258,8 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     AFD_DbgPrint(MID_TRACE,
                 ("AfdCreate(DeviceObject %p Irp %p)\n", DeviceObject, Irp));
 
+    DbgPrint("[AfdCreate] Created socket\n");
+
     DeviceExt = DeviceObject->DeviceExtension;
     FileObject = IrpSp->FileObject;
     Disposition = (IrpSp->Parameters.Create.Options >> 24) & 0xff;
@@ -261,25 +268,27 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
 
     EaInfo = Irp->AssociatedIrp.SystemBuffer;
 
-    if( EaInfo ) {
-       ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1);
-       EaInfoValue = (PWCHAR)(((PCHAR)ConnectInfo) + sizeof(AFD_CREATE_PACKET));
+    if( EaInfo )
+    {
+           ConnectInfo = (PAFD_CREATE_PACKET)(EaInfo->EaName + EaInfo->EaNameLength + 1);
+           EaInfoValue = (PWCHAR)(((PCHAR)ConnectInfo) + sizeof(AFD_CREATE_PACKET));
 
-       EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
-           EaInfo->EaNameLength +
-           EaInfo->EaValueLength;
+           EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
+               EaInfo->EaNameLength +
+               EaInfo->EaValueLength;
 
-       AFD_DbgPrint(MID_TRACE,("EaInfo: %x, EaInfoValue: %x\n",
-                               EaInfo, EaInfoValue));
+           AFD_DbgPrint(MID_TRACE,("EaInfo: %x, EaInfoValue: %x\n",
+                                   EaInfo, EaInfoValue));
     }
 
     AFD_DbgPrint(MID_TRACE,("About to allocate the new FCB\n"));
 
     FCB = ExAllocatePool(NonPagedPool, sizeof(AFD_FCB));
-    if( FCB == NULL ) {
-       Irp->IoStatus.Status = STATUS_NO_MEMORY;
-       IoCompleteRequest(Irp, IO_NO_INCREMENT);
-       return STATUS_NO_MEMORY;
+    if( FCB == NULL )
+    {
+           Irp->IoStatus.Status = STATUS_NO_MEMORY;
+           IoCompleteRequest(Irp, IO_NO_INCREMENT);
+           return STATUS_NO_MEMORY;
     }
 
     AFD_DbgPrint(MID_TRACE,("Initializing the new FCB @ %x (FileObject %x Flags %x)\n", FCB, FileObject, ConnectInfo ? ConnectInfo->EndpointFlags : 0));
@@ -297,8 +306,9 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
 
     KeInitializeMutex( &FCB->Mutex, 0 );
 
-    for( i = 0; i < MAX_FUNCTIONS; i++ ) {
-       InitializeListHead( &FCB->PendingIrpList[i] );
+    for( i = 0; i < MAX_FUNCTIONS; i++ )
+    {
+           InitializeListHead( &FCB->PendingIrpList[i] );
     }
 
     InitializeListHead( &FCB->DatagramList );
@@ -306,46 +316,53 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
 
     AFD_DbgPrint(MID_TRACE,("%x: Checking command channel\n", FCB));
 
-    if( ConnectInfo ) {
-       FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName;
-       FCB->TdiDeviceName.MaximumLength = FCB->TdiDeviceName.Length;
-       FCB->TdiDeviceName.Buffer =
-           ExAllocatePool( NonPagedPool, FCB->TdiDeviceName.Length );
-
-       if( !FCB->TdiDeviceName.Buffer ) {
-           ExFreePool(FCB);
-           AFD_DbgPrint(MID_TRACE,("Could not copy target string\n"));
-           Irp->IoStatus.Status = STATUS_NO_MEMORY;
-           IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
-           return STATUS_NO_MEMORY;
-       }
-
-       RtlCopyMemory( FCB->TdiDeviceName.Buffer,
-                      ConnectInfo->TransportName,
-                      FCB->TdiDeviceName.Length );
+    if( ConnectInfo )
+    {
+           FCB->TdiDeviceName.Length = ConnectInfo->SizeOfTransportName;
+           FCB->TdiDeviceName.MaximumLength = FCB->TdiDeviceName.Length;
+           FCB->TdiDeviceName.Buffer =
+               ExAllocatePool( NonPagedPool, FCB->TdiDeviceName.Length );
 
-       AFD_DbgPrint(MID_TRACE,("Success: %s %wZ\n",
-                               EaInfo->EaName, &FCB->TdiDeviceName));
-    } else {
-       AFD_DbgPrint(MID_TRACE,("Success: Control connection\n"));
+           if( !FCB->TdiDeviceName.Buffer )
+        {
+               ExFreePool(FCB);
+               AFD_DbgPrint(MID_TRACE,("Could not copy target string\n"));
+               Irp->IoStatus.Status = STATUS_NO_MEMORY;
+               IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+               return STATUS_NO_MEMORY;
+           }
+
+           RtlCopyMemory( FCB->TdiDeviceName.Buffer,
+                          ConnectInfo->TransportName,
+                          FCB->TdiDeviceName.Length );
+
+           AFD_DbgPrint(MID_TRACE,("Success: %s %wZ\n",
+                                   EaInfo->EaName, &FCB->TdiDeviceName));
+    }
+    else
+    {
+           AFD_DbgPrint(MID_TRACE,("Success: Control connection\n"));
     }
 
     FileObject->FsContext = FCB;
 
     /* It seems that UDP sockets are writable from inception */
-    if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) {
+    if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS )
+    {
         AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
         
-       /* A datagram socket is always sendable */
-       FCB->PollState |= AFD_EVENT_SEND;
-        FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
-        PollReeval( FCB->DeviceExt, FCB->FileObject );
+           /* A datagram socket is always sendable */
+           FCB->PollState |= AFD_EVENT_SEND;
+            FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
+            PollReeval( FCB->DeviceExt, FCB->FileObject );
     }
 
-    if( !NT_SUCCESS(Status) ) {
-       if( FCB->TdiDeviceName.Buffer ) ExFreePool( FCB->TdiDeviceName.Buffer );
-       ExFreePool( FCB );
-       FileObject->FsContext = NULL;
+    if( !NT_SUCCESS(Status) )
+    {
+           if( FCB->TdiDeviceName.Buffer )
+            ExFreePool( FCB->TdiDeviceName.Buffer );
+           ExFreePool( FCB );
+           FileObject->FsContext = NULL;
     }
 
     Irp->IoStatus.Status = Status;
@@ -411,12 +428,14 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     InFlightRequest[3] = &FCB->ConnectIrp;
 
     /* Cancel our pending requests */
-    for( i = 0; i < IN_FLIGHT_REQUESTS; i++ ) {
-       if( InFlightRequest[i]->InFlightRequest ) {
-           AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n",
-                                   i, InFlightRequest[i]->InFlightRequest));
+    for( i = 0; i < IN_FLIGHT_REQUESTS; i++ )
+    {
+           if( InFlightRequest[i]->InFlightRequest )
+        {
+               AFD_DbgPrint(MID_TRACE,("Cancelling in flight irp %d (%x)\n",
+                                       i, InFlightRequest[i]->InFlightRequest));
             IoCancelIrp(InFlightRequest[i]->InFlightRequest);
-       }
+           }
     }
 
     KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE );
@@ -430,13 +449,13 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
         ExFreePool( FCB->Context );
 
     if( FCB->Recv.Window )
-       ExFreePool( FCB->Recv.Window );
+           ExFreePool( FCB->Recv.Window );
 
     if( FCB->Send.Window )
-       ExFreePool( FCB->Send.Window );
+           ExFreePool( FCB->Send.Window );
 
     if( FCB->AddressFrom )
-       ExFreePool( FCB->AddressFrom );
+           ExFreePool( FCB->AddressFrom );
 
     if( FCB->ConnectInfo )
         ExFreePool( FCB->ConnectInfo );
@@ -454,22 +473,22 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
         ExFreePool( FCB->DisconnectOptions );
 
     if( FCB->LocalAddress )
-       ExFreePool( FCB->LocalAddress );
+           ExFreePool( FCB->LocalAddress );
 
     if( FCB->RemoteAddress )
-       ExFreePool( FCB->RemoteAddress );
+           ExFreePool( FCB->RemoteAddress );
 
     if( FCB->Connection.Object )
-       ObDereferenceObject(FCB->Connection.Object);
+           ObDereferenceObject(FCB->Connection.Object);
 
     if( FCB->AddressFile.Object )
-       ObDereferenceObject(FCB->AddressFile.Object);
+           ObDereferenceObject(FCB->AddressFile.Object);
 
     if( FCB->AddressFile.Handle != INVALID_HANDLE_VALUE )
     {
         if (ZwClose(FCB->AddressFile.Handle) == STATUS_INVALID_HANDLE)
         {
-            DbgPrint("INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB->AddressFile.Handle, FCB->AddressFile.Object);
+            DbgPrint("[AfdCloseSocket] INVALID ADDRESS FILE HANDLE VALUE: %x %x\n", FCB->AddressFile.Handle, FCB->AddressFile.Object);
         }
     }
 
@@ -477,12 +496,12 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
     {
         if (ZwClose(FCB->Connection.Handle) == STATUS_INVALID_HANDLE)
         {
-            DbgPrint("INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB->Connection.Handle, FCB->Connection.Object);
+            DbgPrint("[AfdCloseSocket] INVALID CONNECTION HANDLE VALUE: %x %x\n", FCB->Connection.Handle, FCB->Connection.Object);
         }
     }
 
     if( FCB->TdiDeviceName.Buffer )
-       ExFreePool(FCB->TdiDeviceName.Buffer);
+           ExFreePool(FCB->TdiDeviceName.Buffer);
 
     ExFreePool(FCB);
 
@@ -497,7 +516,8 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
 
 static NTSTATUS NTAPI
 AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
-             PIO_STACK_LOCATION IrpSp) {
+             PIO_STACK_LOCATION IrpSp)
+{
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_DISCONNECT_INFO DisReq;
@@ -547,7 +567,8 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
                                FCB->ConnectInfo,
                                ConnectionReturnInfo);
 
-        if (NT_SUCCESS(Status)) {
+        if (NT_SUCCESS(Status))
+        {
             FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, ConnectionReturnInfo->UserDataLength);
             if (FCB->FilledDisconnectData)
             {
@@ -570,7 +591,8 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
         FCB->PollState |= AFD_EVENT_DISCONNECT;
         FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS;
         PollReeval( FCB->DeviceExt, FCB->FileObject );
-    } else
+    }
+    else
         Status = STATUS_INVALID_PARAMETER;
 
     return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
index b6821b0..fb78fb6 100644 (file)
@@ -128,21 +128,27 @@ static NTSTATUS TdiOpenDevice(
                           0,                                    /* Create options */
                           EaInfo,                               /* EA buffer */
                           EaLength);                            /* EA length */
-    if (NT_SUCCESS(Status)) {
+    if (NT_SUCCESS(Status))
+    {
         Status = ObReferenceObjectByHandle(*Handle,                       /* Handle to open file */
                                            GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,  /* Access mode */
                                            IoFileObjectType,              /* Object type */
                                            KernelMode,                    /* Access mode */
                                            (PVOID*)Object,                /* Pointer to object */
                                            NULL);                         /* Handle information */
-        if (!NT_SUCCESS(Status)) {
+        if (!NT_SUCCESS(Status))
+        {
                        AFD_DbgPrint(MIN_TRACE, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status));
                        ZwClose(*Handle);
-        } else {
+        }
+        else
+        {
                        AFD_DbgPrint(MAX_TRACE, ("Got handle (0x%X)  Object (0x%X)\n",
                                                                         *Handle, *Object));
         }
-    } else {
+    }
+    else
+    {
         AFD_DbgPrint(MIN_TRACE, ("ZwCreateFile() failed with status (0x%X)\n", Status));
     }
 
@@ -329,14 +335,16 @@ NTSTATUS TdiConnect(
 
        AFD_DbgPrint(MAX_TRACE, ("Called\n"));
 
-       if (!ConnectionObject) {
+       if (!ConnectionObject)
+    {
                AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
                *Irp = NULL;
                return STATUS_INVALID_PARAMETER;
        }
 
        DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-       if (!DeviceObject) {
+       if (!DeviceObject)
+    {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
         *Irp = NULL;
         return STATUS_INVALID_PARAMETER;
@@ -387,13 +395,15 @@ NTSTATUS TdiAssociateAddressFile(
        AFD_DbgPrint(MAX_TRACE, ("Called. AddressHandle (0x%X)  ConnectionObject (0x%X)\n",
                                                         AddressHandle, ConnectionObject));
 
-       if (!ConnectionObject) {
+       if (!ConnectionObject)
+    {
                AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
                return STATUS_INVALID_PARAMETER;
        }
 
        DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-       if (!DeviceObject) {
+       if (!DeviceObject)
+    {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
         return STATUS_INVALID_PARAMETER;
        }
@@ -442,16 +452,19 @@ NTSTATUS TdiListen
        PDEVICE_OBJECT DeviceObject;
        NTSTATUS Status;
 
-       AFD_DbgPrint(MAX_TRACE, ("Called\n"));
+       AFD_DbgPrint(MAX_TRACE, ("[AFD, TDIListen] Called\n"));
+    DbgPrint("[AFD, TDIListen] Called\n");
 
-       if (!ConnectionObject) {
+       if (!ConnectionObject)
+    {
                AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n"));
                *Irp = NULL;
                return STATUS_INVALID_PARAMETER;
        }
 
        DeviceObject = IoGetRelatedDeviceObject(ConnectionObject);
-       if (!DeviceObject) {
+       if (!DeviceObject)
+    {
         AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
         *Irp = NULL;
         return STATUS_INVALID_PARAMETER;
@@ -476,6 +489,8 @@ NTSTATUS TdiListen
 
        Status = TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb);
 
+    DbgPrint("[AFD, TDIListen] Done. Status = 0x%x\n", Status);
+
        return Status;
 }
 
index e86a0d7..30ec321 100644 (file)
@@ -1,7 +1,8 @@
 
 include_directories(
     BEFORE include
-    ${REACTOS_SOURCE_DIR}/lib/drivers/oskittcp/include)
+    ${REACTOS_SOURCE_DIR}/lib/drivers/lwip/src/include
+    ${REACTOS_SOURCE_DIR}/lib/drivers/lwip/src/include/ipv4)
 
 add_definitions(
     -DNDIS40
@@ -30,7 +31,7 @@ add_library(tcpip SHARED ${CMAKE_CURRENT_BINARY_DIR}/tcpip_precomp.h.gch ${SOURC
 
 target_link_libraries(tcpip
     ip
-    oskittcp
+    lwip
     ${PSEH_LIB}
     chew)
 
index 303d66a..0e3e409 100644 (file)
 #define DEBUG_INFO     0x02000000
 #define DEBUG_ULTRA    0x7FFFFFFF
 
+#define DBG 1
+
 #if DBG
 
 #define REMOVE_PARENS(...) __VA_ARGS__
 #define TI_DbgPrint(_t_, _x_) \
     DbgPrintEx(DPFLTR_TCPIP_ID, (_t_) | DPFLTR_MASK, "(%s:%d) ", __FILE__, __LINE__), \
     DbgPrintEx(DPFLTR_TCPIP_ID, (_t_) | DPFLTR_MASK, REMOVE_PARENS _x_)
-
+    //DbgPrint(REMOVE_PARENS _x_)
 #else /* DBG */
 
 #define TI_DbgPrint(_t_, _x_)
index f37046d..124df67 100644 (file)
@@ -29,7 +29,6 @@
 #include <fileobjs.h>
 #include <lock.h>
 #include <wait.h>
-#include <oskittcp.h>
 #include <interface.h>
 #include <ports.h>
 #include <ipifcons.h>
index 637900a..8724d16 100644 (file)
@@ -24,15 +24,6 @@ typedef struct TCPv4_HEADER {
   USHORT Urgent;            /* Pointer to urgent data */
 } TCPv4_HEADER, *PTCPv4_HEADER;
 
-/* TCPv4 header flags */
-#define TCP_URG   0x20
-#define TCP_ACK   0x10
-#define TCP_PSH   0x08
-#define TCP_RST   0x04
-#define TCP_SYN   0x02
-#define TCP_FIN   0x01
-
-
 #define TCPOPT_END_OF_LIST  0x0
 #define TCPOPT_NO_OPERATION 0x1
 #define TCPOPT_MAX_SEG_SIZE 0x2
@@ -79,6 +70,19 @@ typedef struct _CLIENT_DATA {
 /* Delay variance factor */
 #define TCP_BETA_RETRANSMISSION_TIMEOUT(x)(((x)*16)/10)   /* 1.6 */
 
+#define SEL_CONNECT 1
+#define SEL_FIN     2
+#define SEL_RST     4
+#define SEL_ABRT    8
+#define SEL_READ    16
+#define SEL_WRITE   32
+#define SEL_ACCEPT  64
+#define SEL_OOB     128
+#define SEL_ERROR   256
+#define SEL_FINOUT  512
+
+#define        FREAD           0x0001
+#define        FWRITE          0x0002
 
 /* Datagram/segment send request flags */
 
@@ -93,9 +97,8 @@ extern LONG TCP_IPIdentification;
 extern CLIENT_DATA ClientInfo;
 
 /* accept.c */
-NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
-                                   PCONNECTION_ENDPOINT Connection,
-                                   PTDI_REQUEST_KERNEL Request );
+NTSTATUS TCPCheckPeerForAccept(PVOID Context,
+                               PTDI_REQUEST_KERNEL Request);
 NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog );
 BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
                                 PCONNECTION_ENDPOINT Connection );
@@ -163,7 +166,7 @@ NTSTATUS TCPSendData(
 
 NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection );
 
-NTSTATUS TCPTranslateError( int OskitError );
+NTSTATUS TCPTranslateError( INT8 err );
 
 UINT TCPAllocatePort( UINT HintPort );
 
@@ -181,3 +184,12 @@ NTSTATUS TCPShutdown(
   VOID);
 
 BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp );
+
+VOID
+TCPUpdateInterfaceLinkStatus(PIP_INTERFACE IF);
+
+VOID
+TCPUpdateInterfaceIPInformation(PIP_INTERFACE IF);
+
+VOID
+FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status);
index 563e662..9b07784 100644 (file)
@@ -135,19 +135,9 @@ struct in_addr
 #define s_impno S_un.S_un_b.s_b4
 #define s_lh    S_un.S_un_b.s_b3
 };
-struct sockaddr_in
-{
-    short sin_family;
-    u_short sin_port;
-    struct in_addr sin_addr;
-    char sin_zero[8];
-};
-typedef struct sockaddr_in SOCKADDR_IN;
-struct sockaddr
-{
-    u_short sa_family;
-    char sa_data[14];
-};
+
+#define __LWIP_INET_H__
+#include "lwip/sockets.h"
 
 /* Sufficient information to manage the entity list */
 typedef struct {
index 5400010..cb48cb4 100644 (file)
@@ -13,6 +13,7 @@
  */
 #define ReferenceObject(Object)                            \
 {                                                          \
+    ASSERT(((Object)->RefCount) > 0);                      \
     InterlockedIncrement(&((Object)->RefCount));           \
 }
 
@@ -22,6 +23,7 @@
  */
 #define DereferenceObject(Object)                           \
 {                                                           \
+    ASSERT(((Object)->RefCount) > 0);                       \
     if (InterlockedDecrement(&((Object)->RefCount)) == 0)   \
         (((Object)->Free)(Object));                         \
 }
@@ -33,7 +35,7 @@
 {                                                        \
     ReferenceObject(Object);                             \
     KeAcquireSpinLock(&((Object)->Lock), Irql);          \
-    memcpy(&(Object)->OldIrql, Irql, sizeof(KIRQL));     \
+    (Object)->OldIrql = *Irql;                           \
 }
 
 /*
@@ -266,10 +268,6 @@ typedef struct _CONNECTION_ENDPOINT {
     LIST_ENTRY ListenRequest;  /* Queued listen requests */
     LIST_ENTRY ReceiveRequest; /* Queued receive requests */
     LIST_ENTRY SendRequest;    /* Queued send requests */
-    LIST_ENTRY CompletionQueue;/* Completed requests to finish */
-
-    /* Signals */
-    UINT    SignalState;       /* Active signals from oskit */
 } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
 
 
index f216ed5..38a5049 100644 (file)
 #include <pseh/pseh2.h>
 
 
-NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
+NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status )
+{
     KIRQL OldIrql;
 
     Irp->IoStatus.Status = Status;
 
-    if( Status == STATUS_PENDING )
-       IoMarkIrpPending( Irp );
-    else {
+    if (Status == STATUS_PENDING)
+           IoMarkIrpPending( Irp );
+    else
+    {
         IoAcquireCancelSpinLock(&OldIrql);
-       (void)IoSetCancelRoutine( Irp, NULL );
+           (void)IoSetCancelRoutine( Irp, NULL );
         IoReleaseCancelSpinLock(OldIrql);
 
-       IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+           IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
     }
 
     return Status;
@@ -56,7 +58,8 @@ NTSTATUS DispPrepareIrpForCancel(
 
     IoAcquireCancelSpinLock(&OldIrql);
 
-    if (!Irp->Cancel && !TransContext->CancelIrps) {
+    if (!Irp->Cancel && !TransContext->CancelIrps)
+    {
         (void)IoSetCancelRoutine(Irp, CancelRoutine);
         IoReleaseCancelSpinLock(OldIrql);
 
@@ -144,38 +147,41 @@ VOID NTAPI DispCancelRequest(
 #endif
 
     /* Try canceling the request */
-    switch(MinorFunction) {
-    case TDI_SEND:
-    case TDI_RECEIVE:
-       DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
-        break;
-
-    case TDI_SEND_DATAGRAM:
-        if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
-            TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n"));
+    switch(MinorFunction)
+    {
+        case TDI_SEND:
+        case TDI_RECEIVE:
+           DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
             break;
-        }
 
-        DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
-        break;
+        case TDI_SEND_DATAGRAM:
+            if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE)
+            {
+                TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n"));
+                break;
+            }
 
-    case TDI_RECEIVE_DATAGRAM:
-        if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
-            TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
+            DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
             break;
-        }
 
-        DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
-        break;
+        case TDI_RECEIVE_DATAGRAM:
+            if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE)
+            {
+                TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n"));
+                break;
+            }
+
+            DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+            break;
 
-    case TDI_CONNECT:
-        DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
-        break;
+        case TDI_CONNECT:
+            DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
+            break;
 
-    default:
-        TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
-        ASSERT(FALSE);
-        break;
+        default:
+            TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
+            ASSERT(FALSE);
+            break;
     }
 
     if (DequeuedIrp)
@@ -256,99 +262,107 @@ NTSTATUS DispTdiAssociateAddress(
  *     Status of operation
  */
 {
-  PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
-  PTRANSPORT_CONTEXT TranContext;
-  PIO_STACK_LOCATION IrpSp;
-  PCONNECTION_ENDPOINT Connection;
-  PFILE_OBJECT FileObject;
-  PADDRESS_FILE AddrFile = NULL;
-  NTSTATUS Status;
-  KIRQL OldIrql;
+    PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
+    PTRANSPORT_CONTEXT TranContext;
+    PIO_STACK_LOCATION IrpSp;
+    PCONNECTION_ENDPOINT Connection;
+    PFILE_OBJECT FileObject;
+    PADDRESS_FILE AddrFile = NULL;
+    NTSTATUS Status;
+    KIRQL OldIrql;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+    TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiAssociateAddress] Called\n"));
 
-  IrpSp = IoGetCurrentIrpStackLocation(Irp);
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
-  /* Get associated connection endpoint file object. Quit if none exists */
+    /* Get associated connection endpoint file object. Quit if none exists */
 
-  TranContext = IrpSp->FileObject->FsContext;
-  if (!TranContext) {
-    TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
-    return STATUS_INVALID_PARAMETER;
-  }
+    TranContext = IrpSp->FileObject->FsContext;
+    if (!TranContext)
+    {
+        TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+        return STATUS_INVALID_PARAMETER;
+    }
 
-  Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
-  if (!Connection) {
-    TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
-    return STATUS_INVALID_PARAMETER;
-  }
+    Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+    if (!Connection)
+    {
+        TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
+        return STATUS_INVALID_PARAMETER;
+    }
 
-  Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;
-
-  Status = ObReferenceObjectByHandle(
-    Parameters->AddressHandle,
-    0,
-    IoFileObjectType,
-    KernelMode,
-    (PVOID*)&FileObject,
-    NULL);
-  if (!NT_SUCCESS(Status)) {
-    TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X): %x.\n",
-      Parameters->AddressHandle, Status));
-    return STATUS_INVALID_PARAMETER;
-  }
+    Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;
 
-  LockObject(Connection, &OldIrql);
+    Status = ObReferenceObjectByHandle(
+        Parameters->AddressHandle,
+        0,
+        IoFileObjectType,
+        KernelMode,
+        (PVOID*)&FileObject,
+        NULL);
 
-  if (Connection->AddressFile) {
-    ObDereferenceObject(FileObject);
-    UnlockObject(Connection, OldIrql);
-    TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
-    return STATUS_INVALID_PARAMETER;
-  }
+    if (!NT_SUCCESS(Status))
+    {
+        TI_DbgPrint(MID_TRACE, ("Bad address file object handle (0x%X): %x.\n",
+            Parameters->AddressHandle, Status));
+        return STATUS_INVALID_PARAMETER;
+    }
 
-  if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
-    ObDereferenceObject(FileObject);
-    UnlockObject(Connection, OldIrql);
-    TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
-      FileObject->FsContext2));
-    return STATUS_INVALID_PARAMETER;
-  }
+    LockObject(Connection, &OldIrql);
 
-  /* Get associated address file object. Quit if none exists */
+    if (Connection->AddressFile)
+    {
+        ObDereferenceObject(FileObject);
+        UnlockObject(Connection, OldIrql);
+        TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
+        return STATUS_INVALID_PARAMETER;
+    }
 
-  TranContext = FileObject->FsContext;
-  if (!TranContext) {
-    ObDereferenceObject(FileObject);
-    UnlockObject(Connection, OldIrql);
-    TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
-    return STATUS_INVALID_PARAMETER;
-  }
+    if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE)
+    {
+        ObDereferenceObject(FileObject);
+        UnlockObject(Connection, OldIrql);
+        TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
+            FileObject->FsContext2));
+        return STATUS_INVALID_PARAMETER;
+    }
 
-  AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
-  if (!AddrFile) {
-      UnlockObject(Connection, OldIrql);
-      ObDereferenceObject(FileObject);
-      TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
-      return STATUS_INVALID_PARAMETER;
-  }
+    /* Get associated address file object. Quit if none exists */
 
-  LockObjectAtDpcLevel(AddrFile);
+    TranContext = FileObject->FsContext;
+    if (!TranContext)
+    {
+        ObDereferenceObject(FileObject);
+        UnlockObject(Connection, OldIrql);
+        TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+        return STATUS_INVALID_PARAMETER;
+    }
 
-  ReferenceObject(AddrFile);
-  Connection->AddressFile = AddrFile;
+    AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
+    if (!AddrFile)
+    {
+        UnlockObject(Connection, OldIrql);
+        ObDereferenceObject(FileObject);
+        TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
+        return STATUS_INVALID_PARAMETER;
+    }
 
-  /* Add connection endpoint to the address file */
-  ReferenceObject(Connection);
-  AddrFile->Connection = Connection;
+    LockObjectAtDpcLevel(AddrFile);
 
-  /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
-  ObDereferenceObject(FileObject);
+    ReferenceObject(AddrFile);
+    Connection->AddressFile = AddrFile;
 
-  UnlockObjectFromDpcLevel(AddrFile);
-  UnlockObject(Connection, OldIrql);
+    /* Add connection endpoint to the address file */
+    ReferenceObject(Connection);
+    AddrFile->Connection = Connection;
 
-  return Status;
+    /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
+    ObDereferenceObject(FileObject);
+
+    UnlockObjectFromDpcLevel(AddrFile);
+    UnlockObject(Connection, OldIrql);
+
+    return Status;
 }
 
 
@@ -368,7 +382,7 @@ NTSTATUS DispTdiConnect(
   PIO_STACK_LOCATION IrpSp;
   NTSTATUS Status;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiConnect] Called\n"));
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
@@ -394,7 +408,8 @@ NTSTATUS DispTdiConnect(
                                    Irp,
                                    DispCancelRequest);
 
-  if (NT_SUCCESS(Status)) {
+  if (NT_SUCCESS(Status))
+  {
       Status = TCPConnect(
           TranContext->Handle.ConnectionContext,
           Parameters->RequestConnectionInformation,
@@ -409,7 +424,7 @@ done:
   } else
       IoMarkIrpPending(Irp);
 
-  TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DispTdiConnect] TCP Connect returned %08x\n", Status));
 
   return Status;
 }
@@ -490,7 +505,7 @@ NTSTATUS DispTdiDisconnect(
   PTRANSPORT_CONTEXT TranContext;
   PIO_STACK_LOCATION IrpSp;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiDisconnect] Called\n"));
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
   DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;
@@ -505,7 +520,8 @@ NTSTATUS DispTdiDisconnect(
   }
 
   Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
-  if (!Connection) {
+  if (!Connection)
+  {
     TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
     Status = STATUS_INVALID_PARAMETER;
     goto done;
@@ -525,7 +541,7 @@ done:
    } else
        IoMarkIrpPending(Irp);
 
-  TI_DbgPrint(MAX_TRACE, ("TCP Disconnect returned %08x\n", Status));
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DispTdiDisconnect] TCP Disconnect returned %08x\n", Status));
 
   return Status;
 }
@@ -541,103 +557,107 @@ NTSTATUS DispTdiListen(
  *     Status of operation
  */
 {
-  PCONNECTION_ENDPOINT Connection;
-  PTDI_REQUEST_KERNEL Parameters;
-  PTRANSPORT_CONTEXT TranContext;
-  PIO_STACK_LOCATION IrpSp;
-  NTSTATUS Status = STATUS_SUCCESS;
-  KIRQL OldIrql;
+    PCONNECTION_ENDPOINT Connection;
+    PTDI_REQUEST_KERNEL Parameters;
+    PTRANSPORT_CONTEXT TranContext;
+    PIO_STACK_LOCATION IrpSp;
+    NTSTATUS Status = STATUS_SUCCESS;
+    KIRQL OldIrql;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+    TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiListen] Called\n"));
+    DbgPrint("[TCPIP, DispTdiListen] Called\n");
 
-  IrpSp = IoGetCurrentIrpStackLocation(Irp);
+    IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
-  /* Get associated connection endpoint file object. Quit if none exists */
+    /* Get associated connection endpoint file object. Quit if none exists */
 
-  TranContext = IrpSp->FileObject->FsContext;
-  if (TranContext == NULL)
+    TranContext = IrpSp->FileObject->FsContext;
+    if (TranContext == NULL)
     {
-      TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
-      Status = STATUS_INVALID_PARAMETER;
-      goto done;
+        TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+        Status = STATUS_INVALID_PARAMETER;
+        goto done;
     }
 
-  Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
-  if (Connection == NULL)
+    Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
+    if (Connection == NULL)
     {
-      TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
-      Status = STATUS_INVALID_PARAMETER;
-      goto done;
+        TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
+        Status = STATUS_INVALID_PARAMETER;
+        goto done;
     }
 
-  Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
+    Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
 
-  Status = DispPrepareIrpForCancel
-      (TranContext->Handle.ConnectionContext,
-       Irp,
-       (PDRIVER_CANCEL)DispCancelListenRequest);
+    Status = DispPrepareIrpForCancel
+        (TranContext->Handle.ConnectionContext,
+        Irp,
+        (PDRIVER_CANCEL)DispCancelListenRequest);
 
-  LockObject(Connection, &OldIrql);
+    LockObject(Connection, &OldIrql);
 
-  if (Connection->AddressFile == NULL)
-  {
-     TI_DbgPrint(MID_TRACE, ("No associated address file\n"));
-     UnlockObject(Connection, OldIrql);
-     Status = STATUS_INVALID_PARAMETER;
-     goto done;
-  }
+    if (Connection->AddressFile == NULL)
+    {
+        TI_DbgPrint(MID_TRACE, ("No associated address file\n"));
+        UnlockObject(Connection, OldIrql);
+        Status = STATUS_INVALID_PARAMETER;
+        goto done;
+    }
 
-  LockObjectAtDpcLevel(Connection->AddressFile);
+    LockObjectAtDpcLevel(Connection->AddressFile);
 
-  /* Listening will require us to create a listening socket and store it in
-   * the address file.  It will be signalled, and attempt to complete an irp
-   * when a new connection arrives. */
-  /* The important thing to note here is that the irp we'll complete belongs
-   * to the socket to be accepted onto, not the listener */
-  if( NT_SUCCESS(Status) && !Connection->AddressFile->Listener ) {
-      Connection->AddressFile->Listener =
-         TCPAllocateConnectionEndpoint( NULL );
-
-      if( !Connection->AddressFile->Listener )
-         Status = STATUS_NO_MEMORY;
-
-      if( NT_SUCCESS(Status) ) {
-          ReferenceObject(Connection->AddressFile);
-         Connection->AddressFile->Listener->AddressFile =
-             Connection->AddressFile;
-
-         Status = TCPSocket( Connection->AddressFile->Listener,
-                             Connection->AddressFile->Family,
-                             SOCK_STREAM,
-                             Connection->AddressFile->Protocol );
-      }
+    /* Listening will require us to create a listening socket and store it in
+    * the address file.  It will be signalled, and attempt to complete an irp
+    * when a new connection arrives. */
+    /* The important thing to note here is that the irp we'll complete belongs
+    * to the socket to be accepted onto, not the listener */
+    if( NT_SUCCESS(Status) && !Connection->AddressFile->Listener )
+    {
+        Connection->AddressFile->Listener = TCPAllocateConnectionEndpoint( NULL );
 
-      if( NT_SUCCESS(Status) )
-         Status = TCPListen( Connection->AddressFile->Listener, 1024 );
-         /* BACKLOG */
-  }
+        if( !Connection->AddressFile->Listener )
+               Status = STATUS_NO_MEMORY;
 
-  if( NT_SUCCESS(Status) ) {
-      Status = TCPAccept
-         ( (PTDI_REQUEST)Parameters,
-           Connection->AddressFile->Listener,
-           Connection,
-           DispDataRequestComplete,
-           Irp );
-  }
+        if( NT_SUCCESS(Status) )
+        {
+            ReferenceObject(Connection->AddressFile);
+               Connection->AddressFile->Listener->AddressFile = Connection->AddressFile;
 
-  UnlockObjectFromDpcLevel(Connection->AddressFile);
-  UnlockObject(Connection, OldIrql);
+               Status = TCPSocket( Connection->AddressFile->Listener,
+                                   Connection->AddressFile->Family,
+                                   SOCK_STREAM,
+                                   Connection->AddressFile->Protocol );
+        }
+
+        if ( NT_SUCCESS(Status) )
+               Status = TCPListen( Connection->AddressFile->Listener, 1024 );
+           /* BACKLOG */
+    }
+
+    if (NT_SUCCESS(Status))
+    {
+        Status = TCPAccept( (PTDI_REQUEST)Parameters,
+               Connection->AddressFile->Listener,
+               Connection,
+               DispDataRequestComplete,
+               Irp );
+    }
+
+    UnlockObjectFromDpcLevel(Connection->AddressFile);
+    UnlockObject(Connection, OldIrql);
 
 done:
-  if (Status != STATUS_PENDING) {
-      DispDataRequestComplete(Irp, Status, 0);
-  } else
-      IoMarkIrpPending(Irp);
+    if (Status != STATUS_PENDING)
+    {
+        DispDataRequestComplete(Irp, Status, 0);
+    }
+    else
+        IoMarkIrpPending(Irp);
 
-  TI_DbgPrint(MID_TRACE,("Leaving %x\n", Status));
+    TI_DbgPrint(MID_TRACE,("[TCPIP, DispTdiListen] Leaving %x\n", Status));
+    DbgPrint("[TCPIP, DispTdiListen] Leaving %x\n", Status);
 
-  return Status;
+    return Status;
 }
 
 
@@ -657,7 +677,7 @@ NTSTATUS DispTdiQueryInformation(
   PTRANSPORT_CONTEXT TranContext;
   PIO_STACK_LOCATION IrpSp;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiQueryInformation] Called\n"));
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
   Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
@@ -786,7 +806,7 @@ NTSTATUS DispTdiReceive(
   NTSTATUS Status;
   ULONG BytesReceived = 0;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiReceive] Called.\n"));
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
   ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
@@ -831,7 +851,7 @@ done:
   } else
       IoMarkIrpPending(Irp);
 
-  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiReceive] Leaving. Status is (0x%X)\n", Status));
 
   return Status;
 }
@@ -854,7 +874,7 @@ NTSTATUS DispTdiReceiveDatagram(
   NTSTATUS Status;
   ULONG BytesReceived = 0;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiReceiveDatagram] Called\n"));
 
   IrpSp     = IoGetCurrentIrpStackLocation(Irp);
   DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
@@ -905,7 +925,7 @@ done:
    } else
        IoMarkIrpPending(Irp);
 
-  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiReceiveDatagram] Leaving. Status is (0x%X)\n", Status));
 
   return Status;
 }
@@ -927,7 +947,7 @@ NTSTATUS DispTdiSend(
   NTSTATUS Status;
   ULONG BytesSent = 0;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiSend] Called.\n"));
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
   SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
@@ -977,7 +997,7 @@ done:
    } else
        IoMarkIrpPending(Irp);
 
-  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiSend] Leaving. Status is (0x%X)\n", Status));
 
   return Status;
 }
@@ -999,7 +1019,7 @@ NTSTATUS DispTdiSendDatagram(
     PTRANSPORT_CONTEXT TranContext;
     NTSTATUS Status;
 
-    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+    TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiSendDatagram] Called.\n"));
 
     IrpSp       = IoGetCurrentIrpStackLocation(Irp);
     DgramInfo   = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters);
@@ -1061,7 +1081,7 @@ done:
     } else
         IoMarkIrpPending(Irp);
 
-    TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
+    TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiSendDatagram] Leaving.\n"));
 
     return Status;
 }
@@ -1083,7 +1103,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
   NTSTATUS Status;
   KIRQL OldIrql;
 
-  TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiSetEventHandler] Called\n"));
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
@@ -1226,6 +1246,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp)
   }
 
   UnlockObject(AddrFile, OldIrql);
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiSetEventHandler] Leaving. Status = 0x%x\n", Status));
 
   return Status;
 }
@@ -1241,7 +1262,7 @@ NTSTATUS DispTdiSetInformation(
  *     Status of operation
  */
 {
-    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+    TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiSetInformation] Called\n"));
 
        return STATUS_NOT_IMPLEMENTED;
 }
@@ -1310,26 +1331,27 @@ NTSTATUS DispTdiQueryInformationEx(
     PMDL OutputMdl          = NULL;
     NTSTATUS Status         = STATUS_SUCCESS;
 
-    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+    TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiQueryInformationEx] Called.\n"));
 
     TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
 
-    switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
-    case TDI_TRANSPORT_ADDRESS_FILE:
-        Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
-        break;
+    switch ((ULONG_PTR)IrpSp->FileObject->FsContext2)
+    {
+        case TDI_TRANSPORT_ADDRESS_FILE:
+            Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
+            break;
 
-    case TDI_CONNECTION_FILE:
-        Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
-        break;
+        case TDI_CONNECTION_FILE:
+            Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
+            break;
 
-    case TDI_CONTROL_CHANNEL_FILE:
-        Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
-        break;
+        case TDI_CONTROL_CHANNEL_FILE:
+            Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
+            break;
 
-    default:
-        TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
-        return STATUS_INVALID_PARAMETER;
+        default:
+            TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
+            return STATUS_INVALID_PARAMETER;
     }
 
     InputBufferLength  = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
@@ -1337,15 +1359,18 @@ NTSTATUS DispTdiQueryInformationEx(
 
     /* Validate parameters */
     if ((InputBufferLength == sizeof(TCP_REQUEST_QUERY_INFORMATION_EX)) &&
-        (OutputBufferLength != 0)) {
+        (OutputBufferLength != 0))
+    {
 
         InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
             IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
         OutputBuffer = Irp->UserBuffer;
 
         QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
-        if (QueryContext) {
-           _SEH2_TRY {
+        if (QueryContext)
+        {
+               _SEH2_TRY
+            {
                 InputMdl = IoAllocateMdl(InputBuffer,
                     sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
                     FALSE, TRUE, NULL);
@@ -1353,7 +1378,8 @@ NTSTATUS DispTdiQueryInformationEx(
                 OutputMdl = IoAllocateMdl(OutputBuffer,
                     OutputBufferLength, FALSE, TRUE, NULL);
 
-                if (InputMdl && OutputMdl) {
+                if (InputMdl && OutputMdl)
+                {
 
                     MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
                         IoModifyAccess);
@@ -1367,13 +1393,18 @@ NTSTATUS DispTdiQueryInformationEx(
 
                     RtlCopyMemory(&QueryContext->QueryInfo,
                         InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
-                } else
+                }
+                else
                     Status = STATUS_INSUFFICIENT_RESOURCES;
-            } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
                 Status = _SEH2_GetExceptionCode();
-            } _SEH2_END;
+            }
+            _SEH2_END;
 
-            if (NT_SUCCESS(Status)) {
+            if (NT_SUCCESS(Status))
+            {
                 Size = MmGetMdlByteCount(OutputMdl);
 
                 QueryContext->Irp       = Irp;
@@ -1387,7 +1418,7 @@ NTSTATUS DispTdiQueryInformationEx(
                     &Size, &QueryContext->QueryInfo.Context);
                 DispTdiQueryInformationExComplete(QueryContext, Status, Size);
 
-                TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
+                TI_DbgPrint(MAX_TRACE, ("[TCPIP, DispTdiQueryInformationEx] Leaving. Status = (0x%X)\n", Status));
 
                 return Status;
             }
@@ -1407,61 +1438,74 @@ NTSTATUS DispTdiQueryInformationEx(
             }
 
             ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
-        } else
+        }
+        else
             Status = STATUS_INSUFFICIENT_RESOURCES;
-    } else if( InputBufferLength ==
-              sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) ) {
-       /* Handle the case where the user is probing the buffer for length */
-       TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n",
-                               InputBufferLength, OutputBufferLength));
+    }
+    else if( InputBufferLength == sizeof(TCP_REQUEST_QUERY_INFORMATION_EX) )
+    {
+           /* Handle the case where the user is probing the buffer for length */
+           TI_DbgPrint(MAX_TRACE, ("InputBufferLength %d OutputBufferLength %d\n",
+                                   InputBufferLength, OutputBufferLength));
         InputBuffer = (PTCP_REQUEST_QUERY_INFORMATION_EX)
             IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
 
-       Size = 0;
+           Size = 0;
 
-        QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
-        if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES;
-
-       _SEH2_TRY {
-           InputMdl = IoAllocateMdl(InputBuffer,
-                                    sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
-                                    FALSE, TRUE, NULL);
-
-           MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
-                               IoModifyAccess);
-
-           InputMdlLocked = TRUE;
-           Status = STATUS_SUCCESS;
-       } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
-           TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n"));
-           Status = _SEH2_GetExceptionCode();
-       } _SEH2_END;
-
-       if( !NT_SUCCESS(Status) || !InputMdl ) {
-           if( InputMdl ) IoFreeMdl( InputMdl );
-           ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
-           return Status;
-       }
-
-       RtlCopyMemory(&QueryContext->QueryInfo,
-                     InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
-
-       QueryContext->Irp       = Irp;
-       QueryContext->InputMdl  = InputMdl;
-       QueryContext->OutputMdl = NULL;
-
-       Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
-       Request.RequestContext      = QueryContext;
-       Status = InfoTdiQueryInformationEx(&Request,
-                                          &QueryContext->QueryInfo.ID,
-                                          NULL,
-                                          &Size,
-                                          &QueryContext->QueryInfo.Context);
-       DispTdiQueryInformationExComplete(QueryContext, Status, Size);
-       TI_DbgPrint(MAX_TRACE, ("Leaving. Status = (0x%X)\n", Status));
-    } else Status = STATUS_INVALID_PARAMETER;
-
-    TI_DbgPrint(MIN_TRACE, ("Leaving. Status = (0x%X)\n", Status));
+        QueryContext = ExAllocatePoolWithTag(NonPagedPool,
+                        sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
+        
+        if (!QueryContext)
+            return STATUS_INSUFFICIENT_RESOURCES;
+
+           _SEH2_TRY
+        {
+               InputMdl = IoAllocateMdl(InputBuffer,
+                                        sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),
+                                        FALSE, TRUE, NULL);
+
+               MmProbeAndLockPages(InputMdl, Irp->RequestorMode,
+                                   IoModifyAccess);
+
+               InputMdlLocked = TRUE;
+               Status = STATUS_SUCCESS;
+           }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+               TI_DbgPrint(MAX_TRACE, ("Failed to acquire client buffer\n"));
+               Status = _SEH2_GetExceptionCode();
+           }
+        _SEH2_END;
+
+           if( !NT_SUCCESS(Status) || !InputMdl )
+        {
+               if( InputMdl )
+                IoFreeMdl( InputMdl );
+               ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
+            TI_DbgPrint(MAX_TRACE, ("[TCPIP, DispTdiQueryInformationEx] Leaving. Status = (0x%X)\n", Status));
+               return Status;
+           }
+
+           RtlCopyMemory(&QueryContext->QueryInfo,
+                         InputBuffer, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
+
+           QueryContext->Irp       = Irp;
+           QueryContext->InputMdl  = InputMdl;
+           QueryContext->OutputMdl = NULL;
+
+           Request.RequestNotifyObject = DispTdiQueryInformationExComplete;
+           Request.RequestContext      = QueryContext;
+           Status = InfoTdiQueryInformationEx(&Request,
+                                              &QueryContext->QueryInfo.ID,
+                                              NULL,
+                                              &Size,
+                                              &QueryContext->QueryInfo.Context);
+           DispTdiQueryInformationExComplete(QueryContext, Status, Size);
+    }
+    else
+        Status = STATUS_INVALID_PARAMETER;
+
+    TI_DbgPrint(MIN_TRACE, ("[TCPIP, DispTdiQueryInformationEx] Leaving. Status = (0x%X)\n", Status));
 
     return Status;
 }
@@ -1484,35 +1528,39 @@ NTSTATUS DispTdiSetInformationEx(
     TDI_REQUEST Request;
     TDI_STATUS Status;
 
-    TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
+    TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiSetInformationEx] Called.\n"));
 
     TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
     Info        = (PTCP_REQUEST_SET_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
 
-    switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
-    case TDI_TRANSPORT_ADDRESS_FILE:
-        Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
-        break;
+    switch ((ULONG_PTR)IrpSp->FileObject->FsContext2)
+    {
+        case TDI_TRANSPORT_ADDRESS_FILE:
+            Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
+            break;
 
-    case TDI_CONNECTION_FILE:
-        Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
-        break;
+        case TDI_CONNECTION_FILE:
+            Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
+            break;
 
-    case TDI_CONTROL_CHANNEL_FILE:
-        Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
-        break;
+        case TDI_CONTROL_CHANNEL_FILE:
+            Request.Handle.ControlChannel = TranContext->Handle.ControlChannel;
+            break;
 
-    default:
-        Irp->IoStatus.Status      = STATUS_INVALID_PARAMETER;
-        Irp->IoStatus.Information = 0;
+        default:
+            Irp->IoStatus.Status      = STATUS_INVALID_PARAMETER;
+            Irp->IoStatus.Information = 0;
 
-        TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
+            TI_DbgPrint(DEBUG_IRP, 
+                ("[TCPIP, DispTdiSetInformationEx] Leaving. Completing IRP at (0x%X).\n",
+                Irp));
 
-        return Irp->IoStatus.Status;
+            return Irp->IoStatus.Status;
     }
 
     Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);
-    if (NT_SUCCESS(Status)) {
+    if (NT_SUCCESS(Status))
+    {
         Request.RequestNotifyObject = DispDataRequestComplete;
         Request.RequestContext      = Irp;
 
@@ -1520,6 +1568,10 @@ NTSTATUS DispTdiSetInformationEx(
             &Info->Buffer, Info->BufferSize);
     }
 
+     TI_DbgPrint(DEBUG_IRP, 
+        ("[TCPIP, DispTdiSetInformationEx] Leaving. Completeing IRP at (0x%X).\n",
+        Irp));
+
     return Status;
 }
 
@@ -1529,7 +1581,8 @@ NTSTATUS DispTdiSetInformationEx(
  * Later on, create an NTE context and NTE instance
  */
 
-NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
+NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp )
+{
     NTSTATUS Status = STATUS_DEVICE_DOES_NOT_EXIST;
     PIP_SET_ADDRESS IpAddrChange =
         (PIP_SET_ADDRESS)Irp->AssociatedIrp.SystemBuffer;
@@ -1538,14 +1591,17 @@ NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
     TI_DbgPrint(MID_TRACE,("Setting IP Address for adapter %d\n",
                           IpAddrChange->NteIndex));
 
-    ForEachInterface(IF) {
-       TI_DbgPrint(MID_TRACE,("Looking at adapter %d\n", IF->Index));
+    ForEachInterface(IF)
+    {
+           TI_DbgPrint(MID_TRACE,("Looking at adapter %d\n", IF->Index));
 
-        if( IF->Unicast.Address.IPv4Address == IpAddrChange->Address ) {
+        if( IF->Unicast.Address.IPv4Address == IpAddrChange->Address )
+        {
             Status = STATUS_DUPLICATE_OBJECTID;
             break;
         }
-        if( IF->Index == IpAddrChange->NteIndex ) {
+        if( IF->Index == IpAddrChange->NteIndex )
+        {
             IPRemoveInterfaceRoute( IF );
 
             IF->Unicast.Type = IP_ADDRESS_V4;
@@ -1553,9 +1609,8 @@ NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
             IF->Netmask.Type = IP_ADDRESS_V4;
             IF->Netmask.Address.IPv4Address = IpAddrChange->Netmask;
             IF->Broadcast.Type = IP_ADDRESS_V4;
-           IF->Broadcast.Address.IPv4Address =
-               IF->Unicast.Address.IPv4Address |
-               ~IF->Netmask.Address.IPv4Address;
+               IF->Broadcast.Address.IPv4Address =
+                   IF->Unicast.Address.IPv4Address | ~IF->Netmask.Address.IPv4Address;
 
             TI_DbgPrint(MID_TRACE,("New Unicast Address: %x\n",
                                    IF->Unicast.Address.IPv4Address));
@@ -1569,19 +1624,23 @@ NTSTATUS DispTdiSetIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
             Irp->IoStatus.Information = IF->Index;
             break;
         }
-    } EndFor(IF);
+    }
+    EndFor(IF);
 
     Irp->IoStatus.Status = Status;
     return Status;
 }
 
-NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
+NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp )
+{
     NTSTATUS Status = STATUS_UNSUCCESSFUL;
     PUSHORT NteIndex = Irp->AssociatedIrp.SystemBuffer;
     IF_LIST_ITER(IF);
 
-    ForEachInterface(IF) {
-        if( IF->Index == *NteIndex ) {
+    ForEachInterface(IF)
+    {
+        if( IF->Index == *NteIndex )
+        {
             IPRemoveInterfaceRoute( IF );
             IF->Unicast.Type = IP_ADDRESS_V4;
             IF->Unicast.Address.IPv4Address = 0;
@@ -1591,7 +1650,8 @@ NTSTATUS DispTdiDeleteIPAddress( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
             IF->Broadcast.Address.IPv4Address = 0;
             Status = STATUS_SUCCESS;
         }
-    } EndFor(IF);
+    }
+    EndFor(IF);
 
     Irp->IoStatus.Status = Status;
     return Status;
index 98cc406..d7b7905 100644 (file)
@@ -413,15 +413,18 @@ NTSTATUS FileOpenConnection(
   NTSTATUS Status;
   PCONNECTION_ENDPOINT Connection;
 
-  TI_DbgPrint(MID_TRACE, ("Called.\n"));
+  TI_DbgPrint(MID_TRACE, ("[TCPIP, FileOpenConnection] Called\n"));
+  //DbgPrint("[TCPIP, FileOpenConnection] Called\n");
 
   Connection = TCPAllocateConnectionEndpoint( ClientContext );
 
-  if( !Connection ) return STATUS_NO_MEMORY;
+  if (!Connection)
+      return STATUS_NO_MEMORY;
 
   Status = TCPSocket( Connection, AF_INET, SOCK_STREAM, IPPROTO_TCP );
 
-  if( !NT_SUCCESS(Status) ) {
+  if (!NT_SUCCESS(Status))
+  {
       DereferenceObject( Connection );
       return Status;
   }
@@ -429,7 +432,8 @@ NTSTATUS FileOpenConnection(
   /* Return connection endpoint file object */
   Request->Handle.ConnectionContext = Connection;
 
-  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, FileOpenConnection] Leaving\n"));
+  //DbgPrint("[TCPIP, FileOpenConnection] Leaving\n");
 
   return STATUS_SUCCESS;
 }
index ced3628..280d01a 100644 (file)
@@ -360,7 +360,7 @@ TiDispatchInternal(
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
 
-  TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatchInternal] Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
     DeviceObject, Irp, IrpSp->MinorFunction));
 
   Irp->IoStatus.Status      = STATUS_SUCCESS;
@@ -435,7 +435,7 @@ TiDispatchInternal(
     Status = STATUS_INVALID_DEVICE_REQUEST;
   }
 
-  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatchInternal] Leaving. Status = (0x%X).\n", Status));
 
   if( Complete )
       IRPFinish( Irp, Status );
@@ -462,7 +462,7 @@ TiDispatch(
 
   IrpSp  = IoGetCurrentIrpStackLocation(Irp);
 
-  TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp));
 
   Irp->IoStatus.Information = 0;
 
@@ -505,7 +505,7 @@ TiDispatch(
     }
   }
 
-  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
+  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status));
 
   return IRPFinish( Irp, Status );
 }
@@ -524,7 +524,7 @@ VOID NTAPI TiUnload(
 
   TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
   if (!IsListEmpty(&AddressFileListHead)) {
-    TI_DbgPrint(MIN_TRACE, ("Open address file objects exists.\n"));
+    TI_DbgPrint(MIN_TRACE, ("[TCPIP, TiUnload] Called. Open address file objects exists.\n"));
   }
   TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
 #endif
@@ -573,7 +573,7 @@ VOID NTAPI TiUnload(
   if (EntityList)
     ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG);
 
-  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, TiUnload] Leaving.\n"));
 }
 
 NTSTATUS NTAPI
@@ -598,7 +598,7 @@ DriverEntry(
   NDIS_STATUS NdisStatus;
   LARGE_INTEGER DueTime;
 
-  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Called\n"));
 
   /* TdiInitialize() ? */
 
@@ -759,6 +759,9 @@ DriverEntry(
   DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
   KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);
 
+  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));
+
+
   return STATUS_SUCCESS;
 }
 
index 72024e8..3764922 100644 (file)
@@ -2,5 +2,6 @@
 add_subdirectory(chew)
 add_subdirectory(csq)
 add_subdirectory(ip)
+add_subdirectory(lwip)
 add_subdirectory(oskittcp)
 add_subdirectory(sound)
index fbdb2d1..8796265 100644 (file)
@@ -3,7 +3,8 @@ add_definitions(-D__NTDRIVER__)
 
 include_directories(
     BEFORE ${REACTOS_SOURCE_DIR}/drivers/network/tcpip/include
-    ${REACTOS_SOURCE_DIR}/lib/drivers/oskittcp/include)
+    ${REACTOS_SOURCE_DIR}/lib/drivers/lwip/src/include
+    ${REACTOS_SOURCE_DIR}/lib/drivers/lwip/src/include/ipv4)
 
 if(ARCH MATCHES i386)
     list(APPEND SOURCE network/i386/checksum.S)
index e0b969f..c1d83ba 100644 (file)
@@ -10,6 +10,9 @@
 
 #include "precomp.h"
 
+#define __LWIP_INET_H__
+#include "lwip/netifapi.h"
+
 
 LIST_ENTRY InterfaceListHead;
 KSPIN_LOCK InterfaceListLock;
@@ -21,6 +24,12 @@ BOOLEAN IpWorkItemQueued = FALSE;
 
 IP_PROTOCOL_HANDLER ProtocolTable[IP_PROTOCOL_TABLE_SIZE];
 
+VOID
+TCPRegisterInterface(PIP_INTERFACE IF);
+
+VOID
+TCPUnregisterInterface(PIP_INTERFACE IF);
+
 VOID DontFreePacket(
     PVOID Object)
 /*
@@ -174,13 +183,14 @@ PIP_INTERFACE IPCreateInterface(
 
     TcpipInitializeSpinLock(&IF->Lock);
 
-    IF->TCPContext = ExAllocatePoolWithTag
-       ( NonPagedPool, sizeof(OSK_IFADDR) + 3 * sizeof( struct sockaddr_in ),
-          OSKITTCP_CONTEXT_TAG );
+    IF->TCPContext = ExAllocatePool
+       ( NonPagedPool, sizeof(struct netif));
     if (!IF->TCPContext) {
         ExFreePoolWithTag(IF, IP_INTERFACE_TAG);
         return NULL;
     }
+    
+    TCPRegisterInterface(IF);
 
 #ifdef __NTDRIVER__
     InsertTDIInterfaceEntity( IF );
@@ -203,8 +213,10 @@ VOID IPDestroyInterface(
 #ifdef __NTDRIVER__
     RemoveTDIInterfaceEntity( IF );
 #endif
+    
+    TCPUnregisterInterface(IF);
 
-    ExFreePoolWithTag(IF->TCPContext, OSKITTCP_CONTEXT_TAG);
+    ExFreePool(IF->TCPContext);
     ExFreePoolWithTag(IF, IP_INTERFACE_TAG);
 }
 
@@ -231,6 +243,8 @@ VOID IPAddInterfaceRoute( PIP_INTERFACE IF ) {
      * other computers */
     if (IF != Loopback)
        ARPTransmit(NULL, NULL, IF);
+    
+    TCPUpdateInterfaceIPInformation(IF);
 }
 
 BOOLEAN IPRegisterInterface(
index 44aa276..1c01c1b 100644 (file)
@@ -54,46 +54,9 @@ static VOID DisplayIPHeader(
       ((IPHeader->DstAddr >> 16) & 0xFF), ((IPHeader->DstAddr >> 24) & 0xFF));
 }
 
-static VOID DisplayTCPHeader(
-    PCHAR Header,
-    UINT Length)
-{
-    /* FIXME: IPv4 only */
-    PIPv4_HEADER IPHeader = (PIPv4_HEADER)Header;
-    PTCPv4_HEADER TCPHeader;
-
-    if (IPHeader->Protocol != IPPROTO_TCP) {
-        DbgPrint("This is not a TCP datagram. Protocol is %d\n", IPHeader->Protocol);
-        return;
-    }
-
-    TCPHeader = (PTCPv4_HEADER)((PCHAR)IPHeader + (IPHeader->VerIHL & 0x0F) * 4);
-
-    DbgPrint("TCP header:\n");
-    DbgPrint("  SourcePort: %d\n", WN2H(TCPHeader->SourcePort));
-    DbgPrint("  DestinationPort: %d\n", WN2H(TCPHeader->DestinationPort));
-    DbgPrint("  SequenceNumber: 0x%x\n", DN2H(TCPHeader->SequenceNumber));
-    DbgPrint("  AckNumber: 0x%x\n", DN2H(TCPHeader->AckNumber));
-    DbgPrint("  DataOffset: 0x%x (0x%x) 32-bit words\n", TCPHeader->DataOffset, TCPHeader->DataOffset >> 4);
-    DbgPrint("  Flags: 0x%x (0x%x)\n", TCPHeader->Flags, TCPHeader->Flags & 0x3F);
-    if ((TCPHeader->Flags & TCP_URG) > 0) DbgPrint("    TCP_URG - Urgent Pointer field significant\n");
-    if ((TCPHeader->Flags & TCP_ACK) > 0) DbgPrint("    TCP_ACK - Acknowledgement field significant\n");
-    if ((TCPHeader->Flags & TCP_PSH) > 0) DbgPrint("    TCP_PSH - Push Function\n");
-    if ((TCPHeader->Flags & TCP_RST) > 0) DbgPrint("    TCP_RST - Reset the connection\n");
-    if ((TCPHeader->Flags & TCP_SYN) > 0) DbgPrint("    TCP_SYN - Synchronize sequence numbers\n");
-    if ((TCPHeader->Flags & TCP_FIN) > 0) DbgPrint("    TCP_FIN - No more data from sender\n");
-    DbgPrint("  Window: 0x%x\n", WN2H(TCPHeader->Window));
-    DbgPrint("  Checksum: 0x%x\n", WN2H(TCPHeader->Checksum));
-    DbgPrint("  Urgent: 0x%x\n", WN2H(TCPHeader->Urgent));
-}
-
-
 VOID DisplayTCPPacket(
     PIP_PACKET IPPacket)
 {
-    UINT Length;
-    PCHAR Buffer;
-
     if ((DbgQueryDebugFilterState(DPFLTR_TCPIP_ID, DEBUG_PBUFFER | DPFLTR_MASK) != TRUE) ||
         (DbgQueryDebugFilterState(DPFLTR_TCPIP_ID, DEBUG_TCP | DPFLTR_MASK) != TRUE)) {
         return;
@@ -112,20 +75,6 @@ VOID DisplayTCPPacket(
     TI_DbgPrint(MIN_TRACE, ("TotalSize (%d).\n", IPPacket->TotalSize));
     TI_DbgPrint(MIN_TRACE, ("ContigSize (%d).\n", IPPacket->ContigSize));
     TI_DbgPrint(MIN_TRACE, ("NdisPacket (0x%X).\n", IPPacket->NdisPacket));
-
-    if (IPPacket->NdisPacket) {
-        NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
-        Buffer = ExAllocatePool(NonPagedPool, Length);
-        if (Buffer) {
-            Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, 0, Length);
-            DisplayTCPHeader(Buffer, Length);
-            ExFreePool(Buffer);
-        }
-    } else {
-        Buffer = IPPacket->Header;
-        Length = IPPacket->ContigSize;
-        DisplayTCPHeader(Buffer, Length);
-    }
 }
 #endif
 
index b300fa3..1b1d3ba 100644 (file)
 
 #include "precomp.h"
 
-/* Listener->Lock MUST be acquired */
-NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
-                    PCONNECTION_ENDPOINT Connection,
-                    PTDI_REQUEST_KERNEL Request ) {
+#include "rosip.h"
+
+NTSTATUS TCPCheckPeerForAccept(PVOID Context,
+                               PTDI_REQUEST_KERNEL Request)
+{
+    struct tcp_pcb *newpcb = Context;
     NTSTATUS Status;
-    SOCKADDR_IN OutAddr;
-    OSK_UINT OutAddrLen;
-    PTA_IP_ADDRESS RequestAddressReturn;
     PTDI_CONNECTION_INFORMATION WhoIsConnecting;
-
-    /* Unpack TDI info -- We need the return connection information
-     * struct to return the address so it can be filtered if needed
-     * by WSAAccept -- The returned address will be passed on to
-     * userland after we complete this irp */
-    WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)
-    Request->ReturnConnectionInformation;
-
-    Status = TCPTranslateError
-    ( OskitTCPAccept( Listener->SocketContext,
-              &Connection->SocketContext,
-              Connection,
-              &OutAddr,
-              sizeof(OutAddr),
-              &OutAddrLen,
-              Request->RequestFlags & TDI_QUERY_ACCEPT ? 0 : 1 ) );
-
-    TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
-
-    if( NT_SUCCESS(Status) && Status != STATUS_PENDING ) {
-    RequestAddressReturn = WhoIsConnecting->RemoteAddress;
-
-    TI_DbgPrint(DEBUG_TCP,("Copying address to %x (Who %x)\n",
-                   RequestAddressReturn, WhoIsConnecting));
-
-        RequestAddressReturn->TAAddressCount = 1;
-    RequestAddressReturn->Address[0].AddressLength = OutAddrLen;
-
-        /* BSD uses the first byte of the sockaddr struct as a length.
-         * Since windows doesn't do that we strip it */
-    RequestAddressReturn->Address[0].AddressType =
-        (OutAddr.sin_family >> 8) & 0xff;
-
-    RtlCopyMemory( &RequestAddressReturn->Address[0].Address,
-               ((PCHAR)&OutAddr) + sizeof(USHORT),
-               sizeof(RequestAddressReturn->Address[0].Address[0]) );
-
-    TI_DbgPrint(DEBUG_TCP,("Done copying\n"));
-    }
-
-    TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
+    PTA_IP_ADDRESS RemoteAddress;
+    struct ip_addr ipaddr;
+
+    DbgPrint("[IP, TCPCheckPeerForAccept] Called\n");
+    
+    if (Request->RequestFlags & TDI_QUERY_ACCEPT)
+        DbgPrint("TDI_QUERY_ACCEPT NOT SUPPORTED!!!\n");
+
+    WhoIsConnecting = (PTDI_CONNECTION_INFORMATION)Request->ReturnConnectionInformation;
+    RemoteAddress = (PTA_IP_ADDRESS)WhoIsConnecting->RemoteAddress;
+    
+    RemoteAddress->TAAddressCount = 1;
+    RemoteAddress->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
+    RemoteAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
+    
+    Status = TCPTranslateError(LibTCPGetPeerName(newpcb,
+                                                 &ipaddr,
+                                                 &RemoteAddress->Address[0].Address[0].sin_port));
+    
+    RemoteAddress->Address[0].Address[0].in_addr = ipaddr.addr;
+    
+    DbgPrint("[IP, TCPCheckPeerForAccept] Leaving. Status %x\n", Status);
 
     return Status;
 }
 
 /* This listen is on a socket we keep as internal.  That socket has the same
  * lifetime as the address file */
-NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
+NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog )
+{
     NTSTATUS Status = STATUS_SUCCESS;
-    SOCKADDR_IN AddressToBind;
+    struct ip_addr AddressToBind;
     KIRQL OldIrql;
 
     ASSERT(Connection);
@@ -76,59 +57,67 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
 
     LockObject(Connection, &OldIrql);
 
-    TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Called\n"));
+    DbgPrint("[IP, TCPListen] Called\n");
 
-    TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
-    Connection->SocketContext));
+    TI_DbgPrint(DEBUG_TCP, ("Connection->SocketContext %x\n",
+        Connection->SocketContext));
+    
+    AddressToBind.addr = Connection->AddressFile->Address.Address.IPv4Address;
 
-    AddressToBind.sin_family = AF_INET;
-    memcpy( &AddressToBind.sin_addr,
-        &Connection->AddressFile->Address.Address.IPv4Address,
-        sizeof(AddressToBind.sin_addr) );
-    AddressToBind.sin_port = Connection->AddressFile->Port;
-
-    TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port));
-
-    Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext,
-                        &AddressToBind,
-                        sizeof(AddressToBind) ) );
+    Status = TCPTranslateError(LibTCPBind(Connection->SocketContext,
+                                          &AddressToBind,
+                                          Connection->AddressFile->Port));
 
     if (NT_SUCCESS(Status))
-        Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
+    {
+        Connection->SocketContext = LibTCPListen(Connection->SocketContext, Backlog);
+        if (!Connection->SocketContext)
+            Status = STATUS_UNSUCCESSFUL;
+    }
 
     UnlockObject(Connection, OldIrql);
 
-    TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status));
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Leaving. Status = %x\n", Status));
+    DbgPrint("[IP, TCPListen] Leaving. Status = %x\n", Status);
 
     return Status;
 }
 
 BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener,
-                  PCONNECTION_ENDPOINT Connection ) {
+                  PCONNECTION_ENDPOINT Connection )
+{
     PLIST_ENTRY ListEntry;
     PTDI_BUCKET Bucket;
     KIRQL OldIrql;
     BOOLEAN Found = FALSE;
 
+    DbgPrint("[IP, TCPAbortListenForSocket] Called\n");
+
     LockObject(Listener, &OldIrql);
 
     ListEntry = Listener->ListenRequest.Flink;
-    while ( ListEntry != &Listener->ListenRequest ) {
-    Bucket = CONTAINING_RECORD(ListEntry, TDI_BUCKET, Entry);
-
-    if( Bucket->AssociatedEndpoint == Connection ) {
-        DereferenceObject(Bucket->AssociatedEndpoint);
-        RemoveEntryList( &Bucket->Entry );
-        ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG );
-        Found = TRUE;
-        break;
-    }
-
-    ListEntry = ListEntry->Flink;
+    while ( ListEntry != &Listener->ListenRequest )
+    {
+        Bucket = CONTAINING_RECORD(ListEntry, TDI_BUCKET, Entry);
+
+        if( Bucket->AssociatedEndpoint == Connection )
+        {
+            DereferenceObject(Bucket->AssociatedEndpoint);
+            RemoveEntryList( &Bucket->Entry );
+            ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG );
+            Found = TRUE;
+            break;
+        }
+
+        ListEntry = ListEntry->Flink;
     }
 
     UnlockObject(Listener, OldIrql);
 
+    DbgPrint("[IP, TCPAbortListenForSocket] Leaving. Status = %s\n",
+        Found == TRUE ? "TRUE" : "FALSE");
+
     return Found;
 }
 
@@ -142,29 +131,28 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
     PTDI_BUCKET Bucket;
     KIRQL OldIrql;
 
-    TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n"));
+    DbgPrint("[IP, TCPAccept] Called\n");
 
     LockObject(Listener, &OldIrql);
 
-    Status = TCPServiceListeningSocket( Listener, Connection,
-                       (PTDI_REQUEST_KERNEL)Request );
-
-    if( Status == STATUS_PENDING ) {
-        Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket),
-                                        TDI_BUCKET_TAG );
-
-        if( Bucket ) {
-            ReferenceObject(Connection);
-            Bucket->AssociatedEndpoint = Connection;
-            Bucket->Request.RequestNotifyObject = Complete;
-            Bucket->Request.RequestContext = Context;
-            InsertTailList( &Listener->ListenRequest, &Bucket->Entry );
-        } else
-            Status = STATUS_NO_MEMORY;
+    Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket),
+                                   TDI_BUCKET_TAG );
+    
+    if( Bucket )
+    {
+        Bucket->AssociatedEndpoint = Connection;
+        ReferenceObject(Bucket->AssociatedEndpoint);
+
+        Bucket->Request.RequestNotifyObject = Complete;
+        Bucket->Request.RequestContext = Context;
+        InsertTailList( &Listener->ListenRequest, &Bucket->Entry );
+        Status = STATUS_PENDING;
     }
+    else
+        Status = STATUS_NO_MEMORY;
 
     UnlockObject(Listener, OldIrql);
 
-    TI_DbgPrint(DEBUG_TCP,("TCPAccept finished %x\n", Status));
+    DbgPrint("[IP, TCPAccept] Leaving. Status = %x\n", Status);
     return Status;
 }
index 4534da3..e859dcf 100644 (file)
  * COPYRIGHT:   See COPYING in the top level directory
  * PROJECT:     ReactOS TCP/IP protocol driver
  * FILE:        transport/tcp/event.c
- * PURPOSE:     Transmission Control Protocol -- Events from oskittcp
- * PROGRAMMERS: Art Yerkes
- * REVISIONS:
- *   CSH 01/08-2000 Created
+ * PURPOSE:     Transmission Control Protocol
+ * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
  */
 
 #include "precomp.h"
 
-int TCPSocketState(void *ClientData,
-           void *WhichSocket,
-           void *WhichConnection,
-           OSK_UINT NewState ) {
-    PCONNECTION_ENDPOINT Connection = WhichConnection;
-
-    TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n",
-               Connection,
-               NewState & SEL_CONNECT ? 'C' : 'c',
-               NewState & SEL_READ    ? 'R' : 'r',
-               NewState & SEL_FIN     ? 'F' : 'f',
-               NewState & SEL_ACCEPT  ? 'A' : 'a',
-               NewState & SEL_WRITE   ? 'W' : 'w'));
-
-    /* If this socket is missing its socket context, that means that it
-     * has been created as a new connection in sonewconn but not accepted
-     * yet. We can safely ignore event notifications on these sockets.
-     * Once they are accepted, they will get a socket context and we will 
-     * be able to process them.
-     */
-    if (!Connection)
-        return 0;
-
-    TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n",
-               NewState, Connection,
-               Connection->SignalState ^ NewState,
-               NewState));
-
-    Connection->SignalState = NewState;
-
-    HandleSignalledConnection(Connection);
-
-    return 0;
-}
-
-void TCPPacketSendComplete( PVOID Context,
-                PNDIS_PACKET NdisPacket,
-                NDIS_STATUS NdisStatus ) {
-    TI_DbgPrint(DEBUG_TCP,("called %x\n", NdisPacket));
-    FreeNdisPacket(NdisPacket);
-    TI_DbgPrint(DEBUG_TCP,("done\n"));
-}
-
-#define STRINGIFY(x) #x
-
-int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
-    NDIS_STATUS NdisStatus;
-    PNEIGHBOR_CACHE_ENTRY NCE;
-    IP_PACKET Packet = { 0 };
-    IP_ADDRESS RemoteAddress, LocalAddress;
-    PIPv4_HEADER Header;
-
-    if( *data == 0x45 ) { /* IPv4 */
-    Header = (PIPv4_HEADER)data;
-    LocalAddress.Type = IP_ADDRESS_V4;
-    LocalAddress.Address.IPv4Address = Header->SrcAddr;
-    RemoteAddress.Type = IP_ADDRESS_V4;
-    RemoteAddress.Address.IPv4Address = Header->DstAddr;
-    } else {
-    TI_DbgPrint(MIN_TRACE,("Outgoing packet is not IPv4\n"));
-    OskitDumpBuffer( data, len );
-    return OSK_EINVAL;
+#include "lwip/err.h"
+#include "lwip/sys.h"
+#include "lwip/pbuf.h"
+#include "lwip/tcp.h"
+#include "lwip/api.h"
+
+#include "rosip.h"
+
+static const char * const tcp_state_str[] = {
+  "CLOSED",      
+  "LISTEN",      
+  "SYN_SENT",    
+  "SYN_RCVD",    
+  "ESTABLISHED", 
+  "FIN_WAIT_1",  
+  "FIN_WAIT_2",  
+  "CLOSE_WAIT",  
+  "CLOSING",     
+  "LAST_ACK",    
+  "TIME_WAIT"   
+};
+
+VOID
+FlushAllQueues(PCONNECTION_ENDPOINT Connection, NTSTATUS Status)
+{
+    PTCP_COMPLETION_ROUTINE Complete;
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    
+    ReferenceObject(Connection);
+    
+    DbgPrint("Flushing recv/all with status: 0x%x\n", Status);
+    
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock))) {
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+        TI_DbgPrint(DEBUG_TCP,
+                    ("Completing Receive request: %x %x\n",
+                     Bucket->Request, Status));
+        
+        Bucket->Status = Status;
+        Bucket->Information = 0;
+        
+        Complete = Bucket->Request.RequestNotifyObject;
+        
+        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
+        
+        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
     }
-
-    if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
-    TI_DbgPrint(MIN_TRACE,("Unable to get route to %s\n", A2S(&RemoteAddress)));
-    return OSK_EADDRNOTAVAIL;
+    
+    if (Status == STATUS_SUCCESS) Status = STATUS_FILE_CLOSED;
+    
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
+    {
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+        Bucket->Status = Status;
+        Bucket->Information = 0;
+        
+        Complete = Bucket->Request.RequestNotifyObject;
+        
+        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
+        
+        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
     }
-
-    NdisStatus = AllocatePacketWithBuffer( &Packet.NdisPacket, NULL, len );
-
-    if (NdisStatus != NDIS_STATUS_SUCCESS) {
-    TI_DbgPrint(DEBUG_TCP, ("Error from NDIS: %08x\n", NdisStatus));
-    return OSK_ENOBUFS;
+    
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
+    {
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );    
+        
+        TI_DbgPrint(DEBUG_TCP,
+                    ("Completing Send request: %x %x\n",
+                     Bucket->Request, Status));
+        
+        Bucket->Status = Status;
+        Bucket->Information = 0;
+        
+        Complete = Bucket->Request.RequestNotifyObject;
+        
+        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
+        
+        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
     }
-
-    GetDataPtr( Packet.NdisPacket, 0,
-        (PCHAR *)&Packet.Header, &Packet.ContigSize );
-
-    RtlCopyMemory( Packet.Header, data, len );
-
-    Packet.HeaderSize = sizeof(IPv4_HEADER);
-    Packet.TotalSize = len;
-    Packet.SrcAddr = LocalAddress;
-    Packet.DstAddr = RemoteAddress;
-
-    if (!NT_SUCCESS(IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL )))
+    
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
     {
-        FreeNdisPacket(Packet.NdisPacket);
-        return OSK_EINVAL;
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+        Bucket->Status = Status;
+        Bucket->Information = 0;
+        
+        Complete = Bucket->Request.RequestNotifyObject;
+        
+        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
+        
+        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
     }
-
-    return 0;
+    
+    DereferenceObject(Connection);
 }
 
-/* Memory management routines
- *
- * By far the most requests for memory are either for 128 or 2049 byte blocks,
- * so we want to satisfy those from lookaside lists. Unfortunately, the
- * TCPFree() function doesn't pass the size of the block to be freed, so we
- * need to keep track of it ourselves. We do it by prepending each block with
- * 4 bytes, indicating if this is a 'L'arge (2049), 'S'mall (128) or 'O'ther
- * block.
- */
-
-/* Set to some non-zero value to get a profile of memory allocation sizes */
-#define MEM_PROFILE 0
-
-#define SMALL_SIZE 128
-#define LARGE_SIZE 2049
-
-#define SIGNATURE_LARGE 'LLLL'
-#define SIGNATURE_SMALL 'SSSS'
-#define SIGNATURE_OTHER 'OOOO'
-static NPAGED_LOOKASIDE_LIST LargeLookasideList;
-static NPAGED_LOOKASIDE_LIST SmallLookasideList;
-
-NTSTATUS
-TCPMemStartup( void )
+VOID
+TCPFinEventHandler(void *arg, err_t err)
 {
-    ExInitializeNPagedLookasideList( &LargeLookasideList,
-                                     NULL,
-                                     NULL,
-                                     0,
-                                     LARGE_SIZE + sizeof( ULONG ),
-                                     OSK_LARGE_TAG,
-                                     0 );
-    ExInitializeNPagedLookasideList( &SmallLookasideList,
-                                     NULL,
-                                     NULL,
-                                     0,
-                                     SMALL_SIZE + sizeof( ULONG ),
-                                     OSK_SMALL_TAG,
-                                     0 );
-
-    return STATUS_SUCCESS;
+    PCONNECTION_ENDPOINT Connection = arg;
+    
+    FlushAllQueues(Connection, TCPTranslateError(err));
+    
+    /* We're already closed so we don't want to call lwip_close */
+    Connection->SocketContext = NULL;
 }
-
-void *TCPMalloc( void *ClientData,
-         OSK_UINT Bytes, OSK_PCHAR File, OSK_UINT Line ) {
-    void *v;
-    ULONG Signature;
-
-#if 0 != MEM_PROFILE
-    static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0;
-    static OSK_UINT ArrayUsed = 0, AllocationCount = 0;
-    OSK_UINT i, NewSize, *NewArray;
-    int Found;
-
-    Found = 0;
-    for ( i = 0; i < ArrayUsed && ! Found; i++ ) {
-    Found = ( Sizes[i] == Bytes );
-    if ( Found ) {
-        Counts[i]++;
-    }
-    }
-    if ( ! Found ) {
-    if ( ArrayAllocated <= ArrayUsed ) {
-        NewSize = ( 0 == ArrayAllocated ? 16 : 2 * ArrayAllocated );
-        NewArray = exAllocatePool( NonPagedPool, 2 * NewSize * sizeof( OSK_UINT ) );
-        if ( NULL != NewArray ) {
-        if ( 0 != ArrayAllocated ) {
-            memcpy( NewArray, Sizes,
-                    ArrayAllocated * sizeof( OSK_UINT ) );
-            exFreePool( Sizes );
-            memcpy( NewArray + NewSize, Counts,
-                    ArrayAllocated * sizeof( OSK_UINT ) );
-            exFreePool( Counts );
-        }
-        Sizes = NewArray;
-        Counts = NewArray + NewSize;
-        ArrayAllocated = NewSize;
-        } else if ( 0 != ArrayAllocated ) {
-        exFreePool( Sizes );
-        exFreePool( Counts );
-        ArrayAllocated = 0;
+    
+VOID
+TCPAcceptEventHandler(void *arg, struct tcp_pcb *newpcb)
+{
+    PCONNECTION_ENDPOINT Connection = arg;
+    PTCP_COMPLETION_ROUTINE Complete;
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    PIRP Irp;
+    NTSTATUS Status;
+    KIRQL OldIrql;
+    
+    DbgPrint("[IP, TCPAcceptEventHandler] Called\n");
+    
+    ReferenceObject(Connection);
+    
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
+    {
+        PIO_STACK_LOCATION IrpSp;
+        
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+        Irp = Bucket->Request.RequestContext;
+        IrpSp = IoGetCurrentIrpStackLocation( Irp );
+        
+        TI_DbgPrint(DEBUG_TCP,("[IP, TCPAcceptEventHandler] Getting the socket\n"));
+        
+        Status = TCPCheckPeerForAccept(newpcb,
+                                       (PTDI_REQUEST_KERNEL)&IrpSp->Parameters);
+        
+        TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n", Status));
+        
+        Bucket->Status = Status;
+        Bucket->Information = 0;
+        
+        DbgPrint("[IP, TCPAcceptEventHandler] Associated with: 0x%x\n",
+            Bucket->AssociatedEndpoint->SocketContext);
+        
+        DbgPrint("[IP, TCPAcceptEventHandler] Completing accept event %x\n", Status);
+        
+        Complete = Bucket->Request.RequestNotifyObject;
+        
+        if (Status == STATUS_SUCCESS)
+        {
+            DbgPrint("[IP, TCPAcceptEventHandler] newpcb->state = %s, listen_pcb->state = %s, newpcb->id = %d\n",
+                tcp_state_str[newpcb->state],
+                tcp_state_str[((struct tcp_pcb*)Connection->SocketContext)->state],
+                newpcb->identifier);
+
+            LockObject(Bucket->AssociatedEndpoint, &OldIrql);
+            Bucket->AssociatedEndpoint->SocketContext = newpcb;
+            
+            LibTCPAccept(newpcb,
+                (struct tcp_pcb*)Connection->SocketContext,
+                Bucket->AssociatedEndpoint);
+
+            DbgPrint("[IP, TCPAcceptEventHandler] Trying to unlock Bucket->AssociatedEndpoint\n");
+            UnlockObject(Bucket->AssociatedEndpoint, OldIrql);
         }
+        
+        DbgPrint("[IP, TCPAcceptEventHandler] Done!\n");
+        
+        Complete(Bucket->Request.RequestContext,
+                    Bucket->Status, Bucket->Information);
+            
+        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
     }
-    if ( ArrayUsed < ArrayAllocated ) {
-        Sizes[ArrayUsed] = Bytes;
-        Counts[ArrayUsed] = 1;
-        ArrayUsed++;
-    }
-    }
+    
+    DereferenceObject(Connection);
+}
 
-    if ( 0 == (++AllocationCount % MEM_PROFILE) ) {
-    TI_DbgPrint(DEBUG_TCP, ("Memory allocation size profile:\n"));
-    for ( i = 0; i < ArrayUsed; i++ ) {
+VOID
+TCPSendEventHandler(void *arg, u16_t space)
+{
+    PCONNECTION_ENDPOINT Connection = arg;
+    PTCP_COMPLETION_ROUTINE Complete;
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    PIRP Irp;
+    NTSTATUS Status;
+    PMDL Mdl;
+    
+    DbgPrint("[IP, TCPSendEventHandler] Called\n");
+    
+    ReferenceObject(Connection);
+
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
+    {
+        UINT SendLen = 0;
+        PVOID SendBuffer = 0;
+        
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+        Irp = Bucket->Request.RequestContext;
+        Mdl = Irp->MdlAddress;
+        
         TI_DbgPrint(DEBUG_TCP,
-                    ("Size %4u Count %5u\n", Sizes[i], Counts[i]));
-    }
-    TI_DbgPrint(DEBUG_TCP, ("End of memory allocation size profile\n"));
-    }
-#endif /* MEM_PROFILE */
-
-    if ( SMALL_SIZE == Bytes ) {
-    v = ExAllocateFromNPagedLookasideList( &SmallLookasideList );
-    Signature = SIGNATURE_SMALL;
-    } else if ( LARGE_SIZE == Bytes ) {
-    v = ExAllocateFromNPagedLookasideList( &LargeLookasideList );
-    Signature = SIGNATURE_LARGE;
-    } else {
-    v = ExAllocatePoolWithTag( NonPagedPool, Bytes + sizeof(ULONG),
-                               OSK_OTHER_TAG );
-    Signature = SIGNATURE_OTHER;
-    }
-    if( v ) {
-    *((ULONG *) v) = Signature;
-    v = (void *)((char *) v + sizeof(ULONG));
+                    ("Getting the user buffer from %x\n", Mdl));
+        
+        NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
+        
+        TI_DbgPrint(DEBUG_TCP,
+                    ("Writing %d bytes to %x\n", SendLen, SendBuffer));
+        
+        TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
+        TI_DbgPrint
+        (DEBUG_TCP,
+         ("Connection->SocketContext: %x\n",
+          Connection->SocketContext));
+        
+        Status = TCPTranslateError(LibTCPSend(Connection->SocketContext,
+                                              SendBuffer,
+                                              SendLen));
+        
+        TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", SendLen));
+        
+        if( Status == STATUS_PENDING )
+        {
+            ExInterlockedInsertHeadList(&Connection->SendRequest,
+                                        &Bucket->Entry,
+                                        &Connection->Lock);
+            break;
+        }
+        else
+        {
+            TI_DbgPrint(DEBUG_TCP,
+                        ("Completing Send request: %x %x\n",
+                         Bucket->Request, Status));
+            
+            Bucket->Status = Status;
+            Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? SendLen : 0;
+            
+            DbgPrint("Completing send req %x\n", Status);
+            
+            Complete = Bucket->Request.RequestNotifyObject;
+            
+            Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
+            
+            ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+        }
     }
+    
+    DereferenceObject(Connection);
 
-    return v;
+    DbgPrint("[IP, TCPSendEventHandler] Leaving\n");
 }
 
-void TCPFree( void *ClientData,
-          void *data, OSK_PCHAR File, OSK_UINT Line ) {
-    ULONG Signature;
-
-    data = (void *)((char *) data - sizeof(ULONG));
-    Signature = *((ULONG *) data);
-    if ( SIGNATURE_SMALL == Signature ) {
-    ExFreeToNPagedLookasideList( &SmallLookasideList, data );
-    } else if ( SIGNATURE_LARGE == Signature ) {
-    ExFreeToNPagedLookasideList( &LargeLookasideList, data );
-    } else if ( SIGNATURE_OTHER == Signature ) {
-    ExFreePoolWithTag( data, OSK_OTHER_TAG );
-    } else {
-    ASSERT( FALSE );
+u32_t
+TCPRecvEventHandler(void *arg, struct pbuf *p)
+{
+    PCONNECTION_ENDPOINT Connection = arg;
+    PTCP_COMPLETION_ROUTINE Complete;
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    PIRP Irp;
+    PMDL Mdl;
+    UINT Received = 0;
+    UINT RecvLen;
+    PUCHAR RecvBuffer;
+    
+    ASSERT(p);
+    
+    ReferenceObject(Connection);
+    
+    DbgPrint("[IP, TCPRecvEventHandler] Called\n");
+    
+    if ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
+    {
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+        Irp = Bucket->Request.RequestContext;
+        Mdl = Irp->MdlAddress;
+        
+        TI_DbgPrint(DEBUG_TCP,
+                    ("[IP, TCPRecvEventHandler] Getting the user buffer from %x\n", Mdl));
+        
+        NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
+        
+        TI_DbgPrint(DEBUG_TCP,
+                    ("[IP, TCPRecvEventHandler] Reading %d bytes to %x\n", RecvLen, RecvBuffer));
+        
+        TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
+        TI_DbgPrint
+        (DEBUG_TCP,
+         ("[IP, TCPRecvEventHandler] Connection->SocketContext: %x\n",
+          Connection->SocketContext));
+        TI_DbgPrint(DEBUG_TCP, ("[IP, TCPRecvEventHandler] RecvBuffer: %x\n", RecvBuffer));
+        
+        RecvLen = MIN(p->tot_len, RecvLen);
+        
+        for (Received = 0; Received < RecvLen; Received += p->len, p = p->next)
+        {
+            DbgPrint("[IP, TCPRecvEventHandler] 0x%x: Copying %d bytes to 0x%x from 0x%x\n",
+                p, p->len, ((PUCHAR)RecvBuffer) + Received, p->payload);
+            
+            RtlCopyMemory(RecvBuffer + Received, p->payload, p->len);
+        }
+        
+        TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
+        
+        Bucket->Status = STATUS_SUCCESS;
+        Bucket->Information = Received;
+        
+        Complete = Bucket->Request.RequestNotifyObject;
+        
+        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
+        
+        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
     }
+
+    DereferenceObject(Connection);
+
+    DbgPrint("[IP, TCPRecvEventHandler] Leaving\n");
+    
+    return Received;
 }
 
-void
-TCPMemShutdown( void )
+VOID
+TCPConnectEventHandler(void *arg, err_t err)
 {
-    ExDeleteNPagedLookasideList( &SmallLookasideList );
-    ExDeleteNPagedLookasideList( &LargeLookasideList );
+    PCONNECTION_ENDPOINT Connection = arg;
+    PTCP_COMPLETION_ROUTINE Complete;
+    PTDI_BUCKET Bucket;
+    PLIST_ENTRY Entry;
+    
+    DbgPrint("[IP, TCPConnectEventHandler] Called\n");
+    
+    ReferenceObject(Connection);
+    
+    while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
+    {
+        
+        Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+        
+        Bucket->Status = TCPTranslateError(err);
+        Bucket->Information = 0;
+        
+        DbgPrint("[IP, TCPConnectEventHandler] Completing connection request! (0x%x)\n", err);
+        
+        Complete = Bucket->Request.RequestNotifyObject;
+        
+        Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
+        
+        ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+    }
+
+    DbgPrint("[IP, TCPConnectEventHandler] Done\n");
+    
+    DereferenceObject(Connection);
 }
index c12bc45..22a94ac 100644 (file)
-/*
- * Copyright (c) 1997-1998 University of Utah and the Flux Group.
- * All rights reserved.
- *
- * This file is part of the Flux OSKit.  The OSKit is free software, also known
- * as "open source;" you can redistribute it and/or modify it under the terms
- * of the GNU General Public License (GPL), version 2, as published by the Free
- * Software Foundation (FSF).  To explore alternate licensing terms, contact
- * the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271.
- *
- * The OSKit is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE.  See the GPL for more details.  You should have
- * received a copy of the GPL along with the OSKit; see the file COPYING.  If
- * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA.
- */
 
 #include "precomp.h"
 
-int if_index = 0;
-struct ifaddr **ifnet_addrs;
+#include "lwip/pbuf.h"
+#include "lwip/netifapi.h"
+#include "lwip/ip.h"
+#include "lwip/api.h"
+#include "lwip/tcpip.h"
 
-int    ifqmaxlen = OSK_IFQ_MAXLEN;
-struct ifnet *ifnet;
-
-/*
- * Network interface utility routines.
- *
- * Routines with ifa_ifwith* names take sockaddr *'s as
- * parameters.
- */
-
-POSK_IFADDR TCPGetInterfaceData( PIP_INTERFACE IF ) {
-    NTSTATUS Status;
-    POSK_IFADDR ifaddr = IF->TCPContext;
-    struct sockaddr_in *addr_in;
-    struct sockaddr_in *dstaddr_in;
-    struct sockaddr_in *netmask_in;
-    ASSERT(ifaddr);
-
-    RtlZeroMemory(ifaddr, sizeof(OSK_IFADDR) + 3 * sizeof( struct sockaddr_in ));
-
-    addr_in = (struct sockaddr_in *)&ifaddr[1];
-    dstaddr_in = (struct sockaddr_in *)&addr_in[1];
-    netmask_in = (struct sockaddr_in *)&dstaddr_in[1];
-
-    TI_DbgPrint(DEBUG_TCPIF,("Called\n"));
-
-    ifaddr->ifa_addr = (struct sockaddr *)addr_in;
-    Status = GetInterfaceIPv4Address( IF,
-                      ADE_UNICAST,
-                      (PULONG)&addr_in->sin_addr.s_addr );
-
-    ASSERT(NT_SUCCESS(Status));
-
-    ifaddr->ifa_dstaddr = (struct sockaddr *)dstaddr_in;
-    Status = GetInterfaceIPv4Address(IF,
-                                     ADE_POINTOPOINT,
-                                     (PULONG)&dstaddr_in->sin_addr.s_addr );
-
-    ASSERT(NT_SUCCESS(Status));
-    
-    ifaddr->ifa_netmask = (struct sockaddr *)netmask_in;
-    Status = GetInterfaceIPv4Address(IF,
-                                     ADE_ADDRMASK,
-                                     (PULONG)&netmask_in->sin_addr.s_addr );
-    
-    ASSERT(NT_SUCCESS(Status));
-
-    TI_DbgPrint(DEBUG_TCPIF,("interface %x : addr %x\n",
-               IF, addr_in->sin_addr.s_addr));
-
-    ifaddr->ifa_flags = 0;
-    ifaddr->ifa_refcnt = 0; /* Anachronistic */
-    ifaddr->ifa_metric = 1; /* We can get it like in ninfo.c, if we want */
-    ifaddr->ifa_mtu = IF->MTU;
-
-    TI_DbgPrint(DEBUG_TCPIF,("Leaving\n"));
-
-    return ifaddr;
+void TCPPacketSendComplete(PVOID Context, PNDIS_PACKET NdisPacket, NDIS_STATUS NdisStatus)
+{
+    FreeNdisPacket(NdisPacket);
 }
 
-POSK_IFADDR TCPFindInterface( void *ClientData,
-                  OSK_UINT AddrType,
-                  OSK_UINT FindType,
-                  OSK_SOCKADDR *ReqAddr,
-                  OSK_IFADDR *Interface ) {
+err_t
+TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest)
+{
+    NDIS_STATUS NdisStatus;
     PNEIGHBOR_CACHE_ENTRY NCE;
-    IP_ADDRESS Destination;
-    struct sockaddr_in *addr_in = (struct sockaddr_in *)ReqAddr;
-    POSK_IFADDR InterfaceData;
-
-    TI_DbgPrint(DEBUG_TCPIF,("called for type %d\n", FindType));
-
-    if( !ReqAddr ) {
-    TI_DbgPrint(DEBUG_TCPIF,("no addr or no ifaddr (%x)\n", ReqAddr));
-    return NULL;
+    IP_PACKET Packet = { 0 };
+    IP_ADDRESS RemoteAddress, LocalAddress;
+    PIPv4_HEADER Header;
+    UINT i;
+    struct pbuf *p1;
+    
+    /* The caller frees the pbuf struct */
+    
+    DbgPrint("[IP, TCPSendDataCallback] Sending data out on %c%c\n", netif->name[0], netif->name[1]);
+    
+    if (((*(u8_t*)p->payload) & 0xF0) == 0x40)
+    {
+        Header = p->payload;
+        
+        LocalAddress.Type = IP_ADDRESS_V4;
+        LocalAddress.Address.IPv4Address = Header->SrcAddr;
+        
+        RemoteAddress.Type = IP_ADDRESS_V4;
+        RemoteAddress.Address.IPv4Address = Header->DstAddr;
+    }
+    else 
+    {
+        return EINVAL;
     }
 
-    Destination.Type = IP_ADDRESS_V4;
-    Destination.Address.IPv4Address = addr_in->sin_addr.s_addr;
+    if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
+    {
+        return EINVAL;
+    }
+    
+    NdisStatus = AllocatePacketWithBuffer(&Packet.NdisPacket, NULL, p->tot_len);
+    if (NdisStatus != NDIS_STATUS_SUCCESS)
+    {
+        return ENOBUFS;
+    }
+    
+    GetDataPtr(Packet.NdisPacket, 0, (PCHAR*)&Packet.Header, &Packet.ContigSize);
+    
+    for (i = 0, p1 = p; i < p->tot_len; i += p1->len, p1 = p1->next)
+    {
+        ASSERT(p1);
+        RtlCopyMemory(((PUCHAR)Packet.Header) + i, p1->payload, p1->len);
+    }
+    
+    Packet.HeaderSize = sizeof(IPv4_HEADER);
+    Packet.TotalSize = p->tot_len;
+    Packet.SrcAddr = LocalAddress;
+    Packet.DstAddr = RemoteAddress;
+    
+    if (!NT_SUCCESS(IPSendDatagram(&Packet, NCE, TCPPacketSendComplete, NULL)))
+    {
+        FreeNdisPacket(Packet.NdisPacket);
+        return EINVAL;
+    }
+    
+    return 0;
+}
 
-    TI_DbgPrint(DEBUG_TCPIF,("Address is %x\n", addr_in->sin_addr.s_addr));
+VOID
+TCPUpdateInterfaceLinkStatus(PIP_INTERFACE IF)
+{
+#if 0
+    ULONG OperationalStatus;
+    
+    GetInterfaceConnectionStatus(IF, &OperationalStatus);
+    
+    if (OperationalStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
+        netif_set_link_up(IF->TCPContext);
+    else
+        netif_set_link_down(IF->TCPContext);
+#endif
+}
 
-    NCE = RouteGetRouteToDestination(&Destination);
-    if (!NCE) return NULL;
+err_t
+TCPInterfaceInit(struct netif *netif)
+{
+    PIP_INTERFACE IF = netif->state;
+    
+    netif->hwaddr_len = IF->AddressLength;
+    RtlCopyMemory(netif->hwaddr, IF->Address, netif->hwaddr_len);
 
-    InterfaceData = TCPGetInterfaceData(NCE->Interface);
+    netif->output = TCPSendDataCallback;
+    netif->mtu = IF->MTU;
+    
+    netif->name[0] = 'e';
+    netif->name[1] = 'n';
+    
+    netif->flags |= NETIF_FLAG_BROADCAST;
+    
+    TCPUpdateInterfaceLinkStatus(IF);
+    
+    TCPUpdateInterfaceIPInformation(IF);
 
-    addr_in = (struct sockaddr_in *)
-    InterfaceData->ifa_addr;
+    return 0;
+}
 
-    TI_DbgPrint(DEBUG_TCPIF,("returning addr %x\n", addr_in->sin_addr.s_addr));
+VOID
+TCPRegisterInterface(PIP_INTERFACE IF)
+{
+    struct ip_addr ipaddr;
+    struct ip_addr netmask;
+    struct ip_addr gw;
+    
+    gw.addr = 0;
+    ipaddr.addr = 0;
+    netmask.addr = 0;
+    
+    IF->TCPContext = netif_add(IF->TCPContext, 
+                               &ipaddr,
+                               &netmask,
+                               &gw,
+                               IF,
+                               TCPInterfaceInit,
+                               tcpip_input);
+}
 
-    return InterfaceData;
+VOID
+TCPUnregisterInterface(PIP_INTERFACE IF)
+{
+    netif_remove(IF->TCPContext);
 }
 
+VOID
+TCPUpdateInterfaceIPInformation(PIP_INTERFACE IF)
+{
+    struct ip_addr ipaddr;
+    struct ip_addr netmask;
+    struct ip_addr gw;
+    
+    gw.addr = 0;
+    
+    GetInterfaceIPv4Address(IF,
+                            ADE_UNICAST,
+                            (PULONG)&ipaddr.addr);
+    
+    GetInterfaceIPv4Address(IF,
+                            ADE_ADDRMASK,
+                            (PULONG)&netmask.addr);
+    
+    netif_set_addr(IF->TCPContext, &ipaddr, &netmask, &gw);
+    
+    if (ipaddr.addr != 0)
+    {
+        netif_set_up(IF->TCPContext);
+        netif_set_default(IF->TCPContext);
+    }
+    else
+    {
+        netif_set_down(IF->TCPContext);
+    }
+}    
index e980f6b..d9967c1 100644 (file)
 
 LONG TCP_IPIdentification = 0;
 static BOOLEAN TCPInitialized = FALSE;
-static NPAGED_LOOKASIDE_LIST TCPSegmentList;
 PORT_SET TCPPorts;
-CLIENT_DATA ClientInfo;
 
-VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
-{
-        PTDI_BUCKET Bucket;
-        PLIST_ENTRY Entry;
-        NTSTATUS Status;
-        PIRP Irp;
-        PMDL Mdl;
-        KIRQL OldIrql;
-        PTCP_COMPLETION_ROUTINE Complete;
-
-        if (ClientInfo.Unlocked)
-            LockObjectAtDpcLevel(Connection);
-
-        TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
-                               Connection, Connection->SocketContext));
-
-        /* Things that can happen when we try the initial connection */
-        if( Connection->SignalState & (SEL_CONNECT | SEL_FIN) ) {
-            while (!IsListEmpty(&Connection->ConnectRequest)) {
-               Entry = RemoveHeadList( &Connection->ConnectRequest );
-
-               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-               Bucket->Status = (Connection->SignalState & SEL_CONNECT) ? STATUS_SUCCESS : STATUS_CANCELLED;
-               Bucket->Information = 0;
-
-               InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
-           }
-       }
-
-       if( Connection->SignalState & (SEL_ACCEPT | SEL_FIN) ) {
-           /* Handle readable on a listening socket --
-            * TODO: Implement filtering
-            */
-           TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
-                                  Connection,
-                                  IsListEmpty(&Connection->ListenRequest) ?
-                                  "empty" : "nonempty"));
-
-           while (!IsListEmpty(&Connection->ListenRequest)) {
-               PIO_STACK_LOCATION IrpSp;
-
-               Entry = RemoveHeadList( &Connection->ListenRequest );
-
-               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-               Irp = Bucket->Request.RequestContext;
-               IrpSp = IoGetCurrentIrpStackLocation( Irp );
-
-               TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
+#include "lwip/pbuf.h"
+#include "lwip/ip.h"
+#include "lwip/init.h"
+#include "lwip/arch.h"
 
-               Status = TCPServiceListeningSocket
-                   ( Connection->AddressFile->Listener,
-                     Bucket->AssociatedEndpoint,
-                     (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
+#include "rosip.h"
 
-               TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
-
-               if( Status == STATUS_PENDING && !(Connection->SignalState & SEL_FIN) ) {
-                   InsertHeadList( &Connection->ListenRequest, &Bucket->Entry );
-                   break;
-               } else {
-                   Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED : Status;
-                   Bucket->Information = 0;
-                   DereferenceObject(Bucket->AssociatedEndpoint);
-
-                   InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
-               }
-          }
-      }
-
-      /* Things that happen after we're connected */
-      if( Connection->SignalState & (SEL_READ | SEL_FIN) ) {
-          TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
-                                 IsListEmpty(&Connection->ReceiveRequest) ?
-                                 "empty" : "nonempty"));
-
-           while (!IsListEmpty(&Connection->ReceiveRequest)) {
-               OSK_UINT RecvLen = 0, Received = 0;
-               PVOID RecvBuffer = 0;
-
-               Entry = RemoveHeadList( &Connection->ReceiveRequest );
-
-               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-               Irp = Bucket->Request.RequestContext;
-               Mdl = Irp->MdlAddress;
-
-               TI_DbgPrint(DEBUG_TCP,
-                           ("Getting the user buffer from %x\n", Mdl));
-
-               NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
-
-               TI_DbgPrint(DEBUG_TCP,
-                           ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
-
-               TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
-               TI_DbgPrint
-                   (DEBUG_TCP,
-                    ("Connection->SocketContext: %x\n",
-                     Connection->SocketContext));
-               TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
-
-               Status = TCPTranslateError
-                    ( OskitTCPRecv( Connection->SocketContext,
-                                    RecvBuffer,
-                                    RecvLen,
-                                    &Received,
-                                    0 ) );
-
-               TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
-
-               if( Status == STATUS_PENDING && !(Connection->SignalState & SEL_FIN) ) {
-                   InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
-                   break;
-               } else {
-                   TI_DbgPrint(DEBUG_TCP,
-                               ("Completing Receive request: %x %x\n",
-                                Bucket->Request, Status));
-
-                   Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED : Status;
-                   Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? Received : 0;
-
-                   InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
-               }
-           }
-       }
-       if( Connection->SignalState & (SEL_WRITE | SEL_FIN) ) {
-           TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
-                                  IsListEmpty(&Connection->SendRequest) ?
-                                  "empty" : "nonempty"));
-
-           while (!IsListEmpty(&Connection->SendRequest)) {
-               OSK_UINT SendLen = 0, Sent = 0;
-               PVOID SendBuffer = 0;
-
-               Entry = RemoveHeadList( &Connection->SendRequest );
-
-               Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
-               Irp = Bucket->Request.RequestContext;
-               Mdl = Irp->MdlAddress;
-
-               TI_DbgPrint(DEBUG_TCP,
-                           ("Getting the user buffer from %x\n", Mdl));
-
-               NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
-
-               TI_DbgPrint(DEBUG_TCP,
-                           ("Writing %d bytes to %x\n", SendLen, SendBuffer));
-
-               TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
-               TI_DbgPrint
-                (DEBUG_TCP,
-                 ("Connection->SocketContext: %x\n",
-                  Connection->SocketContext));
-
-               Status = TCPTranslateError
-                   ( OskitTCPSend( Connection->SocketContext,
-                                   SendBuffer,
-                                   SendLen,
-                                   &Sent,
-                                   0 ) );
-
-               TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
-
-               if( Status == STATUS_PENDING && !(Connection->SignalState & SEL_FIN) ) {
-                   InsertHeadList( &Connection->SendRequest, &Bucket->Entry );
-                   break;
-               } else {
-                   TI_DbgPrint(DEBUG_TCP,
-                               ("Completing Send request: %x %x\n",
-                               Bucket->Request, Status));
-
-                   Bucket->Status = (Status == STATUS_PENDING) ? STATUS_CANCELLED : Status;
-                   Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? Sent : 0;
-
-                   InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
-               }
-           }
-       }
-
-       ReferenceObject(Connection);
-       if (ClientInfo.Unlocked)
-       {
-           UnlockObjectFromDpcLevel(Connection);
-           KeReleaseSpinLock(&ClientInfo.Lock, ClientInfo.OldIrql);
-       }
-       else
-       {
-           UnlockObject(Connection, Connection->OldIrql);
-       }
-
-       while ((Entry = ExInterlockedRemoveHeadList(&Connection->CompletionQueue,
-                                                   &Connection->Lock)))
-       {
-           Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
-           Complete = Bucket->Request.RequestNotifyObject;
-
-           Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-
-           ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
-       }
-
-       if (!ClientInfo.Unlocked)
-       {
-           LockObject(Connection, &OldIrql);
-       }
-       else
-       {
-           KeAcquireSpinLock(&ClientInfo.Lock, &ClientInfo.OldIrql);
-       }
-       DereferenceObject(Connection);
-
-       /* If the socket is dead, remove the reference we added for oskit */
-       if (Connection->SignalState & SEL_FIN)
-       {
-           Connection->SocketContext = NULL;
-           DereferenceObject(Connection);
-       }
-}
-
-VOID ConnectionFree(PVOID Object) {
+VOID ConnectionFree(PVOID Object)
+{
     PCONNECTION_ENDPOINT Connection = Object;
     KIRQL OldIrql;
 
     TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
+    
+    DbgPrint("CONNECTION ENDPOINT: Freeing 0x%x\n", Object);
 
     TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
     RemoveEntryList(&Connection->ListEntry);
@@ -253,7 +39,8 @@ VOID ConnectionFree(PVOID Object) {
     ExFreePoolWithTag( Connection, CONN_ENDPT_TAG );
 }
 
-PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
+PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext )
+{
     PCONNECTION_ENDPOINT Connection =
         ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT),
                               CONN_ENDPT_TAG);
@@ -270,13 +57,11 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
     InitializeListHead(&Connection->ListenRequest);
     InitializeListHead(&Connection->ReceiveRequest);
     InitializeListHead(&Connection->SendRequest);
-    InitializeListHead(&Connection->CompletionQueue);
 
     /* Save client context pointer */
     Connection->ClientContext = ClientContext;
 
-    /* Add an extra reference for oskit */
-    Connection->RefCount = 2;
+    Connection->RefCount = 1;
     Connection->Free = ConnectionFree;
 
     /* Add connection endpoint to global list */
@@ -288,29 +73,31 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
 }
 
 NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
-                    UINT Family, UINT Type, UINT Proto ) {
+                    UINT Family, UINT Type, UINT Proto )
+{
     NTSTATUS Status;
     KIRQL OldIrql;
 
     LockObject(Connection, &OldIrql);
 
-    TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, "
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Called: Connection %x, Family %d, Type %d, "
                            "Proto %d\n",
                            Connection, Family, Type, Proto));
+    DbgPrint("[IP, TCPSocket] Called: Connection %x, Family %d, Type %d, "
+                           "Proto %d\n",
+                           Connection, Family, Type, Proto);
 
-    Status = TCPTranslateError( OskitTCPSocket( Connection,
-                                                &Connection->SocketContext,
-                                                Family,
-                                                Type,
-                                                Proto ) );
-
-    ASSERT_KM_POINTER(Connection->SocketContext);
-
-    TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
-                           Connection->SocketContext));
+    Connection->SocketContext = LibTCPSocket(Connection);
+    if (Connection->SocketContext)
+        Status = STATUS_SUCCESS;
+    else
+        Status = STATUS_INSUFFICIENT_RESOURCES;
 
     UnlockObject(Connection, OldIrql);
 
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Leaving. Status = 0x%x\n", Status));
+    DbgPrint("[IP, TCPSocket] Leaving. Status = 0x%x\n", Status);
+
     return Status;
 }
 
@@ -323,110 +110,15 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
  *     This is the low level interface for receiving TCP data
  */
 {
-    KIRQL OldIrql;
+    DbgPrint("[IP, TCPReceive] Called. Got packet from network stack\n");
 
-    TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to oskit\n",
+    TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to lwIP\n",
                            IPPacket->TotalSize,
                            IPPacket->HeaderSize));
+    
+    LibIPInsertPacket(Interface->TCPContext, IPPacket->Header, IPPacket->TotalSize);
 
-    KeAcquireSpinLock(&ClientInfo.Lock, &OldIrql);
-    ClientInfo.Unlocked = TRUE;
-    ClientInfo.OldIrql = OldIrql;
-
-    OskitTCPReceiveDatagram( IPPacket->Header,
-                             IPPacket->TotalSize,
-                             IPPacket->HeaderSize );
-
-    ClientInfo.Unlocked = FALSE;
-    KeReleaseSpinLock(&ClientInfo.Lock, OldIrql);
-}
-
-/* event.c */
-int TCPSocketState( void *ClientData,
-                    void *WhichSocket,
-                    void *WhichConnection,
-                    OSK_UINT NewState );
-
-int TCPPacketSend( void *ClientData,
-                   OSK_PCHAR Data,
-                   OSK_UINT Len );
-
-POSK_IFADDR TCPFindInterface( void *ClientData,
-                              OSK_UINT AddrType,
-                              OSK_UINT FindType,
-                              OSK_SOCKADDR *ReqAddr );
-
-NTSTATUS TCPMemStartup( void );
-void *TCPMalloc( void *ClientData,
-                 OSK_UINT bytes, OSK_PCHAR file, OSK_UINT line );
-void TCPFree( void *ClientData,
-              void *data, OSK_PCHAR file, OSK_UINT line );
-void TCPMemShutdown( void );
-
-OSKITTCP_EVENT_HANDLERS EventHandlers = {
-    NULL,             /* Client Data */
-    TCPSocketState,   /* SocketState */
-    TCPPacketSend,    /* PacketSend */
-    TCPFindInterface, /* FindInterface */
-    TCPMalloc,        /* Malloc */
-    TCPFree,          /* Free */
-    NULL,             /* Sleep */
-    NULL,             /* Wakeup */
-};
-
-static KEVENT TimerLoopEvent;
-static HANDLE TimerThreadHandle;
-
-/*
- * We are running 2 timers here, one with a 200ms interval (fast) and the other
- * with a 500ms interval (slow). So we need to time out at 200, 400, 500, 600,
- * 800, 1000 and process the "fast" events at 200, 400, 600, 800, 1000 and the
- * "slow" events at 500 and 1000.
- */
-static VOID NTAPI
-TimerThread(PVOID Context)
-{
-    LARGE_INTEGER Timeout;
-    NTSTATUS Status;
-    unsigned Current, NextFast, NextSlow, Next;
-
-    Current = 0;
-    Next = 0;
-    NextFast = 0;
-    NextSlow = 0;
-    while ( 1 ) {
-        if (Next == NextFast) {
-            NextFast += 2;
-       }
-        if (Next == NextSlow) {
-            NextSlow += 5;
-        }
-        Next = min(NextFast, NextSlow);
-        Timeout.QuadPart = (LONGLONG) (Next - Current) * -1000000; /* 100 ms */
-        Status = KeWaitForSingleObject(&TimerLoopEvent, Executive, KernelMode,
-                                       FALSE, &Timeout);
-        if (Status != STATUS_TIMEOUT) {
-            PsTerminateSystemThread(Status);
-        }
-
-        TimerOskitTCP( Next == NextFast, Next == NextSlow );
-
-        Current = Next;
-        if (10 <= Current) {
-            Current = 0;
-            Next = 0;
-            NextFast = 0;
-            NextSlow = 0;
-        }
-    }
-}
-
-static VOID
-StartTimer(VOID)
-{
-    KeInitializeEvent(&TimerLoopEvent, NotificationEvent, FALSE);
-    PsCreateSystemThread(&TimerThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0,
-                         TimerThread, NULL);
+    DbgPrint("[IP, TCPReceive] Leaving\n");
 }
 
 NTSTATUS TCPStartup(VOID)
@@ -438,37 +130,18 @@ NTSTATUS TCPStartup(VOID)
 {
     NTSTATUS Status;
 
-    Status = TCPMemStartup();
-    if ( ! NT_SUCCESS(Status) ) {
-        return Status;
-    }
-
     Status = PortsStartup( &TCPPorts, 1, 0xfffe );
-    if( !NT_SUCCESS(Status) ) {
-        TCPMemShutdown();
+    if( !NT_SUCCESS(Status) )
+    {
         return Status;
     }
-
-    KeInitializeSpinLock(&ClientInfo.Lock);
-    ClientInfo.Unlocked = FALSE;
-
-    RegisterOskitTCPEventHandlers( &EventHandlers );
-    InitOskitTCP();
-
+    
+    /* Initialize our IP library */
+    LibIPInitialize();
+    
     /* Register this protocol with IP layer */
     IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
-
-    ExInitializeNPagedLookasideList(
-        &TCPSegmentList,                /* Lookaside list */
-        NULL,                           /* Allocate routine */
-        NULL,                           /* Free routine */
-        0,                              /* Flags */
-        sizeof(TCP_SEGMENT),            /* Size of each entry */
-        'SPCT',                         /* Tag */
-        0);                             /* Depth */
-
-    StartTimer();
-
+    
     TCPInitialized = TRUE;
 
     return STATUS_SUCCESS;
@@ -482,59 +155,51 @@ NTSTATUS TCPShutdown(VOID)
  *     Status of operation
  */
 {
-    LARGE_INTEGER WaitForThread;
-
     if (!TCPInitialized)
         return STATUS_SUCCESS;
-
-    WaitForThread.QuadPart = -2500000; /* 250 ms */
-    KeSetEvent(&TimerLoopEvent, IO_NO_INCREMENT, FALSE);
-    ZwWaitForSingleObject(TimerThreadHandle, FALSE, &WaitForThread);
+    
+    LibIPShutdown();
 
     /* Deregister this protocol with IP layer */
     IPRegisterProtocol(IPPROTO_TCP, NULL);
 
-    ExDeleteNPagedLookasideList(&TCPSegmentList);
-
     TCPInitialized = FALSE;
 
-    DeinitOskitTCP();
-
     PortsShutdown( &TCPPorts );
 
-    TCPMemShutdown();
-
     return STATUS_SUCCESS;
 }
 
-NTSTATUS TCPTranslateError( int OskitError ) {
+NTSTATUS TCPTranslateError( err_t err )
+{
     NTSTATUS Status;
 
-    switch( OskitError ) {
-    case 0: Status = STATUS_SUCCESS; break;
-    case OSK_EADDRNOTAVAIL: Status = STATUS_INVALID_ADDRESS; break;
-    case OSK_EADDRINUSE: Status = STATUS_ADDRESS_ALREADY_EXISTS; break;
-    case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break;
-    case OSK_ECONNREFUSED: Status = STATUS_REMOTE_NOT_LISTENING; break;
-    case OSK_ECONNRESET: Status = STATUS_REMOTE_DISCONNECT; break;
-    case OSK_ECONNABORTED: Status = STATUS_LOCAL_DISCONNECT; break;
-    case OSK_EWOULDBLOCK:
-    case OSK_EINPROGRESS: Status = STATUS_PENDING; break;
-    case OSK_EINVAL: Status = STATUS_INVALID_PARAMETER; break;
-    case OSK_ENOMEM:
-    case OSK_ENOBUFS: Status = STATUS_INSUFFICIENT_RESOURCES; break;
-    case OSK_ESHUTDOWN: Status = STATUS_FILE_CLOSED; break;
-    case OSK_EMSGSIZE: Status = STATUS_BUFFER_TOO_SMALL; break;
-    case OSK_ETIMEDOUT: Status = STATUS_TIMEOUT; break;
-    case OSK_ENETUNREACH: Status = STATUS_NETWORK_UNREACHABLE; break;
-    case OSK_EFAULT: Status = STATUS_ACCESS_VIOLATION; break;
-    default:
-       DbgPrint("OskitTCP returned unhandled error code: %d\n", OskitError);
-       Status = STATUS_INVALID_CONNECTION;
-       break;
+    switch (err)
+    {
+        case ERR_OK: Status = STATUS_SUCCESS; break; //0
+        case ERR_MEM: Status = STATUS_INSUFFICIENT_RESOURCES; break; //-1
+        case ERR_BUF: Status = STATUS_BUFFER_TOO_SMALL; break; //-2
+        case ERR_TIMEOUT: Status = STATUS_TIMEOUT; break; // -3
+        case ERR_RTE: Status = STATUS_HOST_UNREACHABLE; break; //-4
+        case ERR_ABRT: Status = STATUS_LOCAL_DISCONNECT; break; //-5
+        case ERR_RST: Status = STATUS_REMOTE_DISCONNECT; break; //-6
+        case ERR_CLSD: Status = STATUS_FILE_CLOSED; break; //-7
+        case ERR_CONN: Status = STATUS_UNSUCCESSFUL; break; //-8 (FIXME)
+        case ERR_VAL: Status = STATUS_INVALID_PARAMETER; break; //-9
+        case ERR_ARG: Status = STATUS_INVALID_PARAMETER; break; //-10
+        case ERR_USE: Status = STATUS_ADDRESS_ALREADY_EXISTS; break; //-11
+        case ERR_IF: Status = STATUS_NETWORK_UNREACHABLE; break; //-12
+        case ERR_ISCONN: Status = STATUS_UNSUCCESSFUL; break; //-13 (FIXME)
+        case ERR_INPROGRESS: Status = STATUS_PENDING; break; //-14
+        default:
+            DbgPrint("Invalid error value: %d\n", err);
+            ASSERT(FALSE);
+            Status = STATUS_UNSUCCESSFUL;
+            break;
     }
-
-    TI_DbgPrint(DEBUG_TCP,("Error %d -> %x\n", OskitError, Status));
+    
+    DbgPrint("TCPTranslateError: %d -> %x\n", (unsigned int)err, Status);
+    
     return Status;
 }
 
@@ -543,23 +208,25 @@ NTSTATUS TCPConnect
   PTDI_CONNECTION_INFORMATION ConnInfo,
   PTDI_CONNECTION_INFORMATION ReturnInfo,
   PTCP_COMPLETION_ROUTINE Complete,
-  PVOID Context ) {
+  PVOID Context )
+{
     NTSTATUS Status;
-    SOCKADDR_IN AddressToConnect = { 0 }, AddressToBind = { 0 };
+    struct ip_addr bindaddr, connaddr;
     IP_ADDRESS RemoteAddress;
     USHORT RemotePort;
     PTDI_BUCKET Bucket;
     PNEIGHBOR_CACHE_ENTRY NCE;
     KIRQL OldIrql;
 
-    TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Called\n"));
 
     Status = AddrBuildAddress
         ((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress,
          &RemoteAddress,
          &RemotePort);
 
-    if (!NT_SUCCESS(Status)) {
+    if (!NT_SUCCESS(Status))
+    {
         TI_DbgPrint(DEBUG_TCP, ("Could not AddrBuildAddress in TCPConnect\n"));
         return Status;
     }
@@ -570,9 +237,6 @@ NTSTATUS TCPConnect
                  RemoteAddress.Address.IPv4Address,
                  RemotePort));
 
-    AddressToConnect.sin_family = AF_INET;
-    AddressToBind = AddressToConnect;
-
     LockObject(Connection, &OldIrql);
 
     if (!Connection->AddressFile)
@@ -589,28 +253,28 @@ NTSTATUS TCPConnect
             return STATUS_NETWORK_UNREACHABLE;
         }
 
-        AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
+        bindaddr.addr = NCE->Interface->Unicast.Address.IPv4Address;
     }
     else
     {
-        AddressToBind.sin_addr.s_addr = Connection->AddressFile->Address.Address.IPv4Address;
+        bindaddr.addr = Connection->AddressFile->Address.Address.IPv4Address;
     }
 
-    Status = TCPTranslateError
-        ( OskitTCPBind( Connection->SocketContext,
-                        &AddressToBind,
-                        sizeof(AddressToBind) ) );
-
-    if (NT_SUCCESS(Status)) {
-        memcpy( &AddressToConnect.sin_addr,
-                &RemoteAddress.Address.IPv4Address,
-                sizeof(AddressToConnect.sin_addr) );
-        AddressToConnect.sin_port = RemotePort;
+    Status = TCPTranslateError(LibTCPBind(Connection->SocketContext,
+                                          &bindaddr,
+                                          Connection->AddressFile->Port));
+    
+    DbgPrint("LibTCPBind: 0x%x\n", Status);
 
-        Status = TCPTranslateError
-            ( OskitTCPConnect( Connection->SocketContext,
-                               &AddressToConnect,
-                               sizeof(AddressToConnect) ) );
+    if (NT_SUCCESS(Status))
+    {
+        connaddr.addr = RemoteAddress.Address.IPv4Address;
+        
+        Status = TCPTranslateError(LibTCPConnect(Connection->SocketContext,
+                                                 &connaddr,
+                                                 RemotePort));
+        
+        DbgPrint("LibTCPConnect: 0x%x\n", Status);
 
         if (Status == STATUS_PENDING)
         {
@@ -630,6 +294,8 @@ NTSTATUS TCPConnect
 
     UnlockObject(Connection, OldIrql);
 
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPConnect] Leaving. Status = 0x%x\n", Status));
+
     return Status;
 }
 
@@ -639,23 +305,34 @@ NTSTATUS TCPDisconnect
   PTDI_CONNECTION_INFORMATION ConnInfo,
   PTDI_CONNECTION_INFORMATION ReturnInfo,
   PTCP_COMPLETION_ROUTINE Complete,
-  PVOID Context ) {
+  PVOID Context )
+{
     NTSTATUS Status = STATUS_INVALID_PARAMETER;
     KIRQL OldIrql;
 
-    TI_DbgPrint(DEBUG_TCP,("started\n"));
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Called\n"));
 
     LockObject(Connection, &OldIrql);
 
     if (Flags & TDI_DISCONNECT_RELEASE)
-        Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext));
+    {
+        /* FIXME */
+        LibTCPClose(Connection->SocketContext);
+    }
 
     if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
-        Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
+    {
+        /* FIXME */
+        LibTCPClose(Connection->SocketContext);
+    }
+    
+    Status = STATUS_SUCCESS;
+    
+    DbgPrint("LibTCPClose: %x\n", Status);
 
     UnlockObject(Connection, OldIrql);
 
-    TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status));
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPDisconnect] Leaving. Status = 0x%x\n", Status));
 
     return Status;
 }
@@ -664,7 +341,6 @@ NTSTATUS TCPClose
 ( PCONNECTION_ENDPOINT Connection )
 {
     KIRQL OldIrql;
-    NTSTATUS Status;
     PVOID Socket;
     PADDRESS_FILE AddressFile = NULL;
     PCONNECTION_ENDPOINT AddressConnection = NULL;
@@ -676,21 +352,9 @@ NTSTATUS TCPClose
     /* Don't try to close again if the other side closed us already */
     if (Socket)
     {
-       /* We need to close here otherwise oskit will never indicate
-        * SEL_FIN and we will never fully close the connection */
-       Status = TCPTranslateError( OskitTCPClose( Socket ) );
-
-       if (!NT_SUCCESS(Status))
-       {
-           Connection->SocketContext = Socket;
-           UnlockObject(Connection, OldIrql);
-           return Status;
-       }
-    }
-    else
-    {
-       /* We are already closed by the other end so return success */
-       Status = STATUS_SUCCESS;
+        LibTCPClose(Socket);
+        
+        FlushAllQueues(Connection, STATUS_CANCELLED);
     }
 
     if (Connection->AddressFile)
@@ -715,7 +379,7 @@ NTSTATUS TCPClose
     if (AddressFile)
         DereferenceObject(AddressFile);
 
-    return Status;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS TCPReceiveData
@@ -725,58 +389,38 @@ NTSTATUS TCPReceiveData
   PULONG BytesReceived,
   ULONG ReceiveFlags,
   PTCP_COMPLETION_ROUTINE Complete,
-  PVOID Context ) {
-    PVOID DataBuffer;
-    UINT DataLen, Received = 0;
-    NTSTATUS Status;
+  PVOID Context )
+{
     PTDI_BUCKET Bucket;
     KIRQL OldIrql;
 
-    TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Called for %d bytes (on socket %x)\n",
                            ReceiveLength, Connection->SocketContext));
 
-    NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
-
-    TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
-
     LockObject(Connection, &OldIrql);
+    
+    /* Freed in TCPSocketState */
+    Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
+    if( !Bucket )
+    {
+        TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Failed to allocate bucket\n"));
+        UnlockObject(Connection, OldIrql);
 
-    Status = TCPTranslateError
-        ( OskitTCPRecv
-          ( Connection->SocketContext,
-            DataBuffer,
-            DataLen,
-            &Received,
-            ReceiveFlags ) );
-
-    TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received));
-
-    /* Keep this request around ... there was no data yet */
-    if( Status == STATUS_PENDING ) {
-        /* Freed in TCPSocketState */
-        Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
-        if( !Bucket ) {
-            TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n"));
-            UnlockObject(Connection, OldIrql);
-            return STATUS_NO_MEMORY;
-        }
-
-        Bucket->Request.RequestNotifyObject = Complete;
-        Bucket->Request.RequestContext = Context;
-        *BytesReceived = 0;
-
-        InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry );
-        TI_DbgPrint(DEBUG_TCP,("Queued read irp\n"));
-    } else {
-        TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received));
-        *BytesReceived = Received;
+        return STATUS_NO_MEMORY;
     }
+    
+    Bucket->Request.RequestNotifyObject = Complete;
+    Bucket->Request.RequestContext = Context;
+    *BytesReceived = 0;
+    
+    InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry );
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Queued read irp\n"));
 
     UnlockObject(Connection, OldIrql);
 
-    TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Leaving. Status = STATUS_PENDING\n"));
 
-    return Status;
+    return STATUS_PENDING;
 }
 
 NTSTATUS TCPSendData
@@ -786,35 +430,38 @@ NTSTATUS TCPSendData
   PULONG BytesSent,
   ULONG Flags,
   PTCP_COMPLETION_ROUTINE Complete,
-  PVOID Context ) {
-    UINT Sent = 0;
+  PVOID Context )
+{
     NTSTATUS Status;
     PTDI_BUCKET Bucket;
     KIRQL OldIrql;
 
     LockObject(Connection, &OldIrql);
 
-    TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Called for %d bytes (on socket %x)\n",
                            SendLength, Connection->SocketContext));
 
-    TI_DbgPrint(DEBUG_TCP,("Connection = %x\n", Connection));
-    TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Connection = %x\n", Connection));
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Connection->SocketContext = %x\n",
                            Connection->SocketContext));
 
-    Status = TCPTranslateError
-        ( OskitTCPSend( Connection->SocketContext,
-                        (OSK_PCHAR)BufferData, SendLength,
-                        &Sent, 0 ) );
+    Status = TCPTranslateError(LibTCPSend(Connection->SocketContext,
+                                          BufferData,
+                                          SendLength));
+    
+    DbgPrint("[IP, TCPSendData] LibTCPSend: 0x%x\n", Status);
 
-    TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent));
+    TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Send: %x, %d\n", Status, SendLength));
 
     /* Keep this request around ... there was no data yet */
-    if( Status == STATUS_PENDING ) {
+    if( Status == STATUS_PENDING )
+    {
         /* Freed in TCPSocketState */
         Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
-        if( !Bucket ) {
+        if( !Bucket )
+        {
             UnlockObject(Connection, OldIrql);
-            TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n"));
+            TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Failed to allocate bucket\n"));
             return STATUS_NO_MEMORY;
         }
         
@@ -823,65 +470,84 @@ NTSTATUS TCPSendData
         *BytesSent = 0;
         
         InsertTailList( &Connection->SendRequest, &Bucket->Entry );
-        TI_DbgPrint(DEBUG_TCP,("Queued write irp\n"));
-    } else {
-        TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
-        *BytesSent = Sent;
+        TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Queued write irp\n"));
+    }
+    else
+    {
+        TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Got status %x, bytes %d\n",
+                    Status, SendLength));
+        *BytesSent = SendLength;
     }
 
     UnlockObject(Connection, OldIrql);
 
-    TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
+    TI_DbgPrint(DEBUG_TCP, ("[IP, TCPSendData] Leaving. Status = %x\n", Status));
 
     return Status;
 }
 
-UINT TCPAllocatePort( UINT HintPort ) {
-    if( HintPort ) {
-        if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort;
-        else {
+UINT TCPAllocatePort( UINT HintPort )
+{
+    if( HintPort )
+    {
+        if( AllocatePort( &TCPPorts, HintPort ) )
+            return HintPort;
+        else
+        {
             TI_DbgPrint
                 (MID_TRACE,("We got a hint port but couldn't allocate it\n"));
             return (UINT)-1;
         }
-    } else return AllocatePortFromRange( &TCPPorts, 1024, 5000 );
+    }
+    else
+        return AllocatePortFromRange( &TCPPorts, 1024, 5000 );
 }
 
-VOID TCPFreePort( UINT Port ) {
+VOID TCPFreePort( UINT Port )
+{
     DeallocatePort( &TCPPorts, Port );
 }
 
 NTSTATUS TCPGetSockAddress
 ( PCONNECTION_ENDPOINT Connection,
   PTRANSPORT_ADDRESS Address,
-  BOOLEAN GetRemote ) {
-    OSK_UINT LocalAddress, RemoteAddress;
-    OSK_UI16 LocalPort, RemotePort;
+  BOOLEAN GetRemote )
+{
     PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
+    struct ip_addr ipaddr;
     NTSTATUS Status;
     KIRQL OldIrql;
+    
+    AddressIP->TAAddressCount = 1;
+    AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
+    AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
 
     LockObject(Connection, &OldIrql);
 
-    Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext,
-                                                  &LocalAddress, &LocalPort,
-                                                  &RemoteAddress, &RemotePort));
+    if (GetRemote)
+    {
+        Status = TCPTranslateError(LibTCPGetPeerName(Connection->SocketContext,
+                                    &ipaddr,
+                                    &AddressIP->Address[0].Address[0].sin_port));
+    }
+    else
+    {
+        Status = TCPTranslateError(LibTCPGetHostName(Connection->SocketContext,
+                                    &ipaddr,
+                                    &AddressIP->Address[0].Address[0].sin_port));
+    }
 
     UnlockObject(Connection, OldIrql);
+    
+    AddressIP->Address[0].Address[0].in_addr = ipaddr.addr;
 
-    if (!NT_SUCCESS(Status))
-        return Status;
-
-    AddressIP->TAAddressCount = 1;
-    AddressIP->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
-    AddressIP->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
-    AddressIP->Address[0].Address[0].sin_port = GetRemote ? RemotePort : LocalPort;
-    AddressIP->Address[0].Address[0].in_addr = GetRemote ? RemoteAddress : LocalAddress;
+    DbgPrint("LibTCPGetXXXName: 0x%x\n", Status);
 
     return Status;
 }
 
-BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) {
+BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp )
+{
     PLIST_ENTRY Entry;
     PLIST_ENTRY ListHead[4];
     KIRQL OldIrql;
diff --git a/lib/drivers/lwip/CHANGELOG b/lib/drivers/lwip/CHANGELOG
new file mode 100644 (file)
index 0000000..d0e15f2
--- /dev/null
@@ -0,0 +1,2908 @@
+FUTURE
+
+  * TODO: The lwIP source code makes some invalid assumptions on processor
+    word-length, storage sizes and alignment. See the mailing lists for
+    problems with exoteric (/DSP) architectures showing these problems.
+    We still have to fix some of these issues neatly.
+
+HISTORY
+
+(CVS HEAD)
+
+  * [Enter new changes just after this line - do not remove this line]
+
+  ++ New features:
+
+  2010-07-12: Simon Goldschmidt (patch by Stephane Lesage)
+  * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for
+    IP_MULTICAST_LOOP at socket- and raw-API level.
+
+  2010-06-16: Simon Goldschmidt
+  * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow
+    link-layer-addressed UDP traffic to be received while a netif is down (just
+    like DHCP during configuration)
+
+  2010-05-22: Simon Goldschmidt
+  * many many files: bug #27352: removed packing from ip_addr_t, the packed
+    version is now only used in protocol headers. Added global storage for
+    current src/dest IP address while in input functions.
+
+  2010-05-16: Simon Goldschmidt
+  * def.h: task #10391: Add preprocessor-macros for compile-time htonl
+    calculation (and use them throughout the stack where applicable)
+
+  2010-05-16: Simon Goldschmidt
+  * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool
+    instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h)
+
+  2010-05-16: Simon Goldschmidt
+  * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own
+    MEMP pool instead of the heap
+
+  2010-05-13: Simon Goldschmidt
+  * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added
+    new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast
+    packets to more than one pcb.
+
+  2010-05-02: Simon Goldschmidt
+  * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending
+    UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1
+
+  2010-04-30: Simon Goldschmidt
+  * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that
+    take a precalculated checksum, added pbuf_fill_chksum() to copy data
+    into a pbuf and at the same time calculating the checksum for that data
+
+  2010-04-29: Simon Goldschmidt
+  * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying
+    2-byte-aligned IP addresses and MAC addresses
+
+  2010-04-28: Patch by Bill Auerbach
+  * ip.c: Inline generating IP checksum to save a function call
+
+  2010-04-14: Simon Goldschmidt
+  * tcpip.h/.c, timers.c: Added an overridable define to get informed when the
+    tcpip_thread processes messages or timeouts to implement a watchdog.
+
+  2010-03-28: Simon Goldschmidt
+  * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing
+    fragment if LWIP_NETIF_TX_SINGLE_PBUF==1
+
+  2010-03-27: Simon Goldschmidt
+  * etharp.c: Speedup TX by moving code from find_entry to etharp_output/
+    etharp_query to prevent unnecessary function calls (inspired by
+    patch #7135).
+
+  2010-03-20: Simon Goldschmidt
+  * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code
+    since the linker cannot do this automatically to save space.
+
+  2010-03-20: Simon Goldschmidt
+  * opt.h, etharp.c/.h: Added support for static ARP table entries
+
+  2010-03-14: Simon Goldschmidt
+  * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum
+    when creating TCP segments, not when (re-)transmitting them.
+
+  2010-03-07: Simon Goldschmidt
+  * sockets.c: bug #28775 (select/event_callback: only check select_cb_list
+    on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code.
+    This should speed up receiving data on sockets as the select code in
+    event_callback is only executed when select is waiting.
+
+  2010-03-06: Simon Goldschmidt
+  * tcp_out.c: task #7013 (Create option to have all packets delivered to
+    netif->output in one piece): Always copy to try to create single pbufs
+    in tcp_write.
+
+  2010-03-06: Simon Goldschmidt
+  * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv
+    by not allocating a netbuf): added function netconn_recv_tcp_pbuf()
+    for tcp netconns to receive pbufs, not netbufs; use that function
+    for tcp sockets.
+
+  2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt
+  * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040:
+    Work on tcp_enqueue: Don't waste memory when chaining segments,
+    added option TCP_OVERSIZE to prevent creating many small pbufs when
+    calling tcp_write with many small blocks of data. Instead, pbufs are
+    allocated larger than needed and the space is used for later calls to
+    tcp_write.
+
+  2010-02-21: Simon Goldschmidt
+  * stats.c/.h: Added const char* name to mem- and memp-stats for easier
+    debugging.
+
+  2010-02-21: Simon Goldschmidt
+  * tcp.h (and usages), added tcp_impl.h: Splitted API and internal
+    implementation of tcp to make API usage cleare to application programmers
+
+  2010-02-14: Simon Goldschmidt/Stephane Lesage
+  * ip_addr.h: Improved some defines working on ip addresses, added faster
+    macro to copy addresses that cannot be NULL
+
+  2010-02-13: Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non-
+    blocking send operation)
+
+  2010-02-12: Simon Goldschmidt
+  * sockets.c/.h: Added a minimal version of posix fctl() to have a
+    standardised way to set O_NONBLOCK for nonblocking sockets.
+
+  2010-02-12: Simon Goldschmidt
+  * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated
+    memory): added autoip_set_struct() and dhcp_set_struct() to let autoip
+    and dhcp work with user-allocated structs instead of callin mem_malloc
+
+  2010-02-12: Simon Goldschmidt/Jeff Barber
+  * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has
+    SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT
+
+  2010-02-12: Simon Goldschmidt
+  * sys layer: task #10139 (Prefer statically allocated memory): converted
+    mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t;
+    converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
+    task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX
+    to let sys.h use binary semaphores instead of mutexes - as before)
+
+  2010-02-09: Simon Goldschmidt (Simon Kallweit)
+  * timers.c/.h: Added function sys_restart_timeouts() from patch #7085
+    (Restart system timeout handling)
+
+  2010-02-09: Simon Goldschmidt
+  * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into
+    netif.c) - loopif does not have to be created by the port any more,
+    just define LWIP_HAVE_LOOPIF to 1.
+
+  2010-02-08: Simon Goldschmidt
+  * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa
+    inet_ntoa_r/ipaddr_ntoa_r
+
+  2010-02-08: Simon Goldschmidt
+  * netif.h: Added netif_s/get_igmp_mac_filter() macros
+
+  2010-02-05: Simon Goldschmidt
+  * netif.h: Added function-like macros to get/set the hostname on a netif
+
+  2010-02-04: Simon Goldschmidt
+  * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to
+    make changing the actual implementation behind the typedef easier.
+
+  2010-02-01: Simon Goldschmidt
+  * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool
+    for allocating memory when getaddrinfo() is called.
+
+  2010-01-31: Simon Goldschmidt
+  * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse
+    them once instead of parsing for every option. This also removes
+    the need for mem_malloc from dhcp_recv and makes it possible to
+    correctly retrieve the BOOTP file.
+
+  2010-01-30: simon Goldschmidt
+  * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect
+    the sockets array.
+
+  2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
+  * api.h, api_msg.c, sockets.c: Added except set support in select
+    (patch #6860)
+
+  2010-01-29: Simon Goldschmidt (patch by Laura Garrett)
+  * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c:
+    Add non-blocking support for connect (partly from patch #6860),
+    plus many cleanups in socket & netconn API.
+
+  2010-01-27: Simon Goldschmidt
+  * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding
+    to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605
+
+  2010-01-26: Simon Goldschmidt
+  * snmp: Use memp pools for snmp instead of the heap; added 4 new pools.
+
+  2010-01-14: Simon Goldschmidt
+  * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback
+    by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback()
+
+  2010-01-13: Simon Goldschmidt
+  * mem.c: The heap now may be moved to user-defined memory by defining
+    LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
+    (patch #6966 and bug #26133)
+
+  2010-01-10: Simon Goldschmidt (Bill Auerbach)
+  * opt.h, memp.c: patch #6822 (Add option to place memory pools in
+    separate arrays)
+
+  2010-01-10: Simon Goldschmidt
+  * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define
+    LWIP_RAND() for lwip-wide randomization (to be defined in cc.h)
+
+  2009-12-31: Simon Goldschmidt
+  * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h
+    added timers.c/.h: Separated timer implementation from semaphore/mbox
+    implementation, moved timer implementation to timers.c/.h, timers are
+    now only called from tcpip_thread or by explicitly checking them.
+    (TASK#7235)
+
+  2009-12-27: Simon Goldschmidt
+  * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option
+    LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE)
+
+
+  ++ Bugfixes:
+
+  2010-07-16: Kieran Mansley
+  * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator 
+
+  2010-07-10: Simon Goldschmidt
+  * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options
+
+  2010-06-30: Simon Goldschmidt
+  * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in
+    netconn_delete)
+
+  2010-06-28: Kieran Mansley
+  * timers.c remove unportable printing of C function pointers
+
+  2010-06-24: Simon Goldschmidt
+  * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag
+    NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading
+
+  2010-06-24: Simon Goldschmidt
+  * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly
+    implemented shutdown at socket level.
+
+  2010-06-21: Simon Goldschmidt
+  * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has
+    problems with zero-copy DMA MACs) by adding custom pbufs and implementing
+    custom pbufs that reference other (original) pbufs. Additionally set
+    IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side.
+
+  2010-06-15: Simon Goldschmidt
+  * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses
+
+  2010-06-14: Simon Goldschmidt
+  * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses
+
+  2010-06-12: Simon Goldschmidt
+  * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop
+    state
+
+  2010-05-17: Simon Goldschmidt
+  * netdb.c: Correctly NULL-terminate h_addr_list
+
+  2010-05-16: Simon Goldschmidt
+  * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent
+    "symbol already defined" i.e. when linking to winsock
+
+  2010-05-05: Simon Goldschmidt
+  * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may
+    overflow)
+
+  2010-04-21: Simon Goldschmidt
+  * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening
+    connection)
+
+  2010-03-28: Luca Ceresoli
+  * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers
+
+  2010-03-27: Luca Ceresoli
+  * mib2.c: patch #7130: remove meaningless const qualifiers
+
+  2010-03-26: Simon Goldschmidt
+  * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too
+
+  2010-03-26: Simon Goldschmidt
+  * various files: Fixed compiling with different options disabled (TCP/UDP),
+    triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled
+
+  2010-03-25: Simon Goldschmidt
+  * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly
+
+  2010-03-25: Simon Goldschmidt
+  * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side
+    overrunning our rcv_wnd in ooseq case.
+
+  2010-03-22: Simon Goldschmidt
+  * tcp.c: tcp_listen() did not copy the pcb's prio.
+
+  2010-03-19: Simon Goldschmidt
+  * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set
+
+  2010-03-14: Simon Goldschmidt
+  * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports
+    where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h
+    and basing PBUF_LINK_HLEN on it.
+
+  2010-03-08: Simon Goldschmidt
+  * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections
+    when assiging routable address): when checking incoming packets and
+    aborting existing connection on address change, filter out link-local
+    addresses.
+
+  2010-03-06: Simon Goldschmidt
+  * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING
+
+  2010-03-06: Simon Goldschmidt
+  * ipv4/ip.c: Don't try to forward link-local addresses
+
+  2010-03-06: Simon Goldschmidt
+  * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal-
+    addresses to gw
+
+  2010-03-05: Simon Goldschmidt
+  * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type
+    and state.
+
+  2010-03-05: Simon Goldschmidt
+  * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split
+    into multiple calls to tcp_write.    
+
+  2010-02-21: Simon Goldschmidt
+  * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep
+    the implementation of DNS_USES_STATIC_BUF==1)
+
+  2010-02-20: Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement
+    close() vs. shutdown(). Now the application does not get any more
+    recv callbacks after calling tcp_close(). Added tcp_shutdown().
+
+  2010-02-19: Simon Goldschmidt
+  * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent
+    confusion with realloc()
+
+  2010-02-15: Simon Goldschmidt/Stephane Lesage
+  * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK
+    (fixes bug #28899)
+
+  2010-02-14: Simon Goldschmidt
+  * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with
+    LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and
+    admin-status of a netif are up
+
+  2010-02-14: Simon Goldschmidt
+  * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet
+    reception and is not really necessary
+
+  2010-02-14: Simon Goldschmidt
+  * etharp.c/.h: Fixed ARP input processing: only add a new entry if a
+    request was directed as us (RFC 826, Packet Reception), otherwise
+    only update existing entries; internalized some functions
+
+  2010-02-14: Simon Goldschmidt
+  * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be
+    disabled on netif used for PPPoE) by adding a new netif flag
+    (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet
+    device but prevents usage of ARP (so that ethernet_input can be used
+    for PPPoE).
+
+  2010-02-12: Simon Goldschmidt
+  * netif.c: netif_set_link_up/down: only do something if the link state
+    actually changes
+
+  2010-02-12: Simon Goldschmidt/Stephane Lesage
+  * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking
+    connect)
+
+  2010-02-12: Simon Goldschmidt
+  * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h)
+
+  2010-02-09: Simon Goldschmidt
+  * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110
+   (recv() makes receive window update for data that wasn't received by
+    application)
+
+  2010-02-09: Simon Goldschmidt/Stephane Lesage
+  * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out
+    or any netconn_recv() error)
+
+  2010-02-09: Simon Goldschmidt
+  * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets)
+
+  2010-02-09: Simon Goldschmidt
+  * netif.c: For loopback packets, adjust the stats- and snmp-counters
+    for the loopback netif.
+
+  2010-02-08: Simon Goldschmidt
+  * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity
+    since they are not used anywhere else.
+
+  2010-02-08: Simon Goldschmidt (Stéphane Lesage)
+  * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats
+    (patch from bug #28798)
+
+  2010-02-08: Simon Goldschmidt (Stéphane Lesage)
+  * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and
+    another bug when LWIP_RAND() returns zero.
+
+  2010-02-04: Simon Goldschmidt
+  * nearly every file: Use macros defined in ip_addr.h (some of them new)
+    to work with IP addresses (preparation for bug #27352 - Change ip_addr
+    from struct to typedef (u32_t) - and better code).
+
+  2010-01-31: Simon Goldschmidt
+  * netif.c: Don't call the link-callback from netif_set_up/down() since
+    this invalidly retriggers DHCP.
+
+  2010-01-29: Simon Goldschmidt
+  * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the
+    portability file inet.h and its contents from the stack: moved htonX-
+    functions to def.h (and the new def.c - they are not ipv4 dependent),
+    let inet.h depend on ip_addr.h and not the other way round.
+    This fixes bug #28732.
+
+  2010-01-28: Kieran Mansley
+  * tcp.c: Ensure ssthresh >= 2*MSS
+
+  2010-01-27: Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv
+    callback can lead to accessing unallocated memory. As a consequence,
+    ERR_ABRT means the application has called tcp_abort()!
+
+  2010-01-25: Simon Goldschmidt
+  * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY
+    not implemented in SNMP): write-only or not-accessible are still
+    returned by getnext (though not by get)
+
+  2010-01-24: Simon Goldschmidt
+  * snmp: Renamed the private mib node from 'private' to 'mib_private' to
+    not use reserved C/C++ keywords
+
+  2010-01-23: Simon Goldschmidt
+  * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less
+    than 1 ms
+
+  2010-01-21: Simon Goldschmidt
+  * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called
+    if tcp_enqueue fails) both in raw- and netconn-API
+
+  2010-01-19: Simon Goldschmidt
+  * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp
+
+  2010-01-18: Iordan Neshev/Simon Goldschmidt
+  * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some
+    bugfix backports from 2.4.x.
+
+  2010-01-18: Simon Goldschmidt
+  * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong
+
+  2010-01-17: Simon Goldschmidt
+  * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c):
+    task #10102: "netconn: clean up conn->err threading issues" by adding
+    error return value to struct api_msg_msg
+
+  2010-01-17: Simon Goldschmidt
+  * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept()
+    to return err_t (bugs #27709 and #28087)
+
+  2010-01-14: Simon Goldschmidt
+  * ...: Use typedef for function prototypes throughout the stack.
+
+  2010-01-13: Simon Goldschmidt
+  * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive
+    window = 0) by correctly draining recvmbox/acceptmbox
+
+  2010-01-11: Simon Goldschmidt
+  * pap.c: Fixed bug #13315 (PPP PAP authentication can result in
+    erroneous callbacks) by copying the code from recent pppd
+
+  2010-01-10: Simon Goldschmidt
+  * raw.c: Fixed bug #28506 (raw_bind should filter received packets)
+
+  2010-01-10: Simon Goldschmidt
+  * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)())
+
+  2010-01-08: Simon Goldschmidt
+  * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535)
+
+  2010-01-08: Simon Goldschmidt
+  * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string
+    passed to dns_local_addhost() might be volatile
+
+  2010-01-07: Simon Goldschmidt
+  * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too
+
+  2010-01-06: Simon Goldschmidt
+  * netdb.h: Fixed bug #28496: missing include guards in netdb.h
+
+  2009-12-31: Simon Goldschmidt
+  * many ppp files: Reorganised PPP source code from ucip structure to pppd
+    structure to easily compare our code against the pppd code (around v2.3.1)
+
+  2009-12-27: Simon Goldschmidt
+  * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted
+    unit test
+
+
+(STABLE-1.3.2)
+
+  ++ New features:
+
+  2009-10-27 Simon Goldschmidt/Stephan Lesage
+  * netifapi.c/.h: Added netifapi_netif_set_addr()
+
+  2009-10-07 Simon Goldschmidt/Fabian Koch
+  * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to
+    support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO)
+
+  2009-08-26 Simon Goldschmidt/Simon Kallweit
+  * slipif.c/.h: bug #26397: SLIP polling support
+
+  2009-08-25 Simon Goldschmidt
+  * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN),
+    New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK.
+
+  2009-08-25 Simon Goldschmidt
+  * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*)
+
+  2009-08-24 Jakob Stoklund Olesen
+  * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond
+    to netif_set_link_up().
+
+  2009-08-23 Simon Goldschmidt
+  * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state
+    to a human-readable string.
+
+  ++ Bugfixes:
+
+  2009-12-24: Kieran Mansley
+  * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing
+    (BUG#28241)
+
+  2009-12-06: Simon Goldschmidt
+  * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can
+    be statically allocated (like in ucip)
+
+  2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev)
+  * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT
+
+  2009-12-03: Simon Goldschmidt
+  * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit
+    could have non-zero length
+
+  2009-12-02: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting
+    tcp_input_pcb until after calling the pcb's callbacks
+
+  2009-11-29: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of-
+    sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code
+
+  2009-11-29: Simon Goldschmidt
+  * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by
+    queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty
+
+  2009-11-26: Simon Goldschmidt
+  * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending
+    segment
+
+  2009-11-26: Simon Goldschmidt
+  * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle
+    algorithm at PCB level
+
+  2009-11-22: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent
+
+  2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach)
+  * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when
+    reusing time-wait pcb
+
+  2009-11-20: Simon Goldschmidt (patch by Albert Bartel)
+  * sockets.c: Fixed bug #28062: Data received directly after accepting
+    does not wake up select
+
+  2009-11-11: Simon Goldschmidt
+  * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo)
+
+  2009-10-30: Simon Goldschmidt
+  * opt.h: Increased default value for TCP_MSS to 536, updated default
+    value for TCP_WND to 4*TCP_MSS to keep delayed ACK working.
+
+  2009-10-28: Kieran Mansley
+  * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code
+    to follow algorithm from TCP/IP Illustrated
+
+  2009-10-27: Kieran Mansley
+  * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK
+
+  2009-10-25: Simon Goldschmidt
+  * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if
+    pcb->recv is NULL to keep rcv_wnd correct)
+
+  2009-10-25: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state
+
+  2009-10-23: Simon Goldschmidt (David Empson)
+  * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes
+
+  2009-10-21: Simon Goldschmidt
+  * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and
+    trailing 1 byte len (SYN/FIN)
+
+  2009-10-21: Simon Goldschmidt
+  * tcp_out.c: Fixed bug #27315: zero window probe and FIN
+
+  2009-10-19: Simon Goldschmidt
+  * dhcp.c/.h: Minor code simplification (don't store received pbuf, change
+    conditional code to assert where applicable), check pbuf length before
+    testing for valid reply
+
+  2009-10-19: Simon Goldschmidt
+  * dhcp.c: Removed most calls to udp_connect since they aren't necessary
+    when using udp_sendto_if() - always stay connected to IP_ADDR_ANY.
+
+  2009-10-16: Simon Goldschmidt
+  * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop
+    valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is
+    enabled
+
+  2009-10-15: Simon Goldschmidt (Oleg Tyshev)
+  * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit
+
+  2009-10-15: Simon Goldschmidt
+  * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv()
+    timeout
+
+  2009-10-15: Simon Goldschmidt
+  * autoip.c: Fixed bug #27704: autoip starts with wrong address
+    LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead
+    of network byte order
+
+  2009-10-11 Simon Goldschmidt (Jörg Kesten)
+  * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments
+    which are not consecutive when retransmitting unacked segments
+
+  2009-10-09 Simon Goldschmidt
+  * opt.h: Fixed default values of some stats to only be enabled if used
+    Fixes bug #27338: sys_stats is defined when NO_SYS = 1
+
+  2009-08-30 Simon Goldschmidt
+  * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK
+    function" by checking for loopback before calling ip_frag
+
+  2009-08-25 Simon Goldschmidt
+  * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0
+
+  2009-08-23 Simon Goldschmidt
+  * ppp.c: bug #27078: Possible memory leak in pppInit()
+
+  2009-08-23 Simon Goldschmidt
+  * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result
+    is error.
+
+  2009-08-23 Simon Goldschmidt
+  * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF
+    Fixed wrong parenthesis, added check in init.c
+
+  2009-08-23 Simon Goldschmidt
+  * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms
+
+  2009-08-23 Simon Goldschmidt
+  * many ppp files: bug #27267: Added include to string.h where needed
+
+  2009-08-23 Simon Goldschmidt
+  * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian)
+
+
+(STABLE-1.3.1)
+
+  ++ New features:
+
+  2009-05-10 Simon Goldschmidt
+  * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option
+    LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only
+    one pbuf to help MACs that don't support scatter-gather DMA.
+
+  2009-05-09 Simon Goldschmidt
+  * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming
+    ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN
+
+  2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen
+  * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive
+    extended info about the currently received packet.
+
+  2009-04-27 Simon Goldschmidt
+  * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1
+
+  2009-04-25 Simon Goldschmidt
+  * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next
+    bigger malloc pool if one is empty (only usable with MEM_USE_POOLS).
+
+  2009-04-21 Simon Goldschmidt
+  * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static
+    hosts table. New configuration options DNS_LOCAL_HOSTLIST and
+    DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined
+    as an external function for lookup.
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique
+
+  2009-03-31 Kieran Mansley
+  * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for
+    TCP timestamp options, off by default.  Rework tcp_enqueue() to
+    take option flags rather than specified option data
+
+  2009-02-18 Simon Goldschmidt
+  * cc.h: Added printf formatter for size_t: SZT_F
+
+  2009-02-16 Simon Goldschmidt (patch by Rishi Khan)
+  * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast
+    pings
+
+  2009-02-12 Simon Goldschmidt
+  * init.h: Added LWIP_VERSION to get the current version of the stack
+
+  2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler)
+  * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead
+    of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc
+    is otherwise used)
+
+  2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach)
+  * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial()
+  is only used by UDPLITE at present, so conditionalise it.
+
+  2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli)
+  * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP
+    "seed" address. This should reduce AUTOIP conflicts if
+    LWIP_AUTOIP_CREATE_SEED_ADDR is overridden.
+
+  2008-10-02 Jonathan Larmour and Rishi Khan
+  * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking
+    socket.
+
+  2008-06-30 Simon Goldschmidt
+  * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from
+    interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows
+    mem_free to run between mem_malloc iterations. Added illegal counter for
+    mem stats.
+
+  2008-06-27 Simon Goldschmidt
+  * stats.h/.c, some other files: patch #6483: stats module improvement:
+    Added defines to display each module's statistic individually, added stats
+    defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter.
+
+  2008-06-17 Simon Goldschmidt
+  * err.h: patch #6459: Made err_t overridable to use a more efficient type
+    (define LWIP_ERR_T in cc.h)
+
+  2008-06-17 Simon Goldschmidt
+  * slipif.c: patch #6480: Added a configuration option for slipif for symmetry
+    to loopif
+
+  2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli)
+  * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly
+    modified version of patch # 6370: Moved loopif code to netif.c so that
+    loopback traffic is supported on all netifs (all local IPs).
+    Added option to limit loopback packets for each netifs.
+
+
+  ++ Bugfixes:
+  2009-08-12 Kieran Mansley
+  * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when
+    out of window or out of order properly
+
+  2009-08-12 Kieran Mansley
+  * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1
+
+  2009-07-28 Simon Goldschmidt
+  * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s
+
+  2009-07-27 Kieran Mansley
+  * api.h api_msg.h netdb.h sockets.h: add missing #include directives
+
+  2009-07-09 Kieran Mansley
+  * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for
+    recv_avail and don't increment counters until message successfully
+    sent to mbox
+
+  2009-06-25 Kieran Mansley
+  * api_msg.c api.h: BUG26722: initialise netconn write variables 
+    in netconn_alloc
+
+  2009-06-25 Kieran Mansley
+  * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set
+
+  2009-06-25 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct
+    simultaneous close behaviour, and make snd_nxt have the same meaning 
+    as in the RFCs.
+
+  2009-05-12 Simon Goldschmidt
+  * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on
+    arp_table / uses etharp_query" by adding etharp_gratuitous()
+
+  2009-05-12 Simon Goldschmidt
+  * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options
+    to the IP header (used by igmp_ip_output_if)
+
+  2009-05-06 Simon Goldschmidt
+  * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if
+    defined) for SWAP_BYTES_IN_WORD to speed up checksumming.
+
+  2009-05-05 Simon Goldschmidt
+  * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select()
+    to crash
+
+  2009-05-04 Simon Goldschmidt
+  * init.c: snmp was not initialized in lwip_init()
+
+  2009-05-04 Frédéric Bernon
+  * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled.
+
+  2009-05-03 Simon Goldschmidt
+  * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full
+    (and unsent->next == NULL)
+
+  2009-05-02 Simon Goldschmidt
+  * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after
+    1.3.0 in CVS only) - fixes compilation of ppp_oe.c
+
+  2009-05-02 Simon Goldschmidt
+  * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields
+
+  2009-05-01 Simon Goldschmidt
+  * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets
+
+  2009-05-01 Simon Goldschmidt
+  * ppp.c: bug #24228: Memory corruption with PPP and DHCP
+
+  2009-04-29 Frédéric Bernon
+  * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the
+    SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception
+    of broadcast packets even when this option wasn't set. Port maintainers
+    which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h.
+    If you want this option also filter broadcast on recv operations, you also
+    have to set IP_SOF_BROADCAST_RECV=1 in opt.h.
+
+  2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen
+  * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and
+    DHCP/AUTOIP cooperation
+
+  2009-04-25 Simon Goldschmidt, Oleg Tyshev
+  * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd
+    Fixed by sorting the unsent and unacked queues (segments are inserted at the
+    right place in tcp_output and tcp_rexmit).
+
+  2009-04-25 Simon Goldschmidt
+  * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation
+    when debugging": memp_sizes contained the wrong sizes (including sanity
+    regions); memp pools for MEM_USE_POOLS were too small
+
+  2009-04-24 Simon Goldschmidt, Frédéric Bernon
+  * inet.c: patch #6765: Fix a small problem with the last changes (incorrect
+    behavior, with with ip address string not ended by a '\0', a space or a
+    end of line)
+
+  2009-04-19 Simon Goldschmidt
+  * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails,
+    pcb->err is called, not pcb->connected (with an error code).
+
+  2009-04-19 Simon Goldschmidt
+  * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with
+    no-copy-tcpwrite": deallocate option data, only concat segments with same flags
+
+  2009-04-19 Simon Goldschmidt
+  * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated
+    in the header pbuf, not the data pbuf)
+
+  2009-04-18 Simon Goldschmidt
+  * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore()
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in
+
+  2009-04-15 Simon Goldschmidt
+  * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function
+    ip_hinted_output() (for smaller code mainly)
+
+  2009-04-15 Simon Goldschmidt
+  * inet.c: patch #6765: Supporting new line characters in inet_aton()
+
+  2009-04-15 Simon Goldschmidt
+  * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option;
+    Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu
+    is big enough in dhcp_start
+
+  2009-04-15 Simon Goldschmidt
+  * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY
+
+  2009-04-15 Simon Goldschmidt
+  * sockets.c: bug #26121: set_errno can be overridden
+
+  2009-04-09 Kieran Mansley (patch from Luca Ceresoli <lucaceresoli>)
+  * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when
+    LWIP_TCP==0
+
+  2009-04-09 Kieran Mansley (patch from Roy Lee <roylee17>)
+  * tcp.h: Patch#6802 Add do-while-clauses to those function like
+    macros in tcp.h
+
+  2009-03-31 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window
+    updates are calculated and sent (BUG20515)
+
+  * tcp_in.c: cope with SYN packets received during established states,
+    and retransmission of initial SYN.
+
+  * tcp_out.c: set push bit correctly when tcp segments are merged
+
+  2009-03-27 Kieran Mansley
+  * tcp_out.c set window correctly on probes (correcting change made
+    yesterday)
+
+  2009-03-26 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping
+    connections where no reset required (bug #25622)
+
+  * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes 
+    (bug #20779)
+
+  2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach)
+  * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be
+    too small depending on MEM_ALIGNMENT
+
+  2009-02-16 Simon Goldschmidt
+  * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard;
+    converted size argument of netconn_write to 'size_t'
+
+  2009-02-16 Simon Goldschmidt
+  * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host
+    by moving accept callback function pointer to TCP_PCB_COMMON
+
+  2009-02-12 Simon Goldschmidt
+  * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size"
+    option)
+
+  2009-02-11 Simon Goldschmidt
+  * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start)
+
+  2009-02-11 Simon Goldschmidt
+  * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize:
+    RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv())
+
+  2009-02-10 Simon Goldschmidt
+  * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD:
+    Accepts_pending is decrease on a corresponding listen pcb when a connection
+    in state SYN_RCVD is close.
+
+  2009-01-28 Jonathan Larmour
+  * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run
+    out of pool pbufs.
+
+  2008-12-19 Simon Goldschmidt
+  * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 
+
+  2008-12-10 Tamas Somogyi, Frédéric Bernon
+  * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and
+    port uses deleted netbuf.
+
+  2008-10-18 Simon Goldschmidt
+  * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length
+    in tcp_parseopt
+
+  2008-10-15 Simon Goldschmidt
+  * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers
+    by packing the struct ip_reass_helper.
+
+  2008-10-03 David Woodhouse, Jonathan Larmour
+  * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address.
+
+  2008-10-02 Jonathan Larmour
+  * dns.c: Hard-code structure sizes, to avoid issues on some compilers where
+    padding is included.
+
+  2008-09-30 Jonathan Larmour
+  * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an
+    assertion check that addrlen isn't NULL.
+
+  2008-09-30 Jonathan Larmour
+  * tcp.c: Fix bug #24227, wrong error message in tcp_bind.
+
+  2008-08-26 Simon Goldschmidt
+  * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and
+    inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h
+
+  2008-08-14 Simon Goldschmidt
+  * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when
+    tcp_close returns != ERR_OK)
+
+  2008-07-08 Frédéric Bernon
+  * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters
+    in macros, mainly if MEM_STATS=0 and MEMP_STATS=0).
+
+  2008-06-24 Jonathan Larmour
+  * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused
+    if tcp_seg_copy fails.
+
+  2008-06-17 Simon Goldschmidt
+  * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations)
+    and created defines for swapping bytes and folding u32 to u16.
+
+  2008-05-30 Kieran Mansley
+  * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd
+    rather than rcv_ann_wnd when deciding if packets are in-window.
+    Contributed by <arasmussen@consultant.datasys.swri.edu>
+
+  2008-05-30 Kieran Mansley
+  * mem.h: Fix BUG#23254.  Change macro definition of mem_* to allow
+    passing as function pointers when MEM_LIBC_MALLOC is defined.
+
+  2008-05-09 Jonathan Larmour
+  * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to
+    stop it being treated as a fatal error.
+
+  2008-04-15 Simon Goldschmidt
+  * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP
+    (flag now cleared)
+
+  2008-03-27 Simon Goldschmidt
+  * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free
+    from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1
+    in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs
+    or heap memory from interrupt context
+
+  2008-03-26 Simon Goldschmidt
+  * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote
+    host sent a zero mss as TCP option.
+
+
+(STABLE-1.3.0)
+
+  ++ New features:
+
+  2008-03-10 Jonathan Larmour
+  * inet_chksum.c: Allow choice of one of the sample algorithms to be
+    made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM.
+
+  2008-01-22 Frédéric Bernon
+  * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in 
+    TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names.
+
+  2008-01-14 Frédéric Bernon
+  * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable
+    to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the
+    tcp_recv callback (see rawapi.txt).
+
+  2008-01-14 Frédéric Bernon, Marc Chaland
+  * ip.c: Integrate patch #6369" ip_input : checking before realloc".
+  
+  2008-01-12 Frédéric Bernon
+  * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field
+    netconn::sem per netconn::op_completed like suggested for the task #7490
+    "Add return value to sys_mbox_post".
+
+  2008-01-12 Frédéric Bernon
+  * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE,
+    DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues
+    sizes), like suggested for the task #7490 "Add return value to sys_mbox_post".
+
+  2008-01-10 Frédéric Bernon
+  * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490
+    "Add return value to sys_mbox_post". tcpip_callback is always defined as
+    "blocking" ("block" parameter = 1).
+
+  2008-01-10 Frédéric Bernon
+  * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field
+    netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490
+    "Add return value to sys_mbox_post".
+
+  2008-01-05 Frédéric Bernon
+  * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h:
+    Introduce changes for task #7490 "Add return value to sys_mbox_post" with some
+    modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which
+    indicate the number of pointers query by the mailbox. There is three defines
+    in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the 
+    netconn::acceptmbox. Port maintainers, you can decide to just add this new 
+    parameter in your implementation, but to ignore it to keep the previous behavior.
+    The new sys_mbox_trypost function return a value to know if the mailbox is
+    full or if the message is posted. Take a look to sys_arch.txt for more details.
+    This new function is used in tcpip_input (so, can be called in an interrupt
+    context since the function is not blocking), and in recv_udp and recv_raw.
+
+  2008-01-04 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour
+  * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c,
+    tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the
+    "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add
+    documentation in the rawapi.txt file.
+
+  2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer
+
+  2007-12-31 Frédéric Bernon, Luca Ceresoli
+  * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets
+    in autoip". The change in etharp_raw could be removed, since all calls to
+    etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be
+    wrong in the future.
+
+  2007-12-30 Frédéric Bernon, Tom Evans
+  * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address
+    Filtering" reported by Tom Evans.
+
+  2007-12-21 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour
+  * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c,
+    sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API
+    applications have to call 'tcp_accepted(pcb)' in their accept callback to
+    keep accepting new connections.
+
+  2007-12-13 Frédéric Bernon
+  * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result"
+    by err_t type. Add a new err_t code "ERR_INPROGRESS".
+
+  2007-12-12 Frédéric Bernon
+  * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles
+    are the one which have ram usage.
+
+  2007-12-05 Frédéric Bernon
+  * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static
+    set of variables (=0) or a local one (=1). In this last case, your port should
+    provide a function "struct hostent* sys_thread_hostent( struct hostent* h)"
+    which have to do a copy of "h" and return a pointer ont the "per-thread" copy.
+
+  2007-12-03 Simon Goldschmidt
+  * ip.c: ip_input: check if a packet is for inp first before checking all other
+    netifs on netif_list (speeds up packet receiving in most cases)
+
+  2007-11-30 Simon Goldschmidt
+  * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access
+    UDP: move a (connected) pcb selected for input to the front of the list of
+    pcbs so that it is found faster next time. Same for RAW pcbs that have eaten
+    a packet.
+
+  2007-11-28 Simon Goldschmidt
+  * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS
+
+  2007-11-25 Simon Goldschmidt
+  * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy
+    algorithm.
+
+  2007-11-24 Simon Goldschmidt
+  * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c
+    to the new file netdb.c; included lwip_getaddrinfo.
+
+  2007-11-21 Simon Goldschmidt
+  * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss
+    based on the MTU of the netif used to send. Enabled by default. Disable by
+    setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492.
+
+  2007-11-19 Frédéric Bernon
+  * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name
+    received match the name query), implement DNS_USES_STATIC_BUF (the place where
+    copy dns payload to parse the response), return an error if there is no place
+    for a new query, and fix some minor problems.
+
+  2007-11-16 Simon Goldschmidt
+  * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c
+    removed files: core/inet.c, core/inet6.c
+    Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into
+    inet and chksum part; changed includes in all lwIP files as appropriate
+
+  2007-11-16 Simon Goldschmidt
+  * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential
+    dns resolver function for netconn api (netconn_gethostbyname) and socket api
+    (gethostbyname/gethostbyname_r).
+
+  2007-11-15 Jim Pettinato, Frédéric Bernon
+  * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name
+    requests with RAW api interface. Initialization is done in lwip_init() with
+    build time options. DNS timer is added in tcpip_thread context. DHCP can set
+    DNS server ip addresses when options are received. You need to set LWIP_DNS=1
+    in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get
+    some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo"
+    list with points to improve.
+
+  2007-11-06 Simon Goldschmidt
+  * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly
+    enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status
+    for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined.
+
+  2007-11-06 Simon Goldschmidt
+  * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include
+    core header files in api.h (ip/tcp/udp/raw.h) to hide the internal
+    implementation from netconn api applications.
+
+  2007-11-03 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP &
+    RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled
+    by default). Netconn API users can use the netconn_recv_bufsize macro to access
+    it. This is a first release which have to be improve for TCP. Note it used the
+    netconn::recv_avail which need to be more "thread-safe" (note there is already
+    the problem for FIONREAD with lwip_ioctl/ioctlsocket).
+
+  2007-11-01 Frédéric Bernon, Marc Chaland
+  * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c:
+    Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api
+    layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api
+    layer. This option enable to delayed TCP PUSH flag on multiple "write" calls.
+    Note that previous "copy" parameter for "write" APIs is now called "apiflags".
+
+  2007-10-24 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than 
+    TCP_EVENT_xxx macros to get a code more readable. It could also help to remove
+    some code (like we have talk in "patch #5919 : Create compile switch to remove
+    select code"), but it could be done later.
+
+  2007-10-08 Simon Goldschmidt
+  * many files: Changed initialization: many init functions are not needed any
+    more since we now rely on the compiler initializing global and static
+    variables to zero!
+
+  2007-10-06 Simon Goldschmidt
+  * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY
+    to enqueue the received pbufs so that multiple packets can be reassembled
+    simultaneously and no static reassembly buffer is needed.
+
+  2007-10-05 Simon Goldschmidt
+  * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so
+    all netifs (or ports) can use it.
+
+  2007-10-05 Frédéric Bernon
+  * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the 
+    common function to reduce a little bit the footprint (for all functions using
+    only the "netif" parameter).
+
+  2007-10-03 Frédéric Bernon
+  * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down,
+    netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce
+    a little bit the footprint (for all functions using only the "netif" parameter).
+
+  2007-09-15 Frédéric Bernon
+  * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF
+    option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for
+    netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for
+    IP_MULTICAST_TTL and IP_MULTICAST_IF.
+
+  2007-09-10 Frédéric Bernon
+  * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles
+    even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime()
+    each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can
+    decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but
+    call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime()
+    or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro.
+    This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside
+    snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only
+    when it's queried (any direct call to "sysuptime" is changed by a call to 
+    snmp_get_sysuptime).
+
+  2007-09-09 Frédéric Bernon, Bill Florac
+  * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP,
+    and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags
+    if you want IGMP on an interface. igmp_stop() is now called inside netif_remove().
+    igmp_report_groups() is now called inside netif_set_link_up() (need to have
+    LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait
+    the next query message to receive the matching multicast streams).
+
+  2007-09-08 Frédéric Bernon
+  * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains
+    IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change).
+    Use this new field to access to common pcb fields (ttl, tos, so_options, etc...).
+    Enable to access to these fields with LWIP_TCP=0.
+
+  2007-09-05 Frédéric Bernon
+  * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h,
+    ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option
+    LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default).
+    Be careful, disabling ICMP make your product non-compliant to RFC1122, but
+    help to reduce footprint, and to reduce "visibility" on the Internet.
+
+  2007-09-05 Frédéric Bernon, Bill Florac
+  * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list
+    for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new
+    parameters have to be provided: a task name, and a task stack size. For this
+    one, since it's platform dependant, you could define the best one for you in
+    your lwipopts.h. For port maintainers, you can just add these new parameters
+    in your sys_arch.c file, and but it's not mandatory, use them in your OS
+    specific functions.
+
+  2007-09-05 Frédéric Bernon
+  * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings
+    inside init.c for task #7142 "Sanity check user-configurable values".
+
+  2007-09-04 Frédéric Bernon, Bill Florac
+  * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by
+    memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the
+    value). It will avoid potential fragmentation problems, use a counter to know
+    how many times a group is used on an netif, and free it when all applications
+    leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity
+    check if LWIP_IGMP!=0).
+
+  2007-09-03 Frédéric Bernon
+  * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement".
+    Initialize igmp_mac_filter to NULL in netif_add (this field should be set in
+    the netif's "init" function). Use the "imr_interface" field (for socket layer)
+    and/or the "interface" field (for netconn layer), for join/leave operations.
+    The igmp_join/leavegroup first parameter change from a netif to an ipaddr.
+    This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany).
+
+  2007-08-30 Frédéric Bernon
+  * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions
+    from api/api_lib". Now netbuf API is independant of netconn, and can be used
+    with other API (application based on raw API, or future "socket2" API). Ports
+    maintainers just have to add src/api/netbuf.c in their makefile/projects.
+
+  2007-08-30 Frédéric Bernon, Jonathan Larmour
+  * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check
+    user-configurable values".
+
+  2007-08-29 Frédéric Bernon
+  * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start.
+    igmp_start is call inside netif_add. Now, igmp initialization is in the same
+    spirit than the others modules. Modify some IGMP debug traces.
+
+  2007-08-29 Frédéric Bernon
+  * Add init.h, init.c, Change opt.h, tcpip.c: Task  #7213 "Add a lwip_init function"
+    Add lwip_init function to regroup all modules initializations, and to provide
+    a place to add code for task #7142 "Sanity check user-configurable values".
+    Ports maintainers should remove direct initializations calls from their code,
+    and add init.c in their makefiles. Note that lwip_init() function is called
+    inside tcpip_init, but can also be used by raw api users since all calls are
+    disabled when matching options are disabled. Also note that their is new options
+    in opt.h, you should configure in your lwipopts.h (they are enabled per default).
+
+  2007-08-26 Marc Boucher
+  * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL
+    since they can under certain circumstances be called with an invalid conn
+    pointer after the connection has been closed (and conn has been freed). 
+
+  2007-08-25 Frédéric Bernon (Artem Migaev's Patch)
+  * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up".
+    Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set.
+
+  2007-08-22 Frédéric Bernon
+  * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK
+    to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release.
+
+  2007-08-22 Frédéric Bernon
+  * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT &
+    ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the 
+    name is tcpip_input (we keep the name of 1.2.0 function).
+
+  2007-08-17 Jared Grubb
+  * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool 
+    settings into new memp_std.h and optional user file lwippools.h. This adds
+    more dynamic mempools, and allows the user to create an arbitrary number of
+    mempools for mem_malloc.
+
+  2007-08-16 Marc Boucher
+  * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function;
+    otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely
+    close the connection.
+
+  2007-08-16 Marc Boucher
+  * sockets.c: lwip_accept(): check netconn_peer() error return.
+
+  2007-08-16 Marc Boucher
+  * mem.c, mem.h: Added mem_calloc().
+
+  2007-08-16 Marc Boucher
+  * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT)
+    for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG
+    and starving other message types.
+    Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API
+
+  2007-08-16 Marc Boucher
+  * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf
+    type and flgs (later renamed to flags).
+    Use enum pbuf_flag as pbuf_type.  Renumber PBUF_FLAG_*.
+    Improved lwip_recvfrom().  TCP push now propagated.
+
+  2007-08-16 Marc Boucher
+  * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global
+    provided by etharp.
+
+  2007-08-16 Marc Boucher
+  * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h,
+    etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c:
+    Added PPPoE support and various PPP improvements.
+
+  2007-07-25 Simon Goldschmidt
+  * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial,
+    making netbuf_copy_partial use this function.
+
+  2007-07-25 Simon Goldschmidt
+  * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with
+    2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and
+    other stacks.
+
+  2007-07-13 Jared Grubb (integrated by Frédéric Bernon)
+  * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add
+    a link callback in the netif struct, and functions to handle it. Be carefull
+    for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c)
+    if you want to be sure to be compatible with future changes...
+
+  2007-06-30 Frédéric Bernon
+  * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions.
+
+  2007-06-21 Simon Goldschmidt
+  * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both
+    LWIP_AUTOIP =0 and =1 to remove redundant code.
+
+  2007-06-21 Simon Goldschmidt
+  * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option
+    MEM_USE_POOLS to use 4 pools with different sized elements instead of a
+    heap. This both prevents memory fragmentation and gives a higher speed
+    at the cost of more memory consumption. Turned off by default.
+
+  2007-06-21 Simon Goldschmidt
+  * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of
+    netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into
+    int to be able to send a bigger buffer than 64K with one time (mainly
+    used from lwip_send).
+
+  2007-06-21 Simon Goldschmidt
+  * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write
+    into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too.
+
+  2007-06-21 Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in
+    netconn_write from api_lib.c to api_msg.c to also prevent multiple context-
+    changes on low memory or empty send-buffer.
+
+  2007-06-18 Simon Goldschmidt
+  * etharp.c, etharp.h: Changed etharp to use a defined hardware address length
+    of 6 to avoid loading netif->hwaddr_len every time (since this file is only
+    used for ethernet and struct eth_addr already had a defined length of 6).
+
+  2007-06-17 Simon Goldschmidt
+  * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets
+    to disable UDP checksum generation on transmit.
+
+  2007-06-13 Frédéric Bernon, Simon Goldschmidt
+  * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid
+    pointers or parameters, and let the possibility to redefined it in cc.h. Use
+    this macro to check "conn" parameter in api_msg.c functions.
+
+  2007-06-11 Simon Goldschmidt
+  * sockets.c, sockets.h: Added UDP lite support for sockets
+
+  2007-06-10 Simon Goldschmidt
+  * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled
+    by default) to switch off UDP-Lite support if not needed (reduces udp.c code
+    size)
+
+  2007-06-09 Dominik Spies (integrated by Frédéric Bernon)
+  * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h:
+    AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and
+    LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt
+    (see TODO mark in the source code).
+
+  2007-06-09 Simon Goldschmidt
+  * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for
+    etharp_output() to match netif->output so etharp_output() can be used
+    directly as netif->output to save one function call.
+
+  2007-06-08 Simon Goldschmidt
+  * netif.h, ethernetif.c, slipif.c, loopif.c: Added define
+    NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables,
+    added initialization of those to ethernetif, slipif and loopif.
+
+  2007-05-18 Simon Goldschmidt
+  * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF
+    (defaulting to off for now) that can be set to 0 to send fragmented
+    packets by passing PBUF_REFs down the stack.
+
+  2007-05-23 Frédéric Bernon
+  * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP
+    connections, such present in patch #5959.
+
+  2007-05-23 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx
+    code in only one part...
+
+  2007-05-18 Simon Goldschmidt
+  * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp
+    elements to overflow. This is achieved by adding some bytes before and after
+    each pool element (increasing their size, of course), filling them with a
+    prominent value and checking them on freeing the element.
+    Set it to 2 to also check every element in every pool each time memp_malloc()
+    or memp_free() is called (slower but more helpful).
+
+  2007-05-10 Simon Goldschmidt
+  * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for
+    PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce
+    code size.
+
+  2007-05-11 Frédéric Bernon
+  * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c:
+    Include a function pointer instead of a table index in the message to reduce
+    footprint. Disable some part of lwip_send and lwip_sendto if some options are
+    not set (LWIP_TCP, LWIP_UDP, LWIP_RAW).
+
+  2007-05-10 Simon Goldschmidt
+  * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus
+    \ extern "C" {' in all header files. Now you can write your application using
+    the lwIP stack in C++ and simply #include the core files. Note I have left
+    out the netif/ppp/*h header files for now, since I don't know which files are
+    included by applications and which are for internal use only.
+
+  2007-05-09 Simon Goldschmidt
+  * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library
+    memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for
+    situations where some compilers might inline the copy and save a function
+    call. Also replaced all calls to memcpy() with calls to (S)MEMCPY().
+
+  2007-05-08 Simon Goldschmidt
+  * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc())
+    to be overriden in case the C-library malloc implementation is not protected
+    against concurrent access.
+
+  2007-05-04 Simon Goldschmidt (Atte Kojo)
+  * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending
+    multiple packets to the same host.
+
+  2007-05-04 Frédéric Bernon, Jonathan Larmour
+  * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible
+    to corrupt remote addr/port connection state". Reduce problems "not enought memory" with
+    netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between
+    sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function.
+    Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct,
+    these fields are now renamed "addr" & "port".
+
+  2007-04-11 Jonathan Larmour
+  * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new
+    sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return
+    with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro
+    by the port in sys_arch.h if desired.
+
+  2007-04-06 Frédéric Bernon, Simon Goldschmidt
+  * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API
+    allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp
+    clients, using new functions from netifapi.h. Disable as default (no port change to do).
+
+  2007-04-05 Frédéric Bernon
+  * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant.
+
+  2007-04-04 Simon Goldschmidt
+  * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x)
+    use this for and architecture-independent form to tell the compiler you intentionally
+    are not using this variable. Can be overriden in cc.h.
+
+  2007-03-28 Frédéric Bernon
+  * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to
+    define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded
+    string, point on one of your's ethernetif field, or alloc a string you will free yourself).
+    It will be used by DHCP to register a client hostname, but can also be use when you call
+    snmp_set_sysname.
+
+  2007-03-28 Frédéric Bernon
+  * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to 
+    initialize a network interface's flag with. It tell this interface is an ethernet
+    device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility
+    Support for IPv4" section 4.6) when interface is "up" with netif_set_up().
+
+  2007-03-26 Frédéric Bernon, Jonathan Larmour
+  * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build
+    time if you only use PPP or SLIP. The default is enable. Note we don't have to call 
+    etharp_init in your port's initilization sequence if you use tcpip.c, because this call
+    is done in tcpip_init function.
+
+  2007-03-22 Frédéric Bernon
+  * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the
+    new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in
+    your lwipopts.h. More, unused counters are not defined in the stats structs, and not 
+    display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined
+    but never used. Fix msg_in.c with the correct #if test for a stat display.
+
+  2007-03-21 Kieran Mansley
+  * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). 
+    Provides callback on netif up/down state change.
+
+  2007-03-11 Frédéric Bernon, Mace Gael, Steve Reynolds
+  * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c,
+    ip.c, netif.h, tcpip.c, opt.h:
+    New configuration option LWIP_IGMP to enable IGMP processing. Based on only one 
+    filter per all network interfaces. Declare a new function in netif to enable to
+    control the MAC filter (to reduce lwIP traffic processing).
+
+  2007-03-11 Frédéric Bernon
+  * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can
+    be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this
+    unless you know what you're doing (default are RFC1122 compliant). Note
+    that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds.
+
+  2007-03-08 Frédéric Bernon
+  * tcp.h: Keepalive values can be configured at compile time, but don't change
+    this unless you know what you're doing (default are RFC1122 compliant).
+
+  2007-03-08 Frédéric Bernon
+  * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h:
+    Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO
+    on UDP sockets/netconn.
+
+  2007-03-08 Simon Goldschmidt
+  * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time.
+
+  2007-03-06 Frédéric Bernon
+  * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: 
+    Implement SO_RCVTIMEO on UDP sockets/netconn.
+
+  2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt)
+  * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated
+    on the stack and remove the API msg type from memp
+
+  2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt)
+  * sockets.h, sockets.c: Move socket initialization to new
+    lwip_socket_init() function.
+    NOTE: this changes the API with ports. Ports will have to be
+    updated to call lwip_socket_init() now.
+
+  2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt)
+  * api_lib.c: Use memcpy in netbuf_copy_partial.
+
+
+  ++ Bug fixes:
+
+  2008-03-17 Frédéric Bernon, Ed Kerekes
+  * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have
+    some problems to fill the IP header on some targets, use now the
+    ip.h macros to do it).
+
+  2008-03-13 Frédéric Bernon
+  * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using
+    (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a
+    TCP connection caused a crash. Note that using (lwip_)recvfrom
+    like this is a bit slow and that using (lwip)getpeername is the
+    good lwip way to do it (so, using recv is faster on tcp sockets).
+
+  2008-03-12 Frédéric Bernon, Jonathan Larmour
+  * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's
+    recv_raw() does not consume data", and the ping sample (with
+    LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom
+    returned the IP payload, without the IP header).
+
+  2008-03-04 Jonathan Larmour
+  * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors
+  and/or warnings on some systems where mem_size_t and size_t differ.
+  * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc.
+
+  2008-03-04 Kieran Mansley (contributions by others) 
+  * Numerous small compiler error/warning fixes from contributions to
+    mailing list after 1.3.0 release candidate made.
+
+  2008-01-25 Cui hengbin (integrated by Frédéric Bernon)
+  * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures.
+
+  2008-01-15 Kieran Mansley
+  * tcp_out.c: BUG20511.  Modify persist timer to start when we are
+    prevented from sending by a small send window, not just a zero
+    send window.
+
+  2008-01-09 Jonathan Larmour
+  * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid
+    conflict with Linux system headers.
+
+  2008-01-06 Jonathan Larmour
+  * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP
+    address entirely on receiving a DHCPNAK, and restarting discovery.
+
+  2007-12-21 Simon Goldschmidt
+  * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail
+    is not protected" by using new macros for interlocked access to modify/test
+    netconn->recv_avail.
+
+  2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev)
+  * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state)
+
+  2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm)
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling
+    of silly window avoidance and prevent lwIP from shrinking the window)
+
+  2007-12-04 Simon Goldschmidt
+  * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last
+    data packet was lost): add assert that all segment lists are empty in
+    tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED
+    state from LAST_ACK in tcp_process
+
+  2007-12-02 Simon Goldschmidt
+  * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET
+    If including <sys/time.h> for system-struct timeval, LWIP_TIMEVAL_PRIVATE now
+    has to be set to 0 in lwipopts.h
+
+  2007-12-02 Simon Goldschmidt
+  * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always
+    allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen
+    netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox.
+    This is a fix for thread-safety and allocates all items needed for a netconn
+    when the netconn is created.
+
+  2007-11-30 Simon Goldschmidt
+  * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple
+    netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed
+    to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same
+    port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address)
+
+  2007-11-27 Simon Goldschmidt
+  * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by
+    letting ip_route only use netifs that are up.
+
+  2007-11-27 Simon Goldschmidt
+  * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF
+    and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and
+    sockets block most operations once they have seen a fatal error.
+
+  2007-11-27 Simon Goldschmidt
+  * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the
+    netif to send as an argument (to be able to send on netifs that are down).
+
+  2007-11-26 Simon Goldschmidt
+  * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs
+    arrive out-of-order
+
+  2007-11-21 Simon Goldschmidt
+  * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early
+    Fixed the nagle algorithm; nagle now also works for all raw API applications
+    and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY'
+
+  2007-11-12 Frédéric Bernon
+  * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most
+    of the netconn_peer and netconn_addr processing is done inside tcpip_thread
+    context in do_getaddr.
+
+  2007-11-10 Simon Goldschmidt
+  * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can
+    happen any time). Now the packet simply isn't enqueued when out of memory.
+
+  2007-11-01 Simon Goldschmidt
+  * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or
+    TCP_MSS if that is smaller) as long as no MSS option is received from the
+    remote host.
+
+  2007-11-01 Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN)
+    is now based on TCP_MSS instead of pcb->mss (on passive open now effectively
+    sending our configured TCP_MSS instead of the one received).
+
+  2007-11-01 Simon Goldschmidt
+  * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was
+    calculated based on the configured TCP_MSS, not on the MSS option received
+    with SYN+ACK.
+
+  2007-10-09 Simon Goldschmidt
+  * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too
+    short and also was generated wrong if checksum coverage != tot_len;
+    receive: checksum was calculated wrong if checksum coverage != tot_len
+
+  2007-10-08 Simon Goldschmidt
+  * mem.c: lfree was not updated in mem_realloc!
+
+  2007-10-07 Frédéric Bernon
+  * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential
+    crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT:
+    this change cause an API breakage for netconn_addr, since a parameter
+    type change. Any compiler should cause an error without any changes in
+    yours netconn_peer calls (so, it can't be a "silent change"). It also
+    reduce a little bit the footprint for socket layer (lwip_getpeername &
+    lwip_getsockname use now a common lwip_getaddrname function since 
+    netconn_peer & netconn_addr have the same parameters).
+
+  2007-09-20 Simon Goldschmidt
+  * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state)
+    by checking  tcp_tw_pcbs also
+
+  2007-09-19 Simon Goldschmidt
+  * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies)
+
+  2007-09-15 Mike Kleshov
+  * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used)
+
+  2007-09-06 Frédéric Bernon
+  * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove
+    it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which
+    already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h"
+    if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h.
+
+  2007-08-30 Frédéric Bernon
+  * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, 
+    and fix some coding style.
+
+  2007-08-28 Frédéric Bernon
+  * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any
+    kind of packets. These packets are considered like Ethernet packets (payload 
+    pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets 
+    are considered like IP packets (payload pointing to iphdr).
+
+  2007-08-27 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error
+    problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state
+    and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT).
+
+  2007-08-24 Kieran Mansley
+  * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy
+    compiler (Paradigm C++)
+
+  2007-08-09 Frédéric Bernon, Bill Florac
+  * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement.
+    Introduce IGMP_STATS to centralize statistics management.
+
+  2007-08-09 Frédéric Bernon, Bill Florac
+  * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast
+    packet on a udp pcb binded on an netif's IP address, and not on "any".
+
+  2007-08-09 Frédéric Bernon, Bill Florac
+  * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement.
+    This is mainly on using lookup/lookfor, and some coding styles...
+
+  2007-07-26 Frédéric Bernon (and "thedoctor")
+  * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages.
+
+  2007-07-25 Simon Goldschmidt
+  * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if
+    tcp_output fails in tcp_close, the code in do_close_internal gets simpler
+    (tcp_output is called again later from tcp timers).
+
+  2007-07-25 Simon Goldschmidt
+  * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old
+    copy_from_pbuf, which illegally modified the given pbuf.
+
+  2007-07-25 Simon Goldschmidt
+  * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs:
+    changed snd_queuelen++ to snd_queuelen += pbuf_clen(p).
+
+  2007-07-24 Simon Goldschmidt
+  * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the
+    correct state (must be CLOSED).
+
+  2007-07-13 Thomas Taranowski (commited by Jared Grubb)
+  * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed
+    allocation. It now returns NULL.
+
+  2007-07-13 Frédéric Bernon
+  * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in
+    all error cases.
+
+  2007-07-13 Frédéric Bernon
+  * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed,
+    because current code doesn't follow rawapi.txt documentation.
+
+  2007-07-13 Kieran Mansley
+  * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in
+    out of sequence processing of received packets
+
+  2007-07-03 Simon Goldschmidt
+  * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an
+    assumption is made that this pbuf is in one piece (i.e. not chained). These
+    assumptions clash with the possibility of converting to fully pool-based
+    pbuf implementations, where PBUF_RAM pbufs might be chained.
+
+  2007-07-03 Simon Goldschmidt
+  * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems
+    when closing tcp netconns: removed conn->sem, less context switches when
+    closing, both netconn_close and netconn_delete should safely close tcp
+    connections.
+
+  2007-07-02 Simon Goldschmidt
+  * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c,
+    tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off)
+    to cache ARP table indices with each pcb instead of single-entry cache for
+    the complete stack.
+
+  2007-07-02 Simon Goldschmidt
+  * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent
+    warnings when assigning to smaller types.
+
+  2007-06-28 Simon Goldschmidt
+  * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing.
+
+  2007-06-28 Simon Goldschmidt
+  * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if
+    a segment contained chained pbufs)
+
+  2007-06-28 Frédéric Bernon
+  * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute
+    a "pseudo-random" value based on netif's MAC and some autoip fields. It's always
+    possible to define this macro in your own lwipopts.h to always use C library's
+    rand(). Note that autoip_create_rand_addr doesn't use this macro.
+
+  2007-06-28 Frédéric Bernon
+  * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option
+    LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications
+    in api_lib/api_msg (use pointers and not type with table, etc...) 
+
+  2007-06-26 Simon Goldschmidt
+  * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines.
+
+  2007-06-25 Simon Goldschmidt
+  * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload
+    for udp packets with no matching pcb.
+
+  2007-06-25 Simon Goldschmidt
+  * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match
+    could get udp input packets if the remote side matched.
+
+  2007-06-13 Simon Goldschmidt
+  * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get
+    changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0.
+
+  2007-06-13 Simon Goldschmidt
+  * api_msg.c: pcb_new sets conn->err if protocol is not implemented
+    -> netconn_new_..() does not allocate a new connection for unsupported
+    protocols.
+
+  2007-06-13 Frédéric Bernon, Simon Goldschmidt
+  * api_lib.c: change return expression in netconn_addr and netconn_peer, because
+    conn->err was reset to ERR_OK without any reasons (and error was lost)...
+
+  2007-06-13 Frédéric Bernon, Matthias Weisser
+  * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename
+    MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid
+    some macro names collision with some OS macros.
+
+  2007-06-11 Simon Goldschmidt
+  * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0,
+    create checksum over the complete packet. On RX, if it's < 8 (and not 0),
+    discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both
+    UDP & UDP Lite.
+
+  2007-06-11 Srinivas Gollakota & Oleg Tyshev
+  * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags"
+    where TCP flags wasn't initialized in tcp_keepalive.
+
+  2007-06-03 Simon Goldschmidt
+  * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function
+    registered, p->payload was modified without modifying p->len if sending
+    icmp_dest_unreach() (had no negative effect but was definitively wrong).
+
+  2007-06-03 Simon Goldschmidt
+  * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp
+    re-used the input pbuf even if that didn't have enough space to include the
+    link headers. Now the space is tested and a new pbuf is allocated for the
+    echo response packet if the echo request pbuf isn't big enough.
+
+  2007-06-01 Simon Goldschmidt
+  * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread.
+
+  2007-05-23 Frédéric Bernon
+  * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only
+    allocated by do_listen if success) and netconn_accept errors handling. In
+    most of api_lib functions, we replace some errors checkings like "if (conn==NULL)"
+    by ASSERT, except for netconn_delete.
+
+  2007-05-23 Frédéric Bernon
+  * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return
+    an error code if it's impossible to fetch a pbuf on a TCP connection (and not
+    directly close the recvmbox).
+
+  2007-05-22 Simon Goldschmidt
+  * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of
+    bound but unconnected (and non-listening) tcp_pcbs.
+
+  2007-05-22 Frédéric Bernon
+  * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only
+    used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of
+    sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features
+    like "sys_timeout" in their application threads.
+
+  2007-05-22 Frédéric Bernon
+  * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see
+    which parameters are used by which do_xxx function, and to avoid "misusing"
+    parameters (patch #5938).
+
+  2007-05-22 Simon Goldschmidt
+  * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938:
+    changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto
+    is only 8 bits wide. This affects the api, as there, the protocol was
+    u16_t, too.
+
+  2007-05-18 Simon Goldschmidt
+  * memp.c: addition to patch #5913: smaller pointer was returned but
+    memp_memory was the same size -> did not save memory.
+
+  2007-05-16 Simon Goldschmidt
+  * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns
+    != ERR_OK.
+
+  2007-05-16 Simon Goldschmidt
+  * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same
+    as the one of the netif used for sending to prevent sending from old
+    addresses after a netif address gets changed (partly fixes bug #3168).
+
+  2007-05-16 Frédéric Bernon
+  * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work
+    with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in 
+    tcpip_init) because we have to be sure that network interfaces are already
+    added (mac filter is updated only in igmp_init for the moment).
+
+  2007-05-16 Simon Goldschmidt
+  * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls
+    into sys_arch_sem_wait calls to prevent timers from running while waiting
+    for the heap. This fixes bug #19167.
+
+  2007-05-13 Simon Goldschmidt
+  * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines
+    for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from
+    tcp.h to sockets.h.
+
+  2007-05-07 Simon Goldschmidt
+  * mem.c: Another attempt to fix bug #17922.
+
+  2007-05-04 Simon Goldschmidt
+  * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy()
+    implementation so that it can be reused (don't allocate the target
+    pbuf inside pbuf_copy()).
+
+  2007-05-04 Simon Goldschmidt
+  * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem
+    to save a little RAM (next pointer of memp is not used while not in pool).
+
+  2007-05-03 "maq"
+  * sockets.c: Fix ioctl FIONREAD when some data remains from last recv.
+    (patch #3574).
+
+  2007-04-23 Simon Goldschmidt
+  * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results
+    in NULL reference for incoming TCP packets". Loopif has to be configured
+    (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input()
+    (multithreading environments, e.g. netif->input() = tcpip_input()) or
+    putting packets on a list that is fed to the stack by calling loopif_poll()
+    (single-thread / NO_SYS / polling environment where e.g.
+    netif->input() = ip_input).
+
+  2007-04-17 Jonathan Larmour
+  * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold
+    the difference between two u16_t's.
+  * sockets.h: FD_SETSIZE needs to match number of sockets, which is
+    MEMP_NUM_NETCONN in sockets.c right now.
+
+  2007-04-12 Jonathan Larmour
+  * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580).
+
+  2007-04-12 Kieran Mansley
+  * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission
+    timer is reset to fix bug#19434, with help from Oleg Tyshev.
+
+  2007-04-11 Simon Goldschmidt
+  * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than
+    previously thought need to be copied (everything but PBUF_ROM!). Cleaned up
+    pbuf.c: removed functions no needed any more (by etharp).
+
+  2007-04-11 Kieran Mansley
+  * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix
+    "Constant is long" warnings with 16bit compilers.  Contributed by
+    avatar@mmlab.cse.yzu.edu.tw
+
+  2007-04-05 Frédéric Bernon, Jonathan Larmour
+  * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on
+    the mailbox is active". Now, the post is only done during a connect, and do_send,
+    do_write and do_join_leave_group don't do anything if a previous error was signaled.
+
+  2007-04-03 Frédéric Bernon
+  * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output
+    packets. See patch #5834.
+
+  2007-03-30 Frédéric Bernon
+  * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add
+    missing  pcb allocations checking (in do_bind, and for each raw_new). Fix style.
+
+  2007-03-30 Frédéric Bernon
+  * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with
+    others environment defines (these were too "generic").
+
+  2007-03-28 Frédéric Bernon
+  * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call
+    result and can cause a crash. lwip_send now check netbuf_ref result.
+
+  2007-03-28 Simon Goldschmidt
+  * sockets.c Remove "#include <errno.h>" from sockets.c to avoid multiple
+    definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is
+    defined. This is the way it should have been already (looking at
+    doc/sys_arch.txt)
+
+  2007-03-28 Kieran Mansley
+  * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS +
+    IP and TCP headers *and* physical link headers
+
+  2007-03-26 Frédéric Bernon (based on patch from Dmitry Potapov)
+  * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause
+    to send some garbage. It is not a definitive solution, but the patch does solve
+    the problem for most cases.
+
+  2007-03-22 Frédéric Bernon
+  * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used).
+
+  2007-03-22 Frédéric Bernon
+  * api_lib.c: somes resources couldn't be freed if there was errors during
+    netconn_new_with_proto_and_callback.
+
+  2007-03-22 Frédéric Bernon
+  * ethernetif.c: update netif->input calls to check return value. In older ports,
+    it's a good idea to upgrade them, even if before, there could be another problem
+    (access to an uninitialized mailbox).
+
+  2007-03-21 Simon Goldschmidt
+  * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed
+    by casting to unsigned).
+
+  2007-03-21 Frédéric Bernon
+  * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from
+    api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a
+    dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call.
+    Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a
+    faster and more reliable communication between api_lib and tcpip.
+
+  2007-03-21 Frédéric Bernon
+  * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0.
+
+  2007-03-21 Frédéric Bernon
+  * api_msg.c, igmp.c, igmp.h: Fix C++ style comments
+
+  2007-03-21 Kieran Mansley
+  * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS +
+    IP and TCP headers
+
+  2007-03-21 Kieran Mansley
+  * Fix all uses of pbuf_header to check the return value.  In some
+    cases just assert if it fails as I'm not sure how to fix them, but
+    this is no worse than before when they would carry on regardless
+    of the failure.
+
+  2007-03-21 Kieran Mansley
+  * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and
+    comment out missing header include in icmp.c
+
+  2007-03-20 Frédéric Bernon
+  * memp.h, stats.c: Fix stats_display function where memp_names table wasn't
+    synchronized with memp.h.
+
+  2007-03-20 Frédéric Bernon
+  * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input,
+    tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with 
+    network interfaces. Also fix a compiler warning.
+
+  2007-03-20 Kieran Mansley
+  * udp.c: Only try and use pbuf_header() to make space for headers if
+    not a ROM or REF pbuf.
+
+  2007-03-19 Frédéric Bernon
+  * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg()
+    and api_msg_post().
+
+  2007-03-19 Frédéric Bernon
+  * Remove unimplemented "memp_realloc" function from memp.h.
+
+  2007-03-11 Simon Goldschmidt
+  * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused
+    memory corruption.
+
+  2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251
+    (missing `const' qualifier in socket functions), to get more compatible to
+    standard POSIX sockets.
+
+  2007-03-11 Frédéric Bernon (based on patch from Dmitry Potapov)
+  * sockets.c: Add asserts inside bind, connect and sendto to check input
+    parameters. Remove excessive set_errno() calls after get_socket(), because
+    errno is set inside of get_socket(). Move last sock_set_errno() inside
+    lwip_close.
+
+  2007-03-09 Simon Goldschmidt
+  * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory
+    was allocated too small.
+
+  2007-03-06 Simon Goldschmidt
+  * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect
+    the stack from concurrent access.
+
+  2007-03-06 Frédéric Bernon, Dmitry Potapov
+  * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy
+    call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input().
+
+  2007-03-06 Simon Goldschmidt
+  * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files
+    if IP_FRAG == 0 and IP_REASSEMBLY == 0
+
+  2007-03-06 Frédéric Bernon, Simon Goldschmidt
+  * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration
+    option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput.
+    Allow to do ARP processing for incoming packets inside tcpip_thread
+    (protecting ARP layer against concurrent access). You can also disable
+    old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0.
+    Older ports have to use tcpip_ethinput.
+
+  2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * err.h, err.c: fixed compiler warning "initialization dircards qualifiers
+    from pointer target type"
+
+  2007-03-05 Frédéric Bernon
+  * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES,
+    ETHARP_TRUST_IP_MAC, review SO_REUSE)
+
+  2007-03-04 Frédéric Bernon
+  * api_msg.c: Remove some compiler warnings : parameter "pcb" was never
+    referenced.
+
+  2007-03-04 Frédéric Bernon
+  * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from
+    Dmitry Potapov).
+    The api_msg struct stay on the stack (not moved to netconn struct).
+
+  2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov)
+  * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if
+    SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available)
+    Also fixed cast warning in pbuf_alloc()
+
+  2007-03-04 Simon Goldschmidt
+  * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt
+    existing pbuf chain when enqueuing multiple pbufs to a pending ARP request
+
+  2007-03-03 Frédéric Bernon
+  * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;"
+    It is static, and never used in udp.c except udp_init().
+
+  2007-03-02 Simon Goldschmidt
+  * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from
+    tcpip_thread() to tcpip_init(). This way, raw API connections can be
+    initialized before tcpip_thread is running (e.g. before OS is started)
+
+  2007-03-02 Frédéric Bernon
+  * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call
+    interval.
+
+  2007-02-28 Kieran Mansley 
+  * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved
+    outside the region of the pbuf by pbuf_header()
+
+  2007-02-28 Kieran Mansley 
+  * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero
+    when supplied timeout is also non-zero 
+
+(STABLE-1.2.0)
+
+  2006-12-05 Leon Woestenberg
+  * CHANGELOG: Mention STABLE-1.2.0 release.
+
+  ++ New features:
+
+  2006-12-01 Christiaan Simons
+  * mem.h, opt.h: Added MEM_LIBC_MALLOC option.
+    Note this is a workaround. Currently I have no other options left.
+
+  2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour)
+  * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define
+    to include/lwip/opt.h.
+  * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL.
+    Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h.
+  * opt.h: Add above new options.
+
+  2006-08-18 Christiaan Simons
+  * tcp_{in,out}.c: added SNMP counters.
+  * ipv4/ip.c: added SNMP counters.
+  * ipv4/ip_frag.c: added SNMP counters.
+
+  2006-08-08 Christiaan Simons
+  * etharp.{c,h}: added etharp_find_addr() to read
+    (stable) ethernet/IP address pair from ARP table
+
+  2006-07-14 Christiaan Simons
+  * mib_structs.c: added
+  * include/lwip/snmp_structs.h: added
+  * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct
+
+  2006-07-06 Christiaan Simons
+  * snmp/asn1_{enc,dec}.c added
+  * snmp/mib2.c added
+  * snmp/msg_{in,out}.c added
+  * include/lwip/snmp_asn1.h added
+  * include/lwip/snmp_msg.h added
+  * doc/snmp_agent.txt added
+
+  2006-03-29 Christiaan Simons
+  * inet.c, inet.h: Added platform byteswap support.
+    Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and
+    optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros.
+
+  ++ Bug fixes:
+
+  2006-11-30 Christiaan Simons
+  * dhcp.c: Fixed false triggers of request_timeout.
+
+  2006-11-28 Christiaan Simons
+  * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags.
+
+  2006-10-11 Christiaan Simons
+  * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h:
+    Partially accepted patch #5449 for ANSI C compatibility / build fixes.
+  * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol
+    identifier from 170 to 136 (bug #17574).
+
+  2006-10-10 Christiaan Simons
+  * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice.
+
+  2006-08-17 Christiaan Simons
+  * udp.c: Fixed bug #17200, added check for broadcast
+    destinations for PCBs bound to a unicast address.
+
+  2006-08-07 Christiaan Simons
+  * api_msg.c: Flushing TCP output in do_close() (bug #15926).
+
+  2006-06-27 Christiaan Simons
+  * api_msg.c: Applied patch for cold case (bug #11135).
+    In accept_function() ensure newconn->callback is always initialized.
+
+  2006-06-15 Christiaan Simons
+  * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748),
+    facilitate printing of mem_size_t and u16_t statistics.
+
+  2006-06-14 Christiaan Simons
+  * api_msg.c: Applied patch #5146 to handle allocation failures
+    in accept() by Kevin Lawson.
+
+  2006-05-26 Christiaan Simons
+  * api_lib.c: Removed conn->sem creation and destruction 
+    from netconn_write() and added sys_sem_new to netconn_new_*.
+
+(STABLE-1_1_1)
+
+  2006-03-03  Christiaan Simons
+  * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap
+    access and added pbuf_alloc() return value checks.
+
+  2006-01-01  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is
+    now handled by the checksum routine properly.
+
+  2006-02-27  Leon Woestenberg <leon.woestenberg@gmx.net>
+   * pbuf.c: Fix alignment; pbuf_init() would not work unless
+     pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.)
+
+  2005-12-20  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch
+    submitted by Mitrani Hiroshi.
+
+  2005-12-15  Christiaan Simons
+  * inet.c: Disabled the added summing routine to preserve code space.
+
+  2005-12-14  Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson.
+    Added Curt McDowell's optimized checksumming routine for future
+    inclusion. Need to create test case for unaliged, aligned, odd,
+    even length combination of cases on various endianess machines.
+
+  2005-12-09  Christiaan Simons
+  * inet.c: Rewrote standard checksum routine in proper portable C.
+
+  2005-11-25  Christiaan Simons
+  * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only.
+  * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t,
+    u32_t, s32_t typedefs. This solves most debug word-length assumes.
+
+  2005-07-17 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * inet.c: Fixed unaligned 16-bit access in the standard checksum
+    routine by Peter Jolasson.
+  * slipif.c: Fixed implementation assumption of single-pbuf datagrams.
+
+  2005-02-04 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch.
+  * tcp_{out|in}.c: Applied patch fixing unaligned access.
+
+  2005-01-04 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement.
+
+  2005-01-03 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * udp.c: UDP pcb->recv() was called even when it was NULL.
+
+(STABLE-1_1_0)
+
+  2004-12-28 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.*: Disabled multiple packets on the ARP queue.
+    This clashes with TCP queueing.
+
+  2004-11-28 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.*: Fixed race condition from ARP request to ARP timeout.
+    Halved the ARP period, doubled the period counts.
+    ETHARP_MAX_PENDING now should be at least 2. This prevents
+    the counter from reaching 0 right away (which would allow
+    too little time for ARP responses to be received).
+
+  2004-11-25 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * dhcp.c: Decline messages were not multicast but unicast.
+  * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD.
+    Do not try hard to insert arbitrary packet's source address,
+    etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. 
+    etharp_query() now always DOES call ETHARP_TRY_HARD so that users
+    querying an address will see it appear in the cache (DHCP could
+    suffer from this when a server invalidly gave an in-use address.)
+  * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are
+    comparing network addresses (identifiers), not the network masks
+    themselves.
+  * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given
+    IP address actually belongs to the network of the given interface.
+
+  2004-11-24 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state.
+
+(STABLE-1_1_0-RC1)
+
+  2004-10-16 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately,
+    even if one is already pending, if the rcv_wnd is above a threshold
+    (currently TCP_WND/2). This avoids waiting for a timer to expire to send a
+    delayed ACK in order to open the window if the stack is only receiving data.
+
+  2004-09-12 Kieran Mansley <kjm25@cam.ac.uk>
+  * tcp*.*: Retransmit time-out handling improvement by Sam Jansen.
+
+  2004-08-20 Tony Mountifield <tony@softins.co.uk>
+  * etharp.c: Make sure the first pbuf queued on an ARP entry
+    is properly ref counted.
+
+  2004-07-27 Tony Mountifield <tony@softins.co.uk>
+  * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler
+    warnings about comparison.
+  * pbuf.c: Stopped compiler complaining of empty if statement
+    when LWIP_DEBUGF() empty.  Closed an unclosed comment.
+  * tcp.c: Stopped compiler complaining of empty if statement
+    when LWIP_DEBUGF() empty.
+  * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons().
+  * inet.c: Added a couple of casts to quiet the compiler.
+    No need to test isascii(c) before isdigit(c) or isxdigit(c).
+
+  2004-07-22 Tony Mountifield <tony@softins.co.uk>
+  * inet.c: Made data types consistent in inet_ntoa().
+    Added casts for return values of checksum routines, to pacify compiler.
+  * ip_frag.c, tcp_out.c, sockets.c, pbuf.c
+    Small corrections to some debugging statements, to pacify compiler.
+
+  2004-07-21 Tony Mountifield <tony@softins.co.uk>
+  * etharp.c: Removed spurious semicolon and added missing end-of-comment.
+  * ethernetif.c Updated low_level_output() to match prototype for
+    netif->linkoutput and changed low_level_input() similarly for consistency.
+  * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype
+    of raw_recv() in raw.h and so avoid compiler error.
+  * sockets.c: Added trivial (int) cast to keep compiler happier.
+  * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros.
+
+(STABLE-1_0_0)
+
+  ++ Changes:
+
+  2004-07-05 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure
+    your cc.h file defines this either 1 or 0. If non-defined,
+    defaults to 1.
+  * .c: Added <string.h> and <errno.h> includes where used.
+  * etharp.c: Made some array indices unsigned.
+
+  2004-06-27 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * netif.*: Added netif_set_up()/down().
+  * dhcp.c: Changes to restart program flow.
+
+  2004-05-07 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.c: In find_entry(), instead of a list traversal per candidate, do a
+    single-pass lookup for different candidates. Should exploit locality.
+
+  2004-04-29 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * tcp*.c: Cleaned up source comment documentation for Doxygen processing.
+  * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC.
+  * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by
+    the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option.
+
+  ++ Bug fixes:
+
+  2004-04-27 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution
+    suggested by Timmy Brolin. Fix for 32-bit processors that cannot access
+    non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix
+    is to prefix the 14-bit Ethernet headers with two padding bytes.
+
+  2004-04-23 Leon Woestenberg <leon.woestenberg@gmx.net>
+  * ip_addr.c: Fix in the ip_addr_isbroadcast() check.
+  * etharp.c: Fixed the case where the packet that initiates the ARP request
+    is not queued, and gets lost. Fixed the case where the packets destination
+    address is already known; we now always queue the packet and perform an ARP
+    request.
+
+(STABLE-0_7_0)
+
+  ++ Bug fixes:
+
+  * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition.
+  * Fixed TCP bug in dequeueing of FIN from out of order segment queue.
+  * Fixed two possible NULL references in rare cases.
+
+(STABLE-0_6_6)
+
+  ++ Bug fixes:
+
+  * Fixed DHCP which did not include the IP address in DECLINE messages.
+
+  ++ Changes:
+
+  * etharp.c has been hauled over a bit.
+
+(STABLE-0_6_5)
+
+  ++ Bug fixes:
+
+  * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic.
+  * Packets sent from ARP queue had invalid source hardware address.
+
+  ++ Changes:
+
+  * Pass-by ARP requests do now update the cache.
+
+  ++ New features:
+
+  * No longer dependent on ctype.h.
+  * New socket options.
+  * Raw IP pcb support.
+
+(STABLE-0_6_4)
+
+  ++ Bug fixes:
+
+  * Some debug formatters and casts fixed.
+  * Numereous fixes in PPP.
+
+  ++ Changes:
+
+  * DEBUGF now is LWIP_DEBUGF
+  * pbuf_dechain() has been re-enabled.
+  * Mentioned the changed use of CVS branches in README.
+
+(STABLE-0_6_3)
+
+  ++ Bug fixes:
+
+  * Fixed pool pbuf memory leak in pbuf_alloc().
+    Occured if not enough PBUF_POOL pbufs for a packet pbuf chain.
+    Reported by Savin Zlobec.
+
+  * PBUF_POOL chains had their tot_len field not set for non-first
+    pbufs. Fixed in pbuf_alloc().
+
+  ++ New features:
+
+  * Added PPP stack contributed by Marc Boucher
+
+  ++ Changes:
+
+  * Now drops short packets for ICMP/UDP/TCP protocols. More robust.
+
+  * ARP queueuing now queues the latest packet instead of the first.
+    This is the RFC recommended behaviour, but can be overridden in
+    lwipopts.h.
+
+(0.6.2)
+
+  ++ Bugfixes:
+
+  * TCP has been fixed to deal with the new use of the pbuf->ref
+    counter.
+
+  * DHCP dhcp_inform() crash bug fixed.
+
+  ++ Changes:
+
+  * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed
+    pbuf_refresh(). This has sped up pbuf pool operations considerably.
+    Implemented by David Haas.
+
+(0.6.1)
+
+  ++ New features:
+
+  * The packet buffer implementation has been enhanced to support
+    zero-copy and copy-on-demand for packet buffers which have their
+    payloads in application-managed memory.
+    Implemented by David Haas.
+
+    Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy
+    if an outgoing packet can be directly sent on the link, or perform
+    a copy-on-demand when necessary.
+
+    The application can safely assume the packet is sent, and the RAM
+    is available to the application directly after calling udp_send()
+    or similar function.
+
+  ++ Bugfixes:
+
+  * ARP_QUEUEING should now correctly work for all cases, including
+    PBUF_REF.
+    Implemented by Leon Woestenberg.
+
+  ++ Changes:
+
+  * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer
+    to a '0.0.0.0' IP address.
+
+  * The packet buffer implementation is changed. The pbuf->ref counter
+    meaning has changed, and several pbuf functions have been
+    adapted accordingly.
+
+  * netif drivers have to be changed to set the hardware address length field
+    that must be initialized correctly by the driver (hint: 6 for Ethernet MAC).
+    See the contrib/ports/c16x cs8900 driver as a driver example.
+
+  * netif's have a dhcp field that must be initialized to NULL by the driver.
+    See the contrib/ports/c16x cs8900 driver as a driver example.
+
+(0.5.x) This file has been unmaintained up to 0.6.1. All changes are
+  logged in CVS but have not been explained here.
+
+(0.5.3) Changes since version 0.5.2
+
+  ++ Bugfixes:
+
+  * memp_malloc(MEMP_API_MSG) could fail with multiple application
+    threads because it wasn't protected by semaphores.
+
+  ++ Other changes:
+
+  * struct ip_addr now packed.
+
+  * The name of the time variable in arp.c has been changed to ctime
+    to avoid conflicts with the time() function.
+
+(0.5.2) Changes since version 0.5.1
+
+  ++ New features:
+
+  * A new TCP function, tcp_tmr(), now handles both TCP timers.
+
+  ++ Bugfixes:
+
+  * A bug in tcp_parseopt() could cause the stack to hang because of a
+    malformed TCP