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