#include "morep.h"
#include "parse.h"
-#include "verbose.h"
-
#include "pdu_channel.h"
#include "pdu_encrypted_data.h"
#include "pdu_prng_param.h"
#include "pdu_key.h"
#include "pdu_raw_data.h"
#include "pdu_raw_data.h"
+#include "simulator.h"
+#include "verbose.h"
char *progname = NULL;
#define BUFMAX 4096
-typedef enum {
- nomod_e = 0,
- red_e,
- cryp_e,
- black_e
-} module_t;
-
-typedef enum {
- noserv_e = 0,
- cross_crypto_e,
- local_crypto_e,
- provisioning_e,
- prng_e,
- bypass_e,
- control_e
-} service_id_t;
-
-typedef enum {
- undef_pdu_e = 0,
- channel_e,
- clear_data_e,
- encrypted_data_e,
- key_e,
- prng_param_e,
- raw_data_e,
- status_e,
- nopdu_e
-} pdu_t;
-
-typedef struct {
- char *name;
- service_id_t service_id;
- uint8_t msgtype;
- pdu_t pdu;
-} message_t;
-
+/* definition of all messages */
message_t message_list[] = {
/* Cross cryptographic service */
{"", noserv_e, 0x00, undef_pdu_e}
};
-typedef struct {
- int morep;
- int mode;
- char *etype;
-} comm_t;
-
+/* list of communcation chanels */
#define MAXCOMMS 32
-
comm_t comm_list[MAXCOMMS] = {0};
-typedef struct {
- char *name;
- service_id_t service_id;
- comm_t tx;
- comm_t rx;
-} service_t;
-
+/* definition of all services */
service_t service_list[] = {
{"CROSS_CRYPTO", cross_crypto_e, {-1, 0, "0809"}, {-1, 1, "0809"}},
{"LOCAL_CRYPTO", local_crypto_e, {-1, 0, "080a"}, {-1, 1, "080a"}},
{"", noserv_e, {-1, 0, "0000"}, {-1, 1, "0000"}}
};
+/* signal handler */
void sig_handler (int sig)
{
switch (sig) {
}
}
+/* read a file */
char *read_stream (FILE *sd, int *plen)
{
VERBOSE (morep, TRACE, PRINTF ("read_stream\n"));
return buffer;
}
-void print_message (FILE *fd, char *etype, int mode, uint8_t msg, int seqnum, uint8_t *payload, int len)
-{
- fprintf (fd ? fd : stdout, "%c%s SEG=%d MSG=%d LEN=%d", mode ? 'T' : 'R', etype, seqnum, msg, len);
- if (len > 0) {
- int i;
- fprintf (fd ? fd : stdout, " PAYLOAD=");
- for (i = 0; i < len; i++) {
- fprintf (fd, "%02x", payload[i]);
- }
- }
- fprintf (fd ? fd : stdout, "\n");
-}
-
+/* main function */
int main (int argc, char **argv)
{
char *filename = NULL;
/* log message */
if (log) {
- fprintf (log, "%c%s[%s] SEG=%d MSG=%d LEN=%d %s ", mode ? 'T' : 'R', serv->name, comm->etype, seqnum, msg->msgtype, len, msg->name);
+ fprintf (log, "%c%s[%s] SEG=%d MSG=%d LEN=%d %s ", mode ? 'T' : 'R', serv->name,
+ comm->etype, seqnum, msg->msgtype, len, msg->name);
char buffer[1496 * 3 + 256] = {0};
switch (pdu) {
case channel_e:
/* string payload: "..." (space must be protected by '\') */
if ((*str == '"') && (slen > 1)) {
+ VERBOSE (morep, TRACE, PRINTF ("string payload: \"...\"\n"));
if (maxlen < slen - 2) slen = maxlen + 2;
if (str[slen - 1] == '"') {
len = slen - 2;
/* file payload: @filename */
else if (*str == '@') {
+ VERBOSE (morep, TRACE, PRINTF ("file payload: @filename\n"));
FILE *fid = fopen (str + 1, "r");
if (fid != NULL) {
while ((len < maxlen) && (!feof (fid))) {
/* hexa payload: xxxxxx [0-9a-fA-F] */
else {
- if (maxlen * 2 < slen) slen = maxlen * 2;
+ if (maxlen * 2 < slen) {
+ slen = maxlen * 2;
+ }
if (slen % 2 == 0) {
+ VERBOSE (morep, TRACE, PRINTF ("hexa payload: xxxxxx\n"));
len = slen / 2;
if (len > maxlen) {
VERBOSE (morep, WARNING, PRINTF ("string too large (%d > %d) for '%s'\n", len, maxlen, str));
for (int i = 0; i < len; i++) {
char digit[3] = {0};
char *ptr = NULL;
- digit[0] = str[3 * i];
- digit[1] = str[3 * i + 1];
+ digit[0] = str[2 * i];
+ digit[1] = str[2 * i + 1];
buffer[i] = strtol (digit, &ptr, 16);
if ((*ptr != '\0') && (*ptr != ' ') && (*ptr != '\t')) {
VERBOSE (morep, ERROR, PRINTF ("unrecognize hexa-string (%d) '%s'|%s\n", 2 * i, str, ptr));
return len;
}
-int snprint_array (char *buffer, int size, uint8_t *data, int nb)
+int snprint_array (char *buffer, int size, char *name, uint8_t *data, int nb)
{
int i;
- int len = 0;
+ int len = snprintf (buffer, size, " %s[%d]=", name, nb);
for (i = 0; (i < nb) && (len < size); i++) {
- len += snprintf (buffer + 2 * i, size - len, "%02x", data[i]);
+ len += snprintf (buffer + len, size - len, "%02x", data[i]);
}
return len;
}
@param name field name
@param buf preallocated storage
+ @param optinal parameter to use defined length
*/
-#define PARSE_ARRAY(name, buf) \
+#define PARSE_ARRAY(name, buf, ...) \
else if (strcmp (var, name) == 0) { \
- buf##_len = parse_array (val, buf, (buf##_len) ? buf##_len : (int)sizeof (buf)); \
+ buf##_len = parse_array (val, buf, (1 == __VA_ARGS__ + 0) ? buf##_len : (int)sizeof (buf)); \
}
/**
@param field data from structure
*/
#define FORMAT_INT(name, field) \
- len += snprintf (_buffer, _maxlen - len, "%d", field); \
+ len += snprintf (_buffer + len, _maxlen - len, " %s=%d", name, field); \
if (len == _maxlen) { \
VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
}
@param field data from structure
*/
#define FORMAT_DOUBLE(name, field) \
- len += snprintf (_buffer, _maxlen - len, "%g", field); \
+ len += snprintf (_buffer + len, _maxlen - len, " %s=%g", name, field); \
if (len == _maxlen) { \
VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
}
@param name field name
@param field data from structure
*/
-#define FORMAT_ARRAY(name, field) \
- len += snprint_array (_buffer, _maxlen - len, field, field##_len); \
- if (len == _maxlen) { \
- VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
+#define FORMAT_ARRAY(name, field) \
+ if (field##_len) { \
+ len += snprint_array (_buffer + len, _maxlen - len, name, field, field##_len); \
+ if (len == _maxlen) { \
+ VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
+ } \
}
/**
@param name field name
@param field data from structure
*/
-#define FORMAT_TAB(name, field) \
- len += snprint_array (_buffer, _maxlen - len, field, sizeof (field)); \
- if (len == _maxlen) { \
- VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
+#define FORMAT_TAB(name, field) \
+ len += snprint_array (_buffer + len, _maxlen - len, name, field, sizeof (field)); \
+ if (len == _maxlen) { \
+ VERBOSE (morep, WARNING, PRINTF ("field '%s' too large\n", #field)); \
}
/**
case 2: \
if (ptr + 1 < end) { \
field = ntohs (*((uint16_t *)ptr)); \
- ptr -= 2; \
+ ptr += 2; \
} else { \
VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
ptr = end + 1; \
case 4: \
if (ptr + 3 < end) { \
field = ntohl (*((uint32_t *)ptr)); \
- ptr -= 4; \
+ ptr += 4; \
} else { \
VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
ptr = end + 1; \
case 4: \
if (ptr + 3 < end) { \
field = *(float *)ptr; \
- ptr -= 4; \
+ ptr += 4; \
} else { \
VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
ptr = end + 1; \
case 8: \
if (ptr + 7 < end) { \
field = *(double *)ptr; \
- ptr -= 8; \
+ ptr += 8; \
} else { \
VERBOSE (morep, WARNING, PRINTF ("no data for field '%s'\n", name)); \
ptr = end + 1; \
@param name field name
@param field structure storage
+ @param optinal parameter to use defined length
*/
-#define DESERIAL_ARRAY(name, field) \
- if (field##_len == 0) { \
+#define DESERIAL_ARRAY(name, field, ...) \
+ if ((0 == __VA_ARGS__ + 0) && (ptr < end)) { \
memcpy (field, ptr, end - ptr); \
field##_len = end - ptr; \
ptr = end; \
int parse_array (char *val, uint8_t *buffer, int maxlen);
-int snprint_array (char *buffer, int size, uint8_t *data, int nb);
+int snprint_array (char *buffer, int size, char *name, uint8_t *data, int nb);
#endif /* __PARSE_H__ */
BEGIN_PARSE (line)
PARSE_INT ("CHANNELID", out->channel_id)
PARSE_INT ("BYPASSLEN", out->bypass_len)
- PARSE_ARRAY ("BYPASS", out->bypass)
+ PARSE_ARRAY ("BYPASS", out->bypass, 1)
PARSE_ARRAY ("DATA", out->data)
END_PARSE ()
}
BEGIN_DESERIAL (buffer, len)
DESERIAL_INT ("CHANNELID", out->channel_id)
DESERIAL_INT ("BYPASSLEN", out->bypass_len)
- DESERIAL_ARRAY ("BYPASS", out->bypass)
+ DESERIAL_ARRAY ("BYPASS", out->bypass, 1)
DESERIAL_ARRAY ("DATA", out->data)
END_DESERIAL ()
}
PARSE_INT ("CHANNELID", out->channel_id)
PARSE_TAB ("IV", out->iv)
PARSE_INT ("BYPASSLEN", out->bypass_len)
- PARSE_ARRAY ("BYPASS", out->bypass)
+ PARSE_ARRAY ("BYPASS", out->bypass, 1)
PARSE_ARRAY ("DATA", out->data)
END_PARSE ()
}
DESERIAL_INT ("CHANNELID", out->channel_id)
DESERIAL_TAB ("IV", out->iv)
DESERIAL_INT ("BYPASSLEN", out->bypass_len)
- DESERIAL_ARRAY ("BYPASS", out->bypass)
+ DESERIAL_ARRAY ("BYPASS", out->bypass, 1)
DESERIAL_ARRAY ("DATA", out->data)
END_DESERIAL ()
}
-# Test script
+# Cross crypto test script
-TCROSS_CRYPTO ENCRYPT_CROSS_ASYNC CHANNELID=2 BYPASSLEN=4 BYPASS=11:22:33:44 DATA=@script-cross_crypto.eth
-RCROSS_CRYPTO ENCRYPT_CROSS_ASYNC CHANNELID=2 BYPASSLEN=4 BYPASS=11:22:33:44 DATA=@script-cross_crypto.eth
+T:CROSS_CRYPTO ENCRYPT_CROSS_ASYNC CHANNELID=2 BYPASSLEN=4 BYPASS=11223344 DATA=@script-local_crypto.eth
+R:CROSS_CRYPTO ENCRYPT_CROSS_ASYNC
-TCROSS_CRYPTO ENCRYPTED_CROSS_ASYNC CHANNELID=9 BYPASSLEN=0 DATA=@script-local_crypto.eth
-RCROSS_CRYPTO ENCRYPTED_CROSS_ASYNC CHANNELID=9 BYPASSLEN=0 DATA=@script-local_crypto.eth
+T:CROSS_CRYPTO ENCRYPTED_CROSS_ASYNC CHANNELID=9 BYPASSLEN=1 BYPASS=55 DATA=@script-local_crypto.eth
+RCROSS_CRYPTO ENCRYPTED_CROSS_ASYNC
-TCROSS_CRYPTO DECRYPT_CROSS_ASYNC CHANNELID=5 BYPASSLEN=0 DATA=@script-local_crypto.eth
+T:CROSS_CRYPTO DECRYPT_CROSS_ASYNC CHANNELID=5 BYPASSLEN=0 DATA=@script-local_crypto.eth
RCROSS_CRYPTO DECRYPT_CROSS_ASYNC CHANNELID=5 BYPASSLEN=0 DATA=@script-local_crypto.eth
-TCROSS_CRYPTO DECRYPTED_CROSS_ASYNC CHANNELID=0 BYPASSLEN=4 BYPASS=11:22:33:44 DATA=@script-cross_crypto.eth
-RCROSS_CRYPTO DECRYPTED_CROSS_ASYNC CHANNELID=0 BYPASSLEN=4 BYPASS=11:22:33:44 DATA=@script-cross_crypto.eth
+T:CROSS_CRYPTO DECRYPTED_CROSS_ASYNC CHANNELID=0 BYPASSLEN=4 BYPASS=11223344 DATA=@script-cross_crypto.eth
+R:CROSS_CRYPTO DECRYPTED_CROSS_ASYNC CHANNELID=0 BYPASSLEN=4 BYPASS=11223344 DATA=@script-cross_crypto.eth
-# Test script
+# Local crypto test script
T:LOCAL_CRYPTO ENCRYPT_LOCAL_ASYNC CHANNELID=2 BYPASSLEN=4 BYPASS=11:22:33:44 DATA=@script-cross_crypto.eth
R:LOCAL_CRYPTO ENCRYPT_LOCAL_ASYNC CHANNELID=2 BYPASSLEN=4 BYPASS=11:22:33:44 DATA=@script-cross_crypto.eth
--- /dev/null
+/*
+ File name : simulator.10
+ Projet : MERLIN
+ Date of creation : 2025/04/10
+ Version : 1.0
+ Copyright : Thales SIX
+ Author : Laurent Mazet <laurent.mazet@thalesgroup.com>
+
+ Description : This file defines simulator types
+
+ History :
+ - initial version
+*/
+
+#ifndef __SIMULATOR_H__
+#define __SIMULATOR_H__
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+/**
+ @ingroup SIMULATOR
+
+ Module enumarate values
+*/
+typedef enum {
+ nomod_e = 0, /**< no module defined*/
+ red_e, /**< red radio module */
+ cryp_e, /**< cryptographic module */
+ black_e /**< black radio module */
+} module_t;
+
+/**
+ @ingroup SIMULATOR
+
+ Service enumarate values
+*/
+typedef enum {
+ noserv_e = 0, /**< no service defined */
+ cross_crypto_e, /**< cross cryptographic service */
+ local_crypto_e, /**< local cryptographic service */
+ provisioning_e, /**< provisioning service */
+ prng_e, /**< PRNG service */
+ bypass_e, /**< bypass service */
+ control_e /**< controlservice */
+} service_id_t;
+
+/**
+ @ingroup SIMULATOR
+
+ PDU enumarate values
+*/
+typedef enum {
+ undef_pdu_e = 0, /**< undefined PDU */
+ channel_e, /**< CHANNEL_t PDU */
+ clear_data_e, /**< CLEAR_DATA_t PDU */
+ encrypted_data_e, /**< ENCRYPTED_DATA_t PDU */
+ key_e, /**< KEY_t PDU */
+ prng_param_e, /**< PRNG_PARAM_t PDU */
+ raw_data_e, /**< RAW_DATA_t PDU */
+ status_e, /**< STATUS_t PDU */
+ nopdu_e /**< no PDU */
+} pdu_t;
+
+/**
+ @ingroup SIMULATOR
+
+ Message type
+*/
+typedef struct {
+ char *name; /**< message name */
+ service_id_t service_id; /**< associated service id */
+ uint8_t msgtype; /**< message id */
+ pdu_t pdu; /**< associated PDU type */
+} message_t;
+
+/**
+ @ingroup SIMULATOR
+
+ Communition channel type
+*/
+typedef struct {
+ int morep; /**< referent MOREP index */
+ int mode; /**< transmission mode: 0 for TX, 1 for RX */
+ char *etype; /**< associated Ethertype in a string format */
+} comm_t;
+
+/**
+ @ingroup SIMULATOR
+
+ Service type
+*/
+typedef struct {
+ char *name; /**< service name */
+ service_id_t service_id; /**< service id */
+ comm_t tx; /**< associated TX communication channel */
+ comm_t rx; /**< assiciated RX communication channel */
+} service_t;
+
+#endif /* __SIMULATOR_H__ */
+
+/* vim: set ts=4 sw=4 si et: */