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] - Blame information for rev 520

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 207 jeremybenn
/* Determine protocol families for which interfaces exist.  Linux version.
2
   Copyright (C) 2003 Free Software Foundation, Inc.
3
   This file is part of the GNU C Library.
4
 
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the License, or (at your option) any later version.
9
 
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Lesser General Public License for more details.
14
 
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, write to the Free
17
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18
   02111-1307 USA.  */
19
 
20
#include <errno.h>
21
#include <stdint.h>
22
#include <ifaddrs.h>
23
#include <netdb.h>
24
#include <string.h>
25
#include <time.h>
26
#include <unistd.h>
27
#include <sys/socket.h>
28
 
29
#include <asm/types.h>
30
#include <linux/netlink.h>
31
#include <linux/rtnetlink.h>
32
 
33
#include <stdbool.h>
34
#include <sys/uio.h>
35
 
36
#include "config.h"
37
#include "local.h"
38
 
39
#define __ASSUME_NETLINK_SUPPORT 1
40
 
41
static int
42
make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6)
43
{
44
  struct
45
  {
46
    struct nlmsghdr nlh;
47
    struct rtgenmsg g;
48
  } req;
49
  struct sockaddr_nl nladdr;
50
 
51
  req.nlh.nlmsg_len = sizeof (req);
52
  req.nlh.nlmsg_type = RTM_GETADDR;
53
  req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
54
  req.nlh.nlmsg_pid = 0;
55
  req.nlh.nlmsg_seq = time (NULL);
56
  req.g.rtgen_family = AF_UNSPEC;
57
 
58
  memset (&nladdr, '\0', sizeof (nladdr));
59
  nladdr.nl_family = AF_NETLINK;
60
 
61
  if (TEMP_FAILURE_RETRY (sendto (fd, (void *) &req, sizeof (req), 0,
62
                                    (struct sockaddr *) &nladdr,
63
                                    sizeof (nladdr))) < 0)
64
    return -1;
65
 
66
  *seen_ipv4 = false;
67
  *seen_ipv6 = false;
68
 
69
  bool done = false;
70
  char buf[4096];
71
  struct iovec iov = { buf, sizeof (buf) };
72
 
73
  do
74
    {
75
      struct msghdr msg =
76
        {
77
          (void *) &nladdr, sizeof (nladdr),
78
          &iov, 1,
79
          NULL, 0,
80
 
81
        };
82
 
83
      ssize_t read_len = TEMP_FAILURE_RETRY (recvmsg (fd, &msg, 0));
84
      if (read_len < 0)
85
        return -1;
86
 
87
      if (msg.msg_flags & MSG_TRUNC)
88
        return -1;
89
 
90
      struct nlmsghdr *nlmh;
91
      for (nlmh = (struct nlmsghdr *) buf;
92
           NLMSG_OK (nlmh, (size_t) read_len);
93
           nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, read_len))
94
        {
95
          if (nladdr.nl_pid != 0 || (pid_t) nlmh->nlmsg_pid != pid
96
              || nlmh->nlmsg_seq != req.nlh.nlmsg_seq)
97
            continue;
98
 
99
          if (nlmh->nlmsg_type == RTM_NEWADDR)
100
            {
101
              struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlmh);
102
 
103
              switch (ifam->ifa_family)
104
                {
105
                case AF_INET:
106
                  *seen_ipv4 = true;
107
                  break;
108
                case AF_INET6:
109
                  *seen_ipv6 = true;
110
                  break;
111
                default:
112
                  /* Ignore.  */
113
                  break;
114
                }
115
            }
116
          else if (nlmh->nlmsg_type == NLMSG_DONE)
117
            /* We found the end, leave the loop.  */
118
            done = true;
119
          else ;
120
        }
121
    }
122
  while (! done);
123
 
124
  close (fd);
125
 
126
  return 0;
127
}
128
 
129
 
130
/* We don't know if we have NETLINK support compiled in in our
131
   Kernel.  */
132
#if __ASSUME_NETLINK_SUPPORT == 0
133
/* Define in ifaddrs.h.  */
134
extern int __no_netlink_support attribute_hidden;
135
#else
136
# define __no_netlink_support 0
137
#endif
138
 
139
 
140
void
141
attribute_hidden
142
__check_pf (bool *seen_ipv4, bool *seen_ipv6)
143
{
144
  if (! __no_netlink_support)
145
    {
146
      int fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
147
 
148
      struct sockaddr_nl nladdr;
149
      memset (&nladdr, '\0', sizeof (nladdr));
150
      nladdr.nl_family = AF_NETLINK;
151
 
152
      socklen_t addr_len = sizeof (nladdr);
153
 
154
      if (fd >= 0
155
          && bind (fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) == 0
156
          && getsockname (fd, (struct sockaddr *) &nladdr, &addr_len) == 0
157
          && make_request (fd, nladdr.nl_pid, seen_ipv4, seen_ipv6) == 0)
158
        /* It worked.  */
159
        return;
160
 
161
      if (fd >= 0)
162
        close (fd);
163
 
164
#if __ASSUME_NETLINK_SUPPORT == 0
165
      /* Remember that there is no netlink support.  */
166
      __no_netlink_support = 1;
167
#else
168
      /* We cannot determine what interfaces are available.  Be
169
         pessimistic.  */
170
      *seen_ipv4 = true;
171
      *seen_ipv6 = true;
172
#endif
173
    }
174
 
175
#if __ASSUME_NETLINK_SUPPORT == 0
176
  /* No netlink.  Get the interface list via getifaddrs.  */
177
  struct ifaddrs *ifa = NULL;
178
  if (getifaddrs (&ifa) != 0)
179
    {
180
      /* We cannot determine what interfaces are available.  Be
181
         pessimistic.  */
182
      *seen_ipv4 = true;
183
      *seen_ipv6 = true;
184
      return;
185
    }
186
 
187
  *seen_ipv4 = false;
188
  *seen_ipv6 = false;
189
 
190
  struct ifaddrs *runp;
191
  for (runp = ifa; runp != NULL; runp = runp->ifa_next)
192
    if (runp->ifa_addr->sa_family == PF_INET)
193
      *seen_ipv4 = true;
194
    else if (runp->ifa_addr->sa_family == PF_INET6)
195
      *seen_ipv6 = true;
196
 
197
  (void) freeifaddrs (ifa);
198
#endif
199
}

powered by: WebSVN 2.1.0

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