diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/doc/example.conf ircd-ratbox-ipmask/doc/example.conf
--- ircd-ratbox-1.5-2/doc/example.conf	Wed Apr  7 13:37:42 2004
+++ ircd-ratbox-ipmask/doc/example.conf	Wed Jun 23 09:30:13 2004
@@ -239,6 +239,8 @@
 	 * no_tilde      (old - flag)	| don't prefix ~ to username if no ident
 	 * need_ident    (old + flag)	| require ident for user in this class
 	 * restricted			| prevent user from sending mode changes
+     * mask					| mask the users hostname
+	 * mask_notice			| give a notice when masking this host
 	 */
 	flags = kline_exempt, exceed_limit;
 	
@@ -264,7 +266,7 @@
 	user = "*@*";
 	class = "users";
 	
-	flags = restricted, need_ident;
+	flags = restricted, need_ident, mask, mask_notice;
 };
 
 /* operator {}: defines ircd operators. (OLD O:)
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/include/client.h ircd-ratbox-ipmask/include/client.h
--- ircd-ratbox-1.5-2/include/client.h	Thu Jun 17 11:01:38 2004
+++ ircd-ratbox-ipmask/include/client.h	Wed Jun 23 09:30:13 2004
@@ -149,6 +149,7 @@
 	 * considered a read-only field after the client has registered.
 	 */
 	char host[HOSTLEN + 1];	/* client's hostname */
+	char rhost[HOSTLEN + 1];
 	/*
 	 * client->info for unix clients will normally contain the info from the 
 	 * gcos field in /etc/passwd but anything can go here.
@@ -382,6 +383,8 @@
 #define UMODE_ADMIN        0x40000	/* Admin on server */
 #define UMODE_HIDDENOPER   0x80000	/* Oper hidden from stats p */
 
+#define UMODE_IPMASK	   0x100000
+
 #define UMODE_ALL	   UMODE_SERVNOTICE
 
 
@@ -421,7 +424,7 @@
                          OPER_HIDDENOPER)
 
 #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 | \
@@ -503,6 +506,8 @@
 
 #define SetGotId(x)             ((x)->flags |= FLAGS_GOTID)
 #define IsGotId(x)              (((x)->flags & FLAGS_GOTID) != 0)
+
+#define IsMasked(x)				((x)->umodes & UMODE_IPMASK)
 
 /*
  * flags2 macros.
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/include/numeric.h ircd-ratbox-ipmask/include/numeric.h
--- ircd-ratbox-1.5-2/include/numeric.h	Mon Apr  5 12:22:46 2004
+++ ircd-ratbox-ipmask/include/numeric.h	Wed Jun 23 09:30:13 2004
@@ -183,12 +183,15 @@
 #define RPL_ENDOFBANLIST     368
 /* rpl_endofwhowas above (369) */
 
+#define RPL_WHOWASREALHOST   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 /* -Jeremy */
 
 #define RPL_YOUREOPER        381
 #define RPL_REHASHING        382
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/include/s_conf.h ircd-ratbox-ipmask/include/s_conf.h
--- ircd-ratbox-1.5-2/include/s_conf.h	Wed Apr  7 13:37:45 2004
+++ ircd-ratbox-ipmask/include/s_conf.h	Wed Jun 23 09:30:13 2004
@@ -140,6 +140,9 @@
 #define CONF_FLAGS_CRYPTLINK            0x00400000
 #define CONF_FLAGS_VHOSTED		0x00800000
 #define CONF_FLAGS_TB			0x01000000
+
+#define CONF_FLAGS_IPMASK		0x02000000
+#define CONF_FLAGS_MASK_NOTICE	0x04000000
 /* Macros for struct ConfItem */
 
 #define IsLimitIp(x)            ((x)->flags & CONF_FLAGS_LIMIT_IP)
@@ -162,6 +165,8 @@
 #define IsConfCryptLink(x)      ((x)->flags & CONF_FLAGS_CRYPTLINK)
 #define IsConfVhosted(x)	((x)->flags & CONF_FLAGS_VHOSTED)
 #define IsConfTburst(x)		((x)->flags & CONF_FLAGS_TB)
+#define IsConfDoMaskIp(x)		((x)->flags & CONF_FLAGS_IPMASK)
+#define IsConfMaskNotice(x)		((x)->flags & CONF_FLAGS_MASK_NOTICE)
 
 /* flag definitions for opers now in client.h */
 
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/include/s_serv.h ircd-ratbox-ipmask/include/s_serv.h
--- ircd-ratbox-1.5-2/include/s_serv.h	Sun Apr 11 19:08:13 2004
+++ ircd-ratbox-ipmask/include/s_serv.h	Wed Jun 23 09:30:13 2004
@@ -72,12 +72,13 @@
 #define CAP_UNKLN       0x00100000	/* supports remote unkline */
 #define CAP_CLUSTER	0x00200000	/* supports clustering */
 #define CAP_ENCAP	0x00400000
+#define CAP_IPMASK  0x00800000
 
 #define CAP_MASK        (CAP_QS  | CAP_EX   | CAP_CHW  | \
                          CAP_IE  | CAP_KLN  | \
                          CAP_GLN | CAP_CLUSTER | CAP_ENCAP | \
                          CAP_ZIP  | CAP_ENC | \
-                         CAP_KNOCK  | CAP_UNKLN)
+                         CAP_KNOCK  | CAP_UNKLN | CAP_IPMASK)
 
 #ifdef HAVE_LIBZ
 #define CAP_ZIP_SUPPORTED       CAP_ZIP
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/include/s_user.h ircd-ratbox-ipmask/include/s_user.h
--- ircd-ratbox-1.5-2/include/s_user.h	Sun Mar 28 04:45:14 2004
+++ ircd-ratbox-ipmask/include/s_user.h	Wed Jun 23 09:30:13 2004
@@ -44,7 +44,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 *);
 
 extern int user_modes_from_c_to_bitmask[];
 extern void show_isupport(struct Client *);
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/include/supported.h ircd-ratbox-ipmask/include/supported.h
--- ircd-ratbox-1.5-2/include/supported.h	Wed Apr 21 08:07:13 2004
+++ ircd-ratbox-ipmask/include/supported.h	Wed Jun 23 09:30:13 2004
@@ -65,7 +65,8 @@
 		  " ETRACE" \
 		  " WALLCHOPS" \
 		  " SAFELIST" \
-		  " ELIST=U"
+		  " ELIST=U" \
+                  " IPMASK"
 
 #define FEATURES2VALUES ConfigServerHide.disable_local_channels ? "#" : "#&", \
                         ConfigChannel.use_except ? "e" : "", \
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/include/whowas.h ircd-ratbox-ipmask/include/whowas.h
--- ircd-ratbox-1.5-2/include/whowas.h	Mon Mar 15 11:19:45 2004
+++ ircd-ratbox-ipmask/include/whowas.h	Wed Jun 23 09:30:13 2004
@@ -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 -x CVS -x m_svs.c ircd-ratbox-1.5-2/modules/Makefile.in ircd-ratbox-ipmask/modules/Makefile.in
--- ircd-ratbox-1.5-2/modules/Makefile.in	Thu May 20 05:06:35 2004
+++ ircd-ratbox-ipmask/modules/Makefile.in	Sun Jul 18 13:29:35 2004
@@ -87,6 +87,7 @@
   m_set.c \
   m_stats.c \
   m_svinfo.c \
+  m_svshost.c \
   m_tb.c \
   m_testline.c \
   m_testmask.c \
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/modules/core/m_nick.c ircd-ratbox-ipmask/modules/core/m_nick.c
--- ircd-ratbox-1.5-2/modules/core/m_nick.c	Thu May 20 05:06:44 2004
+++ ircd-ratbox-ipmask/modules/core/m_nick.c	Wed Jun 23 09:30:13 2004
@@ -277,7 +277,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;
@@ -302,23 +302,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))
@@ -591,7 +598,8 @@
 			}
 
 			return do_remote_user(nick, client_p, source_p, parv[5], parv[6],
-					      parv[7], parv[8]);
+					      parv[7], (parc > 9)? parv[8] : NULL,
+						parv[(parc > 9)? 9 : 8]);
 		}
 	}
 	else if(source_p->name[0])
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/modules/m_svshost.c ircd-ratbox-ipmask/modules/m_svshost.c
--- ircd-ratbox-1.5-2/modules/m_svshost.c	Wed Dec 31 17:00:00 1969
+++ ircd-ratbox-ipmask/modules/m_svshost.c	Sun Jul 18 13:29:24 2004
@@ -0,0 +1,124 @@
+/************************************************************************
+ *   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: m_svshost.c,v 1.6 2003/11/05 18:29:47 jeremy 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"
+#include "hash.h"
+
+static void ms_svshost	(struct Client *client_p, struct Client *source_p, int parc, char *parv[]);
+static void me_svshost	(struct Client *client_p, struct Client *source_p, int parc, char *parv[]);
+
+struct Message svshost_msgtab = {
+	"SVSHOST", 0, 0, 4, 0, MFLG_SLOW, 0,
+	{m_ignore, m_ignore, ms_svshost, ms_svshost, m_ignore}
+};
+
+#ifndef STATIC_MODULES
+void _modinit (void)
+{
+	mod_add_cmd (&svshost_msgtab);
+}
+
+void _moddeinit (void)
+{
+	mod_del_cmd (&svshost_msgtab);
+}
+
+const char *_version = "$Revision 1.7 $ 10/06/04";
+#endif
+
+/*
+ * mo_svshost
+ *	parv[0] = sender prefix
+ *      parv[1] = target server
+ *	parv[2] = target nickname
+ *	parv[3] = new hostname
+ */
+
+static void ms_svshost	(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
+{
+	struct Client *target_p;
+	int setflags;
+	const char *nick;
+	const char *hostname;
+	char buffer[BUFSIZE];
+
+	nick = parv[2];
+	hostname = parv[3];
+
+	propagate_generic (client_p, "SVSHOST", parv[1], CAP_IPMASK, "%s :%s", nick, hostname);
+
+	/* Assume nick will be a valid client */
+	target_p = find_client (nick);
+
+	/* Assume all is good */
+	strlcpy (target_p->host, hostname, HOSTLEN);
+
+	sendto_match_servs (&me, "*", CAP_ENCAP, NOCAPS, "ENCAP * SNOTICE :Changed %s's hostname to %s",
+				target_p->name, hostname);
+	sendto_realops_flags (UMODE_SERVNOTICE, L_ALL, "Changed %s's hostname to %s", target_p->name, hostname);
+}
+
+/*
+ * me_svshost
+ *      parv[0] = sender prefix
+ *	parv[1] = target server
+ *      parv[2] = target nickname
+ *      parv[3] = new hostname
+ */
+
+static void me_svshost	(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
+{
+	struct Client *target_p;
+	int setflags;
+	const char *nick;
+	const char *hostname;
+
+	nick = parv[2];
+	hostname = parv[3];
+
+	propagate_generic (client_p, "SVSHOST", parv[1], CAP_IPMASK, "%s :%s", nick, hostname);
+
+        /* Assume nick will be a valid client */
+        target_p = find_client (nick);
+
+        /* Assume all is good */
+        strlcpy (target_p->host, hostname, HOSTLEN);
+
+        sendto_match_servs (&me, "*", CAP_ENCAP, NOCAPS, "ENCAP * SNOTICE :Changed %s's hostname to %s",
+                                target_p->name, hostname);
+	sendto_realops_flags (UMODE_SERVNOTICE, L_ALL, "Changed %s's hostname to %s", target_p->name, hostname);
+}
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/modules/m_whois.c ircd-ratbox-ipmask/modules/m_whois.c
--- ircd-ratbox-1.5-2/modules/m_whois.c	Thu May 20 05:06:37 2004
+++ ircd-ratbox-ipmask/modules/m_whois.c	Wed Jun 23 09:30:13 2004
@@ -303,6 +303,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);
+
 	cur_len = mlen = ircsprintf(buf, form_str(RPL_WHOISCHANNELS), me.name, source_p->name, target_p->name);
 	t = buf + mlen;
 
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/modules/m_whowas.c ircd-ratbox-ipmask/modules/m_whowas.c
--- ircd-ratbox-1.5-2/modules/m_whowas.c	Thu May 20 05:06:37 2004
+++ ircd-ratbox-ipmask/modules/m_whowas.c	Wed Jun 23 09:30:13 2004
@@ -144,7 +144,8 @@
 		{
 			sendto_one(source_p, form_str(RPL_WHOWASUSER),
 				   me.name, parv[0], temp->name,
-				   temp->username, temp->hostname, temp->realname);
+				   temp->username,
+                                   (IsOperAdmin(source_p))? temp->hostname : temp->rhostname, temp->realname);
 
 			if(ConfigServerHide.hide_servers && !IsOper(source_p))
 				sendto_one(source_p, form_str(RPL_WHOISSERVER),
@@ -154,6 +155,7 @@
 				sendto_one(source_p, form_str(RPL_WHOISSERVER),
 					   me.name, parv[0], temp->name,
 					   temp->servername, myctime(temp->logoff));
+
 			cur++;
 			found++;
 		}
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/Makefile.in ircd-ratbox-ipmask/src/Makefile.in
--- ircd-ratbox-1.5-2/src/Makefile.in	Wed Mar 24 17:30:54 2004
+++ ircd-ratbox-ipmask/src/Makefile.in	Wed Jun 23 09:30:13 2004
@@ -69,6 +69,7 @@
   hash.c                        \
   hook.c                        \
   hostmask.c                    \
+  ipmask.c						\
   irc_string.c                  \
   ircd.c                        \
   ircd_signal.c                 \
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/client.c ircd-ratbox-ipmask/src/client.c
--- ircd-ratbox-1.5-2/src/client.c	Wed Mar 24 17:30:54 2004
+++ ircd-ratbox-ipmask/src/client.c	Wed Jun 23 09:30:13 2004
@@ -1541,7 +1541,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 -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/hostmask.c ircd-ratbox-ipmask/src/hostmask.c
--- ircd-ratbox-1.5-2/src/hostmask.c	Tue Mar 23 10:35:54 2004
+++ ircd-ratbox-ipmask/src/hostmask.c	Wed Jun 23 09:30:13 2004
@@ -454,6 +454,9 @@
 	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 +473,9 @@
 
 	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 -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/ipmask.c ircd-ratbox-ipmask/src/ipmask.c
--- ircd-ratbox-1.5-2/src/ipmask.c	Wed Dec 31 17:00:00 1969
+++ ircd-ratbox-ipmask/src/ipmask.c	Wed Jun 23 09:30:13 2004
@@ -0,0 +1,248 @@
+/*
+ *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ *  FreeWorld-ircd:
+ *  ipmask.c: IP Masking routines.
+ *
+ *  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.2 2003/10/20 06:30:42 ircd 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 "memory.h"
+#include "packet.h"
+
+void maskip (struct Client *);
+int calculate_ip (struct Client *);
+
+void maskip (struct Client *client_p)
+{
+	char buf[HOSTLEN];
+	int i = 0,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);
+    mask[0] = '\0';
+
+	if(strchr(buf, '.'))
+	{
+		k = calculate_ip (client_p);
+		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[0] != '\0') {
+			sendto_realops_flags(UMODE_DEBUG, L_ALL, "Applying mask (%s) to %s", mask, client_p->name);
+			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[0] != '\0') {
+			sendto_realops_flags(UMODE_DEBUG, L_ALL, "Applying mask (%s) to %s", mask, client_p->name);
+			strlcpy(client_p->host, mask, HOSTLEN);
+		}
+	}
+#endif
+
+}
+
+int calculate_ip (struct Client *client_p)
+{
+  char buffer[BUFSIZE];
+  char *tmp, *tmp2, *tmp3;
+  int a,b,c,d,e;
+
+/*  if (!MyClient(client_p))
+    return;*/
+
+  strcpy(buffer, client_p->localClient->sockhost);
+
+  if (strchr(buffer, ':'))
+    return 0;
+
+  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;
+}
+
+char *ret_maskip(struct Client *client_p)
+{
+        char buf[HOSTLEN];
+        int i = 0,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);
+        mask[0] = '\0';
+  
+        if(strchr(buf, '.'))
+        {
+                k = calculate_ip (client_p);
+                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
+			    ircsprintf (mask, "%s-%d.%s", ServerInfo.network_name, k, buf);
+			    //strcpy (mask, client_p->host);
+ 
+                }
+                else
+                {
+                        tmp = strrchr(buf, '.');
+                        *tmp = '\0';
+                        tmp--;
+  
+                        ircsprintf(mask, "%s.%d", buf, k);
+                }  
+
+        }
+
+
+#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);
+                }  
+
+        }
+#endif
+
+	if (mask[0] != '\0')
+		return mask;
+	else
+		return client_p->host;
+}
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/messages.tab ircd-ratbox-ipmask/src/messages.tab
--- ircd-ratbox-1.5-2/src/messages.tab	Mon Apr  5 12:22:56 2004
+++ ircd-ratbox-ipmask/src/messages.tab	Wed Jun 23 09:30:13 2004
@@ -24,7 +24,7 @@
 /* 001  RPL_WELCOME, */ ":%s 001 %s :Welcome to the %s Internet Relay Chat Network %s",
 /* 002  RPL_YOURHOST,*/ ":%s 002 %s :Your host is %s, running version %s",
 /* 003  RPL_CREATED, */ ":%s 003 %s :This server was created %s",
-/* 004  RPL_MYINFO, */ ":%s 004 %s %s %s oiwszcerkfydnxbauglZ biklmnopstveI bkloveI",
+/* 004  RPL_MYINFO, */ ":%s 004 %s %s %s oiwszcerkfydnxbauglZX biklmnopstveI bkloveI",
 /* 005  RPL_ISUPPORT, */ ":%s 005 %s %s :are supported by this server",
 /* 006 */       NULL,
 /* 007 */       NULL,
@@ -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_WHOWASREALHOST, */   ":%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 -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/newconf.c ircd-ratbox-ipmask/src/newconf.c
--- ircd-ratbox-1.5-2/src/newconf.c	Wed Apr  7 13:37:50 2004
+++ ircd-ratbox-ipmask/src/newconf.c	Wed Jun 23 09:30:13 2004
@@ -112,6 +112,8 @@
 	{"restricted", CONF_FLAGS_RESTRICTED},
 	{"need_ident", CONF_FLAGS_NEED_IDENTD},
 	{"have_ident", CONF_FLAGS_NEED_IDENTD},
+	{"mask", CONF_FLAGS_IPMASK},
+	{"mask_notice", CONF_FLAGS_MASK_NOTICE},
 	{NULL}
 };
 
@@ -1412,6 +1414,28 @@
 	DupString(yy_achead->className, data);
 }
 
+static void
+conf_set_auth_mask(void *data)
+{
+	int yesno = *(unsigned int *) data;
+
+	if (yesno)
+		yy_achead->flags |= CONF_FLAGS_IPMASK;
+	else
+		yy_achead->flags &= ~CONF_FLAGS_IPMASK;
+}
+
+static void
+conf_set_auth_mask_notice (void *data)
+{
+	int yesno = *(unsigned int *) data;
+
+	if (yesno)
+		yy_achead->flags |= CONF_FLAGS_MASK_NOTICE;
+	else
+		yy_achead->flags &= ~CONF_FLAGS_MASK_NOTICE;
+}
+
 static int
 conf_begin_resv(struct TopConf *tc)
 {
@@ -3066,6 +3090,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", "mask_notice", CF_YESNO, conf_set_auth_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);
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/s_conf.c ircd-ratbox-ipmask/src/s_conf.c
--- ircd-ratbox-1.5-2/src/s_conf.c	Thu Apr 29 07:47:38 2004
+++ ircd-ratbox-ipmask/src/s_conf.c	Wed Jun 23 09:30:13 2004
@@ -56,6 +56,7 @@
 #include "patricia.h"
 #include "reject.h"
 
+char *ret_maskip(struct Client *);
 
 struct config_server_hide ConfigServerHide;
 
@@ -534,6 +535,16 @@
 			SetNeedId(client_p);
 		if(IsConfRestricted(aconf))
 			SetRestricted(client_p);
+
+
+		strlcpy (client_p->rhost, client_p->host, sizeof(client_p->rhost));
+		if(IsConfDoMaskIp(aconf))
+		{
+			strcpy (client_p->host, ret_maskip(client_p));
+			client_p->umodes |= UMODE_IPMASK;
+			if(IsConfMaskNotice(aconf))
+				sendto_realops_flags (UMODE_ALL, L_ALL, "%s masking: %s as %s", client_p->name, client_p->rhost, client_p->host);
+		}
 
 		/* Thanks for spoof idea amm */
 		if(IsConfDoSpoofIp(aconf))
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/s_serv.c ircd-ratbox-ipmask/src/s_serv.c
--- ircd-ratbox-1.5-2/src/s_serv.c	Thu Jun 17 11:01:45 2004
+++ ircd-ratbox-ipmask/src/s_serv.c	Wed Jun 23 09:30:13 2004
@@ -95,6 +95,7 @@
 	{ "UNKLN",	CAP_UNKLN },
 	{ "CLUSTER",	CAP_CLUSTER },
 	{ "ENCAP",	CAP_ENCAP },
+	{ "IPMASK", CAP_IPMASK },
 	{ 0, 		0 }
 };
 
@@ -796,13 +797,15 @@
 		ubuf[1] = '\0';
 	}
 
-		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 -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/s_user.c ircd-ratbox-ipmask/src/s_user.c
--- ircd-ratbox-1.5-2/src/s_user.c	Wed Jun  2 19:32:16 2004
+++ ircd-ratbox-ipmask/src/s_user.c	Wed Jun 23 09:30:13 2004
@@ -54,11 +54,13 @@
 #include "memory.h"
 #include "packet.h"
 #include "reject.h"
+#include "hostmask.h"
 
 static void report_and_set_user_flags(struct Client *, struct ConfItem *);
 static int check_X_line(struct Client *client_p, struct Client *source_p);
 void user_welcome(struct Client *source_p);
 int oper_up(struct Client *source_p, struct ConfItem *aconf);
+char *ret_maskip(struct Client *);
 
 extern char *crypt();
 
@@ -88,6 +90,7 @@
 	{UMODE_UNAUTH, 'u'},
 	{UMODE_WALLOP, 'w'},
 	{UMODE_EXTERNAL, 'x'},
+    {UMODE_IPMASK, 'X'},
 	{UMODE_SPY, 'y'},
 	{UMODE_OPERWALL, 'z'},
 	{UMODE_OPERSPY, 'Z'},
@@ -465,7 +468,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
@@ -611,13 +614,21 @@
 		ubuf[1] = '\0';
 	}
 
-	sendto_server(client_p, NULL, NOCAPS, NOCAPS,
+	sendto_server(client_p, NULL, NOCAPS, CAP_IPMASK,
 		      "NICK %s %d %lu %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);
 
+    sendto_server(client_p, NULL, CAP_IPMASK, NOCAPS,
+              "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->rhost,
+              source_p->info);
+
 	return 0;
 }
 
@@ -844,7 +855,7 @@
  */
 int
 do_remote_user(char *nick, struct Client *client_p, struct Client *source_p,
-	       char *username, char *host, char *server, char *realname)
+	       char *username, char *host, char *server, char *rhost, char *realname)
 {
 	unsigned int oflags;
 	struct User *user;
@@ -865,6 +876,11 @@
 	strlcpy(source_p->host, host, sizeof(source_p->host));
 	strlcpy(source_p->info, realname, sizeof(source_p->info));
 
+	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);
 }
 
@@ -885,7 +901,8 @@
 	struct Client *target_p;
 	int what, setflags;
 	int badflag = NO;	/* Only send one bad flag notice */
-	char buf[BUFSIZE];
+	char buf[BUFSIZE], oldhost[HOSTLEN];
+	struct ConfItem* aconf;
 
 	what = MODE_ADD;
 
@@ -987,6 +1004,47 @@
 					}
 				}
 				break;
+
+				case 'X':
+				if (MyClient(source_p))
+				{
+					aconf = find_address_conf (source_p->rhost, source_p->username, &source_p->localClient->ip, source_p->localClient->aftype);
+
+					strcpy (oldhost, source_p->host);
+
+					if(what == MODE_ADD)
+					{
+						if(IsConfDoSpoofIp(aconf))
+						{
+							source_p->umodes &= ~UMODE_IPMASK;
+							break;
+						}
+
+						if(IsMasked(source_p))
+						{
+							if(!strcmp(ret_maskip(source_p), source_p->host))
+								break;
+
+							source_p->umodes |= UMODE_IPMASK;
+							strcpy(source_p->host, ret_maskip(source_p));
+						}
+
+						source_p->umodes |= UMODE_IPMASK;
+						strcpy(source_p->host, ret_maskip(source_p));
+					}
+
+					if(what == MODE_DEL)
+					{
+						if(!IsMasked(source_p))
+							break;
+
+						source_p->umodes &= ~UMODE_IPMASK;
+						strcpy(source_p->host, source_p->rhost);
+					}
+
+					propagate_generic (&me, "SVSHOST", "*", CAP_IPMASK, "%s :%s", source_p->name, source_p->host);
+			}
+			break;
 
 			case 'p':
 				if (MyConnect(source_p))
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/version.c.SH ircd-ratbox-ipmask/src/version.c.SH
--- ircd-ratbox-1.5-2/src/version.c.SH	Sun Jul  6 08:01:03 2003
+++ ircd-ratbox-ipmask/src/version.c.SH	Sun Jul 18 13:32:03 2004
@@ -52,10 +52,12 @@
 #include "patchlevel.h"
 #include "serno.h"
 
+#define PATCHVER PATCHLEVEL "+ipmask-1.4.3"
+
 const char *generation = "$generation";
 const char *creation = "$creation";
 const char *platform = "$uname";
-const char *ircd_version = PATCHLEVEL;
+const char *ircd_version = PATCHVER;
 const char *serno = SERIALNUM;
 
 const char *infotext[] =
diff -uNrd -x CVS -x m_svs.c ircd-ratbox-1.5-2/src/whowas.c ircd-ratbox-ipmask/src/whowas.c
--- ircd-ratbox-1.5-2/src/whowas.c	Mon Mar 15 11:19:57 2004
+++ ircd-ratbox-ipmask/src/whowas.c	Wed Jun 23 09:30:13 2004
@@ -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;
