New upstream version 3.1.1

This commit is contained in:
billchenchina 2022-11-15 08:50:35 +08:00
parent 4e9934e5ec
commit e7b41df57b
229 changed files with 57000 additions and 12055 deletions

43
tools/Makefile.in Normal file
View file

@ -0,0 +1,43 @@
#
# This is not a standalone makefile, it must be called from the toplevel
# makefile to inherit the correct environment
DEBUG?=-g3
HEADERS=$(wildcard include/*.h)
CFLAGS+=-I../include
ifeq ($(CONFIG_TARGET),mingw)
CFLAGS+=-I../win32
endif
CFLAGS+=$(DEBUG)
LDFLAGS+=-L..
N2N_LIB=../libn2n.a
TOOLS=n2n-benchmark n2n-keygen
TOOLS+=@ADDITIONAL_TOOLS@
TESTS=tests-compress tests-elliptic tests-hashing tests-transform
TESTS+=tests-wire
TESTS+=tests-auth
.PHONY: all clean install
all: $(TOOLS) $(TESTS)
n2n-benchmark.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
n2n-keygen.o: $(N2N_LIB) $(HEADERS) ../Makefile Makefile
n2n-decode: n2n-decode.c $(N2N_LIB) $(HEADERS) ../Makefile Makefile
$(CC) $(CFLAGS) $< $(LDFLAGS) $(LDLIBS) -lpcap -o $@
# See comments in the topdir Makefile about how to generate coverage
# data.
gcov:
gcov $(TOOLS) $(TESTS)
clean:
rm -rf $(TOOLS) *.o *.dSYM *~
rm -f $(TESTS) *.gcno *.gcda
install: $(TOOLS)
$(INSTALL_PROG) $(TOOLS) $(SBINDIR)/

281
tools/n2n-benchmark.c Normal file
View file

@ -0,0 +1,281 @@
/*
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*
*/
#ifndef _MSC_VER
/* MinGW has undefined function gettimeofday() warnings without this header
* but Visual C++ doesnt even have the header */
#include <sys/time.h>
#endif
#include "n2n.h"
#define DURATION 2.5 // test duration per algorithm
#define PACKETS_BEFORE_GETTIME 2047 // do not check time after every packet but after (2 ^ n - 1)
uint8_t PKT_CONTENT[DEFAULT_MTU];
/* Prototypes */
static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c );
static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf);
static void run_hashing_benchmark(void);
static void run_ecc_benchmark(void);
int main(int argc, char * argv[]) {
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
size_t i;
n2n_trans_op_t transop_null, transop_tf;
n2n_trans_op_t transop_aes;
n2n_trans_op_t transop_cc20;
n2n_trans_op_t transop_lzo;
#ifdef HAVE_ZSTD
n2n_trans_op_t transop_zstd;
#endif
n2n_trans_op_t transop_speck;
n2n_edge_conf_t conf;
print_n2n_version();
/* Init configuration */
edge_init_conf_defaults(&conf);
strncpy((char*)conf.community_name, "abc123def456", sizeof(conf.community_name));
conf.encrypt_key = "SoMEVer!S$cUREPassWORD";
pearson_hash_init();
/* Init transops */
n2n_transop_null_init(&conf, &transop_null);
n2n_transop_tf_init(&conf, &transop_tf);
n2n_transop_aes_init(&conf, &transop_aes);
n2n_transop_cc20_init(&conf, &transop_cc20);
n2n_transop_speck_init(&conf, &transop_speck);
n2n_transop_lzo_init(&conf, &transop_lzo);
#ifdef HAVE_ZSTD
n2n_transop_zstd_init(&conf, &transop_zstd);
#endif
/* Setup packet content */
for (i = 0; i < sizeof(PKT_CONTENT) / sizeof(PKT_CONTENT[0]); i++) {
PKT_CONTENT[i] = i & 0x0f;
}
/* Run the tests */
run_transop_benchmark("null", &transop_null, &conf, pktbuf);
run_transop_benchmark("tf", &transop_tf, &conf, pktbuf);
run_transop_benchmark("aes", &transop_aes, &conf, pktbuf);
run_transop_benchmark("cc20", &transop_cc20, &conf, pktbuf);
run_transop_benchmark("speck", &transop_speck, &conf, pktbuf);
run_transop_benchmark("lzo1x", &transop_lzo, &conf, pktbuf);
#ifdef HAVE_ZSTD
run_transop_benchmark("zstd", &transop_zstd, &conf, pktbuf);
#endif
run_ecc_benchmark();
run_hashing_benchmark();
/* Cleanup */
transop_null.deinit(&transop_null);
transop_tf.deinit(&transop_tf);
transop_aes.deinit(&transop_aes);
transop_cc20.deinit(&transop_cc20);
transop_speck.deinit(&transop_speck);
transop_lzo.deinit(&transop_lzo);
#ifdef HAVE_ZSTD
transop_zstd.deinit(&transop_zstd);
#endif
return 0;
}
// --- hashing benchmark ------------------------------------------------------------------
static void run_hashing_benchmark(void) {
const float target_sec = DURATION;
struct timeval t1;
struct timeval t2;
ssize_t nw;
ssize_t target_usec = target_sec * 1e6;
ssize_t tdiff = 0; // microseconds
size_t num_packets = 0;
uint64_t hash;
printf("(%s)\t%s\t%.1f sec\t(%u bytes)",
"prs64", "hash", target_sec, (unsigned int)sizeof(PKT_CONTENT));
fflush(stdout);
gettimeofday( &t1, NULL );
nw = 8;
while(tdiff < target_usec) {
hash = pearson_hash_64(PKT_CONTENT, sizeof(PKT_CONTENT));
hash++; // clever compiler finds out that we do no use the variable
num_packets++;
if (!(num_packets & PACKETS_BEFORE_GETTIME)) {
gettimeofday( &t2, NULL );
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
}
}
float mpps = num_packets / (tdiff / 1e6) / 1e6;
printf(" ---> (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n",
(unsigned int)nw, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT));
printf("\n");
}
// --- ecc benchmark ----------------------------------------------------------------------
static void run_ecc_benchmark(void) {
const float target_sec = DURATION;
struct timeval t1;
struct timeval t2;
ssize_t nw;
ssize_t target_usec = target_sec * 1e6;
ssize_t tdiff = 0; // microseconds
size_t num_packets = 0;
unsigned char b[32];
unsigned char k[32];
memset(b, 0x00, 31);
b[31] = 9;
memset(k, 0x55, 32);
printf("[%s]\t%s\t%.1f sec\t(%u bytes) ",
"curve", "25519", target_sec, 32);
fflush(stdout);
gettimeofday( &t1, NULL );
nw = 32;
while(tdiff < target_usec) {
curve25519(b, k, b);
num_packets++;
gettimeofday( &t2, NULL );
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
}
float mpps = num_packets / (tdiff / 1e6) / 1e6;
printf(" ---> (%u bytes)\t%12u ops\t%8.1f Kops/s\n",
(unsigned int)nw, (unsigned int)num_packets, mpps * 1e3);
printf("\n");
}
// --- transop benchmark ------------------------------------------------------------------
static void run_transop_benchmark(const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf) {
n2n_common_t cmn;
n2n_PACKET_t pkt;
n2n_mac_t mac_buf;
uint8_t decodebuf[N2N_PKT_BUF_SIZE];
const float target_sec = DURATION;
struct timeval t1;
struct timeval t2;
size_t idx;
size_t rem;
size_t nw;
ssize_t target_usec = target_sec * 1e6;
ssize_t tdiff; // microseconds
size_t num_packets;
float mpps;
// encryption
printf("[%s]\t%s\t%.1f sec\t(%u bytes)",
op_name, "encrypt" , target_sec, (unsigned int)sizeof(PKT_CONTENT));
fflush(stdout);
memset(mac_buf, 0, sizeof(mac_buf));
num_packets = 0;
tdiff = 0;
gettimeofday( &t1, NULL );
while(tdiff < target_usec) {
nw = do_encode_packet( pktbuf, N2N_PKT_BUF_SIZE, conf->community_name);
nw += op_fn->fwd(op_fn,
pktbuf+nw, N2N_PKT_BUF_SIZE-nw,
PKT_CONTENT, sizeof(PKT_CONTENT), mac_buf);
num_packets++;
if (!(num_packets & PACKETS_BEFORE_GETTIME)) {
gettimeofday( &t2, NULL );
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
}
}
mpps = num_packets / (tdiff / 1e6) / 1e6;
printf(" ---> (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n",
(unsigned int)nw, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT));
// decrpytion
printf("\t%s\t%.1f sec\t(%u bytes)",
"decrypt" , target_sec, (unsigned int)sizeof(PKT_CONTENT));
fflush(stdout);
num_packets = 0;
tdiff = 0;
gettimeofday( &t1, NULL );
while(tdiff < target_usec) {
idx=0;
rem=nw;
decode_common( &cmn, pktbuf, &rem, &idx);
decode_PACKET( &pkt, &cmn, pktbuf, &rem, &idx );
op_fn->rev(op_fn, decodebuf, N2N_PKT_BUF_SIZE, pktbuf+idx, rem, 0);
num_packets++;
if (!(num_packets & PACKETS_BEFORE_GETTIME)) {
gettimeofday( &t2, NULL );
tdiff = ((t2.tv_sec - t1.tv_sec) * 1000000) + (t2.tv_usec - t1.tv_usec);
}
}
mpps = num_packets / (tdiff / 1e6) / 1e6;
printf(" <--- (%u bytes)\t%12u packets\t%8.1f Kpps\t%8.1f MB/s\n",
(unsigned int)nw, (unsigned int)num_packets, mpps * 1e3, mpps * sizeof(PKT_CONTENT));
if(memcmp(decodebuf, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0)
printf("\tpayload decryption failed!\n");
printf("\n");
}
static ssize_t do_encode_packet( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c )
{
n2n_mac_t destMac={0,1,2,3,4,5};
n2n_common_t cmn;
n2n_PACKET_t pkt;
size_t idx;
memset( &cmn, 0, sizeof(cmn) );
cmn.ttl = N2N_DEFAULT_TTL;
cmn.pc = n2n_packet;
cmn.flags=0; /* no options, not from supernode, no socket */
memcpy( cmn.community, c, N2N_COMMUNITY_SIZE );
memset( &pkt, 0, sizeof(pkt) );
memcpy( pkt.srcMac, destMac, N2N_MAC_SIZE);
memcpy( pkt.dstMac, destMac, N2N_MAC_SIZE);
pkt.sock.family=0; /* do not encode sock */
idx=0;
encode_PACKET( pktbuf, &idx, &cmn, &pkt );
traceEvent( TRACE_DEBUG, "encoded PACKET header of size=%u", (unsigned int)idx );
return idx;
}

371
tools/n2n-decode.c Normal file
View file

@ -0,0 +1,371 @@
/**
* (C) 2019-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not see see <http://www.gnu.org/licenses/>
*
*/
#include <pcap.h>
#include "n2n.h"
#define SNAPLEN 1500
#define TIMEOUT 200
/* *************************************************** */
static int aes_mode = 0;
static int running = 1;
static char *ifname = NULL;
static n2n_edge_conf_t conf;
static n2n_trans_op_t transop;
static pcap_t *handle;
static pcap_dumper_t *dumper;
/* *************************************************** */
static void help() {
fprintf(stderr, "n2n-decode -i ifname -k key -c community [-B bpf] [-w fname] [-v]"
#ifdef N2N_HAVE_AES
" [-A]"
#endif
"\n");
fprintf(stderr, "-i <ifname> | Specify the capture interface name.\n");
fprintf(stderr, "-c <community> | Specify the community.\n");
fprintf(stderr, "-k <key> | Specify the encryption key.\n");
#ifdef N2N_HAVE_AES
fprintf(stderr, "-A | Use AES decryption (default=use twofish).\n");
#endif
fprintf(stderr, "-B <bpf> | Use set a BPF filter for the capture.\n");
fprintf(stderr, "-w <fname> | Write decoded PCAP to file.\n");
fprintf(stderr, "-v | Increase verbosity level.\n");
exit(0);
}
/* *************************************************** */
#ifdef WIN32
BOOL WINAPI term_handler(DWORD sig)
#else
static void term_handler(int sig)
#endif
{
static int called = 0;
if(called) {
traceEvent(TRACE_NORMAL, "Ok I am leaving now");
_exit(0);
} else {
traceEvent(TRACE_NORMAL, "Shutting down...");
called = 1;
}
running = 0;
#ifdef WIN32
return(TRUE);
#endif
}
/* *************************************************** */
static void write_packet(const u_char *packet, struct pcap_pkthdr *hdr) {
pcap_dump((unsigned char*)dumper, hdr, packet);
pcap_dump_flush(dumper);
}
/* *************************************************** */
static int decode_encrypted_packet(const u_char *packet, struct pcap_pkthdr *header,
n2n_PACKET_t *pkt, int encrypted_offset) {
uint8_t decoded_packet[encrypted_offset + N2N_PKT_BUF_SIZE];
int decoded_eth_size;
int transop_shift;
switch(pkt->transform) {
case N2N_TRANSFORM_ID_NULL:
/* Not encrypted, dump it */
write_packet(packet, header);
break;
case N2N_TRANSFORM_ID_TWOFISH:
if(aes_mode) {
traceEvent(TRACE_INFO, "Skipping twofish encrypted packet");
return(-1);
}
break;
case N2N_TRANSFORM_ID_AES:
if(!aes_mode) {
traceEvent(TRACE_INFO, "Skipping AES encrypted packet");
return(-1);
}
break;
default:
traceEvent(TRACE_INFO, "Skipping unknown transform packet: %d", pkt->transform);
return(-2);
}
decoded_eth_size = transop.rev(&transop, decoded_packet+encrypted_offset, N2N_PKT_BUF_SIZE, packet + encrypted_offset,
header->caplen - encrypted_offset, pkt->srcMac);
transop_shift = (header->caplen - encrypted_offset) - decoded_eth_size;
if(transop_shift >= 0) {
int transform_id_offset = encrypted_offset - 2;
/* Copy the initial part of the packet */
memcpy(decoded_packet, packet, encrypted_offset);
/* Change the packet transform to NULL as there is now plaintext data */
*((u_int16_t*)(decoded_packet + transform_id_offset)) = htons(N2N_TRANSFORM_ID_NULL);
// TODO fix IP and UDP chechsums
write_packet(decoded_packet, header);
return(0);
}
traceEvent(TRACE_INFO, "Something was wrong in the decoding");
return(-3);
}
/* *************************************************** */
#define ETH_SIZE 14
#define UDP_SIZE 8
#define MIN_IP_SIZE 20
#define MIN_LEN (ETH_SIZE + UDP_SIZE + MIN_IP_SIZE + sizeof(n2n_common_t))
static int run_packet_loop() {
struct pcap_pkthdr header;
const u_char *packet;
traceEvent(TRACE_NORMAL, "Capturing packets on %s...", ifname);
while(running) {
n2n_common_t common;
n2n_PACKET_t pkt;
uint ipsize, common_offset;
size_t idx, rem;
memset(&common, 0, sizeof(common));
memset(&pkt, 0, sizeof(pkt));
packet = pcap_next(handle, &header);
if(!packet)
continue;
if(header.caplen < MIN_LEN) {
traceEvent(TRACE_INFO, "Skipping packet too small: size=%d", header.caplen);
continue;
}
if(ntohs(*(uint16_t*)(packet + 12)) != 0x0800) {
traceEvent(TRACE_INFO, "Skipping non IPv4 packet");
continue;
}
if(packet[ETH_SIZE + 9] != IPPROTO_UDP) {
traceEvent(TRACE_INFO, "Skipping non UDP packet");
continue;
}
ipsize = (packet[ETH_SIZE] & 0x0F) * 4;
common_offset = ETH_SIZE + ipsize + UDP_SIZE;
idx = common_offset;
rem = header.caplen - idx;
if(decode_common(&common, packet, &rem, &idx) == -1) {
traceEvent(TRACE_INFO, "Skipping packet, decode common failed");
continue;
}
if(strncmp((char*)conf.community_name, (char*)common.community, N2N_COMMUNITY_SIZE) != 0) {
traceEvent(TRACE_INFO, "Skipping packet with non-matching community");
continue;
}
switch(common.pc) {
case n2n_ping:
case n2n_register:
case n2n_deregister:
case n2n_register_ack:
case n2n_register_super:
case n2n_register_super_ack:
case n2n_register_super_nak:
case n2n_federation:
case n2n_peer_info:
case n2n_query_peer:
write_packet(packet, &header);
break;
case n2n_packet:
decode_PACKET(&pkt, &common, packet, &rem, &idx);
decode_encrypted_packet(packet, &header, &pkt, idx);
break;
default:
traceEvent(TRACE_INFO, "Skipping packet with unknown type: %d", common.pc);
continue;
}
}
return(0);
}
/* *************************************************** */
int main(int argc, char* argv[]) {
u_char c;
struct bpf_program fcode;
char *bpf_filter = NULL, *out_fname = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
int rv = 0;
FILE *outf = stdout;
/* Trace to stderr to leave stdout for the PCAP dump if "-w -" is used */
setTraceFile(stderr);
/* Init configuration */
edge_init_conf_defaults(&conf);
while((c = getopt(argc, argv,
"k:i:B:w:c:v"
#ifdef N2N_HAVE_AES
"A"
#endif
)) != '?') {
if(c == 255) break;
switch(c) {
case 'c':
strncpy((char*)conf.community_name, optarg, sizeof(conf.community_name)-1);
break;
case 'i':
ifname = strdup(optarg);
break;
case 'k':
conf.encrypt_key = strdup(optarg);
break;
case 'B':
bpf_filter = strdup(optarg);
break;
#ifdef N2N_HAVE_AES
case 'A':
aes_mode = 1;
break;
#endif
case 'w':
if(strcmp(optarg, "-") != 0)
out_fname = strdup(optarg);
break;
case 'v': /* verbose */
setTraceLevel(getTraceLevel() + 1);
break;
default:
help();
}
}
if((ifname == NULL) || (conf.encrypt_key == NULL) || (conf.community_name[0] == '\0'))
help();
#ifdef N2N_HAVE_AES
if(aes_mode)
n2n_transop_aes_init(&conf, &transop);
else
#endif
n2n_transop_tf_init(&conf, &transop);
if((handle = pcap_create(ifname, errbuf)) == NULL) {
traceEvent(TRACE_ERROR, "Cannot open device %s: %s", ifname, errbuf);
return(1);
}
if((pcap_set_timeout(handle, TIMEOUT) != 0) ||
(pcap_set_snaplen(handle, SNAPLEN) != 0)) {
traceEvent(TRACE_ERROR, "Error while setting timeout/snaplen");
return(1);
}
#ifdef HAVE_PCAP_IMMEDIATE_MODE
/* The timeout is not honored unless immediate mode is set.
* See https://github.com/mfontanini/libtins/issues/180 */
if(pcap_set_immediate_mode(handle, 1) != 0) {
traceEvent(TRACE_ERROR, "Could not set PCAP immediate mode");
return(1);
}
#endif
if(pcap_activate(handle) != 0) {
traceEvent(TRACE_ERROR, "pcap_activate failed: %s", pcap_geterr(handle));
}
if(pcap_datalink(handle) != DLT_EN10MB) {
traceEvent(TRACE_ERROR, "Device %s doesn't provide Ethernet headers - not supported", ifname);
return(2);
}
if(bpf_filter) {
bpf_u_int32 net, mask;
if(pcap_lookupnet(ifname, &net, &mask, errbuf) == -1) {
traceEvent(TRACE_WARNING, "Couldn't get netmask for device %s: %s", ifname, errbuf);
net = 0;
mask = 0;
}
if((pcap_compile(handle, &fcode, bpf_filter, 1, net) < 0)
|| (pcap_setfilter(handle, &fcode) < 0)) {
traceEvent(TRACE_ERROR, "Could not set BPF filter: %s", pcap_geterr(handle));
return(3);
}
}
if(out_fname) {
outf = fopen(out_fname, "wb");
if(outf == NULL) {
traceEvent(TRACE_ERROR, "Could not open %s for write[%d]: %s", errno, strerror(errno));
return(4);
}
}
dumper = pcap_dump_fopen(handle, outf);
if(dumper == NULL) {
traceEvent(TRACE_ERROR, "Could dump file: %s", pcap_geterr(handle));
return(5);
}
#ifdef WIN32
SetConsoleCtrlHandler(term_handler, TRUE);
#else
signal(SIGTERM, term_handler);
signal(SIGINT, term_handler);
#endif
rv = run_packet_loop();
/* Cleanup */
pcap_close(handle);
if(conf.encrypt_key) free(conf.encrypt_key);
if(bpf_filter) free(bpf_filter);
if(ifname) free(ifname);
if(out_fname) {
fclose(outf);
free(out_fname);
}
return(rv);
}

76
tools/n2n-keygen.c Normal file
View file

@ -0,0 +1,76 @@
/*
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include "n2n.h"
int main(int argc, char * argv[]) {
n2n_private_public_key_t prv; /* 32 bytes private key */
n2n_private_public_key_t bin; /* 32 bytes public key binary output buffer */
char asc[44]; /* 43 bytes + 0-terminator ascii string output */
uint8_t fed = 0;
// exactly two parameters required
if(argc != 3) {
// error message to stderr to not interfere with batch usage
fprintf(stderr, "\n"
"n2n-keygen tool\n\n"
" usage: n2n-keygen <username> <password>\n\n"
" or n2n-keygen -F <federation name>\n\n"
" outputs a line to insert at supernode's community file for user-and-\n"
" password authentication or a command line parameter with the public\n"
" federation key for use at edge's command line, please refer to the\n"
" doc/Authentication.md document or the man pages for more details\n\n");
return 1;
}
// federation mode?
if(strcmp(argv[1], "-F") == 0)
fed = 1;
// derive private key from username and password:
// hash username once, hash password twice (so password is bound
// to username but username and password are not interchangeable),
// finally xor the result
// in federation mode: only hash federation name, twice
generate_private_key(prv, argv[2]);
// hash user name only if required
if(!fed) {
bind_private_key_to_username(prv, argv[1]);
}
// calculate the public key into binary output buffer
generate_public_key(bin, prv);
// clear out the private key
memset(prv, 0, sizeof(prv));
// convert binary output to 6-bit-ascii string output
bin_to_ascii(asc, bin, sizeof(bin));
// output
if(fed)
fprintf(stdout, "-P %s\n", asc);
else
fprintf(stdout, "%c %s %s\n", N2N_USER_KEY_LINE_STARTER, argv[1], asc);
return 0;
}

128
tools/tests-auth.c Normal file
View file

@ -0,0 +1,128 @@
/*
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include <inttypes.h>
#include "n2n.h"
#include "hexdump.h"
uint8_t PKT_CONTENT1[]={
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
};
char *PKT_CONTENT2 = "00420mG51WS82GeB30qE3m";
void test_bin_to_ascii (void *buf, unsigned int bufsize) {
char *test_name = "bin_to_ascii";
char out[32];
printf("%s: input size = 0x%x\n", test_name, bufsize);
fhexdump(0, buf, bufsize, stdout);
bin_to_ascii(out, buf, bufsize);
printf("%s: output: %s\n", test_name, out);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_ascii_to_bin (char *buf) {
char *test_name = "ascii_to_bin";
uint8_t out[32];
memset(out, 0, sizeof(out));
printf("%s: input = %s\n", test_name, buf);
ascii_to_bin(out, buf);
// TODO:
// - it would be nice if the function returned the bufsize,
// - or took an allocation size as input
printf("%s: output:\n", test_name);
fhexdump(0, out, sizeof(out), stdout);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_generate_private_key (char *in, n2n_private_public_key_t prv) {
char *test_name = "generate_private_key";
printf("%s: input = %s\n", test_name, in);
generate_private_key(prv, in);
printf("%s: output:\n", test_name);
fhexdump(0, prv, sizeof(n2n_private_public_key_t), stdout);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_generate_public_key (n2n_private_public_key_t prv, n2n_private_public_key_t pub) {
char *test_name = "generate_public_key";
printf("%s: input:\n", test_name);
fhexdump(0, prv, sizeof(n2n_private_public_key_t), stdout);
generate_public_key(pub, prv);
printf("%s: output:\n", test_name);
fhexdump(0, pub, sizeof(n2n_private_public_key_t), stdout);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_generate_shared_secret (n2n_private_public_key_t prv, n2n_private_public_key_t pub) {
char *test_name = "generate_shared_secret";
n2n_private_public_key_t out;
printf("%s: input: prv\n", test_name);
fhexdump(0, prv, sizeof(n2n_private_public_key_t), stdout);
printf("%s: input: pub\n", test_name);
fhexdump(0, pub, sizeof(n2n_private_public_key_t), stdout);
generate_shared_secret(out, prv, pub);
printf("%s: output:\n", test_name);
fhexdump(0, out, sizeof(out), stdout);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
int main (int argc, char * argv[]) {
test_bin_to_ascii(PKT_CONTENT1, sizeof(PKT_CONTENT1));
test_ascii_to_bin(PKT_CONTENT2);
n2n_private_public_key_t prv;
memset(prv, 0, sizeof(prv));
n2n_private_public_key_t pub;
memset(pub, 0, sizeof(pub));
test_generate_private_key(PKT_CONTENT2, prv);
test_generate_public_key(prv, pub);
test_generate_shared_secret(prv, pub);
return 0;
}

165
tools/tests-compress.c Normal file
View file

@ -0,0 +1,165 @@
/*
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include <inttypes.h>
#include <assert.h>
#include "n2n.h"
#include "hexdump.h"
/* heap allocation for compression as per lzo example doc */
#define HEAP_ALLOC(var,size) lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
uint8_t PKT_CONTENT[]={
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
};
static void init_compression_for_benchmark (void) {
if(lzo_init() != LZO_E_OK) {
traceEvent(TRACE_ERROR, "LZO compression init error");
exit(1);
}
#ifdef N2N_HAVE_ZSTD
// zstd does not require initialization. if it were required, this would be a good place
#endif
}
static void deinit_compression_for_benchmark (void) {
// lzo1x does not require de-initialization. if it were required, this would be a good place
#ifdef N2N_HAVE_ZSTD
// zstd does not require de-initialization. if it were required, this would be a good place
#endif
}
void test_lzo1x () {
char *test_name = "lzo1x";
uint8_t compression_buffer[N2N_PKT_BUF_SIZE]; // size allows enough of a reserve required for compression
lzo_uint compression_len = sizeof(compression_buffer);
if(lzo1x_1_compress(PKT_CONTENT, sizeof(PKT_CONTENT), compression_buffer, &compression_len, wrkmem) != LZO_E_OK) {
fprintf(stderr, "%s: compression error\n", test_name);
exit(1);
}
assert(compression_len == 47);
printf("%s: output size = 0x%" PRIx64 "\n", test_name, compression_len);
fhexdump(0, compression_buffer, compression_len, stdout);
uint8_t deflation_buffer[N2N_PKT_BUF_SIZE];
lzo_uint deflated_len;
lzo1x_decompress(compression_buffer, compression_len, deflation_buffer, &deflated_len, NULL);
assert(deflated_len == sizeof(PKT_CONTENT));
if(memcmp(PKT_CONTENT, deflation_buffer, deflated_len)!=0) {
fprintf(stderr, "%s: round-trip buffer mismatch\n", test_name);
exit(1);
}
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_zstd () {
char *test_name = "zstd";
#ifdef N2N_HAVE_ZSTD
uint8_t compression_buffer[N2N_PKT_BUF_SIZE]; // size allows enough of a reserve required for compression
lzo_uint compression_len = sizeof(compression_buffer);
compression_len = N2N_PKT_BUF_SIZE;
compression_len = ZSTD_compress(compression_buffer, compression_len, PKT_CONTENT, sizeof(PKT_CONTENT), ZSTD_COMPRESSION_LEVEL);
if(ZSTD_isError(compression_len)) {
fprintf(stderr, "%s: compression error\n", test_name);
exit(1);
}
assert(compression_len == 33);
printf("%s: output size = 0x%" PRIx64 "\n", test_name, compression_len);
fhexdump(0, compression_buffer, compression_len, stdout);
uint8_t deflation_buffer[N2N_PKT_BUF_SIZE];
int64_t deflated_len = sizeof(deflation_buffer);
deflated_len = (int32_t)ZSTD_decompress(deflation_buffer, deflated_len, compression_buffer, compression_len);
if(ZSTD_isError(deflated_len)) {
fprintf(stderr, "%s: decompression error '%s'\n",
test_name, ZSTD_getErrorName(deflated_len));
exit(1);
}
assert(deflated_len == sizeof(PKT_CONTENT));
if(memcmp(PKT_CONTENT, deflation_buffer, deflated_len)!=0) {
fprintf(stderr, "%s: round-trip buffer mismatch\n", test_name);
exit(1);
}
fprintf(stderr, "%s: tested\n", test_name);
#else
// FIXME - output dummy data to the stdout for easy comparison
printf("zstd: output size = 0x21\n");
printf("000: 28 b5 2f fd 60 00 01 bd 00 00 80 00 01 02 03 04 |( / ` |\n");
printf("010: 05 06 07 08 09 0a 0b 0c 0d 0e 0f 01 00 da 47 9d | G |\n");
printf("020: 4b |K|\n");
fprintf(stderr, "%s: not compiled - dummy data output\n", test_name);
#endif
printf("\n");
}
int main (int argc, char * argv[]) {
/* Also for compression (init moved here for ciphers get run before in case of lzo init error) */
init_compression_for_benchmark();
printf("%s: input size = 0x%" PRIx64 "\n", "original", sizeof(PKT_CONTENT));
fhexdump(0, PKT_CONTENT, sizeof(PKT_CONTENT), stdout);
printf("\n");
test_lzo1x();
test_zstd();
deinit_compression_for_benchmark();
return 0;
}

56
tools/tests-elliptic.c Normal file
View file

@ -0,0 +1,56 @@
/*
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include "n2n.h"
#include "hexdump.h"
void test_curve25519 (unsigned char *pkt_input, unsigned char *key) {
char *test_name = "curve25519";
unsigned char pkt_output[32];
curve25519(pkt_output, key, pkt_input);
printf("%s: output\n", test_name);
fhexdump(0, pkt_output, sizeof(pkt_output), stdout);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
int main (int argc, char * argv[]) {
char *test_name = "environment";
unsigned char key[32];
unsigned char pkt_input[32];
memset(pkt_input, 0, 31);
pkt_input[31] = 9;
memset(key, 0x55, 32);
printf("%s: input\n", test_name);
fhexdump(0, pkt_input, sizeof(pkt_input), stdout);
printf("%s: key\n", test_name);
fhexdump(0, key, sizeof(key), stdout);
printf("\n");
test_curve25519(pkt_input, key);
return 0;
}

119
tools/tests-hashing.c Normal file
View file

@ -0,0 +1,119 @@
/*
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include <inttypes.h>
#include "n2n.h"
#include "hexdump.h"
uint8_t PKT_CONTENT[]={
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
};
void test_pearson_16 (void *buf, unsigned int bufsize) {
char *test_name = "pearson_hash_16";
uint16_t hash = pearson_hash_16(buf, bufsize);
printf("%s: output = 0x%" PRIx16 "\n", test_name, hash);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_pearson_32 (void *buf, unsigned int bufsize) {
char *test_name = "pearson_hash_32";
uint32_t hash = pearson_hash_32(buf, bufsize);
printf("%s: output = 0x%" PRIx32 "\n", test_name, hash);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_pearson_64 (void *buf, unsigned int bufsize) {
char *test_name = "pearson_hash_64";
uint64_t hash = pearson_hash_64(buf, bufsize);
printf("%s: output = 0x%" PRIx64 "\n", test_name, hash);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_pearson_128 (void *buf, unsigned int bufsize) {
char *test_name = "pearson_hash_128";
uint8_t hash[16];
pearson_hash_128(hash, buf, bufsize);
printf("%s: output:\n", test_name);
fhexdump(0, hash, sizeof(hash), stdout);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_pearson_256 (void *buf, unsigned int bufsize) {
char *test_name = "pearson_hash_256";
uint8_t hash[32];
pearson_hash_256(hash, buf, bufsize);
printf("%s: output:\n", test_name);
fhexdump(0, hash, sizeof(hash), stdout);
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
int main (int argc, char * argv[]) {
pearson_hash_init();
char *test_name = "environment";
printf("%s: input size = 0x%" PRIx64 "\n", test_name, sizeof(PKT_CONTENT));
fhexdump(0, PKT_CONTENT, sizeof(PKT_CONTENT), stdout);
printf("\n");
test_pearson_256(PKT_CONTENT, sizeof(PKT_CONTENT));
test_pearson_128(PKT_CONTENT, sizeof(PKT_CONTENT));
test_pearson_64(PKT_CONTENT, sizeof(PKT_CONTENT));
test_pearson_32(PKT_CONTENT, sizeof(PKT_CONTENT));
test_pearson_16(PKT_CONTENT, sizeof(PKT_CONTENT));
return 0;
}

191
tools/tests-transform.c Normal file
View file

@ -0,0 +1,191 @@
/*
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include <inttypes.h>
#include "n2n.h"
#include "hexdump.h"
#define DURATION 2.5 // test duration per algorithm
#define PACKETS_BEFORE_GETTIME 2047 // do not check time after every packet but after (2 ^ n - 1)
uint8_t PKT_CONTENT[]={
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
};
/* Prototypes */
static ssize_t do_encode_packet ( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c );
static void run_transop_benchmark (const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf);
int main (int argc, char * argv[]) {
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
n2n_trans_op_t transop_null, transop_tf;
n2n_trans_op_t transop_aes;
n2n_trans_op_t transop_cc20;
n2n_trans_op_t transop_speck;
n2n_trans_op_t transop_lzo;
#ifdef HAVE_ZSTD
n2n_trans_op_t transop_zstd;
#endif
n2n_edge_conf_t conf;
/* Init configuration */
edge_init_conf_defaults(&conf);
strncpy((char *)conf.community_name, "abc123def456", sizeof(conf.community_name));
conf.encrypt_key = "SoMEVer!S$cUREPassWORD";
char *test_name = "environment";
printf("%s: community_name = \"%s\"\n", test_name, conf.community_name);
printf("%s: encrypt_key = \"%s\"\n", test_name, conf.encrypt_key);
printf("%s: input size = 0x%" PRIx64 "\n", test_name, sizeof(PKT_CONTENT));
fhexdump(0, PKT_CONTENT, sizeof(PKT_CONTENT), stdout);
printf("\n");
/* Init transopts */
n2n_transop_null_init(&conf, &transop_null);
n2n_transop_tf_init(&conf, &transop_tf);
n2n_transop_aes_init(&conf, &transop_aes);
n2n_transop_cc20_init(&conf, &transop_cc20);
n2n_transop_speck_init(&conf, &transop_speck);
n2n_transop_lzo_init(&conf, &transop_lzo);
#ifdef HAVE_ZSTD
n2n_transop_zstd_init(&conf, &transop_zstd);
#endif
/* Run the tests */
/* FIXME: interop tests are pretty useless without the expected encrypted buffer data */
run_transop_benchmark("null", &transop_null, &conf, pktbuf);
run_transop_benchmark("tf", &transop_tf, &conf, pktbuf);
run_transop_benchmark("aes", &transop_aes, &conf, pktbuf);
run_transop_benchmark("cc20", &transop_cc20, &conf, pktbuf);
run_transop_benchmark("speck", &transop_speck, &conf, pktbuf);
run_transop_benchmark("lzo", &transop_lzo, &conf, pktbuf);
#ifdef HAVE_ZSTD
run_transop_benchmark("zstd", &transop_zstd, &conf, pktbuf);
#else
// FIXME - output dummy data to the stdout for easy comparison
printf("zstd: output size = 0x47\n");
printf("000: 03 02 00 03 61 62 63 31 32 33 64 65 66 34 35 36 | abc123def456|\n");
printf("010: 00 00 00 00 00 00 00 00 00 01 02 03 04 05 00 01 | |\n");
printf("020: 02 03 04 05 00 00 28 b5 2f fd 60 00 01 bd 00 00 | ( / ` |\n");
printf("030: 80 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e | |\n");
printf("040: 0f 01 00 da 47 9d 4b | G K|\n");
fprintf(stderr, "%s: not compiled - dummy data output\n", "zstd");
printf("\n");
#endif
/* Cleanup */
transop_null.deinit(&transop_null);
transop_tf.deinit(&transop_tf);
transop_aes.deinit(&transop_aes);
transop_cc20.deinit(&transop_cc20);
transop_speck.deinit(&transop_speck);
transop_lzo.deinit(&transop_lzo);
#ifdef HAVE_ZSTD
transop_zstd.deinit(&transop_zstd);
#endif
return 0;
}
// --- transop benchmark ------------------------------------------------------------------
static void run_transop_benchmark (const char *op_name, n2n_trans_op_t *op_fn, n2n_edge_conf_t *conf, uint8_t *pktbuf) {
n2n_common_t cmn;
n2n_PACKET_t pkt;
n2n_mac_t mac_buf;
uint8_t decodebuf[N2N_PKT_BUF_SIZE];
size_t idx;
size_t rem;
size_t nw;
// encryption
memset(mac_buf, 0, sizeof(mac_buf));
nw = do_encode_packet( pktbuf, N2N_PKT_BUF_SIZE, conf->community_name);
nw += op_fn->fwd(op_fn,
pktbuf+nw, N2N_PKT_BUF_SIZE-nw,
PKT_CONTENT, sizeof(PKT_CONTENT), mac_buf);
printf("%s: output size = 0x%" PRIx64 "\n", op_name, nw);
fhexdump(0, pktbuf, nw, stdout);
// decrpytion
idx=0;
rem=nw;
decode_common( &cmn, pktbuf, &rem, &idx);
decode_PACKET( &pkt, &cmn, pktbuf, &rem, &idx );
op_fn->rev(op_fn, decodebuf, sizeof(decodebuf), pktbuf+idx, rem, 0);
if(memcmp(decodebuf, PKT_CONTENT, sizeof(PKT_CONTENT)) != 0) {
fprintf(stderr, "%s: round-trip buffer mismatch\n", op_name);
exit(1);
}
fprintf(stderr, "%s: tested\n", op_name);
printf("\n");
}
static ssize_t do_encode_packet ( uint8_t * pktbuf, size_t bufsize, const n2n_community_t c )
{
// FIXME: this is a parameter of the test environment
n2n_mac_t destMac={0,1,2,3,4,5};
n2n_common_t cmn;
n2n_PACKET_t pkt;
size_t idx;
memset( &cmn, 0, sizeof(cmn) );
cmn.ttl = N2N_DEFAULT_TTL;
cmn.pc = n2n_packet;
cmn.flags=0; /* no options, not from supernode, no socket */
memcpy( cmn.community, c, N2N_COMMUNITY_SIZE );
memset( &pkt, 0, sizeof(pkt) );
memcpy( pkt.srcMac, destMac, N2N_MAC_SIZE);
memcpy( pkt.dstMac, destMac, N2N_MAC_SIZE);
pkt.sock.family=0; /* do not encode sock */
idx=0;
encode_PACKET( pktbuf, &idx, &cmn, &pkt );
traceEvent( TRACE_DEBUG, "encoded PACKET header of size=%u", (unsigned int)idx );
return idx;
}

201
tools/tests-wire.c Normal file
View file

@ -0,0 +1,201 @@
/*
* (C) 2007-22 - ntop.org and contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include <inttypes.h>
#include "n2n.h"
#include "hexdump.h"
void init_ip_subnet (n2n_ip_subnet_t * d) {
d->net_addr = 0x20212223;
d->net_bitlen = 25;
}
void print_ip_subnet (char *test_name, char *field, n2n_ip_subnet_t * d) {
printf("%s: %s.net_addr = 0x%08x\n",
test_name, field, d->net_addr);
printf("%s: %s.net_bitlen = %i\n",
test_name, field, d->net_bitlen);
}
void init_mac (n2n_mac_t mac, const uint8_t o0, const uint8_t o1,
const uint8_t o2, const uint8_t o3,
const uint8_t o4, const uint8_t o5) {
mac[0] = o0;
mac[1] = o1;
mac[2] = o2;
mac[3] = o3;
mac[4] = o4;
mac[5] = o5;
}
void print_mac (char *test_name, char *field, n2n_mac_t mac) {
printf("%s: %s[] = %x:%x:%x:%x:%x:%x\n",
test_name, field,
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
void init_auth (n2n_auth_t *auth) {
auth->scheme = n2n_auth_simple_id;
auth->token_size = 16;
auth->token[0] = 0xfe;
auth->token[4] = 0xfd;
auth->token[8] = 0xfc;
auth->token[15] = 0xfb;
}
void print_auth (char *test_name, char *field, n2n_auth_t *auth) {
printf("%s: %s.scheme = %i\n", test_name, field, auth->scheme);
printf("%s: %s.token_size = %i\n", test_name, field, auth->token_size);
printf("%s: %s.token[0] = 0x%02x\n", test_name, field, auth->token[0]);
}
void init_common (n2n_common_t *common, char *community) {
memset( common, 0, sizeof(*common) );
common->ttl = N2N_DEFAULT_TTL;
common->flags = 0;
strncpy( (char *)common->community, community, N2N_COMMUNITY_SIZE);
common->community[N2N_COMMUNITY_SIZE - 1] = '\0';
}
void print_common (char *test_name, n2n_common_t *common) {
printf("%s: common.ttl = %i\n", test_name, common->ttl);
printf("%s: common.flags = %i\n", test_name, common->flags);
printf("%s: common.community = \"%s\"\n", test_name, common->community);
}
void test_REGISTER (n2n_common_t *common) {
char *test_name = "REGISTER";
common->pc = n2n_register;
printf("%s: common.pc = %i\n", test_name, common->pc);
n2n_REGISTER_t reg;
memset( &reg, 0, sizeof(reg) );
init_mac( reg.srcMac, 0,1,2,3,4,5);
init_mac( reg.dstMac, 0x10,0x11,0x12,0x13,0x14,0x15);
init_ip_subnet(&reg.dev_addr);
strcpy( (char *)reg.dev_desc, "Dummy_Dev_Desc" );
printf("%s: reg.cookie = %i\n", test_name, reg.cookie);
print_mac(test_name, "reg.srcMac", reg.srcMac);
print_mac(test_name, "reg.dstMac", reg.dstMac);
// TODO: print reg.sock
print_ip_subnet(test_name, "reg.dev_addr", &reg.dev_addr);
printf("%s: reg.dev_desc = \"%s\"\n", test_name, reg.dev_desc);
printf("\n");
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
size_t idx = 0;
size_t retval = encode_REGISTER( pktbuf, &idx, common, &reg);
printf("%s: output retval = 0x%" PRIx64 "\n", test_name, retval);
printf("%s: output idx = 0x%" PRIx64 "\n", test_name, idx);
fhexdump(0, pktbuf, idx, stdout);
// TODO: decode_REGISTER() and print
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_REGISTER_SUPER (n2n_common_t *common) {
char *test_name = "REGISTER_SUPER";
common->pc = n2n_register_super;
printf("%s: common.pc = %i\n", test_name, common->pc);
n2n_REGISTER_SUPER_t reg;
memset( &reg, 0, sizeof(reg) );
init_mac( reg.edgeMac, 0x20,0x21,0x22,0x23,0x24,0x25);
// n2n_sock_t sock
init_ip_subnet(&reg.dev_addr);
strcpy( (char *)reg.dev_desc, "Dummy_Dev_Desc" );
init_auth(&reg.auth);
reg.key_time = 600;
printf("%s: reg.cookie = %i\n", test_name, reg.cookie);
print_mac(test_name, "reg.edgeMac", reg.edgeMac);
// TODO: print reg.sock
print_ip_subnet(test_name, "reg.dev_addr", &reg.dev_addr);
printf("%s: reg.dev_desc = \"%s\"\n", test_name, reg.dev_desc);
print_auth(test_name, "reg.auth", &reg.auth);
printf("%s: reg.key_time = %" PRIi32 "\n", test_name, reg.key_time);
printf("\n");
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
size_t idx = 0;
size_t retval = encode_REGISTER_SUPER( pktbuf, &idx, common, &reg);
printf("%s: output retval = 0x%" PRIx64 "\n", test_name, retval);
printf("%s: output idx = 0x%" PRIx64 "\n", test_name, idx);
fhexdump(0, pktbuf, idx, stdout);
// TODO: decode_REGISTER_SUPER() and print
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
void test_UNREGISTER_SUPER (n2n_common_t *common) {
char *test_name = "UNREGISTER_SUPER";
common->pc = n2n_unregister_super;
printf("%s: common.pc = %i\n", test_name, common->pc);
n2n_UNREGISTER_SUPER_t unreg;
memset( &unreg, 0, sizeof(unreg) );
init_auth(&unreg.auth);
init_mac( unreg.srcMac, 0x30,0x31,0x32,0x33,0x34,0x35);
print_auth(test_name, "unreg.auth", &unreg.auth);
print_mac(test_name, "unreg.srcMac", unreg.srcMac);
printf("\n");
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
size_t idx = 0;
size_t retval = encode_UNREGISTER_SUPER( pktbuf, &idx, common, &unreg);
printf("%s: output retval = 0x%" PRIx64 "\n", test_name, retval);
printf("%s: output idx = 0x%" PRIx64 "\n", test_name, idx);
fhexdump(0, pktbuf, idx, stdout);
// TODO: decode_UNREGISTER_SUPER() and print
fprintf(stderr, "%s: tested\n", test_name);
printf("\n");
}
int main (int argc, char * argv[]) {
char *test_name = "environment";
n2n_common_t common;
init_common( &common, "abc123def456z" );
print_common( test_name, &common );
printf("\n");
test_REGISTER(&common);
test_REGISTER_SUPER(&common);
test_UNREGISTER_SUPER(&common);
// TODO: add more wire tests
return 0;
}