blob: a18dff321f874c26b778d52550e540c62be49549 [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 Harchol161a5d52013-07-25 17:17:48 -070013public class MacAddress implements OFValueType {
Andreas Wundsam40e14f72013-05-06 14:49:08 -070014 static final int MacAddrLen = 6;
15 private final long rawValue;
16
17 private MacAddress(final long rawValue) {
18 this.rawValue = rawValue;
19 }
20
21 public static MacAddress of(final byte[] address) {
22 long raw =
23 (address[0] & 0xFFL) << 40 | (address[1] & 0xFFL) << 32
24 | (address[2] & 0xFFL) << 24 | (address[3] & 0xFFL) << 16
25 | (address[4] & 0xFFL) << 8 | (address[5] & 0xFFL);
26 return MacAddress.of(raw);
27 }
28
29 public static MacAddress of(final long raw) {
30 return new MacAddress(raw);
31 }
32
33 public static MacAddress of(final String string) {
34 int index = 0;
35 int shift = 40;
36
37 long raw = 0;
38 if (string.length() != 6 * 2 + 5)
39 throw new IllegalArgumentException("Mac address not well formed: " + string);
40
41 while (shift >= 0) {
42 raw |=
43 ((long) (Character.digit(string.charAt(index++), 16) << 4 | Character
44 .digit(string.charAt(index++), 16))) << shift;
45
46 if (shift == 0)
47 break;
48 if (string.charAt(index++) != ':')
49 throw new IllegalArgumentException("Mac address not well formed: " + string);
50 shift -= 8;
51 }
52 return MacAddress.of(raw);
53 }
54
55 volatile byte[] bytesCache = null;
56
57 public byte[] getBytes() {
58 if (bytesCache == null) {
59 synchronized (this) {
60 if (bytesCache == null) {
61 bytesCache =
62 new byte[] { (byte) ((rawValue >> 40) & 0xFF),
63 (byte) ((rawValue >> 32) & 0xFF),
64 (byte) ((rawValue >> 24) & 0xFF),
65 (byte) ((rawValue >> 16) & 0xFF),
66 (byte) ((rawValue >> 8) & 0xFF),
67 (byte) ((rawValue >> 0) & 0xFF) };
68 }
69 }
70 }
71 return bytesCache;
72 }
73
74 @Override
75 public int getLength() {
76 return MacAddrLen;
77 }
78
Andreas Wundsam40e14f72013-05-06 14:49:08 -070079 @Override
80 public String toString() {
81 return HexString.toHexString(rawValue, 6);
82 }
83
84 @Override
85 public int hashCode() {
86 final int prime = 31;
87 int result = 1;
88 result = prime * result + (int) (rawValue ^ (rawValue >>> 32));
89 return result;
90 }
91
92 @Override
93 public boolean equals(final Object obj) {
94 if (this == obj)
95 return true;
96 if (obj == null)
97 return false;
98 if (getClass() != obj.getClass())
99 return false;
100 MacAddress other = (MacAddress) obj;
101 if (rawValue != other.rawValue)
102 return false;
103 return true;
104 }
105
106 public long getLong() {
107 return rawValue;
108 }
109
Yotam Harchold7b84202013-07-26 16:08:10 -0700110 public void write6Bytes(ChannelBuffer c) {
111 c.writeInt((int) (this.rawValue >> 16));
112 c.writeShort((int) this.rawValue & 0xFFFF);
Yotam Harchol161a5d52013-07-25 17:17:48 -0700113 }
114
Yotam Harchold7b84202013-07-26 16:08:10 -0700115 public static MacAddress read6Bytes(ChannelBuffer c) throws OFParseError {
116 long raw = c.readUnsignedInt() << 16 | c.readUnsignedShort();
117 return MacAddress.of(raw);
118 }
Yotam Harchol161a5d52013-07-25 17:17:48 -0700119
120
121
Andreas Wundsam40e14f72013-05-06 14:49:08 -0700122}