Nav links

Tuesday, 5 August 2008

Scripting telnet

I bought a new Billion 7401VGPM ADSL modem/router last week. My old Billion 741GE has performed admirably for many years, but I felt it was time to move up to ADSL2+ (from ADSL1), WiFi and VoIP.


The new ADSL standard immediately increased my internet connection speed from 5.5Mb/s to 8.5Mb/s, though if I hadn't looked up the numbers I probably wouldn't have noticed the difference. Of more importance, this is my first wireless access point, so I can finally play Nintendo DS games against non-CPU opponents, and download a plethora of extra puzzles for Picross and Professor Layton. Finally, VoIP will be necessary if I decide to save money by dropping my phone line rental and going Naked.


Unfortunately, the Nintendo DS only supports wireless security up to the insecure WEP standard. As a consequence I wanted to only have the WiFi turned on when I was playing. The router provides a web interface for turning the WiFi on and off, but I was after a one (or zero)-button solution. Luckily, the router also provides a telnet server to allow access to all of its functionality. With the right tools, scripting telnet is a doddle.


I first looked for a free telnet client that provided scripting support. Amazingly, my old favourite from ten years ago was still going strong - Tera Term, though with a new developer and in new Open Source clothing. I quickly came up with a simple script that with a click of a button would tell me if WiFi was on or not, and offer to change it.


;  Telnet login

; open Tera Term
connect '192.168.1.254:23 /nossh /v'

; set username
UsernamePrompt = 'Login:'
Username = '[USERNAME]'
PasswordPrompt = 'Password:'
Password = '[PASSWORD]'

; login
wait   UsernamePrompt
sendln Username

wait   PasswordPrompt
sendln Password

; OK, auto login complete.

finish = 0
while finish = 0
call getstatus
endwhile
sendln 'user logout'
end

flushrecv
sendln 'port wireless status'
waitln 'Disable'
strscan inputstr 'false'
if result <> 0 then
beep
yesnobox 'Wi-Fi is active\n\nTurn off?' 'Wi-Fi Status'
if result then
sendln 'port wireless set Disable true'
else
finish = 1
endif
else
strscan inputstr 'true'
if result <> 0 then
yesnobox 'Wi-Fi is turned off\n\nTurn on?' 'Wi-Fi Status'
if result then
sendln 'port wireless set Disable false'
else
finish = 1
endif
else
messagebox 'Wi-Fi status not found' 'ERROR'
finish = 1
endif
endif
return


That was okay, but I wanted some additions that weren't possible in Tera Term. Specifically, I wanted to set the WiFi to be turned off after some user-defined time, and I wanted the WiFi status to be shown by an icon in the Windows tray. This would require a proper programming or scripting language.


I first looked at Perl. For simplicity of coding the telnet interaction it looked like a winner:


use Net::Telnet;
$telnet = new Net::Telnet ( Timeout=>10, Errmode=>'die' ,Prompt => '/admin> $/i');
$telnet->open('192.168.1.254');
$telnet->login('[USERNAME]', '[PASSWORD]');
print $telnet->cmd('port wireless status');
$telnet->cmd('user logout');
$telnet->close();


However, my other requirements looked like they could be more easily solved in C# (and give me an excuse to play with Microsoft Visual C# 2008 Express). Interestingly, although the .Net framework seems all-encompassing, it doesn't have a nice Telnet wrapper. For this I turned to a nice free wrapper called
C#Telnet. Whilst not as simple as Perl, it was pretty close.


As I wanted the WiFi to be turned off automatically even if the computer running this script was in standby I wanted to use Windows built-in Scheduled Tasks, as these allowed for waking the computer from standby. Again, interacting with scheduled tasks isn't part of the .Net framework, so this time I called on the Task Scheduler Library, which worked a treat.


Once all the libraries were in place the coding was straightforward. The last piece of outside help was to use some GPL icons from Lullabot, so my tray icon could take on different colours indicating if the WiFi was on, off, or scheduled to be turned off.


As this is a project customised for me alone there wouldn't be much point in releasing my finished program. I may produce a more general version one day.


The moral of this story is that tinkerers like me love hardware such as the Billion that provide easily scriptable interfaces.