• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.5/libatalk/util/
1/*
2 * Copyright (c) 1990,1993 Regents of The University of Michigan.
3 * Copyright (c) 1999-2000 Adrian Sun.
4 * All Rights Reserved. See COPYRIGHT.
5 */
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14
15#ifdef HAVE_STDINT_H
16#include <stdint.h>
17#endif
18
19#include <sys/types.h>
20#include <sys/socket.h>
21#include <sys/ioctl.h>
22#include <netinet/in.h>
23#include <netinet/tcp.h>
24#ifdef TRU64
25#include <sys/mbuf.h>
26#include <net/route.h>
27#endif /* TRU64 */
28#include <net/if.h>
29#include <errno.h>
30
31#ifdef __svr4__
32#include <sys/sockio.h>
33#endif
34
35#include <atalk/util.h>
36
37/* allocation size for interface list. */
38#define IFACE_NUM 5
39
40/* we leave all of the ioctl's to the application */
41static int addname(char **list, int *i, const char *name)
42
43{
44    /* if we've run out of room, allocate some more. just return
45     * the present list if we can't. */
46
47    if ((list[*i] = strdup(name)) == NULL)
48      return -1;
49
50    (*i)++;
51    list[*i] = NULL; /* zero out the next entry */
52    return 0;
53}
54
55
56static int getifaces(const int sockfd, char ***list)
57{
58#ifdef HAVE_IFNAMEINDEX
59      struct if_nameindex *ifstart, *ifs;
60      int i = 0;
61	  char **new;
62
63      ifs = ifstart = if_nameindex();
64
65	  new = (char **) malloc((sizeof(ifs)/sizeof(struct if_nameindex) + 1) * sizeof(char *));
66      while (ifs && ifs->if_name) {
67	/* just bail if there's a problem */
68	if (addname(new, &i, ifs->if_name) < 0)
69	  break;
70	ifs++;
71      }
72
73      if_freenameindex(ifstart);
74	  *list = new;
75      return i;
76
77#else
78    struct ifconf	ifc;
79    struct ifreq	ifrs[ 64 ], *ifr, *nextifr;
80    int			ifrsize, i = 0;
81	char **new;
82
83    if (!list)
84      return 0;
85
86    memset( &ifc, 0, sizeof( struct ifconf ));
87    ifc.ifc_len = sizeof( ifrs );
88    memset( ifrs, 0, sizeof( ifrs ));
89    ifc.ifc_buf = (caddr_t)ifrs;
90    if ( ioctl( sockfd, SIOCGIFCONF, &ifc ) < 0 ) {
91	return 0;
92    }
93
94	new = (char **) malloc((ifc.ifc_len/sizeof(struct ifreq) + 1) * sizeof(char *));
95    for ( ifr = ifc.ifc_req; ifc.ifc_len >= (int) sizeof( struct ifreq );
96	    ifc.ifc_len -= ifrsize, ifr = nextifr ) {
97#ifdef BSD4_4
98 	ifrsize = sizeof(ifr->ifr_name) +
99	  (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)
100	   ? ifr->ifr_addr.sa_len : sizeof(struct sockaddr));
101#else /* !BSD4_4 */
102	ifrsize = sizeof( struct ifreq );
103#endif /* BSD4_4 */
104	nextifr = (struct ifreq *)((caddr_t)ifr + ifrsize );
105
106	/* just bail if there's a problem */
107	if (addname(new, &i, ifr->ifr_name) < 0)
108	  break;
109    }
110	*list = new;
111    return i;
112#endif
113}
114
115
116/*
117 * Get interfaces from the kernel. we keep an extra null entry to signify
118 * the end of the interface list.
119 */
120char **getifacelist(void)
121{
122  char **list = NULL; /* FIXME */
123  int  i, fd;
124
125  if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
126    return NULL;
127
128  if ((i = getifaces(fd, &list)) == 0) {
129    free(list);
130    close(fd);
131    return NULL;
132  }
133  close(fd);
134
135  return list;
136}
137
138
139/* go through and free the interface list */
140void freeifacelist(char **ifacelist)
141{
142  char *value, **list = ifacelist;
143
144  if (!ifacelist)
145    return;
146
147  while ((value = *list++)) {
148    free(value);
149  }
150
151  free(ifacelist);
152}
153