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@ms2.inr.ac.ru> 10 * 11 * Changes: 12 * Laszlo Valko <valko@linux.karinthy.hu> 990223: address label must be zero terminated 13 */ 14 15#include <stdio.h> 16#include <stdlib.h> 17#include <unistd.h> 18#include <syslog.h> 19#include <fcntl.h> 20#include <sys/ioctl.h> 21#include <sys/socket.h> 22#include <sys/ioctl.h> 23#include <netinet/in.h> 24#include <arpa/inet.h> 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 37static struct 38{ 39 int ifindex; 40 int family; 41 int oneline; 42 int showqueue; 43 inet_prefix pfx; 44 int scope, scopemask; 45 int flags, flagmask; 46 int up; 47 char *label; 48 int flushed; 49 char *flushb; 50 int flushp; 51 int flushe; 52} filter; 53 54static int do_link; 55 56static void usage(void) __attribute__((noreturn)); 57 58static void usage(void) 59{ 60 if (do_link) { 61 iplink_usage(); 62 } 63 fprintf(stderr, "Usage: ip addr {add|change|replace} IFADDR dev STRING [ LIFETIME ]\n"); 64 fprintf(stderr, " ip addr del IFADDR dev STRING\n"); 65 fprintf(stderr, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n"); 66 fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n"); 67 fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n"); 68 fprintf(stderr, " [ broadcast ADDR ] [ anycast ADDR ]\n"); 69 fprintf(stderr, " [ label STRING ] [ scope SCOPE-ID ]\n"); 70 fprintf(stderr, "SCOPE-ID := [ host | link | global | NUMBER ]\n"); 71 fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n"); 72 fprintf(stderr, "FLAG := [ permanent | dynamic | secondary | primary |\n"); 73 fprintf(stderr, " tentative | deprecated ]\n"); 74 fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n"); 75 fprintf(stderr, "LFT := forever | SECONDS\n"); 76 77 exit(-1); 78} 79 80void print_link_flags(FILE *fp, unsigned flags, unsigned mdown) 81{ 82 fprintf(fp, "<"); 83 if (flags & IFF_UP && !(flags & IFF_RUNNING)) 84 fprintf(fp, "NO-CARRIER%s", flags ? "," : ""); 85 flags &= ~IFF_RUNNING; 86#define _PF(f) if (flags&IFF_##f) { \ 87 flags &= ~IFF_##f ; \ 88 fprintf(fp, #f "%s", flags ? "," : ""); } 89 _PF(LOOPBACK); 90 _PF(BROADCAST); 91 _PF(POINTOPOINT); 92 _PF(MULTICAST); 93 _PF(NOARP); 94 _PF(ALLMULTI); 95 _PF(PROMISC); 96 _PF(MASTER); 97 _PF(SLAVE); 98 _PF(DEBUG); 99 _PF(DYNAMIC); 100 _PF(AUTOMEDIA); 101 _PF(PORTSEL); 102 _PF(NOTRAILERS); 103 _PF(UP); 104#undef _PF 105 if (flags) 106 fprintf(fp, "%x", flags); 107 if (mdown) 108 fprintf(fp, ",M-DOWN"); 109 fprintf(fp, "> "); 110} 111 112void print_queuelen(char *name) 113{ 114 struct ifreq ifr; 115 int s; 116 117 s = socket(AF_INET, SOCK_STREAM, 0); 118 if (s < 0) 119 return; 120 121 memset(&ifr, 0, sizeof(ifr)); 122 strcpy(ifr.ifr_name, name); 123 if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { 124 perror("SIOCGIFXQLEN"); 125 close(s); 126 return; 127 } 128 close(s); 129 130 if (ifr.ifr_qlen) 131 printf("qlen %d", ifr.ifr_qlen); 132} 133 134int print_linkinfo(const struct sockaddr_nl *who, 135 struct nlmsghdr *n, void *arg) 136{ 137 FILE *fp = (FILE*)arg; 138 struct ifinfomsg *ifi = NLMSG_DATA(n); 139 struct rtattr * tb[IFLA_MAX+1]; 140 int len = n->nlmsg_len; 141 unsigned m_flag = 0; 142 143 if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK) 144 return 0; 145 146 len -= NLMSG_LENGTH(sizeof(*ifi)); 147 if (len < 0) 148 return -1; 149 150 if (filter.ifindex && ifi->ifi_index != filter.ifindex) 151 return 0; 152 if (filter.up && !(ifi->ifi_flags&IFF_UP)) 153 return 0; 154 155 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 156 if (tb[IFLA_IFNAME] == NULL) { 157 fprintf(stderr, "BUG: nil ifname\n"); 158 return -1; 159 } 160 if (filter.label && 161 (!filter.family || filter.family == AF_PACKET) && 162 fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) 163 return 0; 164 165 if (n->nlmsg_type == RTM_DELLINK) 166 fprintf(fp, "Deleted "); 167 168 fprintf(fp, "%d: %s", ifi->ifi_index, 169 tb[IFLA_IFNAME] ? (char*)RTA_DATA(tb[IFLA_IFNAME]) : "<nil>"); 170 171 if (tb[IFLA_LINK]) { 172 SPRINT_BUF(b1); 173 int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); 174 if (iflink == 0) 175 fprintf(fp, "@NONE: "); 176 else { 177 fprintf(fp, "@%s: ", ll_idx_n2a(iflink, b1)); 178 m_flag = ll_index_to_flags(iflink); 179 m_flag = !(m_flag & IFF_UP); 180 } 181 } else { 182 fprintf(fp, ": "); 183 } 184 print_link_flags(fp, ifi->ifi_flags, m_flag); 185 186 if (tb[IFLA_MTU]) 187 fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU])); 188 if (tb[IFLA_QDISC]) 189 fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); 190#ifdef IFLA_MASTER 191 if (tb[IFLA_MASTER]) { 192 SPRINT_BUF(b1); 193 fprintf(fp, "master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); 194 } 195#endif 196 if (filter.showqueue) 197 print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME])); 198 199 if (!filter.family || filter.family == AF_PACKET) { 200 SPRINT_BUF(b1); 201 fprintf(fp, "%s", _SL_); 202 fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); 203 204 if (tb[IFLA_ADDRESS]) { 205 fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_ADDRESS]), 206 RTA_PAYLOAD(tb[IFLA_ADDRESS]), 207 ifi->ifi_type, 208 b1, sizeof(b1))); 209 } 210 if (tb[IFLA_BROADCAST]) { 211 if (ifi->ifi_flags&IFF_POINTOPOINT) 212 fprintf(fp, " peer "); 213 else 214 fprintf(fp, " brd "); 215 fprintf(fp, "%s", ll_addr_n2a(RTA_DATA(tb[IFLA_BROADCAST]), 216 RTA_PAYLOAD(tb[IFLA_BROADCAST]), 217 ifi->ifi_type, 218 b1, sizeof(b1))); 219 } 220 } 221 if (do_link && tb[IFLA_STATS] && show_stats) { 222 struct rtnl_link_stats slocal; 223 struct rtnl_link_stats *s = RTA_DATA(tb[IFLA_STATS]); 224 if (((unsigned long)s) & (sizeof(unsigned long)-1)) { 225 memcpy(&slocal, s, sizeof(slocal)); 226 s = &slocal; 227 } 228 fprintf(fp, "%s", _SL_); 229 fprintf(fp, " RX: bytes packets errors dropped overrun mcast %s%s", 230 s->rx_compressed ? "compressed" : "", _SL_); 231 fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", 232 s->rx_bytes, s->rx_packets, s->rx_errors, 233 s->rx_dropped, s->rx_over_errors, 234 s->multicast 235 ); 236 if (s->rx_compressed) 237 fprintf(fp, " %-7u", s->rx_compressed); 238 if (show_stats > 1) { 239 fprintf(fp, "%s", _SL_); 240 fprintf(fp, " RX errors: length crc frame fifo missed%s", _SL_); 241 fprintf(fp, " %-7u %-7u %-7u %-7u %-7u", 242 s->rx_length_errors, 243 s->rx_crc_errors, 244 s->rx_frame_errors, 245 s->rx_fifo_errors, 246 s->rx_missed_errors 247 ); 248 } 249 fprintf(fp, "%s", _SL_); 250 fprintf(fp, " TX: bytes packets errors dropped carrier collsns %s%s", 251 s->tx_compressed ? "compressed" : "", _SL_); 252 fprintf(fp, " %-10u %-8u %-7u %-7u %-7u %-7u", 253 s->tx_bytes, s->tx_packets, s->tx_errors, 254 s->tx_dropped, s->tx_carrier_errors, s->collisions); 255 if (s->tx_compressed) 256 fprintf(fp, " %-7u", s->tx_compressed); 257 if (show_stats > 1) { 258 fprintf(fp, "%s", _SL_); 259 fprintf(fp, " TX errors: aborted fifo window heartbeat%s", _SL_); 260 fprintf(fp, " %-7u %-7u %-7u %-7u", 261 s->tx_aborted_errors, 262 s->tx_fifo_errors, 263 s->tx_window_errors, 264 s->tx_heartbeat_errors 265 ); 266 } 267 } 268 fprintf(fp, "\n"); 269 fflush(fp); 270 return 0; 271} 272 273static int flush_update(void) 274{ 275 if (rtnl_send(&rth, filter.flushb, filter.flushp) < 0) { 276 perror("Failed to send flush request\n"); 277 return -1; 278 } 279 filter.flushp = 0; 280 return 0; 281} 282 283static int set_lifetime(unsigned int *lifetime, char *argv) 284{ 285 if (strcmp(argv, "forever") == 0) 286 *lifetime = INFINITY_LIFE_TIME; 287 else if (get_u32(lifetime, argv, 0)) 288 return -1; 289 290 return 0; 291} 292 293int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, 294 void *arg) 295{ 296 FILE *fp = (FILE*)arg; 297 struct ifaddrmsg *ifa = NLMSG_DATA(n); 298 int len = n->nlmsg_len; 299 int deprecated = 0; 300 struct rtattr * rta_tb[IFA_MAX+1]; 301 char abuf[256]; 302 SPRINT_BUF(b1); 303 304 if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) 305 return 0; 306 len -= NLMSG_LENGTH(sizeof(*ifa)); 307 if (len < 0) { 308 fprintf(stderr, "BUG: wrong nlmsg len %d\n", len); 309 return -1; 310 } 311 312 if (filter.flushb && n->nlmsg_type != RTM_NEWADDR) 313 return 0; 314 315 parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); 316 317 if (!rta_tb[IFA_LOCAL]) 318 rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; 319 if (!rta_tb[IFA_ADDRESS]) 320 rta_tb[IFA_ADDRESS] = rta_tb[IFA_LOCAL]; 321 322 if (filter.ifindex && filter.ifindex != ifa->ifa_index) 323 return 0; 324 if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 325 return 0; 326 if ((filter.flags^ifa->ifa_flags)&filter.flagmask) 327 return 0; 328 if (filter.label) { 329 SPRINT_BUF(b1); 330 const char *label; 331 if (rta_tb[IFA_LABEL]) 332 label = RTA_DATA(rta_tb[IFA_LABEL]); 333 else 334 label = ll_idx_n2a(ifa->ifa_index, b1); 335 if (fnmatch(filter.label, label, 0) != 0) 336 return 0; 337 } 338 if (filter.pfx.family) { 339 if (rta_tb[IFA_LOCAL]) { 340 inet_prefix dst; 341 memset(&dst, 0, sizeof(dst)); 342 dst.family = ifa->ifa_family; 343 memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL])); 344 if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 345 return 0; 346 } 347 } 348 349 if (filter.family && filter.family != ifa->ifa_family) 350 return 0; 351 352 if (filter.flushb) { 353 struct nlmsghdr *fn; 354 if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { 355 if (flush_update()) 356 return -1; 357 } 358 fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); 359 memcpy(fn, n, n->nlmsg_len); 360 fn->nlmsg_type = RTM_DELADDR; 361 fn->nlmsg_flags = NLM_F_REQUEST; 362 fn->nlmsg_seq = ++rth.seq; 363 filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; 364 filter.flushed++; 365 if (show_stats < 2) 366 return 0; 367 } 368 369 if (n->nlmsg_type == RTM_DELADDR) 370 fprintf(fp, "Deleted "); 371 372 if (filter.oneline || filter.flushb) 373 fprintf(fp, "%u: %s", ifa->ifa_index, ll_index_to_name(ifa->ifa_index)); 374 if (ifa->ifa_family == AF_INET) 375 fprintf(fp, " inet "); 376 else if (ifa->ifa_family == AF_INET6) 377 fprintf(fp, " inet6 "); 378 else if (ifa->ifa_family == AF_DECnet) 379 fprintf(fp, " dnet "); 380 else if (ifa->ifa_family == AF_IPX) 381 fprintf(fp, " ipx "); 382 else 383 fprintf(fp, " family %d ", ifa->ifa_family); 384 385 if (rta_tb[IFA_LOCAL]) { 386 fprintf(fp, "%s", rt_addr_n2a(ifa->ifa_family, 387 RTA_PAYLOAD(rta_tb[IFA_LOCAL]), 388 RTA_DATA(rta_tb[IFA_LOCAL]), 389 abuf, sizeof(abuf))); 390 391 if (rta_tb[IFA_ADDRESS] == NULL || 392 memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0) { 393 fprintf(fp, "/%d ", ifa->ifa_prefixlen); 394 } else { 395 fprintf(fp, " peer %s/%d ", 396 rt_addr_n2a(ifa->ifa_family, 397 RTA_PAYLOAD(rta_tb[IFA_ADDRESS]), 398 RTA_DATA(rta_tb[IFA_ADDRESS]), 399 abuf, sizeof(abuf)), 400 ifa->ifa_prefixlen); 401 } 402 } 403 404 if (rta_tb[IFA_BROADCAST]) { 405 fprintf(fp, "brd %s ", 406 rt_addr_n2a(ifa->ifa_family, 407 RTA_PAYLOAD(rta_tb[IFA_BROADCAST]), 408 RTA_DATA(rta_tb[IFA_BROADCAST]), 409 abuf, sizeof(abuf))); 410 } 411 if (rta_tb[IFA_ANYCAST]) { 412 fprintf(fp, "any %s ", 413 rt_addr_n2a(ifa->ifa_family, 414 RTA_PAYLOAD(rta_tb[IFA_ANYCAST]), 415 RTA_DATA(rta_tb[IFA_ANYCAST]), 416 abuf, sizeof(abuf))); 417 } 418 fprintf(fp, "scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1, sizeof(b1))); 419 if (ifa->ifa_flags&IFA_F_SECONDARY) { 420 ifa->ifa_flags &= ~IFA_F_SECONDARY; 421 fprintf(fp, "secondary "); 422 } 423 if (ifa->ifa_flags&IFA_F_TENTATIVE) { 424 ifa->ifa_flags &= ~IFA_F_TENTATIVE; 425 fprintf(fp, "tentative "); 426 } 427 if (ifa->ifa_flags&IFA_F_DEPRECATED) { 428 ifa->ifa_flags &= ~IFA_F_DEPRECATED; 429 deprecated = 1; 430 fprintf(fp, "deprecated "); 431 } 432 if (!(ifa->ifa_flags&IFA_F_PERMANENT)) { 433 fprintf(fp, "dynamic "); 434 } else 435 ifa->ifa_flags &= ~IFA_F_PERMANENT; 436 if (ifa->ifa_flags) 437 fprintf(fp, "flags %02x ", ifa->ifa_flags); 438 if (rta_tb[IFA_LABEL]) 439 fprintf(fp, "%s", (char*)RTA_DATA(rta_tb[IFA_LABEL])); 440 if (rta_tb[IFA_CACHEINFO]) { 441 struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]); 442 char buf[128]; 443 fprintf(fp, "%s", _SL_); 444 if (ci->ifa_valid == INFINITY_LIFE_TIME) 445 sprintf(buf, "valid_lft forever"); 446 else 447 sprintf(buf, "valid_lft %usec", ci->ifa_valid); 448 if (ci->ifa_prefered == INFINITY_LIFE_TIME) 449 sprintf(buf+strlen(buf), " preferred_lft forever"); 450 else { 451 if (deprecated) 452 sprintf(buf+strlen(buf), " preferred_lft %dsec", 453 ci->ifa_prefered); 454 else 455 sprintf(buf+strlen(buf), " preferred_lft %usec", 456 ci->ifa_prefered); 457 } 458 fprintf(fp, " %s", buf); 459 } 460 fprintf(fp, "\n"); 461 fflush(fp); 462 return 0; 463} 464 465 466struct nlmsg_list 467{ 468 struct nlmsg_list *next; 469 struct nlmsghdr h; 470}; 471 472int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) 473{ 474 for ( ;ainfo ; ainfo = ainfo->next) { 475 struct nlmsghdr *n = &ainfo->h; 476 struct ifaddrmsg *ifa = NLMSG_DATA(n); 477 478 if (n->nlmsg_type != RTM_NEWADDR) 479 continue; 480 481 if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifa))) 482 return -1; 483 484 if (ifa->ifa_index != ifindex || 485 (filter.family && filter.family != ifa->ifa_family)) 486 continue; 487 488 print_addrinfo(NULL, n, fp); 489 } 490 return 0; 491} 492 493 494static int store_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, 495 void *arg) 496{ 497 struct nlmsg_list **linfo = (struct nlmsg_list**)arg; 498 struct nlmsg_list *h; 499 struct nlmsg_list **lp; 500 501 h = malloc(n->nlmsg_len+sizeof(void*)); 502 if (h == NULL) 503 return -1; 504 505 memcpy(&h->h, n, n->nlmsg_len); 506 h->next = NULL; 507 508 for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */; 509 *lp = h; 510 511 ll_remember_index(who, n, NULL); 512 return 0; 513} 514 515int ipaddr_list_or_flush(int argc, char **argv, int flush) 516{ 517 struct nlmsg_list *linfo = NULL; 518 struct nlmsg_list *ainfo = NULL; 519 struct nlmsg_list *l, *n; 520 char *filter_dev = NULL; 521 int no_link = 0; 522 523 ipaddr_reset_filter(oneline); 524 filter.showqueue = 1; 525 526 if (filter.family == AF_UNSPEC) 527 filter.family = preferred_family; 528 529 if (flush) { 530 if (argc <= 0) { 531 fprintf(stderr, "Flush requires arguments.\n"); 532 return -1; 533 } 534 if (filter.family == AF_PACKET) { 535 fprintf(stderr, "Cannot flush link addresses.\n"); 536 return -1; 537 } 538 } 539 540 while (argc > 0) { 541 if (strcmp(*argv, "to") == 0) { 542 NEXT_ARG(); 543 get_prefix(&filter.pfx, *argv, filter.family); 544 if (filter.family == AF_UNSPEC) 545 filter.family = filter.pfx.family; 546 } else if (strcmp(*argv, "scope") == 0) { 547 unsigned scope = 0; 548 NEXT_ARG(); 549 filter.scopemask = -1; 550 if (rtnl_rtscope_a2n(&scope, *argv)) { 551 if (strcmp(*argv, "all") != 0) 552 invarg("invalid \"scope\"\n", *argv); 553 scope = RT_SCOPE_NOWHERE; 554 filter.scopemask = 0; 555 } 556 filter.scope = scope; 557 } else if (strcmp(*argv, "up") == 0) { 558 filter.up = 1; 559 } else if (strcmp(*argv, "dynamic") == 0) { 560 filter.flags &= ~IFA_F_PERMANENT; 561 filter.flagmask |= IFA_F_PERMANENT; 562 } else if (strcmp(*argv, "permanent") == 0) { 563 filter.flags |= IFA_F_PERMANENT; 564 filter.flagmask |= IFA_F_PERMANENT; 565 } else if (strcmp(*argv, "secondary") == 0) { 566 filter.flags |= IFA_F_SECONDARY; 567 filter.flagmask |= IFA_F_SECONDARY; 568 } else if (strcmp(*argv, "primary") == 0) { 569 filter.flags &= ~IFA_F_SECONDARY; 570 filter.flagmask |= IFA_F_SECONDARY; 571 } else if (strcmp(*argv, "tentative") == 0) { 572 filter.flags |= IFA_F_TENTATIVE; 573 filter.flagmask |= IFA_F_TENTATIVE; 574 } else if (strcmp(*argv, "deprecated") == 0) { 575 filter.flags |= IFA_F_DEPRECATED; 576 filter.flagmask |= IFA_F_DEPRECATED; 577 } else if (strcmp(*argv, "label") == 0) { 578 NEXT_ARG(); 579 filter.label = *argv; 580 } else { 581 if (strcmp(*argv, "dev") == 0) { 582 NEXT_ARG(); 583 } 584 if (matches(*argv, "help") == 0) 585 usage(); 586 if (filter_dev) 587 duparg2("dev", *argv); 588 filter_dev = *argv; 589 } 590 argv++; argc--; 591 } 592 593 if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) { 594 perror("Cannot send dump request"); 595 exit(1); 596 } 597 598 if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) { 599 fprintf(stderr, "Dump terminated\n"); 600 exit(1); 601 } 602 603 if (filter_dev) { 604 filter.ifindex = ll_name_to_index(filter_dev); 605 if (filter.ifindex <= 0) { 606 fprintf(stderr, "Device \"%s\" does not exist.\n", filter_dev); 607 return -1; 608 } 609 } 610 611 if (flush) { 612 int round = 0; 613 char flushb[4096-512]; 614 615 filter.flushb = flushb; 616 filter.flushp = 0; 617 filter.flushe = sizeof(flushb); 618 619 for (;;) { 620 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 621 perror("Cannot send dump request"); 622 exit(1); 623 } 624 filter.flushed = 0; 625 if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { 626 fprintf(stderr, "Flush terminated\n"); 627 exit(1); 628 } 629 if (filter.flushed == 0) { 630 if (round == 0) { 631 fprintf(stderr, "Nothing to flush.\n"); 632 } else if (show_stats) 633 printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":""); 634 fflush(stdout); 635 return 0; 636 } 637 round++; 638 if (flush_update() < 0) 639 return 1; 640 641 if (show_stats) { 642 printf("\n*** Round %d, deleting %d addresses ***\n", round, filter.flushed); 643 fflush(stdout); 644 } 645 } 646 } 647 648 if (filter.family != AF_PACKET) { 649 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 650 perror("Cannot send dump request"); 651 exit(1); 652 } 653 654 if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) { 655 fprintf(stderr, "Dump terminated\n"); 656 exit(1); 657 } 658 } 659 660 661 if (filter.family && filter.family != AF_PACKET) { 662 struct nlmsg_list **lp; 663 lp=&linfo; 664 665 if (filter.oneline) 666 no_link = 1; 667 668 while ((l=*lp)!=NULL) { 669 int ok = 0; 670 struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 671 struct nlmsg_list *a; 672 673 for (a=ainfo; a; a=a->next) { 674 struct nlmsghdr *n = &a->h; 675 struct ifaddrmsg *ifa = NLMSG_DATA(n); 676 677 if (ifa->ifa_index != ifi->ifi_index || 678 (filter.family && filter.family != ifa->ifa_family)) 679 continue; 680 if ((filter.scope^ifa->ifa_scope)&filter.scopemask) 681 continue; 682 if ((filter.flags^ifa->ifa_flags)&filter.flagmask) 683 continue; 684 if (filter.pfx.family || filter.label) { 685 struct rtattr *tb[IFA_MAX+1]; 686 parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n)); 687 if (!tb[IFA_LOCAL]) 688 tb[IFA_LOCAL] = tb[IFA_ADDRESS]; 689 690 if (filter.pfx.family && tb[IFA_LOCAL]) { 691 inet_prefix dst; 692 memset(&dst, 0, sizeof(dst)); 693 dst.family = ifa->ifa_family; 694 memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL])); 695 if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) 696 continue; 697 } 698 if (filter.label) { 699 SPRINT_BUF(b1); 700 const char *label; 701 if (tb[IFA_LABEL]) 702 label = RTA_DATA(tb[IFA_LABEL]); 703 else 704 label = ll_idx_n2a(ifa->ifa_index, b1); 705 if (fnmatch(filter.label, label, 0) != 0) 706 continue; 707 } 708 } 709 710 ok = 1; 711 break; 712 } 713 if (!ok) 714 *lp = l->next; 715 else 716 lp = &l->next; 717 } 718 } 719 720 for (l=linfo; l; l = n) { 721 n = l->next; 722 if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) { 723 struct ifinfomsg *ifi = NLMSG_DATA(&l->h); 724 if (filter.family != AF_PACKET) 725 print_selected_addrinfo(ifi->ifi_index, ainfo, stdout); 726 } 727 fflush(stdout); 728 free(l); 729 } 730 731 return 0; 732} 733 734int ipaddr_list_link(int argc, char **argv) 735{ 736 preferred_family = AF_PACKET; 737 do_link = 1; 738 return ipaddr_list_or_flush(argc, argv, 0); 739} 740 741void ipaddr_reset_filter(int oneline) 742{ 743 memset(&filter, 0, sizeof(filter)); 744 filter.oneline = oneline; 745} 746 747int default_scope(inet_prefix *lcl) 748{ 749 if (lcl->family == AF_INET) { 750 if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127) 751 return RT_SCOPE_HOST; 752 } 753 return 0; 754} 755 756int ipaddr_modify(int cmd, int flags, int argc, char **argv) 757{ 758 struct { 759 struct nlmsghdr n; 760 struct ifaddrmsg ifa; 761 char buf[256]; 762 } req; 763 char *d = NULL; 764 char *l = NULL; 765 char *lcl_arg = NULL; 766 char *valid_lftp = NULL; 767 char *preferred_lftp = NULL; 768 inet_prefix lcl; 769 inet_prefix peer; 770 int local_len = 0; 771 int peer_len = 0; 772 int brd_len = 0; 773 int any_len = 0; 774 int scoped = 0; 775 __u32 preferred_lft = INFINITY_LIFE_TIME; 776 __u32 valid_lft = INFINITY_LIFE_TIME; 777 struct ifa_cacheinfo cinfo; 778 779 memset(&req, 0, sizeof(req)); 780 781 req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); 782 req.n.nlmsg_flags = NLM_F_REQUEST | flags; 783 req.n.nlmsg_type = cmd; 784 req.ifa.ifa_family = preferred_family; 785 786 while (argc > 0) { 787 if (strcmp(*argv, "peer") == 0 || 788 strcmp(*argv, "remote") == 0) { 789 NEXT_ARG(); 790 791 if (peer_len) 792 duparg("peer", *argv); 793 get_prefix(&peer, *argv, req.ifa.ifa_family); 794 peer_len = peer.bytelen; 795 if (req.ifa.ifa_family == AF_UNSPEC) 796 req.ifa.ifa_family = peer.family; 797 addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); 798 req.ifa.ifa_prefixlen = peer.bitlen; 799 } else if (matches(*argv, "broadcast") == 0 || 800 strcmp(*argv, "brd") == 0) { 801 inet_prefix addr; 802 NEXT_ARG(); 803 if (brd_len) 804 duparg("broadcast", *argv); 805 if (strcmp(*argv, "+") == 0) 806 brd_len = -1; 807 else if (strcmp(*argv, "-") == 0) 808 brd_len = -2; 809 else { 810 get_addr(&addr, *argv, req.ifa.ifa_family); 811 if (req.ifa.ifa_family == AF_UNSPEC) 812 req.ifa.ifa_family = addr.family; 813 addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); 814 brd_len = addr.bytelen; 815 } 816 } else if (strcmp(*argv, "anycast") == 0) { 817 inet_prefix addr; 818 NEXT_ARG(); 819 if (any_len) 820 duparg("anycast", *argv); 821 get_addr(&addr, *argv, req.ifa.ifa_family); 822 if (req.ifa.ifa_family == AF_UNSPEC) 823 req.ifa.ifa_family = addr.family; 824 addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); 825 any_len = addr.bytelen; 826 } else if (strcmp(*argv, "scope") == 0) { 827 unsigned scope = 0; 828 NEXT_ARG(); 829 if (rtnl_rtscope_a2n(&scope, *argv)) 830 invarg(*argv, "invalid scope value."); 831 req.ifa.ifa_scope = scope; 832 scoped = 1; 833 } else if (strcmp(*argv, "dev") == 0) { 834 NEXT_ARG(); 835 d = *argv; 836 } else if (strcmp(*argv, "label") == 0) { 837 NEXT_ARG(); 838 l = *argv; 839 addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1); 840 } else if (matches(*argv, "valid_lft") == 0) { 841 if (valid_lftp) 842 duparg("valid_lft", *argv); 843 NEXT_ARG(); 844 valid_lftp = *argv; 845 if (set_lifetime(&valid_lft, *argv)) 846 invarg("valid_lft value", *argv); 847 } else if (matches(*argv, "preferred_lft") == 0) { 848 if (preferred_lftp) 849 duparg("preferred_lft", *argv); 850 NEXT_ARG(); 851 preferred_lftp = *argv; 852 if (set_lifetime(&preferred_lft, *argv)) 853 invarg("preferred_lft value", *argv); 854 } else { 855 if (strcmp(*argv, "local") == 0) { 856 NEXT_ARG(); 857 } 858 if (matches(*argv, "help") == 0) 859 usage(); 860 if (local_len) 861 duparg2("local", *argv); 862 lcl_arg = *argv; 863 get_prefix(&lcl, *argv, req.ifa.ifa_family); 864 if (req.ifa.ifa_family == AF_UNSPEC) 865 req.ifa.ifa_family = lcl.family; 866 addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); 867 local_len = lcl.bytelen; 868 } 869 argc--; argv++; 870 } 871 if (d == NULL) { 872 fprintf(stderr, "Not enough information: \"dev\" argument is required.\n"); 873 return -1; 874 } 875 if (l && matches(d, l) != 0) { 876 fprintf(stderr, "\"dev\" (%s) must match \"label\" (%s).\n", d, l); 877 exit(1); 878 } 879 880 if (peer_len == 0 && local_len) { 881 if (cmd == RTM_DELADDR && lcl.family == AF_INET && !(lcl.flags & PREFIXLEN_SPECIFIED)) { 882 fprintf(stderr, 883 "Warning: Executing wildcard deletion to stay compatible with old scripts.\n" \ 884 " Explicitly specify the prefix length (%s/%d) to avoid this warning.\n" \ 885 " This special behaviour is likely to disappear in further releases,\n" \ 886 " fix your scripts!\n", lcl_arg, local_len*8); 887 } else { 888 peer = lcl; 889 addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen); 890 } 891 } 892 if (req.ifa.ifa_prefixlen == 0) 893 req.ifa.ifa_prefixlen = lcl.bitlen; 894 895 if (brd_len < 0 && cmd != RTM_DELADDR) { 896 inet_prefix brd; 897 int i; 898 if (req.ifa.ifa_family != AF_INET) { 899 fprintf(stderr, "Broadcast can be set only for IPv4 addresses\n"); 900 return -1; 901 } 902 brd = peer; 903 if (brd.bitlen <= 30) { 904 for (i=31; i>=brd.bitlen; i--) { 905 if (brd_len == -1) 906 brd.data[0] |= htonl(1<<(31-i)); 907 else 908 brd.data[0] &= ~htonl(1<<(31-i)); 909 } 910 addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen); 911 brd_len = brd.bytelen; 912 } 913 } 914 if (!scoped && cmd != RTM_DELADDR) 915 req.ifa.ifa_scope = default_scope(&lcl); 916 917 ll_init_map(&rth); 918 919 if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) { 920 fprintf(stderr, "Cannot find device \"%s\"\n", d); 921 return -1; 922 } 923 924 if (valid_lftp || preferred_lftp) { 925 if (!valid_lft) { 926 fprintf(stderr, "valid_lft is zero\n"); 927 return -1; 928 } 929 if (valid_lft < preferred_lft) { 930 fprintf(stderr, "preferred_lft is greater than valid_lft\n"); 931 return -1; 932 } 933 934 memset(&cinfo, 0, sizeof(cinfo)); 935 cinfo.ifa_prefered = preferred_lft; 936 cinfo.ifa_valid = valid_lft; 937 addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo, 938 sizeof(cinfo)); 939 } 940 941 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 942 exit(2); 943 944 return 0; 945} 946 947int do_ipaddr(int argc, char **argv) 948{ 949 if (argc < 1) 950 return ipaddr_list_or_flush(0, NULL, 0); 951 if (matches(*argv, "add") == 0) 952 return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_EXCL, argc-1, argv+1); 953 if (matches(*argv, "change") == 0 || 954 strcmp(*argv, "chg") == 0) 955 return ipaddr_modify(RTM_NEWADDR, NLM_F_REPLACE, argc-1, argv+1); 956 if (matches(*argv, "replace") == 0) 957 return ipaddr_modify(RTM_NEWADDR, NLM_F_CREATE|NLM_F_REPLACE, argc-1, argv+1); 958 if (matches(*argv, "delete") == 0) 959 return ipaddr_modify(RTM_DELADDR, 0, argc-1, argv+1); 960 if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 961 || matches(*argv, "lst") == 0) 962 return ipaddr_list_or_flush(argc-1, argv+1, 0); 963 if (matches(*argv, "flush") == 0) 964 return ipaddr_list_or_flush(argc-1, argv+1, 1); 965 if (matches(*argv, "help") == 0) 966 usage(); 967 fprintf(stderr, "Command \"%s\" is unknown, try \"ip address help\".\n", *argv); 968 exit(-1); 969} 970 971