private boolean checkOffer(DHCPMessage discoverReply, int xid) { byte replType[] = new byte[1]; replType = discoverReply.getOption(53); if (replType[0] != 2) { return false; } if (discoverReply.getXid() != xid) { return false; } String offered = ipToString(discoverReply.getYiaddr()); String requested = IP; if (IP.length() > 0 && !offered.equals(requested)) { lastError = (new StringBuilder()) .append("Requested address (") .append(IP) .append(") unavailable") .toString(); unavailable = true; return false; } else { return true; } }
private boolean sendMessage( String status, DHCPMessage outMessage, DHCPSocket socket, int xid, int type, byte offeredAddr[]) { if (type == 3) outMessage.setOption(50, offeredAddr); return sendMessage(status, outMessage, socket, xid, type); }
private Object[] acquireAddress(int xid, byte hwaddr[], int sleepTime) { Object results[] = new Object[5]; results[0] = "n/a"; results[1] = String.valueOf(0); results[2] = "error"; results[3] = "no data"; results[4] = "no data"; int releaseTime = -1; DHCPSocket socket = null; DHCPMessage outMessage = new DHCPMessage(); DHCPMessage replyMessage = new DHCPMessage(); byte offeredAddr[] = new byte[4]; byte backupAddr[] = new byte[4]; Random r = new Random(); if ((socket = openSocket(socket)) == null) { results[3] = results[4] = lastError; return results; } outMessage.setChaddr(hwaddr); if (IP.length() > 0) { outMessage.setOption(50, stringToIP(IP)); } for (int i = 0; i < 10; i++) { if (!sendMessage(lastError, outMessage, socket, xid, 1)) { results[3] = results[4] = lastError; socket.close(); return results; } try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } if (socket.receive(replyMessage)) { if (checkOffer(replyMessage, xid)) { offeredAddr = replyMessage.getYiaddr(); System.arraycopy(offeredAddr, 0, backupAddr, 0, 4); break; } if (unavailable) { results[3] = results[4] = lastError; socket.close(); return results; } } if (i == 9) { results[3] = results[4] = "Timed out waiting for DHCPOFFER"; socket.close(); return results; } } releaseTime = 1; outMessage.setOption(54, replyMessage.getOption(54)); sendMessage(lastError, outMessage, socket, xid, 3, offeredAddr); if (!socket.receive(replyMessage)) { results[3] = results[4] = "Timed out waiting for DHCPACK"; socket.close(); return results; } if (replyMessage.getXid() != xid) { results[3] = results[4] = "Received invalid DHCPACK from server"; socket.close(); return results; } try { Thread.sleep(1000); } catch (InterruptedException e) { } outMessage.setCiaddr(backupAddr); outMessage.setOption(50, new byte[4]); outMessage.setOption(51, new byte[4]); outMessage.setOption(54, replyMessage.getOption(54)); sendMessage(lastError, outMessage, socket, r.nextInt(), 7); socket.close(); long totalDuration = System.currentTimeMillis() - startTime; String stateString = (new StringBuilder()).append("leased address ").append(ipToString(backupAddr)).toString(); String duration = (float) totalDuration / 1000F + " sec"; results[0] = results[1] = duration; results[2] = "ok"; results[3] = (new StringBuilder()).append("leased address ").append(ipToString(backupAddr)).toString(); results[4] = stateString; return results; }
private boolean sendMessage( String status, DHCPMessage outMessage, DHCPSocket socket, int xid, int type) { outMessage.setOp((byte) 1); outMessage.setHtype((byte) 1); outMessage.setHlen((byte) 6); outMessage.setHops((byte) 0); outMessage.setXid(xid); outMessage.setSecs((short) 0); if (type == 1 || type == 3) { outMessage.setFlags((short) -32768); } else { outMessage.setFlags((short) 0); } byte initAddr[] = new byte[4]; for (int i = 0; i < 4; i++) initAddr[i] = 0; outMessage.setCiaddr(initAddr); outMessage.setYiaddr(initAddr); outMessage.setSiaddr(initAddr); outMessage.setGiaddr(initAddr); byte mtype[] = new byte[1]; mtype[0] = (byte) type; outMessage.setOption(53, mtype); outMessage.setOption(51, intToBytes(1)); try { socket.send(outMessage); } catch (IOException ie) { status = ie.getMessage(); return false; } return true; }
/** * Returns a DHCP DISCOVER, INFORM, or REQUEST message that can be sent to the DHCP server. DHCP * server should respond with a DHCP OFFER, ACK, or NAK message in response.. * * @param (InetAddress) addr The address to poll * @param (byte) mType The type of DHCP message to send (DISCOVER, INFORM, or REQUEST) * @return The message to send to the DHCP server. */ private static Message getPollingRequest(InetAddress addr, byte mType) { int xid = 0; synchronized (Poller.class) { xid = ++m_nextXid; } DHCPMessage messageOut = new DHCPMessage(); byte[] rawIp = addr.getAddress(); // if targetOffset = true, we don't want to REQUEST the DHCP server's // own IP, so change it by 1, trying to avoid the subnet address // and the broadcast address. if (targetOffset) { if (rawIp[3] % 2 == 0 && rawIp[3] != 0) { --rawIp[3]; } else { ++rawIp[3]; } } // fill DHCPMessage object // messageOut.setOp((byte) 1); messageOut.setHtype((byte) 1); messageOut.setHlen((byte) 6); messageOut.setXid(xid); messageOut.setSecs((short) 0); messageOut.setChaddr(s_hwAddress); // set hardware address if (relayMode) { messageOut.setHops((byte) 1); messageOut.setGiaddr(s_myIpAddress); // set relay address for replies } else { messageOut.setHops((byte) 0); messageOut.setFlags(BROADCAST_FLAG); } messageOut.setOption(MESSAGE_TYPE, new byte[] {mType}); if (mType == DHCPMessage.REQUEST) { if (reqTargetIp) { messageOut.setOption(REQUESTED_IP, rawIp); messageOut.setCiaddr(rawIp); } else { messageOut.setOption(REQUESTED_IP, s_requestIpAddress); messageOut.setCiaddr(s_requestIpAddress); } } if (mType == DHCPMessage.INFORM) { messageOut.setOption(REQUESTED_IP, s_myIpAddress); messageOut.setCiaddr(s_myIpAddress); } return new Message(addr, messageOut); }