diff --git a/client/client.c b/client/client.c index d782a06f..f0acb3d8 100644 --- a/client/client.c +++ b/client/client.c @@ -234,6 +234,16 @@ make_cmd_cbor(char *cmd_buffer) lp_flush(lp); return; } + else if (compare_string(&cmd_buffer[buf_pt], l, "protocols")) + { + printf("protocols\n"); + cbor_string_int(w, "command", SHOW_PROTOCOLS); + write_args_cbor(&cmd_buffer[buf_pt + strlen("protocols")], w); + cbor_close_block_or_list(w); + server_send_byte(cbor_buf, w->pt); + lp_flush(lp); + return; + } else { printf("this command is not implemented yet\n"); diff --git a/client/print_cbor.c b/client/print_cbor.c index 671fa00d..818c0f9b 100644 --- a/client/print_cbor.c +++ b/client/print_cbor.c @@ -1,5 +1,6 @@ #include -#include "nest/cbor_parse.c" +#include "nest/cbor_parse_tools.h" +#include "nest/cbor_shortcuts.h" void print_with_size(byte *string, int len) { @@ -12,6 +13,15 @@ void print_with_size(byte *string, int len) } } +void print_as_time(long int t) +{ + int t1 = t TO_S; + int t2 = t - t1 S; + while (t2 > 999) + t2 = t2/10; + printf("%i.%i", t1, t2); +} + void print_with_size_(byte *string, int len) { for (int i = 0; i < len; i++) @@ -20,15 +30,47 @@ void print_with_size_(byte *string, int len) } } +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 - for (int i = 0; i < val.val-1; i++) + if (tag == 52) { - printf("%i.", buf_read->buff[buf_read->pt + i]); + 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); } - printf("%i", buf_read->buff[buf_read->pt + val.val]); buf_read->pt+=val.val; } @@ -86,6 +128,15 @@ void print_time(int64_t time) } +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) { @@ -627,8 +678,774 @@ void print_show_symbols(struct buff_reader *buf_read) } } +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_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_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_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; + 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); + } + + print_string_string(buf_read, " Status: "); + 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); + + 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); + val = get_value(buf_read); + printf(" Last update: before %lu s\n", val.val); + } + else + { + printf(" Serial number: ---\n"); + printf(" Last update: ---\n"); + } + val = get_value(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")) + { + 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_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")) + { + 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_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) +{ + printf(", %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("\n", val.major, val.val); + 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); + val = get_value(buf_read); + printf(" Restart time: %lu", val.val); + 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; + val = get_value(buf_read); + printf(" LL stale time: %lu\n", val.val); + 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); + 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); + 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 + { + printf("buff[buf_read->pt], val.val); + printf("debug >"); + buf_read->pt += val.val; + } + val = get_value(buf_read); + printf("\n", val.major, val.val); + for (int i = 0; i< 30; i++) + { + printf("\n", buf_read->buff[buf_read->pt+i]); + } + + printf(" Neighbor AS: %lu\n", val.val); + //discard_key(buf_read); + printf("\n ", val.major, val.val); + print_with_size(&buf_read->buff[buf_read->pt], val.val); + buf_read->pt += val.val; + printf(" debug>\n"); + val = get_value(buf_read); + printf("\n", val.major, val.val); + printf(" Local AS: %lu\n", val.val); + + val = get_value(buf_read); + printf("\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); //null list + val = get_value(buf_read); + } + if (compare_buff_str(buf_read, val.val, "error_wait_remains")) + { + buf_read->pt += val.val; + val = get_value(buf_read); + printf(" Error wait: %lu/", val.val); + 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; + val = get_value(buf_read); + printf(" Connect delay: %lu/", val.val); + 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; + val = get_value(buf_read); + printf(" Connect delay: %lu/-\n", val.val); + val = get_value(buf_read); + } + if (compare_buff_str(buf_read, val.val, "neighbor_id")) + { + buf_read->pt += val.val; + printf(" Neighbor ID: "); + printf(", %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("\n", buf_read->buff[buf_read->pt+i]); + } + 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); + val = get_value(buf_read); + printf(" Hold timer: "); + print_as_time(val.val); + printf("/"); + discard_key(buf_read); + val = get_value(buf_read); + printf("%lu\n", val.val); + + discard_key(buf_read); + val = get_value(buf_read); + printf(" Keepalive timer: "); + print_as_time(val.val); + printf("/"); + discard_key(buf_read); + val = get_value(buf_read); + printf("%lu\n", val.val); + } + if (compare_buff_str(buf_read, val.val, "last_err1")) + { + buf_read->pt += val.val; + printf(" Last error: "); + discard_key(buf_read); + print_with_size(&buf_read->buff[buf_read->pt], val.val); + printf(" "); + discard_key(buf_read); + print_with_size(&buf_read->buff[buf_read->pt], val.val); + printf("\n"); + val = get_value(buf_read); + } + + discard_key(buf_read); //channels + val = get_value(buf_read); //open list + val = get_value(buf_read); //open block + while (!val_is_break(val)) + { + discard_key(buf_read); //channel + val = get_value(buf_read); //open 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); + printf("\n"); + val = get_value(buf_read); + } + if (compare_buff_str(buf_read, val.val, "llstale_timer")) + { + buf_read->pt += val.val; + val = get_value(buf_read); + printf(" LL stale timer: "); + print_as_time(val.val); + 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); + printf("\n"); + val = get_value(buf_read); + } + if (compare_buff_str(buf_read, val.val, "igp_ipv4_table")) + { + buf_read->pt += val.val; + printf(" IGP IPv6 table: "); + print_with_size(&buf_read->buff[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: "); + print_with_size(&buf_read->buff[buf_read->pt], val.val); + printf("\n"); + val = get_value(buf_read); + } + val = get_value(buf_read); + } + val = get_value(buf_read); + printf("\n", val.major, val.val); +} + +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 + val = get_value(buf_read); + print_time(val.val); + 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); + } + 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", val.major, val.val); + 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); + printf("\n", val.major, val.val); + } +} + void print_cbor_response(byte *cbor, int len) { + // + 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; @@ -660,11 +1477,13 @@ void print_cbor_response(byte *cbor, int len) 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); } - - - diff --git a/nest/Makefile b/nest/Makefile index f600957f..e38c476a 100644 --- a/nest/Makefile +++ b/nest/Makefile @@ -1,4 +1,4 @@ -src := cbor.c cbor_shortcuts.c +src := cbor.c cbor_shortcuts.c cbor_parse_tools.c obj := $(src-o-files) $(all-client) diff --git a/nest/cbor.c b/nest/cbor.c index c4887643..ef2b7aa8 100644 --- a/nest/cbor.c +++ b/nest/cbor.c @@ -74,7 +74,7 @@ void cbor_add_ipv4(struct cbor_writer *writer, uint32_t addr) void cbor_add_ipv6(struct cbor_writer *writer, uint32_t addr[4]) { write_item(writer, 6, 54); // 6 is TAG, 54 is tag number for ipv6 - write_item(writer, 2, 16); // bytestring of length 8 + write_item(writer, 2, 16); // bytestring of length 16 for (int j = 0; j < 4; j++) { for (int i = 3; i>=0; i--) diff --git a/nest/cbor_cmds.c b/nest/cbor_cmds.c index 021b06ca..8806a0f6 100644 --- a/nest/cbor_cmds.c +++ b/nest/cbor_cmds.c @@ -10,6 +10,10 @@ #include "proto/ospf/ospf_for_cbor.c" +int64_t preprocess_time(btime t) { + return tm_get_real_time(t) TO_S ; +} + uint compare_byte_str(byte *str1, uint length, const char *str2) { if (length != strlen(str2)) { return 0; @@ -36,7 +40,7 @@ proto_state_name_stolen_for_cbor(struct proto *p) } } -void +uint cmd_show_protocols_cbor(byte *tbuf, uint capacity, struct arg_list *args, struct linpool *lp) { log("in cmd_show_protocols_cbor"); @@ -44,7 +48,7 @@ cmd_show_protocols_cbor(byte *tbuf, uint capacity, struct arg_list *args, struct cbor_open_block_with_length(w, 1); cbor_add_string(w, "show_protocols:message"); - cbor_open_block_with_length(w, 2); + cbor_open_block_with_length(w, 1); cbor_add_string(w, "table"); cbor_open_list(w); int all = 0; @@ -84,7 +88,7 @@ cmd_show_protocols_cbor(byte *tbuf, uint capacity, struct arg_list *args, struct if (p->message) cbor_string_string(w, "message", p->message); if (p->cf->router_id) - cbor_string_int(w, "router_id", p->cf->router_id); + cbor_string_ipv4(w, "router_id", p->cf->router_id); if (p->vrf_set) cbor_string_string(w, "vrf", p->vrf ? p->vrf->name : "default"); @@ -94,13 +98,15 @@ cmd_show_protocols_cbor(byte *tbuf, uint capacity, struct arg_list *args, struct { struct channel *c; WALK_LIST(c, p->channels) - channel_show_info(c); + channel_show_info_cbor(w, c); } } cbor_close_block_or_list(w); } } cbor_close_block_or_list(w); + cbor_write_to_file(w, "show_protocol_first_try.cbor"); + return w->pt; } extern pool *rt_table_pool; diff --git a/nest/cbor_parse.c b/nest/cbor_parse.c index d1717ec4..61d25058 100644 --- a/nest/cbor_parse.c +++ b/nest/cbor_parse.c @@ -1,99 +1,6 @@ #include "nest/cbor_cmds.c" +#include "nest/cbor_parse_tools.h" -enum functions { - SHOW_STATUS = 0, - SHOW_MEMORY = 1, - SHOW_SYMBOLS = 2, - SHOW_OSPF = 3, -}; - -enum cbor_majors { - UINT = 0, - NEG_INT = 1, - BYTE_STR = 2, - TEXT = 3, - ARRAY = 4, - BLOCK = 5, - TAG = 6, - FLOAT = 7, -}; - - -struct value { - int major; - int64_t val; -}; - -struct buff_reader { - byte *buff; - uint pt; - uint size; -}; - - -uint compare_buff_str(struct buff_reader *buf_read, uint length, char *string) { - if (length != strlen(string)) { - return 0; - } - for (size_t i = 0; i < strlen(string); i++) { - if (buf_read->buff[i+buf_read->pt]!=string[i]) { - return 0; - } - } - return 1; -}; - -struct value -get_value(struct buff_reader *reader) -{ - struct value val; - byte *buff = reader->buff; - val.major = buff[reader->pt]>>5; - int first_byte_val = buff[reader->pt] - (val.major<<5); - if (first_byte_val <=23) { - val.val = first_byte_val; - reader->pt++; - } else if (first_byte_val == 0x18) - { - val.val = buff[reader->pt+1]; - reader->pt+=2; - } else if (first_byte_val == 0x19) - { - val.val = buff[reader->pt+1]; - val.val = val.val << 8; - val.val += buff[reader->pt+2]; - reader->pt += 3; - } else if (first_byte_val == 0x1a) - { - val.val = 0; - for (int i = 1; i < 4; i++) - { - val.val += buff[reader->pt+i]; - val.val = val.val << 8; - } - val.val += buff[reader->pt+4]; - reader->pt+=5; - } else if (first_byte_val == 0x1b) - { - for(int i = 1; i < 8; i++) { - val.val += buff[reader->pt+i]; - val.val = val.val << 8; - } - val.val += buff[reader->pt+8]; - reader->pt+=9; - } else if (first_byte_val == 0x1f) - { - val.val = -1; - reader->pt++; - } - return val; -} - - -int val_is_break(struct value val) -{ - return val.major == FLOAT && val.val == -1; // break code is 0xff, so the major is same for float and break -} void skip_optional_args(struct buff_reader *rbuf_read, int items_in_block) { @@ -232,6 +139,10 @@ do_command(struct buff_reader *rbuf_read, struct buff_reader *tbuf_read, int ite 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); + 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); default: bug("command %li not found", val.val); return 0; diff --git a/nest/cbor_shortcuts.c b/nest/cbor_shortcuts.c index 0e73f34c..cdf82549 100644 --- a/nest/cbor_shortcuts.c +++ b/nest/cbor_shortcuts.c @@ -4,9 +4,6 @@ #include "nest/cbor_shortcuts.h" -int64_t preprocess_time(btime t) { - return tm_get_real_time(t) TO_S ; -} void cbor_string_string(struct cbor_writer *writer, char *key, const char *value) { cbor_add_string(writer, key); @@ -23,6 +20,18 @@ void cbor_string_uint(struct cbor_writer *writer, char *key, u64 value) { cbor_add_uint(writer, value); } +void cbor_string_ip(struct cbor_writer *writer, char *key, ip_addr addr) { + cbor_add_string(writer, key); + if (ipa_is_ip4(addr)) + { + cbor_add_ipv4(writer, ipa_to_ip4(addr).addr); + } + else + { + cbor_add_ipv6(writer, addr.addr); + } +} + void cbor_string_ipv4(struct cbor_writer *writer, char *key, u32 value) { cbor_add_string(writer, key); cbor_add_ipv4(writer, value); diff --git a/nest/cbor_shortcuts.h b/nest/cbor_shortcuts.h index bd9168d8..6e4b8102 100644 --- a/nest/cbor_shortcuts.h +++ b/nest/cbor_shortcuts.h @@ -7,13 +7,13 @@ #include "nest/protocol.h" #include "lib/ip.h" -int64_t preprocess_time(btime t); void cbor_string_string(struct cbor_writer *writer, char *key, const char *value); void cbor_string_int(struct cbor_writer *writer, char *key, int64_t value); void cbor_string_uint(struct cbor_writer *writer, char *key, u64 value); +void cbor_string_ip(struct cbor_writer *writer, char *key, ip_addr addr); void cbor_string_ipv4(struct cbor_writer *writer, char *key, u32 value); void cbor_string_ipv6(struct cbor_writer *writer, char *key, u32 value[4]); void cbor_named_block_two_ints(struct cbor_writer *writer, char *key, char *name1, int val1, char *name2, int val2); diff --git a/nest/proto.c b/nest/proto.c index ccb19bfe..035315b1 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -2144,6 +2144,7 @@ channel_show_info_cbor(struct cbor_writer *w, struct channel *c) cbor_open_block(w); cbor_string_string(w, "name", c->name); cbor_string_string(w, "state", c_states[c->channel_state]); + cbor_string_string(w, "table", c->table->name); cbor_string_int(w, "preference", c->preference); cbor_string_string(w, "input_filter", filter_name(c->in_filter)); cbor_string_string(w, "output_filter", filter_name(c->out_filter)); @@ -2160,6 +2161,7 @@ channel_show_info_cbor(struct cbor_writer *w, struct channel *c) if (c->channel_state != CS_DOWN) channel_show_stats_cbor(w, c); + cbor_close_block_or_list(w); } void diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 0d61ee4f..e1b12d8b 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -2573,7 +2573,6 @@ bgp_show_capabilities(struct bgp_proto *p UNUSED, struct bgp_caps *caps) static void bgp_show_capabilities_cbor(struct cbor_writer *w, struct bgp_proto *p UNUSED, struct bgp_caps *caps) { - cbor_add_string(w, "capabilities"); cbor_open_block(w); struct bgp_af_caps *ac; uint any_mp_bgp = 0; @@ -2596,16 +2595,12 @@ bgp_show_capabilities_cbor(struct cbor_writer *w, struct bgp_proto *p UNUSED, st if (any_mp_bgp) { - cbor_add_string(w, "multiprotocol"); - cbor_open_block(w); - afn1 = 0; WALK_AF_CAPS(caps, ac) if (ac->ready) afl1[afn1++] = ac->afi; - bgp_show_afis_cbor(w, "AF_announced:", afl1, afn1); - cbor_close_block_or_list(w); + bgp_show_afis_cbor(w, "AF_announced", afl1, afn1); } if (caps->route_refresh) @@ -2621,7 +2616,7 @@ bgp_show_capabilities_cbor(struct cbor_writer *w, struct bgp_proto *p UNUSED, st if (ac->ext_next_hop) afl1[afn1++] = ac->afi; - bgp_show_afis_cbor(w, "IPv6_nexthop:", afl1, afn1); + bgp_show_afis_cbor(w, "IPv6_nexthop", afl1, afn1); } if (caps->ext_messages) @@ -2661,15 +2656,13 @@ bgp_show_capabilities_cbor(struct cbor_writer *w, struct bgp_proto *p UNUSED, st } if (caps->as4_support) - { + { cbor_add_string(w, "4-octet_AS_numbers"); cbor_open_list_with_length(w, 0); } if (any_add_path) { - cli_msg(-1006, " ADD-PATH"); - afn1 = afn2 = 0; WALK_AF_CAPS(caps, ac) { @@ -2858,8 +2851,11 @@ bgp_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) } else { - cbor_string_ipv4(w, "neighbor_addr", *p->remote_ip.addr); - cbor_string_string(w, "iface", p->cf->iface->name); + cbor_string_ip(w, "neighbor_addr", p->remote_ip); + if (p->cf->iface) + cbor_string_string(w, "iface", p->cf->iface->name); + else + cbor_string_string(w, "iface", ""); } if ((p->conn == &p->outgoing_conn) && (p->cf->remote_port != BGP_PORT)) @@ -2899,13 +2895,10 @@ bgp_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) { cbor_add_string(w, "neighbor_id"); cbor_add_ipv4(w, p->remote_id); - cli_msg(-1006, " Local capabilities"); cbor_add_string(w, "local_cap"); - cbor_open_block_with_length(w, 1); bgp_show_capabilities_cbor(w, p, p->conn->local_caps); cbor_add_string(w, "neighbor_cap"); - cbor_open_block_with_length(w, 1); - bgp_show_capabilities(p, p->conn->remote_caps); + bgp_show_capabilities_cbor(w, p, p->conn->remote_caps); cbor_add_string(w, "session"); cbor_open_list(w); @@ -2923,8 +2916,7 @@ bgp_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) cbor_add_string(w, "AS4"); cbor_close_block_or_list(w); - cbor_add_string(w, "source_address"); - cbor_add_ipv6(w, p->local_ip.addr); + cbor_string_ip(w, "source_address", p->local_ip); cbor_string_int(w, "hold_timer", tm_remains(p->conn->hold_timer)); cbor_string_int(w, "hold_t_base", p->conn->hold_time); @@ -2938,19 +2930,24 @@ bgp_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) { const char *err1 = bgp_err_classes[p->last_error_class]; const char *err2 = bgp_last_errmsg(p); - cli_msg(-1006, " Last error: %s%s", err1, err2); + cbor_string_string(w, "last_err1", err1); + cbor_string_string(w, "last_err2", err2); } { struct bgp_channel *c; cbor_add_string(w, "channels"); - cbor_open_block(w); + cbor_open_list(w); WALK_LIST(c, p->p.channels) { + cbor_open_block(w); channel_show_info_cbor(w, &c->c); if (c->c.channel != &channel_bgp) + { + cbor_close_block_or_list(w); continue; + } if (p->gr_active_num) cbor_string_string(w, "neighbor_gr", bgp_gr_states[c->gr_active]); @@ -2962,15 +2959,12 @@ bgp_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) { if (ipa_zero(c->link_addr)) { - cbor_add_string(w, "next_hop"); - cbor_add_ipv6(w, c->next_hop_addr.addr); + cbor_string_ip(w, "next_hop", c->next_hop_addr); } else { - cbor_add_string(w, "next_hop1"); - cbor_add_ipv6(w, c->next_hop_addr.addr); - cbor_add_string(w, "next_hop2"); - cbor_add_ipv6(w, c->link_addr.addr); + cbor_string_ip(w, "next_hop1", c->next_hop_addr); + cbor_string_ip(w, "next_hop2", c->link_addr); } } @@ -2982,6 +2976,7 @@ bgp_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) if (c->base_table) cbor_string_string(w, "base_table", c->base_table->name); + cbor_close_block_or_list(w); } cbor_close_block_or_list(w); } diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index 35452c18..6674e76a 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -898,7 +898,7 @@ rpki_show_proto_info_timer_cbor(struct cbor_writer *w, const char *name, uint nu cbor_open_block(w); if (tm_active(t)) { - cbor_string_int(w, "time", preprocess_time(tm_remains(t))); + cbor_string_int(w, "time", tm_get_real_time(tm_remains(t)) TO_S); cbor_string_int(w, "num", num); } cbor_close_block_or_list(w); @@ -943,7 +943,7 @@ rpki_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) cbor_string_string(w, "status", rpki_cache_state_to_str(cache->state)); cbor_string_string(w, "transport", transport_name); - cbor_string_int(w, "cache_version", cache->version); + cbor_string_int(w, "protocol_version", cache->version); if (cache->request_session_id) cbor_string_string(w, "session_id", "-"); @@ -953,7 +953,7 @@ rpki_show_proto_info_cbor(struct cbor_writer *w, struct proto *P) if (cache->last_update) { cbor_string_int(w, "serial_num", cache->serial_num); - cbor_string_int(w, "last_update", preprocess_time(current_time() - cache->last_update)); + cbor_string_int(w, "last_update", tm_get_real_time(current_time() - cache->last_update) TO_S); } rpki_show_proto_info_timer_cbor(w, "Refresh timer", cache->refresh_interval, cache->refresh_timer); diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index a3bd8224..8df74bc7 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -991,8 +991,8 @@ main(int argc, char **argv) if (!parse_and_exit) { test_old_bird(path_control_socket); - cli_init_unix(use_uid, use_gid); - /*if (path_control_socket_yi) + //cli_init_unix(use_uid, use_gid); + if (path_control_socket_yi) { yi_init_unix(use_uid, use_gid); } @@ -1000,7 +1000,7 @@ main(int argc, char **argv) path_control_socket_yi = "bird.ctl"; log(L_INFO "before function"); yi_init_unix(use_uid, use_gid); - }*/ + } } if (use_gid)