/* vi: set sw=4 ts=4: */
/*
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 *
 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 *
 * Changes:
 * Laszlo Valko <valko@linux.karinthy.hu> 990223: address label must be zero terminated
 */

#include <fnmatch.h>
#include <net/if.h>
#include <net/if_arp.h>

#include "ip_common.h"  /* #include "libbb.h" is inside */
#include "rt_names.h"
#include "utils.h"

#ifndef IFF_LOWER_UP
/* from linux/if.h */
#define IFF_LOWER_UP  0x10000  /* driver signals L1 up */
#endif

struct filter_t {
	char *label;
	char *flushb;
	struct rtnl_handle *rth;
	int scope, scopemask;
	int flags, flagmask;
	int flushp;
	int flushe;
	int ifindex;
	family_t family;
	smallint showqueue;
	smallint oneline;
	smallint up;
	smallint flushed;
	inet_prefix pfx;
} FIX_ALIASING;
typedef struct filter_t filter_t;

#define G_filter (*(filter_t*)&bb_common_bufsiz1)


static void print_link_flags(unsigned flags, unsigned mdown)
{
	static const int flag_masks[] = {
		IFF_LOOPBACK, IFF_BROADCAST, IFF_POINTOPOINT,
		IFF_MULTICAST, IFF_NOARP, IFF_UP, IFF_LOWER_UP };
	static const char flag_labels[] ALIGN1 =
		"LOOPBACK\0""BROADCAST\0""POINTOPOINT\0"
		"MULTICAST\0""NOARP\0""UP\0""LOWER_UP\0";

	bb_putchar('<');
	if (flags & IFF_UP && !(flags & IFF_RUNNING))
		printf("NO-CARRIER,");
	flags &= ~IFF_RUNNING;
#if 0
	_PF(ALLMULTI);
	_PF(PROMISC);
	_PF(MASTER);
	_PF(SLAVE);
	_PF(DEBUG);
	_PF(DYNAMIC);
	_PF(AUTOMEDIA);
	_PF(PORTSEL);
	_PF(NOTRAILERS);
#endif
	flags = print_flags_separated(flag_masks, flag_labels, flags, ",");
	if (flags)
		printf("%x", flags);
	if (mdown)
		printf(",M-DOWN");
	printf("> ");
}

static void print_queuelen(char *name)
{
	struct ifreq ifr;
	int s;

	s = socket(AF_INET, SOCK_STREAM, 0);
	if (s < 0)
		return;

	memset(&ifr, 0, sizeof(ifr));
	strncpy_IFNAMSIZ(ifr.ifr_name, name);
	if (ioctl_or_warn(s, SIOCGIFTXQLEN, &ifr) < 0) {
		close(s);
		return;
	}
	close(s);

	if (ifr.ifr_qlen)
		printf("qlen %d", ifr.ifr_qlen);
}

static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
{
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct rtattr *tb[IFLA_MAX+1];
	int len = n->nlmsg_len;

	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
		return 0;

	len -= NLMSG_LENGTH(sizeof(*ifi));
	if (len < 0)
		return -1;

	if (G_filter.ifindex && ifi->ifi_index != G_filter.ifindex)
		return 0;
	if (G_filter.up && !(ifi->ifi_flags & IFF_UP))
		return 0;

	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		bb_error_msg("nil ifname");
		return -1;
	}
	if (G_filter.label
	 && (!G_filter.family || G_filter.family == AF_PACKET)
	 && fnmatch(G_filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)
	) {
		return 0;
	}

	if (n->nlmsg_type == RTM_DELLINK)
		printf("Deleted ");

	printf("%d: %s", ifi->ifi_index,
		/*tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>" - we checked tb[IFLA_IFNAME] above*/
		(char*)RTA_DATA(tb[IFLA_IFNAME])
	);

	{
		unsigned m_flag = 0;
		if (tb[IFLA_LINK]) {
			SPRINT_BUF(b1);
			int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
			if (iflink == 0)
				printf("@NONE: ");
			else {
				printf("@%s: ", ll_idx_n2a(iflink, b1));
				m_flag = ll_index_to_flags(iflink);
				m_flag = !(m_flag & IFF_UP);
			}
		} else {
			printf(": ");
		}
		print_link_flags(ifi->ifi_flags, m_flag);
	}

	if (tb[IFLA_MTU])
		printf("mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
	if (tb[IFLA_QDISC])
		printf("qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
#ifdef IFLA_MASTER
	if (tb[IFLA_MASTER]) {
		SPRINT_BUF(b1);
		printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
	}
#endif
/* IFLA_OPERSTATE was added to kernel with the same commit as IFF_DORMANT */
#ifdef IFF_DORMANT
	if (tb[IFLA_OPERSTATE]) {
		static const char operstate_labels[] ALIGN1 =
			"UNKNOWN\0""NOTPRESENT\0""DOWN\0""LOWERLAYERDOWN\0"
			"TESTING\0""DORMANT\0""UP\0";
		printf("state %s ", nth_string(operstate_labels,
					*(uint8_t *)RTA_DATA(tb[IFLA_OPERSTATE])));
	}
#endif
	if (G_filter.showqueue)
		print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME]));

	if (!G_filter.family || G_filter.family == AF_PACKET) {
		SPRINT_BUF(b1);
		printf("%c    link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1));

		if (tb[IFLA_ADDRESS]) {
			fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
						      RTA_PAYLOAD(tb[IFLA_ADDRESS]),
						      ifi->ifi_type,
						      b1, sizeof(b1)), stdout);
		}
		if (tb[IFLA_BROADCAST]) {
			if (ifi->ifi_flags & IFF_POINTOPOINT)
				printf(" peer ");
			else
				printf(" brd ");
			fputs(ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
						      ifi->ifi_type,
						      b1, sizeof(b1)), stdout);
		}
	}
	bb_putchar('\n');
	/*fflush_all();*/
	return 0;
}

static int flush_update(void)
{
	if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
		bb_perror_msg("can't send flush request");
		return -1;
	}
	G_filter.flushp = 0;
	return 0;
}

static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
		struct nlmsghdr *n, void *arg UNUSED_PARAM)
{
	struct ifaddrmsg *ifa = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	struct rtattr * rta_tb[IFA_MAX+1];
	char abuf[256];
	SPRINT_BUF(b1);

	if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
		return 0;
	len -= NLMSG_LENGTH(sizeof(*ifa));
	if (len < 0) {
		bb_error_msg("wrong nlmsg len %d", len);
		return -1;
	}

	if (G_filter.flushb && n->nlmsg_type != RTM_NEWADDR)
		return 0;

	memset(rta_tb, 0, sizeof(rta_tb));
	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));

	if (!rta_tb[IFA_LOCAL])
		rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
	if (!rta_tb[IFA_ADDRESS])
		rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];

	if (G_filter.ifindex && G_filter.ifindex != (int) ifa->ifa_index)
		return 0;
	if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
		return 0;
	if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask)
		return 0;
	if (G_filter.label) {
		const char *label;
		if (rta_tb[IFA_LABEL])
			label = RTA_DATA(rta_tb[IFA_LABEL]);
		else
			label = ll_idx_n2a(ifa->ifa_index, b1);
		if (fnmatch(G_filter.label, label, 0) != 0)
			return 0;
	}
	if (G_filter.pfx.family) {
		if (rta_tb[IFA_LOCAL]) {
			inet_prefix dst;
			memset(&dst, 0, sizeof(dst));
			dst.family = ifa->ifa_family;
			memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
			if (inet_addr_match(&dst, &G_filter.pfx, G_filter.pfx.bitlen))
				return 0;
		}
	}

	if (G_filter.flushb) {
		struct nlmsghdr *fn;
		if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > (unsigned) G_filter.flushe) {
			if (flush_update())
				return -1;
		}
		fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
		memcpy(fn, n, n->nlmsg_len);
		fn->nlmsg_type = RTM_DELADDR;
		fn->nlmsg_flags = NLM_F_REQUEST;
		fn->nlmsg_seq = ++G_filter.rth->seq;
		G_filter.flushp = (((char*)fn) + n->nlmsg_len) - G_filter.flushb;
		G_filter.flushed = 1;
		return 0;
	}

	if (n->nlmsg_type == RTM_DELADDR)
		printf("Deleted ");

	if (G_filter.oneline)
		printf("%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
	if (ifa->ifa_family == AF_INET)
		printf("    inet ");
	else if (ifa->ifa_family == AF_INET6)
		printf("    inet6 ");
	else
		printf("    family %d ", ifa->ifa_family);

	if (rta_tb[IFA_LOCAL]) {
		fputs(rt_addr_n2a(ifa->ifa_family,
					      RTA_DATA(rta_tb[IFA_LOCAL]),
					      abuf, sizeof(abuf)), stdout);

		if (rta_tb[IFA_ADDRESS] == NULL
		 || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0
		) {
			printf("/%d ", ifa->ifa_prefixlen);
		} else {
			printf(" peer %s/%d ",
				rt_addr_n2a(ifa->ifa_family,
					    RTA_DATA(rta_tb[IFA_ADDRESS]),
					    abuf, sizeof(abuf)),
				ifa->ifa_prefixlen);
		}
	}

	if (rta_tb[IFA_BROADCAST]) {
		printf("brd %s ",
			rt_addr_n2a(ifa->ifa_family,
					RTA_DATA(rta_tb[IFA_BROADCAST]),
					abuf, sizeof(abuf))
		);
	}
	if (rta_tb[IFA_ANYCAST]) {
		printf("any %s ",
			rt_addr_n2a(ifa->ifa_family,
					RTA_DATA(rta_tb[IFA_ANYCAST]),
					abuf, sizeof(abuf))
		);
	}
	printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1));
	if (ifa->ifa_flags & IFA_F_SECONDARY) {
		ifa->ifa_flags &= ~IFA_F_SECONDARY;
		printf("secondary ");
	}
	if (ifa->ifa_flags & IFA_F_TENTATIVE) {
		ifa->ifa_flags &= ~IFA_F_TENTATIVE;
		printf("tentative ");
	}
	if (ifa->ifa_flags & IFA_F_DEPRECATED) {
		ifa->ifa_flags &= ~IFA_F_DEPRECATED;
		printf("deprecated ");
	}
	if (!(ifa->ifa_flags & IFA_F_PERMANENT)) {
		printf("dynamic ");
	} else
		ifa->ifa_flags &= ~IFA_F_PERMANENT;
	if (ifa->ifa_flags)
		printf("flags %02x ", ifa->ifa_flags);
	if (rta_tb[IFA_LABEL])
		fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout);
	if (rta_tb[IFA_CACHEINFO]) {
		struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
		char buf[128];
		bb_putchar(_SL_);
		if (ci->ifa_valid == 0xFFFFFFFFU)
			sprintf(buf, "valid_lft forever");
		else
			sprintf(buf, "valid_lft %dsec", ci->ifa_valid);
		if (ci->ifa_prefered == 0xFFFFFFFFU)
			sprintf(buf+strlen(buf), " preferred_lft forever");
		else
			sprintf(buf+strlen(buf), " preferred_lft %dsec", ci->ifa_prefered);
		printf("       %s", buf);
	}
	bb_putchar('\n');
	/*fflush_all();*/
	return 0;
}


struct nlmsg_list {
	struct nlmsg_list *next;
	struct nlmsghdr   h;
};

static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo)
{
	for (; ainfo; ainfo = ainfo->next) {
		struct nlmsghdr *n = &ainfo->h;
		struct ifaddrmsg *ifa = NLMSG_DATA(n);

		if (n->nlmsg_type != RTM_NEWADDR)
			continue;
		if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa)))
			return -1;
		if ((int) ifa->ifa_index != ifindex
		 || (G_filter.family && G_filter.family != (family_t) ifa->ifa_family)
		) {
			continue;
		}
		print_addrinfo(NULL, n, NULL);
	}
	return 0;
}


static int FAST_FUNC store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
	struct nlmsg_list **linfo = (struct nlmsg_list**)arg;
	struct nlmsg_list *h;
	struct nlmsg_list **lp;

	h = xzalloc(n->nlmsg_len + sizeof(void*));

	memcpy(&h->h, n, n->nlmsg_len);
	/*h->next = NULL; - xzalloc did it */

	for (lp = linfo; *lp; lp = &(*lp)->next)
		continue;
	*lp = h;

	ll_remember_index(who, n, NULL);
	return 0;
}

static void ipaddr_reset_filter(int _oneline)
{
	memset(&G_filter, 0, sizeof(G_filter));
	G_filter.oneline = _oneline;
}

/* Return value becomes exitcode. It's okay to not return at all */
int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
{
	static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0";

	struct nlmsg_list *linfo = NULL;
	struct nlmsg_list *ainfo = NULL;
	struct nlmsg_list *l;
	struct rtnl_handle rth;
	char *filter_dev = NULL;
	int no_link = 0;

	ipaddr_reset_filter(oneline);
	G_filter.showqueue = 1;

	if (G_filter.family == AF_UNSPEC)
		G_filter.family = preferred_family;

	if (flush) {
		if (!*argv) {
			bb_error_msg_and_die(bb_msg_requires_arg, "flush");
		}
		if (G_filter.family == AF_PACKET) {
			bb_error_msg_and_die("can't flush link addresses");
		}
	}

	while (*argv) {
		const smalluint key = index_in_strings(option, *argv);
		if (key == 0) { /* to */
			NEXT_ARG();
			get_prefix(&G_filter.pfx, *argv, G_filter.family);
			if (G_filter.family == AF_UNSPEC) {
				G_filter.family = G_filter.pfx.family;
			}
		} else if (key == 1) { /* scope */
			uint32_t scope = 0;
			NEXT_ARG();
			G_filter.scopemask = -1;
			if (rtnl_rtscope_a2n(&scope, *argv)) {
				if (strcmp(*argv, "all") != 0) {
					invarg(*argv, "scope");
				}
				scope = RT_SCOPE_NOWHERE;
				G_filter.scopemask = 0;
			}
			G_filter.scope = scope;
		} else if (key == 2) { /* up */
			G_filter.up = 1;
		} else if (key == 3) { /* label */
			NEXT_ARG();
			G_filter.label = *argv;
		} else {
			if (key == 4) /* dev */
				NEXT_ARG();
			if (filter_dev)
				duparg2("dev", *argv);
			filter_dev = *argv;
		}
		argv++;
	}

	xrtnl_open(&rth);

	xrtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK);
	xrtnl_dump_filter(&rth, store_nlmsg, &linfo);

	if (filter_dev) {
		G_filter.ifindex = xll_name_to_index(filter_dev);
	}

	if (flush) {
		char flushb[4096-512];

		G_filter.flushb = flushb;
		G_filter.flushp = 0;
		G_filter.flushe = sizeof(flushb);
		G_filter.rth = &rth;

		for (;;) {
			xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETADDR);
			G_filter.flushed = 0;
			xrtnl_dump_filter(&rth, print_addrinfo, NULL);
			if (G_filter.flushed == 0) {
				return 0;
			}
			if (flush_update() < 0) {
				return 1;
			}
		}
	}

	if (G_filter.family != AF_PACKET) {
		xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETADDR);
		xrtnl_dump_filter(&rth, store_nlmsg, &ainfo);
	}


	if (G_filter.family && G_filter.family != AF_PACKET) {
		struct nlmsg_list **lp;
		lp = &linfo;

		if (G_filter.oneline)
			no_link = 1;

		while ((l = *lp) != NULL) {
			int ok = 0;
			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
			struct nlmsg_list *a;

			for (a = ainfo; a; a = a->next) {
				struct nlmsghdr *n = &a->h;
				struct ifaddrmsg *ifa = NLMSG_DATA(n);

				if ((int) ifa->ifa_index != (int) ifi->ifi_index
				 || (G_filter.family && G_filter.family != (family_t) ifa->ifa_family)
				) {
					continue;
				}
				if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
					continue;
				if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask)
					continue;
				if (G_filter.pfx.family || G_filter.label) {
					struct rtattr *tb[IFA_MAX+1];
					memset(tb, 0, sizeof(tb));
					parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
					if (!tb[IFA_LOCAL])
						tb[IFA_LOCAL] = tb[IFA_ADDRESS];

					if (G_filter.pfx.family && tb[IFA_LOCAL]) {
						inet_prefix dst;
						memset(&dst, 0, sizeof(dst));
						dst.family = ifa->ifa_family;
						memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
						if (inet_addr_match(&dst, &G_filter.pfx, G_filter.pfx.bitlen))
							continue;
					}
					if (G_filter.label) {
						SPRINT_BUF(b1);
						const char *label;
						if (tb[IFA_LABEL])
							label = RTA_DATA(tb[IFA_LABEL]);
						else
							label = ll_idx_n2a(ifa->ifa_index, b1);
						if (fnmatch(G_filter.label, label, 0) != 0)
							continue;
					}
				}

				ok = 1;
				break;
			}
			if (!ok)
				*lp = l->next;
			else
				lp = &l->next;
		}
	}

	for (l = linfo; l; l = l->next) {
		if (no_link || print_linkinfo(&l->h) == 0) {
			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
			if (G_filter.family != AF_PACKET)
				print_selected_addrinfo(ifi->ifi_index, ainfo);
		}
	}

	return 0;
}

static int default_scope(inet_prefix *lcl)
{
	if (lcl->family == AF_INET) {
		if (lcl->bytelen >= 1 && *(uint8_t*)&lcl->data == 127)
			return RT_SCOPE_HOST;
	}
	return 0;
}

/* Return value becomes exitcode. It's okay to not return at all */
static int ipaddr_modify(int cmd, char **argv)
{
	static const char option[] ALIGN1 =
		"peer\0""remote\0""broadcast\0""brd\0"
		"anycast\0""scope\0""dev\0""label\0""local\0";
	struct rtnl_handle rth;
	struct {
		struct nlmsghdr  n;
		struct ifaddrmsg ifa;
		char             buf[256];
	} req;
	char *d = NULL;
	char *l = NULL;
	inet_prefix lcl;
	inet_prefix peer;
	int local_len = 0;
	int peer_len = 0;
	int brd_len = 0;
	int any_len = 0;
	bool scoped = 0;

	memset(&req, 0, sizeof(req));

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST;
	req.n.nlmsg_type = cmd;
	req.ifa.ifa_family = preferred_family;

	while (*argv) {
		unsigned arg = index_in_strings(option, *argv);
		/* if search fails, "local" is assumed */
		if ((int)arg >= 0)
			NEXT_ARG();

		if (arg <= 1) { /* peer, remote */
			if (peer_len) {
				duparg("peer", *argv);
			}
			get_prefix(&peer, *argv, req.ifa.ifa_family);
			peer_len = peer.bytelen;
			if (req.ifa.ifa_family == AF_UNSPEC) {
				req.ifa.ifa_family = peer.family;
			}
			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
			req.ifa.ifa_prefixlen = peer.bitlen;
		} else if (arg <= 3) { /* broadcast, brd */
			inet_prefix addr;
			if (brd_len) {
				duparg("broadcast", *argv);
			}
			if (LONE_CHAR(*argv, '+')) {
				brd_len = -1;
			} else if (LONE_DASH(*argv)) {
				brd_len = -2;
			} else {
				get_addr(&addr, *argv, req.ifa.ifa_family);
				if (req.ifa.ifa_family == AF_UNSPEC)
					req.ifa.ifa_family = addr.family;
				addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
				brd_len = addr.bytelen;
			}
		} else if (arg == 4) { /* anycast */
			inet_prefix addr;
			if (any_len) {
				duparg("anycast", *argv);
			}
			get_addr(&addr, *argv, req.ifa.ifa_family);
			if (req.ifa.ifa_family == AF_UNSPEC) {
				req.ifa.ifa_family = addr.family;
			}
			addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
			any_len = addr.bytelen;
		} else if (arg == 5) { /* scope */
			uint32_t scope = 0;
			if (rtnl_rtscope_a2n(&scope, *argv)) {
				invarg(*argv, "scope");
			}
			req.ifa.ifa_scope = scope;
			scoped = 1;
		} else if (arg == 6) { /* dev */
			d = *argv;
		} else if (arg == 7) { /* label */
			l = *argv;
			addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
		} else {
			/* local (specified or assumed) */
			if (local_len) {
				duparg2("local", *argv);
			}
			get_prefix(&lcl, *argv, req.ifa.ifa_family);
			if (req.ifa.ifa_family == AF_UNSPEC) {
				req.ifa.ifa_family = lcl.family;
			}
			addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
			local_len = lcl.bytelen;
		}
		argv++;
	}

	if (!d) {
		/* There was no "dev IFACE", but we need that */
		bb_error_msg_and_die("need \"dev IFACE\"");
	}
	if (l && strncmp(d, l, strlen(d)) != 0) {
		bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l);
	}

	if (peer_len == 0 && local_len && cmd != RTM_DELADDR) {
		peer = lcl;
		addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen);
	}
	if (req.ifa.ifa_prefixlen == 0)
		req.ifa.ifa_prefixlen = lcl.bitlen;

	if (brd_len < 0 && cmd != RTM_DELADDR) {
		inet_prefix brd;
		int i;
		if (req.ifa.ifa_family != AF_INET) {
			bb_error_msg_and_die("broadcast can be set only for IPv4 addresses");
		}
		brd = peer;
		if (brd.bitlen <= 30) {
			for (i = 31; i >= brd.bitlen; i--) {
				if (brd_len == -1)
					brd.data[0] |= htonl(1<<(31-i));
				else
					brd.data[0] &= ~htonl(1<<(31-i));
			}
			addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen);
			brd_len = brd.bytelen;
		}
	}
	if (!scoped && cmd != RTM_DELADDR)
		req.ifa.ifa_scope = default_scope(&lcl);

	xrtnl_open(&rth);

	ll_init_map(&rth);

	req.ifa.ifa_index = xll_name_to_index(d);

	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
		return 2;

	return 0;
}

/* Return value becomes exitcode. It's okay to not return at all */
int FAST_FUNC do_ipaddr(char **argv)
{
	static const char commands[] ALIGN1 =
		"add\0""delete\0""list\0""show\0""lst\0""flush\0";
	int cmd = 2;
	if (*argv) {
		cmd = index_in_substrings(commands, *argv);
		if (cmd < 0)
			invarg(*argv, applet_name);
		argv++;
		if (cmd <= 1)
			return ipaddr_modify((cmd == 0) ? RTM_NEWADDR : RTM_DELADDR, argv);
	}
	/* 2 == list, 3 == show, 4 == lst */
	return ipaddr_list_or_flush(argv, cmd == 5);
}
