blob: 630edacd1cabeae72beb850f942e5a9321b8efd8 [file] [log] [blame]
/*
* 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.OspfParseException;
import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
import org.onosproject.ospf.protocol.ospfpacket.subtype.LsRequestPacket;
import org.onosproject.ospf.protocol.util.OspfPacketType;
import org.onosproject.ospf.protocol.util.OspfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
/**
* Representation of an OSPF Link State Request packet.
* Link State Request packets are OSPF packet type 3. After exchanging
* database description packets with a neighboring router, a router may
* find that parts of its link-state database are out-of-date. The
* Link State Request packet is used to request the pieces of the
* neighbor's database that are more up-to-date.
*/
public class LsRequest 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 # | 3 | Packet length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Router ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Area ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | AuType |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Authentication |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Authentication |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| LS type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Link State ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Advertising Router |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ... |
LsRequest Message Format
REFERENCE : RFC 2328
*/
private static final Logger log = LoggerFactory.getLogger(LsRequest.class);
private List<LsRequestPacket> linkStateRequests = new ArrayList<>();
/**
* Creates an instance of link state request packet.
*/
public LsRequest() {
}
/**
* Creates an instance of link state request packet.
*
* @param ospfHeader OSPF header instance.
*/
public LsRequest(OspfPacketHeader ospfHeader) {
populateHeader(ospfHeader);
}
/**
* Adds link state request.
*
* @param lsRequestPacket ls request packet instance
*/
public void addLinkStateRequests(LsRequestPacket lsRequestPacket) {
if (!linkStateRequests.contains(lsRequestPacket)) {
linkStateRequests.add(lsRequestPacket);
}
}
/**
* Gets link state request packet instance.
*
* @return link state request packet instance
*/
public List<LsRequestPacket> getLinkStateRequests() {
return linkStateRequests;
}
@Override
public OspfPacketType ospfMessageType() {
return OspfPacketType.LSREQUEST;
}
@Override
public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException {
while (channelBuffer.readableBytes() >= OspfUtil.LSREQUEST_LENGTH) {
LsRequestPacket lsRequestPacket = new LsRequestPacket();
lsRequestPacket.setLsType(channelBuffer.readInt());
byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
lsRequestPacket.setLinkStateId(Ip4Address.valueOf(tempByteArray).toString());
tempByteArray = new byte[OspfUtil.FOUR_BYTES];
channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
lsRequestPacket.setOwnRouterId(Ip4Address.valueOf(tempByteArray).toString());
this.addLinkStateRequests(lsRequestPacket);
}
}
@Override
public byte[] asBytes() {
byte[] lsrMessage = null;
byte[] lsrHeader = getLsrHeaderAsByteArray();
byte[] lsrBody = getLsrBodyAsByteArray();
lsrMessage = Bytes.concat(lsrHeader, lsrBody);
return lsrMessage;
}
/**
* Gets LS request packet header as byte array.
*
* @return LS request packet header as byte array
*/
public byte[] getLsrHeaderAsByteArray() {
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::getLsrBodyAsByteArray {}", e.getMessage());
return Bytes.toArray(headerLst);
}
return Bytes.toArray(headerLst);
}
/**
* Gets LS request packet body as byte array.
*
* @return LS request packet body as byte array
*/
public byte[] getLsrBodyAsByteArray() {
List<Byte> bodyLst = new ArrayList<>();
try {
for (LsRequestPacket lsrPacket : linkStateRequests) {
bodyLst.addAll(Bytes.asList(OspfUtil.convertToFourBytes(lsrPacket.lsType())));
bodyLst.addAll(Bytes.asList(InetAddress.getByName(lsrPacket.linkStateId()).getAddress()));
bodyLst.addAll(Bytes.asList(InetAddress.getByName(lsrPacket.ownRouterId()).getAddress()));
}
} catch (Exception e) {
log.debug("Error::getLsrBodyAsByteArray {}", e.getMessage());
return Bytes.toArray(bodyLst);
}
return Bytes.toArray(bodyLst);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(getClass())
.omitNullValues()
.add("linkStateRequests", linkStateRequests)
.toString();
}
}