@@ -493,11 +493,11 @@ void MDNSResponder::_parsePacket(){
493493 return ;
494494 }
495495
496- int numAnswers = packetHeader[3 ];
496+ int numAnswers = packetHeader[3 ] + packetHeader[ 5 ] ;
497497 // Assume that the PTR answer always comes first and that it is always accompanied by a TXT, SRV, AAAA (optional) and A answer in the same packet.
498498 if (numAnswers < 4 ) {
499499#ifdef MDNS_DEBUG_RX
500- Serial.println (" Expected a packet with 4 answers, returning " );
500+ Serial.printf (" Expected a packet with 4 or more answers, got %u \n " , numAnswers );
501501#endif
502502 _conn->flush ();
503503 return ;
@@ -510,11 +510,14 @@ void MDNSResponder::_parsePacket(){
510510 bool serviceMatch = false ;
511511 MDNSAnswer *answer;
512512 uint8_t partsCollected = 0 ;
513+ uint8_t stringsRead = 0 ;
514+
515+ answerHostName[0 ] = ' \0 ' ;
513516
514517 // Clear answer list
515518 if (_newQuery) {
516- int numAnswers = _getNumAnswers ();
517- for (int n = numAnswers - 1 ; n >= 0 ; n--) {
519+ int oldAnswers = _getNumAnswers ();
520+ for (int n = oldAnswers - 1 ; n >= 0 ; n--) {
518521 answer = _getAnswerFromIdx (n);
519522 os_free (answer->hostname );
520523 os_free (answer);
@@ -526,21 +529,29 @@ void MDNSResponder::_parsePacket(){
526529
527530 while (numAnswers--) {
528531 // Read name
532+ stringsRead = 0 ;
529533 do {
530534 tmp8 = _conn_read8 ();
531535 if (tmp8 & 0xC0 ) { // Compressed pointer (not supported)
532536 tmp8 = _conn_read8 ();
533537 break ;
534538 }
535- if (tmp8 == 0x00 ) { // Énd of name
539+ if (tmp8 == 0x00 ) { // End of name
536540 break ;
537541 }
542+ if (stringsRead > 3 ){
543+ #ifdef MDNS_DEBUG_RX
544+ Serial.println (" failed to read the response name" );
545+ #endif
546+ _conn->flush ();
547+ return ;
548+ }
538549 _conn_readS (serviceName, tmp8);
539550 serviceName[tmp8] = ' \0 ' ;
540551#ifdef MDNS_DEBUG_RX
541552 Serial.printf (" %d " , tmp8);
542553 for (int n = 0 ; n < tmp8; n++) {
543- Serial.printf (" %02x " , serviceName[n]);
554+ Serial.printf (" %c " , serviceName[n]);
544555 }
545556 Serial.println ();
546557#endif
@@ -552,23 +563,41 @@ void MDNSResponder::_parsePacket(){
552563#endif
553564 }
554565 }
566+ stringsRead++;
555567 } while (true );
556568
557569 uint16_t answerType = _conn_read16 (); // Read type
558570 uint16_t answerClass = _conn_read16 (); // Read class
559571 uint32_t answerTtl = _conn_read32 (); // Read ttl
560572 uint16_t answerRdlength = _conn_read16 (); // Read rdlength
561573
574+ if (answerRdlength > 255 ){
575+ if (answerType == MDNS_TYPE_TXT && answerRdlength < 1460 ){
576+ while (--answerRdlength) _conn->read ();
577+ } else {
578+ #ifdef MDNS_DEBUG_RX
579+ Serial.printf (" Data len too long! %u\n " , answerRdlength);
580+ #endif
581+ _conn->flush ();
582+ return ;
583+ }
584+ }
585+
562586#ifdef MDNS_DEBUG_RX
563587 Serial.printf (" type: %04x rdlength: %d\n " , answerType, answerRdlength);
564588#endif
565589
566590 if (answerType == MDNS_TYPE_PTR) {
567591 partsCollected |= 0x01 ;
568592 _conn_readS (hostName, answerRdlength); // Read rdata
593+ if (hostName[answerRdlength-2 ] & 0xc0 ){
594+ memcpy (answerHostName, hostName+1 , answerRdlength-3 );
595+ answerHostName[answerRdlength-3 ] = ' \0 ' ;
596+ }
569597#ifdef MDNS_DEBUG_RX
598+ Serial.printf (" PTR %d " , answerRdlength);
570599 for (int n = 0 ; n < answerRdlength; n++) {
571- Serial.printf (" %02x " , hostName[n]);
600+ Serial.printf (" %c " , hostName[n]);
572601 }
573602 Serial.println ();
574603#endif
@@ -578,8 +607,9 @@ void MDNSResponder::_parsePacket(){
578607 partsCollected |= 0x02 ;
579608 _conn_readS (hostName, answerRdlength); // Read rdata
580609#ifdef MDNS_DEBUG_RX
610+ Serial.printf (" TXT %d " , answerRdlength);
581611 for (int n = 0 ; n < answerRdlength; n++) {
582- Serial.printf (" %02x " , hostName[n]);
612+ Serial.printf (" %c " , hostName[n]);
583613 }
584614 Serial.println ();
585615#endif
@@ -594,14 +624,16 @@ void MDNSResponder::_parsePacket(){
594624 // Read hostname
595625 tmp8 = _conn_read8 ();
596626 if (tmp8 & 0xC0 ) { // Compressed pointer (not supported)
627+ #ifdef MDNS_DEBUG_RX
597628 Serial.println (" Skipping compressed pointer" );
629+ #endif
598630 tmp8 = _conn_read8 ();
599631 }
600632 else {
601633 _conn_readS (answerHostName, tmp8);
602634 answerHostName[tmp8] = ' \0 ' ;
603635#ifdef MDNS_DEBUG_RX
604- Serial.printf (" %d " , tmp8);
636+ Serial.printf (" SRV %d " , tmp8);
605637 for (int n = 0 ; n < tmp8; n++) {
606638 Serial.printf (" %02x " , answerHostName[n]);
607639 }
@@ -621,7 +653,7 @@ void MDNSResponder::_parsePacket(){
621653 }
622654 else {
623655#ifdef MDNS_DEBUG_RX
624- Serial.printf (" Ignoring unsupported type %d \n " , tmp8);
656+ Serial.printf (" Ignoring unsupported type %02x \n " , tmp8);
625657#endif
626658 for (int n = 0 ; n < answerRdlength; n++)
627659 (void )_conn_read8 ();
@@ -654,6 +686,8 @@ void MDNSResponder::_parsePacket(){
654686 }
655687 answer->hostname = (char *)os_malloc (strlen (answerHostName) + 1 );
656688 os_strcpy (answer->hostname , answerHostName);
689+ _conn->flush ();
690+ return ;
657691 }
658692 }
659693
@@ -663,7 +697,7 @@ void MDNSResponder::_parsePacket(){
663697
664698 // PARSE REQUEST NAME
665699
666- hostNameLen = _conn_read8 ();
700+ hostNameLen = _conn_read8 () % 255 ;
667701 _conn_readS (hostName, hostNameLen);
668702 hostName[hostNameLen] = ' \0 ' ;
669703
@@ -685,7 +719,7 @@ void MDNSResponder::_parsePacket(){
685719 }
686720
687721 if (!serviceParsed){
688- serviceNameLen = _conn_read8 ();
722+ serviceNameLen = _conn_read8 () % 255 ;
689723 _conn_readS (serviceName, serviceNameLen);
690724 serviceName[serviceNameLen] = ' \0 ' ;
691725
@@ -718,7 +752,7 @@ void MDNSResponder::_parsePacket(){
718752 }
719753
720754 if (!protoParsed){
721- protoNameLen = _conn_read8 ();
755+ protoNameLen = _conn_read8 () % 255 ;
722756 _conn_readS (protoName, protoNameLen);
723757 protoName[protoNameLen] = ' \0 ' ;
724758 if (protoNameLen == 4 && protoName[0 ] == ' _' ){
@@ -740,7 +774,7 @@ void MDNSResponder::_parsePacket(){
740774
741775 if (!localParsed){
742776 char localName[32 ];
743- uint8_t localNameLen = _conn_read8 ();
777+ uint8_t localNameLen = _conn_read8 () % 31 ;
744778 _conn_readS (localName, localNameLen);
745779 localName[localNameLen] = ' \0 ' ;
746780 tmp = _conn_read8 ();
0 commit comments