use of org.opennms.netmgt.config.dhcpd.DhcpdConfigFactory in project opennms by OpenNMS.
the class Poller method isServer.
/**
* <p>
* This method actually tests the remote host to determine if it is
* running a functional DHCP server.
* </p>
* <p>
* Formats a DHCP query and encodes it in a client request message which
* is sent to the DHCP daemon over the established TCP socket connection.
* If a matching DHCP response packet is not received from the DHCP daemon
* within the specified timeout the client request message will be re-sent
* up to the specified number of retries.
* </p>
* <p>
* If a response is received from the DHCP daemon it is validated to
* ensure that:
* </p>
* <ul>
* <li>The DHCP response packet was sent from the remote host to which the
* original request packet was directed.</li>
* <li>The XID of the DHCP response packet matches the XID of the original
* DHCP request packet.</li>
* </ul>
* <p>
* If the response validates 'true' is returned. Otherwise the request is
* resent until max retry count is exceeded.
* </p>
* <p>
* Before returning, a client disconnect message (remote host field set to
* zero) is sent to the DHCP daemon.
* </p>
*
* @return response time in milliseconds if the specified host responded
* with a valid DHCP offer datagram within the context of the
* specified timeout and retry values or negative one (-1)
* otherwise.
*/
static long isServer(InetAddress host, long timeout, int retries) throws IOException {
boolean isDhcpServer = false;
// List of DHCP queries to try. The default when extended
// mode = false must be listed first. (DISCOVER)
byte[] typeList = { (byte) DHCPMessage.DISCOVER, (byte) DHCPMessage.INFORM, (byte) DHCPMessage.REQUEST };
String[] typeName = { "DISCOVER", "INFORM", "REQUEST" };
DhcpdConfigFactory dcf = DhcpdConfigFactory.getInstance();
if (!paramsChecked) {
String s_extendedMode = dcf.getExtendedMode();
if (s_extendedMode == null) {
extendedMode = false;
} else {
extendedMode = Boolean.parseBoolean(s_extendedMode);
}
LOG.debug("isServer: DHCP extended mode is {}", extendedMode);
String hwAddressStr = dcf.getMacAddress();
LOG.debug("isServer: DHCP query hardware/MAC address is {}", hwAddressStr);
setHwAddress(hwAddressStr);
String myIpStr = dcf.getMyIpAddress();
LOG.debug("isServer: DHCP relay agent address is {}", myIpStr);
if (myIpStr == null || myIpStr.equals("") || myIpStr.equalsIgnoreCase("broadcast")) {
// do nothing
} else {
try {
InetAddressUtils.toIpAddrBytes(myIpStr);
s_myIpAddress = setIpAddress(myIpStr);
relayMode = true;
} catch (IllegalArgumentException e) {
LOG.warn("isServer: DHCP relay agent address is invalid: {}", myIpStr);
}
}
if (extendedMode == true) {
String requestStr = dcf.getRequestIpAddress();
LOG.debug("isServer: REQUEST query target is {}", requestStr);
if (requestStr == null || requestStr.equals("") || requestStr.equalsIgnoreCase("targetSubnet")) {
// do nothing
} else if (requestStr.equalsIgnoreCase("targetHost")) {
targetOffset = false;
} else {
try {
InetAddressUtils.toIpAddrBytes(requestStr);
s_requestIpAddress = setIpAddress(requestStr);
reqTargetIp = false;
targetOffset = false;
} catch (IllegalArgumentException e) {
LOG.warn("isServer: REQUEST query target is invalid: {}", requestStr);
}
}
LOG.debug("REQUEST query options are: reqTargetIp = {}, targetOffset = {}", reqTargetIp, targetOffset);
}
paramsChecked = true;
}
int j = 1;
if (extendedMode == true) {
j = typeList.length;
}
if (timeout < 500) {
timeout = 500;
}
Poller p = new Poller(timeout);
long responseTime = -1;
try {
pollit: for (int i = 0; i < j; i++) {
Message ping = getPollingRequest(host, (byte) typeList[i]);
int rt = retries;
while (rt >= 0 && !isDhcpServer) {
LOG.debug("isServer: sending DHCP {} query to host {} with Xid: {}", typeName[i], InetAddressUtils.str(host), ping.getMessage().getXid());
long start = System.currentTimeMillis();
p.m_outs.writeObject(ping);
long end;
do {
Message resp = null;
try {
resp = (Message) p.m_ins.readObject();
} catch (InterruptedIOException ex) {
resp = null;
}
if (resp != null) {
responseTime = System.currentTimeMillis() - start;
// DEBUG only
LOG.debug("isServer: got a DHCP response from host {} with Xid: {}", InetAddressUtils.str(resp.getAddress()), resp.getMessage().getXid());
if (host.equals(resp.getAddress()) && ping.getMessage().getXid() == resp.getMessage().getXid()) {
// Inspect response message to see if it is a valid DHCP response
byte[] type = resp.getMessage().getOption(MESSAGE_TYPE);
if (type[0] == DHCPMessage.OFFER) {
LOG.debug("isServer: got a DHCP OFFER response, validating...");
} else if (type[0] == DHCPMessage.ACK) {
LOG.debug("isServer: got a DHCP ACK response, validating...");
} else if (type[0] == DHCPMessage.NAK) {
LOG.debug("isServer: got a DHCP NAK response, validating...");
}
// accept offer or ACK or NAK
if (type[0] == DHCPMessage.OFFER || (extendedMode == true && (type[0] == DHCPMessage.ACK || type[0] == DHCPMessage.NAK))) {
LOG.debug("isServer: got a valid DHCP response. responseTime= {}ms", responseTime);
isDhcpServer = true;
break pollit;
}
}
}
end = System.currentTimeMillis();
} while ((end - start) < timeout);
if (!isDhcpServer) {
LOG.debug("Timed out waiting for DHCP response, remaining retries: {}", rt);
}
--rt;
}
}
LOG.debug("Sending disconnect request");
p.m_outs.writeObject(getDisconnectRequest());
LOG.debug("wait half a sec before closing connection");
Thread.sleep(500);
p.close();
} catch (IOException ex) {
LOG.error("IO Exception caught.", ex);
p.close();
throw ex;
} catch (Throwable t) {
LOG.error("Unexpected Exception caught.", t);
p.close();
throw new UndeclaredThrowableException(t);
}
// server or -1 if the remote box is NOT a DHCP server.
if (isDhcpServer) {
return responseTime;
} else {
return -1;
}
}
use of org.opennms.netmgt.config.dhcpd.DhcpdConfigFactory in project opennms by OpenNMS.
the class Dhcpd method onStart.
/**
* <p>onStart</p>
*/
@Override
protected void onStart() {
boolean relayMode = false;
LOG.debug("start: DHCP client daemon 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<Client>());
// load the dhcpd configuration
DhcpdConfigFactory dFactory = null;
try {
DhcpdConfigFactory.reload();
dFactory = DhcpdConfigFactory.getInstance();
} catch (Exception ex) {
LOG.error("Failed to load dhcpd configuration", ex);
throw new UndeclaredThrowableException(ex);
}
//
try {
LOG.debug("start: listening on TCP port {} for incoming client requests.", dFactory.getPort());
m_server = new ServerSocket(dFactory.getPort(), 0, InetAddressUtils.addr("127.0.0.1"));
} catch (IOException ex) {
if (ex instanceof java.net.BindException) {
LOG.error("Failed to listen on DHCP port, perhaps something else is already listening?", ex);
LOG.error("Failed to listen on DHCP port, perhaps something else is already listening?", ex);
} else {
LOG.error("Failed to initialize DHCP socket", ex);
}
throw new UndeclaredThrowableException(ex);
}
// see if we have a valid relay address
String myIpStr = DhcpdConfigFactory.getInstance().getMyIpAddress();
LOG.debug("Checking string \"{}\" to see if we have an IP address", myIpStr);
if (myIpStr != null && !myIpStr.equals("") && !myIpStr.equalsIgnoreCase("broadcast")) {
try {
InetAddressUtils.toIpAddrBytes(myIpStr);
relayMode = true;
} catch (IllegalArgumentException e) {
LOG.warn("Invalid format for IP address: {}", myIpStr);
}
}
LOG.debug("Setting relay mode {}", relayMode);
// open the receiver socket(s)
if (!relayMode || (dFactory.getExtendedMode() != null && dFactory.getExtendedMode().equalsIgnoreCase("true"))) {
try {
LOG.debug("start: starting receiver thread for port 68");
m_listener = new Receiver(m_clients);
m_listener.start();
} catch (IOException ex) {
try {
m_server.close();
} catch (IOException ex1) {
}
throw new UndeclaredThrowableException(ex);
}
}
if (relayMode) {
try {
LOG.debug("start: starting receiver thread for port 67");
m_listener2 = new Receiver2(m_clients);
m_listener2.start();
} catch (IOException ex) {
try {
m_server.close();
} catch (IOException ex1) {
}
throw new UndeclaredThrowableException(ex);
}
}
m_worker = new Thread(this, getName());
m_worker.start();
}
Aggregations