mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-01-27 03:35:38 +00:00
Apply patch #8755: Multicast DNS responder support from Erik Ekman
This commit is contained in:
parent
4af297fc20
commit
4919932c49
1
README
1
README
@ -28,6 +28,7 @@ FEATURES
|
|||||||
* raw/native API for enhanced performance
|
* raw/native API for enhanced performance
|
||||||
* Optional Berkeley-like socket API
|
* Optional Berkeley-like socket API
|
||||||
* DNS (Domain names resolver)
|
* DNS (Domain names resolver)
|
||||||
|
* MDNS (Multicast DNS) responder
|
||||||
|
|
||||||
|
|
||||||
APPLICATIONS
|
APPLICATIONS
|
||||||
|
109
doc/mdns.txt
Normal file
109
doc/mdns.txt
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
Multicast DNS for lwIP
|
||||||
|
|
||||||
|
Author: Erik Ekman
|
||||||
|
|
||||||
|
|
||||||
|
Note! The MDNS responder does not have all features required by the standards.
|
||||||
|
See notes in src/core/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 = 1
|
||||||
|
in lwipopts.h and add src/core/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. MDNS needs one PCB for IPv4 and one for IPv6.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
@ -158,6 +158,9 @@ LWIPERFFILES=$(LWIPDIR)/apps/lwiperf/lwiperf.c
|
|||||||
# SNTPFILES: SNTP client
|
# SNTPFILES: SNTP client
|
||||||
SNTPFILES=$(LWIPDIR)/apps/sntp/sntp.c
|
SNTPFILES=$(LWIPDIR)/apps/sntp/sntp.c
|
||||||
|
|
||||||
|
# MDNSFILES: MDNS responder
|
||||||
|
MDNSFILES=$(LWIPDIR)/apps/mdns/mdns.c
|
||||||
|
|
||||||
# NETBIOSNSFILES: NetBIOS name server
|
# NETBIOSNSFILES: NetBIOS name server
|
||||||
NETBIOSNSFILES=$(LWIPDIR)/apps/netbiosns/netbiosns.c
|
NETBIOSNSFILES=$(LWIPDIR)/apps/netbiosns/netbiosns.c
|
||||||
|
|
||||||
@ -166,4 +169,5 @@ LWIPAPPFILES=$(SNMPFILES) \
|
|||||||
$(HTTPDFILES) \
|
$(HTTPDFILES) \
|
||||||
$(LWIPERFFILES) \
|
$(LWIPERFFILES) \
|
||||||
$(SNTPFILES) \
|
$(SNTPFILES) \
|
||||||
|
$(MDNSFILES) \
|
||||||
$(NETBIOSNSFILES)
|
$(NETBIOSNSFILES)
|
||||||
|
2044
src/apps/mdns/mdns.c
Normal file
2044
src/apps/mdns/mdns.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -247,6 +247,10 @@ netif_add(struct netif *netif,
|
|||||||
/* netif not under AutoIP control by default */
|
/* netif not under AutoIP control by default */
|
||||||
netif->autoip = NULL;
|
netif->autoip = NULL;
|
||||||
#endif /* LWIP_AUTOIP */
|
#endif /* LWIP_AUTOIP */
|
||||||
|
#if LWIP_MDNS
|
||||||
|
/* netif not using MDNS by default */
|
||||||
|
netif->mdns = NULL;
|
||||||
|
#endif /* LWIP_MDNS */
|
||||||
#if LWIP_IPV6_AUTOCONFIG
|
#if LWIP_IPV6_AUTOCONFIG
|
||||||
/* IPv6 address autoconfiguration not enabled by default */
|
/* IPv6 address autoconfiguration not enabled by default */
|
||||||
netif->ip6_autoconfig_enabled = 0;
|
netif->ip6_autoconfig_enabled = 0;
|
||||||
|
78
src/include/lwip/apps/mdns.h
Normal file
78
src/include/lwip/apps/mdns.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Verisure Innovation AB
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Erik Ekman <erik.ekman@verisure.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HDR_MDNS_H
|
||||||
|
#define LWIP_HDR_MDNS_H
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
|
#if LWIP_MDNS
|
||||||
|
|
||||||
|
#define DNSSD_PROTO_UDP 0
|
||||||
|
#define DNSSD_PROTO_TCP 1
|
||||||
|
|
||||||
|
#define MDNS_LABEL_MAXLEN 63
|
||||||
|
|
||||||
|
struct mdns_host;
|
||||||
|
struct mdns_service;
|
||||||
|
|
||||||
|
void mdns_resp_init(void);
|
||||||
|
|
||||||
|
err_t mdns_resp_add_netif(struct netif *netif, char *hostname, u32_t dns_ttl);
|
||||||
|
err_t mdns_resp_remove_netif(struct netif *netif);
|
||||||
|
|
||||||
|
typedef void (*service_get_txt_fn_t)(struct mdns_service *service, void *txt_userdata);
|
||||||
|
err_t 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);
|
||||||
|
err_t mdns_resp_add_service_txtitem(struct mdns_service *service, char *txt, int txt_len);
|
||||||
|
|
||||||
|
|
||||||
|
/* Domain struct and methods - visible for unit tests */
|
||||||
|
#define MDNS_DOMAIN_MAXLEN 256
|
||||||
|
#define MDNS_READNAME_ERROR 0xFFFF
|
||||||
|
|
||||||
|
struct mdns_domain {
|
||||||
|
/* Encoded domain name */
|
||||||
|
u8_t name[MDNS_DOMAIN_MAXLEN];
|
||||||
|
/* Total length of domain name, including zero */
|
||||||
|
u16_t length;
|
||||||
|
/* Set if compression of this domain is not allowed */
|
||||||
|
u8_t skip_compression;
|
||||||
|
};
|
||||||
|
|
||||||
|
err_t mdns_domain_add_label(struct mdns_domain *domain, const char *label, unsigned len);
|
||||||
|
u16_t mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain);
|
||||||
|
int mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b);
|
||||||
|
u8_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain);
|
||||||
|
|
||||||
|
#endif /* LWIP_MDNS */
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_MDNS_H */
|
41
src/include/lwip/apps/mdns_opts.h
Normal file
41
src/include/lwip/apps/mdns_opts.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* File: mdns_opts.h
|
||||||
|
* Author: dziegel
|
||||||
|
*
|
||||||
|
* Created on 13. August 2016, 09:17
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LWIP_HDR_APPS_MDNS_OPTS_H
|
||||||
|
#define LWIP_HDR_APPS_MDNS_OPTS_H
|
||||||
|
/**
|
||||||
|
* @defgroup mdns_opts Options
|
||||||
|
* @ingroup mdns
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LWIP_MDNS==1: Turn on multicast DNS module. UDP must be available for MDNS
|
||||||
|
* transport. IGMP is needed for IPv4 multicast.
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_MDNS
|
||||||
|
#define LWIP_MDNS 0
|
||||||
|
#endif /* LWIP_MDNS */
|
||||||
|
|
||||||
|
/** The maximum number of services per netif */
|
||||||
|
#ifndef MDNS_MAX_SERVICES
|
||||||
|
#define MDNS_MAX_SERVICES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MDNS_DEBUG: Enable debugging for multicast DNS.
|
||||||
|
*/
|
||||||
|
#ifndef MDNS_DEBUG
|
||||||
|
#define MDNS_DEBUG LWIP_DBG_OFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* LWIP_HDR_APPS_MDNS_OPTS_H */
|
||||||
|
|
@ -38,6 +38,7 @@
|
|||||||
#define LWIP_HDR_NETIF_H
|
#define LWIP_HDR_NETIF_H
|
||||||
|
|
||||||
#include "lwip/opt.h"
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/apps/mdns_opts.h"
|
||||||
|
|
||||||
#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
|
#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF)
|
||||||
|
|
||||||
@ -58,6 +59,9 @@ struct autoip;
|
|||||||
#if LWIP_IPV6_DHCP6
|
#if LWIP_IPV6_DHCP6
|
||||||
struct dhcp6;
|
struct dhcp6;
|
||||||
#endif /* LWIP_IPV6_DHCP6 */
|
#endif /* LWIP_IPV6_DHCP6 */
|
||||||
|
#if LWIP_MDNS
|
||||||
|
struct mdns_host;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -255,6 +259,10 @@ struct netif {
|
|||||||
/** the AutoIP client state information for this netif */
|
/** the AutoIP client state information for this netif */
|
||||||
struct autoip *autoip;
|
struct autoip *autoip;
|
||||||
#endif
|
#endif
|
||||||
|
#if LWIP_MDNS
|
||||||
|
/** Interface-specific info for multicast DNS */
|
||||||
|
struct mdns_host *mdns;
|
||||||
|
#endif /* LWIP_MDNS */
|
||||||
#if LWIP_IPV6_AUTOCONFIG
|
#if LWIP_IPV6_AUTOCONFIG
|
||||||
/** is this netif enabled for IPv6 autoconfiguration */
|
/** is this netif enabled for IPv6 autoconfiguration */
|
||||||
u8_t ip6_autoconfig_enabled;
|
u8_t ip6_autoconfig_enabled;
|
||||||
|
@ -69,12 +69,15 @@ extern "C" {
|
|||||||
#define DNS_RRTYPE_MX 15 /* mail exchange */
|
#define DNS_RRTYPE_MX 15 /* mail exchange */
|
||||||
#define DNS_RRTYPE_TXT 16 /* text strings */
|
#define DNS_RRTYPE_TXT 16 /* text strings */
|
||||||
#define DNS_RRTYPE_AAAA 28 /* IPv6 address */
|
#define DNS_RRTYPE_AAAA 28 /* IPv6 address */
|
||||||
|
#define DNS_RRTYPE_SRV 33 /* service location */
|
||||||
|
#define DNS_RRTYPE_ANY 255 /* any type */
|
||||||
|
|
||||||
/* DNS field CLASS used for "Resource Records" */
|
/* DNS field CLASS used for "Resource Records" */
|
||||||
#define DNS_RRCLASS_IN 1 /* the Internet */
|
#define DNS_RRCLASS_IN 1 /* the Internet */
|
||||||
#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
|
#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
|
||||||
#define DNS_RRCLASS_CH 3 /* the CHAOS class */
|
#define DNS_RRCLASS_CH 3 /* the CHAOS class */
|
||||||
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
|
#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */
|
||||||
|
#define DNS_RRCLASS_ANY 255 /* any class */
|
||||||
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
|
#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */
|
||||||
|
|
||||||
/* DNS protocol flags */
|
/* DNS protocol flags */
|
||||||
@ -90,6 +93,8 @@ extern "C" {
|
|||||||
#define DNS_FLAG2_ERR_NONE 0x00
|
#define DNS_FLAG2_ERR_NONE 0x00
|
||||||
#define DNS_FLAG2_ERR_NAME 0x03
|
#define DNS_FLAG2_ERR_NAME 0x03
|
||||||
|
|
||||||
|
#define DNS_HDR_GET_OPCODE(hdr) ((((hdr)->flags1) >> 3) & 0xF)
|
||||||
|
|
||||||
#ifdef PACK_STRUCT_USE_INCLUDES
|
#ifdef PACK_STRUCT_USE_INCLUDES
|
||||||
# include "arch/bpstruct.h"
|
# include "arch/bpstruct.h"
|
||||||
#endif
|
#endif
|
||||||
@ -122,5 +127,5 @@ typedef enum {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* DNS_H */
|
#endif /* LWIP_HDR_PROT_DNS_H */
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "core/test_pbuf.h"
|
#include "core/test_pbuf.h"
|
||||||
#include "etharp/test_etharp.h"
|
#include "etharp/test_etharp.h"
|
||||||
#include "dhcp/test_dhcp.h"
|
#include "dhcp/test_dhcp.h"
|
||||||
|
#include "mdns/test_mdns.h"
|
||||||
|
|
||||||
#include "lwip/init.h"
|
#include "lwip/init.h"
|
||||||
|
|
||||||
@ -42,7 +43,8 @@ int main(void)
|
|||||||
mem_suite,
|
mem_suite,
|
||||||
pbuf_suite,
|
pbuf_suite,
|
||||||
etharp_suite,
|
etharp_suite,
|
||||||
dhcp_suite
|
dhcp_suite,
|
||||||
|
mdns_suite
|
||||||
};
|
};
|
||||||
size_t num = sizeof(suites)/sizeof(void*);
|
size_t num = sizeof(suites)/sizeof(void*);
|
||||||
LWIP_ASSERT("No suites defined", num > 0);
|
LWIP_ASSERT("No suites defined", num > 0);
|
||||||
|
@ -51,6 +51,10 @@
|
|||||||
#define TCP_RCV_SCALE 0
|
#define TCP_RCV_SCALE 0
|
||||||
#define PBUF_POOL_SIZE 400 /* pbuf tests need ~200KByte */
|
#define PBUF_POOL_SIZE 400 /* pbuf tests need ~200KByte */
|
||||||
|
|
||||||
|
/* Enable IGMP and MDNS for MDNS tests */
|
||||||
|
#define LWIP_IGMP 1
|
||||||
|
#define LWIP_MDNS 1
|
||||||
|
|
||||||
/* Minimal changes to opt.h required for etharp unit tests: */
|
/* Minimal changes to opt.h required for etharp unit tests: */
|
||||||
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
|
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
|
||||||
|
|
||||||
|
887
test/unit/mdns/test_mdns.c
Normal file
887
test/unit/mdns/test_mdns.c
Normal file
@ -0,0 +1,887 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Verisure Innovation AB
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Erik Ekman <erik.ekman@verisure.com>
|
||||||
|
*
|
||||||
|
* Please coordinate changes and requests with Erik Ekman
|
||||||
|
* <erik.ekman@verisure.com>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "test_mdns.h"
|
||||||
|
|
||||||
|
#include "lwip/pbuf.h"
|
||||||
|
#include "lwip/apps/mdns.h"
|
||||||
|
|
||||||
|
START_TEST(readname_basic)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00 };
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == sizeof(data));
|
||||||
|
fail_unless(domain.length == sizeof(data));
|
||||||
|
fail_if(memcmp(&domain.name, data, sizeof(data)));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_anydata)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = { 0x05, 0x00, 0xFF, 0x08, 0xc0, 0x0f, 0x04, 0x7f, 0x80, 0x82, 0x88, 0x00 };
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == sizeof(data));
|
||||||
|
fail_unless(domain.length == sizeof(data));
|
||||||
|
fail_if(memcmp(&domain.name, data, sizeof(data)));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_short_buf)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a' };
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == MDNS_READNAME_ERROR);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_long_label)
|
||||||
|
{ static const u8_t data[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i',
|
||||||
|
0x52, 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||||
|
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||||
|
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||||
|
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||||
|
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
|
||||||
|
'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 0x00,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == MDNS_READNAME_ERROR);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_overflow)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x00,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == MDNS_READNAME_ERROR);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_jump_earlier)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
/* Some padding needed, not supported to jump to bytes containing dns header */
|
||||||
|
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
/* 10 */ 0x0f, 0x0e, 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xab,
|
||||||
|
/* 20 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x0c,
|
||||||
|
};
|
||||||
|
static const u8_t fullname[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 20, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == sizeof(data));
|
||||||
|
fail_unless(domain.length == sizeof(fullname));
|
||||||
|
|
||||||
|
fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_jump_earlier_jump)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
/* Some padding needed, not supported to jump to bytes containing dns header */
|
||||||
|
/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x0a, 0xf2,
|
||||||
|
/* 0x10 */ 0x04, 'c', 'a', 's', 't', 0x00, 0xc0, 0x10,
|
||||||
|
/* 0x18 */ 0x05, 'm', 'u', 'l', 't', 'i', 0xc0, 0x16,
|
||||||
|
};
|
||||||
|
static const u8_t fullname[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0x18, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == sizeof(data));
|
||||||
|
fail_unless(domain.length == sizeof(fullname));
|
||||||
|
|
||||||
|
fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_jump_maxdepth)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
/* Some padding needed, not supported to jump to bytes containing dns header */
|
||||||
|
/* 0x00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
/* 0x08 */ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0b, 0x0a, 0xf2,
|
||||||
|
/* 0x10 */ 0x04, 'n', 'a', 'm', 'e', 0xc0, 0x27, 0x03,
|
||||||
|
/* 0x18 */ 0x03, 'd', 'n', 's', 0xc0, 0x10, 0xc0, 0x10,
|
||||||
|
/* 0x20 */ 0x04, 'd', 'e', 'e', 'p', 0xc0, 0x18, 0x00,
|
||||||
|
/* 0x28 */ 0x04, 'c', 'a', 's', 't', 0xc0, 0x20, 0xb0,
|
||||||
|
/* 0x30 */ 0x05, 'm', 'u', 'l', 't', 'i', 0xc0, 0x28,
|
||||||
|
};
|
||||||
|
static const u8_t fullname[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't',
|
||||||
|
0x04, 'd', 'e', 'e', 'p', 0x03, 'd', 'n', 's',
|
||||||
|
0x04, 'n', 'a', 'm', 'e', 0x00,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0x30, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == sizeof(data));
|
||||||
|
fail_unless(domain.length == sizeof(fullname));
|
||||||
|
|
||||||
|
fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_jump_later)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
/* 0x00 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x10, 0x00, 0x01, 0x40,
|
||||||
|
/* 0x10 */ 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xab,
|
||||||
|
};
|
||||||
|
static const u8_t fullname[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == 13);
|
||||||
|
fail_unless(domain.length == sizeof(fullname));
|
||||||
|
|
||||||
|
fail_if(memcmp(&domain.name, fullname, sizeof(fullname)));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_half_jump)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == MDNS_READNAME_ERROR);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_jump_toolong)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc2, 0x10, 0x00, 0x01, 0x40,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 0, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == MDNS_READNAME_ERROR);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_jump_loop_label)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
/* 10 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x10,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 10, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == MDNS_READNAME_ERROR);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(readname_jump_loop_jump)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
/* 10 */ 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0xc0, 0x15,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
offset = mdns_readname(p, 10, &domain);
|
||||||
|
pbuf_free(p);
|
||||||
|
fail_unless(offset == MDNS_READNAME_ERROR);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(add_label_basic)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = { 0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00 };
|
||||||
|
struct mdns_domain domain;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "cast", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == sizeof(data));
|
||||||
|
fail_if(memcmp(&domain.name, data, sizeof(data)));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(add_label_long_label)
|
||||||
|
{
|
||||||
|
static const char *toolong = "abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz0123456789-abcdefghijklmnopqrstuvwxyz0123456789-";
|
||||||
|
struct mdns_domain domain;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, toolong, strlen(toolong));
|
||||||
|
fail_unless(res == ERR_VAL);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(add_label_full)
|
||||||
|
{
|
||||||
|
static const char *label = "0123456789abcdef0123456789abcdef";
|
||||||
|
struct mdns_domain domain;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, label, strlen(label));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 33);
|
||||||
|
res = mdns_domain_add_label(&domain, label, strlen(label));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 66);
|
||||||
|
res = mdns_domain_add_label(&domain, label, strlen(label));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 99);
|
||||||
|
res = mdns_domain_add_label(&domain, label, strlen(label));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 132);
|
||||||
|
res = mdns_domain_add_label(&domain, label, strlen(label));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 165);
|
||||||
|
res = mdns_domain_add_label(&domain, label, strlen(label));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 198);
|
||||||
|
res = mdns_domain_add_label(&domain, label, strlen(label));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 231);
|
||||||
|
res = mdns_domain_add_label(&domain, label, strlen(label));
|
||||||
|
fail_unless(res == ERR_VAL);
|
||||||
|
fail_unless(domain.length == 231);
|
||||||
|
res = mdns_domain_add_label(&domain, label, 25);
|
||||||
|
fail_unless(res == ERR_VAL);
|
||||||
|
fail_unless(domain.length == 231);
|
||||||
|
res = mdns_domain_add_label(&domain, label, 24);
|
||||||
|
fail_unless(res == ERR_VAL);
|
||||||
|
fail_unless(domain.length == 231);
|
||||||
|
res = mdns_domain_add_label(&domain, label, 23);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 255);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain.length == 256);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_VAL);
|
||||||
|
fail_unless(domain.length == 256);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(domain_eq_basic)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x05, 'm', 'u', 'l', 't', 'i', 0x04, 'c', 'a', 's', 't', 0x00,
|
||||||
|
};
|
||||||
|
struct mdns_domain domain1, domain2;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
memset(&domain1, 0, sizeof(domain1));
|
||||||
|
res = mdns_domain_add_label(&domain1, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, "cast", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
fail_unless(domain1.length == sizeof(data));
|
||||||
|
|
||||||
|
memset(&domain2, 0, sizeof(domain2));
|
||||||
|
res = mdns_domain_add_label(&domain2, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, "cast", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
fail_unless(mdns_domain_eq(&domain1, &domain2));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(domain_eq_diff)
|
||||||
|
{
|
||||||
|
struct mdns_domain domain1, domain2;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
memset(&domain1, 0, sizeof(domain1));
|
||||||
|
res = mdns_domain_add_label(&domain1, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, "base", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
memset(&domain2, 0, sizeof(domain2));
|
||||||
|
res = mdns_domain_add_label(&domain2, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, "cast", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
fail_if(mdns_domain_eq(&domain1, &domain2));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(domain_eq_case)
|
||||||
|
{
|
||||||
|
struct mdns_domain domain1, domain2;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
memset(&domain1, 0, sizeof(domain1));
|
||||||
|
res = mdns_domain_add_label(&domain1, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, "cast", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
memset(&domain2, 0, sizeof(domain2));
|
||||||
|
res = mdns_domain_add_label(&domain2, "MulTI", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, "casT", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
fail_unless(mdns_domain_eq(&domain1, &domain2));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(domain_eq_anydata)
|
||||||
|
{
|
||||||
|
static const char data1[] = { 0x05, (char)0xcc, (char)0xdc, 0x00, (char)0xa0 };
|
||||||
|
static const char data2[] = { 0x7f, (char)0x8c, 0x01, (char)0xff, (char)0xcf };
|
||||||
|
struct mdns_domain domain1, domain2;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
memset(&domain1, 0, sizeof(domain1));
|
||||||
|
res = mdns_domain_add_label(&domain1, data1, sizeof(data1));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, "cast", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, data2, sizeof(data2));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
memset(&domain2, 0, sizeof(domain2));
|
||||||
|
res = mdns_domain_add_label(&domain2, data1, sizeof(data1));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, "casT", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, data2, sizeof(data2));
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
fail_unless(mdns_domain_eq(&domain1, &domain2));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(domain_eq_length)
|
||||||
|
{
|
||||||
|
struct mdns_domain domain1, domain2;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
memset(&domain1, 0, sizeof(domain1));
|
||||||
|
memset(domain1.name, 0xAA, sizeof(MDNS_DOMAIN_MAXLEN));
|
||||||
|
res = mdns_domain_add_label(&domain1, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain1, "cast", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
memset(&domain2, 0, sizeof(domain2));
|
||||||
|
memset(domain2.name, 0xBB, sizeof(MDNS_DOMAIN_MAXLEN));
|
||||||
|
res = mdns_domain_add_label(&domain2, "multi", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain2, "cast", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
fail_unless(mdns_domain_eq(&domain1, &domain2));
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(compress_full_match)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x00, 0x00,
|
||||||
|
0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
u8_t length;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "foobar", 6);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "local", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
offset = 2;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
/* Write 0 bytes, then a jump to addr 2 */
|
||||||
|
fail_unless(length == 0);
|
||||||
|
fail_unless(offset == 2);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(compress_full_match_subset)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x00, 0x00,
|
||||||
|
0x02, 'g', 'o', 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
u8_t length;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "foobar", 6);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "local", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
offset = 2;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
/* Write 0 bytes, then a jump to addr 5 */
|
||||||
|
fail_unless(length == 0);
|
||||||
|
fail_unless(offset == 5);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(compress_full_match_jump)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
/* 0x00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||||
|
/* 0x10 */ 0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xc0, 0x00, 0x02, 0x00,
|
||||||
|
/* 0x20 */ 0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0xc0, 0x15,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
u8_t length;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "foobar", 6);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "local", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
offset = 0x20;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
/* Write 0 bytes, then a jump to addr 0x20 */
|
||||||
|
fail_unless(length == 0);
|
||||||
|
fail_unless(offset == 0x20);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(compress_no_match)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x00, 0x00,
|
||||||
|
0x04, 'l', 'w', 'i', 'p', 0x05, 'w', 'i', 'k', 'i', 'a', 0x03, 'c', 'o', 'm', 0x00
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
u8_t length;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "foobar", 6);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "local", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
offset = 2;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
/* Write all bytes, no jump */
|
||||||
|
fail_unless(length == domain.length);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(compress_2nd_label)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x00, 0x00,
|
||||||
|
0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
u8_t length;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "lwip", 4);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "local", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
offset = 2;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
/* Write 5 bytes, then a jump to addr 9 */
|
||||||
|
fail_unless(length == 5);
|
||||||
|
fail_unless(offset == 9);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(compress_2nd_label_short)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x00, 0x00,
|
||||||
|
0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
u8_t length;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "foobar", 6);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "local", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
offset = 2;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
/* Write 5 bytes, then a jump to addr 7 */
|
||||||
|
fail_unless(length == 7);
|
||||||
|
fail_unless(offset == 7);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(compress_jump_to_jump)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
/* 0x00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||||
|
/* 0x10 */ 0x04, 'l', 'w', 'i', 'p', 0x05, 'l', 'o', 'c', 'a', 'l', 0x00, 0xc0, 0x00, 0x02, 0x00,
|
||||||
|
/* 0x20 */ 0x07, 'b', 'a', 'n', 'a', 'n', 'a', 's', 0xc0, 0x15,
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
u8_t length;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "foobar", 6);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "local", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
offset = 0x20;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
/* Dont compress if jump would be to a jump */
|
||||||
|
fail_unless(length == domain.length);
|
||||||
|
|
||||||
|
offset = 0x10;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
/* Write 7 bytes, then a jump to addr 0x15 */
|
||||||
|
fail_unless(length == 7);
|
||||||
|
fail_unless(offset == 0x15);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(compress_long_match)
|
||||||
|
{
|
||||||
|
static const u8_t data[] = {
|
||||||
|
0x00, 0x00,
|
||||||
|
0x06, 'f', 'o', 'o', 'b', 'a', 'r', 0x05, 'l', 'o', 'c', 'a', 'l', 0x03, 'c', 'o', 'm', 0x00
|
||||||
|
};
|
||||||
|
struct pbuf *p;
|
||||||
|
struct mdns_domain domain;
|
||||||
|
u16_t offset;
|
||||||
|
u8_t length;
|
||||||
|
err_t res;
|
||||||
|
|
||||||
|
p = pbuf_alloc(PBUF_RAW, sizeof(data), PBUF_ROM);
|
||||||
|
p->payload = (void *)(size_t)data;
|
||||||
|
fail_if(p == NULL);
|
||||||
|
|
||||||
|
memset(&domain, 0, sizeof(domain));
|
||||||
|
res = mdns_domain_add_label(&domain, "foobar", 6);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, "local", 5);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
res = mdns_domain_add_label(&domain, NULL, 0);
|
||||||
|
fail_unless(res == ERR_OK);
|
||||||
|
|
||||||
|
offset = 2;
|
||||||
|
length = mdns_compress_domain(p, &offset, &domain);
|
||||||
|
fail_unless(length == domain.length);
|
||||||
|
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
Suite* mdns_suite(void)
|
||||||
|
{
|
||||||
|
testfunc tests[] = {
|
||||||
|
TESTFUNC(readname_basic),
|
||||||
|
TESTFUNC(readname_anydata),
|
||||||
|
TESTFUNC(readname_short_buf),
|
||||||
|
TESTFUNC(readname_long_label),
|
||||||
|
TESTFUNC(readname_overflow),
|
||||||
|
TESTFUNC(readname_jump_earlier),
|
||||||
|
TESTFUNC(readname_jump_earlier_jump),
|
||||||
|
TESTFUNC(readname_jump_maxdepth),
|
||||||
|
TESTFUNC(readname_jump_later),
|
||||||
|
TESTFUNC(readname_half_jump),
|
||||||
|
TESTFUNC(readname_jump_toolong),
|
||||||
|
TESTFUNC(readname_jump_loop_label),
|
||||||
|
TESTFUNC(readname_jump_loop_jump),
|
||||||
|
|
||||||
|
TESTFUNC(add_label_basic),
|
||||||
|
TESTFUNC(add_label_long_label),
|
||||||
|
TESTFUNC(add_label_full),
|
||||||
|
|
||||||
|
TESTFUNC(domain_eq_basic),
|
||||||
|
TESTFUNC(domain_eq_diff),
|
||||||
|
TESTFUNC(domain_eq_case),
|
||||||
|
TESTFUNC(domain_eq_anydata),
|
||||||
|
TESTFUNC(domain_eq_length),
|
||||||
|
|
||||||
|
TESTFUNC(compress_full_match),
|
||||||
|
TESTFUNC(compress_full_match_subset),
|
||||||
|
TESTFUNC(compress_full_match_jump),
|
||||||
|
TESTFUNC(compress_no_match),
|
||||||
|
TESTFUNC(compress_2nd_label),
|
||||||
|
TESTFUNC(compress_2nd_label_short),
|
||||||
|
TESTFUNC(compress_jump_to_jump),
|
||||||
|
TESTFUNC(compress_long_match),
|
||||||
|
};
|
||||||
|
return create_suite("MDNS", tests, sizeof(tests)/sizeof(testfunc), NULL, NULL);
|
||||||
|
}
|
8
test/unit/mdns/test_mdns.h
Normal file
8
test/unit/mdns/test_mdns.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef LWIP_HDR_TEST_MDNS_H__
|
||||||
|
#define LWIP_HDR_TEST_MDNS_H__
|
||||||
|
|
||||||
|
#include "../lwip_check.h"
|
||||||
|
|
||||||
|
Suite* mdns_suite(void);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user