blob: 970be462ee17defc65a68cda1120626c0fc834f6 [file] [log] [blame]
/*
* Copyright 2005 The Apache Software Foundation
*
* 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.apache.directory.server.dhcp.options;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.directory.server.dhcp.options.dhcp.BootfileName;
import org.apache.directory.server.dhcp.options.dhcp.ClientIdentifier;
import org.apache.directory.server.dhcp.options.dhcp.DhcpMessageType;
import org.apache.directory.server.dhcp.options.dhcp.IpAddressLeaseTime;
import org.apache.directory.server.dhcp.options.dhcp.MaximumDhcpMessageSize;
import org.apache.directory.server.dhcp.options.dhcp.OptionOverload;
import org.apache.directory.server.dhcp.options.dhcp.ParameterRequestList;
import org.apache.directory.server.dhcp.options.dhcp.RebindingTimeValue;
import org.apache.directory.server.dhcp.options.dhcp.RenewalTimeValue;
import org.apache.directory.server.dhcp.options.dhcp.RequestedIpAddress;
import org.apache.directory.server.dhcp.options.dhcp.ServerIdentifier;
import org.apache.directory.server.dhcp.options.dhcp.TftpServerName;
import org.apache.directory.server.dhcp.options.dhcp.UnrecognizedOption;
import org.apache.directory.server.dhcp.options.dhcp.VendorClassIdentifier;
import org.apache.directory.server.dhcp.options.misc.DefaultFingerServers;
import org.apache.directory.server.dhcp.options.misc.DefaultIrcServers;
import org.apache.directory.server.dhcp.options.misc.DefaultWwwServers;
import org.apache.directory.server.dhcp.options.misc.MobileIpHomeAgents;
import org.apache.directory.server.dhcp.options.misc.NbddServers;
import org.apache.directory.server.dhcp.options.misc.NetbiosNameServers;
import org.apache.directory.server.dhcp.options.misc.NetbiosNodeType;
import org.apache.directory.server.dhcp.options.misc.NetbiosScope;
import org.apache.directory.server.dhcp.options.misc.NisDomain;
import org.apache.directory.server.dhcp.options.misc.NisPlusDomain;
import org.apache.directory.server.dhcp.options.misc.NisPlusServers;
import org.apache.directory.server.dhcp.options.misc.NisServers;
import org.apache.directory.server.dhcp.options.misc.NntpServers;
import org.apache.directory.server.dhcp.options.misc.NtpServers;
import org.apache.directory.server.dhcp.options.misc.Pop3Servers;
import org.apache.directory.server.dhcp.options.misc.SmtpServers;
import org.apache.directory.server.dhcp.options.misc.StdaServers;
import org.apache.directory.server.dhcp.options.misc.StreetTalkServers;
import org.apache.directory.server.dhcp.options.misc.VendorSpecificInformation;
import org.apache.directory.server.dhcp.options.misc.XWindowDisplayManagers;
import org.apache.directory.server.dhcp.options.misc.XWindowFontServers;
import org.apache.directory.server.dhcp.options.perhost.DefaultIpTimeToLive;
import org.apache.directory.server.dhcp.options.perhost.IpForwarding;
import org.apache.directory.server.dhcp.options.perhost.MaximumDatagramSize;
import org.apache.directory.server.dhcp.options.perhost.NonLocalSourceRouting;
import org.apache.directory.server.dhcp.options.perhost.PathMtuAgingTimeout;
import org.apache.directory.server.dhcp.options.perhost.PathMtuPlateauTable;
import org.apache.directory.server.dhcp.options.perhost.PolicyFilter;
import org.apache.directory.server.dhcp.options.perinterface.AllSubnetsAreLocal;
import org.apache.directory.server.dhcp.options.perinterface.BroadcastAddress;
import org.apache.directory.server.dhcp.options.perinterface.InterfaceMtu;
import org.apache.directory.server.dhcp.options.perinterface.MaskSupplier;
import org.apache.directory.server.dhcp.options.perinterface.PerformMaskDiscovery;
import org.apache.directory.server.dhcp.options.perinterface.PerformRouterDiscovery;
import org.apache.directory.server.dhcp.options.perinterface.RouterSolicitationAddress;
import org.apache.directory.server.dhcp.options.perinterface.StaticRoute;
import org.apache.directory.server.dhcp.options.tcp.TcpDefaultTimeToLive;
import org.apache.directory.server.dhcp.options.tcp.TcpKeepaliveGarbage;
import org.apache.directory.server.dhcp.options.tcp.TcpKeepaliveInterval;
import org.apache.directory.server.dhcp.options.vendor.BootFileSize;
import org.apache.directory.server.dhcp.options.vendor.CookieServers;
import org.apache.directory.server.dhcp.options.vendor.DomainName;
import org.apache.directory.server.dhcp.options.vendor.DomainNameServers;
import org.apache.directory.server.dhcp.options.vendor.ExtensionsPath;
import org.apache.directory.server.dhcp.options.vendor.HostName;
import org.apache.directory.server.dhcp.options.vendor.ImpressServers;
import org.apache.directory.server.dhcp.options.vendor.LogServers;
import org.apache.directory.server.dhcp.options.vendor.LprServers;
import org.apache.directory.server.dhcp.options.vendor.MeritDumpFile;
import org.apache.directory.server.dhcp.options.vendor.NameServers;
import org.apache.directory.server.dhcp.options.vendor.ResourceLocationServers;
import org.apache.directory.server.dhcp.options.vendor.RootPath;
import org.apache.directory.server.dhcp.options.vendor.Routers;
import org.apache.directory.server.dhcp.options.vendor.SubnetMask;
import org.apache.directory.server.dhcp.options.vendor.SwapServer;
import org.apache.directory.server.dhcp.options.vendor.TimeOffset;
import org.apache.directory.server.dhcp.options.vendor.TimeServers;
import org.apache.directory.server.i18n.I18n;
/**
* The Dynamic Host Configuration Protocol (DHCP) provides a framework
* for passing configuration information to hosts on a TCP/IP network.
* Configuration parameters and other control information are carried in
* tagged data items that are stored in the 'options' field of the DHCP
* message. The data items themselves are also called "options."
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
*/
public abstract class DhcpOption
{
/**
* An array of concrete implementations of DhcpOption.
*/
private static Class<?> OPTION_CLASSES[] =
{
BootfileName.class,
ClientIdentifier.class,
DhcpMessageType.class,
IpAddressLeaseTime.class,
MaximumDhcpMessageSize.class,
org.apache.directory.server.dhcp.options.dhcp.Message.class,
OptionOverload.class,
ParameterRequestList.class,
RebindingTimeValue.class,
RenewalTimeValue.class,
RequestedIpAddress.class,
ServerIdentifier.class,
TftpServerName.class,
VendorClassIdentifier.class,
ClientIdentifier.class,
DhcpMessageType.class,
IpAddressLeaseTime.class,
MaximumDhcpMessageSize.class,
OptionOverload.class,
ParameterRequestList.class,
RebindingTimeValue.class,
RenewalTimeValue.class,
RequestedIpAddress.class,
ServerIdentifier.class,
TftpServerName.class,
UnrecognizedOption.class,
VendorClassIdentifier.class,
DefaultFingerServers.class,
DefaultIrcServers.class,
DefaultWwwServers.class,
MobileIpHomeAgents.class,
NbddServers.class,
NetbiosNameServers.class,
NetbiosNodeType.class,
NetbiosScope.class,
NisDomain.class,
NisPlusDomain.class,
NisPlusServers.class,
NisServers.class,
NntpServers.class,
NtpServers.class,
Pop3Servers.class,
SmtpServers.class,
StdaServers.class,
StreetTalkServers.class,
VendorSpecificInformation.class,
XWindowDisplayManagers.class,
XWindowFontServers.class,
DefaultIpTimeToLive.class,
IpForwarding.class,
MaximumDatagramSize.class,
NonLocalSourceRouting.class,
PathMtuAgingTimeout.class,
PathMtuPlateauTable.class,
PolicyFilter.class,
AllSubnetsAreLocal.class,
BroadcastAddress.class,
InterfaceMtu.class,
MaskSupplier.class,
PerformMaskDiscovery.class,
PerformRouterDiscovery.class,
RouterSolicitationAddress.class,
StaticRoute.class,
TcpDefaultTimeToLive.class,
TcpKeepaliveGarbage.class,
TcpKeepaliveInterval.class,
BootFileSize.class,
CookieServers.class,
DomainName.class,
DomainNameServers.class,
ExtensionsPath.class,
HostName.class,
ImpressServers.class,
LogServers.class,
LprServers.class,
MeritDumpFile.class,
NameServers.class,
ResourceLocationServers.class,
RootPath.class, Routers.class,
SubnetMask.class,
SwapServer.class,
TimeOffset.class,
TimeServers.class, };
/**
* A map of concrete implementations of DhcpOption indexed by tag code.
*/
private static Map<Integer, Class<?>> OPTION_CLASS_BY_CODE;
/**
* A map of tag codes indexed by OptionClass subclass.
*/
private static Map<Class<?>, Integer> CODE_BY_CLASS;
static
{
try
{
// initialize the tag-to-class and class-to-tag map
Map<Integer, Class<?>> classByCode = new HashMap<Integer, Class<?>>();
Map<Class<?>, Integer> codeByClass = new HashMap<Class<?>, Integer>();
for ( int i = 0; i < OPTION_CLASSES.length; i++ )
{
Class<?> dhcpOptionClass = OPTION_CLASSES[i];
if ( !DhcpOption.class.isAssignableFrom( dhcpOptionClass ) )
{
throw new RuntimeException( I18n.err( I18n.ERR_639, dhcpOptionClass ) );
}
DhcpOption dhcpOption = ( DhcpOption ) dhcpOptionClass.newInstance();
int tagInt = dhcpOption.getTag();
classByCode.put( tagInt, dhcpOptionClass );
codeByClass.put( dhcpOptionClass, tagInt );
}
OPTION_CLASS_BY_CODE = Collections.unmodifiableMap( classByCode );
CODE_BY_CLASS = Collections.unmodifiableMap( codeByClass );
}
catch ( Exception e )
{
throw new RuntimeException( I18n.err( I18n.ERR_640 ), e );
}
}
public static Class<?> getClassByTag( int tag )
{
return OPTION_CLASS_BY_CODE.get( tag );
}
public static int getTagByClass( Class<?> c )
{
return CODE_BY_CLASS.get( c );
}
/**
* The default data array used for simple (unparsed) options.
*/
private byte[] data;
/**
* Get the option's code tag.
*
* @return byte
*/
public abstract byte getTag();
/**
* Set the data (wire format) from a byte array. The default implementation
* just records the data as a byte array. Subclasses may parse the data into
* something more meaningful.
*
* @param data
*/
public void setData( byte data[] )
{
this.data = data;
}
/**
* Get the data (wire format) into a byte array. Subclasses must provide an
* implementation which serializes the parsed data back into a byte array if
* they override {@link #setData(byte[])}.
*
* @return byte[]
*/
public byte[] getData()
{
return data;
}
public final void writeTo( ByteBuffer out )
{
out.put( getTag() );
// FIXME: handle continuation, i.e. options longer than 128 bytes?
byte data[] = getData();
if ( data.length > 255 )
{
throw new IllegalArgumentException( I18n.err( I18n.ERR_641 ) );
}
out.put( ( byte ) data.length );
out.put( data );
}
}