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[] = "@(#)input.c 8.1 (Berkeley) 6/5/93"; 36 #elif defined(__NetBSD__) 37 static char rcsid[] = "$NetBSD$"; 38 #endif 39 #ident "$Revision: 1.1.1.5 $" 40 41 #include "defs.h" 42 43 static void input(struct sockaddr_in *, struct interface *, struct interface *, 44 struct rip *, int); 45 static void input_route(struct interface *, naddr, 46 naddr, naddr, naddr, struct netinfo *); 47 static int ck_passwd(struct interface *, struct rip *, void *, 48 naddr, struct msg_limit *); 49 50 51 /* process RIP input 52 */ 53 void 54 read_rip(int sock, 55 struct interface *sifp) 56 { 57 struct sockaddr_in from; 58 struct interface *aifp; 59 int fromlen, cc; 60 #ifdef USE_PASSIFNAME 61 static struct msg_limit bad_name; 62 struct { 63 char ifname[IFNAMSIZ]; 64 union pkt_buf pbuf; 65 } inbuf; 66 #else 67 struct { 68 union pkt_buf pbuf; 69 } inbuf; 70 #endif 71 72 73 for (;;) { 74 fromlen = sizeof(from); 75 cc = recvfrom(sock, &inbuf, sizeof(inbuf), 0, 76 (struct sockaddr*)&from, &fromlen); 77 if (cc <= 0) { 78 if (cc < 0 && errno != EWOULDBLOCK) 79 LOGERR("recvfrom(rip)"); 80 break; 81 } 82 if (fromlen != sizeof(struct sockaddr_in)) 83 logbad(1,"impossible recvfrom(rip) fromlen=%d", 84 fromlen); 85 86 /* aifp is the "authenticated" interface via which the packet 87 * arrived. In fact, it is only the interface on which 88 * the packet should have arrived based on is source 89 * address. 90 * sifp is interface associated with the socket through which 91 * the packet was received. 92 */ 93 #ifdef USE_PASSIFNAME 94 if ((cc -= sizeof(inbuf.ifname)) < 0) 95 logbad(0,"missing USE_PASSIFNAME; only %d bytes", 96 cc+sizeof(inbuf.ifname)); 97 98 /* check the remote interfaces first */ 99 for (aifp = remote_if; aifp; aifp = aifp->int_rlink) { 100 if (aifp->int_addr == from.sin_addr.s_addr) 101 break; 102 } 103 if (aifp == 0) { 104 aifp = ifwithname(inbuf.ifname, 0); 105 if (aifp == 0) { 106 msglim(&bad_name, from.sin_addr.s_addr, 107 "impossible interface name %.*s", 108 IFNAMSIZ, inbuf.ifname); 109 } else if (((aifp->int_if_flags & IFF_POINTOPOINT) 110 && aifp->int_dstaddr!=from.sin_addr.s_addr) 111 || (!(aifp->int_if_flags & IFF_POINTOPOINT) 112 && !on_net(from.sin_addr.s_addr, 113 aifp->int_net, 114 aifp->int_mask))) { 115 /* If it came via the wrong interface, do not 116 * trust it. 117 */ 118 aifp = 0; 119 } 120 } 121 #else 122 aifp = iflookup(from.sin_addr.s_addr); 123 #endif 124 if (sifp == 0) 125 sifp = aifp; 126 127 input(&from, sifp, aifp, &inbuf.pbuf.rip, cc); 128 } 129 } 130 131 132 /* Process a RIP packet 133 */ 134 static void 135 input(struct sockaddr_in *from, /* received from this IP address */ 136 struct interface *sifp, /* interface of incoming socket */ 137 struct interface *aifp, /* "authenticated" interface */ 138 struct rip *rip, 139 int cc) 140 { 141 # define FROM_NADDR from->sin_addr.s_addr 142 static struct msg_limit use_auth, bad_len, bad_mask; 143 static struct msg_limit unk_router, bad_router, bad_nhop; 144 145 struct rt_entry *rt; 146 struct netinfo *n, *lim; 147 struct interface *ifp1; 148 naddr gate, mask, v1_mask, dst, ddst_h; 149 struct auth *ap; 150 int i; 151 152 /* Notice when we hear from a remote gateway 153 */ 154 if (aifp != 0 155 && (aifp->int_state & IS_REMOTE)) 156 aifp->int_act_time = now.tv_sec; 157 158 trace_rip("Recv", "from", from, sifp, rip, cc); 159 160 if (rip->rip_vers == 0) { 161 msglim(&bad_router, FROM_NADDR, 162 "RIP version 0, cmd %d, packet received from %s", 163 rip->rip_cmd, naddr_ntoa(FROM_NADDR)); 164 return; 165 } else if (rip->rip_vers > RIPv2) { 166 rip->rip_vers = RIPv2; 167 } 168 if (cc > OVER_MAXPACKETSIZE) { 169 msglim(&bad_router, FROM_NADDR, 170 "packet at least %d bytes too long received from %s", 171 cc-MAXPACKETSIZE, naddr_ntoa(FROM_NADDR)); 172 return; 173 } 174 175 n = rip->rip_nets; 176 lim = (struct netinfo *)((char*)rip + cc); 177 178 /* Notice authentication. 179 * As required by section 4.2 in RFC 1723, discard authenticated 180 * RIPv2 messages, but only if configured for that silliness. 181 * 182 * RIPv2 authentication is lame. Why authenticate queries? 183 * Why should a RIPv2 implementation with authentication disabled 184 * not be able to listen to RIPv2 packets with authenication, while 185 * RIPv1 systems will listen? Crazy! 186 */ 187 if (!auth_ok 188 && rip->rip_vers == RIPv2 189 && n < lim && n->n_family == RIP_AF_AUTH) { 190 msglim(&use_auth, FROM_NADDR, 191 "RIPv2 message with authentication from %s discarded", 192 naddr_ntoa(FROM_NADDR)); 193 return; 194 } 195 196 switch (rip->rip_cmd) { 197 case RIPCMD_REQUEST: 198 /* For mere requests, be a little sloppy about the source 199 */ 200 if (aifp == 0) 201 aifp = sifp; 202 203 /* Are we talking to ourself or a remote gateway? 204 */ 205 ifp1 = ifwithaddr(FROM_NADDR, 0, 1); 206 if (ifp1) { 207 if (ifp1->int_state & IS_REMOTE) { 208 /* remote gateway */ 209 aifp = ifp1; 210 if (check_remote(aifp)) { 211 aifp->int_act_time = now.tv_sec; 212 (void)if_ok(aifp, "remote "); 213 } 214 } else if (from->sin_port == htons(RIP_PORT)) { 215 trace_pkt(" discard our own RIP request"); 216 return; 217 } 218 } 219 220 /* did the request come from a router? 221 */ 222 if (from->sin_port == htons(RIP_PORT)) { 223 /* yes, ignore the request if RIP is off so that 224 * the router does not depend on us. 225 */ 226 if (rip_sock < 0 227 || (aifp != 0 228 && IS_RIP_OUT_OFF(aifp->int_state))) { 229 trace_pkt(" discard request while RIP off"); 230 return; 231 } 232 } 233 234 /* According to RFC 1723, we should ignore unathenticated 235 * queries. That is too silly to bother with. Sheesh! 236 * Are forwarding tables supposed to be secret, when 237 * a bad guy can infer them with test traffic? When RIP 238 * is still the most common router-discovery protocol 239 * and so hosts need to send queries that will be answered? 240 * What about `rtquery`? 241 * Maybe on firewalls you'd care, but not enough to 242 * give up the diagnostic facilities of remote probing. 243 */ 244 245 if (n >= lim) { 246 msglim(&bad_len, FROM_NADDR, "empty request from %s", 247 naddr_ntoa(FROM_NADDR)); 248 return; 249 } 250 if (cc%sizeof(*n) != sizeof(struct rip)%sizeof(*n)) { 251 msglim(&bad_len, FROM_NADDR, 252 "request of bad length (%d) from %s", 253 cc, naddr_ntoa(FROM_NADDR)); 254 } 255 256 if (rip->rip_vers == RIPv2 257 && (aifp == 0 || (aifp->int_state & IS_NO_RIPV1_OUT))) { 258 v12buf.buf->rip_vers = RIPv2; 259 /* If we have a secret but it is a cleartext secret, 260 * do not disclose our secret unless the other guy 261 * already knows it. 262 */ 263 ap = find_auth(aifp); 264 if (ap != 0 && ap->type == RIP_AUTH_PW 265 && n->n_family == RIP_AF_AUTH 266 && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) 267 ap = 0; 268 } else { 269 v12buf.buf->rip_vers = RIPv1; 270 ap = 0; 271 } 272 clr_ws_buf(&v12buf, ap); 273 274 do { 275 NTOHL(n->n_metric); 276 277 /* A single entry with family RIP_AF_UNSPEC and 278 * metric HOPCNT_INFINITY means "all routes". 279 * We respond to routers only if we are acting 280 * as a supplier, or to anyone other than a router 281 * (i.e. a query). 282 */ 283 if (n->n_family == RIP_AF_UNSPEC 284 && n->n_metric == HOPCNT_INFINITY) { 285 if (from->sin_port != htons(RIP_PORT)) { 286 /* Answer a query from a utility 287 * program with all we know. 288 */ 289 supply(from, aifp, OUT_QUERY, 0, 290 rip->rip_vers, ap != 0); 291 return; 292 } 293 294 /* A router trying to prime its tables. 295 * Filter the answer in the about same way 296 * broadcasts are filtered. 297 * 298 * Only answer a router if we are a supplier 299 * to keep an unwary host that is just starting 300 * from picking us as a router. Respond with 301 * RIPv1 instead of RIPv2 if that is what we 302 * are broadcasting on the interface to keep 303 * the remote router from getting the wrong 304 * initial idea of the routes we send. 305 */ 306 if (aifp == 0) { 307 trace_pkt("ignore distant router"); 308 return; 309 } 310 if (!supplier 311 || IS_RIP_OFF(aifp->int_state)) { 312 trace_pkt("ignore; not supplying"); 313 return; 314 } 315 316 supply(from, aifp, OUT_UNICAST, 0, 317 (aifp->int_state&IS_NO_RIPV1_OUT) 318 ? RIPv2 : RIPv1, 319 ap != 0); 320 return; 321 } 322 323 /* Ignore authentication */ 324 if (n->n_family == RIP_AF_AUTH) 325 continue; 326 327 if (n->n_family != RIP_AF_INET) { 328 msglim(&bad_router, FROM_NADDR, 329 "request from %s for unsupported (af" 330 " %d) %s", 331 naddr_ntoa(FROM_NADDR), 332 ntohs(n->n_family), 333 naddr_ntoa(n->n_dst)); 334 return; 335 } 336 337 /* We are being asked about a specific destination. 338 */ 339 dst = n->n_dst; 340 if (!check_dst(dst)) { 341 msglim(&bad_router, FROM_NADDR, 342 "bad queried destination %s from %s", 343 naddr_ntoa(dst), 344 naddr_ntoa(FROM_NADDR)); 345 return; 346 } 347 348 /* decide what mask was intended */ 349 if (rip->rip_vers == RIPv1 350 || 0 == (mask = ntohl(n->n_mask)) 351 || 0 != (ntohl(dst) & ~mask)) 352 mask = ripv1_mask_host(dst, aifp); 353 354 /* try to find the answer */ 355 rt = rtget(dst, mask); 356 if (!rt && dst != RIP_DEFAULT) 357 rt = rtfind(n->n_dst); 358 359 if (v12buf.buf->rip_vers != RIPv1) 360 v12buf.n->n_mask = mask; 361 if (rt == 0) { 362 /* we do not have the answer */ 363 v12buf.n->n_metric = HOPCNT_INFINITY; 364 } else { 365 /* we have the answer, so compute the 366 * right metric and next hop. 367 */ 368 v12buf.n->n_family = RIP_AF_INET; 369 v12buf.n->n_dst = dst; 370 v12buf.n->n_metric = (rt->rt_metric+1 371 + ((aifp!=0) 372 ? aifp->int_metric 373 : 1)); 374 if (v12buf.n->n_metric > HOPCNT_INFINITY) 375 v12buf.n->n_metric = HOPCNT_INFINITY; 376 if (v12buf.buf->rip_vers != RIPv1) { 377 v12buf.n->n_tag = rt->rt_tag; 378 v12buf.n->n_mask = mask; 379 if (aifp != 0 380 && on_net(rt->rt_gate, 381 aifp->int_net, 382 aifp->int_mask) 383 && rt->rt_gate != aifp->int_addr) 384 v12buf.n->n_nhop = rt->rt_gate; 385 } 386 } 387 HTONL(v12buf.n->n_metric); 388 389 /* Stop paying attention if we fill the output buffer. 390 */ 391 if (++v12buf.n >= v12buf.lim) 392 break; 393 } while (++n < lim); 394 395 /* Send the answer about specific routes. 396 */ 397 if (ap != 0 && ap->type == RIP_AUTH_MD5) 398 end_md5_auth(&v12buf, ap); 399 400 if (from->sin_port != htons(RIP_PORT)) { 401 /* query */ 402 (void)output(OUT_QUERY, from, aifp, 403 v12buf.buf, 404 ((char *)v12buf.n - (char*)v12buf.buf)); 405 } else if (supplier) { 406 (void)output(OUT_UNICAST, from, aifp, 407 v12buf.buf, 408 ((char *)v12buf.n - (char*)v12buf.buf)); 409 } else { 410 /* Only answer a router if we are a supplier 411 * to keep an unwary host that is just starting 412 * from picking us an a router. 413 */ 414 ; 415 } 416 return; 417 418 case RIPCMD_TRACEON: 419 case RIPCMD_TRACEOFF: 420 /* verify message came from a privileged port */ 421 if (ntohs(from->sin_port) > IPPORT_RESERVED) { 422 msglog("trace command from untrusted port on %s", 423 naddr_ntoa(FROM_NADDR)); 424 return; 425 } 426 if (aifp == 0) { 427 msglog("trace command from unknown router %s", 428 naddr_ntoa(FROM_NADDR)); 429 return; 430 } 431 if (rip->rip_cmd == RIPCMD_TRACEON) { 432 rip->rip_tracefile[cc-4] = '\0'; 433 set_tracefile((char*)rip->rip_tracefile, 434 "trace command: %s\n", 0); 435 } else { 436 trace_off("tracing turned off by %s\n", 437 naddr_ntoa(FROM_NADDR)); 438 } 439 return; 440 441 case RIPCMD_RESPONSE: 442 if (cc%sizeof(*n) != sizeof(struct rip)%sizeof(*n)) { 443 msglim(&bad_len, FROM_NADDR, 444 "response of bad length (%d) from %s", 445 cc, naddr_ntoa(FROM_NADDR)); 446 } 447 448 /* verify message came from a router */ 449 if (from->sin_port != ntohs(RIP_PORT)) { 450 msglim(&bad_router, FROM_NADDR, 451 " discard RIP response from unknown port" 452 " %d", from->sin_port); 453 return; 454 } 455 456 if (rip_sock < 0) { 457 trace_pkt(" discard response while RIP off"); 458 return; 459 } 460 461 /* Are we talking to ourself or a remote gateway? 462 */ 463 ifp1 = ifwithaddr(FROM_NADDR, 0, 1); 464 if (ifp1) { 465 if (ifp1->int_state & IS_REMOTE) { 466 /* remote gateway */ 467 aifp = ifp1; 468 if (check_remote(aifp)) { 469 aifp->int_act_time = now.tv_sec; 470 (void)if_ok(aifp, "remote "); 471 } 472 } else { 473 trace_pkt(" discard our own RIP response"); 474 return; 475 } 476 } 477 478 /* Accept routing packets from routers directly connected 479 * via broadcast or point-to-point networks, and from 480 * those listed in /etc/gateways. 481 */ 482 if (aifp == 0) { 483 msglim(&unk_router, FROM_NADDR, 484 " discard response from %s" 485 " via unexpected interface", 486 naddr_ntoa(FROM_NADDR)); 487 return; 488 } 489 if (IS_RIP_IN_OFF(aifp->int_state)) { 490 trace_pkt(" discard RIPv%d response" 491 " via disabled interface %s", 492 rip->rip_vers, aifp->int_name); 493 return; 494 } 495 496 if (n >= lim) { 497 msglim(&bad_len, FROM_NADDR, "empty response from %s", 498 naddr_ntoa(FROM_NADDR)); 499 return; 500 } 501 502 if (((aifp->int_state & IS_NO_RIPV1_IN) 503 && rip->rip_vers == RIPv1) 504 || ((aifp->int_state & IS_NO_RIPV2_IN) 505 && rip->rip_vers != RIPv1)) { 506 trace_pkt(" discard RIPv%d response", 507 rip->rip_vers); 508 return; 509 } 510 511 /* Ignore routes via dead interface. 512 */ 513 if (aifp->int_state & IS_BROKE) { 514 trace_pkt("%sdiscard response via broken interface %s", 515 aifp->int_name); 516 return; 517 } 518 519 /* If the interface cares, ignore bad routers. 520 * Trace but do not log this problem, because where it 521 * happens, it happens frequently. 522 */ 523 if (aifp->int_state & IS_DISTRUST) { 524 struct tgate *tg = tgates; 525 while (tg->tgate_addr != FROM_NADDR) { 526 tg = tg->tgate_next; 527 if (tg == 0) { 528 trace_pkt(" discard RIP response" 529 " from untrusted router %s", 530 naddr_ntoa(FROM_NADDR)); 531 return; 532 } 533 } 534 } 535 536 /* Authenticate the packet if we have a secret. 537 * If we do not have any secrets, ignore the error in 538 * RFC 1723 and accept it regardless. 539 */ 540 if (aifp->int_auth[0].type != RIP_AUTH_NONE 541 && rip->rip_vers != RIPv1 542 && !ck_passwd(aifp,rip,lim,FROM_NADDR,&use_auth)) 543 return; 544 545 do { 546 if (n->n_family == RIP_AF_AUTH) 547 continue; 548 549 NTOHL(n->n_metric); 550 dst = n->n_dst; 551 if (n->n_family != RIP_AF_INET 552 && (n->n_family != RIP_AF_UNSPEC 553 || dst != RIP_DEFAULT)) { 554 msglim(&bad_router, FROM_NADDR, 555 "route from %s to unsupported" 556 " address family=%d destination=%s", 557 naddr_ntoa(FROM_NADDR), 558 n->n_family, 559 naddr_ntoa(dst)); 560 continue; 561 } 562 if (!check_dst(dst)) { 563 msglim(&bad_router, FROM_NADDR, 564 "bad destination %s from %s", 565 naddr_ntoa(dst), 566 naddr_ntoa(FROM_NADDR)); 567 return; 568 } 569 if (n->n_metric == 0 570 || n->n_metric > HOPCNT_INFINITY) { 571 msglim(&bad_router, FROM_NADDR, 572 "bad metric %d from %s" 573 " for destination %s", 574 n->n_metric, 575 naddr_ntoa(FROM_NADDR), 576 naddr_ntoa(dst)); 577 return; 578 } 579 580 /* Notice the next-hop. 581 */ 582 gate = FROM_NADDR; 583 if (n->n_nhop != 0) { 584 if (rip->rip_vers == RIPv2) { 585 n->n_nhop = 0; 586 } else { 587 /* Use it only if it is valid. */ 588 if (on_net(n->n_nhop, 589 aifp->int_net, aifp->int_mask) 590 && check_dst(n->n_nhop)) { 591 gate = n->n_nhop; 592 } else { 593 msglim(&bad_nhop, FROM_NADDR, 594 "router %s to %s" 595 " has bad next hop %s", 596 naddr_ntoa(FROM_NADDR), 597 naddr_ntoa(dst), 598 naddr_ntoa(n->n_nhop)); 599 n->n_nhop = 0; 600 } 601 } 602 } 603 604 if (rip->rip_vers == RIPv1 605 || 0 == (mask = ntohl(n->n_mask))) { 606 mask = ripv1_mask_host(dst,aifp); 607 } else if ((ntohl(dst) & ~mask) != 0) { 608 msglim(&bad_mask, FROM_NADDR, 609 "router %s sent bad netmask" 610 " %#x with %s", 611 naddr_ntoa(FROM_NADDR), 612 mask, 613 naddr_ntoa(dst)); 614 continue; 615 } 616 if (rip->rip_vers == RIPv1) 617 n->n_tag = 0; 618 619 /* Adjust metric according to incoming interface.. 620 */ 621 n->n_metric += aifp->int_metric; 622 if (n->n_metric > HOPCNT_INFINITY) 623 n->n_metric = HOPCNT_INFINITY; 624 625 /* Recognize and ignore a default route we faked 626 * which is being sent back to us by a machine with 627 * broken split-horizon. 628 * Be a little more paranoid than that, and reject 629 * default routes with the same metric we advertised. 630 */ 631 if (aifp->int_d_metric != 0 632 && dst == RIP_DEFAULT 633 && n->n_metric >= aifp->int_d_metric) 634 continue; 635 636 /* We can receive aggregated RIPv2 routes that must 637 * be broken down before they are transmitted by 638 * RIPv1 via an interface on a subnet. 639 * We might also receive the same routes aggregated 640 * via other RIPv2 interfaces. 641 * This could cause duplicate routes to be sent on 642 * the RIPv1 interfaces. "Longest matching variable 643 * length netmasks" lets RIPv2 listeners understand, 644 * but breaking down the aggregated routes for RIPv1 645 * listeners can produce duplicate routes. 646 * 647 * Breaking down aggregated routes here bloats 648 * the daemon table, but does not hurt the kernel 649 * table, since routes are always aggregated for 650 * the kernel. 651 * 652 * Notice that this does not break down network 653 * routes corresponding to subnets. This is part 654 * of the defense against RS_NET_SYN. 655 */ 656 if (have_ripv1_out 657 && (((rt = rtget(dst,mask)) == 0 658 || !(rt->rt_state & RS_NET_SYN))) 659 && (v1_mask = ripv1_mask_net(dst,0)) > mask) { 660 ddst_h = v1_mask & -v1_mask; 661 i = (v1_mask & ~mask)/ddst_h; 662 if (i >= 511) { 663 /* Punt if we would have to generate 664 * an unreasonable number of routes. 665 */ 666 #ifdef DEBUG 667 msglog("accept %s from %s as 1" 668 " instead of %d routes", 669 addrname(dst,mask,0), 670 naddr_ntoa(FROM_NADDR), 671 i+1); 672 #endif 673 i = 0; 674 } else { 675 mask = v1_mask; 676 } 677 } else { 678 i = 0; 679 } 680 681 for (;;) { 682 input_route(aifp, FROM_NADDR, 683 dst, mask, gate, n); 684 if (i-- == 0) 685 break; 686 dst = htonl(ntohl(dst) + ddst_h); 687 } 688 } while (++n < lim); 689 break; 690 } 691 #undef FROM_NADDR 692 } 693 694 695 /* Process a single input route. 696 */ 697 static void 698 input_route(struct interface *ifp, 699 naddr from, 700 naddr dst, 701 naddr mask, 702 naddr gate, 703 struct netinfo *n) 704 { 705 int i; 706 struct rt_entry *rt; 707 struct rt_spare *rts, *rts0; 708 struct interface *ifp1; 709 time_t new_time; 710 711 712 /* See if the other guy is telling us to send our packets to him. 713 * Sometimes network routes arrive over a point-to-point link for 714 * the network containing the address(es) of the link. 715 * 716 * If our interface is broken, switch to using the other guy. 717 */ 718 ifp1 = ifwithaddr(dst, 1, 1); 719 if (ifp1 != 0 720 && (!(ifp1->int_state & IS_BROKE) 721 || (ifp1->int_state & IS_PASSIVE))) 722 return; 723 724 /* Look for the route in our table. 725 */ 726 rt = rtget(dst, mask); 727 728 /* Consider adding the route if we do not already have it. 729 */ 730 if (rt == 0) { 731 /* Ignore unknown routes being poisoned. 732 */ 733 if (n->n_metric == HOPCNT_INFINITY) 734 return; 735 736 /* Ignore the route if it points to us */ 737 if (n->n_nhop != 0 738 && 0 != ifwithaddr(n->n_nhop, 1, 0)) 739 return; 740 741 /* If something has not gone crazy and tried to fill 742 * our memory, accept the new route. 743 */ 744 if (total_routes < MAX_ROUTES) 745 rtadd(dst, mask, gate, from, n->n_metric, 746 n->n_tag, 0, ifp); 747 return; 748 } 749 750 /* We already know about the route. Consider this update. 751 * 752 * If (rt->rt_state & RS_NET_SYN), then this route 753 * is the same as a network route we have inferred 754 * for subnets we know, in order to tell RIPv1 routers 755 * about the subnets. 756 * 757 * It is impossible to tell if the route is coming 758 * from a distant RIPv2 router with the standard 759 * netmask because that router knows about the entire 760 * network, or if it is a round-about echo of a 761 * synthetic, RIPv1 network route of our own. 762 * The worst is that both kinds of routes might be 763 * received, and the bad one might have the smaller 764 * metric. Partly solve this problem by never 765 * aggregating into such a route. Also keep it 766 * around as long as the interface exists. 767 */ 768 769 rts0 = rt->rt_spares; 770 for (rts = rts0, i = NUM_SPARES; i != 0; i--, rts++) { 771 if (rts->rts_router == from) 772 break; 773 /* Note the worst slot to reuse, 774 * other than the current slot. 775 */ 776 if (rts0 == rt->rt_spares 777 || BETTER_LINK(rt, rts0, rts)) 778 rts0 = rts; 779 } 780 if (i != 0) { 781 /* Found the router 782 */ 783 int old_metric = rts->rts_metric; 784 785 /* Keep poisoned routes around only long enough to pass 786 * the poison on. Get a new timestamp for good routes. 787 */ 788 new_time =((old_metric == HOPCNT_INFINITY) 789 ? rts->rts_time 790 : now.tv_sec); 791 792 /* If this is an update for the router we currently prefer, 793 * then note it. 794 */ 795 if (i == NUM_SPARES) { 796 rtchange(rt,rt->rt_state, gate,rt->rt_router, 797 n->n_metric, n->n_tag, ifp, new_time, 0); 798 /* If the route got worse, check for something better. 799 */ 800 if (n->n_metric > old_metric) 801 rtswitch(rt, 0); 802 return; 803 } 804 805 /* This is an update for a spare route. 806 * Finished if the route is unchanged. 807 */ 808 if (rts->rts_gate == gate 809 && old_metric == n->n_metric 810 && rts->rts_tag == n->n_tag) { 811 rts->rts_time = new_time; 812 return; 813 } 814 815 } else { 816 /* The update is for a route we know about, 817 * but not from a familiar router. 818 * 819 * Ignore the route if it points to us. 820 */ 821 if (n->n_nhop != 0 822 && 0 != ifwithaddr(n->n_nhop, 1, 0)) 823 return; 824 825 rts = rts0; 826 827 /* Save the route as a spare only if it has 828 * a better metric than our worst spare. 829 * This also ignores poisoned routes (those 830 * received with metric HOPCNT_INFINITY). 831 */ 832 if (n->n_metric >= rts->rts_metric) 833 return; 834 835 new_time = now.tv_sec; 836 } 837 838 trace_upslot(rt, rts, gate, from, ifp, n->n_metric,n->n_tag, new_time); 839 840 rts->rts_gate = gate; 841 rts->rts_router = from; 842 rts->rts_metric = n->n_metric; 843 rts->rts_tag = n->n_tag; 844 rts->rts_time = new_time; 845 rts->rts_ifp = ifp; 846 847 /* try to switch to a better route */ 848 rtswitch(rt, rts); 849 } 850 851 852 static int /* 0 if bad */ 853 ck_passwd(struct interface *aifp, 854 struct rip *rip, 855 void *lim, 856 naddr from, 857 struct msg_limit *use_authp) 858 { 859 # define NA (rip->rip_auths) 860 struct netauth *na2; 861 struct auth *ap; 862 MD5_CTX md5_ctx; 863 u_char hash[RIP_AUTH_PW_LEN]; 864 int i; 865 866 867 if ((void *)NA >= lim || NA->a_family != RIP_AF_AUTH) { 868 msglim(use_authp, from, "missing password from %s", 869 naddr_ntoa(from)); 870 return 0; 871 } 872 873 /* accept any current (+/- 24 hours) password 874 */ 875 for (ap = aifp->int_auth, i = 0; i < MAX_AUTH_KEYS; i++, ap++) { 876 if (ap->type != NA->a_type 877 || (u_long)ap->start > (u_long)clk.tv_sec+DAY 878 || (u_long)ap->end+DAY < (u_long)clk.tv_sec) 879 continue; 880 881 if (NA->a_type == RIP_AUTH_PW) { 882 if (!bcmp(NA->au.au_pw, ap->key, RIP_AUTH_PW_LEN)) 883 return 1; 884 885 } else { 886 /* accept MD5 secret with the right key ID 887 */ 888 if (NA->au.a_md5.md5_keyid != ap->keyid) 889 continue; 890 891 na2 = (struct netauth *)((char *)(NA+1) 892 + NA->au.a_md5.md5_pkt_len); 893 if (NA->au.a_md5.md5_pkt_len % sizeof(*NA) != 0 894 || lim < (void *)(na2+1)) { 895 msglim(use_authp, from, 896 "bad MD5 RIP-II pkt length %d from %s", 897 NA->au.a_md5.md5_pkt_len, 898 naddr_ntoa(from)); 899 return 0; 900 } 901 MD5Init(&md5_ctx); 902 MD5Update(&md5_ctx, (u_char *)NA, 903 (char *)na2->au.au_pw - (char *)NA); 904 MD5Update(&md5_ctx, 905 (u_char *)ap->key, sizeof(ap->key)); 906 MD5Final(hash, &md5_ctx); 907 if (na2->a_family != RIP_AF_AUTH 908 || na2->a_type != 1 909 || NA->au.a_md5.md5_auth_len != RIP_AUTH_PW_LEN 910 || bcmp(hash, na2->au.au_pw, sizeof(hash))) 911 return 0; 912 return 1; 913 } 914 } 915 916 msglim(use_authp, from, "bad password from %s", 917 naddr_ntoa(from)); 918 return 0; 919 #undef NA 920 } 921