This commit is contained in:
Alex Young
2012-06-11 13:49:56 +01:00
4 changed files with 145 additions and 41 deletions

View File

@@ -27,18 +27,18 @@ static int is_included_in_acl(int list_length, struct ip_and_mask (*list)[], uni
NULLCHECK( test );
int i;
for (i=0; i < list_length; i++) {
struct ip_and_mask *entry = &(*list)[i];
int testbits;
unsigned char *raw_address1, *raw_address2;
debug("checking acl entry %d (%d/%d)", i, test->generic.sa_family, entry->ip.family);
if (test->generic.sa_family != entry->ip.family) {
continue;
}
if (test->generic.sa_family == AF_INET) {
debug("it's an AF_INET");
raw_address1 = (unsigned char*) &test->v4.sin_addr;
@@ -49,9 +49,9 @@ static int is_included_in_acl(int list_length, struct ip_and_mask (*list)[], uni
raw_address1 = (unsigned char*) &test->v6.sin6_addr;
raw_address2 = (unsigned char*) &entry->ip.v6.sin6_addr;
}
debug("testbits=%d", entry->mask);
for (testbits = entry->mask; testbits > 0; testbits -= 8) {
debug("testbits=%d, c1=%02x, c2=%02x", testbits, raw_address1[0], raw_address2[0]);
if (testbits >= 8) {
@@ -63,17 +63,17 @@ static int is_included_in_acl(int list_length, struct ip_and_mask (*list)[], uni
(raw_address2[0] & testmasks[testbits%8]) )
goto no_match;
}
raw_address1++;
raw_address2++;
}
return 1;
no_match: ;
debug("no match");
}
return 0;
}
@@ -83,7 +83,7 @@ int acl_includes( struct acl * acl, union mysockaddr * addr )
if ( 0 == acl->len ) {
return !( acl->default_deny );
}
}
else {
return is_included_in_acl( acl->len, acl->entries, addr );
}
@@ -97,3 +97,4 @@ void acl_destroy( struct acl * acl )
acl->entries = NULL;
free( acl );
}

View File

@@ -12,9 +12,9 @@ int atoi(const char *nptr);
int parse_ip_to_sockaddr(struct sockaddr* out, char* src)
{
char temp[64];
struct sockaddr_in *v4 = (struct sockaddr_in *) out;
struct sockaddr_in *v4 = (struct sockaddr_in *) out;
struct sockaddr_in6 *v6 = (struct sockaddr_in6 *) out;
/* allow user to start with [ and end with any other invalid char */
{
int i=0, j=0;
@@ -24,7 +24,7 @@ int parse_ip_to_sockaddr(struct sockaddr* out, char* src)
temp[j++] = src[i];
temp[j] = 0;
}
if (temp[0] == '0' && temp[1] == '\0') {
v4->sin_family = AF_INET;
v4->sin_addr.s_addr = INADDR_ANY;
@@ -35,56 +35,58 @@ int parse_ip_to_sockaddr(struct sockaddr* out, char* src)
out->sa_family = AF_INET;
return 1;
}
if (inet_pton(AF_INET6, temp, &v6->sin6_addr) == 1) {
out->sa_family = AF_INET6;
return 1;
}
return 0;
}
int parse_acl(struct ip_and_mask (**out)[], int max, char **entries)
{
struct ip_and_mask (*list)[0];
struct ip_and_mask* list;
int i;
if (max == 0) {
*out = NULL;
return 0;
}
else {
*out = xmalloc(max * sizeof(struct ip_and_mask));
list = xmalloc(max * sizeof(struct ip_and_mask));
*out = (struct ip_and_mask (*)[])list;
debug("acl alloc: %p", *out);
}
list = *out;
for (i = 0; i < max; i++) {
# define MAX_MASK_BITS (outentry->ip.family == AF_INET ? 32 : 128)
int j;
struct ip_and_mask* outentry = list[i];
if (parse_ip_to_sockaddr(&outentry->ip.generic, entries[i]) == 0)
struct ip_and_mask* outentry = &list[i];
# define MAX_MASK_BITS (outentry->ip.family == AF_INET ? 32 : 128)
if (parse_ip_to_sockaddr(&outentry->ip.generic, entries[i]) == 0) {
return i;
}
for (j=0; entries[i][j] && entries[i][j] != '/'; j++)
;
; // increment j!
if (entries[i][j] == '/') {
outentry->mask = atoi(entries[i]+j+1);
if (outentry->mask < 1 || outentry->mask > MAX_MASK_BITS)
return i;
}
else
else {
outentry->mask = MAX_MASK_BITS;
}
# undef MAX_MASK_BITS
debug("acl ptr[%d]: %p %d",i, outentry, outentry->mask);
}
for (i=0; i < max; i++) {
debug("acl entry %d @ %p has mask %d", i, list[i], list[i]->mask);
debug("acl entry %d @ %p has mask %d", i, list[i], list[i].mask);
}
return max;
}