1 /* 2 * Copyright (c) 1989 Stephen Deering 3 * Copyright (c) 1992 Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Stephen Deering of Stanford University. 8 * 9 * %sccs.include.redist.c% 10 * 11 * @(#)ip_mroute.c 7.1 (Berkeley) 07/08/92 12 */ 13 14 /* 15 * Procedures for the kernel part of DVMRP, 16 * a Distance-Vector Multicast Routing Protocol. 17 * (See RFC-1075.) 18 * 19 * Written by David Waitzman, BBN Labs, August 1988. 20 * Modified by Steve Deering, Stanford, February 1989. 21 * 22 * MROUTING 1.1 23 */ 24 25 /* 26 * Copyright (c) 1992 Regents of the University of California. 27 * All rights reserved. 28 * 29 * %sccs.include.redist.c% 30 * 31 * @(#)ip_mroute.c 7.1 (Berkeley) 07/08/92 32 */ 33 #ifndef MROUTING 34 int ip_mrtproto; /* for netstat only */ 35 #else 36 37 #include "param.h" 38 #include "errno.h" 39 #include "ioctl.h" 40 #include "malloc.h" 41 #include "mbuf.h" 42 #include "protosw.h" 43 #include "socket.h" 44 #include "socketvar.h" 45 #include "time.h" 46 47 #include "../net/af.h" 48 #include "../net/if.h" 49 #include "../net/route.h" 50 #include "../net/raw_cb.h" 51 52 #include "in.h" 53 #include "in_systm.h" 54 #include "ip.h" 55 #include "in_pcb.h" 56 #include "in_var.h" 57 #include "ip_var.h" 58 59 #include "igmp.h" 60 #include "igmp_var.h" 61 #include "ip_mroute.h" 62 63 /* Static forwards */ 64 static int ip_mrouter_init __P((struct socket *)); 65 static int add_vif __P((struct vifctl *)); 66 static int del_vif __P((vifi_t *vifip)); 67 static int add_lgrp __P((struct lgrplctl *)); 68 static int del_lgrp __P((struct lgrplctl *)); 69 static int grplst_member __P((struct vif *, struct in_addr)); 70 static u_long nethash __P((struct in_addr in)); 71 static int add_mrt __P((struct mrtctl *)); 72 static int del_mrt __P((struct in_addr *)); 73 static struct mrt *mrtfind __P((struct in_addr)); 74 static void phyint_send __P((struct mbuf *, struct vif *)); 75 static void tunnel_send __P((struct mbuf *, struct vif *)); 76 77 #define INSIZ sizeof(struct in_addr) 78 #define same(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), INSIZ) == 0) 79 #define satosin(sa) ((struct sockaddr_in *)(sa)) 80 81 /* 82 * Globals. All but ip_mrouter and ip_mrtproto could be static, 83 * except for netstat or debugging purposes. 84 */ 85 struct socket *ip_mrouter = NULL; 86 int ip_mrtproto = IGMP_DVMRP; /* for netstat only */ 87 88 struct mrt *mrttable[MRTHASHSIZ]; 89 struct vif viftable[MAXVIFS]; 90 struct mrtstat mrtstat; 91 92 /* 93 * Private variables. 94 */ 95 static vifi_t numvifs = 0; 96 static struct mrt *cached_mrt = NULL; 97 static u_long cached_origin; 98 static u_long cached_originmask; 99 100 /* 101 * Handle DVMRP setsockopt commands to modify the multicast routing tables. 102 */ 103 int 104 ip_mrouter_cmd(cmd, so, m) 105 register int cmd; 106 register struct socket *so; 107 register struct mbuf *m; 108 { 109 register int error = 0; 110 111 if (cmd != DVMRP_INIT && so != ip_mrouter) 112 error = EACCES; 113 else switch (cmd) { 114 115 case DVMRP_INIT: 116 error = ip_mrouter_init(so); 117 break; 118 119 case DVMRP_DONE: 120 error = ip_mrouter_done(); 121 break; 122 123 case DVMRP_ADD_VIF: 124 if (m == NULL || m->m_len < sizeof(struct vifctl)) 125 error = EINVAL; 126 else 127 error = add_vif(mtod(m, struct vifctl *)); 128 break; 129 130 case DVMRP_DEL_VIF: 131 if (m == NULL || m->m_len < sizeof(short)) 132 error = EINVAL; 133 else 134 error = del_vif(mtod(m, vifi_t *)); 135 break; 136 137 case DVMRP_ADD_LGRP: 138 if (m == NULL || m->m_len < sizeof(struct lgrplctl)) 139 error = EINVAL; 140 else 141 error = add_lgrp(mtod(m, struct lgrplctl *)); 142 break; 143 144 case DVMRP_DEL_LGRP: 145 if (m == NULL || m->m_len < sizeof(struct lgrplctl)) 146 error = EINVAL; 147 else 148 error = del_lgrp(mtod(m, struct lgrplctl *)); 149 break; 150 151 case DVMRP_ADD_MRT: 152 if (m == NULL || m->m_len < sizeof(struct mrtctl)) 153 error = EINVAL; 154 else 155 error = add_mrt(mtod(m, struct mrtctl *)); 156 break; 157 158 case DVMRP_DEL_MRT: 159 if (m == NULL || m->m_len < sizeof(struct in_addr)) 160 error = EINVAL; 161 else 162 error = del_mrt(mtod(m, struct in_addr *)); 163 break; 164 165 default: 166 error = EOPNOTSUPP; 167 break; 168 } 169 return (error); 170 } 171 172 /* 173 * Enable multicast routing 174 */ 175 static int 176 ip_mrouter_init(so) 177 register struct socket *so; 178 { 179 if (so->so_type != SOCK_RAW || 180 so->so_proto->pr_protocol != IPPROTO_IGMP) 181 return (EOPNOTSUPP); 182 183 if (ip_mrouter != NULL) 184 return (EADDRINUSE); 185 186 ip_mrouter = so; 187 188 return (0); 189 } 190 191 /* 192 * Disable multicast routing 193 */ 194 int 195 ip_mrouter_done() 196 { 197 register vifi_t vifi; 198 register int i; 199 register struct ifnet *ifp; 200 register int s; 201 struct ifreq ifr; 202 203 s = splnet(); 204 205 /* 206 * For each phyint in use, free its local group list and 207 * disable promiscuous reception of all IP multicasts. 208 */ 209 for (vifi = 0; vifi < numvifs; vifi++) { 210 if (viftable[vifi].v_lcl_addr.s_addr != 0 && 211 !(viftable[vifi].v_flags & VIFF_TUNNEL)) { 212 if (viftable[vifi].v_lcl_grps) 213 free(viftable[vifi].v_lcl_grps, M_MRTABLE); 214 satosin(&ifr.ifr_addr)->sin_family = AF_INET; 215 satosin(&ifr.ifr_addr)->sin_addr.s_addr = INADDR_ANY; 216 ifp = viftable[vifi].v_ifp; 217 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr); 218 } 219 } 220 bzero((caddr_t)viftable, sizeof(viftable)); 221 numvifs = 0; 222 223 /* 224 * Free any multicast route entries. 225 */ 226 for (i = 0; i < MRTHASHSIZ; i++) 227 if (mrttable[i]) 228 free(mrttable[i], M_MRTABLE); 229 bzero((caddr_t)mrttable, sizeof(mrttable)); 230 cached_mrt = NULL; 231 232 ip_mrouter = NULL; 233 234 splx(s); 235 return (0); 236 } 237 238 /* 239 * Add a vif to the vif table 240 */ 241 static int 242 add_vif(vifcp) 243 register struct vifctl *vifcp; 244 { 245 register struct vif *vifp = viftable + vifcp->vifc_vifi; 246 register struct ifaddr *ifa; 247 register struct ifnet *ifp; 248 struct ifreq ifr; 249 register int error, s; 250 static struct sockaddr_in sin = { sizeof(sin), AF_INET }; 251 252 if (vifcp->vifc_vifi >= MAXVIFS) 253 return (EINVAL); 254 if (vifp->v_lcl_addr.s_addr != 0) 255 return (EADDRINUSE); 256 257 /* Find the interface with an address in AF_INET family */ 258 sin.sin_addr = vifcp->vifc_lcl_addr; 259 ifa = ifa_ifwithaddr((struct sockaddr *)&sin); 260 if (ifa == 0) 261 return (EADDRNOTAVAIL); 262 263 s = splnet(); 264 265 if (vifcp->vifc_flags & VIFF_TUNNEL) 266 vifp->v_rmt_addr = vifcp->vifc_rmt_addr; 267 else { 268 /* Make sure the interface supports multicast */ 269 ifp = ifa->ifa_ifp; 270 if ((ifp->if_flags & IFF_MULTICAST) == 0) { 271 splx(s); 272 return (EOPNOTSUPP); 273 } 274 /* 275 * Enable promiscuous reception of all IP multicasts 276 * from the interface. 277 */ 278 satosin(&ifr.ifr_addr)->sin_family = AF_INET; 279 satosin(&ifr.ifr_addr)->sin_addr.s_addr = INADDR_ANY; 280 error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, (caddr_t)&ifr); 281 if (error) { 282 splx(s); 283 return (error); 284 } 285 } 286 287 vifp->v_flags = vifcp->vifc_flags; 288 vifp->v_threshold = vifcp->vifc_threshold; 289 vifp->v_lcl_addr = vifcp->vifc_lcl_addr; 290 vifp->v_ifp = ifa->ifa_ifp; 291 292 /* Adjust numvifs up if the vifi is higher than numvifs */ 293 if (numvifs <= vifcp->vifc_vifi) 294 numvifs = vifcp->vifc_vifi + 1; 295 296 splx(s); 297 return (0); 298 } 299 300 /* 301 * Delete a vif from the vif table 302 */ 303 static int 304 del_vif(vifip) 305 register vifi_t *vifip; 306 { 307 register struct vif *vifp = viftable + *vifip; 308 register vifi_t vifi; 309 register struct ifnet *ifp; 310 register int s; 311 struct ifreq ifr; 312 313 if (*vifip >= numvifs) 314 return (EINVAL); 315 if (vifp->v_lcl_addr.s_addr == 0) 316 return (EADDRNOTAVAIL); 317 318 s = splnet(); 319 320 if (!(vifp->v_flags & VIFF_TUNNEL)) { 321 if (vifp->v_lcl_grps) 322 free(vifp->v_lcl_grps, M_MRTABLE); 323 satosin(&ifr.ifr_addr)->sin_family = AF_INET; 324 satosin(&ifr.ifr_addr)->sin_addr.s_addr = INADDR_ANY; 325 ifp = vifp->v_ifp; 326 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, (caddr_t)&ifr); 327 } 328 329 bzero((caddr_t)vifp, sizeof (*vifp)); 330 331 /* Adjust numvifs down */ 332 for (vifi = numvifs - 1; vifi >= 0; vifi--) 333 if (viftable[vifi].v_lcl_addr.s_addr != 0) 334 break; 335 numvifs = vifi + 1; 336 337 splx(s); 338 return (0); 339 } 340 341 /* 342 * Add the multicast group in the lgrpctl to the list of local multicast 343 * group memberships associated with the vif indexed by gcp->lgc_vifi. 344 */ 345 static int 346 add_lgrp(gcp) 347 register struct lgrplctl *gcp; 348 { 349 register struct vif *vifp; 350 register int s; 351 352 if (gcp->lgc_vifi >= numvifs) 353 return (EINVAL); 354 355 vifp = viftable + gcp->lgc_vifi; 356 if (vifp->v_lcl_addr.s_addr == 0 || (vifp->v_flags & VIFF_TUNNEL)) 357 return (EADDRNOTAVAIL); 358 359 /* If not enough space in existing list, allocate a larger one */ 360 s = splnet(); 361 if (vifp->v_lcl_grps_n + 1 >= vifp->v_lcl_grps_max) { 362 register int num; 363 register struct in_addr *ip; 364 365 num = vifp->v_lcl_grps_max; 366 if (num <= 0) 367 num = 32; /* initial number */ 368 else 369 num += num; /* double last number */ 370 ip = (struct in_addr *)malloc(num * sizeof(*ip), 371 M_MRTABLE, M_NOWAIT); 372 if (ip == NULL) { 373 splx(s); 374 return (ENOBUFS); 375 } 376 377 bzero((caddr_t)ip, num * sizeof(*ip)); /* XXX paranoid */ 378 bcopy((caddr_t)vifp->v_lcl_grps, (caddr_t)ip, 379 vifp->v_lcl_grps_n * sizeof(*ip)); 380 381 vifp->v_lcl_grps_max = num; 382 if (vifp->v_lcl_grps) 383 free(vifp->v_lcl_grps, M_MRTABLE); 384 vifp->v_lcl_grps = ip; 385 386 splx(s); 387 } 388 389 vifp->v_lcl_grps[vifp->v_lcl_grps_n++] = gcp->lgc_gaddr; 390 391 if (gcp->lgc_gaddr.s_addr == vifp->v_cached_group) 392 vifp->v_cached_result = 1; 393 394 splx(s); 395 return (0); 396 } 397 398 /* 399 * Delete the the local multicast group associated with the vif 400 * indexed by gcp->lgc_vifi. 401 */ 402 403 static int 404 del_lgrp(gcp) 405 register struct lgrplctl *gcp; 406 { 407 register struct vif *vifp; 408 register int i, error, s; 409 410 if (gcp->lgc_vifi >= numvifs) 411 return (EINVAL); 412 vifp = viftable + gcp->lgc_vifi; 413 if (vifp->v_lcl_addr.s_addr == 0 || (vifp->v_flags & VIFF_TUNNEL)) 414 return (EADDRNOTAVAIL); 415 416 s = splnet(); 417 418 if (gcp->lgc_gaddr.s_addr == vifp->v_cached_group) 419 vifp->v_cached_result = 0; 420 421 error = EADDRNOTAVAIL; 422 for (i = 0; i < vifp->v_lcl_grps_n; ++i) 423 if (same(&gcp->lgc_gaddr, &vifp->v_lcl_grps[i])) { 424 error = 0; 425 vifp->v_lcl_grps_n--; 426 bcopy((caddr_t)&vifp->v_lcl_grps[i + 1], 427 (caddr_t)&vifp->v_lcl_grps[i], 428 (vifp->v_lcl_grps_n - i) * sizeof(struct in_addr)); 429 error = 0; 430 break; 431 } 432 433 splx(s); 434 return (error); 435 } 436 437 /* 438 * Return 1 if gaddr is a member of the local group list for vifp. 439 */ 440 static int 441 grplst_member(vifp, gaddr) 442 register struct vif *vifp; 443 struct in_addr gaddr; 444 { 445 register int i, s; 446 register u_long addr; 447 448 mrtstat.mrts_grp_lookups++; 449 450 addr = gaddr.s_addr; 451 if (addr == vifp->v_cached_group) 452 return (vifp->v_cached_result); 453 454 mrtstat.mrts_grp_misses++; 455 456 for (i = 0; i < vifp->v_lcl_grps_n; ++i) 457 if (addr == vifp->v_lcl_grps[i].s_addr) { 458 s = splnet(); 459 vifp->v_cached_group = addr; 460 vifp->v_cached_result = 1; 461 splx(s); 462 return (1); 463 } 464 s = splnet(); 465 vifp->v_cached_group = addr; 466 vifp->v_cached_result = 0; 467 splx(s); 468 return (0); 469 } 470 471 /* 472 * A simple hash function: returns MRTHASHMOD of the low-order octet of 473 * the argument's network or subnet number. 474 */ 475 static u_long 476 nethash(in) 477 struct in_addr in; 478 { 479 register u_long n; 480 481 n = in_netof(in); 482 while ((n & 0xff) == 0) 483 n >>= 8; 484 return (MRTHASHMOD(n)); 485 } 486 487 /* 488 * Add an mrt entry 489 */ 490 static int 491 add_mrt(mrtcp) 492 register struct mrtctl *mrtcp; 493 { 494 struct mrt *rt; 495 u_long hash; 496 int s; 497 498 if (rt = mrtfind(mrtcp->mrtc_origin)) { 499 /* Just update the route */ 500 s = splnet(); 501 rt->mrt_parent = mrtcp->mrtc_parent; 502 VIFM_COPY(mrtcp->mrtc_children, rt->mrt_children); 503 VIFM_COPY(mrtcp->mrtc_leaves, rt->mrt_leaves); 504 splx(s); 505 return (0); 506 } 507 508 s = splnet(); 509 510 rt = (struct mrt *)malloc(sizeof(*rt), M_MRTABLE, M_NOWAIT); 511 if (rt == NULL) { 512 splx(s); 513 return (ENOBUFS); 514 } 515 516 /* 517 * insert new entry at head of hash chain 518 */ 519 rt->mrt_origin = mrtcp->mrtc_origin; 520 rt->mrt_originmask = mrtcp->mrtc_originmask; 521 rt->mrt_parent = mrtcp->mrtc_parent; 522 VIFM_COPY(mrtcp->mrtc_children, rt->mrt_children); 523 VIFM_COPY(mrtcp->mrtc_leaves, rt->mrt_leaves); 524 /* link into table */ 525 hash = nethash(mrtcp->mrtc_origin); 526 rt->mrt_next = mrttable[hash]; 527 mrttable[hash] = rt; 528 529 splx(s); 530 return (0); 531 } 532 533 /* 534 * Delete an mrt entry 535 */ 536 static int 537 del_mrt(origin) 538 register struct in_addr *origin; 539 { 540 register struct mrt *rt, *prev_rt; 541 register u_long hash = nethash(*origin); 542 register int s; 543 544 for (prev_rt = rt = mrttable[hash]; rt; prev_rt = rt, rt = rt->mrt_next) 545 if (origin->s_addr == rt->mrt_origin.s_addr) 546 break; 547 if (!rt) 548 return (ESRCH); 549 550 s = splnet(); 551 552 if (rt == cached_mrt) 553 cached_mrt = NULL; 554 555 if (prev_rt == rt) 556 mrttable[hash] = rt->mrt_next; 557 else 558 prev_rt->mrt_next = rt->mrt_next; 559 free(rt, M_MRTABLE); 560 561 splx(s); 562 return (0); 563 } 564 565 /* 566 * Find a route for a given origin IP address. 567 */ 568 static struct mrt * 569 mrtfind(origin) 570 struct in_addr origin; 571 { 572 register struct mrt *rt; 573 register u_int hash; 574 register int s; 575 576 mrtstat.mrts_mrt_lookups++; 577 578 if (cached_mrt != NULL && 579 (origin.s_addr & cached_originmask) == cached_origin) 580 return (cached_mrt); 581 582 mrtstat.mrts_mrt_misses++; 583 584 hash = nethash(origin); 585 for (rt = mrttable[hash]; rt; rt = rt->mrt_next) 586 if ((origin.s_addr & rt->mrt_originmask.s_addr) == 587 rt->mrt_origin.s_addr) { 588 s = splnet(); 589 cached_mrt = rt; 590 cached_origin = rt->mrt_origin.s_addr; 591 cached_originmask = rt->mrt_originmask.s_addr; 592 splx(s); 593 return (rt); 594 } 595 return (NULL); 596 } 597 598 /* 599 * IP multicast forwarding function. This function assumes that the packet 600 * pointed to by "ip" has arrived on (or is about to be sent to) the interface 601 * pointed to by "ifp", and the packet is to be relayed to other networks 602 * that have members of the packet's destination IP multicast group. 603 * 604 * The packet is returned unscathed to the caller, unless it is tunneled 605 * or erroneous, in which case a non-zero return value tells the caller to 606 * discard it. 607 */ 608 609 #define IP_HDR_LEN 20 /* # bytes of fixed IP header (excluding options) */ 610 #define TUNNEL_LEN 12 /* # bytes of IP option for tunnel encapsulation */ 611 612 int 613 ip_mforward(m, ifp) 614 register struct mbuf *m; 615 register struct ifnet *ifp; 616 { 617 register struct ip *ip = mtod(m, struct ip *); 618 register struct mrt *rt; 619 register struct vif *vifp; 620 register int vifi; 621 register u_char *ipoptions; 622 u_long tunnel_src; 623 624 if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 || 625 (ipoptions = (u_char *)(ip + 1))[1] != IPOPT_LSRR ) { 626 /* 627 * Packet arrived via a physical interface. 628 */ 629 tunnel_src = 0; 630 } else { 631 /* 632 * Packet arrived through a tunnel. 633 * 634 * A tunneled packet has a single NOP option and a 635 * two-element loose-source-and-record-route (LSRR) 636 * option immediately following the fixed-size part of 637 * the IP header. At this point in processing, the IP 638 * header should contain the following IP addresses: 639 * 640 * original source - in the source address field 641 * destination group - in the destination address field 642 * remote tunnel end-point - in the first element of LSRR 643 * one of this host's addrs - in the second element of LSRR 644 * 645 * NOTE: RFC-1075 would have the original source and 646 * remote tunnel end-point addresses swapped. However, 647 * that could cause delivery of ICMP error messages to 648 * innocent applications on intermediate routing 649 * hosts! Therefore, we hereby change the spec. 650 */ 651 652 /* 653 * Verify that the tunnel options are well-formed. 654 */ 655 if (ipoptions[0] != IPOPT_NOP || 656 ipoptions[2] != 11 || /* LSRR option length */ 657 ipoptions[3] != 12 || /* LSRR address pointer */ 658 (tunnel_src = *(u_long *)(&ipoptions[4])) == 0) { 659 mrtstat.mrts_bad_tunnel++; 660 return (1); 661 } 662 663 /* 664 * Delete the tunnel options from the packet. 665 */ 666 ovbcopy((caddr_t)(ipoptions + TUNNEL_LEN), (caddr_t)ipoptions, 667 (unsigned)(m->m_len - (IP_HDR_LEN + TUNNEL_LEN))); 668 m->m_len -= TUNNEL_LEN; 669 ip->ip_len -= TUNNEL_LEN; 670 ip->ip_hl -= TUNNEL_LEN >> 2; 671 } 672 673 /* 674 * Don't forward a packet with time-to-live of zero or one, 675 * or a packet destined to a local-only group. 676 */ 677 if (ip->ip_ttl <= 1 || 678 ntohl(ip->ip_dst.s_addr) <= INADDR_MAX_LOCAL_GROUP) 679 return ((int)tunnel_src); 680 681 /* 682 * Don't forward if we don't have a route for the packet's origin. 683 */ 684 if (!(rt = mrtfind(ip->ip_src))) { 685 mrtstat.mrts_no_route++; 686 return ((int)tunnel_src); 687 } 688 689 /* 690 * Don't forward if it didn't arrive from the parent vif for its origin. 691 */ 692 vifi = rt->mrt_parent; 693 if (tunnel_src == 0 ) { 694 if ((viftable[vifi].v_flags & VIFF_TUNNEL) || 695 viftable[vifi].v_ifp != ifp ) 696 return ((int)tunnel_src); 697 } else { 698 if (!(viftable[vifi].v_flags & VIFF_TUNNEL) || 699 viftable[vifi].v_rmt_addr.s_addr != tunnel_src ) 700 return ((int)tunnel_src); 701 } 702 703 /* 704 * For each vif, decide if a copy of the packet should be forwarded. 705 * Forward if: 706 * - the ttl exceeds the vif's threshold AND 707 * - the vif is a child in the origin's route AND 708 * - ( the vif is not a leaf in the origin's route OR 709 * the destination group has members on the vif ) 710 * 711 * (This might be speeded up with some sort of cache -- someday.) 712 */ 713 for (vifp = viftable, vifi = 0; vifi < numvifs; vifp++, vifi++) { 714 if (ip->ip_ttl > vifp->v_threshold && 715 VIFM_ISSET(vifi, rt->mrt_children) && 716 (!VIFM_ISSET(vifi, rt->mrt_leaves) || 717 grplst_member(vifp, ip->ip_dst))) { 718 if (vifp->v_flags & VIFF_TUNNEL) 719 tunnel_send(m, vifp); 720 else 721 phyint_send(m, vifp); 722 } 723 } 724 725 return ((int)tunnel_src); 726 } 727 728 static void 729 phyint_send(m, vifp) 730 register struct mbuf *m; 731 register struct vif *vifp; 732 { 733 register struct ip *ip = mtod(m, struct ip *); 734 register struct mbuf *mb_copy; 735 register struct ip_moptions *imo; 736 register int error; 737 struct ip_moptions simo; 738 739 mb_copy = m_copy(m, 0, M_COPYALL); 740 if (mb_copy == NULL) 741 return; 742 743 imo = &simo; 744 imo->imo_multicast_ifp = vifp->v_ifp; 745 imo->imo_multicast_ttl = ip->ip_ttl - 1; 746 imo->imo_multicast_loop = 1; 747 748 error = ip_output(mb_copy, NULL, NULL, IP_FORWARDING, imo); 749 } 750 751 static void 752 tunnel_send(m, vifp) 753 register struct mbuf *m; 754 register struct vif *vifp; 755 { 756 register struct ip *ip = mtod(m, struct ip *); 757 register struct mbuf *mb_copy, *mb_opts; 758 register struct ip *ip_copy; 759 register int error; 760 register u_char *cp; 761 762 /* 763 * Make sure that adding the tunnel options won't exceed the 764 * maximum allowed number of option bytes. 765 */ 766 if (ip->ip_hl > (60 - TUNNEL_LEN) >> 2) { 767 mrtstat.mrts_cant_tunnel++; 768 return; 769 } 770 771 mb_copy = m_copy(m, 0, M_COPYALL); 772 if (mb_copy == NULL) 773 return; 774 ip_copy = mtod(mb_copy, struct ip *); 775 ip_copy->ip_ttl--; 776 ip_copy->ip_dst = vifp->v_rmt_addr; /* remote tunnel end-point */ 777 /* 778 * Adjust the ip header length to account for the tunnel options. 779 */ 780 ip_copy->ip_hl += TUNNEL_LEN >> 2; 781 ip_copy->ip_len += TUNNEL_LEN; 782 MGETHDR(mb_opts, M_DONTWAIT, MT_HEADER); 783 if (mb_opts == NULL) { 784 m_freem(mb_copy); 785 return; 786 } 787 /* 788 * 'Delete' the base ip header from the mb_copy chain 789 */ 790 mb_copy->m_len -= IP_HDR_LEN; 791 mb_copy->m_data += IP_HDR_LEN; 792 /* 793 * Make mb_opts be the new head of the packet chain. 794 * Any options of the packet were left in the old packet chain head 795 */ 796 mb_opts->m_next = mb_copy; 797 mb_opts->m_len = IP_HDR_LEN + TUNNEL_LEN; 798 mb_opts->m_data += MSIZE - mb_opts->m_len; 799 /* 800 * Copy the base ip header from the mb_copy chain to the new head mbuf 801 */ 802 bcopy((caddr_t)ip_copy, mtod(mb_opts, caddr_t), IP_HDR_LEN); 803 /* 804 * Add the NOP and LSRR after the base ip header 805 */ 806 cp = mtod(mb_opts, u_char *) + IP_HDR_LEN; 807 *cp++ = IPOPT_NOP; 808 *cp++ = IPOPT_LSRR; 809 *cp++ = 11; /* LSRR option length */ 810 *cp++ = 8; /* LSSR pointer to second element */ 811 *(u_long*)cp = vifp->v_lcl_addr.s_addr; /* local tunnel end-point */ 812 cp += 4; 813 *(u_long*)cp = ip->ip_dst.s_addr; /* destination group */ 814 815 error = ip_output(mb_opts, NULL, NULL, IP_FORWARDING, NULL); 816 } 817 #endif 818