1 /* $NetBSD: if.c,v 1.21 2001/01/15 13:19:12 itojun 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.21 2001/01/15 13:19:12 itojun 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 #ifdef MCAST_IFINDEX 502 m.imr_interface.s_addr = htonl(ifp->int_index); 503 #else 504 m.imr_interface.s_addr = ((ifp->int_if_flags 505 & IFF_POINTOPOINT) 506 ? ifp->int_dstaddr 507 : ifp->int_addr); 508 #endif 509 if (setsockopt(rip_sock,IPPROTO_IP,IP_DROP_MEMBERSHIP, 510 &m, sizeof(m)) < 0 511 && errno != EADDRNOTAVAIL 512 && !TRACEACTIONS) 513 LOGERR("setsockopt(IP_DROP_MEMBERSHIP RIP)"); 514 if (rip_sock_mcast == ifp) 515 rip_sock_mcast = 0; 516 } 517 if (ifp->int_rip_sock >= 0) { 518 (void)close(ifp->int_rip_sock); 519 ifp->int_rip_sock = -1; 520 fix_select(); 521 } 522 523 tot_interfaces--; 524 if (!IS_RIP_OFF(ifp->int_state)) 525 rip_interfaces--; 526 527 /* Zap all routes associated with this interface. 528 * Assume routes just using gateways beyond this interface 529 * will timeout naturally, and have probably already died. 530 */ 531 (void)rn_walktree(rhead, walk_bad, 0); 532 533 set_rdisc_mg(ifp, 0); 534 if_bad_rdisc(ifp); 535 } 536 537 free(ifp); 538 } 539 540 541 /* Mark an interface ill. 542 */ 543 void 544 if_sick(struct interface *ifp) 545 { 546 if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) { 547 ifp->int_state |= IS_SICK; 548 ifp->int_act_time = NEVER; 549 trace_if("Chg", ifp); 550 551 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 552 } 553 } 554 555 556 /* Mark an interface dead. 557 */ 558 void 559 if_bad(struct interface *ifp) 560 { 561 struct interface *ifp1; 562 563 564 if (ifp->int_state & IS_BROKE) 565 return; 566 567 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 568 569 ifp->int_state |= (IS_BROKE | IS_SICK); 570 ifp->int_act_time = NEVER; 571 ifp->int_query_time = NEVER; 572 ifp->int_data.ts = now.tv_sec; 573 574 trace_if("Chg", ifp); 575 576 if (!(ifp->int_state & IS_ALIAS)) { 577 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 578 if (ifp1 != ifp 579 && !strcmp(ifp->int_name, ifp1->int_name)) 580 if_bad(ifp1); 581 } 582 (void)rn_walktree(rhead, walk_bad, 0); 583 if_bad_rdisc(ifp); 584 } 585 } 586 587 588 /* Mark an interface alive 589 */ 590 int /* 1=it was dead */ 591 if_ok(struct interface *ifp, 592 const char *type) 593 { 594 struct interface *ifp1; 595 596 597 if (!(ifp->int_state & IS_BROKE)) { 598 if (ifp->int_state & IS_SICK) { 599 trace_act("%sinterface %s to %s working better", 600 type, 601 ifp->int_name, naddr_ntoa(ifp->int_dstaddr)); 602 ifp->int_state &= ~IS_SICK; 603 } 604 return 0; 605 } 606 607 msglog("%sinterface %s to %s restored", 608 type, ifp->int_name, naddr_ntoa(ifp->int_dstaddr)); 609 ifp->int_state &= ~(IS_BROKE | IS_SICK); 610 ifp->int_data.ts = 0; 611 612 if (!(ifp->int_state & IS_ALIAS)) { 613 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 614 if (ifp1 != ifp 615 && !strcmp(ifp->int_name, ifp1->int_name)) 616 if_ok(ifp1, type); 617 } 618 if_ok_rdisc(ifp); 619 } 620 621 if (ifp->int_state & IS_REMOTE) { 622 if (!addrouteforif(ifp)) 623 return 0; 624 } 625 return 1; 626 } 627 628 629 /* disassemble routing message 630 */ 631 void 632 rt_xaddrs(struct rt_addrinfo *info, 633 struct sockaddr *sa, 634 struct sockaddr *lim, 635 int addrs) 636 { 637 int i; 638 #ifdef _HAVE_SA_LEN 639 static struct sockaddr sa_zero; 640 #endif 641 #ifdef sgi 642 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \ 643 : sizeof(__uint64_t)) 644 #else 645 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ 646 : sizeof(long)) 647 #endif 648 649 650 memset(info, 0, sizeof(*info)); 651 info->rti_addrs = addrs; 652 for (i = 0; i < RTAX_MAX && sa < lim; i++) { 653 if ((addrs & (1 << i)) == 0) 654 continue; 655 #ifdef _HAVE_SA_LEN 656 info->rti_info[i] = (sa->sa_len != 0) ? sa : &sa_zero; 657 sa = (struct sockaddr *)((char*)(sa) 658 + ROUNDUP(sa->sa_len)); 659 #else 660 info->rti_info[i] = sa; 661 sa = (struct sockaddr *)((char*)(sa) 662 + ROUNDUP(_FAKE_SA_LEN_DST(sa))); 663 #endif 664 } 665 } 666 667 668 /* Find the network interfaces which have configured themselves. 669 * This must be done regularly, if only for extra addresses 670 * that come and go on interfaces. 671 */ 672 void 673 ifinit(void) 674 { 675 static char *sysctl_buf; 676 static size_t sysctl_buf_size = 0; 677 uint complaints = 0; 678 static u_int prev_complaints = 0; 679 # define COMP_NOT_INET 0x001 680 # define COMP_NOADDR 0x002 681 # define COMP_BADADDR 0x004 682 # define COMP_NODST 0x008 683 # define COMP_NOBADR 0x010 684 # define COMP_NOMASK 0x020 685 # define COMP_DUP 0x040 686 # define COMP_BAD_METRIC 0x080 687 # define COMP_NETMASK 0x100 688 689 struct interface ifs, ifs0, *ifp, *ifp1; 690 struct rt_entry *rt; 691 size_t needed; 692 int mib[6]; 693 struct if_msghdr *ifm; 694 struct ifa_msghdr *ifam, *ifam_lim, *ifam2; 695 int in, ierr, out, oerr; 696 struct intnet *intnetp; 697 struct rt_addrinfo info; 698 #ifdef SIOCGIFMETRIC 699 struct ifreq ifr; 700 #endif 701 702 703 last_ifinit = now; 704 ifinit_timer.tv_sec = now.tv_sec + (supplier 705 ? CHECK_ACT_INTERVAL 706 : CHECK_QUIET_INTERVAL); 707 708 /* mark all interfaces so we can get rid of those that disappear */ 709 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) 710 ifp->int_state &= ~(IS_CHECKED | IS_DUP); 711 712 /* Fetch the interface list, without too many system calls 713 * since we do it repeatedly. 714 */ 715 mib[0] = CTL_NET; 716 mib[1] = PF_ROUTE; 717 mib[2] = 0; 718 mib[3] = AF_INET; 719 mib[4] = NET_RT_IFLIST; 720 mib[5] = 0; 721 for (;;) { 722 if ((needed = sysctl_buf_size) != 0) { 723 if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0) 724 break; 725 /* retry if the table grew */ 726 if (errno != ENOMEM && errno != EFAULT) 727 BADERR(1, "ifinit: sysctl(RT_IFLIST)"); 728 free(sysctl_buf); 729 needed = 0; 730 } 731 if (sysctl(mib, 6, 0, &needed, 0, 0) < 0) 732 BADERR(1,"ifinit: sysctl(RT_IFLIST) estimate"); 733 sysctl_buf = rtmalloc(sysctl_buf_size = needed, 734 "ifinit sysctl"); 735 } 736 737 ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed); 738 for (ifam = (struct ifa_msghdr *)sysctl_buf; 739 ifam < ifam_lim; 740 ifam = ifam2) { 741 742 ifam2 = (struct ifa_msghdr*)((char*)ifam + ifam->ifam_msglen); 743 744 #ifdef RTM_OIFINFO 745 if (ifam->ifam_type == RTM_OIFINFO) { 746 continue; /* just ignore compat message */ 747 } 748 #endif 749 if (ifam->ifam_type == RTM_IFINFO) { 750 struct sockaddr_dl *sdl; 751 752 ifm = (struct if_msghdr *)ifam; 753 /* make prototype structure for the IP aliases 754 */ 755 memset(&ifs0, 0, sizeof(ifs0)); 756 ifs0.int_rip_sock = -1; 757 ifs0.int_index = ifm->ifm_index; 758 ifs0.int_if_flags = ifm->ifm_flags; 759 ifs0.int_state = IS_CHECKED; 760 ifs0.int_query_time = NEVER; 761 ifs0.int_act_time = now.tv_sec; 762 ifs0.int_data.ts = now.tv_sec; 763 ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets; 764 ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors; 765 ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets; 766 ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors; 767 #ifdef sgi 768 ifs0.int_data.odrops = ifm->ifm_data.ifi_odrops; 769 #endif 770 sdl = (struct sockaddr_dl *)(ifm + 1); 771 sdl->sdl_data[sdl->sdl_nlen] = 0; 772 strncpy(ifs0.int_name, sdl->sdl_data, 773 MIN(sizeof(ifs0.int_name), sdl->sdl_nlen)); 774 continue; 775 } 776 if (ifam->ifam_type != RTM_NEWADDR) { 777 logbad(1,"ifinit: out of sync"); 778 continue; 779 } 780 rt_xaddrs(&info, (struct sockaddr *)(ifam+1), 781 (struct sockaddr *)ifam2, 782 ifam->ifam_addrs); 783 784 /* Prepare for the next address of this interface, which 785 * will be an alias. 786 * Do not output RIP or Router-Discovery packets via aliases. 787 */ 788 memcpy(&ifs, &ifs0, sizeof(ifs)); 789 ifs0.int_state |= (IS_ALIAS | IS_NO_RIP_OUT | IS_NO_RDISC); 790 791 if (INFO_IFA(&info) == 0) { 792 if (iff_up(ifs.int_if_flags)) { 793 if (!(prev_complaints & COMP_NOADDR)) 794 msglog("%s has no address", 795 ifs.int_name); 796 complaints |= COMP_NOADDR; 797 } 798 continue; 799 } 800 if (INFO_IFA(&info)->sa_family != AF_INET) { 801 if (iff_up(ifs.int_if_flags)) { 802 if (!(prev_complaints & COMP_NOT_INET)) 803 trace_act("%s: not AF_INET", 804 ifs.int_name); 805 complaints |= COMP_NOT_INET; 806 } 807 continue; 808 } 809 810 ifs.int_addr = S_ADDR(INFO_IFA(&info)); 811 812 if (ntohl(ifs.int_addr)>>24 == 0 813 || ntohl(ifs.int_addr)>>24 == 0xff) { 814 if (iff_up(ifs.int_if_flags)) { 815 if (!(prev_complaints & COMP_BADADDR)) 816 msglog("%s has a bad address", 817 ifs.int_name); 818 complaints |= COMP_BADADDR; 819 } 820 continue; 821 } 822 823 if (ifs.int_if_flags & IFF_LOOPBACK) { 824 ifs.int_state |= IS_PASSIVE | IS_NO_RIP | IS_NO_RDISC; 825 ifs.int_dstaddr = ifs.int_addr; 826 ifs.int_mask = HOST_MASK; 827 ifs.int_ripv1_mask = HOST_MASK; 828 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 829 ifs.int_net = ntohl(ifs.int_dstaddr); 830 if (!foundloopback) { 831 foundloopback = 1; 832 loopaddr = ifs.int_addr; 833 loop_rts.rts_gate = loopaddr; 834 loop_rts.rts_router = loopaddr; 835 } 836 837 } else if (ifs.int_if_flags & IFF_POINTOPOINT) { 838 if (INFO_BRD(&info) == 0 839 || INFO_BRD(&info)->sa_family != AF_INET) { 840 if (iff_up(ifs.int_if_flags)) { 841 if (!(prev_complaints & COMP_NODST)) 842 msglog("%s has a bad" 843 " destination address", 844 ifs.int_name); 845 complaints |= COMP_NODST; 846 } 847 continue; 848 } 849 ifs.int_dstaddr = S_ADDR(INFO_BRD(&info)); 850 if (ntohl(ifs.int_dstaddr)>>24 == 0 851 || ntohl(ifs.int_dstaddr)>>24 == 0xff) { 852 if (iff_up(ifs.int_if_flags)) { 853 if (!(prev_complaints & COMP_NODST)) 854 msglog("%s has a bad" 855 " destination address", 856 ifs.int_name); 857 complaints |= COMP_NODST; 858 } 859 continue; 860 } 861 ifs.int_mask = HOST_MASK; 862 ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info))); 863 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 864 ifs.int_net = ntohl(ifs.int_dstaddr); 865 866 } else { 867 if (INFO_MASK(&info) == 0) { 868 if (iff_up(ifs.int_if_flags)) { 869 if (!(prev_complaints & COMP_NOMASK)) 870 msglog("%s has no netmask", 871 ifs.int_name); 872 complaints |= COMP_NOMASK; 873 } 874 continue; 875 } 876 ifs.int_dstaddr = ifs.int_addr; 877 ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info))); 878 ifs.int_ripv1_mask = ifs.int_mask; 879 ifs.int_std_mask = std_mask(ifs.int_addr); 880 ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask; 881 if (ifs.int_mask != ifs.int_std_mask) 882 ifs.int_state |= IS_SUBNET; 883 884 if (ifs.int_if_flags & IFF_BROADCAST) { 885 if (INFO_BRD(&info) == 0) { 886 if (iff_up(ifs.int_if_flags)) { 887 if (!(prev_complaints 888 & COMP_NOBADR)) 889 msglog("%s has" 890 "no broadcast address", 891 ifs.int_name); 892 complaints |= COMP_NOBADR; 893 } 894 continue; 895 } 896 ifs.int_brdaddr = S_ADDR(INFO_BRD(&info)); 897 } 898 } 899 ifs.int_std_net = ifs.int_net & ifs.int_std_mask; 900 ifs.int_std_addr = htonl(ifs.int_std_net); 901 902 /* Use a minimum metric of one. Treat the interface metric 903 * (default 0) as an increment to the hop count of one. 904 * 905 * The metric obtained from the routing socket dump of 906 * interface addresses is wrong. It is not set by the 907 * SIOCSIFMETRIC ioctl. 908 */ 909 #ifdef SIOCGIFMETRIC 910 strncpy(ifr.ifr_name, ifs.int_name, sizeof(ifr.ifr_name)); 911 if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) { 912 DBGERR(1, "ioctl(SIOCGIFMETRIC)"); 913 ifs.int_metric = 0; 914 } else { 915 ifs.int_metric = ifr.ifr_metric; 916 } 917 #else 918 ifs.int_metric = ifam->ifam_metric; 919 #endif 920 if (ifs.int_metric > HOPCNT_INFINITY) { 921 ifs.int_metric = 0; 922 if (!(prev_complaints & COMP_BAD_METRIC) 923 && iff_up(ifs.int_if_flags)) { 924 complaints |= COMP_BAD_METRIC; 925 msglog("%s has a metric of %d", 926 ifs.int_name, ifs.int_metric); 927 } 928 } 929 930 /* See if this is a familiar interface. 931 * If so, stop worrying about it if it is the same. 932 * Start it over if it now is to somewhere else, as happens 933 * frequently with PPP and SLIP. 934 */ 935 ifp = ifwithname(ifs.int_name, ((ifs.int_state & IS_ALIAS) 936 ? ifs.int_addr 937 : 0)); 938 if (ifp != 0) { 939 ifp->int_state |= IS_CHECKED; 940 941 if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags) 942 & (IFF_BROADCAST 943 | IFF_LOOPBACK 944 | IFF_POINTOPOINT 945 | IFF_MULTICAST)) 946 || 0 != ((ifp->int_state ^ ifs.int_state) 947 & IS_ALIAS) 948 || ifp->int_addr != ifs.int_addr 949 || ifp->int_brdaddr != ifs.int_brdaddr 950 || ifp->int_dstaddr != ifs.int_dstaddr 951 || ifp->int_mask != ifs.int_mask 952 || ifp->int_metric != ifs.int_metric) { 953 /* Forget old information about 954 * a changed interface. 955 */ 956 trace_act("interface %s has changed", 957 ifp->int_name); 958 ifdel(ifp); 959 ifp = 0; 960 } 961 } 962 963 if (ifp != 0) { 964 /* The primary representative of an alias worries 965 * about how things are working. 966 */ 967 if (ifp->int_state & IS_ALIAS) 968 continue; 969 970 /* note interfaces that have been turned off 971 */ 972 if (!iff_up(ifs.int_if_flags)) { 973 if (iff_up(ifp->int_if_flags)) { 974 msglog("interface %s to %s turned off", 975 ifp->int_name, 976 naddr_ntoa(ifp->int_dstaddr)); 977 if_bad(ifp); 978 ifp->int_if_flags &= ~IFF_UP; 979 } else if (now.tv_sec>(ifp->int_data.ts 980 + CHECK_BAD_INTERVAL)) { 981 trace_act("interface %s has been off" 982 " %ld seconds; forget it", 983 ifp->int_name, 984 now.tv_sec-ifp->int_data.ts); 985 ifdel(ifp); 986 } 987 continue; 988 } 989 /* or that were off and are now ok */ 990 if (!iff_up(ifp->int_if_flags)) { 991 ifp->int_if_flags |= IFF_UP; 992 (void)if_ok(ifp, ""); 993 } 994 995 /* If it has been long enough, 996 * see if the interface is broken. 997 */ 998 if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL) 999 continue; 1000 1001 in = ifs.int_data.ipackets - ifp->int_data.ipackets; 1002 ierr = ifs.int_data.ierrors - ifp->int_data.ierrors; 1003 out = ifs.int_data.opackets - ifp->int_data.opackets; 1004 oerr = ifs.int_data.oerrors - ifp->int_data.oerrors; 1005 #ifdef sgi 1006 /* Through at least IRIX 6.2, PPP and SLIP 1007 * count packets dropped by the filters. 1008 * But FDDI rings stuck non-operational count 1009 * dropped packets as they wait for improvement. 1010 */ 1011 if (!(ifp->int_if_flags & IFF_POINTOPOINT)) 1012 oerr += (ifs.int_data.odrops 1013 - ifp->int_data.odrops); 1014 #endif 1015 /* If the interface just awoke, restart the counters. 1016 */ 1017 if (ifp->int_data.ts == 0) { 1018 ifp->int_data = ifs.int_data; 1019 continue; 1020 } 1021 ifp->int_data = ifs.int_data; 1022 1023 /* Withhold judgment when the short error 1024 * counters wrap or the interface is reset. 1025 */ 1026 if (ierr < 0 || in < 0 || oerr < 0 || out < 0) { 1027 LIM_SEC(ifinit_timer, 1028 now.tv_sec+CHECK_BAD_INTERVAL); 1029 continue; 1030 } 1031 1032 /* Withhold judgement when there is no traffic 1033 */ 1034 if (in == 0 && out == 0 && ierr == 0 && oerr == 0) 1035 continue; 1036 1037 /* It is bad if input or output is not working. 1038 * Require presistent problems before marking it dead. 1039 */ 1040 if ((in <= ierr && ierr > 0) 1041 || (out <= oerr && oerr > 0)) { 1042 if (!(ifp->int_state & IS_SICK)) { 1043 trace_act("interface %s to %s" 1044 " sick: in=%d ierr=%d" 1045 " out=%d oerr=%d", 1046 ifp->int_name, 1047 naddr_ntoa(ifp->int_dstaddr), 1048 in, ierr, out, oerr); 1049 if_sick(ifp); 1050 continue; 1051 } 1052 if (!(ifp->int_state & IS_BROKE)) { 1053 msglog("interface %s to %s broken:" 1054 " in=%d ierr=%d out=%d oerr=%d", 1055 ifp->int_name, 1056 naddr_ntoa(ifp->int_dstaddr), 1057 in, ierr, out, oerr); 1058 if_bad(ifp); 1059 } 1060 continue; 1061 } 1062 1063 /* otherwise, it is active and healthy 1064 */ 1065 ifp->int_act_time = now.tv_sec; 1066 (void)if_ok(ifp, ""); 1067 continue; 1068 } 1069 1070 /* This is a new interface. 1071 * If it is dead, forget it. 1072 */ 1073 if (!iff_up(ifs.int_if_flags)) 1074 continue; 1075 1076 /* If it duplicates an existing interface, 1077 * complain about it, mark the other one 1078 * duplicated, and forget this one. 1079 */ 1080 ifp = check_dup(ifs.int_addr,ifs.int_dstaddr,ifs.int_mask, 1081 ifs.int_if_flags); 1082 if (ifp != 0) { 1083 /* Ignore duplicates of itself, caused by having 1084 * IP aliases on the same network. 1085 */ 1086 if (!strcmp(ifp->int_name, ifs.int_name)) 1087 continue; 1088 1089 if (!(prev_complaints & COMP_DUP)) { 1090 complaints |= COMP_DUP; 1091 msglog("%s (%s%s%s) is duplicated by" 1092 " %s (%s%s%s)", 1093 ifs.int_name, 1094 addrname(ifs.int_addr,ifs.int_mask,1), 1095 ((ifs.int_if_flags & IFF_POINTOPOINT) 1096 ? "-->" : ""), 1097 ((ifs.int_if_flags & IFF_POINTOPOINT) 1098 ? naddr_ntoa(ifs.int_dstaddr) : ""), 1099 ifp->int_name, 1100 addrname(ifp->int_addr,ifp->int_mask,1), 1101 ((ifp->int_if_flags & IFF_POINTOPOINT) 1102 ? "-->" : ""), 1103 ((ifp->int_if_flags & IFF_POINTOPOINT) 1104 ? naddr_ntoa(ifp->int_dstaddr) : "")); 1105 } 1106 ifp->int_state |= IS_DUP; 1107 continue; 1108 } 1109 1110 if (0 == (ifs.int_if_flags & (IFF_POINTOPOINT | IFF_BROADCAST)) 1111 && !(ifs.int_state & IS_PASSIVE)) { 1112 trace_act("%s is neither broadcast, point-to-point," 1113 " nor loopback", 1114 ifs.int_name); 1115 if (!(ifs.int_state & IFF_MULTICAST)) 1116 ifs.int_state |= IS_NO_RDISC; 1117 } 1118 1119 1120 /* It is new and ok. Add it to the list of interfaces 1121 */ 1122 ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit ifp"); 1123 memcpy(ifp, &ifs, sizeof(*ifp)); 1124 get_parms(ifp); 1125 if_link(ifp); 1126 trace_if("Add", ifp); 1127 1128 /* Notice likely bad netmask. 1129 */ 1130 if (!(prev_complaints & COMP_NETMASK) 1131 && !(ifp->int_if_flags & IFF_POINTOPOINT) 1132 && ifp->int_addr != RIP_DEFAULT) { 1133 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 1134 if (ifp1->int_mask == ifp->int_mask) 1135 continue; 1136 if (ifp1->int_if_flags & IFF_POINTOPOINT) 1137 continue; 1138 if (ifp1->int_dstaddr == RIP_DEFAULT) 1139 continue; 1140 if (on_net(ifp->int_dstaddr, 1141 ifp1->int_net, ifp1->int_mask) 1142 || on_net(ifp1->int_dstaddr, 1143 ifp->int_net, ifp->int_mask)) { 1144 msglog("possible netmask problem" 1145 " between %s:%s and %s:%s", 1146 ifp->int_name, 1147 addrname(htonl(ifp->int_net), 1148 ifp->int_mask, 1), 1149 ifp1->int_name, 1150 addrname(htonl(ifp1->int_net), 1151 ifp1->int_mask, 1)); 1152 complaints |= COMP_NETMASK; 1153 } 1154 } 1155 } 1156 1157 if (!(ifp->int_state & IS_ALIAS)) { 1158 /* Count the # of directly connected networks. 1159 */ 1160 if (!(ifp->int_if_flags & IFF_LOOPBACK)) 1161 tot_interfaces++; 1162 if (!IS_RIP_OFF(ifp->int_state)) 1163 rip_interfaces++; 1164 1165 /* turn on router discovery and RIP If needed */ 1166 if_ok_rdisc(ifp); 1167 rip_on(ifp); 1168 } 1169 } 1170 1171 /* If we are multi-homed and have at least two interfaces 1172 * listening to RIP, then output by default. 1173 */ 1174 if (!supplier_set && rip_interfaces > 1) 1175 set_supplier(); 1176 1177 /* If we are multi-homed, optionally advertise a route to 1178 * our main address. 1179 */ 1180 if (advertise_mhome 1181 || (tot_interfaces > 1 1182 && mhome 1183 && (ifp = ifwithaddr(myaddr, 0, 0)) != 0 1184 && foundloopback)) { 1185 advertise_mhome = 1; 1186 rt = rtget(myaddr, HOST_MASK); 1187 if (rt != 0) { 1188 if (rt->rt_ifp != ifp 1189 || rt->rt_router != loopaddr) { 1190 rtdelete(rt); 1191 rt = 0; 1192 } else { 1193 loop_rts.rts_ifp = ifp; 1194 loop_rts.rts_metric = 0; 1195 loop_rts.rts_time = rt->rt_time; 1196 rtchange(rt, rt->rt_state | RS_MHOME, 1197 &loop_rts, 0); 1198 } 1199 } 1200 if (rt == 0) { 1201 loop_rts.rts_ifp = ifp; 1202 loop_rts.rts_metric = 0; 1203 rtadd(myaddr, HOST_MASK, RS_MHOME, &loop_rts); 1204 } 1205 } 1206 1207 for (ifp = ifnet; ifp != 0; ifp = ifp1) { 1208 ifp1 = ifp->int_next; /* because we may delete it */ 1209 1210 /* Forget any interfaces that have disappeared. 1211 */ 1212 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) { 1213 trace_act("interface %s has disappeared", 1214 ifp->int_name); 1215 ifdel(ifp); 1216 continue; 1217 } 1218 1219 if ((ifp->int_state & IS_BROKE) 1220 && !(ifp->int_state & IS_PASSIVE)) 1221 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 1222 1223 /* If we ever have a RIPv1 interface, assume we always will. 1224 * It might come back if it ever goes away. 1225 */ 1226 if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier) 1227 have_ripv1_out = 1; 1228 if (!(ifp->int_state & IS_NO_RIPV1_IN)) 1229 have_ripv1_in = 1; 1230 } 1231 1232 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 1233 /* Ensure there is always a network route for interfaces, 1234 * after any dead interfaces have been deleted, which 1235 * might affect routes for point-to-point links. 1236 */ 1237 if (!addrouteforif(ifp)) 1238 continue; 1239 1240 /* Add routes to the local end of point-to-point interfaces 1241 * using loopback. 1242 */ 1243 if ((ifp->int_if_flags & IFF_POINTOPOINT) 1244 && !(ifp->int_state & IS_REMOTE) 1245 && foundloopback) { 1246 /* Delete any routes to the network address through 1247 * foreign routers. Remove even static routes. 1248 */ 1249 del_static(ifp->int_addr, HOST_MASK, 0, 0); 1250 rt = rtget(ifp->int_addr, HOST_MASK); 1251 if (rt != 0 && rt->rt_router != loopaddr) { 1252 rtdelete(rt); 1253 rt = 0; 1254 } 1255 if (rt != 0) { 1256 if (!(rt->rt_state & RS_LOCAL) 1257 || rt->rt_metric > ifp->int_metric) { 1258 ifp1 = ifp; 1259 } else { 1260 ifp1 = rt->rt_ifp; 1261 } 1262 loop_rts.rts_ifp = ifp1; 1263 loop_rts.rts_metric = 0; 1264 loop_rts.rts_time = rt->rt_time; 1265 rtchange(rt, ((rt->rt_state & ~RS_NET_SYN) 1266 | (RS_IF|RS_LOCAL)), 1267 &loop_rts, 0); 1268 } else { 1269 loop_rts.rts_ifp = ifp; 1270 loop_rts.rts_metric = 0; 1271 rtadd(ifp->int_addr, HOST_MASK, 1272 (RS_IF | RS_LOCAL), &loop_rts); 1273 } 1274 } 1275 } 1276 1277 /* add the authority routes */ 1278 for (intnetp = intnets; intnetp!=0; intnetp = intnetp->intnet_next) { 1279 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask); 1280 if (rt != 0 1281 && !(rt->rt_state & RS_NO_NET_SYN) 1282 && !(rt->rt_state & RS_NET_INT)) { 1283 rtdelete(rt); 1284 rt = 0; 1285 } 1286 if (rt == 0) { 1287 loop_rts.rts_ifp = 0; 1288 loop_rts.rts_metric = intnetp->intnet_metric-1; 1289 rtadd(intnetp->intnet_addr, intnetp->intnet_mask, 1290 RS_NET_SYN | RS_NET_INT, &loop_rts); 1291 } 1292 } 1293 1294 prev_complaints = complaints; 1295 } 1296 1297 1298 static void 1299 check_net_syn(struct interface *ifp) 1300 { 1301 struct rt_entry *rt; 1302 static struct rt_spare new; 1303 1304 1305 /* Turn on the need to automatically synthesize a network route 1306 * for this interface only if we are running RIPv1 on some other 1307 * interface that is on a different class-A,B,or C network. 1308 */ 1309 if (have_ripv1_out || have_ripv1_in) { 1310 ifp->int_state |= IS_NEED_NET_SYN; 1311 rt = rtget(ifp->int_std_addr, ifp->int_std_mask); 1312 if (rt != 0 1313 && 0 == (rt->rt_state & RS_NO_NET_SYN) 1314 && (!(rt->rt_state & RS_NET_SYN) 1315 || rt->rt_metric > ifp->int_metric)) { 1316 rtdelete(rt); 1317 rt = 0; 1318 } 1319 if (rt == 0) { 1320 new.rts_ifp = ifp; 1321 new.rts_gate = ifp->int_addr; 1322 new.rts_router = ifp->int_addr; 1323 new.rts_metric = ifp->int_metric; 1324 rtadd(ifp->int_std_addr, ifp->int_std_mask, 1325 RS_NET_SYN, &new); 1326 } 1327 1328 } else { 1329 ifp->int_state &= ~IS_NEED_NET_SYN; 1330 1331 rt = rtget(ifp->int_std_addr, 1332 ifp->int_std_mask); 1333 if (rt != 0 1334 && (rt->rt_state & RS_NET_SYN) 1335 && rt->rt_ifp == ifp) 1336 rtbad_sub(rt); 1337 } 1338 } 1339 1340 1341 /* Add route for interface if not currently installed. 1342 * Create route to other end if a point-to-point link, 1343 * otherwise a route to this (sub)network. 1344 */ 1345 int /* 0=bad interface */ 1346 addrouteforif(struct interface *ifp) 1347 { 1348 struct rt_entry *rt; 1349 static struct rt_spare new; 1350 naddr dst; 1351 1352 1353 /* skip sick interfaces 1354 */ 1355 if (ifp->int_state & IS_BROKE) 1356 return 0; 1357 1358 /* If the interface on a subnet, then install a RIPv1 route to 1359 * the network as well (unless it is sick). 1360 */ 1361 if (ifp->int_state & IS_SUBNET) 1362 check_net_syn(ifp); 1363 1364 dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) 1365 ? ifp->int_dstaddr 1366 : htonl(ifp->int_net)); 1367 1368 new.rts_ifp = ifp; 1369 new.rts_router = ifp->int_addr; 1370 new.rts_gate = ifp->int_addr; 1371 new.rts_metric = ifp->int_metric; 1372 new.rts_time = now.tv_sec; 1373 1374 /* If we are going to send packets to the gateway, 1375 * it must be reachable using our physical interfaces 1376 */ 1377 if ((ifp->int_state & IS_REMOTE) 1378 && !(ifp->int_state & IS_EXTERNAL) 1379 && !check_remote(ifp)) 1380 return 0; 1381 1382 /* We are finished if the correct main interface route exists. 1383 * The right route must be for the right interface, not synthesized 1384 * from a subnet, be a "gateway" or not as appropriate, and so forth. 1385 */ 1386 del_static(dst, ifp->int_mask, 0, 0); 1387 rt = rtget(dst, ifp->int_mask); 1388 if (rt != 0) { 1389 if ((rt->rt_ifp != ifp 1390 || rt->rt_router != ifp->int_addr) 1391 && (!(ifp->int_state & IS_DUP) 1392 || rt->rt_ifp == 0 1393 || (rt->rt_ifp->int_state & IS_BROKE))) { 1394 rtdelete(rt); 1395 rt = 0; 1396 } else { 1397 rtchange(rt, ((rt->rt_state | RS_IF) 1398 & ~(RS_NET_SYN | RS_LOCAL)), 1399 &new, 0); 1400 } 1401 } 1402 if (rt == 0) { 1403 if (ifp->int_transitions++ > 0) 1404 trace_act("re-install interface %s", 1405 ifp->int_name); 1406 1407 rtadd(dst, ifp->int_mask, RS_IF, &new); 1408 } 1409 1410 return 1; 1411 } 1412