DNS resolve programmatically?

I am using:

nRF52840DK
nRF5 SDK for Thread and Zigbee v4.1.0
CLI example with added code
Border Router on Raspberry Pi 3+

Using the CLI, I can get an IPv6 address for a remote website:

>  dns resolve ipv4.google.com fdde:ad00:beef:0:3467:65f8:4139:dad5
> DNS response for ipv4.google.com - 64:ff9b:0:0:0:0:8efb:6f8a TTL: 60
Done

I need to do this in the firmware, so tried the following:

otIp6Address m_mesh_address;
otIp6Address m_host_address;
const char GOOGLE[] = "ipv4.google.com";

void dns_response_handler(void * aContext,  const char * aHostname, const otIp6Address *aAddress, uint32_t aTtl, otError aResult)
{
    char ipv6_str[40] = {0};
    if ((aResult == OT_ERROR_NONE) && (aAddress != NULL))
        udp_address_to_string(ipv6_str, aAddress, sizeof(ipv6_str));
    NRF_LOG_INFO("DNS response: %s %s TTL %d error %d\r\n", aHostname, ipv6_str, aTtl, aResult);
}

static void thread_state_changed_callback(uint32_t flags, void * p_context)
{
    bool addr_found = false;
    otSockAddr sock_addr;
    otOperationalDataset dataset;

    otDeviceRole role = otThreadGetDeviceRole(p_context);

    NRF_LOG_INFO("State changed! Flags: 0x%08x Current role: %d\r\n",
                 flags, otThreadGetDeviceRole(p_context));


    if (role >= OT_DEVICE_ROLE_CHILD)
    {
        otError err;

        err = otDatasetGetActive( thread_ot_instance_get(), &dataset);

        // Mesh local ipv6 address
        for (const otNetifAddress *address = otIp6GetUnicastAddresses(thread_ot_instance_get()); address; address = address->mNext)
        {
            // Mesh local only, not RLOC address
            if ((address->mAddress.mFields.m8[0] == 0xfd) && !address->mRloc && !addr_found)
            {
                addr_found = true;
                sock_addr.mAddress = address->mAddress;
                m_mesh_address = address->mAddress;
            }
        }

     
        if (addr_found)
        {
    
            for (int i=0; i<OT_MESH_LOCAL_PREFIX_SIZE; i++)
                m_host_address.mFields.m8[i] = dataset.mMeshLocalPrefix.m8[i];  // copy mesh local prefix

            // Raspberry Pi
            m_host_address.mFields.m16[4] = 0x0000;
            m_host_address.mFields.m16[5] = 0x6734;
            m_host_address.mFields.m16[6] = 0xf865;
            m_host_address.mFields.m16[7] = 0xd5da;                             // RLOC16 of border router
 
            otDnsQuery query;
            otMessageInfo   msgInfo;

            msgInfo.mPeerAddr = m_host_address;
            msgInfo.mPeerPort = OT_DNS_DEFAULT_SERVER_PORT;     //53
            msgInfo.mIsHostInterface = false;
            msgInfo.mAllowZeroHopLimit = false;
            msgInfo.mSockAddr = m_mesh_address;
            msgInfo.mSockPort = 0;


            query.mHostname = GOOGLE;
            query.mMessageInfo = &msgInfo;
            query.mNoRecursion = false;

            err =  otDnsClientQuery(thread_ot_instance_get(),
                         &query,
                         dns_response_handler,
                         NULL);

            NRF_LOG_INFO("DnsClientQuery(): err = %d\n\r", err);
        }
    }
}

The result is:

<info> app: State changed! Flags: 0x00001035 Current role: 1



<info> app: State changed! Flags: 0x00801064 Current role: 3



<info> app: DnsClientQuery(): err = 0



<info> app: State changed! Flags: 0x00000200 Current role: 3



<info> app: DnsClientQuery(): err = 0



<info> app: DNS response: ipv4.google.com `ÿ ÿ + TTL 0 error 28



<info> app: DNS response: ipv4.google.com `ÿ ÿ + TTL 0 error 28

Error 28 is a response timeout.

How do you get an IPV6 address in firmware?  Is there an example? (I couldn't find one).

Thanks,

Mary

Parents Reply Children
Related