1. Zebra 功能認識
ZEBRA 提供了一個類Cisco命令行的分級多用戶命令解析引擎--VTY(Virtual Terminal)。它是類似於Linux Shell的虛擬終端接口,負責對訪問的安全驗證、數據緩衝、命令解析、模式切換和命令調用。
用戶通過VTYSH的每一次接口訪問都會發起一個對應的VTY。VTY會根據用戶優先級初始化並掛載相應的命令集Command Node。Command Node中以鏈表的形式包含了該用戶可以訪問和使用的Command。
用戶通過各種接口訪問VTY,VTY解析用戶的每個命令,並且通過命令集鏈表找到並執行Command相應函數。這樣,通過訪問VTY實現基於命令集的管理功能。
2. Zebra 架構
Zebra採用模塊化的架構,,整個程序由一系列的守護進程構成,每個路由協議都有自己單獨的路由處理進程,同時,它提供一個管理內核路由表的zebra 守護進程。路由處理程序通過zebra 守護程序管理內核路由表。
由圖示可知,在Zebra中,總共有五個路由守護進程,和一個管理進程。這些路由進程可以和管理進程分佈在不同的機器上,每一個進程可以分別監聽從不同的端口來的VTY連接。
3. 編譯Zebra爲我所用
一般的路由產品都可以拿來Zebra稍加改動就可以使用了。如果你只需要VTY連接功能,通過接口增、改、刪命令的話,Zebra是支持模塊的刪除和屏蔽的。
比如只需要VTY,那麼你編譯的時候可以在congfigure的時候加上如下參數就可以了。
...
cd ../zebra-vtysh && (test -e config.status ||(touch config.status && ./configure --disable-ipv6 --disable-bgpd --disable-ripngd --disable-ospf6d --disable-bgp-announce --enable-vtysh --disable-ospfd --disable-ripd --disable-zebra --prefix=/ --with-cflags="-O2 -Wall" --build=i386 --host=mips-linux --target=mips)) &&
...
(其中,config.status是configure的狀態記錄信息,以備下次使用)
這樣,編譯完zebra後,就可以運行vtysh了,查看它的各種模式(下篇文章會講),就可以開始你的快樂之旅了。
參考:http://www.zebra.org
4. 分析代碼
分析Zebra-VTYSH的源碼,首先從main函數開始,在vtysh-main.c中找到main函數,來進一步分析流程執行如下圖所示:
在平時的使用中我們會發現,配置的時候有很多的視圖(View),每個視圖中有不同的命令可供用戶輸入進行配置。
這裏,根據源碼,視圖可以認爲是Node,而每一個命令稱爲element,他們之間的結構如下圖所示:
如圖中所示,用到的數據結構如下:
/* struct for vector */
struct _vector
{
unsigned int max; /* max number of used slot */
unsigned int alloced; /* number of allocated slot */
void **index; /* index to data */
};
/* 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. */
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;
};
/* Structure of command element. */
struct cmd_element
{
char *string; /* Command specification by string. */
int (*func) (struct cmd_element *, struct vty *, int, char **);
char *doc; /* Documentation of this command. */
int daemon; /* Daemon to which this command belong. */
vector strvec; /* Pointing out each description vector. */
int cmdsize; /* Command index count. */
char *config; /* Configuration string */
vector subconfig; /* Sub configuration string */
};
下面我們所要做的事情就是在node和element中添加我們自己的命令,如果一切順利,稍加處理就可以在圖一中的最後一步也就是loop循環中的vtysh_execute函數中來實現我們的執行過程了。
5. 添加定製命令
5.1 視圖介紹
由上面幾篇文章分析可見,所有的命令都是包含在node中的,根據Cisco或者H3常見路由器或者交換機的CLI格式可見,一個node就對應着一個視圖(View)。常用的視圖包括:普通視圖,管理視圖,文件系統視圖,配置視圖,以及接口配置視圖和VLAN視圖等。
在Zebra-VTYSH源碼中,實現了的有Enable視圖和配置視圖。如下圖所示:
/ # vtysh
Copyright 2010-2011 IBM Co., Ltd.
CLI> enable
CLI#
clear Reset functions
configure Configuration from vty interface
copy Copy from one file to another
debug Debugging functions (see also 'undebug')
disable Turn off privileged mode command
end End current mode and down to previous mode
exit Exit current mode and down to previous mode
list Print command list
no Negate a command or set its defaults
ping send echo messages
quit Exit current mode and down to previous mode
show Show running system information
start-shell Start UNIX shell
telnet Open a telnet connection
terminal Set terminal line parameters
traceroute Trace route to destination
undebug Disable debugging functions (see also 'debug')
write Write running configuration to memory, network, or terminal
CLI# configure terminal
CLI(config)#
access-list Add an access list entry
bgp BGP information
debug Debugging functions (see also 'undebug')
device-config Device configuration
dump Dump packet
enable Modify enable password parameters
end End current mode and down to previous mode
exit Exit current mode and down to previous mode
hostname Set system's network name
interface Select an interface to configure
ip IP information
ipv6 IPv6 information
key Authentication key management
list Print command list
log Logging control
no Negate a command or set its defaults
password Assign the terminal connection password
route-map Create route-map or enter route-map command mode
router Enable a routing process
system-config System and management configuration
username
write Write running configuration to memory, network, or terminal
CLI(config)# system-config
CLI(config-system)#
access Set CPE access ND flag
admin-idle-time Set system idle time
admin-psw Set system administrator password
admin-username Set system administrator username
connection-mode Set network connection mode : static and dynamic
datetime Set date time (format:2000-01-01 00:00:00)
default-gateway Set system's network default gateway
dns-server-1 Set system network DNS server 1
dns-server-2 Set system network DNS server 2
exit Exit current mode and down to previous mode
factory-defaults Restore ALL configure to factory default values( 0: reset all 1: reset with network parameters unchanged)
hostname Set system's network name
image-upgrade Upgrade image via ftp method
ip Set system ip address and netmask
list Print command list
managment-ip-range Set management IP range and netmask
managment-ip-range-flag Set management IP range service flag
mgr-vlan-id Set management VLAN ID
ntpserver Set NTP server
quit Exit current mode and down to previous mode
reset Reset system
snmp-refresh-time Set SNMP service refresh time cycle
snmp-rwcommunicty Set SNMP read/write community
snmp-service Set SNMP service enable or disable
snmp-trap-ip1 Set SNMP trap ip 1 address
snmp-trap-ip2 Set SNMP trap ip 2 address
snmp-trap1-ip-flag Set SNMP trap ip 1 service flag(enable/disable)
snmp-trap2-ip-flag Set SNMP trap ip 2 service flag(enable/disable)
ssh Set ssh service port and timeout values
ssh-service Set ssh service flag
telnet Set telnet PORT
telnet-service Set telnet service flag
timesync Set time sync service flag
timezone Set time zone (0:ShangHai,1:ChongQing)
CLI(config-system)# quit
CLI(config)# device-config
CLI(config-device)#
exit Exit current mode and down to previous mode
list Print command list
port-mirror-analysis-port Device configuration: Set analysis port(1: eth1 2: eth2)
port-mirror-flag Device configuration: Enable or disable port mirror service(0:disable,1:enable)
port-mirror-packet Device configuration: Set packet type to be mirrored(1:Import & Export 2: Import 3: Export)
port-mirror-port Device configuration:Set port to be mirrored
port1-rate Device configuration: set duplex mode and import/export/broadcast/unkown/multicast rate limit.
port2-rate Device configuration: set duplex mode and import/export/broadcast/unkown/multicast rate limit.
quit Exit current mode and down to previous mode
CLI(config-device)#
CLI(config-device)#
如果想要添加自己的命令,可以在原有的視圖上增加(也就是在原有的node中增加commands),或者新開自己的視圖,然後在新視圖中添加自己的commands。
5.2 添加命令
進入vtysh目錄中,查看vtysh_main.c文件的main函數,也就是和vtysh初始化相關的一切都在這裏,基本上在這裏可以完成你需要的一些基本命令。
在函數vtysh_init_vty()中,有個
/* Initialize command interface. Install basic nodes and commands. */
Void cmd_init (int terminal)
的函數,就是負責初始化command接口,安裝node和命令的。
比如你就可以添加自己的視圖如下:
install_element (CONFIG_NODE, &vtysh_sysconfig_cmd);
install_element (CONFIG_NODE, &vtysh_devconfig_cmd);
(其中,安裝的system和device配置的視圖)
/*Added by xyang
* system config node*
*/
DEFUN (system_config,
vtysh_sysconfig_cmd,
"system-config",
SYS_CFG_STR
"\n")
{
//vty_out (vty, "testing by xyang.%s", VTY_NEWLINE);
vty->node = SYSCONFIG_NODE;
return CMD_SUCCESS;
}
DEFUN (device_config,
vtysh_devconfig_cmd,
"device-config",
DEV_CFG_STR
"\n")
{
//vty_out (vty, "testing by xyang.%s", VTY_NEWLINE);
vty->node = DEVCONFIG_NODE;
return CMD_SUCCESS;
}
DEFUN定義爲:
/* DEFUN for vty command interafce. Little bit hacky ;-). */
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
int funcname (struct cmd_element *, struct vty *, int, char **); \
struct cmd_element cmdname = \
{ \
cmdstr, \
funcname, \
helpstr \
}; \
int funcname \
(struct cmd_element *self, struct vty *vty, int argc, char **argv)
SYSCONFIG_NODE和DEVCONFIG_NODE要添加進enum node_type{}中去。
最後就要在init_cmd的最後加進自己的command了
比如
/*add commands to system config node
* added by xyang @ 2012-02-01*
*/
/*management network settings*/
install_element (SYSCONFIG_NODE, &vtysh_system_cfg_ip_cmd);//ip and subnet mask
其中,函數指針需要定義先:
DEFUN (vtysh_system_cfg_ip,
vtysh_system_cfg_ip_cmd,
"ip ADDRESS NETMASK",
"Set system ip address and netmask\n")
{
applyCfg(argv[0],"IPADDR");
applyCfg(argv[1],"NETMASK");
system(NETWORK_SETTING_SCRIPT);
return CMD_SUCCESS;
}
這樣,基本上完成了添加node和命令的任務了。
其他Zebra-VTYH自帶的命令如果不想要的話刪除掉就行了。