0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-09-19 11:55:21 +00:00
bird/client/print_cbor.c
2024-01-12 10:09:45 +01:00

1597 lines
42 KiB
C

#include <time.h>
#include "nest/cbor_parse_tools.h"
#include "nest/cbor_shortcuts.h"
void print_with_size(byte *string, int len)
{
for (int i = 0; i < len; i++)
{
if (string[i] != '_')
putc(string[i], stdout);
else
putc(' ', stdout);
}
}
void print_time(int64_t time)
{
struct tm tm = *localtime(&time);
printf("%d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
}
void print_epoch_time(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); // tag time
ASSERT(val.val == 1);
val = get_value(buf_read); // tag decimal
val = get_value(buf_read); // array
val = get_value(buf_read);
int shift = val.val;
val = get_value(buf_read);
while (shift > 0)
{
shift --;
val.val *= 10;
}
int milisec = 0;
while (shift < 0)
{
shift ++;
milisec *= 10;
milisec += val.val % 10;
val.val /= 10;
}
print_time(val.val);
printf(":%i", milisec);
}
void print_relativ_time(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); // tag decimal
val = get_value(buf_read); // array
val = get_value(buf_read);
int shift = val.val;
val = get_value(buf_read);
while (shift > 0)
{
shift --;
val.val *= 10;
}
int milisec = 0;
while (shift < 0)
{
shift ++;
milisec *= 10;
milisec += val.val % 10;
val.val /= 10;
}
printf("%li.%i s", val.val, milisec);
}
void print_with_size_(byte *string, int len)
{
for (int i = 0; i < len; i++)
{
putc(string[i], stdout);
}
}
void print_with_size_add_space(byte *string, int len, int desired_len)
{
for (int i = 0; i < len; i++)
{
putc(string[i], stdout);
}
for (int i = 0; i < desired_len - len; i++)
{
putc(' ', stdout);
}
}
void print_ip_addr(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); // tag
char buff[NET_MAX_TEXT_LENGTH+1];
int tag = val.val;
val = get_value(buf_read); // bytestring
if (tag == 52)
{
for (int i = 0; i < val.val-1; i++)
{
printf("%i.", buf_read->buff[buf_read->pt + i]);
}
printf("%i", buf_read->buff[buf_read->pt + val.val-1]);
}
else
{
ip6_addr a;// = (ip6_addr*) &buf_read->buff[buf_read->pt];
for (int i = 0; i < 4; i++)
{
a.addr[i] = 0;
for (int j = 0; j < 4; j++)
{
a.addr[i] = a.addr[i] << 8;
a.addr[i] += buf_read->buff[buf_read->pt + 4 * i + j];
}
}
ip6_ntop(a, buff);
printf("%s", buff);
}
buf_read->pt+=val.val;
}
void print_ip_prefix(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); // tag
val = get_value(buf_read); // block
val = get_value(buf_read);
long prefix = val.val;
val = get_value(buf_read); // bytestring
for (int i = 0; i < val.val-1; i++)
{
printf("%i.", buf_read->buff[buf_read->pt + i]);
}
printf("%i/%li", buf_read->buff[buf_read->pt + val.val], prefix);
buf_read->pt+=val.val;
}
void print_distance(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(compare_buff_str(buf_read, val.val, "distance"));
buf_read->pt+=val.val;
val = get_value(buf_read);
if (val.major == UINT)
{
printf("\t\tdistance %li\n", val.val);
return;
}
else if (val.major == TEXT)
{
printf("\t\tdistance ");
print_with_size_(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt+=val.val;
printf("\n");
return;
}
bug("print distance on incorrect type %i\n", val.major);
}
void discard_key(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
if(!(val.major == TEXT))
{
bug("key is not text but %i, pt is %i", val.major, buf_read->pt);
}
buf_read->pt+=val.val;
}
void print_string_string(struct buff_reader *buf_read, char *str)
{
discard_key(buf_read);
printf("%s", str);
struct value val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt += val.val;
}
void print_lsa_router(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
discard_key(buf_read);
printf("\trouter ");
print_ip_addr(buf_read);
printf("\n");
print_distance(buf_read);
discard_key(buf_read); // vlink
val = get_value(buf_read);
ASSERT(val.major == ARRAY);
val = get_value(buf_read);
while (!val_is_break(val))
{
discard_key(buf_read);
printf("\t\tvlink ");
print_ip_addr(buf_read);
discard_key(buf_read);
val = get_value(buf_read);
printf(" metric %li\n", val.val);
val = get_value(buf_read);
}
discard_key(buf_read); // router metric
val = get_value(buf_read);
ASSERT(val.major == ARRAY);
val = get_value(buf_read);
while (!val_is_break(val))
{
discard_key(buf_read);
printf("\t\trouter ");
print_ip_addr(buf_read);
val = get_value(buf_read);
buf_read->pt+=val.val;
val = get_value(buf_read);
printf(" metric %li\n", val.val);
val = get_value(buf_read);
}
discard_key(buf_read); // network
val = get_value(buf_read);
ASSERT(val.major == ARRAY);
val = get_value(buf_read);
while (!val_is_break(val))
{
ASSERT(val.major == BLOCK);
int block_len = val.val;
discard_key(buf_read); // dummy id
val = get_value(buf_read); //id num
discard_key(buf_read); // network
int bracket = !(block_len == 4 && buf_read->buff[buf_read->pt + 8] == 'l');
printf("\t\tnetwork ");
if (bracket)
printf("[");
print_ip_addr(buf_read);
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "nif"))
{
printf("-");
buf_read->pt+=val.val;
val = get_value(buf_read);
printf("%li", val.val);
}
else if (compare_buff_str(buf_read, val.val, "len"))
{
printf("/");
buf_read->pt+=val.val;
val = get_value(buf_read);
printf("%li", val.val);
}
if (bracket)
printf("]");
discard_key(buf_read);
val = get_value(buf_read);
printf(" metric %li\n", val.val);
val = get_value(buf_read);
}
val = get_value(buf_read);
if (!val_is_break(val))
{
val = get_value(buf_read); // open list
while (!val_is_break(val))
{
buf_read->pt+=val.val; // stubnet
val = get_value(buf_read); // open block
discard_key(buf_read); // stubnet
printf("\t\tstubnet ");
val = get_value(buf_read);
print_ip_addr(buf_read);
discard_key(buf_read); // len
val = get_value(buf_read);
printf("/%li", val.val);
discard_key(buf_read); // metric
val = get_value(buf_read);
printf(" metric %li\n", val.val);
}
val = get_value(buf_read);
}
}
void print_lsa_network(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
val = get_value(buf_read);
ASSERT(val.major == TEXT);
if (compare_buff_str(buf_read, val.val, "ospf2"))
{
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == BLOCK);
discard_key(buf_read); // network
printf("\tnetwork ");
print_ip_addr(buf_read);
printf("/");
discard_key(buf_read); // optx
val = get_value(buf_read);
printf("%li\n", val.val);
discard_key(buf_read); // dr
printf("\t\tdr ");
print_ip_addr(buf_read);
printf("\n");
}
else if (compare_buff_str(buf_read, val.val, "ospf"))
{
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == BLOCK);
discard_key(buf_read); // network
printf("\tnetwork ");
print_ip_addr(buf_read);
discard_key(buf_read); // lsa id
val = get_value(buf_read);
printf("-%li\n", val.val);
}
print_distance(buf_read);
discard_key(buf_read); // routers
val = get_value(buf_read);
ASSERT(val.major == ARRAY);
val = get_value(buf_read);
while (!val_is_break(val))
{
discard_key(buf_read);
printf("\t\trouter ");
print_ip_addr(buf_read);
printf("\n");
val = get_value(buf_read);
}
}
void print_lsa_sum_net(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
discard_key(buf_read);
printf("\t\txnetwork ");
print_ip_prefix(buf_read);
discard_key(buf_read);
val = get_value(buf_read);
printf("metric %li\n", val.val);
}
void print_lsa_sum_rt(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
discard_key(buf_read);
printf("\t\txrouter ");
print_ip_addr(buf_read);
discard_key(buf_read);
val = get_value(buf_read);
printf("metric %li\n", val.val);
}
void print_lsa_external(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
val = get_value(buf_read);
int via = 0;
if (compare_buff_str(buf_read, val.val, "via"))
{
buf_read->pt+=val.val;
via = buf_read->pt;
val = get_value(buf_read); // tag
val = get_value(buf_read); // bytestring
buf_read->pt+=val.val;
val = get_value(buf_read);
}
long tag = -1;
if (compare_buff_str(buf_read, val.val, "tag"))
{
buf_read->pt+=val.val;
val = get_value(buf_read);
tag = val.val;
val = get_value(buf_read);
}
discard_key(buf_read); // lsa type
printf("\t\t");
val = get_value(buf_read);
print_with_size_(&buf_read->buff[buf_read->pt], val.val);
printf(" ");
discard_key(buf_read);
print_ip_addr(buf_read);
discard_key(buf_read);
printf(" metric");
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "lsa_type_num"))
{
buf_read->pt+=val.val;
val = get_value(buf_read);
printf("%li", val.val);
val = get_value(buf_read);
}
buf_read->pt+=val.val;
val = get_value(buf_read);
printf(" %li", val.val);
if (via)
{
printf(" via ");
int pt = buf_read->pt;
buf_read->pt = via;
print_ip_addr(buf_read);
buf_read->pt = pt;
}
if (tag >- 1)
{
printf(" tag %08lx", tag);
}
val = get_value(buf_read); // end of block
}
void print_lsa_prefix(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
val = get_value(buf_read);
if (val_is_break(val))
return;
discard_key(buf_read);
val = get_value(buf_read); // open block or break
while (!val_is_break(val))
{
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "stubnet"))
{
buf_read->pt+=val.val;
printf("\t\tstubnet ");
print_ip_prefix(buf_read);
discard_key(buf_read);
val = get_value(buf_read);
printf(" metric %li", val.val);
}
else
{
buf_read->pt+=val.val;
printf("\t\taddress ");
print_ip_prefix(buf_read);
}
printf("\n");
val = get_value(buf_read);
val = get_value(buf_read); // open block or break
}
val = get_value(buf_read);
print_ip_addr(buf_read);
}
void print_show_ospf(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
val = get_value(buf_read);
printf("\n");
if (compare_buff_str(buf_read, val.val, "error"))
{
buf_read->pt+=val.val;
val = get_value(buf_read);
printf("error: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
return;
}
if (compare_buff_str(buf_read, val.val, "not_implemented"))
{
buf_read->pt+=val.val;
val = get_value(buf_read);
printf("not implemented: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
return;
}
buf_read->pt+=val.val;
val = get_value(buf_read); // list
ASSERT(val.major == ARRAY);
int j = val.val;
for (int i = 0; i < j; i++)
{
val = get_value(buf_read); // open block
ASSERT(val.major == BLOCK);
discard_key(buf_read); // dummy id
val = get_value(buf_read);
ASSERT(val.major == UINT);
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "area"))
{
buf_read->pt+=val.val;
printf("area ");
print_ip_addr(buf_read);
printf("\n");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "lsa_router"))
{
buf_read->pt+=val.val;
print_lsa_router(buf_read);
}
else if (compare_buff_str(buf_read, val.val, "lsa_network"))
{
buf_read->pt+=val.val;
print_lsa_network(buf_read);
}
else if (compare_buff_str(buf_read, val.val, "lsa_sum_net"))
{
buf_read->pt+=val.val;
print_lsa_sum_net(buf_read);
}
else if (compare_buff_str(buf_read, val.val, "lsa_sum_rt"))
{
buf_read->pt+=val.val;
print_lsa_sum_rt(buf_read);
}
else if (compare_buff_str(buf_read, val.val, "lsa_prefix"))
{
buf_read->pt+=val.val;
print_lsa_prefix(buf_read);
}
else if (compare_buff_str(buf_read, val.val, "lsa_external"))
{
buf_read->pt+=val.val;
print_lsa_external(buf_read);
}
val = get_value(buf_read);
}
discard_key(buf_read);
val = get_value(buf_read);
while (!val_is_break(val))
{
val = get_value(buf_read);
if (val_is_break(val))
return;
if (compare_buff_str(buf_read, val.val, "other_ABSRs"))
{
buf_read->pt+=val.val;
printf("other ABSRs\n");
val = get_value(buf_read); // null list
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "router"))
{
buf_read->pt+=val.val;
printf("router ");
print_ip_addr(buf_read);
val = get_value(buf_read);
}
buf_read->pt+=val.val;
print_lsa_external(buf_read);
val = get_value(buf_read);
val = get_value(buf_read);
}
}
void print_show_memory(struct buff_reader *buf_read)
{
printf("BIRD memory usage\n");
printf(" Effective Overhead\n");
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
val = get_value(buf_read); // header, may be it should be deleted
ASSERT(val.major == TEXT);
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == TEXT);
buf_read->pt+=val.val;
val = get_value(buf_read); // body
ASSERT(val.major == TEXT);
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == BLOCK);
val = get_value(buf_read);
while (val.major == TEXT && buf_read->pt < buf_read->size)
{
print_with_size(&buf_read->buff[buf_read->pt], val.val);
for (unsigned long i = 0; i < strlen(" ") - val.val; i++)
{
putc(' ', stdout);
}
buf_read->pt+=val.val;
val = get_value(buf_read); // block open
val = get_value(buf_read);
ASSERT(val.major == TEXT);
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == UINT);
printf("%7li B ", val.val);
val = get_value(buf_read);
ASSERT(val.major == TEXT);
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == UINT);
printf("%7li B\n", val.val);
val = get_value(buf_read);
}
}
void print_show_status(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
val = get_value(buf_read);
ASSERT(val.major == TEXT);
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == TEXT);
printf("BIRD ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == TEXT); // body
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == BLOCK);
val = get_value(buf_read);
ASSERT(val.major == TEXT); // router id
buf_read->pt+=val.val;
printf("router id: ");
print_ip_addr(buf_read);
printf("\n");
val = get_value(buf_read);
ASSERT(val.major == TEXT); // hostname
buf_read->pt+=val.val;
printf("hostname: ");
val = get_value(buf_read);
ASSERT(val.major == TEXT);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt+=val.val;
for (int i =0; i<3; i++)
{
val = get_value(buf_read);
ASSERT(val.major == TEXT); // server time, last rebooot, last reconfiguration
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt+=val.val;
printf(": ");
print_epoch_time(buf_read);
printf("\n");
}
val = get_value(buf_read);
if (val.major == TEXT)
{
buf_read->pt+=val.val;
printf("Graceful restart recovery in progress\n");
val = get_value(buf_read); // open 2 block
discard_key(buf_read);
val = get_value(buf_read);
printf(" Waiting for %ld channels to recover\n", val.val);
discard_key(buf_read);
val = get_value(buf_read); // open 2 block
discard_key(buf_read);
printf(" Wait timer is ");
print_relativ_time(buf_read);
discard_key(buf_read);
val = get_value(buf_read);
printf("/%lu", val.val);
}
val = get_value(buf_read);
ASSERT(val.major == TEXT); // state
printf("state: ");
buf_read->pt+=val.val;
val = get_value(buf_read);
ASSERT(val.major == TEXT);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt+=val.val;
}
void print_show_symbols(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
discard_key(buf_read);
val = get_value(buf_read);
int one_item = 0;
if (val.val == 1)
one_item = 1;
if (val.val == 0)
return;
val = get_value(buf_read);
if (val_is_break(val))
{
printf("no names found\n");
return;
}
val = get_value(buf_read);
while (val.major == TEXT)
{
buf_read->pt+=val.val; //name
val = get_value(buf_read);
print_with_size_(&buf_read->buff[buf_read->pt], val.val);
for (int i = val.val; i < 15; i++)
{
printf(" ");
}
buf_read->pt+=val.val;
val = get_value(buf_read); //type
buf_read->pt+=val.val;
val = get_value(buf_read);
print_with_size_(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt+=val.val;
if (one_item)
return;
val = get_value(buf_read);
if (val_is_break(val))
return;
val = get_value(buf_read);
}
}
void print_route_change_line(struct buff_reader *buf_read)
{
for (int i = 0; i < 5; i++)
{
struct value val = get_value(buf_read);
if (val.major == UINT)
printf(" %10lu", val.val);
else
printf(" ---");
}
printf("\n");
}
void print_channel_show_stats(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); //open block
discard_key(buf_read);
val = get_value(buf_read);
printf(" Routes: %lu imported, ", val.val);
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "serial_num"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf("%lu filtered, ", val.val);
val = get_value(buf_read);
}
buf_read->pt += val.val;
val = get_value(buf_read);
printf("%lu exported, ", val.val);
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu preferred\n", val.val);
printf(" Route change stats: received rejected filtered ignored accepted\n");
discard_key(buf_read); //import_updates
val = get_value(buf_read); //open list
printf(" Import updates: ");
print_route_change_line(buf_read);
discard_key(buf_read); //import_updates
val = get_value(buf_read); //open list
printf(" Import withdraws: ");
print_route_change_line(buf_read);
discard_key(buf_read); //import_updates
val = get_value(buf_read); //open list
printf(" Export updates: ");
print_route_change_line(buf_read);
discard_key(buf_read); //import_updates
val = get_value(buf_read); //open list
printf(" Export withdraws: ");
print_route_change_line(buf_read);
val = get_value(buf_read); //close block
}
void print_channel_show_limit(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
int siz = val.val;
buf_read->pt += val.val;
val = get_value(buf_read); //block
val = get_value(buf_read);
if (val_is_break(val))
return;
buf_read->pt += val.val;
printf(" ");
print_with_size(&buf_read->buff[buf_read->pt], siz);
for(int i = 0; i < 16 - siz; i++)
putc(' ', stdout);
val = get_value(buf_read);
printf("%ld ", val.val);
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n Action: ");
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
val = get_value(buf_read);
}
void print_channel_show_info(struct buff_reader *buf_read)
{
// This function expect removed key channels and removed block opening. The reason is bgp channel list.
print_string_string(buf_read, " Channel ");
print_string_string(buf_read, " State: ");
print_string_string(buf_read, " Table: ");
discard_key(buf_read);
struct value val = get_value(buf_read);
printf(" Preference: %ld\n", val.val);
print_string_string(buf_read, " Input filter: ");
print_string_string(buf_read, " Output filter: ");
int pt = buf_read->pt;
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "gr_pending"))
{
buf_read->pt += val.val;
printf(" GR recovery: ");
val = get_value(buf_read);
if (val.val)
printf(" pending");
discard_key(buf_read);
val = get_value(buf_read);
if (val.val)
printf(" waiting");
printf("\n");
}
else
{
buf_read->pt = pt; // this is not nice, but we need the name of the block.
//If the name of the block is allways same, we would need to create lists for limits.
}
print_channel_show_limit(buf_read);
print_channel_show_limit(buf_read);
print_channel_show_limit(buf_read);
val = get_value(buf_read);
if (!val_is_break(val))
{
buf_read->pt += val.val;
print_channel_show_stats(buf_read);
val = get_value(buf_read);
}
}
void print_pipe_show_stats(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); //open block
discard_key(buf_read);
val = get_value(buf_read);
printf(" Routes: %lu imported, ", val.val);
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu exported\n", val.val);
printf(" Route change stats: received rejected filtered ignored accepted\n");
discard_key(buf_read); //import_updates
val = get_value(buf_read); //open list
printf(" Import updates: ");
print_route_change_line(buf_read);
discard_key(buf_read);
val = get_value(buf_read); //open list
printf(" Import withdraws: ");
print_route_change_line(buf_read);
discard_key(buf_read);
val = get_value(buf_read); //open list
printf(" Export updates: ");
print_route_change_line(buf_read);
discard_key(buf_read);
val = get_value(buf_read); //open list
printf(" Export withdraws: ");
print_route_change_line(buf_read);
val = get_value(buf_read); //close block
}
void print_rpki_show_proto_info_timer(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); // name
printf(" ");
print_with_size_add_space(&buf_read->buff[buf_read->pt], val.val, 16);
buf_read->pt += val.val;
val = get_value(buf_read); //open block
val = get_value(buf_read);
if (!val_is_break(val))
{
buf_read->pt += val.val;
printf(": ");
print_relativ_time(buf_read);
printf("/");
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu\n", val.val);
val = get_value(buf_read); //close block
}
else
{
printf(": ---\n");
}
}
void print_show_protocols_rpki(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); //open block
discard_key(buf_read);
val = get_value(buf_read);
printf(" Cache server: ");
print_with_size_(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt += val.val;
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "cache_port"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" Cache port: %lu\n", val.val);
val = get_value(buf_read);
}
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" Status: ");
print_with_size_(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt += val.val;
print_string_string(buf_read, " Transport: ");
discard_key(buf_read);
val = get_value(buf_read);
printf(" Protocol version: %lu\n", val.val);
discard_key(buf_read);
printf(" Session ID: ");
val = get_value(buf_read);
if (val.major == TEXT)
{
printf("---\n");
buf_read->pt += val.val;
}
else
printf("%lu\n", val.val);
int pt = buf_read->pt;
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "serial_num"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" Serial number: %lu\n", val.val);
discard_key(buf_read);
printf(" Last update: before ");
print_relativ_time(buf_read);
printf(" s\n");
}
else
{
printf(" Serial number: ---\n");
printf(" Last update: ---\n");
buf_read->pt = pt;
}
print_rpki_show_proto_info_timer(buf_read);
print_rpki_show_proto_info_timer(buf_read);
print_rpki_show_proto_info_timer(buf_read);
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "no_roa4"))
{
printf(" No roa4 channel\n");
buf_read->pt += val.val;
}
else
{
buf_read->pt += val.val;
val = get_value(buf_read);
print_channel_show_info(buf_read);
}
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "no_roa6"))
{
printf(" No roa6 channel\n");
buf_read->pt += val.val;
}
else
{
buf_read->pt += val.val;
val = get_value(buf_read);
print_channel_show_info(buf_read);
}
val = get_value(buf_read);
val = get_value(buf_read);
}
void print_bgp_show_afis(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); //open list
val = get_value(buf_read); //open block (or break)
while (!val_is_break(val))
{
val = get_value(buf_read); //key
if (compare_buff_str(buf_read, val.val, "name"))
{
buf_read->pt += val.val;
printf(" ");
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt += val.val;
}
else
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" <%lu/", val.val);
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu>\n", val.val);
}
val = get_value(buf_read); //close block
val = get_value(buf_read); //close list or open block
}
}
void print_bgp_capabilities(struct buff_reader *buf_read)
{
discard_key(buf_read);
struct value val = get_value(buf_read); //open block
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "AF_announced"))
{
buf_read->pt += val.val;
printf(" Multiprotocol\n");
printf(" AF announced:");
print_bgp_show_afis(buf_read);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "route_refresh"))
{
buf_read->pt += val.val;
printf(" Route refresh\n");
val = get_value(buf_read); //zero list
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "IPv6_nexthop"))
{
buf_read->pt += val.val;
printf(" Extended next hop\n");
printf(" IPv6 nexthop:\n");
print_bgp_show_afis(buf_read);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "extended_message"))
{
buf_read->pt += val.val;
printf(" Extended message\n");
val = get_value(buf_read); //zero list
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "graceful_restart"))
{
buf_read->pt += val.val;
printf(" Graceful restart\n");
val = get_value(buf_read); //zero list
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "restart_time"))
{
buf_read->pt += val.val;
discard_key(buf_read);
printf(" Restart time: ");
print_epoch_time(buf_read);
printf("\n");
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "restart_recovery"))
{
buf_read->pt += val.val;
printf(" Restart recovery\n");
val = get_value(buf_read); //zero list
val = get_value(buf_read);
}
discard_key(buf_read);
printf(" AF supported:\n");
print_bgp_show_afis(buf_read);
printf(" AF preserved:\n");
discard_key(buf_read);
print_bgp_show_afis(buf_read);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "4-octet_AS_numbers"))
{
buf_read->pt += val.val;
printf(" 4-octet AS numbers\n");
val = get_value(buf_read); //zero list
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "add_path_RX"))
{
buf_read->pt += val.val;
printf(" RX:\n");
print_bgp_show_afis(buf_read);
printf(" TX:\n");
discard_key(buf_read);
print_bgp_show_afis(buf_read);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "enhanced_refresh"))
{
buf_read->pt += val.val;
printf(" Enhanced refresh\n");
val = get_value(buf_read); //zero list
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "long_lived_gr"))
{
buf_read->pt += val.val;
printf(" Long-lived graceful restart\n");
val = get_value(buf_read); //zero list
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "ll_stale_time"))
{
buf_read->pt += val.val;
printf(" LL stale time: ");
print_epoch_time(buf_read);
printf("\n");
discard_key(buf_read);
printf(" AF supported:\n");
print_bgp_show_afis(buf_read);
printf(" AF preserved:\n");
discard_key(buf_read);
print_bgp_show_afis(buf_read);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "hostname"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" Hostname: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "role"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" Role: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
val = get_value(buf_read);
}
}
void print_show_protocols_bgp(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); //open block
discard_key(buf_read);
printf(" BGP state: ");
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt += val.val;
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "neighbor_range"))
{
buf_read->pt += val.val;
printf(" Neighbor range: ");
print_ip_prefix(buf_read);
printf("\n");
}
else
{
buf_read->pt += val.val;
printf(" Neighbor address: ");
print_ip_addr(buf_read);
discard_key(buf_read);
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
}
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "neighbor_port"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" Neighbor port: %lu\n", val.val);
discard_key(buf_read);
}
else
{
buf_read->pt += val.val;
}
val = get_value(buf_read);
printf(" Neighbor AS: %lu\n", val.val);
discard_key(buf_read);
val = get_value(buf_read);
printf(" Local AS: %lu\n", val.val);
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "gr_active"))
{
printf(" Neighbor graceful restart active\n");
buf_read->pt += val.val;
val = get_value(buf_read); //null list
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "error_wait_remains"))
{
buf_read->pt += val.val;
printf(" Error wait: ");
print_relativ_time(buf_read);
printf("/");
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu\n", val.val);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "connect_remains"))
{
buf_read->pt += val.val;
printf(" Connect delay: ");
print_relativ_time(buf_read);
printf("/");
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu\n", val.val);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "restart_time"))
{
buf_read->pt += val.val;
printf(" Restart timer: ");
print_relativ_time(buf_read);
printf("/-\n");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "neighbor_id"))
{
buf_read->pt += val.val;
printf(" Neighbor ID: ");
print_ip_addr(buf_read);
printf("\n");
printf(" Local capabilities\n");
print_bgp_capabilities(buf_read);
printf(" Neighbor capabilities\n");
print_bgp_capabilities(buf_read);
discard_key(buf_read);
printf(" Session: ");
val = get_value(buf_read); //open list
val = get_value(buf_read);
while (!val_is_break(val))
{
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf(" ");
buf_read->pt += val.val;
val = get_value(buf_read);
}
printf("\n");
discard_key(buf_read);
printf(" Source address: ");
print_ip_addr(buf_read);
printf("\n");
discard_key(buf_read);
printf(" Hold timer: ");
print_relativ_time(buf_read);
printf("/");
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu\n", val.val);
discard_key(buf_read);
printf(" Keepalive timer: ");
print_relativ_time(buf_read);
printf("/");
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu\n", val.val);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "last_err1"))
{
buf_read->pt += val.val;
printf(" Last error: ");
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf(" ");
discard_key(buf_read);
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
val = get_value(buf_read);
}
buf_read->pt += val.val; //channels
val = get_value(buf_read); //open list
val = get_value(buf_read); //open block
val = get_value(buf_read); //channel
while (!val_is_break(val))
{
buf_read->pt += val.val;
val = get_value(buf_read); //open block
ASSERT(val.major == BLOCK);
print_channel_show_info(buf_read);
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "neighbor_gr"))
{
buf_read->pt += val.val;
printf(" Neighbor GR: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "llstale_timer"))
{
buf_read->pt += val.val;
printf(" LL stale timer: ");
print_relativ_time(buf_read);
printf("/-");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "next_hop"))
{
buf_read->pt += val.val;
printf(" BGP Next hop: ");
print_ip_addr(buf_read);
printf("\n");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "next_hop1"))
{
buf_read->pt += val.val;
printf(" BGP Next hop: ");
print_ip_addr(buf_read);
discard_key(buf_read);
printf(" ");
print_ip_addr(buf_read);
printf("\n");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "igp_ipv4_table"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" IGP IPv4 table: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "igp_ipv6_table"))
{
buf_read->pt += val.val;
printf(" IGP IPv6 table: ");
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "igp_ipv4_table"))
{
buf_read->pt += val.val;
printf(" Base table: ");
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
val = get_value(buf_read);
}
val = get_value(buf_read);
}
val = get_value(buf_read);
}
void print_show_protocols(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read);
ASSERT(val.major == BLOCK);
discard_key(buf_read); //table
val = get_value(buf_read);
ASSERT(val.major == ARRAY);
val = get_value(buf_read);
printf("%-10s %-10s %-10s %-6s %-18s %s\n",
"Name", "Proto", "Table", "State", "Since", "Info");
while (!val_is_break(val))
{
ASSERT(val.major == BLOCK);
discard_key(buf_read); //name
val = get_value(buf_read);
print_with_size_add_space(&buf_read->buff[buf_read->pt], val.val, 11);
buf_read->pt += val.val;
discard_key(buf_read); //proto
val = get_value(buf_read);
print_with_size_add_space(&buf_read->buff[buf_read->pt], val.val, 11);
buf_read->pt += val.val;
discard_key(buf_read); //table
val = get_value(buf_read);
print_with_size_add_space(&buf_read->buff[buf_read->pt], val.val, 11);
buf_read->pt += val.val;
discard_key(buf_read); //state
val = get_value(buf_read);
print_with_size_add_space(&buf_read->buff[buf_read->pt], val.val, 7);
buf_read->pt += val.val;
discard_key(buf_read); // since
print_epoch_time(buf_read);
printf(" ");
discard_key(buf_read); //info
val = get_value(buf_read);
print_with_size(&buf_read->buff[buf_read->pt], val.val);
buf_read->pt += val.val;
printf("\n");
val = get_value(buf_read);
if (!val_is_break(val))
{
if (compare_buff_str(buf_read, val.val, "description"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" Description: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt += val.val;
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "message"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" Message: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt += val.val;
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "router_id"))
{
buf_read->pt += val.val;
printf(" Router ID: ");
print_ip_addr(buf_read);
val = get_value(buf_read);
}
if (compare_buff_str(buf_read, val.val, "vfr"))
{
buf_read->pt += val.val;
val = get_value(buf_read);
printf(" VRF: ");
print_with_size(&buf_read->buff[buf_read->pt], val.val);
printf("\n");
buf_read->pt += val.val;
val = get_value(buf_read);
}
if (val_is_break(val))
{
return;
}
ASSERT(val.major == TEXT);
if (compare_buff_str(buf_read, val.val, "rpki"))
{
buf_read->pt += val.val;
print_show_protocols_rpki(buf_read);
printf("\n");
}
else if (compare_buff_str(buf_read, val.val, "pipe"))
{
buf_read->pt += val.val;
val = get_value(buf_read); //open block
printf(" Channel %s\n", "main");
print_string_string(buf_read, " Table: ");
print_string_string(buf_read, " Peer table: ");
print_string_string(buf_read, " Table: ");
print_string_string(buf_read, " Import state: ");
print_string_string(buf_read, " Export state: ");
print_string_string(buf_read, " Import filter: ");
print_string_string(buf_read, " Export filter: ");
print_channel_show_limit(buf_read);
print_channel_show_limit(buf_read);
val = get_value(buf_read);
if (!val_is_break(val))
{
buf_read->pt += val.val; // discarding key "stats"
print_pipe_show_stats(buf_read);
val = get_value(buf_read);
}
val = get_value(buf_read);
printf("\n");
}
else if (compare_buff_str(buf_read, val.val, "bgp"))
{
buf_read->pt += val.val;
print_show_protocols_bgp(buf_read);
val = get_value(buf_read);
printf("\n");
}
else
{
buf_read->pt += val.val;
val = get_value(buf_read);
while(!val_is_break(val))
{
print_channel_show_info(buf_read);
val = get_value(buf_read);
if (val.major == TEXT)
{
buf_read->pt += val.val;
val = get_value(buf_read);
}
}
printf("\n");
}
}
val = get_value(buf_read);
}
}
void print_cbor_response(byte *cbor, int len)
{
// This is only for debug purposes
FILE *write_ptr;
write_ptr = fopen("arrived.cbor", "wb");
fwrite(cbor, len, 1, write_ptr);
fclose(write_ptr);
//
struct buff_reader buf_read;
buf_read.buff = cbor;
buf_read.size = len;
buf_read.pt = 0;
struct value val = get_value(&buf_read);
ASSERT(val.major == BLOCK);
ASSERT(val.val <=1);
val = get_value(&buf_read);
ASSERT(val.major == TEXT);
printf("\n");
if (compare_buff_str(&buf_read, val.val, "show_memory:message"))
{
buf_read.pt += val.val;
print_show_memory(&buf_read);
}
else if (compare_buff_str(&buf_read, val.val, "show_status:message"))
{
buf_read.pt += val.val;
print_show_status(&buf_read);
}
else if (compare_buff_str(&buf_read, val.val, "show_symbols:message"))
{
buf_read.pt += val.val;
print_show_symbols(&buf_read);
}
else if (compare_buff_str(&buf_read, val.val, "show_ospf:message"))
{
buf_read.pt += val.val;
print_show_ospf(&buf_read);
}
else if (compare_buff_str(&buf_read, val.val, "show_protocols:message"))
{
buf_read.pt += val.val;
print_show_protocols(&buf_read);
}
printf("\nbird>");
fflush(stdout);
}