1
2
3
4
5 package oshi.software.os.windows;
6
7 import java.nio.charset.StandardCharsets;
8 import java.util.ArrayList;
9 import java.util.List;
10
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 import com.sun.jna.Memory;
15 import com.sun.jna.Native;
16 import com.sun.jna.platform.win32.IPHlpAPI;
17 import com.sun.jna.platform.win32.IPHlpAPI.FIXED_INFO;
18 import com.sun.jna.platform.win32.IPHlpAPI.IP_ADDR_STRING;
19 import com.sun.jna.platform.win32.Kernel32;
20 import com.sun.jna.platform.win32.Kernel32Util;
21 import com.sun.jna.platform.win32.Win32Exception;
22 import com.sun.jna.platform.win32.WinError;
23
24 import oshi.annotation.concurrent.ThreadSafe;
25 import oshi.jna.ByRef.CloseableIntByReference;
26 import oshi.software.common.AbstractNetworkParams;
27 import oshi.util.ExecutingCommand;
28 import oshi.util.ParseUtil;
29
30
31
32
33 @ThreadSafe
34 final class WindowsNetworkParams extends AbstractNetworkParams {
35
36 private static final Logger LOG = LoggerFactory.getLogger(WindowsNetworkParams.class);
37
38 private static final int COMPUTER_NAME_DNS_DOMAIN_FULLY_QUALIFIED = 3;
39
40 @Override
41 public String getDomainName() {
42 char[] buffer = new char[256];
43 try (CloseableIntByReference bufferSize = new CloseableIntByReference(buffer.length)) {
44 if (!Kernel32.INSTANCE.GetComputerNameEx(COMPUTER_NAME_DNS_DOMAIN_FULLY_QUALIFIED, buffer, bufferSize)) {
45 LOG.error("Failed to get dns domain name. Error code: {}", Kernel32.INSTANCE.GetLastError());
46 return "";
47 }
48 }
49 return Native.toString(buffer);
50 }
51
52 @Override
53 public String[] getDnsServers() {
54 try (CloseableIntByReference bufferSize = new CloseableIntByReference()) {
55 int ret = IPHlpAPI.INSTANCE.GetNetworkParams(null, bufferSize);
56 if (ret != WinError.ERROR_BUFFER_OVERFLOW) {
57 LOG.error("Failed to get network parameters buffer size. Error code: {}", ret);
58 return new String[0];
59 }
60
61 try (Memory buffer = new Memory(bufferSize.getValue())) {
62 ret = IPHlpAPI.INSTANCE.GetNetworkParams(buffer, bufferSize);
63 if (ret != 0) {
64 LOG.error("Failed to get network parameters. Error code: {}", ret);
65 return new String[0];
66 }
67 FIXED_INFO fixedInfo = new FIXED_INFO(buffer);
68
69 List<String> list = new ArrayList<>();
70 IP_ADDR_STRING dns = fixedInfo.DnsServerList;
71 while (dns != null) {
72
73
74 String addr = Native.toString(dns.IpAddress.String, StandardCharsets.US_ASCII);
75 int nullPos = addr.indexOf(0);
76 if (nullPos != -1) {
77 addr = addr.substring(0, nullPos);
78 }
79 list.add(addr);
80 dns = dns.Next;
81 }
82 return list.toArray(new String[0]);
83 }
84 }
85 }
86
87 @Override
88 public String getHostName() {
89 try {
90 return Kernel32Util.getComputerName();
91 } catch (Win32Exception e) {
92 return super.getHostName();
93 }
94 }
95
96 @Override
97 public String getIpv4DefaultGateway() {
98 return parseIpv4Route();
99 }
100
101 @Override
102 public String getIpv6DefaultGateway() {
103 return parseIpv6Route();
104 }
105
106 private static String parseIpv4Route() {
107 List<String> lines = ExecutingCommand.runNative("route print -4 0.0.0.0");
108 for (String line : lines) {
109 String[] fields = ParseUtil.whitespaces.split(line.trim());
110 if (fields.length > 2 && "0.0.0.0".equals(fields[0])) {
111 return fields[2];
112 }
113 }
114 return "";
115 }
116
117 private static String parseIpv6Route() {
118 List<String> lines = ExecutingCommand.runNative("route print -6 ::/0");
119 for (String line : lines) {
120 String[] fields = ParseUtil.whitespaces.split(line.trim());
121 if (fields.length > 3 && "::/0".equals(fields[2])) {
122 return fields[3];
123 }
124 }
125 return "";
126 }
127 }