DNS client on STM32 Nucleo and W5100

Posted on 2015/12/13

0


I am still working on a device consisting of STM32 Nucleo F103RB with a W5100 Ethernet shield. This time I included a DNS client, so that the device can connect to a server by knowing its name. The name resolving can be invoked by using the POSIX functions getaddrinfo and gethostbyname.

nucleo_w5100

STM32 Nucleo connected with Ethernet shield.

DNS queries can have different strategies; the details are specified in RFC1034 and RFC1035 The only strategy that I implemented at the moment is the recursive query, where we try to delegate to the DNS server the burden of finding and contacting the authoritative servers. This is done by setting the RD flag (Recursion Desired) in the message header. Many DNS servers like Google 8.8.8.8 oblige to these requests.

The code is present on my GitHub repository, and the simplest example on how to use the getaddrinfo function is the following:

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>

int main()
{
  struct addrinfo *ai;
  struct addrinfo *ai_iter;
  struct addrinfo hints;
  const char *name;
  int res;

  hints.ai_flags = 0;
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = 0;
  name = "www.facebook.com";

  res = getaddrinfo(name, NULL, &hints, &ai);
  if (res != 0)
  {
    if (res == EAI_SYSTEM)
    {
      perror("getaddrinfo");
    }
    else
    {
      fprintf(stderr, "error: getaddrinfo: %d\n", res);
    }
    return 1;
  }
  for (ai_iter = ai; ai_iter != NULL; ai_iter = ai_iter->ai_next)
  {
    struct sockaddr_in *addr;

    addr = (struct sockaddr_in *)ai_iter->ai_addr;

    printf("%s: %s\n",
            ai_iter->ai_canonname,
            inet_ntoa(addr->sin_addr));
  }

  freeaddrinfo(ai);
  return 0;
}

One nice thing of implementing functions as specified by POSIX is that this code now works both on my Linux desktop as well as on my Nucleo. Moreover, the implementation uses Berkeley (POSIX) sockets, so I even verified that my implementation of getaddrinfo can be compiled for Linux, and it works in the same way.

The gethostbyname function has been removed from POSIX.1-2008, but I implemented it anyway because libraries such as libcurl use it.

See also the previous posts:

Advertisements
Posted in: Embedded