1 /* 2 * Copyright (c) 2020 Friedt Professional Engineering Services, Inc 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef DNS_SD_H_ 8 #define DNS_SD_H_ 9 10 #include <stdbool.h> 11 #include <stdint.h> 12 #include <string.h> 13 14 #include <zephyr/net/dns_sd.h> 15 #include <zephyr/net/net_ip.h> 16 #include <zephyr/sys/iterable_sections.h> 17 18 #include "dns_pack.h" 19 20 /* TODO: Move these into Kconfig */ 21 #define DNS_SD_PTR_TTL 4500 22 #define DNS_SD_TXT_TTL 4500 23 #define DNS_SD_SRV_TTL 120 24 #define DNS_SD_A_TTL 120 25 #define DNS_SD_AAAA_TTL 120 26 27 #define DNS_SD_PTR_MASK (NS_CMPRSFLGS << 8) 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #define DNS_SD_FOREACH(it) \ 34 STRUCT_SECTION_FOREACH(dns_sd_rec, it) 35 36 #define DNS_SD_COUNT(dst) \ 37 STRUCT_SECTION_COUNT(dns_sd_rec, dst) 38 39 #define DNS_SD_GET(i, dst) \ 40 STRUCT_SECTION_GET(dns_sd_rec, i, dst) 41 42 /** 43 * @brief Extract labels from a DNS-SD PTR query 44 * 45 * ``` 46 * <sn>._tcp.<domain>. 47 * <instance>.<sn>._tcp.<domain>. 48 * ``` 49 * 50 * Currently sub-types and service domains are unsupported and only the 51 * "local" domain is supported. Specifically, that excludes the following: 52 * ``` 53 * <sub>._sub.<sn>._tcp.<servicedomain>.<parentdomain>. 54 * ``` 55 * 56 * @param query a pointer to the start of the query 57 * @param query_size the number of bytes contained in the query 58 * @param[out] record the DNS-SD record to initialize and populate 59 * @param label array of pointers to suitably sized buffers 60 * @param size array of sizes for each buffer in @p label 61 * @param[inout] n number of elements in @p label and @p size 62 * 63 * @return on success, number of bytes read from @p query 64 * @return on failure, a negative errno value 65 * 66 * @see <a href="https://datatracker.ietf.org/doc/html/rfc6763">RFC 6763</a>, Section 7.2. 67 */ 68 int dns_sd_query_extract(const uint8_t *query, size_t query_size, struct dns_sd_rec *record, 69 char **label, size_t *size, size_t *n); 70 71 /** 72 * @brief See if the DNS SD @p filter matches the @p record 73 * 74 * The fields in @p filter should be populated with filter elements to 75 * identify a possible match. If pointer fields are set to NULL, they 76 * act as a wildcard in the matching process. I.e. they will match 77 * anything. Similarly, the @ref dns_sd_rec.port field may be set to 0 78 * to be used as a wildcard. 79 * 80 * The @ref dns_sd_rec.text and @ref dns_ds_rec.text_size fields 81 * are not included in the matching process. 82 * 83 * For example, the filter below can be used to match any 84 * "_http._tcp" records. 85 * 86 * @code{c} 87 * const struct dns_sd_rec *it; 88 * struct dns_sd_rec filter = { 89 * // match any instance 90 * .instance = NULL, 91 * // match records with service "_http" 92 * .service = "_http", 93 * // match records with protocol "_tcp" 94 * .proto = "_tcp", 95 * // match any domain 96 * .domain = NULL, 97 * // match any port 98 * .port = 0, 99 * }; 100 * 101 * DNS_SD_FOREACH(it) { 102 * if (dns_sd_rec_match(it, filter)) { 103 * // found a match! 104 * } 105 * } 106 * @endcode{c} 107 * 108 * @param record The reference DNS-SD record 109 * @param filter The DNS-SD record filter 110 * 111 * @return true if the @p record matches the @p filter 112 * @return false if @p record is not a match for @p filter 113 * @return false if either @p record or @p filter are invalid 114 */ 115 bool dns_sd_rec_match(const struct dns_sd_rec *record, 116 const struct dns_sd_rec *filter); 117 118 /** 119 * @brief Handle a DNS PTR Query with DNS Service Discovery 120 * 121 * This function should be called once for each DNS-SD record that 122 * matches a particular DNS PTR query. 123 * 124 * If there is no IPv4 address to advertise, then @p addr4 should be 125 * NULL. 126 * 127 * If there is no IPv6 address to advertise, then @p addr6 should be 128 * NULL. 129 * 130 * @param inst the DNS-SD record to advertise 131 * @param addr4 pointer to the IPv4 address 132 * @param addr6 pointer to the IPv6 address 133 * @param buf output buffer 134 * @param buf_size size of the output buffer 135 * 136 * @return on success, number of bytes written to @p buf 137 * @return on failure, a negative errno value 138 */ 139 int dns_sd_handle_ptr_query(const struct dns_sd_rec *inst, 140 const struct in_addr *addr4, const struct in6_addr *addr6, 141 uint8_t *buf, uint16_t buf_size); 142 143 /** 144 * @brief Handle a Service Type Enumeration with DNS Service Discovery 145 * 146 * This function should be called once for each type of advertised service. 147 * 148 * @param service the DNS-SD service to advertise 149 * @param addr4 pointer to the IPv4 address 150 * @param addr6 pointer to the IPv6 address 151 * @param buf output buffer 152 * @param buf_size size of the output buffer 153 * 154 * @return on success, number of bytes written to @p buf 155 * @return on failure, a negative errno value 156 */ 157 int dns_sd_handle_service_type_enum(const struct dns_sd_rec *service, 158 const struct in_addr *addr4, const struct in6_addr *addr6, 159 uint8_t *buf, uint16_t buf_size); 160 161 #ifdef __cplusplus 162 }; 163 #endif 164 165 #endif /* DNS_SD_H_ */ 166