~ubuntu-branches/ubuntu/utopic/eglibc/utopic

« back to all changes in this revision

Viewing changes to ports/sysdeps/unix/bsd/bsd4.4/kfreebsd/if_index.c

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2012-10-26 05:14:58 UTC
  • mfrom: (1.5.1) (4.4.22 experimental)
  • Revision ID: package-import@ubuntu.com-20121026051458-oryotr4i03ob5pab
Tags: 2.16-0ubuntu1
* Merge with unreleased 2.16 in Debian experimental, remaining changes:
  - Drop the Breaks line from libc6, which refers to a Debian transition
  - Remove the libc6 recommends on libc6-i686, which we don't build
  - Enable libc6{,-dev}-armel on armhf and libc6{-dev}-armhf on armel
  - Ship update-locale and validlocale in /usr/sbin in libc-bin
  - Don't build locales or locales-all in Ubuntu, we rely on langpacks
  - Heavily mangle the way we do service restarting on major upgrades
  - Use different MIN_KERNEL_SUPPORTED versions than Debian, due to
    buildd needs.  This should be universally bumped to 3.2.0 once all
    our buildds (including the PPA guests) are running precise kernels
  - Build i386 variants as -march=i686, build amd64 with -O3, and build
    ppc64 variants (both 64-bit and 32-bit) with -O3 -fno-tree-vectorize
  - Re-enable unsubmitted-ldconfig-cache-abi.diff and rebuild the cache
    on upgrades from previous versions that used a different constant
  - debian/patches/any/local-CVE-2012-3406.diff: switch to malloc when
    array grows too large to handle via alloca extension (CVE-2012-3406)
  - Build generic i386/i686 flavour with -mno-tls-direct-seg-refs
* Changes added/dropped with this merge while reducing our delta:
  - Stop building glibc docs from the eglibc source, and instead make
    the glibc-docs stub have a hard dependency on glibc-doc-reference
  - Remove outdated conflicts against ancient versions of ia32-libs
  - Drop the tzdata dependency from libc6, it's in required and minimal
  - Use gcc-4.7/g++-4.7 by default on all our supported architectures
  - Save our historical changelog as changelog.ubuntu in the source
  - Drop nscd's libaudit build-dep for now, as libaudit is in universe
  - Drop the unnecessary Breaks from libc6 to locales and locales-all
  - Ship xen's ld.so.conf.d snippet as /etc/ld.so.conf.d/libc6-xen.conf
* Disable hard failures on the test suite for the first upload to raring

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2002 Free Software Foundation, Inc.
 
2
   This file is part of the GNU C Library.
 
3
   Contributed by Bruno Haible <bruno@clisp.org>, 2002.
 
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 <net/if.h>
 
21
#include <sys/sysctl.h>
 
22
#include <sys/socket.h>
 
23
#include <net/route.h>
 
24
#include <net/if_dl.h>
 
25
#include <alloca.h>
 
26
#include <stdlib.h>
 
27
#include <errno.h>
 
28
#include <string.h>
 
29
 
 
30
 
 
31
typedef int (*if_fn) (void *private, unsigned int index, const char *name);
 
32
 
 
33
/* Iterate through all present interfaces.
 
34
   Call FN once for every interface, returning immediately if FN returns
 
35
   a nonzero value.  */
 
36
static void
 
37
if_iterate (if_fn fn, void *private)
 
38
{
 
39
  int request[6] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
 
40
  char *buf;
 
41
  size_t bufsize = 512;
 
42
  char *bufend;
 
43
  char *p;
 
44
 
 
45
  /* Call the kernel function sysctl_iflist() in /usr/src/sys/net/rtsock.c.  */
 
46
  for (;;)
 
47
    {
 
48
      buf = alloca (bufsize);
 
49
      if (__sysctl (request, 6, buf, &bufsize, NULL, 0) >= 0)
 
50
        break;
 
51
      if (errno != ENOMEM)
 
52
        return;
 
53
      bufsize *= 2;
 
54
    }
 
55
 
 
56
  bufend = buf + bufsize;
 
57
  for (p = buf; p < bufend; )
 
58
    {
 
59
      struct if_msghdr *msg = (struct if_msghdr *) p;
 
60
 
 
61
      if (msg->ifm_version != RTM_VERSION)
 
62
        abort ();
 
63
 
 
64
      switch (msg->ifm_type)
 
65
        {
 
66
        case RTM_IFINFO:
 
67
          if (msg->ifm_addrs & RTA_IFP)
 
68
            {
 
69
              unsigned int index;
 
70
              struct sockaddr_dl *sdl;
 
71
              char namebuf[IFNAMSIZ + 1];
 
72
              size_t namelen;
 
73
 
 
74
              index = msg->ifm_index;
 
75
              if (index == 0)
 
76
                abort ();
 
77
 
 
78
              /* FIXME: 'struct if_msghdr' contains a 'struct if_data' which in turns
 
79
                 contains 'unsigned long' values. Their size therefore depends on
 
80
                 the running kernel (32 or 64 bits). This should be fixed in the
 
81
                 compat layer of the kernel. Meanwhile just workaround the bug here/ */
 
82
#if 0
 
83
              sdl = (struct sockaddr_dl *) (msg + 1);
 
84
#else
 
85
              sdl = (struct sockaddr_dl *) (p + msg->ifm_msglen - sizeof(struct sockaddr_dl) - 2);
 
86
#endif
 
87
              namelen = sdl->sdl_nlen;
 
88
              /* Avoid overflowing namebuf[].  */
 
89
              if (namelen > IFNAMSIZ)
 
90
                namelen = IFNAMSIZ;
 
91
              memcpy (namebuf, sdl->sdl_data, namelen);
 
92
              namebuf[namelen] = '\0';
 
93
 
 
94
              /* Call FN now.  */
 
95
              if (fn (private, index, namebuf))
 
96
                return;
 
97
            }
 
98
          break;
 
99
 
 
100
        case RTM_NEWADDR:
 
101
          break;
 
102
 
 
103
        default:
 
104
          abort ();
 
105
        }
 
106
 
 
107
      p += msg->ifm_msglen;
 
108
    }
 
109
}
 
110
 
 
111
/* ------------------------------------------------------------------------- */
 
112
 
 
113
struct nametoindex_locals
 
114
  {
 
115
    const char *name;
 
116
    unsigned int index;
 
117
  };
 
118
 
 
119
static int
 
120
nametoindex_aux (void *private, unsigned int index, const char *name)
 
121
{
 
122
  struct nametoindex_locals *l = (struct nametoindex_locals *) private;
 
123
  if (strcmp (name, l->name) == 0)
 
124
    {
 
125
      l->index = index;
 
126
      return 1;
 
127
    }
 
128
  return 0;
 
129
}
 
130
 
 
131
/* Return the index of an interface given by name.  */
 
132
unsigned int
 
133
if_nametoindex (const char *ifname)
 
134
{
 
135
  struct nametoindex_locals l;
 
136
 
 
137
  l.name = ifname;
 
138
  l.index = 0;
 
139
  if_iterate (nametoindex_aux, &l);
 
140
 
 
141
  return l.index;
 
142
}
 
143
libc_hidden_def (if_nametoindex)
 
144
 
 
145
/* ------------------------------------------------------------------------- */
 
146
 
 
147
struct indextoname_locals
 
148
  {
 
149
    unsigned int index;
 
150
    char *name;
 
151
    char *retval;
 
152
  };
 
153
 
 
154
static int
 
155
indextoname_aux (void *private, unsigned int index, const char *name)
 
156
{
 
157
  struct indextoname_locals *l = (struct indextoname_locals *) private;
 
158
  if (index == l->index)
 
159
    {
 
160
      strncpy (l->name, name, IF_NAMESIZE);
 
161
      l->retval = l->name;
 
162
      return 1;
 
163
    }
 
164
  __set_errno (ENXIO);
 
165
  return 0;
 
166
}
 
167
 
 
168
/* Return the name of an interface given by name.  */
 
169
char *
 
170
if_indextoname (unsigned int ifindex, char *ifname)
 
171
{
 
172
  struct indextoname_locals l;
 
173
 
 
174
  l.index = ifindex;
 
175
  l.name = ifname;
 
176
  l.retval = NULL;
 
177
  if_iterate (indextoname_aux, &l);
 
178
  return l.retval;
 
179
}
 
180
libc_hidden_def (if_indextoname)
 
181
 
 
182
/* ------------------------------------------------------------------------- */
 
183
 
 
184
struct nameindex_locals
 
185
  {
 
186
    /* Resizable array of 'struct if_nameindex'.  */
 
187
    struct if_nameindex *s_array;
 
188
    size_t s_len;
 
189
    size_t s_allocated;
 
190
    /* Resizable array of char.  */
 
191
    char *c_array;
 
192
    size_t c_len;
 
193
    size_t c_allocated;
 
194
    /* Out-of-memory indicator.  */
 
195
    int oom;
 
196
  };
 
197
 
 
198
static void
 
199
add_s (struct nameindex_locals *l, unsigned int index, char *name)
 
200
{
 
201
  if (l->s_len == l->s_allocated)
 
202
    {
 
203
      size_t new_allocated = 2 * l->s_allocated + 1;
 
204
      struct if_nameindex *new_array =
 
205
        (struct if_nameindex *)
 
206
        realloc (l->s_array, new_allocated * sizeof (struct if_nameindex));
 
207
      if (new_array == NULL)
 
208
        {
 
209
          l->oom = 1;
 
210
          return;
 
211
        }
 
212
      l->s_array = new_array;
 
213
      l->s_allocated = new_allocated;
 
214
    }
 
215
  /* Now l->s_len < l->s_allocated.  */
 
216
  l->s_array[l->s_len].if_index = index;
 
217
  l->s_array[l->s_len].if_name = name;
 
218
  l->s_len++;
 
219
}
 
220
 
 
221
static __inline size_t
 
222
add_c (struct nameindex_locals *l, const char *name)
 
223
{
 
224
  size_t n = strlen (name) + 1;
 
225
  size_t result_offset;
 
226
  if (l->c_len + n > l->c_allocated)
 
227
    {
 
228
      size_t new_allocated =
 
229
        (l->c_len + n < 2 * l->c_allocated + 1
 
230
         ? 2 * l->c_allocated + 1
 
231
         : l->c_len + n);
 
232
      char *new_array = (char *) realloc (l->c_array, new_allocated);
 
233
      if (new_array == NULL)
 
234
        {
 
235
          l->oom = 1;
 
236
          return 0;
 
237
        }
 
238
      l->c_array = new_array;
 
239
      l->c_allocated = new_allocated;
 
240
    }
 
241
  /* Now l->c_len + n <= l->c_allocated.  */
 
242
  result_offset = l->c_len;
 
243
  memcpy (l->c_array + l->c_len, name, n);
 
244
  l->c_len += n;
 
245
  return result_offset;
 
246
}
 
247
 
 
248
static int
 
249
nameindex_aux (void *private, unsigned int index, const char *name)
 
250
{
 
251
  struct nameindex_locals *l = (struct nameindex_locals *) private;
 
252
 
 
253
  size_t name_offset = add_c (l, name);
 
254
  if (!l->oom)
 
255
    {
 
256
      add_s (l, index, (char *) NULL + name_offset);
 
257
      if (!l->oom)
 
258
        return 0;
 
259
    }
 
260
  return 1;
 
261
}
 
262
 
 
263
/* Return an array of 'struct if_nameindex', one for each present
 
264
   interface.  */
 
265
struct if_nameindex *
 
266
if_nameindex (void)
 
267
{
 
268
  struct nameindex_locals l;
 
269
 
 
270
  l.s_array = NULL; l.s_len = 0; l.s_allocated = 0;
 
271
  l.c_array = NULL; l.c_len = 0; l.c_allocated = 0;
 
272
  l.oom = 0;
 
273
  if_iterate (nameindex_aux, &l);
 
274
  if (!l.oom)
 
275
    {
 
276
      /* Convert all offsets to real pointers.  */
 
277
      struct if_nameindex *p;
 
278
      struct if_nameindex *p_end;
 
279
 
 
280
      for (p = l.s_array, p_end = p + l.s_len; p < p_end; p++)
 
281
        p->if_name = l.c_array + (p->if_name - (char *) NULL);
 
282
 
 
283
      /* Add a terminating entry.  */
 
284
      add_s (&l, 0, NULL);
 
285
    }
 
286
  if (l.oom)
 
287
    {
 
288
      free (l.s_array);
 
289
      free (l.c_array);
 
290
      __set_errno (ENOMEM);
 
291
      return NULL;
 
292
    }
 
293
  return l.s_array;
 
294
}
 
295
libc_hidden_def (if_nameindex)
 
296
 
 
297
/* ------------------------------------------------------------------------- */
 
298
 
 
299
/* Free an array returned by if_nameindex().  */
 
300
void
 
301
if_freenameindex (struct if_nameindex *ifn)
 
302
{
 
303
  if (ifn != NULL)
 
304
    {
 
305
      /* Free c_array.  */
 
306
      free (ifn[0].if_name);
 
307
      /* Free s_array.  */
 
308
      free (ifn);
 
309
    }
 
310
}
 
311
libc_hidden_def (if_freenameindex)