code:
/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// clang-format off
// Dont't remove `format off`, it prevent reordering of win-includes.

#  define _POSIX_C_SOURCE 200809L
#  define _XOPEN_SOURCE 700L

#ifdef _WIN32
#  ifndef WIN32_LEAN_AND_MEAN
#    define WIN32_LEAN_AND_MEAN
#  endif
#  ifndef NOMINMAX
#    define NOMINMAX
#  endif
#  ifdef _MSC_VER
#    include <crtdbg.h>
#  endif
#  include <windows.h>  // Must be included before <direct.h>
#  include <direct.h>
#  include <winbase.h>
#  undef interface  // This is also important because of reasons
#endif
// clang-format on

#include "flatbuffers/base.h"
#include "flatbuffers/util.h"

#include <sys/stat.h>
#include <clocale>
#include <cstdlib>
#include <fstream>

namespace flatbuffers {

bool FileExistsRaw(const char *name) {
  std::ifstream ifs(name);
  return ifs.good();
}

bool LoadFileRaw(const char *name, bool binary, std::string *buf) {
  if (DirExists(name)) return false;
  std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in);
  if (!ifs.is_open()) return false;
  if (binary) {
    // The fastest way to read a file into a string.
    ifs.seekg(0, std::ios::end);
    auto size = ifs.tellg();
    (*buf).resize(static_cast<size_t>(size));
    ifs.seekg(0, std::ios::beg);
    ifs.read(&(*buf)[0], (*buf).size());
  } else {
    // This is slower, but works correctly on all platforms for text files.
    std::ostringstream oss;
    oss << ifs.rdbuf();
    *buf = oss.str();
  }
  return !ifs.bad();
}

static LoadFileFunction g_load_file_function = LoadFileRaw;
static FileExistsFunction g_file_exists_function = FileExistsRaw;

bool LoadFile(const char *name, bool binary, std::string *buf) {
  FLATBUFFERS_ASSERT(g_load_file_function);
  return g_load_file_function(name, binary, buf);
}

bool FileExists(const char *name) {
  FLATBUFFERS_ASSERT(g_file_exists_function);
  return g_file_exists_function(name);
}

bool DirExists(const char *name) {
  // clang-format off

  #ifdef _WIN32
    #define flatbuffers_stat _stat
    #define FLATBUFFERS_S_IFDIR _S_IFDIR
  #else
    #define flatbuffers_stat stat
    #define FLATBUFFERS_S_IFDIR S_IFDIR
  #endif
  // clang-format on
  struct flatbuffers_stat file_info;
  if (flatbuffers_stat(name, &file_info) != 0) return false;
  return (file_info.st_mode & FLATBUFFERS_S_IFDIR) != 0;
}

LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function) {
  LoadFileFunction previous_function = g_load_file_function;
  g_load_file_function = load_file_function ? load_file_function : LoadFileRaw;
  return previous_function;
}

FileExistsFunction SetFileExistsFunction(
    FileExistsFunction file_exists_function) {
  FileExistsFunction previous_function = g_file_exists_function;
  g_file_exists_function =
      file_exists_function ? file_exists_function : FileExistsRaw;
  return previous_function;
}

bool SaveFile(const char *name, const char *buf, size_t len, bool binary) {
  std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out);
  if (!ofs.is_open()) return false;
  ofs.write(buf, len);
  return !ofs.bad();
}

// We internally store paths in posix format ('/'). Paths supplied
// by the user should go through PosixPath to ensure correct behavior
// on Windows when paths are string-compared.

static const char kPathSeparatorWindows = '\\';
static const char *PathSeparatorSet = "\\/";  // Intentionally no ':'

std::string StripExtension(const std::string &filepath) {
  size_t i = filepath.find_last_of('.');
  return i != std::string::npos ? filepath.substr(0, i) : filepath;
}

std::string GetExtension(const std::string &filepath) {
  size_t i = filepath.find_last_of('.');
  return i != std::string::npos ? filepath.substr(i + 1) : "";
}

std::string StripPath(const std::string &filepath) {
  size_t i = filepath.find_last_of(PathSeparatorSet);
  return i != std::string::npos ? filepath.substr(i + 1) : filepath;
}

std::string StripFileName(const std::string &filepath) {
  size_t i = filepath.find_last_of(PathSeparatorSet);
  return i != std::string::npos ? filepath.substr(0, i) : "";
}

std::string ConCatPathFileName(const std::string &path,
                               const std::string &filename) {
  std::string filepath = path;
  if (filepath.length()) {
    char &filepath_last_character = string_back(filepath);
    if (filepath_last_character == kPathSeparatorWindows) {
      filepath_last_character = kPathSeparator;
    } else if (filepath_last_character != kPathSeparator) {
      filepath += kPathSeparator;
    }
  }
  filepath += filename;
  // Ignore './' at the start of filepath.
  if (filepath[0] == '.' && filepath[1] == kPathSeparator) {
    filepath.erase(0, 2);
  }
  return filepath;
}

std::string PosixPath(const char *path) {
  std::string p = path;
  std::replace(p.begin(), p.end(), '\\', '/');
  return p;
}

void EnsureDirExists(const std::string &filepath) {
  auto parent = StripFileName(filepath);
  if (parent.length()) EnsureDirExists(parent);
    // clang-format off

  #ifdef _WIN32
    (void)_mkdir(filepath.c_str());
  #else
    mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP);
  #endif
  // clang-format on
}

std::string AbsolutePath(const std::string &filepath) {
  // clang-format off

  #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
    return filepath;
  #else
    #ifdef _WIN32
      char abs_path[MAX_PATH];
      return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path, nullptr)
    #else
      char *abs_path_temp = realpath(filepath.c_str(), nullptr);
      bool success = abs_path_temp != nullptr;
      std::string abs_path;
      if(success) {
        abs_path = abs_path_temp;
        free(abs_path_temp);
      }
      return success
    #endif
      ? abs_path
      : filepath;
  #endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
  // clang-format on
}

// Locale-independent code.
#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && \
    (FLATBUFFERS_LOCALE_INDEPENDENT > 0)

// clang-format off
// Allocate locale instance at startup of application.
ClassicLocale ClassicLocale::instance_;

#ifdef _MSC_VER
  ClassicLocale::ClassicLocale()
    : locale_(_create_locale(LC_ALL, "C")) {}
  ClassicLocale::~ClassicLocale() { _free_locale(locale_); }
#else
  ClassicLocale::ClassicLocale()
    : locale_(newlocale(LC_ALL, "C", nullptr)) {}
  ClassicLocale::~ClassicLocale() { freelocale(locale_); }
#endif
// clang-format on

#endif  // !FLATBUFFERS_LOCALE_INDEPENDENT

std::string RemoveStringQuotes(const std::string &s) {
  auto ch = *s.c_str();
  return ((s.size() >= 2) && (ch == '\"' || ch == '\'') &&
          (ch == string_back(s)))
             ? s.substr(1, s.length() - 2)
             : s;
}

bool SetGlobalTestLocale(const char *locale_name, std::string *_value) {
  const auto the_locale = setlocale(LC_ALL, locale_name);
  if (!the_locale) return false;
  if (_value) *_value = std::string(the_locale);
  return true;
}

bool ReadEnvironmentVariable(const char *var_name, std::string *_value) {
#ifdef _MSC_VER
  __pragma(warning(disable : 4996));  // _CRT_SECURE_NO_WARNINGS
#endif
  auto env_str = std::getenv(var_name);
  if (!env_str) return false;
  if (_value) *_value = std::string(env_str);
  return true;
}

void SetupDefaultCRTReportMode() {
  // clang-format off

  #ifdef _MSC_VER
    // By default, send all reports to STDOUT to prevent CI hangs.
    // Enable assert report box [Abort|Retry|Ignore] if a debugger is present.
    const int dbg_mode = (_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG) |
                         (IsDebuggerPresent() ? _CRTDBG_MODE_WNDW : 0);
    (void)dbg_mode; // release mode fix
    // CrtDebug reports to _CRT_WARN channel.
    _CrtSetReportMode(_CRT_WARN, dbg_mode);
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
    // The assert from <assert.h> reports to _CRT_ERROR channel
    _CrtSetReportMode(_CRT_ERROR, dbg_mode);
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
    // Internal CRT assert channel?
    _CrtSetReportMode(_CRT_ASSERT, dbg_mode);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
  #endif

  // clang-format on
}

}  // namespace flatbuffers

repo_name: veiledmerc/mira

license: mit


code:
#include "Connection.hpp"

#include <Daemon.hpp>
#include <Rpc/Manager.hpp>

#include <cstdio>
#include <vector>
#include <array>

#include <External/flatbuffers/rpc_generated.h>

extern "C"
{
    #include <sys/socket.h>
    #include <unistd.h>
};

using namespace Mira::Rpc;

Connection::Connection(Rpc::Server* p_Server, uint32_t p_ClientId, int32_t p_Socket, struct sockaddr_in& p_Address) :
    m_Socket(p_Socket),
    m_ClientId(p_ClientId),
    m_Running(false),
    m_Thread(-1),
    m_Address { 0 },
    m_Server(p_Server)
{
    memcpy(&m_Address, &p_Address, sizeof(m_Address));
}

Connection::~Connection()
{
    auto s_Ret = 0;

    // Close the socket
    do
    {
        if (m_Socket == -1)
            break;

        s_Ret = shutdown(m_Socket, SHUT_RDWR);
        if (s_Ret != 0)
        {
            fprintf(stderr, "err: could not shutdown socket (%d).\n", s_Ret);
            break;
        }

        s_Ret = close(m_Socket);
        if (s_Ret != 0)
        {
            fprintf(stderr, "err: could not close socket (%d).\n", s_Ret);
            break;
        }
    } while (false);

    // Cancel the thread if needed
    do
    {
        void* s_RetVal = nullptr;

        // Check the thread
        if (m_Thread == -1)
            break;

        // Cancel the thread
        s_Ret = scePthreadCancel(m_Thread);
        if (s_Ret != 0)
        {
            fprintf(stderr, "err: cancel connection thread returned (%d).\n", s_Ret);
            break;
        }

        // Wait for the thread to exit
        s_Ret = scePthreadJoin(m_Thread, &s_RetVal);
        if (s_Ret != 0)
        {
            fprintf(stderr, "err: could not join thread (%lu) ret (%d).\n", m_Thread, s_Ret);
            break;
        }
    } while (false);
}

void Connection::Disconnect()
{
    m_Running = false;
}

void* Connection::ConnectionThread(void* p_ConnectionInstance)
{
    auto s_Connection = static_cast<Connection*>(p_ConnectionInstance);
    if (s_Connection == nullptr)
        return nullptr;

    auto s_Socket = s_Connection->GetSocket();
    if (s_Socket < 0)
        return nullptr;

    uint64_t s_IncomingMessageSize = 0;
    ssize_t s_Ret = -1;

    while ((s_Ret = recv(s_Socket, &s_IncomingMessageSize, sizeof(s_IncomingMessageSize), 0)) > 0 && s_Connection->IsRunning())
    {
        if (s_Ret != sizeof(s_IncomingMessageSize))
        {
            fprintf(stderr, "err: could not get message size.\n");
            break;
        }

        if (s_IncomingMessageSize > RpcConnection_MaxMessageSize)
        {
            fprintf(stderr, "err: incoming message size (0x%lx) > max (0x%x).\n", s_IncomingMessageSize, RpcConnection_MaxMessageSize);
            break;
        }

        if (s_IncomingMessageSize == 0)
        {
            fprintf(stderr, "err: invalid incoming message size of 0.\n");
            break;
        }

        // Allocate the new data
        std::vector<uint8_t> s_Data;
        s_Data.reserve(s_IncomingMessageSize);

        // Read in all of the data from the socket
        s_Ret = recv(s_Socket, s_Data.data(), s_IncomingMessageSize, 0);
        if (s_Ret != s_IncomingMessageSize)
        {
            fprintf(stderr, "err: wanted data (0x%zx) != (0x%lx).\n", s_Ret, s_IncomingMessageSize);
            break;
        }

        // Create a new verifier
        auto s_Verifier = flatbuffers::Verifier(s_Data.data(), s_IncomingMessageSize);

        // Validate the header
        auto s_Valid = VerifyRpcHeaderBuffer(s_Verifier);
        if (!s_Valid)
        {
            fprintf(stderr, "err: could not verify flatbuffer.\n");
            break;
        }

        // Get the header
        auto s_Header = GetRpcHeader(s_Data.data());
        if (s_Header == nullptr)
        {
            fprintf(stderr, "err: header invalid.\n");
            break;
        }

        // Validate the header magic
        if (s_Header->magic() != RpcMagics_Version2)
        {
            fprintf(stderr, "err: invalid magic (%d) wanted (%d).\n", s_Header->magic(), RpcMagics_Version2);
            break;
        }

        // Validate the category
        if (s_Header->category() < RpcCategory_NONE || s_Header->category() >= RpcCategory_MAX)
        {
            fprintf(stderr, "err: invalid category (%d).\n", s_Header->category());
            break;
        }

        auto s_MessageManager = Daemon::GetInstance()->GetMessageManager();
        if (s_MessageManager == nullptr)
        {
            fprintf(stderr, "err: no message manager.\n");
            break;
        }

        s_MessageManager->OnRequest(s_Connection, s_Header);
    }

    return nullptr;
}


code:
#pragma once
#include <cstdint>
#include <memory>

extern "C"
{
    #include <netinet/in.h>
};

#include <orbis/libkernel.h>

namespace Mira
{
    namespace Rpc
    {
        class Server;

        class Connection
        {
        private:
            enum
            {
                RpcConnection_MaxMessageSize = 0x400000,
            };

            // Client socket
            int32_t m_Socket;

            // Client id
            uint32_t m_ClientId;

            // Is the client connection still running
            volatile bool m_Running;

            // Thread
            OrbisPthread m_Thread;

            // Client address
            struct sockaddr_in m_Address;

            // Reference to the server class
            Rpc::Server* m_Server;

            // TODO: mutex

        public:
            Connection(Rpc::Server* p_Server, uint32_t p_ClientId, int32_t p_Socket, struct sockaddr_in& p_Address);
            ~Connection();

            void Disconnect();

            int32_t GetSocket() const { return m_Socket; }
            uint32_t GetId() const { return m_ClientId; }
            bool IsRunning() const { return m_Running; }

            struct sockaddr_in& GetAddress() { return m_Address; }

            OrbisPthread* GetThreadPointer() { return &m_Thread; }

            static void* ConnectionThread(void* p_ConnectionInstance);
        };
    }
}


code:
#pragma once
#include <External/flatbuffers/rpc_generated.h>

#include <functional>
#include <memory>

namespace Mira
{
    namespace Rpc
    {
        class Connection;

        class Listener
        {
        private:
            RpcCategory m_Category;
            uint32_t m_Type;
            std::function<void(Rpc::Connection*, const Rpc::RpcHeader*)> m_Callback;

        public:
            Listener(RpcCategory p_Category, uint32_t p_Type, std::function<void(Rpc::Connection*, const Rpc::RpcHeader*)> p_Callback) :
                m_Category(p_Category),
                m_Type(p_Type),
                m_Callback(p_Callback)
            {

            }

            ~Listener()
            {
                m_Category = RpcCategory_NONE;
                m_Type = 0;
                m_Callback = nullptr;
            }

            RpcCategory GetCategory() const { return m_Category; }
            uint32_t GetType() const { return m_Type; }
            auto GetCallback() const { return m_Callback; }
        };
    }
}


code:
#include "Manager.hpp"
#include "Listener.hpp"
#include "Rpc/Connection.hpp"

#include <External/flatbuffers/rpc_generated.h>

using namespace Mira::Rpc;

Manager::Manager()
{

}

Manager::~Manager()
{

}

// idk: https://stackoverflow.com/questions/20833453/comparing-stdfunctions-for-equality
template<typename T, typename... U>
size_t getAddress(std::function<T(U...)> f)
{
    typedef T(fnType)(U...);
    fnType** fnPointer = f.template target<fnType*>();
    return (size_t)*fnPointer;
}

bool Manager::Register(RpcCategory p_Category, uint32_t p_Type, std::function<void(Rpc::Connection*, const Rpc::RpcHeader*)> p_Callback)
{
    // Check if we have reached our max
    if (m_Listeners.size() >= Manager_MaxListeners)
    {
        fprintf(stderr, "err: reached maximum listener count (%lu)/(%d).\n", m_Listeners.size(), Manager_MaxListeners);
        return false;
    }

    // Check for duplicates
    auto s_It = std::find_if(m_Listeners.begin(), m_Listeners.end(), [&] (std::shared_ptr<Rpc::Listener>& p_Listener)
    {
        if (p_Listener == nullptr)
            return false;

        auto s_CallbackAddress = getAddress(p_Listener->GetCallback());
        auto s_TargetAddress = getAddress(p_Callback);

        if (s_CallbackAddress == s_TargetAddress &&
            p_Listener->GetCategory() == p_Category &&
            p_Listener->GetType() == p_Type)
        {
            return true;
        }

        return false;
    });

    // If there is a duplicate reject it
    if (s_It != m_Listeners.end())
    {
        fprintf(stderr, "err: duplicate message listener is attempting to be registered cat (%d) type (%d).\n", p_Category, p_Type);
        return false;
    }

    // Create a new listener
    auto s_Listener = std::make_shared<Rpc::Listener>(p_Category, p_Type, p_Callback);
    if (s_Listener == nullptr)
    {
        fprintf(stderr, "err: could not allocate message listener for cat (%d) type (%d).\n", p_Category, p_Type);
        return false;
    }

    // Add it to our listeners
    std::lock_guard<std::mutex> s_Guard(m_Lock);
    m_Listeners.push_back(std::move(s_Listener));

    return true;
}

bool Manager::Unregister(RpcCategory p_Category, uint32_t p_Type, std::function<void(Rpc::Connection*, const Rpc::RpcHeader*)> p_Callback)
{
    std::lock_guard<std::mutex> s_Guard(m_Lock);

    auto s_Item = std::remove_if(m_Listeners.begin(), m_Listeners.end(), [&](const std::shared_ptr<Listener> p_Listener)
    {
        if (!p_Listener)
            return false;

        return p_Listener->GetCategory() == p_Category &&
                p_Listener->GetType() == p_Type &&
                getAddress(p_Listener->GetCallback()) == getAddress(p_Callback);
    });

    if (s_Item == m_Listeners.end())
        return false;

    // Remove from the list
    m_Listeners.erase(s_Item);

    return true;
}

void Manager::Clear()
{
    std::lock_guard<std::mutex> s_Guard(m_Lock);
    m_Listeners.clear();
}

void Manager::SendErrorResponse(std::shared_ptr<Rpc::Connection> p_Connection, RpcCategory p_Category, int32_t p_Error)
{
    if (!p_Connection)
        return;

    SendResponse(p_Connection, p_Category, static_cast<uint32_t>(0), p_Error < 0 ? p_Error : (-p_Error), std::vector<uint8_t>());
}

void Manager::SendResponse(std::shared_ptr<Rpc::Connection> p_Connection, RpcCategory p_Category, uint32_t p_Type, int64_t p_Error, std::vector<uint8_t> p_Data)
{
    if (p_Connection == nullptr)
        return;

    auto s_Socket = p_Connection->GetSocket();
    if (s_Socket < 0)
        return;

    flatbuffers::FlatBufferBuilder s_Builder;

    // Create a new vector
    auto s_DataVector = s_Builder.CreateVector(p_Data.data(), p_Data.size());

    // Create a new header
    auto s_Header = CreateRpcHeader(s_Builder, RpcMagics::RpcMagics_Version2, p_Category, p_Type, 0, p_Error, s_DataVector);

    // Finalize the header
    s_Builder.Finish(s_Header);

    // Get the buffer pointer and size
    auto s_BufferPointer = s_Builder.GetBufferPointer();
    auto s_BufferSize = s_Builder.GetSize();

    printf("info: buf: (%p), size: (%x).\n", s_BufferPointer, s_BufferSize);

    auto s_Ret = write(s_Socket, s_BufferPointer, s_BufferSize);
    if (s_Ret <= 0)
    {
        fprintf(stderr, "could not write to socket (%ld).\n", s_Ret);
        return;
    }
}

void Manager::OnRequest(Rpc::Connection* p_Connection, const Mira::Rpc::RpcHeader* p_Message)
{
    if (p_Connection == nullptr)
        return;

    if (p_Message == nullptr)
        return;

    std::lock_guard<std::mutex> s_Guard(m_Lock);
    std::for_each(m_Listeners.begin(), m_Listeners.end(), [&](std::shared_ptr<Listener> p_Listener)
    {
        // Validate the listener
        if (p_Listener == nullptr)
            return;

        // Validate the category
        if (p_Listener->GetCategory() != p_Message->category())
            return;

        // Validate the type
        if (p_Listener->GetType() != p_Message->type())
            return;

        // Call the callback
        auto s_Callback = p_Listener->GetCallback();
        if (s_Callback == nullptr)
            return;

        // Call the callback
        s_Callback(p_Connection, p_Message);
    });
}


code:
#pragma once
#include <External/flatbuffers/rpc_generated.h>
#include <vector>
#include <cstddef>
#include <limits>
#include <mutex>

namespace Mira
{
    namespace Rpc
    {
        struct RpcHeader;
        class Connection;
        class Listener;

        class Manager
        {
        private:
            enum
            {
                Manager_MaxCategories = std::numeric_limits<uint32_t>::max() - 1,
                Manager_MaxListeners = 64,

                // Maximum message size (4MB)
                Manager_MaxMessageSize = 0x4000000,
            };

            std::vector<std::shared_ptr<Rpc::Listener>> m_Listeners;
            std::mutex m_Lock;

        public:
            Manager();
            virtual ~Manager();

            bool Register(RpcCategory p_Category, uint32_t p_Type, std::function<void(Rpc::Connection*, const Rpc::RpcHeader*)>);
            bool Unregister(RpcCategory p_Category, uint32_t p_Type, std::function<void(Rpc::Connection*, const Rpc::RpcHeader*)>);

            void Clear();

            void SendErrorResponse(std::shared_ptr<Rpc::Connection> p_Connection, RpcCategory p_Category, int32_t p_Error);

            void SendResponse(std::shared_ptr<Rpc::Connection> p_Connection, RpcCategory p_Category, uint32_t p_Type, int64_t p_Error, std::vector<uint8_t> p_Data);

            void OnRequest(Rpc::Connection* p_Connection, const Mira::Rpc::RpcHeader* p_Message);
        };
    }
}


code:
#include "Server.hpp"
#include "Connection.hpp"

#include <cstdio>
#include <cstring>
#include <cerrno>

extern "C"
{
    #include <unistd.h>
    #include <sys/time.h>
};

using namespace Mira::Rpc;

Server::Server(uint16_t p_Port) :
    m_Socket(-1),
    m_Port(p_Port),
    m_Thread(-1),
    m_Running(false),
    m_Address { 0 }
{

}

Server::~Server()
{

}

bool Server::OnLoad()
{
    // Initialize the networking
    sceNetInit();

    return Startup();
}

bool Server::OnUnload()
{
    return Teardown();
}

bool Server::OnSuspend()
{
    return Teardown();
}

bool Server::OnResume()
{
    return Startup();
}

bool Server::Startup()
{
    // Debugging output
    printf("rpc server starting...\n");

    do
    {
        // Configure the address
        printf("info: port (%d).\n", m_Port);

        memset(&m_Address, 0, sizeof(m_Address));
        m_Address.sin_len = sizeof(m_Address);
        m_Address.sin_family = AF_INET;
        m_Address.sin_addr.s_addr = htonl(INADDR_ANY);
        m_Address.sin_port = htons(m_Port);

        // Create a new socket
        auto s_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s_Socket <= 0)
        {
            fprintf(stderr, "err: could not create socket (%d).\n", s_Socket);
            break;
        }

        // Bind a new socket
        auto s_Ret = bind(s_Socket, reinterpret_cast<struct sockaddr*>(&m_Address), sizeof(m_Address));
        if (s_Ret < 0)
        {
            fprintf(stderr, "err: could not bind socket (%d).\n", s_Ret);
            fprintf(stderr, "stderrstr: %s.\n", strerror(errno));

            // Shutdown socket
            s_Ret = shutdown(s_Socket, SHUT_RDWR);
            if (s_Ret < 0)
                fprintf(stderr, "err: could not shutdown socket (%d).\n", s_Ret);

            // Close socket
            s_Ret = close(s_Socket);
            if (s_Ret < 0)
                fprintf(stderr, "err: could not close socket (%d).\n", s_Ret);

            break;
        }

        printf("info: socket (%d) bound to port (%d).\n", s_Socket, m_Port);

        // Listen for new connections
        s_Ret = listen(s_Socket, RpcServer_MaxConnections);
        if (s_Ret < 0)
        {
            fprintf(stderr, "err: could not listen on socket (%d).\n", s_Ret);

            // Shutdown socket
            s_Ret = shutdown(s_Socket, SHUT_RDWR);
            if (s_Ret < 0)
                fprintf(stderr, "err: could not shutdown socket (%d).\n", s_Ret);

            // Close socket
            s_Ret = close(s_Socket);
            if (s_Ret < 0)
                fprintf(stderr, "err: could not close socket (%d).\n", s_Ret);

            break;
        }

        // Update the socket
        m_Socket = s_Socket;

        // Create a new server processing thread
        s_Ret = scePthreadCreate(&m_Thread, nullptr, (void*)ServerThread, this, "RpcServer"); //pthread_create(&m_Thread, nullptr, ServerThread, this);
        if (s_Ret != 0)
        {
            fprintf(stderr, "err: could not create new thread (%d).\n", s_Ret);

            // Teardown
            if (!Teardown())
                fprintf(stderr, "err: could not teardown.\n");

            break;
        }
        return true;
    } while (false);

    return true;
}

bool Server::Teardown()
{
    return true;
}

void* Server::ServerThread(void* p_ServerInstance)
{
    auto s_Server = static_cast<Server*>(p_ServerInstance);
    do
    {
        if (s_Server == nullptr)
            break;

        struct timeval s_Timeout
        {
            .tv_sec = 0,
            .tv_usec = 0
        };

        // Hold the client address
        struct sockaddr_in s_ClientAddress = { 0 };
        socklen_t s_ClientAddressLength = sizeof(s_ClientAddress);

        int32_t s_ClientSocket = -1;

        fd_set s_ReadFds;
        FD_ZERO(&s_ReadFds);
        FD_SET(s_Server->m_Socket, &s_ReadFds);

        auto s_Ret = 0;
        while ((s_ClientSocket = accept(s_Server->m_Socket, reinterpret_cast<struct sockaddr*>(&s_ClientAddress), &s_ClientAddressLength)) > 0)
        {
            // Set the client socket options
            s_Ret = setsockopt(s_ClientSocket, SOL_SOCKET, SO_LINGER, &s_Timeout, sizeof(s_Timeout));
            if (s_Ret < 0)
            {
                fprintf(stderr, "err: could not set linger options (%d).\n", s_Ret);

                // Shutdown socket
                s_Ret = shutdown(s_ClientSocket, SHUT_RDWR);
                if (s_Ret != 0)
                    fprintf(stderr, "err: could not shutdown client socket (%d).\n", s_Ret);

                // Close socket
                s_Ret = close(s_ClientSocket);
                if (s_Ret != 0)
                    fprintf(stderr, "err: could not close socket (%d).\n", s_Ret);

                break;
            }

            // Print out the address
            auto l_Address = static_cast<uint32_t>(s_ClientAddress.sin_addr.s_addr);
            printf("got new rpc connection (%d) from IP (%03d.%03d.%03d.%03d).\n",
                s_ClientSocket,
                (l_Address & 0xFF),
                (l_Address >> 8) & 0xFF,
                (l_Address >> 16) & 0xFF,
                (l_Address >> 24) & 0xFF);

            // Allocate a new connection
            auto l_Connection = std::make_shared<Rpc::Connection>(s_Server, ++s_Server->m_NextConnectionId, s_ClientSocket, s_ClientAddress);
            if (l_Connection == nullptr)
            {
                fprintf(stderr, "err: could not allocate connection.\n");

                // Shutdown socket
                s_Ret = shutdown(s_ClientSocket, SHUT_RDWR);
                if (s_Ret != 0)
                    fprintf(stderr, "err: could not shutdown client socket (%d).\n", s_Ret);

                // Close socket
                s_Ret = close(s_ClientSocket);
                if (s_Ret != 0)
                    fprintf(stderr, "err: could not close socket (%d).\n", s_Ret);

                break;
            }

            // Create a new thread
            s_Ret = scePthreadCreate(l_Connection->GetThreadPointer(), nullptr, (void*)Connection::ConnectionThread, l_Connection.get(), "RpcConn");
            if (s_Ret != 0)
            {
                fprintf(stderr, "err: could not create new connection thread (%d).\n", s_Ret);

                // Shutdown socket
                s_Ret = shutdown(s_ClientSocket, SHUT_RDWR);
                if (s_Ret != 0)
                    fprintf(stderr, "err: could not shutdown client socket (%d).\n", s_Ret);

                // Close socket
                s_Ret = close(s_ClientSocket);
                if (s_Ret != 0)
                    fprintf(stderr, "err: could not close socket (%d).\n", s_Ret);

                break;
            }

            // Add the connection to the server list
            s_Server->m_Connections.push_back(std::move(l_Connection));
        }

    } while (false);

    return nullptr;
}


code:
#pragma once
#include <vector>
#include <memory>

#include <Utils/IModule.hpp>
#include <orbis/libkernel.h>
#include <orbis/Net.h>

extern "C"
{
    #include <sys/socket.h>
    #include <netinet/in.h>

    #include <pthread.h>
};

namespace Mira
{
    namespace Rpc
    {
        class Connection;

        class Server :
            public Utils::IModule
        {
        private:
            enum
            {
                RpcServer_MaxConnections = 8,
                RpcServer_DefaultPort = 9999
            };

            // Socket
            int32_t m_Socket;

            // Port
            uint16_t m_Port;

            // Thread
            OrbisPthread m_Thread;

            // Running
            volatile bool m_Running;

            // Give semi-random id for lookup later
            uint32_t m_NextConnectionId;

            // Address
            struct sockaddr_in m_Address;

            // Connections
            std::vector<std::shared_ptr<Rpc::Connection>> m_Connections;

            // TODO: mutex

        public:
            Server(uint16_t p_Port = RpcServer_DefaultPort);
            virtual ~Server();

            virtual const char* GetName() override { return "RpcServer"; }
            virtual bool OnLoad() override;
            virtual bool OnUnload() override;
            virtual bool OnSuspend() override;
            virtual bool OnResume() override;

        protected:
            bool Startup();
            bool Teardown();

            int32_t GetSocketByClientId(uint32_t p_ClientId);

        private:
            static void* ServerThread(void* p_ServerInstance);
        };
    }
}


code:
#pragma once

namespace Mira
{

}


code:
#pragma once

namespace Mira
{
    namespace Utils
    {
        class IModule
        {
        public:
            IModule() { }
            virtual ~IModule() { }

            virtual bool OnLoad() { return true; }
            virtual bool OnUnload() { return true; }
            virtual bool OnSuspend() { return true; }
            virtual bool OnResume() { return true; }

            virtual const char* GetName() { return ""; };
            virtual const char* GetDescription() { return ""; };
        };
    }
}


code:
=== Registry Key ===

SCE_REGMGR_ENT_KEY_DEVENV_TOOL_boot_param

=== RE Location ===

Sce.Vsh.ShellUI.Settings.DebugSettings > CategoryBootParam

=== Default UInt32 Values ===

bootParam_uint_0_31    = 2863311530
bootParam_uint_32_63   = 65535
bootParam_uint_64_95   = 13
bootParam_uint_96_127  = 3
bootParam_uint_128_159 = 0

=== Binary Form ===

10101010 10101010 10101010 10101010
00000000 00000000 11111111 11111111
00000000 00000000 00000000 00001101
00000000 00000000 00000000 00000011
00000000 00000000 00000000 00000000

=== SET 1 ===

BOOTPARAM | 1 << BIT

=== SET 0 ===

BOOTPARAM & ~(1 << BIT)

=== Bytes 0 - 4 ===

private const int Bit_No_Release_Check_Mode = 0;

private const int Bit_No_Testkit_Mode = 1;

private const int Bit_No_Release_Mode_Console = 4;

private const int Bit_No_Disable_Qaf = 8;

private const int Bit_No_Disable_Utoken = 9;

private const int Bit_No_Disable_Razor = 24;

=== Bytes 4 - 8 === // Bit - 32

private const int Bit_No_Fs_Reverted = 32; // 0

private const int Bit_No_Fs_Advanced = 33; // 1

private const int Bit_No_Fs_Trial = 34; // 2

private const int Bit_No_Slow_Hdd_Mode = 40; // 8

private const int Bit_No_Repeat_Kernel_System_Suspend = 62; // 30

=== Bytes 8 - 12 === // Bit - 64

private const int Bit_No_Cpu_Restrict = 64; // 0

private const int Bit_No_Cpu_Only_One = 65; // 1

private const int Bit_No_Disable_Unapproved_Sysctl = 70; // 6

private const int Bit_No_Vm_Compressor_Mode0 = 72; // 8

=== Bytes 12 - 16 === // Bit - 96

private const int Bit_No_Kratos_Swap_Off = 96; // 0

private const int Bit_No_Kratos_Nfs_Mode = 97; // 1

private const int Bit_No_Kratos_Wlan_Off = 100; // 4

=== Bytes 16 - 20 === // Bit - 128

private const int Bit_No_Vsh_4k_Mode = 128; // 0

private const int Bit_No_Base_PS4_Emulation = 146; // 18


code:
syntax = "proto3";

import "external/debugger_structs.proto";

// Has no request payload
message DbgGetProcessListResponse {
    repeated DbgProcessLimited processes = 1;
}

message DbgReadProcessMemoryRequest {
    uint64 address = 1;
    uint32 size = 2;
}

message DbgReadProcessMemoryResponse {
    bytes data = 1;
}

message DbgWriteProcessMemoryRequest {
    uint64 address = 1;
    bytes data = 2; // Size is inside here
} // Bytes are returned in error, no response payload

message DbgProtectProcessMemoryRequest {
    uint64 address = 1;
    uint64 length = 2;
    int32 protection = 3;
} // No response payload

message DbgScanProcessMemoryRequest {
    // TODO: Come back to this
}

message DbgGetProcessInfoRequest {
    int32 processId = 1;
}// Response payload = DbgProcessFull

message DbgAllocateProcessMemoryRequest {
    uint32 size = 1;
}

message DbgAllocateProcessMemoryResponse {
    uint64 address = 1;
    uint32 size = 2;
}

message DbgFreeProcessMemoryRequest {
    uint64 address = 1;
    uint32 size = 2;
}

message DbgGetProcessMapsRequest {
    int32 processId = 1;
} // Response Message = DbgProcessLimited

message DbgAttachRequest {
    int32 processId = 1;
} // No response payload, pid in error

message DbgDetachRequest {
    bool force = 1;
} // No response payload

enum DbgBreakpointType {
    BP_NONE = 0;
    BP_SOFTWARE = 1;
    BP_HARDWARE = 2;
}

message DbgBreakpointRequest {
    bool enabled = 1;
    uint64 address = 2;
    uint32 original = 3;
    DbgBreakpointType breakpointType = 4;
}

message DbgBreakpointResponse {
    uint64 breakpointHandle = 1;
}

message DbgWatchpointRequest {
    bool enabled = 1;
    uint64 address = 2;
    uint32 breakpointType = 3;
    uint32 length = 4;
}

message DbgWatchpointResponse {
    uint64 watchpointHandle = 1;
}

message DbgGetProcessThreadsRequest {
    int32 processId = 1;
}

message DbgGetProcessThreadsResponse {
    repeated DbgThreadLimited threads = 1;
}

message DbgSignalProcessRequest {
    int32 signal = 1;
} // No response message

message DbgGetRegistersRequest {
    int32 threadId = 1;
}

message DbgGetRegistersResponse {
    DbgGpRegisters gpRegisters = 1;
    DbgFpRegisters fpRegisters = 2;
    DbgDbRegisters dbRegisters = 3;
}

message DbgSetRegistersRequest {
    int32 threadId = 1;
    DbgGpRegisters gpRegisters = 2;
    DbgFpRegisters fpRegisters = 3;
    DbgDbRegisters dbRegisters = 4;
} // No Response message payload

message DbgGetThreadInfoRequest {
    int32 threadId = 1;
}

message DbgGetKernelInfoResponse {
    uint64 version = 1;
    bytes gloablConfigData = 2; // len 140?
}

message DbgReadKernelMemoryRequest {
    uint64 address = 1;
    uint64 size = 2;
}

message DbgReadKernelMemoryResponse {
    bytes data = 1;
}

message DbgWriteKernelMemoryRequest {
    uint64 address = 1;
    bytes data = 2;
}

message DbgCommandRequest {
    enum DbgCommands {
        DBG_NONE = 0;
        DBG_REBOOT = 1;
        DBG_SHUTDOWN = 2;
        DBG_PRINT = 3;
        DBG_NOTIFY = 4;
        DBG_INFO = 5;
    }
    DbgCommands command = 1;
}


code:
syntax = "proto3";

message DbgGpRegisters {
    uint64	r_r15 = 1;
	uint64	r_r14 = 2;
	uint64	r_r13 = 3;
	uint64	r_r12 = 4;
	uint64	r_r11 = 5;
	uint64	r_r10 = 6;
	uint64	r_r9 = 7;
	uint64	r_r8 = 8;
	uint64	r_rdi = 9;
	uint64	r_rsi = 10;
	uint64	r_rbp = 11;
	uint64	r_rbx = 12;
	uint64	r_rdx = 13;
	uint64	r_rcx = 14;
	uint64	r_rax = 15;
	uint32	r_trapno = 16;
	uint32	r_fs = 17; // uint16
	uint32	r_gs = 18; // uint16
	uint32	r_err = 19;
	uint32	r_es = 20; // uint16
	uint32	r_ds = 21; // uint16
	uint64	r_rip = 22;
	uint64	r_cs = 23;
	uint64	r_rflags = 24;
	uint64	r_rsp = 25;
	uint64	r_ss = 26;
}

message DbgFpRegisters {
    bytes data = 1; // I really don't feel like dealing with this
}

message DbgDbRegisters {
    repeated uint32 debugRegs = 1; // len 16
}

message DbgThreadLimited {
    uint64 proc = 1;
    int32 threadId = 2;
    string name = 3;
    int64 retval = 4; // len 2
    uint64 kernelStack = 5;
    int32 kernelStackPages = 6;
    int32 err_no = 7;
}

message DbgThreadFull {
    uint64 proc = 1;
    int32 threadId = 2;
    string name = 3;
    int64 retval = 4; // len 2
    uint64 kernelStack = 5;
    int32 kernelStackPages = 6;
    int32 err_no = 7;
    DbgGpRegisters gpRegisters = 8;
    DbgFpRegisters fpRegisters = 9;
    DbgDbRegisters dbRegisters = 10;
}

message DbgCred {
    uint32 effectiveUserId = 1;
    uint32 realUserId = 2;
    uint32 savedUserId = 3;
    int32 numGroups = 4;
    uint32 realGroupId = 5;
    uint32 savedGroupId = 6;
    uint64 prison = 7;
    uint64 sceAuthId = 8;
    repeated uint64 sceCaps = 9; // len 4
    repeated uint64 sceAttr = 10; // len 4
}

message DbgFileDesc {

}

message DbgProcessFull {
    repeated DbgThreadLimited threads = 1;
    uint32 unused = 2;
    int32 processId = 3;
    uint64 parentProc = 4;
    int32 oppid = 5;
    int32 dbgChild = 6;
    uint64 vmspace = 7;
    int32 exitThreads = 8;
    int32 sigParent = 9;
    int32 sig = 10;
    uint32 code = 11;
    uint32 stops = 12;
    uint32 stype = 13;
    uint64 singleThread = 14;
    int32 suspendCount = 15;
    uint64 dynlib = 16;
    string name = 17;
    string elfPath = 18;
    string randomizedPath = 19;
    int32 numThreads = 20;
    repeated DbgVmEntry mapEntries = 21;
}

message DbgVmEntry {
    string name = 1;
    uint64 start = 2;
    uint64 end = 3;
    uint64 offset = 4;
    int32 protection = 5;
}
message DbgProcessLimited {
    int32 processId = 1;
    string name = 2;
    repeated DbgVmEntry entries = 3;
}


code:
syntax = "proto3";

message FmEchoRequest {
    string message = 1;
}

message FmOpenRequest {
    int32 flags = 1;
    int32 mode = 2;
    string path = 3;
}

message FmCloseRequest {
    int32 handle = 1;
}

message FmSeekRequest {
    int32 handle = 1;
    int64 offset = 2;
}

message FmReadRequest {
    int32 handle = 1;
    uint64 size = 2;
}

message FmReadResponse {
    bytes data = 1;
}

message FmWriteRequest {
    int32 handle = 1;
    bytes data = 2;
}

message FmDent {
    uint32 fileno = 1;
    uint32 recLen = 2;
    uint32 type = 3;
    string name = 4;
}

message FmGetDentsRequest {
    string path = 1;
}

message FmGetDentsResponse {
    repeated FmDent dents = 1;
}

message FmTimespec {
    int64 tv_sec = 1;
    int32 tv_nsec = 2;
}

message FmStatRequest {
    int32 handle = 1;
    string path = 2;
}

message FmStatResponse {
    uint32 st_dev = 1;
    uint32 st_ino = 2;
    uint32 st_mode = 3;
    uint32 st_nlink = 4;
    uint32 st_uid = 5;
    uint32 st_gid = 6;
    uint32 st_rdev = 7;
    FmTimespec st_atim = 8;
    FmTimespec st_mtim = 9;
    FmTimespec st_ctim = 10;
    int64 st_size = 11;
    int64 st_blocks = 12;
    uint32 st_blksize = 13;
    uint32 st_flags = 14;
    uint32 st_gen = 15;
    int32 st_lspare = 16;
    FmTimespec st_birthtim = 17;
}

message FmMkdirRequest {
    int32 mode = 1;
    string path = 2;
}

message FmRmdirRequest {
    string path = 1;
}

message FmUnlinkRequest {
    string path = 1;
}

message FmDecryptSelfRequest {
    string path = 1;
}

message FmDecryptSelfResponse {
    bytes data = 1;
}


code:
# Auto detect text files and perform LF normalization
* text=auto


code:
#Ignore thumbnails created by Windows
Thumbs.db
#Ignore files built by Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*
.vs/
#Nuget packages folder
packages/


code:
/*
 * Block.h
 *
 * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,
 * to any person obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 * persons to whom the Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#ifndef _BLOCK_H_
#define _BLOCK_H_

#if !defined(BLOCK_EXPORT)
#   if defined(__cplusplus)
#       define BLOCK_EXPORT extern "C"
#   else
#       define BLOCK_EXPORT extern
#   endif
#endif

#if defined(__cplusplus)
extern "C" {
#endif

/* Create a heap based copy of a Block or simply add a reference to an existing one.
 * This must be paired with Block_release to recover memory, even when running
 * under Objective-C Garbage Collection.
 */
BLOCK_EXPORT void *_Block_copy(const void *aBlock);

/* Lose the reference, and if heap based and last reference, recover the memory. */
BLOCK_EXPORT void _Block_release(const void *aBlock);

#if defined(__cplusplus)
}
#endif

/* Type correct macros. */

#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))

#endif


code:
/*
 * Block_private.h
 *
 * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,
 * to any person obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to permit
 * persons to whom the Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

#ifndef _BLOCK_PRIVATE_H_
#define _BLOCK_PRIVATE_H_

#if !defined(BLOCK_EXPORT)
#   if defined(__cplusplus)
#       define BLOCK_EXPORT extern "C"
#   else
#       define BLOCK_EXPORT extern
#   endif
#endif

#ifndef _MSC_VER
#include <stdbool.h>
#else
/* MSVC doesn't have <stdbool.h>. Compensate. */
typedef char bool;
#define true (bool)1
#define false (bool)0
#endif

#if defined(__cplusplus)
extern "C" {
#endif

enum {
    BLOCK_REFCOUNT_MASK =     (0xffff),
    BLOCK_NEEDS_FREE =        (1 << 24),
    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
    BLOCK_HAS_CTOR =          (1 << 26), /* Helpers have C++ code. */
    BLOCK_IS_GC =             (1 << 27),
    BLOCK_IS_GLOBAL =         (1 << 28),
    BLOCK_HAS_DESCRIPTOR =    (1 << 29)
};

/* Revised new layout. */
struct Block_descriptor {
    unsigned long int reserved;
    unsigned long int size;
    void (*copy)(void *dst, void *src);
    void (*dispose)(void *);
};

struct Block_layout {
    void *isa;
    int flags;
    int reserved;
    void (*invoke)(void *, ...);
    struct Block_descriptor *descriptor;
    /* Imported variables. */
};

struct Block_byref {
    void *isa;
    struct Block_byref *forwarding;
    int flags; /* refcount; */
    int size;
    void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
    void (*byref_destroy)(struct Block_byref *);
    /* long shared[0]; */
};

struct Block_byref_header {
    void *isa;
    struct Block_byref *forwarding;
    int flags;
    int size;
};

/* Runtime support functions used by compiler when generating copy/dispose helpers. */

enum {
    /* See function implementation for a more complete description of these fields and combinations */
    BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)), block, ... */
    BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
    BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the __block variable */
    BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy helpers */
    BLOCK_BYREF_CALLER      = 128  /* called from __block (byref) copy/dispose support routines. */
};

/* Runtime entry point called by compiler when assigning objects inside copy helper routines */
BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
    /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */

/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */
BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);

/* Other support functions */

/* Runtime entry to get total size of a closure */
BLOCK_EXPORT unsigned long int Block_size(void *block_basic);

/* the raw data space for runtime classes for blocks */
/* class+meta used for stack, malloc, and collectable based blocks */
BLOCK_EXPORT void * _NSConcreteStackBlock[32];
BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];

/* the intercept routines that must be used under GC */
BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
                                  void (*setHasRefcount)(const void *, const bool),
                                  void (*gc_assign_strong)(void *, void **),
                                  void (*gc_assign_weak)(const void *, void *),
                                  void (*gc_memmove)(void *, void *, unsigned long));

/* earlier version, now simply transitional */
BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
                                  void (*setHasRefcount)(const void *, const bool),
                                  void (*gc_assign_strong)(void *, void **),
                                  void (*gc_assign_weak)(const void *, void *));

BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
                                 void (*release)(const void *));

/* make a collectable GC heap based Block.  Not useful under non-GC. */
BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);

/* thread-unsafe diagnostic */
BLOCK_EXPORT const char *_Block_dump(const void *block);

/* Obsolete */

/* first layout */
struct Block_basic {
    void *isa;
    int Block_flags;  /* int32_t */
    int Block_size;  /* XXX should be packed into Block_flags */
    void (*Block_invoke)(void *);
    void (*Block_copy)(void *dst, void *src);  /* iff BLOCK_HAS_COPY_DISPOSE */
    void (*Block_dispose)(void *);             /* iff BLOCK_HAS_COPY_DISPOSE */
    /* long params[0];  // where const imports, __block storage references, etc. get laid down */
};

#if defined(__cplusplus)
}
#endif

#endif /* _BLOCK_PRIVATE_H_ */


code:
// $Header: /home/daffy/u0/vern/flex/RCS/FlexLexer.h,v 1.19 96/05/25 20:43:02 vern Exp $
// $FreeBSD: release/9.0.0/usr.bin/lex/FlexLexer.h 126841 2004-03-11 10:43:35Z josef $

// FlexLexer.h -- define interfaces for lexical analyzer classes generated
//		  by flex

// Copyright (c) 1993 The Regents of the University of California.
// All rights reserved.
//
// This code is derived from software contributed to Berkeley by
// Kent Williams and Tom Epperly.
//
// Redistribution and use in source and binary forms are permitted provided
// that: (1) source distributions retain this entire copyright notice and
// comment, and (2) distributions including binaries display the following
// acknowledgement:  ``This product includes software developed by the
// University of California, Berkeley and its contributors'' in the
// documentation or other materials provided with the distribution and in
// all advertising materials mentioning features or use of this software.
// Neither the name of the University nor the names of its contributors may
// be used to endorse or promote products derived from this software without
// specific prior written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

// This file defines FlexLexer, an abstract class which specifies the
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
// which defines a particular lexer class.
//
// If you want to create multiple lexer classes, you use the -P flag
// to rename each yyFlexLexer to some other xxFlexLexer.  You then
// include <FlexLexer.h> in your other sources once per lexer class:
//
//	#undef yyFlexLexer
//	#define yyFlexLexer xxFlexLexer
//	#include <FlexLexer.h>
//
//	#undef yyFlexLexer
//	#define yyFlexLexer zzFlexLexer
//	#include <FlexLexer.h>
//	...

#ifndef __FLEX_LEXER_H
// Never included before - need to define base class.
#define __FLEX_LEXER_H
#include <iostream>

extern "C++" {

struct yy_buffer_state;
typedef int yy_state_type;

class FlexLexer {
public:
	virtual ~FlexLexer()	{ }

	const char* YYText()	{ return yytext; }
	int YYLeng()		{ return yyleng; }

	virtual void
		yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
	virtual struct yy_buffer_state*
		yy_create_buffer( std::istream* s, int size ) = 0;
	virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
	virtual void yyrestart( std::istream* s ) = 0;

	virtual int yylex() = 0;

	// Call yylex with new input/output sources.
	int yylex( std::istream* new_in, std::ostream* new_out = 0 )
		{
		switch_streams( new_in, new_out );
		return yylex();
		}

	// Switch to new input/output streams.  A nil stream pointer
	// indicates "keep the current one".
	virtual void switch_streams( std::istream* new_in = 0,
					std::ostream* new_out = 0 ) = 0;

	int lineno() const		{ return yylineno; }

	int debug() const		{ return yy_flex_debug; }
	void set_debug( int flag )	{ yy_flex_debug = flag; }

protected:
	char* yytext;
	int yyleng;
	int yylineno;		// only maintained if you use %option yylineno
	int yy_flex_debug;	// only has effect with -d or "%option debug"
};

}
#endif

#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
// Either this is the first time through (yyFlexLexerOnce not defined),
// or this is a repeated include to define a different flavor of
// yyFlexLexer, as discussed in the flex man page.
#define yyFlexLexerOnce

class yyFlexLexer : public FlexLexer {
public:
	// arg_yyin and arg_yyout default to the cin and cout, but we
	// only make that assignment when initializing in yylex().
	yyFlexLexer( std::istream* arg_yyin = 0, std::ostream* arg_yyout = 0 );

	virtual ~yyFlexLexer();

	void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
	struct yy_buffer_state* yy_create_buffer( std::istream* s, int size );
	void yy_delete_buffer( struct yy_buffer_state* b );
	void yyrestart( std::istream* s );

	virtual int yylex();
	virtual void switch_streams( std::istream* new_in, std::ostream* new_out );

protected:
	virtual int LexerInput( char* buf, int max_size );
	virtual void LexerOutput( const char* buf, int size );
	virtual void LexerError( const char* msg );

	void yyunput( int c, char* buf_ptr );
	int yyinput();

	void yy_load_buffer_state();
	void yy_init_buffer( struct yy_buffer_state* b, std::istream* s );
	void yy_flush_buffer( struct yy_buffer_state* b );

	int yy_start_stack_ptr;
	int yy_start_stack_depth;
	int* yy_start_stack;

	void yy_push_state( int new_state );
	void yy_pop_state();
	int yy_top_state();

	yy_state_type yy_get_previous_state();
	yy_state_type yy_try_NUL_trans( yy_state_type current_state );
	int yy_get_next_buffer();

	std::istream* yyin;	// input source for default LexerInput
	std::ostream* yyout;	// output sink for default LexerOutput

	struct yy_buffer_state* yy_current_buffer;

	// yy_hold_char holds the character lost when yytext is formed.
	char yy_hold_char;

	// Number of characters read into yy_ch_buf.
	int yy_n_chars;

	// Points to current character in buffer.
	char* yy_c_buf_p;

	int yy_init;		// whether we need to initialize
	int yy_start;		// start state number

	// Flag which is used to allow yywrap()'s to do buffer switches
	// instead of setting up a fresh yyin.  A bit of a hack ...
	int yy_did_buffer_switch_on_eof;

	// The following are not always needed, but may be depending
	// on use of certain flex features (like REJECT or yymore()).

	yy_state_type yy_last_accepting_state;
	char* yy_last_accepting_cpos;

	yy_state_type* yy_state_buf;
	yy_state_type* yy_state_ptr;

	char* yy_full_match;
	int* yy_full_state;
	int yy_full_lp;

	int yy_lp;
	int yy_looking_for_trail_begin;

	int yy_more_flag;
	int yy_more_len;
	int yy_more_offset;
	int yy_prev_more_offset;
};

#endif


code:
/*
 * Copyright (c) 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 * (c) UNIX System Laboratories, Inc.
 * All or some portions of this file are derived from material licensed
 * to the University of California by American Telephone and Telegraph
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * the permission of UNIX System Laboratories, Inc.
 *
 * This code is derived from software contributed to Berkeley by
 * Paul Borman at Krystal Technologies.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * From @(#)ctype.h	8.4 (Berkeley) 1/21/94
 * From FreeBSD: src/include/ctype.h,v 1.27 2004/06/23 07:11:39 tjr Exp
 * $FreeBSD: release/9.0.0/include/_ctype.h 203964 2010-02-16 19:39:50Z imp $
 */

#ifndef __CTYPE_H_
#define	__CTYPE_H_

#include <sys/cdefs.h>
#include <sys/_types.h>

#define	_CTYPE_A	0x00000100L		/* Alpha */
#define	_CTYPE_C	0x00000200L		/* Control */
#define	_CTYPE_D	0x00000400L		/* Digit */
#define	_CTYPE_G	0x00000800L		/* Graph */
#define	_CTYPE_L	0x00001000L		/* Lower */
#define	_CTYPE_P	0x00002000L		/* Punct */
#define	_CTYPE_S	0x00004000L		/* Space */
#define	_CTYPE_U	0x00008000L		/* Upper */
#define	_CTYPE_X	0x00010000L		/* X digit */
#define	_CTYPE_B	0x00020000L		/* Blank */
#define	_CTYPE_R	0x00040000L		/* Print */
#define	_CTYPE_I	0x00080000L		/* Ideogram */
#define	_CTYPE_T	0x00100000L		/* Special */
#define	_CTYPE_Q	0x00200000L		/* Phonogram */
#define	_CTYPE_SW0	0x20000000L		/* 0 width character */
#define	_CTYPE_SW1	0x40000000L		/* 1 width character */
#define	_CTYPE_SW2	0x80000000L		/* 2 width character */
#define	_CTYPE_SW3	0xc0000000L		/* 3 width character */
#define	_CTYPE_SWM	0xe0000000L		/* Mask for screen width data */
#define	_CTYPE_SWS	30			/* Bits to shift to get width */

/* See comments in <sys/_types.h> about __ct_rune_t. */
__BEGIN_DECLS
unsigned long	___runetype(__ct_rune_t) __pure;
__ct_rune_t	___tolower(__ct_rune_t) __pure;
__ct_rune_t	___toupper(__ct_rune_t) __pure;
__END_DECLS

/*
 * _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us
 * to generate code for extern versions of all our inline functions.
 */
#ifdef _EXTERNALIZE_CTYPE_INLINES_
#define	_USE_CTYPE_INLINE_
#define	static
#define	__inline
#endif

extern int __mb_sb_limit;

/*
 * Use inline functions if we are allowed to and the compiler supports them.
 */
#if !defined(_DONT_USE_CTYPE_INLINE_) && \
    (defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus))

#include <runetype.h>

static __inline int
__maskrune(__ct_rune_t _c, unsigned long _f)
{
	return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) :
		_CurrentRuneLocale->__runetype[_c]) & _f;
}

static __inline int
__sbmaskrune(__ct_rune_t _c, unsigned long _f)
{
	return (_c < 0 || _c >= __mb_sb_limit) ? 0 :
	       _CurrentRuneLocale->__runetype[_c] & _f;
}

static __inline int
__istype(__ct_rune_t _c, unsigned long _f)
{
	return (!!__maskrune(_c, _f));
}

static __inline int
__sbistype(__ct_rune_t _c, unsigned long _f)
{
	return (!!__sbmaskrune(_c, _f));
}

static __inline int
__isctype(__ct_rune_t _c, unsigned long _f)
{
	return (_c < 0 || _c >= 128) ? 0 :
	       !!(_DefaultRuneLocale.__runetype[_c] & _f);
}

static __inline __ct_rune_t
__toupper(__ct_rune_t _c)
{
	return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) :
	       _CurrentRuneLocale->__mapupper[_c];
}

static __inline __ct_rune_t
__sbtoupper(__ct_rune_t _c)
{
	return (_c < 0 || _c >= __mb_sb_limit) ? _c :
	       _CurrentRuneLocale->__mapupper[_c];
}

static __inline __ct_rune_t
__tolower(__ct_rune_t _c)
{
	return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) :
	       _CurrentRuneLocale->__maplower[_c];
}

static __inline __ct_rune_t
__sbtolower(__ct_rune_t _c)
{
	return (_c < 0 || _c >= __mb_sb_limit) ? _c :
	       _CurrentRuneLocale->__maplower[_c];
}

static __inline int
__wcwidth(__ct_rune_t _c)
{
	unsigned int _x;

	if (_c == 0)
		return (0);
	_x = (unsigned int)__maskrune(_c, _CTYPE_SWM|_CTYPE_R);
	if ((_x & _CTYPE_SWM) != 0)
		return ((_x & _CTYPE_SWM) >> _CTYPE_SWS);
	return ((_x & _CTYPE_R) != 0 ? 1 : -1);
}

#else /* not using inlines */

__BEGIN_DECLS
int		__maskrune(__ct_rune_t, unsigned long);
int		__sbmaskrune(__ct_rune_t, unsigned long);
int		__istype(__ct_rune_t, unsigned long);
int		__sbistype(__ct_rune_t, unsigned long);
int		__isctype(__ct_rune_t, unsigned long);
__ct_rune_t	__toupper(__ct_rune_t);
__ct_rune_t	__sbtoupper(__ct_rune_t);
__ct_rune_t	__tolower(__ct_rune_t);
__ct_rune_t	__sbtolower(__ct_rune_t);
int		__wcwidth(__ct_rune_t);
__END_DECLS
#endif /* using inlines */

#endif /* !__CTYPE_H_ */


code:
/*-
 * Copyright (c) 2002 Alfred Perlstein <alfred@FreeBSD.org>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	$FreeBSD: release/9.0.0/sys/sys/_semaphore.h 201546 2010-01-05 02:37:59Z davidxu $
 */
#ifndef __SEMAPHORE_H_
#define __SEMAPHORE_H_

typedef intptr_t semid_t;
struct timespec;

#define SEM_VALUE_MAX  __INT_MAX

#ifndef _KERNEL

__BEGIN_DECLS

int ksem_close(semid_t id);
int ksem_post(semid_t id);
int ksem_wait(semid_t id);
int ksem_trywait(semid_t id);
int ksem_timedwait(semid_t id, const struct timespec *abstime);
int ksem_init(semid_t *idp, unsigned int value);
int ksem_open(semid_t *idp, const char *name, int oflag, mode_t mode,
    unsigned int value);
int ksem_unlink(const char *name);
int ksem_getvalue(semid_t id, int *val);
int ksem_destroy(semid_t id);

__END_DECLS

#endif /* !_KERNEL */

#endif /* __SEMAPHORE_H_ */


code:
/*-
 * Copyright (c) 1991, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)a.out.h	8.1 (Berkeley) 6/2/93
 * $FreeBSD: release/9.0.0/include/a.out.h 203964 2010-02-16 19:39:50Z imp $
 */

#ifndef	_AOUT_H_
#define	_AOUT_H_

#include <sys/types.h>
#include <machine/exec.h>
#include <sys/endian.h>
#include <sys/imgact_aout.h>
#include <machine/reloc.h>

#define _AOUT_INCLUDE_
#include <nlist.h>

#endif /* !_AOUT_H_ */


code:
/*-
 * Copyright (c) 1997 John S. Dyson.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. John S. Dyson's name may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * DISCLAIMER:  This code isn't warranted to do anything useful.  Anything
 * bad that happens because of using this software isn't the responsibility
 * of the author.  This software is distributed AS-IS.
 *
 * $FreeBSD: release/9.0.0/sys/sys/aio.h 189822 2009-03-14 19:17:00Z das $
 */

#ifndef _SYS_AIO_H_
#define	_SYS_AIO_H_

#include <sys/types.h>
#include <sys/signal.h>

/*
 * Returned by aio_cancel:
 */
#define	AIO_CANCELED		0x1
#define	AIO_NOTCANCELED		0x2
#define	AIO_ALLDONE		0x3

/*
 * LIO opcodes
 */
#define	LIO_NOP			0x0
#define LIO_WRITE		0x1
#define	LIO_READ		0x2
#ifdef _KERNEL
#define	LIO_SYNC		0x3
#endif

/*
 * LIO modes
 */
#define	LIO_NOWAIT		0x0
#define	LIO_WAIT		0x1

/*
 * Maximum number of allowed LIO operations
 */
#define	AIO_LISTIO_MAX		16

/*
 * Private members for aiocb -- don't access
 * directly.
 */
struct __aiocb_private {
	long	status;
	long	error;
	void	*kernelinfo;
};

/*
 * I/O control block
 */
typedef struct aiocb {
	int	aio_fildes;		/* File descriptor */
	off_t	aio_offset;		/* File offset for I/O */
	volatile void *aio_buf;         /* I/O buffer in process space */
	size_t	aio_nbytes;		/* Number of bytes for I/O */
	int	__spare__[2];
	void	*__spare2__;
	int	aio_lio_opcode;		/* LIO opcode */
	int	aio_reqprio;		/* Request priority -- ignored */
	struct	__aiocb_private	_aiocb_private;
	struct	sigevent aio_sigevent;	/* Signal to deliver */
} aiocb_t;

#ifndef _KERNEL

struct timespec;

__BEGIN_DECLS
/*
 * Asynchronously read from a file
 */
int	aio_read(struct aiocb *);

/*
 * Asynchronously write to file
 */
int	aio_write(struct aiocb *);

/*
 * List I/O Asynchronously/synchronously read/write to/from file
 *	"lio_mode" specifies whether or not the I/O is synchronous.
 *	"acb_list" is an array of "nacb_listent" I/O control blocks.
 *	when all I/Os are complete, the optional signal "sig" is sent.
 */
int	lio_listio(int, struct aiocb * const [], int, struct sigevent *);

/*
 * Get completion status
 *	returns EINPROGRESS until I/O is complete.
 *	this routine does not block.
 */
int	aio_error(const struct aiocb *);

/*
 * Finish up I/O, releasing I/O resources and returns the value
 *	that would have been associated with a synchronous I/O request.
 *	This routine must be called once and only once for each
 *	I/O control block who has had I/O associated with it.
 */
ssize_t	aio_return(struct aiocb *);

/*
 * Cancel I/O
 */
int	aio_cancel(int, struct aiocb *);

/*
 * Suspend until all specified I/O or timeout is complete.
 */
int	aio_suspend(const struct aiocb * const[], int, const struct timespec *);

#ifdef __BSD_VISIBLE
int	aio_waitcomplete(struct aiocb **, struct timespec *);
#endif

int	aio_fsync(int op, struct aiocb *aiocbp);
__END_DECLS

#else

/* Forward declarations for prototypes below. */
struct socket;
struct sockbuf;

extern void (*aio_swake)(struct socket *, struct sockbuf *);

#endif

#endif


code:
/* lint -save -library Flexelint comment for external headers */

/*-
 * Copyright (c) 2001 Charles Mott <cm@linktel.net>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * $FreeBSD: release/9.0.0/sys/netinet/libalias/alias.h 223080 2011-06-14 13:35:24Z ae $
 */

/*
 * Alias.h defines the outside world interfaces for the packet aliasing
 * software.
 *
 * This software is placed into the public domain with no restrictions on its
 * distribution.
 */

#ifndef _ALIAS_H_
#define	_ALIAS_H_

#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>

#define LIBALIAS_BUF_SIZE 128
#ifdef	_KERNEL
/*
 * The kernel version of libalias does not support these features.
 */
#define	NO_FW_PUNCH
#define	NO_USE_SOCKETS
#endif

/*
 * The external interface to libalias, the packet aliasing engine.
 *
 * There are two sets of functions:
 *
 * PacketAlias*() the old API which doesn't take an instance pointer
 * and therefore can only have one packet engine at a time.
 *
 * LibAlias*() the new API which takes as first argument a pointer to
 * the instance of the packet aliasing engine.
 *
 * The functions otherwise correspond to each other one for one, except
 * for the LibAliasUnaliasOut()/PacketUnaliasOut() function which were
 * were misnamed in the old API.
 */

/*
 * The instance structure
 */
struct libalias;

/*
 * An anonymous structure, a pointer to which is returned from
 * PacketAliasRedirectAddr(), PacketAliasRedirectPort() or
 * PacketAliasRedirectProto(), passed to PacketAliasAddServer(),
 * and freed by PacketAliasRedirectDelete().
 */
struct alias_link;

/* Initialization and control functions. */
struct libalias *LibAliasInit(struct libalias *);
void		LibAliasSetAddress(struct libalias *, struct in_addr _addr);
void		LibAliasSetFWBase(struct libalias *, unsigned int _base, unsigned int _num);
void		LibAliasSetSkinnyPort(struct libalias *, unsigned int _port);
unsigned int
		LibAliasSetMode(struct libalias *, unsigned int _flags, unsigned int _mask);
void		LibAliasUninit(struct libalias *);

/* Packet Handling functions. */
int		LibAliasIn (struct libalias *, char *_ptr, int _maxpacketsize);
int		LibAliasOut(struct libalias *, char *_ptr, int _maxpacketsize);
int		LibAliasOutTry(struct libalias *, char *_ptr, int _maxpacketsize, int _create);
int		LibAliasUnaliasOut(struct libalias *, char *_ptr, int _maxpacketsize);

/* Port and address redirection functions. */

int
LibAliasAddServer(struct libalias *, struct alias_link *_lnk,
    struct in_addr _addr, unsigned short _port);
struct alias_link *
LibAliasRedirectAddr(struct libalias *, struct in_addr _src_addr,
    struct in_addr _alias_addr);
int		LibAliasRedirectDynamic(struct libalias *, struct alias_link *_lnk);
void		LibAliasRedirectDelete(struct libalias *, struct alias_link *_lnk);
struct alias_link *
LibAliasRedirectPort(struct libalias *, struct in_addr _src_addr,
    unsigned short _src_port, struct in_addr _dst_addr,
    unsigned short _dst_port, struct in_addr _alias_addr,
    unsigned short _alias_port, unsigned char _proto);
struct alias_link *
LibAliasRedirectProto(struct libalias *, struct in_addr _src_addr,
    struct in_addr _dst_addr, struct in_addr _alias_addr,
    unsigned char _proto);

/* Fragment Handling functions. */
void		LibAliasFragmentIn(struct libalias *, char *_ptr, char *_ptr_fragment);
char           *LibAliasGetFragment(struct libalias *, char *_ptr);
int		LibAliasSaveFragment(struct libalias *, char *_ptr);

/* Miscellaneous functions. */
int		LibAliasCheckNewLink(struct libalias *);
unsigned short
		LibAliasInternetChecksum(struct libalias *, unsigned short *_ptr, int _nbytes);
void		LibAliasSetTarget(struct libalias *, struct in_addr _target_addr);

/* Transparent proxying routines. */
int		LibAliasProxyRule(struct libalias *, const char *_cmd);

/* Module handling API */
int             LibAliasLoadModule(char *);
int             LibAliasUnLoadAllModule(void);
int             LibAliasRefreshModules(void);

/* Mbuf helper function. */
struct mbuf    *m_megapullup(struct mbuf *, int);

/*
 * Mode flags and other constants.
 */

/* Mode flags, set using PacketAliasSetMode() */

/*
 * If PKT_ALIAS_LOG is set, a message will be printed to /var/log/alias.log
 * every time a link is created or deleted.  This is useful for debugging.
 */
#define	PKT_ALIAS_LOG			0x01

/*
 * If PKT_ALIAS_DENY_INCOMING is set, then incoming connections (e.g. to ftp,
 * telnet or web servers will be prevented by the aliasing mechanism.
 */
#define	PKT_ALIAS_DENY_INCOMING		0x02

/*
 * If PKT_ALIAS_SAME_PORTS is set, packets will be attempted sent from the
 * same port as they originated on.  This allows e.g. rsh to work *99% of the
 * time*, but _not_ 100% (it will be slightly flakey instead of not working
 * at all).  This mode bit is set by PacketAliasInit(), so it is a default
 * mode of operation.
 */
#define	PKT_ALIAS_SAME_PORTS		0x04

/*
 * If PKT_ALIAS_USE_SOCKETS is set, then when partially specified links (e.g.
 * destination port and/or address is zero), the packet aliasing engine will
 * attempt to allocate a socket for the aliasing port it chooses.  This will
 * avoid interference with the host machine.  Fully specified links do not
 * require this.  This bit is set after a call to PacketAliasInit(), so it is
 * a default mode of operation.
 */
#ifndef	NO_USE_SOCKETS
#define	PKT_ALIAS_USE_SOCKETS		0x08
#endif
/*-
 * If PKT_ALIAS_UNREGISTERED_ONLY is set, then only packets with
 * unregistered source addresses will be aliased.  Private
 * addresses are those in the following ranges:
 *
 *		10.0.0.0     ->   10.255.255.255
 *		172.16.0.0   ->   172.31.255.255
 *		192.168.0.0  ->   192.168.255.255
 */
#define	PKT_ALIAS_UNREGISTERED_ONLY	0x10

/*
 * If PKT_ALIAS_RESET_ON_ADDR_CHANGE is set, then the table of dynamic
 * aliasing links will be reset whenever PacketAliasSetAddress() changes the
 * default aliasing address.  If the default aliasing address is left
 * unchanged by this function call, then the table of dynamic aliasing links
 * will be left intact.  This bit is set after a call to PacketAliasInit().
 */
#define	PKT_ALIAS_RESET_ON_ADDR_CHANGE	0x20

/*
 * If PKT_ALIAS_PROXY_ONLY is set, then NAT will be disabled and only
 * transparent proxying is performed.
 */
#define	PKT_ALIAS_PROXY_ONLY		0x40

/*
 * If PKT_ALIAS_REVERSE is set, the actions of PacketAliasIn() and
 * PacketAliasOut() are reversed.
 */
#define	PKT_ALIAS_REVERSE		0x80

#ifndef NO_FW_PUNCH
/*
 * If PKT_ALIAS_PUNCH_FW is set, active FTP and IRC DCC connections will
 * create a 'hole' in the firewall to allow the transfers to work.  The
 * ipfw rule number that the hole is created with is controlled by
 * PacketAliasSetFWBase().  The hole will be attached to that
 * particular alias_link, so when the link goes away the hole is deleted.
 */
#define	PKT_ALIAS_PUNCH_FW		0x100
#endif

/*
 * If PKT_ALIAS_SKIP_GLOBAL is set, nat instance is not checked for matching
 * states in 'ipfw nat global' rule.
 */
#define	PKT_ALIAS_SKIP_GLOBAL		0x200

/* Function return codes. */
#define	PKT_ALIAS_ERROR			-1
#define	PKT_ALIAS_OK			1
#define	PKT_ALIAS_IGNORED		2
#define	PKT_ALIAS_UNRESOLVED_FRAGMENT	3
#define	PKT_ALIAS_FOUND_HEADER_FRAGMENT	4

#endif				/* !_ALIAS_H_ */

/* lint -restore */


code:
/*	$FreeBSD: release/9.0.0/sys/contrib/altq/altq/altq.h 130368 2004-06-12 00:57:20Z mlaier $	*/
/*	$KAME: altq.h,v 1.10 2003/07/10 12:07:47 kjc Exp $	*/

/*
 * Copyright (C) 1998-2003
 *	Sony Computer Science Laboratories Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#ifndef _ALTQ_ALTQ_H_
#define	_ALTQ_ALTQ_H_

#if 0
/*
 * allow altq-3 (altqd(8) and /dev/altq) to coexist with the new pf-based altq.
 * altq3 is mainly for research experiments. pf-based altq is for daily use.
 */
#define ALTQ3_COMPAT		/* for compatibility with altq-3 */
#define ALTQ3_CLFIER_COMPAT	/* for compatibility with altq-3 classifier */
#endif

#ifdef ALTQ3_COMPAT
#include <sys/param.h>
#include <sys/ioccom.h>
#include <sys/queue.h>
#include <netinet/in.h>

#ifndef IFNAMSIZ
#define	IFNAMSIZ	16
#endif
#endif /* ALTQ3_COMPAT */

/* altq discipline type */
#define	ALTQT_NONE		0	/* reserved */
#define	ALTQT_CBQ		1	/* cbq */
#define	ALTQT_WFQ		2	/* wfq */
#define	ALTQT_AFMAP		3	/* afmap */
#define	ALTQT_FIFOQ		4	/* fifoq */
#define	ALTQT_RED		5	/* red */
#define	ALTQT_RIO		6	/* rio */
#define	ALTQT_LOCALQ		7	/* local use */
#define	ALTQT_HFSC		8	/* hfsc */
#define	ALTQT_CDNR		9	/* traffic conditioner */
#define	ALTQT_BLUE		10	/* blue */
#define	ALTQT_PRIQ		11	/* priority queue */
#define	ALTQT_JOBS		12	/* JoBS */
#define	ALTQT_MAX		13	/* should be max discipline type + 1 */

#ifdef ALTQ3_COMPAT
struct	altqreq {
	char	ifname[IFNAMSIZ];	/* if name, e.g. "en0" */
	u_long	arg;			/* request-specific argument */
};
#endif

/* simple token backet meter profile */
struct	tb_profile {
	u_int	rate;	/* rate in bit-per-sec */
	u_int	depth;	/* depth in bytes */
};

#ifdef ALTQ3_COMPAT
struct	tbrreq {
	char	ifname[IFNAMSIZ];	/* if name, e.g. "en0" */
	struct	tb_profile tb_prof;	/* token bucket profile */
};

#ifdef ALTQ3_CLFIER_COMPAT
/*
 * common network flow info structure
 */
struct flowinfo {
	u_char		fi_len;		/* total length */
	u_char		fi_family;	/* address family */
	u_int8_t	fi_data[46];	/* actually longer; address family
					   specific flow info. */
};

/*
 * flow info structure for internet protocol family.
 * (currently this is the only protocol family supported)
 */
struct flowinfo_in {
	u_char		fi_len;		/* sizeof(struct flowinfo_in) */
	u_char		fi_family;	/* AF_INET */
	u_int8_t	fi_proto;	/* IPPROTO_XXX */
	u_int8_t	fi_tos;		/* type-of-service */
	struct in_addr	fi_dst;		/* dest address */
	struct in_addr	fi_src;		/* src address */
	u_int16_t	fi_dport;	/* dest port */
	u_int16_t	fi_sport;	/* src port */
	u_int32_t	fi_gpi;		/* generalized port id for ipsec */
	u_int8_t	_pad[28];	/* make the size equal to
					   flowinfo_in6 */
};

#ifdef SIN6_LEN
struct flowinfo_in6 {
	u_char		fi6_len;	/* sizeof(struct flowinfo_in6) */
	u_char		fi6_family;	/* AF_INET6 */
	u_int8_t	fi6_proto;	/* IPPROTO_XXX */
	u_int8_t	fi6_tclass;	/* traffic class */
	u_int32_t	fi6_flowlabel;	/* ipv6 flowlabel */
	u_int16_t	fi6_dport;	/* dest port */
	u_int16_t	fi6_sport;	/* src port */
	u_int32_t	fi6_gpi;	/* generalized port id */
	struct in6_addr fi6_dst;	/* dest address */
	struct in6_addr fi6_src;	/* src address */
};
#endif /* INET6 */

/*
 * flow filters for AF_INET and AF_INET6
 */
struct flow_filter {
	int			ff_ruleno;
	struct flowinfo_in	ff_flow;
	struct {
		struct in_addr	mask_dst;
		struct in_addr	mask_src;
		u_int8_t	mask_tos;
		u_int8_t	_pad[3];
	} ff_mask;
	u_int8_t _pad2[24];	/* make the size equal to flow_filter6 */
};

#ifdef SIN6_LEN
struct flow_filter6 {
	int			ff_ruleno;
	struct flowinfo_in6	ff_flow6;
	struct {
		struct in6_addr	mask6_dst;
		struct in6_addr	mask6_src;
		u_int8_t	mask6_tclass;
		u_int8_t	_pad[3];
	} ff_mask6;
};
#endif /* INET6 */
#endif /* ALTQ3_CLFIER_COMPAT */
#endif /* ALTQ3_COMPAT */

/*
 * generic packet counter
 */
struct pktcntr {
	u_int64_t	packets;
	u_int64_t	bytes;
};

#define	PKTCNTR_ADD(cntr, len)	\
	do { (cntr)->packets++; (cntr)->bytes += len; } while (/*CONSTCOND*/ 0)

#ifdef ALTQ3_COMPAT
/*
 * altq related ioctls
 */
#define	ALTQGTYPE	_IOWR('q', 0, struct altqreq)	/* get queue type */
#if 0
/*
 * these ioctls are currently discipline-specific but could be shared
 * in the future.
 */
#define	ALTQATTACH	_IOW('q', 1, struct altqreq)	/* attach discipline */
#define	ALTQDETACH	_IOW('q', 2, struct altqreq)	/* detach discipline */
#define	ALTQENABLE	_IOW('q', 3, struct altqreq)	/* enable discipline */
#define	ALTQDISABLE	_IOW('q', 4, struct altqreq)	/* disable discipline*/
#define	ALTQCLEAR	_IOW('q', 5, struct altqreq)	/* (re)initialize */
#define	ALTQCONFIG	_IOWR('q', 6, struct altqreq)	/* set config params */
#define	ALTQADDCLASS	_IOWR('q', 7, struct altqreq)	/* add a class */
#define	ALTQMODCLASS	_IOWR('q', 8, struct altqreq)	/* modify a class */
#define	ALTQDELCLASS	_IOWR('q', 9, struct altqreq)	/* delete a class */
#define	ALTQADDFILTER	_IOWR('q', 10, struct altqreq)	/* add a filter */
#define	ALTQDELFILTER	_IOWR('q', 11, struct altqreq)	/* delete a filter */
#define	ALTQGETSTATS	_IOWR('q', 12, struct altqreq)	/* get statistics */
#define	ALTQGETCNTR	_IOWR('q', 13, struct altqreq)	/* get a pkt counter */
#endif /* 0 */
#define	ALTQTBRSET	_IOW('q', 14, struct tbrreq)	/* set tb regulator */
#define	ALTQTBRGET	_IOWR('q', 15, struct tbrreq)	/* get tb regulator */
#endif /* ALTQ3_COMPAT */

#ifdef _KERNEL
#include <altq/altq_var.h>
#endif

#endif /* _ALTQ_ALTQ_H_ */


code:
/*	$KAME: altq_cbq.h,v 1.12 2003/10/03 05:05:15 kjc Exp $	*/

/*
 * Copyright (c) Sun Microsystems, Inc. 1993-1998 All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the SMCC Technology
 *      Development Group at Sun Microsystems, Inc.
 *
 * 4. The name of the Sun Microsystems, Inc nor may not be used to endorse or
 *      promote products derived from this software without specific prior
 *      written permission.
 *
 * SUN MICROSYSTEMS DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE OR THE
 * SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE.  The software is
 * provided "as is" without express or implied warranty of any kind.
 *
 * These notices must be retained in any copies of any part of this software.
 */

#ifndef _ALTQ_ALTQ_CBQ_H_
#define	_ALTQ_ALTQ_CBQ_H_

#include <altq/altq.h>
#include <altq/altq_rmclass.h>
#include <altq/altq_red.h>
#include <altq/altq_rio.h>

#ifdef __cplusplus
extern "C" {
#endif

#define	NULL_CLASS_HANDLE	0

/* class flags should be same as class flags in rm_class.h */
#define	CBQCLF_RED		0x0001	/* use RED */
#define	CBQCLF_ECN		0x0002  /* use RED/ECN */
#define	CBQCLF_RIO		0x0004  /* use RIO */
#define	CBQCLF_FLOWVALVE	0x0008	/* use flowvalve (aka penalty-box) */
#define	CBQCLF_CLEARDSCP	0x0010  /* clear diffserv codepoint */
#define	CBQCLF_BORROW		0x0020  /* borrow from parent */

/* class flags only for root class */
#define	CBQCLF_WRR		0x0100	/* weighted-round robin */
#define	CBQCLF_EFFICIENT	0x0200  /* work-conserving */

/* class flags for special classes */
#define	CBQCLF_ROOTCLASS	0x1000	/* root class */
#define	CBQCLF_DEFCLASS		0x2000	/* default class */
#ifdef ALTQ3_COMPAT
#define	CBQCLF_CTLCLASS		0x4000	/* control class */
#endif
#define	CBQCLF_CLASSMASK	0xf000	/* class mask */

#define	CBQ_MAXQSIZE		200
#define	CBQ_MAXPRI		RM_MAXPRIO

typedef struct _cbq_class_stats_ {
	u_int32_t	handle;
	u_int		depth;

	struct pktcntr	xmit_cnt;	/* packets sent in this class */
	struct pktcntr	drop_cnt;	/* dropped packets */
	u_int		over;		/* # times went over limit */
	u_int		borrows;	/* # times tried to borrow */
	u_int		overactions;	/* # times invoked overlimit action */
	u_int		delays;		/* # times invoked delay actions */

	/* other static class parameters useful for debugging */
	int		priority;
	int		maxidle;
	int		minidle;
	int		offtime;
	int		qmax;
	int		ns_per_byte;
	int		wrr_allot;

	int		qcnt;		/* # packets in queue */
	int		avgidle;

	/* red and rio related info */
	int		qtype;
	struct redstats	red[3];
} class_stats_t;

#ifdef ALTQ3_COMPAT
/*
 * Define structures associated with IOCTLS for cbq.
 */

/*
 * Define the CBQ interface structure.  This must be included in all
 * IOCTL's such that the CBQ driver may find the appropriate CBQ module
 * associated with the network interface to be affected.
 */
struct cbq_interface {
	char	cbq_ifacename[IFNAMSIZ];
};

typedef struct cbq_class_spec {
	u_int		priority;
	u_int		nano_sec_per_byte;
	u_int		maxq;
	u_int		maxidle;
	int		minidle;
	u_int		offtime;
	u_int32_t	parent_class_handle;
	u_int32_t	borrow_class_handle;

	u_int		pktsize;
	int		flags;
} cbq_class_spec_t;

struct cbq_add_class {
	struct cbq_interface	cbq_iface;

	cbq_class_spec_t	cbq_class;
	u_int32_t		cbq_class_handle;
};

struct cbq_delete_class {
	struct cbq_interface	cbq_iface;
	u_int32_t		cbq_class_handle;
};

struct cbq_modify_class {
	struct cbq_interface	cbq_iface;

	cbq_class_spec_t	cbq_class;
	u_int32_t		cbq_class_handle;
};

struct cbq_add_filter {
	struct cbq_interface		cbq_iface;
	u_int32_t		cbq_class_handle;
	struct flow_filter	cbq_filter;

	u_long			cbq_filter_handle;
};

struct cbq_delete_filter {
	struct cbq_interface	cbq_iface;
	u_long			cbq_filter_handle;
};

/* number of classes are returned in nclasses field */
struct cbq_getstats {
	struct cbq_interface	iface;
	int			nclasses;
	class_stats_t		*stats;
};

/*
 * Define IOCTLs for CBQ.
 */
#define	CBQ_IF_ATTACH		_IOW('Q', 1, struct cbq_interface)
#define	CBQ_IF_DETACH		_IOW('Q', 2, struct cbq_interface)
#define	CBQ_ENABLE		_IOW('Q', 3, struct cbq_interface)
#define	CBQ_DISABLE		_IOW('Q', 4, struct cbq_interface)
#define	CBQ_CLEAR_HIERARCHY	_IOW('Q', 5, struct cbq_interface)
#define	CBQ_ADD_CLASS		_IOWR('Q', 7, struct cbq_add_class)
#define	CBQ_DEL_CLASS		_IOW('Q', 8, struct cbq_delete_class)
#define	CBQ_MODIFY_CLASS	_IOWR('Q', 9, struct cbq_modify_class)
#define	CBQ_ADD_FILTER		_IOWR('Q', 10, struct cbq_add_filter)
#define	CBQ_DEL_FILTER		_IOW('Q', 11, struct cbq_delete_filter)
#define	CBQ_GETSTATS		_IOWR('Q', 12, struct cbq_getstats)
#endif /* ALTQ3_COMPAT */

#ifdef _KERNEL
/*
 * Define macros only good for kernel drivers and modules.
 */
#define	CBQ_WATCHDOG		(hz / 20)
#define	CBQ_TIMEOUT		10
#define	CBQ_LS_TIMEOUT		(20 * hz / 1000)

#define	CBQ_MAX_CLASSES	256

#ifdef ALTQ3_COMPAT
#define	CBQ_MAX_FILTERS 256

#define	DISABLE		0x00
#define	ENABLE		0x01
#endif /* ALTQ3_COMPAT */

/*
 * Define State structures.
 */
typedef struct cbqstate {
#ifdef ALTQ3_COMPAT
	struct cbqstate		*cbq_next;
#endif
	int			 cbq_qlen;	/* # of packets in cbq */
	struct rm_class		*cbq_class_tbl[CBQ_MAX_CLASSES];

	struct rm_ifdat		 ifnp;
	struct callout		 cbq_callout;	/* for timeouts */
#ifdef ALTQ3_CLFIER_COMPAT
	struct acc_classifier	cbq_classifier;
#endif
} cbq_state_t;

#endif /* _KERNEL */

#ifdef __cplusplus
}
#endif

#endif /* !_ALTQ_ALTQ_CBQ_H_ */


code:
/*	$KAME: altq_cdnr.h,v 1.9 2003/07/10 12:07:48 kjc Exp $	*/

/*
 * Copyright (C) 1999-2002
 *	Sony Computer Science Laboratories Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef _ALTQ_ALTQ_CDNR_H_
#define	_ALTQ_ALTQ_CDNR_H_

#include <altq/altq.h>

/*
 * traffic conditioner element types
 */
#define	TCETYPE_NONE		0
#define	TCETYPE_TOP		1	/* top level conditioner */
#define	TCETYPE_ELEMENT		2	/* a simple tc element */
#define	TCETYPE_TBMETER		3	/* token bucket meter */
#define	TCETYPE_TRTCM		4	/* (two-rate) three color marker */
#define	TCETYPE_TSWTCM		5	/* time sliding window 3-color maker */

/*
 * traffic conditioner action
 */
struct cdnr_block;

struct tc_action {
	int	tca_code;	/* e.g., TCACODE_PASS */
	/* tca_code dependent variable */
	union {
		u_long		un_value;	/* template */
		u_int8_t	un_dscp;	/* diffserv code point */
		u_long		un_handle;	/* tc action handle */
		struct cdnr_block *un_next;	/* next tc element block */
	} tca_un;
};
#define	tca_value	tca_un.un_value
#define	tca_dscp	tca_un.un_dscp
#define	tca_handle	tca_un.un_handle
#define	tca_next	tca_un.un_next

#define	TCACODE_NONE	0	/* action is not set */
#define	TCACODE_PASS	1 	/* pass this packet */
#define	TCACODE_DROP	2	/* discard this packet */
#define	TCACODE_RETURN	3	/* do not process this packet */
#define	TCACODE_MARK	4	/* mark dscp */
#define	TCACODE_HANDLE	5	/* take action specified by handle */
#define	TCACODE_NEXT	6	/* take action in the next tc element */
#define	TCACODE_MAX	6

#define	CDNR_NULL_HANDLE	0

struct cdnr_interface {
	char	cdnr_ifname[IFNAMSIZ];  /* interface name (e.g., fxp0) */
};

/* simple element operations */
struct cdnr_add_element {
	struct cdnr_interface	iface;
	struct tc_action	action;

	u_long			cdnr_handle;	/* return value */
};

struct cdnr_delete_element {
	struct cdnr_interface	iface;
	u_long			cdnr_handle;
};

/* token-bucket meter operations */
struct cdnr_add_tbmeter {
	struct cdnr_interface	iface;
	struct tb_profile	profile;
	struct tc_action	in_action;
	struct tc_action	out_action;

	u_long			cdnr_handle;	/* return value */
};

struct cdnr_modify_tbmeter {
	struct cdnr_interface	iface;
	u_long			cdnr_handle;
	struct tb_profile	profile;
};

struct cdnr_tbmeter_stats {
	struct cdnr_interface	iface;
	u_long			cdnr_handle;
	struct pktcntr		in_cnt;
	struct pktcntr		out_cnt;
};

/* two-rate three-color marker operations */
struct cdnr_add_trtcm {
	struct cdnr_interface	iface;
	struct tb_profile	cmtd_profile;	/* profile for committed tb */
	struct tb_profile	peak_profile;	/* profile for peak tb */
	struct tc_action	green_action;	/* action for green packets */
	struct tc_action	yellow_action;	/* action for yellow packets */
	struct tc_action	red_action;	/* action for red packets */
	int			coloraware;	/* color-aware/color-blind */

	u_long			cdnr_handle;	/* return value */
};

struct cdnr_modify_trtcm {
	struct cdnr_interface	iface;
	u_long			cdnr_handle;
	struct tb_profile	cmtd_profile;	/* profile for committed tb */
	struct tb_profile	peak_profile;	/* profile for peak tb */
	int			coloraware;	/* color-aware/color-blind */
};

struct cdnr_tcm_stats {
	struct cdnr_interface	iface;
	u_long			cdnr_handle;
	struct pktcntr		green_cnt;
	struct pktcntr		yellow_cnt;
	struct pktcntr		red_cnt;
};

/* time sliding window three-color marker operations */
struct cdnr_add_tswtcm {
	struct cdnr_interface	iface;
	u_int32_t		cmtd_rate;	/* committed rate (bits/sec) */
	u_int32_t		peak_rate;	/* peak rate (bits/sec) */
	u_int32_t		avg_interval;	/* averaging interval (msec) */
	struct tc_action	green_action;	/* action for green packets */
	struct tc_action	yellow_action;	/* action for yellow packets */
	struct tc_action	red_action;	/* action for red packets */

	u_long			cdnr_handle;	/* return value */
};

struct cdnr_modify_tswtcm {
	struct cdnr_interface	iface;
	u_long			cdnr_handle;
	u_int32_t		cmtd_rate;	/* committed rate (bits/sec) */
	u_int32_t		peak_rate;	/* peak rate (bits/sec) */
	u_int32_t		avg_interval;	/* averaging interval (msec) */
};

struct cdnr_add_filter {
	struct cdnr_interface	iface;
	u_long			cdnr_handle;
#ifdef ALTQ3_CLFIER_COMPAT
	struct flow_filter	filter;
#endif
	u_long			filter_handle;	/* return value */
};

struct cdnr_delete_filter {
	struct cdnr_interface	iface;
	u_long			filter_handle;
};

struct tce_stats {
	u_long			tce_handle;	/* tc element handle */
	int			tce_type;	/* e.g., TCETYPE_ELEMENT */
	struct pktcntr		tce_cnts[3];	/* tcm returns 3 counters */
};

struct cdnr_get_stats {
	struct cdnr_interface	iface;
	struct pktcntr		cnts[TCACODE_MAX+1];

	/* element stats */
	int			nskip;		/* skip # of elements */
	int			nelements;	/* # of element stats (WR) */
	struct tce_stats	*tce_stats;	/* pointer to stats array */
};

#define	CDNR_IF_ATTACH		_IOW('Q', 1, struct cdnr_interface)
#define	CDNR_IF_DETACH		_IOW('Q', 2, struct cdnr_interface)
#define	CDNR_ENABLE		_IOW('Q', 3, struct cdnr_interface)
#define	CDNR_DISABLE		_IOW('Q', 4, struct cdnr_interface)
#define	CDNR_ADD_FILTER		_IOWR('Q', 10, struct cdnr_add_filter)
#define	CDNR_DEL_FILTER		_IOW('Q', 11, struct cdnr_delete_filter)
#define	CDNR_GETSTATS		_IOWR('Q', 12, struct cdnr_get_stats)
#define	CDNR_ADD_ELEM		_IOWR('Q', 30, struct cdnr_add_element)
#define	CDNR_DEL_ELEM		_IOW('Q', 31, struct cdnr_delete_element)
#define	CDNR_ADD_TBM		_IOWR('Q', 32, struct cdnr_add_tbmeter)
#define	CDNR_MOD_TBM		_IOW('Q', 33, struct cdnr_modify_tbmeter)
#define	CDNR_TBM_STATS		_IOWR('Q', 34, struct cdnr_tbmeter_stats)
#define	CDNR_ADD_TCM		_IOWR('Q', 35, struct cdnr_add_trtcm)
#define	CDNR_MOD_TCM		_IOWR('Q', 36, struct cdnr_modify_trtcm)
#define	CDNR_TCM_STATS		_IOWR('Q', 37, struct cdnr_tcm_stats)
#define	CDNR_ADD_TSW		_IOWR('Q', 38, struct cdnr_add_tswtcm)
#define	CDNR_MOD_TSW		_IOWR('Q', 39, struct cdnr_modify_tswtcm)

#ifndef DSCP_EF
/* diffserve code points */
#define	DSCP_MASK	0xfc
#define	DSCP_CUMASK	0x03
#define	DSCP_EF		0xb8
#define	DSCP_AF11	0x28
#define	DSCP_AF12	0x30
#define	DSCP_AF13	0x38
#define	DSCP_AF21	0x48
#define	DSCP_AF22	0x50
#define	DSCP_AF23	0x58
#define	DSCP_AF31	0x68
#define	DSCP_AF32	0x70
#define	DSCP_AF33	0x78
#define	DSCP_AF41	0x88
#define	DSCP_AF42	0x90
#define	DSCP_AF43	0x98
#define	AF_CLASSMASK		0xe0
#define	AF_DROPPRECMASK		0x18
#endif

#ifdef _KERNEL

/*
 * packet information passed to the input function of tc elements
 */
struct cdnr_pktinfo {
	int		pkt_len;	/* packet length */
	u_int8_t	pkt_dscp;	/* diffserv code point */
};

/*
 * traffic conditioner control block common to all types of tc elements
 */
struct cdnr_block {
	LIST_ENTRY(cdnr_block)	cb_next;
	int		cb_len;		/* size of this tc element */
	int		cb_type;	/* cdnr block type */
	int		cb_ref;		/* reference count of this element */
	u_long		cb_handle;	/* handle of this tc element */
	struct top_cdnr *cb_top;	/* back pointer to top */
	struct tc_action cb_action;	/* top level action for this tcb */
	struct tc_action *(*cb_input)(struct cdnr_block *,
				      struct cdnr_pktinfo *);
};

/*
 * top level traffic conditioner structure for an interface
 */
struct top_cdnr {
	struct cdnr_block	tc_block;

	LIST_ENTRY(top_cdnr)	tc_next;
	struct ifaltq		*tc_ifq;

	LIST_HEAD(, cdnr_block) tc_elements;
#ifdef ALTQ3_CLFIER_COMPAT
	struct acc_classifier	tc_classifier;
#endif
	struct pktcntr		tc_cnts[TCACODE_MAX+1];
};

/* token bucket element */
struct tbe {
	u_int64_t	rate;
	u_int64_t	depth;

	u_int64_t	token;
	u_int64_t	filluptime;
	u_int64_t	last;
};

/* token bucket meter structure */
struct tbmeter {
	struct cdnr_block	cdnrblk;	/* conditioner block */
	struct tbe		tb;		/* token bucket */
	struct tc_action	in_action;	/* actions for IN/OUT */
	struct tc_action	out_action;	/* actions for IN/OUT */
	struct pktcntr		in_cnt;		/* statistics for IN/OUT */
	struct pktcntr		out_cnt;	/* statistics for IN/OUT */
};

/* two-rate three-color marker structure */
struct trtcm {
	struct cdnr_block	cdnrblk;	/* conditioner block */
	struct tbe		cmtd_tb;	/* committed tb profile */
	struct tbe		peak_tb;	/* peak tb profile */
	struct tc_action	green_action;
	struct tc_action	yellow_action;
	struct tc_action	red_action;
	int			coloraware;
	u_int8_t		green_dscp;
	u_int8_t		yellow_dscp;
	u_int8_t		red_dscp;
	struct pktcntr		green_cnt;
	struct pktcntr		yellow_cnt;
	struct pktcntr		red_cnt;
};

/* time sliding window three-color marker structure */
struct tswtcm {
	struct cdnr_block	cdnrblk;	/* conditioner block */

	u_int32_t		avg_rate;	/* average rate (bytes/sec) */
	u_int64_t		t_front;	/* timestamp of last update */

	u_int64_t		timewin;	/* average interval */
	u_int32_t		cmtd_rate;	/* committed target rate */
	u_int32_t		peak_rate;	/* peak target rate */
	struct tc_action	green_action;
	struct tc_action	yellow_action;
	struct tc_action	red_action;
	u_int8_t		green_dscp;
	u_int8_t		yellow_dscp;
	u_int8_t		red_dscp;
	struct pktcntr		green_cnt;
	struct pktcntr		yellow_cnt;
	struct pktcntr		red_cnt;
};

#endif /* _KERNEL */

#endif /* _ALTQ_ALTQ_CDNR_H_ */