int addr_pton_cidr(const char* p, struct xaddr* n, int* l) { struct xaddr tmp; int masklen = -1; char addrbuf[64]; char* mp; char* cp; /* Don't modify argument */ if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) >= sizeof(addrbuf)) return (-1); if ((mp = strchr(addrbuf, '/')) != NULL) { *mp = '\0'; mp++; masklen = (int) strtol(mp, &cp, 10); if (*mp == '\0' || *cp != '\0' || masklen > 128) return (-1); } if (addr_pton(addrbuf, &tmp) == -1) return (-1); if (mp == NULL) masklen = addr_unicast_masklen(tmp.af); if (addr_masklen_valid(tmp.af, masklen) == -1) return (-1); if (n != NULL) rte_memcpy(n, &tmp, sizeof(*n)); if (l != NULL) *l = masklen; return (0); }
/* * Parse a CIDR address (x.x.x.x/y or xxxx:yyyy::/z). * Return -1 on parse error, -2 on inconsistency or 0 on success. */ static int addr_pton_cidr(const char *p, struct xaddr *n, u_int *l) { struct xaddr tmp; long unsigned int masklen = 999; char addrbuf[64], *mp, *cp; /* Don't modify argument */ if (p == NULL || strlcpy(addrbuf, p, sizeof(addrbuf)) > sizeof(addrbuf)) return -1; if ((mp = strchr(addrbuf, '/')) != NULL) { *mp = '\0'; mp++; masklen = strtoul(mp, &cp, 10); if (*mp == '\0' || *cp != '\0' || masklen > 128) return -1; } if (addr_pton(addrbuf, &tmp) == -1) return -1; if (mp == NULL) masklen = addr_unicast_masklen(tmp.af); if (masklen_valid(tmp.af, masklen) == -1) return -2; if (addr_host_is_all0s(&tmp, masklen) != 0) return -2; if (n != NULL) memcpy(n, &tmp, sizeof(*n)); if (l != NULL) *l = masklen; return 0; }