blob: 2372e1aabc4295d7e6f85f7f88b9b730e7ddbe90 [file] [log] [blame]
Rusty Eddy9cbc0952015-09-14 22:29:07 +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.DeserializationException;
19
20import java.nio.ByteBuffer;
21import java.text.MessageFormat;
22
23import static org.onlab.packet.PacketUtils.checkBufferLength;
24import static org.onlab.packet.PacketUtils.checkInput;
25
Jonathan Hart5af5f142016-01-28 18:45:27 -080026/**
27 * PIM HELLO option.
28 */
Rusty Eddy9cbc0952015-09-14 22:29:07 +000029public class PIMHelloOption {
30
Jonathan Hart5af5f142016-01-28 18:45:27 -080031 /*
Rusty Eddy9cbc0952015-09-14 22:29:07 +000032 * PIM Option types.
33 */
34 public static final short OPT_HOLDTIME = 1;
Jonathan Hart5af5f142016-01-28 18:45:27 -080035 public static final short HOLDTIME_LENGTH = 2;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000036 public static final short DEFAULT_HOLDTIME = 105;
Jonathan Hart5af5f142016-01-28 18:45:27 -080037
38 public static final short OPT_PRUNEDELAY = 2;
39 public static final short PRUNEDELAY_LENGTH = 4;
40 public static final short DEFAULT_PRUNEDELAY = 500; // 500 ms
41 public static final short DEFAULT_OVERRIDEINTERVAL = 2500; // 2500 ms
42
43 public static final short OPT_PRIORITY = 19;
44 public static final short PRIORITY_LENGTH = 4;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000045 public static final int DEFAULT_PRIORITY = 1;
Jonathan Hart5af5f142016-01-28 18:45:27 -080046
47 public static final short OPT_GENID = 20;
48 public static final short GENID_LENGTH = 4;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000049 public static final int DEFAULT_GENID = 0;
50
Jonathan Hart5af5f142016-01-28 18:45:27 -080051 public static final short OPT_ADDRLIST = 24;
52
Rusty Eddy9cbc0952015-09-14 22:29:07 +000053 public static final int MINIMUM_OPTION_LEN_BYTES = 4;
54
55 // Values for this particular hello option.
Jonathan Hart5af5f142016-01-28 18:45:27 -080056 private short optType = 0;
57 private short optLength = 0;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000058 private byte[] optValue;
59
Jonathan Hart5af5f142016-01-28 18:45:27 -080060 /**
61 * Constructs a new hello option with no fields set.
62 */
Rusty Eddy9cbc0952015-09-14 22:29:07 +000063 public PIMHelloOption() {
64 }
65
66 /**
67 * Set a PIM Hello option by type. The length and default value of the
68 * type will be auto filled in by default.
69 *
70 * @param type hello option type
71 */
72 public PIMHelloOption(short type) {
73 this.optType = type;
74 switch (type) {
75 case OPT_HOLDTIME:
Jonathan Hart5af5f142016-01-28 18:45:27 -080076 this.optLength = HOLDTIME_LENGTH;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000077 this.optValue = new byte[optLength];
78 ByteBuffer.wrap(this.optValue).putShort(PIMHelloOption.DEFAULT_HOLDTIME);
79 break;
80
81 case OPT_PRUNEDELAY:
Jonathan Hart5af5f142016-01-28 18:45:27 -080082 this.optLength = PRUNEDELAY_LENGTH;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000083 this.optValue = new byte[this.optLength];
84 ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRUNEDELAY);
85 break;
86
87 case OPT_PRIORITY:
Jonathan Hart5af5f142016-01-28 18:45:27 -080088 this.optLength = PRIORITY_LENGTH;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000089 this.optValue = new byte[this.optLength];
90 ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRIORITY);
91 break;
92
93 case OPT_GENID:
Jonathan Hart5af5f142016-01-28 18:45:27 -080094 this.optLength = GENID_LENGTH;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000095 this.optValue = new byte[this.optLength];
96 ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_GENID);
97 break;
98
99 case OPT_ADDRLIST:
100 this.optLength = 0; // We don't know what the length will be yet.
101 this.optValue = null;
Ray Milkey4fd3ceb2015-12-10 14:43:08 -0800102 break;
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000103
104 default:
105 //log.error("Unkown option type: " + type + "\n" );
106 return;
107 }
108 }
109
110 public void setOptType(short type) {
111 this.optType = type;
112 }
113
114 public short getOptType() {
115 return this.optType;
116 }
117
118 public void setOptLength(short len) {
119 this.optLength = len;
120 }
121
122 public short getOptLength() {
123 return this.optLength;
124 }
125
Jonathan Hart5af5f142016-01-28 18:45:27 -0800126 public void setValue(ByteBuffer bb) {
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000127 this.optValue = new byte[this.optLength];
128 bb.get(this.optValue, 0, this.optLength);
129 }
130
Jonathan Hart5af5f142016-01-28 18:45:27 -0800131 public void setValue(byte[] value) {
132 this.optValue = value;
133 }
134
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000135 public byte[] getValue() {
136 return this.optValue;
137 }
138
Jonathan Hart5af5f142016-01-28 18:45:27 -0800139 /**
140 * Creates a new PIM Hello option with the specified values.
141 *
142 * @param type hello option type
143 * @param length option length
144 * @param value option value
145 * @return new PIM Hello option
146 */
147 public static PIMHelloOption create(short type, short length, ByteBuffer value) {
148 PIMHelloOption option = new PIMHelloOption();
149 option.setOptType(type);
150 option.setOptLength(length);
151 value.rewind();
152 option.setValue(value);
153 return option;
154 }
155
156 /**
157 * Creates a new priority option.
158 *
159 * @param priority priority
160 * @return priority option
161 */
162 public static PIMHelloOption createPriority(int priority) {
163 return create(OPT_PRIORITY, PRIORITY_LENGTH,
164 ByteBuffer.allocate(PRIORITY_LENGTH).putInt(priority));
165 }
166
167 /**
168 * Creates a new hold time option.
169 *
170 * @param holdTime hold time
171 * @return hold time option
172 */
173 public static PIMHelloOption createHoldTime(short holdTime) {
174 return create(OPT_HOLDTIME, HOLDTIME_LENGTH,
175 ByteBuffer.allocate(HOLDTIME_LENGTH).putShort(holdTime));
176 }
177
178 /**
179 * Creates a new generation ID option with a particular generation ID.
180 *
181 * @param genId generation ID value
182 * @return generation ID option
183 */
184 public static PIMHelloOption createGenID(int genId) {
185 return create(OPT_GENID, GENID_LENGTH,
186 ByteBuffer.allocate(GENID_LENGTH).putInt(genId));
187 }
188
189 /**
190 * Creates a new LAN Prune Delay option.
191 *
192 * @param propagationDelay prune delay
193 * @param overrideInterval override interval
194 * @return prune delay option
195 */
196 public static PIMHelloOption createPruneDelay(short propagationDelay, short overrideInterval) {
197 return create(OPT_PRUNEDELAY, PRUNEDELAY_LENGTH,
198 ByteBuffer.allocate(PRUNEDELAY_LENGTH)
199 .putShort(propagationDelay)
200 .putShort(overrideInterval));
201 }
202
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000203 public static PIMHelloOption deserialize(ByteBuffer bb) throws DeserializationException {
Jonathan Hart5af5f142016-01-28 18:45:27 -0800204 checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), MINIMUM_OPTION_LEN_BYTES);
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000205
206 PIMHelloOption opt = new PIMHelloOption();
207 opt.setOptType(bb.getShort());
208 opt.setOptLength(bb.getShort());
209
210 checkBufferLength(bb.limit(), bb.position(), opt.getOptLength());
211 opt.setValue(bb);
212
213 return opt;
214 }
215
Jian Li68c4fc42016-01-11 16:07:03 -0800216 public byte[] serialize() {
Jonathan Hart5af5f142016-01-28 18:45:27 -0800217 int len = MINIMUM_OPTION_LEN_BYTES + this.optLength;
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000218 ByteBuffer bb = ByteBuffer.allocate(len);
219 bb.putShort(this.optType);
220 bb.putShort(this.optLength);
221 bb.put(this.optValue);
222 return bb.array();
223 }
224
225 public String toString() {
226 return MessageFormat.format("Type: {0}, len: {1} value: {2}", this.optType, this.optLength,
227 (this.optValue == null) ? "null" : this.optValue.toString());
228 }
229
230}