123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
- package main
- import (
- "fmt"
- "git.swzry.com/zry/go-hhc-cli/hhc_ast"
- "git.swzry.com/zry/go-hhc-cli/hhc_common"
- "github.com/cheynewallace/tabby"
- "math/rand"
- "net"
- "os"
- "regexp"
- "strconv"
- "strings"
- )
- var FRGEXP *regexp.Regexp
- var ExecSB strings.Builder
- func FExec(ctx *hhc_ast.SDTWalkContext) hhc_common.SDTWalkError {
- fmt.Println("! Command Execute: ", CtxToCommand(ctx))
- ExecSB.WriteString(CtxToCommand(ctx) + "\r\n")
- return nil
- }
- func VLoopbackInf(t string) bool {
- i, e := strconv.Atoi(t)
- if e != nil {
- return false
- }
- if i < 0 || i > 7 {
- return false
- }
- return true
- }
- func VSubnetLen(t string) bool {
- i, e := strconv.Atoi(t)
- if e != nil {
- return false
- }
- if i < 1 || i > 31 {
- return false
- }
- return true
- }
- func VMTU(t string) bool {
- i, e := strconv.Atoi(t)
- if e != nil {
- return false
- }
- if i < 128 || i > 1500 {
- return false
- }
- return true
- }
- func VVlanInf(t string) bool {
- i, e := strconv.Atoi(t)
- if e != nil {
- return false
- }
- if i < 0 || i > 4095 {
- return false
- }
- return true
- }
- func VIPAddress(t string) bool {
- _, err := net.ResolveIPAddr("ip", t)
- return err == nil
- }
- func main() {
- var err error
- FRGEXP, err = regexp.Compile("INTEGER<([0-9]+)\\-([0-9]+)>")
- if err != nil {
- fmt.Println("Failed Compile Regexp:", err)
- return
- }
- ctx := &hhc_ast.SDTWalkContext{ASTNodes: []hhc_ast.ASTNode{}}
- var cur hhc_ast.SyntaxDefTreeNode
- cur = (&hhc_ast.SyntaxDefinitionTreeRoot{}).AddCommand(
- (&hhc_ast.SDTNode_Command{
- Name: "ip",
- Description: "Specify IP configuration",
- }).AddSubCommand(
- (&hhc_ast.SDTNode_Command{
- Name: "address",
- Description: "Set the IP address of an interface",
- }).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "dhcp-alloc",
- Description: "Obtain an IP address through DHCP",
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- })).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "unnumbered",
- Description: "Share an address with another interface",
- }).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "interface",
- Description: "Specify the interface whose ip address was unnumbered",
- }).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "loopback",
- Description: "LoopBack interface",
- }).AddValArgument((&hhc_ast.SDTNode_Argument{
- FormatDescription: "INTEGER<0-7>",
- Description: "LoopBack interface number",
- Validator: VLoopbackInf,
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- }))).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "vlan-interface",
- Description: "VLAN interface",
- }).AddValArgument((&hhc_ast.SDTNode_Argument{
- FormatDescription: "INTEGER<0-4095>",
- Description: "Vlan-interface interface number",
- Validator: VVlanInf,
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- }))))).AddValArgument((&hhc_ast.SDTNode_Argument{
- FormatDescription: "X.X.X.X",
- Description: "IP address",
- Validator: VIPAddress,
- }).AddValArgument((&hhc_ast.SDTNode_Argument{
- FormatDescription: "INTEGER<1-31>",
- Description: "IP mask length",
- Validator: VSubnetLen,
- }).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "sub",
- Description: "Indicate a subordinate address",
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- })).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- })).AddValArgument((&hhc_ast.SDTNode_Argument{
- FormatDescription: "X.X.X.X",
- Description: "IP mask",
- Validator: VIPAddress,
- }).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "sub",
- Description: "Indicate a subordinate address",
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- })).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- })))).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "mtu",
- Description: "Specify the MTU of the interface",
- }).AddValArgument((&hhc_ast.SDTNode_Argument{
- FormatDescription: "INTEGER<128-1500>",
- Description: "MTU in bytes",
- Validator: VMTU,
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- })))).AddCommand((&hhc_ast.SDTNode_Command{
- Name: "ipv6",
- Description: "Specify IPv6 configuration",
- }).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "dhcp",
- Description: "Configure DHCPv6",
- }).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "select",
- Description: "Specify process mode of DHCPv6 packet",
- }).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "relay",
- Description: "Relay mode",
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- })).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "server",
- Description: "Server mode",
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- })))).AddSubCommand((&hhc_ast.SDTNode_Command{
- Name: "mtu",
- Description: "Specify the IPv6 MTU of the interface",
- }).AddValArgument((&hhc_ast.SDTNode_Argument{
- FormatDescription: "INTEGER<128-1500>",
- Description: "MTU in bytes",
- Validator: VMTU,
- }).AddEnd(&hhc_ast.SDTNode_End{
- Exec: FExec,
- }))))
- t := GenerateValByFormatDesc("X.X.X.X")
- fmt.Println(t, VIPAddress(t))
- t = GenerateValByFormatDesc("INTEGER<1-31>")
- fmt.Println(t, VSubnetLen(t))
- fmt.Println("==== ==== ==== Ready ==== ==== ====")
- AutoWalk(ctx, cur)
- fmt.Println("==== ==== ==== End of AutoWalk ==== ==== ====")
- fmt.Println("All Command Lines:")
- fmt.Println(ExecSB.String())
- //_, _ = ctx, cur
- }
- func Walk(ctx *hhc_ast.SDTWalkContext, cur hhc_ast.SyntaxDefTreeNode, token string) hhc_ast.SyntaxDefTreeNode {
- fmt.Println("Walk into with token:", token)
- ncur, err := cur.WalkNext(ctx, token)
- if err != nil {
- fmt.Println("Error In Walk")
- fmt.Println("FES:", err.FES())
- fmt.Println("EES:", err.EES())
- os.Exit(-1)
- }
- fmt.Println("Walked into", GetCtxPath(ctx))
- return ncur
- }
- func AutoWalk(ctx *hhc_ast.SDTWalkContext, cur hhc_ast.SyntaxDefTreeNode) {
- fmt.Println("======== Help of", GetCtxPath(ctx), "========")
- if cur.IsEnd() {
- switch cur.(type) {
- case *hhc_ast.SDTNode_End:
- ncur := cur.(*hhc_ast.SDTNode_End)
- ncur.Exec(ctx)
- }
- return
- }
- PrintHelp(cur.GetHelps(""))
- for _, v := range cur.GetHelps("") {
- nctx := CopyCtx(ctx)
- var cin hhc_ast.SyntaxDefTreeNode
- if v.IsArg {
- cin = Walk(nctx, cur, GenerateValByFormatDesc(v.Name))
- } else {
- cin = Walk(nctx, cur, v.Name)
- }
- AutoWalk(nctx, cin)
- }
- }
- func CopyCtx(ctx *hhc_ast.SDTWalkContext) *hhc_ast.SDTWalkContext {
- nctx := &hhc_ast.SDTWalkContext{ASTNodes: make([]hhc_ast.ASTNode, len(ctx.ASTNodes))}
- for i, v := range ctx.ASTNodes {
- nctx.ASTNodes[i] = v
- }
- return nctx
- }
- func PrintHelp(h []hhc_common.SDTHelpInfo) {
- t := tabby.New()
- for i, v := range h {
- t.AddLine(i, v.IsArg, v.Name, v.Description)
- }
- t.Print()
- }
- func GetCtxPath(ctx *hhc_ast.SDTWalkContext) string {
- sb := strings.Builder{}
- sb.WriteString("/")
- for _, v := range ctx.ASTNodes {
- sb.WriteString(v.GetTokenRaw() + "/")
- }
- return sb.String()
- }
- func CtxToCommand(ctx *hhc_ast.SDTWalkContext) string {
- sb := strings.Builder{}
- for _, v := range ctx.ASTNodes {
- sb.WriteString(v.GetTokenRaw() + " ")
- }
- return sb.String()
- }
- func GenerateValByFormatDesc(format string) string {
- if format == "<cr>" {
- return ""
- }
- if format == "X.X.X.X" {
- return "192.168.1.1"
- }
- ret := FRGEXP.FindAllStringSubmatch(format, 1)
- if len(ret) == 1 {
- if len(ret[0]) == 3 {
- min, _ := strconv.Atoi(ret[0][1])
- max, _ := strconv.Atoi(ret[0][2])
- vi := rand.Intn(max-min) + min
- return strconv.Itoa(vi)
- }
- }
- return ""
- }
|