diff options
Diffstat (limited to 'framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java')
-rw-r--r-- | framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java | 632 |
1 files changed, 0 insertions, 632 deletions
diff --git a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java b/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java deleted file mode 100644 index de5b43fa..00000000 --- a/framework/src/onos/utils/misc/src/main/java/org/onlab/packet/DHCP.java +++ /dev/null @@ -1,632 +0,0 @@ -/* - * 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.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; - -import static com.google.common.base.Preconditions.checkArgument; -import static org.onlab.packet.PacketUtils.checkInput; - -/** - * - */ -public class DHCP extends BasePacket { - /** - * Dynamic Host Configuration Protocol packet. - * ------------------------------------------ |op (1) | htype(1) | hlen(1) | - * hops(1) | ------------------------------------------ | xid (4) | - * ------------------------------------------ | secs (2) | flags (2) | - * ------------------------------------------ | ciaddr (4) | - * ------------------------------------------ | yiaddr (4) | - * ------------------------------------------ | siaddr (4) | - * ------------------------------------------ | giaddr (4) | - * ------------------------------------------ | chaddr (16) | - * ------------------------------------------ | sname (64) | - * ------------------------------------------ | file (128) | - * ------------------------------------------ | options (312) | - * ------------------------------------------ - * - */ - // Header + magic without options - public static final int MIN_HEADER_LENGTH = 240; - public static final byte OPCODE_REQUEST = 0x1; - public static final byte OPCODE_REPLY = 0x2; - - public static final byte HWTYPE_ETHERNET = 0x1; - - public enum DHCPOptionCode { - OptionCode_SubnetMask((byte) 1), OptionCode_RouterAddress((byte) 3), OptionCode_DomainServer((byte) 6), - OptionCode_HostName((byte) 12), OptionCode_DomainName((byte) 15), OptionCode_BroadcastAddress((byte) 28), - OptionCode_RequestedIP((byte) 50), OptionCode_LeaseTime((byte) 51), OptionCode_MessageType((byte) 53), - OptionCode_DHCPServerIp((byte) 54), OptionCode_RequestedParameters((byte) 55), - OptionCode_RenewalTime((byte) 58), OPtionCode_RebindingTime((byte) 59), OptionCode_ClientID((byte) 61), - OptionCode_END((byte) 255); - - protected byte value; - - private DHCPOptionCode(final byte value) { - this.value = value; - } - - public byte getValue() { - return this.value; - } - } - - protected byte opCode; - protected byte hardwareType; - protected byte hardwareAddressLength; - protected byte hops; - protected int transactionId; - protected short seconds; - protected short flags; - protected int clientIPAddress; - protected int yourIPAddress; - protected int serverIPAddress; - protected int gatewayIPAddress; - protected byte[] clientHardwareAddress; - protected String serverName; - protected String bootFileName; - protected List<DHCPOption> options = new ArrayList<DHCPOption>(); - - /** - * @return the opCode - */ - public byte getOpCode() { - return this.opCode; - } - - /** - * @param opCode - * the opCode to set - * @return this - */ - public DHCP setOpCode(final byte opCode) { - this.opCode = opCode; - return this; - } - - /** - * @return the hardwareType - */ - public byte getHardwareType() { - return this.hardwareType; - } - - /** - * @param hardwareType - * the hardwareType to set - * @return this - */ - public DHCP setHardwareType(final byte hardwareType) { - this.hardwareType = hardwareType; - return this; - } - - /** - * @return the hardwareAddressLength - */ - public byte getHardwareAddressLength() { - return this.hardwareAddressLength; - } - - /** - * @param hardwareAddressLength - * the hardwareAddressLength to set - * @return this - */ - public DHCP setHardwareAddressLength(final byte hardwareAddressLength) { - this.hardwareAddressLength = hardwareAddressLength; - return this; - } - - /** - * @return the hops - */ - public byte getHops() { - return this.hops; - } - - /** - * @param hops - * the hops to set - * @return this - */ - public DHCP setHops(final byte hops) { - this.hops = hops; - return this; - } - - /** - * @return the transactionId - */ - public int getTransactionId() { - return this.transactionId; - } - - /** - * @param transactionId - * the transactionId to set - * @return this - */ - public DHCP setTransactionId(final int transactionId) { - this.transactionId = transactionId; - return this; - } - - /** - * @return the seconds - */ - public short getSeconds() { - return this.seconds; - } - - /** - * @param seconds - * the seconds to set - * @return this - */ - public DHCP setSeconds(final short seconds) { - this.seconds = seconds; - return this; - } - - /** - * @return the flags - */ - public short getFlags() { - return this.flags; - } - - /** - * @param flags - * the flags to set - * @return this - */ - public DHCP setFlags(final short flags) { - this.flags = flags; - return this; - } - - /** - * @return the clientIPAddress - */ - public int getClientIPAddress() { - return this.clientIPAddress; - } - - /** - * @param clientIPAddress - * the clientIPAddress to set - * @return this - */ - public DHCP setClientIPAddress(final int clientIPAddress) { - this.clientIPAddress = clientIPAddress; - return this; - } - - /** - * @return the yourIPAddress - */ - public int getYourIPAddress() { - return this.yourIPAddress; - } - - /** - * @param yourIPAddress - * the yourIPAddress to set - * @return this - */ - public DHCP setYourIPAddress(final int yourIPAddress) { - this.yourIPAddress = yourIPAddress; - return this; - } - - /** - * @return the serverIPAddress - */ - public int getServerIPAddress() { - return this.serverIPAddress; - } - - /** - * @param serverIPAddress - * the serverIPAddress to set - * @return this - */ - public DHCP setServerIPAddress(final int serverIPAddress) { - this.serverIPAddress = serverIPAddress; - return this; - } - - /** - * @return the gatewayIPAddress - */ - public int getGatewayIPAddress() { - return this.gatewayIPAddress; - } - - /** - * @param gatewayIPAddress - * the gatewayIPAddress to set - * @return this - */ - public DHCP setGatewayIPAddress(final int gatewayIPAddress) { - this.gatewayIPAddress = gatewayIPAddress; - return this; - } - - /** - * @return the clientHardwareAddress - */ - public byte[] getClientHardwareAddress() { - return this.clientHardwareAddress; - } - - /** - * @param clientHardwareAddress - * the clientHardwareAddress to set - * @return this - */ - public DHCP setClientHardwareAddress(final byte[] clientHardwareAddress) { - this.clientHardwareAddress = clientHardwareAddress; - return this; - } - - /** - * Gets a specific DHCP option parameter. - * - * @param optionCode - * The option code to get - * @return The value of the option if it exists, null otherwise - */ - public DHCPOption getOption(final DHCPOptionCode optionCode) { - for (final DHCPOption opt : this.options) { - if (opt.code == optionCode.value) { - return opt; - } - } - return null; - } - - /** - * @return the options - */ - public List<DHCPOption> getOptions() { - return this.options; - } - - /** - * @param options - * the options to set - * @return this - */ - public DHCP setOptions(final List<DHCPOption> options) { - this.options = options; - return this; - } - - /** - * @return the packetType base on option 53 - */ - public DHCPPacketType getPacketType() { - final ListIterator<DHCPOption> lit = this.options.listIterator(); - while (lit.hasNext()) { - final DHCPOption option = lit.next(); - // only care option 53 - if (option.getCode() == 53) { - return DHCPPacketType.getType(option.getData()[0]); - } - } - return null; - } - - /** - * @return the serverName - */ - public String getServerName() { - return this.serverName; - } - - /** - * @param server - * the serverName to set - * @return this - */ - public DHCP setServerName(final String server) { - this.serverName = server; - return this; - } - - /** - * @return the bootFileName - */ - public String getBootFileName() { - return this.bootFileName; - } - - /** - * @param bootFile - * the bootFileName to set - * @return this - */ - public DHCP setBootFileName(final String bootFile) { - this.bootFileName = bootFile; - return this; - } - - @Override - public byte[] serialize() { - // not guaranteed to retain length/exact format - this.resetChecksum(); - - // minimum size 240 including magic cookie, options generally padded to - // 300 - int optionsLength = 0; - for (final DHCPOption option : this.options) { - if (option.getCode() == 0 || option.getCode() == ((byte) 255)) { - optionsLength += 1; - } else { - optionsLength += 2 + (0xff & option.getLength()); - } - } - int optionsPadLength = 0; - if (optionsLength < 60) { - optionsPadLength = 60 - optionsLength; - } - - final byte[] data = new byte[240 + optionsLength + optionsPadLength]; - final ByteBuffer bb = ByteBuffer.wrap(data); - bb.put(this.opCode); - bb.put(this.hardwareType); - bb.put(this.hardwareAddressLength); - bb.put(this.hops); - bb.putInt(this.transactionId); - bb.putShort(this.seconds); - bb.putShort(this.flags); - bb.putInt(this.clientIPAddress); - bb.putInt(this.yourIPAddress); - bb.putInt(this.serverIPAddress); - bb.putInt(this.gatewayIPAddress); - checkArgument(this.clientHardwareAddress.length <= 16, - "Hardware address is too long (%s bytes)", this.clientHardwareAddress.length); - bb.put(this.clientHardwareAddress); - if (this.clientHardwareAddress.length < 16) { - for (int i = 0; i < 16 - this.clientHardwareAddress.length; ++i) { - bb.put((byte) 0x0); - } - } - this.writeString(this.serverName, bb, 64); - this.writeString(this.bootFileName, bb, 128); - // magic cookie - bb.put((byte) 0x63); - bb.put((byte) 0x82); - bb.put((byte) 0x53); - bb.put((byte) 0x63); - for (final DHCPOption option : this.options) { - final int code = option.getCode() & 0xff; - bb.put((byte) code); - if (code != 0 && code != 255) { - bb.put(option.getLength()); - bb.put(option.getData()); - } - } - // assume the rest is padded out with zeroes - return data; - } - - @Override - public IPacket deserialize(final byte[] data, final int offset, - final int length) { - final ByteBuffer bb = ByteBuffer.wrap(data, offset, length); - if (bb.remaining() < DHCP.MIN_HEADER_LENGTH) { - return this; - } - - this.opCode = bb.get(); - this.hardwareType = bb.get(); - this.hardwareAddressLength = bb.get(); - this.hops = bb.get(); - this.transactionId = bb.getInt(); - this.seconds = bb.getShort(); - this.flags = bb.getShort(); - this.clientIPAddress = bb.getInt(); - this.yourIPAddress = bb.getInt(); - this.serverIPAddress = bb.getInt(); - this.gatewayIPAddress = bb.getInt(); - final int hardwareAddressLength = 0xff & this.hardwareAddressLength; - this.clientHardwareAddress = new byte[hardwareAddressLength]; - - bb.get(this.clientHardwareAddress); - for (int i = hardwareAddressLength; i < 16; ++i) { - bb.get(); - } - this.serverName = this.readString(bb, 64); - this.bootFileName = this.readString(bb, 128); - // read the magic cookie - // magic cookie - bb.get(); - bb.get(); - bb.get(); - bb.get(); - // read options - while (bb.hasRemaining()) { - final DHCPOption option = new DHCPOption(); - int code = 0xff & bb.get(); // convert signed byte to int in range - // [0,255] - option.setCode((byte) code); - if (code == 0) { - // skip these - continue; - } else if (code != 255) { - if (bb.hasRemaining()) { - final int l = 0xff & bb.get(); // convert signed byte to - // int in range [0,255] - option.setLength((byte) l); - if (bb.remaining() >= l) { - final byte[] optionData = new byte[l]; - bb.get(optionData); - option.setData(optionData); - } else { - // Skip the invalid option and set the END option - code = 0xff; - option.setCode((byte) code); - option.setLength((byte) 0); - } - } else { - // Skip the invalid option and set the END option - code = 0xff; - option.setCode((byte) code); - option.setLength((byte) 0); - } - } - this.options.add(option); - if (code == 255) { - // remaining bytes are supposed to be 0, but ignore them just in - // case - break; - } - } - - return this; - } - - protected void writeString(final String string, final ByteBuffer bb, - final int maxLength) { - if (string == null) { - for (int i = 0; i < maxLength; ++i) { - bb.put((byte) 0x0); - } - } else { - byte[] bytes = null; - try { - bytes = string.getBytes("ascii"); - } catch (final UnsupportedEncodingException e) { - throw new RuntimeException("Failure encoding server name", e); - } - int writeLength = bytes.length; - if (writeLength > maxLength) { - writeLength = maxLength; - } - bb.put(bytes, 0, writeLength); - for (int i = writeLength; i < maxLength; ++i) { - bb.put((byte) 0x0); - } - } - } - - private static String readString(final ByteBuffer bb, final int maxLength) { - final byte[] bytes = new byte[maxLength]; - bb.get(bytes); - String result = null; - try { - result = new String(bytes, "ascii").trim(); - } catch (final UnsupportedEncodingException e) { - throw new RuntimeException("Failure decoding string", e); - } - return result; - } - - /** - * Deserializer function for DHCP packets. - * - * @return deserializer function - */ - public static Deserializer<DHCP> deserializer() { - return (data, offset, length) -> { - checkInput(data, offset, length, MIN_HEADER_LENGTH); - - ByteBuffer bb = ByteBuffer.wrap(data, offset, length); - DHCP dhcp = new DHCP(); - - dhcp.opCode = bb.get(); - dhcp.hardwareType = bb.get(); - dhcp.hardwareAddressLength = bb.get(); - dhcp.hops = bb.get(); - dhcp.transactionId = bb.getInt(); - dhcp.seconds = bb.getShort(); - dhcp.flags = bb.getShort(); - dhcp.clientIPAddress = bb.getInt(); - dhcp.yourIPAddress = bb.getInt(); - dhcp.serverIPAddress = bb.getInt(); - dhcp.gatewayIPAddress = bb.getInt(); - final int hardwareAddressLength = 0xff & dhcp.hardwareAddressLength; - dhcp.clientHardwareAddress = new byte[hardwareAddressLength]; - - bb.get(dhcp.clientHardwareAddress); - for (int i = hardwareAddressLength; i < 16; ++i) { - bb.get(); - } - dhcp.serverName = readString(bb, 64); - dhcp.bootFileName = readString(bb, 128); - // read the magic cookie - // magic cookie - bb.get(); - bb.get(); - bb.get(); - bb.get(); - - // read options - boolean foundEndOptionsMarker = false; - while (bb.hasRemaining()) { - final DHCPOption option = new DHCPOption(); - int code = 0xff & bb.get(); // convert signed byte to int in range - // [0,255] - option.setCode((byte) code); - if (code == 0) { - // skip these - continue; - } else if (code != 255) { - if (bb.hasRemaining()) { - final int l = 0xff & bb.get(); // convert signed byte to - // int in range [0,255] - option.setLength((byte) l); - if (bb.remaining() >= l) { - final byte[] optionData = new byte[l]; - bb.get(optionData); - option.setData(optionData); - dhcp.options.add(option); - } else { - throw new DeserializationException( - "Buffer underflow while reading DHCP option"); - } - } - } else if (code == 255) { - DHCPOption end = new DHCPOption(); - end.setCode((byte) 255); - dhcp.options.add(end); - // remaining bytes are supposed to be 0, but ignore them just in - // case - foundEndOptionsMarker = true; - break; - } - } - - if (!foundEndOptionsMarker) { - throw new DeserializationException("DHCP End options marker was missing"); - } - - return dhcp; - }; - } -} |