blob: 9ad3fdbde706e3545d5885f573edce288e308abc [file] [log] [blame]
Rusty Eddy80f12522015-09-03 22:42:02 +00001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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
26import static org.onlab.packet.PacketUtils.checkInput;
27
28public class PIMHello extends BasePacket {
29
30 private IpAddress nbrIpAddress;
Rusty Eddy80f12522015-09-03 22:42:02 +000031 private boolean priorityPresent = false;
32
Rusty Eddy9cbc0952015-09-14 22:29:07 +000033 private Map<Short, PIMHelloOption> options = new HashMap<>();
Rusty Eddy80f12522015-09-03 22:42:02 +000034
35 /**
Rusty Eddy9cbc0952015-09-14 22:29:07 +000036 * Create a PIM Hello packet with the most common hello options and default
37 * values. The values of any options can be easily changed by modifying the value of
38 * the option with the desired change.
Rusty Eddy80f12522015-09-03 22:42:02 +000039 */
Rusty Eddy9cbc0952015-09-14 22:29:07 +000040 public void createDefaultOptions() {
41 options.put(PIMHelloOption.OPT_HOLDTIME, new PIMHelloOption(PIMHelloOption.OPT_HOLDTIME));
42 options.put(PIMHelloOption.OPT_PRIORITY, new PIMHelloOption(PIMHelloOption.OPT_PRIORITY));
43 options.put(PIMHelloOption.OPT_GENID, new PIMHelloOption(PIMHelloOption.OPT_GENID));
Rusty Eddy80f12522015-09-03 22:42:02 +000044 }
45
46 /**
Rusty Eddy9cbc0952015-09-14 22:29:07 +000047 * Add a PIM Hello option to this hello message. Note
Rusty Eddy80f12522015-09-03 22:42:02 +000048 *
Rusty Eddy9cbc0952015-09-14 22:29:07 +000049 * @param opt the PIM Hello option we are adding
Rusty Eddy80f12522015-09-03 22:42:02 +000050 */
Rusty Eddy9cbc0952015-09-14 22:29:07 +000051 public void addOption(PIMHelloOption opt) {
52 this.options.put(opt.getOptType(), opt);
Rusty Eddy80f12522015-09-03 22:42:02 +000053 }
54
Rusty Eddy9cbc0952015-09-14 22:29:07 +000055 public Map<Short, PIMHelloOption> getOptions() {
56 return this.options;
Rusty Eddy80f12522015-09-03 22:42:02 +000057 }
58
59 /**
60 * Sets all payloads parent packet if applicable, then serializes this
61 * packet and all payloads.
62 *
63 * @return a byte[] containing this packet and payloads
64 */
65 @Override
66 public byte[] serialize() {
Rusty Eddy9cbc0952015-09-14 22:29:07 +000067 int totalLen = 0;
Rusty Eddy80f12522015-09-03 22:42:02 +000068
Rusty Eddy80f12522015-09-03 22:42:02 +000069
Rusty Eddy9cbc0952015-09-14 22:29:07 +000070 // Since we are likely to only have 3-4 options, go head and walk the
71 // hashmap twice, once to calculate the space needed to allocate a
72 // buffer, the second time serialize the options into the buffer. This
73 // saves us from allocating an over sized buffer the re-allocating and
74 // copying.
75 for (Short optType : options.keySet()) {
76 PIMHelloOption opt = options.get(optType);
77 totalLen += PIMHelloOption.MINIMUM_OPTION_LEN_BYTES + opt.getOptLength();
78 }
79
80 byte[] data = new byte[totalLen];
Rusty Eddy80f12522015-09-03 22:42:02 +000081 ByteBuffer bb = ByteBuffer.wrap(data);
82
Rusty Eddy9cbc0952015-09-14 22:29:07 +000083 // Now serialize the data.
84 for (Short optType : options.keySet()) {
85 PIMHelloOption opt = options.get(optType);
86 bb.put(opt.serialize());
87 }
Rusty Eddy80f12522015-09-03 22:42:02 +000088 return data;
89 }
90
91 /**
92 * XXX: This is deprecated, DO NOT USE, use the deserializer() function instead.
93 */
Rusty Eddy80f12522015-09-03 22:42:02 +000094 public IPacket deserialize(final byte[] data, final int offset,
95 final int length) {
Rusty Eddy9cbc0952015-09-14 22:29:07 +000096 // TODO: throw an expection?
Rusty Eddy80f12522015-09-03 22:42:02 +000097 return null;
98 }
99
100 /**
101 * Deserialize this hello message.
102 *
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000103 * @return a deserialized hello message
Rusty Eddy80f12522015-09-03 22:42:02 +0000104 */
105 public static Deserializer<PIMHello> deserializer() {
106 return (data, offset, length) -> {
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000107 checkInput(data, offset, length, PIMHelloOption.MINIMUM_OPTION_LEN_BYTES);
Rusty Eddy80f12522015-09-03 22:42:02 +0000108 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
109
110 PIMHello hello = new PIMHello();
111 while (bb.hasRemaining()) {
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000112 PIMHelloOption opt = PIMHelloOption.deserialize(bb);
113 hello.addOption(opt);
Rusty Eddy80f12522015-09-03 22:42:02 +0000114 }
Rusty Eddy80f12522015-09-03 22:42:02 +0000115 return hello;
116 };
117 }
118}