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