ip_output.c revision 1817
1/* 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 34 * $Id$ 35 */ 36 37#include <sys/param.h> 38#include <sys/systm.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 60static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *)); 61static 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 */ 70int 71ip_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 * Verify that we have any chance at all of being able to queue 260 * the packet or packet fragments 261 */ 262 if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >= 263 ifp->if_snd.ifq_maxlen) { 264 error = ENOBUFS; 265 goto bad; 266 } 267 268 /* 269 * Look for broadcast address and 270 * and verify user is allowed to send 271 * such a packet. 272 */ 273 if (in_broadcast(dst->sin_addr, ifp)) { 274 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 275 error = EADDRNOTAVAIL; 276 goto bad; 277 } 278 if ((flags & IP_ALLOWBROADCAST) == 0) { 279 error = EACCES; 280 goto bad; 281 } 282 /* don't allow broadcast messages to be fragmented */ 283 if ((u_short)ip->ip_len > ifp->if_mtu) { 284 error = EMSGSIZE; 285 goto bad; 286 } 287 m->m_flags |= M_BCAST; 288 } else 289 m->m_flags &= ~M_BCAST; 290 291sendit: 292 /* 293 * If small enough for interface, can just send directly. 294 */ 295 if ((u_short)ip->ip_len <= ifp->if_mtu) { 296 ip->ip_len = htons((u_short)ip->ip_len); 297 ip->ip_off = htons((u_short)ip->ip_off); 298 ip->ip_sum = 0; 299 ip->ip_sum = in_cksum(m, hlen); 300 error = (*ifp->if_output)(ifp, m, 301 (struct sockaddr *)dst, ro->ro_rt); 302 goto done; 303 } 304 /* 305 * Too large for interface; fragment if possible. 306 * Must be able to put at least 8 bytes per fragment. 307 */ 308 if (ip->ip_off & IP_DF) { 309 error = EMSGSIZE; 310 ipstat.ips_cantfrag++; 311 goto bad; 312 } 313 len = (ifp->if_mtu - hlen) &~ 7; 314 if (len < 8) { 315 error = EMSGSIZE; 316 goto bad; 317 } 318 319 { 320 int mhlen, firstlen = len; 321 struct mbuf **mnext = &m->m_nextpkt; 322 323 /* 324 * Loop through length of segment after first fragment, 325 * make new header and copy data of each part and link onto chain. 326 */ 327 m0 = m; 328 mhlen = sizeof (struct ip); 329 for (off = hlen + len; off < (u_short)ip->ip_len; off += len) { 330 MGETHDR(m, M_DONTWAIT, MT_HEADER); 331 if (m == 0) { 332 error = ENOBUFS; 333 ipstat.ips_odropped++; 334 goto sendorfree; 335 } 336 m->m_data += max_linkhdr; 337 mhip = mtod(m, struct ip *); 338 *mhip = *ip; 339 if (hlen > sizeof (struct ip)) { 340 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); 341 mhip->ip_hl = mhlen >> 2; 342 } 343 m->m_len = mhlen; 344 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); 345 if (ip->ip_off & IP_MF) 346 mhip->ip_off |= IP_MF; 347 if (off + len >= (u_short)ip->ip_len) 348 len = (u_short)ip->ip_len - off; 349 else 350 mhip->ip_off |= IP_MF; 351 mhip->ip_len = htons((u_short)(len + mhlen)); 352 m->m_next = m_copy(m0, off, len); 353 if (m->m_next == 0) { 354 (void) m_free(m); 355 error = ENOBUFS; /* ??? */ 356 ipstat.ips_odropped++; 357 goto sendorfree; 358 } 359 m->m_pkthdr.len = mhlen + len; 360 m->m_pkthdr.rcvif = (struct ifnet *)0; 361 mhip->ip_off = htons((u_short)mhip->ip_off); 362 mhip->ip_sum = 0; 363 mhip->ip_sum = in_cksum(m, mhlen); 364 *mnext = m; 365 mnext = &m->m_nextpkt; 366 ipstat.ips_ofragments++; 367 } 368 /* 369 * Update first fragment by trimming what's been copied out 370 * and updating header, then send each fragment (in order). 371 */ 372 m = m0; 373 m_adj(m, hlen + firstlen - (u_short)ip->ip_len); 374 m->m_pkthdr.len = hlen + firstlen; 375 ip->ip_len = htons((u_short)m->m_pkthdr.len); 376 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); 377 ip->ip_sum = 0; 378 ip->ip_sum = in_cksum(m, hlen); 379sendorfree: 380 for (m = m0; m; m = m0) { 381 m0 = m->m_nextpkt; 382 m->m_nextpkt = 0; 383 if (error == 0) 384 error = (*ifp->if_output)(ifp, m, 385 (struct sockaddr *)dst, ro->ro_rt); 386 else 387 m_freem(m); 388 } 389 390 if (error == 0) 391 ipstat.ips_fragmented++; 392 } 393done: 394 if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt) 395 RTFREE(ro->ro_rt); 396 return (error); 397bad: 398 m_freem(m0); 399 goto done; 400} 401 402/* 403 * Insert IP options into preformed packet. 404 * Adjust IP destination as required for IP source routing, 405 * as indicated by a non-zero in_addr at the start of the options. 406 */ 407static struct mbuf * 408ip_insertoptions(m, opt, phlen) 409 register struct mbuf *m; 410 struct mbuf *opt; 411 int *phlen; 412{ 413 register struct ipoption *p = mtod(opt, struct ipoption *); 414 struct mbuf *n; 415 register struct ip *ip = mtod(m, struct ip *); 416 unsigned optlen; 417 418 optlen = opt->m_len - sizeof(p->ipopt_dst); 419 if (optlen + (u_short)ip->ip_len > IP_MAXPACKET) 420 return (m); /* XXX should fail */ 421 if (p->ipopt_dst.s_addr) 422 ip->ip_dst = p->ipopt_dst; 423 if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) { 424 MGETHDR(n, M_DONTWAIT, MT_HEADER); 425 if (n == 0) 426 return (m); 427 n->m_pkthdr.len = m->m_pkthdr.len + optlen; 428 m->m_len -= sizeof(struct ip); 429 m->m_data += sizeof(struct ip); 430 n->m_next = m; 431 m = n; 432 m->m_len = optlen + sizeof(struct ip); 433 m->m_data += max_linkhdr; 434 bcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip)); 435 } else { 436 m->m_data -= optlen; 437 m->m_len += optlen; 438 m->m_pkthdr.len += optlen; 439 ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip)); 440 } 441 ip = mtod(m, struct ip *); 442 bcopy((caddr_t)p->ipopt_list, (caddr_t)(ip + 1), (unsigned)optlen); 443 *phlen = sizeof(struct ip) + optlen; 444 ip->ip_len += optlen; 445 return (m); 446} 447 448/* 449 * Copy options from ip to jp, 450 * omitting those not copied during fragmentation. 451 */ 452int 453ip_optcopy(ip, jp) 454 struct ip *ip, *jp; 455{ 456 register u_char *cp, *dp; 457 int opt, optlen, cnt; 458 459 cp = (u_char *)(ip + 1); 460 dp = (u_char *)(jp + 1); 461 cnt = (ip->ip_hl << 2) - sizeof (struct ip); 462 for (; cnt > 0; cnt -= optlen, cp += optlen) { 463 opt = cp[0]; 464 if (opt == IPOPT_EOL) 465 break; 466 if (opt == IPOPT_NOP) { 467 /* Preserve for IP mcast tunnel's LSRR alignment. */ 468 *dp++ = IPOPT_NOP; 469 optlen = 1; 470 continue; 471 } else 472 optlen = cp[IPOPT_OLEN]; 473 /* bogus lengths should have been caught by ip_dooptions */ 474 if (optlen > cnt) 475 optlen = cnt; 476 if (IPOPT_COPIED(opt)) { 477 bcopy((caddr_t)cp, (caddr_t)dp, (unsigned)optlen); 478 dp += optlen; 479 } 480 } 481 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++) 482 *dp++ = IPOPT_EOL; 483 return (optlen); 484} 485 486/* 487 * IP socket option processing. 488 */ 489int 490ip_ctloutput(op, so, level, optname, mp) 491 int op; 492 struct socket *so; 493 int level, optname; 494 struct mbuf **mp; 495{ 496 register struct inpcb *inp = sotoinpcb(so); 497 register struct mbuf *m = *mp; 498 register int optval = 0; 499 int error = 0; 500 501 if (level != IPPROTO_IP) { 502 error = EINVAL; 503 if (op == PRCO_SETOPT && *mp) 504 (void) m_free(*mp); 505 } else switch (op) { 506 507 case PRCO_SETOPT: 508 switch (optname) { 509 case IP_OPTIONS: 510#ifdef notyet 511 case IP_RETOPTS: 512 return (ip_pcbopts(optname, &inp->inp_options, m)); 513#else 514 return (ip_pcbopts(&inp->inp_options, m)); 515#endif 516 517 case IP_TOS: 518 case IP_TTL: 519 case IP_RECVOPTS: 520 case IP_RECVRETOPTS: 521 case IP_RECVDSTADDR: 522 if (m->m_len != sizeof(int)) 523 error = EINVAL; 524 else { 525 optval = *mtod(m, int *); 526 switch (optname) { 527 528 case IP_TOS: 529 inp->inp_ip.ip_tos = optval; 530 break; 531 532 case IP_TTL: 533 inp->inp_ip.ip_ttl = optval; 534 break; 535#define OPTSET(bit) \ 536 if (optval) \ 537 inp->inp_flags |= bit; \ 538 else \ 539 inp->inp_flags &= ~bit; 540 541 case IP_RECVOPTS: 542 OPTSET(INP_RECVOPTS); 543 break; 544 545 case IP_RECVRETOPTS: 546 OPTSET(INP_RECVRETOPTS); 547 break; 548 549 case IP_RECVDSTADDR: 550 OPTSET(INP_RECVDSTADDR); 551 break; 552 } 553 } 554 break; 555#undef OPTSET 556 557 case IP_MULTICAST_IF: 558 case IP_MULTICAST_TTL: 559 case IP_MULTICAST_LOOP: 560 case IP_ADD_MEMBERSHIP: 561 case IP_DROP_MEMBERSHIP: 562 error = ip_setmoptions(optname, &inp->inp_moptions, m); 563 break; 564 565 default: 566 error = ENOPROTOOPT; 567 break; 568 } 569 if (m) 570 (void)m_free(m); 571 break; 572 573 case PRCO_GETOPT: 574 switch (optname) { 575 case IP_OPTIONS: 576 case IP_RETOPTS: 577 *mp = m = m_get(M_WAIT, MT_SOOPTS); 578 if (inp->inp_options) { 579 m->m_len = inp->inp_options->m_len; 580 bcopy(mtod(inp->inp_options, caddr_t), 581 mtod(m, caddr_t), (unsigned)m->m_len); 582 } else 583 m->m_len = 0; 584 break; 585 586 case IP_TOS: 587 case IP_TTL: 588 case IP_RECVOPTS: 589 case IP_RECVRETOPTS: 590 case IP_RECVDSTADDR: 591 *mp = m = m_get(M_WAIT, MT_SOOPTS); 592 m->m_len = sizeof(int); 593 switch (optname) { 594 595 case IP_TOS: 596 optval = inp->inp_ip.ip_tos; 597 break; 598 599 case IP_TTL: 600 optval = inp->inp_ip.ip_ttl; 601 break; 602 603#define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0) 604 605 case IP_RECVOPTS: 606 optval = OPTBIT(INP_RECVOPTS); 607 break; 608 609 case IP_RECVRETOPTS: 610 optval = OPTBIT(INP_RECVRETOPTS); 611 break; 612 613 case IP_RECVDSTADDR: 614 optval = OPTBIT(INP_RECVDSTADDR); 615 break; 616 } 617 *mtod(m, int *) = optval; 618 break; 619 620 case IP_MULTICAST_IF: 621 case IP_MULTICAST_TTL: 622 case IP_MULTICAST_LOOP: 623 case IP_ADD_MEMBERSHIP: 624 case IP_DROP_MEMBERSHIP: 625 error = ip_getmoptions(optname, inp->inp_moptions, mp); 626 break; 627 628 default: 629 error = ENOPROTOOPT; 630 break; 631 } 632 break; 633 } 634 return (error); 635} 636 637/* 638 * Set up IP options in pcb for insertion in output packets. 639 * Store in mbuf with pointer in pcbopt, adding pseudo-option 640 * with destination address if source routed. 641 */ 642int 643#ifdef notyet 644ip_pcbopts(optname, pcbopt, m) 645 int optname; 646#else 647ip_pcbopts(pcbopt, m) 648#endif 649 struct mbuf **pcbopt; 650 register struct mbuf *m; 651{ 652 register cnt, optlen; 653 register u_char *cp; 654 u_char opt; 655 656 /* turn off any old options */ 657 if (*pcbopt) 658 (void)m_free(*pcbopt); 659 *pcbopt = 0; 660 if (m == (struct mbuf *)0 || m->m_len == 0) { 661 /* 662 * Only turning off any previous options. 663 */ 664 if (m) 665 (void)m_free(m); 666 return (0); 667 } 668 669#ifndef vax 670 if (m->m_len % sizeof(long)) 671 goto bad; 672#endif 673 /* 674 * IP first-hop destination address will be stored before 675 * actual options; move other options back 676 * and clear it when none present. 677 */ 678 if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN]) 679 goto bad; 680 cnt = m->m_len; 681 m->m_len += sizeof(struct in_addr); 682 cp = mtod(m, u_char *) + sizeof(struct in_addr); 683 ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt); 684 bzero(mtod(m, caddr_t), sizeof(struct in_addr)); 685 686 for (; cnt > 0; cnt -= optlen, cp += optlen) { 687 opt = cp[IPOPT_OPTVAL]; 688 if (opt == IPOPT_EOL) 689 break; 690 if (opt == IPOPT_NOP) 691 optlen = 1; 692 else { 693 optlen = cp[IPOPT_OLEN]; 694 if (optlen <= IPOPT_OLEN || optlen > cnt) 695 goto bad; 696 } 697 switch (opt) { 698 699 default: 700 break; 701 702 case IPOPT_LSRR: 703 case IPOPT_SSRR: 704 /* 705 * user process specifies route as: 706 * ->A->B->C->D 707 * D must be our final destination (but we can't 708 * check that since we may not have connected yet). 709 * A is first hop destination, which doesn't appear in 710 * actual IP option, but is stored before the options. 711 */ 712 if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr)) 713 goto bad; 714 m->m_len -= sizeof(struct in_addr); 715 cnt -= sizeof(struct in_addr); 716 optlen -= sizeof(struct in_addr); 717 cp[IPOPT_OLEN] = optlen; 718 /* 719 * Move first hop before start of options. 720 */ 721 bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t), 722 sizeof(struct in_addr)); 723 /* 724 * Then copy rest of options back 725 * to close up the deleted entry. 726 */ 727 ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] + 728 sizeof(struct in_addr)), 729 (caddr_t)&cp[IPOPT_OFFSET+1], 730 (unsigned)cnt + sizeof(struct in_addr)); 731 break; 732 } 733 } 734 if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr)) 735 goto bad; 736 *pcbopt = m; 737 return (0); 738 739bad: 740 (void)m_free(m); 741 return (EINVAL); 742} 743 744/* 745 * Set the IP multicast options in response to user setsockopt(). 746 */ 747int 748ip_setmoptions(optname, imop, m) 749 int optname; 750 struct ip_moptions **imop; 751 struct mbuf *m; 752{ 753 register int error = 0; 754 u_char loop; 755 register int i; 756 struct in_addr addr; 757 register struct ip_mreq *mreq; 758 register struct ifnet *ifp; 759 register struct ip_moptions *imo = *imop; 760 struct route ro; 761 register struct sockaddr_in *dst; 762 763 if (imo == NULL) { 764 /* 765 * No multicast option buffer attached to the pcb; 766 * allocate one and initialize to default values. 767 */ 768 imo = (struct ip_moptions*)malloc(sizeof(*imo), M_IPMOPTS, 769 M_WAITOK); 770 771 if (imo == NULL) 772 return (ENOBUFS); 773 *imop = imo; 774 imo->imo_multicast_ifp = NULL; 775 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL; 776 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP; 777 imo->imo_num_memberships = 0; 778 } 779 780 switch (optname) { 781 782 case IP_MULTICAST_IF: 783 /* 784 * Select the interface for outgoing multicast packets. 785 */ 786 if (m == NULL || m->m_len != sizeof(struct in_addr)) { 787 error = EINVAL; 788 break; 789 } 790 addr = *(mtod(m, struct in_addr *)); 791 /* 792 * INADDR_ANY is used to remove a previous selection. 793 * When no interface is selected, a default one is 794 * chosen every time a multicast packet is sent. 795 */ 796 if (addr.s_addr == INADDR_ANY) { 797 imo->imo_multicast_ifp = NULL; 798 break; 799 } 800 /* 801 * The selected interface is identified by its local 802 * IP address. Find the interface and confirm that 803 * it supports multicasting. 804 */ 805 INADDR_TO_IFP(addr, ifp); 806 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 807 error = EADDRNOTAVAIL; 808 break; 809 } 810 imo->imo_multicast_ifp = ifp; 811 break; 812 813 case IP_MULTICAST_TTL: 814 /* 815 * Set the IP time-to-live for outgoing multicast packets. 816 */ 817 if (m == NULL || m->m_len != 1) { 818 error = EINVAL; 819 break; 820 } 821 imo->imo_multicast_ttl = *(mtod(m, u_char *)); 822 break; 823 824 case IP_MULTICAST_LOOP: 825 /* 826 * Set the loopback flag for outgoing multicast packets. 827 * Must be zero or one. 828 */ 829 if (m == NULL || m->m_len != 1 || 830 (loop = *(mtod(m, u_char *))) > 1) { 831 error = EINVAL; 832 break; 833 } 834 imo->imo_multicast_loop = loop; 835 break; 836 837 case IP_ADD_MEMBERSHIP: 838 /* 839 * Add a multicast group membership. 840 * Group must be a valid IP multicast address. 841 */ 842 if (m == NULL || m->m_len != sizeof(struct ip_mreq)) { 843 error = EINVAL; 844 break; 845 } 846 mreq = mtod(m, struct ip_mreq *); 847 if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) { 848 error = EINVAL; 849 break; 850 } 851 /* 852 * If no interface address was provided, use the interface of 853 * the route to the given multicast address. 854 */ 855 if (mreq->imr_interface.s_addr == INADDR_ANY) { 856 ro.ro_rt = NULL; 857 dst = (struct sockaddr_in *)&ro.ro_dst; 858 dst->sin_len = sizeof(*dst); 859 dst->sin_family = AF_INET; 860 dst->sin_addr = mreq->imr_multiaddr; 861 rtalloc(&ro); 862 if (ro.ro_rt == NULL) { 863 error = EADDRNOTAVAIL; 864 break; 865 } 866 ifp = ro.ro_rt->rt_ifp; 867 rtfree(ro.ro_rt); 868 } 869 else { 870 INADDR_TO_IFP(mreq->imr_interface, ifp); 871 } 872 /* 873 * See if we found an interface, and confirm that it 874 * supports multicast. 875 */ 876 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 877 error = EADDRNOTAVAIL; 878 break; 879 } 880 /* 881 * See if the membership already exists or if all the 882 * membership slots are full. 883 */ 884 for (i = 0; i < imo->imo_num_memberships; ++i) { 885 if (imo->imo_membership[i]->inm_ifp == ifp && 886 imo->imo_membership[i]->inm_addr.s_addr 887 == mreq->imr_multiaddr.s_addr) 888 break; 889 } 890 if (i < imo->imo_num_memberships) { 891 error = EADDRINUSE; 892 break; 893 } 894 if (i == IP_MAX_MEMBERSHIPS) { 895 error = ETOOMANYREFS; 896 break; 897 } 898 /* 899 * Everything looks good; add a new record to the multicast 900 * address list for the given interface. 901 */ 902 if ((imo->imo_membership[i] = 903 in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) { 904 error = ENOBUFS; 905 break; 906 } 907 ++imo->imo_num_memberships; 908 break; 909 910 case IP_DROP_MEMBERSHIP: 911 /* 912 * Drop a multicast group membership. 913 * Group must be a valid IP multicast address. 914 */ 915 if (m == NULL || m->m_len != sizeof(struct ip_mreq)) { 916 error = EINVAL; 917 break; 918 } 919 mreq = mtod(m, struct ip_mreq *); 920 if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) { 921 error = EINVAL; 922 break; 923 } 924 /* 925 * If an interface address was specified, get a pointer 926 * to its ifnet structure. 927 */ 928 if (mreq->imr_interface.s_addr == INADDR_ANY) 929 ifp = NULL; 930 else { 931 INADDR_TO_IFP(mreq->imr_interface, ifp); 932 if (ifp == NULL) { 933 error = EADDRNOTAVAIL; 934 break; 935 } 936 } 937 /* 938 * Find the membership in the membership array. 939 */ 940 for (i = 0; i < imo->imo_num_memberships; ++i) { 941 if ((ifp == NULL || 942 imo->imo_membership[i]->inm_ifp == ifp) && 943 imo->imo_membership[i]->inm_addr.s_addr == 944 mreq->imr_multiaddr.s_addr) 945 break; 946 } 947 if (i == imo->imo_num_memberships) { 948 error = EADDRNOTAVAIL; 949 break; 950 } 951 /* 952 * Give up the multicast address record to which the 953 * membership points. 954 */ 955 in_delmulti(imo->imo_membership[i]); 956 /* 957 * Remove the gap in the membership array. 958 */ 959 for (++i; i < imo->imo_num_memberships; ++i) 960 imo->imo_membership[i-1] = imo->imo_membership[i]; 961 --imo->imo_num_memberships; 962 break; 963 964 default: 965 error = EOPNOTSUPP; 966 break; 967 } 968 969 /* 970 * If all options have default values, no need to keep the mbuf. 971 */ 972 if (imo->imo_multicast_ifp == NULL && 973 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL && 974 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP && 975 imo->imo_num_memberships == 0) { 976 free(*imop, M_IPMOPTS); 977 *imop = NULL; 978 } 979 980 return (error); 981} 982 983/* 984 * Return the IP multicast options in response to user getsockopt(). 985 */ 986int 987ip_getmoptions(optname, imo, mp) 988 int optname; 989 register struct ip_moptions *imo; 990 register struct mbuf **mp; 991{ 992 u_char *ttl; 993 u_char *loop; 994 struct in_addr *addr; 995 struct in_ifaddr *ia; 996 997 *mp = m_get(M_WAIT, MT_SOOPTS); 998 999 switch (optname) { 1000 1001 case IP_MULTICAST_IF: 1002 addr = mtod(*mp, struct in_addr *); 1003 (*mp)->m_len = sizeof(struct in_addr); 1004 if (imo == NULL || imo->imo_multicast_ifp == NULL) 1005 addr->s_addr = INADDR_ANY; 1006 else { 1007 IFP_TO_IA(imo->imo_multicast_ifp, ia); 1008 addr->s_addr = (ia == NULL) ? INADDR_ANY 1009 : IA_SIN(ia)->sin_addr.s_addr; 1010 } 1011 return (0); 1012 1013 case IP_MULTICAST_TTL: 1014 ttl = mtod(*mp, u_char *); 1015 (*mp)->m_len = 1; 1016 *ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL 1017 : imo->imo_multicast_ttl; 1018 return (0); 1019 1020 case IP_MULTICAST_LOOP: 1021 loop = mtod(*mp, u_char *); 1022 (*mp)->m_len = 1; 1023 *loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP 1024 : imo->imo_multicast_loop; 1025 return (0); 1026 1027 default: 1028 return (EOPNOTSUPP); 1029 } 1030} 1031 1032/* 1033 * Discard the IP multicast options. 1034 */ 1035void 1036ip_freemoptions(imo) 1037 register struct ip_moptions *imo; 1038{ 1039 register int i; 1040 1041 if (imo != NULL) { 1042 for (i = 0; i < imo->imo_num_memberships; ++i) 1043 in_delmulti(imo->imo_membership[i]); 1044 free(imo, M_IPMOPTS); 1045 } 1046} 1047 1048/* 1049 * Routine called from ip_output() to loop back a copy of an IP multicast 1050 * packet to the input queue of a specified interface. Note that this 1051 * calls the output routine of the loopback "driver", but with an interface 1052 * pointer that might NOT be &loif -- easier than replicating that code here. 1053 */ 1054static void 1055ip_mloopback(ifp, m, dst) 1056 struct ifnet *ifp; 1057 register struct mbuf *m; 1058 register struct sockaddr_in *dst; 1059{ 1060 register struct ip *ip; 1061 struct mbuf *copym; 1062 1063 copym = m_copy(m, 0, M_COPYALL); 1064 if (copym != NULL) { 1065 /* 1066 * We don't bother to fragment if the IP length is greater 1067 * than the interface's MTU. Can this possibly matter? 1068 */ 1069 ip = mtod(copym, struct ip *); 1070 ip->ip_len = htons((u_short)ip->ip_len); 1071 ip->ip_off = htons((u_short)ip->ip_off); 1072 ip->ip_sum = 0; 1073 ip->ip_sum = in_cksum(copym, ip->ip_hl << 2); 1074 (void) looutput(ifp, copym, (struct sockaddr *)dst, NULL); 1075 } 1076} 1077