/*
- * $Id: acl.cc,v 1.77 1997/01/23 18:33:40 wessels Exp $
+ * $Id: acl.cc,v 1.78 1997/02/01 00:28:07 wessels Exp $
*
* DEBUG: section 28 Access Control
* AUTHOR: Duane Wessels
static void aclDestroyAclList _PARAMS((struct _acl_list * list));
static void aclDestroyIpList _PARAMS((struct _acl_ip_data * data));
+static struct _acl_ip_data *aclSplayInsertIp _PARAMS((struct in_addr, struct in_addr, struct in_addr, struct _acl_ip_data *));
+static struct _acl_ip_data *aclSplayIp _PARAMS((struct in_addr, struct _acl_ip_data *));
static void aclDestroyTimeList _PARAMS((struct _acl_time_data * data));
static int aclMatchDomainList _PARAMS((wordlist *, const char *));
static int aclMatchAclList _PARAMS((const struct _acl_list *, aclCheck_t *));
q->mask.s_addr = 0;
return q;
}
- memset(addr1, 0, 256);
- memset(addr2, 0, 256);
- memset(mask, 0, 256);
if (sscanf(t, "%[0-9.]-%[0-9.]/%[0-9.]", addr1, addr2, mask) == 3) {
(void) 0;
} else if (sscanf(t, "%[0-9.]-%[0-9.]", addr1, addr2) == 2) {
aclParseIpList(void *curlist)
{
char *t = NULL;
- struct _acl_ip_data **Tail;
+ struct _acl_ip_data **ip_data = curlist;
struct _acl_ip_data *q = NULL;
- for (Tail = curlist; *Tail; Tail = &((*Tail)->next));
while ((t = strtokFile())) {
if ((q = aclParseIpData(t)) == NULL)
continue;
- *(Tail) = q;
- Tail = &q->next;
+ *ip_data = aclSplayInsertIp(q->addr1, q->addr2, q->mask, *ip_data);
+ }
+
+}
+
+static struct _acl_ip_data *
+aclSplayInsertIp(struct in_addr addr1, struct in_addr addr2, struct in_addr mask, struct _acl_ip_data * t)
+{
+ struct _acl_ip_data *new;
+
+ new = xmalloc(sizeof(struct _acl_ip_data));
+ new->addr1 = addr1;
+ new->addr2 = addr2;
+ new->mask = mask;
+ if (t == NULL) {
+ new->left = new->right = NULL;
+ return new;
+ }
+ t = aclSplayIp(addr1, t);
+ if (addr1.s_addr < t->addr1.s_addr) {
+ new->left = t->left;
+ new->right = t;
+ t->left = NULL;
+ return new;
+ } else if (addr1.s_addr > t->addr1.s_addr) {
+ new->right = t->right;
+ new->left = t;
+ t->right = NULL;
+ return new;
+ } else {
+ debug(28, 0, "aclSplayInsertIp: Address is already in the tree, is this going to be a problem?");
+ safe_free(new);
+ return t;
+ }
+}
+
+static struct _acl_ip_data *
+aclSplayIp(struct in_addr addr1, struct _acl_ip_data * t)
+{
+ struct _acl_ip_data N, *l, *r, *y;
+ if (t == NULL)
+ return t;
+ N.left = N.right = NULL;
+ l = r = &N;
+
+ for (;;) {
+ if (addr1.s_addr < t->addr1.s_addr) {
+ if (t->left == NULL)
+ break;
+ if (addr1.s_addr < t->left->addr1.s_addr) {
+ y = t->left; /* rotate right */
+ t->left = y->right;
+ y->right = t;
+ t = y;
+ if (t->left == NULL)
+ break;
+ }
+ r->left = t; /* link right */
+ r = t;
+ t = t->left;
+ } else if (addr1.s_addr > t->addr1.s_addr) {
+ if (t->right == NULL)
+ break;
+ if (addr1.s_addr > t->right->addr1.s_addr) {
+ y = t->right; /* rotate left */
+ t->right = y->left;
+ y->left = t;
+ t = y;
+ if (t->right == NULL)
+ break;
+ }
+ l->right = t; /* link left */
+ l = t;
+ t = t->right;
+ } else {
+ break;
+ }
}
+ l->right = t->left; /* assemble */
+ r->left = t->right;
+ t->left = N.right;
+ t->right = N.left;
+ return t;
}
static void
return;
}
if ((A = aclFindByName(aclname)) == NULL) {
- debug(28, 3, "aclParseAclLine: Creating ACL '%s'\n", aclname);
+ debug(28, 3, "aclParseAclLine: Creating ACL '%s'\n", aclname);
A = xcalloc(1, sizeof(struct _acl));
xstrncpy(A->name, aclname, ACL_NAME_SZ);
A->type = acltype;
}
static int
-aclMatchIp(struct _acl_ip_data *data, struct in_addr c)
+aclMatchIp(struct _acl_ip_data * data, struct in_addr c)
{
struct in_addr h;
unsigned long lh, la1, la2;
- struct _acl_ip_data *first, *prev;
+ struct _acl_ip_data *root;
- first = data; /* remember first element, this will never be moved */
- prev = NULL; /* previous element in the list */
- while (data) {
- h.s_addr = c.s_addr & data->mask.s_addr;
- debug(28, 3, "aclMatchIp: h = %s\n", inet_ntoa(h));
- debug(28, 3, "aclMatchIp: addr1 = %s\n", inet_ntoa(data->addr1));
- debug(28, 3, "aclMatchIp: addr2 = %s\n", inet_ntoa(data->addr2));
+ h.s_addr = c.s_addr & data->mask.s_addr;
+ debug(28, 3, "aclMatchIp: h = %s\n", inet_ntoa(h));
+ debug(28, 3, "aclMatchIp: addr1 = %s\n", inet_ntoa(data->addr1));
+ debug(28, 3, "aclMatchIp: addr2 = %s\n", inet_ntoa(data->addr2));
+ root = aclSplayIp(h, data);
+ if (h.s_addr == root->addr1.s_addr) {
if (!data->addr2.s_addr) {
- if (h.s_addr == data->addr1.s_addr) {
- debug(28, 3, "aclMatchIp: returning 1\n");
- if (prev != NULL) {
- /* shift the element just found to the second position
- * in the list */
- prev->next = data->next;
- data->next = first->next;
- first->next = data;
- }
- return 1;
- }
+ debug(28, 3, "aclMatchIp: returning 1\n");
+ return 1;
} else {
/* This is a range check */
lh = ntohl(h.s_addr);
return 1;
}
}
- prev = data;
- data = data->next;
}
debug(28, 3, "aclMatchIp: returning 0\n");
return 0;
}
static void
-aclDestroyIpList(struct _acl_ip_data *data)
+aclDestroyIpList(struct _acl_ip_data * data)
{
- struct _acl_ip_data *next = NULL;
- for (; data; data = next) {
- next = data->next;
- safe_free(data);
- }
+ if (data == NULL)
+ return;
+ aclDestroyIpList(data->left);
+ aclDestroyIpList(data->right);
+ safe_free(data);
}
static void