17
17
#include "mdns_networking.h"
18
18
#include "esp_log.h"
19
19
#include "esp_random.h"
20
- #if __has_include ("bsd/string.h" )
21
- #include "bsd/string.h"
22
- #endif
20
+
23
21
#if CONFIG_ETH_ENABLED && CONFIG_MDNS_PREDEF_NETIF_ETH
24
22
#include "esp_eth.h"
25
23
#endif
@@ -439,7 +437,11 @@ static const uint8_t *_mdns_read_fqdn(const uint8_t *packet, const uint8_t *star
439
437
if (name -> parts == 1 && buf [0 ] != '_'
440
438
&& (strcasecmp (buf , MDNS_DEFAULT_DOMAIN ) != 0 )
441
439
&& (strcasecmp (buf , "arpa" ) != 0 )
442
- && (strcasecmp (buf , "ip6" ) != 0 )) {
440
+ && (strcasecmp (buf , "ip6" ) != 0 )
441
+ #ifndef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
442
+ && (strcasecmp (buf , "in-addr" ) != 0 )
443
+ #endif
444
+ ) {
443
445
strlcat (name -> host , "." , sizeof (name -> host ));
444
446
strlcat (name -> host , buf , sizeof (name -> host ));
445
447
} else if (strcasecmp (buf , MDNS_SUB_STR ) == 0 ) {
@@ -643,6 +645,60 @@ static inline int append_one_txt_record_entry(uint8_t *packet, uint16_t *index,
643
645
return len + 1 ;
644
646
}
645
647
648
+ #ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
649
+ static inline int append_single_str (uint8_t * packet , uint16_t * index , const char * str , int len )
650
+ {
651
+ if ((* index + len + 1 ) >= MDNS_MAX_PACKET_SIZE ) {
652
+ return 0 ;
653
+ }
654
+ if (!_mdns_append_u8 (packet , index , len )) {
655
+ return 0 ;
656
+ }
657
+ memcpy (packet + * index , str , len );
658
+ * index += len ;
659
+ return * index ;
660
+ }
661
+
662
+ /**
663
+ * @brief appends FQDN to a packet from hostname separated by dots. This API works the same way as
664
+ * _mdns_append_fqdn(), but refrains from DNS compression (as it's mainly used for IP addresses (many short items),
665
+ * where we gain very little (or compression even gets counter-productive mainly for IPv6 addresses)
666
+ *
667
+ * @param packet MDNS packet
668
+ * @param index offset in the packet
669
+ * @param name name representing FQDN in '.' separated parts
670
+ * @param last true if appending the last part (domain, typically "arpa")
671
+ *
672
+ * @return length of added data: 0 on error or length on success
673
+ */
674
+ static uint16_t append_fqdn_dots (uint8_t * packet , uint16_t * index , const char * name , bool last )
675
+ {
676
+ int len = strlen (name );
677
+ char * host = (char * )name ;
678
+ char * end = host ;
679
+ char * start = host ;
680
+ do {
681
+ end = memchr (start , '.' , len );
682
+ end = end ? end : host + len ;
683
+ int part_len = end - start ;
684
+ if (!append_single_str (packet , index , start , part_len )) {
685
+ return 0 ;
686
+ }
687
+ start = ++ end ;
688
+ } while (end < name + len );
689
+
690
+ if (!append_single_str (packet , index , "arpa" , sizeof ("arpa" ) - 1 )) {
691
+ return 0 ;
692
+ }
693
+
694
+ //empty string so terminate
695
+ if (!_mdns_append_u8 (packet , index , 0 )) {
696
+ return 0 ;
697
+ }
698
+ return * index ;
699
+ }
700
+ #endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
701
+
646
702
/**
647
703
* @brief appends FQDN to a packet, incrementing the index and
648
704
* compressing the output if previous occurrence of the string (or part of it) has been found
@@ -1104,21 +1160,18 @@ static uint16_t _mdns_append_aaaa_record(uint8_t *packet, uint16_t *index, const
1104
1160
*/
1105
1161
static uint16_t _mdns_append_question (uint8_t * packet , uint16_t * index , mdns_out_question_t * q )
1106
1162
{
1107
- const char * str [6 ];
1108
- uint8_t str_index = 0 ;
1109
1163
uint8_t part_length ;
1110
- char * host_dup = NULL ; // need to duplicate host-name for some cases
1164
+ #ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
1111
1165
if (q -> host && strstr (q -> host , "in-addr" )) {
1112
- host_dup = strdup (q -> host );
1113
- char * rest = NULL ;
1114
- for (char * p = strtok_r (host_dup , "." , & rest ); p != NULL ; p = strtok_r (NULL , "." , & rest )) {
1115
- str [str_index ++ ] = p ;
1116
- }
1117
- if (q -> domain ) {
1118
- str [str_index ++ ] = q -> domain ;
1166
+ part_length = append_fqdn_dots (packet , index , q -> host , false);
1167
+ if (!part_length ) {
1168
+ return 0 ;
1119
1169
}
1120
-
1121
- } else {
1170
+ } else
1171
+ #endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
1172
+ {
1173
+ const char * str [4 ];
1174
+ uint8_t str_index = 0 ;
1122
1175
if (q -> host ) {
1123
1176
str [str_index ++ ] = q -> host ;
1124
1177
}
@@ -1131,19 +1184,14 @@ static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out
1131
1184
if (q -> domain ) {
1132
1185
str [str_index ++ ] = q -> domain ;
1133
1186
}
1134
-
1135
- }
1136
-
1137
-
1138
- part_length = _mdns_append_fqdn (packet , index , str , str_index , MDNS_MAX_PACKET_SIZE );
1139
- if (!part_length ) {
1140
- free (host_dup );
1141
- return 0 ;
1187
+ part_length = _mdns_append_fqdn (packet , index , str , str_index , MDNS_MAX_PACKET_SIZE );
1188
+ if (!part_length ) {
1189
+ return 0 ;
1190
+ }
1142
1191
}
1143
1192
1144
1193
part_length += _mdns_append_u16 (packet , index , q -> type );
1145
1194
part_length += _mdns_append_u16 (packet , index , q -> unicast ? 0x8001 : 0x0001 );
1146
- free (host_dup );
1147
1195
return part_length ;
1148
1196
}
1149
1197
@@ -1221,62 +1269,36 @@ static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_h
1221
1269
return num_records ;
1222
1270
}
1223
1271
1224
- static uint16_t _mdns_append_rev_ptr_record (uint8_t * packet , uint16_t * index , const char * name , bool flush , bool bye )
1272
+ #ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
1273
+ /**
1274
+ * @brief Appends reverse lookup PTR record
1275
+ */
1276
+ static uint8_t _mdns_append_reverse_ptr_record (uint8_t * packet , uint16_t * index , const char * name )
1225
1277
{
1226
- const char * str [6 ];
1227
- int i = 0 ;
1228
-
1229
1278
if (strstr (name , "in-addr" ) == NULL ) {
1230
1279
return 0 ;
1231
1280
}
1232
- char * host = strdup (name );
1233
- char * rest = NULL ;
1234
- for (char * p = strtok_r (host , "." , & rest ); p != NULL ; p = strtok_r (NULL , "." , & rest )) {
1235
- str [i ++ ] = p ;
1236
- }
1237
- str [i ++ ] = "arpa" ;
1238
- uint16_t record_length = 0 ;
1239
- uint8_t part_length ;
1240
1281
1241
- part_length = _mdns_append_fqdn (packet , index , str , i , MDNS_MAX_PACKET_SIZE );
1242
- if (!part_length ) {
1282
+ if (!append_fqdn_dots (packet , index , name , false)) {
1243
1283
return 0 ;
1244
1284
}
1245
- record_length += part_length ;
1246
1285
1247
- part_length = _mdns_append_type (packet , index , MDNS_ANSWER_PTR , false, bye ? 0 : MDNS_ANSWER_PTR_TTL );
1248
- if (!part_length ) {
1286
+ if (!_mdns_append_type (packet , index , MDNS_ANSWER_PTR , false, 10 /* TTL set to 10s*/ )) {
1249
1287
return 0 ;
1250
1288
}
1251
- record_length += part_length ;
1252
1289
1253
- uint16_t data_len_location = * index - 2 ;
1254
- str [0 ] = _mdns_self_host .hostname ;
1255
- str [1 ] = MDNS_DEFAULT_DOMAIN ;
1290
+ uint16_t data_len_location = * index - 2 ; /* store the position of size (2=16bis) of this record */
1291
+ const char * str [2 ] = { _mdns_self_host .hostname , MDNS_DEFAULT_DOMAIN };
1256
1292
1257
- part_length = _mdns_append_fqdn (packet , index , str , 2 , MDNS_MAX_PACKET_SIZE );
1293
+ int part_length = _mdns_append_fqdn (packet , index , str , 2 , MDNS_MAX_PACKET_SIZE );
1258
1294
if (!part_length ) {
1259
1295
return 0 ;
1260
1296
}
1261
1297
1262
1298
_mdns_set_u16 (packet , data_len_location , part_length );
1263
- record_length += part_length ;
1264
-
1265
- return record_length ;
1266
- }
1267
-
1268
-
1269
- static uint8_t _mdns_append_reverse_ptr_record (uint8_t * packet , uint16_t * index , const char * name , bool flush , bool bye )
1270
- {
1271
- uint8_t appended_answers = 0 ;
1272
-
1273
- if (_mdns_append_rev_ptr_record (packet , index , name , flush , bye ) <= 0 ) {
1274
- return appended_answers ;
1275
- }
1276
- appended_answers ++ ;
1277
-
1278
- return appended_answers ;
1299
+ return 1 ; /* appending only 1 record */
1279
1300
}
1301
+ #endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
1280
1302
1281
1303
/**
1282
1304
* @brief Append PTR answers to packet
@@ -1316,8 +1338,10 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
1316
1338
if (answer -> type == MDNS_TYPE_PTR ) {
1317
1339
if (answer -> service ) {
1318
1340
return _mdns_append_service_ptr_answers (packet , index , answer -> service , answer -> flush , answer -> bye );
1341
+ #ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
1319
1342
} else if (answer -> host && answer -> host -> hostname && strstr (answer -> host -> hostname , "in-addr" )) {
1320
- return _mdns_append_reverse_ptr_record (packet , index , answer -> host -> hostname , answer -> flush , answer -> bye ) > 0 ;
1343
+ return _mdns_append_reverse_ptr_record (packet , index , answer -> host -> hostname ) > 0 ;
1344
+ #endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
1321
1345
} else {
1322
1346
return _mdns_append_ptr_record (packet , index ,
1323
1347
answer -> custom_instance , answer -> custom_service , answer -> custom_proto ,
@@ -1719,15 +1743,6 @@ static bool _mdns_create_answer_from_service(mdns_tx_packet_t *packet, mdns_serv
1719
1743
return true;
1720
1744
}
1721
1745
1722
- static bool _mdns_create_answer_from_reverse_query (mdns_tx_packet_t * packet , const char * hostname , bool send_flush )
1723
- {
1724
- mdns_host_item_t * host = mdns_get_host_item (hostname );
1725
- if (!_mdns_alloc_answer (& packet -> answers , MDNS_TYPE_PTR , NULL , host , send_flush , false)) {
1726
- return false;
1727
- }
1728
- return true;
1729
- }
1730
-
1731
1746
static bool _mdns_create_answer_from_hostname (mdns_tx_packet_t * packet , const char * hostname , bool send_flush )
1732
1747
{
1733
1748
mdns_host_item_t * host = mdns_get_host_item (hostname );
@@ -1812,18 +1827,24 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
1812
1827
_mdns_free_tx_packet (packet );
1813
1828
return ;
1814
1829
}
1830
+ #ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
1815
1831
} else if (q -> type == MDNS_TYPE_PTR ) {
1816
- if (! _mdns_create_answer_from_reverse_query ( packet , q -> host , send_flush )) {
1817
- _mdns_free_tx_packet ( packet );
1832
+ mdns_host_item_t * host = mdns_get_host_item ( q -> host );
1833
+ if (! _mdns_alloc_answer ( & packet -> answers , MDNS_TYPE_PTR , NULL , host , send_flush , false)) {
1818
1834
return ;
1819
1835
}
1836
+ #endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
1820
1837
} else if (!_mdns_alloc_answer (& packet -> answers , q -> type , NULL , NULL , send_flush , false)) {
1821
1838
_mdns_free_tx_packet (packet );
1822
1839
return ;
1823
1840
}
1824
1841
1825
1842
if (parsed_packet -> src_port != MDNS_SERVICE_PORT && // Repeat the queries only for "One-Shot mDNS queries"
1826
- (q -> type == MDNS_TYPE_ANY || q -> type == MDNS_TYPE_A || q -> type == MDNS_TYPE_AAAA || q -> type == MDNS_TYPE_PTR )) {
1843
+ (q -> type == MDNS_TYPE_ANY || q -> type == MDNS_TYPE_A || q -> type == MDNS_TYPE_AAAA
1844
+ #ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
1845
+ || q -> type == MDNS_TYPE_PTR
1846
+ #endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
1847
+ )) {
1827
1848
mdns_out_question_t * out_question = malloc (sizeof (mdns_out_question_t ));
1828
1849
if (out_question == NULL ) {
1829
1850
HOOK_MALLOC_FAILED ;
@@ -3042,7 +3063,11 @@ static bool _mdns_name_is_discovery(mdns_name_t *name, uint16_t type)
3042
3063
static bool _mdns_name_is_ours (mdns_name_t * name )
3043
3064
{
3044
3065
//domain have to be "local"
3045
- if (_str_null_or_empty (name -> domain ) || ( strcasecmp (name -> domain , MDNS_DEFAULT_DOMAIN ) && strcasecmp (name -> domain , "arpa" )) ) {
3066
+ if (_str_null_or_empty (name -> domain ) || ( strcasecmp (name -> domain , MDNS_DEFAULT_DOMAIN )
3067
+ #ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
3068
+ && strcasecmp (name -> domain , "arpa" )
3069
+ #endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
3070
+ ) ) {
3046
3071
return false;
3047
3072
}
3048
3073
@@ -3967,6 +3992,22 @@ static void perform_event_action(mdns_if_t mdns_if, mdns_event_actions_t action)
3967
3992
if (action & MDNS_EVENT_ANNOUNCE_IP6 ) {
3968
3993
_mdns_announce_pcb (mdns_if , MDNS_IP_PROTOCOL_V6 , NULL , 0 , true);
3969
3994
}
3995
+
3996
+ #ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
3997
+ if (action & MDNS_EVENT_IP4_REVERSE_LOOKUP ) {
3998
+ esp_netif_ip_info_t if_ip_info ;
3999
+ if (esp_netif_get_ip_info (_mdns_get_esp_netif (mdns_if ), & if_ip_info ) == ESP_OK ) {
4000
+ esp_ip4_addr_t * ip = & if_ip_info .ip ;
4001
+ char * reverse_query_name = NULL ;
4002
+ if (asprintf (& reverse_query_name , "%d.%d.%d.%d.in-addr" ,
4003
+ esp_ip4_addr4_16 (ip ), esp_ip4_addr3_16 (ip ),
4004
+ esp_ip4_addr2_16 (ip ), esp_ip4_addr1_16 (ip )) > 0 && reverse_query_name ) {
4005
+ ESP_LOGD (TAG , "Registered reverse query: %s.arpa" , reverse_query_name );
4006
+ _mdns_delegate_hostname_add (reverse_query_name , NULL );
4007
+ }
4008
+ }
4009
+ }
4010
+ #endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
3970
4011
}
3971
4012
3972
4013
/**
0 commit comments