blob: f6148c602398e22b089346abd6520dd367df00d5 [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;
/**
* 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>
* @version $Rev$, $Date$
*/
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 OPTION_CLASS_BY_CODE;
/**
* A map of tag codes indexed by OptionClass subclass.
*/
private static Map CODE_BY_CLASS;
static
{
try
{
// initialize the tag-to-class and class-to-tag map
Map classByCode = new HashMap();
Map codeByClass = new HashMap();
for ( int i = 0; i < OPTION_CLASSES.length; i++ )
{
Class c = OPTION_CLASSES[i];
if ( !DhcpOption.class.isAssignableFrom( c ) )
throw new RuntimeException( "Class " + c + " is not a descendant of DhcpOption" );
DhcpOption o = ( DhcpOption ) c.newInstance();
Integer tagInt = new Integer( o.getTag() );
classByCode.put( tagInt, c );
codeByClass.put( c, tagInt );
}
OPTION_CLASS_BY_CODE = Collections.unmodifiableMap( classByCode );
CODE_BY_CLASS = Collections.unmodifiableMap( codeByClass );
}
catch ( Exception e )
{
throw new RuntimeException( "Can't initialize option field classes", e );
}
}
public static Class getClassByTag( int tag )
{
return ( Class ) OPTION_CLASS_BY_CODE.get( new Integer( tag ) );
}
public static int getTagByClass( Class c )
{
return ( ( Integer ) CODE_BY_CLASS.get( c ) ).intValue();
}
/**
* 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( "Max data length: 128 bytes." );
out.put( ( byte ) data.length );
out.put( data );
}
}