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