指令節點類型定義:隻需要将新增的指令節點加入該枚舉中即可。
enum node_type
{
AUTH_NODE, /* Authentication mode of vty interface. */
RESTRICTED_NODE, /* Restricted view mode */
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. */
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. */
BABEL_NODE, /* Babel 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 */
BGP_IPV6M_NODE, /* BGP IPv6 multicast address family. */
OSPF_NODE, /* OSPF protocol mode */
OSPF6_NODE, /* OSPF protocol for IPv6 mode */
ISIS_NODE, /* ISIS protocol mode */
PIM_NODE, /* PIM 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. */
PROTOCOL_NODE, /* protocol filtering node */
VTY_NODE, /* Vty node. */
*TEST_NODE,*
}
指令節點定義結構:
struct cmd_node
{
/* Node index. */
enum node_type node; // 指令類型
/* Prompt character at vty interface. */
const char *prompt; //指令節點下的提示符字元串,在cmd_prompt()中調用。顯示的是host.name或者目前作業系統的名稱uname().
/* Is this node's configuration goes to vtysh ? */
int vtysh; // 非零時表示不搜尋父節點。
/* Node's configuration write function */
int (*func) (struct vty *); //回調函數,在install_node中調用,可在DEFUN的回調函數實作中執行。
/* Vector of this node's command list. */
vector cmd_vector;
};
定義新增的指令節點示例:
struct cmd_node vty_node =
{
TEST_NODE,
"%s(config-line)# ",
,
};
指令屬性:
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 tokens; /* Vector of cmd_tokens */
u_char attr; /* Command attributes */
};
其中,
string:對應DEFUN中指令字元串,即第三個參數。
func:對應DEFUN中聲明的函數名稱,即第第一個參數。在 cmd_execute_command_real()中被調用。
doc:對應DEFUN中的幫助資訊,即第四個參數
attr:指令屬性,是CMD_ATTR_HIDDEN,還是CMD_ATTR_DEPRECATED。
daemon:該指令所屬的程序号id。vtysh接收到指令後,可通過該字段來确定該指令屬于哪個程序,則傳遞給該程序處理該指令,程序處理完會自動傳回一個結果給vtysh。
終端host結構:可以通過指令設定其中的任何字段,在cmd_init()中初始化,用于cli指令的根節點顯示。
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;
};
vty結構
struct vty
{
/* File descripter of this vty. */
int fd; //vty句柄。
/* 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;//目前的節點類型,對應 enum node_type。
/* Failure count */
int fail;
/* Output buffer. */
struct buffer *obuf;//輸出資訊
/* Command input buffer */
char *buf;//讀入的指令資訊
/* Command cursor point */
int cp;//指向buf的目前指針
/* 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;//是否有轉義字元或換碼符。值為VTY_NORMAL(0),VTY_PRE_ESCAPE(1),VTY_ESCAPE(2)。
/* Current vty status. */
enum {VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE} status;//vty目前狀态,當為VTY_CLOSE時,需要關閉vty,即vty_close()。
/* 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;
/* Terminal monitor. */
int monitor;
/* In configure mode. */
int config;
/* Read and write thread. */
struct thread *t_read;//vty讀操作的定時器線程
struct thread *t_write;//vty寫操作的定時器線程
/* Timeout seconds and thread. */
unsigned long v_timeout;//cli逾時時間
struct thread *t_timeout;//cli逾時時間的定時器線程
/* What address is this vty comming from. */
char address[SU_ADDRSTRLEN];
}
調用DEFUN中定義的回調函數的流程:
