Example #1
0
  /**
   * 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);
  }
  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;
  }
  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;
  }