]>
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>
18 #include <sys/ioctl.h>
19 #include <sys/socket.h>
20 #include <sys/ioctl.h>
21 #include <sys/errno.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
27 #include <linux/netdevice.h>
28 #include <linux/if_arp.h>
29 #include <linux/sockios.h>
34 #include "ip_common.h"
57 static void usage(void) __attribute__((noreturn
));
59 static void usage(void)
64 fprintf(stderr
, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n");
65 fprintf(stderr
, " [ CONFFLAG-LIST ]\n");
66 fprintf(stderr
, " ip addr del IFADDR dev STRING\n");
67 fprintf(stderr
, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
68 fprintf(stderr
, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
69 fprintf(stderr
, "IFADDR := PREFIX | ADDR peer PREFIX\n");
70 fprintf(stderr
, " [ broadcast ADDR ] [ anycast ADDR ]\n");
71 fprintf(stderr
, " [ label STRING ] [ scope SCOPE-ID ]\n");
72 fprintf(stderr
, "SCOPE-ID := [ host | link | global | NUMBER ]\n");
73 fprintf(stderr
, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
74 fprintf(stderr
, "FLAG := [ permanent | dynamic | secondary | primary |\n");
75 fprintf(stderr
, " tentative | deprecated | dadfailed | temporary |\n");
76 fprintf(stderr
, " CONFFLAG-LIST ]\n");
77 fprintf(stderr
, "CONFFLAG-LIST := [ CONFFLAG-LIST ] CONFFLAG\n");
78 fprintf(stderr
, "CONFFLAG := [ home | nodad ]\n");
79 fprintf(stderr
, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
80 fprintf(stderr
, "LFT := forever | SECONDS\n");
85 void print_link_flags(FILE *fp
, unsigned flags
, unsigned mdown
)
88 if (flags
& IFF_UP
&& !(flags
& IFF_RUNNING
))
89 fprintf(fp
, "NO-CARRIER%s", flags
? "," : "");
90 flags
&= ~IFF_RUNNING
;
91 #define _PF(f) if (flags&IFF_##f) { \
93 fprintf(fp, #f "%s", flags ? "," : ""); }
114 fprintf(fp
, "%x", flags
);
116 fprintf(fp
, ",M-DOWN");
120 static const char *oper_states
[] = {
121 "UNKNOWN", "NOTPRESENT", "DOWN", "LOWERLAYERDOWN",
122 "TESTING", "DORMANT", "UP"
125 static void print_operstate(FILE *f
, __u8 state
)
127 if (state
>= sizeof(oper_states
)/sizeof(oper_states
[0]))
128 fprintf(f
, "state %#x ", state
);
130 fprintf(f
, "state %s ", oper_states
[state
]);
133 static void print_queuelen(FILE *f
, const char *name
)
138 s
= socket(AF_INET
, SOCK_STREAM
, 0);
142 memset(&ifr
, 0, sizeof(ifr
));
143 strcpy(ifr
.ifr_name
, name
);
144 if (ioctl(s
, SIOCGIFTXQLEN
, &ifr
) < 0) {
145 fprintf(f
, "ioctl(SIOCGIFXQLEN) failed: %s\n", strerror(errno
));
152 fprintf(f
, "qlen %d", ifr
.ifr_qlen
);
155 static void print_linktype(FILE *fp
, struct rtattr
*tb
)
157 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
158 struct link_util
*lu
;
161 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
);
163 if (!linkinfo
[IFLA_INFO_KIND
])
165 kind
= RTA_DATA(linkinfo
[IFLA_INFO_KIND
]);
167 fprintf(fp
, "%s", _SL_
);
168 fprintf(fp
, " %s ", kind
);
170 lu
= get_link_kind(kind
);
171 if (!lu
|| !lu
->print_opt
)
175 struct rtattr
*attr
[lu
->maxattr
+1], **data
= NULL
;
177 if (linkinfo
[IFLA_INFO_DATA
]) {
178 parse_rtattr_nested(attr
, lu
->maxattr
,
179 linkinfo
[IFLA_INFO_DATA
]);
182 lu
->print_opt(lu
, fp
, data
);
184 if (linkinfo
[IFLA_INFO_XSTATS
] && show_stats
&&
186 lu
->print_xstats(lu
, fp
, linkinfo
[IFLA_INFO_XSTATS
]);
190 static void print_vfinfo(FILE *fp
, struct rtattr
*vfinfo
)
192 struct ifla_vf_mac
*vf_mac
;
193 struct ifla_vf_vlan
*vf_vlan
;
194 struct ifla_vf_tx_rate
*vf_tx_rate
;
195 struct rtattr
*vf
[IFLA_VF_MAX
+1];
198 if (vfinfo
->rta_type
!= IFLA_VF_INFO
) {
199 fprintf(stderr
, "BUG: rta type is %d\n", vfinfo
->rta_type
);
203 parse_rtattr_nested(vf
, IFLA_VF_MAX
, vfinfo
);
205 vf_mac
= RTA_DATA(vf
[IFLA_VF_MAC
]);
206 vf_vlan
= RTA_DATA(vf
[IFLA_VF_VLAN
]);
207 vf_tx_rate
= RTA_DATA(vf
[IFLA_VF_TX_RATE
]);
209 fprintf(fp
, "\n vf %d MAC %s", vf_mac
->vf
,
210 ll_addr_n2a((unsigned char *)&vf_mac
->mac
,
211 ETH_ALEN
, 0, b1
, sizeof(b1
)));
213 fprintf(fp
, ", vlan %d", vf_vlan
->vlan
);
215 fprintf(fp
, ", qos %d", vf_vlan
->qos
);
216 if (vf_tx_rate
->rate
)
217 fprintf(fp
, ", tx rate %d (Mbps)", vf_tx_rate
->rate
);
220 int print_linkinfo(const struct sockaddr_nl
*who
,
221 struct nlmsghdr
*n
, void *arg
)
223 FILE *fp
= (FILE*)arg
;
224 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
225 struct rtattr
* tb
[IFLA_MAX
+1];
226 int len
= n
->nlmsg_len
;
229 if (n
->nlmsg_type
!= RTM_NEWLINK
&& n
->nlmsg_type
!= RTM_DELLINK
)
232 len
-= NLMSG_LENGTH(sizeof(*ifi
));
236 if (filter
.ifindex
&& ifi
->ifi_index
!= filter
.ifindex
)
238 if (filter
.up
&& !(ifi
->ifi_flags
&IFF_UP
))
241 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
242 if (tb
[IFLA_IFNAME
] == NULL
) {
243 fprintf(stderr
, "BUG: device with ifindex %d has nil ifname\n", ifi
->ifi_index
);
246 (!filter
.family
|| filter
.family
== AF_PACKET
) &&
247 fnmatch(filter
.label
, RTA_DATA(tb
[IFLA_IFNAME
]), 0))
250 if (n
->nlmsg_type
== RTM_DELLINK
)
251 fprintf(fp
, "Deleted ");
253 fprintf(fp
, "%d: %s", ifi
->ifi_index
,
254 tb
[IFLA_IFNAME
] ? (char*)RTA_DATA(tb
[IFLA_IFNAME
]) : "<nil>");
258 int iflink
= *(int*)RTA_DATA(tb
[IFLA_LINK
]);
260 fprintf(fp
, "@NONE: ");
262 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
263 m_flag
= ll_index_to_flags(iflink
);
264 m_flag
= !(m_flag
& IFF_UP
);
269 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
272 fprintf(fp
, "mtu %u ", *(int*)RTA_DATA(tb
[IFLA_MTU
]));
274 fprintf(fp
, "qdisc %s ", (char*)RTA_DATA(tb
[IFLA_QDISC
]));
276 if (tb
[IFLA_MASTER
]) {
278 fprintf(fp
, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb
[IFLA_MASTER
]), b1
));
281 if (tb
[IFLA_OPERSTATE
])
282 print_operstate(fp
, *(__u8
*)RTA_DATA(tb
[IFLA_OPERSTATE
]));
284 if (filter
.showqueue
)
285 print_queuelen(fp
, (char*)RTA_DATA(tb
[IFLA_IFNAME
]));
287 if (!filter
.family
|| filter
.family
== AF_PACKET
) {
289 fprintf(fp
, "%s", _SL_
);
290 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
292 if (tb
[IFLA_ADDRESS
]) {
293 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
294 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
298 if (tb
[IFLA_BROADCAST
]) {
299 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
300 fprintf(fp
, " peer ");
302 fprintf(fp
, " brd ");
303 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
304 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
310 if (do_link
&& tb
[IFLA_LINKINFO
] && show_details
)
311 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
313 if (do_link
&& tb
[IFLA_IFALIAS
])
314 fprintf(fp
,"\n alias %s",
315 (const char *) RTA_DATA(tb
[IFLA_IFALIAS
]));
317 if (do_link
&& tb
[IFLA_STATS64
] && show_stats
) {
318 struct rtnl_link_stats64 slocal
;
319 struct rtnl_link_stats64
*s
= RTA_DATA(tb
[IFLA_STATS64
]);
320 if (((unsigned long)s
) & (sizeof(unsigned long)-1)) {
321 memcpy(&slocal
, s
, sizeof(slocal
));
324 fprintf(fp
, "%s", _SL_
);
325 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
326 s
->rx_compressed
? "compressed" : "", _SL_
);
327 fprintf(fp
, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
328 (unsigned long long)s
->rx_bytes
,
329 (unsigned long long)s
->rx_packets
,
330 (unsigned long long)s
->rx_errors
,
331 (unsigned long long)s
->rx_dropped
,
332 (unsigned long long)s
->rx_over_errors
,
333 (unsigned long long)s
->multicast
);
334 if (s
->rx_compressed
)
335 fprintf(fp
, " %-7llu",
336 (unsigned long long)s
->rx_compressed
);
337 if (show_stats
> 1) {
338 fprintf(fp
, "%s", _SL_
);
339 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
340 fprintf(fp
, " %-7llu %-7llu %-7llu %-7llu %-7llu",
341 (unsigned long long)s
->rx_length_errors
,
342 (unsigned long long)s
->rx_crc_errors
,
343 (unsigned long long)s
->rx_frame_errors
,
344 (unsigned long long)s
->rx_fifo_errors
,
345 (unsigned long long)s
->rx_missed_errors
);
347 fprintf(fp
, "%s", _SL_
);
348 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
349 s
->tx_compressed
? "compressed" : "", _SL_
);
350 fprintf(fp
, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
351 (unsigned long long)s
->tx_bytes
,
352 (unsigned long long)s
->tx_packets
,
353 (unsigned long long)s
->tx_errors
,
354 (unsigned long long)s
->tx_dropped
,
355 (unsigned long long)s
->tx_carrier_errors
,
356 (unsigned long long)s
->collisions
);
357 if (s
->tx_compressed
)
358 fprintf(fp
, " %-7llu",
359 (unsigned long long)s
->tx_compressed
);
360 if (show_stats
> 1) {
361 fprintf(fp
, "%s", _SL_
);
362 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
363 fprintf(fp
, " %-7llu %-7llu %-7llu %-7llu",
364 (unsigned long long)s
->tx_aborted_errors
,
365 (unsigned long long)s
->tx_fifo_errors
,
366 (unsigned long long)s
->tx_window_errors
,
367 (unsigned long long)s
->tx_heartbeat_errors
);
370 if (do_link
&& !tb
[IFLA_STATS64
] && tb
[IFLA_STATS
] && show_stats
) {
371 struct rtnl_link_stats slocal
;
372 struct rtnl_link_stats
*s
= RTA_DATA(tb
[IFLA_STATS
]);
373 if (((unsigned long)s
) & (sizeof(unsigned long)-1)) {
374 memcpy(&slocal
, s
, sizeof(slocal
));
377 fprintf(fp
, "%s", _SL_
);
378 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
379 s
->rx_compressed
? "compressed" : "", _SL_
);
380 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
381 s
->rx_bytes
, s
->rx_packets
, s
->rx_errors
,
382 s
->rx_dropped
, s
->rx_over_errors
,
385 if (s
->rx_compressed
)
386 fprintf(fp
, " %-7u", s
->rx_compressed
);
387 if (show_stats
> 1) {
388 fprintf(fp
, "%s", _SL_
);
389 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
390 fprintf(fp
, " %-7u %-7u %-7u %-7u %-7u",
398 fprintf(fp
, "%s", _SL_
);
399 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
400 s
->tx_compressed
? "compressed" : "", _SL_
);
401 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
402 s
->tx_bytes
, s
->tx_packets
, s
->tx_errors
,
403 s
->tx_dropped
, s
->tx_carrier_errors
, s
->collisions
);
404 if (s
->tx_compressed
)
405 fprintf(fp
, " %-7u", s
->tx_compressed
);
406 if (show_stats
> 1) {
407 fprintf(fp
, "%s", _SL_
);
408 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
409 fprintf(fp
, " %-7u %-7u %-7u %-7u",
410 s
->tx_aborted_errors
,
413 s
->tx_heartbeat_errors
417 if (do_link
&& tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
418 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
419 int rem
= RTA_PAYLOAD(vflist
);
420 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
))
429 static int flush_update(void)
431 if (rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) {
432 perror("Failed to send flush request");
439 static int set_lifetime(unsigned int *lifetime
, char *argv
)
441 if (strcmp(argv
, "forever") == 0)
442 *lifetime
= INFINITY_LIFE_TIME
;
443 else if (get_u32(lifetime
, argv
, 0))
449 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
452 FILE *fp
= (FILE*)arg
;
453 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
454 int len
= n
->nlmsg_len
;
456 /* Use local copy of ifa_flags to not interfere with filtering code */
457 unsigned int ifa_flags
;
458 struct rtattr
* rta_tb
[IFA_MAX
+1];
462 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
464 len
-= NLMSG_LENGTH(sizeof(*ifa
));
466 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
470 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
473 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
), n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
475 if (!rta_tb
[IFA_LOCAL
])
476 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
477 if (!rta_tb
[IFA_ADDRESS
])
478 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
480 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
482 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
484 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
489 if (rta_tb
[IFA_LABEL
])
490 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
492 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
493 if (fnmatch(filter
.label
, label
, 0) != 0)
496 if (filter
.pfx
.family
) {
497 if (rta_tb
[IFA_LOCAL
]) {
499 memset(&dst
, 0, sizeof(dst
));
500 dst
.family
= ifa
->ifa_family
;
501 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
502 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
507 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
512 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
516 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
517 memcpy(fn
, n
, n
->nlmsg_len
);
518 fn
->nlmsg_type
= RTM_DELADDR
;
519 fn
->nlmsg_flags
= NLM_F_REQUEST
;
520 fn
->nlmsg_seq
= ++rth
.seq
;
521 filter
.flushp
= (((char*)fn
) + n
->nlmsg_len
) - filter
.flushb
;
527 if (n
->nlmsg_type
== RTM_DELADDR
)
528 fprintf(fp
, "Deleted ");
530 if (filter
.oneline
|| filter
.flushb
)
531 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
532 if (ifa
->ifa_family
== AF_INET
)
533 fprintf(fp
, " inet ");
534 else if (ifa
->ifa_family
== AF_INET6
)
535 fprintf(fp
, " inet6 ");
536 else if (ifa
->ifa_family
== AF_DECnet
)
537 fprintf(fp
, " dnet ");
538 else if (ifa
->ifa_family
== AF_IPX
)
539 fprintf(fp
, " ipx ");
541 fprintf(fp
, " family %d ", ifa
->ifa_family
);
543 if (rta_tb
[IFA_LOCAL
]) {
544 fprintf(fp
, "%s", rt_addr_n2a(ifa
->ifa_family
,
545 RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]),
546 RTA_DATA(rta_tb
[IFA_LOCAL
]),
547 abuf
, sizeof(abuf
)));
549 if (rta_tb
[IFA_ADDRESS
] == NULL
||
550 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]), RTA_DATA(rta_tb
[IFA_LOCAL
]), 4) == 0) {
551 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
553 fprintf(fp
, " peer %s/%d ",
554 rt_addr_n2a(ifa
->ifa_family
,
555 RTA_PAYLOAD(rta_tb
[IFA_ADDRESS
]),
556 RTA_DATA(rta_tb
[IFA_ADDRESS
]),
562 if (rta_tb
[IFA_BROADCAST
]) {
563 fprintf(fp
, "brd %s ",
564 rt_addr_n2a(ifa
->ifa_family
,
565 RTA_PAYLOAD(rta_tb
[IFA_BROADCAST
]),
566 RTA_DATA(rta_tb
[IFA_BROADCAST
]),
567 abuf
, sizeof(abuf
)));
569 if (rta_tb
[IFA_ANYCAST
]) {
570 fprintf(fp
, "any %s ",
571 rt_addr_n2a(ifa
->ifa_family
,
572 RTA_PAYLOAD(rta_tb
[IFA_ANYCAST
]),
573 RTA_DATA(rta_tb
[IFA_ANYCAST
]),
574 abuf
, sizeof(abuf
)));
576 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
577 ifa_flags
= ifa
->ifa_flags
;
578 if (ifa
->ifa_flags
&IFA_F_SECONDARY
) {
579 ifa_flags
&= ~IFA_F_SECONDARY
;
580 if (ifa
->ifa_family
== AF_INET6
)
581 fprintf(fp
, "temporary ");
583 fprintf(fp
, "secondary ");
585 if (ifa
->ifa_flags
&IFA_F_TENTATIVE
) {
586 ifa_flags
&= ~IFA_F_TENTATIVE
;
587 fprintf(fp
, "tentative ");
589 if (ifa
->ifa_flags
&IFA_F_DEPRECATED
) {
590 ifa_flags
&= ~IFA_F_DEPRECATED
;
592 fprintf(fp
, "deprecated ");
594 if (ifa
->ifa_flags
&IFA_F_HOMEADDRESS
) {
595 ifa_flags
&= ~IFA_F_HOMEADDRESS
;
596 fprintf(fp
, "home ");
598 if (ifa
->ifa_flags
&IFA_F_NODAD
) {
599 ifa_flags
&= ~IFA_F_NODAD
;
600 fprintf(fp
, "nodad ");
602 if (!(ifa
->ifa_flags
&IFA_F_PERMANENT
)) {
603 fprintf(fp
, "dynamic ");
605 ifa_flags
&= ~IFA_F_PERMANENT
;
606 if (ifa
->ifa_flags
&IFA_F_DADFAILED
) {
607 ifa_flags
&= ~IFA_F_DADFAILED
;
608 fprintf(fp
, "dadfailed ");
611 fprintf(fp
, "flags %02x ", ifa_flags
);
612 if (rta_tb
[IFA_LABEL
])
613 fprintf(fp
, "%s", (char*)RTA_DATA(rta_tb
[IFA_LABEL
]));
614 if (rta_tb
[IFA_CACHEINFO
]) {
615 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
616 fprintf(fp
, "%s", _SL_
);
617 fprintf(fp
, " valid_lft ");
618 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
)
619 fprintf(fp
, "forever");
621 fprintf(fp
, "%usec", ci
->ifa_valid
);
622 fprintf(fp
, " preferred_lft ");
623 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
)
624 fprintf(fp
, "forever");
627 fprintf(fp
, "%dsec", ci
->ifa_prefered
);
629 fprintf(fp
, "%usec", ci
->ifa_prefered
);
637 int print_addrinfo_primary(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
640 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
642 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
645 return print_addrinfo(who
, n
, arg
);
648 int print_addrinfo_secondary(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
651 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
653 if (!(ifa
->ifa_flags
& IFA_F_SECONDARY
))
656 return print_addrinfo(who
, n
, arg
);
661 struct nlmsg_list
*next
;
665 static int print_selected_addrinfo(int ifindex
, struct nlmsg_list
*ainfo
, FILE *fp
)
667 for ( ;ainfo
; ainfo
= ainfo
->next
) {
668 struct nlmsghdr
*n
= &ainfo
->h
;
669 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
671 if (n
->nlmsg_type
!= RTM_NEWADDR
)
674 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifa
)))
677 if (ifa
->ifa_index
!= ifindex
||
678 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
681 print_addrinfo(NULL
, n
, fp
);
687 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
690 struct nlmsg_list
**linfo
= (struct nlmsg_list
**)arg
;
691 struct nlmsg_list
*h
;
692 struct nlmsg_list
**lp
;
694 h
= malloc(n
->nlmsg_len
+sizeof(void*));
698 memcpy(&h
->h
, n
, n
->nlmsg_len
);
701 for (lp
= linfo
; *lp
; lp
= &(*lp
)->next
) /* NOTHING */;
704 ll_remember_index(who
, n
, NULL
);
708 static int ipaddr_list_or_flush(int argc
, char **argv
, int flush
)
710 struct nlmsg_list
*linfo
= NULL
;
711 struct nlmsg_list
*ainfo
= NULL
;
712 struct nlmsg_list
*l
, *n
;
713 char *filter_dev
= NULL
;
716 ipaddr_reset_filter(oneline
);
717 filter
.showqueue
= 1;
719 if (filter
.family
== AF_UNSPEC
)
720 filter
.family
= preferred_family
;
724 fprintf(stderr
, "Flush requires arguments.\n");
727 if (filter
.family
== AF_PACKET
) {
728 fprintf(stderr
, "Cannot flush link addresses.\n");
734 if (strcmp(*argv
, "to") == 0) {
736 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
737 if (filter
.family
== AF_UNSPEC
)
738 filter
.family
= filter
.pfx
.family
;
739 } else if (strcmp(*argv
, "scope") == 0) {
742 filter
.scopemask
= -1;
743 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
744 if (strcmp(*argv
, "all") != 0)
745 invarg("invalid \"scope\"\n", *argv
);
746 scope
= RT_SCOPE_NOWHERE
;
747 filter
.scopemask
= 0;
749 filter
.scope
= scope
;
750 } else if (strcmp(*argv
, "up") == 0) {
752 } else if (strcmp(*argv
, "dynamic") == 0) {
753 filter
.flags
&= ~IFA_F_PERMANENT
;
754 filter
.flagmask
|= IFA_F_PERMANENT
;
755 } else if (strcmp(*argv
, "permanent") == 0) {
756 filter
.flags
|= IFA_F_PERMANENT
;
757 filter
.flagmask
|= IFA_F_PERMANENT
;
758 } else if (strcmp(*argv
, "secondary") == 0 ||
759 strcmp(*argv
, "temporary") == 0) {
760 filter
.flags
|= IFA_F_SECONDARY
;
761 filter
.flagmask
|= IFA_F_SECONDARY
;
762 } else if (strcmp(*argv
, "primary") == 0) {
763 filter
.flags
&= ~IFA_F_SECONDARY
;
764 filter
.flagmask
|= IFA_F_SECONDARY
;
765 } else if (strcmp(*argv
, "tentative") == 0) {
766 filter
.flags
|= IFA_F_TENTATIVE
;
767 filter
.flagmask
|= IFA_F_TENTATIVE
;
768 } else if (strcmp(*argv
, "deprecated") == 0) {
769 filter
.flags
|= IFA_F_DEPRECATED
;
770 filter
.flagmask
|= IFA_F_DEPRECATED
;
771 } else if (strcmp(*argv
, "home") == 0) {
772 filter
.flags
|= IFA_F_HOMEADDRESS
;
773 filter
.flagmask
|= IFA_F_HOMEADDRESS
;
774 } else if (strcmp(*argv
, "nodad") == 0) {
775 filter
.flags
|= IFA_F_NODAD
;
776 filter
.flagmask
|= IFA_F_NODAD
;
777 } else if (strcmp(*argv
, "dadfailed") == 0) {
778 filter
.flags
|= IFA_F_DADFAILED
;
779 filter
.flagmask
|= IFA_F_DADFAILED
;
780 } else if (strcmp(*argv
, "label") == 0) {
782 filter
.label
= *argv
;
784 if (strcmp(*argv
, "dev") == 0) {
787 if (matches(*argv
, "help") == 0)
790 duparg2("dev", *argv
);
796 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETLINK
) < 0) {
797 perror("Cannot send dump request");
801 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
, NULL
, NULL
) < 0) {
802 fprintf(stderr
, "Dump terminated\n");
807 filter
.ifindex
= ll_name_to_index(filter_dev
);
808 if (filter
.ifindex
<= 0) {
809 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
816 char flushb
[4096-512];
818 filter
.flushb
= flushb
;
820 filter
.flushe
= sizeof(flushb
);
822 while (round
< MAX_ROUNDS
) {
823 const struct rtnl_dump_filter_arg a
[3] = {
825 .filter
= print_addrinfo_secondary
,
831 .filter
= print_addrinfo_primary
,
843 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
844 perror("Cannot send dump request");
848 if (rtnl_dump_filter_l(&rth
, a
) < 0) {
849 fprintf(stderr
, "Flush terminated\n");
852 if (filter
.flushed
== 0) {
856 printf("Nothing to flush.\n");
858 printf("*** Flush is complete after %d round%s ***\n", round
, round
>1?"s":"");
864 if (flush_update() < 0)
868 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
872 /* If we are flushing, and specifying primary, then we
873 * want to flush only a single round. Otherwise, we'll
874 * start flushing secondaries that were promoted to
877 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
880 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", MAX_ROUNDS
); fflush(stderr
);
884 if (filter
.family
!= AF_PACKET
) {
885 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
886 perror("Cannot send dump request");
890 if (rtnl_dump_filter(&rth
, store_nlmsg
, &ainfo
, NULL
, NULL
) < 0) {
891 fprintf(stderr
, "Dump terminated\n");
897 if (filter
.family
&& filter
.family
!= AF_PACKET
) {
898 struct nlmsg_list
**lp
;
904 while ((l
=*lp
)!=NULL
) {
906 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
907 struct nlmsg_list
*a
;
909 for (a
=ainfo
; a
; a
=a
->next
) {
910 struct nlmsghdr
*n
= &a
->h
;
911 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
913 if (ifa
->ifa_index
!= ifi
->ifi_index
||
914 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
916 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
918 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
920 if (filter
.pfx
.family
|| filter
.label
) {
921 struct rtattr
*tb
[IFA_MAX
+1];
922 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
924 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
926 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
928 memset(&dst
, 0, sizeof(dst
));
929 dst
.family
= ifa
->ifa_family
;
930 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
931 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
938 label
= RTA_DATA(tb
[IFA_LABEL
]);
940 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
941 if (fnmatch(filter
.label
, label
, 0) != 0)
956 for (l
=linfo
; l
; l
= n
) {
958 if (no_link
|| print_linkinfo(NULL
, &l
->h
, stdout
) == 0) {
959 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
960 if (filter
.family
!= AF_PACKET
)
961 print_selected_addrinfo(ifi
->ifi_index
, ainfo
, stdout
);
970 int ipaddr_list_link(int argc
, char **argv
)
972 preferred_family
= AF_PACKET
;
974 return ipaddr_list_or_flush(argc
, argv
, 0);
977 void ipaddr_reset_filter(int oneline
)
979 memset(&filter
, 0, sizeof(filter
));
980 filter
.oneline
= oneline
;
983 static int default_scope(inet_prefix
*lcl
)
985 if (lcl
->family
== AF_INET
) {
986 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
987 return RT_SCOPE_HOST
;
992 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
996 struct ifaddrmsg ifa
;
1001 char *lcl_arg
= NULL
;
1002 char *valid_lftp
= NULL
;
1003 char *preferred_lftp
= NULL
;
1011 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
1012 __u32 valid_lft
= INFINITY_LIFE_TIME
;
1013 struct ifa_cacheinfo cinfo
;
1015 memset(&req
, 0, sizeof(req
));
1017 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1018 req
.n
.nlmsg_flags
= NLM_F_REQUEST
| flags
;
1019 req
.n
.nlmsg_type
= cmd
;
1020 req
.ifa
.ifa_family
= preferred_family
;
1023 if (strcmp(*argv
, "peer") == 0 ||
1024 strcmp(*argv
, "remote") == 0) {
1028 duparg("peer", *argv
);
1029 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
1030 peer_len
= peer
.bytelen
;
1031 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1032 req
.ifa
.ifa_family
= peer
.family
;
1033 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
1034 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
1035 } else if (matches(*argv
, "broadcast") == 0 ||
1036 strcmp(*argv
, "brd") == 0) {
1040 duparg("broadcast", *argv
);
1041 if (strcmp(*argv
, "+") == 0)
1043 else if (strcmp(*argv
, "-") == 0)
1046 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1047 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1048 req
.ifa
.ifa_family
= addr
.family
;
1049 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
1050 brd_len
= addr
.bytelen
;
1052 } else if (strcmp(*argv
, "anycast") == 0) {
1056 duparg("anycast", *argv
);
1057 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1058 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1059 req
.ifa
.ifa_family
= addr
.family
;
1060 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
1061 any_len
= addr
.bytelen
;
1062 } else if (strcmp(*argv
, "scope") == 0) {
1065 if (rtnl_rtscope_a2n(&scope
, *argv
))
1066 invarg(*argv
, "invalid scope value.");
1067 req
.ifa
.ifa_scope
= scope
;
1069 } else if (strcmp(*argv
, "dev") == 0) {
1072 } else if (strcmp(*argv
, "label") == 0) {
1075 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
1076 } else if (matches(*argv
, "valid_lft") == 0) {
1078 duparg("valid_lft", *argv
);
1081 if (set_lifetime(&valid_lft
, *argv
))
1082 invarg("valid_lft value", *argv
);
1083 } else if (matches(*argv
, "preferred_lft") == 0) {
1085 duparg("preferred_lft", *argv
);
1087 preferred_lftp
= *argv
;
1088 if (set_lifetime(&preferred_lft
, *argv
))
1089 invarg("preferred_lft value", *argv
);
1090 } else if (strcmp(*argv
, "home") == 0) {
1091 req
.ifa
.ifa_flags
|= IFA_F_HOMEADDRESS
;
1092 } else if (strcmp(*argv
, "nodad") == 0) {
1093 req
.ifa
.ifa_flags
|= IFA_F_NODAD
;
1095 if (strcmp(*argv
, "local") == 0) {
1098 if (matches(*argv
, "help") == 0)
1101 duparg2("local", *argv
);
1103 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
1104 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1105 req
.ifa
.ifa_family
= lcl
.family
;
1106 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
1107 local_len
= lcl
.bytelen
;
1112 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
1115 if (l
&& matches(d
, l
) != 0) {
1116 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
1120 if (peer_len
== 0 && local_len
) {
1121 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
1123 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1124 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1125 " This special behaviour is likely to disappear in further releases,\n" \
1126 " fix your scripts!\n", lcl_arg
, local_len
*8);
1129 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
1132 if (req
.ifa
.ifa_prefixlen
== 0)
1133 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
1135 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
1138 if (req
.ifa
.ifa_family
!= AF_INET
) {
1139 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
1143 if (brd
.bitlen
<= 30) {
1144 for (i
=31; i
>=brd
.bitlen
; i
--) {
1146 brd
.data
[0] |= htonl(1<<(31-i
));
1148 brd
.data
[0] &= ~htonl(1<<(31-i
));
1150 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
1151 brd_len
= brd
.bytelen
;
1154 if (!scoped
&& cmd
!= RTM_DELADDR
)
1155 req
.ifa
.ifa_scope
= default_scope(&lcl
);
1159 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
1160 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
1164 if (valid_lftp
|| preferred_lftp
) {
1166 fprintf(stderr
, "valid_lft is zero\n");
1169 if (valid_lft
< preferred_lft
) {
1170 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
1174 memset(&cinfo
, 0, sizeof(cinfo
));
1175 cinfo
.ifa_prefered
= preferred_lft
;
1176 cinfo
.ifa_valid
= valid_lft
;
1177 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
1181 if (rtnl_talk(&rth
, &req
.n
, 0, 0, NULL
, NULL
, NULL
) < 0)
1187 int do_ipaddr(int argc
, char **argv
)
1190 return ipaddr_list_or_flush(0, NULL
, 0);
1191 if (matches(*argv
, "add") == 0)
1192 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
1193 if (matches(*argv
, "change") == 0 ||
1194 strcmp(*argv
, "chg") == 0)
1195 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
1196 if (matches(*argv
, "replace") == 0)
1197 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
1198 if (matches(*argv
, "delete") == 0)
1199 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
1200 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
1201 || matches(*argv
, "lst") == 0)
1202 return ipaddr_list_or_flush(argc
-1, argv
+1, 0);
1203 if (matches(*argv
, "flush") == 0)
1204 return ipaddr_list_or_flush(argc
-1, argv
+1, 1);
1205 if (matches(*argv
, "help") == 0)
1207 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv
);