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