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

Implemented Option to choose default network interface #3930

Merged
merged 8 commits into from Aug 11, 2017
@@ -4,7 +4,7 @@ Bundle-Name: Eclipse SmartHome Config Core
Bundle-SymbolicName: org.eclipse.smarthome.config.core
Bundle-Version: 0.9.0.qualifier
Bundle-Vendor: Eclipse.org/SmartHome
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: com.google.common.base,
com.google.common.collect,
com.google.gson,
@@ -21,6 +21,7 @@ Import-Package: com.google.common.base,
org.eclipse.smarthome.core.common.registry,
org.eclipse.smarthome.core.events,
org.eclipse.smarthome.core.i18n,
org.eclipse.smarthome.core.net,
org.osgi.framework,
org.osgi.service.component,
org.osgi.service.component.annotations;resolution:=optional,
@@ -1 +1,2 @@
/org.eclipse.smarthome.config.core.internal.i18n.I18nConfigOptionsProvider.xml
/org.eclipse.smarthome.config.core.net.internal.NetworkConfigOptionProvider.xml
@@ -0,0 +1,103 @@
/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.config.core.net.internal;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import org.eclipse.smarthome.config.core.ConfigOptionProvider;
import org.eclipse.smarthome.config.core.ParameterOption;
import org.eclipse.smarthome.core.net.NetUtil;
import org.osgi.service.component.annotations.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Provides a list of IPv4 addresses of the local machine and shows the user which interface belongs to which IP address
*
* @author Stefan Triller - initial contribution
*
*/
@Component
public class NetworkConfigOptionProvider implements ConfigOptionProvider {

static final URI CONFIG_URI = URI.create("system:network");
static final String PARAM_PRIMARY_ADDRESS = "primaryAddress";

private final Logger logger = LoggerFactory.getLogger(NetworkConfigOptionProvider.class);

@Override
public Collection<ParameterOption> getParameterOptions(URI uri, String param, Locale locale) {
if (!uri.equals(CONFIG_URI)) {
return null;
}

if (param.equals(PARAM_PRIMARY_ADDRESS)) {
return getIPv4Addresses();
}
return null;
}

private List<ParameterOption> getIPv4Addresses() {
List<ParameterOption> interfaceOptions = new ArrayList<>();

Set<String> subnets = new HashSet<>();

try {
final Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
final NetworkInterface current = interfaces.nextElement();
if (!current.isUp() || current.isLoopback() || current.isVirtual()) {
continue;
}

for (InterfaceAddress ifAddr : current.getInterfaceAddresses()) {
InetAddress addr = ifAddr.getAddress();

if (addr.isLoopbackAddress() || (addr instanceof Inet6Address)) {
continue;
}

String ipv4Address = addr.getHostAddress();
try {
// InetAddress.getHostAddress() is missing a @NonNull annotation

This comment has been minimized.

Copy link
@kaikreuzer

kaikreuzer Aug 11, 2017

Member

You can make it clear by code, which conversion you are suppressing - no need for this comment. Just do above the following:

        @SuppressWarnings("null")
        @NonNull
        String ipv4Address = addr.getHostAddress();

I think that is the better style we should follow.

@SuppressWarnings("null")
String subNetString = NetUtil.getIpv4NetAddress(ipv4Address, ifAddr.getNetworkPrefixLength())
+ "/" + String.valueOf(ifAddr.getNetworkPrefixLength());
subnets.add(subNetString);
} catch (IllegalArgumentException ex) {
logger.error("Could not calculate network address: {} Ignoring IP {}", ex.getMessage(),
ipv4Address, ex);
}
}
}
} catch (SocketException ex) {
logger.error("Could not retrieve network interface: {}", ex.getMessage(), ex);
return null;
}

for (String subnet : subnets) {
ParameterOption po = new ParameterOption(subnet, subnet);
interfaceOptions.add(po);
}

return interfaceOptions;
}

}
@@ -0,0 +1,68 @@
/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.core.net;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.Test;

/**
* Tests for NetUtil class
*
* @author Stefan Triller - initial contribution
*
*/
public class NetUtilTest {

@Test
public void testNetwork() {
String network = NetUtil.getIpv4NetAddress("192.168.0.1", (short) 24);
assertThat(network, is("192.168.0.0"));

network = NetUtil.getIpv4NetAddress("192.168.23.5", (short) 24);
assertThat(network, is("192.168.23.0"));

network = NetUtil.getIpv4NetAddress("172.16.42.23", (short) 16);
assertThat(network, is("172.16.0.0"));

network = NetUtil.getIpv4NetAddress("10.8.13.5", (short) 8);
assertThat(network, is("10.0.0.0"));

network = NetUtil.getIpv4NetAddress("192.168.5.8", (short) 23);
assertThat(network, is("192.168.4.0"));

network = NetUtil.getIpv4NetAddress("192.168.5.8", (short) 27);
assertThat(network, is("192.168.5.0"));

network = NetUtil.getIpv4NetAddress("192.168.5.8", (short) 29);
assertThat(network, is("192.168.5.8"));

try {
network = NetUtil.getIpv4NetAddress("192.168.5.8", (short) 32);
;

This comment has been minimized.

Copy link
@kaikreuzer

kaikreuzer Aug 11, 2017

Member

Is this line required?

} catch (IllegalArgumentException iae) {
assertThat(iae.getMessage(),
is("IP '192.168.5.8' not a valid IPv4 address or netmask '32' out of bounds (1-31)"));

This comment has been minimized.

Copy link
@kaikreuzer

kaikreuzer Aug 11, 2017

Member

I would actually except a clear message about the error and not "this or that is wrong".

"Netmask '32' is out of bounds (1-31)"

Would be the expected result, do you agree?

}
try {
network = NetUtil.getIpv4NetAddress("192.168.58", (short) 24);
} catch (IllegalArgumentException iae) {
assertThat(iae.getMessage(),
is("IP '192.168.58' not a valid IPv4 address or netmask '24' out of bounds (1-31)"));

This comment has been minimized.

Copy link
@kaikreuzer

kaikreuzer Aug 11, 2017

Member

"IP '192.168.58' is not a valid IPv4 address."

}

try {
network = NetUtil.getIpv4NetAddress("SOME_TEXT", (short) 24);
} catch (IllegalArgumentException iae) {
assertThat(iae.getMessage(),
is("IP 'SOME_TEXT' not a valid IPv4 address or netmask '24' out of bounds (1-31)"));

This comment has been minimized.

Copy link
@kaikreuzer

kaikreuzer Aug 11, 2017

Member

"IP 'SOME_TEXT' is not a valid IPv4 address"

}
}

}
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<config-description:config-descriptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:config-description="http://eclipse.org/smarthome/schemas/config-description/v1.0.0"
xsi:schemaLocation="http://eclipse.org/smarthome/schemas/config-description/v1.0.0
http://eclipse.org/smarthome/schemas/config-description-1.0.0.xsd">

<config-description uri="system:network">
<parameter name="primaryAddress" type="text">
<label>Primary Address</label>
<description>A subnet (e.g. 192.168.1.0/24) <!-- or an IP address (e.g. 192.168.1.5) --></description>
<limitToOptions>true</limitToOptions>
</parameter>
</config-description>

</config-description:config-descriptions>
@@ -28,7 +28,7 @@ Ignore-Package: org.eclipse.smarthome.core.internal.items,org.eclipse.smarthome.
nal,org.eclipse.smarthome.core.internal.events,org.eclipse.smarthome.core.internal.loggin
g
Bundle-Name: Eclipse SmartHome Core
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: Eclipse.org/SmartHome
Bundle-Version: 0.9.0.qualifier
Bundle-ManifestVersion: 2
@@ -0,0 +1 @@
/org.eclipse.smarthome.network.xml
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.