diff options
| -rw-r--r-- | include/osmocom/vty/command.h | 103 | ||||
| -rw-r--r-- | include/osmocom/vty/telnet_interface.h | 17 | ||||
| -rw-r--r-- | include/osmocom/vty/vty.h | 72 | ||||
| -rw-r--r-- | src/vty/command.c | 30 | ||||
| -rw-r--r-- | src/vty/telnet_interface.c | 15 | ||||
| -rw-r--r-- | src/vty/utils.c | 13 | ||||
| -rw-r--r-- | src/vty/vty.c | 45 | 
7 files changed, 209 insertions, 86 deletions
diff --git a/include/osmocom/vty/command.h b/include/osmocom/vty/command.h index 783a7a2d..c50f256f 100644 --- a/include/osmocom/vty/command.h +++ b/include/osmocom/vty/command.h @@ -28,74 +28,80 @@  #include "vector.h"  #include "vty.h" -/* Host configuration variable */ +/*! \addtogroup vty + *  @{ + */ +/*! \file command.h */ + +/*! \brief Host configuration variable */  struct host { -	/* Host name of this router. */ +	/*! \brief Host name of this router. */  	char *name; -	/* Password for vty interface. */ +	/*! \brief Password for vty interface. */  	char *password;  	char *password_encrypt; -	/* Enable password */ +	/*! \brief Enable password */  	char *enable;  	char *enable_encrypt; -	/* System wide terminal lines. */ +	/*! \brief System wide terminal lines. */  	int lines; -	/* Log filename. */ +	/*! \brief Log filename. */  	char *logfile; -	/* config file name of this host */ +	/*! \brief config file name of this host */  	char *config; -	/* Flags for services */ +	/*! \brief Flags for services */  	int advanced;  	int encrypt; -	/* Banner configuration. */ +	/*! \brief Banner configuration. */  	const char *motd;  	char *motdfile; +	/*! \brief VTY application information */  	const struct vty_app_info *app_info;  }; -/* There are some command levels which called from command node. */ +/*! \brief 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. */ -	CFG_LOG_NODE,		/* Configure the logging */ +	AUTH_NODE,		/*!< \brief Authentication mode of vty interface. */ +	VIEW_NODE,		/*!< \brief View node. Default mode of vty interface. */ +	AUTH_ENABLE_NODE,	/*!< \brief Authentication mode for change enable. */ +	ENABLE_NODE,		/*!< \brief Enable node. */ +	CONFIG_NODE,		/*!< \brief Config node. Default mode of config file. */ +	SERVICE_NODE,		/*!< \brief Service node. */ +	DEBUG_NODE,		/*!< \brief Debug node. */ +	CFG_LOG_NODE,		/*!< \brief Configure the logging */ -	VTY_NODE,		/* Vty node. */ +	VTY_NODE,		/*!< \brief Vty node. */ -	L_E1INP_NODE,		/* E1 line in libosmo-abis. */ -	L_IPA_NODE,		/* IPA proxying commands in libosmo-abis. */ +	L_E1INP_NODE,		/*!< \brief E1 line in libosmo-abis. */ +	L_IPA_NODE,		/*!< \brief IPA proxying commands in libosmo-abis. */  	_LAST_OSMOVTY_NODE  }; -/* Node which has some commands and prompt string and configuration -   function pointer . */ +/*! \brief Node which has some commands and prompt string and + * configuration function pointer . */  struct cmd_node { -	/* Node index. */ +	/*! \brief Node index */  	enum node_type node; -	/* Prompt character at vty interface. */ +	/*! \brief Prompt character at vty interface. */  	const char *prompt; -	/* Is this node's configuration goes to vtysh ? */ +	/*! \brief Is this node's configuration goes to vtysh ? */  	int vtysh; -	/* Node's configuration write function */ +	/*! \brief Node's configuration write function */  	int (*func) (struct vty *); -	/* Vector of this node's command list. */ +	/*! \brief Vector of this node's command list. */  	vector cmd_vector;  }; @@ -104,26 +110,26 @@ enum {  	CMD_ATTR_HIDDEN,  }; -/* Structure of command element. */ +/*! \brief Structure of a command element */  struct cmd_element { -	const char *string;	/* Command specification by string. */ +	const char *string;	/*!< \brief 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 */ +	const char *doc;	/*!< \brief Documentation of this command. */ +	int daemon;		/*!< \brief Daemon to which this command belong. */ +	vector strvec;		/*!< \brief Pointing out each description vector. */ +	unsigned int cmdsize;	/*!< \brief Command index count. */ +	char *config;		/*!< \brief Configuration string */ +	vector subconfig;	/*!< \brief Sub configuration string */ +	u_char attr;		/*!< \brief Command attributes */  }; -/* Command description structure. */ +/*! \brief Command description structure. */  struct desc { -	const char *cmd;	/* Command string. */ -	const char *str;	/* Command's description. */ +	const char *cmd;	/*!< \brief Command string. */ +	const char *str;	/*!< \brief Command's description. */  }; -/* Return value of the commands. */ +/*! \brief Return value of the commands. */  #define CMD_SUCCESS              0  #define CMD_WARNING              1  #define CMD_ERR_NO_MATCH         2 @@ -171,13 +177,23 @@ struct desc {    static int funcname \      (struct cmd_element *self, struct vty *vty, int argc, const char *argv[]) -/* DEFUN for vty command interafce. Little bit hacky ;-). */ +/*! \brief Macro for defining a VTY node and function + *  \param[in] funcname Name of the function implementing the node + *  \param[in] cmdname Name of the command node + *  \param[in] cmdstr String with syntax of node + *  \param[in] helpstr String with help message of node + */  #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 */ +/*! \brief Macro for defining a non-static (global) VTY node and function + *  \param[in] funcname Name of the function implementing the node + *  \param[in] cmdname Name of the command node + *  \param[in] cmdstr String with syntax of node + *  \param[in] helpstr String with help message of node + */  #define gDEFUN(funcname, cmdname, cmdstr, helpstr) \    DEFUN_CMD_FUNC_DECL(funcname) \    gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \ @@ -350,4 +366,5 @@ void print_version(int print_copyright);  extern void *tall_vty_cmd_ctx; +/*! }@ */  #endif				/* _ZEBRA_COMMAND_H */ diff --git a/include/osmocom/vty/telnet_interface.h b/include/osmocom/vty/telnet_interface.h index 1d8055e7..c776f51c 100644 --- a/include/osmocom/vty/telnet_interface.h +++ b/include/osmocom/vty/telnet_interface.h @@ -26,15 +26,28 @@  #include <osmocom/vty/vty.h> +/*! \addtogroup vty + *  @{ + */ + +/*! \file telnet_interface.h */ + +/*! \brief A telnet connection */  struct telnet_connection { +	/*! \brief linked list header for internal management */  	struct llist_head entry; +	/*! \brief private data pointer passed through */  	void *priv; +	/*! \brief filedsecriptor (socket ) */  	struct osmo_fd fd; +	/*! \brief VTY instance associated with telnet connection */  	struct vty *vty; +	/*! \brief logging target associated with this telnet connection */  	struct log_target *dbg;  }; -  int telnet_init(void *tall_ctx, void *priv, int port); -#endif +/*! }@ */ + +#endif /* TELNET_INTERFACE_H */ diff --git a/include/osmocom/vty/vty.h b/include/osmocom/vty/vty.h index 8035585d..d1f6f440 100644 --- a/include/osmocom/vty/vty.h +++ b/include/osmocom/vty/vty.h @@ -4,6 +4,11 @@  #include <stdio.h>  #include <stdarg.h> +/*! \defgroup vty VTY (Virtual TTY) interface + *  @{ + */ +/*! \file vty.h */ +  /* GCC have printf type attribute check.  */  #ifdef __GNUC__  #define VTY_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) @@ -21,7 +26,7 @@  #define VTY_BUFSIZ 512  #define VTY_MAXHIST 20 -/* Vty events */ +/*! \brief VTY events */  enum event {  	VTY_SERV,  	VTY_READ, @@ -35,87 +40,94 @@ enum event {  #endif				/* VTYSH */  }; +/*! Internal representation of a single VTY */  struct vty { +	/*! \brief underlying file (if any) */  	FILE *file; -	/* private data, specified by creator */ +	/*! \brief private data, specified by creator */  	void *priv; -	/* File descripter of this vty. */ +	/*! \brief File descripter of this vty. */  	int fd; -	/* Is this vty connect to file or not */ +	/*! \brief Is this vty connect to file or not */  	enum { VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV } type; -	/* Node status of this vty */ +	/*! \brief Node status of this vty */  	int node; -	/* Failure count */ +	/*! \brief Failure count */  	int fail; -	/* Output buffer. */ +	/*! \brief Output buffer. */  	struct buffer *obuf; -	/* Command input buffer */ +	/*! \brief Command input buffer */  	char *buf; -	/* Command cursor point */ +	/*! \brief Command cursor point */  	int cp; -	/* Command length */ +	/*! \brief Command length */  	int length; -	/* Command max length. */ +	/*! \brief Command max length. */  	int max; -	/* Histry of command */ +	/*! \brief Histry of command */  	char *hist[VTY_MAXHIST]; -	/* History lookup current point */ +	/*! \brief History lookup current point */  	int hp; -	/* History insert end point */ +	/*! \brief History insert end point */  	int hindex; -	/* For current referencing point of interface, route-map, +	/*! \brief For current referencing point of interface, route-map,  	   access-list etc... */  	void *index; -	/* For multiple level index treatment such as key chain and key. */ +	/*! \brief For multiple level index treatment such as key chain and key. */  	void *index_sub; -	/* For escape character. */ +	/*! \brief For escape character. */  	unsigned char escape; -	/* Current vty status. */ +	/*! \brief Current vty status. */  	enum { VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE } status; -	/* IAC handling: was the last character received the IAC +	/*! \brief IAC handling +	 * +	 * 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 */ +	/*! \brief 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 +	/*! \brief sub-negotiation buffer */  	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. */ +	/*! \brief 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. */ +	/*! \brief Window width */  	int width; +	/*! \brief Widnow height */  	int height; -	/* Configure lines. */ +	/*! \brief Configure lines. */  	int lines;  	int monitor; -	/* In configure mode. */ +	/*! \brief In configure mode. */  	int config;  }; @@ -127,12 +139,19 @@ static inline char *vty_newline(struct vty *vty)  	return VTY_NEWLINE;  } +/*! Information an application registers with the VTY */  struct vty_app_info { +	/*! \brief name of the application */  	const char *name; +	/*! \brief version string of the application */  	const char *version; +	/*! \brief copyright string of the application */  	const char *copyright; +	/*! \brief \ref talloc context */  	void *tall_ctx; +	/*! \brief call-back for returning to parent n ode */  	enum node_type (*go_parent_cb)(struct vty *vty); +	/*! \brief call-back to determine if node is config node */  	int (*is_config_node)(struct vty *vty, int node);  }; @@ -159,4 +178,7 @@ void *vty_current_index(struct vty *);  int vty_current_node(struct vty *vty);  extern void *tall_vty_ctx; + +/*! }@ */ +  #endif diff --git a/src/vty/command.c b/src/vty/command.c index 1c8df61a..890fb7df 100644 --- a/src/vty/command.c +++ b/src/vty/command.c @@ -40,6 +40,11 @@ Boston, MA 02111-1307, USA.  */  #include <osmocom/core/talloc.h> +/*! \addtogroup vty + * @{ + */ +/*! \file command.c */ +  #define CONFIGFILE_MASK 022  void *tall_vty_cmd_ctx; @@ -81,7 +86,9 @@ struct cmd_node config_node = {  /* Default motd string. */  const char *default_motd = ""; -/* This is called from main when a daemon is invoked with -v or --version. */ +/*! \brief print the version (and optionally copyright) information + * + * This is called from main when a daemon is invoked with -v or --version. */  void print_version(int print_copyright)  {  	printf("%s version %s\n", host.app_info->name, host.app_info->version); @@ -114,7 +121,7 @@ char *argv_concat(const char **argv, int argc, int shift)  	return str;  } -/* Install top node of command vector. */ +/*! \brief Install top node of command vector. */  void install_node(struct cmd_node *node, int (*func) (struct vty *))  {  	vector_set_index(cmdvec, node->node, node); @@ -151,7 +158,7 @@ static int is_config(struct vty *vty)  		return vty->node > CONFIG_NODE;  } -/* Sort each node's command element according to command string. */ +/*! \brief Sort each node's command element according to command string. */  void sort_node(void)  {  	unsigned int i, j; @@ -181,7 +188,7 @@ void sort_node(void)  		}  } -/* Breaking up string into each command piece. I assume given +/*! Breaking up string into each command piece. I assume given     character is separated by a space character. Return value is a     vector which includes char ** data element. */  vector cmd_make_strvec(const char *string) @@ -231,7 +238,7 @@ vector cmd_make_strvec(const char *string)  	}  } -/* Free allocated string vector. */ +/*! \brief Free allocated string vector. */  void cmd_free_strvec(vector v)  {  	unsigned int i; @@ -247,7 +254,7 @@ void cmd_free_strvec(vector v)  	vector_free(v);  } -/* Fetch next description.  Used in cmd_make_descvec(). */ +/*! \brief Fetch next description.  Used in \ref cmd_make_descvec(). */  static char *cmd_desc_str(const char **string)  {  	const char *cp, *start; @@ -282,7 +289,7 @@ static char *cmd_desc_str(const char **string)  	return token;  } -/* New string vector. */ +/*! \brief New string vector. */  static vector cmd_make_descvec(const char *string, const char *descstr)  {  	int multiple = 0; @@ -389,7 +396,7 @@ static int cmd_cmdsize(vector strvec)  	return size;  } -/* Return prompt character of specified node. */ +/*! \brief Return prompt character of specified node. */  const char *cmd_prompt(enum node_type node)  {  	struct cmd_node *cnode; @@ -398,7 +405,10 @@ const char *cmd_prompt(enum node_type node)  	return cnode->prompt;  } -/* Install a command into a node. */ +/*! \brief Install a command into a node + *  \param[in] ntype Node Type + *  \param[cmd] element to be installed + */  void install_element(enum node_type ntype, struct cmd_element *cmd)  {  	struct cmd_node *cnode; @@ -3227,3 +3237,5 @@ void cmd_init(int terminal)  	}  	srand(time(NULL));  } + +/*! }@ */ diff --git a/src/vty/telnet_interface.c b/src/vty/telnet_interface.c index 1a285102..89cba581 100644 --- a/src/vty/telnet_interface.c +++ b/src/vty/telnet_interface.c @@ -33,6 +33,11 @@  #include <osmocom/vty/buffer.h>  #include <osmocom/vty/command.h> +/*! \addtogroup vty + *  @{ + */ +/*! \file telnet_interface.c */ +  /* per connection data */  LLIST_HEAD(active_connections); @@ -47,6 +52,11 @@ static struct osmo_fd server_socket = {  	.priv_nr    = 0,  }; +/*! \brief Initialize telnet based VTY interface + *  \param[in] tall_ctx \ref talloc context + *  \param[in] priv private data to be passed to callback + *  \param[in] port UDP port number + */  int telnet_init(void *tall_ctx, void *priv, int port)  {  	struct sockaddr_in sock_addr; @@ -55,6 +65,7 @@ int telnet_init(void *tall_ctx, void *priv, int port)  	tall_telnet_ctx = talloc_named_const(tall_ctx, 1,  					     "telnet_connection"); +	/* FIXME: use new socket.c code of libosmocore */  	fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);  	if (fd < 0) { @@ -109,6 +120,7 @@ static void print_welcome(int fd)  		write(fd, host.app_info->copyright, strlen(host.app_info->copyright));  } +/*! \brief close a telnet connection */  int telnet_close_client(struct osmo_fd *fd)  {  	struct telnet_connection *conn = (struct telnet_connection*)fd->data; @@ -183,7 +195,7 @@ static int telnet_new_connection(struct osmo_fd *fd, unsigned int what)  	return 0;  } -/* callback from VTY code */ +/*! \brief callback from core VTY code about VTY related events */  void vty_event(enum event event, int sock, struct vty *vty)  {  	struct telnet_connection *connection = vty->priv; @@ -209,3 +221,4 @@ void vty_event(enum event event, int sock, struct vty *vty)  	}  } +/*! }@ */ diff --git a/src/vty/utils.c b/src/vty/utils.c index 7797e62d..47b9931f 100644 --- a/src/vty/utils.c +++ b/src/vty/utils.c @@ -30,6 +30,17 @@  #include <osmocom/vty/vty.h> +/* \file utils.c */ + +/*! \addtogroup rate_ctr + *  @{ + */ + +/*! \brief print a rate counter group to given VTY + *  \param[in] vty The VTY to which it should be printed + *  \param[in] prefix Any additional log prefix ahead of each line + *  \param[in] ctrg Rate counter group to be printed + */  void vty_out_rate_ctr_group(struct vty *vty, const char *prefix,  			    struct rate_ctr_group *ctrg)  { @@ -48,3 +59,5 @@ void vty_out_rate_ctr_group(struct vty *vty, const char *prefix,  			VTY_NEWLINE);  	};  } + +/*! }@ */ diff --git a/src/vty/vty.c b/src/vty/vty.c index 1f3237ad..56e0088c 100644 --- a/src/vty/vty.c +++ b/src/vty/vty.c @@ -18,6 +18,11 @@  #include <osmocom/vty/buffer.h>  #include <osmocom/core/talloc.h> +/* \addtogroup vty + * @{ + */ +/*! \file vty.c */ +  #define SYSCONFDIR "/usr/local/etc"  /* our callback, located in telnet_interface.c */ @@ -44,7 +49,7 @@ static void vty_clear_buf(struct vty *vty)  	memset(vty->buf, 0, vty->max);  } -/* Allocate new vty struct. */ +/*! \brief Allocate a new vty interface structure */  struct vty *vty_new(void)  {  	struct vty *new = talloc_zero(tall_vty_ctx, struct vty); @@ -137,7 +142,7 @@ static void vty_auth(struct vty *vty, char *buf)  	}  } -/* Close vty interface. */ +/*! \brief Close a given vty interface. */  void vty_close(struct vty *vty)  {  	int i; @@ -178,13 +183,17 @@ void vty_close(struct vty *vty)  	talloc_free(vty);  } +/*! \brief Return if this VTY is a shell or not */  int vty_shell(struct vty *vty)  {  	return vty->type == VTY_SHELL ? 1 : 0;  } -/* VTY standard output function. */ +/*! \brief VTY standard output function + *  \param[in] vty VTY to which we should print + *  \param[in] format variable-length format string + */  int vty_out(struct vty *vty, const char *format, ...)  {  	va_list args; @@ -241,6 +250,7 @@ int vty_out(struct vty *vty, const char *format, ...)  	return len;  } +/*! \brief print a newline on the given VTY */  int vty_out_newline(struct vty *vty)  {  	char *p = vty_newline(vty); @@ -248,15 +258,24 @@ int vty_out_newline(struct vty *vty)  	return 0;  } +/*! \brief return the current index of a given VTY */  void *vty_current_index(struct vty *vty)  {  	return vty->index;  } + +/*! \brief return the current node of a given VTY */  int vty_current_node(struct vty *vty)  {  	return vty->node;  } +/*! \brief Lock the configuration to a given VTY + *  \param[in] vty VTY to which the config shall be locked + *  \returns 1 on success, 0 on error + * + * This shall be used to make sure only one VTY at a given time has + * access to modify the configuration */  int vty_config_lock(struct vty *vty)  {  	if (vty_config == 0) { @@ -266,6 +285,10 @@ int vty_config_lock(struct vty *vty)  	return vty->config;  } +/*! \brief Unlock the configuration from a given VTY + *  \param[in] vty VTY from which the configuration shall be unlocked + *  \returns 0 in case of success + */  int vty_config_unlock(struct vty *vty)  {  	if (vty_config == 1 && vty->config == 1) { @@ -1182,7 +1205,7 @@ static void vty_buffer_reset(struct vty *vty)  	vty_redraw_line(vty);  } -/* Read data via vty socket. */ +/*! \brief Read data via vty socket. */  int vty_read(struct vty *vty)  {  	int i; @@ -1401,7 +1424,7 @@ vty_read_file(FILE *confp, void *priv)  	return 0;  } -/* Create new vty structure. */ +/*! \brief Create new vty structure. */  struct vty *  vty_create (int vty_sock, void *priv)  { @@ -1590,7 +1613,7 @@ struct cmd_node vty_node = {  	1,  }; -/* Reset all VTY status. */ +/*! \brief Reset all VTY status. */  void vty_reset(void)  {  	unsigned int i; @@ -1647,6 +1670,10 @@ void vty_init_vtysh(void)  }  extern void *tall_bsc_ctx; + +/*! \brief Initialize VTY layer + *  \param[in] app_info application information + */  /* Install vty's own commands like `who' command. */  void vty_init(struct vty_app_info *app_info)  { @@ -1680,6 +1707,10 @@ void vty_init(struct vty_app_info *app_info)  	install_element(VTY_NODE, &no_vty_login_cmd);  } +/*! \brief Read the configuration file using the VTY code + *  \param[in] file_name file name of the configuration file + *  \param[in] priv private data to be passed to \ref vty_read_file + */  int vty_read_config_file(const char *file_name, void *priv)  {  	FILE *cfile; @@ -1696,3 +1727,5 @@ int vty_read_config_file(const char *file_name, void *priv)  	return rc;  } + +/*! }@ */  | 
