2 * reslist.c - get nameservers from windows *
4 * ircd-ratbox related changes are as follows
6 * Copyright (C) 2008 Aaron Sethman <androsyn@ratbox.org>
7 * Copyright (C) 2008-2012 ircd-ratbox development team
9 * pretty much all of this was yanked from c-ares ares_init.c here is the original
10 * header from there --
12 * Id: ares_init.c,v 1.72 2008-05-15 00:00:19 yangtse Exp $
13 * Copyright 1998 by the Massachusetts Institute of Technology.
14 * Copyright (C) 2007-2008 by Daniel Stenberg
16 * Permission to use, copy, modify, and distribute this
17 * software and its documentation for any purpose and without
18 * fee is hereby granted, provided that the above copyright
19 * notice appear in all copies and that both that copyright
20 * notice and this permission notice appear in supporting
21 * documentation, and that the name of M.I.T. not be used in
22 * advertising or publicity pertaining to distribution of the
23 * software without specific, written prior permission.
24 * M.I.T. makes no representations about the suitability of
25 * this software for any purpose. It is provided "as is"
26 * without express or implied warranty.
37 const char *get_windows_nameservers(void);
40 #define IS_NT() ((int)GetVersion() > 0)
41 #define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
42 #define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
43 #define NAMESERVER "NameServer"
44 #define DHCPNAMESERVER "DhcpNameServer"
45 #define DATABASEPATH "DatabasePath"
46 #define WIN_PATH_HOSTS "\\hosts"
49 get_iphlpapi_dns_info(char *ret_buf
, size_t ret_size
)
51 FIXED_INFO
*fi
= alloca(sizeof(*fi
));
52 DWORD size
= sizeof(*fi
);
53 typedef DWORD(WINAPI
* get_net_param_func
) (FIXED_INFO
*, DWORD
*);
54 get_net_param_func xxGetNetworkParams
; /* available only on Win-98/2000+ */
56 IP_ADDR_STRING
*ipAddr
;
59 size_t ip_size
= sizeof("255.255.255.255,") - 1;
60 size_t left
= ret_size
;
67 handle
= LoadLibrary("iphlpapi.dll");
71 xxGetNetworkParams
= (get_net_param_func
) GetProcAddress(handle
, "GetNetworkParams");
72 if(!xxGetNetworkParams
)
75 res
= (*xxGetNetworkParams
) (fi
, &size
);
76 if((res
!= ERROR_BUFFER_OVERFLOW
) && (res
!= ERROR_SUCCESS
))
80 if(!fi
|| (*xxGetNetworkParams
) (fi
, &size
) != ERROR_SUCCESS
)
85 printf("Host Name: %s\n", fi
->HostName
);
86 printf("Domain Name: %s\n", fi
->DomainName
);
87 printf("DNS Servers:\n" " %s (primary)\n", fi
->DnsServerList
.IpAddress
.String
);
89 if(strlen(fi
->DnsServerList
.IpAddress
.String
) > 0 &&
90 inet_addr(fi
->DnsServerList
.IpAddress
.String
) != INADDR_NONE
&& left
> ip_size
)
92 ret
+= sprintf(ret
, "%s,", fi
->DnsServerList
.IpAddress
.String
);
93 left
-= ret
- ret_buf
;
97 for(i
= 0, ipAddr
= fi
->DnsServerList
.Next
; ipAddr
&& left
> ip_size
;
98 ipAddr
= ipAddr
->Next
, i
++)
100 if(inet_addr(ipAddr
->IpAddress
.String
) != INADDR_NONE
)
102 ret
+= sprintf(ret
, "%s,", ipAddr
->IpAddress
.String
);
103 left
-= ret
- ret_buf
;
107 printf(" %s (secondary %d)\n", ipAddr
->IpAddress
.String
, i
+ 1);
114 if(debug
&& left
<= ip_size
)
115 printf("Too many nameservers. Truncating to %d addressess", count
);
122 * Warning: returns a dynamically allocated buffer, the user MUST
123 * use free() / rb_free() if the function returns 1
126 get_res_nt(HKEY hKey
, const char *subkey
, char **obuf
)
128 /* Test for the size we need */
132 result
= RegQueryValueEx(hKey
, subkey
, 0, NULL
, NULL
, &size
);
133 if((result
!= ERROR_SUCCESS
&& result
!= ERROR_MORE_DATA
) || !size
)
135 *obuf
= rb_malloc(size
+ 1);
139 if(RegQueryValueEx(hKey
, subkey
, 0, NULL
, (LPBYTE
) * obuf
, &size
) != ERROR_SUCCESS
)
153 get_res_interfaces_nt(HKEY hKey
, const char *subkey
, char **obuf
)
155 char enumbuf
[39]; /* GUIDs are 38 chars + 1 for NULL */
156 DWORD enum_size
= 39;
160 while(RegEnumKeyEx(hKey
, idx
++, enumbuf
, &enum_size
, 0,
161 NULL
, NULL
, NULL
) != ERROR_NO_MORE_ITEMS
)
166 if(RegOpenKeyEx(hKey
, enumbuf
, 0, KEY_QUERY_VALUE
, &hVal
) != ERROR_SUCCESS
)
168 rc
= get_res_nt(hVal
, subkey
, obuf
);
177 get_windows_nameservers(void)
180 NameServer info via IPHLPAPI (IP helper API):
181 GetNetworkParams() should be the trusted source for this.
182 Available in Win-98/2000 and later. If that fail, fall-back to
183 registry information.
187 On Windows 9X, the DNS server can be found in:
188 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
190 On Windows NT/2000/XP/2003:
191 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
193 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
195 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
198 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
201 static char namelist
[512];
208 memset(&namelist
, 0, sizeof(namelist
));
209 if(get_iphlpapi_dns_info(namelist
, sizeof(namelist
)) > 0)
216 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE
, WIN_NS_NT_KEY
, 0,
217 KEY_READ
, &mykey
) == ERROR_SUCCESS
)
219 RegOpenKeyEx(mykey
, "Interfaces", 0,
220 KEY_QUERY_VALUE
| KEY_ENUMERATE_SUB_KEYS
, &subkey
);
221 if(get_res_nt(mykey
, NAMESERVER
, &line
))
223 rb_strlcpy(namelist
, line
, sizeof(namelist
));
226 else if(get_res_nt(mykey
, DHCPNAMESERVER
, &line
))
228 rb_strlcpy(namelist
, line
, sizeof(namelist
));
231 /* Try the interfaces */
232 else if(get_res_interfaces_nt(subkey
, NAMESERVER
, &line
))
234 rb_strlcpy(namelist
, line
, sizeof(namelist
));
237 else if(get_res_interfaces_nt(subkey
, DHCPNAMESERVER
, &line
))
239 rb_strlcpy(namelist
, line
, sizeof(namelist
));
248 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE
, WIN_NS_9X
, 0,
249 KEY_READ
, &mykey
) == ERROR_SUCCESS
)
251 if((result
= RegQueryValueEx(mykey
, NAMESERVER
, NULL
, &data_type
,
252 NULL
, &bytes
)) == ERROR_SUCCESS
||
253 result
== ERROR_MORE_DATA
)
257 line
= (char *)rb_malloc(bytes
+ 1);
258 if(RegQueryValueEx(mykey
, NAMESERVER
, NULL
, &data_type
,
259 (unsigned char *)line
, &bytes
) ==
262 rb_strlcpy(namelist
, line
, sizeof(namelist
));
270 if(strlen(namelist
) > 0)