Browse code

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()

Andrei Pelinescu-Onciul authored on 18/06/2010 20:03:46
Showing 3 changed files
... ...
@@ -2073,7 +2073,7 @@ exp_elem:
2073 2073
 				pkg_free(s_tmp.s);
2074 2074
 				if (ip_tmp) {
2075 2075
 					$$=mk_elem($2, $1, 0, NET_ST, 
2076
-								mk_net_bitlen(ip_tmp, ip_tmp->len*8) );
2076
+								mk_new_net_bitlen(ip_tmp, ip_tmp->len*8) );
2077 2077
 				} else {
2078 2078
 					$$=mk_elem($2, $1, 0, RVE_ST, $3);
2079 2079
 				}
... ...
@@ -2113,19 +2113,19 @@ exp_elem2:
2113 2113
 */
2114 2114
 
2115 2115
 ipnet:
2116
-	ip SLASH ip	{ $$=mk_net($1, $3); }
2116
+	ip SLASH ip	{ $$=mk_new_net($1, $3); }
2117 2117
 	| ip SLASH NUMBER {
2118 2118
 		if (($3<0) || ($3>$1->len*8)) {
2119 2119
 			yyerror("invalid bit number in netmask");
2120 2120
 			$$=0;
2121 2121
 		} else {
2122
-			$$=mk_net_bitlen($1, $3);
2122
+			$$=mk_new_net_bitlen($1, $3);
2123 2123
 		/*
2124
-			$$=mk_net($1, htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
2124
+			$$=mk_new_net($1, htonl( ($3)?~( (1<<(32-$3))-1 ):0 ) );
2125 2125
 		*/
2126 2126
 		}
2127 2127
 	}
2128
-	| ip	{ $$=mk_net_bitlen($1, $1->len*8); }
2128
+	| ip	{ $$=mk_new_net_bitlen($1, $1->len*8); }
2129 2129
 	| ip SLASH error { $$=0; yyerror("netmask (eg:255.0.0.0 or 8) expected"); }
2130 2130
 	;
2131 2131
 
... ...
@@ -34,11 +34,10 @@
34 34
  *  2004-10-01  mk_net fixes bad network addresses now (andrei)
35 35
  */
36 36
 
37
-/*!
38
- * \file
39
- * \brief SIP-router core :: 
40
- * \ingroup core
41
- * Module: \ref core
37
+/** inernal ip addresses representation functions.
38
+ * @file ip_addr.c
39
+ * @ingroup core
40
+ * Module: @ref core
42 41
  */
43 42
 
44 43
 
... ...
@@ -48,9 +47,11 @@
48 47
 #include "ip_addr.h"
49 48
 #include "dprint.h"
50 49
 #include "mem/mem.h"
50
+#include "resolve.h"
51
+#include "trim.h"
51 52
 
52 53
 
53
-struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask)
54
+struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask)
54 55
 {
55 56
 	struct net* n;
56 57
 	int warning;
... ...
@@ -88,7 +89,7 @@ error:
88 89
 
89 90
 
90 91
 
91
-struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
92
+struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
92 93
 {
93 94
 	struct ip_addr mask;
94 95
 	int r;
... ...
@@ -103,13 +104,136 @@ struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
103 104
 	mask.af=ip->af;
104 105
 	mask.len=ip->len;
105 106
 	
106
-	return mk_net(ip, &mask);
107
+	return mk_new_net(ip, &mask);
107 108
 error:
108 109
 	return 0;
109 110
 }
110 111
 
111 112
 
112 113
 
114
+/** fills a net structure from an ip and a mask.
115
+ *
116
+ * This function will not print any error messages or allocate
117
+ * memory (as opposed to mk_new_net() above).
118
+ *
119
+ * @param n - destination net structure
120
+ * @param ip
121
+ * @param mask
122
+ * @return -1 on error (af mismatch), 0 on success
123
+ */
124
+int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask)
125
+{
126
+	int r;
127
+	
128
+	if (unlikely((ip->af != mask->af) || (ip->len != mask->len))) {
129
+		return -1;
130
+	}
131
+	n->ip=*ip;
132
+	n->mask=*mask;
133
+	/* fix the network part of the mask */
134
+	for (r=0; r<n->ip.len/4; r++) { /*ipv4 & ipv6 addresses are multiple of 4*/
135
+		n->ip.u.addr32[r] &= n->mask.u.addr32[r];
136
+	};
137
+	return 0;
138
+}
139
+
140
+
141
+
142
+/** fills a net structure from an ip and a bitlen.
143
+ *
144
+ * This function will not print any error messages or allocate
145
+ * memory (as opposed to mk_new_net_bitlen() above).
146
+ *
147
+ * @param n - destination net structure
148
+ * @param ip
149
+ * @param bitlen
150
+ * @return -1 on error (af mismatch), 0 on success
151
+ */
152
+int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen)
153
+{
154
+	struct ip_addr mask;
155
+	int r;
156
+	
157
+	if (unlikely(bitlen>ip->len*8))
158
+		/* bitlen too big */
159
+		return -1;
160
+	memset(&mask,0, sizeof(mask));
161
+	for (r=0;r<bitlen/8;r++) mask.u.addr[r]=0xff;
162
+	if (bitlen%8) mask.u.addr[r]=  ~((1<<(8-(bitlen%8)))-1);
163
+	mask.af=ip->af;
164
+	mask.len=ip->len;
165
+	
166
+	return mk_net(n, ip, &mask);
167
+}
168
+
169
+
170
+
171
+/** initializes a net structure from a string.
172
+ * @param dst - net structure that will be filled
173
+ * @param s - string of the form "ip", "ip/mask_len" or "ip/ip_mak".
174
+ * @return -1 on error, 0 on succes
175
+ */
176
+int mk_net_str(struct net* dst, str* s)
177
+{
178
+	struct ip_addr* t;
179
+	char* p;
180
+	struct ip_addr ip;
181
+	str addr;
182
+	str mask;
183
+	unsigned int bitlen;
184
+	
185
+	/* test for ip only */
186
+	t = str2ip(s);
187
+#ifdef USE_IPV6
188
+	if (unlikely(t == 0))
189
+		t = str2ip6(s);
190
+#endif /* USE_IPV6 */
191
+	if (likely(t))
192
+		return mk_net_bitlen(dst, t, t->len*8);
193
+	/* not a simple ip, maybe an ip/netmask pair */
194
+	p = q_memchr(s->s, '/', s->len);
195
+	if (likely(p)) {
196
+		addr.s = s->s;
197
+		addr.len = (int)(long)(p - s->s);
198
+		mask.s = p + 1;
199
+		mask.len = s->len - (addr.len + 1);
200
+		/* allow '/' enclosed by whitespace */
201
+		trim_trailing(&addr);
202
+		trim_leading(&mask);
203
+		t = str2ip(&addr);
204
+		if (likely(t)) {
205
+			/* it can be a number */
206
+			if (str2int(&mask, &bitlen) == 0)
207
+				return mk_net_bitlen(dst, t, bitlen);
208
+			ip = *t;
209
+			t = str2ip(&mask);
210
+			if (likely(t))
211
+				return mk_net(dst, &ip, t);
212
+			/* error */
213
+			return -1;
214
+		}
215
+#ifdef USE_IPV6
216
+		else {
217
+			t = str2ip6(&addr);
218
+			if (likely(t)) {
219
+				/* it can be a number */
220
+				if (str2int(&mask, &bitlen) == 0)
221
+					return mk_net_bitlen(dst, t, bitlen);
222
+				ip = *t;
223
+				t = str2ip6(&mask);
224
+				if (likely(t))
225
+					return mk_net(dst, &ip, t);
226
+				/* error */
227
+				return -1;
228
+			}
229
+		}
230
+#endif /* USE_IPV6 */
231
+	}
232
+	return -1;
233
+}
234
+
235
+
236
+
113 237
 void print_ip(char* p, struct ip_addr* ip, char *s)
114 238
 {
115 239
 	switch(ip->af){
... ...
@@ -240,8 +240,11 @@ struct socket_id{
240 240
 
241 241
 
242 242
 
243
-struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask);
244
-struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
243
+struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask);
244
+struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen);
245
+int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask);
246
+int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen);
247
+int mk_net_str(struct net* dst, str* s);
245 248
 
246 249
 void print_ip(char* prefix, struct ip_addr* ip, char* suffix);
247 250
 void stdout_print_ip(struct ip_addr* ip);