lwIP  2.0.2
Lightweight IP stack

Modules

 Options
 

Functions

void mdns_resp_init (void)
 
void mdns_resp_netif_settings_changed (struct netif *netif)
 
err_t mdns_resp_add_netif (struct netif *netif, const char *hostname, u32_t dns_ttl)
 
err_t mdns_resp_remove_netif (struct netif *netif)
 
err_t mdns_resp_add_service (struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_data)
 
err_t mdns_resp_add_service_txtitem (struct mdns_service *service, const char *txt, u8_t txt_len)
 

Detailed Description

RFC 6762 - Multicast DNS
RFC 6763 - DNS-Based Service Discovery

Multicast DNS for lwIP

Author: Erik Ekman


Note! The MDNS responder does not have all features required by the standards.
See notes in src/apps/mdns/mdns.c for what is left. It is however usable in normal
cases - but watch out if many devices on the same network try to use the same
host/service instance names.


How to enable:
==============

MDNS support does not depend on DNS.
MDNS supports using IPv4 only, v6 only, or v4+v6.

To enable MDNS responder, set
  LWIP_MDNS_RESPONDER = 1
in lwipopts.h and add src/apps/mdns/mdns.c to your list of files to build.

The max number of services supported per netif is defined by MDNS_MAX_SERVICES,
default is 1.

Increase MEMP_NUM_UDP_PCB by 1. MDNS needs one PCB.
Increase LWIP_NUM_NETIF_CLIENT_DATA by 1 (MDNS needs one entry on netif).

MDNS with IPv4 requires LWIP_IGMP = 1, and preferably LWIP_AUTOIP = 1.
MDNS with IPv6 requires LWIP_IPV6_MLD = 1, and that a link-local address is
generated.

The MDNS code puts its structs on the stack where suitable to reduce dynamic
memory allocation. It may use up to 1kB of stack.

MDNS needs a strncasecmp() implementation. If you have one, define
LWIP_MDNS_STRNCASECMP to it. Otherwise the code will provide an implementation
for you.


How to use:
===========

Call mdns_resp_init() during system initialization.
This opens UDP sockets on port 5353 for IPv4 and IPv6.


To start responding on a netif, run
  mdns_resp_add_netif(struct netif *netif, char *hostname, u32_t dns_ttl)

The hostname will be copied. If this returns successfully, the netif will join
the multicast groups and any MDNS/legacy DNS requests sent unicast or multicast
to port 5353 will be handled:
- <hostname>.local type A, AAAA or ANY returns relevant IP addresses
- Reverse lookups (PTR in-addr.arpa, ip6.arpa) of netif addresses
  returns <hostname>.local
Answers will use the supplied TTL (in seconds)
MDNS allows UTF-8 names, but it is recommended to stay within ASCII,
since the default case-insensitive comparison assumes this.

It is recommended to call this function after an IPv4 address has been set,
since there is currently no check if the v4 address is valid.

Call mdns_resp_netif_settings_changed() every time the IP address
on the netif has changed.

To stop responding on a netif, run
  mdns_resp_remove_netif(struct netif *netif)


Adding services:
================

The netif first needs to be registered. Then run
  mdns_resp_add_service(struct netif *netif, char *name, char *service,
      u16_t proto, u16_t port, u32_t dns_ttl,
      service_get_txt_fn_t txt_fn, void *txt_userdata);

The name and service pointers will be copied. Name refers to the name of the
service instance, and service is the type of service, like _http
proto can be DNSSD_PROTO_UDP or DNSSD_PROTO_TCP which represent _udp and _tcp.
If this call returns successfully, the following queries will be answered:
- _services._dns-sd._udp.local type PTR returns <service>.<proto>.local
- <service>.<proto>.local type PTR returns <name>.<service>.<proto>.local
- <name>.<service>.<proto>.local type SRV returns hostname and port of service
- <name>.<service>.<proto>.local type TXT builds text strings by calling txt_fn
  with the supplied userdata. The callback adds strings to the reply by calling
  mdns_resp_add_service_txtitem(struct mdns_service *service, char *txt,
   int txt_len). Example callback method:

   static void srv_txt(struct mdns_service *service, void *txt_userdata)
   {
     res = mdns_resp_add_service_txtitem(service, "path=/", 6);
     LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return);
   }

  Since a hostname struct is used for TXT storage each single item can be max
  63 bytes long, and  the total max length (including length bytes for each
  item) is 255 bytes.

If your device runs a webserver on port 80, an example call might be:

  mdns_resp_add_service(netif, "myweb", "_http"
      DNSSD_PROTO_TCP, 80, 3600, srv_txt, NULL);

which will publish myweb._http._tcp.local for any hosts looking for web servers,
and point them to <hostname>.local:80

Relevant information will be sent as additional records to reduce number of
requests required from a client.

Removing services is currently not supported. Services are removed when the
netif is removed.

Things left to implement:

Function Documentation

◆ mdns_resp_add_netif()

err_t mdns_resp_add_netif ( struct netif netif,
const char *  hostname,
u32_t  dns_ttl 
)

Activate MDNS responder for a network interface and send announce packets.

Parameters
netifThe network interface to activate.
hostnameName to use. Queries for <hostname>.local will be answered with the IP addresses of the netif. The hostname will be copied, the given pointer can be on the stack.
dns_ttlValidity time in seconds to send out for IP address data in DNS replies
Returns
ERR_OK if netif was added, an err_t otherwise

◆ mdns_resp_add_service()

err_t mdns_resp_add_service ( struct netif netif,
const char *  name,
const char *  service,
enum mdns_sd_proto  proto,
u16_t  port,
u32_t  dns_ttl,
service_get_txt_fn_t  txt_fn,
void *  txt_data 
)

Add a service to the selected network interface.

Parameters
netifThe network interface to publish this service on
nameThe name of the service
serviceThe service type, like "_http"
protoThe service protocol, DNSSD_PROTO_TCP for TCP ("_tcp") and DNSSD_PROTO_UDP for others ("_udp")
portThe port the service listens to
dns_ttlValidity time in seconds to send out for service data in DNS replies
txt_fnCallback to get TXT data. Will be called each time a TXT reply is created to allow dynamic replies.
txt_dataUserdata pointer for txt_fn
Returns
ERR_OK if the service was added to the netif, an err_t otherwise

◆ mdns_resp_add_service_txtitem()

err_t mdns_resp_add_service_txtitem ( struct mdns_service service,
const char *  txt,
u8_t  txt_len 
)

Call this function from inside the service_get_txt_fn_t callback to add text data. Buffer for TXT data is 256 bytes, and each field is prefixed with a length byte.

Parameters
serviceThe service provided to the get_txt callback
txtString to add to the TXT field.
txt_lenLength of string
Returns
ERR_OK if the string was added to the reply, an err_t otherwise

◆ mdns_resp_init()

void mdns_resp_init ( void  )

Initiate MDNS responder. Will open UDP sockets on port 5353

◆ mdns_resp_netif_settings_changed()

void mdns_resp_netif_settings_changed ( struct netif netif)

Announce IP settings have changed on netif. Call this in your callback registered by netif_set_status_callback(). This function may go away in the future when netif supports registering multiple callback functions.

Parameters
netifThe network interface where settings have changed.

◆ mdns_resp_remove_netif()

err_t mdns_resp_remove_netif ( struct netif netif)

Stop responding to MDNS queries on this interface, leave multicast groups, and free the helper structure and any of its services.

Parameters
netifThe network interface to remove.
Returns
ERR_OK if netif was removed, an err_t otherwise