blob: ae9d7173933c26e2861f52cd27b30be583025ec9 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
alshabibc4901cd2014-09-05 16:50:40 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
alshabibc4901cd2014-09-05 16:50:40 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
alshabibc4901cd2014-09-05 16:50:40 -070016
17/**
18 *
19 */
20package org.onlab.packet;
21
22import java.nio.ByteBuffer;
Jonathan Hart2a655752015-04-07 16:46:33 -070023import java.util.LinkedList;
alshabibc4901cd2014-09-05 16:50:40 -070024import java.util.List;
25
Jonathan Hart2a655752015-04-07 16:46:33 -070026import static org.onlab.packet.PacketUtils.*;
27
alshabibc4901cd2014-09-05 16:50:40 -070028/**
alshabibc4901cd2014-09-05 16:50:40 -070029 *
30 */
31public class LLDP extends BasePacket {
Jonathan Hart2a655752015-04-07 16:46:33 -070032 public static final byte CHASSIS_TLV_TYPE = 1;
33 public static final short CHASSIS_TLV_SIZE = 7;
34 public static final byte CHASSIS_TLV_SUBTYPE = 4;
35
36 public static final byte PORT_TLV_TYPE = 2;
37 public static final short PORT_TLV_SIZE = 5;
38 public static final byte PORT_TLV_SUBTYPE = 2;
39
40 public static final byte TTL_TLV_TYPE = 3;
41 public static final short TTL_TLV_SIZE = 2;
42
alshabibc4901cd2014-09-05 16:50:40 -070043 protected LLDPTLV chassisId;
44 protected LLDPTLV portId;
45 protected LLDPTLV ttl;
46 protected List<LLDPTLV> optionalTLVList;
47 protected short ethType;
48
49 public LLDP() {
Jonathan Hart2a655752015-04-07 16:46:33 -070050 this.optionalTLVList = new LinkedList<>();
alshabibc4901cd2014-09-05 16:50:40 -070051 this.ethType = Ethernet.TYPE_LLDP;
52 }
53
54 /**
55 * @return the chassisId
56 */
57 public LLDPTLV getChassisId() {
58 return this.chassisId;
59 }
60
61 /**
tom5f18cf32014-09-13 14:10:57 -070062 * @param chassis
alshabibc4901cd2014-09-05 16:50:40 -070063 * the chassisId to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -080064 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070065 */
66 public LLDP setChassisId(final LLDPTLV chassis) {
67 this.chassisId = chassis;
68 return this;
69 }
70
71 /**
72 * @return the portId
73 */
74 public LLDPTLV getPortId() {
75 return this.portId;
76 }
77
78 /**
79 * @param portId
80 * the portId to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -080081 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070082 */
83 public LLDP setPortId(final LLDPTLV portId) {
84 this.portId = portId;
85 return this;
86 }
87
88 /**
89 * @return the ttl
90 */
91 public LLDPTLV getTtl() {
92 return this.ttl;
93 }
94
95 /**
96 * @param ttl
97 * the ttl to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -080098 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070099 */
100 public LLDP setTtl(final LLDPTLV ttl) {
101 this.ttl = ttl;
102 return this;
103 }
104
105 /**
106 * @return the optionalTLVList
107 */
108 public List<LLDPTLV> getOptionalTLVList() {
109 return this.optionalTLVList;
110 }
111
112 /**
113 * @param optionalTLVList
114 * the optionalTLVList to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800115 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700116 */
117 public LLDP setOptionalTLVList(final List<LLDPTLV> optionalTLVList) {
118 this.optionalTLVList = optionalTLVList;
119 return this;
120 }
121
122 @Override
123 public byte[] serialize() {
124 int length = 2 + this.chassisId.getLength() + 2
125 + this.portId.getLength() + 2 + this.ttl.getLength() + 2;
126 for (final LLDPTLV tlv : this.optionalTLVList) {
127 length += 2 + tlv.getLength();
128 }
129
130 final byte[] data = new byte[length];
131 final ByteBuffer bb = ByteBuffer.wrap(data);
132 bb.put(this.chassisId.serialize());
133 bb.put(this.portId.serialize());
134 bb.put(this.ttl.serialize());
135 for (final LLDPTLV tlv : this.optionalTLVList) {
136 bb.put(tlv.serialize());
137 }
138 bb.putShort((short) 0); // End of LLDPDU
139
140 /*
141 * if (this.parent != null && this.parent instanceof Ethernet) {
142 * ((Ethernet) this.parent).setEtherType(this.ethType); }
143 */
144
145 return data;
146 }
147
148 @Override
149 public IPacket deserialize(final byte[] data, final int offset,
Jonathan Hart2a655752015-04-07 16:46:33 -0700150 final int length) {
alshabibc4901cd2014-09-05 16:50:40 -0700151 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
152 LLDPTLV tlv;
153 do {
Jonathan Hart2a655752015-04-07 16:46:33 -0700154 try {
155 tlv = new LLDPOrganizationalTLV().deserialize(bb);
156 } catch (DeserializationException e) {
157 break;
158 }
alshabibc4901cd2014-09-05 16:50:40 -0700159
160 // if there was a failure to deserialize stop processing TLVs
161 if (tlv == null) {
162 break;
163 }
164 switch (tlv.getType()) {
165 case 0x0:
166 // can throw this one away, its just an end delimiter
167 break;
168 case 0x1:
169 this.chassisId = tlv;
170 break;
171 case 0x2:
172 this.portId = tlv;
173 break;
174 case 0x3:
175 this.ttl = tlv;
176 break;
alshabib7911a052014-10-16 17:49:37 -0700177
alshabibc4901cd2014-09-05 16:50:40 -0700178 default:
179 this.optionalTLVList.add(tlv);
180 break;
181 }
182 } while (tlv.getType() != 0 && bb.hasRemaining());
183 return this;
184 }
185
186 /*
187 * (non-Javadoc)
188 *
189 * @see java.lang.Object#hashCode()
190 */
191 @Override
192 public int hashCode() {
193 final int prime = 883;
194 int result = super.hashCode();
195 result = prime * result
196 + (this.chassisId == null ? 0 : this.chassisId.hashCode());
197 result = prime * result + this.optionalTLVList.hashCode();
198 result = prime * result
199 + (this.portId == null ? 0 : this.portId.hashCode());
200 result = prime * result + (this.ttl == null ? 0 : this.ttl.hashCode());
201 return result;
202 }
203
204 /*
205 * (non-Javadoc)
206 *
207 * @see java.lang.Object#equals(java.lang.Object)
208 */
209 @Override
210 public boolean equals(final Object obj) {
211 if (this == obj) {
212 return true;
213 }
214 if (!super.equals(obj)) {
215 return false;
216 }
217 if (!(obj instanceof LLDP)) {
218 return false;
219 }
220 final LLDP other = (LLDP) obj;
221 if (this.chassisId == null) {
222 if (other.chassisId != null) {
223 return false;
224 }
225 } else if (!this.chassisId.equals(other.chassisId)) {
226 return false;
227 }
228 if (!this.optionalTLVList.equals(other.optionalTLVList)) {
229 return false;
230 }
231 if (this.portId == null) {
232 if (other.portId != null) {
233 return false;
234 }
235 } else if (!this.portId.equals(other.portId)) {
236 return false;
237 }
238 if (this.ttl == null) {
239 if (other.ttl != null) {
240 return false;
241 }
242 } else if (!this.ttl.equals(other.ttl)) {
243 return false;
244 }
245 return true;
246 }
Jonathan Hart2a655752015-04-07 16:46:33 -0700247
248 /**
249 * Deserializer function for LLDP packets.
250 *
251 * @return deserializer function
252 */
253 public static Deserializer<LLDP> deserializer() {
254 return (data, offset, length) -> {
255 checkInput(data, offset, length, 0);
256
257 LLDP lldp = new LLDP();
258
259 int currentIndex = 0;
260
261 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
262 LLDPTLV tlv;
263 do {
264 // Each new TLV must be a minimum of 2 bytes
265 // (containing the type and length fields).
266 currentIndex += 2;
267 checkHeaderLength(length, currentIndex);
268
269 tlv = new LLDPOrganizationalTLV().deserialize(bb);
270
271 // if there was a failure to deserialize stop processing TLVs
272 if (tlv == null) {
273 break;
274 }
275 switch (tlv.getType()) {
276 case 0x0:
277 // can throw this one away, it's just an end delimiter
278 break;
279 case 0x1:
280 lldp.chassisId = tlv;
281 break;
282 case 0x2:
283 lldp.portId = tlv;
284 break;
285 case 0x3:
286 lldp.ttl = tlv;
287 break;
288 default:
289 lldp.optionalTLVList.add(tlv);
290 break;
291 }
292
293 currentIndex += tlv.getLength();
294 } while (tlv.getType() != 0);
295
296 return lldp;
297 };
298 }
299
alshabibc4901cd2014-09-05 16:50:40 -0700300}