Module: sip-router
Branch: master
Commit: dc4cdb294cc135a01032dd613d79bfe625351612
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=dc4cdb2…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Date: Fri Jun 18 22:03:46 2010 +0200
core: functions for parsing a network address
- added mk_net_str(): initialize a struct net from a string of the
form ip/mask, ip/bitlen or ip
- renamed mk_net() and mk_net_bitlen() to mk_new_net() and
mk_new_net_bitlen()
---
cfg.y | 10 ++--
ip_addr.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
ip_addr.h | 7 ++-
3 files changed, 142 insertions(+), 15 deletions(-)
diff --git a/cfg.y b/cfg.y
index ae214f2..f2b71a5 100644
--- a/cfg.y
+++ b/cfg.y
@@ -2073,7 +2073,7 @@ exp_elem:
pkg_free(s_tmp.s);
if (ip_tmp) {
$$=mk_elem($2, $1, 0, NET_ST,
- mk_net_bitlen(ip_tmp, ip_tmp->len*8) );
+ mk_new_net_bitlen(ip_tmp, ip_tmp->len*8) );
} else {
$$=mk_elem($2, $1, 0, RVE_ST, $3);
}
@@ -2113,19 +2113,19 @@ exp_elem2:
*/
ipnet:
- ip SLASH ip { $$=mk_net($1, $3); }
+ ip SLASH ip { $$=mk_new_net($1, $3); }
| ip SLASH NUMBER {
if (($3<0) || ($3>$1->len*8)) {
yyerror("invalid bit number in netmask");
$$=0;
} else {
- $$=mk_net_bitlen($1, $3);
+ $$=mk_new_net_bitlen($1, $3);
/*
- $$=mk_net($1, htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
+ $$=mk_new_net($1, htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
*/
}
}
- | ip { $$=mk_net_bitlen($1, $1->len*8); }
+ | ip { $$=mk_new_net_bitlen($1, $1->len*8); }
| ip SLASH error { $$=0; yyerror("netmask (eg:255.0.0.0 or 8) expected"); }
;
diff --git a/ip_addr.c b/ip_addr.c
index 06a5bf2..5651809 100644
--- a/ip_addr.c
+++ b/ip_addr.c
@@ -34,11 +34,10 @@
* 2004-10-01 mk_net fixes bad network addresses now (andrei)
*/
-/*!
- * \file
- * \brief SIP-router core ::
- * \ingroup core
- * Module: \ref core
+/** inernal ip addresses representation functions.
+ * @file ip_addr.c
+ * @ingroup core
+ * Module: @ref core
*/
@@ -48,9 +47,11 @@
#include "ip_addr.h"
#include "dprint.h"
#include "mem/mem.h"
+#include "resolve.h"
+#include "trim.h"
-struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask)
+struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask)
{
struct net* n;
int warning;
@@ -88,7 +89,7 @@ error:
-struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
+struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
{
struct ip_addr mask;
int r;
@@ -103,13 +104,136 @@ struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
mask.af=ip->af;
mask.len=ip->len;
- return mk_net(ip, &mask);
+ return mk_new_net(ip, &mask);
error:
return 0;
}
+/** fills a net structure from an ip and a mask.
+ *
+ * This function will not print any error messages or allocate
+ * memory (as opposed to mk_new_net() above).
+ *
+ * @param n - destination net structure
+ * @param ip
+ * @param mask
+ * @return -1 on error (af mismatch), 0 on success
+ */
+int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask)
+{
+ int r;
+
+ if (unlikely((ip->af != mask->af) || (ip->len != mask->len))) {
+ return -1;
+ }
+ n->ip=*ip;
+ n->mask=*mask;
+ /* fix the network part of the mask */
+ for (r=0; r<n->ip.len/4; r++) { /*ipv4 & ipv6 addresses are multiple of 4*/
+ n->ip.u.addr32[r] &= n->mask.u.addr32[r];
+ };
+ return 0;
+}
+
+
+
+/** 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);
+}
+
+
+
+/** 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);
+#ifdef USE_IPV6
+ if (unlikely(t == 0))
+ t = str2ip6(s);
+#endif /* USE_IPV6 */
+ 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;
+ }
+#ifdef USE_IPV6
+ 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;
+ }
+ }
+#endif /* USE_IPV6 */
+ }
+ return -1;
+}
+
+
+
void print_ip(char* p, struct ip_addr* ip, char *s)
{
switch(ip->af){
diff --git a/ip_addr.h b/ip_addr.h
index fd19c42..50fbf58 100644
--- a/ip_addr.h
+++ b/ip_addr.h
@@ -240,8 +240,11 @@ struct socket_id{
-struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask);
-struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
+struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask);
+struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
+int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask);
+int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen);
+int mk_net_str(struct net* dst, str* s);
void print_ip(char* prefix, struct ip_addr* ip, char* suffix);
void stdout_print_ip(struct ip_addr* ip);