From: Michael Poole Date: Sun, 17 Oct 2004 01:58:17 +0000 (+0000) Subject: Add support for CIDR-based MOTD masks. X-Git-Url: http://git.pk910.de/?a=commitdiff_plain;h=ed9de9e9dd8a8b224147e97a85c0641a9c7e690a;p=ircu2.10.12-pk.git Add support for CIDR-based MOTD masks. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1248 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- diff --git a/ChangeLog b/ChangeLog index e754d48..1d3480b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2004-10-16 Michael Poole + + * 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 * ircd/numeric.h: Remove the unused RPL_STATMEM and diff --git a/include/motd.h b/include/motd.h index 3383b91..6de178e 100644 --- a/include/motd.h +++ b/include/motd.h @@ -33,29 +33,36 @@ #include #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 */ diff --git a/ircd/class.c b/ircd/class.c index 9c00e84..53fd65e 100644 --- a/ircd/class.c +++ b/ircd/class.c @@ -38,7 +38,7 @@ #include /** 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. diff --git a/ircd/match.c b/ircd/match.c index 0bb6aa9..1424007 100644 --- a/ircd/match.c +++ b/ircd/match.c @@ -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)) diff --git a/ircd/motd.c b/ircd/motd.c index 3b77ac3..8359f21 100644 --- a/ircd/motd.c +++ b/ircd/motd.c @@ -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; }