summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_btoa.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_btoa.c')
-rw-r--r--bgpd/bgp_btoa.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/bgpd/bgp_btoa.c b/bgpd/bgp_btoa.c
new file mode 100644
index 0000000..8e27d97
--- /dev/null
+++ b/bgpd/bgp_btoa.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* BGP dump to ascii converter
+ * Copyright (C) 1999 Kunihiro Ishiguro
+ */
+
+#include <zebra.h>
+
+#include "zebra.h"
+#include "stream.h"
+#include "log.h"
+#include "prefix.h"
+#include "command.h"
+#include "memory.h"
+#include "privs.h"
+#include "filter.h"
+
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_dump.h"
+#include "bgpd/bgp_attr.h"
+#include "bgpd/bgp_aspath.h"
+
+/* privileges */
+static zebra_capabilities_t _caps_p[] = {
+ ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN,
+};
+
+struct zebra_privs_t bgpd_privs = {
+#if defined(FRR_USER) && defined(FRR_GROUP)
+ .user = FRR_USER,
+ .group = FRR_GROUP,
+#endif
+#ifdef VTY_GROUP
+ .vty_group = VTY_GROUP,
+#endif
+ .caps_p = _caps_p,
+ .cap_num_p = array_size(_caps_p),
+ .cap_num_i = 0,
+};
+
+enum MRT_MSG_TYPES {
+ MSG_NULL,
+ MSG_START, /* sender is starting up */
+ MSG_DIE, /* receiver should shut down */
+ MSG_I_AM_DEAD, /* sender is shutting down */
+ MSG_PEER_DOWN, /* sender's peer is down */
+ MSG_PROTOCOL_BGP, /* msg is a BGP packet */
+ MSG_PROTOCOL_RIP, /* msg is a RIP packet */
+ MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */
+ MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */
+ MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */
+ MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */
+ MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */
+ MSG_TABLE_DUMP /* routing table dump */
+};
+
+static void attr_parse(struct stream *s, uint16_t len)
+{
+ unsigned int flag;
+ unsigned int type;
+ uint16_t length;
+ uint16_t lim;
+
+ lim = s->getp + len;
+
+ printf("%s s->getp %zd, len %d, lim %d\n", __func__, s->getp, len, lim);
+
+ while (s->getp < lim) {
+ flag = stream_getc(s);
+ type = stream_getc(s);
+
+ if (flag & BGP_ATTR_FLAG_EXTLEN)
+ length = stream_getw(s);
+ else
+ length = stream_getc(s);
+
+ printf("FLAG: %d\n", flag);
+ printf("TYPE: %d\n", type);
+ printf("Len: %d\n", length);
+
+ switch (type) {
+ case BGP_ATTR_ORIGIN: {
+ uint8_t origin;
+ origin = stream_getc(s);
+ printf("ORIGIN: %d\n", origin);
+ } break;
+ case BGP_ATTR_AS_PATH: {
+ struct aspath *aspath;
+
+ aspath = aspath_parse(s, length, 1,
+ bgp_get_asnotation(NULL));
+ printf("ASPATH: %s\n", aspath->str);
+ aspath_free(aspath);
+ } break;
+ case BGP_ATTR_NEXT_HOP: {
+ struct in_addr nexthop;
+ nexthop.s_addr = stream_get_ipv4(s);
+ printf("NEXTHOP: %pI4\n", &nexthop);
+ } break;
+ default:
+ stream_getw_from(s, length);
+ break;
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ int fd;
+ struct stream *s;
+ time_t now;
+ int type;
+ int subtype;
+ size_t len;
+ int source_as;
+ int dest_as;
+ ifindex_t ifindex;
+ int family;
+ struct in_addr sip;
+ struct in_addr dip;
+ uint16_t viewno, seq_num;
+ struct prefix_ipv4 p;
+ char tbuf[32];
+
+ s = stream_new(10000);
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
+ exit(1);
+ }
+ fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+ fprintf(stdout,
+ "%% Can't open configuration file %s due to '%s'.\n",
+ argv[1], safe_strerror(errno));
+ exit(1);
+ }
+
+ while (1) {
+ stream_reset(s);
+
+ ret = stream_read(s, fd, 12);
+ if (ret != 12) {
+ if (!ret)
+ printf("END OF FILE\n");
+ else if (ret < 0)
+ printf("ERROR OF READ\n");
+ else
+ printf("UNDERFLOW\n");
+ break;
+ }
+
+ /* Extract header. */
+ now = stream_getl(s);
+ type = stream_getw(s);
+ subtype = stream_getw(s);
+ len = stream_getl(s);
+
+ printf("TIME: %s", ctime_r(&now, tbuf));
+
+ /* printf ("TYPE: %d/%d\n", type, subtype); */
+
+ if (type == MSG_PROTOCOL_BGP4MP)
+ printf("TYPE: BGP4MP");
+ else if (type == MSG_PROTOCOL_BGP4MP_ET)
+ printf("TYPE: BGP4MP_ET");
+ else if (type == MSG_TABLE_DUMP)
+ printf("TYPE: MSG_TABLE_DUMP");
+ else
+ printf("TYPE: Unknown %d", type);
+
+ if (type == MSG_TABLE_DUMP)
+ switch (subtype) {
+ case AFI_IP:
+ printf("/AFI_IP\n");
+ break;
+ case AFI_IP6:
+ printf("/AFI_IP6\n");
+ break;
+ default:
+ printf("/UNKNOWN %d", subtype);
+ break;
+ }
+ else {
+ switch (subtype) {
+ case BGP4MP_STATE_CHANGE:
+ printf("/CHANGE\n");
+ break;
+ case BGP4MP_MESSAGE:
+ printf("/MESSAGE\n");
+ break;
+ case BGP4MP_ENTRY:
+ printf("/ENTRY\n");
+ break;
+ case BGP4MP_SNAPSHOT:
+ printf("/SNAPSHOT\n");
+ break;
+ default:
+ printf("/UNKNOWN %d", subtype);
+ break;
+ }
+ }
+
+ printf("len: %zd\n", len);
+
+ ret = stream_read(s, fd, len);
+ if (ret != (int)len) {
+ if (!ret)
+ printf("END OF FILE 2\n");
+ else if (ret < 0)
+ printf("ERROR OF READ 2\n");
+ else
+ printf("UNDERFLOW 2\n");
+ break;
+ }
+
+ /* printf ("now read %d\n", len); */
+
+ if (type == MSG_TABLE_DUMP) {
+ uint8_t status;
+ time_t originated;
+ struct in_addr peer;
+ uint16_t attrlen;
+
+ viewno = stream_getw(s);
+ seq_num = stream_getw(s);
+ printf("VIEW: %d\n", viewno);
+ printf("SEQUENCE: %d\n", seq_num);
+
+ /* start */
+ while (s->getp < len - 16) {
+ p.prefix.s_addr = stream_get_ipv4(s);
+ p.prefixlen = stream_getc(s);
+ printf("PREFIX: %pI4/%d\n", &p.prefix,
+ p.prefixlen);
+
+ status = stream_getc(s);
+ originated = stream_getl(s);
+ peer.s_addr = stream_get_ipv4(s);
+ source_as = stream_getw(s);
+
+ printf("FROM: %pI4 AS%d\n", &peer, source_as);
+ printf("ORIGINATED: %s", ctime_r(&originated,
+ tbuf));
+
+ attrlen = stream_getw(s);
+ printf("ATTRLEN: %d\n", attrlen);
+
+ attr_parse(s, attrlen);
+
+ printf("STATUS: 0x%x\n", status);
+ }
+ } else {
+ source_as = stream_getw(s);
+ dest_as = stream_getw(s);
+ printf("source_as: %d\n", source_as);
+ printf("dest_as: %d\n", dest_as);
+
+ ifindex = stream_getw(s);
+ family = stream_getw(s);
+
+ printf("ifindex: %d\n", ifindex);
+ printf("family: %d\n", family);
+
+ sip.s_addr = stream_get_ipv4(s);
+ dip.s_addr = stream_get_ipv4(s);
+
+ printf("saddr: %pI4\n", &sip);
+ printf("daddr: %pI4\n", &dip);
+
+ printf("\n");
+ }
+ }
+ close(fd);
+ return 0;
+}