1/* 2 * Copyright (c) 2013, 2014 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#ifndef _NET_NECP_H_ 30#define _NET_NECP_H_ 31 32#include <netinet/in.h> 33#include <sys/socket.h> 34 35/* 36 * Name registered by the ipsec kernel control 37 */ 38#define NECP_CONTROL_NAME "com.apple.net.necp_control" 39 40struct necp_packet_header { 41 u_int8_t packet_type; 42 u_int8_t flags; 43 u_int32_t message_id; 44}; 45#define NECP_PACKET_TYPE_POLICY_ADD 1 46#define NECP_PACKET_TYPE_POLICY_GET 2 47#define NECP_PACKET_TYPE_POLICY_DELETE 3 48#define NECP_PACKET_TYPE_POLICY_APPLY_ALL 4 49#define NECP_PACKET_TYPE_POLICY_LIST_ALL 5 50#define NECP_PACKET_TYPE_POLICY_DELETE_ALL 6 51#define NECP_PACKET_TYPE_SET_SESSION_PRIORITY 7 52#define NECP_PACKET_TYPE_LOCK_SESSION_TO_PROC 8 53#define NECP_PACKET_TYPE_REGISTER_SERVICE 9 54#define NECP_PACKET_TYPE_UNREGISTER_SERVICE 10 55 56#define NECP_PACKET_FLAGS_RESPONSE 0x01 // Used for acks, errors, and query responses 57 58#define NECP_TLV_NIL 0 59#define NECP_TLV_ERROR 1 // u_int32_t 60#define NECP_TLV_POLICY_ORDER 2 // u_int32_t 61#define NECP_TLV_POLICY_CONDITION 3 62#define NECP_TLV_POLICY_RESULT 4 63#define NECP_TLV_POLICY_ID 5 // u_int32_t 64#define NECP_TLV_SESSION_PRIORITY 6 // u_int32_t 65#define NECP_TLV_ATTRIBUTE_DOMAIN 7 // char[] 66#define NECP_TLV_ATTRIBUTE_ACCOUNT 8 // char[] 67#define NECP_TLV_SERVICE_UUID 9 // uuid_t 68 69#define NECP_POLICY_CONDITION_FLAGS_NEGATIVE 0x01 // Negative 70 71// Conditions 72#define NECP_POLICY_CONDITION_DEFAULT 0 // N/A, not valid with any other conditions 73// Socket/Application conditions 74#define NECP_POLICY_CONDITION_APPLICATION 1 // uuid_t, uses effective UUID when possible 75#define NECP_POLICY_CONDITION_REAL_APPLICATION 2 // uuid_t, never uses effective UUID. Only valid with NECP_POLICY_CONDITION_APPLICATION 76// Application-only Conditions 77#define NECP_POLICY_CONDITION_DOMAIN 3 // String, such as apple.com 78#define NECP_POLICY_CONDITION_ACCOUNT 4 // String 79// Socket/Application condition 80#define NECP_POLICY_CONDITION_ENTITLEMENT 5 // String 81#define NECP_POLICY_CONDITION_PID 6 // pid_t 82#define NECP_POLICY_CONDITION_UID 7 // uid_t 83#define NECP_POLICY_CONDITION_ALL_INTERFACES 8 // N/A 84#define NECP_POLICY_CONDITION_BOUND_INTERFACE 9 // String 85#define NECP_POLICY_CONDITION_TRAFFIC_CLASS 10 // necp_policy_condition_tc_range 86// Socket/IP conditions 87#define NECP_POLICY_CONDITION_IP_PROTOCOL 11 // u_int8_t 88#define NECP_POLICY_CONDITION_LOCAL_ADDR 12 // necp_policy_condition_addr 89#define NECP_POLICY_CONDITION_REMOTE_ADDR 13 // necp_policy_condition_addr 90#define NECP_POLICY_CONDITION_LOCAL_ADDR_RANGE 14 // necp_policy_condition_addr_range 91#define NECP_POLICY_CONDITION_REMOTE_ADDR_RANGE 15 // necp_policy_condition_addr_range 92 93// Results 94#define NECP_POLICY_RESULT_PASS 1 // N/A 95#define NECP_POLICY_RESULT_SKIP 2 // u_int32_t, policy order to skip to. 0 to skip all session policies. 96#define NECP_POLICY_RESULT_DROP 3 // N/A 97#define NECP_POLICY_RESULT_SOCKET_DIVERT 4 // u_int32_t, flow divert control unit 98#define NECP_POLICY_RESULT_SOCKET_FILTER 5 // u_int32_t, filter control unit 99#define NECP_POLICY_RESULT_IP_TUNNEL 6 // String, interface name 100#define NECP_POLICY_RESULT_IP_FILTER 7 // ? 101#define NECP_POLICY_RESULT_TRIGGER 8 // service uuid_t 102#define NECP_POLICY_RESULT_TRIGGER_IF_NEEDED 9 // service uuid_t 103#define NECP_POLICY_RESULT_TRIGGER_SCOPED 10 // service uuid_t 104#define NECP_POLICY_RESULT_NO_TRIGGER_SCOPED 11 // service uuid_t 105#define NECP_POLICY_RESULT_SOCKET_SCOPED 12 // String, interface name 106 107#define NECP_POLICY_RESULT_MAX NECP_POLICY_RESULT_SOCKET_SCOPED 108 109// Errors 110#define NECP_ERROR_INTERNAL 0 111#define NECP_ERROR_UNKNOWN_PACKET_TYPE 1 112#define NECP_ERROR_INVALID_TLV 2 113#define NECP_ERROR_POLICY_RESULT_INVALID 3 114#define NECP_ERROR_POLICY_CONDITIONS_INVALID 4 115#define NECP_ERROR_POLICY_ID_NOT_FOUND 5 116#define NECP_ERROR_INVALID_PROCESS 6 117 118// Modifiers 119#define NECP_MASK_USERSPACE_ONLY 0x80000000 // on filter_control_unit value 120 121struct necp_policy_condition_tc_range { 122 u_int32_t start_tc; 123 u_int32_t end_tc; 124} __attribute__((__packed__)); 125 126struct necp_policy_condition_addr { 127 u_int8_t prefix; 128 union { 129 struct sockaddr sa; 130 struct sockaddr_in sin; 131 struct sockaddr_in6 sin6; 132 } address; 133} __attribute__((__packed__)); 134 135struct necp_policy_condition_addr_range { 136 union { 137 struct sockaddr sa; 138 struct sockaddr_in sin; 139 struct sockaddr_in6 sin6; 140 } start_address; 141 union { 142 struct sockaddr sa; 143 struct sockaddr_in sin; 144 struct sockaddr_in6 sin6; 145 } end_address; 146} __attribute__((__packed__)); 147 148#define NECP_SESSION_PRIORITY_UNKNOWN 0 149#define NECP_SESSION_PRIORITY_CONTROL 1 150#define NECP_SESSION_PRIORITY_PRIVILEGED_TUNNEL 2 151#define NECP_SESSION_PRIORITY_HIGH 3 152#define NECP_SESSION_PRIORITY_DEFAULT 4 153#define NECP_SESSION_PRIORITY_LOW 5 154 155#define NECP_SESSION_NUM_PRIORITIES NECP_SESSION_PRIORITY_LOW 156 157typedef u_int32_t necp_policy_id; 158typedef u_int32_t necp_policy_order; 159 160typedef u_int32_t necp_kernel_policy_result; 161typedef u_int32_t necp_kernel_policy_filter; 162 163typedef union { 164 u_int tunnel_interface_index; 165 u_int scoped_interface_index; 166 u_int32_t flow_divert_control_unit; 167 u_int32_t filter_control_unit; 168} necp_kernel_policy_routing_result_parameter; 169 170#define NECP_SERVICE_FLAGS_REGISTERED 0x01 171struct necp_aggregate_result { 172 necp_kernel_policy_result routing_result; 173 necp_kernel_policy_routing_result_parameter routing_result_parameter; 174 necp_kernel_policy_filter filter_control_unit; 175 necp_kernel_policy_result service_action; 176 uuid_t service_uuid; 177 u_int32_t service_flags; 178 u_int32_t service_data; 179}; 180 181#ifdef BSD_KERNEL_PRIVATE 182#include <stdbool.h> 183#include <sys/socketvar.h> 184#include <sys/kern_control.h> 185#include <netinet/ip_var.h> 186#include <netinet6/ip6_var.h> 187 188#define NECPCTL_DROP_ALL_LEVEL 1 /* Drop all packets if no policy matches above this level */ 189#define NECPCTL_DEBUG 2 /* Log all kernel policy matches */ 190#define NECPCTL_PASS_LOOPBACK 3 /* Pass all loopback traffic */ 191#define NECPCTL_PASS_KEEPALIVES 4 /* Pass all kernel-generated keepalive traffic */ 192 193#define NECPCTL_NAMES { \ 194 { 0, 0 }, \ 195 { "drop_all_level", CTLTYPE_INT }, \ 196 { "debug", CTLTYPE_INT }, \ 197 { "pass_loopback", CTLTYPE_INT }, \ 198 { "pass_keepalives", CTLTYPE_INT }, \ 199} 200 201typedef u_int32_t necp_kernel_policy_id; 202#define NECP_KERNEL_POLICY_ID_NONE 0 203#define NECP_KERNEL_POLICY_ID_NO_MATCH 1 204#define NECP_KERNEL_POLICY_ID_FIRST_VALID 2 205 206typedef u_int32_t necp_app_id; 207 208#define NECP_KERNEL_POLICY_RESULT_NONE 0 209#define NECP_KERNEL_POLICY_RESULT_PASS NECP_POLICY_RESULT_PASS 210#define NECP_KERNEL_POLICY_RESULT_SKIP NECP_POLICY_RESULT_SKIP 211#define NECP_KERNEL_POLICY_RESULT_DROP NECP_POLICY_RESULT_DROP 212#define NECP_KERNEL_POLICY_RESULT_SOCKET_DIVERT NECP_POLICY_RESULT_SOCKET_DIVERT 213#define NECP_KERNEL_POLICY_RESULT_SOCKET_FILTER NECP_POLICY_RESULT_SOCKET_FILTER 214#define NECP_KERNEL_POLICY_RESULT_IP_TUNNEL NECP_POLICY_RESULT_IP_TUNNEL 215#define NECP_KERNEL_POLICY_RESULT_IP_FILTER NECP_POLICY_RESULT_IP_FILTER 216#define NECP_KERNEL_POLICY_RESULT_TRIGGER NECP_POLICY_RESULT_TRIGGER 217#define NECP_KERNEL_POLICY_RESULT_TRIGGER_IF_NEEDED NECP_POLICY_RESULT_TRIGGER_IF_NEEDED 218#define NECP_KERNEL_POLICY_RESULT_TRIGGER_SCOPED NECP_POLICY_RESULT_TRIGGER_SCOPED 219#define NECP_KERNEL_POLICY_RESULT_NO_TRIGGER_SCOPED NECP_POLICY_RESULT_NO_TRIGGER_SCOPED 220#define NECP_KERNEL_POLICY_RESULT_SOCKET_SCOPED NECP_POLICY_RESULT_SOCKET_SCOPED 221 222typedef struct { 223 u_int32_t identifier; 224 u_int32_t data; 225} necp_kernel_policy_service; 226 227typedef union { 228 u_int tunnel_interface_index; 229 u_int scoped_interface_index; 230 u_int32_t flow_divert_control_unit; 231 u_int32_t filter_control_unit; 232 u_int32_t skip_policy_order; 233 necp_kernel_policy_service service; 234} necp_kernel_policy_result_parameter; 235 236union necp_sockaddr_union { 237 struct sockaddr sa; 238 struct sockaddr_in sin; 239 struct sockaddr_in6 sin6; 240}; 241 242struct necp_kernel_socket_policy { 243 LIST_ENTRY(necp_kernel_socket_policy) chain; 244 necp_policy_id parent_policy_id; 245 necp_kernel_policy_id id; 246 necp_policy_order order; 247 u_int32_t session_order; 248 249 u_int32_t condition_mask; 250 u_int32_t condition_negated_mask; 251 necp_kernel_policy_id cond_policy_id; 252 u_int32_t cond_app_id; // Locally assigned ID value stored 253 u_int32_t cond_real_app_id; // Locally assigned ID value stored 254 u_int32_t cond_account_id; // Locally assigned ID value stored 255 char *cond_domain; // String 256 u_int8_t cond_domain_dot_count; // Number of dots in cond_domain 257 pid_t cond_pid; 258 uid_t cond_uid; 259 ifnet_t cond_bound_interface; // Matches specific binding only 260 struct necp_policy_condition_tc_range cond_traffic_class; // Matches traffic class in range 261 u_int16_t cond_protocol; // Matches IP protcol number 262 union necp_sockaddr_union cond_local_start; // Matches local IP address (or start) 263 union necp_sockaddr_union cond_local_end; // Matches IP address range 264 u_int8_t cond_local_prefix; // Defines subnet 265 union necp_sockaddr_union cond_remote_start; // Matches remote IP address (or start) 266 union necp_sockaddr_union cond_remote_end; // Matches IP address range 267 u_int8_t cond_remote_prefix; // Defines subnet 268 269 necp_kernel_policy_result result; 270 necp_kernel_policy_result_parameter result_parameter; 271}; 272 273struct necp_kernel_ip_output_policy { 274 LIST_ENTRY(necp_kernel_ip_output_policy) chain; 275 necp_policy_id parent_policy_id; 276 necp_kernel_policy_id id; 277 necp_policy_order suborder; 278 necp_policy_order order; 279 u_int32_t session_order; 280 281 u_int32_t condition_mask; 282 u_int32_t condition_negated_mask; 283 necp_kernel_policy_id cond_policy_id; 284 ifnet_t cond_bound_interface; // Matches specific binding only 285 u_int16_t cond_protocol; // Matches IP protcol number 286 union necp_sockaddr_union cond_local_start; // Matches local IP address (or start) 287 union necp_sockaddr_union cond_local_end; // Matches IP address range 288 u_int8_t cond_local_prefix; // Defines subnet 289 union necp_sockaddr_union cond_remote_start; // Matches remote IP address (or start) 290 union necp_sockaddr_union cond_remote_end; // Matches IP address range 291 u_int8_t cond_remote_prefix; // Defines subnet 292 u_int32_t cond_last_interface_index; 293 294 necp_kernel_policy_result result; 295 necp_kernel_policy_result_parameter result_parameter; 296}; 297 298#define MAX_KERNEL_SOCKET_POLICIES 1 299#define MAX_KERNEL_IP_OUTPUT_POLICIES 4 300struct necp_session_policy { 301 LIST_ENTRY(necp_session_policy) chain; 302 bool applied; // Applied into the kernel table 303 bool pending_deletion; // Waiting to be removed from kernel table 304 bool pending_update; // Policy has been modified since creation/last application 305 necp_policy_id id; 306 necp_policy_order order; 307 u_int8_t *result; 308 size_t result_size; 309 u_int8_t *conditions; // Array of conditions, each with a size_t length at start 310 size_t conditions_size; 311 312 uuid_t applied_app_uuid; 313 uuid_t applied_real_app_uuid; 314 char *applied_domain; 315 char *applied_account; 316 317 uuid_t applied_service_uuid; 318 319 necp_kernel_policy_id kernel_socket_policies[MAX_KERNEL_SOCKET_POLICIES]; 320 necp_kernel_policy_id kernel_ip_output_policies[MAX_KERNEL_IP_OUTPUT_POLICIES]; 321}; 322 323struct necp_aggregate_socket_result { 324 necp_kernel_policy_result result; 325 necp_kernel_policy_result_parameter result_parameter; 326 necp_kernel_policy_filter filter_control_unit; 327}; 328 329struct necp_inpcb_result { 330 char *application_layer_domain; 331 u_int32_t application_layer_account_id; 332 necp_kernel_policy_id policy_id; 333 int32_t policy_gencount; 334 u_int32_t flowhash; 335 struct necp_aggregate_socket_result results; 336}; 337 338errno_t necp_init(void); 339 340errno_t necp_set_socket_attributes(struct socket *so, struct sockopt *sopt); 341errno_t necp_get_socket_attributes(struct socket *so, struct sockopt *sopt); 342 343u_int32_t necp_socket_get_content_filter_control_unit(struct socket *so); 344 345bool necp_socket_should_use_flow_divert(struct inpcb *inp); 346u_int32_t necp_socket_get_flow_divert_control_unit(struct inpcb *inp); 347 348bool necp_socket_should_rescope(struct inpcb *inp); 349u_int necp_socket_get_rescope_if_index(struct inpcb *inp); 350 351bool necp_socket_is_allowed_to_send_recv(struct inpcb *inp, necp_kernel_policy_id *return_policy_id); 352bool necp_socket_is_allowed_to_send_recv_v4(struct inpcb *inp, u_int16_t local_port, u_int16_t remote_port, struct in_addr *local_addr, struct in_addr *remote_addr, ifnet_t interface, necp_kernel_policy_id *return_policy_id); 353bool necp_socket_is_allowed_to_send_recv_v6(struct inpcb *inp, u_int16_t local_port, u_int16_t remote_port, struct in6_addr *local_addr, struct in6_addr *remote_addr, ifnet_t interface, necp_kernel_policy_id *return_policy_id); 354int necp_mark_packet_from_socket(struct mbuf *packet, struct inpcb *inp, necp_kernel_policy_id policy_id); 355necp_kernel_policy_id necp_get_policy_id_from_packet(struct mbuf *packet); 356u_int32_t necp_get_last_interface_index_from_packet(struct mbuf *packet); 357 358necp_kernel_policy_id necp_socket_find_policy_match(struct inpcb *inp, struct sockaddr *override_local_addr, struct sockaddr *override_remote_addr, u_int32_t override_bound_interface); 359necp_kernel_policy_id necp_ip_output_find_policy_match(struct mbuf *packet, int flags, struct ip_out_args *ipoa, necp_kernel_policy_result *result, necp_kernel_policy_result_parameter *result_parameter); 360necp_kernel_policy_id necp_ip6_output_find_policy_match(struct mbuf *packet, int flags, struct ip6_out_args *ip6oa, necp_kernel_policy_result *result, necp_kernel_policy_result_parameter *result_parameter); 361 362int necp_mark_packet_from_ip(struct mbuf *packet, necp_kernel_policy_id policy_id); 363int necp_mark_packet_from_interface(struct mbuf *packet, ifnet_t interface); 364 365ifnet_t necp_get_ifnet_from_result_parameter(necp_kernel_policy_result_parameter *result_parameter); 366bool necp_packet_can_rebind_to_ifnet(struct mbuf *packet, struct ifnet *interface, struct route *new_route, int family); 367 368int necp_mark_packet_as_keepalive(struct mbuf *packet, bool is_keepalive); 369bool necp_get_is_keepalive_from_packet(struct mbuf *packet); 370 371#endif /* BSD_KERNEL_PRIVATE */ 372#ifndef KERNEL 373int necp_match_policy(const uint8_t *parameters, size_t parameters_size, struct necp_aggregate_result *returned_result); 374#endif /* !KERNEL */ 375 376#endif 377