mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
cbor.c: primitive tools for writing cbor
This commit is contained in:
parent
cebae02023
commit
52921062b8
114
nest/cbor.c
Normal file
114
nest/cbor.c
Normal 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
29
nest/cbor_shortcuts.c
Normal 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);
|
||||
}
|
||||
|
65
nest/cmds.c
65
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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user