[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: IP masks support for modes in channels (patch) (fwd)
- To: ircd-users@xxxxxxx
- Subject: Re: IP masks support for modes in channels (patch) (fwd)
- From: Kuba Pamirski <crio@xxxxxxxxxxxxx>
- Date: Sat, 16 Sep 2000 09:04:56 +0200 (CEST)
- Delivered-to: ircd-users-out@irc.org
- Delivered-to: ircd-users@irc.org
---------- Forwarded message ----------
Date: Sat, 16 Sep 2000 09:03:22 +0200 (CEST)
From: Kuba Pamirski <crio@xxxxxxxxxxxxx>
To: ircd-dev@xxxxxxx
Subject: IP masks support for modes in channels (patch)
Hello,
I did what I've been actually thinking about for a longer period of time
- implemented netmasks support for +b/+e/+I channel modes. It is partially
based on ircd/s_conf.c match_ipmask() code. It has been tested with
v6-enabled ircd 2.10.3p1 and should hopefully work both for v4 and v6
compiled daemons. This patch finnally makes channel
bans/invitations/exempts be more precise. It won't break The Protocol
since you could previously /mode #chan +b
*!*@0:0:0:0:0:ffff:150.254.176.0/124 but it wouldn't work. Now it does...
Later I could modify this patch a bit so that the daemon might recognize
duplicate (redundant) modes, for example dissallow banning
*!*@150.254.176.0/28 when *!*@150.254.176.0/26 ban is present.
Kuba /crio/ Pamirski
...and here goes the diff...
--- irc2.10.3/ircd/channel.c Wed Aug 23 15:49:24 2000
+++ irc2.10.3-dbg/ircd/channel.c Sat Sep 16 08:36:39 2000
@@ -263,4 +263,5 @@
/*
* match_modeid - returns a pointer to the mode structure if matching else NULL
+ * modified to support netmasks in +b/+e/+I channel modes -- crio /16.09.2000/
*/
static Link *match_modeid(type, cptr, chptr)
@@ -270,5 +271,12 @@
{
Reg Link *tmp;
- char *s;
+ char *s, *pa, *pm;
+ char dummy[128];
+ u_long lmask;
+ int mval;
+ struct IN_ADDR addr;
+#ifdef INET6
+ int j;
+#endif
if (!IsPerson(cptr))
@@ -299,7 +307,71 @@
for (tmp = chptr->mlist; tmp; tmp = tmp->next)
- if (tmp->flags == type &&
- match(tmp->value.cp, s) == 0)
- break;
+ if (tmp->flags == type)
+ if (index(index(tmp->value.cp, '@'),
+ '/')==NULL)
+ {
+ if (match(tmp->value.cp, s) == 0)
+ break;
+ }
+ else
+ {
+ strncpyzt(dummy, tmp->value.cp,
+ sizeof(dummy));
+ pa = index(dummy, '@') + 1;
+
+ /* Improper use - hostname couldn't
+ start with '/' character */
+
+ if ((pm = index(pa, '/')) == pa + 1)
+ continue;
+
+ *pm = '\0';
+ mval = atoi(pm + 1);
+#ifndef INET6
+ if (mval < 0 || mval > 32)
+ continue;
+
+ lmask = htonl((u_long)
+ 0xffffffffL << (32-m));
+ addr.s_addr = inetaddr(pa);
+ if (((addr.s_addr ^ cptr->ip.s_addr) &
+ lmask))
+ continue;
+#else
+ if (mval < 0 || mval > 128)
+ continue;
+
+ inet_pton(AF_INET6, pa,
+ (void *)addr.s6_addr);
+ j = mval & 0x1f;
+ mval >>= 5;
+
+ if (mval & memcmp((void *)addr.s6_addr,
+ (void *)(cptr->ip.s6_addr),
+ mval << 2))
+ continue;
+
+ if (j)
+ {
+ lmask = htonl((u_long)
+ 0xffffffffL << (32-j));
+ if ((((u_int32_t *)
+ (addr.s6_addr))[mval] ^
+ ((u_int32_t *)
+ (cptr->ip.s6_addr))
+ [mval]) & lmask)
+ continue;
+ }
+#endif
+ /* Substitute original mode's hostname
+ with '*' wildcard since ip number has
+ been positively matched above */
+
+ *pa = '*';
+ pa[1] = '\0';
+
+ if (match(dummy, s) == 0)
+ break;
+ }
}
}