diff -urP linux/Documentation/Configure.help linux/Documentation/Configure.help
--- linux/Documentation/Configure.help	Tue Jan  4 13:12:10 2000
+++ linux/Documentation/Configure.help	Thu Feb 10 17:29:48 2000
@@ -12039,7 +12039,40 @@
 
   If you do not have any Quicknet telephony cards, you can safely
   ignore this option.
- 
+
+Deny packets with SYN and FIN set.
+CONFIG_TCPIP_STACK_SYNFIN
+  This will DENY all incoming packets with the SYN & FIN flags set.  Much
+  like the option TCP_DROP_SYNFIN in the FreeBSD kernel config.  This
+  breaks RFC 1644 but say Y if security is more important.
+
+Drop packets without SYN, FIN or RST
+CONFIG_TCPIP_STACK_BOGUS
+  All incoming TCP packets must have either SYN, FIN or RST set, or the
+  packet will be dropped. Say Y if security is more important.
+
+Deny packets looking for ACK values
+CONFIG_TCPIP_STACK_ACK
+  Typlicly OS detection tools will send packets to an open port looking for
+  the ACK to be the same as the ISN, or ISN++.  This will deny incoming TCP
+  packets with FIN, PSH and URG set, thus blocking packets with SYN, 
+  FIN, URG and PSH also.  Packets of these structure are use in OS detection
+  utilites such as nmap (test 3 & 7).  Say Y if security is more important.
+
+Block outgoing ICMP Port Unreachable Messages
+CONFIG_TCPIP_STACK_ICMP_PU
+  Instead of limiting the rate that the kernel sends destination port 
+  unreachable messages, totaly block them.  Setting this will block all UDP
+  portscans, and block packets used for OS detection (nmap's PU test). This
+  breaks allot of RFC's, as do many of these TCPIP configurable stack
+  options. Say N if you plan to do this with ipchains, otherwise say Y.
+
+Log all packets with bad flags
+CONFIG_TCPIP_STACK_LOG
+  This would probably be a good idea if you are interested in knowing what
+  is going on, on your system.  Any TCP packets you set to deny above will
+  be logged, the logs will also include the flags used.
+
 #
 # A couple of things I keep forgetting:
 #   capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, 
diff -urP linux/arch/i386/config.in linux/arch/i386/config.in
--- linux/arch/i386/config.in	Tue Jan  4 13:12:11 2000
+++ linux/arch/i386/config.in	Thu Feb 10 17:29:48 2000
@@ -207,3 +207,12 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+mainmenu_option next_comment
+comment 'TCP/IP stack options'
+
+bool 'Deny packets with SYN and FIN set' CONFIG_TCPIP_STACK_SYNFIN
+bool 'Drop packets without SYN, FIN or RST' CONFIG_TCPIP_STACK_BOGUS
+bool 'Deny packets looking for ACK values' CONFIG_TCPIP_STACK_ACK
+bool 'Block outgoing ICMP Port Unreachable Messages' CONFIG_TCPIP_STACK_ICMP_PU
+bool 'Log all packets with bad tcp flags' CONFIG_TCPIP_STACK_LOG
+endmenu
diff -urP linux/arch/i386/defconfig linux/arch/i386/defconfig
--- linux/arch/i386/defconfig	Wed Aug 25 20:29:46 1999
+++ linux/arch/i386/defconfig	Thu Feb 10 17:29:48 2000
@@ -354,6 +354,15 @@
 # CONFIG_SOUND is not set
 
 #
+# TCP/IP stack
+#
+CONFIG_TCPIP_STACK_SYNFIN=y
+CONFIG_TCPIP_STACK_BOGUS=y
+CONFIG_TCPIP_STACK_ACK=y
+CONFIG_TCPIP_STACK_ICMP_PU=n
+CONFIG_TCPIP_STACK_LOG=y
+
+#
 # Kernel hacking
 #
 # CONFIG_MAGIC_SYSRQ is not set
diff -urP linux/net/ipv4/tcp_ipv4.c linux/net/ipv4/tcp_ipv4.c
--- linux/net/ipv4/tcp_ipv4.c	Tue Jan  4 13:12:27 2000
+++ linux/net/ipv4/tcp_ipv4.c	Thu Feb 10 17:34:59 2000
@@ -1708,6 +1708,21 @@
 	if (len < sizeof(struct tcphdr))
 		goto bad_packet;
 
+#ifdef CONFIG_TCPIP_STACK_SYNFIN
+       if(th->fin && th->syn)
+               goto tcp_bad_flag;
+#endif
+
+#ifdef CONFIG_TCPIP_STACK_BOGUS
+       if(!(th->ack || th->syn || th->rst))
+               goto tcp_bad_flag;
+#endif
+
+#ifdef CONFIG_TCPIP_STACK_ACK
+       if(th->fin && th->psh && th->urg)
+               goto tcp_bad_flag;
+#endif
+
 	/* Try to use the device checksum if provided. */
 	switch (skb->ip_summed) {
 	case CHECKSUM_NONE:
@@ -1768,6 +1783,31 @@
 
 	__skb_queue_tail(&sk->back_log, skb);
 	return 0;
+
+#ifdef CONFIG_TCPIP_STACK_LOG
+               
+tcp_bad_flag:
+       printk(KERN_INFO
+               "Packet log: badflag DENY %s PROTO=TCP %d.%d.%d.%d:%d "
+               "%d.%d.%d.%d:%d L=%hu:%u:%u S=0x%2.2hX I=%hu:%u:%u "
+               "T=%hu %c%c%c%c%c%c\n",
+               skb->dev->name, NIPQUAD(skb->nh.iph->saddr), ntohs(th->source),
+               NIPQUAD(skb->nh.iph->daddr), ntohs(th->dest),
+               ntohs(skb->nh.iph->tot_len), skb->len, skb->len - th->doff*4,
+               skb->nh.iph->tos, ntohs(skb->nh.iph->id), ntohl(th->seq),
+               ntohl(th->ack_seq), skb->nh.iph->ttl,
+               th->ack ? 'A' : '.',
+               th->syn ? 'S' : '.',
+               th->fin ? 'F' : '.',
+               th->rst ? 'R' : '.',
+               th->psh ? 'P' : '.',
+               th->urg ? 'U' : '.' );
+       goto bad_packet;
+
+#else
+tcp_bad_flag:
+       goto bad_packet;
+#endif
 
 no_tcp_socket:
 	tcp_v4_send_reset(skb);
diff -urP linux/net/ipv4/udp.c linux/net/ipv4/udp.c
--- linux/net/ipv4/udp.c	Mon Aug  9 15:05:10 1999
+++ linux/net/ipv4/udp.c	Thu Feb 10 17:29:48 2000
@@ -1131,9 +1131,12 @@
 		    (unsigned short)csum_fold(csum_partial((char*)uh, ulen, skb->csum))) 
 			goto csum_error;
 #endif
-  		udp_statistics.UdpNoPorts++;
-		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
 
+  		udp_statistics.UdpNoPorts++;
+#ifdef CONFIG_TCPIP_STACK_ICMP_PU
+#else		
+ 		icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
+#endif
 		/*
 		 * Hmm.  We got an UDP broadcast to a port to which we
 		 * don't wanna listen.  Ignore it.
