1 /* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgment: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * $FreeBSD$ 34 */ 35 36 #include "defs.h" 37 #include "pathnames.h" 38 39 #if !defined(sgi) && !defined(__NetBSD__) 40 static char sccsid[] __attribute__((unused)) = "@(#)if.c 8.1 (Berkeley) 6/5/93"; 41 #elif defined(__NetBSD__) 42 #include <sys/cdefs.h> 43 __RCSID("$NetBSD$"); 44 #endif 45 #ident "$FreeBSD$" 46 47 struct interface *ifnet; /* all interfaces */ 48 49 /* hash table for all interfaces, big enough to tolerate ridiculous 50 * numbers of IP aliases. Crazy numbers of aliases such as 7000 51 * still will not do well, but not just in looking up interfaces 52 * by name or address. 53 */ 54 #define AHASH_LEN 211 /* must be prime */ 55 #define AHASH(a) &ahash_tbl[(a)%AHASH_LEN] 56 struct interface *ahash_tbl[AHASH_LEN]; 57 58 #define BHASH_LEN 211 /* must be prime */ 59 #define BHASH(a) &bhash_tbl[(a)%BHASH_LEN] 60 struct interface *bhash_tbl[BHASH_LEN]; 61 62 struct interface *remote_if; /* remote interfaces */ 63 64 /* hash for physical interface names. 65 * Assume there are never more 100 or 200 real interfaces, and that 66 * aliases are put on the end of the hash chains. 67 */ 68 #define NHASH_LEN 97 69 struct interface *nhash_tbl[NHASH_LEN]; 70 71 int tot_interfaces; /* # of remote and local interfaces */ 72 int rip_interfaces; /* # of interfaces doing RIP */ 73 int foundloopback; /* valid flag for loopaddr */ 74 naddr loopaddr; /* our address on loopback */ 75 struct rt_spare loop_rts; 76 77 struct timeval ifinit_timer; 78 static struct timeval last_ifinit; 79 #define IF_RESCAN_DELAY() (last_ifinit.tv_sec == now.tv_sec \ 80 && last_ifinit.tv_usec == now.tv_usec \ 81 && timercmp(&ifinit_timer, &now, >)) 82 83 int have_ripv1_out; /* have a RIPv1 interface */ 84 int have_ripv1_in; 85 86 87 static struct interface** 88 nhash(char *p) 89 { 90 u_int i; 91 92 for (i = 0; *p != '\0'; p++) { 93 i = ((i<<1) & 0x7fffffff) | ((i>>31) & 1); 94 i ^= *p; 95 } 96 return &nhash_tbl[i % NHASH_LEN]; 97 } 98 99 100 /* Link a new interface into the lists and hash tables. 101 */ 102 void 103 if_link(struct interface *ifp) 104 { 105 struct interface **hifp; 106 107 ifp->int_prev = &ifnet; 108 ifp->int_next = ifnet; 109 if (ifnet != 0) 110 ifnet->int_prev = &ifp->int_next; 111 ifnet = ifp; 112 113 hifp = AHASH(ifp->int_addr); 114 ifp->int_ahash_prev = hifp; 115 if ((ifp->int_ahash = *hifp) != 0) 116 (*hifp)->int_ahash_prev = &ifp->int_ahash; 117 *hifp = ifp; 118 119 if (ifp->int_if_flags & IFF_BROADCAST) { 120 hifp = BHASH(ifp->int_brdaddr); 121 ifp->int_bhash_prev = hifp; 122 if ((ifp->int_bhash = *hifp) != 0) 123 (*hifp)->int_bhash_prev = &ifp->int_bhash; 124 *hifp = ifp; 125 } 126 127 if (ifp->int_state & IS_REMOTE) { 128 ifp->int_rlink_prev = &remote_if; 129 ifp->int_rlink = remote_if; 130 if (remote_if != 0) 131 remote_if->int_rlink_prev = &ifp->int_rlink; 132 remote_if = ifp; 133 } 134 135 hifp = nhash(ifp->int_name); 136 if (ifp->int_state & IS_ALIAS) { 137 /* put aliases on the end of the hash chain */ 138 while (*hifp != 0) 139 hifp = &(*hifp)->int_nhash; 140 } 141 ifp->int_nhash_prev = hifp; 142 if ((ifp->int_nhash = *hifp) != 0) 143 (*hifp)->int_nhash_prev = &ifp->int_nhash; 144 *hifp = ifp; 145 } 146 147 148 /* Find the interface with an address 149 */ 150 struct interface * 151 ifwithaddr(naddr addr, 152 int bcast, /* notice IFF_BROADCAST address */ 153 int remote) /* include IS_REMOTE interfaces */ 154 { 155 struct interface *ifp, *possible = 0; 156 157 remote = (remote == 0) ? IS_REMOTE : 0; 158 159 for (ifp = *AHASH(addr); ifp; ifp = ifp->int_ahash) { 160 if (ifp->int_addr != addr) 161 continue; 162 if ((ifp->int_state & remote) != 0) 163 continue; 164 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0) 165 return ifp; 166 possible = ifp; 167 } 168 169 if (possible || !bcast) 170 return possible; 171 172 for (ifp = *BHASH(addr); ifp; ifp = ifp->int_bhash) { 173 if (ifp->int_brdaddr != addr) 174 continue; 175 if ((ifp->int_state & remote) != 0) 176 continue; 177 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0) 178 return ifp; 179 possible = ifp; 180 } 181 182 return possible; 183 } 184 185 186 /* find the interface with a name 187 */ 188 struct interface * 189 ifwithname(char *name, /* "ec0" or whatever */ 190 naddr addr) /* 0 or network address */ 191 { 192 struct interface *ifp; 193 194 for (;;) { 195 for (ifp = *nhash(name); ifp != 0; ifp = ifp->int_nhash) { 196 /* If the network address is not specified, 197 * ignore any alias interfaces. Otherwise, look 198 * for the interface with the target name and address. 199 */ 200 if (!strcmp(ifp->int_name, name) 201 && ((addr == 0 && !(ifp->int_state & IS_ALIAS)) 202 || (ifp->int_addr == addr))) 203 return ifp; 204 } 205 206 /* If there is no known interface, maybe there is a 207 * new interface. So just once look for new interfaces. 208 */ 209 if (IF_RESCAN_DELAY()) 210 return 0; 211 ifinit(); 212 } 213 } 214 215 216 struct interface * 217 ifwithindex(u_short index, 218 int rescan_ok) 219 { 220 struct interface *ifp; 221 222 for (;;) { 223 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) { 224 if (ifp->int_index == index) 225 return ifp; 226 } 227 228 /* If there is no known interface, maybe there is a 229 * new interface. So just once look for new interfaces. 230 */ 231 if (!rescan_ok 232 || IF_RESCAN_DELAY()) 233 return 0; 234 ifinit(); 235 } 236 } 237 238 239 /* Find an interface from which the specified address 240 * should have come from. Used for figuring out which 241 * interface a packet came in on. 242 */ 243 struct interface * 244 iflookup(naddr addr) 245 { 246 struct interface *ifp, *maybe; 247 248 maybe = 0; 249 for (;;) { 250 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 251 if (ifp->int_if_flags & IFF_POINTOPOINT) { 252 /* finished with a match */ 253 if (ifp->int_dstaddr == addr) 254 return ifp; 255 256 } else { 257 /* finished with an exact match */ 258 if (ifp->int_addr == addr) 259 return ifp; 260 261 /* Look for the longest approximate match. 262 */ 263 if (on_net(addr, ifp->int_net, ifp->int_mask) 264 && (maybe == 0 265 || ifp->int_mask > maybe->int_mask)) 266 maybe = ifp; 267 } 268 } 269 270 if (maybe != 0 271 || IF_RESCAN_DELAY()) 272 return maybe; 273 274 /* If there is no known interface, maybe there is a 275 * new interface. So just once look for new interfaces. 276 */ 277 ifinit(); 278 } 279 } 280 281 282 /* Return the classical netmask for an IP address. 283 */ 284 naddr /* host byte order */ 285 std_mask(naddr addr) /* network byte order */ 286 { 287 addr = ntohl(addr); /* was a host, not a network */ 288 289 if (addr == 0) /* default route has mask 0 */ 290 return 0; 291 if (IN_CLASSA(addr)) 292 return IN_CLASSA_NET; 293 if (IN_CLASSB(addr)) 294 return IN_CLASSB_NET; 295 return IN_CLASSC_NET; 296 } 297 298 299 /* Find the netmask that would be inferred by RIPv1 listeners 300 * on the given interface for a given network. 301 * If no interface is specified, look for the best fitting interface. 302 */ 303 naddr 304 ripv1_mask_net(naddr addr, /* in network byte order */ 305 struct interface *ifp) /* as seen on this interface */ 306 { 307 struct r1net *r1p; 308 naddr mask = 0; 309 310 if (addr == 0) /* default always has 0 mask */ 311 return mask; 312 313 if (ifp != 0 && ifp->int_ripv1_mask != HOST_MASK) { 314 /* If the target network is that of the associated interface 315 * on which it arrived, then use the netmask of the interface. 316 */ 317 if (on_net(addr, ifp->int_net, ifp->int_std_mask)) 318 mask = ifp->int_ripv1_mask; 319 320 } else { 321 /* Examine all interfaces, and if it the target seems 322 * to have the same network number of an interface, use the 323 * netmask of that interface. If there is more than one 324 * such interface, prefer the interface with the longest 325 * match. 326 */ 327 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 328 if (on_net(addr, ifp->int_std_net, ifp->int_std_mask) 329 && ifp->int_ripv1_mask > mask 330 && ifp->int_ripv1_mask != HOST_MASK) 331 mask = ifp->int_ripv1_mask; 332 } 333 334 } 335 336 /* check special definitions */ 337 if (mask == 0) { 338 for (r1p = r1nets; r1p != 0; r1p = r1p->r1net_next) { 339 if (on_net(addr, r1p->r1net_net, r1p->r1net_match) 340 && r1p->r1net_mask > mask) 341 mask = r1p->r1net_mask; 342 } 343 344 /* Otherwise, make the classic A/B/C guess. 345 */ 346 if (mask == 0) 347 mask = std_mask(addr); 348 } 349 350 return mask; 351 } 352 353 354 naddr 355 ripv1_mask_host(naddr addr, /* in network byte order */ 356 struct interface *ifp) /* as seen on this interface */ 357 { 358 naddr mask = ripv1_mask_net(addr, ifp); 359 360 361 /* If the computed netmask does not mask the address, 362 * then assume it is a host address 363 */ 364 if ((ntohl(addr) & ~mask) != 0) 365 mask = HOST_MASK; 366 return mask; 367 } 368 369 370 /* See if an IP address looks reasonable as a destination. 371 */ 372 int /* 0=bad */ 373 check_dst(naddr addr) 374 { 375 addr = ntohl(addr); 376 377 if (IN_CLASSA(addr)) { 378 if (addr == 0) 379 return 1; /* default */ 380 381 addr >>= IN_CLASSA_NSHIFT; 382 return (addr != 0 && addr != IN_LOOPBACKNET); 383 } 384 385 return (IN_CLASSB(addr) || IN_CLASSC(addr)); 386 } 387 388 389 /* See a new interface duplicates an existing interface. 390 */ 391 struct interface * 392 check_dup(naddr addr, /* IP address, so network byte order */ 393 naddr dstaddr, /* ditto */ 394 naddr mask, /* mask, so host byte order */ 395 int if_flags) 396 { 397 struct interface *ifp; 398 399 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) { 400 if (ifp->int_mask != mask) 401 continue; 402 403 if (!iff_up(ifp->int_if_flags)) 404 continue; 405 406 /* The local address can only be shared with a point-to-point 407 * link. 408 */ 409 if (ifp->int_addr == addr 410 && (((if_flags|ifp->int_if_flags) & IFF_POINTOPOINT) == 0)) 411 return ifp; 412 413 if (on_net(ifp->int_dstaddr, ntohl(dstaddr),mask)) 414 return ifp; 415 } 416 return 0; 417 } 418 419 420 /* See that a remote gateway is reachable. 421 * Note that the answer can change as real interfaces come and go. 422 */ 423 int /* 0=bad */ 424 check_remote(struct interface *ifp) 425 { 426 struct rt_entry *rt; 427 428 /* do not worry about other kinds */ 429 if (!(ifp->int_state & IS_REMOTE)) 430 return 1; 431 432 rt = rtfind(ifp->int_addr); 433 if (rt != 0 434 && rt->rt_ifp != 0 435 &&on_net(ifp->int_addr, 436 rt->rt_ifp->int_net, rt->rt_ifp->int_mask)) 437 return 1; 438 439 /* the gateway cannot be reached directly from one of our 440 * interfaces 441 */ 442 if (!(ifp->int_state & IS_BROKE)) { 443 msglog("unreachable gateway %s in "_PATH_GATEWAYS, 444 naddr_ntoa(ifp->int_addr)); 445 if_bad(ifp); 446 } 447 return 0; 448 } 449 450 451 /* Delete an interface. 452 */ 453 static void 454 ifdel(struct interface *ifp) 455 { 456 struct ip_mreq m; 457 struct interface *ifp1; 458 459 460 trace_if("Del", ifp); 461 462 ifp->int_state |= IS_BROKE; 463 464 /* unlink the interface 465 */ 466 *ifp->int_prev = ifp->int_next; 467 if (ifp->int_next != 0) 468 ifp->int_next->int_prev = ifp->int_prev; 469 *ifp->int_ahash_prev = ifp->int_ahash; 470 if (ifp->int_ahash != 0) 471 ifp->int_ahash->int_ahash_prev = ifp->int_ahash_prev; 472 *ifp->int_nhash_prev = ifp->int_nhash; 473 if (ifp->int_nhash != 0) 474 ifp->int_nhash->int_nhash_prev = ifp->int_nhash_prev; 475 if (ifp->int_if_flags & IFF_BROADCAST) { 476 *ifp->int_bhash_prev = ifp->int_bhash; 477 if (ifp->int_bhash != 0) 478 ifp->int_bhash->int_bhash_prev = ifp->int_bhash_prev; 479 } 480 if (ifp->int_state & IS_REMOTE) { 481 *ifp->int_rlink_prev = ifp->int_rlink; 482 if (ifp->int_rlink != 0) 483 ifp->int_rlink->int_rlink_prev = ifp->int_rlink_prev; 484 } 485 486 if (!(ifp->int_state & IS_ALIAS)) { 487 /* delete aliases when the main interface dies 488 */ 489 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 490 if (ifp1 != ifp 491 && !strcmp(ifp->int_name, ifp1->int_name)) 492 ifdel(ifp1); 493 } 494 495 if ((ifp->int_if_flags & IFF_MULTICAST) 496 #ifdef MCAST_PPP_BUG 497 && !(ifp->int_if_flags & IFF_POINTOPOINT) 498 #endif 499 && rip_sock >= 0) { 500 m.imr_multiaddr.s_addr = htonl(INADDR_RIP_GROUP); 501 m.imr_interface.s_addr = ((ifp->int_if_flags 502 & IFF_POINTOPOINT) 503 ? ifp->int_dstaddr 504 : ifp->int_addr); 505 if (setsockopt(rip_sock,IPPROTO_IP,IP_DROP_MEMBERSHIP, 506 &m, sizeof(m)) < 0 507 && errno != EADDRNOTAVAIL 508 && !TRACEACTIONS) 509 LOGERR("setsockopt(IP_DROP_MEMBERSHIP RIP)"); 510 if (rip_sock_mcast == ifp) 511 rip_sock_mcast = 0; 512 } 513 if (ifp->int_rip_sock >= 0) { 514 (void)close(ifp->int_rip_sock); 515 ifp->int_rip_sock = -1; 516 fix_select(); 517 } 518 519 tot_interfaces--; 520 if (!IS_RIP_OFF(ifp->int_state)) 521 rip_interfaces--; 522 523 /* Zap all routes associated with this interface. 524 * Assume routes just using gateways beyond this interface 525 * will timeout naturally, and have probably already died. 526 */ 527 (void)rn_walktree(rhead, walk_bad, 0); 528 529 set_rdisc_mg(ifp, 0); 530 if_bad_rdisc(ifp); 531 } 532 533 free(ifp); 534 } 535 536 537 /* Mark an interface ill. 538 */ 539 void 540 if_sick(struct interface *ifp) 541 { 542 if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) { 543 ifp->int_state |= IS_SICK; 544 ifp->int_act_time = NEVER; 545 trace_if("Chg", ifp); 546 547 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 548 } 549 } 550 551 552 /* Mark an interface dead. 553 */ 554 void 555 if_bad(struct interface *ifp) 556 { 557 struct interface *ifp1; 558 559 560 if (ifp->int_state & IS_BROKE) 561 return; 562 563 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 564 565 ifp->int_state |= (IS_BROKE | IS_SICK); 566 ifp->int_act_time = NEVER; 567 ifp->int_query_time = NEVER; 568 ifp->int_data.ts = now.tv_sec; 569 570 trace_if("Chg", ifp); 571 572 if (!(ifp->int_state & IS_ALIAS)) { 573 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 574 if (ifp1 != ifp 575 && !strcmp(ifp->int_name, ifp1->int_name)) 576 if_bad(ifp1); 577 } 578 (void)rn_walktree(rhead, walk_bad, 0); 579 if_bad_rdisc(ifp); 580 } 581 } 582 583 584 /* Mark an interface alive 585 */ 586 int /* 1=it was dead */ 587 if_ok(struct interface *ifp, 588 const char *type) 589 { 590 struct interface *ifp1; 591 592 593 if (!(ifp->int_state & IS_BROKE)) { 594 if (ifp->int_state & IS_SICK) { 595 trace_act("%sinterface %s to %s working better", 596 type, 597 ifp->int_name, naddr_ntoa(ifp->int_dstaddr)); 598 ifp->int_state &= ~IS_SICK; 599 } 600 return 0; 601 } 602 603 msglog("%sinterface %s to %s restored", 604 type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr)); 605 ifp->int_state &= ~(IS_BROKE | IS_SICK); 606 ifp->int_data.ts = 0; 607 608 if (!(ifp->int_state & IS_ALIAS)) { 609 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 610 if (ifp1 != ifp 611 && !strcmp(ifp->int_name, ifp1->int_name)) 612 if_ok(ifp1, type); 613 } 614 if_ok_rdisc(ifp); 615 } 616 617 if (ifp->int_state & IS_REMOTE) { 618 if (!addrouteforif(ifp)) 619 return 0; 620 } 621 return 1; 622 } 623 624 625 /* disassemble routing message 626 */ 627 void 628 rt_xaddrs(struct rt_addrinfo *info, 629 struct sockaddr *sa, 630 struct sockaddr *lim, 631 int addrs) 632 { 633 int i; 634 #ifdef _HAVE_SA_LEN 635 static struct sockaddr sa_zero; 636 #endif 637 #ifdef sgi 638 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \ 639 : sizeof(__uint64_t)) 640 #else 641 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ 642 : sizeof(long)) 643 #endif 644 645 646 memset(info, 0, sizeof(*info)); 647 info->rti_addrs = addrs; 648 for (i = 0; i < RTAX_MAX && sa < lim; i++) { 649 if ((addrs & (1 << i)) == 0) 650 continue; 651 #ifdef _HAVE_SA_LEN 652 info->rti_info[i] = (sa->sa_len != 0) ? sa : &sa_zero; 653 sa = (struct sockaddr *)((char*)(sa) 654 + ROUNDUP(sa->sa_len)); 655 #else 656 info->rti_info[i] = sa; 657 sa = (struct sockaddr *)((char*)(sa) 658 + ROUNDUP(_FAKE_SA_LEN_DST(sa))); 659 #endif 660 } 661 } 662 663 664 /* Find the network interfaces which have configured themselves. 665 * This must be done regularly, if only for extra addresses 666 * that come and go on interfaces. 667 */ 668 void 669 ifinit(void) 670 { 671 static char *sysctl_buf; 672 static size_t sysctl_buf_size = 0; 673 uint complaints = 0; 674 static u_int prev_complaints = 0; 675 # define COMP_NOT_INET 0x001 676 # define COMP_NOADDR 0x002 677 # define COMP_BADADDR 0x004 678 # define COMP_NODST 0x008 679 # define COMP_NOBADR 0x010 680 # define COMP_NOMASK 0x020 681 # define COMP_DUP 0x040 682 # define COMP_BAD_METRIC 0x080 683 # define COMP_NETMASK 0x100 684 685 struct interface ifs, ifs0, *ifp, *ifp1; 686 struct rt_entry *rt; 687 size_t needed; 688 int mib[6]; 689 struct if_msghdr *ifm; 690 struct ifa_msghdr *ifam, *ifam_lim, *ifam2; 691 int in, ierr, out, oerr; 692 struct intnet *intnetp; 693 struct rt_addrinfo info; 694 #ifdef SIOCGIFMETRIC 695 struct ifreq ifr; 696 #endif 697 698 699 last_ifinit = now; 700 ifinit_timer.tv_sec = now.tv_sec + (supplier 701 ? CHECK_ACT_INTERVAL 702 : CHECK_QUIET_INTERVAL); 703 704 /* mark all interfaces so we can get rid of those that disappear */ 705 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) 706 ifp->int_state &= ~(IS_CHECKED | IS_DUP); 707 708 /* Fetch the interface list, without too many system calls 709 * since we do it repeatedly. 710 */ 711 mib[0] = CTL_NET; 712 mib[1] = PF_ROUTE; 713 mib[2] = 0; 714 mib[3] = AF_INET; 715 mib[4] = NET_RT_IFLIST; 716 mib[5] = 0; 717 for (;;) { 718 if ((needed = sysctl_buf_size) != 0) { 719 if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0) 720 break; 721 /* retry if the table grew */ 722 if (errno != ENOMEM && errno != EFAULT) 723 BADERR(1, "ifinit: sysctl(RT_IFLIST)"); 724 free(sysctl_buf); 725 needed = 0; 726 } 727 if (sysctl(mib, 6, 0, &needed, 0, 0) < 0) 728 BADERR(1,"ifinit: sysctl(RT_IFLIST) estimate"); 729 sysctl_buf = rtmalloc(sysctl_buf_size = needed, 730 "ifinit sysctl"); 731 } 732 733 ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed); 734 for (ifam = (struct ifa_msghdr *)sysctl_buf; 735 ifam < ifam_lim; 736 ifam = ifam2) { 737 738 ifam2 = (struct ifa_msghdr*)((char*)ifam + ifam->ifam_msglen); 739 740 if (ifam->ifam_type == RTM_IFINFO) { 741 struct sockaddr_dl *sdl; 742 743 ifm = (struct if_msghdr *)ifam; 744 /* make prototype structure for the IP aliases 745 */ 746 memset(&ifs0, 0, sizeof(ifs0)); 747 ifs0.int_rip_sock = -1; 748 ifs0.int_index = ifm->ifm_index; 749 ifs0.int_if_flags = ifm->ifm_flags; 750 ifs0.int_state = IS_CHECKED; 751 ifs0.int_query_time = NEVER; 752 ifs0.int_act_time = now.tv_sec; 753 ifs0.int_data.ts = now.tv_sec; 754 ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets; 755 ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors; 756 ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets; 757 ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors; 758 #ifdef sgi 759 ifs0.int_data.odrops = ifm->ifm_data.ifi_odrops; 760 #endif 761 sdl = (struct sockaddr_dl *)(ifm + 1); 762 sdl->sdl_data[sdl->sdl_nlen] = 0; 763 strncpy(ifs0.int_name, sdl->sdl_data, 764 MIN(sizeof(ifs0.int_name), sdl->sdl_nlen)); 765 continue; 766 } 767 if (ifam->ifam_type != RTM_NEWADDR) { 768 logbad(1,"ifinit: out of sync"); 769 continue; 770 } 771 rt_xaddrs(&info, (struct sockaddr *)(ifam+1), 772 (struct sockaddr *)ifam2, 773 ifam->ifam_addrs); 774 775 /* Prepare for the next address of this interface, which 776 * will be an alias. 777 * Do not output RIP or Router-Discovery packets via aliases. 778 */ 779 memcpy(&ifs, &ifs0, sizeof(ifs)); 780 ifs0.int_state |= (IS_ALIAS | IS_NO_RIP_OUT | IS_NO_RDISC); 781 782 if (INFO_IFA(&info) == 0) { 783 if (iff_up(ifs.int_if_flags)) { 784 if (!(prev_complaints & COMP_NOADDR)) 785 msglog("%s has no address", 786 ifs.int_name); 787 complaints |= COMP_NOADDR; 788 } 789 continue; 790 } 791 if (INFO_IFA(&info)->sa_family != AF_INET) { 792 if (iff_up(ifs.int_if_flags)) { 793 if (!(prev_complaints & COMP_NOT_INET)) 794 trace_act("%s: not AF_INET", 795 ifs.int_name); 796 complaints |= COMP_NOT_INET; 797 } 798 continue; 799 } 800 801 ifs.int_addr = S_ADDR(INFO_IFA(&info)); 802 803 if (ntohl(ifs.int_addr)>>24 == 0 804 || ntohl(ifs.int_addr)>>24 == 0xff) { 805 if (iff_up(ifs.int_if_flags)) { 806 if (!(prev_complaints & COMP_BADADDR)) 807 msglog("%s has a bad address", 808 ifs.int_name); 809 complaints |= COMP_BADADDR; 810 } 811 continue; 812 } 813 814 if (ifs.int_if_flags & IFF_LOOPBACK) { 815 ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC; 816 ifs.int_dstaddr = ifs.int_addr; 817 ifs.int_mask = HOST_MASK; 818 ifs.int_ripv1_mask = HOST_MASK; 819 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 820 ifs.int_net = ntohl(ifs.int_dstaddr); 821 if (!foundloopback) { 822 foundloopback = 1; 823 loopaddr = ifs.int_addr; 824 loop_rts.rts_gate = loopaddr; 825 loop_rts.rts_router = loopaddr; 826 } 827 828 } else if (ifs.int_if_flags & IFF_POINTOPOINT) { 829 if (INFO_BRD(&info) == 0 830 || INFO_BRD(&info)->sa_family != AF_INET) { 831 if (iff_up(ifs.int_if_flags)) { 832 if (!(prev_complaints & COMP_NODST)) 833 msglog("%s has a bad" 834 " destination address", 835 ifs.int_name); 836 complaints |= COMP_NODST; 837 } 838 continue; 839 } 840 ifs.int_dstaddr = S_ADDR(INFO_BRD(&info)); 841 if (ntohl(ifs.int_dstaddr)>>24 == 0 842 || ntohl(ifs.int_dstaddr)>>24 == 0xff) { 843 if (iff_up(ifs.int_if_flags)) { 844 if (!(prev_complaints & COMP_NODST)) 845 msglog("%s has a bad" 846 " destination address", 847 ifs.int_name); 848 complaints |= COMP_NODST; 849 } 850 continue; 851 } 852 ifs.int_mask = HOST_MASK; 853 ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info))); 854 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 855 ifs.int_net = ntohl(ifs.int_dstaddr); 856 857 } else { 858 if (INFO_MASK(&info) == 0) { 859 if (iff_up(ifs.int_if_flags)) { 860 if (!(prev_complaints & COMP_NOMASK)) 861 msglog("%s has no netmask", 862 ifs.int_name); 863 complaints |= COMP_NOMASK; 864 } 865 continue; 866 } 867 ifs.int_dstaddr = ifs.int_addr; 868 ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info))); 869 ifs.int_ripv1_mask = ifs.int_mask; 870 ifs.int_std_mask = std_mask(ifs.int_addr); 871 ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask; 872 if (ifs.int_mask != ifs.int_std_mask) 873 ifs.int_state |= IS_SUBNET; 874 875 if (ifs.int_if_flags & IFF_BROADCAST) { 876 if (INFO_BRD(&info) == 0) { 877 if (iff_up(ifs.int_if_flags)) { 878 if (!(prev_complaints 879 & COMP_NOBADR)) 880 msglog("%s has" 881 "no broadcast address", 882 ifs.int_name); 883 complaints |= COMP_NOBADR; 884 } 885 continue; 886 } 887 ifs.int_brdaddr = S_ADDR(INFO_BRD(&info)); 888 } 889 } 890 ifs.int_std_net = ifs.int_net & ifs.int_std_mask; 891 ifs.int_std_addr = htonl(ifs.int_std_net); 892 893 /* Use a minimum metric of one. Treat the interface metric 894 * (default 0) as an increment to the hop count of one. 895 * 896 * The metric obtained from the routing socket dump of 897 * interface addresses is wrong. It is not set by the 898 * SIOCSIFMETRIC ioctl. 899 */ 900 #ifdef SIOCGIFMETRIC 901 strncpy(ifr.ifr_name, ifs.int_name, sizeof(ifr.ifr_name)); 902 if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) { 903 DBGERR(1, "ioctl(SIOCGIFMETRIC)"); 904 ifs.int_metric = 0; 905 } else { 906 ifs.int_metric = ifr.ifr_metric; 907 } 908 #else 909 ifs.int_metric = ifam->ifam_metric; 910 #endif 911 if (ifs.int_metric > HOPCNT_INFINITY) { 912 ifs.int_metric = 0; 913 if (!(prev_complaints & COMP_BAD_METRIC) 914 && iff_up(ifs.int_if_flags)) { 915 complaints |= COMP_BAD_METRIC; 916 msglog("%s has a metric of %d", 917 ifs.int_name, ifs.int_metric); 918 } 919 } 920 921 /* See if this is a familiar interface. 922 * If so, stop worrying about it if it is the same. 923 * Start it over if it now is to somewhere else, as happens 924 * frequently with PPP and SLIP. 925 */ 926 ifp = ifwithname(ifs.int_name, ((ifs.int_state & IS_ALIAS) 927 ? ifs.int_addr 928 : 0)); 929 if (ifp != 0) { 930 ifp->int_state |= IS_CHECKED; 931 932 if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags) 933 & (IFF_BROADCAST 934 | IFF_LOOPBACK 935 | IFF_POINTOPOINT 936 | IFF_MULTICAST)) 937 || 0 != ((ifp->int_state ^ ifs.int_state) 938 & IS_ALIAS) 939 || ifp->int_addr != ifs.int_addr 940 || ifp->int_brdaddr != ifs.int_brdaddr 941 || ifp->int_dstaddr != ifs.int_dstaddr 942 || ifp->int_mask != ifs.int_mask 943 || ifp->int_metric != ifs.int_metric) { 944 /* Forget old information about 945 * a changed interface. 946 */ 947 trace_act("interface %s has changed", 948 ifp->int_name); 949 ifdel(ifp); 950 ifp = 0; 951 } 952 } 953 954 if (ifp != 0) { 955 /* The primary representative of an alias worries 956 * about how things are working. 957 */ 958 if (ifp->int_state & IS_ALIAS) 959 continue; 960 961 /* note interfaces that have been turned off 962 */ 963 if (!iff_up(ifs.int_if_flags)) { 964 if (iff_up(ifp->int_if_flags)) { 965 msglog("interface %s to %s turned off", 966 ifp->int_name, 967 naddr_ntoa(ifp->int_dstaddr)); 968 if_bad(ifp); 969 ifp->int_if_flags &= ~IFF_UP; 970 } else if (now.tv_sec>(ifp->int_data.ts 971 + CHECK_BAD_INTERVAL)) { 972 trace_act("interface %s has been off" 973 " %ld seconds; forget it", 974 ifp->int_name, 975 now.tv_sec-ifp->int_data.ts); 976 ifdel(ifp); 977 } 978 continue; 979 } 980 /* or that were off and are now ok */ 981 if (!iff_up(ifp->int_if_flags)) { 982 ifp->int_if_flags |= IFF_UP; 983 (void)if_ok(ifp, ""); 984 } 985 986 /* If it has been long enough, 987 * see if the interface is broken. 988 */ 989 if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL) 990 continue; 991 992 in = ifs.int_data.ipackets - ifp->int_data.ipackets; 993 ierr = ifs.int_data.ierrors - ifp->int_data.ierrors; 994 out = ifs.int_data.opackets - ifp->int_data.opackets; 995 oerr = ifs.int_data.oerrors - ifp->int_data.oerrors; 996 #ifdef sgi 997 /* Through at least IRIX 6.2, PPP and SLIP 998 * count packets dropped by the filters. 999 * But FDDI rings stuck non-operational count 1000 * dropped packets as they wait for improvement. 1001 */ 1002 if (!(ifp->int_if_flags & IFF_POINTOPOINT)) 1003 oerr += (ifs.int_data.odrops 1004 - ifp->int_data.odrops); 1005 #endif 1006 /* If the interface just awoke, restart the counters. 1007 */ 1008 if (ifp->int_data.ts == 0) { 1009 ifp->int_data = ifs.int_data; 1010 continue; 1011 } 1012 ifp->int_data = ifs.int_data; 1013 1014 /* Withhold judgment when the short error 1015 * counters wrap or the interface is reset. 1016 */ 1017 if (ierr < 0 || in < 0 || oerr < 0 || out < 0) { 1018 LIM_SEC(ifinit_timer, 1019 now.tv_sec+CHECK_BAD_INTERVAL); 1020 continue; 1021 } 1022 1023 /* Withhold judgement when there is no traffic 1024 */ 1025 if (in == 0 && out == 0 && ierr == 0 && oerr == 0) 1026 continue; 1027 1028 /* It is bad if input or output is not working. 1029 * Require presistent problems before marking it dead. 1030 */ 1031 if ((in <= ierr && ierr > 0) 1032 || (out <= oerr && oerr > 0)) { 1033 if (!(ifp->int_state & IS_SICK)) { 1034 trace_act("interface %s to %s" 1035 " sick: in=%d ierr=%d" 1036 " out=%d oerr=%d", 1037 ifp->int_name, 1038 naddr_ntoa(ifp->int_dstaddr), 1039 in, ierr, out, oerr); 1040 if_sick(ifp); 1041 continue; 1042 } 1043 if (!(ifp->int_state & IS_BROKE)) { 1044 msglog("interface %s to %s broken:" 1045 " in=%d ierr=%d out=%d oerr=%d", 1046 ifp->int_name, 1047 naddr_ntoa(ifp->int_dstaddr), 1048 in, ierr, out, oerr); 1049 if_bad(ifp); 1050 } 1051 continue; 1052 } 1053 1054 /* otherwise, it is active and healthy 1055 */ 1056 ifp->int_act_time = now.tv_sec; 1057 (void)if_ok(ifp, ""); 1058 continue; 1059 } 1060 1061 /* This is a new interface. 1062 * If it is dead, forget it. 1063 */ 1064 if (!iff_up(ifs.int_if_flags)) 1065 continue; 1066 1067 /* If it duplicates an existing interface, 1068 * complain about it, mark the other one 1069 * duplicated, and forget this one. 1070 */ 1071 ifp = check_dup(ifs.int_addr,ifs.int_dstaddr,ifs.int_mask, 1072 ifs.int_if_flags); 1073 if (ifp != 0) { 1074 /* Ignore duplicates of itself, caused by having 1075 * IP aliases on the same network. 1076 */ 1077 if (!strcmp(ifp->int_name, ifs.int_name)) 1078 continue; 1079 1080 if (!(prev_complaints & COMP_DUP)) { 1081 complaints |= COMP_DUP; 1082 msglog("%s (%s%s%s) is duplicated by" 1083 " %s (%s%s%s)", 1084 ifs.int_name, 1085 addrname(ifs.int_addr,ifs.int_mask,1), 1086 ((ifs.int_if_flags & IFF_POINTOPOINT) 1087 ? "-->" : ""), 1088 ((ifs.int_if_flags & IFF_POINTOPOINT) 1089 ? naddr_ntoa(ifs.int_dstaddr) : ""), 1090 ifp->int_name, 1091 addrname(ifp->int_addr,ifp->int_mask,1), 1092 ((ifp->int_if_flags & IFF_POINTOPOINT) 1093 ? "-->" : ""), 1094 ((ifp->int_if_flags & IFF_POINTOPOINT) 1095 ? naddr_ntoa(ifp->int_dstaddr) : "")); 1096 } 1097 ifp->int_state |= IS_DUP; 1098 continue; 1099 } 1100 1101 if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT | IFF_BROADCAST)) 1102 && !(ifs.int_state & IS_PASSIVE)) { 1103 trace_act("%s is neither broadcast, point-to-point," 1104 " nor loopback", 1105 ifs.int_name); 1106 if (!(ifs.int_state & IFF_MULTICAST)) 1107 ifs.int_state |= IS_NO_RDISC; 1108 } 1109 1110 1111 /* It is new and ok. Add it to the list of interfaces 1112 */ 1113 ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit ifp"); 1114 memcpy(ifp, &ifs, sizeof(*ifp)); 1115 get_parms(ifp); 1116 if_link(ifp); 1117 trace_if("Add", ifp); 1118 1119 /* Notice likely bad netmask. 1120 */ 1121 if (!(prev_complaints & COMP_NETMASK) 1122 && !(ifp->int_if_flags & IFF_POINTOPOINT) 1123 && ifp->int_addr != RIP_DEFAULT) { 1124 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 1125 if (ifp1->int_mask == ifp->int_mask) 1126 continue; 1127 if (ifp1->int_if_flags & IFF_POINTOPOINT) 1128 continue; 1129 if (ifp1->int_dstaddr == RIP_DEFAULT) 1130 continue; 1131 /* ignore aliases on the right network */ 1132 if (!strcmp(ifp->int_name, ifp1->int_name)) 1133 continue; 1134 if (on_net(ifp->int_dstaddr, 1135 ifp1->int_net, ifp1->int_mask) 1136 || on_net(ifp1->int_dstaddr, 1137 ifp->int_net, ifp->int_mask)) { 1138 msglog("possible netmask problem" 1139 " between %s:%s and %s:%s", 1140 ifp->int_name, 1141 addrname(htonl(ifp->int_net), 1142 ifp->int_mask, 1), 1143 ifp1->int_name, 1144 addrname(htonl(ifp1->int_net), 1145 ifp1->int_mask, 1)); 1146 complaints |= COMP_NETMASK; 1147 } 1148 } 1149 } 1150 1151 if (!(ifp->int_state & IS_ALIAS)) { 1152 /* Count the # of directly connected networks. 1153 */ 1154 if (!(ifp->int_if_flags & IFF_LOOPBACK)) 1155 tot_interfaces++; 1156 if (!IS_RIP_OFF(ifp->int_state)) 1157 rip_interfaces++; 1158 1159 /* turn on router discovery and RIP If needed */ 1160 if_ok_rdisc(ifp); 1161 rip_on(ifp); 1162 } 1163 } 1164 1165 /* If we are multi-homed and have at least two interfaces 1166 * listening to RIP, then output by default. 1167 */ 1168 if (!supplier_set && rip_interfaces > 1) 1169 set_supplier(); 1170 1171 /* If we are multi-homed, optionally advertise a route to 1172 * our main address. 1173 */ 1174 if (advertise_mhome 1175 || (tot_interfaces > 1 1176 && mhome 1177 && (ifp = ifwithaddr(myaddr, 0, 0)) != 0 1178 && foundloopback)) { 1179 advertise_mhome = 1; 1180 rt = rtget(myaddr, HOST_MASK); 1181 if (rt != 0) { 1182 if (rt->rt_ifp != ifp 1183 || rt->rt_router != loopaddr) { 1184 rtdelete(rt); 1185 rt = 0; 1186 } else { 1187 loop_rts.rts_ifp = ifp; 1188 loop_rts.rts_metric = 0; 1189 loop_rts.rts_time = rt->rt_time; 1190 rtchange(rt, rt->rt_state | RS_MHOME, 1191 &loop_rts, 0); 1192 } 1193 } 1194 if (rt == 0) { 1195 loop_rts.rts_ifp = ifp; 1196 loop_rts.rts_metric = 0; 1197 rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts); 1198 } 1199 } 1200 1201 for (ifp = ifnet; ifp != 0; ifp = ifp1) { 1202 ifp1 = ifp->int_next; /* because we may delete it */ 1203 1204 /* Forget any interfaces that have disappeared. 1205 */ 1206 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) { 1207 trace_act("interface %s has disappeared", 1208 ifp->int_name); 1209 ifdel(ifp); 1210 continue; 1211 } 1212 1213 if ((ifp->int_state & IS_BROKE) 1214 && !(ifp->int_state & IS_PASSIVE)) 1215 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 1216 1217 /* If we ever have a RIPv1 interface, assume we always will. 1218 * It might come back if it ever goes away. 1219 */ 1220 if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier) 1221 have_ripv1_out = 1; 1222 if (!(ifp->int_state & IS_NO_RIPV1_IN)) 1223 have_ripv1_in = 1; 1224 } 1225 1226 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 1227 /* Ensure there is always a network route for interfaces, 1228 * after any dead interfaces have been deleted, which 1229 * might affect routes for point-to-point links. 1230 */ 1231 if (!addrouteforif(ifp)) 1232 continue; 1233 1234 /* Add routes to the local end of point-to-point interfaces 1235 * using loopback. 1236 */ 1237 if ((ifp->int_if_flags & IFF_POINTOPOINT) 1238 && !(ifp->int_state & IS_REMOTE) 1239 && foundloopback) { 1240 /* Delete any routes to the network address through 1241 * foreign routers. Remove even static routes. 1242 */ 1243 del_static(ifp->int_addr, HOST_MASK, 0, 0); 1244 rt = rtget(ifp->int_addr, HOST_MASK); 1245 if (rt != 0 && rt->rt_router != loopaddr) { 1246 rtdelete(rt); 1247 rt = 0; 1248 } 1249 if (rt != 0) { 1250 if (!(rt->rt_state & RS_LOCAL) 1251 || rt->rt_metric > ifp->int_metric) { 1252 ifp1 = ifp; 1253 } else { 1254 ifp1 = rt->rt_ifp; 1255 } 1256 loop_rts.rts_ifp = ifp1; 1257 loop_rts.rts_metric = 0; 1258 loop_rts.rts_time = rt->rt_time; 1259 rtchange(rt, ((rt->rt_state & ~RS_NET_SYN) 1260 | (RS_IF|RS_LOCAL)), 1261 &loop_rts, 0); 1262 } else { 1263 loop_rts.rts_ifp = ifp; 1264 loop_rts.rts_metric = 0; 1265 rtadd(ifp->int_addr, HOST_MASK, 1266 (RS_IF | RS_LOCAL), &loop_rts); 1267 } 1268 } 1269 } 1270 1271 /* add the authority routes */ 1272 for (intnetp = intnets; intnetp!=0; intnetp = intnetp->intnet_next) { 1273 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask); 1274 if (rt != 0 1275 && !(rt->rt_state & RS_NO_NET_SYN) 1276 && !(rt->rt_state & RS_NET_INT)) { 1277 rtdelete(rt); 1278 rt = 0; 1279 } 1280 if (rt == 0) { 1281 loop_rts.rts_ifp = 0; 1282 loop_rts.rts_metric = intnetp->intnet_metric-1; 1283 rtadd(intnetp->intnet_addr, intnetp->intnet_mask, 1284 RS_NET_SYN | RS_NET_INT, &loop_rts); 1285 } 1286 } 1287 1288 prev_complaints = complaints; 1289 } 1290 1291 1292 static void 1293 check_net_syn(struct interface *ifp) 1294 { 1295 struct rt_entry *rt; 1296 static struct rt_spare new; 1297 1298 1299 /* Turn on the need to automatically synthesize a network route 1300 * for this interface only if we are running RIPv1 on some other 1301 * interface that is on a different class-A,B,or C network. 1302 */ 1303 if (have_ripv1_out || have_ripv1_in) { 1304 ifp->int_state |= IS_NEED_NET_SYN; 1305 rt = rtget(ifp->int_std_addr, ifp->int_std_mask); 1306 if (rt != 0 1307 && 0 == (rt->rt_state & RS_NO_NET_SYN) 1308 && (!(rt->rt_state & RS_NET_SYN) 1309 || rt->rt_metric > ifp->int_metric)) { 1310 rtdelete(rt); 1311 rt = 0; 1312 } 1313 if (rt == 0) { 1314 new.rts_ifp = ifp; 1315 new.rts_gate = ifp->int_addr; 1316 new.rts_router = ifp->int_addr; 1317 new.rts_metric = ifp->int_metric; 1318 rtadd(ifp->int_std_addr, ifp->int_std_mask, 1319 RS_NET_SYN, &new); 1320 } 1321 1322 } else { 1323 ifp->int_state &= ~IS_NEED_NET_SYN; 1324 1325 rt = rtget(ifp->int_std_addr, 1326 ifp->int_std_mask); 1327 if (rt != 0 1328 && (rt->rt_state & RS_NET_SYN) 1329 && rt->rt_ifp == ifp) 1330 rtbad_sub(rt); 1331 } 1332 } 1333 1334 1335 /* Add route for interface if not currently installed. 1336 * Create route to other end if a point-to-point link, 1337 * otherwise a route to this (sub)network. 1338 */ 1339 int /* 0=bad interface */ 1340 addrouteforif(struct interface *ifp) 1341 { 1342 struct rt_entry *rt; 1343 static struct rt_spare new; 1344 naddr dst; 1345 1346 1347 /* skip sick interfaces 1348 */ 1349 if (ifp->int_state & IS_BROKE) 1350 return 0; 1351 1352 /* If the interface on a subnet, then install a RIPv1 route to 1353 * the network as well (unless it is sick). 1354 */ 1355 if (ifp->int_state & IS_SUBNET) 1356 check_net_syn(ifp); 1357 1358 dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) 1359 ? ifp->int_dstaddr 1360 : htonl(ifp->int_net)); 1361 1362 new.rts_ifp = ifp; 1363 new.rts_router = ifp->int_addr; 1364 new.rts_gate = ifp->int_addr; 1365 new.rts_metric = ifp->int_metric; 1366 new.rts_time = now.tv_sec; 1367 1368 /* If we are going to send packets to the gateway, 1369 * it must be reachable using our physical interfaces 1370 */ 1371 if ((ifp->int_state & IS_REMOTE) 1372 && !(ifp->int_state & IS_EXTERNAL) 1373 && !check_remote(ifp)) 1374 return 0; 1375 1376 /* We are finished if the correct main interface route exists. 1377 * The right route must be for the right interface, not synthesized 1378 * from a subnet, be a "gateway" or not as appropriate, and so forth. 1379 */ 1380 del_static(dst, ifp->int_mask, 0, 0); 1381 rt = rtget(dst, ifp->int_mask); 1382 if (rt != 0) { 1383 if ((rt->rt_ifp != ifp 1384 || rt->rt_router != ifp->int_addr) 1385 && (!(ifp->int_state & IS_DUP) 1386 || rt->rt_ifp == 0 1387 || (rt->rt_ifp->int_state & IS_BROKE))) { 1388 rtdelete(rt); 1389 rt = 0; 1390 } else { 1391 rtchange(rt, ((rt->rt_state | RS_IF) 1392 & ~(RS_NET_SYN | RS_LOCAL)), 1393 &new, 0); 1394 } 1395 } 1396 if (rt == 0) { 1397 if (ifp->int_transitions++ > 0) 1398 trace_act("re-install interface %s", 1399 ifp->int_name); 1400 1401 rtadd(dst, ifp->int_mask, RS_IF, &new); 1402 } 1403 1404 return 1; 1405 } 1406