blob: 1c2f928a01d9ef00d3b91df2d480c1a3813a6fe0 [file] [log] [blame]
Charles M.C. Chanea5aa472015-01-03 13:40:39 +08001/*
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -08002 * Copyright 2014-2015 Open Networking Laboratory
Charles M.C. Chanea5aa472015-01-03 13:40:39 +08003 *
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 */
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080016package org.onlab.packet.ndp;
17
18import org.onlab.packet.BasePacket;
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080019import org.onlab.packet.IPacket;
20
21import java.nio.ByteBuffer;
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -080022import java.util.List;
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080023
24/**
25 * Implements ICMPv6 Router Advertisement packet format. (RFC 4861)
26 */
27public class RouterAdvertisement extends BasePacket {
28 public static final byte HEADER_LENGTH = 12; // bytes
29
30 protected byte currentHopLimit;
31 protected byte mFlag;
32 protected byte oFlag;
33 protected short routerLifetime;
34 protected int reachableTime;
35 protected int retransmitTimer;
36
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -080037 private final NeighborDiscoveryOptions options =
38 new NeighborDiscoveryOptions();
39
Charles M.C. Chanea5aa472015-01-03 13:40:39 +080040 /**
41 * Gets current hop limit.
42 *
43 * @return the current hop limit
44 */
45 public byte getCurrentHopLimit() {
46 return this.currentHopLimit;
47 }
48
49 /**
50 * Sets current hop limit.
51 *
52 * @param currentHopLimit the current hop limit to set
53 * @return this
54 */
55 public RouterAdvertisement setCurrentHopLimit(final byte currentHopLimit) {
56 this.currentHopLimit = currentHopLimit;
57 return this;
58 }
59
60 /**
61 * Gets managed address configuration flag.
62 *
63 * @return the managed address configuration flag
64 */
65 public byte getMFlag() {
66 return this.mFlag;
67 }
68
69 /**
70 * Sets managed address configuration flag.
71 *
72 * @param mFlag the managed address configuration flag to set
73 * @return this
74 */
75 public RouterAdvertisement setMFlag(final byte mFlag) {
76 this.mFlag = mFlag;
77 return this;
78 }
79
80 /**
81 * Gets other configuration flag.
82 *
83 * @return the other configuration flag
84 */
85 public byte getOFlag() {
86 return this.oFlag;
87 }
88
89 /**
90 * Sets other configuration flag.
91 *
92 * @param oFlag the other configuration flag to set
93 * @return this
94 */
95 public RouterAdvertisement setOFlag(final byte oFlag) {
96 this.oFlag = oFlag;
97 return this;
98 }
99
100 /**
101 * Gets router lifetime.
102 *
103 * @return the router lifetime
104 */
105 public short getRouterLifetime() {
106 return this.routerLifetime;
107 }
108
109 /**
110 * Sets router lifetime.
111 *
112 * @param routerLifetime the router lifetime to set
113 * @return this
114 */
115 public RouterAdvertisement setRouterLifetime(final short routerLifetime) {
116 this.routerLifetime = routerLifetime;
117 return this;
118 }
119
120 /**
121 * Gets reachable time.
122 *
123 * @return the reachable time
124 */
125 public int getReachableTime() {
126 return this.reachableTime;
127 }
128
129 /**
130 * Sets reachable time.
131 *
132 * @param reachableTime the reachable time to set
133 * @return this
134 */
135 public RouterAdvertisement setReachableTime(final int reachableTime) {
136 this.reachableTime = reachableTime;
137 return this;
138 }
139
140 /**
141 * Gets retransmission timer.
142 *
143 * @return the retransmission timer
144 */
145 public int getRetransmitTimer() {
146 return this.retransmitTimer;
147 }
148
149 /**
150 * Sets retransmission timer.
151 *
152 * @param retransmitTimer the retransmission timer to set
153 * @return this
154 */
155 public RouterAdvertisement setRetransmitTimer(final int retransmitTimer) {
156 this.retransmitTimer = retransmitTimer;
157 return this;
158 }
159
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -0800160 /**
161 * Gets the Neighbor Discovery Protocol packet options.
162 *
163 * @return the Neighbor Discovery Protocol packet options
164 */
165 public List<NeighborDiscoveryOptions.Option> getOptions() {
166 return this.options.options();
167 }
168
169 /**
170 * Adds a Neighbor Discovery Protocol packet option.
171 *
172 * @param type the option type
173 * @param data the option data
174 * @return this
175 */
176 public RouterAdvertisement addOption(final byte type, final byte[] data) {
177 this.options.addOption(type, data);
178 return this;
179 }
180
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800181 @Override
182 public byte[] serialize() {
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -0800183 byte[] optionsData = null;
184 if (this.options.hasOptions()) {
185 optionsData = this.options.serialize();
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800186 }
187
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -0800188 int optionsLength = 0;
189 if (optionsData != null) {
190 optionsLength = optionsData.length;
Charles M.C. Chan5c0b4762015-01-10 18:38:37 +0800191 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800192
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -0800193 final byte[] data = new byte[HEADER_LENGTH + optionsLength];
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800194 final ByteBuffer bb = ByteBuffer.wrap(data);
195
196 bb.put(this.currentHopLimit);
197 bb.put((byte) ((this.mFlag & 0x1) << 7 | (this.oFlag & 0x1) << 6));
198 bb.putShort(routerLifetime);
199 bb.putInt(reachableTime);
200 bb.putInt(retransmitTimer);
201
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -0800202 if (optionsData != null) {
203 bb.put(optionsData);
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800204 }
205
206 return data;
207 }
208
209 @Override
210 public IPacket deserialize(byte[] data, int offset, int length) {
211 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
212 int bscratch;
213
214 this.currentHopLimit = bb.get();
215 bscratch = bb.get();
216 this.mFlag = (byte) ((bscratch >> 7) & 0x1);
217 this.oFlag = (byte) ((bscratch >> 6) & 0x1);
218 this.routerLifetime = bb.getShort();
219 this.reachableTime = bb.getInt();
220 this.retransmitTimer = bb.getInt();
221
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -0800222 this.options.deserialize(data, bb.position(),
223 bb.limit() - bb.position());
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800224
225 return this;
226 }
227
228 /*
229 * (non-Javadoc)
230 *
231 * @see java.lang.Object#hashCode()
232 */
233 @Override
234 public int hashCode() {
235 final int prime = 5807;
236 int result = super.hashCode();
237 result = prime * result + this.currentHopLimit;
238 result = prime * result + this.mFlag;
239 result = prime * result + this.oFlag;
240 result = prime * result + this.routerLifetime;
241 result = prime * result + this.reachableTime;
242 result = prime * result + this.retransmitTimer;
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -0800243 result = prime * result + this.options.hashCode();
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800244 return result;
245 }
246
247 /*
248 * (non-Javadoc)
249 *
250 * @see java.lang.Object#equals(java.lang.Object)
251 */
252 @Override
253 public boolean equals(final Object obj) {
254 if (this == obj) {
255 return true;
256 }
257 if (!super.equals(obj)) {
258 return false;
259 }
260 if (!(obj instanceof RouterAdvertisement)) {
261 return false;
262 }
263 final RouterAdvertisement other = (RouterAdvertisement) obj;
264 if (this.currentHopLimit != other.currentHopLimit) {
265 return false;
266 }
267 if (this.mFlag != other.mFlag) {
268 return false;
269 }
270 if (this.oFlag != other.oFlag) {
271 return false;
272 }
273 if (this.routerLifetime != other.routerLifetime) {
274 return false;
275 }
276 if (this.reachableTime != other.reachableTime) {
277 return false;
278 }
279 if (this.retransmitTimer != other.retransmitTimer) {
280 return false;
281 }
Pavlin Radoslavova2626ef2015-02-18 18:33:25 -0800282 if (!this.options.equals(other.options)) {
283 return false;
284 }
Charles M.C. Chanea5aa472015-01-03 13:40:39 +0800285 return true;
286 }
287}