/**
   * Process the set request
   *
   * @param rpc RpcPacket
   * @return RpcPacket
   */
  private final RpcPacket procSet(RpcPacket rpc) {

    //	Get the call parameters

    int progId = rpc.unpackInt();
    int verId = rpc.unpackInt();
    int proto = rpc.unpackInt();
    int port = rpc.unpackInt();

    //	DEBUG

    if (Debug.EnableInfo && hasDebug())
      Debug.println(
          "[PortMap] Set port program="
              + Rpc.getServiceName(progId)
              + ", version="
              + verId
              + ", protocol="
              + (proto == Rpc.TCP ? "TCP" : "UDP")
              + ", port="
              + port);

    //	Check if the port is already mapped

    PortMapping portMap = findPortMapping(progId, verId, proto);
    int portAdded = Rpc.False;

    if (portMap == null) {

      //	Add a mapping for the new service

      portMap = new PortMapping(progId, verId, proto, port);
      if (addPortMapping(portMap) == true) portAdded = Rpc.True;
    }

    //	Check if the service is on the same port as the current port mapping, and it is not
    //	an attempt to set the port mapper service port.

    else if (progId != PortMapper.ProgramId && portMap.getPort() == port) {

      //	Settings are the same as the existing service settings so accept it

      portAdded = Rpc.True;
    }

    //	Build the response header

    rpc.buildResponseHeader();

    //	Pack a boolean indicating if the port was added, or not

    rpc.packInt(portAdded);
    rpc.setLength();

    //	Return the response

    return rpc;
  }
  /**
   * Process the unset request
   *
   * @param rpc RpcPacket
   * @return RpcPacket
   */
  private final RpcPacket procUnSet(RpcPacket rpc) {

    //	Get the call parameters

    int progId = rpc.unpackInt();
    int verId = rpc.unpackInt();
    int proto = rpc.unpackInt();
    int port = rpc.unpackInt();

    //	DEBUG

    if (Debug.EnableInfo && hasDebug())
      Debug.println(
          "[PortMap] UnSet port program="
              + Rpc.getServiceName(progId)
              + ", version="
              + verId
              + ", protocol="
              + (proto == Rpc.TCP ? "TCP" : "UDP")
              + ", port="
              + port);

    //	Check if the port is mapped, and it is not an attempt to remove a portmapper portt

    PortMapping portMap = findPortMapping(progId, verId, proto);
    int portRemoved = Rpc.False;

    if (portMap != null && progId != PortMapper.ProgramId) {

      //	Remove the port mapping

      if (removePortMapping(portMap) == true) portRemoved = Rpc.True;
    }

    //	Build the response header

    rpc.buildResponseHeader();

    //	Pack a boolean indicating if the port was removed, or not

    rpc.packInt(portRemoved);
    rpc.setLength();

    //	Return the response

    return rpc;
  }
  /**
   * Process the get port request
   *
   * @param rpc RpcPacket
   * @return RpcPacket
   */
  private final RpcPacket procGetPort(RpcPacket rpc) {

    //	Get the call parameters

    int progId = rpc.unpackInt();
    int verId = rpc.unpackInt();
    int proto = rpc.unpackInt();

    //	Find the required port mapping

    PortMapping portMap = findPortMapping(progId, verId, proto);

    //	DEBUG

    if (Debug.EnableInfo && hasDebug())
      Debug.println(
          "[PortMap] Get port program="
              + Rpc.getServiceName(progId)
              + ", version="
              + verId
              + ", protocol="
              + (proto == Rpc.TCP ? "TCP" : "UDP")
              + ", port="
              + (portMap != null ? portMap.getPort() : 0));

    //	Build the response header

    rpc.buildResponseHeader();

    //	Pack the port number of the requested RPC service, or zero if not found

    rpc.packInt(portMap != null ? portMap.getPort() : 0);
    rpc.setLength();

    //	Return the response

    return rpc;
  }