/**
   * Process an RPC request
   *
   * @param rpc RpcPacket
   * @return RpcPacket
   * @throws IOException
   */
  public RpcPacket processRpc(RpcPacket rpc) throws IOException {

    //	Validate the request

    if (rpc.getProgramId() != PortMapper.ProgramId) {

      //	Request is not for us

      rpc.buildAcceptErrorResponse(Rpc.StsProgUnavail);
      return rpc;
    } else if (rpc.getProgramVersion() != PortMapper.VersionId) {

      //	Request is not for this version of portmapper

      rpc.buildProgramMismatchResponse(PortMapper.VersionId, PortMapper.VersionId);
      return rpc;
    }

    //	Position the RPC buffer pointer at the start of the call parameters

    rpc.positionAtParameters();

    //	Process the RPC request

    RpcPacket response = null;

    switch (rpc.getProcedureId()) {

        //	Null request

      case PortMapper.ProcNull:
        response = procNull(rpc);
        break;

        //	Set a port

      case PortMapper.ProcSet:
        response = procSet(rpc);
        break;

        //	Release a port

      case PortMapper.ProcUnSet:
        response = procUnSet(rpc);
        break;

        //	Get the port for a service

      case PortMapper.ProcGetPort:
        response = procGetPort(rpc);
        break;

        //	Dump ports request

      case PortMapper.ProcDump:
        response = procDump(rpc);
        break;
    }

    //	Return the RPC response

    return response;
  }