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