blob: 7723d6f38a947725befe29f77e5bf95c7a0fd1c1 [file] [log] [blame]
Andreas Wundsam40e14f72013-05-06 14:49:08 -07001package org.openflow.types;
2
3import org.jboss.netty.buffer.ChannelBuffer;
4import org.openflow.exceptions.OFParseError;
Andreas Wundsam40e14f72013-05-06 14:49:08 -07005import org.openflow.util.HexString;
6
7/**
8 * Wrapper around a 6 byte mac address.
9 *
10 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
11 */
12
Yotam Harchol5c9d6f42013-08-01 11:09:20 -070013public class MacAddress implements OFValueType<MacAddress> {
Andreas Wundsam40e14f72013-05-06 14:49:08 -070014 static final int MacAddrLen = 6;
15 private final long rawValue;
16
Yotam Harcholff8f85e2013-08-21 10:02:23 -070017 public static final MacAddress NO_MASK = MacAddress.of(0xFFFFFFFFFFFFFFFFl);
18 public static final MacAddress FULL_MASK = MacAddress.of(0x0);
Yotam Harcholc2813602013-08-20 12:14:22 -070019
Andreas Wundsam40e14f72013-05-06 14:49:08 -070020 private MacAddress(final long rawValue) {
21 this.rawValue = rawValue;
22 }
23
24 public static MacAddress of(final byte[] address) {
25 long raw =
26 (address[0] & 0xFFL) << 40 | (address[1] & 0xFFL) << 32
27 | (address[2] & 0xFFL) << 24 | (address[3] & 0xFFL) << 16
28 | (address[4] & 0xFFL) << 8 | (address[5] & 0xFFL);
29 return MacAddress.of(raw);
30 }
31
32 public static MacAddress of(final long raw) {
33 return new MacAddress(raw);
34 }
35
36 public static MacAddress of(final String string) {
37 int index = 0;
38 int shift = 40;
39
40 long raw = 0;
41 if (string.length() != 6 * 2 + 5)
42 throw new IllegalArgumentException("Mac address not well formed: " + string);
43
44 while (shift >= 0) {
45 raw |=
46 ((long) (Character.digit(string.charAt(index++), 16) << 4 | Character
47 .digit(string.charAt(index++), 16))) << shift;
48
49 if (shift == 0)
50 break;
51 if (string.charAt(index++) != ':')
52 throw new IllegalArgumentException("Mac address not well formed: " + string);
53 shift -= 8;
54 }
55 return MacAddress.of(raw);
56 }
57
58 volatile byte[] bytesCache = null;
59
60 public byte[] getBytes() {
61 if (bytesCache == null) {
62 synchronized (this) {
63 if (bytesCache == null) {
64 bytesCache =
65 new byte[] { (byte) ((rawValue >> 40) & 0xFF),
66 (byte) ((rawValue >> 32) & 0xFF),
67 (byte) ((rawValue >> 24) & 0xFF),
68 (byte) ((rawValue >> 16) & 0xFF),
69 (byte) ((rawValue >> 8) & 0xFF),
70 (byte) ((rawValue >> 0) & 0xFF) };
71 }
72 }
73 }
74 return bytesCache;
75 }
76
77 @Override
78 public int getLength() {
79 return MacAddrLen;
80 }
81
Andreas Wundsam40e14f72013-05-06 14:49:08 -070082 @Override
83 public String toString() {
84 return HexString.toHexString(rawValue, 6);
85 }
86
87 @Override
88 public int hashCode() {
89 final int prime = 31;
90 int result = 1;
91 result = prime * result + (int) (rawValue ^ (rawValue >>> 32));
92 return result;
93 }
94
95 @Override
96 public boolean equals(final Object obj) {
97 if (this == obj)
98 return true;
99 if (obj == null)
100 return false;
101 if (getClass() != obj.getClass())
102 return false;
103 MacAddress other = (MacAddress) obj;
104 if (rawValue != other.rawValue)
105 return false;
106 return true;
107 }
108
109 public long getLong() {
110 return rawValue;
111 }
112
Yotam Harchold7b84202013-07-26 16:08:10 -0700113 public void write6Bytes(ChannelBuffer c) {
114 c.writeInt((int) (this.rawValue >> 16));
115 c.writeShort((int) this.rawValue & 0xFFFF);
Yotam Harchol161a5d52013-07-25 17:17:48 -0700116 }
117
Yotam Harchold7b84202013-07-26 16:08:10 -0700118 public static MacAddress read6Bytes(ChannelBuffer c) throws OFParseError {
119 long raw = c.readUnsignedInt() << 16 | c.readUnsignedShort();
120 return MacAddress.of(raw);
121 }
Yotam Harchol5c9d6f42013-08-01 11:09:20 -0700122
123 @Override
124 public MacAddress applyMask(MacAddress mask) {
125 return MacAddress.of(this.rawValue & mask.rawValue);
126 }
Yotam Harchol161a5d52013-07-25 17:17:48 -0700127
128
129
Andreas Wundsam40e14f72013-05-06 14:49:08 -0700130}