blob: ab7e8852fe328707925fe408b21415a68d2ec5bb [file] [log] [blame]
Manicdb26412016-02-16 19:44:34 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
Manicdb26412016-02-16 19:44:34 +05303 *
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.onosproject.ospf.protocol.ospfpacket.types;
17
18import com.google.common.base.MoreObjects;
19import com.google.common.primitives.Bytes;
20import org.jboss.netty.buffer.ChannelBuffer;
21import org.onlab.packet.Ip4Address;
22import org.onosproject.ospf.exceptions.OspfErrorType;
23import org.onosproject.ospf.exceptions.OspfParseException;
24import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
sunishvkf7c56552016-07-18 16:02:39 +053025import org.onosproject.ospf.controller.OspfPacketType;
Manicdb26412016-02-16 19:44:34 +053026import org.onosproject.ospf.protocol.util.OspfUtil;
27import org.slf4j.Logger;
28import org.slf4j.LoggerFactory;
29
30import java.util.ArrayList;
31import java.util.List;
32
33/**
34 * Defines an OSPF Hello Message, and the fields and methods to access it.
35 * Hello packets are OSPF packet type 1. These packets are sent
36 * periodically on all interfaces in order to establish and
37 * maintain neighbor relationships.
38 */
39public class HelloPacket extends OspfPacketHeader {
40
41 /*
42 0 1 2 3
43 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
44 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 | Version # | 1 | Packet length |
46 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 | Router ID |
48 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 | Area ID |
50 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51 | Checksum | AuType |
52 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53 | Authentication |
54 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 | Authentication |
56 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 | Network Mask |
58 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 | HelloInterval | Options | Rtr Pri |
60 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61 | RouterDeadInterval |
62 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63 | Designated Router |
64 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65 | Backup Designated Router |
66 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67 | Neighbor |
68 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69 | ... |
70
71 Hello Message Format
72 REFERENCE : RFC 2328
73 */
74
75 private static final Logger log = LoggerFactory.getLogger(HelloPacket.class);
76 private Ip4Address networkMask;
77 private int options;
78 private int helloInterval;
79 private int routerPriority;
80 private int routerDeadInterval;
81 private Ip4Address bdr;
82 private Ip4Address dr;
83 private List<Ip4Address> neighborAddress = new ArrayList<>();
84
85 /**
86 * Creates an instance of Hello packet.
87 */
88 public HelloPacket() {
89 }
90
91 /**
92 * Creates an instance of Hello packet.
93 *
94 * @param ospfHeader OSPF header instance.
95 */
96 public HelloPacket(OspfPacketHeader ospfHeader) {
97 populateHeader(ospfHeader);
98 }
99
100 /**
101 * Gets network mask.
102 *
103 * @return network mask
104 */
105 public Ip4Address networkMask() {
106 return networkMask;
107 }
108
109 /**
110 * Sets network mask.
111 *
112 * @param networkMask network mask
113 */
114 public void setNetworkMask(Ip4Address networkMask) {
115 this.networkMask = networkMask;
116 }
117
118 /**
119 * Gets BDRs IP address.
120 *
121 * @return BDRs IP address
122 */
123 public Ip4Address bdr() {
124 return bdr;
125 }
126
127 /**
128 * Sets BDR IP address.
129 *
130 * @param bdr BDR IP address
131 */
132 public void setBdr(Ip4Address bdr) {
133 this.bdr = bdr;
134 }
135
136 /**
137 * Gets DRs IP address.
138 *
139 * @return DRs IP address
140 */
141 public Ip4Address dr() {
142 return dr;
143 }
144
145 /**
146 * Sets DRs IP address.
147 *
148 * @param dr DRs IP address
149 */
150 public void setDr(Ip4Address dr) {
151 this.dr = dr;
152 }
153
154 /**
155 * Adds neighbor to map.
156 *
157 * @param neighborID neighbors id
158 */
159 public void addNeighbor(Ip4Address neighborID) {
160 if (!neighborAddress.contains(neighborID)) {
161 neighborAddress.add(neighborID);
162 }
163 }
164
165 /**
166 * Checks neighbor is in map or not.
167 *
168 * @param neighborID neighbors id
169 * @return true if neighbor exist else false
170 */
171 public boolean containsNeighbour(Ip4Address neighborID) {
172 return (neighborAddress.contains(neighborID)) ? true : false;
173 }
174
175 /**
176 * Gets options value.
177 *
178 * @return options value
179 */
180 public int options() {
181 return options;
182 }
183
184 /**
185 * Sets options value.
186 *
187 * @param options options value
188 */
189 public void setOptions(int options) {
190 this.options = options;
191 }
192
193 /**
194 * Gets router priority.
195 *
196 * @return routerPriority
197 */
198 public int routerPriority() {
199 return routerPriority;
200 }
201
202 /**
203 * Sets router priority.
204 *
205 * @param routerPriority router priority
206 */
207 public void setRouterPriority(int routerPriority) {
208 this.routerPriority = routerPriority;
209 }
210
211 /**
212 * Gets hello interval.
213 *
214 * @return hello Interval
215 */
216 public int helloInterval() {
217 return helloInterval;
218 }
219
220 /**
221 * Sets hello Interval.
222 *
223 * @param helloInterval hello Interval
224 */
225 public void setHelloInterval(int helloInterval) {
226 this.helloInterval = helloInterval;
227 }
228
229 /**
230 * Gets router dead interval.
231 *
232 * @return router dead interval
233 */
234 public int routerDeadInterval() {
235 return routerDeadInterval;
236 }
237
238 /**
239 * Sets router dead interval.
240 *
241 * @param routerDeadInterval router dead interval
242 */
243 public void setRouterDeadInterval(int routerDeadInterval) {
244 this.routerDeadInterval = routerDeadInterval;
245 }
246
247 @Override
248 public OspfPacketType ospfMessageType() {
249 return OspfPacketType.HELLO;
250 }
251
252 @Override
253 public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException {
254
255 try {
256 byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
257 channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
258 this.setNetworkMask(Ip4Address.valueOf(tempByteArray));
259 this.setHelloInterval(channelBuffer.readShort());
260 this.setOptions(channelBuffer.readByte());
261 this.setRouterPriority(channelBuffer.readByte() & 0xff);
262 this.setRouterDeadInterval(channelBuffer.readInt());
263 tempByteArray = new byte[OspfUtil.FOUR_BYTES];
264 channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
265 this.setDr(Ip4Address.valueOf(tempByteArray));
266 tempByteArray = new byte[OspfUtil.FOUR_BYTES];
267 channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
268 this.setBdr(Ip4Address.valueOf(tempByteArray));
269
270 while (channelBuffer.readableBytes() > 0) {
271 tempByteArray = new byte[OspfUtil.FOUR_BYTES];
272 channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
273 this.addNeighbor(Ip4Address.valueOf(tempByteArray));
274 }
275
276 } catch (Exception e) {
277 log.debug("Error::HelloPacket:: {}", e.getMessage());
278 throw new OspfParseException(OspfErrorType.MESSAGE_HEADER_ERROR, OspfErrorType.BAD_MESSAGE_LENGTH);
279 }
280 }
281
282 @Override
283 public byte[] asBytes() {
284
285 byte[] helloMessage = null;
286 byte[] helloHeader = getHelloHeaderAsByteArray();
287 byte[] helloBody = getHelloBodyAsByteArray();
288 helloMessage = Bytes.concat(helloHeader, helloBody);
289
290 log.debug("HelloPacket::asBytes::Hello asBytes:: {}", helloMessage);
291
292 return helloMessage;
293 }
294
295 /**
296 * Gets hello header as byte array.
297 *
298 * @return hello header
299 */
300 public byte[] getHelloHeaderAsByteArray() {
301 List<Byte> headerLst = new ArrayList<>();
302 try {
303 headerLst.add((byte) this.ospfVersion());
304 headerLst.add((byte) this.ospfType());
305 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.ospfPacLength())));
306 headerLst.addAll(Bytes.asList(this.routerId().toOctets()));
307 headerLst.addAll(Bytes.asList(this.areaId().toOctets()));
308 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.checksum())));
309 headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.authType())));
310 //Authentication is 0 always. Total 8 bytes consist of zero
311 byte[] auth = new byte[OspfUtil.EIGHT_BYTES];
312 headerLst.addAll(Bytes.asList(auth));
313 } catch (Exception e) {
314 log.debug("Error::getHelloHeaderAsByteArray {}", e.getMessage());
315 return Bytes.toArray(headerLst);
316 }
317
318 return Bytes.toArray(headerLst);
319 }
320
321 /**
322 * Gets hello body as byte array.
323 *
324 * @return hello body as byte array
325 */
326 public byte[] getHelloBodyAsByteArray() {
327 List<Byte> bodyLst = new ArrayList<>();
328
329 try {
330 bodyLst.addAll(Bytes.asList(this.networkMask().toOctets()));
331 bodyLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.helloInterval())));
332 bodyLst.add((byte) this.options());
333 bodyLst.add((byte) this.routerPriority());
334 bodyLst.addAll(Bytes.asList(OspfUtil.convertToFourBytes(this.routerDeadInterval())));
335 bodyLst.addAll(Bytes.asList(this.dr().toOctets()));
336 bodyLst.addAll(Bytes.asList(this.bdr().toOctets()));
337 for (Ip4Address neighbour : neighborAddress) {
338 bodyLst.addAll(Bytes.asList(neighbour.toOctets()));
339 }
340
341 } catch (Exception e) {
342 log.debug("Error::getHelloBodyAsByteArray {}", e.getMessage());
343 return Bytes.toArray(bodyLst);
344 }
345
346 return Bytes.toArray(bodyLst);
347 }
348
349 @Override
350 public String toString() {
351 return MoreObjects.toStringHelper(getClass())
352 .omitNullValues()
353 .add("networkMask", networkMask)
354 .add("options", options)
355 .add("helloInterval", helloInterval)
356 .add("routerPriority", routerPriority)
357 .add("routerDeadInterval", routerDeadInterval)
358 .add("bdr", bdr)
359 .add("dr", dr)
360 .toString();
361 }
362}