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