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