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