(root)/
glibc-2.38/
resolv/
tst-resolv-binary.c
       1  /* Test handling of binary domain names with res_send.
       2     Copyright (C) 2018-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <resolv.h>
      20  #include <string.h>
      21  #include <support/check.h>
      22  #include <support/resolv_test.h>
      23  
      24  static void
      25  response (const struct resolv_response_context *ctx,
      26            struct resolv_response_builder *b,
      27            const char *qname, uint16_t qclass, uint16_t qtype)
      28  {
      29    TEST_COMPARE (qclass, C_IN);
      30    TEST_COMPARE (qtype, T_TXT);
      31    TEST_VERIFY (strlen (qname) <= 255);
      32  
      33    struct resolv_response_flags flags = { 0 };
      34    resolv_response_init (b, flags);
      35    resolv_response_add_question (b, qname, qclass, qtype);
      36    resolv_response_section (b, ns_s_an);
      37    resolv_response_open_record (b, qname, qclass, T_TXT, 0x12345678);
      38    unsigned char qnamelen = strlen (qname);
      39    resolv_response_add_data (b, &qnamelen, 1);
      40    resolv_response_add_data (b, qname, qnamelen);
      41    resolv_response_close_record (b);
      42  }
      43  
      44  static int
      45  do_test (void)
      46  {
      47    struct resolv_test *aux = resolv_test_start
      48      ((struct resolv_redirect_config)
      49       {
      50         .response_callback = response,
      51       });
      52  
      53    for (int b = 0; b <= 255; ++b)
      54      {
      55        unsigned char query[] =
      56          {
      57            b, b,                 /* Transaction ID.  */
      58            1, 0,                 /* Query with RD flag.  */
      59            0, 1,                 /* One question.  */
      60            0, 0, 0, 0, 0, 0,     /* The other sections are empty.  */
      61            1, b, 7, 'e', 'x', 'a', 'm', 'p', 'l', 'e', 0,
      62            0, T_TXT,             /* TXT query.  */
      63            0, 1,                 /* Class IN.  */
      64          };
      65        unsigned char response[512];
      66        int ret = res_send (query, sizeof (query), response, sizeof (response));
      67  
      68        char expected_name[20];
      69        /* The name is uncompressed in the query, so we can reference it
      70           directly.  */
      71        TEST_VERIFY_EXIT (ns_name_ntop (query + 12, expected_name,
      72                                        sizeof (expected_name)) >= 0);
      73        TEST_COMPARE (ret,
      74                      (ssize_t) sizeof (query)
      75                      + 2             /* Compression reference.  */
      76                      + 2 + 2 + 4 + 2 /* Type, class, TTL, RDATA length.  */
      77                      + 1             /* Pascal-style string length.  */
      78                      + strlen (expected_name));
      79  
      80        /* Mark as answer, with recursion available, and one answer.  */
      81        query[2] = 0x81;
      82        query[3] = 0x80;
      83        query[7] = 1;
      84  
      85        /* Prefix of the response must match the query.  */
      86        TEST_COMPARE (memcmp (response, query, sizeof (query)), 0);
      87  
      88        /* The actual answer follows, starting with the compression
      89           reference.  */
      90        unsigned char *p = response + sizeof (query);
      91        TEST_COMPARE (*p++, 0xc0);
      92        TEST_COMPARE (*p++, 0x0c);
      93  
      94        /* Type and class.  */
      95        TEST_COMPARE (*p++, 0);
      96        TEST_COMPARE (*p++, T_TXT);
      97        TEST_COMPARE (*p++, 0);
      98        TEST_COMPARE (*p++, C_IN);
      99  
     100        /* TTL.  */
     101        TEST_COMPARE (*p++, 0x12);
     102        TEST_COMPARE (*p++, 0x34);
     103        TEST_COMPARE (*p++, 0x56);
     104        TEST_COMPARE (*p++, 0x78);
     105  
     106        /* RDATA length.  */
     107        TEST_COMPARE (*p++, 0);
     108        TEST_COMPARE (*p++, 1 + strlen (expected_name));
     109  
     110        /* RDATA.  */
     111        TEST_COMPARE (*p++, strlen (expected_name));
     112        TEST_COMPARE (memcmp (p, expected_name, strlen (expected_name)), 0);
     113      }
     114  
     115    resolv_test_end (aux);
     116  
     117    return 0;
     118  }
     119  
     120  #include <support/test-driver.c>