blob: 1820cc31ba7062be2e02d797fd1f224e7738300a [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
Jonathan Hart4a60bb32015-06-30 15:31:20 -070023import static org.onlab.packet.PacketUtils.checkHeaderLength;
alshabib7b808c52015-06-26 14:22:24 -070024import static org.onlab.packet.PacketUtils.checkInput;
25
Ari Saha79d7c252015-06-26 10:31:48 -070026/**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070027 * EAPOL (Extensible Authentication Protocol over LAN) header.
Ari Saha79d7c252015-06-26 10:31:48 -070028 */
29public class EAPOL extends BasePacket {
30
31 private byte version = 0x01;
32 private byte eapolType;
33 private short packetLength;
34
Jonathan Hart4a60bb32015-06-30 15:31:20 -070035 private static final int HEADER_LENGTH = 4;
36
37 // EAPOL Packet Type
Ari Saha79d7c252015-06-26 10:31:48 -070038 public static final byte EAPOL_PACKET = 0x0;
39 public static final byte EAPOL_START = 0x1;
40 public static final byte EAPOL_LOGOFF = 0x2;
41 public static final byte EAPOL_KEY = 0x3;
42 public static final byte EAPOL_ASF = 0x4;
43
44 public static final MacAddress PAE_GROUP_ADDR = MacAddress.valueOf(new byte[] {
45 (byte) 0x01, (byte) 0x80, (byte) 0xc2, (byte) 0x00, (byte) 0x00, (byte) 0x03
46 });
47
Ari Saha79d7c252015-06-26 10:31:48 -070048 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070049 * Gets the version.
50 *
Ari Saha79d7c252015-06-26 10:31:48 -070051 * @return version
52 */
53 public byte getVersion() {
54 return this.version;
55 }
56
57 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070058 * Sets the version.
59 *
Ari Saha79d7c252015-06-26 10:31:48 -070060 * @param version EAPOL version
61 * @return this
62 */
63 public EAPOL setVersion(final byte version) {
64 this.version = version;
65 return this;
66 }
67
68 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070069 * Gets the type.
70 *
Ari Saha79d7c252015-06-26 10:31:48 -070071 * @return EAPOL type
72 */
73 public byte getEapolType() {
74 return this.eapolType;
75 }
76
77 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070078 * Sets the EAPOL type.
79 *
Ari Saha79d7c252015-06-26 10:31:48 -070080 * @param eapolType EAPOL type
81 * @return this
82 */
83 public EAPOL setEapolType(final byte eapolType) {
84 this.eapolType = eapolType;
85 return this;
86 }
87
88 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070089 * Gets the packet length.
90 *
Ari Saha79d7c252015-06-26 10:31:48 -070091 * @return packet length
92 */
93 public short getPacketLength() {
94 return this.packetLength;
95 }
96
97 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -070098 * Sets the packet length.
99 *
Ari Saha79d7c252015-06-26 10:31:48 -0700100 * @param packetLen packet length
101 * @return this
102 */
103 public EAPOL setPacketLength(final short packetLen) {
104 this.packetLength = packetLen;
105 return this;
106 }
107
Ari Saha79d7c252015-06-26 10:31:48 -0700108 /**
109 * Serializes the packet, based on the code/type using the payload
110 * to compute its length.
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700111 *
Ari Saha79d7c252015-06-26 10:31:48 -0700112 * @return this
113 */
114 @Override
115 public byte[] serialize() {
Ari Saha79d7c252015-06-26 10:31:48 -0700116 byte[] payloadData = null;
117
118 if (this.payload != null) {
119 this.payload.setParent(this);
120 payloadData = this.payload.serialize();
121 }
122
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700123 // prepare the buffer to hold the version (1), packet type (1),
124 // packet length (2) and the eap payload.
125 // if there is no payload, packet length is 0
Ari Saha79d7c252015-06-26 10:31:48 -0700126 byte[] data = new byte[4 + this.packetLength];
127 final ByteBuffer bb = ByteBuffer.wrap(data);
128 bb.put(this.version);
129 bb.put(this.eapolType);
130 bb.putShort(this.packetLength);
131
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700132 // put the EAP payload
Ari Saha79d7c252015-06-26 10:31:48 -0700133 if (payloadData != null) {
134 bb.put(payloadData);
135 }
136
137 return data;
138 }
139
Ari Saha79d7c252015-06-26 10:31:48 -0700140 @Override
141 public int hashCode() {
142 final int prime = 3889;
143 int result = super.hashCode();
144 result = prime * result + this.version;
145 result = prime * result + this.eapolType;
146 result = prime * result + this.packetLength;
147 return result;
148 }
149
150 /**
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700151 * Deserializer for EAPOL packets.
Ari Saha79d7c252015-06-26 10:31:48 -0700152 *
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700153 * @return deserializer
Ari Saha79d7c252015-06-26 10:31:48 -0700154 */
alshabib7b808c52015-06-26 14:22:24 -0700155 public static Deserializer<EAPOL> deserializer() {
156 return (data, offset, length) -> {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700157 checkInput(data, offset, length, HEADER_LENGTH);
alshabib7b808c52015-06-26 14:22:24 -0700158
159 EAPOL eapol = new EAPOL();
160 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
161 eapol.setVersion(bb.get());
162 eapol.setEapolType(bb.get());
163 eapol.setPacketLength(bb.getShort());
164
165 if (eapol.packetLength > 0) {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700166 checkHeaderLength(length, HEADER_LENGTH + eapol.packetLength);
167 // deserialize the EAP Payload
168 eapol.payload = EAP.deserializer().deserialize(data,
169 bb.position(), bb.limit() - bb.position());
alshabib7b808c52015-06-26 14:22:24 -0700170
alshabib7b808c52015-06-26 14:22:24 -0700171 eapol.payload.setParent(eapol);
172 }
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700173
alshabib7b808c52015-06-26 14:22:24 -0700174 return eapol;
175 };
176 }
177
178 @Override
179 public IPacket deserialize(final byte[] data, final int offset,
180 final int length) {
181 final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
182
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700183 // deserialize the EAPOL header
alshabib7b808c52015-06-26 14:22:24 -0700184 this.version = bb.get();
185 this.eapolType = bb.get();
186 this.packetLength = bb.getShort();
187
188 if (this.packetLength > 0) {
Jonathan Hart4a60bb32015-06-30 15:31:20 -0700189 // deserialize the EAP Payload
alshabib7b808c52015-06-26 14:22:24 -0700190 this.payload = new EAP();
191
192 this.payload = this.payload.deserialize(data, bb.position(), length - 4);
193 this.payload.setParent(this);
194 }
195
alshabib7b808c52015-06-26 14:22:24 -0700196 return this;
197 }
Ari Saha79d7c252015-06-26 10:31:48 -0700198}
199