Files
flexnbd-c/parse.c

88 lines
2.0 KiB
C
Raw Normal View History

#include "parse.h"
#include "util.h"
int atoi(const char *nptr);
#define IS_IP_VALID_CHAR(x) ( ((x) >= '0' && (x) <= '9' ) || \
((x) >= 'a' && (x) <= 'f') || \
((x) >= 'A' && (x) <= 'F' ) || \
(x) == ':' || (x) == '.' \
)
int parse_ip_to_sockaddr(struct sockaddr* out, char* src)
{
char temp[64];
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;
if (src[i] == '[')
i++;
for (; i<64 && IS_IP_VALID_CHAR(src[i]); i++)
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;
return 1;
}
if (inet_pton(AF_INET, temp, &v4->sin_addr) == 1) {
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)
{
int i;
if (max == 0) {
*out = NULL;
return 0;
}
else {
*out = xmalloc(max * sizeof(struct ip_and_mask));
debug("acl alloc: %p", *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 = *out+i;
if (parse_ip_to_sockaddr(&outentry->ip.generic, entries[i]) == 0)
return i;
for (j=0; entries[i][j] && entries[i][j] != '/'; j++)
;
if (entries[i][j] == '/') {
outentry->mask = atoi(entries[i]+j+1);
if (outentry->mask < 1 || outentry->mask > MAX_MASK_BITS)
return i;
}
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++) {
struct ip_and_mask* entry = *out+i;
debug("acl entry %d @ %p has mask %d", i, entry, entry->mask);
}
return max;
}