* sysdeps/generic/ifreq.h (__if_nextreq): New function.
[glibc.git] / sysdeps / unix / sysv / linux / ifreq.h
blobf498e5c32a253e82702ff3bb63246b24e335b5b1
1 /* Copyright (C) 1999,2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Andreas Jaeger <aj@suse.de>.
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.
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.
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. */
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <net/if.h>
24 #include <sys/socket.h>
25 #include <sys/ioctl.h>
26 #include "kernel-features.h"
28 /* Variable to signal whether SIOCGIFCONF is not available. */
29 #if __ASSUME_SIOCGIFNAME == 0 || 1
30 static int old_siocgifconf;
31 #else
32 # define old_siocgifconf 0
33 #endif
36 static inline void
37 __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd)
39 int fd = sockfd;
40 struct ifconf ifc;
41 int rq_len;
42 int nifs;
43 # define RQ_IFS 4
45 if (fd < 0)
46 fd = __opensock ();
47 if (fd < 0)
49 *num_ifs = 0;
50 *ifreqs = NULL;
51 return;
54 ifc.ifc_buf = NULL;
56 /* We may be able to get the needed buffer size directly, rather than
57 guessing. */
58 if (! old_siocgifconf)
60 ifc.ifc_buf = NULL;
61 ifc.ifc_len = 0;
62 if (__ioctl (fd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0)
64 # if __ASSUME_SIOCGIFNAME == 0
65 old_siocgifconf = 1;
66 # endif
67 rq_len = RQ_IFS * sizeof (struct ifreq);
69 else
70 rq_len = ifc.ifc_len;
72 else
73 rq_len = RQ_IFS * sizeof (struct ifreq);
75 /* Read all the interfaces out of the kernel. */
76 while (1)
78 ifc.ifc_len = rq_len;
79 ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len);
80 if (ifc.ifc_buf == NULL || __ioctl (fd, SIOCGIFCONF, &ifc) < 0)
82 if (ifc.ifc_buf)
83 free (ifc.ifc_buf);
85 if (fd != sockfd)
86 __close (fd);
88 *num_ifs = 0;
89 *ifreqs = NULL;
90 return;
93 if (!old_siocgifconf || ifc.ifc_len < rq_len)
94 break;
96 rq_len *= 2;
99 nifs = ifc.ifc_len / sizeof (struct ifreq);
101 if (fd != sockfd)
102 __close (fd);
104 *num_ifs = nifs;
105 *ifreqs = realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq));
108 static inline struct ifreq *
109 __if_nextreq (struct ifreq *ifr)
111 return ifr + 1;
114 static inline void
115 __if_freereq (struct ifreq *ifreqs, int num_ifs)
117 free (ifreqs);