ip_output.c revision 15652
192372Sphk/* 292372Sphk * Copyright (c) 1982, 1986, 1988, 1990, 1993 392372Sphk * The Regents of the University of California. All rights reserved. 492372Sphk * 592372Sphk * Redistribution and use in source and binary forms, with or without 692372Sphk * modification, are permitted provided that the following conditions 792372Sphk * are met: 892372Sphk * 1. Redistributions of source code must retain the above copyright 992372Sphk * notice, this list of conditions and the following disclaimer. 1092372Sphk * 2. Redistributions in binary form must reproduce the above copyright 1192372Sphk * notice, this list of conditions and the following disclaimer in the 1292372Sphk * documentation and/or other materials provided with the distribution. 1392372Sphk * 3. All advertising materials mentioning features or use of this software 1492372Sphk * must display the following acknowledgement: 1592372Sphk * This product includes software developed by the University of 1692372Sphk * California, Berkeley and its contributors. 1792372Sphk * 4. Neither the name of the University nor the names of its contributors 1892372Sphk * may be used to endorse or promote products derived from this software 1992372Sphk * without specific prior written permission. 2092372Sphk * 2192372Sphk * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2292372Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2392372Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2492372Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2592372Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2692372Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2792372Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2892372Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2992372Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3092372Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3192372Sphk * SUCH DAMAGE. 3292372Sphk * 3392372Sphk * @(#)ip_output.c 8.3 (Berkeley) 1/21/94 3492372Sphk * $Id: ip_output.c,v 1.36 1996/04/21 13:47:43 bde Exp $ 3592372Sphk */ 3692372Sphk 3792372Sphk#define _IP_VHL 3892372Sphk 3992372Sphk#include <sys/param.h> 4092372Sphk#include <sys/queue.h> 4192372Sphk#include <sys/systm.h> 4292372Sphk#include <sys/malloc.h> 4392372Sphk#include <sys/mbuf.h> 4492372Sphk#include <sys/errno.h> 4592372Sphk#include <sys/protosw.h> 4692372Sphk#include <sys/socket.h> 4792372Sphk#include <sys/socketvar.h> 4892372Sphk 4992372Sphk#include <net/if.h> 5092372Sphk#include <net/route.h> 5192372Sphk 5292372Sphk#include <netinet/in.h> 5392372Sphk#include <netinet/in_systm.h> 5492372Sphk#include <netinet/ip.h> 5592372Sphk#include <netinet/in_pcb.h> 5692372Sphk#include <netinet/in_var.h> 5792372Sphk#include <netinet/ip_var.h> 5892372Sphk 5997075Sphk#ifdef vax 6092372Sphk#include <machine/mtpr.h> 6192372Sphk#endif 6292372Sphk#include <machine/in_cksum.h> 6392372Sphk 6492372Sphku_short ip_id; 6592372Sphk 6692372Sphkstatic struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *)); 6792372Sphkstatic void ip_mloopback 6892372Sphk __P((struct ifnet *, struct mbuf *, struct sockaddr_in *)); 6992372Sphkstatic int ip_getmoptions 7092372Sphk __P((int, struct ip_moptions *, struct mbuf **)); 7192372Sphkstatic int ip_optcopy __P((struct ip *, struct ip *)); 7292372Sphkstatic int ip_pcbopts __P((struct mbuf **, struct mbuf *)); 7392372Sphkstatic int ip_setmoptions 7492372Sphk __P((int, struct ip_moptions **, struct mbuf *)); 7592372Sphk 7692372Sphk/* 7792372Sphk * IP output. The packet in mbuf chain m contains a skeletal IP 7892372Sphk * header (with len, off, ttl, proto, tos, src, dst). 7992372Sphk * The mbuf chain containing the packet will be freed. 8092372Sphk * The mbuf opt, if present, will not be freed. 8192372Sphk */ 8292372Sphkint 8392372Sphkip_output(m0, opt, ro, flags, imo) 8492372Sphk struct mbuf *m0; 8592372Sphk struct mbuf *opt; 8693250Sphk struct route *ro; 8792372Sphk int flags; 8892372Sphk struct ip_moptions *imo; 8992372Sphk{ 9092372Sphk struct ip *ip, *mhip; 9194287Sphk struct ifnet *ifp; 9292372Sphk struct mbuf *m = m0; 9392372Sphk int hlen = sizeof (struct ip); 9494285Sphk int len, off, error = 0; 9592372Sphk struct sockaddr_in *dst; 9694287Sphk struct in_ifaddr *ia; 9792372Sphk int isbroadcast; 9892372Sphk 9992372Sphk#ifdef DIAGNOSTIC 10092372Sphk if ((m->m_flags & M_PKTHDR) == 0) 10193358Sphk panic("ip_output no HDR"); 10292372Sphk if (!ro) 10392372Sphk panic("ip_output no route, proto = %d", 10492372Sphk mtod(m, struct ip *)->ip_p); 10592372Sphk#endif 10694287Sphk if (opt) { 10792372Sphk m = ip_insertoptions(m, opt, &len); 10892372Sphk hlen = len; 10992372Sphk } 11092372Sphk ip = mtod(m, struct ip *); 11192372Sphk /* 11292372Sphk * Fill in IP header. 113105551Sphk */ 114105551Sphk if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) { 115105551Sphk ip->ip_vhl = IP_MAKE_VHL(IPVERSION, hlen >> 2); 11694287Sphk ip->ip_off &= IP_DF; 117105551Sphk ip->ip_id = htons(ip_id++); 11894285Sphk ipstat.ips_localout++; 11992372Sphk } else { 12092372Sphk hlen = IP_VHL_HL(ip->ip_vhl) << 2; 12192372Sphk } 12292372Sphk 12393090Sphk dst = (struct sockaddr_in *)&ro->ro_dst; 12492372Sphk /* 12592372Sphk * If there is a cached route, 12692372Sphk * check that it is to the same destination 12792372Sphk * and is still up. If not, free it and try again. 12893090Sphk */ 12992372Sphk if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 || 13092372Sphk dst->sin_addr.s_addr != ip->ip_dst.s_addr)) { 13192372Sphk RTFREE(ro->ro_rt); 13292372Sphk ro->ro_rt = (struct rtentry *)0; 13392372Sphk } 13492372Sphk if (ro->ro_rt == 0) { 13593090Sphk dst->sin_family = AF_INET; 13693090Sphk dst->sin_len = sizeof(*dst); 13792372Sphk dst->sin_addr = ip->ip_dst; 13893090Sphk } 13993090Sphk /* 14092372Sphk * If routing to interface only, 14192372Sphk * short circuit routing lookup. 14293090Sphk */ 14393090Sphk#define ifatoia(ifa) ((struct in_ifaddr *)(ifa)) 14492372Sphk#define sintosa(sin) ((struct sockaddr *)(sin)) 14593090Sphk if (flags & IP_ROUTETOIF) { 14693090Sphk if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 && 14793090Sphk (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) { 14893090Sphk ipstat.ips_noroute++; 14993090Sphk error = ENETUNREACH; 15093090Sphk goto bad; 15193090Sphk } 15293090Sphk ifp = ia->ia_ifp; 15392372Sphk ip->ip_ttl = 1; 15492372Sphk isbroadcast = in_broadcast(dst->sin_addr, ifp); 15593090Sphk } else { 15692372Sphk /* 15792372Sphk * If this is the case, we probably don't want to allocate 15893090Sphk * a protocol-cloned route since we didn't get one from the 15993090Sphk * ULP. This lets TCP do its thing, while not burdening 16092372Sphk * forwarding or ICMP with the overhead of cloning a route. 16192372Sphk * Of course, we still want to do any cloning requested by 16292372Sphk * the link layer, as this is probably required in all cases 163104064Sphk * for correct operation (as it is for ARP). 16492372Sphk */ 16592372Sphk if (ro->ro_rt == 0) 16692372Sphk rtalloc_ign(ro, RTF_PRCLONING); 167105542Sphk if (ro->ro_rt == 0) { 16892372Sphk ipstat.ips_noroute++; 169104064Sphk error = EHOSTUNREACH; 17092372Sphk goto bad; 17192372Sphk } 17292372Sphk ia = ifatoia(ro->ro_rt->rt_ifa); 17392372Sphk ifp = ro->ro_rt->rt_ifp; 17492372Sphk ro->ro_rt->rt_use++; 17592372Sphk if (ro->ro_rt->rt_flags & RTF_GATEWAY) 176103009Sphk dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; 17792372Sphk if (ro->ro_rt->rt_flags & RTF_HOST) 17892372Sphk isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST); 17992372Sphk else 18092372Sphk isbroadcast = in_broadcast(dst->sin_addr, ifp); 18192372Sphk } 18293248Sphk if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) { 18393358Sphk struct in_multi *inm; 18492372Sphk 18592372Sphk m->m_flags |= M_MCAST; 18698066Sphk /* 18792372Sphk * IP destination address is multicast. Make sure "dst" 18892372Sphk * still points to the address in "ro". (It may have been 18993248Sphk * 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 661 default: 662 error = ENOPROTOOPT; 663 break; 664 } 665 if (m) 666 (void)m_free(m); 667 break; 668 669 case PRCO_GETOPT: 670 switch (optname) { 671 case IP_OPTIONS: 672 case IP_RETOPTS: 673 *mp = m = m_get(M_WAIT, MT_SOOPTS); 674 if (inp->inp_options) { 675 m->m_len = inp->inp_options->m_len; 676 (void)memcpy(mtod(m, void *), 677 mtod(inp->inp_options, void *), (unsigned)m->m_len); 678 } else 679 m->m_len = 0; 680 break; 681 682 case IP_TOS: 683 case IP_TTL: 684 case IP_RECVOPTS: 685 case IP_RECVRETOPTS: 686 case IP_RECVDSTADDR: 687 *mp = m = m_get(M_WAIT, MT_SOOPTS); 688 m->m_len = sizeof(int); 689 switch (optname) { 690 691 case IP_TOS: 692 optval = inp->inp_ip.ip_tos; 693 break; 694 695 case IP_TTL: 696 optval = inp->inp_ip.ip_ttl; 697 break; 698 699#define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0) 700 701 case IP_RECVOPTS: 702 optval = OPTBIT(INP_RECVOPTS); 703 break; 704 705 case IP_RECVRETOPTS: 706 optval = OPTBIT(INP_RECVRETOPTS); 707 break; 708 709 case IP_RECVDSTADDR: 710 optval = OPTBIT(INP_RECVDSTADDR); 711 break; 712 } 713 *mtod(m, int *) = optval; 714 break; 715 716 case IP_MULTICAST_IF: 717 case IP_MULTICAST_VIF: 718 case IP_MULTICAST_TTL: 719 case IP_MULTICAST_LOOP: 720 case IP_ADD_MEMBERSHIP: 721 case IP_DROP_MEMBERSHIP: 722 error = ip_getmoptions(optname, inp->inp_moptions, mp); 723 break; 724 725 case IP_PORTRANGE: 726 *mp = m = m_get(M_WAIT, MT_SOOPTS); 727 m->m_len = sizeof(int); 728 729 if (inp->inp_flags & INP_HIGHPORT) 730 optval = IP_PORTRANGE_HIGH; 731 else if (inp->inp_flags & INP_LOWPORT) 732 optval = IP_PORTRANGE_LOW; 733 else 734 optval = 0; 735 736 *mtod(m, int *) = optval; 737 break; 738 739 default: 740 error = ENOPROTOOPT; 741 break; 742 } 743 break; 744 } 745 return (error); 746} 747 748/* 749 * Set up IP options in pcb for insertion in output packets. 750 * Store in mbuf with pointer in pcbopt, adding pseudo-option 751 * with destination address if source routed. 752 */ 753static int 754#ifdef notyet 755ip_pcbopts(optname, pcbopt, m) 756 int optname; 757#else 758ip_pcbopts(pcbopt, m) 759#endif 760 struct mbuf **pcbopt; 761 register struct mbuf *m; 762{ 763 register cnt, optlen; 764 register u_char *cp; 765 u_char opt; 766 767 /* turn off any old options */ 768 if (*pcbopt) 769 (void)m_free(*pcbopt); 770 *pcbopt = 0; 771 if (m == (struct mbuf *)0 || m->m_len == 0) { 772 /* 773 * Only turning off any previous options. 774 */ 775 if (m) 776 (void)m_free(m); 777 return (0); 778 } 779 780#ifndef vax 781 if (m->m_len % sizeof(long)) 782 goto bad; 783#endif 784 /* 785 * IP first-hop destination address will be stored before 786 * actual options; move other options back 787 * and clear it when none present. 788 */ 789 if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN]) 790 goto bad; 791 cnt = m->m_len; 792 m->m_len += sizeof(struct in_addr); 793 cp = mtod(m, u_char *) + sizeof(struct in_addr); 794 ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt); 795 bzero(mtod(m, caddr_t), sizeof(struct in_addr)); 796 797 for (; cnt > 0; cnt -= optlen, cp += optlen) { 798 opt = cp[IPOPT_OPTVAL]; 799 if (opt == IPOPT_EOL) 800 break; 801 if (opt == IPOPT_NOP) 802 optlen = 1; 803 else { 804 optlen = cp[IPOPT_OLEN]; 805 if (optlen <= IPOPT_OLEN || optlen > cnt) 806 goto bad; 807 } 808 switch (opt) { 809 810 default: 811 break; 812 813 case IPOPT_LSRR: 814 case IPOPT_SSRR: 815 /* 816 * user process specifies route as: 817 * ->A->B->C->D 818 * D must be our final destination (but we can't 819 * check that since we may not have connected yet). 820 * A is first hop destination, which doesn't appear in 821 * actual IP option, but is stored before the options. 822 */ 823 if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr)) 824 goto bad; 825 m->m_len -= sizeof(struct in_addr); 826 cnt -= sizeof(struct in_addr); 827 optlen -= sizeof(struct in_addr); 828 cp[IPOPT_OLEN] = optlen; 829 /* 830 * Move first hop before start of options. 831 */ 832 bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t), 833 sizeof(struct in_addr)); 834 /* 835 * Then copy rest of options back 836 * to close up the deleted entry. 837 */ 838 ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] + 839 sizeof(struct in_addr)), 840 (caddr_t)&cp[IPOPT_OFFSET+1], 841 (unsigned)cnt + sizeof(struct in_addr)); 842 break; 843 } 844 } 845 if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr)) 846 goto bad; 847 *pcbopt = m; 848 return (0); 849 850bad: 851 (void)m_free(m); 852 return (EINVAL); 853} 854 855/* 856 * Set the IP multicast options in response to user setsockopt(). 857 */ 858static int 859ip_setmoptions(optname, imop, m) 860 int optname; 861 struct ip_moptions **imop; 862 struct mbuf *m; 863{ 864 register int error = 0; 865 u_char loop; 866 register int i; 867 struct in_addr addr; 868 register struct ip_mreq *mreq; 869 register struct ifnet *ifp; 870 register struct ip_moptions *imo = *imop; 871 struct route ro; 872 register struct sockaddr_in *dst; 873 int s; 874 875 if (imo == NULL) { 876 /* 877 * No multicast option buffer attached to the pcb; 878 * allocate one and initialize to default values. 879 */ 880 imo = (struct ip_moptions*)malloc(sizeof(*imo), M_IPMOPTS, 881 M_WAITOK); 882 883 if (imo == NULL) 884 return (ENOBUFS); 885 *imop = imo; 886 imo->imo_multicast_ifp = NULL; 887 imo->imo_multicast_vif = -1; 888 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL; 889 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP; 890 imo->imo_num_memberships = 0; 891 } 892 893 switch (optname) { 894 /* store an index number for the vif you wanna use in the send */ 895 case IP_MULTICAST_VIF: 896 if (!legal_vif_num) { 897 error = EOPNOTSUPP; 898 break; 899 } 900 if (m == NULL || m->m_len != sizeof(int)) { 901 error = EINVAL; 902 break; 903 } 904 i = *(mtod(m, int *)); 905 if (!legal_vif_num(i) && (i != -1)) { 906 error = EINVAL; 907 break; 908 } 909 imo->imo_multicast_vif = i; 910 break; 911 912 case IP_MULTICAST_IF: 913 /* 914 * Select the interface for outgoing multicast packets. 915 */ 916 if (m == NULL || m->m_len != sizeof(struct in_addr)) { 917 error = EINVAL; 918 break; 919 } 920 addr = *(mtod(m, struct in_addr *)); 921 /* 922 * INADDR_ANY is used to remove a previous selection. 923 * When no interface is selected, a default one is 924 * chosen every time a multicast packet is sent. 925 */ 926 if (addr.s_addr == INADDR_ANY) { 927 imo->imo_multicast_ifp = NULL; 928 break; 929 } 930 /* 931 * The selected interface is identified by its local 932 * IP address. Find the interface and confirm that 933 * it supports multicasting. 934 */ 935 s = splimp(); 936 INADDR_TO_IFP(addr, ifp); 937 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 938 splx(s); 939 error = EADDRNOTAVAIL; 940 break; 941 } 942 imo->imo_multicast_ifp = ifp; 943 splx(s); 944 break; 945 946 case IP_MULTICAST_TTL: 947 /* 948 * Set the IP time-to-live for outgoing multicast packets. 949 */ 950 if (m == NULL || m->m_len != 1) { 951 error = EINVAL; 952 break; 953 } 954 imo->imo_multicast_ttl = *(mtod(m, u_char *)); 955 break; 956 957 case IP_MULTICAST_LOOP: 958 /* 959 * Set the loopback flag for outgoing multicast packets. 960 * Must be zero or one. 961 */ 962 if (m == NULL || m->m_len != 1 || 963 (loop = *(mtod(m, u_char *))) > 1) { 964 error = EINVAL; 965 break; 966 } 967 imo->imo_multicast_loop = loop; 968 break; 969 970 case IP_ADD_MEMBERSHIP: 971 /* 972 * Add a multicast group membership. 973 * Group must be a valid IP multicast address. 974 */ 975 if (m == NULL || m->m_len != sizeof(struct ip_mreq)) { 976 error = EINVAL; 977 break; 978 } 979 mreq = mtod(m, struct ip_mreq *); 980 if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) { 981 error = EINVAL; 982 break; 983 } 984 s = splimp(); 985 /* 986 * If no interface address was provided, use the interface of 987 * the route to the given multicast address. 988 */ 989 if (mreq->imr_interface.s_addr == INADDR_ANY) { 990 bzero((caddr_t)&ro, sizeof(ro)); 991 dst = (struct sockaddr_in *)&ro.ro_dst; 992 dst->sin_len = sizeof(*dst); 993 dst->sin_family = AF_INET; 994 dst->sin_addr = mreq->imr_multiaddr; 995 rtalloc(&ro); 996 if (ro.ro_rt == NULL) { 997 error = EADDRNOTAVAIL; 998 splx(s); 999 break; 1000 } 1001 ifp = ro.ro_rt->rt_ifp; 1002 rtfree(ro.ro_rt); 1003 } 1004 else { 1005 INADDR_TO_IFP(mreq->imr_interface, ifp); 1006 } 1007 1008 /* 1009 * See if we found an interface, and confirm that it 1010 * supports multicast. 1011 */ 1012 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) { 1013 error = EADDRNOTAVAIL; 1014 splx(s); 1015 break; 1016 } 1017 /* 1018 * See if the membership already exists or if all the 1019 * membership slots are full. 1020 */ 1021 for (i = 0; i < imo->imo_num_memberships; ++i) { 1022 if (imo->imo_membership[i]->inm_ifp == ifp && 1023 imo->imo_membership[i]->inm_addr.s_addr 1024 == mreq->imr_multiaddr.s_addr) 1025 break; 1026 } 1027 if (i < imo->imo_num_memberships) { 1028 error = EADDRINUSE; 1029 splx(s); 1030 break; 1031 } 1032 if (i == IP_MAX_MEMBERSHIPS) { 1033 error = ETOOMANYREFS; 1034 splx(s); 1035 break; 1036 } 1037 /* 1038 * Everything looks good; add a new record to the multicast 1039 * address list for the given interface. 1040 */ 1041 if ((imo->imo_membership[i] = 1042 in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) { 1043 error = ENOBUFS; 1044 splx(s); 1045 break; 1046 } 1047 ++imo->imo_num_memberships; 1048 splx(s); 1049 break; 1050 1051 case IP_DROP_MEMBERSHIP: 1052 /* 1053 * Drop a multicast group membership. 1054 * Group must be a valid IP multicast address. 1055 */ 1056 if (m == NULL || m->m_len != sizeof(struct ip_mreq)) { 1057 error = EINVAL; 1058 break; 1059 } 1060 mreq = mtod(m, struct ip_mreq *); 1061 if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) { 1062 error = EINVAL; 1063 break; 1064 } 1065 1066 s = splimp(); 1067 /* 1068 * If an interface address was specified, get a pointer 1069 * to its ifnet structure. 1070 */ 1071 if (mreq->imr_interface.s_addr == INADDR_ANY) 1072 ifp = NULL; 1073 else { 1074 INADDR_TO_IFP(mreq->imr_interface, ifp); 1075 if (ifp == NULL) { 1076 error = EADDRNOTAVAIL; 1077 splx(s); 1078 break; 1079 } 1080 } 1081 /* 1082 * Find the membership in the membership array. 1083 */ 1084 for (i = 0; i < imo->imo_num_memberships; ++i) { 1085 if ((ifp == NULL || 1086 imo->imo_membership[i]->inm_ifp == ifp) && 1087 imo->imo_membership[i]->inm_addr.s_addr == 1088 mreq->imr_multiaddr.s_addr) 1089 break; 1090 } 1091 if (i == imo->imo_num_memberships) { 1092 error = EADDRNOTAVAIL; 1093 splx(s); 1094 break; 1095 } 1096 /* 1097 * Give up the multicast address record to which the 1098 * membership points. 1099 */ 1100 in_delmulti(imo->imo_membership[i]); 1101 /* 1102 * Remove the gap in the membership array. 1103 */ 1104 for (++i; i < imo->imo_num_memberships; ++i) 1105 imo->imo_membership[i-1] = imo->imo_membership[i]; 1106 --imo->imo_num_memberships; 1107 splx(s); 1108 break; 1109 1110 default: 1111 error = EOPNOTSUPP; 1112 break; 1113 } 1114 1115 /* 1116 * If all options have default values, no need to keep the mbuf. 1117 */ 1118 if (imo->imo_multicast_ifp == NULL && 1119 imo->imo_multicast_vif == -1 && 1120 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL && 1121 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP && 1122 imo->imo_num_memberships == 0) { 1123 free(*imop, M_IPMOPTS); 1124 *imop = NULL; 1125 } 1126 1127 return (error); 1128} 1129 1130/* 1131 * Return the IP multicast options in response to user getsockopt(). 1132 */ 1133static int 1134ip_getmoptions(optname, imo, mp) 1135 int optname; 1136 register struct ip_moptions *imo; 1137 register struct mbuf **mp; 1138{ 1139 u_char *ttl; 1140 u_char *loop; 1141 struct in_addr *addr; 1142 struct in_ifaddr *ia; 1143 1144 *mp = m_get(M_WAIT, MT_SOOPTS); 1145 1146 switch (optname) { 1147 1148 case IP_MULTICAST_VIF: 1149 if (imo != NULL) 1150 *(mtod(*mp, int *)) = imo->imo_multicast_vif; 1151 else 1152 *(mtod(*mp, int *)) = -1; 1153 (*mp)->m_len = sizeof(int); 1154 return(0); 1155 1156 case IP_MULTICAST_IF: 1157 addr = mtod(*mp, struct in_addr *); 1158 (*mp)->m_len = sizeof(struct in_addr); 1159 if (imo == NULL || imo->imo_multicast_ifp == NULL) 1160 addr->s_addr = INADDR_ANY; 1161 else { 1162 IFP_TO_IA(imo->imo_multicast_ifp, ia); 1163 addr->s_addr = (ia == NULL) ? INADDR_ANY 1164 : IA_SIN(ia)->sin_addr.s_addr; 1165 } 1166 return (0); 1167 1168 case IP_MULTICAST_TTL: 1169 ttl = mtod(*mp, u_char *); 1170 (*mp)->m_len = 1; 1171 *ttl = (imo == NULL) ? IP_DEFAULT_MULTICAST_TTL 1172 : imo->imo_multicast_ttl; 1173 return (0); 1174 1175 case IP_MULTICAST_LOOP: 1176 loop = mtod(*mp, u_char *); 1177 (*mp)->m_len = 1; 1178 *loop = (imo == NULL) ? IP_DEFAULT_MULTICAST_LOOP 1179 : imo->imo_multicast_loop; 1180 return (0); 1181 1182 default: 1183 return (EOPNOTSUPP); 1184 } 1185} 1186 1187/* 1188 * Discard the IP multicast options. 1189 */ 1190void 1191ip_freemoptions(imo) 1192 register struct ip_moptions *imo; 1193{ 1194 register int i; 1195 1196 if (imo != NULL) { 1197 for (i = 0; i < imo->imo_num_memberships; ++i) 1198 in_delmulti(imo->imo_membership[i]); 1199 free(imo, M_IPMOPTS); 1200 } 1201} 1202 1203/* 1204 * Routine called from ip_output() to loop back a copy of an IP multicast 1205 * packet to the input queue of a specified interface. Note that this 1206 * calls the output routine of the loopback "driver", but with an interface 1207 * pointer that might NOT be a loopback interface -- evil, but easier than 1208 * replicating that code here. 1209 */ 1210static void 1211ip_mloopback(ifp, m, dst) 1212 struct ifnet *ifp; 1213 register struct mbuf *m; 1214 register struct sockaddr_in *dst; 1215{ 1216 register struct ip *ip; 1217 struct mbuf *copym; 1218 1219 copym = m_copy(m, 0, M_COPYALL); 1220 if (copym != NULL) { 1221 /* 1222 * We don't bother to fragment if the IP length is greater 1223 * than the interface's MTU. Can this possibly matter? 1224 */ 1225 ip = mtod(copym, struct ip *); 1226 ip->ip_len = htons((u_short)ip->ip_len); 1227 ip->ip_off = htons((u_short)ip->ip_off); 1228 ip->ip_sum = 0; 1229 if (ip->ip_vhl == IP_VHL_BORING) { 1230 ip->ip_sum = in_cksum_hdr(ip); 1231 } else { 1232 ip->ip_sum = in_cksum(copym, 1233 IP_VHL_HL(ip->ip_vhl) << 2); 1234 } 1235 /* 1236 * NB: 1237 * We can't simply call ip_input() directly because 1238 * the ip_mforward() depends on the `input interface' 1239 * being set to something unreasonable so that we don't 1240 * attempt to forward the looped-back copy. 1241 * It's also not clear whether there are any lingering 1242 * reentrancy problems in other areas which might be 1243 * exposed by this code. For the moment, we'll err 1244 * on the side of safety by continuing to abuse 1245 * loinput(). 1246 */ 1247#ifdef notdef 1248 copym->m_pkthdr.rcvif = &loif[0]; 1249 ip_input(copym) 1250#else 1251 (void) looutput(ifp, copym, (struct sockaddr *)dst, NULL); 1252#endif 1253 } 1254} 1255