blob: 2f0c3692d9adf627c8d439db03ad01449a22bafd [file] [log] [blame]
Rusty Eddy80f12522015-09-03 22:42:02 +00001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Rusty Eddy80f12522015-09-03 22:42:02 +00003 *
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.onlab.packet.pim;
17
18import org.onlab.packet.BasePacket;
19import org.onlab.packet.Deserializer;
20import org.onlab.packet.IPacket;
21import org.onlab.packet.IpAddress;
Rusty Eddy80f12522015-09-03 22:42:02 +000022import java.nio.ByteBuffer;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000023import java.util.HashMap;
24import java.util.Map;
Rusty Eddy80f12522015-09-03 22:42:02 +000025
Jian Li5fc14292015-12-04 11:30:46 -080026import static com.google.common.base.MoreObjects.toStringHelper;
Rusty Eddy80f12522015-09-03 22:42:02 +000027import static org.onlab.packet.PacketUtils.checkInput;
28
29public class PIMHello extends BasePacket {
30
31 private IpAddress nbrIpAddress;
Rusty Eddy80f12522015-09-03 22:42:02 +000032 private boolean priorityPresent = false;
33
Rusty Eddy9cbc0952015-09-14 22:29:07 +000034 private Map<Short, PIMHelloOption> options = new HashMap<>();
Rusty Eddy80f12522015-09-03 22:42:02 +000035
36 /**
Rusty Eddy9cbc0952015-09-14 22:29:07 +000037 * Create a PIM Hello packet with the most common hello options and default
38 * values. The values of any options can be easily changed by modifying the value of
39 * the option with the desired change.
Rusty Eddy80f12522015-09-03 22:42:02 +000040 */
Rusty Eddy9cbc0952015-09-14 22:29:07 +000041 public void createDefaultOptions() {
42 options.put(PIMHelloOption.OPT_HOLDTIME, new PIMHelloOption(PIMHelloOption.OPT_HOLDTIME));
43 options.put(PIMHelloOption.OPT_PRIORITY, new PIMHelloOption(PIMHelloOption.OPT_PRIORITY));
44 options.put(PIMHelloOption.OPT_GENID, new PIMHelloOption(PIMHelloOption.OPT_GENID));
Rusty Eddy80f12522015-09-03 22:42:02 +000045 }
46
47 /**
Rusty Eddy9cbc0952015-09-14 22:29:07 +000048 * Add a PIM Hello option to this hello message. Note
Rusty Eddy80f12522015-09-03 22:42:02 +000049 *
Rusty Eddy9cbc0952015-09-14 22:29:07 +000050 * @param opt the PIM Hello option we are adding
Rusty Eddy80f12522015-09-03 22:42:02 +000051 */
Rusty Eddy9cbc0952015-09-14 22:29:07 +000052 public void addOption(PIMHelloOption opt) {
53 this.options.put(opt.getOptType(), opt);
Rusty Eddy80f12522015-09-03 22:42:02 +000054 }
55
Rusty Eddy9cbc0952015-09-14 22:29:07 +000056 public Map<Short, PIMHelloOption> getOptions() {
57 return this.options;
Rusty Eddy80f12522015-09-03 22:42:02 +000058 }
59
60 /**
61 * Sets all payloads parent packet if applicable, then serializes this
62 * packet and all payloads.
63 *
64 * @return a byte[] containing this packet and payloads
65 */
66 @Override
67 public byte[] serialize() {
Rusty Eddy9cbc0952015-09-14 22:29:07 +000068 int totalLen = 0;
Rusty Eddy80f12522015-09-03 22:42:02 +000069
Rusty Eddy80f12522015-09-03 22:42:02 +000070
Rusty Eddy9cbc0952015-09-14 22:29:07 +000071 // Since we are likely to only have 3-4 options, go head and walk the
72 // hashmap twice, once to calculate the space needed to allocate a
73 // buffer, the second time serialize the options into the buffer. This
74 // saves us from allocating an over sized buffer the re-allocating and
75 // copying.
76 for (Short optType : options.keySet()) {
77 PIMHelloOption opt = options.get(optType);
78 totalLen += PIMHelloOption.MINIMUM_OPTION_LEN_BYTES + opt.getOptLength();
79 }
80
81 byte[] data = new byte[totalLen];
Rusty Eddy80f12522015-09-03 22:42:02 +000082 ByteBuffer bb = ByteBuffer.wrap(data);
83
Rusty Eddy9cbc0952015-09-14 22:29:07 +000084 // Now serialize the data.
85 for (Short optType : options.keySet()) {
86 PIMHelloOption opt = options.get(optType);
87 bb.put(opt.serialize());
88 }
Rusty Eddy80f12522015-09-03 22:42:02 +000089 return data;
90 }
91
92 /**
93 * XXX: This is deprecated, DO NOT USE, use the deserializer() function instead.
94 */
Rusty Eddy80f12522015-09-03 22:42:02 +000095 public IPacket deserialize(final byte[] data, final int offset,
96 final int length) {
Rusty Eddy9cbc0952015-09-14 22:29:07 +000097 // TODO: throw an expection?
Rusty Eddy80f12522015-09-03 22:42:02 +000098 return null;
99 }
100
101 /**
102 * Deserialize this hello message.
103 *
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000104 * @return a deserialized hello message
Rusty Eddy80f12522015-09-03 22:42:02 +0000105 */
106 public static Deserializer<PIMHello> deserializer() {
107 return (data, offset, length) -> {
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000108 checkInput(data, offset, length, PIMHelloOption.MINIMUM_OPTION_LEN_BYTES);
Rusty Eddy80f12522015-09-03 22:42:02 +0000109 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
110
111 PIMHello hello = new PIMHello();
112 while (bb.hasRemaining()) {
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000113 PIMHelloOption opt = PIMHelloOption.deserialize(bb);
114 hello.addOption(opt);
Rusty Eddy80f12522015-09-03 22:42:02 +0000115 }
Rusty Eddy80f12522015-09-03 22:42:02 +0000116 return hello;
117 };
118 }
Jian Li5fc14292015-12-04 11:30:46 -0800119
120 @Override
121 public String toString() {
122 return toStringHelper(getClass())
123 .add("nbrIpAddress", nbrIpAddress.toString())
124 .add("priorityPresent", Boolean.toString(priorityPresent))
125 .toString();
126 // TODO: need to handle options
127 }
Rusty Eddy80f12522015-09-03 22:42:02 +0000128}