title: Setting IPv4/IPv6 address and port to a sockaddr_storage structure
body: <p>I'm porting a <strong>IPv4</strong> application to a <strong>AF-independent</strong> codebase(it should work with IPv4 and IPv6). Now I'm using <strong>sockaddr_storage</strong> wherever I can, however now I have to set(populate) a <strong>sockaddr_storage</strong>. But I don't know what the correct way is. The previous code was:</p>
  
  <pre><code>// defined in data_socket.h
  struct sockaddr_in laddr;
  </code></pre>
  
  <p>Now there is this function that sets <strong>sin_addr</strong> and <strong>sin_port</strong>:</p>
  
  <pre><code>void DataSocket::SetLocalAddr(const char *addr, const int port)
  {
      this-&gt;laddr.sin_port = htons(port);
      if(addr != NULL)
          this-&gt;laddr.sin_addr.s_addr = inet_addr(addr);
      else
          this-&gt;laddr.sin_addr.s_addr = inet_addr("0.0.0.0");
  }
  </code></pre>
  
  <p>As you see this is the old style(uses IPv4). </p>
  
  <p>Now my changes are below. First I've changed <strong><code>sockaddr_in</code></strong> to <strong><code>sockaddr_storage</code></strong></p>
  
  <pre><code>// defined in data_socket.h
  struct sockaddr_storage laddr;
  </code></pre>
  
  <p>Then I changed the code above to support <strong>IPv4</strong> and <strong>IPv6</strong>:</p>
  
  <pre><code>void DataSocket::SetLocalAddr(const char *addr, const int port)
  { 
  switch (this-&gt;GetAddrFamily(addr)) {
      case AF_INET:
          (struct sockaddr_in *) this-&gt;laddr.sin_port = htons(port);
          if(addr != NULL)
              inet_pton(AF_INET, addr, (struct sockaddr_in *) this-&gt;laddr.sin_addr);
          else
              inet_pton(AF_INET, "0.0.0.0", (struct sockaddr_in *) this-&gt;laddr.sin_addr);
          break;
  
      case AF_INET6:
          (struct sockaddr_in6 *) this-&gt;laddr.sin6_port = htons(port);
          if(addr != NULL)
              inet_pton(AF_INET6, addr, (struct sockaddr_in6 *) this-&gt;laddr.sin6_addr);
          else
              inet_pton(AF_INET6, "0:0:0:0:0:0:0:0", (struct sockaddr_in6 *) this-&gt;laddr.sin6_addr);
          break;
  
      default:
          return NULL;
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Where <code>GetAddrFamily()</code> is:</p>
  
  <pre><code>int DataSocket::GetAddrFamily(const char *addr)
  {
      struct addrinfo hints, *res;
      int status, result;
  
      memset(&amp;hints, 0, sizeof(hints));
      hints.ai_family = AF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
  
      if ((status = getaddrinfo(addr, 0, &amp;hints, &amp;res)) != 0)
      {
          fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
          return false;
      }
  
      result = res-&gt;ai_family; // This might be AF_INET, AF_INET6,etc..
      freeaddrinfo(res); // We're done with res, free it up
  
      return result;
  }
  </code></pre>
  
  <p>It seems my way is to complex. Is this the correct way to do this? Because I've changed sockaddr_in to sockaddr_storage, actually I just want the reverse of this question: <a href="https://stackoverflow.com/questions/1276294/getting-ipv4-address-from-a-sockaddr-structure">Getting IPV4 address from a sockaddr structure</a> </p>
  
  <p>I'm trying to find the best solution, for example here: <a href="http://www.kame.net/newsletter/19980604/" rel="nofollow noreferrer">http://www.kame.net/newsletter/19980604/</a> it says never use <code>inet_ntop()</code> and <code>inet_pton()</code>, however some others(like the Beej's network tutorial) says that <code>inet_ntop()</code> and <code>inet_pton()</code> should be used for <strong>IPv6</strong> based application.</p>
  
  <p>Is my way of implementation correct or should I change it?</p>