Skip to content

Commit

Permalink
Add PW_TYPE_COMBO_IP_PREFIX (conffile parser only)
Browse files Browse the repository at this point in the history
Change 'ipaddr' to PW_TYPE_COMBO_IP_PREFIX so we can be really lazy about IP formats
  • Loading branch information
arr2036 committed May 30, 2014
1 parent 9448bcd commit 3ba4a62
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 44 deletions.
6 changes: 5 additions & 1 deletion src/include/conffile.h
Expand Up @@ -72,14 +72,18 @@ typedef struct timeval _timeval_t;
__builtin_choose_expr(__builtin_types_compatible_p(uint8_t[6], _ct), _p, (conf_type_mismatch) 0),\
__builtin_choose_expr((_t == PW_TYPE_SIGNED),\
__builtin_choose_expr(__builtin_types_compatible_p(int32_t *, _ct), _p, (conf_type_mismatch) 0),\
__builtin_choose_expr((_t == PW_TYPE_COMBO_IP),\
__builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
__builtin_choose_expr((_t == PW_TYPE_INTEGER64),\
__builtin_choose_expr(__builtin_types_compatible_p(uint64_t *, _ct), _p, (conf_type_mismatch) 0),\
__builtin_choose_expr((_t == PW_TYPE_IPV4PREFIX),\
__builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
__builtin_choose_expr((_t == PW_TYPE_TIMEVAL),\
__builtin_choose_expr(__builtin_types_compatible_p(_timeval_t *, _ct), _p, (conf_type_mismatch) 0),\
__builtin_choose_expr((_t == PW_TYPE_COMBO_IPPREFIX),\
__builtin_choose_expr(__builtin_types_compatible_p(fr_ipaddr_t *, _ct), _p, (conf_type_mismatch) 0),\
(conf_type_invalid) 0\
))))))))))))))))))
))))))))))))))))))))

# define FR_CONF_OFFSET(_t, _s, _f) _t, FR_CONF_TYPE_CHECK(((_t) & 0xff), __typeof__(&(((_s *)NULL)->_f)), offsetof(_s, _f)), NULL
# define FR_CONF_POINTER(_t, _p) _t, 0, FR_CONF_TYPE_CHECK(((_t) & 0xff), __typeof__(_p), _p)
Expand Down
1 change: 1 addition & 0 deletions src/include/radius.h
Expand Up @@ -30,6 +30,7 @@ typedef enum {
PW_TYPE_VSA, //!< Vendor-Specific, for RADIUS attribute 26.
PW_TYPE_TIMEVAL, //!< Time value (struct timeval), only for config items.
PW_TYPE_BOOLEAN, //!< A truth value.
PW_TYPE_COMBO_IPPREFIX, //!< WiMAX IPv4 or IPv6 address prefix depending on length.
PW_TYPE_MAX //!< Number of defined data types.
} PW_TYPE;

Expand Down
1 change: 1 addition & 0 deletions src/lib/radius.c
Expand Up @@ -3999,6 +3999,7 @@ ssize_t rad_vp2data(uint8_t const **out, VALUE_PAIR const *vp)
case PW_TYPE_ABINARY:
case PW_TYPE_ETHERNET:
case PW_TYPE_COMBO_IP:
case PW_TYPE_COMBO_IPPREFIX:
{
void const *p = &vp->data;
memcpy(out, &p, sizeof(*out));
Expand Down
1 change: 1 addition & 0 deletions src/lib/valuepair.c
Expand Up @@ -2445,6 +2445,7 @@ int8_t paircmp_value(VALUE_PAIR const *one, VALUE_PAIR const *two)
*/
case PW_TYPE_INVALID: /* We should never see these */
case PW_TYPE_COMBO_IP: /* This should of been converted into IPADDR/IPV6ADDR */
case PW_TYPE_COMBO_IPPREFIX: /* This should of been converted into IPADDR/IPV6ADDR */
case PW_TYPE_TLV:
case PW_TYPE_EXTENDED:
case PW_TYPE_LONG_EXTENDED:
Expand Down
3 changes: 2 additions & 1 deletion src/main/client.c
Expand Up @@ -426,7 +426,8 @@ static CONF_PARSER limit_config[] = {
#endif

static const CONF_PARSER client_config[] = {
{ "ipaddr", FR_CONF_POINTER(PW_TYPE_IPV4PREFIX, &cl_ipaddr), NULL },
{ "ipaddr", FR_CONF_POINTER(PW_TYPE_COMBO_IPPREFIX, &cl_ipaddr), NULL },
{ "ipv4addr", FR_CONF_POINTER(PW_TYPE_IPV4PREFIX, &cl_ipaddr), NULL },
{ "ipv6addr", FR_CONF_POINTER(PW_TYPE_IPV6PREFIX, &cl_ipaddr), NULL },
{ "netmask", FR_CONF_POINTER(PW_TYPE_INTEGER, &cl_prefix), NULL },

Expand Down
101 changes: 59 additions & 42 deletions src/main/conffile.c
Expand Up @@ -903,6 +903,53 @@ static char const *cf_expand_variables(char const *cf, int *lineno,

static char const *parse_spaces = " ";

/** Validation function for ipaddr conffile types
*
*/
static inline int fr_item_validate_ipaddr(CONF_SECTION *cs, char const *name, PW_TYPE type, char const *value,
fr_ipaddr_t *ipaddr)
{
char ipbuf[128];

if (strcmp(value, "*") == 0) {
cf_log_info(cs, "%.*s\t%s = *", cs->depth, parse_spaces, name);
} else if (strspn(value, ".0123456789abdefABCDEF:%[]/") == strlen(value)) {
cf_log_info(cs, "%.*s\t%s = %s", cs->depth, parse_spaces, name, value);
} else {
cf_log_info(cs, "%.*s\t%s = %s IPv%s address [%s]", cs->depth, parse_spaces, name, value,
(ipaddr->af == AF_INET ? "4" : " 6"), ip_ntoh(ipaddr, ipbuf, sizeof(ipbuf)));
}

switch (type) {
case PW_TYPE_IPADDR:
case PW_TYPE_IPV6ADDR:
case PW_TYPE_COMBO_IP:
switch (ipaddr->af) {
case AF_INET:
if (ipaddr->prefix != 32) {
ERROR("Invalid IPv4 mask length \"/%i\". Only \"/32\" permitted for non-prefix types",
ipaddr->prefix);

return -1;
}
break;

case AF_INET6:
if (ipaddr->prefix != 128) {
ERROR("Invalid IPv6 mask length \"/%i\". Only \"/128\" permitted for non-prefix types",
ipaddr->prefix);

return -1;
}
break;

default:
return -1;
}
default:
return 0;
}
}

/*
* Parses an item (not a CONF_ITEM) into the specified format,
Expand All @@ -919,6 +966,7 @@ int cf_item_parse(CONF_SECTION *cs, char const *name, int type, void *data, char
char **q;
char const *value;
CONF_PAIR const *cp = NULL;
fr_ipaddr_t *ipaddr;
char buffer[8192];

if (!cs) return -1;
Expand Down Expand Up @@ -1138,66 +1186,35 @@ int cf_item_parse(CONF_SECTION *cs, char const *name, int type, void *data, char

case PW_TYPE_IPADDR:
case PW_TYPE_IPV4PREFIX:
{
fr_ipaddr_t *ipaddr = data;
char ipbuf[128];
ipaddr = data;

if (fr_pton4(ipaddr, value, 0, true, false) < 0) {
ERROR("%s", fr_strerror());
return -1;
}

/*
* Debug format depends on format of input string
*/
if (strcmp(value, "*") == 0) {
cf_log_info(cs, "%.*s\t%s = *", cs->depth, parse_spaces, name);
} else if ((strspn(value, "0123456789./") == strlen(value)) ||
(strspn(value, "0123456789xabcdefABCDEF/") == strlen(value))) {
cf_log_info(cs, "%.*s\t%s = %s", cs->depth, parse_spaces, name, value);
} else {
cf_log_info(cs, "%.*s\t%s = %s IP address [%s]",
cs->depth, parse_spaces, name, value, ip_ntoh(ipaddr, ipbuf, sizeof(ipbuf)));
}

if ((type == PW_TYPE_IPADDR) && (ipaddr->prefix != 32)) {
ERROR("Invalid IPv4 mask length \"/%i\". Only \"/32\" permitted for non-prefix types",
ipaddr->prefix);
return -1;
}
}
if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
break;

case PW_TYPE_IPV6ADDR:
case PW_TYPE_IPV6PREFIX:
{
fr_ipaddr_t *ipaddr = data;
char ipbuf[128];
ipaddr = data;

if (fr_pton6(ipaddr, value, 0, true, false) < 0) {
ERROR("%s", fr_strerror());
return -1;
}
if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
break;

/*
* Debug format depends on format of input string
*/
if (strcmp(value, "*") == 0) {
cf_log_info(cs, "%.*s\t%s = *", cs->depth, parse_spaces, name);
} else if (strspn(value, "0123456789abdefABCDEF:%[]/") == strlen(value)) {
cf_log_info(cs, "%.*s\t%s = %s", cs->depth, parse_spaces, name, value);
} else {
cf_log_info(cs, "%.*s\t%s = %s IPv6 address [%s]", cs->depth, parse_spaces, name, value,
ip_ntoh(ipaddr, ipbuf, sizeof(ipbuf)));
}
case PW_TYPE_COMBO_IP:
case PW_TYPE_COMBO_IPPREFIX:
ipaddr = data;

if ((type == PW_TYPE_IPV6ADDR) && (ipaddr->prefix != 128)) {
ERROR("Invalid IPv6 mask length \"/%i\". Only \"/128\" permitted "
"for non-prefix types", ipaddr->prefix);
if (fr_pton(ipaddr, value, 0, true) < 0) {
ERROR("%s", fr_strerror());
return -1;
}
}

if (fr_item_validate_ipaddr(cs, name, type, value, ipaddr) < 0) return -1;
break;

case PW_TYPE_TIMEVAL: {
Expand Down

0 comments on commit 3ba4a62

Please sign in to comment.