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 :)