diff options
Diffstat (limited to 'framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java')
-rw-r--r-- | framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java new file mode 100644 index 00000000..1820cc31 --- /dev/null +++ b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/EAPOL.java @@ -0,0 +1,199 @@ +/* + * + * * Copyright 2015 AT&T Foundry + * * + * * 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 static org.onlab.packet.PacketUtils.checkHeaderLength; +import static org.onlab.packet.PacketUtils.checkInput; + +/** + * EAPOL (Extensible Authentication Protocol over LAN) header. + */ +public class EAPOL extends BasePacket { + + private byte version = 0x01; + private byte eapolType; + private short packetLength; + + private static final int HEADER_LENGTH = 4; + + // EAPOL Packet Type + public static final byte EAPOL_PACKET = 0x0; + public static final byte EAPOL_START = 0x1; + public static final byte EAPOL_LOGOFF = 0x2; + public static final byte EAPOL_KEY = 0x3; + public static final byte EAPOL_ASF = 0x4; + + public static final MacAddress PAE_GROUP_ADDR = MacAddress.valueOf(new byte[] { + (byte) 0x01, (byte) 0x80, (byte) 0xc2, (byte) 0x00, (byte) 0x00, (byte) 0x03 + }); + + /** + * Gets the version. + * + * @return version + */ + public byte getVersion() { + return this.version; + } + + /** + * Sets the version. + * + * @param version EAPOL version + * @return this + */ + public EAPOL setVersion(final byte version) { + this.version = version; + return this; + } + + /** + * Gets the type. + * + * @return EAPOL type + */ + public byte getEapolType() { + return this.eapolType; + } + + /** + * Sets the EAPOL type. + * + * @param eapolType EAPOL type + * @return this + */ + public EAPOL setEapolType(final byte eapolType) { + this.eapolType = eapolType; + return this; + } + + /** + * Gets the packet length. + * + * @return packet length + */ + public short getPacketLength() { + return this.packetLength; + } + + /** + * Sets the packet length. + * + * @param packetLen packet length + * @return this + */ + public EAPOL setPacketLength(final short packetLen) { + this.packetLength = packetLen; + return this; + } + + /** + * Serializes the packet, based on the code/type using the payload + * to compute its length. + * + * @return this + */ + @Override + public byte[] serialize() { + byte[] payloadData = null; + + if (this.payload != null) { + this.payload.setParent(this); + payloadData = this.payload.serialize(); + } + + // prepare the buffer to hold the version (1), packet type (1), + // packet length (2) and the eap payload. + // if there is no payload, packet length is 0 + byte[] data = new byte[4 + this.packetLength]; + final ByteBuffer bb = ByteBuffer.wrap(data); + bb.put(this.version); + bb.put(this.eapolType); + bb.putShort(this.packetLength); + + // put the EAP payload + if (payloadData != null) { + bb.put(payloadData); + } + + return data; + } + + @Override + public int hashCode() { + final int prime = 3889; + int result = super.hashCode(); + result = prime * result + this.version; + result = prime * result + this.eapolType; + result = prime * result + this.packetLength; + return result; + } + + /** + * Deserializer for EAPOL packets. + * + * @return deserializer + */ + public static Deserializer<EAPOL> deserializer() { + return (data, offset, length) -> { + checkInput(data, offset, length, HEADER_LENGTH); + + EAPOL eapol = new EAPOL(); + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + eapol.setVersion(bb.get()); + eapol.setEapolType(bb.get()); + eapol.setPacketLength(bb.getShort()); + + if (eapol.packetLength > 0) { + checkHeaderLength(length, HEADER_LENGTH + eapol.packetLength); + // deserialize the EAP Payload + eapol.payload = EAP.deserializer().deserialize(data, + bb.position(), bb.limit() - bb.position()); + + eapol.payload.setParent(eapol); + } + + return eapol; + }; + } + + @Override + public IPacket deserialize(final byte[] data, final int offset, + final int length) { + final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); + + // deserialize the EAPOL header + this.version = bb.get(); + this.eapolType = bb.get(); + this.packetLength = bb.getShort(); + + if (this.packetLength > 0) { + // deserialize the EAP Payload + this.payload = new EAP(); + + this.payload = this.payload.deserialize(data, bb.position(), length - 4); + this.payload.setParent(this); + } + + return this; + } +} + |