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 acknowledgement: 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 34 #if !defined(lint) && !defined(sgi) && !defined(__NetBSD__) 35 static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; 36 #elif defined(__NetBSD__) 37 static char rcsid[] = "$NetBSD$"; 38 #endif 39 #ident "$Revision: 1.17 $" 40 41 #include "defs.h" 42 #include "pathnames.h" 43 44 struct interface *ifnet; /* all interfaces */ 45 int tot_interfaces; /* # of remote and local interfaces */ 46 int rip_interfaces; /* # of interfaces doing RIP */ 47 int foundloopback; /* valid flag for loopaddr */ 48 naddr loopaddr; /* our address on loopback */ 49 50 struct timeval ifinit_timer; 51 52 int have_ripv1_out; /* have a RIPv1 interface */ 53 int have_ripv1_in; 54 55 56 /* Find the interface with an address 57 */ 58 struct interface * 59 ifwithaddr(naddr addr, 60 int bcast, /* notice IFF_BROADCAST address */ 61 int remote) /* include IS_REMOTE interfaces */ 62 { 63 struct interface *ifp, *possible = 0; 64 65 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 66 if (ifp->int_addr == addr 67 || ((ifp->int_if_flags & IFF_BROADCAST) 68 && ifp->int_brdaddr == addr 69 && bcast)) { 70 if ((ifp->int_state & IS_REMOTE) && !remote) 71 continue; 72 73 if (!(ifp->int_state & IS_BROKE) 74 && !(ifp->int_state & IS_PASSIVE)) 75 return ifp; 76 77 possible = ifp; 78 } 79 } 80 81 return possible; 82 } 83 84 85 /* find the interface with a name 86 */ 87 struct interface * 88 ifwithname(char *name, /* "ec0" or whatever */ 89 naddr addr) /* 0 or network address */ 90 { 91 struct interface *ifp; 92 93 94 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) { 95 if (!strcmp(ifp->int_name, name) 96 && (ifp->int_addr == addr 97 || (addr == 0 && !(ifp->int_state & IS_ALIAS)))) 98 return ifp; 99 } 100 return 0; 101 } 102 103 104 struct interface * 105 ifwithindex(u_short index) 106 { 107 struct interface *ifp; 108 109 110 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) { 111 if (ifp->int_index == index) 112 return ifp; 113 } 114 return 0; 115 } 116 117 118 /* Find an interface from which the specified address 119 * should have come from. Used for figuring out which 120 * interface a packet came in on -- for tracing. 121 */ 122 struct interface * 123 iflookup(naddr addr) 124 { 125 struct interface *ifp, *maybe; 126 127 maybe = 0; 128 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 129 if (ifp->int_if_flags & IFF_POINTOPOINT) { 130 if (ifp->int_dstaddr == addr) 131 /* finished with a match */ 132 return ifp; 133 134 } else { 135 /* finished with an exact match */ 136 if (ifp->int_addr == addr) 137 return ifp; 138 if ((ifp->int_if_flags & IFF_BROADCAST) 139 && ifp->int_brdaddr == addr) 140 return ifp; 141 142 /* Look for the longest approximate match. 143 */ 144 if (on_net(addr, ifp->int_net, ifp->int_mask) 145 && (maybe == 0 146 || ifp->int_mask > maybe->int_mask)) 147 maybe = ifp; 148 } 149 } 150 151 return maybe; 152 } 153 154 155 /* Return the classical netmask for an IP address. 156 */ 157 naddr 158 std_mask(naddr addr) /* in network order */ 159 { 160 NTOHL(addr); /* was a host, not a network */ 161 162 if (addr == 0) /* default route has mask 0 */ 163 return 0; 164 if (IN_CLASSA(addr)) 165 return IN_CLASSA_NET; 166 if (IN_CLASSB(addr)) 167 return IN_CLASSB_NET; 168 return IN_CLASSC_NET; 169 } 170 171 172 /* Find the netmask that would be inferred by RIPv1 listeners 173 * on the given interface for a given network. 174 * If no interface is specified, look for the best fitting interface. 175 */ 176 naddr 177 ripv1_mask_net(naddr addr, /* in network byte order */ 178 struct interface *ifp) /* as seen on this interface */ 179 { 180 naddr mask = 0; 181 182 if (addr == 0) /* default always has 0 mask */ 183 return mask; 184 185 if (ifp != 0) { 186 /* If the target network is that of the associated interface 187 * on which it arrived, then use the netmask of the interface. 188 */ 189 if (on_net(addr, ifp->int_net, ifp->int_std_mask)) 190 mask = ifp->int_ripv1_mask; 191 192 } else { 193 /* Examine all interfaces, and if it the target seems 194 * to have the same network number of an interface, use the 195 * netmask of that interface. If there is more than one 196 * such interface, prefer the interface with the longest 197 * match. 198 */ 199 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 200 if (on_net(addr, ifp->int_std_net, ifp->int_std_mask) 201 && ifp->int_ripv1_mask > mask) 202 mask = ifp->int_ripv1_mask; 203 } 204 } 205 206 /* Otherwise, make the classic A/B/C guess. 207 */ 208 if (mask == 0) 209 mask = std_mask(addr); 210 211 return mask; 212 } 213 214 215 naddr 216 ripv1_mask_host(naddr addr, /* in network byte order */ 217 struct interface *ifp) /* as seen on this interface */ 218 { 219 naddr mask = ripv1_mask_net(addr, ifp); 220 221 222 /* If the computed netmask does not mask the address, 223 * then assume it is a host address 224 */ 225 if ((ntohl(addr) & ~mask) != 0) 226 mask = HOST_MASK; 227 return mask; 228 } 229 230 231 /* See if a IP address looks reasonable as a destination 232 */ 233 int /* 0=bad */ 234 check_dst(naddr addr) 235 { 236 NTOHL(addr); 237 238 if (IN_CLASSA(addr)) { 239 if (addr == 0) 240 return 1; /* default */ 241 242 addr >>= IN_CLASSA_NSHIFT; 243 return (addr != 0 && addr != IN_LOOPBACKNET); 244 } 245 246 return (IN_CLASSB(addr) || IN_CLASSC(addr)); 247 } 248 249 250 /* Delete an interface. 251 */ 252 static void 253 ifdel(struct interface *ifp) 254 { 255 struct ip_mreq m; 256 struct interface *ifp1; 257 258 259 trace_if("Del", ifp); 260 261 ifp->int_state |= IS_BROKE; 262 263 /* unlink the interface 264 */ 265 if (rip_sock_mcast == ifp) 266 rip_sock_mcast = 0; 267 if (ifp->int_next != 0) 268 ifp->int_next->int_prev = ifp->int_prev; 269 if (ifp->int_prev != 0) 270 ifp->int_prev->int_next = ifp->int_next; 271 else 272 ifnet = ifp->int_next; 273 274 if (!(ifp->int_state & IS_ALIAS)) { 275 /* delete aliases 276 */ 277 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 278 if (ifp1 != ifp 279 && !strcmp(ifp->int_name, ifp1->int_name)) 280 ifdel(ifp1); 281 } 282 283 if ((ifp->int_if_flags & IFF_MULTICAST) 284 #ifdef MCAST_PPP_BUG 285 && !(ifp->int_if_flags & IFF_POINTOPOINT) 286 #endif 287 && rip_sock >= 0) { 288 m.imr_multiaddr.s_addr = htonl(INADDR_RIP_GROUP); 289 m.imr_interface.s_addr = ((ifp->int_if_flags 290 & IFF_POINTOPOINT) 291 ? ifp->int_dstaddr 292 : ifp->int_addr); 293 if (setsockopt(rip_sock,IPPROTO_IP,IP_DROP_MEMBERSHIP, 294 &m, sizeof(m)) < 0 295 && errno != EADDRNOTAVAIL 296 && !TRACEACTIONS) 297 LOGERR("setsockopt(IP_DROP_MEMBERSHIP RIP)"); 298 } 299 if (ifp->int_rip_sock >= 0) { 300 (void)close(ifp->int_rip_sock); 301 ifp->int_rip_sock = -1; 302 fix_select(); 303 } 304 305 tot_interfaces--; 306 if (!IS_RIP_OFF(ifp->int_state)) 307 rip_interfaces--; 308 309 /* Zap all routes associated with this interface. 310 * Assume routes just using gateways beyond this interface will 311 * timeout naturally, and have probably already died. 312 */ 313 (void)rn_walktree(rhead, walk_bad, 0); 314 315 set_rdisc_mg(ifp, 0); 316 if_bad_rdisc(ifp); 317 } 318 319 free(ifp); 320 } 321 322 323 /* Mark an interface ill. 324 */ 325 void 326 if_sick(struct interface *ifp) 327 { 328 if (0 == (ifp->int_state & (IS_SICK | IS_BROKE))) { 329 ifp->int_state |= IS_SICK; 330 trace_if("Chg", ifp); 331 332 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 333 } 334 } 335 336 337 /* Mark an interface dead. 338 */ 339 void 340 if_bad(struct interface *ifp) 341 { 342 struct interface *ifp1; 343 344 345 if (ifp->int_state & IS_BROKE) 346 return; 347 348 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 349 350 ifp->int_state |= (IS_BROKE | IS_SICK); 351 ifp->int_state &= ~(IS_RIP_QUERIED | IS_ACTIVE); 352 ifp->int_data.ts = 0; 353 354 trace_if("Chg", ifp); 355 356 if (!(ifp->int_state & IS_ALIAS)) { 357 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 358 if (ifp1 != ifp 359 && !strcmp(ifp->int_name, ifp1->int_name)) 360 if_bad(ifp1); 361 } 362 (void)rn_walktree(rhead, walk_bad, 0); 363 if_bad_rdisc(ifp); 364 } 365 } 366 367 368 /* Mark an interface alive 369 */ 370 int /* 1=it was dead */ 371 if_ok(struct interface *ifp, 372 char *type) 373 { 374 struct interface *ifp1; 375 376 377 if (!(ifp->int_state & IS_BROKE)) { 378 if (ifp->int_state & IS_SICK) { 379 trace_act("%sinterface %s to %s working better\n", 380 type, 381 ifp->int_name, naddr_ntoa(ifp->int_addr)); 382 ifp->int_state &= ~IS_SICK; 383 } 384 return 0; 385 } 386 387 msglog("%sinterface %s to %s restored", 388 type, ifp->int_name, naddr_ntoa(ifp->int_addr)); 389 ifp->int_state &= ~(IS_BROKE | IS_SICK); 390 ifp->int_data.ts = 0; 391 392 if (!(ifp->int_state & IS_ALIAS)) { 393 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 394 if (ifp1 != ifp 395 && !strcmp(ifp->int_name, ifp1->int_name)) 396 if_ok(ifp1, type); 397 } 398 if_ok_rdisc(ifp); 399 } 400 return 1; 401 } 402 403 404 /* disassemble routing message 405 */ 406 void 407 rt_xaddrs(struct rt_addrinfo *info, 408 struct sockaddr *sa, 409 struct sockaddr *lim, 410 int addrs) 411 { 412 int i; 413 #ifdef _HAVE_SA_LEN 414 static struct sockaddr sa_zero; 415 #endif 416 #ifdef sgi 417 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) \ 418 : sizeof(__uint64_t)) 419 #else 420 #define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \ 421 : sizeof(long)) 422 #endif 423 424 425 bzero(info, sizeof(*info)); 426 info->rti_addrs = addrs; 427 for (i = 0; i < RTAX_MAX && sa < lim; i++) { 428 if ((addrs & (1 << i)) == 0) 429 continue; 430 #ifdef _HAVE_SA_LEN 431 info->rti_info[i] = (sa->sa_len != 0) ? sa : &sa_zero; 432 sa = (struct sockaddr *)((char*)(sa) 433 + ROUNDUP(sa->sa_len)); 434 #else 435 info->rti_info[i] = sa; 436 sa = (struct sockaddr *)((char*)(sa) 437 + ROUNDUP(_FAKE_SA_LEN_DST(sa))); 438 #endif 439 } 440 } 441 442 443 /* Find the network interfaces which have configured themselves. 444 * This must be done regularly, if only for extra addresses 445 * that come and go on interfaces. 446 */ 447 void 448 ifinit(void) 449 { 450 static char *sysctl_buf; 451 static size_t sysctl_buf_size = 0; 452 uint complaints = 0; 453 static u_int prev_complaints = 0; 454 # define COMP_NOT_INET 0x001 455 # define COMP_WIERD 0x002 456 # define COMP_NOADDR 0x004 457 # define COMP_BADADDR 0x008 458 # define COMP_NODST 0x010 459 # define COMP_NOBADR 0x020 460 # define COMP_NOMASK 0x040 461 # define COMP_DUP 0x080 462 # define COMP_BAD_METRIC 0x100 463 # define COMP_NETMASK 0x200 464 465 struct interface ifs, ifs0, *ifp, *ifp1; 466 struct rt_entry *rt; 467 size_t needed; 468 int mib[6]; 469 struct if_msghdr *ifm; 470 struct ifa_msghdr *ifam, *ifam_lim, *ifam2; 471 struct sockaddr_dl *sdl; 472 int in, ierr, out, oerr; 473 struct intnet *intnetp; 474 struct rt_addrinfo info; 475 #ifdef SIOCGIFMETRIC 476 struct ifreq ifr; 477 #endif 478 479 480 ifinit_timer.tv_sec = now.tv_sec + (supplier 481 ? CHECK_ACT_INTERVAL 482 : CHECK_QUIET_INTERVAL); 483 484 /* mark all interfaces so we can get rid of thost that disappear */ 485 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) 486 ifp->int_state &= ~(IS_CHECKED | IS_DUP); 487 488 /* Fetch the interface list, without too many system calls 489 * since we do it repeatedly. 490 */ 491 mib[0] = CTL_NET; 492 mib[1] = PF_ROUTE; 493 mib[2] = 0; 494 mib[3] = AF_INET; 495 mib[4] = NET_RT_IFLIST; 496 mib[5] = 0; 497 for (;;) { 498 if ((needed = sysctl_buf_size) != 0) { 499 if (sysctl(mib, 6, sysctl_buf,&needed, 0, 0) >= 0) 500 break; 501 if (errno != ENOMEM && errno != EFAULT) 502 BADERR(1, "ifinit: get interface table"); 503 free(sysctl_buf); 504 needed = 0; 505 } 506 if (sysctl(mib, 6, 0, &needed, 0, 0) < 0) 507 BADERR(1,"ifinit: route-sysctl-estimate"); 508 sysctl_buf = rtmalloc(sysctl_buf_size = needed, "ifinit"); 509 } 510 511 ifam_lim = (struct ifa_msghdr *)(sysctl_buf + needed); 512 for (ifam = (struct ifa_msghdr *)sysctl_buf; 513 ifam < ifam_lim; 514 ifam = ifam2) { 515 516 ifam2 = (struct ifa_msghdr*)((char*)ifam + ifam->ifam_msglen); 517 518 if (ifam->ifam_type == RTM_IFINFO) { 519 ifm = (struct if_msghdr *)ifam; 520 /* make prototype structure for the IP aliases 521 */ 522 bzero(&ifs0, sizeof(ifs0)); 523 ifs0.int_rip_sock = -1; 524 ifs0.int_index = ifm->ifm_index; 525 ifs0.int_if_flags = ifm->ifm_flags; 526 ifs0.int_state = IS_CHECKED; 527 ifs0.int_act_time = now.tv_sec; 528 ifs0.int_data.ts = now.tv_sec; 529 ifs0.int_data.ipackets = ifm->ifm_data.ifi_ipackets; 530 ifs0.int_data.ierrors = ifm->ifm_data.ifi_ierrors; 531 ifs0.int_data.opackets = ifm->ifm_data.ifi_opackets; 532 ifs0.int_data.oerrors = ifm->ifm_data.ifi_oerrors; 533 #ifdef sgi 534 ifs0.int_data.odrops = ifm->ifm_data.ifi_odrops; 535 #endif 536 sdl = (struct sockaddr_dl *)(ifm + 1); 537 sdl->sdl_data[sdl->sdl_nlen] = 0; 538 continue; 539 } 540 if (ifam->ifam_type != RTM_NEWADDR) { 541 logbad(1,"ifinit: out of sync"); 542 continue; 543 } 544 545 rt_xaddrs(&info, (struct sockaddr *)(ifam+1), 546 (struct sockaddr *)ifam2, 547 ifam->ifam_addrs); 548 549 if (INFO_IFA(&info) == 0) { 550 if (iff_alive(ifs.int_if_flags)) { 551 if (!(prev_complaints & COMP_NOADDR)) 552 msglog("%s has no address", 553 sdl->sdl_data); 554 complaints |= COMP_NOADDR; 555 } 556 continue; 557 } 558 if (INFO_IFA(&info)->sa_family != AF_INET) { 559 if (iff_alive(ifs.int_if_flags)) { 560 if (!(prev_complaints & COMP_NOT_INET)) 561 trace_act("%s: not AF_INET\n", 562 sdl->sdl_data); 563 complaints |= COMP_NOT_INET; 564 } 565 continue; 566 } 567 568 bcopy(&ifs0, &ifs, sizeof(ifs0)); 569 ifs0.int_state |= IS_ALIAS; /* next will be an alias */ 570 571 ifs.int_addr = S_ADDR(INFO_IFA(&info)); 572 573 if (ntohl(ifs.int_addr)>>24 == 0 574 || ntohl(ifs.int_addr)>>24 == 0xff) { 575 if (iff_alive(ifs.int_if_flags)) { 576 if (!(prev_complaints & COMP_BADADDR)) 577 msglog("%s has a bad address", 578 sdl->sdl_data); 579 complaints |= COMP_BADADDR; 580 } 581 continue; 582 } 583 584 if (ifs.int_if_flags & IFF_BROADCAST) { 585 if (INFO_MASK(&info) == 0) { 586 if (iff_alive(ifs.int_if_flags)) { 587 if (!(prev_complaints & COMP_NOMASK)) 588 msglog("%s has no netmask", 589 sdl->sdl_data); 590 complaints |= COMP_NOMASK; 591 } 592 continue; 593 } 594 ifs.int_dstaddr = ifs.int_addr; 595 ifs.int_mask = ntohl(S_ADDR(INFO_MASK(&info))); 596 ifs.int_ripv1_mask = ifs.int_mask; 597 ifs.int_net = ntohl(ifs.int_addr) & ifs.int_mask; 598 ifs.int_std_mask = std_mask(ifs.int_addr); 599 if (ifs.int_mask != ifs.int_std_mask) 600 ifs.int_state |= IS_SUBNET; 601 602 if (INFO_BRD(&info) == 0) { 603 if (iff_alive(ifs.int_if_flags)) { 604 if (!(prev_complaints & COMP_NOBADR)) 605 msglog("%s has no" 606 " broadcast address", 607 sdl->sdl_data); 608 complaints |= COMP_NOBADR; 609 } 610 continue; 611 } 612 ifs.int_brdaddr = S_ADDR(INFO_BRD(&info)); 613 614 } else if (ifs.int_if_flags & IFF_POINTOPOINT) { 615 if (INFO_BRD(&info) == 0 616 || INFO_BRD(&info)->sa_family != AF_INET) { 617 if (iff_alive(ifs.int_if_flags)) { 618 if (!(prev_complaints & COMP_NODST)) 619 msglog("%s has a bad" 620 " destination address", 621 sdl->sdl_data); 622 complaints |= COMP_NODST; 623 } 624 continue; 625 } 626 ifs.int_dstaddr = S_ADDR(INFO_BRD(&info)); 627 if (ntohl(ifs.int_dstaddr)>>24 == 0 628 || ntohl(ifs.int_dstaddr)>>24 == 0xff) { 629 if (iff_alive(ifs.int_if_flags)) { 630 if (!(prev_complaints & COMP_NODST)) 631 msglog("%s has a bad" 632 " destination address", 633 sdl->sdl_data); 634 complaints |= COMP_NODST; 635 } 636 continue; 637 } 638 ifs.int_mask = HOST_MASK; 639 ifs.int_ripv1_mask = ntohl(S_ADDR(INFO_MASK(&info))); 640 ifs.int_net = ntohl(ifs.int_dstaddr); 641 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 642 643 } else if (ifs.int_if_flags & IFF_LOOPBACK) { 644 ifs.int_state |= IS_PASSIVE | IS_NO_RIP; 645 ifs.int_dstaddr = ifs.int_addr; 646 ifs.int_mask = HOST_MASK; 647 ifs.int_ripv1_mask = HOST_MASK; 648 ifs.int_net = ntohl(ifs.int_dstaddr); 649 ifs.int_std_mask = std_mask(ifs.int_dstaddr); 650 if (!foundloopback) { 651 foundloopback = 1; 652 loopaddr = ifs.int_addr; 653 } 654 655 } else { 656 if (!(prev_complaints & COMP_WIERD)) 657 trace_act("%s is neither broadcast" 658 " nor point-to-point nor loopback", 659 sdl->sdl_data); 660 complaints |= COMP_WIERD; 661 continue; 662 } 663 ifs.int_std_net = ifs.int_net & ifs.int_std_mask; 664 ifs.int_std_addr = htonl(ifs.int_std_net); 665 666 /* Use a minimum metric of one. Treat the interface metric 667 * (default 0) as an increment to the hop count of one. 668 * 669 * The metric obtained from the routing socket dump of 670 * interface addresses is wrong. It is not set by the 671 * SIOCSIFMETRIC ioctl. 672 */ 673 #ifdef SIOCGIFMETRIC 674 strncpy(ifr.ifr_name, sdl->sdl_data, sizeof(ifr.ifr_name)); 675 if (ioctl(rt_sock, SIOCGIFMETRIC, &ifr) < 0) { 676 DBGERR(1, "ioctl(SIOCGIFMETRIC)"); 677 ifs.int_metric = 0; 678 } else { 679 ifs.int_metric = ifr.ifr_metric; 680 } 681 #else 682 ifs.int_metric = ifam->ifam_metric; 683 #endif 684 if (ifs.int_metric > HOPCNT_INFINITY) { 685 ifs.int_metric = 0; 686 if (!(prev_complaints & COMP_BAD_METRIC) 687 && iff_alive(ifs.int_if_flags)) { 688 complaints |= COMP_BAD_METRIC; 689 msglog("%s has a metric of %d", 690 sdl->sdl_data, ifs.int_metric); 691 } 692 } 693 694 /* See if this is a familiar interface. 695 * If so, stop worrying about it if it is the same. 696 * Start it over if it now is to somewhere else, as happens 697 * frequently with PPP and SLIP. 698 */ 699 ifp = ifwithname(sdl->sdl_data, ((ifs.int_state & IS_ALIAS) 700 ? ifs.int_addr 701 : 0)); 702 if (ifp != 0) { 703 ifp->int_state |= IS_CHECKED; 704 705 if (0 != ((ifp->int_if_flags ^ ifs.int_if_flags) 706 & (IFF_BROADCAST 707 | IFF_LOOPBACK 708 | IFF_POINTOPOINT 709 | IFF_MULTICAST)) 710 || 0 != ((ifp->int_state ^ ifs.int_state) 711 & IS_ALIAS) 712 || ifp->int_addr != ifs.int_addr 713 || ifp->int_brdaddr != ifs.int_brdaddr 714 || ifp->int_dstaddr != ifs.int_dstaddr 715 || ifp->int_mask != ifs.int_mask 716 || ifp->int_metric != ifs.int_metric) { 717 /* Forget old information about 718 * a changed interface. 719 */ 720 trace_act("interface %s has changed\n", 721 ifp->int_name); 722 ifdel(ifp); 723 ifp = 0; 724 } 725 } 726 727 if (ifp != 0) { 728 /* The primary representative of an alias worries 729 * about how things are working. 730 */ 731 if (ifp->int_state & IS_ALIAS) 732 continue; 733 734 /* note interfaces that have been turned off 735 */ 736 if (!iff_alive(ifs.int_if_flags)) { 737 if (iff_alive(ifp->int_if_flags)) { 738 msglog("interface %s to %s turned off", 739 ifp->int_name, 740 naddr_ntoa(ifp->int_addr)); 741 if_bad(ifp); 742 ifp->int_if_flags &= ~IFF_UP_RUNNING; 743 } 744 continue; 745 } 746 /* or that were off and are now ok */ 747 if (!iff_alive(ifp->int_if_flags)) { 748 ifp->int_if_flags |= IFF_UP_RUNNING; 749 (void)if_ok(ifp, ""); 750 } 751 752 /* If it has been long enough, 753 * see if the interface is broken. 754 */ 755 if (now.tv_sec < ifp->int_data.ts+CHECK_BAD_INTERVAL) 756 continue; 757 758 in = ifs.int_data.ipackets - ifp->int_data.ipackets; 759 ierr = ifs.int_data.ierrors - ifp->int_data.ierrors; 760 out = ifs.int_data.opackets - ifp->int_data.opackets; 761 oerr = ifs.int_data.oerrors - ifp->int_data.oerrors; 762 #ifdef sgi 763 /* Through at least IRIX 6.2, PPP and SLIP 764 * count packets dropped by the filters. 765 * But FDDI rings stuck non-operational count 766 * dropped packets as they wait for improvement. 767 */ 768 if (!(ifp->int_if_flags & IFF_POINTOPOINT)) 769 oerr += (ifs.int_data.odrops 770 - ifp->int_data.odrops); 771 #endif 772 /* If the interface just awoke, restart the counters. 773 */ 774 if (ifp->int_data.ts == 0) { 775 ifp->int_data = ifs.int_data; 776 continue; 777 } 778 ifp->int_data = ifs.int_data; 779 780 /* Withhold judgement when the short error 781 * counters wrap or the interface is reset. 782 */ 783 if (ierr < 0 || in < 0 || oerr < 0 || out < 0) { 784 LIM_SEC(ifinit_timer, 785 now.tv_sec+CHECK_BAD_INTERVAL); 786 continue; 787 } 788 789 /* Withhold judgement when there is no traffic 790 */ 791 if (in == 0 && out == 0 && ierr == 0 && oerr == 0) 792 continue; 793 794 /* It is bad if input or output is not working. 795 * Require presistent problems before marking it dead. 796 */ 797 if ((in <= ierr && ierr > 0) 798 || (out <= oerr && oerr > 0)) { 799 if (!(ifp->int_state & IS_SICK)) { 800 trace_act("interface %s to %s" 801 " sick: in=%d ierr=%d" 802 " out=%d oerr=%d\n", 803 ifp->int_name, 804 naddr_ntoa(ifp->int_addr), 805 in, ierr, out, oerr); 806 if_sick(ifp); 807 continue; 808 } 809 if (!(ifp->int_state & IS_BROKE)) { 810 msglog("interface %s to %s bad:" 811 " in=%d ierr=%d out=%d oerr=%d", 812 ifp->int_name, 813 naddr_ntoa(ifp->int_addr), 814 in, ierr, out, oerr); 815 if_bad(ifp); 816 } 817 continue; 818 } 819 820 /* otherwise, it is active and healthy 821 */ 822 ifp->int_act_time = now.tv_sec; 823 (void)if_ok(ifp, ""); 824 continue; 825 } 826 827 /* This is a new interface. 828 * If it is dead, forget it. 829 */ 830 if (!iff_alive(ifs.int_if_flags)) 831 continue; 832 833 /* See if it duplicates an existing interface. 834 */ 835 for (ifp = ifnet; 0 != ifp; ifp = ifp->int_next) { 836 if (ifp->int_mask != ifs.int_mask) 837 continue; 838 if (((ifp->int_addr != ifs.int_addr 839 && ifs.int_mask != HOST_MASK) 840 || (ifp->int_dstaddr != ifs.int_dstaddr 841 && ifs.int_mask == HOST_MASK))) 842 continue; 843 if (!iff_alive(ifp->int_if_flags)) 844 continue; 845 /* Let one of our real interfaces be marked 846 * passive. 847 */ 848 if ((ifp->int_state & IS_PASSIVE) 849 && !(ifp->int_state & IS_EXTERNAL)) 850 continue; 851 852 /* It does duplicate an existing interface, 853 * so complain about it, mark the other one 854 * duplicated, and for get this one. 855 */ 856 if (!(prev_complaints & COMP_DUP)) { 857 complaints |= COMP_DUP; 858 msglog("%s is duplicated by %s at %s", 859 sdl->sdl_data, ifp->int_name, 860 naddr_ntoa(ifp->int_addr)); 861 } 862 ifp->int_state |= IS_DUP; 863 break; 864 } 865 if (ifp != 0) 866 continue; 867 868 /* It is new and ok. So make it real 869 */ 870 strncpy(ifs.int_name, sdl->sdl_data, 871 MIN(sizeof(ifs.int_name)-1, sdl->sdl_nlen)); 872 get_parms(&ifs); 873 874 /* Add it to the list of interfaces 875 */ 876 ifp = (struct interface *)rtmalloc(sizeof(*ifp), "ifinit"); 877 bcopy(&ifs, ifp, sizeof(*ifp)); 878 if (ifnet != 0) { 879 ifp->int_next = ifnet; 880 ifnet->int_prev = ifp; 881 } 882 ifnet = ifp; 883 trace_if("Add", ifp); 884 885 /* Notice likely bad netmask. 886 */ 887 if (!(prev_complaints & COMP_NETMASK) 888 && !(ifp->int_if_flags & IFF_POINTOPOINT)) { 889 for (ifp1 = ifnet; 0 != ifp1; ifp1 = ifp1->int_next) { 890 if (ifp1->int_mask == ifp->int_mask) 891 continue; 892 if (ifp1->int_if_flags & IFF_POINTOPOINT) 893 continue; 894 if (on_net(ifp->int_addr, 895 ifp1->int_net, ifp1->int_mask) 896 || on_net(ifp1->int_addr, 897 ifp->int_net, ifp->int_mask)) { 898 msglog("possible netmask problem" 899 " betwen %s:%s and %s:%s", 900 ifp->int_name, 901 addrname(htonl(ifp->int_net), 902 ifp->int_mask, 1), 903 ifp1->int_name, 904 addrname(htonl(ifp1->int_net), 905 ifp1->int_mask, 1)); 906 complaints |= COMP_NETMASK; 907 } 908 } 909 } 910 911 /* Count the # of directly connected networks. 912 */ 913 if (!(ifp->int_state & IS_ALIAS)) { 914 if (!(ifp->int_if_flags & IFF_LOOPBACK)) 915 tot_interfaces++; 916 if (!IS_RIP_OFF(ifp->int_state)) 917 rip_interfaces++; 918 } 919 920 if_ok_rdisc(ifp); 921 rip_on(ifp); 922 } 923 924 /* If we are multi-homed and have at least one interface 925 * listening to RIP, then output by default. 926 */ 927 if (!supplier_set && rip_interfaces > 1) 928 set_supplier(); 929 930 /* If we are multi-homed, optionally advertise a route to 931 * our main address. 932 */ 933 if (advertise_mhome 934 || (tot_interfaces > 1 935 && mhome 936 && (ifp = ifwithaddr(myaddr, 0, 0)) != 0 937 && foundloopback)) { 938 advertise_mhome = 1; 939 rt = rtget(myaddr, HOST_MASK); 940 if (rt != 0) { 941 if (rt->rt_ifp != ifp 942 || rt->rt_router != loopaddr) { 943 rtdelete(rt); 944 rt = 0; 945 } else { 946 rtchange(rt, rt->rt_state | RS_MHOME, 947 loopaddr, loopaddr, 948 0, 0, ifp, rt->rt_time, 0); 949 } 950 } 951 if (rt == 0) 952 rtadd(myaddr, HOST_MASK, loopaddr, loopaddr, 953 0, 0, RS_MHOME, ifp); 954 } 955 956 for (ifp = ifnet; ifp != 0; ifp = ifp1) { 957 ifp1 = ifp->int_next; /* because we may delete it */ 958 959 /* Forget any interfaces that have disappeared. 960 */ 961 if (!(ifp->int_state & (IS_CHECKED | IS_REMOTE))) { 962 trace_act("interface %s has disappeared\n", 963 ifp->int_name); 964 ifdel(ifp); 965 continue; 966 } 967 968 if ((ifp->int_state & IS_BROKE) 969 && !(ifp->int_state & IS_PASSIVE)) 970 LIM_SEC(ifinit_timer, now.tv_sec+CHECK_BAD_INTERVAL); 971 972 /* If we ever have a RIPv1 interface, assume we always will. 973 * It might come back if it ever goes away. 974 */ 975 if (!(ifp->int_state & IS_NO_RIPV1_OUT) && supplier) 976 have_ripv1_out = 1; 977 if (!(ifp->int_state & IS_NO_RIPV1_IN)) 978 have_ripv1_in = 1; 979 } 980 981 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 982 /* Ensure there is always a network route for interfaces, 983 * after any dead interfaces have been deleted, which 984 * might affect routes for point-to-point links. 985 */ 986 addrouteforif(ifp); 987 988 /* Add routes to the local end of point-to-point interfaces 989 * using loopback. 990 */ 991 if ((ifp->int_if_flags & IFF_POINTOPOINT) 992 && !(ifp->int_state & IS_REMOTE) 993 && foundloopback) { 994 /* Delete any routes to the network address through 995 * foreign routers. Remove even static routes. 996 */ 997 del_static(ifp->int_addr, HOST_MASK, 0); 998 rt = rtget(ifp->int_addr, HOST_MASK); 999 if (rt != 0 && rt->rt_router != loopaddr) { 1000 rtdelete(rt); 1001 rt = 0; 1002 } 1003 if (rt != 0) { 1004 if (!(rt->rt_state & RS_LOCAL) 1005 || rt->rt_metric > ifp->int_metric) { 1006 ifp1 = ifp; 1007 } else { 1008 ifp1 = rt->rt_ifp; 1009 } 1010 rtchange(rt,((rt->rt_state & ~RS_NET_SYN) 1011 | (RS_IF|RS_LOCAL)), 1012 loopaddr, loopaddr, 1013 0, 0, ifp1, rt->rt_time, 0); 1014 } else { 1015 rtadd(ifp->int_addr, HOST_MASK, 1016 loopaddr, loopaddr, 1017 0, 0, (RS_IF | RS_LOCAL), ifp); 1018 } 1019 } 1020 } 1021 1022 /* add the authority routes */ 1023 for (intnetp = intnets; intnetp!=0; intnetp = intnetp->intnet_next) { 1024 rt = rtget(intnetp->intnet_addr, intnetp->intnet_mask); 1025 if (rt != 0 1026 && !(rt->rt_state & RS_NO_NET_SYN) 1027 && !(rt->rt_state & RS_NET_INT)) { 1028 rtdelete(rt); 1029 rt = 0; 1030 } 1031 if (rt == 0) 1032 rtadd(intnetp->intnet_addr, intnetp->intnet_mask, 1033 loopaddr, loopaddr, intnetp->intnet_metric-1, 1034 0, RS_NET_SYN | RS_NET_INT, 0); 1035 } 1036 1037 prev_complaints = complaints; 1038 } 1039 1040 1041 static void 1042 check_net_syn(struct interface *ifp) 1043 { 1044 struct rt_entry *rt; 1045 1046 1047 /* Turn on the need to automatically synthesize a network route 1048 * for this interface only if we are running RIPv1 on some other 1049 * interface that is on a different class-A,B,or C network. 1050 */ 1051 if (have_ripv1_out || have_ripv1_in) { 1052 ifp->int_state |= IS_NEED_NET_SYN; 1053 rt = rtget(ifp->int_std_addr, ifp->int_std_mask); 1054 if (rt != 0 1055 && 0 == (rt->rt_state & RS_NO_NET_SYN) 1056 && (!(rt->rt_state & RS_NET_SYN) 1057 || rt->rt_metric > ifp->int_metric)) { 1058 rtdelete(rt); 1059 rt = 0; 1060 } 1061 if (rt == 0) 1062 rtadd(ifp->int_std_addr, ifp->int_std_mask, 1063 ifp->int_addr, ifp->int_addr, 1064 ifp->int_metric, 0, RS_NET_SYN, ifp); 1065 1066 } else { 1067 ifp->int_state &= ~IS_NEED_NET_SYN; 1068 1069 rt = rtget(ifp->int_std_addr, 1070 ifp->int_std_mask); 1071 if (rt != 0 1072 && (rt->rt_state & RS_NET_SYN) 1073 && rt->rt_ifp == ifp) 1074 rtbad_sub(rt); 1075 } 1076 } 1077 1078 1079 /* Add route for interface if not currently installed. 1080 * Create route to other end if a point-to-point link, 1081 * otherwise a route to this (sub)network. 1082 */ 1083 void 1084 addrouteforif(struct interface *ifp) 1085 { 1086 struct rt_entry *rt; 1087 naddr dst, gate; 1088 1089 1090 /* skip sick interfaces 1091 */ 1092 if (ifp->int_state & IS_BROKE) 1093 return; 1094 1095 /* If the interface on a subnet, then install a RIPv1 route to 1096 * the network as well (unless it is sick). 1097 */ 1098 if (ifp->int_state & IS_SUBNET) 1099 check_net_syn(ifp); 1100 1101 if (ifp->int_state & IS_REMOTE) { 1102 dst = ifp->int_addr; 1103 gate = ifp->int_dstaddr; 1104 /* If we are going to send packets to the gateway, 1105 * it must be reachable using our physical interfaces 1106 */ 1107 if (!(ifp->int_state && IS_EXTERNAL) 1108 && !rtfind(ifp->int_dstaddr) 1109 && ifp->int_transitions == 0) { 1110 msglog("unreachable gateway %s in " 1111 _PATH_GATEWAYS" entry %s", 1112 naddr_ntoa(gate), ifp->int_name); 1113 return; 1114 } 1115 1116 } else { 1117 dst = (0 != (ifp->int_if_flags & (IFF_POINTOPOINT 1118 | IFF_LOOPBACK)) 1119 ? ifp->int_dstaddr 1120 : htonl(ifp->int_net)); 1121 gate = ifp->int_addr; 1122 } 1123 1124 /* We are finished if the correct main interface route exists. 1125 * The right route must be for the right interface, not synthesized 1126 * from a subnet, be a "gateway" or not as appropriate, and so forth. 1127 */ 1128 del_static(dst, ifp->int_mask, 0); 1129 rt = rtget(dst, ifp->int_mask); 1130 if (rt != 0) { 1131 if ((rt->rt_ifp != ifp 1132 || rt->rt_router != ifp->int_addr) 1133 && (!(ifp->int_state & IS_DUP) 1134 || rt->rt_ifp == 0 1135 || (rt->rt_ifp->int_state & IS_BROKE))) { 1136 rtdelete(rt); 1137 rt = 0; 1138 } else { 1139 rtchange(rt, ((rt->rt_state | RS_IF) 1140 & ~(RS_NET_SYN | RS_LOCAL)), 1141 ifp->int_addr, ifp->int_addr, 1142 ifp->int_metric, 0, ifp, now.tv_sec, 0); 1143 } 1144 } 1145 if (rt == 0) { 1146 if (ifp->int_transitions++ > 0) 1147 trace_act("re-install interface %s\n", 1148 ifp->int_name); 1149 1150 rtadd(dst, ifp->int_mask, gate, gate, 1151 ifp->int_metric, 0, RS_IF, ifp); 1152 } 1153 } 1154