blob: 4b8688b50fc3cbcddd8d62bdf47b72345e702408 [file] [log] [blame]
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +08001/*
2 * Copyright 2014 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 */
16
17
18
19package org.onlab.packet;
20
21import java.nio.ByteBuffer;
22import java.util.Arrays;
23
24/**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080025 * Implements ICMPv6 Neighbor Solicitation packet format. (RFC 4861)
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080026 */
27public class NeighborAdvertisement extends BasePacket {
28 public static final byte HEADER_LENGTH = 20; // bytes
29
30 protected byte routerFlag;
31 protected byte solicitedFlag;
32 protected byte overrideFlag;
33 protected byte[] targetAddress = new byte[Ip6Address.BYTE_LENGTH];
34
35 /**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080036 * Gets router flag.
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080037 *
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080038 * @return the router flag
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080039 */
40 public byte getRouterFlag() {
41 return this.routerFlag;
42 }
43
44 /**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080045 * Sets router flag.
46 *
47 * @param routerFlag the router flag to set
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080048 * @return this
49 */
50 public NeighborAdvertisement setRouterFlag(final byte routerFlag) {
51 this.routerFlag = routerFlag;
52 return this;
53 }
54
55 /**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080056 * Gets solicited flag.
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080057 *
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080058 * @return the solicited flag
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080059 */
60 public byte getSolicitedFlag() {
61 return this.solicitedFlag;
62 }
63
64 /**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080065 * Sets solicited flag.
66 *
67 * @param solicitedFlag the solicited flag to set
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080068 * @return this
69 */
70 public NeighborAdvertisement setSolicitedFlag(final byte solicitedFlag) {
71 this.solicitedFlag = solicitedFlag;
72 return this;
73 }
74
75 /**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080076 * Gets override flag.
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080077 *
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080078 * @return the override flag
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080079 */
80 public byte getOverrideFlag() {
81 return this.overrideFlag;
82 }
83
84 /**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080085 * Sets override flag.
86 *
87 * @param overrideFlag the override flag to set
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080088 * @return this
89 */
90 public NeighborAdvertisement setOverrideFlag(final byte overrideFlag) {
91 this.overrideFlag = overrideFlag;
92 return this;
93 }
94
95 /**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +080096 * Gets target address.
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +080097 *
98 * @return the target IPv6 address
99 */
100 public byte[] getTargetAddress() {
101 return this.targetAddress;
102 }
103
104 /**
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800105 * Sets target address.
106 *
107 * @param targetAddress the target IPv6 address to set
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +0800108 * @return this
109 */
110 public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) {
111 this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
112 return this;
113 }
114
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +0800115 @Override
116 public byte[] serialize() {
117 byte[] payloadData = null;
118 if (this.payload != null) {
119 this.payload.setParent(this);
120 payloadData = this.payload.serialize();
121 }
122
123 int payloadLength = payloadData == null ? 0 : (short) payloadData.length;
124
125 final byte[] data = new byte[HEADER_LENGTH + payloadLength];
126 final ByteBuffer bb = ByteBuffer.wrap(data);
127
128 bb.putInt((this.routerFlag & 0x1) << 31 | (this.solicitedFlag & 0x1) << 30 | (this.overrideFlag & 0x1) << 29);
129 bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
130 if (payloadData != null) {
131 bb.put(payloadData);
132 }
133
134 return data;
135 }
136
137 @Override
138 public IPacket deserialize(byte[] data, int offset, int length) {
139 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
140 int iscratch;
141
142 iscratch = bb.getInt();
143 this.routerFlag = (byte) (iscratch >> 31 & 0x1);
144 this.solicitedFlag = (byte) (iscratch >> 30 & 0x1);
145 this.overrideFlag = (byte) (iscratch >> 29 & 0x1);
146 bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
147
148 this.payload = new Data();
149 this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
150 - bb.position());
151 this.payload.setParent(this);
152
153 return this;
154 }
155
156 /*
Charles M.C. Chan7fee36a2014-12-31 00:19:59 +0800157 * (non-Javadoc)
158 *
159 * @see java.lang.Object#hashCode()
160 */
Charles M.C. Chan93b7fb02014-12-28 03:59:36 +0800161 @Override
162 public int hashCode() {
163 final int prime = 5807;
164 int result = super.hashCode();
165 ByteBuffer bb;
166 result = prime * result + this.routerFlag;
167 result = prime * result + this.solicitedFlag;
168 result = prime * result + this.overrideFlag;
169 bb = ByteBuffer.wrap(this.targetAddress);
170 for (int i = 0; i < 4; i++) {
171 result = prime * result + bb.getInt();
172 }
173 return result;
174 }
175
176 /*
177 * (non-Javadoc)
178 *
179 * @see java.lang.Object#equals(java.lang.Object)
180 */
181 @Override
182 public boolean equals(final Object obj) {
183 if (this == obj) {
184 return true;
185 }
186 if (!super.equals(obj)) {
187 return false;
188 }
189 if (!(obj instanceof NeighborAdvertisement)) {
190 return false;
191 }
192 final NeighborAdvertisement other = (NeighborAdvertisement) obj;
193 if (this.routerFlag != other.routerFlag) {
194 return false;
195 }
196 if (this.solicitedFlag != other.solicitedFlag) {
197 return false;
198 }
199 if (this.overrideFlag != other.overrideFlag) {
200 return false;
201 }
202 if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
203 return false;
204 }
205 return true;
206 }
207}