blob: 33b1f857f9fa78e8422b45c3d876907e5b4e9044 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
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;
Jian Li5fc14292015-12-04 11:30:46 -080023import java.util.Arrays;
Jonathan Hart2a655752015-04-07 16:46:33 -070024import java.util.LinkedList;
alshabibc4901cd2014-09-05 16:50:40 -070025import java.util.List;
26
Jian Li5fc14292015-12-04 11:30:46 -080027import static com.google.common.base.MoreObjects.toStringHelper;
Jonathan Hart2a655752015-04-07 16:46:33 -070028import static org.onlab.packet.PacketUtils.*;
29
alshabibc4901cd2014-09-05 16:50:40 -070030/**
Jian Li5fc14292015-12-04 11:30:46 -080031 * Representation of an LLDP Packet.
alshabibc4901cd2014-09-05 16:50:40 -070032 */
33public class LLDP extends BasePacket {
Jonathan Hart2a655752015-04-07 16:46:33 -070034 public static final byte CHASSIS_TLV_TYPE = 1;
35 public static final short CHASSIS_TLV_SIZE = 7;
36 public static final byte CHASSIS_TLV_SUBTYPE = 4;
37
38 public static final byte PORT_TLV_TYPE = 2;
39 public static final short PORT_TLV_SIZE = 5;
40 public static final byte PORT_TLV_SUBTYPE = 2;
41
42 public static final byte TTL_TLV_TYPE = 3;
43 public static final short TTL_TLV_SIZE = 2;
44
alshabibc4901cd2014-09-05 16:50:40 -070045 protected LLDPTLV chassisId;
46 protected LLDPTLV portId;
47 protected LLDPTLV ttl;
48 protected List<LLDPTLV> optionalTLVList;
49 protected short ethType;
50
51 public LLDP() {
Jonathan Hart2a655752015-04-07 16:46:33 -070052 this.optionalTLVList = new LinkedList<>();
alshabibc4901cd2014-09-05 16:50:40 -070053 this.ethType = Ethernet.TYPE_LLDP;
54 }
55
56 /**
57 * @return the chassisId
58 */
59 public LLDPTLV getChassisId() {
60 return this.chassisId;
61 }
62
63 /**
Jian Li5fc14292015-12-04 11:30:46 -080064 * @param chassis the chassisId to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -080065 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070066 */
67 public LLDP setChassisId(final LLDPTLV chassis) {
68 this.chassisId = chassis;
69 return this;
70 }
71
72 /**
73 * @return the portId
74 */
75 public LLDPTLV getPortId() {
76 return this.portId;
77 }
78
79 /**
Jian Li5fc14292015-12-04 11:30:46 -080080 * @param portId 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 /**
Jian Li5fc14292015-12-04 11:30:46 -080096 * @param ttl the ttl to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -080097 * @return this
alshabibc4901cd2014-09-05 16:50:40 -070098 */
99 public LLDP setTtl(final LLDPTLV ttl) {
100 this.ttl = ttl;
101 return this;
102 }
103
104 /**
105 * @return the optionalTLVList
106 */
107 public List<LLDPTLV> getOptionalTLVList() {
108 return this.optionalTLVList;
109 }
110
111 /**
Jian Li5fc14292015-12-04 11:30:46 -0800112 * @param optionalTLVList the optionalTLVList to set
Yuta HIGUCHI2281b3f2014-11-04 00:20:48 -0800113 * @return this
alshabibc4901cd2014-09-05 16:50:40 -0700114 */
115 public LLDP setOptionalTLVList(final List<LLDPTLV> optionalTLVList) {
116 this.optionalTLVList = optionalTLVList;
117 return this;
118 }
119
jaegonkim47b1b4a2017-12-04 14:08:26 +0900120 /**
121 * Adds additional TLV to optionalTLVList.
122 * @param lldptlv the optional TLV to be added
123 * @return this
124 */
125 public LLDP addOptionalTLV(final LLDPTLV lldptlv) {
126 this.optionalTLVList.add(lldptlv);
127 return this;
128 }
129
alshabibc4901cd2014-09-05 16:50:40 -0700130 @Override
131 public byte[] serialize() {
132 int length = 2 + this.chassisId.getLength() + 2
133 + this.portId.getLength() + 2 + this.ttl.getLength() + 2;
134 for (final LLDPTLV tlv : this.optionalTLVList) {
135 length += 2 + tlv.getLength();
136 }
137
138 final byte[] data = new byte[length];
139 final ByteBuffer bb = ByteBuffer.wrap(data);
140 bb.put(this.chassisId.serialize());
141 bb.put(this.portId.serialize());
142 bb.put(this.ttl.serialize());
143 for (final LLDPTLV tlv : this.optionalTLVList) {
144 bb.put(tlv.serialize());
145 }
146 bb.putShort((short) 0); // End of LLDPDU
147
148 /*
149 * if (this.parent != null && this.parent instanceof Ethernet) {
150 * ((Ethernet) this.parent).setEtherType(this.ethType); }
151 */
152
153 return data;
154 }
155
alshabibc4901cd2014-09-05 16:50:40 -0700156
157 /*
158 * (non-Javadoc)
159 *
160 * @see java.lang.Object#hashCode()
161 */
162 @Override
163 public int hashCode() {
164 final int prime = 883;
165 int result = super.hashCode();
166 result = prime * result
167 + (this.chassisId == null ? 0 : this.chassisId.hashCode());
168 result = prime * result + this.optionalTLVList.hashCode();
169 result = prime * result
170 + (this.portId == null ? 0 : this.portId.hashCode());
171 result = prime * result + (this.ttl == null ? 0 : this.ttl.hashCode());
172 return result;
173 }
174
175 /*
176 * (non-Javadoc)
177 *
178 * @see java.lang.Object#equals(java.lang.Object)
179 */
180 @Override
181 public boolean equals(final Object obj) {
182 if (this == obj) {
183 return true;
184 }
185 if (!super.equals(obj)) {
186 return false;
187 }
188 if (!(obj instanceof LLDP)) {
189 return false;
190 }
191 final LLDP other = (LLDP) obj;
192 if (this.chassisId == null) {
193 if (other.chassisId != null) {
194 return false;
195 }
196 } else if (!this.chassisId.equals(other.chassisId)) {
197 return false;
198 }
199 if (!this.optionalTLVList.equals(other.optionalTLVList)) {
200 return false;
201 }
202 if (this.portId == null) {
203 if (other.portId != null) {
204 return false;
205 }
206 } else if (!this.portId.equals(other.portId)) {
207 return false;
208 }
209 if (this.ttl == null) {
210 if (other.ttl != null) {
211 return false;
212 }
213 } else if (!this.ttl.equals(other.ttl)) {
214 return false;
215 }
216 return true;
217 }
Jonathan Hart2a655752015-04-07 16:46:33 -0700218
219 /**
220 * Deserializer function for LLDP packets.
221 *
222 * @return deserializer function
223 */
224 public static Deserializer<LLDP> deserializer() {
225 return (data, offset, length) -> {
226 checkInput(data, offset, length, 0);
227
228 LLDP lldp = new LLDP();
229
230 int currentIndex = 0;
231
232 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
233 LLDPTLV tlv;
234 do {
235 // Each new TLV must be a minimum of 2 bytes
236 // (containing the type and length fields).
237 currentIndex += 2;
238 checkHeaderLength(length, currentIndex);
239
240 tlv = new LLDPOrganizationalTLV().deserialize(bb);
241
242 // if there was a failure to deserialize stop processing TLVs
243 if (tlv == null) {
244 break;
245 }
246 switch (tlv.getType()) {
Jian Li5fc14292015-12-04 11:30:46 -0800247 case 0x0:
248 // can throw this one away, it's just an end delimiter
249 break;
250 case 0x1:
251 lldp.chassisId = tlv;
252 break;
253 case 0x2:
254 lldp.portId = tlv;
255 break;
256 case 0x3:
257 lldp.ttl = tlv;
258 break;
259 default:
260 lldp.optionalTLVList.add(tlv);
261 break;
Jonathan Hart2a655752015-04-07 16:46:33 -0700262 }
263
264 currentIndex += tlv.getLength();
265 } while (tlv.getType() != 0);
266
267 return lldp;
268 };
269 }
270
Jian Li5fc14292015-12-04 11:30:46 -0800271 @Override
272 public String toString() {
273 return toStringHelper(getClass())
274 .add("chassisId", Arrays.toString(chassisId.getValue()))
275 .add("portId", Arrays.toString(portId.getValue()))
276 .add("ttl", Arrays.toString(ttl.getValue()))
277 .add("ethType", Short.toString(ethType))
278 .toString();
279
280 // TODO: need to handle optionalTLVList
281 }
alshabibc4901cd2014-09-05 16:50:40 -0700282}