Lines 1-149
Link Here
|
1 |
--- ifaddr.c.orig 2010-01-14 23:49:24.515378502 +0300 |
|
|
2 |
+++ ifaddr.c 2010-01-14 23:50:07.723908032 +0300 |
3 |
@@ -10,6 +10,7 @@ |
4 |
#include <stdlib.h> |
5 |
#include <netinet/in.h> |
6 |
#include <arpa/inet.h> |
7 |
+#include <ifaddrs.h> |
8 |
|
9 |
#include <assert.h> |
10 |
#include <limits.h> |
11 |
@@ -21,114 +22,29 @@ |
12 |
*/ |
13 |
int |
14 |
if2addr( const char* ifname, |
15 |
- struct sockaddr *addr, size_t addrlen ) |
16 |
+ struct sockaddr_in *addr, size_t addrlen ) |
17 |
{ |
18 |
- int rc, sockfd; |
19 |
- char *buf, *rec; |
20 |
- size_t buflen, sa_len; |
21 |
- int last_len; |
22 |
- struct ifconf ifc; |
23 |
- struct ifreq ifr; |
24 |
- |
25 |
- static size_t IFC_TABLE_SIZE; |
26 |
- |
27 |
- static const size_t IFC_ENTRIES = 32; |
28 |
- static const size_t MAX_IFCBUF_SIZE = (1024 * 256); |
29 |
- |
30 |
- IFC_TABLE_SIZE = sizeof(struct ifreq) * IFC_ENTRIES; |
31 |
+ int rc = -1; |
32 |
+ struct ifaddrs *ifr, *ifc; |
33 |
+ struct sockaddr_in *sin; |
34 |
|
35 |
assert( ifname && addr && addrlen ); |
36 |
- rc = 0; |
37 |
- |
38 |
- /* acquire the list of network interfaces */ |
39 |
- |
40 |
- sockfd = socket( AF_INET, SOCK_DGRAM, 0 ); |
41 |
- if( -1 == sockfd ) return -1; |
42 |
- |
43 |
- buf = NULL; buflen = IFC_TABLE_SIZE; last_len = 0; |
44 |
- for( ; buflen < MAX_IFCBUF_SIZE; buflen += IFC_TABLE_SIZE ) { |
45 |
- if( NULL == (buf = malloc( buflen )) ) { |
46 |
- rc = -1; |
47 |
- break; |
48 |
- } |
49 |
- |
50 |
- ifc.ifc_len = buflen; |
51 |
- ifc.ifc_buf = buf; |
52 |
- if( ioctl( sockfd, SIOCGIFCONF, &ifc ) < 0 ) { |
53 |
- if( (EINVAL != errno) || (last_len != 0) ) { |
54 |
- rc = errno; |
55 |
- break; |
56 |
- } |
57 |
- } |
58 |
- else { |
59 |
- if( ifc.ifc_len == last_len ) |
60 |
- break; |
61 |
- else |
62 |
- last_len = ifc.ifc_len; |
63 |
- } |
64 |
- |
65 |
- free( buf ); |
66 |
- buf = NULL; |
67 |
- } /* for */ |
68 |
- |
69 |
- (void) close( sockfd ); |
70 |
- if( buflen > MAX_IFCBUF_SIZE ) rc = -1; |
71 |
- |
72 |
- if( 0 != rc ) { |
73 |
- if( NULL != buf ) free( buf ); |
74 |
- return rc; |
75 |
- } |
76 |
|
77 |
- assert( ifc.ifc_buf ); |
78 |
+ getifaddrs(&ifr); |
79 |
|
80 |
- /* look for ifname in the list */ |
81 |
- |
82 |
- for( rec = ifc.ifc_buf; rec < (ifc.ifc_buf + ifc.ifc_len); ) { |
83 |
- (void) memcpy( &ifr, rec, sizeof(struct ifreq) ); |
84 |
- |
85 |
- #ifdef NO_SOCKADDR_SA_LEN |
86 |
- switch( ifr.ifr_addr.sa_family ) |
87 |
- { |
88 |
- case AF_INET: |
89 |
- sa_len = sizeof(struct sockaddr); break; |
90 |
-#ifndef NO_INET6_SUPPORT |
91 |
- case AF_INET6: |
92 |
- sa_len = sizeof(struct sockaddr_in6); break; |
93 |
-#endif |
94 |
- default: |
95 |
- rc = -1; break; |
96 |
- } |
97 |
- #else |
98 |
- sa_len = ifr.ifr_addr.sa_len; |
99 |
- #endif |
100 |
- if( 0 != rc ) break; |
101 |
- |
102 |
- if( ifr.ifr_addr.sa_family != AF_INET ) |
103 |
+ for (ifc = ifr; ifc != NULL; ifc = ifc->ifa_next) { |
104 |
+ if (strcmp(ifc->ifa_name, ifname) != 0) |
105 |
continue; |
106 |
- |
107 |
- if( 0 == strncmp(ifname, ifr.ifr_name, sizeof(struct ifreq)) ) { |
108 |
- if( addrlen < sa_len ) { |
109 |
- rc = -1; |
110 |
- break; |
111 |
- } |
112 |
- |
113 |
- (void) memcpy( addr, &(ifr.ifr_addr), sa_len ); |
114 |
- break; |
115 |
- } |
116 |
- else { |
117 |
- /* rec += (sa_len + sizeof( ifr.ifr_name )); */ |
118 |
- /**** the above is per R. Stevens' book and not working |
119 |
- **** on 64-bit Linux */ |
120 |
- |
121 |
- rec += sizeof(ifr); |
122 |
- } |
123 |
- } /* for */ |
124 |
- |
125 |
- if( rec >= (buf + ifc.ifc_len) ) { |
126 |
- rc = -1; |
127 |
+ if (ifc->ifa_addr == NULL) |
128 |
+ continue; |
129 |
+ sin = (struct sockaddr_in *)ifc->ifa_addr; |
130 |
+ if (sin->sin_family != AF_INET) |
131 |
+ continue; |
132 |
+ memcpy(addr, sin, addrlen); |
133 |
+ rc = 0; |
134 |
} |
135 |
|
136 |
- free( buf ); |
137 |
+ freeifaddrs(ifr); |
138 |
return rc; |
139 |
} |
140 |
|
141 |
@@ -147,7 +63,7 @@ |
142 |
(void) strncpy( buf, s, len ); |
143 |
} |
144 |
else { |
145 |
- rc = if2addr( s, (struct sockaddr*)&saddr, sizeof(saddr) ); |
146 |
+ rc = if2addr( s, (struct sockaddr_in *)&saddr, sizeof(saddr) ); |
147 |
if( 0 != rc ) return rc; |
148 |
|
149 |
(void) strncpy( buf, inet_ntoa(saddr.sin_addr), len ); |