blob: 82776e25ac69b93c5d0674c853dc2d69016999fa [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/**
25 * Implements ICMPv6 Neighbor Solicitation packet format.
26 */
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 /**
36 *
37 * @return true if router flag is set
38 */
39 public byte getRouterFlag() {
40 return this.routerFlag;
41 }
42
43 /**
44 * @param routerFlag
45 * the routerFlag to set
46 * @return this
47 */
48 public NeighborAdvertisement setRouterFlag(final byte routerFlag) {
49 this.routerFlag = routerFlag;
50 return this;
51 }
52
53 /**
54 *
55 * @return true if solicited flag is set
56 */
57 public byte getSolicitedFlag() {
58 return this.solicitedFlag;
59 }
60
61 /**
62 * @param solicitedFlag
63 * the routerFlag to set
64 * @return this
65 */
66 public NeighborAdvertisement setSolicitedFlag(final byte solicitedFlag) {
67 this.solicitedFlag = solicitedFlag;
68 return this;
69 }
70
71 /**
72 *
73 * @return true if override flag is set
74 */
75 public byte getOverrideFlag() {
76 return this.overrideFlag;
77 }
78
79 /**
80 * @param overrideFlag
81 * the routerFlag to set
82 * @return this
83 */
84 public NeighborAdvertisement setOverrideFlag(final byte overrideFlag) {
85 this.overrideFlag = overrideFlag;
86 return this;
87 }
88
89 /**
90 *
91 * @return the target IPv6 address
92 */
93 public byte[] getTargetAddress() {
94 return this.targetAddress;
95 }
96
97 /**
98 * @param targetAddress
99 * the sourceAddress to set
100 * @return this
101 */
102 public NeighborAdvertisement setTargetAddress(final byte[] targetAddress) {
103 this.targetAddress = Arrays.copyOfRange(targetAddress, 0, Ip6Address.BYTE_LENGTH);
104 return this;
105 }
106
107 /**
108 * Serializes the packet. Will compute and set the following fields if they
109 * are set to specific values at the time serialize is called: -routerFlag : 0
110 * -solicitedFlag : 0 -overrideFlag : 0
111 */
112 @Override
113 public byte[] serialize() {
114 byte[] payloadData = null;
115 if (this.payload != null) {
116 this.payload.setParent(this);
117 payloadData = this.payload.serialize();
118 }
119
120 int payloadLength = payloadData == null ? 0 : (short) payloadData.length;
121
122 final byte[] data = new byte[HEADER_LENGTH + payloadLength];
123 final ByteBuffer bb = ByteBuffer.wrap(data);
124
125 bb.putInt((this.routerFlag & 0x1) << 31 | (this.solicitedFlag & 0x1) << 30 | (this.overrideFlag & 0x1) << 29);
126 bb.put(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
127 if (payloadData != null) {
128 bb.put(payloadData);
129 }
130
131 return data;
132 }
133
134 @Override
135 public IPacket deserialize(byte[] data, int offset, int length) {
136 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
137 int iscratch;
138
139 iscratch = bb.getInt();
140 this.routerFlag = (byte) (iscratch >> 31 & 0x1);
141 this.solicitedFlag = (byte) (iscratch >> 30 & 0x1);
142 this.overrideFlag = (byte) (iscratch >> 29 & 0x1);
143 bb.get(this.targetAddress, 0, Ip6Address.BYTE_LENGTH);
144
145 this.payload = new Data();
146 this.payload = this.payload.deserialize(data, bb.position(), bb.limit()
147 - bb.position());
148 this.payload.setParent(this);
149
150 return this;
151 }
152
153 /*
154 * (non-Javadoc)
155 *
156 * @see java.lang.Object#hashCode()
157 */
158 @Override
159 public int hashCode() {
160 final int prime = 5807;
161 int result = super.hashCode();
162 ByteBuffer bb;
163 result = prime * result + this.routerFlag;
164 result = prime * result + this.solicitedFlag;
165 result = prime * result + this.overrideFlag;
166 bb = ByteBuffer.wrap(this.targetAddress);
167 for (int i = 0; i < 4; i++) {
168 result = prime * result + bb.getInt();
169 }
170 return result;
171 }
172
173 /*
174 * (non-Javadoc)
175 *
176 * @see java.lang.Object#equals(java.lang.Object)
177 */
178 @Override
179 public boolean equals(final Object obj) {
180 if (this == obj) {
181 return true;
182 }
183 if (!super.equals(obj)) {
184 return false;
185 }
186 if (!(obj instanceof NeighborAdvertisement)) {
187 return false;
188 }
189 final NeighborAdvertisement other = (NeighborAdvertisement) obj;
190 if (this.routerFlag != other.routerFlag) {
191 return false;
192 }
193 if (this.solicitedFlag != other.solicitedFlag) {
194 return false;
195 }
196 if (this.overrideFlag != other.overrideFlag) {
197 return false;
198 }
199 if (!Arrays.equals(this.targetAddress, other.targetAddress)) {
200 return false;
201 }
202 return true;
203 }
204}