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