Logo Search packages:      
Sourcecode: rageircd version File versions  Download package

iphash.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: iphash.c,v 1.18.2.1 2004/12/07 03:05:12 pneumatus Exp $
 */

#include "struct.h"
#include "common.h"
#include "sys.h"
#include "numeric.h"
#include "h.h"
#include "memory.h"
#include <fcntl.h>

IPEntry *ip_hash_table[IP_HASH_SIZE];
BlockHeap *ipentry_heap = NULL;

void init_ip_hash()
{
      ipentry_heap = BlockHeapCreate(sizeof(IPEntry), CLIENT_HEAP_SIZE);
      memset(ip_hash_table, '\0', IP_HASH_SIZE);
}

static int hash_ip(struct in_addr *addr)
{
      unsigned long ip = ntohl(addr->s_addr);
      return (((ip >> 12) + ip) & (IP_HASH_SIZE - 1));
}

IPEntry *find_or_add_ip(struct in_addr *addr)
{
      int hash = hash_ip(addr);
      IPEntry *ipe;

      for (ipe = ip_hash_table[hash]; ipe != NULL; ipe = ipe->next) {
            if (ipe->ip.s_addr == addr->s_addr) {
                  return ipe;
            }
      }

      ipe = BlockHeapAlloc(ipentry_heap);
      memcpy(&ipe->ip, addr, sizeof(struct in_addr));
      ipe->count = 0;

      if (ip_hash_table[hash] != NULL) {
            ipe->next = ip_hash_table[hash];
      }
      else {
            ipe->next = NULL;
      }
      ip_hash_table[hash] = ipe;

      return ipe;
}

void remove_one_ip(struct in_addr *addr)
{
      int hash = hash_ip(addr);
      IPEntry *ipe, *last = NULL;

      for (ipe = ip_hash_table[hash]; ipe != NULL; ipe = ipe->next) {
            if (ipe->ip.s_addr != addr->s_addr) {
                  last = ipe;
                  continue;
            }

            ASSERT(ipe->count > 0);

            if (--ipe->count) {
                  return;
            }
            if (last != NULL) {
                  last->next = ipe->next;
            }
            else {
                  ip_hash_table[hash] = ipe->next;
            }
            BlockHeapFree(ipentry_heap, ipe);
            break;
      }
}

void count_ip_hash_memory(int *ip_entry_cnt, unsigned long *ip_entry_mem)
{
      int hash, cnt = 0;
      IPEntry *ipe;

      for (hash = 0; hash < IP_HASH_SIZE; hash++) {
            for (ipe = ip_hash_table[hash]; ipe != NULL; ipe = ipe->next) {
                  cnt++;
            }
      }

      *ip_entry_cnt = cnt;
      *ip_entry_mem = (cnt * sizeof(IPEntry));
}

void list_ip_hash(aClient *cptr)
{
      int hash;
      IPEntry *ipe;

      send_me_debugNA(cptr, "i :IP Address        Count");

      for (hash = 0; hash < IP_HASH_SIZE; hash++) {
            for (ipe = ip_hash_table[hash]; ipe != NULL; ipe = ipe->next) {
                  send_me_debug(cptr, "i :%-17s %d", inetntoa((const char *)&ipe->ip), ipe->count);
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index