/* 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 "common_bufsiz.h"
#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;
	/* Flush cmd buf. If !NULL, print_addrinfo() constructs flush commands in it */
	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;
	/* Misnomer. Does not mean "flushed something" */
	/* More like "flush commands were constructed by print_addrinfo()" */
	smallint flushed;
	inet_prefix pfx;
} FIX_ALIASING;
typedef struct filter_t filter_t;

#define G_filter (*(filter_t*)bb_common_bufsiz1)
#define INIT_G() do { setup_common_bufsiz(); } while (0)

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 does this
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL) {
		bb_simple_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]) {
			int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
			if (iflink == 0)
				printf("@NONE: ");
			else {
				printf("@%s: ", ll_index_to_name(iflink));
				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]) {
		printf("master %s ", ll_index_to_name(*(int*)RTA_DATA(tb[IFLA_MASTER])));
	}
#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_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
		bb_simple_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;
	unsigned int ifa_flags;
	struct rtattr *rta_tb[IFA_MAX+1];

	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 does this
	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));

	ifa_flags = rta_tb[IFA_FLAGS] ? *(__u32*)RTA_DATA(rta_tb[IFA_FLAGS]) : ifa->ifa_flags;

	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 != ifa->ifa_index)
		return 0;
	if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask)
		return 0;
	if ((G_filter.flags ^ 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_index_to_name(ifa->ifa_index);
		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 > 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])),
			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])),
				ifa->ifa_prefixlen
			);
		}
	}

	if (rta_tb[IFA_BROADCAST]) {
		printf("brd %s ",
			rt_addr_n2a(ifa->ifa_family,
				RTA_DATA(rta_tb[IFA_BROADCAST]))
		);
	}
	if (rta_tb[IFA_ANYCAST]) {
		printf("any %s ",
			rt_addr_n2a(ifa->ifa_family,
				RTA_DATA(rta_tb[IFA_ANYCAST]))
		);
	}
	printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope));
	if (ifa_flags & IFA_F_SECONDARY) {
		ifa_flags &= ~IFA_F_SECONDARY;
		printf("secondary ");
	}
	if (ifa_flags & IFA_F_TENTATIVE) {
		ifa_flags &= ~IFA_F_TENTATIVE;
		printf("tentative ");
	}
	if (ifa_flags & IFA_F_DADFAILED) {
		ifa_flags &= ~IFA_F_DADFAILED;
		printf("dadfailed ");
	}
	if (ifa_flags & IFA_F_DEPRECATED) {
		ifa_flags &= ~IFA_F_DEPRECATED;
		printf("deprecated ");
	}
	if (!(ifa_flags & IFA_F_PERMANENT)) {
		printf("dynamic ");
	} else
		ifa_flags &= ~IFA_F_PERMANENT;
	if (ifa_flags & IFA_F_NOPREFIXROUTE) {
		ifa_flags &= ~IFA_F_NOPREFIXROUTE;
		printf("noprefixroute ");
	}
	if (ifa_flags)
		printf("flags %02x ", 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 (ifa->ifa_index != ifindex
		 || (G_filter.family && G_filter.family != 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;

	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_simple_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_1_to_2(*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;

		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 (ifa->ifa_index != ifi->ifi_index
				 || (G_filter.family && G_filter.family != 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 does this
					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) {
						const char *label;
						if (tb[IFA_LABEL])
							label = RTA_DATA(tb[IFA_LABEL]);
						else
							label = ll_index_to_name(ifa->ifa_index);
						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 ((oneline && G_filter.family != AF_PACKET)
		/* ^^^^^^^^^ "ip -oneline a" does not print link info */
		 || (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 void set_lifetime(unsigned int *lifetime, char *argv, const char *errmsg)
{
	if (strcmp(argv, "forever") == 0)
		*lifetime = INFINITY_LIFE_TIME;
	else
		*lifetime = get_u32(argv, errmsg);
}

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, int flags, char **argv)
{
	/* If you add stuff here, update ipaddr_full_usage */
	static const char option[] ALIGN1 =
		"peer\0""remote\0""broadcast\0""brd\0"
		"anycast\0""valid_lft\0""preferred_lft\0"
		"scope\0""dev\0""label\0""noprefixroute\0""local\0";
#define option_peer      option
#define option_broadcast (option           + sizeof("peer") + sizeof("remote"))
#define option_anycast   (option_broadcast + sizeof("broadcast") + sizeof("brd"))
#define option_valid_lft (option_anycast   + sizeof("anycast"))
#define option_pref_lft  (option_valid_lft + sizeof("valid_lft"))
	struct rtnl_handle rth;
	struct {
		struct nlmsghdr  n;
		struct ifaddrmsg ifa;
		char             buf[256];
	} req;
	char *d = NULL;
	char *l = NULL;
	char *valid_lftp = NULL;
	char *preferred_lftp = 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;
	__u32 valid_lft = INFINITY_LIFE_TIME;
	__u32 preferred_lft = INFINITY_LIFE_TIME;
	unsigned int ifa_flags = 0;

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

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | flags;
	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 (arg <= 1) { /* peer, remote */
			NEXT_ARG();
			if (peer_len) {
				duparg(option_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;
			NEXT_ARG();
			if (brd_len) {
				duparg(option_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;
			NEXT_ARG();
			if (any_len) {
				duparg(option_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) { /* valid_lft */
			if (valid_lftp)
				duparg(option_valid_lft, *argv);
			NEXT_ARG();
			valid_lftp = *argv;
			set_lifetime(&valid_lft, *argv, option_valid_lft);
		} else if (arg == 6) { /* preferred_lft */
			if (preferred_lftp)
				duparg(option_pref_lft, *argv);
			NEXT_ARG();
			preferred_lftp = *argv;
			set_lifetime(&preferred_lft, *argv, option_pref_lft);
		} else if (arg == 7) { /* scope */
			uint32_t scope = 0;
			NEXT_ARG();
			if (rtnl_rtscope_a2n(&scope, *argv)) {
				invarg_1_to_2(*argv, "scope");
			}
			req.ifa.ifa_scope = scope;
			scoped = 1;
		} else if (arg == 8) { /* dev */
			NEXT_ARG();
			d = *argv;
		} else if (arg == 9) { /* label */
			NEXT_ARG();
			l = *argv;
			addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
		} else if (arg == 10) { /* noprefixroute */
			ifa_flags |= IFA_F_NOPREFIXROUTE;
		} else {
			/* local (specified or assumed) */
			if ((int)arg >= 0)
				NEXT_ARG();
			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 (ifa_flags <= 0xff)
		req.ifa.ifa_flags = ifa_flags;
	else
		addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags);

	if (!d) {
		/* There was no "dev IFACE", but we need that */
		bb_simple_error_msg_and_die("need \"dev IFACE\"");
	}
	if (l && !is_prefixed_with(l, d)) {
		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_simple_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 (valid_lftp || preferred_lftp) {
		struct ifa_cacheinfo cinfo = {};

		if (!valid_lft) {
			fprintf(stderr, "valid_lft is zero\n");
			return 1;
		}
		if (valid_lft < preferred_lft) {
			fprintf(stderr, "preferred_lft is greater than valid_lft\n");
			return 1;
		}

		cinfo.ifa_prefered = preferred_lft;
		cinfo.ifa_valid = valid_lft;
		addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo,
			  sizeof(cinfo));
	}

	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 =
		/* 0    1         2      3          4         5       6       7      8 */
		"add\0""change\0""chg\0""replace\0""delete\0""list\0""show\0""lst\0""flush\0";
	int cmd = 2;

	INIT_G();

	if (*argv) {
		cmd = index_in_substrings(commands, *argv);
		if (cmd < 0)
			invarg_1_to_2(*argv, applet_name);
		argv++;
		if (cmd <= 4) {
			return ipaddr_modify(
				/*cmd:*/ cmd == 4 ? RTM_DELADDR : RTM_NEWADDR,
				/*flags:*/
					cmd == 0 ? NLM_F_CREATE|NLM_F_EXCL : /* add */
					cmd == 1 || cmd == 2 ? NLM_F_REPLACE : /* change */
					cmd == 3 ? NLM_F_CREATE|NLM_F_REPLACE : /* replace */
					0 /* delete */
			, argv);
		}
	}
	return ipaddr_list_or_flush(argv, cmd == 8);
}
