source: trunk/libs/newlib/src/newlib/libc/sys/linux/net/ifname.c

Last change on this file was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 5.6 KB
Line 
1/*      $KAME: ifname.c,v 1.4 2001/08/20 02:32:40 itojun Exp $  */
2
3/*
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33#include <sys/types.h>
34#include <sys/types.h>
35
36/*
37 * TODO:
38 * - prototype defs into arpa/inet.h, not net/if.h (bsd-api-new-02)
39 */
40
41#include <sys/param.h>
42#include <sys/socket.h>
43#include <sys/sockio.h>
44#include <sys/sysctl.h>
45#include <net/if.h>
46#include <net/route.h>
47#include <net/if_dl.h>
48
49#include <unistd.h>
50#include <errno.h>
51#include <stdlib.h>
52#include <string.h>
53
54#define ROUNDUP(a) \
55        ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
56#define ADVANCE(x, n)
57
58static unsigned int
59if_onametoindex(ifname)
60        const char *ifname;
61{
62        struct if_nameindex *iff = if_nameindex(), *ifx;
63        int ret;
64
65        if (iff == NULL) return 0;
66        ifx = iff;
67        while (ifx->if_name != NULL) {
68                if (strcmp(ifx->if_name, ifname) == 0) {
69                        ret = ifx->if_index;
70                        if_freenameindex(iff);
71                        return ret;
72                }
73                ifx++;
74        }
75        if_freenameindex(iff);
76        errno = ENXIO;
77        return 0;
78}
79 
80unsigned int
81if_nametoindex(ifname)
82        const char *ifname;
83{
84        int s;
85        struct ifreq ifr;
86
87        s = socket(AF_INET, SOCK_DGRAM, 0);
88        if (s == -1)
89                return (0);
90        strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
91        if (ioctl(s, SIOCGIFINDEX, &ifr) == -1) {
92                close (s);
93                return (if_onametoindex(ifname));
94        }
95        close(s);
96        return (ifr.ifr_index);
97}
98
99char *
100if_indextoname(ifindex, ifname)
101        unsigned int ifindex;
102        char *ifname; /* at least IF_NAMESIZE */
103{
104        struct if_nameindex *iff = if_nameindex(), *ifx;
105        char *cp, *dp;
106
107        if (iff == NULL) return NULL;
108        ifx = iff;
109        while (ifx->if_index != 0) {
110                if (ifx->if_index == ifindex) {
111                        cp = ifname;
112                        dp = ifx->if_name;
113                        while ((*cp++ = *dp++)) ;
114                        if_freenameindex(iff);
115                        return (ifname);
116                }
117                ifx++;
118        }
119        if_freenameindex(iff);
120        errno = ENXIO;
121        return NULL;
122}
123
124struct if_nameindex *
125if_nameindex()
126{
127        size_t needed;
128        int mib[6], ifn = 0, off = 0, hlen;
129        unsigned int i;
130        char *buf = NULL, *lim, *next, *cp, *ifbuf = NULL;
131        struct rt_msghdr *rtm;
132        struct if_msghdr *ifm;
133        struct sockaddr *sa;
134        struct if_nameindex *ret = NULL;
135        static int ifxs = 64;   /* initial upper limit */
136        struct _ifx {
137                int if_index;
138                int if_off;
139        } *ifx = NULL;
140
141        mib[0] = CTL_NET;
142        mib[1] = PF_ROUTE;
143        mib[2] = 0;             /* protocol */
144        mib[3] = 0;             /* wildcard address family */
145        mib[4] = 0;
146        mib[5] = 0;             /* no flags */
147        if (__sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
148                return NULL;
149        if ((buf = malloc(needed)) == NULL) {
150                errno = ENOMEM;
151                goto end;
152        }
153        /* XXX: we may have allocated too much than necessary */
154        if ((ifbuf = malloc(needed)) == NULL) {
155                errno = ENOMEM;
156                goto end;
157        }
158        if ((ifx = (struct _ifx *)malloc(sizeof(*ifx) * ifxs)) == NULL) {
159                errno = ENOMEM;
160                goto end;
161        }
162        if (__sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
163                /* sysctl has set errno */
164                goto end;
165        }
166        lim = buf + needed;
167        for (next = buf; next < lim; next += rtm->rtm_msglen) {
168                rtm = (struct rt_msghdr *)next;
169                if (rtm->rtm_version != RTM_VERSION) {
170                        errno = EPROTONOSUPPORT;
171                        goto end;
172                }
173                switch (rtm->rtm_type) {
174                case RTM_IFINFO:
175                        ifm = (struct if_msghdr *)rtm;
176                        ifx[ifn].if_index = ifm->ifm_index;
177                        ifx[ifn].if_off = off;
178                        cp = (char *)(ifm + 1);
179                        for (i = 1; i; i <<= 1) {
180                                if (i & ifm->ifm_addrs) {
181                                        sa = (struct sockaddr *)cp;
182                                        ADVANCE(cp, sa);
183                                }
184                        }
185                        if (++ifn == ifxs) {
186                                /* we need more memory */
187                                struct _ifx *newifx;
188
189                                ifxs *= 2;
190                                if ((newifx = (struct _ifx *)malloc(sizeof(*newifx) * ifxs)) == NULL) {
191                                        errno = ENOMEM;
192                                        goto end;
193                                }
194
195                                /* copy and free old data */
196                                memcpy(newifx, ifx, (sizeof(*ifx) * ifxs) / 2);
197                                free(ifx);
198                                ifx = newifx;
199                        }
200                }
201        }
202        hlen = sizeof(struct if_nameindex) * (ifn + 1);
203        if ((cp = (char *)malloc(hlen + off)) == NULL) {
204                errno = ENOMEM;
205                goto end;
206        }
207        bcopy(ifbuf, cp + hlen, off);
208        ret = (struct if_nameindex *)cp;
209        for (i = 0; i < ifn; i++) {
210                ret[i].if_index = ifx[i].if_index;
211                ret[i].if_name = cp + hlen + ifx[i].if_off;
212        }
213        ret[ifn].if_index = 0;
214        ret[ifn].if_name = NULL;
215
216  end:
217        if (buf) free(buf);
218        if (ifbuf) free(ifbuf);
219        if (ifx) free(ifx);
220
221        return ret;
222}
223
224void if_freenameindex(ptr)
225        struct if_nameindex *ptr;
226{
227        free(ptr);
228}
Note: See TracBrowser for help on using the repository browser.