Commit in reactos on MAIN
drivers/lib/oskittcp/include/memtrack.h+51.1 -> 1.2
                            /oskiterrno.h+1-11.1 -> 1.2
                            /oskittcp.h+24-271.1 -> 1.2
drivers/lib/oskittcp/include/freebsd/src/sys/netinet/in_pcb.h+1-21.1 -> 1.2
drivers/lib/oskittcp/include/freebsd/src/sys/sys/mbuf.h+1-11.1 -> 1.2
                                                /proc.h+2-11.1 -> 1.2
                                                /socketvar.h+3-21.1 -> 1.2
drivers/lib/oskittcp/oskittcp/in.c-321.1 -> 1.2
                             /interface.c+60-481.1 -> 1.2
                             /ip_output.c+2-381.1 -> 1.2
                             /kern_clock.c-531.1 -> 1.2
                             /sleep.c+45-721.1 -> 1.2
                             /tcp_input.c+69-491.1 -> 1.2
                             /tcp_output.c+6-491.1 -> 1.2
                             /tcp_subr.c+1-11.1 -> 1.2
                             /uipc_socket.c+84-3001.1 -> 1.2
                             /uipc_socket2.c+53-521.1 -> 1.2
drivers/net/ndis/ndis/buffer.c+25-101.8 -> 1.9
                     /miniport.c+12-71.27 -> 1.28
                     /protocol.c+11.16 -> 1.17
drivers/net/tcpip/makefile+21-111.16 -> 1.17
                 /notes.txt+81.1 -> 1.2
drivers/net/tcpip/datalink/arp.c+7-241.5 -> 1.6
                          /lan.c+50-1611.15 -> 1.16
                          /loopback.c+21.7 -> 1.8
drivers/net/tcpip/include/interface.h+161.1 -> 1.2
                         /memtrack.h+741.1 -> 1.2
                         /prefix.h+281.1 -> 1.2
                         /datagram.h+1-31.4 -> 1.5
                         /debug.h+61.8 -> 1.9
                         /info.h+58-51.5 -> 1.6
                         /ip.h+7-181.10 -> 1.11
                         /lan.h-11.6 -> 1.7
                         /router.h+4-21.3 -> 1.4
                         /routines.h+5-211.5 -> 1.6
                         /tcp.h+15-241.5 -> 1.6
                         /tcpip.h+31-11.8 -> 1.9
                         /titypes.h+23-301.6 -> 1.7
drivers/net/tcpip/network/prefix.c+1391.1 -> 1.2
                         /icmp.c+11-131.7 -> 1.8
                         /ip.c+55-1261.9 -> 1.10
                         /neighbor.c+4-41.4 -> 1.5
                         /receive.c+91-921.8 -> 1.9
                         /route.c+25-21.5 -> 1.6
                         /router.c+64-301.5 -> 1.6
                         /transmit.c+21-111.9 -> 1.10
drivers/net/tcpip/tcpip/iinfo.c+1081.1 -> 1.2
                       /interface.c+1081.1 -> 1.2
                       /irp.c+301.1 -> 1.2
                       /memtrack.c+1461.1 -> 1.2
                       /ninfo.c+2481.1 -> 1.2
                       /tinfo.c+401.1 -> 1.2
                       /address.c+4-11.11 -> 1.12
                       /checksum.c+11.4 -> 1.5
                       /dispatch.c+125-571.11 -> 1.12
                       /fileobjs.c+24-421.13 -> 1.14
                       /info.c+152-4611.5 -> 1.6
                       /main.c+37-461.23 -> 1.24
                       /pool.c+11.2 -> 1.3
                       /routines.c+94-1301.12 -> 1.13
drivers/net/tcpip/transport/datagram/datagram.c+103-1131.7 -> 1.8
drivers/net/tcpip/transport/rawip/rawip.c+30-311.5 -> 1.6
drivers/net/tcpip/transport/tcp/event.c+3231.1 -> 1.2
                               /if.c+1831.1 -> 1.2
                               /tcp.c+181-17471.10 -> 1.11
                               /tcp_input.c-41841.1 removed
                               /tcp_ipv4.c-25231.1 removed
                               /tcp_output.c-15491.2 removed
                               /tcp_timer.c-7021.1 removed
                               /tcpcore.c-27831.1 removed
drivers/net/tcpip/transport/udp/udp.c+19-261.7 -> 1.8
lib/msafd/makefile+1-11.13 -> 1.14
lib/msafd/misc/dllmain.c+19-171.12 -> 1.13
lib/ws2_32/makefile+1-11.14 -> 1.15
lib/ws2_32/include/ws2_32.h+101.7 -> 1.8
lib/ws2_32/misc/dllmain.c+3-21.14 -> 1.15
               /ns.c+205-31.6 -> 1.7
+3357-15743
5 removed + 72 modified, total 77 files
This is a merge onto head of the last two months worth of changes to the
networking code.

There is individual change info on the branch arty_20040329.

Here is a summary of what changed:

tcpip: 

- Added a mostly working transport/tcp branch based on oskittcp 
  (checked in at drivers/lib/oskittcp).  This code shares almost nothing
  with the previous version.

- Regularized IRP handling

- Fixed ownership of buffers throughout tcpip.sys.  Buffers are now
  required to be copied in a few more cases, but everybody can call
  anybody else and not have to worry about keeping a buffer alive
  for any specific reason.

- Also moved lots more operations onto the stack (small datastructures
  and pointers).  This will result in a further simplification of the
  code here.

- Made each completion routine solely responsible for freeing memory
  from the corresponding action.

- Removed reference counted small address structures in favor if inlines

- Changed and clarified ownership rules almost everwhere

- Fixed a few more type punning style errors

- Added more info used by iphlpapi

- Added some memory tracing stuff

ndis:

- Fixed one or two type punning errors

ws2_32:

- Added getservbyname and getprotobyname (partial)

oskittcp:

- Diagnostics everywhere

- Eliminated dependence on raw_ip input

- Simplified buffering and signalling model a bit

- Added memory checking as in tcpip

- more to come

reactos/drivers/lib/oskittcp/include
memtrack.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- memtrack.h	29 May 2004 00:15:45 -0000	1.1
+++ memtrack.h	9 Jun 2004 18:11:36 -0000	1.2
@@ -68,6 +68,11 @@
 #define Untrack(x)
 #define TrackTag(x)
 #define FreeNdisPacket FreeNdisPacketX
+#define exFreePool(x) ExFreePool(x)
+#define exAllocatePool(x,y) ExAllocatePool(x,y)
+#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolWithTag(x,y,z)
+#define TrackWithTag(a,b,c,d)
+#define UntrackFL(a,b,c)
 #endif
 
 #endif/*MEMMTRAC_H*/

reactos/drivers/lib/oskittcp/include
oskiterrno.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- oskiterrno.h	29 May 2004 00:15:45 -0000	1.1
+++ oskiterrno.h	9 Jun 2004 18:11:36 -0000	1.2
@@ -51,7 +51,7 @@
 #define	OSK_ENOENT		2		/* No such file or directory */
 #define	OSK_ESRCH		3		/* No such process */
 #define	OSK_EINTR		4		/* Interrupted system call */
-#define	OSK_EIO		5		/* Input/output error */
+#define	OSK_EIO		        5		/* Input/output error */
 #define	OSK_ENXIO		6		/* Device not configured */
 #define	OSK_E2BIG		7		/* Argument list too long */
 #define	OSK_ENOEXEC		8		/* Exec format error */

reactos/drivers/lib/oskittcp/include
oskittcp.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- oskittcp.h	29 May 2004 00:15:45 -0000	1.1
+++ oskittcp.h	9 Jun 2004 18:11:36 -0000	1.2
@@ -39,46 +39,34 @@
 #include <oskittypes.h>
 
 #define IPHDR_SIZE 20
+#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
 
-typedef void (*OSKITTCP_SOCKET_DATA_AVAILABLE)
+typedef void (*OSKITTCP_SOCKET_STATE)
     ( void *ClientData,
       void *WhichSocket,
       void *WhichConnection,
-      OSK_PCHAR Data,
-      OSK_UINT Len );
-typedef void (*OSKITTCP_SOCKET_CONNECT_INDICATION)
-    ( void *ClientData, 
-      void *WhichSocket, 
-      void *WhichConnection );
-typedef void (*OSKITTCP_SOCKET_CLOSE_INDICATION)
-    ( void *WhichSocket );
-typedef void (*OSKITTCP_SOCKET_PENDING_CONNECT_INDICATION)
-    ( void *WhichSocket );
-typedef void (*OSKITTCP_SOCKET_RESET_INDICATION)
-    ( void *WhichSocket );
+      OSK_UINT SelFlags,
+      OSK_UINT SocketState );
 typedef int (*OSKITTCP_SEND_PACKET)
     ( void *ClientData,
       void *WhichSocket,
       void *WhichConnection,
       OSK_PCHAR Data,
       OSK_UINT Len );
-typedef int (*OSKITTCP_NEED_BIND)
-    ( void *ClientData,
-      void *WhichSocket, 
-      void *WhichConnection,
-      struct sockaddr *address, 
-      OSK_UINT addrlen, 
-      OSK_UINT reuseport );
 
 typedef struct _OSKITTCP_EVENT_HANDLERS {
     void *ClientData;
-    OSKITTCP_SOCKET_DATA_AVAILABLE SocketDataAvailable;
-    OSKITTCP_SOCKET_CONNECT_INDICATION SocketConnectIndication;
-    OSKITTCP_SOCKET_CLOSE_INDICATION SocketCloseIndication;
-    OSKITTCP_SOCKET_PENDING_CONNECT_INDICATION SocketPendingConnectIndication;
-    OSKITTCP_SOCKET_RESET_INDICATION SocketResetIndication;
+    OSKITTCP_SOCKET_STATE SocketState;
     OSKITTCP_SEND_PACKET PacketSend;
-    OSKITTCP_NEED_BIND Bind;
 } OSKITTCP_EVENT_HANDLERS, *POSKITTCP_EVENT_HANDLERS;
 
 extern OSKITTCP_EVENT_HANDLERS OtcpEvent;
@@ -92,7 +80,12 @@
 ( POSKITTCP_EVENT_HANDLERS EventHandlers );
 extern void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len,
 				     OSK_UINT IpHeaderLen );
-
+extern int OskitTCPReceive( void *socket, 
+			    void *Addr,
+			    OSK_PCHAR Data,
+			    OSK_UINT Len,
+			    OSK_UINT *OutLen,
+			    OSK_UINT Flags );
 #undef errno
 
 #define malloc(x,...) fbsd_malloc(x,__FILE__,__LINE__)
@@ -103,4 +96,8 @@
 
 #define SOCK_MAXADDRLEN 255
 
+#define OSK_MSG_OOB      0x01
+#define OSK_MSG_PEEK     0x02
+#define OSK_MSG_DONTWAIT 0x80
+
 #endif/*OSKITTCP_H*/

reactos/drivers/lib/oskittcp/include/freebsd/src/sys/netinet
in_pcb.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- in_pcb.h	29 May 2004 00:15:45 -0000	1.1
+++ in_pcb.h	9 Jun 2004 18:11:37 -0000	1.2
@@ -97,8 +97,7 @@
 	 in_pcblookuphash __P((struct inpcbinfo *,
 	    struct in_addr, u_int, struct in_addr, u_int));
 void	 in_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
-	    u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int)));
-void	 in_pcbrehash __P((struct inpcb *));
+	    u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int)));void     in_pcbrehash __P((struct inpcb *));
 void	 in_rtchange __P((struct inpcb *, int));
 void	 in_setpeeraddr __P((struct inpcb *, struct mbuf *));
 void	 in_setsockaddr __P((struct inpcb *, struct mbuf *));

reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys
mbuf.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- mbuf.h	29 May 2004 00:15:46 -0000	1.1
+++ mbuf.h	9 Jun 2004 18:11:37 -0000	1.2
@@ -351,7 +351,7 @@
 	  if ((m)->m_flags & M_EXT) { \
 		MCLFREE((m)->m_ext.ext_buf); \
 	  } \
-	  (nn) = (m)->m_next; \
+	  /* (nn) = (m)->m_next; */ \
 	  FREE((m), mbtypes[(m)->m_type]); \
 	}
 #endif /* OSKIT */

reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys
proc.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- proc.h	29 May 2004 00:15:46 -0000	1.1
+++ proc.h	9 Jun 2004 18:11:37 -0000	1.2
@@ -62,6 +62,7 @@
 #include <sys/rtprio.h>			/* For struct rtprio. */
 #include <sys/select.h>			/* For struct selinfo. */
 #include <sys/time.h>			/* For structs itimerval, timeval. */
+#include <sys/socketvar.h>
 
 #ifdef OSKIT
 #include <oskit/dev/dev.h>
@@ -319,7 +320,7 @@
 void	sleep __P((void *chan, int pri));
 int	tsleep __P((void *chan, int pri, char *wmesg, int timo));
 void	unsleep __P((struct proc *));
-void	wakeup __P((void *chan));
+void	wakeup __P((struct socket *so, struct selinfo *si, void *chan));
 
 __dead void cpu_exit __P((struct proc *)) __dead2;
 __dead void exit1 __P((struct proc *, int)) __dead2;

reactos/drivers/lib/oskittcp/include/freebsd/src/sys/sys
socketvar.h 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- socketvar.h	29 May 2004 00:15:46 -0000	1.1
+++ socketvar.h	9 Jun 2004 18:11:37 -0000	1.2
@@ -181,11 +181,11 @@
 		((sb)->sb_flags |= SB_LOCK), 0)
 
 /* release lock on sockbuf sb */
-#define	sbunlock(sb) { \
+#define	sbunlock(so, sb) { \
 	(sb)->sb_flags &= ~SB_LOCK; \
 	if ((sb)->sb_flags & SB_WANT) { \
 		(sb)->sb_flags &= ~SB_WANT; \
-		wakeup((caddr_t)&(sb)->sb_flags); \
+		wakeup(so, &(sb)->sb_sel, (caddr_t)&(sb)->sb_flags); \
 	} \
 }
 
@@ -195,6 +195,7 @@
 			}
 
 #define	sowwakeup(so)	sowakeup((so), &(so)->so_snd)
+#define	socwakeup(so)	sowakeup((so), &(so)->so_snd)
 
 #ifdef KERNEL
 extern u_long	sb_max;

reactos/drivers/lib/oskittcp/oskittcp
in.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- in.c	29 May 2004 00:15:46 -0000	1.1
+++ in.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -64,38 +64,6 @@
 	struct in_multihead mk_head;
 };
 
-/*
- * Return the network number from an internet address.
- */
-u_long
-in_netof(in)
-	struct in_addr in;
-{
-	register u_long i = ntohl(in.s_addr);
-	register u_long net;
-	register struct in_ifaddr *ia;
-
-	if (IN_CLASSA(i))
-		net = i & IN_CLASSA_NET;
-	else if (IN_CLASSB(i))
-		net = i & IN_CLASSB_NET;
-	else if (IN_CLASSC(i))
-		net = i & IN_CLASSC_NET;
-	else if (IN_CLASSD(i))
-		net = i & IN_CLASSD_NET;
-	else
-		return (0);
-
-	/*
-	 * Check whether network is a subnet;
-	 * if so, return subnet number.
-	 */
-	for (ia = in_ifaddr; ia; ia = ia->ia_next)
-		if (net == ia->ia_net)
-			return (i & ia->ia_subnetmask);
-	return (net);
-}
-
 #ifndef SUBNETSARELOCAL
 #define	SUBNETSARELOCAL	1
 #endif

reactos/drivers/lib/oskittcp/oskittcp
interface.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- interface.c	29 May 2004 00:15:46 -0000	1.1
+++ interface.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -54,9 +54,6 @@
     if( OtcpEvent.PacketSend ) 
 	OS_DbgPrint(OSK_MID_TRACE,("SendPacket handler registered: %x\n",
 				   OtcpEvent.PacketSend));
-    if( OtcpEvent.Bind )
-	OS_DbgPrint(OSK_MID_TRACE,("Bind handler registered: %x\n",
-				   OtcpEvent.Bind));
 }
 
 void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len ) {
@@ -85,42 +82,49 @@
 	*aso = so;
     }
     return error;
-#if 0
-    register struct protosw *prp;
-    register struct socket *so;
-    register int error;
+}
 
-    if (proto) {
-	prp = pffindproto(domain, proto, type);
-    } else {
-	prp = pffindtype(domain, type);
-    }
-    if (prp == 0 || prp->pr_usrreq == 0) {
-	return (EPROTONOSUPPORT);
-    }
-    if (prp->pr_type != type) {
-	return (EPROTOTYPE);
+int OskitTCPRecv( void *connection,
+		  void *Addr,
+		  OSK_PCHAR Data,
+		  OSK_UINT Len,
+		  OSK_UINT *OutLen,
+		  OSK_UINT Flags ) {
+    struct mbuf *paddr = 0;
+    struct mbuf m, *mp;
+    struct uio uio = { 0 };
+    int error = 0;
+    int tcp_flags = 0;
+
+    if( Flags & OSK_MSG_OOB )      tcp_flags |= MSG_OOB;
+    if( Flags & OSK_MSG_DONTWAIT ) tcp_flags |= MSG_DONTWAIT;
+    if( Flags & OSK_MSG_PEEK )     tcp_flags |= MSG_PEEK;
+
+    uio.uio_resid = Len;
+    m.m_len = Len;
+    m.m_data = Data;
+    m.m_type = MT_DATA;
+    m.m_flags = M_PKTHDR | M_EOR;
+
+    mp = &m;
+
+    OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len));
+	
+    error = soreceive( connection, &paddr, &uio, &mp, NULL /* SCM_RIGHTS */, 
+		       &tcp_flags );
+
+    if( error == 0 ) {
+	OS_DbgPrint(OSK_MID_TRACE,("Successful read from TCP:\n"));
+	OskitDumpBuffer( m.m_data, uio.uio_resid );
     }
-    MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_WAIT);
-    bzero((caddr_t)so, sizeof(*so));
-    so->so_type = type;
-    so->so_proto = prp;
-    error =
-	(*prp->pr_usrreq)(so, PRU_ATTACH,
-			  (struct mbuf *)0, 
-			  (struct mbuf *)proto, 
-			  (struct mbuf *)0);
-    if (error) {
-	so->so_state |= SS_NOFDREF;
-	sofree(so);
-	return (error);
-    }
-    *aso = so;
-    OS_DbgPrint(OSK_MAX_TRACE,("Returning Socket %x\n", so));
-    return STATUS_SUCCESS;
-#endif
-}
 
+    if( paddr )
+	memcpy( Addr, paddr, min(sizeof(struct sockaddr),paddr->m_len) );
+
+    *OutLen = uio.uio_resid;
+    return error;
+}
+		  
 static int
 getsockaddr(namp, uaddr, len)
 /* [<][>][^][v][top][bottom][index][help] */
@@ -209,10 +213,13 @@
     return (error);    
 }
 
-DWORD OskitTCPClose( VOID *socket ) {
+DWORD OskitTCPClose( void *socket ) {
+    struct socket *so = socket;
+    so->so_connection = 0;
+    soclose( so );
 }
 
-DWORD OskitTCPSend( VOID *socket, OSK_PCHAR Data, OSK_UINT Len, int flags ) {
+DWORD OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, int flags ) {
     OskitDumpBuffer( Data, Len );
     struct mbuf mb;
     mb.m_data = Data;
@@ -220,11 +227,17 @@
     return sosend( socket, NULL, NULL, (struct mbuf *)&mb, NULL, 0 );
 }
 
-void OskitTCPReceive( VOID *socket, PVOID AddrOut, 
-		      OSK_PCHAR Data, OSK_UINT Len, OSK_UINT *OutLen ) {
-}
+void *OskitTCPAccept( void *socket, 
+		      void *AddrOut, 
+		      OSK_UINT AddrLen,
+		      OSK_UINT *OutAddrLen ) {
+    struct mbuf nam;
+    int error;
 
-VOID *OskitTCPAccept( VOID *socket, PVOID AddrOut ) {
+    nam.m_data = AddrOut;
+    nam.m_len  = AddrLen;
+
+    return soaccept( socket, &nam );
 }
 
 void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, 
@@ -246,13 +259,11 @@
     /* The buffer Ip is freed by tcp_input */
 }
 
-void OskitTCPBind( VOID *socket, PVOID name ) {
-}
-
-void OskitTCPListen( VOID *socket, int backlog ) {
+void OskitTCPListen( void *socket, int backlog ) {
+    return solisten( socket, backlog );
 }
 
-void OskitTCPSetAddress( VOID *socket, 
+void OskitTCPSetAddress( void *socket, 
 			 ULONG LocalAddress,
 			 USHORT LocalPort,
 			 ULONG RemoteAddress,
@@ -268,7 +279,7 @@
 	     RemoteAddress, RemotePort);
 }
 
-void OskitTCPGetAddress( VOID *socket, 
+void OskitTCPGetAddress( void *socket, 
 			 PULONG LocalAddress,
 			 PUSHORT LocalPort,
 			 PULONG RemoteAddress,
@@ -290,3 +301,4 @@
     DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file, line);
     KeBugCheck(0);
 }
+

reactos/drivers/lib/oskittcp/oskittcp
ip_output.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- ip_output.c	29 May 2004 00:15:46 -0000	1.1
+++ ip_output.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -132,45 +132,9 @@
 	      m->m_data + IPHDR_SIZE, m->m_len - IPHDR_SIZE );
     }
 
-    return (error);
-}
+    OS_DbgPrint(OSK_MID_TRACE,("Error from upper layer: %d\n", error));
 
-/*
- * Copy options from ip to jp,
- * omitting those not copied during fragmentation.
- */
-int
-ip_optcopy(ip, jp)
-	struct ip *ip, *jp;
-{
-	register u_char *cp, *dp;
-	int opt, optlen, cnt;
-
-	cp = (u_char *)(ip + 1);
-	dp = (u_char *)(jp + 1);
-	cnt = (ip->ip_hl << 2) - sizeof (struct ip);
-	for (; cnt > 0; cnt -= optlen, cp += optlen) {
-		opt = cp[0];
-		if (opt == IPOPT_EOL)
-			break;
-		if (opt == IPOPT_NOP) {
-			/* Preserve for IP mcast tunnel's LSRR alignment. */
-			*dp++ = IPOPT_NOP;
-			optlen = 1;
-			continue;
-		} else
-			optlen = cp[IPOPT_OLEN];
-		/* bogus lengths should have been caught by ip_dooptions */
-		if (optlen > cnt)
-			optlen = cnt;
-		if (IPOPT_COPIED(opt)) {
-			(void)memcpy(dp, cp, (unsigned)optlen);
-			dp += optlen;
-		}
-	}
-	for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
-		*dp++ = IPOPT_EOL;
-	return (optlen);
+    return (error);
 }
 
 /*

reactos/drivers/lib/oskittcp/oskittcp
kern_clock.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- kern_clock.c	29 May 2004 00:15:46 -0000	1.1
+++ kern_clock.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -140,59 +140,6 @@
 volatile struct	timeval mono_time;
 
 /*
- * The real-time timer, interrupting hz times per second.
- */
-void bsd_hardclock(void)
-{
-	register struct callout *p1;
-	register int needsoft;
-	unsigned cpl;
-	int s;
-
-	save_cpl(&cpl);
-	splhigh();
-
-	/*
-	 * Update real-time timeout queue.
-	 * At front of queue are some number of events which are ``due''.
-	 * The time to these is <= 0 and if negative represents the
-	 * number of ticks which have passed since it was supposed to happen.
-	 * The rest of the q elements (times > 0) are events yet to happen,
-	 * where the time for each is given as a delta from the previous.
-	 * Decrementing just the first of these serves to decrement the time
-	 * to all events.
-	 */
-	needsoft = 0;
-	for (p1 = calltodo.c_next; p1 != NULL; p1 = p1->c_next) {
-		if (--p1->c_time > 0)
-			break;
-		needsoft = 1;
-		if (p1->c_time == 0)
-			break;
-	}
-
-	/*
-	 * Increment the time-of-day.
-	 */
-	ticks++;
-	BUMPTIME(&mono_time, tick);
-	BUMPTIME(&time, tick);
-
-	/*
-	 * At this point, we might need a soft interrupt. We say, what the
-	 * heck, let's do the work now. Reduce priority level to softclock
-	 * first, though. The alternative (postponing it) would be called
-	 * 'setsoftclock'
-	 */
-	if (needsoft) {
-		(void)splsoftclock();
-		softclock();
-	}
-
-	restore_cpl(cpl);
-}
-
-/*
  * Software (low priority) clock interrupt.
  * Run periodic events from timeout queue.
  */

reactos/drivers/lib/oskittcp/oskittcp
sleep.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- sleep.c	29 May 2004 00:15:46 -0000	1.1
+++ sleep.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -12,18 +12,18 @@
 } SLEEPING_THREAD, *PSLEEPING_THREAD;
 
 LIST_ENTRY SleepingThreadsList;
-KSPIN_LOCK SleepingThreadsLock;
+FAST_MUTEX SleepingThreadsLock;
 
 /* clock_init */
 int ncallout = 256;
 struct callout *callout;
 
 void init_freebsd_sched() {
-    KeInitializeSpinLock( &SleepingThreadsLock );
+    ExInitializeFastMutex( &SleepingThreadsLock );
     InitializeListHead( &SleepingThreadsList );    
 }
 
-void tsleep( void *token, int priority, char *wmesg, int tmio ) {
+int tsleep( void *token, int priority, char *wmesg, int tmio ) {
     KIRQL OldIrql;
     KEVENT Event;
     PLIST_ENTRY Entry;
@@ -37,43 +37,65 @@
     if( SleepingThread ) {
 	KeInitializeEvent( &SleepingThread->Event, NotificationEvent, FALSE );
 	SleepingThread->SleepToken = token;
-	ExInterlockedInsertTailList( &SleepingThreadsList,
-				     &SleepingThread->Entry,
-				     &SleepingThreadsLock );
-    }
 
-    OS_DbgPrint(OSK_MID_TRACE,("Waiting on %x\n", token));
-    KeWaitForSingleObject( &SleepingThread->Event,
-			   WrSuspended,
-			   KernelMode,
-			   TRUE,
-			   NULL );
+	ExAcquireFastMutex( &SleepingThreadsLock );
+	InsertTailList( &SleepingThreadsList, &SleepingThread->Entry );
+	ExReleaseFastMutex( &SleepingThreadsLock );
+
+	OS_DbgPrint(OSK_MID_TRACE,("Waiting on %x\n", token));
+	KeWaitForSingleObject( &SleepingThread->Event,
+			       WrSuspended,
+			       KernelMode,
+			       TRUE,
+			       NULL );
+
+	ExAcquireFastMutex( &SleepingThreadsLock );
+	RemoveEntryList( &SleepingThread->Entry );
+	ExReleaseFastMutex( &SleepingThreadsLock );
+
+	ExFreePool( SleepingThread );
+    }
     OS_DbgPrint(OSK_MID_TRACE,("Waiting finished: %x\n", token));
+    return 0;
 }
 
-void wakeup( void *token ) {
+void wakeup( struct socket *so, struct selinfo *si, void *token ) {
     KIRQL OldIrql;
     KEVENT Event;
     PLIST_ENTRY Entry;
     PSLEEPING_THREAD SleepingThread;
-    
-    OS_DbgPrint(OSK_MID_TRACE,("Wakeup %x!\n",token));
 
-    KeAcquireSpinLock( &SleepingThreadsLock, &OldIrql );
+    OS_DbgPrint
+	(OSK_MID_TRACE,("XXX Bytes to receive: %d\n", so->so_rcv.sb_cc));
+
+    if( so->so_rcv.sb_cc && si )
+	si->si_flags |= SEL_READ;
+
+    OS_DbgPrint(OSK_MID_TRACE,("Wakeup %x (socket %x, si_flags %x, state %x)!\n",
+			       token, so, si ? si->si_flags : 0,
+			       so->so_state));
+
+    if( OtcpEvent.SocketState ) {
+	OS_DbgPrint(OSK_MID_TRACE,("Calling client's socket state fn\n"));
+	OtcpEvent.SocketState( OtcpEvent.ClientData,
+			       so,
+			       so->so_connection,
+			       si ? si->si_flags : 0,
+			       so->so_state );
+    }
+
+    ExAcquireFastMutex( &SleepingThreadsLock );
     Entry = SleepingThreadsList.Flink;
     while( Entry != &SleepingThreadsList ) {
 	SleepingThread = CONTAINING_RECORD(Entry, SLEEPING_THREAD, Entry);
+	OS_DbgPrint(OSK_MID_TRACE,("Sleeper @ %x\n", SleepingThread));
 	if( SleepingThread->SleepToken == token ) {
-	    RemoveEntryList(Entry);
-	    KeReleaseSpinLock( &SleepingThreadsLock, OldIrql );
 	    OS_DbgPrint(OSK_MID_TRACE,("Setting event to wake %x\n", token));
-	    KeSetEvent( &SleepingThread->Event, IO_NO_INCREMENT, FALSE );
-	    ExFreePool( SleepingThread );
-	    return;
+	    KeSetEvent( &SleepingThread->Event, IO_NETWORK_INCREMENT, FALSE );
 	}
 	Entry = Entry->Flink;
     }
-    KeReleaseSpinLock( &SleepingThreadsLock, OldIrql );
+    ExReleaseFastMutex( &SleepingThreadsLock );
     OS_DbgPrint(OSK_MID_TRACE,("Wakeup done %x\n", token));
 }
 
@@ -142,32 +164,6 @@
 	return (x);				\
 }
 
-#if 0
-GENSPL(splbio, cpl |= bio_imask)
-GENSPL(splclock, cpl = HWI_MASK | SWI_MASK)
-GENSPL(splhigh, cpl = HWI_MASK | SWI_MASK)
-GENSPL(splimp, cpl |= net_imask)
-GENSPL(splnet, cpl |= SWI_NET_MASK)
-GENSPL(splsoftclock, cpl = SWI_CLOCK_MASK)
-GENSPL(splsofttty, cpl |= SWI_TTY_MASK)
-GENSPL(splstatclock, cpl |= stat_imask)
-GENSPL(spltty, cpl |= tty_imask)
-#endif
-
-#if 0
-void spl0(void) {
-    cpl = SWI_AST_MASK;
-    if (ipending & ~SWI_AST_MASK)
-	splz();
-}
-
-void splx(int ipl) {
-    cpl = ipl;
-    if (ipending & ~ipl)
-	splz();
-}
-#endif
-
 void splz(void) {
     OS_DbgPrint(OSK_MID_TRACE,("Called SPLZ\n"));
 }
@@ -184,26 +180,3 @@
 {
     cpl = x;
 }
-
-void selrecord( struct proc *selector, struct selinfo *sip) {
-    OS_DbgPrint(OSK_MID_TRACE,("Called selrecord\n"));
-}
-
-void wakeupsocket( struct socket *so, struct selinfo *sel ) {
-    void *connection = so->so_connection;
-    char *data = 0;
-    int datalen = 0;
-    int flags = 0;
-    
-    OS_DbgPrint(OSK_MID_TRACE,("Wakeup: %x\n", so));
-#if 0
-    if( soreceive(so, &paddr, 0, &mp0, &controlp, flags) == 0 ) {
-	/* We have data available */
-	OS_DbgPrint(OSK_MID_TRACE,("Data available on %x\n", so));
-    }
-#endif
-}
-
-void selwakeup( struct selinfo *sel ) {
-    OS_DbgPrint(OSK_MID_TRACE,("Called selwakeup\n"));
-}

reactos/drivers/lib/oskittcp/oskittcp
tcp_input.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- tcp_input.c	29 May 2004 00:15:46 -0000	1.1
+++ tcp_input.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -74,58 +74,30 @@
 
 #endif /* TUBA_INCLUDE */
 
-/*
- * Insert segment ti into reassembly queue of tcp with
- * control block tp.  Return TH_FIN if reassembly now includes
- * a segment with FIN.  The macro form does the common case inline
- * (segment is the next to be received on an established connection,
- * and the queue is empty), avoiding linkage into and removal
- * from the queue and repetition of various conversions.
- * Set DELACK for segments received in order, but ack immediately
- * when segments are out of order (so fast retransmit can work).
- */
-#ifdef TCP_ACK_HACK
-#define	TCP_REASS(tp, ti, m, so, flags) { \
-	if ((ti)->ti_seq == (tp)->rcv_nxt && \
-	    (tp)->seg_next == (struct tcpiphdr *)(tp) && \
-	    (tp)->t_state == TCPS_ESTABLISHED) { \
-		if (ti->ti_flags & TH_PUSH) \
-			tp->t_flags |= TF_ACKNOW; \
-		else \
-			tp->t_flags |= TF_DELACK; \
-		(tp)->rcv_nxt += (ti)->ti_len - IPHDR_SIZE; \
-                OS_DbgPrint(OSK_MID_TRACE,("Added %d to rcv_nxt\n", \
-                                           (ti)->ti_len - IPHDR_SIZE)); \
-		flags = (ti)->ti_flags & TH_FIN; \
-		tcpstat.tcps_rcvpack++;\
-		tcpstat.tcps_rcvbyte += (ti)->ti_len;\
-		sbappend(so, &(so)->so_rcv, (m)); \
-		sorwakeup(so); \
-	} else { \
-		(flags) = tcp_reass((tp), (ti), (m)); \
-		tp->t_flags |= TF_ACKNOW; \
-	} \
-}
-#else
 #define	TCP_REASS(tp, ti, m, so, flags) { \
 	if ((ti)->ti_seq == (tp)->rcv_nxt && \
 	    (tp)->seg_next == (struct tcpiphdr *)(tp) && \
 	    (tp)->t_state == TCPS_ESTABLISHED) { \
 		tp->t_flags |= TF_DELACK; \
-		(tp)->rcv_nxt += (ti)->ti_len - IPHDR_SIZE; \
-                OS_DbgPrint(OSK_MID_TRACE,("Added %d to rcv_nxt\n", \
-                                           (ti)->ti_len - IPHDR_SIZE)); \
+                if (!(ti)->ti_flags & TH_FIN && \
+		    !(ti)->ti_flags & TH_RST) { \
+		    (tp)->rcv_nxt += (ti)->ti_len - sizeof(struct ip); \
+                    OS_DbgPrint(OSK_MID_TRACE,("(REASS2) Added %d to rcv_nxt\n", \
+                                               (ti)->ti_len - sizeof(struct ip))); \
+                } else { \
+                    so->so_rcv.sb_sel.si_flags |= SEL_FIN; \
+		} \
 		flags = (ti)->ti_flags & TH_FIN; \
-		tcpstat.tcps_rcvpack++;\
-		tcpstat.tcps_rcvbyte += (ti)->ti_len;\
-		sbappend(so, &(so)->so_rcv, (m)); \
+		tcpstat.tcps_rcvpack++; \
+		tcpstat.tcps_rcvbyte += (ti)->ti_len; \
+                sbappend(so, &so->so_rcv, (m)); \
 		sorwakeup(so); \
 	} else { \
 		(flags) = tcp_reass((tp), (ti), (m)); \
 		tp->t_flags |= TF_ACKNOW; \
 	} \
 }
-#endif
+
 #ifndef TUBA_INCLUDE
 
 int
@@ -231,13 +203,30 @@
 		ti = (struct tcpiphdr *)ti->ti_next;
 		if (so->so_state & SS_CANTRCVMORE)
 		    m_freem(m);
-		else
-			sbappend(so, &so->so_rcv, m);
+		else {
+		    sbappend(so, &so->so_rcv, (m));
+		}
 	} while (ti != (struct tcpiphdr *)tp && ti->ti_seq == tp->rcv_nxt);
 	sorwakeup(so);
 	return (flags);
 }
 
+void rip_input_mini(so, ti, m)
+    struct socket *so;
+    struct tcpiphdr *ti;
+    struct mbuf *m;
+{
+	register struct ip *ip = mtod(m, struct ip *);
+	register struct inpcb *inp;
+	struct	sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
+
+	ripsrc.sin_addr = ti->ti_src;
+	
+	sbappendaddr(&so->so_rcv,
+		     (struct sockaddr *)&ripsrc, m,
+		     (struct mbuf *)0);
+}
+
 /*
  * TCP input routine, follows pages 65-76 of the
  * protocol specification dated September, 1981 very closely.
@@ -249,6 +238,8 @@
 {
 	register struct tcpiphdr *ti;
 	register struct inpcb *inp;
+	struct sockaddr_in addr = { 0 };
+        struct mbuf mhdr = { 0 }, mpayload = { 0 };
 	caddr_t optp = NULL;
 	int optlen = 0;
 	int len, tlen, off;
@@ -342,6 +333,8 @@
 	m->m_data += sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
 	m->m_len  -= sizeof(struct tcpiphdr)+off-sizeof(struct tcphdr);
 
+	OskitDumpBuffer(m->m_data, m->m_len);
+
 	/*
 	 * Locate pcb for segment.
 	 */
@@ -380,6 +373,22 @@
 		tiwin = ti->ti_win;
 
 	so = inp->inp_socket;
+
+#if 0
+	mhdr.m_type = MT_HEADER;
+	memcpy(mhdr.m_pktdat, ti, sizeof(ti));
+	mhdr.m_data = mhdr.m_pktdat;
+	mhdr.m_len = 0;
+	mhdr.m_flags = M_PKTHDR | M_EOR;
+	mhdr.m_next = &mpayload;
+	mpayload.m_type = MT_DATA;
+	mpayload.m_data = m->m_data + sizeof(*ti);
+	mpayload.m_len = m->m_len - sizeof(*ti);
+	mpayload.m_flags = M_EOR;
+
+	rip_input_mini(so, ti, &mhdr);
+#endif
+
 	if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) {
 #ifdef TCPDEBUG
 		if (so->so_options & SO_DEBUG) {
@@ -589,14 +598,17 @@
 			 */
 			++tcpstat.tcps_preddat;
 			tp->rcv_nxt += ti->ti_len;
-			OS_DbgPrint(OSK_MID_TRACE,("Added %d to rcv_nxt\n",
-						   ti->ti_len));
 			tcpstat.tcps_rcvpack++;
 			tcpstat.tcps_rcvbyte += ti->ti_len;
 			/*
 			 * Add data to socket buffer.
 			 */
-			sbappend(so, &so->so_rcv, m);
+			OS_DbgPrint
+			    (OSK_MID_TRACE,("Adding %d to socket buffer\n",
+					    m->m_len));
+
+			sbappend(so, &so->so_rcv, (m));
+			so->so_rcv.sb_cc += m->m_len;
 			sorwakeup(so);
 #ifdef TCP_ACK_HACK
 			/*
@@ -879,6 +891,7 @@
 				  so));
 			    tp->t_state = TCPS_ESTABLISHED;
 			    tp->t_timer[TCPT_KEEP] = tcp_keepidle;
+			    socwakeup(so);
 			}
 		} else {
 		/*
@@ -1173,8 +1186,9 @@
 	 * error and we send an RST and drop the connection.
 	 */
 	if (tiflags & TH_SYN) {
-		tp = tcp_drop(tp, ECONNRESET);
-		goto dropwithreset;
+	    OS_DbgPrint(OSK_MID_TRACE,("SYN In window\n"));
+	    tp = tcp_drop(tp, ECONNRESET);
+	    goto dropwithreset;
 	}
 
 	/*
@@ -1415,7 +1429,7 @@
 			ourfinisacked = 0;
 		}
 		if (so->so_snd.sb_flags & SB_NOTIFY)
-			sowwakeup(so);
+		    sowwakeup(so);
 		tp->snd_una = ti->ti_ack;
 		if (SEQ_LT(tp->snd_nxt, tp->snd_una))
 			tp->snd_nxt = tp->snd_una;
@@ -1522,6 +1536,9 @@
 		 * actually wanting to send this much urgent data.
 		 */
 		if (ti->ti_urp + so->so_rcv.sb_cc > sb_max) {
+		    OS_DbgPrint(OSK_MID_TRACE,
+				("%x: Urgent pointer out of range: %x\n",
+				 ti->ti_urp));
 			ti->ti_urp = 0;			/* XXX */
 			tiflags &= ~TH_URG;		/* XXX */
 			goto dodata;			/* XXX */
@@ -1579,6 +1596,9 @@
 	 * case PRU_RCVD).  If a FIN has already been received on this
 	 * connection then we just ignore the text.
 	 */
+	
+	OS_DbgPrint(OSK_MID_TRACE,("TIFlags: %x\n", tiflags));
+
 	if ((ti->ti_len || (tiflags&TH_FIN)) &&
 	    TCPS_HAVERCVDFIN(tp->t_state) == 0) {
 	    TCP_REASS(tp, ti, m, so, tiflags);
@@ -1589,7 +1609,7 @@
 		 */
 		len = so->so_rcv.sb_hiwat - (tp->rcv_adv - tp->rcv_nxt);
 	} else {
-	    m_freem(m);
+	    /*m_freem(m);*/
 	    tiflags &= ~TH_FIN;
 	}
 

reactos/drivers/lib/oskittcp/oskittcp
tcp_output.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- tcp_output.c	29 May 2004 00:15:46 -0000	1.1
+++ tcp_output.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -85,8 +85,7 @@
 	struct rmxp_tao *taop;
 	struct rmxp_tao tao_noncached;
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
+	OS_DbgPrint(OSK_MID_TRACE,("Start\n"));
 
 	/*
 	 * Determine length of data that should be transmitted,
@@ -102,7 +101,9 @@
 		 * slow start to get ack "clock" running again.
 		 */
 		tp->snd_cwnd = tp->t_maxseg;
+
 again:
+	OS_DbgPrint(OSK_MID_TRACE,("Again...\n"));
 	sendalot = 0;
 	off = tp->snd_nxt - tp->snd_una;
 	win = min(tp->snd_wnd, tp->snd_cwnd);
@@ -237,9 +238,6 @@
 			goto send;
 	}
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
-
 	/*
 	 * Compare available window to amount of window
 	 * known to peer (as advertised window less
@@ -262,9 +260,6 @@
 			goto send;
 	}
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
-
 	/*
 	 * Send if we owe peer an ACK.
 	 */
@@ -284,9 +279,6 @@
 	    ((tp->t_flags & TF_SENTFIN) == 0 || tp->snd_nxt == tp->snd_una))
 		goto send;
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
-
 	/*
 	 * TCP window updates are not reliable, rather a polling protocol
 	 * using ``persist'' packets is used to insure receipt of window
@@ -321,9 +313,6 @@
 	/*return (0);*/
 
 send:
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
-
 	/*
 	 * Before ESTABLISHED, force sending of initial options
 	 * unless TCP set not to do any options.
@@ -358,9 +347,6 @@
 		}
  	}
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
-
  	/*
 	 * Send a timestamp and echo-reply if this is a SYN and our side
 	 * wants to use timestamps (TF_REQ_TSTMP is set) or both our side
@@ -379,9 +365,6 @@
  		optlen += TCPOLEN_TSTAMP_APPA;
  	}
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
-
  	/*
 	 * Send `CC-family' options if our side wants to use them (TF_REQ_CC),
 	 * options are allowed (!TF_NOOPT) and it's not a RST.
@@ -457,9 +440,6 @@
 
  	hdrlen += optlen;
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
-
 	/*
 	 * Adjust data length if insertion of options will
 	 * bump the packet length beyond the t_maxopd length.
@@ -480,8 +460,6 @@
 		panic("tcphdr too big");
 /*#endif*/
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : tp->rcv_nxt %x\n", tp->rcv_nxt));
 
 	/*
 	 * Grab a header mbuf, attaching a copy of data to
@@ -607,21 +585,12 @@
 	if (win < (long)(so->so_rcv.sb_hiwat / 4) && win < (long)tp->t_maxseg)
 		win = 0;
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : AckNumber %x\n", ti->ti_ack));
-
 	if (win > (long)TCP_MAXWIN << tp->rcv_scale)
 		win = (long)TCP_MAXWIN << tp->rcv_scale;
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : AckNumber %x\n", ti->ti_ack));
-
 	if (win < (long)(tp->rcv_adv - tp->rcv_nxt))
 		win = (long)(tp->rcv_adv - tp->rcv_nxt);
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : AckNumber %x\n", ti->ti_ack));
-
 	ti->ti_win = htons((u_short) (win>>tp->rcv_scale));
 	if (SEQ_GT(tp->snd_up, tp->snd_nxt)) {
 	    ti->ti_urp = htons((u_short)(tp->snd_up - tp->snd_nxt));
@@ -640,9 +609,6 @@
 	 * checksum extended header and data.
 	 */
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : AckNumber %x\n", ti->ti_ack));
-
 	if (len + optlen) {
 	    ti->ti_src.s_addr = tp->t_inpcb->inp_laddr.s_addr;
 	    ti->ti_dst.s_addr = tp->t_inpcb->inp_faddr.s_addr;
@@ -651,14 +617,8 @@
 					 optlen + len));
 	}
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : AckNumber %x\n", ti->ti_ack));
-
 	ti->ti_sum = in_cksum(m, (int)(hdrlen + len));
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : AckNumber %x\n", ti->ti_ack));
-
 	/*
 	 * In transmit state, time the transmission and arrange for
 	 * the retransmit.  In persist state, just set snd_max.
@@ -711,9 +671,6 @@
 		if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
 			tp->snd_max = tp->snd_nxt + len;
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : AckNumber %x\n", ti->ti_ack));
-
 #ifdef TCPDEBUG
 	/*
 	 * Trace.
@@ -756,9 +713,7 @@
 	}
 #endif
 
-	OS_DbgPrint(OSK_MID_TRACE,
-		    ("Before IP_OUTPUT : AckNumber %x\n", ti->ti_ack));
-
+	OS_DbgPrint(OSK_MID_TRACE,("Calling ip_output\n"));
 	error = ip_output(so, m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route,
 			  so->so_options & SO_DONTROUTE, 0);
     }
@@ -799,6 +754,8 @@
 		tp->rcv_adv = tp->rcv_nxt + win;
 	tp->last_ack_sent = tp->rcv_nxt;
 	tp->t_flags &= ~(TF_ACKNOW|TF_DELACK);
+	OS_DbgPrint(OSK_MID_TRACE,("sendalot: %d (flags %x)\n", 
+				   sendalot, tp->t_flags));
 	if (sendalot)
 		goto again;
 	return (0);

reactos/drivers/lib/oskittcp/oskittcp
tcp_subr.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- tcp_subr.c	29 May 2004 00:15:46 -0000	1.1
+++ tcp_subr.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -427,7 +427,7 @@
 		so->so_error = error;
 	else
 		tp->t_softerror = error;
-	wakeup((caddr_t) &so->so_timeo);
+	wakeup(so, NULL, (caddr_t) &so->so_timeo);
 	sorwakeup(so);
 	sowwakeup(so);
 }

reactos/drivers/lib/oskittcp/oskittcp
uipc_socket.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- uipc_socket.c	29 May 2004 00:15:46 -0000	1.1
+++ uipc_socket.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -393,7 +393,7 @@
 		    (atomic || space < so->so_snd.sb_lowat || space < clen)) {
 			if (so->so_state & SS_NBIO)
 				snderr(EWOULDBLOCK);
-			sbunlock(&so->so_snd);
+			sbunlock(so, &so->so_snd);
 			error = sbwait(&so->so_snd);
 			splx(s);
 			if (error)
@@ -480,12 +480,14 @@
 	} while (resid);
 
 release:
-	sbunlock(&so->so_snd);
+	sbunlock(so, &so->so_snd);
 out:
+#ifndef __REACTOS__
 	if (top)
-		m_freem(top);
+	    m_freem(top);
 	if (control)
-		m_freem(control);
+	    m_freem(control);
+#endif /* The caller owns top and control */
 	return (error);
 }
 
@@ -506,305 +508,87 @@
  * only for the count in uio_resid.
  */
 int
-soreceive(so, paddr, uio, mp0, controlp, flagsp)
+soreceive(so, paddr, uio, _mp0, controlp, flagsp)
 	register struct socket *so;
 	struct mbuf **paddr;
 	struct uio *uio;
-	struct mbuf **mp0;
+	struct mbuf **_mp0;
 	struct mbuf **controlp;
 	int *flagsp;
 {
-	register struct mbuf *m, **mp;
-	register int flags, len, error, s, offset;
-	struct protosw *pr = so->so_proto;
-	struct mbuf *nextrecord;
-	int moff, type = 0;
-	int orig_resid = uio->uio_resid;
-
-	mp = mp0;
-	if (paddr)
-		*paddr = 0;
-	if (controlp)
-		*controlp = 0;
-	if (flagsp)
-		flags = *flagsp &~ MSG_EOR;
-	else
-		flags = 0;
-	if (flags & MSG_OOB) {
-		m = m_get(M_WAIT, MT_DATA);
-		error = (*pr->pr_usrreq)(so, PRU_RCVOOB,
-		    m, (struct mbuf *)(flags & MSG_PEEK), (struct mbuf *)0);
-		if (error)
-			goto bad;
-		do {
-			error = uiomove(mtod(m, caddr_t),
-			    (int) min(uio->uio_resid, m->m_len), uio);
-			/*m = m_free(m);*/
-		} while (uio->uio_resid && error == 0 && m);
-bad:
-		if (m)
-		    /*m_freem(m);*/
-		return (error);
-	}
-	if (mp)
-		*mp = (struct mbuf *)0;
-	if (so->so_state & SS_ISCONFIRMING && uio->uio_resid)
-		(*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
-		    (struct mbuf *)0, (struct mbuf *)0);
-
-restart:
-	error = sblock(&so->so_rcv, SBLOCKWAIT(flags));
-	if (error)
-		return (error);
-	s = splnet();
-
-	m = so->so_rcv.sb_mb;
-	/*
-	 * If we have less data than requested, block awaiting more
-	 * (subject to any timeout) if:
-	 *   1. the current count is less than the low water mark, or
-	 *   2. MSG_WAITALL is set, and it is possible to do the entire
-	 *	receive operation at once if we block (resid <= hiwat).
-	 *   3. MSG_DONTWAIT is not set
-	 * If MSG_WAITALL is set but resid is larger than the receive buffer,
-	 * we have to do the receive in sections, and thus risk returning
-	 * a short count if a timeout or signal occurs after we start.
-	 */
-	if (m == 0 || (((flags & MSG_DONTWAIT) == 0 &&
-	    so->so_rcv.sb_cc < uio->uio_resid) &&
-	    (so->so_rcv.sb_cc < so->so_rcv.sb_lowat ||
-	    ((flags & MSG_WAITALL) && uio->uio_resid <= so->so_rcv.sb_hiwat)) &&
-	    m->m_nextpkt == 0 && (pr->pr_flags & PR_ATOMIC) == 0)) {
-#ifdef DIAGNOSTIC
-		if (m == 0 && so->so_rcv.sb_cc)
-			panic("receive 1");
-#endif
-		if (so->so_error) {
-			if (m)
-				goto dontblock;
-			error = so->so_error;
-			if ((flags & MSG_PEEK) == 0)
-				so->so_error = 0;
-			goto release;
-		}
-		if (so->so_state & SS_CANTRCVMORE) {
-			if (m)
-				goto dontblock;
-			else
-				goto release;
-		}
-		for (; m; m = m->m_next)
-			if (m->m_type == MT_OOBDATA  || (m->m_flags & M_EOR)) {
-				m = so->so_rcv.sb_mb;
-				goto dontblock;
-			}
-		if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 &&
-		    (so->so_proto->pr_flags & PR_CONNREQUIRED)) {
-			error = ENOTCONN;
-			goto release;
-		}
-		if (uio->uio_resid == 0)
-			goto release;
-		if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) {
-			error = EWOULDBLOCK;
-			goto release;
-		}
-		sbunlock(&so->so_rcv);
-		error = sbwait(&so->so_rcv);
-		splx(s);
-		if (error)
-			return (error);
-		goto restart;
-	}
-dontblock:
-	if (uio->uio_procp)
-		uio->uio_procp->p_stats->p_ru.ru_msgrcv++;
-	nextrecord = m->m_nextpkt;
-	if (pr->pr_flags & PR_ADDR) {
-#ifdef DIAGNOSTIC
-		if (m->m_type != MT_SONAME)
-			panic("receive 1a");
-#endif
-		orig_resid = 0;
-		if (flags & MSG_PEEK) {
-			if (paddr)
-				*paddr = m_copy(m, 0, m->m_len);
-			m = m->m_next;
-		} else {
-			sbfree(&so->so_rcv, m);
-			if (paddr) {
-				*paddr = m;
-				so->so_rcv.sb_mb = m->m_next;
-				m->m_next = 0;
-				m = so->so_rcv.sb_mb;
-			} else {
-				MFREE(m, so->so_rcv.sb_mb);
-				m = so->so_rcv.sb_mb;
-			}
-		}
-	}
-	while (m && m->m_type == MT_CONTROL && error == 0) {
-		if (flags & MSG_PEEK) {
-			if (controlp)
-				*controlp = m_copy(m, 0, m->m_len);
-			m = m->m_next;
-		} else {
-		    sbfree(&so->so_rcv, m);
-			if (controlp) {
-#ifndef __REACTOS__
-				if (pr->pr_domain->dom_externalize &&
-				    mtod(m, struct cmsghdr *)->cmsg_type ==
-				    SCM_RIGHTS)
-				   error = (*pr->pr_domain->dom_externalize)(m);
-				*controlp = m;
-				so->so_rcv.sb_mb = m->m_next;
-				m->m_next = 0;
-				m = so->so_rcv.sb_mb;
-#endif
-			} else {
-			    /*MFREE(m, so->so_rcv.sb_mb);*/
-				m = so->so_rcv.sb_mb;
-			}
-		}
-		if (controlp) {
-			orig_resid = 0;
-			controlp = &(*controlp)->m_next;
-		}
-	}
-	if (m) {
-		if ((flags & MSG_PEEK) == 0)
-			m->m_nextpkt = nextrecord;
-		type = m->m_type;
-		if (type == MT_OOBDATA)
-			flags |= MSG_OOB;
-	}
-	moff = 0;
-	offset = 0;
-	while (m && uio->uio_resid > 0 && error == 0) {
-		if (m->m_type == MT_OOBDATA) {
-			if (type != MT_OOBDATA)
-				break;
-		} else if (type == MT_OOBDATA)
-			break;
-#ifdef DIAGNOSTIC
-		else if (m->m_type != MT_DATA && m->m_type != MT_HEADER)
-			panic("receive 3");
-#endif
-		so->so_state &= ~SS_RCVATMARK;
-		len = uio->uio_resid;
-		if (so->so_oobmark && len > so->so_oobmark - offset)
-			len = so->so_oobmark - offset;
-		if (len > m->m_len - moff)
-			len = m->m_len - moff;
-		/*
-		 * If mp is set, just pass back the mbufs.
-		 * Otherwise copy them out via the uio, then free.
-		 * Sockbuf must be consistent here (points to current mbuf,
-		 * it points to next record) when we drop priority;
-		 * we must note any additions to the sockbuf when we
-		 * block interrupts again.
-		 */
-		if (mp == 0) {
-			splx(s);
-			error = uiomove(mtod(m, caddr_t) + moff, (int)len, uio);
-			s = splnet();
-		} else
-			uio->uio_resid -= len;
-		if (len == m->m_len - moff) {
-			if (m->m_flags & M_EOR)
-				flags |= MSG_EOR;
-			if (flags & MSG_PEEK) {
-				m = m->m_next;
-				moff = 0;
-			} else {
-				nextrecord = m->m_nextpkt;
-				sbfree(&so->so_rcv, m);
-				if (mp) {
-					*mp = m;
-					mp = &m->m_next;
-					so->so_rcv.sb_mb = m = m->m_next;
-					*mp = (struct mbuf *)0;
-				} else {
-				    /*MFREE(m, so->so_rcv.sb_mb);*/
-					m = so->so_rcv.sb_mb;
-				}
-				if (m)
-					m->m_nextpkt = nextrecord;
-			}
-		} else {
-			if (flags & MSG_PEEK)
-				moff += len;
-			else {
-				if (mp)
-					*mp = m_copym(m, 0, len, M_WAIT);
-				m->m_data += len;
-				m->m_len -= len;
-				so->so_rcv.sb_cc -= len;
-			}
-		}
-		if (so->so_oobmark) {
-			if ((flags & MSG_PEEK) == 0) {
-				so->so_oobmark -= len;
-				if (so->so_oobmark == 0) {
-					so->so_state |= SS_RCVATMARK;
-					break;
-				}
-			} else {
-				offset += len;
-				if (offset == so->so_oobmark)
-					break;
-			}
-		}
-		if (flags & MSG_EOR)
-			break;
-		/*
-		 * If the MSG_WAITALL flag is set (for non-atomic socket),
-		 * we must not quit until "uio->uio_resid == 0" or an error
-		 * termination.  If a signal/timeout occurs, return
-		 * with a short count but without error.
-		 * Keep sockbuf locked against other readers.
-		 */
-		while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 &&
-		    !sosendallatonce(so) && !nextrecord) {
-			if (so->so_error || so->so_state & SS_CANTRCVMORE)
-				break;
-			error = sbwait(&so->so_rcv);
-			if (error) {
-				sbunlock(&so->so_rcv);
-				splx(s);
-				return (0);
-			}
-			m = so->so_rcv.sb_mb;
-			if (m)
-				nextrecord = m->m_nextpkt;
-		}
-	}
+    struct mbuf dummy = { 0 };
+    struct mbuf *mb = &dummy, *mn, *mp0 = *_mp0;
+    int total = 0, copyamt;
+
+    dummy.m_nextpkt = so->so_rcv.sb_mb;
+    uio->uio_resid = 0;
+
+    if( mp0->m_len == 0 )
+	return 0;
+
+    if( so->so_rcv.sb_cc == 0 && so->so_rcv.sb_sel.si_flags & SEL_FIN )
+	return OSK_ESHUTDOWN;
+
+    while( mb->m_nextpkt && total < mp0->m_len ) {
+	OS_DbgPrint(OSK_MID_TRACE, ("Looking at packet %x\n", mb));
+
+	if( *flagsp & MSG_OOB ) {
+	    OS_DbgPrint(OSK_MID_TRACE, ("Searching for oob: %x\n", mb));
+	    while( mb->m_nextpkt && mb->m_nextpkt->m_type != MT_OOBDATA ) 
+		mb = mb->m_nextpkt;
+	} else {
+	    while( mb->m_nextpkt && mb->m_nextpkt->m_type != MT_DATA ) {
+		OS_DbgPrint
+		    (OSK_MID_TRACE, 
+		     ("Searching for data: %x (%x@%x)\n", 
+		      mb->m_nextpkt->m_type, 
+		      mb->m_nextpkt->m_len, 
+		      mb->m_nextpkt->m_data));
+		mb = mb->m_nextpkt;
+	    }
+	}
+
+	if( !mb->m_nextpkt ) break;
+
+	mn = mb->m_nextpkt;
+
+	if( !mn->m_next ) mn->m_next = mn->m_data;
+	copyamt = min(mn->m_len, mp0->m_len);
+	OS_DbgPrint(OSK_MID_TRACE,
+		    ("Copying %d bytes (%d,%d) (total is %d so far)\n",
+		     copyamt, mn->m_len, mp0->m_len, total + copyamt));
+	memcpy( mp0->m_data + total, mn->m_next, copyamt );
+	total += copyamt;
+	mp0->m_len -= copyamt;
+
+	if( copyamt < mn->m_len ) {
+	    if( !(*flagsp & MSG_PEEK) ) 
+		((caddr_t)mn->m_next) += copyamt;
+	    break;
+	}	    
+
+	mb->m_nextpkt = mn->m_nextpkt; 
+    }
+
+    /* Free previous buffers if not peek */
+    if( !(*flagsp & MSG_PEEK) ) {
+	while( dummy.m_nextpkt && dummy.m_nextpkt != mn ) {
+	    mb = dummy.m_nextpkt;
+	    dummy.m_nextpkt = mb->m_nextpkt;
+	    OS_DbgPrint
+		(OSK_MID_TRACE,
+		 ("Deleting buf %x", mb));
+	    m_free(mb);
+	}
+	so->so_rcv.sb_cc -= total;
+	so->so_rcv.sb_mb = dummy.m_nextpkt;
+    }
 
-	if (m && pr->pr_flags & PR_ATOMIC) {
-		flags |= MSG_TRUNC;
-		if ((flags & MSG_PEEK) == 0)
-			(void) sbdroprecord(&so->so_rcv);
-	}
-	if ((flags & MSG_PEEK) == 0) {
-		if (m == 0)
-			so->so_rcv.sb_mb = nextrecord;
-		if (pr->pr_flags & PR_WANTRCVD && so->so_pcb)
-			(*pr->pr_usrreq)(so, PRU_RCVD, (struct mbuf *)0,
-			    (struct mbuf *)flags, (struct mbuf *)0);
-	}
-	if (orig_resid == uio->uio_resid && orig_resid &&
-	    (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) {
-		sbunlock(&so->so_rcv);
-		splx(s);
-		goto restart;
-	}
+    uio->uio_resid = total;
 
-	if (flagsp)
-		*flagsp |= flags;
-release:
-	sbunlock(&so->so_rcv);
-	splx(s);
-	return (error);
+    OS_DbgPrint(OSK_MID_TRACE,("Leaving (success)\n"));
+
+    return 0;
 }
 
 int
@@ -836,7 +620,7 @@
 	(void) sblock(sb, M_WAITOK);
 	s = splimp();
 	socantrcvmore(so);
-	sbunlock(sb);
+	sbunlock(so, sb);
 	asb = *sb;
 	bzero((caddr_t)sb, sizeof (*sb));
 	splx(s);
@@ -958,7 +742,7 @@
 	}
 bad:
 	if (m)
-	    /*(void) m_free(m);*/
+	    (void) m_free(m);
 	return (error);
 }
 
@@ -1039,8 +823,8 @@
 		    }
 
 		default:
-			(void)m_free(m);
-			return (ENOPROTOOPT);
+		    (void)m_free(m);
+		    return (ENOPROTOOPT);
 		}
 		*mp = m;
 		return (0);
@@ -1057,5 +841,5 @@
 		gsignal(-so->so_pgid, SIGURG);
 	else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
 		psignal(p, SIGURG);
-	selwakeup(&so->so_rcv.sb_sel);
+	wakeup(so, NULL, 0);
 }

reactos/drivers/lib/oskittcp/oskittcp
uipc_socket2.c 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- uipc_socket2.c	29 May 2004 00:15:46 -0000	1.1
+++ uipc_socket2.c	9 Jun 2004 18:11:37 -0000	1.2
@@ -111,20 +111,14 @@
 	so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
 	so->so_state |= SS_ISCONNECTED;
 	if (head && soqremque(so, 0)) {
-		soqinsque(head, so, 1);
-		sorwakeup(head);
-		wakeup((caddr_t)&head->so_timeo);
+	    soqinsque(head, so, 1);
+	    sorwakeup(head);
+	    wakeup(so, NULL, (caddr_t)&head->so_timeo);
 	} else {
-		wakeup((caddr_t)&so->so_timeo);
-		sorwakeup(so);
-		sowwakeup(so);
+	    wakeup(so, NULL, (caddr_t)&so->so_timeo);
+	    sorwakeup(so);
+	    socwakeup(so);
 	}
-
-	if( OtcpEvent.SocketConnectIndication )
-	    OtcpEvent.SocketConnectIndication
-		( OtcpEvent.ClientData,
-		  so,
-		  so->so_connection );
 }
 
 void
@@ -134,7 +128,7 @@
 
 	so->so_state &= ~SS_ISCONNECTING;
 	so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
-	wakeup((caddr_t)&so->so_timeo);
+	wakeup(so, NULL, (caddr_t)&so->so_timeo);
 	sowwakeup(so);
 	sorwakeup(so);
 }
@@ -146,7 +140,7 @@
 
 	so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
 	so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
-	wakeup((caddr_t)&so->so_timeo);
+	wakeup(so, NULL, (caddr_t)&so->so_timeo);
 	sowwakeup(so);
 	sorwakeup(so);
 }
@@ -194,7 +188,7 @@
 	}
 	if (connstatus) {
 		sorwakeup(head);
-		wakeup((caddr_t)&head->so_timeo);
+		wakeup(so, NULL, (caddr_t)&head->so_timeo);
 		so->so_state |= connstatus;
 	}
 	return (so);
@@ -327,23 +321,7 @@
 {
 	struct proc *p;
 
-	selwakeup(&sb->sb_sel);
-#ifndef OSKIT
-	/*
-	 * in the OS Kit, we do not want notifications to stop
-	 */
-	sb->sb_flags &= ~SB_SEL;
-#endif
-	if (sb->sb_flags & SB_WAIT) {
-		sb->sb_flags &= ~SB_WAIT;
-		wakeup((caddr_t)&sb->sb_cc);
-	}
-	if (so->so_state & SS_ASYNC) {
-		if (so->so_pgid < 0)
-			gsignal(-so->so_pgid, SIGIO);
-		else if (so->so_pgid > 0 && (p = pfind(so->so_pgid)) != 0)
-			psignal(p, SIGIO);
-	}
+	wakeup(so, &sb->sb_sel, (caddr_t)&sb->sb_cc);
 }
 
 /*
@@ -383,7 +361,6 @@
 	register struct socket *so;
 	u_long sndcc, rcvcc;
 {
-
 	if (sbreserve(&so->so_snd, sndcc) == 0)
 		goto bad;
 	if (sbreserve(&so->so_rcv, rcvcc) == 0)
@@ -470,28 +447,47 @@
     struct sockbuf *sb;
     struct mbuf *m;
 {
-	register struct mbuf *n;
+	register struct mbuf *n, *new_mbuf;
+
+	free( malloc( 2 ) );
 
 	if (m == 0)
 		return;
+
 	n = sb->sb_mb;
-	if (n) {
-		while (n->m_nextpkt)
-			n = n->m_nextpkt;
-		do {
-			if (n->m_flags & M_EOR) {
-				sbappendrecord(sb, m); /* XXXXXX!!!! */
-				return;
-			}
-		} while (n->m_next && (n = n->m_next));
-	}
-	OskitDumpBuffer( m->m_data, m->m_len );
-	if( OtcpEvent.SocketDataAvailable )
-	    OtcpEvent.SocketDataAvailable
-		( OtcpEvent.ClientData,
-		  so,
-		  so->so_connection,
-		  m->m_data, m->m_len );
+	OS_DbgPrint(OSK_MID_TRACE,("sbappendrecord: %x\n", n));
+
+	while( n && n->m_nextpkt ) n = n->m_nextpkt;
+
+	new_mbuf = malloc( sizeof( *m ) + m->m_len );
+	memset( new_mbuf, 0, sizeof( *m ) );
+
+	free( malloc( 2 ) );
+
+	new_mbuf->m_type = MT_DATA;
+	free( malloc( 2 ) );
+
+	new_mbuf->m_len = m->m_len;
+	free( malloc( 2 ) );
+
+	new_mbuf->m_data = ((caddr_t)new_mbuf) + sizeof(*new_mbuf);
+	free( malloc( 2 ) );
+
+	memcpy( new_mbuf->m_data, m->m_data, m->m_len );
+
+	free( malloc( 2 ) );
+
+	if( n ) {
+	    n->m_nextpkt = new_mbuf;
+	    OS_DbgPrint(OSK_MID_TRACE,("SK BUFF NEW: %x\n", n->m_nextpkt));
+	} else {
+	    sb->sb_mb = new_mbuf;
+	    OS_DbgPrint(OSK_MID_TRACE,
+			("SK BUFF HEAD: %x (new pkt %d bytes)\n", 
+			 sb->sb_mb, sb->sb_mb->m_len));
+	}
+
+	free( malloc( 2 ) );
 }
 
 #ifdef SOCKBUF_DEBUG
@@ -539,6 +535,7 @@
 	 * Put the first mbuf on the queue.
 	 * Note this permits zero length records.
 	 */
+
 	sballoc(sb, m0);
 	if (m)
 		m->m_nextpkt = m0;
@@ -615,7 +612,7 @@
 	int space = /*asa->sa_len;*/ sizeof(struct sockaddr);
 
 if (m0 && (m0->m_flags & M_PKTHDR) == 0)
-panic("sbappendaddr");
+    panic("sbappendaddr");
 	if (m0)
 		space += m0->m_pkthdr.len;
 	for (n = control; n; n = n->m_next) {
@@ -709,6 +706,8 @@
 			    (unsigned)m->m_len);
 			n->m_len += m->m_len;
 			sb->sb_cc += m->m_len;
+			OS_DbgPrint(OSK_MID_TRACE,("SB->SB_CC = %d\n",
+						   sb->sb_cc));
 			m = m_free(m);
 			continue;
 		}
@@ -771,6 +770,8 @@
 			m->m_len -= len;
 			m->m_data += len;
 			sb->sb_cc -= len;
+			OS_DbgPrint(OSK_MID_TRACE,("SB->SB_CC = %d\n",
+						   sb->sb_cc));
 			break;
 		}
 		len -= m->m_len;

reactos/drivers/net/ndis/ndis
buffer.c 1.8 -> 1.9
diff -u -r1.8 -r1.9
--- buffer.c	11 May 2004 20:52:09 -0000	1.8
+++ buffer.c	9 Jun 2004 18:11:37 -0000	1.9
@@ -52,7 +52,6 @@
     return Offset;
 }
 
-
 UINT CopyBufferToBufferChain(
     PNDIS_BUFFER DstBuffer,
     UINT DstOffset,
@@ -355,6 +354,18 @@
         "VirtualAddress (0x%X)  Length (%d)\n",
         Status, Buffer, PoolHandle, VirtualAddress, Length));
 
+#if 0
+    Temp = Pool->FreeList;
+    while( Temp ) {
+	NDIS_DbgPrint(MID_TRACE,("Free buffer -> %x\n", Temp));
+	Temp = Temp->Next;
+    }
+    
+    NDIS_DbgPrint(MID_TRACE,("|:. <- End free buffers"));
+#endif
+
+    if(!VirtualAddress && !Length) return;
+
     KeAcquireSpinLock(&Pool->SpinLock, &OldIrql);
 
     if (Pool->FreeList) {
@@ -370,13 +381,13 @@
         Temp->Mdl.MdlFlags      |= (MDL_SOURCE_IS_NONPAGED_POOL | MDL_ALLOCATED_FIXED_SIZE);
         Temp->Mdl.MappedSystemVa = VirtualAddress;
 #else
-	    Temp->Mdl.Next = (PMDL)NULL;
-	    Temp->Mdl.Size = (CSHORT)(sizeof(MDL) +
-            (ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length) * sizeof(ULONG)));
-	    Temp->Mdl.MdlFlags   = (MDL_SOURCE_IS_NONPAGED_POOL | MDL_ALLOCATED_FIXED_SIZE);
-;	    Temp->Mdl.StartVa    = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
-	    Temp->Mdl.ByteOffset = (ULONG_PTR)(VirtualAddress - PAGE_ROUND_DOWN(VirtualAddress));
-	    Temp->Mdl.ByteCount  = Length;
+	Temp->Mdl.Next = (PMDL)NULL;
+	Temp->Mdl.Size = (CSHORT)(sizeof(MDL) +
+				  (ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length) * sizeof(ULONG)));
+	Temp->Mdl.MdlFlags   = (MDL_SOURCE_IS_NONPAGED_POOL | MDL_ALLOCATED_FIXED_SIZE);
+	;	    Temp->Mdl.StartVa    = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
+	Temp->Mdl.ByteOffset = (ULONG_PTR)(VirtualAddress - PAGE_ROUND_DOWN(VirtualAddress));
+	Temp->Mdl.ByteCount  = Length;
         Temp->Mdl.MappedSystemVa = VirtualAddress;
 #if 0
 	    //Temp->Mdl.Process    = PsGetCurrentProcess();
@@ -392,6 +403,8 @@
     } else {
         KeReleaseSpinLock(&Pool->SpinLock, OldIrql);
         *Status = NDIS_STATUS_FAILURE;
+	NDIS_DbgPrint(MID_TRACE, ("Can't get another packet.\n"));
+	KeBugCheck(0);
     }
 }
 
@@ -429,10 +442,12 @@
 
         if (NumberOfDescriptors > 0) {
             Buffer             = &Pool->Buffers[0];
+	    DbgPrint("NDIS BUFFER ADDRESS << %x >>\n", Buffer);
             Pool->FreeList     = Buffer;
             for (i = 1; i < NumberOfDescriptors; i++) {
                 Buffer->Next = &Pool->Buffers[i];
                 Buffer       = Buffer->Next;
+		DbgPrint("NDIS BUFFER ADDRESS << %x >>\n", Buffer);
             }
             Buffer->Next = NULL;
         } else
@@ -850,8 +865,8 @@
     Pool = Temp->BufferPool;
 
     KeAcquireSpinLock(&Pool->SpinLock, &OldIrql);
-    Buffer->Next   = (PMDL)Pool->FreeList;
-    Pool->FreeList = (PNETWORK_HEADER)Buffer;
+    Temp->Next     = (PNETWORK_HEADER)Pool->FreeList;
+    Pool->FreeList = (PNETWORK_HEADER)Temp;
     KeReleaseSpinLock(&Pool->SpinLock, OldIrql);
 }
 

reactos/drivers/net/ndis/ndis
miniport.c 1.27 -> 1.28
diff -u -r1.27 -r1.28
--- miniport.c	11 May 2004 20:52:09 -0000	1.27
+++ miniport.c	9 Jun 2004 18:11:37 -0000	1.28
@@ -322,6 +322,8 @@
 
   NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
 
+  if( !Filter ) return;
+
   Adapter = (PLOGICAL_ADAPTER)Filter->Miniport;
 
   NDIS_DbgPrint(MAX_TRACE, ("acquiring miniport block lock\n"));
@@ -372,13 +374,15 @@
  *     PacketSize          = Total size of received packet
  */
 {
-    MiniIndicateData((PLOGICAL_ADAPTER)Filter->Miniport,
-                     MacReceiveContext,
-                     HeaderBuffer,
-                     HeaderBufferSize,
-                     LookaheadBuffer,
-                     LookaheadBufferSize,
-                     PacketSize);
+    if( Filter ) {
+	MiniIndicateData((PLOGICAL_ADAPTER)Filter->Miniport,
+			 MacReceiveContext,
+			 HeaderBuffer,
+			 HeaderBufferSize,
+			 LookaheadBuffer,
+			 LookaheadBufferSize,
+			 PacketSize);
+    }
 }
 
 
@@ -1555,6 +1559,7 @@
           NDIS_DbgPrint(MIN_TRACE, ("error: unsupported media\n"));
           ExFreePool(Adapter);
           ASSERT(FALSE);
+	  KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
           return;
         }
 

reactos/drivers/net/ndis/ndis
protocol.c 1.16 -> 1.17
diff -u -r1.16 -r1.17
--- protocol.c	11 May 2004 20:52:09 -0000	1.16
+++ protocol.c	9 Jun 2004 18:11:37 -0000	1.17
@@ -411,6 +411,7 @@
     /* XXX sd - why is that true? */
 
     if (Packet == Adapter->LoopPacket) {
+	NDIS_DbgPrint(MAX_TRACE, ("LoopPacket\n"));
         /* NDIS is responsible for looping this packet */
         NdisCopyFromPacketToPacket(Packet,
                                    ByteOffset,

reactos/drivers/net/tcpip
makefile 1.16 -> 1.17
diff -u -r1.16 -r1.17
--- makefile	4 Mar 2004 20:45:38 -0000	1.16
+++ makefile	9 Jun 2004 18:11:37 -0000	1.17
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.16 2004/03/04 20:45:38 chorns Exp $
+# $Id: makefile,v 1.17 2004/06/09 18:11:37 arty Exp $
 
 PATH_TO_TOP = ../../..
 
@@ -8,9 +8,16 @@
 
 TARGET_NAME = tcpip
 
-TARGET_CFLAGS = -I./include -DDBG=1 -DNDIS40 -D__USE_W32API
+TARGET_CFLAGS = \
+	-D__USE_W32API \
+	-DNDIS40 \
+	-DMEMTRACK \
+	-I./include \
+	-I$(PATH_TO_TOP)/drivers/lib/oskittcp/include \
+	-I$(PATH_TO_TOP)/w32api/include \
+	-I$(PATH_TO_TOP)/include
 
-TARGET_DDKLIBS = ndis.a
+TARGET_DDKLIBS = ndis.a $(PATH_TO_TOP)/dk/w32/lib/oskittcp.a
 
 TARGET_CLEAN = \
   tcpip/*.o \
@@ -19,32 +26,35 @@
   transport/datagram/*.o \
   transport/rawip/*.o \
   transport/tcp/*.o \
-  transport/udp/*.o
+  transport/udp/*.o 
 
 TCPIP_OBJECTS    = tcpip/main.o tcpip/address.o tcpip/checksum.o \
-                   tcpip/dispatch.o tcpip/fileobjs.o tcpip/info.o \
-                   tcpip/pool.o tcpip/routines.o
+                   tcpip/dispatch.o tcpip/fileobjs.o \
+                   tcpip/pool.o tcpip/routines.o tcpip/interface.o \
+		   tcpip/memtrack.o tcpip/irp.o
+INFO_OBJECTS     = tcpip/info.o tcpip/ninfo.o tcpip/tinfo.o tcpip/iinfo.o
 DATALINK_OBJECTS = datalink/arp.o datalink/lan.o datalink/loopback.o
 NETWORK_OBJECTS  = network/icmp.o network/ip.o network/neighbor.o \
                    network/receive.o network/route.o network/router.o \
-                   network/transmit.o
+                   network/transmit.o network/prefix.o
 DATAGRAM_OBJECTS = transport/datagram/datagram.o
 RAWIP_OBJECTS    = transport/rawip/rawip.o
-TCP_OBJECTS      = transport/tcp/tcp.o transport/tcp/tcpcore.o \
-                   transport/tcp/tcp_input.o transport/tcp/tcp_ipv4.o \
-                   transport/tcp/tcp_output.o transport/tcp/tcp_timer.o
+TCP_OBJECTS      = transport/tcp/tcp.o transport/tcp/event.o transport/tcp/if.o
 UDP_OBJECTS      = transport/udp/udp.o
 ARCH_OBJECTS     = tcpip/i386/checksum.o
 
 TARGET_OBJECTS = \
   $(TCPIP_OBJECTS) \
+  $(INFO_OBJECTS) \
   $(DATALINK_OBJECTS) \
   $(NETWORK_OBJECTS) \
   $(DATAGRAM_OBJECTS) \
   $(RAWIP_OBJECTS) \
   $(TCP_OBJECTS) \
+  $(FREEBSD_OBJECTS) \
+  $(REACTOS_OBJECTS) \
   $(UDP_OBJECTS) \
-  $(ARCH_OBJECTS)
+  $(ARCH_OBJECTS) \
 
 include $(PATH_TO_TOP)/rules.mak
 

reactos/drivers/net/tcpip
notes.txt 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- notes.txt	4 Mar 2004 20:45:38 -0000	1.1
+++ notes.txt	9 Jun 2004 18:11:37 -0000	1.2
@@ -1,4 +1,12 @@
 
+Ideas for optimizations:
+
+* transmit.c (SendFragments, IPSendComplete):
+  Keep IPFRAGMENT_CONTEXT objects and PathMTU buffers in a pool
+
+
+References:
+
 RFC 791 - Internet Protocol
 http://www.faqs.org/rfcs/rfc791.html
 

reactos/drivers/net/tcpip/datalink
arp.c 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- arp.c	11 May 2004 20:52:09 -0000	1.5
+++ arp.c	9 Jun 2004 18:11:37 -0000	1.6
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <arp.h>
 #include <routines.h>
@@ -43,42 +44,25 @@
  */
 {
     PNDIS_PACKET NdisPacket;
-    PNDIS_BUFFER NdisBuffer;
     NDIS_STATUS NdisStatus;
     PARP_HEADER Header;
     PVOID DataBuffer;
-    ULONG Size;
+    ULONG Size, Contig;
 
     TI_DbgPrint(DEBUG_ARP, ("Called.\n"));
 
     /* Prepare ARP packet */
-    Size = MaxLLHeaderSize + sizeof(ARP_HEADER) + 
+    Size = MaxLLHeaderSize +
+	sizeof(ARP_HEADER) + 
         2 * LinkAddressLength + /* Hardware address length */
         2 * ProtoAddressLength; /* Protocol address length */
     Size = MAX(Size, MinLLFrameSize);
 
-    DataBuffer = ExAllocatePool(NonPagedPool, Size);
-    if (!DataBuffer)
-        return NULL;
-
-    /* Allocate NDIS packet */
-    NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
-    if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        ExFreePool(DataBuffer);
-        return NULL;
-    }
+    NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, Size );
+    if( !NT_SUCCESS(NdisStatus) ) return NULL;
 
-    /* Allocate NDIS buffer for maximum link level header and ARP packet */
-    NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
-        DataBuffer, Size);
-    if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        NdisFreePacket(NdisPacket);
-        ExFreePool(DataBuffer);
-        return NULL;
-    }
+    GetDataPtr( NdisPacket, 0, &DataBuffer, &Contig );
 
-    /* Link NDIS buffer into packet */
-    NdisChainBufferAtFront(NdisPacket, NdisBuffer);
     RtlZeroMemory(DataBuffer, Size);
     Header = (PARP_HEADER)((ULONG_PTR)DataBuffer + MaxLLHeaderSize);
     Header->HWType       = HardwareType;
@@ -126,7 +110,6 @@
  */
 {
     TI_DbgPrint(DEBUG_ARP, ("Called.\n"));
-
     FreeNdisPacket(NdisPacket);
 }
 

reactos/drivers/net/tcpip/datalink
lan.c 1.15 -> 1.16
diff -u -r1.15 -r1.16
--- lan.c	11 May 2004 20:52:09 -0000	1.15
+++ lan.c	9 Jun 2004 18:11:37 -0000	1.16
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <lan.h>
 #include <address.h>
@@ -20,7 +21,6 @@
 LIST_ENTRY AdapterListHead;
 KSPIN_LOCK AdapterListLock;
 
-
 NDIS_STATUS NDISCall(
     PLAN_ADAPTER Adapter,
     NDIS_REQUEST_TYPE Type,
@@ -73,72 +73,6 @@
 }
 
 
-PNDIS_PACKET AllocateTDPacket(
-    PLAN_ADAPTER Adapter)
-/*
- * FUNCTION: Allocates an NDIS packet for NdisTransferData
- * ARGUMENTS:
- *     Adapter = Pointer to LAN_ADAPTER structure
- * RETURNS:
- *     Pointer to NDIS packet or NULL if there was not enough free
- *     non-paged memory
- */
-{
-    NDIS_STATUS NdisStatus;
-    PNDIS_PACKET NdisPacket;
-    PNDIS_BUFFER Buffer;
-    PVOID Data;
-
-    NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
-    if (NdisStatus != NDIS_STATUS_SUCCESS)
-        return NULL;
-
-    Data = ExAllocatePool(NonPagedPool, Adapter->MTU);
-    if (!Data) {
-        NdisFreePacket(NdisPacket);
-        return NULL;
-    }
-        
-    NdisAllocateBuffer(&NdisStatus,
-                      &Buffer,
-                      GlobalBufferPool,
-                      Data,
-                      Adapter->MTU);
-    if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        NdisFreePacket(NdisPacket);
-        ExFreePool(Data);
-        return NULL;
-    }
-
-    NdisChainBufferAtFront(NdisPacket, Buffer);
-
-    PC(NdisPacket)->Context = NULL; /* End of list */
-
-    return NdisPacket;
-}
-
-
-VOID FreeTDPackets(
-    PLAN_ADAPTER Adapter)
-/*
- * FUNCTION: Frees transfer data packets
- * ARGUMENTS:
- *     Adapter = Pointer to LAN_ADAPTER structure
- */
-{
-    PNDIS_PACKET NdisPacket, Next;
-
-    /* Release transfer data packets */
-    NdisPacket = Adapter->TDPackets;
-    while (NdisPacket) {
-        Next = PC(NdisPacket)->Context;
-        FreeNdisPacket(NdisPacket);
-        NdisPacket = Next;
-    }
-    Adapter->TDPackets = NULL;
-}
-
-
 VOID FreeAdapter(
     PLAN_ADAPTER Adapter)
 /*
@@ -147,8 +81,7 @@
  *     Adapter = Pointer to LAN_ADAPTER structure to free
  */
 {
-    FreeTDPackets(Adapter);
-    ExFreePool(Adapter);
+    exFreePool(Adapter);
 }
 
 
@@ -241,12 +174,11 @@
  *     Status         = Status of the operation
  */
 {
-	PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
+    PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
 
     TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
 
     AdjustPacket(Packet, Adapter->HeaderSize, PC(Packet)->DLOffset);
-
     (*PC(Packet)->DLComplete)(Adapter->Context, Packet, Status);
 }
 
@@ -285,28 +217,35 @@
                                      &IPPacket.ContigSize,
                                      &IPPacket.TotalSize);
 
+	IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred;
         /* Determine which upper layer protocol that should receive
            this packet and pass it to the correct receive handler */
+
+        OskitDumpBuffer( IPPacket.Header, BytesTransferred );
+
         PacketType = ((PETH_HEADER)IPPacket.Header)->EType;
+	IPPacket.Header += MaxLLHeaderSize;
+
+	TI_DbgPrint
+		(DEBUG_DATALINK,
+		 ("Ether Type = %x ContigSize = %d Total = %d\n",
+		  PacketType, IPPacket.ContigSize, IPPacket.TotalSize));
+	
         switch (PacketType) {
             case ETYPE_IPv4:
             case ETYPE_IPv6:
+		TI_DbgPrint(MID_TRACE,("Received IP Packet\n"));
                 IPReceive(Adapter->Context, &IPPacket);
                 break;
             case ETYPE_ARP:
+		TI_DbgPrint(MID_TRACE,("Received ARP Packet\n"));
                 ARPReceive(Adapter->Context, &IPPacket);
             default:
                 break;
         }
     }
 
-    /* Release the packet descriptor */
-    KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
-
-    PC(Packet)->Context = Adapter->TDPackets;
-    Adapter->TDPackets  = Packet;
-
-    KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
+    FreeNdisPacket( Packet );
 }
 
 
@@ -333,8 +272,10 @@
  */
 {
     USHORT EType;
-    UINT PacketType;
+    UINT PacketType, BytesTransferred;
     IP_PACKET IPPacket;
+    PCHAR BufferData;
+    NDIS_STATUS NdisStatus;
     PNDIS_PACKET NdisPacket;
     PNDIS_BUFFER NdisBuffer;
     PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
@@ -374,22 +315,13 @@
     /* Get a transfer data packet */
 
     KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
+    NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, Adapter->MTU );
+    if( NdisStatus != NDIS_STATUS_SUCCESS ) return NDIS_STATUS_NOT_ACCEPTED;
+    GetDataPtr( NdisPacket, 0, &BufferData, &PacketSize );
 
-    NdisPacket = Adapter->TDPackets;
-    if (NdisPacket == (PNDIS_PACKET)NULL) {
-        TI_DbgPrint(DEBUG_DATALINK, ("No available packet descriptors.\n"));
-        /* We don't have a free packet descriptor. Drop the packet */
-        KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
-        return NDIS_STATUS_SUCCESS;
-    }
-    Adapter->TDPackets = PC(NdisPacket)->Context;
-
-    KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
-
+    IPPacket.NdisPacket = NdisPacket;
+	
     if (LookaheadBufferSize < PacketSize) {
-        NDIS_STATUS NdisStatus;
-        UINT BytesTransferred;
-
         /* Get the data */
         NdisTransferData(&NdisStatus,
                          Adapter->NdisHandle,
@@ -398,45 +330,23 @@
                          PacketSize,
                          NdisPacket,
                          &BytesTransferred);
-        if (NdisStatus != NDIS_STATUS_PENDING)
-            ProtocolTransferDataComplete(BindingContext,
-                                         NdisPacket,
-                                         NdisStatus,
-                                         BytesTransferred);
-
-        return NDIS_STATUS_SUCCESS;
+    } else {
+	NdisStatus = NDIS_STATUS_SUCCESS;
+	BytesTransferred = PacketSize;
+	RtlCopyMemory(BufferData,
+		      HeaderBuffer, 
+		      HeaderBufferSize);
+	RtlCopyMemory(BufferData + HeaderBufferSize,
+		      LookaheadBuffer, LookaheadBufferSize);
     }
 
-    /* We got all the data in the lookahead buffer */
-
-    IPPacket.NdisPacket = NdisPacket;
-
-    NdisGetFirstBufferFromPacket(NdisPacket,
-                                 &NdisBuffer,
-                                 &IPPacket.Header,
-                                 &IPPacket.ContigSize,
-                                 &IPPacket.TotalSize);
-
-    RtlCopyMemory(IPPacket.Header, LookaheadBuffer, PacketSize);
-
-    switch (PacketType) {
-        case ETYPE_IPv4:
-        case ETYPE_IPv6:
-            IPReceive(Adapter->Context, &IPPacket);
-            break;
-        case ETYPE_ARP:
-            ARPReceive(Adapter->Context, &IPPacket);
-            break;
-        default:
-            break;
-    }
+    if (NdisStatus != NDIS_STATUS_PENDING)
+	ProtocolTransferDataComplete(BindingContext,
+				     NdisPacket,
+				     NdisStatus,
+				     BytesTransferred);
 
     /* Release the packet descriptor */
-    KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
-
-    PC(NdisPacket)->Context = Adapter->TDPackets;
-    Adapter->TDPackets      = NdisPacket;
-
     KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
 
     return NDIS_STATUS_SUCCESS;
@@ -537,7 +447,7 @@
        area so it can be undone before we release the packet */
     Data = AdjustPacket(NdisPacket, Offset, Adapter->HeaderSize);
     PC(NdisPacket)->DLOffset = Offset;
-
+	
     if (Adapter->State == LAN_STATE_STARTED) {
         switch (Adapter->Media) {
         case NdisMedium802_3:
@@ -633,7 +543,7 @@
     if(!AnsiLen)
 	return STATUS_NO_MEMORY;
     
-    AnsiAddress.Buffer = ExAllocatePoolWithTag(PagedPool, AnsiLen, 0x01020304);
+    AnsiAddress.Buffer = exAllocatePoolWithTag(PagedPool, AnsiLen, 0x01020304);
     if(!AnsiAddress.Buffer)
 	return STATUS_NO_MEMORY;
 
@@ -642,14 +552,14 @@
     
     Status = RtlUnicodeStringToAnsiString(&AnsiAddress, &UnicodeAddress, FALSE);
     if (!NT_SUCCESS(Status)) {
-	ExFreePool(AnsiAddress.Buffer);
+	exFreePool(AnsiAddress.Buffer);
 	return STATUS_UNSUCCESSFUL;
     }
     
     AnsiAddress.Buffer[AnsiAddress.Length] = 0;
     *Address = AddrBuildIPv4(inet_addr(AnsiAddress.Buffer));
     if (!Address) {
-	ExFreePool(AnsiAddress.Buffer);
+	exFreePool(AnsiAddress.Buffer);
 	return STATUS_UNSUCCESSFUL;
     }
 
@@ -693,20 +603,6 @@
         return;
     }
 
-    /* Allocate packets for NdisTransferData */
-    /* FIXME: How many should we allocate? */
-    Adapter->TDPackets = NULL;
-    for (i = 0; i < 2; i++) {
-        Packet              = AllocateTDPacket(Adapter);
-        if (!Packet) {
-            TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-            FreeTDPackets(Adapter);
-            return;
-        }
-        PC(Packet)->Context = Adapter->TDPackets;
-        Adapter->TDPackets  = Packet;
-    }
-
     /* Bind the adapter to IP layer */
     BindInfo.Context       = Adapter;
     BindInfo.HeaderSize    = Adapter->HeaderSize;
@@ -717,9 +613,9 @@
     BindInfo.Transmit      = LANTransmit;
 
     IF = IPCreateInterface(&BindInfo);
+
     if (!IF) {
         TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-        FreeTDPackets(Adapter);
         return;
     }
 
@@ -750,7 +646,6 @@
 	    ZwClose(RegHandle);
 	if(Address) Address->Free(Address);
 	if(Netmask) Netmask->Free(Netmask);
-	FreeTDPackets(Adapter);
 	IPDestroyInterface(IF);
 	return;
     }
@@ -769,7 +664,6 @@
     if (!IPCreateNTE(IF, Address, AddrCountPrefixBits(Netmask))) {
 	Netmask->Free(Netmask);
         TI_DbgPrint(MIN_TRACE, ("IPCreateNTE() failed.\n"));
-        FreeTDPackets(Adapter);
         IPDestroyInterface(IF);
         return;
     }
@@ -791,13 +685,11 @@
                           sizeof(UINT));
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
         TI_DbgPrint(MID_TRACE, ("Could not set packet filter (0x%X).\n", NdisStatus));
-        FreeTDPackets(Adapter);
         IPDestroyInterface(IF);
         return;
     }
 
     Adapter->Context = IF;
-
     Adapter->State = LAN_STATE_STARTED;
 }
 
@@ -818,9 +710,6 @@
         IPUnregisterInterface(IF);
 
         IPDestroyInterface(IF);
-
-        /* Free transfer data packets */
-        FreeTDPackets(Adapter);
     }
 }
 
@@ -848,7 +737,7 @@
 
     TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
 
-    IF = ExAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER));
+    IF = exAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER));
     if (!IF) {
         TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
         return NDIS_STATUS_RESOURCES;
@@ -885,7 +774,7 @@
     if (NdisStatus == NDIS_STATUS_PENDING)
         KeWaitForSingleObject(&IF->Event, UserRequest, KernelMode, FALSE, NULL);
     else if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        ExFreePool(IF);
+	exFreePool(IF);
         return NdisStatus;
     }
 
@@ -910,7 +799,7 @@
     default:
         /* Unsupported media */
         TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
-        ExFreePool(IF);
+        exFreePool(IF);
         return NDIS_STATUS_NOT_SUPPORTED;
     }
 
@@ -921,7 +810,7 @@
                           &IF->MTU,
                           sizeof(UINT));
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        ExFreePool(IF);
+        exFreePool(IF);
         return NdisStatus;
     }
 
@@ -933,7 +822,7 @@
                           sizeof(UINT));
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
         TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n"));
-        ExFreePool(IF);
+        exFreePool(IF);
         return NdisStatus;
     }
 
@@ -956,7 +845,7 @@
                           IF->HWAddressLength);
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
         TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n"));
-        ExFreePool(IF);
+        exFreePool(IF);
         return NdisStatus;
     }
 
@@ -968,7 +857,7 @@
                           sizeof(UINT));
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
         TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n"));
-        ExFreePool(IF);
+        exFreePool(IF);
         return NdisStatus;
     }
 

reactos/drivers/net/tcpip/datalink
loopback.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- loopback.c	11 May 2004 20:52:09 -0000	1.7
+++ loopback.c	9 Jun 2004 18:11:37 -0000	1.8
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <loopback.h>
 #include <ip.h>
@@ -169,6 +170,7 @@
       BindInfo.Transmit = LoopTransmit;
 
       Loopback = IPCreateInterface(&BindInfo);
+
       if ((Loopback != NULL) && (IPCreateNTE(Loopback, Address, 8)))
         {
           /* Reference the interface for the NTE. The reference for

reactos/drivers/net/tcpip/include
interface.h 1.1 -> 1.2
diff -N interface.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ interface.h	9 Jun 2004 18:11:37 -0000	1.2
@@ -0,0 +1,16 @@
+#ifndef _TCPIP_INTERFACE_H
+#define _TCPIP_INTERFACE_H
+
+#include <ip.h>
+
+NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface,
+				  ULONG Type,
+				  PULONG Address );
+
+UINT CountInterfaces();
+
+NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed );
+NTSTATUS GetInterfaceName( PIP_INTERFACE Interface, PCHAR NameBuffer,
+			   UINT NameMaxLen );
+
+#endif//_TCPIP_INTERFACE_H

reactos/drivers/net/tcpip/include
memtrack.h 1.1 -> 1.2
diff -N memtrack.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ memtrack.h	9 Jun 2004 18:11:37 -0000	1.2
@@ -0,0 +1,74 @@
+#ifndef MEMTRACK_H
+#define MEMTRACK_H
+
+#ifndef FOURCC
+#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
+#endif
+
+#define FBSD_MALLOC FOURCC('d','s','b','f')
+#define EXALLOC_TAG FOURCC('E','x','A','l')
+
+#define AllocatePacketWithBuffer(x,y,z) AllocatePacketWithBufferX(x,y,z,__FILE__,__LINE__)
+#define FreeNdisPacket(x) FreeNdisPacketX(x,__FILE__,__LINE__)
+
+#ifdef MEMTRACK
+#define MTMARK() TrackDumpFL(__FILE__, __LINE__)
+#define NdisAllocateBuffer(x,y,z,a,b) { \
+    NdisAllocateBuffer(x,y,z,a,b); \
+    if( *x == NDIS_STATUS_SUCCESS ) { \
+        Track(NDIS_BUFFER_TAG, *y); \
+    } \
+}
+#define NdisAllocatePacket(x,y,z) { \
+    NdisAllocatePacket(x,y,z); \
+    if( *x == NDIS_STATUS_SUCCESS ) { \
+        Track(NDIS_PACKET_TAG, *y); \
+    } \
+}
+#define NdisFreePacket(x) { Untrack(x); NdisFreePacket(x); }
+#define NdisFreeBuffer(x) { Untrack(x); NdisFreeBuffer(x); }
+#define exAllocatePool(x,y) ExAllocatePoolX(x,y,__FILE__,__LINE__) 
+#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolX(x,y,__FILE__,__LINE__)
+#define exFreePool(x) ExFreePoolX(x,__FILE__,__LINE__)
+
+extern LIST_ENTRY AllocatedObjectsHead;
+extern KSPIN_LOCK AllocatedObjectsLock;
+
+typedef struct _ALLOCATION_TRACKER {
+    LIST_ENTRY Entry;
+    DWORD Tag;
+    PVOID Thing;
+    PCHAR FileName;
+    DWORD LineNo;
+} ALLOCATION_TRACKER, *PALLOCATION_TRACKER;
+
+VOID TrackingInit();
+VOID TrackWithTag( DWORD Tag, PVOID Thing, PCHAR File, DWORD Line );
+#define Track(Tag,Thing) TrackWithTag(Tag,Thing,__FILE__,__LINE__)
+VOID UntrackFL( PCHAR File, DWORD Line, PVOID Thing );
+#define Untrack(Thing) UntrackFL(__FILE__,__LINE__,Thing)
+VOID TrackDumpFL( PCHAR File, DWORD Line );
+#define TrackDump() TrackDumpFL(__FILE__,__LINE__)
+VOID TrackTag( DWORD Tag );
+
+static inline PVOID ExAllocatePoolX( POOL_TYPE type, SIZE_T size, PCHAR File, ULONG Line ) {
+    PVOID Out = ExAllocatePool( type, size );
+    if( Out ) TrackWithTag( EXALLOC_TAG, Out, File, Line );
+    return Out;
+}
+static inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) {
+    UntrackFL(File, Line, Data);
+    ExFreePool(Data);
+}
+
+#define MEMTRACK_MAX_TAGS_TO_TRACK 64
+#else
+#define MTMARK()
+#define Track(x,y)
+#define TrackingInit()
+#define TrackDump()
+#define Untrack(x)
+#define TrackTag(x)
+#endif
+
+#endif/*MEMMTRAC_H*/

reactos/drivers/net/tcpip/include
prefix.h 1.1 -> 1.2
diff -N prefix.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ prefix.h	9 Jun 2004 18:11:37 -0000	1.2
@@ -0,0 +1,28 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS TCP/IP protocol driver
+ * FILE:        include/info.h
+ * PURPOSE:     TdiQueryInformation definitions
+ */
+#ifndef __PREFIX_H
+#define __PREFIX_H
+
+/* Prefix List Entry */
+typedef struct _PREFIX_LIST_ENTRY {
+    DEFINE_TAG
+    LIST_ENTRY ListEntry;    /* Entry on list */
+    ULONG RefCount;          /* Reference count */
+    PIP_INTERFACE Interface; /* Pointer to interface */
+    PIP_ADDRESS Prefix;      /* Pointer to prefix */
+    UINT PrefixLength;       /* Length of prefix */
+} PREFIX_LIST_ENTRY, *PPREFIX_LIST_ENTRY;
+
+extern LIST_ENTRY PrefixListHead;
+extern KSPIN_LOCK PrefixListLock;
+
+VOID InitPLE();
+PPREFIX_LIST_ENTRY CreatePLE(PIP_INTERFACE IF, PIP_ADDRESS Prefix, UINT Len);
+VOID DestroyPLE(PPREFIX_LIST_ENTRY PLE);
+VOID DestroyPLEs();
+
+#endif/*__PREFIX_H*/

reactos/drivers/net/tcpip/include
datagram.h 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- datagram.h	4 Jul 2001 20:40:22 -0000	1.4
+++ datagram.h	9 Jun 2004 18:11:37 -0000	1.5
@@ -35,9 +35,7 @@
 NTSTATUS DGSendDatagram(
   PTDI_REQUEST Request,
   PTDI_CONNECTION_INFORMATION ConnInfo,
-  PNDIS_BUFFER Buffer,
-  ULONG DataSize,
-  DATAGRAM_BUILD_ROUTINE Build);
+  PIP_PACKET Packet);
 
 NTSTATUS DGReceiveDatagram(
   PTDI_REQUEST Request,

reactos/drivers/net/tcpip/include
debug.h 1.8 -> 1.9
diff -u -r1.8 -r1.9
--- debug.h	25 Dec 2003 14:06:14 -0000	1.8
+++ debug.h	9 Jun 2004 18:11:37 -0000	1.9
@@ -57,6 +57,7 @@
 
 #endif /* _MSC_VER */
 
+#if 0
 #ifdef ASSERT
 #undef ASSERT
 #endif
@@ -66,6 +67,7 @@
 #else /* NASSERT */
 #define ASSERT(x) if (!(x)) { TI_DbgPrint(MIN_TRACE, ("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__)); KeBugCheck(0); }
 #endif /* NASSERT */
+#endif
 
 #define ASSERT_IRQL(x) ASSERT(KeGetCurrentIrql() <= (x))
 
@@ -73,8 +75,10 @@
 
 #define TI_DbgPrint(_t_, _x_)
 
+#if 0
 #define ASSERT_IRQL(x)
 #define ASSERT(x)
+#endif
 
 #endif /* DBG */
 
@@ -103,6 +107,8 @@
 
 #define CP CHECKPOINT
 
+#include <memtrack.h>
+
 #endif /* __DEBUG_H */
 
 /* EOF */

reactos/drivers/net/tcpip/include
info.h 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- info.h	12 Mar 2004 04:21:59 -0000	1.5
+++ info.h	9 Jun 2004 18:11:37 -0000	1.6
@@ -48,7 +48,7 @@
 
 typedef struct IPROUTE_ENTRY {
     ULONG Dest;
-    ULONG Index;            //matches if_index in IFEntry and iae_index in IPAddrEntry
+    ULONG Index;    //matches if_index in IFEntry and iae_index in IPAddrEntry
     ULONG Metric1;
     ULONG Metric2;
     ULONG Metric3;
@@ -87,13 +87,13 @@
  
 #define	IP_MIB_STATS_ID           1
 #define IF_MIB_STATS_ID           1
+
+#ifndef IP_MIB_ROUTETABLE_ENTRY_ID
+#define IP_MIB_ROUTETABLE_ENTRY_ID 0x101
+#endif
 #ifndef IP_MIB_ADDRTABLE_ENTRY_ID
 #define	IP_MIB_ADDRTABLE_ENTRY_ID 0x102
 #endif
-#ifndef IP_MIB_ROUTETABLE_ENTRY_ID
-#define IP_MIB_ROUTETABLE_ENTRY_ID 0x103
-#endif
-
 #ifndef MAX_PHYSADDR_SIZE
 #define	MAX_PHYSADDR_SIZE 8
 #endif
@@ -137,6 +137,59 @@
     PVOID Buffer,
     UINT BufferSize);
 
+/* Network layer info functions */
+TDI_STATUS InfoNetworkLayerTdiQueryEx( UINT InfoClass,
+				       UINT InfoType,
+				       UINT InfoId,
+				       PVOID Context,
+				       TDIEntityID *id,
+				       PNDIS_BUFFER Buffer,
+				       PUINT BufferSize );
+
+TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass,
+				     UINT InfoType,
+				     UINT InfoId,
+				     PVOID Context,
+				     TDIEntityID *id,
+				     PCHAR Buffer,
+				     UINT BufferSize );
+
+TDI_STATUS InfoTransportLayerTdiQueryEx( UINT InfoClass,
+					 UINT InfoType,
+					 UINT InfoId,
+					 PVOID Context,
+					 TDIEntityID *id,
+					 PNDIS_BUFFER Buffer,
+					 PUINT BufferSize );
+
+TDI_STATUS InfoTransportLayerTdiSetEx( UINT InfoClass,
+				       UINT InfoType,
+				       UINT InfoId,
+				       PVOID Context,
+				       TDIEntityID *id,
+				       PCHAR Buffer,
+				       UINT BufferSize );
+
+TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass,
+				    UINT InfoType,
+				    UINT InfoId,
+				    PVOID Context,
+				    TDIEntityID *id,
+				    PNDIS_BUFFER Buffer,
+				    PUINT BufferSize );
+
+TDI_STATUS InfoInterfaceTdiSetEx( UINT InfoClass,
+				  UINT InfoType,
+				  UINT InfoId,
+				  PVOID Context,
+				  TDIEntityID *id,
+				  PCHAR Buffer,
+				  UINT BufferSize );
+
+/* Insert and remove interface entities */
+VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface );
+VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface );
+
 #endif /* __INFO_H */
 
 /* EOF */

reactos/drivers/net/tcpip/include
ip.h 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- ip.h	12 Mar 2004 04:21:59 -0000	1.10
+++ ip.h	9 Jun 2004 18:11:37 -0000	1.11
@@ -9,6 +9,7 @@
 
 typedef VOID (*OBJECT_FREE_ROUTINE)(PVOID Object);
 
+#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d))
 
 /* Raw IPv4 style address */
 typedef ULONG IPv4_RAW_ADDRESS;
@@ -93,7 +94,6 @@
 /* The ProtocolReserved field is structured as a PACKET_CONTEXT */
 #define PC(Packet) ((PPACKET_CONTEXT)(&Packet->ProtocolReserved))
 
-
 /* Address information a.k.a ADE */
 typedef struct _ADDRESS_ENTRY {
     DEFINE_TAG
@@ -105,10 +105,12 @@
     PIP_ADDRESS             Address;    /* Pointer to address identifying this entry */
 } ADDRESS_ENTRY, *PADDRESS_ENTRY;
 
-/* Values for address type */
-#define ADE_UNICAST   0x01
-#define ADE_MULTICAST 0x02
-#define ADE_ADDRMASK  0x03
+/* Values for address type -- also the interface flags */
+/* These values are mean to overlap meaningfully with the BSD ones */
+#define ADE_UNICAST     0x01
+#define ADE_MULTICAST   0x02
+#define ADE_ADDRMASK    0x04
+#define ADE_POINTOPOINT 0x10
 
 /* There is one NTE for each source (unicast) address assigned to an interface */
 typedef struct _NET_TABLE_ENTRY {
@@ -162,17 +164,6 @@
 } IP_INTERFACE, *PIP_INTERFACE;
 
 
-/* Prefix List Entry */
-typedef struct _PREFIX_LIST_ENTRY {
-    DEFINE_TAG
-    LIST_ENTRY ListEntry;    /* Entry on list */
-    ULONG RefCount;          /* Reference count */
-    PIP_INTERFACE Interface; /* Pointer to interface */
-    PIP_ADDRESS Prefix;      /* Pointer to prefix */
-    UINT PrefixLength;       /* Length of prefix */
-} PREFIX_LIST_ENTRY, *PPREFIX_LIST_ENTRY;
-
-
 #define IP_PROTOCOL_TABLE_SIZE 0x100
 
 typedef VOID (*IP_PROTOCOL_HANDLER)(
@@ -202,8 +193,6 @@
 extern KSPIN_LOCK InterfaceListLock;
 extern LIST_ENTRY NetTableListHead;
 extern KSPIN_LOCK NetTableListLock;
-extern LIST_ENTRY PrefixListHead;
-extern KSPIN_LOCK PrefixListLock;
 extern UINT MaxLLHeaderSize;
 extern UINT MinLLFrameSize;
 

reactos/drivers/net/tcpip/include
lan.h 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- lan.h	9 Feb 2004 06:59:01 -0000	1.6
+++ lan.h	9 Jun 2004 18:11:37 -0000	1.7
@@ -56,7 +56,6 @@
     UINT MacOptions;                        /* MAC options for NIC driver/adapter */
     UINT Speed;                             /* Link speed */
     UINT PacketFilter;                      /* Packet filter for this adapter */
-    PNDIS_PACKET TDPackets;                 /* Transfer Data packets */
 } LAN_ADAPTER, *PLAN_ADAPTER;
 
 /* LAN adapter state constants */

reactos/drivers/net/tcpip/include
router.h 1.3 -> 1.4
diff -u -r1.3 -r1.4
--- router.h	4 Jul 2001 20:40:23 -0000	1.3
+++ router.h	9 Jun 2004 18:11:37 -0000	1.4
@@ -17,7 +17,6 @@
     OBJECT_FREE_ROUTINE Free;     /* Routine used to free resources for the object */
     PIP_ADDRESS NetworkAddress;   /* Address of network */
     PIP_ADDRESS Netmask;          /* Netmask of network */
-    PNET_TABLE_ENTRY NTE;         /* Pointer to NTE to use */
     PNEIGHBOR_CACHE_ENTRY Router; /* Pointer to NCE of router to use */
     UINT Metric;                  /* Cost of this route */
 } FIB_ENTRY, *PFIB_ENTRY;
@@ -34,7 +33,6 @@
 PFIB_ENTRY RouterAddRoute(
     PIP_ADDRESS NetworkAddress,
     PIP_ADDRESS Netmask,
-    PNET_TABLE_ENTRY NTE,
     PNEIGHBOR_CACHE_ENTRY Router,
     UINT Metric);
 
@@ -58,6 +56,10 @@
 NTSTATUS RouterShutdown(
     VOID);
 
+UINT CountFIBs();
+
+UINT CopyFIBs( PFIB_ENTRY Target );
+
 #endif /* __ROUTER_H */
 
 /* EOF */

reactos/drivers/net/tcpip/include
routines.h 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- routines.h	25 Dec 2003 14:06:14 -0000	1.5
+++ routines.h	9 Jun 2004 18:11:37 -0000	1.6
@@ -8,25 +8,7 @@
 #define __ROUTINES_H
 
 
-inline NTSTATUS BuildDatagramSendRequest(
-    PDATAGRAM_SEND_REQUEST *SendRequest,
-    PIP_ADDRESS RemoteAddress,
-    USHORT RemotePort,
-    PNDIS_BUFFER Buffer,
-    DWORD BufferSize,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    DATAGRAM_BUILD_ROUTINE Build,
-    ULONG Flags);
-
-inline NTSTATUS BuildTCPSendRequest(
-    PTCP_SEND_REQUEST *SendRequest,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    PVOID ProtocolContext);
-
-UINT Random(
-    VOID);
+UINT Random(VOID);
 
 UINT CopyBufferToBufferChain(
     PNDIS_BUFFER DstBuffer,
@@ -53,8 +35,10 @@
     UINT SrcOffset,
     UINT Length);
 
-VOID FreeNdisPacket(
-    PNDIS_PACKET Packet);
+VOID FreeNdisPacketX(
+    PNDIS_PACKET Packet,
+    PCHAR File,
+    UINT Line);
 
 PVOID AdjustPacket(
     PNDIS_PACKET Packet,

reactos/drivers/net/tcpip/include
tcp.h 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- tcp.h	4 Mar 2004 20:45:38 -0000	1.5
+++ tcp.h	9 Jun 2004 18:11:37 -0000	1.6
@@ -35,6 +35,9 @@
 
 #define TCPOPTLEN_MAX_SEG_SIZE  0x4
 
+/* Data offset; 32-bit words (leftmost 4 bits); convert to bytes */
+#define TCP_DATA_OFFSET(DataOffset)(((DataOffset) & 0xF0) >> (4-2))
+
 
 /* TCPv4 pseudo header */
 typedef struct TCPv4_PSEUDO_HEADER {
@@ -70,10 +73,9 @@
 #define SRF_SYN   TCP_SYN
 #define SRF_FIN   TCP_FIN
 
-
 PTCP_SEGMENT TCPCreateSegment(
   PIP_PACKET IPPacket,
-  ULONG SequenceNumber,
+  PTCPv4_HEADER TCPHeader,
   ULONG SegmentLength);
 
 VOID TCPFreeSegment(
@@ -81,25 +83,8 @@
 
 VOID TCPAddSegment(
   PCONNECTION_ENDPOINT Connection,
-  PTCP_SEGMENT Segment);
-
-inline NTSTATUS TCPBuildSendRequest(
-    PTCP_SEND_REQUEST *SendRequest,
-    PDATAGRAM_SEND_REQUEST *DGSendRequest,
-    PCONNECTION_ENDPOINT Connection,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    PNDIS_BUFFER Buffer,
-    DWORD BufferSize,
-    ULONG Flags);
-
-inline NTSTATUS TCPBuildAndTransmitSendRequest(
-    PCONNECTION_ENDPOINT Connection,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    PNDIS_BUFFER Buffer,
-    DWORD BufferSize,
-    ULONG Flags);
+  PTCP_SEGMENT Segment,
+  PULONG Acknowledged);
 
 NTSTATUS TCPConnect(
   PTDI_REQUEST Request,
@@ -108,10 +93,16 @@
 
 NTSTATUS TCPListen(
   PTDI_REQUEST Request,
-  PTDI_CONNECTION_INFORMATION ConnInfo,
-  PTDI_CONNECTION_INFORMATION ReturnInfo);
+  UINT Backlog );
+
+NTSTATUS TCPReceiveData(
+  PTDI_REQUEST Request,
+  PNDIS_BUFFER Buffer,
+  ULONG ReceiveLength,
+  ULONG ReceiveFlags,
+  PULONG BytesReceived);
 
-NTSTATUS TCPSendDatagram(
+NTSTATUS TCPSendData(
   PTDI_REQUEST Request,
   PTDI_CONNECTION_INFORMATION ConnInfo,
   PNDIS_BUFFER Buffer,

reactos/drivers/net/tcpip/include
tcpip.h 1.8 -> 1.9
diff -u -r1.8 -r1.9
--- tcpip.h	12 Mar 2004 04:21:59 -0000	1.8
+++ tcpip.h	9 Jun 2004 18:11:37 -0000	1.9
@@ -63,6 +63,8 @@
 #define MAX(value1, value2) \
     ((value1 > value2)? value1 : value2)
 
+#define NDIS_BUFFER_TAG FOURCC('n','b','u','f')
+#define NDIS_PACKET_TAG FOURCC('n','p','k','t')
 
 #ifdef i386
 
@@ -110,6 +112,34 @@
 
 #endif /* i386 */
 
+typedef TDI_STATUS (*InfoRequest_f)( UINT InfoClass, 
+				     UINT InfoType,
+				     UINT InfoId,
+				     PVOID Context,
+				     TDIEntityID *id,
+				     PNDIS_BUFFER Buffer,
+				     PUINT BufferSize );
+
+typedef TDI_STATUS (*InfoSet_f)( UINT InfoClass, 
+				 UINT InfoType,
+				 UINT InfoId,
+				 PVOID Context,
+				 TDIEntityID *id,
+				 PCHAR Buffer,
+				 UINT BufferSize );
+
+/* Sufficient information to manage the entity list */
+typedef struct {
+    UINT tei_entity;
+    UINT tei_instance;
+    PVOID context;
+    InfoRequest_f info_req;
+    InfoSet_f info_set;
+} TDIEntityInfo;
+
+#ifndef htons
+#define htons(x) (((x) << 16) | (((x) >> 8) & 0xff))
+#endif
 
 /* Global variable */
 extern PDEVICE_OBJECT TCPDeviceObject;
@@ -123,7 +153,7 @@
 extern NDIS_HANDLE GlobalPacketPool;
 extern NDIS_HANDLE GlobalBufferPool;
 extern KSPIN_LOCK EntityListLock;
-extern TDIEntityID *EntityList;
+extern TDIEntityInfo *EntityList;
 extern ULONG EntityCount;
 extern ULONG EntityMax;
 extern UDP_STATISTICS UDPStats;

reactos/drivers/net/tcpip/include
titypes.h 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- titypes.h	4 Mar 2004 20:45:38 -0000	1.6
+++ titypes.h	9 Jun 2004 18:11:37 -0000	1.7
@@ -65,7 +65,7 @@
 #else /* DBG */
 
 #define DEFINE_TAG
-#define INIT_TAG (Object, Tag)
+#define INIT_TAG(Object, Tag)
 
 /*
  * VOID ReferenceObject(
@@ -127,17 +127,18 @@
     PIP_PACKET *IPPacket);
 
 typedef struct _DATAGRAM_SEND_REQUEST {
-    LIST_ENTRY ListEntry;                 /* Entry on list */
-    PIP_ADDRESS RemoteAddress;            /* Pointer to remote IP address */
-    USHORT RemotePort;                    /* Remote port number */
-    PNDIS_BUFFER Buffer;                  /* Pointer to NDIS buffer to send */
-    DWORD BufferSize;                     /* Size of Buffer */
+    LIST_ENTRY ListEntry;
+    PNDIS_PACKET PacketToSend;
     DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
     PVOID Context;                        /* Pointer to context information */
-    DATAGRAM_BUILD_ROUTINE Build;         /* Datagram build routine */
+    IP_PACKET Packet;
+    UINT BufferSize;
+    IP_ADDRESS RemoteAddress;
+    USHORT RemotePort;
     ULONG Flags;                          /* Protocol specific flags */
 } DATAGRAM_SEND_REQUEST, *PDATAGRAM_SEND_REQUEST;
 
+#if 0
 #define InitializeDatagramSendRequest( \
   _SendRequest, \
   _RemoteAddress, \
@@ -157,6 +158,7 @@
     (_SendRequest)->Build = (_Build); \
     (_SendRequest)->Flags = (_Flags); \
   }
+#endif /* These things bug me...  They hide the member names. */
 
 /* Transport address file context structure. The FileObject->FsContext2
    field holds a pointer to this structure */
@@ -254,32 +256,17 @@
     USHORT Protocol;        /* Protocol number */
 } AF_SEARCH, *PAF_SEARCH;
 
-
-
 /*******************************************************
 * Connection-oriented communication support structures *
 *******************************************************/
 
-typedef struct _TCP_SEND_REQUEST {
+typedef struct _TCP_RECEIVE_REQUEST {
   LIST_ENTRY ListEntry;                 /* Entry on list */
+  PNDIS_BUFFER Buffer;                  /* Pointer to receive buffer */
+  ULONG BufferSize;                     /* Size of Buffer */
   DATAGRAM_COMPLETION_ROUTINE Complete; /* Completion routine */
   PVOID Context;                        /* Pointer to context information */
-  PVOID ProtocolContext;                /* Protocol specific context */
-  ULONG Flags;                          /* Protocol specific flags */
-  ULONG SequenceNumber;                 /* Sequence number (network byte order) */
-  ULONG AckNumber;                      /* Acknowledgement number (network byte order) */
-} TCP_SEND_REQUEST, *PTCP_SEND_REQUEST;
-
-#define InitializeTCPSendRequest( \
-  _SendRequest, \
-  _Complete, \
-  _Context, \
-  _ProtocolContext) { \
-    (_SendRequest)->Complete = (_Complete); \
-    (_SendRequest)->Context = (_Context); \
-    (_SendRequest)->ProtocolContext = (_ProtocolContext); \
-  }
-
+} TCP_RECEIVE_REQUEST, *PTCP_RECEIVE_REQUEST;
 
 /* Connection states */
 typedef enum {
@@ -302,8 +289,10 @@
 typedef struct _TCP_SEGMENT {
   LIST_ENTRY ListEntry;
   PIP_PACKET IPPacket;        /* Pointer to IP packet */
+  PVOID SegmentData;          /* Pointer to segment data */
   ULONG SequenceNumber;       /* Sequence number of first byte in segment */
   ULONG Length;               /* Number of bytes in segment */
+  ULONG BytesDelivered;       /* Number of bytes already delivered to the client */
 } TCP_SEGMENT, *PTCP_SEGMENT;
 
 
@@ -316,15 +305,16 @@
   ULONG RefCount;             /* Number of references to this object */
   PVOID ClientContext;        /* Pointer to client context information */
   PADDRESS_FILE AddressFile;  /* Associated address file object (NULL if none) */
+  PVOID SocketContext;        /* Context for lower layer */
 
-  CONNECTION_STATE State;     /* Connection state */
-
+#if 0
   PIP_ADDRESS LocalAddress;   /* Pointer to local IP address */
   USHORT LocalPort;           /* Local port number (network byte order) */
 
   PIP_ADDRESS RemoteAddress;  /* Pointer to remote IP address */
   USHORT RemotePort;          /* Remote port number (network byte order) */
 
+  CONNECTION_STATE State;     /* Connection state */
   /* Send sequence variables */
   ULONG SendUnacknowledged;   /* Highest sequence number that is acknowledged */
   ULONG SendNext;             /* Sequence number of last data block sent */
@@ -335,20 +325,23 @@
   ULONG SendISS;              /* Initial send sequence number */
 
   /* Receive sequence variables */
-  ULONG ReceiveNext;          /* Sequence number of last data block received */
+  ULONG ReceiveNext;          /* Next sequence number expected and start of receive window */
   ULONG ReceiveWindow;        /* Maximum allowed number of octets in a segment */
   ULONG ReceiveUrgentPointer; /* Sequence number of start of urgent data */
   ULONG ReceiveIRS;           /* Initial receive sequence number */
+  ULONG ReceiveDelivered;     /* Next sequence number to be delivered to the client */
 
   /* Statistics for computing the retransmission timeout */
   ULONG TimestampSend;        /* Timestamp when sending a segment */
   ULONG TimestampAck;         /* Timestamp when receiving acknowledgment */
+#endif
 
   /* Requests */
   PTDI_REQUEST ListenRequest; /* Queued listen request */
+  LIST_ENTRY ReceiveRequests; /* Queued receive requests */
 
   /* Queues */
-  LIST_ENTRY ReceivedSegments;
+  LIST_ENTRY ReceivedSegments;/* Segments that are received */
 
 } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;
 

reactos/drivers/net/tcpip/network
prefix.c 1.1 -> 1.2
diff -N prefix.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ prefix.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,139 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS TCP/IP protocol driver
+ * FILE:        network/ip.c
+ * PURPOSE:     Internet Protocol module
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ *              Art Yerkes (arty@users.sourceforge.net)
+ * REVISIONS:
+ *   CSH 01/08-2000 Created
+ */
+#include <roscfg.h>
+#include <tcpip.h>
+#include <ip.h>
+#include <tcp.h>
+#include <loopback.h>
+#include <neighbor.h>
+#include <receive.h>
+#include <address.h>
+#include <route.h>
+#include <icmp.h>
+#include <prefix.h>
+#include <pool.h>
+
+LIST_ENTRY PrefixListHead;
+KSPIN_LOCK PrefixListLock;
+
+/* --------- The Prefix List ---------- */
+
+VOID InitPLE() {
+    /* Initialize the prefix list and protecting lock */
+    InitializeListHead(&PrefixListHead);
+    KeInitializeSpinLock(&PrefixListLock);
+}
+
+
+PPREFIX_LIST_ENTRY CreatePLE(PIP_INTERFACE IF, PIP_ADDRESS Prefix, UINT Length)
+/*
+ * FUNCTION: Creates a prefix list entry and binds it to an interface
+ * ARGUMENTS:
+ *     IF     = Pointer to interface
+ *     Prefix = Pointer to prefix
+ *     Length = Length of prefix
+ * RETURNS:
+ *     Pointer to PLE, NULL if there was not enough free resources
+ * NOTES:
+ *     The prefix list entry retains a reference to the interface and
+ *     the provided address.  The caller is responsible for providing
+ *     these references
+ */
+{
+    PPREFIX_LIST_ENTRY PLE;
+
+    TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X)  Prefix (0x%X)  Length (%d).\n", IF, Prefix, Length));
+
+    TI_DbgPrint(DEBUG_IP, ("Prefix (%s).\n", A2S(Prefix)));
+
+    /* Allocate space for an PLE and set it up */
+    PLE = ExAllocatePool(NonPagedPool, sizeof(PREFIX_LIST_ENTRY));
+    if (!PLE) {
+        TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+        return NULL;
+    }
+
+    INIT_TAG(PLE, TAG('P','L','E',' '));
+    PLE->RefCount     = 1;
+    PLE->Interface    = IF;
+    PLE->Prefix       = Prefix;
+    PLE->PrefixLength = Length;
+
+    /* Add PLE to the global prefix list */
+    ExInterlockedInsertTailList(&PrefixListHead, &PLE->ListEntry, &PrefixListLock);
+
+    return PLE;
+}
+
+
+VOID DestroyPLE(
+    PPREFIX_LIST_ENTRY PLE)
+/*
+ * FUNCTION: Destroys an prefix list entry
+ * ARGUMENTS:
+ *     PLE = Pointer to prefix list entry
+ * NOTES:
+ *     The prefix list lock must be held when called
+ */
+{
+    TI_DbgPrint(DEBUG_IP, ("Called. PLE (0x%X).\n", PLE));
+
+    TI_DbgPrint(DEBUG_IP, ("PLE (%s).\n", PLE->Prefix));
+
+    /* Unlink the prefix list entry from the list */
+    RemoveEntryList(&PLE->ListEntry);
+
+    /* Dereference the address */
+    DereferenceObject(PLE->Prefix);
+
+    /* Dereference the interface */
+    DereferenceObject(PLE->Interface);
+
+#ifdef DBG
+    PLE->RefCount--;
+
+    if (PLE->RefCount != 0) {
+        TI_DbgPrint(MIN_TRACE, ("Prefix list entry at (0x%X) has (%d) references (should be 0).\n", PLE, PLE->RefCount));
+    }
+#endif
+
+    /* And free the PLE */
+    ExFreePool(PLE);
+}
+
+
+VOID DestroyPLEs(
+    VOID)
+/*
+ * FUNCTION: Destroys all prefix list entries
+ */
+{
+    KIRQL OldIrql;
+    PLIST_ENTRY CurrentEntry;
+    PLIST_ENTRY NextEntry;
+    PPREFIX_LIST_ENTRY Current;
+
+    TI_DbgPrint(DEBUG_IP, ("Called.\n"));
+
+    KeAcquireSpinLock(&PrefixListLock, &OldIrql);
+
+    /* Search the list and remove every PLE we find */
+    CurrentEntry = PrefixListHead.Flink;
+    while (CurrentEntry != &PrefixListHead) {
+        NextEntry = CurrentEntry->Flink;
+	Current = CONTAINING_RECORD(CurrentEntry, PREFIX_LIST_ENTRY, ListEntry);
+        /* Destroy the PLE */
+        DestroyPLE(Current);
+        CurrentEntry = NextEntry;
+    }
+    KeReleaseSpinLock(&PrefixListLock, OldIrql);
+}
+

reactos/drivers/net/tcpip/network
icmp.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- icmp.c	4 Mar 2004 20:45:39 -0000	1.7
+++ icmp.c	9 Jun 2004 18:11:38 -0000	1.8
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <icmp.h>
 #include <rawip.h>
@@ -38,8 +39,6 @@
     FreeNdisPacket(Packet);
 
     TI_DbgPrint(DEBUG_ICMP, ("Freeing IP packet at %X.\n", IPPacket));
-
-    (*IPPacket->Free)(IPPacket);
 }
 
 
@@ -79,9 +78,8 @@
 
     Size = MaxLLHeaderSize + sizeof(IPv4_HEADER) +
         sizeof(ICMP_HEADER) + DataSize;
-    DataBuffer = ExAllocatePool(NonPagedPool, Size);
+    DataBuffer = exAllocatePool(NonPagedPool, Size);
     if (!DataBuffer) {
-        (*IPPacket->Free)(IPPacket);
         return NULL;
     }
 
@@ -90,10 +88,10 @@
     /* Allocate NDIS packet */
     NdisAllocatePacket(&NdisStatus, &NdisPacket, GlobalPacketPool);
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        (*IPPacket->Free)(IPPacket);
-        ExFreePool(DataBuffer);
+        exFreePool(DataBuffer);
         return NULL;
     }
+    Track(NDIS_PACKET_TAG,NdisPacket);
 
     TI_DbgPrint(MAX_TRACE, ("NdisPacket at (0x%X).\n", NdisPacket));
 
@@ -101,12 +99,12 @@
     NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
         DataBuffer, Size);
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        (*IPPacket->Free)(IPPacket);
-        NdisFreePacket(NdisPacket);
-        ExFreePool(DataBuffer);
+        FreeNdisPacket(NdisPacket);
+        exFreePool(DataBuffer);
         return NULL;
     }
-
+    Track(NDIS_BUFFER_TAG,NdisBuffer);
+    
     TI_DbgPrint(MAX_TRACE, ("NdisBuffer at (0x%X).\n", NdisBuffer));
 
     /* Link NDIS buffer into packet */
@@ -202,9 +200,10 @@
         ((PICMP_HEADER)NewPacket->Data)->Code     = 0;
         ((PICMP_HEADER)NewPacket->Data)->Checksum = 0;
 
+#ifdef DBG
         DisplayIPPacket(IPPacket);
-
         DisplayIPPacket(NewPacket);
+#endif
 
         ICMPTransmit(NTE, NewPacket);
 
@@ -245,11 +244,11 @@
         IPv4Checksum(IPPacket->Data, IPPacket->TotalSize - IPPacket->HeaderSize, 0);
 
     /* Get a route to the destination address */
+    PNEIGHBOR_CACHE_ENTRY *NCE = RouterGetRoute( &IPPacket->DstAddr, NULL );
     if (RouteGetRouteToDestination(&IPPacket->DstAddr, NTE, &RCN) == IP_SUCCESS) {
         /* Send the packet */
         if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS) {
             FreeNdisPacket(IPPacket->NdisPacket);
-            (*IPPacket->Free)(IPPacket);
         }
         /* We're done with the RCN */
         DereferenceObject(RCN);
@@ -261,7 +260,6 @@
             IPPacket->DstAddr.Address.IPv4Address));
         /* Discard packet */
         FreeNdisPacket(IPPacket->NdisPacket);
-        (*IPPacket->Free)(IPPacket);
     }
 }
 

reactos/drivers/net/tcpip/network
ip.c 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- ip.c	9 Feb 2004 06:59:01 -0000	1.9
+++ ip.c	9 Jun 2004 18:11:38 -0000	1.10
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <ip.h>
 #include <tcp.h>
@@ -14,6 +15,7 @@
 #include <neighbor.h>
 #include <receive.h>
 #include <address.h>
+#include <prefix.h>
 #include <route.h>
 #include <icmp.h>
 #include <pool.h>
@@ -25,8 +27,6 @@
 KSPIN_LOCK InterfaceListLock;
 LIST_ENTRY NetTableListHead;
 KSPIN_LOCK NetTableListLock;
-LIST_ENTRY PrefixListHead;
-KSPIN_LOCK PrefixListLock;
 UINT MaxLLHeaderSize; /* Largest maximum header size */
 UINT MinLLFrameSize;  /* Largest minimum frame size */
 BOOLEAN IPInitialized = FALSE;
@@ -47,6 +47,17 @@
 }
 
 
+VOID DontFreePacket(
+    PVOID Object)
+/*
+ * FUNCTION: Do nothing for when the IPPacket struct is part of another
+ * ARGUMENTS:
+ *     Object = Pointer to an IP packet structure
+ */
+{
+}
+
+
 VOID FreeADE(
     PVOID Object)
 /*
@@ -55,7 +66,7 @@
  *     Object = Pointer to an address entry structure
  */
 {
-    ExFreePool(Object);
+    exFreePool(Object);
 }
 
 
@@ -67,7 +78,7 @@
  *     Object = Pointer to an net table entry structure
  */
 {
-    ExFreePool(Object);
+    exFreePool(Object);
 }
 
 
@@ -79,7 +90,7 @@
  *     Object = Pointer to an interface structure
  */
 {
-    ExFreePool(Object);
+    exFreePool(Object);
 }
 
 
@@ -114,7 +125,7 @@
         A2S(Address), A2S(NTE->Address)));
 
     /* Allocate space for an ADE and set it up */
-    ADE = ExAllocatePool(NonPagedPool, sizeof(ADDRESS_ENTRY));
+    ADE = exAllocatePool(NonPagedPool, sizeof(ADDRESS_ENTRY));
     if (!ADE) {
         TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
         return NULL;
@@ -221,119 +232,35 @@
 
   INIT_TAG(IPPacket, TAG('I','P','K','T'));
 
-  IPPacket->Free     = FreePacket;
-  IPPacket->RefCount = 1;
-  IPPacket->Type     = Type;
+  IPPacket->Free       = FreePacket;
+  IPPacket->RefCount   = 1;
+  IPPacket->Type       = Type;
+  IPPacket->HeaderSize = 20;
 
   return IPPacket;
 }
 
-
-PPREFIX_LIST_ENTRY CreatePLE(
-    PIP_INTERFACE IF,
-    PIP_ADDRESS Prefix,
-    UINT Length)
+PIP_PACKET IPInitializePacket(
+    PIP_PACKET IPPacket,
+    ULONG Type)
 /*
- * FUNCTION: Creates a prefix list entry and binds it to an interface
+ * FUNCTION: Creates an IP packet object
  * ARGUMENTS:
- *     IF     = Pointer to interface
- *     Prefix = Pointer to prefix
- *     Length = Length of prefix
+ *     Type = Type of IP packet
  * RETURNS:
- *     Pointer to PLE, NULL if there was not enough free resources
- * NOTES:
- *     The prefix list entry retains a reference to the interface and
- *     the provided address.  The caller is responsible for providing
- *     these references
- */
-{
-    PPREFIX_LIST_ENTRY PLE;
-
-    TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X)  Prefix (0x%X)  Length (%d).\n", IF, Prefix, Length));
-
-    TI_DbgPrint(DEBUG_IP, ("Prefix (%s).\n", A2S(Prefix)));
-
-    /* Allocate space for an PLE and set it up */
-    PLE = ExAllocatePool(NonPagedPool, sizeof(PREFIX_LIST_ENTRY));
-    if (!PLE) {
-        TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-        return NULL;
-    }
-
-    INIT_TAG(PLE, TAG('P','L','E',' '));
-    PLE->RefCount     = 1;
-    PLE->Interface    = IF;
-    PLE->Prefix       = Prefix;
-    PLE->PrefixLength = Length;
-
-    /* Add PLE to the global prefix list */
-    ExInterlockedInsertTailList(&PrefixListHead, &PLE->ListEntry, &PrefixListLock);
-
-    return PLE;
-}
-
-
-VOID DestroyPLE(
-    PPREFIX_LIST_ENTRY PLE)
-/*
- * FUNCTION: Destroys an prefix list entry
- * ARGUMENTS:
- *     PLE = Pointer to prefix list entry
- * NOTES:
- *     The prefix list lock must be held when called
- */
-{
-    TI_DbgPrint(DEBUG_IP, ("Called. PLE (0x%X).\n", PLE));
-
-    TI_DbgPrint(DEBUG_IP, ("PLE (%s).\n", PLE->Prefix));
-
-    /* Unlink the prefix list entry from the list */
-    RemoveEntryList(&PLE->ListEntry);
-
-    /* Dereference the address */
-    DereferenceObject(PLE->Prefix);
-
-    /* Dereference the interface */
-    DereferenceObject(PLE->Interface);
-
-#ifdef DBG
-    PLE->RefCount--;
-
-    if (PLE->RefCount != 0) {
-        TI_DbgPrint(MIN_TRACE, ("Prefix list entry at (0x%X) has (%d) references (should be 0).\n", PLE, PLE->RefCount));
-    }
-#endif
-
-    /* And free the PLE */
-    ExFreePool(PLE);
-}
-
-
-VOID DestroyPLEs(
-    VOID)
-/*
- * FUNCTION: Destroys all prefix list entries
+ *     Pointer to the created IP packet. NULL if there was not enough free resources.
  */
 {
-    KIRQL OldIrql;
-    PLIST_ENTRY CurrentEntry;
-    PLIST_ENTRY NextEntry;
-    PPREFIX_LIST_ENTRY Current;
-
-    TI_DbgPrint(DEBUG_IP, ("Called.\n"));
-
-    KeAcquireSpinLock(&PrefixListLock, &OldIrql);
-
-    /* Search the list and remove every PLE we find */
-    CurrentEntry = PrefixListHead.Flink;
-    while (CurrentEntry != &PrefixListHead) {
-        NextEntry = CurrentEntry->Flink;
-	      Current = CONTAINING_RECORD(CurrentEntry, PREFIX_LIST_ENTRY, ListEntry);
-        /* Destroy the PLE */
-        DestroyPLE(Current);
-        CurrentEntry = NextEntry;
-    }
-    KeReleaseSpinLock(&PrefixListLock, OldIrql);
+    /* FIXME: Is this needed? */
+    RtlZeroMemory(IPPacket, sizeof(IP_PACKET));
+    
+    INIT_TAG(IPPacket, TAG('I','P','K','T'));
+    
+    IPPacket->Free     = DontFreePacket;
+    IPPacket->RefCount = 1;
+    IPPacket->Type     = Type;
+    
+    return IPPacket;
 }
 
 
@@ -364,7 +291,7 @@
     TI_DbgPrint(DEBUG_IP, ("Address (%s).\n", A2S(Address)));
 
     /* Allocate room for an NTE */
-    NTE = ExAllocatePool(NonPagedPool, sizeof(NET_TABLE_ENTRY));
+    NTE = exAllocatePool(NonPagedPool, sizeof(NET_TABLE_ENTRY));
     if (!NTE) {
         TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
         return NULL;
@@ -392,7 +319,7 @@
     ADE = CreateADE(IF, NTE->Address, ADE_UNICAST, NTE);
     if (!ADE) {
         TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-        ExFreePool(NTE);
+        exFreePool(NTE);
         return NULL;
     }
 
@@ -400,7 +327,7 @@
     NTE->PLE = CreatePLE(IF, NTE->Address, PrefixLength);
     if (!NTE->PLE) {
         DestroyADE(IF, ADE);
-        ExFreePool(NTE);
+        exFreePool(NTE);
         return NULL;
     }
 
@@ -462,7 +389,7 @@
     }
 #endif
     /* And free the NTE */
-    ExFreePool(NTE);
+    exFreePool(NTE);
 }
 
 
@@ -792,7 +719,7 @@
     }
 #endif
 
-    IF = ExAllocatePool(NonPagedPool, sizeof(IP_INTERFACE));
+    IF = exAllocatePool(NonPagedPool, sizeof(IP_INTERFACE));
     if (!IF) {
         TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
         return NULL;
@@ -821,6 +748,8 @@
 
     KeInitializeSpinLock(&IF->Lock);
 
+    InsertTDIInterfaceEntity( IF );
+
     return IF;
 }
 
@@ -838,6 +767,8 @@
 
     TI_DbgPrint(DEBUG_IP, ("Called. IF (0x%X).\n", IF));
 
+    RemoveTDIInterfaceEntity( IF );
+
     KeAcquireSpinLock(&NetTableListLock, &OldIrql1);
     KeAcquireSpinLock(&IF->Lock, &OldIrql2);
     DestroyADEs(IF);
@@ -852,7 +783,8 @@
         TI_DbgPrint(MIN_TRACE, ("Interface at (0x%X) has (%d) references (should be 0).\n", IF, IF->RefCount));
     }
 #endif
-    ExFreePool(IF);
+
+    exFreePool(IF);
 }
 
 
@@ -891,30 +823,29 @@
             KeReleaseSpinLock(&IF->Lock, OldIrql);
             return FALSE;
         }
-#if 1
+
         /* Reference objects for forward information base */
         ReferenceObject(Current->Address);
         ReferenceObject(Current->PLE->Prefix);
-        ReferenceObject(Current);
+	ReferenceObject(NCE);
+
         /* NCE is already referenced */
-        if (!RouterAddRoute(Current->Address, Current->PLE->Prefix, Current, NCE, 1)) {
+        if (!RouterAddRoute(Current->Address, Current->PLE->Prefix, NCE, 1)) {
             TI_DbgPrint(MIN_TRACE, ("Could not add route due to insufficient resources.\n"));
             DereferenceObject(Current->Address);
             DereferenceObject(Current->PLE->Prefix);
-            DereferenceObject(Current);
             DereferenceObject(NCE);
         }
-#else
+
         RCN = RouteAddRouteToDestination(Current->Address, Current, IF, NCE);
         if (!RCN) {
             TI_DbgPrint(MIN_TRACE, ("Could not create RCN.\n"));
             DereferenceObject(Current->Address);
             KeReleaseSpinLock(&IF->Lock, OldIrql);
-            return FALSE;
         }
         /* Don't need this any more since the route cache references the NCE */
         DereferenceObject(NCE);
-#endif
+
         CurrentEntry = CurrentEntry->Flink;
     }
 
@@ -1096,9 +1027,7 @@
     InitializeListHead(&ReassemblyListHead);
     KeInitializeSpinLock(&ReassemblyListLock);
 
-    /* Initialize the prefix list and protecting lock */
-    InitializeListHead(&PrefixListHead);
-    KeInitializeSpinLock(&PrefixListLock);
+    InitPLE();
 
     /* Initialize our periodic timer and its associated DPC object. When the
        timer expires, the IPTimeout deferred procedure call (DPC) is queued */

reactos/drivers/net/tcpip/network
neighbor.c 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- neighbor.c	25 Feb 2004 20:27:56 -0000	1.4
+++ neighbor.c	9 Jun 2004 18:11:38 -0000	1.5
@@ -7,10 +7,10 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <neighbor.h>
 #include <routines.h>
-#include <neighbor.h>
 #include <transmit.h>
 #include <address.h>
 #include <route.h>
@@ -186,7 +186,7 @@
               NdisPacket = NextNdisPacket;
             }
 
-#if DBG
+#ifdef DBG
           if (CurNCE->RefCount != 1)
             {
               TI_DbgPrint(DEBUG_REFCOUNT, ("NCE at (0x%X) has (%d) references (should be 1).\n", CurNCE, CurNCE->RefCount));
@@ -293,7 +293,7 @@
   NCE->Interface = Interface;
   NCE->Address = Address;
   NCE->LinkAddressLength = LinkAddressLength;
-  NCE->LinkAddress = (PVOID)((ULONG_PTR)NCE + sizeof(NEIGHBOR_CACHE_ENTRY));
+  NCE->LinkAddress = (PVOID)&NCE[1];
   if (LinkAddress != NULL)
     {
       RtlCopyMemory(NCE->LinkAddress, LinkAddress, LinkAddressLength);
@@ -524,7 +524,7 @@
           /* Remove reference to the address */
           DereferenceObject(CurNCE->Address);
 
-#if DBG
+#ifdef DBG
           CurNCE->RefCount--;
 
           if (CurNCE->RefCount != 0)

reactos/drivers/net/tcpip/network
receive.c 1.8 -> 1.9
diff -u -r1.8 -r1.9
--- receive.c	4 Mar 2004 20:45:39 -0000	1.8
+++ receive.c	9 Jun 2004 18:11:38 -0000	1.9
@@ -9,6 +9,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <receive.h>
 #include <routines.h>
@@ -100,7 +101,7 @@
     TI_DbgPrint(DEBUG_IP, ("Freeing fragment data at (0x%X).\n", CurrentF->Data));
 
     /* Free the fragment data buffer */
-    ExFreePool(CurrentF->Data);
+    exFreePool(CurrentF->Data);
 
     TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF));
 
@@ -112,7 +113,7 @@
   /* Free resources for the header, if it exists */
   if (IPDR->IPv4Header) {
     TI_DbgPrint(DEBUG_IP, ("Freeing IPv4 header data at (0x%X).\n", IPDR->IPv4Header));
-    ExFreePool(IPDR->IPv4Header);
+    exFreePool(IPDR->IPv4Header);
   }
 
   TI_DbgPrint(DEBUG_IP, ("Freeing IPDR data at (0x%X).\n", IPDR));
@@ -201,6 +202,11 @@
   PVOID Data;
 
   TI_DbgPrint(DEBUG_IP, ("Reassembling datagram from IPDR at (0x%X).\n", IPDR));
+  TI_DbgPrint(DEBUG_IP, ("IPDR->HeaderSize = %d\n", IPDR->HeaderSize));
+  TI_DbgPrint(DEBUG_IP, ("IPDR->DataSize = %d\n", IPDR->DataSize));
+
+  TI_DbgPrint(DEBUG_IP, ("Fragment header:\n"));
+  OskitDumpBuffer(IPDR->IPv4Header, IPDR->HeaderSize);
 
   /* FIXME: Assume IPv4 */
   IPPacket = IPCreatePacket(IP_ADDRESS_V4);
@@ -216,7 +222,7 @@
   RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS));
 
   /* Allocate space for full IP datagram */
-  IPPacket->Header = ExAllocatePool(NonPagedPool, IPPacket->TotalSize);
+  IPPacket->Header = exAllocatePool(NonPagedPool, IPPacket->TotalSize);
   if (!IPPacket->Header) {
     TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
     (*IPPacket->Free)(IPPacket);
@@ -226,7 +232,7 @@
   /* Copy the header into the buffer */
   RtlCopyMemory(IPPacket->Header, IPDR->IPv4Header, IPDR->HeaderSize);  
   
-  Data = (PVOID)((ULONG_PTR)IPPacket->Header + IPDR->HeaderSize);
+  Data = IPPacket->Header + IPDR->HeaderSize;
   IPPacket->Data = Data;
 
   /* Copy data from all fragments into buffer */
@@ -237,11 +243,10 @@
     TI_DbgPrint(DEBUG_IP, ("Copying (%d) bytes of fragment data from (0x%X) to offset (%d).\n",
       Current->Size, Data, Current->Offset));
     /* Copy fragment data to the destination buffer at the correct offset */
-    RtlCopyMemory(
-		  (PVOID)((ULONG_PTR)Data + Current->Offset),
-      Current->Data,
-      Current->Size);
-
+    RtlCopyMemory((PVOID)((ULONG_PTR)Data + Current->Offset),
+		  Current->Data,
+		  Current->Size);
+    OskitDumpBuffer( Data, Current->Offset + Current->Size );
     CurrentEntry = CurrentEntry->Flink;
   }
 
@@ -269,7 +274,7 @@
   RemoveIPDR(IPDR);
   FreeIPDR(IPDR);
   if (Buffer)
-    ExFreePool(Buffer);
+    exFreePool(Buffer);
 }
 
 
@@ -399,7 +404,7 @@
 
     /* If this is the first fragment, save the IP header */
     if (FragFirst == 0) {
-      IPDR->IPv4Header = ExAllocatePool(NonPagedPool, IPPacket->HeaderSize);
+	IPDR->IPv4Header = exAllocatePool(NonPagedPool, IPPacket->HeaderSize);
       if (!IPDR->IPv4Header) {
         /* We don't have the resources to process this packet, discard it */
         Cleanup(&IPDR->Lock, OldIrql, IPDR, NULL);
@@ -426,7 +431,7 @@
     TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment));
 
     Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize;
-    Fragment->Data = ExAllocatePool(NonPagedPool, Fragment->Size);
+    Fragment->Data = exAllocatePool(NonPagedPool, Fragment->Size);
     if (!Fragment->Data) {
       /* We don't have the resources to process this packet, discard it */
       Cleanup(&IPDR->Lock, OldIrql, IPDR, Fragment);
@@ -437,13 +442,12 @@
       Fragment->Data, Fragment->Size));
 
     /* Copy datagram data into fragment buffer */
-    CopyPacketToBuffer(
-		  Fragment->Data,
-      IPPacket->NdisPacket,
-      IPPacket->Position,
-      Fragment->Size);
-      Fragment->Offset = FragFirst;
-
+    CopyPacketToBuffer(Fragment->Data,
+		       IPPacket->NdisPacket,
+		       IPPacket->Position + MaxLLHeaderSize,
+		       Fragment->Size);
+    Fragment->Offset = FragFirst;
+    
     /* If this is the last fragment, compute and save the datagram data size */
     if (!MoreFragments)
       IPDR->DataSize = FragFirst + Fragment->Size;
@@ -463,7 +467,7 @@
 
     Datagram = ReassembleDatagram(IPDR);
 
-	  KeReleaseSpinLock(&IPDR->Lock, OldIrql);
+    KeReleaseSpinLock(&IPDR->Lock, OldIrql);
 
     RemoveIPDR(IPDR);
     FreeIPDR(IPDR);
@@ -478,7 +482,7 @@
     IPDispatchProtocol(NTE, Datagram);
 
     /* We're done with this datagram */
-    ExFreePool(Datagram->Header);
+    exFreePool(Datagram->Header);
     TI_DbgPrint(MAX_TRACE, ("Freeing datagram at (0x%X).\n", Datagram));
     (*Datagram->Free)(Datagram);
   } else
@@ -525,7 +529,6 @@
 {
 }
 
-
 VOID IPv4Receive(
   PVOID Context,
   PIP_PACKET IPPacket)
@@ -536,81 +539,77 @@
  *     IPPacket = Pointer to IP packet
  */
 {
-  PNEIGHBOR_CACHE_ENTRY NCE;
-  PNET_TABLE_ENTRY NTE;
-  UINT AddressType;
-
-  TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
-
-  IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2;
-
-  if (IPPacket->HeaderSize > IPv4_MAX_HEADER_SIZE) {
-    TI_DbgPrint(MIN_TRACE, ("Datagram received with incorrect header size (%d).\n",
-      IPPacket->HeaderSize));
-    /* Discard packet */
-    return;
-  }
-
-  /* Checksum IPv4 header */
-  if (!IPv4CorrectChecksum(IPPacket->Header, IPPacket->HeaderSize)) {
-    TI_DbgPrint(MIN_TRACE, ("Datagram received with bad checksum. Checksum field (0x%X)\n",
-      WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum)));
-    /* Discard packet */
-    return;
-  }
-
-//    TI_DbgPrint(DEBUG_IP, ("TotalSize (datalink) is (%d).\n", IPPacket->TotalSize));
-
-  IPPacket->TotalSize = WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength);
-
-//    TI_DbgPrint(DEBUG_IP, ("TotalSize (IPv4) is (%d).\n", IPPacket->TotalSize));
-
-	AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr);
-	AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr);
-
-  IPPacket->Position = IPPacket->HeaderSize;
-  IPPacket->Data     = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize);
-
-  /* FIXME: Possibly forward packets with multicast addresses */
-
-  /* FIXME: Should we allow packets to be received on the wrong interface? */
-#if 0
-  NTE = IPLocateNTE(&IPPacket->DstAddr, &AddressType);
-#else
-  NTE = IPLocateNTEOnInterface((PIP_INTERFACE)Context, &IPPacket->DstAddr, &AddressType);
-#endif
-  if (NTE) {
-    /* This packet is destined for us */
-    ProcessFragment((PIP_INTERFACE)Context, IPPacket, NTE);
-
-    /* Done with this NTE */
-    DereferenceObject(NTE);
-  } else {
-    /* This packet is not destined for us. If we are a router,
-       try to find a route and forward the packet */
-
-    /* FIXME: Check if acting as a router */
-#if 1
-    //NCE = RouteFindRouter(&IPPacket->DstAddr, NULL);
-    NCE = NULL;
-    if (NCE) {
-      /* FIXME: Possibly fragment datagram */
-      /* Forward the packet */
-      IPSendFragment(IPPacket, NCE);
+    PNEIGHBOR_CACHE_ENTRY NCE;
+    PNET_TABLE_ENTRY NTE;
+    UINT AddressType;
+    
+    TI_DbgPrint(DEBUG_IP, ("Received IPv4 datagram.\n"));
+    
+    IPPacket->HeaderSize = (((PIPv4_HEADER)IPPacket->Header)->VerIHL & 0x0F) << 2;
+    TI_DbgPrint(DEBUG_IP, ("IPPacket->HeaderSize = %d\n", IPPacket->HeaderSize));
+
+    if (IPPacket->HeaderSize > IPv4_MAX_HEADER_SIZE) {
+	TI_DbgPrint
+	    (MIN_TRACE, 
+	     ("Datagram received with incorrect header size (%d).\n",
+	      IPPacket->HeaderSize));
+	/* Discard packet */
+	return;
+    }
+    
+    /* Checksum IPv4 header */
+    if (!IPv4CorrectChecksum(IPPacket->Header, IPPacket->HeaderSize)) {
+	TI_DbgPrint
+	    (MIN_TRACE, 
+	     ("Datagram received with bad checksum. Checksum field (0x%X)\n",
+	      WN2H(((PIPv4_HEADER)IPPacket->Header)->Checksum)));
+	/* Discard packet */
+	return;
+    }
+    
+    IPPacket->TotalSize = WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength);
+    
+    AddrInitIPv4(&IPPacket->SrcAddr, ((PIPv4_HEADER)IPPacket->Header)->SrcAddr);
+    AddrInitIPv4(&IPPacket->DstAddr, ((PIPv4_HEADER)IPPacket->Header)->DstAddr);
+    
+    IPPacket->Position = IPPacket->HeaderSize;
+    IPPacket->Data     = (PVOID)((ULONG_PTR)IPPacket->Header + IPPacket->HeaderSize) + 14; /* XXX 14 */
+    
+    OskitDumpBuffer(IPPacket->Data - IPPacket->HeaderSize, IPPacket->TotalSize);
+
+    /* FIXME: Possibly forward packets with multicast addresses */
+    
+    /* FIXME: Should we allow packets to be received on the wrong interface? */
+    NTE = IPLocateNTEOnInterface((PIP_INTERFACE)Context, &IPPacket->DstAddr, &AddressType);
+    
+    if (NTE) {
+	/* This packet is destined for us */
+	ProcessFragment((PIP_INTERFACE)Context, IPPacket, NTE);
+	
+	/* Done with this NTE */
+	DereferenceObject(NTE);
     } else {
-      TI_DbgPrint(MIN_TRACE, ("No route to destination (0x%X).\n",
-        IPPacket->DstAddr.Address.IPv4Address));
-
-      /* FIXME: Send ICMP error code */
+	/* This packet is not destined for us. If we are a router,
+	   try to find a route and forward the packet */
+	
+	/* FIXME: Check if acting as a router */
+	NCE = NULL;
+	if (NCE) {
+	    /* FIXME: Possibly fragment datagram */
+	    /* Forward the packet */
+	    IPSendFragment(IPPacket, NCE);
+	} else {
+	    TI_DbgPrint(MIN_TRACE, ("No route to destination (0x%X).\n",
+				    IPPacket->DstAddr.Address.IPv4Address));
+	    
+	    /* FIXME: Send ICMP error code */
+	}
     }
-#endif
-  }
 }
 
 
-VOID IPReceive(
-  PVOID Context,
-  PIP_PACKET IPPacket)
+VOID IPReceive( PVOID Context,
+	        PIP_PACKET IPPacket )
 /*
  * FUNCTION: Receives an IP datagram (or fragment)
  * ARGUMENTS:

reactos/drivers/net/tcpip/network
route.c 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- route.c	8 Mar 2004 10:20:18 -0000	1.5
+++ route.c	9 Jun 2004 18:11:38 -0000	1.6
@@ -6,9 +6,15 @@
  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
  * NOTES:       The route cache is implemented as a binary search
  *              tree to obtain fast searches
+ *
+ *   This data is not authoritative.  It is a searchable cache that allows
+ *   quick access to route information to selected hosts.  This information
+ *   should always defer to the FIB.
+ *
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <route.h>
 #include <router.h>
@@ -23,7 +29,7 @@
 NPAGED_LOOKASIDE_LIST IPRCNList;
 
 
-#if DBG
+#ifdef DBG
 VOID PrintTree(
     PROUTE_CACHE_NODE Node)
 /*
@@ -50,6 +56,17 @@
 }
 #endif
 
+UINT CountRouteNodes( PROUTE_CACHE_NODE Node ) {
+    if( !Node ) Node = RouteCache;
+    if( IsInternalRCN(Node) )
+        return 
+	    /* Traverse left subtree */
+	    CountRouteNodes(Node->Left) + 
+	    /* Traverse right subtree */
+	    CountRouteNodes(Node->Right) + 1;
+    else
+	return 0;
+}
 
 VOID FreeRCN(
     PVOID Object)
@@ -168,6 +185,8 @@
 {
     PROUTE_CACHE_NODE RCN;
 
+    MTMARK();
+
     TI_DbgPrint(DEBUG_RCACHE, ("Called.\n"));
 
     RCN = ExAllocateFromNPagedLookasideList(&IPRCNList);
@@ -176,6 +195,8 @@
         return NULL;
     }
 
+    MTMARK();
+
     RCN->Free = FreeRCN;
 
     if (ExternalRCN->Left)
@@ -186,6 +207,8 @@
     RCN->Left   = ExternalRCN;
     RCN->Right  = ExternalRCN;
 
+    MTMARK();
+
     return RCN;
 }
 
@@ -364,7 +387,7 @@
         DereferenceObject(Node->NTE);
         DereferenceObject(Node->NCE);
 
-#if DBG
+#ifdef DBG
         if (Node->RefCount != 1)
             TI_DbgPrint(MIN_TRACE, ("RCN at (0x%X) has (%d) references (should be 1).\n", Node, Node->RefCount));
 #endif

reactos/drivers/net/tcpip/network
router.c 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- router.c	24 Sep 2002 15:11:34 -0000	1.5
+++ router.c	9 Jun 2004 18:11:38 -0000	1.6
@@ -4,12 +4,18 @@
  * FILE:        network/router.c
  * PURPOSE:     IP routing subsystem
  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * NOTES:
+ *   This file holds authoritative routing information.
+ *   Information queries on the route table should be handled here.
+ *   This information should always override the route cache info.
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <address.h>
 #include <router.h>
+#include <prefix.h>
 #include <pool.h>
 
 
@@ -48,7 +54,6 @@
     DereferenceObject(FIBE->NetworkAddress);
     DereferenceObject(FIBE->Netmask);
     DereferenceObject(FIBE->Router);
-    DereferenceObject(FIBE->NTE);
 
 #ifdef DBG
     FIBE->RefCount--;
@@ -79,7 +84,7 @@
     CurrentEntry = FIBListHead.Flink;
     while (CurrentEntry != &FIBListHead) {
         NextEntry = CurrentEntry->Flink;
-	    Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry);
+	Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry);
         /* Destroy the FIB entry */
         DestroyFIBE(Current);
         CurrentEntry = NextEntry;
@@ -87,6 +92,43 @@
 }
 
 
+UINT CountFIBs() {
+    UINT FibCount = 0;
+    PLIST_ENTRY CurrentEntry;
+    PLIST_ENTRY NextEntry;
+
+    /* Search the list and remove every FIB entry we find */
+    CurrentEntry = FIBListHead.Flink;
+    while (CurrentEntry != &FIBListHead) {
+        NextEntry = CurrentEntry->Flink;
+        CurrentEntry = NextEntry;
+	FibCount++;
+    }
+
+    return FibCount;
+}
+
+
+UINT CopyFIBs( PFIB_ENTRY Target ) {
+    UINT FibCount = 0;
+    PLIST_ENTRY CurrentEntry;
+    PLIST_ENTRY NextEntry;
+    PFIB_ENTRY Current;
+
+    /* Search the list and remove every FIB entry we find */
+    CurrentEntry = FIBListHead.Flink;
+    while (CurrentEntry != &FIBListHead) {
+        NextEntry = CurrentEntry->Flink;
+	Current = CONTAINING_RECORD(CurrentEntry, FIB_ENTRY, ListEntry);
+	Target[FibCount] = *Current;
+        CurrentEntry = NextEntry;
+	FibCount++;
+    }
+
+    return FibCount;    
+}
+
+
 UINT CommonPrefixLength(
     PIP_ADDRESS Address1,
     PIP_ADDRESS Address2)
@@ -108,33 +150,25 @@
 
     TI_DbgPrint(DEBUG_ROUTER, ("Called. Address1 (0x%X)  Address2 (0x%X).\n", Address1, Address2));
 
-    TI_DbgPrint(DEBUG_ROUTER, ("Address1 (%s)  Address2 (%s).\n",
-        A2S(Address1), A2S(Address2)));
+    /*TI_DbgPrint(DEBUG_ROUTER, ("Target  (%s) \n", A2S(Address1)));*/
+    /*TI_DbgPrint(DEBUG_ROUTER, ("Adapter (%s).\n", A2S(Address2)));*/
 
     if (Address1->Type == IP_ADDRESS_V4)
         Size = sizeof(IPv4_RAW_ADDRESS);
     else
         Size = sizeof(IPv6_RAW_ADDRESS);
 
-    Addr1 = (PUCHAR)&Address1->Address;
-    Addr2 = (PUCHAR)&Address2->Address;
+    Addr1 = (PUCHAR)&Address1->Address.IPv4Address;
+    Addr2 = (PUCHAR)&Address2->Address.IPv4Address;
 
     /* Find first non-matching byte */
-    for (i = 0; ; i++) {
-        if (i == Size)
-            return 8 * i; /* The two addresses are equal */
-
-        if (Addr1[i] != Addr2[i])
-            break;
-    }
+    for (i = 0; i < Size && Addr1[i] == Addr2[i]; i++);
+    if( i == Size ) return 8 * i;
 
     /* Find first non-matching bit */
     Bitmask = 0x80;
-    for (j = 0; ; j++) {
-        if ((Addr1[i] & Bitmask) != (Addr2[i] & Bitmask))
-            break;
+    for (j = 0; (Addr1[i] & Bitmask) != (Addr2[i] & Bitmask); j++)
         Bitmask >>= 1;
-    }
 
     return 8 * i + j;
 }
@@ -161,8 +195,10 @@
 
     TI_DbgPrint(DEBUG_ROUTER, ("Called. Address (0x%X)  Prefix (0x%X)  Length (%d).\n", Address, Prefix, Length));
 
+#if 0
     TI_DbgPrint(DEBUG_ROUTER, ("Address (%s)  Prefix (%s).\n",
         A2S(Address), A2S(Prefix)));
+#endif
 
     /* Check that initial integral bytes match */
     while (Length > 8) {
@@ -207,7 +243,8 @@
 
     CurrentEntry = Interface->NTEListHead.Flink;
     while (CurrentEntry != &Interface->NTEListHead) {
-	    Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
+	Current = CONTAINING_RECORD(CurrentEntry, NET_TABLE_ENTRY, IFListEntry);
+	TI_DbgPrint(DEBUG_ROUTER, ("Looking at NTE %s\n", A2S(Current->Address)));
 
         Length = CommonPrefixLength(Destination, Current->Address);
         if (BestNTE) {
@@ -271,7 +308,6 @@
 PFIB_ENTRY RouterAddRoute(
     PIP_ADDRESS NetworkAddress,
     PIP_ADDRESS Netmask,
-    PNET_TABLE_ENTRY NTE,
     PNEIGHBOR_CACHE_ENTRY Router,
     UINT Metric)
 /*
@@ -279,24 +315,23 @@
  * ARGUMENTS:
  *     NetworkAddress = Pointer to address of network
  *     Netmask        = Pointer to netmask of network
- *     NTE            = Pointer to NTE to use
  *     Router         = Pointer to NCE of router to use
  *     Metric         = Cost of this route
  * RETURNS:
  *     Pointer to FIB entry if the route was added, NULL if not
  * NOTES:
- *     The FIB entry references the NetworkAddress, Netmask, NTE and
+ *     The FIB entry references the NetworkAddress, Netmask and
  *     the NCE of the router. The caller is responsible for providing
  *     these references
  */
 {
     PFIB_ENTRY FIBE;
 
-    TI_DbgPrint(DEBUG_ROUTER, ("Called. NetworkAddress (0x%X)  Netmask (0x%X)  NTE (0x%X)  "
-        "Router (0x%X)  Metric (%d).\n", NetworkAddress, Netmask, NTE, Router, Metric));
+    TI_DbgPrint(DEBUG_ROUTER, ("Called. NetworkAddress (0x%X)  Netmask (0x%X) "
+        "Router (0x%X)  Metric (%d).\n", NetworkAddress, Netmask, Router, Metric));
 
-    TI_DbgPrint(DEBUG_ROUTER, ("NetworkAddress (%s)  Netmask (%s)  NTE (%s)  Router (%s).\n",
-        A2S(NetworkAddress), A2S(Netmask), A2S(NTE->Address), A2S(Router->Address)));
+    TI_DbgPrint(DEBUG_ROUTER, ("NetworkAddress (%s)  Netmask (%s)  Router (%s).\n",
+			       A2S(NetworkAddress), A2S(Netmask), A2S(Router->Address)));
 
     FIBE = ExAllocatePool(NonPagedPool, sizeof(FIB_ENTRY));
     if (!FIBE) {
@@ -304,13 +339,11 @@
         return NULL;
     }
 
-   INIT_TAG(NTE, TAG('N','T','E',' '));
    INIT_TAG(Router, TAG('R','O','U','T'));
 
     FIBE->Free           = FreeFIB;
     FIBE->NetworkAddress = NetworkAddress;
     FIBE->Netmask        = Netmask;
-    FIBE->NTE            = NTE;
     FIBE->Router         = Router;
     FIBE->Metric         = Metric;
 
@@ -346,8 +379,9 @@
 
     TI_DbgPrint(DEBUG_ROUTER, ("Called. Destination (0x%X)  NTE (0x%X).\n", Destination, NTE));
 
-    TI_DbgPrint(DEBUG_ROUTER, ("Destination (%s)  NTE (%s).\n",
-        A2S(Destination), A2S(NTE->Address)));
+    TI_DbgPrint(DEBUG_ROUTER, ("Destination (%s)\n", A2S(Destination)));
+    if( NTE )
+	TI_DbgPrint(DEBUG_ROUTER, ("NTE (%s).\n", A2S(NTE->Address)));
 
     KeAcquireSpinLock(&FIBLock, &OldIrql);
 
@@ -476,7 +510,7 @@
 
     ReferenceObject(pNetworkAddress);
     ReferenceObject(pNetmask);
-    FIBE = RouterAddRoute(pNetworkAddress, pNetmask, NTE, NCE, 1);
+    FIBE = RouterAddRoute(pNetworkAddress, pNetmask, NCE, 1);
     if (!FIBE) {
         /* Not enough free resources */
         NBRemoveNeighbor(NCE);

reactos/drivers/net/tcpip/network
transmit.c 1.9 -> 1.10
diff -u -r1.9 -r1.10
--- transmit.c	11 May 2004 20:52:10 -0000	1.9
+++ transmit.c	9 Jun 2004 18:11:38 -0000	1.10
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <transmit.h>
 #include <routines.h>
@@ -66,6 +67,7 @@
         /* Calculate checksum of IP header */
         Header->Checksum = 0;
         Header->Checksum = (USHORT)IPv4Checksum(Header, IFC->HeaderSize, 0);
+	TI_DbgPrint(MID_TRACE,("IP Check: %x\n", Header->Checksum));
 
         /* Update pointers */
         IFC->DatagramData = (PVOID)((ULONG_PTR)IFC->DatagramData + DataSize);
@@ -103,23 +105,23 @@
     TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X)  NCE (0x%X)  PathMTU (%d).\n",
         IPPacket, NCE, PathMTU));
 
-    IFC = ExAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT));
+    IFC = exAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT));
     if (IFC == NULL)
         return STATUS_INSUFFICIENT_RESOURCES;
 
     /* We allocate a buffer for a PathMTU sized packet and reuse
        it for all fragments */
-    Data = ExAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
+    Data = exAllocatePool(NonPagedPool, MaxLLHeaderSize + PathMTU);
     if (Data == NULL) {
-        ExFreePool(IFC);
+        exFreePool(IFC);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
     /* Allocate NDIS packet */
     NdisAllocatePacket(&NdisStatus, &IFC->NdisPacket, GlobalPacketPool);
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        ExFreePool(Data);
-        ExFreePool(IFC);
+        exFreePool(Data);
+        exFreePool(IFC);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -127,9 +129,9 @@
     NdisAllocateBuffer(&NdisStatus, &IFC->NdisBuffer,
         GlobalBufferPool, Data, MaxLLHeaderSize + PathMTU);
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        NdisFreePacket(IFC->NdisPacket);
-        ExFreePool(Data);
-        ExFreePool(IFC);
+        FreeNdisPacket(IFC->NdisPacket);
+        exFreePool(Data);
+        exFreePool(IFC);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -206,8 +208,11 @@
             /* There are no more fragments to transmit, so call completion handler */
             NdisPacket = IFC->Datagram;
             FreeNdisPacket(IFC->NdisPacket);
-            ExFreePool(IFC);
-            (*PC(NdisPacket)->Complete)(PC(NdisPacket)->Context, NdisPacket, NdisStatus);
+            exFreePool(IFC);
+            (*PC(NdisPacket)->Complete)
+		(PC(NdisPacket)->Context, 
+		 NdisPacket, 
+		 NdisStatus);
         }
     }
 }
@@ -304,10 +309,11 @@
     TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X)  RCN (0x%X)\n", IPPacket, RCN));
 
     DISPLAY_IP_PACKET(IPPacket);
+    OskitDumpBuffer( IPPacket->Header, IPPacket->TotalSize );
 
     NCE = RCN->NCE;
 
-#if DBG
+#ifdef DBG
     if (!NCE) {
         TI_DbgPrint(MIN_TRACE, ("No NCE to use.\n"));
         FreeNdisPacket(IPPacket->NdisPacket);
@@ -317,16 +323,20 @@
 
     /* Fetch path MTU now, because it may change */
     PathMTU = RCN->PathMTU;
+    TI_DbgPrint(MID_TRACE,("PathMTU: %d\n", PathMTU));
 
     if (IPPacket->TotalSize > PathMTU) {
+	TI_DbgPrint(MID_TRACE,("Doing SendFragments\n"));
         return SendFragments(IPPacket, NCE, PathMTU);
     } else {
         if ((IPPacket->Flags & IP_PACKET_FLAG_RAW) == 0) {
             /* Calculate checksum of IP header */
+	    TI_DbgPrint(MID_TRACE,("-> not IP_PACKET_FLAG_RAW\n"));
             ((PIPv4_HEADER)IPPacket->Header)->Checksum = 0;
 
             ((PIPv4_HEADER)IPPacket->Header)->Checksum = (USHORT)
                 IPv4Checksum(IPPacket->Header, IPPacket->HeaderSize, 0);
+	    TI_DbgPrint(MID_TRACE,("IP Check: %x\n", ((PIPv4_HEADER)IPPacket->Header)->Checksum));
 
             TI_DbgPrint(MAX_TRACE, ("Sending packet (length is %d).\n",
                 WN2H(((PIPv4_HEADER)IPPacket->Header)->TotalLength)));

reactos/drivers/net/tcpip/tcpip
iinfo.c 1.1 -> 1.2
diff -N iinfo.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ iinfo.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,108 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS TCP/IP protocol driver
+ * FILE:        tcpip/iinfo.c
+ * PURPOSE:     Per-interface information.
+ * PROGRAMMERS: Art Yerkes
+ * REVISIONS:
+ *   CSH 01/08-2000 Created
+ */
+#include <roscfg.h>
+#include <tcpip.h>
+#include <lan.h>
+#include <address.h>
+#include <info.h>
+#include <pool.h>
+#include <ip.h>
+
+TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID *ID,
+				       PIP_INTERFACE Interface,
+				       PNDIS_BUFFER Buffer,
+				       PUINT BufferSize) {
+    TDI_STATUS Status = TDI_INVALID_REQUEST;
+    PIFENTRY OutData;
+    PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context;
+    PCHAR IFDescr;
+    KIRQL OldIrql;
+    ULONG Size;
+    UINT DescrLenMax = MAX_IFDESCR_LEN - 1;
+
+    TI_DbgPrint(MAX_TRACE, 
+		("Getting IFEntry MIB (IF %08x LA %08x) (%04x:%d)\n",
+		 Interface, IF, ID->tei_entity, ID->tei_instance));
+
+    OutData = 
+	(PIFENTRY)ExAllocatePool( NonPagedPool, 
+				  sizeof(IFENTRY) + MAX_IFDESCR_LEN );
+    
+    if( !OutData ) return TDI_INVALID_REQUEST; /* Out of memory */
+
+    RtlZeroMemory( OutData, sizeof(IFENTRY) + MAX_IFDESCR_LEN );
+
+    OutData->Index = ID->tei_instance + 1; 
+    /* viz: tcpip keeps those indices */
+    OutData->Type = IF ? 1 : 0; /* XXX other -- for now ... */
+    OutData->Mtu = Interface->MTU;
+    TI_DbgPrint(MAX_TRACE, 
+		("Getting interface speed\n"));
+    OutData->PhysAddrLen = Interface->AddressLength;
+    OutData->AdminStatus = 1; /* XXX Up -- How do I know? */
+    OutData->OperStatus = 1; /* XXX Up -- How do I know? */
+
+    IFDescr = (PCHAR)&OutData[1];
+
+    if( IF ) {
+	GetInterfaceSpeed( Interface, &OutData->Speed );
+	TI_DbgPrint(MAX_TRACE,
+		    ("IF Speed = %d * 100bps\n", OutData->Speed));
+	memcpy(OutData->PhysAddr,Interface->Address,Interface->AddressLength);
+	TI_DbgPrint(MAX_TRACE, ("Got HWAddr\n"));
+	GetInterfaceName( Interface, IFDescr, MAX_IFDESCR_LEN - 1 );
+	DescrLenMax = strlen( IFDescr ) + 1;
+    }
+
+    IFDescr[DescrLenMax] = 0; /* Terminate ifdescr string */
+
+    TI_DbgPrint(MAX_TRACE, ("Copied in name %s\n", IFDescr));
+    OutData->DescrLen = DescrLenMax;
+    IFDescr += DescrLenMax;
+    Size = IFDescr - (PCHAR)OutData + 1;
+
+    TI_DbgPrint(MAX_TRACE, ("Finished IFEntry MIB (%04x:%d) size %d\n",
+			    ID->tei_entity, ID->tei_instance, Size));
+
+    Status = InfoCopyOut( OutData, Size, Buffer, BufferSize );
+    ExFreePool( OutData );
+
+    return Status;
+}
+    
+TDI_STATUS InfoInterfaceTdiQueryEx( UINT InfoClass,
+				    UINT InfoType,
+				    UINT InfoId,
+				    PVOID Context,
+				    TDIEntityID *id,
+				    PNDIS_BUFFER Buffer,
+				    PUINT BufferSize ) {
+    if( InfoClass == INFO_CLASS_GENERIC &&
+	InfoType == INFO_TYPE_PROVIDER &&
+	InfoId == ENTITY_TYPE_ID ) {
+	ULONG Temp = IF_MIB;
+	return InfoCopyOut( &Temp, sizeof(Temp), Buffer, BufferSize );
+    } else if( InfoClass == INFO_CLASS_PROTOCOL && 
+	       InfoType == INFO_TYPE_PROVIDER &&
+	       InfoId == IF_MIB_STATS_ID ) {
+	return InfoTdiQueryGetInterfaceMIB( id, Context, Buffer, BufferSize );
+    } else 
+	return TDI_INVALID_REQUEST;
+}
+
+TDI_STATUS InfoInterfaceTdiSetEx( UINT InfoClass,
+				  UINT InfoType,
+				  UINT InfoId,
+				  PVOID Context,
+				  TDIEntityID *id,
+				  PCHAR Buffer,
+				  UINT BufferSize ) {
+    return TDI_INVALID_REQUEST;
+}

reactos/drivers/net/tcpip/tcpip
interface.c 1.1 -> 1.2
diff -N interface.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ interface.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,108 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS TCP/IP protocol driver
+ * FILE:        tcpip/interface.c
+ * PURPOSE:     Convenient abstraction for getting and setting information
+ *              in IP_INTERFACE.
+ * PROGRAMMERS: Art Yerkes
+ * REVISIONS:
+ *   CSH 01/08-2000 Created
+ */
+#include <roscfg.h>
+#include <tcpip.h>
+#include <lan.h>
+#include <address.h>
+#include <pool.h>
+#include <ip.h>
+
+NTSTATUS GetInterfaceIPv4Address( PIP_INTERFACE Interface, 
+				  ULONG TargetType,
+				  PULONG Address ) {
+    PLIST_ENTRY CurrentIFEntry;
+    PLIST_ENTRY CurrentADEEntry;
+    PADDRESS_ENTRY CurrentADE;
+    
+    CurrentADEEntry = Interface->ADEListHead.Flink;
+    while (CurrentADEEntry != &Interface->ADEListHead)
+    {
+	CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
+	if (CurrentADE->Type == TargetType) {
+	    *Address = CurrentADE->Address->Address.IPv4Address;
+	    return STATUS_SUCCESS;
+	}
+	CurrentADEEntry = CurrentADEEntry->Flink;
+    }
+    
+    return STATUS_UNSUCCESSFUL;
+}
+
+UINT CountInterfaces() {
+    DWORD Count = 0;
+    KIRQL OldIrql;
+    PLIST_ENTRY CurrentIFEntry;
+
+    KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
+    
+    CurrentIFEntry = InterfaceListHead.Flink;
+    while (CurrentIFEntry != &InterfaceListHead) {
+	Count++;
+	CurrentIFEntry = CurrentIFEntry->Flink;
+    }
+
+    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
+
+    return Count;
+}
+
+UINT CountInterfaceAddresses( PIP_INTERFACE Interface ) {
+    UINT AddrCount = 0;
+    PADDRESS_ENTRY CurrentADE;
+    PLIST_ENTRY CurrentADEntry;
+
+    CurrentADEntry = Interface->ADEListHead.Flink;
+    
+    while( CurrentADEntry != &Interface->ADEListHead ) {
+	CurrentADEntry = CurrentADEntry->Flink;
+	CurrentADE = CONTAINING_RECORD(CurrentADEntry, 
+				       ADDRESS_ENTRY, 
+				       ListEntry);
+	if( CurrentADE->Type == ADE_UNICAST )
+	    AddrCount++;
+    }
+
+    return AddrCount;
+}
+
+NTSTATUS GetInterfaceSpeed( PIP_INTERFACE Interface, PUINT Speed ) {
+    NDIS_STATUS NdisStatus;
+    PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context;
+    
+    /* Get maximum link speed */
+    NdisStatus = NDISCall(IF,
+                          NdisRequestQueryInformation,
+                          OID_GEN_LINK_SPEED,
+                          Speed,
+                          sizeof(UINT));
+    
+    return 
+	NdisStatus != NDIS_STATUS_SUCCESS ? 
+	STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
+}
+
+NTSTATUS GetInterfaceName( PIP_INTERFACE Interface, 
+			   PCHAR NameBuffer,
+			   UINT Len ) {
+    NDIS_STATUS NdisStatus;
+    PLAN_ADAPTER IF = (PLAN_ADAPTER)Interface->Context;
+    
+    /* Get maximum link speed */
+    NdisStatus = NDISCall(IF,
+                          NdisRequestQueryInformation,
+                          OID_GEN_FRIENDLY_NAME,
+                          NameBuffer,
+			  Len);
+    
+    return 
+	NdisStatus != NDIS_STATUS_SUCCESS ? 
+	STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
+}

reactos/drivers/net/tcpip/tcpip
irp.c 1.1 -> 1.2
diff -N irp.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ irp.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,30 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS TCP/IP protocol driver
+ * FILE:        tcpip/dispatch.h
+ * PURPOSE:     TDI dispatch routines
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * REVISIONS:
+ *   CSH 01/08-2000 Created
+ * TODO:        Validate device object in all dispatch routines
+ */
+#include <roscfg.h>
+#include <tcpip.h>
+#include <dispatch.h>
+#include <routines.h>
+#include <datagram.h>
+#include <info.h>
+
+NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
+    IoSetCancelRoutine( Irp, NULL );
+
+    if( Status == STATUS_PENDING )
+	IoMarkIrpPending( Irp );
+    else {
+	Irp->IoStatus.Status = Status;
+	IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+    }
+
+    return Status;
+}
+

reactos/drivers/net/tcpip/tcpip
memtrack.c 1.1 -> 1.2
diff -N memtrack.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ memtrack.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,146 @@
+#define MEMTRACK_NO_POOL
+#include <roscfg.h>
+#include <tcpip.h>
+#include <ntddk.h>
+#include <memtrack.h>
+
+#ifdef MEMTRACK
+LIST_ENTRY AllocatedObjectsList;
+KSPIN_LOCK AllocatedObjectsLock;
+DWORD TagsToShow[MEMTRACK_MAX_TAGS_TO_TRACK] = { 0 };
+
+VOID TrackTag( DWORD Tag ) {
+    UINT i;
+
+    for( i = 0; TagsToShow[i]; i++ );
+    TagsToShow[i] = Tag;
+}
+
+VOID TrackingInit() {
+    KeInitializeSpinLock( &AllocatedObjectsLock );
+    InitializeListHead( &AllocatedObjectsList );
+}
+
+VOID ShowTrackedThing( PCHAR What, PALLOCATION_TRACKER Thing, 
+		       PCHAR File, UINT Line ) {
+    /* if( ShowTag( Thing->Tag ) ) */
+    if( File ) {
+	DbgPrint( "[%s] Thing %08x %c%c%c%c (%s:%d) (Called from %s:%d)\n", 
+		  What,
+		  Thing->Thing,
+		  ((PCHAR)&Thing->Tag)[3],
+		  ((PCHAR)&Thing->Tag)[2],
+		  ((PCHAR)&Thing->Tag)[1],
+		  ((PCHAR)&Thing->Tag)[0],
+		  Thing->FileName,
+		  Thing->LineNo,
+		  File, Line );
+    } else {
+	DbgPrint( "[%s] Thing %08x %c%c%c%c (%s:%d)\n", 
+		  What,
+		  Thing->Thing,
+		  ((PCHAR)&Thing->Tag)[3],
+		  ((PCHAR)&Thing->Tag)[2],
+		  ((PCHAR)&Thing->Tag)[1],
+		  ((PCHAR)&Thing->Tag)[0],
+		  Thing->FileName,
+		  Thing->LineNo );
+    }
+}
+
+VOID TrackWithTag( DWORD Tag, PVOID Thing, PCHAR FileName, DWORD LineNo ) {
+    PALLOCATION_TRACKER TrackedThing = 
+	ExAllocatePool( NonPagedPool, sizeof(*TrackedThing) );
+
+    KIRQL OldIrql;
+    PLIST_ENTRY Entry;
+    PALLOCATION_TRACKER ThingInList;
+
+    KeAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
+    Entry = AllocatedObjectsList.Flink;
+    while( Entry != &AllocatedObjectsList ) {
+	ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry);
+	if( ThingInList->Thing == Thing ) {
+	    RemoveEntryList(Entry);
+	    
+	    ShowTrackedThing( "Alloc", ThingInList, FileName, LineNo );
+	    
+	    ExFreePool( ThingInList );
+	    TrackDumpFL( FileName, LineNo );
+	    KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
+	    DbgPrint("TRACK: SPECIFIED ALREADY ALLOCATED ITEM %x\n", Thing);
+	    KeBugCheck( 0 );
+	}
+	Entry = Entry->Flink;
+    }
+
+    KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
+
+    if( TrackedThing ) {
+	TrackedThing->Tag      = Tag;
+	TrackedThing->Thing    = Thing;
+	TrackedThing->FileName = FileName;
+	TrackedThing->LineNo   = LineNo;
+	
+	ExInterlockedInsertTailList( &AllocatedObjectsList, 
+				     &TrackedThing->Entry,
+				     &AllocatedObjectsLock );
+	ShowTrackedThing( "Alloc", TrackedThing, FileName, LineNo );
+    }
+
+    /*TrackDumpFL( FileName, LineNo );*/
+}
+
+BOOL ShowTag( DWORD Tag ) {
+    UINT i;
+
+    for( i = 0; TagsToShow[i] && TagsToShow[i] != Tag; i++ );
+    
+    return TagsToShow[i] ? TRUE : FALSE;
+}
+
+VOID UntrackFL( PCHAR File, DWORD Line, PVOID Thing ) {
+    KIRQL OldIrql;
+    PLIST_ENTRY Entry;
+    PALLOCATION_TRACKER ThingInList;
+
+    KeAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
+    Entry = AllocatedObjectsList.Flink;
+    while( Entry != &AllocatedObjectsList ) {
+	ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry);
+	if( ThingInList->Thing == Thing ) {
+	    RemoveEntryList(Entry);
+	    
+	    ShowTrackedThing( "Free ", ThingInList, File, Line );
+	    
+	    ExFreePool( ThingInList );
+	    KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
+	    /* TrackDumpFL( File, Line ); */
+	    return;
+	}
+	Entry = Entry->Flink;
+    }
+    KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
+    TrackDumpFL( File, Line );
+    DbgPrint("UNTRACK: SPECIFIED ALREADY FREE ITEM %x\n", Thing);
+    KeBugCheck( 0 );
+}
+
+VOID TrackDumpFL( PCHAR File, DWORD Line ) {
+    KIRQL OldIrql;
+    PLIST_ENTRY Entry;
+    PALLOCATION_TRACKER Thing;
+
+    DbgPrint("Dump: %s:%d\n", File, Line);
+
+    KeAcquireSpinLock( &AllocatedObjectsLock, &OldIrql );
+    Entry = AllocatedObjectsList.Flink;
+    while( Entry != &AllocatedObjectsList ) {
+	Thing = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry);
+	ShowTrackedThing( "Dump ", Thing, 0, 0 );
+	Entry = Entry->Flink;
+    }
+    KeReleaseSpinLock( &AllocatedObjectsLock, OldIrql );
+}
+
+#endif/*MEMTRACK*/

reactos/drivers/net/tcpip/tcpip
ninfo.c 1.1 -> 1.2
diff -N ninfo.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ninfo.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,248 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS TCP/IP protocol driver
+ * FILE:        tcpip/ninfo.c
+ * PURPOSE:     Network information
+ * PROGRAMMERS: Art Yerkes
+ * REVISIONS:
+ *   CSH 01/08-2000 Created
+ */
+#include <roscfg.h>
+#include <tcpip.h>
+#include <address.h>
+#include <info.h>
+#include <pool.h>
+#include <prefix.h>
+#include <ip.h>
+#include <route.h>
+
+TDI_STATUS InfoTdiQueryGetAddrTable( PNDIS_BUFFER Buffer, 
+				     PUINT BufferSize ) {
+    PIP_INTERFACE CurrentIF;
+    PLIST_ENTRY CurrentIFEntry;
+    TDI_STATUS Status = TDI_INVALID_REQUEST;
+    KIRQL OldIrql;
+    UINT Count = 1; /* Start adapter indices at 1 */
+    UINT IfCount = CountInterfaces();
+    PIPADDR_ENTRY IpAddress = 
+	ExAllocatePool( NonPagedPool, sizeof( IPADDR_ENTRY ) * IfCount );
+    PIPADDR_ENTRY IpCurrent = IpAddress;
+
+    TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+    
+    KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
+    
+    CurrentIFEntry = InterfaceListHead.Flink;
+    while (CurrentIFEntry != &InterfaceListHead)
+    {
+	CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+
+	IpCurrent->Index     = Count;
+	IpCurrent->Addr      = 0;
+	IpCurrent->BcastAddr = 0;
+	IpCurrent->Mask      = 0;
+	
+	/* Locate the diffrent addresses and put them the right place */
+	GetInterfaceIPv4Address( CurrentIF,
+				 ADE_UNICAST,
+				 &IpAddress->Addr );
+	GetInterfaceIPv4Address( CurrentIF,
+				 ADE_MULTICAST,
+				 &IpAddress->BcastAddr );
+	GetInterfaceIPv4Address( CurrentIF,
+				 ADE_ADDRMASK,
+				 &IpAddress->Mask );
+	IpCurrent++;
+	CurrentIFEntry = CurrentIFEntry->Flink;
+	Count++;
+    }
+    
+    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
+
+    Status = InfoCopyOut( IpAddress, sizeof(*IpAddress) * Count,
+			  Buffer, BufferSize );
+    
+    ExFreePool( IpAddress );
+
+    TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
+
+    return Status;
+}
+
+/* Get IPRouteEntry s for each of the routes in the system */
+TDI_STATUS InfoTdiQueryGetRouteTable( PNDIS_BUFFER Buffer, PUINT BufferSize ) {
+    PIP_INTERFACE CurrentIF;
+    PLIST_ENTRY CurrentIFEntry;
+    TDI_STATUS Status;
+    KIRQL OldIrql;
+    UINT RtCount = CountFIBs(),
+	Size = sizeof( IPROUTE_ENTRY ) * RtCount;
+    PFIB_ENTRY RCache = 
+	ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ),
+	RCacheCur = RCache;
+    PIPROUTE_ENTRY RouteEntries = ExAllocatePool( NonPagedPool, Size ),
+	RtCurrent = RouteEntries;
+
+    TI_DbgPrint(MAX_TRACE, ("Called, routes = %d, RCache = %08x\n", 
+			    RtCount, RCache));
+
+    if( !RCache || !RouteEntries ) {
+	if( RCache ) ExFreePool( RCache );
+	if( RouteEntries ) ExFreePool( RouteEntries );
+	return STATUS_NO_MEMORY;
+    }
+
+    RtlZeroMemory( RouteEntries, Size );
+
+    RtCount = CopyFIBs( RCache );
+    
+    while( RtCurrent < RouteEntries + RtCount ) {
+	/* Copy Desitnation */
+	if( RCacheCur->NetworkAddress && RCacheCur->Netmask && 
+	    RCacheCur->Router && RCacheCur->Router->Address ) {
+	    TI_DbgPrint(MAX_TRACE, ("%d: NA %08x NM %08x GW %08x MT %d\n",
+				    RtCurrent - RouteEntries,
+				    RCacheCur->NetworkAddress->Address,
+				    RCacheCur->Netmask->Address,
+				    RCacheCur->Router->Address->Address,
+				    RCacheCur->Metric));
+	    
+	    RtlCopyMemory( &RtCurrent->Dest, 
+			   &RCacheCur->NetworkAddress->Address,
+			   sizeof(RtCurrent->Dest) );
+	    RtlCopyMemory( &RtCurrent->Mask,
+			   &RCacheCur->Netmask->Address,
+			   sizeof(RtCurrent->Mask) );
+	    /* Currently, this address is stuffed into the pointer.
+	     * That probably is not intended. */
+	    RtlCopyMemory( &RtCurrent->Gw,
+			   &RCacheCur->Router->Address->Address,
+			   sizeof(RtCurrent->Gw) );
+	    RtCurrent->Metric1 = RCacheCur->Metric;
+	    RtCurrent->Type = 2 /* PF_INET */;
+	    
+	    KeAcquireSpinLock(&EntityListLock, &OldIrql);
+	    for( RtCurrent->Index = EntityCount - 1; 
+		 RtCurrent->Index >= 0 &&
+		     RCacheCur->Router->Interface != 
+		     EntityList[RtCurrent->Index].context;
+		 RtCurrent->Index-- );
+	    RtCurrent->Index = EntityList[RtCurrent->Index].tei_instance;
+	    KeReleaseSpinLock(&EntityListLock, OldIrql);
+	} else {
+	    TI_DbgPrint(MAX_TRACE, ("%d: BAD: NA %08x NM %08x GW %08x MT %d\n",
+				    RtCurrent - RouteEntries,
+				    RCacheCur->NetworkAddress,
+				    RCacheCur->Netmask,
+				    RCacheCur->Router,
+				    RCacheCur->Router ? 
+				    RCacheCur->Router->Address : 0,
+				    RCacheCur->Metric));
+	}
+	RtCurrent++; RCacheCur++;
+    }
+
+    Status = InfoCopyOut( RouteEntries, Size, Buffer, BufferSize );
+
+    ExFreePool( RouteEntries );
+    ExFreePool( RCache );
+
+    TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
+
+    return Status;
+}
+		
+TDI_STATUS InfoTdiQueryGetIPSnmpInfo( PNDIS_BUFFER Buffer,
+				      PUINT BufferSize ) {
+    KIRQL OldIrql;
+    PIP_INTERFACE CurrentIF;
+    PLIST_ENTRY CurrentIFEntry;
+    IPSNMP_INFO SnmpInfo;
+    UINT IfCount = CountInterfaces();
+    UINT AddrCount = 0;
+    UINT RouteCount = CountRouteNodes( NULL );
+    TDI_STATUS Status = TDI_INVALID_REQUEST;
+
+    TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+    RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
+    
+    /* Count number of addresses */
+    AddrCount = 0;
+    KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
+    
+    CurrentIFEntry = InterfaceListHead.Flink;
+    while (CurrentIFEntry != &InterfaceListHead)
+    {
+	CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
+	AddrCount += CountInterfaceAddresses( CurrentIF );
+	CurrentIFEntry = CurrentIFEntry->Flink;
+    }
+    
+    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
+    
+    SnmpInfo.NumIf = IfCount;
+    SnmpInfo.NumAddr = AddrCount;
+    SnmpInfo.NumRoutes = RouteCount;
+
+    Status = InfoCopyOut( &SnmpInfo, sizeof(SnmpInfo), 
+			  Buffer, BufferSize );
+
+    TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
+
+    return Status;
+}
+
+TDI_STATUS InfoNetworkLayerTdiQueryEx( UINT InfoClass,
+				       UINT InfoType,
+				       UINT InfoId,
+				       PVOID Context,
+				       TDIEntityID *id,
+				       PNDIS_BUFFER Buffer,
+				       PUINT BufferSize ) {
+    TDI_STATUS Status = TDI_INVALID_REQUEST;
+    
+    TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+    switch( InfoClass ) {
+    case INFO_CLASS_GENERIC:
+	if( InfoType == INFO_TYPE_PROVIDER && InfoId == ENTITY_TYPE_ID ) {
+	    ULONG Return = CL_NL_IP;
+	    Status = InfoCopyOut( &Return, sizeof(Return), 
+				  Buffer, BufferSize );
+	}
+	break;
+
+    case INFO_CLASS_PROTOCOL:
+	switch( InfoType ) {
+	case INFO_TYPE_PROVIDER:
+	    switch( InfoId ) {
+	    case IP_MIB_ADDRTABLE_ENTRY_ID:
+		Status = InfoTdiQueryGetAddrTable( Buffer, BufferSize );
+		break;
+
+	    case IP_MIB_ROUTETABLE_ENTRY_ID:
+		Status = InfoTdiQueryGetRouteTable( Buffer, BufferSize );
+		break;
+
+	    case IP_MIB_STATS_ID:
+		Status = InfoTdiQueryGetIPSnmpInfo( Buffer, BufferSize );
+		break;
+	    }
+	    break;
+	}
+    }
+
+    TI_DbgPrint(MAX_TRACE, ("Returning %08x\n", Status));
+
+    return Status;
+}
+
+TDI_STATUS InfoNetworkLayerTdiSetEx( UINT InfoClass,
+				     UINT InfoType,
+				     UINT InfoId,
+				     PVOID Context,
+				     TDIEntityID *id,
+				     PCHAR Buffer,
+				     UINT BufferSize ) {
+}

reactos/drivers/net/tcpip/tcpip
tinfo.c 1.1 -> 1.2
diff -N tinfo.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tinfo.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,40 @@
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS TCP/IP protocol driver
+ * FILE:        tcpip/tinfo.c
+ * PURPOSE:     Transport layer information
+ * PROGRAMMERS: Art Yerkes
+ * REVISIONS:
+ *   CSH 01/08-2000 Created
+ */
+#include <roscfg.h>
+#include <tcpip.h>
+#include <address.h>
+#include <pool.h>
+#include <ip.h>
+
+TDI_STATUS InfoTransportLayerTdiQueryEx( UINT InfoClass,
+					 UINT InfoType,
+					 UINT InfoId,
+					 PVOID Context,
+					 TDIEntityID *id,
+					 PNDIS_BUFFER Buffer,
+					 PUINT BufferSize ) {
+    if( InfoClass == INFO_CLASS_GENERIC &&
+	InfoType == INFO_TYPE_PROVIDER &&
+	InfoId == ENTITY_TYPE_ID ) {
+	ULONG Temp = CL_TL_UDP;
+	return InfoCopyOut( &Temp, sizeof(Temp), Buffer, BufferSize );
+    }
+    
+    return TDI_INVALID_REQUEST;
+}
+
+TDI_STATUS InfoTransportLayerTdiSetEx( UINT InfoClass,
+				       UINT InfoType,
+				       UINT InfoId,
+				       PVOID Context,
+				       TDIEntityID *id,
+				       PCHAR Buffer,
+				       UINT BufferSize ) {
+}

reactos/drivers/net/tcpip/tcpip
address.c 1.11 -> 1.12
diff -u -r1.11 -r1.12
--- address.c	12 Mar 2004 04:21:59 -0000	1.11
+++ address.c	9 Jun 2004 18:11:38 -0000	1.12
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <address.h>
 #include <pool.h>
@@ -164,7 +165,9 @@
                     }
                 }
 
-                IPAddress = ExAllocatePool(NonPagedPool, sizeof(IP_ADDRESS));
+                IPAddress = ExAllocatePoolWithTag(NonPagedPool,
+					          sizeof(IP_ADDRESS),
+						  FOURCC('I','P','v','4'));
                 if (IPAddress) {
                     AddrInitIPv4(IPAddress, ValidAddr->in_addr);
                     *Address = IPAddress;

reactos/drivers/net/tcpip/tcpip
checksum.c 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- checksum.c	11 May 2004 20:52:10 -0000	1.4
+++ checksum.c	9 Jun 2004 18:11:38 -0000	1.5
@@ -8,6 +8,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <checksum.h>
 

reactos/drivers/net/tcpip/tcpip
dispatch.c 1.11 -> 1.12
diff -u -r1.11 -r1.12
--- dispatch.c	8 Mar 2004 10:20:18 -0000	1.11
+++ dispatch.c	9 Jun 2004 18:11:38 -0000	1.12
@@ -8,6 +8,7 @@
  *   CSH 01/08-2000 Created
  * TODO:        Validate device object in all dispatch routines
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <dispatch.h>
 #include <routines.h>
@@ -53,13 +54,9 @@
     Irp->IoStatus.Status      = STATUS_CANCELLED;
     Irp->IoStatus.Information = 0;
 
-    TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
-
-    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-
     TI_DbgPrint(DEBUG_IRP, ("Leaving (IRP was already cancelled).\n"));
 
-    return STATUS_CANCELLED;
+    return IRPFinish(Irp, STATUS_CANCELLED);
 }
 
 
@@ -223,7 +220,7 @@
 
     TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
 
-    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+    IRPFinish(Irp, STATUS_SUCCESS);
 }
 
 
@@ -239,7 +236,7 @@
 {
   TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
 
-	return STATUS_NOT_IMPLEMENTED;
+  return STATUS_NOT_IMPLEMENTED;
 }
 
 
@@ -378,11 +375,14 @@
   Request.RequestNotifyObject      = DispDataRequestComplete;
   Request.RequestContext           = Irp;
 
+  /* XXX Handle connected UDP, etc... */
   Status = TCPConnect(
     &Request,
     Parameters->RequestConnectionInformation,
     Parameters->ReturnConnectionInformation);
 
+  TI_DbgPrint(MAX_TRACE, ("TCP Connect returned %08x\n", Status));
+
   return Status;
 }
 
@@ -555,36 +555,7 @@
 
   Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
 
-  /* Initialize a listen request */
-  Request = (PTDI_REQUEST) ExAllocatePool(NonPagedPool, sizeof(TDI_REQUEST));
-  if (Request == NULL)
-    {
-      return STATUS_NO_MEMORY;
-    }
-
-  Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);
-  if (NT_SUCCESS(Status))
-    {
-      Request->Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
-      Request->RequestNotifyObject      = DispDataRequestComplete;
-      Request->RequestContext           = Irp;
-
-      Status = TCPListen(
-        Request,
-        Parameters->RequestConnectionInformation,
-        Parameters->ReturnConnectionInformation);
-      if (Status != STATUS_PENDING)
-        {
-          IoAcquireCancelSpinLock(&OldIrql);
-          IoSetCancelRoutine(Irp, NULL);
-          IoReleaseCancelSpinLock(OldIrql);
-        }
-    }
-
-  if (Status != STATUS_PENDING)
-    {
-      ExFreePool(Request);
-    }
+  Status = TCPListen( Request, 1024 /* BACKLOG */ );
 
   return Status;
 }
@@ -683,9 +654,61 @@
  *     Status of operation
  */
 {
+  PIO_STACK_LOCATION IrpSp;
+  PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
+  PTRANSPORT_CONTEXT TranContext;
+  TDI_REQUEST Request;
+  NTSTATUS Status;
+  ULONG BytesReceived;
+
   TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
 
-	return STATUS_NOT_IMPLEMENTED;
+  IrpSp = IoGetCurrentIrpStackLocation(Irp);
+  ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
+
+  TranContext = IrpSp->FileObject->FsContext;
+  if (TranContext == NULL)
+    {
+      TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+      return STATUS_INVALID_CONNECTION;
+    }
+
+  if (TranContext->Handle.ConnectionContext == NULL)
+    {
+      TI_DbgPrint(MID_TRACE, ("No connection endpoint file object.\n"));
+      return STATUS_INVALID_CONNECTION;
+    }
+
+  /* Initialize a receive request */
+  Request.Handle.ConnectionContext = TranContext->Handle.ConnectionContext;
+  Request.RequestNotifyObject = DispDataRequestComplete;
+  Request.RequestContext = Irp;
+  Status = DispPrepareIrpForCancel(
+    IrpSp->FileObject->FsContext,
+    Irp,
+    (PDRIVER_CANCEL)DispCancelRequest);
+  if (NT_SUCCESS(Status))
+    {
+      Status = TCPReceiveData(
+        &Request,
+        (PNDIS_BUFFER)Irp->MdlAddress,
+        ReceiveInfo->ReceiveLength,
+        ReceiveInfo->ReceiveFlags,
+        &BytesReceived);
+      if (Status != STATUS_PENDING)
+      {
+          DispDataRequestComplete(Irp, Status, BytesReceived);
+      }
+    }
+
+  if (Status != STATUS_PENDING)
+    {
+      IrpSp->Control &= ~SL_PENDING_RETURNED;
+    }
+
+  TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
+
+  return Status;
 }
 
 
@@ -712,6 +735,12 @@
   DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
 
   TranContext = IrpSp->FileObject->FsContext;
+  if (TranContext == NULL)
+    {
+      TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
+      return STATUS_INVALID_ADDRESS;
+    }
+
   /* Initialize a receive request */
   Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
   Request.RequestNotifyObject  = DispDataRequestComplete;
@@ -720,22 +749,26 @@
     IrpSp->FileObject->FsContext,
     Irp,
     (PDRIVER_CANCEL)DispCancelRequest);
-  if (NT_SUCCESS(Status)) {
-    Status = UDPReceiveDatagram(
-      &Request,
-      DgramInfo->ReceiveDatagramInformation,
-      (PNDIS_BUFFER)Irp->MdlAddress,
-      DgramInfo->ReceiveLength,
-      DgramInfo->ReceiveFlags,
-      DgramInfo->ReturnDatagramInformation,
-      &BytesReceived);
-    if (Status != STATUS_PENDING) {
-      DispDataRequestComplete(Irp, Status, BytesReceived);
-      /* Return STATUS_PENDING because DispPrepareIrpForCancel marks
-         the Irp as pending */
-      Status = STATUS_PENDING;
+  if (NT_SUCCESS(Status))
+    {
+      Status = UDPReceiveDatagram(
+        &Request,
+        DgramInfo->ReceiveDatagramInformation,
+        (PNDIS_BUFFER)Irp->MdlAddress,
+        DgramInfo->ReceiveLength,
+        DgramInfo->ReceiveFlags,
+        DgramInfo->ReturnDatagramInformation,
+        &BytesReceived);
+      if (Status != STATUS_PENDING)
+        {
+          DispDataRequestComplete(Irp, Status, BytesReceived);
+        }
+    }
+
+  if (Status != STATUS_PENDING)
+    {
+      IrpSp->Control &= ~SL_PENDING_RETURNED;
     }
-  }
 
   TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
 
@@ -753,9 +786,46 @@
  *     Status of operation
  */
 {
+    PIO_STACK_LOCATION IrpSp;
+    TDI_REQUEST Request;
+    PTDI_REQUEST_KERNEL_SEND SendInfo;
+    PTRANSPORT_CONTEXT TranContext;
+    NTSTATUS Status;
+
     TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
 
-	return STATUS_NOT_IMPLEMENTED;
+    IrpSp       = IoGetCurrentIrpStackLocation(Irp);
+    SendInfo    = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
+    TranContext = IrpSp->FileObject->FsContext;
+
+    /* Initialize a send request */
+    Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
+    Request.RequestNotifyObject  = DispDataRequestComplete;
+    Request.RequestContext       = Irp;
+
+    Status = DispPrepareIrpForCancel(
+        IrpSp->FileObject->FsContext,
+        Irp,
+        (PDRIVER_CANCEL)DispCancelRequest);
+    if (NT_SUCCESS(Status)) {
+
+        /* FIXME: DgramInfo->SendDatagramInformation->RemoteAddress 
+           must be of type PTDI_ADDRESS_IP */
+
+        Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
+            &Request, NULL, 
+	    (PNDIS_BUFFER)Irp->MdlAddress, SendInfo->SendLength);
+        if (Status != STATUS_PENDING) {
+            DispDataRequestComplete(Irp, Status, 0);
+            /* Return STATUS_PENDING because DispPrepareIrpForCancel
+               marks Irp as pending */
+            Status = STATUS_PENDING;
+        }
+    }
+
+    TI_DbgPrint(DEBUG_IRP, ("Leaving.\n"));
+
+    return Status;
 }
 
 
@@ -1209,9 +1279,7 @@
 
         TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
 
-        IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-
-        return STATUS_INVALID_PARAMETER;
+        return IRPFinish(Irp, STATUS_INVALID_PARAMETER);
     }
 
     Status = DispPrepareIrpForCancel(TranContext, Irp, NULL);

reactos/drivers/net/tcpip/tcpip
fileobjs.c 1.13 -> 1.14
diff -u -r1.13 -r1.14
--- fileobjs.c	11 May 2004 20:52:10 -0000	1.13
+++ fileobjs.c	9 Jun 2004 18:11:38 -0000	1.14
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <datagram.h>
 #include <address.h>
@@ -16,6 +17,7 @@
 #include <udp.h>
 #include <ip.h>
 #include <fileobjs.h>
+#include <oskittcp.h>
 
 /* List of all address file objects managed by this driver */
 LIST_ENTRY AddressFileListHead;
@@ -98,7 +100,8 @@
   CurrentEntry = AddrFile->TransmitQueue.Flink;
   while (CurrentEntry != &AddrFile->TransmitQueue) {
     NextEntry = CurrentEntry->Flink;
-    SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
+    SendRequest = CONTAINING_RECORD(CurrentEntry, 
+				    DATAGRAM_SEND_REQUEST, ListEntry);
     /* Abort the request and free its resources */
     KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
     (*SendRequest->Complete)(SendRequest->Context, STATUS_ADDRESS_CLOSED, 0);
@@ -309,7 +312,7 @@
   case IPPROTO_TCP:
     /* FIXME: If specified port is 0, a port is chosen dynamically */
     AddrFile->Port = Address->Address[0].Address[0].sin_port;
-    AddrFile->Send = TCPSendDatagram;
+    AddrFile->Send = TCPSendData;
     break;
 
   case IPPROTO_UDP:
@@ -437,7 +440,9 @@
   PTDI_REQUEST Request,
   PVOID ClientContext)
 {
+  NTSTATUS Status;
   PCONNECTION_ENDPOINT Connection;
+  PADDRESS_FILE AddrFile;
 
   TI_DbgPrint(MID_TRACE, ("Called.\n"));
 
@@ -455,15 +460,26 @@
   /* Reference the object */
   Connection->RefCount = 1;
 
-  /* Put connection in the closed state */
-  Connection->State = ctClosed;
-
   /* Save client context pointer */
   Connection->ClientContext = ClientContext;
+  Status = OskitTCPSocket( Connection,
+			   &Connection->SocketContext,
+			   AF_INET,
+			   SOCK_STREAM,
+			   IPPROTO_TCP );
+  DbgPrint("STATUS from OSKITTCP was %08x\n", Status);
+  
+  /* Initialize receive requests queue */
+  InitializeListHead(&Connection->ReceiveRequests);
 
-  /* Initialize receive queue */
+  /* Initialize received segments queue */
   InitializeListHead(&Connection->ReceivedSegments);
 
+TI_DbgPrint(MIN_TRACE, ("X1 cur 0x%x\n", &Connection->ReceivedSegments));
+TI_DbgPrint(MIN_TRACE, ("X1 Flink 0x%x\n", Connection->ReceivedSegments.Flink));
+TI_DbgPrint(MIN_TRACE, ("X1 Blink 0x%x\n", Connection->ReceivedSegments.Blink));
+
+
   /* Return connection endpoint file object */
   Request->Handle.ConnectionContext = Connection;
 
@@ -497,43 +513,9 @@
 
   Connection = Request->Handle.ConnectionContext;
 
-#if 0
-  KeAcquireSpinLock(&Connection->Lock, &OldIrql);
-  if ((!AF_IS_BUSY(Connection)) && (Connection->RefCount == 1)) {
-    /* Set connection endpoint file object exclusive to us */
-    AF_SET_BUSY(Connection);
-    AF_CLR_VALID(Connection);
-
-    KeReleaseSpinLock(&Connection->Lock, OldIrql);
-#endif
-    DeleteConnectionEndpoint(Connection);
-#if 0
-  } else {
-    if (!AF_IS_PENDING(Connection, AFF_DELETE)) {
-      Connection->Complete = Request->RequestNotifyObject;
-      Connection->Context  = Request->RequestContext;
-
-      /* Shedule connection endpoint for deletion */
-      AF_SET_PENDING(Connection, AFF_DELETE);
-      AF_CLR_VALID(Connection);
-
-      if (!AF_IS_BUSY(Connection)) {
-        /* Worker function is not running, so shedule it to run */
-        AF_SET_BUSY(Connection);
-        KeReleaseSpinLock(&Connection->Lock, OldIrql);
-        ExQueueWorkItem(&Connection->WorkItem, CriticalWorkQueue);
-      } else
-        KeReleaseSpinLock(&Connection->Lock, OldIrql);
-
-      TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
-
-      return STATUS_PENDING;
-    } else
-      Status = STATUS_ADDRESS_CLOSED;
+  TCPClose(Request);
+  DeleteConnectionEndpoint(Connection);
 
-    KeReleaseSpinLock(&Connection->Lock, OldIrql);
-  }
-#endif
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 
   return Status;

reactos/drivers/net/tcpip/tcpip
info.c 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- info.c	12 Mar 2004 04:21:59 -0000	1.5
+++ info.c	9 Jun 2004 18:11:38 -0000	1.6
@@ -7,321 +7,110 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <info.h>
 #include <routines.h>
+#include <debug.h>
 
-
-TDI_STATUS IPTdiQueryInformationEx(
-  PTDI_REQUEST Request,
-  TDIObjectID *ID,
-  PNDIS_BUFFER Buffer,
-  PUINT BufferSize,
-  PVOID Context)
-/*
- * FUNCTION: Returns extended information about network layer
- * ARGUMENTS:
- *   Request    = Pointer to TDI request structure for the request
- *   ID         = TDI object ID
- *   Buffer     = Pointer to buffer with data to use. 
- *   BufferSize = Pointer to buffer with size of Buffer. On return
- *                  this is filled with number of bytes returned
- *   Context    = Pointer to context buffer
- * RETURNS:
- *   Status of operation
- */
-{
-  PLIST_ENTRY CurrentIFEntry;
-  PLIST_ENTRY CurrentADEEntry;
-  PADDRESS_ENTRY CurrentADE;
-  PIP_INTERFACE CurrentIF;
-  IPADDR_ENTRY IpAddress;
-  IPSNMP_INFO SnmpInfo;
-  KIRQL OldIrql;
-  ULONG Entity;
-  ULONG Temp;
-  UINT Count;
-  UINT BufSize;
-
-  BufSize = *BufferSize;
-
-  /* Make return parameters consistent every time */
-  *BufferSize = 0;
-
-  Entity = ID->toi_entity.tei_entity;
-  if (Entity != CL_NL_ENTITY)
-    {
-      /* We can't handle this entity */
-      return TDI_INVALID_PARAMETER;
-    }
-
-  if (ID->toi_entity.tei_instance != TL_INSTANCE)
-    {
-      /* Only a single instance is supported */
-      return TDI_INVALID_REQUEST;
+TDI_STATUS InfoCopyOut( PCHAR DataOut, UINT SizeOut,
+			PNDIS_BUFFER ClientBuf, PUINT ClientBufSize ) {
+    UINT RememberedCBSize = *ClientBufSize;
+    *ClientBufSize = SizeOut;
+    if( RememberedCBSize < SizeOut )
+	return TDI_BUFFER_TOO_SMALL;
+    else {
+	CopyBufferToBufferChain( ClientBuf, 0, (PUCHAR)DataOut, SizeOut );
+	return TDI_SUCCESS;
     }
+}
 
-  if (ID->toi_class == INFO_CLASS_GENERIC)
-    {
-      if ((ID->toi_type == INFO_TYPE_PROVIDER) && 
-        (ID->toi_id == ENTITY_TYPE_ID))
-        {
-          if (BufSize < sizeof(ULONG))
-            {
-              return TDI_BUFFER_TOO_SMALL;
-            }
+VOID InsertTDIInterfaceEntity( PIP_INTERFACE Interface ) {
+    KIRQL OldIrql;
+    UINT Count = 0, i;
 
-          Temp = CL_NL_IP;
-          Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
+    TI_DbgPrint(MAX_TRACE, 
+		("Inserting interface %08x (%d entities already)\n", 
+		 Interface, EntityCount));
+
+    KeAcquireSpinLock( &EntityListLock, &OldIrql );
+
+    /* Count IP Entities */
+    for( i = 0; i < EntityCount; i++ )
+	if( EntityList[i].tei_entity == IF_ENTITY ) {
+	    Count++;
+	    TI_DbgPrint(MAX_TRACE, ("Entity %d is an IF.  Found %d\n", 
+				    i, Count));
+	}
+    
+    EntityList[EntityCount].tei_entity = IF_ENTITY;
+    EntityList[EntityCount].tei_instance = Count;
+    EntityList[EntityCount].context  = Interface;
+    EntityList[EntityCount].info_req = InfoInterfaceTdiQueryEx;
+    EntityList[EntityCount].info_set = InfoInterfaceTdiSetEx;
+    
+    EntityCount++;
 
-          return TDI_SUCCESS;
-        }
+    KeReleaseSpinLock( &EntityListLock, OldIrql );
+}
 
-      return TDI_INVALID_PARAMETER;
-    }
+VOID RemoveTDIInterfaceEntity( PIP_INTERFACE Interface ) {
+    KIRQL OldIrql;
+    UINT Count = 0, i;
 
-  if (ID->toi_class == INFO_CLASS_PROTOCOL)
-    {
-      if (ID->toi_type != INFO_TYPE_PROVIDER)
-        {
-          return TDI_INVALID_PARAMETER;
-        }
-
-      switch (ID->toi_id)
-        {
-          case IP_MIB_ADDRTABLE_ENTRY_ID:
-            Temp = 0;
-
-            KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
-
-            CurrentIFEntry = InterfaceListHead.Flink;
-            while (CurrentIFEntry != &InterfaceListHead)
-              {
-	              CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
-
-                if (Temp + sizeof(IPADDR_ENTRY) > BufSize)
-                  {
-                    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
-                    return TDI_BUFFER_TOO_SMALL;
-                  }
-
-                IpAddress.Addr      = 0;
-                IpAddress.BcastAddr = 0;
-                IpAddress.Mask      = 0;
-
-                /* Locate the diffrent addresses and put them the right place */
-                CurrentADEEntry = CurrentIF->ADEListHead.Flink;
-                while (CurrentADEEntry != &CurrentIF->ADEListHead)
-                  {
-	                  CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
-
-                    switch (CurrentADE->Type)
-                      {
-                        case ADE_UNICAST:
-                          IpAddress.Addr = CurrentADE->Address->Address.IPv4Address;
-                          break;
-                        case ADE_MULTICAST:
-                          IpAddress.BcastAddr = CurrentADE->Address->Address.IPv4Address;
-                          break;
-                        case ADE_ADDRMASK:
-                          IpAddress.Mask = CurrentADE->Address->Address.IPv4Address;
-                          break;
-                        default:
-                          /* Should not happen */
-                          TI_DbgPrint(MIN_TRACE, ("Unknown address entry type (0x%X)\n", CurrentADE->Type));
-                          break;
-                      }
-                    CurrentADEEntry = CurrentADEEntry->Flink;
-                  }
-
-                /* Pack the address information into IPADDR_ENTRY structure */
-                IpAddress.Index     = 0;
-                IpAddress.ReasmSize = 0;
-                IpAddress.Context   = 0;
-                IpAddress.Pad       = 0;
-
-                Count = CopyBufferToBufferChain(Buffer, Temp, (PUCHAR)&IpAddress, sizeof(IPADDR_ENTRY));
-                Temp += sizeof(IPADDR_ENTRY);
-
-                CurrentIFEntry = CurrentIFEntry->Flink;
-              }
-
-            KeReleaseSpinLock(&InterfaceListLock, OldIrql);
-
-            return TDI_SUCCESS;
-
-          case IP_MIB_STATS_ID:
-            if (BufSize < sizeof(IPSNMP_INFO))
-              {
-                return TDI_BUFFER_TOO_SMALL;
-              }
-
-            RtlZeroMemory(&SnmpInfo, sizeof(IPSNMP_INFO));
-
-	    /* Count number of interfaces */
-	    Count = 0;
-	    KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
-
-	    CurrentIFEntry = InterfaceListHead.Flink;
-	    while (CurrentIFEntry != &InterfaceListHead)
-	      {
-		Count++;
-		CurrentIFEntry = CurrentIFEntry->Flink;
-	      }
-	    
-	    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
-	    
-	    SnmpInfo.NumIf = Count;
-
-            /* Count number of addresses */
-            Count = 0;
-            KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
-
-            CurrentIFEntry = InterfaceListHead.Flink;
-            while (CurrentIFEntry != &InterfaceListHead)
-              {
-	              CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
-                  Count++;
-                  CurrentIFEntry = CurrentIFEntry->Flink;
-              }
-
-            KeReleaseSpinLock(&InterfaceListLock, OldIrql);
-
-            SnmpInfo.NumAddr = Count;
-            Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&SnmpInfo, sizeof(IPSNMP_INFO));
-
-            return TDI_SUCCESS;
-
-          default:
-            /* We can't handle this ID */
-            return TDI_INVALID_PARAMETER;
-        }
+    KeAcquireSpinLock( &EntityListLock, &OldIrql );
+    
+    /* Remove entities that have this interface as context
+     * In the future, this might include AT_ENTITY types, too
+     */
+    for( i = 0; i < EntityCount; i++ ) {
+	if( EntityList[i].context == Interface ) {
+	    if( i != EntityCount-1 ) 
+		memcpy( &EntityList[i], 
+			&EntityList[--EntityCount],
+			sizeof(EntityList[i]) );
+	}
     }
 
-  return TDI_INVALID_PARAMETER;
+    KeReleaseSpinLock( &EntityListLock, OldIrql );
 }
 
 TDI_STATUS InfoTdiQueryListEntities(PNDIS_BUFFER Buffer,
-				    UINT BufSize,
 				    PUINT BufferSize)
 {
-    UINT Count, Size, Temp;
+    UINT Count, Size, BufSize = *BufferSize;
     KIRQL OldIrql;
+    TDIEntityID *EntityOutList;
     PLIST_ENTRY CurrentIFEntry;
 
-    /* Count Adapters */
-    KeAcquireSpinLock(&InterfaceListLock, &OldIrql);
-    
-    CurrentIFEntry = InterfaceListHead.Flink;
-    Count = EntityCount;
+    TI_DbgPrint(MAX_TRACE,("About to copy %d TDIEntityIDs to user\n",
+			   EntityCount));
     
-    while( CurrentIFEntry != &InterfaceListHead ) {
-	Count++;
-	CurrentIFEntry = CurrentIFEntry->Flink;
-    }
-    
-    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
-    
-    Size = Count * sizeof(TDIEntityID);
+    KeAcquireSpinLock(&EntityListLock, &OldIrql);
+
+    Size = EntityCount * sizeof(TDIEntityID);
     *BufferSize = Size;
     
     if (BufSize < Size)
     {
+	KeReleaseSpinLock( &EntityListLock, OldIrql );
 	/* The buffer is too small to contain requested data */
 	return TDI_BUFFER_TOO_SMALL;
     }
-    
-    DbgPrint("About to copy %d TDIEntityIDs (%d bytes) to user\n",
-	     Count, Size);
-    
-    KeAcquireSpinLock(&EntityListLock, &OldIrql);
-    
-    /* Update entity list */
-    for( Temp = EntityCount; Temp < Count; Temp++ ) {
-	EntityList[Temp].tei_entity = IF_ENTITY;
-	EntityList[Temp].tei_instance = Temp - EntityCount;
+        
+    /* Return entity list -- Copy only the TDIEntityID parts. */
+    for( Count = 0; Count < EntityCount; Count++ ) {
+	CopyBufferToBufferChain(Buffer, 
+				Count * sizeof(TDIEntityID), 
+				(PUCHAR)&EntityList[Count], 
+				sizeof(TDIEntityID));
     }
-    EntityMax = Count;
-    
-    /* Return entity list */
-    Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)EntityList, Size);
     
     KeReleaseSpinLock(&EntityListLock, OldIrql);
     
-    *BufferSize = Size;
-
     return TDI_SUCCESS;
 }
 
-TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIObjectID *ID,
-				       PNDIS_BUFFER Buffer,
-				       UINT BufSize,
-				       PUINT BufferSize) {
-    PIFENTRY OutData;
-    UINT ListedIfIndex, Count, Size;
-    PLIST_ENTRY CurrentADEEntry;
-    PADDRESS_ENTRY CurrentADE;
-    PLIST_ENTRY CurrentIFEntry;
-    PIP_INTERFACE CurrentIF;
-    PCHAR IFDescr;
-    KIRQL OldIrql;
-
-    OutData = ExAllocatePool( NonPagedPool, 
-			      sizeof(IFENTRY) + MAX_IFDESCR_LEN );
-
-    if( !OutData ) return STATUS_NO_MEMORY;
-
-    RtlZeroMemory( OutData,sizeof(IFENTRY) + MAX_IFDESCR_LEN );
-
-    KeAcquireSpinLock(&EntityListLock, &OldIrql);
-    ListedIfIndex = ID->toi_entity.tei_instance - EntityCount;
-    if( ListedIfIndex > EntityMax ) {
-	KeReleaseSpinLock(&EntityListLock,OldIrql);
-	return TDI_INVALID_REQUEST;
-    }
-    
-    CurrentIFEntry = InterfaceListHead.Flink;
-    
-    for( Count = 0; Count < ListedIfIndex; Count++ )
-	CurrentIFEntry = CurrentIFEntry->Flink;
-    
-    CurrentIF = CONTAINING_RECORD(CurrentIFEntry, IP_INTERFACE, ListEntry);
-
-    CurrentADEEntry = CurrentIF->ADEListHead.Flink;
-    if( CurrentADEEntry == &CurrentIF->ADEListHead ) {
-	KeReleaseSpinLock( &EntityListLock, OldIrql );
-	return TDI_INVALID_REQUEST;
-    }
-
-    CurrentADE = CONTAINING_RECORD(CurrentADEEntry, ADDRESS_ENTRY, ListEntry);
-    
-    OutData->Index = Count + 1; /* XXX - arty What goes here?? */
-    OutData->Type = CurrentADE->Type;
-    OutData->Mtu = CurrentIF->MTU;
-    OutData->Speed = 10000000; /* XXX - arty Not sure */
-    memcpy(OutData->PhysAddr,
-	   CurrentIF->Address,CurrentIF->AddressLength);
-    OutData->PhysAddrLen = CurrentIF->AddressLength;
-    OutData->AdminStatus = TRUE;
-    OutData->OperStatus = TRUE;
-    IFDescr = (PCHAR)&OutData[1];
-    strcpy(IFDescr,"ethernet adapter");
-    OutData->DescrLen = strlen(IFDescr);
-    IFDescr = IFDescr + strlen(IFDescr);
-    Size = IFDescr - (PCHAR)OutData;
-
-    KeReleaseSpinLock(&InterfaceListLock, OldIrql);
-
-    *BufferSize = Size;
-
-    if( BufSize < Size ) {
-	return TDI_BUFFER_TOO_SMALL;
-    } else {
-	CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&OutData, Size);
-	return TDI_SUCCESS;
-    }
-}
-    
 TDI_STATUS InfoTdiQueryInformationEx(
   PTDI_REQUEST Request,
   TDIObjectID *ID,
@@ -341,170 +130,72 @@
  *   Status of operation
  */
 {
-  PLIST_ENTRY CurrentIFEntry;
-  PLIST_ENTRY CurrentADEEntry;
-  PLIST_ENTRY CurrentADFEntry;
-  PADDRESS_FILE CurrentADF;
-  PADDRESS_ENTRY CurrentADE;
-  PIP_INTERFACE CurrentIF;
-  ADDRESS_INFO Info;
-  KIRQL OldIrql;
-  UINT BufSize;
-  UINT Entity;
-  UINT Offset;
-  ULONG Temp;
-  UINT Count;
-  UINT Size;
-  TDIEntityID EntityId;
-
-  Offset = 0;
-  BufSize = *BufferSize;
-
-  /* Check wether it is a query for a list of entities */
-  Entity = ID->toi_entity.tei_entity;
-  if (Entity == GENERIC_ENTITY)
-    {
-      if ((ID->toi_class  != INFO_CLASS_GENERIC) ||
-          (ID->toi_type != INFO_TYPE_PROVIDER) ||
-          (ID->toi_id != ENTITY_LIST_ID))
-        {
-          return TDI_INVALID_PARAMETER;
-        }
-
-      return InfoTdiQueryListEntities(Buffer, BufSize, BufferSize);
-    }
-
-  /* Get an IFENTRY */
-  if (ID->toi_class == INFO_CLASS_PROTOCOL && 
-      ID->toi_type  == INFO_TYPE_PROVIDER &&
-      ID->toi_id    == IF_MIB_STATS_ID) 
-    {
-      if(ID->toi_entity.tei_entity != IF_ENTITY)
-	return TDI_INVALID_REQUEST;
-
-      return InfoTdiQueryGetInterfaceMIB(ID, Buffer, BufSize, BufferSize);
-    }
-
-    if ((Entity != CL_TL_ENTITY) && (Entity != CO_TL_ENTITY))
-      {
-        /* We can't handle this entity, pass it on */
-        return IPTdiQueryInformationEx(
-          Request, ID, Buffer, BufferSize, Context);
-      }
-
-    /* Make return parameters consistent every time */
-    *BufferSize = 0;
-
-    if (ID->toi_entity.tei_instance != TL_INSTANCE)
-      {
-        /* We only support a single instance */
-        return TDI_INVALID_REQUEST;
-      }
-
-    if (ID->toi_class == INFO_CLASS_GENERIC)
-      {
-        if ((ID->toi_type != INFO_TYPE_PROVIDER) ||
-            (ID->toi_id != ENTITY_TYPE_ID))
-            return TDI_INVALID_PARAMETER;
-
-        if (BufSize < sizeof(ULONG))
-          {
-            return TDI_BUFFER_TOO_SMALL;
-          }
-
-        if (Entity == CL_TL_ENTITY)
-          {
-            Temp = CL_TL_UDP;
-          }
-        else if (Entity == CO_TL_ENTITY)
-          {
-            Temp = CO_TL_TCP;
-          }
+    KIRQL OldIrql;
+    UINT i;
+    PVOID context;
+    NTSTATUS Status = STATUS_SUCCESS;
+    TDIEntityID EntityId;
+    BOOL FoundEntity = FALSE;
+    InfoRequest_f InfoRequest;
+
+    TI_DbgPrint(MAX_TRACE,
+		("InfoEx Req: %x %x %x!%04x:%d\n",
+		 ID->toi_class,
+		 ID->toi_type,
+		 ID->toi_id,
+		 ID->toi_entity.tei_entity,
+		 ID->toi_entity.tei_instance));
+
+    /* Check wether it is a query for a list of entities */
+    if (ID->toi_entity.tei_entity == GENERIC_ENTITY)
+    {
+	if ((ID->toi_class != INFO_CLASS_GENERIC) ||
+	    (ID->toi_type != INFO_TYPE_PROVIDER) ||
+	    (ID->toi_id != ENTITY_LIST_ID))
+	    Status = TDI_INVALID_PARAMETER;
         else
-          {
-            return TDI_INVALID_PARAMETER;
-          }
-
-        Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&Temp, sizeof(ULONG));
-
-        return TDI_SUCCESS;
+	    Status = InfoTdiQueryListEntities(Buffer, BufferSize);
+    } else {
+	KeAcquireSpinLock( &EntityListLock, &OldIrql );
+	
+	for( i = 0; i < EntityCount; i++ ) {
+	    if( EntityList[i].tei_entity == ID->toi_entity.tei_entity &&
+		EntityList[i].tei_instance == ID->toi_entity.tei_instance ) {
+		InfoRequest = EntityList[i].info_req;
+		context = EntityList[i].context;
+		FoundEntity = TRUE;
+		break;
+	    }
+	}
+	
+	KeReleaseSpinLock( &EntityListLock, OldIrql );
+	
+	if( FoundEntity ) {
+	    TI_DbgPrint(MAX_TRACE,
+			("Calling Entity %d (%04x:%d) InfoEx (%x,%x,%x)\n",
+			 i, ID->toi_entity.tei_entity,
+			 ID->toi_entity.tei_instance,
+			 ID->toi_class, ID->toi_type, ID->toi_id));
+	    Status = InfoRequest( ID->toi_class,
+				  ID->toi_type,
+				  ID->toi_id,
+				  context,
+				  &ID->toi_entity,
+				  Buffer,
+				  BufferSize );
+	}
     }
 
-  if (ID->toi_class == INFO_CLASS_PROTOCOL)
-    {
-      if (ID->toi_type != INFO_TYPE_PROVIDER)
-        {
-          return TDI_INVALID_PARAMETER;
-        }
-
-      switch (ID->toi_id)
-        {
-          case UDP_MIB_STAT_ID:
-            if (Entity != CL_TL_ENTITY)
-              {
-                return TDI_INVALID_PARAMETER;
-              }
-
-            if (BufSize < sizeof(UDPStats))
-              {
-                return TDI_BUFFER_TOO_SMALL;
-              }
-
-            Count = CopyBufferToBufferChain(Buffer, 0, (PUCHAR)&UDPStats, sizeof(UDP_STATISTICS));
-
-            return TDI_SUCCESS;
-
-          case UDP_MIB_TABLE_ID:
-            if (Entity != CL_TL_ENTITY)
-            {
-                return TDI_INVALID_PARAMETER;
-            }
-
-            Offset = 0;
-
-            KeAcquireSpinLock(&AddressFileListLock, &OldIrql);
-
-            CurrentADFEntry = AddressFileListHead.Flink;
-            while (CurrentADFEntry != &AddressFileListHead)
-              {
-	              CurrentADF = CONTAINING_RECORD(CurrentADFEntry, ADDRESS_FILE, ListEntry);
-
-                if (Offset + sizeof(ADDRESS_INFO) > BufSize)
-                  {
-                    KeReleaseSpinLock(&AddressFileListLock, OldIrql);
-                    *BufferSize = Offset;
-                    return TDI_BUFFER_OVERFLOW;
-                  }
-
-                Info.LocalAddress = CurrentADF->ADE->Address->Address.IPv4Address;
-                Info.LocalPort = CurrentADF->Port;
-
-                Count = CopyBufferToBufferChain(Buffer, Offset, (PUCHAR)&Info, sizeof(ADDRESS_INFO));
-                Offset += Count;
+    TI_DbgPrint(MAX_TRACE,("Status: %08x\n", Status));
 
-                CurrentADFEntry = CurrentADFEntry->Flink;
-              }
-
-            KeReleaseSpinLock(&AddressFileListLock, OldIrql);
-
-            *BufferSize = Offset;
-
-            return STATUS_SUCCESS;
-
-          default:
-            /* We can't handle this ID */
-            return TDI_INVALID_PARAMETER;
-        }
-    }
-
-    return TDI_INVALID_PARAMETER;
+    return Status;
 }
 
-TDI_STATUS InfoTdiSetInformationEx(
-  PTDI_REQUEST Request,
-  TDIObjectID *ID,
-  PVOID Buffer,
-  UINT BufferSize)
+TDI_STATUS InfoTdiSetInformationEx
+(PTDI_REQUEST Request,
+ TDIObjectID *ID,
+ PVOID Buffer,
+ UINT BufferSize)
 /*
  * FUNCTION: Sets extended information
  * ARGUMENTS:
@@ -516,30 +207,30 @@
  *   Status of operation
  */
 {
-  switch( ID->toi_class ) {
-  case INFO_CLASS_PROTOCOL:
-    switch( ID->toi_type ) {
-    case INFO_TYPE_PROVIDER:
-      switch( ID->toi_id ) {
-      case IP_MIB_ROUTETABLE_ENTRY_ID:
-	if( ID->toi_entity.tei_entity == CL_NL_ENTITY &&
-	    ID->toi_entity.tei_instance == TL_INSTANCE &&
-	    BufferSize >= sizeof(IPROUTE_ENTRY) ) {
-	    /* Add route -- buffer is an IPRouteEntry */
-	    PIPROUTE_ENTRY ire = (PIPROUTE_ENTRY)Buffer;
-	  RouteFriendlyAddRoute( ire );				 
-	} else {
-	    return TDI_INVALID_PARAMETER; 
-	    /* In my experience, we are being over
-	       protective compared to windows */
+    switch( ID->toi_class ) {
+    case INFO_CLASS_PROTOCOL:
+	switch( ID->toi_type ) {
+	case INFO_TYPE_PROVIDER:
+	    switch( ID->toi_id ) {
+	    case IP_MIB_ROUTETABLE_ENTRY_ID:
+		if( ID->toi_entity.tei_entity == CL_NL_ENTITY &&
+		    ID->toi_entity.tei_instance == TL_INSTANCE &&
+		    BufferSize >= sizeof(IPROUTE_ENTRY) ) {
+		    /* Add route -- buffer is an IPRouteEntry */
+		    PIPROUTE_ENTRY ire = (PIPROUTE_ENTRY)Buffer;
+		    RouteFriendlyAddRoute( ire );
+		} else {
+		    return TDI_INVALID_PARAMETER; 
+		    /* In my experience, we are being over
+		       protective compared to windows */
+		}
+		break;
+	    }
+	    break;
 	}
 	break;
-      }
-      break;
     }
-    break;
-  }
-
-  return TDI_INVALID_PARAMETER;
-}
     
+    return TDI_INVALID_PARAMETER;
+}
+

reactos/drivers/net/tcpip/tcpip
main.c 1.23 -> 1.24
diff -u -r1.23 -r1.24
--- main.c	15 May 2004 07:49:05 -0000	1.23
+++ main.c	9 Jun 2004 18:11:38 -0000	1.24
@@ -17,6 +17,8 @@
 #include <udp.h>
 #include <tcp.h>
 #include <rosrtl/string.h>
+#include <info.h>
+#include <memtrack.h>
 
 #define NDEBUG
 
@@ -33,7 +35,7 @@
 NDIS_HANDLE GlobalPacketPool     = NULL;
 NDIS_HANDLE GlobalBufferPool     = NULL;
 KSPIN_LOCK EntityListLock;
-TDIEntityID *EntityList          = NULL;
+TDIEntityInfo *EntityList        = NULL;
 ULONG EntityCount                = 0;
 ULONG EntityMax                  = 0;
 UDP_STATISTICS UDPStats;
@@ -456,18 +458,9 @@
     Status = STATUS_INVALID_DEVICE_REQUEST;
   }
 
-  if (Status != STATUS_PENDING) {
-    IrpSp->Control &= ~SL_PENDING_RETURNED;
-    Irp->IoStatus.Status = Status;
-
-    TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
-
-    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-  }
-
   TI_DbgPrint(DEBUG_IRP, ("Leaving. Status is (0x%X)\n", Status));
 
-  return Status;
+  return IRPFinish( Irp, Status );
 }
 
 
@@ -487,7 +480,7 @@
  *     Status of the operation
  */
 {
-	NTSTATUS Status;
+  NTSTATUS Status;
   PIO_STACK_LOCATION IrpSp;
 
   IrpSp = IoGetCurrentIrpStackLocation(Irp);
@@ -560,17 +553,9 @@
     Status = STATUS_INVALID_DEVICE_REQUEST;
   }
 
-  if (Status != STATUS_PENDING) {
-    Irp->IoStatus.Status = Status;
-
-    TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
-
-    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-  }
-
   TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
 
-	return Status;
+  return IRPFinish( Irp, Status );
 }
 
 
@@ -627,17 +612,9 @@
     }
   }
 
-  if (Status != STATUS_PENDING) {
-    Irp->IoStatus.Status = Status;
-
-    TI_DbgPrint(DEBUG_IRP, ("Completing IRP at (0x%X).\n", Irp));
-
-    IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
-  }
-
   TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
 
-  return Status;
+  return IRPFinish( Irp, Status );
 }
 
 
@@ -726,6 +703,14 @@
   NDIS_STRING DeviceName;
 
   TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+  
+  TrackingInit();
+  TrackTag(NDIS_BUFFER_TAG);
+  TrackTag(NDIS_PACKET_TAG);
+  TrackTag(FBSD_MALLOC);
+  TrackTag(EXALLOC_TAG);
+
+  InitOskitTCP();
 
   /* TdiInitialize() ? */
 
@@ -770,6 +755,28 @@
     return Status;
   }
 
+  /* Setup network layer and transport layer entities */
+  KeInitializeSpinLock(&EntityListLock);
+  EntityList = ExAllocatePool(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES );
+  if (!NT_SUCCESS(Status)) {
+	  TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
+    TiUnload(DriverObject);
+    return STATUS_INSUFFICIENT_RESOURCES;
+  }
+
+  EntityList[0].tei_entity   = CL_NL_ENTITY;
+  EntityList[0].tei_instance = 0;
+  EntityList[0].context      = 0;
+  EntityList[0].info_req     = InfoNetworkLayerTdiQueryEx;
+  EntityList[0].info_set     = InfoNetworkLayerTdiSetEx;
+  EntityList[1].tei_entity   = CL_TL_ENTITY;
+  EntityList[1].tei_instance = 0;
+  EntityList[1].context      = 0;
+  EntityList[1].info_req     = InfoTransportLayerTdiQueryEx;
+  EntityList[1].info_set     = InfoTransportLayerTdiSetEx;
+  EntityCount = 2;
+  EntityMax   = MAX_TDI_ENTITIES;
+
   /* Allocate NDIS packet descriptors */
   NdisAllocatePacketPool(&NdisStatus, &GlobalPacketPool, 100, sizeof(PACKET_CONTEXT));
   if (NdisStatus != NDIS_STATUS_SUCCESS) {
@@ -830,22 +837,6 @@
     return STATUS_INSUFFICIENT_RESOURCES;
   }
 
-  /* Setup network layer and transport layer entities */
-  KeInitializeSpinLock(&EntityListLock);
-  EntityList = ExAllocatePool(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES );
-  if (!NT_SUCCESS(Status)) {
-	  TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-    TiUnload(DriverObject);
-    return STATUS_INSUFFICIENT_RESOURCES;
-  }
-
-  EntityList[0].tei_entity   = CL_NL_ENTITY;
-  EntityList[0].tei_instance = 0;
-  EntityList[1].tei_entity   = CL_TL_ENTITY;
-  EntityList[1].tei_instance = 0;
-  EntityCount = 2;
-  EntityMax   = MAX_TDI_ENTITIES;
-
   /* Use direct I/O */
   IPDeviceObject->Flags    |= DO_DIRECT_IO;
   RawIPDeviceObject->Flags |= DO_DIRECT_IO;

reactos/drivers/net/tcpip/tcpip
pool.c 1.2 -> 1.3
diff -u -r1.2 -r1.3
--- pool.c	2 Aug 2000 00:21:37 -0000	1.2
+++ pool.c	9 Jun 2004 18:11:38 -0000	1.3
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <pool.h>
 

reactos/drivers/net/tcpip/tcpip
routines.c 1.12 -> 1.13
diff -u -r1.12 -r1.13
--- routines.c	11 May 2004 20:52:10 -0000	1.12
+++ routines.c	9 Jun 2004 18:11:38 -0000	1.13
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <routines.h>
 #include <pool.h>
@@ -16,89 +17,6 @@
 static UINT RandomNumber = 0x12345678;
 
 
-inline NTSTATUS BuildDatagramSendRequest(
-    PDATAGRAM_SEND_REQUEST *SendRequest,
-    PIP_ADDRESS RemoteAddress,
-    USHORT RemotePort,
-    PNDIS_BUFFER Buffer,
-    DWORD BufferSize,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    DATAGRAM_BUILD_ROUTINE Build,
-    ULONG Flags)
-/*
- * FUNCTION: Allocates and intializes a datagram send request
- * ARGUMENTS:
- *     SendRequest     = Pointer to datagram send request
- *     RemoteAddress   = Pointer to remote IP address
- *     RemotePort      = Remote port number
- *     Buffer          = Pointer to NDIS buffer to send
- *     BufferSize      = Size of Buffer
- *     Complete        = Completion routine
- *     Context         = Pointer to context information
- *     Build           = Datagram build routine
- *     Flags           = Protocol specific flags
- * RETURNS:
- *     Status of operation
- */
-{
-  PDATAGRAM_SEND_REQUEST Request;
-
-  Request = ExAllocatePool(NonPagedPool, sizeof(DATAGRAM_SEND_REQUEST));
-  if (!Request)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  InitializeDatagramSendRequest(
-    Request,
-    RemoteAddress,
-    RemotePort,
-    Buffer,
-    BufferSize,
-    Complete,
-    Context,
-    Build,
-    Flags);
-
-  *SendRequest = Request;
-
-  return STATUS_SUCCESS;
-}
-
-
-inline NTSTATUS BuildTCPSendRequest(
-    PTCP_SEND_REQUEST *SendRequest,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    PVOID ProtocolContext)
-/*
- * FUNCTION: Allocates and intializes a TCP send request
- * ARGUMENTS:
- *     SendRequest     = Pointer to TCP send request
- *     Complete        = Completion routine
- *     Context         = Pointer to context information
- *     ProtocolContext = Protocol specific context
- * RETURNS:
- *     Status of operation
- */
-{
-  PTCP_SEND_REQUEST Request;
-
-  Request = ExAllocatePool(NonPagedPool, sizeof(TCP_SEND_REQUEST));
-  if (!Request)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  InitializeTCPSendRequest(
-    Request,
-    Complete,
-    Context,
-    ProtocolContext);
-
-  *SendRequest = Request;
-
-  return STATUS_SUCCESS;
-}
-
-
 UINT Random(
     VOID)
 /*
@@ -389,35 +307,6 @@
 }
 
 
-VOID FreeNdisPacket(
-    PNDIS_PACKET Packet)
-/*
- * FUNCTION: Frees an NDIS packet
- * ARGUMENTS:
- *     Packet = Pointer to NDIS packet to be freed
- */
-{
-    PNDIS_BUFFER Buffer, NextBuffer;
-
-    TI_DbgPrint(DEBUG_BUFFER, ("Packet (0x%X)\n", Packet));
-
-    /* Free all the buffers in the packet first */
-    NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
-    for (; Buffer != NULL; Buffer = NextBuffer) {
-        PVOID Data;
-        UINT Length;
-
-        NdisGetNextBuffer(Buffer, &NextBuffer);
-        NdisQueryBuffer(Buffer, &Data, &Length);
-        NdisFreeBuffer(Buffer);
-        ExFreePool(Data);
-    }
-
-    /* Finally free the NDIS packet discriptor */
-    NdisFreePacket(Packet);
-}
-
-
 PVOID AdjustPacket(
     PNDIS_PACKET Packet,
     UINT Available,
@@ -538,32 +427,21 @@
         for (; Buffer != NULL; Buffer = NextBuffer) {
             NdisGetNextBuffer(Buffer, &NextBuffer);
             NdisQueryBuffer(Buffer, (PVOID)&p, &Length);
-
-            for (i = 0; i < Length; i++) {
-                if (i % 16 == 0)
-                    DbgPrint("\n");
-                DbgPrint("%02X ", (p[i]) & 0xFF);
-            }
-            DbgPrint("\n");
+	    OskitDumpBuffer( p, Length );
         }
     } else {
         p      = IPPacket->Header;
         Length = IPPacket->ContigSize;
-        for (i = 0; i < Length; i++) {
-            if (i % 16 == 0)
-                DbgPrint("\n");
-            DbgPrint("%02X ", (p[i]) & 0xFF);
-        }
-        DbgPrint("\n");
+	OskitDumpBuffer( p, Length );
     }
 
     if (IPPacket->NdisPacket) {
         NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
         Length -= MaxLLHeaderSize;
-        CharBuffer = ExAllocatePool(NonPagedPool, Length);
+        CharBuffer = exAllocatePool(NonPagedPool, Length);
         Length = CopyPacketToBuffer(CharBuffer, IPPacket->NdisPacket, MaxLLHeaderSize, Length);
         DisplayIPHeader(CharBuffer, Length);
-        ExFreePool(CharBuffer);
+        exFreePool(CharBuffer);
     } else {
         CharBuffer = IPPacket->Header;
         Length = IPPacket->ContigSize;
@@ -633,10 +511,10 @@
     if (IPPacket->NdisPacket) {
         NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length);
         Length -= MaxLLHeaderSize;
-        Buffer = ExAllocatePool(NonPagedPool, Length);
+        Buffer = exAllocatePool(NonPagedPool, Length);
         Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, MaxLLHeaderSize, Length);
         DisplayTCPHeader(Buffer, Length);
-        ExFreePool(Buffer);
+        exFreePool(Buffer);
     } else {
         Buffer = IPPacket->Header;
         Length = IPPacket->ContigSize;
@@ -644,4 +522,90 @@
     }
 }
 
-#endif /* DBG */
+#endif DBG /* DBG */
+
+void GetDataPtr( PNDIS_PACKET Packet,
+		 UINT Offset, 
+		 PUCHAR *DataOut,
+		 PUINT Size ) {
+    PNDIS_BUFFER Buffer;
+
+    NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
+    if( !Buffer ) return NULL;
+    SkipToOffset( Buffer, Offset, DataOut, Size );
+}
+
+
+#undef NdisAllocatePacket
+#undef NdisAllocateBuffer
+#undef NdisFreeBuffer
+#undef NdisFreePacket
+
+NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket,
+				       PCHAR Data, UINT Len,
+				       PCHAR File, UINT Line ) {
+    PNDIS_PACKET Packet;
+    PNDIS_BUFFER Buffer;
+    NDIS_STATUS Status;
+    PCHAR NewData;
+
+    NewData = ExAllocatePool( NonPagedPool, Len );
+    if( !NewData ) return NDIS_STATUS_NOT_ACCEPTED; // XXX 
+    TrackWithTag(EXALLOC_TAG, NewData, File, Line);
+
+    if( Data ) 
+	RtlCopyMemory(NewData, Data, Len);
+
+    NdisAllocatePacket( &Status, &Packet, GlobalPacketPool );
+    if( Status != NDIS_STATUS_SUCCESS ) {
+	ExFreePool( NewData );
+	return Status;
+    }
+    TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line);
+
+    NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len );
+    if( Status != NDIS_STATUS_SUCCESS ) {
+	ExFreePool( NewData );
+	FreeNdisPacket( Packet );
+    }
+    TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line);
+
+    NdisChainBufferAtFront( Packet, Buffer );
+    *NdisPacket = Packet;
+
+    return NDIS_STATUS_SUCCESS;
+}
+
+
+VOID FreeNdisPacketX
+( PNDIS_PACKET Packet,
+  PCHAR File,
+  UINT Line )
+/*
+ * FUNCTION: Frees an NDIS packet
+ * ARGUMENTS:
+ *     Packet = Pointer to NDIS packet to be freed
+ */
+{
+    PNDIS_BUFFER Buffer, NextBuffer;
+
+    TI_DbgPrint(DEBUG_BUFFER, ("Packet (0x%X)\n", Packet));
+
+    /* Free all the buffers in the packet first */
+    NdisQueryPacket(Packet, NULL, NULL, &Buffer, NULL);
+    for (; Buffer != NULL; Buffer = NextBuffer) {
+        PVOID Data;
+        UINT Length;
+
+        NdisGetNextBuffer(Buffer, &NextBuffer);
+        NdisQueryBuffer(Buffer, &Data, &Length);
+        NdisFreeBuffer(Buffer);
+	UntrackFL(File,Line,Buffer);
+        ExFreePool(Data);
+	UntrackFL(File,Line,Data);
+    }
+
+    /* Finally free the NDIS packet discriptor */
+    NdisFreePacket(Packet);
+    UntrackFL(File,Line,Packet);
+}

reactos/drivers/net/tcpip/transport/datagram
datagram.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- datagram.c	11 May 2004 20:52:10 -0000	1.7
+++ datagram.c	9 Jun 2004 18:11:38 -0000	1.8
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <datagram.h>
 #include <routines.h>
@@ -124,13 +125,6 @@
   CompleteContext = SendRequest->Context;
   BytesSent       = SendRequest->BufferSize;
 
-  /* Remove data buffer before releasing memory for packet buffers */
-  NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
-  NdisUnchainBufferAtBack(Packet, &NdisBuffer);
-  FreeNdisPacket(Packet);
-  DereferenceObject(SendRequest->RemoteAddress);
-  ExFreePool(SendRequest);
-
   /* If there are pending send requests, shedule worker function */
   KeAcquireSpinLock(&DGPendingListLock, &OldIrql);
   QueueWorkItem = (!IsListEmpty(&DGPendingListHead));
@@ -141,7 +135,7 @@
   TI_DbgPrint(MAX_TRACE, ("Calling 0x%X.\n", Complete));
 
   /* Call completion routine for send request */
-  (*Complete)(CompleteContext, NdisStatus, BytesSent);
+  (*Complete)(Context, NdisStatus, BytesSent);
 
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 }
@@ -168,8 +162,6 @@
 
   TI_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-  ASSERT(SendRequest->Build);
-
   /* Get the information we need from the address file
      now so we minimize the time we hold the spin lock */
   KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
@@ -182,71 +174,73 @@
   /* Loop until there are no more send requests in the
      transmit queue or until we run out of resources */
   for (;;)
-    {
-      Status = (*SendRequest->Build)(SendRequest, ADE->Address, LocalPort, &IPPacket);
+  {
+      TI_DbgPrint(MIN_TRACE, ("Looping on DGSend !!!! WHEE!\n"));
       if (!NT_SUCCESS(Status))
-        {
+      {
           KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
           /* An error occurred, enqueue the send request again and return */
           InsertHeadList(&AddrFile->TransmitQueue, &SendRequest->ListEntry);
           DereferenceObject(ADE);
           KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-    
+	  
           TI_DbgPrint(MIN_TRACE, ("Leaving (insufficient resources).\n"));
           return;
-        }
-
+      }
+      
       /* Get a route to the destination address */
-      if (RouteGetRouteToDestination(SendRequest->RemoteAddress, ADE->NTE, &RCN) == IP_SUCCESS)
-        {
+      if (RouteGetRouteToDestination(&SendRequest->RemoteAddress, ADE->NTE, &RCN) == IP_SUCCESS)
+      {
           /* Set completion routine and send the packet */
+	  IPPacket = &SendRequest->Packet;
           PC(IPPacket->NdisPacket)->Complete = SendDatagramComplete;
           PC(IPPacket->NdisPacket)->Context  = SendRequest;
           if (IPSendDatagram(IPPacket, RCN) != STATUS_SUCCESS)
-            {
-              SendDatagramComplete(SendRequest,
-                IPPacket->NdisPacket,
-                NDIS_STATUS_REQUEST_ABORTED);
-            }
+	  {
+	      TI_DbgPrint(MIN_TRACE, ("!! Datagram sent !! (completing)\n"));
+	      SendDatagramComplete(SendRequest,
+				   IPPacket->NdisPacket,
+				   NDIS_STATUS_REQUEST_ABORTED);
+	  }
           /* We're done with the RCN */
           DereferenceObject(RCN);
-        }
+      }
       else
-        {
-          /* No route to destination */
-          /* FIXME: Which error code should we use here? */
-          TI_DbgPrint(MIN_TRACE, ("No route to destination address (0x%X).\n",
-              SendRequest->RemoteAddress->Address.IPv4Address));
-          SendDatagramComplete(SendRequest,
-            IPPacket->NdisPacket,
-            NDIS_STATUS_REQUEST_ABORTED);
-        }
+      {
+	  /* No route to destination */
+	  /* FIXME: Which error code should we use here? */
+	  TI_DbgPrint(MIN_TRACE, 
+		      ("No route to destination address (0x%X).\n",
+		       SendRequest->RemoteAddress.Address.IPv4Address));
+	  SendDatagramComplete(SendRequest,
+			       IPPacket->NdisPacket,
+			       NDIS_STATUS_REQUEST_ABORTED);
+      }
 
-      (*IPPacket->Free)(IPPacket);
-  
       /* Check transmit queue for more to send */
-  
+      
       KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-  
+      
       if (!IsListEmpty(&AddrFile->TransmitQueue))
-        {
+      {
           /* Transmit queue is not empty, process one more request */
           CurrentEntry = RemoveHeadList(&AddrFile->TransmitQueue);
           SendRequest  = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry);
-    
+	  
           KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-        }
+	  TI_DbgPrint(MIN_TRACE, ("List is not empty\n"));
+      }
       else
-        {
+      {
           /* Transmit queue is empty */
           AF_CLR_PENDING(AddrFile, AFF_SEND);
           DereferenceObject(ADE);
           KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-  
+	  
           TI_DbgPrint(MAX_TRACE, ("Leaving (empty queue).\n"));
           return;
-        }
-    }
+      }
+  }
 }
 
 
@@ -346,7 +340,7 @@
             {
               DereferenceObject(Current->RemoteAddress);
             }
-          ExFreePool(Current);
+          exFreePool(Current);
         }
     }
   else if (AddrFile->RegisteredReceiveDatagramHandler)
@@ -431,8 +425,7 @@
     {
       /* Complete the request and free its resources */
       (*Current->Complete)(Current->Context, STATUS_CANCELLED, 0);
-      DereferenceObject(Current->RemoteAddress);
-      ExFreePool(Current);
+      exFreePool(Current);
     }
   else
     {
@@ -489,7 +482,7 @@
         {
           DereferenceObject(Current->RemoteAddress);
         }
-      ExFreePool(Current);
+      exFreePool(Current);
     }
   else
     {
@@ -528,83 +521,80 @@
       KeReleaseSpinLock(&AddressFile->Lock, OldIrql);
       /* Send the datagram */
       DGSend(AddressFile, SendRequest);
-      TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n"));
+      TI_DbgPrint(MAX_TRACE, ("Leaving (pending).\n")); 
     }
   return STATUS_PENDING;
 }
 
-NTSTATUS DGSendDatagram(
-  PTDI_REQUEST Request,
-  PTDI_CONNECTION_INFORMATION ConnInfo,
-  PNDIS_BUFFER Buffer,
-  ULONG DataSize,
-  DATAGRAM_BUILD_ROUTINE Build)
+NTSTATUS DGSendDatagram( PTDI_REQUEST Request,
+			 PTDI_CONNECTION_INFORMATION ConnInfo,
+			 PIP_PACKET Packet ) {
 /*
  * FUNCTION: Sends a datagram to a remote address
  * ARGUMENTS:
  *     Request   = Pointer to TDI request
  *     ConnInfo  = Pointer to connection information
- *     Buffer    = Pointer to NDIS buffer with data
- *     DataSize  = Size in bytes of data to be sent
- *     Build     = Pointer to datagram build routine
+ *     Packet    = Pointer to NDIS buffer with data
  * RETURNS:
  *     Status of operation
  */
-{
-  PADDRESS_FILE AddrFile;
-  KIRQL OldIrql;
-  NTSTATUS Status;
-  PDATAGRAM_SEND_REQUEST SendRequest;
-
-  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
-  AddrFile = Request->Handle.AddressHandle;
-
-  KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
-
-  if (AF_IS_VALID(AddrFile))
+    PADDRESS_FILE AddrFile;
+    KIRQL OldIrql;
+    NTSTATUS Status;
+    PDATAGRAM_SEND_REQUEST SendRequest;
+    
+    TI_DbgPrint(MAX_TRACE, ("Called.\n"));
+    
+    AddrFile = Request->Handle.AddressHandle;
+    
+    KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+    
+    if (AF_IS_VALID(AddrFile)) {
+	/* Initialize a send request */
+	SendRequest = exAllocatePool( NonPagedPool,
+				      sizeof( DATAGRAM_SEND_REQUEST ) );
+	
+	if( SendRequest ) {
+	    KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+	    return STATUS_INSUFFICIENT_RESOURCES;
+	}
+	
+	SendRequest->Complete = Request->RequestNotifyObject;
+	SendRequest->Context = Request->RequestContext;
+	NdisQueryPacketLength( Packet->NdisPacket,
+			       &SendRequest->BufferSize );
+	SendRequest->Packet = *Packet;
+	
+	if (NT_SUCCESS(Status)) {
+	    Status = AddrGetAddress(ConnInfo->RemoteAddress,
+				    &SendRequest->RemoteAddress,
+				    &SendRequest->RemotePort,
+				    &AddrFile->AddrCache);
+	    if (NT_SUCCESS(Status))
+	    {
+		KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+		return DGTransmit(AddrFile, SendRequest);
+	    }
+	    else
+	    {
+		exFreePool(SendRequest);
+	    }
+	}
+	else
+	{
+	    Status = STATUS_INSUFFICIENT_RESOURCES;
+	}
+    }
+    else
     {
-      /* Initialize a send request */
-      Status = BuildDatagramSendRequest(&SendRequest,
-        NULL,
-        0,
-        Buffer,
-        DataSize,
-        Request->RequestNotifyObject,
-        Request->RequestContext,
-        Build,
-        0);
-      if (NT_SUCCESS(Status))
-        {
-          Status = AddrGetAddress(ConnInfo->RemoteAddress,
-            &SendRequest->RemoteAddress,
-            &SendRequest->RemotePort,
-            &AddrFile->AddrCache);
-          if (NT_SUCCESS(Status))
-            {
-              KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-              return DGTransmit(AddrFile, SendRequest);
-            }
-          else
-            {
-              ExFreePool(SendRequest);
-            }
-        }
-      else
-        {
-          Status = STATUS_INSUFFICIENT_RESOURCES;
-        }
+	Status = STATUS_ADDRESS_CLOSED;
     }
-  else
-    {
-      Status = STATUS_ADDRESS_CLOSED;
-    }
-
-  KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
-  TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
-
-  return Status;
+    
+    KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+    
+    TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
+    
+    return Status;
 }
 
 
@@ -645,7 +635,7 @@
 
   if (AF_IS_VALID(AddrFile))
     {
-      ReceiveRequest = ExAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
+      ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST));
       if (ReceiveRequest)
         {
           /* Initialize a receive request */
@@ -660,7 +650,7 @@
               if (!NT_SUCCESS(Status))
                 {
                   KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-                  ExFreePool(ReceiveRequest);
+                  exFreePool(ReceiveRequest);
                   return Status;
                 }
             }

reactos/drivers/net/tcpip/transport/rawip
rawip.c 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- rawip.c	4 Jul 2001 20:40:23 -0000	1.5
+++ rawip.c	9 Jun 2004 18:11:38 -0000	1.6
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <rawip.h>
 #include <routines.h>
@@ -21,8 +22,7 @@
 NTSTATUS BuildRawIPPacket(
     PVOID Context,
     PIP_ADDRESS LocalAddress,
-    USHORT LocalPort,
-    PIP_PACKET *IPPacket)
+    USHORT LocalPort )
 /*
  * FUNCTION: Builds an UDP packet
  * ARGUMENTS:
@@ -35,43 +35,26 @@
  */
 {
     PVOID Header;
-    PIP_PACKET Packet;
     NDIS_STATUS NdisStatus;
     PNDIS_BUFFER HeaderBuffer;
     PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
-
-    TI_DbgPrint(MAX_TRACE, ("TCPIP.SYS: NDIS data buffer is at (0x%X).\n", SendRequest->Buffer));
-    TI_DbgPrint(MAX_TRACE, ("NDIS data buffer Next is at (0x%X).\n", SendRequest->Buffer->Next));
-    TI_DbgPrint(MAX_TRACE, ("NDIS data buffer Size is (0x%X).\n", SendRequest->Buffer->Size));
-    TI_DbgPrint(MAX_TRACE, ("NDIS data buffer MappedSystemVa is (0x%X).\n", SendRequest->Buffer->MappedSystemVa));
-    TI_DbgPrint(MAX_TRACE, ("NDIS data buffer StartVa is (0x%X).\n", SendRequest->Buffer->StartVa));
-    TI_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteCount is (0x%X).\n", SendRequest->Buffer->ByteCount));
-    TI_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", SendRequest->Buffer->ByteOffset));
+    PIP_PACKET Packet = &SendRequest->Packet;
 
     /* Prepare packet */
 
     /* FIXME: Assumes IPv4 */
-    Packet = IPCreatePacket(IP_ADDRESS_V4);
     if (!Packet)
         return STATUS_INSUFFICIENT_RESOURCES;
 
+    IPInitializePacket(Packet,IP_ADDRESS_V4);
     Packet->Flags      = IP_PACKET_FLAG_RAW;    /* Don't touch IP header */
     Packet->TotalSize  = SendRequest->BufferSize;
 
-    /* Allocate NDIS packet */
-    NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
-    if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus))
-        (*Packet->Free)(Packet);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
     if (MaxLLHeaderSize != 0) {
         Header = ExAllocatePool(NonPagedPool, MaxLLHeaderSize);
         if (!Header) {
             TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n"));
-            NdisFreePacket(Packet->NdisPacket);
-            (*Packet->Free)(Packet);
+            FreeNdisPacket(Packet->NdisPacket);
             return STATUS_INSUFFICIENT_RESOURCES;
         }
 
@@ -87,21 +70,15 @@
         if (NdisStatus != NDIS_STATUS_SUCCESS) {
             TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for packet headers. NdisStatus = (0x%X)\n", NdisStatus));
             ExFreePool(Header);
-            NdisFreePacket(Packet->NdisPacket);
-            (*Packet->Free)(Packet);
+            FreeNdisPacket(Packet->NdisPacket);
             return STATUS_INSUFFICIENT_RESOURCES;
         }
         /* Chain header at front of packet */
         NdisChainBufferAtFront(Packet->NdisPacket, HeaderBuffer);
     }
 
-    /* Chain data after link level header if it exists */
-    NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
-
     DISPLAY_IP_PACKET(Packet);
 
-    *IPPacket = Packet;
-
     return STATUS_SUCCESS;
 }
 
@@ -122,8 +99,30 @@
  *     Status of operation
  */
 {
-    return DGSendDatagram(Request, ConnInfo,
-        Buffer, DataSize, BuildRawIPPacket);
+    NDIS_STATUS Status;
+    PCHAR BufferData;
+    UINT BufferLen;
+    PADDRESS_FILE AddrFile = 
+	(PADDRESS_FILE)Request->Handle.AddressHandle;
+    PDATAGRAM_SEND_REQUEST SendRequest;
+
+    SendRequest = ExAllocatePool( NonPagedPool, sizeof(*SendRequest) );
+
+    NdisQueryBuffer( Buffer, &BufferData, &BufferLen );
+    Status = AllocatePacketWithBuffer( &SendRequest->Packet.NdisPacket,
+				       BufferData,
+				       BufferLen );
+    
+    if( Status != NDIS_STATUS_SUCCESS ) {
+	BuildRawIPPacket( SendRequest,
+			  (PIP_ADDRESS)&AddrFile->ADE->Address->Address.
+			  IPv4Address,
+			  AddrFile->Port );
+	Status = DGSendDatagram(Request, ConnInfo, &SendRequest->Packet);
+	NdisFreeBuffer( Buffer );
+    }
+
+    return Status;
 }
 
 

reactos/drivers/net/tcpip/transport/tcp
event.c 1.1 -> 1.2
diff -N event.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ event.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,323 @@
+/*
+ * 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
+ */
+#include <roscfg.h>
+#include <limits.h>
+#include <tcpip.h>
+#include <tcp.h>
+#include <pool.h>
+#include <route.h>
+#include <router.h>
+#include <address.h>
+#include <neighbor.h>
+#include <datagram.h>
+#include <checksum.h>
+#include <routines.h>
+#include <oskittcp.h>
+
+extern ULONG TCP_IPIdentification;
+
+void TCPRecvNotify( PCONNECTION_ENDPOINT Connection, UINT Flags ) {
+    int error = 0;
+    NTSTATUS Status = 0;
+    CHAR DataBuffer[1024];
+    UINT BytesRead = 0, BytesTaken = 0;
+    PTDI_IND_RECEIVE ReceiveHandler;
+    PTDI_IND_DISCONNECT DisconnectHandler;
+    PVOID HandlerContext;
+    SOCKADDR Addr;
+
+    TI_DbgPrint(MID_TRACE,("XX> Called\n"));
+    
+    do { 
+	error = OskitTCPRecv( Connection->SocketContext,
+			      &Addr,
+			      DataBuffer,
+			      1024,
+			      &BytesRead,
+			      Flags | OSK_MSG_DONTWAIT | OSK_MSG_PEEK );
+
+	switch( error ) {
+	case 0:
+	    ReceiveHandler = Connection->AddressFile->ReceiveHandler;
+	    HandlerContext = Connection->AddressFile->ReceiveHandlerContext;
+	    
+	    TI_DbgPrint(MID_TRACE,("Received %d bytes\n", BytesRead));
+	    
+	    if( Connection->AddressFile->RegisteredReceiveHandler ) 
+		Status = ReceiveHandler( HandlerContext,
+					 NULL,
+					 TDI_RECEIVE_NORMAL,
+					 BytesRead,
+					 BytesRead,
+					 &BytesTaken,
+					 DataBuffer,
+					 NULL );
+	    else
+		Status = STATUS_UNSUCCESSFUL;
+	    
+	    if( Status == STATUS_SUCCESS ) {
+		OskitTCPRecv( Connection->SocketContext,
+			      &Addr,
+			      DataBuffer,
+			      BytesTaken,
+			      &BytesRead,
+			      Flags | OSK_MSG_DONTWAIT );
+	    }
+	    break;
+
+	case OSK_ESHUTDOWN:
+	case OSK_ECONNRESET:
+	    DisconnectHandler = Connection->AddressFile->DisconnectHandler;
+	    HandlerContext = Connection->AddressFile->DisconnectHandlerContext;
+	    
+	    if( Connection->AddressFile->RegisteredDisconnectHandler )
+		Status = DisconnectHandler( HandlerContext,
+					    NULL,
+					    0,
+					    NULL,
+					    0,
+					    NULL,
+					    (error == OSK_ESHUTDOWN) ? 
+					    TDI_DISCONNECT_RELEASE :
+					    TDI_DISCONNECT_ABORT );
+	    else
+		Status = STATUS_UNSUCCESSFUL;
+	    break;
+	    
+	default:
+	    assert( 0 );
+	    break;
+	}
+    } while( error == 0 && BytesRead > 0 && BytesTaken > 0 );
+
+    TI_DbgPrint(MID_TRACE,("XX> Leaving\n"));
+}
+
+void TCPCloseNotify( PCONNECTION_ENDPOINT Connection ) {
+    TCPRecvNotify( Connection, 0 );
+}
+
+char *FlagNames[] = { "SEL_CONNECT",
+		      "SEL_FIN",
+		      "SEL_ACCEPT",
+		      "SEL_OOB",
+		      "SEL_READ",
+		      "SEL_WRITE",
+		       0 };
+int FlagValues[]   = { SEL_CONNECT,
+		       SEL_FIN,
+		       SEL_ACCEPT,
+		       SEL_OOB,
+		       SEL_READ,
+		       SEL_WRITE,
+		       0 };
+
+void TCPSocketState( void *ClientData,
+		     void *WhichSocket,
+		     void *WhichConnection,
+		     OSK_UINT Flags,
+		     OSK_UINT SocketState ) {
+    int i;
+    PCONNECTION_ENDPOINT Connection = 
+	(PCONNECTION_ENDPOINT)WhichConnection;
+
+    TI_DbgPrint(MID_TRACE,("TCPSocketState: (socket %x) %x %x\n",
+			   WhichSocket, Flags, SocketState));
+
+    for( i = 0; FlagValues[i]; i++ ) {
+	if( Flags & FlagValues[i] ) 
+	    TI_DbgPrint(MID_TRACE,("Flag %s\n", FlagNames[i]));
+    }
+
+    if( Flags & SEL_CONNECT ) 
+	/* TCPConnectNotify( Connection ); */ ;
+    if( Flags & SEL_FIN )
+	TCPCloseNotify( Connection );
+    if( Flags & SEL_ACCEPT )
+	/* TCPAcceptNotify( Connection ); */ ;
+    if( Flags & SEL_OOB ) 
+	TCPRecvNotify( Connection, MSG_OOB );
+    if( Flags & SEL_WRITE )
+	/* TCPSendNotify( Connection ); */ ;
+    if( Flags & SEL_READ )
+	TCPRecvNotify( Connection, 0 );
+}
+
+void TCPPacketSendComplete( PVOID Context,
+			    NDIS_STATUS NdisStatus,
+			    DWORD BytesSent ) {
+    TI_DbgPrint(MID_TRACE,("called\n"));
+    PDATAGRAM_SEND_REQUEST Send = (PDATAGRAM_SEND_REQUEST)Context;
+    if( Send->Packet.NdisPacket )
+	FreeNdisPacket( Send->Packet.NdisPacket );
+    exFreePool( Send );
+}
+
+NTSTATUS AddHeaderIPv4(
+    PDATAGRAM_SEND_REQUEST SendRequest,
+    PIP_ADDRESS LocalAddress,
+    USHORT LocalPort,
+    PIP_ADDRESS RemoteAddress,
+    USHORT RemotePort) {
+/*
+ * FUNCTION: Adds an IPv4 and TCP header to an IP packet
+ * ARGUMENTS:
+ *     SendRequest      = Pointer to send request
+ *     Connection       = Pointer to connection endpoint
+ *     LocalAddress     = Pointer to our local address
+ *     LocalPort        = The port we send this segment from
+ *     IPPacket         = Pointer to IP packet
+ * RETURNS:
+ *     Status of operation
+ */
+    PIPv4_HEADER IPHeader;
+    PIP_PACKET IPPacket;
+    PVOID Header;
+    NDIS_STATUS NdisStatus;
+    PNDIS_BUFFER HeaderBuffer;
+    PCHAR BufferContent;
+    ULONG BufferSize;
+    ULONG PayloadBufferSize;
+    
+    IPPacket = &SendRequest->Packet;
+
+    BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER);
+    Header     = exAllocatePool(NonPagedPool, BufferSize);
+    if (!Header)
+	return STATUS_INSUFFICIENT_RESOURCES;
+    
+    TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n", BufferSize, Header));
+    
+    NdisQueryPacketLength( IPPacket->NdisPacket, &PayloadBufferSize );
+
+    /* Allocate NDIS buffer for maximum Link level, IP and TCP header */
+    NdisAllocateBuffer(&NdisStatus,
+		       &HeaderBuffer,
+		       GlobalBufferPool,
+		       Header,
+		       BufferSize);
+    if (NdisStatus != NDIS_STATUS_SUCCESS) {
+	exFreePool(Header);
+	TI_DbgPrint(MAX_TRACE, ("Error from NDIS: %08x\n", NdisStatus));
+	return STATUS_INSUFFICIENT_RESOURCES;
+    }
+    
+    /* Chain header at front of NDIS packet */
+    NdisChainBufferAtFront(IPPacket->NdisPacket, HeaderBuffer);
+    IPPacket->HeaderSize = 20;
+    IPPacket->ContigSize = BufferSize;
+    IPPacket->TotalSize  = IPPacket->HeaderSize + PayloadBufferSize;
+    IPPacket->Header     = (PVOID)((ULONG_PTR)Header + MaxLLHeaderSize);
+    IPPacket->Flags      = 0;
+    
+    /* Build IPv4 header */
+    IPHeader = (PIPv4_HEADER)IPPacket->Header;
+    /* Version = 4, Length = 5 DWORDs */
+    IPHeader->VerIHL = 0x45;
+    /* Normal Type-of-Service */
+    IPHeader->Tos = 0;
+    /* Length of header and data */
+    IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
+    /* Identification */
+    IPHeader->Id = WH2N((USHORT)InterlockedIncrement(&TCP_IPIdentification));
+    /* One fragment at offset 0 */
+    IPHeader->FlagsFragOfs = WH2N((USHORT)IPv4_DF_MASK);
+    /* Time-to-Live is 128 */
+    IPHeader->Ttl = 128;
+    /* Transmission Control Protocol */
+    IPHeader->Protocol = IPPROTO_TCP;
+    /* Checksum is 0 (for later calculation of this) */
+    IPHeader->Checksum = 0;
+    /* Source address */
+    IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
+    /* Destination address. FIXME: IPv4 only */
+    IPHeader->DstAddr = RemoteAddress->Address.IPv4Address;
+
+    return STATUS_SUCCESS;
+}
+
+int TCPPacketSend(void *ClientData,
+		  void *WhichSocket, 
+		  void *WhichConnection,
+		  OSK_PCHAR data,
+		  OSK_UINT len ) {
+    PADDRESS_FILE AddrFile;
+    PNDIS_BUFFER NdisPacket;
+    NDIS_STATUS NdisStatus;
+    KIRQL OldIrql;
+    PDATAGRAM_SEND_REQUEST SendRequest;
+    PNEIGHBOR_CACHE_ENTRY NCE = 0;
+    PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)WhichConnection;
+    IP_ADDRESS RemoteAddress, LocalAddress;
+    USHORT RemotePort, LocalPort;
+    PULONG AckNumber = (PULONG)data;
+
+    TI_DbgPrint(MID_TRACE,("TCP OUTPUT:\n"));
+    OskitDumpBuffer( data, len );
+
+    SendRequest = 
+	(PDATAGRAM_SEND_REQUEST)
+	exAllocatePool( NonPagedPool, sizeof( DATAGRAM_SEND_REQUEST ) );
+    /* if( !SendRequest || !Connection ) return OSK_EINVAL; */
+
+    RemoteAddress.Type = LocalAddress.Type = IP_ADDRESS_V4;
+
+    OskitTCPGetAddress( WhichSocket,
+			&LocalAddress.Address.IPv4Address,
+			&LocalPort,
+			&RemoteAddress.Address.IPv4Address,
+			&RemotePort );
+
+    NCE = RouterGetRoute( &RemoteAddress, NULL );
+
+    if( !NCE ) return OSK_EADDRNOTAVAIL;
+
+    GetInterfaceIPv4Address(NCE->Interface, 
+			    ADE_UNICAST, 
+			    &LocalAddress.Address.IPv4Address );
+
+    if( Connection ) 
+	KeAcquireSpinLock( &Connection->Lock, &OldIrql );
+
+    NdisStatus = 
+	AllocatePacketWithBuffer( &SendRequest->PacketToSend, data, len );
+    if (NdisStatus != NDIS_STATUS_SUCCESS) {
+	TI_DbgPrint(MAX_TRACE, ("Error from NDIS: %08x\n", NdisStatus));
+	goto end;
+    }
+
+    SendRequest->Packet.NdisPacket = SendRequest->PacketToSend;
+
+    SendRequest->Complete = TCPPacketSendComplete;
+    SendRequest->Context = Connection;
+    SendRequest->RemoteAddress = RemoteAddress;
+    SendRequest->RemotePort = RemotePort;
+    NdisQueryPacketLength( SendRequest->Packet.NdisPacket,
+			   &SendRequest->BufferSize );
+
+    AddHeaderIPv4( SendRequest, 
+		   &LocalAddress, 
+		   LocalPort,
+		   &RemoteAddress,
+		   RemotePort );
+
+    if( Connection ) 
+	DGTransmit( Connection->AddressFile, SendRequest );
+    else
+	DbgPrint("Transmit called without connection.\n");
+
+end:
+    if( Connection )
+	KeReleaseSpinLock( &Connection->Lock, OldIrql );
+
+    if( !NT_SUCCESS(NdisStatus) ) return OSK_EINVAL;
+    else return 0;
+}
+

reactos/drivers/net/tcpip/transport/tcp
if.c 1.1 -> 1.2
diff -N if.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ if.c	9 Jun 2004 18:11:38 -0000	1.2
@@ -0,0 +1,183 @@
+/*
+ * 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 <roscfg.h>
+#include <limits.h>
+#include <tcpip.h>
+#include <tcp.h>
+#include <pool.h>
+#include <route.h>
+#include <address.h>
+#include <datagram.h>
+#include <checksum.h>
+#include <routines.h>
+#include <neighbor.h>
+#include <oskittcp.h>
+
+#if 0
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <oskit/c/assert.h>
+#include <net/if.h>
+#endif
+
+#include <oskittcp.h>
+
+int if_index = 0;
+struct ifaddr **ifnet_addrs;
+
+int	ifqmaxlen = OSK_IFQ_MAXLEN;
+struct	ifnet *ifnet;
+
+/*
+ * Network interface utility routines.
+ *
+ * Routines with ifa_ifwith* names take sockaddr *'s as
+ * parameters.
+ */
+void
+ifinit()
+{
+}
+
+void
+if_attach(ifp)
+	struct ifnet *ifp;
+{
+    KeBugCheck( 0xface );
+}
+
+struct ifnet *
+ifunit(char *name)
+{
+	return 0;
+}
+
+int ifa_iffind(addr, ifaddr, type)
+	struct sockaddr *addr;
+	struct ifaddr *ifaddr;
+	int type;
+{
+    PNEIGHBOR_CACHE_ENTRY NCE;
+    IP_ADDRESS Destination;
+    NTSTATUS Status;
+    struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
+
+    TI_DbgPrint(MID_TRACE,("called for type %d\n", type));
+
+    if( !addr || !ifaddr ) {
+	TI_DbgPrint(MID_TRACE,("no addr or no ifaddr (%x %x)\n", 
+			       addr, ifaddr));
+	return OSK_EINVAL;
+    }
+
+    Destination.Type = IP_ADDRESS_V4;
+    Destination.Address.IPv4Address = addr_in->sin_addr.s_addr;
+
+    NCE = RouterGetRoute(&Destination, NULL);
+
+    if( !NCE || !NCE->Interface ) {
+	TI_DbgPrint(MID_TRACE,("no neighbor cache or no interface (%x %x)\n",
+			       NCE, NCE->Interface));
+	return OSK_EADDRNOTAVAIL;
+    }
+
+    /* XXX - Point-to-point interfaces not supported yet */
+    memset(&ifaddr->ifa_dstaddr, 0, sizeof( struct sockaddr ) );
+    
+    addr_in->sin_family = PF_INET;
+    addr_in = (struct sockaddr_in *)&ifaddr->ifa_addr;
+    Status = GetInterfaceIPv4Address( NCE->Interface,
+				      type,
+				      &addr_in->sin_addr.s_addr );
+
+    if( !NT_SUCCESS(Status) )
+	addr_in->sin_addr.s_addr = 0;
+    
+    ifaddr->ifa_flags = 0; /* XXX what goes here? */
+    ifaddr->ifa_refcnt = 0; /* Anachronistic */
+    ifaddr->ifa_metric = 1; /* We can get it like in ninfo.c, if we want */
+    ifaddr->ifa_mtu = NCE->Interface->MTU;
+    
+    TI_DbgPrint(MID_TRACE,("status in iffind: %x\n", Status));
+
+    return NT_SUCCESS(Status) ? 0 : OSK_EADDRNOTAVAIL;
+}
+
+/*
+ * Find an interface on a specific network.  If many, choice
+ * is most specific found.
+ */
+int ifa_ifwithnet(addr, ifaddr)
+	struct sockaddr *addr;
+	struct ifaddr *ifaddr;
+{
+    return ifa_iffind(addr, ifaddr, ADE_UNICAST);
+}
+
+/*
+ * Locate the point to point interface with a given destination address.
+ */
+/*ARGSUSED*/
+struct ifaddr *
+ifa_ifwithdstaddr(addr, ifaddr)
+	register struct sockaddr *addr;
+	register struct ifaddr *ifaddr;
+{
+    return ifa_iffind(addr, ifaddr, ADE_POINTOPOINT);
+}
+
+/*
+ * Locate an interface based on a complete address.
+ */
+/*ARGSUSED*/
+int ifa_ifwithaddr(addr, ifaddr)
+    struct sockaddr *addr;
+    struct ifaddr *ifaddr;
+{
+    int error = ifa_ifwithnet( addr, ifaddr );
+    struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
+    struct sockaddr_in *faddr_in = (struct sockaddr_in *)ifaddr->ifa_addr;
+    if( error != 0 ) return error;
+    else return 
+	     (faddr_in->sin_addr.s_addr == addr_in->sin_addr.s_addr) ?
+	     0 : OSK_EADDRNOTAVAIL;
+}
+
+/*
+ * Handle interface watchdog timer routines.  Called
+ * from softclock, we decrement timers (if set) and
+ * call the appropriate interface routine on expiration.
+ */
+void
+if_slowtimo(arg)
+	void *arg;
+{
+#if 0
+	register struct ifnet *ifp;
+	int s = splimp();
+
+	for (ifp = ifnet; ifp; ifp = ifp->if_next) {
+		if (ifp->if_timer == 0 || --ifp->if_timer)
+			continue;
+		if (ifp->if_watchdog)
+			(*ifp->if_watchdog)(ifp->if_unit);
+	}
+	splx(s);
+	timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ);
+#endif
+}

reactos/drivers/net/tcpip/transport/tcp
tcp.c 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- tcp.c	5 Mar 2004 00:48:11 -0000	1.10
+++ tcp.c	9 Jun 2004 18:11:38 -0000	1.11
@@ -7,6 +7,8 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
+#include <limits.h>
 #include <tcpip.h>
 #include <tcp.h>
 #include <pool.h>
@@ -14,1804 +16,236 @@
 #include <datagram.h>
 #include <checksum.h>
 #include <routines.h>
+#include <oskittcp.h>
 
-
+LONG TCP_IPIdentification = 0;
 static BOOLEAN TCPInitialized = FALSE;
-static LONG IPIdentification = 0;
 static NPAGED_LOOKASIDE_LIST TCPSegmentList;
 
-
-PTCP_SEGMENT TCPCreateSegment(
-  PIP_PACKET IPPacket,
-  ULONG SequenceNumber,
-  ULONG SegmentLength)
-/*
- * FUNCTION: Creates a TCP segment object
- * ARGUMENTS:
- *     IPPacket       = Pointer to IP packet containing segment data
- *     SequenceNumber = Sequence number of first byte in the segment
- *     SegmentLength  = Number of bytes in the segment
- * RETURNS:
- *     Pointer to the created TCP segment. NULL if there was not enough free resources.
- */
-{
-  PTCP_SEGMENT Segment;
-
-  ASSERT(IPPacket);
-
-  Segment = ExAllocateFromNPagedLookasideList(&TCPSegmentList);
-  if (Segment == NULL)
-    return NULL;
-
-  Segment->IPPacket = IPPacket;
-  Segment->SequenceNumber = SequenceNumber;
-  Segment->Length = SegmentLength;
-
-  TI_DbgPrint(DEBUG_TCP, ("Created TCP segment (SequenceNumber %d, Length %d)\n",
-    Segment->SequenceNumber, Segment->Length));
-
-  return Segment;
-}
-
-
-VOID TCPFreeSegment(
-  PTCP_SEGMENT Segment)
-/*
- * FUNCTION: Frees a TCP segment object
- * ARGUMENTS:
- *     Segment = Pointer to an TCP segment structure
- */
-{
-  ASSERT(Segment);
-
-  ExFreeToNPagedLookasideList(&TCPSegmentList, Segment);
-}
-
-
-VOID TCPAddSegment(
-  PCONNECTION_ENDPOINT Connection,
-  PTCP_SEGMENT Segment)
+VOID TCPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
 /*
- * FUNCTION: Adds a TCP segment object to the receive queue of a connection
- * ARGUMENTS:
- *     Connection = Pointer to connection endpoint
- *     Segment    = Pointer to TCP segment object
- * RETURNS:
- *     Nothing.
- */
-{
-  PLIST_ENTRY CurrentEntry;
-  PLIST_ENTRY NextEntry;
-  PTCP_SEGMENT Current;
-
-  ASSERT(Connection);
-  ASSERT(Segment);
-
-  /* FIXME: Handle sequence number wraparound */
-
-  /* If all segments arrive in-order then all segments will be put last in the
-     receive queue when they arrive */
-
-  if (IsListEmpty(&Connection->ReceivedSegments))
-    {
-      /* This is the first segment received since the connection was created
-         or since all data is delivered to the client */
-      InsertTailList(&Connection->ReceivedSegments, &Segment->ListEntry);
-      return;
-    }
-
-  CurrentEntry = Connection->ReceivedSegments.Blink;
-  Current = CONTAINING_RECORD(CurrentEntry, TCP_SEGMENT, ListEntry);
-  if (Segment->SequenceNumber >= Current->SequenceNumber)
-    {
-      /* This segment has the highest sequence number yet received since the
-         connection was created */
-      InsertTailList(&Connection->ReceivedSegments, &Segment->ListEntry);
-      return;
-    }
-
-
-  TI_DbgPrint(MIN_TRACE, ("FIXME: Cannot handle segments that arrive out-of-order.\n"));
-
-#if 0
-  do
-    {
-      if (SequenceNumber + Length...)
-        {
-        }
-
-      CurrentEntry = CurrentEntry->Blink;
-      Current = CONTAINING_RECORD(CurrentEntry, TCP_SEGMENT, ListEntry);
-    }
-  while (CurrentEntry != &Connection->ReceivedSegments);
-#endif
-}
-
-
-NTSTATUS TCPiAddHeaderIPv4(
-  PDATAGRAM_SEND_REQUEST SendRequest,
-  PCONNECTION_ENDPOINT Connection,
-  PIP_ADDRESS LocalAddress,
-  USHORT LocalPort,
-  PIP_PACKET IPPacket,
-  PTCPv4_HEADER *pTcpHeader,
-  PULONG pTcpHeaderLength)
-/*
- * FUNCTION: Adds an IPv4 and TCP header to an IP packet
- * ARGUMENTS:
- *     SendRequest      = Pointer to send request
- *     Connection       = Pointer to connection endpoint
- *     LocalAddress     = Pointer to our local address
- *     LocalPort        = The port we send this segment from
- *     IPPacket         = Pointer to IP packet
- *     TcpHeader        = Address of pointer to TCPv4 header (out)
- *     pTcpHeaderLength = Address of buffer for length of TCP header
- * RETURNS:
- *     Status of operation
- */
-{
-  PIPv4_HEADER IPHeader;
-  PTCPv4_HEADER TCPHeader;
-  PVOID Header;
-	ULONG BufferSize;
-  NDIS_STATUS NdisStatus;
-  PNDIS_BUFFER HeaderBuffer;
-  PTCP_SEND_REQUEST TcpSendRequest = (PTCP_SEND_REQUEST)SendRequest->Context;
-
-  ASSERT(SendRequest);
-  ASSERT(Connection);
-  ASSERT(LocalAddress);
-  ASSERT(IPPacket);
-  ASSERT(pTcpHeader);
-
-	BufferSize = MaxLLHeaderSize + sizeof(IPv4_HEADER) + sizeof(TCPv4_HEADER);
-  Header     = ExAllocatePool(NonPagedPool, BufferSize);
-  if (!Header)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n", BufferSize, Header));
-
-  /* Allocate NDIS buffer for maximum Link level, IP and TCP header */
-  NdisAllocateBuffer(&NdisStatus,
-                     &HeaderBuffer,
-                     GlobalBufferPool,
-                     Header,
-                     BufferSize);
-  if (NdisStatus != NDIS_STATUS_SUCCESS) {
-    ExFreePool(Header);
-    return STATUS_INSUFFICIENT_RESOURCES;
-  }
-
-  /* Chain header at front of NDIS packet */
-  NdisChainBufferAtFront(IPPacket->NdisPacket, HeaderBuffer);
-
-  IPPacket->ContigSize = BufferSize;
-  IPPacket->Header     = (PVOID)((ULONG_PTR)Header + MaxLLHeaderSize);
-  IPPacket->HeaderSize = 20;
-
-  /* Build IPv4 header */
-  IPHeader = (PIPv4_HEADER)IPPacket->Header;
-  /* Version = 4, Length = 5 DWORDs */
-  IPHeader->VerIHL = 0x45;
-  /* Normal Type-of-Service */
-  IPHeader->Tos = 0;
-  /* Length of header and data */
-  IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
-  /* Identification */
-  IPHeader->Id = WH2N((USHORT)InterlockedIncrement(&IPIdentification));
-  /* One fragment at offset 0 */
-  IPHeader->FlagsFragOfs = 0;
-  /* Time-to-Live is 128 */
-  IPHeader->Ttl = 128;
-  /* Transmission Control Protocol */
-  IPHeader->Protocol = IPPROTO_TCP;
-  /* Checksum is 0 (for later calculation of this) */
-  IPHeader->Checksum = 0;
-  /* Source address */
-  IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
-  /* Destination address. FIXME: IPv4 only */
-  IPHeader->DstAddr = SendRequest->RemoteAddress->Address.IPv4Address;
-
-  /* Build TCP header */
-  TCPHeader = (PTCPv4_HEADER)((ULONG_PTR)IPHeader + sizeof(IPv4_HEADER));
-  /* Port values are already big-endian values */
-  TCPHeader->SourcePort      = LocalPort;
-  TCPHeader->DestinationPort = SendRequest->RemotePort;
-  /* TcpSendRequest->SequenceNumber is already a big-endian value */
-  TCPHeader->SequenceNumber  = TcpSendRequest->SequenceNumber;
-  /* TcpSendRequest->AckNumber is already a big-endian value */
-  TCPHeader->AckNumber       = ((SendRequest->Flags & SRF_ACK) > 0) ? TcpSendRequest->AckNumber : 0;
-  TCPHeader->DataOffset      = (sizeof(TCPv4_HEADER) / 4) << 4;
-  TCPHeader->Flags           = SendRequest->Flags;
-  TCPHeader->Window          = 0;
-  /* FIXME: Calculate TCP checksum and put it in TCP header */
-  TCPHeader->Checksum        = 0;
-  TCPHeader->Urgent          = 0;
-
-  *pTcpHeader = TCPHeader;
-  *pTcpHeaderLength = sizeof(TCPv4_HEADER);
-
-  return STATUS_SUCCESS;
-}
-
-
-NTSTATUS TCPiBuildPacket(
-  PVOID Context,
-  PIP_ADDRESS LocalAddress,
-  USHORT LocalPort,
-  PIP_PACKET *IPPacket)
-/*
- * FUNCTION: Builds a TCP packet
+ * FUNCTION: Receives and queues TCP data
  * ARGUMENTS:
- *     Context      = Pointer to context information (DATAGRAM_SEND_REQUEST)
- *     LocalAddress = Pointer to our local address
- *     LocalPort    = The port we send this segment from
- *     IPPacket     = Address of pointer to IP packet
- * RETURNS:
- *     Status of operation
+ *     NTE      = Pointer to net table entry which the packet was received on
+ *     IPPacket = Pointer to an IP packet that was received
  * NOTES:
- *     The Context field in the send request structure (pointed to
- *     by the Context field) contains a pointer to the CONNECTION_ENDPOINT
- *     structure for the connection
- */
-{
-  NTSTATUS Status;
-  PIP_PACKET Packet;
-  NDIS_STATUS NdisStatus;
-  PDATAGRAM_SEND_REQUEST SendRequest;
-  PCONNECTION_ENDPOINT Connection;
-  ULONG Checksum;
-  TCPv4_PSEUDO_HEADER TcpPseudoHeader;
-  PTCPv4_HEADER TcpHeader;
-  ULONG TcpHeaderLength;
-
-  ASSERT(LocalAddress);
-  ASSERT(IPPacket);
-
-  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
-  SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
-  ASSERT(SendRequest);
-  Connection = (PCONNECTION_ENDPOINT)SendRequest->Context;
-  ASSERT(Connection);
-
-  /* Prepare packet */
-
-  /* FIXME: Assumes IPv4 */
-  Packet = IPCreatePacket(IP_ADDRESS_V4);
-  if (Packet == NULL)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  Packet->TotalSize = sizeof(IPv4_HEADER) +
-                      sizeof(TCPv4_HEADER)  +
-                      SendRequest->BufferSize;
-
-  /* Allocate NDIS packet */
-  NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
-  if (NdisStatus != NDIS_STATUS_SUCCESS) {
-    (*Packet->Free)(Packet);
-    return STATUS_INSUFFICIENT_RESOURCES;
-  }
-
-  switch (SendRequest->RemoteAddress->Type) {
-  case IP_ADDRESS_V4:
-    Status = TCPiAddHeaderIPv4(SendRequest, Connection, LocalAddress,
-      LocalPort, Packet, &TcpHeader, &TcpHeaderLength);
-    break;
-  case IP_ADDRESS_V6:
-    /* FIXME: Support IPv6 */
-    TI_DbgPrint(MIN_TRACE, ("IPv6 TCP segments are not supported.\n"));
-  default:
-    Status = STATUS_UNSUCCESSFUL;
-    break;
-  }
-  if (!NT_SUCCESS(Status)) {
-    TI_DbgPrint(MIN_TRACE, ("Cannot add TCP header. Status (0x%X)\n", Status));
-    NdisFreePacket(Packet->NdisPacket);
-    (*Packet->Free)(Packet);
-    return Status;
-  }
-
-  /* Build pseudo TCP header which is used to prevent misrouted segments */
-  TcpPseudoHeader.SourceAddress = LocalAddress->Address.IPv4Address;
-  TcpPseudoHeader.DestinationAddress = SendRequest->RemoteAddress->Address.IPv4Address;
-  TcpPseudoHeader.Zero = 0;
-  TcpPseudoHeader.Protocol = IPPROTO_TCP;
-  /* Length of TCP header and segment data */
-  TcpPseudoHeader.TCPLength = WH2N(TcpHeaderLength + SendRequest->BufferSize);
-  Checksum = TCPv4Checksum((PUCHAR)&TcpPseudoHeader, sizeof(TCPv4_PSEUDO_HEADER), 0);
-
-  /* Add checksum for TCP header */
-  Checksum = TCPv4Checksum((PUCHAR)TcpHeader, TcpHeaderLength, ~Checksum);
-
-  /* Chain data after header if it exists */
-  if (SendRequest->Buffer != NULL)
-    {
-      PVOID Data;
-      UINT Size;
-      /*
-       * NOTE:
-       * Don't name the variable NdisBuffer, because that's internal name
-       * used by the NdisChainBufferAtBack macro and it's the easiest way
-       * how to achieve an elegant crash.
-       */
-      PNDIS_BUFFER _NdisBuffer = SendRequest->Buffer;
-      NdisChainBufferAtBack(Packet->NdisPacket, _NdisBuffer);
-      /* Add checksum for segment data */
-      /* FIXME: Verify that there is no problem for chained buffers with an odd length */
-      while (_NdisBuffer != NULL)
-        {
-          NdisQueryBuffer(_NdisBuffer, &Data, &Size);
-          DbgPrint("Checksum7:(%d bytes)\n", Size);
-          Checksum = TCPv4Checksum(Data, Size, ~Checksum);
-          NdisGetNextBuffer(_NdisBuffer, &_NdisBuffer);
-        }
-    }
-
-  TcpHeader->Checksum = Checksum;
-  DbgPrint("Checksum8: (0x%x)\n", Checksum);
-
-  DISPLAY_TCP_PACKET(Packet);
-
-  *IPPacket = Packet;
-
-  return STATUS_SUCCESS;
-}
-
-
-VOID TCPiSendRequestComplete(
-  PVOID Context,
-  NDIS_STATUS Status,
-  ULONG Count)
-/*
- * FUNCTION: Completion routine for datagram send requests
- * ARGUMENTS:
- *     Context = Pointer to context information (TCP_SEND_REQUEST)
- *     Status  = Status of the request
- *     Count   = Number of bytes sent or received
+ *     This is the low level interface for receiving TCP data
  */
 {
-  DATAGRAM_COMPLETION_ROUTINE Complete;
-  PVOID CompleteContext;
-  PTCP_SEND_REQUEST SendRequest = (PTCP_SEND_REQUEST)Context;
-
-  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
-  Complete        = SendRequest->Complete;
-  CompleteContext = SendRequest->Context;
-  ExFreePool(SendRequest);
-
-  if (Complete != NULL)
-    {
-      TI_DbgPrint(MAX_TRACE, ("Calling completion routine.\n"));
+    PCHAR BufferData = exAllocatePool( NonPagedPool, IPPacket->TotalSize );
 
-      /* Call upper level completion routine */
-      (*Complete)(CompleteContext, Status, Count);
+    if( BufferData ) {
+	TI_DbgPrint(MID_TRACE,("Sending packet %d (%d) to oskit\n", 
+			       IPPacket->TotalSize,
+			       IPPacket->HeaderSize));
+
+	memcpy( BufferData, IPPacket->Header, IPPacket->HeaderSize );
+	memcpy( BufferData + IPPacket->HeaderSize, IPPacket->Data,
+		IPPacket->TotalSize - IPPacket->HeaderSize );
+	
+	OskitTCPReceiveDatagram( BufferData, 
+				 IPPacket->TotalSize, 
+				 IPPacket->HeaderSize );
+
+	exFreePool( BufferData );
     }
-
-  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 }
 
+/* event.c */
+void TCPSocketState( void *ClientData,
+		     void *WhichSocket,
+		     void *WhichConnection,
+		     OSK_UINT SelFlags,
+		     OSK_UINT SocketState );
+
+int TCPPacketSend( void *ClientData,
+		   void *WhichSocket,
+		   void *WhichConnection,
+		   OSK_PCHAR Data,
+		   OSK_UINT Len );
+
+OSKITTCP_EVENT_HANDLERS EventHandlers = {
+    NULL, /* Client Data */
+    TCPSocketState, /* SocketState */
+    TCPPacketSend, /* PacketSend */
+};
 
-VOID TCPTimeout(VOID)
+NTSTATUS TCPStartup(VOID)
 /*
- * FUNCTION: Transmission Control Protocol timeout handler
- * NOTES:
- *     This routine is called by IPTimeout to perform several
- *     maintainance tasks
- */
-{
-}
-
-
-inline NTSTATUS TCPBuildSendRequest(
-    PTCP_SEND_REQUEST *SendRequest,
-    PDATAGRAM_SEND_REQUEST *DGSendRequest,
-    PCONNECTION_ENDPOINT Connection,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    PNDIS_BUFFER Buffer,
-    DWORD BufferSize,
-    ULONG Flags)
-/*
- * FUNCTION: Allocates and intializes a TCP send request
- * ARGUMENTS:
- *     SendRequest   = TCP send request
- *     DGSendRequest = Datagram send request (optional)
- *     Connection    = Connection endpoint
- *     Complete      = Completion routine
- *     Context       = Pointer to context information
- *     Buffer        = Pointer to NDIS buffer to send (optional)
- *     BufferSize    = Size of Buffer
- *     Flags         = Protocol specific flags
+ * FUNCTION: Initializes the TCP subsystem
  * RETURNS:
  *     Status of operation
  */
 {
-  PDATAGRAM_SEND_REQUEST DGSendReq;
-  NTSTATUS Status;
-
-  ASSERT(SendRequest);
-  ASSERT(Connection);
-
-  Status = BuildTCPSendRequest(
-    SendRequest,
-    Complete,
-    Context,
-    NULL);
-  if (!NT_SUCCESS(Status))
-    return Status;
-
-  Status = BuildDatagramSendRequest(
-    &DGSendReq,                   /* Datagram send request */
-    Connection->RemoteAddress,    /* Address of remote peer */
-    Connection->RemotePort,       /* Port of remote peer */
-    Buffer,                       /* Buffer */
-    BufferSize,                   /* Size of buffer */
-    (DATAGRAM_COMPLETION_ROUTINE)
-      TCPiSendRequestComplete,    /* Completion function */
-    *SendRequest,                 /* Context for completion function */
-    TCPiBuildPacket,              /* Packet build function */
-    Flags);                       /* Protocol specific flags */
-  if (!NT_SUCCESS(Status)) {
-    ExFreePool(*SendRequest);
-    return Status;
-  }
-
-  if (DGSendRequest)
-    *DGSendRequest = DGSendReq;
-
-  return STATUS_SUCCESS;
+    InitOskitTCP();
+    RegisterOskitTCPEventHandlers( &EventHandlers );
+    
+    /* 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 */
+	TAG('T','C','P','S'),           /* Tag */
+	0);                             /* Depth */
+    
+    TCPInitialized = TRUE;
+    
+    return STATUS_SUCCESS;
 }
 
 
-inline NTSTATUS TCPBuildAndTransmitSendRequest(
-    PCONNECTION_ENDPOINT Connection,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    PNDIS_BUFFER Buffer,
-    DWORD BufferSize,
-    ULONG Flags)
+NTSTATUS TCPShutdown(VOID)
 /*
- * FUNCTION: Allocates and intializes a TCP send request
- * ARGUMENTS:
- *     Connection    = Connection endpoint
- *     Complete      = Completion routine (optional)
- *     Context       = Pointer to context information
- *     Buffer        = Pointer to NDIS buffer to send (optional)
- *     BufferSize    = Size of Buffer
- *     Flags         = Protocol specific flags
+ * FUNCTION: Shuts down the TCP subsystem
  * RETURNS:
  *     Status of operation
  */
 {
-  PDATAGRAM_SEND_REQUEST DGSendRequest;
-  PTCP_SEND_REQUEST TCPSendRequest;
-  NTSTATUS Status;
-
-  ASSERT(Connection);
-
-  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
-  Status = TCPBuildSendRequest(
-    &TCPSendRequest,
-    &DGSendRequest,
-    Connection,                   /* Connection endpoint */
-    Complete,                     /* Completion routine */
-    Context,                      /* Completion routine context */
-    Buffer,                       /* Buffer */
-    BufferSize,                   /* Size of buffer */
-    Flags);                       /* Protocol specific flags */
-  if (!NT_SUCCESS(Status))
-    return Status;
+    if (!TCPInitialized)
+	return STATUS_SUCCESS;
+    
+    /* Deregister this protocol with IP layer */
+    IPRegisterProtocol(IPPROTO_TCP, NULL);
+    
+    ExDeleteNPagedLookasideList(&TCPSegmentList);
+    
+    TCPInitialized = FALSE;
 
-  Status = DGTransmit(
-    Connection->AddressFile,
-    DGSendRequest);
-  if (!NT_SUCCESS(Status)) {
-    ExFreePool(DGSendRequest);
-    ExFreePool(TCPSendRequest);
-    return Status;
-  }
-
-  return STATUS_SUCCESS;
+    DeinitOskitTCP();
+    
+    return STATUS_SUCCESS;
 }
 
+NTSTATUS TCPTranslateError( int OskitError ) {
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
 
-inline NTSTATUS TCPBuildAndTransmitSendRequest2(
-    PCONNECTION_ENDPOINT Connection,
-    DATAGRAM_COMPLETION_ROUTINE Complete,
-    PVOID Context,
-    PNDIS_BUFFER Buffer,
-    DWORD BufferSize,
-    ULONG Flags,
-    ULONG SequenceNumber,
-    ULONG AckNumber)
-/*
- * FUNCTION: Allocates and intializes a TCP send request
- * ARGUMENTS:
- *     Connection     = Connection endpoint
- *     Complete       = Completion routine (optional)
- *     Context        = Pointer to context information
- *     Buffer         = Pointer to NDIS buffer to send
- *     BufferSize     = Size of Buffer
- *     Flags          = Protocol specific flags
- *     SequenceNumber = Sequence number (host byte order)
- *     AckNumber      = Acknowledgement number (host byte order)
- * RETURNS:
- *     Status of operation
- */
-{
-  PDATAGRAM_SEND_REQUEST DGSendRequest;
-  PTCP_SEND_REQUEST TCPSendRequest;
-  NTSTATUS Status;
-
-  ASSERT(Connection);
-
-  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
-  Status = TCPBuildSendRequest(
-    &TCPSendRequest,
-    &DGSendRequest,
-    Connection,                   /* Connection endpoint */
-    Complete,                     /* Completion routine */
-    Context,                      /* Completion routine context */
-    Buffer,                       /* Buffer */
-    BufferSize,                   /* Size of buffer */
-    Flags);                       /* Protocol specific flags */
-  if (!NT_SUCCESS(Status))
-    return Status;
+    switch( OskitError ) {
+    case 0: Status = STATUS_SUCCESS; break;
+	/*case OAK_EADDRNOTAVAIL: */
+    case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break;
+    case OSK_ECONNREFUSED:
+    case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break;
+    default: Status = STATUS_INVALID_CONNECTION; break;
+    }
 
-  /* Set extra information and convert to network byte order if necessary */
-  TCPSendRequest->SequenceNumber = DH2N(SequenceNumber);
-  TCPSendRequest->AckNumber = DH2N(AckNumber);
-
-  Status = DGTransmit(
-    Connection->AddressFile,
-    DGSendRequest);
-  if (!NT_SUCCESS(Status)) {
-    ExFreePool(DGSendRequest);
-    ExFreePool(TCPSendRequest);
+    TI_DbgPrint(MID_TRACE,("Error %d -> %x\n", OskitError, Status));
     return Status;
-  }
-
-  return STATUS_SUCCESS;
 }
 
-
-NTSTATUS TCPConnect(
-  PTDI_REQUEST Request,
+NTSTATUS TCPConnect
+( PTDI_REQUEST Request,
   PTDI_CONNECTION_INFORMATION ConnInfo,
-  PTDI_CONNECTION_INFORMATION ReturnInfo)
-/*
- * FUNCTION: Attempts to connect to a remote peer
- * ARGUMENTS:
- *     Request    = Pointer to TDI request
- *     ConnInfo   = Pointer to connection information
- *     ReturnInfo = Pointer to structure for return information (optional)
- * RETURNS:
- *     Status of operation
- * NOTES:
- *     This is the high level interface for connecting to remote peers
- */
-{
-  PDATAGRAM_SEND_REQUEST DGSendRequest;
-  PTCP_SEND_REQUEST TCPSendRequest;
-  PCONNECTION_ENDPOINT Connection;
-  LARGE_INTEGER DueTime;
-  NTSTATUS Status;
-  KIRQL OldIrql;
-  PNDIS_BUFFER NdisBuffer;
-  NDIS_STATUS NdisStatus;
-  PVOID DataBuffer;
-  ULONG Size;
-
-  ASSERT(Request);
-  ASSERT(ConnInfo);
-
-  TI_DbgPrint(MID_TRACE, ("Called.\n"));
-
-  Connection = Request->Handle.ConnectionContext;
-
-  KeAcquireSpinLock(&Connection->Lock, &OldIrql);
-
-  if (Connection->State != ctClosed) {
-    /* The connection has already been opened so return success */
+  PTDI_CONNECTION_INFORMATION ReturnInfo ) {
+    KIRQL OldIrql;
+    NTSTATUS Status;
+    SOCKADDR_IN AddressToConnect;
+    PCONNECTION_ENDPOINT Connection;
+
+    Connection = Request->Handle.ConnectionContext;
+
+    KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+    
+    PIP_ADDRESS RemoteAddress;
+    USHORT RemotePort;
+
+    Status = AddrBuildAddress(
+	(PTA_ADDRESS)(&((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress)->
+		      Address[0]),
+	&RemoteAddress,
+	&RemotePort);
+
+    if (!NT_SUCCESS(Status)) {
+	TI_DbgPrint(MID_TRACE, ("Could not AddrBuildAddress in TCPConnect\n"));
+	KeReleaseSpinLock(&Connection->Lock, OldIrql);
+	return Status;
+    }
+    
+    AddressToConnect.sin_family = AF_INET;
+
+    memcpy( &AddressToConnect.sin_addr, 
+	    &RemoteAddress->Address.IPv4Address,
+	    sizeof(AddressToConnect.sin_addr) );
+    AddressToConnect.sin_port = RemotePort;
     KeReleaseSpinLock(&Connection->Lock, OldIrql);
-    return STATUS_SUCCESS;
-  }
-
-  Connection->LocalAddress = Connection->AddressFile->ADE->Address;
-  Connection->LocalPort    = Connection->AddressFile->Port;
-
-  Status = AddrBuildAddress(
-    (PTA_ADDRESS)(&((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress)->Address[0]),
-    &Connection->RemoteAddress,
-    &Connection->RemotePort);
-  if (!NT_SUCCESS(Status)) {
-    KeReleaseSpinLock(&Connection->Lock, OldIrql);
-    return Status;
-  }
 
-  /* Allocate NDIS buffer */
-
-  Size = sizeof(IPv4_HEADER);
-  DataBuffer = ExAllocatePool(NonPagedPool, Size);
-  if (!DataBuffer) {
-    return STATUS_INSUFFICIENT_RESOURCES;
-  }
-
-  NdisAllocateBuffer(&NdisStatus, &NdisBuffer, GlobalBufferPool,
-    DataBuffer, Size);
-  if (NdisStatus != NDIS_STATUS_SUCCESS) {
-    KeReleaseSpinLock(&Connection->Lock, OldIrql);
-    ExFreePool(Connection->RemoteAddress);
-    return NdisStatus;
-  }
-
-  /* Issue SYN segment */
-
-  Status = TCPBuildAndTransmitSendRequest(
-    Connection,                   /* Connection endpoint */
-    Request->RequestNotifyObject, /* Completion routine */
-    Request->RequestContext,      /* Completion routine context */
-    NdisBuffer,                   /* Buffer */
-    0,                            /* Size of buffer */
-    SRF_SYN);                     /* Protocol specific flags */
-  if (!NT_SUCCESS(Status)) {
-    KeReleaseSpinLock(&Connection->Lock, OldIrql);
-    ExFreePool(Connection->RemoteAddress);
-    return Status;
-  }
-
-  KeReleaseSpinLock(&Connection->Lock, OldIrql);
-
-  Status = STATUS_PENDING;
-
-  TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
-
-  return Status;
+    return TCPTranslateError( OskitTCPConnect(Connection->SocketContext,
+					      Connection,
+					      &AddressToConnect, 
+					      sizeof(AddressToConnect)) );
 }
 
+NTSTATUS TCPClose
+( PTDI_REQUEST Request ) {
+    PCONNECTION_ENDPOINT Connection;
 
-NTSTATUS TCPListen(
-  PTDI_REQUEST Request,
-  PTDI_CONNECTION_INFORMATION ConnInfo,
-  PTDI_CONNECTION_INFORMATION ReturnInfo)
-/*
- * FUNCTION: Start listening for a connection from a remote peer
- * ARGUMENTS:
- *     Request    = Pointer to TDI request
- *     ConnInfo   = Pointer to connection information
- *     ReturnInfo = Pointer to structure for return information (optional)
- * RETURNS:
- *     Status of operation
- * NOTES:
- *     This is the high level interface for listening for connections from remote peers
- */
-{
-  PDATAGRAM_SEND_REQUEST DGSendRequest;
-  PTCP_SEND_REQUEST TCPSendRequest;
-  PCONNECTION_ENDPOINT Connection;
-  LARGE_INTEGER DueTime;
-  NTSTATUS Status;
-  KIRQL OldIrql;
-
-  ASSERT(Request);
-  ASSERT(ConnInfo);
-
-  TI_DbgPrint(MID_TRACE, ("Called.\n"));
-
-  Connection = Request->Handle.ConnectionContext;
-
-  KeAcquireSpinLock(&Connection->Lock, &OldIrql);
-
-  if (Connection->State != ctClosed) {
-    /* The connection has already been opened so return unsuccessful */
-    KeReleaseSpinLock(&Connection->Lock, OldIrql);
-    return STATUS_UNSUCCESSFUL;
-  }
-
-  Connection->LocalAddress  = Connection->AddressFile->ADE->Address;
-  Connection->LocalPort     = Connection->AddressFile->Port;
-  Connection->ListenRequest = Request;
-
-  TI_DbgPrint(MIN_TRACE, ("Connection->LocalAddress (%s).\n", A2S(Connection->LocalAddress)));
-  TI_DbgPrint(MIN_TRACE, ("Connection->LocalPort (%d).\n", Connection->LocalPort));
-
-  /* Start listening for connection requests */
-  Connection->State = ctListen;
-
-  KeReleaseSpinLock(&Connection->Lock, OldIrql);
-
-  Status = STATUS_PENDING;
-
-  TI_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X)\n", Status));
-
-  return Status;
-}
-
-
-NTSTATUS TCPSendDatagram(
-  PTDI_REQUEST Request,
-  PTDI_CONNECTION_INFORMATION ConnInfo,
-  PNDIS_BUFFER Buffer,
-  ULONG DataSize)
-/*
- * FUNCTION: Sends TCP data to a remote address
- * ARGUMENTS:
- *     Request   = Pointer to TDI request
- *     ConnInfo  = Pointer to connection information
- *     Buffer    = Pointer to NDIS buffer with data
- *     DataSize  = Size in bytes of data to be sent
- * RETURNS:
- *     Status of operation
- */
-{
-  ASSERT(Request);
-  ASSERT(ConnInfo);
-  ASSERT(Buffer);
-
-  return STATUS_SUCCESS;
-}
-
-
-static inline ULONG TCPiSelectISS(
-  PCONNECTION_ENDPOINT Connection)
-{
-  ASSERT(Connection);
-
-  TI_DbgPrint(MIN_TRACE, ("Select ISS.\n"));
-  return 0x10000;
-}
-
-
-static inline VOID TCPiReceiveListen(
-  PADDRESS_FILE AddrFile,
-  PIP_PACKET IPPacket,
-  PTCPv4_HEADER TCPHeader)
-{
-  ASSERT(AddrFile);
-  ASSERT(IPPacket);
-  ASSERT(TCPHeader);
-
-  /* FIXME: Protect AddrFile->Connection */
-
-  if ((TCPHeader->Flags & TCP_RST) > 0)
-    {
-      /* Discard */
-      TI_DbgPrint(DEBUG_TCP, ("Discard.\n"));
-      return;
-    }
-
-  if ((TCPHeader->Flags & TCP_ACK) > 0)
-    {
-      /* FIXME: Send RST (if no RST)
-          <SEQ=SEG.ACK><CTL=RST> */
-      TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
-      return;
-    }
-
-  if ((TCPHeader->Flags & TCP_SYN) > 0)
-    {
-      PCONNECTION_ENDPOINT Connection = AddrFile->Connection;
-      register UCHAR DelayedControls;
-      register NTSTATUS Status;
-
-      /* FIXME: If the SEG.PRC is greater than the TCB.PRC then if allowed by
-          the user and the system set TCB.PRC<-SEG.PRC, if not allowed
-          send a reset and return. */
-      if (FALSE)
-        {
-          /* FIXME: Send RST (if no RST)
-            * <SEQ=SEG.ACK><CTL=RST>
-            */
-          TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
-          return;
-        }
-
-      /* Set RCV.NXT to SEG.SEQ+1, IRS is set to SEG.SEQ and any other
-        control or text should be queued for processing later.  ISS
-        should be selected and a SYN segment sent of the form:
-
-          <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>
-
-        SND.NXT is set to ISS+1 and SND.UNA to ISS.  The connection
-        state should be changed to SYN-RECEIVED.  Note that any other
-        incoming control or data (combined with SYN) will be processed
-        in the SYN-RECEIVED state, but processing of SYN and ACK should
-        not be repeated.  If the listen was not fully specified (i.e.,
-        the foreign socket was not fully specified), then the
-        unspecified fields should be filled in now.
-      */
-      TI_DbgPrint(DEBUG_TCP, ("Go to ctSynReceived connection state.\n"));
-
-      Connection->RemotePort = TCPHeader->SourcePort;
-      /* FIXME: IPv4 only */
-      Connection->RemoteAddress = AddrCloneAddress(&IPPacket->SrcAddr);
-      if (Connection->RemoteAddress == NULL)
-        {
-          /* FIXME: Send RST (if no RST)
-           * <SEQ=SEG.ACK><CTL=RST>
-           */
-          TI_DbgPrint(MIN_TRACE, ("FIXME: Send RST.\n"));
-          return;
-        }
-
-      Connection->ReceiveNext = DN2H(TCPHeader->SequenceNumber) + 1;
-      Connection->ReceiveIRS = DN2H(TCPHeader->SequenceNumber);
-      Connection->State = ctSynReceived;
-
-      Connection->SendISS = TCPiSelectISS(Connection);
-      Connection->SendNext = Connection->SendISS + 1;
-      Connection->SendUnacknowledged = Connection->SendISS;
-
-      DelayedControls = TCPHeader->Flags & (~(TCP_SYN | TCP_ACK));
-      if (DelayedControls > 0)
-        {
-          TI_DbgPrint(MIN_TRACE, ("FIXME: Queue controls (0x%x) for later processing.\n", DelayedControls));
-        }
-
-        TI_DbgPrint(MIN_TRACE, ("IPPacket->HeaderSize: %d\n", IPPacket->HeaderSize));
-        TI_DbgPrint(MIN_TRACE, ("TCPHeader->DataOffset: %d\n", TCPHeader->DataOffset));
-        TI_DbgPrint(MIN_TRACE, ("IPPacket->TotalSize: %d\n", IPPacket->TotalSize));
-
-      if (IPPacket->HeaderSize + (TCPHeader->DataOffset & 0x0F) > IPPacket->TotalSize)
-        {
-          TI_DbgPrint(MIN_TRACE, ("FIXME: Queue segment data (%d bytes) for later processing.\n",
-            (IPPacket->HeaderSize + (TCPHeader->DataOffset & 0x0F)) - IPPacket->TotalSize));
-        }
-
-      /* Issue SYN/ACK segment */
-      Status = TCPBuildAndTransmitSendRequest2(
-        Connection,               /* Connection endpoint */
-        NULL,                     /* Completion routine */
-        NULL,                     /* Completion routine context */
-        NULL,                     /* Buffer */
-        0,                        /* Size of buffer */
-        SRF_SYN | SRF_ACK,        /* Protocol specific flags */
-        Connection->SendISS,      /* Sequence number */
-        Connection->ReceiveNext); /* Acknowledgement number */
-      if (!NT_SUCCESS(Status))
[truncated at 1000 lines; 996 more skipped]

reactos/drivers/net/tcpip/transport/tcp
tcp_input.c removed after 1.1
diff -N tcp_input.c
--- tcp_input.c	15 Jan 2003 21:57:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,4184 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS TCP/IP protocol driver
- * FILE:        transport/tcp/tcp_input.c
- * PURPOSE:     Transmission Control Protocol
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- *   CSH 15-01-2003 Imported from linux kernel 2.4.20
- */
-
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		Implementation of the Transmission Control Protocol(TCP).
- *
- * Version:	$Id: tcp_input.c,v 1.1 2003/01/15 21:57:31 chorns Exp $
- *
- * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
- *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Mark Evans, <evansmp@uhura.aston.ac.uk>
- *		Corey Minyard <wf-rch!minyard@relay.EU.net>
- *		Florian La Roche, <flla@stud.uni-sb.de>
- *		Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
- *		Linus Torvalds, <torvalds@cs.helsinki.fi>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
- *		Matthew Dillon, <dillon@apollo.west.oic.com>
- *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
- *		Jorge Cwik, <jorge@laser.satlink.net>
- */
-
-/*
- * Changes:
- *		Pedro Roque	:	Fast Retransmit/Recovery.
- *					Two receive queues.
- *					Retransmit queue handled by TCP.
- *					Better retransmit timer handling.
- *					New congestion avoidance.
- *					Header prediction.
- *					Variable renaming.
- *
- *		Eric		:	Fast Retransmit.
- *		Randy Scott	:	MSS option defines.
- *		Eric Schenk	:	Fixes to slow start algorithm.
- *		Eric Schenk	:	Yet another double ACK bug.
- *		Eric Schenk	:	Delayed ACK bug fixes.
- *		Eric Schenk	:	Floyd style fast retrans war avoidance.
- *		David S. Miller	:	Don't allow zero congestion window.
- *		Eric Schenk	:	Fix retransmitter so that it sends
- *					next packet on ack of previous packet.
- *		Andi Kleen	:	Moved open_request checking here
- *					and process RSTs for open_requests.
- *		Andi Kleen	:	Better prune_queue, and other fixes.
- *		Andrey Savochkin:	Fix RTT measurements in the presnce of
- *					timestamps.
- *		Andrey Savochkin:	Check sequence numbers correctly when
- *					removing SACKs due to in sequence incoming
- *					data segments.
- *		Andi Kleen:		Make sure we never ack data there is not
- *					enough room for. Also make this condition
- *					a fatal error if it might still happen.
- *		Andi Kleen:		Add tcp_measure_rcv_mss to make 
- *					connections with MSS<min(MTU,ann. MSS)
- *					work without delayed acks. 
- *		Andi Kleen:		Process packets with PSH set in the
- *					fast path.
- *		J Hadi Salim:		ECN support
- *	 	Andrei Gurtov,
- *		Pasi Sarolahti,
- *		Panu Kuhlberg:		Experimental audit of TCP (re)transmission
- *					engine. Lots of bugs are found.
- */
-
-#if 0
-#include <linux/config.h>
-#include <linux/mm.h>
-#include <linux/sysctl.h>
-#include <net/tcp.h>
-#include <net/inet_common.h>
-#include <linux/ipsec.h>
-#else
-#include "linux.h"
-#include "tcpcore.h"
-#endif
-
-int sysctl_tcp_timestamps = 1;
-int sysctl_tcp_window_scaling = 1;
-int sysctl_tcp_sack = 1;
-int sysctl_tcp_fack = 1;
-int sysctl_tcp_reordering = TCP_FASTRETRANS_THRESH;
-#ifdef CONFIG_INET_ECN
-int sysctl_tcp_ecn = 1;
-#else
-int sysctl_tcp_ecn = 0;
-#endif
-int sysctl_tcp_dsack = 1;
-int sysctl_tcp_app_win = 31;
-int sysctl_tcp_adv_win_scale = 2;
-
-int sysctl_tcp_stdurg = 0;
-int sysctl_tcp_rfc1337 = 0;
-//int sysctl_tcp_max_orphans = NR_FILE;
-
-#define FLAG_DATA		0x01 /* Incoming frame contained data.		*/
-#define FLAG_WIN_UPDATE		0x02 /* Incoming ACK was a window update.	*/
-#define FLAG_DATA_ACKED		0x04 /* This ACK acknowledged new data.		*/
-#define FLAG_RETRANS_DATA_ACKED	0x08 /* "" "" some of which was retransmitted.	*/
-#define FLAG_SYN_ACKED		0x10 /* This ACK acknowledged SYN.		*/
-#define FLAG_DATA_SACKED	0x20 /* New SACK.				*/
-#define FLAG_ECE		0x40 /* ECE in this ACK				*/
-#define FLAG_DATA_LOST		0x80 /* SACK detected data lossage.		*/
-#define FLAG_SLOWPATH		0x100 /* Do not skip RFC checks for window update.*/
-
-#define FLAG_ACKED		(FLAG_DATA_ACKED|FLAG_SYN_ACKED)
-#define FLAG_NOT_DUP		(FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED)
-#define FLAG_CA_ALERT		(FLAG_DATA_SACKED|FLAG_ECE)
-#define FLAG_FORWARD_PROGRESS	(FLAG_ACKED|FLAG_DATA_SACKED)
-
-#define IsReno(tp) ((tp)->sack_ok == 0)
-#define IsFack(tp) ((tp)->sack_ok & 2)
-#define IsDSack(tp) ((tp)->sack_ok & 4)
-
-#define TCP_REMNANT (TCP_FLAG_FIN|TCP_FLAG_URG|TCP_FLAG_SYN|TCP_FLAG_PSH)
-
-/* Adapt the MSS value used to make delayed ack decision to the 
- * real world.
- */ 
-static __inline__ void tcp_measure_rcv_mss(struct tcp_opt *tp, struct sk_buff *skb)
-{
-#if 0
-	unsigned int len, lss;
-
-	lss = tp->ack.last_seg_size; 
-	tp->ack.last_seg_size = 0; 
-
-	/* skb->len may jitter because of SACKs, even if peer
-	 * sends good full-sized frames.
-	 */
-	len = skb->len;
-	if (len >= tp->ack.rcv_mss) {
-		tp->ack.rcv_mss = len;
-	} else {
-		/* Otherwise, we make more careful check taking into account,
-		 * that SACKs block is variable.
-		 *
-		 * "len" is invariant segment length, including TCP header.
-		 */
-		len += skb->data - skb->h.raw;
-		if (len >= TCP_MIN_RCVMSS + sizeof(struct tcphdr) ||
-		    /* If PSH is not set, packet should be
-		     * full sized, provided peer TCP is not badly broken.
-		     * This observation (if it is correct 8)) allows
-		     * to handle super-low mtu links fairly.
-		     */
-		    (len >= TCP_MIN_MSS + sizeof(struct tcphdr) &&
-		     !(tcp_flag_word(skb->h.th)&TCP_REMNANT))) {
-			/* Subtract also invariant (if peer is RFC compliant),
-			 * tcp header plus fixed timestamp option length.
-			 * Resulting "len" is MSS free of SACK jitter.
-			 */
-			len -= tp->tcp_header_len;
-			tp->ack.last_seg_size = len;
-			if (len == lss) {
-				tp->ack.rcv_mss = len;
-				return;
-			}
-		}
-		tp->ack.pending |= TCP_ACK_PUSHED;
-	}
-#endif
-}
-
-static void tcp_incr_quickack(struct tcp_opt *tp)
-{
-#if 0
-	unsigned quickacks = tp->rcv_wnd/(2*tp->ack.rcv_mss);
-
-	if (quickacks==0)
-		quickacks=2;
-	if (quickacks > tp->ack.quick)
-		tp->ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
-#endif
-}
-
-void tcp_enter_quickack_mode(struct tcp_opt *tp)
-{
-#if 0
-	tcp_incr_quickack(tp);
-	tp->ack.pingpong = 0;
-	tp->ack.ato = TCP_ATO_MIN;
-#endif
-}
-
-/* Send ACKs quickly, if "quick" count is not exhausted
- * and the session is not interactive.
- */
-
-static __inline__ int tcp_in_quickack_mode(struct tcp_opt *tp)
-{
-#if 0
-	return (tp->ack.quick && !tp->ack.pingpong);
-#else
-  return 0;
-#endif
-}
-
-/* Buffer size and advertised window tuning.
- *
- * 1. Tuning sk->sndbuf, when connection enters established state.
- */
-
-static void tcp_fixup_sndbuf(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	int sndmem = tp->mss_clamp+MAX_TCP_HEADER+16+sizeof(struct sk_buff);
-
-	if (sk->sndbuf < 3*sndmem)
-		sk->sndbuf = min(3*sndmem, sysctl_tcp_wmem[2]);
-#endif
-}
-
-/* 2. Tuning advertised window (window_clamp, rcv_ssthresh)
- *
- * All tcp_full_space() is split to two parts: "network" buffer, allocated
- * forward and advertised in receiver window (tp->rcv_wnd) and
- * "application buffer", required to isolate scheduling/application
- * latencies from network.
- * window_clamp is maximal advertised window. It can be less than
- * tcp_full_space(), in this case tcp_full_space() - window_clamp
- * is reserved for "application" buffer. The less window_clamp is
- * the smoother our behaviour from viewpoint of network, but the lower
- * throughput and the higher sensitivity of the connection to losses. 8)
- *
- * rcv_ssthresh is more strict window_clamp used at "slow start"
- * phase to predict further behaviour of this connection.
- * It is used for two goals:
- * - to enforce header prediction at sender, even when application
- *   requires some significant "application buffer". It is check #1.
- * - to prevent pruning of receive queue because of misprediction
- *   of receiver window. Check #2.
- *
- * The scheme does not work when sender sends good segments opening
- * window and then starts to feed us spagetti. But it should work
- * in common situations. Otherwise, we have to rely on queue collapsing.
- */
-
-/* Slow part of check#2. */
-static int
-__tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
-{
-#if 0
-	/* Optimize this! */
-	int truesize = tcp_win_from_space(skb->truesize)/2;
-	int window = tcp_full_space(sk)/2;
-
-	while (tp->rcv_ssthresh <= window) {
-		if (truesize <= skb->len)
-			return 2*tp->ack.rcv_mss;
-
-		truesize >>= 1;
-		window >>= 1;
-	}
-	return 0;
-#else
-  return 0;
-#endif
-}
-
-static __inline__ void
-tcp_grow_window(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
-{
-#if 0
-	/* Check #1 */
-	if (tp->rcv_ssthresh < tp->window_clamp &&
-	    (int)tp->rcv_ssthresh < tcp_space(sk) &&
-	    !tcp_memory_pressure) {
-		int incr;
-
-		/* Check #2. Increase window, if skb with such overhead
-		 * will fit to rcvbuf in future.
-		 */
-		if (tcp_win_from_space(skb->truesize) <= skb->len)
-			incr = 2*tp->advmss;
-		else
-			incr = __tcp_grow_window(sk, tp, skb);
-
-		if (incr) {
-			tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, tp->window_clamp);
-			tp->ack.quick |= 1;
-		}
-	}
-#endif
-}
-
-/* 3. Tuning rcvbuf, when connection enters established state. */
-
-static void tcp_fixup_rcvbuf(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	int rcvmem = tp->advmss+MAX_TCP_HEADER+16+sizeof(struct sk_buff);
-
-	/* Try to select rcvbuf so that 4 mss-sized segments
-	 * will fit to window and correspoding skbs will fit to our rcvbuf.
-	 * (was 3; 4 is minimum to allow fast retransmit to work.)
-	 */
-	while (tcp_win_from_space(rcvmem) < tp->advmss)
-		rcvmem += 128;
-	if (sk->rcvbuf < 4*rcvmem)
-		sk->rcvbuf = min(4*rcvmem, sysctl_tcp_rmem[2]);
-#endif
-}
-
-/* 4. Try to fixup all. It is made iimediately after connection enters
- *    established state.
- */
-static void tcp_init_buffer_space(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	int maxwin;
-
-	if (!(sk->userlocks&SOCK_RCVBUF_LOCK))
-		tcp_fixup_rcvbuf(sk);
-	if (!(sk->userlocks&SOCK_SNDBUF_LOCK))
-		tcp_fixup_sndbuf(sk);
-
-	maxwin = tcp_full_space(sk);
-
-	if (tp->window_clamp >= maxwin) {
-		tp->window_clamp = maxwin;
-
-		if (sysctl_tcp_app_win && maxwin>4*tp->advmss)
-			tp->window_clamp = max(maxwin-(maxwin>>sysctl_tcp_app_win), 4*tp->advmss);
-	}
-
-	/* Force reservation of one segment. */
-	if (sysctl_tcp_app_win &&
-	    tp->window_clamp > 2*tp->advmss &&
-	    tp->window_clamp + tp->advmss > maxwin)
-		tp->window_clamp = max(2*tp->advmss, maxwin-tp->advmss);
-
-	tp->rcv_ssthresh = min(tp->rcv_ssthresh, tp->window_clamp);
-	tp->snd_cwnd_stamp = tcp_time_stamp;
-#endif
-}
-
-/* 5. Recalculate window clamp after socket hit its memory bounds. */
-static void tcp_clamp_window(struct sock *sk, struct tcp_opt *tp)
-{
-#if 0
-	struct sk_buff *skb;
-	unsigned int app_win = tp->rcv_nxt - tp->copied_seq;
-	int ofo_win = 0;
-
-	tp->ack.quick = 0;
-
-	skb_queue_walk(&tp->out_of_order_queue, skb) {
-		ofo_win += skb->len;
-	}
-
-	/* If overcommit is due to out of order segments,
-	 * do not clamp window. Try to expand rcvbuf instead.
-	 */
-	if (ofo_win) {
-		if (sk->rcvbuf < sysctl_tcp_rmem[2] &&
-		    !(sk->userlocks&SOCK_RCVBUF_LOCK) &&
-		    !tcp_memory_pressure &&
-		    atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0])
-			sk->rcvbuf = min(atomic_read(&sk->rmem_alloc), sysctl_tcp_rmem[2]);
-	}
-	if (atomic_read(&sk->rmem_alloc) > sk->rcvbuf) {
-		app_win += ofo_win;
-		if (atomic_read(&sk->rmem_alloc) >= 2*sk->rcvbuf)
-			app_win >>= 1;
-		if (app_win > tp->ack.rcv_mss)
-			app_win -= tp->ack.rcv_mss;
-		app_win = max(app_win, 2U*tp->advmss);
-
-		if (!ofo_win)
-			tp->window_clamp = min(tp->window_clamp, app_win);
-		tp->rcv_ssthresh = min(tp->window_clamp, 2U*tp->advmss);
-	}
-#endif
-}
-
-/* There is something which you must keep in mind when you analyze the
- * behavior of the tp->ato delayed ack timeout interval.  When a
- * connection starts up, we want to ack as quickly as possible.  The
- * problem is that "good" TCP's do slow start at the beginning of data
- * transmission.  The means that until we send the first few ACK's the
- * sender will sit on his end and only queue most of his data, because
- * he can only send snd_cwnd unacked packets at any given time.  For
- * each ACK we send, he increments snd_cwnd and transmits more of his
- * queue.  -DaveM
- */
-static void tcp_event_data_recv(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
-{
-#if 0
-	u32 now;
-
-	tcp_schedule_ack(tp);
-
-	tcp_measure_rcv_mss(tp, skb);
-
-	now = tcp_time_stamp;
-
-	if (!tp->ack.ato) {
-		/* The _first_ data packet received, initialize
-		 * delayed ACK engine.
-		 */
-		tcp_incr_quickack(tp);
-		tp->ack.ato = TCP_ATO_MIN;
-	} else {
-		int m = now - tp->ack.lrcvtime;
-
-		if (m <= TCP_ATO_MIN/2) {
-			/* The fastest case is the first. */
-			tp->ack.ato = (tp->ack.ato>>1) + TCP_ATO_MIN/2;
-		} else if (m < tp->ack.ato) {
-			tp->ack.ato = (tp->ack.ato>>1) + m;
-			if (tp->ack.ato > tp->rto)
-				tp->ack.ato = tp->rto;
-		} else if (m > tp->rto) {
-			/* Too long gap. Apparently sender falled to
-			 * restart window, so that we send ACKs quickly.
-			 */
-			tcp_incr_quickack(tp);
-			tcp_mem_reclaim(sk);
-		}
-	}
-	tp->ack.lrcvtime = now;
-
-	TCP_ECN_check_ce(tp, skb);
-
-	if (skb->len >= 128)
-		tcp_grow_window(sk, tp, skb);
-#endif
-}
-
-/* Called to compute a smoothed rtt estimate. The data fed to this
- * routine either comes from timestamps, or from segments that were
- * known _not_ to have been retransmitted [see Karn/Partridge
- * Proceedings SIGCOMM 87]. The algorithm is from the SIGCOMM 88
- * piece by Van Jacobson.
- * NOTE: the next three routines used to be one big routine.
- * To save cycles in the RFC 1323 implementation it was better to break
- * it up into three procedures. -- erics
- */
-static __inline__ void tcp_rtt_estimator(struct tcp_opt *tp, __u32 mrtt)
-{
-#if 0
-	long m = mrtt; /* RTT */
-
-	/*	The following amusing code comes from Jacobson's
-	 *	article in SIGCOMM '88.  Note that rtt and mdev
-	 *	are scaled versions of rtt and mean deviation.
-	 *	This is designed to be as fast as possible 
-	 *	m stands for "measurement".
-	 *
-	 *	On a 1990 paper the rto value is changed to:
-	 *	RTO = rtt + 4 * mdev
-	 *
-	 * Funny. This algorithm seems to be very broken.
-	 * These formulae increase RTO, when it should be decreased, increase
-	 * too slowly, when it should be incresed fastly, decrease too fastly
-	 * etc. I guess in BSD RTO takes ONE value, so that it is absolutely
-	 * does not matter how to _calculate_ it. Seems, it was trap
-	 * that VJ failed to avoid. 8)
-	 */
-	if(m == 0)
-		m = 1;
-	if (tp->srtt != 0) {
-		m -= (tp->srtt >> 3);	/* m is now error in rtt est */
-		tp->srtt += m;		/* rtt = 7/8 rtt + 1/8 new */
-		if (m < 0) {
-			m = -m;		/* m is now abs(error) */
-			m -= (tp->mdev >> 2);   /* similar update on mdev */
-			/* This is similar to one of Eifel findings.
-			 * Eifel blocks mdev updates when rtt decreases.
-			 * This solution is a bit different: we use finer gain
-			 * for mdev in this case (alpha*beta).
-			 * Like Eifel it also prevents growth of rto,
-			 * but also it limits too fast rto decreases,
-			 * happening in pure Eifel.
-			 */
-			if (m > 0)
-				m >>= 3;
-		} else {
-			m -= (tp->mdev >> 2);   /* similar update on mdev */
-		}
-		tp->mdev += m;	    	/* mdev = 3/4 mdev + 1/4 new */
-		if (tp->mdev > tp->mdev_max) {
-			tp->mdev_max = tp->mdev;
-			if (tp->mdev_max > tp->rttvar)
-				tp->rttvar = tp->mdev_max;
-		}
-		if (after(tp->snd_una, tp->rtt_seq)) {
-			if (tp->mdev_max < tp->rttvar)
-				tp->rttvar -= (tp->rttvar-tp->mdev_max)>>2;
-			tp->rtt_seq = tp->snd_nxt;
-			tp->mdev_max = TCP_RTO_MIN;
-		}
-	} else {
-		/* no previous measure. */
-		tp->srtt = m<<3;	/* take the measured time to be rtt */
-		tp->mdev = m<<1;	/* make sure rto = 3*rtt */
-		tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN);
-		tp->rtt_seq = tp->snd_nxt;
-	}
-#endif
-}
-
-/* Calculate rto without backoff.  This is the second half of Van Jacobson's
- * routine referred to above.
- */
-static __inline__ void tcp_set_rto(struct tcp_opt *tp)
-{
-#if 0
-	/* Old crap is replaced with new one. 8)
-	 *
-	 * More seriously:
-	 * 1. If rtt variance happened to be less 50msec, it is hallucination.
-	 *    It cannot be less due to utterly erratic ACK generation made
-	 *    at least by solaris and freebsd. "Erratic ACKs" has _nothing_
-	 *    to do with delayed acks, because at cwnd>2 true delack timeout
-	 *    is invisible. Actually, Linux-2.4 also generates erratic
-	 *    ACKs in some curcumstances.
-	 */
-	tp->rto = (tp->srtt >> 3) + tp->rttvar;
-
-	/* 2. Fixups made earlier cannot be right.
-	 *    If we do not estimate RTO correctly without them,
-	 *    all the algo is pure shit and should be replaced
-	 *    with correct one. It is exaclty, which we pretend to do.
-	 */
-#endif
-}
-
-/* NOTE: clamping at TCP_RTO_MIN is not required, current algo
- * guarantees that rto is higher.
- */
-static __inline__ void tcp_bound_rto(struct tcp_opt *tp)
-{
-#if 0
-	if (tp->rto > TCP_RTO_MAX)
-		tp->rto = TCP_RTO_MAX;
-#endif
-}
-
-/* Save metrics learned by this TCP session.
-   This function is called only, when TCP finishes successfully
-   i.e. when it enters TIME-WAIT or goes from LAST-ACK to CLOSE.
- */
-void tcp_update_metrics(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct dst_entry *dst = __sk_dst_get(sk);
-
-	dst_confirm(dst);
-
-	if (dst && (dst->flags&DST_HOST)) {
-		int m;
-
-		if (tp->backoff || !tp->srtt) {
-			/* This session failed to estimate rtt. Why?
-			 * Probably, no packets returned in time.
-			 * Reset our results.
-			 */
-			if (!(dst->mxlock&(1<<RTAX_RTT)))
-				dst->rtt = 0;
-			return;
-		}
-
-		m = dst->rtt - tp->srtt;
-
-		/* If newly calculated rtt larger than stored one,
-		 * store new one. Otherwise, use EWMA. Remember,
-		 * rtt overestimation is always better than underestimation.
-		 */
-		if (!(dst->mxlock&(1<<RTAX_RTT))) {
-			if (m <= 0)
-				dst->rtt = tp->srtt;
-			else
-				dst->rtt -= (m>>3);
-		}
-
-		if (!(dst->mxlock&(1<<RTAX_RTTVAR))) {
-			if (m < 0)
-				m = -m;
-
-			/* Scale deviation to rttvar fixed point */
-			m >>= 1;
-			if (m < tp->mdev)
-				m = tp->mdev;
-
-			if (m >= dst->rttvar)
-				dst->rttvar = m;
-			else
-				dst->rttvar -= (dst->rttvar - m)>>2;
-		}
-
-		if (tp->snd_ssthresh >= 0xFFFF) {
-			/* Slow start still did not finish. */
-			if (dst->ssthresh &&
-			    !(dst->mxlock&(1<<RTAX_SSTHRESH)) &&
-			    (tp->snd_cwnd>>1) > dst->ssthresh)
-				dst->ssthresh = (tp->snd_cwnd>>1);
-			if (!(dst->mxlock&(1<<RTAX_CWND)) &&
-			    tp->snd_cwnd > dst->cwnd)
-				dst->cwnd = tp->snd_cwnd;
-		} else if (tp->snd_cwnd > tp->snd_ssthresh &&
-			   tp->ca_state == TCP_CA_Open) {
-			/* Cong. avoidance phase, cwnd is reliable. */
-			if (!(dst->mxlock&(1<<RTAX_SSTHRESH)))
-				dst->ssthresh = max(tp->snd_cwnd>>1, tp->snd_ssthresh);
-			if (!(dst->mxlock&(1<<RTAX_CWND)))
-				dst->cwnd = (dst->cwnd + tp->snd_cwnd)>>1;
-		} else {
-			/* Else slow start did not finish, cwnd is non-sense,
-			   ssthresh may be also invalid.
-			 */
-			if (!(dst->mxlock&(1<<RTAX_CWND)))
-				dst->cwnd = (dst->cwnd + tp->snd_ssthresh)>>1;
-			if (dst->ssthresh &&
-			    !(dst->mxlock&(1<<RTAX_SSTHRESH)) &&
-			    tp->snd_ssthresh > dst->ssthresh)
-				dst->ssthresh = tp->snd_ssthresh;
-		}
-
-		if (!(dst->mxlock&(1<<RTAX_REORDERING))) {
-			if (dst->reordering < tp->reordering &&
-			    tp->reordering != sysctl_tcp_reordering)
-				dst->reordering = tp->reordering;
-		}
-	}
-#endif
-}
-
-/* Increase initial CWND conservatively: if estimated
- * RTT is low enough (<20msec) or if we have some preset ssthresh.
- *
- * Numbers are taken from RFC2414.
- */
-__u32 tcp_init_cwnd(struct tcp_opt *tp)
-{
-#if 0
-	__u32 cwnd;
-
-	if (tp->mss_cache > 1460)
-		return 2;
-
-	cwnd = (tp->mss_cache > 1095) ? 3 : 4;
-
-	if (!tp->srtt || (tp->snd_ssthresh >= 0xFFFF && tp->srtt > ((HZ/50)<<3)))
-		cwnd = 2;
-	else if (cwnd > tp->snd_ssthresh)
-		cwnd = tp->snd_ssthresh;
-
-	return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
-#else
-  return 0;
-#endif
-}
-
-/* Initialize metrics on socket. */
-
-static void tcp_init_metrics(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct dst_entry *dst = __sk_dst_get(sk);
-
-	if (dst == NULL)
-		goto reset;
-
-	dst_confirm(dst);
-
-	if (dst->mxlock&(1<<RTAX_CWND))
-		tp->snd_cwnd_clamp = dst->cwnd;
-	if (dst->ssthresh) {
-		tp->snd_ssthresh = dst->ssthresh;
-		if (tp->snd_ssthresh > tp->snd_cwnd_clamp)
-			tp->snd_ssthresh = tp->snd_cwnd_clamp;
-	}
-	if (dst->reordering && tp->reordering != dst->reordering) {
-		tp->sack_ok &= ~2;
-		tp->reordering = dst->reordering;
-	}
-
-	if (dst->rtt == 0)
-		goto reset;
-
-	if (!tp->srtt && dst->rtt < (TCP_TIMEOUT_INIT<<3))
-		goto reset;
-
-	/* Initial rtt is determined from SYN,SYN-ACK.
-	 * The segment is small and rtt may appear much
-	 * less than real one. Use per-dst memory
-	 * to make it more realistic.
-	 *
-	 * A bit of theory. RTT is time passed after "normal" sized packet
-	 * is sent until it is ACKed. In normal curcumstances sending small
-	 * packets force peer to delay ACKs and calculation is correct too.
-	 * The algorithm is adaptive and, provided we follow specs, it
-	 * NEVER underestimate RTT. BUT! If peer tries to make some clever
-	 * tricks sort of "quick acks" for time long enough to decrease RTT
-	 * to low value, and then abruptly stops to do it and starts to delay
-	 * ACKs, wait for troubles.
-	 */
-	if (dst->rtt > tp->srtt)
-		tp->srtt = dst->rtt;
-	if (dst->rttvar > tp->mdev) {
-		tp->mdev = dst->rttvar;
-		tp->mdev_max = tp->rttvar = max(tp->mdev, TCP_RTO_MIN);
-	}
-	tcp_set_rto(tp);
-	tcp_bound_rto(tp);
-	if (tp->rto < TCP_TIMEOUT_INIT && !tp->saw_tstamp)
-		goto reset;
-	tp->snd_cwnd = tcp_init_cwnd(tp);
-	tp->snd_cwnd_stamp = tcp_time_stamp;
-	return;
-
-reset:
-	/* Play conservative. If timestamps are not
-	 * supported, TCP will fail to recalculate correct
-	 * rtt, if initial rto is too small. FORGET ALL AND RESET!
-	 */
-	if (!tp->saw_tstamp && tp->srtt) {
-		tp->srtt = 0;
-		tp->mdev = tp->mdev_max = tp->rttvar = TCP_TIMEOUT_INIT;
-		tp->rto = TCP_TIMEOUT_INIT;
-	}
-#endif
-}
-
-static void tcp_update_reordering(struct tcp_opt *tp, int metric, int ts)
-{
-#if 0
-	if (metric > tp->reordering) {
-		tp->reordering = min(TCP_MAX_REORDERING, metric);
-
-		/* This exciting event is worth to be remembered. 8) */
-		if (ts)
-			NET_INC_STATS_BH(TCPTSReorder);
-		else if (IsReno(tp))
-			NET_INC_STATS_BH(TCPRenoReorder);
-		else if (IsFack(tp))
-			NET_INC_STATS_BH(TCPFACKReorder);
-		else
-			NET_INC_STATS_BH(TCPSACKReorder);
-#if FASTRETRANS_DEBUG > 1
-		printk(KERN_DEBUG "Disorder%d %d %u f%u s%u rr%d\n",
-		       tp->sack_ok, tp->ca_state,
-		       tp->reordering, tp->fackets_out, tp->sacked_out,
-		       tp->undo_marker ? tp->undo_retrans : 0);
-#endif
-		/* Disable FACK yet. */
-		tp->sack_ok &= ~2;
-	}
-#endif
-}
-
-/* This procedure tags the retransmission queue when SACKs arrive.
- *
- * We have three tag bits: SACKED(S), RETRANS(R) and LOST(L).
- * Packets in queue with these bits set are counted in variables
- * sacked_out, retrans_out and lost_out, correspondingly.
- *
- * Valid combinations are:
- * Tag  InFlight	Description
- * 0	1		- orig segment is in flight.
- * S	0		- nothing flies, orig reached receiver.
- * L	0		- nothing flies, orig lost by net.
- * R	2		- both orig and retransmit are in flight.
- * L|R	1		- orig is lost, retransmit is in flight.
- * S|R  1		- orig reached receiver, retrans is still in flight.
- * (L|S|R is logically valid, it could occur when L|R is sacked,
- *  but it is equivalent to plain S and code short-curcuits it to S.
- *  L|S is logically invalid, it would mean -1 packet in flight 8))
- *
- * These 6 states form finite state machine, controlled by the following events:
- * 1. New ACK (+SACK) arrives. (tcp_sacktag_write_queue())
- * 2. Retransmission. (tcp_retransmit_skb(), tcp_xmit_retransmit_queue())
- * 3. Loss detection event of one of three flavors:
- *	A. Scoreboard estimator decided the packet is lost.
- *	   A'. Reno "three dupacks" marks head of queue lost.
- *	   A''. Its FACK modfication, head until snd.fack is lost.
- *	B. SACK arrives sacking data transmitted after never retransmitted
- *	   hole was sent out.
- *	C. SACK arrives sacking SND.NXT at the moment, when the
- *	   segment was retransmitted.
- * 4. D-SACK added new rule: D-SACK changes any tag to S.
- *
- * It is pleasant to note, that state diagram turns out to be commutative,
- * so that we are allowed not to be bothered by order of our actions,
- * when multiple events arrive simultaneously. (see the function below).
- *
- * Reordering detection.
- * --------------------
- * Reordering metric is maximal distance, which a packet can be displaced
- * in packet stream. With SACKs we can estimate it:
- *
- * 1. SACK fills old hole and the corresponding segment was not
- *    ever retransmitted -> reordering. Alas, we cannot use it
- *    when segment was retransmitted.
- * 2. The last flaw is solved with D-SACK. D-SACK arrives
- *    for retransmitted and already SACKed segment -> reordering..
- * Both of these heuristics are not used in Loss state, when we cannot
- * account for retransmits accurately.
- */
-static int
-tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_una)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	unsigned char *ptr = ack_skb->h.raw + TCP_SKB_CB(ack_skb)->sacked;
-	struct tcp_sack_block *sp = (struct tcp_sack_block *)(ptr+2);
-	int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3;
-	int reord = tp->packets_out;
-	int prior_fackets;
-	u32 lost_retrans = 0;
-	int flag = 0;
-	int i;
-
-	if (!tp->sacked_out)
-		tp->fackets_out = 0;
-	prior_fackets = tp->fackets_out;
-
-	for (i=0; i<num_sacks; i++, sp++) {
-		struct sk_buff *skb;
-		__u32 start_seq = ntohl(sp->start_seq);
-		__u32 end_seq = ntohl(sp->end_seq);
-		int fack_count = 0;
-		int dup_sack = 0;
-
-		/* Check for D-SACK. */
-		if (i == 0) {
-			u32 ack = TCP_SKB_CB(ack_skb)->ack_seq;
-
-			if (before(start_seq, ack)) {
-				dup_sack = 1;
-				tp->sack_ok |= 4;
-				NET_INC_STATS_BH(TCPDSACKRecv);
-			} else if (num_sacks > 1 &&
-				   !after(end_seq, ntohl(sp[1].end_seq)) &&
-				   !before(start_seq, ntohl(sp[1].start_seq))) {
-				dup_sack = 1;
-				tp->sack_ok |= 4;
-				NET_INC_STATS_BH(TCPDSACKOfoRecv);
-			}
-
-			/* D-SACK for already forgotten data...
-			 * Do dumb counting. */
-			if (dup_sack &&
-			    !after(end_seq, prior_snd_una) &&
-			    after(end_seq, tp->undo_marker))
-				tp->undo_retrans--;
-
-			/* Eliminate too old ACKs, but take into
-			 * account more or less fresh ones, they can
-			 * contain valid SACK info.
-			 */
-			if (before(ack, prior_snd_una-tp->max_window))
-				return 0;
-		}
-
-		/* Event "B" in the comment above. */
-		if (after(end_seq, tp->high_seq))
-			flag |= FLAG_DATA_LOST;
-
-		for_retrans_queue(skb, sk, tp) {
-			u8 sacked = TCP_SKB_CB(skb)->sacked;
-			int in_sack;
-
-			/* The retransmission queue is always in order, so
-			 * we can short-circuit the walk early.
-			 */
-			if(!before(TCP_SKB_CB(skb)->seq, end_seq))
-				break;
-
-			fack_count++;
-
-			in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) &&
-				!before(end_seq, TCP_SKB_CB(skb)->end_seq);
-
-			/* Account D-SACK for retransmitted packet. */
-			if ((dup_sack && in_sack) &&
-			    (sacked & TCPCB_RETRANS) &&
-			    after(TCP_SKB_CB(skb)->end_seq, tp->undo_marker))
-				tp->undo_retrans--;
-
-			/* The frame is ACKed. */
-			if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una)) {
-				if (sacked&TCPCB_RETRANS) {
-					if ((dup_sack && in_sack) &&
-					    (sacked&TCPCB_SACKED_ACKED))
-						reord = min(fack_count, reord);
-				} else {
-					/* If it was in a hole, we detected reordering. */
-					if (fack_count < prior_fackets &&
-					    !(sacked&TCPCB_SACKED_ACKED))
-						reord = min(fack_count, reord);
-				}
-
-				/* Nothing to do; acked frame is about to be dropped. */
-				continue;
-			}
-
-			if ((sacked&TCPCB_SACKED_RETRANS) &&
-			    after(end_seq, TCP_SKB_CB(skb)->ack_seq) &&
-			    (!lost_retrans || after(end_seq, lost_retrans)))
-				lost_retrans = end_seq;
-
-			if (!in_sack)
-				continue;
-
-			if (!(sacked&TCPCB_SACKED_ACKED)) {
-				if (sacked & TCPCB_SACKED_RETRANS) {
-					/* If the segment is not tagged as lost,
-					 * we do not clear RETRANS, believing
-					 * that retransmission is still in flight.
-					 */
-					if (sacked & TCPCB_LOST) {
-						TCP_SKB_CB(skb)->sacked &= ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
-						tp->lost_out--;
-						tp->retrans_out--;
-					}
-				} else {
-					/* New sack for not retransmitted frame,
-					 * which was in hole. It is reordering.
-					 */
-					if (!(sacked & TCPCB_RETRANS) &&
-					    fack_count < prior_fackets)
-						reord = min(fack_count, reord);
-
-					if (sacked & TCPCB_LOST) {
-						TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
-						tp->lost_out--;
-					}
-				}
-
-				TCP_SKB_CB(skb)->sacked |= TCPCB_SACKED_ACKED;
-				flag |= FLAG_DATA_SACKED;
-				tp->sacked_out++;
-
-				if (fack_count > tp->fackets_out)
-					tp->fackets_out = fack_count;
-			} else {
-				if (dup_sack && (sacked&TCPCB_RETRANS))
-					reord = min(fack_count, reord);
-			}
-
-			/* D-SACK. We can detect redundant retransmission
-			 * in S|R and plain R frames and clear it.
-			 * undo_retrans is decreased above, L|R frames
-			 * are accounted above as well.
-			 */
-			if (dup_sack &&
-			    (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS)) {
-				TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
-				tp->retrans_out--;
-			}
-		}
-	}
-
-	/* Check for lost retransmit. This superb idea is
-	 * borrowed from "ratehalving". Event "C".
-	 * Later note: FACK people cheated me again 8),
-	 * we have to account for reordering! Ugly,
-	 * but should help.
-	 */
-	if (lost_retrans && tp->ca_state == TCP_CA_Recovery) {
-		struct sk_buff *skb;
-
-		for_retrans_queue(skb, sk, tp) {
-			if (after(TCP_SKB_CB(skb)->seq, lost_retrans))
-				break;
-			if (!after(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
-				continue;
-			if ((TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) &&
-			    after(lost_retrans, TCP_SKB_CB(skb)->ack_seq) &&
-			    (IsFack(tp) ||
-			     !before(lost_retrans, TCP_SKB_CB(skb)->ack_seq+tp->reordering*tp->mss_cache))) {
-				TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
-				tp->retrans_out--;
-
-				if (!(TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_SACKED_ACKED))) {
-					tp->lost_out++;
-					TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
-					flag |= FLAG_DATA_SACKED;
-					NET_INC_STATS_BH(TCPLostRetransmit);
[truncated at 1000 lines; 3188 more skipped]

reactos/drivers/net/tcpip/transport/tcp
tcp_ipv4.c removed after 1.1
diff -N tcp_ipv4.c
--- tcp_ipv4.c	15 Jan 2003 21:57:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,2523 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS TCP/IP protocol driver
- * FILE:        transport/tcp/tcp_ipv4.c
- * PURPOSE:     Transmission Control Protocol
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- *   CSH 15-01-2003 Imported from linux kernel 2.4.20
- */
-
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		Implementation of the Transmission Control Protocol(TCP).
- *
- * Version:	$Id: tcp_ipv4.c,v 1.1 2003/01/15 21:57:31 chorns Exp $
- *
- *		IPv4 specific functions
- *
- *
- *		code split from:
- *		linux/ipv4/tcp.c
- *		linux/ipv4/tcp_input.c
- *		linux/ipv4/tcp_output.c
- *
- *		See tcp.c for author information
- *
- *	This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-
-/*
- * Changes:
- *		David S. Miller	:	New socket lookup architecture.
- *					This code is dedicated to John Dyson.
- *		David S. Miller :	Change semantics of established hash,
- *					half is devoted to TIME_WAIT sockets
- *					and the rest go in the other half.
- *		Andi Kleen :		Add support for syncookies and fixed
- *					some bugs: ip options weren't passed to
- *					the TCP layer, missed a check for an ACK bit.
- *		Andi Kleen :		Implemented fast path mtu discovery.
- *	     				Fixed many serious bugs in the
- *					open_request handling and moved
- *					most of it into the af independent code.
- *					Added tail drop and some other bugfixes.
- *					Added new listen sematics.
- *		Mike McLagan	:	Routing by source
- *	Juan Jose Ciarlante:		ip_dynaddr bits
- *		Andi Kleen:		various fixes.
- *	Vitaly E. Lavrov	:	Transparent proxy revived after year coma.
- *	Andi Kleen		:	Fix new listen.
- *	Andi Kleen		:	Fix accept error reporting.
- */
-
-#if 0
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/random.h>
-#include <linux/cache.h>
-#include <linux/init.h>
-
-#include <net/icmp.h>
-#include <net/tcp.h>
-#include <net/ipv6.h>
-#include <net/inet_common.h>
-
-#include <linux/inet.h>
-#include <linux/stddef.h>
-#include <linux/ipsec.h>
-#else
-#include "linux.h"
-#include "tcpcore.h"
-#endif
-
-extern int sysctl_ip_dynaddr;
-extern int sysctl_ip_default_ttl;
-int sysctl_tcp_tw_reuse = 0;
-
-/* Check TCP sequence numbers in ICMP packets. */
-#define ICMP_MIN_LENGTH 8
-
-/* Socket used for sending RSTs */ 	
-#if 0
-static struct inode tcp_inode;
-static struct socket *tcp_socket=&tcp_inode.u.socket_i;
-#endif
-
-void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len, 
-		       struct sk_buff *skb);
-
-/*
- * ALL members must be initialised to prevent gcc-2.7.2.3 miscompilation
- */
-#if 0
-struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = {
-	__tcp_ehash:          NULL,
-	__tcp_bhash:          NULL,
-	__tcp_bhash_size:     0,
-	__tcp_ehash_size:     0,
-	__tcp_listening_hash: { NULL, },
-	__tcp_lhash_lock:     RW_LOCK_UNLOCKED,
-	__tcp_lhash_users:    ATOMIC_INIT(0),
-	__tcp_lhash_wait:
-	  __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait),
-	__tcp_portalloc_lock: SPIN_LOCK_UNLOCKED
-};
-#endif
-
-/*
- * This array holds the first and last local port number.
- * For high-usage systems, use sysctl to change this to
- * 32768-61000
- */
-int sysctl_local_port_range[2] = { 1024, 4999 };
-int tcp_port_rover = (1024 - 1);
-
-static __inline__ int tcp_hashfn(__u32 laddr, __u16 lport,
-				 __u32 faddr, __u16 fport)
-{
-	int h = ((laddr ^ lport) ^ (faddr ^ fport));
-	h ^= h>>16;
-	h ^= h>>8;
-	return h & (tcp_ehash_size - 1);
-}
-
-static __inline__ int tcp_sk_hashfn(struct sock *sk)
-{
-	__u32 laddr = sk->rcv_saddr;
-	__u16 lport = sk->num;
-	__u32 faddr = sk->daddr;
-	__u16 fport = sk->dport;
-
-	return tcp_hashfn(laddr, lport, faddr, fport);
-}
-
-/* Allocate and initialize a new TCP local port bind bucket.
- * The bindhash mutex for snum's hash chain must be held here.
- */
-struct tcp_bind_bucket *tcp_bucket_create(struct tcp_bind_hashbucket *head,
-					  unsigned short snum)
-{
-#if 0
-	struct tcp_bind_bucket *tb;
-
-	tb = kmem_cache_alloc(tcp_bucket_cachep, SLAB_ATOMIC);
-	if(tb != NULL) {
-		tb->port = snum;
-		tb->fastreuse = 0;
-		tb->owners = NULL;
-		if((tb->next = head->chain) != NULL)
-			tb->next->pprev = &tb->next;
-		head->chain = tb;
-		tb->pprev = &head->chain;
-	}
-	return tb;
-#else
-  return NULL;
-#endif
-}
-
-/* Caller must disable local BH processing. */
-static __inline__ void __tcp_inherit_port(struct sock *sk, struct sock *child)
-{
-#if 0
-	struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(child->num)];
-	struct tcp_bind_bucket *tb;
-
-	spin_lock(&head->lock);
-	tb = (struct tcp_bind_bucket *)sk->prev;
-	if ((child->bind_next = tb->owners) != NULL)
-		tb->owners->bind_pprev = &child->bind_next;
-	tb->owners = child;
-	child->bind_pprev = &tb->owners;
-	child->prev = (struct sock *) tb;
-	spin_unlock(&head->lock);
-#endif
-}
-
-__inline__ void tcp_inherit_port(struct sock *sk, struct sock *child)
-{
-#if 0
-	local_bh_disable();
-	__tcp_inherit_port(sk, child);
-	local_bh_enable();
-#endif
-}
-
-static inline void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, unsigned short snum)
-{
-#if 0
-	sk->num = snum;
-	if ((sk->bind_next = tb->owners) != NULL)
-		tb->owners->bind_pprev = &sk->bind_next;
-	tb->owners = sk;
-	sk->bind_pprev = &tb->owners;
-	sk->prev = (struct sock *) tb;
-#endif
-}
-
-static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
-{
-#if 0
-	struct sock *sk2 = tb->owners;
-	int sk_reuse = sk->reuse;
-	
-	for( ; sk2 != NULL; sk2 = sk2->bind_next) {
-		if (sk != sk2 &&
-		    sk2->reuse <= 1 &&
-		    sk->bound_dev_if == sk2->bound_dev_if) {
-			if (!sk_reuse	||
-			    !sk2->reuse	||
-			    sk2->state == TCP_LISTEN) {
-				if (!sk2->rcv_saddr	||
-				    !sk->rcv_saddr	||
-				    (sk2->rcv_saddr == sk->rcv_saddr))
-					break;
-			}
-		}
-	}
-	return sk2 != NULL;
-#else
-  return 0;
-#endif
-}
-
-/* Obtain a reference to a local port for the given sock,
- * if snum is zero it means select any available local port.
- */
-static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
-{
-#if 0
-	struct tcp_bind_hashbucket *head;
-	struct tcp_bind_bucket *tb;
-	int ret;
-
-	local_bh_disable();
-	if (snum == 0) {
-		int low = sysctl_local_port_range[0];
-		int high = sysctl_local_port_range[1];
-		int remaining = (high - low) + 1;
-		int rover;
-
-		spin_lock(&tcp_portalloc_lock);
-		rover = tcp_port_rover;
-		do {	rover++;
-			if ((rover < low) || (rover > high))
-				rover = low;
-			head = &tcp_bhash[tcp_bhashfn(rover)];
-			spin_lock(&head->lock);
-			for (tb = head->chain; tb; tb = tb->next)
-				if (tb->port == rover)
-					goto next;
-			break;
-		next:
-			spin_unlock(&head->lock);
-		} while (--remaining > 0);
-		tcp_port_rover = rover;
-		spin_unlock(&tcp_portalloc_lock);
-
-		/* Exhausted local port range during search? */
-		ret = 1;
-		if (remaining <= 0)
-			goto fail;
-
-		/* OK, here is the one we will use.  HEAD is
-		 * non-NULL and we hold it's mutex.
-		 */
-		snum = rover;
-		tb = NULL;
-	} else {
-		head = &tcp_bhash[tcp_bhashfn(snum)];
-		spin_lock(&head->lock);
-		for (tb = head->chain; tb != NULL; tb = tb->next)
-			if (tb->port == snum)
-				break;
-	}
-	if (tb != NULL && tb->owners != NULL) {
-		if (sk->reuse > 1)
-			goto success;
-		if (tb->fastreuse > 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
-			goto success;
-		} else {
-			ret = 1;
-			if (tcp_bind_conflict(sk, tb))
-				goto fail_unlock;
-		}
-	}
-	ret = 1;
-	if (tb == NULL &&
-	    (tb = tcp_bucket_create(head, snum)) == NULL)
-			goto fail_unlock;
-	if (tb->owners == NULL) {
-		if (sk->reuse && sk->state != TCP_LISTEN)
-			tb->fastreuse = 1;
-		else
-			tb->fastreuse = 0;
-	} else if (tb->fastreuse &&
-		   ((sk->reuse == 0) || (sk->state == TCP_LISTEN)))
-		tb->fastreuse = 0;
-success:
-	if (sk->prev == NULL)
-		tcp_bind_hash(sk, tb, snum);
-	BUG_TRAP(sk->prev == (struct sock *) tb);
- 	ret = 0;
-
-fail_unlock:
-	spin_unlock(&head->lock);
-fail:
-	local_bh_enable();
-	return ret;
-#else
-  return 0;
-#endif
-}
-
-/* Get rid of any references to a local port held by the
- * given sock.
- */
-__inline__ void __tcp_put_port(struct sock *sk)
-{
-#if 0
-	struct tcp_bind_hashbucket *head = &tcp_bhash[tcp_bhashfn(sk->num)];
-	struct tcp_bind_bucket *tb;
-
-	spin_lock(&head->lock);
-	tb = (struct tcp_bind_bucket *) sk->prev;
-	if (sk->bind_next)
-		sk->bind_next->bind_pprev = sk->bind_pprev;
-	*(sk->bind_pprev) = sk->bind_next;
-	sk->prev = NULL;
-	sk->num = 0;
-	if (tb->owners == NULL) {
-		if (tb->next)
-			tb->next->pprev = tb->pprev;
-		*(tb->pprev) = tb->next;
-		kmem_cache_free(tcp_bucket_cachep, tb);
-	}
-	spin_unlock(&head->lock);
-#endif
-}
-
-void tcp_put_port(struct sock *sk)
-{
-#if 0
-	local_bh_disable();
-	__tcp_put_port(sk);
-	local_bh_enable();
-#endif
-}
-
-/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP.
- * Look, when several writers sleep and reader wakes them up, all but one
- * immediately hit write lock and grab all the cpus. Exclusive sleep solves
- * this, _but_ remember, it adds useless work on UP machines (wake up each
- * exclusive lock release). It should be ifdefed really.
- */
-
-void tcp_listen_wlock(void)
-{
-#if 0
-	write_lock(&tcp_lhash_lock);
-
-	if (atomic_read(&tcp_lhash_users)) {
-		DECLARE_WAITQUEUE(wait, current);
-
-		add_wait_queue_exclusive(&tcp_lhash_wait, &wait);
-		for (;;) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			if (atomic_read(&tcp_lhash_users) == 0)
-				break;
-			write_unlock_bh(&tcp_lhash_lock);
-			schedule();
-			write_lock_bh(&tcp_lhash_lock);
-		}
-
-		__set_current_state(TASK_RUNNING);
-		remove_wait_queue(&tcp_lhash_wait, &wait);
-	}
-#endif
-}
-
-static __inline__ void __tcp_v4_hash(struct sock *sk, const int listen_possible)
-{
-#if 0
-	struct sock **skp;
-	rwlock_t *lock;
-
-	BUG_TRAP(sk->pprev==NULL);
-	if(listen_possible && sk->state == TCP_LISTEN) {
-		skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)];
-		lock = &tcp_lhash_lock;
-		tcp_listen_wlock();
-	} else {
-		skp = &tcp_ehash[(sk->hashent = tcp_sk_hashfn(sk))].chain;
-		lock = &tcp_ehash[sk->hashent].lock;
-		write_lock(lock);
-	}
-	if((sk->next = *skp) != NULL)
-		(*skp)->pprev = &sk->next;
-	*skp = sk;
-	sk->pprev = skp;
-	sock_prot_inc_use(sk->prot);
-	write_unlock(lock);
-	if (listen_possible && sk->state == TCP_LISTEN)
-		wake_up(&tcp_lhash_wait);
-#endif
-}
-
-static void tcp_v4_hash(struct sock *sk)
-{
-#if 0
-	if (sk->state != TCP_CLOSE) {
-		local_bh_disable();
-		__tcp_v4_hash(sk, 1);
-		local_bh_enable();
-	}
-#endif
-}
-
-void tcp_unhash(struct sock *sk)
-{
-#if 0
-	rwlock_t *lock;
-
-	if (!sk->pprev)
-		goto ende;
-
-	if (sk->state == TCP_LISTEN) {
-		local_bh_disable();
-		tcp_listen_wlock();
-		lock = &tcp_lhash_lock;
-	} else {
-		struct tcp_ehash_bucket *head = &tcp_ehash[sk->hashent];
-		lock = &head->lock;
-		write_lock_bh(&head->lock);
-	}
-
-	if(sk->pprev) {
-		if(sk->next)
-			sk->next->pprev = sk->pprev;
-		*sk->pprev = sk->next;
-		sk->pprev = NULL;
-		sock_prot_dec_use(sk->prot);
-	}
-	write_unlock_bh(lock);
-
- ende:
-	if (sk->state == TCP_LISTEN)
-		wake_up(&tcp_lhash_wait);
-#endif
-}
-
-/* Don't inline this cruft.  Here are some nice properties to
- * exploit here.  The BSD API does not allow a listening TCP
- * to specify the remote port nor the remote address for the
- * connection.  So always assume those are both wildcarded
- * during the search since they can never be otherwise.
- */
-static struct sock *__tcp_v4_lookup_listener(struct sock *sk, u32 daddr, unsigned short hnum, int dif)
-{
-#if 0
-	struct sock *result = NULL;
-	int score, hiscore;
-
-	hiscore=0;
-	for(; sk; sk = sk->next) {
-		if(sk->num == hnum) {
-			__u32 rcv_saddr = sk->rcv_saddr;
-
-			score = 1;
-			if(rcv_saddr) {
-				if (rcv_saddr != daddr)
-					continue;
-				score++;
-			}
-			if (sk->bound_dev_if) {
-				if (sk->bound_dev_if != dif)
-					continue;
-				score++;
-			}
-			if (score == 3)
-				return sk;
-			if (score > hiscore) {
-				hiscore = score;
-				result = sk;
-			}
-		}
-	}
-	return result;
-#else
-  return NULL;
-#endif
-}
-
-/* Optimize the common listener case. */
-__inline__ struct sock *tcp_v4_lookup_listener(u32 daddr, unsigned short hnum, int dif)
-{
-#if 0
-	struct sock *sk;
-
-	read_lock(&tcp_lhash_lock);
-	sk = tcp_listening_hash[tcp_lhashfn(hnum)];
-	if (sk) {
-		if (sk->num == hnum &&
-		    sk->next == NULL &&
-		    (!sk->rcv_saddr || sk->rcv_saddr == daddr) &&
-		    !sk->bound_dev_if)
-			goto sherry_cache;
-		sk = __tcp_v4_lookup_listener(sk, daddr, hnum, dif);
-	}
-	if (sk) {
-sherry_cache:
-		sock_hold(sk);
-	}
-	read_unlock(&tcp_lhash_lock);
-	return sk;
-#else
-  return NULL;
-#endif
-}
-
-/* Sockets in TCP_CLOSE state are _always_ taken out of the hash, so
- * we need not check it for TCP lookups anymore, thanks Alexey. -DaveM
- *
- * Local BH must be disabled here.
- */
-
-static inline struct sock *__tcp_v4_lookup_established(u32 saddr, u16 sport,
-						       u32 daddr, u16 hnum, int dif)
-{
-#if 0
-	struct tcp_ehash_bucket *head;
-	TCP_V4_ADDR_COOKIE(acookie, saddr, daddr)
-	__u32 ports = TCP_COMBINED_PORTS(sport, hnum);
-	struct sock *sk;
-	int hash;
-
-	/* Optimize here for direct hit, only listening connections can
-	 * have wildcards anyways.
-	 */
-	hash = tcp_hashfn(daddr, hnum, saddr, sport);
-	head = &tcp_ehash[hash];
-	read_lock(&head->lock);
-	for(sk = head->chain; sk; sk = sk->next) {
-		if(TCP_IPV4_MATCH(sk, acookie, saddr, daddr, ports, dif))
-			goto hit; /* You sunk my battleship! */
-	}
-
-	/* Must check for a TIME_WAIT'er before going to listener hash. */
-	for(sk = (head + tcp_ehash_size)->chain; sk; sk = sk->next)
-		if(TCP_IPV4_MATCH(sk, acookie, saddr, daddr, ports, dif))
-			goto hit;
-	read_unlock(&head->lock);
-
-	return NULL;
-
-hit:
-	sock_hold(sk);
-	read_unlock(&head->lock);
-	return sk;
-#else
-  return NULL;
-#endif
-}
-
-static inline struct sock *__tcp_v4_lookup(u32 saddr, u16 sport,
-					   u32 daddr, u16 hnum, int dif)
-{
-#if 0
-	struct sock *sk;
-
-	sk = __tcp_v4_lookup_established(saddr, sport, daddr, hnum, dif);
-
-	if (sk)
-		return sk;
-		
-	return tcp_v4_lookup_listener(daddr, hnum, dif);
-#else
-  return NULL;
-#endif
-}
-
-__inline__ struct sock *tcp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
-{
-#if 0
-	struct sock *sk;
-
-	local_bh_disable();
-	sk = __tcp_v4_lookup(saddr, sport, daddr, ntohs(dport), dif);
-	local_bh_enable();
-
-	return sk;
-#else
-  return NULL;
-#endif
-}
-
-static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb)
-{
-#if 0
-	return secure_tcp_sequence_number(skb->nh.iph->daddr,
-					  skb->nh.iph->saddr,
-					  skb->h.th->dest,
-					  skb->h.th->source);
-#else
-  return 0;
-#endif
-}
-
-/* called with local bh disabled */
-static int __tcp_v4_check_established(struct sock *sk, __u16 lport,
-				      struct tcp_tw_bucket **twp)
-{
-#if 0
-	u32 daddr = sk->rcv_saddr;
-	u32 saddr = sk->daddr;
-	int dif = sk->bound_dev_if;
-	TCP_V4_ADDR_COOKIE(acookie, saddr, daddr)
-	__u32 ports = TCP_COMBINED_PORTS(sk->dport, lport);
-	int hash = tcp_hashfn(daddr, lport, saddr, sk->dport);
-	struct tcp_ehash_bucket *head = &tcp_ehash[hash];
-	struct sock *sk2, **skp;
-	struct tcp_tw_bucket *tw;
-
-	write_lock(&head->lock);
-
-	/* Check TIME-WAIT sockets first. */
-	for(skp = &(head + tcp_ehash_size)->chain; (sk2=*skp) != NULL;
-	    skp = &sk2->next) {
-		tw = (struct tcp_tw_bucket*)sk2;
-
-		if(TCP_IPV4_MATCH(sk2, acookie, saddr, daddr, ports, dif)) {
-			struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-
-			/* With PAWS, it is safe from the viewpoint
-			   of data integrity. Even without PAWS it
-			   is safe provided sequence spaces do not
-			   overlap i.e. at data rates <= 80Mbit/sec.
-
-			   Actually, the idea is close to VJ's one,
-			   only timestamp cache is held not per host,
-			   but per port pair and TW bucket is used
-			   as state holder.
-
-			   If TW bucket has been already destroyed we
-			   fall back to VJ's scheme and use initial
-			   timestamp retrieved from peer table.
-			 */
-			if (tw->ts_recent_stamp &&
-			    (!twp || (sysctl_tcp_tw_reuse &&
-				      xtime.tv_sec - tw->ts_recent_stamp > 1))) {
-				if ((tp->write_seq = tw->snd_nxt+65535+2) == 0)
-					tp->write_seq = 1;
-				tp->ts_recent = tw->ts_recent;
-				tp->ts_recent_stamp = tw->ts_recent_stamp;
-				sock_hold(sk2);
-				skp = &head->chain;
-				goto unique;
-			} else
-				goto not_unique;
-		}
-	}
-	tw = NULL;
-
-	/* And established part... */
-	for(skp = &head->chain; (sk2=*skp)!=NULL; skp = &sk2->next) {
-		if(TCP_IPV4_MATCH(sk2, acookie, saddr, daddr, ports, dif))
-			goto not_unique;
-	}
-
-unique:
-	/* Must record num and sport now. Otherwise we will see
-	 * in hash table socket with a funny identity. */
-	sk->num = lport;
-	sk->sport = htons(lport);
-	BUG_TRAP(sk->pprev==NULL);
-	if ((sk->next = *skp) != NULL)
-		(*skp)->pprev = &sk->next;
-
-	*skp = sk;
-	sk->pprev = skp;
-	sk->hashent = hash;
-	sock_prot_inc_use(sk->prot);
-	write_unlock(&head->lock);
-
-	if (twp) {
-		*twp = tw;
-		NET_INC_STATS_BH(TimeWaitRecycled);
-	} else if (tw) {
-		/* Silly. Should hash-dance instead... */
-		tcp_tw_deschedule(tw);
-		tcp_timewait_kill(tw);
-		NET_INC_STATS_BH(TimeWaitRecycled);
-
-		tcp_tw_put(tw);
-	}
-
-	return 0;
-
-not_unique:
-	write_unlock(&head->lock);
-	return -EADDRNOTAVAIL;
-#else
-  return 0;
-#endif
-}
-
-/*
- * Bind a port for a connect operation and hash it.
- */
-static int tcp_v4_hash_connect(struct sock *sk)
-{
-#if 0
-	unsigned short snum = sk->num;
-	struct tcp_bind_hashbucket *head;
-	struct tcp_bind_bucket *tb;
-
-	if (snum == 0) {
-		int rover;
-		int low = sysctl_local_port_range[0];
-		int high = sysctl_local_port_range[1];
-		int remaining = (high - low) + 1;
-		struct tcp_tw_bucket *tw = NULL;
-
-		local_bh_disable();
-
-		/* TODO. Actually it is not so bad idea to remove
-		 * tcp_portalloc_lock before next submission to Linus.
-		 * As soon as we touch this place at all it is time to think.
-		 *
-		 * Now it protects single _advisory_ variable tcp_port_rover,
-		 * hence it is mostly useless.
-		 * Code will work nicely if we just delete it, but
-		 * I am afraid in contented case it will work not better or
-		 * even worse: another cpu just will hit the same bucket
-		 * and spin there.
-		 * So some cpu salt could remove both contention and
-		 * memory pingpong. Any ideas how to do this in a nice way?
-		 */
-		spin_lock(&tcp_portalloc_lock);
-		rover = tcp_port_rover;
-
-		do {
-			rover++;
-			if ((rover < low) || (rover > high))
-				rover = low;
-			head = &tcp_bhash[tcp_bhashfn(rover)];
-			spin_lock(&head->lock);		
-
-			/* Does not bother with rcv_saddr checks,
-			 * because the established check is already
-			 * unique enough.
-			 */
-			for (tb = head->chain; tb; tb = tb->next) {
-				if (tb->port == rover) {
-					BUG_TRAP(tb->owners != NULL);
-					if (tb->fastreuse >= 0)
-						goto next_port;
-					if (!__tcp_v4_check_established(sk, rover, &tw))
-						goto ok;
-					goto next_port;
-				}
-			}
-
-			tb = tcp_bucket_create(head, rover);
-			if (!tb) {
-				spin_unlock(&head->lock);
-				break;
-			}
-			tb->fastreuse = -1;
-			goto ok;
-
-		next_port:
-			spin_unlock(&head->lock);
-		} while (--remaining > 0);
-		tcp_port_rover = rover;
-		spin_unlock(&tcp_portalloc_lock);
-
-		local_bh_enable();
-
-		return -EADDRNOTAVAIL;
-
-	ok:
-		/* All locks still held and bhs disabled */
-		tcp_port_rover = rover;
-		spin_unlock(&tcp_portalloc_lock);
-
-		tcp_bind_hash(sk, tb, rover);
-		if (!sk->pprev) {
-			sk->sport = htons(rover);
-			__tcp_v4_hash(sk, 0);
-		}
-		spin_unlock(&head->lock);
-
-		if (tw) {
-			tcp_tw_deschedule(tw);
-			tcp_timewait_kill(tw);
-			tcp_tw_put(tw);
-		}
-
-		local_bh_enable();
-		return 0;
-	}
-
-	head  = &tcp_bhash[tcp_bhashfn(snum)];
-	tb  = (struct tcp_bind_bucket *)sk->prev;
-	spin_lock_bh(&head->lock);
-	if (tb->owners == sk && sk->bind_next == NULL) {
-		__tcp_v4_hash(sk, 0);
-		spin_unlock_bh(&head->lock);
-		return 0;
-	} else {
-		int ret;
-		spin_unlock(&head->lock);
-		/* No definite answer... Walk to established hash table */
-		ret = __tcp_v4_check_established(sk, snum, NULL);
-		local_bh_enable();
-		return ret;
-	}
-#else
-  return 0;
-#endif
-}
-
-/* This will initiate an outgoing connection. */
-int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct sockaddr_in *usin = (struct sockaddr_in *) uaddr;
-	struct rtable *rt;
-	u32 daddr, nexthop;
-	int tmp;
-	int err;
-
-	if (addr_len < sizeof(struct sockaddr_in))
-		return(-EINVAL);
-
-	if (usin->sin_family != AF_INET)
-		return(-EAFNOSUPPORT);
-
-	nexthop = daddr = usin->sin_addr.s_addr;
-	if (sk->protinfo.af_inet.opt && sk->protinfo.af_inet.opt->srr) {
-		if (daddr == 0)
-			return -EINVAL;
-		nexthop = sk->protinfo.af_inet.opt->faddr;
-	}
-
-	tmp = ip_route_connect(&rt, nexthop, sk->saddr,
-			       RT_CONN_FLAGS(sk), sk->bound_dev_if);
-	if (tmp < 0)
-		return tmp;
-
-	if (rt->rt_flags&(RTCF_MULTICAST|RTCF_BROADCAST)) {
-		ip_rt_put(rt);
-		return -ENETUNREACH;
-	}
-
-	__sk_dst_set(sk, &rt->u.dst);
-	sk->route_caps = rt->u.dst.dev->features;
-
-	if (!sk->protinfo.af_inet.opt || !sk->protinfo.af_inet.opt->srr)
-		daddr = rt->rt_dst;
-
-	if (!sk->saddr)
-		sk->saddr = rt->rt_src;
-	sk->rcv_saddr = sk->saddr;
-
-	if (tp->ts_recent_stamp && sk->daddr != daddr) {
-		/* Reset inherited state */
-		tp->ts_recent = 0;
-		tp->ts_recent_stamp = 0;
-		tp->write_seq = 0;
-	}
-
-	if (sysctl_tcp_tw_recycle &&
-	    !tp->ts_recent_stamp &&
-	    rt->rt_dst == daddr) {
-		struct inet_peer *peer = rt_get_peer(rt);
-
-		/* VJ's idea. We save last timestamp seen from
-		 * the destination in peer table, when entering state TIME-WAIT
-		 * and initialize ts_recent from it, when trying new connection.
-		 */
-
-		if (peer && peer->tcp_ts_stamp + TCP_PAWS_MSL >= xtime.tv_sec) {
-			tp->ts_recent_stamp = peer->tcp_ts_stamp;
-			tp->ts_recent = peer->tcp_ts;
-		}
-	}
-
-	sk->dport = usin->sin_port;
-	sk->daddr = daddr;
-
-	tp->ext_header_len = 0;
-	if (sk->protinfo.af_inet.opt)
-		tp->ext_header_len = sk->protinfo.af_inet.opt->optlen;
-
-	tp->mss_clamp = 536;
-
-	/* Socket identity is still unknown (sport may be zero).
-	 * However we set state to SYN-SENT and not releasing socket
-	 * lock select source port, enter ourselves into the hash tables and
-	 * complete initalization after this.
-	 */
-	tcp_set_state(sk, TCP_SYN_SENT);
-	err = tcp_v4_hash_connect(sk);
-	if (err)
-		goto failure;
-
-	if (!tp->write_seq)
-		tp->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
-							   sk->sport, usin->sin_port);
-
-	sk->protinfo.af_inet.id = tp->write_seq^jiffies;
-
-	err = tcp_connect(sk);
-	if (err)
-		goto failure;
-
-	return 0;
-
-failure:
-	tcp_set_state(sk, TCP_CLOSE);
-	__sk_dst_reset(sk);
-	sk->route_caps = 0;
-	sk->dport = 0;
-	return err;
-#else
-  return 0;
-#endif
-}
-
-static __inline__ int tcp_v4_iif(struct sk_buff *skb)
-{
-#if 0
-	return ((struct rtable*)skb->dst)->rt_iif;
-#else
-  return 0;
-#endif
-}
-
-static __inline__ unsigned tcp_v4_synq_hash(u32 raddr, u16 rport)
-{
-#if 0
-	unsigned h = raddr ^ rport;
-	h ^= h>>16;
-	h ^= h>>8;
-	return h&(TCP_SYNQ_HSIZE-1);
-#else
-  return 0;
-#endif
-}
-
-static struct open_request *tcp_v4_search_req(struct tcp_opt *tp, 
-					      struct open_request ***prevp,
-					      __u16 rport,
-					      __u32 raddr, __u32 laddr)
-{
-#if 0
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	struct open_request *req, **prev;  
-
-	for (prev = &lopt->syn_table[tcp_v4_synq_hash(raddr, rport)];
-	     (req = *prev) != NULL;
-	     prev = &req->dl_next) {
-		if (req->rmt_port == rport &&
-		    req->af.v4_req.rmt_addr == raddr &&
-		    req->af.v4_req.loc_addr == laddr &&
-		    TCP_INET_FAMILY(req->class->family)) {
-			BUG_TRAP(req->sk == NULL);
-			*prevp = prev;
-			return req; 
-		}
-	}
-
-	return NULL;
-#else
-  return NULL;
-#endif
-}
-
-static void tcp_v4_synq_add(struct sock *sk, struct open_request *req)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	unsigned h = tcp_v4_synq_hash(req->af.v4_req.rmt_addr, req->rmt_port);
-
-	req->expires = jiffies + TCP_TIMEOUT_INIT;
[truncated at 1000 lines; 1527 more skipped]

reactos/drivers/net/tcpip/transport/tcp
tcp_output.c removed after 1.2
diff -N tcp_output.c
--- tcp_output.c	24 Jul 2003 18:14:59 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,1549 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS TCP/IP protocol driver
- * FILE:        transport/tcp/tcp_output.c
- * PURPOSE:     Transmission Control Protocol
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- *   CSH 15-01-2003 Imported from linux kernel 2.4.20
- */
-
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		Implementation of the Transmission Control Protocol(TCP).
- *
- * Version:	$Id: tcp_output.c,v 1.2 2003/07/24 18:14:59 royce Exp $
- *
- * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
- *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Mark Evans, <evansmp@uhura.aston.ac.uk>
- *		Corey Minyard <wf-rch!minyard@relay.EU.net>
- *		Florian La Roche, <flla@stud.uni-sb.de>
- *		Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
- *		Linus Torvalds, <torvalds@cs.helsinki.fi>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
- *		Matthew Dillon, <dillon@apollo.west.oic.com>
- *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
- *		Jorge Cwik, <jorge@laser.satlink.net>
- */
-
-/*
- * Changes:	Pedro Roque	:	Retransmit queue handled by TCP.
- *				:	Fragmentation on mtu decrease
- *				:	Segment collapse on retransmit
- *				:	AF independence
- *
- *		Linus Torvalds	:	send_delayed_ack
- *		David S. Miller	:	Charge memory using the right skb
- *					during syn/ack processing.
- *		David S. Miller :	Output engine completely rewritten.
- *		Andrea Arcangeli:	SYNACK carry ts_recent in tsecr.
- *		Cacophonix Gaul :	draft-minshall-nagle-01
- *		J Hadi Salim	:	ECN support
- *
- */
-
-#if 0
-#include <net/tcp.h>
-
-#include <linux/compiler.h>
-#include <linux/smp_lock.h>
-#else
-#include "linux.h"
-#include "tcpcore.h"
-#endif
-
-/* People can turn this off for buggy TCP's found in printers etc. */
-int sysctl_tcp_retrans_collapse = 1;
-
-static __inline__
-void update_send_head(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
-{
-	tp->send_head = skb->next;
-	if (tp->send_head == (struct sk_buff *) &sk->write_queue)
-		tp->send_head = NULL;
-	tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
-	if (tp->packets_out++ == 0)
-		tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
-}
-
-/* SND.NXT, if window was not shrunk.
- * If window has been shrunk, what should we make? It is not clear at all.
- * Using SND.UNA we will fail to open window, SND.NXT is out of window. :-(
- * Anything in between SND.UNA...SND.UNA+SND.WND also can be already
- * invalid. OK, let's make this for now:
- */
-static __inline__ __u32 tcp_acceptable_seq(struct sock *sk, struct tcp_opt *tp)
-{
-	if (!before(tp->snd_una+tp->snd_wnd, tp->snd_nxt))
-		return tp->snd_nxt;
-	else
-		return tp->snd_una+tp->snd_wnd;
-}
-
-/* Calculate mss to advertise in SYN segment.
- * RFC1122, RFC1063, draft-ietf-tcpimpl-pmtud-01 state that:
- *
- * 1. It is independent of path mtu.
- * 2. Ideally, it is maximal possible segment size i.e. 65535-40.
- * 3. For IPv4 it is reasonable to calculate it from maximal MTU of
- *    attached devices, because some buggy hosts are confused by
- *    large MSS.
- * 4. We do not make 3, we advertise MSS, calculated from first
- *    hop device mtu, but allow to raise it to ip_rt_min_advmss.
- *    This may be overriden via information stored in routing table.
- * 5. Value 65535 for MSS is valid in IPv6 and means "as large as possible,
- *    probably even Jumbo".
- */
-static __u16 tcp_advertise_mss(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct dst_entry *dst = __sk_dst_get(sk);
-	int mss = tp->advmss;
-
-	if (dst && dst->advmss < mss) {
-		mss = dst->advmss;
-		tp->advmss = mss;
-	}
-
-	return (__u16)mss;
-#else
-  return 0;
-#endif
-}
-
-/* RFC2861. Reset CWND after idle period longer RTO to "restart window".
- * This is the first part of cwnd validation mechanism. */
-static void tcp_cwnd_restart(struct tcp_opt *tp)
-{
-#if 0
-	s32 delta = tcp_time_stamp - tp->lsndtime;
-	u32 restart_cwnd = tcp_init_cwnd(tp);
-	u32 cwnd = tp->snd_cwnd;
-
-	tp->snd_ssthresh = tcp_current_ssthresh(tp);
-	restart_cwnd = min(restart_cwnd, cwnd);
-
-	while ((delta -= tp->rto) > 0 && cwnd > restart_cwnd)
-		cwnd >>= 1;
-	tp->snd_cwnd = max(cwnd, restart_cwnd);
-	tp->snd_cwnd_stamp = tcp_time_stamp;
-	tp->snd_cwnd_used = 0;
-#endif
-}
-
-static __inline__ void tcp_event_data_sent(struct tcp_opt *tp, struct sk_buff *skb)
-{
-#if 0
-	u32 now = tcp_time_stamp;
-
-	if (!tp->packets_out && (s32)(now - tp->lsndtime) > tp->rto)
-		tcp_cwnd_restart(tp);
-
-	tp->lsndtime = now;
-
-	/* If it is a reply for ato after last received
-	 * packet, enter pingpong mode.
-	 */
-	if ((u32)(now - tp->ack.lrcvtime) < tp->ack.ato)
-		tp->ack.pingpong = 1;
-#endif
-}
-
-static __inline__ void tcp_event_ack_sent(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-
-	tcp_dec_quickack_mode(tp);
-	tcp_clear_xmit_timer(sk, TCP_TIME_DACK);
-#endif
-}
-
-/* Chose a new window to advertise, update state in tcp_opt for the
- * socket, and return result with RFC1323 scaling applied.  The return
- * value can be stuffed directly into th->window for an outgoing
- * frame.
- */
-static __inline__ u16 tcp_select_window(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	u32 cur_win = tcp_receive_window(tp);
-	u32 new_win = __tcp_select_window(sk);
-
-	/* Never shrink the offered window */
-	if(new_win < cur_win) {
-		/* Danger Will Robinson!
-		 * Don't update rcv_wup/rcv_wnd here or else
-		 * we will not be able to advertise a zero
-		 * window in time.  --DaveM
-		 *
-		 * Relax Will Robinson.
-		 */
-		new_win = cur_win;
-	}
-	tp->rcv_wnd = new_win;
-	tp->rcv_wup = tp->rcv_nxt;
-
-	/* RFC1323 scaling applied */
-	new_win >>= tp->rcv_wscale;
-
-	/* If we advertise zero window, disable fast path. */
-	if (new_win == 0)
-		tp->pred_flags = 0;
-
-	return new_win;
-#else
-  return 0;
-#endif
-}
-
-
-/* This routine actually transmits TCP packets queued in by
- * tcp_do_sendmsg().  This is used by both the initial
- * transmission and possible later retransmissions.
- * All SKB's seen here are completely headerless.  It is our
- * job to build the TCP header, and pass the packet down to
- * IP so it can do the same plus pass the packet off to the
- * device.
- *
- * We are working here with either a clone of the original
- * SKB, or a fresh unique copy made by the retransmit engine.
- */
-int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb)
-{
-#if 0
-	if(skb != NULL) {
-		struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-		struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
-		int tcp_header_size = tp->tcp_header_len;
-		struct tcphdr *th;
-		int sysctl_flags;
-		int err;
-
-#define SYSCTL_FLAG_TSTAMPS	0x1
-#define SYSCTL_FLAG_WSCALE	0x2
-#define SYSCTL_FLAG_SACK	0x4
-
-		sysctl_flags = 0;
-		if (tcb->flags & TCPCB_FLAG_SYN) {
-			tcp_header_size = sizeof(struct tcphdr) + TCPOLEN_MSS;
-			if(sysctl_tcp_timestamps) {
-				tcp_header_size += TCPOLEN_TSTAMP_ALIGNED;
-				sysctl_flags |= SYSCTL_FLAG_TSTAMPS;
-			}
-			if(sysctl_tcp_window_scaling) {
-				tcp_header_size += TCPOLEN_WSCALE_ALIGNED;
-				sysctl_flags |= SYSCTL_FLAG_WSCALE;
-			}
-			if(sysctl_tcp_sack) {
-				sysctl_flags |= SYSCTL_FLAG_SACK;
-				if(!(sysctl_flags & SYSCTL_FLAG_TSTAMPS))
-					tcp_header_size += TCPOLEN_SACKPERM_ALIGNED;
-			}
-		} else if (tp->eff_sacks) {
-			/* A SACK is 2 pad bytes, a 2 byte header, plus
-			 * 2 32-bit sequence numbers for each SACK block.
-			 */
-			tcp_header_size += (TCPOLEN_SACK_BASE_ALIGNED +
-					    (tp->eff_sacks * TCPOLEN_SACK_PERBLOCK));
-		}
-		th = (struct tcphdr *) skb_push(skb, tcp_header_size);
-		skb->h.th = th;
-		skb_set_owner_w(skb, sk);
-
-		/* Build TCP header and checksum it. */
-		th->source		= sk->sport;
-		th->dest		= sk->dport;
-		th->seq			= htonl(tcb->seq);
-		th->ack_seq		= htonl(tp->rcv_nxt);
-		*(((__u16 *)th) + 6)	= htons(((tcp_header_size >> 2) << 12) | tcb->flags);
-		if (tcb->flags & TCPCB_FLAG_SYN) {
-			/* RFC1323: The window in SYN & SYN/ACK segments
-			 * is never scaled.
-			 */
-			th->window	= htons(tp->rcv_wnd);
-		} else {
-			th->window	= htons(tcp_select_window(sk));
-		}
-		th->check		= 0;
-		th->urg_ptr		= 0;
-
-		if (tp->urg_mode &&
-		    between(tp->snd_up, tcb->seq+1, tcb->seq+0xFFFF)) {
-			th->urg_ptr		= htons(tp->snd_up-tcb->seq);
-			th->urg			= 1;
-		}
-
-		if (tcb->flags & TCPCB_FLAG_SYN) {
-			tcp_syn_build_options((__u32 *)(th + 1),
-					      tcp_advertise_mss(sk),
-					      (sysctl_flags & SYSCTL_FLAG_TSTAMPS),
-					      (sysctl_flags & SYSCTL_FLAG_SACK),
-					      (sysctl_flags & SYSCTL_FLAG_WSCALE),
-					      tp->rcv_wscale,
-					      tcb->when,
-		      			      tp->ts_recent);
-		} else {
-			tcp_build_and_update_options((__u32 *)(th + 1),
-						     tp, tcb->when);
-
-			TCP_ECN_send(sk, tp, skb, tcp_header_size);
-		}
-		tp->af_specific->send_check(sk, th, skb->len, skb);
-
-		if (tcb->flags & TCPCB_FLAG_ACK)
-			tcp_event_ack_sent(sk);
-
-		if (skb->len != tcp_header_size)
-			tcp_event_data_sent(tp, skb);
-
-		TCP_INC_STATS(TcpOutSegs);
-
-		err = tp->af_specific->queue_xmit(skb);
-		if (err <= 0)
-			return err;
-
-		tcp_enter_cwr(tp);
-
-		/* NET_XMIT_CN is special. It does not guarantee,
-		 * that this packet is lost. It tells that device
-		 * is about to start to drop packets or already
-		 * drops some packets of the same priority and
-		 * invokes us to send less aggressively.
-		 */
-		return err == NET_XMIT_CN ? 0 : err;
-	}
-	return -ENOBUFS;
-#undef SYSCTL_FLAG_TSTAMPS
-#undef SYSCTL_FLAG_WSCALE
-#undef SYSCTL_FLAG_SACK
-#else
-  return 0;
-#endif
-}
-
-
-/* This is the main buffer sending routine. We queue the buffer
- * and decide whether to queue or transmit now.
- *
- * NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames,
- * otherwise socket can stall.
- */
-void tcp_send_skb(struct sock *sk, struct sk_buff *skb, int force_queue, unsigned cur_mss)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-
-	/* Advance write_seq and place onto the write_queue. */
-	tp->write_seq = TCP_SKB_CB(skb)->end_seq;
-	__skb_queue_tail(&sk->write_queue, skb);
-	tcp_charge_skb(sk, skb);
-
-	if (!force_queue && tp->send_head == NULL && tcp_snd_test(tp, skb, cur_mss, tp->nonagle)) {
-		/* Send it out now. */
-		TCP_SKB_CB(skb)->when = tcp_time_stamp;
-		if (tcp_transmit_skb(sk, skb_clone(skb, sk->allocation)) == 0) {
-			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
-			tcp_minshall_update(tp, cur_mss, skb);
-			if (tp->packets_out++ == 0)
-				tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
-			return;
-		}
-	}
-	/* Queue it, remembering where we must start sending. */
-	if (tp->send_head == NULL)
-		tp->send_head = skb;
-#endif
-}
-
-/* Send _single_ skb sitting at the send head. This function requires
- * true push pending frames to setup probe timer etc.
- */
-void tcp_push_one(struct sock *sk, unsigned cur_mss)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct sk_buff *skb = tp->send_head;
-
-	if (tcp_snd_test(tp, skb, cur_mss, 1)) {
-		/* Send it out now. */
-		TCP_SKB_CB(skb)->when = tcp_time_stamp;
-		if (tcp_transmit_skb(sk, skb_clone(skb, sk->allocation)) == 0) {
-			tp->send_head = NULL;
-			tp->snd_nxt = TCP_SKB_CB(skb)->end_seq;
-			if (tp->packets_out++ == 0)
-				tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
-			return;
-		}
-	}
-#endif
-}
-
-/* Split fragmented skb to two parts at length len. */
-
-static void skb_split(struct sk_buff *skb, struct sk_buff *skb1, u32 len)
-{
-#if 0
-	int i;
-	int pos = skb->len - skb->data_len;
-
-	if (len < pos) {
-		/* Split line is inside header. */
-		memcpy(skb_put(skb1, pos-len), skb->data + len, pos-len);
-
-		/* And move data appendix as is. */
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
-			skb_shinfo(skb1)->frags[i] = skb_shinfo(skb)->frags[i];
-
-		skb_shinfo(skb1)->nr_frags = skb_shinfo(skb)->nr_frags;
-		skb_shinfo(skb)->nr_frags = 0;
-
-		skb1->data_len = skb->data_len;
-		skb1->len += skb1->data_len;
-		skb->data_len = 0;
-		skb->len = len;
-		skb->tail = skb->data+len;
-	} else {
-		int k = 0;
-		int nfrags = skb_shinfo(skb)->nr_frags;
-
-		/* Second chunk has no header, nothing to copy. */
-
-		skb_shinfo(skb)->nr_frags = 0;
-		skb1->len = skb1->data_len = skb->len - len;
-		skb->len = len;
-		skb->data_len = len - pos;
-
-		for (i=0; i<nfrags; i++) {
-			int size = skb_shinfo(skb)->frags[i].size;
-			if (pos + size > len) {
-				skb_shinfo(skb1)->frags[k] = skb_shinfo(skb)->frags[i];
-
-				if (pos < len) {
-					/* Split frag.
-					 * We have to variants in this case:
-					 * 1. Move all the frag to the second
-					 *    part, if it is possible. F.e.
-					 *    this approach is mandatory for TUX,
-					 *    where splitting is expensive.
-					 * 2. Split is accurately. We make this.
-					 */
-					get_page(skb_shinfo(skb)->frags[i].page);
-					skb_shinfo(skb1)->frags[0].page_offset += (len-pos);
-					skb_shinfo(skb1)->frags[0].size -= (len-pos);
-					skb_shinfo(skb)->frags[i].size = len-pos;
-					skb_shinfo(skb)->nr_frags++;
-				}
-				k++;
-			} else {
-				skb_shinfo(skb)->nr_frags++;
-			}
-			pos += size;
-		}
-		skb_shinfo(skb1)->nr_frags = k;
-	}
-#endif
-}
-
-/* Function to create two new TCP segments.  Shrinks the given segment
- * to the specified size and appends a new segment with the rest of the
- * packet to the list.  This won't be called frequently, I hope. 
- * Remember, these are still headerless SKBs at this point.
- */
-static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	struct sk_buff *buff;
-	int nsize = skb->len - len;
-	u16 flags;
-
-	if (skb_cloned(skb) &&
-	    skb_is_nonlinear(skb) &&
-	    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
-		return -ENOMEM;
-
-	/* Get a new skb... force flag on. */
-	buff = tcp_alloc_skb(sk, nsize, GFP_ATOMIC);
-	if (buff == NULL)
-		return -ENOMEM; /* We'll just try again later. */
-	tcp_charge_skb(sk, buff);
-
-	/* Correct the sequence numbers. */
-	TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
-	TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq;
-	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq;
-
-	/* PSH and FIN should only be set in the second packet. */
-	flags = TCP_SKB_CB(skb)->flags;
-	TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH);
-	TCP_SKB_CB(buff)->flags = flags;
-	TCP_SKB_CB(buff)->sacked = TCP_SKB_CB(skb)->sacked&(TCPCB_LOST|TCPCB_EVER_RETRANS|TCPCB_AT_TAIL);
-	if (TCP_SKB_CB(buff)->sacked&TCPCB_LOST) {
-		tp->lost_out++;
-		tp->left_out++;
-	}
-	TCP_SKB_CB(skb)->sacked &= ~TCPCB_AT_TAIL;
-
-	if (!skb_shinfo(skb)->nr_frags && skb->ip_summed != CHECKSUM_HW) {
-		/* Copy and checksum data tail into the new buffer. */
-		buff->csum = csum_partial_copy_nocheck(skb->data + len, skb_put(buff, nsize),
-						       nsize, 0);
-
-		skb_trim(skb, len);
-
-		skb->csum = csum_block_sub(skb->csum, buff->csum, len);
-	} else {
-		skb->ip_summed = CHECKSUM_HW;
-		skb_split(skb, buff, len);
-	}
-
-	buff->ip_summed = skb->ip_summed;
-
-	/* Looks stupid, but our code really uses when of
-	 * skbs, which it never sent before. --ANK
-	 */
-	TCP_SKB_CB(buff)->when = TCP_SKB_CB(skb)->when;
-
-	/* Link BUFF into the send queue. */
-	__skb_append(skb, buff);
-
-	return 0;
-#else
-  return 0;
-#endif
-}
-
-/* This function synchronize snd mss to current pmtu/exthdr set.
-
-   tp->user_mss is mss set by user by TCP_MAXSEG. It does NOT counts
-   for TCP options, but includes only bare TCP header.
-
-   tp->mss_clamp is mss negotiated at connection setup.
-   It is minumum of user_mss and mss received with SYN.
-   It also does not include TCP options.
-
-   tp->pmtu_cookie is last pmtu, seen by this function.
-
-   tp->mss_cache is current effective sending mss, including
-   all tcp options except for SACKs. It is evaluated,
-   taking into account current pmtu, but never exceeds
-   tp->mss_clamp.
-
-   NOTE1. rfc1122 clearly states that advertised MSS
-   DOES NOT include either tcp or ip options.
-
-   NOTE2. tp->pmtu_cookie and tp->mss_cache are READ ONLY outside
-   this function.			--ANK (980731)
- */
-
-int tcp_sync_mss(struct sock *sk, u32 pmtu)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	int mss_now;
-
-	/* Calculate base mss without TCP options:
-	   It is MMS_S - sizeof(tcphdr) of rfc1122
-	 */
-
-	mss_now = pmtu - tp->af_specific->net_header_len - sizeof(struct tcphdr);
-
-	/* Clamp it (mss_clamp does not include tcp options) */
-	if (mss_now > tp->mss_clamp)
-		mss_now = tp->mss_clamp;
-
-	/* Now subtract optional transport overhead */
-	mss_now -= tp->ext_header_len;
-
-	/* Then reserve room for full set of TCP options and 8 bytes of data */
-	if (mss_now < 48)
-		mss_now = 48;
-
-	/* Now subtract TCP options size, not including SACKs */
-	mss_now -= tp->tcp_header_len - sizeof(struct tcphdr);
-
-	/* Bound mss with half of window */
-	if (tp->max_window && mss_now > (tp->max_window>>1))
-		mss_now = max((tp->max_window>>1), 68U - tp->tcp_header_len);
-
-	/* And store cached results */
-	tp->pmtu_cookie = pmtu;
-	tp->mss_cache = mss_now;
-	return mss_now;
-#else
-  return 0;
-#endif
-}
-
-
-/* This routine writes packets to the network.  It advances the
- * send_head.  This happens as incoming acks open up the remote
- * window for us.
- *
- * Returns 1, if no segments are in flight and we have queued segments, but
- * cannot send anything now because of SWS or another problem.
- */
-int tcp_write_xmit(struct sock *sk, int nonagle)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	unsigned int mss_now;
-
-	/* If we are closed, the bytes will have to remain here.
-	 * In time closedown will finish, we empty the write queue and all
-	 * will be happy.
-	 */
-	if(sk->state != TCP_CLOSE) {
-		struct sk_buff *skb;
-		int sent_pkts = 0;
-
-		/* Account for SACKS, we may need to fragment due to this.
-		 * It is just like the real MSS changing on us midstream.
-		 * We also handle things correctly when the user adds some
-		 * IP options mid-stream.  Silly to do, but cover it.
-		 */
-		mss_now = tcp_current_mss(sk); 
-
-		while((skb = tp->send_head) &&
-		      tcp_snd_test(tp, skb, mss_now, tcp_skb_is_last(sk, skb) ? nonagle : 1)) {
-			if (skb->len > mss_now) {
-				if (tcp_fragment(sk, skb, mss_now))
-					break;
-			}
-
-			TCP_SKB_CB(skb)->when = tcp_time_stamp;
-			if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))
-				break;
-			/* Advance the send_head.  This one is sent out. */
-			update_send_head(sk, tp, skb);
-			tcp_minshall_update(tp, mss_now, skb);
-			sent_pkts = 1;
-		}
-
-		if (sent_pkts) {
-			tcp_cwnd_validate(sk, tp);
-			return 0;
-		}
-
-		return !tp->packets_out && tp->send_head;
-	}
-	return 0;
-#else
-  return 0;
-#endif
-}
-
-/* This function returns the amount that we can raise the
- * usable window based on the following constraints
- *  
- * 1. The window can never be shrunk once it is offered (RFC 793)
- * 2. We limit memory per socket
- *
- * RFC 1122:
- * "the suggested [SWS] avoidance algorithm for the receiver is to keep
- *  RECV.NEXT + RCV.WIN fixed until:
- *  RCV.BUFF - RCV.USER - RCV.WINDOW >= min(1/2 RCV.BUFF, MSS)"
- *
- * i.e. don't raise the right edge of the window until you can raise
- * it at least MSS bytes.
- *
- * Unfortunately, the recommended algorithm breaks header prediction,
- * since header prediction assumes th->window stays fixed.
- *
- * Strictly speaking, keeping th->window fixed violates the receiver
- * side SWS prevention criteria. The problem is that under this rule
- * a stream of single byte packets will cause the right side of the
- * window to always advance by a single byte.
- * 
- * Of course, if the sender implements sender side SWS prevention
- * then this will not be a problem.
- * 
- * BSD seems to make the following compromise:
- * 
- *	If the free space is less than the 1/4 of the maximum
- *	space available and the free space is less than 1/2 mss,
- *	then set the window to 0.
- *	[ Actually, bsd uses MSS and 1/4 of maximal _window_ ]
- *	Otherwise, just prevent the window from shrinking
- *	and from being larger than the largest representable value.
- *
- * This prevents incremental opening of the window in the regime
- * where TCP is limited by the speed of the reader side taking
- * data out of the TCP receive queue. It does nothing about
- * those cases where the window is constrained on the sender side
- * because the pipeline is full.
- *
- * BSD also seems to "accidentally" limit itself to windows that are a
- * multiple of MSS, at least until the free space gets quite small.
- * This would appear to be a side effect of the mbuf implementation.
- * Combining these two algorithms results in the observed behavior
- * of having a fixed window size at almost all times.
- *
- * Below we obtain similar behavior by forcing the offered window to
- * a multiple of the mss when it is feasible to do so.
- *
- * Note, we don't "adjust" for TIMESTAMP or SACK option bytes.
- * Regular options like TIMESTAMP are taken into account.
- */
-u32 __tcp_select_window(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	/* MSS for the peer's data.  Previous verions used mss_clamp
-	 * here.  I don't know if the value based on our guesses
-	 * of peer's MSS is better for the performance.  It's more correct
-	 * but may be worse for the performance because of rcv_mss
-	 * fluctuations.  --SAW  1998/11/1
-	 */
-	int mss = tp->ack.rcv_mss;
-	int free_space = tcp_space(sk);
-	int full_space = min_t(int, tp->window_clamp, tcp_full_space(sk));
-	int window;
-
-	if (mss > full_space)
-		mss = full_space; 
-
-	if (free_space < full_space/2) {
-		tp->ack.quick = 0;
-
-		if (tcp_memory_pressure)
-			tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U*tp->advmss);
-
-		if (free_space < mss)
-			return 0;
-	}
-
-	if (free_space > tp->rcv_ssthresh)
-		free_space = tp->rcv_ssthresh;
-
-	/* Get the largest window that is a nice multiple of mss.
-	 * Window clamp already applied above.
-	 * If our current window offering is within 1 mss of the
-	 * free space we just keep it. This prevents the divide
-	 * and multiply from happening most of the time.
-	 * We also don't do any window rounding when the free space
-	 * is too small.
-	 */
-	window = tp->rcv_wnd;
-	if (window <= free_space - mss || window > free_space)
-		window = (free_space/mss)*mss;
-
-	return window;
-#else
-  return 0;
-#endif
-}
-
-/* Attempt to collapse two adjacent SKB's during retransmission. */
-static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb, int mss_now)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	struct sk_buff *next_skb = skb->next;
-
-	/* The first test we must make is that neither of these two
-	 * SKB's are still referenced by someone else.
-	 */
-	if(!skb_cloned(skb) && !skb_cloned(next_skb)) {
-		int skb_size = skb->len, next_skb_size = next_skb->len;
-		u16 flags = TCP_SKB_CB(skb)->flags;
-
-		/* Also punt if next skb has been SACK'd. */
-		if(TCP_SKB_CB(next_skb)->sacked & TCPCB_SACKED_ACKED)
-			return;
-
-		/* Next skb is out of window. */
-		if (after(TCP_SKB_CB(next_skb)->end_seq, tp->snd_una+tp->snd_wnd))
-			return;
-
-		/* Punt if not enough space exists in the first SKB for
-		 * the data in the second, or the total combined payload
-		 * would exceed the MSS.
-		 */
-		if ((next_skb_size > skb_tailroom(skb)) ||
-		    ((skb_size + next_skb_size) > mss_now))
-			return;
-
-		/* Ok.  We will be able to collapse the packet. */
-		__skb_unlink(next_skb, next_skb->list);
-
-		if (next_skb->ip_summed == CHECKSUM_HW)
-			skb->ip_summed = CHECKSUM_HW;
-
-		if (skb->ip_summed != CHECKSUM_HW) {
-			memcpy(skb_put(skb, next_skb_size), next_skb->data, next_skb_size);
-			skb->csum = csum_block_add(skb->csum, next_skb->csum, skb_size);
-		}
-
-		/* Update sequence range on original skb. */
-		TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(next_skb)->end_seq;
-
-		/* Merge over control information. */
-		flags |= TCP_SKB_CB(next_skb)->flags; /* This moves PSH/FIN etc. over */
-		TCP_SKB_CB(skb)->flags = flags;
-
-		/* All done, get rid of second SKB and account for it so
-		 * packet counting does not break.
-		 */
-		TCP_SKB_CB(skb)->sacked |= TCP_SKB_CB(next_skb)->sacked&(TCPCB_EVER_RETRANS|TCPCB_AT_TAIL);
-		if (TCP_SKB_CB(next_skb)->sacked&TCPCB_SACKED_RETRANS)
-			tp->retrans_out--;
-		if (TCP_SKB_CB(next_skb)->sacked&TCPCB_LOST) {
-			tp->lost_out--;
-			tp->left_out--;
-		}
-		/* Reno case is special. Sigh... */
-		if (!tp->sack_ok && tp->sacked_out) {
-			tp->sacked_out--;
-			tp->left_out--;
-		}
-
-		/* Not quite right: it can be > snd.fack, but
-		 * it is better to underestimate fackets.
-		 */
-		if (tp->fackets_out)
-			tp->fackets_out--;
-		tcp_free_skb(sk, next_skb);
-		tp->packets_out--;
-	}
-#endif
-}
-
-/* Do a simple retransmit without using the backoff mechanisms in
- * tcp_timer. This is used for path mtu discovery. 
- * The socket is already locked here.
- */ 
-void tcp_simple_retransmit(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct sk_buff *skb;
-	unsigned int mss = tcp_current_mss(sk);
-	int lost = 0;
-
-	for_retrans_queue(skb, sk, tp) {
-		if (skb->len > mss && 
-		    !(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED)) {
-			if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) {
-				TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
-				tp->retrans_out--;
-			}
-			if (!(TCP_SKB_CB(skb)->sacked&TCPCB_LOST)) {
-				TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
-				tp->lost_out++;
-				lost = 1;
-			}
-		}
-	}
-
-	if (!lost)
-		return;
-
-	tcp_sync_left_out(tp);
-
- 	/* Don't muck with the congestion window here.
-	 * Reason is that we do not increase amount of _data_
-	 * in network, but units changed and effective
-	 * cwnd/ssthresh really reduced now.
-	 */
-	if (tp->ca_state != TCP_CA_Loss) {
-		tp->high_seq = tp->snd_nxt;
-		tp->snd_ssthresh = tcp_current_ssthresh(tp);
-		tp->prior_ssthresh = 0;
-		tp->undo_marker = 0;
-		tp->ca_state = TCP_CA_Loss;
-	}
-	tcp_xmit_retransmit_queue(sk);
-#endif
-}
-
-/* This retransmits one SKB.  Policy decisions and retransmit queue
- * state updates are done by the caller.  Returns non-zero if an
- * error occurred which prevented the send.
- */
-int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	unsigned int cur_mss = tcp_current_mss(sk);
-	int err;
-
-	/* Do not sent more than we queued. 1/4 is reserved for possible
-	 * copying overhead: frgagmentation, tunneling, mangling etc.
-	 */
-	if (atomic_read(&sk->wmem_alloc) > min(sk->wmem_queued+(sk->wmem_queued>>2),sk->sndbuf))
-		return -EAGAIN;
-
-	/* If receiver has shrunk his window, and skb is out of
-	 * new window, do not retransmit it. The exception is the
-	 * case, when window is shrunk to zero. In this case
-	 * our retransmit serves as a zero window probe.
-	 */
-	if (!before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd)
-	    && TCP_SKB_CB(skb)->seq != tp->snd_una)
-		return -EAGAIN;
-
-	if(skb->len > cur_mss) {
-		if(tcp_fragment(sk, skb, cur_mss))
-			return -ENOMEM; /* We'll try again later. */
-
-		/* New SKB created, account for it. */
-		tp->packets_out++;
-	}
-
-	/* Collapse two adjacent packets if worthwhile and we can. */
-	if(!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) &&
-	   (skb->len < (cur_mss >> 1)) &&
-	   (skb->next != tp->send_head) &&
-	   (skb->next != (struct sk_buff *)&sk->write_queue) &&
-	   (skb_shinfo(skb)->nr_frags == 0 && skb_shinfo(skb->next)->nr_frags == 0) &&
-	   (sysctl_tcp_retrans_collapse != 0))
-		tcp_retrans_try_collapse(sk, skb, cur_mss);
-
-	if(tp->af_specific->rebuild_header(sk))
-		return -EHOSTUNREACH; /* Routing failure or similar. */
-
-	/* Some Solaris stacks overoptimize and ignore the FIN on a
-	 * retransmit when old data is attached.  So strip it off
-	 * since it is cheap to do so and saves bytes on the network.
-	 */
-	if(skb->len > 0 &&
-	   (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) &&
-	   tp->snd_una == (TCP_SKB_CB(skb)->end_seq - 1)) {
-		if (!pskb_trim(skb, 0)) {
-			TCP_SKB_CB(skb)->seq = TCP_SKB_CB(skb)->end_seq - 1;
-			skb->ip_summed = CHECKSUM_NONE;
-			skb->csum = 0;
-		}
-	}
-
-	/* Make a copy, if the first transmission SKB clone we made
-	 * is still in somebody's hands, else make a clone.
-	 */
-	TCP_SKB_CB(skb)->when = tcp_time_stamp;
-
-	err = tcp_transmit_skb(sk, (skb_cloned(skb) ?
-				    pskb_copy(skb, GFP_ATOMIC):
-				    skb_clone(skb, GFP_ATOMIC)));
-
-	if (err == 0) {
-		/* Update global TCP statistics. */
-		TCP_INC_STATS(TcpRetransSegs);
-
-#if FASTRETRANS_DEBUG > 0
-		if (TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_RETRANS) {
-			if (net_ratelimit())
-				printk(KERN_DEBUG "retrans_out leaked.\n");
-		}
-#endif
-		TCP_SKB_CB(skb)->sacked |= TCPCB_RETRANS;
-		tp->retrans_out++;
-
-		/* Save stamp of the first retransmit. */
-		if (!tp->retrans_stamp)
-			tp->retrans_stamp = TCP_SKB_CB(skb)->when;
-
-		tp->undo_retrans++;
-
-		/* snd_nxt is stored to detect loss of retransmitted segment,
-		 * see tcp_input.c tcp_sacktag_write_queue().
-		 */
-		TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt;
-	}
-	return err;
-#else
-  return 0;
-#endif
-}
-
-/* This gets called after a retransmit timeout, and the initially
- * retransmitted data is acknowledged.  It tries to continue
- * resending the rest of the retransmit queue, until either
- * we've sent it all or the congestion window limit is reached.
- * If doing SACK, the first ACK which comes back for a timeout
- * based retransmit packet might feed us FACK information again.
- * If so, we use it to avoid unnecessarily retransmissions.
- */
-void tcp_xmit_retransmit_queue(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct sk_buff *skb;
-	int packet_cnt = tp->lost_out;
-
-	/* First pass: retransmit lost packets. */
-	if (packet_cnt) {
-		for_retrans_queue(skb, sk, tp) {
-			__u8 sacked = TCP_SKB_CB(skb)->sacked;
-
-			if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)
-				return;
-
-			if (sacked&TCPCB_LOST) {
-				if (!(sacked&(TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) {
-					if (tcp_retransmit_skb(sk, skb))
-						return;
-					if (tp->ca_state != TCP_CA_Loss)
-						NET_INC_STATS_BH(TCPFastRetrans);
-					else
-						NET_INC_STATS_BH(TCPSlowStartRetrans);
[truncated at 1000 lines; 553 more skipped]

reactos/drivers/net/tcpip/transport/tcp
tcp_timer.c removed after 1.1
diff -N tcp_timer.c
--- tcp_timer.c	15 Jan 2003 21:57:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,702 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS TCP/IP protocol driver
- * FILE:        transport/tcp/tcp_input.c
- * PURPOSE:     Transmission Control Protocol
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- *   CSH 15-01-2003 Imported from linux kernel 2.4.20
- */
-
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		Implementation of the Transmission Control Protocol(TCP).
- *
- * Version:	$Id: tcp_timer.c,v 1.1 2003/01/15 21:57:31 chorns Exp $
- *
- * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
- *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Mark Evans, <evansmp@uhura.aston.ac.uk>
- *		Corey Minyard <wf-rch!minyard@relay.EU.net>
- *		Florian La Roche, <flla@stud.uni-sb.de>
- *		Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
- *		Linus Torvalds, <torvalds@cs.helsinki.fi>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
- *		Matthew Dillon, <dillon@apollo.west.oic.com>
- *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
- *		Jorge Cwik, <jorge@laser.satlink.net>
- */
-
-#if 0
-#include <net/tcp.h>
-#else
-#include "linux.h"
-#include "tcpcore.h"
-#endif
-
-int sysctl_tcp_syn_retries = TCP_SYN_RETRIES; 
-int sysctl_tcp_synack_retries = TCP_SYNACK_RETRIES; 
-//int sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME;
-int sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES;
-//int sysctl_tcp_keepalive_intvl = TCP_KEEPALIVE_INTVL;
-int sysctl_tcp_retries1 = TCP_RETR1;
-int sysctl_tcp_retries2 = TCP_RETR2;
-int sysctl_tcp_orphan_retries;
-
-static void tcp_write_timer(unsigned long);
-static void tcp_delack_timer(unsigned long);
-static void tcp_keepalive_timer (unsigned long data);
-
-//const char timer_bug_msg[] = KERN_DEBUG "tcpbug: unknown timer value\n";
-
-/*
- * Using different timers for retransmit, delayed acks and probes
- * We may wish use just one timer maintaining a list of expire jiffies 
- * to optimize.
- */
-
-void tcp_init_xmit_timers(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-
-	init_timer(&tp->retransmit_timer);
-	tp->retransmit_timer.function=&tcp_write_timer;
-	tp->retransmit_timer.data = (unsigned long) sk;
-	tp->pending = 0;
-
-	init_timer(&tp->delack_timer);
-	tp->delack_timer.function=&tcp_delack_timer;
-	tp->delack_timer.data = (unsigned long) sk;
-	tp->ack.pending = 0;
-
-	init_timer(&sk->timer);
-	sk->timer.function=&tcp_keepalive_timer;
-	sk->timer.data = (unsigned long) sk;
-#endif
-}
-
-void tcp_clear_xmit_timers(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-
-	tp->pending = 0;
-	if (timer_pending(&tp->retransmit_timer) &&
-	    del_timer(&tp->retransmit_timer))
-		__sock_put(sk);
-
-	tp->ack.pending = 0;
-	tp->ack.blocked = 0;
-	if (timer_pending(&tp->delack_timer) &&
-	    del_timer(&tp->delack_timer))
-		__sock_put(sk);
-
-	if(timer_pending(&sk->timer) && del_timer(&sk->timer))
-		__sock_put(sk);
-#endif
-}
-
-static void tcp_write_err(struct sock *sk)
-{
-#if 0
-	sk->err = sk->err_soft ? : ETIMEDOUT;
-	sk->error_report(sk);
-
-	tcp_done(sk);
-	NET_INC_STATS_BH(TCPAbortOnTimeout);
-#endif
-}
-
-/* Do not allow orphaned sockets to eat all our resources.
- * This is direct violation of TCP specs, but it is required
- * to prevent DoS attacks. It is called when a retransmission timeout
- * or zero probe timeout occurs on orphaned socket.
- *
- * Criterium is still not confirmed experimentally and may change.
- * We kill the socket, if:
- * 1. If number of orphaned sockets exceeds an administratively configured
- *    limit.
- * 2. If we have strong memory pressure.
- */
-static int tcp_out_of_resources(struct sock *sk, int do_reset)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	int orphans = atomic_read(&tcp_orphan_count);
-
-	/* If peer does not open window for long time, or did not transmit 
-	 * anything for long time, penalize it. */
-	if ((s32)(tcp_time_stamp - tp->lsndtime) > 2*TCP_RTO_MAX || !do_reset)
-		orphans <<= 1;
-
-	/* If some dubious ICMP arrived, penalize even more. */
-	if (sk->err_soft)
-		orphans <<= 1;
-
-	if (orphans >= sysctl_tcp_max_orphans ||
-	    (sk->wmem_queued > SOCK_MIN_SNDBUF &&
-	     atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2])) {
-		if (net_ratelimit())
-			printk(KERN_INFO "Out of socket memory\n");
-
-		/* Catch exceptional cases, when connection requires reset.
-		 *      1. Last segment was sent recently. */
-		if ((s32)(tcp_time_stamp - tp->lsndtime) <= TCP_TIMEWAIT_LEN ||
-		    /*  2. Window is closed. */
-		    (!tp->snd_wnd && !tp->packets_out))
-			do_reset = 1;
-		if (do_reset)
-			tcp_send_active_reset(sk, GFP_ATOMIC);
-		tcp_done(sk);
-		NET_INC_STATS_BH(TCPAbortOnMemory);
-		return 1;
-	}
-	return 0;
-#else
-	return 0;
-#endif
-}
-
-/* Calculate maximal number or retries on an orphaned socket. */
-static int tcp_orphan_retries(struct sock *sk, int alive)
-{
-#if 0
-	int retries = sysctl_tcp_orphan_retries; /* May be zero. */
-
-	/* We know from an ICMP that something is wrong. */
-	if (sk->err_soft && !alive)
-		retries = 0;
-
-	/* However, if socket sent something recently, select some safe
-	 * number of retries. 8 corresponds to >100 seconds with minimal
-	 * RTO of 200msec. */
-	if (retries == 0 && alive)
-		retries = 8;
-	return retries;
-#else
-	return 0;
-#endif
-}
-
-/* A write timeout has occurred. Process the after effects. */
-static int tcp_write_timeout(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	int retry_until;
-
-	if ((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV)) {
-		if (tp->retransmits)
-			dst_negative_advice(&sk->dst_cache);
-		retry_until = tp->syn_retries ? : sysctl_tcp_syn_retries;
-	} else {
-		if (tp->retransmits >= sysctl_tcp_retries1) {
-			/* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu black
-			   hole detection. :-(
-
-			   It is place to make it. It is not made. I do not want
-			   to make it. It is disguisting. It does not work in any
-			   case. Let me to cite the same draft, which requires for
-			   us to implement this:
-
-   "The one security concern raised by this memo is that ICMP black holes
-   are often caused by over-zealous security administrators who block
-   all ICMP messages.  It is vitally important that those who design and
-   deploy security systems understand the impact of strict filtering on
-   upper-layer protocols.  The safest web site in the world is worthless
-   if most TCP implementations cannot transfer data from it.  It would
-   be far nicer to have all of the black holes fixed rather than fixing
-   all of the TCP implementations."
-
-                           Golden words :-).
-		   */
-
-			dst_negative_advice(&sk->dst_cache);
-		}
-
-		retry_until = sysctl_tcp_retries2;
-		if (sk->dead) {
-			int alive = (tp->rto < TCP_RTO_MAX);
- 
-			retry_until = tcp_orphan_retries(sk, alive);
-
-			if (tcp_out_of_resources(sk, alive || tp->retransmits < retry_until))
-				return 1;
-		}
-	}
-
-	if (tp->retransmits >= retry_until) {
-		/* Has it gone just too far? */
-		tcp_write_err(sk);
-		return 1;
-	}
-	return 0;
-#else
-	return 0;
-#endif
-}
-
-static void tcp_delack_timer(unsigned long data)
-{
-#if 0
-	struct sock *sk = (struct sock*)data;
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-
-	bh_lock_sock(sk);
-	if (sk->lock.users) {
-		/* Try again later. */
-		tp->ack.blocked = 1;
-		NET_INC_STATS_BH(DelayedACKLocked);
-		if (!mod_timer(&tp->delack_timer, jiffies + TCP_DELACK_MIN))
-			sock_hold(sk);
-		goto out_unlock;
-	}
-
-	tcp_mem_reclaim(sk);
-
-	if (sk->state == TCP_CLOSE || !(tp->ack.pending&TCP_ACK_TIMER))
-		goto out;
-
-	if ((long)(tp->ack.timeout - jiffies) > 0) {
-		if (!mod_timer(&tp->delack_timer, tp->ack.timeout))
-			sock_hold(sk);
-		goto out;
-	}
-	tp->ack.pending &= ~TCP_ACK_TIMER;
-
-	if (skb_queue_len(&tp->ucopy.prequeue)) {
-		struct sk_buff *skb;
-
-		net_statistics[smp_processor_id()*2].TCPSchedulerFailed += skb_queue_len(&tp->ucopy.prequeue);
-
-		while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL)
-			sk->backlog_rcv(sk, skb);
-
-		tp->ucopy.memory = 0;
-	}
-
-	if (tcp_ack_scheduled(tp)) {
-		if (!tp->ack.pingpong) {
-			/* Delayed ACK missed: inflate ATO. */
-			tp->ack.ato = min(tp->ack.ato << 1, tp->rto);
-		} else {
-			/* Delayed ACK missed: leave pingpong mode and
-			 * deflate ATO.
-			 */
-			tp->ack.pingpong = 0;
-			tp->ack.ato = TCP_ATO_MIN;
-		}
-		tcp_send_ack(sk);
-		NET_INC_STATS_BH(DelayedACKs);
-	}
-	TCP_CHECK_TIMER(sk);
-
-out:
-	if (tcp_memory_pressure)
-		tcp_mem_reclaim(sk);
-out_unlock:
-	bh_unlock_sock(sk);
-	sock_put(sk);
-#endif
-}
-
-static void tcp_probe_timer(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	int max_probes;
-
-	if (tp->packets_out || !tp->send_head) {
-		tp->probes_out = 0;
-		return;
-	}
-
-	/* *WARNING* RFC 1122 forbids this
-	 *
-	 * It doesn't AFAIK, because we kill the retransmit timer -AK
-	 *
-	 * FIXME: We ought not to do it, Solaris 2.5 actually has fixing
-	 * this behaviour in Solaris down as a bug fix. [AC]
-	 *
-	 * Let me to explain. probes_out is zeroed by incoming ACKs
-	 * even if they advertise zero window. Hence, connection is killed only
-	 * if we received no ACKs for normal connection timeout. It is not killed
-	 * only because window stays zero for some time, window may be zero
-	 * until armageddon and even later. We are in full accordance
-	 * with RFCs, only probe timer combines both retransmission timeout
-	 * and probe timeout in one bottle.				--ANK
-	 */
-	max_probes = sysctl_tcp_retries2;
-
-	if (sk->dead) {
-		int alive = ((tp->rto<<tp->backoff) < TCP_RTO_MAX);
- 
-		max_probes = tcp_orphan_retries(sk, alive);
-
-		if (tcp_out_of_resources(sk, alive || tp->probes_out <= max_probes))
-			return;
-	}
-
-	if (tp->probes_out > max_probes) {
-		tcp_write_err(sk);
-	} else {
-		/* Only send another probe if we didn't close things up. */
-		tcp_send_probe0(sk);
-	}
-#endif
-}
-
-/*
- *	The TCP retransmit timer.
- */
-
-static void tcp_retransmit_timer(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-
-	if (tp->packets_out == 0)
-		goto out;
-
-	BUG_TRAP(!skb_queue_empty(&sk->write_queue));
-
-	if (tp->snd_wnd == 0 && !sk->dead &&
-	    !((1<<sk->state)&(TCPF_SYN_SENT|TCPF_SYN_RECV))) {
-		/* Receiver dastardly shrinks window. Our retransmits
-		 * become zero probes, but we should not timeout this
-		 * connection. If the socket is an orphan, time it out,
-		 * we cannot allow such beasts to hang infinitely.
-		 */
-#ifdef TCP_DEBUG
-		if (net_ratelimit())
-			printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
-			       NIPQUAD(sk->daddr), htons(sk->dport), sk->num,
-			       tp->snd_una, tp->snd_nxt);
-#endif
-		if (tcp_time_stamp - tp->rcv_tstamp > TCP_RTO_MAX) {
-			tcp_write_err(sk);
-			goto out;
-		}
-		tcp_enter_loss(sk, 0);
-		tcp_retransmit_skb(sk, skb_peek(&sk->write_queue));
-		__sk_dst_reset(sk);
-		goto out_reset_timer;
-	}
-
-	if (tcp_write_timeout(sk))
-		goto out;
-
-	if (tp->retransmits == 0) {
-		if (tp->ca_state == TCP_CA_Disorder || tp->ca_state == TCP_CA_Recovery) {
-			if (tp->sack_ok) {
-				if (tp->ca_state == TCP_CA_Recovery)
-					NET_INC_STATS_BH(TCPSackRecoveryFail);
-				else
-					NET_INC_STATS_BH(TCPSackFailures);
-			} else {
-				if (tp->ca_state == TCP_CA_Recovery)
-					NET_INC_STATS_BH(TCPRenoRecoveryFail);
-				else
-					NET_INC_STATS_BH(TCPRenoFailures);
-			}
-		} else if (tp->ca_state == TCP_CA_Loss) {
-			NET_INC_STATS_BH(TCPLossFailures);
-		} else {
-			NET_INC_STATS_BH(TCPTimeouts);
-		}
-	}
-
-	tcp_enter_loss(sk, 0);
-
-	if (tcp_retransmit_skb(sk, skb_peek(&sk->write_queue)) > 0) {
-		/* Retransmission failed because of local congestion,
-		 * do not backoff.
-		 */
-		if (!tp->retransmits)
-			tp->retransmits=1;
-		tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS,
-				     min(tp->rto, TCP_RESOURCE_PROBE_INTERVAL));
-		goto out;
-	}
-
-	/* Increase the timeout each time we retransmit.  Note that
-	 * we do not increase the rtt estimate.  rto is initialized
-	 * from rtt, but increases here.  Jacobson (SIGCOMM 88) suggests
-	 * that doubling rto each time is the least we can get away with.
-	 * In KA9Q, Karn uses this for the first few times, and then
-	 * goes to quadratic.  netBSD doubles, but only goes up to *64,
-	 * and clamps at 1 to 64 sec afterwards.  Note that 120 sec is
-	 * defined in the protocol as the maximum possible RTT.  I guess
-	 * we'll have to use something other than TCP to talk to the
-	 * University of Mars.
-	 *
-	 * PAWS allows us longer timeouts and large windows, so once
-	 * implemented ftp to mars will work nicely. We will have to fix
-	 * the 120 second clamps though!
-	 */
-	tp->backoff++;
-	tp->retransmits++;
-
-out_reset_timer:
-	tp->rto = min(tp->rto << 1, TCP_RTO_MAX);
-	tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
-	if (tp->retransmits > sysctl_tcp_retries1)
-		__sk_dst_reset(sk);
-
-out:;
-#endif
-}
-
-static void tcp_write_timer(unsigned long data)
-{
-#if 0
-	struct sock *sk = (struct sock*)data;
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	int event;
-
-	bh_lock_sock(sk);
-	if (sk->lock.users) {
-		/* Try again later */
-		if (!mod_timer(&tp->retransmit_timer, jiffies + (HZ/20)))
-			sock_hold(sk);
-		goto out_unlock;
-	}
-
-	if (sk->state == TCP_CLOSE || !tp->pending)
-		goto out;
-
-	if ((long)(tp->timeout - jiffies) > 0) {
-		if (!mod_timer(&tp->retransmit_timer, tp->timeout))
-			sock_hold(sk);
-		goto out;
-	}
-
-	event = tp->pending;
-	tp->pending = 0;
-
-	switch (event) {
-	case TCP_TIME_RETRANS:
-		tcp_retransmit_timer(sk);
-		break;
-	case TCP_TIME_PROBE0:
-		tcp_probe_timer(sk);
-		break;
-	}
-	TCP_CHECK_TIMER(sk);
-
-out:
-	tcp_mem_reclaim(sk);
-out_unlock:
-	bh_unlock_sock(sk);
-	sock_put(sk);
-#endif
-}
-
-/*
- *	Timer for listening sockets
- */
-
-static void tcp_synack_timer(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	int max_retries = tp->syn_retries ? : sysctl_tcp_synack_retries;
-	int thresh = max_retries;
-	unsigned long now = jiffies;
-	struct open_request **reqp, *req;
-	int i, budget;
-
-	if (lopt == NULL || lopt->qlen == 0)
-		return;
-
-	/* Normally all the openreqs are young and become mature
-	 * (i.e. converted to established socket) for first timeout.
-	 * If synack was not acknowledged for 3 seconds, it means
-	 * one of the following things: synack was lost, ack was lost,
-	 * rtt is high or nobody planned to ack (i.e. synflood).
-	 * When server is a bit loaded, queue is populated with old
-	 * open requests, reducing effective size of queue.
-	 * When server is well loaded, queue size reduces to zero
-	 * after several minutes of work. It is not synflood,
-	 * it is normal operation. The solution is pruning
-	 * too old entries overriding normal timeout, when
-	 * situation becomes dangerous.
-	 *
-	 * Essentially, we reserve half of room for young
-	 * embrions; and abort old ones without pity, if old
-	 * ones are about to clog our table.
-	 */
-	if (lopt->qlen>>(lopt->max_qlen_log-1)) {
-		int young = (lopt->qlen_young<<1);
-
-		while (thresh > 2) {
-			if (lopt->qlen < young)
-				break;
-			thresh--;
-			young <<= 1;
-		}
-	}
-
-	if (tp->defer_accept)
-		max_retries = tp->defer_accept;
-
-	budget = 2*(TCP_SYNQ_HSIZE/(TCP_TIMEOUT_INIT/TCP_SYNQ_INTERVAL));
-	i = lopt->clock_hand;
-
-	do {
-		reqp=&lopt->syn_table[i];
-		while ((req = *reqp) != NULL) {
-			if ((long)(now - req->expires) >= 0) {
-				if ((req->retrans < thresh ||
-				     (req->acked && req->retrans < max_retries))
-				    && !req->class->rtx_syn_ack(sk, req, NULL)) {
-					unsigned long timeo;
-
-					if (req->retrans++ == 0)
-						lopt->qlen_young--;
-					timeo = min((TCP_TIMEOUT_INIT << req->retrans),
-						    TCP_RTO_MAX);
-					req->expires = now + timeo;
-					reqp = &req->dl_next;
-					continue;
-				}
-
-				/* Drop this request */
-				write_lock(&tp->syn_wait_lock);
-				*reqp = req->dl_next;
-				write_unlock(&tp->syn_wait_lock);
-				lopt->qlen--;
-				if (req->retrans == 0)
-					lopt->qlen_young--;
-				tcp_openreq_free(req);
-				continue;
-			}
-			reqp = &req->dl_next;
-		}
-
-		i = (i+1)&(TCP_SYNQ_HSIZE-1);
-
-	} while (--budget > 0);
-
-	lopt->clock_hand = i;
-
-	if (lopt->qlen)
-		tcp_reset_keepalive_timer(sk, TCP_SYNQ_INTERVAL);
-#endif
-}
-
-void tcp_delete_keepalive_timer (struct sock *sk)
-{
-#if 0
-	if (timer_pending(&sk->timer) && del_timer (&sk->timer))
-		__sock_put(sk);
-#endif
-}
-
-void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len)
-{
-#if 0
-	if (!mod_timer(&sk->timer, jiffies+len))
-		sock_hold(sk);
-#endif
-}
-
-void tcp_set_keepalive(struct sock *sk, int val)
-{
-#if 0
-	if ((1<<sk->state)&(TCPF_CLOSE|TCPF_LISTEN))
-		return;
-
-	if (val && !sk->keepopen)
-		tcp_reset_keepalive_timer(sk, keepalive_time_when(&sk->tp_pinfo.af_tcp));
-	else if (!val)
-		tcp_delete_keepalive_timer(sk);
-#endif
-}
-
-
-static void tcp_keepalive_timer (unsigned long data)
-{
-#if 0
-	struct sock *sk = (struct sock *) data;
-	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
-	__u32 elapsed;
-
-	/* Only process if socket is not in use. */
-	bh_lock_sock(sk);
-	if (sk->lock.users) {
-		/* Try again later. */ 
-		tcp_reset_keepalive_timer (sk, HZ/20);
-		goto out;
-	}
-
-	if (sk->state == TCP_LISTEN) {
-		tcp_synack_timer(sk);
-		goto out;
-	}
-
-	if (sk->state == TCP_FIN_WAIT2 && sk->dead) {
-		if (tp->linger2 >= 0) {
-			int tmo = tcp_fin_time(tp) - TCP_TIMEWAIT_LEN;
-
-			if (tmo > 0) {
-				tcp_time_wait(sk, TCP_FIN_WAIT2, tmo);
-				goto out;
-			}
-		}
-		tcp_send_active_reset(sk, GFP_ATOMIC);
-		goto death;
-	}
-
-	if (!sk->keepopen || sk->state == TCP_CLOSE)
-		goto out;
-
-	elapsed = keepalive_time_when(tp);
-
-	/* It is alive without keepalive 8) */
-	if (tp->packets_out || tp->send_head)
-		goto resched;
-
-	elapsed = tcp_time_stamp - tp->rcv_tstamp;
-
-	if (elapsed >= keepalive_time_when(tp)) {
-		if ((!tp->keepalive_probes && tp->probes_out >= sysctl_tcp_keepalive_probes) ||
-		     (tp->keepalive_probes && tp->probes_out >= tp->keepalive_probes)) {
-			tcp_send_active_reset(sk, GFP_ATOMIC);
-			tcp_write_err(sk);
-			goto out;
-		}
-		if (tcp_write_wakeup(sk) <= 0) {
-			tp->probes_out++;
-			elapsed = keepalive_intvl_when(tp);
-		} else {
-			/* If keepalive was lost due to local congestion,
-			 * try harder.
-			 */
-			elapsed = TCP_RESOURCE_PROBE_INTERVAL;
-		}
-	} else {
-		/* It is tp->rcv_tstamp + keepalive_time_when(tp) */
-		elapsed = keepalive_time_when(tp) - elapsed;
-	}
-
-	TCP_CHECK_TIMER(sk);
-	tcp_mem_reclaim(sk);
-
-resched:
-	tcp_reset_keepalive_timer (sk, elapsed);
-	goto out;
-
-death:	
-	tcp_done(sk);
-
-out:
-	bh_unlock_sock(sk);
-	sock_put(sk);
-#endif
-}

reactos/drivers/net/tcpip/transport/tcp
tcpcore.c removed after 1.1
diff -N tcpcore.c
--- tcpcore.c	15 Jan 2003 21:57:31 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,2783 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS TCP/IP protocol driver
- * FILE:        transport/tcp/tcpcore.c
- * PURPOSE:     Transmission Control Protocol
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- *   CSH 15-01-2003 Imported from linux kernel 2.4.20
- */
-
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		Implementation of the Transmission Control Protocol(TCP).
- *
- * Version:	$Id: tcpcore.c,v 1.1 2003/01/15 21:57:31 chorns Exp $
- *
- * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
- *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- *		Mark Evans, <evansmp@uhura.aston.ac.uk>
- *		Corey Minyard <wf-rch!minyard@relay.EU.net>
- *		Florian La Roche, <flla@stud.uni-sb.de>
- *		Charles Hedrick, <hedrick@klinzhai.rutgers.edu>
- *		Linus Torvalds, <torvalds@cs.helsinki.fi>
- *		Alan Cox, <gw4pts@gw4pts.ampr.org>
- *		Matthew Dillon, <dillon@apollo.west.oic.com>
- *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
- *		Jorge Cwik, <jorge@laser.satlink.net>
- *
- * Fixes:
- *		Alan Cox	:	Numerous verify_area() calls
- *		Alan Cox	:	Set the ACK bit on a reset
- *		Alan Cox	:	Stopped it crashing if it closed while
- *					sk->inuse=1 and was trying to connect
- *					(tcp_err()).
- *		Alan Cox	:	All icmp error handling was broken
- *					pointers passed where wrong and the
- *					socket was looked up backwards. Nobody
- *					tested any icmp error code obviously.
- *		Alan Cox	:	tcp_err() now handled properly. It
- *					wakes people on errors. poll
- *					behaves and the icmp error race
- *					has gone by moving it into sock.c
- *		Alan Cox	:	tcp_send_reset() fixed to work for
- *					everything not just packets for
- *					unknown sockets.
- *		Alan Cox	:	tcp option processing.
- *		Alan Cox	:	Reset tweaked (still not 100%) [Had
- *					syn rule wrong]
- *		Herp Rosmanith  :	More reset fixes
- *		Alan Cox	:	No longer acks invalid rst frames.
- *					Acking any kind of RST is right out.
- *		Alan Cox	:	Sets an ignore me flag on an rst
- *					receive otherwise odd bits of prattle
- *					escape still
- *		Alan Cox	:	Fixed another acking RST frame bug.
- *					Should stop LAN workplace lockups.
- *		Alan Cox	: 	Some tidyups using the new skb list
- *					facilities
- *		Alan Cox	:	sk->keepopen now seems to work
- *		Alan Cox	:	Pulls options out correctly on accepts
- *		Alan Cox	:	Fixed assorted sk->rqueue->next errors
- *		Alan Cox	:	PSH doesn't end a TCP read. Switched a
- *					bit to skb ops.
- *		Alan Cox	:	Tidied tcp_data to avoid a potential
- *					nasty.
- *		Alan Cox	:	Added some better commenting, as the
- *					tcp is hard to follow
- *		Alan Cox	:	Removed incorrect check for 20 * psh
- *	Michael O'Reilly	:	ack < copied bug fix.
- *	Johannes Stille		:	Misc tcp fixes (not all in yet).
- *		Alan Cox	:	FIN with no memory -> CRASH
- *		Alan Cox	:	Added socket option proto entries.
- *					Also added awareness of them to accept.
- *		Alan Cox	:	Added TCP options (SOL_TCP)
- *		Alan Cox	:	Switched wakeup calls to callbacks,
- *					so the kernel can layer network
- *					sockets.
- *		Alan Cox	:	Use ip_tos/ip_ttl settings.
- *		Alan Cox	:	Handle FIN (more) properly (we hope).
- *		Alan Cox	:	RST frames sent on unsynchronised
- *					state ack error.
- *		Alan Cox	:	Put in missing check for SYN bit.
- *		Alan Cox	:	Added tcp_select_window() aka NET2E
- *					window non shrink trick.
- *		Alan Cox	:	Added a couple of small NET2E timer
- *					fixes
- *		Charles Hedrick :	TCP fixes
- *		Toomas Tamm	:	TCP window fixes
- *		Alan Cox	:	Small URG fix to rlogin ^C ack fight
- *		Charles Hedrick	:	Rewrote most of it to actually work
- *		Linus		:	Rewrote tcp_read() and URG handling
- *					completely
- *		Gerhard Koerting:	Fixed some missing timer handling
- *		Matthew Dillon  :	Reworked TCP machine states as per RFC
- *		Gerhard Koerting:	PC/TCP workarounds
- *		Adam Caldwell	:	Assorted timer/timing errors
- *		Matthew Dillon	:	Fixed another RST bug
- *		Alan Cox	:	Move to kernel side addressing changes.
- *		Alan Cox	:	Beginning work on TCP fastpathing
- *					(not yet usable)
- *		Arnt Gulbrandsen:	Turbocharged tcp_check() routine.
- *		Alan Cox	:	TCP fast path debugging
- *		Alan Cox	:	Window clamping
- *		Michael Riepe	:	Bug in tcp_check()
- *		Matt Dillon	:	More TCP improvements and RST bug fixes
- *		Matt Dillon	:	Yet more small nasties remove from the
- *					TCP code (Be very nice to this man if
- *					tcp finally works 100%) 8)
- *		Alan Cox	:	BSD accept semantics.
- *		Alan Cox	:	Reset on closedown bug.
- *	Peter De Schrijver	:	ENOTCONN check missing in tcp_sendto().
- *		Michael Pall	:	Handle poll() after URG properly in
- *					all cases.
- *		Michael Pall	:	Undo the last fix in tcp_read_urg()
- *					(multi URG PUSH broke rlogin).
- *		Michael Pall	:	Fix the multi URG PUSH problem in
- *					tcp_readable(), poll() after URG
- *					works now.
- *		Michael Pall	:	recv(...,MSG_OOB) never blocks in the
- *					BSD api.
- *		Alan Cox	:	Changed the semantics of sk->socket to
- *					fix a race and a signal problem with
- *					accept() and async I/O.
- *		Alan Cox	:	Relaxed the rules on tcp_sendto().
- *		Yury Shevchuk	:	Really fixed accept() blocking problem.
- *		Craig I. Hagan  :	Allow for BSD compatible TIME_WAIT for
- *					clients/servers which listen in on
- *					fixed ports.
- *		Alan Cox	:	Cleaned the above up and shrank it to
- *					a sensible code size.
- *		Alan Cox	:	Self connect lockup fix.
- *		Alan Cox	:	No connect to multicast.
- *		Ross Biro	:	Close unaccepted children on master
- *					socket close.
- *		Alan Cox	:	Reset tracing code.
- *		Alan Cox	:	Spurious resets on shutdown.
- *		Alan Cox	:	Giant 15 minute/60 second timer error
- *		Alan Cox	:	Small whoops in polling before an
- *					accept.
- *		Alan Cox	:	Kept the state trace facility since
- *					it's handy for debugging.
- *		Alan Cox	:	More reset handler fixes.
- *		Alan Cox	:	Started rewriting the code based on
- *					the RFC's for other useful protocol
- *					references see: Comer, KA9Q NOS, and
- *					for a reference on the difference
- *					between specifications and how BSD
- *					works see the 4.4lite source.
- *		A.N.Kuznetsov	:	Don't time wait on completion of tidy
- *					close.
- *		Linus Torvalds	:	Fin/Shutdown & copied_seq changes.
- *		Linus Torvalds	:	Fixed BSD port reuse to work first syn
- *		Alan Cox	:	Reimplemented timers as per the RFC
- *					and using multiple timers for sanity.
- *		Alan Cox	:	Small bug fixes, and a lot of new
- *					comments.
- *		Alan Cox	:	Fixed dual reader crash by locking
- *					the buffers (much like datagram.c)
- *		Alan Cox	:	Fixed stuck sockets in probe. A probe
- *					now gets fed up of retrying without
- *					(even a no space) answer.
- *		Alan Cox	:	Extracted closing code better
- *		Alan Cox	:	Fixed the closing state machine to
- *					resemble the RFC.
- *		Alan Cox	:	More 'per spec' fixes.
- *		Jorge Cwik	:	Even faster checksumming.
- *		Alan Cox	:	tcp_data() doesn't ack illegal PSH
- *					only frames. At least one pc tcp stack
- *					generates them.
- *		Alan Cox	:	Cache last socket.
- *		Alan Cox	:	Per route irtt.
- *		Matt Day	:	poll()->select() match BSD precisely on error
- *		Alan Cox	:	New buffers
- *		Marc Tamsky	:	Various sk->prot->retransmits and
- *					sk->retransmits misupdating fixed.
- *					Fixed tcp_write_timeout: stuck close,
- *					and TCP syn retries gets used now.
- *		Mark Yarvis	:	In tcp_read_wakeup(), don't send an
- *					ack if state is TCP_CLOSED.
- *		Alan Cox	:	Look up device on a retransmit - routes may
- *					change. Doesn't yet cope with MSS shrink right
- *					but its a start!
- *		Marc Tamsky	:	Closing in closing fixes.
- *		Mike Shaver	:	RFC1122 verifications.
- *		Alan Cox	:	rcv_saddr errors.
- *		Alan Cox	:	Block double connect().
- *		Alan Cox	:	Small hooks for enSKIP.
- *		Alexey Kuznetsov:	Path MTU discovery.
- *		Alan Cox	:	Support soft errors.
- *		Alan Cox	:	Fix MTU discovery pathological case
- *					when the remote claims no mtu!
- *		Marc Tamsky	:	TCP_CLOSE fix.
- *		Colin (G3TNE)	:	Send a reset on syn ack replies in
- *					window but wrong (fixes NT lpd problems)
- *		Pedro Roque	:	Better TCP window handling, delayed ack.
- *		Joerg Reuter	:	No modification of locked buffers in
- *					tcp_do_retransmit()
- *		Eric Schenk	:	Changed receiver side silly window
- *					avoidance algorithm to BSD style
- *					algorithm. This doubles throughput
- *					against machines running Solaris,
- *					and seems to result in general
- *					improvement.
- *	Stefan Magdalinski	:	adjusted tcp_readable() to fix FIONREAD
- *	Willy Konynenberg	:	Transparent proxying support.
- *	Mike McLagan		:	Routing by source
- *		Keith Owens	:	Do proper merging with partial SKB's in
- *					tcp_do_sendmsg to avoid burstiness.
- *		Eric Schenk	:	Fix fast close down bug with
- *					shutdown() followed by close().
- *		Andi Kleen 	:	Make poll agree with SIGIO
- *	Salvatore Sanfilippo	:	Support SO_LINGER with linger == 1 and
- *					lingertime == 0 (RFC 793 ABORT Call)
- *					
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or(at your option) any later version.
- *
- * Description of States:
- *
- *	TCP_SYN_SENT		sent a connection request, waiting for ack
- *
- *	TCP_SYN_RECV		received a connection request, sent ack,
- *				waiting for final ack in three-way handshake.
- *
- *	TCP_ESTABLISHED		connection established
- *
- *	TCP_FIN_WAIT1		our side has shutdown, waiting to complete
- *				transmission of remaining buffered data
- *
- *	TCP_FIN_WAIT2		all buffered data sent, waiting for remote
- *				to shutdown
- *
- *	TCP_CLOSING		both sides have shutdown but we still have
- *				data we have to finish sending
- *
- *	TCP_TIME_WAIT		timeout to catch resent junk before entering
- *				closed, can only be entered from FIN_WAIT2
- *				or CLOSING.  Required because the other end
- *				may not have gotten our last ACK causing it
- *				to retransmit the data packet (which we ignore)
- *
- *	TCP_CLOSE_WAIT		remote side has shutdown and is waiting for
- *				us to finish writing our data and to shutdown
- *				(we have to close() to move on to LAST_ACK)
- *
- *	TCP_LAST_ACK		out side has shutdown after remote has
- *				shutdown.  There may still be data in our
- *				buffer that we have to finish sending
- *
- *	TCP_CLOSE		socket is finished
- */
-
-#if 0
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/smp_lock.h>
-#include <linux/fs.h>
-
-#include <net/icmp.h>
-#include <net/tcp.h>
-
-#include <asm/uaccess.h>
-#include <asm/ioctls.h>
-#else
-#include "linux.h"
-#include "tcpcore.h"
-#endif
-
-int sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT;
-
-#ifdef ROS_STATISTICS
-struct tcp_mib	tcp_statistics[NR_CPUS*2];
-#endif
-
-kmem_cache_t *tcp_openreq_cachep;
-kmem_cache_t *tcp_bucket_cachep;
-kmem_cache_t *tcp_timewait_cachep;
-
-#if 0
-atomic_t tcp_orphan_count = ATOMIC_INIT(0);
-#endif
-
-int sysctl_tcp_mem[3];
-int sysctl_tcp_wmem[3] = { 4*1024, 16*1024, 128*1024 };
-int sysctl_tcp_rmem[3] = { 4*1024, 87380, 87380*2 };
-
-atomic_t tcp_memory_allocated;	/* Current allocated memory. */
-atomic_t tcp_sockets_allocated;	/* Current number of TCP sockets. */
-
-/* Pressure flag: try to collapse.
- * Technical note: it is used by multiple contexts non atomically.
- * All the tcp_mem_schedule() is of this nature: accounting
- * is strict, actions are advisory and have some latency. */
-int tcp_memory_pressure;
-
-#define TCP_PAGES(amt) (((amt)+TCP_MEM_QUANTUM-1)/TCP_MEM_QUANTUM)
-
-int tcp_mem_schedule(struct sock *sk, int size, int kind)
-{
-	int amt = TCP_PAGES(size);
-
-	sk->forward_alloc += amt*TCP_MEM_QUANTUM;
-	atomic_add(amt, &tcp_memory_allocated);
-
-	/* Under limit. */
-	if (atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) {
-		if (tcp_memory_pressure)
-			tcp_memory_pressure = 0;
-		return 1;
-	}
-
-	/* Over hard limit. */
-	if (atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]) {
-		tcp_enter_memory_pressure();
-		goto suppress_allocation;
-	}
-
-	/* Under pressure. */
-	if (atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[1])
-		tcp_enter_memory_pressure();
-
-	if (kind) {
-		if (atomic_read(&sk->rmem_alloc) < sysctl_tcp_rmem[0])
-			return 1;
-	} else {
-		if (sk->wmem_queued < sysctl_tcp_wmem[0])
-			return 1;
-	}
-
-	if (!tcp_memory_pressure ||
-	    sysctl_tcp_mem[2] > atomic_read(&tcp_sockets_allocated)
-	    * TCP_PAGES(sk->wmem_queued+atomic_read(&sk->rmem_alloc)+
-			sk->forward_alloc))
-		return 1;
-
-suppress_allocation:
-
-	if (kind == 0) {
-		tcp_moderate_sndbuf(sk);
-
-		/* Fail only if socket is _under_ its sndbuf.
-		 * In this case we cannot block, so that we have to fail.
-		 */
-		if (sk->wmem_queued+size >= sk->sndbuf)
-			return 1;
-	}
-
-	/* Alas. Undo changes. */
-	sk->forward_alloc -= amt*TCP_MEM_QUANTUM;
-	atomic_sub(amt, &tcp_memory_allocated);
-	return 0;
-}
-
-void __tcp_mem_reclaim(struct sock *sk)
-{
-	if (sk->forward_alloc >= TCP_MEM_QUANTUM) {
-		atomic_sub(sk->forward_alloc/TCP_MEM_QUANTUM, &tcp_memory_allocated);
-		sk->forward_alloc &= (TCP_MEM_QUANTUM-1);
-		if (tcp_memory_pressure &&
-		    atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0])
-			tcp_memory_pressure = 0;
-	}
-}
-
-void tcp_rfree(struct sk_buff *skb)
-{
-	struct sock *sk = skb->sk;
-
-	atomic_sub(skb->truesize, &sk->rmem_alloc);
-	sk->forward_alloc += skb->truesize;
-}
-
-/*
- * LISTEN is a special case for poll..
- */
-static __inline__ unsigned int tcp_listen_poll(struct sock *sk, poll_table *wait)
-{
-	return sk->tp_pinfo.af_tcp.accept_queue ? (POLLIN | POLLRDNORM) : 0;
-}
-
-/*
- *	Wait for a TCP event.
- *
- *	Note that we don't need to lock the socket, as the upper poll layers
- *	take care of normal races (between the test and the event) and we don't
- *	go look at any of the socket buffers directly.
- */
-unsigned int tcp_poll(struct file * file, struct socket *sock, poll_table *wait)
-{
-#if 0
-	unsigned int mask;
-	struct sock *sk = sock->sk;
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-
-	poll_wait(file, sk->sleep, wait);
-	if (sk->state == TCP_LISTEN)
-		return tcp_listen_poll(sk, wait);
-
-	/* Socket is not locked. We are protected from async events
-	   by poll logic and correct handling of state changes
-	   made by another threads is impossible in any case.
-	 */
-
-	mask = 0;
-	if (sk->err)
-		mask = POLLERR;
-
-	/*
-	 * POLLHUP is certainly not done right. But poll() doesn't
-	 * have a notion of HUP in just one direction, and for a
-	 * socket the read side is more interesting.
-	 *
-	 * Some poll() documentation says that POLLHUP is incompatible
-	 * with the POLLOUT/POLLWR flags, so somebody should check this
-	 * all. But careful, it tends to be safer to return too many
-	 * bits than too few, and you can easily break real applications
-	 * if you don't tell them that something has hung up!
-	 *
-	 * Check-me.
-	 *
-	 * Check number 1. POLLHUP is _UNMASKABLE_ event (see UNIX98 and
-	 * our fs/select.c). It means that after we received EOF,
-	 * poll always returns immediately, making impossible poll() on write()
-	 * in state CLOSE_WAIT. One solution is evident --- to set POLLHUP
-	 * if and only if shutdown has been made in both directions.
-	 * Actually, it is interesting to look how Solaris and DUX
-	 * solve this dilemma. I would prefer, if PULLHUP were maskable,
-	 * then we could set it on SND_SHUTDOWN. BTW examples given
-	 * in Stevens' books assume exactly this behaviour, it explains
-	 * why PULLHUP is incompatible with POLLOUT.	--ANK
-	 *
-	 * NOTE. Check for TCP_CLOSE is added. The goal is to prevent
-	 * blocking on fresh not-connected or disconnected socket. --ANK
-	 */
-	if (sk->shutdown == SHUTDOWN_MASK || sk->state == TCP_CLOSE)
-		mask |= POLLHUP;
-	if (sk->shutdown & RCV_SHUTDOWN)
-		mask |= POLLIN | POLLRDNORM;
-
-	/* Connected? */
-	if ((1 << sk->state) & ~(TCPF_SYN_SENT|TCPF_SYN_RECV)) {
-		/* Potential race condition. If read of tp below will
-		 * escape above sk->state, we can be illegally awaken
-		 * in SYN_* states. */
-		if ((tp->rcv_nxt != tp->copied_seq) &&
-		    (tp->urg_seq != tp->copied_seq ||
-		     tp->rcv_nxt != tp->copied_seq+1 ||
-		     sk->urginline || !tp->urg_data))
-			mask |= POLLIN | POLLRDNORM;
-
-		if (!(sk->shutdown & SEND_SHUTDOWN)) {
-			if (tcp_wspace(sk) >= tcp_min_write_space(sk)) {
-				mask |= POLLOUT | POLLWRNORM;
-			} else {  /* send SIGIO later */
-				set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-				set_bit(SOCK_NOSPACE, &sk->socket->flags);
-
-				/* Race breaker. If space is freed after
-				 * wspace test but before the flags are set,
-				 * IO signal will be lost.
-				 */
-				if (tcp_wspace(sk) >= tcp_min_write_space(sk))
-					mask |= POLLOUT | POLLWRNORM;
-			}
-		}
-
-		if (tp->urg_data & TCP_URG_VALID)
-			mask |= POLLPRI;
-	}
-	return mask;
-#else
-  return 0;
-#endif
-}
-
-/*
- *	TCP socket write_space callback.
- */
-void tcp_write_space(struct sock *sk)
-{
-#if 0
-	struct socket *sock = sk->socket;
-
-	if (tcp_wspace(sk) >= tcp_min_write_space(sk) && sock) {
-		clear_bit(SOCK_NOSPACE, &sock->flags);
-
-		if (sk->sleep && waitqueue_active(sk->sleep))
-			wake_up_interruptible(sk->sleep);
-
-		if (sock->fasync_list && !(sk->shutdown&SEND_SHUTDOWN))
-			sock_wake_async(sock, 2, POLL_OUT);
-	}
-#endif
-}
-
-int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	int answ;
-
-	switch(cmd) {
-	case SIOCINQ:
-		if (sk->state == TCP_LISTEN)
-			return(-EINVAL);
-
-		lock_sock(sk);
-		if ((1<<sk->state) & (TCPF_SYN_SENT|TCPF_SYN_RECV))
-			answ = 0;
-		else if (sk->urginline || !tp->urg_data ||
-			 before(tp->urg_seq,tp->copied_seq) ||
-			 !before(tp->urg_seq,tp->rcv_nxt)) {
-			answ = tp->rcv_nxt - tp->copied_seq;
-
-			/* Subtract 1, if FIN is in queue. */
-			if (answ && !skb_queue_empty(&sk->receive_queue))
-				answ -= ((struct sk_buff*)sk->receive_queue.prev)->h.th->fin;
-		} else
-			answ = tp->urg_seq - tp->copied_seq;
-		release_sock(sk);
-		break;
-	case SIOCATMARK:
-		{
-			answ = tp->urg_data && tp->urg_seq == tp->copied_seq;
-			break;
-		}
-	case SIOCOUTQ:
-		if (sk->state == TCP_LISTEN)
-			return(-EINVAL);
-
-		if ((1<<sk->state) & (TCPF_SYN_SENT|TCPF_SYN_RECV))
-			answ = 0;
-		else
-			answ = tp->write_seq - tp->snd_una;
-		break;
-	default:
-		return(-ENOIOCTLCMD);
-	};
-
-	return put_user(answ, (int *)arg);
-#else
-return 0;
-#endif
-}
-
-
-int tcp_listen_start(struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct tcp_listen_opt *lopt;
-
-	sk->max_ack_backlog = 0;
-	sk->ack_backlog = 0;
-	tp->accept_queue = tp->accept_queue_tail = NULL;
-	tp->syn_wait_lock = RW_LOCK_UNLOCKED;
-	tcp_delack_init(tp);
-
-	lopt = kmalloc(sizeof(struct tcp_listen_opt), GFP_KERNEL);
-	if (!lopt)
-		return -ENOMEM;
-
-	memset(lopt, 0, sizeof(struct tcp_listen_opt));
-	for (lopt->max_qlen_log = 6; ; lopt->max_qlen_log++)
-		if ((1<<lopt->max_qlen_log) >= sysctl_max_syn_backlog)
-			break;
-
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt = lopt;
-	write_unlock_bh(&tp->syn_wait_lock);
-
-	/* There is race window here: we announce ourselves listening,
-	 * but this transition is still not validated by get_port().
-	 * It is OK, because this socket enters to hash table only
-	 * after validation is complete.
-	 */
-	sk->state = TCP_LISTEN;
-	if (sk->prot->get_port(sk, sk->num) == 0) {
-		sk->sport = htons(sk->num);
-
-		sk_dst_reset(sk);
-		sk->prot->hash(sk);
-
-		return 0;
-	}
-
-	sk->state = TCP_CLOSE;
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt = NULL;
-	write_unlock_bh(&tp->syn_wait_lock);
-	kfree(lopt);
-	return -EADDRINUSE;
-#endif
-}
-
-/*
- *	This routine closes sockets which have been at least partially
- *	opened, but not yet accepted.
- */
-
-static void tcp_listen_stop (struct sock *sk)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	struct tcp_listen_opt *lopt = tp->listen_opt;
-	struct open_request *acc_req = tp->accept_queue;
-	struct open_request *req;
-	int i;
-
-	tcp_delete_keepalive_timer(sk);
-
-	/* make all the listen_opt local to us */
-	write_lock_bh(&tp->syn_wait_lock);
-	tp->listen_opt =NULL;
-	write_unlock_bh(&tp->syn_wait_lock);
-	tp->accept_queue = tp->accept_queue_tail = NULL;
-
-	if (lopt->qlen) {
-		for (i=0; i<TCP_SYNQ_HSIZE; i++) {
-			while ((req = lopt->syn_table[i]) != NULL) {
-				lopt->syn_table[i] = req->dl_next;
-				lopt->qlen--;
-				tcp_openreq_free(req);
-
-		/* Following specs, it would be better either to send FIN
-		 * (and enter FIN-WAIT-1, it is normal close)
-		 * or to send active reset (abort). 
-		 * Certainly, it is pretty dangerous while synflood, but it is
-		 * bad justification for our negligence 8)
-		 * To be honest, we are not able to make either
-		 * of the variants now.			--ANK
-		 */
-			}
-		}
-	}
-	BUG_TRAP(lopt->qlen == 0);
-
-	kfree(lopt);
-
-	while ((req=acc_req) != NULL) {
-		struct sock *child = req->sk;
-
-		acc_req = req->dl_next;
-
-		local_bh_disable();
-		bh_lock_sock(child);
-		BUG_TRAP(child->lock.users==0);
-		sock_hold(child);
-
-		tcp_disconnect(child, O_NONBLOCK);
-
-		sock_orphan(child);
-
-		atomic_inc(&tcp_orphan_count);
-
-		tcp_destroy_sock(child);
-
-		bh_unlock_sock(child);
-		local_bh_enable();
-		sock_put(child);
-
-		tcp_acceptq_removed(sk);
-		tcp_openreq_fastfree(req);
-	}
-	BUG_TRAP(sk->ack_backlog == 0);
-#endif
-}
-
-/*
- *	Wait for a socket to get into the connected state
- *
- *	Note: Must be called with the socket locked.
- */
-static int wait_for_tcp_connect(struct sock * sk, int flags, long *timeo_p)
-{
-#if 0
-	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
-
-	while((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) {
-		if(sk->err)
-			return sock_error(sk);
-		if((1 << sk->state) &
-		   ~(TCPF_SYN_SENT | TCPF_SYN_RECV))
-			return -EPIPE;
-		if(!*timeo_p)
-			return -EAGAIN;
-		if(signal_pending(tsk))
-			return sock_intr_errno(*timeo_p);
-
-		__set_task_state(tsk, TASK_INTERRUPTIBLE);
-		add_wait_queue(sk->sleep, &wait);
-		sk->tp_pinfo.af_tcp.write_pending++;
-
-		release_sock(sk);
-		*timeo_p = schedule_timeout(*timeo_p);
-		lock_sock(sk);
-
-		__set_task_state(tsk, TASK_RUNNING);
-		remove_wait_queue(sk->sleep, &wait);
-		sk->tp_pinfo.af_tcp.write_pending--;
-	}
-	return 0;
-#else
-  return 0;
-#endif
-}
-
-static inline int tcp_memory_free(struct sock *sk)
-{
-	return sk->wmem_queued < sk->sndbuf;
-}
-
-/*
- *	Wait for more memory for a socket
- */
-static int wait_for_tcp_memory(struct sock * sk, long *timeo)
-{
-#if 0
-	int err = 0;
-	long vm_wait = 0;
-	long current_timeo = *timeo;
-	DECLARE_WAITQUEUE(wait, current);
-
-	if (tcp_memory_free(sk))
-		current_timeo = vm_wait = (net_random()%(HZ/5))+2;
-
-	add_wait_queue(sk->sleep, &wait);
-	for (;;) {
-		set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-
-		set_current_state(TASK_INTERRUPTIBLE);
-
-		if (sk->err || (sk->shutdown & SEND_SHUTDOWN))
-			goto do_error;
-		if (!*timeo)
-			goto do_nonblock;
-		if (signal_pending(current))
-			goto do_interrupted;
-		clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-		if (tcp_memory_free(sk) && !vm_wait)
-			break;
-
-		set_bit(SOCK_NOSPACE, &sk->socket->flags);
-		sk->tp_pinfo.af_tcp.write_pending++;
-		release_sock(sk);
-		if (!tcp_memory_free(sk) || vm_wait)
-			current_timeo = schedule_timeout(current_timeo);
-		lock_sock(sk);
-		sk->tp_pinfo.af_tcp.write_pending--;
-
-		if (vm_wait) {
-			vm_wait -= current_timeo;
-			current_timeo = *timeo;
-			if (current_timeo != MAX_SCHEDULE_TIMEOUT &&
-			    (current_timeo -= vm_wait) < 0)
-				current_timeo = 0;
-			vm_wait = 0;
-		}
-		*timeo = current_timeo;
-	}
-out:
-	current->state = TASK_RUNNING;
-	remove_wait_queue(sk->sleep, &wait);
-	return err;
-
-do_error:
-	err = -EPIPE;
-	goto out;
-do_nonblock:
-	err = -EAGAIN;
-	goto out;
-do_interrupted:
-	err = sock_intr_errno(*timeo);
-	goto out;
-#endif
-}
-
-ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags);
-
-static inline int
-can_coalesce(struct sk_buff *skb, int i, struct page *page, int off)
-{
-#if 0
-	if (i) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
-		return page == frag->page &&
-			off == frag->page_offset+frag->size;
-	}
-	return 0;
-#else
-return 0;
-#endif
-}
-
-static inline void
-fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size)
-{
-	skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-	frag->page = page;
-	frag->page_offset = off;
-	frag->size = size;
-	skb_shinfo(skb)->nr_frags = i+1;
-}
-
-static inline void tcp_mark_push(struct tcp_opt *tp, struct sk_buff *skb)
-{
-	TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
-	tp->pushed_seq = tp->write_seq;
-}
-
-static inline int forced_push(struct tcp_opt *tp)
-{
-	return after(tp->write_seq, tp->pushed_seq + (tp->max_window>>1));
-}
-
-static inline void
-skb_entail(struct sock *sk, struct tcp_opt *tp, struct sk_buff *skb)
-{
-	skb->csum = 0;
-	TCP_SKB_CB(skb)->seq = tp->write_seq;
-	TCP_SKB_CB(skb)->end_seq = tp->write_seq;
-	TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK;
-	TCP_SKB_CB(skb)->sacked = 0;
-	__skb_queue_tail(&sk->write_queue, skb);
-	tcp_charge_skb(sk, skb);
-	if (tp->send_head == NULL)
-		tp->send_head = skb;
-}
-
-static inline void
-tcp_mark_urg(struct tcp_opt *tp, int flags, struct sk_buff *skb)
-{
-#if 0
-	if (flags & MSG_OOB) {
-		tp->urg_mode = 1;
-		tp->snd_up = tp->write_seq;
-		TCP_SKB_CB(skb)->sacked |= TCPCB_URG;
-	}
-#endif
-}
-
-static inline void
-tcp_push(struct sock *sk, struct tcp_opt *tp, int flags, int mss_now, int nonagle)
-{
-#if 0
-	if (tp->send_head) {
-		struct sk_buff *skb = sk->write_queue.prev;
-		if (!(flags&MSG_MORE) || forced_push(tp))
-			tcp_mark_push(tp, skb);
-		tcp_mark_urg(tp, flags, skb);
-		__tcp_push_pending_frames(sk, tp, mss_now, (flags&MSG_MORE) ? 2 : nonagle);
-	}
-#endif
-}
-
-static int tcp_error(struct sock *sk, int flags, int err)
-{
-#if 0
-	if (err == -EPIPE)
-		err = sock_error(sk) ? : -EPIPE;
-	if (err == -EPIPE && !(flags&MSG_NOSIGNAL))
-		send_sig(SIGPIPE, current, 0);
-	return err;
-#else
-  return 0;
-#endif
-}
-
-ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags)
-{
-#if 0
-	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
-	int mss_now;
-	int err;
-	ssize_t copied;
-	long timeo = sock_sndtimeo(sk, flags&MSG_DONTWAIT);
-
-	/* Wait for a connection to finish. */
-	if ((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))
-		if((err = wait_for_tcp_connect(sk, 0, &timeo)) != 0)
-			goto out_err;
-
-	clear_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-
-	mss_now = tcp_current_mss(sk);
-	copied = 0;
-
-	err = -EPIPE;
-	if (sk->err || (sk->shutdown & SEND_SHUTDOWN))
-		goto do_error;
-
-	while (psize > 0) {
-		struct sk_buff *skb = sk->write_queue.prev;
-		int offset, size, copy, i;
-		struct page *page;
-
-		page = pages[poffset/PAGE_SIZE];
-		offset = poffset % PAGE_SIZE;
-		size = min_t(size_t, psize, PAGE_SIZE-offset);
-
-		if (tp->send_head==NULL || (copy = mss_now - skb->len) <= 0) {
-new_segment:
-			if (!tcp_memory_free(sk))
-				goto wait_for_sndbuf;
-
-			skb = tcp_alloc_pskb(sk, 0, tp->mss_cache, sk->allocation);
-			if (skb == NULL)
-				goto wait_for_memory;
-
-			skb_entail(sk, tp, skb);
-			copy = mss_now;
-		}
-
-		if (copy > size)
-			copy = size;
-
-		i = skb_shinfo(skb)->nr_frags;
-		if (can_coalesce(skb, i, page, offset)) {
-			skb_shinfo(skb)->frags[i-1].size += copy;
-		} else if (i < MAX_SKB_FRAGS) {
-			get_page(page);
-			fill_page_desc(skb, i, page, offset, copy);
-		} else {
-			tcp_mark_push(tp, skb);
-			goto new_segment;
-		}
-
-		skb->len += copy;
-		skb->data_len += copy;
-		skb->ip_summed = CHECKSUM_HW;
-		tp->write_seq += copy;
-		TCP_SKB_CB(skb)->end_seq += copy;
-
-		if (!copied)
-			TCP_SKB_CB(skb)->flags &= ~TCPCB_FLAG_PSH;
-
-		copied += copy;
-		poffset += copy;
-		if (!(psize -= copy))
-			goto out;
-
-		if (skb->len != mss_now || (flags&MSG_OOB))
-			continue;
-
-		if (forced_push(tp)) {
-			tcp_mark_push(tp, skb);
-			__tcp_push_pending_frames(sk, tp, mss_now, 1);
-		} else if (skb == tp->send_head)
-			tcp_push_one(sk, mss_now);
-		continue;
-
-wait_for_sndbuf:
-		set_bit(SOCK_NOSPACE, &sk->socket->flags);
-wait_for_memory:
-		if (copied)
-			tcp_push(sk, tp, flags&~MSG_MORE, mss_now, 1);
-
-		if ((err = wait_for_tcp_memory(sk, &timeo)) != 0)
-			goto do_error;
-
-		mss_now = tcp_current_mss(sk);
-	}
-
-out:
-	if (copied)
-		tcp_push(sk, tp, flags, mss_now, tp->nonagle);
-	return copied;
-
-do_error:
-	if (copied)
-		goto out;
-out_err:
-	return tcp_error(sk, flags, err);
-#else 
-return 0;
-#endif
-}
-
-ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags)
-{
-#if 0
-	ssize_t res;
-	struct sock *sk = sock->sk;
-
-#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
-
-	if (!(sk->route_caps & NETIF_F_SG) || 
[truncated at 1000 lines; 1787 more skipped]

reactos/drivers/net/tcpip/transport/udp
udp.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- udp.c	11 May 2004 20:52:10 -0000	1.7
+++ udp.c	9 Jun 2004 18:11:39 -0000	1.8
@@ -7,6 +7,7 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
+#include <roscfg.h>
 #include <tcpip.h>
 #include <udp.h>
 #include <routines.h>
@@ -91,7 +92,7 @@
   /* Source address */
   IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
   /* Destination address. FIXME: IPv4 only */
-  IPHeader->DstAddr = SendRequest->RemoteAddress->Address.IPv4Address;
+  IPHeader->DstAddr = SendRequest->RemoteAddress.Address.IPv4Address;
 
   /* Build UDP header */
   UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPHeader + sizeof(IPv4_HEADER));
@@ -110,8 +111,7 @@
 NTSTATUS BuildUDPPacket(
   PVOID Context,
   PIP_ADDRESS LocalAddress,
-  USHORT LocalPort,
-  PIP_PACKET *IPPacket)
+  USHORT LocalPort)
 /*
  * FUNCTION: Builds an UDP packet
  * ARGUMENTS:
@@ -124,16 +124,16 @@
  */
 {
   NTSTATUS Status;
-  PIP_PACKET Packet;
   NDIS_STATUS NdisStatus;
   PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
+  PIP_PACKET Packet = &SendRequest->Packet;
 
   TI_DbgPrint(MAX_TRACE, ("Called.\n"));
 
   /* Prepare packet */
 
   /* FIXME: Assumes IPv4 */
-  Packet = IPCreatePacket(IP_ADDRESS_V4);
+  IPInitializePacket(IP_ADDRESS_V4, &SendRequest->Packet);
   if (!Packet)
     return STATUS_INSUFFICIENT_RESOURCES;
 
@@ -141,15 +141,7 @@
                       sizeof(UDP_HEADER)  +
                       SendRequest->BufferSize;
 
-  /* Allocate NDIS packet */
-  NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
-  if (NdisStatus != NDIS_STATUS_SUCCESS) {
-    TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus));
-    (*Packet->Free)(Packet);
-    return STATUS_INSUFFICIENT_RESOURCES;
-  }
-
-  switch (SendRequest->RemoteAddress->Type) {
+  switch (SendRequest->RemoteAddress.Type) {
   case IP_ADDRESS_V4:
     Status = AddUDPHeaderIPv4(SendRequest, LocalAddress, LocalPort, Packet);
     break;
@@ -162,18 +154,12 @@
   }
   if (!NT_SUCCESS(Status)) {
     TI_DbgPrint(MIN_TRACE, ("Cannot add UDP header. Status = (0x%X)\n", Status));
-    NdisFreePacket(Packet->NdisPacket);
-    (*Packet->Free)(Packet);
+    FreeNdisPacket(Packet->NdisPacket);
     return Status;
   }
 
-  /* Chain data after header */
-  NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
-
   DISPLAY_IP_PACKET(Packet);
 
-  *IPPacket = Packet;
-
   return STATUS_SUCCESS;
 }
 
@@ -194,11 +180,18 @@
  *     Status of operation
  */
 {
-  return DGSendDatagram(Request,
-                        ConnInfo,
-                        Buffer,
-                        DataSize,
-                        BuildUDPPacket);
+    PDATAGRAM_SEND_REQUEST SendRequest;
+    PADDRESS_FILE AddrFile = 
+	(PADDRESS_FILE)Request->Handle.AddressHandle;
+    
+    BuildUDPPacket( SendRequest,
+		    (PIP_ADDRESS)&AddrFile->ADE->Address->Address.
+		    IPv4Address,
+		    AddrFile->Port );
+
+    return DGSendDatagram(Request,
+			  ConnInfo,
+			  &SendRequest->Packet);
 }
 
 

reactos/lib/msafd
makefile 1.13 -> 1.14
diff -u -r1.13 -r1.14
--- makefile	29 May 2004 21:24:44 -0000	1.13
+++ makefile	9 Jun 2004 18:11:39 -0000	1.14
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.13 2004/05/29 21:24:44 hbirr Exp $
+# $Id: makefile,v 1.14 2004/06/09 18:11:39 arty Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/msafd/misc
dllmain.c 1.12 -> 1.13
diff -u -r1.12 -r1.13
--- dllmain.c	4 Mar 2004 20:45:39 -0000	1.12
+++ dllmain.c	9 Jun 2004 18:11:39 -0000	1.13
@@ -15,8 +15,8 @@
 #ifdef DBG
 
 /* See debug.h for debug/trace constants */
-DWORD DebugTraceLevel = MIN_TRACE;
-//DWORD DebugTraceLevel = DEBUG_ULTRA;
+//DWORD DebugTraceLevel = MIN_TRACE;
+DWORD DebugTraceLevel = DEBUG_ULTRA;
 
 #endif /* DBG */
 
@@ -566,27 +566,29 @@
   Request.lpfnCondition = lpfnCondition;
   Request.dwCallbackData = dwCallbackData;
 
+  
+
   Status = NtDeviceIoControlFile(
-    (HANDLE)s,
-    NULL,
-		NULL,
-		NULL,
-		&Iosb,
-		IOCTL_AFD_ACCEPT,
-		&Request,
-		sizeof(FILE_REQUEST_ACCEPT),
-		&Reply,
-		sizeof(FILE_REPLY_ACCEPT));
+      (HANDLE)s,
+      NULL,
+      NULL,
+      NULL,
+      &Iosb,
+      IOCTL_AFD_ACCEPT,
+      &Request,
+      sizeof(FILE_REQUEST_ACCEPT),
+      &Reply,
+      sizeof(FILE_REPLY_ACCEPT));
   if (Status == STATUS_PENDING) {
-    AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
-    /* FIXME: Wait only for blocking sockets */
-		Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
+      AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
+      /* FIXME: Wait only for blocking sockets */
+      Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
   }
 
   if (!NT_SUCCESS(Status)) {
 	  *lpErrno = Reply.Status;
-    return INVALID_SOCKET;
-	}
+	  return INVALID_SOCKET;
+  }
 
   *addrlen = Reply.addrlen;
 

reactos/lib/ws2_32
makefile 1.14 -> 1.15
diff -u -r1.14 -r1.15
--- makefile	29 May 2004 21:24:47 -0000	1.14
+++ makefile	9 Jun 2004 18:11:39 -0000	1.15
@@ -1,4 +1,4 @@
-# $Id: makefile,v 1.14 2004/05/29 21:24:47 hbirr Exp $
+# $Id: makefile,v 1.15 2004/06/09 18:11:39 arty Exp $
 
 PATH_TO_TOP = ../..
 

reactos/lib/ws2_32/include
ws2_32.h 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- ws2_32.h	11 Jan 2004 20:46:06 -0000	1.7
+++ ws2_32.h	9 Jun 2004 18:11:39 -0000	1.8
@@ -28,10 +28,20 @@
 extern BOOL Initialized;	/* TRUE if WSAStartup() has been successfully called */
 extern WSPUPCALLTABLE UpcallTable;
 
+#define WS2_INTERNAL_MAX_ALIAS 16
+
+typedef struct _WINSOCK_GETSERVBYNAME_CACHE {
+    UINT Size;
+    SERVENT ServerEntry;
+    PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS];
+    CHAR Data[1];
+} WINSOCK_GETSERVBYNAME_CACHE, *PWINSOCK_GETSERVBYNAME_CACHE;
 
 typedef struct _WINSOCK_THREAD_BLOCK {
     INT LastErrorValue;     /* Error value from last function that failed */
     CHAR Intoa[16];         /* Buffer for inet_ntoa() */
+    PWINSOCK_GETSERVBYNAME_CACHE 
+    Getservbyname;          /* Buffer used by getservbyname */
 } WINSOCK_THREAD_BLOCK, *PWINSOCK_THREAD_BLOCK;
 
 

reactos/lib/ws2_32/misc
dllmain.c 1.14 -> 1.15
diff -u -r1.14 -r1.15
--- dllmain.c	25 Jan 2004 08:32:44 -0000	1.14
+++ dllmain.c	9 Jun 2004 18:11:39 -0000	1.15
@@ -17,7 +17,6 @@
 
 /* See debug.h for debug/trace constants */
 DWORD DebugTraceLevel = MIN_TRACE;
-//DWORD DebugTraceLevel = DEBUG_ULTRA;
 
 #endif /* DBG */
 
@@ -37,7 +36,8 @@
 EXPORT
 WSAGetLastError(VOID)
 {
-  PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
+  
+PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
 
   if (p) {
     return p->LastErrorValue;
@@ -667,6 +667,7 @@
     }
 
     p->LastErrorValue = NO_ERROR;
+    p->Getservbyname  = NULL;
 
     NtCurrentTeb()->WinSockData = p;
     break;

reactos/lib/ws2_32/misc
ns.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- ns.c	15 Feb 2004 07:03:02 -0000	1.6
+++ ns.c	9 Jun 2004 18:11:39 -0000	1.7
@@ -7,8 +7,13 @@
  * REVISIONS:
  *   CSH 01/09-2000 Created
  */
+#include <ctype.h>
 #include <ws2_32.h>
 
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif/*BUFSIZ*/
+
 /* Name resolution APIs */
 
 /*
@@ -420,9 +425,58 @@
     return (LPPROTOENT)NULL;
 }
 
+#define SKIPWS(ptr,act) \
+{while(*ptr && isspace(*ptr)) ptr++; if(!*ptr) act;}
+#define SKIPANDMARKSTR(ptr,act) \
+{while(*ptr && !isspace(*ptr)) ptr++; \
+ if(!*ptr) {act;} else { *ptr = 0; ptr++; }}
+ 
+
+static BOOL DecodeServEntFromString( IN  PCHAR ServiceString,
+				     OUT PCHAR *ServiceName,
+				     OUT PCHAR *PortNumberStr,
+				     OUT PCHAR *ProtocolStr,
+				     IN  PCHAR *Aliases,
+				     IN  DWORD MaxAlias ) {
+    UINT NAliases = 0;
+
+    WS_DbgPrint(MAX_TRACE, ("Parsing service ent [%s]\n", ServiceString));
+
+    SKIPWS(ServiceString, return FALSE);
+    *ServiceName = ServiceString;
+    SKIPANDMARKSTR(ServiceString, return FALSE);
+    SKIPWS(ServiceString, return FALSE);
+    *PortNumberStr = ServiceString;
+    SKIPANDMARKSTR(ServiceString, ;);
+
+    while( *ServiceString && NAliases < MaxAlias - 1 ) {
+	SKIPWS(ServiceString, break);
+	if( *ServiceString ) {
+	    SKIPANDMARKSTR(ServiceString, ;);
+	    if( strlen(ServiceString) ) {
+		WS_DbgPrint(MAX_TRACE, ("Alias: %s\n", ServiceString));
+		*Aliases++ = ServiceString;
+		NAliases++;
+	    }
+	}
+    }
+    *Aliases = NULL;
+
+    *ProtocolStr = strchr(*PortNumberStr,'/');
+    if( !*ProtocolStr ) return FALSE;
+    **ProtocolStr = 0; (*ProtocolStr)++;
+
+    WS_DbgPrint(MAX_TRACE, ("Parsing done: %s %s %s %d\n",
+			    *ServiceName, *ProtocolStr, *PortNumberStr,
+			    NAliases));
+
+    return TRUE;
+}
+
+#define ADJ_PTR(p,b1,b2) p = (p - b1) + b2
 
 /*
- * @unimplemented
+ * @implemented
  */
 LPSERVENT
 EXPORT
@@ -430,9 +484,157 @@
     IN  CONST CHAR FAR* name, 
     IN  CONST CHAR FAR* proto)
 {
-    UNIMPLEMENTED
+    BOOL  Found = FALSE;
+    HANDLE ServicesFile;
+    CHAR ServiceDBData[BUFSIZ] = { 0 };
+    PCHAR SystemDirectory = ServiceDBData; /* Reuse this stack space */
+    PCHAR ServicesFileLocation = "\\drivers\\etc\\services";
+    PCHAR ThisLine = 0, NextLine = 0, ServiceName = 0, PortNumberStr = 0, 
+	ProtocolStr = 0, Comment = 0;
+    PCHAR Aliases[WS2_INTERNAL_MAX_ALIAS] = { 0 };
+    UINT i,SizeNeeded = 0, 
+	SystemDirSize = sizeof(ServiceDBData) - 1;
+    DWORD ReadSize = 0, ValidData = 0;
+    PWINSOCK_THREAD_BLOCK p = NtCurrentTeb()->WinSockData;
+    
+    if( !p ) {
+	WSASetLastError( WSANOTINITIALISED );
+	return NULL;
+    }
 
-    return (LPSERVENT)NULL;
+    if( !name ) {
+	WSASetLastError( WSANO_RECOVERY );
+	return NULL;
+    }
+    
+    if( !GetSystemDirectoryA( SystemDirectory, SystemDirSize ) ) {
+	WSASetLastError( WSANO_RECOVERY );
+	WS_DbgPrint(MIN_TRACE, ("Could not get windows system directory.\n"));
+	return NULL; /* Can't get system directory */
+    }
+    
+    strncat( SystemDirectory, ServicesFileLocation, SystemDirSize );
+
+    ServicesFile = CreateFileA( SystemDirectory,
+				GENERIC_READ,
+				FILE_SHARE_READ,
+				NULL,
+				OPEN_EXISTING,
+				FILE_ATTRIBUTE_NORMAL | 
+				FILE_FLAG_SEQUENTIAL_SCAN,
+				NULL );
+
+    if( ServicesFile == INVALID_HANDLE_VALUE ) {
+	WSASetLastError( WSANO_RECOVERY );
+	return NULL;
+    }
+
+    /* Scan the services file ... 
+     *
+     * We will read up to BUFSIZ bytes per pass, until the buffer does not
+     * contain a full line, then we will try to read more.
+     *
+     * We fall from the loop if the buffer does not have a line terminator.
+     */
+
+    /* Initial Read */
+    while( !Found &&
+	   ReadFile( ServicesFile, ServiceDBData + ValidData,
+		     sizeof( ServiceDBData ) - ValidData,
+		     &ReadSize, NULL ) ) {
+	ValidData += ReadSize;
+	ReadSize = 0;
+	NextLine = ThisLine = ServiceDBData;
+
+	/* Find the beginning of the next line */
+	while( NextLine < ServiceDBData + ValidData &&
+	       *NextLine != '\r' && *NextLine != '\n' ) NextLine++;
+	
+	/* Zero and skip, so we can treat what we have as a string */
+	if( NextLine >= ServiceDBData + ValidData ) 
+	    break;
+
+	*NextLine = 0; NextLine++;
+
+	Comment = strchr( ThisLine, '#' );
+	if( Comment ) *Comment = 0; /* Terminate at comment start */
+
+	if( DecodeServEntFromString( ThisLine, 
+				     &ServiceName, 
+				     &PortNumberStr,
+				     &ProtocolStr,
+				     Aliases,
+				     WS2_INTERNAL_MAX_ALIAS ) &&
+	    !strcmp( ServiceName, name ) &&
+	    (proto ? !strcmp( ProtocolStr, proto ) : TRUE) ) {
+	    WS_DbgPrint(MAX_TRACE,("Found the service entry.\n"));
+
+	    Found = TRUE;
+	    SizeNeeded = sizeof(WINSOCK_GETSERVBYNAME_CACHE) + 
+		(NextLine - ThisLine);
+	    break;
+	}
+
+	/* Get rid of everything we read so far */
+	while( NextLine <= ServiceDBData + ValidData &&
+	       isspace( *NextLine ) ) NextLine++;
+
+	WS_DbgPrint(MAX_TRACE,("About to move %d chars\n", 
+			       ServiceDBData + ValidData - NextLine));
+
+	memmove( ServiceDBData, NextLine, 
+		 ServiceDBData + ValidData - NextLine );
+	ValidData -= NextLine - ServiceDBData;
+	WS_DbgPrint(MAX_TRACE,("Valid bytes: %d\n", ValidData));
+    }
+
+    /* This we'll do no matter what */
+    CloseHandle( ServicesFile );
+    
+    if( !Found ) {
+	WS_DbgPrint(MAX_TRACE,("Not found\n"));
+	WSASetLastError( WSANO_DATA );
+	return NULL;
+    }
+    
+    if( !p->Getservbyname || p->Getservbyname->Size < SizeNeeded ) {
+	/* Free previous getservbyname buffer, allocate bigger */
+	if( p->Getservbyname ) 
+	    HeapFree(GlobalHeap, 0, p->Getservbyname);
+	p->Getservbyname = HeapAlloc(GlobalHeap, 0, SizeNeeded);
+	if( !p->Getservbyname ) {
+	    WS_DbgPrint(MIN_TRACE,("Couldn't allocate %d bytes\n", 
+				   SizeNeeded));
+	    WSASetLastError( WSATRY_AGAIN );
+	    return NULL;
+	}
+	p->Getservbyname->Size = SizeNeeded;
+    }
+
+    /* Copy the data */
+    memmove( p->Getservbyname->Data, 
+	     ThisLine,
+	     NextLine - ThisLine );
+
+    ADJ_PTR(ServiceName,ThisLine,p->Getservbyname->Data);
+    ADJ_PTR(ProtocolStr,ThisLine,p->Getservbyname->Data);
+    WS_DbgPrint(MAX_TRACE,
+		("ServiceName: %s, Protocol: %s\n", ServiceName, ProtocolStr));
+		
+    for( i = 0; Aliases[i]; i++ ) {
+	ADJ_PTR(Aliases[i],ThisLine,p->Getservbyname->Data);
+	WS_DbgPrint(MAX_TRACE,("Aliase %d: %s\n", i, Aliases[i]));
+    }
+
+    memcpy(p->Getservbyname,Aliases,sizeof(Aliases));
+
+    /* Create the struct proper */
+    p->Getservbyname->ServerEntry.s_name = ServiceName;
+    p->Getservbyname->ServerEntry.s_aliases = p->Getservbyname->Aliases;
+    p->Getservbyname->ServerEntry.s_port = htons(atoi(PortNumberStr));
+    p->Getservbyname->ServerEntry.s_proto = ProtocolStr;
+
+    return &p->Getservbyname->ServerEntry;
 }
 
 
CVSspam 0.2.8