1*10465441SEvalZeroMulticast DNS for lwIP 2*10465441SEvalZero 3*10465441SEvalZeroAuthor: Erik Ekman 4*10465441SEvalZero 5*10465441SEvalZero 6*10465441SEvalZeroNote! The MDNS responder does not have all features required by the standards. 7*10465441SEvalZeroSee notes in src/apps/mdns/mdns.c for what is left. It is however usable in normal 8*10465441SEvalZerocases - but watch out if many devices on the same network try to use the same 9*10465441SEvalZerohost/service instance names. 10*10465441SEvalZero 11*10465441SEvalZero 12*10465441SEvalZeroHow to enable: 13*10465441SEvalZero============== 14*10465441SEvalZero 15*10465441SEvalZeroMDNS support does not depend on DNS. 16*10465441SEvalZeroMDNS supports using IPv4 only, v6 only, or v4+v6. 17*10465441SEvalZero 18*10465441SEvalZeroTo enable MDNS responder, set 19*10465441SEvalZero LWIP_MDNS_RESPONDER = 1 20*10465441SEvalZeroin lwipopts.h and add src/apps/mdns/mdns.c to your list of files to build. 21*10465441SEvalZero 22*10465441SEvalZeroThe max number of services supported per netif is defined by MDNS_MAX_SERVICES, 23*10465441SEvalZerodefault is 1. 24*10465441SEvalZero 25*10465441SEvalZeroIncrease MEMP_NUM_UDP_PCB by 1. MDNS needs one PCB. 26*10465441SEvalZeroIncrease LWIP_NUM_NETIF_CLIENT_DATA by 1 (MDNS needs one entry on netif). 27*10465441SEvalZero 28*10465441SEvalZeroMDNS with IPv4 requires LWIP_IGMP = 1, and preferably LWIP_AUTOIP = 1. 29*10465441SEvalZeroMDNS with IPv6 requires LWIP_IPV6_MLD = 1, and that a link-local address is 30*10465441SEvalZerogenerated. 31*10465441SEvalZero 32*10465441SEvalZeroThe MDNS code puts its structs on the stack where suitable to reduce dynamic 33*10465441SEvalZeromemory allocation. It may use up to 1kB of stack. 34*10465441SEvalZero 35*10465441SEvalZeroMDNS (like other apps) needs a strncasecmp() implementation. If you have one, define 36*10465441SEvalZero'lwip_strnicmp' to it. Otherwise the code will provide an implementation 37*10465441SEvalZerofor you. 38*10465441SEvalZero 39*10465441SEvalZero 40*10465441SEvalZeroHow to use: 41*10465441SEvalZero=========== 42*10465441SEvalZero 43*10465441SEvalZeroCall mdns_resp_init() during system initialization. 44*10465441SEvalZeroThis opens UDP sockets on port 5353 for IPv4 and IPv6. 45*10465441SEvalZero 46*10465441SEvalZero 47*10465441SEvalZeroTo start responding on a netif, run 48*10465441SEvalZero mdns_resp_add_netif(struct netif *netif, char *hostname, u32_t dns_ttl) 49*10465441SEvalZero 50*10465441SEvalZeroThe hostname will be copied. If this returns successfully, the netif will join 51*10465441SEvalZerothe multicast groups and any MDNS/legacy DNS requests sent unicast or multicast 52*10465441SEvalZeroto port 5353 will be handled: 53*10465441SEvalZero- <hostname>.local type A, AAAA or ANY returns relevant IP addresses 54*10465441SEvalZero- Reverse lookups (PTR in-addr.arpa, ip6.arpa) of netif addresses 55*10465441SEvalZero returns <hostname>.local 56*10465441SEvalZeroAnswers will use the supplied TTL (in seconds) 57*10465441SEvalZeroMDNS allows UTF-8 names, but it is recommended to stay within ASCII, 58*10465441SEvalZerosince the default case-insensitive comparison assumes this. 59*10465441SEvalZero 60*10465441SEvalZeroCall mdns_resp_announce() every time the IP address on the netif has changed. 61*10465441SEvalZero 62*10465441SEvalZeroCall mdns_resp_restart() every time the network interface comes up after being 63*10465441SEvalZerodown, for example cable connected after being disconnected, administrative 64*10465441SEvalZerointerface comes up after being down, or the device wakes up from sleep. 65*10465441SEvalZero 66*10465441SEvalZeroTo stop responding on a netif, run 67*10465441SEvalZero mdns_resp_remove_netif(struct netif *netif) 68*10465441SEvalZero 69*10465441SEvalZero 70*10465441SEvalZeroAdding services: 71*10465441SEvalZero================ 72*10465441SEvalZero 73*10465441SEvalZeroThe netif first needs to be registered. Then run 74*10465441SEvalZero mdns_resp_add_service(struct netif *netif, char *name, char *service, 75*10465441SEvalZero u16_t proto, u16_t port, u32_t dns_ttl, 76*10465441SEvalZero service_get_txt_fn_t txt_fn, void *txt_userdata); 77*10465441SEvalZero 78*10465441SEvalZeroThe name and service pointers will be copied. Name refers to the name of the 79*10465441SEvalZeroservice instance, and service is the type of service, like _http 80*10465441SEvalZeroproto can be DNSSD_PROTO_UDP or DNSSD_PROTO_TCP which represent _udp and _tcp. 81*10465441SEvalZeroIf this call returns successfully, the following queries will be answered: 82*10465441SEvalZero- _services._dns-sd._udp.local type PTR returns <service>.<proto>.local 83*10465441SEvalZero- <service>.<proto>.local type PTR returns <name>.<service>.<proto>.local 84*10465441SEvalZero- <name>.<service>.<proto>.local type SRV returns hostname and port of service 85*10465441SEvalZero- <name>.<service>.<proto>.local type TXT builds text strings by calling txt_fn 86*10465441SEvalZero with the supplied userdata. The callback adds strings to the reply by calling 87*10465441SEvalZero mdns_resp_add_service_txtitem(struct mdns_service *service, char *txt, 88*10465441SEvalZero int txt_len). Example callback method: 89*10465441SEvalZero 90*10465441SEvalZero static void srv_txt(struct mdns_service *service, void *txt_userdata) 91*10465441SEvalZero { 92*10465441SEvalZero res = mdns_resp_add_service_txtitem(service, "path=/", 6); 93*10465441SEvalZero LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return); 94*10465441SEvalZero } 95*10465441SEvalZero 96*10465441SEvalZero Since a hostname struct is used for TXT storage each single item can be max 97*10465441SEvalZero 63 bytes long, and the total max length (including length bytes for each 98*10465441SEvalZero item) is 255 bytes. 99*10465441SEvalZero 100*10465441SEvalZeroIf your device runs a webserver on port 80, an example call might be: 101*10465441SEvalZero 102*10465441SEvalZero mdns_resp_add_service(netif, "myweb", "_http" 103*10465441SEvalZero DNSSD_PROTO_TCP, 80, 3600, srv_txt, NULL); 104*10465441SEvalZero 105*10465441SEvalZerowhich will publish myweb._http._tcp.local for any hosts looking for web servers, 106*10465441SEvalZeroand point them to <hostname>.local:80 107*10465441SEvalZero 108*10465441SEvalZeroRelevant information will be sent as additional records to reduce number of 109*10465441SEvalZerorequests required from a client. 110*10465441SEvalZero 111*10465441SEvalZeroTo remove a service from a netif, run 112*10465441SEvalZero mdns_resp_del_service(struct netif *netif, s8_t slot)