1 /* 2 * Copyright (c) 1983, 1988, 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[] = "@(#)output.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 43 44 int update_seqno; 45 46 47 /* walk the tree of routes with this for output 48 */ 49 struct { 50 struct sockaddr_in to; 51 naddr to_mask; 52 naddr to_net; 53 naddr to_std_mask; 54 naddr to_std_net; 55 struct interface *ifp; /* usually output interface */ 56 struct ws_buf { /* info for each buffer */ 57 struct rip *buf; 58 struct netinfo *n; 59 struct netinfo *base; 60 struct netinfo *lim; 61 enum output_type type; 62 } v12, v2; 63 char metric; /* adjust metrics by interface */ 64 int npackets; 65 int gen_limit; 66 u_int state; 67 #define WS_ST_FLASH 0x001 /* send only changed routes */ 68 #define WS_ST_RIP2_SAFE 0x002 /* send RIPv2 safe for RIPv1 */ 69 #define WS_ST_RIP2_ALL 0x004 /* send full featured RIPv2 */ 70 #define WS_ST_AG 0x008 /* ok to aggregate subnets */ 71 #define WS_ST_SUPER_AG 0x010 /* ok to aggregate networks */ 72 #define WS_ST_SUB_AG 0x020 /* aggregate subnets in odd case */ 73 #define WS_ST_QUERY 0x040 /* responding to a query */ 74 #define WS_ST_TO_ON_NET 0x080 /* sending onto one of our nets */ 75 #define WS_ST_DEFAULT 0x100 /* faking a default */ 76 #define WS_ST_PM_RDISC 0x200 /* poor-man's router discovery */ 77 } ws; 78 79 /* A buffer for what can be heard by both RIPv1 and RIPv2 listeners */ 80 union pkt_buf ripv12_buf; 81 82 /* Another for only RIPv2 listeners */ 83 union pkt_buf rip_v2_buf; 84 85 86 87 /* Send the contents of the global buffer via the non-multicast socket 88 */ 89 int /* <0 on failure */ 90 output(enum output_type type, 91 struct sockaddr_in *dst, /* send to here */ 92 struct interface *ifp, 93 struct rip *buf, 94 int size) /* this many bytes */ 95 { 96 struct sockaddr_in sin; 97 int flags; 98 char *msg; 99 int res; 100 naddr tgt_mcast; 101 int soc; 102 int serrno; 103 104 sin = *dst; 105 if (sin.sin_port == 0) 106 sin.sin_port = htons(RIP_PORT); 107 #ifdef _HAVE_SIN_LEN 108 if (sin.sin_len == 0) 109 sin.sin_len = sizeof(sin); 110 #endif 111 112 soc = rip_sock; 113 flags = 0; 114 115 switch (type) { 116 case OUT_QUERY: 117 msg = "Answer Query"; 118 if (soc < 0) 119 soc = ifp->int_rip_sock; 120 break; 121 case OUT_UNICAST: 122 msg = "Send"; 123 if (soc < 0) 124 soc = ifp->int_rip_sock; 125 flags = MSG_DONTROUTE; 126 break; 127 case OUT_BROADCAST: 128 if (ifp->int_if_flags & IFF_POINTOPOINT) { 129 msg = "Send"; 130 } else { 131 msg = "Send bcast"; 132 } 133 flags = MSG_DONTROUTE; 134 break; 135 case OUT_MULTICAST: 136 if (ifp->int_if_flags & IFF_POINTOPOINT) { 137 msg = "Send pt-to-pt"; 138 } else if (ifp->int_state & IS_DUP) { 139 trace_act("abort multicast output via %s" 140 " with duplicate address\n", 141 ifp->int_name); 142 return 0; 143 } else { 144 msg = "Send mcast"; 145 if (rip_sock_mcast != ifp) { 146 #ifdef MCAST_PPP_BUG 147 /* Do not specifiy the primary interface 148 * explicitly if we have the multicast 149 * point-to-point kernel bug, since the 150 * kernel will do the wrong thing if the 151 * local address of a point-to-point link 152 * is the same as the address of an ordinary 153 * interface. 154 */ 155 if (ifp->int_addr == myaddr) { 156 tgt_mcast = 0; 157 } else 158 #endif 159 tgt_mcast = ifp->int_addr; 160 if (0 > setsockopt(rip_sock, 161 IPPROTO_IP, IP_MULTICAST_IF, 162 &tgt_mcast, 163 sizeof(tgt_mcast))) { 164 serrno = errno; 165 LOGERR("setsockopt(rip_sock," 166 "IP_MULTICAST_IF)"); 167 errno = serrno; 168 ifp = 0; 169 return -1; 170 } 171 rip_sock_mcast = ifp; 172 } 173 sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP); 174 } 175 176 case NO_OUT_MULTICAST: 177 case NO_OUT_RIPV2: 178 break; 179 } 180 181 trace_rip(msg, "to", &sin, ifp, buf, size); 182 183 res = sendto(soc, buf, size, flags, 184 (struct sockaddr *)&sin, sizeof(sin)); 185 if (res < 0 186 && (ifp == 0 || !(ifp->int_state & IS_BROKE))) { 187 serrno = errno; 188 msglog("%s sendto(%s%s%s.%d): %s", msg, 189 ifp != 0 ? ifp->int_name : "", 190 ifp != 0 ? ", " : "", 191 inet_ntoa(sin.sin_addr), 192 ntohs(sin.sin_port), 193 strerror(errno)); 194 errno = serrno; 195 } 196 197 return res; 198 } 199 200 201 /* install authentication if appropriate 202 */ 203 static void 204 set_auth(struct ws_buf *w) 205 { 206 if (ws.ifp != 0 207 && ws.ifp->int_passwd[0] != '\0' 208 && (ws.state & WS_ST_RIP2_SAFE)) { 209 w->n->n_family = RIP_AF_AUTH; 210 ((struct netauth*)w->n)->a_type = RIP_AUTH_PW; 211 bcopy(ws.ifp->int_passwd, ((struct netauth*)w->n)->au.au_pw, 212 sizeof(((struct netauth*)w->n)->au.au_pw)); 213 w->n++; 214 } 215 } 216 217 218 /* Send the buffer 219 */ 220 static void 221 supply_write(struct ws_buf *wb) 222 { 223 /* Output multicast only if legal. 224 * If we would multcast and it would be illegal, then discard the 225 * packet. 226 */ 227 switch (wb->type) { 228 case NO_OUT_MULTICAST: 229 trace_pkt("skip multicast to %s because impossible\n", 230 naddr_ntoa(ws.to.sin_addr.s_addr)); 231 break; 232 case NO_OUT_RIPV2: 233 break; 234 default: 235 if (output(wb->type, &ws.to, ws.ifp, wb->buf, 236 ((char *)wb->n - (char*)wb->buf)) < 0 237 && ws.ifp != 0) 238 if_sick(ws.ifp); 239 ws.npackets++; 240 break; 241 } 242 243 bzero(wb->n = wb->base, sizeof(*wb->n)*NETS_LEN); 244 if (wb->buf->rip_vers == RIPv2) 245 set_auth(wb); 246 } 247 248 249 /* put an entry into the packet 250 */ 251 static void 252 supply_out(struct ag_info *ag) 253 { 254 int i; 255 naddr mask, v1_mask, s_mask, dst_h, ddst_h; 256 struct ws_buf *wb; 257 258 259 /* Skip this route if doing a flash update and it and the routes 260 * it aggregates have not changed recently. 261 */ 262 if (ag->ag_seqno < update_seqno 263 && (ws.state & WS_ST_FLASH)) 264 return; 265 266 /* Skip this route if required by split-horizon. 267 */ 268 if (ag->ag_state & AGS_SPLIT_HZ) 269 return; 270 271 dst_h = ag->ag_dst_h; 272 mask = ag->ag_mask; 273 v1_mask = ripv1_mask_host(htonl(dst_h), 274 (ws.state & WS_ST_TO_ON_NET) ? ws.ifp : 0); 275 s_mask = std_mask(htonl(dst_h)); 276 i = 0; 277 278 /* If we are sending RIPv2 packets that cannot (or must not) be 279 * heard by RIPv1 listeners, do not worry about sub- or supernets. 280 * Subnets (from other networks) can only be sent via multicast. 281 * A pair of subnet routes might have been promoted so that they 282 * are legal to send by RIPv1. 283 * If RIPv1 is off, use the multicast buffer, unless this is the 284 * fake default route and it is acting as a poor-man's router- 285 * discovery mechanism. 286 */ 287 if (((ws.state & WS_ST_RIP2_ALL) 288 && (dst_h != RIP_DEFAULT || !(ws.state & WS_ST_PM_RDISC))) 289 || ((ag->ag_state & AGS_RIPV2) && v1_mask != mask)) { 290 /* use the RIPv2-only buffer */ 291 wb = &ws.v2; 292 293 } else { 294 /* use the RIPv1-or-RIPv2 buffer */ 295 wb = &ws.v12; 296 297 /* Convert supernet route into corresponding set of network 298 * routes for RIPv1, but leave non-contiguous netmasks 299 * to ag_check(). 300 */ 301 if (v1_mask > mask 302 && mask + (mask & -mask) == 0) { 303 ddst_h = v1_mask & -v1_mask; 304 i = (v1_mask & ~mask)/ddst_h; 305 306 if (i > ws.gen_limit) { 307 /* Punt if we would have to generate an 308 * unreasonable number of routes. 309 */ 310 #ifdef DEBUG 311 msglog("sending %s to %s as 1 instead" 312 " of %d routes", 313 addrname(htonl(dst_h),mask,1), 314 naddr_ntoa(ws.to.sin_addr.s_addr), 315 i+1); 316 #endif 317 i = 0; 318 319 } else { 320 mask = v1_mask; 321 ws.gen_limit -= i; 322 } 323 } 324 } 325 326 do { 327 wb->n->n_family = RIP_AF_INET; 328 wb->n->n_dst = htonl(dst_h); 329 /* If the route is from router-discovery or we are 330 * shutting down, admit only a bad metric. 331 */ 332 wb->n->n_metric = ((stopint || ag->ag_metric < 1) 333 ? HOPCNT_INFINITY 334 : ag->ag_metric); 335 HTONL(wb->n->n_metric); 336 if (wb->buf->rip_vers == RIPv2) { 337 if (ag->ag_nhop != 0 338 && (ws.state & WS_ST_RIP2_SAFE) 339 && ((ws.state & WS_ST_QUERY) 340 || (ag->ag_nhop != ws.ifp->int_addr 341 && on_net(ag->ag_nhop, 342 ws.ifp->int_net, 343 ws.ifp->int_mask)))) 344 wb->n->n_nhop = ag->ag_nhop; 345 if ((ws.state & WS_ST_RIP2_ALL) 346 || mask != s_mask) 347 wb->n->n_mask = htonl(mask); 348 wb->n->n_tag = ag->ag_tag; 349 } 350 dst_h += ddst_h; 351 352 if (++wb->n >= wb->lim) 353 supply_write(wb); 354 } while (i-- != 0); 355 } 356 357 358 /* supply one route from the table 359 */ 360 /* ARGSUSED */ 361 static int 362 walk_supply(struct radix_node *rn, 363 struct walkarg *w) 364 { 365 #define RT ((struct rt_entry *)rn) 366 u_short ags; 367 char metric, pref; 368 naddr dst, nhop; 369 370 371 /* Do not advertise the loopback interface 372 * or external remote interfaces 373 */ 374 if ((RT->rt_state & RS_IF) 375 && RT->rt_ifp != 0 376 && ((RT->rt_ifp->int_if_flags & IFF_LOOPBACK) 377 || (RT->rt_ifp->int_state & IS_EXTERNAL)) 378 && !(RT->rt_state & RS_MHOME)) 379 return 0; 380 381 /* If being quiet about our ability to forward, then 382 * do not say anything unless responding to a query. 383 */ 384 if (!supplier && !(ws.state & WS_ST_QUERY)) 385 return 0; 386 387 dst = RT->rt_dst; 388 389 /* do not collide with the fake default route */ 390 if (dst == RIP_DEFAULT 391 && (ws.state & WS_ST_DEFAULT)) 392 return 0; 393 394 if (RT->rt_state & RS_NET_SYN) { 395 if (RT->rt_state & RS_NET_INT) { 396 /* Do not send manual synthetic network routes 397 * into the subnet. 398 */ 399 if (on_net(ws.to.sin_addr.s_addr, 400 ntohl(dst), RT->rt_mask)) 401 return 0; 402 403 } else { 404 /* Do not send automatic synthetic network routes 405 * if they are not needed becaus no RIPv1 listeners 406 * can hear them. 407 */ 408 if (ws.state & WS_ST_RIP2_ALL) 409 return 0; 410 411 /* Do not send automatic synthetic network routes to 412 * the real subnet. 413 */ 414 if (on_net(ws.to.sin_addr.s_addr, 415 ntohl(dst), RT->rt_mask)) 416 return 0; 417 } 418 nhop = 0; 419 420 } else { 421 /* Advertise the next hop if this is not a route for one 422 * of our interfaces and the next hop is on the same 423 * network as the target. 424 */ 425 if (!(RT->rt_state & RS_IF) 426 && RT->rt_gate != myaddr 427 && RT->rt_gate != loopaddr) 428 nhop = RT->rt_gate; 429 else 430 nhop = 0; 431 } 432 433 metric = RT->rt_metric; 434 ags = 0; 435 436 if (RT->rt_state & RS_MHOME) { 437 /* retain host route of multi-homed servers */ 438 ; 439 440 } else if (RT_ISHOST(RT)) { 441 /* We should always aggregate the host routes 442 * for the local end of our point-to-point links. 443 * If we are suppressing host routes in general, then do so. 444 * Avoid advertising host routes onto their own network, 445 * where they should be handled by proxy-ARP. 446 */ 447 if ((RT->rt_state & RS_LOCAL) 448 || ridhosts 449 || (ws.state & WS_ST_SUPER_AG) 450 || on_net(dst, ws.to_net, ws.to_mask)) 451 ags |= AGS_SUPPRESS; 452 453 if (ws.state & WS_ST_SUPER_AG) 454 ags |= AGS_PROMOTE; 455 456 } else if (ws.state & WS_ST_AG) { 457 /* Aggregate network routes, if we are allowed. 458 */ 459 ags |= AGS_SUPPRESS; 460 461 /* Generate supernets if allowed. 462 * If we can be heard by RIPv1 systems, we will 463 * later convert back to ordinary nets. 464 * This unifies dealing with received supernets. 465 */ 466 if ((RT->rt_state & RS_SUBNET) 467 || (ws.state & WS_ST_SUPER_AG)) 468 ags |= AGS_PROMOTE; 469 470 } 471 472 /* Do not send RIPv1 advertisements of subnets to other 473 * networks. If possible, multicast them by RIPv2. 474 */ 475 if ((RT->rt_state & RS_SUBNET) 476 && !(ws.state & WS_ST_RIP2_ALL) 477 && !on_net(dst, ws.to_std_net, ws.to_std_mask)) { 478 ags |= AGS_RIPV2 | AGS_PROMOTE; 479 if (ws.state & WS_ST_SUB_AG) 480 ags |= AGS_SUPPRESS; 481 } 482 483 /* Do not send a route back to where it came from, except in 484 * response to a query. This is "split-horizon". That means not 485 * advertising back to the same network and so via the same interface. 486 * 487 * We want to suppress routes that might have been fragmented 488 * from this route by a RIPv1 router and sent back to us, and so we 489 * cannot forget this route here. Let the split-horizon route 490 * aggregate (suppress) the fragmented routes and then itself be 491 * forgotten. 492 * 493 * Include the routes for both ends of point-to-point interfaces 494 * since the other side presumably knows them as well as we do. 495 */ 496 if (RT->rt_ifp == ws.ifp && ws.ifp != 0 497 && !(ws.state & WS_ST_QUERY) 498 && (ws.state & WS_ST_TO_ON_NET) 499 && (!(RT->rt_state & RS_IF) 500 || ws.ifp->int_if_flags & IFF_POINTOPOINT)) { 501 /* Poison-reverse the route instead of only not advertising it 502 * it is recently changed from some other route. 503 * In almost all cases, if there is no spare for the route 504 * then it is either old or a brand new route, and if it 505 * is brand new, there is no need for poison-reverse. 506 */ 507 metric = HOPCNT_INFINITY; 508 if (RT->rt_poison_time < now_expire 509 || RT->rt_spares[1].rts_gate ==0) { 510 ags |= AGS_SPLIT_HZ; 511 ags &= ~(AGS_PROMOTE | AGS_SUPPRESS); 512 } 513 } 514 515 /* Adjust the outgoing metric by the cost of the link. 516 */ 517 pref = metric + ws.metric; 518 if (pref < HOPCNT_INFINITY) { 519 /* Keep track of the best metric with which the 520 * route has been advertised recently. 521 */ 522 if (RT->rt_poison_metric >= metric 523 || RT->rt_poison_time < now_expire) { 524 RT->rt_poison_time = now.tv_sec; 525 RT->rt_poison_metric = metric; 526 } 527 metric = pref; 528 529 } else { 530 /* Do not advertise stable routes that will be ignored, 531 * unless they are being held down and poisoned. If the 532 * route recently was advertised with a metric that would 533 * have been less than infinity through this interface, we 534 * need to continue to advertise it in order to poison it. 535 */ 536 pref = RT->rt_poison_metric + ws.metric; 537 if (pref >= HOPCNT_INFINITY 538 || RT->rt_poison_time < now_garbage ) 539 return 0; 540 541 metric = HOPCNT_INFINITY; 542 } 543 544 ag_check(dst, RT->rt_mask, 0, nhop, metric, pref, 545 RT->rt_seqno, RT->rt_tag, ags, supply_out); 546 return 0; 547 #undef RT 548 } 549 550 551 /* Supply dst with the contents of the routing tables. 552 * If this won't fit in one packet, chop it up into several. 553 */ 554 void 555 supply(struct sockaddr_in *dst, 556 struct interface *ifp, /* output interface */ 557 enum output_type type, 558 int flash, /* 1=flash update */ 559 int vers) /* RIP version */ 560 { 561 static int init = 1; 562 struct rt_entry *rt; 563 564 565 ws.state = 0; 566 ws.gen_limit = 1024; 567 568 ws.to = *dst; 569 ws.to_std_mask = std_mask(ws.to.sin_addr.s_addr); 570 ws.to_std_net = ntohl(ws.to.sin_addr.s_addr) & ws.to_std_mask; 571 572 if (ifp != 0) { 573 ws.to_mask = ifp->int_mask; 574 ws.to_net = ifp->int_net; 575 if (on_net(ws.to.sin_addr.s_addr, ws.to_net, ws.to_mask)) 576 ws.state |= WS_ST_TO_ON_NET; 577 578 } else { 579 ws.to_mask = ripv1_mask_net(ws.to.sin_addr.s_addr, 0); 580 ws.to_net = ntohl(ws.to.sin_addr.s_addr) & ws.to_mask; 581 rt = rtfind(dst->sin_addr.s_addr); 582 if (rt) 583 ifp = rt->rt_ifp; 584 } 585 586 ws.npackets = 0; 587 if (flash) 588 ws.state |= WS_ST_FLASH; 589 if (type == OUT_QUERY) 590 ws.state |= WS_ST_QUERY; 591 592 if ((ws.ifp = ifp) == 0) { 593 ws.metric = 1; 594 } else { 595 /* Adjust the advertised metric by the outgoing interface 596 * metric. 597 */ 598 ws.metric = ifp->int_metric+1; 599 } 600 601 if (init) { 602 init = 0; 603 604 bzero(&ripv12_buf, sizeof(ripv12_buf)); 605 ripv12_buf.rip.rip_cmd = RIPCMD_RESPONSE; 606 ws.v12.buf = &ripv12_buf.rip; 607 ws.v12.base = &ws.v12.buf->rip_nets[0]; 608 ws.v12.lim = ws.v12.base + NETS_LEN; 609 610 bzero(&rip_v2_buf, sizeof(rip_v2_buf)); 611 rip_v2_buf.rip.rip_cmd = RIPCMD_RESPONSE; 612 rip_v2_buf.rip.rip_vers = RIPv2; 613 ws.v2.buf = &rip_v2_buf.rip; 614 ws.v2.base = &ws.v2.buf->rip_nets[0]; 615 ws.v2.lim = ws.v2.base + NETS_LEN; 616 } 617 ripv12_buf.rip.rip_vers = vers; 618 619 ws.v12.n = ws.v12.base; 620 set_auth(&ws.v12); 621 ws.v2.n = ws.v2.base; 622 set_auth(&ws.v2); 623 624 switch (type) { 625 case OUT_BROADCAST: 626 ws.v2.type = ((ws.ifp != 0 627 && (ws.ifp->int_if_flags & IFF_MULTICAST)) 628 ? OUT_MULTICAST 629 : NO_OUT_MULTICAST); 630 ws.v12.type = OUT_BROADCAST; 631 break; 632 case OUT_MULTICAST: 633 ws.v2.type = ((ws.ifp != 0 634 && (ws.ifp->int_if_flags & IFF_MULTICAST)) 635 ? OUT_MULTICAST 636 : NO_OUT_MULTICAST); 637 ws.v12.type = OUT_BROADCAST; 638 break; 639 case OUT_UNICAST: 640 case OUT_QUERY: 641 ws.v2.type = (vers == RIPv2) ? type : NO_OUT_RIPV2; 642 ws.v12.type = type; 643 break; 644 default: 645 ws.v2.type = type; 646 ws.v12.type = type; 647 break; 648 } 649 650 if (vers == RIPv2) { 651 /* if asked to send RIPv2, send at least that which can 652 * be safely heard by RIPv1 listeners. 653 */ 654 ws.state |= WS_ST_RIP2_SAFE; 655 656 /* full RIPv2 only if cannot be heard by RIPv1 listeners */ 657 if (type != OUT_BROADCAST) 658 ws.state |= WS_ST_RIP2_ALL; 659 if (!(ws.state & WS_ST_TO_ON_NET)) { 660 ws.state |= (WS_ST_AG | WS_ST_SUPER_AG); 661 } else if (ws.ifp == 0 || !(ws.ifp->int_state & IS_NO_AG)) { 662 ws.state |= WS_ST_AG; 663 if (type != OUT_BROADCAST 664 && (ws.ifp == 0 665 || !(ws.ifp->int_state & IS_NO_SUPER_AG))) 666 ws.state |= WS_ST_SUPER_AG; 667 } 668 669 } else if (ws.ifp == 0 || !(ws.ifp->int_state & IS_NO_AG)) { 670 ws.state |= WS_ST_SUB_AG; 671 } 672 673 if (supplier) { 674 /* Fake a default route if asked, and if there is not 675 * a better, real default route. 676 */ 677 if (ifp->int_d_metric != 0 678 && (0 == (rt = rtget(RIP_DEFAULT, 0)) 679 || rt->rt_metric+ws.metric >= ifp->int_d_metric)) { 680 ws.state |= WS_ST_DEFAULT; 681 ag_check(0, 0, 0, 0, 682 ifp->int_d_metric,ifp->int_d_metric, 683 0, 0, 0, supply_out); 684 } 685 if ((ws.state & WS_ST_RIP2_ALL) 686 && (ifp->int_state & IS_PM_RDISC)) { 687 ws.state |= WS_ST_PM_RDISC; 688 ripv12_buf.rip.rip_vers = RIPv1; 689 } 690 } 691 692 (void)rn_walktree(rhead, walk_supply, 0); 693 ag_flush(0,0,supply_out); 694 695 /* Flush the packet buffers, provided they are not empty and 696 * do not contain only the password. 697 */ 698 if (ws.v12.n != ws.v12.base 699 && (ws.v12.n > ws.v12.base+1 700 || ws.v12.n->n_family != RIP_AF_AUTH)) 701 supply_write(&ws.v12); 702 if (ws.v2.n != ws.v2.base 703 && (ws.v2.n > ws.v2.base+1 704 || ws.v2.n->n_family != RIP_AF_AUTH)) 705 supply_write(&ws.v2); 706 707 /* If we sent nothing and this is an answer to a query, send 708 * an empty buffer. 709 */ 710 if (ws.npackets == 0 711 && (ws.state & WS_ST_QUERY)) 712 supply_write(&ws.v12); 713 } 714 715 716 /* send all of the routing table or just do a flash update 717 */ 718 void 719 rip_bcast(int flash) 720 { 721 #ifdef _HAVE_SIN_LEN 722 static struct sockaddr_in dst = {sizeof(dst), AF_INET}; 723 #else 724 static struct sockaddr_in dst = {AF_INET}; 725 #endif 726 struct interface *ifp; 727 enum output_type type; 728 int vers; 729 struct timeval rtime; 730 731 732 need_flash = 0; 733 intvl_random(&rtime, MIN_WAITTIME, MAX_WAITTIME); 734 no_flash = rtime; 735 timevaladd(&no_flash, &now); 736 737 if (rip_sock < 0) 738 return; 739 740 trace_act("send %s and inhibit dynamic updates for %.3f sec\n", 741 flash ? "dynamic update" : "all routes", 742 rtime.tv_sec + ((float)rtime.tv_usec)/1000000.0); 743 744 for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) { 745 /* skip interfaces not doing RIP, those already queried, 746 * and aliases. Do try broken interfaces to see 747 * if they have healed. 748 */ 749 if (0 != (ifp->int_state & (IS_PASSIVE | IS_ALIAS))) 750 continue; 751 752 /* skip turned off interfaces */ 753 if (!iff_alive(ifp->int_if_flags)) 754 continue; 755 756 /* default to RIPv1 output */ 757 if (ifp->int_state & IS_NO_RIPV1_OUT) { 758 /* Say nothing if this interface is turned off */ 759 if (ifp->int_state & IS_NO_RIPV2_OUT) 760 continue; 761 vers = RIPv2; 762 } else { 763 vers = RIPv1; 764 } 765 766 if (ifp->int_if_flags & IFF_BROADCAST) { 767 /* ordinary, hardware interface */ 768 dst.sin_addr.s_addr = ifp->int_brdaddr; 769 /* if RIPv1 is not turned off, then broadcast so 770 * that RIPv1 listeners can hear. 771 */ 772 if (vers == RIPv2 773 && (ifp->int_state & IS_NO_RIPV1_OUT)) { 774 type = OUT_MULTICAST; 775 } else { 776 type = OUT_BROADCAST; 777 } 778 779 } else if (ifp->int_if_flags & IFF_POINTOPOINT) { 780 /* point-to-point hardware interface */ 781 dst.sin_addr.s_addr = ifp->int_dstaddr; 782 type = OUT_UNICAST; 783 784 } else { 785 /* remote interface */ 786 dst.sin_addr.s_addr = ifp->int_addr; 787 type = OUT_UNICAST; 788 } 789 790 supply(&dst, ifp, type, flash, vers); 791 } 792 793 update_seqno++; /* all routes are up to date */ 794 } 795 796 797 /* Ask for routes 798 * Do it only once to an interface, and not even after the interface 799 * was broken and recovered. 800 */ 801 void 802 rip_query(void) 803 { 804 #ifdef _HAVE_SIN_LEN 805 static struct sockaddr_in dst = {sizeof(dst), AF_INET}; 806 #else 807 static struct sockaddr_in dst = {AF_INET}; 808 #endif 809 struct interface *ifp; 810 struct rip buf; 811 enum output_type type; 812 813 814 if (rip_sock < 0) 815 return; 816 817 bzero(&buf, sizeof(buf)); 818 819 for (ifp = ifnet; ifp; ifp = ifp->int_next) { 820 /* skip interfaces not doing RIP, those already queried, 821 * and aliases. Do try broken interfaces to see 822 * if they have healed. 823 */ 824 if (0 != (ifp->int_state & (IS_RIP_QUERIED 825 | IS_PASSIVE | IS_ALIAS))) 826 continue; 827 828 /* skip turned off interfaces */ 829 if (!iff_alive(ifp->int_if_flags)) 830 continue; 831 832 /* default to RIPv1 output */ 833 if (ifp->int_state & IS_NO_RIPV2_OUT) { 834 /* Say nothing if this interface is turned off */ 835 if (ifp->int_state & IS_NO_RIPV1_OUT) 836 continue; 837 buf.rip_vers = RIPv1; 838 } else { 839 buf.rip_vers = RIPv2; 840 } 841 842 buf.rip_cmd = RIPCMD_REQUEST; 843 buf.rip_nets[0].n_family = RIP_AF_UNSPEC; 844 buf.rip_nets[0].n_metric = htonl(HOPCNT_INFINITY); 845 846 if (ifp->int_if_flags & IFF_BROADCAST) { 847 /* ordinary, hardware interface */ 848 dst.sin_addr.s_addr = ifp->int_brdaddr; 849 /* if RIPv1 is not turned off, then broadcast so 850 * that RIPv1 listeners can hear. 851 */ 852 if (buf.rip_vers == RIPv2 853 && (ifp->int_state & IS_NO_RIPV1_OUT)) { 854 type = OUT_MULTICAST; 855 } else { 856 type = OUT_BROADCAST; 857 } 858 859 } else if (ifp->int_if_flags & IFF_POINTOPOINT) { 860 /* point-to-point hardware interface */ 861 dst.sin_addr.s_addr = ifp->int_dstaddr; 862 type = OUT_UNICAST; 863 864 } else { 865 /* remote interface */ 866 dst.sin_addr.s_addr = ifp->int_addr; 867 type = OUT_UNICAST; 868 } 869 870 ifp->int_state |= IS_RIP_QUERIED; 871 if (output(type, &dst, ifp, &buf, sizeof(buf)) < 0) 872 if_sick(ifp); 873 } 874 } 875