+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
#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 */
#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;
}
/** 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;
}
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;
MaxSendq(p) = (sendq > 0) ?
sendq : feature_int(FEAT_DEFAULTMAXSENDQLENGTH);
p->valid = 1;
- if (p != t)
- Links(p) = 0;
}
/** Find a connection class by name.
if (!ircd_strcmp(ConClass(cltmp), name))
return cltmp;
}
- return connClassList;
+ return NULL;
}
/** Report connection classes to a client.
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 {
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))
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)
{
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);
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;
}