LCOV - code coverage report
Current view: top level - zephyr/net - dns_sd.h Coverage Total Hit
Test: new.info Lines: 100.0 % 26 26
Test Date: 2025-09-05 22:20:39

            Line data    Source code
       1            1 : /** @file
       2              :  *  @brief DNS Service Discovery
       3              :  */
       4              : 
       5              : /*
       6              :  * Copyright (c) 2020 Friedt Professional Engineering Services, Inc
       7              :  *
       8              :  * SPDX-License-Identifier: Apache-2.0
       9              :  */
      10              : 
      11              : #ifndef ZEPHYR_INCLUDE_NET_DNS_SD_H_
      12              : #define ZEPHYR_INCLUDE_NET_DNS_SD_H_
      13              : 
      14              : #include <stdint.h>
      15              : #include <zephyr/sys/byteorder.h>
      16              : #include <zephyr/sys/iterable_sections.h>
      17              : 
      18              : #ifdef __cplusplus
      19              : extern "C" {
      20              : #endif
      21              : 
      22              : /**
      23              :  * @brief DNS Service Discovery
      24              :  *
      25              :  * @details This API enables services to be advertised via DNS. To
      26              :  * advertise a service, system or application code should use
      27              :  * @ref DNS_SD_REGISTER_TCP_SERVICE or
      28              :  * @ref DNS_SD_REGISTER_UDP_SERVICE.
      29              :  *
      30              :  * @see <a href="https://tools.ietf.org/html/rfc6763">RFC 6763</a>
      31              :  *
      32              :  * @defgroup dns_sd DNS Service Discovery
      33              :  * @since 2.5
      34              :  * @version 0.8.0
      35              :  * @ingroup networking
      36              :  * @{
      37              :  */
      38              : 
      39              : /** RFC 1034 Section 3.1 */
      40            1 : #define DNS_SD_INSTANCE_MIN_SIZE 1
      41              : /** RFC 1034 Section 3.1, RFC 6763 Section 7.2 */
      42            1 : #define DNS_SD_INSTANCE_MAX_SIZE 63
      43              : /** RFC 6763 Section 7.2 - inclusive of underscore */
      44            1 : #define DNS_SD_SERVICE_MIN_SIZE 2
      45              : /** RFC 6763 Section 7.2 - inclusive of underscore */
      46            1 : #define DNS_SD_SERVICE_MAX_SIZE 16
      47              : /** RFC 6763 Section 4.1.2 */
      48            1 : #define DNS_SD_SERVICE_PREFIX '_'
      49              : /** RFC 6763 Section 4.1.2 - either _tcp or _udp (case insensitive) */
      50            1 : #define DNS_SD_PROTO_SIZE 4
      51              : /** ICANN Rules for TLD naming */
      52            1 : #define DNS_SD_DOMAIN_MIN_SIZE 2
      53              : /** RFC 1034 Section 3.1, RFC 6763 Section 7.2 */
      54            1 : #define DNS_SD_DOMAIN_MAX_SIZE 63
      55              : 
      56              : /**
      57              :  * Minimum number of segments in a fully-qualified name
      58              :  *
      59              :  * This represents FQN's of the form below
      60              :  * ```
      61              :  * <sn>._tcp.<domain>.
      62              :  * ```
      63              :  * Currently sub-types and service domains are unsupported and only the
      64              :  * "local" domain is supported. Specifically, that excludes the following:
      65              :  * ```
      66              :  * <sub>._sub.<sn>._tcp.<servicedomain>.<parentdomain>.
      67              :  * ```
      68              :  * @see <a href="https://datatracker.ietf.org/doc/html/rfc6763">RFC 6763</a>, Section 7.2.
      69              :  */
      70            1 : #define DNS_SD_MIN_LABELS 3
      71              : /**
      72              :  * Maximum number of segments in a fully-qualified name
      73              :  *
      74              :  * This represents FQN's of the form below
      75              :  * ```
      76              :  * <instance>.<sn>._tcp.<domain>.
      77              :  * ```
      78              :  *
      79              :  * Currently sub-types and service domains are unsupported and only the
      80              :  * "local" domain is supported. Specifically, that excludes the following:
      81              :  * ```
      82              :  * <sub>._sub.<sn>._tcp.<servicedomain>.<parentdomain>.
      83              :  * ```
      84              :  * @see <a href="https://datatracker.ietf.org/doc/html/rfc6763">RFC 6763</a>, Section 7.2.
      85              :  */
      86            1 : #define DNS_SD_MAX_LABELS 4
      87              : 
      88              : /**
      89              :  * @brief Register a service for DNS Service Discovery
      90              :  *
      91              :  * This macro should be used for advanced use cases. Two simple use cases are
      92              :  * when a custom @p _domain or a custom (non-standard) @p _proto is required.
      93              :  *
      94              :  * Another use case is when the port number is not preassigned. That could
      95              :  * be for a number of reasons, but the most common use case would be for
      96              :  * ephemeral port usage - i.e. when the service is bound using port number 0.
      97              :  * In that case, Zephyr (like other OS's) will simply choose an unused port.
      98              :  * When using ephemeral ports, it can be helpful to assign @p _port to the
      99              :  * @ref sockaddr_in.sin_port field of an IPv4 @ref sockaddr_in, or to the
     100              :  * @ref sockaddr_in6.sin6_port field of an IPv6 @ref sockaddr_in6.
     101              :  *
     102              :  * The service can be referenced using the @p _id variable.
     103              :  *
     104              :  * @param _id variable name for the DNS-SD service record
     105              :  * @param _instance name of the service instance such as "My HTTP Server"
     106              :  * @param _service name of the service, such as "_http"
     107              :  * @param _proto protocol used by the service - either "_tcp" or "_udp"
     108              :  * @param _domain the domain of the service, such as "local"
     109              :  * @param _text information for the DNS TXT record
     110              :  * @param _port a pointer to the port number that this service will use
     111              :  */
     112              : #define DNS_SD_REGISTER_SERVICE(_id, _instance, _service, _proto,       \
     113            1 :                                 _domain, _text, _port)                  \
     114              :         static const STRUCT_SECTION_ITERABLE(dns_sd_rec, _id) = {       \
     115              :                 .instance = _instance,                                  \
     116              :                 .service = _service,                                    \
     117              :                 .proto = _proto,                                        \
     118              :                 .domain = _domain,                                      \
     119              :                 .text = (const char *)_text,                            \
     120              :                 .text_size = sizeof(_text) - 1,                         \
     121              :                 .port = _port,                                          \
     122              :         }
     123              : 
     124              : /**
     125              :  * @brief Register a TCP service for DNS Service Discovery
     126              :  *
     127              :  * This macro can be used for service advertisement using DNS-SD.
     128              :  *
     129              :  * The service can be referenced using the @p id variable.
     130              :  *
     131              :  * Example (with TXT):
     132              :  * @code{.c}
     133              :  * #include <zephyr/net/dns_sd.h>
     134              :  * static const char bar_txt[] = {
     135              :  *   "\x06" "path=/"
     136              :  *   "\x0f" "this=is the way"
     137              :  *   "\x0e" "foo or=foo not"
     138              :  *   "\x17" "this=has\0embedded\0nulls"
     139              :  *   "\x04" "true"
     140              :  * };
     141              :  * DNS_SD_REGISTER_TCP_SERVICE(bar, CONFIG_NET_HOSTNAME,
     142              :  *   "_bar", "local", bar_txt, 4242);
     143              :  * @endcode
     144              :  *
     145              :  * TXT records begin with a single length byte (hex-encoded)
     146              :  * and contain key=value pairs. Thus, the length of the key-value pair
     147              :  * must not exceed 255 bytes. Care must be taken to ensure that the
     148              :  * encoded length value is correct.
     149              :  *
     150              :  * For additional rules on TXT encoding, see RFC 6763, Section 6.
     151              : 
     152              :  * @param id variable name for the DNS-SD service record
     153              :  * @param instance name of the service instance such as "My HTTP Server"
     154              :  * @param service name of the service, such as "_http"
     155              :  * @param domain the domain of the service, such as "local"
     156              :  * @param text information for the DNS TXT record
     157              :  * @param port the port number that this service will use
     158              :  *
     159              :  * @see <a href="https://tools.ietf.org/html/rfc6763">RFC 6763</a>
     160              :  */
     161              : #define DNS_SD_REGISTER_TCP_SERVICE(id, instance, service, domain, text, \
     162            1 :                                     port)                                \
     163              :         static const uint16_t id ## _port = sys_cpu_to_be16(port); \
     164              :         DNS_SD_REGISTER_SERVICE(id, instance, service, "_tcp", domain,         \
     165              :                                 text, &id ## _port)
     166              : 
     167              : /**
     168              :  * @brief Register a UDP service for DNS Service Discovery
     169              :  *
     170              :  * This macro can be used for service advertisement using DNS-SD.
     171              :  *
     172              :  * The service can be referenced using the @p id variable.
     173              :  *
     174              :  * Example (no TXT):
     175              :  * @code{.c}
     176              :  * #include <zephyr/net/dns_sd.h>
     177              :  * DNS_SD_REGISTER_UDP_SERVICE(foo, CONFIG_NET_HOSTNAME,
     178              :  *   "_foo", "local", DNS_SD_EMPTY_TXT, 4242);
     179              :  * @endcode
     180              :  *
     181              :  * @param id variable name for the DNS-SD service record
     182              :  * @param instance name of the service instance such as "My TFTP Server"
     183              :  * @param service name of the service, such as "_tftp"
     184              :  * @param domain the domain of the service, such as "local" or "zephyrproject.org"
     185              :  * @param text information for the DNS TXT record
     186              :  * @param port a pointer to the port number that this service will use
     187              :  *
     188              :  * @see <a href="https://tools.ietf.org/html/rfc6763">RFC 6763</a>
     189              :  */
     190              : #define DNS_SD_REGISTER_UDP_SERVICE(id, instance, service, domain, text, \
     191            1 :                                     port)                                \
     192              :         static const uint16_t id ## _port = sys_cpu_to_be16(port); \
     193              :         DNS_SD_REGISTER_SERVICE(id, instance, service, "_udp", domain,         \
     194              :                                 text, &id ## _port)
     195              : 
     196              : /** Empty DNS-SD TXT specifier */
     197            1 : #define DNS_SD_EMPTY_TXT dns_sd_empty_txt
     198              : 
     199              : /**
     200              :  * @brief DNS Service Discovery record
     201              :  *
     202              :  * This structure used in the implementation of RFC 6763 and should not
     203              :  * need to be accessed directly from application code.
     204              :  *
     205              :  * The @a port pointer must be non-NULL. When the value in @a port
     206              :  * is non-zero, the service is advertised as being on that particular
     207              :  * port. When the value in @a port is zero, then the service is not
     208              :  * advertised.
     209              :  *
     210              :  * Thus, it is possible for multiple services to advertise on a
     211              :  * particular port if they hard-code the port.
     212              :  *
     213              :  * @see <a href="https://tools.ietf.org/html/rfc6763">RFC 6763</a>
     214              :  */
     215            1 : struct dns_sd_rec {
     216              :         /** "<Instance>" - e.g. "My HTTP Server" */
     217            1 :         const char *instance;
     218              :         /** Top half of the "<Service>" such as "_http" */
     219            1 :         const char *service;
     220              :         /** Bottom half of the "<Service>" "_tcp" or "_udp" */
     221            1 :         const char *proto;
     222              :         /** "<Domain>" such as "local" or "zephyrproject.org" */
     223            1 :         const char *domain;
     224              :         /** DNS TXT record */
     225            1 :         const char *text;
     226              :         /** Size (in bytes) of the DNS TXT record  */
     227            1 :         size_t text_size;
     228              :         /** A pointer to the port number used by the service */
     229            1 :         const uint16_t *port;
     230              : };
     231              : 
     232              : /** @cond INTERNAL_HIDDEN */
     233              : 
     234              : /**
     235              :  * @brief Empty TXT specifier for DNS-SD
     236              :  *
     237              :  * @internal
     238              :  */
     239              : extern const char dns_sd_empty_txt[1];
     240              : /**
     241              :  * @brief Wildcard Port specifier for DNS-SD
     242              :  *
     243              :  * @internal
     244              :  */
     245              : extern const uint16_t dns_sd_port_zero;
     246              : 
     247              : /** @endcond */
     248              : 
     249              : /**
     250              :  * @brief Obtain the size of DNS-SD TXT data
     251              :  *
     252              :  * @param rec the record to in question
     253              :  * @return the size of the text field
     254              :  */
     255            1 : static inline size_t dns_sd_txt_size(const struct dns_sd_rec *rec)
     256              : {
     257              :         return rec->text_size;
     258              : }
     259              : 
     260              : /**
     261              :  * @brief Check if @a rec is a DNS-SD Service Type Enumeration
     262              :  *
     263              :  * DNS-SD Service Type Enumeration is used by network tooling to
     264              :  * acquire a list of all mDNS-advertised services belonging to a
     265              :  * particular host on a particular domain.
     266              :  *
     267              :  * For example, for the domain '.local', the equivalent query
     268              :  * would be '_services._dns-sd._udp.local'.
     269              :  *
     270              :  * Currently, only the '.local' domain is supported.
     271              :  *
     272              :  * @see <a href="https://datatracker.ietf.org/doc/html/rfc6763#section-9">Service Type Enumeration, RFC 6763</a>.
     273              :  *
     274              :  * @param rec the record to in question
     275              :  * @return true if @a rec is a DNS-SD Service Type Enumeration
     276              :  */
     277            1 : bool dns_sd_is_service_type_enumeration(const struct dns_sd_rec *rec);
     278              : 
     279              : /**
     280              :  * @brief Create a wildcard filter for DNS-SD records
     281              :  *
     282              :  * @param filter a pointer to the filter to use
     283              :  */
     284            1 : void dns_sd_create_wildcard_filter(struct dns_sd_rec *filter);
     285              : 
     286              : /**
     287              :  * @}
     288              :  */
     289              : 
     290              : #ifdef __cplusplus
     291              : };
     292              : #endif
     293              : 
     294              : #endif /* ZEPHYR_INCLUDE_NET_DNS_SD_H_ */
        

Generated by: LCOV version 2.0-1