diff -uNrd ircd-hybrid-6.dist/include/client.h ircd-hybrid-6/include/client.h
--- ircd-hybrid-6.dist/include/client.h	Mon Dec 10 22:27:18 2001
+++ ircd-hybrid-6/include/client.h	Mon Dec 10 23:33:42 2001
@@ -238,6 +238,9 @@
   time_t            last_nick_change;
   int               number_of_nick_changes;
 #endif
+#ifdef ANTI_IP_SPOOF
+  unsigned int random_ping;
+#endif
   time_t            last_knock; /* don't allow knock to flood */
   /*
    * client->sockhost contains the ip address gotten from the socket as a
@@ -348,6 +351,10 @@
 #define FLAGS2_B_LINED      0x0008      /* client is graced with B line */
 #define FLAGS2_F_LINED      0x0010      /* client is graced with F line */
 #define FLAGS2_EXEMPTGLINE  0x2000      /* client can't be G-lined */
+
+#ifdef ANTI_IP_SPOOF
+# define FLAGS2_GOT_ANTI_SPOOF_PING    0x800000
+#endif
 
 /* oper priv flags */
 #define FLAGS2_OPER_GLOBAL_KILL 0x0020  /* oper can global kill */
diff -uNrd ircd-hybrid-6.dist/include/config.h ircd-hybrid-6/include/config.h
--- ircd-hybrid-6.dist/include/config.h	Mon Dec 10 22:27:18 2001
+++ ircd-hybrid-6/include/config.h	Mon Dec 10 22:46:15 2001
@@ -674,6 +674,13 @@
  */
 #undef  NO_PRIORITY
 
+/* ANTI_IP_SPOOF - protects against TCP sequence guessing attacks
+ * Define this if you want the server to send a random ping at USER or NICK
+ * to defeat IP sequence spoofers. Note, this will stop _some_ very few
+ * clients from using the server. MIRC/IRCII clients are fine with this though
+ */
+#define ANTI_IP_SPOOF
+
 /* ----------------- not approved on EFnet section --------------------
  *
  * if you are not an efnet admin - we recommend you enable most of these.. 
diff -uNrd ircd-hybrid-6.dist/include/config.h.dist ircd-hybrid-6/include/config.h.dist
--- ircd-hybrid-6.dist/include/config.h.dist	Mon Dec 10 22:27:18 2001
+++ ircd-hybrid-6/include/config.h.dist	Mon Dec 10 22:46:35 2001
@@ -674,6 +674,13 @@
  */
 #undef  NO_PRIORITY
 
+/* ANTI_IP_SPOOF - protects against TCP sequence guessing attacks
+ * Define this if you want the server to send a random ping at USER or NICK
+ * to defeat IP sequence spoofers. Note, this will stop _some_ very few
+ * clients from using the server. MIRC/IRCII clients are fine with this though
+ */
+#define ANTI_IP_SPOOF
+
 /* ----------------- not approved on EFnet section --------------------
  *
  * if you are not an efnet admin - we recommend you enable most of these.. 
diff -uNrd ircd-hybrid-6.dist/include/msg.h ircd-hybrid-6/include/msg.h
--- ircd-hybrid-6.dist/include/msg.h	Mon Dec 10 22:27:19 2001
+++ ircd-hybrid-6/include/msg.h	Mon Dec 10 22:51:33 2001
@@ -180,7 +180,12 @@
 #ifdef IDLE_FROM_MSG
 
   /* Only m_private has reset idle flag set */
+#ifdef ANTI_IP_SPOOF
+  /* if ANTI_IP_SPOOF, allow user to PONG even when not registered */
+  { MSG_PONG,    m_pong,     0, MAXPARA, 1, 1, 0, 0L },
+#else
   { MSG_PONG,    m_pong,     0, MAXPARA, 1, 0, 0, 0L },
+#endif
   { MSG_PING,    m_ping,     0, MAXPARA, 1, 0, 0, 0L },
 
 #else
@@ -190,7 +195,12 @@
    * when its 0, for IDLE_FROM_MSG ping/pong do not reset idle time
    */
 
+#ifdef ANTI_IP_SPOOF
+  /* if ANTI_IP_SPOOF, allow user to PONG even when not registered */
+  { MSG_PONG,    m_pong,     0, MAXPARA, 1, 1, 0, 0L },
+#else
   { MSG_PONG,    m_pong,     0, MAXPARA, 1, 0, 1, 0L },
+#endif
   { MSG_PING,    m_ping,     0, MAXPARA, 1, 0, 1, 0L },
 
 #endif  /* IDLE_FROM_MSG */
diff -uNrd ircd-hybrid-6.dist/include/s_stats.h ircd-hybrid-6/include/s_stats.h
--- ircd-hybrid-6.dist/include/s_stats.h	Mon Dec 10 22:27:20 2001
+++ ircd-hybrid-6/include/s_stats.h	Mon Dec 10 22:52:07 2001
@@ -65,6 +65,9 @@
 #ifdef FLUD
   unsigned int    is_flud;        /* users/channels flood protected */
 #endif /* FLUD */
+#ifdef ANTI_IP_SPOOF
+  unsigned int    is_ipspoof;
+#endif
 };
 
 extern struct ServerStatistics* ServerStats;
diff -uNrd ircd-hybrid-6.dist/src/.depend ircd-hybrid-6/src/.depend
--- ircd-hybrid-6.dist/src/.depend	Mon Dec 10 22:27:12 2001
+++ ircd-hybrid-6/src/.depend	Mon Dec 10 23:14:44 2001
@@ -30,8 +30,8 @@
  ../include/numeric.h ../include/res.h ../include/fileio.h \
  ../include/../adns/adns.h ../include/s_bsd.h ../include/s_conf.h \
  ../include/motd.h ../include/s_log.h ../include/s_misc.h \
- ../include/s_serv.h ../include/send.h ../include/struct.h \
- ../include/whowas.h ../include/s_debug.h
+ ../include/s_serv.h ../include/s_stats.h ../include/send.h \
+ ../include/struct.h ../include/whowas.h ../include/s_debug.h
 dbuf.o: dbuf.c ../include/dbuf.h ../include/config.h \
  ../include/setup.h ../include/common.h ../include/irc_string.h \
  ../include/ircd_defs.h
@@ -228,7 +228,8 @@
 m_pong.o: m_pong.c ../include/m_commands.h ../include/config.h \
  ../include/setup.h ../include/client.h ../include/ircd_defs.h \
  ../include/dbuf.h ../include/ircd.h ../include/numeric.h \
- ../include/send.h ../include/channel.h ../include/irc_string.h
+ ../include/send.h ../include/channel.h ../include/s_stats.h \
+ ../include/irc_string.h
 m_quit.o: m_quit.c ../include/m_commands.h ../include/config.h \
  ../include/setup.h ../include/client.h ../include/ircd_defs.h \
  ../include/dbuf.h ../include/ircd.h ../include/numeric.h \
diff -uNrd ircd-hybrid-6.dist/src/client.c ircd-hybrid-6/src/client.c
--- ircd-hybrid-6.dist/src/client.c	Mon Dec 10 22:27:13 2001
+++ ircd-hybrid-6/src/client.c	Mon Dec 10 22:54:05 2001
@@ -42,6 +42,7 @@
 #include "s_log.h"
 #include "s_misc.h"
 #include "s_serv.h"
+#include "s_stats.h"
 #include "send.h"
 #include "struct.h"
 #include "whowas.h"
@@ -543,6 +544,10 @@
                   sendto_ops("No response from %s, closing link",
                              get_client_name(cptr, MASK_IP));
                 }
+#ifdef ANTI_IP_SPOOF
+               if (!IsRegistered(cptr) && (cptr->name[0]) && (cptr->user))
+                 ServerStats->is_ipspoof++;
+#endif
               /*
                * this is used for KILL lines with time restrictions
                * on them - send a messgae to the user being killed
diff -uNrd ircd-hybrid-6.dist/src/m_pong.c ircd-hybrid-6/src/m_pong.c
--- ircd-hybrid-6.dist/src/m_pong.c	Mon Dec 10 22:27:15 2001
+++ ircd-hybrid-6/src/m_pong.c	Mon Dec 10 23:53:11 2001
@@ -28,6 +28,7 @@
 #include "numeric.h"
 #include "send.h"
 #include "channel.h"
+#include "s_stats.h"
 #include "irc_string.h"
 
 #ifdef DEBUGMODE
@@ -139,6 +140,35 @@
       if (MyConnect(sptr))
       {
         sptr->flags &= ~FLAGS_PINGSENT;
+#ifdef ANTI_IP_SPOOF
+  /* ANTI_IP_SPOOF delays the registration of a local client until after we
+     have received a response from a PING containing a random integer.  When
+     we receive the resulting PONG, then we register the client.
+  */
+
+  if(MyConnect(sptr) && !IsRegisteredUser(sptr) && sptr->random_ping) {
+      unsigned int received_random_ping;
+      received_random_ping = strtoul(origin, (char **)NULL, 10);
+
+      if(received_random_ping) {
+          /* Ensure that aClient has a user and a nick (redundant) */
+          if((sptr->user) && (sptr->name[0])) {
+              if(received_random_ping == sptr->random_ping) {
+                  char buf[USERLEN + 1];
+                  strncpy_irc(buf, sptr->username, USERLEN);
+                  buf[USERLEN] = '\0';
+
+                  sptr->flags2 |= FLAGS2_GOT_ANTI_SPOOF_PING;
+                  register_user(cptr, sptr, sptr->name, buf);
+                  return 0;
+              } else {
+                 ServerStats->is_ipspoof++;
+                 return exit_client(cptr,sptr,&me,"Wrong randon PONG response.");
+              }
+          }
+      }
+  }
+#endif
 #ifdef NEED_SPLITCODE
 #ifdef SPLIT_PONG
         if (IsServer(sptr))
diff -uNrd ircd-hybrid-6.dist/src/s_user.c ircd-hybrid-6/src/s_user.c
--- ircd-hybrid-6.dist/src/s_user.c	Mon Dec 10 22:27:17 2001
+++ ircd-hybrid-6/src/s_user.c	Mon Dec 10 23:44:23 2001
@@ -504,7 +504,7 @@
 **         nick from local user or kill him/her...
 */
 
-static int register_user(aClient *cptr, aClient *sptr, 
+int register_user(aClient *cptr, aClient *sptr, 
                          char *nick, char *username)
 {
   aConfItem*  aconf;
@@ -1183,6 +1183,11 @@
 
               sendto_common_channels(sptr, ":%s NICK :%s", parv[0], nick);
               if (sptr->user)
+#ifdef ANTI_IP_SPOOF
+       /* Don't send out a nick-change if they haven't PONG'd us
+        * because they haven't registered yet if they haven't! -JailBird */
+       if ((!MyConnect(sptr)) || (sptr->flags2 & FLAGS2_GOT_ANTI_SPOOF_PING)) 
+#endif
                 {
                   add_history(sptr,1);
               
@@ -1232,6 +1237,19 @@
           ** may reject the client and call exit_client for it
           ** --must test this and exit m_nick too!!!
           */
+/* anti ip sequence prediction spoof code
+   it needs a good going over by someone else, but it
+   works... -Dianora
+*/
+#ifdef ANTI_IP_SPOOF
+       if(MyConnect(sptr))
+       {
+               strcpy(sptr->name,nick);
+               sptr->random_ping = (unsigned int)my_rand();
+               sendto_one(sptr, "PING :%u", sptr->random_ping);
+               sptr->flags |= FLAGS_PINGSENT;
+       } else
+#endif
             if (register_user(cptr, sptr, nick, buf) == CLIENT_EXITED)
               return CLIENT_EXITED;
         }
@@ -1915,6 +1933,22 @@
       user->server = me.name;
     }
   strncpy_irc(sptr->info, realname, REALLEN);
+
+#ifdef ANTI_IP_SPOOF
+  user->last = CurrentTime;
+  if(MyConnect(sptr))
+     {
+       if (sptr->name[0]) /* NICK already received, now I have USER... */
+         {
+          sptr->random_ping = (unsigned int)my_rand();
+          sendto_one(sptr, "PING :%u", sptr->random_ping);
+          sptr->flags |= FLAGS_PINGSENT;  
+        }
+       if (!IsGotId(sptr))
+         strncpy_irc(sptr->username, username, USERLEN);
+       return 0;
+     } 
+#endif
 
   if (sptr->name[0]) /* NICK already received, now I have USER... */
     return register_user(cptr, sptr, sptr->name, username);
