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