Add support for CIDR-based MOTD masks.
authorMichael Poole <mdpoole@troilus.org>
Sun, 17 Oct 2004 01:58:17 +0000 (01:58 +0000)
committerMichael Poole <mdpoole@troilus.org>
Sun, 17 Oct 2004 01:58:17 +0000 (01:58 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1248 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

ChangeLog
include/motd.h
ircd/class.c
ircd/match.c
ircd/motd.c

index e754d48f130c7dc30a15abb99311c9331ff9de66..1d3480b381d4200664b8fe5b87291ed2a90ab3d7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2004-10-16  Michael Poole <mdpoole@troilus.org>
+
+       * ircd/class.c: Make find_class() return NULL for unknown classes,
+       rather than returning the start of connClassList.
+
+       * ircd/match.c (parse_ipmask): Translate IPv4 masks as
+       IPv4-compatible addresses.
+       (check_ipmask): Fix comparison of IP masks.
+
+       * ircd/motd.h, ircd/motd.c: Add a new MOTD type, MOTD_IPMASK, that
+       uses CIDR style masks in the hostname field of a Motd block.
+
 2004-10-16  Michael Poole <mdpoole@troilus.org>
 
        * ircd/numeric.h: Remove the unused RPL_STATMEM and
index 3383b91fa7621e72790bb6b3e357b42eedef9558..6de178eb01b3005d3021ac143f94041e67e4fc30 100644 (file)
 #include <sys/types.h>
 #define INCLUDED_sys_types_h
 #endif
-
+#ifndef INCLUDED_res_H
+#include "res.h"
+#endif
 
 struct Client;
 struct TRecord;
 struct StatDesc;
 
+/** Type of MOTD. */
+enum MotdType {
+    MOTD_UNIVERSAL, /**< MOTD for all users */
+    MOTD_HOSTMASK,  /**< MOTD selected by hostmask */
+    MOTD_IPMASK,    /**< MOTD selected by IP mask */
+    MOTD_CLASS      /**< MOTD selected by connection class */
+};
+
 /** Entry for a single Message Of The Day (MOTD). */
 struct Motd {
   struct Motd*         next;     /**< Next MOTD in the linked list. */
-  int                  type;     /**< Type of MOTD (MOTD_UNIVERSAL,
-                                     MOTD_HOSTMASK or MOTD_CLASS) */
-  /* Used for classname if it is a class. */
+  enum MotdType                type;     /**< Type of MOTD. */
   char*                        hostmask; /**< Hostmask if type==MOTD_HOSTMASK,
-                                     class name if type==MOTD_CLASS. */
+                                     class name if type==MOTD_CLASS,
+                                     text IP mask if type==MOTD_IPMASK. */
+  struct irc_in_addr    address;  /**< Address if type==MOTD_IPMASK. */
+  unsigned char         addrbits; /**< Number of bits checked in Motd::address. */
   char*                        path;     /**< Pathname of MOTD file. */
   int                  maxcount; /**< Number of lines for MOTD. */
   struct MotdCache*    cache;    /**< MOTD cache entry. */
 };
 
-#define MOTD_UNIVERSAL 0         /**< MOTD selected by no criteria */
-#define MOTD_HOSTMASK  1         /**< MOTD selected by hostmask */
-#define MOTD_CLASS     2         /**< MOTD selected by connection class */
-
 /** Length of one MOTD line(80 chars + '\\0'). */
 #define MOTD_LINESIZE  81
 /** Maximum number of lines for local MOTD */
index 9c00e848bc145f9c615eac23744c1c0308f1c0d1..53fd65edd1cb00a713add3bc7a43a2894b3134e5 100644 (file)
@@ -38,7 +38,7 @@
 #include <assert.h>
 
 /** List of all connection classes. */
-static struct ConnectionClass* connClassList = 0;
+static struct ConnectionClass* connClassList;
 /** Number of allocated connection classes. */
 static unsigned int connClassAllocCount;
 
@@ -49,15 +49,21 @@ const struct ConnectionClass* get_class_list(void)
 }
 
 /** Allocate a new connection class.
+ * If #connClassList is not null, insert the new class just after it.
  * @return Newly allocated connection class structure.
  */
 struct ConnectionClass* make_class(void)
 {
   struct ConnectionClass *tmp;
 
-  tmp = (struct ConnectionClass*) MyMalloc(sizeof(struct ConnectionClass));
-  tmp->ref_count = 1;
+  tmp = (struct ConnectionClass*) MyCalloc(1, sizeof(struct ConnectionClass));
   assert(0 != tmp);
+  tmp->ref_count = 1;
+  if (connClassList)
+  {
+    tmp->next = connClassList->next;
+    connClassList->next = tmp;
+  }
   ++connClassAllocCount;
   return tmp;
 }
@@ -215,24 +221,16 @@ unsigned int get_con_freq(struct ConnectionClass * clptr)
 void add_class(char *name, unsigned int ping, unsigned int confreq,
                unsigned int maxli, unsigned int sendq)
 {
-  struct ConnectionClass* t;
   struct ConnectionClass* p;
 
-  t = find_class(name);
-  if ((t == connClassList) && (name != NULL))
-  {
-    p = (struct ConnectionClass *) make_class();
-    p->next = t->next;
-    t->next = p;
-  }
-  else
-  {
-    if (ConClass(t) != NULL)
-      MyFree(ConClass(t));
-    p = t;
-  }
   Debug((DEBUG_DEBUG, "Add Class %s: cf: %u pf: %u ml: %u sq: %d",
          name, confreq, ping, maxli, sendq));
+  assert(name != NULL);
+  p = find_class(name);
+  if (!p)
+    p = make_class();
+  else
+    MyFree(ConClass(p));
   ConClass(p) = name;
   ConFreq(p) = confreq;
   PingFreq(p) = ping;
@@ -240,8 +238,6 @@ void add_class(char *name, unsigned int ping, unsigned int confreq,
   MaxSendq(p) = (sendq > 0) ?
      sendq : feature_int(FEAT_DEFAULTMAXSENDQLENGTH);
   p->valid = 1;
-  if (p != t)
-    Links(p) = 0;
 }
 
 /** Find a connection class by name.
@@ -256,7 +252,7 @@ struct ConnectionClass* find_class(const char *name)
     if (!ircd_strcmp(ConClass(cltmp), name))
       return cltmp;
   }
-  return connClassList;
+  return NULL;
 }
 
 /** Report connection classes to a client.
index 0bb6aa9565ac45220f5a576435dcae6b009f6849..1424007c0e37987826a393374d609926706c6734 100644 (file)
@@ -904,7 +904,8 @@ int ipmask_parse(const char *in, struct irc_in_addr *mask, unsigned char *bits_p
   if (check_if_ipmask(in)) {
     bits = ipmask_parse_ipv4(in, &ipv4);
     mask->in6_16[0] = mask->in6_16[1] = mask->in6_16[2] = 0;
-    mask->in6_16[3] = mask->in6_16[4] = mask->in6_16[5] = 0;
+    mask->in6_16[3] = mask->in6_16[4] = 0;
+    mask->in6_16[5] = 0xffff;
     memcpy(&mask->in6_16[6], &ipv4.s_addr, sizeof(ipv4.s_addr));
     bits += 96;
   } else {
@@ -941,7 +942,7 @@ int ipmask_check(const struct irc_in_addr *addr, const struct irc_in_addr *mask,
 
   for (k = 0; k < 8; k++) {
     if (bits < 16)
-      return (addr->in6_16[k] & ((unsigned char) (0xffff << (16-bits)))) == mask->in6_16[k];
+      return (addr->in6_16[k] & htons(0xffff << (16-bits))) == mask->in6_16[k];
     if (addr->in6_16[k] != mask->in6_16[k])
       return 0;
     if (!(bits -= 16))
index 3b77ac326ef0880e1d1da4965b7bad7340a3284b..8359f21426648689e4d0104e987a7630d8def482 100644 (file)
@@ -70,14 +70,9 @@ static struct Motd *
 motd_create(const char *hostmask, const char *path, int maxcount)
 {
   struct Motd* tmp;
-  int type = MOTD_UNIVERSAL;
 
   assert(0 != path);
 
-  if (hostmask != NULL && find_class(hostmask))
-    type = MOTD_CLASS;
-  else
-    type = MOTD_HOSTMASK;
   /* allocate memory and initialize the structure */
   if (MotdList.freelist)
   {
@@ -85,9 +80,16 @@ motd_create(const char *hostmask, const char *path, int maxcount)
     MotdList.freelist = tmp->next;
   } else
     tmp = (struct Motd *)MyMalloc(sizeof(struct Motd));
-
   tmp->next = 0;
-  tmp->type = type;
+
+  if (hostmask == NULL)
+    tmp->type = MOTD_UNIVERSAL;
+  else if (find_class(hostmask))
+    tmp->type = MOTD_CLASS;
+  else if (ipmask_parse(hostmask, &tmp->address, &tmp->addrbits))
+    tmp->type = MOTD_IPMASK;
+  else
+    tmp->type = MOTD_HOSTMASK;
 
   if (hostmask != NULL)
     DupString(tmp->hostmask, hostmask);
@@ -250,15 +252,19 @@ motd_lookup(struct Client *cptr)
     return MotdList.remote;
 
   c_class = get_client_class(cptr);
+  assert(c_class != NULL);
 
   /* check the motd blocks first */
   for (ptr = MotdList.other; ptr; ptr = ptr->next)
   {
-    if (ptr->type == MOTD_CLASS &&
-        !match(ptr->hostmask, c_class))
+    if (ptr->type == MOTD_CLASS
+        && !match(ptr->hostmask, c_class))
+      return ptr;
+    else if (ptr->type == MOTD_HOSTMASK
+             && !match(ptr->hostmask, cli_sockhost(cptr)))
       return ptr;
-    else if (ptr->type == MOTD_HOSTMASK && c_class != NULL &&
-             !match(ptr->hostmask, cli_sockhost(cptr)))
+    else if (ptr->type == MOTD_IPMASK
+             && ipmask_check(&cli_ip(cptr), &ptr->address, ptr->addrbits))
       return ptr;
   }