1/*
2 * Copyright (c) 2008-2013 Apple 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
30
31/* ----------------------------------------------------------------------------------
32Application of kernel control for interface creation
33
34Theory of operation:
35utun (user tunnel) acts as glue between kernel control sockets and network interfaces.
36This kernel control will register an interface for every client that connects.
37---------------------------------------------------------------------------------- */
38
39#include <sys/systm.h>
40#include <sys/kern_control.h>
41#include <net/kpi_protocol.h>
42#include <net/kpi_interface.h>
43#include <sys/socket.h>
44#include <net/if.h>
45#include <net/if_types.h>
46#include <net/bpf.h>
47#include <net/if_utun.h>
48#include <libkern/OSMalloc.h>
49#include <libkern/OSAtomic.h>
50#include <sys/mbuf.h>
51#include <sys/sockio.h>
52#include <netinet/in.h>
53#include <netinet6/in6_var.h>
54#include <netinet6/in6_var.h>
55#include <sys/kauth.h>
56
57
58/* Kernel Control functions */
59static errno_t	utun_ctl_connect(kern_ctl_ref kctlref, struct sockaddr_ctl *sac,
60								 void **unitinfo);
61static errno_t	utun_ctl_disconnect(kern_ctl_ref kctlref, u_int32_t unit,
62									void *unitinfo);
63static errno_t	utun_ctl_send(kern_ctl_ref kctlref, u_int32_t unit,
64							   void *unitinfo, mbuf_t m, int flags);
65static errno_t	utun_ctl_getopt(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo,
66								 int opt, void *data, size_t *len);
67static errno_t	utun_ctl_setopt(kern_ctl_ref kctlref, u_int32_t unit, void *unitinfo,
68								 int opt, void *data, size_t len);
69
70/* Network Interface functions */
71static errno_t	utun_output(ifnet_t interface, mbuf_t data);
72static errno_t	utun_demux(ifnet_t interface, mbuf_t data, char *frame_header,
73						   protocol_family_t *protocol);
74static errno_t	utun_framer(ifnet_t interface, mbuf_t *packet,
75    const struct sockaddr *dest, const char *desk_linkaddr,
76    const char *frame_type, u_int32_t *prepend_len, u_int32_t *postpend_len);
77static errno_t	utun_add_proto(ifnet_t interface, protocol_family_t protocol,
78							   const struct ifnet_demux_desc *demux_array,
79							   u_int32_t demux_count);
80static errno_t	utun_del_proto(ifnet_t interface, protocol_family_t protocol);
81static errno_t	utun_ioctl(ifnet_t interface, u_long cmd, void *data);
82static void		utun_detached(ifnet_t interface);
83
84/* Protocol handlers */
85static errno_t	utun_attach_proto(ifnet_t interface, protocol_family_t proto);
86static errno_t	utun_proto_input(ifnet_t interface, protocol_family_t protocol,
87								 mbuf_t m, char *frame_header);
88static errno_t utun_proto_pre_output(ifnet_t interface, protocol_family_t protocol,
89					 mbuf_t *packet, const struct sockaddr *dest, void *route,
90					 char *frame_type, char *link_layer_dest);
91__private_extern__ errno_t utun_pkt_input (struct utun_pcb *pcb, mbuf_t m);
92
93static kern_ctl_ref	utun_kctlref;
94static u_int32_t	utun_family;
95static OSMallocTag	utun_malloc_tag;
96static SInt32		utun_ifcount = 0;
97
98/* Prepend length */
99void*
100utun_alloc(size_t size)
101{
102	size_t	*mem = OSMalloc(size + sizeof(size_t), utun_malloc_tag);
103
104	if (mem) {
105		*mem = size + sizeof(size_t);
106		mem++;
107	}
108
109	return (void*)mem;
110}
111
112void
113utun_free(void *ptr)
114{
115	size_t	*size = ptr;
116	size--;
117	OSFree(size, *size, utun_malloc_tag);
118}
119
120errno_t
121utun_register_control(void)
122{
123	struct kern_ctl_reg	kern_ctl;
124	errno_t				result = 0;
125
126	/* Create a tag to allocate memory */
127	utun_malloc_tag = OSMalloc_Tagalloc(UTUN_CONTROL_NAME, OSMT_DEFAULT);
128
129	/* Find a unique value for our interface family */
130	result = mbuf_tag_id_find(UTUN_CONTROL_NAME, &utun_family);
131	if (result != 0) {
132		printf("utun_register_control - mbuf_tag_id_find_internal failed: %d\n", result);
133		return result;
134	}
135
136	bzero(&kern_ctl, sizeof(kern_ctl));
137	strncpy(kern_ctl.ctl_name, UTUN_CONTROL_NAME, sizeof(kern_ctl.ctl_name));
138	kern_ctl.ctl_name[sizeof(kern_ctl.ctl_name) - 1] = 0;
139	kern_ctl.ctl_flags = CTL_FLAG_PRIVILEGED; /* Require root */
140	kern_ctl.ctl_sendsize = 512 * 1024;
141	kern_ctl.ctl_recvsize = 512 * 1024;
142	kern_ctl.ctl_connect = utun_ctl_connect;
143	kern_ctl.ctl_disconnect = utun_ctl_disconnect;
144	kern_ctl.ctl_send = utun_ctl_send;
145	kern_ctl.ctl_setopt = utun_ctl_setopt;
146	kern_ctl.ctl_getopt = utun_ctl_getopt;
147
148	utun_ctl_init_crypto();
149
150	result = ctl_register(&kern_ctl, &utun_kctlref);
151	if (result != 0) {
152		printf("utun_register_control - ctl_register failed: %d\n", result);
153		return result;
154	}
155
156	/* Register the protocol plumbers */
157	if ((result = proto_register_plumber(PF_INET, utun_family,
158										 utun_attach_proto, NULL)) != 0) {
159		printf("utun_register_control - proto_register_plumber(PF_INET, %d) failed: %d\n",
160			   utun_family, result);
161		ctl_deregister(utun_kctlref);
162		return result;
163	}
164
165	/* Register the protocol plumbers */
166	if ((result = proto_register_plumber(PF_INET6, utun_family,
167										 utun_attach_proto, NULL)) != 0) {
168		proto_unregister_plumber(PF_INET, utun_family);
169		ctl_deregister(utun_kctlref);
170		printf("utun_register_control - proto_register_plumber(PF_INET6, %d) failed: %d\n",
171			   utun_family, result);
172		return result;
173	}
174
175	return 0;
176}
177
178/* Kernel control functions */
179
180static errno_t
181utun_ctl_connect(
182	kern_ctl_ref		kctlref,
183	struct sockaddr_ctl	*sac,
184	void				**unitinfo)
185{
186	struct ifnet_init_eparams	utun_init;
187	struct utun_pcb				*pcb;
188	errno_t						result;
189	struct ifnet_stats_param 	stats;
190
191	/* kernel control allocates, interface frees */
192	pcb = utun_alloc(sizeof(*pcb));
193	if (pcb == NULL)
194		return ENOMEM;
195
196	/* Setup the protocol control block */
197	bzero(pcb, sizeof(*pcb));
198	*unitinfo = pcb;
199	pcb->utun_ctlref = kctlref;
200	pcb->utun_unit = sac->sc_unit;
201
202	printf("utun_ctl_connect: creating interface utun%d\n", pcb->utun_unit - 1);
203
204	/* Create the interface */
205	bzero(&utun_init, sizeof(utun_init));
206	utun_init.ver = IFNET_INIT_CURRENT_VERSION;
207	utun_init.len = sizeof (utun_init);
208	utun_init.flags = IFNET_INIT_LEGACY;
209	utun_init.name = "utun";
210	utun_init.unit = pcb->utun_unit - 1;
211	utun_init.family = utun_family;
212	utun_init.type = IFT_OTHER;
213	utun_init.output = utun_output;
214	utun_init.demux = utun_demux;
215	utun_init.framer_extended = utun_framer;
216	utun_init.add_proto = utun_add_proto;
217	utun_init.del_proto = utun_del_proto;
218	utun_init.softc = pcb;
219	utun_init.ioctl = utun_ioctl;
220	utun_init.detach = utun_detached;
221
222	result = ifnet_allocate_extended(&utun_init, &pcb->utun_ifp);
223	if (result != 0) {
224		printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result);
225		utun_free(pcb);
226		return result;
227	}
228	OSIncrementAtomic(&utun_ifcount);
229
230	/* Set flags and additional information. */
231	ifnet_set_mtu(pcb->utun_ifp, 1500);
232	ifnet_set_flags(pcb->utun_ifp, IFF_UP | IFF_MULTICAST | IFF_POINTOPOINT, 0xffff);
233
234	/* The interface must generate its own IPv6 LinkLocal address,
235	 * if possible following the recommendation of RFC2472 to the 64bit interface ID
236	 */
237	ifnet_set_eflags(pcb->utun_ifp, IFEF_NOAUTOIPV6LL, IFEF_NOAUTOIPV6LL);
238
239	/* Reset the stats in case as the interface may have been recycled */
240	bzero(&stats, sizeof(struct ifnet_stats_param));
241	ifnet_set_stat(pcb->utun_ifp, &stats);
242
243	/* Attach the interface */
244	result = ifnet_attach(pcb->utun_ifp, NULL);
245	if (result != 0) {
246		printf("utun_ctl_connect - ifnet_allocate failed: %d\n", result);
247		ifnet_release(pcb->utun_ifp);
248		utun_free(pcb);
249	}
250
251	/* Attach to bpf */
252	if (result == 0)
253		bpfattach(pcb->utun_ifp, DLT_NULL, 4);
254
255	/* The interfaces resoures allocated, mark it as running */
256	if (result == 0)
257		ifnet_set_flags(pcb->utun_ifp, IFF_RUNNING, IFF_RUNNING);
258
259	return result;
260}
261
262static errno_t
263utun_detach_ip(
264	ifnet_t				interface,
265	protocol_family_t	protocol,
266	socket_t			pf_socket)
267{
268	errno_t result = EPROTONOSUPPORT;
269
270	/* Attempt a detach */
271	if (protocol == PF_INET) {
272		struct ifreq	ifr;
273
274		bzero(&ifr, sizeof(ifr));
275		snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d",
276				 ifnet_name(interface), ifnet_unit(interface));
277
278		result = sock_ioctl(pf_socket, SIOCPROTODETACH, &ifr);
279	}
280	else if (protocol == PF_INET6) {
281		struct in6_ifreq	ifr6;
282
283		bzero(&ifr6, sizeof(ifr6));
284		snprintf(ifr6.ifr_name, sizeof(ifr6.ifr_name), "%s%d",
285				 ifnet_name(interface), ifnet_unit(interface));
286
287		result = sock_ioctl(pf_socket, SIOCPROTODETACH_IN6, &ifr6);
288	}
289
290	return result;
291}
292
293static void
294utun_remove_address(
295	ifnet_t				interface,
296	protocol_family_t	protocol,
297	ifaddr_t			address,
298	socket_t			pf_socket)
299{
300	errno_t result = 0;
301
302	/* Attempt a detach */
303	if (protocol == PF_INET) {
304		struct ifreq	ifr;
305
306		bzero(&ifr, sizeof(ifr));
307		snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d",
308				 ifnet_name(interface), ifnet_unit(interface));
309		result = ifaddr_address(address, &ifr.ifr_addr, sizeof(ifr.ifr_addr));
310		if (result != 0) {
311			printf("utun_remove_address - ifaddr_address failed: %d", result);
312		}
313		else {
314			result = sock_ioctl(pf_socket, SIOCDIFADDR, &ifr);
315			if (result != 0) {
316				printf("utun_remove_address - SIOCDIFADDR failed: %d", result);
317			}
318		}
319	}
320	else if (protocol == PF_INET6) {
321		struct in6_ifreq	ifr6;
322
323		bzero(&ifr6, sizeof(ifr6));
324		snprintf(ifr6.ifr_name, sizeof(ifr6.ifr_name), "%s%d",
325				 ifnet_name(interface), ifnet_unit(interface));
326		result = ifaddr_address(address, (struct sockaddr*)&ifr6.ifr_addr,
327								sizeof(ifr6.ifr_addr));
328		if (result != 0) {
329			printf("utun_remove_address - ifaddr_address failed (v6): %d",
330				   result);
331		}
332		else {
333			result = sock_ioctl(pf_socket, SIOCDIFADDR_IN6, &ifr6);
334			if (result != 0) {
335				printf("utun_remove_address - SIOCDIFADDR_IN6 failed: %d",
336					   result);
337			}
338		}
339	}
340}
341
342static void
343utun_cleanup_family(
344	ifnet_t				interface,
345	protocol_family_t	protocol)
346{
347	errno_t		result = 0;
348	socket_t	pf_socket = NULL;
349	ifaddr_t	*addresses = NULL;
350	int			i;
351
352	if (protocol != PF_INET && protocol != PF_INET6) {
353		printf("utun_cleanup_family - invalid protocol family %d\n", protocol);
354		return;
355	}
356
357	/* Create a socket for removing addresses and detaching the protocol */
358	result = sock_socket(protocol, SOCK_DGRAM, 0, NULL, NULL, &pf_socket);
359	if (result != 0) {
360		if (result != EAFNOSUPPORT)
361			printf("utun_cleanup_family - failed to create %s socket: %d\n",
362				protocol == PF_INET ? "IP" : "IPv6", result);
363		goto cleanup;
364	}
365
366        /* always set SS_PRIV, we want to close and detach regardless */
367        sock_setpriv(pf_socket, 1);
368
369	result = utun_detach_ip(interface, protocol, pf_socket);
370	if (result == 0 || result == ENXIO) {
371		/* We are done! We either detached or weren't attached. */
372		goto cleanup;
373	}
374	else if (result != EBUSY) {
375		/* Uh, not really sure what happened here... */
376		printf("utun_cleanup_family - utun_detach_ip failed: %d\n", result);
377		goto cleanup;
378	}
379
380	/*
381	 * At this point, we received an EBUSY error. This means there are
382	 * addresses attached. We should detach them and then try again.
383	 */
384	result = ifnet_get_address_list_family(interface, &addresses, protocol);
385	if (result != 0) {
386		printf("fnet_get_address_list_family(%s%d, 0xblah, %s) - failed: %d\n",
387			ifnet_name(interface), ifnet_unit(interface),
388			protocol == PF_INET ? "PF_INET" : "PF_INET6", result);
389		goto cleanup;
390	}
391
392	for (i = 0; addresses[i] != 0; i++) {
393		utun_remove_address(interface, protocol, addresses[i], pf_socket);
394	}
395	ifnet_free_address_list(addresses);
396	addresses = NULL;
397
398	/*
399	 * The addresses should be gone, we should try the remove again.
400	 */
401	result = utun_detach_ip(interface, protocol, pf_socket);
402	if (result != 0 && result != ENXIO) {
403		printf("utun_cleanup_family - utun_detach_ip failed: %d\n", result);
404	}
405
406cleanup:
407	if (pf_socket != NULL)
408		sock_close(pf_socket);
409
410	if (addresses != NULL)
411		ifnet_free_address_list(addresses);
412}
413
414static errno_t
415utun_ctl_disconnect(
416	__unused kern_ctl_ref	kctlref,
417	__unused u_int32_t		unit,
418	void					*unitinfo)
419{
420	struct utun_pcb	*pcb = unitinfo;
421	ifnet_t			ifp = pcb->utun_ifp;
422	errno_t			result = 0;
423
424	utun_cleanup_crypto(pcb);
425
426	pcb->utun_ctlref = NULL;
427	pcb->utun_unit = 0;
428
429	/*
430	 * We want to do everything in our power to ensure that the interface
431	 * really goes away when the socket is closed. We must remove IP/IPv6
432	 * addresses and detach the protocols. Finally, we can remove and
433	 * release the interface.
434	 */
435	utun_cleanup_family(ifp, AF_INET);
436	utun_cleanup_family(ifp, AF_INET6);
437
438	if ((result = ifnet_detach(ifp)) != 0) {
439		printf("utun_ctl_disconnect - ifnet_detach failed: %d\n", result);
440	}
441
442	if ((result = ifnet_release(ifp)) != 0) {
443		printf("utun_ctl_disconnect - ifnet_release failed: %d\n", result);
444	}
445
446	return 0;
447}
448
449static errno_t
450utun_ctl_send(
451	__unused kern_ctl_ref	kctlref,
452	__unused u_int32_t		unit,
453	void					*unitinfo,
454	mbuf_t					m,
455	__unused int			flags)
456{
457	/*
458	 * The userland ABI requires the first four bytes have the protocol family
459	 * in network byte order: swap them
460	 */
461	if (m_pktlen(m) >= 4)
462		*(protocol_family_t *)mbuf_data(m) = ntohl(*(protocol_family_t *)mbuf_data(m));
463	else
464		printf("%s - unexpected short mbuf pkt len %d\n", __func__, m_pktlen(m) );
465
466	return utun_pkt_input((struct utun_pcb *)unitinfo, m);
467}
468
469static errno_t
470utun_ctl_setopt(
471	__unused kern_ctl_ref	kctlref,
472	__unused u_int32_t		unit,
473	void					*unitinfo,
474	int						opt,
475	void					*data,
476	size_t					len)
477{
478	struct utun_pcb			*pcb = unitinfo;
479	errno_t					result = 0;
480
481	/* check for privileges for privileged options */
482	switch (opt) {
483		case UTUN_OPT_FLAGS:
484		case UTUN_OPT_EXT_IFDATA_STATS:
485		case UTUN_OPT_SET_DELEGATE_INTERFACE:
486			if (kauth_cred_issuser(kauth_cred_get()) == 0) {
487				return EPERM;
488			}
489			break;
490	}
491
492	switch (opt) {
493		case UTUN_OPT_FLAGS:
494			if (len != sizeof(u_int32_t))
495				result = EMSGSIZE;
496			else
497				pcb->utun_flags = *(u_int32_t *)data;
498			break;
499
500		case UTUN_OPT_ENABLE_CRYPTO:
501			result = utun_ctl_enable_crypto(kctlref, unit, unitinfo, opt, data, len);
502			break;
503
504		case UTUN_OPT_CONFIG_CRYPTO_KEYS:
505			result = utun_ctl_config_crypto_keys(kctlref, unit, unitinfo, opt, data, len);
506			break;
507
508		case UTUN_OPT_UNCONFIG_CRYPTO_KEYS:
509			result = utun_ctl_unconfig_crypto_keys(kctlref, unit, unitinfo, opt, data, len);
510			break;
511
512		case UTUN_OPT_DISABLE_CRYPTO:
513			result = utun_ctl_disable_crypto(kctlref, unit, unitinfo, opt, data, len);
514			break;
515
516		case UTUN_OPT_STOP_CRYPTO_DATA_TRAFFIC:
517			result = utun_ctl_stop_crypto_data_traffic(kctlref, unit, unitinfo, opt, data, len);
518			break;
519
520		case UTUN_OPT_START_CRYPTO_DATA_TRAFFIC:
521			result = utun_ctl_start_crypto_data_traffic(kctlref, unit, unitinfo, opt, data, len);
522			break;
523
524		case UTUN_OPT_CONFIG_CRYPTO_FRAMER:
525			result = utun_ctl_config_crypto_framer(kctlref, unit, unitinfo, opt, data, len);
526			break;
527
528		case UTUN_OPT_UNCONFIG_CRYPTO_FRAMER:
529			result = utun_ctl_unconfig_crypto_framer(kctlref, unit, unitinfo, opt, data, len);
530			break;
531
532		case UTUN_OPT_EXT_IFDATA_STATS:
533			if (len != sizeof(int)) {
534				result = EMSGSIZE;
535				break;
536			}
537			pcb->utun_ext_ifdata_stats = (*(int *)data) ? 1 : 0;
538			break;
539
540		case UTUN_OPT_INC_IFDATA_STATS_IN:
541		case UTUN_OPT_INC_IFDATA_STATS_OUT: {
542			struct utun_stats_param *utsp = (struct utun_stats_param *)data;
543
544			if (utsp == NULL || len < sizeof(struct utun_stats_param)) {
545				result = EINVAL;
546				break;
547			}
548			if (!pcb->utun_ext_ifdata_stats) {
549				result = EINVAL;
550				break;
551			}
552			if (opt == UTUN_OPT_INC_IFDATA_STATS_IN)
553				ifnet_stat_increment_in(pcb->utun_ifp, utsp->utsp_packets,
554					utsp->utsp_bytes, utsp->utsp_errors);
555			else
556				ifnet_stat_increment_out(pcb->utun_ifp, utsp->utsp_packets,
557					utsp->utsp_bytes, utsp->utsp_errors);
558			break;
559		}
560
561	        case UTUN_OPT_SET_DELEGATE_INTERFACE: {
562			ifnet_t		del_ifp = NULL;
563			char            name[IFNAMSIZ];
564
565			if (len > IFNAMSIZ - 1) {
566				result = EMSGSIZE;
567				break;
568			}
569			if (len != 0) {    /* if len==0, del_ifp will be NULL causing the delegate to be removed */
570				bcopy(data, name, len);
571				name[len] = 0;
572				result = ifnet_find_by_name(name, &del_ifp);
573			}
574			if (result == 0) {
575				result = ifnet_set_delegate(pcb->utun_ifp, del_ifp);
576				if (del_ifp)
577					ifnet_release(del_ifp);
578			}
579			break;
580		}
581
582	        default:
583			result = ENOPROTOOPT;
584			break;
585	}
586
587	return result;
588}
589
590static errno_t
591utun_ctl_getopt(
592	__unused kern_ctl_ref	kctlref,
593	__unused u_int32_t		unit,
594	void					*unitinfo,
595	int						opt,
596	void					*data,
597	size_t					*len)
598{
599	struct utun_pcb			*pcb = unitinfo;
600	errno_t					result = 0;
601
602	switch (opt) {
603		case UTUN_OPT_FLAGS:
604			if (*len != sizeof(u_int32_t))
605				result = EMSGSIZE;
606			else
607				*(u_int32_t *)data = pcb->utun_flags;
608			break;
609
610		case UTUN_OPT_EXT_IFDATA_STATS:
611			if (*len != sizeof(int))
612				result = EMSGSIZE;
613			else
614				*(int *)data = (pcb->utun_ext_ifdata_stats) ? 1 : 0;
615			break;
616
617		case UTUN_OPT_IFNAME:
618			*len = snprintf(data, *len, "%s%d", ifnet_name(pcb->utun_ifp), ifnet_unit(pcb->utun_ifp)) + 1;
619			break;
620
621		case UTUN_OPT_GENERATE_CRYPTO_KEYS_IDX:
622			result = utun_ctl_generate_crypto_keys_idx(kctlref, unit, unitinfo, opt, data, len);
623			break;
624
625		default:
626			result = ENOPROTOOPT;
627			break;
628	}
629
630	return result;
631}
632
633/* Network Interface functions */
634static errno_t
635utun_output(
636			   ifnet_t	interface,
637			   mbuf_t	data)
638{
639	struct utun_pcb	*pcb = ifnet_softc(interface);
640	errno_t			result;
641
642	if (m_pktlen(data) >= 4) {
643		bpf_tap_out(pcb->utun_ifp, DLT_NULL, data, 0, 0);
644	}
645
646	if (pcb->utun_flags & UTUN_FLAGS_NO_OUTPUT) {
647		/* flush data */
648		mbuf_freem(data);
649		return 0;
650	}
651
652	// otherwise, fall thru to ctl_enqueumbuf
653	if (pcb->utun_ctlref) {
654		int	length;
655
656		// only pass packets to utun-crypto if crypto is enabled and 'suspend data traffic' is not.
657		if ((pcb->utun_flags & (UTUN_FLAGS_CRYPTO | UTUN_FLAGS_CRYPTO_STOP_DATA_TRAFFIC)) == UTUN_FLAGS_CRYPTO) {
658			if (utun_pkt_crypto_output(pcb, &data) == 0) {
659				return 0;
660			}
661		}
662
663		/*
664		 * The ABI requires the protocol in network byte order
665		 */
666		if (m_pktlen(data) >= 4)
667			*(u_int32_t *)mbuf_data(data) = htonl(*(u_int32_t *)mbuf_data(data));
668
669		length = mbuf_pkthdr_len(data);
670		result = ctl_enqueuembuf(pcb->utun_ctlref, pcb->utun_unit, data, CTL_DATA_EOR);
671		if (result != 0) {
672			mbuf_freem(data);
673			printf("utun_output - ctl_enqueuembuf failed: %d\n", result);
674
675			ifnet_stat_increment_out(interface, 0, 0, 1);
676		}
677		else {
678			if (!pcb->utun_ext_ifdata_stats)
679				ifnet_stat_increment_out(interface, 1, length, 0);
680		}
681	}
682	else
683		mbuf_freem(data);
684
685	return 0;
686}
687
688/* Network Interface functions */
689static errno_t
690utun_demux(
691	__unused ifnet_t	interface,
692	mbuf_t				data,
693	__unused char		*frame_header,
694	protocol_family_t	*protocol)
695{
696
697	while (data != NULL && mbuf_len(data) < 1) {
698		data = mbuf_next(data);
699	}
700
701	if (data == NULL)
702		return ENOENT;
703
704	*protocol = *(u_int32_t *)mbuf_data(data);
705	return 0;
706}
707
708static errno_t
709utun_framer(
710		   __unused ifnet_t				interface,
711		   mbuf_t				*packet,
712			__unused const struct sockaddr *dest,
713			__unused const char *desk_linkaddr,
714			const char *frame_type,
715			u_int32_t *prepend_len,
716			u_int32_t *postpend_len)
717{
718    if (mbuf_prepend(packet, sizeof(protocol_family_t), MBUF_DONTWAIT) != 0) {
719		printf("utun_framer - ifnet_output prepend failed\n");
720
721		ifnet_stat_increment_out(interface, 0, 0, 1);
722
723		// just	return, because the buffer was freed in mbuf_prepend
724        return EJUSTRETURN;
725    }
726	if (prepend_len != NULL)
727		*prepend_len = sizeof(protocol_family_t);
728	if (postpend_len != NULL)
729		*postpend_len = 0;
730
731    // place protocol number at the beginning of the mbuf
732    *(protocol_family_t *)mbuf_data(*packet) = *(protocol_family_t *)(uintptr_t)(size_t)frame_type;
733
734    return 0;
735}
736
737static errno_t
738utun_add_proto(
739	__unused ifnet_t						interface,
740	protocol_family_t						protocol,
741	__unused const struct ifnet_demux_desc	*demux_array,
742	__unused u_int32_t						demux_count)
743{
744	switch(protocol) {
745		case PF_INET:
746			return 0;
747		case PF_INET6:
748			return 0;
749		default:
750			break;
751	}
752
753	return ENOPROTOOPT;
754}
755
756static errno_t
757utun_del_proto(
758	__unused ifnet_t 			interface,
759	__unused protocol_family_t	protocol)
760{
761	return 0;
762}
763
764static errno_t
765utun_ioctl(
766	ifnet_t		interface,
767	u_long		command,
768	void		*data)
769{
770	errno_t	result = 0;
771
772	switch(command) {
773		case SIOCSIFMTU:
774			ifnet_set_mtu(interface, ((struct ifreq*)data)->ifr_mtu);
775			break;
776
777		case SIOCSIFFLAGS:
778			/* ifioctl() takes care of it */
779			break;
780
781		default:
782			result = EOPNOTSUPP;
783	}
784
785	return result;
786}
787
788static void
789utun_detached(
790	ifnet_t	interface)
791{
792	struct utun_pcb	*pcb = ifnet_softc(interface);
793
794	utun_free(pcb);
795
796	OSDecrementAtomic(&utun_ifcount);
797}
798
799/* Protocol Handlers */
800
801static errno_t
802utun_proto_input(
803	__unused ifnet_t	interface,
804	protocol_family_t	protocol,
805	mbuf_t				m,
806	__unused char		*frame_header)
807{
808
809	// remove protocol family first
810	mbuf_adj(m, sizeof(u_int32_t));
811
812	if (proto_input(protocol, m) != 0)
813		m_freem(m);
814
815	return 0;
816}
817
818static errno_t
819utun_proto_pre_output(
820	__unused ifnet_t	interface,
821	protocol_family_t	protocol,
822	__unused mbuf_t		*packet,
823	__unused const struct sockaddr *dest,
824	__unused void *route,
825	__unused char *frame_type,
826	__unused char *link_layer_dest)
827{
828
829	*(protocol_family_t *)(void *)frame_type = protocol;
830		return 0;
831}
832
833static errno_t
834utun_attach_proto(
835	ifnet_t				interface,
836	protocol_family_t	protocol)
837{
838	struct ifnet_attach_proto_param	proto;
839	errno_t							result;
840
841	bzero(&proto, sizeof(proto));
842	proto.input = utun_proto_input;
843	proto.pre_output = utun_proto_pre_output;
844
845	result = ifnet_attach_protocol(interface, protocol, &proto);
846	if (result != 0 && result != EEXIST) {
847		printf("utun_attach_inet - ifnet_attach_protocol %d failed: %d\n",
848			protocol, result);
849	}
850
851	return result;
852}
853
854errno_t
855utun_pkt_input (struct utun_pcb *pcb, mbuf_t m)
856{
857	errno_t	result;
858	protocol_family_t protocol = 0;
859
860	mbuf_pkthdr_setrcvif(m, pcb->utun_ifp);
861
862	if (m_pktlen(m) >= 4)  {
863		protocol = *(u_int32_t *)mbuf_data(m);
864
865		bpf_tap_in(pcb->utun_ifp, DLT_NULL, m, 0, 0);
866	}
867	if (pcb->utun_flags & UTUN_FLAGS_NO_INPUT) {
868		/* flush data */
869		mbuf_freem(m);
870		return 0;
871	}
872
873	// quick exit for keepalive packets
874	if (protocol == AF_UTUN && pcb->utun_flags & UTUN_FLAGS_CRYPTO) {
875		if (utun_pkt_crypto_output(pcb, &m) == 0) {
876			return 0;
877		}
878		printf("%s: utun_pkt_crypto_output failed, flags %x\n", __FUNCTION__, pcb->utun_flags);
879		return EINVAL;
880	}
881
882	if (!pcb->utun_ext_ifdata_stats) {
883		struct ifnet_stat_increment_param	incs;
884
885		bzero(&incs, sizeof(incs));
886		incs.packets_in = 1;
887		incs.bytes_in = mbuf_pkthdr_len(m);
888		result = ifnet_input(pcb->utun_ifp, m, &incs);
889	} else {
890		result = ifnet_input(pcb->utun_ifp, m, NULL);
891	}
892	if (result != 0) {
893		ifnet_stat_increment_in(pcb->utun_ifp, 0, 0, 1);
894
895		printf("%s - ifnet_input failed: %d\n", __FUNCTION__, result);
896		mbuf_freem(m);
897	}
898
899	return 0;
900}
901