blob: 5a641700fb172c5176643994f7d32a943b5f8010 [file] [log] [blame]
Rusty Eddy9cbc0952015-09-14 22:29:07 +00001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present Open Networking Laboratory
Rusty Eddy9cbc0952015-09-14 22:29:07 +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.DeserializationException;
19
20import java.nio.ByteBuffer;
21import java.text.MessageFormat;
kdarapu229bc452017-04-23 00:29:12 +053022import java.util.Arrays;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000023
24import static org.onlab.packet.PacketUtils.checkBufferLength;
25import static org.onlab.packet.PacketUtils.checkInput;
26
Jonathan Hart5af5f142016-01-28 18:45:27 -080027/**
28 * PIM HELLO option.
29 */
Rusty Eddy9cbc0952015-09-14 22:29:07 +000030public class PIMHelloOption {
31
Jonathan Hart5af5f142016-01-28 18:45:27 -080032 /*
Rusty Eddy9cbc0952015-09-14 22:29:07 +000033 * PIM Option types.
34 */
35 public static final short OPT_HOLDTIME = 1;
Jonathan Hart5af5f142016-01-28 18:45:27 -080036 public static final short HOLDTIME_LENGTH = 2;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000037 public static final short DEFAULT_HOLDTIME = 105;
Jonathan Hart5af5f142016-01-28 18:45:27 -080038
39 public static final short OPT_PRUNEDELAY = 2;
40 public static final short PRUNEDELAY_LENGTH = 4;
41 public static final short DEFAULT_PRUNEDELAY = 500; // 500 ms
42 public static final short DEFAULT_OVERRIDEINTERVAL = 2500; // 2500 ms
43
44 public static final short OPT_PRIORITY = 19;
45 public static final short PRIORITY_LENGTH = 4;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000046 public static final int DEFAULT_PRIORITY = 1;
Jonathan Hart5af5f142016-01-28 18:45:27 -080047
48 public static final short OPT_GENID = 20;
49 public static final short GENID_LENGTH = 4;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000050 public static final int DEFAULT_GENID = 0;
51
Jonathan Hart5af5f142016-01-28 18:45:27 -080052 public static final short OPT_ADDRLIST = 24;
53
Rusty Eddy9cbc0952015-09-14 22:29:07 +000054 public static final int MINIMUM_OPTION_LEN_BYTES = 4;
55
56 // Values for this particular hello option.
Jonathan Hart5af5f142016-01-28 18:45:27 -080057 private short optType = 0;
58 private short optLength = 0;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000059 private byte[] optValue;
60
Jonathan Hart5af5f142016-01-28 18:45:27 -080061 /**
62 * Constructs a new hello option with no fields set.
63 */
Rusty Eddy9cbc0952015-09-14 22:29:07 +000064 public PIMHelloOption() {
65 }
66
67 /**
68 * Set a PIM Hello option by type. The length and default value of the
69 * type will be auto filled in by default.
70 *
71 * @param type hello option type
72 */
73 public PIMHelloOption(short type) {
74 this.optType = type;
75 switch (type) {
76 case OPT_HOLDTIME:
Jonathan Hart5af5f142016-01-28 18:45:27 -080077 this.optLength = HOLDTIME_LENGTH;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000078 this.optValue = new byte[optLength];
79 ByteBuffer.wrap(this.optValue).putShort(PIMHelloOption.DEFAULT_HOLDTIME);
80 break;
81
82 case OPT_PRUNEDELAY:
Jonathan Hart5af5f142016-01-28 18:45:27 -080083 this.optLength = PRUNEDELAY_LENGTH;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000084 this.optValue = new byte[this.optLength];
85 ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRUNEDELAY);
86 break;
87
88 case OPT_PRIORITY:
Jonathan Hart5af5f142016-01-28 18:45:27 -080089 this.optLength = PRIORITY_LENGTH;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000090 this.optValue = new byte[this.optLength];
91 ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRIORITY);
92 break;
93
94 case OPT_GENID:
Jonathan Hart5af5f142016-01-28 18:45:27 -080095 this.optLength = GENID_LENGTH;
Rusty Eddy9cbc0952015-09-14 22:29:07 +000096 this.optValue = new byte[this.optLength];
97 ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_GENID);
98 break;
99
100 case OPT_ADDRLIST:
101 this.optLength = 0; // We don't know what the length will be yet.
102 this.optValue = null;
Ray Milkey4fd3ceb2015-12-10 14:43:08 -0800103 break;
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000104
105 default:
106 //log.error("Unkown option type: " + type + "\n" );
107 return;
108 }
109 }
110
111 public void setOptType(short type) {
112 this.optType = type;
113 }
114
115 public short getOptType() {
116 return this.optType;
117 }
118
119 public void setOptLength(short len) {
120 this.optLength = len;
121 }
122
123 public short getOptLength() {
124 return this.optLength;
125 }
126
Jonathan Hart5af5f142016-01-28 18:45:27 -0800127 public void setValue(ByteBuffer bb) {
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000128 this.optValue = new byte[this.optLength];
129 bb.get(this.optValue, 0, this.optLength);
130 }
131
Jonathan Hart5af5f142016-01-28 18:45:27 -0800132 public void setValue(byte[] value) {
133 this.optValue = value;
134 }
135
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000136 public byte[] getValue() {
137 return this.optValue;
138 }
139
Jonathan Hart5af5f142016-01-28 18:45:27 -0800140 /**
141 * Creates a new PIM Hello option with the specified values.
142 *
143 * @param type hello option type
144 * @param length option length
145 * @param value option value
146 * @return new PIM Hello option
147 */
148 public static PIMHelloOption create(short type, short length, ByteBuffer value) {
149 PIMHelloOption option = new PIMHelloOption();
150 option.setOptType(type);
151 option.setOptLength(length);
152 value.rewind();
153 option.setValue(value);
154 return option;
155 }
156
157 /**
158 * Creates a new priority option.
159 *
160 * @param priority priority
161 * @return priority option
162 */
163 public static PIMHelloOption createPriority(int priority) {
164 return create(OPT_PRIORITY, PRIORITY_LENGTH,
165 ByteBuffer.allocate(PRIORITY_LENGTH).putInt(priority));
166 }
167
168 /**
169 * Creates a new hold time option.
170 *
171 * @param holdTime hold time
172 * @return hold time option
173 */
174 public static PIMHelloOption createHoldTime(short holdTime) {
175 return create(OPT_HOLDTIME, HOLDTIME_LENGTH,
176 ByteBuffer.allocate(HOLDTIME_LENGTH).putShort(holdTime));
177 }
178
179 /**
180 * Creates a new generation ID option with a particular generation ID.
181 *
182 * @param genId generation ID value
183 * @return generation ID option
184 */
185 public static PIMHelloOption createGenID(int genId) {
186 return create(OPT_GENID, GENID_LENGTH,
187 ByteBuffer.allocate(GENID_LENGTH).putInt(genId));
188 }
189
190 /**
191 * Creates a new LAN Prune Delay option.
192 *
193 * @param propagationDelay prune delay
194 * @param overrideInterval override interval
195 * @return prune delay option
196 */
197 public static PIMHelloOption createPruneDelay(short propagationDelay, short overrideInterval) {
198 return create(OPT_PRUNEDELAY, PRUNEDELAY_LENGTH,
199 ByteBuffer.allocate(PRUNEDELAY_LENGTH)
200 .putShort(propagationDelay)
201 .putShort(overrideInterval));
202 }
203
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000204 public static PIMHelloOption deserialize(ByteBuffer bb) throws DeserializationException {
Jonathan Hart5af5f142016-01-28 18:45:27 -0800205 checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), MINIMUM_OPTION_LEN_BYTES);
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000206
207 PIMHelloOption opt = new PIMHelloOption();
208 opt.setOptType(bb.getShort());
209 opt.setOptLength(bb.getShort());
210
211 checkBufferLength(bb.limit(), bb.position(), opt.getOptLength());
212 opt.setValue(bb);
213
214 return opt;
215 }
216
Jian Li68c4fc42016-01-11 16:07:03 -0800217 public byte[] serialize() {
Jonathan Hart5af5f142016-01-28 18:45:27 -0800218 int len = MINIMUM_OPTION_LEN_BYTES + this.optLength;
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000219 ByteBuffer bb = ByteBuffer.allocate(len);
220 bb.putShort(this.optType);
221 bb.putShort(this.optLength);
222 bb.put(this.optValue);
223 return bb.array();
224 }
225
226 public String toString() {
227 return MessageFormat.format("Type: {0}, len: {1} value: {2}", this.optType, this.optLength,
kdarapu229bc452017-04-23 00:29:12 +0530228 Arrays.toString(this.optValue));
Rusty Eddy9cbc0952015-09-14 22:29:07 +0000229 }
230
231}