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