Post

Netgear GS728TP CLI and scripting

It’s been a long time between posts. I can assure you I’m not dead. At least not that I know of. I’ve been doing some neat stuff, but have been too lazy to post any of it - because as any dev will tell you - doing documentation is boring.

So, after upgrading my access points to use a Cisco Virtual Wireless Controller, I was using the web interface on my Netgear GS728TP - but it really sucks. It’s slow. It’s really slow - but it has a fully functioning CLI under the hood. However, the SSH server is old as well, so it needs a whole heap of legacy enablement in the SSH client to function. It is an EoL product, being first released in November 2017 from what I can tell. However they’re cheap to find second hand, and have 8x POE+ ports - which means they’ll run your high power PoE kit.

I did some work with expect - and came up with this script to do some pretty common functions.

Save as ~/bin/switch.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#!/usr/bin/expect
set switch_password "<switch password>"
set switch_login "admin@<switch ip>"
set TFTPSERVER "<tftp server ip>"
set switch_ssh_opts "-oPubKeyAcceptedAlgorithms=ssh-rsa -oRequiredRSASize=1024 -oKexAlgorithms=diffie-hellman-group1-sha1 -oHostKeyAlgorithms=ssh-rsa,ssh-dss -oCiphers=aes128-cbc,aes128-ctr,aes256-ctr"
set commands(0) "terminal datadump"
set commands(1) "terminal width 0"
set timeout 120

set func [lindex $argv 0]
switch $func {
	if {
		set arg [lindex $argv 1]
		switch $arg {
			description {
				append commands([array size commands]) "show interfaces description"
			}
			detail {
				set port [lindex $argv 2]
				append commands([array size commands]) "show interfaces switchport ge $port"
			}
			reset {
				set port [lindex $argv 2]
				append commands([array size commands]) "config"
				append commands([array size commands]) "interface GigabitEthernet $port"
				append commands([array size commands]) "shutdown"
				append commands([array size commands]) "no shutdown"
				append commands([array size commands]) "exit\rexit\r"
			}
			summary {
				append commands([array size commands]) "show interfaces status detailed"
			}
			default {
				puts "Subcommands:\r"
				puts "\tdescription\r"
				puts "\tdetail <port>\r"
				puts "\treset <port>\r"
				puts "\tsummary\r"
				exit 0
			}
		}
	}
	poe {
		set arg [lindex $argv 1]
		switch $arg {
			consumption {
				append commands([array size commands]) "show power inline consumption"
			}	
			off {
				set port [lindex $argv 2]
				append commands([array size commands]) "config"
				append commands([array size commands]) "interface GigabitEthernet $port"
				append commands([array size commands]) "power inline never"
				append commands([array size commands]) "exit\rexit\r"
			}
			on {
				set port [lindex $argv 2]
				append commands([array size commands]) "config"
				append commands([array size commands]) "interface GigabitEthernet $port"
				append commands([array size commands]) "power inline auto"
				append commands([array size commands]) "exit\rexit\r"
			}
			reset {
				set port [lindex $argv 2]
				append commands([array size commands]) "config"
				append commands([array size commands]) "interface GigabitEthernet $port"
				append commands([array size commands]) "power inline never"
				append commands([array size commands]) "power inline auto"
				append commands([array size commands]) "exit\rexit\r"
			}
			summary {
				append commands([array size commands]) "show power inline"
			}	
			default {
				puts "Subcommands:\r"
				puts "\tconsumption\r"
				puts "\toff <port>\r"
				puts "\ton <port>\r"
				puts "\treset <port>\r"
				puts "\tsummary\r"
				exit 0
			}
		}
	}
	reboot {
		send -- "reload\r"
		expect "(Y/N)"
		send -- "y\r"
		interact
	}
	saveconfig {
		set DATE [clock format [clock seconds] -format {%Y-%m-%d_%H%M}]
		append commands([array size commands]) "copy running-config tftp://$TFTPSERVER/gs728tp/running-config-$DATE.txt"
	}
	vlan {
		append commands([array size commands]) "show vlan"
	}
	default {
		puts "Commands:\r"
		puts "\tif <cmd>\r"
		puts "\tpoe <cmd>\r"
		puts "\treboot\r"
		puts "\tsaveconfig\r"
		puts "\tvlan\r"
		exit
	}
}

eval spawn ssh $switch_ssh_opts $switch_login

expect "assword:"
send -- "$switch_password\r"
for { set index 0 }  { $index < [array size commands] }  { incr index } {
	expect "#"
	send -- "$commands($index)\r"
}
expect "\r\nconsole#"
send -- "exit\r"
expect eof

This gives me a nice little easy to use command set for some very basic stuff - however, if you’re like me with a million scripts, I also forget the options :)

As such, I took a dive into the bash-completion universe and managed to come up with this.

Save as ~/.bash_completion.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#/usr/bin/env bash
_switch_completions()
{
  local cur prev

  COMPREPLY=()
  cur=${COMP_WORDS[COMP_CWORD]}
  prev=${COMP_WORDS[COMP_CWORD-1]}

  if [ $COMP_CWORD -eq 1 ]; then
    COMPREPLY=( $(compgen -W "if poe reboot saveconfig vlan" -- $cur) )
  elif [ $COMP_CWORD -eq 2 ]; then
    case "$prev" in
      "if")
        COMPREPLY=( $(compgen -W "description detail reset summary" -- $cur) )
        ;;
      "poe")
        COMPREPLY=( $(compgen -W "consumption off on reset summary" -- $cur) )
        ;;
      *)
        ;;
    esac
  fi

  return 0
} &&
complete -F _switch_completions switch

As an example, if I run switch if summary, I’ll get the following output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
spawn ssh -oPubKeyAcceptedAlgorithms=ssh-rsa -oRequiredRSASize=1024 -oKexAlgorithms=diffie-hellman-group1-sha1 -oHostKeyAlgorithms=ssh-rsa,ssh-dss -oCiphers=aes128-cbc,aes128-ctr,aes256-ctr admin@<switch-ip>
admin@<switch-ip>'s password:

console#terminal datadump
console#terminal width 0
console#show interfaces status detailed
                                             Flow Link          Back   Mdix
Port     Type         Duplex  Speed Neg      ctrl State       Pressure Mode
-------- ------------ ------  ----- -------- ---- ----------- -------- -------
g1       1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g2       1G-Copper      --      --     --     --  Down           --     --    
g3       1G-Copper      --      --     --     --  Down           --     --    
g4       1G-Copper      --      --     --     --  Down           --     --    
g5       1G-Copper      --      --     --     --  Down           --     --    
g6       1G-Copper      --      --     --     --  Down           --     --    
g7       1G-Copper      --      --     --     --  Down           --     --    
g8       1G-Copper      --      --     --     --  Down           --     --    
g9       1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g10      1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g11      1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g12      1G-Copper    Full    1000  Disabled Off  Up          Disabled On     
g13      1G-Copper    Full    100   Enabled  Off  Up          Disabled On     
g14      1G-Copper    Full    100   Enabled  Off  Up          Disabled Off    
g15      1G-Copper      --      --     --     --  Down           --     --    
g16      1G-Copper      --      --     --     --  Down           --     --    
g17      1G-Copper      --      --     --     --  Down           --     --    
g18      1G-Copper      --      --     --     --  Down           --     --    
g19      1G-Copper      --      --     --     --  Down           --     --    
g20      1G-Copper      --      --     --     --  Down           --     --    
g21      1G-Copper      --      --     --     --  Down           --     --    
g22      1G-Copper      --      --     --     --  Down           --     --    
g23      1G-Copper    Full    1000  Enabled  Off  Up          Disabled On     
g24      1G-Copper    Full    100   Enabled  Off  Up          Disabled Off    
g25      1G-Fiber       --      --     --     --  Down           --     --    
g26      1G-Fiber       --      --     --     --  Down           --     --    
g27      1G-Fiber       --      --     --     --  Down           --     --    
g28      1G-Fiber       --      --     --     --  Down           --     --    

                                          Flow    Link        
Ch       Type    Duplex  Speed  Neg      control  State       
-------- ------- ------  -----  -------- -------  ----------- 
po 1        --     --      --      --       --    Not Present 
po 2        --     --      --      --       --    Not Present 
po 3        --     --      --      --       --    Not Present 
po 4        --     --      --      --       --    Not Present 
po 5        --     --      --      --       --    Not Present 
po 6        --     --      --      --       --    Not Present 
po 7        --     --      --      --       --    Not Present 
po 8        --     --      --      --       --    Not Present 
console#exit

So now, not only do I have an easy way to bring up basic details of the switch, when I forget what options do what, you can just use the TAB auto-completion in bash. Yay, yet another thing I don’t have to remember in the day-to-day :)

This post is licensed under CC BY 4.0 by the author.