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 
38 static 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 
56 static int do_link;
57 
58 static void usage(void) __attribute__((noreturn));
59 
usage(void)60 static 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 
print_link_flags(FILE * fp,unsigned flags,unsigned mdown)86 void 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 
121 static const char *oper_states[] = {
122 	"UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
123 	"TESTING", "DORMANT",	 "UP"
124 };
125 
print_operstate(FILE * f,__u8 state)126 static 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 
get_operstate(const char * name)134 int 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 
print_queuelen(FILE * f,struct rtattr * tb[IFLA_MAX+1])144 static 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 
171 static const char *link_modes[] = {
172 	"DEFAULT", "DORMANT"
173 };
174 
print_linkmode(FILE * f,struct rtattr * tb)175 static 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 
print_linktype(FILE * fp,struct rtattr * tb)185 static 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 
print_vfinfo(FILE * fp,struct rtattr * vfinfo)220 static 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 
print_link_stats64(FILE * fp,const struct rtnl_link_stats64 * s)269 static 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 
print_link_stats(FILE * fp,const struct rtnl_link_stats * s)317 static 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 
print_linkinfo(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)360 int 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 
flush_update(void)484 static 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 
set_lifetime(unsigned int * lifetime,char * argv)494 static 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 
print_addrinfo(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)504 int 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 
print_addrinfo_primary(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)692 int 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 
print_addrinfo_secondary(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)703 int 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 
714 struct nlmsg_list
715 {
716 	struct nlmsg_list *next;
717 	struct nlmsghdr	  h;
718 };
719 
print_selected_addrinfo(int ifindex,struct nlmsg_list * ainfo,FILE * fp)720 static 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 
store_nlmsg(const struct sockaddr_nl * who,struct nlmsghdr * n,void * arg)742 static 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 
ipaddr_list_or_flush(int argc,char ** argv,int flush)763 static 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) {
909 flush_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 
ipaddr_list_link(int argc,char ** argv)1027 int 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 
ipaddr_reset_filter(int oneline)1034 void ipaddr_reset_filter(int oneline)
1035 {
1036 	memset(&filter, 0, sizeof(filter));
1037 	filter.oneline = oneline;
1038 }
1039 
default_scope(inet_prefix * lcl)1040 static 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 
ipaddr_modify(int cmd,int flags,int argc,char ** argv)1049 static 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 
do_ipaddr(int argc,char ** argv)1244 int 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