]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/ipaddress.c
2 * ipaddress.c "ip address".
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.
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
12 * Laszlo Valko <valko@linux.karinthy.hu> 990223: address label must be zero terminated
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
22 #include <sys/ioctl.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
28 #include <linux/netdevice.h>
29 #include <linux/if_arp.h>
30 #include <linux/sockios.h>
35 #include "ip_common.h"
56 static void usage(void) __attribute__((noreturn
));
58 static void usage(void)
63 fprintf(stderr
, "Usage: ip addr {add|del} IFADDR dev STRING\n");
64 fprintf(stderr
, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
65 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
66 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
67 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
68 fprintf(stderr
, " [ label STRING ] [ scope SCOPE-ID ]\n");
69 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
70 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
71 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
72 fprintf(stderr
, " tentative | deprecated ]\n");
76 void print_link_flags(FILE *fp
, unsigned flags
, unsigned mdown
)
79 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
80 fprintf(fp
, "NO-CARRIER%s", flags
? "," : "");
81 flags
&= ~IFF_RUNNING
;
82 #define _PF(f) if (flags&IFF_##f) { \
84 fprintf(fp, #f "%s", flags ? "," : ""); }
102 fprintf(fp
, "%x", flags
);
104 fprintf(fp
, ",M-DOWN");
108 void print_queuelen(char *name
)
113 s
= socket(AF_INET
, SOCK_STREAM
, 0);
117 memset(&ifr
, 0, sizeof(ifr
));
118 strcpy(ifr
.ifr_name
, name
);
119 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
120 perror("SIOCGIFXQLEN");
127 printf("qlen %d", ifr
.ifr_qlen
);
130 int print_linkinfo(const struct sockaddr_nl
*who
,
131 struct nlmsghdr
*n
, void *arg
)
133 FILE *fp
= (FILE*)arg
;
134 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
135 struct rtattr
* tb
[IFLA_MAX
+1];
136 int len
= n
->nlmsg_len
;
139 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
142 len
-= NLMSG_LENGTH(sizeof(*ifi
));
146 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
148 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
151 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
152 if (tb
[IFLA_IFNAME
] == NULL
) {
153 fprintf(stderr
, "BUG: nil ifname\n");
157 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
158 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
161 if (n
->nlmsg_type
== RTM_DELLINK
)
162 fprintf(fp
, "Deleted ");
164 fprintf(fp
, "%d: %s", ifi
->ifi_index
,
165 tb
[IFLA_IFNAME
] ? (char*)RTA_DATA(tb
[IFLA_IFNAME
]) : "<nil>");
169 int iflink
= *(int*)RTA_DATA(tb
[IFLA_LINK
]);
171 fprintf(fp
, "@NONE: ");
173 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
174 m_flag
= ll_index_to_flags(iflink
);
175 m_flag
= !(m_flag
& IFF_UP
);
180 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
183 fprintf(fp
, "mtu %u ", *(int*)RTA_DATA(tb
[IFLA_MTU
]));
185 fprintf(fp
, "qdisc %s ", (char*)RTA_DATA(tb
[IFLA_QDISC
]));
187 if (tb
[IFLA_MASTER
]) {
189 fprintf(fp
, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb
[IFLA_MASTER
]), b1
));
192 if (filter
.showqueue
)
193 print_queuelen((char*)RTA_DATA(tb
[IFLA_IFNAME
]));
195 if (!filter
.family
|| filter
.family
== AF_PACKET
) {
197 fprintf(fp
, "%s", _SL_
);
198 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
200 if (tb
[IFLA_ADDRESS
]) {
201 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
202 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
206 if (tb
[IFLA_BROADCAST
]) {
207 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
208 fprintf(fp
, " peer ");
210 fprintf(fp
, " brd ");
211 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
212 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
217 if (do_link
&& tb
[IFLA_STATS
] && show_stats
) {
218 struct rtnl_link_stats slocal
;
219 struct rtnl_link_stats
*s
= RTA_DATA(tb
[IFLA_STATS
]);
220 if (((unsigned long)s
) & (sizeof(unsigned long)-1)) {
221 memcpy(&slocal
, s
, sizeof(slocal
));
224 fprintf(fp
, "%s", _SL_
);
225 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
226 s
->rx_compressed
? "compressed" : "", _SL_
);
227 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
228 s
->rx_bytes
, s
->rx_packets
, s
->rx_errors
,
229 s
->rx_dropped
, s
->rx_over_errors
,
232 if (s
->rx_compressed
)
233 fprintf(fp
, " %-7u", s
->rx_compressed
);
234 if (show_stats
> 1) {
235 fprintf(fp
, "%s", _SL_
);
236 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
237 fprintf(fp
, " %-7u %-7u %-7u %-7u %-7u",
245 fprintf(fp
, "%s", _SL_
);
246 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
247 s
->tx_compressed
? "compressed" : "", _SL_
);
248 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
249 s
->tx_bytes
, s
->tx_packets
, s
->tx_errors
,
250 s
->tx_dropped
, s
->tx_carrier_errors
, s
->collisions
);
251 if (s
->tx_compressed
)
252 fprintf(fp
, " %-7u", s
->tx_compressed
);
253 if (show_stats
> 1) {
254 fprintf(fp
, "%s", _SL_
);
255 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
256 fprintf(fp
, " %-7u %-7u %-7u %-7u",
257 s
->tx_aborted_errors
,
260 s
->tx_heartbeat_errors
269 static int flush_update(void)
271 if (rtnl_send(&rth
, filter
.flushb
, filter
.flushp
) < 0) {
272 perror("Failed to send flush request\n");
279 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
282 FILE *fp
= (FILE*)arg
;
283 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
284 int len
= n
->nlmsg_len
;
285 struct rtattr
* rta_tb
[IFA_MAX
+1];
289 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
291 len
-= NLMSG_LENGTH(sizeof(*ifa
));
293 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
297 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
300 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
), n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
302 if (!rta_tb
[IFA_LOCAL
])
303 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
304 if (!rta_tb
[IFA_ADDRESS
])
305 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
307 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
309 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
311 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
316 if (rta_tb
[IFA_LABEL
])
317 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
319 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
320 if (fnmatch(filter
.label
, label
, 0) != 0)
323 if (filter
.pfx
.family
) {
324 if (rta_tb
[IFA_LOCAL
]) {
326 memset(&dst
, 0, sizeof(dst
));
327 dst
.family
= ifa
->ifa_family
;
328 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
329 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
334 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
339 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
343 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
344 memcpy(fn
, n
, n
->nlmsg_len
);
345 fn
->nlmsg_type
= RTM_DELADDR
;
346 fn
->nlmsg_flags
= NLM_F_REQUEST
;
347 fn
->nlmsg_seq
= ++rth
.seq
;
348 filter
.flushp
= (((char*)fn
) + n
->nlmsg_len
) - filter
.flushb
;
354 if (n
->nlmsg_type
== RTM_DELADDR
)
355 fprintf(fp
, "Deleted ");
357 if (filter
.oneline
|| filter
.flushb
)
358 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
359 if (ifa
->ifa_family
== AF_INET
)
360 fprintf(fp
, " inet ");
361 else if (ifa
->ifa_family
== AF_INET6
)
362 fprintf(fp
, " inet6 ");
363 else if (ifa
->ifa_family
== AF_DECnet
)
364 fprintf(fp
, " dnet ");
365 else if (ifa
->ifa_family
== AF_IPX
)
366 fprintf(fp
, " ipx ");
368 fprintf(fp
, " family %d ", ifa
->ifa_family
);
370 if (rta_tb
[IFA_LOCAL
]) {
371 fprintf(fp
, "%s", rt_addr_n2a(ifa
->ifa_family
,
372 RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]),
373 RTA_DATA(rta_tb
[IFA_LOCAL
]),
374 abuf
, sizeof(abuf
)));
376 if (rta_tb
[IFA_ADDRESS
] == NULL
||
377 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]), RTA_DATA(rta_tb
[IFA_LOCAL
]), 4) == 0) {
378 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
380 fprintf(fp
, " peer %s/%d ",
381 rt_addr_n2a(ifa
->ifa_family
,
382 RTA_PAYLOAD(rta_tb
[IFA_ADDRESS
]),
383 RTA_DATA(rta_tb
[IFA_ADDRESS
]),
389 if (rta_tb
[IFA_BROADCAST
]) {
390 fprintf(fp
, "brd %s ",
391 rt_addr_n2a(ifa
->ifa_family
,
392 RTA_PAYLOAD(rta_tb
[IFA_BROADCAST
]),
393 RTA_DATA(rta_tb
[IFA_BROADCAST
]),
394 abuf
, sizeof(abuf
)));
396 if (rta_tb
[IFA_ANYCAST
]) {
397 fprintf(fp
, "any %s ",
398 rt_addr_n2a(ifa
->ifa_family
,
399 RTA_PAYLOAD(rta_tb
[IFA_ANYCAST
]),
400 RTA_DATA(rta_tb
[IFA_ANYCAST
]),
401 abuf
, sizeof(abuf
)));
403 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
404 if (ifa
->ifa_flags
&IFA_F_SECONDARY
) {
405 ifa
->ifa_flags
&= ~IFA_F_SECONDARY
;
406 fprintf(fp
, "secondary ");
408 if (ifa
->ifa_flags
&IFA_F_TENTATIVE
) {
409 ifa
->ifa_flags
&= ~IFA_F_TENTATIVE
;
410 fprintf(fp
, "tentative ");
412 if (ifa
->ifa_flags
&IFA_F_DEPRECATED
) {
413 ifa
->ifa_flags
&= ~IFA_F_DEPRECATED
;
414 fprintf(fp
, "deprecated ");
416 if (!(ifa
->ifa_flags
&IFA_F_PERMANENT
)) {
417 fprintf(fp
, "dynamic ");
419 ifa
->ifa_flags
&= ~IFA_F_PERMANENT
;
421 fprintf(fp
, "flags %02x ", ifa
->ifa_flags
);
422 if (rta_tb
[IFA_LABEL
])
423 fprintf(fp
, "%s", (char*)RTA_DATA(rta_tb
[IFA_LABEL
]));
424 if (rta_tb
[IFA_CACHEINFO
]) {
425 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
427 fprintf(fp
, "%s", _SL_
);
428 if (ci
->ifa_valid
== 0xFFFFFFFFU
)
429 sprintf(buf
, "valid_lft forever");
431 sprintf(buf
, "valid_lft %dsec", ci
->ifa_valid
);
432 if (ci
->ifa_prefered
== 0xFFFFFFFFU
)
433 sprintf(buf
+strlen(buf
), " preferred_lft forever");
435 sprintf(buf
+strlen(buf
), " preferred_lft %dsec", ci
->ifa_prefered
);
436 fprintf(fp
, " %s", buf
);
446 struct nlmsg_list
*next
;
450 int print_selected_addrinfo(int ifindex
, struct nlmsg_list
*ainfo
, FILE *fp
)
452 for ( ;ainfo
; ainfo
= ainfo
->next
) {
453 struct nlmsghdr
*n
= &ainfo
->h
;
454 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
456 if (n
->nlmsg_type
!= RTM_NEWADDR
)
459 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifa
)))
462 if (ifa
->ifa_index
!= ifindex
||
463 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
466 print_addrinfo(NULL
, n
, fp
);
472 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
475 struct nlmsg_list
**linfo
= (struct nlmsg_list
**)arg
;
476 struct nlmsg_list
*h
;
477 struct nlmsg_list
**lp
;
479 h
= malloc(n
->nlmsg_len
+sizeof(void*));
483 memcpy(&h
->h
, n
, n
->nlmsg_len
);
486 for (lp
= linfo
; *lp
; lp
= &(*lp
)->next
) /* NOTHING */;
489 ll_remember_index(who
, n
, NULL
);
493 int ipaddr_list_or_flush(int argc
, char **argv
, int flush
)
495 struct nlmsg_list
*linfo
= NULL
;
496 struct nlmsg_list
*ainfo
= NULL
;
497 struct nlmsg_list
*l
;
498 char *filter_dev
= NULL
;
501 ipaddr_reset_filter(oneline
);
502 filter
.showqueue
= 1;
504 if (filter
.family
== AF_UNSPEC
)
505 filter
.family
= preferred_family
;
509 fprintf(stderr
, "Flush requires arguments.\n");
512 if (filter
.family
== AF_PACKET
) {
513 fprintf(stderr
, "Cannot flush link addresses.\n");
519 if (strcmp(*argv
, "to") == 0) {
521 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
522 if (filter
.family
== AF_UNSPEC
)
523 filter
.family
= filter
.pfx
.family
;
524 } else if (strcmp(*argv
, "scope") == 0) {
527 filter
.scopemask
= -1;
528 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
529 if (strcmp(*argv
, "all") != 0)
530 invarg("invalid \"scope\"\n", *argv
);
531 scope
= RT_SCOPE_NOWHERE
;
532 filter
.scopemask
= 0;
534 filter
.scope
= scope
;
535 } else if (strcmp(*argv
, "up") == 0) {
537 } else if (strcmp(*argv
, "dynamic") == 0) {
538 filter
.flags
&= ~IFA_F_PERMANENT
;
539 filter
.flagmask
|= IFA_F_PERMANENT
;
540 } else if (strcmp(*argv
, "permanent") == 0) {
541 filter
.flags
|= IFA_F_PERMANENT
;
542 filter
.flagmask
|= IFA_F_PERMANENT
;
543 } else if (strcmp(*argv
, "secondary") == 0) {
544 filter
.flags
|= IFA_F_SECONDARY
;
545 filter
.flagmask
|= IFA_F_SECONDARY
;
546 } else if (strcmp(*argv
, "primary") == 0) {
547 filter
.flags
&= ~IFA_F_SECONDARY
;
548 filter
.flagmask
|= IFA_F_SECONDARY
;
549 } else if (strcmp(*argv
, "tentative") == 0) {
550 filter
.flags
|= IFA_F_TENTATIVE
;
551 filter
.flagmask
|= IFA_F_TENTATIVE
;
552 } else if (strcmp(*argv
, "deprecated") == 0) {
553 filter
.flags
|= IFA_F_DEPRECATED
;
554 filter
.flagmask
|= IFA_F_DEPRECATED
;
555 } else if (strcmp(*argv
, "label") == 0) {
557 filter
.label
= *argv
;
559 if (strcmp(*argv
, "dev") == 0) {
562 if (matches(*argv
, "help") == 0)
565 duparg2("dev", *argv
);
571 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETLINK
) < 0) {
572 perror("Cannot send dump request");
576 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
, NULL
, NULL
) < 0) {
577 fprintf(stderr
, "Dump terminated\n");
582 filter
.ifindex
= ll_name_to_index(filter_dev
);
583 if (filter
.ifindex
<= 0) {
584 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
591 char flushb
[4096-512];
593 filter
.flushb
= flushb
;
595 filter
.flushe
= sizeof(flushb
);
598 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
599 perror("Cannot send dump request");
603 if (rtnl_dump_filter(&rth
, print_addrinfo
, stdout
, NULL
, NULL
) < 0) {
604 fprintf(stderr
, "Flush terminated\n");
607 if (filter
.flushed
== 0) {
609 fprintf(stderr
, "Nothing to flush.\n");
610 } else if (show_stats
)
611 printf("*** Flush is complete after %d round%s ***\n", round
, round
>1?"s":"");
616 if (flush_update() < 0)
620 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
626 if (filter
.family
!= AF_PACKET
) {
627 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
628 perror("Cannot send dump request");
632 if (rtnl_dump_filter(&rth
, store_nlmsg
, &ainfo
, NULL
, NULL
) < 0) {
633 fprintf(stderr
, "Dump terminated\n");
639 if (filter
.family
&& filter
.family
!= AF_PACKET
) {
640 struct nlmsg_list
**lp
;
646 while ((l
=*lp
)!=NULL
) {
648 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
649 struct nlmsg_list
*a
;
651 for (a
=ainfo
; a
; a
=a
->next
) {
652 struct nlmsghdr
*n
= &a
->h
;
653 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
655 if (ifa
->ifa_index
!= ifi
->ifi_index
||
656 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
658 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
660 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
662 if (filter
.pfx
.family
|| filter
.label
) {
663 struct rtattr
*tb
[IFA_MAX
+1];
664 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
666 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
668 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
670 memset(&dst
, 0, sizeof(dst
));
671 dst
.family
= ifa
->ifa_family
;
672 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
673 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
680 label
= RTA_DATA(tb
[IFA_LABEL
]);
682 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
683 if (fnmatch(filter
.label
, label
, 0) != 0)
698 for (l
=linfo
; l
; l
= l
->next
) {
699 if (no_link
|| print_linkinfo(NULL
, &l
->h
, stdout
) == 0) {
700 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
701 if (filter
.family
!= AF_PACKET
)
702 print_selected_addrinfo(ifi
->ifi_index
, ainfo
, stdout
);
710 int ipaddr_list_link(int argc
, char **argv
)
712 preferred_family
= AF_PACKET
;
714 return ipaddr_list_or_flush(argc
, argv
, 0);
717 void ipaddr_reset_filter(int oneline
)
719 memset(&filter
, 0, sizeof(filter
));
720 filter
.oneline
= oneline
;
723 int default_scope(inet_prefix
*lcl
)
725 if (lcl
->family
== AF_INET
) {
726 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
727 return RT_SCOPE_HOST
;
732 int ipaddr_modify(int cmd
, int argc
, char **argv
)
736 struct ifaddrmsg ifa
;
741 char *lcl_arg
= NULL
;
750 memset(&req
, 0, sizeof(req
));
752 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
753 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
754 req
.n
.nlmsg_type
= cmd
;
755 req
.ifa
.ifa_family
= preferred_family
;
758 if (strcmp(*argv
, "peer") == 0 ||
759 strcmp(*argv
, "remote") == 0) {
763 duparg("peer", *argv
);
764 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
765 peer_len
= peer
.bytelen
;
766 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
767 req
.ifa
.ifa_family
= peer
.family
;
768 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
769 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
770 } else if (matches(*argv
, "broadcast") == 0 ||
771 strcmp(*argv
, "brd") == 0) {
775 duparg("broadcast", *argv
);
776 if (strcmp(*argv
, "+") == 0)
778 else if (strcmp(*argv
, "-") == 0)
781 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
782 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
783 req
.ifa
.ifa_family
= addr
.family
;
784 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
785 brd_len
= addr
.bytelen
;
787 } else if (strcmp(*argv
, "anycast") == 0) {
791 duparg("anycast", *argv
);
792 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
793 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
794 req
.ifa
.ifa_family
= addr
.family
;
795 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
796 any_len
= addr
.bytelen
;
797 } else if (strcmp(*argv
, "scope") == 0) {
800 if (rtnl_rtscope_a2n(&scope
, *argv
))
801 invarg(*argv
, "invalid scope value.");
802 req
.ifa
.ifa_scope
= scope
;
804 } else if (strcmp(*argv
, "dev") == 0) {
807 } else if (strcmp(*argv
, "label") == 0) {
810 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
812 if (strcmp(*argv
, "local") == 0) {
815 if (matches(*argv
, "help") == 0)
818 duparg2("local", *argv
);
820 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
821 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
822 req
.ifa
.ifa_family
= lcl
.family
;
823 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
824 local_len
= lcl
.bytelen
;
829 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
832 if (l
&& matches(d
, l
) != 0) {
833 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
837 if (peer_len
== 0 && local_len
) {
838 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
840 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
841 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
842 " This special behaviour is likely to disappear in further releases,\n" \
843 " fix your scripts!\n", lcl_arg
, local_len
*8);
846 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
849 if (req
.ifa
.ifa_prefixlen
== 0)
850 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
852 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
855 if (req
.ifa
.ifa_family
!= AF_INET
) {
856 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
860 if (brd
.bitlen
<= 30) {
861 for (i
=31; i
>=brd
.bitlen
; i
--) {
863 brd
.data
[0] |= htonl(1<<(31-i
));
865 brd
.data
[0] &= ~htonl(1<<(31-i
));
867 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
868 brd_len
= brd
.bytelen
;
871 if (!scoped
&& cmd
!= RTM_DELADDR
)
872 req
.ifa
.ifa_scope
= default_scope(&lcl
);
876 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
877 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
881 if (rtnl_talk(&rth
, &req
.n
, 0, 0, NULL
, NULL
, NULL
) < 0)
887 int do_ipaddr(int argc
, char **argv
)
890 return ipaddr_list_or_flush(0, NULL
, 0);
891 if (matches(*argv
, "add") == 0)
892 return ipaddr_modify(RTM_NEWADDR
, argc
-1, argv
+1);
893 if (matches(*argv
, "delete") == 0)
894 return ipaddr_modify(RTM_DELADDR
, argc
-1, argv
+1);
895 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
896 || matches(*argv
, "lst") == 0)
897 return ipaddr_list_or_flush(argc
-1, argv
+1, 0);
898 if (matches(*argv
, "flush") == 0)
899 return ipaddr_list_or_flush(argc
-1, argv
+1, 1);
900 if (matches(*argv
, "help") == 0)
902 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv
);