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