| /* |
| * Copyright 2016-present Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.onosproject.ospf.protocol.ospfpacket.types; |
| |
| import com.google.common.base.MoreObjects; |
| import com.google.common.primitives.Bytes; |
| import org.jboss.netty.buffer.ChannelBuffer; |
| import org.onlab.packet.Ip4Address; |
| import org.onosproject.ospf.exceptions.OspfErrorType; |
| import org.onosproject.ospf.exceptions.OspfParseException; |
| import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader; |
| import org.onosproject.ospf.controller.OspfPacketType; |
| import org.onosproject.ospf.protocol.util.OspfUtil; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Defines an OSPF Hello Message, and the fields and methods to access it. |
| * Hello packets are OSPF packet type 1. These packets are sent |
| * periodically on all interfaces in order to establish and |
| * maintain neighbor relationships. |
| */ |
| public class HelloPacket extends OspfPacketHeader { |
| |
| /* |
| 0 1 2 3 |
| 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 |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Version # | 1 | Packet length | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Router ID | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Area ID | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Checksum | AuType | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Authentication | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Authentication | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Network Mask | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | HelloInterval | Options | Rtr Pri | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | RouterDeadInterval | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Designated Router | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Backup Designated Router | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | Neighbor | |
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| | ... | |
| |
| Hello Message Format |
| REFERENCE : RFC 2328 |
| */ |
| |
| private static final Logger log = LoggerFactory.getLogger(HelloPacket.class); |
| private Ip4Address networkMask; |
| private int options; |
| private int helloInterval; |
| private int routerPriority; |
| private int routerDeadInterval; |
| private Ip4Address bdr; |
| private Ip4Address dr; |
| private List<Ip4Address> neighborAddress = new ArrayList<>(); |
| |
| /** |
| * Creates an instance of Hello packet. |
| */ |
| public HelloPacket() { |
| } |
| |
| /** |
| * Creates an instance of Hello packet. |
| * |
| * @param ospfHeader OSPF header instance. |
| */ |
| public HelloPacket(OspfPacketHeader ospfHeader) { |
| populateHeader(ospfHeader); |
| } |
| |
| /** |
| * Gets network mask. |
| * |
| * @return network mask |
| */ |
| public Ip4Address networkMask() { |
| return networkMask; |
| } |
| |
| /** |
| * Sets network mask. |
| * |
| * @param networkMask network mask |
| */ |
| public void setNetworkMask(Ip4Address networkMask) { |
| this.networkMask = networkMask; |
| } |
| |
| /** |
| * Gets BDRs IP address. |
| * |
| * @return BDRs IP address |
| */ |
| public Ip4Address bdr() { |
| return bdr; |
| } |
| |
| /** |
| * Sets BDR IP address. |
| * |
| * @param bdr BDR IP address |
| */ |
| public void setBdr(Ip4Address bdr) { |
| this.bdr = bdr; |
| } |
| |
| /** |
| * Gets DRs IP address. |
| * |
| * @return DRs IP address |
| */ |
| public Ip4Address dr() { |
| return dr; |
| } |
| |
| /** |
| * Sets DRs IP address. |
| * |
| * @param dr DRs IP address |
| */ |
| public void setDr(Ip4Address dr) { |
| this.dr = dr; |
| } |
| |
| /** |
| * Adds neighbor to map. |
| * |
| * @param neighborID neighbors id |
| */ |
| public void addNeighbor(Ip4Address neighborID) { |
| if (!neighborAddress.contains(neighborID)) { |
| neighborAddress.add(neighborID); |
| } |
| } |
| |
| /** |
| * Checks neighbor is in map or not. |
| * |
| * @param neighborID neighbors id |
| * @return true if neighbor exist else false |
| */ |
| public boolean containsNeighbour(Ip4Address neighborID) { |
| return (neighborAddress.contains(neighborID)) ? true : false; |
| } |
| |
| /** |
| * Gets options value. |
| * |
| * @return options value |
| */ |
| public int options() { |
| return options; |
| } |
| |
| /** |
| * Sets options value. |
| * |
| * @param options options value |
| */ |
| public void setOptions(int options) { |
| this.options = options; |
| } |
| |
| /** |
| * Gets router priority. |
| * |
| * @return routerPriority |
| */ |
| public int routerPriority() { |
| return routerPriority; |
| } |
| |
| /** |
| * Sets router priority. |
| * |
| * @param routerPriority router priority |
| */ |
| public void setRouterPriority(int routerPriority) { |
| this.routerPriority = routerPriority; |
| } |
| |
| /** |
| * Gets hello interval. |
| * |
| * @return hello Interval |
| */ |
| public int helloInterval() { |
| return helloInterval; |
| } |
| |
| /** |
| * Sets hello Interval. |
| * |
| * @param helloInterval hello Interval |
| */ |
| public void setHelloInterval(int helloInterval) { |
| this.helloInterval = helloInterval; |
| } |
| |
| /** |
| * Gets router dead interval. |
| * |
| * @return router dead interval |
| */ |
| public int routerDeadInterval() { |
| return routerDeadInterval; |
| } |
| |
| /** |
| * Sets router dead interval. |
| * |
| * @param routerDeadInterval router dead interval |
| */ |
| public void setRouterDeadInterval(int routerDeadInterval) { |
| this.routerDeadInterval = routerDeadInterval; |
| } |
| |
| @Override |
| public OspfPacketType ospfMessageType() { |
| return OspfPacketType.HELLO; |
| } |
| |
| @Override |
| public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException { |
| |
| try { |
| byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES]; |
| channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES); |
| this.setNetworkMask(Ip4Address.valueOf(tempByteArray)); |
| this.setHelloInterval(channelBuffer.readShort()); |
| this.setOptions(channelBuffer.readByte()); |
| this.setRouterPriority(channelBuffer.readByte() & 0xff); |
| this.setRouterDeadInterval(channelBuffer.readInt()); |
| tempByteArray = new byte[OspfUtil.FOUR_BYTES]; |
| channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES); |
| this.setDr(Ip4Address.valueOf(tempByteArray)); |
| tempByteArray = new byte[OspfUtil.FOUR_BYTES]; |
| channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES); |
| this.setBdr(Ip4Address.valueOf(tempByteArray)); |
| |
| while (channelBuffer.readableBytes() > 0) { |
| tempByteArray = new byte[OspfUtil.FOUR_BYTES]; |
| channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES); |
| this.addNeighbor(Ip4Address.valueOf(tempByteArray)); |
| } |
| |
| } catch (Exception e) { |
| log.debug("Error::HelloPacket:: {}", e.getMessage()); |
| throw new OspfParseException(OspfErrorType.MESSAGE_HEADER_ERROR, OspfErrorType.BAD_MESSAGE_LENGTH); |
| } |
| } |
| |
| @Override |
| public byte[] asBytes() { |
| |
| byte[] helloMessage = null; |
| byte[] helloHeader = getHelloHeaderAsByteArray(); |
| byte[] helloBody = getHelloBodyAsByteArray(); |
| helloMessage = Bytes.concat(helloHeader, helloBody); |
| |
| log.debug("HelloPacket::asBytes::Hello asBytes:: {}", helloMessage); |
| |
| return helloMessage; |
| } |
| |
| /** |
| * Gets hello header as byte array. |
| * |
| * @return hello header |
| */ |
| public byte[] getHelloHeaderAsByteArray() { |
| List<Byte> headerLst = new ArrayList<>(); |
| try { |
| headerLst.add((byte) this.ospfVersion()); |
| headerLst.add((byte) this.ospfType()); |
| headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.ospfPacLength()))); |
| headerLst.addAll(Bytes.asList(this.routerId().toOctets())); |
| headerLst.addAll(Bytes.asList(this.areaId().toOctets())); |
| headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.checksum()))); |
| headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.authType()))); |
| //Authentication is 0 always. Total 8 bytes consist of zero |
| byte[] auth = new byte[OspfUtil.EIGHT_BYTES]; |
| headerLst.addAll(Bytes.asList(auth)); |
| } catch (Exception e) { |
| log.debug("Error::getHelloHeaderAsByteArray {}", e.getMessage()); |
| return Bytes.toArray(headerLst); |
| } |
| |
| return Bytes.toArray(headerLst); |
| } |
| |
| /** |
| * Gets hello body as byte array. |
| * |
| * @return hello body as byte array |
| */ |
| public byte[] getHelloBodyAsByteArray() { |
| List<Byte> bodyLst = new ArrayList<>(); |
| |
| try { |
| bodyLst.addAll(Bytes.asList(this.networkMask().toOctets())); |
| bodyLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.helloInterval()))); |
| bodyLst.add((byte) this.options()); |
| bodyLst.add((byte) this.routerPriority()); |
| bodyLst.addAll(Bytes.asList(OspfUtil.convertToFourBytes(this.routerDeadInterval()))); |
| bodyLst.addAll(Bytes.asList(this.dr().toOctets())); |
| bodyLst.addAll(Bytes.asList(this.bdr().toOctets())); |
| for (Ip4Address neighbour : neighborAddress) { |
| bodyLst.addAll(Bytes.asList(neighbour.toOctets())); |
| } |
| |
| } catch (Exception e) { |
| log.debug("Error::getHelloBodyAsByteArray {}", e.getMessage()); |
| return Bytes.toArray(bodyLst); |
| } |
| |
| return Bytes.toArray(bodyLst); |
| } |
| |
| @Override |
| public String toString() { |
| return MoreObjects.toStringHelper(getClass()) |
| .omitNullValues() |
| .add("networkMask", networkMask) |
| .add("options", options) |
| .add("helloInterval", helloInterval) |
| .add("routerPriority", routerPriority) |
| .add("routerDeadInterval", routerDeadInterval) |
| .add("bdr", bdr) |
| .add("dr", dr) |
| .toString(); |
| } |
| } |