]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/ip_output.c
39daf80997b3acb4479fcead48df68f2086a1c96
[apple/xnu.git] / bsd / netinet / ip_output.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * Copyright (c) 1982, 1986, 1988, 1990, 1993
27 * The Regents of the University of California. All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 *
57 * @(#)ip_output.c 8.3 (Berkeley) 1/21/94
58 * $FreeBSD: src/sys/netinet/ip_output.c,v 1.99.2.16 2001/07/19 06:37:26 kris Exp $
59 */
60
61 #define _IP_VHL
62
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kernel.h>
66 #include <sys/malloc.h>
67 #include <sys/mbuf.h>
68 #include <sys/protosw.h>
69 #include <sys/socket.h>
70 #include <sys/socketvar.h>
71
72 #include <net/if.h>
73 #include <net/route.h>
74
75 #include <netinet/in.h>
76 #include <netinet/in_systm.h>
77 #include <netinet/ip.h>
78 #include <netinet/in_pcb.h>
79 #include <netinet/in_var.h>
80 #include <netinet/ip_var.h>
81
82 #include "faith.h"
83
84 #include <net/dlil.h>
85 #include <sys/kdebug.h>
86
87 #define DBG_LAYER_BEG NETDBG_CODE(DBG_NETIP, 1)
88 #define DBG_LAYER_END NETDBG_CODE(DBG_NETIP, 3)
89 #define DBG_FNC_IP_OUTPUT NETDBG_CODE(DBG_NETIP, (1 << 8) | 1)
90 #define DBG_FNC_IPSEC4_OUTPUT NETDBG_CODE(DBG_NETIP, (2 << 8) | 1)
91
92
93 #if vax
94 #include <machine/mtpr.h>
95 #endif
96
97 #if __FreeBSD__
98 #include <machine/in_cksum.h>
99
100 static MALLOC_DEFINE(M_IPMOPTS, "ip_moptions", "internet multicast options");
101 #endif
102
103 #if IPSEC
104 #include <netinet6/ipsec.h>
105 #include <netkey/key.h>
106 #if IPSEC_DEBUG
107 #include <netkey/key_debug.h>
108 #else
109 #define KEYDEBUG(lev,arg)
110 #endif
111 #endif /*IPSEC*/
112
113 #include <netinet/ip_fw.h>
114
115 #if DUMMYNET
116 #include <netinet/ip_dummynet.h>
117 #endif
118
119 #if IPFIREWALL_FORWARD_DEBUG
120 #define print_ip(a) printf("%ld.%ld.%ld.%ld",(ntohl(a.s_addr)>>24)&0xFF,\
121 (ntohl(a.s_addr)>>16)&0xFF,\
122 (ntohl(a.s_addr)>>8)&0xFF,\
123 (ntohl(a.s_addr))&0xFF);
124 #endif
125
126 u_short ip_id;
127
128 static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *));
129 static struct ifnet *ip_multicast_if __P((struct in_addr *, int *));
130 static void ip_mloopback
131 __P((struct ifnet *, struct mbuf *, struct sockaddr_in *, int));
132 static int ip_getmoptions
133 __P((struct sockopt *, struct ip_moptions *));
134 static int ip_pcbopts __P((int, struct mbuf **, struct mbuf *));
135 static int ip_setmoptions
136 __P((struct sockopt *, struct ip_moptions **));
137
138 int ip_createmoptions(struct ip_moptions **imop);
139 int ip_addmembership(struct ip_moptions *imo, struct ip_mreq *mreq);
140 int ip_dropmembership(struct ip_moptions *imo, struct ip_mreq *mreq);
141 int ip_optcopy __P((struct ip *, struct ip *));
142 extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **));
143 #ifdef __APPLE__
144 extern struct mbuf* m_dup(register struct mbuf *m, int how);
145 #endif
146
147 static u_long lo_dl_tag = 0;
148
149 void in_delayed_cksum(struct mbuf *m);
150 extern int apple_hwcksum_tx;
151 extern u_long route_generation;
152
153 extern struct protosw inetsw[];
154
155 extern struct ip_linklocal_stat ip_linklocal_stat;
156
157 /* temporary: for testing */
158 #if IPSEC
159 extern int ipsec_bypass;
160 #endif
161
162 /*
163 * IP output. The packet in mbuf chain m contains a skeletal IP
164 * header (with len, off, ttl, proto, tos, src, dst).
165 * The mbuf chain containing the packet will be freed.
166 * The mbuf opt, if present, will not be freed.
167 */
168 int
169 ip_output(m0, opt, ro, flags, imo)
170 struct mbuf *m0;
171 struct mbuf *opt;
172 struct route *ro;
173 int flags;
174 struct ip_moptions *imo;
175 {
176 struct ip *ip, *mhip;
177 struct ifnet *ifp = NULL;
178 struct mbuf *m = m0;
179 int hlen = sizeof (struct ip);
180 int len, off, error = 0;
181 struct sockaddr_in *dst = NULL;
182 struct in_ifaddr *ia = NULL;
183 int isbroadcast, sw_csum;
184 #if IPSEC
185 struct route iproute;
186 struct socket *so = NULL;
187 struct secpolicy *sp = NULL;
188 #endif
189 u_int16_t divert_cookie; /* firewall cookie */
190 #if IPFIREWALL_FORWARD
191 int fwd_rewrite_src = 0;
192 #endif
193 struct ip_fw_chain *rule = NULL;
194
195 #if IPDIVERT
196 /* Get and reset firewall cookie */
197 divert_cookie = ip_divert_cookie;
198 ip_divert_cookie = 0;
199 #else
200 divert_cookie = 0;
201 #endif
202
203 KERNEL_DEBUG(DBG_FNC_IP_OUTPUT | DBG_FUNC_START, 0,0,0,0,0);
204
205 #if IPFIREWALL && DUMMYNET
206 /*
207 * dummynet packet are prepended a vestigial mbuf with
208 * m_type = MT_DUMMYNET and m_data pointing to the matching
209 * rule.
210 */
211 if (m->m_type == MT_DUMMYNET) {
212 /*
213 * the packet was already tagged, so part of the
214 * processing was already done, and we need to go down.
215 * Get parameters from the header.
216 */
217 rule = (struct ip_fw_chain *)(m->m_data) ;
218 opt = NULL ;
219 ro = & ( ((struct dn_pkt *)m)->ro ) ;
220 imo = NULL ;
221 dst = ((struct dn_pkt *)m)->dn_dst ;
222 ifp = ((struct dn_pkt *)m)->ifp ;
223 flags = ((struct dn_pkt *)m)->flags;
224 m0 = m = m->m_next ;
225 #if IPSEC
226 if (ipsec_bypass == 0 && (flags & IP_NOIPSEC) == 0) {
227 so = ipsec_getsocket(m);
228 (void)ipsec_setsocket(m, NULL);
229 }
230 #endif
231 ip = mtod(m, struct ip *);
232 hlen = IP_VHL_HL(ip->ip_vhl) << 2 ;
233 if (ro->ro_rt != NULL)
234 ia = (struct in_ifaddr *)ro->ro_rt->rt_ifa;
235 goto sendit;
236 } else
237 rule = NULL ;
238 #endif
239 #if IPSEC
240 if (ipsec_bypass == 0 && (flags & IP_NOIPSEC) == 0) {
241 so = ipsec_getsocket(m);
242 (void)ipsec_setsocket(m, NULL);
243 }
244 #endif
245
246 #if DIAGNOSTIC
247 if ((m->m_flags & M_PKTHDR) == 0)
248 panic("ip_output no HDR");
249 if (!ro)
250 panic("ip_output no route, proto = %d",
251 mtod(m, struct ip *)->ip_p);
252 #endif
253 if (opt) {
254 m = ip_insertoptions(m, opt, &len);
255 hlen = len;
256 }
257 ip = mtod(m, struct ip *);
258 /*
259 * Fill in IP header.
260 */
261 if ((flags & (IP_FORWARDING|IP_RAWOUTPUT)) == 0) {
262 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, hlen >> 2);
263 ip->ip_off &= IP_DF;
264 #if RANDOM_IP_ID
265 ip->ip_id = ip_randomid();
266 #else
267 ip->ip_id = htons(ip_id++);
268 #endif
269 ipstat.ips_localout++;
270 } else {
271 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
272 }
273
274 KERNEL_DEBUG(DBG_LAYER_BEG, ip->ip_dst.s_addr,
275 ip->ip_src.s_addr, ip->ip_p, ip->ip_off, ip->ip_len);
276
277 dst = (struct sockaddr_in *)&ro->ro_dst;
278
279 /*
280 * If there is a cached route,
281 * check that it is to the same destination
282 * and is still up. If not, free it and try again.
283 * The address family should also be checked in case of sharing the
284 * cache with IPv6.
285 */
286
287 if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
288 dst->sin_family != AF_INET ||
289 dst->sin_addr.s_addr != ip->ip_dst.s_addr ||
290 ro->ro_rt->generation_id != route_generation) ) {
291 rtfree(ro->ro_rt);
292 ro->ro_rt = (struct rtentry *)0;
293 }
294 if (ro->ro_rt == 0) {
295 bzero(dst, sizeof(*dst));
296 dst->sin_family = AF_INET;
297 dst->sin_len = sizeof(*dst);
298 dst->sin_addr = ip->ip_dst;
299 }
300 /*
301 * If routing to interface only,
302 * short circuit routing lookup.
303 */
304 #define ifatoia(ifa) ((struct in_ifaddr *)(ifa))
305 #define sintosa(sin) ((struct sockaddr *)(sin))
306 if (flags & IP_ROUTETOIF) {
307 if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == 0 &&
308 (ia = ifatoia(ifa_ifwithnet(sintosa(dst)))) == 0) {
309 ipstat.ips_noroute++;
310 error = ENETUNREACH;
311 goto bad;
312 }
313 ifp = ia->ia_ifp;
314 ip->ip_ttl = 1;
315 isbroadcast = in_broadcast(dst->sin_addr, ifp);
316 } else {
317 /*
318 * If this is the case, we probably don't want to allocate
319 * a protocol-cloned route since we didn't get one from the
320 * ULP. This lets TCP do its thing, while not burdening
321 * forwarding or ICMP with the overhead of cloning a route.
322 * Of course, we still want to do any cloning requested by
323 * the link layer, as this is probably required in all cases
324 * for correct operation (as it is for ARP).
325 */
326 if (ro->ro_rt == 0)
327 rtalloc_ign(ro, RTF_PRCLONING);
328 if (ro->ro_rt == 0) {
329 ipstat.ips_noroute++;
330 error = EHOSTUNREACH;
331 goto bad;
332 }
333 ia = ifatoia(ro->ro_rt->rt_ifa);
334 ifp = ro->ro_rt->rt_ifp;
335 ro->ro_rt->rt_use++;
336 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
337 dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway;
338 if (ro->ro_rt->rt_flags & RTF_HOST)
339 isbroadcast = (ro->ro_rt->rt_flags & RTF_BROADCAST);
340 else
341 isbroadcast = in_broadcast(dst->sin_addr, ifp);
342 }
343 if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
344 struct in_multi *inm;
345
346 m->m_flags |= M_MCAST;
347 /*
348 * IP destination address is multicast. Make sure "dst"
349 * still points to the address in "ro". (It may have been
350 * changed to point to a gateway address, above.)
351 */
352 dst = (struct sockaddr_in *)&ro->ro_dst;
353 /*
354 * See if the caller provided any multicast options
355 */
356 if (imo != NULL) {
357 if ((flags & IP_RAWOUTPUT) == 0) ip->ip_ttl = imo->imo_multicast_ttl;
358 if (imo->imo_multicast_ifp != NULL) {
359 ifp = imo->imo_multicast_ifp;
360 }
361 if (imo->imo_multicast_vif != -1 &&
362 ((flags & IP_RAWOUTPUT) == 0 || ip->ip_src.s_addr == INADDR_ANY))
363 ip->ip_src.s_addr =
364 ip_mcast_src(imo->imo_multicast_vif);
365 } else
366 if ((flags & IP_RAWOUTPUT) == 0) ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL;
367 /*
368 * Confirm that the outgoing interface supports multicast.
369 */
370 if ((imo == NULL) || (imo->imo_multicast_vif == -1)) {
371 if ((ifp->if_flags & IFF_MULTICAST) == 0) {
372 ipstat.ips_noroute++;
373 error = ENETUNREACH;
374 goto bad;
375 }
376 }
377 /*
378 * If source address not specified yet, use address
379 * of outgoing interface.
380 */
381 if (ip->ip_src.s_addr == INADDR_ANY) {
382 register struct in_ifaddr *ia1;
383
384 TAILQ_FOREACH(ia1, &in_ifaddrhead, ia_link)
385 if (ia1->ia_ifp == ifp) {
386 ip->ip_src = IA_SIN(ia1)->sin_addr;
387
388 break;
389 }
390 if (ip->ip_src.s_addr == INADDR_ANY) {
391 error = ENETUNREACH;
392 goto bad;
393 }
394 }
395
396 IN_LOOKUP_MULTI(ip->ip_dst, ifp, inm);
397 if (inm != NULL &&
398 (imo == NULL || imo->imo_multicast_loop)) {
399 /*
400 * If we belong to the destination multicast group
401 * on the outgoing interface, and the caller did not
402 * forbid loopback, loop back a copy.
403 */
404 ip_mloopback(ifp, m, dst, hlen);
405 }
406 else {
407 /*
408 * If we are acting as a multicast router, perform
409 * multicast forwarding as if the packet had just
410 * arrived on the interface to which we are about
411 * to send. The multicast forwarding function
412 * recursively calls this function, using the
413 * IP_FORWARDING flag to prevent infinite recursion.
414 *
415 * Multicasts that are looped back by ip_mloopback(),
416 * above, will be forwarded by the ip_input() routine,
417 * if necessary.
418 */
419 if (ip_mrouter && (flags & IP_FORWARDING) == 0) {
420 /*
421 * Check if rsvp daemon is running. If not, don't
422 * set ip_moptions. This ensures that the packet
423 * is multicast and not just sent down one link
424 * as prescribed by rsvpd.
425 */
426 if (!rsvp_on)
427 imo = NULL;
428 if (ip_mforward(ip, ifp, m, imo) != 0) {
429 m_freem(m);
430 goto done;
431 }
432 }
433 }
434
435 /*
436 * Multicasts with a time-to-live of zero may be looped-
437 * back, above, but must not be transmitted on a network.
438 * Also, multicasts addressed to the loopback interface
439 * are not sent -- the above call to ip_mloopback() will
440 * loop back a copy if this host actually belongs to the
441 * destination group on the loopback interface.
442 */
443 if (ip->ip_ttl == 0 || ifp->if_flags & IFF_LOOPBACK) {
444 m_freem(m);
445 goto done;
446 }
447
448 goto sendit;
449 }
450 #ifndef notdef
451 /*
452 * If source address not specified yet, use address
453 * of outgoing interface.
454 */
455 if (ip->ip_src.s_addr == INADDR_ANY) {
456 ip->ip_src = IA_SIN(ia)->sin_addr;
457 #if IPFIREWALL_FORWARD
458 /* Keep note that we did this - if the firewall changes
459 * the next-hop, our interface may change, changing the
460 * default source IP. It's a shame so much effort happens
461 * twice. Oh well.
462 */
463 fwd_rewrite_src++;
464 #endif /* IPFIREWALL_FORWARD */
465 }
466 #endif /* notdef */
467 /*
468 * Verify that we have any chance at all of being able to queue
469 * the packet or packet fragments
470 */
471 if ((ifp->if_snd.ifq_len + ip->ip_len / ifp->if_mtu + 1) >=
472 ifp->if_snd.ifq_maxlen) {
473 error = ENOBUFS;
474 goto bad;
475 }
476
477 /*
478 * Look for broadcast address and
479 * and verify user is allowed to send
480 * such a packet.
481 */
482 if (isbroadcast) {
483 if ((ifp->if_flags & IFF_BROADCAST) == 0) {
484 error = EADDRNOTAVAIL;
485 goto bad;
486 }
487 if ((flags & IP_ALLOWBROADCAST) == 0) {
488 error = EACCES;
489 goto bad;
490 }
491 /* don't allow broadcast messages to be fragmented */
492 if ((u_short)ip->ip_len > ifp->if_mtu) {
493 error = EMSGSIZE;
494 goto bad;
495 }
496 m->m_flags |= M_BCAST;
497 } else {
498 m->m_flags &= ~M_BCAST;
499 }
500
501 sendit:
502 /*
503 * Force IP TTL to 255 following draft-ietf-zeroconf-ipv4-linklocal.txt
504 */
505 if (IN_LINKLOCAL(ntohl(ip->ip_src.s_addr)) || IN_LINKLOCAL(ntohl(ip->ip_dst.s_addr))) {
506 ip_linklocal_stat.iplls_out_total++;
507 if (ip->ip_ttl != MAXTTL) {
508 ip_linklocal_stat.iplls_out_badttl++;
509 ip->ip_ttl = MAXTTL;
510 }
511 }
512
513 #if IPSEC
514 /* temporary for testing only: bypass ipsec alltogether */
515
516 if (ipsec_bypass != 0 || (flags & IP_NOIPSEC) != 0)
517 goto skip_ipsec;
518
519 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_START, 0,0,0,0,0);
520
521 /* get SP for this packet */
522 if (so == NULL)
523 sp = ipsec4_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND, flags, &error);
524 else
525 sp = ipsec4_getpolicybysock(m, IPSEC_DIR_OUTBOUND, so, &error);
526
527 if (sp == NULL) {
528 ipsecstat.out_inval++;
529 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_END, 0,0,0,0,0);
530 goto bad;
531 }
532
533 error = 0;
534
535 /* check policy */
536 switch (sp->policy) {
537 case IPSEC_POLICY_DISCARD:
538 /*
539 * This packet is just discarded.
540 */
541 ipsecstat.out_polvio++;
542 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_END, 1,0,0,0,0);
543 goto bad;
544
545 case IPSEC_POLICY_BYPASS:
546 case IPSEC_POLICY_NONE:
547 /* no need to do IPsec. */
548 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_END, 2,0,0,0,0);
549 goto skip_ipsec;
550
551 case IPSEC_POLICY_IPSEC:
552 if (sp->req == NULL) {
553 /* acquire a policy */
554 error = key_spdacquire(sp);
555 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_END, 3,0,0,0,0);
556 goto bad;
557 }
558 break;
559
560 case IPSEC_POLICY_ENTRUST:
561 default:
562 printf("ip_output: Invalid policy found. %d\n", sp->policy);
563 }
564 {
565 struct ipsec_output_state state;
566 bzero(&state, sizeof(state));
567 state.m = m;
568 if (flags & IP_ROUTETOIF) {
569 state.ro = &iproute;
570 bzero(&iproute, sizeof(iproute));
571 } else
572 state.ro = ro;
573 state.dst = (struct sockaddr *)dst;
574
575 ip->ip_sum = 0;
576
577 /*
578 * XXX
579 * delayed checksums are not currently compatible with IPsec
580 */
581 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
582 in_delayed_cksum(m);
583 m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
584 }
585
586 HTONS(ip->ip_len);
587 HTONS(ip->ip_off);
588
589 error = ipsec4_output(&state, sp, flags);
590
591 m0 = m = state.m;
592
593 if (flags & IP_ROUTETOIF) {
594 /*
595 * if we have tunnel mode SA, we may need to ignore
596 * IP_ROUTETOIF.
597 */
598 if (state.ro != &iproute || state.ro->ro_rt != NULL) {
599 flags &= ~IP_ROUTETOIF;
600 ro = state.ro;
601 }
602 } else
603 ro = state.ro;
604
605 dst = (struct sockaddr_in *)state.dst;
606 if (error) {
607 /* mbuf is already reclaimed in ipsec4_output. */
608 m0 = NULL;
609 switch (error) {
610 case EHOSTUNREACH:
611 case ENETUNREACH:
612 case EMSGSIZE:
613 case ENOBUFS:
614 case ENOMEM:
615 break;
616 default:
617 printf("ip4_output (ipsec): error code %d\n", error);
618 /*fall through*/
619 case ENOENT:
620 /* don't show these error codes to the user */
621 error = 0;
622 break;
623 }
624 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_END, 4,0,0,0,0);
625 goto bad;
626 }
627 }
628
629 /* be sure to update variables that are affected by ipsec4_output() */
630 ip = mtod(m, struct ip *);
631
632 #ifdef _IP_VHL
633 hlen = IP_VHL_HL(ip->ip_vhl) << 2;
634 #else
635 hlen = ip->ip_hl << 2;
636 #endif
637 /* Check that there wasn't a route change and src is still valid */
638
639 if (ro->ro_rt->generation_id != route_generation) {
640 if (ifa_foraddr(ip->ip_src.s_addr) == NULL && ((flags & (IP_ROUTETOIF | IP_FORWARDING)) == 0)) {
641 error = EADDRNOTAVAIL;
642 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_END, 5,0,0,0,0);
643 goto bad;
644 }
645 rtfree(ro->ro_rt);
646 ro->ro_rt = NULL;
647 }
648
649 if (ro->ro_rt == NULL) {
650 if ((flags & IP_ROUTETOIF) == 0) {
651 printf("ip_output: "
652 "can't update route after IPsec processing\n");
653 error = EHOSTUNREACH; /*XXX*/
654 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_END, 6,0,0,0,0);
655 goto bad;
656 }
657 } else {
658 ia = ifatoia(ro->ro_rt->rt_ifa);
659 ifp = ro->ro_rt->rt_ifp;
660 }
661
662 /* make it flipped, again. */
663 NTOHS(ip->ip_len);
664 NTOHS(ip->ip_off);
665 KERNEL_DEBUG(DBG_FNC_IPSEC4_OUTPUT | DBG_FUNC_END, 7,0xff,0xff,0xff,0xff);
666 skip_ipsec:
667 #endif /*IPSEC*/
668
669 /*
670 * IpHack's section.
671 * - Xlate: translate packet's addr/port (NAT).
672 * - Firewall: deny/allow/etc.
673 * - Wrap: fake packet's addr/port <unimpl.>
674 * - Encapsulate: put it in another IP and send out. <unimp.>
675 */
676 if (fr_checkp) {
677 struct mbuf *m1 = m;
678
679 if ((error = (*fr_checkp)(ip, hlen, ifp, 1, &m1)) || !m1)
680 goto done;
681 ip = mtod(m0 = m = m1, struct ip *);
682 }
683
684 /*
685 * Check with the firewall...
686 */
687 if (fw_enable && ip_fw_chk_ptr) {
688 struct sockaddr_in *old = dst;
689
690 off = (*ip_fw_chk_ptr)(&ip,
691 hlen, ifp, &divert_cookie, &m, &rule, &dst);
692 /*
693 * On return we must do the following:
694 * IP_FW_PORT_DENY_FLAG -> drop the pkt (XXX new)
695 * 1<=off<= 0xffff -> DIVERT
696 * (off & IP_FW_PORT_DYNT_FLAG) -> send to a DUMMYNET pipe
697 * (off & IP_FW_PORT_TEE_FLAG) -> TEE the packet
698 * dst != old -> IPFIREWALL_FORWARD
699 * off==0, dst==old -> accept
700 * If some of the above modules is not compiled in, then
701 * we should't have to check the corresponding condition
702 * (because the ipfw control socket should not accept
703 * unsupported rules), but better play safe and drop
704 * packets in case of doubt.
705 */
706 m0 = m;
707 if ( (off & IP_FW_PORT_DENY_FLAG) || m == NULL) {
708 if (m)
709 m_freem(m);
710 error = EACCES ;
711 goto done ;
712 }
713 ip = mtod(m, struct ip *);
714 if (off == 0 && dst == old) /* common case */
715 goto pass ;
716 #if DUMMYNET
717 if ((off & IP_FW_PORT_DYNT_FLAG) != 0) {
718 /*
719 * pass the pkt to dummynet. Need to include
720 * pipe number, m, ifp, ro, dst because these are
721 * not recomputed in the next pass.
722 * All other parameters have been already used and
723 * so they are not needed anymore.
724 * XXX note: if the ifp or ro entry are deleted
725 * while a pkt is in dummynet, we are in trouble!
726 */
727 error = dummynet_io(off & 0xffff, DN_TO_IP_OUT, m,
728 ifp,ro,dst,rule, flags);
729 goto done;
730 }
731 #endif
732 #if IPDIVERT
733 if (off != 0 && (off & IP_FW_PORT_DYNT_FLAG) == 0) {
734 struct mbuf *clone = NULL;
735
736 /* Clone packet if we're doing a 'tee' */
737 if ((off & IP_FW_PORT_TEE_FLAG) != 0)
738 clone = m_dup(m, M_DONTWAIT);
739 /*
740 * XXX
741 * delayed checksums are not currently compatible
742 * with divert sockets.
743 */
744 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
745 in_delayed_cksum(m);
746 m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
747 }
748
749 /* Restore packet header fields to original values */
750 HTONS(ip->ip_len);
751 HTONS(ip->ip_off);
752
753 /* Deliver packet to divert input routine */
754 ip_divert_cookie = divert_cookie;
755 divert_packet(m, 0, off & 0xffff);
756
757 /* If 'tee', continue with original packet */
758 if (clone != NULL) {
759 m0 = m = clone;
760 ip = mtod(m, struct ip *);
761 goto pass;
762 }
763 goto done;
764 }
765 #endif
766
767 #if IPFIREWALL_FORWARD
768 /* Here we check dst to make sure it's directly reachable on the
769 * interface we previously thought it was.
770 * If it isn't (which may be likely in some situations) we have
771 * to re-route it (ie, find a route for the next-hop and the
772 * associated interface) and set them here. This is nested
773 * forwarding which in most cases is undesirable, except where
774 * such control is nigh impossible. So we do it here.
775 * And I'm babbling.
776 */
777 if (off == 0 && old != dst) {
778 struct in_ifaddr *ia;
779
780 /* It's changed... */
781 /* There must be a better way to do this next line... */
782 static struct route sro_fwd, *ro_fwd = &sro_fwd;
783 #if IPFIREWALL_FORWARD_DEBUG
784 printf("IPFIREWALL_FORWARD: New dst ip: ");
785 print_ip(dst->sin_addr);
786 printf("\n");
787 #endif
788 /*
789 * We need to figure out if we have been forwarded
790 * to a local socket. If so then we should somehow
791 * "loop back" to ip_input, and get directed to the
792 * PCB as if we had received this packet. This is
793 * because it may be dificult to identify the packets
794 * you want to forward until they are being output
795 * and have selected an interface. (e.g. locally
796 * initiated packets) If we used the loopback inteface,
797 * we would not be able to control what happens
798 * as the packet runs through ip_input() as
799 * it is done through a ISR.
800 */
801 TAILQ_FOREACH(ia, &in_ifaddrhead, ia_link) {
802 /*
803 * If the addr to forward to is one
804 * of ours, we pretend to
805 * be the destination for this packet.
806 */
807 if (IA_SIN(ia)->sin_addr.s_addr ==
808 dst->sin_addr.s_addr)
809 break;
810 }
811 if (ia) {
812 /* tell ip_input "dont filter" */
813 ip_fw_fwd_addr = dst;
814 if (m->m_pkthdr.rcvif == NULL)
815 m->m_pkthdr.rcvif = ifunit("lo0");
816 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
817 m->m_pkthdr.csum_flags |=
818 CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
819 m->m_pkthdr.csum_data = 0xffff;
820 }
821 m->m_pkthdr.csum_flags |=
822 CSUM_IP_CHECKED | CSUM_IP_VALID;
823 HTONS(ip->ip_len);
824 HTONS(ip->ip_off);
825 ip_input(m);
826 goto done;
827 }
828 /* Some of the logic for this was
829 * nicked from above.
830 *
831 * This rewrites the cached route in a local PCB.
832 * Is this what we want to do?
833 */
834 bcopy(dst, &ro_fwd->ro_dst, sizeof(*dst));
835
836 ro_fwd->ro_rt = 0;
837 rtalloc_ign(ro_fwd, RTF_PRCLONING);
838
839 if (ro_fwd->ro_rt == 0) {
840 ipstat.ips_noroute++;
841 error = EHOSTUNREACH;
842 goto bad;
843 }
844
845 ia = ifatoia(ro_fwd->ro_rt->rt_ifa);
846 ifp = ro_fwd->ro_rt->rt_ifp;
847 ro_fwd->ro_rt->rt_use++;
848 if (ro_fwd->ro_rt->rt_flags & RTF_GATEWAY)
849 dst = (struct sockaddr_in *)ro_fwd->ro_rt->rt_gateway;
850 if (ro_fwd->ro_rt->rt_flags & RTF_HOST)
851 isbroadcast =
852 (ro_fwd->ro_rt->rt_flags & RTF_BROADCAST);
853 else
854 isbroadcast = in_broadcast(dst->sin_addr, ifp);
855 rtfree(ro->ro_rt);
856 ro->ro_rt = ro_fwd->ro_rt;
857 dst = (struct sockaddr_in *)&ro_fwd->ro_dst;
858
859 /*
860 * If we added a default src ip earlier,
861 * which would have been gotten from the-then
862 * interface, do it again, from the new one.
863 */
864 if (fwd_rewrite_src)
865 ip->ip_src = IA_SIN(ia)->sin_addr;
866 goto pass ;
867 }
868 #endif /* IPFIREWALL_FORWARD */
869 /*
870 * if we get here, none of the above matches, and
871 * we have to drop the pkt
872 */
873 m_freem(m);
874 error = EACCES; /* not sure this is the right error msg */
875 goto done;
876 }
877
878 pass:
879 m->m_pkthdr.csum_flags |= CSUM_IP;
880 sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist;
881
882 if ((ifp->if_hwassist & CSUM_TCP_SUM16) != 0) {
883 /*
884 * Special case code for GMACE
885 * frames that can be checksumed by GMACE SUM16 HW:
886 * frame >64, no fragments, no UDP
887 */
888 if (apple_hwcksum_tx && (m->m_pkthdr.csum_flags & CSUM_TCP)
889 && (ip->ip_len > 50) && (ip->ip_len <= ifp->if_mtu)) {
890 /* Apple GMAC HW, expects STUFF_OFFSET << 16 | START_OFFSET */
891 u_short offset = (IP_VHL_HL(ip->ip_vhl) << 2) +14 ; /* IP+Enet header length */
892 u_short csumprev= m->m_pkthdr.csum_data & 0xFFFF;
893 m->m_pkthdr.csum_flags = CSUM_DATA_VALID | CSUM_TCP_SUM16; /* for GMAC */
894 m->m_pkthdr.csum_data = (csumprev + offset) << 16 ;
895 m->m_pkthdr.csum_data += offset;
896 sw_csum = CSUM_DELAY_IP; /* do IP hdr chksum in software */
897 }
898 else {
899 /* let the software handle any UDP or TCP checksums */
900 sw_csum |= (CSUM_DELAY_DATA & m->m_pkthdr.csum_flags);
901 }
902 }
903
904 if (sw_csum & CSUM_DELAY_DATA) {
905 in_delayed_cksum(m);
906 sw_csum &= ~CSUM_DELAY_DATA;
907 m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
908 }
909
910 m->m_pkthdr.csum_flags &= ifp->if_hwassist;
911
912 /*
913 * If small enough for interface, or the interface will take
914 * care of the fragmentation for us, can just send directly.
915 */
916 if ((u_short)ip->ip_len <= ifp->if_mtu ||
917 ifp->if_hwassist & CSUM_FRAGMENT) {
918 HTONS(ip->ip_len);
919 HTONS(ip->ip_off);
920 ip->ip_sum = 0;
921 if (sw_csum & CSUM_DELAY_IP) {
922 ip->ip_sum = in_cksum(m, hlen);
923 }
924
925 #ifndef __APPLE__
926 /* Record statistics for this interface address. */
927 if (!(flags & IP_FORWARDING) && ia != NULL) {
928 ia->ia_ifa.if_opackets++;
929 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
930 }
931 #endif
932
933 #if IPSEC
934 /* clean ipsec history once it goes out of the node */
935 if (ipsec_bypass == 0 && (flags & IP_NOIPSEC) == 0)
936 ipsec_delaux(m);
937 #endif
938 #if __APPLE__
939 error = dlil_output(ifptodlt(ifp, PF_INET), m, (void *) ro->ro_rt,
940 (struct sockaddr *)dst, 0);
941 #else
942 error = (*ifp->if_output)(ifp, m,
943 (struct sockaddr *)dst, ro->ro_rt);
944 #endif
945 goto done;
946 }
947 /*
948 * Too large for interface; fragment if possible.
949 * Must be able to put at least 8 bytes per fragment.
950 */
951 if (ip->ip_off & IP_DF) {
952 error = EMSGSIZE;
953 /*
954 * This case can happen if the user changed the MTU
955 * of an interface after enabling IP on it. Because
956 * most netifs don't keep track of routes pointing to
957 * them, there is no way for one to update all its
958 * routes when the MTU is changed.
959 */
960 if ((ro->ro_rt->rt_flags & (RTF_UP | RTF_HOST))
961 && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU)
962 && (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) {
963 ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu;
964 }
965 ipstat.ips_cantfrag++;
966 goto bad;
967 }
968 len = (ifp->if_mtu - hlen) &~ 7;
969 if (len < 8) {
970 error = EMSGSIZE;
971 goto bad;
972 }
973
974 /*
975 * if the interface will not calculate checksums on
976 * fragmented packets, then do it here.
977 */
978 if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA &&
979 (ifp->if_hwassist & CSUM_IP_FRAGS) == 0) {
980 in_delayed_cksum(m);
981 if (m == NULL)
982 return(ENOMEM);
983 m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
984 }
985
986
987 {
988 int mhlen, firstlen = len;
989 struct mbuf **mnext = &m->m_nextpkt;
990 int nfrags = 1;
991
992 /*
993 * Loop through length of segment after first fragment,
994 * make new header and copy data of each part and link onto chain.
995 */
996 m0 = m;
997 mhlen = sizeof (struct ip);
998 for (off = hlen + len; off < (u_short)ip->ip_len; off += len) {
999 MGETHDR(m, M_DONTWAIT, MT_HEADER);
1000 if (m == 0) {
1001 error = ENOBUFS;
1002 ipstat.ips_odropped++;
1003 goto sendorfree;
1004 }
1005 m->m_flags |= (m0->m_flags & M_MCAST) | M_FRAG;
1006 m->m_data += max_linkhdr;
1007 mhip = mtod(m, struct ip *);
1008 *mhip = *ip;
1009 if (hlen > sizeof (struct ip)) {
1010 mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip);
1011 mhip->ip_vhl = IP_MAKE_VHL(IPVERSION, mhlen >> 2);
1012 }
1013 m->m_len = mhlen;
1014 mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF);
1015 if (ip->ip_off & IP_MF)
1016 mhip->ip_off |= IP_MF;
1017 if (off + len >= (u_short)ip->ip_len)
1018 len = (u_short)ip->ip_len - off;
1019 else
1020 mhip->ip_off |= IP_MF;
1021 mhip->ip_len = htons((u_short)(len + mhlen));
1022 m->m_next = m_copy(m0, off, len);
1023 if (m->m_next == 0) {
1024 (void) m_free(m);
1025 error = ENOBUFS; /* ??? */
1026 ipstat.ips_odropped++;
1027 goto sendorfree;
1028 }
1029 m->m_pkthdr.len = mhlen + len;
1030 m->m_pkthdr.rcvif = (struct ifnet *)0;
1031 m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags;
1032 HTONS(mhip->ip_off);
1033 mhip->ip_sum = 0;
1034 if (sw_csum & CSUM_DELAY_IP) {
1035 mhip->ip_sum = in_cksum(m, mhlen);
1036 }
1037 *mnext = m;
1038 mnext = &m->m_nextpkt;
1039 nfrags++;
1040 }
1041 ipstat.ips_ofragments += nfrags;
1042
1043 /* set first/last markers for fragment chain */
1044 m->m_flags |= M_LASTFRAG;
1045 m0->m_flags |= M_FIRSTFRAG | M_FRAG;
1046 m0->m_pkthdr.csum_data = nfrags;
1047
1048 /*
1049 * Update first fragment by trimming what's been copied out
1050 * and updating header, then send each fragment (in order).
1051 */
1052 m = m0;
1053 m_adj(m, hlen + firstlen - (u_short)ip->ip_len);
1054 m->m_pkthdr.len = hlen + firstlen;
1055 ip->ip_len = htons((u_short)m->m_pkthdr.len);
1056 ip->ip_off |= IP_MF;
1057 HTONS(ip->ip_off);
1058 ip->ip_sum = 0;
1059 if (sw_csum & CSUM_DELAY_IP) {
1060 ip->ip_sum = in_cksum(m, hlen);
1061 }
1062 sendorfree:
1063
1064 KERNEL_DEBUG(DBG_LAYER_END, ip->ip_dst.s_addr,
1065 ip->ip_src.s_addr, ip->ip_p, ip->ip_off, ip->ip_len);
1066
1067 for (m = m0; m; m = m0) {
1068 m0 = m->m_nextpkt;
1069 m->m_nextpkt = 0;
1070 #if IPSEC
1071 /* clean ipsec history once it goes out of the node */
1072 if (ipsec_bypass == 0 && (flags & IP_NOIPSEC) == 0)
1073 ipsec_delaux(m);
1074 #endif
1075 if (error == 0) {
1076 #ifndef __APPLE__
1077 /* Record statistics for this interface address. */
1078 if (ia != NULL) {
1079 ia->ia_ifa.if_opackets++;
1080 ia->ia_ifa.if_obytes += m->m_pkthdr.len;
1081 }
1082 #endif
1083
1084 #if __APPLE__
1085 error = dlil_output(ifptodlt(ifp, PF_INET), m, (void *) ro->ro_rt,
1086 (struct sockaddr *)dst, 0);
1087 #else
1088 error = (*ifp->if_output)(ifp, m,
1089 (struct sockaddr *)dst, ro->ro_rt);
1090 #endif
1091 } else
1092 m_freem(m);
1093 }
1094
1095 if (error == 0)
1096 ipstat.ips_fragmented++;
1097 }
1098 done:
1099 #if IPSEC
1100 if (ipsec_bypass == 0 && (flags & IP_NOIPSEC) == 0) {
1101 if (ro == &iproute && ro->ro_rt) {
1102 rtfree(ro->ro_rt);
1103 ro->ro_rt = NULL;
1104 }
1105 if (sp != NULL) {
1106 KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
1107 printf("DP ip_output call free SP:%x\n", sp));
1108 key_freesp(sp);
1109 }
1110 }
1111 #endif /* IPSEC */
1112
1113 KERNEL_DEBUG(DBG_FNC_IP_OUTPUT | DBG_FUNC_END, error,0,0,0,0);
1114 return (error);
1115 bad:
1116 m_freem(m0);
1117 goto done;
1118 }
1119
1120 void
1121 in_delayed_cksum(struct mbuf *m)
1122 {
1123 struct ip *ip;
1124 u_short csum, offset;
1125 ip = mtod(m, struct ip *);
1126 offset = IP_VHL_HL(ip->ip_vhl) << 2 ;
1127 csum = in_cksum_skip(m, ip->ip_len, offset);
1128 if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0)
1129 csum = 0xffff;
1130 offset += m->m_pkthdr.csum_data & 0xFFFF; /* checksum offset */
1131
1132 if (offset > ip->ip_len) /* bogus offset */
1133 return;
1134
1135 if (offset + sizeof(u_short) > m->m_len) {
1136 printf("delayed m_pullup, m->len: %d off: %d p: %d\n",
1137 m->m_len, offset, ip->ip_p);
1138 /*
1139 * XXX
1140 * this shouldn't happen, but if it does, the
1141 * correct behavior may be to insert the checksum
1142 * in the existing chain instead of rearranging it.
1143 */
1144 m = m_pullup(m, offset + sizeof(u_short));
1145 }
1146 *(u_short *)(m->m_data + offset) = csum;
1147 }
1148
1149 /*
1150 * Insert IP options into preformed packet.
1151 * Adjust IP destination as required for IP source routing,
1152 * as indicated by a non-zero in_addr at the start of the options.
1153 *
1154 * XXX This routine assumes that the packet has no options in place.
1155 */
1156 static struct mbuf *
1157 ip_insertoptions(m, opt, phlen)
1158 register struct mbuf *m;
1159 struct mbuf *opt;
1160 int *phlen;
1161 {
1162 register struct ipoption *p = mtod(opt, struct ipoption *);
1163 struct mbuf *n;
1164 register struct ip *ip = mtod(m, struct ip *);
1165 unsigned optlen;
1166
1167 optlen = opt->m_len - sizeof(p->ipopt_dst);
1168 if (optlen + (u_short)ip->ip_len > IP_MAXPACKET)
1169 return (m); /* XXX should fail */
1170 if (p->ipopt_dst.s_addr)
1171 ip->ip_dst = p->ipopt_dst;
1172 if (m->m_flags & M_EXT || m->m_data - optlen < m->m_pktdat) {
1173 MGETHDR(n, M_DONTWAIT, MT_HEADER);
1174 if (n == 0)
1175 return (m);
1176 n->m_pkthdr.rcvif = (struct ifnet *)0;
1177 n->m_pkthdr.len = m->m_pkthdr.len + optlen;
1178 m->m_len -= sizeof(struct ip);
1179 m->m_data += sizeof(struct ip);
1180 n->m_next = m;
1181 m = n;
1182 m->m_len = optlen + sizeof(struct ip);
1183 m->m_data += max_linkhdr;
1184 (void)memcpy(mtod(m, void *), ip, sizeof(struct ip));
1185 } else {
1186 m->m_data -= optlen;
1187 m->m_len += optlen;
1188 m->m_pkthdr.len += optlen;
1189 ovbcopy((caddr_t)ip, mtod(m, caddr_t), sizeof(struct ip));
1190 }
1191 ip = mtod(m, struct ip *);
1192 bcopy(p->ipopt_list, ip + 1, optlen);
1193 *phlen = sizeof(struct ip) + optlen;
1194 ip->ip_vhl = IP_MAKE_VHL(IPVERSION, *phlen >> 2);
1195 ip->ip_len += optlen;
1196 return (m);
1197 }
1198
1199 /*
1200 * Copy options from ip to jp,
1201 * omitting those not copied during fragmentation.
1202 */
1203 int
1204 ip_optcopy(ip, jp)
1205 struct ip *ip, *jp;
1206 {
1207 register u_char *cp, *dp;
1208 int opt, optlen, cnt;
1209
1210 cp = (u_char *)(ip + 1);
1211 dp = (u_char *)(jp + 1);
1212 cnt = (IP_VHL_HL(ip->ip_vhl) << 2) - sizeof (struct ip);
1213 for (; cnt > 0; cnt -= optlen, cp += optlen) {
1214 opt = cp[0];
1215 if (opt == IPOPT_EOL)
1216 break;
1217 if (opt == IPOPT_NOP) {
1218 /* Preserve for IP mcast tunnel's LSRR alignment. */
1219 *dp++ = IPOPT_NOP;
1220 optlen = 1;
1221 continue;
1222 }
1223 #if DIAGNOSTIC
1224 if (cnt < IPOPT_OLEN + sizeof(*cp))
1225 panic("malformed IPv4 option passed to ip_optcopy");
1226 #endif
1227 optlen = cp[IPOPT_OLEN];
1228 #if DIAGNOSTIC
1229 if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
1230 panic("malformed IPv4 option passed to ip_optcopy");
1231 #endif
1232 /* bogus lengths should have been caught by ip_dooptions */
1233 if (optlen > cnt)
1234 optlen = cnt;
1235 if (IPOPT_COPIED(opt)) {
1236 bcopy(cp, dp, optlen);
1237 dp += optlen;
1238 }
1239 }
1240 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
1241 *dp++ = IPOPT_EOL;
1242 return (optlen);
1243 }
1244
1245 /*
1246 * IP socket option processing.
1247 */
1248 int
1249 ip_ctloutput(so, sopt)
1250 struct socket *so;
1251 struct sockopt *sopt;
1252 {
1253 struct inpcb *inp = sotoinpcb(so);
1254 int error, optval;
1255
1256 error = optval = 0;
1257 if (sopt->sopt_level != IPPROTO_IP) {
1258 return (EINVAL);
1259 }
1260
1261 switch (sopt->sopt_dir) {
1262 case SOPT_SET:
1263 switch (sopt->sopt_name) {
1264 case IP_OPTIONS:
1265 #ifdef notyet
1266 case IP_RETOPTS:
1267 #endif
1268 {
1269 struct mbuf *m;
1270 if (sopt->sopt_valsize > MLEN) {
1271 error = EMSGSIZE;
1272 break;
1273 }
1274 MGET(m, sopt->sopt_p ? M_WAIT : M_DONTWAIT, MT_HEADER);
1275 if (m == 0) {
1276 error = ENOBUFS;
1277 break;
1278 }
1279 m->m_len = sopt->sopt_valsize;
1280 error = sooptcopyin(sopt, mtod(m, char *), m->m_len,
1281 m->m_len);
1282 if (error)
1283 break;
1284
1285 return (ip_pcbopts(sopt->sopt_name, &inp->inp_options,
1286 m));
1287 }
1288
1289 case IP_TOS:
1290 case IP_TTL:
1291 case IP_RECVOPTS:
1292 case IP_RECVRETOPTS:
1293 case IP_RECVDSTADDR:
1294 case IP_RECVIF:
1295 case IP_RECVTTL:
1296 #if defined(NFAITH) && NFAITH > 0
1297 case IP_FAITH:
1298 #endif
1299 error = sooptcopyin(sopt, &optval, sizeof optval,
1300 sizeof optval);
1301 if (error)
1302 break;
1303
1304 switch (sopt->sopt_name) {
1305 case IP_TOS:
1306 inp->inp_ip_tos = optval;
1307 break;
1308
1309 case IP_TTL:
1310 inp->inp_ip_ttl = optval;
1311 break;
1312 #define OPTSET(bit) \
1313 if (optval) \
1314 inp->inp_flags |= bit; \
1315 else \
1316 inp->inp_flags &= ~bit;
1317
1318 case IP_RECVOPTS:
1319 OPTSET(INP_RECVOPTS);
1320 break;
1321
1322 case IP_RECVRETOPTS:
1323 OPTSET(INP_RECVRETOPTS);
1324 break;
1325
1326 case IP_RECVDSTADDR:
1327 OPTSET(INP_RECVDSTADDR);
1328 break;
1329
1330 case IP_RECVIF:
1331 OPTSET(INP_RECVIF);
1332 break;
1333
1334 case IP_RECVTTL:
1335 OPTSET(INP_RECVTTL);
1336 break;
1337
1338 #if defined(NFAITH) && NFAITH > 0
1339 case IP_FAITH:
1340 OPTSET(INP_FAITH);
1341 break;
1342 #endif
1343 }
1344 break;
1345 #undef OPTSET
1346
1347 case IP_MULTICAST_IF:
1348 case IP_MULTICAST_VIF:
1349 case IP_MULTICAST_TTL:
1350 case IP_MULTICAST_LOOP:
1351 case IP_ADD_MEMBERSHIP:
1352 case IP_DROP_MEMBERSHIP:
1353 error = ip_setmoptions(sopt, &inp->inp_moptions);
1354 break;
1355
1356 case IP_PORTRANGE:
1357 error = sooptcopyin(sopt, &optval, sizeof optval,
1358 sizeof optval);
1359 if (error)
1360 break;
1361
1362 switch (optval) {
1363 case IP_PORTRANGE_DEFAULT:
1364 inp->inp_flags &= ~(INP_LOWPORT);
1365 inp->inp_flags &= ~(INP_HIGHPORT);
1366 break;
1367
1368 case IP_PORTRANGE_HIGH:
1369 inp->inp_flags &= ~(INP_LOWPORT);
1370 inp->inp_flags |= INP_HIGHPORT;
1371 break;
1372
1373 case IP_PORTRANGE_LOW:
1374 inp->inp_flags &= ~(INP_HIGHPORT);
1375 inp->inp_flags |= INP_LOWPORT;
1376 break;
1377
1378 default:
1379 error = EINVAL;
1380 break;
1381 }
1382 break;
1383
1384 #if IPSEC
1385 case IP_IPSEC_POLICY:
1386 {
1387 caddr_t req = NULL;
1388 size_t len = 0;
1389 int priv;
1390 struct mbuf *m;
1391 int optname;
1392
1393 if ((error = soopt_getm(sopt, &m)) != 0) /* XXX */
1394 break;
1395 if ((error = soopt_mcopyin(sopt, m)) != 0) /* XXX */
1396 break;
1397 priv = (sopt->sopt_p != NULL &&
1398 suser(sopt->sopt_p->p_ucred,
1399 &sopt->sopt_p->p_acflag) != 0) ? 0 : 1;
1400 if (m) {
1401 req = mtod(m, caddr_t);
1402 len = m->m_len;
1403 }
1404 optname = sopt->sopt_name;
1405 error = ipsec4_set_policy(inp, optname, req, len, priv);
1406 m_freem(m);
1407 break;
1408 }
1409 #endif /*IPSEC*/
1410
1411 default:
1412 error = ENOPROTOOPT;
1413 break;
1414 }
1415 break;
1416
1417 case SOPT_GET:
1418 switch (sopt->sopt_name) {
1419 case IP_OPTIONS:
1420 case IP_RETOPTS:
1421 if (inp->inp_options)
1422 error = sooptcopyout(sopt,
1423 mtod(inp->inp_options,
1424 char *),
1425 inp->inp_options->m_len);
1426 else
1427 sopt->sopt_valsize = 0;
1428 break;
1429
1430 case IP_TOS:
1431 case IP_TTL:
1432 case IP_RECVOPTS:
1433 case IP_RECVRETOPTS:
1434 case IP_RECVDSTADDR:
1435 case IP_RECVIF:
1436 case IP_RECVTTL:
1437 case IP_PORTRANGE:
1438 #if defined(NFAITH) && NFAITH > 0
1439 case IP_FAITH:
1440 #endif
1441 switch (sopt->sopt_name) {
1442
1443 case IP_TOS:
1444 optval = inp->inp_ip_tos;
1445 break;
1446
1447 case IP_TTL:
1448 optval = inp->inp_ip_ttl;
1449 break;
1450
1451 #define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0)
1452
1453 case IP_RECVOPTS:
1454 optval = OPTBIT(INP_RECVOPTS);
1455 break;
1456
1457 case IP_RECVRETOPTS:
1458 optval = OPTBIT(INP_RECVRETOPTS);
1459 break;
1460
1461 case IP_RECVDSTADDR:
1462 optval = OPTBIT(INP_RECVDSTADDR);
1463 break;
1464
1465 case IP_RECVIF:
1466 optval = OPTBIT(INP_RECVIF);
1467 break;
1468
1469 case IP_RECVTTL:
1470 optval = OPTBIT(INP_RECVTTL);
1471 break;
1472
1473 case IP_PORTRANGE:
1474 if (inp->inp_flags & INP_HIGHPORT)
1475 optval = IP_PORTRANGE_HIGH;
1476 else if (inp->inp_flags & INP_LOWPORT)
1477 optval = IP_PORTRANGE_LOW;
1478 else
1479 optval = 0;
1480 break;
1481
1482 #if defined(NFAITH) && NFAITH > 0
1483 case IP_FAITH:
1484 optval = OPTBIT(INP_FAITH);
1485 break;
1486 #endif
1487 }
1488 error = sooptcopyout(sopt, &optval, sizeof optval);
1489 break;
1490
1491 case IP_MULTICAST_IF:
1492 case IP_MULTICAST_VIF:
1493 case IP_MULTICAST_TTL:
1494 case IP_MULTICAST_LOOP:
1495 case IP_ADD_MEMBERSHIP:
1496 case IP_DROP_MEMBERSHIP:
1497 error = ip_getmoptions(sopt, inp->inp_moptions);
1498 break;
1499
1500 #if IPSEC
1501 case IP_IPSEC_POLICY:
1502 {
1503 struct mbuf *m = NULL;
1504 caddr_t req = NULL;
1505 size_t len = 0;
1506
1507 if (m != 0) {
1508 req = mtod(m, caddr_t);
1509 len = m->m_len;
1510 }
1511 error = ipsec4_get_policy(sotoinpcb(so), req, len, &m);
1512 if (error == 0)
1513 error = soopt_mcopyout(sopt, m); /* XXX */
1514 if (error == 0)
1515 m_freem(m);
1516 break;
1517 }
1518 #endif /*IPSEC*/
1519
1520 default:
1521 error = ENOPROTOOPT;
1522 break;
1523 }
1524 break;
1525 }
1526 return (error);
1527 }
1528
1529 /*
1530 * Set up IP options in pcb for insertion in output packets.
1531 * Store in mbuf with pointer in pcbopt, adding pseudo-option
1532 * with destination address if source routed.
1533 */
1534 static int
1535 ip_pcbopts(optname, pcbopt, m)
1536 int optname;
1537 struct mbuf **pcbopt;
1538 register struct mbuf *m;
1539 {
1540 register int cnt, optlen;
1541 register u_char *cp;
1542 u_char opt;
1543
1544 /* turn off any old options */
1545 if (*pcbopt)
1546 (void)m_free(*pcbopt);
1547 *pcbopt = 0;
1548 if (m == (struct mbuf *)0 || m->m_len == 0) {
1549 /*
1550 * Only turning off any previous options.
1551 */
1552 if (m)
1553 (void)m_free(m);
1554 return (0);
1555 }
1556
1557 #ifndef vax
1558 if (m->m_len % sizeof(int32_t))
1559 goto bad;
1560 #endif
1561 /*
1562 * IP first-hop destination address will be stored before
1563 * actual options; move other options back
1564 * and clear it when none present.
1565 */
1566 if (m->m_data + m->m_len + sizeof(struct in_addr) >= &m->m_dat[MLEN])
1567 goto bad;
1568 cnt = m->m_len;
1569 m->m_len += sizeof(struct in_addr);
1570 cp = mtod(m, u_char *) + sizeof(struct in_addr);
1571 ovbcopy(mtod(m, caddr_t), (caddr_t)cp, (unsigned)cnt);
1572 bzero(mtod(m, caddr_t), sizeof(struct in_addr));
1573
1574 for (; cnt > 0; cnt -= optlen, cp += optlen) {
1575 opt = cp[IPOPT_OPTVAL];
1576 if (opt == IPOPT_EOL)
1577 break;
1578 if (opt == IPOPT_NOP)
1579 optlen = 1;
1580 else {
1581 if (cnt < IPOPT_OLEN + sizeof(*cp))
1582 goto bad;
1583 optlen = cp[IPOPT_OLEN];
1584 if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt)
1585 goto bad;
1586 }
1587 switch (opt) {
1588
1589 default:
1590 break;
1591
1592 case IPOPT_LSRR:
1593 case IPOPT_SSRR:
1594 /*
1595 * user process specifies route as:
1596 * ->A->B->C->D
1597 * D must be our final destination (but we can't
1598 * check that since we may not have connected yet).
1599 * A is first hop destination, which doesn't appear in
1600 * actual IP option, but is stored before the options.
1601 */
1602 if (optlen < IPOPT_MINOFF - 1 + sizeof(struct in_addr))
1603 goto bad;
1604 m->m_len -= sizeof(struct in_addr);
1605 cnt -= sizeof(struct in_addr);
1606 optlen -= sizeof(struct in_addr);
1607 cp[IPOPT_OLEN] = optlen;
1608 /*
1609 * Move first hop before start of options.
1610 */
1611 bcopy((caddr_t)&cp[IPOPT_OFFSET+1], mtod(m, caddr_t),
1612 sizeof(struct in_addr));
1613 /*
1614 * Then copy rest of options back
1615 * to close up the deleted entry.
1616 */
1617 ovbcopy((caddr_t)(&cp[IPOPT_OFFSET+1] +
1618 sizeof(struct in_addr)),
1619 (caddr_t)&cp[IPOPT_OFFSET+1],
1620 (unsigned)cnt + sizeof(struct in_addr));
1621 break;
1622 }
1623 }
1624 if (m->m_len > MAX_IPOPTLEN + sizeof(struct in_addr))
1625 goto bad;
1626 *pcbopt = m;
1627 return (0);
1628
1629 bad:
1630 (void)m_free(m);
1631 return (EINVAL);
1632 }
1633
1634 /*
1635 * XXX
1636 * The whole multicast option thing needs to be re-thought.
1637 * Several of these options are equally applicable to non-multicast
1638 * transmission, and one (IP_MULTICAST_TTL) totally duplicates a
1639 * standard option (IP_TTL).
1640 */
1641
1642 /*
1643 * following RFC1724 section 3.3, 0.0.0.0/8 is interpreted as interface index.
1644 */
1645 static struct ifnet *
1646 ip_multicast_if(a, ifindexp)
1647 struct in_addr *a;
1648 int *ifindexp;
1649 {
1650 int ifindex;
1651 struct ifnet *ifp;
1652
1653 if (ifindexp)
1654 *ifindexp = 0;
1655 if (ntohl(a->s_addr) >> 24 == 0) {
1656 ifindex = ntohl(a->s_addr) & 0xffffff;
1657 if (ifindex < 0 || if_index < ifindex)
1658 return NULL;
1659 ifp = ifindex2ifnet[ifindex];
1660 if (ifindexp)
1661 *ifindexp = ifindex;
1662 } else {
1663 INADDR_TO_IFP(*a, ifp);
1664 }
1665 return ifp;
1666 }
1667
1668 /*
1669 * Set the IP multicast options in response to user setsockopt().
1670 */
1671 static int
1672 ip_setmoptions(sopt, imop)
1673 struct sockopt *sopt;
1674 struct ip_moptions **imop;
1675 {
1676 int error = 0;
1677 int i;
1678 struct in_addr addr;
1679 struct ip_mreq mreq;
1680 struct ifnet *ifp = NULL;
1681 struct ip_moptions *imo = *imop;
1682 int ifindex;
1683 int s;
1684
1685 if (imo == NULL) {
1686 /*
1687 * No multicast option buffer attached to the pcb;
1688 * allocate one and initialize to default values.
1689 */
1690 error = ip_createmoptions(imop);
1691 if (error != 0)
1692 return error;
1693 imo = *imop;
1694 }
1695
1696 switch (sopt->sopt_name) {
1697 /* store an index number for the vif you wanna use in the send */
1698 case IP_MULTICAST_VIF:
1699 if (legal_vif_num == 0) {
1700 error = EOPNOTSUPP;
1701 break;
1702 }
1703 error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
1704 if (error)
1705 break;
1706 if (!legal_vif_num(i) && (i != -1)) {
1707 error = EINVAL;
1708 break;
1709 }
1710 imo->imo_multicast_vif = i;
1711 break;
1712
1713 case IP_MULTICAST_IF:
1714 /*
1715 * Select the interface for outgoing multicast packets.
1716 */
1717 error = sooptcopyin(sopt, &addr, sizeof addr, sizeof addr);
1718 if (error)
1719 break;
1720 /*
1721 * INADDR_ANY is used to remove a previous selection.
1722 * When no interface is selected, a default one is
1723 * chosen every time a multicast packet is sent.
1724 */
1725 if (addr.s_addr == INADDR_ANY) {
1726 imo->imo_multicast_ifp = NULL;
1727 break;
1728 }
1729 /*
1730 * The selected interface is identified by its local
1731 * IP address. Find the interface and confirm that
1732 * it supports multicasting.
1733 */
1734 s = splimp();
1735 ifp = ip_multicast_if(&addr, &ifindex);
1736 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1737 splx(s);
1738 error = EADDRNOTAVAIL;
1739 break;
1740 }
1741 imo->imo_multicast_ifp = ifp;
1742 if (ifindex)
1743 imo->imo_multicast_addr = addr;
1744 else
1745 imo->imo_multicast_addr.s_addr = INADDR_ANY;
1746 splx(s);
1747 break;
1748
1749 case IP_MULTICAST_TTL:
1750 /*
1751 * Set the IP time-to-live for outgoing multicast packets.
1752 * The original multicast API required a char argument,
1753 * which is inconsistent with the rest of the socket API.
1754 * We allow either a char or an int.
1755 */
1756 if (sopt->sopt_valsize == 1) {
1757 u_char ttl;
1758 error = sooptcopyin(sopt, &ttl, 1, 1);
1759 if (error)
1760 break;
1761 imo->imo_multicast_ttl = ttl;
1762 } else {
1763 u_int ttl;
1764 error = sooptcopyin(sopt, &ttl, sizeof ttl,
1765 sizeof ttl);
1766 if (error)
1767 break;
1768 if (ttl > 255)
1769 error = EINVAL;
1770 else
1771 imo->imo_multicast_ttl = ttl;
1772 }
1773 break;
1774
1775 case IP_MULTICAST_LOOP:
1776 /*
1777 * Set the loopback flag for outgoing multicast packets.
1778 * Must be zero or one. The original multicast API required a
1779 * char argument, which is inconsistent with the rest
1780 * of the socket API. We allow either a char or an int.
1781 */
1782 if (sopt->sopt_valsize == 1) {
1783 u_char loop;
1784 error = sooptcopyin(sopt, &loop, 1, 1);
1785 if (error)
1786 break;
1787 imo->imo_multicast_loop = !!loop;
1788 } else {
1789 u_int loop;
1790 error = sooptcopyin(sopt, &loop, sizeof loop,
1791 sizeof loop);
1792 if (error)
1793 break;
1794 imo->imo_multicast_loop = !!loop;
1795 }
1796 break;
1797
1798 case IP_ADD_MEMBERSHIP:
1799 /*
1800 * Add a multicast group membership.
1801 * Group must be a valid IP multicast address.
1802 */
1803 error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
1804 if (error)
1805 break;
1806
1807 error = ip_addmembership(imo, &mreq);
1808 break;
1809
1810 case IP_DROP_MEMBERSHIP:
1811 /*
1812 * Drop a multicast group membership.
1813 * Group must be a valid IP multicast address.
1814 */
1815 error = sooptcopyin(sopt, &mreq, sizeof mreq, sizeof mreq);
1816 if (error)
1817 break;
1818
1819 error = ip_dropmembership(imo, &mreq);
1820 break;
1821
1822 default:
1823 error = EOPNOTSUPP;
1824 break;
1825 }
1826
1827 /*
1828 * If all options have default values, no need to keep the mbuf.
1829 */
1830 if (imo->imo_multicast_ifp == NULL &&
1831 imo->imo_multicast_vif == -1 &&
1832 imo->imo_multicast_ttl == IP_DEFAULT_MULTICAST_TTL &&
1833 imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP &&
1834 imo->imo_num_memberships == 0) {
1835 FREE(*imop, M_IPMOPTS);
1836 *imop = NULL;
1837 }
1838
1839 return (error);
1840 }
1841
1842 /*
1843 * Set the IP multicast options in response to user setsockopt().
1844 */
1845 __private_extern__ int
1846 ip_createmoptions(
1847 struct ip_moptions **imop)
1848 {
1849 struct ip_moptions *imo;
1850 imo = (struct ip_moptions*) _MALLOC(sizeof(*imo), M_IPMOPTS,
1851 M_WAITOK);
1852
1853 if (imo == NULL)
1854 return (ENOBUFS);
1855 *imop = imo;
1856 imo->imo_multicast_ifp = NULL;
1857 imo->imo_multicast_addr.s_addr = INADDR_ANY;
1858 imo->imo_multicast_vif = -1;
1859 imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL;
1860 imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
1861 imo->imo_num_memberships = 0;
1862
1863 return 0;
1864 }
1865
1866 /*
1867 * Add membership to an IPv4 multicast.
1868 */
1869 __private_extern__ int
1870 ip_addmembership(
1871 struct ip_moptions *imo,
1872 struct ip_mreq *mreq)
1873 {
1874 struct route ro;
1875 struct sockaddr_in *dst;
1876 struct ifnet *ifp = NULL;
1877 int error = 0;
1878 int s = 0;
1879 int i;
1880
1881 if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {
1882 error = EINVAL;
1883 return error;
1884 }
1885 s = splimp();
1886 /*
1887 * If no interface address was provided, use the interface of
1888 * the route to the given multicast address.
1889 */
1890 if (mreq->imr_interface.s_addr == INADDR_ANY) {
1891 bzero((caddr_t)&ro, sizeof(ro));
1892 dst = (struct sockaddr_in *)&ro.ro_dst;
1893 dst->sin_len = sizeof(*dst);
1894 dst->sin_family = AF_INET;
1895 dst->sin_addr = mreq->imr_multiaddr;
1896 rtalloc(&ro);
1897 if (ro.ro_rt != NULL) {
1898 ifp = ro.ro_rt->rt_ifp;
1899 rtfree(ro.ro_rt);
1900 }
1901 else {
1902 /* If there's no default route, try using loopback */
1903 mreq->imr_interface.s_addr = INADDR_LOOPBACK;
1904 }
1905 }
1906
1907 if (ifp == NULL) {
1908 ifp = ip_multicast_if(&mreq->imr_interface, NULL);
1909 }
1910
1911 /*
1912 * See if we found an interface, and confirm that it
1913 * supports multicast.
1914 */
1915 if (ifp == NULL || (ifp->if_flags & IFF_MULTICAST) == 0) {
1916 error = EADDRNOTAVAIL;
1917 splx(s);
1918 return error;
1919 }
1920 /*
1921 * See if the membership already exists or if all the
1922 * membership slots are full.
1923 */
1924 for (i = 0; i < imo->imo_num_memberships; ++i) {
1925 if (imo->imo_membership[i]->inm_ifp == ifp &&
1926 imo->imo_membership[i]->inm_addr.s_addr
1927 == mreq->imr_multiaddr.s_addr)
1928 break;
1929 }
1930 if (i < imo->imo_num_memberships) {
1931 error = EADDRINUSE;
1932 splx(s);
1933 return error;
1934 }
1935 if (i == IP_MAX_MEMBERSHIPS) {
1936 error = ETOOMANYREFS;
1937 splx(s);
1938 return error;
1939 }
1940 /*
1941 * Everything looks good; add a new record to the multicast
1942 * address list for the given interface.
1943 */
1944 if ((imo->imo_membership[i] =
1945 in_addmulti(&mreq->imr_multiaddr, ifp)) == NULL) {
1946 error = ENOBUFS;
1947 splx(s);
1948 return error;
1949 }
1950 ++imo->imo_num_memberships;
1951 splx(s);
1952
1953 return error;
1954 }
1955
1956 /*
1957 * Drop membership of an IPv4 multicast.
1958 */
1959 __private_extern__ int
1960 ip_dropmembership(
1961 struct ip_moptions *imo,
1962 struct ip_mreq *mreq)
1963 {
1964 int error = 0;
1965 int s = 0;
1966 struct ifnet* ifp = NULL;
1967 int i;
1968
1969 if (!IN_MULTICAST(ntohl(mreq->imr_multiaddr.s_addr))) {
1970 error = EINVAL;
1971 return error;
1972 }
1973
1974 s = splimp();
1975 /*
1976 * If an interface address was specified, get a pointer
1977 * to its ifnet structure.
1978 */
1979 if (mreq->imr_interface.s_addr == INADDR_ANY)
1980 ifp = NULL;
1981 else {
1982 ifp = ip_multicast_if(&mreq->imr_interface, NULL);
1983 if (ifp == NULL) {
1984 error = EADDRNOTAVAIL;
1985 splx(s);
1986 return error;
1987 }
1988 }
1989 /*
1990 * Find the membership in the membership array.
1991 */
1992 for (i = 0; i < imo->imo_num_memberships; ++i) {
1993 if ((ifp == NULL ||
1994 imo->imo_membership[i]->inm_ifp == ifp) &&
1995 imo->imo_membership[i]->inm_addr.s_addr ==
1996 mreq->imr_multiaddr.s_addr)
1997 break;
1998 }
1999 if (i == imo->imo_num_memberships) {
2000 error = EADDRNOTAVAIL;
2001 splx(s);
2002 return error;
2003 }
2004 /*
2005 * Give up the multicast address record to which the
2006 * membership points.
2007 */
2008 in_delmulti(imo->imo_membership[i]);
2009 /*
2010 * Remove the gap in the membership array.
2011 */
2012 for (++i; i < imo->imo_num_memberships; ++i)
2013 imo->imo_membership[i-1] = imo->imo_membership[i];
2014 --imo->imo_num_memberships;
2015 splx(s);
2016
2017 return error;
2018 }
2019
2020 /*
2021 * Return the IP multicast options in response to user getsockopt().
2022 */
2023 static int
2024 ip_getmoptions(sopt, imo)
2025 struct sockopt *sopt;
2026 register struct ip_moptions *imo;
2027 {
2028 struct in_addr addr;
2029 struct in_ifaddr *ia;
2030 int error, optval;
2031 u_char coptval;
2032
2033 error = 0;
2034 switch (sopt->sopt_name) {
2035 case IP_MULTICAST_VIF:
2036 if (imo != NULL)
2037 optval = imo->imo_multicast_vif;
2038 else
2039 optval = -1;
2040 error = sooptcopyout(sopt, &optval, sizeof optval);
2041 break;
2042
2043 case IP_MULTICAST_IF:
2044 if (imo == NULL || imo->imo_multicast_ifp == NULL)
2045 addr.s_addr = INADDR_ANY;
2046 else if (imo->imo_multicast_addr.s_addr) {
2047 /* return the value user has set */
2048 addr = imo->imo_multicast_addr;
2049 } else {
2050 IFP_TO_IA(imo->imo_multicast_ifp, ia);
2051 addr.s_addr = (ia == NULL) ? INADDR_ANY
2052 : IA_SIN(ia)->sin_addr.s_addr;
2053 }
2054 error = sooptcopyout(sopt, &addr, sizeof addr);
2055 break;
2056
2057 case IP_MULTICAST_TTL:
2058 if (imo == 0)
2059 optval = coptval = IP_DEFAULT_MULTICAST_TTL;
2060 else
2061 optval = coptval = imo->imo_multicast_ttl;
2062 if (sopt->sopt_valsize == 1)
2063 error = sooptcopyout(sopt, &coptval, 1);
2064 else
2065 error = sooptcopyout(sopt, &optval, sizeof optval);
2066 break;
2067
2068 case IP_MULTICAST_LOOP:
2069 if (imo == 0)
2070 optval = coptval = IP_DEFAULT_MULTICAST_LOOP;
2071 else
2072 optval = coptval = imo->imo_multicast_loop;
2073 if (sopt->sopt_valsize == 1)
2074 error = sooptcopyout(sopt, &coptval, 1);
2075 else
2076 error = sooptcopyout(sopt, &optval, sizeof optval);
2077 break;
2078
2079 default:
2080 error = ENOPROTOOPT;
2081 break;
2082 }
2083 return (error);
2084 }
2085
2086 /*
2087 * Discard the IP multicast options.
2088 */
2089 void
2090 ip_freemoptions(imo)
2091 register struct ip_moptions *imo;
2092 {
2093 register int i;
2094
2095 if (imo != NULL) {
2096 for (i = 0; i < imo->imo_num_memberships; ++i)
2097 if (imo->imo_membership[i] != NULL)
2098 in_delmulti(imo->imo_membership[i]);
2099 FREE(imo, M_IPMOPTS);
2100 }
2101 }
2102
2103 /*
2104 * Routine called from ip_output() to loop back a copy of an IP multicast
2105 * packet to the input queue of a specified interface. Note that this
2106 * calls the output routine of the loopback "driver", but with an interface
2107 * pointer that might NOT be a loopback interface -- evil, but easier than
2108 * replicating that code here.
2109 */
2110 static void
2111 ip_mloopback(ifp, m, dst, hlen)
2112 struct ifnet *ifp;
2113 register struct mbuf *m;
2114 register struct sockaddr_in *dst;
2115 int hlen;
2116 {
2117 register struct ip *ip;
2118 struct mbuf *copym;
2119
2120 copym = m_copy(m, 0, M_COPYALL);
2121 if (copym != NULL && (copym->m_flags & M_EXT || copym->m_len < hlen))
2122 copym = m_pullup(copym, hlen);
2123 if (copym != NULL) {
2124 /*
2125 * We don't bother to fragment if the IP length is greater
2126 * than the interface's MTU. Can this possibly matter?
2127 */
2128 ip = mtod(copym, struct ip *);
2129 HTONS(ip->ip_len);
2130 HTONS(ip->ip_off);
2131 ip->ip_sum = 0;
2132 ip->ip_sum = in_cksum(copym, hlen);
2133 /*
2134 * NB:
2135 * It's not clear whether there are any lingering
2136 * reentrancy problems in other areas which might
2137 * be exposed by using ip_input directly (in
2138 * particular, everything which modifies the packet
2139 * in-place). Yet another option is using the
2140 * protosw directly to deliver the looped back
2141 * packet. For the moment, we'll err on the side
2142 * of safety by using if_simloop().
2143 */
2144 #if 1 /* XXX */
2145 if (dst->sin_family != AF_INET) {
2146 printf("ip_mloopback: bad address family %d\n",
2147 dst->sin_family);
2148 dst->sin_family = AF_INET;
2149 }
2150 #endif
2151
2152
2153 /*
2154 * Mark checksum as valid or calculate checksum for loopback.
2155 *
2156 * This is done this way because we have to embed the ifp of
2157 * the interface we will send the original copy of the packet
2158 * out on in the mbuf. ip_input will check if_hwassist of the
2159 * embedded ifp and ignore all csum_flags if if_hwassist is 0.
2160 * The UDP checksum has not been calculated yet.
2161 */
2162 if (copym->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
2163 if (ifp->if_hwassist) {
2164 copym->m_pkthdr.csum_flags |=
2165 CSUM_DATA_VALID | CSUM_PSEUDO_HDR |
2166 CSUM_IP_CHECKED | CSUM_IP_VALID;
2167 copym->m_pkthdr.csum_data = 0xffff;
2168 } else {
2169 NTOHS(ip->ip_len);
2170 in_delayed_cksum(copym);
2171 HTONS(ip->ip_len);
2172 }
2173 }
2174
2175
2176 /*
2177 * TedW:
2178 * We need to send all loopback traffic down to dlil in case
2179 * a filter has tapped-in.
2180 */
2181
2182 if (lo_dl_tag == 0)
2183 dlil_find_dltag(APPLE_IF_FAM_LOOPBACK, 0, PF_INET, &lo_dl_tag);
2184
2185 /*
2186 * Stuff the 'real' ifp into the pkthdr, to be used in matching
2187 * in ip_input(); we need the loopback ifp/dl_tag passed as args
2188 * to make the loopback driver compliant with the data link
2189 * requirements.
2190 */
2191 if (lo_dl_tag) {
2192 copym->m_pkthdr.rcvif = ifp;
2193 dlil_output(lo_dl_tag, copym, 0, (struct sockaddr *) dst, 0);
2194 } else {
2195 printf("Warning: ip_output call to dlil_find_dltag failed!\n");
2196 m_freem(copym);
2197 }
2198
2199 /* if_simloop(ifp, copym, (struct sockaddr *)dst, 0);*/
2200 }
2201 }