1 /**
2  * @file win32/srv.c  Get DNS Server IP code for Windows
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 #include <winsock2.h>
7 #include <iphlpapi.h>
8 #include <io.h>
9 #include <re_types.h>
10 #include <re_fmt.h>
11 #include <re_mbuf.h>
12 #include <re_list.h>
13 #include <re_sa.h>
14 #include <re_dns.h>
15 #include "../dns.h"
16 
17 
18 #define DEBUG_MODULE "win32/srv"
19 #define DEBUG_LEVEL 5
20 #include <re_dbg.h>
21 
22 
get_windns(char * domain,size_t dsize,struct sa * srvv,uint32_t * n)23 int get_windns(char *domain, size_t dsize, struct sa *srvv, uint32_t *n)
24 {
25 	FIXED_INFO *     FixedInfo = NULL;
26 	ULONG            ulOutBufLen;
27 	DWORD            dwRetVal;
28 	IP_ADDR_STRING * pIPAddr;
29 	HANDLE           hLib;
30 	union {
31 		FARPROC proc;
32 		DWORD (WINAPI *_GetNetworkParams)(FIXED_INFO*, DWORD*);
33 	} u;
34 	uint32_t i;
35 	int err;
36 
37 	if (!srvv || !n || !*n)
38 		return EINVAL;
39 
40 	hLib = LoadLibrary(TEXT("iphlpapi.dll"));
41 	if (!hLib)
42 		return ENOSYS;
43 
44 	u.proc = GetProcAddress(hLib, TEXT("GetNetworkParams"));
45 	if (!u.proc) {
46 		err = ENOSYS;
47 		goto out;
48 	}
49 
50 	FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof( FIXED_INFO ));
51 	ulOutBufLen = sizeof( FIXED_INFO );
52 
53 	if (ERROR_BUFFER_OVERFLOW == (*u._GetNetworkParams)(FixedInfo,
54 							    &ulOutBufLen)) {
55 		GlobalFree( FixedInfo );
56 		FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, ulOutBufLen);
57 	}
58 
59 	if ((dwRetVal = (*u._GetNetworkParams)( FixedInfo, &ulOutBufLen ))) {
60 		DEBUG_WARNING("couldn't get network params (%d)\n", dwRetVal);
61 		err = ENOENT;
62 		goto out;
63 	}
64 
65 	str_ncpy(domain, FixedInfo->DomainName, dsize);
66 
67 #if 0
68 	printf( "Host Name: %s\n", FixedInfo->HostName);
69 	printf( "Domain Name: %s\n", FixedInfo->DomainName);
70 	printf( "DNS Servers:\n" );
71 	printf( "\t%s\n", FixedInfo->DnsServerList.IpAddress.String );
72 #endif
73 
74 	i = 0;
75 	pIPAddr = &FixedInfo->DnsServerList;
76 	while (pIPAddr && strlen(pIPAddr->IpAddress.String) > 0) {
77 		err = sa_set_str(&srvv[i], pIPAddr->IpAddress.String,
78 				 DNS_PORT);
79 		if (err) {
80 			DEBUG_WARNING("sa_set_str: %s (%m)\n",
81 				      pIPAddr->IpAddress.String, err);
82 		}
83 		DEBUG_INFO("dns ip %u: %j\n", i, &srvv[i]);
84 		++i;
85 		pIPAddr = pIPAddr ->Next;
86 
87 		if (i >= *n)
88 			break;
89 	}
90 
91 	*n = i;
92 	DEBUG_INFO("got %u nameservers\n", i);
93 	err = i>0 ? 0 : ENOENT;
94 
95  out:
96 	if (FixedInfo)
97 		GlobalFree(FixedInfo);
98 	FreeLibrary(hLib);
99 	return err;
100 }
101