mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-23 15:27:28 +02:00
Merge pull request #219 from david-cermak/feat/mdns_reverse_query_ip6
feat(mdns): Add support for IPv6 reverse query
This commit is contained in:
@ -276,16 +276,15 @@ void app_main(void)
|
|||||||
* This is typically performed in "GOT_IP" event handler, but we call it here directly
|
* This is typically performed in "GOT_IP" event handler, but we call it here directly
|
||||||
* since the `EXAMPLE_INTERFACE` netif is connected already, to keep the example simple.
|
* since the `EXAMPLE_INTERFACE` netif is connected already, to keep the example simple.
|
||||||
*/
|
*/
|
||||||
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ENABLE_IP4));
|
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_ENABLE_IP6));
|
||||||
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ANNOUNCE_IP4));
|
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ANNOUNCE_IP4 | MDNS_EVENT_ANNOUNCE_IP6));
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES)
|
#if defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES)
|
||||||
while (mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_IP4_REVERSE_LOOKUP) != ESP_OK) {
|
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_IP4_REVERSE_LOOKUP | MDNS_EVENT_IP6_REVERSE_LOOKUP));
|
||||||
vTaskDelay(50 / portTICK_PERIOD_MS);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // CONFIG_MDNS_ADD_CUSTOM_NETIF
|
||||||
|
|
||||||
initialise_button();
|
initialise_button();
|
||||||
xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL);
|
xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL);
|
||||||
}
|
}
|
||||||
|
@ -120,10 +120,11 @@ def test_examples_protocol_mdns(dut):
|
|||||||
2. get the dut host name (and IP address)
|
2. get the dut host name (and IP address)
|
||||||
3. check the mdns name is accessible
|
3. check the mdns name is accessible
|
||||||
4. check DUT output if mdns advertized host is resolved
|
4. check DUT output if mdns advertized host is resolved
|
||||||
|
5. check if DUT responds to dig
|
||||||
|
6. check the DUT is searchable via reverse IP lookup
|
||||||
"""
|
"""
|
||||||
|
|
||||||
specific_host = dut.expect(re.compile(
|
specific_host = dut.expect(r'mdns hostname set to: \[(.*?)\]')[1].decode()
|
||||||
b'mdns hostname set to: \[(.*?)\]')).group(1).decode() # noqa: W605
|
|
||||||
|
|
||||||
mdns_server_events = {
|
mdns_server_events = {
|
||||||
'stop': Event(),
|
'stop': Event(),
|
||||||
@ -132,9 +133,14 @@ def test_examples_protocol_mdns(dut):
|
|||||||
}
|
}
|
||||||
mdns_responder = Thread(target=mdns_server,
|
mdns_responder = Thread(target=mdns_server,
|
||||||
args=(str(specific_host), mdns_server_events))
|
args=(str(specific_host), mdns_server_events))
|
||||||
ip_address = dut.expect(
|
ipv4 = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]',
|
||||||
re.compile(b'IPv4 address:([a-zA-Z0-9]*).*')).group(1).decode()
|
timeout=30)[1].decode()
|
||||||
print('Connected to AP with IP: {}'.format(ip_address))
|
ip_addresses = [ipv4]
|
||||||
|
if dut.app.sdkconfig.get('LWIP_IPV6') is True:
|
||||||
|
ipv6_r = r':'.join((r'[0-9a-fA-F]{4}', ) * 8)
|
||||||
|
ipv6 = dut.expect(ipv6_r, timeout=30)[0].decode()
|
||||||
|
ip_addresses.append(ipv6)
|
||||||
|
print('Connected with IP addresses: {}'.format(','.join(ip_addresses)))
|
||||||
try:
|
try:
|
||||||
# 3. check the mdns name is accessible.
|
# 3. check the mdns name is accessible.
|
||||||
mdns_responder.start()
|
mdns_responder.start()
|
||||||
@ -165,11 +171,25 @@ def test_examples_protocol_mdns(dut):
|
|||||||
])
|
])
|
||||||
print('Resolving {} using "dig" succeeded with:\n{}'.format(
|
print('Resolving {} using "dig" succeeded with:\n{}'.format(
|
||||||
specific_host, dig_output))
|
specific_host, dig_output))
|
||||||
if not ip_address.encode('utf-8') in dig_output:
|
if not ipv4.encode('utf-8') in dig_output:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Test has failed: Incorrectly resolved DUT hostname using dig'
|
'Test has failed: Incorrectly resolved DUT hostname using dig'
|
||||||
"Output should've contained DUT's IP address:{}".format(
|
"Output should've contained DUT's IP address:{}".format(ipv4))
|
||||||
ip_address))
|
# 6. check the DUT reverse lookup
|
||||||
|
if dut.app.sdkconfig.get('MDNS_RESPOND_REVERSE_QUERIES') is True:
|
||||||
|
for ip_address in ip_addresses:
|
||||||
|
dig_output = subprocess.check_output([
|
||||||
|
'dig', '+short', '-p', '5353', '@224.0.0.251', '-x',
|
||||||
|
'{}'.format(ip_address)
|
||||||
|
])
|
||||||
|
print('Reverse lookup for {} using "dig" succeeded with:\n{}'.
|
||||||
|
format(ip_address, dig_output))
|
||||||
|
if specific_host not in dig_output.decode():
|
||||||
|
raise ValueError(
|
||||||
|
'Test has failed: Incorrectly resolved DUT IP address using dig'
|
||||||
|
"Output should've contained DUT's name:{}".format(
|
||||||
|
specific_host))
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
mdns_server_events['stop'].set()
|
mdns_server_events['stop'].set()
|
||||||
mdns_responder.join()
|
mdns_responder.join()
|
||||||
|
@ -6,6 +6,7 @@ CONFIG_MDNS_PREDEF_NETIF_STA=n
|
|||||||
CONFIG_MDNS_PREDEF_NETIF_AP=n
|
CONFIG_MDNS_PREDEF_NETIF_AP=n
|
||||||
CONFIG_MDNS_PREDEF_NETIF_ETH=n
|
CONFIG_MDNS_PREDEF_NETIF_ETH=n
|
||||||
CONFIG_MDNS_ADD_CUSTOM_NETIF=y
|
CONFIG_MDNS_ADD_CUSTOM_NETIF=y
|
||||||
|
CONFIG_MDNS_RESPOND_REVERSE_QUERIES=y
|
||||||
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
|
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
|
||||||
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
|
||||||
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
CONFIG_EXAMPLE_CONNECT_WIFI=n
|
||||||
|
@ -437,8 +437,8 @@ static const uint8_t *_mdns_read_fqdn(const uint8_t *packet, const uint8_t *star
|
|||||||
if (name->parts == 1 && buf[0] != '_'
|
if (name->parts == 1 && buf[0] != '_'
|
||||||
&& (strcasecmp(buf, MDNS_DEFAULT_DOMAIN) != 0)
|
&& (strcasecmp(buf, MDNS_DEFAULT_DOMAIN) != 0)
|
||||||
&& (strcasecmp(buf, "arpa") != 0)
|
&& (strcasecmp(buf, "arpa") != 0)
|
||||||
&& (strcasecmp(buf, "ip6") != 0)
|
|
||||||
#ifndef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
#ifndef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
||||||
|
&& (strcasecmp(buf, "ip6") != 0)
|
||||||
&& (strcasecmp(buf, "in-addr") != 0)
|
&& (strcasecmp(buf, "in-addr") != 0)
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
@ -1162,7 +1162,7 @@ static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out
|
|||||||
{
|
{
|
||||||
uint8_t part_length;
|
uint8_t part_length;
|
||||||
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
||||||
if (q->host && strstr(q->host, "in-addr")) {
|
if (q->host && (strstr(q->host, "in-addr") || strstr(q->host, "ip6"))) {
|
||||||
part_length = append_fqdn_dots(packet, index, q->host, false);
|
part_length = append_fqdn_dots(packet, index, q->host, false);
|
||||||
if (!part_length) {
|
if (!part_length) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -1275,7 +1275,7 @@ static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_h
|
|||||||
*/
|
*/
|
||||||
static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char *name)
|
static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char *name)
|
||||||
{
|
{
|
||||||
if (strstr(name, "in-addr") == NULL) {
|
if (strstr(name, "in-addr") == NULL && strstr(name, "ip6") == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1339,7 +1339,8 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
|
|||||||
if (answer->service) {
|
if (answer->service) {
|
||||||
return _mdns_append_service_ptr_answers(packet, index, answer->service, answer->flush, answer->bye);
|
return _mdns_append_service_ptr_answers(packet, index, answer->service, answer->flush, answer->bye);
|
||||||
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
||||||
} else if (answer->host && answer->host->hostname && strstr(answer->host->hostname, "in-addr")) {
|
} else if (answer->host && answer->host->hostname &&
|
||||||
|
(strstr(answer->host->hostname, "in-addr") || strstr(answer->host->hostname, "ip6"))) {
|
||||||
return _mdns_append_reverse_ptr_record(packet, index, answer->host->hostname) > 0;
|
return _mdns_append_reverse_ptr_record(packet, index, answer->host->hostname) > 0;
|
||||||
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
|
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
|
||||||
} else {
|
} else {
|
||||||
@ -3966,6 +3967,13 @@ void _mdns_disable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
|||||||
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state = PCB_OFF;
|
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state = PCB_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|
||||||
|
static inline char nibble_to_hex(int var)
|
||||||
|
{
|
||||||
|
return var > 9 ? var - 10 + 'a' : var + '0';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs interface changes based on system events or custom commands
|
* @brief Performs interface changes based on system events or custom commands
|
||||||
*/
|
*/
|
||||||
@ -4007,6 +4015,32 @@ static void perform_event_action(mdns_if_t mdns_if, mdns_event_actions_t action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_LWIP_IPV6
|
||||||
|
if (action & MDNS_EVENT_IP6_REVERSE_LOOKUP) {
|
||||||
|
esp_ip6_addr_t addr6;
|
||||||
|
if (!esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(mdns_if), &addr6) && !_ipv6_address_is_zero(addr6)) {
|
||||||
|
uint8_t *paddr = (uint8_t *)&addr6.addr;
|
||||||
|
const char sub[] = "ip6";
|
||||||
|
const size_t query_name_size = 4 * sizeof(addr6.addr) /* (2 nibbles + 2 dots)/per byte of IP address */ + sizeof(sub);
|
||||||
|
char *reverse_query_name = malloc(query_name_size);
|
||||||
|
if (reverse_query_name) {
|
||||||
|
char *ptr = &reverse_query_name[query_name_size]; // point to the end
|
||||||
|
memcpy(ptr - sizeof(sub), sub, sizeof(sub)); // copy the IP sub-domain
|
||||||
|
ptr -= sizeof(sub) + 1; // move before the sub-domain
|
||||||
|
while (reverse_query_name < ptr) { // continue populating reverse query from the end
|
||||||
|
*ptr-- = '.'; // nibble by nibble, until we reach the beginning
|
||||||
|
*ptr-- = nibble_to_hex(((*paddr) >> 4) & 0x0F);
|
||||||
|
*ptr-- = '.';
|
||||||
|
*ptr-- = nibble_to_hex((*paddr) & 0x0F);
|
||||||
|
paddr++;
|
||||||
|
}
|
||||||
|
ESP_LOGD(TAG, "Registered reverse query: %s.arpa", reverse_query_name);
|
||||||
|
_mdns_delegate_hostname_add(reverse_query_name, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_LWIP_IPV6 */
|
||||||
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
|
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,11 @@
|
|||||||
#define MDNS_PACKET_QUEUE_LEN 16 // Maximum packets that can be queued for parsing
|
#define MDNS_PACKET_QUEUE_LEN 16 // Maximum packets that can be queued for parsing
|
||||||
#define MDNS_ACTION_QUEUE_LEN 16 // Maximum actions pending to the server
|
#define MDNS_ACTION_QUEUE_LEN 16 // Maximum actions pending to the server
|
||||||
#define MDNS_TXT_MAX_LEN 1024 // Maximum string length of text data in TXT record
|
#define MDNS_TXT_MAX_LEN 1024 // Maximum string length of text data in TXT record
|
||||||
|
#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES)
|
||||||
|
#define MDNS_NAME_MAX_LEN (64+4) // Need to account for IPv6 reverse queries (64 char address + ".ip6" )
|
||||||
|
#else
|
||||||
#define MDNS_NAME_MAX_LEN 64 // Maximum string length of hostname, instance, service and proto
|
#define MDNS_NAME_MAX_LEN 64 // Maximum string length of hostname, instance, service and proto
|
||||||
|
#endif
|
||||||
#define MDNS_NAME_BUF_LEN (MDNS_NAME_MAX_LEN+1) // Maximum char buffer size to hold hostname, instance, service or proto
|
#define MDNS_NAME_BUF_LEN (MDNS_NAME_MAX_LEN+1) // Maximum char buffer size to hold hostname, instance, service or proto
|
||||||
#define MDNS_MAX_PACKET_SIZE 1460 // Maximum size of mDNS outgoing packet
|
#define MDNS_MAX_PACKET_SIZE 1460 // Maximum size of mDNS outgoing packet
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ int main(int argc, char *argv[])
|
|||||||
ESP_ERROR_CHECK(mdns_hostname_set(CONFIG_TEST_HOSTNAME));
|
ESP_ERROR_CHECK(mdns_hostname_set(CONFIG_TEST_HOSTNAME));
|
||||||
ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_TEST_HOSTNAME);
|
ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_TEST_HOSTNAME);
|
||||||
ESP_ERROR_CHECK(mdns_register_netif(sta));
|
ESP_ERROR_CHECK(mdns_register_netif(sta));
|
||||||
ESP_ERROR_CHECK(mdns_netif_action(sta, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_IP4_REVERSE_LOOKUP));
|
ESP_ERROR_CHECK(mdns_netif_action(sta, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_IP4_REVERSE_LOOKUP | MDNS_EVENT_IP6_REVERSE_LOOKUP));
|
||||||
|
|
||||||
#ifdef REGISTER_SERVICE
|
#ifdef REGISTER_SERVICE
|
||||||
//set default mDNS instance name
|
//set default mDNS instance name
|
||||||
|
Reference in New Issue
Block a user