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