1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 * 5 * Copyright (c) 1983, 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgment: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * $FreeBSD: src/sbin/routed/output.c,v 1.7 2000/08/11 08:24:38 sheldonh Exp $ 37 */ 38 39 #pragma ident "%Z%%M% %I% %E% SMI" 40 41 #include "defs.h" 42 #include <md5.h> 43 44 uint_t update_seqno; 45 46 47 /* 48 * walk the tree of routes with this for output 49 */ 50 static struct { 51 struct sockaddr_in to; 52 in_addr_t to_mask; 53 in_addr_t to_net; 54 in_addr_t to_std_mask; 55 in_addr_t to_std_net; 56 struct interface *ifp; /* usually output interface */ 57 struct auth *a; 58 uint8_t metric; /* adjust metrics by interface */ 59 uint32_t npackets; 60 uint32_t gen_limit; 61 #define WS_GEN_LIMIT_MAX 1024 62 uint16_t state; 63 #define WS_ST_FLASH 0x001 /* send only changed routes */ 64 #define WS_ST_RIP2_ALL 0x002 /* send full featured RIPv2 */ 65 #define WS_ST_AG 0x004 /* ok to aggregate subnets */ 66 #define WS_ST_SUPER_AG 0x008 /* ok to aggregate networks */ 67 #define WS_ST_QUERY 0x010 /* responding to a query */ 68 #define WS_ST_TO_ON_NET 0x020 /* sending onto one of our nets */ 69 #define WS_ST_DEFAULT 0x040 /* faking a default */ 70 } ws; 71 72 /* A buffer for what can be heard by both RIPv1 and RIPv2 listeners */ 73 struct ws_buf v12buf; 74 static union pkt_buf ripv12_buf; 75 76 /* Another for only RIPv2 listeners */ 77 static struct ws_buf v2buf; 78 static union pkt_buf rip_v2_buf; 79 80 81 82 void 83 bufinit(void) 84 { 85 ripv12_buf.rip.rip_cmd = RIPCMD_RESPONSE; 86 v12buf.buf = &ripv12_buf.rip; 87 v12buf.base = &v12buf.buf->rip_nets[0]; 88 89 rip_v2_buf.rip.rip_cmd = RIPCMD_RESPONSE; 90 rip_v2_buf.rip.rip_vers = RIPv2; 91 v2buf.buf = &rip_v2_buf.rip; 92 v2buf.base = &v2buf.buf->rip_nets[0]; 93 } 94 95 96 /* 97 * Send the contents of the global buffer via the non-multicast socket 98 */ 99 int /* <0 on failure */ 100 output(enum output_type type, 101 struct sockaddr_in *dst, /* send to here */ 102 struct interface *ifp, 103 struct rip *buf, 104 int size) /* this many bytes */ 105 { 106 struct sockaddr_in sin; 107 int flags; 108 const char *msg; 109 int res; 110 int ifindex; 111 struct in_addr addr; 112 static int rip_sock_ifindex; 113 114 sin = *dst; 115 if (sin.sin_port == 0) 116 sin.sin_port = htons(RIP_PORT); 117 118 flags = 0; 119 120 if (ifp == NULL && type == OUT_MULTICAST) { 121 msglog("Cannot send RIP message to %s", 122 inet_ntoa(sin.sin_addr)); 123 return (-1); 124 } 125 126 switch (type) { 127 case OUT_QUERY: 128 msg = "Answer Query"; 129 break; 130 case OUT_UNICAST: 131 msg = "Send"; 132 flags = MSG_DONTROUTE; 133 break; 134 case OUT_BROADCAST: 135 msg = "Send bcast"; 136 break; 137 case OUT_MULTICAST: 138 msg = "Send mcast"; 139 break; 140 141 case NO_OUT_MULTICAST: 142 case NO_OUT_RIPV2: 143 default: 144 #ifdef DEBUG 145 abort(); 146 #endif 147 return (-1); 148 } 149 150 /* 151 * Note that we intentionally reset IP_XMIT_IF to zero if 152 * we're doing multicast. The kernel ignores IP_MULTICAST_IF 153 * if IP_XMIT_IF is set, and we can't deal with alias source 154 * addresses without it. 155 */ 156 ifindex = (type != OUT_MULTICAST && type != OUT_QUERY && 157 ifp != NULL && ifp->int_phys != NULL) ? 158 ifp->int_phys->phyi_index : 0; 159 if (rip_sock_ifindex != ifindex) { 160 if (setsockopt(rip_sock, IPPROTO_IP, IP_XMIT_IF, &ifindex, 161 sizeof (ifindex)) == -1) { 162 LOGERR("setsockopt(rip_sock, IP_XMIT_IF)"); 163 return (-1); 164 } 165 rip_sock_ifindex = ifindex; 166 } 167 168 if (rip_sock_interface != ifp) { 169 /* 170 * For multicast, we have to choose the source 171 * address. This is either the local address 172 * (non-point-to-point) or the remote address. 173 */ 174 if (ifp != NULL) { 175 addr.s_addr = (ifp->int_if_flags & IFF_POINTOPOINT) ? 176 ifp->int_dstaddr : ifp->int_addr; 177 if (type == OUT_MULTICAST && 178 setsockopt(rip_sock, IPPROTO_IP, 179 IP_MULTICAST_IF, &addr, sizeof (addr)) == -1) { 180 LOGERR("setsockopt(rip_sock, IP_MULTICAST_IF)"); 181 return (-1); 182 } 183 } 184 rip_sock_interface = ifp; 185 } 186 187 trace_rip(msg, "to", &sin, ifp, buf, size); 188 189 res = sendto(rip_sock, buf, size, flags, 190 (struct sockaddr *)&sin, sizeof (sin)); 191 if (res < 0 && 192 (ifp == NULL || !(ifp->int_state & IS_BROKE))) { 193 writelog(LOG_WARNING, "%s sendto(%s%s%s.%d): %s", msg, 194 ifp != NULL ? ifp->int_name : "", 195 ifp != NULL ? ", " : "", 196 inet_ntoa(sin.sin_addr), 197 ntohs(sin.sin_port), 198 rip_strerror(errno)); 199 } 200 201 return (res); 202 } 203 204 205 /* 206 * Find the first key for a packet to send. 207 * Try for a key that is eligible and has not expired, but settle for 208 * the last key if they have all expired. 209 * If no key is ready yet, give up. 210 */ 211 struct auth * 212 find_auth(struct interface *ifp) 213 { 214 struct auth *ap, *res = NULL; 215 int i; 216 217 218 if (ifp == NULL) 219 return (NULL); 220 221 if ((ap = ifp->int_auth) == NULL) 222 return (NULL); 223 224 for (i = 0; i < MAX_AUTH_KEYS; i++, ap++) { 225 /* stop looking after the last key */ 226 if (ap->type == RIP_AUTH_NONE) 227 break; 228 229 /* ignore keys that are not ready yet */ 230 if ((ulong_t)ap->start > (ulong_t)clk.tv_sec) 231 continue; 232 233 if ((ulong_t)ap->end < (ulong_t)clk.tv_sec) { 234 /* note best expired password as a fall-back */ 235 if (res == NULL || 236 (((ulong_t)ap->end > (ulong_t)res->end)) && 237 ((ulong_t)res->end < (ulong_t)clk.tv_sec)) 238 res = ap; 239 continue; 240 } 241 242 /* note key with the best future */ 243 if (res == NULL || (ulong_t)res->end < (ulong_t)ap->end) 244 res = ap; 245 } 246 return (res); 247 } 248 249 250 void 251 clr_ws_buf(struct ws_buf *wb, struct auth *ap) 252 { 253 struct netauth *na; 254 255 wb->lim = wb->base + NETS_LEN; 256 wb->n = wb->base; 257 (void) memset(wb->n, 0, NETS_LEN*sizeof (*wb->n)); 258 259 /* 260 * (start to) install authentication if appropriate 261 */ 262 if (ap == NULL) 263 return; 264 265 na = (struct netauth *)wb->n; 266 if (ap->type == RIP_AUTH_PW) { 267 na->a_family = RIP_AF_AUTH; 268 na->a_type = RIP_AUTH_PW; 269 (void) memcpy(na->au.au_pw, ap->key, sizeof (na->au.au_pw)); 270 wb->n++; 271 272 } else if (ap->type == RIP_AUTH_MD5) { 273 na->a_family = RIP_AF_AUTH; 274 na->a_type = RIP_AUTH_MD5; 275 na->au.a_md5.md5_keyid = ap->keyid; 276 na->au.a_md5.md5_auth_len = RIP_AUTH_MD5_LEN; 277 na->au.a_md5.md5_seqno = htonl(clk.tv_sec); 278 wb->n++; 279 wb->lim--; /* make room for trailer */ 280 } 281 } 282 283 284 void 285 end_md5_auth(struct ws_buf *wb, struct auth *ap) 286 { 287 struct netauth *na, *na2; 288 MD5_CTX md5_ctx; 289 int len; 290 291 na = (struct netauth *)wb->base; 292 na2 = (struct netauth *)wb->n; 293 len = (char *)na2-(char *)wb->buf; 294 na2->a_family = RIP_AF_AUTH; 295 na2->a_type = RIP_AUTH_TRAILER; 296 na->au.a_md5.md5_pkt_len = htons(len); 297 MD5Init(&md5_ctx); 298 /* len+4 to include auth trailer's family/type in MD5 sum */ 299 MD5Update(&md5_ctx, (uchar_t *)wb->buf, len + 4); 300 MD5Update(&md5_ctx, ap->key, RIP_AUTH_MD5_LEN); 301 MD5Final(na2->au.au_pw, &md5_ctx); 302 wb->n++; 303 } 304 305 306 /* 307 * Send the buffer 308 */ 309 static void 310 supply_write(struct ws_buf *wb) 311 { 312 /* 313 * Output multicast only if legal. 314 * If we would multicast and it would be illegal, then discard the 315 * packet. 316 */ 317 switch (wb->type) { 318 case NO_OUT_MULTICAST: 319 trace_pkt("skip multicast to %s because impossible", 320 naddr_ntoa(ws.to.sin_addr.s_addr)); 321 break; 322 case NO_OUT_RIPV2: 323 break; 324 default: 325 if (ws.a != NULL && ws.a->type == RIP_AUTH_MD5) 326 end_md5_auth(wb, ws.a); 327 if (output(wb->type, &ws.to, ws.ifp, wb->buf, 328 ((char *)wb->n - (char *)wb->buf)) < 0 && ws.ifp != NULL) 329 if_sick(ws.ifp, _B_FALSE); 330 ws.npackets++; 331 break; 332 } 333 334 clr_ws_buf(wb, ws.a); 335 } 336 337 338 /* 339 * Put an entry into the packet 340 */ 341 static void 342 supply_out(struct ag_info *ag) 343 { 344 uint32_t dstcount; 345 in_addr_t mask, v1_mask, dst_h, ddst_h = 0; 346 struct ws_buf *wb; 347 348 349 /* 350 * Skip this route if doing a flash update and it and the routes 351 * it aggregates have not changed recently. 352 */ 353 if (ag->ag_seqno < update_seqno && (ws.state & WS_ST_FLASH)) 354 return; 355 356 dst_h = ag->ag_dst_h; 357 mask = ag->ag_mask; 358 v1_mask = ripv1_mask_host(htonl(dst_h), 359 (ws.state & WS_ST_TO_ON_NET) ? ws.ifp : NULL); 360 dstcount = 0; 361 362 /* 363 * If we are sending RIPv2 packets that cannot (or must not) be 364 * heard by RIPv1 listeners, do not worry about sub- or supernets. 365 * Subnets (from other networks) can only be sent via multicast. 366 * A pair of subnet routes might have been promoted so that they 367 * are legal to send by RIPv1. 368 * If RIPv1 is off, use the multicast buffer. 369 */ 370 if ((ws.state & WS_ST_RIP2_ALL) || 371 ((ag->ag_state & AGS_RIPV2) && v1_mask != mask)) { 372 /* use the RIPv2-only buffer */ 373 wb = &v2buf; 374 375 } else { 376 /* 377 * use the RIPv1-or-RIPv2 buffer 378 */ 379 wb = &v12buf; 380 381 /* 382 * Convert supernet route into corresponding set of network 383 * routes for RIPv1, but leave non-contiguous netmasks 384 * to ag_check(). 385 */ 386 if (v1_mask > mask && 387 mask + (mask & -mask) == 0) { 388 ddst_h = v1_mask & -v1_mask; 389 dstcount = (v1_mask & ~mask)/ddst_h; 390 391 if (dstcount > ws.gen_limit) { 392 /* 393 * Punt if we would have to generate an 394 * unreasonable number of routes. 395 */ 396 if (TRACECONTENTS) 397 trace_misc("sending %s-->%s as 1" 398 " instead of %d routes", 399 addrname(htonl(dst_h), mask, 1), 400 naddr_ntoa(ws.to.sin_addr.s_addr), 401 dstcount + 1); 402 dstcount = 0; 403 404 } else { 405 mask = v1_mask; 406 ws.gen_limit -= dstcount; 407 } 408 } 409 } 410 411 do { 412 wb->n->n_family = RIP_AF_INET; 413 wb->n->n_dst = htonl(dst_h); 414 /* 415 * If the route is from router-discovery or we are 416 * shutting down, or this is a broken/sick interface, 417 * admit only a bad metric. 418 */ 419 wb->n->n_metric = ((stopint || ag->ag_metric < 1 || 420 (ag->ag_ifp && (ag->ag_ifp->int_state & 421 (IS_BROKE|IS_SICK)))) ? HOPCNT_INFINITY : ag->ag_metric); 422 wb->n->n_metric = htonl(wb->n->n_metric); 423 /* 424 * Any non-zero bits in the supposedly unused RIPv1 fields 425 * cause the old `routed` to ignore the route. 426 * That means the mask and so forth cannot be sent 427 * in the hybrid RIPv1/RIPv2 mode. 428 */ 429 if (ws.state & WS_ST_RIP2_ALL) { 430 if (ag->ag_nhop != 0 && 431 ((ws.state & WS_ST_QUERY) || 432 (ag->ag_nhop != ws.ifp->int_addr && 433 on_net(ag->ag_nhop, ws.ifp->int_net, 434 ws.ifp->int_mask)) && 435 ifwithaddr(ag->ag_nhop, _B_FALSE, _B_FALSE) == 436 NULL)) 437 wb->n->n_nhop = ag->ag_nhop; 438 wb->n->n_mask = htonl(mask); 439 wb->n->n_tag = ag->ag_tag; 440 } 441 dst_h += ddst_h; 442 443 if (++wb->n >= wb->lim) 444 supply_write(wb); 445 } while (dstcount-- > 0); 446 } 447 448 449 /* 450 * Supply one route from the table 451 */ 452 /* ARGSUSED */ 453 static int 454 walk_supply(struct radix_node *rn, void *argp) 455 { 456 #define RT ((struct rt_entry *)rn) 457 ushort_t ags; 458 uint8_t metric, pref; 459 in_addr_t dst, nhop; 460 struct rt_spare *rts; 461 uint_t sparecount; 462 463 464 /* 465 * Do not advertise external remote interfaces or passive interfaces. 466 */ 467 if ((RT->rt_state & RS_IF) && RT->rt_ifp != NULL && 468 (RT->rt_ifp->int_state & IS_PASSIVE) && 469 !(RT->rt_state & RS_MHOME)) 470 return (0); 471 /* 472 * Do not advertise routes learnt from /etc/gateways. 473 */ 474 if (RT->rt_spares[0].rts_origin == RO_FILE) 475 return (0); 476 477 /* 478 * Do not advertise routes which would lead to forwarding on a 479 * non-forwarding interface. 480 */ 481 if (RT->rt_state & RS_NOPROPAGATE) 482 return (0); 483 484 /* 485 * If being quiet about our ability to forward, then 486 * do not say anything unless responding to a query, 487 * except about our main interface. 488 */ 489 if (!should_supply(NULL) && !(ws.state & WS_ST_QUERY) && 490 !(RT->rt_state & RS_MHOME)) 491 return (0); 492 493 dst = RT->rt_dst; 494 495 /* 496 * do not collide with the fake default route 497 */ 498 if (dst == RIP_DEFAULT && (ws.state & WS_ST_DEFAULT)) 499 return (0); 500 501 if (RT->rt_state & RS_NET_SYN) { 502 if (RT->rt_state & RS_NET_INT) { 503 /* 504 * Do not send manual synthetic network routes 505 * into the subnet. 506 */ 507 if (on_net(ws.to.sin_addr.s_addr, 508 ntohl(dst), RT->rt_mask)) 509 return (0); 510 511 } else { 512 /* 513 * Do not send automatic synthetic network routes 514 * if they are not needed because no RIPv1 listeners 515 * can hear them. 516 */ 517 if (ws.state & WS_ST_RIP2_ALL) 518 return (0); 519 520 /* 521 * Do not send automatic synthetic network routes to 522 * the real subnet. 523 */ 524 if (on_net(ws.to.sin_addr.s_addr, 525 ntohl(dst), RT->rt_mask)) 526 return (0); 527 } 528 nhop = 0; 529 530 } else { 531 /* 532 * Advertise the next hop if this is not a route for one 533 * of our interfaces and the next hop is on the same 534 * network as the target. 535 * The final determination is made by supply_out(). 536 */ 537 if (!(RT->rt_state & RS_IF) && !(RT->rt_state & RS_MHOME) && 538 RT->rt_gate != loopaddr) 539 nhop = RT->rt_gate; 540 else 541 nhop = 0; 542 } 543 544 metric = RT->rt_metric; 545 ags = 0; 546 547 if (!RT_ISHOST(RT)) { 548 /* 549 * Always suppress network routes into other, existing 550 * network routes 551 */ 552 ags |= AGS_SUPPRESS; 553 554 /* 555 * Generate supernets if allowed. 556 * If we can be heard by RIPv1 systems, we will 557 * later convert back to ordinary nets. 558 * This unifies dealing with received supernets. 559 */ 560 if ((ws.state & WS_ST_AG) && ((RT->rt_state & RS_SUBNET) || 561 (ws.state & WS_ST_SUPER_AG))) 562 ags |= AGS_AGGREGATE; 563 } else if (!(RT->rt_state & RS_MHOME)) { 564 /* 565 * We should always suppress (into existing network routes) 566 * the host routes for the local end of our point-to-point 567 * links. 568 * If we are suppressing host routes in general, then do so. 569 * Avoid advertising host routes onto their own network, 570 * where they should be handled by proxy-ARP. 571 */ 572 if ((RT->rt_state & RS_LOCAL) || ridhosts || 573 on_net(dst, ws.to_net, ws.to_mask)) 574 ags |= AGS_SUPPRESS; 575 576 /* 577 * Aggregate stray host routes into network routes if allowed. 578 * We cannot aggregate host routes into small network routes 579 * without confusing RIPv1 listeners into thinking the 580 * network routes are host routes. 581 */ 582 if ((ws.state & WS_ST_AG) && (ws.state & WS_ST_RIP2_ALL)) 583 ags |= AGS_AGGREGATE; 584 } 585 586 /* 587 * Do not send RIPv1 advertisements of subnets to other 588 * networks. If possible, multicast them by RIPv2. 589 */ 590 if ((RT->rt_state & RS_SUBNET) && !(ws.state & WS_ST_RIP2_ALL) && 591 !on_net(dst, ws.to_std_net, ws.to_std_mask)) 592 ags |= AGS_RIPV2 | AGS_AGGREGATE; 593 594 595 /* 596 * Do not send a route back to where it came from, except in 597 * response to a query. This is "split-horizon". That means not 598 * advertising back to the same network and so via the same interface. 599 * 600 * We want to suppress routes that might have been fragmented 601 * from this route by a RIPv1 router and sent back to us, and so we 602 * cannot forget this route here. Let the split-horizon route 603 * suppress the fragmented routes and then itself be forgotten. 604 * 605 * Include the routes for both ends of point-to-point interfaces 606 * among those suppressed by split-horizon, since the other side 607 * should knows them as well as we do. 608 * 609 * Notice spare routes with the same metric that we are about to 610 * advertise, to split the horizon on redundant, inactive paths. 611 */ 612 if (ws.ifp != NULL && !(ws.state & WS_ST_QUERY) && 613 (ws.state & WS_ST_TO_ON_NET) && (!(RT->rt_state & RS_IF) || 614 (ws.ifp->int_if_flags & IFF_POINTOPOINT))) { 615 for (rts = RT->rt_spares, sparecount = 0; 616 sparecount < RT->rt_num_spares; sparecount++, rts++) { 617 if (rts->rts_metric > metric || rts->rts_ifp != ws.ifp) 618 continue; 619 620 /* 621 * If we do not mark the route with AGS_SPLIT_HZ here, 622 * it will be poisoned-reverse, or advertised back 623 * toward its source with an infinite metric. 624 * If we have recently advertised the route with a 625 * better metric than we now have, then we should 626 * poison-reverse the route before suppressing it for 627 * split-horizon. 628 * 629 * In almost all cases, if there is no spare for the 630 * route then it is either old and dead or a brand 631 * new route. If it is brand new, there is no need 632 * for poison-reverse. If it is old and dead, it 633 * is already poisoned. 634 */ 635 if (RT->rt_poison_time < now_expire || 636 RT->rt_poison_metric >= metric || 637 RT->rt_spares[1].rts_gate == 0) { 638 ags |= AGS_SPLIT_HZ; 639 ags &= ~AGS_SUPPRESS; 640 } 641 metric = HOPCNT_INFINITY; 642 break; 643 } 644 } 645 646 /* 647 * Keep track of the best metric with which the 648 * route has been advertised recently. 649 */ 650 if (RT->rt_poison_metric >= metric || 651 RT->rt_poison_time < now_expire) { 652 RT->rt_poison_time = now.tv_sec; 653 RT->rt_poison_metric = metric; 654 } 655 656 /* 657 * Adjust the outgoing metric by the cost of the link. 658 * Avoid aggregation when a route is counting to infinity. 659 */ 660 pref = RT->rt_poison_metric + ws.metric; 661 metric += ws.metric; 662 663 /* 664 * If this is a static route pointing to the same interface 665 * upon which we are sending out the RIP RESPONSE 666 * adjust the preference so that we don't aggregate into this 667 * route. Note that the maximum possible hop count on a route 668 * per RFC 2453 is 16 (HOPCNT_INFINITY) 669 */ 670 if ((RT->rt_state & RS_STATIC) && (ws.ifp == RT->rt_ifp)) 671 pref = (HOPCNT_INFINITY+1); 672 673 /* 674 * Do not advertise stable routes that will be ignored, 675 * unless we are answering a query. 676 * If the route recently was advertised with a metric that 677 * would have been less than infinity through this interface, 678 * we need to continue to advertise it in order to poison it. 679 */ 680 if (metric >= HOPCNT_INFINITY) { 681 if (!(ws.state & WS_ST_QUERY) && (pref >= HOPCNT_INFINITY || 682 RT->rt_poison_time < now_garbage)) 683 return (0); 684 685 metric = HOPCNT_INFINITY; 686 } 687 688 /* 689 * supply this route out on the wire- we only care about dest/mask 690 * and so can ignore all rt_spares[i] with i > 0 691 */ 692 ag_check(dst, RT->rt_mask, 0, RT->rt_ifp, nhop, metric, pref, 693 RT->rt_seqno, RT->rt_tag, ags, supply_out); 694 return (0); 695 #undef RT 696 } 697 698 699 /* 700 * Supply dst with the contents of the routing tables. 701 * If this won't fit in one packet, chop it up into several. 702 */ 703 void 704 supply(struct sockaddr_in *dst, 705 struct interface *ifp, /* output interface */ 706 enum output_type type, 707 int flash, /* 1=flash update */ 708 int vers, /* RIP version */ 709 boolean_t passwd_ok) /* OK to include cleartext password */ 710 { 711 struct rt_entry *rt; 712 uint8_t def_metric; 713 714 715 ws.state = 0; 716 ws.gen_limit = WS_GEN_LIMIT_MAX; 717 718 ws.to = *dst; 719 ws.to_std_mask = std_mask(ws.to.sin_addr.s_addr); 720 ws.to_std_net = ntohl(ws.to.sin_addr.s_addr) & ws.to_std_mask; 721 722 if (ifp != NULL) { 723 ws.to_mask = ifp->int_mask; 724 ws.to_net = ifp->int_net; 725 if (on_net(ws.to.sin_addr.s_addr, ws.to_net, ws.to_mask) || 726 type == OUT_MULTICAST) 727 ws.state |= WS_ST_TO_ON_NET; 728 729 } else { 730 ws.to_mask = ripv1_mask_net(ws.to.sin_addr.s_addr, NULL); 731 ws.to_net = ntohl(ws.to.sin_addr.s_addr) & ws.to_mask; 732 rt = rtfind(dst->sin_addr.s_addr); 733 if (rt != NULL) 734 ifp = rt->rt_ifp; 735 else 736 return; 737 } 738 739 ws.npackets = 0; 740 if (flash) 741 ws.state |= WS_ST_FLASH; 742 743 ws.ifp = ifp; 744 745 /* 746 * Routes in the table were already adjusted by their respective 747 * destination interface costs (which are zero by default) on 748 * input. The following is the value by which each route's metric 749 * will be bumped up on output. 750 */ 751 ws.metric = 1; 752 753 ripv12_buf.rip.rip_vers = vers; 754 755 switch (type) { 756 case OUT_MULTICAST: 757 if (ifp->int_if_flags & IFF_MULTICAST) 758 v2buf.type = OUT_MULTICAST; 759 else 760 v2buf.type = NO_OUT_MULTICAST; 761 v12buf.type = OUT_BROADCAST; 762 break; 763 764 case OUT_QUERY: 765 ws.state |= WS_ST_QUERY; 766 /* FALLTHROUGH */ 767 case OUT_BROADCAST: 768 case OUT_UNICAST: 769 v2buf.type = (vers == RIPv2) ? type : NO_OUT_RIPV2; 770 v12buf.type = type; 771 break; 772 773 case NO_OUT_MULTICAST: 774 case NO_OUT_RIPV2: 775 return; /* no output */ 776 } 777 778 if (vers == RIPv2) { 779 /* full RIPv2 only if cannot be heard by RIPv1 listeners */ 780 if (type != OUT_BROADCAST) 781 ws.state |= WS_ST_RIP2_ALL; 782 if ((ws.state & WS_ST_QUERY) || !(ws.state & WS_ST_TO_ON_NET)) { 783 ws.state |= (WS_ST_AG | WS_ST_SUPER_AG); 784 } else if (ifp == NULL || !(ifp->int_state & IS_NO_AG)) { 785 ws.state |= WS_ST_AG; 786 if (type != OUT_BROADCAST && (ifp == NULL || 787 !(ifp->int_state & IS_NO_SUPER_AG))) 788 ws.state |= WS_ST_SUPER_AG; 789 } 790 791 /* See if this packet needs authenticating */ 792 ws.a = find_auth(ifp); 793 if (!passwd_ok && ws.a != NULL && ws.a->type == RIP_AUTH_PW) 794 ws.a = NULL; 795 if (ws.a != NULL && (ulong_t)ws.a->end < (ulong_t)clk.tv_sec && 796 !ws.a->warnedflag) { 797 /* 798 * If the best key is an expired one, we may as 799 * well use it. Log this event. 800 */ 801 writelog(LOG_WARNING, 802 "Using expired auth while transmitting to %s", 803 naddr_ntoa(ws.to.sin_addr.s_addr)); 804 ws.a->warnedflag = 1; 805 } 806 } else { 807 ws.a = NULL; 808 } 809 810 clr_ws_buf(&v12buf, ws.a); 811 clr_ws_buf(&v2buf, ws.a); 812 813 /* 814 * Fake a default route if asked and if there is not already 815 * a better, real default route. 816 */ 817 if (should_supply(NULL) && (def_metric = ifp->int_d_metric) != 0) { 818 if (NULL == (rt = rtget(RIP_DEFAULT, 0)) || 819 rt->rt_metric+ws.metric >= def_metric) { 820 ws.state |= WS_ST_DEFAULT; 821 ag_check(0, 0, 0, NULL, 0, def_metric, def_metric, 822 0, 0, 0, supply_out); 823 } else { 824 def_metric = rt->rt_metric+ws.metric; 825 } 826 827 /* 828 * If both RIPv2 and the poor-man's router discovery 829 * kludge are on, arrange to advertise an extra 830 * default route via RIPv1. 831 */ 832 if ((ws.state & WS_ST_RIP2_ALL) && 833 (ifp->int_state & IS_PM_RDISC)) { 834 ripv12_buf.rip.rip_vers = RIPv1; 835 v12buf.n->n_family = RIP_AF_INET; 836 v12buf.n->n_dst = htonl(RIP_DEFAULT); 837 v12buf.n->n_metric = htonl(def_metric); 838 v12buf.n++; 839 } 840 } 841 842 (void) rn_walktree(rhead, walk_supply, NULL); 843 ag_flush(0, 0, supply_out); 844 845 /* 846 * Flush the packet buffers, provided they are not empty and 847 * do not contain only the password. 848 */ 849 if (v12buf.n != v12buf.base && 850 (v12buf.n > v12buf.base+1 || 851 v12buf.base->n_family != RIP_AF_AUTH)) 852 supply_write(&v12buf); 853 if (v2buf.n != v2buf.base && (v2buf.n > v2buf.base+1 || 854 v2buf.base->n_family != RIP_AF_AUTH)) 855 supply_write(&v2buf); 856 857 /* 858 * If we sent nothing and this is an answer to a query, send 859 * an empty buffer. 860 */ 861 if (ws.npackets == 0 && (ws.state & WS_ST_QUERY)) { 862 supply_write(&v2buf); 863 if (ws.npackets == 0) 864 supply_write(&v12buf); 865 } 866 } 867 868 869 /* 870 * send all of the routing table or just do a flash update 871 */ 872 void 873 rip_bcast(int flash) 874 { 875 static struct sockaddr_in dst = {AF_INET}; 876 struct interface *ifp; 877 enum output_type type; 878 int vers; 879 struct timeval rtime; 880 881 882 need_flash = _B_FALSE; 883 intvl_random(&rtime, MIN_WAITTIME, MAX_WAITTIME); 884 no_flash = rtime; 885 timevaladd(&no_flash, &now); 886 887 if (!rip_enabled) 888 return; 889 890 trace_act("send %s and inhibit dynamic updates for %.3f sec", 891 flash ? "dynamic update" : "all routes", 892 rtime.tv_sec + ((double)rtime.tv_usec)/1000000.0); 893 894 for (ifp = ifnet; ifp != NULL; ifp = ifp->int_next) { 895 /* 896 * Skip interfaces not doing RIP or for which IP 897 * forwarding isn't turned on. Skip duplicate 898 * interfaces, we don't want to generate duplicate 899 * packets. Do try broken interfaces to see if they 900 * have healed. 901 */ 902 if (IS_RIP_OUT_OFF(ifp->int_state) || 903 (ifp->int_state & IS_DUP) || 904 !IS_IFF_ROUTING(ifp->int_if_flags)) 905 continue; 906 907 /* skip turned off interfaces */ 908 if (!IS_IFF_UP(ifp->int_if_flags)) 909 continue; 910 911 /* skip interfaces we shouldn't use */ 912 if (IS_IFF_QUIET(ifp->int_if_flags)) 913 continue; 914 915 vers = (ifp->int_state & IS_NO_RIPV1_OUT) ? RIPv2 : RIPv1; 916 dst.sin_addr.s_addr = ifp->int_ripout_addr; 917 918 /* 919 * Ignore the interface if it's not broadcast, 920 * point-to-point, or remote. It must be non-broadcast 921 * multiaccess, and therefore unsupported. 922 */ 923 if (!(ifp->int_if_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) && 924 !(ifp->int_state & IS_REMOTE)) 925 continue; 926 927 type = (ifp->int_if_flags & IFF_BROADCAST) ? 928 OUT_BROADCAST : OUT_UNICAST; 929 if (vers == RIPv2 && (ifp->int_if_flags & IFF_MULTICAST) && 930 !(ifp->int_state & IS_NO_RIP_MCAST)) 931 type = OUT_MULTICAST; 932 933 supply(&dst, ifp, type, flash, vers, _B_TRUE); 934 } 935 936 update_seqno++; /* all routes are up to date */ 937 } 938 939 940 /* 941 * Ask for routes 942 * Do it only once to an interface, and not even after the interface 943 * was broken and recovered. 944 */ 945 void 946 rip_query(void) 947 { 948 static struct sockaddr_in dst = {AF_INET}; 949 struct interface *ifp; 950 struct rip buf; 951 enum output_type type; 952 953 954 if (!rip_enabled) 955 return; 956 957 (void) memset(&buf, 0, sizeof (buf)); 958 959 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 960 /* 961 * Skip interfaces those already queried. Do not ask 962 * via interfaces through which we don't accept input. 963 * Do not ask via interfaces that cannot send RIP 964 * packets. Don't send queries on duplicate 965 * interfaces, that would generate duplicate packets 966 * on link. Do try broken interfaces to see if they 967 * have healed. 968 */ 969 if (IS_RIP_IN_OFF(ifp->int_state) || 970 (ifp->int_state & IS_DUP) || 971 ifp->int_query_time != NEVER) 972 continue; 973 974 /* skip turned off interfaces */ 975 if (!IS_IFF_UP(ifp->int_if_flags)) 976 continue; 977 978 /* skip interfaces we shouldn't use */ 979 if (IS_IFF_QUIET(ifp->int_if_flags)) 980 continue; 981 982 /* 983 * Ignore the interface if it's not broadcast, 984 * point-to-point, or remote. It must be non-broadcast 985 * multiaccess, and therefore unsupported. 986 */ 987 if (!(ifp->int_if_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) && 988 !(ifp->int_state & IS_REMOTE)) 989 continue; 990 991 buf.rip_cmd = RIPCMD_REQUEST; 992 buf.rip_nets[0].n_family = RIP_AF_UNSPEC; 993 buf.rip_nets[0].n_metric = htonl(HOPCNT_INFINITY); 994 995 /* 996 * Send a RIPv1 query only if allowed and if we will 997 * listen to RIPv1 routers. 998 */ 999 if ((ifp->int_state & IS_NO_RIPV1_OUT) || 1000 (ifp->int_state & IS_NO_RIPV1_IN)) { 1001 buf.rip_vers = RIPv2; 1002 } else { 1003 buf.rip_vers = RIPv1; 1004 } 1005 1006 dst.sin_addr.s_addr = ifp->int_ripout_addr; 1007 1008 type = (ifp->int_if_flags & IFF_BROADCAST) ? 1009 OUT_BROADCAST : OUT_UNICAST; 1010 if (buf.rip_vers == RIPv2 && 1011 (ifp->int_if_flags & IFF_MULTICAST) && 1012 !(ifp->int_state & IS_NO_RIP_MCAST)) 1013 type = OUT_MULTICAST; 1014 1015 ifp->int_query_time = now.tv_sec+SUPPLY_INTERVAL; 1016 if (output(type, &dst, ifp, &buf, sizeof (buf)) < 0) 1017 if_sick(ifp, _B_FALSE); 1018 } 1019 } 1020