diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2008-10-21 12:42:45 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2008-10-21 12:42:45 +0000 |
commit | 8fbd8ac8ddad83f7ea724f12a1f5e6bf4af50f88 (patch) | |
tree | 161401339554a4326c5ad2fe8f75b8b442e29b6a | |
parent | 7effd7ae99b2288452762f29cde8311ec72c2cb8 (diff) | |
download | busybox-w32-8fbd8ac8ddad83f7ea724f12a1f5e6bf4af50f88.tar.gz busybox-w32-8fbd8ac8ddad83f7ea724f12a1f5e6bf4af50f88.tar.bz2 busybox-w32-8fbd8ac8ddad83f7ea724f12a1f5e6bf4af50f88.zip |
- fix ip route rejecting dotted quads as prefix
- adjust error message for wrong prefix not to mention address
Previously e.g. ip route add 127.0.0.0/255.0.0.0 dev dummy0
was rejected, saying
ip: an inet address is expected rather than "127.0.0.0/255.0.0.0"
function old new delta
get_prefix_1 201 309 +108
get_prefix 55 73 +18
get_addr 55 73 +18
get_addr32 48 58 +10
get_addr_1 249 204 -45
.rodata 114569 114524 -45
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/2 up/down: 154/-90) Total: 64 bytes
-rw-r--r-- | networking/libiproute/utils.c | 64 | ||||
-rw-r--r-- | networking/libiproute/utils.h | 2 |
2 files changed, 35 insertions, 31 deletions
diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index 706710e1f..cd101f176 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c | |||
@@ -115,10 +115,6 @@ int get_s8(int8_t * val, char *arg, int base) | |||
115 | 115 | ||
116 | int get_addr_1(inet_prefix * addr, char *name, int family) | 116 | int get_addr_1(inet_prefix * addr, char *name, int family) |
117 | { | 117 | { |
118 | char *cp; | ||
119 | unsigned char *ap = (unsigned char *) addr->data; | ||
120 | int i; | ||
121 | |||
122 | memset(addr, 0, sizeof(*addr)); | 118 | memset(addr, 0, sizeof(*addr)); |
123 | 119 | ||
124 | if (strcmp(name, bb_str_default) == 0 || | 120 | if (strcmp(name, bb_str_default) == 0 || |
@@ -143,24 +139,17 @@ int get_addr_1(inet_prefix * addr, char *name, int family) | |||
143 | addr->family = AF_INET; | 139 | addr->family = AF_INET; |
144 | if (family != AF_UNSPEC && family != AF_INET) | 140 | if (family != AF_UNSPEC && family != AF_INET) |
145 | return -1; | 141 | return -1; |
142 | if (inet_pton(AF_INET, name, addr->data) <= 0) | ||
143 | return -1; | ||
146 | addr->bytelen = 4; | 144 | addr->bytelen = 4; |
147 | addr->bitlen = -1; | 145 | addr->bitlen = -1; |
148 | for (cp = name, i = 0; *cp; cp++) { | ||
149 | if (*cp <= '9' && *cp >= '0') { | ||
150 | ap[i] = 10 * ap[i] + (*cp - '0'); | ||
151 | continue; | ||
152 | } | ||
153 | if (*cp == '.' && ++i <= 3) | ||
154 | continue; | ||
155 | return -1; | ||
156 | } | ||
157 | return 0; | 146 | return 0; |
158 | } | 147 | } |
159 | 148 | ||
160 | int get_prefix_1(inet_prefix * dst, char *arg, int family) | 149 | int get_prefix_1(inet_prefix * dst, char *arg, int family) |
161 | { | 150 | { |
162 | int err; | 151 | int err; |
163 | int plen; | 152 | unsigned plen; |
164 | char *slash; | 153 | char *slash; |
165 | 154 | ||
166 | memset(dst, 0, sizeof(*dst)); | 155 | memset(dst, 0, sizeof(*dst)); |
@@ -177,23 +166,36 @@ int get_prefix_1(inet_prefix * dst, char *arg, int family) | |||
177 | *slash = '\0'; | 166 | *slash = '\0'; |
178 | err = get_addr_1(dst, arg, family); | 167 | err = get_addr_1(dst, arg, family); |
179 | if (err == 0) { | 168 | if (err == 0) { |
180 | switch (dst->family) { | 169 | dst->bitlen = (dst->family == AF_INET6) ? 128 : 32; |
181 | case AF_INET6: | ||
182 | dst->bitlen = 128; | ||
183 | break; | ||
184 | default: | ||
185 | case AF_INET: | ||
186 | dst->bitlen = 32; | ||
187 | } | ||
188 | if (slash) { | 170 | if (slash) { |
189 | if (get_integer(&plen, slash + 1, 0) || plen > dst->bitlen) { | 171 | inet_prefix netmask_pfx; |
172 | |||
173 | netmask_pfx.family = AF_UNSPEC; | ||
174 | if ((get_unsigned(&plen, slash + 1, 0) || plen > dst->bitlen) | ||
175 | && (get_addr_1(&netmask_pfx, slash + 1, family))) | ||
190 | err = -1; | 176 | err = -1; |
191 | goto done; | 177 | else if (netmask_pfx.family == AF_INET) { |
178 | /* fill in prefix length of dotted quad */ | ||
179 | uint32_t mask = ntohl(netmask_pfx.data[0]); | ||
180 | uint32_t host = ~mask; | ||
181 | |||
182 | /* a valid netmask must be 2^n - 1 */ | ||
183 | if (!(host & (host + 1))) { | ||
184 | for (plen = 0; mask; mask <<= 1) | ||
185 | ++plen; | ||
186 | if (plen >= 0 && plen <= dst->bitlen) { | ||
187 | dst->bitlen = plen; | ||
188 | /* dst->flags |= PREFIXLEN_SPECIFIED; */ | ||
189 | } else | ||
190 | err = -1; | ||
191 | } else | ||
192 | err = -1; | ||
193 | } else { | ||
194 | /* plain prefix */ | ||
195 | dst->bitlen = plen; | ||
192 | } | 196 | } |
193 | dst->bitlen = plen; | ||
194 | } | 197 | } |
195 | } | 198 | } |
196 | done: | ||
197 | if (slash) | 199 | if (slash) |
198 | *slash = '/'; | 200 | *slash = '/'; |
199 | return err; | 201 | return err; |
@@ -202,10 +204,10 @@ int get_prefix_1(inet_prefix * dst, char *arg, int family) | |||
202 | int get_addr(inet_prefix * dst, char *arg, int family) | 204 | int get_addr(inet_prefix * dst, char *arg, int family) |
203 | { | 205 | { |
204 | if (family == AF_PACKET) { | 206 | if (family == AF_PACKET) { |
205 | bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg); | 207 | bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "address"); |
206 | } | 208 | } |
207 | if (get_addr_1(dst, arg, family)) { | 209 | if (get_addr_1(dst, arg, family)) { |
208 | bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg); | 210 | bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "address", arg); |
209 | } | 211 | } |
210 | return 0; | 212 | return 0; |
211 | } | 213 | } |
@@ -213,10 +215,10 @@ int get_addr(inet_prefix * dst, char *arg, int family) | |||
213 | int get_prefix(inet_prefix * dst, char *arg, int family) | 215 | int get_prefix(inet_prefix * dst, char *arg, int family) |
214 | { | 216 | { |
215 | if (family == AF_PACKET) { | 217 | if (family == AF_PACKET) { |
216 | bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg); | 218 | bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "prefix"); |
217 | } | 219 | } |
218 | if (get_prefix_1(dst, arg, family)) { | 220 | if (get_prefix_1(dst, arg, family)) { |
219 | bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg); | 221 | bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "prefix", arg); |
220 | } | 222 | } |
221 | return 0; | 223 | return 0; |
222 | } | 224 | } |
@@ -226,7 +228,7 @@ uint32_t get_addr32(char *name) | |||
226 | inet_prefix addr; | 228 | inet_prefix addr; |
227 | 229 | ||
228 | if (get_addr_1(&addr, name, AF_INET)) { | 230 | if (get_addr_1(&addr, name, AF_INET)) { |
229 | bb_error_msg_and_die("an IP address is expected rather than \"%s\"", name); | 231 | bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "IP", "address", name); |
230 | } | 232 | } |
231 | return addr.data[0]; | 233 | return addr.data[0]; |
232 | } | 234 | } |
diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h index 607083af8..1af39ffe1 100644 --- a/networking/libiproute/utils.h +++ b/networking/libiproute/utils.h | |||
@@ -39,6 +39,8 @@ typedef struct { | |||
39 | uint32_t data[4]; | 39 | uint32_t data[4]; |
40 | } inet_prefix; | 40 | } inet_prefix; |
41 | 41 | ||
42 | #define PREFIXLEN_SPECIFIED 1 | ||
43 | |||
42 | #define DN_MAXADDL 20 | 44 | #define DN_MAXADDL 20 |
43 | #ifndef AF_DECnet | 45 | #ifndef AF_DECnet |
44 | #define AF_DECnet 12 | 46 | #define AF_DECnet 12 |