From 2937c0dd20f2f3c0065b671bbfe3fafcd8862eaf Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 26 Jan 2010 17:36:17 +0100 Subject: [PATCH] [MINOR] standard: str2mask: string to netmask converter This function converts a dotted or CIDR value to a netmask. --- include/common/standard.h | 6 ++++++ src/standard.c | 41 +++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/include/common/standard.h b/include/common/standard.h index b19f0ccd9f..fcac72fd59 100644 --- a/include/common/standard.h +++ b/include/common/standard.h @@ -162,6 +162,12 @@ struct sockaddr_in *str2sa(char *str); */ struct sockaddr_in *str2sa_range(char *str, int *low, int *high); +/* converts to a struct in_addr containing a network mask. It can be + * passed in dotted form (255.255.255.0) or in CIDR form (24). It returns 1 + * if the conversion succeeds otherwise non-zero. + */ +int str2mask(const char *str, struct in_addr *mask); + /* * converts to two struct in_addr* which must be pre-allocated. * The format is "addr[/mask]", where "addr" cannot be empty, and mask diff --git a/src/standard.c b/src/standard.c index f841c6dcda..e9be0f97f5 100644 --- a/src/standard.c +++ b/src/standard.c @@ -315,6 +315,30 @@ struct sockaddr_in *str2sa_range(char *str, int *low, int *high) return &sa; } +/* converts to a struct in_addr containing a network mask. It can be + * passed in dotted form (255.255.255.0) or in CIDR form (24). It returns 1 + * if the conversion succeeds otherwise non-zero. + */ +int str2mask(const char *str, struct in_addr *mask) +{ + if (strchr(str, '.') != NULL) { /* dotted notation */ + if (!inet_pton(AF_INET, str, mask)) + return 0; + } + else { /* mask length */ + char *err; + unsigned long len = strtol(str, &err, 10); + + if (!*str || (err && *err) || (unsigned)len > 32) + return 0; + if (len) + mask->s_addr = htonl(~0UL << (32 - len)); + else + mask->s_addr = 0; + } + return 1; +} + /* * converts to two struct in_addr* which must be pre-allocated. * The format is "addr[/mask]", where "addr" cannot be empty, and mask @@ -326,7 +350,6 @@ int str2net(const char *str, struct in_addr *addr, struct in_addr *mask) __label__ out_free, out_err; char *c, *s; int ret_val; - unsigned long len; s = strdup(str); if (!s) @@ -338,20 +361,8 @@ int str2net(const char *str, struct in_addr *addr, struct in_addr *mask) if ((c = strrchr(s, '/')) != NULL) { *c++ = '\0'; /* c points to the mask */ - if (strchr(c, '.') != NULL) { /* dotted notation */ - if (!inet_pton(AF_INET, c, mask)) - goto out_err; - } - else { /* mask length */ - char *err; - len = strtol(c, &err, 10); - if (!*c || (err && *err) || (unsigned)len > 32) - goto out_err; - if (len) - mask->s_addr = htonl(~0UL << (32 - len)); - else - mask->s_addr = 0; - } + if (!str2mask(c, mask)) + goto out_err; } else { mask->s_addr = ~0U;