1 /* $NetBSD: if.c,v 1.20 2000/06/11 23:43:17 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1983, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgment: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) 37 static char sccsid[] __attribute__((unused)) = "@(#)if.c 8.1 (Berkeley) 6/5/93"; 38 #elif defined(__NetBSD__) 39 #include <sys/cdefs.h> 40 __RCSID("$NetBSD: if.c,v 1.20 2000/06/11 23:43:17 christos Exp $"); 41 #endif 42 43 #include "defs.h" 44 #include "pathnames.h" 45 46 struct interface *ifnet; /* all interfaces */ 47 48 /* hash table for all interfaces, big enough to tolerate ridiculous 49 * numbers of IP aliases. Crazy numbers of aliases such as 7000 50 * still will not do well, but not just in looking up interfaces 51 * by name or address. 52 */ 53 #define AHASH_LEN 211 /* must be prime */ 54 #define AHASH(a) &ahash_tbl[(a)%AHASH_LEN] 55 struct interface *ahash_tbl[AHASH_LEN]; 56 57 #define BHASH_LEN 211 /* must be prime */ 58 #define BHASH(a) &bhash_tbl[(a)%BHASH_LEN] 59 struct interface *bhash_tbl[BHASH_LEN]; 60 61 struct interface *remote_if; /* remote interfaces */ 62 63 /* hash for physical interface names. 64 * Assume there are never more 100 or 200 real interfaces, and that 65 * aliases are put on the end of the hash chains. 66 */ 67 #define NHASH_LEN 97 68 struct interface *nhash_tbl[NHASH_LEN]; 69 70 int tot_interfaces; /* # of remote and local interfaces */ 71 int rip_interfaces; /* # of interfaces doing RIP */ 72 int foundloopback; /* valid flag for loopaddr */ 73 naddr loopaddr; /* our address on loopback */ 74 struct rt_spare loop_rts; 75 76 struct timeval ifinit_timer; 77 static struct timeval last_ifinit; 78 #define IF_RESCAN_DELAY() (last_ifinit.tv_sec == now.tv_sec \ 79 && last_ifinit.tv_usec == now.tv_usec \ 80 && timercmp(&ifinit_timer, &now, >)) 81 82 int have_ripv1_out; /* have a RIPv1 interface */ 83 int have_ripv1_in; 84 85 86 static struct interface** 87 nhash(char *p) 88 { 89 u_int i; 90 91 for (i = 0; *p != '\0'; p++) { 92 i = ((i<<1) & 0x7fffffff) | ((i>>31) & 1); 93 i ^= *p; 94 } 95 return &nhash_tbl[i % NHASH_LEN]; 96 } 97 98 99 /* Link a new interface into the lists and hash tables. 100 */ 101 void 102 if_link(struct interface *ifp) 103 { 104 struct interface **hifp; 105 106 ifp->int_prev = &ifnet; 107 ifp->int_next = ifnet; 108 if (ifnet != 0) 109 ifnet->int_prev = &ifp->int_next; 110 ifnet = ifp; 111 112 hifp = AHASH(ifp->int_addr); 113 ifp->int_ahash_prev = hifp; 114 if ((ifp->int_ahash = *hifp) != 0) 115 (*hifp)->int_ahash_prev = &ifp->int_ahash; 116 *hifp = ifp; 117 118 if (ifp->int_if_flags & IFF_BROADCAST) { 119 hifp = BHASH(ifp->int_brdaddr); 120 ifp->int_bhash_prev = hifp; 121 if ((ifp->int_bhash = *hifp) != 0) 122 (*hifp)->int_bhash_prev = &ifp->int_bhash; 123 *hifp = ifp; 124 } 125 126 if (ifp->int_state & IS_REMOTE) { 127 ifp->int_rlink_prev = &remote_if; 128 ifp->int_rlink = remote_if; 129 if (remote_if != 0) 130 remote_if->int_rlink_prev = &ifp->int_rlink; 131 remote_if = ifp; 132 } 133 134 hifp = nhash(ifp->int_name); 135 if (ifp->int_state & IS_ALIAS) { 136 /* put aliases on the end of the hash chain */ 137 while (*hifp != 0) 138 hifp = &(*hifp)->int_nhash; 139 } 140 ifp->int_nhash_prev = hifp; 141 if ((ifp->int_nhash = *hifp) != 0) 142 (*hifp)->int_nhash_prev = &ifp->int_nhash; 143 *hifp = ifp; 144 } 145 146 147 /* Find the interface with an address 148 */ 149 struct interface * 150 ifwithaddr(naddr addr, 151 int bcast, /* notice IFF_BROADCAST address */ 152 int remote) /* include IS_REMOTE interfaces */ 153 { 154 struct interface *ifp, *possible = 0; 155 156 remote = (remote == 0) ? IS_REMOTE : 0; 157 158 for (ifp = *AHASH(addr); ifp; ifp = ifp->int_ahash) { 159 if (ifp->int_addr != addr) 160 continue; 161 if ((ifp->int_state & remote) != 0) 162 continue; 163 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0) 164 return ifp; 165 possible = ifp; 166 } 167 168 if (possible || !bcast) 169 return possible; 170 171 for (ifp = *BHASH(addr); ifp; ifp = ifp->int_bhash) { 172 if (ifp->int_brdaddr != addr) 173 continue; 174 if ((ifp->int_state & remote) != 0) 175 continue; 176 if ((ifp->int_state & (IS_BROKE | IS_PASSIVE)) == 0) 177 return ifp; 178 possible = ifp; 179 } 180 181 return possible; 182 } 183 184 185 /* find the interface with a name 186 */ 187 struct interface * 188 ifwithname(char *name, /* "ec0" or whatever */ 189 naddr addr) /* 0 or network address */ 190 { 191 struct interface *ifp; 192 193 for (;;) { 194 for (ifp = *nhash(name); ifp != 0; ifp = ifp->int_nhash) { 195 /* If the network address is not specified, 196 * ignore any alias interfaces. Otherwise, look 197 * for the interface with the target name and address. 198 */ 199 if (!strcmp(ifp->int_name, name) 200 && ((addr == 0 && !(ifp->int_state & IS_ALIAS)) 201 || (ifp->int_addr == addr))) 202 return ifp; 203 } 204 205 /* If there is no known interface, maybe there is a 206 * new interface. So just once look for new interfaces. 207 */ 208 if (IF_RESCAN_DELAY()) 209 return 0; 210 ifinit(); 211 } 212 } 213 214 215 struct interface * 216 ifwithindex(u_short index, 217 int rescan_ok) 218 { 219 struct interface *ifp; 220 221 for (;;) { 222 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) { 223 if (ifp->int_index == index) 224 return ifp; 225 } 226 227 /* If there is no known interface, maybe there is a 228 * new interface. So just once look for new interfaces. 229 */ 230 if (!rescan_ok 231 || IF_RESCAN_DELAY()) 232 return 0; 233 ifinit(); 234 } 235 } 236 237 238 /* Find an interface from which the specified address 239 * should have come from. Used for figuring out which 240 * interface a packet came in on. 241 */ 242 struct interface * 243 iflookup(naddr addr) 244 { 245 struct interface *ifp, *maybe; 246 int once = 0; 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 || once) 271 return maybe; 272 273 /* If there is no known interface, maybe there is a 274 * new interface. So just once look for new interfaces. 275 */ 276 ifinit(); 277 once = 1; 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 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 a IP address looks reasonable as a destination 371 */ 372 int /* 0=bad */ 373 check_dst(naddr addr) 374 { 375 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 #ifdef RTM_OIFINFO 741 if (ifam->ifam_type == RTM_OIFINFO) { 742 continue; /* just ignore compat message */ 743 } 744 #endif 745 if (ifam->ifam_type == RTM_IFINFO) { 746 struct sockaddr_dl *sdl; 747 748 ifm = (struct if_msghdr *)ifam; 749 /* make prototype structure for the IP aliases 750 */ 751 memset(&ifs0, 0, sizeof(ifs0)); 752 ifs0.int_rip_sock = -1; 753 ifs0.int_index = ifm->ifm_index; 754 ifs0.int_if_flags = ifm->ifm_flags; 755 ifs0.int_state = IS_CHECKED; 756 ifs0.int_query_time = NEVER; 757 ifs0.int_act_time = now.tv_sec; 758 ifs0.int_data.ts = now.tv_sec; 759 ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets; 760 ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors; 761 ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets; 762 ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors; 763 #ifdef sgi 764 ifs0.int_data.odrops = ifm->ifm_data.ifi_odrops; 765 #endif 766 sdl = (struct sockaddr_dl *)(ifm + 1); 767 sdl->sdl_data[sdl->sdl_nlen] = 0; 768 strncpy(ifs0.int_name, sdl->sdl_data, 769 MIN(sizeof(ifs0.int_name), sdl->sdl_nlen)); 770 continue; 771 } 772 if (ifam->ifam_type != RTM_NEWADDR) { 773 logbad(1,"ifinit: out of sync"); 774 continue; 775 } 776 rt_xaddrs(&info, (struct sockaddr *)(ifam+1), 777 (struct sockaddr *)ifam2, 778 ifam->ifam_addrs); 779 780 /* Prepare for the next address of this interface, which 781 * will be an alias. 782 * Do not output RIP or Router-Discovery packets via aliases. 783 */ 784 memcpy(&ifs, &ifs0, sizeof(ifs)); 785 ifs0.int_state |= (IS_ALIAS | IS_NO_RIP_OUT | IS_NO_RDISC); 786 787 if (INFO_IFA(&info) == 0) { 788 if (iff_up(ifs.int_if_flags)) { 789 if (!(prev_complaints & COMP_NOADDR)) 790 msglog("%s has no address", 791 ifs.int_name); 792 complaints |= COMP_NOADDR; 793 } 794 continue; 795 } 796 if (INFO_IFA(&info)->sa_family != AF_INET) { 797 if (iff_up(ifs.int_if_flags)) { 798 if (!(prev_complaints & COMP_NOT_INET)) 799 trace_act("%s: not AF_INET", 800 ifs.int_name); 801 complaints |= COMP_NOT_INET; 802 } 803 continue; 804 } 805 806 ifs.int_addr = S_ADDR(INFO_IFA(&info)); 807 808 if (ntohl(ifs.int_addr)>>24 == 0 809 || ntohl(ifs.int_addr)>>24 == 0xff) { 810 if (iff_up(ifs.int_if_flags)) { 811 if (!(prev_complaints & COMP_BADADDR)) 812 msglog("%s has a bad address", 813 ifs.int_name); 814 complaints |= COMP_BADADDR; 815 } 816 continue; 817 } 818 819 if (ifs.int_if_flags & IFF_LOOPBACK) { 820 ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC; 821 ifs.int_dstaddr = ifs.int_addr; 822 ifs.int_mask = HOST_MASK; 823 ifs.int_ripv1_mask = HOST_MASK; 824 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 825 ifs.int_net = ntohl(ifs.int_dstaddr); 826 if (!foundloopback) { 827 foundloopback = 1; 828 loopaddr = ifs.int_addr; 829 loop_rts.rts_gate = loopaddr; 830 loop_rts.rts_router = loopaddr; 831 } 832 833 } else if (ifs.int_if_flags & IFF_POINTOPOINT) { 834 if (INFO_BRD(&info) == 0 835 || INFO_BRD(&info)->sa_family != AF_INET) { 836 if (iff_up(ifs.int_if_flags)) { 837 if (!(prev_complaints & COMP_NODST)) 838 msglog("%s has a bad" 839 " destination address", 840 ifs.int_name); 841 complaints |= COMP_NODST; 842 } 843 continue; 844 } 845 ifs.int_dstaddr = S_ADDR(INFO_BRD(&info)); 846 if (ntohl(ifs.int_dstaddr)>>24 == 0 847 || ntohl(ifs.int_dstaddr)>>24 == 0xff) { 848 if (iff_up(ifs.int_if_flags)) { 849 if (!(prev_complaints & COMP_NODST)) 850 msglog("%s has a bad" 851 " destination address", 852 ifs.int_name); 853 complaints |= COMP_NODST; 854 } 855 continue; 856 } 857 ifs.int_mask = HOST_MASK; 858 ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info))); 859 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 860 ifs.int_net = ntohl(ifs.int_dstaddr); 861 862 } else { 863 if (INFO_MASK(&info) == 0) { 864 if (iff_up(ifs.int_if_flags)) { 865 if (!(prev_complaints & COMP_NOMASK)) 866 msglog("%s has no netmask", 867 ifs.int_name); 868 complaints |= COMP_NOMASK; 869 } 870 continue; 871 } 872 ifs.int_dstaddr = ifs.int_addr; 873 ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info))); 874 ifs.int_ripv1_mask = ifs.int_mask; 875 ifs.int_std_mask = std_mask(ifs.int_addr); 876 ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask; 877 if (ifs.int_mask != ifs.int_std_mask) 878 ifs.int_state |= IS_SUBNET; 879 880 if (ifs.int_if_flags & IFF_BROADCAST) { 881 if (INFO_BRD(&info) == 0) { 882 if (iff_up(ifs.int_if_flags)) { 883 if (!(prev_complaints 884 & COMP_NOBADR)) 885 msglog("%s has" 886 "no broadcast address", 887 ifs.int_name); 888 complaints |= COMP_NOBADR; 889 } 890 continue; 891 } 892 ifs.int_brdaddr = S_ADDR(INFO_BRD(&info)); 893 } 894 } 895 ifs.int_std_net = ifs.int_net & ifs.int_std_mask; 896 ifs.int_std_addr = htonl(ifs.int_std_net); 897 898 /* Use a minimum metric of one. Treat the interface metric 899 * (default 0) as an increment to the hop count of one. 900 * 901 * The metric obtained from the routing socket dump of 902 * interface addresses is wrong. It is not set by the 903 * SIOCSIFMETRIC ioctl. 904 */ 905 #ifdef SIOCGIFMETRIC 906 strncpy(ifr.ifr_name, ifs.int_name, sizeof(ifr.ifr_name)); 907 if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) { 908 DBGERR(1, "ioctl(SIOCGIFMETRIC)"); 909 ifs.int_metric = 0; 910 } else { 911 ifs.int_metric = ifr.ifr_metric; 912 } 913 #else 914 ifs.int_metric = ifam->ifam_metric; 915 #endif 916 if (ifs.int_metric > HOPCNT_INFINITY) { 917 ifs.int_metric = 0; 918 if (!(prev_complaints & COMP_BAD_METRIC) 919 && iff_up(ifs.int_if_flags)) { 920 complaints |= COMP_BAD_METRIC; 921 msglog("%s has a metric of %d", 922 ifs.int_name, ifs.int_metric); 923 } 924 } 925 926 /* See if this is a familiar interface. 927 * If so, stop worrying about it if it is the same. 928 * Start it over if it now is to somewhere else, as happens 929 * frequently with PPP and SLIP. 930 */ 931 ifp = ifwithname(ifs.int_name, ((ifs.int_state & IS_ALIAS) 932 ? ifs.int_addr 933 : 0)); 934 if (ifp != 0) { 935 ifp->int_state |= IS_CHECKED; 936 937 if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags) 938 & (IFF_BROADCAST 939 | IFF_LOOPBACK 940 | IFF_POINTOPOINT 941 | IFF_MULTICAST)) 942 || 0 != ((ifp->int_state ^ ifs.int_state) 943 & IS_ALIAS) 944 || ifp->int_addr != ifs.int_addr 945 || ifp->int_brdaddr != ifs.int_brdaddr 946 || ifp->int_dstaddr != ifs.int_dstaddr 947 || ifp->int_mask != ifs.int_mask 948 || ifp->int_metric != ifs.int_metric) { 949 /* Forget old information about 950 * a changed interface. 951 */ 952 trace_act("interface %s has changed", 953 ifp->int_name); 954 ifdel(ifp); 955 ifp = 0; 956 } 957 } 958 959 if (ifp != 0) { 960 /* The primary representative of an alias worries 961 * about how things are working. 962 */ 963 if (ifp->int_state & IS_ALIAS) 964 continue; 965 966 /* note interfaces that have been turned off 967 */ 968 if (!iff_up(ifs.int_if_flags)) { 969 if (iff_up(ifp->int_if_flags)) { 970 msglog("interface %s to %s turned off", 971 ifp->int_name, 972 naddr_ntoa(ifp->int_dstaddr)); 973 if_bad(ifp); 974 ifp->int_if_flags &= ~IFF_UP; 975 } else if (now.tv_sec>(ifp->int_data.ts 976 + CHECK_BAD_INTERVAL)) { 977 trace_act("interface %s has been off" 978 " %ld seconds; forget it", 979 ifp->int_name, 980 now.tv_sec-ifp->int_data.ts); 981 ifdel(ifp); 982 } 983 continue; 984 } 985 /* or that were off and are now ok */ 986 if (!iff_up(ifp->int_if_flags)) { 987 ifp->int_if_flags |= IFF_UP; 988 (void)if_ok(ifp, ""); 989 } 990 991 /* If it has been long enough, 992 * see if the interface is broken. 993 */ 994 if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL) 995 continue; 996 997 in = ifs.int_data.ipackets - ifp->int_data.ipackets; 998 ierr = ifs.int_data.ierrors - ifp->int_data.ierrors; 999 out = ifs.int_data.opackets - ifp->int_data.opackets; 1000 oerr = ifs.int_data.oerrors - ifp->int_data.oerrors; 1001 #ifdef sgi 1002 /* Through at least IRIX 6.2, PPP and SLIP 1003 * count packets dropped by the filters. 1004 * But FDDI rings stuck non-operational count 1005 * dropped packets as they wait for improvement. 1006 */ 1007 if (!(ifp->int_if_flags & IFF_POINTOPOINT)) 1008 oerr += (ifs.int_data.odrops 1009 - ifp->int_data.odrops); 1010 #endif 1011 /* If the interface just awoke, restart the counters. 1012 */ 1013 if (ifp->int_data.ts == 0) { 1014 ifp->int_data = ifs.int_data; 1015 continue; 1016 } 1017 ifp->int_data = ifs.int_data; 1018 1019 /* Withhold judgment when the short error 1020 * counters wrap or the interface is reset. 1021 */ 1022 if (ierr < 0 || in < 0 || oerr < 0 || out < 0) { 1023 LIM_SEC(ifinit_timer, 1024 now.tv_sec+CHECK_BAD_INTERVAL); 1025 continue; 1026 } 1027 1028 /* Withhold judgement when there is no traffic 1029 */ 1030 if (in == 0 && out == 0 && ierr == 0 && oerr == 0) 1031 continue; 1032 1033 /* It is bad if input or output is not working. 1034 * Require presistent problems before marking it dead. 1035 */ 1036 if ((in <= ierr && ierr > 0) 1037 || (out <= oerr && oerr > 0)) { 1038 if (!(ifp->int_state & IS_SICK)) { 1039 trace_act("interface %s to %s" 1040 " sick: in=%d ierr=%d" 1041 " out=%d oerr=%d", 1042 ifp->int_name, 1043 naddr_ntoa(ifp->int_dstaddr), 1044 in, ierr, out, oerr); 1045 if_sick(ifp); 1046 continue; 1047 } 1048 if (!(ifp->int_state & IS_BROKE)) { 1049 msglog("interface %s to %s broken:" 1050 " in=%d ierr=%d out=%d oerr=%d", 1051 ifp->int_name, 1052 naddr_ntoa(ifp->int_dstaddr), 1053 in, ierr, out, oerr); 1054 if_bad(ifp); 1055 } 1056 continue; 1057 } 1058 1059 /* otherwise, it is active and healthy 1060 */ 1061 ifp->int_act_time = now.tv_sec; 1062 (void)if_ok(ifp, ""); 1063 continue; 1064 } 1065 1066 /* This is a new interface. 1067 * If it is dead, forget it. 1068 */ 1069 if (!iff_up(ifs.int_if_flags)) 1070 continue; 1071 1072 /* If it duplicates an existing interface, 1073 * complain about it, mark the other one 1074 * duplicated, and forget this one. 1075 */ 1076 ifp = check_dup(ifs.int_addr,ifs.int_dstaddr,ifs.int_mask, 1077 ifs.int_if_flags); 1078 if (ifp != 0) { 1079 /* Ignore duplicates of itself, caused by having 1080 * IP aliases on the same network. 1081 */ 1082 if (!strcmp(ifp->int_name, ifs.int_name)) 1083 continue; 1084 1085 if (!(prev_complaints & COMP_DUP)) { 1086 complaints |= COMP_DUP; 1087 msglog("%s (%s%s%s) is duplicated by" 1088 " %s (%s%s%s)", 1089 ifs.int_name, 1090 addrname(ifs.int_addr,ifs.int_mask,1), 1091 ((ifs.int_if_flags & IFF_POINTOPOINT) 1092 ? "-->" : ""), 1093 ((ifs.int_if_flags & IFF_POINTOPOINT) 1094 ? naddr_ntoa(ifs.int_dstaddr) : ""), 1095 ifp->int_name, 1096 addrname(ifp->int_addr,ifp->int_mask,1), 1097 ((ifp->int_if_flags & IFF_POINTOPOINT) 1098 ? "-->" : ""), 1099 ((ifp->int_if_flags & IFF_POINTOPOINT) 1100 ? naddr_ntoa(ifp->int_dstaddr) : "")); 1101 } 1102 ifp->int_state |= IS_DUP; 1103 continue; 1104 } 1105 1106 if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT | IFF_BROADCAST)) 1107 && !(ifs.int_state & IS_PASSIVE)) { 1108 trace_act("%s is neither broadcast, point-to-point," 1109 " nor loopback", 1110 ifs.int_name); 1111 if (!(ifs.int_state & IFF_MULTICAST)) 1112 ifs.int_state |= IS_NO_RDISC; 1113 } 1114 1115 1116 /* It is new and ok. Add it to the list of interfaces 1117 */ 1118 ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit ifp"); 1119 memcpy(ifp, &ifs, sizeof(*ifp)); 1120 get_parms(ifp); 1121 if_link(ifp); 1122 trace_if("Add", ifp); 1123 1124 /* Notice likely bad netmask. 1125 */ 1126 if (!(prev_complaints & COMP_NETMASK) 1127 && !(ifp->int_if_flags & IFF_POINTOPOINT) 1128 && ifp->int_addr != RIP_DEFAULT) { 1129 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 1130 if (ifp1->int_mask == ifp->int_mask) 1131 continue; 1132 if (ifp1->int_if_flags & IFF_POINTOPOINT) 1133 continue; 1134 if (ifp1->int_dstaddr == RIP_DEFAULT) 1135 continue; 1136 if (on_net(ifp->int_dstaddr, 1137 ifp1->int_net, ifp1->int_mask) 1138 || on_net(ifp1->int_dstaddr, 1139 ifp->int_net, ifp->int_mask)) { 1140 msglog("possible netmask problem" 1141 " between %s:%s and %s:%s", 1142 ifp->int_name, 1143 addrname(htonl(ifp->int_net), 1144 ifp->int_mask, 1), 1145 ifp1->int_name, 1146 addrname(htonl(ifp1->int_net), 1147 ifp1->int_mask, 1)); 1148 complaints |= COMP_NETMASK; 1149 } 1150 } 1151 } 1152 1153 if (!(ifp->int_state & IS_ALIAS)) { 1154 /* Count the # of directly connected networks. 1155 */ 1156 if (!(ifp->int_if_flags & IFF_LOOPBACK)) 1157 tot_interfaces++; 1158 if (!IS_RIP_OFF(ifp->int_state)) 1159 rip_interfaces++; 1160 1161 /* turn on router discovery and RIP If needed */ 1162 if_ok_rdisc(ifp); 1163 rip_on(ifp); 1164 } 1165 } 1166 1167 /* If we are multi-homed and have at least two interfaces 1168 * listening to RIP, then output by default. 1169 */ 1170 if (!supplier_set && rip_interfaces > 1) 1171 set_supplier(); 1172 1173 /* If we are multi-homed, optionally advertise a route to 1174 * our main address. 1175 */ 1176 if (advertise_mhome 1177 || (tot_interfaces > 1 1178 && mhome 1179 && (ifp = ifwithaddr(myaddr, 0, 0)) != 0 1180 && foundloopback)) { 1181 advertise_mhome = 1; 1182 rt = rtget(myaddr, HOST_MASK); 1183 if (rt != 0) { 1184 if (rt->rt_ifp != ifp 1185 || rt->rt_router != loopaddr) { 1186 rtdelete(rt); 1187 rt = 0; 1188 } else { 1189 loop_rts.rts_ifp = ifp; 1190 loop_rts.rts_metric = 0; 1191 loop_rts.rts_time = rt->rt_time; 1192 rtchange(rt, rt->rt_state | RS_MHOME, 1193 &loop_rts, 0); 1194 } 1195 } 1196 if (rt == 0) { 1197 loop_rts.rts_ifp = ifp; 1198 loop_rts.rts_metric = 0; 1199 rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts); 1200 } 1201 } 1202 1203 for (ifp = ifnet; ifp != 0; ifp = ifp1) { 1204 ifp1 = ifp->int_next; /* because we may delete it */ 1205 1206 /* Forget any interfaces that have disappeared. 1207 */ 1208 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) { 1209 trace_act("interface %s has disappeared", 1210 ifp->int_name); 1211 ifdel(ifp); 1212 continue; 1213 } 1214 1215 if ((ifp->int_state & IS_BROKE) 1216 && !(ifp->int_state & IS_PASSIVE)) 1217 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 1218 1219 /* If we ever have a RIPv1 interface, assume we always will. 1220 * It might come back if it ever goes away. 1221 */ 1222 if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier) 1223 have_ripv1_out = 1; 1224 if (!(ifp->int_state & IS_NO_RIPV1_IN)) 1225 have_ripv1_in = 1; 1226 } 1227 1228 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 1229 /* Ensure there is always a network route for interfaces, 1230 * after any dead interfaces have been deleted, which 1231 * might affect routes for point-to-point links. 1232 */ 1233 if (!addrouteforif(ifp)) 1234 continue; 1235 1236 /* Add routes to the local end of point-to-point interfaces 1237 * using loopback. 1238 */ 1239 if ((ifp->int_if_flags & IFF_POINTOPOINT) 1240 && !(ifp->int_state & IS_REMOTE) 1241 && foundloopback) { 1242 /* Delete any routes to the network address through 1243 * foreign routers. Remove even static routes. 1244 */ 1245 del_static(ifp->int_addr, HOST_MASK, 0, 0); 1246 rt = rtget(ifp->int_addr, HOST_MASK); 1247 if (rt != 0 && rt->rt_router != loopaddr) { 1248 rtdelete(rt); 1249 rt = 0; 1250 } 1251 if (rt != 0) { 1252 if (!(rt->rt_state & RS_LOCAL) 1253 || rt->rt_metric > ifp->int_metric) { 1254 ifp1 = ifp; 1255 } else { 1256 ifp1 = rt->rt_ifp; 1257 } 1258 loop_rts.rts_ifp = ifp1; 1259 loop_rts.rts_metric = 0; 1260 loop_rts.rts_time = rt->rt_time; 1261 rtchange(rt, ((rt->rt_state & ~RS_NET_SYN) 1262 | (RS_IF|RS_LOCAL)), 1263 &loop_rts, 0); 1264 } else { 1265 loop_rts.rts_ifp = ifp; 1266 loop_rts.rts_metric = 0; 1267 rtadd(ifp->int_addr, HOST_MASK, 1268 (RS_IF | RS_LOCAL), &loop_rts); 1269 } 1270 } 1271 } 1272 1273 /* add the authority routes */ 1274 for (intnetp = intnets; intnetp!=0; intnetp = intnetp->intnet_next) { 1275 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask); 1276 if (rt != 0 1277 && !(rt->rt_state & RS_NO_NET_SYN) 1278 && !(rt->rt_state & RS_NET_INT)) { 1279 rtdelete(rt); 1280 rt = 0; 1281 } 1282 if (rt == 0) { 1283 loop_rts.rts_ifp = 0; 1284 loop_rts.rts_metric = intnetp->intnet_metric-1; 1285 rtadd(intnetp->intnet_addr, intnetp->intnet_mask, 1286 RS_NET_SYN | RS_NET_INT, &loop_rts); 1287 } 1288 } 1289 1290 prev_complaints = complaints; 1291 } 1292 1293 1294 static void 1295 check_net_syn(struct interface *ifp) 1296 { 1297 struct rt_entry *rt; 1298 static struct rt_spare new; 1299 1300 1301 /* Turn on the need to automatically synthesize a network route 1302 * for this interface only if we are running RIPv1 on some other 1303 * interface that is on a different class-A,B,or C network. 1304 */ 1305 if (have_ripv1_out || have_ripv1_in) { 1306 ifp->int_state |= IS_NEED_NET_SYN; 1307 rt = rtget(ifp->int_std_addr, ifp->int_std_mask); 1308 if (rt != 0 1309 && 0 == (rt->rt_state & RS_NO_NET_SYN) 1310 && (!(rt->rt_state & RS_NET_SYN) 1311 || rt->rt_metric > ifp->int_metric)) { 1312 rtdelete(rt); 1313 rt = 0; 1314 } 1315 if (rt == 0) { 1316 new.rts_ifp = ifp; 1317 new.rts_gate = ifp->int_addr; 1318 new.rts_router = ifp->int_addr; 1319 new.rts_metric = ifp->int_metric; 1320 rtadd(ifp->int_std_addr, ifp->int_std_mask, 1321 RS_NET_SYN, &new); 1322 } 1323 1324 } else { 1325 ifp->int_state &= ~IS_NEED_NET_SYN; 1326 1327 rt = rtget(ifp->int_std_addr, 1328 ifp->int_std_mask); 1329 if (rt != 0 1330 && (rt->rt_state & RS_NET_SYN) 1331 && rt->rt_ifp == ifp) 1332 rtbad_sub(rt); 1333 } 1334 } 1335 1336 1337 /* Add route for interface if not currently installed. 1338 * Create route to other end if a point-to-point link, 1339 * otherwise a route to this (sub)network. 1340 */ 1341 int /* 0=bad interface */ 1342 addrouteforif(struct interface *ifp) 1343 { 1344 struct rt_entry *rt; 1345 static struct rt_spare new; 1346 naddr dst; 1347 1348 1349 /* skip sick interfaces 1350 */ 1351 if (ifp->int_state & IS_BROKE) 1352 return 0; 1353 1354 /* If the interface on a subnet, then install a RIPv1 route to 1355 * the network as well (unless it is sick). 1356 */ 1357 if (ifp->int_state & IS_SUBNET) 1358 check_net_syn(ifp); 1359 1360 dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) 1361 ? ifp->int_dstaddr 1362 : htonl(ifp->int_net)); 1363 1364 new.rts_ifp = ifp; 1365 new.rts_router = ifp->int_addr; 1366 new.rts_gate = ifp->int_addr; 1367 new.rts_metric = ifp->int_metric; 1368 new.rts_time = now.tv_sec; 1369 1370 /* If we are going to send packets to the gateway, 1371 * it must be reachable using our physical interfaces 1372 */ 1373 if ((ifp->int_state & IS_REMOTE) 1374 && !(ifp->int_state & IS_EXTERNAL) 1375 && !check_remote(ifp)) 1376 return 0; 1377 1378 /* We are finished if the correct main interface route exists. 1379 * The right route must be for the right interface, not synthesized 1380 * from a subnet, be a "gateway" or not as appropriate, and so forth. 1381 */ 1382 del_static(dst, ifp->int_mask, 0, 0); 1383 rt = rtget(dst, ifp->int_mask); 1384 if (rt != 0) { 1385 if ((rt->rt_ifp != ifp 1386 || rt->rt_router != ifp->int_addr) 1387 && (!(ifp->int_state & IS_DUP) 1388 || rt->rt_ifp == 0 1389 || (rt->rt_ifp->int_state & IS_BROKE))) { 1390 rtdelete(rt); 1391 rt = 0; 1392 } else { 1393 rtchange(rt, ((rt->rt_state | RS_IF) 1394 & ~(RS_NET_SYN | RS_LOCAL)), 1395 &new, 0); 1396 } 1397 } 1398 if (rt == 0) { 1399 if (ifp->int_transitions++ > 0) 1400 trace_act("re-install interface %s", 1401 ifp->int_name); 1402 1403 rtadd(dst, ifp->int_mask, RS_IF, &new); 1404 } 1405 1406 return 1; 1407 } 1408