ip_output.c revision 41793
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.82 1998/09/02 15:11:14 wollman Exp $ 35 */ 36 37#define _IP_VHL 38 39#include "opt_ipfw.h" 40#include "opt_ipdn.h" 41#include "opt_ipdivert.h" 42#include "opt_ipfilter.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/malloc.h> 47#include <sys/mbuf.h> 48#include <sys/protosw.h> 49#include <sys/socket.h> 50#include <sys/socketvar.h> 51 52#include <net/if.h> 53#include <net/route.h> 54 55#include <netinet/in.h> 56#include <netinet/in_systm.h> 57#include <netinet/ip.h> 58#include <netinet/in_pcb.h> 59#include <netinet/in_var.h> 60#include <netinet/ip_var.h> 61 62#ifdef vax 63#include <machine/mtpr.h> 64#endif 65#include <machine/in_cksum.h> 66 67static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options"); 68 69#if !defined(COMPAT_IPFW) || COMPAT_IPFW == 1 70#undef COMPAT_IPFW 71#define COMPAT_IPFW 1 72#else 73#undef COMPAT_IPFW 74#endif 75 76#ifdef COMPAT_IPFW 77#include <netinet/ip_fw.h> 78#endif 79 80#ifdef DUMMYNET 81#include <netinet/ip_dummynet.h> 82#endif 83 84#ifdef IPFIREWALL_FORWARD_DEBUG 85#define print_ip(a) printf("%ld.%ld.%ld.%ld",(ntohl(a.s_addr)>>24)&0xFF,\ 86 (ntohl(a.s_addr)>>16)&0xFF,\ 87 (ntohl(a.s_addr)>>8)&0xFF,\ 88 (ntohl(a.s_addr))&0xFF); 89#endif 90 91u_short ip_id; 92 93static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *)); 94static void ip_mloopback 95 __P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int)); 96static int ip_getmoptions 97 __P((struct sockopt *, struct ip_moptions *)); 98static int ip_pcbopts __P((int, struct mbuf **, struct mbuf *)); 99static int ip_setmoptions 100 __P((struct sockopt *, struct ip_moptions **)); 101 102#if defined(IPFILTER_LKM) || defined(IPFILTER) 103int ip_optcopy __P((struct ip *, struct ip *)); 104extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); 105#else 106static int ip_optcopy __P((struct ip *, struct ip *)); 107#endif 108 109 110extern struct protosw inetsw[]; 111 112/* 113 * IP output. The packet in mbuf chain m contains a skeletal IP 114 * header (with len, off, ttl, proto, tos, src, dst). 115 * The mbuf chain containing the packet will be freed. 116 * The mbuf opt, if present, will not be freed. 117 */ 118int 119ip_output(m0, opt, ro, flags, imo) 120 struct mbuf *m0; 121 struct mbuf *opt; 122 struct route *ro; 123 int flags; 124 struct ip_moptions *imo; 125{ 126 struct ip *ip, *mhip; 127 struct ifnet *ifp; 128 struct mbuf *m = m0; 129 int hlen = sizeof (struct ip); 130 int len, off, error = 0; 131 struct sockaddr_in *dst; 132 struct in_ifaddr *ia; 133 int isbroadcast; 134#ifdef IPFIREWALL_FORWARD 135 int fwd_rewrite_src = 0; 136#endif 137 138#ifndef IPDIVERT /* dummy variable for the firewall code to play with */ 139 u_short ip_divert_cookie = 0 ; 140#endif 141#ifdef COMPAT_IPFW 142 struct ip_fw_chain *rule = NULL ; 143#endif 144 145#if defined(IPFIREWALL) && defined(DUMMYNET) 146 /* 147 * dummynet packet are prepended a vestigial mbuf with 148 * m_type = MT_DUMMYNET and m_data pointing to the matching 149 * rule. 150 */ 151 if (m->m_type == MT_DUMMYNET) { 152 struct mbuf *tmp_m = m ; 153 /* 154 * the packet was already tagged, so part of the 155 * processing was already done, and we need to go down. 156 * opt, flags and imo have already been used, and now 157 * they are used to hold ifp and hlen and NULL, respectively. 158 */ 159 rule = (struct ip_fw_chain *)(m->m_data) ; 160 m = m->m_next ; 161 free(tmp_m, M_IPFW); 162 ip = mtod(m, struct ip *); 163 dst = (struct sockaddr_in *)&ro->ro_dst; 164 ifp = (struct ifnet *)opt; 165 hlen = IP_VHL_HL(ip->ip_vhl) << 2 ; 166 opt = NULL ; 167 flags = 0 ; /* XXX is this correct ? */ 168 goto sendit; 169 } else 170 rule = NULL ; 171#endif 172 173#ifdef DIAGNOSTIC 174 if ((m->m_flags & M_PKTHDR) == 0) 175 panic("ip_output no HDR"); 176 if (!ro) 177 panic("ip_output no route, proto = %d", 178 mtod(m, struct ip *)->ip_p); 179#endif 180 if (opt) { 181 m = ip_insertoptions(m, opt, &len); 182 hlen = len; 183 } 184 ip = mtod(m, struct ip *); 185 /* 186 * Fill in IP header. 187 */ 188 if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) { 189 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, hlen >> 2); 190 ip->ip_off &= IP_DF; 191 ip->ip_id = htons(ip_id++); 192 ipstat.ips_localout++; 193 } else { 194 hlen = IP_VHL_HL(ip->ip_vhl) << 2; 195 } 196 197 dst = (struct sockaddr_in *)&ro->ro_dst; 198 /* 199 * If there is a cached route, 200 * check that it is to the same destination 201 * and is still up. If not, free it and try again. 202 */ 203 if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || 204 dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { 205 RTFREE(ro->ro_rt); 206 ro->ro_rt = (struct rtentry *)0; 207 } 208 if (ro->ro_rt == 0) { 209 dst->sin_family = AF_INET; 210 dst->sin_len = sizeof(*dst); 211 dst->sin_addr = ip->ip_dst; 212 } 213 /* 214 * If routing to interface only, 215 * short circuit routing lookup. 216 */ 217#define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) 218#define sintosa(sin) ((struct sockaddr *)(sin)) 219 if (flags & IP_ROUTETOIF) { 220 if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 && 221 (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) { 222 ipstat.ips_noroute++; 223 error = ENETUNREACH; 224 goto bad; 225 } 226 ifp = ia->ia_ifp; 227 ip->ip_ttl = 1; 228 isbroadcast = in_broadcast(dst->sin_addr, ifp); 229 } else { 230 /* 231 * If this is the case, we probably don't want to allocate 232 * a protocol-cloned route since we didn't get one from the 233 * ULP. This lets TCP do its thing, while not burdening 234 * forwarding or ICMP with the overhead of cloning a route. 235 * Of course, we still want to do any cloning requested by 236 * the link layer, as this is probably required in all cases 237 * for correct operation (as it is for ARP). 238 */ 239 if (ro->ro_rt == 0) 240 rtalloc_ign(ro, RTF_PRCLONING); 241 if (ro->ro_rt == 0) { 242 ipstat.ips_noroute++; 243 error = EHOSTUNREACH; 244 goto bad; 245 } 246 ia = ifatoia(ro->ro_rt->rt_ifa); 247 ifp = ro->ro_rt->rt_ifp; 248 ro->ro_rt->rt_use++; 249 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 250 dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; 251 if (ro->ro_rt->rt_flags & RTF_HOST) 252 isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST); 253 else 254 isbroadcast = in_broadcast(dst->sin_addr, ifp); 255 } 256 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { 257 struct in_multi *inm; 258 259 m->m_flags |= M_MCAST; 260 /* 261 * IP destination address is multicast. Make sure "dst" 262 * still points to the address in "ro". (It may have been 263 * changed to point to a gateway address, above.) 264 */ 265 dst = (struct sockaddr_in *)&ro->ro_dst; 266 /* 267 * See if the caller provided any multicast options 268 */ 269 if (imo != NULL) { 270 ip->ip_ttl = imo->imo_multicast_ttl; 271 if (imo->imo_multicast_ifp != NULL) 272 ifp = imo->imo_multicast_ifp; 273 if (imo->imo_multicast_vif != -1) 274 ip->ip_src.s_addr = 275 ip_mcast_src(imo->imo_multicast_vif); 276 } else 277 ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL; 278 /* 279 * Confirm that the outgoing interface supports multicast. 280 */ 281 if ((imo == NULL) || (imo->imo_multicast_vif == -1)) { 282 if ((ifp->if_flags & IFF_MULTICAST) == 0) { 283 ipstat.ips_noroute++; 284 error = ENETUNREACH; 285 goto bad; 286 } 287 } 288 /* 289 * If source address not specified yet, use address 290 * of outgoing interface. 291 */ 292 if (ip->ip_src.s_addr == INADDR_ANY) { 293 register struct in_ifaddr *ia1; 294 295 for (ia1 = in_ifaddrhead.tqh_first; ia1; 296 ia1 = ia1->ia_link.tqe_next) 297 if (ia1->ia_ifp == ifp) { 298 ip->ip_src = IA_SIN(ia1)->sin_addr; 299 break; 300 } 301 } 302 303 IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm); 304 if (inm != NULL && 305 (imo == NULL || imo->imo_multicast_loop)) { 306 /* 307 * If we belong to the destination multicast group 308 * on the outgoing interface, and the caller did not 309 * forbid loopback, loop back a copy. 310 */ 311 ip_mloopback(ifp, m, dst, hlen); 312 } 313 else { 314 /* 315 * If we are acting as a multicast router, perform 316 * multicast forwarding as if the packet had just 317 * arrived on the interface to which we are about 318 * to send. The multicast forwarding function 319 * recursively calls this function, using the 320 * IP_FORWARDING flag to prevent infinite recursion. 321 * 322 * Multicasts that are looped back by ip_mloopback(), 323 * above, will be forwarded by the ip_input() routine, 324 * if necessary. 325 */ 326 if (ip_mrouter && (flags & IP_FORWARDING) == 0) { 327 /* 328 * Check if rsvp daemon is running. If not, don't 329 * set ip_moptions. This ensures that the packet 330 * is multicast and not just sent down one link 331 * as prescribed by rsvpd. 332 */ 333 if (!rsvp_on) 334 imo = NULL; 335 if (ip_mforward(ip, ifp, m, imo) != 0) { 336 m_freem(m); 337 goto done; 338 } 339 } 340 } 341 342 /* 343 * Multicasts with a time-to-live of zero may be looped- 344 * back, above, but must not be transmitted on a network. 345 * Also, multicasts addressed to the loopback interface 346 * are not sent -- the above call to ip_mloopback() will 347 * loop back a copy if this host actually belongs to the 348 * destination group on the loopback interface. 349 */ 350 if (ip->ip_ttl == 0 || ifp->if_flags & IFF_LOOPBACK) { 351 m_freem(m); 352 goto done; 353 } 354 355 goto sendit; 356 } 357#ifndef notdef 358 /* 359 * If source address not specified yet, use address 360 * of outgoing interface. 361 */ 362 if (ip->ip_src.s_addr == INADDR_ANY) { 363 ip->ip_src = IA_SIN(ia)->sin_addr; 364#ifdef IPFIREWALL_FORWARD 365 /* Keep note that we did this - if the firewall changes 366 * the next-hop, our interface may change, changing the 367 * default source IP. It's a shame so much effort happens 368 * twice. Oh well. 369 */ 370 fwd_rewrite_src++; 371#endif /* IPFIREWALL_FORWARD */ 372 } 373#endif /* notdef */ 374 /* 375 * Verify that we have any chance at all of being able to queue 376 * the packet or packet fragments 377 */ 378 if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >= 379 ifp->if_snd.ifq_maxlen) { 380 error = ENOBUFS; 381 goto bad; 382 } 383 384 /* 385 * Look for broadcast address and 386 * and verify user is allowed to send 387 * such a packet. 388 */ 389 if (isbroadcast) { 390 if ((ifp->if_flags & IFF_BROADCAST) == 0) { 391 error = EADDRNOTAVAIL; 392 goto bad; 393 } 394 if ((flags & IP_ALLOWBROADCAST) == 0) { 395 error = EACCES; 396 goto bad; 397 } 398 /* don't allow broadcast messages to be fragmented */ 399 if ((u_short)ip->ip_len > ifp->if_mtu) { 400 error = EMSGSIZE; 401 goto bad; 402 } 403 m->m_flags |= M_BCAST; 404 } else { 405 m->m_flags &= ~M_BCAST; 406 } 407 408sendit: 409 /* 410 * IpHack's section. 411 * - Xlate: translate packet's addr/port (NAT). 412 * - Firewall: deny/allow/etc. 413 * - Wrap: fake packet's addr/port <unimpl.> 414 * - Encapsulate: put it in another IP and send out. <unimp.> 415 */ 416#if defined(IPFILTER) || defined(IPFILTER_LKM) 417 if (fr_checkp) { 418 struct mbuf *m1 = m; 419 420 if ((error = (*fr_checkp)(ip, hlen, ifp, 1, &m1)) || !m1) 421 goto done; 422 ip = mtod(m = m1, struct ip *); 423 } 424#endif 425 426#ifdef COMPAT_IPFW 427 if (ip_nat_ptr && !(*ip_nat_ptr)(&ip, &m, ifp, IP_NAT_OUT)) { 428 error = EACCES; 429 goto done; 430 } 431 432 /* 433 * Check with the firewall... 434 */ 435 if (ip_fw_chk_ptr) { 436 struct sockaddr_in *old = dst; 437 438 off = (*ip_fw_chk_ptr)(&ip, 439 hlen, ifp, &ip_divert_cookie, &m, &rule, &dst); 440 /* 441 * On return we must do the following: 442 * m == NULL -> drop the pkt 443 * 1<=off<= 0xffff -> DIVERT 444 * (off & 0x10000) -> send to a DUMMYNET pipe 445 * dst != old -> IPFIREWALL_FORWARD 446 * off==0, dst==old -> accept 447 * If some of the above modules is not compiled in, then 448 * we should't have to check the corresponding condition 449 * (because the ipfw control socket should not accept 450 * unsupported rules), but better play safe and drop 451 * packets in case of doubt. 452 */ 453 if (!m) { /* firewall said to reject */ 454 error = EACCES; 455 goto done; 456 } 457 if (off == 0 && dst == old) /* common case */ 458 goto pass ; 459#ifdef DUMMYNET 460 if (off & 0x10000) { 461 /* 462 * pass the pkt to dummynet. Need to include 463 * pipe number, m, ifp, ro, hlen because these are 464 * not recomputed in the next pass. 465 * All other parameters have been already used and 466 * so they are not needed anymore. 467 * XXX note: if the ifp or ro entry are deleted 468 * while a pkt is in dummynet, we are in trouble! 469 */ 470 dummynet_io(off & 0xffff, DN_TO_IP_OUT, m,ifp,ro,hlen,rule); 471 goto done; 472 } 473#endif 474#ifdef IPDIVERT 475 if (off > 0 && off < 0x10000) { /* Divert packet */ 476 ip_divert_port = off & 0xffff ; 477 (*inetsw[ip_protox[IPPROTO_DIVERT]].pr_input)(m, 0); 478 goto done; 479 } 480#endif 481 482#ifdef IPFIREWALL_FORWARD 483 /* Here we check dst to make sure it's directly reachable on the 484 * interface we previously thought it was. 485 * If it isn't (which may be likely in some situations) we have 486 * to re-route it (ie, find a route for the next-hop and the 487 * associated interface) and set them here. This is nested 488 * forwarding which in most cases is undesirable, except where 489 * such control is nigh impossible. So we do it here. 490 * And I'm babbling. 491 */ 492 if (off == 0 && old != dst) { 493 struct in_ifaddr *ia; 494 495 /* It's changed... */ 496 /* There must be a better way to do this next line... */ 497 static struct route sro_fwd, *ro_fwd = &sro_fwd; 498#ifdef IPFIREWALL_FORWARD_DEBUG 499 printf("IPFIREWALL_FORWARD: New dst ip: "); 500 print_ip(dst->sin_addr); 501 printf("\n"); 502#endif 503 /* 504 * We need to figure out if we have been forwarded 505 * to a local socket. If so then we should somehow 506 * "loop back" to ip_input, and get directed to the 507 * PCB as if we had received this packet. This is 508 * because it may be dificult to identify the packets 509 * you want to forward until they are being output 510 * and have selected an interface. (e.g. locally 511 * initiated packets) If we used the loopback inteface, 512 * we would not be able to control what happens 513 * as the packet runs through ip_input() as 514 * it is done through a ISR. 515 */ 516 for (ia = TAILQ_FIRST(&in_ifaddrhead); ia; 517 ia = TAILQ_NEXT(ia, ia_link)) { 518 /* 519 * If the addr to forward to is one 520 * of ours, we pretend to 521 * be the destination for this packet. 522 */ 523 if (IA_SIN(ia)->sin_addr.s_addr == 524 dst->sin_addr.s_addr) 525 break; 526 } 527 if (ia) { 528 /* tell ip_input "dont filter" */ 529 ip_fw_fwd_addr = dst; 530 if (m->m_pkthdr.rcvif == NULL) 531 m->m_pkthdr.rcvif = ifunit("lo0"); 532 ip->ip_len = htons((u_short)ip->ip_len); 533 ip->ip_off = htons((u_short)ip->ip_off); 534 ip->ip_sum = 0; 535 if (ip->ip_vhl == IP_VHL_BORING) { 536 ip->ip_sum = in_cksum_hdr(ip); 537 } else { 538 ip->ip_sum = in_cksum(m, hlen); 539 } 540 ip_input(m); 541 goto done; 542 } 543 /* Some of the logic for this was 544 * nicked from above. 545 * 546 * This rewrites the cached route in a local PCB. 547 * Is this what we want to do? 548 */ 549 bcopy(dst, &ro_fwd->ro_dst, sizeof(*dst)); 550 551 ro_fwd->ro_rt = 0; 552 rtalloc_ign(ro_fwd, RTF_PRCLONING); 553 554 if (ro_fwd->ro_rt == 0) { 555 ipstat.ips_noroute++; 556 error = EHOSTUNREACH; 557 goto bad; 558 } 559 560 ia = ifatoia(ro_fwd->ro_rt->rt_ifa); 561 ifp = ro_fwd->ro_rt->rt_ifp; 562 ro_fwd->ro_rt->rt_use++; 563 if (ro_fwd->ro_rt->rt_flags & RTF_GATEWAY) 564 dst = (struct sockaddr_in *)ro_fwd->ro_rt->rt_gateway; 565 if (ro_fwd->ro_rt->rt_flags & RTF_HOST) 566 isbroadcast = 567 (ro_fwd->ro_rt->rt_flags & RTF_BROADCAST); 568 else 569 isbroadcast = in_broadcast(dst->sin_addr, ifp); 570 RTFREE(ro->ro_rt); 571 ro->ro_rt = ro_fwd->ro_rt; 572 dst = (struct sockaddr_in *)&ro_fwd->ro_dst; 573 574 /* 575 * If we added a default src ip earlier, 576 * which would have been gotten from the-then 577 * interface, do it again, from the new one. 578 */ 579 if (fwd_rewrite_src) 580 ip->ip_src = IA_SIN(ia)->sin_addr; 581 goto pass ; 582 } 583#endif /* IPFIREWALL_FORWARD */ 584 /* 585 * if we get here, none of the above matches, and 586 * we have to drop the pkt 587 */ 588 m_freem(m); 589 error = EACCES; /* not sure this is the right error msg */ 590 goto done; 591 } 592#endif /* COMPAT_IPFW */ 593 594pass: 595 /* 596 * If small enough for interface, can just send directly. 597 */ 598 if ((u_short)ip->ip_len <= ifp->if_mtu) { 599 ip->ip_len = htons((u_short)ip->ip_len); 600 ip->ip_off = htons((u_short)ip->ip_off); 601 ip->ip_sum = 0; 602 if (ip->ip_vhl == IP_VHL_BORING) { 603 ip->ip_sum = in_cksum_hdr(ip); 604 } else { 605 ip->ip_sum = in_cksum(m, hlen); 606 } 607 error = (*ifp->if_output)(ifp, m, 608 (struct sockaddr *)dst, ro->ro_rt); 609 goto done; 610 } 611 /* 612 * Too large for interface; fragment if possible. 613 * Must be able to put at least 8 bytes per fragment. 614 */ 615 if (ip->ip_off & IP_DF) { 616 error = EMSGSIZE; 617 /* 618 * This case can happen if the user changed the MTU 619 * of an interface after enabling IP on it. Because 620 * most netifs don't keep track of routes pointing to 621 * them, there is no way for one to update all its 622 * routes when the MTU is changed. 623 */ 624 if ((ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST)) 625 && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU) 626 && (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) { 627 ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu; 628 } 629 ipstat.ips_cantfrag++; 630 goto bad; 631 } 632 len = (ifp->if_mtu - hlen) &~ 7; 633 if (len < 8) { 634 error = EMSGSIZE; 635 goto bad; 636 } 637 638 { 639 int mhlen, firstlen = len; 640 struct mbuf **mnext = &m->m_nextpkt; 641 642 /* 643 * Loop through length of segment after first fragment, 644 * make new header and copy data of each part and link onto chain. 645 */ 646 m0 = m; 647 mhlen = sizeof (struct ip); 648 for (off = hlen + len; off < (u_short)ip->ip_len; off += len) { 649 MGETHDR(m, M_DONTWAIT, MT_HEADER); 650 if (m == 0) { 651 error = ENOBUFS; 652 ipstat.ips_odropped++; 653 goto sendorfree; 654 } 655 m->m_flags |= (m0->m_flags & M_MCAST); 656 m->m_data += max_linkhdr; 657 mhip = mtod(m, struct ip *); 658 *mhip = *ip; 659 if (hlen > sizeof (struct ip)) { 660 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); 661 mhip->ip_vhl = IP_MAKE_VHL(IPVERSION, mhlen >> 2); 662 } 663 m->m_len = mhlen; 664 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); 665 if (ip->ip_off & IP_MF) 666 mhip->ip_off |= IP_MF; 667 if (off + len >= (u_short)ip->ip_len) 668 len = (u_short)ip->ip_len - off; 669 else 670 mhip->ip_off |= IP_MF; 671 mhip->ip_len = htons((u_short)(len + mhlen)); 672 m->m_next = m_copy(m0, off, len); 673 if (m->m_next == 0) { 674 (void) m_free(m); 675 error = ENOBUFS; /* ??? */ 676 ipstat.ips_odropped++; 677 goto sendorfree; 678 } 679 m->m_pkthdr.len = mhlen + len; 680 m->m_pkthdr.rcvif = (struct ifnet *)0; 681 mhip->ip_off = htons((u_short)mhip->ip_off); 682 mhip->ip_sum = 0; 683 if (mhip->ip_vhl == IP_VHL_BORING) { 684 mhip->ip_sum = in_cksum_hdr(mhip); 685 } else { 686 mhip->ip_sum = in_cksum(m, mhlen); 687 } 688 *mnext = m; 689 mnext = &m->m_nextpkt; 690 ipstat.ips_ofragments++; 691 } 692 /* 693 * Update first fragment by trimming what's been copied out 694 * and updating header, then send each fragment (in order). 695 */ 696 m = m0; 697 m_adj(m, hlen + firstlen - (u_short)ip->ip_len); 698 m->m_pkthdr.len = hlen + firstlen; 699 ip->ip_len = htons((u_short)m->m_pkthdr.len); 700 ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); 701 ip->ip_sum = 0; 702 if (ip->ip_vhl == IP_VHL_BORING) { 703 ip->ip_sum = in_cksum_hdr(ip); 704 } else { 705 ip->ip_sum = in_cksum(m, hlen); 706 } 707sendorfree: 708 for (m = m0; m; m = m0) { 709 m0 = m->m_nextpkt; 710 m->m_nextpkt = 0; 711 if (error == 0) 712 error = (*ifp->if_output)(ifp, m, 713 (struct sockaddr *)dst, ro->ro_rt); 714 else 715 m_freem(m); 716 } 717 718 if (error == 0) 719 ipstat.ips_fragmented++; 720 } 721done: 722 return (error); 723bad: 724 m_freem(m0); 725 goto done; 726} 727 728/* 729 * Insert IP options into preformed packet. 730 * Adjust IP destination as required for IP source routing, 731 * as indicated by a non-zero in_addr at the start of the options. 732 * 733 * XXX This routine assumes that the packet has no options in place. 734 */ 735static struct mbuf * 736ip_insertoptions(m, opt, phlen) 737 register struct mbuf *m; 738 struct mbuf *opt; 739 int *phlen; 740{ 741 register struct ipoption *p = mtod(opt, struct ipoption *); 742 struct mbuf *n; 743 register struct ip *ip = mtod(m, struct ip *); 744 unsigned optlen; 745 746 optlen = opt->m_len - sizeof(p->ipopt_dst); 747 if (optlen + (u_short)ip->ip_len > IP_MAXPACKET) 748 return (m); /* XXX should fail */ 749 if (p->ipopt_dst.s_addr) 750 ip->ip_dst = p->ipopt_dst; 751 if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) { 752 MGETHDR(n, M_DONTWAIT, MT_HEADER); 753 if (n == 0) 754 return (m); 755 n->m_pkthdr.len = m->m_pkthdr.len + optlen; 756 m->m_len -= sizeof(struct ip); 757 m->m_data += sizeof(struct ip); 758 n->m_next = m; 759 m = n; 760 m->m_len = optlen + sizeof(struct ip); 761 m->m_data += max_linkhdr; 762 (void)memcpy(mtod(m, void *), ip, sizeof(struct ip)); 763 } else { 764 m->m_data -= optlen; 765 m->m_len += optlen; 766 m->m_pkthdr.len += optlen; 767 ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip)); 768 } 769 ip = mtod(m, struct ip *); 770 bcopy(p->ipopt_list, ip + 1, optlen); 771 *phlen = sizeof(struct ip) + optlen; 772 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, *phlen >> 2); 773 ip->ip_len += optlen; 774 return (m); 775} 776 777/* 778 * Copy options from ip to jp, 779 * omitting those not copied during fragmentation. 780 */ 781#if !defined(IPFILTER) && !defined(IPFILTER_LKM) 782static 783#endif 784int 785ip_optcopy(ip, jp) 786 struct ip *ip, *jp; 787{ 788 register u_char *cp, *dp; 789 int opt, optlen, cnt; 790 791 cp = (u_char *)(ip + 1); 792 dp = (u_char *)(jp + 1); 793 cnt = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip); 794 for (; cnt > 0; cnt -= optlen, cp += optlen) { 795 opt = cp[0]; 796 if (opt == IPOPT_EOL) 797 break; 798 if (opt == IPOPT_NOP) { 799 /* Preserve for IP mcast tunnel's LSRR alignment. */ 800 *dp++ = IPOPT_NOP; 801 optlen = 1; 802 continue; 803 } else 804 optlen = cp[IPOPT_OLEN]; 805 /* bogus lengths should have been caught by ip_dooptions */ 806 if (optlen > cnt) 807 optlen = cnt; 808 if (IPOPT_COPIED(opt)) { 809 bcopy(cp, dp, optlen); 810 dp += optlen; 811 } 812 } 813 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++) 814 *dp++ = IPOPT_EOL; 815 return (optlen); 816} 817 818/* 819 * IP socket option processing. 820 */ 821int 822ip_ctloutput(so, sopt) 823 struct socket *so; 824 struct sockopt *sopt; 825{ 826 struct inpcb *inp = sotoinpcb(so); 827 int error, optval; 828 829 error = optval = 0; 830 if (sopt->sopt_level != IPPROTO_IP) { 831 return (EINVAL); 832 } 833 834 switch (sopt->sopt_dir) { 835 case SOPT_SET: 836 switch (sopt->sopt_name) { 837 case IP_OPTIONS: 838#ifdef notyet 839 case IP_RETOPTS: 840#endif 841 { 842 struct mbuf *m; 843 if (sopt->sopt_valsize > MLEN) { 844 error = EMSGSIZE; 845 break; 846 } 847 MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_HEADER); 848 if (m == 0) { 849 error = ENOBUFS; 850 break; 851 } 852 m->m_len = sopt->sopt_valsize; 853 error = sooptcopyin(sopt, mtod(m, char *), m->m_len, 854 m->m_len); 855 856 return (ip_pcbopts(sopt->sopt_name, &inp->inp_options, 857 m)); 858 } 859 860 case IP_TOS: 861 case IP_TTL: 862 case IP_RECVOPTS: 863 case IP_RECVRETOPTS: 864 case IP_RECVDSTADDR: 865 case IP_RECVIF: 866 error = sooptcopyin(sopt, &optval, sizeof optval, 867 sizeof optval); 868 if (error) 869 break; 870 871 switch (sopt->sopt_name) { 872 case IP_TOS: 873 inp->inp_ip_tos = optval; 874 break; 875 876 case IP_TTL: 877 inp->inp_ip_ttl = optval; 878 break; 879#define OPTSET(bit) \ 880 if (optval) \ 881 inp->inp_flags |= bit; \ 882 else \ 883 inp->inp_flags &= ~bit; 884 885 case IP_RECVOPTS: 886 OPTSET(INP_RECVOPTS); 887 break; 888 889 case IP_RECVRETOPTS: 890 OPTSET(INP_RECVRETOPTS); 891 break; 892 893 case IP_RECVDSTADDR: 894 OPTSET(INP_RECVDSTADDR); 895 break; 896 897 case IP_RECVIF: 898 OPTSET(INP_RECVIF); 899 break; 900 } 901 break; 902#undef OPTSET 903 904 case IP_MULTICAST_IF: 905 case IP_MULTICAST_VIF: 906 case IP_MULTICAST_TTL: 907 case IP_MULTICAST_LOOP: 908 case IP_ADD_MEMBERSHIP: 909 case IP_DROP_MEMBERSHIP: 910 error = ip_setmoptions(sopt, &inp->inp_moptions); 911 break; 912 913 case IP_PORTRANGE: 914 error = sooptcopyin(sopt, &optval, sizeof optval, 915 sizeof optval); 916 if (error) 917 break; 918 919 switch (optval) { 920 case IP_PORTRANGE_DEFAULT: 921 inp->inp_flags &= ~(INP_LOWPORT); 922 inp->inp_flags &= ~(INP_HIGHPORT); 923 break; 924 925 case IP_PORTRANGE_HIGH: 926 inp->inp_flags &= ~(INP_LOWPORT); 927 inp->inp_flags |= INP_HIGHPORT; 928 break; 929 930 case IP_PORTRANGE_LOW: 931 inp->inp_flags &= ~(INP_HIGHPORT); 932 inp->inp_flags |= INP_LOWPORT; 933 break; 934 935 default: 936 error = EINVAL; 937 break; 938 } 939 break; 940 941 default: 942 error = ENOPROTOOPT; 943 break; 944 } 945 break; 946 947 case SOPT_GET: 948 switch (sopt->sopt_name) { 949 case IP_OPTIONS: 950 case IP_RETOPTS: 951 if (inp->inp_options) 952 error = sooptcopyout(sopt, 953 mtod(inp->inp_options, 954 char *), 955 inp->inp_options->m_len); 956 else 957 sopt->sopt_valsize = 0; 958 break; 959 960 case IP_TOS: 961 case IP_TTL: 962 case IP_RECVOPTS: 963 case IP_RECVRETOPTS: 964 case IP_RECVDSTADDR: 965 case IP_RECVIF: 966 case IP_PORTRANGE: 967 switch (sopt->sopt_name) { 968 969 case IP_TOS: 970 optval = inp->inp_ip_tos; 971 break; 972 973 case IP_TTL: 974 optval = inp->inp_ip_ttl; 975 break; 976 977#define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0) 978 979 case IP_RECVOPTS: 980 optval = OPTBIT(INP_RECVOPTS); 981 break; 982 983 case IP_RECVRETOPTS: 984 optval = OPTBIT(INP_RECVRETOPTS); 985 break; 986 987 case IP_RECVDSTADDR: 988 optval = OPTBIT(INP_RECVDSTADDR); 989 break; 990 991 case IP_RECVIF: 992 optval = OPTBIT(INP_RECVIF); 993 break; 994 995 case IP_PORTRANGE: 996 if (inp->inp_flags & INP_HIGHPORT) 997 optval = IP_PORTRANGE_HIGH; 998 else if (inp->inp_flags & INP_LOWPORT) 999 optval = IP_PORTRANGE_LOW; 1000 else 1001 optval = 0; 1002 break; 1003 } 1004 error = sooptcopyout(sopt, &optval, sizeof optval); 1005 break; 1006 1007 case IP_MULTICAST_IF: 1008 case IP_MULTICAST_VIF: 1009 case IP_MULTICAST_TTL: 1010 case IP_MULTICAST_LOOP: 1011 case IP_ADD_MEMBERSHIP: 1012 case IP_DROP_MEMBERSHIP: 1013 error = ip_getmoptions(sopt, inp->inp_moptions); 1014 break; 1015 1016 default: 1017 error = ENOPROTOOPT; 1018 break; 1019 } 1020 break; 1021 } 1022 return (error); 1023} 1024 1025/* 1026 * Set up IP options in pcb for insertion in output packets. 1027 * Store in mbuf with pointer in pcbopt, adding pseudo-option 1028 * with destination address if source routed. 1029 */ 1030static int 1031ip_pcbopts(optname, pcbopt, m) 1032 int optname; 1033 struct mbuf **pcbopt; 1034 register struct mbuf *m; 1035{ 1036 register int cnt, optlen; 1037 register u_char *cp; 1038 u_char opt; 1039 1040 /* turn off any old options */ 1041 if (*pcbopt) 1042 (void)m_free(*pcbopt); 1043 *pcbopt = 0; 1044 if (m == (struct mbuf *)0 || m->m_len == 0) { 1045 /* 1046 * Only turning off any previous options. 1047 */ 1048 if (m) 1049 (void)m_free(m); 1050 return (0); 1051 } 1052 1053#ifndef vax 1054 if (m->m_len % sizeof(int32_t)) 1055 goto bad; 1056#endif 1057 /* 1058 * IP first-hop destination address will be stored before 1059 * actual options; move other options back 1060 * and clear it when none present. 1061 */ 1062 if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN]) 1063 goto bad; 1064 cnt = m->m_len; 1065 m->m_len += sizeof(struct in_addr); 1066 cp = mtod(m, u_char *) + sizeof(struct in_addr); 1067 ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt); 1068 bzero(mtod(m, caddr_t), sizeof(struct in_addr)); 1069 1070 for (; cnt > 0; cnt -= optlen, cp += optlen) { 1071 opt = cp[IPOPT_OPTVAL]; 1072 if (opt == IPOPT_EOL) 1073 break; 1074 if (opt == IPOPT_NOP) 1075 optlen = 1; 1076 else { 1077 optlen = cp[IPOPT_OLEN]; 1078 if (optlen <= IPOPT_OLEN || optlen > cnt) 1079 goto bad; 1080 } 1081 switch (opt) { 1082 1083 default: 1084 break; 1085 1086 case IPOPT_LSRR: 1087 case IPOPT_SSRR: 1088 /* 1089 * user process specifies route as: 1090 * ->A->B->C->D 1091 * D must be our final destination (but we can't 1092 * check that since we may not have connected yet). 1093 * A is first hop destination, which doesn't appear in 1094 * actual IP option, but is stored before the options. 1095 */ 1096 if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr)) 1097 goto bad; 1098 m->m_len -= sizeof(struct in_addr); 1099 cnt -= sizeof(struct in_addr); 1100 optlen -= sizeof(struct in_addr); 1101 cp[IPOPT_OLEN] = optlen; 1102 /* 1103 * Move first hop before start of options. 1104 */ 1105 bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t), 1106 sizeof(struct in_addr)); 1107 /* 1108 * Then copy rest of options back 1109 * to close up the deleted entry. 1110 */ 1111 ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] + 1112 sizeof(struct in_addr)), 1113 (caddr_t)&cp[IPOPT_OFFSET+1], 1114 (unsigned)cnt + sizeof(struct in_addr)); 1115 break; 1116 } 1117 } 1118 if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr)) 1119 goto bad; 1120 *pcbopt = m; 1121 return (0); 1122 1123bad: 1124 (void)m_free(m); 1125 return (EINVAL); 1126} 1127 1128/* 1129 * XXX 1130 * The whole multicast option thing needs to be re-thought. 1131 * Several of these options are equally applicable to non-multicast 1132 * transmission, and one (IP_MULTICAST_TTL) totally duplicates a 1133 * standard option (IP_TTL). 1134 */ 1135/* 1136 * Set the IP multicast options in response to user setsockopt(). 1137 */ 1138static int 1139ip_setmoptions(sopt, imop) 1140 struct sockopt *sopt; 1141 struct ip_moptions **imop; 1142{ 1143 int error = 0; 1144 int i; 1145 struct in_addr addr; 1146 struct ip_mreq mreq; 1147 struct ifnet *ifp; 1148 struct ip_moptions *imo = *imop; 1149 struct route ro; 1150 struct sockaddr_in *dst; 1151 int s; 1152 1153 if (imo == NULL) { 1154 /* 1155 * No multicast option buffer attached to the pcb; 1156 * allocate one and initialize to default values. 1157 */ 1158 imo = (struct ip_moptions*)malloc(sizeof(*imo), M_IPMOPTS, 1159 M_WAITOK); 1160 1161 if (imo == NULL) 1162 return (ENOBUFS); 1163 *imop = imo; 1164 imo->imo_multicast_ifp = NULL; 1165 imo->imo_multicast_vif = -1; 1166 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL; 1167 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP; 1168 imo->imo_num_memberships = 0; 1169 } 1170 1171 switch (sopt->sopt_name) { 1172 /* store an index number for the vif you wanna use in the send */ 1173 case IP_MULTICAST_VIF: 1174 if (legal_vif_num == 0) { 1175 error = EOPNOTSUPP; 1176 break; 1177 } 1178 error = sooptcopyin(sopt, &i, sizeof i, sizeof i); 1179 if (error) 1180 break; 1181 if (!legal_vif_num(i) && (i != -1)) { 1182 error = EINVAL; 1183 break; 1184 } 1185 imo->imo_multicast_vif = i; 1186 break; 1187 1188 case IP_MULTICAST_IF: 1189 /* 1190 * Select the interface for outgoing multicast packets. 1191 */ 1192 error = sooptcopyin(sopt, &addr, sizeof addr, sizeof addr); 1193 if (error) 1194 break; 1195 /* 1196 * INADDR_ANY is used to remove a previous selection. 1197 * When no interface is selected, a default one is 1198 * chosen every time a multicast packet is sent. 1199 */ 1200 if (addr.s_addr == INADDR_ANY) { 1201 imo->imo_multicast_ifp = NULL; 1202 break; 1203 } 1204 /* 1205 * The selected interface is identified by its local 1206 * IP address. Find the interface and confirm that 1207 * it supports multicasting. 1208 */ 1209 s = splimp(); 1210 INADDR_TO_IFP(addr, ifp); 1211 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 1212 splx(s); 1213 error = EADDRNOTAVAIL; 1214 break; 1215 } 1216 imo->imo_multicast_ifp = ifp; 1217 splx(s); 1218 break; 1219 1220 case IP_MULTICAST_TTL: 1221 /* 1222 * Set the IP time-to-live for outgoing multicast packets. 1223 * The original multicast API required a char argument, 1224 * which is inconsistent with the rest of the socket API. 1225 * We allow either a char or an int. 1226 */ 1227 if (sopt->sopt_valsize == 1) { 1228 u_char ttl; 1229 error = sooptcopyin(sopt, &ttl, 1, 1); 1230 if (error) 1231 break; 1232 imo->imo_multicast_ttl = ttl; 1233 } else { 1234 u_int ttl; 1235 error = sooptcopyin(sopt, &ttl, sizeof ttl, 1236 sizeof ttl); 1237 if (error) 1238 break; 1239 if (ttl > 255) 1240 error = EINVAL; 1241 else 1242 imo->imo_multicast_ttl = ttl; 1243 } 1244 break; 1245 1246 case IP_MULTICAST_LOOP: 1247 /* 1248 * Set the loopback flag for outgoing multicast packets. 1249 * Must be zero or one. The original multicast API required a 1250 * char argument, which is inconsistent with the rest 1251 * of the socket API. We allow either a char or an int. 1252 */ 1253 if (sopt->sopt_valsize == 1) { 1254 u_char loop; 1255 error = sooptcopyin(sopt, &loop, 1, 1); 1256 if (error) 1257 break; 1258 imo->imo_multicast_loop = !!loop; 1259 } else { 1260 u_int loop; 1261 error = sooptcopyin(sopt, &loop, sizeof loop, 1262 sizeof loop); 1263 if (error) 1264 break; 1265 imo->imo_multicast_loop = !!loop; 1266 } 1267 break; 1268 1269 case IP_ADD_MEMBERSHIP: 1270 /* 1271 * Add a multicast group membership. 1272 * Group must be a valid IP multicast address. 1273 */ 1274 error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq); 1275 if (error) 1276 break; 1277 1278 if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) { 1279 error = EINVAL; 1280 break; 1281 } 1282 s = splimp(); 1283 /* 1284 * If no interface address was provided, use the interface of 1285 * the route to the given multicast address. 1286 */ 1287 if (mreq.imr_interface.s_addr == INADDR_ANY) { 1288 bzero((caddr_t)&ro, sizeof(ro)); 1289 dst = (struct sockaddr_in *)&ro.ro_dst; 1290 dst->sin_len = sizeof(*dst); 1291 dst->sin_family = AF_INET; 1292 dst->sin_addr = mreq.imr_multiaddr; 1293 rtalloc(&ro); 1294 if (ro.ro_rt == NULL) { 1295 error = EADDRNOTAVAIL; 1296 splx(s); 1297 break; 1298 } 1299 ifp = ro.ro_rt->rt_ifp; 1300 rtfree(ro.ro_rt); 1301 } 1302 else { 1303 INADDR_TO_IFP(mreq.imr_interface, ifp); 1304 } 1305 1306 /* 1307 * See if we found an interface, and confirm that it 1308 * supports multicast. 1309 */ 1310 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 1311 error = EADDRNOTAVAIL; 1312 splx(s); 1313 break; 1314 } 1315 /* 1316 * See if the membership already exists or if all the 1317 * membership slots are full. 1318 */ 1319 for (i = 0; i < imo->imo_num_memberships; ++i) { 1320 if (imo->imo_membership[i]->inm_ifp == ifp && 1321 imo->imo_membership[i]->inm_addr.s_addr 1322 == mreq.imr_multiaddr.s_addr) 1323 break; 1324 } 1325 if (i < imo->imo_num_memberships) { 1326 error = EADDRINUSE; 1327 splx(s); 1328 break; 1329 } 1330 if (i == IP_MAX_MEMBERSHIPS) { 1331 error = ETOOMANYREFS; 1332 splx(s); 1333 break; 1334 } 1335 /* 1336 * Everything looks good; add a new record to the multicast 1337 * address list for the given interface. 1338 */ 1339 if ((imo->imo_membership[i] = 1340 in_addmulti(&mreq.imr_multiaddr, ifp)) == NULL) { 1341 error = ENOBUFS; 1342 splx(s); 1343 break; 1344 } 1345 ++imo->imo_num_memberships; 1346 splx(s); 1347 break; 1348 1349 case IP_DROP_MEMBERSHIP: 1350 /* 1351 * Drop a multicast group membership. 1352 * Group must be a valid IP multicast address. 1353 */ 1354 error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq); 1355 if (error) 1356 break; 1357 1358 if (!IN_MULTICAST(ntohl(mreq.imr_multiaddr.s_addr))) { 1359 error = EINVAL; 1360 break; 1361 } 1362 1363 s = splimp(); 1364 /* 1365 * If an interface address was specified, get a pointer 1366 * to its ifnet structure. 1367 */ 1368 if (mreq.imr_interface.s_addr == INADDR_ANY) 1369 ifp = NULL; 1370 else { 1371 INADDR_TO_IFP(mreq.imr_interface, ifp); 1372 if (ifp == NULL) { 1373 error = EADDRNOTAVAIL; 1374 splx(s); 1375 break; 1376 } 1377 } 1378 /* 1379 * Find the membership in the membership array. 1380 */ 1381 for (i = 0; i < imo->imo_num_memberships; ++i) { 1382 if ((ifp == NULL || 1383 imo->imo_membership[i]->inm_ifp == ifp) && 1384 imo->imo_membership[i]->inm_addr.s_addr == 1385 mreq.imr_multiaddr.s_addr) 1386 break; 1387 } 1388 if (i == imo->imo_num_memberships) { 1389 error = EADDRNOTAVAIL; 1390 splx(s); 1391 break; 1392 } 1393 /* 1394 * Give up the multicast address record to which the 1395 * membership points. 1396 */ 1397 in_delmulti(imo->imo_membership[i]); 1398 /* 1399 * Remove the gap in the membership array. 1400 */ 1401 for (++i; i < imo->imo_num_memberships; ++i) 1402 imo->imo_membership[i-1] = imo->imo_membership[i]; 1403 --imo->imo_num_memberships; 1404 splx(s); 1405 break; 1406 1407 default: 1408 error = EOPNOTSUPP; 1409 break; 1410 } 1411 1412 /* 1413 * If all options have default values, no need to keep the mbuf. 1414 */ 1415 if (imo->imo_multicast_ifp == NULL && 1416 imo->imo_multicast_vif == -1 && 1417 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL && 1418 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP && 1419 imo->imo_num_memberships == 0) { 1420 free(*imop, M_IPMOPTS); 1421 *imop = NULL; 1422 } 1423 1424 return (error); 1425} 1426 1427/* 1428 * Return the IP multicast options in response to user getsockopt(). 1429 */ 1430static int 1431ip_getmoptions(sopt, imo) 1432 struct sockopt *sopt; 1433 register struct ip_moptions *imo; 1434{ 1435 struct in_addr addr; 1436 struct in_ifaddr *ia; 1437 int error, optval; 1438 u_char coptval; 1439 1440 error = 0; 1441 switch (sopt->sopt_name) { 1442 case IP_MULTICAST_VIF: 1443 if (imo != NULL) 1444 optval = imo->imo_multicast_vif; 1445 else 1446 optval = -1; 1447 error = sooptcopyout(sopt, &optval, sizeof optval); 1448 break; 1449 1450 case IP_MULTICAST_IF: 1451 if (imo == NULL || imo->imo_multicast_ifp == NULL) 1452 addr.s_addr = INADDR_ANY; 1453 else { 1454 IFP_TO_IA(imo->imo_multicast_ifp, ia); 1455 addr.s_addr = (ia == NULL) ? INADDR_ANY 1456 : IA_SIN(ia)->sin_addr.s_addr; 1457 } 1458 error = sooptcopyout(sopt, &addr, sizeof addr); 1459 break; 1460 1461 case IP_MULTICAST_TTL: 1462 if (imo == 0) 1463 optval = coptval = IP_DEFAULT_MULTICAST_TTL; 1464 else 1465 optval = coptval = imo->imo_multicast_ttl; 1466 if (sopt->sopt_valsize == 1) 1467 error = sooptcopyout(sopt, &coptval, 1); 1468 else 1469 error = sooptcopyout(sopt, &optval, sizeof optval); 1470 break; 1471 1472 case IP_MULTICAST_LOOP: 1473 if (imo == 0) 1474 optval = coptval = IP_DEFAULT_MULTICAST_LOOP; 1475 else 1476 optval = coptval = imo->imo_multicast_loop; 1477 if (sopt->sopt_valsize == 1) 1478 error = sooptcopyout(sopt, &coptval, 1); 1479 else 1480 error = sooptcopyout(sopt, &optval, sizeof optval); 1481 break; 1482 1483 default: 1484 error = ENOPROTOOPT; 1485 break; 1486 } 1487 return (error); 1488} 1489 1490/* 1491 * Discard the IP multicast options. 1492 */ 1493void 1494ip_freemoptions(imo) 1495 register struct ip_moptions *imo; 1496{ 1497 register int i; 1498 1499 if (imo != NULL) { 1500 for (i = 0; i < imo->imo_num_memberships; ++i) 1501 in_delmulti(imo->imo_membership[i]); 1502 free(imo, M_IPMOPTS); 1503 } 1504} 1505 1506/* 1507 * Routine called from ip_output() to loop back a copy of an IP multicast 1508 * packet to the input queue of a specified interface. Note that this 1509 * calls the output routine of the loopback "driver", but with an interface 1510 * pointer that might NOT be a loopback interface -- evil, but easier than 1511 * replicating that code here. 1512 */ 1513static void 1514ip_mloopback(ifp, m, dst, hlen) 1515 struct ifnet *ifp; 1516 register struct mbuf *m; 1517 register struct sockaddr_in *dst; 1518 int hlen; 1519{ 1520 register struct ip *ip; 1521 struct mbuf *copym; 1522 1523 copym = m_copy(m, 0, M_COPYALL); 1524 if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen)) 1525 copym = m_pullup(copym, hlen); 1526 if (copym != NULL) { 1527 /* 1528 * We don't bother to fragment if the IP length is greater 1529 * than the interface's MTU. Can this possibly matter? 1530 */ 1531 ip = mtod(copym, struct ip *); 1532 ip->ip_len = htons((u_short)ip->ip_len); 1533 ip->ip_off = htons((u_short)ip->ip_off); 1534 ip->ip_sum = 0; 1535 if (ip->ip_vhl == IP_VHL_BORING) { 1536 ip->ip_sum = in_cksum_hdr(ip); 1537 } else { 1538 ip->ip_sum = in_cksum(copym, hlen); 1539 } 1540 /* 1541 * NB: 1542 * It's not clear whether there are any lingering 1543 * reentrancy problems in other areas which might 1544 * be exposed by using ip_input directly (in 1545 * particular, everything which modifies the packet 1546 * in-place). Yet another option is using the 1547 * protosw directly to deliver the looped back 1548 * packet. For the moment, we'll err on the side 1549 * of safety by using if_simloop(). 1550 */ 1551#if 1 /* XXX */ 1552 if (dst->sin_family != AF_INET) { 1553 printf("ip_mloopback: bad address family %d\n", 1554 dst->sin_family); 1555 dst->sin_family = AF_INET; 1556 } 1557#endif 1558 1559#ifdef notdef 1560 copym->m_pkthdr.rcvif = ifp; 1561 ip_input(copym); 1562#else 1563 if_simloop(ifp, copym, (struct sockaddr *)dst, 0); 1564#endif 1565 } 1566} 1567