blob: 3849caa91347bb0cc28e1d022d7a91ce01750900 [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
151 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700152 * Deserializer for EAPOL packets.
Ari Saha79d7c252015-06-26 10:31:48 -0700153 *
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700154 * @return deserializer
Ari Saha79d7c252015-06-26 10:31:48 -0700155 */
alshabib7b808c52015-06-26 14:22:24 -0700156 public static Deserializer<EAPOL> deserializer() {
157 return (data, offset, length) -> {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700158 checkInput(data, offset, length, HEADER_LENGTH);
alshabib7b808c52015-06-26 14:22:24 -0700159
160 EAPOL eapol = new EAPOL();
161 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
162 eapol.setVersion(bb.get());
163 eapol.setEapolType(bb.get());
164 eapol.setPacketLength(bb.getShort());
165
166 if (eapol.packetLength > 0) {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700167 checkHeaderLength(length, HEADER_LENGTH + eapol.packetLength);
168 // deserialize the EAP Payload
169 eapol.payload = EAP.deserializer().deserialize(data,
170 bb.position(), bb.limit() - bb.position());
alshabib7b808c52015-06-26 14:22:24 -0700171
alshabib7b808c52015-06-26 14:22:24 -0700172 eapol.payload.setParent(eapol);
173 }
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700174
alshabib7b808c52015-06-26 14:22:24 -0700175 return eapol;
176 };
177 }
178
179 @Override
180 public IPacket deserialize(final byte[] data, final int offset,
181 final int length) {
182 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
183
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700184 // deserialize the EAPOL header
alshabib7b808c52015-06-26 14:22:24 -0700185 this.version = bb.get();
186 this.eapolType = bb.get();
187 this.packetLength = bb.getShort();
188
189 if (this.packetLength > 0) {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700190 // deserialize the EAP Payload
alshabib7b808c52015-06-26 14:22:24 -0700191 this.payload = new EAP();
192
193 this.payload = this.payload.deserialize(data, bb.position(), length - 4);
194 this.payload.setParent(this);
195 }
196
alshabib7b808c52015-06-26 14:22:24 -0700197 return this;
198 }
Jian Li5fc14292015-12-04 11:30:46 -0800199
200 @Override
201 public String toString() {
202 return toStringHelper(getClass())
203 .add("version", Byte.toString(version))
204 .add("eapolType", Byte.toString(eapolType))
205 .add("packetLength", Short.toString(packetLength))
206 .toString();
207 }
Ari Saha79d7c252015-06-26 10:31:48 -0700208}
209