/*
* LIB/IPLIST.C
*
* (c)Copyright 2001, Russell Vincent, All Rights Reserved. Refer to
* the COPYRIGHT file in the base directory of this distribution
* for specific rights granted.
*
*
* This file maintains an IP address hash list that can be used
* as a ban/spam list.
*/
#include "defs.h"
#define DEFAULT_HSIZE 64
#define DEFAULT_HLINK 8
Prototype void IPListAdd(IPList **iplist, char *ip, int count, time_t expire, int hashsize, int hashlinksize);
Prototype int IPListCheck(IPList *iplist, char *ip, int decrement, time_t expire, time_t t, int hashsize);
Prototype void IPListDump(FILE *fo, IPList *iplist, int hashsize);
void
IPListAdd(IPList **iplist, char *ip, int count, time_t expire, int hashsize, int hashlinksize)
{
md5hash_t iphash;
IPList *ipl;
IPList *iparray;
if (hashsize == 0)
hashsize = DEFAULT_HSIZE;
if (hashlinksize == 0)
hashlinksize = DEFAULT_HLINK;
if (*iplist == NULL) {
*iplist = (struct IPList *)malloc(hashsize * sizeof(struct IPList));
if (*iplist == NULL)
return;
bzero(*iplist, hashsize * sizeof(struct IPList));
}
iparray = *iplist;
memcpy(&iphash, md5hash(ip), sizeof(iphash));
ipl = &iparray[(iphash.h1 + iphash.h2) & (hashsize - 1)];
if (ipl->il_ip != NULL && strcmp(ip, ipl->il_ip) == 0)
return;
while (ipl->il_expire != 0 && ipl->il_next != NULL) {
ipl = ipl->il_next;
hashlinksize--;
if (ipl != NULL && ipl->il_ip != NULL && strcmp(ip, ipl->il_ip) == 0)
return;
}
if (hashlinksize < 0)
return;
if (ipl->il_expire != 0) {
ipl->il_next = (struct IPList *) malloc(sizeof(struct IPList));
ipl = ipl->il_next;
bzero(ipl, sizeof(*ipl));
}
if (ipl->il_ip != NULL)
free(ipl->il_ip);
ipl->il_ip = strdup(ip);
ipl->il_count = count;
ipl->il_expire = expire;
ipl->il_next = NULL;
}
/*
* Check to see if an IP has reached a count of zero
*
* Returns:
* -1 = not found or expired
* 0 = count is zero
* >0 = count
*/
int
IPListCheck(IPList *iplist, char *ip, int decrement, time_t expire, time_t t, int hashsize)
{
md5hash_t iphash;
IPList *ipl;
if (iplist == NULL)
return(-1);
if (hashsize == 0)
hashsize = DEFAULT_HSIZE;
memcpy(&iphash, md5hash(ip), sizeof(iphash));
ipl = &iplist[(iphash.h1 + iphash.h2) & (hashsize - 1)];
while (ipl != NULL && ipl->il_ip != NULL && strcmp(ip, ipl->il_ip) != 0)
ipl = ipl->il_next;
if (ipl == NULL)
return(-1);
if (ipl->il_expire < t) {
if (ipl->il_ip != NULL)
free(ipl->il_ip);
bzero(ipl, sizeof(*ipl));
return(-1);
}
if (decrement && ipl->il_count > 0) {
ipl->il_count--;
ipl->il_expire = expire;
}
return(ipl->il_count);
}
void
IPListDelete(IPList *iplist, char *ip)
{
}
void
IPListDump(FILE *fo, IPList *iplist, int hashsize)
{
time_t t = time(NULL);
int i;
IPList *ipl;
if (iplist == NULL)
return;
if (hashsize == 0)
hashsize = DEFAULT_HSIZE;
for (i = 0; i < hashsize; i++) {
ipl = &iplist[i];
while (ipl != NULL) {
if (ipl->il_ip != NULL)
fprintf(fo, "%c %-50s %10d %12u\n",
(ipl->il_count == 0 && ipl->il_expire > t) ? 'B' : ' ',
ipl->il_ip,
ipl->il_count,
ipl->il_expire - t
);
ipl = ipl->il_next;
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1