/* Convert struct addrinfo values to a string.
   Copyright (C) 2016-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <support/format_nss.h>

#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <support/support.h>
#include <support/xmemstream.h>

static size_t
socket_address_length (int family)
{
  switch (family)
    {
    case AF_INET:
      return sizeof (struct sockaddr_in);
    case AF_INET6:
      return sizeof (struct sockaddr_in6);
    default:
      return -1;
    }
}

static void
format_ai_flags_1 (FILE *out, struct addrinfo *ai, int flag, const char *name,
                   int * flags_printed)
{
  if ((ai->ai_flags & flag) != 0)
    fprintf (out, " %s", name);
  *flags_printed |= flag;
}

static void
format_ai_flags (FILE *out, struct addrinfo *ai)
{
  if (ai == NULL)
    return;

  if (ai->ai_flags != 0)
    {
      fprintf (out, "flags:");
      int flags_printed = 0;
#define FLAG(flag) format_ai_flags_1 (out, ai, flag, #flag, &flags_printed)
      FLAG (AI_PASSIVE);
      FLAG (AI_CANONNAME);
      FLAG (AI_NUMERICHOST);
      FLAG (AI_V4MAPPED);
      FLAG (AI_ALL);
      FLAG (AI_ADDRCONFIG);
      FLAG (AI_IDN);
      FLAG (AI_CANONIDN);
      FLAG (AI_IDN_ALLOW_UNASSIGNED);
      FLAG (AI_IDN_USE_STD3_ASCII_RULES);
      FLAG (AI_NUMERICSERV);
#undef FLAG
      int remaining = ai->ai_flags & ~flags_printed;
      if (remaining != 0)
        fprintf (out, " %08x", remaining);
      fprintf (out, "\n");
    }

  /* Report flag mismatches within the list.  */
  int flags = ai->ai_flags;
  int index = 1;
  ai = ai->ai_next;
  while (ai != NULL)
    {
      if (ai->ai_flags != flags)
        fprintf (out, "error: flags at %d: 0x%x expected, 0x%x actual\n",
                 index, flags, ai->ai_flags);
      ai = ai->ai_next;
      ++index;
    }
}

static void
format_ai_canonname (FILE *out, struct addrinfo *ai)
{
  if (ai == NULL)
    return;
  if (ai->ai_canonname != NULL)
    fprintf (out, "canonname: %s\n", ai->ai_canonname);

  /* Report incorrectly set ai_canonname fields on subsequent list
     entries.  */
  int index = 1;
  ai = ai->ai_next;
  while (ai != NULL)
    {
      if (ai->ai_canonname != NULL)
        fprintf (out, "error: canonname set at %d: %s\n",
                 index, ai->ai_canonname);
      ai = ai->ai_next;
      ++index;
    }
}

static void
format_ai_one (FILE *out, struct addrinfo *ai)
{
  {
    char type_buf[32];
    const char *type_str;
    char proto_buf[32];
    const char *proto_str;

    /* ai_socktype */
    switch (ai->ai_socktype)
      {
      case SOCK_RAW:
        type_str = "RAW";
        break;
      case SOCK_DGRAM:
        type_str = "DGRAM";
        break;
      case SOCK_STREAM:
        type_str = "STREAM";
        break;
      default:
        snprintf (type_buf, sizeof (type_buf), "%d", ai->ai_socktype);
        type_str = type_buf;
      }

    /* ai_protocol */
    switch (ai->ai_protocol)
      {
      case IPPROTO_IP:
        proto_str = "IP";
        break;
      case IPPROTO_UDP:
        proto_str = "UDP";
        break;
      case IPPROTO_TCP:
        proto_str = "TCP";
        break;
      default:
        snprintf (proto_buf, sizeof (proto_buf), "%d", ai->ai_protocol);
        proto_str = proto_buf;
      }
    fprintf (out, "address: %s/%s", type_str, proto_str);
  }

  /* ai_addrlen */
  if (ai->ai_addrlen != socket_address_length (ai->ai_family))
    {
      char *family = support_format_address_family (ai->ai_family);
      fprintf (out, "error: invalid address length %d for %s\n",
               ai->ai_addrlen, family);
      free (family);
    }

  /* ai_addr */
  {
    char buf[128];
    uint16_t port;
    const char *ret;
    switch (ai->ai_family)
      {
      case AF_INET:
        {
          struct sockaddr_in *sin = (struct sockaddr_in *) ai->ai_addr;
          ret = inet_ntop (AF_INET, &sin->sin_addr, buf, sizeof (buf));
          port = sin->sin_port;
        }
        break;
      case AF_INET6:
        {
          struct sockaddr_in6 *sin = (struct sockaddr_in6 *) ai->ai_addr;
          ret = inet_ntop (AF_INET6, &sin->sin6_addr, buf, sizeof (buf));
          port = sin->sin6_port;
        }
        break;
      default:
        errno = EAFNOSUPPORT;
        ret = NULL;
      }
    if (ret == NULL)
        fprintf (out, "error: inet_top failed: %m\n");
    else
      fprintf (out, " %s %u\n", buf, ntohs (port));
  }
}

/* Format all the addresses in one address family.  */
static void
format_ai_family (FILE *out, struct addrinfo *ai, int family)
{
  while (ai)
    {
      if (ai->ai_family == family)
        format_ai_one (out, ai);
      ai = ai->ai_next;
    }
}

char *
support_format_addrinfo (struct addrinfo *ai, int ret)
{
  int errno_copy = errno;

  struct xmemstream mem;
  xopen_memstream (&mem);
  if (ret != 0)
    {
      fprintf (mem.out, "error: %s\n", gai_strerror (ret));
      if (ret == EAI_SYSTEM)
        {
          errno = errno_copy;
          fprintf (mem.out, "error: %m\n");
        }
    }
  else
    {
      format_ai_flags (mem.out, ai);
      format_ai_canonname (mem.out, ai);
      format_ai_family (mem.out, ai, AF_INET);
      format_ai_family (mem.out, ai, AF_INET6);
    }

  xfclose_memstream (&mem);
  return mem.buffer;
}
