开源路由软件zebra的命令存储原理及使用方法
2013-01-28 21:11
363 查看
ZZ FROM: http://www.cnblogs.com/iTsihang/archive/2012/12/05/2783252.html
===============================================================================================================
zebra在设计命令格式的时候,将命令节点Node和命令Command分开,整个命令结构是一个树状的,如图:
NODEn表示命令节点,CMDn表示具体的命令。在zebra的整个命令行设计当中,zebra用向量的概念将命令和节点连接起来,建立起隶属关系。一个全局向量CMDVEC,指向整个命令结构,CMDVEC的每一个索引值都是一个具体的命令节点(如果有的话);在每个命令节点的结构中又存在各自的向量cmd_vector,该向量将指向隶属于该节点的命令,cmd_vector中的每个索引值都是一个具体的命令(如果注册的话)。于是,从最初的CMDVEC向量开始,程序就能“顺藤摸瓜“找到任何一个已经注册的命令。比如,程序调用某个方法,该方法对应的命令是CMD1,而该命令的调用是在NODEn这个节点下,那么自然而然,程序就能锁定CMDVEC—>NODEn—>CMD1,实现一条匹配。
命令的注册过程
zebra要成功注册一个命令,需要以下几个步骤:1> 安装一个节点。如果不需要新的命令节点,而使用zebra中自带的节点,可省去这个步骤;2> 写一条命令的实现;3> 将一条实现了的命令安装到命令节点下。
介绍之前,有必要说明一下和命令相关的数据结构。
向量
在zebra.h中定义,表示一个向量结构。该结构中,max表示目前使用的最大slot,alloced表示已经分配给该向量的最大slot数,max <= alloced。Index通过索引方式,存储value。
命令节点
该结构在command.h中定义,用来表示一个命令节点,节点的类型由node_type枚举指出,节点的标识字符由prompt表示,func表示该节点对应的操作方法,该节点下的命令由vector定义的cmd_vector表示。例如,在全局配置模式下,命令节点的定义可以是:
命令
此外,command.h中还有一个重要的结构,就是cmd_element结构,该结构定义了一条命令的全部信息,定义如下:
string 描述了命令的实现串,比如我要显示某个配置信息:“show where are you from“;
func 则是实现string的具体方法;
doc 是string的解释,zebra将string和doc 解析存储,由strvec这个向量指向。
下面,我们逐步使用zebra。
安装一个命令节点
zebra中安装命令节点的接口:void
install_node (struct cmd_node *node, int (*func) (struct vty *))
我们知道,整个zebra的框架是由一个向量指向一个节点,该节点又存在另一个向量,这个向量又有自己的存储结构。从而将整个zebra的命令连接起来,起到提纲挈领的作用。zebra中由vector定义了一个全局向量,名为cmdvec,也就是上文说的CMDVEC。命令节点安装的实质就是将一个cmd_node结构的地址,存储到cmdvec中的一个未被使用的slot—index[i]里。
你可以将自己的命令安装在zebra原带的节点下,也可以添加自己新的节点,我以我的名字命名了一个新的节点。在command.c的73行定义:
将TSIHANG_NODE添加到node_type的CONFIG_NODE之后。然后在command.c的3115行,使用install_node将这个节点安装到cmdvec中:install_node (&tsihang_node, NULL);
写一条命令的实现方法
zebra实现命令的方法由command.h中的一个宏来实现
这个宏很有意思,它表明了一个命令的结构,命令描述,命令的解释,和命令的具体实现方法。编辑command.c文件,照着样子写一条命令实现方法。
例如,我实现的一个简单方法:
但是这样还是不够的,要进入tsihang_node节点还得靠一个触发命令
安装命令
命令的安装实质是将一个cmd_element结构,存储到cmd_node结构中的成员cmd_vec向量的一个未被使用的slot里。
调用接口
/* Install a command into a node. */
void
install_element (enum node_type ntype, struct cmd_element *cmd) ,将刚才写好的命令安装到定义的节点下
在command.c中3192行添加
/* 为了进入自定义节点,需要安装触发命令 */
install_element(ENABLE_NODE, &tsihang_enable_cmd);
install_element(TSIHANG_NODE,
&tsihang_hello_cmd);
编译,运行
编译在我的博客:http://www.cnblogs.com/iTsihang/archive/2012/11/22/2783249.html
中有介绍。
编译完成后,进入zebra目录,执行./zebra&,然后远程登录 telnet 127.0.0.1 2061 端口,zebra的密码都在zebra.conf文件中,登录后可使用。
进到tsihang节点下,运行命令:
本测试例子下载:http://files.cnblogs.com/iTsihang/zebra-0.95a-t.tar.zip
===============================================================================================================
zebra在设计命令格式的时候,将命令节点Node和命令Command分开,整个命令结构是一个树状的,如图:
NODEn表示命令节点,CMDn表示具体的命令。在zebra的整个命令行设计当中,zebra用向量的概念将命令和节点连接起来,建立起隶属关系。一个全局向量CMDVEC,指向整个命令结构,CMDVEC的每一个索引值都是一个具体的命令节点(如果有的话);在每个命令节点的结构中又存在各自的向量cmd_vector,该向量将指向隶属于该节点的命令,cmd_vector中的每个索引值都是一个具体的命令(如果注册的话)。于是,从最初的CMDVEC向量开始,程序就能“顺藤摸瓜“找到任何一个已经注册的命令。比如,程序调用某个方法,该方法对应的命令是CMD1,而该命令的调用是在NODEn这个节点下,那么自然而然,程序就能锁定CMDVEC—>NODEn—>CMD1,实现一条匹配。
命令的注册过程
zebra要成功注册一个命令,需要以下几个步骤:1> 安装一个节点。如果不需要新的命令节点,而使用zebra中自带的节点,可省去这个步骤;2> 写一条命令的实现;3> 将一条实现了的命令安装到命令节点下。
介绍之前,有必要说明一下和命令相关的数据结构。
向量
1 /* struct for vector */ 2 struct _vector 3 { 4 unsigned int max; /* max number of used slot */ 5 unsigned int alloced; /* number of allocated slot */ 6 void **index; /* index to data */ 7 };
在zebra.h中定义,表示一个向量结构。该结构中,max表示目前使用的最大slot,alloced表示已经分配给该向量的最大slot数,max <= alloced。Index通过索引方式,存储value。
命令节点
1 /* Node which has some commands and prompt string and configuration function pointer . */ 2 3 struct cmd_node 5 { 7 /* Node index. */ 9 enum node_type node; 11 /* Prompt character at vty interface. */ 13 char *prompt; 17 /* Is this node's configuration goes to vtysh ? */ 19 int vtysh; 23 /* Node's configuration write function */ 25 int (*func) (struct vty *); 29 /* Vector of this node's command list. */ 31 vector cmd_vector; 33 };
该结构在command.h中定义,用来表示一个命令节点,节点的类型由node_type枚举指出,节点的标识字符由prompt表示,func表示该节点对应的操作方法,该节点下的命令由vector定义的cmd_vector表示。例如,在全局配置模式下,命令节点的定义可以是:
1 struct cmd_node config_node = 3 { 5 CONFIG_NODE, 7 "%s(config)# ", 9 1 11 };
命令
此外,command.h中还有一个重要的结构,就是cmd_element结构,该结构定义了一条命令的全部信息,定义如下:
1 /* Structure of command element. */ 3 struct cmd_element 5 { 7 char *string; /* Command specification by string. */ 9 int (*func) (struct cmd_element *, struct vty *, int, char **); 11 char *doc; /* Documentation of this command. */ 13 int daemon; /* Daemon to which this command belong. */ 15 vector strvec; /* Pointing out each description vector. */ 17 int cmdsize; /* Command index count. */ 19 char *config; /* Configuration string */ 21 vector subconfig; /* Sub configuration string */ 23 };
string 描述了命令的实现串,比如我要显示某个配置信息:“show where are you from“;
func 则是实现string的具体方法;
doc 是string的解释,zebra将string和doc 解析存储,由strvec这个向量指向。
下面,我们逐步使用zebra。
安装一个命令节点
zebra中安装命令节点的接口:void
install_node (struct cmd_node *node, int (*func) (struct vty *))
我们知道,整个zebra的框架是由一个向量指向一个节点,该节点又存在另一个向量,这个向量又有自己的存储结构。从而将整个zebra的命令连接起来,起到提纲挈领的作用。zebra中由vector定义了一个全局向量,名为cmdvec,也就是上文说的CMDVEC。命令节点安装的实质就是将一个cmd_node结构的地址,存储到cmdvec中的一个未被使用的slot—index[i]里。
你可以将自己的命令安装在zebra原带的节点下,也可以添加自己新的节点,我以我的名字命名了一个新的节点。在command.c的73行定义:
1 struct cmd_node tsihang_node = 3 { 5 TSIHANG_NODE, 7 "%s(tsihang)# ", 9 1 11 };
将TSIHANG_NODE添加到node_type的CONFIG_NODE之后。然后在command.c的3115行,使用install_node将这个节点安装到cmdvec中:install_node (&tsihang_node, NULL);
写一条命令的实现方法
zebra实现命令的方法由command.h中的一个宏来实现
1 /* DEFUN for vty command interafce. */ 3 #define DEFUN(funcname, cmdname, cmdstr, helpstr) \ 5 int funcname (struct cmd_element *, struct vty *, int, char **); \ 7 struct cmd_element cmdname = \ 9 { \ 11 cmdstr, \ 13 funcname, \ 15 helpstr \ 17 }; \ 19 int funcname \ 21 (struct cmd_element *self, struct vty *vty, int argc, char **argv)
这个宏很有意思,它表明了一个命令的结构,命令描述,命令的解释,和命令的具体实现方法。编辑command.c文件,照着样子写一条命令实现方法。
例如,我实现的一个简单方法:
1 DEFUN (tsihang_hello, 3 tsihang_hello_cmd, 5 "tsihang say hello", 7 "Greet\n" 9 "Greet to someone\n") 11 { 13 vty_out (vty, "Hello,you can do like this %s", VTY_NEWLINE); 15 return CMD_SUCCESS; 17 }
但是这样还是不够的,要进入tsihang_node节点还得靠一个触发命令
1 //add by Tsihang for test cmmand 3 /* Tsihang command */ 5 DEFUN (tsihang_enable, 7 tsihang_enable_cmd, 9 "tsihang", 11 "Turn on privileged mode command\n") 13 { 15 vty->node = TSIHANG_NODE; 17 return CMD_SUCCESS; 19 }
安装命令
命令的安装实质是将一个cmd_element结构,存储到cmd_node结构中的成员cmd_vec向量的一个未被使用的slot里。
调用接口
/* Install a command into a node. */
void
install_element (enum node_type ntype, struct cmd_element *cmd) ,将刚才写好的命令安装到定义的节点下
在command.c中3192行添加
/* 为了进入自定义节点,需要安装触发命令 */
install_element(ENABLE_NODE, &tsihang_enable_cmd);
install_element(TSIHANG_NODE,
&tsihang_hello_cmd);
编译,运行
编译在我的博客:http://www.cnblogs.com/iTsihang/archive/2012/11/22/2783249.html
中有介绍。
编译完成后,进入zebra目录,执行./zebra&,然后远程登录 telnet 127.0.0.1 2061 端口,zebra的密码都在zebra.conf文件中,登录后可使用。
进到tsihang节点下,运行命令:
1 Router(tsihang)#tsihang say hello 3 Hello, you can do like this 5 Router(tsihang)#
本测试例子下载:http://files.cnblogs.com/iTsihang/zebra-0.95a-t.tar.zip
相关文章推荐
- 开源路由软件zebra的命令存储原理及使用方法
- 开源路由软件zebra的命令存储原理及使用方法
- zebra命令存储原理和使用方法
- LDD命令的原理与使用方法
- Ldd命令原理及使用方法
- LDD命令的原理与使用方法
- LDD命令的原理与使用方法
- Linux Shell脚本ldd命令原理及使用方法
- 使用 mysqldump 命令导出数据库存储过程及函数的方法!
- win8/10 bcdboot引导修复命令的原理和使用方法
- LDD命令的原理与使用方法(转)
- ldd命令原理及使用方法
- Linux Shell脚本Ldd命令原理及使用方法
- 【转】LDD命令的原理与使用方法
- [转]LDD命令的原理与使用方法
- LDD命令的原理与使用方法
- Linux中cp和scp命令的使用方法
- Windows下使用wxPython的pycrust交互shell方法。运行pywrap命令
- EasyMock的原理及使用方法