Skip to content

Commit d4825f5

Browse files
committed
feat(mdns): Add support for IPv6 reverse query
Implements reverse querries together with b87bef5 (IPv4) Closes #101
1 parent de1480a commit d4825f5

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

components/mdns/mdns.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,8 @@ static const uint8_t *_mdns_read_fqdn(const uint8_t *packet, const uint8_t *star
437437
if (name->parts == 1 && buf[0] != '_'
438438
&& (strcasecmp(buf, MDNS_DEFAULT_DOMAIN) != 0)
439439
&& (strcasecmp(buf, "arpa") != 0)
440-
&& (strcasecmp(buf, "ip6") != 0)
441440
#ifndef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
441+
&& (strcasecmp(buf, "ip6") != 0)
442442
&& (strcasecmp(buf, "in-addr") != 0)
443443
#endif
444444
) {
@@ -1162,7 +1162,7 @@ static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out
11621162
{
11631163
uint8_t part_length;
11641164
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
1165-
if (q->host && strstr(q->host, "in-addr")) {
1165+
if (q->host && (strstr(q->host, "in-addr") || strstr(q->host, "ip6"))) {
11661166
part_length = append_fqdn_dots(packet, index, q->host, false);
11671167
if (!part_length) {
11681168
return 0;
@@ -1275,7 +1275,7 @@ static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_h
12751275
*/
12761276
static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char *name)
12771277
{
1278-
if (strstr(name, "in-addr") == NULL) {
1278+
if (strstr(name, "in-addr") == NULL && strstr(name, "ip6") == NULL) {
12791279
return 0;
12801280
}
12811281

@@ -1339,7 +1339,8 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
13391339
if (answer->service) {
13401340
return _mdns_append_service_ptr_answers(packet, index, answer->service, answer->flush, answer->bye);
13411341
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
1342-
} else if (answer->host && answer->host->hostname && strstr(answer->host->hostname, "in-addr")) {
1342+
} else if (answer->host && answer->host->hostname &&
1343+
(strstr(answer->host->hostname, "in-addr") || strstr(answer->host->hostname, "ip6"))) {
13431344
return _mdns_append_reverse_ptr_record(packet, index, answer->host->hostname) > 0;
13441345
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
13451346
} else {
@@ -3966,6 +3967,13 @@ void _mdns_disable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
39663967
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state = PCB_OFF;
39673968
}
39683969

3970+
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
3971+
static inline char nibble_to_hex(int var)
3972+
{
3973+
return var > 9 ? var - 10 + 'a' : var + '0';
3974+
}
3975+
#endif
3976+
39693977
/**
39703978
* @brief Performs interface changes based on system events or custom commands
39713979
*/
@@ -4007,6 +4015,31 @@ static void perform_event_action(mdns_if_t mdns_if, mdns_event_actions_t action)
40074015
}
40084016
}
40094017
}
4018+
4019+
if (action & MDNS_EVENT_IP6_REVERSE_LOOKUP) {
4020+
esp_ip6_addr_t addr6;
4021+
if (!esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(mdns_if), &addr6) && !_ipv6_address_is_zero(addr6)) {
4022+
uint8_t *paddr = (uint8_t *)&addr6.addr;
4023+
const char sub[] = "ip6";
4024+
const size_t query_name_size = 4 * sizeof(addr6.addr) /* (2 nibbles + 2 dots)/per byte of IP address */ + sizeof(sub);
4025+
char *reverse_query_name = malloc(query_name_size);
4026+
if (reverse_query_name) {
4027+
char *ptr = &reverse_query_name[query_name_size]; // point to the end
4028+
memcpy(ptr - sizeof(sub), sub, sizeof(sub)); // copy the IP sub-domain
4029+
ptr -= sizeof(sub) + 1; // move before the sub-domain
4030+
while (reverse_query_name < ptr) { // continue populating reverse query from the end
4031+
*ptr-- = '.'; // nibble by nibble, until we reach the beginning
4032+
*ptr-- = nibble_to_hex(((*paddr) >> 4) & 0x0F);
4033+
*ptr-- = '.';
4034+
*ptr-- = nibble_to_hex((*paddr) & 0x0F);
4035+
paddr++;
4036+
}
4037+
ESP_LOGD(TAG, "Registered reverse query: %s.arpa", reverse_query_name);
4038+
_mdns_delegate_hostname_add(reverse_query_name, NULL);
4039+
}
4040+
}
4041+
}
4042+
40104043
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
40114044
}
40124045

components/mdns/private_include/mdns_private.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@
8989
#define MDNS_PACKET_QUEUE_LEN 16 // Maximum packets that can be queued for parsing
9090
#define MDNS_ACTION_QUEUE_LEN 16 // Maximum actions pending to the server
9191
#define MDNS_TXT_MAX_LEN 1024 // Maximum string length of text data in TXT record
92+
#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES)
93+
#define MDNS_NAME_MAX_LEN (64+4) // Need to account for IPv6 reverse queries (64 char address + ".ip6" )
94+
#else
9295
#define MDNS_NAME_MAX_LEN 64 // Maximum string length of hostname, instance, service and proto
96+
#endif
9397
#define MDNS_NAME_BUF_LEN (MDNS_NAME_MAX_LEN+1) // Maximum char buffer size to hold hostname, instance, service or proto
9498
#define MDNS_MAX_PACKET_SIZE 1460 // Maximum size of mDNS outgoing packet
9599

components/mdns/tests/host_test/main/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
4242
ESP_ERROR_CHECK(mdns_hostname_set(CONFIG_TEST_HOSTNAME));
4343
ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_TEST_HOSTNAME);
4444
ESP_ERROR_CHECK(mdns_register_netif(sta));
45-
ESP_ERROR_CHECK(mdns_netif_action(sta, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_IP4_REVERSE_LOOKUP));
45+
ESP_ERROR_CHECK(mdns_netif_action(sta, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_IP4_REVERSE_LOOKUP | MDNS_EVENT_IP6_REVERSE_LOOKUP));
4646

4747
#ifdef REGISTER_SERVICE
4848
//set default mDNS instance name

0 commit comments

Comments
 (0)