0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-08 12:18:42 +00:00

cbor.c: primitive tools for writing cbor

This commit is contained in:
Katerina Kubecova 2023-11-23 08:52:51 +01:00
parent cebae02023
commit 52921062b8
4 changed files with 229 additions and 4 deletions

114
nest/cbor.c Normal file
View File

@ -0,0 +1,114 @@
#include <stdint.h>
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);
}
}

29
nest/cbor_shortcuts.c Normal file
View File

@ -0,0 +1,29 @@
#include <stdio.h>
#include <stdlib.h>
#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);
}

View File

@ -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

View File

@ -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;