Package org.apache.directory.server.dhcp.service

Source Code of org.apache.directory.server.dhcp.service.AbstractDhcpService

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you 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.service;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Iterator;

import org.apache.directory.server.dhcp.DhcpException;
import org.apache.directory.server.dhcp.messages.DhcpMessage;
import org.apache.directory.server.dhcp.messages.MessageType;
import org.apache.directory.server.dhcp.options.DhcpOption;
import org.apache.directory.server.dhcp.options.OptionsField;
import org.apache.directory.server.dhcp.options.dhcp.ParameterRequestList;
import org.apache.directory.server.dhcp.options.dhcp.ServerIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Abstract implementation of the server-side DHCP protocol. This class just
* provides some utility methods and dispatches server-bound messages to handler
* methods which can be overridden to provide the functionality.
* <p>
* Client-bound messages and BOOTP messages are ignored.
*
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev: 545042 $, $Date: 2007-06-06 22:32:01 -0500 (Mi, 06 Jun 2007) $
*
*/
public abstract class AbstractDhcpService implements DhcpService {
    private static final Logger logger = LoggerFactory
            .getLogger(AbstractDhcpService.class);

    /*
     * @see org.apache.directory.server.dhcp.DhcpService#getReplyFor(org.apache.directory.server.dhcp.messages.DhcpMessage)
     */
    public final DhcpMessage getReplyFor(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        // ignore messages with an op != REQUEST/REPLY
        if (request.getOp() != DhcpMessage.OP_BOOTREQUEST
                && request.getOp() != DhcpMessage.OP_BOOTREPLY)
            return null;

        // message type option MUST be set - we don't support plain BOOTP.
        if (null == request.getMessageType()) {
            logger.warn("Missing message type option - plain BOOTP not supported.");
            return null;
        }

        // dispatch based on the message type
        switch (request.getMessageType().getCode()){
            // client-to-server messages
            case MessageType.CODE_DHCPDISCOVER :
                return handleDISCOVER(localAddress, clientAddress, request);
            case MessageType.CODE_DHCPREQUEST :
                return handleREQUEST(localAddress, clientAddress, request);
            case MessageType.CODE_DHCPRELEASE :
                return handleRELEASE(localAddress, clientAddress, request);
            case MessageType.CODE_DHCPINFORM :
                return handleINFORM(localAddress, clientAddress, request);

            case MessageType.CODE_DHCPOFFER :
                return handleOFFER(localAddress, clientAddress, request);

                // server-to-client messages
            case MessageType.CODE_DHCPDECLINE :
            case MessageType.CODE_DHCPACK :
            case MessageType.CODE_DHCPNAK :
                return null; // just ignore them

            default :
                return handleUnknownMessage(clientAddress, request);
        }
    }

    /**
     * Handle unknown DHCP message. The default implementation just logs and
     * ignores it.
     *
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     */
    protected DhcpMessage handleUnknownMessage(InetSocketAddress clientAddress,
            DhcpMessage request) {
        if (logger.isWarnEnabled())
            logger.warn("Got unknkown DHCP message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPINFORM message. The default implementation just ignores it.
     *
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     */
    protected DhcpMessage handleINFORM(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger.debug("Got INFORM message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPRELEASE message. The default implementation just ignores it.
     *
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     */
    protected DhcpMessage handleRELEASE(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger.debug("Got RELEASE message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPREQUEST message. The default implementation just ignores it.
     *
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     */
    protected DhcpMessage handleREQUEST(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger.debug("Got REQUEST message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPDISCOVER message. The default implementation just ignores it.
     *
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     * @throws DhcpException
     */
    protected DhcpMessage handleDISCOVER(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger.debug("Got DISCOVER message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPOFFER message. The default implementation just ignores it.
     *
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     * @throws DhcpException
     */
    protected DhcpMessage handleOFFER(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger
                    .debug("Got OFFER message: " + request + " from:  " + clientAddress);
        return null;
    }

    /**
     * Initialize a general DHCP reply message. Sets:
     * <ul>
     * <li>op=BOOTREPLY
     * <li>htype, hlen, xid, flags, giaddr, chaddr like in request message
     * <li>hops, secs to 0.
     * <li>server hostname to the hostname appropriate for the interface the
     * request was received on
     * <li>the server identifier set to the address of the interface the request
     * was received on
     * </ul>
     *
     * @param localAddress
     * @param request
     * @return DhcpMessage
     */
    protected final DhcpMessage initGeneralReply(InetSocketAddress localAddress,
            DhcpMessage request) {
        final DhcpMessage reply = new DhcpMessage();

        reply.setOp(DhcpMessage.OP_BOOTREPLY);

        reply.setHardwareAddress(request.getHardwareAddress());
        reply.setTransactionId(request.getTransactionId());
        reply.setFlags(request.getFlags());
        reply.setRelayAgentAddress(request.getRelayAgentAddress());

        // set server hostname
        reply.setServerHostname(localAddress.getHostName());

        // set server identifier based on the IF on which we received the packet
        reply.getOptions().add(new ServerIdentifier(localAddress.getAddress()));

        return reply;
    }

    /**
     * Check if an address is the zero-address
     *
     * @param addr
     * @return boolean
     */
    private boolean isZeroAddress(byte[] addr) {
        for (int i = 0; i < addr.length; i++)
            if (addr[i] != 0)
                return false;
        return true;
    }

    /**
     * Determine address on which to base selection. If the relay agent address is
     * set, we use the relay agent's address, otherwise we use the address we
     * received the request from.
     *
     * @param clientAddress
     * @param request
     * @return InetAddress
     */
    protected final InetAddress determineSelectionBase(
            InetSocketAddress clientAddress, DhcpMessage request) {
        // FIXME: do we know
        // a) the interface address over which we received a message (!)
        // b) the client address (if specified)
        // c) the relay agent address?

        // if the relay agent address is set, we use it as the selection base
        if (!isZeroAddress(request.getRelayAgentAddress().getAddress()))
            return request.getRelayAgentAddress();

        return clientAddress.getAddress();
    }

    /**
     * Strip options that the client doesn't want, if the ParameterRequestList
     * option is present.
     *
     * @param request
     * @param options
     */
    protected final void stripUnwantedOptions(DhcpMessage request,
            OptionsField options) {
        final ParameterRequestList prl = (ParameterRequestList) request
                .getOptions().get(ParameterRequestList.class);
        if (null != prl) {
            final byte[] list = prl.getData();
            for (final Iterator i = options.iterator(); i.hasNext();) {
                final DhcpOption o = (DhcpOption) i.next();
                for (int j = 0; j < list.length; j++)
                    if (list[j] == o.getTag())
                        continue;
                i.remove();
            }
        }
    }
}
TOP

Related Classes of org.apache.directory.server.dhcp.service.AbstractDhcpService

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.