diff options
Diffstat (limited to 'framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java')
-rw-r--r-- | framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java new file mode 100644 index 00000000..ae9d7173 --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/LLDP.java @@ -0,0 +1,300 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * + */ +package org.onlab.packet; + +import java.nio.ByteBuffer; +import java.util.LinkedList; +import java.util.List; + +import static org.onlab.packet.PacketUtils.*; + +/** + * + */ +public class LLDP extends BasePacket { + public static final byte CHASSIS_TLV_TYPE = 1; + public static final short CHASSIS_TLV_SIZE = 7; + public static final byte CHASSIS_TLV_SUBTYPE = 4; + + public static final byte PORT_TLV_TYPE = 2; + public static final short PORT_TLV_SIZE = 5; + public static final byte PORT_TLV_SUBTYPE = 2; + + public static final byte TTL_TLV_TYPE = 3; + public static final short TTL_TLV_SIZE = 2; + + protected LLDPTLV chassisId; + protected LLDPTLV portId; + protected LLDPTLV ttl; + protected List<LLDPTLV> optionalTLVList; + protected short ethType; + + public LLDP() { + this.optionalTLVList = new LinkedList<>(); + this.ethType = Ethernet.TYPE_LLDP; + } + + /** + * @return the chassisId + */ + public LLDPTLV getChassisId() { + return this.chassisId; + } + + /** + * @param chassis + * the chassisId to set + * @return this + */ + public LLDP setChassisId(final LLDPTLV chassis) { + this.chassisId = chassis; + return this; + } + + /** + * @return the portId + */ + public LLDPTLV getPortId() { + return this.portId; + } + + /** + * @param portId + * the portId to set + * @return this + */ + public LLDP setPortId(final LLDPTLV portId) { + this.portId = portId; + return this; + } + + /** + * @return the ttl + */ + public LLDPTLV getTtl() { + return this.ttl; + } + + /** + * @param ttl + * the ttl to set + * @return this + */ + public LLDP setTtl(final LLDPTLV ttl) { + this.ttl = ttl; + return this; + } + + /** + * @return the optionalTLVList + */ + public List<LLDPTLV> getOptionalTLVList() { + return this.optionalTLVList; + } + + /** + * @param optionalTLVList + * the optionalTLVList to set + * @return this + */ + public LLDP setOptionalTLVList(final List<LLDPTLV> optionalTLVList) { + this.optionalTLVList = optionalTLVList; + return this; + } + + @Override + public byte[] serialize() { + int length = 2 + this.chassisId.getLength() + 2 + + this.portId.getLength() + 2 + this.ttl.getLength() + 2; + for (final LLDPTLV tlv : this.optionalTLVList) { + length += 2 + tlv.getLength(); + } + + final byte[] data = new byte[length]; + final ByteBuffer bb = ByteBuffer.wrap(data); + bb.put(this.chassisId.serialize()); + bb.put(this.portId.serialize()); + bb.put(this.ttl.serialize()); + for (final LLDPTLV tlv : this.optionalTLVList) { + bb.put(tlv.serialize()); + } + bb.putShort((short) 0); // End of LLDPDU + + /* + * if (this.parent != null && this.parent instanceof Ethernet) { + * ((Ethernet) this.parent).setEtherType(this.ethType); } + */ + + return data; + } + + @Override + public IPacket deserialize(final byte[] data, final int offset, + final int length) { + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + LLDPTLV tlv; + do { + try { + tlv = new LLDPOrganizationalTLV().deserialize(bb); + } catch (DeserializationException e) { + break; + } + + // if there was a failure to deserialize stop processing TLVs + if (tlv == null) { + break; + } + switch (tlv.getType()) { + case 0x0: + // can throw this one away, its just an end delimiter + break; + case 0x1: + this.chassisId = tlv; + break; + case 0x2: + this.portId = tlv; + break; + case 0x3: + this.ttl = tlv; + break; + + default: + this.optionalTLVList.add(tlv); + break; + } + } while (tlv.getType() != 0 && bb.hasRemaining()); + return this; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 883; + int result = super.hashCode(); + result = prime * result + + (this.chassisId == null ? 0 : this.chassisId.hashCode()); + result = prime * result + this.optionalTLVList.hashCode(); + result = prime * result + + (this.portId == null ? 0 : this.portId.hashCode()); + result = prime * result + (this.ttl == null ? 0 : this.ttl.hashCode()); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (!super.equals(obj)) { + return false; + } + if (!(obj instanceof LLDP)) { + return false; + } + final LLDP other = (LLDP) obj; + if (this.chassisId == null) { + if (other.chassisId != null) { + return false; + } + } else if (!this.chassisId.equals(other.chassisId)) { + return false; + } + if (!this.optionalTLVList.equals(other.optionalTLVList)) { + return false; + } + if (this.portId == null) { + if (other.portId != null) { + return false; + } + } else if (!this.portId.equals(other.portId)) { + return false; + } + if (this.ttl == null) { + if (other.ttl != null) { + return false; + } + } else if (!this.ttl.equals(other.ttl)) { + return false; + } + return true; + } + + /** + * Deserializer function for LLDP packets. + * + * @return deserializer function + */ + public static Deserializer<LLDP> deserializer() { + return (data, offset, length) -> { + checkInput(data, offset, length, 0); + + LLDP lldp = new LLDP(); + + int currentIndex = 0; + + ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + LLDPTLV tlv; + do { + // Each new TLV must be a minimum of 2 bytes + // (containing the type and length fields). + currentIndex += 2; + checkHeaderLength(length, currentIndex); + + tlv = new LLDPOrganizationalTLV().deserialize(bb); + + // if there was a failure to deserialize stop processing TLVs + if (tlv == null) { + break; + } + switch (tlv.getType()) { + case 0x0: + // can throw this one away, it's just an end delimiter + break; + case 0x1: + lldp.chassisId = tlv; + break; + case 0x2: + lldp.portId = tlv; + break; + case 0x3: + lldp.ttl = tlv; + break; + default: + lldp.optionalTLVList.add(tlv); + break; + } + + currentIndex += tlv.getLength(); + } while (tlv.getType() != 0); + + return lldp; + }; + } + +} |