blob: 0c2d676b17eafb9a3b6ef41ae184e23930b25f98 [file] [log] [blame]
Rusty Eddy80f12522015-09-03 22:42:02 +00001/*
2 * Copyright 2015 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.pim;
17
18import org.onlab.packet.DeserializationException;
19import org.onlab.packet.Ip4Address;
20import org.onlab.packet.IpAddress;
21import org.onlab.packet.Ip6Address;
22
23import java.nio.ByteBuffer;
24
25import static org.onlab.packet.PacketUtils.checkInput;
26
27public class PIMAddrUnicast {
28 private byte family;
29 private byte encType;
30 IpAddress addr;
31
32 public static final int ENC_UNICAST_IPV4_BYTE_LENGTH = 2 + Ip4Address.BYTE_LENGTH;
33 public static final int ENC_UNICAST_IPV6_BYTE_LENGTH = 2 + Ip6Address.BYTE_LENGTH;
34
35 /**
36 * PIM Encoded Source Address.
37 */
38 public PIMAddrUnicast() {
39 this.family = 4;
40 this.encType = 0;
41 }
42
43 /**
44 * PIM Encoded Source Address.
45 *
46 * @param addr IPv4 or IPv6
47 */
48 public PIMAddrUnicast(String addr) {
49 this.addr = IpAddress.valueOf(addr);
50 if (this.addr.isIp4()) {
51 this.family = 4;
52 } else {
53 this.family = 6;
54 }
55 this.encType = 0;
56 }
57
58 /**
59 * PIM Encoded Source Address.
60 *
61 * @param addr IPv4 or IPv6
62 */
63 public void setAddr(IpAddress addr) {
64 this.addr = addr;
65 if (this.addr.isIp4()) {
66 this.family = 4;
67 } else {
68 this.family = 6;
69 }
70 }
71
72 /**
73 * Get the address of this encoded address.
74 *
75 * @return source address
76 */
77 public IpAddress getAddr() {
78 return this.addr;
79 }
80
81 /**
82 * Get the IP family of this address: 4 or 6.
83 *
84 * @return the IP address family
85 */
86 public int getFamily() {
87 return this.family;
88 }
89
90 /**
91 * The size in bytes of a serialized address.
92 *
93 * @return the number of bytes when serialized
94 */
95 public int getByteSize() {
96 int size = 2;
97 if (addr != null) {
98 size += addr.isIp4() ? 4 : 16;
99 } else {
100 size += 4;
101 }
102 return size;
103 }
104
105 public byte[] serialize() {
106 int len = getByteSize();
107
108 final byte[] data = new byte[len];
109 final ByteBuffer bb = ByteBuffer.wrap(data);
110
111 bb.put(family);
112 bb.put(encType);
113 bb.put(addr.toOctets());
114 return data;
115 }
116
117 public PIMAddrUnicast deserialize(ByteBuffer bb) throws DeserializationException {
118
119 // Assume IPv4 for check length until we read the encoded family.
120 checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_UNICAST_IPV4_BYTE_LENGTH);
121 this.family = bb.get();
122
123 // If we have IPv6 we need to ensure we have adequate buffer space.
124 if (this.family != 4 && this.family != 6) {
125 throw new DeserializationException("Invalid address family: " + this.family);
126 } else if (this.family == 6) {
127 // Subtract -1 from ENC_UNICAST_IPv6 BYTE_LENGTH because we read one byte for family previously.
128 checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_UNICAST_IPV6_BYTE_LENGTH - 1);
129 }
130
131 this.encType = bb.get();
132 if (this.family == 4) {
133 this.addr = IpAddress.valueOf(bb.getInt());
134 } else if (this.family == 6) {
135 this.addr = Ip6Address.valueOf(bb.array(), 2);
136 }
137 return this;
138 }
139
140 /*
141 * (non-Javadoc)
142 *
143 * @see java.lang.Object#hashCode()
144 */
145 @Override
146 public int hashCode() {
147 final int prime = 2521;
148 int result = super.hashCode();
149 result = prime * result + this.family;
150 result = prime * result + this.encType;
151 result = prime * result + this.addr.hashCode();
152 return result;
153 }
154
155 /*
156 * (non-Javadoc)
157 *
158 * @see java.lang.Object#hashCode()
159 */
160 @Override
161 public boolean equals(final Object obj) {
162 if (this == obj) {
163 return true;
164 }
165 if (!(obj instanceof PIMAddrUnicast)) {
166 return false;
167 }
168 final PIMAddrUnicast other = (PIMAddrUnicast) obj;
169 if (this.family != this.family) {
170 return false;
171 }
172
173 if (this.encType != other.encType) {
174 return false;
175 }
176
177 if (!this.addr.equals(other.addr)) {
178 return false;
179 }
180 return true;
181 }
182}