]> arthur.barton.de Git - netatalk.git/blob - libatalk/util/getiface.c
Warning fixes.
[netatalk.git] / libatalk / util / getiface.c
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 #include <net/if.h>
25 #include <errno.h>
26
27 #ifdef __svr4__
28 #include <sys/sockio.h>
29 #endif
30
31 #include <atalk/util.h>
32
33 /* allocation size for interface list. */
34 #define IFACE_NUM 5
35
36 /* we leave all of the ioctl's to the application */
37 static int addname(char **list, int *i, int *length, const char *name) 
38
39 {
40     /* if we've run out of room, allocate some more. just return
41      * the present list if we can't. */
42      if (*i >= *length) {
43       char **new = realloc(list, sizeof(char **)*(*length + IFACE_NUM));
44        
45       if (!new) /* just break if we can't allocate anything */
46         return -1;
47       *length += IFACE_NUM;
48     }
49      
50     if ((list[*i] = strdup(name)) == NULL)
51       return -1;
52
53     (*i)++;
54     list[*i] = NULL; /* zero out the next entry */
55     return 0;
56 }
57
58
59 static int getifaces(const int sockfd, char **list, int *length)
60 {
61 #ifdef HAVE_IFNAMEINDEX
62       struct if_nameindex *ifstart, *ifs;
63       int i = 0;
64   
65       if (!list || *length < 1) 
66         return 0;
67
68       ifs = ifstart = if_nameindex();
69       while (ifs && ifs->if_name) {
70         /* just bail if there's a problem */
71         if (addname(list, &i, length, ifs->if_name) < 0)
72           break;
73         ifs++;
74       }
75
76       if_freenameindex(ifstart);
77       return i;
78
79 #else
80     struct ifconf       ifc;
81     struct ifreq        ifrs[ 64 ], *ifr, *nextifr;
82     int                 ifrsize, i = 0;
83
84     if (!list || *length < 1)
85       return 0;
86
87     memset( &ifc, 0, sizeof( struct ifconf ));
88     ifc.ifc_len = sizeof( ifrs );
89     memset( ifrs, 0, sizeof( ifrs ));
90     ifc.ifc_buf = (caddr_t)ifrs;
91     if ( ioctl( sockfd, SIOCGIFCONF, &ifc ) < 0 ) {
92         return 0;
93     }
94
95     for ( ifr = ifc.ifc_req; ifc.ifc_len >= 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(list, &i, length, ifr->ifr_name) < 0)
108           break;
109     }
110     return i;
111 #endif
112 }
113
114
115 /*
116  * Get interfaces from the kernel. we keep an extra null entry to signify
117  * the end of the interface list. 
118  */
119 char **getifacelist()
120 {
121   char **list = (char **) malloc(sizeof(char **)*(IFACE_NUM + 1));
122   char **new;
123   int length = IFACE_NUM, i, fd;
124
125   if (!list)
126     return NULL;
127       
128   if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
129     return NULL;
130
131   if ((i = getifaces(fd, list, &length)) == 0) {
132     free(list);
133     close(fd);
134     return NULL;
135   }
136   close(fd);
137
138   if ((i < length) && 
139       (new = (char **) realloc(list, sizeof(char **)*(i + 1))))
140     return new;
141
142   return list;
143 }
144
145
146 /* go through and free the interface list */
147 void freeifacelist(char **ifacelist)
148 {
149   char *value, **list = ifacelist;
150
151   if (!ifacelist)
152     return;
153
154   while ((value = *list++)) {
155     free(value);
156   }
157
158   free(ifacelist);
159 }