blob: cd46eee824859d122a4b4d577b87963d21526ffd [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
120 @Override
121 public byte[] serialize() {
122 int length = 2 + this.chassisId.getLength() + 2
123 + this.portId.getLength() + 2 + this.ttl.getLength() + 2;
124 for (final LLDPTLV tlv : this.optionalTLVList) {
125 length += 2 + tlv.getLength();
126 }
127
128 final byte[] data = new byte[length];
129 final ByteBuffer bb = ByteBuffer.wrap(data);
130 bb.put(this.chassisId.serialize());
131 bb.put(this.portId.serialize());
132 bb.put(this.ttl.serialize());
133 for (final LLDPTLV tlv : this.optionalTLVList) {
134 bb.put(tlv.serialize());
135 }
136 bb.putShort((short) 0); // End of LLDPDU
137
138 /*
139 * if (this.parent != null && this.parent instanceof Ethernet) {
140 * ((Ethernet) this.parent).setEtherType(this.ethType); }
141 */
142
143 return data;
144 }
145
alshabibc4901cd2014-09-05 16:50:40 -0700146
147 /*
148 * (non-Javadoc)
149 *
150 * @see java.lang.Object#hashCode()
151 */
152 @Override
153 public int hashCode() {
154 final int prime = 883;
155 int result = super.hashCode();
156 result = prime * result
157 + (this.chassisId == null ? 0 : this.chassisId.hashCode());
158 result = prime * result + this.optionalTLVList.hashCode();
159 result = prime * result
160 + (this.portId == null ? 0 : this.portId.hashCode());
161 result = prime * result + (this.ttl == null ? 0 : this.ttl.hashCode());
162 return result;
163 }
164
165 /*
166 * (non-Javadoc)
167 *
168 * @see java.lang.Object#equals(java.lang.Object)
169 */
170 @Override
171 public boolean equals(final Object obj) {
172 if (this == obj) {
173 return true;
174 }
175 if (!super.equals(obj)) {
176 return false;
177 }
178 if (!(obj instanceof LLDP)) {
179 return false;
180 }
181 final LLDP other = (LLDP) obj;
182 if (this.chassisId == null) {
183 if (other.chassisId != null) {
184 return false;
185 }
186 } else if (!this.chassisId.equals(other.chassisId)) {
187 return false;
188 }
189 if (!this.optionalTLVList.equals(other.optionalTLVList)) {
190 return false;
191 }
192 if (this.portId == null) {
193 if (other.portId != null) {
194 return false;
195 }
196 } else if (!this.portId.equals(other.portId)) {
197 return false;
198 }
199 if (this.ttl == null) {
200 if (other.ttl != null) {
201 return false;
202 }
203 } else if (!this.ttl.equals(other.ttl)) {
204 return false;
205 }
206 return true;
207 }
Jonathan Hart2a655752015-04-07 16:46:33 -0700208
209 /**
210 * Deserializer function for LLDP packets.
211 *
212 * @return deserializer function
213 */
214 public static Deserializer<LLDP> deserializer() {
215 return (data, offset, length) -> {
216 checkInput(data, offset, length, 0);
217
218 LLDP lldp = new LLDP();
219
220 int currentIndex = 0;
221
222 ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
223 LLDPTLV tlv;
224 do {
225 // Each new TLV must be a minimum of 2 bytes
226 // (containing the type and length fields).
227 currentIndex += 2;
228 checkHeaderLength(length, currentIndex);
229
230 tlv = new LLDPOrganizationalTLV().deserialize(bb);
231
232 // if there was a failure to deserialize stop processing TLVs
233 if (tlv == null) {
234 break;
235 }
236 switch (tlv.getType()) {
Jian Li5fc14292015-12-04 11:30:46 -0800237 case 0x0:
238 // can throw this one away, it's just an end delimiter
239 break;
240 case 0x1:
241 lldp.chassisId = tlv;
242 break;
243 case 0x2:
244 lldp.portId = tlv;
245 break;
246 case 0x3:
247 lldp.ttl = tlv;
248 break;
249 default:
250 lldp.optionalTLVList.add(tlv);
251 break;
Jonathan Hart2a655752015-04-07 16:46:33 -0700252 }
253
254 currentIndex += tlv.getLength();
255 } while (tlv.getType() != 0);
256
257 return lldp;
258 };
259 }
260
Jian Li5fc14292015-12-04 11:30:46 -0800261 @Override
262 public String toString() {
263 return toStringHelper(getClass())
264 .add("chassisId", Arrays.toString(chassisId.getValue()))
265 .add("portId", Arrays.toString(portId.getValue()))
266 .add("ttl", Arrays.toString(ttl.getValue()))
267 .add("ethType", Short.toString(ethType))
268 .toString();
269
270 // TODO: need to handle optionalTLVList
271 }
alshabibc4901cd2014-09-05 16:50:40 -0700272}