blob: d454f1a9ece90d38d69ef2638427d6152455d1d6 [file] [log] [blame]
/*
* Copyright 2015 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.onlab.packet.pim;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Deserializer;
import org.onlab.packet.IPacket;
import org.onlab.packet.IpAddress;
import java.nio.ByteBuffer;
import java.util.Random;
import static org.onlab.packet.PacketUtils.checkInput;
public class PIMHello extends BasePacket {
private IpAddress nbrIpAddress;
private int holdtime = 105;
private int genid = 0;
private int priority = 1;
private boolean priorityPresent = false;
public static final int MINIMUM_OPTION_LEN_BYTES = 4;
/**
* PIM Option types.
*/
public enum Option {
HOLDTIME (1, 2),
PRUNEDELAY(2, 4),
PRIORITY (19, 4),
GENID (20, 4),
ADDRLIST (24, 0);
private final int optType;
private final int optLen;
Option(int ot, int ol) {
this.optType = ot;
this.optLen = ol;
}
public int optType() {
return this.optType;
}
public int optLen() {
return this.optLen;
}
}
/**
* Add the holdtime to the packet.
*
* @param holdtime the holdtime in seconds
*/
public void addHoldtime(int holdtime) {
this.holdtime = holdtime;
}
/**
* Add the hello priority.
*
* @param priority default is 1, the higher the better
*/
public void addPriority(int priority) {
this.priority = priority;
this.priorityPresent = true;
}
/**
* Add a Gen ID.
*
* @param genid a random generated number, changes only after reset.
*/
public void addGenId(int genid) {
if (genid == 0) {
this.addGenId();
} else {
this.genid = genid;
}
}
/**
* Add the genid. Let this function figure out the number.
*/
public void addGenId() {
Random rand = new Random();
this.genid = rand.nextInt();
}
/**
* Sets all payloads parent packet if applicable, then serializes this
* packet and all payloads.
*
* @return a byte[] containing this packet and payloads
*/
@Override
public byte[] serialize() {
// TODO: Figure out a better way to calculate buffer size
int size = Option.PRIORITY.optLen() + 4 +
Option.GENID.optLen() + 4 +
Option.HOLDTIME.optLen() + 4;
byte[] data = new byte[size]; // Come up with something better
ByteBuffer bb = ByteBuffer.wrap(data);
// Add the priority
bb.putShort((short) Option.PRIORITY.optType);
bb.putShort((short) Option.PRIORITY.optLen);
bb.putInt(this.priority);
// Add the genid
bb.putShort((short) Option.GENID.optType);
bb.putShort((short) Option.GENID.optLen);
bb.putInt(this.genid);
// Add the holdtime
bb.putShort((short) Option.HOLDTIME.optType);
bb.putShort((short) Option.HOLDTIME.optLen);
bb.putShort((short) this.holdtime);
return data;
}
/**
* XXX: This is deprecated, DO NOT USE, use the deserializer() function instead.
*/
// @Override
public IPacket deserialize(final byte[] data, final int offset,
final int length) {
//
return null;
}
/**
* Deserialize this hello message.
*
* @return a deserialized hello message.
*/
public static Deserializer<PIMHello> deserializer() {
return (data, offset, length) -> {
checkInput(data, offset, length, MINIMUM_OPTION_LEN_BYTES);
final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
PIMHello hello = new PIMHello();
while (bb.hasRemaining()) {
int optType = bb.getShort();
int optLen = bb.getShort();
// Check that we have enough buffer for the next option.
checkInput(data, bb.position(), bb.limit() - bb.position(), optLen);
if (optType == Option.GENID.optType) {
hello.addGenId(bb.getInt());
} else if (optType == Option.PRIORITY.optType) {
hello.addPriority(bb.getInt());
} else if (optType == Option.HOLDTIME.optType) {
hello.addHoldtime((int) bb.getShort());
}
}
return hello;
};
}
}