diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2004-01-04 17:55:20 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2004-01-04 17:55:20 +0000 |
commit | 3c4eeacbd5b8a4df31f4e22bb61675044158048f (patch) | |
tree | 16ec37d08f4f3dfe35fb823c1dd22cf2cd871f95 /usr.sbin/bgpctl | |
parent | 8f6a17ac45764584f68bf4aae33935782f9625b3 (diff) |
add infrastructure for command line parsing
to test that i had to add a "show neighbor" view...
Diffstat (limited to 'usr.sbin/bgpctl')
-rw-r--r-- | usr.sbin/bgpctl/bgpctl.c | 134 |
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); } |