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