| /* |
| * Copyright 2015-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.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.HashMap; |
| import java.util.Map; |
| |
| import static com.google.common.base.MoreObjects.toStringHelper; |
| import static org.onlab.packet.PacketUtils.checkInput; |
| |
| public class PIMHello extends BasePacket { |
| |
| private IpAddress nbrIpAddress; |
| private boolean priorityPresent = false; |
| |
| private Map<Short, PIMHelloOption> options = new HashMap<>(); |
| |
| /** |
| * Create a PIM Hello packet with the most common hello options and default |
| * values. The values of any options can be easily changed by modifying the value of |
| * the option with the desired change. |
| */ |
| public void createDefaultOptions() { |
| options.put(PIMHelloOption.OPT_HOLDTIME, new PIMHelloOption(PIMHelloOption.OPT_HOLDTIME)); |
| options.put(PIMHelloOption.OPT_PRIORITY, new PIMHelloOption(PIMHelloOption.OPT_PRIORITY)); |
| options.put(PIMHelloOption.OPT_GENID, new PIMHelloOption(PIMHelloOption.OPT_GENID)); |
| } |
| |
| /** |
| * Add a PIM Hello option to this hello message. Note |
| * |
| * @param opt the PIM Hello option we are adding |
| */ |
| public void addOption(PIMHelloOption opt) { |
| this.options.put(opt.getOptType(), opt); |
| } |
| |
| public Map<Short, PIMHelloOption> getOptions() { |
| return this.options; |
| } |
| |
| /** |
| * 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() { |
| int totalLen = 0; |
| |
| |
| // Since we are likely to only have 3-4 options, go head and walk the |
| // hashmap twice, once to calculate the space needed to allocate a |
| // buffer, the second time serialize the options into the buffer. This |
| // saves us from allocating an over sized buffer the re-allocating and |
| // copying. |
| for (Short optType : options.keySet()) { |
| PIMHelloOption opt = options.get(optType); |
| totalLen += PIMHelloOption.MINIMUM_OPTION_LEN_BYTES + opt.getOptLength(); |
| } |
| |
| byte[] data = new byte[totalLen]; |
| ByteBuffer bb = ByteBuffer.wrap(data); |
| |
| // Now serialize the data. |
| for (Short optType : options.keySet()) { |
| PIMHelloOption opt = options.get(optType); |
| bb.put(opt.serialize()); |
| } |
| return data; |
| } |
| |
| /** |
| * XXX: This is deprecated, DO NOT USE, use the deserializer() function instead. |
| */ |
| public IPacket deserialize(final byte[] data, final int offset, |
| final int length) { |
| // TODO: throw an expection? |
| return null; |
| } |
| |
| /** |
| * Deserialize this hello message. |
| * |
| * @return a deserialized hello message |
| */ |
| public static Deserializer<PIMHello> deserializer() { |
| return (data, offset, length) -> { |
| checkInput(data, offset, length, PIMHelloOption.MINIMUM_OPTION_LEN_BYTES); |
| final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); |
| |
| PIMHello hello = new PIMHello(); |
| while (bb.hasRemaining()) { |
| PIMHelloOption opt = PIMHelloOption.deserialize(bb); |
| hello.addOption(opt); |
| } |
| return hello; |
| }; |
| } |
| |
| @Override |
| public String toString() { |
| return toStringHelper(getClass()) |
| .add("nbrIpAddress", nbrIpAddress.toString()) |
| .add("priorityPresent", Boolean.toString(priorityPresent)) |
| .toString(); |
| // TODO: need to handle options |
| } |
| } |