diff options
-rw-r--r-- | configure.in | 3 | ||||
-rw-r--r-- | include/Makefile.am | 2 | ||||
-rw-r--r-- | include/osmocom/Makefile.am | 1 | ||||
-rw-r--r-- | include/osmocom/vty/Makefile.am | 2 | ||||
-rw-r--r-- | include/osmocom/vty/buffer.h | 102 | ||||
-rw-r--r-- | include/osmocom/vty/command.h | 392 | ||||
-rw-r--r-- | include/osmocom/vty/logging.h | 7 | ||||
-rw-r--r-- | include/osmocom/vty/telnet_interface.h | 40 | ||||
-rw-r--r-- | include/osmocom/vty/vector.h | 64 | ||||
-rw-r--r-- | include/osmocom/vty/vty.h | 151 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/logging.c | 2 | ||||
-rw-r--r-- | src/vty/Makefile.am | 11 | ||||
-rw-r--r-- | src/vty/buffer.c | 463 | ||||
-rw-r--r-- | src/vty/command.c | 3176 | ||||
-rw-r--r-- | src/vty/logging_vty.c | 347 | ||||
-rw-r--r-- | src/vty/telnet_interface.c | 203 | ||||
-rw-r--r-- | src/vty/utils.c | 50 | ||||
-rw-r--r-- | src/vty/vector.c | 192 | ||||
-rw-r--r-- | src/vty/vty.c | 1685 |
20 files changed, 6893 insertions, 2 deletions
diff --git a/configure.in b/configure.in index 9879ebc0..abf098cc 100644 --- a/configure.in +++ b/configure.in @@ -46,10 +46,13 @@ AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "x1") AC_OUTPUT( libosmocore.pc + include/osmocom/Makefile + include/osmocom/vty/Makefile include/osmocore/Makefile include/osmocore/protocol/Makefile include/Makefile src/Makefile + src/vty/Makefile tests/Makefile tests/timer/Makefile tests/sms/Makefile diff --git a/include/Makefile.am b/include/Makefile.am index f0015d5f..185c6968 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1 +1 @@ -SUBDIRS = osmocore +SUBDIRS = osmocom osmocore diff --git a/include/osmocom/Makefile.am b/include/osmocom/Makefile.am new file mode 100644 index 00000000..c9023e65 --- /dev/null +++ b/include/osmocom/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = vty diff --git a/include/osmocom/vty/Makefile.am b/include/osmocom/vty/Makefile.am new file mode 100644 index 00000000..e51dcb83 --- /dev/null +++ b/include/osmocom/vty/Makefile.am @@ -0,0 +1,2 @@ +noinst_HEADERS = buffer.h command.h vector.h vty.h \ + telnet_interface.h diff --git a/include/osmocom/vty/buffer.h b/include/osmocom/vty/buffer.h new file mode 100644 index 00000000..c9467a91 --- /dev/null +++ b/include/osmocom/vty/buffer.h @@ -0,0 +1,102 @@ +/* + * Buffering to output and input. + * Copyright (C) 1998 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ZEBRA_BUFFER_H +#define _ZEBRA_BUFFER_H + +#include <sys/types.h> + +/* Create a new buffer. Memory will be allocated in chunks of the given + size. If the argument is 0, the library will supply a reasonable + default size suitable for buffering socket I/O. */ +struct buffer *buffer_new(void *ctx, size_t); + +/* Free all data in the buffer. */ +void buffer_reset(struct buffer *); + +/* This function first calls buffer_reset to release all buffered data. + Then it frees the struct buffer itself. */ +void buffer_free(struct buffer *); + +/* Add the given data to the end of the buffer. */ +extern void buffer_put(struct buffer *, const void *, size_t); +/* Add a single character to the end of the buffer. */ +extern void buffer_putc(struct buffer *, u_char); +/* Add a NUL-terminated string to the end of the buffer. */ +extern void buffer_putstr(struct buffer *, const char *); + +/* Combine all accumulated (and unflushed) data inside the buffer into a + single NUL-terminated string allocated using XMALLOC(MTYPE_TMP). Note + that this function does not alter the state of the buffer, so the data + is still inside waiting to be flushed. */ +char *buffer_getstr(struct buffer *); + +/* Returns 1 if there is no pending data in the buffer. Otherwise returns 0. */ +int buffer_empty(struct buffer *); + +typedef enum { + /* An I/O error occurred. The buffer should be destroyed and the + file descriptor should be closed. */ + BUFFER_ERROR = -1, + + /* The data was written successfully, and the buffer is now empty + (there is no pending data waiting to be flushed). */ + BUFFER_EMPTY = 0, + + /* There is pending data in the buffer waiting to be flushed. Please + try flushing the buffer when select indicates that the file descriptor + is writeable. */ + BUFFER_PENDING = 1 +} buffer_status_t; + +/* Try to write this data to the file descriptor. Any data that cannot + be written immediately is added to the buffer queue. */ +extern buffer_status_t buffer_write(struct buffer *, int fd, + const void *, size_t); + +/* This function attempts to flush some (but perhaps not all) of + the queued data to the given file descriptor. */ +extern buffer_status_t buffer_flush_available(struct buffer *, int fd); + +/* The following 2 functions (buffer_flush_all and buffer_flush_window) + are for use in lib/vty.c only. They should not be used elsewhere. */ + +/* Call buffer_flush_available repeatedly until either all data has been + flushed, or an I/O error has been encountered, or the operation would + block. */ +extern buffer_status_t buffer_flush_all(struct buffer *, int fd); + +/* Attempt to write enough data to the given fd to fill a window of the + given width and height (and remove the data written from the buffer). + + If !no_more, then a message saying " --More-- " is appended. + If erase is true, then first overwrite the previous " --More-- " message + with spaces. + + Any write error (including EAGAIN or EINTR) will cause this function + to return -1 (because the logic for handling the erase and more features + is too complicated to retry the write later). +*/ +extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width, + int height, int erase, int no_more); + +#endif /* _ZEBRA_BUFFER_H */ diff --git a/include/osmocom/vty/command.h b/include/osmocom/vty/command.h new file mode 100644 index 00000000..1db8ffea --- /dev/null +++ b/include/osmocom/vty/command.h @@ -0,0 +1,392 @@ +/* + * Zebra configuration command interface routine + * Copyright (C) 1997, 98 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ZEBRA_COMMAND_H +#define _ZEBRA_COMMAND_H + +#include <stdio.h> +#include <sys/types.h> +#include "vector.h" +#include "vty.h" + +/* Host configuration variable */ +struct host { + /* Host name of this router. */ + char *name; + + /* Password for vty interface. */ + char *password; + char *password_encrypt; + + /* Enable password */ + char *enable; + char *enable_encrypt; + + /* System wide terminal lines. */ + int lines; + + /* Log filename. */ + char *logfile; + + /* config file name of this host */ + char *config; + + /* Flags for services */ + int advanced; + int encrypt; + + /* Banner configuration. */ + const char *motd; + char *motdfile; + + const char *prog_name; + const char *prog_version; + const char *prog_copyright; +}; + +/* There are some command levels which called from command node. */ +enum node_type { + AUTH_NODE, /* Authentication mode of vty interface. */ + VIEW_NODE, /* View node. Default mode of vty interface. */ + AUTH_ENABLE_NODE, /* Authentication mode for change enable. */ + ENABLE_NODE, /* Enable node. */ + CONFIG_NODE, /* Config node. Default mode of config file. */ + SERVICE_NODE, /* Service node. */ + DEBUG_NODE, /* Debug node. */ +#if 0 + AAA_NODE, /* AAA node. */ + KEYCHAIN_NODE, /* Key-chain node. */ + KEYCHAIN_KEY_NODE, /* Key-chain key node. */ + INTERFACE_NODE, /* Interface mode node. */ + ZEBRA_NODE, /* zebra connection node. */ + TABLE_NODE, /* rtm_table selection node. */ + RIP_NODE, /* RIP protocol mode node. */ + RIPNG_NODE, /* RIPng protocol mode node. */ + BGP_NODE, /* BGP protocol mode which includes BGP4+ */ + BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */ + BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */ + BGP_IPV4M_NODE, /* BGP IPv4 multicast address family. */ + BGP_IPV6_NODE, /* BGP IPv6 address family */ + OSPF_NODE, /* OSPF protocol mode */ + OSPF6_NODE, /* OSPF protocol for IPv6 mode */ + ISIS_NODE, /* ISIS protocol mode */ + MASC_NODE, /* MASC for multicast. */ + IRDP_NODE, /* ICMP Router Discovery Protocol mode. */ + IP_NODE, /* Static ip route node. */ + ACCESS_NODE, /* Access list node. */ + PREFIX_NODE, /* Prefix list node. */ + ACCESS_IPV6_NODE, /* Access list node. */ + PREFIX_IPV6_NODE, /* Prefix list node. */ + AS_LIST_NODE, /* AS list node. */ + COMMUNITY_LIST_NODE, /* Community list node. */ + RMAP_NODE, /* Route map node. */ + SMUX_NODE, /* SNMP configuration node. */ + DUMP_NODE, /* Packet dump node. */ + FORWARDING_NODE, /* IP forwarding node. */ +#endif + VTY_NODE, /* Vty node. */ + + GSMNET_NODE, + BTS_NODE, + TRX_NODE, + TS_NODE, + SUBSCR_NODE, + MGCP_NODE, + GBPROXY_NODE, + SGSN_NODE, + NS_NODE, + BSSGP_NODE, +}; + +/* Node which has some commands and prompt string and configuration + function pointer . */ +struct cmd_node { + /* Node index. */ + enum node_type node; + + /* Prompt character at vty interface. */ + const char *prompt; + + /* Is this node's configuration goes to vtysh ? */ + int vtysh; + + /* Node's configuration write function */ + int (*func) (struct vty *); + + /* Vector of this node's command list. */ + vector cmd_vector; +}; + +enum { + CMD_ATTR_DEPRECATED = 1, + CMD_ATTR_HIDDEN, +}; + +/* Structure of command element. */ +struct cmd_element { + const char *string; /* Command specification by string. */ + int (*func) (struct cmd_element *, struct vty *, int, const char *[]); + const char *doc; /* Documentation of this command. */ + int daemon; /* Daemon to which this command belong. */ + vector strvec; /* Pointing out each description vector. */ + unsigned int cmdsize; /* Command index count. */ + char *config; /* Configuration string */ + vector subconfig; /* Sub configuration string */ + u_char attr; /* Command attributes */ +}; + +/* Command description structure. */ +struct desc { + const char *cmd; /* Command string. */ + const char *str; /* Command's description. */ +}; + +/* Return value of the commands. */ +#define CMD_SUCCESS 0 +#define CMD_WARNING 1 +#define CMD_ERR_NO_MATCH 2 +#define CMD_ERR_AMBIGUOUS 3 +#define CMD_ERR_INCOMPLETE 4 +#define CMD_ERR_EXEED_ARGC_MAX 5 +#define CMD_ERR_NOTHING_TODO 6 +#define CMD_COMPLETE_FULL_MATCH 7 +#define CMD_COMPLETE_MATCH 8 +#define CMD_COMPLETE_LIST_MATCH 9 +#define CMD_SUCCESS_DAEMON 10 + +/* Argc max counts. */ +#define CMD_ARGC_MAX 25 + +/* Turn off these macros when uisng cpp with extract.pl */ +#ifndef VTYSH_EXTRACT_PL + +/* helper defines for end-user DEFUN* macros */ +#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \ + static struct cmd_element cmdname = \ + { \ + .string = cmdstr, \ + .func = funcname, \ + .doc = helpstr, \ + .attr = attrs, \ + .daemon = dnum, \ + }; + +/* global (non static) cmd_element */ +#define gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \ + struct cmd_element cmdname = \ + { \ + .string = cmdstr, \ + .func = funcname, \ + .doc = helpstr, \ + .attr = attrs, \ + .daemon = dnum, \ + }; + +#define DEFUN_CMD_FUNC_DECL(funcname) \ + static int funcname (struct cmd_element *, struct vty *, int, const char *[]); \ + +#define DEFUN_CMD_FUNC_TEXT(funcname) \ + static int funcname \ + (struct cmd_element *self, struct vty *vty, int argc, const char *argv[]) + +/* DEFUN for vty command interafce. Little bit hacky ;-). */ +#define DEFUN(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_FUNC_DECL(funcname) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \ + DEFUN_CMD_FUNC_TEXT(funcname) + +/* global (non static) cmd_element */ +#define gDEFUN(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_FUNC_DECL(funcname) \ + gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \ + DEFUN_CMD_FUNC_TEXT(funcname) + +#define DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \ + DEFUN_CMD_FUNC_DECL(funcname) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \ + DEFUN_CMD_FUNC_TEXT(funcname) + +#define DEFUN_HIDDEN(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN) + +#define DEFUN_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED) \ + +/* DEFUN_NOSH for commands that vtysh should ignore */ +#define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \ + DEFUN(funcname, cmdname, cmdstr, helpstr) + +/* DEFSH for vtysh. */ +#define DEFSH(daemon, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, 0, daemon) \ + +/* DEFUN + DEFSH */ +#define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_FUNC_DECL(funcname) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon) \ + DEFUN_CMD_FUNC_TEXT(funcname) + +/* DEFUN + DEFSH with attributes */ +#define DEFUNSH_ATTR(daemon, funcname, cmdname, cmdstr, helpstr, attr) \ + DEFUN_CMD_FUNC_DECL(funcname) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, daemon) \ + DEFUN_CMD_FUNC_TEXT(funcname) + +#define DEFUNSH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \ + DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN) + +#define DEFUNSH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \ + DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED) + +/* ALIAS macro which define existing command's alias. */ +#define ALIAS(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) + +/* global (non static) cmd_element */ +#define gALIAS(funcname, cmdname, cmdstr, helpstr) \ + gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) + +#define ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) + +#define ALIAS_HIDDEN(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, 0) + +#define ALIAS_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, 0) + +#define ALIAS_SH(daemon, funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon) + +#define ALIAS_SH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, daemon) + +#define ALIAS_SH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \ + DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, daemon) + +#endif /* VTYSH_EXTRACT_PL */ + +/* Some macroes */ +#define CMD_OPTION(S) ((S[0]) == '[') +#define CMD_VARIABLE(S) (((S[0]) >= 'A' && (S[0]) <= 'Z') || ((S[0]) == '<')) +#define CMD_VARARG(S) ((S[0]) == '.') +#define CMD_RANGE(S) ((S[0] == '<')) + +#define CMD_IPV4(S) ((strcmp ((S), "A.B.C.D") == 0)) +#define CMD_IPV4_PREFIX(S) ((strcmp ((S), "A.B.C.D/M") == 0)) +#define CMD_IPV6(S) ((strcmp ((S), "X:X::X:X") == 0)) +#define CMD_IPV6_PREFIX(S) ((strcmp ((S), "X:X::X:X/M") == 0)) + +/* Common descriptions. */ +#define SHOW_STR "Show running system information\n" +#define IP_STR "IP information\n" +#define IPV6_STR "IPv6 information\n" +#define NO_STR "Negate a command or set its defaults\n" +#define CLEAR_STR "Reset functions\n" +#define RIP_STR "RIP information\n" +#define BGP_STR "BGP information\n" +#define OSPF_STR "OSPF information\n" +#define NEIGHBOR_STR "Specify neighbor router\n" +#define DEBUG_STR "Debugging functions (see also 'undebug')\n" +#define UNDEBUG_STR "Disable debugging functions (see also 'debug')\n" +#define ROUTER_STR "Enable a routing process\n" +#define AS_STR "AS number\n" +#define MBGP_STR "MBGP information\n" +#define MATCH_STR "Match values from routing table\n" +#define SET_STR "Set values in destination routing protocol\n" +#define OUT_STR "Filter outgoing routing updates\n" +#define IN_STR "Filter incoming routing updates\n" +#define V4NOTATION_STR "specify by IPv4 address notation(e.g. 0.0.0.0)\n" +#define OSPF6_NUMBER_STR "Specify by number\n" +#define INTERFACE_STR "Interface infomation\n" +#define IFNAME_STR "Interface name(e.g. ep0)\n" +#define IP6_STR "IPv6 Information\n" +#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n" +#define OSPF6_ROUTER_STR "Enable a routing process\n" +#define OSPF6_INSTANCE_STR "<1-65535> Instance ID\n" +#define SECONDS_STR "<1-65535> Seconds\n" +#define ROUTE_STR "Routing Table\n" +#define PREFIX_LIST_STR "Build a prefix list\n" +#define OSPF6_DUMP_TYPE_LIST \ +"(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)" +#define ISIS_STR "IS-IS information\n" +#define AREA_TAG_STR "[area tag]\n" + +#define CONF_BACKUP_EXT ".sav" + +/* IPv4 only machine should not accept IPv6 address for peer's IP + address. So we replace VTY command string like below. */ +#ifdef HAVE_IPV6 +#define NEIGHBOR_CMD "neighbor (A.B.C.D|X:X::X:X) " +#define NO_NEIGHBOR_CMD "no neighbor (A.B.C.D|X:X::X:X) " +#define NEIGHBOR_ADDR_STR "Neighbor address\nIPv6 address\n" +#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|X:X::X:X|WORD) " +#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|X:X::X:X|WORD) " +#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nNeighbor tag\n" +#else +#define NEIGHBOR_CMD "neighbor A.B.C.D " +#define NO_NEIGHBOR_CMD "no neighbor A.B.C.D " +#define NEIGHBOR_ADDR_STR "Neighbor address\n" +#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|WORD) " +#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|WORD) " +#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor tag\n" +#endif /* HAVE_IPV6 */ + +/* Prototypes. */ +void install_node(struct cmd_node *, int (*)(struct vty *)); +void install_default(enum node_type); +void install_element(enum node_type, struct cmd_element *); +void install_element_ve(struct cmd_element *cmd); +void sort_node(); + +/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated + string with a space between each element (allocated using + XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */ +char *argv_concat(const char **argv, int argc, int shift); + +vector cmd_make_strvec(const char *); +void cmd_free_strvec(vector); +vector cmd_describe_command(); +char **cmd_complete_command(); +const char *cmd_prompt(enum node_type); +int config_from_file(struct vty *, FILE *); +enum node_type node_parent(enum node_type); +int cmd_execute_command(vector, struct vty *, struct cmd_element **, int); +int cmd_execute_command_strict(vector, struct vty *, struct cmd_element **); +void config_replace_string(struct cmd_element *, char *, ...); +void cmd_init(int); + +/* Export typical functions. */ +extern struct cmd_element config_exit_cmd; +extern struct cmd_element config_help_cmd; +extern struct cmd_element config_list_cmd; +char *host_config_file(); +void host_config_set(const char *); + +/* This is called from main when a daemon is invoked with -v or --version. */ +void print_version(int print_copyright); + +extern void *tall_vty_cmd_ctx; + +enum node_type (*vty_go_parent_cb)(struct vty *vty); + +#endif /* _ZEBRA_COMMAND_H */ diff --git a/include/osmocom/vty/logging.h b/include/osmocom/vty/logging.h new file mode 100644 index 00000000..f8ffbc3e --- /dev/null +++ b/include/osmocom/vty/logging.h @@ -0,0 +1,7 @@ +#ifndef _VTY_LOGGING_H +#define _VTY_LOGGING_H + +#define LOGGING_STR "Configure log message to this terminal\n" +#define FILTER_STR "Filter log messages\n" + +#endif /* _VTY_LOGGING_H */ diff --git a/include/osmocom/vty/telnet_interface.h b/include/osmocom/vty/telnet_interface.h new file mode 100644 index 00000000..444e6497 --- /dev/null +++ b/include/osmocom/vty/telnet_interface.h @@ -0,0 +1,40 @@ +/* minimalistic telnet/network interface it might turn into a wire interface */ +/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org> + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#ifndef TELNET_INTERFACE_H +#define TELNET_INTERFACE_H + +#include <osmocore/logging.h> +#include <osmocore/select.h> + +#include <osmocom/vty/vty.h> + +struct telnet_connection { + struct llist_head entry; + void *priv; + struct bsc_fd fd; + struct vty *vty; + struct log_target *dbg; +}; + + +int telnet_init(void *tall_ctx, void *priv, int port); + +#endif diff --git a/include/osmocom/vty/vector.h b/include/osmocom/vty/vector.h new file mode 100644 index 00000000..22a184d6 --- /dev/null +++ b/include/osmocom/vty/vector.h @@ -0,0 +1,64 @@ +/* + * Generic vector interface header. + * Copyright (C) 1997, 98 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef _ZEBRA_VECTOR_H +#define _ZEBRA_VECTOR_H + +/* struct for vector */ +struct _vector { + unsigned int active; /* number of active slots */ + unsigned int alloced; /* number of allocated slot */ + void **index; /* index to data */ +}; +typedef struct _vector *vector; + +#define VECTOR_MIN_SIZE 1 + +/* (Sometimes) usefull macros. This macro convert index expression to + array expression. */ +/* Reference slot at given index, caller must ensure slot is active */ +#define vector_slot(V,I) ((V)->index[(I)]) +/* Number of active slots. + * Note that this differs from vector_count() as it the count returned + * will include any empty slots + */ +#define vector_active(V) ((V)->active) + +/* Prototypes. */ +vector vector_init(unsigned int size); +void vector_ensure(vector v, unsigned int num); +int vector_empty_slot(vector v); +int vector_set(vector v, void *val); +int vector_set_index(vector v, unsigned int i, void *val); +void vector_unset(vector v, unsigned int i); +unsigned int vector_count(vector v); +void vector_only_wrapper_free(vector v); +void vector_only_index_free(void *index); +void vector_free(vector v); +vector vector_copy(vector v); + +void *vector_lookup(vector, unsigned int); +void *vector_lookup_ensure(vector, unsigned int); + +extern void *tall_vty_vec_ctx; + +#endif /* _ZEBRA_VECTOR_H */ diff --git a/include/osmocom/vty/vty.h b/include/osmocom/vty/vty.h new file mode 100644 index 00000000..f82ada1c --- /dev/null +++ b/include/osmocom/vty/vty.h @@ -0,0 +1,151 @@ +#ifndef _VTY_H +#define _VTY_H + +#include <stdio.h> +#include <stdarg.h> + +/* GCC have printf type attribute check. */ +#ifdef __GNUC__ +#define VTY_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#else +#define VTY_PRINTF_ATTRIBUTE(a,b) +#endif /* __GNUC__ */ + +/* Does the I/O error indicate that the operation should be retried later? */ +#define ERRNO_IO_RETRY(EN) \ + (((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR)) + +/* Vty read buffer size. */ +#define VTY_READ_BUFSIZ 512 + +#define VTY_BUFSIZ 512 +#define VTY_MAXHIST 20 + +/* Vty events */ +enum event { + VTY_SERV, + VTY_READ, + VTY_WRITE, + VTY_CLOSED, + VTY_TIMEOUT_RESET, +#ifdef VTYSH + VTYSH_SERV, + VTYSH_READ, + VTYSH_WRITE +#endif /* VTYSH */ +}; + +struct vty { + FILE *file; + + /* private data, specified by creator */ + void *priv; + + /* File descripter of this vty. */ + int fd; + + /* Is this vty connect to file or not */ + enum { VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV } type; + + /* Node status of this vty */ + int node; + + /* Failure count */ + int fail; + + /* Output buffer. */ + struct buffer *obuf; + + /* Command input buffer */ + char *buf; + + /* Command cursor point */ + int cp; + + /* Command length */ + int length; + + /* Command max length. */ + int max; + + /* Histry of command */ + char *hist[VTY_MAXHIST]; + + /* History lookup current point */ + int hp; + + /* History insert end point */ + int hindex; + + /* For current referencing point of interface, route-map, + access-list etc... */ + void *index; + + /* For multiple level index treatment such as key chain and key. */ + void *index_sub; + + /* For escape character. */ + unsigned char escape; + + /* Current vty status. */ + enum { VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE } status; + + /* IAC handling: was the last character received the IAC + * (interpret-as-command) escape character (and therefore the next + * character will be the command code)? Refer to Telnet RFC 854. */ + unsigned char iac; + + /* IAC SB (option subnegotiation) handling */ + unsigned char iac_sb_in_progress; + /* At the moment, we care only about the NAWS (window size) negotiation, + * and that requires just a 5-character buffer (RFC 1073): + * <NAWS char> <16-bit width> <16-bit height> */ +#define TELNET_NAWS_SB_LEN 5 + unsigned char sb_buf[TELNET_NAWS_SB_LEN]; + /* How many subnegotiation characters have we received? We just drop + * those that do not fit in the buffer. */ + size_t sb_len; + + /* Window width/height. */ + int width; + int height; + + /* Configure lines. */ + int lines; + + int monitor; + + /* In configure mode. */ + int config; +}; + +/* Small macro to determine newline is newline only or linefeed needed. */ +#define VTY_NEWLINE ((vty->type == VTY_TERM) ? "\r\n" : "\n") + +static inline char *vty_newline(struct vty *vty) +{ + return VTY_NEWLINE; +} + +/* Prototypes. */ +void vty_init(const char *name, const char *version, const char *copyright); +int vty_read_config_file(const char *file_name, void *priv); +void vty_init_vtysh (void); +void vty_reset (void); +struct vty *vty_new (void); +struct vty *vty_create (int vty_sock, void *priv); +int vty_out (struct vty *, const char *, ...) VTY_PRINTF_ATTRIBUTE(2, 3); +int vty_out_newline(struct vty *); +int vty_read(struct vty *vty); +//void vty_time_print (struct vty *, int); +void vty_close (struct vty *); +char *vty_get_cwd (void); +void vty_log (const char *level, const char *proto, const char *fmt, va_list); +int vty_config_lock (struct vty *); +int vty_config_unlock (struct vty *); +int vty_shell (struct vty *); +int vty_shell_serv (struct vty *); +void vty_hello (struct vty *); + +void *tall_vty_ctx; +#endif diff --git a/src/Makefile.am b/src/Makefile.am index ce063d05..2e2eaf0e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,5 @@ +SUBDRIS=vty + # This is _NOT_ the library release version, it's an API version. # Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification LIBVERSION=0:0:0 diff --git a/src/logging.c b/src/logging.c index e72a6e20..531cea6c 100644 --- a/src/logging.c +++ b/src/logging.c @@ -37,7 +37,7 @@ #include <osmocore/utils.h> #include <osmocore/logging.h> -static const struct log_info *log_info; +const struct log_info *log_info; static struct log_context log_context; static void *tall_log_ctx = NULL; diff --git a/src/vty/Makefile.am b/src/vty/Makefile.am new file mode 100644 index 00000000..bc10a0f8 --- /dev/null +++ b/src/vty/Makefile.am @@ -0,0 +1,11 @@ +# This is _NOT_ the library release version, it's an API version. +# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification +LIBVERSION=0:0:0 + +INCLUDES = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS = -fPIC -Wall + +lib_LTLIBRARIES = libosmovty.la + +libosmovty_la_SOURCES = buffer.c command.c vty.c vector.c utils.c \ + telnet_interface.c logging_vty.c diff --git a/src/vty/buffer.c b/src/vty/buffer.c new file mode 100644 index 00000000..a5655b93 --- /dev/null +++ b/src/vty/buffer.c @@ -0,0 +1,463 @@ +/* + * Buffering of output and input. + * Copyright (C) 1998 Kunihiro Ishiguro + * + * This file is part of GNU Zebra. + * + * GNU Zebra is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> |