1/*
2 * ipaddress.c		"ip address".
3 *
4 *		This program is free software; you can redistribute it and/or
5 *		modify it under the terms of the GNU General Public License
6 *		as published by the Free Software Foundation; either version
7 *		2 of the License, or (at your option) any later version.
8 *
9 * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 *
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
16#include <syslog.h>
17#include <inttypes.h>
18#include <fcntl.h>
19#include <sys/ioctl.h>
20#include <sys/socket.h>
21#include <sys/ioctl.h>
22#include <sys/errno.h>
23#include <netinet/in.h>
24#include <arpa/inet.h>
25#include <string.h>
26#include <fnmatch.h>
27
28#include <linux/netdevice.h>
29#include <linux/if_arp.h>
30#include <linux/sockios.h>
31
32#include "rt_names.h"
33#include "utils.h"
34#include "ll_map.h"
35#include "ip_common.h"
36
37
38static struct
39{
40	int ifindex;
41	int family;
42	int oneline;
43	int showqueue;
44	inet_prefix pfx;
45	int scope, scopemask;
46	int flags, flagmask;
47	int up;
48	char *label;
49	int flushed;
50	char *flushb;
51	int flushp;
52	int flushe;
53	int group;
54} filter;
55
56static int do_link;
57
58static void usage(void) __attribute__((noreturn));
59
60static void usage(void)
61{
62	if (do_link) {
63		iplink_usage();
64	}
65	fprintf(stderr, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n");
66	fprintf(stderr, "                                                      [ CONFFLAG-LIST ]\n");
67	fprintf(stderr, "       ip addr del IFADDR dev STRING\n");
68	fprintf(stderr, "       ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
69	fprintf(stderr, "                            [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
70	fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n");
71	fprintf(stderr, "          [ broadcast ADDR ] [ anycast ADDR ]\n");
72	fprintf(stderr, "          [ label STRING ] [ scope SCOPE-ID ]\n");
73	fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
74	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
75	fprintf(stderr, "FLAG  := [ permanent | dynamic | secondary | primary |\n");
76	fprintf(stderr, "           tentative | deprecated | dadfailed | temporary |\n");
77	fprintf(stderr, "           CONFFLAG-LIST ]\n");
78	fprintf(stderr, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
79	fprintf(stderr, "CONFFLAG  := [ home | nodad ]\n");
80	fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
81	fprintf(stderr, "LFT := forever | SECONDS\n");
82
83	exit(-1);
84}
85
86void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
87{
88	fprintf(fp, "<");
89	if (flags & IFF_UP && !(flags & IFF_RUNNING))
90		fprintf(fp, "NO-CARRIER%s", flags ? "," : "");
91	flags &= ~IFF_RUNNING;
92#define _PF(f) if (flags&IFF_##f) { \
93                  flags &= ~IFF_##f ; \
94                  fprintf(fp, #f "%s", flags ? "," : ""); }
95	_PF(LOOPBACK);
96	_PF(BROADCAST);
97	_PF(POINTOPOINT);
98	_PF(MULTICAST);
99	_PF(NOARP);
100	_PF(ALLMULTI);
101	_PF(PROMISC);
102	_PF(MASTER);
103	_PF(SLAVE);
104	_PF(DEBUG);
105	_PF(DYNAMIC);
106	_PF(AUTOMEDIA);
107	_PF(PORTSEL);
108	_PF(NOTRAILERS);
109	_PF(UP);
110	_PF(LOWER_UP);
111	_PF(DORMANT);
112	_PF(ECHO);
113#undef _PF
114        if (flags)
115		fprintf(fp, "%x", flags);
116	if (mdown)
117		fprintf(fp, ",M-DOWN");
118	fprintf(fp, "> ");
119}
120
121static const char *oper_states[] = {
122	"UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
123	"TESTING", "DORMANT",	 "UP"
124};
125
126static void print_operstate(FILE *f, __u8 state)
127{
128	if (state >= sizeof(oper_states)/sizeof(oper_states[0]))
129		fprintf(f, "state %#x ", state);
130	else
131		fprintf(f, "state %s ", oper_states[state]);
132}
133
134int get_operstate(const char *name)
135{
136	int i;
137
138	for (i = 0; i < sizeof(oper_states)/sizeof(oper_states[0]); i++)
139		if (strcasecmp(name, oper_states[i]) == 0)
140			return i;
141	return -1;
142}
143
144static void print_queuelen(FILE *f, struct rtattr *tb[IFLA_MAX + 1])
145{
146	int qlen;
147
148	if (tb[IFLA_TXQLEN])
149		qlen = *(int *)RTA_DATA(tb[IFLA_TXQLEN]);
150	else {
151		struct ifreq ifr;
152		int s = socket(AF_INET, SOCK_STREAM, 0);
153
154		if (s < 0)
155			return;
156
157		memset(&ifr, 0, sizeof(ifr));
158		strcpy(ifr.ifr_name, rta_getattr_str(tb[IFLA_IFNAME]));
159		if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) {
160			fprintf(f, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno));
161			close(s);
162			return;
163		}
164		close(s);
165		qlen = ifr.ifr_qlen;
166	}
167	if (qlen)
168		fprintf(f, "qlen %d", qlen);
169}
170
171static const char *link_modes[] = {
172	"DEFAULT", "DORMANT"
173};
174
175static void print_linkmode(FILE *f, struct rtattr *tb)
176{
177	unsigned int mode = rta_getattr_u8(tb);
178
179	if (mode >= sizeof(link_modes) / sizeof(link_modes[0]))
180		fprintf(f, "mode %d ", mode);
181	else
182		fprintf(f, "mode %s ", link_modes[mode]);
183}
184
185static void print_linktype(FILE *fp, struct rtattr *tb)
186{
187	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
188	struct link_util *lu;
189	char *kind;
190
191	parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb);
192
193	if (!linkinfo[IFLA_INFO_KIND])
194		return;
195	kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]);
196
197	fprintf(fp, "%s", _SL_);
198	fprintf(fp, "    %s ", kind);
199
200	lu = get_link_kind(kind);
201	if (!lu || !lu->print_opt)
202		return;
203
204	if (1) {
205		struct rtattr *attr[lu->maxattr+1], **data = NULL;
206
207		if (linkinfo[IFLA_INFO_DATA]) {
208			parse_rtattr_nested(attr, lu->maxattr,
209					    linkinfo[IFLA_INFO_DATA]);
210			data = attr;
211		}
212		lu->print_opt(lu, fp, data);
213
214		if (linkinfo[IFLA_INFO_XSTATS] && show_stats &&
215		    lu->print_xstats)
216			lu->print_xstats(lu, fp, linkinfo[IFLA_INFO_XSTATS]);
217	}
218}
219
220static void print_vfinfo(FILE *fp, struct rtattr *vfinfo)
221{
222	struct ifla_vf_mac *vf_mac;
223	struct ifla_vf_vlan *vf_vlan;
224	struct ifla_vf_tx_rate *vf_tx_rate;
225	struct ifla_vf_spoofchk *vf_spoofchk;
226	struct rtattr *vf[IFLA_VF_MAX+1];
227	struct rtattr *tmp;
228	SPRINT_BUF(b1);
229
230	if (vfinfo->rta_type != IFLA_VF_INFO) {
231		fprintf(stderr, "BUG: rta type is %d\n", vfinfo->rta_type);
232		return;
233	}
234
235	parse_rtattr_nested(vf, IFLA_VF_MAX, vfinfo);
236
237	vf_mac = RTA_DATA(vf[IFLA_VF_MAC]);
238	vf_vlan = RTA_DATA(vf[IFLA_VF_VLAN]);
239	vf_tx_rate = RTA_DATA(vf[IFLA_VF_TX_RATE]);
240
241	/* Check if the spoof checking vf info type is supported by
242	 * this kernel.
243	 */
244	tmp = (struct rtattr *)((char *)vf[IFLA_VF_TX_RATE] +
245			vf[IFLA_VF_TX_RATE]->rta_len);
246
247	if (tmp->rta_type != IFLA_VF_SPOOFCHK)
248		vf_spoofchk = NULL;
249	else
250		vf_spoofchk = RTA_DATA(vf[IFLA_VF_SPOOFCHK]);
251
252	fprintf(fp, "\n    vf %d MAC %s", vf_mac->vf,
253		ll_addr_n2a((unsigned char *)&vf_mac->mac,
254		ETH_ALEN, 0, b1, sizeof(b1)));
255	if (vf_vlan->vlan)
256		fprintf(fp, ", vlan %d", vf_vlan->vlan);
257	if (vf_vlan->qos)
258		fprintf(fp, ", qos %d", vf_vlan->qos);
259	if (vf_tx_rate->rate)
260		fprintf(fp, ", tx rate %d (Mbps)", vf_tx_rate->rate);
261	if (vf_spoofchk && vf_spoofchk->setting != -1) {
262		if (vf_spoofchk->setting)
263			fprintf(fp, ", spoof checking on");
264		else
265			fprintf(fp, ", spoof checking off");
266	}
267}
268
269static void print_link_stats64(FILE *fp, const struct rtnl_link_stats64 *s) {
270	fprintf(fp, "%s", _SL_);
271	fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
272		s->rx_compressed ? "compressed" : "", _SL_);
273	fprintf(fp, "    %-10"PRIu64" %-8"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"",
274		(uint64_t)s->rx_bytes,
275		(uint64_t)s->rx_packets,
276		(uint64_t)s->rx_errors,
277		(uint64_t)s->rx_dropped,
278		(uint64_t)s->rx_over_errors,
279		(uint64_t)s->multicast);
280	if (s->rx_compressed)
281		fprintf(fp, " %-7"PRIu64"",
282			(uint64_t)s->rx_compressed);
283	if (show_stats > 1) {
284		fprintf(fp, "%s", _SL_);
285		fprintf(fp, "    RX errors: length  crc     frame   fifo    missed%s", _SL_);
286		fprintf(fp, "               %-7"PRIu64"  %-7"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"",
287			(uint64_t)s->rx_length_errors,
288			(uint64_t)s->rx_crc_errors,
289			(uint64_t)s->rx_frame_errors,
290			(uint64_t)s->rx_fifo_errors,
291			(uint64_t)s->rx_missed_errors);
292	}
293	fprintf(fp, "%s", _SL_);
294	fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
295		(uint64_t)s->tx_compressed ? "compressed" : "", _SL_);
296	fprintf(fp, "    %-10"PRIu64" %-8"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"",
297		(uint64_t)s->tx_bytes,
298		(uint64_t)s->tx_packets,
299		(uint64_t)s->tx_errors,
300		(uint64_t)s->tx_dropped,
301		(uint64_t)s->tx_carrier_errors,
302		(uint64_t)s->collisions);
303	if (s->tx_compressed)
304		fprintf(fp, " %-7"PRIu64"",
305			(uint64_t)s->tx_compressed);
306	if (show_stats > 1) {
307		fprintf(fp, "%s", _SL_);
308		fprintf(fp, "    TX errors: aborted fifo    window  heartbeat%s", _SL_);
309		fprintf(fp, "               %-7"PRIu64"  %-7"PRIu64" %-7"PRIu64" %-7"PRIu64"",
310			(uint64_t)s->tx_aborted_errors,
311			(uint64_t)s->tx_fifo_errors,
312			(uint64_t)s->tx_window_errors,
313			(uint64_t)s->tx_heartbeat_errors);
314	}
315}
316
317static void print_link_stats(FILE *fp, const struct rtnl_link_stats *s)
318{
319	fprintf(fp, "%s", _SL_);
320	fprintf(fp, "    RX: bytes  packets  errors  dropped overrun mcast   %s%s",
321		s->rx_compressed ? "compressed" : "", _SL_);
322	fprintf(fp, "    %-10u %-8u %-7u %-7u %-7u %-7u",
323		s->rx_bytes, s->rx_packets, s->rx_errors,
324		s->rx_dropped, s->rx_over_errors,
325		s->multicast
326		);
327	if (s->rx_compressed)
328		fprintf(fp, " %-7u", s->rx_compressed);
329	if (show_stats > 1) {
330		fprintf(fp, "%s", _SL_);
331		fprintf(fp, "    RX errors: length  crc     frame   fifo    missed%s", _SL_);
332		fprintf(fp, "               %-7u  %-7u %-7u %-7u %-7u",
333			s->rx_length_errors,
334			s->rx_crc_errors,
335			s->rx_frame_errors,
336			s->rx_fifo_errors,
337			s->rx_missed_errors
338			);
339	}
340	fprintf(fp, "%s", _SL_);
341	fprintf(fp, "    TX: bytes  packets  errors  dropped carrier collsns %s%s",
342		s->tx_compressed ? "compressed" : "", _SL_);
343	fprintf(fp, "    %-10u %-8u %-7u %-7u %-7u %-7u",
344		s->tx_bytes, s->tx_packets, s->tx_errors,
345		s->tx_dropped, s->tx_carrier_errors, s->collisions);
346	if (s->tx_compressed)
347		fprintf(fp, " %-7u", s->tx_compressed);
348	if (show_stats > 1) {
349		fprintf(fp, "%s", _SL_);
350		fprintf(fp, "    TX errors: aborted fifo    window  heartbeat%s", _SL_);
351		fprintf(fp, "               %-7u  %-7u %-7u %-7u",
352			s->tx_aborted_errors,
353			s->tx_fifo_errors,
354			s->tx_window_errors,
355			s->tx_heartbeat_errors
356			);
357	}
358}
359
360int print_linkinfo(const struct sockaddr_nl *who,
361		   struct nlmsghdr *n, void *arg)
362{
363	FILE *fp = (FILE*)arg;
364	struct ifinfomsg *ifi = NLMSG_DATA(n);
365	struct rtattr * tb[IFLA_MAX+1];
366	int len = n->nlmsg_len;
367	unsigned m_flag = 0;
368
369	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
370		return 0;
371
372	len -= NLMSG_LENGTH(sizeof(*ifi));
373	if (len < 0)
374		return -1;
375
376	if (filter.ifindex && ifi->ifi_index != filter.ifindex)
377		return 0;
378	if (filter.up && !(ifi->ifi_flags&IFF_UP))
379		return 0;
380
381	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
382	if (tb[IFLA_IFNAME] == NULL) {
383		fprintf(stderr, "BUG: device with ifindex %d has nil ifname\n", ifi->ifi_index);
384	}
385	if (filter.label &&
386	    (!filter.family || filter.family == AF_PACKET) &&
387	    fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0))
388		return 0;
389
390	if (tb[IFLA_GROUP]) {
391		int group = *(int*)RTA_DATA(tb[IFLA_GROUP]);
392		if (group != filter.group)
393			return -1;
394	}
395
396	if (n->nlmsg_type == RTM_DELLINK)
397		fprintf(fp, "Deleted ");
398
399	fprintf(fp, "%d: %s", ifi->ifi_index,
400		tb[IFLA_IFNAME] ? rta_getattr_str(tb[IFLA_IFNAME]) : "<nil>");
401
402	if (tb[IFLA_LINK]) {
403		SPRINT_BUF(b1);
404		int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]);
405		if (iflink == 0)
406			fprintf(fp, "@NONE: ");
407		else {
408			fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1));
409			m_flag = ll_index_to_flags(iflink);
410			m_flag = !(m_flag & IFF_UP);
411		}
412	} else {
413		fprintf(fp, ": ");
414	}
415	print_link_flags(fp, ifi->ifi_flags, m_flag);
416
417	if (tb[IFLA_MTU])
418		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
419	if (tb[IFLA_QDISC])
420		fprintf(fp, "qdisc %s ", rta_getattr_str(tb[IFLA_QDISC]));
421	if (tb[IFLA_MASTER]) {
422		SPRINT_BUF(b1);
423		fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1));
424	}
425
426	if (tb[IFLA_OPERSTATE])
427		print_operstate(fp, rta_getattr_u8(tb[IFLA_OPERSTATE]));
428
429	if (do_link && tb[IFLA_LINKMODE])
430		print_linkmode(fp, tb[IFLA_LINKMODE]);
431
432	if (filter.showqueue)
433		print_queuelen(fp, tb);
434
435	if (!filter.family || filter.family == AF_PACKET) {
436		SPRINT_BUF(b1);
437		fprintf(fp, "%s", _SL_);
438		fprintf(fp, "    link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1)));
439
440		if (tb[IFLA_ADDRESS]) {
441			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]),
442						      RTA_PAYLOAD(tb[IFLA_ADDRESS]),
443						      ifi->ifi_type,
444						      b1, sizeof(b1)));
445		}
446		if (tb[IFLA_BROADCAST]) {
447			if (ifi->ifi_flags&IFF_POINTOPOINT)
448				fprintf(fp, " peer ");
449			else
450				fprintf(fp, " brd ");
451			fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]),
452						      RTA_PAYLOAD(tb[IFLA_BROADCAST]),
453						      ifi->ifi_type,
454						      b1, sizeof(b1)));
455		}
456	}
457
458	if (do_link && tb[IFLA_LINKINFO] && show_details)
459		print_linktype(fp, tb[IFLA_LINKINFO]);
460
461	if (do_link && tb[IFLA_IFALIAS])
462		fprintf(fp,"\n    alias %s",
463			rta_getattr_str(tb[IFLA_IFALIAS]));
464
465	if (do_link && show_stats) {
466		if (tb[IFLA_STATS64])
467			print_link_stats64(fp, RTA_DATA(tb[IFLA_STATS64]));
468		else if (tb[IFLA_STATS])
469			print_link_stats(fp, RTA_DATA(tb[IFLA_STATS]));
470	}
471
472	if (do_link && tb[IFLA_VFINFO_LIST] && tb[IFLA_NUM_VF]) {
473		struct rtattr *i, *vflist = tb[IFLA_VFINFO_LIST];
474		int rem = RTA_PAYLOAD(vflist);
475		for (i = RTA_DATA(vflist); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
476			print_vfinfo(fp, i);
477	}
478
479	fprintf(fp, "\n");
480	fflush(fp);
481	return 0;
482}
483
484static int flush_update(void)
485{
486	if (rtnl_send_check(&rth, filter.flushb, filter.flushp) < 0) {
487		perror("Failed to send flush request");
488		return -1;
489	}
490	filter.flushp = 0;
491	return 0;
492}
493
494static int set_lifetime(unsigned int *lifetime, char *argv)
495{
496	if (strcmp(argv, "forever") == 0)
497		*lifetime = INFINITY_LIFE_TIME;
498	else if (get_u32(lifetime, argv, 0))
499		return -1;
500
501	return 0;
502}
503
504int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
505		   void *arg)
506{
507	FILE *fp = (FILE*)arg;
508	struct ifaddrmsg *ifa = NLMSG_DATA(n);
509	int len = n->nlmsg_len;
510	int deprecated = 0;
511	/* Use local copy of ifa_flags to not interfere with filtering code */
512	unsigned int ifa_flags;
513	struct rtattr * rta_tb[IFA_MAX+1];
514	char abuf[256];
515	SPRINT_BUF(b1);
516
517	if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR)
518		return 0;
519	len -= NLMSG_LENGTH(sizeof(*ifa));
520	if (len < 0) {
521		fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
522		return -1;
523	}
524
525	if (filter.flushb && n->nlmsg_type != RTM_NEWADDR)
526		return 0;
527
528	parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa)));
529
530	if (!rta_tb[IFA_LOCAL])
531		rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
532	if (!rta_tb[IFA_ADDRESS])
533		rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL];
534
535	if (filter.ifindex && filter.ifindex != ifa->ifa_index)
536		return 0;
537	if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
538		return 0;
539	if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
540		return 0;
541	if (filter.label) {
542		SPRINT_BUF(b1);
543		const char *label;
544		if (rta_tb[IFA_LABEL])
545			label = RTA_DATA(rta_tb[IFA_LABEL]);
546		else
547			label = ll_idx_n2a(ifa->ifa_index, b1);
548		if (fnmatch(filter.label, label, 0) != 0)
549			return 0;
550	}
551	if (filter.pfx.family) {
552		if (rta_tb[IFA_LOCAL]) {
553			inet_prefix dst;
554			memset(&dst, 0, sizeof(dst));
555			dst.family = ifa->ifa_family;
556			memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL]));
557			if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
558				return 0;
559		}
560	}
561
562	if (filter.family && filter.family != ifa->ifa_family)
563		return 0;
564
565	if (filter.flushb) {
566		struct nlmsghdr *fn;
567		if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
568			if (flush_update())
569				return -1;
570		}
571		fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
572		memcpy(fn, n, n->nlmsg_len);
573		fn->nlmsg_type = RTM_DELADDR;
574		fn->nlmsg_flags = NLM_F_REQUEST;
575		fn->nlmsg_seq = ++rth.seq;
576		filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
577		filter.flushed++;
578		if (show_stats < 2)
579			return 0;
580	}
581
582	if (n->nlmsg_type == RTM_DELADDR)
583		fprintf(fp, "Deleted ");
584
585	if (filter.oneline || filter.flushb)
586		fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index));
587	if (ifa->ifa_family == AF_INET)
588		fprintf(fp, "    inet ");
589	else if (ifa->ifa_family == AF_INET6)
590		fprintf(fp, "    inet6 ");
591	else if (ifa->ifa_family == AF_DECnet)
592		fprintf(fp, "    dnet ");
593	else if (ifa->ifa_family == AF_IPX)
594		fprintf(fp, "     ipx ");
595	else
596		fprintf(fp, "    family %d ", ifa->ifa_family);
597
598	if (rta_tb[IFA_LOCAL]) {
599		fprintf(fp, "%s", rt_addr_n2a(ifa->ifa_family,
600					      RTA_PAYLOAD(rta_tb[IFA_LOCAL]),
601					      RTA_DATA(rta_tb[IFA_LOCAL]),
602					      abuf, sizeof(abuf)));
603
604		if (rta_tb[IFA_ADDRESS] == NULL ||
605		    memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) {
606			fprintf(fp, "/%d ", ifa->ifa_prefixlen);
607		} else {
608			fprintf(fp, " peer %s/%d ",
609				rt_addr_n2a(ifa->ifa_family,
610					    RTA_PAYLOAD(rta_tb[IFA_ADDRESS]),
611					    RTA_DATA(rta_tb[IFA_ADDRESS]),
612					    abuf, sizeof(abuf)),
613				ifa->ifa_prefixlen);
614		}
615	}
616
617	if (rta_tb[IFA_BROADCAST]) {
618		fprintf(fp, "brd %s ",
619			rt_addr_n2a(ifa->ifa_family,
620				    RTA_PAYLOAD(rta_tb[IFA_BROADCAST]),
621				    RTA_DATA(rta_tb[IFA_BROADCAST]),
622				    abuf, sizeof(abuf)));
623	}
624	if (rta_tb[IFA_ANYCAST]) {
625		fprintf(fp, "any %s ",
626			rt_addr_n2a(ifa->ifa_family,
627				    RTA_PAYLOAD(rta_tb[IFA_ANYCAST]),
628				    RTA_DATA(rta_tb[IFA_ANYCAST]),
629				    abuf, sizeof(abuf)));
630	}
631	fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1)));
632	ifa_flags = ifa->ifa_flags;
633	if (ifa->ifa_flags&IFA_F_SECONDARY) {
634		ifa_flags &= ~IFA_F_SECONDARY;
635		if (ifa->ifa_family == AF_INET6)
636			fprintf(fp, "temporary ");
637		else
638			fprintf(fp, "secondary ");
639	}
640	if (ifa->ifa_flags&IFA_F_TENTATIVE) {
641		ifa_flags &= ~IFA_F_TENTATIVE;
642		fprintf(fp, "tentative ");
643	}
644	if (ifa->ifa_flags&IFA_F_DEPRECATED) {
645		ifa_flags &= ~IFA_F_DEPRECATED;
646		deprecated = 1;
647		fprintf(fp, "deprecated ");
648	}
649	if (ifa->ifa_flags&IFA_F_HOMEADDRESS) {
650		ifa_flags &= ~IFA_F_HOMEADDRESS;
651		fprintf(fp, "home ");
652	}
653	if (ifa->ifa_flags&IFA_F_NODAD) {
654		ifa_flags &= ~IFA_F_NODAD;
655		fprintf(fp, "nodad ");
656	}
657	if (!(ifa->ifa_flags&IFA_F_PERMANENT)) {
658		fprintf(fp, "dynamic ");
659	} else
660		ifa_flags &= ~IFA_F_PERMANENT;
661	if (ifa->ifa_flags&IFA_F_DADFAILED) {
662		ifa_flags &= ~IFA_F_DADFAILED;
663		fprintf(fp, "dadfailed ");
664	}
665	if (ifa_flags)
666		fprintf(fp, "flags %02x ", ifa_flags);
667	if (rta_tb[IFA_LABEL])
668		fprintf(fp, "%s", rta_getattr_str(rta_tb[IFA_LABEL]));
669	if (rta_tb[IFA_CACHEINFO]) {
670		struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]);
671		fprintf(fp, "%s", _SL_);
672		fprintf(fp, "       valid_lft ");
673		if (ci->ifa_valid == INFINITY_LIFE_TIME)
674			fprintf(fp, "forever");
675		else
676			fprintf(fp, "%usec", ci->ifa_valid);
677		fprintf(fp, " preferred_lft ");
678		if (ci->ifa_prefered == INFINITY_LIFE_TIME)
679			fprintf(fp, "forever");
680		else {
681			if (deprecated)
682				fprintf(fp, "%dsec", ci->ifa_prefered);
683			else
684				fprintf(fp, "%usec", ci->ifa_prefered);
685		}
686	}
687	fprintf(fp, "\n");
688	fflush(fp);
689	return 0;
690}
691
692int print_addrinfo_primary(const struct sockaddr_nl *who, struct nlmsghdr *n,
693			   void *arg)
694{
695	struct ifaddrmsg *ifa = NLMSG_DATA(n);
696
697	if (ifa->ifa_flags & IFA_F_SECONDARY)
698		return 0;
699
700	return print_addrinfo(who, n, arg);
701}
702
703int print_addrinfo_secondary(const struct sockaddr_nl *who, struct nlmsghdr *n,
704			     void *arg)
705{
706	struct ifaddrmsg *ifa = NLMSG_DATA(n);
707
708	if (!(ifa->ifa_flags & IFA_F_SECONDARY))
709		return 0;
710
711	return print_addrinfo(who, n, arg);
712}
713
714struct nlmsg_list
715{
716	struct nlmsg_list *next;
717	struct nlmsghdr	  h;
718};
719
720static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp)
721{
722	for ( ;ainfo ;  ainfo = ainfo->next) {
723		struct nlmsghdr *n = &ainfo->h;
724		struct ifaddrmsg *ifa = NLMSG_DATA(n);
725
726		if (n->nlmsg_type != RTM_NEWADDR)
727			continue;
728
729		if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa)))
730			return -1;
731
732		if (ifa->ifa_index != ifindex ||
733		    (filter.family && filter.family != ifa->ifa_family))
734			continue;
735
736		print_addrinfo(NULL, n, fp);
737	}
738	return 0;
739}
740
741
742static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n,
743		       void *arg)
744{
745	struct nlmsg_list **linfo = (struct nlmsg_list**)arg;
746	struct nlmsg_list *h;
747	struct nlmsg_list **lp;
748
749	h = malloc(n->nlmsg_len+sizeof(void*));
750	if (h == NULL)
751		return -1;
752
753	memcpy(&h->h, n, n->nlmsg_len);
754	h->next = NULL;
755
756	for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */;
757	*lp = h;
758
759	ll_remember_index(who, n, NULL);
760	return 0;
761}
762
763static int ipaddr_list_or_flush(int argc, char **argv, int flush)
764{
765	struct nlmsg_list *linfo = NULL;
766	struct nlmsg_list *ainfo = NULL;
767	struct nlmsg_list *l, *n;
768	char *filter_dev = NULL;
769	int no_link = 0;
770
771	ipaddr_reset_filter(oneline);
772	filter.showqueue = 1;
773
774	if (filter.family == AF_UNSPEC)
775		filter.family = preferred_family;
776
777	filter.group = INIT_NETDEV_GROUP;
778
779	if (flush) {
780		if (argc <= 0) {
781			fprintf(stderr, "Flush requires arguments.\n");
782
783			return -1;
784		}
785		if (filter.family == AF_PACKET) {
786			fprintf(stderr, "Cannot flush link addresses.\n");
787			return -1;
788		}
789	}
790
791	while (argc > 0) {
792		if (strcmp(*argv, "to") == 0) {
793			NEXT_ARG();
794			get_prefix(&filter.pfx, *argv, filter.family);
795			if (filter.family == AF_UNSPEC)
796				filter.family = filter.pfx.family;
797		} else if (strcmp(*argv, "scope") == 0) {
798			unsigned scope = 0;
799			NEXT_ARG();
800			filter.scopemask = -1;
801			if (rtnl_rtscope_a2n(&scope, *argv)) {
802				if (strcmp(*argv, "all") != 0)
803					invarg("invalid \"scope\"\n", *argv);
804				scope = RT_SCOPE_NOWHERE;
805				filter.scopemask = 0;
806			}
807			filter.scope = scope;
808		} else if (strcmp(*argv, "up") == 0) {
809			filter.up = 1;
810		} else if (strcmp(*argv, "dynamic") == 0) {
811			filter.flags &= ~IFA_F_PERMANENT;
812			filter.flagmask |= IFA_F_PERMANENT;
813		} else if (strcmp(*argv, "permanent") == 0) {
814			filter.flags |= IFA_F_PERMANENT;
815			filter.flagmask |= IFA_F_PERMANENT;
816		} else if (strcmp(*argv, "secondary") == 0 ||
817			   strcmp(*argv, "temporary") == 0) {
818			filter.flags |= IFA_F_SECONDARY;
819			filter.flagmask |= IFA_F_SECONDARY;
820		} else if (strcmp(*argv, "primary") == 0) {
821			filter.flags &= ~IFA_F_SECONDARY;
822			filter.flagmask |= IFA_F_SECONDARY;
823		} else if (strcmp(*argv, "tentative") == 0) {
824			filter.flags |= IFA_F_TENTATIVE;
825			filter.flagmask |= IFA_F_TENTATIVE;
826		} else if (strcmp(*argv, "deprecated") == 0) {
827			filter.flags |= IFA_F_DEPRECATED;
828			filter.flagmask |= IFA_F_DEPRECATED;
829		} else if (strcmp(*argv, "home") == 0) {
830			filter.flags |= IFA_F_HOMEADDRESS;
831			filter.flagmask |= IFA_F_HOMEADDRESS;
832		} else if (strcmp(*argv, "nodad") == 0) {
833			filter.flags |= IFA_F_NODAD;
834			filter.flagmask |= IFA_F_NODAD;
835		} else if (strcmp(*argv, "dadfailed") == 0) {
836			filter.flags |= IFA_F_DADFAILED;
837			filter.flagmask |= IFA_F_DADFAILED;
838		} else if (strcmp(*argv, "label") == 0) {
839			NEXT_ARG();
840			filter.label = *argv;
841		} else if (strcmp(*argv, "group") == 0) {
842			NEXT_ARG();
843			if (rtnl_group_a2n(&filter.group, *argv))
844				invarg("Invalid \"group\" value\n", *argv);
845		} else {
846			if (strcmp(*argv, "dev") == 0) {
847				NEXT_ARG();
848			}
849			if (matches(*argv, "help") == 0)
850				usage();
851			if (filter_dev)
852				duparg2("dev", *argv);
853			filter_dev = *argv;
854		}
855		argv++; argc--;
856	}
857
858	if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) {
859		perror("Cannot send dump request");
860		exit(1);
861	}
862
863	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo) < 0) {
864		fprintf(stderr, "Dump terminated\n");
865		exit(1);
866	}
867
868	if (filter_dev) {
869		filter.ifindex = ll_name_to_index(filter_dev);
870		if (filter.ifindex <= 0) {
871			fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev);
872			return -1;
873		}
874	}
875
876	if (flush) {
877		int round = 0;
878		char flushb[4096-512];
879
880		filter.flushb = flushb;
881		filter.flushp = 0;
882		filter.flushe = sizeof(flushb);
883
884		while ((max_flush_loops == 0) || (round < max_flush_loops)) {
885			const struct rtnl_dump_filter_arg a[3] = {
886				{
887					.filter = print_addrinfo_secondary,
888					.arg1 = stdout,
889				},
890				{
891					.filter = print_addrinfo_primary,
892					.arg1 = stdout,
893				},
894				{
895					.filter = NULL,
896					.arg1 = NULL,
897				},
898			};
899			if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
900				perror("Cannot send dump request");
901				exit(1);
902			}
903			filter.flushed = 0;
904			if (rtnl_dump_filter_l(&rth, a) < 0) {
905				fprintf(stderr, "Flush terminated\n");
906				exit(1);
907			}
908			if (filter.flushed == 0) {
909flush_done:
910				if (show_stats) {
911					if (round == 0)
912						printf("Nothing to flush.\n");
913					else
914						printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":"");
915				}
916				fflush(stdout);
917				return 0;
918			}
919			round++;
920			if (flush_update() < 0)
921				return 1;
922
923			if (show_stats) {
924				printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed);
925				fflush(stdout);
926			}
927
928			/* If we are flushing, and specifying primary, then we
929			 * want to flush only a single round.  Otherwise, we'll
930			 * start flushing secondaries that were promoted to
931			 * primaries.
932			 */
933			if (!(filter.flags & IFA_F_SECONDARY) && (filter.flagmask & IFA_F_SECONDARY))
934				goto flush_done;
935		}
936		fprintf(stderr, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops);
937		fflush(stderr);
938		return 1;
939	}
940
941	if (filter.family != AF_PACKET) {
942		if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {
943			perror("Cannot send dump request");
944			exit(1);
945		}
946
947		if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo) < 0) {
948			fprintf(stderr, "Dump terminated\n");
949			exit(1);
950		}
951	}
952
953
954	if (filter.family && filter.family != AF_PACKET) {
955		struct nlmsg_list **lp;
956		lp=&linfo;
957
958		if (filter.oneline)
959			no_link = 1;
960
961		while ((l=*lp)!=NULL) {
962			int ok = 0;
963			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
964			struct nlmsg_list *a;
965
966			for (a=ainfo; a; a=a->next) {
967				struct nlmsghdr *n = &a->h;
968				struct ifaddrmsg *ifa = NLMSG_DATA(n);
969
970				if (ifa->ifa_index != ifi->ifi_index ||
971				    (filter.family && filter.family != ifa->ifa_family))
972					continue;
973				if ((filter.scope^ifa->ifa_scope)&filter.scopemask)
974					continue;
975				if ((filter.flags^ifa->ifa_flags)&filter.flagmask)
976					continue;
977				if (filter.pfx.family || filter.label) {
978					struct rtattr *tb[IFA_MAX+1];
979					parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));
980					if (!tb[IFA_LOCAL])
981						tb[IFA_LOCAL] = tb[IFA_ADDRESS];
982
983					if (filter.pfx.family && tb[IFA_LOCAL]) {
984						inet_prefix dst;
985						memset(&dst, 0, sizeof(dst));
986						dst.family = ifa->ifa_family;
987						memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));
988						if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))
989							continue;
990					}
991					if (filter.label) {
992						SPRINT_BUF(b1);
993						const char *label;
994						if (tb[IFA_LABEL])
995							label = RTA_DATA(tb[IFA_LABEL]);
996						else
997							label = ll_idx_n2a(ifa->ifa_index, b1);
998						if (fnmatch(filter.label, label, 0) != 0)
999							continue;
1000					}
1001				}
1002
1003				ok = 1;
1004				break;
1005			}
1006			if (!ok)
1007				*lp = l->next;
1008			else
1009				lp = &l->next;
1010		}
1011	}
1012
1013	for (l=linfo; l; l = n) {
1014		n = l->next;
1015		if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {
1016			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);
1017			if (filter.family != AF_PACKET)
1018				print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);
1019		}
1020		fflush(stdout);
1021		free(l);
1022	}
1023
1024	return 0;
1025}
1026
1027int ipaddr_list_link(int argc, char **argv)
1028{
1029	preferred_family = AF_PACKET;
1030	do_link = 1;
1031	return ipaddr_list_or_flush(argc, argv, 0);
1032}
1033
1034void ipaddr_reset_filter(int oneline)
1035{
1036	memset(&filter, 0, sizeof(filter));
1037	filter.oneline = oneline;
1038}
1039
1040static int default_scope(inet_prefix *lcl)
1041{
1042	if (lcl->family == AF_INET) {
1043		if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127)
1044			return RT_SCOPE_HOST;
1045	}
1046	return 0;
1047}
1048
1049static int ipaddr_modify(int cmd, int flags, int argc, char **argv)
1050{
1051	struct {
1052		struct nlmsghdr 	n;
1053		struct ifaddrmsg 	ifa;
1054		char   			buf[256];
1055	} req;
1056	char  *d = NULL;
1057	char  *l = NULL;
1058	char  *lcl_arg = NULL;
1059	char  *valid_lftp = NULL;
1060	char  *preferred_lftp = NULL;
1061	inet_prefix lcl;
1062	inet_prefix peer;
1063	int local_len = 0;
1064	int peer_len = 0;
1065	int brd_len = 0;
1066	int any_len = 0;
1067	int scoped = 0;
1068	__u32 preferred_lft = INFINITY_LIFE_TIME;
1069	__u32 valid_lft = INFINITY_LIFE_TIME;
1070	struct ifa_cacheinfo cinfo;
1071
1072	memset(&req, 0, sizeof(req));
1073
1074	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
1075	req.n.nlmsg_flags = NLM_F_REQUEST | flags;
1076	req.n.nlmsg_type = cmd;
1077	req.ifa.ifa_family = preferred_family;
1078
1079	while (argc > 0) {
1080		if (strcmp(*argv, "peer") == 0 ||
1081		    strcmp(*argv, "remote") == 0) {
1082			NEXT_ARG();
1083
1084			if (peer_len)
1085				duparg("peer", *argv);
1086			get_prefix(&peer, *argv, req.ifa.ifa_family);
1087			peer_len = peer.bytelen;
1088			if (req.ifa.ifa_family == AF_UNSPEC)
1089				req.ifa.ifa_family = peer.family;
1090			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);
1091			req.ifa.ifa_prefixlen = peer.bitlen;
1092		} else if (matches(*argv, "broadcast") == 0 ||
1093			   strcmp(*argv, "brd") == 0) {
1094			inet_prefix addr;
1095			NEXT_ARG();
1096			if (brd_len)
1097				duparg("broadcast", *argv);
1098			if (strcmp(*argv, "+") == 0)
1099				brd_len = -1;
1100			else if (strcmp(*argv, "-") == 0)
1101				brd_len = -2;
1102			else {
1103				get_addr(&addr, *argv, req.ifa.ifa_family);
1104				if (req.ifa.ifa_family == AF_UNSPEC)
1105					req.ifa.ifa_family = addr.family;
1106				addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);
1107				brd_len = addr.bytelen;
1108			}
1109		} else if (strcmp(*argv, "anycast") == 0) {
1110			inet_prefix addr;
1111			NEXT_ARG();
1112			if (any_len)
1113				duparg("anycast", *argv);
1114			get_addr(&addr, *argv, req.ifa.ifa_family);
1115			if (req.ifa.ifa_family == AF_UNSPEC)
1116				req.ifa.ifa_family = addr.family;
1117			addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
1118			any_len = addr.bytelen;
1119		} else if (strcmp(*argv, "scope") == 0) {
1120			unsigned scope = 0;
1121			NEXT_ARG();
1122			if (rtnl_rtscope_a2n(&scope, *argv))
1123				invarg(*argv, "invalid scope value.");
1124			req.ifa.ifa_scope = scope;
1125			scoped = 1;
1126		} else if (strcmp(*argv, "dev") == 0) {
1127			NEXT_ARG();
1128			d = *argv;
1129		} else if (strcmp(*argv, "label") == 0) {
1130			NEXT_ARG();
1131			l = *argv;
1132			addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1);
1133		} else if (matches(*argv, "valid_lft") == 0) {
1134			if (valid_lftp)
1135				duparg("valid_lft", *argv);
1136			NEXT_ARG();
1137			valid_lftp = *argv;
1138			if (set_lifetime(&valid_lft, *argv))
1139				invarg("valid_lft value", *argv);
1140		} else if (matches(*argv, "preferred_lft") == 0) {
1141			if (preferred_lftp)
1142				duparg("preferred_lft", *argv);
1143			NEXT_ARG();
1144			preferred_lftp = *argv;
1145			if (set_lifetime(&preferred_lft, *argv))
1146				invarg("preferred_lft value", *argv);
1147		} else if (strcmp(*argv, "home") == 0) {
1148			req.ifa.ifa_flags |= IFA_F_HOMEADDRESS;
1149		} else if (strcmp(*argv, "nodad") == 0) {
1150			req.ifa.ifa_flags |= IFA_F_NODAD;
1151		} else {
1152			if (strcmp(*argv, "local") == 0) {
1153				NEXT_ARG();
1154			}
1155			if (matches(*argv, "help") == 0)
1156				usage();
1157			if (local_len)
1158				duparg2("local", *argv);
1159			lcl_arg = *argv;
1160			get_prefix(&lcl, *argv, req.ifa.ifa_family);
1161			if (req.ifa.ifa_family == AF_UNSPEC)
1162				req.ifa.ifa_family = lcl.family;
1163			addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);
1164			local_len = lcl.bytelen;
1165		}
1166		argc--; argv++;
1167	}
1168	if (d == NULL) {
1169		fprintf(stderr, "Not enough information: \"dev\" argument is required.\n");
1170		return -1;
1171	}
1172	if (l && matches(d, l) != 0) {
1173		fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l);
1174		return -1;
1175	}
1176
1177	if (peer_len == 0 && local_len) {
1178		if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) {
1179			fprintf(stderr,
1180			    "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1181			    "         Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1182			    "         This special behaviour is likely to disappear in further releases,\n" \
1183			    "         fix your scripts!\n", lcl_arg, local_len*8);
1184		} else {
1185			peer = lcl;
1186			addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen);
1187		}
1188	}
1189	if (req.ifa.ifa_prefixlen == 0)
1190		req.ifa.ifa_prefixlen = lcl.bitlen;
1191
1192	if (brd_len < 0 && cmd != RTM_DELADDR) {
1193		inet_prefix brd;
1194		int i;
1195		if (req.ifa.ifa_family != AF_INET) {
1196			fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n");
1197			return -1;
1198		}
1199		brd = peer;
1200		if (brd.bitlen <= 30) {
1201			for (i=31; i>=brd.bitlen; i--) {
1202				if (brd_len == -1)
1203					brd.data[0] |= htonl(1<<(31-i));
1204				else
1205					brd.data[0] &= ~htonl(1<<(31-i));
1206			}
1207			addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen);
1208			brd_len = brd.bytelen;
1209		}
1210	}
1211	if (!scoped && cmd != RTM_DELADDR)
1212		req.ifa.ifa_scope = default_scope(&lcl);
1213
1214	ll_init_map(&rth);
1215
1216	if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) {
1217		fprintf(stderr, "Cannot find device \"%s\"\n", d);
1218		return -1;
1219	}
1220
1221	if (valid_lftp || preferred_lftp) {
1222		if (!valid_lft) {
1223			fprintf(stderr, "valid_lft is zero\n");
1224			return -1;
1225		}
1226		if (valid_lft < preferred_lft) {
1227			fprintf(stderr, "preferred_lft is greater than valid_lft\n");
1228			return -1;
1229		}
1230
1231		memset(&cinfo, 0, sizeof(cinfo));
1232		cinfo.ifa_prefered = preferred_lft;
1233		cinfo.ifa_valid = valid_lft;
1234		addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo,
1235			  sizeof(cinfo));
1236	}
1237
1238	if (rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0)
1239		return -2;
1240
1241	return 0;
1242}
1243
1244int do_ipaddr(int argc, char **argv)
1245{
1246	if (argc < 1)
1247		return ipaddr_list_or_flush(0, NULL, 0);
1248	if (matches(*argv, "add") == 0)
1249		return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1);
1250	if (matches(*argv, "change") == 0 ||
1251		strcmp(*argv, "chg") == 0)
1252		return ipaddr_modify(RTM_NEWADDR, NLM_F_REPLACE, argc-1, argv+1);
1253	if (matches(*argv, "replace") == 0)
1254		return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1);
1255	if (matches(*argv, "delete") == 0)
1256		return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1);
1257	if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
1258	    || matches(*argv, "lst") == 0)
1259		return ipaddr_list_or_flush(argc-1, argv+1, 0);
1260	if (matches(*argv, "flush") == 0)
1261		return ipaddr_list_or_flush(argc-1, argv+1, 1);
1262	if (matches(*argv, "help") == 0)
1263		usage();
1264	fprintf(stderr, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv);
1265	exit(-1);
1266}
1267
1268