]> git.basschouten.com Git - openhab-addons.git/blob
0a2ab367fb886d3983066396382f5e3c6d59cc9c
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.magentatv.internal.network;
14
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;
22
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;
29
30 /**
31  * The {@link MagentaTVNetwork} supplies network functions.
32  *
33  * @author Markus Michels - Initial contribution
34  */
35 @NonNullByDefault
36 public class MagentaTVNetwork {
37     private final Logger logger = LoggerFactory.getLogger(MagentaTVNetwork.class);
38
39     private String localIP = "";
40     private String localPort = "";
41     private String localMAC = "";
42     private @Nullable NetworkInterface localInterface;
43
44     /**
45      * Init local network interface, determine local IP and MAC address
46      *
47      * @param networkAddressService
48      * @return
49      */
50     public void initLocalNet(String localIP, String localPort) throws MagentaTVException {
51         try {
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!");
54             }
55             this.localPort = localPort;
56             this.localIP = localIP;
57
58             // get MAC address
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) ? ":" : ""));
66                 }
67                 localMAC = sb.toString().toUpperCase();
68                 logger.debug("Local IP address={}, Local MAC address = {}", localIP, localMAC);
69                 return;
70             }
71         } catch (UnknownHostException | SocketException e) {
72             throw new MagentaTVException(e);
73         }
74
75         throw new MagentaTVException(
76                 "Unable to get local IP / MAC address, check network settings in openHAB system configuration!");
77     }
78
79     /**
80      * Checks if client ip equals or is in range of ip networks provided by
81      * semicolon separated list
82      *
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
86      */
87     public static boolean isIpInSubnet(String clientIp, String ipList) {
88         if (ipList.isEmpty()) {
89             // No ip address provided
90             return true;
91         }
92         String[] subnetMasks = ipList.split(";");
93         for (String subnetMask : subnetMasks) {
94             subnetMask = subnetMask.trim();
95             if (clientIp.equals(subnetMask)) {
96                 return true;
97             }
98             if (subnetMask.contains("/")) {
99                 if (new SubnetUtils(subnetMask).getInfo().isInRange(clientIp)) {
100                     return true;
101                 }
102             }
103         }
104         return false;
105     }
106
107     @Nullable
108     public NetworkInterface getLocalInterface() {
109         return localInterface;
110     }
111
112     public String getLocalIP() {
113         return localIP;
114     }
115
116     public String getLocalPort() {
117         return localPort;
118     }
119
120     public String getLocalMAC() {
121         return localMAC;
122     }
123
124     public static final int WOL_PORT = 9;
125
126     /**
127      * Send a Wake-on-LAN packet
128      *
129      * @param ipAddr destination ip
130      * @param macAddress destination MAC address
131      * @throws MagentaTVException
132      */
133     public void sendWakeOnLAN(String ipAddr, String macAddress) throws MagentaTVException {
134         try {
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;
139             }
140             for (int i = 6; i < bytes.length; i += macBytes.length) {
141                 System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
142             }
143
144             InetAddress address = InetAddress.getByName(ipAddr);
145             DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, WOL_PORT);
146             try (DatagramSocket socket = new DatagramSocket()) {
147                 socket.send(packet);
148             }
149
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);
153         }
154     }
155
156     /**
157      * Convert MAC address from string to byte array
158      *
159      * @param macStr MAC address as string
160      * @return MAC address as byte array
161      * @throws IllegalArgumentException
162      */
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.");
168         }
169         try {
170             for (int i = 0; i < 6; i++) {
171                 bytes[i] = (byte) Integer.parseInt(hex[i], 16);
172             }
173         } catch (NumberFormatException e) {
174             throw new IllegalArgumentException("Invalid hex digit in MAC address.", e);
175         }
176         return bytes;
177     }
178 }