@@ -59,7 +59,7 @@ static unsigned dns6_addr_time;
5959/* for the aging of certain requests like DNS */
6060#define TIMEOUT_DEFAULT 1000 /* milliseconds */
6161
62- #ifdef _WIN32
62+ #if defined( _WIN32 )
6363
6464int get_dns_addr (struct in_addr * pdns_addr )
6565{
@@ -116,7 +116,104 @@ static void winsock_cleanup(void)
116116 WSACleanup ();
117117}
118118
119- #else
119+ #elif defined(__APPLE__ )
120+
121+ #include <resolv.h>
122+
123+ static int get_dns_addr_cached (void * pdns_addr , void * cached_addr ,
124+ socklen_t addrlen , unsigned * cached_time )
125+ {
126+ struct stat old_stat ;
127+ if (curtime - * cached_time < TIMEOUT_DEFAULT ) {
128+ memcpy (pdns_addr , cached_addr , addrlen );
129+ return 0 ;
130+ }
131+ return 1 ;
132+ }
133+
134+ static int get_dns_addr_libresolv (int af , void * pdns_addr , void * cached_addr ,
135+ socklen_t addrlen , uint32_t * scope_id ,
136+ unsigned * cached_time )
137+ {
138+ char buff [512 ];
139+ struct __res_state state ;
140+ union res_sockaddr_union servers [NI_MAXSERV ];
141+ int count ;
142+ int found ;
143+
144+ if (res_ninit (& state ) != 0 ) {
145+ return -1 ;
146+ }
147+
148+ count = res_getservers (& state , servers , NI_MAXSERV );
149+ found = 0 ;
150+ DEBUG_MISC ("IP address of your DNS(s):" );
151+ for (int i = 0 ; i < count ; i ++ ) {
152+ if (af == servers [i ].sin .sin_family ) {
153+ found ++ ;
154+ }
155+
156+ // we use the first found entry
157+ if (found == 1 ) {
158+ memcpy (pdns_addr , & servers [i ].sin .sin_addr , addrlen );
159+ memcpy (cached_addr , & servers [i ].sin .sin_addr , addrlen );
160+ if (scope_id ) {
161+ * scope_id = 0 ;
162+ }
163+ * cached_time = curtime ;
164+ }
165+
166+ if (found > 3 ) {
167+ DEBUG_MISC (" (more)" );
168+ break ;
169+ } else if (slirp_debug & DBG_MISC ) {
170+ char s [INET6_ADDRSTRLEN ];
171+ const char * res = inet_ntop (servers [i ].sin .sin_family ,
172+ & servers [i ].sin .sin_addr ,
173+ s ,
174+ sizeof (s ));
175+ if (!res ) {
176+ res = " (string conversion error)" ;
177+ }
178+ DEBUG_MISC (" %s" , res );
179+ }
180+ }
181+
182+ res_nclose (& state );
183+ if (!found )
184+ return -1 ;
185+ return 0 ;
186+ }
187+
188+ int get_dns_addr (struct in_addr * pdns_addr )
189+ {
190+ if (dns_addr .s_addr != 0 ) {
191+ int ret ;
192+ ret = get_dns_addr_cached (pdns_addr , & dns_addr , sizeof (dns_addr ),
193+ & dns_addr_time );
194+ if (ret <= 0 ) {
195+ return ret ;
196+ }
197+ }
198+ return get_dns_addr_libresolv (AF_INET , pdns_addr , & dns_addr ,
199+ sizeof (dns_addr ), NULL , & dns_addr_time );
200+ }
201+
202+ int get_dns6_addr (struct in6_addr * pdns6_addr , uint32_t * scope_id )
203+ {
204+ if (!in6_zero (& dns6_addr )) {
205+ int ret ;
206+ ret = get_dns_addr_cached (pdns6_addr , & dns6_addr , sizeof (dns6_addr ),
207+ & dns6_addr_time );
208+ if (ret <= 0 ) {
209+ return ret ;
210+ }
211+ }
212+ return get_dns_addr_libresolv (AF_INET6 , pdns6_addr , & dns6_addr ,
213+ sizeof (dns6_addr ), scope_id , & dns6_addr_time );
214+ }
215+
216+ #else // !defined(_WIN32) && !defined(__APPLE__)
120217
121218static int get_dns_addr_cached (void * pdns_addr , void * cached_addr ,
122219 socklen_t addrlen , struct stat * cached_stat ,
0 commit comments