|
44 | 44 | #include "NetworkBufferManagement.h" |
45 | 45 |
|
46 | 46 | #include <string.h> |
47 | | -#include <strings.h> |
48 | 47 |
|
49 | 48 | #if ( ipconfigUSE_DNS != 0 ) |
50 | 49 |
|
|
238 | 237 |
|
239 | 238 |
|
240 | 239 | #if ( ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_MDNS != 0 ) ) |
| 240 | + /** |
| 241 | + * @brief Local implementation of posix strncasecmp |
| 242 | + */ |
| 243 | + static int local_strncasecmp( const char * s1, |
| 244 | + const char * s2, |
| 245 | + size_t n ) |
| 246 | + { |
| 247 | + while( n-- != 0 ) |
| 248 | + { |
| 249 | + char c1 = *s1++; |
| 250 | + char c2 = *s2++; |
| 251 | + |
| 252 | + if( ( c1 >= 'A' ) && ( c1 <= 'Z' ) ) |
| 253 | + { |
| 254 | + c1 += 'a' - 'A'; |
| 255 | + } |
| 256 | + |
| 257 | + if( ( c2 >= 'A' ) && ( c2 <= 'Z' ) ) |
| 258 | + { |
| 259 | + c2 += 'a' - 'A'; |
| 260 | + } |
| 261 | + |
| 262 | + if( c1 > c2 ) |
| 263 | + { |
| 264 | + return 1; |
| 265 | + } |
| 266 | + |
| 267 | + if( c2 > c1 ) |
| 268 | + { |
| 269 | + return -1; |
| 270 | + } |
| 271 | + |
| 272 | + if( c1 == '\0' ) |
| 273 | + { |
| 274 | + break; |
| 275 | + } |
| 276 | + } |
| 277 | + |
| 278 | + return 0; |
| 279 | + } |
241 | 280 |
|
242 | 281 | /** |
243 | 282 | * @brief Compare a DNS label sequence with a dot-separated name string. |
|
349 | 388 | } |
350 | 389 |
|
351 | 390 | /* The dot string should have a segment of the same length at this point. */ |
352 | | - ulComparison = strncasecmp( ( char const * ) pcDnsSegment, pcDotSegment, uxSegmentLength ); |
| 391 | + ulComparison = local_strncasecmp( ( char const * ) pcDnsSegment, pcDotSegment, uxSegmentLength ); |
353 | 392 |
|
354 | 393 | if( ulComparison != 0 ) |
355 | 394 | { |
|
431 | 470 | * - pxDNSRecords and uxDNSRecordCount |
432 | 471 | * |
433 | 472 | * @param[in,out] xSet a set of variables that are shared among the helper functions. |
434 | | - * @param[in] pxEndPoint The end-point on which the DNS message was received. |
435 | | - * Necessary when LLMNR/MDNS are enabled, and IPv4_BACKWARD_COMPATIBLE is 0. |
| 473 | + * @param[in] pxEndPoint The endpoint on which the DNS message was received. |
| 474 | + * Necessary when LLMNR/MDNS are enabled |
436 | 475 | * Otherwise may be NULL. |
437 | 476 | * @return pdTRUE if everything went okay |
438 | 477 | */ |
|
442 | 481 | UBaseType_t x; |
443 | 482 | size_t uxResult; |
444 | 483 |
|
445 | | - ( void ) pxEndPoint; |
446 | 484 | #if ( ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_MDNS == 1 ) ) |
447 | | - #if ( ipconfigIPv4_BACKWARD_COMPATIBLE == 0 ) |
448 | | - NetworkEndPoint_t xEndPoint; |
449 | | - configASSERT( pxEndPoint != NULL ); |
| 485 | + NetworkEndPoint_t xEndPoint; |
| 486 | + configASSERT( pxEndPoint != NULL ); |
450 | 487 |
|
451 | | - /* Make a copy of the end-point because xApplicationDNSQueryHook() is allowed |
452 | | - * to write into it. */ |
453 | | - ( void ) memcpy( &( xEndPoint ), pxEndPoint, sizeof( xEndPoint ) ); |
454 | | - #else |
455 | | - #endif |
| 488 | + /* Make a copy of the end-point because xApplicationDNSQueryHook() is allowed |
| 489 | + * to write into it. */ |
| 490 | + ( void ) memcpy( &( xEndPoint ), pxEndPoint, sizeof( xEndPoint ) ); |
456 | 491 |
|
457 | 492 | #if ( ipconfigDNSQuery_BACKWARD_COMPATIBLE == 1 ) |
458 | 493 | xSet->uxDNSRecordCount = 0; |
|
470 | 505 | #endif /* if ( ipconfigDNSQuery_BACKWARD_COMPATIBLE == 1 ) */ |
471 | 506 | #endif /* if ( ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_MDNS == 1 ) ) */ |
472 | 507 |
|
| 508 | + ( void ) pxEndPoint; |
| 509 | + |
473 | 510 | for( x = 0U; x < xSet->usQuestions; x++ ) |
474 | 511 | { |
475 | 512 | #if ( ( ipconfigUSE_LLMNR == 1 ) || ( ipconfigUSE_MDNS == 1 ) ) |
|
517 | 554 | xSet->usType = usChar2u16( xSet->pucByte ); |
518 | 555 | xSet->usClass = usChar2u16( &( xSet->pucByte[ 2 ] ) ); |
519 | 556 |
|
| 557 | + /* This should have been set by now. */ |
| 558 | + configASSERT( xSet->pxDNSRecords != NULL ); |
| 559 | + |
520 | 560 | #if ( ( ipconfigDNSQuery_BACKWARD_COMPATIBLE == 1 ) ) |
521 | 561 | { |
522 | 562 | ( void ) i; |
523 | | - /* This should have been set in the main DNS function */ |
524 | | - configASSERT( xSet->pxDNSRecords != NULL ); |
525 | 563 |
|
526 | 564 | if( x == 0U ) |
527 | 565 | { |
|
535 | 573 | { |
536 | 574 | xSet->xDNSRecordsMatched = pdTRUE; |
537 | 575 | #if ( ( ipconfigUSE_IPv6 != 0 ) ) |
538 | | - if( ( xSet->usType == dnsTYPE_AAAA_HOST ) || ( xSet->usType == dnsTYPE_ANY_HOST ) ) |
| 576 | + if( |
| 577 | + ( xEndPoint.bits.bIPv6 != pdFALSE ) && |
| 578 | + ( ( xSet->usType == dnsTYPE_AAAA_HOST ) || |
| 579 | + ( xSet->usType == dnsTYPE_ANY_HOST ) ) ) |
539 | 580 | { |
540 | 581 | xSet->pxDNSRecords[ xSet->uxDNSRecordCount++ ] = |
541 | 582 | ( DNSRecord_t ) { |
|
544 | 585 | .uxIncludeInAnswer = pdTRUE, |
545 | 586 | }; |
546 | 587 | } |
547 | | - #endif |
| 588 | + #endif /* if ( ( ipconfigUSE_IPv6 != 0 ) ) */ |
548 | 589 | #if ( ( ipconfigUSE_IPv4 != 0 ) ) |
549 | | - if( ( xSet->usType == dnsTYPE_A_HOST ) || ( xSet->usType == dnsTYPE_ANY_HOST ) ) |
| 590 | + if( |
| 591 | + ( xEndPoint.ipv4_settings.ulIPAddress != 0U ) && |
| 592 | + ( ( xSet->usType == dnsTYPE_A_HOST ) || |
| 593 | + ( xSet->usType == dnsTYPE_ANY_HOST ) ) ) |
550 | 594 | { |
551 | 595 | xSet->pxDNSRecords[ xSet->uxDNSRecordCount++ ] = |
552 | 596 | ( DNSRecord_t ) { |
|
555 | 599 | .uxIncludeInAnswer = pdTRUE, |
556 | 600 | }; |
557 | 601 | } |
558 | | - #endif |
| 602 | + #endif /* if ( ( ipconfigUSE_IPv4 != 0 ) ) */ |
559 | 603 | } |
560 | 604 | } |
561 | 605 | } |
|
581 | 625 | break; |
582 | 626 |
|
583 | 627 | default: |
584 | | - FreeRTOS_printf( ( "DNS_ParseDNSReply: Unsupported record type %u\n", pRecord->usRecordType ) ); |
| 628 | + FreeRTOS_printf( ( "parseDNSQuestions: Unsupported record type %u\n", pRecord->usRecordType ) ); |
585 | 629 | /* Unsupported record type. Skip. */ |
586 | 630 | continue; |
587 | 631 | } |
|
595 | 639 |
|
596 | 640 | if( ( xTypeMatch == pdTRUE ) && ( xNameMatch == pdTRUE ) ) |
597 | 641 | { |
| 642 | + if( ( pRecord->usRecordType == dnsTYPE_A_HOST ) && ( xEndPoint.ipv4_settings.ulIPAddress == 0U ) ) |
| 643 | + { |
| 644 | + FreeRTOS_printf( ( "parseDNSQuestions: No IPV4 address, skipping A record even though it matches.\n" ) ); |
| 645 | + continue; |
| 646 | + } |
| 647 | + |
| 648 | + if( ( pRecord->usRecordType == dnsTYPE_AAAA_HOST ) && ( xEndPoint.bits.bIPv6 == pdFALSE ) ) |
| 649 | + { |
| 650 | + FreeRTOS_printf( ( "parseDNSQuestions: No IPV6 address, skipping AAAA record even though it matches.\n" ) ); |
| 651 | + continue; |
| 652 | + } |
| 653 | + |
598 | 654 | pRecord->uxIncludeInAnswer = pdTRUE; |
599 | 655 | xSet->xDNSRecordsMatched = pdTRUE; |
600 | 656 | } |
|
777 | 833 | UBaseType_t const uxUDPOffset = ( UBaseType_t ) ( pucUDPPayloadBuffer - pxNetworkBuffer->pucEthernetBuffer ); |
778 | 834 | UBaseType_t uxExtraSize = 0; |
779 | 835 | UBaseType_t uxDataLength; |
780 | | - UBaseType_t pxNumAnswers = 0; |
| 836 | + UBaseType_t uxNumAnswers = 0; |
781 | 837 | uint8_t * pucNewBuffer = NULL; |
782 | 838 | uint8_t * start_of_dns_answers; |
783 | 839 | UBaseType_t uxIsLLMNR; |
784 | | - BaseType_t usLength; |
| 840 | + BaseType_t uxLength; |
785 | 841 | configASSERT( ( uxUDPOffset == ipUDP_PAYLOAD_OFFSET_IPv4 ) || ( uxUDPOffset == ipUDP_PAYLOAD_OFFSET_IPv6 ) ); |
786 | 842 |
|
787 | 843 | uxDataLength = uxBufferLength + |
|
799 | 855 | continue; |
800 | 856 | } |
801 | 857 |
|
802 | | - pxNumAnswers++; |
| 858 | + uxNumAnswers++; |
803 | 859 | uxExtraSize += strlen( pRecord->pcName ) + 2; /* Name */ |
804 | 860 | uxExtraSize += 2; /* Type */ |
805 | 861 | uxExtraSize += 2; /* Class */ |
|
891 | 947 | } |
892 | 948 |
|
893 | 949 | /* We leave 'usIdentifier' and 'usQuestions' untouched */ |
894 | | - vSetField16( xSet.pxDNSMessageHeader, DNSMessage_t, usFlags, dnsLLMNR_FLAGS_IS_RESPONSE ); /* Set the response flag */ |
895 | | - vSetField16( xSet.pxDNSMessageHeader, DNSMessage_t, usAnswers, pxNumAnswers ); |
896 | | - vSetField16( xSet.pxDNSMessageHeader, DNSMessage_t, usAuthorityRRs, 0 ); /* No authority */ |
| 950 | + vSetField16( |
| 951 | + xSet.pxDNSMessageHeader, |
| 952 | + DNSMessage_t, |
| 953 | + usFlags, |
| 954 | + xSet.usPortNumber == ipLLMNR_PORT ? dnsLLMNR_FLAGS_IS_RESPONSE : dnsMDNS_FLAGS_IS_RESPONSE ); /* Set the response flag */ |
| 955 | + vSetField16( xSet.pxDNSMessageHeader, DNSMessage_t, usAnswers, uxNumAnswers ); |
| 956 | + vSetField16( xSet.pxDNSMessageHeader, DNSMessage_t, usAuthorityRRs, 0 ); /* No authority */ |
897 | 957 | vSetField16( xSet.pxDNSMessageHeader, DNSMessage_t, usAdditionalRRs, 0 ); |
898 | 958 |
|
899 | 959 | start_of_dns_answers = xSet.pucByte; |
|
972 | 1032 |
|
973 | 1033 | case dnsTYPE_TXT: |
974 | 1034 | { |
975 | | - size_t xTextLength; |
976 | | - vSetField16( middle, MDNSResponseMiddle_t, usDataLength, strlen( record->xData.pcTxtRecord ) + 1 ); |
977 | | - xSet.pucByte += sizeof( *middle ); |
978 | | - xTextLength = strlen( record->xData.pcTxtRecord ); |
| 1035 | + size_t xTextLength = strlen( record->xData.pcTxtRecord ); |
979 | 1036 |
|
980 | 1037 | if( xTextLength > 255 ) |
981 | 1038 | { |
|
985 | 1042 | break; |
986 | 1043 | } |
987 | 1044 |
|
| 1045 | + vSetField16( middle, MDNSResponseMiddle_t, usDataLength, strlen( record->xData.pcTxtRecord ) + 1 ); |
| 1046 | + xSet.pucByte += sizeof( *middle ); |
988 | 1047 | *xSet.pucByte++ = ( uint8_t ) xTextLength; |
989 | 1048 | memcpy( xSet.pucByte, record->xData.pcTxtRecord, xTextLength ); |
990 | 1049 | xSet.pucByte += xTextLength; |
|
1021 | 1080 | vSetField16( xSet.pxDNSMessageHeader, DNSMessage_t, usQuestions, 0 ); |
1022 | 1081 | } |
1023 | 1082 |
|
1024 | | - usLength = ( BaseType_t ) ( xSet.pucByte - pucNewBuffer ); |
1025 | | - prepareReplyDNSMessage( pxNetworkBuffer, usLength ); |
| 1083 | + uxLength = ( BaseType_t ) ( xSet.pucByte - pucNewBuffer ); |
| 1084 | + prepareReplyDNSMessage( pxNetworkBuffer, uxLength ); |
1026 | 1085 | /* This function will fill in the eth addresses and send the packet */ |
1027 | 1086 | vReturnEthernetFrame( pxNetworkBuffer, pdFALSE ); |
1028 | 1087 | } |
|
0 commit comments