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 48
 #include "ip_addr.h"
49 49
 #include "dprint.h"
50 50
 #include "mem/mem.h"
51
+#include "resolve.h"
52
+#include "trim.h"
51 53
 
52 54
 
53
-struct net* mk_net(struct ip_addr* ip, struct ip_addr* mask)
55
+struct net* mk_new_net(struct ip_addr* ip, struct ip_addr* mask)
54 56
 {
55 57
 	struct net* n;
56 58
 	int warning;
... ...
@@ -88,7 +89,7 @@ error:
88 88
 
89 89
 
90 90
 
91
-struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
91
+struct net* mk_new_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
92 92
 {
93 93
 	struct ip_addr mask;
94 94
 	int r;
... ...
@@ -103,13 +104,136 @@ struct net* mk_net_bitlen(struct ip_addr* ip, unsigned int bitlen)
103 103
 	mask.af=ip->af;
104 104
 	mask.len=ip->len;
105 105
 	
106
-	return mk_net(ip, &mask);
106
+	return mk_new_net(ip, &mask);
107 107
 error:
108 108
 	return 0;
109 109
 }
110 110
 
111 111
 
112 112
 
113
+/** fills a net structure from an ip and a mask.
114
+ *
115
+ * This function will not print any error messages or allocate
116
+ * memory (as opposed to mk_new_net() above).
117
+ *
118
+ * @param n - destination net structure
119
+ * @param ip
120
+ * @param mask
121
+ * @return -1 on error (af mismatch), 0 on success
122
+ */
123
+int mk_net(struct net* n, struct ip_addr* ip, struct ip_addr* mask)
124
+{
125
+	int r;
126
+	
127
+	if (unlikely((ip->af != mask->af) || (ip->len != mask->len))) {
128
+		return -1;
129
+	}
130
+	n->ip=*ip;
131
+	n->mask=*mask;
132
+	/* fix the network part of the mask */
133
+	for (r=0; r<n->ip.len/4; r++) { /*ipv4 & ipv6 addresses are multiple of 4*/
134
+		n->ip.u.addr32[r] &= n->mask.u.addr32[r];
135
+	};
136
+	return 0;
137
+}
138
+
139
+
140
+
141
+/** fills a net structure from an ip and a bitlen.
142
+ *
143
+ * This function will not print any error messages or allocate
144
+ * memory (as opposed to mk_new_net_bitlen() above).
145
+ *
146
+ * @param n - destination net structure
147
+ * @param ip
148
+ * @param bitlen
149
+ * @return -1 on error (af mismatch), 0 on success
150
+ */
151
+int mk_net_bitlen(struct net* n, struct ip_addr* ip, unsigned int bitlen)
152
+{
153
+	struct ip_addr mask;
154
+	int r;
155
+	
156
+	if (unlikely(bitlen>ip->len*8))
157
+		/* bitlen too big */
158
+		return -1;
159
+	memset(&mask,0, sizeof(mask));
160
+	for (r=0;r<bitlen/8;r++) mask.u.addr[r]=0xff;
161
+	if (bitlen%8) mask.u.addr[r]=  ~((1<<(8-(bitlen%8)))-1);
162
+	mask.af=ip->af;
163
+	mask.len=ip->len;
164
+	
165
+	return mk_net(n, ip, &mask);
166
+}
167
+
168
+
169
+
170
+/** initializes a net structure from a string.
171
+ * @param dst - net structure that will be filled
172
+ * @param s - string of the form "ip", "ip/mask_len" or "ip/ip_mak".
173
+ * @return -1 on error, 0 on succes
174
+ */
175
+int mk_net_str(struct net* dst, str* s)
176
+{
177
+	struct ip_addr* t;
178
+	char* p;
179
+	struct ip_addr ip;
180
+	str addr;
181
+	str mask;
182
+	unsigned int bitlen;
183
+	
184
+	/* test for ip only */
185
+	t = str2ip(s);
186
+#ifdef USE_IPV6
187
+	if (unlikely(t == 0))
188
+		t = str2ip6(s);
189
+#endif /* USE_IPV6 */
190
+	if (likely(t))
191
+		return mk_net_bitlen(dst, t, t->len*8);
192
+	/* not a simple ip, maybe an ip/netmask pair */
193
+	p = q_memchr(s->s, '/', s->len);
194
+	if (likely(p)) {
195
+		addr.s = s->s;
196
+		addr.len = (int)(long)(p - s->s);
197
+		mask.s = p + 1;
198
+		mask.len = s->len - (addr.len + 1);
199
+		/* allow '/' enclosed by whitespace */
200
+		trim_trailing(&addr);
201
+		trim_leading(&mask);
202
+		t = str2ip(&addr);
203
+		if (likely(t)) {
204
+			/* it can be a number */
205
+			if (str2int(&mask, &bitlen) == 0)
206
+				return mk_net_bitlen(dst, t, bitlen);
207
+			ip = *t;
208
+			t = str2ip(&mask);
209
+			if (likely(t))
210
+				return mk_net(dst, &ip, t);
211
+			/* error */
212
+			return -1;
213
+		}
214
+#ifdef USE_IPV6
215
+		else {
216
+			t = str2ip6(&addr);
217
+			if (likely(t)) {
218
+				/* it can be a number */
219
+				if (str2int(&mask, &bitlen) == 0)
220
+					return mk_net_bitlen(dst, t, bitlen);
221
+				ip = *t;
222
+				t = str2ip6(&mask);
223
+				if (likely(t))
224
+					return mk_net(dst, &ip, t);
225
+				/* error */
226
+				return -1;
227
+			}
228
+		}
229
+#endif /* USE_IPV6 */
230
+	}
231
+	return -1;
232
+}
233
+
234
+
235
+
113 236
 void print_ip(char* p, struct ip_addr* ip, char *s)
114 237
 {
115 238
 	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);