/[svn]/ircd-hybrid/trunk/src/hostmask.c
ViewVC logotype

Annotation of /ircd-hybrid/trunk/src/hostmask.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1786 - (hide annotations)
Mon Jan 28 19:30:26 2013 UTC (7 years, 7 months ago) by michael
File MIME type: text/x-chdr
File size: 21226 byte(s)
- Fixed possible core in try_parse_v4_netmask() as reported by bobnomnom

1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * hostmask.c: Code to efficiently find IP & hostmask based configs.
4     *
5     * Copyright (C) 2005 by the past and present ircd coders, and others.
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20     * USA
21     *
22 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26     #include "memory.h"
27     #include "ircd_defs.h"
28 michael 1011 #include "list.h"
29 michael 1309 #include "conf.h"
30 adx 30 #include "hostmask.h"
31     #include "send.h"
32     #include "irc_string.h"
33 michael 1369 #include "ircd.h"
34 adx 30
35    
36     #define DigitParse(ch) do { \
37     if (ch >= '0' && ch <= '9') \
38     ch = ch - '0'; \
39     else if (ch >= 'A' && ch <= 'F') \
40     ch = ch - 'A' + 10; \
41     else if (ch >= 'a' && ch <= 'f') \
42     ch = ch - 'a' + 10; \
43 michael 1298 } while (0);
44 adx 30
45     /* The mask parser/type determination code... */
46    
47     /* int try_parse_v6_netmask(const char *, struct irc_ssaddr *, int *);
48     * Input: A possible IPV6 address as a string.
49     * Output: An integer describing whether it is an IPV6 or hostmask,
50     * an address(if it is IPV6), a bitlength(if it is IPV6).
51     * Side effects: None
52     * Comments: Called from parse_netmask
53     */
54     /* Fixed so ::/0 (any IPv6 address) is valid
55     Also a bug in DigitParse above.
56     -Gozem 2002-07-19 gozem@linux.nu
57     */
58     #ifdef IPV6
59     static int
60     try_parse_v6_netmask(const char *text, struct irc_ssaddr *addr, int *b)
61     {
62     const char *p;
63     char c;
64     int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
65     int dp = 0;
66     int nyble = 4;
67     int finsert = -1;
68     int bits = 128;
69     int deficit = 0;
70     short dc[8];
71 michael 1298 struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
72 adx 30
73     for (p = text; (c = *p); p++)
74     if (IsXDigit(c))
75     {
76     if (nyble == 0)
77     return HM_HOST;
78     DigitParse(c);
79     d[dp] |= c << (4 * --nyble);
80     }
81     else if (c == ':')
82     {
83     if (p > text && *(p - 1) == ':')
84     {
85     if (finsert >= 0)
86     return HM_HOST;
87     finsert = dp;
88     }
89     else
90     {
91     /* If there were less than 4 hex digits, e.g. :ABC: shift right
92     * so we don't interpret it as ABC0 -A1kmm */
93     d[dp] = d[dp] >> 4 * nyble;
94     nyble = 4;
95     if (++dp >= 8)
96     return HM_HOST;
97     }
98     }
99     else if (c == '*')
100     {
101     /* * must be last, and * is ambiguous if there is a ::... -A1kmm */
102     if (finsert >= 0 || *(p + 1) || dp == 0 || *(p - 1) != ':')
103     return HM_HOST;
104     bits = dp * 16;
105     }
106     else if (c == '/')
107     {
108     char *after;
109    
110     d[dp] = d[dp] >> 4 * nyble;
111     dp++;
112     bits = strtoul(p + 1, &after, 10);
113 michael 1298
114 adx 30 if (bits < 0 || *after)
115     return HM_HOST;
116     if (bits > dp * 4 && !(finsert >= 0 && bits <= 128))
117     return HM_HOST;
118     break;
119     }
120     else
121     return HM_HOST;
122    
123     d[dp] = d[dp] >> 4 * nyble;
124 michael 1298
125 adx 30 if (c == 0)
126     dp++;
127     if (finsert < 0 && bits == 0)
128     bits = dp * 16;
129 michael 1298
130 adx 30 /* How many words are missing? -A1kmm */
131     deficit = bits / 16 + ((bits % 16) ? 1 : 0) - dp;
132 michael 1298
133 adx 30 /* Now fill in the gaps(from ::) in the copied table... -A1kmm */
134     for (dp = 0, nyble = 0; dp < 8; dp++)
135     {
136     if (nyble == finsert && deficit)
137     {
138     dc[dp] = 0;
139     deficit--;
140     }
141     else
142     dc[dp] = d[nyble++];
143     }
144 michael 1298
145 adx 30 /* Set unused bits to 0... -A1kmm */
146     if (bits < 128 && (bits % 16 != 0))
147     dc[bits / 16] &= ~((1 << (15 - bits % 16)) - 1);
148     for (dp = bits / 16 + (bits % 16 ? 1 : 0); dp < 8; dp++)
149     dc[dp] = 0;
150 michael 1298
151 adx 30 /* And assign... -A1kmm */
152     if (addr)
153     for (dp = 0; dp < 8; dp++)
154     /* The cast is a kludge to make netbsd work. */
155     ((unsigned short *)&v6->sin6_addr)[dp] = htons(dc[dp]);
156 michael 1298
157 adx 30 if (b != NULL)
158     *b = bits;
159     return HM_IPV6;
160     }
161     #endif
162    
163     /* int try_parse_v4_netmask(const char *, struct irc_ssaddr *, int *);
164     * Input: A possible IPV4 address as a string.
165     * Output: An integer describing whether it is an IPV4 or hostmask,
166     * an address(if it is IPV4), a bitlength(if it is IPV4).
167     * Side effects: None
168     * Comments: Called from parse_netmask
169     */
170     static int
171     try_parse_v4_netmask(const char *text, struct irc_ssaddr *addr, int *b)
172     {
173     const char *p;
174     const char *digits[4];
175     unsigned char addb[4];
176     int n = 0, bits = 0;
177     char c;
178 michael 1298 struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
179 adx 30
180     digits[n++] = text;
181    
182     for (p = text; (c = *p); p++)
183     if (c >= '0' && c <= '9') /* empty */
184     ;
185     else if (c == '.')
186     {
187     if (n >= 4)
188     return HM_HOST;
189 michael 1298
190 adx 30 digits[n++] = p + 1;
191     }
192     else if (c == '*')
193     {
194     if (*(p + 1) || n == 0 || *(p - 1) != '.')
195     return HM_HOST;
196 michael 1298
197 adx 30 bits = (n - 1) * 8;
198     break;
199     }
200     else if (c == '/')
201     {
202     char *after;
203     bits = strtoul(p + 1, &after, 10);
204 michael 1298
205 michael 1786 if (bits < 0 || *after)
206 adx 30 return HM_HOST;
207     if (bits > n * 8)
208     return HM_HOST;
209 michael 1298
210 adx 30 break;
211     }
212     else
213     return HM_HOST;
214    
215     if (n < 4 && bits == 0)
216     bits = n * 8;
217     if (bits)
218     while (n < 4)
219     digits[n++] = "0";
220 michael 1298
221 adx 30 for (n = 0; n < 4; n++)
222     addb[n] = strtoul(digits[n], NULL, 10);
223 michael 1298
224 adx 30 if (bits == 0)
225     bits = 32;
226 michael 1298
227 adx 30 /* Set unused bits to 0... -A1kmm */
228     if (bits < 32 && bits % 8)
229     addb[bits / 8] &= ~((1 << (8 - bits % 8)) - 1);
230     for (n = bits / 8 + (bits % 8 ? 1 : 0); n < 4; n++)
231     addb[n] = 0;
232     if (addr)
233     v4->sin_addr.s_addr =
234     htonl(addb[0] << 24 | addb[1] << 16 | addb[2] << 8 | addb[3]);
235     if (b != NULL)
236     *b = bits;
237     return HM_IPV4;
238     }
239    
240     /* int parse_netmask(const char *, struct irc_ssaddr *, int *);
241     * Input: A hostmask, or an IPV4/6 address.
242     * Output: An integer describing whether it is an IPV4, IPV6 address or a
243     * hostmask, an address(if it is an IP mask),
244     * a bitlength(if it is IP mask).
245     * Side effects: None
246     */
247     int
248     parse_netmask(const char *text, struct irc_ssaddr *addr, int *b)
249     {
250     #ifdef IPV6
251 michael 1298 if (strchr(text, ':'))
252 adx 30 return try_parse_v6_netmask(text, addr, b);
253     #endif
254     if (strchr(text, '.'))
255     return try_parse_v4_netmask(text, addr, b);
256     return HM_HOST;
257     }
258    
259     /* The address matching stuff... */
260     /* int match_ipv6(struct irc_ssaddr *, struct irc_ssaddr *, int)
261     * Input: An IP address, an IP mask, the number of bits in the mask.
262     * Output: if match, -1 else 0
263     * Side effects: None
264     */
265     #ifdef IPV6
266     int
267 michael 1455 match_ipv6(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
268 adx 30 {
269     int i, m, n = bits / 8;
270 michael 1455 const struct sockaddr_in6 *v6 = (const struct sockaddr_in6 *)addr;
271     const struct sockaddr_in6 *v6mask = (const struct sockaddr_in6 *)mask;
272 adx 30
273     for (i = 0; i < n; i++)
274     if (v6->sin6_addr.s6_addr[i] != v6mask->sin6_addr.s6_addr[i])
275     return 0;
276     if ((m = bits % 8) == 0)
277     return -1;
278     if ((v6->sin6_addr.s6_addr[n] & ~((1 << (8 - m)) - 1)) ==
279     v6mask->sin6_addr.s6_addr[n])
280     return -1;
281     return 0;
282     }
283     #endif
284 michael 1372
285 adx 30 /* int match_ipv4(struct irc_ssaddr *, struct irc_ssaddr *, int)
286     * Input: An IP address, an IP mask, the number of bits in the mask.
287     * Output: if match, -1 else 0
288     * Side Effects: None
289     */
290     int
291 michael 1455 match_ipv4(const struct irc_ssaddr *addr, const struct irc_ssaddr *mask, int bits)
292 adx 30 {
293 michael 1455 const struct sockaddr_in *v4 = (const struct sockaddr_in *)addr;
294     const struct sockaddr_in *v4mask = (const struct sockaddr_in *)mask;
295 michael 1298
296 adx 30 if ((ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1)) !=
297     ntohl(v4mask->sin_addr.s_addr))
298     return 0;
299     return -1;
300     }
301    
302     /*
303     * mask_addr
304     *
305     * inputs - pointer to the ip to mask
306     * - bitlen
307     * output - NONE
308     * side effects -
309     */
310     void
311     mask_addr(struct irc_ssaddr *ip, int bits)
312     {
313     int mask;
314     #ifdef IPV6
315     struct sockaddr_in6 *v6_base_ip;
316     int i, m, n;
317     #endif
318     struct sockaddr_in *v4_base_ip;
319    
320     #ifdef IPV6
321     if (ip->ss.ss_family != AF_INET6)
322     #endif
323     {
324 michael 1298 v4_base_ip = (struct sockaddr_in *)ip;
325    
326 adx 30 mask = ~((1 << (32 - bits)) - 1);
327 michael 1298 v4_base_ip->sin_addr.s_addr = htonl(ntohl(v4_base_ip->sin_addr.s_addr) & mask);
328 adx 30 }
329     #ifdef IPV6
330     else
331     {
332     n = bits / 8;
333     m = bits % 8;
334 michael 1298 v6_base_ip = (struct sockaddr_in6 *)ip;
335 adx 30
336     mask = ~((1 << (8 - m)) -1 );
337     v6_base_ip->sin6_addr.s6_addr[n] = v6_base_ip->sin6_addr.s6_addr[n] & mask;
338 michael 1298
339 db 300 for (i = n + 1; i < 16; i++)
340     v6_base_ip->sin6_addr.s6_addr[i] = 0;
341 adx 30 }
342     #endif
343     }
344    
345     /* Hashtable stuff...now external as its used in m_stats.c */
346 michael 1367 dlink_list atable[ATABLE_SIZE];
347 adx 30
348     void
349     init_host_hash(void)
350     {
351     memset(&atable, 0, sizeof(atable));
352     }
353    
354     /* unsigned long hash_ipv4(struct irc_ssaddr*)
355     * Input: An IP address.
356     * Output: A hash value of the IP address.
357     * Side effects: None
358     */
359 michael 1343 static uint32_t
360 adx 30 hash_ipv4(struct irc_ssaddr *addr, int bits)
361     {
362     if (bits != 0)
363     {
364     struct sockaddr_in *v4 = (struct sockaddr_in *)addr;
365 michael 1343 uint32_t av = ntohl(v4->sin_addr.s_addr) & ~((1 << (32 - bits)) - 1);
366 michael 1298
367     return (av ^ (av >> 12) ^ (av >> 24)) & (ATABLE_SIZE - 1);
368 adx 30 }
369    
370 michael 1298 return 0;
371 adx 30 }
372    
373     /* unsigned long hash_ipv6(struct irc_ssaddr*)
374     * Input: An IP address.
375     * Output: A hash value of the IP address.
376     * Side effects: None
377     */
378     #ifdef IPV6
379 michael 1343 static uint32_t
380 adx 30 hash_ipv6(struct irc_ssaddr *addr, int bits)
381     {
382 michael 1343 uint32_t v = 0, n;
383 michael 1298 struct sockaddr_in6 *v6 = (struct sockaddr_in6 *)addr;
384    
385 adx 30 for (n = 0; n < 16; n++)
386     {
387     if (bits >= 8)
388     {
389     v ^= v6->sin6_addr.s6_addr[n];
390     bits -= 8;
391     }
392     else if (bits)
393     {
394     v ^= v6->sin6_addr.s6_addr[n] & ~((1 << (8 - bits)) - 1);
395     return v & (ATABLE_SIZE - 1);
396     }
397     else
398     return v & (ATABLE_SIZE - 1);
399     }
400     return v & (ATABLE_SIZE - 1);
401     }
402     #endif
403    
404     /* int hash_text(const char *start)
405     * Input: The start of the text to hash.
406     * Output: The hash of the string between 1 and (TH_MAX-1)
407     * Side-effects: None.
408     */
409 michael 1343 static uint32_t
410 adx 30 hash_text(const char *start)
411     {
412     const char *p = start;
413 michael 1343 uint32_t h = 0;
414 adx 30
415 michael 1367 for (; *p; ++p)
416     h = (h << 4) - (h + (unsigned char)ToLower(*p));
417 michael 1298
418     return h & (ATABLE_SIZE - 1);
419 adx 30 }
420    
421     /* unsigned long get_hash_mask(const char *)
422     * Input: The text to hash.
423     * Output: The hash of the string right of the first '.' past the last
424     * wildcard in the string.
425     * Side-effects: None.
426     */
427 michael 1343 static uint32_t
428 adx 30 get_mask_hash(const char *text)
429     {
430     const char *hp = "", *p;
431    
432     for (p = text + strlen(text) - 1; p >= text; p--)
433 adx 723 if (IsMWildChar(*p))
434 adx 30 return hash_text(hp);
435     else if (*p == '.')
436     hp = p + 1;
437     return hash_text(text);
438     }
439    
440 michael 1632 /* struct MaskItem *find_conf_by_address(const char *, struct irc_ssaddr *,
441 adx 30 * int type, int fam, const char *username)
442     * Input: The hostname, the address, the type of mask to find, the address
443     * family, the username.
444     * Output: The matching value with the highest precedence.
445     * Side-effects: None
446     * Note: Setting bit 0 of the type means that the username is ignored.
447     * Warning: IsNeedPassword for everything that is not an auth{} entry
448 michael 1632 * should always be true (i.e. conf->flags & CONF_FLAGS_NEED_PASSWORD == 0)
449 adx 30 */
450 michael 1632 struct MaskItem *
451 michael 1369 find_conf_by_address(const char *name, struct irc_ssaddr *addr, unsigned int type,
452 michael 1371 int fam, const char *username, const char *password, int do_match)
453 adx 30 {
454 michael 1343 unsigned int hprecv = 0;
455 michael 1367 dlink_node *ptr = NULL;
456 michael 1632 struct MaskItem *hprec = NULL;
457     struct AddressRec *arec = NULL;
458 adx 30 int b;
459 michael 1371 int (*cmpfunc)(const char *, const char *) = do_match ? match : irccmp;
460 adx 30
461     if (username == NULL)
462     username = "";
463     if (password == NULL)
464     password = "";
465    
466     if (addr)
467     {
468     /* Check for IPV6 matches... */
469     #ifdef IPV6
470     if (fam == AF_INET6)
471     {
472     for (b = 128; b >= 0; b -= 16)
473     {
474 michael 1367 DLINK_FOREACH(ptr, atable[hash_ipv6(addr, b)].head)
475     {
476     arec = ptr->data;
477    
478 adx 30 if (arec->type == (type & ~0x1) &&
479     arec->precedence > hprecv &&
480     arec->masktype == HM_IPV6 &&
481     match_ipv6(addr, &arec->Mask.ipa.addr,
482     arec->Mask.ipa.bits) &&
483 michael 1652 (type & 0x1 || !cmpfunc(arec->username, username)) &&
484 michael 1632 (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
485     match_conf_password(password, arec->conf)))
486 adx 30 {
487     hprecv = arec->precedence;
488 michael 1632 hprec = arec->conf;
489 adx 30 }
490 michael 1367 }
491 adx 30 }
492     }
493     else
494     #endif
495     if (fam == AF_INET)
496     {
497     for (b = 32; b >= 0; b -= 8)
498     {
499 michael 1367 DLINK_FOREACH(ptr, atable[hash_ipv4(addr, b)].head)
500     {
501     arec = ptr->data;
502    
503 adx 30 if (arec->type == (type & ~0x1) &&
504     arec->precedence > hprecv &&
505     arec->masktype == HM_IPV4 &&
506     match_ipv4(addr, &arec->Mask.ipa.addr,
507     arec->Mask.ipa.bits) &&
508 michael 1652 (type & 0x1 || !cmpfunc(arec->username, username)) &&
509 michael 1632 (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
510     match_conf_password(password, arec->conf)))
511 adx 30 {
512     hprecv = arec->precedence;
513 michael 1632 hprec = arec->conf;
514 adx 30 }
515 michael 1367 }
516 adx 30 }
517     }
518     }
519    
520     if (name != NULL)
521     {
522     const char *p = name;
523    
524     while (1)
525     {
526 michael 1367 DLINK_FOREACH(ptr, atable[hash_text(p)].head)
527     {
528     arec = ptr->data;
529     if ((arec->type == (type & ~0x1)) &&
530 adx 30 arec->precedence > hprecv &&
531     (arec->masktype == HM_HOST) &&
532 michael 1652 !cmpfunc(arec->Mask.hostname, name) &&
533     (type & 0x1 || !cmpfunc(arec->username, username)) &&
534 michael 1632 (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
535     match_conf_password(password, arec->conf)))
536 adx 30 {
537     hprecv = arec->precedence;
538 michael 1632 hprec = arec->conf;
539 adx 30 }
540 michael 1367 }
541 adx 30 p = strchr(p, '.');
542     if (p == NULL)
543     break;
544     p++;
545     }
546 michael 1367
547     DLINK_FOREACH(ptr, atable[0].head)
548     {
549     arec = ptr->data;
550    
551 adx 30 if (arec->type == (type & ~0x1) &&
552     arec->precedence > hprecv &&
553     arec->masktype == HM_HOST &&
554 michael 1652 !cmpfunc(arec->Mask.hostname, name) &&
555 michael 1655 (type & 0x1 || !cmpfunc(arec->username, username)) &&
556 michael 1632 (IsNeedPassword(arec->conf) || arec->conf->passwd == NULL ||
557     match_conf_password(password, arec->conf)))
558 adx 30 {
559     hprecv = arec->precedence;
560 michael 1632 hprec = arec->conf;
561 adx 30 }
562 michael 1367 }
563 adx 30 }
564    
565     return hprec;
566     }
567    
568 michael 1632 /* struct MaskItem* find_address_conf(const char*, const char*,
569 adx 30 * struct irc_ssaddr*, int, char *);
570     * Input: The hostname, username, address, address family.
571 michael 1632 * Output: The applicable MaskItem.
572 adx 30 * Side-effects: None
573     */
574 michael 1632 struct MaskItem *
575 adx 30 find_address_conf(const char *host, const char *user,
576     struct irc_ssaddr *ip, int aftype, char *password)
577     {
578 michael 1632 struct MaskItem *authcnf = NULL, *killcnf = NULL;
579 adx 30
580 michael 1426 /* Find the best auth{} block... If none, return NULL -A1kmm */
581 michael 1632 if ((authcnf = find_conf_by_address(host, ip, CONF_CLIENT, aftype, user,
582     password, 1)) == NULL)
583 michael 1298 return NULL;
584 adx 30
585 michael 1426 /* If they are exempt from K-lines, return the best auth{} block. -A1kmm */
586 michael 1632 if (IsConfExemptKline(authcnf))
587     return authcnf;
588 adx 30
589     /* Find the best K-line... -A1kmm */
590 michael 1632 killcnf = find_conf_by_address(host, ip, CONF_KLINE, aftype, user, NULL, 1);
591 adx 30
592 michael 1426 /*
593     * If they are K-lined, return the K-line. Otherwise, return the
594     * auth{} block. -A1kmm
595     */
596 michael 1632 if (killcnf != NULL)
597     return killcnf;
598 adx 30
599 michael 1632 if (IsConfExemptGline(authcnf))
600     return authcnf;
601 adx 30
602 michael 1632 killcnf = find_conf_by_address(host, ip, CONF_GLINE, aftype, user, NULL, 1);
603     if (killcnf != NULL)
604     return killcnf;
605    
606     return authcnf;
607 adx 30 }
608    
609 michael 1632 /* struct MaskItem* find_dline_conf(struct irc_ssaddr*, int)
610 adx 30 *
611     * Input: An address, an address family.
612     * Output: The best matching D-line or exempt line.
613     * Side effects: None.
614     */
615 michael 1632 struct MaskItem *
616 adx 30 find_dline_conf(struct irc_ssaddr *addr, int aftype)
617     {
618 michael 1632 struct MaskItem *eline;
619 adx 30
620 michael 1632 eline = find_conf_by_address(NULL, addr, CONF_EXEMPT | 1, aftype,
621 michael 1371 NULL, NULL, 1);
622 adx 30 if (eline != NULL)
623 michael 1298 return eline;
624    
625 michael 1371 return find_conf_by_address(NULL, addr, CONF_DLINE | 1, aftype, NULL, NULL, 1);
626 adx 30 }
627    
628 michael 1632 /* void add_conf_by_address(int, struct MaskItem *aconf)
629 adx 30 * Input:
630     * Output: None
631     * Side-effects: Adds this entry to the hash table.
632     */
633     void
634 michael 1632 add_conf_by_address(const unsigned int type, struct MaskItem *conf)
635 adx 30 {
636     const char *address;
637     const char *username;
638 michael 1343 static unsigned int prec_value = 0xFFFFFFFF;
639 michael 1367 int bits = 0;
640 adx 30 struct AddressRec *arec;
641    
642 michael 1632 address = conf->host;
643     username = conf->user;
644 adx 30
645 michael 1632 assert(type);
646 adx 30
647     if (EmptyString(address))
648     address = "/NOMATCH!/";
649    
650     arec = MyMalloc(sizeof(struct AddressRec));
651 michael 1367 arec->masktype = parse_netmask(address, &arec->Mask.ipa.addr, &bits);
652 adx 30 arec->Mask.ipa.bits = bits;
653 michael 1367 arec->username = username;
654 michael 1632 arec->conf = conf;
655 michael 1367 arec->precedence = prec_value--;
656     arec->type = type;
657 michael 1298
658 michael 1367 switch (arec->masktype)
659     {
660     case HM_IPV4:
661     /* We have to do this, since we do not re-hash for every bit -A1kmm. */
662     bits -= bits % 8;
663     dlinkAdd(arec, &arec->node, &atable[hash_ipv4(&arec->Mask.ipa.addr, bits)]);
664     break;
665 adx 30 #ifdef IPV6
666 michael 1367 case HM_IPV6:
667     /* We have to do this, since we do not re-hash for every bit -A1kmm. */
668     bits -= bits % 16;
669     dlinkAdd(arec, &arec->node, &atable[hash_ipv6(&arec->Mask.ipa.addr, bits)]);
670     break;
671 adx 30 #endif
672 michael 1367 default: /* HM_HOST */
673     arec->Mask.hostname = address;
674     dlinkAdd(arec, &arec->node, &atable[get_mask_hash(address)]);
675     break;
676 adx 30 }
677     }
678    
679 michael 1632 /* void delete_one_address(const char*, struct MaskItem*)
680     * Input: An address string, the associated MaskItem.
681 adx 30 * Output: None
682 michael 1632 * Side effects: Deletes an address record. Frees the MaskItem if there
683 adx 30 * is nothing referencing it, sets it as illegal otherwise.
684     */
685     void
686 michael 1632 delete_one_address_conf(const char *address, struct MaskItem *conf)
687 adx 30 {
688 michael 1367 int bits = 0;
689     uint32_t hv = 0;
690     dlink_node *ptr = NULL, *ptr_next = NULL;
691 adx 30 struct irc_ssaddr addr;
692 michael 1298
693 michael 1367 switch (parse_netmask(address, &addr, &bits))
694     {
695     case HM_IPV4:
696     /* We have to do this, since we do not re-hash for every bit -A1kmm. */
697     bits -= bits % 8;
698     hv = hash_ipv4(&addr, bits);
699     break;
700 adx 30 #ifdef IPV6
701 michael 1367 case HM_IPV6:
702     /* We have to do this, since we do not re-hash for every bit -A1kmm. */
703     bits -= bits % 16;
704     hv = hash_ipv6(&addr, bits);
705     break;
706 adx 30 #endif
707 michael 1367 default: /* HM_HOST */
708     hv = get_mask_hash(address);
709     break;
710 adx 30 }
711 michael 1298
712 michael 1367 DLINK_FOREACH_SAFE(ptr, ptr_next, atable[hv].head)
713 adx 30 {
714 michael 1367 struct AddressRec *arec = ptr->data;
715    
716 michael 1632 if (arec->conf == conf)
717 adx 30 {
718 michael 1367 dlinkDelete(&arec->node, &atable[hv]);
719 michael 1298
720 michael 1644 if (!conf->ref_count)
721 michael 1632 conf_free(conf);
722 michael 1298
723 adx 30 MyFree(arec);
724     return;
725     }
726     }
727     }
728    
729     /* void clear_out_address_conf(void)
730     * Input: None
731     * Output: None
732     * Side effects: Clears out all address records in the hash table,
733 michael 1632 * frees them, and frees the MaskItems if nothing references
734 adx 30 * them, otherwise sets them as illegal.
735     */
736     void
737     clear_out_address_conf(void)
738     {
739 michael 1367 unsigned int i = 0;
740     dlink_node *ptr = NULL, *ptr_next = NULL;
741 adx 30
742 michael 1367 for (i = 0; i < ATABLE_SIZE; ++i)
743 adx 30 {
744 michael 1367 DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
745 adx 30 {
746 michael 1367 struct AddressRec *arec = ptr->data;
747    
748 michael 1628 /*
749     * We keep the temporary K-lines and destroy the permanent ones,
750     * just to be confusing :) -A1kmm
751     */
752 michael 1649 if (arec->conf->until || IsConfDatabase(arec->conf))
753 michael 1628 continue;
754 michael 1622
755 michael 1628 dlinkDelete(&arec->node, &atable[i]);
756 michael 1298
757 michael 1644 if (!arec->conf->ref_count)
758 michael 1632 conf_free(arec->conf);
759 michael 1628 MyFree(arec);
760 adx 30 }
761     }
762     }
763    
764 michael 1369 static void
765     hostmask_send_expiration(struct AddressRec *arec)
766     {
767     char ban_type = '\0';
768    
769     if (!ConfigFileEntry.tkline_expire_notices)
770     return;
771    
772     switch (arec->type)
773     {
774     case CONF_KLINE:
775     ban_type = 'K';
776     break;
777     case CONF_DLINE:
778     ban_type = 'D';
779     break;
780     case CONF_GLINE:
781     ban_type = 'G';
782     break;
783 michael 1644 default: break;
784 michael 1369 }
785    
786 michael 1618 sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE,
787 michael 1369 "Temporary %c-line for [%s@%s] expired", ban_type,
788 michael 1632 (arec->conf->user) ? arec->conf->user : "*",
789     (arec->conf->host) ? arec->conf->host : "*");
790 michael 1369 }
791    
792     void
793     hostmask_expire_temporary(void)
794     {
795     unsigned int i = 0;
796     dlink_node *ptr = NULL, *ptr_next = NULL;
797    
798     for (i = 0; i < ATABLE_SIZE; ++i)
799     {
800     DLINK_FOREACH_SAFE(ptr, ptr_next, atable[i].head)
801     {
802     struct AddressRec *arec = ptr->data;
803    
804 michael 1649 if (!arec->conf->until || arec->conf->until > CurrentTime)
805 michael 1369 continue;
806    
807     switch (arec->type)
808     {
809     case CONF_KLINE:
810     case CONF_DLINE:
811     case CONF_GLINE:
812     hostmask_send_expiration(arec);
813    
814     dlinkDelete(&arec->node, &atable[i]);
815 michael 1632 conf_free(arec->conf);
816 michael 1369 MyFree(arec);
817     break;
818 michael 1644 default: break;
819 michael 1369 }
820     }
821     }
822     }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28