/* vi: set sw=4 ts=4: */
/*
- * iproute.c "ip route".
- *
- * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
- *
- * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
*
+ * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
* Changes:
*
- * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
+ * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
* Kunihiro Ishiguro <kunihiro@zebra.org> 001102: rtnh_ifindex was not initialized
*/
-#include "ip_common.h" /* #include "libbb.h" is inside */
+#include "ip_common.h" /* #include "libbb.h" is inside */
#include "rt_names.h"
#include "utils.h"
//int type; - read-only
//int typemask; - unused
//int tos, tosmask; - unused
- int iif, iifmask;
- int oif, oifmask;
+ int iif;
+ int oif;
//int realm, realmmask; - unused
//inet_prefix rprefsrc; - read-only
inet_prefix rvia;
{
struct rtmsg *r = NLMSG_DATA(n);
int len = n->nlmsg_len;
- struct rtattr * tb[RTA_MAX+1];
+ struct rtattr *tb[RTA_MAX+1];
char abuf[256];
inet_prefix dst;
inet_prefix src;
}
memset(tb, 0, sizeof(tb));
+ memset(&src, 0, sizeof(src));
+ memset(&dst, 0, sizeof(dst));
parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
+ if (tb[RTA_SRC]) {
+ src.bitlen = r->rtm_src_len;
+ src.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4);
+ memcpy(src.data, RTA_DATA(tb[RTA_SRC]), src.bytelen);
+ }
+ if (tb[RTA_DST]) {
+ dst.bitlen = r->rtm_dst_len;
+ dst.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4);
+ memcpy(dst.data, RTA_DATA(tb[RTA_DST]), dst.bytelen);
+ }
+
if (G_filter.rdst.family
&& inet_addr_match(&dst, &G_filter.rdst, G_filter.rdst.bitlen)
) {
) {
return 0;
}
- if (G_filter.flushb
- && r->rtm_family == AF_INET6
- && r->rtm_dst_len == 0
- && r->rtm_type == RTN_UNREACHABLE
- && tb[RTA_PRIORITY]
- && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1
- ) {
- return 0;
+ if (G_filter.oif != 0) {
+ if (!tb[RTA_OIF])
+ return 0;
+ if (G_filter.oif != *(int*)RTA_DATA(tb[RTA_OIF]))
+ return 0;
}
if (G_filter.flushb) {
struct nlmsghdr *fn;
+
+ /* We are creating route flush commands */
+
+ if (r->rtm_family == AF_INET6
+ && r->rtm_dst_len == 0
+ && r->rtm_type == RTN_UNREACHABLE
+ && tb[RTA_PRIORITY]
+ && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1
+ ) {
+ return 0;
+ }
+
if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) {
if (flush_update())
bb_error_msg_and_die("flush");
}
- fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
+ fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
memcpy(fn, n, n->nlmsg_len);
fn->nlmsg_type = RTM_DELROUTE;
fn->nlmsg_flags = NLM_F_REQUEST;
return 0;
}
+ /* We are printing routes */
+
if (n->nlmsg_type == RTM_DELROUTE) {
printf("Deleted ");
}
RTA_DATA(tb[RTA_GATEWAY]),
abuf, sizeof(abuf)));
}
- if (tb[RTA_OIF] && G_filter.oifmask != -1) {
+ if (tb[RTA_OIF]) {
printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
}
+ /* Todo: parse & show "proto kernel", "scope link" here */
+
if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) {
/* Do not use format_host(). It is our local addr
and symbolic name will not be useful.
printf(" error %d", ci->rta_error);
}
}
- if (tb[RTA_IIF] && G_filter.iifmask != -1) {
+ if (tb[RTA_IIF] && G_filter.iif == 0) {
printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
}
bb_putchar('\n');
};
struct rtnl_handle rth;
struct {
- struct nlmsghdr n;
- struct rtmsg r;
- char buf[1024];
+ struct nlmsghdr n;
+ struct rtmsg r;
+ char buf[1024];
} req;
char mxbuf[256];
struct rtattr * mxrta = (void*)mxbuf;
NEXT_ARG();
}
if ((**argv < '0' || **argv > '9')
- && rtnl_rtntype_a2n(&type, *argv) == 0) {
+ && rtnl_rtntype_a2n(&type, *argv) == 0
+ ) {
NEXT_ARG();
req.r.rtm_type = type;
ok |= type_ok;
if (id) {
idx = xll_name_to_index(id);
G_filter.iif = idx;
- G_filter.iifmask = -1;
}
if (od) {
idx = xll_name_to_index(od);
G_filter.oif = idx;
- G_filter.oifmask = -1;
}
}
}
req.r.rtm_dst_len = addr.bitlen;
}
- argv++;
}
+ argv++;
}
if (req.r.rtm_dst_len == 0) {