No meu último post eu falei sobre como acessar via telnet a interface modo texto (aka CLI) do modem D-Link 500G. Para quem gosta de trabalhar no terminal só isso já é uma maravilha, porém essa descoberta tem algumas outras vantagens…
E se nós pudéssemos controlar/manipular o modem através de scripts? Isso sim seria legal… Mas como criar um shell script para interagir com telnet é um tanto quanto chato, eu criei um módulo python para fazer isso. Então seguindo os exemplos do posts passado, vamos ver como fazer a mesma coisa porém dessa vez através do módulo Python:
Imprimir o help
Observe que foram criadas constantes para os valores padrão de configuração do modem, portanto se você usa o aparelho da maneira como ele lhe foi entregue, provavelmente não precisará alterar nada no códgo abaixo.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from dlink500g import *
try:
modem = DLink500G(DEFAULT_ADDRESS, DEFAULT_PORT)
modem.connect(DEFAULT_USERNAME, DEFAULT_PASSWORD)
print modem.command('help')
modem.command('quit')
except Exception, ex:
print 'Error:', str(ex)
Reiniciar o modem
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from dlink500g import *
try:
modem = DLink500G(DEFAULT_ADDRESS, DEFAULT_PORT)
modem.connect(DEFAULT_USERNAME, DEFAULT_PASSWORD)
modem.command('reboot')
except Exception, ex:
print 'Error:', str(ex)
Código fonte
Abaixo está o conteúdo da primeira versão deste módulo, que provavelmente sofrerá alterações e/ou bugfixes, portanto para se você deseja obter uma versão mais atualizada acesse o código fonte disponível no meu repositório svn do Google Code.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# This module provides a python interface to D-Link 500G CLI.
#
# written by Arthur Furlan <arthur.furlan@gmail.com>
import re, telnetlib
# default configuration
DEFAULT_ADDRESS = '10.0.0.1'
DEFAULT_PORT = 23
DEFAULT_USERNAME = 'admin'
DEFAULT_PASSWORD = 'admin'
class DLink500G:
def __init__(self, address, port):
self.address = address
self.port = port
self.connected = False
def __del__(self):
if self.connected:
self.command('quit')
self.telnet.close()
def connect(self, username, password):
self.telnet = telnetlib.Telnet(self.address, self.port)
self.telnet.read_until('login: ')
self.telnet.write("%s\n" % username)
self.telnet.read_until('password: ')
self.telnet.write("%s\n" % password)
response = self.telnet.expect(['\$'], 5)
if response[0] == -1:
raise Exception('Login failed.')
self.connected = True
def command(self, cmd):
if not self.connected:
raise Exception('Not logged in.')
self.telnet.write("%s\n" % cmd)
self.connected = not (cmd == 'quit')
if self.connected:
response = self.telnet.read_until('$').replace('\r', '').split('\n')
if re.match('^Error: ', response[1]):
raise Exception(re.sub('^Error: ', '', response[1]))
return '\n'.join(response[1:len(response)-1])
Sinta-se a vontade para enviar-me crítricas e/ou sugestões. :)
UPDATE1: Seguindo o “conselho” do Eduardo Willians, alterei a visibilidade dos atributos para público.
UPDATE2: Aproveitei o embalo para criar um projeto no Google Code, cuja a intenção é criar um pacote com módulos para vários dispositivos da D-Link que seguem a mesma linha. Lá você poderá encontrar as versões mais recentes desse módulo.
UPDATE3: Notícia divulgada também no br-linux.org


