Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Host/domain name, dns servers and default gateways information for Win/Linux #294

Merged
merged 15 commits into from
Jan 26, 2017
Merged
Prev Previous commit
Next Next commit
style fixing
  • Loading branch information
chikei committed Jan 4, 2017
commit 092e65b52122e4a5c0578156094cfde334f21e93
30 changes: 16 additions & 14 deletions oshi-core/src/main/java/oshi/jna/platform/windows/IPHlpAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,21 +151,22 @@ class IP_ADDRESS_STRING extends Structure {

@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"String"});
return Arrays.asList(new String[] { "String" });
}
}

class IP_ADDR_STRING extends Structure {
public static class ByReference extends IP_ADDR_STRING implements Structure.ByReference{}

public ByReference Next;
public IP_ADDRESS_STRING IpAddress;
public IP_ADDRESS_STRING IpMask;
public int Context;

public static class ByReference extends IP_ADDR_STRING implements Structure.ByReference {
}

@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"Next", "IpAddress", "IpMask", "Context"});
return Arrays.asList(new String[] { "Next", "IpAddress", "IpMask", "Context" });
}
}

Expand All @@ -182,8 +183,8 @@ class FIXED_INFO extends Structure {

@Override
protected List<String> getFieldOrder() {
return Arrays.asList(new String[]{"HostName", "DomainName", "CurrentDnsServer", "DnsServerList",
"NodeType", "ScopeId", "EnableRouting", "EnableProxy", "EnableDns"});
return Arrays.asList(new String[] { "HostName", "DomainName", "CurrentDnsServer", "DnsServerList",
"NodeType", "ScopeId", "EnableRouting", "EnableProxy", "EnableDns" });
}

public FIXED_INFO(Pointer p) {
Expand Down Expand Up @@ -239,15 +240,16 @@ public FIXED_INFO(Pointer p) {
* computer.
*
* @param pFixedInfo
* A pointer to a buffer that contains a FIXED_INFO structure that
* receives the network parameters for the local computer, if the
* function was successful. This buffer must be allocated by the caller
* prior to calling the GetNetworkParams function.
* A pointer to a buffer that contains a FIXED_INFO structure
* that receives the network parameters for the local computer,
* if the function was successful. This buffer must be allocated
* by the caller prior to calling the GetNetworkParams function.
* @param pOutBufLen
* A pointer to a ULONG variable that specifies the size of the FIXED_INFO
* structure. If this size is insufficient to hold the information,
* GetNetworkParams fills in this variable with the required size, and
* returns an error code of ERROR_BUFFER_OVERFLOW.
* A pointer to a ULONG variable that specifies the size of the
* FIXED_INFO structure. If this size is insufficient to hold the
* information, GetNetworkParams fills in this variable with the
* required size, and returns an error code of
* ERROR_BUFFER_OVERFLOW.
* @return If the function succeeds, the return value is ERROR_SUCCESS.
*/
int GetNetworkParams(FIXED_INFO pFixedInfo, ULONGByReference pOutBufLen);
Expand Down
11 changes: 6 additions & 5 deletions oshi-core/src/main/java/oshi/software/os/NetworkParams.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import java.io.Serializable;

/**
* NetworkParams presents network parameters of running OS, such as DNS, host name etc.
* NetworkParams presents network parameters of running OS, such as DNS, host
* name etc.
*/
public interface NetworkParams extends Serializable {

Expand All @@ -41,14 +42,14 @@ public interface NetworkParams extends Serializable {
String[] getDnsServers();

/**
* @return Gets default gateway(routing destination for 0.0.0.0/0) for IPv4, empty string if not
* defined.
* @return Gets default gateway(routing destination for 0.0.0.0/0) for IPv4,
* empty string if not defined.
*/
String getIpv4DefaultGateway();

/**
* @return Gets default gateway(routing destination for ::/0) for IPv6, empty string if not
* defined.
* @return Gets default gateway(routing destination for ::/0) for IPv6,
* empty string if not defined.
*/
String getIpv6DefaultGateway();
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,20 @@
*/
package oshi.software.os.linux;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

import oshi.software.os.NetworkParams;
import oshi.util.ExecutingCommand;
import oshi.util.FileUtil;
import oshi.util.ParseUtil;

public class LinuxNetworkParams implements NetworkParams{
public class LinuxNetworkParams implements NetworkParams {

private static final long serialVersionUID = 1L;

private static final Logger LOG = LoggerFactory.getLogger(LinuxNetworkParams.class);
private static final String IPV4_DEFAULT_DEST = "0.0.0.0";
private static final String IPV6_DEFAULT_DEST = "::/0";

/**
* {@inheritDoc}
Expand All @@ -41,7 +40,7 @@ public class LinuxNetworkParams implements NetworkParams{
public String getHostName() {
String hn = FileUtil.getStringFromFile("/proc/sys/kernel/hostname");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer native calls to reading files or parsing command lines. In this case, there is a gethostname() function in libc.

int dot = hn.indexOf('.');
if(dot == -1) {
if (dot == -1) {
return hn;
} else {
return hn.substring(0, dot);
Expand All @@ -65,18 +64,17 @@ public String[] getDnsServers() {
String key = "nameserver";
int maxNameServer = 3;
List<String> servers = new ArrayList<>();
for(String line: resolv){
if(!line.startsWith(key)) continue;

String value = line.substring(key.length())
.replaceFirst("^[ \t]+", "");
if(value.length() == 0 ||
value.charAt(0) == '#' || value.charAt(0) == ';') continue;
String val = value.split("[ \t#;]", 2)[0];
servers.add(val);
if(servers.size() >= maxNameServer) break;
for (int i = 0; i < resolv.size() && servers.size() < maxNameServer; i++) {
String line = resolv.get(i);
if (line.startsWith(key)) {
String value = line.substring(key.length()).replaceFirst("^[ \t]+", "");
if (value.length() != 0 && value.charAt(0) != '#' && value.charAt(0) != ';') {
String val = value.split("[ \t#;]", 2)[0];
servers.add(val);
}
}
}
return servers.toArray(new String[0]);
return servers.toArray(new String[servers.size()]);
}

/**
Expand All @@ -85,24 +83,22 @@ public String[] getDnsServers() {
@Override
public String getIpv4DefaultGateway() {
List<String> routes = ExecutingCommand.runNative("route -A inet -n");
if(routes.size() <= 2){
if (routes.size() <= 2) {
return "";
}

String gateway = "";
int minMetric = Integer.MAX_VALUE;

for(int i = 2; i < routes.size(); i++){
for (int i = 2; i < routes.size(); i++) {
String[] fields = routes.get(i).split("\\s+");
if(fields.length > 4 && fields[0].equals("0.0.0.0")) {
try{
boolean isGateway = fields[3].indexOf('G') != -1;
int metric = Integer.parseInt(fields[4]);
if(isGateway && (metric < minMetric)){
minMetric = metric;
gateway = fields[1];
}
} catch (NumberFormatException ignored){}
if (fields.length > 4 && fields[0].equals(IPV4_DEFAULT_DEST)) {
boolean isGateway = fields[3].indexOf('G') != -1;
int metric = ParseUtil.parseIntOrDefault(fields[4], Integer.MAX_VALUE);
if (isGateway && (metric < minMetric)) {
minMetric = metric;
gateway = fields[1];
}
}
}
return gateway;
Expand All @@ -114,24 +110,22 @@ public String getIpv4DefaultGateway() {
@Override
public String getIpv6DefaultGateway() {
List<String> routes = ExecutingCommand.runNative("route -A inet6 -n");
if(routes.size() <= 2){
if (routes.size() <= 2) {
return "";
}

String gateway = "";
int minMetric = Integer.MAX_VALUE;

for(int i = 2; i < routes.size(); i++){
for (int i = 2; i < routes.size(); i++) {
String[] fields = routes.get(i).split("\\s+");
if(fields.length > 3 && fields[0].equals("::/0")) {
try{
boolean isGateway = fields[2].indexOf('G') != -1;
int metric = Integer.parseInt(fields[3]);
if(isGateway && (metric < minMetric)){
minMetric = metric;
gateway = fields[1];
}
} catch (NumberFormatException ignored){}
if (fields.length > 3 && fields[0].equals(IPV6_DEFAULT_DEST)) {
boolean isGateway = fields[2].indexOf('G') != -1;
int metric = ParseUtil.parseIntOrDefault(fields[3], Integer.MAX_VALUE);
if (isGateway && (metric < minMetric)) {
minMetric = metric;
gateway = fields[1];
}
}
}
return gateway;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ public class WindowsNetworkParams implements NetworkParams {

private static final Logger LOG = LoggerFactory.getLogger(WindowsNetworkParams.class);

private static final WmiUtil.ValueType[] GATEWAY_TYPES = {WmiUtil.ValueType.STRING, WmiUtil.ValueType.UINT16};
private static final WmiUtil.ValueType[] GATEWAY_TYPES = { WmiUtil.ValueType.STRING, WmiUtil.ValueType.UINT16 };
private static final String IPV4_DEFAULT_DEST = "0.0.0.0/0";
private static final String IPV6_DEFAULT_DEST = "::/0";

/**
* {@inheritDoc}
Expand Down Expand Up @@ -76,8 +78,10 @@ public String getDomainName() {
*/
@Override
public String[] getDnsServers() {
// this may be done by iterating WMI instances ROOT\CIMV2\Win32_NetworkAdapterConfiguration
// then sort by IPConnectionMetric, but current JNA release does not have string array support
// this may be done by iterating WMI instances
// ROOT\CIMV2\Win32_NetworkAdapterConfiguration
// then sort by IPConnectionMetric, but current JNA release does not
// have string array support
// for Variant (it's merged but not release yet).
WinDef.ULONGByReference bufferSize = new WinDef.ULONGByReference();
int ret = IPHlpAPI.INSTANCE.GetNetworkParams(null, bufferSize);
Expand All @@ -95,31 +99,31 @@ public String[] getDnsServers() {

List<String> list = new ArrayList<>();
IPHlpAPI.IP_ADDR_STRING dns = buffer.DnsServerList;
while(dns != null) {
while (dns != null) {
String addr = new String(dns.IpAddress.String);
int nullPos = addr.indexOf(0);
if(nullPos != -1) {
if (nullPos != -1) {
addr = addr.substring(0, nullPos);
}
list.add(addr);
dns = dns.Next;
}

return list.toArray(new String[0]);
return list.toArray(new String[list.size()]);
}

/**
* {@inheritDoc}
*/
@Override
public String getIpv4DefaultGateway() {
String dest = "0.0.0.0/0";
String dest = IPV4_DEFAULT_DEST;
return getNextHop(dest);
}

private String getNextHop(String dest) {
Map<String, List<Object>> vals = WmiUtil.selectObjectsFrom("ROOT\\StandardCimv2", "MSFT_NetRoute",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ROOT\\StandardCimv2 requires Windows 8+. This call produces errors on Windows 7.

We need to provide a fallback method for finding the default gateway on Win7. My suggestion would be to parse the output of netstat -nr and return the gateway for 0.0.0.0 (IPv4) and ::/0 (IPv6).

"NextHop,RouteMetric", "WHERE DestinationPrefix=\"" + dest + "\"", GATEWAY_TYPES);
"NextHop,RouteMetric", "WHERE DestinationPrefix=\"" + dest + "\"", GATEWAY_TYPES);
List<Object> metrics = vals.get("RouteMetric");
if (vals.get("RouteMetric").size() == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style/readability: use !isEmpty() and go straight to what's currently under else. Then just put the return ""; after the if.

return "";
Expand All @@ -142,7 +146,7 @@ private String getNextHop(String dest) {
*/
@Override
public String getIpv6DefaultGateway() {
String dest = "::/0";
String dest = IPV6_DEFAULT_DEST;
return getNextHop(dest);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@

import oshi.SystemInfo;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
* Test network parameters
Expand Down
11 changes: 6 additions & 5 deletions oshi-json/src/main/java/oshi/json/software/os/NetworkParams.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import oshi.json.json.OshiJsonObject;

/**
* NetworkParams presents network parameters of running OS, such as DNS, host name etc.
* NetworkParams presents network parameters of running OS, such as DNS, host
* name etc.
*/
public interface NetworkParams extends OshiJsonObject {

Expand All @@ -41,14 +42,14 @@ public interface NetworkParams extends OshiJsonObject {
String[] getDnsServers();

/**
* @return Gets default gateway(routing destination for 0.0.0.0/0) for IPv4, empty string if not
* defined.
* @return Gets default gateway(routing destination for 0.0.0.0/0) for IPv4,
* empty string if not defined.
*/
String getIpv4DefaultGateway();

/**
* @return Gets default gateway(routing destination for ::/0) for IPv6, empty string if not
* defined.
* @return Gets default gateway(routing destination for ::/0) for IPv6,
* empty string if not defined.
*/
String getIpv6DefaultGateway();
}