2 * Copyright (c) 2010-2021 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.magentatv.internal.network;
15 import java.io.IOException;
16 import java.net.DatagramPacket;
17 import java.net.DatagramSocket;
18 import java.net.InetAddress;
19 import java.net.NetworkInterface;
20 import java.net.SocketException;
21 import java.net.UnknownHostException;
23 import org.apache.commons.net.util.SubnetUtils;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.magentatv.internal.MagentaTVException;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * The {@link MagentaTVNetwork} supplies network functions.
33 * @author Markus Michels - Initial contribution
36 public class MagentaTVNetwork {
37 private final Logger logger = LoggerFactory.getLogger(MagentaTVNetwork.class);
39 private String localIP = "";
40 private String localPort = "";
41 private String localMAC = "";
42 private @Nullable NetworkInterface localInterface;
45 * Init local network interface, determine local IP and MAC address
47 * @param networkAddressService
50 public void initLocalNet(String localIP, String localPort) throws MagentaTVException {
52 if (localIP.isEmpty() || localIP.equals("0.0.0.0") || localIP.equals("127.0.0.1")) {
53 throw new MagentaTVException("Unable to detect local IP address!");
55 this.localPort = localPort;
56 this.localIP = localIP;
59 InetAddress ip = InetAddress.getByName(localIP);
60 localInterface = NetworkInterface.getByInetAddress(ip);
61 if (localInterface != null) {
62 byte[] mac = localInterface.getHardwareAddress();
63 StringBuilder sb = new StringBuilder();
64 for (int i = 0; i < mac.length; i++) {
65 sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
67 localMAC = sb.toString().toUpperCase();
68 logger.debug("Local IP address={}, Local MAC address = {}", localIP, localMAC);
71 } catch (UnknownHostException | SocketException e) {
72 throw new MagentaTVException(e);
75 throw new MagentaTVException(
76 "Unable to get local IP / MAC address, check network settings in openHAB system configuration!");
80 * Checks if client ip equals or is in range of ip networks provided by
81 * semicolon separated list
83 * @param clientIp in numeric form like "192.168.0.10"
84 * @param ipList like "127.0.0.1;192.168.0.0/24;10.0.0.0/8"
85 * @return true if client ip from the list os ips and networks
87 public static boolean isIpInSubnet(String clientIp, String ipList) {
88 if (ipList.isEmpty()) {
89 // No ip address provided
92 String[] subnetMasks = ipList.split(";");
93 for (String subnetMask : subnetMasks) {
94 subnetMask = subnetMask.trim();
95 if (clientIp.equals(subnetMask)) {
98 if (subnetMask.contains("/")) {
99 if (new SubnetUtils(subnetMask).getInfo().isInRange(clientIp)) {
108 public NetworkInterface getLocalInterface() {
109 return localInterface;
112 public String getLocalIP() {
116 public String getLocalPort() {
120 public String getLocalMAC() {
124 public static final int WOL_PORT = 9;
127 * Send a Wake-on-LAN packet
129 * @param ipAddr destination ip
130 * @param macAddress destination MAC address
131 * @throws MagentaTVException
133 public void sendWakeOnLAN(String ipAddr, String macAddress) throws MagentaTVException {
135 byte[] macBytes = getMacBytes(macAddress);
136 byte[] bytes = new byte[6 + 16 * macBytes.length];
137 for (int i = 0; i < 6; i++) {
138 bytes[i] = (byte) 0xff;
140 for (int i = 6; i < bytes.length; i += macBytes.length) {
141 System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
144 InetAddress address = InetAddress.getByName(ipAddr);
145 DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, WOL_PORT);
146 try (DatagramSocket socket = new DatagramSocket()) {
150 logger.debug("Wake-on-LAN packet sent to {} / {}", ipAddr, macAddress);
151 } catch (IOException e) {
152 throw new MagentaTVException(e, "Unable to send Wake-on-LAN packet to {} / {}", ipAddr, macAddress);
157 * Convert MAC address from string to byte array
159 * @param macStr MAC address as string
160 * @return MAC address as byte array
161 * @throws IllegalArgumentException
163 private static byte[] getMacBytes(String macStr) throws IllegalArgumentException {
164 byte[] bytes = new byte[6];
165 String[] hex = macStr.split("(\\:|\\-)");
166 if (hex.length != 6) {
167 throw new IllegalArgumentException("Invalid MAC address.");
170 for (int i = 0; i < 6; i++) {
171 bytes[i] = (byte) Integer.parseInt(hex[i], 16);
173 } catch (NumberFormatException e) {
174 throw new IllegalArgumentException("Invalid hex digit in MAC address.", e);