Module: sip-router
Branch: master
Commit: dc4cdb294cc135a01032dd613d79bfe625351612
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=dc4cdb294cc135a01032dd613d79bfe625351612

Author: Andrei Pelinescu-Onciul <[email protected]>
Committer: Andrei Pelinescu-Onciul <[email protected]>
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);


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to