+ memset(cond_buf, 0, condition_tlv_length);
+ u_int8_t *cond_buf_cursor = cond_buf;
+ if (condition_mask == NECP_POLICY_CONDITION_DEFAULT) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_DEFAULT, 0, "", cond_buf, condition_tlv_length);
+ } else {
+ if (condition_mask & NECP_KERNEL_CONDITION_ALL_INTERFACES) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_ALL_INTERFACES, 0, "", cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_HAS_CLIENT) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_HAS_CLIENT, 0, "", cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_LOCAL_NETWORKS) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_LOCAL_NETWORKS, 0, "", cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_BOUND_INTERFACE) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_BOUND_INTERFACE, strlen(if_name) + 1,
+ if_name, cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_PROTOCOL) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_IP_PROTOCOL, sizeof(policy->cond_protocol), &policy->cond_protocol,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_APP_ID) {
+ struct necp_uuid_id_mapping *entry = necp_uuid_lookup_uuid_with_app_id_locked(policy->cond_app_id);
+ if (entry != NULL) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_APPLICATION, sizeof(entry->uuid), entry->uuid,
+ cond_buf, condition_tlv_length);
+ }
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_REAL_APP_ID) {
+ struct necp_uuid_id_mapping *entry = necp_uuid_lookup_uuid_with_app_id_locked(policy->cond_real_app_id);
+ if (entry != NULL) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_REAL_APPLICATION, sizeof(entry->uuid), entry->uuid,
+ cond_buf, condition_tlv_length);
+ }
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_DOMAIN) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_DOMAIN, strlen(policy->cond_domain) + 1, policy->cond_domain,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_ACCOUNT_ID) {
+ if (account_id_entry != NULL) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_ACCOUNT, strlen(account_id_entry->string) + 1, account_id_entry->string,
+ cond_buf, condition_tlv_length);
+ }
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_PID) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_PID, sizeof(policy->cond_pid), &policy->cond_pid,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_UID) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_UID, sizeof(policy->cond_uid), &policy->cond_uid,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_TRAFFIC_CLASS) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_TRAFFIC_CLASS, sizeof(policy->cond_traffic_class), &policy->cond_traffic_class,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_ENTITLEMENT) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_ENTITLEMENT, 0, "",
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_CUSTOM_ENTITLEMENT) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_ENTITLEMENT, strlen(policy->cond_custom_entitlement) + 1, policy->cond_custom_entitlement,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_PLATFORM_BINARY) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_PLATFORM_BINARY, 0, "", cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_SDK_VERSION) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_SDK_VERSION,
+ sizeof(policy->cond_sdk_version), &policy->cond_sdk_version,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_LOCAL_START) {
+ if (condition_mask & NECP_KERNEL_CONDITION_LOCAL_END) {
+ struct necp_policy_condition_addr_range range;
+ memcpy(&range.start_address, &policy->cond_local_start, sizeof(policy->cond_local_start));
+ memcpy(&range.end_address, &policy->cond_local_end, sizeof(policy->cond_local_end));
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_LOCAL_ADDR_RANGE, sizeof(range), &range,
+ cond_buf, condition_tlv_length);
+ } else {
+ struct necp_policy_condition_addr addr;
+ addr.prefix = policy->cond_local_prefix;
+ memcpy(&addr.address, &policy->cond_local_start, sizeof(policy->cond_local_start));
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_LOCAL_ADDR, sizeof(addr), &addr,
+ cond_buf, condition_tlv_length);
+ }
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_REMOTE_START) {
+ if (condition_mask & NECP_KERNEL_CONDITION_REMOTE_END) {
+ struct necp_policy_condition_addr_range range;
+ memcpy(&range.start_address, &policy->cond_remote_start, sizeof(policy->cond_remote_start));
+ memcpy(&range.end_address, &policy->cond_remote_end, sizeof(policy->cond_remote_end));
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_REMOTE_ADDR_RANGE, sizeof(range), &range,
+ cond_buf, condition_tlv_length);
+ } else {
+ struct necp_policy_condition_addr addr;
+ addr.prefix = policy->cond_remote_prefix;
+ memcpy(&addr.address, &policy->cond_remote_start, sizeof(policy->cond_remote_start));
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_REMOTE_ADDR, sizeof(addr), &addr,
+ cond_buf, condition_tlv_length);
+ }
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_AGENT_TYPE) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_AGENT_TYPE,
+ sizeof(policy->cond_agent_type), &policy->cond_agent_type,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_CLIENT_FLAGS) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_CLIENT_FLAGS, sizeof(policy->cond_client_flags), &policy->cond_client_flags, cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_LOCAL_EMPTY) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_FLOW_LOCAL_ADDR_EMPTY, 0, "", cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_REMOTE_EMPTY) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_FLOW_REMOTE_ADDR_EMPTY, 0, "", cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_SIGNING_IDENTIFIER) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_SIGNING_IDENTIFIER, strlen(policy->cond_signing_identifier) + 1, policy->cond_signing_identifier,
+ cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_PACKET_FILTER_TAGS) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_PACKET_FILTER_TAGS, sizeof(policy->cond_packet_filter_tags), &policy->cond_packet_filter_tags, cond_buf, condition_tlv_length);
+ }
+ if (condition_mask & NECP_KERNEL_CONDITION_IS_LOOPBACK) {
+ cond_buf_cursor = necp_buffer_write_tlv(cond_buf_cursor, NECP_POLICY_CONDITION_FLOW_IS_LOOPBACK, 0, "", cond_buf, condition_tlv_length);
+ }
+ }