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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [common/] [current/] [src/] [ifaddrs.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      src/ifaddrs.c
4
//
5
//==========================================================================
6
// ####BSDCOPYRIGHTBEGIN####                                    
7
// -------------------------------------------                  
8
// This file is part of eCos, the Embedded Configurable Operating System.
9
//
10
// Portions of this software may have been derived from FreeBSD, OpenBSD,
11
// or other sources, and if so are covered by the appropriate copyright
12
// and license included herein.                                 
13
//
14
// Portions created by the Free Software Foundation are         
15
// Copyright (C) 2002 Free Software Foundation, Inc.            
16
// -------------------------------------------                  
17
// ####BSDCOPYRIGHTEND####                                      
18
//==========================================================================
19
 
20
//
21
// Adapted from KAME getifaddrs.c, if_nametoindex.c, if_indextoname.c
22
//
23
 
24
/*      $KAME: getifaddrs.c,v 1.9 2001/08/20 02:31:20 itojun Exp $      */
25
/*      $KAME: if_nametoindex.c,v 1.6 2000/11/24 08:18:54 itojun Exp $  */
26
/*      $KAME: if_indextoname.c,v 1.7 2000/11/08 03:09:30 itojun Exp $  */
27
 
28
/*
29
 * Copyright (c) 1995, 1999
30
 *      Berkeley Software Design, Inc.  All rights reserved.
31
 *
32
 * Redistribution and use in source and binary forms, with or without
33
 * modification, are permitted provided that the following conditions
34
 * are met:
35
 * 1. Redistributions of source code must retain the above copyright
36
 *    notice, this list of conditions and the following disclaimer.
37
 *
38
 * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
39
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41
 * ARE DISCLAIMED.  IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
42
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48
 * SUCH DAMAGE.
49
 *
50
 *      BSDI getifaddrs.c,v 2.12 2000/02/23 14:51:59 dab Exp
51
 */
52
 
53
#include <cyg/infra/diag.h>
54
 
55
#include <unistd.h>
56
#include <stdlib.h>
57
#include <string.h>
58
 
59
#undef _KERNEL
60
#undef __INSIDE_NET
61
#include <sys/param.h>
62
#include <sys/types.h>
63
#include <sys/ioctl.h>
64
#include <sys/socket.h>
65
#include <net/if.h>
66
#include <net/if_dl.h>
67
#ifndef CYGPKG_NET_OPENBSD_STACK
68
#include <net/if_var.h>
69
#endif
70
#include <errno.h>
71
#include <netinet/in.h>
72
#include <net/netdb.h>
73
#include <ifaddrs.h>
74
#include <netinet/in_var.h>
75
 
76
 
77
#if !defined(AF_LINK)
78
#define SA_LEN(sa)      sizeof(struct sockaddr)
79
#endif
80
 
81
#if !defined(SA_LEN)
82
#define SA_LEN(sa)      (sa)->sa_len
83
#endif
84
 
85
#define SALIGN  (sizeof(long) - 1)
86
#define SA_RLEN(sa)     ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
87
 
88
#ifndef ALIGNBYTES
89
/*
90
 * On systems with a routing socket, ALIGNBYTES should match the value
91
 * that the kernel uses when building the messages.
92
 */
93
#define ALIGNBYTES      XXX
94
#endif
95
#ifndef ALIGN
96
#define ALIGN(p)        (((u_long)(p) + ALIGNBYTES) &~ ALIGNBYTES)
97
#endif
98
 
99
int
100
getifaddrs(struct ifaddrs **pif)
101
{
102
    int icnt = 1;  // Interface count
103
    int dcnt = 0;  // Data [length] count
104
    int ncnt = 0;  // Length of interface names
105
    char *buf;
106
#define IF_WORK_SPACE_SZ        1024
107
    int i, sock;
108
#ifdef CYGPKG_NET_INET6
109
    int sock6;
110
    struct in6_ifreq ifrq6;
111
#endif
112
    struct ifconf ifc;
113
    struct ifreq *ifr, *lifr;
114
    struct ifreq ifrq;
115
    char *data, *names;
116
    struct ifaddrs *ifa, *ift;
117
 
118
    buf = malloc(IF_WORK_SPACE_SZ);
119
    if (buf == NULL)
120
        return (-1);
121
    ifc.ifc_buf = buf;
122
    ifc.ifc_len = IF_WORK_SPACE_SZ;
123
 
124
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
125
    {
126
        free(buf);
127
        return (-1);
128
    }
129
    i =  ioctl(sock, SIOCGIFCONF, (char *)&ifc);
130
 
131
    if (i < 0) {
132
        close(sock);
133
        free(buf);
134
        return (-1);
135
    }
136
 
137
    ifr = ifc.ifc_req;
138
    lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
139
 
140
    while (ifr < lifr) {
141
        struct sockaddr *sa;
142
 
143
        sa = &ifr->ifr_addr;
144
        ++icnt;
145
        dcnt += SA_RLEN(sa) * 3;  /* addr, mask, brdcst */
146
        ncnt += sizeof(ifr->ifr_name) + 1;
147
 
148
        if (SA_LEN(sa) < sizeof(*sa))
149
            ifr = (struct ifreq *)(((char *)sa) + sizeof(*sa));
150
        else
151
            ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
152
    }
153
 
154
    if (icnt + dcnt + ncnt == 1) {
155
        // Nothing found
156
        *pif = NULL;
157
        free(buf);
158
        close(sock);
159
        return (0);
160
    }
161
    data = malloc(sizeof(struct ifaddrs) * icnt + dcnt + ncnt);
162
    if (data == NULL) {
163
        free(buf);
164
        close(sock);
165
        return(-1);
166
    }
167
 
168
    ifa = (struct ifaddrs *)(void *)data;
169
    data += sizeof(struct ifaddrs) * icnt;
170
    names = data + dcnt;
171
 
172
    memset(ifa, 0, sizeof(struct ifaddrs) * icnt);
173
    ift = ifa;
174
 
175
    ifr = ifc.ifc_req;
176
 
177
#ifdef CYGPKG_NET_INET6
178
    if ((sock6 = socket(AF_INET6, SOCK_STREAM, 0)) < 0) {
179
      free(buf);
180
      free(ifa);
181
      close(sock);
182
      return (-1);
183
    }
184
#endif
185
 
186
    while (ifr < lifr) {
187
       struct sockaddr * sa;
188
 
189
        ift->ifa_name = names;
190
        names[sizeof(ifr->ifr_name)] = 0;
191
        strncpy(names, ifr->ifr_name, sizeof(ifr->ifr_name));
192
        while (*names++) ;
193
 
194
        ift->ifa_addr = (struct sockaddr *)data;
195
        sa = &ifr->ifr_addr;
196
        memcpy(data, sa, SA_LEN(sa));
197
        data += SA_RLEN(sa);
198
 
199
        if ((sa->sa_family == AF_INET) || (sa->sa_family == AF_INET6)) {
200
          struct sockaddr *sa_netmask = NULL;
201
          struct sockaddr *sa_broadcast = NULL;
202
          struct sockaddr *sa_dst = NULL;
203
 
204
          memset(&ifrq,0,sizeof(ifrq));
205
          strcpy(ifrq.ifr_name,ifr->ifr_name);
206
          ioctl( sock, SIOCGIFFLAGS, &ifrq );
207
 
208
          ift->ifa_flags = ifrq.ifr_flags;
209
 
210
          memcpy(&ifrq.ifr_addr, ift->ifa_addr,sizeof(struct sockaddr));
211
          if (sa->sa_family == AF_INET) {
212
            ioctl(sock, SIOCGIFNETMASK, &ifrq);
213
            sa_netmask = &ifrq.ifr_addr;
214
          }
215
#ifdef CYGPKG_NET_INET6
216
          if (sa->sa_family == AF_INET6) {
217
            memset(&ifrq6,0,sizeof(ifrq));
218
            strcpy(ifrq6.ifr_name,ifr->ifr_name);
219
            memcpy(&ifrq6.ifr_addr, ift->ifa_addr,sizeof(struct sockaddr));
220
 
221
            ioctl(sock6, SIOCGIFNETMASK_IN6, &ifrq6);
222
            sa_netmask = (struct sockaddr *)&ifrq6.ifr_addr;
223
          }
224
#endif
225
          ift->ifa_netmask = (struct sockaddr *)data;
226
          memcpy(data, sa_netmask, SA_LEN(sa_netmask));
227
          data += SA_RLEN(sa_netmask);
228
 
229
          memcpy(&ifrq.ifr_addr, ift->ifa_addr,sizeof(struct sockaddr));
230
          if ((sa->sa_family == AF_INET) && (ift->ifa_flags & IFF_BROADCAST)) {
231
            if (ioctl(sock, SIOCGIFBRDADDR, &ifrq) == 0) {
232
              sa_broadcast = &ifrq.ifr_addr;
233
              ift->ifa_broadaddr = (struct sockaddr *)data;
234
              memcpy(data, sa_broadcast, SA_LEN(sa_broadcast));
235
              data += SA_RLEN(sa_broadcast);
236
            }
237
          }
238
 
239
          memcpy(&ifrq.ifr_addr, ift->ifa_addr,sizeof(struct sockaddr));
240
          if ((sa->sa_family == AF_INET) &&
241
              (ift->ifa_flags & IFF_POINTOPOINT)) {
242
            if (ioctl(sock, SIOCGIFDSTADDR, &ifrq) == 0) {
243
              sa_dst = &ifrq.ifr_addr;
244
              ift->ifa_dstaddr = (struct sockaddr *)data;
245
              memcpy(data, sa_dst, SA_LEN(sa_dst));
246
              data += SA_RLEN(sa_dst);
247
            }
248
          }
249
        }
250
 
251
        if (SA_LEN(sa) < sizeof(*sa))
252
            ifr = (struct ifreq *)(((char *)sa) + sizeof(*sa));
253
        else
254
            ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
255
        ift = (ift->ifa_next = ift + 1);
256
    }
257
    free(buf);
258
 
259
    if (--ift >= ifa) {
260
        ift->ifa_next = NULL;
261
        *pif = ifa;
262
    } else {
263
        *pif = NULL;
264
        free(ifa);
265
    }
266
#ifdef CYGPKG_NET_INET6
267
    close(sock6);
268
#endif
269
    close(sock);
270
    return (0);
271
}
272
 
273
void
274
freeifaddrs(struct ifaddrs *ifp)
275
{
276
    free(ifp);
277
}
278
 
279
void
280
_show_all_interfaces(void)
281
{
282
    struct ifaddrs *iflist, *ifp;
283
    char addr[64];
284
    int indx;
285
 
286
    if (getifaddrs(&iflist) < 0) {
287
        diag_printf("Can't get interface information!!\n");
288
        return;
289
    }
290
    ifp = iflist;
291
    while (ifp != (struct ifaddrs *)NULL) {
292
        if (ifp->ifa_addr->sa_family != AF_LINK) {
293
            getnameinfo (ifp->ifa_addr, ifp->ifa_addr->sa_len, addr,
294
                         sizeof(addr), 0, 0, NI_NUMERICHOST);
295
            diag_printf("%p - %s - %s\n", ifp, ifp->ifa_name, addr);
296
        }
297
        ifp = ifp->ifa_next;
298
    }
299
    indx = if_nametoindex(iflist->ifa_name);
300
    diag_printf("indx(%s) = %d\n", iflist->ifa_name, indx);
301
    if (indx > 0) {
302
        if (if_indextoname(indx, addr)) {
303
            diag_printf("index(%s) = %d/%s\n", iflist->ifa_name, indx, addr);
304
        } else {
305
            diag_printf("index(%s) = %d: %s\n", iflist->ifa_name, indx, strerror(errno));
306
        }
307
    } else {
308
        diag_printf("index(%s): %s\n", iflist->ifa_name, strerror(errno));
309
    }
310
    freeifaddrs(iflist);
311
}
312
 
313
/*
314
 * From RFC 2553:
315
 *
316
 * 4.1 Name-to-Index
317
 *
318
 *
319
 *    The first function maps an interface name into its corresponding
320
 *    index.
321
 *
322
 *       #include <net/if.h>
323
 *
324
 *       unsigned int  if_nametoindex(const char *ifname);
325
 *
326
 *    If the specified interface name does not exist, the return value is
327
 *    0, and errno is set to ENXIO.  If there was a system error (such as
328
 *    running out of memory), the return value is 0 and errno is set to the
329
 *    proper value (e.g., ENOMEM).
330
 */
331
 
332
unsigned int
333
if_nametoindex(const char *ifname)
334
{
335
    struct ifaddrs *ifaddrs, *ifa;
336
    unsigned int ni;
337
 
338
    if (getifaddrs(&ifaddrs) < 0)
339
        return(0);
340
 
341
    ni = 0;
342
 
343
    for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
344
        if (ifa->ifa_addr &&
345
            ifa->ifa_addr->sa_family == AF_LINK &&
346
            strcmp(ifa->ifa_name, ifname) == 0) {
347
            ni = ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index;
348
            break;
349
        }
350
    }
351
 
352
    freeifaddrs(ifaddrs);
353
    if (!ni)
354
        errno = ENXIO;
355
    return(ni);
356
}
357
 
358
/*
359
 * From RFC 2533:
360
 *
361
 * The second function maps an interface index into its corresponding
362
 * name.
363
 *
364
 *    #include <net/if.h>
365
 *
366
 *    char  *if_indextoname(unsigned int ifindex, char *ifname);
367
 *
368
 * The ifname argument must point to a buffer of at least IF_NAMESIZE
369
 * bytes into which the interface name corresponding to the specified
370
 * index is returned.  (IF_NAMESIZE is also defined in <net/if.h> and
371
 * its value includes a terminating null byte at the end of the
372
 * interface name.) This pointer is also the return value of the
373
 * function.  If there is no interface corresponding to the specified
374
 * index, NULL is returned, and errno is set to ENXIO, if there was a
375
 * system error (such as running out of memory), if_indextoname returns
376
 * NULL and errno would be set to the proper value (e.g., ENOMEM).
377
 */
378
 
379
char *
380
if_indextoname(unsigned int ifindex, char *ifname)
381
{
382
    struct ifaddrs *ifaddrs, *ifa;
383
    int error = 0;
384
 
385
    if (getifaddrs(&ifaddrs) < 0)
386
        return(NULL);   /* getifaddrs properly set errno */
387
 
388
    for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
389
        if (ifa->ifa_addr &&
390
            ifa->ifa_addr->sa_family == AF_LINK &&
391
            ifindex == ((struct sockaddr_dl*)ifa->ifa_addr)->sdl_index)
392
            break;
393
    }
394
 
395
    if (ifa == NULL) {
396
        error = ENXIO;
397
        ifname = NULL;
398
    }
399
    else
400
        strncpy(ifname, ifa->ifa_name, IFNAMSIZ);
401
 
402
    freeifaddrs(ifaddrs);
403
 
404
    errno = error;
405
    return(ifname);
406
}

powered by: WebSVN 2.1.0

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