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