/** initializes a net structure from a string. * @param dst - net structure that will be filled * @param s - string of the form "ip", "ip/mask_len" or "ip/ip_mak". * @return -1 on error, 0 on succes */ int mk_net_str(struct net* dst, str* s) { struct ip_addr* t; char* p; struct ip_addr ip; str addr; str mask; unsigned int bitlen; /* test for ip only */ t = str2ip(s); if (unlikely(t == 0)) t = str2ip6(s); if (likely(t)) return mk_net_bitlen(dst, t, t->len*8); /* not a simple ip, maybe an ip/netmask pair */ p = q_memchr(s->s, '/', s->len); if (likely(p)) { addr.s = s->s; addr.len = (int)(long)(p - s->s); mask.s = p + 1; mask.len = s->len - (addr.len + 1); /* allow '/' enclosed by whitespace */ trim_trailing(&addr); trim_leading(&mask); t = str2ip(&addr); if (likely(t)) { /* it can be a number */ if (str2int(&mask, &bitlen) == 0) return mk_net_bitlen(dst, t, bitlen); ip = *t; t = str2ip(&mask); if (likely(t)) return mk_net(dst, &ip, t); /* error */ return -1; } else { t = str2ip6(&addr); if (likely(t)) { /* it can be a number */ if (str2int(&mask, &bitlen) == 0) return mk_net_bitlen(dst, t, bitlen); ip = *t; t = str2ip6(&mask); if (likely(t)) return mk_net(dst, &ip, t); /* error */ return -1; } } } return -1; }
/** fills a net structure from an ip and a bitlen. * * This function will not print any error messages or allocate * memory (as opposed to mk_new_net_bitlen() above). * * @param n - destination net structure * @param ip * @param bitlen * @return -1 on error (af mismatch), 0 on success */ int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen) { struct ip_addr mask; int r; if (unlikely(bitlen>ip->len*8)) /* bitlen too big */ return -1; memset(&mask,0, sizeof(mask)); for (r=0;r<bitlen/8;r++) mask.u.addr[r]=0xff; if (bitlen%8) mask.u.addr[r]= ~((1<<(8-(bitlen%8)))-1); mask.af=ip->af; mask.len=ip->len; return mk_net(n, ip, &mask); }
struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen) { struct ip_addr mask; unsigned int r; if (bitlen>ip->len*8){ LM_CRIT("bad bitlen number %d\n", bitlen); goto error; } memset(&mask,0, sizeof(mask)); for (r=0;r<bitlen/8;r++) mask.u.addr[r]=0xff; if (bitlen%8) mask.u.addr[r]= ~((1<<(8-(bitlen%8)))-1); mask.af=ip->af; mask.len=ip->len; return mk_net(ip, &mask); error: return 0; }