2 * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <sys/systm.h>
30 #include <sys/socket.h>
32 #include <net/if_types.h>
33 #include <net/if_utun.h>
35 #include <netinet/in.h>
36 #include <netinet6/in6_var.h>
37 #include <netinet6/in6_var.h>
38 #include <netinet/ip.h>
39 #include <netinet/ip6.h>
40 #include <netinet/ip_var.h>
41 #include <net/if_utun.h>
42 #include <net/if_utun_crypto_dtls.h>
45 extern errno_t
utun_pkt_input (struct utun_pcb
*pcb
, mbuf_t m
);
47 static UInt32 dtls_kpi_callbacks_inited
= FALSE
;
48 static unsigned int dtls_kpi_flags
= 0;
49 static utun_crypto_kpi_connect_func dtls_kpi_connect
= (__typeof__(dtls_kpi_connect
))NULL
;
50 static utun_crypto_kpi_send_func dtls_kpi_send
= (__typeof__(dtls_kpi_send
))NULL
;
52 // convert this mutex to shared lock
53 static UInt32 dtls_ctl_mutex_inited
= FALSE
;
54 static lck_grp_t
*dtls_ctl_mutex_grp
= NULL
;
55 static lck_grp_attr_t
*dtls_ctl_mutex_grp_attr
= NULL
;
56 static lck_attr_t
*dtls_ctl_mutex_attr
= NULL
;
57 static lck_mtx_t dtls_ctl_mutex
;
59 #define utun_ctl_get_first_framer(ctx, inner_type) (utun_crypto_framer_t *)LIST_FIRST(&ctx->framer_listheads[UTUN_CRYPTO_INNER_TYPE_TO_IDX(inner_type)])
60 #define utun_get_framer_listhead(ctx, inner_type) &ctx->framer_listheads[UTUN_CRYPTO_INNER_TYPE_TO_IDX(inner_type)]
63 utun_ctl_clr_dtls_framer (utun_crypto_framer_t
*rem_framer
)
65 if (!rem_framer
) return;
67 // TOFIX: switch to BPF
68 LIST_REMOVE(rem_framer
, framer_chain
); // unchain the framer
69 if (rem_framer
->dir
== UTUN_CRYPTO_DIR_IN
) {
70 if (utun_crypto_framer_state_dtls_in(rem_framer
).in_pattern
) {
71 utun_free(utun_crypto_framer_state_dtls_in(rem_framer
).in_pattern
);
73 if (utun_crypto_framer_state_dtls_in(rem_framer
).in_pattern_mask
) {
74 utun_free(utun_crypto_framer_state_dtls_in(rem_framer
).in_pattern_mask
);
76 if (utun_crypto_framer_state_dtls_in(rem_framer
).in_pattern_masked
) {
77 utun_free(utun_crypto_framer_state_dtls_in(rem_framer
).in_pattern_masked
);
80 if (utun_crypto_framer_state_dtls_out(rem_framer
).out_pattern
) {
81 utun_free(utun_crypto_framer_state_dtls_out(rem_framer
).out_pattern
);
84 utun_free(rem_framer
);
90 utun_ctl_clr_dtls_framers (utun_crypto_framer_t
*first_framer
)
92 utun_crypto_framer_t
*cur_framer
, *nxt_framer
;
94 // check framer->state.u.dtls.u.in.listhead for duplicates;
95 for (cur_framer
= first_framer
;
97 cur_framer
= nxt_framer
) {
98 nxt_framer
= (__typeof__(nxt_framer
))LIST_NEXT(cur_framer
, framer_chain
);
99 utun_ctl_clr_dtls_framer(cur_framer
);
106 utun_ctl_clr_dtls_all_framers (utun_crypto_ctx_t
*crypto_ctx
)
108 utun_ctl_clr_dtls_framers(utun_ctl_get_first_framer(crypto_ctx
, UTUN_CRYPTO_INNER_TYPE_IPv4
));
109 utun_ctl_clr_dtls_framers(utun_ctl_get_first_framer(crypto_ctx
, UTUN_CRYPTO_INNER_TYPE_IPv6
));
110 crypto_ctx
->num_framers
= 0;
114 utun_ctl_restart_dtls_framers (utun_crypto_framer_t
*first_framer
)
116 utun_crypto_framer_t
*cur_framer
;
118 // check framer->state.u.dtls.u.in.listhead for duplicates;
119 for (cur_framer
= first_framer
;
121 cur_framer
= (__typeof__(cur_framer
))LIST_NEXT(cur_framer
, framer_chain
)) {
122 utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field
= utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field_initval
;
129 utun_ctl_restart_dtls_all_framers (utun_crypto_ctx_t
*crypto_ctx
)
131 utun_ctl_restart_dtls_framers(utun_ctl_get_first_framer(crypto_ctx
, UTUN_CRYPTO_INNER_TYPE_IPv4
));
132 utun_ctl_restart_dtls_framers(utun_ctl_get_first_framer(crypto_ctx
, UTUN_CRYPTO_INNER_TYPE_IPv6
));
136 is_pattern_all_zeroes (u_int8_t
*pattern
,
141 if (!pattern
|| !pattern_len
) return FALSE
; // false if args are NULL
143 for (i
= 0; i
< pattern_len
; i
++) {
144 if (pattern
[i
] != 0) return FALSE
;
150 is_pattern_masked_all_zeroes (u_int8_t
*pattern
,
151 u_int8_t
*pattern_mask
,
156 if (!pattern
|| !pattern_mask
|| !pattern_len
) return FALSE
; // false if args are NULL
158 for (i
= 0; i
< pattern_len
; i
++) {
159 if ((pattern
[i
] & pattern_mask
[i
])) return FALSE
;
165 utun_ctl_calc_dtls_framer_pattern_and_mask (u_int8_t
*pattern_masked
, u_int8_t
*pattern
, u_int8_t
*mask
, int len
)
168 for (i
= 0; i
< len
; i
++) {
169 pattern_masked
[i
] = (pattern
[i
] & mask
[i
]);
174 utun_ctl_did_dtls_framer_pattern_match (u_int8_t
*input
, u_int8_t
*pattern_masked
, int len
)
177 for (i
= 0; i
< len
; i
++) {
178 if ((input
[i
] & pattern_masked
[i
]) != pattern_masked
[i
]) return FALSE
;
184 utun_pkt_dtls_input_frame_is_data(utun_crypto_ctx_t
*crypto_ctx
,
186 protocol_family_t family
,
190 utun_crypto_framer_t
*cur_framer
;
192 p
= mtod(*pkt
, __typeof__(p
));
193 for (cur_framer
= utun_ctl_get_first_framer(crypto_ctx
, utun_crypto_framer_protocol_family_to_inner_type(family
));
195 cur_framer
= (__typeof__(cur_framer
))LIST_NEXT(cur_framer
, framer_chain
)) {
196 if (m_pktlen(*pkt
) < utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_len
) {
199 if ((*pkt
)->m_len
< utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_len
) {
200 *pkt
= m_pullup(*pkt
, utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_len
);
202 (*pkt
)->m_len
< utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_len
) {
205 p
= mtod(*pkt
, __typeof__(p
));
207 // TOFIX: switch to BPF
208 if (utun_ctl_did_dtls_framer_pattern_match(p
,
209 utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_masked
,
210 utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_len
)) {
211 *striplen
= utun_crypto_framer_state_dtls_in(cur_framer
).in_data_offset
;
218 #define GETLONG(l, cp) { \
219 (l) = *(cp)++ << 8; \
220 (l) |= *(cp)++; (l) <<= 8; \
221 (l) |= *(cp)++; (l) <<= 8; \
224 #define PUTLONG(l, cp) { \
225 *(cp)++ = (u_char) ((l) >> 24); \
226 *(cp)++ = (u_char) ((l) >> 16); \
227 *(cp)++ = (u_char) ((l) >> 8); \
228 *(cp)++ = (u_char) (l); \
232 utun_pkt_dtls_output_frame_encapsulate (utun_crypto_ctx_t
*crypto_ctx
,
234 protocol_family_t proto
)
237 utun_crypto_framer_t
*cur_framer
;
240 // TOFIX: switch to BPF
242 if (!crypto_ctx
->num_framers
) {
245 if (proto
!= AF_INET
&& proto
!= AF_INET6
) {
246 printf("%s: unsupported proto %d\n", __FUNCTION__
, proto
);
250 for (cur_framer
= utun_ctl_get_first_framer(crypto_ctx
, utun_crypto_framer_protocol_family_to_inner_type(proto
));
251 cur_framer
!= NULL
&& !utun_crypto_framer_state_dtls_out(cur_framer
).out_pattern
;
252 cur_framer
= (__typeof__(cur_framer
))LIST_NEXT(cur_framer
, framer_chain
));
254 !utun_crypto_framer_state_dtls_out(cur_framer
).out_pattern_len
) {
258 pkt_len
= m_pktlen(*pkt
);
260 // prepend/encapsulate the output pattern
261 if (mbuf_prepend(pkt
, utun_crypto_framer_state_dtls_out(cur_framer
).out_pattern_len
, MBUF_DONTWAIT
) != 0) {
262 printf("%s - ifnet_output prepend failed\n", __FUNCTION__
);
266 p
= mtod(*pkt
, __typeof__(p
));
268 utun_crypto_framer_state_dtls_out(cur_framer
).out_pattern
,
269 utun_crypto_framer_state_dtls_out(cur_framer
).out_pattern_len
);
270 // fill a "length" field... if configured
271 if (utun_crypto_framer_state_dtls_out(cur_framer
).len_field_mask
) {
273 u_int8_t
*q
= p
+ utun_crypto_framer_state_dtls_out(cur_framer
).len_field_offset
;
275 tmp
&= ((pkt_len
+ utun_crypto_framer_state_dtls_out(cur_framer
).len_field_extra
) & utun_crypto_framer_state_dtls_out(cur_framer
).len_field_mask
);
276 q
= p
+ utun_crypto_framer_state_dtls_out(cur_framer
).len_field_offset
;
279 // fill a "sequence" field... if configured
280 if (utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field_mask
) {
281 u_int32_t tmp
= (utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field
& utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field_mask
);
282 u_int8_t
*q
= p
+ utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field_offset
;
284 tmp
&= (utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field
& utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field_mask
);
285 q
= p
+ utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field_offset
;
287 utun_crypto_framer_state_dtls_out(cur_framer
).sequence_field
++;
293 utun_ctl_init_crypto_dtls (void)
295 if (OSCompareAndSwap(FALSE
, TRUE
, &dtls_ctl_mutex_inited
)) {
296 if (!dtls_ctl_mutex_grp_attr
)
297 dtls_ctl_mutex_grp_attr
= lck_grp_attr_alloc_init();
298 if (!dtls_ctl_mutex_grp
)
299 dtls_ctl_mutex_grp
= lck_grp_alloc_init("utun-crypto", dtls_ctl_mutex_grp_attr
);
300 if (!dtls_ctl_mutex_attr
)
301 dtls_ctl_mutex_attr
= lck_attr_alloc_init();
303 lck_mtx_init(&dtls_ctl_mutex
, dtls_ctl_mutex_grp
, dtls_ctl_mutex_attr
);
308 * Summary: registers the DTLS Kext routines with UTUN... so that UTUN can make calls into DTLS
311 utun_ctl_register_dtls (utun_crypto_kpi_reg_t
*reg
)
313 //printf("%s: entering\n", __FUNCTION__);
314 if (!reg
) return EINVAL
;
316 //printf("%s: type %d\n", __FUNCTION__, reg->crypto_kpi_type);
317 if (reg
->crypto_kpi_type
!= UTUN_CRYPTO_TYPE_DTLS
) {
321 if (!reg
->crypto_kpi_connect
) {
325 if (!reg
->crypto_kpi_send
) {
329 // printf("%s: pre-value of dtls_kpi_callbacks_inited %lu\n", __FUNCTION__,
330 // dtls_kpi_callbacks_inited);
331 if (OSCompareAndSwap(FALSE
, TRUE
, &dtls_kpi_callbacks_inited
)) {
332 dtls_kpi_flags
= reg
->crypto_kpi_flags
;
333 dtls_kpi_connect
= reg
->crypto_kpi_connect
;
334 dtls_kpi_send
= reg
->crypto_kpi_send
;
336 //printf("%s: post-value of dtls_kpi_callbacks_inited %lu\n", __FUNCTION__,
337 // dtls_kpi_callbacks_inited);
342 * Summary: enables dtls crypto info for the specified utun. dtls ref is passed into args.
345 utun_ctl_enable_crypto_dtls(struct utun_pcb
*pcb
, utun_crypto_args_t
*args
)
347 utun_crypto_ctx_t
*crypto_ctx
;
349 lck_mtx_lock(&dtls_ctl_mutex
);
351 //printf("%s: entering, flags %x, kpi-handle %x, kpi-ref %p, kpi-refcnt %d\n", __FUNCTION__, pcb->utun_flags, crypto_ctx->kpi_handle, crypto_ctx->kpi_ref, crypto_ctx->kpi_refcnt);
353 crypto_ctx
= &pcb
->utun_crypto_ctx
[UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_IN
)];
354 if (crypto_ctx
->valid
) {
355 printf("%s: dtls already enabled (prev %u, now %u)\n", __FUNCTION__
,
356 crypto_ctx
->kpi_handle
, args
->u
.dtls_v1
.kpi_handle
);
357 lck_mtx_unlock(&dtls_ctl_mutex
);
361 crypto_ctx
= &pcb
->utun_crypto_ctx
[UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_OUT
)];
362 if (!crypto_ctx
->valid
) {
363 crypto_ctx
->kpi_handle
= args
->u
.dtls_v1
.kpi_handle
;
365 printf("%s: dtls already enabled for egress (prev %u, now %u)\n", __FUNCTION__
,
366 crypto_ctx
->kpi_handle
, args
->u
.dtls_v1
.kpi_handle
);
367 lck_mtx_unlock(&dtls_ctl_mutex
);
370 // crypto_ctx->valid will be set in utun_ctl_enable_crypto
371 lck_mtx_unlock(&dtls_ctl_mutex
);
376 * Summary: disables dtls crypto info for the specified utun.
379 utun_ctl_disable_crypto_dtls(struct utun_pcb
*pcb
)
381 utun_crypto_ctx_t
*crypto_ctx
;
383 lck_mtx_lock(&dtls_ctl_mutex
);
385 //printf("%s: entering, flags %x, kpi-handle %d, kpi-ref %p, kpi-refcnt %d\n", __FUNCTION__, pcb->utun_flags, crypto_ctx->kpi_handle, crypto_ctx->kpi_ref, crypto_ctx->kpi_refcnt);
387 crypto_ctx
= &pcb
->utun_crypto_ctx
[UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_IN
)];
388 if (crypto_ctx
->valid
&&
389 crypto_ctx
->type
== UTUN_CRYPTO_TYPE_DTLS
) {
390 utun_ctl_clr_dtls_all_framers(crypto_ctx
);
393 crypto_ctx
= &pcb
->utun_crypto_ctx
[UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_OUT
)];
394 if (!crypto_ctx
->valid
||
395 crypto_ctx
->type
!= UTUN_CRYPTO_TYPE_DTLS
) {
396 lck_mtx_unlock(&dtls_ctl_mutex
);
399 if (crypto_ctx
->kpi_ref
) {
400 if (dtls_kpi_connect
) {
401 (void)dtls_kpi_connect(crypto_ctx
->kpi_handle
, NULL
);
402 if (--crypto_ctx
->kpi_refcnt
== 0) {
403 crypto_ctx
->kpi_ref
= (__typeof__(crypto_ctx
->kpi_ref
))NULL
;
404 crypto_ctx
->kpi_handle
= UTUN_CRYPTO_DTLS_HANDLE_INVALID
;
406 // printf("%s: ### dtls_kpi_refcnt %d not yet zero\n",
407 // __FUNCTION__, crypto_ctx->kpi_refcnt);
410 printf("%s: ### dtls_ctl_connect unavailable\n", __FUNCTION__
);
411 lck_mtx_unlock(&dtls_ctl_mutex
);
415 if (crypto_ctx
->kpi_handle
< 0) {
416 printf("%s: dtls already disabled\n", __FUNCTION__
);
417 lck_mtx_unlock(&dtls_ctl_mutex
);
420 crypto_ctx
->kpi_handle
= UTUN_CRYPTO_DTLS_HANDLE_INVALID
;
422 utun_ctl_clr_dtls_all_framers(crypto_ctx
);
423 lck_mtx_unlock(&dtls_ctl_mutex
);
427 static utun_crypto_framer_t
*
428 utun_ctl_get_dtls_in_framer (utun_crypto_framer_t
*first_framer
,
429 u_int8_t
*in_pattern
,
431 u_int8_t
*in_pattern_mask
,
432 int in_pattern_mask_len
)
434 utun_crypto_framer_t
*cur_framer
;
436 // check framer->u.listhead for duplicates;
437 for (cur_framer
= first_framer
;
439 cur_framer
= (__typeof__(cur_framer
))LIST_NEXT(cur_framer
, framer_chain
)) {
440 // TOFIX: use in_pattern_masked
441 if (utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_len
== in_pattern_len
&&
442 memcmp(utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern
,
444 in_pattern_len
) == 0 &&
445 utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_len
== in_pattern_mask_len
&&
446 memcmp(utun_crypto_framer_state_dtls_in(cur_framer
).in_pattern_mask
,
448 in_pattern_mask_len
) == 0) {
458 utun_ctl_config_crypto_dtls_framer (utun_crypto_ctx_t
*crypto_ctx
,
459 utun_crypto_framer_args_t
*args
)
461 utun_crypto_framer_t
*framer
, *new_framer
= NULL
, *dup_framer
;
463 if (args
->ver
!= UTUN_CRYPTO_DTLS_VER_1
) {
466 if (!args
->type
|| args
->type
>= UTUN_CRYPTO_INNER_TYPE_MAX
) {
470 lck_mtx_lock(&dtls_ctl_mutex
);
472 if (args
->dir
== UTUN_CRYPTO_DIR_IN
) {
473 // Input framer (for tunnel hdr detection and decapsulation). there can be several pattern that identify data (vs. control) packets.
475 // First, the args need to be verified for errors/inconsistencies
476 // pattern and mask have to be configured
477 if (!utun_crypto_framer_args_dtls_in(args
).in_pattern_len
||
478 !utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
) {
479 lck_mtx_unlock(&dtls_ctl_mutex
);
480 printf("%s: invalid dtls in-pattern %d mask %d\n", __FUNCTION__
,
481 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
,
482 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
);
485 // pattern and mask lengths have to match
486 if (utun_crypto_framer_args_dtls_in(args
).in_pattern_len
!= utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
) {
487 lck_mtx_unlock(&dtls_ctl_mutex
);
488 printf("%s: inconsistent dtls in-pattern %d mask %d\n",__FUNCTION__
,
489 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
,
490 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
);
493 // check for len inconsistencies
494 if ((u_int32_t
)utun_crypto_framer_args_dtls_in(args
).in_pattern_len
+ (u_int32_t
)utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
!= args
->varargs_buflen
) {
495 lck_mtx_unlock(&dtls_ctl_mutex
);
496 printf("%s: inconsistent dtls in-pattern %d mask %d, total %d\n",__FUNCTION__
,
497 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
,
498 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
,
499 args
->varargs_buflen
);
502 // utun_crypto_framer_args_dtls_in(args).in_pattern should not be all zeros
503 if (is_pattern_all_zeroes(&args
->varargs_buf
[0],
504 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
)) {
505 lck_mtx_unlock(&dtls_ctl_mutex
);
506 printf("%s: in-pattern is all zeros, len %d\n",__FUNCTION__
,
507 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
);
510 // utun_crypto_framer_args_dtls_in(args).in_pattern_mask should not be all zeros
511 if (is_pattern_all_zeroes(&args
->varargs_buf
[utun_crypto_framer_args_dtls_in(args
).in_pattern_len
],
512 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
)) {
513 lck_mtx_unlock(&dtls_ctl_mutex
);
514 printf("%s: in-pattern-mask is all zeros, len %d\n",__FUNCTION__
,
515 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
);
518 // utun_crypto_framer_args_dtls_in(args).in_pattern & utun_crypto_framer_args_dtls_in(args).in_pattern_mask should not be zeros
519 if (is_pattern_masked_all_zeroes(&args
->varargs_buf
[0],
520 &args
->varargs_buf
[utun_crypto_framer_args_dtls_in(args
).in_pattern_len
],
521 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
)) {
522 lck_mtx_unlock(&dtls_ctl_mutex
);
523 printf("%s: in-pattern-masked is all zeros, len %d\n",__FUNCTION__
,
524 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
);
528 // Secondly, we need to be careful about existing framer configs
529 if (!(framer
= utun_ctl_get_first_framer(crypto_ctx
, args
->inner_type
))) {
530 // no framers configured
531 if (!(framer
= utun_alloc(sizeof(*framer
)))) {
532 lck_mtx_unlock(&dtls_ctl_mutex
);
535 bzero(framer
, sizeof(*framer
));
536 // fall through to fill-in the 1st framer
538 // at least one framer configured... check framer->u.listhead for duplicates;
539 if ((dup_framer
= utun_ctl_get_dtls_in_framer(framer
/* could be a list */,
540 &args
->varargs_buf
[0],
541 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
,
542 &args
->varargs_buf
[utun_crypto_framer_args_dtls_in(args
).in_pattern_len
],
543 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
))) {
545 lck_mtx_unlock(&dtls_ctl_mutex
);
546 printf("%s: ignoring duplicate framer for type %d\n",__FUNCTION__
,
551 if (!(new_framer
= utun_alloc(sizeof(*new_framer
)))) {
552 lck_mtx_unlock(&dtls_ctl_mutex
);
555 bzero(new_framer
, sizeof(*new_framer
));
557 // fall through to fill-in additional framer
559 LIST_INSERT_HEAD(utun_get_framer_listhead(crypto_ctx
, args
->inner_type
),
563 framer
->inner_type
= args
->inner_type
;
564 framer
->inner_protocol_family
= utun_crypto_framer_inner_type_to_protocol_family(args
->inner_type
);
565 // allocate and fill the pattern
566 if (!(utun_crypto_framer_state_dtls_in(framer
).in_pattern
= utun_alloc(utun_crypto_framer_args_dtls_in(args
).in_pattern_len
))) {
567 utun_ctl_clr_dtls_framer(framer
);
568 lck_mtx_unlock(&dtls_ctl_mutex
);
571 memcpy(utun_crypto_framer_state_dtls_in(framer
).in_pattern
,
572 &args
->varargs_buf
[0],
573 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
);
574 utun_crypto_framer_state_dtls_in(framer
).in_pattern_len
= utun_crypto_framer_args_dtls_in(args
).in_pattern_len
;
576 // allocate and fill the pattern-mask
577 if (!(utun_crypto_framer_state_dtls_in(framer
).in_pattern_mask
= utun_alloc(utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
))) {
578 utun_ctl_clr_dtls_framer(framer
);
579 lck_mtx_unlock(&dtls_ctl_mutex
);
582 memcpy(utun_crypto_framer_state_dtls_in(framer
).in_pattern_mask
,
583 &args
->varargs_buf
[utun_crypto_framer_args_dtls_in(args
).in_pattern_len
],
584 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
);
585 utun_crypto_framer_state_dtls_in(framer
).in_data_offset
= utun_crypto_framer_args_dtls_in(args
).in_data_offset
;
587 if (!(utun_crypto_framer_state_dtls_in(framer
).in_pattern_masked
= utun_alloc(utun_crypto_framer_args_dtls_in(args
).in_pattern_len
))) {
588 utun_ctl_clr_dtls_framer(framer
);
589 lck_mtx_unlock(&dtls_ctl_mutex
);
592 utun_ctl_calc_dtls_framer_pattern_and_mask(utun_crypto_framer_state_dtls_in(framer
).in_pattern_masked
,
593 utun_crypto_framer_state_dtls_in(framer
).in_pattern
,
594 utun_crypto_framer_state_dtls_in(framer
).in_pattern_mask
,
595 utun_crypto_framer_state_dtls_in(framer
).in_pattern_len
);
596 // TOFIX: switch to BPF
597 crypto_ctx
->num_framers
++;
599 // Output Framer (for tunnel hdr encapsulation)... there can only be one for each type of traffic (see caller of this function)
601 // pattern and mask have to be configured
602 if (!utun_crypto_framer_args_dtls_out(args
).out_pattern_len
) {
603 lck_mtx_unlock(&dtls_ctl_mutex
);
604 printf("%s: invalid output framer, len %d\n",__FUNCTION__
,
605 utun_crypto_framer_args_dtls_out(args
).out_pattern_len
);
608 // utun_crypto_framer_args_dtls_out(args).out_pattern should not be all zeros;
609 if (is_pattern_all_zeroes(&args
->varargs_buf
[0],
610 utun_crypto_framer_args_dtls_out(args
).out_pattern_len
)) {
611 lck_mtx_unlock(&dtls_ctl_mutex
);
612 printf("%s: zeroed output framer, len %d\n",__FUNCTION__
,
613 utun_crypto_framer_args_dtls_out(args
).out_pattern_len
);
617 // can't have the offset/extra configured while the mask is cleared
618 if ((utun_crypto_framer_args_dtls_out(args
).len_field_offset
|| utun_crypto_framer_args_dtls_out(args
).len_field_extra
) && !utun_crypto_framer_args_dtls_out(args
).len_field_mask
) {
619 lck_mtx_unlock(&dtls_ctl_mutex
);
620 printf("%s: output framer has invalid length-field %d,%d,%x\n",__FUNCTION__
,
621 (int)utun_crypto_framer_args_dtls_out(args
).len_field_offset
,
622 (int)utun_crypto_framer_args_dtls_out(args
).len_field_extra
,
623 utun_crypto_framer_args_dtls_out(args
).len_field_mask
);
626 // any length field should be within the bounds of the out-pattern
627 if (utun_crypto_framer_args_dtls_out(args
).len_field_offset
>= utun_crypto_framer_args_dtls_out(args
).out_pattern_len
) {
628 lck_mtx_unlock(&dtls_ctl_mutex
);
632 // can't have the offset configured while the mask is cleared
633 if ((utun_crypto_framer_args_dtls_out(args
).sequence_field
|| utun_crypto_framer_args_dtls_out(args
).sequence_field_offset
) && !utun_crypto_framer_args_dtls_out(args
).sequence_field_mask
) {
634 lck_mtx_unlock(&dtls_ctl_mutex
);
635 printf("%s: output framer has invalid sequence-field %d,%d,%x\n",__FUNCTION__
,
636 (int)utun_crypto_framer_args_dtls_out(args
).sequence_field
,
637 (int)utun_crypto_framer_args_dtls_out(args
).sequence_field_offset
,
638 utun_crypto_framer_args_dtls_out(args
).sequence_field_mask
);
641 // any sequence field should be within the bounds of the out-pattern
642 if (utun_crypto_framer_args_dtls_out(args
).sequence_field_offset
>= utun_crypto_framer_args_dtls_out(args
).out_pattern_len
) {
643 lck_mtx_unlock(&dtls_ctl_mutex
);
647 // check for len inconsistencies
648 if ((u_int32_t
)utun_crypto_framer_args_dtls_out(args
).out_pattern_len
!= args
->varargs_buflen
) {
649 lck_mtx_unlock(&dtls_ctl_mutex
);
653 if (!(framer
= utun_ctl_get_first_framer(crypto_ctx
, args
->inner_type
))) {
654 if (!(framer
= utun_alloc(sizeof(*framer
)))) {
655 lck_mtx_unlock(&dtls_ctl_mutex
);
658 bzero(framer
, sizeof(*framer
));
659 LIST_INSERT_HEAD(utun_get_framer_listhead(crypto_ctx
, args
->inner_type
),
662 // fall through to fill-in 1st framer
664 // only one outbound framer may be configured.. is it a dup?
665 if (framer
->inner_type
== args
->inner_type
&&
666 utun_crypto_framer_state_dtls_out(framer
).out_pattern_len
== utun_crypto_framer_args_dtls_out(args
).out_pattern_len
&&
667 utun_crypto_framer_state_dtls_out(framer
).out_pattern
&&
668 memcmp(utun_crypto_framer_state_dtls_out(framer
).out_pattern
,
669 &args
->varargs_buf
[0],
670 utun_crypto_framer_args_dtls_out(args
).out_pattern_len
) == 0) {
672 lck_mtx_unlock(&dtls_ctl_mutex
);
676 // overwrite the previous one
677 if (utun_crypto_framer_state_dtls_out(framer
).out_pattern
) {
678 utun_free(utun_crypto_framer_state_dtls_out(framer
).out_pattern
);
680 // fall through to fill-in additional framer
683 framer
->inner_type
= args
->inner_type
;
684 framer
->inner_protocol_family
= utun_crypto_framer_inner_type_to_protocol_family(args
->inner_type
);
686 // alloc and fill in the out-pattern
687 if (!(utun_crypto_framer_state_dtls_out(framer
).out_pattern
= utun_alloc(utun_crypto_framer_args_dtls_out(args
).out_pattern_len
))) {
688 utun_ctl_clr_dtls_framer(framer
);
689 lck_mtx_unlock(&dtls_ctl_mutex
);
692 memcpy(utun_crypto_framer_state_dtls_out(framer
).out_pattern
,
693 &args
->varargs_buf
[0],
694 utun_crypto_framer_args_dtls_out(args
).out_pattern_len
);
695 utun_crypto_framer_state_dtls_out(framer
).out_pattern_len
= utun_crypto_framer_args_dtls_out(args
).out_pattern_len
;
697 utun_crypto_framer_state_dtls_out(framer
).len_field_mask
= utun_crypto_framer_args_dtls_out(args
).len_field_mask
;
698 utun_crypto_framer_state_dtls_out(framer
).len_field_offset
= utun_crypto_framer_args_dtls_out(args
).len_field_offset
;
699 utun_crypto_framer_state_dtls_out(framer
).len_field_extra
= utun_crypto_framer_args_dtls_out(args
).len_field_extra
;
700 utun_crypto_framer_state_dtls_out(framer
).sequence_field_initval
= utun_crypto_framer_args_dtls_out(args
).sequence_field
;
701 utun_crypto_framer_state_dtls_out(framer
).sequence_field_mask
= utun_crypto_framer_args_dtls_out(args
).sequence_field_mask
;
702 utun_crypto_framer_state_dtls_out(framer
).sequence_field_offset
= utun_crypto_framer_args_dtls_out(args
).sequence_field_offset
;
703 crypto_ctx
->num_framers
= 1;
705 framer
->type
= args
->type
;
706 framer
->dir
= args
->dir
;
709 lck_mtx_unlock(&dtls_ctl_mutex
);
714 utun_ctl_unconfig_crypto_dtls_framer (utun_crypto_ctx_t
*crypto_ctx
,
715 utun_crypto_framer_args_t
*args
)
717 utun_crypto_framer_t
*framer
, *rem_framer
;
719 if (args
->ver
!= UTUN_CRYPTO_DTLS_VER_1
) {
722 if (!args
->type
|| args
->type
>= UTUN_CRYPTO_INNER_TYPE_MAX
) {
726 lck_mtx_lock(&dtls_ctl_mutex
);
728 if (args
->dir
== UTUN_CRYPTO_DIR_IN
) {
729 if (!utun_crypto_framer_args_dtls_in(args
).in_pattern_len
) {
730 // no pattern means... clear all
731 utun_ctl_clr_dtls_framers(utun_ctl_get_first_framer(crypto_ctx
, args
->inner_type
));
732 lck_mtx_unlock(&dtls_ctl_mutex
);
736 // when both specified, pattern and mask lengths have to match
737 if (utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
&&
738 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
!= utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
) {
739 lck_mtx_unlock(&dtls_ctl_mutex
);
742 // check for len inconsistencies
743 if ((u_int32_t
)utun_crypto_framer_args_dtls_in(args
).in_pattern_len
+ (u_int32_t
)utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
!= args
->varargs_buflen
) {
744 lck_mtx_unlock(&dtls_ctl_mutex
);
747 // utun_crypto_framer_args_dtls_in(args).in_pattern should not be all zeros
748 if (is_pattern_all_zeroes(&args
->varargs_buf
[0],
749 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
)) {
750 lck_mtx_unlock(&dtls_ctl_mutex
);
753 // when specified, utun_crypto_framer_args_dtls_in(args).in_pattern_mask should not be all zeros
754 if (utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
&&
755 is_pattern_all_zeroes(&args
->varargs_buf
[utun_crypto_framer_args_dtls_in(args
).in_pattern_len
],
756 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
)) {
757 lck_mtx_unlock(&dtls_ctl_mutex
);
760 // utun_crypto_framer_args_dtls_in(args).in_pattern & utun_crypto_framer_args_dtls_in(args).in_pattern_mask should not be zeros
761 if (is_pattern_masked_all_zeroes(&args
->varargs_buf
[0],
762 &args
->varargs_buf
[utun_crypto_framer_args_dtls_in(args
).in_pattern_len
],
763 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
)) {
764 lck_mtx_unlock(&dtls_ctl_mutex
);
768 if ((u_int32_t
)utun_crypto_framer_args_dtls_in(args
).in_pattern_len
+ (u_int32_t
)utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
!= args
->varargs_buflen
) {
769 lck_mtx_unlock(&dtls_ctl_mutex
);
773 if (!(framer
= utun_ctl_get_first_framer(crypto_ctx
, args
->inner_type
))) {
775 printf("%s: no framers configured\n", __FUNCTION__
);
776 lck_mtx_unlock(&dtls_ctl_mutex
);
779 if ((rem_framer
= utun_ctl_get_dtls_in_framer(framer
,
780 &args
->varargs_buf
[0],
781 utun_crypto_framer_args_dtls_in(args
).in_pattern_len
,
782 &args
->varargs_buf
[utun_crypto_framer_args_dtls_in(args
).in_pattern_len
],
783 utun_crypto_framer_args_dtls_in(args
).in_pattern_mask_len
))) {
784 utun_ctl_clr_dtls_framer(rem_framer
);
785 if (crypto_ctx
->num_framers
) crypto_ctx
->num_framers
--;
787 printf("%s: no matching ingress framer\n", __FUNCTION__
);
789 lck_mtx_unlock(&dtls_ctl_mutex
);
793 framer
= utun_ctl_get_first_framer(crypto_ctx
, args
->inner_type
);
794 // overwrite the previous one
796 if (framer
->inner_type
!= args
->inner_type
||
797 (utun_crypto_framer_args_dtls_out(args
).out_pattern_len
&&
798 utun_crypto_framer_state_dtls_out(framer
).out_pattern_len
!= utun_crypto_framer_args_dtls_out(args
).out_pattern_len
) ||
799 (utun_crypto_framer_args_dtls_out(args
).out_pattern_len
&&
800 memcmp(utun_crypto_framer_state_dtls_out(framer
).out_pattern
,
801 &args
->varargs_buf
[0],
802 utun_crypto_framer_args_dtls_out(args
).out_pattern_len
))) {
803 printf("%s: no matching egress framer\n", __FUNCTION__
);
804 lck_mtx_unlock(&dtls_ctl_mutex
);
807 utun_ctl_clr_dtls_framer(framer
);
808 if (crypto_ctx
->num_framers
) crypto_ctx
->num_framers
--;
812 lck_mtx_unlock(&dtls_ctl_mutex
);
817 * Summary: enables handling of data traffic
820 utun_ctl_start_datatraffic_crypto_dtls(struct utun_pcb
*pcb
)
822 utun_crypto_ctx_t
*crypto_ctx
;
824 lck_mtx_lock(&dtls_ctl_mutex
);
826 //printf("%s: entering, flags %x, kpi-handle %d, kpi-ref %p, kpi-refcnt %d\n", __FUNCTION__, pcb->utun_flags, crypto_ctx->kpi_handle, crypto_ctx->kpi_ref, crypto_ctx->kpi_refcnt);
828 crypto_ctx
= &pcb
->utun_crypto_ctx
[UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_OUT
)];
830 if (crypto_ctx
->kpi_handle
< 0) {
831 printf("%s: dtls disabled\n", __FUNCTION__
);
832 lck_mtx_unlock(&dtls_ctl_mutex
);
836 if (!crypto_ctx
->kpi_ref
) {
837 if (dtls_kpi_connect
) {
838 crypto_ctx
->kpi_ref
= dtls_kpi_connect(crypto_ctx
->kpi_handle
, pcb
);
839 if (!crypto_ctx
->kpi_ref
) {
840 printf("%s: ### dtls_kpi_connect failed\n", __FUNCTION__
);
841 lck_mtx_unlock(&dtls_ctl_mutex
);
844 crypto_ctx
->kpi_refcnt
++;
846 printf("%s: ### dtls_kpi_connect unavailable\n", __FUNCTION__
);
847 lck_mtx_unlock(&dtls_ctl_mutex
);
851 printf("%s: dtls already stitched\n", __FUNCTION__
);
852 lck_mtx_unlock(&dtls_ctl_mutex
);
855 utun_ctl_restart_dtls_all_framers(crypto_ctx
); // for dynamic egress hdrs
857 //printf("%s: leaving, flags %x, kpi-handle %d, kpi-ref %p, kpi-refcnt %d\n", __FUNCTION__, pcb->utun_flags, crypto_ctx->kpi_handle, crypto_ctx->kpi_ref, crypto_ctx->kpi_refcnt);
858 lck_mtx_unlock(&dtls_ctl_mutex
);
863 * Summary: disables handling of data traffic
866 utun_ctl_stop_datatraffic_crypto_dtls(struct utun_pcb
*pcb
)
868 utun_crypto_ctx_t
*crypto_ctx
;
870 lck_mtx_lock(&dtls_ctl_mutex
);
872 //printf("%s: entering, flags %x, kpi-ref %p, kpi-refcnt %d\n", __FUNCTION__, pcb->utun_flags, crypto_ctx->kpi_ref, crypto_ctx->kpi_refcnt);
874 crypto_ctx
= &pcb
->utun_crypto_ctx
[UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_OUT
)];
876 if (crypto_ctx
->kpi_ref
) {
877 if (dtls_kpi_connect
) {
878 (void)dtls_kpi_connect(crypto_ctx
->kpi_handle
, NULL
);
879 if (--crypto_ctx
->kpi_refcnt
== 0) {
880 crypto_ctx
->kpi_ref
= (__typeof__(crypto_ctx
->kpi_ref
))NULL
;
881 crypto_ctx
->kpi_handle
= UTUN_CRYPTO_DTLS_HANDLE_INVALID
;
883 // printf("%s: ### dtls_kpi_refcnt %d not yet zero\n",
884 // __FUNCTION__, crypto_ctx->kpi_refcnt);
887 printf("%s: dtls_kpi_connect unavailable\n", __FUNCTION__
);
888 lck_mtx_unlock(&dtls_ctl_mutex
);
892 printf("%s: dtls already not-stitched\n", __FUNCTION__
);
893 lck_mtx_unlock(&dtls_ctl_mutex
);
896 lck_mtx_unlock(&dtls_ctl_mutex
);
900 #define utun_pkt_dtls_prepend_proto(pkt, pf) do { \
901 if (mbuf_prepend(pkt, sizeof(protocol_family_t), MBUF_DONTWAIT) != 0) { \
902 printf("%s - ifnet_output prepend failed\n", __FUNCTION__); \
903 lck_mtx_unlock(&dtls_ctl_mutex); \
906 *(protocol_family_t *)mbuf_data(*pkt) = pf; \
909 #define utun_pkt_dtls_puntup(pcb, pkt, errstr, rc) do { \
910 *(protocol_family_t *)mbuf_data(*pkt) = htonl(*(protocol_family_t *)mbuf_data(*pkt)); \
911 rc = ctl_enqueuembuf(pcb->utun_ctlref, pcb->utun_unit, *pkt, CTL_DATA_EOR); \
913 printf("%s: - ctl_enqueuembuf failed (rc %d) for %s:\n", __FUNCTION__, rc, (char *)errstr); \
915 ifnet_stat_increment_out(pcb->utun_ifp, 0, 0, 1); \
916 lck_mtx_unlock(&dtls_ctl_mutex); \
923 utun_pkt_dtls_output(struct utun_pcb
*pcb
, mbuf_t
*pkt
)
925 errno_t rc
= ENETUNREACH
;
927 utun_crypto_ctx_t
*crypto_ctx
;
928 protocol_family_t proto
;
930 //printf("%s: entering, flags %x, ifp %p\n", __FUNCTION__, pcb->utun_flags, pcb->utun_ifp);
932 if (!(pcb
->utun_flags
& UTUN_FLAGS_CRYPTO
)) {
933 printf("%s - crypto disabled\n", __FUNCTION__
);
937 if (!pcb
->utun_ifp
) {
938 printf("%s - utun ifp cleared\n", __FUNCTION__
);
942 proto
= *(mtod(*pkt
, protocol_family_t
*));
944 lck_mtx_lock(&dtls_ctl_mutex
);
946 len
= mbuf_pkthdr_len(*pkt
);
948 crypto_ctx
= &pcb
->utun_crypto_ctx
[UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_OUT
)];
950 //printf("%s: entering, kpi-handle %d, kpi-ref %p, kpi-refcnt %d\n", __FUNCTION__, crypto_ctx->kpi_handle, crypto_ctx->kpi_ref, crypto_ctx->kpi_refcnt);
952 if (dtls_kpi_send
&& (crypto_ctx
->kpi_handle
>= 0) && crypto_ctx
->kpi_ref
) {
953 m_adj(*pkt
, sizeof(protocol_family_t
));
955 if (!(rc
= utun_pkt_dtls_output_frame_encapsulate(crypto_ctx
, pkt
, proto
))) {
956 rc
= dtls_kpi_send(crypto_ctx
->kpi_ref
, pkt
);
958 printf("%s: DTLS failed to send pkt %d\n", __FUNCTION__
, rc
);
959 // <rdar://problem/11385397>
960 // dtls_kpi_send (by way of so_inject_data_out) frees mbuf during certain error cases,
961 ifnet_stat_increment_out(pcb
->utun_ifp
, 0, 0, 1); // increment errors
962 lck_mtx_unlock(&dtls_ctl_mutex
);
963 return 0; // and drop packet
965 } else if (rc
== EINVAL
) {
966 // unsupported proto... fall through and punt (but 1st undo the protocol strip)
967 utun_pkt_dtls_prepend_proto(pkt
, proto
);
968 utun_pkt_dtls_puntup(pcb
, pkt
, (char *)"unsupported proto", rc
);
970 // mbuf_prepend failure... mbuf will be already freed
971 printf("%s: failed to encrypsulate and send pkt %d\n", __FUNCTION__
,rc
);
972 ifnet_stat_increment_out(pcb
->utun_ifp
, 0, 0, 1); // increment errors
973 lck_mtx_unlock(&dtls_ctl_mutex
);
974 return 0; // and drop packet
977 utun_pkt_dtls_puntup(pcb
, pkt
, (char *)"slowpath", rc
);
981 ifnet_stat_increment_out(pcb
->utun_ifp
, 1, len
, 0);
983 lck_mtx_unlock(&dtls_ctl_mutex
);
988 utun_pkt_dtls_input(struct utun_pcb
*pcb
, mbuf_t
*pkt
, __unused protocol_family_t family
)
990 utun_crypto_ctx_t
*crypto_ctx
;
993 //printf("%s: got pkt %d\n", __FUNCTION__,family);
994 if (!(pcb
->utun_flags
& UTUN_FLAGS_CRYPTO
)) {
995 printf("%s - crypto disabled\n", __FUNCTION__
);
999 if (!pcb
->utun_ifp
) {
1000 printf("%s - utun ifp cleared\n", __FUNCTION__
);
1004 lck_mtx_lock(&dtls_ctl_mutex
);
1007 * make sure that family matches what the UTUN was configured for (punt those that don't... along with all that fail to match the data pattern.
1009 crypto_ctx
= &pcb
->utun_crypto_ctx
[UTUN_CRYPTO_DIR_TO_IDX(UTUN_CRYPTO_DIR_IN
)];
1010 if (crypto_ctx
->num_framers
&&
1011 !utun_pkt_dtls_input_frame_is_data(crypto_ctx
, pkt
, AF_INET
, &striplen
) &&
1012 !utun_pkt_dtls_input_frame_is_data(crypto_ctx
, pkt
, AF_INET6
, &striplen
)) {
1013 // control or unknown traffic, so punt up to the plugin
1016 utun_pkt_dtls_prepend_proto(pkt
, family
);
1017 *(protocol_family_t
*)mbuf_data(*pkt
) = htonl(*(protocol_family_t
*)mbuf_data(*pkt
));
1018 rc
= ctl_enqueuembuf(pcb
->utun_ctlref
, pcb
->utun_unit
, *pkt
, CTL_DATA_EOR
);
1021 printf("%s: - ctl_enqueuembuf failed: %d\n", __FUNCTION__
, rc
);
1023 lck_mtx_unlock(&dtls_ctl_mutex
);
1026 printf("%s: - ctl_enqueuembuf punted a packet up to UTUN ctrl sock: %d\n", __FUNCTION__
, rc
);
1027 ifnet_stat_increment_in(pcb
->utun_ifp
, 1, mbuf_pkthdr_len(*pkt
), 0);
1030 lck_mtx_unlock(&dtls_ctl_mutex
);
1034 //printf("%s: - about to strip tunneled hdr of len %d\n", __FUNCTION__, striplen);
1035 m_adj(*pkt
, striplen
);
1038 utun_pkt_dtls_prepend_proto(pkt
, family
);
1040 ifnet_stat_increment_in(pcb
->utun_ifp
, 1, mbuf_pkthdr_len(*pkt
), 0);
1042 (void)utun_pkt_input(pcb
, *pkt
);
1043 lck_mtx_unlock(&dtls_ctl_mutex
);