diff -ru irc2.11.1p1/common/send.c irc2.11.1p1+v6/common/send.c
--- irc2.11.1p1/common/send.c	2005-02-22 17:34:02.000000000 +0100
+++ irc2.11.1p1+v6/common/send.c	2005-06-01 07:18:29.000000000 +0200
@@ -1298,6 +1298,8 @@
 			case EXITC_GUHMAX:	anyptr="G u@h max"; break;
 			case EXITC_LHMAX:	anyptr="L IP  max"; break;
 			case EXITC_LUHMAX:	anyptr="L u@h max"; break;
+/*			case EXITC_RHMAX:	anyptr="R IP  max"; break;
+			case EXITC_RUHMAX:	anyptr="R u@h max"; break; */
 			case EXITC_AREF:
 			case EXITC_AREFQ:	anyptr=" Denied  "; break;
 			case EXITC_KLINE:	anyptr=" K lined "; break;
diff -ru irc2.11.1p1/common/struct_def.h irc2.11.1p1+v6/common/struct_def.h
--- irc2.11.1p1/common/struct_def.h	2005-03-30 01:23:49.000000000 +0200
+++ irc2.11.1p1+v6/common/struct_def.h	2005-06-01 03:31:08.000000000 +0200
@@ -304,6 +304,7 @@
 	struct	CPing	*ping;
 	time_t	hold;	/* Hold action until this time (calendar time) */
 	char	*source_ip;
+	int	chkmask;
 #ifndef VMSP
 	aClass	*class;  /* Class of connection */
 #endif
diff -ru irc2.11.1p1/common/support.c irc2.11.1p1+v6/common/support.c
--- irc2.11.1p1/common/support.c	2005-02-04 19:08:48.000000000 +0100
+++ irc2.11.1p1+v6/common/support.c	2005-06-01 10:34:50.000000000 +0200
@@ -742,7 +742,7 @@
 char	*make_version(void)
 {
 	int ve, re, mi, dv, pl;
-	char ver[15];
+	char ver[15+2]; /* +r */
 
 	sscanf(PATCHLEVEL, "%2d%2d%2d%2d%2d", &ve, &re, &mi, &dv, &pl);
 	/* version & revision */
@@ -754,6 +754,7 @@
 		sprintf(ver + strlen(ver), "%c%d", DEVLEVEL, dv);
 	if (pl)	/* patchlevel */
 		sprintf(ver + strlen(ver), "p%d", pl);
+	strcat(ver, "+r");
 	return mystrdup(ver);
 }
 
diff -ru irc2.11.1p1/ircd/list.c irc2.11.1p1+v6/ircd/list.c
--- irc2.11.1p1/ircd/list.c	2005-01-30 14:42:03.000000000 +0100
+++ irc2.11.1p1+v6/ircd/list.c	2005-06-01 06:46:15.000000000 +0200
@@ -584,6 +584,11 @@
 	aconf->hold = time(NULL);
 	aconf->source_ip = NULL;
 	aconf->flags = 0L;
+#ifdef INET6
+	aconf->chkmask = 128;
+#else
+	aconf->chkmask = 32;
+#endif
 	Class(aconf) = NULL;
 	return (aconf);
 }
diff -ru irc2.11.1p1/ircd/s_conf.c irc2.11.1p1+v6/ircd/s_conf.c
--- irc2.11.1p1/ircd/s_conf.c	2005-04-14 01:14:38.000000000 +0200
+++ irc2.11.1p1+v6/ircd/s_conf.c	2005-06-01 08:46:27.000000000 +0200
@@ -354,6 +354,34 @@
 	    }
 }
 
+static int match_ip(struct IN_ADDR *addr1, struct IN_ADDR *addr2, int m)
+{
+	u_long lmask;
+#ifdef INET6
+	int j;
+
+	j = m & 0x1F;	/* number not mutliple of 32 bits */
+	m >>= 5;	/* number of 32 bits */
+
+	if (m && memcmp((void *)(addr1->s6_addr), 
+		(void *)(addr2->s6_addr), m << 2))
+		return 1;
+
+	if (j)
+	{
+		lmask = htonl((u_long)0xffffffffL << (32 - j));
+		if ((((u_int32_t *)(addr1->s6_addr))[m] ^
+			((u_int32_t *)(addr2->s6_addr))[m]) & lmask)
+			return 1;
+	}
+
+	return 0;
+#else
+	lmask = htonl((u_long)0xffffffffL << (32 - m));
+	return ((addr1->s_addr ^ addr2->s_addr) & lmask) ? 1 : 0;
+#endif
+}
+
 /*
  * Match address by #IP bitmask (10.11.12.128/27)
  * Now should work for IPv6 too.
@@ -394,9 +422,7 @@
 #ifndef	INET6
 	if (m < 0 || m > 32)
 		goto badmask;
-	lmask = htonl((u_long)0xffffffffL << (32 - m));
 	addr.s_addr = inetaddr(mask);
-	return ((addr.s_addr ^ cptr->ip.s_addr) & lmask) ? 1 : 0;
 #else
 	if (m < 0 || m > 128)
 		goto badmask;
@@ -414,24 +440,10 @@
 		if (m <= 96)
 			goto badmask;
 	}
+#endif
 
-	j = m & 0x1F;	/* number not mutliple of 32 bits */
-	m >>= 5;	/* number of 32 bits */
-
-	if (m && memcmp((void *)(addr.s6_addr), 
-		(void *)(cptr->ip.s6_addr), m << 2))
-		return 1;
-
-	if (j)
-	{
-		lmask = htonl((u_long)0xffffffffL << (32 - j));
-		if ((((u_int32_t *)(addr.s6_addr))[m] ^
-			((u_int32_t *)(cptr->ip.s6_addr))[m]) & lmask)
-			return 1;
-	}
+	return match_ip(&addr, &cptr->ip, m);
 
-	return 0;
-#endif
 badmask:
 	if (maskwithusername)
 	sendto_flag(SCH_ERROR, "Ignoring bad mask: %s", omask);
@@ -720,12 +732,13 @@
 	{
 		int hcnt = 0, ucnt = 0;
 		int ghcnt = 0, gucnt = 0;
+		int i, m;
 		anUser *user = NULL;
 		/* check on local/global limits per host and per user@host */
 
 		/*
 		** local limits first to save CPU if any is hit.
-		**	host check is done on the IP address.
+		**	host check is done on the HOST, and NOT the IP address.
 		**	user check is done on the IDENT reply.
 		*/
 		if (ConfMaxHLocal(aconf) > 0 || ConfMaxUHLocal(aconf) > 0 ||
@@ -734,7 +747,8 @@
 			for ((user = hash_find_hostname(cptr->sockhost, NULL));
 			     user; user = user->hhnext)
 			{
-				if (!mycmp(cptr->sockhost, user->host))
+				if (!mycmp(cptr->user->sip, user->sip) &&
+				    !mycmp(cptr->sockhost, user->host))
 				{
 					ghcnt++;
 					if (MyConnect(user->bcptr))
@@ -779,6 +793,54 @@
 					}
 				}
 			}
+
+
+			m = aconf->chkmask;
+#ifdef INET6
+			if (IN6_IS_ADDR_V4MAPPED(&cptr->ip))
+			{
+				if (m <= 32)
+					m += 96;
+				if (m <= 96)
+					m = 128;
+			}
+
+			if(m < 128)
+#else
+			if(m < 32)
+#endif
+			{
+				for(i = 0; i < highest_fd; i++)
+				{
+					aClient *acptr;
+					if(!(acptr = local[i]) || !IsPerson(acptr))
+						continue;
+					if(!match_ip(&acptr->ip, &cptr->ip, m))
+					{
+						hcnt++;
+						ghcnt++;
+						if (!mycmp(acptr->user->username,
+							   cptr->user->username
+							   ))
+						{
+							ucnt++;
+							gucnt++;
+						}
+
+						if (ConfMaxUHLocal(aconf) > 0 &&
+						    ucnt >= ConfMaxUHLocal(aconf))
+						{
+							return -10; /* EXITC_RUHMAX */
+						}
+	
+						if (ConfMaxHLocal(aconf) > 0 &&
+						    hcnt >= ConfMaxHLocal(aconf))
+						{
+							return -9; /* EXITC_RHMAX */
+						}
+					}
+				}
+			}
 		}
 	}
 
@@ -1669,6 +1731,20 @@
 					pline_flags_parse(tmp3));
 			}
 
+			if(tmp4 && aconf->status == CONF_CLIENT)
+			{
+				aconf->chkmask = atoi(tmp4);
+#ifndef	INET6
+				if (aconf->chkmask < 0 || aconf->chkmask > 32 ||
+				    (aconf->chkmask == 0 && !isdigit(*tmp4)))
+					aconf->chkmask = 32;
+#else
+				if (aconf->chkmask < 1 || aconf->chkmask > 128 ||
+				    (aconf->chkmask == 0 && !isdigit(*tmp4)))
+					aconf->chkmask = 128;
+#endif
+			}
+
 			/* trying to find exact conf line in already existing
 			 * conf, so we don't delete old one, just update it */
 			if (
@@ -1686,6 +1762,7 @@
 				 * (from lowercase i:lines). In any case we
 				 * don't want old flags to remain. --B. */
 				bconf->flags = aconf->flags;
+				bconf->chkmask = aconf->chkmask;
 				/* in case class was changed */
 				if (aconf->status == CONF_CLIENT &&
 					aconf->class != bconf->class)
diff -ru irc2.11.1p1/ircd/s_user.c irc2.11.1p1+v6/ircd/s_user.c
--- irc2.11.1p1/ircd/s_user.c	2005-04-14 01:10:37.000000000 +0200
+++ irc2.11.1p1+v6/ircd/s_user.c	2005-06-01 07:19:27.000000000 +0200
@@ -484,8 +484,10 @@
 		if ((i = check_client(sptr)))
 		{
 			struct msg_set { char shortm; char *longm; };
-#define EXIT_MSG_COUNT 8
+#define EXIT_MSG_COUNT 10
 			static struct msg_set exit_msg[EXIT_MSG_COUNT] = {
+			{ EXITC_LUHMAX, "Too many user connections (range)" },
+			{ EXITC_LHMAX, "Too many host connections (range)" },
 			{ EXITC_BADPASS, "Bad password" },
 			{ EXITC_GUHMAX, "Too many user connections (global)" },
 			{ EXITC_GHMAX, "Too many host connections (global)" },
