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