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); }
int addr_netmask(int af, u_int l, struct xaddr* n) { int i; if (addr_masklen_valid(af, l) != 0 || n == NULL) return (-1); memset(n, '\0', sizeof(*n)); switch (af) { case AF_INET: n->af = AF_INET; n->v4.s_addr = (l == 32) ? 0xffffffffUL : htonl(~(0xffffffffUL >> l)); return (0); case AF_INET6: n->af = AF_INET6; for (i = 0; i < 4 && l >= 32; i++, l -= 32) n->addr32[i] = 0xffffffffU; if (i < 4 && l != 0) n->addr32[i] = htonl(~(0xffffffffU >> l)); return (0); default: return (-1); } }