OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc2/] [newlib/] [libc/] [sys/] [linux/] [net/] [check_pf.c] - Diff between revs 207 and 520

Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 520
/* Determine protocol families for which interfaces exist.  Linux version.
/* Determine protocol families for which interfaces exist.  Linux version.
   Copyright (C) 2003 Free Software Foundation, Inc.
   Copyright (C) 2003 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   This file is part of the GNU C Library.
 
 
   The GNU C Library is free software; you can redistribute it and/or
   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   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,
   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   Lesser General Public License for more details.
 
 
   You should have received a copy of the GNU Lesser General Public
   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */
   02111-1307 USA.  */
 
 
#include <errno.h>
#include <errno.h>
#include <stdint.h>
#include <stdint.h>
#include <ifaddrs.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <netdb.h>
#include <string.h>
#include <string.h>
#include <time.h>
#include <time.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/socket.h>
 
 
#include <asm/types.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/rtnetlink.h>
 
 
#include <stdbool.h>
#include <stdbool.h>
#include <sys/uio.h>
#include <sys/uio.h>
 
 
#include "config.h"
#include "config.h"
#include "local.h"
#include "local.h"
 
 
#define __ASSUME_NETLINK_SUPPORT 1
#define __ASSUME_NETLINK_SUPPORT 1
 
 
static int
static int
make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6)
make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6)
{
{
  struct
  struct
  {
  {
    struct nlmsghdr nlh;
    struct nlmsghdr nlh;
    struct rtgenmsg g;
    struct rtgenmsg g;
  } req;
  } req;
  struct sockaddr_nl nladdr;
  struct sockaddr_nl nladdr;
 
 
  req.nlh.nlmsg_len = sizeof (req);
  req.nlh.nlmsg_len = sizeof (req);
  req.nlh.nlmsg_type = RTM_GETADDR;
  req.nlh.nlmsg_type = RTM_GETADDR;
  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
  req.nlh.nlmsg_pid = 0;
  req.nlh.nlmsg_pid = 0;
  req.nlh.nlmsg_seq = time (NULL);
  req.nlh.nlmsg_seq = time (NULL);
  req.g.rtgen_family = AF_UNSPEC;
  req.g.rtgen_family = AF_UNSPEC;
 
 
  memset (&nladdr, '\0', sizeof (nladdr));
  memset (&nladdr, '\0', sizeof (nladdr));
  nladdr.nl_family = AF_NETLINK;
  nladdr.nl_family = AF_NETLINK;
 
 
  if (TEMP_FAILURE_RETRY (sendto (fd, (void *) &req, sizeof (req), 0,
  if (TEMP_FAILURE_RETRY (sendto (fd, (void *) &req, sizeof (req), 0,
                                    (struct sockaddr *) &nladdr,
                                    (struct sockaddr *) &nladdr,
                                    sizeof (nladdr))) < 0)
                                    sizeof (nladdr))) < 0)
    return -1;
    return -1;
 
 
  *seen_ipv4 = false;
  *seen_ipv4 = false;
  *seen_ipv6 = false;
  *seen_ipv6 = false;
 
 
  bool done = false;
  bool done = false;
  char buf[4096];
  char buf[4096];
  struct iovec iov = { buf, sizeof (buf) };
  struct iovec iov = { buf, sizeof (buf) };
 
 
  do
  do
    {
    {
      struct msghdr msg =
      struct msghdr msg =
        {
        {
          (void *) &nladdr, sizeof (nladdr),
          (void *) &nladdr, sizeof (nladdr),
          &iov, 1,
          &iov, 1,
          NULL, 0,
          NULL, 0,
          0
          0
        };
        };
 
 
      ssize_t read_len = TEMP_FAILURE_RETRY (recvmsg (fd, &msg, 0));
      ssize_t read_len = TEMP_FAILURE_RETRY (recvmsg (fd, &msg, 0));
      if (read_len < 0)
      if (read_len < 0)
        return -1;
        return -1;
 
 
      if (msg.msg_flags & MSG_TRUNC)
      if (msg.msg_flags & MSG_TRUNC)
        return -1;
        return -1;
 
 
      struct nlmsghdr *nlmh;
      struct nlmsghdr *nlmh;
      for (nlmh = (struct nlmsghdr *) buf;
      for (nlmh = (struct nlmsghdr *) buf;
           NLMSG_OK (nlmh, (size_t) read_len);
           NLMSG_OK (nlmh, (size_t) read_len);
           nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, read_len))
           nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, read_len))
        {
        {
          if (nladdr.nl_pid != 0 || (pid_t) nlmh->nlmsg_pid != pid
          if (nladdr.nl_pid != 0 || (pid_t) nlmh->nlmsg_pid != pid
              || nlmh->nlmsg_seq != req.nlh.nlmsg_seq)
              || nlmh->nlmsg_seq != req.nlh.nlmsg_seq)
            continue;
            continue;
 
 
          if (nlmh->nlmsg_type == RTM_NEWADDR)
          if (nlmh->nlmsg_type == RTM_NEWADDR)
            {
            {
              struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlmh);
              struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlmh);
 
 
              switch (ifam->ifa_family)
              switch (ifam->ifa_family)
                {
                {
                case AF_INET:
                case AF_INET:
                  *seen_ipv4 = true;
                  *seen_ipv4 = true;
                  break;
                  break;
                case AF_INET6:
                case AF_INET6:
                  *seen_ipv6 = true;
                  *seen_ipv6 = true;
                  break;
                  break;
                default:
                default:
                  /* Ignore.  */
                  /* Ignore.  */
                  break;
                  break;
                }
                }
            }
            }
          else if (nlmh->nlmsg_type == NLMSG_DONE)
          else if (nlmh->nlmsg_type == NLMSG_DONE)
            /* We found the end, leave the loop.  */
            /* We found the end, leave the loop.  */
            done = true;
            done = true;
          else ;
          else ;
        }
        }
    }
    }
  while (! done);
  while (! done);
 
 
  close (fd);
  close (fd);
 
 
  return 0;
  return 0;
}
}
 
 
 
 
/* We don't know if we have NETLINK support compiled in in our
/* We don't know if we have NETLINK support compiled in in our
   Kernel.  */
   Kernel.  */
#if __ASSUME_NETLINK_SUPPORT == 0
#if __ASSUME_NETLINK_SUPPORT == 0
/* Define in ifaddrs.h.  */
/* Define in ifaddrs.h.  */
extern int __no_netlink_support attribute_hidden;
extern int __no_netlink_support attribute_hidden;
#else
#else
# define __no_netlink_support 0
# define __no_netlink_support 0
#endif
#endif
 
 
 
 
void
void
attribute_hidden
attribute_hidden
__check_pf (bool *seen_ipv4, bool *seen_ipv6)
__check_pf (bool *seen_ipv4, bool *seen_ipv6)
{
{
  if (! __no_netlink_support)
  if (! __no_netlink_support)
    {
    {
      int fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
      int fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
 
 
      struct sockaddr_nl nladdr;
      struct sockaddr_nl nladdr;
      memset (&nladdr, '\0', sizeof (nladdr));
      memset (&nladdr, '\0', sizeof (nladdr));
      nladdr.nl_family = AF_NETLINK;
      nladdr.nl_family = AF_NETLINK;
 
 
      socklen_t addr_len = sizeof (nladdr);
      socklen_t addr_len = sizeof (nladdr);
 
 
      if (fd >= 0
      if (fd >= 0
          && bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
          && bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
          && getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) == 0
          && getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) == 0
          && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6) == 0)
          && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6) == 0)
        /* It worked.  */
        /* It worked.  */
        return;
        return;
 
 
      if (fd >= 0)
      if (fd >= 0)
        close (fd);
        close (fd);
 
 
#if __ASSUME_NETLINK_SUPPORT == 0
#if __ASSUME_NETLINK_SUPPORT == 0
      /* Remember that there is no netlink support.  */
      /* Remember that there is no netlink support.  */
      __no_netlink_support = 1;
      __no_netlink_support = 1;
#else
#else
      /* We cannot determine what interfaces are available.  Be
      /* We cannot determine what interfaces are available.  Be
         pessimistic.  */
         pessimistic.  */
      *seen_ipv4 = true;
      *seen_ipv4 = true;
      *seen_ipv6 = true;
      *seen_ipv6 = true;
#endif
#endif
    }
    }
 
 
#if __ASSUME_NETLINK_SUPPORT == 0
#if __ASSUME_NETLINK_SUPPORT == 0
  /* No netlink.  Get the interface list via getifaddrs.  */
  /* No netlink.  Get the interface list via getifaddrs.  */
  struct ifaddrs *ifa = NULL;
  struct ifaddrs *ifa = NULL;
  if (getifaddrs (&ifa) != 0)
  if (getifaddrs (&ifa) != 0)
    {
    {
      /* We cannot determine what interfaces are available.  Be
      /* We cannot determine what interfaces are available.  Be
         pessimistic.  */
         pessimistic.  */
      *seen_ipv4 = true;
      *seen_ipv4 = true;
      *seen_ipv6 = true;
      *seen_ipv6 = true;
      return;
      return;
    }
    }
 
 
  *seen_ipv4 = false;
  *seen_ipv4 = false;
  *seen_ipv6 = false;
  *seen_ipv6 = false;
 
 
  struct ifaddrs *runp;
  struct ifaddrs *runp;
  for (runp = ifa; runp != NULL; runp = runp->ifa_next)
  for (runp = ifa; runp != NULL; runp = runp->ifa_next)
    if (runp->ifa_addr->sa_family == PF_INET)
    if (runp->ifa_addr->sa_family == PF_INET)
      *seen_ipv4 = true;
      *seen_ipv4 = true;
    else if (runp->ifa_addr->sa_family == PF_INET6)
    else if (runp->ifa_addr->sa_family == PF_INET6)
      *seen_ipv6 = true;
      *seen_ipv6 = true;
 
 
  (void) freeifaddrs (ifa);
  (void) freeifaddrs (ifa);
#endif
#endif
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.