]>
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 (tb
[IFLA_GROUP
]) {
251 int group
= *(int*)RTA_DATA(tb
[IFLA_GROUP
]);
252 if (group
!= filter
.group
)
256 if (n
->nlmsg_type
== RTM_DELLINK
)
257 fprintf(fp
, "Deleted ");
259 fprintf(fp
, "%d: %s", ifi
->ifi_index
,
260 tb
[IFLA_IFNAME
] ? (char*)RTA_DATA(tb
[IFLA_IFNAME
]) : "<nil>");
264 int iflink
= *(int*)RTA_DATA(tb
[IFLA_LINK
]);
266 fprintf(fp
, "@NONE: ");
268 fprintf(fp
, "@%s: ", ll_idx_n2a(iflink
, b1
));
269 m_flag
= ll_index_to_flags(iflink
);
270 m_flag
= !(m_flag
& IFF_UP
);
275 print_link_flags(fp
, ifi
->ifi_flags
, m_flag
);
278 fprintf(fp
, "mtu %u ", *(int*)RTA_DATA(tb
[IFLA_MTU
]));
280 fprintf(fp
, "qdisc %s ", (char*)RTA_DATA(tb
[IFLA_QDISC
]));
281 if (tb
[IFLA_MASTER
]) {
283 fprintf(fp
, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb
[IFLA_MASTER
]), b1
));
285 if (tb
[IFLA_OPERSTATE
])
286 print_operstate(fp
, *(__u8
*)RTA_DATA(tb
[IFLA_OPERSTATE
]));
288 if (filter
.showqueue
)
289 print_queuelen(fp
, (char*)RTA_DATA(tb
[IFLA_IFNAME
]));
291 if (!filter
.family
|| filter
.family
== AF_PACKET
) {
293 fprintf(fp
, "%s", _SL_
);
294 fprintf(fp
, " link/%s ", ll_type_n2a(ifi
->ifi_type
, b1
, sizeof(b1
)));
296 if (tb
[IFLA_ADDRESS
]) {
297 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_ADDRESS
]),
298 RTA_PAYLOAD(tb
[IFLA_ADDRESS
]),
302 if (tb
[IFLA_BROADCAST
]) {
303 if (ifi
->ifi_flags
&IFF_POINTOPOINT
)
304 fprintf(fp
, " peer ");
306 fprintf(fp
, " brd ");
307 fprintf(fp
, "%s", ll_addr_n2a(RTA_DATA(tb
[IFLA_BROADCAST
]),
308 RTA_PAYLOAD(tb
[IFLA_BROADCAST
]),
314 if (do_link
&& tb
[IFLA_LINKINFO
] && show_details
)
315 print_linktype(fp
, tb
[IFLA_LINKINFO
]);
317 if (do_link
&& tb
[IFLA_IFALIAS
])
318 fprintf(fp
,"\n alias %s",
319 (const char *) RTA_DATA(tb
[IFLA_IFALIAS
]));
321 if (do_link
&& tb
[IFLA_STATS64
] && show_stats
) {
322 struct rtnl_link_stats64 slocal
;
323 struct rtnl_link_stats64
*s
= RTA_DATA(tb
[IFLA_STATS64
]);
324 if (((unsigned long)s
) & (sizeof(unsigned long)-1)) {
325 memcpy(&slocal
, s
, sizeof(slocal
));
328 fprintf(fp
, "%s", _SL_
);
329 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
330 s
->rx_compressed
? "compressed" : "", _SL_
);
331 fprintf(fp
, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
332 (unsigned long long)s
->rx_bytes
,
333 (unsigned long long)s
->rx_packets
,
334 (unsigned long long)s
->rx_errors
,
335 (unsigned long long)s
->rx_dropped
,
336 (unsigned long long)s
->rx_over_errors
,
337 (unsigned long long)s
->multicast
);
338 if (s
->rx_compressed
)
339 fprintf(fp
, " %-7llu",
340 (unsigned long long)s
->rx_compressed
);
341 if (show_stats
> 1) {
342 fprintf(fp
, "%s", _SL_
);
343 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
344 fprintf(fp
, " %-7llu %-7llu %-7llu %-7llu %-7llu",
345 (unsigned long long)s
->rx_length_errors
,
346 (unsigned long long)s
->rx_crc_errors
,
347 (unsigned long long)s
->rx_frame_errors
,
348 (unsigned long long)s
->rx_fifo_errors
,
349 (unsigned long long)s
->rx_missed_errors
);
351 fprintf(fp
, "%s", _SL_
);
352 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
353 s
->tx_compressed
? "compressed" : "", _SL_
);
354 fprintf(fp
, " %-10llu %-8llu %-7llu %-7llu %-7llu %-7llu",
355 (unsigned long long)s
->tx_bytes
,
356 (unsigned long long)s
->tx_packets
,
357 (unsigned long long)s
->tx_errors
,
358 (unsigned long long)s
->tx_dropped
,
359 (unsigned long long)s
->tx_carrier_errors
,
360 (unsigned long long)s
->collisions
);
361 if (s
->tx_compressed
)
362 fprintf(fp
, " %-7llu",
363 (unsigned long long)s
->tx_compressed
);
364 if (show_stats
> 1) {
365 fprintf(fp
, "%s", _SL_
);
366 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
367 fprintf(fp
, " %-7llu %-7llu %-7llu %-7llu",
368 (unsigned long long)s
->tx_aborted_errors
,
369 (unsigned long long)s
->tx_fifo_errors
,
370 (unsigned long long)s
->tx_window_errors
,
371 (unsigned long long)s
->tx_heartbeat_errors
);
374 if (do_link
&& !tb
[IFLA_STATS64
] && tb
[IFLA_STATS
] && show_stats
) {
375 struct rtnl_link_stats slocal
;
376 struct rtnl_link_stats
*s
= RTA_DATA(tb
[IFLA_STATS
]);
377 if (((unsigned long)s
) & (sizeof(unsigned long)-1)) {
378 memcpy(&slocal
, s
, sizeof(slocal
));
381 fprintf(fp
, "%s", _SL_
);
382 fprintf(fp
, " RX: bytes packets errors dropped overrun mcast %s%s",
383 s
->rx_compressed
? "compressed" : "", _SL_
);
384 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
385 s
->rx_bytes
, s
->rx_packets
, s
->rx_errors
,
386 s
->rx_dropped
, s
->rx_over_errors
,
389 if (s
->rx_compressed
)
390 fprintf(fp
, " %-7u", s
->rx_compressed
);
391 if (show_stats
> 1) {
392 fprintf(fp
, "%s", _SL_
);
393 fprintf(fp
, " RX errors: length crc frame fifo missed%s", _SL_
);
394 fprintf(fp
, " %-7u %-7u %-7u %-7u %-7u",
402 fprintf(fp
, "%s", _SL_
);
403 fprintf(fp
, " TX: bytes packets errors dropped carrier collsns %s%s",
404 s
->tx_compressed
? "compressed" : "", _SL_
);
405 fprintf(fp
, " %-10u %-8u %-7u %-7u %-7u %-7u",
406 s
->tx_bytes
, s
->tx_packets
, s
->tx_errors
,
407 s
->tx_dropped
, s
->tx_carrier_errors
, s
->collisions
);
408 if (s
->tx_compressed
)
409 fprintf(fp
, " %-7u", s
->tx_compressed
);
410 if (show_stats
> 1) {
411 fprintf(fp
, "%s", _SL_
);
412 fprintf(fp
, " TX errors: aborted fifo window heartbeat%s", _SL_
);
413 fprintf(fp
, " %-7u %-7u %-7u %-7u",
414 s
->tx_aborted_errors
,
417 s
->tx_heartbeat_errors
421 if (do_link
&& tb
[IFLA_VFINFO_LIST
] && tb
[IFLA_NUM_VF
]) {
422 struct rtattr
*i
, *vflist
= tb
[IFLA_VFINFO_LIST
];
423 int rem
= RTA_PAYLOAD(vflist
);
424 for (i
= RTA_DATA(vflist
); RTA_OK(i
, rem
); i
= RTA_NEXT(i
, rem
))
433 static int flush_update(void)
435 if (rtnl_send_check(&rth
, filter
.flushb
, filter
.flushp
) < 0) {
436 perror("Failed to send flush request");
443 static int set_lifetime(unsigned int *lifetime
, char *argv
)
445 if (strcmp(argv
, "forever") == 0)
446 *lifetime
= INFINITY_LIFE_TIME
;
447 else if (get_u32(lifetime
, argv
, 0))
453 int print_addrinfo(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
456 FILE *fp
= (FILE*)arg
;
457 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
458 int len
= n
->nlmsg_len
;
460 /* Use local copy of ifa_flags to not interfere with filtering code */
461 unsigned int ifa_flags
;
462 struct rtattr
* rta_tb
[IFA_MAX
+1];
466 if (n
->nlmsg_type
!= RTM_NEWADDR
&& n
->nlmsg_type
!= RTM_DELADDR
)
468 len
-= NLMSG_LENGTH(sizeof(*ifa
));
470 fprintf(stderr
, "BUG: wrong nlmsg len %d\n", len
);
474 if (filter
.flushb
&& n
->nlmsg_type
!= RTM_NEWADDR
)
477 parse_rtattr(rta_tb
, IFA_MAX
, IFA_RTA(ifa
), n
->nlmsg_len
- NLMSG_LENGTH(sizeof(*ifa
)));
479 if (!rta_tb
[IFA_LOCAL
])
480 rta_tb
[IFA_LOCAL
] = rta_tb
[IFA_ADDRESS
];
481 if (!rta_tb
[IFA_ADDRESS
])
482 rta_tb
[IFA_ADDRESS
] = rta_tb
[IFA_LOCAL
];
484 if (filter
.ifindex
&& filter
.ifindex
!= ifa
->ifa_index
)
486 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
488 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
493 if (rta_tb
[IFA_LABEL
])
494 label
= RTA_DATA(rta_tb
[IFA_LABEL
]);
496 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
497 if (fnmatch(filter
.label
, label
, 0) != 0)
500 if (filter
.pfx
.family
) {
501 if (rta_tb
[IFA_LOCAL
]) {
503 memset(&dst
, 0, sizeof(dst
));
504 dst
.family
= ifa
->ifa_family
;
505 memcpy(&dst
.data
, RTA_DATA(rta_tb
[IFA_LOCAL
]), RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]));
506 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
511 if (filter
.family
&& filter
.family
!= ifa
->ifa_family
)
516 if (NLMSG_ALIGN(filter
.flushp
) + n
->nlmsg_len
> filter
.flushe
) {
520 fn
= (struct nlmsghdr
*)(filter
.flushb
+ NLMSG_ALIGN(filter
.flushp
));
521 memcpy(fn
, n
, n
->nlmsg_len
);
522 fn
->nlmsg_type
= RTM_DELADDR
;
523 fn
->nlmsg_flags
= NLM_F_REQUEST
;
524 fn
->nlmsg_seq
= ++rth
.seq
;
525 filter
.flushp
= (((char*)fn
) + n
->nlmsg_len
) - filter
.flushb
;
531 if (n
->nlmsg_type
== RTM_DELADDR
)
532 fprintf(fp
, "Deleted ");
534 if (filter
.oneline
|| filter
.flushb
)
535 fprintf(fp
, "%u: %s", ifa
->ifa_index
, ll_index_to_name(ifa
->ifa_index
));
536 if (ifa
->ifa_family
== AF_INET
)
537 fprintf(fp
, " inet ");
538 else if (ifa
->ifa_family
== AF_INET6
)
539 fprintf(fp
, " inet6 ");
540 else if (ifa
->ifa_family
== AF_DECnet
)
541 fprintf(fp
, " dnet ");
542 else if (ifa
->ifa_family
== AF_IPX
)
543 fprintf(fp
, " ipx ");
545 fprintf(fp
, " family %d ", ifa
->ifa_family
);
547 if (rta_tb
[IFA_LOCAL
]) {
548 fprintf(fp
, "%s", rt_addr_n2a(ifa
->ifa_family
,
549 RTA_PAYLOAD(rta_tb
[IFA_LOCAL
]),
550 RTA_DATA(rta_tb
[IFA_LOCAL
]),
551 abuf
, sizeof(abuf
)));
553 if (rta_tb
[IFA_ADDRESS
] == NULL
||
554 memcmp(RTA_DATA(rta_tb
[IFA_ADDRESS
]), RTA_DATA(rta_tb
[IFA_LOCAL
]), 4) == 0) {
555 fprintf(fp
, "/%d ", ifa
->ifa_prefixlen
);
557 fprintf(fp
, " peer %s/%d ",
558 rt_addr_n2a(ifa
->ifa_family
,
559 RTA_PAYLOAD(rta_tb
[IFA_ADDRESS
]),
560 RTA_DATA(rta_tb
[IFA_ADDRESS
]),
566 if (rta_tb
[IFA_BROADCAST
]) {
567 fprintf(fp
, "brd %s ",
568 rt_addr_n2a(ifa
->ifa_family
,
569 RTA_PAYLOAD(rta_tb
[IFA_BROADCAST
]),
570 RTA_DATA(rta_tb
[IFA_BROADCAST
]),
571 abuf
, sizeof(abuf
)));
573 if (rta_tb
[IFA_ANYCAST
]) {
574 fprintf(fp
, "any %s ",
575 rt_addr_n2a(ifa
->ifa_family
,
576 RTA_PAYLOAD(rta_tb
[IFA_ANYCAST
]),
577 RTA_DATA(rta_tb
[IFA_ANYCAST
]),
578 abuf
, sizeof(abuf
)));
580 fprintf(fp
, "scope %s ", rtnl_rtscope_n2a(ifa
->ifa_scope
, b1
, sizeof(b1
)));
581 ifa_flags
= ifa
->ifa_flags
;
582 if (ifa
->ifa_flags
&IFA_F_SECONDARY
) {
583 ifa_flags
&= ~IFA_F_SECONDARY
;
584 if (ifa
->ifa_family
== AF_INET6
)
585 fprintf(fp
, "temporary ");
587 fprintf(fp
, "secondary ");
589 if (ifa
->ifa_flags
&IFA_F_TENTATIVE
) {
590 ifa_flags
&= ~IFA_F_TENTATIVE
;
591 fprintf(fp
, "tentative ");
593 if (ifa
->ifa_flags
&IFA_F_DEPRECATED
) {
594 ifa_flags
&= ~IFA_F_DEPRECATED
;
596 fprintf(fp
, "deprecated ");
598 if (ifa
->ifa_flags
&IFA_F_HOMEADDRESS
) {
599 ifa_flags
&= ~IFA_F_HOMEADDRESS
;
600 fprintf(fp
, "home ");
602 if (ifa
->ifa_flags
&IFA_F_NODAD
) {
603 ifa_flags
&= ~IFA_F_NODAD
;
604 fprintf(fp
, "nodad ");
606 if (!(ifa
->ifa_flags
&IFA_F_PERMANENT
)) {
607 fprintf(fp
, "dynamic ");
609 ifa_flags
&= ~IFA_F_PERMANENT
;
610 if (ifa
->ifa_flags
&IFA_F_DADFAILED
) {
611 ifa_flags
&= ~IFA_F_DADFAILED
;
612 fprintf(fp
, "dadfailed ");
615 fprintf(fp
, "flags %02x ", ifa_flags
);
616 if (rta_tb
[IFA_LABEL
])
617 fprintf(fp
, "%s", (char*)RTA_DATA(rta_tb
[IFA_LABEL
]));
618 if (rta_tb
[IFA_CACHEINFO
]) {
619 struct ifa_cacheinfo
*ci
= RTA_DATA(rta_tb
[IFA_CACHEINFO
]);
620 fprintf(fp
, "%s", _SL_
);
621 fprintf(fp
, " valid_lft ");
622 if (ci
->ifa_valid
== INFINITY_LIFE_TIME
)
623 fprintf(fp
, "forever");
625 fprintf(fp
, "%usec", ci
->ifa_valid
);
626 fprintf(fp
, " preferred_lft ");
627 if (ci
->ifa_prefered
== INFINITY_LIFE_TIME
)
628 fprintf(fp
, "forever");
631 fprintf(fp
, "%dsec", ci
->ifa_prefered
);
633 fprintf(fp
, "%usec", ci
->ifa_prefered
);
641 int print_addrinfo_primary(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
644 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
646 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
649 return print_addrinfo(who
, n
, arg
);
652 int print_addrinfo_secondary(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
655 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
657 if (!(ifa
->ifa_flags
& IFA_F_SECONDARY
))
660 return print_addrinfo(who
, n
, arg
);
665 struct nlmsg_list
*next
;
669 static int print_selected_addrinfo(int ifindex
, struct nlmsg_list
*ainfo
, FILE *fp
)
671 for ( ;ainfo
; ainfo
= ainfo
->next
) {
672 struct nlmsghdr
*n
= &ainfo
->h
;
673 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
675 if (n
->nlmsg_type
!= RTM_NEWADDR
)
678 if (n
->nlmsg_len
< NLMSG_LENGTH(sizeof(ifa
)))
681 if (ifa
->ifa_index
!= ifindex
||
682 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
685 print_addrinfo(NULL
, n
, fp
);
691 static int store_nlmsg(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
,
694 struct nlmsg_list
**linfo
= (struct nlmsg_list
**)arg
;
695 struct nlmsg_list
*h
;
696 struct nlmsg_list
**lp
;
698 h
= malloc(n
->nlmsg_len
+sizeof(void*));
702 memcpy(&h
->h
, n
, n
->nlmsg_len
);
705 for (lp
= linfo
; *lp
; lp
= &(*lp
)->next
) /* NOTHING */;
708 ll_remember_index(who
, n
, NULL
);
712 static int ipaddr_list_or_flush(int argc
, char **argv
, int flush
)
714 struct nlmsg_list
*linfo
= NULL
;
715 struct nlmsg_list
*ainfo
= NULL
;
716 struct nlmsg_list
*l
, *n
;
717 char *filter_dev
= NULL
;
720 ipaddr_reset_filter(oneline
);
721 filter
.showqueue
= 1;
723 if (filter
.family
== AF_UNSPEC
)
724 filter
.family
= preferred_family
;
726 filter
.group
= INIT_NETDEV_GROUP
;
730 fprintf(stderr
, "Flush requires arguments.\n");
734 if (filter
.family
== AF_PACKET
) {
735 fprintf(stderr
, "Cannot flush link addresses.\n");
741 if (strcmp(*argv
, "to") == 0) {
743 get_prefix(&filter
.pfx
, *argv
, filter
.family
);
744 if (filter
.family
== AF_UNSPEC
)
745 filter
.family
= filter
.pfx
.family
;
746 } else if (strcmp(*argv
, "scope") == 0) {
749 filter
.scopemask
= -1;
750 if (rtnl_rtscope_a2n(&scope
, *argv
)) {
751 if (strcmp(*argv
, "all") != 0)
752 invarg("invalid \"scope\"\n", *argv
);
753 scope
= RT_SCOPE_NOWHERE
;
754 filter
.scopemask
= 0;
756 filter
.scope
= scope
;
757 } else if (strcmp(*argv
, "up") == 0) {
759 } else if (strcmp(*argv
, "dynamic") == 0) {
760 filter
.flags
&= ~IFA_F_PERMANENT
;
761 filter
.flagmask
|= IFA_F_PERMANENT
;
762 } else if (strcmp(*argv
, "permanent") == 0) {
763 filter
.flags
|= IFA_F_PERMANENT
;
764 filter
.flagmask
|= IFA_F_PERMANENT
;
765 } else if (strcmp(*argv
, "secondary") == 0 ||
766 strcmp(*argv
, "temporary") == 0) {
767 filter
.flags
|= IFA_F_SECONDARY
;
768 filter
.flagmask
|= IFA_F_SECONDARY
;
769 } else if (strcmp(*argv
, "primary") == 0) {
770 filter
.flags
&= ~IFA_F_SECONDARY
;
771 filter
.flagmask
|= IFA_F_SECONDARY
;
772 } else if (strcmp(*argv
, "tentative") == 0) {
773 filter
.flags
|= IFA_F_TENTATIVE
;
774 filter
.flagmask
|= IFA_F_TENTATIVE
;
775 } else if (strcmp(*argv
, "deprecated") == 0) {
776 filter
.flags
|= IFA_F_DEPRECATED
;
777 filter
.flagmask
|= IFA_F_DEPRECATED
;
778 } else if (strcmp(*argv
, "home") == 0) {
779 filter
.flags
|= IFA_F_HOMEADDRESS
;
780 filter
.flagmask
|= IFA_F_HOMEADDRESS
;
781 } else if (strcmp(*argv
, "nodad") == 0) {
782 filter
.flags
|= IFA_F_NODAD
;
783 filter
.flagmask
|= IFA_F_NODAD
;
784 } else if (strcmp(*argv
, "dadfailed") == 0) {
785 filter
.flags
|= IFA_F_DADFAILED
;
786 filter
.flagmask
|= IFA_F_DADFAILED
;
787 } else if (strcmp(*argv
, "label") == 0) {
789 filter
.label
= *argv
;
790 } else if (strcmp(*argv
, "group") == 0) {
792 if (rtnl_group_a2n(&filter
.group
, *argv
))
793 invarg("Invalid \"group\" value\n", *argv
);
795 if (strcmp(*argv
, "dev") == 0) {
798 if (matches(*argv
, "help") == 0)
801 duparg2("dev", *argv
);
807 if (rtnl_wilddump_request(&rth
, preferred_family
, RTM_GETLINK
) < 0) {
808 perror("Cannot send dump request");
812 if (rtnl_dump_filter(&rth
, store_nlmsg
, &linfo
, NULL
, NULL
) < 0) {
813 fprintf(stderr
, "Dump terminated\n");
818 filter
.ifindex
= ll_name_to_index(filter_dev
);
819 if (filter
.ifindex
<= 0) {
820 fprintf(stderr
, "Device \"%s\" does not exist.\n", filter_dev
);
827 char flushb
[4096-512];
829 filter
.flushb
= flushb
;
831 filter
.flushe
= sizeof(flushb
);
833 while ((max_flush_loops
== 0) || (round
< max_flush_loops
)) {
834 const struct rtnl_dump_filter_arg a
[3] = {
836 .filter
= print_addrinfo_secondary
,
842 .filter
= print_addrinfo_primary
,
854 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
855 perror("Cannot send dump request");
859 if (rtnl_dump_filter_l(&rth
, a
) < 0) {
860 fprintf(stderr
, "Flush terminated\n");
863 if (filter
.flushed
== 0) {
867 printf("Nothing to flush.\n");
869 printf("*** Flush is complete after %d round%s ***\n", round
, round
>1?"s":"");
875 if (flush_update() < 0)
879 printf("\n*** Round %d, deleting %d addresses ***\n", round
, filter
.flushed
);
883 /* If we are flushing, and specifying primary, then we
884 * want to flush only a single round. Otherwise, we'll
885 * start flushing secondaries that were promoted to
888 if (!(filter
.flags
& IFA_F_SECONDARY
) && (filter
.flagmask
& IFA_F_SECONDARY
))
891 fprintf(stderr
, "*** Flush remains incomplete after %d rounds. ***\n", max_flush_loops
);
896 if (filter
.family
!= AF_PACKET
) {
897 if (rtnl_wilddump_request(&rth
, filter
.family
, RTM_GETADDR
) < 0) {
898 perror("Cannot send dump request");
902 if (rtnl_dump_filter(&rth
, store_nlmsg
, &ainfo
, NULL
, NULL
) < 0) {
903 fprintf(stderr
, "Dump terminated\n");
909 if (filter
.family
&& filter
.family
!= AF_PACKET
) {
910 struct nlmsg_list
**lp
;
916 while ((l
=*lp
)!=NULL
) {
918 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
919 struct nlmsg_list
*a
;
921 for (a
=ainfo
; a
; a
=a
->next
) {
922 struct nlmsghdr
*n
= &a
->h
;
923 struct ifaddrmsg
*ifa
= NLMSG_DATA(n
);
925 if (ifa
->ifa_index
!= ifi
->ifi_index
||
926 (filter
.family
&& filter
.family
!= ifa
->ifa_family
))
928 if ((filter
.scope
^ifa
->ifa_scope
)&filter
.scopemask
)
930 if ((filter
.flags
^ifa
->ifa_flags
)&filter
.flagmask
)
932 if (filter
.pfx
.family
|| filter
.label
) {
933 struct rtattr
*tb
[IFA_MAX
+1];
934 parse_rtattr(tb
, IFA_MAX
, IFA_RTA(ifa
), IFA_PAYLOAD(n
));
936 tb
[IFA_LOCAL
] = tb
[IFA_ADDRESS
];
938 if (filter
.pfx
.family
&& tb
[IFA_LOCAL
]) {
940 memset(&dst
, 0, sizeof(dst
));
941 dst
.family
= ifa
->ifa_family
;
942 memcpy(&dst
.data
, RTA_DATA(tb
[IFA_LOCAL
]), RTA_PAYLOAD(tb
[IFA_LOCAL
]));
943 if (inet_addr_match(&dst
, &filter
.pfx
, filter
.pfx
.bitlen
))
950 label
= RTA_DATA(tb
[IFA_LABEL
]);
952 label
= ll_idx_n2a(ifa
->ifa_index
, b1
);
953 if (fnmatch(filter
.label
, label
, 0) != 0)
968 for (l
=linfo
; l
; l
= n
) {
970 if (no_link
|| print_linkinfo(NULL
, &l
->h
, stdout
) == 0) {
971 struct ifinfomsg
*ifi
= NLMSG_DATA(&l
->h
);
972 if (filter
.family
!= AF_PACKET
)
973 print_selected_addrinfo(ifi
->ifi_index
, ainfo
, stdout
);
982 int ipaddr_list_link(int argc
, char **argv
)
984 preferred_family
= AF_PACKET
;
986 return ipaddr_list_or_flush(argc
, argv
, 0);
989 void ipaddr_reset_filter(int oneline
)
991 memset(&filter
, 0, sizeof(filter
));
992 filter
.oneline
= oneline
;
995 static int default_scope(inet_prefix
*lcl
)
997 if (lcl
->family
== AF_INET
) {
998 if (lcl
->bytelen
>= 1 && *(__u8
*)&lcl
->data
== 127)
999 return RT_SCOPE_HOST
;
1004 static int ipaddr_modify(int cmd
, int flags
, int argc
, char **argv
)
1008 struct ifaddrmsg ifa
;
1013 char *lcl_arg
= NULL
;
1014 char *valid_lftp
= NULL
;
1015 char *preferred_lftp
= NULL
;
1023 __u32 preferred_lft
= INFINITY_LIFE_TIME
;
1024 __u32 valid_lft
= INFINITY_LIFE_TIME
;
1025 struct ifa_cacheinfo cinfo
;
1027 memset(&req
, 0, sizeof(req
));
1029 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifaddrmsg
));
1030 req
.n
.nlmsg_flags
= NLM_F_REQUEST
| flags
;
1031 req
.n
.nlmsg_type
= cmd
;
1032 req
.ifa
.ifa_family
= preferred_family
;
1035 if (strcmp(*argv
, "peer") == 0 ||
1036 strcmp(*argv
, "remote") == 0) {
1040 duparg("peer", *argv
);
1041 get_prefix(&peer
, *argv
, req
.ifa
.ifa_family
);
1042 peer_len
= peer
.bytelen
;
1043 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1044 req
.ifa
.ifa_family
= peer
.family
;
1045 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &peer
.data
, peer
.bytelen
);
1046 req
.ifa
.ifa_prefixlen
= peer
.bitlen
;
1047 } else if (matches(*argv
, "broadcast") == 0 ||
1048 strcmp(*argv
, "brd") == 0) {
1052 duparg("broadcast", *argv
);
1053 if (strcmp(*argv
, "+") == 0)
1055 else if (strcmp(*argv
, "-") == 0)
1058 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1059 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1060 req
.ifa
.ifa_family
= addr
.family
;
1061 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &addr
.data
, addr
.bytelen
);
1062 brd_len
= addr
.bytelen
;
1064 } else if (strcmp(*argv
, "anycast") == 0) {
1068 duparg("anycast", *argv
);
1069 get_addr(&addr
, *argv
, req
.ifa
.ifa_family
);
1070 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1071 req
.ifa
.ifa_family
= addr
.family
;
1072 addattr_l(&req
.n
, sizeof(req
), IFA_ANYCAST
, &addr
.data
, addr
.bytelen
);
1073 any_len
= addr
.bytelen
;
1074 } else if (strcmp(*argv
, "scope") == 0) {
1077 if (rtnl_rtscope_a2n(&scope
, *argv
))
1078 invarg(*argv
, "invalid scope value.");
1079 req
.ifa
.ifa_scope
= scope
;
1081 } else if (strcmp(*argv
, "dev") == 0) {
1084 } else if (strcmp(*argv
, "label") == 0) {
1087 addattr_l(&req
.n
, sizeof(req
), IFA_LABEL
, l
, strlen(l
)+1);
1088 } else if (matches(*argv
, "valid_lft") == 0) {
1090 duparg("valid_lft", *argv
);
1093 if (set_lifetime(&valid_lft
, *argv
))
1094 invarg("valid_lft value", *argv
);
1095 } else if (matches(*argv
, "preferred_lft") == 0) {
1097 duparg("preferred_lft", *argv
);
1099 preferred_lftp
= *argv
;
1100 if (set_lifetime(&preferred_lft
, *argv
))
1101 invarg("preferred_lft value", *argv
);
1102 } else if (strcmp(*argv
, "home") == 0) {
1103 req
.ifa
.ifa_flags
|= IFA_F_HOMEADDRESS
;
1104 } else if (strcmp(*argv
, "nodad") == 0) {
1105 req
.ifa
.ifa_flags
|= IFA_F_NODAD
;
1107 if (strcmp(*argv
, "local") == 0) {
1110 if (matches(*argv
, "help") == 0)
1113 duparg2("local", *argv
);
1115 get_prefix(&lcl
, *argv
, req
.ifa
.ifa_family
);
1116 if (req
.ifa
.ifa_family
== AF_UNSPEC
)
1117 req
.ifa
.ifa_family
= lcl
.family
;
1118 addattr_l(&req
.n
, sizeof(req
), IFA_LOCAL
, &lcl
.data
, lcl
.bytelen
);
1119 local_len
= lcl
.bytelen
;
1124 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
1127 if (l
&& matches(d
, l
) != 0) {
1128 fprintf(stderr
, "\"dev\" (%s) must match \"label\" (%s).\n", d
, l
);
1132 if (peer_len
== 0 && local_len
) {
1133 if (cmd
== RTM_DELADDR
&& lcl
.family
== AF_INET
&& !(lcl
.flags
& PREFIXLEN_SPECIFIED
)) {
1135 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \
1136 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \
1137 " This special behaviour is likely to disappear in further releases,\n" \
1138 " fix your scripts!\n", lcl_arg
, local_len
*8);
1141 addattr_l(&req
.n
, sizeof(req
), IFA_ADDRESS
, &lcl
.data
, lcl
.bytelen
);
1144 if (req
.ifa
.ifa_prefixlen
== 0)
1145 req
.ifa
.ifa_prefixlen
= lcl
.bitlen
;
1147 if (brd_len
< 0 && cmd
!= RTM_DELADDR
) {
1150 if (req
.ifa
.ifa_family
!= AF_INET
) {
1151 fprintf(stderr
, "Broadcast can be set only for IPv4 addresses\n");
1155 if (brd
.bitlen
<= 30) {
1156 for (i
=31; i
>=brd
.bitlen
; i
--) {
1158 brd
.data
[0] |= htonl(1<<(31-i
));
1160 brd
.data
[0] &= ~htonl(1<<(31-i
));
1162 addattr_l(&req
.n
, sizeof(req
), IFA_BROADCAST
, &brd
.data
, brd
.bytelen
);
1163 brd_len
= brd
.bytelen
;
1166 if (!scoped
&& cmd
!= RTM_DELADDR
)
1167 req
.ifa
.ifa_scope
= default_scope(&lcl
);
1171 if ((req
.ifa
.ifa_index
= ll_name_to_index(d
)) == 0) {
1172 fprintf(stderr
, "Cannot find device \"%s\"\n", d
);
1176 if (valid_lftp
|| preferred_lftp
) {
1178 fprintf(stderr
, "valid_lft is zero\n");
1181 if (valid_lft
< preferred_lft
) {
1182 fprintf(stderr
, "preferred_lft is greater than valid_lft\n");
1186 memset(&cinfo
, 0, sizeof(cinfo
));
1187 cinfo
.ifa_prefered
= preferred_lft
;
1188 cinfo
.ifa_valid
= valid_lft
;
1189 addattr_l(&req
.n
, sizeof(req
), IFA_CACHEINFO
, &cinfo
,
1193 if (rtnl_talk(&rth
, &req
.n
, 0, 0, NULL
, NULL
, NULL
) < 0)
1199 int do_ipaddr(int argc
, char **argv
)
1202 return ipaddr_list_or_flush(0, NULL
, 0);
1203 if (matches(*argv
, "add") == 0)
1204 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_EXCL
, argc
-1, argv
+1);
1205 if (matches(*argv
, "change") == 0 ||
1206 strcmp(*argv
, "chg") == 0)
1207 return ipaddr_modify(RTM_NEWADDR
, NLM_F_REPLACE
, argc
-1, argv
+1);
1208 if (matches(*argv
, "replace") == 0)
1209 return ipaddr_modify(RTM_NEWADDR
, NLM_F_CREATE
|NLM_F_REPLACE
, argc
-1, argv
+1);
1210 if (matches(*argv
, "delete") == 0)
1211 return ipaddr_modify(RTM_DELADDR
, 0, argc
-1, argv
+1);
1212 if (matches(*argv
, "list") == 0 || matches(*argv
, "show") == 0
1213 || matches(*argv
, "lst") == 0)
1214 return ipaddr_list_or_flush(argc
-1, argv
+1, 0);
1215 if (matches(*argv
, "flush") == 0)
1216 return ipaddr_list_or_flush(argc
-1, argv
+1, 1);
1217 if (matches(*argv
, "help") == 0)
1219 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip addr help\".\n", *argv
);