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