commit - 2cbf96e394f7a7decbae2f8a6829b8cddd03536b
commit + f943f99c53a154c97b93aaff0c6147d40bd8de82
blob - cb93dae29f883f57ee923b60a332edcaf8749fa6
blob + d0ea33ff297130b499703d8f068c954783abcdb3
--- Makefile
+++ Makefile
#
PROG= nsh
+SUBDIR += bgpnsh
+
.PHONY: release dist
.include "nsh-version.mk"
CFLAGS+=-Wmissing-prototypes -Wformat -Wall -Wbad-function-cast -I/usr/local/include #-W -Wpointer-arith
CPPFLAGS+=-DNSH_VERSION=${NSH_VERSION} -DNSH_REXEC_PATH=${NSH_REXEC_PATH}
-SRCS=arp.c compile.c main.c genget.c commands.c stats.c kroute.c
+SRCS=arp.c compile.c main.c genget.c commands.c bgpcommands.c stats.c kroute.c
SRCS+=ctl.c show.c if.c version.c route.c conf.c complete.c ieee80211.c
SRCS+=bridge.c tunnel.c media.c sysctl.c passwd.c pfsync.c carp.c
-SRCS+=trunk.c who.c more.c stringlist.c utils.c sqlite3.c ppp.c
-SRCS+=nopt.c pflow.c wg.c nameserver.c ndp.c umb.c utf8.c
+SRCS+=trunk.c who.c more.c stringlist.c utils.c sqlite3.c ppp.c prompt.c
+SRCS+=nopt.c pflow.c wg.c nameserver.c ndp.c umb.c utf8.c cmdargs.c ctlargs.c
+SRCS+=helpcommands.c makeargv.c
CLEANFILES+=compile.c
LDADD=-lutil -ledit -ltermcap -lsqlite3 -L/usr/local/lib #-static
rm ${.CURDIR}/nsh-dist.txt.new
.include <bsd.prog.mk>
+.include <bsd.subdir.mk>
blob - /dev/null
blob + 1f466aefdc939449c3b12b9646e9c5a6a53a1353 (mode 644)
--- /dev/null
+++ bgpcommands.c
+/*
+ * Copyright (c) 2008-2009 Chris Cappuccio <chris@nmedia.net>
+ * Copyright (c) 2023 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h> /* MAXHOSTNAMELEN */
+#include <net/if.h> /* IFNAMSIZ */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+
+#include "externs.h"
+#include "commands.h"
+#include "ctl.h"
+
+char bgpd_socket_path[PATH_MAX];
+
+#define BGPSOCK "-s", bgpd_socket_path
+
+struct prot1 bgcs[] = {
+ { "announced", "All announced networks",
+ { BGPCTL, BGPSOCK, "network", "show", OPT, NULL } },
+ { "interfaces", "Interface states",
+ { BGPCTL, BGPSOCK, "show", "interfaces", NULL } },
+ { "nexthop", "BGP nexthop routes",
+ { BGPCTL, BGPSOCK, "show", "nexthop", NULL } },
+ { "summary", "Neighbor session states and counters",
+ { BGPCTL, BGPSOCK, "show", "summary", OPT, NULL } },
+ { "rib", "Routing Information Base",
+ { BGPCTL, BGPSOCK, "show", "rib", OPT, OPT, OPT, NULL } },
+ { "neighbor", "Detailed peer",
+ { BGPCTL, BGPSOCK, "show", "neighbor", REQ, OPT, NULL } },
+ { "ip", "IP BGP",
+ { BGPCTL, BGPSOCK, "show", "ip", "bgp", OPT, OPT, OPT, NULL } },
+ { 0, 0, { 0 } }
+};
+
+/* Initialize the globally stored BGPD socket path. */
+void
+init_bgpd_socket_path(int rtable)
+{
+ snprintf(bgpd_socket_path, sizeof(bgpd_socket_path),
+ "%s.%d", BGPD_SOCKET_PATH, rtable);
+}
blob - /dev/null
blob + 66fa671ac5ac8390f2891dc49b5bc3f1b2b477f3 (mode 644)
--- /dev/null
+++ bgpnsh/.gitignore
+obj/**
blob - /dev/null
blob + d4f2f7232f6db50ce16ca840c67378a609085eb5 (mode 644)
--- /dev/null
+++ bgpnsh/Makefile
+#
+PROG= bgpnsh
+
+.PATH=${.CURDIR}/..
+
+.include "../nsh-version.mk"
+
+.if ${NSH_RELEASE} != Yes
+DEBUG?=-O0 -g
+.endif
+
+.if make(install)
+DESTDIR?=/usr/local
+BINDIR?=/bin
+MANDIR?=/man/man
+.endif
+
+CFLAGS+=-Wmissing-prototypes -Wformat -Wall -Wbad-function-cast
+CPPFLAGS+=-DNSH_VERSION=${NSH_VERSION}
+
+SRCS=bgpnsh.c compile.c bgpcommands.c complete.c genget.c more.c \
+ stringlist.c utf8.c stubs.c cmdargs.c ctlargs.c prompt.c \
+ helpcommands.c makeargv.c
+CLEANFILES+=compile.c
+LDADD=-lutil -ledit -ltermcap
+
+MAN=bgpnsh.8
+
+compile.c: compile.sh
+ sh ${.CURDIR}/../compile.sh
+
+.include <bsd.prog.mk>
blob - /dev/null
blob + 526a5088941e553ced275539ec25a922a24d03d6 (mode 644)
--- /dev/null
+++ bgpnsh/bgpnsh.8
+
+.\" Copyright (c) 2023 Stefan Sperling
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate$
+.Dt BGPNSH 1
+.Os
+.Sh NAME
+.Nm bgpnsh
+.Nd BGP Looking Glass Network Shell
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+.Nm
+is a command interpreter intended for interactive use as a BGP
+Looking Glass shell for routers running
+.Xr bgpd 8 .
+.Pp
+.Nm
+is an alternative to
+.Xr bgplgsh 1
+with a user interface that matches the user interface of
+.Xr nsh 8 .
+.Pp
+All functionality of
+.Nm
+is also available in
+.Xr nsh 8 .
+Unlike
+.Xr nsh 8 ,
+.Nm
+restricts users to commands which obtain BGP routing information for
+diagnostic purposes.
+.Pp
+.Nm
+will usually be configured as the login shell for dedicated user accounts
+which are used to obtain BGP routing information from the system.
+See
+.Xr shells 5
+for more information.
+.Sh ENVIRONMENT
+.Bl -tag -width BGPNSH_SOCKET
+.It Ev BGPNSH_SOCKET
+Sets an alternative path to the restricted control socket of
+.Xr bgpd 8 .
+The default path is
+.Pa /var/www/run/bgpd.rsock .
+.Sh SEE ALSO
+.Xr bgplgsh 1 ,
+.Xr shells 5 ,
+.Xr bgpd 8 ,
+.Xr bgplg 8 ,
+.Xr nsh 8
blob - /dev/null
blob + fe3730444452dde0891c8c67fdb741b605e6f00c (mode 644)
--- /dev/null
+++ bgpnsh/bgpnsh.c
+/*
+ * Copyright (c) 2023 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h> /* MAXHOSTNAMELEN */
+#include <net/if.h> /* IFNAMSIZ */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include "../externs.h"
+#include "../editing.h"
+#include "../commands.h"
+#include "../ctl.h"
+
+#define BGPNSH_SOCKET "/var/www/run/bgpd.rsock" /* restricted socket */
+
+History *histc = NULL;
+History *histi = NULL;
+HistEvent ev;
+EditLine *elc = NULL;
+EditLine *eli = NULL;
+EditLine *elp = NULL;
+char *cursor_pos = NULL;
+
+pid_t child;
+
+void sigalarm(int signo)
+{
+ if (child != -1) {
+ kill(child, SIGKILL);
+ }
+}
+
+int editing = 1, config_mode = 0;
+int cli_rtable;
+int bridge;
+size_t Intlist_nitems = 0, Bridgelist_nitems = 0;
+int priv;
+
+char hbuf[MAXHOSTNAMELEN]; /* host name */
+char ifname[IFNAMSIZ]; /* interface name */
+
+struct intlist *whichlist;
+
+extern struct prot1 bgcs[];
+
+struct prot prots[] = {
+ { "bgp", bgcs },
+};
+
+Menu showlist[] = {
+ { "bgp", "BGP information",
+ CMPL(ta) (char **)bgcs, sizeof(struct prot1), 0, 4, pr_prot1 },
+ { 0, 0, 0, 0, 0 }
+};
+
+static int
+showcmd(int argc, char **argv)
+{
+ Menu *s; /* pointer to current command */
+
+ if (argc < 2) {
+ show_help(argc, argv);
+ return 0;
+ }
+
+ /*
+ * Validate show argument
+ */
+ s = (Menu *) genget(argv[1], (char **) showlist, sizeof(Menu));
+ if (s == 0) {
+ printf("%% Invalid argument %s\n", argv[1]);
+ return 0;
+ } else if (Ambiguous(s)) {
+ printf("%% Ambiguous argument %s\n", argv[1]);
+ return 0;
+ }
+ if (((s->minarg + 2) > argc) || ((s->maxarg + 2) < argc)) {
+ printf("%% Wrong number of argument%s to 'show %s' command"
+ " (min %i, max %i)\n", argc <= 2 ? "" : "s", s->name,
+ s->minarg, s->maxarg);
+ return 0;
+ }
+
+ (*s->handler)(argc, argv, NULL);
+ return 0;
+}
+
+int
+quit(void)
+{
+ printf("%% Session terminated.\n");
+ exit(0);
+ return 0;
+}
+
+Command cmdtab[] = {
+ { "show", "Show system information",
+ CMPL(ta) (char **)showlist, sizeof(Menu), showcmd, 0, 0, 0, 0 },
+ { "quit", "Close current connection",
+ CMPL0 0, 0, quit, 0, 0, 0, 0 },
+ { "help", 0,
+ CMPL(c) 0, 0, help, 0, 0, 0, 0 },
+ { 0, 0, CMPL0 0, 0, 0, 0, 0, 0, 0 }
+};
+size_t cmdtab_nitems = nitems(cmdtab);
+
+Command *
+getcmd(char *name)
+{
+ Command *cm;
+
+ cm = (Command *) genget(name, (char **) cmdtab, sizeof(Command));
+ return cm;
+}
+
+void
+command(void)
+{
+ Command *c;
+ u_int num;
+
+ for (;;) {
+ const char *buf;
+ cursor_pos = NULL;
+
+ if ((buf = el_gets(elc, &num)) == NULL || num == 0)
+ break;
+
+ if (buf[--num] == '\n') {
+ if (num == 0)
+ break;
+ }
+ if (num >= sizeof(line)) {
+ printf("%% Input exceeds permitted length\n");
+ break;
+ }
+ memcpy(line, buf, (size_t)num);
+ line[num] = '\0';
+ history(histc, &ev, H_ENTER, buf);
+
+ if (line[0] == 0)
+ break;
+ makeargv();
+ if (margv[0] == 0) {
+ break;
+ }
+
+ c = getcmd(margv[0]);
+ if (Ambiguous(c)) {
+ printf("%% Ambiguous command\n");
+ continue;
+ }
+ if (c == 0) {
+ int val = el_burrito(elc, margc, margv);
+ if (val)
+ printf("%% Invalid command\n");
+ continue;
+ }
+ if (NO_ARG(margv[0]) && ! c->nocmd) {
+ printf("%% Invalid command: %s %s\n", margv[0],
+ margv[1]);
+ continue;
+ }
+
+ if ((*c->handler) (margc, margv, 0))
+ break;
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *socket_path;
+
+ if (argc != 1) {
+ fprintf(stderr, "usage: %s\n", getprogname());
+ return 1;
+ }
+
+ inithist();
+ initedit();
+
+ if (unveil(BGPCTL, "x") == -1)
+ err(1, "unveil %s", BGPCTL);
+
+ if (unveil(NULL, NULL) == -1)
+ err(1, "unveil");
+
+ if (pledge("stdio tty proc exec", NULL) == -1)
+ err(1, "pledge");
+
+ socket_path = getenv("BGPNSH_SOCKET");
+ if (socket_path == NULL)
+ socket_path = BGPNSH_SOCKET;
+ if (strlcpy(bgpd_socket_path, socket_path, sizeof(bgpd_socket_path)) >=
+ sizeof(bgpd_socket_path))
+ err(1, "bgpd socket path too long");
+
+ command();
+
+ return 0;
+}
blob - /dev/null
blob + 452b80c34d3ec3eb9123284e8a249c1af6874380 (mode 644)
--- /dev/null
+++ bgpnsh/stubs.c
+/*
+ * Copyright (c) 2023 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* These functions are stubbed out in bgpnsh but required for linking. */
+
+#include "../stringlist.h"
+
+int is_bridge(int, char *);
+int db_select_rtable_rtables(StringList *);
+
+int
+is_bridge(int s, char *brdg)
+{
+ return 0;
+}
+
+int
+db_select_rtable_rtables(StringList *words)
+{
+ return -1;
+}
blob - eebb73667f75dda726d8e045bee3e25554254690
blob + 4a9419a0ddac0891c65b10ea7ab7e5150a51e051
--- commands.c
+++ commands.c
#include "sysctl.h"
#include "ctl.h"
-char prompt[128];
-char saved_prompt[sizeof(prompt)];
-
-char line[1024];
-char saveline[1024];
-int margc;
char hname[HSIZE];
-static char hbuf[MAXHOSTNAMELEN]; /* host name */
-static char ifname[IFNAMSIZ]; /* interface name */
+char hbuf[MAXHOSTNAMELEN]; /* host name */
+char ifname[IFNAMSIZ]; /* interface name */
struct intlist *whichlist;
-#define NARGS sizeof(line)/2 /* max arguments in char line[] */
-char *margv[NARGS]; /* argv storage */
-size_t cursor_argc; /* location of cursor in margv */
-size_t cursor_argo; /* offset of cursor margv[cursor_argc] */
-
pid_t child;
static int disable(void);
static int exitconfig(int, char**);
int rtable(int, char**);
int group(int, char**);
-static int nsh_setrtable(int);
static int pr_routes(int, char **);
static int pr_routes6(int, char **);
static int pr_arp(int, char **);
static int pr_ndp(int, char **);
static int pr_sadb(int, char **);
static int pr_kernel(int, char **);
-static int pr_prot1(int, char **);
static int pr_dhcp(int, char **);
static int pr_conf(int, char **);
static int pr_s_conf(int, char **);
static int show_hostname(int, char **);
static int wr_startup(void);
static int wr_conf(char *);
-static int show_help(int, char **);
static int sysctlhelp(int, char **, char **, int);
static int flush_pf(char *);
static int flush_help(void);
static int int_shell(char *, int, int, char **);
static int int_help(void);
static int int_exit(void);
-static int el_burrito(EditLine *, int, char **);
static int hostname(int, char **);
-static int help(int, char**);
static int manual(int, char**);
static int nocmd(int, char **);
static int docmd(int, char **);
static int nreboot(void);
static int halt(void);
static int powerdown(void);
-static Command *getcmd(char *);
static void pf_stats(void);
-static void sigalarm(int);
#include "commands.h"
}
}
+static struct fpf {
+ char *name;
+ char *help;
+ char *cmd;
+ char *arg;
+} fpfs[] = {
+ { "all", "all PF elements", PFCTL, "-Fall" },
+ { "nat", "NAT rules", PFCTL, "-Fnat" },
+ { "queue", "queue rules", PFCTL, "-Fqueue" },
+ { "filter", "filter rules", PFCTL, "-Frules" },
+ { "states", "NAT/filter states", PFCTL, "-Fstate" },
+ { "stats", "PF statistics", PFCTL, "-Finfo" },
+ { "tables", "PF address tables", PFCTL, "-FTables" },
+ { 0, 0, 0, 0 }
+};
+
+static struct stt {
+ char *name;
+ char *help;
+ void (*handler) ();
+} stts[] = {
+ { "ip", "Internet Protocol", ip_stats },
+ { "ah", "Authentication Header", ah_stats },
+ { "esp", "Encapsulated Security Payload", esp_stats },
+ { "tcp", "Transmission Control Protocol", tcp_stats },
+ { "udp", "Unreliable Datagram Protocol", udp_stats },
+ { "icmp", "Internet Control Message Protocol", icmp_stats },
+ { "igmp", "Internet Group Management Protocol", igmp_stats },
+ { "ipcomp", "IP Compression", ipcomp_stats },
+ { "route", "Routing", rt_stats },
+ { "carp", "Common Address Redundancy Protocol", carp_stats },
+ { "mbuf", "Packet memory buffer", mbpr },
+ { "pf", "Packet Filter", pf_stats },
+ { 0, 0, 0 }
+};
+
+
+struct prot1 oscs[] = {
+ { "fib", "Forward Information Base",
+ { OSPFCTL, "show", "fib", OPT, OPT, NULL } },
+ { "database", "Link State Database",
+ { OSPFCTL, "show", "database", OPT, OPT, NULL } },
+ { "interfaces", "Interface",
+ { OSPFCTL, "show", "interfaces", OPT, NULL } },
+ { "neighbor", "Neighbor",
+ { OSPFCTL, "show", "neighbor", OPT, NULL } },
+ { "rib", "Routing Information Base",
+ { OSPFCTL, "show", "rib", OPT, NULL } },
+ { "summary", "Summary",
+ { OSPFCTL, "show", "summary", NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 os6cs[] = {
+ { "fib", "Forward Information Base",
+ { OSPF6CTL, "show", "fib", OPT, OPT, NULL } },
+ { "database", "Link State Database",
+ { OSPF6CTL, "show", "database", OPT, OPT, NULL } },
+ { "interfaces", "Interface",
+ { OSPF6CTL, "show", "interfaces", OPT, NULL } },
+ { "neighbor", "Neighbor",
+ { OSPF6CTL, "show", "neighbor", OPT, NULL } },
+ { "rib", "Routing Information Base",
+ { OSPF6CTL, "show", "rib", OPT, NULL } },
+ { "summary", "Summary",
+ { OSPF6CTL, "show", "summary", NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 pfcs[] = {
+ { "all", "all pf info except fingerprints and interfaces",
+ { PFCTL, "-sall", NULL, NULL, NULL, NULL } },
+ { "anchors", "currently loaded anchors in main pf ruleset",
+ { PFCTL, "-sAnchors", NULL, NULL, NULL } },
+ { "info ", "pf filter statistics, counters and tracking",
+ { PFCTL, "-sinfo", "-v", NULL, NULL, NULL } },
+ { "labels", "per rule stats (bytes, packets and states)",
+ { PFCTL, "-slabels", NULL, NULL, NULL, NULL } },
+ { "memory", "current pf pool memory hard limit",
+ { PFCTL, "-smemory", NULL, NULL, NULL, NULL } },
+ { "queues", "currently loaded pf queue definition",
+ { PFCTL, "-squeue", "-v", NULL, NULL, NULL } },
+ { "rules", "active pf firewall rule",
+ { PFCTL, "-srules", NULL, NULL, NULL, NULL } },
+ { "sources", "contents of the pf source tracking table",
+ { PFCTL, "-sSources", NULL, NULL, NULL, NULL } },
+ { "states", "contents of the pf state table",
+ { PFCTL, "-sstates", NULL, NULL, NULL, NULL } },
+ { "tables", "pf table",
+ { PFCTL, "-sTables", NULL, NULL, NULL, NULL } },
+ { "timeouts", "current pf global timeout",
+ { PFCTL, "-stimeouts", NULL, NULL, NULL, NULL } },
+ { "osfingerprint", "pf Operating System fingerprint",
+ { PFCTL, "-sosfp", NULL, NULL, NULL, NULL } },
+ { "interfaces", "pf usable interfaces/ interface group",
+ { PFCTL, "-sInterfaces", NULL, NULL, NULL, NULL } },
+ { 0, 0, { 0 } }
+};
+struct prot1 eics[] = {
+ { "interfaces", "Interface",
+ { EIGRPCTL, "show", "interfaces", OPT, OPT, NULL } },
+ { "neighbor", "Neighbor",
+ { EIGRPCTL, "show", "neighbor", OPT, OPT, NULL } },
+ { "topology", "Topology",
+ { EIGRPCTL, "show", "topology", OPT, OPT, NULL } },
+ { "traffic", "Traffic",
+ { EIGRPCTL, "show", "traffic", OPT, OPT, NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 rics[] = {
+ { "fib", "Forward Information Base",
+ { RIPCTL, "show", "fib", OPT, NULL } },
+ { "interfaces", "Interfaces",
+ { RIPCTL, "show", "interfaces", NULL } },
+ { "neighbor", "Neighbor",
+ { RIPCTL, "show", "neighbor", NULL } },
+ { "rib", "Routing Information Base",
+ { RIPCTL, "show", "rib", NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 lics[] = {
+ { "fib", "Forward Information Base",
+ { LDPCTL, "show", "fib", OPT, NULL } },
+ { "interfaces", "Interfaces",
+ { LDPCTL, "show", "interfaces", NULL } },
+ { "neighbor", "Neighbors",
+ { LDPCTL, "show", "neighbor", NULL } },
+ { "lib", "Label Information Base",
+ { LDPCTL, "show", "lib", NULL } },
+ { "discovery", "Adjacencies",
+ { LDPCTL, "show", "discovery", NULL } },
+ { "l2vpn", "Pseudowire",
+ { LDPCTL, "show", "l2vpn", OPT, NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 iscs[] = {
+ { "flows", "Display IPsec flows",
+ { IPSECCTL, "-sf", NULL } },
+ { "sadb", "Display SADB",
+ { IPSECCTL, "-ss", NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 ikcs[] = {
+ { "monitor", "Monitor internal iked messages",
+ { IKECTL, "monitor", NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 dvcs[] = {
+ { "igmp", "Internet Group Message Protocol",
+ { DVMRPCTL, "show", "igmp", NULL } },
+ { "interfaces", "Interfaces",
+ { DVMRPCTL, "show", "interfaces", OPT, NULL } },
+ { "mfc", "Multicast Forwarding Cache",
+ { DVMRPCTL, "show", "mfc", OPT, NULL } },
+ { "neighbor", "Neighbor",
+ { DVMRPCTL, "show", "neighbor", OPT, NULL } },
+ { "rib", "Routing Information Base",
+ { DVMRPCTL, "show", "rib", OPT, NULL } },
+ { "summary", "Summary",
+ { DVMRPCTL, "show", "summary", NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 rlcs[] = {
+ { "hosts", "hosts",
+ { RELAYCTL, "show", "hosts", NULL } },
+ { "redirects", "redirects",
+ { RELAYCTL, "show", "redirects", NULL } },
+ { "status", "status",
+ { RELAYCTL, "show", "relays", NULL } },
+ { "sessions", "sessions",
+ { RELAYCTL, "show", "sessions", NULL } },
+ { "summary", "summary",
+ { RELAYCTL, "show", "summary", NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 smcs[] = {
+ { "queue", "envelopes in queue",
+ { SMTPCTL, "show", "queue", NULL } },
+ { "runqueue", "envelopes scheduled for delivery",
+ { SMTPCTL, "show", "runqueue", NULL } },
+ { "stats", "runtime statistics",
+ { SMTPCTL, "show", "stats", NULL } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 dhcs[] = {
+ { "leases", "leases", { 0 } },
+ { 0, 0, { 0 } }
+};
+
+struct prot1 ldcs[] = {
+ { "stats", "statistics counters",
+ { LDAPCTL, "stats", NULL } },
+ { 0, 0, { 0 } }
+};
+
+extern struct prot1 bgcs[];
+
+/* show yyy zzz */
+struct prot prots[] = {
+ { "bgp", bgcs },
+ { "ospf", oscs },
+ { "ospf6", os6cs },
+ { "pf", pfcs },
+ { "eigrp", eics },
+ { "rip", rics },
+ { "ike", ikcs },
+ { "ipsec", iscs },
+ { "ldp", lics },
+ { "dvmrp", dvcs },
+ { "relay", rlcs },
+ { "smtp", smcs },
+ { "ldap", ldcs },
+ { 0, 0 }
+};
+
+
/*
* Quit command
*/
if (unlink(outpath) == -1)
printf("%% unlink %s: %s\n", outpath, strerror(errno));
return(error);
-}
-
-static int
-show_help(int argc, char **argv)
-{
- Menu *s; /* pointer to current command */
- u_int z = 0;
-
- printf("%% Commands may be abbreviated.\n");
- printf("%% 'show' commands are:\n\n");
-
- for (s = showlist; s->name; s++) {
- if (strlen(s->name) > z)
- z = strlen(s->name);
- }
-
- for (s = showlist; s->name; s++) {
- if (s->help)
- printf(" %-*s %s\n", z, s->name, s->help);
- }
- return 0;
}
/*
}
void
-makeargv()
-{
- char *cp, *cp2, *base, c;
- char **argp = margv;
-
- margc = 0;
- cp = line;
- if (*cp == '!') { /* Special case shell escape */
- /* save for shell command */
- strlcpy(saveline, line, sizeof(saveline));
-
- *argp++ = "!"; /* No room in string to get this */
- margc++;
- cp++;
- }
- while ((c = *cp)) {
- int inquote = 0;
- while (isspace((unsigned char)c))
- c = *++cp;
- if (c == '\0')
- break;
- *argp++ = cp;
- cursor_argc = margc += 1;
- base = cp;
- for (cursor_argo = 0, cp2 = cp; c != '\0';
- cursor_argo = (cp + 1) - base, c = *++cp) {
- if (inquote) {
- if (c == inquote) {
- inquote = 0;
- continue;
- }
- } else {
- if (c == '\\') {
- if ((c = *++cp) == '\0')
- break;
- } else if (c == '"') {
- inquote = '"';
- continue;
- } else if (c == '\'') {
- inquote = '\'';
- continue;
- } else if (isspace((unsigned char)c)) {
- cursor_argo = 0;
- break;
- }
- }
- *cp2++ = c;
- }
- *cp2 = '\0';
- if (c == '\0') {
- cursor_argc--;
- break;
- }
- cp++;
- }
- *argp++ = 0;
- if (cursor_pos == line) {
- cursor_argc = 0;
- cursor_argo = 0;
- }
-}
-
-void
command()
{
Command *c;
u_int num;
+ init_bgpd_socket_path(getrtable());
+
if (editing) {
inithist();
initedit();
}
/*
- * Help command.
- */
-static int
-help(int argc, char **argv)
-{
- Command *c;
-
- if (argc == 1) {
- u_int z = 0;
-
- printf("%% Commands may be abbreviated.\n");
- printf("%% Commands are:\n\n");
-
- for (c = cmdtab; c->name; c++)
- if (((c->needpriv && priv) || !c->needpriv)
- && strlen(c->name) > z)
- z = strlen(c->name);
- for (c = cmdtab; c->name; c++) {
- if (c->help &&
- ((c->needpriv && priv) || !c->needpriv) &&
- ((c->needconfig && config_mode) || !c->needconfig))
- printf(" %-*s %s\n", z, c->name, c->help);
- }
- return 0;
- }
- while (--argc > 0) {
- char *arg;
- arg = *++argv;
- c = getcmd(arg);
- if (Ambiguous(c))
- printf("%% Ambiguous help command %s\n", arg);
- else if (c == (Command *)0)
- printf("%% Invalid help command %s\n", arg);
- else
- printf("%% %s: %s\n", arg, c->help);
- }
- return 0;
-}
-
-/*
* Manual command.
*/
printf("%s\n", hbuf);
return 0;
-}
-
-int
-nsh_setrtable(int rtableid)
-{
- int cur_rtable;
- errno = 0;
-
- cur_rtable = getrtable();
- if (cur_rtable != rtableid && setrtable(rtableid) < 0)
- switch(errno) {
- case EINVAL:
- printf("%% rtable %d not initialized\n",
- cli_rtable);
- break;
- case EPERM:
- printf("%% nsh not running as root?\n");
- break;
- default:
- printf("%% setrtable failed: %d\n", errno);
- }
- return(errno);
}
/*
}
return 0;
-}
-
-/*
- * cmd, multiple args
- *
- * If no error occurs then return the program's exit code (>= 0).
- * Return -1 on error to run the program or if the program was
- * terminated in an abnormal way, such as being killed by a signal.
- */
-int
-cmdargs(char *cmd, char *arg[])
-{
- return cmdargs_output(cmd, arg, -1, -1);
-}
-
-/*
- * cmd, multiple args, capture stdout and stderr output
- *
- * If no error occurs then return the program's exit code (>= 0).
- * Return -1 on error to run the program or if the program was
- * terminated in an abnormal way, such as being killed by a signal.
- */
-int
-cmdargs_output(char *cmd, char *arg[], int stdoutfd, int stderrfd)
-{
- sig_t sigint, sigquit, sigchld;
- int status = -1;
-
- sigint = signal(SIGINT, SIG_IGN);
- sigquit = signal(SIGQUIT, SIG_IGN);
- sigchld = signal(SIGCHLD, SIG_DFL);
-
- switch (child = fork()) {
- case -1:
- printf("%% fork failed: %s\n", strerror(errno));
- return -1;
-
- case 0:
- {
- char *shellp = cmd;
-
- signal(SIGQUIT, SIG_DFL);
- signal(SIGINT, SIG_DFL);
- signal(SIGCHLD, SIG_DFL);
-
- if (cli_rtable != 0 && nsh_setrtable(cli_rtable))
- _exit(0);
-
- if (stdoutfd != -1) {
- if (stdoutfd != STDOUT_FILENO &&
- dup2(stdoutfd, STDOUT_FILENO) == -1) {
- printf("%% dup2: %s\n",
- strerror(errno));
- _exit(0);
- }
- }
- if (stderrfd != -1) {
- if (stderrfd != STDERR_FILENO &&
- dup2(stderrfd, STDERR_FILENO) == -1) {
- printf("%% dup2 failed: %s\n",
- strerror(errno));
- _exit(0);
- }
- }
-
- execv(shellp, arg);
- printf("%% execv failed: %s\n", strerror(errno));
- _exit(127); /* same as what ksh(1) would do here */
- }
- break;
- default:
- signal(SIGALRM, sigalarm);
- wait(&status); /* Wait for cmd to complete */
- if (WIFEXITED(status)) /* normal exit? */
- status = WEXITSTATUS(status); /* exit code */
- break;
- }
-
- signal(SIGINT, sigint);
- signal(SIGQUIT, sigquit);
- signal(SIGCHLD, sigchld);
- signal(SIGALRM, SIG_DFL);
- child = -1;
-
- return status;
}
/*
initedit();
return(0);
-}
-
-void
-gen_help(char **x, char *cmdprefix, char *descrsuffix, int szstruct)
-{
- /* only for structures starting with char *name; char *help; !! */
- char **y = x;
- struct ghs *ghs;
- int z = 0;
-
- printf("%% Arguments may be abbreviated\n\n");
-
- while (*y != 0) {
- if (strlen(*y) > z)
- z = strlen(*y);
- y = (char **)((char *)y + szstruct);
- }
-
- while (*x != 0) {
- ghs = (struct ghs *)x;
- if (ghs->help)
- printf(" %s %-*s %s %s\n", cmdprefix, z, *x,
- ghs->help, descrsuffix);
- x = (char **)((char *)x + szstruct);
- }
- return;
}
/*
unsigned int lnum; /* line number */
u_int z = 0; /* max length of cmdtab argument */
+ init_bgpd_socket_path(getrtable());
+
if ((rcfile = fopen(rcname, "r")) == 0) {
printf("%% Unable to open %s: %s\n", rcname, strerror(errno));
return 1;
return;
}
-/*
- * for the purpose of interface handler routines, 1 here is failure and
- * 0 is success
- */
int
-el_burrito(EditLine *el, int argc, char **argv)
-{
- char *colon;
- int val;
-
- if (!editing) /* Nothing to parse, fail */
- return(1);
-
- /*
- * el_parse will always return a non-error status if someone specifies
- * argv[0] with a colon. The idea of the colon is to allow host-
- * specific commands, which is really only useful in .editrc, so
- * it is invalid here.
- */
- colon = strchr(argv[0], ':');
- if (colon)
- return(1);
-
- val = el_parse(el, argc, (const char **)argv);
-
- if (val == 0)
- return(0);
- else
- return(1);
-}
-
-char *
-cprompt(void)
-{
- int pr;
- char tmp[4];
-
- if (cli_rtable)
- snprintf(tmp, sizeof(tmp), "%d", cli_rtable);
-
- gethostname(hbuf, sizeof(hbuf));
- pr = priv | cli_rtable | config_mode;
- snprintf(prompt, sizeof(prompt), "%s%s%s%s%s%s%s%s%s/", hbuf,
- pr ? "(" : "",
- config_mode ? "config" : "",
- config_mode && priv ? "-" : "",
- priv ? "p" : "",
- (( priv && cli_rtable) || (config_mode && cli_rtable)) ? "-" : "",
- cli_rtable ? "rtable " : "", cli_rtable ? tmp : "",
- pr ?")" : "");
-
- return(prompt);
-}
-
-char *
-iprompt(void)
-{
- gethostname(hbuf, sizeof(hbuf));
- snprintf(prompt, sizeof(prompt), "%s(%s-%s)/", hbuf,
- bridge ? "bridge" : "interface", ifname);
-
- return(prompt);
-}
-
-char *
-pprompt(void)
-{
- return(prompt);
-}
-
-static void
-setprompt(const char *s)
-{
- strlcpy(saved_prompt, prompt, sizeof(saved_prompt));
- strlcpy(prompt, s, sizeof(prompt));
-}
-
-static void
-restoreprompt(void)
-{
- strlcpy(prompt, saved_prompt, sizeof(prompt));
-}
-
-int
wr_startup(void)
{
char *argv[] = { SAVESCRIPT, NSHRC_TEMP, NULL };
cmdargs(PFCTL, argv);
return;
-}
-
-int
-pr_prot1(int argc, char **argv)
-{
- struct prot1 *x;
- struct prot *prot;
- char *args[NOPTFILL] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
- char **fillargs;
- char prefix[64];
-
- /* loop protocol list to find table pointer */
- prot = (struct prot *) genget(argv[1], (char **)prots,
- sizeof(struct prot));
- if (prot == 0) {
- printf("%% Internal error - Invalid argument %s\n", argv[1]);
- return 0;
- } else if (Ambiguous(prot)) {
- printf("%% Internal error - Ambiguous argument %s\n", argv[1]);
- return 0;
- }
-
- snprintf(prefix, sizeof(prefix), "show %s", prot->name);
-
- /* no clue? we can help */
- if (argc < 3 || argv[2][0] == '?') {
- gen_help((char **)prot->table, prefix, "information",
- sizeof(struct prot1));
- return 0;
- }
- x = (struct prot1 *) genget(argv[2], (char **)prot->table,
- sizeof(struct prot1));
- if (x == 0) {
- printf("%% Invalid argument %s\n", argv[2]);
- return 0;
- } else if (Ambiguous(x)) {
- printf("%% Ambiguous argument %s\n", argv[2]);
- return 0;
- }
-
- fillargs = step_optreq(x->args, args, argc, argv, 3);
- if (fillargs == NULL)
- return 0;
-
- cmdargs(fillargs[0], fillargs);
-
- return 1;
}
-char **
-step_optreq(char **xargs, char **args, int argc, char **argv, int skip)
-{
- int i;
- int fill = 0; /* total fillable arguments */
- int flc = 0; /* number of filled arguments */
-
- /* count fillable arguments */
- for (i = 0; i < NOPTFILL - 1; i++) {
- if (xargs[i] == OPT || xargs[i] == REQ)
- fill++;
- if (xargs[i] == NULL)
- break;
- }
-
- if (argc - skip > fill) {
- printf("%% Superfluous argument: %s\n", argv[skip + fill]);
- return NULL;
- }
-
- /* copy xargs to args, replace OPT/REQ args with argv past skip */
- for (i = 0; i < NOPTFILL - 2; i++) {
- if (xargs[i] == NULL) {
- args[i] = NULL;
- if (i > 1)
- /*
- * all **args passed must have at least two arguments
- * and a terminating NULL. the point of this check
- * is to allow the first two arguments to be NULL but
- * still fill in fillargs[x] with corresponding NULL
- */
- break;
- }
- if (xargs[i] == OPT || xargs[i] == REQ) {
- /* copy from argv to args */
- if (argc - skip - flc > 0) {
- args[i] = argv[skip + flc];
- flc++;
- } else if (xargs[i] == REQ) {
- printf("%% Missing required argument\n");
- return NULL;
- } else {
- args[i] = NULL;
- break;
- }
- } else {
- /* copy from xargs to args */
- args[i] = xargs[i];
- }
- }
-
- return(args);
-}
-
int
pr_dhcp(int argc, char **argv)
{
blob - 264b9b5372a9039445ca747b326559f4b291a05f
blob + 538228794818b95a085bd5e3aa46337a017832b2
--- commands.h
+++ commands.h
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-static struct fpf {
- char *name;
- char *help;
- char *cmd;
- char *arg;
-} fpfs[] = {
- { "all", "all PF elements", PFCTL, "-Fall" },
- { "nat", "NAT rules", PFCTL, "-Fnat" },
- { "queue", "queue rules", PFCTL, "-Fqueue" },
- { "filter", "filter rules", PFCTL, "-Frules" },
- { "states", "NAT/filter states", PFCTL, "-Fstate" },
- { "stats", "PF statistics", PFCTL, "-Finfo" },
- { "tables", "PF address tables", PFCTL, "-FTables" },
- { 0, 0, 0, 0 }
-};
-
-static struct stt {
- char *name;
- char *help;
- void (*handler) ();
-} stts[] = {
- { "ip", "Internet Protocol", ip_stats },
- { "ah", "Authentication Header", ah_stats },
- { "esp", "Encapsulated Security Payload", esp_stats },
- { "tcp", "Transmission Control Protocol", tcp_stats },
- { "udp", "Unreliable Datagram Protocol", udp_stats },
- { "icmp", "Internet Control Message Protocol", icmp_stats },
- { "igmp", "Internet Group Management Protocol", igmp_stats },
- { "ipcomp", "IP Compression", ipcomp_stats },
- { "route", "Routing", rt_stats },
- { "carp", "Common Address Redundancy Protocol", carp_stats },
- { "mbuf", "Packet memory buffer", mbpr },
- { "pf", "Packet Filter", pf_stats },
- { 0, 0, 0 }
-};
-
struct prot1 {
char *name;
char *help;
struct prot1 *table;
};
-struct prot1 bgcs[] = {
- { "announced", "All announced networks",
- { BGPCTL, "network", "show", OPT, NULL } },
- { "interfaces", "Interface states",
- { BGPCTL, "show", "interfaces", NULL } },
- { "nexthop", "BGP nexthop routes",
- { BGPCTL, "show", "nexthop", NULL } },
- { "summary", "Neighbor session states and counters",
- { BGPCTL, "show", "summary", OPT, NULL } },
- { "rib", "Routing Information Base",
- { BGPCTL, "show", "rib", OPT, OPT, OPT, NULL } },
- { "neighbor", "Detailed peer",
- { BGPCTL, "show", "neighbor", REQ, OPT, NULL } },
- { "ip", "IP BGP",
- { BGPCTL, "show", "ip", "bgp", OPT, OPT, OPT, NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 oscs[] = {
- { "fib", "Forward Information Base",
- { OSPFCTL, "show", "fib", OPT, OPT, NULL } },
- { "database", "Link State Database",
- { OSPFCTL, "show", "database", OPT, OPT, NULL } },
- { "interfaces", "Interface",
- { OSPFCTL, "show", "interfaces", OPT, NULL } },
- { "neighbor", "Neighbor",
- { OSPFCTL, "show", "neighbor", OPT, NULL } },
- { "rib", "Routing Information Base",
- { OSPFCTL, "show", "rib", OPT, NULL } },
- { "summary", "Summary",
- { OSPFCTL, "show", "summary", NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 os6cs[] = {
- { "fib", "Forward Information Base",
- { OSPF6CTL, "show", "fib", OPT, OPT, NULL } },
- { "database", "Link State Database",
- { OSPF6CTL, "show", "database", OPT, OPT, NULL } },
- { "interfaces", "Interface",
- { OSPF6CTL, "show", "interfaces", OPT, NULL } },
- { "neighbor", "Neighbor",
- { OSPF6CTL, "show", "neighbor", OPT, NULL } },
- { "rib", "Routing Information Base",
- { OSPF6CTL, "show", "rib", OPT, NULL } },
- { "summary", "Summary",
- { OSPF6CTL, "show", "summary", NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 pfcs[] = {
- { "all", "all pf info except fingerprints and interfaces",
- { PFCTL, "-sall", NULL, NULL, NULL, NULL } },
- { "anchors", "currently loaded anchors in main pf ruleset",
- { PFCTL, "-sAnchors", NULL, NULL, NULL } },
- { "info ", "pf filter statistics, counters and tracking",
- { PFCTL, "-sinfo", "-v", NULL, NULL, NULL } },
- { "labels", "per rule stats (bytes, packets and states)",
- { PFCTL, "-slabels", NULL, NULL, NULL, NULL } },
- { "memory", "current pf pool memory hard limit",
- { PFCTL, "-smemory", NULL, NULL, NULL, NULL } },
- { "queues", "currently loaded pf queue definition",
- { PFCTL, "-squeue", "-v", NULL, NULL, NULL } },
- { "rules", "active pf firewall rule",
- { PFCTL, "-srules", NULL, NULL, NULL, NULL } },
- { "sources", "contents of the pf source tracking table",
- { PFCTL, "-sSources", NULL, NULL, NULL, NULL } },
- { "states", "contents of the pf state table",
- { PFCTL, "-sstates", NULL, NULL, NULL, NULL } },
- { "tables", "pf table",
- { PFCTL, "-sTables", NULL, NULL, NULL, NULL } },
- { "timeouts", "current pf global timeout",
- { PFCTL, "-stimeouts", NULL, NULL, NULL, NULL } },
- { "osfingerprint", "pf Operating System fingerprint",
- { PFCTL, "-sosfp", NULL, NULL, NULL, NULL } },
- { "interfaces", "pf usable interfaces/ interface group",
- { PFCTL, "-sInterfaces", NULL, NULL, NULL, NULL } },
- { 0, 0, { 0 } }
-};
-struct prot1 eics[] = {
- { "interfaces", "Interface",
- { EIGRPCTL, "show", "interfaces", OPT, OPT, NULL } },
- { "neighbor", "Neighbor",
- { EIGRPCTL, "show", "neighbor", OPT, OPT, NULL } },
- { "topology", "Topology",
- { EIGRPCTL, "show", "topology", OPT, OPT, NULL } },
- { "traffic", "Traffic",
- { EIGRPCTL, "show", "traffic", OPT, OPT, NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 rics[] = {
- { "fib", "Forward Information Base",
- { RIPCTL, "show", "fib", OPT, NULL } },
- { "interfaces", "Interfaces",
- { RIPCTL, "show", "interfaces", NULL } },
- { "neighbor", "Neighbor",
- { RIPCTL, "show", "neighbor", NULL } },
- { "rib", "Routing Information Base",
- { RIPCTL, "show", "rib", NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 lics[] = {
- { "fib", "Forward Information Base",
- { LDPCTL, "show", "fib", OPT, NULL } },
- { "interfaces", "Interfaces",
- { LDPCTL, "show", "interfaces", NULL } },
- { "neighbor", "Neighbors",
- { LDPCTL, "show", "neighbor", NULL } },
- { "lib", "Label Information Base",
- { LDPCTL, "show", "lib", NULL } },
- { "discovery", "Adjacencies",
- { LDPCTL, "show", "discovery", NULL } },
- { "l2vpn", "Pseudowire",
- { LDPCTL, "show", "l2vpn", OPT, NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 iscs[] = {
- { "flows", "Display IPsec flows",
- { IPSECCTL, "-sf", NULL } },
- { "sadb", "Display SADB",
- { IPSECCTL, "-ss", NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 ikcs[] = {
- { "monitor", "Monitor internal iked messages",
- { IKECTL, "monitor", NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 dvcs[] = {
- { "igmp", "Internet Group Message Protocol",
- { DVMRPCTL, "show", "igmp", NULL } },
- { "interfaces", "Interfaces",
- { DVMRPCTL, "show", "interfaces", OPT, NULL } },
- { "mfc", "Multicast Forwarding Cache",
- { DVMRPCTL, "show", "mfc", OPT, NULL } },
- { "neighbor", "Neighbor",
- { DVMRPCTL, "show", "neighbor", OPT, NULL } },
- { "rib", "Routing Information Base",
- { DVMRPCTL, "show", "rib", OPT, NULL } },
- { "summary", "Summary",
- { DVMRPCTL, "show", "summary", NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 rlcs[] = {
- { "hosts", "hosts",
- { RELAYCTL, "show", "hosts", NULL } },
- { "redirects", "redirects",
- { RELAYCTL, "show", "redirects", NULL } },
- { "status", "status",
- { RELAYCTL, "show", "relays", NULL } },
- { "sessions", "sessions",
- { RELAYCTL, "show", "sessions", NULL } },
- { "summary", "summary",
- { RELAYCTL, "show", "summary", NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 smcs[] = {
- { "queue", "envelopes in queue",
- { SMTPCTL, "show", "queue", NULL } },
- { "runqueue", "envelopes scheduled for delivery",
- { SMTPCTL, "show", "runqueue", NULL } },
- { "stats", "runtime statistics",
- { SMTPCTL, "show", "stats", NULL } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 dhcs[] = {
- { "leases", "leases", { 0 } },
- { 0, 0, { 0 } }
-};
-
-struct prot1 ldcs[] = {
- { "stats", "statistics counters",
- { LDAPCTL, "stats", NULL } },
- { 0, 0, { 0 } }
-};
-
-/* show yyy zzz */
-struct prot prots[] = {
- { "bgp", bgcs },
- { "ospf", oscs },
- { "ospf6", os6cs },
- { "pf", pfcs },
- { "eigrp", eics },
- { "rip", rics },
- { "ike", ikcs },
- { "ipsec", iscs },
- { "ldp", lics },
- { "dvmrp", dvcs },
- { "relay", rlcs },
- { "smtp", smcs },
- { "ldap", ldcs },
- { 0, 0 }
-};
+#define BGPD_SOCKET_PATH "/var/run/bgpd.sock"
+extern char bgpd_socket_path[PATH_MAX];
+void init_bgpd_socket_path(int);
+extern struct prot prots[];
+int show_help(int, char **);
+Command *getcmd(char *);
+extern Menu showlist[];
+void makeargv(void);
+extern pid_t child;
+extern int nsh_setrtable(int);
+extern void sigalarm(int);
+extern char hbuf[MAXHOSTNAMELEN];
+extern char ifname[IFNAMSIZ];
+int help(int, char**);
blob - /dev/null
blob + 7d771aecb5d74acb2b75f635b6d2b242448eb42a (mode 644)
--- /dev/null
+++ cmdargs.c
+/*
+ * Copyright (c) 2008-2009 Chris Cappuccio <chris@nmedia.net>
+ * Copyright (c) 2023 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h> /* MAXHOSTNAMELEN */
+#include <net/if.h> /* IFNAMSIZ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "externs.h"
+#include "commands.h"
+
+/*
+ * cmd, multiple args
+ *
+ * If no error occurs then return the program's exit code (>= 0).
+ * Return -1 on error to run the program or if the program was
+ * terminated in an abnormal way, such as being killed by a signal.
+ */
+int
+cmdargs(char *cmd, char *arg[])
+{
+ return cmdargs_output(cmd, arg, -1, -1);
+}
+
+/*
+ * cmd, multiple args, capture stdout and stderr output
+ *
+ * If no error occurs then return the program's exit code (>= 0).
+ * Return -1 on error to run the program or if the program was
+ * terminated in an abnormal way, such as being killed by a signal.
+ */
+int
+cmdargs_output(char *cmd, char *arg[], int stdoutfd, int stderrfd)
+{
+ sig_t sigint, sigquit, sigchld;
+ int status = -1;
+
+ sigint = signal(SIGINT, SIG_IGN);
+ sigquit = signal(SIGQUIT, SIG_IGN);
+ sigchld = signal(SIGCHLD, SIG_DFL);
+
+ switch (child = fork()) {
+ case -1:
+ printf("%% fork failed: %s\n", strerror(errno));
+ return -1;
+
+ case 0:
+ {
+ char *shellp = cmd;
+
+ signal(SIGQUIT, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGCHLD, SIG_DFL);
+
+ if (cli_rtable != 0 && nsh_setrtable(cli_rtable))
+ _exit(0);
+
+ if (stdoutfd != -1) {
+ if (stdoutfd != STDOUT_FILENO &&
+ dup2(stdoutfd, STDOUT_FILENO) == -1) {
+ printf("%% dup2: %s\n",
+ strerror(errno));
+ _exit(0);
+ }
+ }
+ if (stderrfd != -1) {
+ if (stderrfd != STDERR_FILENO &&
+ dup2(stderrfd, STDERR_FILENO) == -1) {
+ printf("%% dup2 failed: %s\n",
+ strerror(errno));
+ _exit(0);
+ }
+ }
+
+ execv(shellp, arg);
+ printf("%% execv failed: %s\n", strerror(errno));
+ _exit(127); /* same as what ksh(1) would do here */
+ }
+ break;
+ default:
+ signal(SIGALRM, sigalarm);
+ wait(&status); /* Wait for cmd to complete */
+ if (WIFEXITED(status)) /* normal exit? */
+ status = WEXITSTATUS(status); /* exit code */
+ break;
+ }
+
+ signal(SIGINT, sigint);
+ signal(SIGQUIT, sigquit);
+ signal(SIGCHLD, sigchld);
+ signal(SIGALRM, SIG_DFL);
+ child = -1;
+
+ return status;
+}
+
+int
+nsh_setrtable(int rtableid)
+{
+ int ret = 0;
+
+ if (getrtable() == rtableid)
+ return 0;
+
+ if (setrtable(rtableid) < 0) {
+ ret = errno;
+ switch(errno) {
+ case EINVAL:
+ printf("%% rtable %d not initialized\n",
+ cli_rtable);
+ break;
+ case EPERM:
+ printf("%% nsh not running as root?\n");
+ break;
+ default:
+ printf("%% setrtable failed: %d\n", errno);
+ }
+ } else
+ init_bgpd_socket_path(rtableid);
+
+ return(ret);
+}
blob - 5e3fe1c55c3a61150359610b85098421e3d2cb8e
blob + 1aa4e516adf58328b4cf0e36ccae19bbe005a6cc
--- complete.c
+++ complete.c
eli = NULL;
}
}
+
+/*
+ * for the purpose of interface handler routines, 1 here is failure and
+ * 0 is success
+ */
+int
+el_burrito(EditLine *el, int argc, char **argv)
+{
+ char *colon;
+ int val;
+
+ if (!editing) /* Nothing to parse, fail */
+ return(1);
+
+ /*
+ * el_parse will always return a non-error status if someone specifies
+ * argv[0] with a colon. The idea of the colon is to allow host-
+ * specific commands, which is really only useful in .editrc, so
+ * it is invalid here.
+ */
+ colon = strchr(argv[0], ':');
+ if (colon)
+ return(1);
+
+ val = el_parse(el, argc, (const char **)argv);
+
+ if (val == 0)
+ return(0);
+ else
+ return(1);
+}
blob - 136e119c84cf7769ae95dad3ae5cf92c014581d5
blob + e9b851d07ca29dd0a429191bc48990f82b492690
--- editing.h
+++ editing.h
extern char *cursor_pos; /* cursor position we're looking for */
extern size_t cursor_argc; /* location of cursor in margv */
extern size_t cursor_argo; /* offset of cursor in margv[cursor_argc] */
+
+int el_burrito(EditLine *, int, char **);
blob - 0be9d4e399ef96e55a54cac6c8dd39ed4b847d08
blob + 610184e1adf628ff1d5a11f25b77b38f302ad923
--- externs.h
+++ externs.h
extern char *__progname; /* duh */
extern char *vers; /* the version of nsh */
extern char saveline[1024]; /* command line */
+#define NARGS (sizeof(line)/2) /* max arguments in char line[] */
extern char line[1024]; /* command line for makeargv() */
extern int margc; /* makeargv() arg count */
extern char *margv[]; /* makeargv() args */
/* ctl.c declarations moved to ctl.h */
+/* cmdargs.c */
+int cmdargs_output(char *, char **, int, int);
+int cmdargs(char *, char **);
+int nsh_setrtable(int);
+
/* commands.c */
+extern pid_t child;
#define NOPTFILL 7
#define DEFAULT_EDITOR "/usr/bin/vi"
#define NSHRC_TEMP "/var/run/nshrc"
#define DHCPLEASES "/var/db/dhcpd.leases"
#endif
int quit(void);
+void sigalarm(int);
void command(void);
-char **step_optreq(char **, char **, int, char **, int);
int argvtostring(int, char **, char *, int);
int cmdrc(char rcname[FILENAME_MAX]);
-int cmdargs_output(char *, char **, int, int);
-int cmdargs(char *, char **);
+
+/* prompt.c */
char *iprompt(void);
char *cprompt(void);
char *pprompt(void);
+void setprompt(const char *);
+void restoreprompt(void);
+extern char prompt[128];
+extern char saved_prompt[sizeof(prompt)];
+
int group (int, char **);
void gen_help(char **, char *, char *, int);
void makeargv(void);
int mbs2ws(wchar_t **, size_t *, const char *);
#endif
int mbsavis(char**, int *, const char *);
+
+/* ctlargs.c */
+int pr_prot1(int, char **);
+char **step_optreq(char **, char **, int, char **, int);
blob - /dev/null
blob + 5d373722a7134a484dfb1355223c8f59b95898cd (mode 644)
--- /dev/null
+++ ctlargs.c
+/*
+ * Copyright (c) 2008 Chris Cappuccio <chris@nmedia.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h> /* MAXHOSTNAMELEN */
+#include <net/if.h> /* IFNAMSIZ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+
+#include "externs.h"
+#include "commands.h"
+#include "ctl.h"
+
+int
+pr_prot1(int argc, char **argv)
+{
+ struct prot1 *x;
+ struct prot *prot;
+ char *args[NOPTFILL] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+ char **fillargs;
+ char prefix[64];
+
+ /* loop protocol list to find table pointer */
+ prot = (struct prot *) genget(argv[1], (char **)prots,
+ sizeof(struct prot));
+ if (prot == 0) {
+ printf("%% Internal error - Invalid argument %s\n", argv[1]);
+ return 0;
+ } else if (Ambiguous(prot)) {
+ printf("%% Internal error - Ambiguous argument %s\n", argv[1]);
+ return 0;
+ }
+
+ snprintf(prefix, sizeof(prefix), "show %s", prot->name);
+
+ /* no clue? we can help */
+ if (argc < 3 || argv[2][0] == '?') {
+ gen_help((char **)prot->table, prefix, "information",
+ sizeof(struct prot1));
+ return 0;
+ }
+ x = (struct prot1 *) genget(argv[2], (char **)prot->table,
+ sizeof(struct prot1));
+ if (x == 0) {
+ printf("%% Invalid argument %s\n", argv[2]);
+ return 0;
+ } else if (Ambiguous(x)) {
+ printf("%% Ambiguous argument %s\n", argv[2]);
+ return 0;
+ }
+
+ fillargs = step_optreq(x->args, args, argc, argv, 3);
+ if (fillargs == NULL)
+ return 0;
+
+ cmdargs(fillargs[0], fillargs);
+
+ return 1;
+}
+
+char **
+step_optreq(char **xargs, char **args, int argc, char **argv, int skip)
+{
+ int i;
+ int fill = 0; /* total fillable arguments */
+ int flc = 0; /* number of filled arguments */
+
+ /* count fillable arguments */
+ for (i = 0; i < NOPTFILL - 1; i++) {
+ if (xargs[i] == OPT || xargs[i] == REQ)
+ fill++;
+ if (xargs[i] == NULL)
+ break;
+ }
+
+ if (argc - skip > fill) {
+ printf("%% Superfluous argument: %s\n", argv[skip + fill]);
+ return NULL;
+ }
+
+ /* copy xargs to args, replace OPT/REQ args with argv past skip */
+ for (i = 0; i < NOPTFILL - 2; i++) {
+ if (xargs[i] == NULL) {
+ args[i] = NULL;
+ if (i > 1)
+ /*
+ * all **args passed must have at least two arguments
+ * and a terminating NULL. the point of this check
+ * is to allow the first two arguments to be NULL but
+ * still fill in fillargs[x] with corresponding NULL
+ */
+ break;
+ }
+ if (xargs[i] == OPT || xargs[i] == REQ) {
+ /* copy from argv to args */
+ if (argc - skip - flc > 0) {
+ args[i] = argv[skip + flc];
+ flc++;
+ } else if (xargs[i] == REQ) {
+ printf("%% Missing required argument\n");
+ return NULL;
+ } else {
+ args[i] = NULL;
+ break;
+ }
+ } else {
+ /* copy from xargs to args */
+ args[i] = xargs[i];
+ }
+ }
+
+ return(args);
+}
blob - /dev/null
blob + 9564ad11cfdf44c8f81f31ff2f0d694bd6248954 (mode 644)
--- /dev/null
+++ helpcommands.c
+/*
+ * Copyright (c) 2002-2008 Chris Cappuccio <chris@nmedia.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h> /* MAXHOSTNAMELEN */
+#include <net/if.h> /* IFNAMSIZ */
+
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "externs.h"
+#include "commands.h"
+
+int
+show_help(int argc, char **argv)
+{
+ Menu *s; /* pointer to current command */
+ u_int z = 0;
+
+ printf("%% Commands may be abbreviated.\n");
+ printf("%% 'show' commands are:\n\n");
+
+ for (s = showlist; s->name; s++) {
+ if (strlen(s->name) > z)
+ z = strlen(s->name);
+ }
+
+ for (s = showlist; s->name; s++) {
+ if (s->help)
+ printf(" %-*s %s\n", z, s->name, s->help);
+ }
+ return 0;
+}
+
+void
+gen_help(char **x, char *cmdprefix, char *descrsuffix, int szstruct)
+{
+ /* only for structures starting with char *name; char *help; !! */
+ char **y = x;
+ struct ghs *ghs;
+ int z = 0;
+
+ printf("%% Arguments may be abbreviated\n\n");
+
+ while (*y != 0) {
+ if (strlen(*y) > z)
+ z = strlen(*y);
+ y = (char **)((char *)y + szstruct);
+ }
+
+ while (*x != 0) {
+ ghs = (struct ghs *)x;
+ if (ghs->help)
+ printf(" %s %-*s %s %s\n", cmdprefix, z, *x,
+ ghs->help, descrsuffix);
+ x = (char **)((char *)x + szstruct);
+ }
+ return;
+}
+
+/*
+ * Help command.
+ */
+int
+help(int argc, char **argv)
+{
+ Command *c;
+
+ if (argc == 1) {
+ u_int z = 0;
+
+ printf("%% Commands may be abbreviated.\n");
+ printf("%% Commands are:\n\n");
+
+ for (c = cmdtab; c->name; c++)
+ if (((c->needpriv && priv) || !c->needpriv)
+ && strlen(c->name) > z)
+ z = strlen(c->name);
+ for (c = cmdtab; c->name; c++) {
+ if (c->help &&
+ ((c->needpriv && priv) || !c->needpriv) &&
+ ((c->needconfig && config_mode) || !c->needconfig))
+ printf(" %-*s %s\n", z, c->name, c->help);
+ }
+ return 0;
+ }
+ while (--argc > 0) {
+ char *arg;
+ arg = *++argv;
+ c = getcmd(arg);
+ if (Ambiguous(c))
+ printf("%% Ambiguous help command %s\n", arg);
+ else if (c == (Command *)0)
+ printf("%% Invalid help command %s\n", arg);
+ else
+ printf("%% %s: %s\n", arg, c->help);
+ }
+ return 0;
+}
blob - /dev/null
blob + a4984bcc41ea04e1e693647e0d98fe6a2f50308a (mode 644)
--- /dev/null
+++ makeargv.c
+/*
+ * Copyright (c) 2002-2008 Chris Cappuccio <chris@nmedia.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "externs.h"
+#include "editing.h"
+
+char line[1024];
+char saveline[1024];
+int margc;
+
+char *margv[NARGS]; /* argv storage */
+size_t cursor_argc; /* location of cursor in margv */
+size_t cursor_argo; /* offset of cursor margv[cursor_argc] */
+
+void
+makeargv(void)
+{
+ char *cp, *cp2, *base, c;
+ char **argp = margv;
+
+ margc = 0;
+ cp = line;
+ if (*cp == '!') { /* Special case shell escape */
+ /* save for shell command */
+ strlcpy(saveline, line, sizeof(saveline));
+
+ *argp++ = "!"; /* No room in string to get this */
+ margc++;
+ cp++;
+ }
+ while ((c = *cp)) {
+ int inquote = 0;
+ while (isspace((unsigned char)c))
+ c = *++cp;
+ if (c == '\0')
+ break;
+ *argp++ = cp;
+ cursor_argc = margc += 1;
+ base = cp;
+ for (cursor_argo = 0, cp2 = cp; c != '\0';
+ cursor_argo = (cp + 1) - base, c = *++cp) {
+ if (inquote) {
+ if (c == inquote) {
+ inquote = 0;
+ continue;
+ }
+ } else {
+ if (c == '\\') {
+ if ((c = *++cp) == '\0')
+ break;
+ } else if (c == '"') {
+ inquote = '"';
+ continue;
+ } else if (c == '\'') {
+ inquote = '\'';
+ continue;
+ } else if (isspace((unsigned char)c)) {
+ cursor_argo = 0;
+ break;
+ }
+ }
+ *cp2++ = c;
+ }
+ *cp2 = '\0';
+ if (c == '\0') {
+ cursor_argc--;
+ break;
+ }
+ cp++;
+ }
+ *argp++ = 0;
+ if (cursor_pos == line) {
+ cursor_argc = 0;
+ cursor_argo = 0;
+ }
+}
blob - /dev/null
blob + a5c39ddcf37cedf5347166188640b610e796ba30 (mode 644)
--- /dev/null
+++ prompt.c
+/*
+ * Copyright (c) 2008-2009 Chris Cappuccio <chris@nmedia.net>
+ * Copyright (c) 2023 Stefan Sperling <stsp@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h> /* MAXHOSTNAMELEN */
+#include <net/if.h> /* IFNAMSIZ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "externs.h"
+#include "commands.h"
+
+char prompt[128];
+char saved_prompt[sizeof(prompt)];
+
+char *
+cprompt(void)
+{
+ int pr;
+ char tmp[4];
+
+ if (cli_rtable)
+ snprintf(tmp, sizeof(tmp), "%d", cli_rtable);
+
+ gethostname(hbuf, sizeof(hbuf));
+ pr = priv | cli_rtable | config_mode;
+ snprintf(prompt, sizeof(prompt), "%s%s%s%s%s%s%s%s%s/", hbuf,
+ pr ? "(" : "",
+ config_mode ? "config" : "",
+ config_mode && priv ? "-" : "",
+ priv ? "p" : "",
+ (( priv && cli_rtable) || (config_mode && cli_rtable)) ? "-" : "",
+ cli_rtable ? "rtable " : "", cli_rtable ? tmp : "",
+ pr ?")" : "");
+
+ return(prompt);
+}
+
+char *
+iprompt(void)
+{
+ gethostname(hbuf, sizeof(hbuf));
+ snprintf(prompt, sizeof(prompt), "%s(%s-%s)/", hbuf,
+ bridge ? "bridge" : "interface", ifname);
+
+ return(prompt);
+}
+
+char *
+pprompt(void)
+{
+ return(prompt);
+}
+
+void
+setprompt(const char *s)
+{
+ strlcpy(saved_prompt, prompt, sizeof(saved_prompt));
+ strlcpy(prompt, s, sizeof(prompt));
+}
+
+void
+restoreprompt(void)
+{
+ strlcpy(prompt, saved_prompt, sizeof(prompt));
+}