1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
|
/** \file
* \brief The protocol header. All the facilities related to over-the-wire data
* formats are defined here.
*/
/*
* Copyright (c) 2019-2022 David Timber <dxdt@dev.snart.me>
*
* 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.
*/
#pragma once
#include "util_ct.h"
#include <stdint.h>
#include <stddef.h>
#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;
typedef struct prne_htbt_status prne_htbt_status_t;
typedef struct prne_htbt_host_info prne_htbt_host_info_t;
typedef struct prne_htbt_msg_head prne_htbt_msg_head_t;
typedef struct prne_htbt_cmd prne_htbt_cmd_t;
typedef struct prne_htbt_bin_meta prne_htbt_bin_meta_t;
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, // 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, // 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, // The null value
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 // Meta value: the number of enums.
} prne_iflag_t;
// The internet protocol version
typedef enum {
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]; // 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; // The IP address object
uint16_t port; // The port number in the host endian
};
// The host credential object
struct prne_host_cred {
char *id; // The null-terminated username string (dynamically allocated)
char *pw; // The null-terminated password string (dynamically allocated)
};
// The heartbeat framing protocol OP codes
typedef enum {
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, // 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, // Success
// More input data required or more output buffer required
PRNE_HTBT_SER_RC_MORE_BUF,
PRNE_HTBT_SER_RC_ERRNO, // errno set
PRNE_HTBT_SER_RC_FMT_ERR, // Input data format error
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; // 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; // 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; // 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; // 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; // 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]; // 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]; // 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; // 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; // 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
/*
* 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
/*
* 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)
/*
* 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 Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
void prne_htbt_init_msg_head (prne_htbt_msg_head_t *mh);
/**
* \brief Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
void prne_htbt_init_status (prne_htbt_status_t *s);
/**
* \brief Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
bool prne_htbt_alloc_host_info (
prne_htbt_host_info_t *hi,
const size_t cred_len,
const size_t bf_len);
/**
* \brief Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
void prne_htbt_init_bin_meta (prne_htbt_bin_meta_t *nb);
/**
* \brief Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
void prne_htbt_init_hover (prne_htbt_hover_t *ho);
/**
* \brief Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 *src,
prne_htbt_hover_t *dst);
/**
* \brief Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
void prne_htbt_init_stdio (prne_htbt_stdio_t *s);
/**
* \brief Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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 Initialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
void prne_htbt_init_rcb (prne_htbt_rcb_t *r);
/**
* \brief Deinitialisation function
* \see [/doc/impl.md#Resource Allocation](/doc/impl.md#resource_allocation)
*/
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,
const size_t add_argc,
char **add_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);
|