1 /* $NetBSD: ip_output.c,v 1.19 1994/06/29 06:38:27 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1988, 1990, 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. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 36 */ 37 38 #include <sys/param.h> 39 #include <sys/malloc.h> 40 #include <sys/mbuf.h> 41 #include <sys/errno.h> 42 #include <sys/protosw.h> 43 #include <sys/socket.h> 44 #include <sys/socketvar.h> 45 46 #include <net/if.h> 47 #include <net/route.h> 48 49 #include <netinet/in.h> 50 #include <netinet/in_systm.h> 51 #include <netinet/ip.h> 52 #include <netinet/in_pcb.h> 53 #include <netinet/in_var.h> 54 #include <netinet/ip_var.h> 55 56 #ifdef vax 57 #include <machine/mtpr.h> 58 #endif 59 60 static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *)); 61 static void ip_mloopback 62 __P((struct ifnet *, struct mbuf *, struct sockaddr_in *)); 63 64 /* 65 * IP output. The packet in mbuf chain m contains a skeletal IP 66 * header (with len, off, ttl, proto, tos, src, dst). 67 * The mbuf chain containing the packet will be freed. 68 * The mbuf opt, if present, will not be freed. 69 */ 70 int 71 ip_output(m0, opt, ro, flags, imo) 72 struct mbuf *m0; 73 struct mbuf *opt; 74 struct route *ro; 75 int flags; 76 struct ip_moptions *imo; 77 { 78 register struct ip *ip, *mhip; 79 register struct ifnet *ifp; 80 register struct mbuf *m = m0; 81 register int hlen = sizeof (struct ip); 82 int len, off, error = 0; 83 struct route iproute; 84 struct sockaddr_in *dst; 85 struct in_ifaddr *ia; 86 87 #ifdef DIAGNOSTIC 88 if ((m->m_flags & M_PKTHDR) == 0) 89 panic("ip_output no HDR"); 90 #endif 91 if (opt) { 92 m = ip_insertoptions(m, opt, &len); 93 hlen = len; 94 } 95 ip = mtod(m, struct ip *); 96 /* 97 * Fill in IP header. 98 */ 99 if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) { 100 ip->ip_v = IPVERSION; 101 ip->ip_off &= IP_DF; 102 ip->ip_id = htons(ip_id++); 103 ip->ip_hl = hlen >> 2; 104 ipstat.ips_localout++; 105 } else { 106 hlen = ip->ip_hl << 2; 107 } 108 /* 109 * Route packet. 110 */ 111 if (ro == 0) { 112 ro = &iproute; 113 bzero((caddr_t)ro, sizeof (*ro)); 114 } 115 dst = (struct sockaddr_in *)&ro->ro_dst; 116 /* 117 * If there is a cached route, 118 * check that it is to the same destination 119 * and is still up. If not, free it and try again. 120 */ 121 if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || 122 dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { 123 RTFREE(ro->ro_rt); 124 ro->ro_rt = (struct rtentry *)0; 125 } 126 if (ro->ro_rt == 0) { 127 dst->sin_family = AF_INET; 128 dst->sin_len = sizeof(*dst); 129 dst->sin_addr = ip->ip_dst; 130 } 131 /* 132 * If routing to interface only, 133 * short circuit routing lookup. 134 */ 135 #define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) 136 #define sintosa(sin) ((struct sockaddr *)(sin)) 137 if (flags & IP_ROUTETOIF) { 138 if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 && 139 (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) { 140 ipstat.ips_noroute++; 141 error = ENETUNREACH; 142 goto bad; 143 } 144 ifp = ia->ia_ifp; 145 ip->ip_ttl = 1; 146 } else { 147 if (ro->ro_rt == 0) 148 rtalloc(ro); 149 if (ro->ro_rt == 0) { 150 ipstat.ips_noroute++; 151 error = EHOSTUNREACH; 152 goto bad; 153 } 154 ia = ifatoia(ro->ro_rt->rt_ifa); 155 ifp = ro->ro_rt->rt_ifp; 156 ro->ro_rt->rt_use++; 157 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 158 dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; 159 } 160 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { 161 struct in_multi *inm; 162 extern struct ifnet loif; 163 164 m->m_flags |= M_MCAST; 165 /* 166 * IP destination address is multicast. Make sure "dst" 167 * still points to the address in "ro". (It may have been 168 * changed to point to a gateway address, above.) 169 */ 170 dst = (struct sockaddr_in *)&ro->ro_dst; 171 /* 172 * See if the caller provided any multicast options 173 */ 174 if (imo != NULL) { 175 ip->ip_ttl = imo->imo_multicast_ttl; 176 if (imo->imo_multicast_ifp != NULL) 177 ifp = imo->imo_multicast_ifp; 178 } else 179 ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL; 180 /* 181 * Confirm that the outgoing interface supports multicast. 182 */ 183 if ((ifp->if_flags & IFF_MULTICAST) == 0) { 184 ipstat.ips_noroute++; 185 error = ENETUNREACH; 186 goto bad; 187 } 188 /* 189 * If source address not specified yet, use address 190 * of outgoing interface. 191 */ 192 if (ip->ip_src.s_addr == INADDR_ANY) { 193 register struct in_ifaddr *ia; 194 195 for (ia = in_ifaddr; ia; ia = ia->ia_next) 196 if (ia->ia_ifp == ifp) { 197 ip->ip_src = IA_SIN(ia)->sin_addr; 198 break; 199 } 200 } 201 202 IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm); 203 if (inm != NULL && 204 (imo == NULL || imo->imo_multicast_loop)) { 205 /* 206 * If we belong to the destination multicast group 207 * on the outgoing interface, and the caller did not 208 * forbid loopback, loop back a copy. 209 */ 210 ip_mloopback(ifp, m, dst); 211 } 212 #ifdef MROUTING 213 else { 214 /* 215 * If we are acting as a multicast router, perform 216 * multicast forwarding as if the packet had just 217 * arrived on the interface to which we are about 218 * to send. The multicast forwarding function 219 * recursively calls this function, using the 220 * IP_FORWARDING flag to prevent infinite recursion. 221 * 222 * Multicasts that are looped back by ip_mloopback(), 223 * above, will be forwarded by the ip_input() routine, 224 * if necessary. 225 */ 226 extern struct socket *ip_mrouter; 227 if (ip_mrouter && (flags & IP_FORWARDING) == 0) { 228 if (ip_mforward(m, ifp) != 0) { 229 m_freem(m); 230 goto done; 231 } 232 } 233 } 234 #endif 235 /* 236 * Multicasts with a time-to-live of zero may be looped- 237 * back, above, but must not be transmitted on a network. 238 * Also, multicasts addressed to the loopback interface 239 * are not sent -- the above call to ip_mloopback() will 240 * loop back a copy if this host actually belongs to the 241 * destination group on the loopback interface. 242 */ 243 if (ip->ip_ttl == 0 || ifp == &loif) { 244 m_freem(m); 245 goto done; 246 } 247 248 goto sendit; 249 } 250 #ifndef notdef 251 /* 252 * If source address not specified yet, use address 253 * of outgoing interface. 254 */ 255 if (ip->ip_src.s_addr == INADDR_ANY) 256 ip->ip_src = IA_SIN(ia)->sin_addr; 257 #endif 258 /* 259 * Look for broadcast address and 260 * and verify user is allowed to send 261 * such a packet. 262 */ 263 if (in_broadcast(dst->sin_addr, ifp)) { 264 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 265 error = EADDRNOTAVAIL; 266 goto bad; 267 } 268 if ((flags & IP_ALLOWBROADCAST) == 0) { 269 error = EACCES; 270 goto bad; 271 } 272 /* don't allow broadcast messages to be fragmented */ 273 if ((u_short)ip->ip_len > ifp->if_mtu) { 274 error = EMSGSIZE; 275 goto bad; 276 } 277 m->m_flags |= M_BCAST; 278 } else 279 m->m_flags &= ~M_BCAST; 280 281 sendit: 282 /* 283 * If small enough for interface, can just send directly. 284 */ 285 if ((u_short)ip->ip_len <= ifp->if_mtu) { 286 ip->ip_len = htons((u_short)ip->ip_len); 287 ip->ip_off = htons((u_short)ip->ip_off); 288 ip->ip_sum = 0; 289 ip->ip_sum = in_cksum(m, hlen); 290 error = (*ifp->if_output)(ifp, m, 291 (struct sockaddr *)dst, ro->ro_rt); 292 goto done; 293 } 294 /* 295 * Too large for interface; fragment if possible. 296 * Must be able to put at least 8 bytes per fragment. 297 */ 298 if (ip->ip_off & IP_DF) { 299 error = EMSGSIZE; 300 ipstat.ips_cantfrag++; 301 goto bad; 302 } 303 len = (ifp->if_mtu - hlen) &~ 7; 304 if (len < 8) { 305 error = EMSGSIZE; 306 goto bad; 307 } 308 309 { 310 int mhlen, firstlen = len; 311 struct mbuf **mnext = &m->m_nextpkt; 312 313 /* 314 * Loop through length of segment after first fragment, 315 * make new header and copy data of each part and link onto chain. 316 */ 317 m0 = m; 318 mhlen = sizeof (struct ip); 319 for (off = hlen + len; off < (u_short)ip->ip_len; off += len) { 320 MGETHDR(m, M_DONTWAIT, MT_HEADER); 321 if (m == 0) { 322 error = ENOBUFS; 323 ipstat.ips_odropped++; 324 goto sendorfree; 325 } 326 m->m_data += max_linkhdr; 327 mhip = mtod(m, struct ip *); 328 *mhip = *ip; 329 if (hlen > sizeof (struct ip)) { 330 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); 331 mhip->ip_hl = mhlen >> 2; 332 } 333 m->m_len = mhlen; 334 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); 335 if (ip->ip_off & IP_MF) 336 mhip->ip_off |= IP_MF; 337 if (off + len >= (u_short)ip->ip_len) 338 len = (u_short)ip->ip_len - off; 339 else 340 mhip->ip_off |= IP_MF; 341 mhip->ip_len = htons((u_short)(len + mhlen)); 342 m->m_next = m_copy(m0, off, len); 343 if (m->m_next == 0) { 344 (void) m_free(m); 345 error = ENOBUFS; /* ??? */ 346 ipstat.ips_odropped++; 347 goto sendorfree; 348 } 349 m->m_pkthdr.len = mhlen + len; 350 m->m_pkthdr.rcvif = (struct ifnet *)0; 351 mhip->ip_off = htons((u_short)mhip->ip_off); 352 mhip->ip_sum = 0; 353 mhip->ip_sum = in_cksum(m, mhlen); 354 *mnext = m; 355 mnext = &m->m_nextpkt; 356 ipstat.ips_ofragments++; 357 } 358 /* 359 * Update first fragment by trimming what's been copied out 360 * and updating header, then send each fragment (in order). 361 */ 362 m = m0; 363 m_adj(m, hlen + firstlen - (u_short)ip->ip_len); 364 m->m_pkthdr.len = hlen + firstlen; 365 ip->ip_len = htons((u_short)m->m_pkthdr.len); 366 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); 367 ip->ip_sum = 0; 368 ip->ip_sum = in_cksum(m, hlen); 369 sendorfree: 370 for (m = m0; m; m = m0) { 371 m0 = m->m_nextpkt; 372 m->m_nextpkt = 0; 373 if (error == 0) 374 error = (*ifp->if_output)(ifp, m, 375 (struct sockaddr *)dst, ro->ro_rt); 376 else 377 m_freem(m); 378 } 379 380 if (error == 0) 381 ipstat.ips_fragmented++; 382 } 383 done: 384 if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt) 385 RTFREE(ro->ro_rt); 386 return (error); 387 bad: 388 m_freem(m0); 389 goto done; 390 } 391 392 /* 393 * Insert IP options into preformed packet. 394 * Adjust IP destination as required for IP source routing, 395 * as indicated by a non-zero in_addr at the start of the options. 396 */ 397 static struct mbuf * 398 ip_insertoptions(m, opt, phlen) 399 register struct mbuf *m; 400 struct mbuf *opt; 401 int *phlen; 402 { 403 register struct ipoption *p = mtod(opt, struct ipoption *); 404 struct mbuf *n; 405 register struct ip *ip = mtod(m, struct ip *); 406 unsigned optlen; 407 408 optlen = opt->m_len - sizeof(p->ipopt_dst); 409 if (optlen + (u_short)ip->ip_len > IP_MAXPACKET) 410 return (m); /* XXX should fail */ 411 if (p->ipopt_dst.s_addr) 412 ip->ip_dst = p->ipopt_dst; 413 if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) { 414 MGETHDR(n, M_DONTWAIT, MT_HEADER); 415 if (n == 0) 416 return (m); 417 n->m_pkthdr.len = m->m_pkthdr.len + optlen; 418 m->m_len -= sizeof(struct ip); 419 m->m_data += sizeof(struct ip); 420 n->m_next = m; 421 m = n; 422 m->m_len = optlen + sizeof(struct ip); 423 m->m_data += max_linkhdr; 424 bcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip)); 425 } else { 426 m->m_data -= optlen; 427 m->m_len += optlen; 428 m->m_pkthdr.len += optlen; 429 ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip)); 430 } 431 ip = mtod(m, struct ip *); 432 bcopy((caddr_t)p->ipopt_list, (caddr_t)(ip + 1), (unsigned)optlen); 433 *phlen = sizeof(struct ip) + optlen; 434 ip->ip_len += optlen; 435 return (m); 436 } 437 438 /* 439 * Copy options from ip to jp, 440 * omitting those not copied during fragmentation. 441 */ 442 int 443 ip_optcopy(ip, jp) 444 struct ip *ip, *jp; 445 { 446 register u_char *cp, *dp; 447 int opt, optlen, cnt; 448 449 cp = (u_char *)(ip + 1); 450 dp = (u_char *)(jp + 1); 451 cnt = (ip->ip_hl << 2) - sizeof (struct ip); 452 for (; cnt > 0; cnt -= optlen, cp += optlen) { 453 opt = cp[0]; 454 if (opt == IPOPT_EOL) 455 break; 456 if (opt == IPOPT_NOP) { 457 /* Preserve for IP mcast tunnel's LSRR alignment. */ 458 *dp++ = IPOPT_NOP; 459 optlen = 1; 460 continue; 461 } else 462 optlen = cp[IPOPT_OLEN]; 463 /* bogus lengths should have been caught by ip_dooptions */ 464 if (optlen > cnt) 465 optlen = cnt; 466 if (IPOPT_COPIED(opt)) { 467 bcopy((caddr_t)cp, (caddr_t)dp, (unsigned)optlen); 468 dp += optlen; 469 } 470 } 471 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++) 472 *dp++ = IPOPT_EOL; 473 return (optlen); 474 } 475 476 /* 477 * IP socket option processing. 478 */ 479 int 480 ip_ctloutput(op, so, level, optname, mp) 481 int op; 482 struct socket *so; 483 int level, optname; 484 struct mbuf **mp; 485 { 486 register struct inpcb *inp = sotoinpcb(so); 487 register struct mbuf *m = *mp; 488 register int optval; 489 int error = 0; 490 491 if (level != IPPROTO_IP) { 492 error = EINVAL; 493 if (op == PRCO_SETOPT && *mp) 494 (void) m_free(*mp); 495 } else switch (op) { 496 497 case PRCO_SETOPT: 498 switch (optname) { 499 case IP_OPTIONS: 500 #ifdef notyet 501 case IP_RETOPTS: 502 return (ip_pcbopts(optname, &inp->inp_options, m)); 503 #else 504 return (ip_pcbopts(&inp->inp_options, m)); 505 #endif 506 507 case IP_TOS: 508 case IP_TTL: 509 case IP_RECVOPTS: 510 case IP_RECVRETOPTS: 511 case IP_RECVDSTADDR: 512 if (m->m_len != sizeof(int)) 513 error = EINVAL; 514 else { 515 optval = *mtod(m, int *); 516 switch (optname) { 517 518 case IP_TOS: 519 inp->inp_ip.ip_tos = optval; 520 break; 521 522 case IP_TTL: 523 inp->inp_ip.ip_ttl = optval; 524 break; 525 #define OPTSET(bit) \ 526 if (optval) \ 527 inp->inp_flags |= bit; \ 528 else \ 529 inp->inp_flags &= ~bit; 530 531 case IP_RECVOPTS: 532 OPTSET(INP_RECVOPTS); 533 break; 534 535 case IP_RECVRETOPTS: 536 OPTSET(INP_RECVRETOPTS); 537 break; 538 539 case IP_RECVDSTADDR: 540 OPTSET(INP_RECVDSTADDR); 541 break; 542 } 543 } 544 break; 545 #undef OPTSET 546 547 case IP_MULTICAST_IF: 548 case IP_MULTICAST_TTL: 549 case IP_MULTICAST_LOOP: 550 case IP_ADD_MEMBERSHIP: 551 case IP_DROP_MEMBERSHIP: 552 error = ip_setmoptions(optname, &inp->inp_moptions, m); 553 break; 554 555 default: 556 error = ENOPROTOOPT; 557 break; 558 } 559 if (m) 560 (void)m_free(m); 561 break; 562 563 case PRCO_GETOPT: 564 switch (optname) { 565 case IP_OPTIONS: 566 case IP_RETOPTS: 567 *mp = m = m_get(M_WAIT, MT_SOOPTS); 568 if (inp->inp_options) { 569 m->m_len = inp->inp_options->m_len; 570 bcopy(mtod(inp->inp_options, caddr_t), 571 mtod(m, caddr_t), (unsigned)m->m_len); 572 } else 573 m->m_len = 0; 574 break; 575 576 case IP_TOS: 577 case IP_TTL: 578 case IP_RECVOPTS: 579 case IP_RECVRETOPTS: 580 case IP_RECVDSTADDR: 581 *mp = m = m_get(M_WAIT, MT_SOOPTS); 582 m->m_len = sizeof(int); 583 switch (optname) { 584 585 case IP_TOS: 586 optval = inp->inp_ip.ip_tos; 587 break; 588 589 case IP_TTL: 590 optval = inp->inp_ip.ip_ttl; 591 break; 592 593 #define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0) 594 595 case IP_RECVOPTS: 596 optval = OPTBIT(INP_RECVOPTS); 597 break; 598 599 case IP_RECVRETOPTS: 600 optval = OPTBIT(INP_RECVRETOPTS); 601 break; 602 603 case IP_RECVDSTADDR: 604 optval = OPTBIT(INP_RECVDSTADDR); 605 break; 606 } 607 *mtod(m, int *) = optval; 608 break; 609 610 case IP_MULTICAST_IF: 611 case IP_MULTICAST_TTL: 612 case IP_MULTICAST_LOOP: 613 case IP_ADD_MEMBERSHIP: 614 case IP_DROP_MEMBERSHIP: 615 error = ip_getmoptions(optname, inp->inp_moptions, mp); 616 break; 617 618 default: 619 error = ENOPROTOOPT; 620 break; 621 } 622 break; 623 } 624 return (error); 625 } 626 627 /* 628 * Set up IP options in pcb for insertion in output packets. 629 * Store in mbuf with pointer in pcbopt, adding pseudo-option 630 * with destination address if source routed. 631 */ 632 int 633 #ifdef notyet 634 ip_pcbopts(optname, pcbopt, m) 635 int optname; 636 #else 637 ip_pcbopts(pcbopt, m) 638 #endif 639 struct mbuf **pcbopt; 640 register struct mbuf *m; 641 { 642 register cnt, optlen; 643 register u_char *cp; 644 u_char opt; 645 646 /* turn off any old options */ 647 if (*pcbopt) 648 (void)m_free(*pcbopt); 649 *pcbopt = 0; 650 if (m == (struct mbuf *)0 || m->m_len == 0) { 651 /* 652 * Only turning off any previous options. 653 */ 654 if (m) 655 (void)m_free(m); 656 return (0); 657 } 658 659 #ifndef vax 660 if (m->m_len % sizeof(long)) 661 goto bad; 662 #endif 663 /* 664 * IP first-hop destination address will be stored before 665 * actual options; move other options back 666 * and clear it when none present. 667 */ 668 if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN]) 669 goto bad; 670 cnt = m->m_len; 671 m->m_len += sizeof(struct in_addr); 672 cp = mtod(m, u_char *) + sizeof(struct in_addr); 673 ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt); 674 bzero(mtod(m, caddr_t), sizeof(struct in_addr)); 675 676 for (; cnt > 0; cnt -= optlen, cp += optlen) { 677 opt = cp[IPOPT_OPTVAL]; 678 if (opt == IPOPT_EOL) 679 break; 680 if (opt == IPOPT_NOP) 681 optlen = 1; 682 else { 683 optlen = cp[IPOPT_OLEN]; 684 if (optlen <= IPOPT_OLEN || optlen > cnt) 685 goto bad; 686 } 687 switch (opt) { 688 689 default: 690 break; 691 692 case IPOPT_LSRR: 693 case IPOPT_SSRR: 694 /* 695 * user process specifies route as: 696 * ->A->B->C->D 697 * D must be our final destination (but we can't 698 * check that since we may not have connected yet). 699 * A is first hop destination, which doesn't appear in 700 * actual IP option, but is stored before the options. 701 */ 702 if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr)) 703 goto bad; 704 m->m_len -= sizeof(struct in_addr); 705 cnt -= sizeof(struct in_addr); 706 optlen -= sizeof(struct in_addr); 707 cp[IPOPT_OLEN] = optlen; 708 /* 709 * Move first hop before start of options. 710 */ 711 bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t), 712 sizeof(struct in_addr)); 713 /* 714 * Then copy rest of options back 715 * to close up the deleted entry. 716 */ 717 ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] + 718 sizeof(struct in_addr)), 719 (caddr_t)&cp[IPOPT_OFFSET+1], 720 (unsigned)cnt + sizeof(struct in_addr)); 721 break; 722 } 723 } 724 if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr)) 725 goto bad; 726 *pcbopt = m; 727 return (0); 728 729 bad: 730 (void)m_free(m); 731 return (EINVAL); 732 } 733 734 /* 735 * Set the IP multicast options in response to user setsockopt(). 736 */ 737 int 738 ip_setmoptions(optname, imop, m) 739 int optname; 740 struct ip_moptions **imop; 741 struct mbuf *m; 742 { 743 register int error = 0; 744 u_char loop; 745 register int i; 746 struct in_addr addr; 747 register struct ip_mreq *mreq; 748 register struct ifnet *ifp; 749 register struct ip_moptions *imo = *imop; 750 struct route ro; 751 register struct sockaddr_in *dst; 752 753 if (imo == NULL) { 754 /* 755 * No multicast option buffer attached to the pcb; 756 * allocate one and initialize to default values. 757 */ 758 imo = (struct ip_moptions*)malloc(sizeof(*imo), M_IPMOPTS, 759 M_WAITOK); 760 761 if (imo == NULL) 762 return (ENOBUFS); 763 *imop = imo; 764 imo->imo_multicast_ifp = NULL; 765 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL; 766 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP; 767 imo->imo_num_memberships = 0; 768 } 769 770 switch (optname) { 771 772 case IP_MULTICAST_IF: 773 /* 774 * Select the interface for outgoing multicast packets. 775 */ 776 if (m == NULL || m->m_len != sizeof(struct in_addr)) { 777 error = EINVAL; 778 break; 779 } 780 addr = *(mtod(m, struct in_addr *)); 781 /* 782 * INADDR_ANY is used to remove a previous selection. 783 * When no interface is selected, a default one is 784 * chosen every time a multicast packet is sent. 785 */ 786 if (addr.s_addr == INADDR_ANY) { 787 imo->imo_multicast_ifp = NULL; 788 break; 789 } 790 /* 791 * The selected interface is identified by its local 792 * IP address. Find the interface and confirm that 793 * it supports multicasting. 794 */ 795 INADDR_TO_IFP(addr, ifp); 796 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 797 error = EADDRNOTAVAIL; 798 break; 799 } 800 imo->imo_multicast_ifp = ifp; 801 break; 802 803 case IP_MULTICAST_TTL: 804 /* 805 * Set the IP time-to-live for outgoing multicast packets. 806 */ 807 if (m == NULL || m->m_len != 1) { 808 error = EINVAL; 809 break; 810 } 811 imo->imo_multicast_ttl = *(mtod(m, u_char *)); 812 break; 813 814 case IP_MULTICAST_LOOP: 815 /* 816 * Set the loopback flag for outgoing multicast packets. 817 * Must be zero or one. 818 */ 819 if (m == NULL || m->m_len != 1 || 820 (loop = *(mtod(m, u_char *))) > 1) { 821 error = EINVAL; 822 break; 823 } 824 imo->imo_multicast_loop = loop; 825 break; 826 827 case IP_ADD_MEMBERSHIP: 828 /* 829 * Add a multicast group membership. 830 * Group must be a valid IP multicast address. 831 */ 832 if (m == NULL || m->m_len != sizeof(struct ip_mreq)) { 833 error = EINVAL; 834 break; 835 } 836 mreq = mtod(m, struct ip_mreq *); 837 if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) { 838 error = EINVAL; 839 break; 840 } 841 /* 842 * If no interface address was provided, use the interface of 843 * the route to the given multicast address. 844 */ 845 if (mreq->imr_interface.s_addr == INADDR_ANY) { 846 ro.ro_rt = NULL; 847 dst = (struct sockaddr_in *)&ro.ro_dst; 848 dst->sin_len = sizeof(*dst); 849 dst->sin_family = AF_INET; 850 dst->sin_addr = mreq->imr_multiaddr; 851 rtalloc(&ro); 852 if (ro.ro_rt == NULL) { 853 error = EADDRNOTAVAIL; 854 break; 855 } 856 ifp = ro.ro_rt->rt_ifp; 857 rtfree(ro.ro_rt); 858 } 859 else { 860 INADDR_TO_IFP(mreq->imr_interface, ifp); 861 } 862 /* 863 * See if we found an interface, and confirm that it 864 * supports multicast. 865 */ 866 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 867 error = EADDRNOTAVAIL; 868 break; 869 } 870 /* 871 * See if the membership already exists or if all the 872 * membership slots are full. 873 */ 874 for (i = 0; i < imo->imo_num_memberships; ++i) { 875 if (imo->imo_membership[i]->inm_ifp == ifp && 876 imo->imo_membership[i]->inm_addr.s_addr 877 == mreq->imr_multiaddr.s_addr) 878 break; 879 } 880 if (i < imo->imo_num_memberships) { 881 error = EADDRINUSE; 882 break; 883 } 884 if (i == IP_MAX_MEMBERSHIPS) { 885 error = ETOOMANYREFS; 886 break; 887 } 888 /* 889 * Everything looks good; add a new record to the multicast 890 * address list for the given interface. 891 */ 892 if ((imo->imo_membership[i] = 893 in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) { 894 error = ENOBUFS; 895 break; 896 } 897 ++imo->imo_num_memberships; 898 break; 899 900 case IP_DROP_MEMBERSHIP: 901 /* 902 * Drop a multicast group membership. 903 * Group must be a valid IP multicast address. 904 */ 905 if (m == NULL || m->m_len != sizeof(struct ip_mreq)) { 906 error = EINVAL; 907 break; 908 } 909 mreq = mtod(m, struct ip_mreq *); 910 if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) { 911 error = EINVAL; 912 break; 913 } 914 /* 915 * If an interface address was specified, get a pointer 916 * to its ifnet structure. 917 */ 918 if (mreq->imr_interface.s_addr == INADDR_ANY) 919 ifp = NULL; 920 else { 921 INADDR_TO_IFP(mreq->imr_interface, ifp); 922 if (ifp == NULL) { 923 error = EADDRNOTAVAIL; 924 break; 925 } 926 } 927 /* 928 * Find the membership in the membership array. 929 */ 930 for (i = 0; i < imo->imo_num_memberships; ++i) { 931 if ((ifp == NULL || 932 imo->imo_membership[i]->inm_ifp == ifp) && 933 imo->imo_membership[i]->inm_addr.s_addr == 934 mreq->imr_multiaddr.s_addr) 935 break; 936 } 937 if (i == imo->imo_num_memberships) { 938 error = EADDRNOTAVAIL; 939 break; 940 } 941 /* 942 * Give up the multicast address record to which the 943 * membership points. 944 */ 945 in_delmulti(imo->imo_membership[i]); 946 /* 947 * Remove the gap in the membership array. 948 */ 949 for (++i; i < imo->imo_num_memberships; ++i) 950 imo->imo_membership[i-1] = imo->imo_membership[i]; 951 --imo->imo_num_memberships; 952 break; 953 954 default: 955 error = EOPNOTSUPP; 956 break; 957 } 958 959 /* 960 * If all options have default values, no need to keep the mbuf. 961 */ 962 if (imo->imo_multicast_ifp == NULL && 963 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL && 964 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP && 965 imo->imo_num_memberships == 0) { 966 free(*imop, M_IPMOPTS); 967 *imop = NULL; 968 } 969 970 return (error); 971 } 972 973 /* 974 * Return the IP multicast options in response to user getsockopt(). 975 */ 976 int 977 ip_getmoptions(optname, imo, mp) 978 int optname; 979 register struct ip_moptions *imo; 980 register struct mbuf **mp; 981 { 982 u_char *ttl; 983 u_char *loop; 984 struct in_addr *addr; 985 struct in_ifaddr *ia; 986 987 *mp = m_get(M_WAIT, MT_SOOPTS); 988 989 switch (optname) { 990 991 case IP_MULTICAST_IF: 992 addr = mtod(*mp, struct in_addr *); 993 (*mp)->m_len = sizeof(struct in_addr); 994 if (imo == NULL || imo->imo_multicast_ifp == NULL) 995 addr->s_addr = INADDR_ANY; 996 else { 997 IFP_TO_IA(imo->imo_multicast_ifp, ia); 998 addr->s_addr = (ia == NULL) ? INADDR_ANY 999 : IA_SIN(ia)->sin_addr.s_addr; 1000 } 1001 return (0); 1002 1003 case IP_MULTICAST_TTL: 1004 ttl = mtod(*mp, u_char *); 1005 (*mp)->m_len = 1; 1006 *ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL 1007 : imo->imo_multicast_ttl; 1008 return (0); 1009 1010 case IP_MULTICAST_LOOP: 1011 loop = mtod(*mp, u_char *); 1012 (*mp)->m_len = 1; 1013 *loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP 1014 : imo->imo_multicast_loop; 1015 return (0); 1016 1017 default: 1018 return (EOPNOTSUPP); 1019 } 1020 } 1021 1022 /* 1023 * Discard the IP multicast options. 1024 */ 1025 void 1026 ip_freemoptions(imo) 1027 register struct ip_moptions *imo; 1028 { 1029 register int i; 1030 1031 if (imo != NULL) { 1032 for (i = 0; i < imo->imo_num_memberships; ++i) 1033 in_delmulti(imo->imo_membership[i]); 1034 free(imo, M_IPMOPTS); 1035 } 1036 } 1037 1038 /* 1039 * Routine called from ip_output() to loop back a copy of an IP multicast 1040 * packet to the input queue of a specified interface. Note that this 1041 * calls the output routine of the loopback "driver", but with an interface 1042 * pointer that might NOT be &loif -- easier than replicating that code here. 1043 */ 1044 static void 1045 ip_mloopback(ifp, m, dst) 1046 struct ifnet *ifp; 1047 register struct mbuf *m; 1048 register struct sockaddr_in *dst; 1049 { 1050 register struct ip *ip; 1051 struct mbuf *copym; 1052 1053 copym = m_copy(m, 0, M_COPYALL); 1054 if (copym != NULL) { 1055 /* 1056 * We don't bother to fragment if the IP length is greater 1057 * than the interface's MTU. Can this possibly matter? 1058 */ 1059 ip = mtod(copym, struct ip *); 1060 ip->ip_len = htons((u_short)ip->ip_len); 1061 ip->ip_off = htons((u_short)ip->ip_off); 1062 ip->ip_sum = 0; 1063 ip->ip_sum = in_cksum(copym, ip->ip_hl << 2); 1064 (void) looutput(ifp, copym, (struct sockaddr *)dst, NULL); 1065 } 1066 } 1067