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