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