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