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