]>
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"
52 struct rtnl_handle
*rth
;
57 static void usage(void) __attribute__((noreturn
));
59 static void usage(void)
64 fprintf(stderr
, "Usage: ip addr {add|del} IFADDR dev STRING\n");
65 fprintf(stderr
, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
66 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
67 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
68 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
69 fprintf(stderr
, " [ label STRING ] [ scope SCOPE-ID ]\n");
70 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
71 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
72 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
73 fprintf(stderr
, " tentative | deprecated ]\n");
77 void print_link_flags(FILE *fp
, unsigned flags
, unsigned mdown
)
80 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
81 fprintf(fp
, "NO-CARRIER%s", flags
? "," : "");
82 flags
&= ~IFF_RUNNING
;
83 #define _PF(f) if (flags&IFF_##f) { \
85 fprintf(fp, #f "%s", flags ? "," : ""); }
103 fprintf(fp
, "%x", flags
);
105 fprintf(fp
, ",M-DOWN");
109 void print_queuelen(char *name
)
114 s
= socket(AF_INET
, SOCK_STREAM
, 0);
118 memset(&ifr
, 0, sizeof(ifr
));
119 strcpy(ifr
.ifr_name
, name
);
120 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
121 perror("SIOCGIFXQLEN");
128 printf("qlen %d", ifr
.ifr_qlen
);
131 int print_linkinfo(const struct sockaddr_nl
*who
,
132 struct nlmsghdr
*n
, void *arg
)
134 FILE *fp
= (FILE*)arg
;
135 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
136 struct rtattr
* tb
[IFLA_MAX
+1];
137 int len
= n
->nlmsg_len
;
140 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
143 len
-= NLMSG_LENGTH(sizeof(*ifi
));
147 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
149 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
152 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
153 if (tb
[IFLA_IFNAME
] == NULL
) {
154 fprintf(stderr
, "BUG: nil ifname\n");
158 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
159 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
162 if (n
->nlmsg_type
== RTM_DELLINK
)
163 fprintf(fp
, "Deleted ");
165 fprintf(fp
, "%d: %s", ifi
->ifi_index
,
166 tb
[IFLA_IFNAME
] ? (char*)RTA_DATA(tb
[IFLA_IFNAME
]) : "<nil>");
170 int iflink
= *(int*)RTA_DATA(tb
[IFLA_LINK
]);
172 fprintf(fp
, "@NONE: ");
174 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
175 m_flag
= ll_index_to_flags(iflink
);
176 m_flag
= !(m_flag
& IFF_UP
);
181 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
184 fprintf(fp
, "mtu %u ", *(int*)RTA_DATA(tb
[IFLA_MTU
]));
186 fprintf(fp
, "qdisc %s ", (char*)RTA_DATA(tb
[IFLA_QDISC
]));
188 if (tb
[IFLA_MASTER
]) {
190 fprintf(fp
, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb
[IFLA_MASTER
]), b1
));
193 if (filter
.showqueue
)
194 print_queuelen((char*)RTA_DATA(tb
[IFLA_IFNAME
]));
196 if (!filter
.family
|| filter
.family
== AF_PACKET
) {
198 fprintf(fp
, "%s", _SL_
);
199 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
201 if (tb
[IFLA_ADDRESS
]) {
202 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
203 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
207 if (tb
[IFLA_BROADCAST
]) {
208 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
209 fprintf(fp
, " peer ");
211 fprintf(fp
, " brd ");
212 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
213 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
218 if (do_link
&& tb
[IFLA_STATS
] && show_stats
) {
219 struct rtnl_link_stats slocal
;
220 struct rtnl_link_stats
*s
= RTA_DATA(tb
[IFLA_STATS
]);
221 if (((unsigned long)s
) & (sizeof(unsigned long)-1)) {
222 memcpy(&slocal
, s
, sizeof(slocal
));
225 fprintf(fp
, "%s", _SL_
);
226 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
227 s
->rx_compressed
? "compressed" : "", _SL_
);
228 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
229 s
->rx_bytes
, s
->rx_packets
, s
->rx_errors
,
230 s
->rx_dropped
, s
->rx_over_errors
,
233 if (s
->rx_compressed
)
234 fprintf(fp
, " %-7u", s
->rx_compressed
);
235 if (show_stats
> 1) {
236 fprintf(fp
, "%s", _SL_
);
237 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
238 fprintf(fp
, " %-7u %-7u %-7u %-7u %-7u",
246 fprintf(fp
, "%s", _SL_
);
247 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
248 s
->tx_compressed
? "compressed" : "", _SL_
);
249 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
250 s
->tx_bytes
, s
->tx_packets
, s
->tx_errors
,
251 s
->tx_dropped
, s
->tx_carrier_errors
, s
->collisions
);
252 if (s
->tx_compressed
)
253 fprintf(fp
, " %-7u", s
->tx_compressed
);
254 if (show_stats
> 1) {
255 fprintf(fp
, "%s", _SL_
);
256 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
257 fprintf(fp
, " %-7u %-7u %-7u %-7u",
258 s
->tx_aborted_errors
,
261 s
->tx_heartbeat_errors
270 static int flush_update(void)
272 if (rtnl_send(filter
.rth
, filter
.flushb
, filter
.flushp
) < 0) {
273 perror("Failed to send flush request\n");
280 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
283 FILE *fp
= (FILE*)arg
;
284 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
285 int len
= n
->nlmsg_len
;
286 struct rtattr
* rta_tb
[IFA_MAX
+1];
290 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
292 len
-= NLMSG_LENGTH(sizeof(*ifa
));
294 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
298 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
301 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
), n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
303 if (!rta_tb
[IFA_LOCAL
])
304 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
305 if (!rta_tb
[IFA_ADDRESS
])
306 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
308 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
310 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
312 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
317 if (rta_tb
[IFA_LABEL
])
318 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
320 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
321 if (fnmatch(filter
.label
, label
, 0) != 0)
324 if (filter
.pfx
.family
) {
325 if (rta_tb
[IFA_LOCAL
]) {
327 memset(&dst
, 0, sizeof(dst
));
328 dst
.family
= ifa
->ifa_family
;
329 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
330 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
335 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
340 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
344 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
345 memcpy(fn
, n
, n
->nlmsg_len
);
346 fn
->nlmsg_type
= RTM_DELADDR
;
347 fn
->nlmsg_flags
= NLM_F_REQUEST
;
348 fn
->nlmsg_seq
= ++filter
.rth
->seq
;
349 filter
.flushp
= (((char*)fn
) + n
->nlmsg_len
) - filter
.flushb
;
355 if (n
->nlmsg_type
== RTM_DELADDR
)
356 fprintf(fp
, "Deleted ");
358 if (filter
.oneline
|| filter
.flushb
)
359 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
360 if (ifa
->ifa_family
== AF_INET
)
361 fprintf(fp
, " inet ");
362 else if (ifa
->ifa_family
== AF_INET6
)
363 fprintf(fp
, " inet6 ");
364 else if (ifa
->ifa_family
== AF_DECnet
)
365 fprintf(fp
, " dnet ");
366 else if (ifa
->ifa_family
== AF_IPX
)
367 fprintf(fp
, " ipx ");
369 fprintf(fp
, " family %d ", ifa
->ifa_family
);
371 if (rta_tb
[IFA_LOCAL
]) {
372 fprintf(fp
, "%s", rt_addr_n2a(ifa
->ifa_family
,
373 RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]),
374 RTA_DATA(rta_tb
[IFA_LOCAL
]),
375 abuf
, sizeof(abuf
)));
377 if (rta_tb
[IFA_ADDRESS
] == NULL
||
378 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]), RTA_DATA(rta_tb
[IFA_LOCAL
]), 4) == 0) {
379 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
381 fprintf(fp
, " peer %s/%d ",
382 rt_addr_n2a(ifa
->ifa_family
,
383 RTA_PAYLOAD(rta_tb
[IFA_ADDRESS
]),
384 RTA_DATA(rta_tb
[IFA_ADDRESS
]),
390 if (rta_tb
[IFA_BROADCAST
]) {
391 fprintf(fp
, "brd %s ",
392 rt_addr_n2a(ifa
->ifa_family
,
393 RTA_PAYLOAD(rta_tb
[IFA_BROADCAST
]),
394 RTA_DATA(rta_tb
[IFA_BROADCAST
]),
395 abuf
, sizeof(abuf
)));
397 if (rta_tb
[IFA_ANYCAST
]) {
398 fprintf(fp
, "any %s ",
399 rt_addr_n2a(ifa
->ifa_family
,
400 RTA_PAYLOAD(rta_tb
[IFA_ANYCAST
]),
401 RTA_DATA(rta_tb
[IFA_ANYCAST
]),
402 abuf
, sizeof(abuf
)));
404 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
405 if (ifa
->ifa_flags
&IFA_F_SECONDARY
) {
406 ifa
->ifa_flags
&= ~IFA_F_SECONDARY
;
407 fprintf(fp
, "secondary ");
409 if (ifa
->ifa_flags
&IFA_F_TENTATIVE
) {
410 ifa
->ifa_flags
&= ~IFA_F_TENTATIVE
;
411 fprintf(fp
, "tentative ");
413 if (ifa
->ifa_flags
&IFA_F_DEPRECATED
) {
414 ifa
->ifa_flags
&= ~IFA_F_DEPRECATED
;
415 fprintf(fp
, "deprecated ");
417 if (!(ifa
->ifa_flags
&IFA_F_PERMANENT
)) {
418 fprintf(fp
, "dynamic ");
420 ifa
->ifa_flags
&= ~IFA_F_PERMANENT
;
422 fprintf(fp
, "flags %02x ", ifa
->ifa_flags
);
423 if (rta_tb
[IFA_LABEL
])
424 fprintf(fp
, "%s", (char*)RTA_DATA(rta_tb
[IFA_LABEL
]));
425 if (rta_tb
[IFA_CACHEINFO
]) {
426 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
428 fprintf(fp
, "%s", _SL_
);
429 if (ci
->ifa_valid
== 0xFFFFFFFFU
)
430 sprintf(buf
, "valid_lft forever");
432 sprintf(buf
, "valid_lft %dsec", ci
->ifa_valid
);
433 if (ci
->ifa_prefered
== 0xFFFFFFFFU
)
434 sprintf(buf
+strlen(buf
), " preferred_lft forever");
436 sprintf(buf
+strlen(buf
), " preferred_lft %dsec", ci
->ifa_prefered
);
437 fprintf(fp
, " %s", buf
);
447 struct nlmsg_list
*next
;
451 int print_selected_addrinfo(int ifindex
, struct nlmsg_list
*ainfo
, FILE *fp
)
453 for ( ;ainfo
; ainfo
= ainfo
->next
) {
454 struct nlmsghdr
*n
= &ainfo
->h
;
455 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
457 if (n
->nlmsg_type
!= RTM_NEWADDR
)
460 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifa
)))
463 if (ifa
->ifa_index
!= ifindex
||
464 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
467 print_addrinfo(NULL
, n
, fp
);
473 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
476 struct nlmsg_list
**linfo
= (struct nlmsg_list
**)arg
;
477 struct nlmsg_list
*h
;
478 struct nlmsg_list
**lp
;
480 h
= malloc(n
->nlmsg_len
+sizeof(void*));
484 memcpy(&h
->h
, n
, n
->nlmsg_len
);
487 for (lp
= linfo
; *lp
; lp
= &(*lp
)->next
) /* NOTHING */;
490 ll_remember_index(who
, n
, NULL
);
494 int ipaddr_list_or_flush(int argc
, char **argv
, int flush
)
496 struct nlmsg_list
*linfo
= NULL
;
497 struct nlmsg_list
*ainfo
= NULL
;
498 struct nlmsg_list
*l
;
499 struct rtnl_handle rth
;
500 char *filter_dev
= NULL
;
503 ipaddr_reset_filter(oneline
);
504 filter
.showqueue
= 1;
506 if (filter
.family
== AF_UNSPEC
)
507 filter
.family
= preferred_family
;
511 fprintf(stderr
, "Flush requires arguments.\n");
514 if (filter
.family
== AF_PACKET
) {
515 fprintf(stderr
, "Cannot flush link addresses.\n");
521 if (strcmp(*argv
, "to") == 0) {
523 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
524 if (filter
.family
== AF_UNSPEC
)
525 filter
.family
= filter
.pfx
.family
;
526 } else if (strcmp(*argv
, "scope") == 0) {
529 filter
.scopemask
= -1;
530 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
531 if (strcmp(*argv
, "all") != 0)
532 invarg("invalid \"scope\"\n", *argv
);
533 scope
= RT_SCOPE_NOWHERE
;
534 filter
.scopemask
= 0;
536 filter
.scope
= scope
;
537 } else if (strcmp(*argv
, "up") == 0) {
539 } else if (strcmp(*argv
, "dynamic") == 0) {
540 filter
.flags
&= ~IFA_F_PERMANENT
;
541 filter
.flagmask
|= IFA_F_PERMANENT
;
542 } else if (strcmp(*argv
, "permanent") == 0) {
543 filter
.flags
|= IFA_F_PERMANENT
;
544 filter
.flagmask
|= IFA_F_PERMANENT
;
545 } else if (strcmp(*argv
, "secondary") == 0) {
546 filter
.flags
|= IFA_F_SECONDARY
;
547 filter
.flagmask
|= IFA_F_SECONDARY
;
548 } else if (strcmp(*argv
, "primary") == 0) {
549 filter
.flags
&= ~IFA_F_SECONDARY
;
550 filter
.flagmask
|= IFA_F_SECONDARY
;
551 } else if (strcmp(*argv
, "tentative") == 0) {
552 filter
.flags
|= IFA_F_TENTATIVE
;
553 filter
.flagmask
|= IFA_F_TENTATIVE
;
554 } else if (strcmp(*argv
, "deprecated") == 0) {
555 filter
.flags
|= IFA_F_DEPRECATED
;
556 filter
.flagmask
|= IFA_F_DEPRECATED
;
557 } else if (strcmp(*argv
, "label") == 0) {
559 filter
.label
= *argv
;
561 if (strcmp(*argv
, "dev") == 0) {
564 if (matches(*argv
, "help") == 0)
567 duparg2("dev", *argv
);
573 if (rtnl_open(&rth
, 0) < 0)
576 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETLINK
) < 0) {
577 perror("Cannot send dump request");
581 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
, NULL
, NULL
) < 0) {
582 fprintf(stderr
, "Dump terminated\n");
587 filter
.ifindex
= ll_name_to_index(filter_dev
);
588 if (filter
.ifindex
<= 0) {
589 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
596 char flushb
[4096-512];
598 filter
.flushb
= flushb
;
600 filter
.flushe
= sizeof(flushb
);
604 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
605 perror("Cannot send dump request");
609 if (rtnl_dump_filter(&rth
, print_addrinfo
, stdout
, NULL
, NULL
) < 0) {
610 fprintf(stderr
, "Flush terminated\n");
613 if (filter
.flushed
== 0) {
615 fprintf(stderr
, "Nothing to flush.\n");
616 } else if (show_stats
)
617 printf("*** Flush is complete after %d round%s ***\n", round
, round
>1?"s":"");
622 if (flush_update() < 0)
625 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
631 if (filter
.family
!= AF_PACKET
) {
632 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
633 perror("Cannot send dump request");
637 if (rtnl_dump_filter(&rth
, store_nlmsg
, &ainfo
, NULL
, NULL
) < 0) {
638 fprintf(stderr
, "Dump terminated\n");
644 if (filter
.family
&& filter
.family
!= AF_PACKET
) {
645 struct nlmsg_list
**lp
;
651 while ((l
=*lp
)!=NULL
) {
653 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
654 struct nlmsg_list
*a
;
656 for (a
=ainfo
; a
; a
=a
->next
) {
657 struct nlmsghdr
*n
= &a
->h
;
658 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
660 if (ifa
->ifa_index
!= ifi
->ifi_index
||
661 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
663 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
665 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
667 if (filter
.pfx
.family
|| filter
.label
) {
668 struct rtattr
*tb
[IFA_MAX
+1];
669 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
671 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
673 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
675 memset(&dst
, 0, sizeof(dst
));
676 dst
.family
= ifa
->ifa_family
;
677 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
678 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
685 label
= RTA_DATA(tb
[IFA_LABEL
]);
687 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
688 if (fnmatch(filter
.label
, label
, 0) != 0)
703 for (l
=linfo
; l
; l
= l
->next
) {
704 if (no_link
|| print_linkinfo(NULL
, &l
->h
, stdout
) == 0) {
705 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
706 if (filter
.family
!= AF_PACKET
)
707 print_selected_addrinfo(ifi
->ifi_index
, ainfo
, stdout
);
715 int ipaddr_list_link(int argc
, char **argv
)
717 preferred_family
= AF_PACKET
;
719 return ipaddr_list_or_flush(argc
, argv
, 0);
722 void ipaddr_reset_filter(int oneline
)
724 memset(&filter
, 0, sizeof(filter
));
725 filter
.oneline
= oneline
;
728 int default_scope(inet_prefix
*lcl
)
730 if (lcl
->family
== AF_INET
) {
731 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
732 return RT_SCOPE_HOST
;
737 int ipaddr_modify(int cmd
, int argc
, char **argv
)
739 struct rtnl_handle rth
;
742 struct ifaddrmsg ifa
;
747 char *lcl_arg
= NULL
;
756 memset(&req
, 0, sizeof(req
));
758 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
759 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
760 req
.n
.nlmsg_type
= cmd
;
761 req
.ifa
.ifa_family
= preferred_family
;
764 if (strcmp(*argv
, "peer") == 0 ||
765 strcmp(*argv
, "remote") == 0) {
769 duparg("peer", *argv
);
770 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
771 peer_len
= peer
.bytelen
;
772 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
773 req
.ifa
.ifa_family
= peer
.family
;
774 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
775 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
776 } else if (matches(*argv
, "broadcast") == 0 ||
777 strcmp(*argv
, "brd") == 0) {
781 duparg("broadcast", *argv
);
782 if (strcmp(*argv
, "+") == 0)
784 else if (strcmp(*argv
, "-") == 0)
787 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
788 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
789 req
.ifa
.ifa_family
= addr
.family
;
790 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
791 brd_len
= addr
.bytelen
;
793 } else if (strcmp(*argv
, "anycast") == 0) {
797 duparg("anycast", *argv
);
798 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
799 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
800 req
.ifa
.ifa_family
= addr
.family
;
801 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
802 any_len
= addr
.bytelen
;
803 } else if (strcmp(*argv
, "scope") == 0) {
806 if (rtnl_rtscope_a2n(&scope
, *argv
))
807 invarg(*argv
, "invalid scope value.");
808 req
.ifa
.ifa_scope
= scope
;
810 } else if (strcmp(*argv
, "dev") == 0) {
813 } else if (strcmp(*argv
, "label") == 0) {
816 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
818 if (strcmp(*argv
, "local") == 0) {
821 if (matches(*argv
, "help") == 0)
824 duparg2("local", *argv
);
826 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
827 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
828 req
.ifa
.ifa_family
= lcl
.family
;
829 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
830 local_len
= lcl
.bytelen
;
835 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
838 if (l
&& matches(d
, l
) != 0) {
839 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
843 if (peer_len
== 0 && local_len
) {
844 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
846 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
847 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
848 " This special behaviour is likely to disappear in further releases,\n" \
849 " fix your scripts!\n", lcl_arg
, local_len
*8);
852 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
855 if (req
.ifa
.ifa_prefixlen
== 0)
856 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
858 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
861 if (req
.ifa
.ifa_family
!= AF_INET
) {
862 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
866 if (brd
.bitlen
<= 30) {
867 for (i
=31; i
>=brd
.bitlen
; i
--) {
869 brd
.data
[0] |= htonl(1<<(31-i
));
871 brd
.data
[0] &= ~htonl(1<<(31-i
));
873 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
874 brd_len
= brd
.bytelen
;
877 if (!scoped
&& cmd
!= RTM_DELADDR
)
878 req
.ifa
.ifa_scope
= default_scope(&lcl
);
880 if (rtnl_open(&rth
, 0) < 0)
885 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
886 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
890 if (rtnl_talk(&rth
, &req
.n
, 0, 0, NULL
, NULL
, NULL
) < 0)
896 int do_ipaddr(int argc
, char **argv
)
899 return ipaddr_list_or_flush(0, NULL
, 0);
900 if (matches(*argv
, "add") == 0)
901 return ipaddr_modify(RTM_NEWADDR
, argc
-1, argv
+1);
902 if (matches(*argv
, "delete") == 0)
903 return ipaddr_modify(RTM_DELADDR
, argc
-1, argv
+1);
904 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
905 || matches(*argv
, "lst") == 0)
906 return ipaddr_list_or_flush(argc
-1, argv
+1, 0);
907 if (matches(*argv
, "flush") == 0)
908 return ipaddr_list_or_flush(argc
-1, argv
+1, 1);
909 if (matches(*argv
, "help") == 0)
911 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv
);