Skip to content

Instantly share code, notes, and snippets.

@archaelus
Created February 26, 2009 20:39
Show Gist options
  • Save archaelus/71094 to your computer and use it in GitHub Desktop.
Save archaelus/71094 to your computer and use it in GitHub Desktop.
-module(dns_test).
-compile(export_all).
-define(IF_KEY, "\\hklm\\system\\CurrentControlSet\\Services\\TcpIp\\Parameters\\Interfaces").
-define(TOP_KEY, "\\hklm\\system\\CurrentControlSet\\Services\\TcpIp\\Parameters").
reg() ->
{ok, R} = win32reg:open([read]),
R.
interfaces(R) ->
ok = win32reg:change_key(R, ?IF_KEY),
{ok, I} = win32reg:sub_keys(R),
I.
config_keys(R, Key) ->
ok = win32reg:change_key(R, Key),
[ {K,
case win32reg:value(R, K) of
{ok, V} -> translate(K, V);
_ -> undefined
end
} || K <- ["Domain", "DhcpDomain",
"NameServer", "DhcpNameServer", "SearchList"]].
translate(NS, V) when NS =:= "NameServer"; NS =:= "DhcpNameServer" ->
[list_to_tuple([list_to_integer(I) || I <- string:tokens(IP, ".")]) || IP <- string:tokens(V, ",")];
translate(_, V) -> V.
interface_configs(R) ->
[{If, config_keys(R, ?IF_KEY ++ "\\" ++ If)}
|| If <- interfaces(R)].
sort_configs(Configs) ->
lists:sort(fun ({_, A}, {_, B}) ->
ANS = proplists:get_value("NameServer", A),
BNS = proplists:get_value("NameServer", B),
if ANS =/= undefined, BNS =:= undefined -> false;
true -> count_undef(A) < count_undef(B)
end
end,
Configs).
count_undef(L) when is_list(L) ->
lists:foldl(fun ({_K, undefined}, Acc) -> Acc +1;
({_K, []}, Acc) -> Acc +1;
(_, Acc) -> Acc
end, 0, L).
all_configs() ->
R = reg(),
TopConfig = config_keys(R, ?TOP_KEY),
Configs = [{top, TopConfig}
| interface_configs(R)],
win32reg:close(R),
{TopConfig, Configs}.
pick_config() ->
{TopConfig, Configs} = all_configs(),
NSConfigs = [{If, C} || {If, C} <- Configs,
get_value(["NameServer","DhcpNameServer"], C) =/= undefined],
case get_value(["NameServer","DhcpNameServer"],
TopConfig) of
%% No top level nameserver to pick interface with
undefined ->
hd(sort_configs(NSConfigs));
%% Top level has a nameserver - use this to select an interface.
NS ->
Cs = [ {If, C}
|| {If, C} <- Configs,
lists:member(NS,
[get_value(["NameServer"], C),
get_value(["DhcpNameServer"], C)])],
hd(sort_configs(Cs))
end.
get_value([], _Config) -> undefined;
get_value([K|Keys], Config) ->
case proplists:get_value(K, Config) of
undefined -> get_value(Keys, Config);
V -> V
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment