diff options
Diffstat (limited to 'networking/libiproute/iproute.c')
-rw-r--r-- | networking/libiproute/iproute.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index f6071b463..f8a67d9ee 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -31,8 +31,8 @@ struct filter_t { | |||
31 | //int type; - read-only | 31 | //int type; - read-only |
32 | //int typemask; - unused | 32 | //int typemask; - unused |
33 | //int tos, tosmask; - unused | 33 | //int tos, tosmask; - unused |
34 | int iif, iifmask; | 34 | int iif; |
35 | int oif, oifmask; | 35 | int oif; |
36 | //int realm, realmmask; - unused | 36 | //int realm, realmmask; - unused |
37 | //inet_prefix rprefsrc; - read-only | 37 | //inet_prefix rprefsrc; - read-only |
38 | inet_prefix rvia; | 38 | inet_prefix rvia; |
@@ -82,7 +82,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
82 | { | 82 | { |
83 | struct rtmsg *r = NLMSG_DATA(n); | 83 | struct rtmsg *r = NLMSG_DATA(n); |
84 | int len = n->nlmsg_len; | 84 | int len = n->nlmsg_len; |
85 | struct rtattr * tb[RTA_MAX+1]; | 85 | struct rtattr *tb[RTA_MAX+1]; |
86 | char abuf[256]; | 86 | char abuf[256]; |
87 | inet_prefix dst; | 87 | inet_prefix dst; |
88 | inet_prefix src; | 88 | inet_prefix src; |
@@ -159,8 +159,21 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
159 | } | 159 | } |
160 | 160 | ||
161 | memset(tb, 0, sizeof(tb)); | 161 | memset(tb, 0, sizeof(tb)); |
162 | memset(&src, 0, sizeof(src)); | ||
163 | memset(&dst, 0, sizeof(dst)); | ||
162 | parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); | 164 | parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); |
163 | 165 | ||
166 | if (tb[RTA_SRC]) { | ||
167 | src.bitlen = r->rtm_src_len; | ||
168 | src.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4); | ||
169 | memcpy(src.data, RTA_DATA(tb[RTA_SRC]), src.bytelen); | ||
170 | } | ||
171 | if (tb[RTA_DST]) { | ||
172 | dst.bitlen = r->rtm_dst_len; | ||
173 | dst.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4); | ||
174 | memcpy(dst.data, RTA_DATA(tb[RTA_DST]), dst.bytelen); | ||
175 | } | ||
176 | |||
164 | if (G_filter.rdst.family | 177 | if (G_filter.rdst.family |
165 | && inet_addr_match(&dst, &G_filter.rdst, G_filter.rdst.bitlen) | 178 | && inet_addr_match(&dst, &G_filter.rdst, G_filter.rdst.bitlen) |
166 | ) { | 179 | ) { |
@@ -182,23 +195,32 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
182 | ) { | 195 | ) { |
183 | return 0; | 196 | return 0; |
184 | } | 197 | } |
185 | if (G_filter.flushb | 198 | if (G_filter.oif != 0) { |
186 | && r->rtm_family == AF_INET6 | 199 | if (!tb[RTA_OIF]) |
187 | && r->rtm_dst_len == 0 | 200 | return 0; |
188 | && r->rtm_type == RTN_UNREACHABLE | 201 | if (G_filter.oif != *(int*)RTA_DATA(tb[RTA_OIF])) |
189 | && tb[RTA_PRIORITY] | 202 | return 0; |
190 | && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1 | ||
191 | ) { | ||
192 | return 0; | ||
193 | } | 203 | } |
194 | 204 | ||
195 | if (G_filter.flushb) { | 205 | if (G_filter.flushb) { |
196 | struct nlmsghdr *fn; | 206 | struct nlmsghdr *fn; |
207 | |||
208 | /* We are creating route flush commands */ | ||
209 | |||
210 | if (r->rtm_family == AF_INET6 | ||
211 | && r->rtm_dst_len == 0 | ||
212 | && r->rtm_type == RTN_UNREACHABLE | ||
213 | && tb[RTA_PRIORITY] | ||
214 | && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1 | ||
215 | ) { | ||
216 | return 0; | ||
217 | } | ||
218 | |||
197 | if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) { | 219 | if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) { |
198 | if (flush_update()) | 220 | if (flush_update()) |
199 | bb_error_msg_and_die("flush"); | 221 | bb_error_msg_and_die("flush"); |
200 | } | 222 | } |
201 | fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); | 223 | fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); |
202 | memcpy(fn, n, n->nlmsg_len); | 224 | memcpy(fn, n, n->nlmsg_len); |
203 | fn->nlmsg_type = RTM_DELROUTE; | 225 | fn->nlmsg_type = RTM_DELROUTE; |
204 | fn->nlmsg_flags = NLM_F_REQUEST; | 226 | fn->nlmsg_flags = NLM_F_REQUEST; |
@@ -208,6 +230,8 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
208 | return 0; | 230 | return 0; |
209 | } | 231 | } |
210 | 232 | ||
233 | /* We are printing routes */ | ||
234 | |||
211 | if (n->nlmsg_type == RTM_DELROUTE) { | 235 | if (n->nlmsg_type == RTM_DELROUTE) { |
212 | printf("Deleted "); | 236 | printf("Deleted "); |
213 | } | 237 | } |
@@ -257,10 +281,12 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
257 | RTA_DATA(tb[RTA_GATEWAY]), | 281 | RTA_DATA(tb[RTA_GATEWAY]), |
258 | abuf, sizeof(abuf))); | 282 | abuf, sizeof(abuf))); |
259 | } | 283 | } |
260 | if (tb[RTA_OIF] && G_filter.oifmask != -1) { | 284 | if (tb[RTA_OIF]) { |
261 | printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); | 285 | printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); |
262 | } | 286 | } |
263 | 287 | ||
288 | /* Todo: parse & show "proto kernel", "scope link" here */ | ||
289 | |||
264 | if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) { | 290 | if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) { |
265 | /* Do not use format_host(). It is our local addr | 291 | /* Do not use format_host(). It is our local addr |
266 | and symbolic name will not be useful. | 292 | and symbolic name will not be useful. |
@@ -292,7 +318,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
292 | printf(" error %d", ci->rta_error); | 318 | printf(" error %d", ci->rta_error); |
293 | } | 319 | } |
294 | } | 320 | } |
295 | if (tb[RTA_IIF] && G_filter.iifmask != -1) { | 321 | if (tb[RTA_IIF] && G_filter.iif == 0) { |
296 | printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); | 322 | printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); |
297 | } | 323 | } |
298 | bb_putchar('\n'); | 324 | bb_putchar('\n'); |
@@ -413,7 +439,8 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
413 | NEXT_ARG(); | 439 | NEXT_ARG(); |
414 | } | 440 | } |
415 | if ((**argv < '0' || **argv > '9') | 441 | if ((**argv < '0' || **argv > '9') |
416 | && rtnl_rtntype_a2n(&type, *argv) == 0) { | 442 | && rtnl_rtntype_a2n(&type, *argv) == 0 |
443 | ) { | ||
417 | NEXT_ARG(); | 444 | NEXT_ARG(); |
418 | req.r.rtm_type = type; | 445 | req.r.rtm_type = type; |
419 | ok |= type_ok; | 446 | ok |= type_ok; |
@@ -662,12 +689,10 @@ static int iproute_list_or_flush(char **argv, int flush) | |||
662 | if (id) { | 689 | if (id) { |
663 | idx = xll_name_to_index(id); | 690 | idx = xll_name_to_index(id); |
664 | G_filter.iif = idx; | 691 | G_filter.iif = idx; |
665 | G_filter.iifmask = -1; | ||
666 | } | 692 | } |
667 | if (od) { | 693 | if (od) { |
668 | idx = xll_name_to_index(od); | 694 | idx = xll_name_to_index(od); |
669 | G_filter.oif = idx; | 695 | G_filter.oif = idx; |
670 | G_filter.oifmask = -1; | ||
671 | } | 696 | } |
672 | } | 697 | } |
673 | 698 | ||