From 52921062b87afd3b698336ec4bfcb96b29268a99 Mon Sep 17 00:00:00 2001 From: Katerina Kubecova Date: Thu, 23 Nov 2023 08:52:51 +0100 Subject: [PATCH] cbor.c: primitive tools for writing cbor --- nest/cbor.c | 114 ++++++++++++++++++++++++++++++++++++++++++ nest/cbor_shortcuts.c | 29 +++++++++++ nest/cmds.c | 65 +++++++++++++++++++++++- yang/show_status.yang | 25 +++++++-- 4 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 nest/cbor.c create mode 100644 nest/cbor_shortcuts.c diff --git a/nest/cbor.c b/nest/cbor.c new file mode 100644 index 000000000..418d32f57 --- /dev/null +++ b/nest/cbor.c @@ -0,0 +1,114 @@ +#include + + + +struct cbor_writer { + int pt; // where will next byte go + int capacity; + struct linpool *lp; + int8_t *cbor; +}; + +void write_item(struct cbor_writer *writer, int8_t major, int num); +void check_memory(struct cbor_writer *writer, int add_size); + + + +struct cbor_writer *cbor_init(struct linpool *lp, int size_guess) { + struct cbor_writer *writer = (struct cbor_writer *) lp_alloc(lp, sizeof(struct cbor_writer)); + writer->cbor = lp_alloc(lp, size_guess * sizeof(int8_t)); + writer->capacity = size_guess; + writer->lp = lp; + writer->pt =0; + return writer; +} + +void cbor_open_block(struct cbor_writer *writer) { // We will need to close the block later manualy + check_memory(writer, 2); + writer->cbor[writer->pt] = 0xbf; + writer->pt++; +} + +void cbor_open_list(struct cbor_writer *writer) { + check_memory(writer, 2); + writer->cbor[writer->pt] = 0x9f; + writer->pt++; +} + +void cbor_close_block_or_list(struct cbor_writer *writer) { + check_memory(writer, 2); + writer->cbor[writer->pt] = 0xff; + writer->pt++; +} + +void cbor_open_block_with_length(struct cbor_writer *writer, int length) { + write_item(writer, 5, length); +} + +void cbor_open_list_with_length(struct cbor_writer *writer, int length) { + write_item(writer, 4, length); +} + + +void cbor_add_int(struct cbor_writer *writer, int item) { + if (item >= 0) { + write_item(writer, 0, item); // 0 is the "major" (three bits) introducing positive int, 1 is for negative + } + else { + write_item(writer, 1, item); + } +} +void cbor_add_string(struct cbor_writer *writer, char *string) { + int length = strlen(string); + write_item(writer, 3, length); // 3 is major, then goes length of string and string + check_memory(writer, length); + memcpy(writer->cbor+writer->pt, string, length); + writer->pt+=length; +} + +void write_item(struct cbor_writer *writer, int8_t major, int num) { + major = major<<5; + check_memory(writer, 10); + if (num > (1<<(2*8))-1) { // We need 4 bytes to encode the num + major += 0x1a; // reserving those bytes + writer->cbor[writer->pt] = major; + writer->pt++; + for (int i = 3; i>=0; i--) { // write n-th byte of num + uint8_t to_write = (num>>(i*8)) & 0xff; + writer->cbor[writer->pt] = to_write; + writer->pt++; + } + return; + } + if (num > (1<<(8))-1) { // We need 2 bytes to encode the num + major += 0x19; // reserving those bytes + writer->cbor[writer->pt] = major; + writer->pt++; + for (int i = 1; i>=0; i--) { // write n-th byte of num + uint8_t to_write = (num>>(i*8)) & 0xff; + writer->cbor[writer->pt] = to_write; + writer->pt++; + } + return; + } + if (num > 23) { // byte is enough, but aditional value would be too big + major += 0x18; // reserving those bytes + writer->cbor[writer->pt] = major; + writer->pt++; + uint8_t to_write = num & 0xff; + writer->cbor[writer->pt] = to_write; + writer->pt++; + return; + } + major += num; // we can store the num as additional value + writer->cbor[writer->pt] = major; + writer->pt++; +} + +void check_memory(struct cbor_writer *writer, int add_size) { + if (writer->capacity - writer->pt-add_size < 0) { + int8_t *a = writer->cbor; + writer->cbor = lp_alloc(writer->lp, writer->capacity*2); + memcpy(writer->cbor, a, writer->pt); + } +} diff --git a/nest/cbor_shortcuts.c b/nest/cbor_shortcuts.c new file mode 100644 index 000000000..d60a12475 --- /dev/null +++ b/nest/cbor_shortcuts.c @@ -0,0 +1,29 @@ +#include +#include + +#include "nest/cbor.c" + + +void cbor_string_string(struct cbor_writer *writer, char *key, char *value) { + cbor_add_string(writer, key); + cbor_add_string(writer, value); +} + +void cbor_named_block_two_ints(struct cbor_writer *writer, char *key, char *name1, int val1, char *name2, int val2) { + cbor_add_string(writer, key); + cbor_open_block_with_length(writer, 2); + cbor_add_string(writer, name1); + cbor_add_int(writer, val1); + cbor_add_string(writer, name2); + cbor_add_int(writer, val2); +} + +void cbor_write_to_file(struct cbor_writer *writer, char *filename) { + FILE *write_ptr; + + write_ptr = fopen(filename, "wb"); + + fwrite(writer->cbor, writer->pt, 1, write_ptr); + fclose(write_ptr); +} + diff --git a/nest/cmds.c b/nest/cmds.c index d49bbc53c..4562262ae 100644 --- a/nest/cmds.c +++ b/nest/cmds.c @@ -15,6 +15,7 @@ #include "lib/string.h" #include "lib/resource.h" #include "filter/filter.h" +#include "nest/cbor_shortcuts.c" extern int shutting_down; extern int configuring; @@ -26,7 +27,7 @@ cmd_show_status(void) cli_msg(-1000, "BIRD " BIRD_VERSION); tm_format_time(tim, &config->tf_base, current_time()); - cli_msg(-1011, "Router ID is %R", config->router_id); + cli_msg(-1011, "Router ID is %R %i %x", config->router_id, config->router_id, config->router_id); cli_msg(-1011, "Hostname is %s", config->hostname); cli_msg(-1011, "Current server time is %s", tim); tm_format_time(tim, &config->tf_base, boot_time); @@ -42,6 +43,34 @@ cmd_show_status(void) cli_msg(13, "Reconfiguration in progress"); else cli_msg(13, "Daemon is up and running"); + + + byte time[TM_DATETIME_BUFFER_SIZE]; + tm_format_time(time, &config->tf_base, current_time()); + struct cbor_writer *w = cbor_init(lp_new(proto_pool), 1000); + cbor_open_block_with_length(w, 3); + cbor_string_string(w, "BIRD", BIRD_VERSION); + cbor_add_string(w, "body"); + cbor_open_block(w); + cbor_add_string(w, "router_id"); + cbor_add_int(w, config->router_id); + cbor_string_string(w, "hostname", config->hostname); + cbor_string_string(w, "server_time", time); + tm_format_time(time, &config->tf_base, boot_time); + cbor_string_string(w, "last_reboot", time); + tm_format_time(time, &config->tf_base, config->load_time); + cbor_string_string(w, "last_reconfiguration", time); + + // TODO graceful restart + cbor_close_block_or_list(w); + cbor_add_string(w, "state"); + if (shutting_down) + cbor_add_string(w, "Shutdown in progress"); + else if (configuring) + cbor_add_string(w, "Reconfiguration in progress"); + else + cbor_add_string(w, "Daemon is up and running"); + cbor_write_to_file(w, "test.cbor"); } void @@ -127,6 +156,40 @@ cmd_show_memory(void) #endif print_size("Total:", total); cli_msg(0, ""); + + + struct cbor_writer *w = cbor_init(lp_new(proto_pool), 1000); + cbor_open_block_with_length(w, 2); + + cbor_string_string(w, "BIRD memory usage", "header"); + + cbor_add_string(w, "body"); + cbor_open_block(w); + + struct resmem memory = rmemsize(rt_table_pool); + cbor_named_block_two_ints(w, "routing_tables", "effective", memory.effective, "overhead", memory.overhead); + + memory = rmemsize(rta_pool); + cbor_named_block_two_ints(w, "route_attributes", "effective", memory.effective, "overhead", memory.overhead); + + memory = rmemsize(proto_pool); + cbor_named_block_two_ints(w, "protocols", "effective", memory.effective, "overhead", memory.overhead); + + memory = rmemsize(config_pool); + cbor_named_block_two_ints(w, "current_config", "effective", memory.effective, "overhead", memory.overhead); + + memory = rmemsize(&root_pool); +#ifdef HAVE_MMAP + cbor_named_block_two_ints(w, "standby", "effective", 0, "overhead", page_size * *pages_kept); +#endif + memory.overhead += page_size * *pages_kept; + cbor_named_block_two_ints(w, "total", "effective", memory.effective, "overhead", memory.overhead); + + cbor_close_block_or_list(w); // we do not know for sure, that standby memory will be printed, so we do not know number of block items. If we know that, we open the block for 6 (or 5) items and we do not close anything + + + cbor_write_to_file(w, "/home/kkubecova/Dokumenty/bird/yang/show_memory_generated.yang"); + } void diff --git a/yang/show_status.yang b/yang/show_status.yang index a3573effc..2e4ea86e2 100644 --- a/yang/show_status.yang +++ b/yang/show_status.yang @@ -7,11 +7,22 @@ module show_status { description "cli show status format"; typedef date-and-time { - type string { - pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?' + type string { + pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?' + '(Z|[\+\-]\d{2}:\d{2})'; + } + } + + grouping timer { + leaf remains { + type decimal64 { + fraction-digits 3; + } + } + leaf count_time { + type uint32; + } } -} container message { @@ -39,6 +50,14 @@ module show_status { leaf last_reconfiguration { type date-and-time; } + container gr_restart { + leaf waiting_for_n_channels_to_recover { + type int32; + } + container wait_timer { + uses timer + } + } } leaf state { type string; -- 2.47.2