/* Check recvmsg results for netlink sockets.
   Copyright (C) 2015-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 <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/socket.h>

#include "netlinkaccess.h"

static int
get_address_family (int fd)
{
  struct sockaddr_storage sa;
  socklen_t sa_len = sizeof (sa);
  if (__getsockname (fd, (struct sockaddr *) &sa, &sa_len) < 0)
    return -1;
  /* Check that the socket family number is preserved despite in-band
     signaling.  */
  _Static_assert (sizeof (sa.ss_family) < sizeof (int), "address family size");
  _Static_assert (0 < (__typeof__ (sa.ss_family)) -1,
                  "address family unsigned");
  return sa.ss_family;
}

void
__netlink_assert_response (int fd, ssize_t result)
{
  if (result < 0)
    {
      /* Check if the error is unexpected.  */
      bool terminate = false;
      int error_code = errno;
      int family = get_address_family (fd);
      if (family != AF_NETLINK)
        /* If the address family does not match (or getsockname
           failed), report the original error.  */
        terminate = true;
      else if (error_code == EBADF
          || error_code == ENOTCONN
          || error_code == ENOTSOCK
          || error_code == ECONNREFUSED)
        /* These errors indicate that the descriptor is not a
           connected socket.  */
        terminate = true;
      else if (error_code == EAGAIN || error_code == EWOULDBLOCK)
        {
          /* The kernel might return EAGAIN for other reasons than a
             non-blocking socket.  But if the socket is not blocking,
             it is not ours, so report the error.  */
          int mode = __fcntl (fd, F_GETFL, 0);
          if (mode < 0 || (mode & O_NONBLOCK) != 0)
            terminate = true;
        }
      if (terminate)
        {
          char message[200];
          if (family < 0)
            __snprintf (message, sizeof (message),
                        "Unexpected error %d on netlink descriptor %d",
                        error_code, fd);
          else
            __snprintf (message, sizeof (message),
                        "Unexpected error %d on netlink descriptor %d"
                        " (address family %d)",
                        error_code, fd, family);
          __libc_fatal (message);
        }
      else
        /* Restore orignal errno value.  */
        __set_errno (error_code);
    }
  else if (result < sizeof (struct nlmsghdr))
    {
      char message[200];
      int family = get_address_family (fd);
      if (family < 0)
          __snprintf (message, sizeof (message),
                      "Unexpected netlink response of size %zd"
                      " on descriptor %d",
                      result, fd);
      else
          __snprintf (message, sizeof (message),
                      "Unexpected netlink response of size %zd"
                      " on descriptor %d (address family %d)",
                      result, fd, family);
      __libc_fatal (message);
    }
}
libc_hidden_def (__netlink_assert_response)
