Domino on Linux/Unix, Troubleshooting, Best Practices, Tips and more ...

 
alt

Daniel Nashed

 

    Getting DNS TXT records in C

    Daniel Nashed  10 May 2021 11:37:10


    Getting the TXT records for a DNS entries is important today (checking SPF records, ACME challenges, DMARC records .. ).

    But this isn't part of the standard resolver processes you would use for normal DNS queries.


    I have been looking for TXT record resolution for a while and finally found it in one of my oldest IT books "DNS & Bind".
    Even there wasn't a complete example and I needed to do a lot of research this morning.

    The result doesn't look that complicated. But the devil is still in the detail.
    This functionality has been always there and you would need it also to query MX records for example.

    Windows implemented their own interface - DnsQuery(). The call also looks simple but I didn't find any example or full documentation for the call.
    My new functionality in SpamGeek will be Linux only for now -- Because "libspf" is also only available for Linux ..

    In case you need a routine to get the DNS TXT records, here is an example that uses the newer thread safe interface.

    It needs to init a structure per thread. Or like in my example code per request.
    The routine doesn't have all error logging and is more an example.


    -- Daniel


    #include


    int GetTxtRecord (char *pszDomain)
    {
      unsigned char Buffer[8000]   = {0};
      unsigned char Result[2048]   = {0};
      const unsigned char *pResult = NULL;
      struct __res_state ResState  = {0};
      ns_msg nsMsg = {0};
      ns_rr  rr;

      int  type     = 0;
      int  ret      = 0;
      int  size     = 0;
      int  len      = 0;
      int  count    0;
      int  i        = 0;
      int  res_init = 0;

      ret = res_ninit (&ResState);

      if (ret)
      {
        printf ("error initializing resolver\n");
        goto close;
      }
      res_init = 1;

      memset(Buffer, 0, sizeof (Buffer));

      size = res_nquery (&ResState, pszDomain, C_IN, T_TXT, Buffer, sizeof(Buffer)-1);

      if (0 == size)
        goto close;

      ret = ns_initparse (Buffer, size, &nsMsg);

      if (ret)
        goto close;

      count = ns_msg_count (nsMsg, ns_s_an);

      for (i=0; i
      {
        ret = ns_parserr (&nsMsg, ns_s_an, i , &rr);

        if (ret)
          goto close;

        type = ns_rr_type (rr);
        if (ns_t_txt == type)
        {
          len = ns_rr_rdlen (rr);
          pResult = ns_rr_rdata (rr);

          if ( (len>1) && (len < sizeof(Result)) )
          {
            len--;
            memcpy (Result, pResult+1, len);
            Result[len] = '\0';
            printf ("#%d [%s]\n", i, Result);
          }
       }

      } /* for */

    close:

      if (res_init)
        res_nclose (&ResState);

      return ret;
    }

    Links

      Archives


      • [IBM Lotus Domino]
      • [Domino on Linux]
      • [Nash!Com]
      • [Daniel Nashed]