blob: 3a2aa5239767e086e6fb1e6b8f6b8d7980851f9c [file] [log] [blame]
Ari Saha79d7c252015-06-26 10:31:48 -07001/*
2 *
3 * * Copyright 2015 AT&T Foundry
4 * *
5 * * Licensed under the Apache License, Version 2.0 (the "License");
6 * * you may not use this file except in compliance with the License.
7 * * You may obtain a copy of the License at
8 * *
9 * * http://www.apache.org/licenses/LICENSE-2.0
10 * *
11 * * Unless required by applicable law or agreed to in writing, software
12 * * distributed under the License is distributed on an "AS IS" BASIS,
13 * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * * See the License for the specific language governing permissions and
15 * * limitations under the License.
16 *
17 */
18
Jonathan Hart4a60bb32015-06-30 15:31:20 -070019package org.onlab.packet;
Ari Saha79d7c252015-06-26 10:31:48 -070020
21import java.nio.ByteBuffer;
22
Jian Li5fc14292015-12-04 11:30:46 -080023import static com.google.common.base.MoreObjects.toStringHelper;
Jonathan Hart4a60bb32015-06-30 15:31:20 -070024import static org.onlab.packet.PacketUtils.checkHeaderLength;
alshabib7b808c52015-06-26 14:22:24 -070025import static org.onlab.packet.PacketUtils.checkInput;
26
Ari Saha79d7c252015-06-26 10:31:48 -070027/**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070028 * EAPOL (Extensible Authentication Protocol over LAN) header.
Ari Saha79d7c252015-06-26 10:31:48 -070029 */
30public class EAPOL extends BasePacket {
31
32 private byte version = 0x01;
33 private byte eapolType;
34 private short packetLength;
35
Jonathan Hart4a60bb32015-06-30 15:31:20 -070036 private static final int HEADER_LENGTH = 4;
37
38 // EAPOL Packet Type
Ari Saha79d7c252015-06-26 10:31:48 -070039 public static final byte EAPOL_PACKET = 0x0;
40 public static final byte EAPOL_START = 0x1;
41 public static final byte EAPOL_LOGOFF = 0x2;
42 public static final byte EAPOL_KEY = 0x3;
43 public static final byte EAPOL_ASF = 0x4;
44
45 public static final MacAddress PAE_GROUP_ADDR = MacAddress.valueOf(new byte[] {
46 (byte) 0x01, (byte) 0x80, (byte) 0xc2, (byte) 0x00, (byte) 0x00, (byte) 0x03
47 });
48
Ari Saha79d7c252015-06-26 10:31:48 -070049 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070050 * Gets the version.
51 *
Ari Saha79d7c252015-06-26 10:31:48 -070052 * @return version
53 */
54 public byte getVersion() {
55 return this.version;
56 }
57
58 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070059 * Sets the version.
60 *
Ari Saha79d7c252015-06-26 10:31:48 -070061 * @param version EAPOL version
62 * @return this
63 */
64 public EAPOL setVersion(final byte version) {
65 this.version = version;
66 return this;
67 }
68
69 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070070 * Gets the type.
71 *
Ari Saha79d7c252015-06-26 10:31:48 -070072 * @return EAPOL type
73 */
74 public byte getEapolType() {
75 return this.eapolType;
76 }
77
78 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070079 * Sets the EAPOL type.
80 *
Ari Saha79d7c252015-06-26 10:31:48 -070081 * @param eapolType EAPOL type
82 * @return this
83 */
84 public EAPOL setEapolType(final byte eapolType) {
85 this.eapolType = eapolType;
86 return this;
87 }
88
89 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070090 * Gets the packet length.
91 *
Ari Saha79d7c252015-06-26 10:31:48 -070092 * @return packet length
93 */
94 public short getPacketLength() {
95 return this.packetLength;
96 }
97
98 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070099 * Sets the packet length.
100 *
Ari Saha79d7c252015-06-26 10:31:48 -0700101 * @param packetLen packet length
102 * @return this
103 */
104 public EAPOL setPacketLength(final short packetLen) {
105 this.packetLength = packetLen;
106 return this;
107 }
108
Ari Saha79d7c252015-06-26 10:31:48 -0700109 /**
110 * Serializes the packet, based on the code/type using the payload
111 * to compute its length.
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700112 *
Ari Saha79d7c252015-06-26 10:31:48 -0700113 * @return this
114 */
115 @Override
116 public byte[] serialize() {
Ari Saha79d7c252015-06-26 10:31:48 -0700117 byte[] payloadData = null;
118
119 if (this.payload != null) {
120 this.payload.setParent(this);
121 payloadData = this.payload.serialize();
122 }
123
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700124 // prepare the buffer to hold the version (1), packet type (1),
125 // packet length (2) and the eap payload.
126 // if there is no payload, packet length is 0
Ari Saha79d7c252015-06-26 10:31:48 -0700127 byte[] data = new byte[4 + this.packetLength];
128 final ByteBuffer bb = ByteBuffer.wrap(data);
129 bb.put(this.version);
130 bb.put(this.eapolType);
131 bb.putShort(this.packetLength);
132
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700133 // put the EAP payload
Ari Saha79d7c252015-06-26 10:31:48 -0700134 if (payloadData != null) {
135 bb.put(payloadData);
136 }
137
138 return data;
139 }
140
Ari Saha79d7c252015-06-26 10:31:48 -0700141 @Override
142 public int hashCode() {
143 final int prime = 3889;
144 int result = super.hashCode();
145 result = prime * result + this.version;
146 result = prime * result + this.eapolType;
147 result = prime * result + this.packetLength;
148 return result;
149 }
150
Ray Milkey86f20cc2015-12-09 16:54:09 -0800151 @Override
152 public boolean equals(Object o) {
153 if (this == o) {
154 return true;
155 }
156 if (!(o instanceof EAPOL)) {
157 return false;
158 }
159 EAPOL that = (EAPOL) o;
160
161 if (this.version != that.version) {
162 return false;
163 }
164 if (this.eapolType != that.eapolType) {
165 return false;
166 }
167 if (this.packetLength != that.packetLength) {
168 return false;
169 }
170 return true;
171 }
172
Ari Saha79d7c252015-06-26 10:31:48 -0700173 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700174 * Deserializer for EAPOL packets.
Ari Saha79d7c252015-06-26 10:31:48 -0700175 *
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700176 * @return deserializer
Ari Saha79d7c252015-06-26 10:31:48 -0700177 */
alshabib7b808c52015-06-26 14:22:24 -0700178 public static Deserializer<EAPOL> deserializer() {
179 return (data, offset, length) -> {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700180 checkInput(data, offset, length, HEADER_LENGTH);
alshabib7b808c52015-06-26 14:22:24 -0700181
182 EAPOL eapol = new EAPOL();
183 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
184 eapol.setVersion(bb.get());
185 eapol.setEapolType(bb.get());
186 eapol.setPacketLength(bb.getShort());
187
188 if (eapol.packetLength > 0) {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700189 checkHeaderLength(length, HEADER_LENGTH + eapol.packetLength);
190 // deserialize the EAP Payload
191 eapol.payload = EAP.deserializer().deserialize(data,
192 bb.position(), bb.limit() - bb.position());
alshabib7b808c52015-06-26 14:22:24 -0700193
alshabib7b808c52015-06-26 14:22:24 -0700194 eapol.payload.setParent(eapol);
195 }
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700196
alshabib7b808c52015-06-26 14:22:24 -0700197 return eapol;
198 };
199 }
200
201 @Override
202 public IPacket deserialize(final byte[] data, final int offset,
203 final int length) {
204 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
205
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700206 // deserialize the EAPOL header
alshabib7b808c52015-06-26 14:22:24 -0700207 this.version = bb.get();
208 this.eapolType = bb.get();
209 this.packetLength = bb.getShort();
210
211 if (this.packetLength > 0) {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700212 // deserialize the EAP Payload
alshabib7b808c52015-06-26 14:22:24 -0700213 this.payload = new EAP();
214
215 this.payload = this.payload.deserialize(data, bb.position(), length - 4);
216 this.payload.setParent(this);
217 }
218
alshabib7b808c52015-06-26 14:22:24 -0700219 return this;
220 }
Jian Li5fc14292015-12-04 11:30:46 -0800221
222 @Override
223 public String toString() {
224 return toStringHelper(getClass())
225 .add("version", Byte.toString(version))
226 .add("eapolType", Byte.toString(eapolType))
227 .add("packetLength", Short.toString(packetLength))
228 .toString();
229 }
Ari Saha79d7c252015-06-26 10:31:48 -0700230}
231