8
8
#include <stdlib.h>
9
9
#include "sockets_global.h"
10
10
#include <arpa/inet.h>
11
+ #include <net/if.h>
12
+ #include <ifaddrs.h>
11
13
12
14
/*
13
15
* Converts the current herrno error value into an EAI_* error code.
@@ -90,6 +92,31 @@ static struct addrinfo *makeipv4info(int type, int proto, uint32_t ip, uint16_t
90
92
}
91
93
92
94
95
+ /*
96
+ * AI_ADDRCONFIG check: Build a mask containing a bit set for each address
97
+ * family configured in the system.
98
+ *
99
+ */
100
+ static int addrconfig (uint32_t * mask )
101
+ {
102
+ struct ifaddrs * ifaddrs , * ifa ;
103
+
104
+ if (getifaddrs (& ifaddrs ) < 0 )
105
+ return -1 ;
106
+
107
+ * mask = 0 ;
108
+ for (ifa = ifaddrs ; ifa != NULL ; ifa = ifa -> ifa_next )
109
+ if (ifa -> ifa_addr && (ifa -> ifa_flags & IFF_UP ))
110
+ {
111
+ if (ifa -> ifa_addr -> sa_family < ((unsigned short )(sizeof (* mask ) * 8 )))
112
+ * mask |= (uint32_t )1 << ifa -> ifa_addr -> sa_family ;
113
+ }
114
+
115
+ freeifaddrs (ifaddrs );
116
+ return 0 ;
117
+ }
118
+
119
+
93
120
/*
94
121
* getaddrinfo() non-thread-safe IPv4-only implementation
95
122
* Address-family-independent hostname to address resolution.
@@ -107,19 +134,23 @@ int __getaddrinfo(const char *node, const char *service, const struct addrinfo *
107
134
int protocol = 0 ;
108
135
int flags = 0 ;
109
136
const char * name = NULL ;
137
+ uint32_t mask = (uint32_t )~0UL ;
110
138
111
139
* res = NULL ;
112
140
113
141
if (hints != NULL )
114
142
{
115
143
flags = hints -> ai_flags ;
116
144
117
- if (flags & ~(AI_PASSIVE |AI_CANONNAME |AI_NUMERICHOST ))
145
+ if (flags & ~(AI_PASSIVE |AI_CANONNAME |AI_NUMERICHOST | AI_ADDRCONFIG ))
118
146
return EAI_BADFLAGS ;
119
147
/* only accept AF_INET and AF_UNSPEC */
120
148
if (hints -> ai_family && (hints -> ai_family != AF_INET ))
121
149
return EAI_FAMILY ;
122
150
151
+ if ((hints -> ai_flags & AI_ADDRCONFIG ) != 0 && addrconfig (& mask ) < 0 )
152
+ return EAI_FAIL ;
153
+
123
154
/* protocol sanity check */
124
155
switch (hints -> ai_socktype )
125
156
{
@@ -184,15 +215,16 @@ int __getaddrinfo(const char *node, const char *service, const struct addrinfo *
184
215
struct servent * sp ;
185
216
186
217
d = strtoul (service , & end , 0 );
187
- if (!end [0 ]) {
188
- if (d > 65535 )
189
- return (EAI_SERVICE );
218
+ if (!end [0 ])
219
+ {
220
+ if (d > 65535UL )
221
+ return EAI_SERVICE ;
190
222
port = htons ((unsigned short ) d );
191
223
} else
192
224
{
193
225
sp = getservbyname (service , NULL );
194
226
if (sp == NULL )
195
- return ( EAI_SERVICE ) ;
227
+ return EAI_SERVICE ;
196
228
port = sp -> s_port ;
197
229
}
198
230
}
0 commit comments