blob: ae7deaa50a47756ca36b66769f8db57c3ecaac3b [file] [log] [blame]
Hugo Benichi88ad29b2017-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
Etan Cohen42ab31a2018-11-02 15:07:20 -070019import static org.junit.Assert.assertArrayEquals;
Hugo Benichi88ad29b2017-10-12 21:33:40 +090020import static org.junit.Assert.assertEquals;
Hugo Benichi88ad29b2017-10-12 21:33:40 +090021import static org.junit.Assert.assertFalse;
Roshan Piuse26dae32018-10-05 09:42:19 -070022import static org.junit.Assert.assertTrue;
Hugo Benichid380d142017-11-09 00:22:25 +090023import static org.junit.Assert.fail;
Hugo Benichi88ad29b2017-10-12 21:33:40 +090024
Remi NGUYEN VAN154cf1d2021-06-29 17:16:28 +090025import android.os.Build;
26
Brett Chabot147f6cf2019-03-04 14:14:56 -080027import androidx.test.filters.SmallTest;
Hugo Benichi88ad29b2017-10-12 21:33:40 +090028
Chalard Jean79162542020-08-19 16:07:22 +090029import com.android.net.module.util.MacAddressUtils;
Remi NGUYEN VAN154cf1d2021-06-29 17:16:28 +090030import com.android.testutils.DevSdkIgnoreRule;
31import com.android.testutils.DevSdkIgnoreRunner;
Chalard Jean79162542020-08-19 16:07:22 +090032
Hugo Benichi88ad29b2017-10-12 21:33:40 +090033import org.junit.Test;
34import org.junit.runner.RunWith;
35
Etan Cohen42ab31a2018-11-02 15:07:20 -070036import java.net.Inet6Address;
37import java.util.Arrays;
38import java.util.Random;
39
Hugo Benichi88ad29b2017-10-12 21:33:40 +090040@SmallTest
Remi NGUYEN VAN154cf1d2021-06-29 17:16:28 +090041@RunWith(DevSdkIgnoreRunner.class)
42@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
Hugo Benichi88ad29b2017-10-12 21:33:40 +090043public class MacAddressTest {
44
45 static class AddrTypeTestCase {
46 byte[] addr;
Hugo Benichi5bc35462017-11-16 14:40:16 +090047 int expectedType;
Hugo Benichi88ad29b2017-10-12 21:33:40 +090048
Hugo Benichi5bc35462017-11-16 14:40:16 +090049 static AddrTypeTestCase of(int expectedType, int... addr) {
Hugo Benichi88ad29b2017-10-12 21:33:40 +090050 AddrTypeTestCase t = new AddrTypeTestCase();
Hugo Benichi5bc35462017-11-16 14:40:16 +090051 t.expectedType = expectedType;
Hugo Benichi88ad29b2017-10-12 21:33:40 +090052 t.addr = toByteArray(addr);
53 return t;
54 }
55 }
56
57 @Test
58 public void testMacAddrTypes() {
59 AddrTypeTestCase[] testcases = {
Hugo Benichi5bc35462017-11-16 14:40:16 +090060 AddrTypeTestCase.of(MacAddress.TYPE_UNKNOWN),
61 AddrTypeTestCase.of(MacAddress.TYPE_UNKNOWN, 0),
62 AddrTypeTestCase.of(MacAddress.TYPE_UNKNOWN, 1, 2, 3, 4, 5),
63 AddrTypeTestCase.of(MacAddress.TYPE_UNKNOWN, 1, 2, 3, 4, 5, 6, 7),
64 AddrTypeTestCase.of(MacAddress.TYPE_UNICAST, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0),
65 AddrTypeTestCase.of(MacAddress.TYPE_BROADCAST, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),
66 AddrTypeTestCase.of(MacAddress.TYPE_MULTICAST, 1, 2, 3, 4, 5, 6),
67 AddrTypeTestCase.of(MacAddress.TYPE_MULTICAST, 11, 22, 33, 44, 55, 66),
68 AddrTypeTestCase.of(MacAddress.TYPE_MULTICAST, 33, 33, 0xaa, 0xbb, 0xcc, 0xdd)
Hugo Benichi88ad29b2017-10-12 21:33:40 +090069 };
70
71 for (AddrTypeTestCase t : testcases) {
Hugo Benichi5bc35462017-11-16 14:40:16 +090072 int got = MacAddress.macAddressType(t.addr);
Hugo Benichi88ad29b2017-10-12 21:33:40 +090073 String msg = String.format("expected type of %s to be %s, but got %s",
Hugo Benichi5bc35462017-11-16 14:40:16 +090074 Arrays.toString(t.addr), t.expectedType, got);
75 assertEquals(msg, t.expectedType, got);
Hugo Benichid380d142017-11-09 00:22:25 +090076
Hugo Benichi5bc35462017-11-16 14:40:16 +090077 if (got != MacAddress.TYPE_UNKNOWN) {
Hugo Benichi8f217582018-01-12 09:46:29 +090078 assertEquals(got, MacAddress.fromBytes(t.addr).getAddressType());
Hugo Benichid380d142017-11-09 00:22:25 +090079 }
Hugo Benichi88ad29b2017-10-12 21:33:40 +090080 }
81 }
82
Hugo Benichid380d142017-11-09 00:22:25 +090083 @Test
Hugo Benichi3f83b8a2017-12-15 10:07:35 +090084 public void testToOuiString() {
Hugo Benichi5bc35462017-11-16 14:40:16 +090085 String[][] macs = {
Hugo Benichi3f83b8a2017-12-15 10:07:35 +090086 {"07:00:d3:56:8a:c4", "07:00:d3"},
87 {"33:33:aa:bb:cc:dd", "33:33:aa"},
88 {"06:00:00:00:00:00", "06:00:00"},
89 {"07:00:d3:56:8a:c4", "07:00:d3"}
Hugo Benichi5bc35462017-11-16 14:40:16 +090090 };
91
92 for (String[] pair : macs) {
93 String mac = pair[0];
94 String expected = pair[1];
Hugo Benichi3f83b8a2017-12-15 10:07:35 +090095 assertEquals(expected, MacAddress.fromString(mac).toOuiString());
Hugo Benichi5bc35462017-11-16 14:40:16 +090096 }
97 }
98
99 @Test
100 public void testHexPaddingWhenPrinting() {
101 String[] macs = {
102 "07:00:d3:56:8a:c4",
103 "33:33:aa:bb:cc:dd",
104 "06:00:00:00:00:00",
105 "07:00:d3:56:8a:c4"
106 };
107
108 for (String mac : macs) {
109 assertEquals(mac, MacAddress.fromString(mac).toString());
110 assertEquals(mac,
111 MacAddress.stringAddrFromByteAddr(MacAddress.byteAddrFromStringAddr(mac)));
112 }
113 }
114
115 @Test
Hugo Benichid380d142017-11-09 00:22:25 +0900116 public void testIsMulticastAddress() {
117 MacAddress[] multicastAddresses = {
118 MacAddress.BROADCAST_ADDRESS,
Hugo Benichi5bc35462017-11-16 14:40:16 +0900119 MacAddress.fromString("07:00:d3:56:8a:c4"),
120 MacAddress.fromString("33:33:aa:bb:cc:dd"),
Hugo Benichid380d142017-11-09 00:22:25 +0900121 };
122 MacAddress[] unicastAddresses = {
123 MacAddress.ALL_ZEROS_ADDRESS,
Hugo Benichi5bc35462017-11-16 14:40:16 +0900124 MacAddress.fromString("00:01:44:55:66:77"),
125 MacAddress.fromString("08:00:22:33:44:55"),
126 MacAddress.fromString("06:00:00:00:00:00"),
Hugo Benichid380d142017-11-09 00:22:25 +0900127 };
128
129 for (MacAddress mac : multicastAddresses) {
130 String msg = mac.toString() + " expected to be a multicast address";
Aaron Huangadfebb82019-12-17 00:33:18 +0800131 assertTrue(msg, MacAddressUtils.isMulticastAddress(mac));
Hugo Benichid380d142017-11-09 00:22:25 +0900132 }
133 for (MacAddress mac : unicastAddresses) {
134 String msg = mac.toString() + " expected not to be a multicast address";
Aaron Huangadfebb82019-12-17 00:33:18 +0800135 assertFalse(msg, MacAddressUtils.isMulticastAddress(mac));
Hugo Benichid380d142017-11-09 00:22:25 +0900136 }
137 }
138
139 @Test
140 public void testIsLocallyAssignedAddress() {
141 MacAddress[] localAddresses = {
Hugo Benichi5bc35462017-11-16 14:40:16 +0900142 MacAddress.fromString("06:00:00:00:00:00"),
143 MacAddress.fromString("07:00:d3:56:8a:c4"),
144 MacAddress.fromString("33:33:aa:bb:cc:dd"),
Hugo Benichid380d142017-11-09 00:22:25 +0900145 };
146 MacAddress[] universalAddresses = {
Hugo Benichi5bc35462017-11-16 14:40:16 +0900147 MacAddress.fromString("00:01:44:55:66:77"),
148 MacAddress.fromString("08:00:22:33:44:55"),
Hugo Benichid380d142017-11-09 00:22:25 +0900149 };
150
151 for (MacAddress mac : localAddresses) {
152 String msg = mac.toString() + " expected to be a locally assigned address";
153 assertTrue(msg, mac.isLocallyAssigned());
154 }
155 for (MacAddress mac : universalAddresses) {
156 String msg = mac.toString() + " expected not to be globally unique address";
157 assertFalse(msg, mac.isLocallyAssigned());
158 }
159 }
160
161 @Test
162 public void testMacAddressConversions() {
163 final int iterations = 10000;
164 for (int i = 0; i < iterations; i++) {
Aaron Huangadfebb82019-12-17 00:33:18 +0800165 MacAddress mac = MacAddressUtils.createRandomUnicastAddress();
Hugo Benichid380d142017-11-09 00:22:25 +0900166
167 String stringRepr = mac.toString();
168 byte[] bytesRepr = mac.toByteArray();
169
Hugo Benichi5bc35462017-11-16 14:40:16 +0900170 assertEquals(mac, MacAddress.fromString(stringRepr));
171 assertEquals(mac, MacAddress.fromBytes(bytesRepr));
Hugo Benichi21c7a522017-12-05 13:14:08 +0900172
173 assertEquals(mac, MacAddress.fromString(MacAddress.stringAddrFromByteAddr(bytesRepr)));
174 assertEquals(mac, MacAddress.fromBytes(MacAddress.byteAddrFromStringAddr(stringRepr)));
Hugo Benichid380d142017-11-09 00:22:25 +0900175 }
176 }
177
178 @Test
179 public void testMacAddressRandomGeneration() {
180 final int iterations = 1000;
181 final String expectedAndroidOui = "da:a1:19";
182 for (int i = 0; i < iterations; i++) {
Jong Wook Kim93dd5e62018-01-31 19:03:19 -0800183 MacAddress mac = MacAddress.createRandomUnicastAddressWithGoogleBase();
Hugo Benichid380d142017-11-09 00:22:25 +0900184 String stringRepr = mac.toString();
185
186 assertTrue(stringRepr + " expected to be a locally assigned address",
187 mac.isLocallyAssigned());
188 assertTrue(stringRepr + " expected to begin with " + expectedAndroidOui,
189 stringRepr.startsWith(expectedAndroidOui));
190 }
191
192 final Random r = new Random();
193 final String anotherOui = "24:5f:78";
194 final String expectedLocalOui = "26:5f:78";
Hugo Benichi5bc35462017-11-16 14:40:16 +0900195 final MacAddress base = MacAddress.fromString(anotherOui + ":0:0:0");
Hugo Benichid380d142017-11-09 00:22:25 +0900196 for (int i = 0; i < iterations; i++) {
Aaron Huangadfebb82019-12-17 00:33:18 +0800197 MacAddress mac = MacAddressUtils.createRandomUnicastAddress(base, r);
Hugo Benichid380d142017-11-09 00:22:25 +0900198 String stringRepr = mac.toString();
199
200 assertTrue(stringRepr + " expected to be a locally assigned address",
201 mac.isLocallyAssigned());
Hugo Benichi8f217582018-01-12 09:46:29 +0900202 assertEquals(MacAddress.TYPE_UNICAST, mac.getAddressType());
Hugo Benichid380d142017-11-09 00:22:25 +0900203 assertTrue(stringRepr + " expected to begin with " + expectedLocalOui,
204 stringRepr.startsWith(expectedLocalOui));
205 }
Jong Wook Kim93dd5e62018-01-31 19:03:19 -0800206
207 for (int i = 0; i < iterations; i++) {
Aaron Huangadfebb82019-12-17 00:33:18 +0800208 MacAddress mac = MacAddressUtils.createRandomUnicastAddress();
Jong Wook Kim93dd5e62018-01-31 19:03:19 -0800209 String stringRepr = mac.toString();
210
211 assertTrue(stringRepr + " expected to be a locally assigned address",
212 mac.isLocallyAssigned());
213 assertEquals(MacAddress.TYPE_UNICAST, mac.getAddressType());
214 }
Hugo Benichid380d142017-11-09 00:22:25 +0900215 }
216
217 @Test
218 public void testConstructorInputValidation() {
219 String[] invalidStringAddresses = {
Hugo Benichid380d142017-11-09 00:22:25 +0900220 "",
221 "abcd",
222 "1:2:3:4:5",
223 "1:2:3:4:5:6:7",
224 "10000:2:3:4:5:6",
225 };
226
227 for (String s : invalidStringAddresses) {
228 try {
Hugo Benichi5bc35462017-11-16 14:40:16 +0900229 MacAddress mac = MacAddress.fromString(s);
230 fail("MacAddress.fromString(" + s + ") should have failed, but returned " + mac);
Hugo Benichid380d142017-11-09 00:22:25 +0900231 } catch (IllegalArgumentException excepted) {
232 }
233 }
234
Hugo Benichi5bc35462017-11-16 14:40:16 +0900235 try {
236 MacAddress mac = MacAddress.fromString(null);
237 fail("MacAddress.fromString(null) should have failed, but returned " + mac);
238 } catch (NullPointerException excepted) {
239 }
240
Hugo Benichid380d142017-11-09 00:22:25 +0900241 byte[][] invalidBytesAddresses = {
Hugo Benichid380d142017-11-09 00:22:25 +0900242 {},
243 {1,2,3,4,5},
244 {1,2,3,4,5,6,7},
245 };
246
247 for (byte[] b : invalidBytesAddresses) {
248 try {
Hugo Benichi5bc35462017-11-16 14:40:16 +0900249 MacAddress mac = MacAddress.fromBytes(b);
250 fail("MacAddress.fromBytes(" + Arrays.toString(b)
Hugo Benichid380d142017-11-09 00:22:25 +0900251 + ") should have failed, but returned " + mac);
252 } catch (IllegalArgumentException excepted) {
253 }
254 }
Hugo Benichi5bc35462017-11-16 14:40:16 +0900255
256 try {
257 MacAddress mac = MacAddress.fromBytes(null);
258 fail("MacAddress.fromBytes(null) should have failed, but returned " + mac);
259 } catch (NullPointerException excepted) {
260 }
Hugo Benichid380d142017-11-09 00:22:25 +0900261 }
262
Roshan Piuse26dae32018-10-05 09:42:19 -0700263 @Test
264 public void testMatches() {
265 // match 4 bytes prefix
266 assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
267 MacAddress.fromString("aa:bb:cc:dd:00:00"),
268 MacAddress.fromString("ff:ff:ff:ff:00:00")));
269
270 // match bytes 0,1,2 and 5
271 assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
272 MacAddress.fromString("aa:bb:cc:00:00:11"),
273 MacAddress.fromString("ff:ff:ff:00:00:ff")));
274
275 // match 34 bit prefix
276 assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
277 MacAddress.fromString("aa:bb:cc:dd:c0:00"),
278 MacAddress.fromString("ff:ff:ff:ff:c0:00")));
279
280 // fail to match 36 bit prefix
281 assertFalse(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
282 MacAddress.fromString("aa:bb:cc:dd:40:00"),
283 MacAddress.fromString("ff:ff:ff:ff:f0:00")));
284
285 // match all 6 bytes
286 assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
287 MacAddress.fromString("aa:bb:cc:dd:ee:11"),
288 MacAddress.fromString("ff:ff:ff:ff:ff:ff")));
289
290 // match none of 6 bytes
291 assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
292 MacAddress.fromString("00:00:00:00:00:00"),
293 MacAddress.fromString("00:00:00:00:00:00")));
294 }
295
Etan Cohen42ab31a2018-11-02 15:07:20 -0700296 /**
297 * Tests that link-local address generation from MAC is valid.
298 */
299 @Test
300 public void testLinkLocalFromMacGeneration() {
301 MacAddress mac = MacAddress.fromString("52:74:f2:b1:a8:7f");
302 byte[] inet6ll = {(byte) 0xfe, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x74,
303 (byte) 0xf2, (byte) 0xff, (byte) 0xfe, (byte) 0xb1, (byte) 0xa8, 0x7f};
304 Inet6Address llv6 = mac.getLinkLocalIpv6FromEui48Mac();
305 assertTrue(llv6.isLinkLocalAddress());
306 assertArrayEquals(inet6ll, llv6.getAddress());
307 }
308
Hugo Benichid380d142017-11-09 00:22:25 +0900309 static byte[] toByteArray(int... in) {
Hugo Benichi88ad29b2017-10-12 21:33:40 +0900310 byte[] out = new byte[in.length];
311 for (int i = 0; i < in.length; i++) {
312 out[i] = (byte) in[i];
313 }
314 return out;
315 }
316}