dhcpd.java
来自「opennms得相关源码 请大家看看」· Java 代码 · 共 495 行 · 第 1/2 页
JAVA
495 行
//// This file is part of the OpenNMS(R) Application.//// OpenNMS(R) is Copyright (C) 2002-2003 The OpenNMS Group, Inc. All rights reserved.// OpenNMS(R) is a derivative work, containing both original code, included code and modified// code that was published under the GNU General Public License. Copyrights for modified // and included code are below.//// OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc.//// Modifications://// 2005 Jan 28: Added ability to listen on port 67 and/or 68// depending on config options// 2003 Jan 31: Cleaned up some unused imports.//// Original code base Copyright (C) 1999-2001 Oculan Corp. All rights reserved.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details. //// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // For more information contact: // OpenNMS Licensing <license@opennms.org>// http://www.opennms.org/// http://www.opennms.com///// Tab Stop = 8//package org.opennms.netmgt.dhcpd;import java.io.IOException;import java.io.InterruptedIOException;import java.lang.reflect.UndeclaredThrowableException;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.util.Collections;import java.util.LinkedList;import java.util.List;import java.util.Observable;import java.util.Observer;import org.apache.log4j.Category;import org.exolab.castor.xml.MarshalException;import org.exolab.castor.xml.ValidationException;import org.opennms.core.fiber.PausableFiber;import org.opennms.core.utils.ThreadCategory;import org.opennms.netmgt.config.DhcpdConfigFactory;import org.opennms.netmgt.utils.IpValidator;/** * <P> * The DHCP client daemon serves as a multiplexor for DHCP requests and * responses. The Bootp/DHCP protocol specifies that a DHCP server listens for * requests on local UDP/67 and will either send/broadcast responses to UDP/68 * or UDP/67 or will unicast responses back to the client's UDP port on from * which the request originated. * </p> * * <p> * The DHCP daemon accepts client connections on TCP/5818. Once a client is * connected it can begin forwarding requests. A list of all currently connected * clients is maintained. Requests have the following format: * </p> * <ul> * <li>byte 1 - byte 4 : 32-bit remote host IP address</li> * <li>byte 5 - byte 8 : 32-bit buffer length</li> * <li>byte 9 - byte n : buffer containing the formatted DHCP discover request. * </li> * </ul> * * <p> * The client indicates that it is finished by sending a request with the remote * host IP address set to zero (0). * </p> * * <p> * Incoming requests are sent to UDP/67 on specified remote host. If the remote * host is runnning a DHCP server it will send/broadcast an appropriate response * to UDP/68 or UDP/67 (or will unicast the response). * </p> * * <p> * The DHCP daemon includes a listener thread which binds to UDP/68 or UDP/67 * and simply listens for any incoming DHCP responses. In extended mode, * threads are started on both ports. When a datagram is received by the * listener thread(s) it loops through the list of currently connected clients * and forwards the DHCP response packet to each client. It is the responsibility * of the client to validate that the datagram is in response to a DHCP request * packet that it generated. * </p> * * @author <A HREF="mailto:mike@opennms.org">Mike </A> * @author <A HREF="http://www.opennms.org/">OpenNMS </A> * */public final class Dhcpd implements PausableFiber, Runnable, Observer { /** * Log4J prefix */ private static final String LOG4J_CATEGORY = "OpenNMS.Dhcpd"; /** * The singular instance of the DHCP server. */ private final static Dhcpd m_singleton = new Dhcpd(); /** * List of clients currently connected to the DHCP daemon */ private static List m_clients; /** * Socket over which the daemon actively listens for new client connection * requests. */ private ServerSocket m_server; /** * DHCP response port 67 listener. */ private Receiver m_listener; /** * DHCP response port 68 listener. */ private Receiver2 m_listener2; /** * The current status of the fiber. */ private int m_status; /** * The working thread */ private Thread m_worker; /** * Constructs a new DHCP server instance. All of the internal fields are * initialized to <code>null</code>. * */ private Dhcpd() { m_clients = null; m_server = null; m_listener = null; m_status = START_PENDING; m_worker = null; } /** * Starts the server instance. If the server is running then an exception is * thrown. Also, since the opening of sockets and other resources are * delayed until this method is invoked, standard exceptions are rethrown as * an {@link java.lang.reflect.UndeclaredThrowableExceptionundeclared * throwable}. * * @throws java.lang.IllegalStateException * Thrown if the server is already running. * * @throws java.lang.reflect.UndeclaredThrowableException * Thrown if a non-runtime exception is genereated during * startup. * */ public synchronized void start() { ThreadCategory.setPrefix(LOG4J_CATEGORY); Category log = ThreadCategory.getInstance(getClass()); boolean relayMode = false; if (log.isDebugEnabled()) log.debug("start: DHCP client daemon starting..."); m_status = STARTING; // Only allow start to be called once. // if (m_worker != null && m_worker.isAlive()) throw new IllegalStateException("The server is already running"); // Unless the worker has died, then stop // and continue. // if (m_worker != null) stop(); // the client list // m_clients = Collections.synchronizedList(new LinkedList()); // load the dhcpd configuration DhcpdConfigFactory dFactory = null; try { DhcpdConfigFactory.reload(); dFactory = DhcpdConfigFactory.getInstance(); } catch (MarshalException ex) { log.error("Failed to load dhcpd configuration", ex); throw new UndeclaredThrowableException(ex); } catch (ValidationException ex) { log.error("Failed to load dhcpd configuration", ex); throw new UndeclaredThrowableException(ex); } catch (IOException ex) { log.error("Failed to load dhcpd configuration", ex); throw new UndeclaredThrowableException(ex); } // open the server // try { if (log.isDebugEnabled()) log.debug("start: listening on TCP port " + dFactory.getPort() + " for incoming client requests."); m_server = new ServerSocket(dFactory.getPort()); } catch (IOException ex) { throw new UndeclaredThrowableException(ex); } // see if we have a valid relay address String myIpStr = DhcpdConfigFactory.getInstance().getMyIpAddress(); if (log.isDebugEnabled()) log.debug("Checking string \"" + myIpStr + "\" to see if we have an IP address"); if (myIpStr != null && !myIpStr.equals("") && !myIpStr.equalsIgnoreCase("broadcast")) { if(IpValidator.isIpValid(myIpStr)) { relayMode = true; } } if (log.isDebugEnabled()) log.debug("Setting relay mode " + relayMode); // open the receiver socket(s) // if(!relayMode || (dFactory.getExtendedMode() != null && dFactory.getExtendedMode().equalsIgnoreCase("true"))) { try { if (log.isDebugEnabled()) log.debug("start: starting receiver thread for port 68"); m_listener = new Receiver(m_clients); m_listener.start(); } catch (IOException ex) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?