blob: 7d6f77e5abf36c6737b353b2024c9947e2005399 [file] [log] [blame]
alshabibc4901cd2014-09-05 16:50:40 -07001/*******************************************************************************
2 * Copyright 2014 Open Networking Laboratory
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 ******************************************************************************/
16package org.onlab.packet;
17
18import java.util.Arrays;
19
20/**
21 * The class representing MAC address.
22 *
23 * @author Sho Shimizu (sho.shimizu@gmail.com)
24 */
25public class MACAddress {
26 public static final int MAC_ADDRESS_LENGTH = 6;
27 private byte[] address = new byte[MACAddress.MAC_ADDRESS_LENGTH];
28
29 public MACAddress(final byte[] address) {
30 this.address = Arrays.copyOf(address, MACAddress.MAC_ADDRESS_LENGTH);
31 }
32
33 /**
34 * Returns a MAC address instance representing the value of the specified
35 * {@code String}.
36 *
37 * @param address
38 * the String representation of the MAC Address to be parsed.
39 * @return a MAC Address instance representing the value of the specified
40 * {@code String}.
41 * @throws IllegalArgumentException
42 * if the string cannot be parsed as a MAC address.
43 */
44 public static MACAddress valueOf(final String address) {
45 final String[] elements = address.split(":");
46 if (elements.length != MACAddress.MAC_ADDRESS_LENGTH) {
47 throw new IllegalArgumentException(
48 "Specified MAC Address must contain 12 hex digits"
49 + " separated pairwise by :'s.");
50 }
51
52 final byte[] addressInBytes = new byte[MACAddress.MAC_ADDRESS_LENGTH];
53 for (int i = 0; i < MACAddress.MAC_ADDRESS_LENGTH; i++) {
54 final String element = elements[i];
55 addressInBytes[i] = (byte) Integer.parseInt(element, 16);
56 }
57
58 return new MACAddress(addressInBytes);
59 }
60
61 /**
62 * Returns a MAC address instance representing the specified {@code byte}
63 * array.
64 *
65 * @param address
66 * the byte array to be parsed.
67 * @return a MAC address instance representing the specified {@code byte}
68 * array.
69 * @throws IllegalArgumentException
70 * if the byte array cannot be parsed as a MAC address.
71 */
72 public static MACAddress valueOf(final byte[] address) {
73 if (address.length != MACAddress.MAC_ADDRESS_LENGTH) {
74 throw new IllegalArgumentException("the length is not "
75 + MACAddress.MAC_ADDRESS_LENGTH);
76 }
77
78 return new MACAddress(address);
79 }
80
81 /**
82 * Returns a MAC address instance representing the specified {@code long}
83 * value. The lower 48 bits of the long value are used to parse as a MAC
84 * address.
85 *
86 * @param address
87 * the long value to be parsed. The lower 48 bits are used for a
88 * MAC address.
89 * @return a MAC address instance representing the specified {@code long}
90 * value.
91 * @throws IllegalArgumentException
92 * if the long value cannot be parsed as a MAC address.
93 */
94 public static MACAddress valueOf(final long address) {
95 final byte[] addressInBytes = new byte[] {
96 (byte) (address >> 40 & 0xff), (byte) (address >> 32 & 0xff),
97 (byte) (address >> 24 & 0xff), (byte) (address >> 16 & 0xff),
98 (byte) (address >> 8 & 0xff), (byte) (address >> 0 & 0xff) };
99
100 return new MACAddress(addressInBytes);
101 }
102
103 /**
104 * Returns the length of the {@code MACAddress}.
105 *
106 * @return the length of the {@code MACAddress}.
107 */
108 public int length() {
109 return this.address.length;
110 }
111
112 /**
113 * Returns the value of the {@code MACAddress} as a {@code byte} array.
114 *
115 * @return the numeric value represented by this object after conversion to
116 * type {@code byte} array.
117 */
118 public byte[] toBytes() {
119 return Arrays.copyOf(this.address, this.address.length);
120 }
121
122 /**
123 * Returns the value of the {@code MACAddress} as a {@code long}.
124 *
125 * @return the numeric value represented by this object after conversion to
126 * type {@code long}.
127 */
128 public long toLong() {
129 long mac = 0;
130 for (int i = 0; i < 6; i++) {
131 final long t = (this.address[i] & 0xffL) << (5 - i) * 8;
132 mac |= t;
133 }
134 return mac;
135 }
136
137 /**
138 * Returns {@code true} if the MAC address is the broadcast address.
139 *
140 * @return {@code true} if the MAC address is the broadcast address.
141 */
142 public boolean isBroadcast() {
143 for (final byte b : this.address) {
144 if (b != -1) {
145 return false;
146 }
147 }
148 return true;
149 }
150
151 /**
152 * Returns {@code true} if the MAC address is the multicast address.
153 *
154 * @return {@code true} if the MAC address is the multicast address.
155 */
156 public boolean isMulticast() {
157 if (this.isBroadcast()) {
158 return false;
159 }
160 return (this.address[0] & 0x01) != 0;
161 }
162
163 @Override
164 public boolean equals(final Object o) {
165 if (o == this) {
166 return true;
167 }
168
169 if (!(o instanceof MACAddress)) {
170 return false;
171 }
172
173 final MACAddress other = (MACAddress) o;
174 return Arrays.equals(this.address, other.address);
175 }
176
177 @Override
178 public int hashCode() {
179 return Arrays.hashCode(this.address);
180 }
181
182 @Override
183 public String toString() {
184 final StringBuilder builder = new StringBuilder();
185 for (final byte b : this.address) {
186 if (builder.length() > 0) {
187 builder.append(":");
188 }
189 builder.append(String.format("%02X", b & 0xFF));
190 }
191 return builder.toString();
192 }
193
194 /**
195 * @return MAC address in string representation without colons (useful for
196 * radix tree storage)
197 */
198 public String toStringNoColon() {
199 final StringBuilder builder = new StringBuilder();
200 for (final byte b : this.address) {
201 builder.append(String.format("%02X", b & 0xFF));
202 }
203 return builder.toString();
204 }
205
206 public byte[] getAddress() {
207 return this.address;
208 }
209}