/* nat64-macos.h * * Copyright (c) 2022-2023 Apple Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef NAT64_H #define NAT64_H #include "srp.h" #include "dns-msg.h" #include "srp-crypto.h" #include "ioloop.h" #include "dnssd-proxy.h" #include "srp-gw.h" #include "srp-proxy.h" #include "srp-mdns-proxy.h" #include "config-parse.h" #include "cti-services.h" #include "route.h" #define DNSMessageHeader dns_wire_t #include "ioloop-common.h" // for service_connection_t #define NAT64_PREFIX_LLQ_QUERY_DOMAIN "ipv4only.arpa" #define NAT64_PREFIX_SLASH_96_BYTES 12 // Thread spec limit NAT64 prefix to /96 #define NAT64_THREAD_PREFIX_SETTLING_TIME 10 // In seconds #define NAT64_BR_PREFIX_PUBLISHER_WAIT_TIME 30 // In seconds #define NAT64_INFRA_PREFIX_LIMIT 3 // Max number of allowed nat64 prefixes from infra on thread network // Refer to https://www.rfc-editor.org/rfc/rfc4191 typedef enum { nat64_preference_medium = 0, nat64_preference_high = 1, nat64_preference_low = 3, nat64_preference_reserved = 2, } nat64_preference; typedef enum { nat64_prefix_action_none = 0, nat64_prefix_action_add = 1, nat64_prefix_action_remove = 2, } nat64_prefix_action; typedef struct nat64_prefix nat64_prefix_t; typedef struct nat64 nat64_t; struct nat64_prefix { uint32_t ref_count; nat64_prefix_t *NULLABLE next; struct in6_addr prefix; int prefix_len; nat64_preference priority; nat64_prefix_action action; int rloc; bool pending; }; // ipv4 default route monitor typedef enum nat64_ipv4_default_route_monitor_event_type { nat64_event_ipv4_default_route_invalid = 0, nat64_event_ipv4_default_route_update, nat64_event_ipv4_default_route_showed_up, nat64_event_ipv4_default_route_went_away, } nat64_ipv4_default_route_monitor_event_type_t; typedef enum { nat64_ipv4_default_route_monitor_state_invalid = 0, nat64_ipv4_default_route_monitor_state_init, nat64_ipv4_default_route_monitor_state_wait_for_event, } nat64_ipv4_default_route_monitor_state_type_t; typedef struct nat64_ipv4_default_route_monitor_event { char *NONNULL name; union { bool has_ipv4_connectivity; bool has_ipv4_default_route; }; nat64_ipv4_default_route_monitor_event_type_t event_type; } nat64_ipv4_default_route_monitor_event_t; typedef struct { uint32_t ref_count; nat64_ipv4_default_route_monitor_state_type_t state; bool has_ipv4_default_route; char *NONNULL state_name; nat64_t *NONNULL nat64; } nat64_ipv4_default_route_monitor_t; // Infrastructure prefix monitor typedef enum nat64_infra_prefix_monitor_event_type { nat64_event_infra_prefix_invalid = 0, nat64_event_infra_prefix_update, } nat64_infra_prefix_monitor_event_type_t; typedef struct nat64_infra_prefix_monitor_event { char *NONNULL name; DNSServiceFlags flags; union { const void *NULLABLE rdata; nat64_prefix_t *NULLABLE prefix; }; nat64_infra_prefix_monitor_event_type_t event_type; } nat64_infra_prefix_monitor_event_t; typedef enum { nat64_infra_prefix_monitor_state_invalid = 0, nat64_infra_prefix_monitor_state_init, nat64_infra_prefix_monitor_state_wait_for_change, nat64_infra_prefix_monitor_state_change_occurred, } nat64_infra_prefix_monitor_state_type_t; typedef struct { uint32_t ref_count; nat64_infra_prefix_monitor_state_type_t state; char *NONNULL state_name; DNSServiceRef NULLABLE sdRef; // LLQ sdRef nat64_prefix_t *NULLABLE infra_nat64_prefixes; nat64_t *NONNULL nat64; bool canceled; } nat64_infra_prefix_monitor_t; // Thread prefix monitor typedef enum nat64_thread_prefix_monitor_event_type { nat64_event_thread_prefix_invalid = 0, nat64_event_thread_prefix_init_wait_ended, nat64_event_thread_prefix_update, } nat64_thread_prefix_monitor_event_type_t; typedef struct nat64_thread_prefix_monitor_event { char *NONNULL name; union { nat64_prefix_t *NULLABLE prefix; cti_route_vec_t *NULLABLE routes; }; nat64_thread_prefix_monitor_event_type_t event_type; } nat64_thread_prefix_monitor_event_t; typedef enum { nat64_thread_prefix_monitor_state_invalid = 0, nat64_thread_prefix_monitor_state_init, nat64_thread_prefix_monitor_state_wait_for_settling, nat64_thread_prefix_monitor_state_wait_for_change, nat64_thread_prefix_monitor_state_change_occurred, } nat64_thread_prefix_monitor_state_type_t; typedef struct { uint32_t ref_count; nat64_thread_prefix_monitor_state_type_t state; char *NONNULL state_name; nat64_prefix_t *NULLABLE thread_nat64_prefixes; wakeup_t *NULLABLE timer; nat64_t *NONNULL nat64; } nat64_thread_prefix_monitor_t; // Infra nat64 prefix publisher typedef enum nat64_infra_prefix_publisher_event_type { nat64_event_nat64_infra_prefix_publisher_invalid = 0, nat64_event_nat64_infra_prefix_publisher_thread_prefix_changed, nat64_event_nat64_infra_prefix_publisher_infra_prefix_changed, nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_went_away, nat64_event_nat64_infra_prefix_publisher_routable_omr_prefix_showed_up, nat64_event_nat64_infra_prefix_publisher_shutdown, } nat64_infra_prefix_publisher_event_type_t; typedef struct nat64_infra_prefix_publisher_event { char *NONNULL name; nat64_prefix_t *NULLABLE prefix; nat64_infra_prefix_publisher_event_type_t event_type; } nat64_infra_prefix_publisher_event_t; typedef enum { nat64_infra_prefix_publisher_state_invalid = 0, nat64_infra_prefix_publisher_state_init, nat64_infra_prefix_publisher_state_wait, // Wait for infra prefix nat64_infra_prefix_publisher_state_ignore, // Ignore infra prefix nat64_infra_prefix_publisher_state_check, // Check infra prefix nat64_infra_prefix_publisher_state_publish, // Publish infra prefix nat64_infra_prefix_publisher_state_publishing, // Publishing infra prefix } nat64_infra_prefix_publisher_state_type_t; typedef struct { uint32_t ref_count; nat64_infra_prefix_publisher_state_type_t state; char *NONNULL state_name; bool routable_omr_prefix_present; nat64_prefix_t *NULLABLE proposed_prefix; nat64_t *NONNULL nat64; } nat64_infra_prefix_publisher_t; // BR nat64 prefix publisher typedef enum nat64_br_prefix_publisher_event_type { nat64_event_nat64_br_prefix_publisher_invalid = 0, nat64_event_nat64_br_prefix_publisher_okay_to_publish, nat64_event_nat64_br_prefix_publisher_ipv4_default_route_showed_up, nat64_event_nat64_br_prefix_publisher_ipv4_default_route_went_away, nat64_event_nat64_br_prefix_publisher_thread_prefix_changed, nat64_event_nat64_br_prefix_publisher_infra_prefix_changed, nat64_event_nat64_br_prefix_publisher_shutdown, } nat64_br_prefix_publisher_event_type_t; typedef struct nat64_br_prefix_publisher_event { char *NONNULL name; nat64_prefix_t *NULLABLE prefix; nat64_br_prefix_publisher_event_type_t event_type; } nat64_br_prefix_publisher_event_t; typedef enum { nat64_br_prefix_publisher_state_invalid = 0, nat64_br_prefix_publisher_state_init, nat64_br_prefix_publisher_state_start_timer, nat64_br_prefix_publisher_state_wait_for_anything, nat64_br_prefix_publisher_state_publish, nat64_br_prefix_publisher_state_publishing, } nat64_br_prefix_publisher_state_type_t; typedef struct { uint32_t ref_count; nat64_br_prefix_publisher_state_type_t state; char *NONNULL state_name; nat64_prefix_t *NULLABLE br_prefix; wakeup_t *NULLABLE timer; bool wait_finished; nat64_t *NONNULL nat64; } nat64_br_prefix_publisher_t; struct nat64 { uint32_t ref_count; route_state_t *NONNULL route_state; nat64_prefix_t *NULLABLE update_queue; // State machines nat64_ipv4_default_route_monitor_t *NULLABLE ipv4_monitor; nat64_infra_prefix_monitor_t *NULLABLE infra_monitor; nat64_thread_prefix_monitor_t *NULLABLE thread_monitor; nat64_infra_prefix_publisher_t *NULLABLE nat64_infra_prefix_publisher; nat64_br_prefix_publisher_t *NULLABLE nat64_br_prefix_publisher; }; nat64_t *NULLABLE nat64_create(route_state_t *NONNULL route_state); nat64_prefix_t *NULLABLE nat64_prefix_create(struct in6_addr *NONNULL address, int prefix_length, nat64_preference pref, int rloc); void nat64_add_prefix(route_state_t *NONNULL route_state, const uint8_t *NONNULL const data, offmesh_route_preference_t route_pref); void nat64_remove_prefix(route_state_t *NONNULL route_state, const uint8_t *NONNULL const data); void nat64_offmesh_route_list_callback(route_state_t *NONNULL route_state, cti_route_vec_t *NONNULL routes, cti_status_t status); void nat64_init(route_state_t *NONNULL route_state); void nat64_default_route_update(nat64_t *NONNULL nat64, bool has_ipv4_connectivity); void nat64_omr_route_update(nat64_t *NONNULL nat64, bool has_routable_omr_prefix); void nat64_stop(route_state_t *NONNULL route_state); void nat64_start(route_state_t *NONNULL route_state); void nat64_thread_shutdown(route_state_t *NONNULL route_state); #endif /* NAT64_H */ // Local Variables: // mode: C // tab-width: 4 // c-file-style: "bsd" // c-basic-offset: 4 // fill-column: 120 // indent-tabs-mode: nil // End: