diff -uNrd ircd-ratbox-1.1-2/include/client.h ircd-ratbox-1.1-2-umode-X/include/client.h
--- ircd-ratbox-1.1-2/include/client.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/client.h	Mon Jul 14 10:01:49 2003
@@ -152,6 +152,7 @@
 	 * considered a read-only field after the client has registered.
 	 */
 	char host[HOSTLEN + 1];	/* client's hostname */
+	char rhost[HOSTLEN + 1]; /* client's real hostname */
 	/*
 	 * client->info for unix clients will normally contain the info from the 
 	 * gcos field in /etc/passwd but anything can go here.
@@ -379,6 +380,7 @@
 #define UMODE_CALLERID     0x2000	/* block unless caller id's */
 #define UMODE_UNAUTH       0x4000	/* show unauth connects here */
 #define UMODE_LOCOPS       0x8000	/* show locops */
+#define UMODE_IPMASK       0x80000      /* client's hostname is masked */
 
 /* user information flags, only settable by remote mode or local oper */
 #define UMODE_OPER         0x20000	/* Operator */
@@ -419,12 +421,12 @@
 #define FLAGS2_FLOODDONE        0x800000
 
 #define SEND_UMODES  (UMODE_INVISIBLE | UMODE_OPER | UMODE_WALLOP | \
-                      UMODE_ADMIN)
+                      UMODE_ADMIN | UMODE_IPMASK)
 #define ALL_UMODES   (SEND_UMODES | UMODE_SERVNOTICE | UMODE_CCONN | \
                       UMODE_REJ | UMODE_SKILL | UMODE_FULL | UMODE_SPY | \
                       UMODE_NCHANGE | UMODE_OPERWALL | UMODE_DEBUG | \
                       UMODE_BOTS | UMODE_EXTERNAL | UMODE_LOCOPS | \
- 		      UMODE_ADMIN | UMODE_UNAUTH | UMODE_CALLERID)
+ 		      UMODE_ADMIN | UMODE_UNAUTH | UMODE_CALLERID )
 
 #define FLAGS_ID     (FLAGS_NEEDID | FLAGS_GOTID)
 
@@ -492,6 +494,7 @@
 #define SetWallops(x)           ((x)->umodes |= UMODE_WALLOP)
 #define SetCallerId(x)		((x)->umodes |= UMODE_CALLERID)
 #define IsSetCallerId(x)	((x)->umodes & UMODE_CALLERID)
+#define IsMasked(x)		((x)->umodes & UMODE_IPMASK)
 
 #define SetNeedId(x)            ((x)->flags |= FLAGS_NEEDID)
 #define IsNeedId(x)             (((x)->flags & FLAGS_NEEDID) != 0)
diff -uNrd ircd-ratbox-1.1-2/include/ircd.h ircd-ratbox-1.1-2-umode-X/include/ircd.h
--- ircd-ratbox-1.1-2/include/ircd.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/ircd.h	Sun Jul 13 19:32:51 2003
@@ -117,4 +117,6 @@
 extern unsigned long get_maxrss(void);
 extern void set_time(void);
 
+int svshost_check (void);
+
 #endif
diff -uNrd ircd-ratbox-1.1-2/include/newconf.h ircd-ratbox-1.1-2-umode-X/include/newconf.h
--- ircd-ratbox-1.1-2/include/newconf.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/newconf.h	Sat Jul 19 18:44:59 2003
@@ -101,6 +101,8 @@
 void conf_set_serverinfo_max_clients(void *data);
 void conf_set_serverinfo_max_buffer(void *data);
 void conf_set_serverinfo_hub(void *data);
+void conf_set_serverinfo_skip_svshost_check(void *data);
+void conf_set_serverinfo_disallow_masking(void *data);
 
 void conf_set_modules_path(void *data);
 void conf_set_modules_module(void *data);
@@ -174,6 +176,8 @@
 void conf_set_auth_no_tilde(void *data);
 void conf_set_auth_gline_exempt(void *data);
 void conf_set_auth_flood_exempt(void *data);
+void conf_set_auth_mask(void *data);
+void conf_set_auth_no_mask_notice(void *data);
 void conf_set_auth_redir_serv(void *data);
 void conf_set_auth_redir_port(void *data);
 void conf_set_auth_class(void *data);
diff -uNrd ircd-ratbox-1.1-2/include/numeric.h ircd-ratbox-1.1-2-umode-X/include/numeric.h
--- ircd-ratbox-1.1-2/include/numeric.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/numeric.h	Tue Jul 15 09:21:23 2003
@@ -183,12 +183,16 @@
 #define RPL_ENDOFBANLIST     368
 /* rpl_endofwhowas above (369) */
 
+#define RPL_WHOWASHOST       370
+
 #define RPL_INFO             371
 #define RPL_MOTD             372
 #define RPL_INFOSTART        373
 #define RPL_ENDOFINFO        374
 #define RPL_MOTDSTART        375
 #define RPL_ENDOFMOTD        376
+
+#define RPL_WHOISHOST        378
 
 #define RPL_YOUREOPER        381
 #define RPL_REHASHING        382
diff -uNrd ircd-ratbox-1.1-2/include/patchlevel.h ircd-ratbox-1.1-2-umode-X/include/patchlevel.h
--- ircd-ratbox-1.1-2/include/patchlevel.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/patchlevel.h	Sun Jul 13 19:32:52 2003
@@ -25,5 +25,5 @@
  */
 
 #ifndef PATCHLEVEL
-#define PATCHLEVEL   "ircd-ratbox-1.1-1"
+#define PATCHLEVEL   "ircd-ratbox-1.1-1+ipmask"
 #endif
diff -uNrd ircd-ratbox-1.1-2/include/s_conf.h ircd-ratbox-1.1-2-umode-X/include/s_conf.h
--- ircd-ratbox-1.1-2/include/s_conf.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/s_conf.h	Sat Jul 19 18:38:19 2003
@@ -138,6 +138,8 @@
 #define CONF_FLAGS_TEMPORARY            0x00080000
 #define CONF_FLAGS_CRYPTLINK            0x00100000
 #define CONF_FLAGS_VHOSTED		0x00200000
+#define CONF_FLAGS_IPMASK		0x00400000
+#define CONF_FLAGS_NO_MASK_NOTICE	0x00800000
 /* Macros for struct ConfItem */
 
 #define IsLimitIp(x)            ((x)->flags & CONF_FLAGS_LIMIT_IP)
@@ -158,6 +160,8 @@
 #define IsConfCompressed(x)     ((x)->flags & CONF_FLAGS_COMPRESSED)
 #define IsConfCryptLink(x)      ((x)->flags & CONF_FLAGS_CRYPTLINK)
 #define IsConfVhosted(x)	((x)->flags & CONF_FLAGS_VHOSTED)
+#define IsConfDoMaskIp(x)	((x)->flags & CONF_FLAGS_IPMASK)
+#define IsConfNoMaskNotice(x)	((x)->flags & CONF_FLAGS_NO_MASK_NOTICE)
 
 /* flag definitions for opers now in client.h */
 
@@ -296,6 +300,8 @@
 	int specific_ipv4_vhost;
 	int specific_ipv6_vhost;
 	struct sockaddr_in dns_host;
+	int skip_svshost_check;
+	int disallow_masking;
 };
 
 struct admin_info
diff -uNrd ircd-ratbox-1.1-2/include/s_serv.h ircd-ratbox-1.1-2-umode-X/include/s_serv.h
--- ircd-ratbox-1.1-2/include/s_serv.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/s_serv.h	Tue Jul 15 09:03:37 2003
@@ -74,12 +74,14 @@
 #define CAP_UNKLN       0x00100000	/* supports remote unkline */
 #define CAP_CLUSTER	0x00200000	/* supports clustering */
 #define CAP_ENCAP	0x00400000
+#define CAP_IPMASK	0x00800000
+#define CAP_SVS		0x01000000
 
 #define CAP_MASK        (CAP_QS  | CAP_EX   | CAP_CHW  | \
                          CAP_IE  | CAP_EOB  | CAP_KLN  | \
                          CAP_GLN | CAP_CLUSTER | CAP_ENCAP | \
-                         CAP_UID | CAP_ZIP  | CAP_ENC | \
-                         CAP_KNOCK  | CAP_UNKLN)
+                         CAP_ZIP  | CAP_ENC | \
+                         CAP_KNOCK  | CAP_UNKLN | CAP_IPMASK | CAP_SVS)
 
 #ifdef HAVE_LIBZ
 #define CAP_ZIP_SUPPORTED       CAP_ZIP
diff -uNrd ircd-ratbox-1.1-2/include/s_user.h ircd-ratbox-1.1-2-umode-X/include/s_user.h
--- ircd-ratbox-1.1-2/include/s_user.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/s_user.h	Sun Jul 13 19:32:52 2003
@@ -42,7 +42,7 @@
 extern int do_local_user(char *, struct Client *, struct Client *, char *, char *, char *, char *);
 
 extern int do_remote_user(char *, struct Client *, struct Client *,
-			  char *, char *, char *, char *, char *);
+			  char *, char *, char *, char *, char *, char *);
 
 extern int user_modes_from_c_to_bitmask[];
 extern void show_isupport(struct Client *);
diff -uNrd ircd-ratbox-1.1-2/include/whowas.h ircd-ratbox-1.1-2-umode-X/include/whowas.h
--- ircd-ratbox-1.1-2/include/whowas.h	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/include/whowas.h	Sun Jul 13 19:32:52 2003
@@ -51,6 +51,7 @@
 	char name[NICKLEN];
 	char username[USERLEN + 1];
 	char hostname[HOSTLEN + 1];
+	char rhostname[HOSTLEN + 1];
 	const char *servername;
 	char realname[REALLEN + 1];
 	time_t logoff;
diff -uNrd ircd-ratbox-1.1-2/modules/Makefile.in ircd-ratbox-1.1-2-umode-X/modules/Makefile.in
--- ircd-ratbox-1.1-2/modules/Makefile.in	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/modules/Makefile.in	Sun Jul 13 19:32:52 2003
@@ -87,6 +87,7 @@
   m_set.c \
   m_stats.c \
   m_svinfo.c \
+  m_svs.c \
   m_testline.c \
   m_time.c \
   m_topic.c \
diff -uNrd ircd-ratbox-1.1-2/modules/core/m_nick.c ircd-ratbox-1.1-2-umode-X/modules/core/m_nick.c
--- ircd-ratbox-1.1-2/modules/core/m_nick.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/modules/core/m_nick.c	Tue Jul 15 09:15:59 2003
@@ -270,7 +270,8 @@
  *    parv[5] = username
  *    parv[6] = hostname
  *    parv[7] = server
- *    parv[8] = ircname
+ *    parc[8] = realhost
+ *    parv[9] = ircname
  */
 static void
 ms_nick(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
@@ -286,7 +287,7 @@
 	}
 
 	/* parc == 3 on nickchange, parc == 9 on new nick */
-	if((IsClient(source_p) && (parc != 3)) || (IsServer(source_p) && (parc != 9)))
+	if((IsClient(source_p) && (parc != 3)) || (IsServer(source_p) && ((parc != 9) && (parc != 10))))
 	{
 		char tbuf[BUFSIZE] = { 0 };
 		int j;
@@ -311,23 +312,30 @@
 	/* fix the length of the nick */
 	strlcpy(nick, parv[1], sizeof(nick));
 
-	if(check_clean_nick(client_p, source_p, nick, parv[1], 
-			    (parc == 9 ? parv[7] : (char *)source_p->user->server)))
-		return;
+	if(parc == 9 || parc == 10)
+	{
+		if(check_clean_nick(client_p, source_p, nick, parv[1], parv[7]))
+			return;
+	}
+	else
+	{
+		if(check_clean_nick(client_p, source_p, nick, parv[1], (char *)source_p->user->server))
+			return;
+	}
 
-	if(parc == 9)
+	if(parc == 9 || parc == 10)
 	{
 		if(check_clean_user(client_p, nick, parv[5], parv[7]) ||
 		   check_clean_host(client_p, nick, parv[6], parv[7]))
 			return;
 
 		/* check the length of the clients gecos */
-		if(strlen(parv[8]) > REALLEN)
+		if(strlen(parv[(parc > 9)? 9 : 8]) > REALLEN)
 		{
 			sendto_realops_flags(UMODE_ALL, L_ALL,
 					     "Long realname from server %s for %s", parv[7],
 					     parv[1]);
-			parv[8][REALLEN] = '\0';
+			parv[(parc > 9)? 9 : 8][REALLEN] = '\0';
 		}
 
 		if(IsServer(source_p))
@@ -385,7 +393,7 @@
 	char *name;
 
 	id = parv[8];
-	name = parv[9];
+	name = parv[(parc > 10)? 10 : 9];
 
 	/* parse the nickname */
 	strlcpy(nick, parv[1], sizeof(nick));
@@ -670,7 +678,7 @@
 			}
 
 			return do_remote_user(nick, client_p, source_p, parv[5], parv[6],
-					      parv[7], parv[8], NULL);
+					      parv[7], (parc > 9)? parv[8] : NULL, parv[(parc > 9)? 9 : 8], NULL);
 		}
 	}
 	else if(source_p->name[0])
@@ -747,7 +755,7 @@
 
 	}
 
-	return do_remote_user(nick, client_p, source_p, parv[5], parv[6], parv[7], name, id);
+	return do_remote_user(nick, client_p, source_p, parv[5], parv[6], parv[7], (parc > 10)? parv[9] : NULL, name, id);
 }
 
 static int
diff -uNrd ircd-ratbox-1.1-2/modules/m_svs.c ircd-ratbox-1.1-2-umode-X/modules/m_svs.c
--- ircd-ratbox-1.1-2/modules/m_svs.c	Wed Dec 31 17:00:00 1969
+++ ircd-ratbox-1.1-2-umode-X/modules/m_svs.c	Sun Jul 13 19:32:52 2003
@@ -0,0 +1,91 @@
+/************************************************************************
+ *   IRC - Internet Relay Chat, doc/example_module.c
+ *   Copyright (C) 2001 Hybrid Development Team
+ *
+ *   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 1, or (at your option)
+ *   any later version.
+ *
+ *   This program 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
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *   $Id: example_module.c,v 1.6 2002/05/24 23:48:33 androsyn Exp $
+ */
+
+/* List of ircd includes from ../include/ */
+#include "stdinc.h"
+#include "handlers.h"
+#include "client.h"
+#include "common.h"     /* FALSE bleah */
+#include "ircd.h"
+#include "irc_string.h"
+#include "numeric.h"
+#include "fdlist.h"
+#include "s_bsd.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "send.h"
+#include "msg.h"
+#include "parse.h"
+#include "modules.h"
+
+
+static void ms_svshost(struct Client *client_p, struct Client *source_p,
+			int parc, char *parv[]);
+
+
+struct Message svshost_msgtab = {
+  "SVSHOST", 0, 0, 2, 2, MFLG_SLOW, 0,
+  {m_ignore,m_ignore,ms_svshost,m_ignore}
+};
+
+#ifndef STATIC_MODULES
+/* Here we tell it what to do when the module is loaded */
+void
+_modinit(void)
+{
+  /* This will add the commands in test_msgtab (which is above) */
+  mod_add_cmd(&svshost_msgtab);
+}
+
+/* here we tell it what to do when the module is unloaded */
+void
+_moddeinit(void)
+{
+  /* This will remove the commands in test_msgtab (which is above) */
+  mod_del_cmd(&svshost_msgtab);
+}
+
+/* When we last modified the file (shown in /modlist), this is usually:
+ */
+const char *_version = "$Revision: 1.0 $";
+#endif
+
+static void ms_svshost(struct Client *client_p, struct Client *source_p,
+			int parc, char *parv[])
+{
+	struct Client *target_p;
+	char *nick, *host;
+
+	nick = parv[1];
+	host = parv[2];
+
+	sendto_server(client_p, NULL, CAP_SVS, NOCAPS, ":%s SVSHOST %s %s", parv[0], nick, host);
+
+	if (!(target_p = find_client(nick)))
+		return;
+
+	strlcpy(target_p->host, host, sizeof(target_p->host));
+
+	return;
+}
+
+/* END OF SVS MODULE */
diff -uNrd ircd-ratbox-1.1-2/modules/m_whois.c ircd-ratbox-1.1-2-umode-X/modules/m_whois.c
--- ircd-ratbox-1.1-2/modules/m_whois.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/modules/m_whois.c	Wed Jul 16 20:38:21 2003
@@ -359,6 +359,9 @@
 		   target_p->username, target_p->host, target_p->info);
 	server_name = (char *) target_p->user->server;
 
+        if (IsOper(source_p) || source_p == target_p)
+                sendto_one(source_p, form_str(RPL_WHOISHOST), me.name, source_p->name, target_p->name, target_p->rhost);
+
 	ircsprintf(buf, form_str(RPL_WHOISCHANNELS), me.name, source_p->name, target_p->name, "");
 
 	mlen = strlen(buf);
diff -uNrd ircd-ratbox-1.1-2/modules/m_whowas.c ircd-ratbox-1.1-2-umode-X/modules/m_whowas.c
--- ircd-ratbox-1.1-2/modules/m_whowas.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/modules/m_whowas.c	Tue Jul 15 11:05:39 2003
@@ -152,6 +152,9 @@
 				sendto_one(source_p, form_str(RPL_WHOISSERVER),
 					   me.name, parv[0], temp->name,
 					   temp->servername, myctime(temp->logoff));
+
+                        if (IsOper(source_p))
+                                sendto_one(source_p, form_str(RPL_WHOWASHOST), me.name, parv[0], temp->name, temp->hostname, temp->rhostname);
 			cur++;
 			found++;
 		}
diff -uNrd ircd-ratbox-1.1-2/src/Makefile.in ircd-ratbox-1.1-2-umode-X/src/Makefile.in
--- ircd-ratbox-1.1-2/src/Makefile.in	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/Makefile.in	Sun Jul 13 19:32:52 2003
@@ -72,6 +72,7 @@
   irc_string.c                  \
   ircd.c                        \
   ircd_signal.c                 \
+  ipmask.c			\
   kdparse.c			\
   linebuf.c                     \
   listener.c                    \
@@ -106,6 +107,7 @@
   s_user.c                      \
   scache.c                      \
   send.c                        \
+  svs.c				\
   @SNPRINTF_C@			\
   sprintf_irc.c			\
   tools.c                       \
diff -uNrd ircd-ratbox-1.1-2/src/client.c ircd-ratbox-1.1-2-umode-X/src/client.c
--- ircd-ratbox-1.1-2/src/client.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/client.c	Sun Jul 13 19:34:24 2003
@@ -1565,7 +1565,7 @@
 		if(IsPerson(source_p))
 			sendto_realops_flags(UMODE_CCONN, L_ALL,
 					     "Client exiting: %s (%s@%s) [%s] [%s]",
-					     source_p->name, source_p->username, source_p->host,
+					     source_p->name, source_p->username, source_p->rhost,
 					     comment,
 #ifdef HIDE_SPOOF_IPS
 					     IsIPSpoof(source_p) ? "255.255.255.255" :
diff -uNrd ircd-ratbox-1.1-2/src/hostmask.c ircd-ratbox-1.1-2-umode-X/src/hostmask.c
--- ircd-ratbox-1.1-2/src/hostmask.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/hostmask.c	Sun Jul 13 19:32:52 2003
@@ -454,6 +454,10 @@
 	aconf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
 				     CONF_KILL, client_p->localClient->aftype, client_p->username);
 
+	if (!aconf)
+		aconf = find_conf_by_address(client_p->rhost, &client_p->localClient->ip,
+					CONF_KILL, client_p->localClient->aftype, client_p->username);
+
 	return aconf;
 }
 
@@ -470,6 +474,10 @@
 
 	aconf = find_conf_by_address(client_p->host, &client_p->localClient->ip,
 				     CONF_GLINE, client_p->localClient->aftype, client_p->username);
+
+	if (!aconf)
+		aconf = find_conf_by_address(client_p->rhost, &client_p->localClient->ip,
+					CONF_GLINE, client_p->localClient->aftype, client_p->username);
 
 	return aconf;
 }
diff -uNrd ircd-ratbox-1.1-2/src/ipmask.c ircd-ratbox-1.1-2-umode-X/src/ipmask.c
--- ircd-ratbox-1.1-2/src/ipmask.c	Wed Dec 31 17:00:00 1969
+++ ircd-ratbox-1.1-2-umode-X/src/ipmask.c	Sun Jul 13 19:32:52 2003
@@ -0,0 +1,170 @@
+/*
+ *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ *  m_away.c: Negotiates capabilities with a remote server.
+ *
+ *  Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ *  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.
+ *
+ *  This program 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
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ *
+ *  $Id: ipmask.c,v 1.10 2003/06/22 15:01:30 jeremy Exp $
+ */
+
+#include "stdinc.h"
+#include "tools.h"
+#include "s_user.h"
+#include "channel.h"
+#include "channel_mode.h"
+#include "class.h"
+#include "client.h"
+#include "common.h"
+#include "fdlist.h"
+#include "hash.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "ircd.h"
+#include "listener.h"
+#include "motd.h"
+#include "ircd_handler.h"
+#include "msg.h"
+#include "numeric.h"
+#include "s_bsd.h"
+#include "s_conf.h"
+#include "s_log.h"
+#include "s_serv.h"
+#include "s_stats.h"
+#include "scache.h"
+#include "send.h"
+#include "supported.h"
+#include "whowas.h"
+#include "md5.h"
+#include "memory.h"
+#include "packet.h"
+
+int calculate_ip (struct Client *);
+
+char *maskip(struct Client *client_p)
+{
+	char buf[HOSTLEN];
+	int j = 0,k = 0;
+	char *tmp = NULL;
+	char *tmp2 = NULL;
+	char *tmp3 = NULL;
+	char *tmp4 = NULL;
+	static char mask[HOSTLEN];
+
+	strlcpy(buf, client_p->rhost, HOSTLEN);
+	j = strlen(buf);
+
+        /*ilog(L_NOTICE, "%s", client_p->localClient->sockhost);*/
+        k = calculate_ip(client_p);
+
+	if(strchr(buf, '.'))
+	{
+		if(!isdigit(buf[j - 1]))
+		{
+			tmp = strchr(buf, '.');
+			*tmp = '\0';
+			tmp++;
+			tmp2 = strchr(tmp, '.');
+
+			if(tmp2 != NULL)
+				ircsprintf(mask, "%s-%d.%s", ServerInfo.network_name, k, tmp);
+
+		}
+		else
+		{
+			tmp = strrchr(buf, '.');
+			*tmp = '\0';
+			tmp--;
+
+			ircsprintf(mask, "%s.%d", buf, k);
+		}
+
+		/*if(mask != NULL)
+			strlcpy(client_p->host, mask, HOSTLEN);*/
+	}
+
+
+#ifdef IPV6
+	if(strchr(buf, ':'))
+	{
+		tmp = strrchr(buf, ':');
+		*tmp = '\0';
+		tmp--;
+		tmp2 = strrchr(tmp, ':');
+
+		if(tmp2 != NULL)
+		{
+			tmp3 = strrchr(tmp2, ':');
+
+			if(tmp3 != NULL)
+			{
+				tmp4 = strrchr(tmp3, ':');
+				*tmp4 = '\0';
+				tmp4--;
+			}
+			ircsprintf(mask, "%s::IPV6", buf);
+		}
+
+		/*if(mask != NULL)
+			strlcpy(client_p->host, mask, HOSTLEN);*/
+	}
+#endif
+
+  return mask;
+}
+
+int calculate_ip (struct Client *client_p)
+{
+  char buffer[BUFSIZE];
+  char *tmp = NULL;
+  char *tmp2 = NULL;
+  char *tmp3 = NULL;
+  int a,b,c,d,e;
+
+/*  if (!MyClient(client_p))
+    return;*/
+
+  strcpy(buffer, client_p->localClient->sockhost);
+
+  if ((tmp = strchr(buffer, '.')) != NULL)
+  {
+    *tmp = '\0';
+    tmp++;
+
+    if ((tmp2 = strchr(tmp, '.')) != NULL)
+    {
+      *tmp2 = '\0';
+      tmp2++;
+
+      if ((tmp3 = strchr(tmp2, '.')) != NULL)
+      {
+        *tmp3 = '\0';
+        tmp3++;
+      }
+    }
+  }
+
+  a = atoi(buffer);
+  b = atoi(tmp);
+  c = atoi(tmp2);
+  d = atoi(tmp3);
+
+  e = a + b + c + d;
+  e = e * e * 1024 % 100000;
+
+  return e;
+}
diff -uNrd ircd-ratbox-1.1-2/src/messages.tab ircd-ratbox-1.1-2-umode-X/src/messages.tab
--- ircd-ratbox-1.1-2/src/messages.tab	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/messages.tab	Tue Jul 15 09:22:26 2003
@@ -394,7 +394,7 @@
 /* 367 RPL_BANLIST, */          ":%s 367 %s %s %s %s %lu",
 /* 368 RPL_ENDOFBANLIST, */     ":%s 368 %s %s :End of Channel Ban List",
 /* 369 RPL_ENDOFWHOWAS, */      ":%s 369 %s %s :End of WHOWAS",
-/* 370 */       NULL,
+/* 370 RPL_WHOWASHOST, */       ":%s 370 %s :%s was connected from *@%s [%s]",
 /* 371 RPL_INFO, */             ":%s 371 %s :%s",
 /* 372 RPL_MOTD, */             ":%s 372 %s :- %s",
 /* 373 RPL_INFOSTART, */        ":%s 373 %s :Server INFO",
@@ -402,7 +402,7 @@
 /* 375 RPL_MOTDSTART, */        ":%s 375 %s :- %s Message of the Day - ",
 /* 376 RPL_ENDOFMOTD, */        ":%s 376 %s :End of /MOTD command.",
 /* 377 */       NULL,
-/* 378 */       NULL,
+/* 378 RPL_WHOISHOST, */        ":%s 378 %s %s is connected from *@%s",
 /* 379 */       NULL,
 /* 380 */       NULL,
 /* 381 RPL_YOUREOPER, */        ":%s 381 %s :You have entered... the Vanity Zone!.",
diff -uNrd ircd-ratbox-1.1-2/src/newconf.c ircd-ratbox-1.1-2-umode-X/src/newconf.c
--- ircd-ratbox-1.1-2/src/newconf.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/newconf.c	Sat Jul 19 20:03:16 2003
@@ -316,6 +316,8 @@
 	add_conf_item("serverinfo", "max_clients", CF_INT, conf_set_serverinfo_max_clients);
 	add_conf_item("serverinfo", "max_buffer", CF_INT, conf_set_serverinfo_max_buffer);
 	add_conf_item("serverinfo", "hub", CF_YESNO, conf_set_serverinfo_hub);
+	add_conf_item("serverinfo", "skip_svshost_check", CF_YESNO, conf_set_serverinfo_skip_svshost_check);
+	add_conf_item("serverinfo", "disallow_masking", CF_YESNO, conf_set_serverinfo_disallow_masking);
 
 	add_top_conf("admin", NULL, NULL);
 	add_conf_item("admin", "name", CF_QSTRING, conf_set_admin_name);
@@ -385,6 +387,8 @@
 	add_conf_item("auth", "flood_exempt", CF_YESNO, conf_set_auth_flood_exempt);
 	add_conf_item("auth", "redirserv", CF_QSTRING, conf_set_auth_redir_serv);
 	add_conf_item("auth", "redirport", CF_INT, conf_set_auth_redir_port);
+	add_conf_item("auth", "mask", CF_YESNO, conf_set_auth_mask);
+	add_conf_item("auth", "no_mask_notice", CF_YESNO, conf_set_auth_no_mask_notice);
 	add_conf_item("auth", "flags", CF_STRING | CF_FLIST, conf_set_auth_flags);
 
 	add_top_conf("resv", conf_begin_resv, conf_end_resv);
@@ -693,6 +697,22 @@
 }
 
 void
+conf_set_serverinfo_skip_svshost_check(void *data)
+{
+	int check = *(int *) data;
+
+	ServerInfo.skip_svshost_check = check;
+}
+
+void
+conf_set_serverinfo_disallow_masking(void *data)
+{
+	int check = *(int *) data;
+
+	ServerInfo.disallow_masking = check;
+}
+
+void
 conf_set_modules_module(void *data)
 {
 #ifndef STATIC_MODULES
@@ -886,6 +906,8 @@
 	{"restricted", CONF_FLAGS_RESTRICTED},
 	{"need_ident", CONF_FLAGS_NEED_IDENTD},
 	{"have_ident", CONF_FLAGS_NEED_IDENTD},
+	{"mask", CONF_FLAGS_IPMASK},
+	{"no_mask_notice", CONF_FLAGS_NO_MASK_NOTICE},
 	{NULL}
 };
 
@@ -1650,6 +1672,26 @@
 		yy_achead->flags |= CONF_FLAGS_EXEMPTFLOOD;
 	else
 		yy_achead->flags &= ~CONF_FLAGS_EXEMPTFLOOD;
+}
+
+void
+conf_set_auth_mask(void *data)
+{
+      int yesno = *(unsigned int *) data;
+
+      if(yesno)
+              yy_achead->flags |= CONF_FLAGS_IPMASK;
+}
+
+void
+conf_set_auth_no_mask_notice(void *data)
+{
+      int yesno = *(unsigned int *) data;
+
+      if(yesno)
+              yy_achead->flags |= CONF_FLAGS_NO_MASK_NOTICE;
+      else
+              yy_achead->flags &= ~CONF_FLAGS_NO_MASK_NOTICE;
 }
 
 void
diff -uNrd ircd-ratbox-1.1-2/src/s_conf.c ircd-ratbox-1.1-2-umode-X/src/s_conf.c
--- ircd-ratbox-1.1-2/src/s_conf.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/s_conf.c	Sat Jul 19 18:43:36 2003
@@ -113,6 +113,8 @@
 /* conf uline link list root */
 struct ConfItem *u_conf = ((struct ConfItem *) NULL);
 
+char *maskip (struct Client *client_p);
+
 /*
  * conf_dns_callback
  * inputs	- pointer to struct ConfItem
@@ -528,6 +530,22 @@
 			if(IsConfRestricted(aconf))
 				SetRestricted(client_p);
 
+			/* Save our hostname before its modified */
+			strlcpy (client_p->rhost, client_p->host, sizeof(client_p->rhost));
+
+			if((IsConfDoMaskIp(aconf) && !IsConfDoSpoofIp(aconf)))
+			{
+				strcpy(client_p->host, maskip(client_p));
+				client_p->umodes |= UMODE_IPMASK;
+				ilog(L_NOTICE, "Masking..");
+				if(!IsConfNoMaskNotice(aconf))
+				{
+					sendto_realops_flags(UMODE_ALL, L_ADMIN,
+								":%s masking: %s as %s",
+								client_p->name, client_p->rhost, client_p->host);
+				}
+			}
+
 			/* Thanks for spoof idea amm */
 			if(IsConfDoSpoofIp(aconf))
 			{
@@ -1085,6 +1103,8 @@
 	ServerInfo.max_buffer = MAX_BUFFER;	/*       actually do anything! */
 	/* Don't reset hub, as that will break lazylinks */
 	/* ServerInfo.hub = NO; */
+	ServerInfo.skip_svshost_check = NO;
+	ServerInfo.disallow_masking = NO;
 	ServerInfo.dns_host.sin_addr.s_addr = 0;
 	ServerInfo.dns_host.sin_port = 0;
 	AdminInfo.name = NULL;
diff -uNrd ircd-ratbox-1.1-2/src/s_serv.c ircd-ratbox-1.1-2-umode-X/src/s_serv.c
--- ircd-ratbox-1.1-2/src/s_serv.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/s_serv.c	Tue Jul 15 09:17:29 2003
@@ -99,6 +99,8 @@
 	{ "UNKLN",	CAP_UNKLN },
 	{ "CLUSTER",	CAP_CLUSTER },
 	{ "ENCAP",	CAP_ENCAP },
+	{ "IPMASK",	CAP_IPMASK },
+	{ "SVS",	CAP_SVS },
 	{ 0, 		0 }
 };
 
@@ -799,21 +801,23 @@
 	}
 
 	if(HasID(target_p) && IsCapable(client_p, CAP_UID))
-		sendto_one(client_p, "CLIENT %s %d %lu %s %s %s %s %s :%s",
+		sendto_one(client_p, "CLIENT %s %d %lu %s %s %s %s %s %s :%s",
 			   target_p->name,
 			   target_p->hopcount + 1,
 			   (unsigned long) target_p->tsinfo,
 			   ubuf,
 			   target_p->username, target_p->host,
-			   target_p->user->server, target_p->user->id, target_p->info);
+			   target_p->user->server, target_p->user->id,
+			   IsCapable(client_p, CAP_IPMASK)? target_p->rhost : "", target_p->info);
 	else
-		sendto_one(client_p, "NICK %s %d %lu %s %s %s %s :%s",
+		sendto_one(client_p, "NICK %s %d %lu %s %s %s %s %s :%s",
 			   target_p->name,
 			   target_p->hopcount + 1,
 			   (unsigned long) target_p->tsinfo,
 			   ubuf,
 			   target_p->username, target_p->host,
-			   target_p->user->server, target_p->info);
+			   target_p->user->server,
+			   IsCapable(client_p, CAP_IPMASK)? target_p->rhost : "", target_p->info);
 }
 
 /*
diff -uNrd ircd-ratbox-1.1-2/src/s_user.c ircd-ratbox-1.1-2-umode-X/src/s_user.c
--- ircd-ratbox-1.1-2/src/s_user.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/s_user.c	Sat Jul 19 20:44:37 2003
@@ -63,6 +63,7 @@
 static int introduce_client(struct Client *client_p, struct Client *source_p,
 			    struct User *user, char *nick);
 int oper_up(struct Client *source_p, struct ConfItem *aconf);
+char *maskip (struct Client *client_p);
 
 extern char *crypt();
 
@@ -93,6 +94,7 @@
 	{UMODE_EXTERNAL, 'x'},
 	{UMODE_SPY, 'y'},
 	{UMODE_OPERWALL, 'z'},
+	{UMODE_IPMASK, 'X'},
 	{0, 0}
 };
 
@@ -131,7 +133,7 @@
 	0,			/* U */
 	0,			/* V */
 	0,			/* W */
-	0,			/* X */
+	UMODE_IPMASK,		/* X */
 	0,			/* Y */
 	0,			/* Z 0x5A */
 	0, 0, 0, 0, 0,		/* 0x5F */
@@ -480,7 +482,7 @@
 		 ipaddr, HOSTIPLEN);
 	sendto_realops_flags(UMODE_CCONN, L_ALL,
 			     "Client connecting: %s (%s@%s) [%s] {%s} [%s]",
-			     nick, source_p->username, source_p->host,
+			     nick, source_p->username, source_p->rhost,
 #ifdef HIDE_SPOOF_IPS
 			     IsIPSpoof(source_p) ? "255.255.255.255" :
 #endif
@@ -652,21 +654,21 @@
 			continue;
 
 		if(IsCapable(server, CAP_UID) && HasID(source_p))
-			sendto_one(server, "CLIENT %s %d %lu %s %s %s %s %s :%s",
+			sendto_one(server, "CLIENT %s %d %lu %s %s %s %s %s %s :%s",
 				   nick,
 				   source_p->hopcount + 1,
 				   (unsigned long) source_p->tsinfo,
 				   ubuf,
 				   source_p->username, source_p->host, user->server,
-				   user->id, source_p->info);
+				   user->id, IsCapable(server, CAP_IPMASK)? source_p->rhost : "", source_p->info);
 		else
-			sendto_one(server, "NICK %s %d %lu %s %s %s %s :%s",
+			sendto_one(server, "NICK %s %d %lu %s %s %s %s %s :%s",
 				   nick,
 				   source_p->hopcount + 1,
 				   (unsigned long) source_p->tsinfo,
 				   ubuf,
 				   source_p->username, source_p->host, user->server,
-				   source_p->info);
+				   IsCapable(server, CAP_IPMASK)? source_p->rhost : "", source_p->info);
 	}
 
 	return 0;
@@ -881,7 +883,7 @@
  */
 int
 do_remote_user(char *nick, struct Client *client_p, struct Client *source_p,
-	       char *username, char *host, char *server, char *realname, char *id)
+	       char *username, char *host, char *server, char *rhost, char *realname, char *id)
 {
 	unsigned int oflags;
 	struct User *user;
@@ -904,6 +906,11 @@
 	if(id)
 		strlcpy(source_p->user->id, id, sizeof(source_p->user->id));
 
+	if(rhost)
+		strlcpy(source_p->rhost, rhost, sizeof(source_p->rhost));
+	else
+		strlcpy(source_p->rhost, "unavailable", sizeof(source_p->rhost));
+
 	return register_remote_user(client_p, source_p, source_p->name, username);
 }
 
@@ -926,8 +933,14 @@
 	int badflag = NO;	/* Only send one bad flag notice */
 	char buf[BUFSIZE];
 
+	struct ConfItem* aconf;
+	dlink_node *ptr;
+
 	what = MODE_ADD;
 
+        if (MyClient (source_p)) 
+		aconf = find_address_conf(source_p->host,source_p->username,&source_p->localClient->ip,source_p->localClient->aftype);
+
 	if(parc < 2)
 	{
 		sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS), me.name, parv[0], "MODE");
@@ -1030,6 +1043,58 @@
 				/* we may not get these,
 				 * but they shouldnt be in default
 				 */
+			case 'X':
+/* Thnx to Hwy for pointing out that our CAP check isn't going to work
+ * due to a lack of global CAPAB's
+
+				if(ServerInfo.skip_svshost_check < 1) {
+					sendto_realops_flags (UMODE_DEBUG, L_ALL, "Checking Servers for CAP_SVS");
+					if(svshost_check() < 0)
+					{
+						sendto_one(source_p, ":%s NOTICE %s :Not all servers support SVSHOST, UMODE -X/+X disabled.", me.name, source_p->name);
+						source_p->umodes &= ~UMODE_IPMASK;
+						break;
+					}
+				}
+
+				sendto_realops_flags(UMODE_DEBUG, L_ALL, "All Servers support CAP_SVS");
+*/
+
+				if (MyClient(source_p))
+				{
+					if (ServerInfo.disallow_masking > 0)
+					{
+						sendto_one(source_p, ":%s NOTICE %s :Masking Disabled", me.name, source_p->name);
+						source_p->umodes &= ~UMODE_IPMASK;
+						break;
+					}
+
+					if ((aconf != NULL) && !(IsConfDoSpoofIp(aconf)))
+					{
+						if (what == MODE_ADD)
+						{
+							if (!strcmp(maskip(source_p), source_p->host))
+								break;
+
+							source_p->umodes |= UMODE_IPMASK;
+							strcpy (source_p->host, maskip(source_p));
+							sendto_server (NULL, NULL, CAP_SVS, NOCAPS, ":%s SVSHOST %s %s", me.name, source_p->name, source_p->host);
+							break;
+						}
+						else
+						{
+							if (!IsMasked(source_p))
+								break;
+
+							source_p->umodes &= ~UMODE_IPMASK;
+							strcpy (source_p->host, source_p->rhost);
+							sendto_server(NULL, NULL, CAP_SVS, NOCAPS, ":%s SVSHOST %s %s", me.name, source_p->name, source_p->host);
+							break;
+						}
+					}
+
+				}
+				break;
 			case ' ':
 			case '\n':
 			case '\r':
@@ -1083,6 +1148,8 @@
 		++Count.invisi;
 	if((setflags & UMODE_INVISIBLE) && !IsInvisible(source_p))
 		--Count.invisi;
+
+
 	/*
 	 * compare new flags with old flags and send string which
 	 * will cause servers to update correctly.
diff -uNrd ircd-ratbox-1.1-2/src/svs.c ircd-ratbox-1.1-2-umode-X/src/svs.c
--- ircd-ratbox-1.1-2/src/svs.c	Wed Dec 31 17:00:00 1969
+++ ircd-ratbox-1.1-2-umode-X/src/svs.c	Wed Jul 16 20:54:29 2003
@@ -0,0 +1,64 @@
+/*
+ *  ircd-ratbox: an advanced Internet Relay Chat Daemon(ircd).
+ *  svs.c: Message of the day functions.
+ *
+ *  Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
+ *  Copyright (C) 1996-2002 Hybrid Development Team
+ *  Copyright (C) 2002 ircd-ratbox development team
+ *
+ *  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.
+ *
+ *  This program 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
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
+ *  USA
+ *
+ *  $Id: motd.c,v 7.30 2003/02/06 01:47:39 ejb Exp $
+ */
+
+#include "stdinc.h"
+
+#include "tools.h"
+#include "motd.h"
+#include "ircd.h"
+#include "fdlist.h"
+#include "s_bsd.h"
+#include "fileio.h"
+#include "res.h"
+#include "s_conf.h"
+#include "class.h"
+#include "send.h"
+#include "numeric.h"
+#include "client.h"
+#include "irc_string.h"
+#include "sprintf_irc.h"
+#include "memory.h"
+#include "s_serv.h"
+
+int svshost_check (void)
+{
+	dlink_node *ptr;
+	struct Client *target_p;
+
+        DLINK_FOREACH(ptr, serv_list.head)
+        {
+                target_p = ptr->data;
+		if(IsCapable(target_p, CAP_SVS)) {
+			continue;
+		}
+		else {
+			sendto_realops_flags(UMODE_DEBUG, L_ALL, "Server %s does not support CAP_SVS", target_p->name);
+			return -1;
+		}
+        }
+
+	return 0;
+}
diff -uNrd ircd-ratbox-1.1-2/src/whowas.c ircd-ratbox-1.1-2-umode-X/src/whowas.c
--- ircd-ratbox-1.1-2/src/whowas.c	Mon Jun  9 13:51:34 2003
+++ ircd-ratbox-1.1-2-umode-X/src/whowas.c	Sun Jul 13 19:32:52 2003
@@ -88,6 +88,7 @@
 	strlcpy(who->name, client_p->name, sizeof(who->name));
 	strcpy(who->username, client_p->username);
 	strcpy(who->hostname, client_p->host);
+	strcpy(who->rhostname, client_p->rhost);
 	strcpy(who->realname, client_p->info);
 
 	who->servername = client_p->user->server;
