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