summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-01-04 17:55:20 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-01-04 17:55:20 +0000
commit3c4eeacbd5b8a4df31f4e22bb61675044158048f (patch)
tree16ec37d08f4f3dfe35fb823c1dd22cf2cd871f95 /usr.sbin
parent8f6a17ac45764584f68bf4aae33935782f9625b3 (diff)
add infrastructure for command line parsing
to test that i had to add a "show neighbor" view...
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpctl/bgpctl.c134
1 files changed, 117 insertions, 17 deletions
diff --git a/usr.sbin/bgpctl/bgpctl.c b/usr.sbin/bgpctl/bgpctl.c
index 0338f81bc16..4677c491b73 100644
--- a/usr.sbin/bgpctl/bgpctl.c
+++ b/usr.sbin/bgpctl/bgpctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bgpctl.c,v 1.9 2004/01/04 02:51:24 henning Exp $ */
+/* $OpenBSD: bgpctl.c,v 1.10 2004/01/04 17:55:19 henning Exp $ */
/*
* Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
@@ -28,24 +28,42 @@
#include "session.h"
#include "log.h"
+enum actions {
+ SHOW,
+ SHOW_SUMMARY,
+ SHOW_NEIGHBOR
+};
+
+struct keywords {
+ const char *keyword;
+ int value;
+};
+
+static const struct keywords keywords_main[] = {
+ { "show", SHOW}
+};
+
+static const struct keywords keywords_show[] = {
+ { "neighbor", SHOW_NEIGHBOR},
+ { "summary", SHOW_SUMMARY}
+};
+
int main(int, char *[]);
-void summary_head(void);
-int summary_msg(struct imsg *);
+int match_keyword(const char *, const struct keywords [], size_t);
+void show_summary_head(void);
+int show_summary_msg(struct imsg *);
+int show_neighbor_msg(struct imsg *);
static char *fmt_timeframe(time_t t);
struct imsgbuf ibuf;
-enum views {
- VIEW_SUMMARY
-};
-
int
main(int argc, char *argv[])
{
struct sockaddr_un sun;
int fd, n, done;
struct imsg imsg;
- enum views view = VIEW_SUMMARY;
+ enum actions action = SHOW_SUMMARY;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
err(1, "control_init: socket");
@@ -63,10 +81,29 @@ main(int argc, char *argv[])
imsg_init(&ibuf, fd);
done = 0;
- switch (view) {
- case VIEW_SUMMARY:
+ if (argc >= 2)
+ action = match_keyword(argv[1], keywords_main,
+ sizeof(keywords_main)/sizeof(keywords_main[0]));
+
+again:
+ switch (action) {
+ case SHOW:
+ if (argc >= 3) {
+ action = match_keyword(argv[2], keywords_show,
+ sizeof(keywords_show)/sizeof(keywords_show[0]));
+ goto again;
+ }
+ /* fallthrough */
+ case SHOW_SUMMARY:
+ if (argc >= 4)
+ errx(1, "\"show summary\" does not take arguments");
imsg_compose(&ibuf, IMSG_CTL_SHOW_NEIGHBOR, 0, NULL, 0);
- summary_head();
+ show_summary_head();
+ break;
+ case SHOW_NEIGHBOR:
+ /* get ip address of neighbor, limit query to that */
+ imsg_compose(&ibuf, IMSG_CTL_SHOW_NEIGHBOR, 0, NULL, 0);
+ break;
}
while (!done) {
@@ -82,9 +119,14 @@ main(int argc, char *argv[])
done = 1;
break;
}
- switch (view) {
- case VIEW_SUMMARY:
- done = summary_msg(&imsg);
+ switch (action) {
+ case SHOW:
+ case SHOW_SUMMARY:
+ done = show_summary_msg(&imsg);
+ break;
+ case SHOW_NEIGHBOR:
+ done = show_neighbor_msg(&imsg);
+ break;
}
imsg_free(&imsg);
}
@@ -92,15 +134,37 @@ main(int argc, char *argv[])
close(fd);
}
+int
+match_keyword(const char *word, const struct keywords table[], size_t cnt)
+{
+ u_int match, res, i;
+
+ match = res = 0;
+
+ for (i = 0; i < cnt; i++)
+ if (strncmp(word, table[i].keyword,
+ strlen(word)) == 0) {
+ match++;
+ res = table[i].value;
+ }
+
+ if (match > 1)
+ errx(1, "ambigous command: %s", word);
+ if (match < 1)
+ errx(1, "unknown command: %s", word);
+
+ return (res);
+}
+
void
-summary_head(void)
+show_summary_head(void)
{
printf("%-15s %-5s %-10s %-10s %-8s %s\n", "Neighbor", "AS", "MsgRcvd",
"MsgSent", "Up/Down", "State");
}
int
-summary_msg(struct imsg *imsg)
+show_summary_msg(struct imsg *imsg)
{
struct peer *p;
@@ -123,6 +187,42 @@ summary_msg(struct imsg *imsg)
return (0);
}
+int
+show_neighbor_msg(struct imsg *imsg)
+{
+ struct peer *p;
+
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_NEIGHBOR:
+ p = imsg->data;
+ printf("BGP neighbor is %s, remote AS %u\n",
+ inet_ntoa(p->conf.remote_addr.sin_addr),
+ p->conf.remote_as);
+ if (p->conf.descr[0])
+ printf(" Description: %s\n", p->conf.descr);
+ printf(" BGP version 4, remote router-id %s\n",
+ log_ntoa(p->remote_bgpid));
+ printf(" BGP state = %s", statenames[p->state]);
+ if (p->stats.last_updown != 0)
+ printf(", %s for %s",
+ p->state == STATE_ESTABLISHED ? "up" : "down",
+ fmt_timeframe(p->stats.last_updown));
+ printf("\n");
+ printf(" Last read %s, holdtime %us, keepalive interval %us\n",
+ fmt_timeframe(p->stats.last_read),
+ p->holdtime, p->holdtime/3);
+ printf("\n");
+ break;
+ case IMSG_CTL_END:
+ return (1);
+ break;
+ default:
+ break;
+ }
+
+ return (0);
+}
+
#define TF_BUFS 8
#define TF_LEN 9
@@ -139,7 +239,7 @@ fmt_timeframe(time_t t)
idx = 0;
if (t == 0) {
- snprintf(buf, TF_LEN, "%-8s", "Never");
+ snprintf(buf, TF_LEN, "%s", "Never");
return (buf);
}