00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef AUTOCONF_TEST
00034 #include "config.h"
00035 #endif
00036
00037 #include <unistd.h>
00038 #include <stdio.h>
00039 #include <sys/types.h>
00040 #include <netdb.h>
00041 #include <sys/ioctl.h>
00042 #include <netdb.h>
00043 #include <sys/ioctl.h>
00044 #include <sys/time.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048
00049 #ifdef HAVE_SYS_TIME_H
00050 #include <sys/time.h>
00051 #endif
00052
00053 #ifndef SIOCGIFCONF
00054 #ifdef HAVE_SYS_SOCKIO_H
00055 #include <sys/sockio.h>
00056 #endif
00057 #endif
00058
00059 #ifdef HAVE_STDLIB_H
00060 #include <stdlib.h>
00061 #endif
00062
00063 #ifdef HAVE_STRING_H
00064 #include <string.h>
00065 #endif
00066
00067 #ifdef HAVE_STRINGS_H
00068 #include <strings.h>
00069 #endif
00070
00071 #ifdef __COMPAR_FN_T
00072 #define QSORT_CAST (__compar_fn_t)
00073 #endif
00074
00075 #ifndef QSORT_CAST
00076 #define QSORT_CAST (int (*)(const void *, const void *))
00077 #endif
00078
00079 #ifdef HAVE_NET_IF_H
00080 #include <net/if.h>
00081 #endif
00082
00083 #include "interfaces.h"
00084
00085 #if HAVE_IFACE_IFCONF
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
00096 {
00097 struct ifconf ifc;
00098 char buff[8192];
00099 int fd, i, n;
00100 struct ifreq *ifr=NULL;
00101 int total = 0;
00102 struct in_addr ipaddr;
00103 struct in_addr nmask;
00104 char *iname;
00105
00106 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
00107 return -1;
00108 }
00109
00110 ifc.ifc_len = sizeof(buff);
00111 ifc.ifc_buf = buff;
00112
00113 if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
00114 close(fd);
00115 return -1;
00116 }
00117
00118 ifr = ifc.ifc_req;
00119
00120 n = ifc.ifc_len / sizeof(struct ifreq);
00121
00122
00123 for (i=n-1;i>=0 && total < max_interfaces;i--) {
00124 if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) {
00125 continue;
00126 }
00127
00128 iname = ifr[i].ifr_name;
00129 ipaddr = (*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr;
00130
00131 if (ioctl(fd, SIOCGIFFLAGS, &ifr[i]) != 0) {
00132 continue;
00133 }
00134
00135 if (!(ifr[i].ifr_flags & IFF_UP)) {
00136 continue;
00137 }
00138
00139 if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) {
00140 continue;
00141 }
00142
00143 nmask = ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr;
00144
00145 strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1);
00146 ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
00147 ifaces[total].ip = ipaddr;
00148 ifaces[total].netmask = nmask;
00149 total++;
00150 }
00151
00152 close(fd);
00153
00154 return total;
00155 }
00156
00157 #define _FOUND_IFACE_ANY
00158 #endif
00159 #ifdef HAVE_IFACE_IFREQ
00160
00161 #ifndef I_STR
00162 #include <sys/stropts.h>
00163 #endif
00164
00165
00166
00167
00168
00169 static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
00170 {
00171 struct ifreq ifreq;
00172 struct strioctl strioctl;
00173 char buff[8192];
00174 int fd, i, n;
00175 struct ifreq *ifr=NULL;
00176 int total = 0;
00177 struct in_addr ipaddr;
00178 struct in_addr nmask;
00179 char *iname;
00180
00181 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
00182 return -1;
00183 }
00184
00185 strioctl.ic_cmd = SIOCGIFCONF;
00186 strioctl.ic_dp = buff;
00187 strioctl.ic_len = sizeof(buff);
00188 if (ioctl(fd, I_STR, &strioctl) < 0) {
00189 close(fd);
00190 return -1;
00191 }
00192
00193
00194
00195 n = strioctl.ic_len / sizeof(struct ifreq);
00196
00197
00198
00199
00200 if (n*sizeof(struct ifreq) + sizeof(int) == strioctl.ic_len) {
00201 ifr = (struct ifreq *)(buff + sizeof(int));
00202 } else {
00203 ifr = (struct ifreq *)buff;
00204 }
00205
00206
00207
00208 for (i = 0; i<n && total < max_interfaces; i++) {
00209 ifreq = ifr[i];
00210
00211 strioctl.ic_cmd = SIOCGIFFLAGS;
00212 strioctl.ic_dp = (char *)&ifreq;
00213 strioctl.ic_len = sizeof(struct ifreq);
00214 if (ioctl(fd, I_STR, &strioctl) != 0) {
00215 continue;
00216 }
00217
00218 if (!(ifreq.ifr_flags & IFF_UP)) {
00219 continue;
00220 }
00221
00222 strioctl.ic_cmd = SIOCGIFADDR;
00223 strioctl.ic_dp = (char *)&ifreq;
00224 strioctl.ic_len = sizeof(struct ifreq);
00225 if (ioctl(fd, I_STR, &strioctl) != 0) {
00226 continue;
00227 }
00228
00229 ipaddr = (*(struct sockaddr_in *) &ifreq.ifr_addr).sin_addr;
00230 iname = ifreq.ifr_name;
00231
00232 strioctl.ic_cmd = SIOCGIFNETMASK;
00233 strioctl.ic_dp = (char *)&ifreq;
00234 strioctl.ic_len = sizeof(struct ifreq);
00235 if (ioctl(fd, I_STR, &strioctl) != 0) {
00236 continue;
00237 }
00238
00239 nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
00240
00241 strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1);
00242 ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
00243 ifaces[total].ip = ipaddr;
00244 ifaces[total].netmask = nmask;
00245
00246 total++;
00247 }
00248
00249 close(fd);
00250
00251 return total;
00252 }
00253
00254 #define _FOUND_IFACE_ANY
00255 #endif
00256 #ifdef HAVE_IFACE_AIX
00257
00258
00259
00260
00261 static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
00262 {
00263 char buff[8192];
00264 int fd, i;
00265 struct ifconf ifc;
00266 struct ifreq *ifr=NULL;
00267 struct in_addr ipaddr;
00268 struct in_addr nmask;
00269 char *iname;
00270 int total = 0;
00271
00272 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
00273 return -1;
00274 }
00275
00276
00277 ifc.ifc_len = sizeof(buff);
00278 ifc.ifc_buf = buff;
00279
00280 if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
00281 close(fd);
00282 return -1;
00283 }
00284
00285 ifr = ifc.ifc_req;
00286
00287
00288 i = ifc.ifc_len;
00289
00290 while (i > 0 && total < max_interfaces) {
00291 uint_t inc;
00292
00293 inc = ifr->ifr_addr.sa_len;
00294
00295 if (ioctl(fd, SIOCGIFADDR, ifr) != 0) {
00296 goto next;
00297 }
00298
00299 ipaddr = (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr;
00300 iname = ifr->ifr_name;
00301
00302 if (ioctl(fd, SIOCGIFFLAGS, ifr) != 0) {
00303 goto next;
00304 }
00305
00306 if (!(ifr->ifr_flags & IFF_UP)) {
00307 goto next;
00308 }
00309
00310 if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) {
00311 goto next;
00312 }
00313
00314 nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
00315
00316 strncpy(ifaces[total].name, iname, sizeof(ifaces[total].name)-1);
00317 ifaces[total].name[sizeof(ifaces[total].name)-1] = 0;
00318 ifaces[total].ip = ipaddr;
00319 ifaces[total].netmask = nmask;
00320
00321 total++;
00322
00323 next:
00324
00325
00326
00327
00328
00329
00330
00331 if (inc < sizeof(ifr->ifr_addr))
00332 inc = sizeof(ifr->ifr_addr);
00333 inc += IFNAMSIZ;
00334
00335 ifr = (struct ifreq*) (((char*) ifr) + inc);
00336 i -= inc;
00337 }
00338
00339
00340 close(fd);
00341 return total;
00342 }
00343
00344 #define _FOUND_IFACE_ANY
00345 #endif
00346 #ifndef _FOUND_IFACE_ANY
00347 static int _get_interfaces(struct iface_struct *ifaces, int max_interfaces)
00348 {
00349 return -1;
00350 }
00351 #endif
00352
00353
00354 static int iface_comp(struct iface_struct *i1, struct iface_struct *i2)
00355 {
00356 int r;
00357 r = strcmp(i1->name, i2->name);
00358 if (r) return r;
00359 r = ntohl(i1->ip.s_addr) - ntohl(i2->ip.s_addr);
00360 if (r) return r;
00361 r = ntohl(i1->netmask.s_addr) - ntohl(i2->netmask.s_addr);
00362 return r;
00363 }
00364
00365 int get_interfaces(struct iface_struct *ifaces, int max_interfaces);
00366
00367
00368 int get_interfaces(struct iface_struct *ifaces, int max_interfaces)
00369 {
00370 int total, i, j;
00371
00372 total = _get_interfaces(ifaces, max_interfaces);
00373 if (total <= 0) return total;
00374
00375
00376 qsort(ifaces, total, sizeof(ifaces[0]), QSORT_CAST iface_comp);
00377
00378 for (i=1;i<total;) {
00379 if (iface_comp(&ifaces[i-1], &ifaces[i]) == 0) {
00380 for (j=i-1;j<total-1;j++) {
00381 ifaces[j] = ifaces[j+1];
00382 }
00383 total--;
00384 } else {
00385 i++;
00386 }
00387 }
00388
00389 return total;
00390 }
00391
00392
00393 #ifdef AUTOCONF_TEST
00394
00395
00396 int main()
00397 {
00398 struct iface_struct ifaces[MAX_INTERFACES];
00399 int total = get_interfaces(ifaces, MAX_INTERFACES);
00400 int i;
00401
00402 printf("got %d interfaces:\n", total);
00403 if (total <= 0) exit(1);
00404
00405 for (i=0;i<total;i++) {
00406 printf("%-10s ", ifaces[i].name);
00407 printf("IP=%s ", inet_ntoa(ifaces[i].ip));
00408 printf("NETMASK=%s\n", inet_ntoa(ifaces[i].netmask));
00409 }
00410 return 0;
00411 }
00412 #endif