cbor_close_block_or_list(w);
}
+int serial_num = 0;
+
void
make_cmd_cbor(char *cmd_buffer)
{
struct linpool *lp = lp_new(&root_pool);
struct cbor_writer *w = cbor_init(cbor_buf, l*10, lp);
+
+ write_item(w, 6, 24); // tag 24 - cbor binary
+ int length_pt = w->pt + 1;
+ cbor_write_item_with_constant_val_length_4(w, 2, 0);
+ cbor_open_list_with_length(w, 2);
+ cbor_write_item_with_constant_val_length_4(w, 0, serial_num);
+
cbor_open_block_with_length(w, 1);
cbor_add_string(w, "command:do");
{
cbor_string_int(w, "command", SHOW_MEMORY);
cbor_close_block_or_list(w);
+ rewrite_4bytes_int(w, length_pt, w->pt);
server_send_byte(cbor_buf, w->pt);
lp_flush(lp);
return;
{
cbor_string_int(w, "command", SHOW_STATUS);
cbor_close_block_or_list(w);
- cbor_write_to_file(w, "status_command.cbor");
+ rewrite_4bytes_int(w, length_pt, w->pt);
server_send_byte(cbor_buf, w->pt);
lp_flush(lp);
return;
cbor_string_int(w, "command", SHOW_SYMBOLS);
write_args_cbor(&cmd_buffer[buf_pt + strlen("symbols ")], w);
cbor_close_block_or_list(w);
+ rewrite_4bytes_int(w, length_pt, w->pt);
server_send_byte(cbor_buf, w->pt);
lp_flush(lp);
return;
cbor_string_int(w, "command", SHOW_OSPF);
write_args_cbor(&cmd_buffer[buf_pt + strlen("ospf")], w);
cbor_close_block_or_list(w);
+ rewrite_4bytes_int(w, length_pt, w->pt);
server_send_byte(cbor_buf, w->pt);
lp_flush(lp);
return;
cbor_string_int(w, "command", SHOW_PROTOCOLS);
write_args_cbor(&cmd_buffer[buf_pt + strlen("protocols")], w);
cbor_close_block_or_list(w);
+ rewrite_4bytes_int(w, length_pt, w->pt);
server_send_byte(cbor_buf, w->pt);
lp_flush(lp);
return;
else if (compare_string(cmd_buffer, l, "down"))
{
cbor_add_string(w, "down");
+ rewrite_4bytes_int(w, length_pt, w->pt);
server_send_byte(cbor_buf, w->pt);
die("Shutdown from client");
return;
void
server_got_binary(int c)
{
- // TODO check cbor hello
if (cbor_mode == 0)
{
byte expected[] = {0x87, 0x42, 0x49, 0x52, 0x44, 0x0D, 0x0A, 0x1A, 0x0A, 0x01};
cbor_mode = 1;
}
else {
- print_cbor_response(server_read_buf, c);
+ int length = 0;
+ for (int i = 0; i < 4; i++)
+ {
+ length = length << 8;
+ length += server_read_buf[3 + i];
+ }
+ printf("length of message is %i\n", length);
+ if (length > c - 7)
+ {
+ byte bigger_buf[length];
+ memcpy(bigger_buf, server_read_buf, c);
+ int cc = read(server_fd, &bigger_buf[c], length - c + 7);
+ if (!cc)
+ die("Connection closed by server");
+ if (cc < 0)
+ {
+ DIE("Server read error");
+ }
+ print_cbor_response(&bigger_buf[13], length);
+ }
+ else
+ {
+ printf("no need to load more\n");
+ for (int i = 0; i < 15; i++)
+ {
+ printf("%i %x\n",i, server_read_buf[i] );
+ }
+ print_cbor_response(&server_read_buf[13], c);
+ }
}
busy = 0;
skip_input = 0;
struct value val = get_value(buf_read);
if(!(val.major == TEXT))
{
- bug("key is not text but %i", val.major);
+ bug("key is not text but %i, pt is %i", val.major, buf_read->pt);
}
buf_read->pt+=val.val;
}
}
}
+
+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);
val = get_value(buf_read);
}
-void print_route_change_line(struct buff_reader *buf_read)
+void print_channel_show_info(struct buff_reader *buf_read)
{
- for (int i = 0; i < 5; i++)
+// 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"))
{
- struct value val = get_value(buf_read);
- if (val.major == UINT)
- printf(" %10lu", val.val);
- else
- printf(" ---");
+ 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);
}
- printf("\n");
}
+
void print_pipe_show_stats(struct buff_reader *buf_read)
{
struct value val = get_value(buf_read); //open block
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;
+ val = get_value(buf_read);
+ printf(": ");
+ print_as_time(val.val);
+ 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
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);
}
- print_string_string(buf_read, " Status: ");
+ 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);
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"))
{
printf(" Serial number: %lu\n", val.val);
discard_key(buf_read);
val = get_value(buf_read);
- printf(" Last update: before %lu s\n", val.val);
+ printf(" Last update: before ");
+ print_as_time(val.val);
+ printf(" s\n");
}
else
{
printf(" Serial number: ---\n");
printf(" Last update: ---\n");
+ buf_read->pt = pt;
}
- val = get_value(buf_read);
-}
+ print_rpki_show_proto_info_timer(buf_read);
+ print_rpki_show_proto_info_timer(buf_read);
+ print_rpki_show_proto_info_timer(buf_read);
-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"))
+
+ 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);
- printf("%lu filtered, ", val.val);
- val = get_value(buf_read);
+ print_channel_show_info(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_info(struct buff_reader *buf_read)
-{
- 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"))
+ if (compare_buff_str(buf_read, val.val, "no_roa6"))
{
+ printf(" No roa6 channel\n");
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);
+ 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
void print_bgp_capabilities(struct buff_reader *buf_read)
{
- printf("<debug capabilities <%s>, %x %x>\n", &buf_read->buff[buf_read->pt], buf_read->buff[buf_read->pt], buf_read->buff[buf_read->pt+1]);
discard_key(buf_read);
struct value val = get_value(buf_read); //open block
- printf("<debug: val major %i, val val %li>\n", val.major, val.val);
val = get_value(buf_read);
if (compare_buff_str(buf_read, val.val, "AF_announced"))
{
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);
}
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);
}
}
else
{
- printf("<debug ");
- print_with_size(&buf_read->buff[buf_read->pt], val.val);
- printf("debug >");
buf_read->pt += val.val;
}
val = get_value(buf_read);
- printf("<debug maj %i val %li>\n", val.major, val.val);
- for (int i = 0; i< 30; i++)
- {
- printf("<debug capabilities %x>\n", buf_read->buff[buf_read->pt+i]);
- }
printf(" Neighbor AS: %lu\n", val.val);
- //discard_key(buf_read);
- printf("<debug");
- val = get_value(buf_read);
- printf(" maj %i val %li>\n ", val.major, val.val);
- print_with_size(&buf_read->buff[buf_read->pt], val.val);
- buf_read->pt += val.val;
- printf(" debug>\n");
+ discard_key(buf_read);
val = get_value(buf_read);
- printf("<debug maj %i val %li>\n", val.major, val.val);
printf(" Local AS: %lu\n", val.val);
val = get_value(buf_read);
- printf("<debug maj %i val %li>\n", val.major, val.val);
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);
- printf(" Error wait: %lu/", val.val);
+ printf(" Error wait: ");
+ print_as_time(val.val);
+ printf("/");
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu\n", val.val);
{
buf_read->pt += val.val;
val = get_value(buf_read);
- printf(" Connect delay: %lu/", val.val);
+ printf(" Connect delay: ");
+ print_as_time(val.val);
+ printf("/");
discard_key(buf_read);
val = get_value(buf_read);
printf("%lu\n", val.val);
{
buf_read->pt += val.val;
val = get_value(buf_read);
- printf(" Connect delay: %lu/-\n", val.val);
+ printf(" Connect delay: ");
+ print_as_time(val.val);
+ 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: ");
- printf("<debug capabilities <%s>, %x %x>\n", &buf_read->buff[buf_read->pt], buf_read->buff[buf_read->pt], buf_read->buff[buf_read->pt+1]);
- for (int i = 0; i< 30; i++)
- {
- printf("<debug capabilities %x>\n", buf_read->buff[buf_read->pt+i]);
- }
print_ip_addr(buf_read);
printf("\n");
printf(" Local capabilities\n");
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: ");
- 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(" ");
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);
}
- discard_key(buf_read); //channels
+ 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))
{
- discard_key(buf_read); //channel
+ 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);
}
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_ipv4_table"))
+ 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);
}
{
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);
- printf("<debug: val major %i, val val %li>\n", val.major, val.val);
}
void print_show_protocols(struct buff_reader *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; // 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("<debug: val major %i, val val %li>\n", val.major, val.val);
printf("\n");
}
else
}
}
val = get_value(buf_read);
- printf("<debug: val major %i, val val %li>\n", val.major, val.val);
}
}
{
case SHOW_MEMORY:
skip_optional_args(rbuf_read, items_in_block);
- return cmd_show_memory_cbor(tbuf_read->buff, tbuf_read->size, lp);
+ return cmd_show_memory_cbor(&tbuf_read->buff[tbuf_read->pt], tbuf_read->size, lp);
case SHOW_STATUS:
log("show status");
skip_optional_args(rbuf_read, items_in_block);
- return cmd_show_status_cbor(tbuf_read->buff, tbuf_read->size, lp);
+ return cmd_show_status_cbor(&tbuf_read->buff[tbuf_read->pt], tbuf_read->size, lp);
case SHOW_SYMBOLS:
args = parse_arguments(rbuf_read, items_in_block, lp);
- return cmd_show_symbols_cbor(tbuf_read->buff, tbuf_read->size, args, lp);
+ return cmd_show_symbols_cbor(&tbuf_read->buff[tbuf_read->pt], tbuf_read->size, args, lp);
case SHOW_OSPF:
args = parse_arguments(rbuf_read, items_in_block, lp);
log("args %i, pt %i", args, args->pt);
- return cmd_show_ospf_cbor(tbuf_read->buff, tbuf_read->size, args, lp);
+ return cmd_show_ospf_cbor(&tbuf_read->buff[tbuf_read->pt], tbuf_read->size, args, lp);
case SHOW_PROTOCOLS:
args = parse_arguments(rbuf_read, items_in_block, lp);
log("args %i, pt %i", args, args->pt);
- return cmd_show_protocols_cbor(tbuf_read->buff, tbuf_read->size, args, lp);
+ return cmd_show_protocols_cbor(&tbuf_read->buff[tbuf_read->pt], tbuf_read->size, args, lp);
default:
bug("command %li not found", val.val);
return 0;
}
}
+uint
+add_header(struct buff_reader *tbuf_read, struct linpool *lp, int serial_num)
+{
+ struct cbor_writer *w = cbor_init(tbuf_read->buff, tbuf_read->size, lp);
+ write_item(w, 6, 24); // tag 24 - cbor binary
+ int length_pt = w->pt + 1; // place where we will put final size
+ cbor_write_item_with_constant_val_length_4(w, 2, 0);
+ cbor_open_list_with_length(w, 2);
+ cbor_write_item_with_constant_val_length_4(w, 0, serial_num);
+ tbuf_read->pt+=w->pt;
+ return length_pt;
+}
+
+uint
+read_head(struct buff_reader *rbuf_read)
+{
+ struct value val = get_value(rbuf_read); //tag
+ val = get_value(rbuf_read); //bytestring
+ val = get_value(rbuf_read); //list
+ val = get_value(rbuf_read); //serial_num
+ int ret = val.val;
+ return ret;
+}
+
uint
detect_down(uint size, byte *rbuf)
{
rbuf_read.buff = rbuf;
rbuf_read.size = size;
rbuf_read.pt = 0;
+ read_head(&rbuf_read);
struct value val = get_value(&rbuf_read);
ASSERT(val.major == BLOCK);
val = get_value(&rbuf_read);
return (val.major = TEXT && compare_buff_str(&rbuf_read, val.val, "down"));
}
-
uint
parse_cbor(uint size, byte *rbuf, byte *tbuf, uint tbsize, struct linpool* lp)
{
rbuf_read.pt = 0;
tbuf_read.pt = 0;
- if (size == 0)
+ if (size <=7)
{
return 0;
}
+
+ int serial_num = read_head(&rbuf_read);
+ int length_pt = add_header(&tbuf_read, lp, serial_num);
+ for (int i = 0; i < 15; i++)
+ {
+ log("%i %x",i, tbuf[i] );
+ }
+ tbuf_read.size = tbsize - tbuf_read.pt;
+
struct value val = get_value(&rbuf_read);
ASSERT(val.major == BLOCK);
ASSERT(val.val <=1);
ASSERT(compare_buff_str(&rbuf_read, val.val, "command"));
rbuf_read.pt+=val.val;
- tbuf_read.pt = do_command(&rbuf_read, &tbuf_read, items_in_block, lp);
+ tbuf_read.pt += do_command(&rbuf_read, &tbuf_read, items_in_block, lp);
if (items_in_block == -1)
{
val = get_value(&rbuf_read);
}
}
}
+ struct cbor_writer *w = cbor_init(tbuf_read.buff, tbuf_read.size, lp);
+ rewrite_4bytes_int(w, length_pt, tbuf_read.pt - 7); // add final length to header
+ for (int i = 0; i < 15; i++)
+ {
+ log("%i %x",i, tbuf[i] );
+ }
lp_flush(lp);
log("parsed");
return tbuf_read.pt;