blob: aa8e01046a018a68ef7b14f9718a58f23ed466fe [file] [log] [blame]
Hugo Benichi59c8e422017-10-12 21:33:40 +09001/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.net;
18
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090019import android.annotation.IntDef;
Hugo Benichi48872c62018-01-12 09:46:29 +090020import android.annotation.NonNull;
Etan Cohena4824cf2018-11-02 15:07:20 -070021import android.annotation.Nullable;
Mathew Inwood53f089f2018-08-08 14:44:44 +010022import android.annotation.UnsupportedAppUsage;
Hugo Benichiac52e402017-11-09 00:22:25 +090023import android.os.Parcel;
24import android.os.Parcelable;
25
26import com.android.internal.util.BitUtils;
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090027import com.android.internal.util.Preconditions;
Hugo Benichi59c8e422017-10-12 21:33:40 +090028
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090029import java.lang.annotation.Retention;
30import java.lang.annotation.RetentionPolicy;
Etan Cohena4824cf2018-11-02 15:07:20 -070031import java.net.Inet6Address;
32import java.net.UnknownHostException;
Jong Wook Kimf0a55cc2018-01-31 19:03:19 -080033import java.security.SecureRandom;
Hugo Benichi59c8e422017-10-12 21:33:40 +090034import java.util.Arrays;
Hugo Benichiac52e402017-11-09 00:22:25 +090035import java.util.Random;
Hugo Benichi59c8e422017-10-12 21:33:40 +090036
37/**
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090038 * Representation of a MAC address.
39 *
40 * This class only supports 48 bits long addresses and does not support 64 bits long addresses.
41 * Instances of this class are immutable.
Hugo Benichi59c8e422017-10-12 21:33:40 +090042 */
Hugo Benichiac52e402017-11-09 00:22:25 +090043public final class MacAddress implements Parcelable {
Hugo Benichi59c8e422017-10-12 21:33:40 +090044
45 private static final int ETHER_ADDR_LEN = 6;
Hugo Benichiac52e402017-11-09 00:22:25 +090046 private static final byte[] ETHER_ADDR_BROADCAST = addr(0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
Hugo Benichi59c8e422017-10-12 21:33:40 +090047
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090048 /**
49 * The MacAddress representing the unique broadcast MAC address.
50 */
51 public static final MacAddress BROADCAST_ADDRESS = MacAddress.fromBytes(ETHER_ADDR_BROADCAST);
Hugo Benichiac52e402017-11-09 00:22:25 +090052
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090053 /**
54 * The MacAddress zero MAC address.
Remi NGUYEN VAN31f1d0c2019-01-20 12:52:43 +090055 *
56 * <p>Not publicly exposed or treated specially since the OUI 00:00:00 is registered.
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090057 * @hide
58 */
Mathew Inwood53f089f2018-08-08 14:44:44 +010059 @UnsupportedAppUsage
Hugo Benichiac52e402017-11-09 00:22:25 +090060 public static final MacAddress ALL_ZEROS_ADDRESS = new MacAddress(0);
61
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090062 /** @hide */
63 @Retention(RetentionPolicy.SOURCE)
64 @IntDef(prefix = { "TYPE_" }, value = {
65 TYPE_UNKNOWN,
66 TYPE_UNICAST,
67 TYPE_MULTICAST,
68 TYPE_BROADCAST,
69 })
70 public @interface MacAddressType { }
Hugo Benichi59c8e422017-10-12 21:33:40 +090071
Hugo Benichi48872c62018-01-12 09:46:29 +090072 /** @hide Indicates a MAC address of unknown type. */
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090073 public static final int TYPE_UNKNOWN = 0;
74 /** Indicates a MAC address is a unicast address. */
75 public static final int TYPE_UNICAST = 1;
76 /** Indicates a MAC address is a multicast address. */
77 public static final int TYPE_MULTICAST = 2;
78 /** Indicates a MAC address is the broadcast address. */
79 public static final int TYPE_BROADCAST = 3;
Hugo Benichiac52e402017-11-09 00:22:25 +090080
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090081 private static final long VALID_LONG_MASK = (1L << 48) - 1;
82 private static final long LOCALLY_ASSIGNED_MASK = MacAddress.fromString("2:0:0:0:0:0").mAddr;
83 private static final long MULTICAST_MASK = MacAddress.fromString("1:0:0:0:0:0").mAddr;
84 private static final long OUI_MASK = MacAddress.fromString("ff:ff:ff:0:0:0").mAddr;
85 private static final long NIC_MASK = MacAddress.fromString("0:0:0:ff:ff:ff").mAddr;
86 private static final MacAddress BASE_GOOGLE_MAC = MacAddress.fromString("da:a1:19:0:0:0");
87
88 // Internal representation of the MAC address as a single 8 byte long.
Hugo Benichiac52e402017-11-09 00:22:25 +090089 // The encoding scheme sets the two most significant bytes to 0. The 6 bytes of the
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090090 // MAC address are encoded in the 6 least significant bytes of the long, where the first
Hugo Benichiac52e402017-11-09 00:22:25 +090091 // byte of the array is mapped to the 3rd highest logical byte of the long, the second
92 // byte of the array is mapped to the 4th highest logical byte of the long, and so on.
93 private final long mAddr;
94
95 private MacAddress(long addr) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090096 mAddr = (VALID_LONG_MASK & addr);
Hugo Benichiac52e402017-11-09 00:22:25 +090097 }
98
Hugo Benichi84bb7fc2017-11-16 14:40:16 +090099 /**
100 * Returns the type of this address.
101 *
102 * @return the int constant representing the MAC address type of this MacAddress.
103 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900104 public @MacAddressType int getAddressType() {
Hugo Benichiac52e402017-11-09 00:22:25 +0900105 if (equals(BROADCAST_ADDRESS)) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900106 return TYPE_BROADCAST;
Hugo Benichiac52e402017-11-09 00:22:25 +0900107 }
108 if (isMulticastAddress()) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900109 return TYPE_MULTICAST;
Hugo Benichiac52e402017-11-09 00:22:25 +0900110 }
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900111 return TYPE_UNICAST;
Hugo Benichiac52e402017-11-09 00:22:25 +0900112 }
113
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900114 /**
115 * @return true if this MacAddress is a multicast address.
116 * @hide
117 */
Hugo Benichiac52e402017-11-09 00:22:25 +0900118 public boolean isMulticastAddress() {
119 return (mAddr & MULTICAST_MASK) != 0;
120 }
121
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900122 /**
123 * @return true if this MacAddress is a locally assigned address.
124 */
Hugo Benichiac52e402017-11-09 00:22:25 +0900125 public boolean isLocallyAssigned() {
126 return (mAddr & LOCALLY_ASSIGNED_MASK) != 0;
127 }
128
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900129 /**
130 * @return a byte array representation of this MacAddress.
131 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900132 public @NonNull byte[] toByteArray() {
Hugo Benichiac52e402017-11-09 00:22:25 +0900133 return byteAddrFromLongAddr(mAddr);
134 }
135
136 @Override
Hugo Benichi48872c62018-01-12 09:46:29 +0900137 public @NonNull String toString() {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900138 return stringAddrFromLongAddr(mAddr);
139 }
140
141 /**
Hugo Benichia0ecf382017-12-15 10:07:35 +0900142 * @return a String representation of the OUI part of this MacAddress made of 3 hexadecimal
143 * numbers in [0,ff] joined by ':' characters.
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900144 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900145 public @NonNull String toOuiString() {
Hugo Benichia0ecf382017-12-15 10:07:35 +0900146 return String.format(
147 "%02x:%02x:%02x", (mAddr >> 40) & 0xff, (mAddr >> 32) & 0xff, (mAddr >> 24) & 0xff);
Hugo Benichiac52e402017-11-09 00:22:25 +0900148 }
149
150 @Override
151 public int hashCode() {
152 return (int) ((mAddr >> 32) ^ mAddr);
153 }
154
155 @Override
156 public boolean equals(Object o) {
157 return (o instanceof MacAddress) && ((MacAddress) o).mAddr == mAddr;
158 }
159
160 @Override
161 public void writeToParcel(Parcel out, int flags) {
162 out.writeLong(mAddr);
163 }
164
165 @Override
166 public int describeContents() {
167 return 0;
168 }
169
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700170 public static final @android.annotation.NonNull Parcelable.Creator<MacAddress> CREATOR =
Hugo Benichiac52e402017-11-09 00:22:25 +0900171 new Parcelable.Creator<MacAddress>() {
172 public MacAddress createFromParcel(Parcel in) {
173 return new MacAddress(in.readLong());
174 }
175
176 public MacAddress[] newArray(int size) {
177 return new MacAddress[size];
178 }
179 };
180
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900181 /**
182 * Returns true if the given byte array is an valid MAC address.
183 * A valid byte array representation for a MacAddress is a non-null array of length 6.
184 *
185 * @param addr a byte array.
186 * @return true if the given byte array is not null and has the length of a MAC address.
187 *
188 * @hide
189 */
Hugo Benichi59c8e422017-10-12 21:33:40 +0900190 public static boolean isMacAddress(byte[] addr) {
191 return addr != null && addr.length == ETHER_ADDR_LEN;
192 }
193
194 /**
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900195 * Returns the MAC address type of the MAC address represented by the given byte array,
196 * or null if the given byte array does not represent a MAC address.
197 * A valid byte array representation for a MacAddress is a non-null array of length 6.
198 *
199 * @param addr a byte array representing a MAC address.
200 * @return the int constant representing the MAC address type of the MAC address represented
201 * by the given byte array, or type UNKNOWN if the byte array is not a valid MAC address.
202 *
203 * @hide
Hugo Benichiac52e402017-11-09 00:22:25 +0900204 */
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900205 public static int macAddressType(byte[] addr) {
Hugo Benichi59c8e422017-10-12 21:33:40 +0900206 if (!isMacAddress(addr)) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900207 return TYPE_UNKNOWN;
Hugo Benichi59c8e422017-10-12 21:33:40 +0900208 }
Hugo Benichi48872c62018-01-12 09:46:29 +0900209 return MacAddress.fromBytes(addr).getAddressType();
Hugo Benichiac52e402017-11-09 00:22:25 +0900210 }
211
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900212 /**
213 * Converts a String representation of a MAC address to a byte array representation.
214 * A valid String representation for a MacAddress is a series of 6 values in the
215 * range [0,ff] printed in hexadecimal and joined by ':' characters.
216 *
217 * @param addr a String representation of a MAC address.
218 * @return the byte representation of the MAC address.
219 * @throws IllegalArgumentException if the given String is not a valid representation.
220 *
221 * @hide
222 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900223 public static @NonNull byte[] byteAddrFromStringAddr(String addr) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900224 Preconditions.checkNotNull(addr);
Hugo Benichiac52e402017-11-09 00:22:25 +0900225 String[] parts = addr.split(":");
226 if (parts.length != ETHER_ADDR_LEN) {
227 throw new IllegalArgumentException(addr + " was not a valid MAC address");
Hugo Benichi59c8e422017-10-12 21:33:40 +0900228 }
Hugo Benichiac52e402017-11-09 00:22:25 +0900229 byte[] bytes = new byte[ETHER_ADDR_LEN];
230 for (int i = 0; i < ETHER_ADDR_LEN; i++) {
231 int x = Integer.valueOf(parts[i], 16);
232 if (x < 0 || 0xff < x) {
233 throw new IllegalArgumentException(addr + "was not a valid MAC address");
234 }
235 bytes[i] = (byte) x;
236 }
237 return bytes;
238 }
239
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900240 /**
241 * Converts a byte array representation of a MAC address to a String representation made
242 * of 6 hexadecimal numbers in [0,ff] joined by ':' characters.
243 * A valid byte array representation for a MacAddress is a non-null array of length 6.
244 *
245 * @param addr a byte array representation of a MAC address.
246 * @return the String representation of the MAC address.
247 * @throws IllegalArgumentException if the given byte array is not a valid representation.
248 *
249 * @hide
250 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900251 public static @NonNull String stringAddrFromByteAddr(byte[] addr) {
Hugo Benichiac52e402017-11-09 00:22:25 +0900252 if (!isMacAddress(addr)) {
253 return null;
254 }
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900255 return String.format("%02x:%02x:%02x:%02x:%02x:%02x",
256 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
Hugo Benichiac52e402017-11-09 00:22:25 +0900257 }
258
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900259 private static byte[] byteAddrFromLongAddr(long addr) {
Hugo Benichiac52e402017-11-09 00:22:25 +0900260 byte[] bytes = new byte[ETHER_ADDR_LEN];
261 int index = ETHER_ADDR_LEN;
262 while (index-- > 0) {
263 bytes[index] = (byte) addr;
264 addr = addr >> 8;
265 }
266 return bytes;
267 }
268
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900269 private static long longAddrFromByteAddr(byte[] addr) {
270 Preconditions.checkNotNull(addr);
Hugo Benichiac52e402017-11-09 00:22:25 +0900271 if (!isMacAddress(addr)) {
272 throw new IllegalArgumentException(
273 Arrays.toString(addr) + " was not a valid MAC address");
274 }
275 long longAddr = 0;
276 for (byte b : addr) {
277 longAddr = (longAddr << 8) + BitUtils.uint8(b);
278 }
279 return longAddr;
280 }
281
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900282 // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr))
283 // that avoids the allocation of an intermediary byte[].
284 private static long longAddrFromStringAddr(String addr) {
285 Preconditions.checkNotNull(addr);
Hugo Benichiac52e402017-11-09 00:22:25 +0900286 String[] parts = addr.split(":");
287 if (parts.length != ETHER_ADDR_LEN) {
288 throw new IllegalArgumentException(addr + " was not a valid MAC address");
289 }
290 long longAddr = 0;
Hugo Benichid2c5b192017-12-05 13:14:08 +0900291 for (int i = 0; i < parts.length; i++) {
292 int x = Integer.valueOf(parts[i], 16);
Hugo Benichiac52e402017-11-09 00:22:25 +0900293 if (x < 0 || 0xff < x) {
294 throw new IllegalArgumentException(addr + "was not a valid MAC address");
295 }
296 longAddr = x + (longAddr << 8);
297 }
298 return longAddr;
299 }
300
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900301 // Internal conversion function equivalent to stringAddrFromByteAddr(byteAddrFromLongAddr(addr))
302 // that avoids the allocation of an intermediary byte[].
Hugo Benichi48872c62018-01-12 09:46:29 +0900303 private static @NonNull String stringAddrFromLongAddr(long addr) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900304 return String.format("%02x:%02x:%02x:%02x:%02x:%02x",
305 (addr >> 40) & 0xff,
306 (addr >> 32) & 0xff,
307 (addr >> 24) & 0xff,
308 (addr >> 16) & 0xff,
309 (addr >> 8) & 0xff,
310 addr & 0xff);
Hugo Benichiac52e402017-11-09 00:22:25 +0900311 }
312
313 /**
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900314 * Creates a MacAddress from the given String representation. A valid String representation
315 * for a MacAddress is a series of 6 values in the range [0,ff] printed in hexadecimal
316 * and joined by ':' characters.
317 *
318 * @param addr a String representation of a MAC address.
319 * @return the MacAddress corresponding to the given String representation.
320 * @throws IllegalArgumentException if the given String is not a valid representation.
Hugo Benichiac52e402017-11-09 00:22:25 +0900321 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900322 public static @NonNull MacAddress fromString(@NonNull String addr) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900323 return new MacAddress(longAddrFromStringAddr(addr));
Hugo Benichiac52e402017-11-09 00:22:25 +0900324 }
325
326 /**
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900327 * Creates a MacAddress from the given byte array representation.
328 * A valid byte array representation for a MacAddress is a non-null array of length 6.
329 *
330 * @param addr a byte array representation of a MAC address.
331 * @return the MacAddress corresponding to the given byte array representation.
332 * @throws IllegalArgumentException if the given byte array is not a valid representation.
Hugo Benichiac52e402017-11-09 00:22:25 +0900333 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900334 public static @NonNull MacAddress fromBytes(@NonNull byte[] addr) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900335 return new MacAddress(longAddrFromByteAddr(addr));
336 }
337
338 /**
339 * Returns a generated MAC address whose 24 least significant bits constituting the
Jong Wook Kimf0a55cc2018-01-31 19:03:19 -0800340 * NIC part of the address are randomly selected and has Google OUI base.
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900341 *
342 * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
343 *
Jong Wook Kimf0a55cc2018-01-31 19:03:19 -0800344 * @return a random locally assigned, unicast MacAddress with Google OUI.
345 *
346 * @hide
347 */
348 public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() {
349 return createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom());
350 }
351
352 /**
353 * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the
354 * unicast bit, are randomly selected.
355 *
356 * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
357 *
358 * @return a random locally assigned, unicast MacAddress.
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900359 *
360 * @hide
361 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900362 public static @NonNull MacAddress createRandomUnicastAddress() {
Jong Wook Kimf0a55cc2018-01-31 19:03:19 -0800363 SecureRandom r = new SecureRandom();
364 long addr = r.nextLong() & VALID_LONG_MASK;
365 addr |= LOCALLY_ASSIGNED_MASK;
366 addr &= ~MULTICAST_MASK;
367 return new MacAddress(addr);
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900368 }
369
370 /**
371 * Returns a randomly generated MAC address using the given Random object and the same
372 * OUI values as the given MacAddress.
373 *
374 * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
375 *
376 * @param base a base MacAddress whose OUI is used for generating the random address.
377 * @param r a standard Java Random object used for generating the random address.
378 * @return a random locally assigned MacAddress.
379 *
380 * @hide
381 */
Hugo Benichi48872c62018-01-12 09:46:29 +0900382 public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) {
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900383 long addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong());
Jong Wook Kimf0a55cc2018-01-31 19:03:19 -0800384 addr |= LOCALLY_ASSIGNED_MASK;
385 addr &= ~MULTICAST_MASK;
Hugo Benichi84bb7fc2017-11-16 14:40:16 +0900386 return new MacAddress(addr);
Hugo Benichiac52e402017-11-09 00:22:25 +0900387 }
388
389 // Convenience function for working around the lack of byte literals.
390 private static byte[] addr(int... in) {
391 if (in.length != ETHER_ADDR_LEN) {
392 throw new IllegalArgumentException(Arrays.toString(in)
393 + " was not an array with length equal to " + ETHER_ADDR_LEN);
394 }
395 byte[] out = new byte[ETHER_ADDR_LEN];
396 for (int i = 0; i < ETHER_ADDR_LEN; i++) {
397 out[i] = (byte) in[i];
398 }
399 return out;
Hugo Benichi59c8e422017-10-12 21:33:40 +0900400 }
Roshan Pius99cfe092018-10-05 09:42:19 -0700401
402 /**
403 * Checks if this MAC Address matches the provided range.
404 *
405 * @param baseAddress MacAddress representing the base address to compare with.
406 * @param mask MacAddress representing the mask to use during comparison.
407 * @return true if this MAC Address matches the given range.
408 *
409 * @hide
410 */
411 public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
412 Preconditions.checkNotNull(baseAddress);
413 Preconditions.checkNotNull(mask);
414 return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr);
415 }
Etan Cohena4824cf2018-11-02 15:07:20 -0700416
417 /**
418 * Create a link-local Inet6Address from the MAC address. The EUI-48 MAC address is converted
419 * to an EUI-64 MAC address per RFC 4291. The resulting EUI-64 is used to construct a link-local
420 * IPv6 address per RFC 4862.
421 *
422 * @return A link-local Inet6Address constructed from the MAC address.
423 * @hide
424 */
425 public @Nullable Inet6Address getLinkLocalIpv6FromEui48Mac() {
426 byte[] macEui48Bytes = toByteArray();
427 byte[] addr = new byte[16];
428
429 addr[0] = (byte) 0xfe;
430 addr[1] = (byte) 0x80;
431 addr[8] = (byte) (macEui48Bytes[0] ^ (byte) 0x02); // flip the link-local bit
432 addr[9] = macEui48Bytes[1];
433 addr[10] = macEui48Bytes[2];
434 addr[11] = (byte) 0xff;
435 addr[12] = (byte) 0xfe;
436 addr[13] = macEui48Bytes[3];
437 addr[14] = macEui48Bytes[4];
438 addr[15] = macEui48Bytes[5];
439
440 try {
441 return Inet6Address.getByAddress(null, addr, 0);
442 } catch (UnknownHostException e) {
443 return null;
444 }
445 }
Hugo Benichi59c8e422017-10-12 21:33:40 +0900446}