blob: 040d875eb4b9e07ec31bf36708f8f888d83fd4ab [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
17 public static final MacAddress NO_MASK = MacAddress.of(0xFFFFFFFFFFFFFFFFl);
18 public static final MacAddress FULL_MASK = MacAddress.of(0x0);
19
20 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
82 @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
113 public void write6Bytes(ChannelBuffer c) {
114 c.writeInt((int) (this.rawValue >> 16));
115 c.writeShort((int) this.rawValue & 0xFFFF);
116 }
117
118 public static MacAddress read6Bytes(ChannelBuffer c) throws OFParseError {
119 long raw = c.readUnsignedInt() << 16 | c.readUnsignedShort();
120 return MacAddress.of(raw);
121 }
122
123 @Override
124 public MacAddress applyMask(MacAddress mask) {
125 return MacAddress.of(this.rawValue & mask.rawValue);
126 }
127
128
129
130}