From 9160b0ff433762164e2b30ca73a479bc10c6f3c4 Mon Sep 17 00:00:00 2001 From: Maxim Slipenko Date: Sun, 2 Oct 2022 13:55:59 +0300 Subject: [PATCH] init project --- client.go | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ go.mod | 7 ++++ go.sum | 4 ++ iproute.go | 83 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 client.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 iproute.go diff --git a/client.go b/client.go new file mode 100644 index 0000000..cf84176 --- /dev/null +++ b/client.go @@ -0,0 +1,105 @@ +package client + +import ( + "fmt" + "log" + "sync" + + "github.com/reiver/go-telnet" +) + +type Client struct { + t *telnet.Conn + mutex sync.Mutex + login string + password string +} + +func (c *Client) readUntil(read bool, delims ...string) ([]byte, int, error) { + if len(delims) == 0 { + return nil, 0, nil + } + p := make([]string, len(delims)) + for i, s := range delims { + if len(s) == 0 { + return nil, 0, nil + } + p[i] = s + } + var line []byte + b := make([]byte, 1) + for { + _, err := c.t.Read(b) + if err != nil { + return nil, 0, err + } + if read { + line = append(line, b...) + } + for i, s := range p { + if s[0] == b[0] { + if len(s) == 1 { + return line, i, nil + } + p[i] = s[1:] + } else { + p[i] = delims[i] + } + } + } +} + +func (c *Client) ExecuteCommand(cmd string) []byte { + c.mutex.Lock() + c.t.Write([]byte(cmd + "\n")) + result, _ := c.ReadUntil(">") + c.mutex.Unlock() + return result +} + +func (c *Client) ReadUntil(delims ...string) ([]byte, error) { + d, _, err := c.readUntil(true, delims...) + return d, err +} + +func (c *Client) SkipUntil(delims ...string) error { + _, _, err := c.readUntil(false, delims...) + return err +} + +func expect(c *Client, d ...string) { + c.SkipUntil(d...) +} + +func (c *Client) Authorize() { + c.mutex.Lock() + + expect(c, "Login:") + fmt.Println("l") + c.t.Write([]byte(c.login + "\n")) + expect(c, "Password:") + fmt.Println("p") + c.t.Write([]byte(c.password + "\n")) + expect(c, ">") + + c.mutex.Unlock() +} + +func New(dst string, login string, password string) (*Client, error) { + t, err := telnet.DialTo(dst) + + if err != nil { + log.Fatal(err) + } + + if err != nil { + return nil, err + } + + return &Client{ + t: t, + mutex: sync.Mutex{}, + login: login, + password: password, + }, nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..18d1d10 --- /dev/null +++ b/go.mod @@ -0,0 +1,7 @@ +module git.slipenko.com/Maks1mS/go-keenetic + +go 1.18 + +require github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e + +require github.com/reiver/go-oi v1.0.0 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4b7b7a4 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/reiver/go-oi v1.0.0 h1:nvECWD7LF+vOs8leNGV/ww+F2iZKf3EYjYZ527turzM= +github.com/reiver/go-oi v1.0.0/go.mod h1:RrDBct90BAhoDTxB1fenZwfykqeGvhI6LsNfStJoEkI= +github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e h1:quuzZLi72kkJjl+f5AQ93FMcadG19WkS7MO6TXFOSas= +github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e/go.mod h1:+5vNVvEWwEIx86DB9Ke/+a5wBI464eDRo3eF0LcfpWg= diff --git a/iproute.go b/iproute.go new file mode 100644 index 0000000..cdeef44 --- /dev/null +++ b/iproute.go @@ -0,0 +1,83 @@ +package client + +import ( + "errors" + "fmt" + "strings" +) + +type IProute struct { + Destination string + Gateway string + Interface string + Metric string +} + +func GetIpRoutesCmd() string { + return "show ip route" +} + +func (c *Client) GetIpRoutes() []IProute { + raw := c.ExecuteCommand(GetIpRoutesCmd()) + + prefix := 305 + postfix := 12 + + string_result := string(raw[prefix : len(raw)-postfix]) + lines := strings.Split(string_result, "\r\n") + + result := make([]IProute, len(lines)) + + for i, x := range lines { + l := strings.Fields(x) + result[i] = IProute{Destination: l[0], Gateway: l[1], Interface: l[2], Metric: l[3]} + } + + return result +} + +func AddIpRouteCmd(route IProute, auto bool) string { + autoString := "auto" + + if !auto { + autoString = "" + } + + return fmt.Sprintf("ip route %s %s %s %s %s", route.Destination, route.Gateway, route.Interface, route.Metric, autoString) +} + +func (c *Client) AddIpRoute(route IProute, auto bool) error { + cmd := AddIpRouteCmd(route, auto) + raw := c.ExecuteCommand(cmd) + + prefix := len(cmd)*4 + 7 + postfix := 11 + + result := string(raw[prefix : len(raw)-postfix]) + + if strings.HasPrefix(result, "Network::RoutingTable: added static route") || strings.HasPrefix(result, "Network::RoutingTable: renewed static route") { + return nil + } else { + return errors.New(result) + } +} + +func RemoveIpRouteCmd(route IProute) string { + return fmt.Sprintf("no ip route %s %s %s", route.Destination, route.Interface, route.Metric) +} + +func (c *Client) RemoveIpRoute(route IProute) error { + cmd := RemoveIpRouteCmd(route) + raw := c.ExecuteCommand(cmd) + + prefix := len(cmd)*4 + 7 + postfix := 11 + + result := string(raw[prefix : len(raw)-postfix]) + + if strings.HasPrefix(result, "Network::RoutingTable: deleted static route:") { + return nil + } else { + return errors.New(result) + } +}